From 2ef589c820be33f7eb362b1f8c9fa2c7f5b5a9e6 Mon Sep 17 00:00:00 2001 From: Noah van der Aa Date: Tue, 22 Oct 2024 18:23:19 +0200 Subject: [PATCH 001/119] okaaay let's go --- README.md | 4 +- gradle.properties | 6 +- .../api/0001-Convert-project-to-Gradle.patch | 4 +- patches/api/0002-Build-system-changes.patch | 2 +- patches/api/0003-Test-changes.patch | 2 +- patches/api/0004-Code-Generation.patch | 8 +- patches/api/0005-Add-FastUtil-to-Bukkit.patch | 2 +- patches/api/0006-Adventure.patch | 93 ++++++++++--------- .../0008-Use-ASM-for-event-executors.patch | 2 +- patches/api/0009-Paper-Plugins.patch | 2 +- patches/api/0010-Add-Position.patch | 2 +- patches/api/0011-Timings-v2.patch | 4 +- ...-option-to-load-extra-plugin-jars-no.patch | 4 +- .../0013-Player-affects-spawning-API.patch | 4 +- patches/api/0017-Add-view-distance-API.patch | 4 +- ...cord-chat-API-from-spigot-subclasses.patch | 8 +- .../0024-Player-Tab-List-and-Title-APIs.patch | 4 +- .../api/0026-Complete-resource-pack-API.patch | 4 +- patches/api/0039-LootTable-API.patch | 4 +- ...0045-Add-String-based-Action-Bar-API.patch | 6 +- patches/api/0053-Fix-upstream-javadocs.patch | 32 +++---- .../0059-Shoulder-Entities-Release-API.patch | 4 +- patches/api/0065-LivingEntity-setKiller.patch | 2 +- ...low-plugins-to-use-SLF4J-for-logging.patch | 2 +- ...efixes-in-implementation-logging-con.patch | 2 +- patches/api/0073-AsyncTabCompleteEvent.patch | 2 +- ...nt-protocol-version-and-virtual-host.patch | 2 +- ...8-Ability-to-apply-mending-to-XP-API.patch | 6 +- .../api/0084-Add-ArmorStand-Item-Meta.patch | 4 +- .../0089-Player.setPlayerProfile-API.patch | 4 +- ...2-Add-openSign-method-to-HumanEntity.patch | 8 +- ...93-Add-Ban-Methods-to-Player-Objects.patch | 4 +- .../api/0097-Location.isChunkLoaded-API.patch | 2 +- ...ld.spawnParticle-API-and-add-Builder.patch | 4 +- ...ion.toBlockLocation-toCenterLocation.patch | 2 +- ...Add-getNearbyXXX-methods-to-Location.patch | 2 +- patches/api/0112-Expand-Explosions-API.patch | 2 +- .../0114-LivingEntity-Active-Item-API.patch | 4 +- .../0116-Add-World.getEntity-UUID-API.patch | 2 +- .../0117-InventoryCloseEvent-Reason-API.patch | 2 +- ...125-Expand-Location-Manipulation-API.patch | 2 +- ...vide-Chunk-Coordinates-as-a-Long-API.patch | 2 +- ...Blocks-to-be-accessed-via-a-long-key.patch | 4 +- patches/api/0137-isChunkGenerated-API.patch | 4 +- patches/api/0139-Async-Chunks-API.patch | 2 +- ...-ray-tracing-methods-to-LivingEntity.patch | 2 +- ...e-attack-cooldown-methods-for-Player.patch | 4 +- patches/api/0146-Material-API-additions.patch | 6 +- patches/api/0147-Add-Material-Tags.patch | 2 +- ...149-Add-LivingEntity-getTargetEntity.patch | 2 +- patches/api/0150-Add-sun-related-API.patch | 2 +- .../0166-Fix-Spigot-annotation-mistakes.patch | 36 +++---- patches/api/0169-Add-Heightmap-API.patch | 2 +- ...ue-custom-payload-channel-size-limit.patch | 2 +- .../0183-Add-Player-Client-Options-API.patch | 4 +- patches/api/0186-Villager-Restocks-API.patch | 2 +- patches/api/0190-Potential-bed-API.patch | 4 +- .../0193-Support-components-in-ItemMeta.patch | 14 +-- patches/api/0198-Brand-support.patch | 4 +- ...-Add-methods-to-get-translation-keys.patch | 40 ++++---- ...al-open-container-api-to-HumanEntity.patch | 2 +- .../api/0208-Player-elytra-boost-API.patch | 4 +- ...0-Expose-LivingEntity-hurt-direction.patch | 4 +- ...et-Material-from-Boats-and-Minecarts.patch | 11 ++- patches/api/0235-Add-sendOpLevel-API.patch | 4 +- .../api/0254-Improve-Item-Rarity-API.patch | 8 +- ...-add-isDeeplySleeping-to-HumanEntity.patch | 4 +- patches/api/0270-Add-basic-Datapack-API.patch | 8 +- .../api/0272-ItemStack-repair-check-API.patch | 2 +- patches/api/0275-ItemStack-editMeta.patch | 2 +- ...7-Improve-item-default-attribute-API.patch | 10 +- .../api/0280-Add-PlayerKickEvent-causes.patch | 4 +- .../0284-Add-more-line-of-sight-methods.patch | 2 +- patches/api/0287-Missing-Entity-API.patch | 11 ++- patches/api/0291-Stinger-API.patch | 2 +- ...o-find-targets-for-lightning-strikes.patch | 2 +- .../0304-Get-entity-default-attributes.patch | 4 +- ...sCollision-methods-to-various-places.patch | 8 +- patches/api/0325-Multi-Block-Change-API.patch | 4 +- patches/api/0328-Dolphin-API.patch | 6 +- ...-command-sender-which-forwards-feedb.patch | 4 +- .../api/0331-Implement-regenerateChunk.patch | 2 +- patches/api/0332-Add-GameEvent-tags.patch | 4 +- .../api/0340-Add-enchantWithLevels-API.patch | 2 +- ...Add-method-isTickingWorlds-to-Bukkit.patch | 4 +- patches/api/0352-Add-Player-getFishHook.patch | 4 +- patches/api/0353-More-Teleport-API.patch | 4 +- ...stom-Chat-Completion-Suggestions-API.patch | 4 +- .../0364-Elder-Guardian-appearance-API.patch | 4 +- .../0371-Add-Player-Warden-Warning-API.patch | 4 +- ...la-friendly-methods-to-update-trades.patch | 2 +- patches/api/0374-ItemStack-damage-API.patch | 2 +- .../0381-Add-Sneaking-API-for-Entities.patch | 6 +- patches/api/0383-Flying-Fall-Damage-API.patch | 4 +- patches/api/0385-Win-Screen-API.patch | 4 +- patches/api/0398-Fix-BanList-API.patch | 8 +- .../api/0406-Add-Listing-API-for-Player.patch | 4 +- .../api/0408-Fix-NPE-on-Boat-getStatus.patch | 4 +- ...proper-checking-of-empty-item-stacks.patch | 2 +- .../0420-Add-player-idle-duration-API.patch | 4 +- ...predicate-for-blocks-when-raytracing.patch | 2 +- ...ry-durability-check-in-ItemStack-isS.patch | 2 +- .../api/0427-Add-Structure-check-API.patch | 2 +- ...0428-Experimental-annotations-change.patch | 40 +++++--- patches/api/0430-Improve-Registry.patch | 4 +- .../api/0431-Add-experience-points-API.patch | 4 +- .../0452-Deprecate-ItemStack-setType.patch | 2 +- .../0454-API-for-checking-sent-chunks.patch | 4 +- .../0457-Fix-SpawnerEntry-Equipment-API.patch | 29 +++++- patches/api/0458-Fix-ItemFlags.patch | 2 +- ...d-API-to-get-player-ha-proxy-address.patch | 4 +- .../0465-Brigadier-based-command-API.patch | 2 +- patches/api/0469-General-ItemMeta-fixes.patch | 4 +- ...ntroduce-registry-entry-and-builders.patch | 4 +- ...CanPlaceOn-and-CanDestroy-NBT-values.patch | 4 +- patches/api/0482-Leashable-API.patch | 2 +- patches/api/0485-Add-FeatureFlag-API.patch | 63 ++++++++----- .../api/0490-Improve-entity-effect-API.patch | 4 +- .../server/0001-Setup-Gradle-project.patch | 2 +- .../0002-Remap-fixes.patch | 0 .../0003-Build-system-changes.patch | 0 .../0004-Test-changes.patch | 0 .../0005-Paper-config-files.patch | 0 .../0006-MC-Dev-fixes.patch | 0 .../0007-ConcurrentUtil.patch | 0 .../{server => unapplied}/0008-CB-fixes.patch | 0 .../{server => unapplied}/0009-MC-Utils.patch | 0 .../0010-Adventure.patch | 0 ...oleAppender-for-console-improvements.patch | 0 ...n-prefixes-using-Log4J-configuration.patch | 0 ...e-Log4J-Configuration-Plugin-Loggers.patch | 0 ...r-to-keep-logging-IO-off-main-thread.patch | 0 ...ktraces-in-log-messages-crash-report.patch | 0 ...s-to-contain-the-source-jars-in-stac.patch | 0 .../0017-Paper-command.patch | 0 .../0018-Paper-Metrics.patch | 0 .../0019-Paper-Plugins.patch | 0 .../0020-Plugin-remapping.patch | 0 .../0021-Hook-into-CB-plugin-rewrites.patch | 0 ...ion-calls-in-plugins-using-internals.patch | 0 .../0023-Timings-v2.patch | 0 ...024-Further-improve-server-tick-loop.patch | 0 ...-option-to-load-extra-plugin-jars-no.patch | 0 .../0026-Support-components-in-ItemMeta.patch | 0 ...cactus-bamboo-and-reed-growth-height.patch | 0 ...figurable-baby-zombie-movement-speed.patch | 0 ...029-Configurable-fishing-time-ranges.patch | 0 .../0030-Allow-nerfed-mobs-to-jump.patch | 0 ...onfigurable-entity-despawn-distances.patch | 0 ...ck-and-tnt-entities-at-the-specified.patch | 0 ...0033-Expose-server-build-information.patch | 0 .../0034-Player-affects-spawning-API.patch | 0 ...035-Only-refresh-abilities-if-needed.patch | 0 .../0036-Entity-Origin-API.patch | 0 ...vent-block-entity-and-entity-crashes.patch | 0 ...nfigurable-top-of-nether-void-damage.patch | 0 ...e-before-converting-and-renaming-pla.patch | 0 ...ties-to-activation-range-ignore-list.patch | 0 .../0041-Configurable-end-credits.patch | 0 ...-explosions-processing-dead-entities.patch | 0 .../0043-Optimize-explosions.patch | 0 .../0044-Disable-explosion-knockback.patch | 0 .../0045-Disable-thunder.patch | 0 .../0046-Disable-ice-and-snow.patch | 0 ...7-Configurable-mob-spawner-tick-rate.patch | 0 .../0048-Use-null-Locale-by-default.patch | 0 .../0049-Add-BeaconEffectEvent.patch | 0 ...figurable-container-update-tick-rate.patch | 0 .../0051-Use-UserCache-for-player-heads.patch | 0 .../0052-Disable-spigot-tick-limiters.patch | 0 ...awn-location-event-changing-location.patch | 0 ...urable-Disabling-Cat-Chest-Detection.patch | 0 ...055-Improve-Player-chat-API-handling.patch | 0 ...chunks-are-slime-spawn-chunks-toggle.patch | 0 .../0057-Expose-server-CommandMap.patch | 0 ...e-informative-in-maxHealth-exception.patch | 0 .../0059-Player-Tab-List-and-Title-APIs.patch | 0 ...dd-configurable-portal-search-radius.patch | 0 .../0061-Add-velocity-warnings.patch | 0 .../0062-Add-exception-reporting-event.patch | 0 ...oreboards-for-non-players-by-default.patch | 0 ...working-with-arrows-stuck-in-living-.patch | 0 .../0065-Chunk-Save-Reattempt.patch | 0 .../0066-Complete-resource-pack-API.patch | 0 ...ading-permissions.yml-before-plugins.patch | 0 ...llow-Reloading-of-Custom-Permissions.patch | 0 .../0069-Remove-Metadata-on-reload.patch | 0 ...070-Handle-Item-Meta-Inconsistencies.patch | 0 ...urable-Non-Player-Arrow-Despawn-Rate.patch | 0 .../0072-Add-World-Util-Methods.patch | 0 ...3-Custom-replacement-for-eaten-items.patch | 0 ...th-absorb-values-and-repair-bad-data.patch | 0 ...075-Use-a-Shared-Random-for-Entities.patch | 0 ...le-spawn-chances-for-skeleton-horses.patch | 0 ...ckPhysicsEvent-if-a-plugin-has-a-lis.patch | 0 ...Entity-AddTo-RemoveFrom-World-Events.patch | 0 ...79-Configurable-Chunk-Inhabited-Time.patch | 0 .../0080-EntityPathfindEvent.patch | 0 ...egionFileCache-and-make-configurable.patch | 0 ...2-Do-not-load-chunks-for-Pathfinding.patch | 0 ...0083-Add-PlayerUseUnknownEntityEvent.patch | 0 ...gurable-random-tick-rates-for-blocks.patch | 0 ...g-BlockPlaceEvent-triggering-physics.patch | 0 .../0086-Optimize-DataBits.patch | 0 ...nilla-per-world-scoreboard-coloring-.patch | 0 .../0088-Configurable-Player-Collision.patch | 0 ...ent-to-allow-plugins-to-handle-clien.patch | 0 .../0090-Configurable-RCON-IP-address.patch | 0 ...ityRegainHealthEvent-isFastRegen-API.patch | 0 ...-to-configure-frosted_ice-properties.patch | 0 ...-possibility-for-getServer-singleton.patch | 0 ...y-scoreboard-teams-to-scoreboard.dat.patch | 0 ...able-API-and-replenishable-lootables.patch | 0 ...tem-property-for-disabling-watchdoge.patch | 0 .../0097-Async-GameProfileCache-saving.patch | 0 ...8-Optional-TNT-doesn-t-move-in-water.patch | 0 ...r-redstone-torch-rapid-clock-removal.patch | 0 .../0100-Add-server-name-parameter.patch | 0 .../0101-Fix-global-sound-handling.patch | 0 ...blocking-on-Network-Manager-creation.patch | 0 ...e-profiles-that-have-no-UUID-and-no-.patch | 0 ...setting-for-proxy-online-mode-status.patch | 0 ...ptimise-BlockState-s-hashCode-equals.patch | 0 ...onfigurable-packet-in-spam-threshold.patch | 0 ...07-Configurable-flying-kick-messages.patch | 0 .../0108-Add-EntityZapEvent.patch | 0 ...-entity-nbt-data-from-falling-blocks.patch | 0 ...110-Cache-user-authenticator-threads.patch | 0 ...1-Allow-Reloading-of-Command-Aliases.patch | 0 ...2-Add-source-to-PlayerExpChangeEvent.patch | 0 .../0113-Add-ProjectileCollideEvent.patch | 0 ...vent-Pathfinding-out-of-World-Border.patch | 0 ...ize-Level.hasChunkAt-BlockPosition-Z.patch | 0 ...-Bound-Treasure-Maps-to-World-Border.patch | 0 ...figurable-Cartographer-Treasure-Maps.patch | 0 ...-to-control-if-armor-stands-can-move.patch | 0 .../0119-String-based-Action-Bar-API.patch | 0 ...20-Properly-fix-item-duplication-bug.patch | 0 .../0121-Firework-API-s.patch | 0 .../0122-PlayerTeleportEndGatewayEvent.patch | 0 ...rovide-E-TE-Chunk-count-stat-methods.patch | 0 .../0124-Enforce-Sync-Player-Saves.patch | 0 ...PI-for-Reason-Source-Triggering-play.patch | 0 .../0126-Cap-Entity-Collisions.patch | 0 ...e-CraftScheduler-Async-Task-Debugger.patch | 0 ...le-async-calls-to-restart-the-server.patch | 0 ...ke-parrots-stay-on-shoulders-despite.patch | 0 ...n-option-to-prevent-player-names-fro.patch | 0 ...urable-option-to-disable-creeper-lin.patch | 0 .../0132-Item-canEntityPickup.patch | 0 ...PlayerPickupItemEvent-setFlyAtPlayer.patch | 0 .../0134-PlayerAttemptPickupItemEvent.patch | 0 ...-profile-lookups-to-worldgen-threads.patch | 0 .../0136-Basic-PlayerProfile-API.patch | 0 .../0137-Add-UnknownCommandEvent.patch | 0 .../0138-Shoulder-Entities-Release-API.patch | 0 .../0139-Profile-Lookup-Events.patch | 0 ...player-logins-during-server-shutdown.patch | 0 .../0141-Entity-fromMobSpawner.patch | 0 ...42-Improve-the-Saddle-API-for-Horses.patch | 0 .../0143-ensureServerConversions-API.patch | 0 .../0144-Implement-getI18NDisplayName.patch | 0 .../0145-ProfileWhitelistVerifyEvent.patch | 0 .../0146-Fix-this-stupid-bullshit.patch | 0 .../0147-LivingEntity-setKiller.patch | 0 ...awns-should-honor-nametags-and-leash.patch | 0 ...imer-when-spawner-event-is-cancelled.patch | 0 ...-a-custom-authentication-servers-dow.patch | 0 .../0151-Add-PlayerJumpEvent.patch | 0 ...dle-ServerboundKeepAlivePacket-async.patch | 0 ...nt-protocol-version-and-virtual-host.patch | 0 ...rt-serverside-behavior-of-keepalives.patch | 0 ...dEffects-only-to-players-who-can-see.patch | 0 .../0156-Add-PlayerArmorChangeEvent.patch | 0 ...rom-being-processed-when-the-player-.patch | 0 ...117075-Block-entity-unload-lag-spike.patch | 0 ...e-implementations-for-captured-block.patch | 0 ...-get-a-BlockState-without-a-snapshot.patch | 0 .../0161-AsyncTabCompleteEvent.patch | 0 .../0162-PlayerPickupExperienceEvent.patch | 0 ...3-Ability-to-apply-mending-to-XP-API.patch | 0 ...4-PlayerNaturallySpawnCreaturesEvent.patch | 0 ...-Add-setPlayerProfile-API-for-Skulls.patch | 0 .../0166-PreCreatureSpawnEvent.patch | 0 .../0167-Fill-Profile-Property-Events.patch | 0 ...PlayerAdvancementCriterionGrantEvent.patch | 0 .../0169-Add-ArmorStand-Item-Meta.patch | 0 ...-Extend-Player-Interact-cancellation.patch | 0 .../0171-Tameable-getOwnerUniqueId-API.patch | 0 .../0172-Toggleable-player-crits.patch | 0 ...le-Explicit-Network-Manager-Flushing.patch | 0 ...nt-extended-PaperServerListPingEvent.patch | 0 ...dd-more-fields-to-AsyncPreLoginEvent.patch | 0 .../0176-Player.setPlayerProfile-API.patch | 0 .../0177-getPlayerUniqueId-API.patch | 0 .../0178-Improved-Async-Task-Scheduler.patch | 0 ...ke-legacy-ping-handler-more-reliable.patch | 0 ...ServerListPingEvent-for-legacy-pings.patch | 0 ...81-Flag-to-disable-the-channel-limit.patch | 0 ...2-Add-openSign-method-to-HumanEntity.patch | 0 ...urable-sprint-interruption-on-attack.patch | 0 .../0184-EndermanEscapeEvent.patch | 0 .../0185-Enderman.teleportRandomly.patch | 0 ...0186-Block-Enderpearl-Travel-Exploit.patch | 0 ...ld.spawnParticle-API-and-add-Builder.patch | 0 ...-allowed-colored-signs-to-be-created.patch | 0 .../0189-EndermanAttackPlayerEvent.patch | 0 .../0190-WitchConsumePotionEvent.patch | 0 .../0191-WitchThrowPotionEvent.patch | 0 .../0192-WitchReadyPotionEvent.patch | 0 ...0193-ItemStack-getMaxItemUseDuration.patch | 0 ...94-Add-EntityTeleportEndGatewayEvent.patch | 0 ...ed-flag-on-cancel-of-Explosion-Event.patch | 0 .../0196-Fix-CraftEntity-hashCode.patch | 0 ...7-Configurable-LootPool-luck-formula.patch | 0 ...ils-when-failing-to-save-player-data.patch | 0 ...e-shield-blocking-delay-configurable.patch | 0 .../0200-Improve-EntityShootBowEvent.patch | 0 .../0201-PlayerReadyArrowEvent.patch | 0 .../0202-Add-entity-knockback-events.patch | 0 .../0203-Expand-Explosions-API.patch | 0 .../0204-LivingEntity-Active-Item-API.patch | 0 .../0205-RangedEntity-API.patch | 0 ...to-disable-ender-dragon-legacy-check.patch | 0 ...7-Implement-World.getEntity-UUID-API.patch | 0 .../0208-InventoryCloseEvent-Reason-API.patch | 0 .../0209-Vex-get-setSummoner-API.patch | 0 ...-more-information-to-Entity.toString.patch | 0 .../0211-EnderDragon-Events.patch | 0 .../0212-PlayerElytraBoostEvent.patch | 0 .../0213-PlayerLaunchProjectileEvent.patch | 0 .../0214-Improve-BlockPosition-inlining.patch | 0 ...t-armor-stands-from-doing-entity-loo.patch | 0 ...6-Vanished-players-don-t-have-rights.patch | 0 ...-Allow-disabling-armor-stand-ticking.patch | 0 .../0218-SkeletonHorse-Additions.patch | 0 .../0219-Expand-ArmorStand-API.patch | 0 .../0220-AnvilDamageEvent.patch | 0 .../0221-Add-TNTPrimeEvent.patch | 0 ...nd-make-tab-spam-limits-configurable.patch | 0 .../0223-Fix-NBT-type-issues.patch | 0 ...Remove-unnecessary-itemmeta-handling.patch | 0 ...ies-option-to-debug-dupe-uuid-issues.patch | 0 ...dd-Early-Warning-Feature-to-WatchDog.patch | 0 ...27-Use-ConcurrentHashMap-in-JsonList.patch | 0 ...28-Use-a-Queue-for-Queueing-Commands.patch | 0 ...lock-entities-from-a-chunk-without-s.patch | 0 ...ptimize-BlockPosition-helper-methods.patch | 0 ...default-mob-spawn-range-and-water-an.patch | 0 .../0232-Slime-Pathfinder-Events.patch | 0 ...le-speed-for-water-flowing-over-lava.patch | 0 ...234-Optimize-CraftBlockData-Creation.patch | 0 .../0235-Optimize-MappedRegistry.patch | 0 .../0236-Add-PhantomPreSpawnEvent.patch | 0 .../0237-Add-More-Creeper-API.patch | 0 .../0238-Inventory-removeItemAnySlot.patch | 0 ...loadChunk-int-int-false-load-unconve.patch | 0 ...-ray-tracing-methods-to-LivingEntity.patch | 0 ...e-attack-cooldown-methods-for-Player.patch | 0 .../0242-Improve-death-events.patch | 0 ...ow-chests-to-be-placed-with-NBT-data.patch | 0 .../0244-Mob-Pathfinding-API.patch | 0 ...interactions-from-causing-chunk-load.patch | 0 ...wning-from-loading-generating-chunks.patch | 0 ...nt-furnace-cook-speed-multiplier-API.patch | 0 .../0248-Honor-EntityAgeable.ageLock.patch | 0 ...ble-connection-throttle-kick-message.patch | 0 ...ent-chunk-loading-from-Fluid-Flowing.patch | 0 .../0251-PreSpawnerSpawnEvent.patch | 0 ...252-Add-LivingEntity-getTargetEntity.patch | 0 .../0253-Add-sun-related-API.patch | 0 .../0254-Turtle-API.patch | 0 ...tator-target-events-and-improve-impl.patch | 0 .../0256-Add-more-Witch-API.patch | 0 ...owned-for-Villager-Aggression-Config.patch | 0 ...event-players-from-moving-into-unloa.patch | 0 ...59-Reset-players-airTicks-on-respawn.patch | 0 ...-after-profile-lookups-if-not-needed.patch | 0 ...er-Thread-Pool-and-Thread-Priorities.patch | 0 .../0262-Optimize-World-Time-Updates.patch | 0 ...store-custom-InventoryHolder-support.patch | 0 .../0264-Fix-SpongeAbsortEvent-handling.patch | 0 ...t-allow-digging-into-unloaded-chunks.patch | 0 ...ault-permission-message-configurable.patch | 0 ...entity-dismount-during-teleportation.patch | 0 .../0268-Add-more-Zombie-API.patch | 0 .../0269-Book-size-limits.patch | 0 .../0270-Add-PlayerConnectionCloseEvent.patch | 0 ...-Replace-OfflinePlayer-getLastPlayed.patch | 0 ...vehicle-tracking-issue-on-disconnect.patch | 0 ...r-remove-if-the-handle-is-a-custom-p.patch | 0 .../0274-BlockDestroyEvent.patch | 0 .../0275-Async-command-map-building.patch | 0 .../0276-Brigadier-Mojang-API.patch | 0 ...rove-exact-choice-recipe-ingredients.patch | 0 .../0278-Limit-Client-Sign-length-more.patch | 0 ...oggleEvent-when-whitelist-is-toggled.patch | 0 ...nd-additions-to-the-spawn-reason-API.patch | 0 .../0281-Fire-event-on-GS4-query.patch | 0 .../0282-Add-PlayerPostRespawnEvent.patch | 0 .../0283-Server-Tick-Events.patch | 0 ...0284-PlayerDeathEvent-getItemsToKeep.patch | 0 ...Optimize-Captured-BlockEntity-Lookup.patch | 0 .../0286-Mob-Spawner-API-Enhancements.patch | 0 ...l-to-changed-postToMainThread-method.patch | 0 ...n-item-frames-are-modified-MC-123450.patch | 0 .../0289-Implement-CraftBlockSoundGroup.patch | 0 ...290-Expose-the-internal-current-tick.patch | 0 ...ate-location-if-we-failed-to-read-it.patch | 0 ...al-Spawned-mobs-towards-natural-spaw.patch | 0 ...gurable-projectile-relative-velocity.patch | 0 .../0294-offset-item-frame-ticking.patch | 0 ...revent-consuming-the-wrong-itemstack.patch | 0 ...96-Dont-send-unnecessary-sign-update.patch | 0 ...d-option-to-disable-pillager-patrols.patch | 0 ...nk-loads-when-villagers-try-to-find-.patch | 0 ...5656-Fix-Follow-Range-Initial-Target.patch | 0 .../0300-Duplicate-UUID-Resolve-Option.patch | 0 ...layerDeathEvent-shouldDropExperience.patch | 0 ...oading-chunks-checking-hive-position.patch | 0 ...Chunks-from-Hoppers-and-other-things.patch | 0 ...ptimise-EntityGetter-getPlayerByUUID.patch | 0 ...0305-Fix-items-not-falling-correctly.patch | 0 ...mize-call-to-getFluid-for-explosions.patch | 0 ...rializing-mismatching-chunk-coordina.patch | 0 .../0308-Alternative-item-despawn-rate.patch | 0 .../0309-Tracking-Range-Improvements.patch | 0 ...get-gravity-in-void.-Fixes-MC-167279.patch | 0 ...311-Improve-Block-breakNaturally-API.patch | 0 ...e-getChunkAt-calls-for-loaded-chunks.patch | 0 .../0313-Add-debug-for-sync-chunk-loads.patch | 0 .../0314-Improve-java-version-check.patch | 0 .../0315-Add-ThrownEggHatchEvent.patch | 0 .../0316-Entity-Jump-API.patch | 0 ...n-to-nerf-pigmen-from-nether-portals.patch | 0 .../0318-Make-the-GUI-graph-fancier.patch | 0 ...319-add-hand-to-BlockMultiPlaceEvent.patch | 0 ...ripwire-hook-placement-before-update.patch | 0 ...to-allow-iron-golems-to-spawn-in-air.patch | 0 ...-chance-of-villager-zombie-infection.patch | 0 .../0323-Optimise-Chunk-getFluid.patch | 0 ...erbose-world-setting-to-false-by-def.patch | 0 ...-Add-tick-times-API-and-mspt-command.patch | 0 ...326-Expose-MinecraftServer-isRunning.patch | 0 ...Add-Raw-Byte-ItemStack-Serialization.patch | 0 ...spawn-settings-and-per-player-option.patch | 0 ...nnections-shouldn-t-hold-up-shutdown.patch | 0 ...low-bees-to-load-chunks-for-beehives.patch | 0 ...-PlayerChunkMap-adds-crashing-server.patch | 0 .../0332-Don-t-tick-dead-players.patch | 0 ...d-Player-s-shouldn-t-be-able-to-move.patch | 0 ...move-existing-players-to-world-spawn.patch | 0 .../0335-Optimize-Pathfinding.patch | 0 ...36-Reduce-Either-Optional-allocation.patch | 0 ...duce-memory-footprint-of-CompoundTag.patch | 0 ...vent-opening-inventories-when-frozen.patch | 0 ...-entity-collision-code-if-not-needed.patch | 0 ...-Implement-Player-Client-Options-API.patch | 0 ...layer-is-attempted-to-be-removed-fro.patch | 0 ...nEvent-when-Player-is-actually-ready.patch | 0 ...pawn-point-if-spawn-in-unloaded-worl.patch | 0 ...PlayerAttackEntityCooldownResetEvent.patch | 0 ...t-fire-BlockFade-on-worldgen-threads.patch | 0 ...ntom-creative-and-insomniac-controls.patch | 0 ...item-duplication-and-teleport-issues.patch | 0 .../0348-Villager-Restocks-API.patch | 0 ...PickItem-Packet-and-kick-for-invalid.patch | 0 ...-per-thread-native-byte-buffer-cache.patch | 0 .../0351-misc-debugging-dumps.patch | 0 ...52-Prevent-teleporting-dead-entities.patch | 0 .../0353-Implement-Mob-Goal-API.patch | 0 .../0354-Add-villager-reputation-API.patch | 0 ...ceOrb-merging-stacking-API-and-fixes.patch | 0 ...6-Fix-PotionEffect-ignores-icon-flag.patch | 0 .../0357-Potential-bed-API.patch | 0 ...Wait-for-Async-Tasks-during-shutdown.patch | 0 ...der-respects-game-and-entity-rules-f.patch | 0 ...n-for-console-having-all-permissions.patch | 0 ...ix-villager-trading-demand-MC-163962.patch | 0 .../0362-Maps-shouldn-t-load-chunks.patch | 0 ...ookup-for-Treasure-Maps-Fixes-lag-fr.patch | 0 ...er-runTaskTimerAsynchronously-Plugin.patch | 0 ...ston-physics-inconsistency-MC-188840.patch | 0 ...ssing-chunks-due-to-integer-overflow.patch | 0 ...t-position-desync-causing-tp-exploit.patch | 0 ...Holder-method-without-block-snapshot.patch | 0 .../0369-Add-PlayerRecipeBookClickEvent.patch | 0 ...0-Hide-sync-chunk-writes-behind-flag.patch | 0 ...71-Add-permission-for-command-blocks.patch | 0 ...-position-and-AABB-are-never-invalid.patch | 0 ...ld-Difficulty-Remembering-Difficulty.patch | 0 .../0374-Paper-dumpitem-command.patch | 0 ...-Legacy-Component-serialization-size.patch | 0 ...-Plugin-Tickets-to-API-Chunk-Methods.patch | 0 ...7-Add-BlockStateMeta-clearBlockState.patch | 0 ...nvert-legacy-attributes-in-Item-Meta.patch | 0 ...o-not-accept-invalid-client-settings.patch | 0 ...ve-fix-EntityTargetLivingEntityEvent.patch | 0 .../0381-Add-entity-liquid-API.patch | 0 .../0382-Add-PrepareResultEvent.patch | 0 ...k-for-portal-on-world-gen-entity-add.patch | 0 ...ix-arrows-never-despawning-MC-125757.patch | 0 ...-Vanilla-Command-permission-checking.patch | 0 ...4-Bukkit-world-container-is-not-used.patch | 0 ...-5885-Unable-to-disable-advancements.patch | 0 ...ataPlayer-leak-due-from-quitting-ear.patch | 0 ...ze-NetworkManager-Exception-Handling.patch | 0 ...Fix-some-rails-connecting-improperly.patch | 0 ...istake-in-CB-NBT-int-deserialization.patch | 0 .../0392-Brand-support.patch | 0 ...yPickupItemAnimation-to-LivingEntity.patch | 0 .../0394-Don-t-require-FACING-data.patch | 0 ...geEvent-not-firing-for-all-use-cases.patch | 0 .../0396-Add-moon-phase-API.patch | 0 ...erver-load-chunks-from-newer-version.patch | 0 ...-headless-pistons-from-being-created.patch | 0 .../0399-Add-BellRingEvent.patch | 0 ...Add-zombie-targets-turtle-egg-config.patch | 0 .../0401-Buffer-joins-to-world.patch | 0 ...rs-not-working-in-some-kick-messages.patch | 0 .../0403-Add-more-Evoker-API.patch | 0 ...-Add-methods-to-get-translation-keys.patch | 0 ...ate-HoverEvent-from-ItemStack-Entity.patch | 0 .../0406-Cache-block-data-strings.patch | 0 ...ortation-and-cancel-velocity-if-tele.patch | 0 ...al-open-container-api-to-HumanEntity.patch | 0 ...taFixerUpper-Rewrite-Rules-on-demand.patch | 0 ...p-capture-to-capture-all-items-added.patch | 0 ...y-Counter-to-allow-plugins-to-use-va.patch | 0 ...-track-plugin-scoreboards-by-default.patch | 0 .../0413-Entity-isTicking.patch | 0 ...-non-whitelisted-player-when-white-l.patch | 0 ...x-Concurrency-issue-in-ShufflingList.patch | 0 ...Reset-Ender-Crystals-on-Dragon-Spawn.patch | 0 ...r-large-move-vectors-crashing-server.patch | 0 .../0418-Optimise-getType-calls.patch | 0 .../0419-Villager-resetOffers.patch | 0 ...ace-order-when-capturing-blockstates.patch | 0 ...tem-locations-dropped-from-campfires.patch | 0 ...22-Fix-bell-block-entity-memory-leak.patch | 0 ...ling-up-when-item-stack-is-empty-in-.patch | 0 ...-Add-getOfflinePlayerIfCached-String.patch | 0 .../0425-Add-ignore-discounts-API.patch | 0 ...-Toggle-for-removing-existing-dragon.patch | 0 ...ix-client-lag-on-advancement-loading.patch | 0 .../0428-Item-no-age-no-player-pickup.patch | 0 ...0429-Beacon-API-custom-effect-ranges.patch | 0 .../0430-Add-API-for-quit-reason.patch | 0 ...ing-Trader-spawn-rate-config-options.patch | 0 .../0432-Add-Destroy-Speed-API.patch | 0 ...r-spawnParticle-x-y-z-precision-loss.patch | 0 ...434-Add-LivingEntity-clearActiveItem.patch | 0 .../0435-Add-PlayerItemCooldownEvent.patch | 0 ...prove-performance-of-the-end-generat.patch | 0 .../0437-More-lightning-API.patch | 0 ...-should-not-bypass-cramming-gamerule.patch | 0 ...d-missing-default-perms-for-commands.patch | 0 .../0440-Add-PlayerShearBlockEvent.patch | 0 .../0441-Limit-recipe-packets.patch | 0 ...x-CraftSound-backwards-compatibility.patch | 0 ...0443-Player-Chunk-Load-Unload-Events.patch | 0 ...44-Optimize-Dynamic-get-Missing-Keys.patch | 0 ...5-Expose-LivingEntity-hurt-direction.patch | 0 ...-OBSTRUCTED-reason-to-BedEnterResult.patch | 0 ...nvalid-ingredient-lists-in-VillagerA.patch | 0 .../0448-Add-TargetHitEvent.patch | 0 .../0449-MC-4-Fix-item-position-desync.patch | 0 .../0450-Additional-Block-Material-API.patch | 0 .../0451-Fix-harming-potion-dupe.patch | 0 ...et-Material-from-Boats-and-Minecarts.patch | 0 ...mob-spawner-spawn-egg-transformation.patch | 0 ...Fix-Not-a-string-Map-Conversion-spam.patch | 0 ...5-Add-PlayerFlowerPotManipulateEvent.patch | 0 ...act-event-not-being-called-sometimes.patch | 0 .../0457-Zombie-API-breaking-doors.patch | 0 ...0458-Fix-nerfed-slime-when-splitting.patch | 0 .../0459-Add-EntityLoadCrossbowEvent.patch | 0 .../0460-Add-WorldGameRuleChangeEvent.patch | 0 ...461-Add-ServerResourcesReloadedEvent.patch | 0 ...ld-settings-for-mobs-picking-up-loot.patch | 0 .../0463-Add-BlockFailedDispenseEvent.patch | 0 ...464-Add-PlayerLecternPageChangeEvent.patch | 0 ...465-Add-PlayerLoomPatternSelectEvent.patch | 0 ...onfigurable-door-breaking-difficulty.patch | 0 ...pty-commands-shall-not-be-dispatched.patch | 0 .../0468-Remove-stale-POIs.patch | 0 .../0469-Fix-villager-boat-exploit.patch | 0 .../0470-Add-sendOpLevel-API.patch | 0 ...gistryAccess-for-managing-Registries.patch | 0 .../0472-Add-StructuresLocateEvent.patch | 0 ...n-for-requiring-a-player-participant.patch | 0 ...onent-with-empty-text-instead-of-thr.patch | 0 ...0475-Make-schedule-command-per-world.patch | 0 ...0476-Configurable-max-leash-distance.patch | 0 .../0477-Add-BlockPreDispenseEvent.patch | 0 ...78-Add-PlayerChangeBeaconEffectEvent.patch | 0 ...le-for-always-placing-the-dragon-egg.patch | 0 ...d-PlayerStonecutterRecipeSelectEvent.patch | 0 .../0481-Expand-EntityUnleashEvent.patch | 0 ...-shield-blocking-on-dimension-change.patch | 0 .../0483-Add-DragonEggFormEvent.patch | 0 .../0484-Add-EntityMoveEvent.patch | 0 ...disable-pathfinding-updates-on-block.patch | 0 .../0486-Inline-shift-direction-fields.patch | 0 ...w-adding-items-to-BlockDropItemEvent.patch | 0 ...ainThreadExecutor-to-BukkitScheduler.patch | 0 ...-entity-allow-attribute-registration.patch | 0 ...fix-dead-slime-setSize-invincibility.patch | 0 ...ipes-should-return-an-immutable-list.patch | 0 .../0492-Expose-Tracked-Players.patch | 0 .../0493-Improve-ServerGUI.patch | 0 ...0494-fix-converting-txt-to-json-file.patch | 0 .../0495-Add-worldborder-events.patch | 0 .../0496-Add-PlayerNameEntityEvent.patch | 0 .../0497-Add-recipe-to-cook-events.patch | 0 .../0498-Add-Block-isValidTool.patch | 0 ...-using-signs-inside-spawn-protection.patch | 0 .../0500-Expand-world-key-API.patch | 0 ...lternative-constructor-for-Rotations.patch | 0 ...ed-item-when-player-has-disconnected.patch | 0 ...telist-use-configurable-kick-message.patch | 0 ...ignore-result-of-PlayerEditBookEvent.patch | 0 .../0505-Expose-protocol-version.patch | 0 ...tab-completions-for-brigadier-comman.patch | 0 ...ItemConsumeEvent-cancelling-properly.patch | 0 .../0508-Add-bypass-host-check.patch | 0 .../0509-Set-area-affect-cloud-rotation.patch | 0 ...-add-isDeeplySleeping-to-HumanEntity.patch | 0 ...-add-consumeFuel-to-FurnaceBurnEvent.patch | 0 ...t-set-drop-chance-to-EntityEquipment.patch | 0 ...fix-PigZombieAngerEvent-cancellation.patch | 0 ...fix-PlayerItemHeldEvent-firing-twice.patch | 0 .../0515-Add-PlayerDeepSleepEvent.patch | 0 .../0516-More-World-API.patch | 0 .../0517-Add-PlayerBedFailEnterEvent.patch | 0 ...s-to-convert-between-Component-and-B.patch | 0 ...pawnEvent-fix-passed-parameter-issue.patch | 0 ...eacon-activation-deactivation-events.patch | 0 ...Add-Channel-initialization-listeners.patch | 0 ...mmands-if-tab-completion-is-disabled.patch | 0 .../0523-Add-more-WanderingTrader-API.patch | 0 ...Add-EntityBlockStorage-clearEntities.patch | 0 ...essage-to-PlayerAdvancementDoneEvent.patch | 0 .../0526-Add-HiddenPotionEffect-API.patch | 0 .../0527-Inventory-close.patch | 0 ...n-in-sunlight-API-for-Phantoms-and-S.patch | 0 .../0529-Add-basic-Datapack-API.patch | 0 ...nment-variable-to-disable-server-gui.patch | 0 ...531-Expand-PlayerGameModeChangeEvent.patch | 0 .../0532-ItemStack-repair-check-API.patch | 0 .../0533-More-Enchantment-API.patch | 0 ...ove-range-check-for-block-placing-up.patch | 0 .../0535-Add-Mob-lookAt-API.patch | 0 ...if-bucket-dispenses-will-succeed-for.patch | 0 .../0537-Add-Unix-domain-socket-support.patch | 0 .../0538-Add-EntityInsideBlockEvent.patch | 0 ...9-Improve-item-default-attribute-API.patch | 0 ...cause-to-Weather-ThunderChangeEvents.patch | 0 .../0541-More-Lidded-Block-API.patch | 0 ...542-Limit-item-frame-cursors-on-maps.patch | 0 .../0543-Add-PlayerKickEvent-causes.patch | 0 .../0544-Add-PufferFishStateChangeEvent.patch | 0 ...yerBucketEmptyEvent-result-itemstack.patch | 0 ...ttedContainer-instead-of-ThreadingDe.patch | 0 ...n-to-fix-items-merging-through-walls.patch | 0 .../0548-Add-BellRevealRaiderEvent.patch | 0 .../0549-Fix-invulnerable-end-crystals.patch | 0 ...550-Add-ElderGuardianAppearanceEvent.patch | 0 ...e-Biome-Mob-Lookups-for-Mob-Spawning.patch | 0 .../0552-Line-Of-Sight-Changes.patch | 0 .../0553-add-per-world-spawn-limits.patch | 0 .../0554-Fix-potions-splash-events.patch | 0 .../0555-Add-more-LimitedRegion-API.patch | 0 ...PlayerDropItemEvent-using-wrong-item.patch | 0 .../0557-Missing-Entity-API.patch | 0 ...-of-Block-applyBoneMeal-always-being.patch | 0 ...etChunkIfLoadedImmediately-in-places.patch | 0 ...from-signs-not-firing-command-events.patch | 0 .../0561-Add-PlayerArmSwingEvent.patch | 0 ...k-event-leave-message-not-being-sent.patch | 0 ...n-t-apply-cramming-damage-to-players.patch | 0 ...nd-timings-for-sensors-and-behaviors.patch | 0 .../0565-Add-missing-forceDrop-toggles.patch | 0 .../0566-Stinger-API.patch | 0 .../0567-Add-System.out-err-catcher.patch | 0 ...-AFK-kick-while-watching-end-credits.patch | 0 ...riting-of-comments-to-server.propert.patch | 0 .../0570-Add-PlayerSetSpawnEvent.patch | 0 ...ers-respect-inventory-max-stack-size.patch | 0 ...mize-entity-tracker-passenger-checks.patch | 0 ...g-option-for-Piglins-guarding-chests.patch | 0 .../0574-Add-EntityDamageItemEvent.patch | 0 ...ptimize-indirect-passenger-iteration.patch | 0 ...tem-frame-map-cursor-update-interval.patch | 0 ...target-without-changing-other-things.patch | 0 .../0578-Add-BlockBreakBlockEvent.patch | 0 ...t-data-components-copy-in-smithing-r.patch | 0 .../0580-More-CommandBlock-API.patch | 0 ...d-missing-team-sidebar-display-slots.patch | 0 .../0582-Add-back-EntityPortalExitEvent.patch | 0 ...o-find-targets-for-lightning-strikes.patch | 0 .../0584-Get-entity-default-attributes.patch | 0 .../0585-Left-handed-API.patch | 0 .../0586-Add-more-advancement-API.patch | 0 ...0587-Add-ItemFactory-getSpawnEgg-API.patch | 0 .../0588-Add-critical-damage-API.patch | 0 .../0589-Fix-issues-with-mob-conversion.patch | 0 ...sCollision-methods-to-various-places.patch | 0 .../0591-Goat-ram-API.patch | 0 ...Add-API-for-resetting-a-single-score.patch | 0 ...93-Add-Raw-Byte-Entity-Serialization.patch | 0 ...594-Vanilla-command-permission-fixes.patch | 0 ...-logic-for-inventories-on-chunk-unlo.patch | 0 ...596-Fix-GameProfileCache-concurrency.patch | 0 ...0597-Improve-and-expand-AsyncCatcher.patch | 0 ...aper-mobcaps-and-paper-playermobcaps.patch | 0 ...itize-ResourceLocation-error-logging.patch | 0 ...ally-inline-methods-in-BlockPosition.patch | 0 ...uler-threads-according-to-the-plugin.patch | 0 ...d-getChunkAt-has-inlined-logic-for-l.patch | 0 ...bour-chunk-data-off-disk-when-conver.patch | 0 ...id-state-when-raytracing-skip-air-bl.patch | 0 .../0605-Time-scoreboard-search.patch | 0 ...primise-map-impl-for-tracked-players.patch | 0 .../0607-Add-missing-InventoryType.patch | 0 ...timise-BlockSoil-nearby-water-lookup.patch | 0 ...entory-not-closing-on-entity-removal.patch | 0 ...irement-before-suggesting-root-nodes.patch | 0 ...-ServerboundCommandSuggestionPacket-.patch | 0 .../0612-Add-packet-limiter-config.patch | 0 ...rnColor-on-tropical-fish-bucket-meta.patch | 0 .../0614-Ensure-valid-vehicle-status.patch | 0 ...oftlocked-end-exit-portal-generation.patch | 0 ...or-causing-a-crash-when-trying-to-ge.patch | 0 ...n-t-log-debug-logging-being-disabled.patch | 0 ...ious-menus-with-empty-level-accesses.patch | 0 .../0619-Preserve-overstacked-loot.patch | 0 ...date-head-rotation-in-missing-places.patch | 0 ...-unintended-light-block-manipulation.patch | 0 .../0622-Fix-CraftCriteria-defaults-map.patch | 0 ...-Fix-upstreams-block-state-factories.patch | 0 .../0624-Configurable-feature-seeds.patch | 0 .../0625-Add-root-admin-user-detection.patch | 0 ...-t-attempt-to-teleport-dead-entities.patch | 0 ...sive-velocity-through-repeated-crits.patch | 0 ...de-code-using-deprecated-for-removal.patch | 0 .../0629-Fix-Spigot-growth-modifiers.patch | 0 ...rOpenersCounter-openCount-from-going.patch | 0 .../0631-Add-PlayerItemFrameChangeEvent.patch | 0 .../0632-Optimize-HashMapPalette.patch | 0 ...t-isSectionEmpty-int-and-optimize-Pa.patch | 0 .../0634-Add-more-Campfire-API.patch | 0 ...-data-to-disk-if-it-serializes-witho.patch | 0 ...ward-CraftEntity-in-teleport-command.patch | 0 .../0637-Improve-scoreboard-entries.patch | 0 .../0638-Entity-powdered-snow-API.patch | 0 .../0639-Add-API-for-item-entity-health.patch | 0 ...max-block-light-for-monster-spawning.patch | 0 ...-pistons-and-BlockPistonRetractEvent.patch | 0 ...d-canSmelt-methods-to-FurnaceInvento.patch | 0 .../0643-Bucketable-API.patch | 0 .../0644-Validate-usernames.patch | 0 ...ter-animal-spawn-height-configurable.patch | 0 ...vanilla-BiomeProvider-from-WorldInfo.patch | 0 ...tion-for-worlds-affected-by-time-cmd.patch | 0 ...check-for-PersistentDataContainer-ha.patch | 0 ...49-Multiple-Entries-with-Scoreboards.patch | 0 ...0650-Reset-placed-block-on-exception.patch | 0 ...-configurable-height-for-slime-spawn.patch | 0 .../0652-Fix-xp-reward-for-baby-zombies.patch | 0 ...ulti-Block-Change-API-Implementation.patch | 0 .../0654-Fix-NotePlayEvent.patch | 0 .../0655-Freeze-Tick-Lock-API.patch | 0 .../0656-More-PotionEffectType-API.patch | 0 ...-for-StructureTemplate.Pallete-cache.patch | 0 ...-command-sender-which-forwards-feedb.patch | 0 ...d-missing-structure-set-seed-configs.patch | 0 ...elled-powdered-snow-bucket-placement.patch | 0 ...date-calls-to-CraftServer-getSpawnLi.patch | 0 .../0662-Add-GameEvent-tags.patch | 0 ...sks-fairly-for-worlds-while-waiting-.patch | 0 .../0664-Furnace-RecipesUsed-API.patch | 0 ...igurable-sculk-sensor-listener-range.patch | 0 .../0666-Add-missing-block-data-API.patch | 0 ...efault-CustomSpawners-in-custom-worl.patch | 0 ...o-worldlist-before-initing-the-world.patch | 0 .../0669-Custom-Potion-Mixes.patch | 0 ...670-Force-close-world-loading-screen.patch | 0 ...0671-Fix-falling-block-spawn-methods.patch | 0 ...-Expose-furnace-minecart-push-values.patch | 0 ...rojectileHitEvent-for-piercing-arrow.patch | 0 .../0674-More-Projectile-API.patch | 0 ...ix-swamp-hut-cat-generation-deadlock.patch | 0 ...cle-movement-from-players-while-tele.patch | 0 .../0677-Implement-getComputedBiome-API.patch | 0 .../0678-Make-some-itemstacks-nonnull.patch | 0 ...0679-Implement-enchantWithLevels-API.patch | 0 .../0680-Fix-saving-in-unloadWorld.patch | 0 .../0681-Buffer-OOB-setBlock-calls.patch | 0 .../0682-Add-TameableDeathMessageEvent.patch | 0 ...lock-data-for-EntityChangeBlockEvent.patch | 0 ...ables-running-when-mob-loot-gamerule.patch | 0 ...assenger-world-matches-ridden-entity.patch | 0 ...eys-and-optimize-reference-Holder-ta.patch | 0 ...llow-changing-the-EnderDragon-podium.patch | 0 ...verriding-a-block-entity-during-worl.patch | 0 ...nt-tile-entity-copies-loading-chunks.patch | 0 ...tead-of-display-name-in-PlayerList-g.patch | 0 .../0691-Expand-PlayerItemDamageEvent.patch | 0 .../0692-WorldCreator-keepSpawnLoaded.patch | 0 ...E-in-CraftPersistentDataTypeRegistry.patch | 0 ..._destroyed-trigger-in-the-correct-pl.patch | 0 ...eEvent-and-CollarColorable-interface.patch | 0 ...-CauldronLevelChange-on-initial-fill.patch | 0 ...-snow-cauldrons-not-turning-to-water.patch | 0 .../0698-Add-PlayerStopUsingItemEvent.patch | 0 .../0699-Don-t-tick-markers.patch | 0 .../0700-Expand-FallingBlock-API.patch | 0 .../0701-Add-support-for-Proxy-Protocol.patch | 0 ...ix-OfflinePlayer-getBedSpawnLocation.patch | 0 ...ntory-for-smokers-and-blast-furnaces.patch | 0 .../0704-Sanitize-sent-BlockEntity-NBT.patch | 0 ...t-selector-resolving-in-books-by-def.patch | 0 ...entity-loading-causing-async-lookups.patch | 0 ...n-on-world-create-while-being-ticked.patch | 0 ...708-Dont-resent-entity-on-art-update.patch | 0 .../0709-Add-WardenAngerChangeEvent.patch | 0 ...-strict-advancement-dimension-checks.patch | 0 ...rtant-BlockStateListPopulator-method.patch | 0 .../0712-Nameable-Banner-API.patch | 0 ...broadcast-messages-to-command-blocks.patch | 0 ...mpty-items-from-being-added-to-world.patch | 0 ...shPotion-and-LingeringPotion-spawnin.patch | 0 .../0716-Add-Player-getFishHook.patch | 0 ...-chunk-for-dynamic-game-event-listen.patch | 0 ...us-missing-EntityDropItemEvent-calls.patch | 0 .../0719-Fix-Bee-flower-NPE.patch | 0 ...g-not-using-commands.spam-exclusions.patch | 0 .../0721-More-Teleport-API.patch | 0 .../0722-Add-EntityPortalReadyEvent.patch | 0 ...-level-random-in-entity-constructors.patch | 0 ...ck-entities-after-destroy-prediction.patch | 0 ...-on-plugins-accessing-faraway-chunks.patch | 0 ...stom-Chat-Completion-Suggestions-API.patch | 0 ...-Add-and-fix-missing-BlockFadeEvents.patch | 0 .../0728-Collision-API.patch | 0 ...and-message-for-brigadier-syntax-exc.patch | 0 .../0730-Block-Ticking-API.patch | 0 ...1-Add-Velocity-IP-Forwarding-Support.patch | 0 ...0732-Add-NamespacedKey-biome-methods.patch | 0 ...ix-plugin-loggers-on-server-shutdown.patch | 0 ...ook-changes-from-crashing-the-server.patch | 0 ...ntityChangeBlockEvent-in-more-places.patch | 0 .../0736-Missing-eating-regain-reason.patch | 0 .../0737-Missing-effect-cause.patch | 0 ...-serialization-deserialization-for-P.patch | 0 ...39-Call-BlockPhysicsEvent-more-often.patch | 0 .../0740-Configurable-chat-thread-limit.patch | 0 ...-of-WorldCreator-keepSpawnLoaded-ret.patch | 0 .../0742-fix-Jigsaw-block-kicking-user.patch | 0 ...rmEvent-for-mud-converting-into-clay.patch | 0 .../0744-Add-getDrops-to-BlockState.patch | 0 .../0745-Fix-a-bunch-of-vanilla-bugs.patch | 0 ...ry-onTrackingStart-during-navigation.patch | 0 .../0747-Fix-custom-piglin-loved-items.patch | 0 .../0748-EntityPickupItemEvent-fixes.patch | 0 ...-interactions-with-items-on-cooldown.patch | 0 ...0-Add-PlayerInventorySlotChangeEvent.patch | 0 .../0751-Elder-Guardian-appearance-API.patch | 0 .../0752-Add-entity-knockback-API.patch | 0 .../0753-Detect-headless-JREs.patch | 0 ...y-vehicle-collision-event-not-called.patch | 0 .../0755-Add-EntityToggleSitEvent.patch | 0 .../0756-Add-fire-tick-delay-option.patch | 0 .../0757-Add-Moving-Piston-API.patch | 0 .../0758-Ignore-impossible-spawn-tick.patch | 0 ...nt-and-EntitySelectorParser-permissi.patch | 0 ...tEvent-cancellation-cant-fully-preve.patch | 0 .../0761-Add-PrePlayerAttackEntityEvent.patch | 0 ...re-reset-EnderDragon-boss-event-name.patch | 0 .../0763-Add-Player-Warden-Warning-API.patch | 0 ...la-friendly-methods-to-update-trades.patch | 0 ...0765-Add-paper-dumplisteners-command.patch | 0 ...global-player-list-where-appropriate.patch | 0 ...async-entity-add-due-to-fungus-trees.patch | 0 .../0768-ItemStack-damage-API.patch | 0 .../0769-Friction-API.patch | 0 ...ntrol-player-s-insomnia-and-phantoms.patch | 0 ...x-premature-player-kicks-on-shutdown.patch | 0 .../0772-Sync-offhand-slot-in-menus.patch | 0 .../0773-Player-Entity-Tracking-Events.patch | 0 .../0774-Limit-pet-look-distance.patch | 0 .../0775-fix-Instruments.patch | 0 ...-for-some-hot-BlockBehavior-and-Flui.patch | 0 ...ies-in-dispense-events-regarding-sta.patch | 0 .../0778-Add-BlockLockCheckEvent.patch | 0 .../0779-Add-Sneaking-API-for-Entities.patch | 0 .../0780-Improve-logging-and-errors.patch | 0 .../0781-Improve-PortalEvents.patch | 0 ...tion-for-spider-worldborder-climbing.patch | 0 ...ssing-SpigotConfig-logCommands-check.patch | 0 ...-Allay-stopDancing-while-not-dancing.patch | 0 .../0785-Flying-Fall-Damage.patch | 0 ...sion-moving-velocity-to-VehicleBlock.patch | 0 ...config-for-disabling-entity-tag-tags.patch | 0 ...le-player-info-update-packet-on-join.patch | 0 ...nk-items-during-EntityResurrectEvent.patch | 0 .../0790-Win-Screen-API.patch | 0 ...tItemStack-setAmount-null-assignment.patch | 0 ...Fix-force-opening-enchantment-tables.patch | 0 .../0793-Add-Entity-Body-Yaw-API.patch | 0 ...event-sleeping-villagers-moving-towa.patch | 0 .../0795-Add-EntityFertilizeEggEvent.patch | 0 ...ity-drop-not-updating-the-client-inv.patch | 0 ...ItemEvent-and-EntityCompostItemEvent.patch | 0 ...ectly-handle-ArmorStand-invisibility.patch | 0 ...vancement-triggers-for-entity-damage.patch | 0 ...0800-Fix-text-display-error-on-spawn.patch | 0 ...inventories-returning-null-Locations.patch | 0 .../0802-Add-Shearable-API.patch | 0 ...-Fix-SpawnEggMeta-get-setSpawnedType.patch | 0 ...ng-to-bad-recipes-in-furnace-like-ti.patch | 0 ...uence-violations-like-they-should-be.patch | 0 ...expired-keys-from-impacting-new-join.patch | 0 ...nts-being-fired-from-unloaded-chunks.patch | 0 .../0808-Use-array-for-gamerule-storage.patch | 0 ...-Fix-a-couple-of-upstream-bed-issues.patch | 0 ...Fix-demo-flag-not-enabling-demo-mode.patch | 0 .../0811-Add-Mob-Experience-reward-API.patch | 0 ...-redstone-on-top-of-trap-doors-early.patch | 0 ...-Lazy-Initialization-for-Enum-Fields.patch | 0 ...814-More-accurate-isInOpenWater-impl.patch | 0 .../0815-Expand-PlayerItemMendEvent.patch | 0 ...esh-ProjectileSource-for-projectiles.patch | 0 .../0817-Add-transient-modifier-API.patch | 0 .../0818-Fix-block-place-logic.patch | 0 ...und-playing-for-BlockItem-ItemStacks.patch | 0 ...ll-BlockGrowEvent-for-missing-blocks.patch | 0 ...anhasbukkit-default-if-alias-block-e.patch | 0 ...apLike-spam-for-missing-key-selector.patch | 0 ...3-Fix-sniffer-removeExploredLocation.patch | 0 ...-to-remove-all-active-potion-effects.patch | 0 ...crafting-result-amount-for-fireworks.patch | 0 ...26-Add-event-for-player-editing-sign.patch | 0 ...ck-item-frames-if-players-can-see-it.patch | 0 ...permission-levels-for-command-blocks.patch | 0 ...-Add-option-to-disable-block-updates.patch | 0 ...0830-Call-missing-BlockDispenseEvent.patch | 0 ...d-chunks-for-supporting-block-checks.patch | 0 ...-Optimize-player-lookups-for-beacons.patch | 0 .../0833-More-Sign-Block-API.patch | 0 ...34-fix-item-meta-for-tadpole-buckets.patch | 0 .../0835-Fix-BanList-API.patch | 0 ...nd-water-fluid-explosion-resistance-.patch | 0 ...ix-possible-NPE-on-painting-creation.patch | 0 ...Timer-for-Wandering-Traders-spawned-.patch | 0 ...enceOrb-should-call-EntitySpawnEvent.patch | 0 ...st-throw-both-Spread-and-Grow-Events.patch | 0 .../0841-Add-whitelist-events.patch | 0 .../0842-Implement-PlayerFailMoveEvent.patch | 0 ...Folia-scheduler-and-owned-region-API.patch | 0 ...ase-allay-memory-on-non-item-targets.patch | 0 ...-API-for-updating-recipes-on-clients.patch | 0 ...ation-when-spawning-display-entities.patch | 0 ...0847-Only-capture-actual-tree-growth.patch | 0 ...urce-for-mushroom-block-spread-event.patch | 0 ...eData-on-more-entities-when-spawning.patch | 0 ...0-Use-correct-seed-on-api-world-load.patch | 0 ...ata-neighbour-ticks-outside-of-range.patch | 0 .../0852-Cache-map-ids-on-item-frames.patch | 0 ...x-custom-statistic-criteria-creation.patch | 0 .../0854-Bandaid-fix-for-Effect.patch | 0 .../0855-SculkCatalyst-bloom-API.patch | 0 ...-API-for-an-entity-s-scoreboard-name.patch | 0 ...place-methods-with-old-StructureType.patch | 0 ...te-namespaced-commands-if-send-names.patch | 0 ...y-handle-BlockBreakEvent-isDropItems.patch | 0 ...-entity-death-event-for-ender-dragon.patch | 0 ...ntity-tracking-range-by-Y-coordinate.patch | 0 .../0862-Add-Listing-API-for-Player.patch | 0 ...nfigurable-Region-Compression-Format.patch | 0 ...64-Add-BlockFace-to-BlockDamageEvent.patch | 0 .../0865-Fix-NPE-on-Boat-getStatus.patch | 0 .../0866-Expand-Pose-API.patch | 0 .../0867-More-DragonBattle-API.patch | 0 .../0868-Add-PlayerPickItemEvent.patch | 0 .../0869-Allow-trident-custom-damage.patch | 0 ...70-Expose-hand-in-BlockCanBuildEvent.patch | 0 ...e-nearest-structure-border-iteration.patch | 0 ...-Implement-OfflinePlayer-isConnected.patch | 0 .../0873-Fix-slot-desync.patch | 0 ...-titleOverride-to-InventoryOpenEvent.patch | 0 ...875-Configure-sniffer-egg-hatch-time.patch | 0 ...l-proximity-check-before-entity-look.patch | 0 ...Skip-POI-finding-if-stuck-in-vehicle.patch | 0 ...ot-sanity-checks-in-container-clicks.patch | 0 ...all-BlockRedstoneEvents-for-lecterns.patch | 0 ...proper-checking-of-empty-item-stacks.patch | 0 ...Fix-silent-equipment-change-for-mobs.patch | 0 .../0882-Fix-spigot-s-Forced-Stats.patch | 0 ...sing-InventoryHolders-to-inventories.patch | 0 ...-entities-in-chunks-that-are-positio.patch | 0 ...ssing-logs-for-log-ips-config-option.patch | 0 ...on-on-UpgradeData.BlockFixers-class-.patch | 0 ...n-AdvancementProgress-getDateAwarded.patch | 0 ...sidebar-objectives-not-being-cleared.patch | 0 ...ix-missing-map-initialize-event-call.patch | 0 ...ta-when-attaching-firework-to-entity.patch | 0 ...891-Fix-UnsafeValues-loadAdvancement.patch | 0 .../0892-Add-player-idle-duration-API.patch | 0 ...k-if-we-can-see-non-visible-entities.patch | 0 ...-NPE-in-SculkBloomEvent-world-access.patch | 0 ...stack-for-Player-sendEquipmentChange.patch | 0 .../0896-Optimize-VarInts.patch | 0 ...he-collision-shape-of-a-block-before.patch | 0 ...predicate-for-blocks-when-raytracing.patch | 0 ...tem-packets-with-collector-as-source.patch | 0 .../0900-Expand-LingeringPotion-API.patch | 0 ...ingEffect-powers-lightning-rods-and-.patch | 0 ...sh-event-for-all-player-interactions.patch | 0 ...several-issues-with-EntityBreedEvent.patch | 0 ...0904-Add-UUID-attribute-modifier-API.patch | 0 ...g-event-call-for-entity-teleport-API.patch | 0 ...ly-create-LootContext-for-criterions.patch | 0 ...n-t-fire-sync-events-during-worldgen.patch | 0 .../0908-Add-Structure-check-API.patch | 0 ...m-getAttributeModifier-duplication-c.patch | 0 ...estore-vanilla-entity-drops-behavior.patch | 0 ...1-Dont-resend-blocks-on-interactions.patch | 0 .../0912-add-more-scoreboard-API.patch | 0 .../0913-Improve-Registry.patch | 0 ...-on-null-loc-for-EntityTeleportEvent.patch | 0 .../0915-Add-experience-points-API.patch | 0 .../0916-Add-drops-to-shear-events.patch | 0 .../0917-Add-PlayerShieldDisableEvent.patch | 0 ...date-ResourceLocation-in-NBT-reading.patch | 0 ...e-experience-dropping-on-block-break.patch | 0 .../0920-Fixup-NamespacedKey-handling.patch | 0 ...921-Expose-LootTable-of-DecoratedPot.patch | 0 ...llocation-of-Vec3D-by-entity-tracker.patch | 0 ...erTradeEvent-and-PlayerPurchaseEvent.patch | 0 .../0924-Add-ShulkerDuplicateEvent.patch | 0 ...Add-api-for-spawn-egg-texture-colors.patch | 0 .../0926-Add-Lifecycle-Event-system.patch | 0 .../0927-ItemStack-Tooltip-API.patch | 0 ...kSnapshot-includeLightData-parameter.patch | 0 .../0929-Add-FluidState-API.patch | 0 .../0930-add-number-format-api.patch | 0 .../0931-improve-BanList-types.patch | 0 .../0932-Expanded-Hopper-API.patch | 0 ...33-Add-BlockBreakProgressUpdateEvent.patch | 0 .../0934-Deprecate-ItemStack-setType.patch | 0 .../0935-Add-CartographyItemEvent.patch | 0 .../0936-More-Raid-API.patch | 0 ...ing-message-for-initial-server-start.patch | 0 ...8-Configurable-max-block-fluid-ticks.patch | 0 .../0939-Fix-bees-aging-inside-hives.patch | 0 ...40-Disable-memory-reserve-allocating.patch | 0 ...eByEntityEvent-for-unowned-wither-sk.patch | 0 .../0942-Fix-DamageSource-API.patch | 0 ...invalid-block-entity-during-world-ge.patch | 0 ...tackOverflowError-for-some-dispenses.patch | 0 .../0945-Improve-tag-parser-handling.patch | 0 .../0946-Item-Mutation-Fixes.patch | 0 ...7-Per-world-ticks-per-spawn-settings.patch | 0 ...he-changed-item-from-dispense-events.patch | 0 ...and-End-Portal-Frames-from-being-des.patch | 0 ...re-disarming-not-working-as-intended.patch | 0 ...g-for-mobs-immune-to-default-effects.patch | 0 .../0952-Deep-clone-nbt-tags-in-PDC.patch | 0 ...0953-Support-old-UUID-format-for-NBT.patch | 0 ...954-Fix-shield-disable-inconsistency.patch | 0 ...e-Large-Packets-disconnecting-client.patch | 0 .../0956-Fix-ItemFlags.patch | 0 ...met-damage-reduction-inconsistencies.patch | 0 ...a-handling-of-LivingEntity-actuallyH.patch | 0 ...ve-checking-handled-tags-in-itemmeta.patch | 0 .../0960-General-ItemMeta-fixes.patch | 0 ...961-Expose-hasColor-to-leather-armor.patch | 0 ...d-API-to-get-player-ha-proxy-address.patch | 0 .../0963-More-Chest-Block-API.patch | 0 ...ata-component-type-on-encoding-error.patch | 0 .../0965-Brigadier-based-command-API.patch | 0 .../0966-Fix-issues-with-Recipe-API.patch | 0 ...967-Fix-equipment-slot-and-group-API.patch | 0 ...plugin-to-use-Paper-PluginLoader-API.patch | 0 ...oversized-item-data-in-equipment-and.patch | 0 ...ent-NPE-if-hooked-entity-was-cleared.patch | 0 ...ing-BlockPlaceEvent-calling-onRemove.patch | 0 ...0972-Add-missing-fishing-event-state.patch | 0 ...cate-InvAction-HOTBAR_MOVE_AND_READD.patch | 0 ...onnect-packet-in-phases-where-it-doe.patch | 0 .../0975-Adopt-MaterialRerouting.patch | 0 .../0976-Suspicious-Effect-Entry-API.patch | 0 ...heck-if-itemstack-is-stackable-first.patch | 0 ...removing-recipes-from-RecipeIterator.patch | 0 ...amage-tick-when-blocking-with-shield.patch | 0 ...the-experimental-smithing-inventory-.patch | 0 .../0981-Moonrise-optimisation-patches.patch | 0 .../0982-Rewrite-dataconverter-system.patch | 0 ...983-disable-forced-empty-world-ticks.patch | 0 ...ldBounds-and-getBlockState-for-inlin.patch | 0 ...item-frames-performance-and-bug-fixe.patch | 0 ...cing-for-EntityLiving-hasLineOfSight.patch | 0 ...-Manager-and-add-advanced-packet-sup.patch | 0 ...988-Allow-Saving-of-Oversized-Chunks.patch | 0 ...0989-Flat-bedrock-generator-settings.patch | 0 .../0990-Entity-Activation-Range-2.0.patch | 0 .../0991-Optional-per-player-mob-spawns.patch | 0 .../0992-Anti-Xray.patch | 0 ...3-Eigencraft-redstone-implementation.patch | 0 ...nate-Current-redstone-implementation.patch | 0 ...ng-PreCreatureSpawnEvent-with-per-pl.patch | 0 ...ocity-compression-and-cipher-natives.patch | 0 ...ptimize-Collision-to-not-load-chunks.patch | 0 ...oalSelector-Goal.Flag-Set-operations.patch | 0 .../0999-Optimize-Hoppers.patch | 0 ...000-Entity-load-save-limit-per-chunk.patch | 0 .../1001-Optimize-Voxel-Shape-Merging.patch | 0 ...-Optimize-Bit-Operations-by-inlining.patch | 0 .../1003-Remove-streams-from-hot-code.patch | 0 ...der-Remove-Streams-Optimized-collect.patch | 0 ...lementation-for-blockstate-state-loo.patch | 0 ...y-type-tags-suggestions-in-selectors.patch | 0 ...e-Oversized-block-entities-in-chunks.patch | 0 .../1008-API-for-checking-sent-chunks.patch | 0 ...heck-distance-in-entity-interactions.patch | 0 .../1010-Configurable-Sand-Duping.patch | 0 .../1011-Optimise-general-POI-access.patch | 0 ...2-Improve-performance-of-mass-crafts.patch | 0 .../1013-Properly-resend-entities.patch | 0 .../1014-Registry-Modification-API.patch | 0 ...1015-Add-registry-entry-and-builders.patch | 0 .../1016-Improved-Watchdog-Support.patch | 0 ...17-Proxy-ItemStack-to-CraftItemStack.patch | 0 ...w-accessible-directly-from-ItemStack.patch | 0 ...raft-commands-in-function-parsing-an.patch | 0 ...020-optimize-dirt-and-snow-spreading.patch | 0 .../1021-Fix-NPE-for-Jukebox-setRecord.patch | 0 ...1022-Fix-CraftWorld-isChunkGenerated.patch | 0 .../1023-fix-horse-inventories.patch | 0 ...tityDamageEvents-before-actuallyHurt.patch | 0 ...er-desync-when-new-players-are-added.patch | 0 .../1026-Lag-compensation-ticks.patch | 0 ...l-more-information-in-watchdog-dumps.patch | 0 .../1028-Write-SavedData-IO-async.patch | 0 .../1029-Add-ItemType-getItemRarity.patch | 0 ...-Incremental-chunk-and-player-saving.patch | 0 ...culate-regionfile-header-if-it-is-co.patch | 0 .../1032-Bundle-spark.patch | 0 .../1033-Add-plugin-info-at-startup.patch | 0 ...ction-leniency-distance-configurable.patch | 0 .../1035-Fix-PickupStatus-getting-reset.patch | 0 ...type-in-SculkSensorBlock-canActivate.patch | 0 ...CanPlaceOn-and-CanDestroy-NBT-values.patch | 0 ...ion-for-horizontal-only-item-merging.patch | 0 ...on-checking-in-player-move-packet-ha.patch | 0 ...1040-Add-skipping-world-symlink-scan.patch | 0 .../1041-Add-even-more-Enchantment-API.patch | 0 .../1042-Leashable-API.patch | 0 .../1043-Fix-CraftBukkit-drag-system.patch | 0 ...vent-firing-for-block-entity-loading.patch | 0 ...e-lootable-item-function-from-compas.patch | 0 ...oy-placed-blocks-on-the-end-platform.patch | 0 ...1047-Add-enchantment-seed-update-API.patch | 0 ...sending-chat-to-client-with-updating.patch | 0 ...-Fix-InventoryOpenEvent-cancellation.patch | 0 ...Fire-BlockExpEvent-on-grindstone-use.patch | 0 .../1051-Check-dead-flag-in-isAlive.patch | 0 .../1052-Add-FeatureFlag-API.patch | 0 .../1053-Tag-Lifecycle-Events.patch | 0 .../1054-Item-serialization-as-json.patch | 0 ...date-slot-in-PlayerInventory-setSlot.patch | 0 ...all-time-unused-skip-tick-protection.patch | 0 ...etty-printing-for-advancement-saving.patch | 0 ...ndPreprocessEvent-on-signed-commands.patch | 0 ...Levels-with-enchantment-registry-set.patch | 0 .../1060-Improve-entity-effect-API.patch | 0 .../1061-Add-recipeBrewTime.patch | 0 ...062-Call-bucket-events-for-cauldrons.patch | 0 ...063-Add-PlayerInsertLecternBookEvent.patch | 0 .../1064-Void-damage-configuration-API.patch | 0 .../1065-Add-Offline-PDC-API.patch | 0 ...ew-bypassEnchantmentLevelRestriction.patch | 0 ...d-proper-async-player-disconnections.patch | 0 ...s-send-Banner-patterns-to-the-client.patch | 0 ...99-Optimise-nearby-player-retrieval.patch} | 0 work/BuildData | 2 +- work/Bukkit | 2 +- work/CraftBukkit | 2 +- work/Spigot | 2 +- 1191 files changed, 410 insertions(+), 357 deletions(-) rename patches/{server => unapplied}/0002-Remap-fixes.patch (100%) rename patches/{server => unapplied}/0003-Build-system-changes.patch (100%) rename patches/{server => unapplied}/0004-Test-changes.patch (100%) rename patches/{server => unapplied}/0005-Paper-config-files.patch (100%) rename patches/{server => unapplied}/0006-MC-Dev-fixes.patch (100%) rename patches/{server => unapplied}/0007-ConcurrentUtil.patch (100%) rename patches/{server => unapplied}/0008-CB-fixes.patch (100%) rename patches/{server => unapplied}/0009-MC-Utils.patch (100%) rename patches/{server => unapplied}/0010-Adventure.patch (100%) rename patches/{server => unapplied}/0011-Use-TerminalConsoleAppender-for-console-improvements.patch (100%) rename patches/{server => unapplied}/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch (100%) rename patches/{server => unapplied}/0013-Improve-Log4J-Configuration-Plugin-Loggers.patch (100%) rename patches/{server => unapplied}/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch (100%) rename patches/{server => unapplied}/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch (100%) rename patches/{server => unapplied}/0016-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch (100%) rename patches/{server => unapplied}/0017-Paper-command.patch (100%) rename patches/{server => unapplied}/0018-Paper-Metrics.patch (100%) rename patches/{server => unapplied}/0019-Paper-Plugins.patch (100%) rename patches/{server => unapplied}/0020-Plugin-remapping.patch (100%) rename patches/{server => unapplied}/0021-Hook-into-CB-plugin-rewrites.patch (100%) rename patches/{server => unapplied}/0022-Remap-reflection-calls-in-plugins-using-internals.patch (100%) rename patches/{server => unapplied}/0023-Timings-v2.patch (100%) rename patches/{server => unapplied}/0024-Further-improve-server-tick-loop.patch (100%) rename patches/{server => unapplied}/0025-Add-command-line-option-to-load-extra-plugin-jars-no.patch (100%) rename patches/{server => unapplied}/0026-Support-components-in-ItemMeta.patch (100%) rename patches/{server => unapplied}/0027-Configurable-cactus-bamboo-and-reed-growth-height.patch (100%) rename patches/{server => unapplied}/0028-Configurable-baby-zombie-movement-speed.patch (100%) rename patches/{server => unapplied}/0029-Configurable-fishing-time-ranges.patch (100%) rename patches/{server => unapplied}/0030-Allow-nerfed-mobs-to-jump.patch (100%) rename patches/{server => unapplied}/0031-Add-configurable-entity-despawn-distances.patch (100%) rename patches/{server => unapplied}/0032-Drop-falling-block-and-tnt-entities-at-the-specified.patch (100%) rename patches/{server => unapplied}/0033-Expose-server-build-information.patch (100%) rename patches/{server => unapplied}/0034-Player-affects-spawning-API.patch (100%) rename patches/{server => unapplied}/0035-Only-refresh-abilities-if-needed.patch (100%) rename patches/{server => unapplied}/0036-Entity-Origin-API.patch (100%) rename patches/{server => unapplied}/0037-Prevent-block-entity-and-entity-crashes.patch (100%) rename patches/{server => unapplied}/0038-Configurable-top-of-nether-void-damage.patch (100%) rename patches/{server => unapplied}/0039-Check-online-mode-before-converting-and-renaming-pla.patch (100%) rename patches/{server => unapplied}/0040-Add-more-entities-to-activation-range-ignore-list.patch (100%) rename patches/{server => unapplied}/0041-Configurable-end-credits.patch (100%) rename patches/{server => unapplied}/0042-Fix-lag-from-explosions-processing-dead-entities.patch (100%) rename patches/{server => unapplied}/0043-Optimize-explosions.patch (100%) rename patches/{server => unapplied}/0044-Disable-explosion-knockback.patch (100%) rename patches/{server => unapplied}/0045-Disable-thunder.patch (100%) rename patches/{server => unapplied}/0046-Disable-ice-and-snow.patch (100%) rename patches/{server => unapplied}/0047-Configurable-mob-spawner-tick-rate.patch (100%) rename patches/{server => unapplied}/0048-Use-null-Locale-by-default.patch (100%) rename patches/{server => unapplied}/0049-Add-BeaconEffectEvent.patch (100%) rename patches/{server => unapplied}/0050-Configurable-container-update-tick-rate.patch (100%) rename patches/{server => unapplied}/0051-Use-UserCache-for-player-heads.patch (100%) rename patches/{server => unapplied}/0052-Disable-spigot-tick-limiters.patch (100%) rename patches/{server => unapplied}/0053-Fix-spawn-location-event-changing-location.patch (100%) rename patches/{server => unapplied}/0054-Configurable-Disabling-Cat-Chest-Detection.patch (100%) rename patches/{server => unapplied}/0055-Improve-Player-chat-API-handling.patch (100%) rename patches/{server => unapplied}/0056-All-chunks-are-slime-spawn-chunks-toggle.patch (100%) rename patches/{server => unapplied}/0057-Expose-server-CommandMap.patch (100%) rename patches/{server => unapplied}/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch (100%) rename patches/{server => unapplied}/0059-Player-Tab-List-and-Title-APIs.patch (100%) rename patches/{server => unapplied}/0060-Add-configurable-portal-search-radius.patch (100%) rename patches/{server => unapplied}/0061-Add-velocity-warnings.patch (100%) rename patches/{server => unapplied}/0062-Add-exception-reporting-event.patch (100%) rename patches/{server => unapplied}/0063-Disable-Scoreboards-for-non-players-by-default.patch (100%) rename patches/{server => unapplied}/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch (100%) rename patches/{server => unapplied}/0065-Chunk-Save-Reattempt.patch (100%) rename patches/{server => unapplied}/0066-Complete-resource-pack-API.patch (100%) rename patches/{server => unapplied}/0067-Default-loading-permissions.yml-before-plugins.patch (100%) rename patches/{server => unapplied}/0068-Allow-Reloading-of-Custom-Permissions.patch (100%) rename patches/{server => unapplied}/0069-Remove-Metadata-on-reload.patch (100%) rename patches/{server => unapplied}/0070-Handle-Item-Meta-Inconsistencies.patch (100%) rename patches/{server => unapplied}/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch (100%) rename patches/{server => unapplied}/0072-Add-World-Util-Methods.patch (100%) rename patches/{server => unapplied}/0073-Custom-replacement-for-eaten-items.patch (100%) rename patches/{server => unapplied}/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch (100%) rename patches/{server => unapplied}/0075-Use-a-Shared-Random-for-Entities.patch (100%) rename patches/{server => unapplied}/0076-Configurable-spawn-chances-for-skeleton-horses.patch (100%) rename patches/{server => unapplied}/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch (100%) rename patches/{server => unapplied}/0078-Entity-AddTo-RemoveFrom-World-Events.patch (100%) rename patches/{server => unapplied}/0079-Configurable-Chunk-Inhabited-Time.patch (100%) rename patches/{server => unapplied}/0080-EntityPathfindEvent.patch (100%) rename patches/{server => unapplied}/0081-Sanitise-RegionFileCache-and-make-configurable.patch (100%) rename patches/{server => unapplied}/0082-Do-not-load-chunks-for-Pathfinding.patch (100%) rename patches/{server => unapplied}/0083-Add-PlayerUseUnknownEntityEvent.patch (100%) rename patches/{server => unapplied}/0084-Configurable-random-tick-rates-for-blocks.patch (100%) rename patches/{server => unapplied}/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch (100%) rename patches/{server => unapplied}/0086-Optimize-DataBits.patch (100%) rename patches/{server => unapplied}/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch (100%) rename patches/{server => unapplied}/0088-Configurable-Player-Collision.patch (100%) rename patches/{server => unapplied}/0089-Add-handshake-event-to-allow-plugins-to-handle-clien.patch (100%) rename patches/{server => unapplied}/0090-Configurable-RCON-IP-address.patch (100%) rename patches/{server => unapplied}/0091-EntityRegainHealthEvent-isFastRegen-API.patch (100%) rename patches/{server => unapplied}/0092-Add-ability-to-configure-frosted_ice-properties.patch (100%) rename patches/{server => unapplied}/0093-remove-null-possibility-for-getServer-singleton.patch (100%) rename patches/{server => unapplied}/0094-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch (100%) rename patches/{server => unapplied}/0095-LootTable-API-and-replenishable-lootables.patch (100%) rename patches/{server => unapplied}/0096-System-property-for-disabling-watchdoge.patch (100%) rename patches/{server => unapplied}/0097-Async-GameProfileCache-saving.patch (100%) rename patches/{server => unapplied}/0098-Optional-TNT-doesn-t-move-in-water.patch (100%) rename patches/{server => unapplied}/0099-Faster-redstone-torch-rapid-clock-removal.patch (100%) rename patches/{server => unapplied}/0100-Add-server-name-parameter.patch (100%) rename patches/{server => unapplied}/0101-Fix-global-sound-handling.patch (100%) rename patches/{server => unapplied}/0102-Avoid-blocking-on-Network-Manager-creation.patch (100%) rename patches/{server => unapplied}/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch (100%) rename patches/{server => unapplied}/0104-Add-setting-for-proxy-online-mode-status.patch (100%) rename patches/{server => unapplied}/0105-Optimise-BlockState-s-hashCode-equals.patch (100%) rename patches/{server => unapplied}/0106-Configurable-packet-in-spam-threshold.patch (100%) rename patches/{server => unapplied}/0107-Configurable-flying-kick-messages.patch (100%) rename patches/{server => unapplied}/0108-Add-EntityZapEvent.patch (100%) rename patches/{server => unapplied}/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch (100%) rename patches/{server => unapplied}/0110-Cache-user-authenticator-threads.patch (100%) rename patches/{server => unapplied}/0111-Allow-Reloading-of-Command-Aliases.patch (100%) rename patches/{server => unapplied}/0112-Add-source-to-PlayerExpChangeEvent.patch (100%) rename patches/{server => unapplied}/0113-Add-ProjectileCollideEvent.patch (100%) rename patches/{server => unapplied}/0114-Prevent-Pathfinding-out-of-World-Border.patch (100%) rename patches/{server => unapplied}/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch (100%) rename patches/{server => unapplied}/0116-Bound-Treasure-Maps-to-World-Border.patch (100%) rename patches/{server => unapplied}/0117-Configurable-Cartographer-Treasure-Maps.patch (100%) rename patches/{server => unapplied}/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch (100%) rename patches/{server => unapplied}/0119-String-based-Action-Bar-API.patch (100%) rename patches/{server => unapplied}/0120-Properly-fix-item-duplication-bug.patch (100%) rename patches/{server => unapplied}/0121-Firework-API-s.patch (100%) rename patches/{server => unapplied}/0122-PlayerTeleportEndGatewayEvent.patch (100%) rename patches/{server => unapplied}/0123-Provide-E-TE-Chunk-count-stat-methods.patch (100%) rename patches/{server => unapplied}/0124-Enforce-Sync-Player-Saves.patch (100%) rename patches/{server => unapplied}/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch (100%) rename patches/{server => unapplied}/0126-Cap-Entity-Collisions.patch (100%) rename patches/{server => unapplied}/0127-Remove-CraftScheduler-Async-Task-Debugger.patch (100%) rename patches/{server => unapplied}/0128-Properly-handle-async-calls-to-restart-the-server.patch (100%) rename patches/{server => unapplied}/0129-Add-option-to-make-parrots-stay-on-shoulders-despite.patch (100%) rename patches/{server => unapplied}/0130-Add-configuration-option-to-prevent-player-names-fro.patch (100%) rename patches/{server => unapplied}/0131-provide-a-configurable-option-to-disable-creeper-lin.patch (100%) rename patches/{server => unapplied}/0132-Item-canEntityPickup.patch (100%) rename patches/{server => unapplied}/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch (100%) rename patches/{server => unapplied}/0134-PlayerAttemptPickupItemEvent.patch (100%) rename patches/{server => unapplied}/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch (100%) rename patches/{server => unapplied}/0136-Basic-PlayerProfile-API.patch (100%) rename patches/{server => unapplied}/0137-Add-UnknownCommandEvent.patch (100%) rename patches/{server => unapplied}/0138-Shoulder-Entities-Release-API.patch (100%) rename patches/{server => unapplied}/0139-Profile-Lookup-Events.patch (100%) rename patches/{server => unapplied}/0140-Block-player-logins-during-server-shutdown.patch (100%) rename patches/{server => unapplied}/0141-Entity-fromMobSpawner.patch (100%) rename patches/{server => unapplied}/0142-Improve-the-Saddle-API-for-Horses.patch (100%) rename patches/{server => unapplied}/0143-ensureServerConversions-API.patch (100%) rename patches/{server => unapplied}/0144-Implement-getI18NDisplayName.patch (100%) rename patches/{server => unapplied}/0145-ProfileWhitelistVerifyEvent.patch (100%) rename patches/{server => unapplied}/0146-Fix-this-stupid-bullshit.patch (100%) rename patches/{server => unapplied}/0147-LivingEntity-setKiller.patch (100%) rename patches/{server => unapplied}/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch (100%) rename patches/{server => unapplied}/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch (100%) rename patches/{server => unapplied}/0150-Allow-specifying-a-custom-authentication-servers-dow.patch (100%) rename patches/{server => unapplied}/0151-Add-PlayerJumpEvent.patch (100%) rename patches/{server => unapplied}/0152-handle-ServerboundKeepAlivePacket-async.patch (100%) rename patches/{server => unapplied}/0153-Expose-client-protocol-version-and-virtual-host.patch (100%) rename patches/{server => unapplied}/0154-revert-serverside-behavior-of-keepalives.patch (100%) rename patches/{server => unapplied}/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch (100%) rename patches/{server => unapplied}/0156-Add-PlayerArmorChangeEvent.patch (100%) rename patches/{server => unapplied}/0157-Prevent-logins-from-being-processed-when-the-player-.patch (100%) rename patches/{server => unapplied}/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch (100%) rename patches/{server => unapplied}/0159-use-CB-BlockState-implementations-for-captured-block.patch (100%) rename patches/{server => unapplied}/0160-API-to-get-a-BlockState-without-a-snapshot.patch (100%) rename patches/{server => unapplied}/0161-AsyncTabCompleteEvent.patch (100%) rename patches/{server => unapplied}/0162-PlayerPickupExperienceEvent.patch (100%) rename patches/{server => unapplied}/0163-Ability-to-apply-mending-to-XP-API.patch (100%) rename patches/{server => unapplied}/0164-PlayerNaturallySpawnCreaturesEvent.patch (100%) rename patches/{server => unapplied}/0165-Add-setPlayerProfile-API-for-Skulls.patch (100%) rename patches/{server => unapplied}/0166-PreCreatureSpawnEvent.patch (100%) rename patches/{server => unapplied}/0167-Fill-Profile-Property-Events.patch (100%) rename patches/{server => unapplied}/0168-Add-PlayerAdvancementCriterionGrantEvent.patch (100%) rename patches/{server => unapplied}/0169-Add-ArmorStand-Item-Meta.patch (100%) rename patches/{server => unapplied}/0170-Extend-Player-Interact-cancellation.patch (100%) rename patches/{server => unapplied}/0171-Tameable-getOwnerUniqueId-API.patch (100%) rename patches/{server => unapplied}/0172-Toggleable-player-crits.patch (100%) rename patches/{server => unapplied}/0173-Disable-Explicit-Network-Manager-Flushing.patch (100%) rename patches/{server => unapplied}/0174-Implement-extended-PaperServerListPingEvent.patch (100%) rename patches/{server => unapplied}/0175-Add-more-fields-to-AsyncPreLoginEvent.patch (100%) rename patches/{server => unapplied}/0176-Player.setPlayerProfile-API.patch (100%) rename patches/{server => unapplied}/0177-getPlayerUniqueId-API.patch (100%) rename patches/{server => unapplied}/0178-Improved-Async-Task-Scheduler.patch (100%) rename patches/{server => unapplied}/0179-Make-legacy-ping-handler-more-reliable.patch (100%) rename patches/{server => unapplied}/0180-Call-PaperServerListPingEvent-for-legacy-pings.patch (100%) rename patches/{server => unapplied}/0181-Flag-to-disable-the-channel-limit.patch (100%) rename patches/{server => unapplied}/0182-Add-openSign-method-to-HumanEntity.patch (100%) rename patches/{server => unapplied}/0183-Configurable-sprint-interruption-on-attack.patch (100%) rename patches/{server => unapplied}/0184-EndermanEscapeEvent.patch (100%) rename patches/{server => unapplied}/0185-Enderman.teleportRandomly.patch (100%) rename patches/{server => unapplied}/0186-Block-Enderpearl-Travel-Exploit.patch (100%) rename patches/{server => unapplied}/0187-Expand-World.spawnParticle-API-and-add-Builder.patch (100%) rename patches/{server => unapplied}/0188-Fix-exploit-that-allowed-colored-signs-to-be-created.patch (100%) rename patches/{server => unapplied}/0189-EndermanAttackPlayerEvent.patch (100%) rename patches/{server => unapplied}/0190-WitchConsumePotionEvent.patch (100%) rename patches/{server => unapplied}/0191-WitchThrowPotionEvent.patch (100%) rename patches/{server => unapplied}/0192-WitchReadyPotionEvent.patch (100%) rename patches/{server => unapplied}/0193-ItemStack-getMaxItemUseDuration.patch (100%) rename patches/{server => unapplied}/0194-Add-EntityTeleportEndGatewayEvent.patch (100%) rename patches/{server => unapplied}/0195-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch (100%) rename patches/{server => unapplied}/0196-Fix-CraftEntity-hashCode.patch (100%) rename patches/{server => unapplied}/0197-Configurable-LootPool-luck-formula.patch (100%) rename patches/{server => unapplied}/0198-Print-Error-details-when-failing-to-save-player-data.patch (100%) rename patches/{server => unapplied}/0199-Make-shield-blocking-delay-configurable.patch (100%) rename patches/{server => unapplied}/0200-Improve-EntityShootBowEvent.patch (100%) rename patches/{server => unapplied}/0201-PlayerReadyArrowEvent.patch (100%) rename patches/{server => unapplied}/0202-Add-entity-knockback-events.patch (100%) rename patches/{server => unapplied}/0203-Expand-Explosions-API.patch (100%) rename patches/{server => unapplied}/0204-LivingEntity-Active-Item-API.patch (100%) rename patches/{server => unapplied}/0205-RangedEntity-API.patch (100%) rename patches/{server => unapplied}/0206-Add-config-to-disable-ender-dragon-legacy-check.patch (100%) rename patches/{server => unapplied}/0207-Implement-World.getEntity-UUID-API.patch (100%) rename patches/{server => unapplied}/0208-InventoryCloseEvent-Reason-API.patch (100%) rename patches/{server => unapplied}/0209-Vex-get-setSummoner-API.patch (100%) rename patches/{server => unapplied}/0210-add-more-information-to-Entity.toString.patch (100%) rename patches/{server => unapplied}/0211-EnderDragon-Events.patch (100%) rename patches/{server => unapplied}/0212-PlayerElytraBoostEvent.patch (100%) rename patches/{server => unapplied}/0213-PlayerLaunchProjectileEvent.patch (100%) rename patches/{server => unapplied}/0214-Improve-BlockPosition-inlining.patch (100%) rename patches/{server => unapplied}/0215-Option-to-prevent-armor-stands-from-doing-entity-loo.patch (100%) rename patches/{server => unapplied}/0216-Vanished-players-don-t-have-rights.patch (100%) rename patches/{server => unapplied}/0217-Allow-disabling-armor-stand-ticking.patch (100%) rename patches/{server => unapplied}/0218-SkeletonHorse-Additions.patch (100%) rename patches/{server => unapplied}/0219-Expand-ArmorStand-API.patch (100%) rename patches/{server => unapplied}/0220-AnvilDamageEvent.patch (100%) rename patches/{server => unapplied}/0221-Add-TNTPrimeEvent.patch (100%) rename patches/{server => unapplied}/0222-Break-up-and-make-tab-spam-limits-configurable.patch (100%) rename patches/{server => unapplied}/0223-Fix-NBT-type-issues.patch (100%) rename patches/{server => unapplied}/0224-Remove-unnecessary-itemmeta-handling.patch (100%) rename patches/{server => unapplied}/0225-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch (100%) rename patches/{server => unapplied}/0226-Add-Early-Warning-Feature-to-WatchDog.patch (100%) rename patches/{server => unapplied}/0227-Use-ConcurrentHashMap-in-JsonList.patch (100%) rename patches/{server => unapplied}/0228-Use-a-Queue-for-Queueing-Commands.patch (100%) rename patches/{server => unapplied}/0229-Ability-to-get-block-entities-from-a-chunk-without-s.patch (100%) rename patches/{server => unapplied}/0230-Optimize-BlockPosition-helper-methods.patch (100%) rename patches/{server => unapplied}/0231-Restore-vanilla-default-mob-spawn-range-and-water-an.patch (100%) rename patches/{server => unapplied}/0232-Slime-Pathfinder-Events.patch (100%) rename patches/{server => unapplied}/0233-Configurable-speed-for-water-flowing-over-lava.patch (100%) rename patches/{server => unapplied}/0234-Optimize-CraftBlockData-Creation.patch (100%) rename patches/{server => unapplied}/0235-Optimize-MappedRegistry.patch (100%) rename patches/{server => unapplied}/0236-Add-PhantomPreSpawnEvent.patch (100%) rename patches/{server => unapplied}/0237-Add-More-Creeper-API.patch (100%) rename patches/{server => unapplied}/0238-Inventory-removeItemAnySlot.patch (100%) rename patches/{server => unapplied}/0239-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch (100%) rename patches/{server => unapplied}/0240-Add-ray-tracing-methods-to-LivingEntity.patch (100%) rename patches/{server => unapplied}/0241-Expose-attack-cooldown-methods-for-Player.patch (100%) rename patches/{server => unapplied}/0242-Improve-death-events.patch (100%) rename patches/{server => unapplied}/0243-Allow-chests-to-be-placed-with-NBT-data.patch (100%) rename patches/{server => unapplied}/0244-Mob-Pathfinding-API.patch (100%) rename patches/{server => unapplied}/0245-Prevent-various-interactions-from-causing-chunk-load.patch (100%) rename patches/{server => unapplied}/0246-Prevent-mob-spawning-from-loading-generating-chunks.patch (100%) rename patches/{server => unapplied}/0247-Implement-furnace-cook-speed-multiplier-API.patch (100%) rename patches/{server => unapplied}/0248-Honor-EntityAgeable.ageLock.patch (100%) rename patches/{server => unapplied}/0249-Configurable-connection-throttle-kick-message.patch (100%) rename patches/{server => unapplied}/0250-Prevent-chunk-loading-from-Fluid-Flowing.patch (100%) rename patches/{server => unapplied}/0251-PreSpawnerSpawnEvent.patch (100%) rename patches/{server => unapplied}/0252-Add-LivingEntity-getTargetEntity.patch (100%) rename patches/{server => unapplied}/0253-Add-sun-related-API.patch (100%) rename patches/{server => unapplied}/0254-Turtle-API.patch (100%) rename patches/{server => unapplied}/0255-Call-player-spectator-target-events-and-improve-impl.patch (100%) rename patches/{server => unapplied}/0256-Add-more-Witch-API.patch (100%) rename patches/{server => unapplied}/0257-Check-Drowned-for-Villager-Aggression-Config.patch (100%) rename patches/{server => unapplied}/0258-Add-option-to-prevent-players-from-moving-into-unloa.patch (100%) rename patches/{server => unapplied}/0259-Reset-players-airTicks-on-respawn.patch (100%) rename patches/{server => unapplied}/0260-Don-t-sleep-after-profile-lookups-if-not-needed.patch (100%) rename patches/{server => unapplied}/0261-Improve-Server-Thread-Pool-and-Thread-Priorities.patch (100%) rename patches/{server => unapplied}/0262-Optimize-World-Time-Updates.patch (100%) rename patches/{server => unapplied}/0263-Restore-custom-InventoryHolder-support.patch (100%) rename patches/{server => unapplied}/0264-Fix-SpongeAbsortEvent-handling.patch (100%) rename patches/{server => unapplied}/0265-Don-t-allow-digging-into-unloaded-chunks.patch (100%) rename patches/{server => unapplied}/0266-Make-the-default-permission-message-configurable.patch (100%) rename patches/{server => unapplied}/0267-force-entity-dismount-during-teleportation.patch (100%) rename patches/{server => unapplied}/0268-Add-more-Zombie-API.patch (100%) rename patches/{server => unapplied}/0269-Book-size-limits.patch (100%) rename patches/{server => unapplied}/0270-Add-PlayerConnectionCloseEvent.patch (100%) rename patches/{server => unapplied}/0271-Replace-OfflinePlayer-getLastPlayed.patch (100%) rename patches/{server => unapplied}/0272-Workaround-for-vehicle-tracking-issue-on-disconnect.patch (100%) rename patches/{server => unapplied}/0273-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch (100%) rename patches/{server => unapplied}/0274-BlockDestroyEvent.patch (100%) rename patches/{server => unapplied}/0275-Async-command-map-building.patch (100%) rename patches/{server => unapplied}/0276-Brigadier-Mojang-API.patch (100%) rename patches/{server => unapplied}/0277-Improve-exact-choice-recipe-ingredients.patch (100%) rename patches/{server => unapplied}/0278-Limit-Client-Sign-length-more.patch (100%) rename patches/{server => unapplied}/0279-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch (100%) rename patches/{server => unapplied}/0280-Fixes-and-additions-to-the-spawn-reason-API.patch (100%) rename patches/{server => unapplied}/0281-Fire-event-on-GS4-query.patch (100%) rename patches/{server => unapplied}/0282-Add-PlayerPostRespawnEvent.patch (100%) rename patches/{server => unapplied}/0283-Server-Tick-Events.patch (100%) rename patches/{server => unapplied}/0284-PlayerDeathEvent-getItemsToKeep.patch (100%) rename patches/{server => unapplied}/0285-Optimize-Captured-BlockEntity-Lookup.patch (100%) rename patches/{server => unapplied}/0286-Mob-Spawner-API-Enhancements.patch (100%) rename patches/{server => unapplied}/0287-Fix-CB-call-to-changed-postToMainThread-method.patch (100%) rename patches/{server => unapplied}/0288-Fix-sounds-when-item-frames-are-modified-MC-123450.patch (100%) rename patches/{server => unapplied}/0289-Implement-CraftBlockSoundGroup.patch (100%) rename patches/{server => unapplied}/0290-Expose-the-internal-current-tick.patch (100%) rename patches/{server => unapplied}/0291-Show-blockstate-location-if-we-failed-to-read-it.patch (100%) rename patches/{server => unapplied}/0292-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch (100%) rename patches/{server => unapplied}/0293-Configurable-projectile-relative-velocity.patch (100%) rename patches/{server => unapplied}/0294-offset-item-frame-ticking.patch (100%) rename patches/{server => unapplied}/0295-Prevent-consuming-the-wrong-itemstack.patch (100%) rename patches/{server => unapplied}/0296-Dont-send-unnecessary-sign-update.patch (100%) rename patches/{server => unapplied}/0297-Add-option-to-disable-pillager-patrols.patch (100%) rename patches/{server => unapplied}/0298-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch (100%) rename patches/{server => unapplied}/0299-MC-145656-Fix-Follow-Range-Initial-Target.patch (100%) rename patches/{server => unapplied}/0300-Duplicate-UUID-Resolve-Option.patch (100%) rename patches/{server => unapplied}/0301-PlayerDeathEvent-shouldDropExperience.patch (100%) rename patches/{server => unapplied}/0302-Prevent-bees-loading-chunks-checking-hive-position.patch (100%) rename patches/{server => unapplied}/0303-Don-t-load-Chunks-from-Hoppers-and-other-things.patch (100%) rename patches/{server => unapplied}/0304-Optimise-EntityGetter-getPlayerByUUID.patch (100%) rename patches/{server => unapplied}/0305-Fix-items-not-falling-correctly.patch (100%) rename patches/{server => unapplied}/0306-Optimize-call-to-getFluid-for-explosions.patch (100%) rename patches/{server => unapplied}/0307-Guard-against-serializing-mismatching-chunk-coordina.patch (100%) rename patches/{server => unapplied}/0308-Alternative-item-despawn-rate.patch (100%) rename patches/{server => unapplied}/0309-Tracking-Range-Improvements.patch (100%) rename patches/{server => unapplied}/0310-Bees-get-gravity-in-void.-Fixes-MC-167279.patch (100%) rename patches/{server => unapplied}/0311-Improve-Block-breakNaturally-API.patch (100%) rename patches/{server => unapplied}/0312-Optimise-getChunkAt-calls-for-loaded-chunks.patch (100%) rename patches/{server => unapplied}/0313-Add-debug-for-sync-chunk-loads.patch (100%) rename patches/{server => unapplied}/0314-Improve-java-version-check.patch (100%) rename patches/{server => unapplied}/0315-Add-ThrownEggHatchEvent.patch (100%) rename patches/{server => unapplied}/0316-Entity-Jump-API.patch (100%) rename patches/{server => unapplied}/0317-Add-option-to-nerf-pigmen-from-nether-portals.patch (100%) rename patches/{server => unapplied}/0318-Make-the-GUI-graph-fancier.patch (100%) rename patches/{server => unapplied}/0319-add-hand-to-BlockMultiPlaceEvent.patch (100%) rename patches/{server => unapplied}/0320-Validate-tripwire-hook-placement-before-update.patch (100%) rename patches/{server => unapplied}/0321-Add-option-to-allow-iron-golems-to-spawn-in-air.patch (100%) rename patches/{server => unapplied}/0322-Configurable-chance-of-villager-zombie-infection.patch (100%) rename patches/{server => unapplied}/0323-Optimise-Chunk-getFluid.patch (100%) rename patches/{server => unapplied}/0324-Set-spigots-verbose-world-setting-to-false-by-def.patch (100%) rename patches/{server => unapplied}/0325-Add-tick-times-API-and-mspt-command.patch (100%) rename patches/{server => unapplied}/0326-Expose-MinecraftServer-isRunning.patch (100%) rename patches/{server => unapplied}/0327-Add-Raw-Byte-ItemStack-Serialization.patch (100%) rename patches/{server => unapplied}/0328-Pillager-patrol-spawn-settings-and-per-player-option.patch (100%) rename patches/{server => unapplied}/0329-Remote-Connections-shouldn-t-hold-up-shutdown.patch (100%) rename patches/{server => unapplied}/0330-Do-not-allow-bees-to-load-chunks-for-beehives.patch (100%) rename patches/{server => unapplied}/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch (100%) rename patches/{server => unapplied}/0332-Don-t-tick-dead-players.patch (100%) rename patches/{server => unapplied}/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch (100%) rename patches/{server => unapplied}/0334-Don-t-move-existing-players-to-world-spawn.patch (100%) rename patches/{server => unapplied}/0335-Optimize-Pathfinding.patch (100%) rename patches/{server => unapplied}/0336-Reduce-Either-Optional-allocation.patch (100%) rename patches/{server => unapplied}/0337-Reduce-memory-footprint-of-CompoundTag.patch (100%) rename patches/{server => unapplied}/0338-Prevent-opening-inventories-when-frozen.patch (100%) rename patches/{server => unapplied}/0339-Don-t-run-entity-collision-code-if-not-needed.patch (100%) rename patches/{server => unapplied}/0340-Implement-Player-Client-Options-API.patch (100%) rename patches/{server => unapplied}/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch (100%) rename patches/{server => unapplied}/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch (100%) rename patches/{server => unapplied}/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch (100%) rename patches/{server => unapplied}/0344-Add-PlayerAttackEntityCooldownResetEvent.patch (100%) rename patches/{server => unapplied}/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch (100%) rename patches/{server => unapplied}/0346-Add-phantom-creative-and-insomniac-controls.patch (100%) rename patches/{server => unapplied}/0347-Fix-item-duplication-and-teleport-issues.patch (100%) rename patches/{server => unapplied}/0348-Villager-Restocks-API.patch (100%) rename patches/{server => unapplied}/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch (100%) rename patches/{server => unapplied}/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch (100%) rename patches/{server => unapplied}/0351-misc-debugging-dumps.patch (100%) rename patches/{server => unapplied}/0352-Prevent-teleporting-dead-entities.patch (100%) rename patches/{server => unapplied}/0353-Implement-Mob-Goal-API.patch (100%) rename patches/{server => unapplied}/0354-Add-villager-reputation-API.patch (100%) rename patches/{server => unapplied}/0355-ExperienceOrb-merging-stacking-API-and-fixes.patch (100%) rename patches/{server => unapplied}/0356-Fix-PotionEffect-ignores-icon-flag.patch (100%) rename patches/{server => unapplied}/0357-Potential-bed-API.patch (100%) rename patches/{server => unapplied}/0358-Wait-for-Async-Tasks-during-shutdown.patch (100%) rename patches/{server => unapplied}/0359-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch (100%) rename patches/{server => unapplied}/0360-Add-option-for-console-having-all-permissions.patch (100%) rename patches/{server => unapplied}/0361-Fix-villager-trading-demand-MC-163962.patch (100%) rename patches/{server => unapplied}/0362-Maps-shouldn-t-load-chunks.patch (100%) rename patches/{server => unapplied}/0363-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch (100%) rename patches/{server => unapplied}/0364-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch (100%) rename patches/{server => unapplied}/0365-Fix-piston-physics-inconsistency-MC-188840.patch (100%) rename patches/{server => unapplied}/0366-Fix-missing-chunks-due-to-integer-overflow.patch (100%) rename patches/{server => unapplied}/0367-Prevent-position-desync-causing-tp-exploit.patch (100%) rename patches/{server => unapplied}/0368-Inventory-getHolder-method-without-block-snapshot.patch (100%) rename patches/{server => unapplied}/0369-Add-PlayerRecipeBookClickEvent.patch (100%) rename patches/{server => unapplied}/0370-Hide-sync-chunk-writes-behind-flag.patch (100%) rename patches/{server => unapplied}/0371-Add-permission-for-command-blocks.patch (100%) rename patches/{server => unapplied}/0372-Ensure-Entity-position-and-AABB-are-never-invalid.patch (100%) rename patches/{server => unapplied}/0373-Fix-Per-World-Difficulty-Remembering-Difficulty.patch (100%) rename patches/{server => unapplied}/0374-Paper-dumpitem-command.patch (100%) rename patches/{server => unapplied}/0375-Improve-Legacy-Component-serialization-size.patch (100%) rename patches/{server => unapplied}/0376-Add-Plugin-Tickets-to-API-Chunk-Methods.patch (100%) rename patches/{server => unapplied}/0377-Add-BlockStateMeta-clearBlockState.patch (100%) rename patches/{server => unapplied}/0378-Convert-legacy-attributes-in-Item-Meta.patch (100%) rename patches/{server => unapplied}/0379-Do-not-accept-invalid-client-settings.patch (100%) rename patches/{server => unapplied}/0380-Improve-fix-EntityTargetLivingEntityEvent.patch (100%) rename patches/{server => unapplied}/0381-Add-entity-liquid-API.patch (100%) rename patches/{server => unapplied}/0382-Add-PrepareResultEvent.patch (100%) rename patches/{server => unapplied}/0383-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch (100%) rename patches/{server => unapplied}/0384-Fix-arrows-never-despawning-MC-125757.patch (100%) rename patches/{server => unapplied}/0385-Thread-Safe-Vanilla-Command-permission-checking.patch (100%) rename patches/{server => unapplied}/0386-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch (100%) rename patches/{server => unapplied}/0387-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch (100%) rename patches/{server => unapplied}/0388-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch (100%) rename patches/{server => unapplied}/0389-Optimize-NetworkManager-Exception-Handling.patch (100%) rename patches/{server => unapplied}/0390-Fix-some-rails-connecting-improperly.patch (100%) rename patches/{server => unapplied}/0391-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch (100%) rename patches/{server => unapplied}/0392-Brand-support.patch (100%) rename patches/{server => unapplied}/0393-Add-playPickupItemAnimation-to-LivingEntity.patch (100%) rename patches/{server => unapplied}/0394-Don-t-require-FACING-data.patch (100%) rename patches/{server => unapplied}/0395-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch (100%) rename patches/{server => unapplied}/0396-Add-moon-phase-API.patch (100%) rename patches/{server => unapplied}/0397-Do-not-let-the-server-load-chunks-from-newer-version.patch (100%) rename patches/{server => unapplied}/0398-Prevent-headless-pistons-from-being-created.patch (100%) rename patches/{server => unapplied}/0399-Add-BellRingEvent.patch (100%) rename patches/{server => unapplied}/0400-Add-zombie-targets-turtle-egg-config.patch (100%) rename patches/{server => unapplied}/0401-Buffer-joins-to-world.patch (100%) rename patches/{server => unapplied}/0402-Fix-hex-colors-not-working-in-some-kick-messages.patch (100%) rename patches/{server => unapplied}/0403-Add-more-Evoker-API.patch (100%) rename patches/{server => unapplied}/0404-Add-methods-to-get-translation-keys.patch (100%) rename patches/{server => unapplied}/0405-Create-HoverEvent-from-ItemStack-Entity.patch (100%) rename patches/{server => unapplied}/0406-Cache-block-data-strings.patch (100%) rename patches/{server => unapplied}/0407-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch (100%) rename patches/{server => unapplied}/0408-Add-additional-open-container-api-to-HumanEntity.patch (100%) rename patches/{server => unapplied}/0409-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch (100%) rename patches/{server => unapplied}/0410-Extend-block-drop-capture-to-capture-all-items-added.patch (100%) rename patches/{server => unapplied}/0411-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch (100%) rename patches/{server => unapplied}/0412-Lazily-track-plugin-scoreboards-by-default.patch (100%) rename patches/{server => unapplied}/0413-Entity-isTicking.patch (100%) rename patches/{server => unapplied}/0414-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch (100%) rename patches/{server => unapplied}/0415-Fix-Concurrency-issue-in-ShufflingList.patch (100%) rename patches/{server => unapplied}/0416-Reset-Ender-Crystals-on-Dragon-Spawn.patch (100%) rename patches/{server => unapplied}/0417-Fix-for-large-move-vectors-crashing-server.patch (100%) rename patches/{server => unapplied}/0418-Optimise-getType-calls.patch (100%) rename patches/{server => unapplied}/0419-Villager-resetOffers.patch (100%) rename patches/{server => unapplied}/0420-Retain-block-place-order-when-capturing-blockstates.patch (100%) rename patches/{server => unapplied}/0421-Fix-item-locations-dropped-from-campfires.patch (100%) rename patches/{server => unapplied}/0422-Fix-bell-block-entity-memory-leak.patch (100%) rename patches/{server => unapplied}/0423-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch (100%) rename patches/{server => unapplied}/0424-Add-getOfflinePlayerIfCached-String.patch (100%) rename patches/{server => unapplied}/0425-Add-ignore-discounts-API.patch (100%) rename patches/{server => unapplied}/0426-Toggle-for-removing-existing-dragon.patch (100%) rename patches/{server => unapplied}/0427-Fix-client-lag-on-advancement-loading.patch (100%) rename patches/{server => unapplied}/0428-Item-no-age-no-player-pickup.patch (100%) rename patches/{server => unapplied}/0429-Beacon-API-custom-effect-ranges.patch (100%) rename patches/{server => unapplied}/0430-Add-API-for-quit-reason.patch (100%) rename patches/{server => unapplied}/0431-Add-Wandering-Trader-spawn-rate-config-options.patch (100%) rename patches/{server => unapplied}/0432-Add-Destroy-Speed-API.patch (100%) rename patches/{server => unapplied}/0433-Fix-Player-spawnParticle-x-y-z-precision-loss.patch (100%) rename patches/{server => unapplied}/0434-Add-LivingEntity-clearActiveItem.patch (100%) rename patches/{server => unapplied}/0435-Add-PlayerItemCooldownEvent.patch (100%) rename patches/{server => unapplied}/0436-Significantly-improve-performance-of-the-end-generat.patch (100%) rename patches/{server => unapplied}/0437-More-lightning-API.patch (100%) rename patches/{server => unapplied}/0438-Climbing-should-not-bypass-cramming-gamerule.patch (100%) rename patches/{server => unapplied}/0439-Add-missing-default-perms-for-commands.patch (100%) rename patches/{server => unapplied}/0440-Add-PlayerShearBlockEvent.patch (100%) rename patches/{server => unapplied}/0441-Limit-recipe-packets.patch (100%) rename patches/{server => unapplied}/0442-Fix-CraftSound-backwards-compatibility.patch (100%) rename patches/{server => unapplied}/0443-Player-Chunk-Load-Unload-Events.patch (100%) rename patches/{server => unapplied}/0444-Optimize-Dynamic-get-Missing-Keys.patch (100%) rename patches/{server => unapplied}/0445-Expose-LivingEntity-hurt-direction.patch (100%) rename patches/{server => unapplied}/0446-Add-OBSTRUCTED-reason-to-BedEnterResult.patch (100%) rename patches/{server => unapplied}/0447-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch (100%) rename patches/{server => unapplied}/0448-Add-TargetHitEvent.patch (100%) rename patches/{server => unapplied}/0449-MC-4-Fix-item-position-desync.patch (100%) rename patches/{server => unapplied}/0450-Additional-Block-Material-API.patch (100%) rename patches/{server => unapplied}/0451-Fix-harming-potion-dupe.patch (100%) rename patches/{server => unapplied}/0452-API-to-get-Material-from-Boats-and-Minecarts.patch (100%) rename patches/{server => unapplied}/0453-Allow-disabling-mob-spawner-spawn-egg-transformation.patch (100%) rename patches/{server => unapplied}/0454-Fix-Not-a-string-Map-Conversion-spam.patch (100%) rename patches/{server => unapplied}/0455-Add-PlayerFlowerPotManipulateEvent.patch (100%) rename patches/{server => unapplied}/0456-Fix-interact-event-not-being-called-sometimes.patch (100%) rename patches/{server => unapplied}/0457-Zombie-API-breaking-doors.patch (100%) rename patches/{server => unapplied}/0458-Fix-nerfed-slime-when-splitting.patch (100%) rename patches/{server => unapplied}/0459-Add-EntityLoadCrossbowEvent.patch (100%) rename patches/{server => unapplied}/0460-Add-WorldGameRuleChangeEvent.patch (100%) rename patches/{server => unapplied}/0461-Add-ServerResourcesReloadedEvent.patch (100%) rename patches/{server => unapplied}/0462-Add-world-settings-for-mobs-picking-up-loot.patch (100%) rename patches/{server => unapplied}/0463-Add-BlockFailedDispenseEvent.patch (100%) rename patches/{server => unapplied}/0464-Add-PlayerLecternPageChangeEvent.patch (100%) rename patches/{server => unapplied}/0465-Add-PlayerLoomPatternSelectEvent.patch (100%) rename patches/{server => unapplied}/0466-Configurable-door-breaking-difficulty.patch (100%) rename patches/{server => unapplied}/0467-Empty-commands-shall-not-be-dispatched.patch (100%) rename patches/{server => unapplied}/0468-Remove-stale-POIs.patch (100%) rename patches/{server => unapplied}/0469-Fix-villager-boat-exploit.patch (100%) rename patches/{server => unapplied}/0470-Add-sendOpLevel-API.patch (100%) rename patches/{server => unapplied}/0471-Add-RegistryAccess-for-managing-Registries.patch (100%) rename patches/{server => unapplied}/0472-Add-StructuresLocateEvent.patch (100%) rename patches/{server => unapplied}/0473-Collision-option-for-requiring-a-player-participant.patch (100%) rename patches/{server => unapplied}/0474-Return-chat-component-with-empty-text-instead-of-thr.patch (100%) rename patches/{server => unapplied}/0475-Make-schedule-command-per-world.patch (100%) rename patches/{server => unapplied}/0476-Configurable-max-leash-distance.patch (100%) rename patches/{server => unapplied}/0477-Add-BlockPreDispenseEvent.patch (100%) rename patches/{server => unapplied}/0478-Add-PlayerChangeBeaconEffectEvent.patch (100%) rename patches/{server => unapplied}/0479-Add-toggle-for-always-placing-the-dragon-egg.patch (100%) rename patches/{server => unapplied}/0480-Add-PlayerStonecutterRecipeSelectEvent.patch (100%) rename patches/{server => unapplied}/0481-Expand-EntityUnleashEvent.patch (100%) rename patches/{server => unapplied}/0482-Reset-shield-blocking-on-dimension-change.patch (100%) rename patches/{server => unapplied}/0483-Add-DragonEggFormEvent.patch (100%) rename patches/{server => unapplied}/0484-Add-EntityMoveEvent.patch (100%) rename patches/{server => unapplied}/0485-added-option-to-disable-pathfinding-updates-on-block.patch (100%) rename patches/{server => unapplied}/0486-Inline-shift-direction-fields.patch (100%) rename patches/{server => unapplied}/0487-Allow-adding-items-to-BlockDropItemEvent.patch (100%) rename patches/{server => unapplied}/0488-Add-getMainThreadExecutor-to-BukkitScheduler.patch (100%) rename patches/{server => unapplied}/0489-living-entity-allow-attribute-registration.patch (100%) rename patches/{server => unapplied}/0490-fix-dead-slime-setSize-invincibility.patch (100%) rename patches/{server => unapplied}/0491-Merchant-getRecipes-should-return-an-immutable-list.patch (100%) rename patches/{server => unapplied}/0492-Expose-Tracked-Players.patch (100%) rename patches/{server => unapplied}/0493-Improve-ServerGUI.patch (100%) rename patches/{server => unapplied}/0494-fix-converting-txt-to-json-file.patch (100%) rename patches/{server => unapplied}/0495-Add-worldborder-events.patch (100%) rename patches/{server => unapplied}/0496-Add-PlayerNameEntityEvent.patch (100%) rename patches/{server => unapplied}/0497-Add-recipe-to-cook-events.patch (100%) rename patches/{server => unapplied}/0498-Add-Block-isValidTool.patch (100%) rename patches/{server => unapplied}/0499-Allow-using-signs-inside-spawn-protection.patch (100%) rename patches/{server => unapplied}/0500-Expand-world-key-API.patch (100%) rename patches/{server => unapplied}/0501-Add-fast-alternative-constructor-for-Rotations.patch (100%) rename patches/{server => unapplied}/0502-Drop-carried-item-when-player-has-disconnected.patch (100%) rename patches/{server => unapplied}/0503-forced-whitelist-use-configurable-kick-message.patch (100%) rename patches/{server => unapplied}/0504-Don-t-ignore-result-of-PlayerEditBookEvent.patch (100%) rename patches/{server => unapplied}/0505-Expose-protocol-version.patch (100%) rename patches/{server => unapplied}/0506-Enhance-console-tab-completions-for-brigadier-comman.patch (100%) rename patches/{server => unapplied}/0507-Fix-PlayerItemConsumeEvent-cancelling-properly.patch (100%) rename patches/{server => unapplied}/0508-Add-bypass-host-check.patch (100%) rename patches/{server => unapplied}/0509-Set-area-affect-cloud-rotation.patch (100%) rename patches/{server => unapplied}/0510-add-isDeeplySleeping-to-HumanEntity.patch (100%) rename patches/{server => unapplied}/0511-add-consumeFuel-to-FurnaceBurnEvent.patch (100%) rename patches/{server => unapplied}/0512-add-get-set-drop-chance-to-EntityEquipment.patch (100%) rename patches/{server => unapplied}/0513-fix-PigZombieAngerEvent-cancellation.patch (100%) rename patches/{server => unapplied}/0514-fix-PlayerItemHeldEvent-firing-twice.patch (100%) rename patches/{server => unapplied}/0515-Add-PlayerDeepSleepEvent.patch (100%) rename patches/{server => unapplied}/0516-More-World-API.patch (100%) rename patches/{server => unapplied}/0517-Add-PlayerBedFailEnterEvent.patch (100%) rename patches/{server => unapplied}/0518-Implement-methods-to-convert-between-Component-and-B.patch (100%) rename patches/{server => unapplied}/0519-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch (100%) rename patches/{server => unapplied}/0520-Introduce-beacon-activation-deactivation-events.patch (100%) rename patches/{server => unapplied}/0521-Add-Channel-initialization-listeners.patch (100%) rename patches/{server => unapplied}/0522-Send-empty-commands-if-tab-completion-is-disabled.patch (100%) rename patches/{server => unapplied}/0523-Add-more-WanderingTrader-API.patch (100%) rename patches/{server => unapplied}/0524-Add-EntityBlockStorage-clearEntities.patch (100%) rename patches/{server => unapplied}/0525-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch (100%) rename patches/{server => unapplied}/0526-Add-HiddenPotionEffect-API.patch (100%) rename patches/{server => unapplied}/0527-Inventory-close.patch (100%) rename patches/{server => unapplied}/0528-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch (100%) rename patches/{server => unapplied}/0529-Add-basic-Datapack-API.patch (100%) rename patches/{server => unapplied}/0530-Add-environment-variable-to-disable-server-gui.patch (100%) rename patches/{server => unapplied}/0531-Expand-PlayerGameModeChangeEvent.patch (100%) rename patches/{server => unapplied}/0532-ItemStack-repair-check-API.patch (100%) rename patches/{server => unapplied}/0533-More-Enchantment-API.patch (100%) rename patches/{server => unapplied}/0534-Move-range-check-for-block-placing-up.patch (100%) rename patches/{server => unapplied}/0535-Add-Mob-lookAt-API.patch (100%) rename patches/{server => unapplied}/0536-Correctly-check-if-bucket-dispenses-will-succeed-for.patch (100%) rename patches/{server => unapplied}/0537-Add-Unix-domain-socket-support.patch (100%) rename patches/{server => unapplied}/0538-Add-EntityInsideBlockEvent.patch (100%) rename patches/{server => unapplied}/0539-Improve-item-default-attribute-API.patch (100%) rename patches/{server => unapplied}/0540-Add-cause-to-Weather-ThunderChangeEvents.patch (100%) rename patches/{server => unapplied}/0541-More-Lidded-Block-API.patch (100%) rename patches/{server => unapplied}/0542-Limit-item-frame-cursors-on-maps.patch (100%) rename patches/{server => unapplied}/0543-Add-PlayerKickEvent-causes.patch (100%) rename patches/{server => unapplied}/0544-Add-PufferFishStateChangeEvent.patch (100%) rename patches/{server => unapplied}/0545-Fix-PlayerBucketEmptyEvent-result-itemstack.patch (100%) rename patches/{server => unapplied}/0546-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch (100%) rename patches/{server => unapplied}/0547-Add-option-to-fix-items-merging-through-walls.patch (100%) rename patches/{server => unapplied}/0548-Add-BellRevealRaiderEvent.patch (100%) rename patches/{server => unapplied}/0549-Fix-invulnerable-end-crystals.patch (100%) rename patches/{server => unapplied}/0550-Add-ElderGuardianAppearanceEvent.patch (100%) rename patches/{server => unapplied}/0551-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch (100%) rename patches/{server => unapplied}/0552-Line-Of-Sight-Changes.patch (100%) rename patches/{server => unapplied}/0553-add-per-world-spawn-limits.patch (100%) rename patches/{server => unapplied}/0554-Fix-potions-splash-events.patch (100%) rename patches/{server => unapplied}/0555-Add-more-LimitedRegion-API.patch (100%) rename patches/{server => unapplied}/0556-Fix-PlayerDropItemEvent-using-wrong-item.patch (100%) rename patches/{server => unapplied}/0557-Missing-Entity-API.patch (100%) rename patches/{server => unapplied}/0558-Fix-return-value-of-Block-applyBoneMeal-always-being.patch (100%) rename patches/{server => unapplied}/0559-Use-getChunkIfLoadedImmediately-in-places.patch (100%) rename patches/{server => unapplied}/0560-Fix-commands-from-signs-not-firing-command-events.patch (100%) rename patches/{server => unapplied}/0561-Add-PlayerArmSwingEvent.patch (100%) rename patches/{server => unapplied}/0562-Fix-kick-event-leave-message-not-being-sent.patch (100%) rename patches/{server => unapplied}/0563-Don-t-apply-cramming-damage-to-players.patch (100%) rename patches/{server => unapplied}/0564-Rate-options-and-timings-for-sensors-and-behaviors.patch (100%) rename patches/{server => unapplied}/0565-Add-missing-forceDrop-toggles.patch (100%) rename patches/{server => unapplied}/0566-Stinger-API.patch (100%) rename patches/{server => unapplied}/0567-Add-System.out-err-catcher.patch (100%) rename patches/{server => unapplied}/0568-Prevent-AFK-kick-while-watching-end-credits.patch (100%) rename patches/{server => unapplied}/0569-Allow-skipping-writing-of-comments-to-server.propert.patch (100%) rename patches/{server => unapplied}/0570-Add-PlayerSetSpawnEvent.patch (100%) rename patches/{server => unapplied}/0571-Make-hoppers-respect-inventory-max-stack-size.patch (100%) rename patches/{server => unapplied}/0572-Optimize-entity-tracker-passenger-checks.patch (100%) rename patches/{server => unapplied}/0573-Config-option-for-Piglins-guarding-chests.patch (100%) rename patches/{server => unapplied}/0574-Add-EntityDamageItemEvent.patch (100%) rename patches/{server => unapplied}/0575-Optimize-indirect-passenger-iteration.patch (100%) rename patches/{server => unapplied}/0576-Configurable-item-frame-map-cursor-update-interval.patch (100%) rename patches/{server => unapplied}/0577-Change-EnderEye-target-without-changing-other-things.patch (100%) rename patches/{server => unapplied}/0578-Add-BlockBreakBlockEvent.patch (100%) rename patches/{server => unapplied}/0579-Option-to-prevent-data-components-copy-in-smithing-r.patch (100%) rename patches/{server => unapplied}/0580-More-CommandBlock-API.patch (100%) rename patches/{server => unapplied}/0581-Add-missing-team-sidebar-display-slots.patch (100%) rename patches/{server => unapplied}/0582-Add-back-EntityPortalExitEvent.patch (100%) rename patches/{server => unapplied}/0583-Add-methods-to-find-targets-for-lightning-strikes.patch (100%) rename patches/{server => unapplied}/0584-Get-entity-default-attributes.patch (100%) rename patches/{server => unapplied}/0585-Left-handed-API.patch (100%) rename patches/{server => unapplied}/0586-Add-more-advancement-API.patch (100%) rename patches/{server => unapplied}/0587-Add-ItemFactory-getSpawnEgg-API.patch (100%) rename patches/{server => unapplied}/0588-Add-critical-damage-API.patch (100%) rename patches/{server => unapplied}/0589-Fix-issues-with-mob-conversion.patch (100%) rename patches/{server => unapplied}/0590-Add-hasCollision-methods-to-various-places.patch (100%) rename patches/{server => unapplied}/0591-Goat-ram-API.patch (100%) rename patches/{server => unapplied}/0592-Add-API-for-resetting-a-single-score.patch (100%) rename patches/{server => unapplied}/0593-Add-Raw-Byte-Entity-Serialization.patch (100%) rename patches/{server => unapplied}/0594-Vanilla-command-permission-fixes.patch (100%) rename patches/{server => unapplied}/0595-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch (100%) rename patches/{server => unapplied}/0596-Fix-GameProfileCache-concurrency.patch (100%) rename patches/{server => unapplied}/0597-Improve-and-expand-AsyncCatcher.patch (100%) rename patches/{server => unapplied}/0598-Add-paper-mobcaps-and-paper-playermobcaps.patch (100%) rename patches/{server => unapplied}/0599-Sanitize-ResourceLocation-error-logging.patch (100%) rename patches/{server => unapplied}/0600-Manually-inline-methods-in-BlockPosition.patch (100%) rename patches/{server => unapplied}/0601-Name-craft-scheduler-threads-according-to-the-plugin.patch (100%) rename patches/{server => unapplied}/0602-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch (100%) rename patches/{server => unapplied}/0603-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch (100%) rename patches/{server => unapplied}/0604-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch (100%) rename patches/{server => unapplied}/0605-Time-scoreboard-search.patch (100%) rename patches/{server => unapplied}/0606-Oprimise-map-impl-for-tracked-players.patch (100%) rename patches/{server => unapplied}/0607-Add-missing-InventoryType.patch (100%) rename patches/{server => unapplied}/0608-Optimise-BlockSoil-nearby-water-lookup.patch (100%) rename patches/{server => unapplied}/0609-Fix-merchant-inventory-not-closing-on-entity-removal.patch (100%) rename patches/{server => unapplied}/0610-Check-requirement-before-suggesting-root-nodes.patch (100%) rename patches/{server => unapplied}/0611-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch (100%) rename patches/{server => unapplied}/0612-Add-packet-limiter-config.patch (100%) rename patches/{server => unapplied}/0613-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch (100%) rename patches/{server => unapplied}/0614-Ensure-valid-vehicle-status.patch (100%) rename patches/{server => unapplied}/0615-Prevent-softlocked-end-exit-portal-generation.patch (100%) rename patches/{server => unapplied}/0616-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch (100%) rename patches/{server => unapplied}/0617-Don-t-log-debug-logging-being-disabled.patch (100%) rename patches/{server => unapplied}/0618-fix-various-menus-with-empty-level-accesses.patch (100%) rename patches/{server => unapplied}/0619-Preserve-overstacked-loot.patch (100%) rename patches/{server => unapplied}/0620-Update-head-rotation-in-missing-places.patch (100%) rename patches/{server => unapplied}/0621-prevent-unintended-light-block-manipulation.patch (100%) rename patches/{server => unapplied}/0622-Fix-CraftCriteria-defaults-map.patch (100%) rename patches/{server => unapplied}/0623-Fix-upstreams-block-state-factories.patch (100%) rename patches/{server => unapplied}/0624-Configurable-feature-seeds.patch (100%) rename patches/{server => unapplied}/0625-Add-root-admin-user-detection.patch (100%) rename patches/{server => unapplied}/0626-don-t-attempt-to-teleport-dead-entities.patch (100%) rename patches/{server => unapplied}/0627-Prevent-excessive-velocity-through-repeated-crits.patch (100%) rename patches/{server => unapplied}/0628-Remove-client-side-code-using-deprecated-for-removal.patch (100%) rename patches/{server => unapplied}/0629-Fix-Spigot-growth-modifiers.patch (100%) rename patches/{server => unapplied}/0630-Prevent-ContainerOpenersCounter-openCount-from-going.patch (100%) rename patches/{server => unapplied}/0631-Add-PlayerItemFrameChangeEvent.patch (100%) rename patches/{server => unapplied}/0632-Optimize-HashMapPalette.patch (100%) rename patches/{server => unapplied}/0633-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch (100%) rename patches/{server => unapplied}/0634-Add-more-Campfire-API.patch (100%) rename patches/{server => unapplied}/0635-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch (100%) rename patches/{server => unapplied}/0636-Forward-CraftEntity-in-teleport-command.patch (100%) rename patches/{server => unapplied}/0637-Improve-scoreboard-entries.patch (100%) rename patches/{server => unapplied}/0638-Entity-powdered-snow-API.patch (100%) rename patches/{server => unapplied}/0639-Add-API-for-item-entity-health.patch (100%) rename patches/{server => unapplied}/0640-Configurable-max-block-light-for-monster-spawning.patch (100%) rename patches/{server => unapplied}/0641-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch (100%) rename patches/{server => unapplied}/0642-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch (100%) rename patches/{server => unapplied}/0643-Bucketable-API.patch (100%) rename patches/{server => unapplied}/0644-Validate-usernames.patch (100%) rename patches/{server => unapplied}/0645-Make-water-animal-spawn-height-configurable.patch (100%) rename patches/{server => unapplied}/0646-Expose-vanilla-BiomeProvider-from-WorldInfo.patch (100%) rename patches/{server => unapplied}/0647-Add-config-option-for-worlds-affected-by-time-cmd.patch (100%) rename patches/{server => unapplied}/0648-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch (100%) rename patches/{server => unapplied}/0649-Multiple-Entries-with-Scoreboards.patch (100%) rename patches/{server => unapplied}/0650-Reset-placed-block-on-exception.patch (100%) rename patches/{server => unapplied}/0651-Add-configurable-height-for-slime-spawn.patch (100%) rename patches/{server => unapplied}/0652-Fix-xp-reward-for-baby-zombies.patch (100%) rename patches/{server => unapplied}/0653-Multi-Block-Change-API-Implementation.patch (100%) rename patches/{server => unapplied}/0654-Fix-NotePlayEvent.patch (100%) rename patches/{server => unapplied}/0655-Freeze-Tick-Lock-API.patch (100%) rename patches/{server => unapplied}/0656-More-PotionEffectType-API.patch (100%) rename patches/{server => unapplied}/0657-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch (100%) rename patches/{server => unapplied}/0658-API-for-creating-command-sender-which-forwards-feedb.patch (100%) rename patches/{server => unapplied}/0659-Add-missing-structure-set-seed-configs.patch (100%) rename patches/{server => unapplied}/0660-Fix-cancelled-powdered-snow-bucket-placement.patch (100%) rename patches/{server => unapplied}/0661-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch (100%) rename patches/{server => unapplied}/0662-Add-GameEvent-tags.patch (100%) rename patches/{server => unapplied}/0663-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch (100%) rename patches/{server => unapplied}/0664-Furnace-RecipesUsed-API.patch (100%) rename patches/{server => unapplied}/0665-Configurable-sculk-sensor-listener-range.patch (100%) rename patches/{server => unapplied}/0666-Add-missing-block-data-API.patch (100%) rename patches/{server => unapplied}/0667-Option-to-have-default-CustomSpawners-in-custom-worl.patch (100%) rename patches/{server => unapplied}/0668-Put-world-into-worldlist-before-initing-the-world.patch (100%) rename patches/{server => unapplied}/0669-Custom-Potion-Mixes.patch (100%) rename patches/{server => unapplied}/0670-Force-close-world-loading-screen.patch (100%) rename patches/{server => unapplied}/0671-Fix-falling-block-spawn-methods.patch (100%) rename patches/{server => unapplied}/0672-Expose-furnace-minecart-push-values.patch (100%) rename patches/{server => unapplied}/0673-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch (100%) rename patches/{server => unapplied}/0674-More-Projectile-API.patch (100%) rename patches/{server => unapplied}/0675-Fix-swamp-hut-cat-generation-deadlock.patch (100%) rename patches/{server => unapplied}/0676-Don-t-allow-vehicle-movement-from-players-while-tele.patch (100%) rename patches/{server => unapplied}/0677-Implement-getComputedBiome-API.patch (100%) rename patches/{server => unapplied}/0678-Make-some-itemstacks-nonnull.patch (100%) rename patches/{server => unapplied}/0679-Implement-enchantWithLevels-API.patch (100%) rename patches/{server => unapplied}/0680-Fix-saving-in-unloadWorld.patch (100%) rename patches/{server => unapplied}/0681-Buffer-OOB-setBlock-calls.patch (100%) rename patches/{server => unapplied}/0682-Add-TameableDeathMessageEvent.patch (100%) rename patches/{server => unapplied}/0683-Fix-new-block-data-for-EntityChangeBlockEvent.patch (100%) rename patches/{server => unapplied}/0684-fix-player-loottables-running-when-mob-loot-gamerule.patch (100%) rename patches/{server => unapplied}/0685-Ensure-entity-passenger-world-matches-ridden-entity.patch (100%) rename patches/{server => unapplied}/0686-Cache-resource-keys-and-optimize-reference-Holder-ta.patch (100%) rename patches/{server => unapplied}/0687-Allow-changing-the-EnderDragon-podium.patch (100%) rename patches/{server => unapplied}/0688-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch (100%) rename patches/{server => unapplied}/0689-Prevent-tile-entity-copies-loading-chunks.patch (100%) rename patches/{server => unapplied}/0690-Use-username-instead-of-display-name-in-PlayerList-g.patch (100%) rename patches/{server => unapplied}/0691-Expand-PlayerItemDamageEvent.patch (100%) rename patches/{server => unapplied}/0692-WorldCreator-keepSpawnLoaded.patch (100%) rename patches/{server => unapplied}/0693-Fix-CME-in-CraftPersistentDataTypeRegistry.patch (100%) rename patches/{server => unapplied}/0694-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch (100%) rename patches/{server => unapplied}/0695-Add-EntityDyeEvent-and-CollarColorable-interface.patch (100%) rename patches/{server => unapplied}/0696-Fire-CauldronLevelChange-on-initial-fill.patch (100%) rename patches/{server => unapplied}/0697-fix-powder-snow-cauldrons-not-turning-to-water.patch (100%) rename patches/{server => unapplied}/0698-Add-PlayerStopUsingItemEvent.patch (100%) rename patches/{server => unapplied}/0699-Don-t-tick-markers.patch (100%) rename patches/{server => unapplied}/0700-Expand-FallingBlock-API.patch (100%) rename patches/{server => unapplied}/0701-Add-support-for-Proxy-Protocol.patch (100%) rename patches/{server => unapplied}/0702-Fix-OfflinePlayer-getBedSpawnLocation.patch (100%) rename patches/{server => unapplied}/0703-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch (100%) rename patches/{server => unapplied}/0704-Sanitize-sent-BlockEntity-NBT.patch (100%) rename patches/{server => unapplied}/0705-Disable-component-selector-resolving-in-books-by-def.patch (100%) rename patches/{server => unapplied}/0706-Prevent-entity-loading-causing-async-lookups.patch (100%) rename patches/{server => unapplied}/0707-Throw-exception-on-world-create-while-being-ticked.patch (100%) rename patches/{server => unapplied}/0708-Dont-resent-entity-on-art-update.patch (100%) rename patches/{server => unapplied}/0709-Add-WardenAngerChangeEvent.patch (100%) rename patches/{server => unapplied}/0710-Add-option-for-strict-advancement-dimension-checks.patch (100%) rename patches/{server => unapplied}/0711-Add-missing-important-BlockStateListPopulator-method.patch (100%) rename patches/{server => unapplied}/0712-Nameable-Banner-API.patch (100%) rename patches/{server => unapplied}/0713-Don-t-broadcast-messages-to-command-blocks.patch (100%) rename patches/{server => unapplied}/0714-Prevent-empty-items-from-being-added-to-world.patch (100%) rename patches/{server => unapplied}/0715-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch (100%) rename patches/{server => unapplied}/0716-Add-Player-getFishHook.patch (100%) rename patches/{server => unapplied}/0717-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch (100%) rename patches/{server => unapplied}/0718-Add-various-missing-EntityDropItemEvent-calls.patch (100%) rename patches/{server => unapplied}/0719-Fix-Bee-flower-NPE.patch (100%) rename patches/{server => unapplied}/0720-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch (100%) rename patches/{server => unapplied}/0721-More-Teleport-API.patch (100%) rename patches/{server => unapplied}/0722-Add-EntityPortalReadyEvent.patch (100%) rename patches/{server => unapplied}/0723-Don-t-use-level-random-in-entity-constructors.patch (100%) rename patches/{server => unapplied}/0724-Send-block-entities-after-destroy-prediction.patch (100%) rename patches/{server => unapplied}/0725-Warn-on-plugins-accessing-faraway-chunks.patch (100%) rename patches/{server => unapplied}/0726-Custom-Chat-Completion-Suggestions-API.patch (100%) rename patches/{server => unapplied}/0727-Add-and-fix-missing-BlockFadeEvents.patch (100%) rename patches/{server => unapplied}/0728-Collision-API.patch (100%) rename patches/{server => unapplied}/0729-Fix-suggest-command-message-for-brigadier-syntax-exc.patch (100%) rename patches/{server => unapplied}/0730-Block-Ticking-API.patch (100%) rename patches/{server => unapplied}/0731-Add-Velocity-IP-Forwarding-Support.patch (100%) rename patches/{server => unapplied}/0732-Add-NamespacedKey-biome-methods.patch (100%) rename patches/{server => unapplied}/0733-Fix-plugin-loggers-on-server-shutdown.patch (100%) rename patches/{server => unapplied}/0734-Stop-large-look-changes-from-crashing-the-server.patch (100%) rename patches/{server => unapplied}/0735-Fire-EntityChangeBlockEvent-in-more-places.patch (100%) rename patches/{server => unapplied}/0736-Missing-eating-regain-reason.patch (100%) rename patches/{server => unapplied}/0737-Missing-effect-cause.patch (100%) rename patches/{server => unapplied}/0738-Added-byte-array-serialization-deserialization-for-P.patch (100%) rename patches/{server => unapplied}/0739-Call-BlockPhysicsEvent-more-often.patch (100%) rename patches/{server => unapplied}/0740-Configurable-chat-thread-limit.patch (100%) rename patches/{server => unapplied}/0741-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch (100%) rename patches/{server => unapplied}/0742-fix-Jigsaw-block-kicking-user.patch (100%) rename patches/{server => unapplied}/0743-use-BlockFormEvent-for-mud-converting-into-clay.patch (100%) rename patches/{server => unapplied}/0744-Add-getDrops-to-BlockState.patch (100%) rename patches/{server => unapplied}/0745-Fix-a-bunch-of-vanilla-bugs.patch (100%) rename patches/{server => unapplied}/0746-Remove-unnecessary-onTrackingStart-during-navigation.patch (100%) rename patches/{server => unapplied}/0747-Fix-custom-piglin-loved-items.patch (100%) rename patches/{server => unapplied}/0748-EntityPickupItemEvent-fixes.patch (100%) rename patches/{server => unapplied}/0749-Correctly-handle-interactions-with-items-on-cooldown.patch (100%) rename patches/{server => unapplied}/0750-Add-PlayerInventorySlotChangeEvent.patch (100%) rename patches/{server => unapplied}/0751-Elder-Guardian-appearance-API.patch (100%) rename patches/{server => unapplied}/0752-Add-entity-knockback-API.patch (100%) rename patches/{server => unapplied}/0753-Detect-headless-JREs.patch (100%) rename patches/{server => unapplied}/0754-fix-entity-vehicle-collision-event-not-called.patch (100%) rename patches/{server => unapplied}/0755-Add-EntityToggleSitEvent.patch (100%) rename patches/{server => unapplied}/0756-Add-fire-tick-delay-option.patch (100%) rename patches/{server => unapplied}/0757-Add-Moving-Piston-API.patch (100%) rename patches/{server => unapplied}/0758-Ignore-impossible-spawn-tick.patch (100%) rename patches/{server => unapplied}/0759-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch (100%) rename patches/{server => unapplied}/0760-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch (100%) rename patches/{server => unapplied}/0761-Add-PrePlayerAttackEntityEvent.patch (100%) rename patches/{server => unapplied}/0762-ensure-reset-EnderDragon-boss-event-name.patch (100%) rename patches/{server => unapplied}/0763-Add-Player-Warden-Warning-API.patch (100%) rename patches/{server => unapplied}/0764-More-vanilla-friendly-methods-to-update-trades.patch (100%) rename patches/{server => unapplied}/0765-Add-paper-dumplisteners-command.patch (100%) rename patches/{server => unapplied}/0766-check-global-player-list-where-appropriate.patch (100%) rename patches/{server => unapplied}/0767-Fix-async-entity-add-due-to-fungus-trees.patch (100%) rename patches/{server => unapplied}/0768-ItemStack-damage-API.patch (100%) rename patches/{server => unapplied}/0769-Friction-API.patch (100%) rename patches/{server => unapplied}/0770-Ability-to-control-player-s-insomnia-and-phantoms.patch (100%) rename patches/{server => unapplied}/0771-Fix-premature-player-kicks-on-shutdown.patch (100%) rename patches/{server => unapplied}/0772-Sync-offhand-slot-in-menus.patch (100%) rename patches/{server => unapplied}/0773-Player-Entity-Tracking-Events.patch (100%) rename patches/{server => unapplied}/0774-Limit-pet-look-distance.patch (100%) rename patches/{server => unapplied}/0775-fix-Instruments.patch (100%) rename patches/{server => unapplied}/0776-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch (100%) rename patches/{server => unapplied}/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch (100%) rename patches/{server => unapplied}/0778-Add-BlockLockCheckEvent.patch (100%) rename patches/{server => unapplied}/0779-Add-Sneaking-API-for-Entities.patch (100%) rename patches/{server => unapplied}/0780-Improve-logging-and-errors.patch (100%) rename patches/{server => unapplied}/0781-Improve-PortalEvents.patch (100%) rename patches/{server => unapplied}/0782-Add-config-option-for-spider-worldborder-climbing.patch (100%) rename patches/{server => unapplied}/0783-Add-missing-SpigotConfig-logCommands-check.patch (100%) rename patches/{server => unapplied}/0784-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch (100%) rename patches/{server => unapplied}/0785-Flying-Fall-Damage.patch (100%) rename patches/{server => unapplied}/0786-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch (100%) rename patches/{server => unapplied}/0787-config-for-disabling-entity-tag-tags.patch (100%) rename patches/{server => unapplied}/0788-Use-single-player-info-update-packet-on-join.patch (100%) rename patches/{server => unapplied}/0789-Correctly-shrink-items-during-EntityResurrectEvent.patch (100%) rename patches/{server => unapplied}/0790-Win-Screen-API.patch (100%) rename patches/{server => unapplied}/0791-Remove-CraftItemStack-setAmount-null-assignment.patch (100%) rename patches/{server => unapplied}/0792-Fix-force-opening-enchantment-tables.patch (100%) rename patches/{server => unapplied}/0793-Add-Entity-Body-Yaw-API.patch (100%) rename patches/{server => unapplied}/0794-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch (100%) rename patches/{server => unapplied}/0795-Add-EntityFertilizeEggEvent.patch (100%) rename patches/{server => unapplied}/0796-Fix-HumanEntity-drop-not-updating-the-client-inv.patch (100%) rename patches/{server => unapplied}/0797-Add-CompostItemEvent-and-EntityCompostItemEvent.patch (100%) rename patches/{server => unapplied}/0798-Correctly-handle-ArmorStand-invisibility.patch (100%) rename patches/{server => unapplied}/0799-Fix-advancement-triggers-for-entity-damage.patch (100%) rename patches/{server => unapplied}/0800-Fix-text-display-error-on-spawn.patch (100%) rename patches/{server => unapplied}/0801-Fix-inventories-returning-null-Locations.patch (100%) rename patches/{server => unapplied}/0802-Add-Shearable-API.patch (100%) rename patches/{server => unapplied}/0803-Fix-SpawnEggMeta-get-setSpawnedType.patch (100%) rename patches/{server => unapplied}/0804-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch (100%) rename patches/{server => unapplied}/0805-Treat-sequence-violations-like-they-should-be.patch (100%) rename patches/{server => unapplied}/0806-Prevent-causing-expired-keys-from-impacting-new-join.patch (100%) rename patches/{server => unapplied}/0807-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch (100%) rename patches/{server => unapplied}/0808-Use-array-for-gamerule-storage.patch (100%) rename patches/{server => unapplied}/0809-Fix-a-couple-of-upstream-bed-issues.patch (100%) rename patches/{server => unapplied}/0810-Fix-demo-flag-not-enabling-demo-mode.patch (100%) rename patches/{server => unapplied}/0811-Add-Mob-Experience-reward-API.patch (100%) rename patches/{server => unapplied}/0812-Break-redstone-on-top-of-trap-doors-early.patch (100%) rename patches/{server => unapplied}/0813-Avoid-Lazy-Initialization-for-Enum-Fields.patch (100%) rename patches/{server => unapplied}/0814-More-accurate-isInOpenWater-impl.patch (100%) rename patches/{server => unapplied}/0815-Expand-PlayerItemMendEvent.patch (100%) rename patches/{server => unapplied}/0816-Refresh-ProjectileSource-for-projectiles.patch (100%) rename patches/{server => unapplied}/0817-Add-transient-modifier-API.patch (100%) rename patches/{server => unapplied}/0818-Fix-block-place-logic.patch (100%) rename patches/{server => unapplied}/0819-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch (100%) rename patches/{server => unapplied}/0820-Call-BlockGrowEvent-for-missing-blocks.patch (100%) rename patches/{server => unapplied}/0821-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch (100%) rename patches/{server => unapplied}/0822-fix-MapLike-spam-for-missing-key-selector.patch (100%) rename patches/{server => unapplied}/0823-Fix-sniffer-removeExploredLocation.patch (100%) rename patches/{server => unapplied}/0824-Add-method-to-remove-all-active-potion-effects.patch (100%) rename patches/{server => unapplied}/0825-Fix-incorrect-crafting-result-amount-for-fireworks.patch (100%) rename patches/{server => unapplied}/0826-Add-event-for-player-editing-sign.patch (100%) rename patches/{server => unapplied}/0827-Only-tick-item-frames-if-players-can-see-it.patch (100%) rename patches/{server => unapplied}/0828-Fix-cmd-permission-levels-for-command-blocks.patch (100%) rename patches/{server => unapplied}/0829-Add-option-to-disable-block-updates.patch (100%) rename patches/{server => unapplied}/0830-Call-missing-BlockDispenseEvent.patch (100%) rename patches/{server => unapplied}/0831-Don-t-load-chunks-for-supporting-block-checks.patch (100%) rename patches/{server => unapplied}/0832-Optimize-player-lookups-for-beacons.patch (100%) rename patches/{server => unapplied}/0833-More-Sign-Block-API.patch (100%) rename patches/{server => unapplied}/0834-fix-item-meta-for-tadpole-buckets.patch (100%) rename patches/{server => unapplied}/0835-Fix-BanList-API.patch (100%) rename patches/{server => unapplied}/0836-Determine-lava-and-water-fluid-explosion-resistance-.patch (100%) rename patches/{server => unapplied}/0837-Fix-possible-NPE-on-painting-creation.patch (100%) rename patches/{server => unapplied}/0838-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch (100%) rename patches/{server => unapplied}/0839-ExperienceOrb-should-call-EntitySpawnEvent.patch (100%) rename patches/{server => unapplied}/0840-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch (100%) rename patches/{server => unapplied}/0841-Add-whitelist-events.patch (100%) rename patches/{server => unapplied}/0842-Implement-PlayerFailMoveEvent.patch (100%) rename patches/{server => unapplied}/0843-Folia-scheduler-and-owned-region-API.patch (100%) rename patches/{server => unapplied}/0844-Only-erase-allay-memory-on-non-item-targets.patch (100%) rename patches/{server => unapplied}/0845-API-for-updating-recipes-on-clients.patch (100%) rename patches/{server => unapplied}/0846-Fix-rotation-when-spawning-display-entities.patch (100%) rename patches/{server => unapplied}/0847-Only-capture-actual-tree-growth.patch (100%) rename patches/{server => unapplied}/0848-Use-correct-source-for-mushroom-block-spread-event.patch (100%) rename patches/{server => unapplied}/0849-Respect-randomizeData-on-more-entities-when-spawning.patch (100%) rename patches/{server => unapplied}/0850-Use-correct-seed-on-api-world-load.patch (100%) rename patches/{server => unapplied}/0851-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch (100%) rename patches/{server => unapplied}/0852-Cache-map-ids-on-item-frames.patch (100%) rename patches/{server => unapplied}/0853-Fix-custom-statistic-criteria-creation.patch (100%) rename patches/{server => unapplied}/0854-Bandaid-fix-for-Effect.patch (100%) rename patches/{server => unapplied}/0855-SculkCatalyst-bloom-API.patch (100%) rename patches/{server => unapplied}/0856-API-for-an-entity-s-scoreboard-name.patch (100%) rename patches/{server => unapplied}/0857-Deprecate-and-replace-methods-with-old-StructureType.patch (100%) rename patches/{server => unapplied}/0858-Don-t-tab-complete-namespaced-commands-if-send-names.patch (100%) rename patches/{server => unapplied}/0859-Properly-handle-BlockBreakEvent-isDropItems.patch (100%) rename patches/{server => unapplied}/0860-Fire-entity-death-event-for-ender-dragon.patch (100%) rename patches/{server => unapplied}/0861-Configurable-entity-tracking-range-by-Y-coordinate.patch (100%) rename patches/{server => unapplied}/0862-Add-Listing-API-for-Player.patch (100%) rename patches/{server => unapplied}/0863-Configurable-Region-Compression-Format.patch (100%) rename patches/{server => unapplied}/0864-Add-BlockFace-to-BlockDamageEvent.patch (100%) rename patches/{server => unapplied}/0865-Fix-NPE-on-Boat-getStatus.patch (100%) rename patches/{server => unapplied}/0866-Expand-Pose-API.patch (100%) rename patches/{server => unapplied}/0867-More-DragonBattle-API.patch (100%) rename patches/{server => unapplied}/0868-Add-PlayerPickItemEvent.patch (100%) rename patches/{server => unapplied}/0869-Allow-trident-custom-damage.patch (100%) rename patches/{server => unapplied}/0870-Expose-hand-in-BlockCanBuildEvent.patch (100%) rename patches/{server => unapplied}/0871-Optimize-nearest-structure-border-iteration.patch (100%) rename patches/{server => unapplied}/0872-Implement-OfflinePlayer-isConnected.patch (100%) rename patches/{server => unapplied}/0873-Fix-slot-desync.patch (100%) rename patches/{server => unapplied}/0874-Add-titleOverride-to-InventoryOpenEvent.patch (100%) rename patches/{server => unapplied}/0875-Configure-sniffer-egg-hatch-time.patch (100%) rename patches/{server => unapplied}/0876-Do-crystal-portal-proximity-check-before-entity-look.patch (100%) rename patches/{server => unapplied}/0877-Skip-POI-finding-if-stuck-in-vehicle.patch (100%) rename patches/{server => unapplied}/0878-Add-slot-sanity-checks-in-container-clicks.patch (100%) rename patches/{server => unapplied}/0879-Call-BlockRedstoneEvents-for-lecterns.patch (100%) rename patches/{server => unapplied}/0880-Allow-proper-checking-of-empty-item-stacks.patch (100%) rename patches/{server => unapplied}/0881-Fix-silent-equipment-change-for-mobs.patch (100%) rename patches/{server => unapplied}/0882-Fix-spigot-s-Forced-Stats.patch (100%) rename patches/{server => unapplied}/0883-Add-missing-InventoryHolders-to-inventories.patch (100%) rename patches/{server => unapplied}/0884-Do-not-read-tile-entities-in-chunks-that-are-positio.patch (100%) rename patches/{server => unapplied}/0885-Add-missing-logs-for-log-ips-config-option.patch (100%) rename patches/{server => unapplied}/0886-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch (100%) rename patches/{server => unapplied}/0887-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch (100%) rename patches/{server => unapplied}/0888-Fix-team-sidebar-objectives-not-being-cleared.patch (100%) rename patches/{server => unapplied}/0889-Fix-missing-map-initialize-event-call.patch (100%) rename patches/{server => unapplied}/0890-Update-entity-data-when-attaching-firework-to-entity.patch (100%) rename patches/{server => unapplied}/0891-Fix-UnsafeValues-loadAdvancement.patch (100%) rename patches/{server => unapplied}/0892-Add-player-idle-duration-API.patch (100%) rename patches/{server => unapplied}/0893-Don-t-check-if-we-can-see-non-visible-entities.patch (100%) rename patches/{server => unapplied}/0894-Fix-NPE-in-SculkBloomEvent-world-access.patch (100%) rename patches/{server => unapplied}/0895-Allow-null-itemstack-for-Player-sendEquipmentChange.patch (100%) rename patches/{server => unapplied}/0896-Optimize-VarInts.patch (100%) rename patches/{server => unapplied}/0897-Add-API-to-get-the-collision-shape-of-a-block-before.patch (100%) rename patches/{server => unapplied}/0898-Add-predicate-for-blocks-when-raytracing.patch (100%) rename patches/{server => unapplied}/0899-Broadcast-take-item-packets-with-collector-as-source.patch (100%) rename patches/{server => unapplied}/0900-Expand-LingeringPotion-API.patch (100%) rename patches/{server => unapplied}/0901-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch (100%) rename patches/{server => unapplied}/0902-Add-hand-to-fish-event-for-all-player-interactions.patch (100%) rename patches/{server => unapplied}/0903-Fix-several-issues-with-EntityBreedEvent.patch (100%) rename patches/{server => unapplied}/0904-Add-UUID-attribute-modifier-API.patch (100%) rename patches/{server => unapplied}/0905-Fix-missing-event-call-for-entity-teleport-API.patch (100%) rename patches/{server => unapplied}/0906-Lazily-create-LootContext-for-criterions.patch (100%) rename patches/{server => unapplied}/0907-Don-t-fire-sync-events-during-worldgen.patch (100%) rename patches/{server => unapplied}/0908-Add-Structure-check-API.patch (100%) rename patches/{server => unapplied}/0909-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch (100%) rename patches/{server => unapplied}/0910-Restore-vanilla-entity-drops-behavior.patch (100%) rename patches/{server => unapplied}/0911-Dont-resend-blocks-on-interactions.patch (100%) rename patches/{server => unapplied}/0912-add-more-scoreboard-API.patch (100%) rename patches/{server => unapplied}/0913-Improve-Registry.patch (100%) rename patches/{server => unapplied}/0914-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch (100%) rename patches/{server => unapplied}/0915-Add-experience-points-API.patch (100%) rename patches/{server => unapplied}/0916-Add-drops-to-shear-events.patch (100%) rename patches/{server => unapplied}/0917-Add-PlayerShieldDisableEvent.patch (100%) rename patches/{server => unapplied}/0918-Validate-ResourceLocation-in-NBT-reading.patch (100%) rename patches/{server => unapplied}/0919-Properly-handle-experience-dropping-on-block-break.patch (100%) rename patches/{server => unapplied}/0920-Fixup-NamespacedKey-handling.patch (100%) rename patches/{server => unapplied}/0921-Expose-LootTable-of-DecoratedPot.patch (100%) rename patches/{server => unapplied}/0922-Reduce-allocation-of-Vec3D-by-entity-tracker.patch (100%) rename patches/{server => unapplied}/0923-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch (100%) rename patches/{server => unapplied}/0924-Add-ShulkerDuplicateEvent.patch (100%) rename patches/{server => unapplied}/0925-Add-api-for-spawn-egg-texture-colors.patch (100%) rename patches/{server => unapplied}/0926-Add-Lifecycle-Event-system.patch (100%) rename patches/{server => unapplied}/0927-ItemStack-Tooltip-API.patch (100%) rename patches/{server => unapplied}/0928-Add-getChunkSnapshot-includeLightData-parameter.patch (100%) rename patches/{server => unapplied}/0929-Add-FluidState-API.patch (100%) rename patches/{server => unapplied}/0930-add-number-format-api.patch (100%) rename patches/{server => unapplied}/0931-improve-BanList-types.patch (100%) rename patches/{server => unapplied}/0932-Expanded-Hopper-API.patch (100%) rename patches/{server => unapplied}/0933-Add-BlockBreakProgressUpdateEvent.patch (100%) rename patches/{server => unapplied}/0934-Deprecate-ItemStack-setType.patch (100%) rename patches/{server => unapplied}/0935-Add-CartographyItemEvent.patch (100%) rename patches/{server => unapplied}/0936-More-Raid-API.patch (100%) rename patches/{server => unapplied}/0937-Add-onboarding-message-for-initial-server-start.patch (100%) rename patches/{server => unapplied}/0938-Configurable-max-block-fluid-ticks.patch (100%) rename patches/{server => unapplied}/0939-Fix-bees-aging-inside-hives.patch (100%) rename patches/{server => unapplied}/0940-Disable-memory-reserve-allocating.patch (100%) rename patches/{server => unapplied}/0941-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch (100%) rename patches/{server => unapplied}/0942-Fix-DamageSource-API.patch (100%) rename patches/{server => unapplied}/0943-Fix-creation-of-invalid-block-entity-during-world-ge.patch (100%) rename patches/{server => unapplied}/0944-Fix-possible-StackOverflowError-for-some-dispenses.patch (100%) rename patches/{server => unapplied}/0945-Improve-tag-parser-handling.patch (100%) rename patches/{server => unapplied}/0946-Item-Mutation-Fixes.patch (100%) rename patches/{server => unapplied}/0947-Per-world-ticks-per-spawn-settings.patch (100%) rename patches/{server => unapplied}/0948-Properly-track-the-changed-item-from-dispense-events.patch (100%) rename patches/{server => unapplied}/0949-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch (100%) rename patches/{server => unapplied}/0950-Fix-tripwire-disarming-not-working-as-intended.patch (100%) rename patches/{server => unapplied}/0951-Add-config-for-mobs-immune-to-default-effects.patch (100%) rename patches/{server => unapplied}/0952-Deep-clone-nbt-tags-in-PDC.patch (100%) rename patches/{server => unapplied}/0953-Support-old-UUID-format-for-NBT.patch (100%) rename patches/{server => unapplied}/0954-Fix-shield-disable-inconsistency.patch (100%) rename patches/{server => unapplied}/0955-Handle-Large-Packets-disconnecting-client.patch (100%) rename patches/{server => unapplied}/0956-Fix-ItemFlags.patch (100%) rename patches/{server => unapplied}/0957-Fix-helmet-damage-reduction-inconsistencies.patch (100%) rename patches/{server => unapplied}/0958-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch (100%) rename patches/{server => unapplied}/0959-improve-checking-handled-tags-in-itemmeta.patch (100%) rename patches/{server => unapplied}/0960-General-ItemMeta-fixes.patch (100%) rename patches/{server => unapplied}/0961-Expose-hasColor-to-leather-armor.patch (100%) rename patches/{server => unapplied}/0962-Added-API-to-get-player-ha-proxy-address.patch (100%) rename patches/{server => unapplied}/0963-More-Chest-Block-API.patch (100%) rename patches/{server => unapplied}/0964-Print-data-component-type-on-encoding-error.patch (100%) rename patches/{server => unapplied}/0965-Brigadier-based-command-API.patch (100%) rename patches/{server => unapplied}/0966-Fix-issues-with-Recipe-API.patch (100%) rename patches/{server => unapplied}/0967-Fix-equipment-slot-and-group-API.patch (100%) rename patches/{server => unapplied}/0968-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch (100%) rename patches/{server => unapplied}/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch (100%) rename patches/{server => unapplied}/0970-Prevent-NPE-if-hooked-entity-was-cleared.patch (100%) rename patches/{server => unapplied}/0971-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch (100%) rename patches/{server => unapplied}/0972-Add-missing-fishing-event-state.patch (100%) rename patches/{server => unapplied}/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch (100%) rename patches/{server => unapplied}/0974-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch (100%) rename patches/{server => unapplied}/0975-Adopt-MaterialRerouting.patch (100%) rename patches/{server => unapplied}/0976-Suspicious-Effect-Entry-API.patch (100%) rename patches/{server => unapplied}/0977-check-if-itemstack-is-stackable-first.patch (100%) rename patches/{server => unapplied}/0978-Fix-removing-recipes-from-RecipeIterator.patch (100%) rename patches/{server => unapplied}/0979-Configurable-damage-tick-when-blocking-with-shield.patch (100%) rename patches/{server => unapplied}/0980-Properly-remove-the-experimental-smithing-inventory-.patch (100%) rename patches/{server => unapplied}/0981-Moonrise-optimisation-patches.patch (100%) rename patches/{server => unapplied}/0982-Rewrite-dataconverter-system.patch (100%) rename patches/{server => unapplied}/0983-disable-forced-empty-world-ticks.patch (100%) rename patches/{server => unapplied}/0984-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch (100%) rename patches/{server => unapplied}/0985-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch (100%) rename patches/{server => unapplied}/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch (100%) rename patches/{server => unapplied}/0987-Optimize-Network-Manager-and-add-advanced-packet-sup.patch (100%) rename patches/{server => unapplied}/0988-Allow-Saving-of-Oversized-Chunks.patch (100%) rename patches/{server => unapplied}/0989-Flat-bedrock-generator-settings.patch (100%) rename patches/{server => unapplied}/0990-Entity-Activation-Range-2.0.patch (100%) rename patches/{server => unapplied}/0991-Optional-per-player-mob-spawns.patch (100%) rename patches/{server => unapplied}/0992-Anti-Xray.patch (100%) rename patches/{server => unapplied}/0993-Eigencraft-redstone-implementation.patch (100%) rename patches/{server => unapplied}/0994-Add-Alternate-Current-redstone-implementation.patch (100%) rename patches/{server => unapplied}/0995-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch (100%) rename patches/{server => unapplied}/0996-Use-Velocity-compression-and-cipher-natives.patch (100%) rename patches/{server => unapplied}/0997-Optimize-Collision-to-not-load-chunks.patch (100%) rename patches/{server => unapplied}/0998-Optimize-GoalSelector-Goal.Flag-Set-operations.patch (100%) rename patches/{server => unapplied}/0999-Optimize-Hoppers.patch (100%) rename patches/{server => unapplied}/1000-Entity-load-save-limit-per-chunk.patch (100%) rename patches/{server => unapplied}/1001-Optimize-Voxel-Shape-Merging.patch (100%) rename patches/{server => unapplied}/1002-Optimize-Bit-Operations-by-inlining.patch (100%) rename patches/{server => unapplied}/1003-Remove-streams-from-hot-code.patch (100%) rename patches/{server => unapplied}/1004-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch (100%) rename patches/{server => unapplied}/1005-Custom-table-implementation-for-blockstate-state-loo.patch (100%) rename patches/{server => unapplied}/1006-Fix-entity-type-tags-suggestions-in-selectors.patch (100%) rename patches/{server => unapplied}/1007-Handle-Oversized-block-entities-in-chunks.patch (100%) rename patches/{server => unapplied}/1008-API-for-checking-sent-chunks.patch (100%) rename patches/{server => unapplied}/1009-Check-distance-in-entity-interactions.patch (100%) rename patches/{server => unapplied}/1010-Configurable-Sand-Duping.patch (100%) rename patches/{server => unapplied}/1011-Optimise-general-POI-access.patch (100%) rename patches/{server => unapplied}/1012-Improve-performance-of-mass-crafts.patch (100%) rename patches/{server => unapplied}/1013-Properly-resend-entities.patch (100%) rename patches/{server => unapplied}/1014-Registry-Modification-API.patch (100%) rename patches/{server => unapplied}/1015-Add-registry-entry-and-builders.patch (100%) rename patches/{server => unapplied}/1016-Improved-Watchdog-Support.patch (100%) rename patches/{server => unapplied}/1017-Proxy-ItemStack-to-CraftItemStack.patch (100%) rename patches/{server => unapplied}/1018-Make-a-PDC-view-accessible-directly-from-ItemStack.patch (100%) rename patches/{server => unapplied}/1019-Prioritize-Minecraft-commands-in-function-parsing-an.patch (100%) rename patches/{server => unapplied}/1020-optimize-dirt-and-snow-spreading.patch (100%) rename patches/{server => unapplied}/1021-Fix-NPE-for-Jukebox-setRecord.patch (100%) rename patches/{server => unapplied}/1022-Fix-CraftWorld-isChunkGenerated.patch (100%) rename patches/{server => unapplied}/1023-fix-horse-inventories.patch (100%) rename patches/{server => unapplied}/1024-Only-call-EntityDamageEvents-before-actuallyHurt.patch (100%) rename patches/{server => unapplied}/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch (100%) rename patches/{server => unapplied}/1026-Lag-compensation-ticks.patch (100%) rename patches/{server => unapplied}/1027-Detail-more-information-in-watchdog-dumps.patch (100%) rename patches/{server => unapplied}/1028-Write-SavedData-IO-async.patch (100%) rename patches/{server => unapplied}/1029-Add-ItemType-getItemRarity.patch (100%) rename patches/{server => unapplied}/1030-Incremental-chunk-and-player-saving.patch (100%) rename patches/{server => unapplied}/1031-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch (100%) rename patches/{server => unapplied}/1032-Bundle-spark.patch (100%) rename patches/{server => unapplied}/1033-Add-plugin-info-at-startup.patch (100%) rename patches/{server => unapplied}/1034-Make-interaction-leniency-distance-configurable.patch (100%) rename patches/{server => unapplied}/1035-Fix-PickupStatus-getting-reset.patch (100%) rename patches/{server => unapplied}/1036-Check-for-block-type-in-SculkSensorBlock-canActivate.patch (100%) rename patches/{server => unapplied}/1037-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch (100%) rename patches/{server => unapplied}/1038-Configuration-for-horizontal-only-item-merging.patch (100%) rename patches/{server => unapplied}/1039-Optimise-collision-checking-in-player-move-packet-ha.patch (100%) rename patches/{server => unapplied}/1040-Add-skipping-world-symlink-scan.patch (100%) rename patches/{server => unapplied}/1041-Add-even-more-Enchantment-API.patch (100%) rename patches/{server => unapplied}/1042-Leashable-API.patch (100%) rename patches/{server => unapplied}/1043-Fix-CraftBukkit-drag-system.patch (100%) rename patches/{server => unapplied}/1044-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch (100%) rename patches/{server => unapplied}/1045-Remove-set-damage-lootable-item-function-from-compas.patch (100%) rename patches/{server => unapplied}/1046-Properly-destroy-placed-blocks-on-the-end-platform.patch (100%) rename patches/{server => unapplied}/1047-Add-enchantment-seed-update-API.patch (100%) rename patches/{server => unapplied}/1048-Fix-synchronise-sending-chat-to-client-with-updating.patch (100%) rename patches/{server => unapplied}/1049-Fix-InventoryOpenEvent-cancellation.patch (100%) rename patches/{server => unapplied}/1050-Fire-BlockExpEvent-on-grindstone-use.patch (100%) rename patches/{server => unapplied}/1051-Check-dead-flag-in-isAlive.patch (100%) rename patches/{server => unapplied}/1052-Add-FeatureFlag-API.patch (100%) rename patches/{server => unapplied}/1053-Tag-Lifecycle-Events.patch (100%) rename patches/{server => unapplied}/1054-Item-serialization-as-json.patch (100%) rename patches/{server => unapplied}/1055-Validate-slot-in-PlayerInventory-setSlot.patch (100%) rename patches/{server => unapplied}/1056-Remove-wall-time-unused-skip-tick-protection.patch (100%) rename patches/{server => unapplied}/1057-Disable-pretty-printing-for-advancement-saving.patch (100%) rename patches/{server => unapplied}/1058-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch (100%) rename patches/{server => unapplied}/1059-Add-enchantWithLevels-with-enchantment-registry-set.patch (100%) rename patches/{server => unapplied}/1060-Improve-entity-effect-API.patch (100%) rename patches/{server => unapplied}/1061-Add-recipeBrewTime.patch (100%) rename patches/{server => unapplied}/1062-Call-bucket-events-for-cauldrons.patch (100%) rename patches/{server => unapplied}/1063-Add-PlayerInsertLecternBookEvent.patch (100%) rename patches/{server => unapplied}/1064-Void-damage-configuration-API.patch (100%) rename patches/{server => unapplied}/1065-Add-Offline-PDC-API.patch (100%) rename patches/{server => unapplied}/1066-Add-AnvilView-bypassEnchantmentLevelRestriction.patch (100%) rename patches/{server => unapplied}/1067-Add-proper-async-player-disconnections.patch (100%) rename patches/{server => unapplied}/1068-Always-send-Banner-patterns-to-the-client.patch (100%) rename patches/unapplied/{server/1036-Optimise-nearby-player-retrieval.patch => 9999-Optimise-nearby-player-retrieval.patch} (100%) diff --git a/README.md b/README.md index 062f378c862a..de9253cf0b14 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ How To (Plugin Developers) io.papermc.paper paper-api - 1.21.1-R0.1-SNAPSHOT + 1.21.2-R0.1-SNAPSHOT provided ``` @@ -53,7 +53,7 @@ repositories { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.2-R0.1-SNAPSHOT") } java { diff --git a/gradle.properties b/gradle.properties index 4d595c30f355..c61582a178da 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,9 +1,9 @@ group=io.papermc.paper -version=1.21.1-R0.1-SNAPSHOT -mcVersion=1.21.1 +version=1.21.2-R0.1-SNAPSHOT +mcVersion=1.21.2 # Set to true while updating Minecraft version -updatingMinecraft=false +updatingMinecraft=true org.gradle.caching=true org.gradle.parallel=true diff --git a/patches/api/0001-Convert-project-to-Gradle.patch b/patches/api/0001-Convert-project-to-Gradle.patch index 2f36dea1d538..42bb94fe5a7f 100644 --- a/patches/api/0001-Convert-project-to-Gradle.patch +++ b/patches/api/0001-Convert-project-to-Gradle.patch @@ -124,7 +124,7 @@ index 0000000000000000000000000000000000000000..7ac6af074d76b782ef14fe4690bb5b63 +} diff --git a/pom.xml b/pom.xml deleted file mode 100644 -index 19c192e313d48ae35622a032e2b0911ea9fb8aa1..0000000000000000000000000000000000000000 +index 9a148bbfa61552dcaa8c0170022fcc463dbcd87b..0000000000000000000000000000000000000000 --- a/pom.xml +++ /dev/null @@ -1,267 +0,0 @@ @@ -135,7 +135,7 @@ index 19c192e313d48ae35622a032e2b0911ea9fb8aa1..00000000000000000000000000000000 - - org.spigotmc - spigot-api -- 1.21.1-R0.1-SNAPSHOT +- 1.21.2-R0.1-SNAPSHOT - jar - - Spigot-API diff --git a/patches/api/0002-Build-system-changes.patch b/patches/api/0002-Build-system-changes.patch index 60f39fcfceb3..944fcfdff7b2 100644 --- a/patches/api/0002-Build-system-changes.patch +++ b/patches/api/0002-Build-system-changes.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Build system changes diff --git a/build.gradle.kts b/build.gradle.kts -index 6271e2bad0ed937c2c46a8c8fdf186c46b0b620e..78aadebda145fe83327ceb430c4b38f9a8e45a2b 100644 +index 7ac6af074d76b782ef14fe4690bb5b630ededa32..0b837b485bec96fa37ed65c18df97e55cecd0e9d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,15 +18,27 @@ dependencies { diff --git a/patches/api/0003-Test-changes.patch b/patches/api/0003-Test-changes.patch index a94334f9673e..0355a16c86b8 100644 --- a/patches/api/0003-Test-changes.patch +++ b/patches/api/0003-Test-changes.patch @@ -12,7 +12,7 @@ Co-authored-by: Riley Park Co-authored-by: Jake Potrebic diff --git a/build.gradle.kts b/build.gradle.kts -index 665ad8b7d2728b836f26c2344111144728e00fb6..35480b9f7bb14217130b1b3a0638365a98c7a9d5 100644 +index 0b837b485bec96fa37ed65c18df97e55cecd0e9d..c8a8903d1b0c9822743549ecb8e4fdc7d0fd07c1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -107,6 +107,12 @@ tasks.test { diff --git a/patches/api/0004-Code-Generation.patch b/patches/api/0004-Code-Generation.patch index 56d1a8f094d9..fd41f2bc506f 100644 --- a/patches/api/0004-Code-Generation.patch +++ b/patches/api/0004-Code-Generation.patch @@ -7,7 +7,7 @@ Currently includes generated key holder classes for types used in the Registry Modification API diff --git a/build.gradle.kts b/build.gradle.kts -index 35480b9f7bb14217130b1b3a0638365a98c7a9d5..f7aa3f53e119b756b4645ca88cf9642d0f549d2c 100644 +index c8a8903d1b0c9822743549ecb8e4fdc7d0fd07c1..032f8b762b552e8cae20bbdd75c1e0844e64386a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,7 @@ @@ -366,13 +366,13 @@ index 0000000000000000000000000000000000000000..99375deaa6b90b33cd6a77e0df651236 +record TypedKeyImpl(Key key, RegistryKey registryKey) implements TypedKey { +} diff --git a/src/main/java/org/bukkit/MinecraftExperimental.java b/src/main/java/org/bukkit/MinecraftExperimental.java -index a86b87e4c3332202e40e484c3f9c6562b419c70f..305532968f9f7dd497c77259ed147ea2f081bc74 100644 +index b7845523e8587e13b86516c0012fe097d904846c..08d1deb42b17987b24699aa42d1166e08fbe846e 100644 --- a/src/main/java/org/bukkit/MinecraftExperimental.java +++ b/src/main/java/org/bukkit/MinecraftExperimental.java -@@ -47,5 +47,6 @@ public @interface MinecraftExperimental { - @ApiStatus.Internal +@@ -48,5 +48,6 @@ public @interface MinecraftExperimental { public enum Requires { + WINTER_DROP, + BUNDLE, TRADE_REBALANCE // Paper } } diff --git a/patches/api/0005-Add-FastUtil-to-Bukkit.patch b/patches/api/0005-Add-FastUtil-to-Bukkit.patch index 68e47ea275f7..e4778e955969 100644 --- a/patches/api/0005-Add-FastUtil-to-Bukkit.patch +++ b/patches/api/0005-Add-FastUtil-to-Bukkit.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add FastUtil to Bukkit Doesn't expose to plugins, just allows Paper-API to use it for optimization diff --git a/build.gradle.kts b/build.gradle.kts -index f11a22ab01e97e51619c96f2d8a78a99297efc59..2f266350a787a4cfdfda1b0e760bfb7604cac43c 100644 +index 032f8b762b552e8cae20bbdd75c1e0844e64386a..4b6c5d1ae45d93d88adb7035eb19935361c06178 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -23,6 +23,7 @@ dependencies { diff --git a/patches/api/0006-Adventure.patch b/patches/api/0006-Adventure.patch index e464b2a6e636..f96052e8818a 100644 --- a/patches/api/0006-Adventure.patch +++ b/patches/api/0006-Adventure.patch @@ -8,7 +8,7 @@ Co-authored-by: Jake Potrebic Co-authored-by: Yannick Lamprecht diff --git a/build.gradle.kts b/build.gradle.kts -index b2e0bb305d015a19a4cb1e81e1b3b983c979d56d..562f8ae2d9cd2a1238bde1e5cfbf546c4f56bd6e 100644 +index 4b6c5d1ae45d93d88adb7035eb19935361c06178..cce9caa52c9a2208acccbd25fa88c0de066f23a4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,12 +11,28 @@ java { @@ -1494,7 +1494,7 @@ index 18a53194483410c4d5ad35f901c90d44efaeef60..aff43d77f31d81b82e5fc5fea6272dda String getDisplayName(); diff --git a/src/main/java/org/bukkit/Sound.java b/src/main/java/org/bukkit/Sound.java -index f4d7efee38c3b1381fdbcd47ab1f59fb02728cf2..b2ff1da3386223a544ab5fc363a90c66c8869242 100644 +index 8824e83039195882fa9c2a854460b0aeedfb7d21..cf17af024b1953b6f21f18885411ea6a0baa1d4c 100644 --- a/src/main/java/org/bukkit/Sound.java +++ b/src/main/java/org/bukkit/Sound.java @@ -10,7 +10,7 @@ import org.jetbrains.annotations.NotNull; @@ -1506,7 +1506,7 @@ index f4d7efee38c3b1381fdbcd47ab1f59fb02728cf2..b2ff1da3386223a544ab5fc363a90c66 AMBIENT_BASALT_DELTAS_ADDITIONS("ambient.basalt_deltas.additions"), AMBIENT_BASALT_DELTAS_LOOP("ambient.basalt_deltas.loop"), -@@ -1635,4 +1635,11 @@ public enum Sound implements Keyed { +@@ -1660,4 +1660,11 @@ public enum Sound implements Keyed { public NamespacedKey getKey() { return key; } @@ -2320,7 +2320,7 @@ index 558fe6e23f562ee873fc84112f930c6ea19a09f4..c78fb359bd28b8dc1ba242642ec612e8 + // Paper end } diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5adc4c867f 100644 +index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306ec156c71b 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java @@ -57,7 +57,41 @@ import org.jetbrains.annotations.Nullable; @@ -2427,7 +2427,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a public String getPlayerListName(); /** -@@ -103,14 +174,18 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -103,7 +174,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * If the value is null, the name will be identical to {@link #getName()}. * * @param name new player list name @@ -2437,6 +2437,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a public void setPlayerListName(@Nullable String name); /** +@@ -125,7 +198,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * Gets the currently displayed player list header for this player. * * @return player list header or null @@ -2446,7 +2447,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a @Nullable public String getPlayerListHeader(); -@@ -118,7 +193,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -133,7 +208,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * Gets the currently displayed player list footer for this player. * * @return player list header or null @@ -2456,7 +2457,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a @Nullable public String getPlayerListFooter(); -@@ -126,14 +203,18 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -141,14 +218,18 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * Sets the currently displayed player list header for this player. * * @param header player list header, null for empty @@ -2475,7 +2476,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a public void setPlayerListFooter(@Nullable String footer); /** -@@ -142,7 +223,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -157,7 +238,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param header player list header, null for empty * @param footer player list footer, null for empty @@ -2485,7 +2486,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a public void setPlayerListHeaderFooter(@Nullable String header, @Nullable String footer); /** -@@ -219,9 +302,25 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -234,9 +317,25 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * Kicks player with custom kick message. * * @param message kick message @@ -2511,7 +2512,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a /** * Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will * update the entry. -@@ -884,6 +983,106 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -899,6 +998,106 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public void sendEquipmentChange(@NotNull LivingEntity entity, @NotNull Map items); @@ -2618,7 +2619,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a /** * Send a sign change. This fakes a sign change packet for a user at * a certain location. This will not actually change the world in any way. -@@ -901,7 +1100,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -916,7 +1115,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param lines the new text on the sign or null to clear it * @throws IllegalArgumentException if location is null * @throws IllegalArgumentException if lines is non-null and has a length less than 4 @@ -2630,7 +2631,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a public void sendSignChange(@NotNull Location loc, @Nullable String[] lines) throws IllegalArgumentException; /** -@@ -923,7 +1126,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -938,7 +1141,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException if location is null * @throws IllegalArgumentException if dyeColor is null * @throws IllegalArgumentException if lines is non-null and has a length less than 4 @@ -2642,7 +2643,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a public void sendSignChange(@NotNull Location loc, @Nullable String[] lines, @NotNull DyeColor dyeColor) throws IllegalArgumentException; /** -@@ -946,7 +1153,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -961,7 +1168,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException if location is null * @throws IllegalArgumentException if dyeColor is null * @throws IllegalArgumentException if lines is non-null and has a length less than 4 @@ -2654,7 +2655,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a public void sendSignChange(@NotNull Location loc, @Nullable String[] lines, @NotNull DyeColor dyeColor, boolean hasGlowingText) throws IllegalArgumentException; /** -@@ -1421,7 +1632,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1436,7 +1647,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException Thrown if the URL is null. * @throws IllegalArgumentException Thrown if the URL is too long. * @deprecated Minecraft no longer uses textures packs. Instead you @@ -2663,7 +2664,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a */ @Deprecated public void setTexturePack(@NotNull String url); -@@ -1457,7 +1668,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1472,7 +1683,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException Thrown if the URL is null. * @throws IllegalArgumentException Thrown if the URL is too long. The * length restriction is an implementation specific arbitrary value. @@ -2673,7 +2674,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a public void setResourcePack(@NotNull String url); /** -@@ -1489,6 +1702,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1504,6 +1717,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * pack correctly. * * @@ -2681,7 +2682,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a * @param url The URL from which the client will download the resource * pack. The string must contain only US-ASCII characters and should * be encoded as per RFC 1738. -@@ -1501,6 +1715,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1516,6 +1730,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException Thrown if the hash is not 20 bytes * long. */ @@ -2689,7 +2690,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a public void setResourcePack(@NotNull String url, @Nullable byte[] hash); /** -@@ -1525,12 +1740,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1540,12 +1755,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * {@link PlayerResourcePackStatusEvent} to figure out whether or not * the player loaded the pack! *
  • To remove a resource pack you can use @@ -2704,7 +2705,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a * @param url The URL from which the client will download the resource * pack. The string must contain only US-ASCII characters and should * be encoded as per RFC 1738. -@@ -1544,8 +1760,10 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1559,8 +1775,10 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException Thrown if the hash is not 20 bytes * long. */ @@ -2715,7 +2716,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a /** * Request that the player's client download and switch resource packs. *

    -@@ -1568,7 +1786,54 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1583,7 +1801,54 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * {@link PlayerResourcePackStatusEvent} to figure out whether or not * the player loaded the pack! *

  • To remove a resource pack you can use @@ -2771,7 +2772,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a *
  • The request is sent with empty string as the hash when the hash is * not provided. This might result in newer versions not loading the * pack correctly. -@@ -1587,7 +1852,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1602,7 +1867,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * length restriction is an implementation specific arbitrary value. * @throws IllegalArgumentException Thrown if the hash is not 20 bytes * long. @@ -2781,7 +2782,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a public void setResourcePack(@NotNull String url, @Nullable byte[] hash, boolean force); /** -@@ -1612,7 +1879,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1627,7 +1894,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * {@link PlayerResourcePackStatusEvent} to figure out whether or not * the player loaded the pack! *
  • To remove a resource pack you can use @@ -2790,7 +2791,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a *
  • The request is sent with empty string as the hash when the hash is * not provided. This might result in newer versions not loading the * pack correctly. -@@ -1632,9 +1899,61 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1647,9 +1914,61 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * length restriction is an implementation specific arbitrary value. * @throws IllegalArgumentException Thrown if the hash is not 20 bytes * long. @@ -2852,7 +2853,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a /** * Request that the player's client download and switch resource packs. *

    -@@ -1657,7 +1976,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1672,7 +1991,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * {@link PlayerResourcePackStatusEvent} to figure out whether or not * the player loaded the pack! *

  • To remove a resource pack you can use @@ -2861,7 +2862,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a *
  • The request is sent with empty string as the hash when the hash is * not provided. This might result in newer versions not loading the * pack correctly. -@@ -1678,9 +1997,60 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1693,9 +2012,60 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * length restriction is an implementation specific arbitrary value. * @throws IllegalArgumentException Thrown if the hash is not 20 bytes * long. @@ -2922,7 +2923,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a /** * Request that the player's client download and include another resource pack. *

    -@@ -1733,12 +2103,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1748,12 +2118,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param id the id of the resource pack. * @throws IllegalArgumentException If the ID is null. @@ -2937,7 +2938,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a */ public void removeResourcePacks(); -@@ -1876,7 +2248,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1891,7 +2263,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param title Title text * @param subtitle Subtitle text @@ -2946,7 +2947,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a */ @Deprecated public void sendTitle(@Nullable String title, @Nullable String subtitle); -@@ -1895,7 +2267,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1910,7 +2282,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param fadeIn time in ticks for titles to fade in. Defaults to 10. * @param stay time in ticks for titles to stay. Defaults to 70. * @param fadeOut time in ticks for titles to fade out. Defaults to 20. @@ -2956,7 +2957,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a public void sendTitle(@Nullable String title, @Nullable String subtitle, int fadeIn, int stay, int fadeOut); /** -@@ -2170,6 +2544,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2185,6 +2559,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public int getClientViewDistance(); @@ -2971,7 +2972,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a /** * Gets the player's estimated ping in milliseconds. * -@@ -2195,8 +2577,10 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2210,8 +2592,10 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * they wish. * * @return the player's locale @@ -2982,7 +2983,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a public String getLocale(); /** -@@ -2248,6 +2632,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2263,6 +2647,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public boolean isAllowingServerListings(); @@ -2997,7 +2998,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a // Spigot start public class Spigot extends Entity.Spigot { -@@ -2279,11 +2671,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2294,11 +2686,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM throw new UnsupportedOperationException("Not supported yet."); } @@ -3011,7 +3012,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a @Override public void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent... components) { throw new UnsupportedOperationException("Not supported yet."); -@@ -2294,7 +2688,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2309,7 +2703,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param position the screen position * @param component the components to send @@ -3021,7 +3022,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a public void sendMessage(@NotNull net.md_5.bungee.api.ChatMessageType position, @NotNull net.md_5.bungee.api.chat.BaseComponent component) { throw new UnsupportedOperationException("Not supported yet."); } -@@ -2304,7 +2700,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2319,7 +2715,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param position the screen position * @param components the components to send @@ -3031,7 +3032,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a public void sendMessage(@NotNull net.md_5.bungee.api.ChatMessageType position, @NotNull net.md_5.bungee.api.chat.BaseComponent... components) { throw new UnsupportedOperationException("Not supported yet."); } -@@ -2315,7 +2713,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2330,7 +2728,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param position the screen position * @param sender the sender of the message * @param component the components to send @@ -3041,7 +3042,7 @@ index fb976b3f5e92016373b83b1ab70032fb910f60d3..5bcec42a91859002409cab9756999e5a public void sendMessage(@NotNull net.md_5.bungee.api.ChatMessageType position, @Nullable java.util.UUID sender, @NotNull net.md_5.bungee.api.chat.BaseComponent component) { throw new UnsupportedOperationException("Not supported yet."); } -@@ -2326,7 +2726,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2341,7 +2741,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param position the screen position * @param sender the sender of the message * @param components the components to send @@ -4710,10 +4711,10 @@ index 9bab73c3c2ca759b8e1c7d07d98cc593c961666a..f0c6943da3f783101ca647b75b3230fa throw new UnsupportedOperationException("Not supported yet."); } diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java -index 9fb9f00f39d68777cde660b06beaa58b25cd4470..014c1a0379e532a5c924694a8e0715eb0ba50ec2 100644 +index 1d810042652dac9c35dd358f9d87e3dd2cebc48e..fabddfe3763e143b5a769764cb324f97876ccb1c 100644 --- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java +++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java -@@ -37,6 +37,24 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -44,6 +44,24 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste */ boolean hasDisplayName(); @@ -4738,7 +4739,7 @@ index 9fb9f00f39d68777cde660b06beaa58b25cd4470..014c1a0379e532a5c924694a8e0715eb /** * Gets the display name that is set. *

    -@@ -44,7 +62,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -51,7 +69,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * before calling this method. * * @return the display name that is set @@ -4748,7 +4749,7 @@ index 9fb9f00f39d68777cde660b06beaa58b25cd4470..014c1a0379e532a5c924694a8e0715eb @NotNull String getDisplayName(); -@@ -52,7 +72,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -59,7 +79,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * Sets the display name. * * @param name the name to set @@ -4758,7 +4759,7 @@ index 9fb9f00f39d68777cde660b06beaa58b25cd4470..014c1a0379e532a5c924694a8e0715eb void setDisplayName(@Nullable String name); /** -@@ -65,6 +87,32 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -72,6 +94,32 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste */ boolean hasItemName(); @@ -4791,7 +4792,7 @@ index 9fb9f00f39d68777cde660b06beaa58b25cd4470..014c1a0379e532a5c924694a8e0715eb /** * Gets the item name that is set. *
    -@@ -75,7 +123,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -82,7 +130,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * calling this method. * * @return the item name that is set @@ -4801,7 +4802,7 @@ index 9fb9f00f39d68777cde660b06beaa58b25cd4470..014c1a0379e532a5c924694a8e0715eb @NotNull String getItemName(); -@@ -86,7 +136,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -93,7 +143,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * anvil, is not styled with italics, and does not show labels. * * @param name the name to set @@ -4811,7 +4812,7 @@ index 9fb9f00f39d68777cde660b06beaa58b25cd4470..014c1a0379e532a5c924694a8e0715eb void setItemName(@Nullable String name); /** -@@ -127,6 +179,24 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -134,6 +186,24 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste */ boolean hasLore(); @@ -4836,7 +4837,7 @@ index 9fb9f00f39d68777cde660b06beaa58b25cd4470..014c1a0379e532a5c924694a8e0715eb /** * Gets the lore that is set. *

    -@@ -134,7 +204,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -141,7 +211,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * calling this method. * * @return a list of lore that is set @@ -4846,7 +4847,7 @@ index 9fb9f00f39d68777cde660b06beaa58b25cd4470..014c1a0379e532a5c924694a8e0715eb @Nullable List getLore(); -@@ -143,7 +215,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -150,7 +222,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * Removes lore when given null. * * @param lore the lore that will be set diff --git a/patches/api/0008-Use-ASM-for-event-executors.patch b/patches/api/0008-Use-ASM-for-event-executors.patch index b16393a72e84..fdb54d4a85ed 100644 --- a/patches/api/0008-Use-ASM-for-event-executors.patch +++ b/patches/api/0008-Use-ASM-for-event-executors.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Use ASM for event executors. Uses method handles for private or static methods. diff --git a/build.gradle.kts b/build.gradle.kts -index 562f8ae2d9cd2a1238bde1e5cfbf546c4f56bd6e..65783c7a3711fa147a4e090a9715f7e218a312ac 100644 +index cce9caa52c9a2208acccbd25fa88c0de066f23a4..2b1d08d8e16037f6d17c74ea613eaa2ca36c664e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -47,6 +47,9 @@ dependencies { diff --git a/patches/api/0009-Paper-Plugins.patch b/patches/api/0009-Paper-Plugins.patch index 175cbd40eb42..b9fcf1aeb9c9 100644 --- a/patches/api/0009-Paper-Plugins.patch +++ b/patches/api/0009-Paper-Plugins.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Paper Plugins diff --git a/build.gradle.kts b/build.gradle.kts -index 65783c7a3711fa147a4e090a9715f7e218a312ac..c55223e0d0c30b7575bc5322e993d0205cbda85f 100644 +index 2b1d08d8e16037f6d17c74ea613eaa2ca36c664e..940fb51c1f3054465f305e98b13aac49c77e3a91 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -52,7 +52,7 @@ dependencies { diff --git a/patches/api/0010-Add-Position.patch b/patches/api/0010-Add-Position.patch index 2e4718c86b46..23e8152911b9 100644 --- a/patches/api/0010-Add-Position.patch +++ b/patches/api/0010-Add-Position.patch @@ -392,7 +392,7 @@ index 0000000000000000000000000000000000000000..0e6a6a6738353b118e0ed093994dda06 + } +} diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java -index 7c4db051472fb6a6c6d24092dc6f75487356690a..85c342fc50f2fe0ce9a1b3980df9e088c3dea92d 100644 +index 734054f1e8dad74c13d7ae0b1c1af2d9f45b2636..bc8a64d54e001eae6ef4520a49e261b96c5ae9f3 100644 --- a/src/main/java/org/bukkit/Location.java +++ b/src/main/java/org/bukkit/Location.java @@ -20,7 +20,7 @@ import org.jetbrains.annotations.Nullable; diff --git a/patches/api/0011-Timings-v2.patch b/patches/api/0011-Timings-v2.patch index 928003f6213f..3e430feef495 100644 --- a/patches/api/0011-Timings-v2.patch +++ b/patches/api/0011-Timings-v2.patch @@ -3484,10 +3484,10 @@ index 516d7fc7812aac343782861d0d567f54aa578c2a..00000000000000000000000000000000 - // Spigot end -} diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 5bcec42a91859002409cab9756999e5adc4c867f..3594b0eb4068c83c93efe948a8ef4ba217edce17 100644 +index 0f562dcca9bb0ffc3a3fcb1c2221306ec156c71b..9e072342eb5af366a4f860db71e15a63b29038aa 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -2731,7 +2731,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2746,7 +2746,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM @Deprecated // Paper public void sendMessage(@NotNull net.md_5.bungee.api.ChatMessageType position, @Nullable java.util.UUID sender, @NotNull net.md_5.bungee.api.chat.BaseComponent... components) { throw new UnsupportedOperationException("Not supported yet."); diff --git a/patches/api/0012-Add-command-line-option-to-load-extra-plugin-jars-no.patch b/patches/api/0012-Add-command-line-option-to-load-extra-plugin-jars-no.patch index 8dc512dfb3e8..c73bf65b9727 100644 --- a/patches/api/0012-Add-command-line-option-to-load-extra-plugin-jars-no.patch +++ b/patches/api/0012-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/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 6ecab28705afc0e3652677b516d8a5398e8b2666..db51751d2dc1ac419e8fac32466ad3a7727fa2fe 100644 +index 8d729fb196d83e01e4652fb1f77f5cab7b57cc31..d978c72cdbc10792f852a4ba372518073893d02b 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java @@ -83,6 +83,20 @@ public final class Bukkit { @@ -32,7 +32,7 @@ index 6ecab28705afc0e3652677b516d8a5398e8b2666..db51751d2dc1ac419e8fac32466ad3a7 * Attempts to set the {@link Server} singleton. *

    diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index f4b2ad91c7a46af5fc16f31369d155e4e3ab3aae..638e98416fdf7ac065abe058d625b1c924be5abb 100644 +index 57c9b560c77a56588870598acb543469040ceec1..8949b8e29ae7f412481291630a5cb7b5b8809842 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -68,6 +68,18 @@ import org.jetbrains.annotations.Nullable; diff --git a/patches/api/0013-Player-affects-spawning-API.patch b/patches/api/0013-Player-affects-spawning-API.patch index fff702d95822..cf908129f87e 100644 --- a/patches/api/0013-Player-affects-spawning-API.patch +++ b/patches/api/0013-Player-affects-spawning-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Player affects spawning API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 3594b0eb4068c83c93efe948a8ef4ba217edce17..1ba2f706a62ee6962451305b1895654453b485cd 100644 +index 9e072342eb5af366a4f860db71e15a63b29038aa..fbcf2a18456b6e700003019965354ce7cbe2fd0d 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -2583,6 +2583,22 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2598,6 +2598,22 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM @Deprecated // Paper public String getLocale(); diff --git a/patches/api/0017-Add-view-distance-API.patch b/patches/api/0017-Add-view-distance-API.patch index aff8f375d85c..493c2f67936f 100644 --- a/patches/api/0017-Add-view-distance-API.patch +++ b/patches/api/0017-Add-view-distance-API.patch @@ -79,10 +79,10 @@ index 9732929b666b0a5e1a2a41c8e8794cc4f2535e41..0a3a66e04f8785874f10a76603bff464 * Gets all generated structures that intersect the chunk at the given * coordinates.
    diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 1ba2f706a62ee6962451305b1895654453b485cd..7d530bd0e4d833da760d1cf82aba966b7fb480b1 100644 +index fbcf2a18456b6e700003019965354ce7cbe2fd0d..18075f35f62b94c24673211be1d287f57f88c0dc 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -2597,6 +2597,82 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2612,6 +2612,82 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param affects Whether the player can affect mob spawning */ public void setAffectsSpawning(boolean affects); diff --git a/patches/api/0020-Graduate-bungeecord-chat-API-from-spigot-subclasses.patch b/patches/api/0020-Graduate-bungeecord-chat-API-from-spigot-subclasses.patch index d88bd2a23610..2e693b71afc8 100644 --- a/patches/api/0020-Graduate-bungeecord-chat-API-from-spigot-subclasses.patch +++ b/patches/api/0020-Graduate-bungeecord-chat-API-from-spigot-subclasses.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Graduate bungeecord chat API from spigot subclasses Change Javadoc to be accurate diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index fe074fe9553f61bdd72b64830532a78415348781..4c5327da1468cb1f9af00a99e7e79f578c47ee2a 100644 +index 26f3ac9c15ff554becfe8ea53a48f67b2de60ed6..bd3fa2bcee24ab7e8f740722f55ed6294fdb294a 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java @@ -472,6 +472,30 @@ public final class Bukkit { @@ -41,7 +41,7 @@ index fe074fe9553f61bdd72b64830532a78415348781..4c5327da1468cb1f9af00a99e7e79f57 * Gets the name of the update folder. The update folder is used to safely * update plugins at the right moment on a plugin load. diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 9545da2adacaf0bd719c2baef929588cd1042d25..19b75704ed9eee0c929df417e1e5d0ea3718e2f8 100644 +index d78481bf17818415524f14417caf86d5684b2235..067eb3a5f5676f3b1b3f49a65df9c4054c48a1e7 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -383,6 +383,30 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi @@ -76,10 +76,10 @@ index 9545da2adacaf0bd719c2baef929588cd1042d25..19b75704ed9eee0c929df417e1e5d0ea * Gets the name of the update folder. The update folder is used to safely * update plugins at the right moment on a plugin load. diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 7d530bd0e4d833da760d1cf82aba966b7fb480b1..f9bacbfa223826b3b54525648080fda306a1ec36 100644 +index 18075f35f62b94c24673211be1d287f57f88c0dc..9674e920bda2d1c6428081ae7f18cade58b7900d 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1214,6 +1214,42 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1229,6 +1229,42 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public void sendMap(@NotNull MapView map); diff --git a/patches/api/0024-Player-Tab-List-and-Title-APIs.patch b/patches/api/0024-Player-Tab-List-and-Title-APIs.patch index 33be050ecfac..197c04e321f4 100644 --- a/patches/api/0024-Player-Tab-List-and-Title-APIs.patch +++ b/patches/api/0024-Player-Tab-List-and-Title-APIs.patch @@ -432,10 +432,10 @@ index 0000000000000000000000000000000000000000..20a028450667edf102b59b6b50ac6e89 + } +} diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index f9bacbfa223826b3b54525648080fda306a1ec36..a0317801b5a41d523324c1482356f26935f6a330 100644 +index 9674e920bda2d1c6428081ae7f18cade58b7900d..ae5ea0513a0688e229a0c49dadf344bfd6704288 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1248,6 +1248,131 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1263,6 +1263,131 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM public default void sendMessage(net.md_5.bungee.api.ChatMessageType position, net.md_5.bungee.api.chat.BaseComponent... components) { spigot().sendMessage(position, components); } diff --git a/patches/api/0026-Complete-resource-pack-API.patch b/patches/api/0026-Complete-resource-pack-API.patch index 22c24d7cc108..339876b64013 100644 --- a/patches/api/0026-Complete-resource-pack-API.patch +++ b/patches/api/0026-Complete-resource-pack-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Complete resource pack API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index a0317801b5a41d523324c1482356f26935f6a330..47c792202e8cc6d97fcb5e9bed98d327ecc5ab2b 100644 +index ae5ea0513a0688e229a0c49dadf344bfd6704288..a00afb924b6938e6abb0e1445da0b46415ff0f88 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -2212,6 +2212,180 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2227,6 +2227,180 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM void setResourcePack(@NotNull UUID uuid, @NotNull String url, byte @Nullable [] hash, net.kyori.adventure.text.@Nullable Component prompt, boolean force); // Paper end diff --git a/patches/api/0039-LootTable-API.patch b/patches/api/0039-LootTable-API.patch index 366e828564fe..75ed22dfb5ff 100644 --- a/patches/api/0039-LootTable-API.patch +++ b/patches/api/0039-LootTable-API.patch @@ -426,10 +426,10 @@ index 9ea403e6fd8e960d017660e0aec118abeda2c42b..238d118f7788b13cd86b7e9ea3a0fc38 +public interface StorageMinecart extends Minecart, InventoryHolder, LootableEntityInventory { // Paper } diff --git a/src/main/java/org/bukkit/loot/Lootable.java b/src/main/java/org/bukkit/loot/Lootable.java -index 24a3d989db3bc67e7afe8459a3d4bb132f448ea7..ad4b0fb7f55ed44dc74fb5a4bd36be6004231116 100644 +index b3e9347496fd60aa4f5d18ff256e8d4d73f2d9cd..649dd959035843604525a637dba639a4fbd34f97 100644 --- a/src/main/java/org/bukkit/loot/Lootable.java +++ b/src/main/java/org/bukkit/loot/Lootable.java -@@ -36,6 +36,31 @@ public interface Lootable { +@@ -35,6 +35,31 @@ public interface Lootable { @Nullable LootTable getLootTable(); diff --git a/patches/api/0045-Add-String-based-Action-Bar-API.patch b/patches/api/0045-Add-String-based-Action-Bar-API.patch index 8107305c07dd..d57aae4afec2 100644 --- a/patches/api/0045-Add-String-based-Action-Bar-API.patch +++ b/patches/api/0045-Add-String-based-Action-Bar-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add String based Action Bar API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 47c792202e8cc6d97fcb5e9bed98d327ecc5ab2b..add0826af957c773975f840c28cf77afbab85a09 100644 +index a00afb924b6938e6abb0e1445da0b46415ff0f88..67e2d3e70c13754371591daf5bb11304aeb9fa87 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1215,6 +1215,39 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1230,6 +1230,39 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM public void sendMap(@NotNull MapView map); // Paper start @@ -48,7 +48,7 @@ index 47c792202e8cc6d97fcb5e9bed98d327ecc5ab2b..add0826af957c773975f840c28cf77af /** * Sends the component to the player * -@@ -1242,9 +1275,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1257,9 +1290,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM /** * Sends an array of components as a single message to the specified screen position of this player * diff --git a/patches/api/0053-Fix-upstream-javadocs.patch b/patches/api/0053-Fix-upstream-javadocs.patch index 135849142cbe..9f7110425a07 100644 --- a/patches/api/0053-Fix-upstream-javadocs.patch +++ b/patches/api/0053-Fix-upstream-javadocs.patch @@ -89,10 +89,10 @@ index db6fcd635e295e561642d49941fd8e611247d38e..344b2b5d9207d2645bc5417d1ec00dd0 MOTION_BLOCKING_NO_LEAVES, /** diff --git a/src/main/java/org/bukkit/Particle.java b/src/main/java/org/bukkit/Particle.java -index 62a8bb18855be13ed1c466b4be7afcd3c91dc7aa..de9fd0fadd6d16ffe883a618bf499214878f443d 100644 +index 13557f78a6853fdf0619f0479cab7591ddadf666..a1896780f312a91ab2330d2c850641d66143f23e 100644 --- a/src/main/java/org/bukkit/Particle.java +++ b/src/main/java/org/bukkit/Particle.java -@@ -195,7 +195,7 @@ public enum Particle implements Keyed { +@@ -206,7 +206,7 @@ public enum Particle implements Keyed { } /** @@ -430,7 +430,7 @@ index 4e1fb0974d061d5bb64899cac576318d2e6f8bf6..539b3527d0c66611e21712f29b90fba9 public int getEntityId(); diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java -index 40214a136894270695746ac83fb5f7bcc406f34a..2bb4d2da99d3f0f70e19381c13b43c147c34f944 100644 +index 29f9b380dda2f370e2a1159811167431796ec8a8..46a076bd8dc2f5d1094899638ab255a5a31c2568 100644 --- a/src/main/java/org/bukkit/entity/HumanEntity.java +++ b/src/main/java/org/bukkit/entity/HumanEntity.java @@ -22,6 +22,11 @@ import org.jetbrains.annotations.Nullable; @@ -500,10 +500,10 @@ index ae9eaaa8e38e1d9dfc459926c7fc51ddb89de84a..b2ec535bb1b0ce0c114ddd7638b90218 @Override public int getConversionTime(); diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index add0826af957c773975f840c28cf77afbab85a09..fea44ddd358b65681d13215244836c21fc88e0fd 100644 +index 67e2d3e70c13754371591daf5bb11304aeb9fa87..68f36afc6124f07d0e4bd75569252f3ebbb319a0 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -476,15 +476,15 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -491,15 +491,15 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM /** * Saves the players current location, health, inventory, motion, and @@ -523,7 +523,7 @@ index add0826af957c773975f840c28cf77afbab85a09..fea44ddd358b65681d13215244836c21 *

    * Note: This will overwrite the players current inventory, health, * motion, etc, with the state from the saved dat file. -@@ -821,7 +821,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -836,7 +836,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM /** * Plays an effect to just this player. * @@ -532,7 +532,7 @@ index add0826af957c773975f840c28cf77afbab85a09..fea44ddd358b65681d13215244836c21 * @param loc the location to play the effect at * @param effect the {@link Effect} * @param data a data bit needed for some effects -@@ -1232,7 +1232,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1247,7 +1247,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * Use supplied alternative character to the section symbol to represent legacy color codes. * @@ -541,7 +541,7 @@ index add0826af957c773975f840c28cf77afbab85a09..fea44ddd358b65681d13215244836c21 * @param message The message to send * @deprecated use {@link #sendActionBar(net.kyori.adventure.text.Component)} */ -@@ -1705,7 +1705,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1720,7 +1720,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM /** * Allows this player to see a player that was previously hidden. If @@ -550,7 +550,7 @@ index add0826af957c773975f840c28cf77afbab85a09..fea44ddd358b65681d13215244836c21 * remain hidden until the other plugin calls this method too. * * @param plugin Plugin that wants to show the player -@@ -1732,7 +1732,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1747,7 +1747,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM /** * Allows this player to see an entity that was previously hidden. If @@ -559,7 +559,7 @@ index add0826af957c773975f840c28cf77afbab85a09..fea44ddd358b65681d13215244836c21 * remain hidden until the other plugin calls this method too. * * @param plugin Plugin that wants to show the entity -@@ -1815,9 +1815,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1830,9 +1830,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * case this method will have no affect on them. Use the * {@link PlayerResourcePackStatusEvent} to figure out whether or not * the player loaded the pack! @@ -569,7 +569,7 @@ index add0826af957c773975f840c28cf77afbab85a09..fea44ddd358b65681d13215244836c21 *

  • The request is send with "null" as the hash. This might result * in newer versions not loading the pack correctly. * -@@ -1851,9 +1848,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1866,9 +1863,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * case this method will have no affect on them. Use the * {@link PlayerResourcePackStatusEvent} to figure out whether or not * the player loaded the pack! @@ -579,7 +579,7 @@ index add0826af957c773975f840c28cf77afbab85a09..fea44ddd358b65681d13215244836c21 *
  • The request is send with empty string as the hash. This might result * in newer versions not loading the pack correctly. * -@@ -1890,9 +1884,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1905,9 +1899,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * case this method will have no affect on them. Use the * {@link PlayerResourcePackStatusEvent} to figure out whether or not * the player loaded the pack! @@ -1604,10 +1604,10 @@ index 35c6594fd1040a1af1029e7260e5e3a9307b107d..d58719ee75bef8bc265bfc81bc5d88a4 void addChargedProjectile(@NotNull ItemStack item); } diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java -index 014c1a0379e532a5c924694a8e0715eb0ba50ec2..10ca843e57c74dfa32d539acd174c8867dfd56ec 100644 +index fabddfe3763e143b5a769764cb324f97876ccb1c..480dd9a5ff334e6f32b98aa0108ff02e6f7077ab 100644 --- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java +++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java -@@ -540,7 +540,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -744,7 +744,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * The returned component is a snapshot of its current state and does not * reflect a live view of what is on an item. After changing any value on * this component, it must be set with @@ -1616,7 +1616,7 @@ index 014c1a0379e532a5c924694a8e0715eb0ba50ec2..10ca843e57c74dfa32d539acd174c886 * to apply the changes. * * @return component -@@ -549,7 +549,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -753,7 +753,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste JukeboxPlayableComponent getJukeboxPlayable(); /** @@ -1625,7 +1625,7 @@ index 014c1a0379e532a5c924694a8e0715eb0ba50ec2..10ca843e57c74dfa32d539acd174c886 * * @param jukeboxPlayable new component */ -@@ -576,7 +576,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -780,7 +780,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste /** * Return an immutable copy of all {@link Attribute}s and their * {@link AttributeModifier}s for a given {@link EquipmentSlot}.
    diff --git a/patches/api/0059-Shoulder-Entities-Release-API.patch b/patches/api/0059-Shoulder-Entities-Release-API.patch index 51832da222a0..183b51f4d71b 100644 --- a/patches/api/0059-Shoulder-Entities-Release-API.patch +++ b/patches/api/0059-Shoulder-Entities-Release-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Shoulder Entities Release API diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java -index 2bb4d2da99d3f0f70e19381c13b43c147c34f944..b8431d9722ef9fce0ac9e18367abef22717997ca 100644 +index 46a076bd8dc2f5d1094899638ab255a5a31c2568..08cef0d9fc27d0c09472cfe7091330d95956d9eb 100644 --- a/src/main/java/org/bukkit/entity/HumanEntity.java +++ b/src/main/java/org/bukkit/entity/HumanEntity.java -@@ -346,6 +346,26 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder +@@ -377,6 +377,26 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder */ public int getExpToLevel(); diff --git a/patches/api/0065-LivingEntity-setKiller.patch b/patches/api/0065-LivingEntity-setKiller.patch index fb3719a67986..0c89dae9a658 100644 --- a/patches/api/0065-LivingEntity-setKiller.patch +++ b/patches/api/0065-LivingEntity-setKiller.patch @@ -5,7 +5,7 @@ Subject: [PATCH] LivingEntity#setKiller diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java -index 32e89741ffd895e31af0104a0126c2f72742a1bb..f154c5607b1dc3585052d9f02cf8b28cf8a3c886 100644 +index b0fbad5de65c33710ec46734ad6c69ec9b2769d5..e6bdfd14bffa394cd717de7118de951a997f50b3 100644 --- a/src/main/java/org/bukkit/entity/LivingEntity.java +++ b/src/main/java/org/bukkit/entity/LivingEntity.java @@ -365,6 +365,15 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource diff --git a/patches/api/0067-Allow-plugins-to-use-SLF4J-for-logging.patch b/patches/api/0067-Allow-plugins-to-use-SLF4J-for-logging.patch index dae4f692516f..d94d18165b8c 100644 --- a/patches/api/0067-Allow-plugins-to-use-SLF4J-for-logging.patch +++ b/patches/api/0067-Allow-plugins-to-use-SLF4J-for-logging.patch @@ -14,7 +14,7 @@ it without having to shade it in the plugin and going through several layers of logging abstraction. diff --git a/build.gradle.kts b/build.gradle.kts -index c55223e0d0c30b7575bc5322e993d0205cbda85f..33e4635dbe6afabecfaaaeff57495e5b3ca5f891 100644 +index 940fb51c1f3054465f305e98b13aac49c77e3a91..6c8464d9e862b1b4dbf7a77e25446aa870803dae 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,6 +12,8 @@ java { diff --git a/patches/api/0068-Handle-plugin-prefixes-in-implementation-logging-con.patch b/patches/api/0068-Handle-plugin-prefixes-in-implementation-logging-con.patch index f80ceb6cb702..74e02036c1a7 100644 --- a/patches/api/0068-Handle-plugin-prefixes-in-implementation-logging-con.patch +++ b/patches/api/0068-Handle-plugin-prefixes-in-implementation-logging-con.patch @@ -17,7 +17,7 @@ The implementation should handle plugin prefixes by displaying logger names when appropriate. diff --git a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java -index 2a14522c484febcd880d00197df4359a0020dddd..f81e335a4e533221529355bec2f5d588aa79e60c 100644 +index 7f17337b9f0fb60fa1c91c47af496c03290d1b1c..801578de8599d6b546cde63b3f2655fab48eee03 100644 --- a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java +++ b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java @@ -47,7 +47,7 @@ public abstract class JavaPlugin extends PluginBase { diff --git a/patches/api/0073-AsyncTabCompleteEvent.patch b/patches/api/0073-AsyncTabCompleteEvent.patch index e78867039c9c..a48195bf9fc6 100644 --- a/patches/api/0073-AsyncTabCompleteEvent.patch +++ b/patches/api/0073-AsyncTabCompleteEvent.patch @@ -596,7 +596,7 @@ index 270e6d8ad4358baa256cee5f16cff281f063ce3b..6465e290c090d82986352d5ab7ba5dc6 @Override diff --git a/src/test/java/org/bukkit/AnnotationTest.java b/src/test/java/org/bukkit/AnnotationTest.java -index 7ff939ea41417bad3a436a87c89d5efa7ecefe86..88d5db2995829cba919d78f988d5c735cf70cb1b 100644 +index f8b8969ee7a0b6f7b3224ff081e35c14a398c9d0..f9e4b16a21d6cc6c9cbbe06d20c8af25e72e3ddb 100644 --- a/src/test/java/org/bukkit/AnnotationTest.java +++ b/src/test/java/org/bukkit/AnnotationTest.java @@ -48,6 +48,8 @@ public class AnnotationTest { diff --git a/patches/api/0074-Expose-client-protocol-version-and-virtual-host.patch b/patches/api/0074-Expose-client-protocol-version-and-virtual-host.patch index 0a078f013df6..5f15d77dd217 100644 --- a/patches/api/0074-Expose-client-protocol-version-and-virtual-host.patch +++ b/patches/api/0074-Expose-client-protocol-version-and-virtual-host.patch @@ -55,7 +55,7 @@ index 0000000000000000000000000000000000000000..c84ce3fc874eea3d8f0b1cf5273996d9 + +} diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index fea44ddd358b65681d13215244836c21fc88e0fd..d470b26abbf54514e498d81d68af566e2af0a63f 100644 +index 68f36afc6124f07d0e4bd75569252f3ebbb319a0..a605425b79131f885051d91bb57a30a695e0ce46 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java @@ -57,7 +57,7 @@ import org.jetbrains.annotations.Nullable; diff --git a/patches/api/0078-Ability-to-apply-mending-to-XP-API.patch b/patches/api/0078-Ability-to-apply-mending-to-XP-API.patch index bb3d96e6f16f..7d05cddb6591 100644 --- a/patches/api/0078-Ability-to-apply-mending-to-XP-API.patch +++ b/patches/api/0078-Ability-to-apply-mending-to-XP-API.patch @@ -10,10 +10,10 @@ 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/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index d470b26abbf54514e498d81d68af566e2af0a63f..77a740fb62a9c442c9b67943f8775a824cf2617f 100644 +index a605425b79131f885051d91bb57a30a695e0ce46..f93ede618b3098faf3ba6e63bfbcea6e36ff3146 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1548,6 +1548,15 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1563,6 +1563,15 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public void resetPlayerWeather(); @@ -29,7 +29,7 @@ index d470b26abbf54514e498d81d68af566e2af0a63f..77a740fb62a9c442c9b67943f8775a82 /** * Gets the player's cooldown between picking up experience orbs. * -@@ -1573,8 +1582,20 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1588,8 +1597,20 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * Gives the player the amount of experience specified. * * @param amount Exp amount to give diff --git a/patches/api/0084-Add-ArmorStand-Item-Meta.patch b/patches/api/0084-Add-ArmorStand-Item-Meta.patch index aed15d7522d5..36fe72fcef7c 100644 --- a/patches/api/0084-Add-ArmorStand-Item-Meta.patch +++ b/patches/api/0084-Add-ArmorStand-Item-Meta.patch @@ -95,10 +95,10 @@ index 0000000000000000000000000000000000000000..7e4acfff16db80a75e1ff2fee1972b16 + void setMarker(boolean marker); +} diff --git a/src/main/java/org/bukkit/inventory/ItemType.java b/src/main/java/org/bukkit/inventory/ItemType.java -index d4c29562aa3999afdac8b5bc457aa3153a0e9d77..270f85e99084ddf029bef076c335fe6b9bbddbb5 100644 +index 9a28c9dfe8dd5dd73f08ab4907db7f257719dc7e..88e1883dffb64974f5ec60acbf2828cfb9de9439 100644 --- a/src/main/java/org/bukkit/inventory/ItemType.java +++ b/src/main/java/org/bukkit/inventory/ItemType.java -@@ -1791,7 +1791,7 @@ public interface ItemType extends Keyed, Translatable { +@@ -1942,7 +1942,7 @@ public interface ItemType extends Keyed, Translatable { ItemType.Typed RABBIT_STEW = getItemType("rabbit_stew"); ItemType.Typed RABBIT_FOOT = getItemType("rabbit_foot"); ItemType.Typed RABBIT_HIDE = getItemType("rabbit_hide"); diff --git a/patches/api/0089-Player.setPlayerProfile-API.patch b/patches/api/0089-Player.setPlayerProfile-API.patch index ad5dc34a8985..1af7898bdc7a 100644 --- a/patches/api/0089-Player.setPlayerProfile-API.patch +++ b/patches/api/0089-Player.setPlayerProfile-API.patch @@ -93,10 +93,10 @@ index 7a1b80e8d02f23c5d246c3032e5ced909f10bd41..01c052d90bbdad3fc374eb9c8e0a5133 /** diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 77a740fb62a9c442c9b67943f8775a824cf2617f..b427a37d1b382037e946e5a899e571c3aebe5ba9 100644 +index f93ede618b3098faf3ba6e63bfbcea6e36ff3146..9f16ea635a27563a8568d10365f1b284cc93b15a 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3114,6 +3114,26 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3129,6 +3129,26 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM } // Paper end diff --git a/patches/api/0092-Add-openSign-method-to-HumanEntity.patch b/patches/api/0092-Add-openSign-method-to-HumanEntity.patch index 102ec8ae000c..bef8b5e42da3 100644 --- a/patches/api/0092-Add-openSign-method-to-HumanEntity.patch +++ b/patches/api/0092-Add-openSign-method-to-HumanEntity.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add openSign method to HumanEntity diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java -index b8431d9722ef9fce0ac9e18367abef22717997ca..0d01fe9c96a1b9076dbd6d031fa8cd41954ea8db 100644 +index 08cef0d9fc27d0c09472cfe7091330d95956d9eb..00b803cee96fef8830e5db8722c98ff14630fd2a 100644 --- a/src/main/java/org/bukkit/entity/HumanEntity.java +++ b/src/main/java/org/bukkit/entity/HumanEntity.java -@@ -507,6 +507,26 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder +@@ -538,6 +538,26 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder */ @Deprecated public void setShoulderEntityRight(@Nullable Entity entity); @@ -36,10 +36,10 @@ index b8431d9722ef9fce0ac9e18367abef22717997ca..0d01fe9c96a1b9076dbd6d031fa8cd41 /** * Make the entity drop the item in their hand. diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index b427a37d1b382037e946e5a899e571c3aebe5ba9..d8f97d8626850ed833b2dd32fab682cdf61a9948 100644 +index 9f16ea635a27563a8568d10365f1b284cc93b15a..e1516a8e88aab4bb43a77b773d6682070e8a9b8a 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3075,10 +3075,12 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3090,10 +3090,12 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM /** * Open a Sign for editing by the Player. * diff --git a/patches/api/0093-Add-Ban-Methods-to-Player-Objects.patch b/patches/api/0093-Add-Ban-Methods-to-Player-Objects.patch index 8508d5aa31e9..b30b80d2f07d 100644 --- a/patches/api/0093-Add-Ban-Methods-to-Player-Objects.patch +++ b/patches/api/0093-Add-Ban-Methods-to-Player-Objects.patch @@ -86,10 +86,10 @@ index abbf3d6f11350ab2dd47a277771d9f46221036bd..a9d63b1630b05b86a0396355fcfee261 /** * Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index d8f97d8626850ed833b2dd32fab682cdf61a9948..8a0e8447a7c5241a53ae933229f369bf93300c72 100644 +index e1516a8e88aab4bb43a77b773d6682070e8a9b8a..4ef6591ce8d85abd15ccefba57ce66091f385e1a 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1215,6 +1215,186 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1230,6 +1230,186 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM public void sendMap(@NotNull MapView map); // Paper start diff --git a/patches/api/0097-Location.isChunkLoaded-API.patch b/patches/api/0097-Location.isChunkLoaded-API.patch index e1a043b2b47b..c865422539dd 100644 --- a/patches/api/0097-Location.isChunkLoaded-API.patch +++ b/patches/api/0097-Location.isChunkLoaded-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Location.isChunkLoaded() API diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java -index 85c342fc50f2fe0ce9a1b3980df9e088c3dea92d..251d26e6870490abd3e915c5e7c06ce1075a24ab 100644 +index bc8a64d54e001eae6ef4520a49e261b96c5ae9f3..7c7d2b2dc082fd3b5681a15a600422ae3937e2e1 100644 --- a/src/main/java/org/bukkit/Location.java +++ b/src/main/java/org/bukkit/Location.java @@ -533,6 +533,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm diff --git a/patches/api/0098-Expand-World.spawnParticle-API-and-add-Builder.patch b/patches/api/0098-Expand-World.spawnParticle-API-and-add-Builder.patch index 884983b69f88..419d06621378 100644 --- a/patches/api/0098-Expand-World.spawnParticle-API-and-add-Builder.patch +++ b/patches/api/0098-Expand-World.spawnParticle-API-and-add-Builder.patch @@ -597,10 +597,10 @@ index 0000000000000000000000000000000000000000..6c405755f4507d6fbc6c3877c611a719 + } +} diff --git a/src/main/java/org/bukkit/Particle.java b/src/main/java/org/bukkit/Particle.java -index de9fd0fadd6d16ffe883a618bf499214878f443d..6f049e9044de4139971312f85ada19fb026fe75f 100644 +index a1896780f312a91ab2330d2c850641d66143f23e..37e7862be843da4f48ac061fb1625854fd671b2a 100644 --- a/src/main/java/org/bukkit/Particle.java +++ b/src/main/java/org/bukkit/Particle.java -@@ -194,6 +194,18 @@ public enum Particle implements Keyed { +@@ -205,6 +205,18 @@ public enum Particle implements Keyed { return key; } diff --git a/patches/api/0102-Location.toBlockLocation-toCenterLocation.patch b/patches/api/0102-Location.toBlockLocation-toCenterLocation.patch index c86b874f5f80..890edb723c04 100644 --- a/patches/api/0102-Location.toBlockLocation-toCenterLocation.patch +++ b/patches/api/0102-Location.toBlockLocation-toCenterLocation.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Location.toBlockLocation/toCenterLocation() Convert location objects to their block coordinates, or the center of the block diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java -index 251d26e6870490abd3e915c5e7c06ce1075a24ab..24a872dfc8cf1f4a567b6ebd5a5e742593616ede 100644 +index 7c7d2b2dc082fd3b5681a15a600422ae3937e2e1..3bcc8266d6b1de3c3f964ffad9820bf1b94bbd00 100644 --- a/src/main/java/org/bukkit/Location.java +++ b/src/main/java/org/bukkit/Location.java @@ -534,6 +534,32 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm diff --git a/patches/api/0109-Add-getNearbyXXX-methods-to-Location.patch b/patches/api/0109-Add-getNearbyXXX-methods-to-Location.patch index 1898cc3ed689..63749fbc2588 100644 --- a/patches/api/0109-Add-getNearbyXXX-methods-to-Location.patch +++ b/patches/api/0109-Add-getNearbyXXX-methods-to-Location.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add "getNearbyXXX" methods to Location diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java -index 24a872dfc8cf1f4a567b6ebd5a5e742593616ede..3161eae2fa5f03b7d3a5e9945ab659c15cf568c6 100644 +index 3bcc8266d6b1de3c3f964ffad9820bf1b94bbd00..df88bc77a3fa2506adf17eddc6300ac65774df6f 100644 --- a/src/main/java/org/bukkit/Location.java +++ b/src/main/java/org/bukkit/Location.java @@ -12,6 +12,15 @@ import org.bukkit.util.Vector; diff --git a/patches/api/0112-Expand-Explosions-API.patch b/patches/api/0112-Expand-Explosions-API.patch index 063dcb23797c..42f8422bee4f 100644 --- a/patches/api/0112-Expand-Explosions-API.patch +++ b/patches/api/0112-Expand-Explosions-API.patch @@ -9,7 +9,7 @@ Co-authored-by: Esoteric Enderman <90862990+EsotericEnderman@users.noreply.githu Co-authored-by: Bjarne Koll diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java -index 3161eae2fa5f03b7d3a5e9945ab659c15cf568c6..af737017ee397f80c44ee02c6cc60cefa07f59c1 100644 +index df88bc77a3fa2506adf17eddc6300ac65774df6f..fe2e0939df61b1f59d12adf3f760f1d619bb3de3 100644 --- a/src/main/java/org/bukkit/Location.java +++ b/src/main/java/org/bukkit/Location.java @@ -7,6 +7,7 @@ import java.util.HashMap; diff --git a/patches/api/0114-LivingEntity-Active-Item-API.patch b/patches/api/0114-LivingEntity-Active-Item-API.patch index 89c2ebf21789..885fb3349a11 100644 --- a/patches/api/0114-LivingEntity-Active-Item-API.patch +++ b/patches/api/0114-LivingEntity-Active-Item-API.patch @@ -9,10 +9,10 @@ such as a bow or eating food. Co-authored-by: Jake Potrebic diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java -index 0d01fe9c96a1b9076dbd6d031fa8cd41954ea8db..b0cb4377e14da5ef1e155513046c2340ab6e525e 100644 +index 00b803cee96fef8830e5db8722c98ff14630fd2a..5acc8740d14b53aadef1aa4d63d3355149acd0e2 100644 --- a/src/main/java/org/bukkit/entity/HumanEntity.java +++ b/src/main/java/org/bukkit/entity/HumanEntity.java -@@ -336,7 +336,9 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder +@@ -367,7 +367,9 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * blocking). * * @return Whether their hand is raised diff --git a/patches/api/0116-Add-World.getEntity-UUID-API.patch b/patches/api/0116-Add-World.getEntity-UUID-API.patch index 93e1d998ed71..b0b2aa8c6fa3 100644 --- a/patches/api/0116-Add-World.getEntity-UUID-API.patch +++ b/patches/api/0116-Add-World.getEntity-UUID-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add World.getEntity(UUID) API diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index 50c1e4957f66826feb0a2eb04293dbd6b5595700..fd61be5d75dadb91b5a4bb8dfe246c7ec7aa2f1f 100644 +index c2b5fdaace13c8bd46c073ac6d427fe411d96367..2053c92bc7e81b420ebf96cbd5f1275c514dd5f3 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -932,6 +932,17 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient diff --git a/patches/api/0117-InventoryCloseEvent-Reason-API.patch b/patches/api/0117-InventoryCloseEvent-Reason-API.patch index 1be4583340b2..572f11d4e603 100644 --- a/patches/api/0117-InventoryCloseEvent-Reason-API.patch +++ b/patches/api/0117-InventoryCloseEvent-Reason-API.patch @@ -7,7 +7,7 @@ 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/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java -index 9cbb9093e7d8cd21eef6a23c265d68d7d0ee97b8..3985798654a3085c128144e46f7113b7744b8d14 100644 +index 5acc8740d14b53aadef1aa4d63d3355149acd0e2..6c2f01bf452d991faf40b995225bf7b7e49281df 100644 --- a/src/main/java/org/bukkit/entity/HumanEntity.java +++ b/src/main/java/org/bukkit/entity/HumanEntity.java @@ -187,6 +187,15 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder diff --git a/patches/api/0125-Expand-Location-Manipulation-API.patch b/patches/api/0125-Expand-Location-Manipulation-API.patch index e345f50d6207..ff5737313417 100644 --- a/patches/api/0125-Expand-Location-Manipulation-API.patch +++ b/patches/api/0125-Expand-Location-Manipulation-API.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Expand Location Manipulation API Adds set(x, y, z), add(base, x, y, z), subtract(base, x, y, z); diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java -index af737017ee397f80c44ee02c6cc60cefa07f59c1..41125de49db8eafce4be59cc110ce5be06836a47 100644 +index fe2e0939df61b1f59d12adf3f760f1d619bb3de3..56fd66a3fb5f6e33812d2981cd192d317453a0f5 100644 --- a/src/main/java/org/bukkit/Location.java +++ b/src/main/java/org/bukkit/Location.java @@ -545,6 +545,59 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm diff --git a/patches/api/0129-Provide-Chunk-Coordinates-as-a-Long-API.patch b/patches/api/0129-Provide-Chunk-Coordinates-as-a-Long-API.patch index eb66322fb835..1d69849b56f1 100644 --- a/patches/api/0129-Provide-Chunk-Coordinates-as-a-Long-API.patch +++ b/patches/api/0129-Provide-Chunk-Coordinates-as-a-Long-API.patch @@ -44,7 +44,7 @@ index 20ed1c40437cbf8449dd4d7876086ccb6407b470..8764441ec1bae67a029b13c4c9824657 * Gets the world containing this chunk * diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index fd61be5d75dadb91b5a4bb8dfe246c7ec7aa2f1f..4ecbfe4d28316527ff00e206941da9c0fc9235d0 100644 +index 2053c92bc7e81b420ebf96cbd5f1275c514dd5f3..11362777d834cad2265984c7aa493358105cbf68 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -182,6 +182,37 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient diff --git a/patches/api/0132-Allow-Blocks-to-be-accessed-via-a-long-key.patch b/patches/api/0132-Allow-Blocks-to-be-accessed-via-a-long-key.patch index 5204a8d4dbb9..5498e1910c58 100644 --- a/patches/api/0132-Allow-Blocks-to-be-accessed-via-a-long-key.patch +++ b/patches/api/0132-Allow-Blocks-to-be-accessed-via-a-long-key.patch @@ -18,7 +18,7 @@ Y range: [0, 1023] X, Z range: [-67 108 864, 67 108 863] diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java -index 41125de49db8eafce4be59cc110ce5be06836a47..4df9a225e93aafb1e4af9591c482ac07e7f65422 100644 +index 56fd66a3fb5f6e33812d2981cd192d317453a0f5..12e1733d06471d0c2253ae846ee93a09140843cc 100644 --- a/src/main/java/org/bukkit/Location.java +++ b/src/main/java/org/bukkit/Location.java @@ -15,7 +15,6 @@ import org.jetbrains.annotations.Nullable; @@ -50,7 +50,7 @@ index 41125de49db8eafce4be59cc110ce5be06836a47..4df9a225e93aafb1e4af9591c482ac07 * @return A new location where X/Y/Z are the center of the block */ diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index 4ecbfe4d28316527ff00e206941da9c0fc9235d0..190aba1ff06357dc0ef9341e584ab79b928d8f64 100644 +index 11362777d834cad2265984c7aa493358105cbf68..c474f6f0f1d758507f53c6f1ffbe3e26883e1425 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -99,6 +99,41 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient diff --git a/patches/api/0137-isChunkGenerated-API.patch b/patches/api/0137-isChunkGenerated-API.patch index a1d9b815f963..c379d6eb0343 100644 --- a/patches/api/0137-isChunkGenerated-API.patch +++ b/patches/api/0137-isChunkGenerated-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] isChunkGenerated API diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java -index 4df9a225e93aafb1e4af9591c482ac07e7f65422..c30600666e7b32b8b4ba1e20ede04fd5ebd5a692 100644 +index 12e1733d06471d0c2253ae846ee93a09140843cc..b02efba048be00e42502111fcdd2297529926666 100644 --- a/src/main/java/org/bukkit/Location.java +++ b/src/main/java/org/bukkit/Location.java @@ -3,6 +3,7 @@ package org.bukkit; @@ -37,7 +37,7 @@ index 4df9a225e93aafb1e4af9591c482ac07e7f65422..c30600666e7b32b8b4ba1e20ede04fd5 /** diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index 190aba1ff06357dc0ef9341e584ab79b928d8f64..1cc5bdd63a97a6bb62b1d29aca01658359bd15f1 100644 +index c474f6f0f1d758507f53c6f1ffbe3e26883e1425..ba9ab1d46effe1e6c08cebddb8b856e2b294d7cb 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -248,6 +248,19 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient diff --git a/patches/api/0139-Async-Chunks-API.patch b/patches/api/0139-Async-Chunks-API.patch index 037378415a38..caa55b4c1fae 100644 --- a/patches/api/0139-Async-Chunks-API.patch +++ b/patches/api/0139-Async-Chunks-API.patch @@ -8,7 +8,7 @@ Adds API's to load or generate chunks asynchronously. Also adds utility methods to Entity to teleport asynchronously. diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index 1cc5bdd63a97a6bb62b1d29aca01658359bd15f1..6242b64416fdea1f3fd6378ba26ed7bb33ab4cc4 100644 +index ba9ab1d46effe1e6c08cebddb8b856e2b294d7cb..c77ca55c0686512e6d50b559139b6d6bbeb61062 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -977,6 +977,472 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient diff --git a/patches/api/0140-Add-ray-tracing-methods-to-LivingEntity.patch b/patches/api/0140-Add-ray-tracing-methods-to-LivingEntity.patch index 3001f15899a1..673555fc8b15 100644 --- a/patches/api/0140-Add-ray-tracing-methods-to-LivingEntity.patch +++ b/patches/api/0140-Add-ray-tracing-methods-to-LivingEntity.patch @@ -78,7 +78,7 @@ index 0000000000000000000000000000000000000000..bb12061985cdffbacfa2d113beaa35b2 + } +} diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java -index 0ed64618b3f62ee984fe4f99dc6a52d5fad7b3cc..fab432fc00cf41d240ba172d5be43464ca2417b3 100644 +index 434ad8b07b6ee0b0919de8044d14fe3c789e203f..09b0dd1b14e2848253c1d3bfecb98951764737ee 100644 --- a/src/main/java/org/bukkit/entity/LivingEntity.java +++ b/src/main/java/org/bukkit/entity/LivingEntity.java @@ -85,6 +85,98 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource diff --git a/patches/api/0141-Expose-attack-cooldown-methods-for-Player.patch b/patches/api/0141-Expose-attack-cooldown-methods-for-Player.patch index 53aad00d9378..baf7c6305e21 100644 --- a/patches/api/0141-Expose-attack-cooldown-methods-for-Player.patch +++ b/patches/api/0141-Expose-attack-cooldown-methods-for-Player.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Expose attack cooldown methods for Player diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 8a0e8447a7c5241a53ae933229f369bf93300c72..dc9829ab0f4efcf9534f1b2d4a2e48ea49e8d372 100644 +index 4ef6591ce8d85abd15ccefba57ce66091f385e1a..4ee5dd69ba1ab743662f1069eabdb7622f53bc9d 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3316,6 +3316,28 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3331,6 +3331,28 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM void setPlayerProfile(com.destroystokyo.paper.profile.@NotNull PlayerProfile profile); // Paper end - Player Profile API diff --git a/patches/api/0146-Material-API-additions.patch b/patches/api/0146-Material-API-additions.patch index bfae3f8d2b77..fa9a794ccad4 100644 --- a/patches/api/0146-Material-API-additions.patch +++ b/patches/api/0146-Material-API-additions.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Material API additions diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java -index 625fed5709d8dd814f4143d30ddb43bc57644fe6..28f2192f8a2748dfc631ce4b33599e23e6e68c62 100644 +index a53b79552a8a810ec0b1f1943e30c470217b26a9..6ebf024d5c2d5fc7253319b68ceed212de1cd73d 100644 --- a/src/main/java/org/bukkit/Material.java +++ b/src/main/java/org/bukkit/Material.java -@@ -131,6 +131,7 @@ import org.jetbrains.annotations.Nullable; +@@ -134,6 +134,7 @@ import org.jetbrains.annotations.Nullable; /** * An enum of all material IDs accepted by the official server and client */ @@ -16,7 +16,7 @@ index 625fed5709d8dd814f4143d30ddb43bc57644fe6..28f2192f8a2748dfc631ce4b33599e23 public enum Material implements Keyed, Translatable { // AIR(9648, 0), -@@ -4681,6 +4682,22 @@ public enum Material implements Keyed, Translatable { +@@ -4846,6 +4847,22 @@ public enum Material implements Keyed, Translatable { }); } diff --git a/patches/api/0147-Add-Material-Tags.patch b/patches/api/0147-Add-Material-Tags.patch index e5d1a2657dc4..c9fb3747a620 100644 --- a/patches/api/0147-Add-Material-Tags.patch +++ b/patches/api/0147-Add-Material-Tags.patch @@ -1140,7 +1140,7 @@ index 0000000000000000000000000000000000000000..bc07aaa5a001f8b58d0603d5db88f9c5 + .ensureSize("WATER_BASED", 12).lock(); +} diff --git a/src/main/java/org/bukkit/Tag.java b/src/main/java/org/bukkit/Tag.java -index e2a9b7db56e3048d1872f008a104bc33ddba98c3..b587897a26e9464b61a29e7482c60d2a66469571 100644 +index 2877eba0017ab8f3d94ca40a5e575e80adf0952e..0eca6dc6bcd9bbcad0a98a5956091bec362f2db6 100644 --- a/src/main/java/org/bukkit/Tag.java +++ b/src/main/java/org/bukkit/Tag.java @@ -11,6 +11,10 @@ import org.jetbrains.annotations.NotNull; diff --git a/patches/api/0149-Add-LivingEntity-getTargetEntity.patch b/patches/api/0149-Add-LivingEntity-getTargetEntity.patch index 27bc5319658b..40667d692a0b 100644 --- a/patches/api/0149-Add-LivingEntity-getTargetEntity.patch +++ b/patches/api/0149-Add-LivingEntity-getTargetEntity.patch @@ -51,7 +51,7 @@ index 0000000000000000000000000000000000000000..caa56541c435a3d9103cb0220ab88563 + } +} diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java -index fab432fc00cf41d240ba172d5be43464ca2417b3..b5ea7b60b47f056553a1cec766c57e0f75735633 100644 +index 09b0dd1b14e2848253c1d3bfecb98951764737ee..9e0137ea412ec8c65b2903a76499ba8222446ea3 100644 --- a/src/main/java/org/bukkit/entity/LivingEntity.java +++ b/src/main/java/org/bukkit/entity/LivingEntity.java @@ -175,6 +175,77 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource diff --git a/patches/api/0150-Add-sun-related-API.patch b/patches/api/0150-Add-sun-related-API.patch index 640a7df744ac..e0ca3a8475e6 100644 --- a/patches/api/0150-Add-sun-related-API.patch +++ b/patches/api/0150-Add-sun-related-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add sun related API diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index 6242b64416fdea1f3fd6378ba26ed7bb33ab4cc4..fcdc5d83621acff5f9210585455be1ea50abb77c 100644 +index c77ca55c0686512e6d50b559139b6d6bbeb61062..7dbc2e4883feb5b0b1a20cf36cda01ef3795a262 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -1798,6 +1798,16 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient diff --git a/patches/api/0166-Fix-Spigot-annotation-mistakes.patch b/patches/api/0166-Fix-Spigot-annotation-mistakes.patch index 779749140432..9ec07a782b04 100644 --- a/patches/api/0166-Fix-Spigot-annotation-mistakes.patch +++ b/patches/api/0166-Fix-Spigot-annotation-mistakes.patch @@ -300,10 +300,10 @@ index b02efba048be00e42502111fcdd2297529926666..fb4b6f0e908ffa50c3b2f8d04d9f3810 if (this.world == null) { return null; diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java -index 28f2192f8a2748dfc631ce4b33599e23e6e68c62..bddfc295bb1247097cb5fdae6e13585a45c18e1c 100644 +index 6ebf024d5c2d5fc7253319b68ceed212de1cd73d..309a79cbe65498c90d9e135607bc246688ac6274 100644 --- a/src/main/java/org/bukkit/Material.java +++ b/src/main/java/org/bukkit/Material.java -@@ -4702,20 +4702,20 @@ public enum Material implements Keyed, Translatable { +@@ -4867,20 +4867,20 @@ public enum Material implements Keyed, Translatable { * Do not use for any reason. * * @return ID of this material @@ -328,7 +328,7 @@ index 28f2192f8a2748dfc631ce4b33599e23e6e68c62..bddfc295bb1247097cb5fdae6e13585a public boolean isLegacy() { return legacy; } -@@ -4791,8 +4791,10 @@ public enum Material implements Keyed, Translatable { +@@ -4956,8 +4956,10 @@ public enum Material implements Keyed, Translatable { * Gets the MaterialData class associated with this Material * * @return MaterialData associated with this Material @@ -339,7 +339,7 @@ index 28f2192f8a2748dfc631ce4b33599e23e6e68c62..bddfc295bb1247097cb5fdae6e13585a public Class getData() { Preconditions.checkArgument(legacy, "Cannot get data class of Modern Material"); return ctor.getDeclaringClass(); -@@ -5248,7 +5250,11 @@ public enum Material implements Keyed, Translatable { +@@ -5413,7 +5415,11 @@ public enum Material implements Keyed, Translatable { * material. * * @return true if this material can be interacted with. @@ -715,10 +715,10 @@ index 3e07fc1bc0e08d0cfd998711c7fd547b2b7b6b73..f4a739d8022d19a7ae0ee9bf93eb5c48 /** diff --git a/src/main/java/org/bukkit/block/BlockType.java b/src/main/java/org/bukkit/block/BlockType.java -index 6c745f4db620870d7e74ead2e846df34832a9e8e..eb6b330763931b55d73537153dbdb5cc96d3e94f 100644 +index cd575a28733a101b3b18ecdeb28ce474413045d6..5ba088456e2c647a719c4ee1e6f006f5c1cca651 100644 --- a/src/main/java/org/bukkit/block/BlockType.java +++ b/src/main/java/org/bukkit/block/BlockType.java -@@ -3437,9 +3437,14 @@ public interface BlockType extends Keyed, Translatable { +@@ -3576,9 +3576,14 @@ public interface BlockType extends Keyed, Translatable { * state as well. This method will return true if there is at least one * state in which additional interact handling is performed for the * block type. @@ -837,10 +837,10 @@ index 3afe2787de576f7190d87c796bea0ab34dc30248..875817b807c9f515eb07b03cc85d3689 /** diff --git a/src/main/java/org/bukkit/entity/EntityType.java b/src/main/java/org/bukkit/entity/EntityType.java -index 4047f026ab796eca7ad2d6718e1436f251c08e93..d248069adfc67eb840951f7ab4a1fa5d30214dec 100644 +index f5b0ff195b3f7cf1c5b8ebe2fb8cefcf6c1012f4..1c1cdfd6b5a98a378ff7bb7bb3201e84662b52f3 100644 --- a/src/main/java/org/bukkit/entity/EntityType.java +++ b/src/main/java/org/bukkit/entity/EntityType.java -@@ -381,9 +381,9 @@ public enum EntityType implements Keyed, Translatable { +@@ -424,9 +424,9 @@ public enum EntityType implements Keyed, Translatable { * * @param name the entity type's name * @return the matching entity type or null @@ -932,10 +932,10 @@ index 9e0137ea412ec8c65b2903a76499ba8222446ea3..db7dafba43b50146a32d749ec043c5d5 /** diff --git a/src/main/java/org/bukkit/entity/Minecart.java b/src/main/java/org/bukkit/entity/Minecart.java -index 95c79c5fa0c4e30201f887da6467ce5f81c8a255..a1e4328994a119de2966dce5470581b5a520d55e 100644 +index 4910075d0fb21b4dc4fab57894f9c7cca3093e3b..9125cc9f60258938946ee30932f0299edcd9573b 100644 --- a/src/main/java/org/bukkit/entity/Minecart.java +++ b/src/main/java/org/bukkit/entity/Minecart.java -@@ -101,7 +101,9 @@ public interface Minecart extends Vehicle { +@@ -106,7 +106,9 @@ public interface Minecart extends Vehicle { * Passing a null value will set the minecart to have no display block. * * @param material the material to set as display block. @@ -945,7 +945,7 @@ index 95c79c5fa0c4e30201f887da6467ce5f81c8a255..a1e4328994a119de2966dce5470581b5 public void setDisplayBlock(@Nullable MaterialData material); /** -@@ -109,8 +111,10 @@ public interface Minecart extends Vehicle { +@@ -114,8 +116,10 @@ public interface Minecart extends Vehicle { * This function will return the type AIR if none is set. * * @return the block displayed by this minecart. @@ -970,10 +970,10 @@ index 60522888bc320ba0a55655532e19185fac816bd1..4aa07d4edb2c81d0ae7999b30ad53ff8 /** diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index dc9829ab0f4efcf9534f1b2d4a2e48ea49e8d372..e65f4f0df2e6832cf089572822c96ecc7a83dab3 100644 +index 4ee5dd69ba1ab743662f1069eabdb7622f53bc9d..2435b7d14b52bbd47c4ddb7bdd6849acf42bffef 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1640,11 +1640,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1655,11 +1655,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM /** * Forces an update of the player's entire inventory. @@ -1776,10 +1776,10 @@ index 597a18a767b68b47e81454b7d44613c7178c1366..bc3440eb72127824b3961fbdae583bb6 public ItemStack getInput() { return this.ingredient.getItemStack(); diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java -index 10ca843e57c74dfa32d539acd174c8867dfd56ec..e7ee3c9ac835a6eaf7faae44e6b2a811e8f8a703 100644 +index 480dd9a5ff334e6f32b98aa0108ff02e6f7077ab..59e1987f0f0accef369cc29dbec464185eb7c99c 100644 --- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java +++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java -@@ -144,6 +144,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -151,6 +151,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste /** * Checks for existence of a localized name. * @@ -1787,7 +1787,7 @@ index 10ca843e57c74dfa32d539acd174c8867dfd56ec..e7ee3c9ac835a6eaf7faae44e6b2a811 * @return true if this has a localized name * @deprecated meta no longer exists */ -@@ -156,6 +157,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -163,6 +164,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * Plugins should check that hasLocalizedName() returns true * before calling this method. * @@ -1795,7 +1795,7 @@ index 10ca843e57c74dfa32d539acd174c8867dfd56ec..e7ee3c9ac835a6eaf7faae44e6b2a811 * @return the localized name that is set * @deprecated meta no longer exists */ -@@ -166,6 +168,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -173,6 +175,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste /** * Sets the localized name. * @@ -1803,7 +1803,7 @@ index 10ca843e57c74dfa32d539acd174c8867dfd56ec..e7ee3c9ac835a6eaf7faae44e6b2a811 * @param name the name to set * @deprecated meta no longer exists */ -@@ -545,7 +548,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -749,7 +752,7 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * * @return component */ diff --git a/patches/api/0169-Add-Heightmap-API.patch b/patches/api/0169-Add-Heightmap-API.patch index b5d70f803f2e..a60fccf2adde 100644 --- a/patches/api/0169-Add-Heightmap-API.patch +++ b/patches/api/0169-Add-Heightmap-API.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add Heightmap API Changed to use upstream's heightmap API - Machine_Maker diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java -index eec6c9cd7da6938351905129bb5a66f49a257d01..65618b6b3c950fb27707f243a766511d6cd3aab4 100644 +index fb4b6f0e908ffa50c3b2f8d04d9f3810898b8d5e..bdc065a486306236c7f0960718bea53bc0b0a9b6 100644 --- a/src/main/java/org/bukkit/Location.java +++ b/src/main/java/org/bukkit/Location.java @@ -649,6 +649,30 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm diff --git a/patches/api/0173-Set-true-custom-payload-channel-size-limit.patch b/patches/api/0173-Set-true-custom-payload-channel-size-limit.patch index c524e2aaa0d2..e64cd78834e7 100644 --- a/patches/api/0173-Set-true-custom-payload-channel-size-limit.patch +++ b/patches/api/0173-Set-true-custom-payload-channel-size-limit.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Set true custom payload channel size limit This fixes compatibility with some mods that are sending very long channel names. Also gives developers the ability to send longer channel names. diff --git a/src/main/java/org/bukkit/plugin/messaging/Messenger.java b/src/main/java/org/bukkit/plugin/messaging/Messenger.java -index 9d2c68c826f3b867d407e7f13c6394a899cc8ee8..aec70aa740152c34297c42ad6e06c8b54523e78b 100644 +index c748a94523c8bc2140e1842ed7d8d462b52507d5..754fac6b2a45399efa34b06c6aa61f88c19e3d2b 100644 --- a/src/main/java/org/bukkit/plugin/messaging/Messenger.java +++ b/src/main/java/org/bukkit/plugin/messaging/Messenger.java @@ -24,7 +24,7 @@ public interface Messenger { diff --git a/patches/api/0183-Add-Player-Client-Options-API.patch b/patches/api/0183-Add-Player-Client-Options-API.patch index 56be6b483bb5..5e7bc03bd3e7 100644 --- a/patches/api/0183-Add-Player-Client-Options-API.patch +++ b/patches/api/0183-Add-Player-Client-Options-API.patch @@ -224,10 +224,10 @@ index 0000000000000000000000000000000000000000..6cf6aa876278d0d3e75148608951fc58 + } +} diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index e65f4f0df2e6832cf089572822c96ecc7a83dab3..b5573a26486fdfb6eb3aa7f9c46a67c8cddba34d 100644 +index 2435b7d14b52bbd47c4ddb7bdd6849acf42bffef..f4b1ed868a1fc8aa22fd07c3bf3aef886b8c8679 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3335,6 +3335,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3350,6 +3350,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM void resetCooldown(); // Paper end - attack cooldown API diff --git a/patches/api/0186-Villager-Restocks-API.patch b/patches/api/0186-Villager-Restocks-API.patch index 39c67cae0f00..66dc60c254fc 100644 --- a/patches/api/0186-Villager-Restocks-API.patch +++ b/patches/api/0186-Villager-Restocks-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Villager Restocks API diff --git a/src/main/java/org/bukkit/entity/Villager.java b/src/main/java/org/bukkit/entity/Villager.java -index cfa0d4809f9bb4ac150251efa85ba4d1808ab1b2..ecb0f32a4449f8000248c4bebf89a56df186899f 100644 +index af4582f3e4687933dac6ccd43667a373f8daedb6..5a61175ccfe67c0a3c55cc2b84772fa8f6e6a6cb 100644 --- a/src/main/java/org/bukkit/entity/Villager.java +++ b/src/main/java/org/bukkit/entity/Villager.java @@ -82,6 +82,20 @@ public interface Villager extends AbstractVillager { diff --git a/patches/api/0190-Potential-bed-API.patch b/patches/api/0190-Potential-bed-API.patch index 1cbb7daffa24..a45ca6b83555 100644 --- a/patches/api/0190-Potential-bed-API.patch +++ b/patches/api/0190-Potential-bed-API.patch @@ -8,10 +8,10 @@ Adds a new method to fetch the location of a player's bed without generating any getPotentialBedLocation - Gets the last known location of a player's bed. This does not preform any check if the bed is still valid and does not load any chunks. diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java -index 3985798654a3085c128144e46f7113b7744b8d14..11c5846848a6631a9376934622caeadd448b0391 100644 +index 6c2f01bf452d991faf40b995225bf7b7e49281df..92ceb765ccb80c3b09ac3ede9bcaad6219fabd3d 100644 --- a/src/main/java/org/bukkit/entity/HumanEntity.java +++ b/src/main/java/org/bukkit/entity/HumanEntity.java -@@ -277,6 +277,19 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder +@@ -308,6 +308,19 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder */ public int getSleepTicks(); diff --git a/patches/api/0193-Support-components-in-ItemMeta.patch b/patches/api/0193-Support-components-in-ItemMeta.patch index 5c407e184d66..d66067471bb3 100644 --- a/patches/api/0193-Support-components-in-ItemMeta.patch +++ b/patches/api/0193-Support-components-in-ItemMeta.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Support components in ItemMeta diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java -index e7ee3c9ac835a6eaf7faae44e6b2a811e8f8a703..1a4260b00b193b94ce4b1b2954644f4e41baff4c 100644 +index 59e1987f0f0accef369cc29dbec464185eb7c99c..afdcc2d67d55f2f07c913816e1f5b290d1415357 100644 --- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java +++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java @@ -5,6 +5,7 @@ import java.util.Collection; @@ -13,10 +13,10 @@ index e7ee3c9ac835a6eaf7faae44e6b2a811e8f8a703..1a4260b00b193b94ce4b1b2954644f4e import java.util.Map; import java.util.Set; +import net.kyori.adventure.text.Component; + import org.bukkit.NamespacedKey; + import org.bukkit.Tag; import org.bukkit.attribute.Attribute; - import org.bukkit.attribute.AttributeModifier; - import org.bukkit.configuration.serialization.ConfigurationSerializable; -@@ -68,6 +69,20 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -75,6 +76,20 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste @NotNull String getDisplayName(); @@ -37,7 +37,7 @@ index e7ee3c9ac835a6eaf7faae44e6b2a811e8f8a703..1a4260b00b193b94ce4b1b2954644f4e /** * Sets the display name. * -@@ -77,6 +92,16 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -84,6 +99,16 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste @Deprecated // Paper void setDisplayName(@Nullable String name); @@ -54,7 +54,7 @@ index e7ee3c9ac835a6eaf7faae44e6b2a811e8f8a703..1a4260b00b193b94ce4b1b2954644f4e /** * Checks for existence of an item name. *
    -@@ -213,6 +238,19 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -220,6 +245,19 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste @Nullable List getLore(); @@ -74,7 +74,7 @@ index e7ee3c9ac835a6eaf7faae44e6b2a811e8f8a703..1a4260b00b193b94ce4b1b2954644f4e /** * Sets the lore for this item. * Removes lore when given null. -@@ -223,6 +261,16 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -230,6 +268,16 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste @Deprecated // Paper void setLore(@Nullable List lore); diff --git a/patches/api/0198-Brand-support.patch b/patches/api/0198-Brand-support.patch index 64e9c90fb4f7..9c23fa64a05e 100644 --- a/patches/api/0198-Brand-support.patch +++ b/patches/api/0198-Brand-support.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Brand support diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index b5573a26486fdfb6eb3aa7f9c46a67c8cddba34d..3f7ce423ef9f43c1ce9f8ef968eb2e3220906d77 100644 +index f4b1ed868a1fc8aa22fd07c3bf3aef886b8c8679..38c61979c20768ad7790c2c7d6463c9d10fb3611 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3448,6 +3448,16 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3463,6 +3463,16 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM // Paper end } diff --git a/patches/api/0202-Add-methods-to-get-translation-keys.patch b/patches/api/0202-Add-methods-to-get-translation-keys.patch index fe71b1056aa5..825d506e8a31 100644 --- a/patches/api/0202-Add-methods-to-get-translation-keys.patch +++ b/patches/api/0202-Add-methods-to-get-translation-keys.patch @@ -119,7 +119,7 @@ index 81e45984a88fc84acd0f76d825abf4ddaed0ac3b..fdc42a79c5af30fdade41ee99245e664 /** diff --git a/src/main/java/org/bukkit/GameRule.java b/src/main/java/org/bukkit/GameRule.java -index dc66bd69646ac949d1386ce8f6ff913e9475439d..4482e8f2c617c2f51b2b53762e775d118002363a 100644 +index b3211a705acc26449675727823aa42ae6bacac4f..8b6584fae0a9d5cccbe350d889fa8b4a14c78ca3 100644 --- a/src/main/java/org/bukkit/GameRule.java +++ b/src/main/java/org/bukkit/GameRule.java @@ -15,7 +15,7 @@ import org.jetbrains.annotations.Nullable; @@ -131,7 +131,7 @@ index dc66bd69646ac949d1386ce8f6ff913e9475439d..4482e8f2c617c2f51b2b53762e775d11 private static Map> gameRules = new HashMap<>(); // Boolean rules -@@ -355,4 +355,11 @@ public final class GameRule { +@@ -366,4 +366,11 @@ public final class GameRule { public static GameRule[] values() { return gameRules.values().toArray(new GameRule[gameRules.size()]); } @@ -144,10 +144,10 @@ index dc66bd69646ac949d1386ce8f6ff913e9475439d..4482e8f2c617c2f51b2b53762e775d11 + // Paper end } diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java -index bddfc295bb1247097cb5fdae6e13585a45c18e1c..39bf5b2e93f45000d2e894b5c3d059b889068aae 100644 +index 309a79cbe65498c90d9e135607bc246688ac6274..8820dd330cee4f8463f2f39f84d4be0762558368 100644 --- a/src/main/java/org/bukkit/Material.java +++ b/src/main/java/org/bukkit/Material.java -@@ -132,7 +132,7 @@ import org.jetbrains.annotations.Nullable; +@@ -135,7 +135,7 @@ import org.jetbrains.annotations.Nullable; * An enum of all material IDs accepted by the official server and client */ @SuppressWarnings({"DeprecatedIsStillUsed", "deprecation"}) // Paper @@ -156,7 +156,7 @@ index bddfc295bb1247097cb5fdae6e13585a45c18e1c..39bf5b2e93f45000d2e894b5c3d059b8 // AIR(9648, 0), STONE(22948), -@@ -4698,6 +4698,17 @@ public enum Material implements Keyed, Translatable { +@@ -4863,6 +4863,17 @@ public enum Material implements Keyed, Translatable { } // Paper end @@ -174,7 +174,7 @@ index bddfc295bb1247097cb5fdae6e13585a45c18e1c..39bf5b2e93f45000d2e894b5c3d059b8 /** * Do not use for any reason. * -@@ -5447,9 +5458,11 @@ public enum Material implements Keyed, Translatable { +@@ -5612,9 +5623,11 @@ public enum Material implements Keyed, Translatable { * material * @see #getBlockTranslationKey() * @see #getItemTranslationKey() @@ -235,7 +235,7 @@ index e3faa2c675c85a9cbdbbb1debec0ff81c58a1bbd..fd1629c2d2028a88fb3d56b0aeb833d1 String getTranslationKey(); } diff --git a/src/main/java/org/bukkit/attribute/Attribute.java b/src/main/java/org/bukkit/attribute/Attribute.java -index ef9c998691d101c26b5247a4962628a7bc9e513f..947874c0172b690e7752e49b7bec64e0c0308515 100644 +index e5a9d1692f0f6fd8e9ac4903782e9330b4da6ef3..6075cd2a88394cd7f0ce2470e732a45094b033c0 100644 --- a/src/main/java/org/bukkit/attribute/Attribute.java +++ b/src/main/java/org/bukkit/attribute/Attribute.java @@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull; @@ -247,7 +247,7 @@ index ef9c998691d101c26b5247a4962628a7bc9e513f..947874c0172b690e7752e49b7bec64e0 /** * Maximum health of an Entity. -@@ -153,4 +153,12 @@ public enum Attribute implements Keyed, Translatable { +@@ -157,4 +157,12 @@ public enum Attribute implements Keyed, Translatable { public String getTranslationKey() { return Bukkit.getUnsafe().getTranslationKey(this); } @@ -261,10 +261,10 @@ index ef9c998691d101c26b5247a4962628a7bc9e513f..947874c0172b690e7752e49b7bec64e0 + // Paper end } diff --git a/src/main/java/org/bukkit/block/Biome.java b/src/main/java/org/bukkit/block/Biome.java -index d3087d60378822cdd7cea25fd63d3f496e3cd2fb..5d8fa5b39a5d50cca48ba63af3a84b80f279b649 100644 +index 2201b63e7335b12622268a3ef40d1fcb06c1d705..b71975b904d48e22a0e2134bb0e8231679dd9700 100644 --- a/src/main/java/org/bukkit/block/Biome.java +++ b/src/main/java/org/bukkit/block/Biome.java -@@ -8,7 +8,7 @@ import org.jetbrains.annotations.NotNull; +@@ -10,7 +10,7 @@ import org.jetbrains.annotations.NotNull; /** * Holds all accepted Biomes in the default server */ @@ -273,7 +273,7 @@ index d3087d60378822cdd7cea25fd63d3f496e3cd2fb..5d8fa5b39a5d50cca48ba63af3a84b80 OCEAN, PLAINS, DESERT, -@@ -89,4 +89,11 @@ public enum Biome implements Keyed { +@@ -94,4 +94,11 @@ public enum Biome implements Keyed { public NamespacedKey getKey() { return key; } @@ -312,10 +312,10 @@ index 745413357506fa7399f8ba44dfe222d1f0c919f1..25db31b2e9a6d75f0c59f75237842f9a // Paper end } diff --git a/src/main/java/org/bukkit/block/BlockType.java b/src/main/java/org/bukkit/block/BlockType.java -index eb6b330763931b55d73537153dbdb5cc96d3e94f..5bfa98695265cdfd246411f93ab670d2c9e64ef1 100644 +index 5ba088456e2c647a719c4ee1e6f006f5c1cca651..aebd34785bb2070389ad2e2803fa9ff803b318c5 100644 --- a/src/main/java/org/bukkit/block/BlockType.java +++ b/src/main/java/org/bukkit/block/BlockType.java -@@ -125,7 +125,7 @@ import org.jetbrains.annotations.Nullable; +@@ -129,7 +129,7 @@ import org.jetbrains.annotations.Nullable; * changes may occur. Do not use this API in plugins. */ @ApiStatus.Internal @@ -324,7 +324,7 @@ index eb6b330763931b55d73537153dbdb5cc96d3e94f..5bfa98695265cdfd246411f93ab670d2 /** * Typed represents a subtype of {@link BlockType}s that have a known block -@@ -3502,4 +3502,13 @@ public interface BlockType extends Keyed, Translatable { +@@ -3641,4 +3641,13 @@ public interface BlockType extends Keyed, Translatable { @Nullable @Deprecated Material asMaterial(); @@ -384,10 +384,10 @@ index c4f86ba1037f3f0e5d697a0962d71d6f8c7c1fbe..ac0371285370594d4de1554871b19bbc // Paper end } diff --git a/src/main/java/org/bukkit/entity/EntityType.java b/src/main/java/org/bukkit/entity/EntityType.java -index d248069adfc67eb840951f7ab4a1fa5d30214dec..976f701ed9b9873945a5628173c580e2e6873864 100644 +index 1c1cdfd6b5a98a378ff7bb7bb3201e84662b52f3..be1c8c9b27ad792f2b0ff1cec0c575eb1fc3023a 100644 --- a/src/main/java/org/bukkit/entity/EntityType.java +++ b/src/main/java/org/bukkit/entity/EntityType.java -@@ -23,7 +23,7 @@ import org.jetbrains.annotations.Contract; +@@ -45,7 +45,7 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -396,7 +396,7 @@ index d248069adfc67eb840951f7ab4a1fa5d30214dec..976f701ed9b9873945a5628173c580e2 // These strings MUST match the strings in nms.EntityTypes and are case sensitive. /** -@@ -427,10 +427,22 @@ public enum EntityType implements Keyed, Translatable { +@@ -470,10 +470,22 @@ public enum EntityType implements Keyed, Translatable { @Override @NotNull @@ -564,10 +564,10 @@ index af09398e0864d338da530495bfd577db8adbe65a..60eec8a12f01562678732bcf38ac407e // Paper end } diff --git a/src/main/java/org/bukkit/inventory/ItemType.java b/src/main/java/org/bukkit/inventory/ItemType.java -index 1db9c6bd6e44ddd3d8550a2906422c97d45eb9ea..2b1a1ad04212651ad5a43edecca12b495ce61fd5 100644 +index 88e1883dffb64974f5ec60acbf2828cfb9de9439..49e5a9ea7cf5e4d7a4333d2cffa4e44b1a436403 100644 --- a/src/main/java/org/bukkit/inventory/ItemType.java +++ b/src/main/java/org/bukkit/inventory/ItemType.java -@@ -47,7 +47,7 @@ import org.jetbrains.annotations.Nullable; +@@ -48,7 +48,7 @@ import org.jetbrains.annotations.Nullable; * changes may occur. Do not use this API in plugins. */ @ApiStatus.Internal @@ -576,7 +576,7 @@ index 1db9c6bd6e44ddd3d8550a2906422c97d45eb9ea..2b1a1ad04212651ad5a43edecca12b49 /** * Typed represents a subtype of {@link ItemType}s that have a known item meta type -@@ -2297,4 +2297,13 @@ public interface ItemType extends Keyed, Translatable { +@@ -2448,4 +2448,13 @@ public interface ItemType extends Keyed, Translatable { @Nullable @Deprecated Material asMaterial(); diff --git a/patches/api/0204-Add-additional-open-container-api-to-HumanEntity.patch b/patches/api/0204-Add-additional-open-container-api-to-HumanEntity.patch index 3fe46b8c28ba..8fc602cf5596 100644 --- a/patches/api/0204-Add-additional-open-container-api-to-HumanEntity.patch +++ b/patches/api/0204-Add-additional-open-container-api-to-HumanEntity.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add additional open container api to HumanEntity diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java -index 11c5846848a6631a9376934622caeadd448b0391..f20b0a439c4d5cd2c6caa70a46b1b49f8ab23425 100644 +index 92ceb765ccb80c3b09ac3ede9bcaad6219fabd3d..25f671863e23fdb674c55f3e1f50b1f195ca5469 100644 --- a/src/main/java/org/bukkit/entity/HumanEntity.java +++ b/src/main/java/org/bukkit/entity/HumanEntity.java @@ -182,6 +182,92 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder diff --git a/patches/api/0208-Player-elytra-boost-API.patch b/patches/api/0208-Player-elytra-boost-API.patch index 556783227408..9dcab2869b8e 100644 --- a/patches/api/0208-Player-elytra-boost-API.patch +++ b/patches/api/0208-Player-elytra-boost-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Player elytra boost API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 3f7ce423ef9f43c1ce9f8ef968eb2e3220906d77..77e14139e5cd22278e6decc7e5de31411fa2ae45 100644 +index 38c61979c20768ad7790c2c7d6463c9d10fb3611..756240eef598bdf44507ab003cf1141ac0122292 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3342,6 +3342,25 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3357,6 +3357,25 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM @NotNull T getClientOption(com.destroystokyo.paper.@NotNull ClientOption option); // Paper end - client option API diff --git a/patches/api/0220-Expose-LivingEntity-hurt-direction.patch b/patches/api/0220-Expose-LivingEntity-hurt-direction.patch index cd51cbd838b7..1ee818c76f33 100644 --- a/patches/api/0220-Expose-LivingEntity-hurt-direction.patch +++ b/patches/api/0220-Expose-LivingEntity-hurt-direction.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Expose LivingEntity hurt direction diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java -index d06539841d973030c0cd5bb06a085ed2f0f73af6..7759062ca34506c56d2d1340cf1d9c2d36151d48 100644 +index 25f671863e23fdb674c55f3e1f50b1f195ca5469..b9c19abe26c100558c4a0388d65c2316261ee1d3 100644 --- a/src/main/java/org/bukkit/entity/HumanEntity.java +++ b/src/main/java/org/bukkit/entity/HumanEntity.java @@ -356,6 +356,16 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder @@ -23,7 +23,7 @@ index d06539841d973030c0cd5bb06a085ed2f0f73af6..7759062ca34506c56d2d1340cf1d9c2d + // Paper end + /** - * Get the sleep ticks of the player. This value may be capped. + * Check whether a cooldown is active on the specified item. * diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java index 784da48ffc63bc932caafe58cf56ad30e7a86be6..49352ed3928163c6322634b8e6f1d3dd8caa5e74 100644 diff --git a/patches/api/0225-Add-API-to-get-Material-from-Boats-and-Minecarts.patch b/patches/api/0225-Add-API-to-get-Material-from-Boats-and-Minecarts.patch index 081fbd1bf88e..143ac8e614db 100644 --- a/patches/api/0225-Add-API-to-get-Material-from-Boats-and-Minecarts.patch +++ b/patches/api/0225-Add-API-to-get-Material-from-Boats-and-Minecarts.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add API to get Material from Boats and Minecarts diff --git a/src/main/java/org/bukkit/entity/Boat.java b/src/main/java/org/bukkit/entity/Boat.java -index 88852215d01f3fc4866449f7b826f6603b0ed9d8..f7548098bcdd033d9c530fdc584fc5538c635ca1 100644 +index dbdd2c1ad74a4d56e282736cd06d6937701f2e5c..a0fb3c44405f6362f8a1613661d507e448f7ba6b 100644 --- a/src/main/java/org/bukkit/entity/Boat.java +++ b/src/main/java/org/bukkit/entity/Boat.java -@@ -175,4 +175,14 @@ public interface Boat extends Vehicle { +@@ -181,4 +181,14 @@ public interface Boat extends Vehicle { ON_LAND, IN_AIR; } @@ -24,17 +24,18 @@ index 88852215d01f3fc4866449f7b826f6603b0ed9d8..f7548098bcdd033d9c530fdc584fc553 + // Paper end } diff --git a/src/main/java/org/bukkit/entity/Minecart.java b/src/main/java/org/bukkit/entity/Minecart.java -index a1e4328994a119de2966dce5470581b5a520d55e..d1f602faa34cc5cc4563e18b63a40078e406641d 100644 +index 9125cc9f60258938946ee30932f0299edcd9573b..148d8cddba48a886eddef72a3de63d5eaa15949f 100644 --- a/src/main/java/org/bukkit/entity/Minecart.java +++ b/src/main/java/org/bukkit/entity/Minecart.java -@@ -1,5 +1,6 @@ +@@ -1,6 +1,7 @@ package org.bukkit.entity; + import org.bukkit.GameRule; +import org.bukkit.Material; import org.bukkit.block.data.BlockData; import org.bukkit.material.MaterialData; import org.bukkit.util.Vector; -@@ -147,4 +148,14 @@ public interface Minecart extends Vehicle { +@@ -152,4 +153,14 @@ public interface Minecart extends Vehicle { * @return the current block offset for this minecart. */ public int getDisplayBlockOffset(); diff --git a/patches/api/0235-Add-sendOpLevel-API.patch b/patches/api/0235-Add-sendOpLevel-API.patch index 360c197b188e..f6506212bcac 100644 --- a/patches/api/0235-Add-sendOpLevel-API.patch +++ b/patches/api/0235-Add-sendOpLevel-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add sendOpLevel API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 77e14139e5cd22278e6decc7e5de31411fa2ae45..466218a3b7f749b3de67e619285ceeb6d85cc28e 100644 +index 756240eef598bdf44507ab003cf1141ac0122292..7e2f2904cc6da994aaf8764399a836c5586cbd70 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3361,6 +3361,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3376,6 +3376,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM } // Paper end - elytra boost API diff --git a/patches/api/0254-Improve-Item-Rarity-API.patch b/patches/api/0254-Improve-Item-Rarity-API.patch index 7a78a33aecb9..6914d28cf844 100644 --- a/patches/api/0254-Improve-Item-Rarity-API.patch +++ b/patches/api/0254-Improve-Item-Rarity-API.patch @@ -43,10 +43,10 @@ index 0000000000000000000000000000000000000000..f1cd5a4f37eee8975ac3d0421b524afc + } +} diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java -index 39bf5b2e93f45000d2e894b5c3d059b889068aae..4ceb90598e4060678c2382568d4a691769efe126 100644 +index 8820dd330cee4f8463f2f39f84d4be0762558368..39277b3113a3bd0736330773e3c5c1f747773b55 100644 --- a/src/main/java/org/bukkit/Material.java +++ b/src/main/java/org/bukkit/Material.java -@@ -4709,6 +4709,21 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla +@@ -4874,6 +4874,21 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla } // Paper end - add Translatable @@ -132,10 +132,10 @@ index 60eec8a12f01562678732bcf38ac407e70d74965..45fc5fab3817a8d9e1c83bcfb0add9eb // Paper end } diff --git a/src/main/java/org/bukkit/inventory/ItemType.java b/src/main/java/org/bukkit/inventory/ItemType.java -index 2b1a1ad04212651ad5a43edecca12b495ce61fd5..9077257ed935a26af057b9d090f7d819956ebbce 100644 +index 49e5a9ea7cf5e4d7a4333d2cffa4e44b1a436403..d049aec3865c0eaa570ffe4234f02ff13d77e542 100644 --- a/src/main/java/org/bukkit/inventory/ItemType.java +++ b/src/main/java/org/bukkit/inventory/ItemType.java -@@ -2306,4 +2306,13 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans +@@ -2457,4 +2457,13 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans @Override @NotNull String getTranslationKey(); // Paper end - add Translatable diff --git a/patches/api/0256-add-isDeeplySleeping-to-HumanEntity.patch b/patches/api/0256-add-isDeeplySleeping-to-HumanEntity.patch index 14754cc21ce1..29f430175b35 100644 --- a/patches/api/0256-add-isDeeplySleeping-to-HumanEntity.patch +++ b/patches/api/0256-add-isDeeplySleeping-to-HumanEntity.patch @@ -5,7 +5,7 @@ Subject: [PATCH] add isDeeplySleeping to HumanEntity diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java -index 937c136f2499bd1660989d14c0f50a7ef9a1a2b6..b1b18886fc63a4854c2858ff9869da70e92dae26 100644 +index b9c19abe26c100558c4a0388d65c2316261ee1d3..36b48bfff60ecc3d49f9f6575a91dd6b73ecf1ab 100644 --- a/src/main/java/org/bukkit/entity/HumanEntity.java +++ b/src/main/java/org/bukkit/entity/HumanEntity.java @@ -366,6 +366,15 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder @@ -22,5 +22,5 @@ index 937c136f2499bd1660989d14c0f50a7ef9a1a2b6..b1b18886fc63a4854c2858ff9869da70 + // Paper end + /** - * Get the sleep ticks of the player. This value may be capped. + * Check whether a cooldown is active on the specified item. * diff --git a/patches/api/0270-Add-basic-Datapack-API.patch b/patches/api/0270-Add-basic-Datapack-API.patch index 5535058f121b..796a519bd972 100644 --- a/patches/api/0270-Add-basic-Datapack-API.patch +++ b/patches/api/0270-Add-basic-Datapack-API.patch @@ -237,10 +237,10 @@ index b558fa73dbcf3747690933e6aadf7061a0de2630..be68351555bde59a4e55bf1bad261e9f @NotNull diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java -index 4ceb90598e4060678c2382568d4a691769efe126..052d319e69f22277cb6e379e47380c7dc466d120 100644 +index 39277b3113a3bd0736330773e3c5c1f747773b55..c18fb0c9a6635a67041ba7499e8b2f97ce9a76d4 100644 --- a/src/main/java/org/bukkit/Material.java +++ b/src/main/java/org/bukkit/Material.java -@@ -5518,6 +5518,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla +@@ -5683,6 +5683,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla * @param world the world to check * @return true if this material can be used in this World. */ @@ -277,10 +277,10 @@ index 42930006b6425b5d82233e4ffe7025ce5397b277..45693e6c02eac37eb609cd3c59253a94 // Paper end } diff --git a/src/main/java/org/bukkit/entity/EntityType.java b/src/main/java/org/bukkit/entity/EntityType.java -index 976f701ed9b9873945a5628173c580e2e6873864..eea0351559a2835280713f5d5d1d430c7cf857a0 100644 +index be1c8c9b27ad792f2b0ff1cec0c575eb1fc3023a..f08d241d5350dfdb0d325e89190c90f79a5c791e 100644 --- a/src/main/java/org/bukkit/entity/EntityType.java +++ b/src/main/java/org/bukkit/entity/EntityType.java -@@ -449,6 +449,7 @@ public enum EntityType implements Keyed, Translatable, net.kyori.adventure.trans +@@ -492,6 +492,7 @@ public enum EntityType implements Keyed, Translatable, net.kyori.adventure.trans * @param world the world to check * @return true if this EntityType can be used to spawn an Entity for this World. */ diff --git a/patches/api/0272-ItemStack-repair-check-API.patch b/patches/api/0272-ItemStack-repair-check-API.patch index 783c40966a96..6ef26350c743 100644 --- a/patches/api/0272-ItemStack-repair-check-API.patch +++ b/patches/api/0272-ItemStack-repair-check-API.patch @@ -25,7 +25,7 @@ index 51473ffbec65a2344449daa8ff5cf535b0b60520..07669aad6d9910174fbc8fdf3cdd5421 // Paper end } diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index d2af613c56010f3b0dd0d3ff7b438193127353d0..5b84aec2897b35da3e1bee8ac73fba5c83717d5d 100644 +index 45fc5fab3817a8d9e1c83bcfb0add9eba023abfe..ea50697a8dcdf87be046569b75fcc53ec870ca3e 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -1006,5 +1006,27 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat diff --git a/patches/api/0275-ItemStack-editMeta.patch b/patches/api/0275-ItemStack-editMeta.patch index 83787f07f979..7361918ba909 100644 --- a/patches/api/0275-ItemStack-editMeta.patch +++ b/patches/api/0275-ItemStack-editMeta.patch @@ -5,7 +5,7 @@ Subject: [PATCH] ItemStack#editMeta diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index b38154b45935ec45154e89277a8c2b1b9e46522d..7789c57ee27dc0e95764a6a5830de4cba210aa3b 100644 +index ea50697a8dcdf87be046569b75fcc53ec870ca3e..1d1731776af5f59cd9e6bd07cb3b9fab5073ef66 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -574,6 +574,50 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat diff --git a/patches/api/0277-Improve-item-default-attribute-API.patch b/patches/api/0277-Improve-item-default-attribute-API.patch index cba247deebfd..5fd65d72195c 100644 --- a/patches/api/0277-Improve-item-default-attribute-API.patch +++ b/patches/api/0277-Improve-item-default-attribute-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Improve item default attribute API diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java -index 052d319e69f22277cb6e379e47380c7dc466d120..eec1e53ce607d36a2e72f16a4a351869fd2f609f 100644 +index c18fb0c9a6635a67041ba7499e8b2f97ce9a76d4..3b344a49c26e9f4b3a7ae54ecb90da7c08d0ad49 100644 --- a/src/main/java/org/bukkit/Material.java +++ b/src/main/java/org/bukkit/Material.java -@@ -4724,6 +4724,23 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla +@@ -4889,6 +4889,23 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla } // Paper end - item rarity API @@ -32,7 +32,7 @@ index 052d319e69f22277cb6e379e47380c7dc466d120..eec1e53ce607d36a2e72f16a4a351869 /** * Do not use for any reason. * -@@ -5431,13 +5448,34 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla +@@ -5596,13 +5613,34 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla } } @@ -72,10 +72,10 @@ index 052d319e69f22277cb6e379e47380c7dc466d120..eec1e53ce607d36a2e72f16a4a351869 * * @param slot the {@link EquipmentSlot} to check diff --git a/src/main/java/org/bukkit/inventory/ItemType.java b/src/main/java/org/bukkit/inventory/ItemType.java -index 9077257ed935a26af057b9d090f7d819956ebbce..c42cfa76ff73a3ce8a164cb94a9c3f553b005ea5 100644 +index d049aec3865c0eaa570ffe4234f02ff13d77e542..7a1a0aebbfdaac6b6af41236d4a00512244b58fa 100644 --- a/src/main/java/org/bukkit/inventory/ItemType.java +++ b/src/main/java/org/bukkit/inventory/ItemType.java -@@ -2256,6 +2256,21 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans +@@ -2407,6 +2407,21 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans // @NotNull // EquipmentSlot getEquipmentSlot(); diff --git a/patches/api/0280-Add-PlayerKickEvent-causes.patch b/patches/api/0280-Add-PlayerKickEvent-causes.patch index aa55ace2fe76..69ccfc773574 100644 --- a/patches/api/0280-Add-PlayerKickEvent-causes.patch +++ b/patches/api/0280-Add-PlayerKickEvent-causes.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerKickEvent causes diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 466218a3b7f749b3de67e619285ceeb6d85cc28e..7f854d545a76a6e4dd2439f9a6e193fa54d5874d 100644 +index 7e2f2904cc6da994aaf8764399a836c5586cbd70..b39e8c1cdeee3d554839a055ccbae725aa3d66f5 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -319,6 +319,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -334,6 +334,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param message kick message */ void kick(final net.kyori.adventure.text.@Nullable Component message); diff --git a/patches/api/0284-Add-more-line-of-sight-methods.patch b/patches/api/0284-Add-more-line-of-sight-methods.patch index 151554550047..43d0fda6245c 100644 --- a/patches/api/0284-Add-more-line-of-sight-methods.patch +++ b/patches/api/0284-Add-more-line-of-sight-methods.patch @@ -23,7 +23,7 @@ index d8b1fa79dc24138dc71e32c14bda71c1d570ed88..b68367f123f029c3ff47eab6bfabd7a8 // Paper end } diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java -index 4327045ec437c9c81bcd4c34c4959de6d5798132..4ba92fe8979ed127c18cb78c2b8204daa2425ed7 100644 +index 49352ed3928163c6322634b8e6f1d3dd8caa5e74..2eb6f650610ca1a9b9fca49e453f79e08944be75 100644 --- a/src/main/java/org/bukkit/entity/LivingEntity.java +++ b/src/main/java/org/bukkit/entity/LivingEntity.java @@ -622,6 +622,19 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource diff --git a/patches/api/0287-Missing-Entity-API.patch b/patches/api/0287-Missing-Entity-API.patch index 94f2d56efecc..00f38bebc3a5 100644 --- a/patches/api/0287-Missing-Entity-API.patch +++ b/patches/api/0287-Missing-Entity-API.patch @@ -1095,15 +1095,18 @@ index 4374d5206d4d15a4d8d228c137ed9a96821a1f02..0eb7214472f3a43641a3526000af6bee +} +// Paper end diff --git a/src/main/java/org/bukkit/entity/Salmon.java b/src/main/java/org/bukkit/entity/Salmon.java -index a52a7af219633d575dcbe8ac4b219834bfd4d4d2..1e839b247182af6873a4d74b236d6412817c18bf 100644 +index 407aa5de170a3f0160c197a2b228f2e3b3269387..d8a2d44fe50a9ab24d8916aad270dfba0bd84e5e 100644 --- a/src/main/java/org/bukkit/entity/Salmon.java +++ b/src/main/java/org/bukkit/entity/Salmon.java -@@ -4,4 +4,4 @@ package org.bukkit.entity; +@@ -5,7 +5,7 @@ import org.jetbrains.annotations.NotNull; /** * Represents a salmon fish. */ --public interface Salmon extends Fish { } -+public interface Salmon extends io.papermc.paper.entity.SchoolableFish { } // Paper - Schooling Fish API +-public interface Salmon extends Fish { ++public interface Salmon extends io.papermc.paper.entity.SchoolableFish { // Paper - Schooling Fish API + + /** + * Get the variant of this salmon. diff --git a/src/main/java/org/bukkit/entity/TNTPrimed.java b/src/main/java/org/bukkit/entity/TNTPrimed.java index 0813bd913c8fdb2001963ce3e82c07c2af105418..87e717c9ea61b0cbf536bc62fa829ddcfae5ad8c 100644 --- a/src/main/java/org/bukkit/entity/TNTPrimed.java diff --git a/patches/api/0291-Stinger-API.patch b/patches/api/0291-Stinger-API.patch index 84fe8f4c2266..a12c525d768a 100644 --- a/patches/api/0291-Stinger-API.patch +++ b/patches/api/0291-Stinger-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Stinger API diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java -index 73247ab2cd2cf0035cf88c98250736f9bc9ee517..22428de50580f7b70d14484ba229aa271bfd7069 100644 +index c0772f72768846cffd065c53de7326f9fe6386a2..f7a3dd62ae5e492a7bccf8167cec0fc560499fa2 100644 --- a/src/main/java/org/bukkit/entity/LivingEntity.java +++ b/src/main/java/org/bukkit/entity/LivingEntity.java @@ -451,6 +451,52 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource diff --git a/patches/api/0303-Add-methods-to-find-targets-for-lightning-strikes.patch b/patches/api/0303-Add-methods-to-find-targets-for-lightning-strikes.patch index b045b2afc976..dd357bfe8c44 100644 --- a/patches/api/0303-Add-methods-to-find-targets-for-lightning-strikes.patch +++ b/patches/api/0303-Add-methods-to-find-targets-for-lightning-strikes.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add methods to find targets for lightning strikes diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index d3fc033aba36c5fd99846e9200ed0071fddd6045..637480c622bdb170456baabe71d84e446ebd7b13 100644 +index ce1f3ffbab6a8dc8395e3a5b74a7874bb6b38aa9..90270582b75705e42b4690cadb6d15de3188d98f 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -692,6 +692,37 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient diff --git a/patches/api/0304-Get-entity-default-attributes.patch b/patches/api/0304-Get-entity-default-attributes.patch index d77cd64f2c47..fd13ed8d7cfb 100644 --- a/patches/api/0304-Get-entity-default-attributes.patch +++ b/patches/api/0304-Get-entity-default-attributes.patch @@ -32,10 +32,10 @@ index 07669aad6d9910174fbc8fdf3cdd54211fbfcee3..a25f7378e5cef3899c38dd34d369da04 // Paper end } diff --git a/src/main/java/org/bukkit/entity/EntityType.java b/src/main/java/org/bukkit/entity/EntityType.java -index 976f701ed9b9873945a5628173c580e2e6873864..6905614c3d277a3a725554f02cc92d4b3430eecc 100644 +index f08d241d5350dfdb0d325e89190c90f79a5c791e..6521a20d69a4c8e75be7e9b3fdebbc25b843ec1b 100644 --- a/src/main/java/org/bukkit/entity/EntityType.java +++ b/src/main/java/org/bukkit/entity/EntityType.java -@@ -441,6 +441,25 @@ public enum EntityType implements Keyed, Translatable, net.kyori.adventure.trans +@@ -484,6 +484,25 @@ public enum EntityType implements Keyed, Translatable, net.kyori.adventure.trans Preconditions.checkArgument(this != UNKNOWN, "UNKNOWN entities do not have translation keys"); return org.bukkit.Bukkit.getUnsafe().getTranslationKey(this); } diff --git a/patches/api/0309-Add-hasCollision-methods-to-various-places.patch b/patches/api/0309-Add-hasCollision-methods-to-various-places.patch index 59e7c03a1f8d..d9455d45a633 100644 --- a/patches/api/0309-Add-hasCollision-methods-to-various-places.patch +++ b/patches/api/0309-Add-hasCollision-methods-to-various-places.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add hasCollision methods to various places diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java -index eec1e53ce607d36a2e72f16a4a351869fd2f609f..23fff8ee71b99aab8e650f3916511b7f34b5eb4e 100644 +index 3b344a49c26e9f4b3a7ae54ecb90da7c08d0ad49..615eb24ffdd8f6d55ccd4f21760b809c1098bc68 100644 --- a/src/main/java/org/bukkit/Material.java +++ b/src/main/java/org/bukkit/Material.java -@@ -4741,6 +4741,21 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla +@@ -4906,6 +4906,21 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla } // Paper end - item default attributes API @@ -67,10 +67,10 @@ index f4a739d8022d19a7ae0ee9bf93eb5c4846b4bd40..94e1278340c0d9d2be9edc68f6454143 + // Paper end } diff --git a/src/main/java/org/bukkit/block/BlockType.java b/src/main/java/org/bukkit/block/BlockType.java -index 5bfa98695265cdfd246411f93ab670d2c9e64ef1..a58ef2238208fbb55341f4532eaa288577ed8c0e 100644 +index aebd34785bb2070389ad2e2803fa9ff803b318c5..c080c2a3323d19cb3d549aa0fe6c164666d7da75 100644 --- a/src/main/java/org/bukkit/block/BlockType.java +++ b/src/main/java/org/bukkit/block/BlockType.java -@@ -3511,4 +3511,13 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran +@@ -3650,4 +3650,13 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran @Override @NotNull String getTranslationKey(); // Paper end - add Translatable diff --git a/patches/api/0325-Multi-Block-Change-API.patch b/patches/api/0325-Multi-Block-Change-API.patch index 9d93df870696..a53a8e108b34 100644 --- a/patches/api/0325-Multi-Block-Change-API.patch +++ b/patches/api/0325-Multi-Block-Change-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Multi Block Change API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 7f854d545a76a6e4dd2439f9a6e193fa54d5874d..48b3154ee164b9de74433556d8727e8b818ffbe5 100644 +index b39e8c1cdeee3d554839a055ccbae725aa3d66f5..d61adb687aedb987e33d66978ef4b77ea1b0356f 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -937,6 +937,29 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -952,6 +952,29 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public void sendBlockDamage(@NotNull Location loc, float progress); diff --git a/patches/api/0328-Dolphin-API.patch b/patches/api/0328-Dolphin-API.patch index 73beed437bbb..8c3706b8706c 100644 --- a/patches/api/0328-Dolphin-API.patch +++ b/patches/api/0328-Dolphin-API.patch @@ -5,16 +5,16 @@ Subject: [PATCH] Dolphin API diff --git a/src/main/java/org/bukkit/entity/Dolphin.java b/src/main/java/org/bukkit/entity/Dolphin.java -index f00eaadcdde7ceef95def2d8ec6eb63a76c177bd..8ab329946daaff25646f3dd4582feb9e4c0685ca 100644 +index fcf09afd38277180aa299703000e46dd2482c372..d3d3f8b20769eec65a81d9a59195625cb2be8579 100644 --- a/src/main/java/org/bukkit/entity/Dolphin.java +++ b/src/main/java/org/bukkit/entity/Dolphin.java @@ -1,3 +1,52 @@ package org.bukkit.entity; --public interface Dolphin extends WaterMob { } +-public interface Dolphin extends Ageable, WaterMob { } +import org.bukkit.Location; + -+public interface Dolphin extends WaterMob { // Paper start - Dolphin API ++public interface Dolphin extends Ageable, WaterMob { // Paper start - Dolphin API + + /** + * Gets the moistness level of this dolphin diff --git a/patches/api/0330-API-for-creating-command-sender-which-forwards-feedb.patch b/patches/api/0330-API-for-creating-command-sender-which-forwards-feedb.patch index 38c276ea9d13..2fdc723ece43 100644 --- a/patches/api/0330-API-for-creating-command-sender-which-forwards-feedb.patch +++ b/patches/api/0330-API-for-creating-command-sender-which-forwards-feedb.patch @@ -5,7 +5,7 @@ Subject: [PATCH] API for creating command sender which forwards feedback diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 8a22c242a93b0e16e0bca583d0918bab695248b1..aa1795b9640a5e39cc5063dd3c389f6d5815ed36 100644 +index be68351555bde59a4e55bf1bad261e9f6bc9f704..e2d3e42b403dce454988c3ae3e44bcd89337b1cf 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java @@ -1595,6 +1595,20 @@ public final class Bukkit { @@ -30,7 +30,7 @@ index 8a22c242a93b0e16e0bca583d0918bab695248b1..aa1795b9640a5e39cc5063dd3c389f6d * Gets the folder that contains all of the various {@link World}s. * diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 67b5cb7635c4251c259b1fb1ef50f99a0b2647e5..65060c06c1e5521656bd88547b8d0df5975c1d29 100644 +index 45693e6c02eac37eb609cd3c59253a949a6ca4c0..5dd7ce5c008c852dbeb0474a70e9357230406318 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -1349,6 +1349,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi diff --git a/patches/api/0331-Implement-regenerateChunk.patch b/patches/api/0331-Implement-regenerateChunk.patch index 480af4b7470a..4146857008a0 100644 --- a/patches/api/0331-Implement-regenerateChunk.patch +++ b/patches/api/0331-Implement-regenerateChunk.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Implement regenerateChunk diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index 637480c622bdb170456baabe71d84e446ebd7b13..8e9ab00503167799c6c929d00e48c07cb328848c 100644 +index 90270582b75705e42b4690cadb6d15de3188d98f..2720f290a632dd32fd9e70a40e73db9d1d161e94 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -405,8 +405,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient diff --git a/patches/api/0332-Add-GameEvent-tags.patch b/patches/api/0332-Add-GameEvent-tags.patch index 8af580d84b28..d976b18139b9 100644 --- a/patches/api/0332-Add-GameEvent-tags.patch +++ b/patches/api/0332-Add-GameEvent-tags.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add GameEvent tags diff --git a/src/main/java/org/bukkit/Tag.java b/src/main/java/org/bukkit/Tag.java -index b587897a26e9464b61a29e7482c60d2a66469571..8bfec649f7c6dda956bc388a21b489f3565ff384 100644 +index 0eca6dc6bcd9bbcad0a98a5956091bec362f2db6..42f0501ae6a2d9297bdd9bb9ab2fbb02abb881f5 100644 --- a/src/main/java/org/bukkit/Tag.java +++ b/src/main/java/org/bukkit/Tag.java -@@ -1315,6 +1315,25 @@ public interface Tag extends Keyed { +@@ -1411,6 +1411,25 @@ public interface Tag extends Keyed { */ Tag ENTITY_TYPES_REDIRECTABLE_PROJECTILE = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("redirectable_projectile"), EntityType.class); diff --git a/patches/api/0340-Add-enchantWithLevels-API.patch b/patches/api/0340-Add-enchantWithLevels-API.patch index 878b0c7df50b..093eaf700c0d 100644 --- a/patches/api/0340-Add-enchantWithLevels-API.patch +++ b/patches/api/0340-Add-enchantWithLevels-API.patch @@ -70,7 +70,7 @@ index 96546712f788e091749a1b4eebc6b1d6c3db7814..bd0e55562f1cabef3078573182e0cf9f + // Paper end - enchantWithLevels API } diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 7789c57ee27dc0e95764a6a5830de4cba210aa3b..ab74890e9b6a13b76756f884d6d176bb45470191 100644 +index 1d1731776af5f59cd9e6bd07cb3b9fab5073ef66..9b2a62dc3da6718a3e8b39b4fb8bee3781e800cb 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -678,6 +678,24 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat diff --git a/patches/api/0349-Add-method-isTickingWorlds-to-Bukkit.patch b/patches/api/0349-Add-method-isTickingWorlds-to-Bukkit.patch index b0d1284d7c4a..e41abd2d6008 100644 --- a/patches/api/0349-Add-method-isTickingWorlds-to-Bukkit.patch +++ b/patches/api/0349-Add-method-isTickingWorlds-to-Bukkit.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add method isTickingWorlds() to Bukkit. diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 702e622a2ef2c3dcb0e582e38b3b10f9c939ed97..3a8be5316229f372b471549a00eae958543ac91d 100644 +index 22021582b2f490ea2db87f2d3fe8a99b44d4f457..adc95cd1486791787950533ef8e4baaf5d3827cc 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java @@ -809,12 +809,26 @@ public final class Bukkit { @@ -56,7 +56,7 @@ index 702e622a2ef2c3dcb0e582e38b3b10f9c939ed97..3a8be5316229f372b471549a00eae958 * @param world the world to unload * @param save whether to save the chunks before unloading diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 28e883ffb5c4db22613035899be4a627c230fbf4..547ba309beb6a4d1fdfadb234d671c1475abaae5 100644 +index 178e91f3ad918c1a5600d6e9a14a21d478f7e1df..0648130a6ce2e08d96b05fde1cfd58c2bb24ae07 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -679,34 +679,55 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi diff --git a/patches/api/0352-Add-Player-getFishHook.patch b/patches/api/0352-Add-Player-getFishHook.patch index 0e0d38d513b4..340b5b119eaa 100644 --- a/patches/api/0352-Add-Player-getFishHook.patch +++ b/patches/api/0352-Add-Player-getFishHook.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Player#getFishHook diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java -index b1b18886fc63a4854c2858ff9869da70e92dae26..773651350c17cae9058346a590eda758071b7447 100644 +index 36b48bfff60ecc3d49f9f6575a91dd6b73ecf1ab..488604ba1a516b477693877c74712e4a45624a8b 100644 --- a/src/main/java/org/bukkit/entity/HumanEntity.java +++ b/src/main/java/org/bukkit/entity/HumanEntity.java -@@ -394,6 +394,13 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder +@@ -425,6 +425,13 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder @Nullable public Location getPotentialBedLocation(); // Paper end diff --git a/patches/api/0353-More-Teleport-API.patch b/patches/api/0353-More-Teleport-API.patch index a464ab538828..48ac16d6f37b 100644 --- a/patches/api/0353-More-Teleport-API.patch +++ b/patches/api/0353-More-Teleport-API.patch @@ -158,10 +158,10 @@ index f51f3f04ba9efe15f68620c5531b502710078b6e..8bada7f7f0200103edc415ad003132d9 * Teleports this entity to the given location. If this entity is riding a * vehicle, it will be dismounted prior to teleportation. diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 48b3154ee164b9de74433556d8727e8b818ffbe5..fc6a7fcb7a3f1c92f725715eaea55500d6f553c1 100644 +index d61adb687aedb987e33d66978ef4b77ea1b0356f..503a2ecd4ffca92ee529e3e15136c368d75692c0 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3521,6 +3521,45 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3536,6 +3536,45 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM String getClientBrandName(); // Paper end diff --git a/patches/api/0355-Custom-Chat-Completion-Suggestions-API.patch b/patches/api/0355-Custom-Chat-Completion-Suggestions-API.patch index 83811edce408..d36522af5422 100644 --- a/patches/api/0355-Custom-Chat-Completion-Suggestions-API.patch +++ b/patches/api/0355-Custom-Chat-Completion-Suggestions-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Custom Chat Completion Suggestions API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index fc6a7fcb7a3f1c92f725715eaea55500d6f553c1..9e1785692bea39cda723094eba3985c6655ad267 100644 +index 503a2ecd4ffca92ee529e3e15136c368d75692c0..675053adf68df2c77ef128f2aec72e22f0f48adf 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3405,6 +3405,31 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3420,6 +3420,31 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM void sendOpLevel(byte level); // Paper end - sendOpLevel API diff --git a/patches/api/0364-Elder-Guardian-appearance-API.patch b/patches/api/0364-Elder-Guardian-appearance-API.patch index 4c5b51b7a5c9..8a3655450e14 100644 --- a/patches/api/0364-Elder-Guardian-appearance-API.patch +++ b/patches/api/0364-Elder-Guardian-appearance-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Elder Guardian appearance API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 9e1785692bea39cda723094eba3985c6655ad267..6546bcbcced9468008212e9cf96a06c50c14a93f 100644 +index 675053adf68df2c77ef128f2aec72e22f0f48adf..9c9077c781b8f11d3a41d479ff9415fe83c70e81 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3585,6 +3585,24 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3600,6 +3600,24 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM void lookAt(@NotNull org.bukkit.entity.Entity entity, @NotNull io.papermc.paper.entity.LookAnchor playerAnchor, @NotNull io.papermc.paper.entity.LookAnchor entityAnchor); // Paper end - Teleport API diff --git a/patches/api/0371-Add-Player-Warden-Warning-API.patch b/patches/api/0371-Add-Player-Warden-Warning-API.patch index d1728e94925d..e766dc65f7f6 100644 --- a/patches/api/0371-Add-Player-Warden-Warning-API.patch +++ b/patches/api/0371-Add-Player-Warden-Warning-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Player Warden Warning API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 6546bcbcced9468008212e9cf96a06c50c14a93f..edf4b93624e5c308be9bf0498187404c13525e09 100644 +index 9c9077c781b8f11d3a41d479ff9415fe83c70e81..41a01924b4ffda5e321338ef9831c12ba5ee751a 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3601,6 +3601,59 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3616,6 +3616,59 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param silent whether sound should be silenced */ void showElderGuardian(boolean silent); diff --git a/patches/api/0372-More-vanilla-friendly-methods-to-update-trades.patch b/patches/api/0372-More-vanilla-friendly-methods-to-update-trades.patch index dcad21ff699c..b56f34f9d14d 100644 --- a/patches/api/0372-More-vanilla-friendly-methods-to-update-trades.patch +++ b/patches/api/0372-More-vanilla-friendly-methods-to-update-trades.patch @@ -5,7 +5,7 @@ Subject: [PATCH] More vanilla friendly methods to update trades diff --git a/src/main/java/org/bukkit/entity/Villager.java b/src/main/java/org/bukkit/entity/Villager.java -index 0759f66986cec2c7e3f765aaa5b1654b5ed9f4b5..444744ea6f5921b0ae229995f8b15ea9d980c402 100644 +index 163f1afde2e04fdf4dddb894da62b301b52ed539..bc7137eb802d4613d042fba5fd97eca54a6eea29 100644 --- a/src/main/java/org/bukkit/entity/Villager.java +++ b/src/main/java/org/bukkit/entity/Villager.java @@ -64,8 +64,11 @@ public interface Villager extends AbstractVillager { diff --git a/patches/api/0374-ItemStack-damage-API.patch b/patches/api/0374-ItemStack-damage-API.patch index b3bc59b4df09..e48a903a6547 100644 --- a/patches/api/0374-ItemStack-damage-API.patch +++ b/patches/api/0374-ItemStack-damage-API.patch @@ -66,7 +66,7 @@ index 86c5ceddc722d28261f8a6d8368400fe2731aaf0..9f3e2903c955f2a5d1b25825c49188df + // Paper end - ItemStack damage API } diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index a20f3a0894b700c235da1b8e1481062014054585..5c02a5fe37ea09502ca6c93d637a8ef5e4392ad4 100644 +index 9b2a62dc3da6718a3e8b39b4fb8bee3781e800cb..e39c9167bd66c528c09b256f15cc6c58666f0ca0 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -1090,5 +1090,19 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat diff --git a/patches/api/0381-Add-Sneaking-API-for-Entities.patch b/patches/api/0381-Add-Sneaking-API-for-Entities.patch index 5419ce7d3c5a..29e6c9875000 100644 --- a/patches/api/0381-Add-Sneaking-API-for-Entities.patch +++ b/patches/api/0381-Add-Sneaking-API-for-Entities.patch @@ -35,10 +35,10 @@ index 9f4498a955279b8b5c418609801fd09444a1efb5..6dcaf7e9bc9afb708ab569e82f27c878 * Get the category of spawn to which this entity belongs. * diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index edf4b93624e5c308be9bf0498187404c13525e09..9dbcbefe989c6f4ab00a2ba90fa5cdb29dc74797 100644 +index 41a01924b4ffda5e321338ef9831c12ba5ee751a..fb72464d86de30775e6c324bfd6a9491cc2bee2b 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -459,6 +459,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -474,6 +474,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @return true if player is in sneak mode */ @@ -46,7 +46,7 @@ index edf4b93624e5c308be9bf0498187404c13525e09..9dbcbefe989c6f4ab00a2ba90fa5cdb2 public boolean isSneaking(); /** -@@ -466,6 +467,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -481,6 +482,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param sneak true if player should appear sneaking */ diff --git a/patches/api/0383-Flying-Fall-Damage-API.patch b/patches/api/0383-Flying-Fall-Damage-API.patch index 13493c2aa922..c3b86a21d23a 100644 --- a/patches/api/0383-Flying-Fall-Damage-API.patch +++ b/patches/api/0383-Flying-Fall-Damage-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Flying Fall Damage API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 9dbcbefe989c6f4ab00a2ba90fa5cdb29dc74797..32484ae22a7398bd4df94c185e7c1b4cb1d0f76c 100644 +index fb72464d86de30775e6c324bfd6a9491cc2bee2b..d1301c8201c56602fbedcf5475650c5b7e600609 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1908,6 +1908,23 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1923,6 +1923,23 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public void setAllowFlight(boolean flight); diff --git a/patches/api/0385-Win-Screen-API.patch b/patches/api/0385-Win-Screen-API.patch index cdeea2f4f9d4..c4ac3dae99b6 100644 --- a/patches/api/0385-Win-Screen-API.patch +++ b/patches/api/0385-Win-Screen-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Win Screen API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 32484ae22a7398bd4df94c185e7c1b4cb1d0f76c..c86d8b88a1501bd8fd7562a21ee111607e523962 100644 +index d1301c8201c56602fbedcf5475650c5b7e600609..ee43ecd0bf4d12549323976a0e1c3b023a41333b 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1247,6 +1247,47 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1262,6 +1262,47 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public void sendMap(@NotNull MapView map); diff --git a/patches/api/0398-Fix-BanList-API.patch b/patches/api/0398-Fix-BanList-API.patch index a9640f44a249..a5c5275a12e3 100644 --- a/patches/api/0398-Fix-BanList-API.patch +++ b/patches/api/0398-Fix-BanList-API.patch @@ -130,10 +130,10 @@ index e805e629cede1c4c0674282c930cb67852718c3e..5248cf08ef83c7304dd76c42a2f646bb + // Paper end } diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index c86d8b88a1501bd8fd7562a21ee111607e523962..fbaea481feccfc71d744d9f93de3bf637fdcaaad 100644 +index ee43ecd0bf4d12549323976a0e1c3b023a41333b..6103c945b351a9cf6a29b5ab4fa7adb4546097e2 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -343,7 +343,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -358,7 +358,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * (updated) previous ban */ @Nullable @@ -142,7 +142,7 @@ index c86d8b88a1501bd8fd7562a21ee111607e523962..fbaea481feccfc71d744d9f93de3bf63 /** * Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will -@@ -359,7 +359,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -374,7 +374,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * (updated) previous ban */ @Nullable @@ -151,7 +151,7 @@ index c86d8b88a1501bd8fd7562a21ee111607e523962..fbaea481feccfc71d744d9f93de3bf63 /** * Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will -@@ -375,7 +375,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -390,7 +390,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * (updated) previous ban */ @Nullable diff --git a/patches/api/0406-Add-Listing-API-for-Player.patch b/patches/api/0406-Add-Listing-API-for-Player.patch index 47a8946b80ba..acf4f19c19da 100644 --- a/patches/api/0406-Add-Listing-API-for-Player.patch +++ b/patches/api/0406-Add-Listing-API-for-Player.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Listing API for Player diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index fbaea481feccfc71d744d9f93de3bf637fdcaaad..24dc710f61d08253f66e7ecfd69873e7ebf68d1b 100644 +index 6103c945b351a9cf6a29b5ab4fa7adb4546097e2..38e296eab48b5408255fdb13d6a7b488471395d2 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -2038,6 +2038,32 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2053,6 +2053,32 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public boolean canSee(@NotNull Entity entity); diff --git a/patches/api/0408-Fix-NPE-on-Boat-getStatus.patch b/patches/api/0408-Fix-NPE-on-Boat-getStatus.patch index 1cf6096a92f8..985aab9f2b60 100644 --- a/patches/api/0408-Fix-NPE-on-Boat-getStatus.patch +++ b/patches/api/0408-Fix-NPE-on-Boat-getStatus.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix NPE on Boat getStatus diff --git a/src/main/java/org/bukkit/entity/Boat.java b/src/main/java/org/bukkit/entity/Boat.java -index f7548098bcdd033d9c530fdc584fc5538c635ca1..2ac685fb1817f3ce06ebe6391cc863712d68367c 100644 +index a0fb3c44405f6362f8a1613661d507e448f7ba6b..7076870c1abfa0edef33e00c39514aa413920f59 100644 --- a/src/main/java/org/bukkit/entity/Boat.java +++ b/src/main/java/org/bukkit/entity/Boat.java -@@ -169,6 +169,7 @@ public interface Boat extends Vehicle { +@@ -175,6 +175,7 @@ public interface Boat extends Vehicle { */ public enum Status { diff --git a/patches/api/0418-Allow-proper-checking-of-empty-item-stacks.patch b/patches/api/0418-Allow-proper-checking-of-empty-item-stacks.patch index ae89ab9bc017..0fe58e036986 100644 --- a/patches/api/0418-Allow-proper-checking-of-empty-item-stacks.patch +++ b/patches/api/0418-Allow-proper-checking-of-empty-item-stacks.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Allow proper checking of empty item stacks This adds a method to check if an item stack is empty or not. This mirrors vanilla's implementation of the same method. diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 5c02a5fe37ea09502ca6c93d637a8ef5e4392ad4..8ded653f2b0549ebbe1a84d50ff0f3c85ddd07b7 100644 +index e39c9167bd66c528c09b256f15cc6c58666f0ca0..773780811a24aa1c1591257a993e30f2d99da436 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -1104,5 +1104,24 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat diff --git a/patches/api/0420-Add-player-idle-duration-API.patch b/patches/api/0420-Add-player-idle-duration-API.patch index 2fbfc5dc581c..b11b57b66070 100644 --- a/patches/api/0420-Add-player-idle-duration-API.patch +++ b/patches/api/0420-Add-player-idle-duration-API.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add player idle duration API Implements API for getting and resetting a player's idle duration. diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 24dc710f61d08253f66e7ecfd69873e7ebf68d1b..09094f55509eaf66670c27409b4d5ec3d73412b0 100644 +index 38e296eab48b5408255fdb13d6a7b488471395d2..598a1df25f12e2175865bf98dae030b33f78cf7c 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3742,6 +3742,29 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3757,6 +3757,29 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM void increaseWardenWarningLevel(); // Paper end diff --git a/patches/api/0422-Add-predicate-for-blocks-when-raytracing.patch b/patches/api/0422-Add-predicate-for-blocks-when-raytracing.patch index 13d64df888b1..e24c9fcedf96 100644 --- a/patches/api/0422-Add-predicate-for-blocks-when-raytracing.patch +++ b/patches/api/0422-Add-predicate-for-blocks-when-raytracing.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add predicate for blocks when raytracing diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index 907906e15c9250fea385e49f10d3c248236fd004..02184b68cc126b278985fd966e3c8e4ade18c464 100644 +index f037f46a9c6ce894f24af14c20fb514a58a8aee9..86fd5f3d322b6203f02ca7c427ccd56336b93fc0 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -1649,6 +1649,27 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient diff --git a/patches/api/0426-Remove-unnecessary-durability-check-in-ItemStack-isS.patch b/patches/api/0426-Remove-unnecessary-durability-check-in-ItemStack-isS.patch index bdb434071da5..88ecd35099b5 100644 --- a/patches/api/0426-Remove-unnecessary-durability-check-in-ItemStack-isS.patch +++ b/patches/api/0426-Remove-unnecessary-durability-check-in-ItemStack-isS.patch @@ -9,7 +9,7 @@ By removing this check we avoid unnecessarily allocating useless `ItemMeta` obje This is a leftover from when checking for the item's durability was "free" because the durability was stored in the `ItemStack` itself, this [was changed in Minecraft 1.13](https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/commits/f8b2086d60942eb2cd7ac25a2a1408cb790c222c#src/main/java/org/bukkit/inventory/ItemStack.java). diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 5b918d510b9c8a6f8c6d146e90e1d0ef4a204b5a..13d035ace9fbe93c3754595ac6cadbfbe30062a5 100644 +index 773780811a24aa1c1591257a993e30f2d99da436..e6c69a54e0c1dc511fe5769f869dcecb13e04ed3 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -307,7 +307,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat diff --git a/patches/api/0427-Add-Structure-check-API.patch b/patches/api/0427-Add-Structure-check-API.patch index e2d19afb3258..43073fe8f413 100644 --- a/patches/api/0427-Add-Structure-check-API.patch +++ b/patches/api/0427-Add-Structure-check-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add Structure check API diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index 02184b68cc126b278985fd966e3c8e4ade18c464..ecc2d486cfec79cce27a947dfeed4853575a594d 100644 +index 86fd5f3d322b6203f02ca7c427ccd56336b93fc0..16570c3c7ed5e7ad25f20c1034f7b966d6e694da 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -78,6 +78,30 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient diff --git a/patches/api/0428-Experimental-annotations-change.patch b/patches/api/0428-Experimental-annotations-change.patch index 010af408d2d1..2bf2c2cd371d 100644 --- a/patches/api/0428-Experimental-annotations-change.patch +++ b/patches/api/0428-Experimental-annotations-change.patch @@ -5,43 +5,49 @@ Subject: [PATCH] Experimental annotations change diff --git a/src/main/java/org/bukkit/FeatureFlag.java b/src/main/java/org/bukkit/FeatureFlag.java -index 7522c611b5214dd09867c434d5f7cf161f5c04ca..026b1832bcd163ab89668c991bf002e608e36aef 100644 +index 710f8e6242eab7b638e4f42e4e9790007f4c67b7..82f9ba32256bfc1125ee970a7fed0895fe08f145 100644 --- a/src/main/java/org/bukkit/FeatureFlag.java +++ b/src/main/java/org/bukkit/FeatureFlag.java -@@ -13,6 +13,7 @@ public interface FeatureFlag extends Keyed { - - public static final FeatureFlag VANILLA = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("vanilla")); +@@ -29,6 +29,7 @@ public interface FeatureFlag extends Keyed { + @Deprecated + public static final FeatureFlag UPDATE_1_20 = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("update_1_20")); + @ApiStatus.Experimental // Paper - add missing annotation - public static final FeatureFlag BUNDLE = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("bundle")); + public static final FeatureFlag TRADE_REBALANCE = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("trade_rebalance")); /** -@@ -23,6 +24,7 @@ public interface FeatureFlag extends Keyed { +@@ -39,10 +40,13 @@ public interface FeatureFlag extends Keyed { @Deprecated - public static final FeatureFlag UPDATE_1_20 = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("update_1_20")); + public static final FeatureFlag UPDATE_121 = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("update_1_21")); + @ApiStatus.Experimental // Paper - add missing annotation - public static final FeatureFlag TRADE_REBALANCE = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("trade_rebalance")); + public static final FeatureFlag WINTER_DROP = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("winter_drop")); - /** ++ @ApiStatus.Experimental // Paper - add missing annotation + public static final FeatureFlag REDSTONE_EXPERIMENTS = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("redstone_experiments")); + ++ @ApiStatus.Experimental // Paper - add missing annotation + public static final FeatureFlag MINECART_IMPROVEMENTS = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("minecart_improvements")); + + } diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java -index 23fff8ee71b99aab8e650f3916511b7f34b5eb4e..77a15a99e441bd81650806142581bd5b24f30e10 100644 +index 615eb24ffdd8f6d55ccd4f21760b809c1098bc68..f4ccb19107464e92744fbf66d55bf81fd50dfcc3 100644 --- a/src/main/java/org/bukkit/Material.java +++ b/src/main/java/org/bukkit/Material.java -@@ -2501,6 +2501,8 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla +@@ -2631,6 +2631,8 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla EGG(21603, 16), COMPASS(24139), RECOVERY_COMPASS(12710), + @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation + @ApiStatus.Experimental // Paper - add missing annotation BUNDLE(16835, 1), - FISHING_ROD(4167, 1, 64), - CLOCK(14980), + WHITE_BUNDLE(12072, 1), + ORANGE_BUNDLE(18288, 1), diff --git a/src/main/java/org/bukkit/Sound.java b/src/main/java/org/bukkit/Sound.java -index b2ff1da3386223a544ab5fc363a90c66c8869242..8c7b50906fc5b84c5570408f357410810bbfbded 100644 +index cf17af024b1953b6f21f18885411ea6a0baa1d4c..544d5bf9fafe91e81314c75114a8a3516808db1d 100644 --- a/src/main/java/org/bukkit/Sound.java +++ b/src/main/java/org/bukkit/Sound.java -@@ -1506,8 +1506,14 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa +@@ -1530,9 +1530,18 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa ITEM_BUCKET_FILL_LAVA("item.bucket.fill_lava"), ITEM_BUCKET_FILL_POWDER_SNOW("item.bucket.fill_powder_snow"), ITEM_BUCKET_FILL_TADPOLE("item.bucket.fill_tadpole"), @@ -51,8 +57,12 @@ index b2ff1da3386223a544ab5fc363a90c66c8869242..8c7b50906fc5b84c5570408f35741081 + @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation + @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation ITEM_BUNDLE_INSERT("item.bundle.insert"), ++<<<<<<< HEAD + ITEM_BUNDLE_INSERT_FAIL("item.bundle.insert_fail"), ++======= + @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation + @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation ++>>>>>>> Experimental annotations change ITEM_BUNDLE_REMOVE_ONE("item.bundle.remove_one"), ITEM_CHORUS_FRUIT_TELEPORT("item.chorus_fruit.teleport"), ITEM_CROP_PLANT("item.crop.plant"), diff --git a/patches/api/0430-Improve-Registry.patch b/patches/api/0430-Improve-Registry.patch index 453d8c9488b4..22a37762fcfb 100644 --- a/patches/api/0430-Improve-Registry.patch +++ b/patches/api/0430-Improve-Registry.patch @@ -146,10 +146,10 @@ index 6112db5d1153d045f2271038bada6b46d1a6a051..67cf3fcad21a8977d6fad172cc776b62 } } diff --git a/src/main/java/org/bukkit/Sound.java b/src/main/java/org/bukkit/Sound.java -index 8c7b50906fc5b84c5570408f357410810bbfbded..7a35120c82b88774de777d3c3176ef553a8e9244 100644 +index 544d5bf9fafe91e81314c75114a8a3516808db1d..a52c8a0bd030265567b7c1aa80b04eced37fcbbf 100644 --- a/src/main/java/org/bukkit/Sound.java +++ b/src/main/java/org/bukkit/Sound.java -@@ -1636,6 +1636,13 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa +@@ -1664,6 +1664,13 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa this.key = NamespacedKey.minecraft(key); } diff --git a/patches/api/0431-Add-experience-points-API.patch b/patches/api/0431-Add-experience-points-API.patch index 9b489a9ded02..568b3a2494c7 100644 --- a/patches/api/0431-Add-experience-points-API.patch +++ b/patches/api/0431-Add-experience-points-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add experience points API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 09094f55509eaf66670c27409b4d5ec3d73412b0..4bc4a1c0c6f6759f984843823f1bbec6ffed92bc 100644 +index 598a1df25f12e2175865bf98dae030b33f78cf7c..f7b9cf1f2b90feb954e4d9b03b3a12abe7864a12 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1907,6 +1907,45 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1922,6 +1922,45 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param exp New total experience points */ public void setTotalExperience(int exp); diff --git a/patches/api/0452-Deprecate-ItemStack-setType.patch b/patches/api/0452-Deprecate-ItemStack-setType.patch index cdb918bc110d..84fbcf3899ba 100644 --- a/patches/api/0452-Deprecate-ItemStack-setType.patch +++ b/patches/api/0452-Deprecate-ItemStack-setType.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Deprecate ItemStack#setType diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 718070359c644de65c8fc2b34ad39913525d18c6..5b261bcffa7d04c9e7db57fee37d4a1471cbbd64 100644 +index 49390979cc0c68b8e719f2a2ce9e7d193c747959..82a66820311cfd918ea322f57df97e3a56e79c1d 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -143,8 +143,18 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat diff --git a/patches/api/0454-API-for-checking-sent-chunks.patch b/patches/api/0454-API-for-checking-sent-chunks.patch index a3844b54010e..bca113f6abfa 100644 --- a/patches/api/0454-API-for-checking-sent-chunks.patch +++ b/patches/api/0454-API-for-checking-sent-chunks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] API for checking sent chunks diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 4bc4a1c0c6f6759f984843823f1bbec6ffed92bc..7b699c1e63cf5bc805754101f28066f836877ee2 100644 +index f7b9cf1f2b90feb954e4d9b03b3a12abe7864a12..fc16c3df002ca097d9f815c04687e115c911304f 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3804,6 +3804,47 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3819,6 +3819,47 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM void resetIdleDuration(); // Paper end diff --git a/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch b/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch index 0a16b34cd5e0..c860be02a467 100644 --- a/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch +++ b/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch @@ -4,11 +4,30 @@ Date: Fri, 26 Apr 2024 17:00:00 -0700 Subject: [PATCH] Fix SpawnerEntry$Equipment API +diff --git a/src/main/java/org/bukkit/Sound.java b/src/main/java/org/bukkit/Sound.java +index a52c8a0bd030265567b7c1aa80b04eced37fcbbf..c866613ee1fb47daf89179dd30d74489c90be96d 100644 +--- a/src/main/java/org/bukkit/Sound.java ++++ b/src/main/java/org/bukkit/Sound.java +@@ -1536,12 +1536,11 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa + @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation + @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation + ITEM_BUNDLE_INSERT("item.bundle.insert"), +-<<<<<<< HEAD ++ @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation ++ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation + ITEM_BUNDLE_INSERT_FAIL("item.bundle.insert_fail"), +-======= + @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation + @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation +->>>>>>> Experimental annotations change + ITEM_BUNDLE_REMOVE_ONE("item.bundle.remove_one"), + ITEM_CHORUS_FRUIT_TELEPORT("item.chorus_fruit.teleport"), + ITEM_CROP_PLANT("item.crop.plant"), diff --git a/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java b/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java -index 02b3471774ff1fd4ad15c2f04064fd485ef8f3e5..0fc5f04b8bb475e8afce61c6187a390cd36c3d9f 100644 +index fc1c0435dfea121923eb1fe0182880752f321143..4f00ebb78f7549aed0a250f494222b97b830d0f3 100644 --- a/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java +++ b/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java -@@ -121,28 +121,29 @@ public class SpawnerEntry { +@@ -120,27 +120,33 @@ public class SpawnerEntry { private final Map dropChances; public Equipment(@NotNull LootTable equipmentLootTable, @NotNull Map dropChances) { @@ -21,9 +40,11 @@ index 02b3471774ff1fd4ad15c2f04064fd485ef8f3e5..0fc5f04b8bb475e8afce61c6187a390c - * Set the loot table for the entity. + * Set the loot table for the spawned entity's equipment slots. *
    -- * To remove a loot table use null. Do not use {@link LootTables#EMPTY} -- * to clear a LootTable. ++<<<<<<< HEAD + * To remove a loot table use null. ++======= + * To remove a loot table use {@link LootTables#EMPTY}. ++>>>>>>> Fix SpawnerEntry$Equipment API * * @param table this {@link org.bukkit.entity.Mob} will have. */ diff --git a/patches/api/0458-Fix-ItemFlags.patch b/patches/api/0458-Fix-ItemFlags.patch index a6301eff75c6..3ca141cfa509 100644 --- a/patches/api/0458-Fix-ItemFlags.patch +++ b/patches/api/0458-Fix-ItemFlags.patch @@ -47,7 +47,7 @@ index 5b8dac777bb1640dc00bbe98feb6460c36eebb98..1af15fd327e0613cd1a179bd7fef1e83 /** * Setting to show/hide item-specific information, including, but not limited to: diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 5b261bcffa7d04c9e7db57fee37d4a1471cbbd64..1d2ffdf88daa9186993c69c5ab2b96520b41920b 100644 +index 82a66820311cfd918ea322f57df97e3a56e79c1d..77edc2e1c5c865db7e101aaa186657ac85edfed9 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -588,6 +588,13 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat diff --git a/patches/api/0463-Added-API-to-get-player-ha-proxy-address.patch b/patches/api/0463-Added-API-to-get-player-ha-proxy-address.patch index b1702bee61c4..08d7bec7038a 100644 --- a/patches/api/0463-Added-API-to-get-player-ha-proxy-address.patch +++ b/patches/api/0463-Added-API-to-get-player-ha-proxy-address.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Added API to get player ha proxy address diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 7b699c1e63cf5bc805754101f28066f836877ee2..7c56182acaf827f4b1a986a61cea8e9960604c98 100644 +index fc16c3df002ca097d9f815c04687e115c911304f..c8532a25d64217bcfddf075fd09e255aa9a769e7 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -251,6 +251,16 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -266,6 +266,16 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM @Nullable public InetSocketAddress getAddress(); diff --git a/patches/api/0465-Brigadier-based-command-API.patch b/patches/api/0465-Brigadier-based-command-API.patch index 88ce5b7aab3d..069f7c4c4a58 100644 --- a/patches/api/0465-Brigadier-based-command-API.patch +++ b/patches/api/0465-Brigadier-based-command-API.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Brigadier based command API Co-authored-by: Jake Potrebic diff --git a/build.gradle.kts b/build.gradle.kts -index be8492b23d10332d046150a4ff18c67cc1b0f5d2..6c1cba3e87d2e3cb3eec65345ed7dcc56fd96363 100644 +index 6c8464d9e862b1b4dbf7a77e25446aa870803dae..e7c96be769fde8375b9a1b128cc7ce474144d16d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -27,6 +27,7 @@ configurations.api { diff --git a/patches/api/0469-General-ItemMeta-fixes.patch b/patches/api/0469-General-ItemMeta-fixes.patch index f74fb26a3576..953fd2e49c5d 100644 --- a/patches/api/0469-General-ItemMeta-fixes.patch +++ b/patches/api/0469-General-ItemMeta-fixes.patch @@ -112,10 +112,10 @@ index ff6818b6d9e0207eafdd749928f33aeac3f27191..992f39da07bafe9769effaa7dc6adc01 * Checks to see if this item has a maximum amount of damage. * diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java -index 1a4260b00b193b94ce4b1b2954644f4e41baff4c..5d5fcb2720b62e47d47f441032c4de02574b051a 100644 +index afdcc2d67d55f2f07c913816e1f5b290d1415357..fc089b796f5a0f2e1ab081cc710e4bb5c3f5ee7b 100644 --- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java +++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java -@@ -673,8 +673,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -877,8 +877,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste /** * Set all {@link Attribute}s and their {@link AttributeModifier}s. diff --git a/patches/api/0473-Introduce-registry-entry-and-builders.patch b/patches/api/0473-Introduce-registry-entry-and-builders.patch index 2731a371af9c..5d06fe497471 100644 --- a/patches/api/0473-Introduce-registry-entry-and-builders.patch +++ b/patches/api/0473-Introduce-registry-entry-and-builders.patch @@ -487,10 +487,10 @@ index cb5f7dfcdbbb548d93ad21c215ba35a9e142a7b2..e2c632afdf555418dd1dc6ad6c5d1976 + // Paper end } diff --git a/src/main/java/org/bukkit/inventory/ItemType.java b/src/main/java/org/bukkit/inventory/ItemType.java -index c42cfa76ff73a3ce8a164cb94a9c3f553b005ea5..15d68c4997f739c39675ef8ffa5ab7967dac59f2 100644 +index 7a1a0aebbfdaac6b6af41236d4a00512244b58fa..ef3a30d5cca29c7a7c546791be3c333e63e425f4 100644 --- a/src/main/java/org/bukkit/inventory/ItemType.java +++ b/src/main/java/org/bukkit/inventory/ItemType.java -@@ -46,7 +46,7 @@ import org.jetbrains.annotations.Nullable; +@@ -47,7 +47,7 @@ import org.jetbrains.annotations.Nullable; * official replacement for the aforementioned enum. Entirely incompatible * changes may occur. Do not use this API in plugins. */ diff --git a/patches/api/0479-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch b/patches/api/0479-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch index 3dd2df1411fa..9ee5f867c6fc 100644 --- a/patches/api/0479-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch +++ b/patches/api/0479-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch @@ -228,10 +228,10 @@ index 7ff6d60deb129e23b2a4d772aee123eb6c0b6433..52a2763773b234c581b2dcc6f0584f8d return key; } diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java -index 5d5fcb2720b62e47d47f441032c4de02574b051a..f5541454ba5e508a72c83989c6feaef5406e2535 100644 +index fc089b796f5a0f2e1ab081cc710e4bb5c3f5ee7b..2a86e599175549a3021a63a837f8cc9d8da5697d 100644 --- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java +++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java -@@ -806,4 +806,98 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste +@@ -1010,4 +1010,98 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste @SuppressWarnings("javadoc") @NotNull ItemMeta clone(); diff --git a/patches/api/0482-Leashable-API.patch b/patches/api/0482-Leashable-API.patch index e37174d49956..b84951d969d6 100644 --- a/patches/api/0482-Leashable-API.patch +++ b/patches/api/0482-Leashable-API.patch @@ -48,7 +48,7 @@ index 0000000000000000000000000000000000000000..7e687535d1a622ddf25e3ece387dbfd5 + boolean setLeashHolder(@Nullable Entity holder); +} diff --git a/src/main/java/org/bukkit/entity/Boat.java b/src/main/java/org/bukkit/entity/Boat.java -index 2ac685fb1817f3ce06ebe6391cc863712d68367c..d80524fe32672a8b8940d1028abf22026dace8d2 100644 +index 7076870c1abfa0edef33e00c39514aa413920f59..574574dc4f54a4ce32e7c97f2fbeb92a4991d353 100644 --- a/src/main/java/org/bukkit/entity/Boat.java +++ b/src/main/java/org/bukkit/entity/Boat.java @@ -7,7 +7,7 @@ import org.jetbrains.annotations.NotNull; diff --git a/patches/api/0485-Add-FeatureFlag-API.patch b/patches/api/0485-Add-FeatureFlag-API.patch index ae5e00b28300..ccff2872435a 100644 --- a/patches/api/0485-Add-FeatureFlag-API.patch +++ b/patches/api/0485-Add-FeatureFlag-API.patch @@ -104,10 +104,10 @@ index 0000000000000000000000000000000000000000..0955699df65ccbb8711cfa48f0b34d5a + @Unmodifiable Set getFeatureFlags(); +} diff --git a/src/main/java/org/bukkit/FeatureFlag.java b/src/main/java/org/bukkit/FeatureFlag.java -index 026b1832bcd163ab89668c991bf002e608e36aef..b5e87480b6a1d064547e4e608f3d402825931a00 100644 +index 82f9ba32256bfc1125ee970a7fed0895fe08f145..163b73204f3c94c1a234eb86cc73bd92858bc5e4 100644 --- a/src/main/java/org/bukkit/FeatureFlag.java +++ b/src/main/java/org/bukkit/FeatureFlag.java -@@ -1,37 +1,56 @@ +@@ -1,17 +1,24 @@ package org.bukkit; +// Paper start - overhaul FeatureFlag API @@ -136,12 +136,14 @@ index 026b1832bcd163ab89668c991bf002e608e36aef..b5e87480b6a1d064547e4e608f3d4028 + */ + FeatureFlag VANILLA = create("vanilla"); -+ /** -+ * The {@code bundle} feature flag. -+ */ - @ApiStatus.Experimental // Paper - add missing annotation + /** + * AVAILABLE BETWEEN VERSIONS: 1.19.3 - 1.21.2 +@@ -19,34 +26,43 @@ public interface FeatureFlag extends Keyed { + * @deprecated not available since 1.21.2 + */ + @Deprecated - public static final FeatureFlag BUNDLE = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("bundle")); -+ FeatureFlag BUNDLE = create("bundle"); ++ FeatureFlag BUNDLE = deprecated("bundle"); /** - * AVAILABLE BETWEEN VERSIONS: 1.19 - 1.19.4 @@ -155,21 +157,35 @@ index 026b1832bcd163ab89668c991bf002e608e36aef..b5e87480b6a1d064547e4e608f3d4028 @ApiStatus.Experimental // Paper - add missing annotation - public static final FeatureFlag TRADE_REBALANCE = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("trade_rebalance")); + FeatureFlag TRADE_REBALANCE = create("trade_rebalance"); -+ + +- /** +- * AVAILABLE BETWEEN VERSIONS: 1.20.5 - 1.20.6 +- * +- * @deprecated not available since 1.21 +- */ +- @Deprecated +- public static final FeatureFlag UPDATE_121 = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("update_1_21")); + @Deprecated(since = "1.20") + FeatureFlag UPDATE_1_20 = deprecated("update_1_20"); + + @Deprecated(since = "1.21") + FeatureFlag UPDATE_121 = deprecated("update_1_21"); - /** -- * AVAILABLE BETWEEN VERSIONS: 1.20.5 - 1.20.6 -- * -- * @deprecated not available since 1.21 + @ApiStatus.Experimental // Paper - add missing annotation +- public static final FeatureFlag WINTER_DROP = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("winter_drop")); ++ FeatureFlag WINTER_DROP = create("winter_drop"); + + @ApiStatus.Experimental // Paper - add missing annotation +- public static final FeatureFlag REDSTONE_EXPERIMENTS = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("redstone_experiments")); ++ FeatureFlag REDSTONE_EXPERIMENTS = create("redstone_experiments"); + + @ApiStatus.Experimental // Paper - add missing annotation +- public static final FeatureFlag MINECART_IMPROVEMENTS = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("minecart_improvements")); ++ FeatureFlag MINECART_IMPROVEMENTS = create("minecart_improvements"); ++ ++ /** + * An index of all feature flags. - */ -- @Deprecated -- public static final FeatureFlag UPDATE_121 = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("update_1_21")); ++ */ + Index ALL_FLAGS = Index.create(FeatureFlag::key, List.copyOf(FeatureFlagImpl.ALL_FLAGS)); + + private static FeatureFlag create(@Subst("vanilla") final String name) { @@ -182,6 +198,7 @@ index 026b1832bcd163ab89668c991bf002e608e36aef..b5e87480b6a1d064547e4e608f3d4028 + return new FeatureFlagImpl.Deprecated(NamespacedKey.minecraft(name)); + } + // Paper end - overhaul FeatureFlag API + } diff --git a/src/main/java/org/bukkit/FeatureFlagImpl.java b/src/main/java/org/bukkit/FeatureFlagImpl.java new file mode 100644 @@ -244,10 +261,10 @@ index 330e3013eda204aa9b33d5e1c3104e0b595abdbc..c80e0ef587a001ee6de3f5c182cc9696 /** * Do not use, method will get removed, and the plugin won't run diff --git a/src/main/java/org/bukkit/block/BlockType.java b/src/main/java/org/bukkit/block/BlockType.java -index a58ef2238208fbb55341f4532eaa288577ed8c0e..fb2b373c1822e7248a30e610d11e2c2bd438c19a 100644 +index c080c2a3323d19cb3d549aa0fe6c164666d7da75..ed534fe4983873a2d5f623f0d9d5e3ce254615eb 100644 --- a/src/main/java/org/bukkit/block/BlockType.java +++ b/src/main/java/org/bukkit/block/BlockType.java -@@ -125,7 +125,7 @@ import org.jetbrains.annotations.Nullable; +@@ -129,7 +129,7 @@ import org.jetbrains.annotations.Nullable; * changes may occur. Do not use this API in plugins. */ @ApiStatus.Internal @@ -256,7 +273,7 @@ index a58ef2238208fbb55341f4532eaa288577ed8c0e..fb2b373c1822e7248a30e610d11e2c2b /** * Typed represents a subtype of {@link BlockType}s that have a known block -@@ -3490,7 +3490,9 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran +@@ -3629,7 +3629,9 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran * * @param world the world to check * @return true if this BlockType can be used in this World. @@ -267,10 +284,10 @@ index a58ef2238208fbb55341f4532eaa288577ed8c0e..fb2b373c1822e7248a30e610d11e2c2b /** diff --git a/src/main/java/org/bukkit/entity/EntityType.java b/src/main/java/org/bukkit/entity/EntityType.java -index ba605ad75d4ed920c0dc4527529998041a58676b..a78e1c431a6ea46ba7c44880e25a871f473bef41 100644 +index 6521a20d69a4c8e75be7e9b3fdebbc25b843ec1b..37dbd114f91a26bc09a1230d38afe7f6a99e5c28 100644 --- a/src/main/java/org/bukkit/entity/EntityType.java +++ b/src/main/java/org/bukkit/entity/EntityType.java -@@ -23,7 +23,7 @@ import org.jetbrains.annotations.Contract; +@@ -45,7 +45,7 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -293,10 +310,10 @@ index 5067f1371433cccd3287af7f03e152f2c3c1ece3..e0cb282541548ac3bd24cce86b3413f5 /** * Gets the unique name of this world diff --git a/src/main/java/org/bukkit/inventory/ItemType.java b/src/main/java/org/bukkit/inventory/ItemType.java -index 15d68c4997f739c39675ef8ffa5ab7967dac59f2..f96ced6ae8a969319728efb4fc4fe545923e32be 100644 +index ef3a30d5cca29c7a7c546791be3c333e63e425f4..72803c00e4af576f286d2af34bf300ee554a7f3c 100644 --- a/src/main/java/org/bukkit/inventory/ItemType.java +++ b/src/main/java/org/bukkit/inventory/ItemType.java -@@ -47,7 +47,7 @@ import org.jetbrains.annotations.Nullable; +@@ -48,7 +48,7 @@ import org.jetbrains.annotations.Nullable; * changes may occur. Do not use this API in plugins. */ @ApiStatus.Experimental // Paper - already required for registry builders @@ -305,7 +322,7 @@ index 15d68c4997f739c39675ef8ffa5ab7967dac59f2..f96ced6ae8a969319728efb4fc4fe545 /** * Typed represents a subtype of {@link ItemType}s that have a known item meta type -@@ -2300,7 +2300,9 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans +@@ -2451,7 +2451,9 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * * @param world the world to check * @return true if this ItemType can be used in this World. diff --git a/patches/api/0490-Improve-entity-effect-API.patch b/patches/api/0490-Improve-entity-effect-API.patch index 912d051f49b5..014c98492877 100644 --- a/patches/api/0490-Improve-entity-effect-API.patch +++ b/patches/api/0490-Improve-entity-effect-API.patch @@ -118,10 +118,10 @@ index 725ef320f929d5e3d141c1ed3246d73a7d741f31..d0ae8a94db20281d3664d74718c65234 + // Paper end - broadcast hurt animation } diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 7c56182acaf827f4b1a986a61cea8e9960604c98..8086acceacbceb2c5a7228fff005e41a86d37008 100644 +index c8532a25d64217bcfddf075fd09e255aa9a769e7..81e287c8df1c10cf1e268f3bbd262926d60b70c0 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3859,4 +3859,16 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3874,4 +3874,16 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM @Override Spigot spigot(); // Spigot end diff --git a/patches/server/0001-Setup-Gradle-project.patch b/patches/server/0001-Setup-Gradle-project.patch index baefb46a2de7..6ff6ed67af70 100644 --- a/patches/server/0001-Setup-Gradle-project.patch +++ b/patches/server/0001-Setup-Gradle-project.patch @@ -175,7 +175,7 @@ index 71a22e50d5e543d41b0d285fabfa0965a393ab2e..00000000000000000000000000000000 - org.spigotmc - spigot - jar -- 1.21.1-R0.1-SNAPSHOT +- 1.21.2-R0.1-SNAPSHOT - Spigot - https://www.spigotmc.org/ - diff --git a/patches/server/0002-Remap-fixes.patch b/patches/unapplied/0002-Remap-fixes.patch similarity index 100% rename from patches/server/0002-Remap-fixes.patch rename to patches/unapplied/0002-Remap-fixes.patch diff --git a/patches/server/0003-Build-system-changes.patch b/patches/unapplied/0003-Build-system-changes.patch similarity index 100% rename from patches/server/0003-Build-system-changes.patch rename to patches/unapplied/0003-Build-system-changes.patch diff --git a/patches/server/0004-Test-changes.patch b/patches/unapplied/0004-Test-changes.patch similarity index 100% rename from patches/server/0004-Test-changes.patch rename to patches/unapplied/0004-Test-changes.patch diff --git a/patches/server/0005-Paper-config-files.patch b/patches/unapplied/0005-Paper-config-files.patch similarity index 100% rename from patches/server/0005-Paper-config-files.patch rename to patches/unapplied/0005-Paper-config-files.patch diff --git a/patches/server/0006-MC-Dev-fixes.patch b/patches/unapplied/0006-MC-Dev-fixes.patch similarity index 100% rename from patches/server/0006-MC-Dev-fixes.patch rename to patches/unapplied/0006-MC-Dev-fixes.patch diff --git a/patches/server/0007-ConcurrentUtil.patch b/patches/unapplied/0007-ConcurrentUtil.patch similarity index 100% rename from patches/server/0007-ConcurrentUtil.patch rename to patches/unapplied/0007-ConcurrentUtil.patch diff --git a/patches/server/0008-CB-fixes.patch b/patches/unapplied/0008-CB-fixes.patch similarity index 100% rename from patches/server/0008-CB-fixes.patch rename to patches/unapplied/0008-CB-fixes.patch diff --git a/patches/server/0009-MC-Utils.patch b/patches/unapplied/0009-MC-Utils.patch similarity index 100% rename from patches/server/0009-MC-Utils.patch rename to patches/unapplied/0009-MC-Utils.patch diff --git a/patches/server/0010-Adventure.patch b/patches/unapplied/0010-Adventure.patch similarity index 100% rename from patches/server/0010-Adventure.patch rename to patches/unapplied/0010-Adventure.patch diff --git a/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch b/patches/unapplied/0011-Use-TerminalConsoleAppender-for-console-improvements.patch similarity index 100% rename from patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch rename to patches/unapplied/0011-Use-TerminalConsoleAppender-for-console-improvements.patch diff --git a/patches/server/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch b/patches/unapplied/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch similarity index 100% rename from patches/server/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch rename to patches/unapplied/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch diff --git a/patches/server/0013-Improve-Log4J-Configuration-Plugin-Loggers.patch b/patches/unapplied/0013-Improve-Log4J-Configuration-Plugin-Loggers.patch similarity index 100% rename from patches/server/0013-Improve-Log4J-Configuration-Plugin-Loggers.patch rename to patches/unapplied/0013-Improve-Log4J-Configuration-Plugin-Loggers.patch diff --git a/patches/server/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch b/patches/unapplied/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch similarity index 100% rename from patches/server/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch rename to patches/unapplied/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch diff --git a/patches/server/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch b/patches/unapplied/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch similarity index 100% rename from patches/server/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch rename to patches/unapplied/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch diff --git a/patches/server/0016-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch b/patches/unapplied/0016-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch similarity index 100% rename from patches/server/0016-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch rename to patches/unapplied/0016-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch diff --git a/patches/server/0017-Paper-command.patch b/patches/unapplied/0017-Paper-command.patch similarity index 100% rename from patches/server/0017-Paper-command.patch rename to patches/unapplied/0017-Paper-command.patch diff --git a/patches/server/0018-Paper-Metrics.patch b/patches/unapplied/0018-Paper-Metrics.patch similarity index 100% rename from patches/server/0018-Paper-Metrics.patch rename to patches/unapplied/0018-Paper-Metrics.patch diff --git a/patches/server/0019-Paper-Plugins.patch b/patches/unapplied/0019-Paper-Plugins.patch similarity index 100% rename from patches/server/0019-Paper-Plugins.patch rename to patches/unapplied/0019-Paper-Plugins.patch diff --git a/patches/server/0020-Plugin-remapping.patch b/patches/unapplied/0020-Plugin-remapping.patch similarity index 100% rename from patches/server/0020-Plugin-remapping.patch rename to patches/unapplied/0020-Plugin-remapping.patch diff --git a/patches/server/0021-Hook-into-CB-plugin-rewrites.patch b/patches/unapplied/0021-Hook-into-CB-plugin-rewrites.patch similarity index 100% rename from patches/server/0021-Hook-into-CB-plugin-rewrites.patch rename to patches/unapplied/0021-Hook-into-CB-plugin-rewrites.patch diff --git a/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch b/patches/unapplied/0022-Remap-reflection-calls-in-plugins-using-internals.patch similarity index 100% rename from patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch rename to patches/unapplied/0022-Remap-reflection-calls-in-plugins-using-internals.patch diff --git a/patches/server/0023-Timings-v2.patch b/patches/unapplied/0023-Timings-v2.patch similarity index 100% rename from patches/server/0023-Timings-v2.patch rename to patches/unapplied/0023-Timings-v2.patch diff --git a/patches/server/0024-Further-improve-server-tick-loop.patch b/patches/unapplied/0024-Further-improve-server-tick-loop.patch similarity index 100% rename from patches/server/0024-Further-improve-server-tick-loop.patch rename to patches/unapplied/0024-Further-improve-server-tick-loop.patch diff --git a/patches/server/0025-Add-command-line-option-to-load-extra-plugin-jars-no.patch b/patches/unapplied/0025-Add-command-line-option-to-load-extra-plugin-jars-no.patch similarity index 100% rename from patches/server/0025-Add-command-line-option-to-load-extra-plugin-jars-no.patch rename to patches/unapplied/0025-Add-command-line-option-to-load-extra-plugin-jars-no.patch diff --git a/patches/server/0026-Support-components-in-ItemMeta.patch b/patches/unapplied/0026-Support-components-in-ItemMeta.patch similarity index 100% rename from patches/server/0026-Support-components-in-ItemMeta.patch rename to patches/unapplied/0026-Support-components-in-ItemMeta.patch diff --git a/patches/server/0027-Configurable-cactus-bamboo-and-reed-growth-height.patch b/patches/unapplied/0027-Configurable-cactus-bamboo-and-reed-growth-height.patch similarity index 100% rename from patches/server/0027-Configurable-cactus-bamboo-and-reed-growth-height.patch rename to patches/unapplied/0027-Configurable-cactus-bamboo-and-reed-growth-height.patch diff --git a/patches/server/0028-Configurable-baby-zombie-movement-speed.patch b/patches/unapplied/0028-Configurable-baby-zombie-movement-speed.patch similarity index 100% rename from patches/server/0028-Configurable-baby-zombie-movement-speed.patch rename to patches/unapplied/0028-Configurable-baby-zombie-movement-speed.patch diff --git a/patches/server/0029-Configurable-fishing-time-ranges.patch b/patches/unapplied/0029-Configurable-fishing-time-ranges.patch similarity index 100% rename from patches/server/0029-Configurable-fishing-time-ranges.patch rename to patches/unapplied/0029-Configurable-fishing-time-ranges.patch diff --git a/patches/server/0030-Allow-nerfed-mobs-to-jump.patch b/patches/unapplied/0030-Allow-nerfed-mobs-to-jump.patch similarity index 100% rename from patches/server/0030-Allow-nerfed-mobs-to-jump.patch rename to patches/unapplied/0030-Allow-nerfed-mobs-to-jump.patch diff --git a/patches/server/0031-Add-configurable-entity-despawn-distances.patch b/patches/unapplied/0031-Add-configurable-entity-despawn-distances.patch similarity index 100% rename from patches/server/0031-Add-configurable-entity-despawn-distances.patch rename to patches/unapplied/0031-Add-configurable-entity-despawn-distances.patch diff --git a/patches/server/0032-Drop-falling-block-and-tnt-entities-at-the-specified.patch b/patches/unapplied/0032-Drop-falling-block-and-tnt-entities-at-the-specified.patch similarity index 100% rename from patches/server/0032-Drop-falling-block-and-tnt-entities-at-the-specified.patch rename to patches/unapplied/0032-Drop-falling-block-and-tnt-entities-at-the-specified.patch diff --git a/patches/server/0033-Expose-server-build-information.patch b/patches/unapplied/0033-Expose-server-build-information.patch similarity index 100% rename from patches/server/0033-Expose-server-build-information.patch rename to patches/unapplied/0033-Expose-server-build-information.patch diff --git a/patches/server/0034-Player-affects-spawning-API.patch b/patches/unapplied/0034-Player-affects-spawning-API.patch similarity index 100% rename from patches/server/0034-Player-affects-spawning-API.patch rename to patches/unapplied/0034-Player-affects-spawning-API.patch diff --git a/patches/server/0035-Only-refresh-abilities-if-needed.patch b/patches/unapplied/0035-Only-refresh-abilities-if-needed.patch similarity index 100% rename from patches/server/0035-Only-refresh-abilities-if-needed.patch rename to patches/unapplied/0035-Only-refresh-abilities-if-needed.patch diff --git a/patches/server/0036-Entity-Origin-API.patch b/patches/unapplied/0036-Entity-Origin-API.patch similarity index 100% rename from patches/server/0036-Entity-Origin-API.patch rename to patches/unapplied/0036-Entity-Origin-API.patch diff --git a/patches/server/0037-Prevent-block-entity-and-entity-crashes.patch b/patches/unapplied/0037-Prevent-block-entity-and-entity-crashes.patch similarity index 100% rename from patches/server/0037-Prevent-block-entity-and-entity-crashes.patch rename to patches/unapplied/0037-Prevent-block-entity-and-entity-crashes.patch diff --git a/patches/server/0038-Configurable-top-of-nether-void-damage.patch b/patches/unapplied/0038-Configurable-top-of-nether-void-damage.patch similarity index 100% rename from patches/server/0038-Configurable-top-of-nether-void-damage.patch rename to patches/unapplied/0038-Configurable-top-of-nether-void-damage.patch diff --git a/patches/server/0039-Check-online-mode-before-converting-and-renaming-pla.patch b/patches/unapplied/0039-Check-online-mode-before-converting-and-renaming-pla.patch similarity index 100% rename from patches/server/0039-Check-online-mode-before-converting-and-renaming-pla.patch rename to patches/unapplied/0039-Check-online-mode-before-converting-and-renaming-pla.patch diff --git a/patches/server/0040-Add-more-entities-to-activation-range-ignore-list.patch b/patches/unapplied/0040-Add-more-entities-to-activation-range-ignore-list.patch similarity index 100% rename from patches/server/0040-Add-more-entities-to-activation-range-ignore-list.patch rename to patches/unapplied/0040-Add-more-entities-to-activation-range-ignore-list.patch diff --git a/patches/server/0041-Configurable-end-credits.patch b/patches/unapplied/0041-Configurable-end-credits.patch similarity index 100% rename from patches/server/0041-Configurable-end-credits.patch rename to patches/unapplied/0041-Configurable-end-credits.patch diff --git a/patches/server/0042-Fix-lag-from-explosions-processing-dead-entities.patch b/patches/unapplied/0042-Fix-lag-from-explosions-processing-dead-entities.patch similarity index 100% rename from patches/server/0042-Fix-lag-from-explosions-processing-dead-entities.patch rename to patches/unapplied/0042-Fix-lag-from-explosions-processing-dead-entities.patch diff --git a/patches/server/0043-Optimize-explosions.patch b/patches/unapplied/0043-Optimize-explosions.patch similarity index 100% rename from patches/server/0043-Optimize-explosions.patch rename to patches/unapplied/0043-Optimize-explosions.patch diff --git a/patches/server/0044-Disable-explosion-knockback.patch b/patches/unapplied/0044-Disable-explosion-knockback.patch similarity index 100% rename from patches/server/0044-Disable-explosion-knockback.patch rename to patches/unapplied/0044-Disable-explosion-knockback.patch diff --git a/patches/server/0045-Disable-thunder.patch b/patches/unapplied/0045-Disable-thunder.patch similarity index 100% rename from patches/server/0045-Disable-thunder.patch rename to patches/unapplied/0045-Disable-thunder.patch diff --git a/patches/server/0046-Disable-ice-and-snow.patch b/patches/unapplied/0046-Disable-ice-and-snow.patch similarity index 100% rename from patches/server/0046-Disable-ice-and-snow.patch rename to patches/unapplied/0046-Disable-ice-and-snow.patch diff --git a/patches/server/0047-Configurable-mob-spawner-tick-rate.patch b/patches/unapplied/0047-Configurable-mob-spawner-tick-rate.patch similarity index 100% rename from patches/server/0047-Configurable-mob-spawner-tick-rate.patch rename to patches/unapplied/0047-Configurable-mob-spawner-tick-rate.patch diff --git a/patches/server/0048-Use-null-Locale-by-default.patch b/patches/unapplied/0048-Use-null-Locale-by-default.patch similarity index 100% rename from patches/server/0048-Use-null-Locale-by-default.patch rename to patches/unapplied/0048-Use-null-Locale-by-default.patch diff --git a/patches/server/0049-Add-BeaconEffectEvent.patch b/patches/unapplied/0049-Add-BeaconEffectEvent.patch similarity index 100% rename from patches/server/0049-Add-BeaconEffectEvent.patch rename to patches/unapplied/0049-Add-BeaconEffectEvent.patch diff --git a/patches/server/0050-Configurable-container-update-tick-rate.patch b/patches/unapplied/0050-Configurable-container-update-tick-rate.patch similarity index 100% rename from patches/server/0050-Configurable-container-update-tick-rate.patch rename to patches/unapplied/0050-Configurable-container-update-tick-rate.patch diff --git a/patches/server/0051-Use-UserCache-for-player-heads.patch b/patches/unapplied/0051-Use-UserCache-for-player-heads.patch similarity index 100% rename from patches/server/0051-Use-UserCache-for-player-heads.patch rename to patches/unapplied/0051-Use-UserCache-for-player-heads.patch diff --git a/patches/server/0052-Disable-spigot-tick-limiters.patch b/patches/unapplied/0052-Disable-spigot-tick-limiters.patch similarity index 100% rename from patches/server/0052-Disable-spigot-tick-limiters.patch rename to patches/unapplied/0052-Disable-spigot-tick-limiters.patch diff --git a/patches/server/0053-Fix-spawn-location-event-changing-location.patch b/patches/unapplied/0053-Fix-spawn-location-event-changing-location.patch similarity index 100% rename from patches/server/0053-Fix-spawn-location-event-changing-location.patch rename to patches/unapplied/0053-Fix-spawn-location-event-changing-location.patch diff --git a/patches/server/0054-Configurable-Disabling-Cat-Chest-Detection.patch b/patches/unapplied/0054-Configurable-Disabling-Cat-Chest-Detection.patch similarity index 100% rename from patches/server/0054-Configurable-Disabling-Cat-Chest-Detection.patch rename to patches/unapplied/0054-Configurable-Disabling-Cat-Chest-Detection.patch diff --git a/patches/server/0055-Improve-Player-chat-API-handling.patch b/patches/unapplied/0055-Improve-Player-chat-API-handling.patch similarity index 100% rename from patches/server/0055-Improve-Player-chat-API-handling.patch rename to patches/unapplied/0055-Improve-Player-chat-API-handling.patch diff --git a/patches/server/0056-All-chunks-are-slime-spawn-chunks-toggle.patch b/patches/unapplied/0056-All-chunks-are-slime-spawn-chunks-toggle.patch similarity index 100% rename from patches/server/0056-All-chunks-are-slime-spawn-chunks-toggle.patch rename to patches/unapplied/0056-All-chunks-are-slime-spawn-chunks-toggle.patch diff --git a/patches/server/0057-Expose-server-CommandMap.patch b/patches/unapplied/0057-Expose-server-CommandMap.patch similarity index 100% rename from patches/server/0057-Expose-server-CommandMap.patch rename to patches/unapplied/0057-Expose-server-CommandMap.patch diff --git a/patches/server/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch b/patches/unapplied/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch similarity index 100% rename from patches/server/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch rename to patches/unapplied/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch diff --git a/patches/server/0059-Player-Tab-List-and-Title-APIs.patch b/patches/unapplied/0059-Player-Tab-List-and-Title-APIs.patch similarity index 100% rename from patches/server/0059-Player-Tab-List-and-Title-APIs.patch rename to patches/unapplied/0059-Player-Tab-List-and-Title-APIs.patch diff --git a/patches/server/0060-Add-configurable-portal-search-radius.patch b/patches/unapplied/0060-Add-configurable-portal-search-radius.patch similarity index 100% rename from patches/server/0060-Add-configurable-portal-search-radius.patch rename to patches/unapplied/0060-Add-configurable-portal-search-radius.patch diff --git a/patches/server/0061-Add-velocity-warnings.patch b/patches/unapplied/0061-Add-velocity-warnings.patch similarity index 100% rename from patches/server/0061-Add-velocity-warnings.patch rename to patches/unapplied/0061-Add-velocity-warnings.patch diff --git a/patches/server/0062-Add-exception-reporting-event.patch b/patches/unapplied/0062-Add-exception-reporting-event.patch similarity index 100% rename from patches/server/0062-Add-exception-reporting-event.patch rename to patches/unapplied/0062-Add-exception-reporting-event.patch diff --git a/patches/server/0063-Disable-Scoreboards-for-non-players-by-default.patch b/patches/unapplied/0063-Disable-Scoreboards-for-non-players-by-default.patch similarity index 100% rename from patches/server/0063-Disable-Scoreboards-for-non-players-by-default.patch rename to patches/unapplied/0063-Disable-Scoreboards-for-non-players-by-default.patch diff --git a/patches/server/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch b/patches/unapplied/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch similarity index 100% rename from patches/server/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch rename to patches/unapplied/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch diff --git a/patches/server/0065-Chunk-Save-Reattempt.patch b/patches/unapplied/0065-Chunk-Save-Reattempt.patch similarity index 100% rename from patches/server/0065-Chunk-Save-Reattempt.patch rename to patches/unapplied/0065-Chunk-Save-Reattempt.patch diff --git a/patches/server/0066-Complete-resource-pack-API.patch b/patches/unapplied/0066-Complete-resource-pack-API.patch similarity index 100% rename from patches/server/0066-Complete-resource-pack-API.patch rename to patches/unapplied/0066-Complete-resource-pack-API.patch diff --git a/patches/server/0067-Default-loading-permissions.yml-before-plugins.patch b/patches/unapplied/0067-Default-loading-permissions.yml-before-plugins.patch similarity index 100% rename from patches/server/0067-Default-loading-permissions.yml-before-plugins.patch rename to patches/unapplied/0067-Default-loading-permissions.yml-before-plugins.patch diff --git a/patches/server/0068-Allow-Reloading-of-Custom-Permissions.patch b/patches/unapplied/0068-Allow-Reloading-of-Custom-Permissions.patch similarity index 100% rename from patches/server/0068-Allow-Reloading-of-Custom-Permissions.patch rename to patches/unapplied/0068-Allow-Reloading-of-Custom-Permissions.patch diff --git a/patches/server/0069-Remove-Metadata-on-reload.patch b/patches/unapplied/0069-Remove-Metadata-on-reload.patch similarity index 100% rename from patches/server/0069-Remove-Metadata-on-reload.patch rename to patches/unapplied/0069-Remove-Metadata-on-reload.patch diff --git a/patches/server/0070-Handle-Item-Meta-Inconsistencies.patch b/patches/unapplied/0070-Handle-Item-Meta-Inconsistencies.patch similarity index 100% rename from patches/server/0070-Handle-Item-Meta-Inconsistencies.patch rename to patches/unapplied/0070-Handle-Item-Meta-Inconsistencies.patch diff --git a/patches/server/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch b/patches/unapplied/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch similarity index 100% rename from patches/server/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch rename to patches/unapplied/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch diff --git a/patches/server/0072-Add-World-Util-Methods.patch b/patches/unapplied/0072-Add-World-Util-Methods.patch similarity index 100% rename from patches/server/0072-Add-World-Util-Methods.patch rename to patches/unapplied/0072-Add-World-Util-Methods.patch diff --git a/patches/server/0073-Custom-replacement-for-eaten-items.patch b/patches/unapplied/0073-Custom-replacement-for-eaten-items.patch similarity index 100% rename from patches/server/0073-Custom-replacement-for-eaten-items.patch rename to patches/unapplied/0073-Custom-replacement-for-eaten-items.patch diff --git a/patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch b/patches/unapplied/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch similarity index 100% rename from patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch rename to patches/unapplied/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch diff --git a/patches/server/0075-Use-a-Shared-Random-for-Entities.patch b/patches/unapplied/0075-Use-a-Shared-Random-for-Entities.patch similarity index 100% rename from patches/server/0075-Use-a-Shared-Random-for-Entities.patch rename to patches/unapplied/0075-Use-a-Shared-Random-for-Entities.patch diff --git a/patches/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch b/patches/unapplied/0076-Configurable-spawn-chances-for-skeleton-horses.patch similarity index 100% rename from patches/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch rename to patches/unapplied/0076-Configurable-spawn-chances-for-skeleton-horses.patch diff --git a/patches/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch b/patches/unapplied/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch similarity index 100% rename from patches/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch rename to patches/unapplied/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch diff --git a/patches/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch b/patches/unapplied/0078-Entity-AddTo-RemoveFrom-World-Events.patch similarity index 100% rename from patches/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch rename to patches/unapplied/0078-Entity-AddTo-RemoveFrom-World-Events.patch diff --git a/patches/server/0079-Configurable-Chunk-Inhabited-Time.patch b/patches/unapplied/0079-Configurable-Chunk-Inhabited-Time.patch similarity index 100% rename from patches/server/0079-Configurable-Chunk-Inhabited-Time.patch rename to patches/unapplied/0079-Configurable-Chunk-Inhabited-Time.patch diff --git a/patches/server/0080-EntityPathfindEvent.patch b/patches/unapplied/0080-EntityPathfindEvent.patch similarity index 100% rename from patches/server/0080-EntityPathfindEvent.patch rename to patches/unapplied/0080-EntityPathfindEvent.patch diff --git a/patches/server/0081-Sanitise-RegionFileCache-and-make-configurable.patch b/patches/unapplied/0081-Sanitise-RegionFileCache-and-make-configurable.patch similarity index 100% rename from patches/server/0081-Sanitise-RegionFileCache-and-make-configurable.patch rename to patches/unapplied/0081-Sanitise-RegionFileCache-and-make-configurable.patch diff --git a/patches/server/0082-Do-not-load-chunks-for-Pathfinding.patch b/patches/unapplied/0082-Do-not-load-chunks-for-Pathfinding.patch similarity index 100% rename from patches/server/0082-Do-not-load-chunks-for-Pathfinding.patch rename to patches/unapplied/0082-Do-not-load-chunks-for-Pathfinding.patch diff --git a/patches/server/0083-Add-PlayerUseUnknownEntityEvent.patch b/patches/unapplied/0083-Add-PlayerUseUnknownEntityEvent.patch similarity index 100% rename from patches/server/0083-Add-PlayerUseUnknownEntityEvent.patch rename to patches/unapplied/0083-Add-PlayerUseUnknownEntityEvent.patch diff --git a/patches/server/0084-Configurable-random-tick-rates-for-blocks.patch b/patches/unapplied/0084-Configurable-random-tick-rates-for-blocks.patch similarity index 100% rename from patches/server/0084-Configurable-random-tick-rates-for-blocks.patch rename to patches/unapplied/0084-Configurable-random-tick-rates-for-blocks.patch diff --git a/patches/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch b/patches/unapplied/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch similarity index 100% rename from patches/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch rename to patches/unapplied/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch diff --git a/patches/server/0086-Optimize-DataBits.patch b/patches/unapplied/0086-Optimize-DataBits.patch similarity index 100% rename from patches/server/0086-Optimize-DataBits.patch rename to patches/unapplied/0086-Optimize-DataBits.patch diff --git a/patches/server/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch b/patches/unapplied/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch similarity index 100% rename from patches/server/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch rename to patches/unapplied/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch diff --git a/patches/server/0088-Configurable-Player-Collision.patch b/patches/unapplied/0088-Configurable-Player-Collision.patch similarity index 100% rename from patches/server/0088-Configurable-Player-Collision.patch rename to patches/unapplied/0088-Configurable-Player-Collision.patch diff --git a/patches/server/0089-Add-handshake-event-to-allow-plugins-to-handle-clien.patch b/patches/unapplied/0089-Add-handshake-event-to-allow-plugins-to-handle-clien.patch similarity index 100% rename from patches/server/0089-Add-handshake-event-to-allow-plugins-to-handle-clien.patch rename to patches/unapplied/0089-Add-handshake-event-to-allow-plugins-to-handle-clien.patch diff --git a/patches/server/0090-Configurable-RCON-IP-address.patch b/patches/unapplied/0090-Configurable-RCON-IP-address.patch similarity index 100% rename from patches/server/0090-Configurable-RCON-IP-address.patch rename to patches/unapplied/0090-Configurable-RCON-IP-address.patch diff --git a/patches/server/0091-EntityRegainHealthEvent-isFastRegen-API.patch b/patches/unapplied/0091-EntityRegainHealthEvent-isFastRegen-API.patch similarity index 100% rename from patches/server/0091-EntityRegainHealthEvent-isFastRegen-API.patch rename to patches/unapplied/0091-EntityRegainHealthEvent-isFastRegen-API.patch diff --git a/patches/server/0092-Add-ability-to-configure-frosted_ice-properties.patch b/patches/unapplied/0092-Add-ability-to-configure-frosted_ice-properties.patch similarity index 100% rename from patches/server/0092-Add-ability-to-configure-frosted_ice-properties.patch rename to patches/unapplied/0092-Add-ability-to-configure-frosted_ice-properties.patch diff --git a/patches/server/0093-remove-null-possibility-for-getServer-singleton.patch b/patches/unapplied/0093-remove-null-possibility-for-getServer-singleton.patch similarity index 100% rename from patches/server/0093-remove-null-possibility-for-getServer-singleton.patch rename to patches/unapplied/0093-remove-null-possibility-for-getServer-singleton.patch diff --git a/patches/server/0094-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch b/patches/unapplied/0094-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch similarity index 100% rename from patches/server/0094-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch rename to patches/unapplied/0094-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch diff --git a/patches/server/0095-LootTable-API-and-replenishable-lootables.patch b/patches/unapplied/0095-LootTable-API-and-replenishable-lootables.patch similarity index 100% rename from patches/server/0095-LootTable-API-and-replenishable-lootables.patch rename to patches/unapplied/0095-LootTable-API-and-replenishable-lootables.patch diff --git a/patches/server/0096-System-property-for-disabling-watchdoge.patch b/patches/unapplied/0096-System-property-for-disabling-watchdoge.patch similarity index 100% rename from patches/server/0096-System-property-for-disabling-watchdoge.patch rename to patches/unapplied/0096-System-property-for-disabling-watchdoge.patch diff --git a/patches/server/0097-Async-GameProfileCache-saving.patch b/patches/unapplied/0097-Async-GameProfileCache-saving.patch similarity index 100% rename from patches/server/0097-Async-GameProfileCache-saving.patch rename to patches/unapplied/0097-Async-GameProfileCache-saving.patch diff --git a/patches/server/0098-Optional-TNT-doesn-t-move-in-water.patch b/patches/unapplied/0098-Optional-TNT-doesn-t-move-in-water.patch similarity index 100% rename from patches/server/0098-Optional-TNT-doesn-t-move-in-water.patch rename to patches/unapplied/0098-Optional-TNT-doesn-t-move-in-water.patch diff --git a/patches/server/0099-Faster-redstone-torch-rapid-clock-removal.patch b/patches/unapplied/0099-Faster-redstone-torch-rapid-clock-removal.patch similarity index 100% rename from patches/server/0099-Faster-redstone-torch-rapid-clock-removal.patch rename to patches/unapplied/0099-Faster-redstone-torch-rapid-clock-removal.patch diff --git a/patches/server/0100-Add-server-name-parameter.patch b/patches/unapplied/0100-Add-server-name-parameter.patch similarity index 100% rename from patches/server/0100-Add-server-name-parameter.patch rename to patches/unapplied/0100-Add-server-name-parameter.patch diff --git a/patches/server/0101-Fix-global-sound-handling.patch b/patches/unapplied/0101-Fix-global-sound-handling.patch similarity index 100% rename from patches/server/0101-Fix-global-sound-handling.patch rename to patches/unapplied/0101-Fix-global-sound-handling.patch diff --git a/patches/server/0102-Avoid-blocking-on-Network-Manager-creation.patch b/patches/unapplied/0102-Avoid-blocking-on-Network-Manager-creation.patch similarity index 100% rename from patches/server/0102-Avoid-blocking-on-Network-Manager-creation.patch rename to patches/unapplied/0102-Avoid-blocking-on-Network-Manager-creation.patch diff --git a/patches/server/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch b/patches/unapplied/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch similarity index 100% rename from patches/server/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch rename to patches/unapplied/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch diff --git a/patches/server/0104-Add-setting-for-proxy-online-mode-status.patch b/patches/unapplied/0104-Add-setting-for-proxy-online-mode-status.patch similarity index 100% rename from patches/server/0104-Add-setting-for-proxy-online-mode-status.patch rename to patches/unapplied/0104-Add-setting-for-proxy-online-mode-status.patch diff --git a/patches/server/0105-Optimise-BlockState-s-hashCode-equals.patch b/patches/unapplied/0105-Optimise-BlockState-s-hashCode-equals.patch similarity index 100% rename from patches/server/0105-Optimise-BlockState-s-hashCode-equals.patch rename to patches/unapplied/0105-Optimise-BlockState-s-hashCode-equals.patch diff --git a/patches/server/0106-Configurable-packet-in-spam-threshold.patch b/patches/unapplied/0106-Configurable-packet-in-spam-threshold.patch similarity index 100% rename from patches/server/0106-Configurable-packet-in-spam-threshold.patch rename to patches/unapplied/0106-Configurable-packet-in-spam-threshold.patch diff --git a/patches/server/0107-Configurable-flying-kick-messages.patch b/patches/unapplied/0107-Configurable-flying-kick-messages.patch similarity index 100% rename from patches/server/0107-Configurable-flying-kick-messages.patch rename to patches/unapplied/0107-Configurable-flying-kick-messages.patch diff --git a/patches/server/0108-Add-EntityZapEvent.patch b/patches/unapplied/0108-Add-EntityZapEvent.patch similarity index 100% rename from patches/server/0108-Add-EntityZapEvent.patch rename to patches/unapplied/0108-Add-EntityZapEvent.patch diff --git a/patches/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch b/patches/unapplied/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch similarity index 100% rename from patches/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch rename to patches/unapplied/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch diff --git a/patches/server/0110-Cache-user-authenticator-threads.patch b/patches/unapplied/0110-Cache-user-authenticator-threads.patch similarity index 100% rename from patches/server/0110-Cache-user-authenticator-threads.patch rename to patches/unapplied/0110-Cache-user-authenticator-threads.patch diff --git a/patches/server/0111-Allow-Reloading-of-Command-Aliases.patch b/patches/unapplied/0111-Allow-Reloading-of-Command-Aliases.patch similarity index 100% rename from patches/server/0111-Allow-Reloading-of-Command-Aliases.patch rename to patches/unapplied/0111-Allow-Reloading-of-Command-Aliases.patch diff --git a/patches/server/0112-Add-source-to-PlayerExpChangeEvent.patch b/patches/unapplied/0112-Add-source-to-PlayerExpChangeEvent.patch similarity index 100% rename from patches/server/0112-Add-source-to-PlayerExpChangeEvent.patch rename to patches/unapplied/0112-Add-source-to-PlayerExpChangeEvent.patch diff --git a/patches/server/0113-Add-ProjectileCollideEvent.patch b/patches/unapplied/0113-Add-ProjectileCollideEvent.patch similarity index 100% rename from patches/server/0113-Add-ProjectileCollideEvent.patch rename to patches/unapplied/0113-Add-ProjectileCollideEvent.patch diff --git a/patches/server/0114-Prevent-Pathfinding-out-of-World-Border.patch b/patches/unapplied/0114-Prevent-Pathfinding-out-of-World-Border.patch similarity index 100% rename from patches/server/0114-Prevent-Pathfinding-out-of-World-Border.patch rename to patches/unapplied/0114-Prevent-Pathfinding-out-of-World-Border.patch diff --git a/patches/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch b/patches/unapplied/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch similarity index 100% rename from patches/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch rename to patches/unapplied/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch diff --git a/patches/server/0116-Bound-Treasure-Maps-to-World-Border.patch b/patches/unapplied/0116-Bound-Treasure-Maps-to-World-Border.patch similarity index 100% rename from patches/server/0116-Bound-Treasure-Maps-to-World-Border.patch rename to patches/unapplied/0116-Bound-Treasure-Maps-to-World-Border.patch diff --git a/patches/server/0117-Configurable-Cartographer-Treasure-Maps.patch b/patches/unapplied/0117-Configurable-Cartographer-Treasure-Maps.patch similarity index 100% rename from patches/server/0117-Configurable-Cartographer-Treasure-Maps.patch rename to patches/unapplied/0117-Configurable-Cartographer-Treasure-Maps.patch diff --git a/patches/server/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch b/patches/unapplied/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch similarity index 100% rename from patches/server/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch rename to patches/unapplied/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch diff --git a/patches/server/0119-String-based-Action-Bar-API.patch b/patches/unapplied/0119-String-based-Action-Bar-API.patch similarity index 100% rename from patches/server/0119-String-based-Action-Bar-API.patch rename to patches/unapplied/0119-String-based-Action-Bar-API.patch diff --git a/patches/server/0120-Properly-fix-item-duplication-bug.patch b/patches/unapplied/0120-Properly-fix-item-duplication-bug.patch similarity index 100% rename from patches/server/0120-Properly-fix-item-duplication-bug.patch rename to patches/unapplied/0120-Properly-fix-item-duplication-bug.patch diff --git a/patches/server/0121-Firework-API-s.patch b/patches/unapplied/0121-Firework-API-s.patch similarity index 100% rename from patches/server/0121-Firework-API-s.patch rename to patches/unapplied/0121-Firework-API-s.patch diff --git a/patches/server/0122-PlayerTeleportEndGatewayEvent.patch b/patches/unapplied/0122-PlayerTeleportEndGatewayEvent.patch similarity index 100% rename from patches/server/0122-PlayerTeleportEndGatewayEvent.patch rename to patches/unapplied/0122-PlayerTeleportEndGatewayEvent.patch diff --git a/patches/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch b/patches/unapplied/0123-Provide-E-TE-Chunk-count-stat-methods.patch similarity index 100% rename from patches/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch rename to patches/unapplied/0123-Provide-E-TE-Chunk-count-stat-methods.patch diff --git a/patches/server/0124-Enforce-Sync-Player-Saves.patch b/patches/unapplied/0124-Enforce-Sync-Player-Saves.patch similarity index 100% rename from patches/server/0124-Enforce-Sync-Player-Saves.patch rename to patches/unapplied/0124-Enforce-Sync-Player-Saves.patch diff --git a/patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch b/patches/unapplied/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch similarity index 100% rename from patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch rename to patches/unapplied/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch diff --git a/patches/server/0126-Cap-Entity-Collisions.patch b/patches/unapplied/0126-Cap-Entity-Collisions.patch similarity index 100% rename from patches/server/0126-Cap-Entity-Collisions.patch rename to patches/unapplied/0126-Cap-Entity-Collisions.patch diff --git a/patches/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch b/patches/unapplied/0127-Remove-CraftScheduler-Async-Task-Debugger.patch similarity index 100% rename from patches/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch rename to patches/unapplied/0127-Remove-CraftScheduler-Async-Task-Debugger.patch diff --git a/patches/server/0128-Properly-handle-async-calls-to-restart-the-server.patch b/patches/unapplied/0128-Properly-handle-async-calls-to-restart-the-server.patch similarity index 100% rename from patches/server/0128-Properly-handle-async-calls-to-restart-the-server.patch rename to patches/unapplied/0128-Properly-handle-async-calls-to-restart-the-server.patch diff --git a/patches/server/0129-Add-option-to-make-parrots-stay-on-shoulders-despite.patch b/patches/unapplied/0129-Add-option-to-make-parrots-stay-on-shoulders-despite.patch similarity index 100% rename from patches/server/0129-Add-option-to-make-parrots-stay-on-shoulders-despite.patch rename to patches/unapplied/0129-Add-option-to-make-parrots-stay-on-shoulders-despite.patch diff --git a/patches/server/0130-Add-configuration-option-to-prevent-player-names-fro.patch b/patches/unapplied/0130-Add-configuration-option-to-prevent-player-names-fro.patch similarity index 100% rename from patches/server/0130-Add-configuration-option-to-prevent-player-names-fro.patch rename to patches/unapplied/0130-Add-configuration-option-to-prevent-player-names-fro.patch diff --git a/patches/server/0131-provide-a-configurable-option-to-disable-creeper-lin.patch b/patches/unapplied/0131-provide-a-configurable-option-to-disable-creeper-lin.patch similarity index 100% rename from patches/server/0131-provide-a-configurable-option-to-disable-creeper-lin.patch rename to patches/unapplied/0131-provide-a-configurable-option-to-disable-creeper-lin.patch diff --git a/patches/server/0132-Item-canEntityPickup.patch b/patches/unapplied/0132-Item-canEntityPickup.patch similarity index 100% rename from patches/server/0132-Item-canEntityPickup.patch rename to patches/unapplied/0132-Item-canEntityPickup.patch diff --git a/patches/server/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch b/patches/unapplied/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch similarity index 100% rename from patches/server/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch rename to patches/unapplied/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch diff --git a/patches/server/0134-PlayerAttemptPickupItemEvent.patch b/patches/unapplied/0134-PlayerAttemptPickupItemEvent.patch similarity index 100% rename from patches/server/0134-PlayerAttemptPickupItemEvent.patch rename to patches/unapplied/0134-PlayerAttemptPickupItemEvent.patch diff --git a/patches/server/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch b/patches/unapplied/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch similarity index 100% rename from patches/server/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch rename to patches/unapplied/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch diff --git a/patches/server/0136-Basic-PlayerProfile-API.patch b/patches/unapplied/0136-Basic-PlayerProfile-API.patch similarity index 100% rename from patches/server/0136-Basic-PlayerProfile-API.patch rename to patches/unapplied/0136-Basic-PlayerProfile-API.patch diff --git a/patches/server/0137-Add-UnknownCommandEvent.patch b/patches/unapplied/0137-Add-UnknownCommandEvent.patch similarity index 100% rename from patches/server/0137-Add-UnknownCommandEvent.patch rename to patches/unapplied/0137-Add-UnknownCommandEvent.patch diff --git a/patches/server/0138-Shoulder-Entities-Release-API.patch b/patches/unapplied/0138-Shoulder-Entities-Release-API.patch similarity index 100% rename from patches/server/0138-Shoulder-Entities-Release-API.patch rename to patches/unapplied/0138-Shoulder-Entities-Release-API.patch diff --git a/patches/server/0139-Profile-Lookup-Events.patch b/patches/unapplied/0139-Profile-Lookup-Events.patch similarity index 100% rename from patches/server/0139-Profile-Lookup-Events.patch rename to patches/unapplied/0139-Profile-Lookup-Events.patch diff --git a/patches/server/0140-Block-player-logins-during-server-shutdown.patch b/patches/unapplied/0140-Block-player-logins-during-server-shutdown.patch similarity index 100% rename from patches/server/0140-Block-player-logins-during-server-shutdown.patch rename to patches/unapplied/0140-Block-player-logins-during-server-shutdown.patch diff --git a/patches/server/0141-Entity-fromMobSpawner.patch b/patches/unapplied/0141-Entity-fromMobSpawner.patch similarity index 100% rename from patches/server/0141-Entity-fromMobSpawner.patch rename to patches/unapplied/0141-Entity-fromMobSpawner.patch diff --git a/patches/server/0142-Improve-the-Saddle-API-for-Horses.patch b/patches/unapplied/0142-Improve-the-Saddle-API-for-Horses.patch similarity index 100% rename from patches/server/0142-Improve-the-Saddle-API-for-Horses.patch rename to patches/unapplied/0142-Improve-the-Saddle-API-for-Horses.patch diff --git a/patches/server/0143-ensureServerConversions-API.patch b/patches/unapplied/0143-ensureServerConversions-API.patch similarity index 100% rename from patches/server/0143-ensureServerConversions-API.patch rename to patches/unapplied/0143-ensureServerConversions-API.patch diff --git a/patches/server/0144-Implement-getI18NDisplayName.patch b/patches/unapplied/0144-Implement-getI18NDisplayName.patch similarity index 100% rename from patches/server/0144-Implement-getI18NDisplayName.patch rename to patches/unapplied/0144-Implement-getI18NDisplayName.patch diff --git a/patches/server/0145-ProfileWhitelistVerifyEvent.patch b/patches/unapplied/0145-ProfileWhitelistVerifyEvent.patch similarity index 100% rename from patches/server/0145-ProfileWhitelistVerifyEvent.patch rename to patches/unapplied/0145-ProfileWhitelistVerifyEvent.patch diff --git a/patches/server/0146-Fix-this-stupid-bullshit.patch b/patches/unapplied/0146-Fix-this-stupid-bullshit.patch similarity index 100% rename from patches/server/0146-Fix-this-stupid-bullshit.patch rename to patches/unapplied/0146-Fix-this-stupid-bullshit.patch diff --git a/patches/server/0147-LivingEntity-setKiller.patch b/patches/unapplied/0147-LivingEntity-setKiller.patch similarity index 100% rename from patches/server/0147-LivingEntity-setKiller.patch rename to patches/unapplied/0147-LivingEntity-setKiller.patch diff --git a/patches/server/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch b/patches/unapplied/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch similarity index 100% rename from patches/server/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch rename to patches/unapplied/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch diff --git a/patches/server/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch b/patches/unapplied/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch similarity index 100% rename from patches/server/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch rename to patches/unapplied/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch diff --git a/patches/server/0150-Allow-specifying-a-custom-authentication-servers-dow.patch b/patches/unapplied/0150-Allow-specifying-a-custom-authentication-servers-dow.patch similarity index 100% rename from patches/server/0150-Allow-specifying-a-custom-authentication-servers-dow.patch rename to patches/unapplied/0150-Allow-specifying-a-custom-authentication-servers-dow.patch diff --git a/patches/server/0151-Add-PlayerJumpEvent.patch b/patches/unapplied/0151-Add-PlayerJumpEvent.patch similarity index 100% rename from patches/server/0151-Add-PlayerJumpEvent.patch rename to patches/unapplied/0151-Add-PlayerJumpEvent.patch diff --git a/patches/server/0152-handle-ServerboundKeepAlivePacket-async.patch b/patches/unapplied/0152-handle-ServerboundKeepAlivePacket-async.patch similarity index 100% rename from patches/server/0152-handle-ServerboundKeepAlivePacket-async.patch rename to patches/unapplied/0152-handle-ServerboundKeepAlivePacket-async.patch diff --git a/patches/server/0153-Expose-client-protocol-version-and-virtual-host.patch b/patches/unapplied/0153-Expose-client-protocol-version-and-virtual-host.patch similarity index 100% rename from patches/server/0153-Expose-client-protocol-version-and-virtual-host.patch rename to patches/unapplied/0153-Expose-client-protocol-version-and-virtual-host.patch diff --git a/patches/server/0154-revert-serverside-behavior-of-keepalives.patch b/patches/unapplied/0154-revert-serverside-behavior-of-keepalives.patch similarity index 100% rename from patches/server/0154-revert-serverside-behavior-of-keepalives.patch rename to patches/unapplied/0154-revert-serverside-behavior-of-keepalives.patch diff --git a/patches/server/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch b/patches/unapplied/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch similarity index 100% rename from patches/server/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch rename to patches/unapplied/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch diff --git a/patches/server/0156-Add-PlayerArmorChangeEvent.patch b/patches/unapplied/0156-Add-PlayerArmorChangeEvent.patch similarity index 100% rename from patches/server/0156-Add-PlayerArmorChangeEvent.patch rename to patches/unapplied/0156-Add-PlayerArmorChangeEvent.patch diff --git a/patches/server/0157-Prevent-logins-from-being-processed-when-the-player-.patch b/patches/unapplied/0157-Prevent-logins-from-being-processed-when-the-player-.patch similarity index 100% rename from patches/server/0157-Prevent-logins-from-being-processed-when-the-player-.patch rename to patches/unapplied/0157-Prevent-logins-from-being-processed-when-the-player-.patch diff --git a/patches/server/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch b/patches/unapplied/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch similarity index 100% rename from patches/server/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch rename to patches/unapplied/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch diff --git a/patches/server/0159-use-CB-BlockState-implementations-for-captured-block.patch b/patches/unapplied/0159-use-CB-BlockState-implementations-for-captured-block.patch similarity index 100% rename from patches/server/0159-use-CB-BlockState-implementations-for-captured-block.patch rename to patches/unapplied/0159-use-CB-BlockState-implementations-for-captured-block.patch diff --git a/patches/server/0160-API-to-get-a-BlockState-without-a-snapshot.patch b/patches/unapplied/0160-API-to-get-a-BlockState-without-a-snapshot.patch similarity index 100% rename from patches/server/0160-API-to-get-a-BlockState-without-a-snapshot.patch rename to patches/unapplied/0160-API-to-get-a-BlockState-without-a-snapshot.patch diff --git a/patches/server/0161-AsyncTabCompleteEvent.patch b/patches/unapplied/0161-AsyncTabCompleteEvent.patch similarity index 100% rename from patches/server/0161-AsyncTabCompleteEvent.patch rename to patches/unapplied/0161-AsyncTabCompleteEvent.patch diff --git a/patches/server/0162-PlayerPickupExperienceEvent.patch b/patches/unapplied/0162-PlayerPickupExperienceEvent.patch similarity index 100% rename from patches/server/0162-PlayerPickupExperienceEvent.patch rename to patches/unapplied/0162-PlayerPickupExperienceEvent.patch diff --git a/patches/server/0163-Ability-to-apply-mending-to-XP-API.patch b/patches/unapplied/0163-Ability-to-apply-mending-to-XP-API.patch similarity index 100% rename from patches/server/0163-Ability-to-apply-mending-to-XP-API.patch rename to patches/unapplied/0163-Ability-to-apply-mending-to-XP-API.patch diff --git a/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch b/patches/unapplied/0164-PlayerNaturallySpawnCreaturesEvent.patch similarity index 100% rename from patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch rename to patches/unapplied/0164-PlayerNaturallySpawnCreaturesEvent.patch diff --git a/patches/server/0165-Add-setPlayerProfile-API-for-Skulls.patch b/patches/unapplied/0165-Add-setPlayerProfile-API-for-Skulls.patch similarity index 100% rename from patches/server/0165-Add-setPlayerProfile-API-for-Skulls.patch rename to patches/unapplied/0165-Add-setPlayerProfile-API-for-Skulls.patch diff --git a/patches/server/0166-PreCreatureSpawnEvent.patch b/patches/unapplied/0166-PreCreatureSpawnEvent.patch similarity index 100% rename from patches/server/0166-PreCreatureSpawnEvent.patch rename to patches/unapplied/0166-PreCreatureSpawnEvent.patch diff --git a/patches/server/0167-Fill-Profile-Property-Events.patch b/patches/unapplied/0167-Fill-Profile-Property-Events.patch similarity index 100% rename from patches/server/0167-Fill-Profile-Property-Events.patch rename to patches/unapplied/0167-Fill-Profile-Property-Events.patch diff --git a/patches/server/0168-Add-PlayerAdvancementCriterionGrantEvent.patch b/patches/unapplied/0168-Add-PlayerAdvancementCriterionGrantEvent.patch similarity index 100% rename from patches/server/0168-Add-PlayerAdvancementCriterionGrantEvent.patch rename to patches/unapplied/0168-Add-PlayerAdvancementCriterionGrantEvent.patch diff --git a/patches/server/0169-Add-ArmorStand-Item-Meta.patch b/patches/unapplied/0169-Add-ArmorStand-Item-Meta.patch similarity index 100% rename from patches/server/0169-Add-ArmorStand-Item-Meta.patch rename to patches/unapplied/0169-Add-ArmorStand-Item-Meta.patch diff --git a/patches/server/0170-Extend-Player-Interact-cancellation.patch b/patches/unapplied/0170-Extend-Player-Interact-cancellation.patch similarity index 100% rename from patches/server/0170-Extend-Player-Interact-cancellation.patch rename to patches/unapplied/0170-Extend-Player-Interact-cancellation.patch diff --git a/patches/server/0171-Tameable-getOwnerUniqueId-API.patch b/patches/unapplied/0171-Tameable-getOwnerUniqueId-API.patch similarity index 100% rename from patches/server/0171-Tameable-getOwnerUniqueId-API.patch rename to patches/unapplied/0171-Tameable-getOwnerUniqueId-API.patch diff --git a/patches/server/0172-Toggleable-player-crits.patch b/patches/unapplied/0172-Toggleable-player-crits.patch similarity index 100% rename from patches/server/0172-Toggleable-player-crits.patch rename to patches/unapplied/0172-Toggleable-player-crits.patch diff --git a/patches/server/0173-Disable-Explicit-Network-Manager-Flushing.patch b/patches/unapplied/0173-Disable-Explicit-Network-Manager-Flushing.patch similarity index 100% rename from patches/server/0173-Disable-Explicit-Network-Manager-Flushing.patch rename to patches/unapplied/0173-Disable-Explicit-Network-Manager-Flushing.patch diff --git a/patches/server/0174-Implement-extended-PaperServerListPingEvent.patch b/patches/unapplied/0174-Implement-extended-PaperServerListPingEvent.patch similarity index 100% rename from patches/server/0174-Implement-extended-PaperServerListPingEvent.patch rename to patches/unapplied/0174-Implement-extended-PaperServerListPingEvent.patch diff --git a/patches/server/0175-Add-more-fields-to-AsyncPreLoginEvent.patch b/patches/unapplied/0175-Add-more-fields-to-AsyncPreLoginEvent.patch similarity index 100% rename from patches/server/0175-Add-more-fields-to-AsyncPreLoginEvent.patch rename to patches/unapplied/0175-Add-more-fields-to-AsyncPreLoginEvent.patch diff --git a/patches/server/0176-Player.setPlayerProfile-API.patch b/patches/unapplied/0176-Player.setPlayerProfile-API.patch similarity index 100% rename from patches/server/0176-Player.setPlayerProfile-API.patch rename to patches/unapplied/0176-Player.setPlayerProfile-API.patch diff --git a/patches/server/0177-getPlayerUniqueId-API.patch b/patches/unapplied/0177-getPlayerUniqueId-API.patch similarity index 100% rename from patches/server/0177-getPlayerUniqueId-API.patch rename to patches/unapplied/0177-getPlayerUniqueId-API.patch diff --git a/patches/server/0178-Improved-Async-Task-Scheduler.patch b/patches/unapplied/0178-Improved-Async-Task-Scheduler.patch similarity index 100% rename from patches/server/0178-Improved-Async-Task-Scheduler.patch rename to patches/unapplied/0178-Improved-Async-Task-Scheduler.patch diff --git a/patches/server/0179-Make-legacy-ping-handler-more-reliable.patch b/patches/unapplied/0179-Make-legacy-ping-handler-more-reliable.patch similarity index 100% rename from patches/server/0179-Make-legacy-ping-handler-more-reliable.patch rename to patches/unapplied/0179-Make-legacy-ping-handler-more-reliable.patch diff --git a/patches/server/0180-Call-PaperServerListPingEvent-for-legacy-pings.patch b/patches/unapplied/0180-Call-PaperServerListPingEvent-for-legacy-pings.patch similarity index 100% rename from patches/server/0180-Call-PaperServerListPingEvent-for-legacy-pings.patch rename to patches/unapplied/0180-Call-PaperServerListPingEvent-for-legacy-pings.patch diff --git a/patches/server/0181-Flag-to-disable-the-channel-limit.patch b/patches/unapplied/0181-Flag-to-disable-the-channel-limit.patch similarity index 100% rename from patches/server/0181-Flag-to-disable-the-channel-limit.patch rename to patches/unapplied/0181-Flag-to-disable-the-channel-limit.patch diff --git a/patches/server/0182-Add-openSign-method-to-HumanEntity.patch b/patches/unapplied/0182-Add-openSign-method-to-HumanEntity.patch similarity index 100% rename from patches/server/0182-Add-openSign-method-to-HumanEntity.patch rename to patches/unapplied/0182-Add-openSign-method-to-HumanEntity.patch diff --git a/patches/server/0183-Configurable-sprint-interruption-on-attack.patch b/patches/unapplied/0183-Configurable-sprint-interruption-on-attack.patch similarity index 100% rename from patches/server/0183-Configurable-sprint-interruption-on-attack.patch rename to patches/unapplied/0183-Configurable-sprint-interruption-on-attack.patch diff --git a/patches/server/0184-EndermanEscapeEvent.patch b/patches/unapplied/0184-EndermanEscapeEvent.patch similarity index 100% rename from patches/server/0184-EndermanEscapeEvent.patch rename to patches/unapplied/0184-EndermanEscapeEvent.patch diff --git a/patches/server/0185-Enderman.teleportRandomly.patch b/patches/unapplied/0185-Enderman.teleportRandomly.patch similarity index 100% rename from patches/server/0185-Enderman.teleportRandomly.patch rename to patches/unapplied/0185-Enderman.teleportRandomly.patch diff --git a/patches/server/0186-Block-Enderpearl-Travel-Exploit.patch b/patches/unapplied/0186-Block-Enderpearl-Travel-Exploit.patch similarity index 100% rename from patches/server/0186-Block-Enderpearl-Travel-Exploit.patch rename to patches/unapplied/0186-Block-Enderpearl-Travel-Exploit.patch diff --git a/patches/server/0187-Expand-World.spawnParticle-API-and-add-Builder.patch b/patches/unapplied/0187-Expand-World.spawnParticle-API-and-add-Builder.patch similarity index 100% rename from patches/server/0187-Expand-World.spawnParticle-API-and-add-Builder.patch rename to patches/unapplied/0187-Expand-World.spawnParticle-API-and-add-Builder.patch diff --git a/patches/server/0188-Fix-exploit-that-allowed-colored-signs-to-be-created.patch b/patches/unapplied/0188-Fix-exploit-that-allowed-colored-signs-to-be-created.patch similarity index 100% rename from patches/server/0188-Fix-exploit-that-allowed-colored-signs-to-be-created.patch rename to patches/unapplied/0188-Fix-exploit-that-allowed-colored-signs-to-be-created.patch diff --git a/patches/server/0189-EndermanAttackPlayerEvent.patch b/patches/unapplied/0189-EndermanAttackPlayerEvent.patch similarity index 100% rename from patches/server/0189-EndermanAttackPlayerEvent.patch rename to patches/unapplied/0189-EndermanAttackPlayerEvent.patch diff --git a/patches/server/0190-WitchConsumePotionEvent.patch b/patches/unapplied/0190-WitchConsumePotionEvent.patch similarity index 100% rename from patches/server/0190-WitchConsumePotionEvent.patch rename to patches/unapplied/0190-WitchConsumePotionEvent.patch diff --git a/patches/server/0191-WitchThrowPotionEvent.patch b/patches/unapplied/0191-WitchThrowPotionEvent.patch similarity index 100% rename from patches/server/0191-WitchThrowPotionEvent.patch rename to patches/unapplied/0191-WitchThrowPotionEvent.patch diff --git a/patches/server/0192-WitchReadyPotionEvent.patch b/patches/unapplied/0192-WitchReadyPotionEvent.patch similarity index 100% rename from patches/server/0192-WitchReadyPotionEvent.patch rename to patches/unapplied/0192-WitchReadyPotionEvent.patch diff --git a/patches/server/0193-ItemStack-getMaxItemUseDuration.patch b/patches/unapplied/0193-ItemStack-getMaxItemUseDuration.patch similarity index 100% rename from patches/server/0193-ItemStack-getMaxItemUseDuration.patch rename to patches/unapplied/0193-ItemStack-getMaxItemUseDuration.patch diff --git a/patches/server/0194-Add-EntityTeleportEndGatewayEvent.patch b/patches/unapplied/0194-Add-EntityTeleportEndGatewayEvent.patch similarity index 100% rename from patches/server/0194-Add-EntityTeleportEndGatewayEvent.patch rename to patches/unapplied/0194-Add-EntityTeleportEndGatewayEvent.patch diff --git a/patches/server/0195-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch b/patches/unapplied/0195-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch similarity index 100% rename from patches/server/0195-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch rename to patches/unapplied/0195-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch diff --git a/patches/server/0196-Fix-CraftEntity-hashCode.patch b/patches/unapplied/0196-Fix-CraftEntity-hashCode.patch similarity index 100% rename from patches/server/0196-Fix-CraftEntity-hashCode.patch rename to patches/unapplied/0196-Fix-CraftEntity-hashCode.patch diff --git a/patches/server/0197-Configurable-LootPool-luck-formula.patch b/patches/unapplied/0197-Configurable-LootPool-luck-formula.patch similarity index 100% rename from patches/server/0197-Configurable-LootPool-luck-formula.patch rename to patches/unapplied/0197-Configurable-LootPool-luck-formula.patch diff --git a/patches/server/0198-Print-Error-details-when-failing-to-save-player-data.patch b/patches/unapplied/0198-Print-Error-details-when-failing-to-save-player-data.patch similarity index 100% rename from patches/server/0198-Print-Error-details-when-failing-to-save-player-data.patch rename to patches/unapplied/0198-Print-Error-details-when-failing-to-save-player-data.patch diff --git a/patches/server/0199-Make-shield-blocking-delay-configurable.patch b/patches/unapplied/0199-Make-shield-blocking-delay-configurable.patch similarity index 100% rename from patches/server/0199-Make-shield-blocking-delay-configurable.patch rename to patches/unapplied/0199-Make-shield-blocking-delay-configurable.patch diff --git a/patches/server/0200-Improve-EntityShootBowEvent.patch b/patches/unapplied/0200-Improve-EntityShootBowEvent.patch similarity index 100% rename from patches/server/0200-Improve-EntityShootBowEvent.patch rename to patches/unapplied/0200-Improve-EntityShootBowEvent.patch diff --git a/patches/server/0201-PlayerReadyArrowEvent.patch b/patches/unapplied/0201-PlayerReadyArrowEvent.patch similarity index 100% rename from patches/server/0201-PlayerReadyArrowEvent.patch rename to patches/unapplied/0201-PlayerReadyArrowEvent.patch diff --git a/patches/server/0202-Add-entity-knockback-events.patch b/patches/unapplied/0202-Add-entity-knockback-events.patch similarity index 100% rename from patches/server/0202-Add-entity-knockback-events.patch rename to patches/unapplied/0202-Add-entity-knockback-events.patch diff --git a/patches/server/0203-Expand-Explosions-API.patch b/patches/unapplied/0203-Expand-Explosions-API.patch similarity index 100% rename from patches/server/0203-Expand-Explosions-API.patch rename to patches/unapplied/0203-Expand-Explosions-API.patch diff --git a/patches/server/0204-LivingEntity-Active-Item-API.patch b/patches/unapplied/0204-LivingEntity-Active-Item-API.patch similarity index 100% rename from patches/server/0204-LivingEntity-Active-Item-API.patch rename to patches/unapplied/0204-LivingEntity-Active-Item-API.patch diff --git a/patches/server/0205-RangedEntity-API.patch b/patches/unapplied/0205-RangedEntity-API.patch similarity index 100% rename from patches/server/0205-RangedEntity-API.patch rename to patches/unapplied/0205-RangedEntity-API.patch diff --git a/patches/server/0206-Add-config-to-disable-ender-dragon-legacy-check.patch b/patches/unapplied/0206-Add-config-to-disable-ender-dragon-legacy-check.patch similarity index 100% rename from patches/server/0206-Add-config-to-disable-ender-dragon-legacy-check.patch rename to patches/unapplied/0206-Add-config-to-disable-ender-dragon-legacy-check.patch diff --git a/patches/server/0207-Implement-World.getEntity-UUID-API.patch b/patches/unapplied/0207-Implement-World.getEntity-UUID-API.patch similarity index 100% rename from patches/server/0207-Implement-World.getEntity-UUID-API.patch rename to patches/unapplied/0207-Implement-World.getEntity-UUID-API.patch diff --git a/patches/server/0208-InventoryCloseEvent-Reason-API.patch b/patches/unapplied/0208-InventoryCloseEvent-Reason-API.patch similarity index 100% rename from patches/server/0208-InventoryCloseEvent-Reason-API.patch rename to patches/unapplied/0208-InventoryCloseEvent-Reason-API.patch diff --git a/patches/server/0209-Vex-get-setSummoner-API.patch b/patches/unapplied/0209-Vex-get-setSummoner-API.patch similarity index 100% rename from patches/server/0209-Vex-get-setSummoner-API.patch rename to patches/unapplied/0209-Vex-get-setSummoner-API.patch diff --git a/patches/server/0210-add-more-information-to-Entity.toString.patch b/patches/unapplied/0210-add-more-information-to-Entity.toString.patch similarity index 100% rename from patches/server/0210-add-more-information-to-Entity.toString.patch rename to patches/unapplied/0210-add-more-information-to-Entity.toString.patch diff --git a/patches/server/0211-EnderDragon-Events.patch b/patches/unapplied/0211-EnderDragon-Events.patch similarity index 100% rename from patches/server/0211-EnderDragon-Events.patch rename to patches/unapplied/0211-EnderDragon-Events.patch diff --git a/patches/server/0212-PlayerElytraBoostEvent.patch b/patches/unapplied/0212-PlayerElytraBoostEvent.patch similarity index 100% rename from patches/server/0212-PlayerElytraBoostEvent.patch rename to patches/unapplied/0212-PlayerElytraBoostEvent.patch diff --git a/patches/server/0213-PlayerLaunchProjectileEvent.patch b/patches/unapplied/0213-PlayerLaunchProjectileEvent.patch similarity index 100% rename from patches/server/0213-PlayerLaunchProjectileEvent.patch rename to patches/unapplied/0213-PlayerLaunchProjectileEvent.patch diff --git a/patches/server/0214-Improve-BlockPosition-inlining.patch b/patches/unapplied/0214-Improve-BlockPosition-inlining.patch similarity index 100% rename from patches/server/0214-Improve-BlockPosition-inlining.patch rename to patches/unapplied/0214-Improve-BlockPosition-inlining.patch diff --git a/patches/server/0215-Option-to-prevent-armor-stands-from-doing-entity-loo.patch b/patches/unapplied/0215-Option-to-prevent-armor-stands-from-doing-entity-loo.patch similarity index 100% rename from patches/server/0215-Option-to-prevent-armor-stands-from-doing-entity-loo.patch rename to patches/unapplied/0215-Option-to-prevent-armor-stands-from-doing-entity-loo.patch diff --git a/patches/server/0216-Vanished-players-don-t-have-rights.patch b/patches/unapplied/0216-Vanished-players-don-t-have-rights.patch similarity index 100% rename from patches/server/0216-Vanished-players-don-t-have-rights.patch rename to patches/unapplied/0216-Vanished-players-don-t-have-rights.patch diff --git a/patches/server/0217-Allow-disabling-armor-stand-ticking.patch b/patches/unapplied/0217-Allow-disabling-armor-stand-ticking.patch similarity index 100% rename from patches/server/0217-Allow-disabling-armor-stand-ticking.patch rename to patches/unapplied/0217-Allow-disabling-armor-stand-ticking.patch diff --git a/patches/server/0218-SkeletonHorse-Additions.patch b/patches/unapplied/0218-SkeletonHorse-Additions.patch similarity index 100% rename from patches/server/0218-SkeletonHorse-Additions.patch rename to patches/unapplied/0218-SkeletonHorse-Additions.patch diff --git a/patches/server/0219-Expand-ArmorStand-API.patch b/patches/unapplied/0219-Expand-ArmorStand-API.patch similarity index 100% rename from patches/server/0219-Expand-ArmorStand-API.patch rename to patches/unapplied/0219-Expand-ArmorStand-API.patch diff --git a/patches/server/0220-AnvilDamageEvent.patch b/patches/unapplied/0220-AnvilDamageEvent.patch similarity index 100% rename from patches/server/0220-AnvilDamageEvent.patch rename to patches/unapplied/0220-AnvilDamageEvent.patch diff --git a/patches/server/0221-Add-TNTPrimeEvent.patch b/patches/unapplied/0221-Add-TNTPrimeEvent.patch similarity index 100% rename from patches/server/0221-Add-TNTPrimeEvent.patch rename to patches/unapplied/0221-Add-TNTPrimeEvent.patch diff --git a/patches/server/0222-Break-up-and-make-tab-spam-limits-configurable.patch b/patches/unapplied/0222-Break-up-and-make-tab-spam-limits-configurable.patch similarity index 100% rename from patches/server/0222-Break-up-and-make-tab-spam-limits-configurable.patch rename to patches/unapplied/0222-Break-up-and-make-tab-spam-limits-configurable.patch diff --git a/patches/server/0223-Fix-NBT-type-issues.patch b/patches/unapplied/0223-Fix-NBT-type-issues.patch similarity index 100% rename from patches/server/0223-Fix-NBT-type-issues.patch rename to patches/unapplied/0223-Fix-NBT-type-issues.patch diff --git a/patches/server/0224-Remove-unnecessary-itemmeta-handling.patch b/patches/unapplied/0224-Remove-unnecessary-itemmeta-handling.patch similarity index 100% rename from patches/server/0224-Remove-unnecessary-itemmeta-handling.patch rename to patches/unapplied/0224-Remove-unnecessary-itemmeta-handling.patch diff --git a/patches/server/0225-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch b/patches/unapplied/0225-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch similarity index 100% rename from patches/server/0225-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch rename to patches/unapplied/0225-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch diff --git a/patches/server/0226-Add-Early-Warning-Feature-to-WatchDog.patch b/patches/unapplied/0226-Add-Early-Warning-Feature-to-WatchDog.patch similarity index 100% rename from patches/server/0226-Add-Early-Warning-Feature-to-WatchDog.patch rename to patches/unapplied/0226-Add-Early-Warning-Feature-to-WatchDog.patch diff --git a/patches/server/0227-Use-ConcurrentHashMap-in-JsonList.patch b/patches/unapplied/0227-Use-ConcurrentHashMap-in-JsonList.patch similarity index 100% rename from patches/server/0227-Use-ConcurrentHashMap-in-JsonList.patch rename to patches/unapplied/0227-Use-ConcurrentHashMap-in-JsonList.patch diff --git a/patches/server/0228-Use-a-Queue-for-Queueing-Commands.patch b/patches/unapplied/0228-Use-a-Queue-for-Queueing-Commands.patch similarity index 100% rename from patches/server/0228-Use-a-Queue-for-Queueing-Commands.patch rename to patches/unapplied/0228-Use-a-Queue-for-Queueing-Commands.patch diff --git a/patches/server/0229-Ability-to-get-block-entities-from-a-chunk-without-s.patch b/patches/unapplied/0229-Ability-to-get-block-entities-from-a-chunk-without-s.patch similarity index 100% rename from patches/server/0229-Ability-to-get-block-entities-from-a-chunk-without-s.patch rename to patches/unapplied/0229-Ability-to-get-block-entities-from-a-chunk-without-s.patch diff --git a/patches/server/0230-Optimize-BlockPosition-helper-methods.patch b/patches/unapplied/0230-Optimize-BlockPosition-helper-methods.patch similarity index 100% rename from patches/server/0230-Optimize-BlockPosition-helper-methods.patch rename to patches/unapplied/0230-Optimize-BlockPosition-helper-methods.patch diff --git a/patches/server/0231-Restore-vanilla-default-mob-spawn-range-and-water-an.patch b/patches/unapplied/0231-Restore-vanilla-default-mob-spawn-range-and-water-an.patch similarity index 100% rename from patches/server/0231-Restore-vanilla-default-mob-spawn-range-and-water-an.patch rename to patches/unapplied/0231-Restore-vanilla-default-mob-spawn-range-and-water-an.patch diff --git a/patches/server/0232-Slime-Pathfinder-Events.patch b/patches/unapplied/0232-Slime-Pathfinder-Events.patch similarity index 100% rename from patches/server/0232-Slime-Pathfinder-Events.patch rename to patches/unapplied/0232-Slime-Pathfinder-Events.patch diff --git a/patches/server/0233-Configurable-speed-for-water-flowing-over-lava.patch b/patches/unapplied/0233-Configurable-speed-for-water-flowing-over-lava.patch similarity index 100% rename from patches/server/0233-Configurable-speed-for-water-flowing-over-lava.patch rename to patches/unapplied/0233-Configurable-speed-for-water-flowing-over-lava.patch diff --git a/patches/server/0234-Optimize-CraftBlockData-Creation.patch b/patches/unapplied/0234-Optimize-CraftBlockData-Creation.patch similarity index 100% rename from patches/server/0234-Optimize-CraftBlockData-Creation.patch rename to patches/unapplied/0234-Optimize-CraftBlockData-Creation.patch diff --git a/patches/server/0235-Optimize-MappedRegistry.patch b/patches/unapplied/0235-Optimize-MappedRegistry.patch similarity index 100% rename from patches/server/0235-Optimize-MappedRegistry.patch rename to patches/unapplied/0235-Optimize-MappedRegistry.patch diff --git a/patches/server/0236-Add-PhantomPreSpawnEvent.patch b/patches/unapplied/0236-Add-PhantomPreSpawnEvent.patch similarity index 100% rename from patches/server/0236-Add-PhantomPreSpawnEvent.patch rename to patches/unapplied/0236-Add-PhantomPreSpawnEvent.patch diff --git a/patches/server/0237-Add-More-Creeper-API.patch b/patches/unapplied/0237-Add-More-Creeper-API.patch similarity index 100% rename from patches/server/0237-Add-More-Creeper-API.patch rename to patches/unapplied/0237-Add-More-Creeper-API.patch diff --git a/patches/server/0238-Inventory-removeItemAnySlot.patch b/patches/unapplied/0238-Inventory-removeItemAnySlot.patch similarity index 100% rename from patches/server/0238-Inventory-removeItemAnySlot.patch rename to patches/unapplied/0238-Inventory-removeItemAnySlot.patch diff --git a/patches/server/0239-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch b/patches/unapplied/0239-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch similarity index 100% rename from patches/server/0239-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch rename to patches/unapplied/0239-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch diff --git a/patches/server/0240-Add-ray-tracing-methods-to-LivingEntity.patch b/patches/unapplied/0240-Add-ray-tracing-methods-to-LivingEntity.patch similarity index 100% rename from patches/server/0240-Add-ray-tracing-methods-to-LivingEntity.patch rename to patches/unapplied/0240-Add-ray-tracing-methods-to-LivingEntity.patch diff --git a/patches/server/0241-Expose-attack-cooldown-methods-for-Player.patch b/patches/unapplied/0241-Expose-attack-cooldown-methods-for-Player.patch similarity index 100% rename from patches/server/0241-Expose-attack-cooldown-methods-for-Player.patch rename to patches/unapplied/0241-Expose-attack-cooldown-methods-for-Player.patch diff --git a/patches/server/0242-Improve-death-events.patch b/patches/unapplied/0242-Improve-death-events.patch similarity index 100% rename from patches/server/0242-Improve-death-events.patch rename to patches/unapplied/0242-Improve-death-events.patch diff --git a/patches/server/0243-Allow-chests-to-be-placed-with-NBT-data.patch b/patches/unapplied/0243-Allow-chests-to-be-placed-with-NBT-data.patch similarity index 100% rename from patches/server/0243-Allow-chests-to-be-placed-with-NBT-data.patch rename to patches/unapplied/0243-Allow-chests-to-be-placed-with-NBT-data.patch diff --git a/patches/server/0244-Mob-Pathfinding-API.patch b/patches/unapplied/0244-Mob-Pathfinding-API.patch similarity index 100% rename from patches/server/0244-Mob-Pathfinding-API.patch rename to patches/unapplied/0244-Mob-Pathfinding-API.patch diff --git a/patches/server/0245-Prevent-various-interactions-from-causing-chunk-load.patch b/patches/unapplied/0245-Prevent-various-interactions-from-causing-chunk-load.patch similarity index 100% rename from patches/server/0245-Prevent-various-interactions-from-causing-chunk-load.patch rename to patches/unapplied/0245-Prevent-various-interactions-from-causing-chunk-load.patch diff --git a/patches/server/0246-Prevent-mob-spawning-from-loading-generating-chunks.patch b/patches/unapplied/0246-Prevent-mob-spawning-from-loading-generating-chunks.patch similarity index 100% rename from patches/server/0246-Prevent-mob-spawning-from-loading-generating-chunks.patch rename to patches/unapplied/0246-Prevent-mob-spawning-from-loading-generating-chunks.patch diff --git a/patches/server/0247-Implement-furnace-cook-speed-multiplier-API.patch b/patches/unapplied/0247-Implement-furnace-cook-speed-multiplier-API.patch similarity index 100% rename from patches/server/0247-Implement-furnace-cook-speed-multiplier-API.patch rename to patches/unapplied/0247-Implement-furnace-cook-speed-multiplier-API.patch diff --git a/patches/server/0248-Honor-EntityAgeable.ageLock.patch b/patches/unapplied/0248-Honor-EntityAgeable.ageLock.patch similarity index 100% rename from patches/server/0248-Honor-EntityAgeable.ageLock.patch rename to patches/unapplied/0248-Honor-EntityAgeable.ageLock.patch diff --git a/patches/server/0249-Configurable-connection-throttle-kick-message.patch b/patches/unapplied/0249-Configurable-connection-throttle-kick-message.patch similarity index 100% rename from patches/server/0249-Configurable-connection-throttle-kick-message.patch rename to patches/unapplied/0249-Configurable-connection-throttle-kick-message.patch diff --git a/patches/server/0250-Prevent-chunk-loading-from-Fluid-Flowing.patch b/patches/unapplied/0250-Prevent-chunk-loading-from-Fluid-Flowing.patch similarity index 100% rename from patches/server/0250-Prevent-chunk-loading-from-Fluid-Flowing.patch rename to patches/unapplied/0250-Prevent-chunk-loading-from-Fluid-Flowing.patch diff --git a/patches/server/0251-PreSpawnerSpawnEvent.patch b/patches/unapplied/0251-PreSpawnerSpawnEvent.patch similarity index 100% rename from patches/server/0251-PreSpawnerSpawnEvent.patch rename to patches/unapplied/0251-PreSpawnerSpawnEvent.patch diff --git a/patches/server/0252-Add-LivingEntity-getTargetEntity.patch b/patches/unapplied/0252-Add-LivingEntity-getTargetEntity.patch similarity index 100% rename from patches/server/0252-Add-LivingEntity-getTargetEntity.patch rename to patches/unapplied/0252-Add-LivingEntity-getTargetEntity.patch diff --git a/patches/server/0253-Add-sun-related-API.patch b/patches/unapplied/0253-Add-sun-related-API.patch similarity index 100% rename from patches/server/0253-Add-sun-related-API.patch rename to patches/unapplied/0253-Add-sun-related-API.patch diff --git a/patches/server/0254-Turtle-API.patch b/patches/unapplied/0254-Turtle-API.patch similarity index 100% rename from patches/server/0254-Turtle-API.patch rename to patches/unapplied/0254-Turtle-API.patch diff --git a/patches/server/0255-Call-player-spectator-target-events-and-improve-impl.patch b/patches/unapplied/0255-Call-player-spectator-target-events-and-improve-impl.patch similarity index 100% rename from patches/server/0255-Call-player-spectator-target-events-and-improve-impl.patch rename to patches/unapplied/0255-Call-player-spectator-target-events-and-improve-impl.patch diff --git a/patches/server/0256-Add-more-Witch-API.patch b/patches/unapplied/0256-Add-more-Witch-API.patch similarity index 100% rename from patches/server/0256-Add-more-Witch-API.patch rename to patches/unapplied/0256-Add-more-Witch-API.patch diff --git a/patches/server/0257-Check-Drowned-for-Villager-Aggression-Config.patch b/patches/unapplied/0257-Check-Drowned-for-Villager-Aggression-Config.patch similarity index 100% rename from patches/server/0257-Check-Drowned-for-Villager-Aggression-Config.patch rename to patches/unapplied/0257-Check-Drowned-for-Villager-Aggression-Config.patch diff --git a/patches/server/0258-Add-option-to-prevent-players-from-moving-into-unloa.patch b/patches/unapplied/0258-Add-option-to-prevent-players-from-moving-into-unloa.patch similarity index 100% rename from patches/server/0258-Add-option-to-prevent-players-from-moving-into-unloa.patch rename to patches/unapplied/0258-Add-option-to-prevent-players-from-moving-into-unloa.patch diff --git a/patches/server/0259-Reset-players-airTicks-on-respawn.patch b/patches/unapplied/0259-Reset-players-airTicks-on-respawn.patch similarity index 100% rename from patches/server/0259-Reset-players-airTicks-on-respawn.patch rename to patches/unapplied/0259-Reset-players-airTicks-on-respawn.patch diff --git a/patches/server/0260-Don-t-sleep-after-profile-lookups-if-not-needed.patch b/patches/unapplied/0260-Don-t-sleep-after-profile-lookups-if-not-needed.patch similarity index 100% rename from patches/server/0260-Don-t-sleep-after-profile-lookups-if-not-needed.patch rename to patches/unapplied/0260-Don-t-sleep-after-profile-lookups-if-not-needed.patch diff --git a/patches/server/0261-Improve-Server-Thread-Pool-and-Thread-Priorities.patch b/patches/unapplied/0261-Improve-Server-Thread-Pool-and-Thread-Priorities.patch similarity index 100% rename from patches/server/0261-Improve-Server-Thread-Pool-and-Thread-Priorities.patch rename to patches/unapplied/0261-Improve-Server-Thread-Pool-and-Thread-Priorities.patch diff --git a/patches/server/0262-Optimize-World-Time-Updates.patch b/patches/unapplied/0262-Optimize-World-Time-Updates.patch similarity index 100% rename from patches/server/0262-Optimize-World-Time-Updates.patch rename to patches/unapplied/0262-Optimize-World-Time-Updates.patch diff --git a/patches/server/0263-Restore-custom-InventoryHolder-support.patch b/patches/unapplied/0263-Restore-custom-InventoryHolder-support.patch similarity index 100% rename from patches/server/0263-Restore-custom-InventoryHolder-support.patch rename to patches/unapplied/0263-Restore-custom-InventoryHolder-support.patch diff --git a/patches/server/0264-Fix-SpongeAbsortEvent-handling.patch b/patches/unapplied/0264-Fix-SpongeAbsortEvent-handling.patch similarity index 100% rename from patches/server/0264-Fix-SpongeAbsortEvent-handling.patch rename to patches/unapplied/0264-Fix-SpongeAbsortEvent-handling.patch diff --git a/patches/server/0265-Don-t-allow-digging-into-unloaded-chunks.patch b/patches/unapplied/0265-Don-t-allow-digging-into-unloaded-chunks.patch similarity index 100% rename from patches/server/0265-Don-t-allow-digging-into-unloaded-chunks.patch rename to patches/unapplied/0265-Don-t-allow-digging-into-unloaded-chunks.patch diff --git a/patches/server/0266-Make-the-default-permission-message-configurable.patch b/patches/unapplied/0266-Make-the-default-permission-message-configurable.patch similarity index 100% rename from patches/server/0266-Make-the-default-permission-message-configurable.patch rename to patches/unapplied/0266-Make-the-default-permission-message-configurable.patch diff --git a/patches/server/0267-force-entity-dismount-during-teleportation.patch b/patches/unapplied/0267-force-entity-dismount-during-teleportation.patch similarity index 100% rename from patches/server/0267-force-entity-dismount-during-teleportation.patch rename to patches/unapplied/0267-force-entity-dismount-during-teleportation.patch diff --git a/patches/server/0268-Add-more-Zombie-API.patch b/patches/unapplied/0268-Add-more-Zombie-API.patch similarity index 100% rename from patches/server/0268-Add-more-Zombie-API.patch rename to patches/unapplied/0268-Add-more-Zombie-API.patch diff --git a/patches/server/0269-Book-size-limits.patch b/patches/unapplied/0269-Book-size-limits.patch similarity index 100% rename from patches/server/0269-Book-size-limits.patch rename to patches/unapplied/0269-Book-size-limits.patch diff --git a/patches/server/0270-Add-PlayerConnectionCloseEvent.patch b/patches/unapplied/0270-Add-PlayerConnectionCloseEvent.patch similarity index 100% rename from patches/server/0270-Add-PlayerConnectionCloseEvent.patch rename to patches/unapplied/0270-Add-PlayerConnectionCloseEvent.patch diff --git a/patches/server/0271-Replace-OfflinePlayer-getLastPlayed.patch b/patches/unapplied/0271-Replace-OfflinePlayer-getLastPlayed.patch similarity index 100% rename from patches/server/0271-Replace-OfflinePlayer-getLastPlayed.patch rename to patches/unapplied/0271-Replace-OfflinePlayer-getLastPlayed.patch diff --git a/patches/server/0272-Workaround-for-vehicle-tracking-issue-on-disconnect.patch b/patches/unapplied/0272-Workaround-for-vehicle-tracking-issue-on-disconnect.patch similarity index 100% rename from patches/server/0272-Workaround-for-vehicle-tracking-issue-on-disconnect.patch rename to patches/unapplied/0272-Workaround-for-vehicle-tracking-issue-on-disconnect.patch diff --git a/patches/server/0273-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch b/patches/unapplied/0273-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch similarity index 100% rename from patches/server/0273-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch rename to patches/unapplied/0273-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch diff --git a/patches/server/0274-BlockDestroyEvent.patch b/patches/unapplied/0274-BlockDestroyEvent.patch similarity index 100% rename from patches/server/0274-BlockDestroyEvent.patch rename to patches/unapplied/0274-BlockDestroyEvent.patch diff --git a/patches/server/0275-Async-command-map-building.patch b/patches/unapplied/0275-Async-command-map-building.patch similarity index 100% rename from patches/server/0275-Async-command-map-building.patch rename to patches/unapplied/0275-Async-command-map-building.patch diff --git a/patches/server/0276-Brigadier-Mojang-API.patch b/patches/unapplied/0276-Brigadier-Mojang-API.patch similarity index 100% rename from patches/server/0276-Brigadier-Mojang-API.patch rename to patches/unapplied/0276-Brigadier-Mojang-API.patch diff --git a/patches/server/0277-Improve-exact-choice-recipe-ingredients.patch b/patches/unapplied/0277-Improve-exact-choice-recipe-ingredients.patch similarity index 100% rename from patches/server/0277-Improve-exact-choice-recipe-ingredients.patch rename to patches/unapplied/0277-Improve-exact-choice-recipe-ingredients.patch diff --git a/patches/server/0278-Limit-Client-Sign-length-more.patch b/patches/unapplied/0278-Limit-Client-Sign-length-more.patch similarity index 100% rename from patches/server/0278-Limit-Client-Sign-length-more.patch rename to patches/unapplied/0278-Limit-Client-Sign-length-more.patch diff --git a/patches/server/0279-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch b/patches/unapplied/0279-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch similarity index 100% rename from patches/server/0279-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch rename to patches/unapplied/0279-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch diff --git a/patches/server/0280-Fixes-and-additions-to-the-spawn-reason-API.patch b/patches/unapplied/0280-Fixes-and-additions-to-the-spawn-reason-API.patch similarity index 100% rename from patches/server/0280-Fixes-and-additions-to-the-spawn-reason-API.patch rename to patches/unapplied/0280-Fixes-and-additions-to-the-spawn-reason-API.patch diff --git a/patches/server/0281-Fire-event-on-GS4-query.patch b/patches/unapplied/0281-Fire-event-on-GS4-query.patch similarity index 100% rename from patches/server/0281-Fire-event-on-GS4-query.patch rename to patches/unapplied/0281-Fire-event-on-GS4-query.patch diff --git a/patches/server/0282-Add-PlayerPostRespawnEvent.patch b/patches/unapplied/0282-Add-PlayerPostRespawnEvent.patch similarity index 100% rename from patches/server/0282-Add-PlayerPostRespawnEvent.patch rename to patches/unapplied/0282-Add-PlayerPostRespawnEvent.patch diff --git a/patches/server/0283-Server-Tick-Events.patch b/patches/unapplied/0283-Server-Tick-Events.patch similarity index 100% rename from patches/server/0283-Server-Tick-Events.patch rename to patches/unapplied/0283-Server-Tick-Events.patch diff --git a/patches/server/0284-PlayerDeathEvent-getItemsToKeep.patch b/patches/unapplied/0284-PlayerDeathEvent-getItemsToKeep.patch similarity index 100% rename from patches/server/0284-PlayerDeathEvent-getItemsToKeep.patch rename to patches/unapplied/0284-PlayerDeathEvent-getItemsToKeep.patch diff --git a/patches/server/0285-Optimize-Captured-BlockEntity-Lookup.patch b/patches/unapplied/0285-Optimize-Captured-BlockEntity-Lookup.patch similarity index 100% rename from patches/server/0285-Optimize-Captured-BlockEntity-Lookup.patch rename to patches/unapplied/0285-Optimize-Captured-BlockEntity-Lookup.patch diff --git a/patches/server/0286-Mob-Spawner-API-Enhancements.patch b/patches/unapplied/0286-Mob-Spawner-API-Enhancements.patch similarity index 100% rename from patches/server/0286-Mob-Spawner-API-Enhancements.patch rename to patches/unapplied/0286-Mob-Spawner-API-Enhancements.patch diff --git a/patches/server/0287-Fix-CB-call-to-changed-postToMainThread-method.patch b/patches/unapplied/0287-Fix-CB-call-to-changed-postToMainThread-method.patch similarity index 100% rename from patches/server/0287-Fix-CB-call-to-changed-postToMainThread-method.patch rename to patches/unapplied/0287-Fix-CB-call-to-changed-postToMainThread-method.patch diff --git a/patches/server/0288-Fix-sounds-when-item-frames-are-modified-MC-123450.patch b/patches/unapplied/0288-Fix-sounds-when-item-frames-are-modified-MC-123450.patch similarity index 100% rename from patches/server/0288-Fix-sounds-when-item-frames-are-modified-MC-123450.patch rename to patches/unapplied/0288-Fix-sounds-when-item-frames-are-modified-MC-123450.patch diff --git a/patches/server/0289-Implement-CraftBlockSoundGroup.patch b/patches/unapplied/0289-Implement-CraftBlockSoundGroup.patch similarity index 100% rename from patches/server/0289-Implement-CraftBlockSoundGroup.patch rename to patches/unapplied/0289-Implement-CraftBlockSoundGroup.patch diff --git a/patches/server/0290-Expose-the-internal-current-tick.patch b/patches/unapplied/0290-Expose-the-internal-current-tick.patch similarity index 100% rename from patches/server/0290-Expose-the-internal-current-tick.patch rename to patches/unapplied/0290-Expose-the-internal-current-tick.patch diff --git a/patches/server/0291-Show-blockstate-location-if-we-failed-to-read-it.patch b/patches/unapplied/0291-Show-blockstate-location-if-we-failed-to-read-it.patch similarity index 100% rename from patches/server/0291-Show-blockstate-location-if-we-failed-to-read-it.patch rename to patches/unapplied/0291-Show-blockstate-location-if-we-failed-to-read-it.patch diff --git a/patches/server/0292-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch b/patches/unapplied/0292-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch similarity index 100% rename from patches/server/0292-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch rename to patches/unapplied/0292-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch diff --git a/patches/server/0293-Configurable-projectile-relative-velocity.patch b/patches/unapplied/0293-Configurable-projectile-relative-velocity.patch similarity index 100% rename from patches/server/0293-Configurable-projectile-relative-velocity.patch rename to patches/unapplied/0293-Configurable-projectile-relative-velocity.patch diff --git a/patches/server/0294-offset-item-frame-ticking.patch b/patches/unapplied/0294-offset-item-frame-ticking.patch similarity index 100% rename from patches/server/0294-offset-item-frame-ticking.patch rename to patches/unapplied/0294-offset-item-frame-ticking.patch diff --git a/patches/server/0295-Prevent-consuming-the-wrong-itemstack.patch b/patches/unapplied/0295-Prevent-consuming-the-wrong-itemstack.patch similarity index 100% rename from patches/server/0295-Prevent-consuming-the-wrong-itemstack.patch rename to patches/unapplied/0295-Prevent-consuming-the-wrong-itemstack.patch diff --git a/patches/server/0296-Dont-send-unnecessary-sign-update.patch b/patches/unapplied/0296-Dont-send-unnecessary-sign-update.patch similarity index 100% rename from patches/server/0296-Dont-send-unnecessary-sign-update.patch rename to patches/unapplied/0296-Dont-send-unnecessary-sign-update.patch diff --git a/patches/server/0297-Add-option-to-disable-pillager-patrols.patch b/patches/unapplied/0297-Add-option-to-disable-pillager-patrols.patch similarity index 100% rename from patches/server/0297-Add-option-to-disable-pillager-patrols.patch rename to patches/unapplied/0297-Add-option-to-disable-pillager-patrols.patch diff --git a/patches/server/0298-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch b/patches/unapplied/0298-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch similarity index 100% rename from patches/server/0298-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch rename to patches/unapplied/0298-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch diff --git a/patches/server/0299-MC-145656-Fix-Follow-Range-Initial-Target.patch b/patches/unapplied/0299-MC-145656-Fix-Follow-Range-Initial-Target.patch similarity index 100% rename from patches/server/0299-MC-145656-Fix-Follow-Range-Initial-Target.patch rename to patches/unapplied/0299-MC-145656-Fix-Follow-Range-Initial-Target.patch diff --git a/patches/server/0300-Duplicate-UUID-Resolve-Option.patch b/patches/unapplied/0300-Duplicate-UUID-Resolve-Option.patch similarity index 100% rename from patches/server/0300-Duplicate-UUID-Resolve-Option.patch rename to patches/unapplied/0300-Duplicate-UUID-Resolve-Option.patch diff --git a/patches/server/0301-PlayerDeathEvent-shouldDropExperience.patch b/patches/unapplied/0301-PlayerDeathEvent-shouldDropExperience.patch similarity index 100% rename from patches/server/0301-PlayerDeathEvent-shouldDropExperience.patch rename to patches/unapplied/0301-PlayerDeathEvent-shouldDropExperience.patch diff --git a/patches/server/0302-Prevent-bees-loading-chunks-checking-hive-position.patch b/patches/unapplied/0302-Prevent-bees-loading-chunks-checking-hive-position.patch similarity index 100% rename from patches/server/0302-Prevent-bees-loading-chunks-checking-hive-position.patch rename to patches/unapplied/0302-Prevent-bees-loading-chunks-checking-hive-position.patch diff --git a/patches/server/0303-Don-t-load-Chunks-from-Hoppers-and-other-things.patch b/patches/unapplied/0303-Don-t-load-Chunks-from-Hoppers-and-other-things.patch similarity index 100% rename from patches/server/0303-Don-t-load-Chunks-from-Hoppers-and-other-things.patch rename to patches/unapplied/0303-Don-t-load-Chunks-from-Hoppers-and-other-things.patch diff --git a/patches/server/0304-Optimise-EntityGetter-getPlayerByUUID.patch b/patches/unapplied/0304-Optimise-EntityGetter-getPlayerByUUID.patch similarity index 100% rename from patches/server/0304-Optimise-EntityGetter-getPlayerByUUID.patch rename to patches/unapplied/0304-Optimise-EntityGetter-getPlayerByUUID.patch diff --git a/patches/server/0305-Fix-items-not-falling-correctly.patch b/patches/unapplied/0305-Fix-items-not-falling-correctly.patch similarity index 100% rename from patches/server/0305-Fix-items-not-falling-correctly.patch rename to patches/unapplied/0305-Fix-items-not-falling-correctly.patch diff --git a/patches/server/0306-Optimize-call-to-getFluid-for-explosions.patch b/patches/unapplied/0306-Optimize-call-to-getFluid-for-explosions.patch similarity index 100% rename from patches/server/0306-Optimize-call-to-getFluid-for-explosions.patch rename to patches/unapplied/0306-Optimize-call-to-getFluid-for-explosions.patch diff --git a/patches/server/0307-Guard-against-serializing-mismatching-chunk-coordina.patch b/patches/unapplied/0307-Guard-against-serializing-mismatching-chunk-coordina.patch similarity index 100% rename from patches/server/0307-Guard-against-serializing-mismatching-chunk-coordina.patch rename to patches/unapplied/0307-Guard-against-serializing-mismatching-chunk-coordina.patch diff --git a/patches/server/0308-Alternative-item-despawn-rate.patch b/patches/unapplied/0308-Alternative-item-despawn-rate.patch similarity index 100% rename from patches/server/0308-Alternative-item-despawn-rate.patch rename to patches/unapplied/0308-Alternative-item-despawn-rate.patch diff --git a/patches/server/0309-Tracking-Range-Improvements.patch b/patches/unapplied/0309-Tracking-Range-Improvements.patch similarity index 100% rename from patches/server/0309-Tracking-Range-Improvements.patch rename to patches/unapplied/0309-Tracking-Range-Improvements.patch diff --git a/patches/server/0310-Bees-get-gravity-in-void.-Fixes-MC-167279.patch b/patches/unapplied/0310-Bees-get-gravity-in-void.-Fixes-MC-167279.patch similarity index 100% rename from patches/server/0310-Bees-get-gravity-in-void.-Fixes-MC-167279.patch rename to patches/unapplied/0310-Bees-get-gravity-in-void.-Fixes-MC-167279.patch diff --git a/patches/server/0311-Improve-Block-breakNaturally-API.patch b/patches/unapplied/0311-Improve-Block-breakNaturally-API.patch similarity index 100% rename from patches/server/0311-Improve-Block-breakNaturally-API.patch rename to patches/unapplied/0311-Improve-Block-breakNaturally-API.patch diff --git a/patches/server/0312-Optimise-getChunkAt-calls-for-loaded-chunks.patch b/patches/unapplied/0312-Optimise-getChunkAt-calls-for-loaded-chunks.patch similarity index 100% rename from patches/server/0312-Optimise-getChunkAt-calls-for-loaded-chunks.patch rename to patches/unapplied/0312-Optimise-getChunkAt-calls-for-loaded-chunks.patch diff --git a/patches/server/0313-Add-debug-for-sync-chunk-loads.patch b/patches/unapplied/0313-Add-debug-for-sync-chunk-loads.patch similarity index 100% rename from patches/server/0313-Add-debug-for-sync-chunk-loads.patch rename to patches/unapplied/0313-Add-debug-for-sync-chunk-loads.patch diff --git a/patches/server/0314-Improve-java-version-check.patch b/patches/unapplied/0314-Improve-java-version-check.patch similarity index 100% rename from patches/server/0314-Improve-java-version-check.patch rename to patches/unapplied/0314-Improve-java-version-check.patch diff --git a/patches/server/0315-Add-ThrownEggHatchEvent.patch b/patches/unapplied/0315-Add-ThrownEggHatchEvent.patch similarity index 100% rename from patches/server/0315-Add-ThrownEggHatchEvent.patch rename to patches/unapplied/0315-Add-ThrownEggHatchEvent.patch diff --git a/patches/server/0316-Entity-Jump-API.patch b/patches/unapplied/0316-Entity-Jump-API.patch similarity index 100% rename from patches/server/0316-Entity-Jump-API.patch rename to patches/unapplied/0316-Entity-Jump-API.patch diff --git a/patches/server/0317-Add-option-to-nerf-pigmen-from-nether-portals.patch b/patches/unapplied/0317-Add-option-to-nerf-pigmen-from-nether-portals.patch similarity index 100% rename from patches/server/0317-Add-option-to-nerf-pigmen-from-nether-portals.patch rename to patches/unapplied/0317-Add-option-to-nerf-pigmen-from-nether-portals.patch diff --git a/patches/server/0318-Make-the-GUI-graph-fancier.patch b/patches/unapplied/0318-Make-the-GUI-graph-fancier.patch similarity index 100% rename from patches/server/0318-Make-the-GUI-graph-fancier.patch rename to patches/unapplied/0318-Make-the-GUI-graph-fancier.patch diff --git a/patches/server/0319-add-hand-to-BlockMultiPlaceEvent.patch b/patches/unapplied/0319-add-hand-to-BlockMultiPlaceEvent.patch similarity index 100% rename from patches/server/0319-add-hand-to-BlockMultiPlaceEvent.patch rename to patches/unapplied/0319-add-hand-to-BlockMultiPlaceEvent.patch diff --git a/patches/server/0320-Validate-tripwire-hook-placement-before-update.patch b/patches/unapplied/0320-Validate-tripwire-hook-placement-before-update.patch similarity index 100% rename from patches/server/0320-Validate-tripwire-hook-placement-before-update.patch rename to patches/unapplied/0320-Validate-tripwire-hook-placement-before-update.patch diff --git a/patches/server/0321-Add-option-to-allow-iron-golems-to-spawn-in-air.patch b/patches/unapplied/0321-Add-option-to-allow-iron-golems-to-spawn-in-air.patch similarity index 100% rename from patches/server/0321-Add-option-to-allow-iron-golems-to-spawn-in-air.patch rename to patches/unapplied/0321-Add-option-to-allow-iron-golems-to-spawn-in-air.patch diff --git a/patches/server/0322-Configurable-chance-of-villager-zombie-infection.patch b/patches/unapplied/0322-Configurable-chance-of-villager-zombie-infection.patch similarity index 100% rename from patches/server/0322-Configurable-chance-of-villager-zombie-infection.patch rename to patches/unapplied/0322-Configurable-chance-of-villager-zombie-infection.patch diff --git a/patches/server/0323-Optimise-Chunk-getFluid.patch b/patches/unapplied/0323-Optimise-Chunk-getFluid.patch similarity index 100% rename from patches/server/0323-Optimise-Chunk-getFluid.patch rename to patches/unapplied/0323-Optimise-Chunk-getFluid.patch diff --git a/patches/server/0324-Set-spigots-verbose-world-setting-to-false-by-def.patch b/patches/unapplied/0324-Set-spigots-verbose-world-setting-to-false-by-def.patch similarity index 100% rename from patches/server/0324-Set-spigots-verbose-world-setting-to-false-by-def.patch rename to patches/unapplied/0324-Set-spigots-verbose-world-setting-to-false-by-def.patch diff --git a/patches/server/0325-Add-tick-times-API-and-mspt-command.patch b/patches/unapplied/0325-Add-tick-times-API-and-mspt-command.patch similarity index 100% rename from patches/server/0325-Add-tick-times-API-and-mspt-command.patch rename to patches/unapplied/0325-Add-tick-times-API-and-mspt-command.patch diff --git a/patches/server/0326-Expose-MinecraftServer-isRunning.patch b/patches/unapplied/0326-Expose-MinecraftServer-isRunning.patch similarity index 100% rename from patches/server/0326-Expose-MinecraftServer-isRunning.patch rename to patches/unapplied/0326-Expose-MinecraftServer-isRunning.patch diff --git a/patches/server/0327-Add-Raw-Byte-ItemStack-Serialization.patch b/patches/unapplied/0327-Add-Raw-Byte-ItemStack-Serialization.patch similarity index 100% rename from patches/server/0327-Add-Raw-Byte-ItemStack-Serialization.patch rename to patches/unapplied/0327-Add-Raw-Byte-ItemStack-Serialization.patch diff --git a/patches/server/0328-Pillager-patrol-spawn-settings-and-per-player-option.patch b/patches/unapplied/0328-Pillager-patrol-spawn-settings-and-per-player-option.patch similarity index 100% rename from patches/server/0328-Pillager-patrol-spawn-settings-and-per-player-option.patch rename to patches/unapplied/0328-Pillager-patrol-spawn-settings-and-per-player-option.patch diff --git a/patches/server/0329-Remote-Connections-shouldn-t-hold-up-shutdown.patch b/patches/unapplied/0329-Remote-Connections-shouldn-t-hold-up-shutdown.patch similarity index 100% rename from patches/server/0329-Remote-Connections-shouldn-t-hold-up-shutdown.patch rename to patches/unapplied/0329-Remote-Connections-shouldn-t-hold-up-shutdown.patch diff --git a/patches/server/0330-Do-not-allow-bees-to-load-chunks-for-beehives.patch b/patches/unapplied/0330-Do-not-allow-bees-to-load-chunks-for-beehives.patch similarity index 100% rename from patches/server/0330-Do-not-allow-bees-to-load-chunks-for-beehives.patch rename to patches/unapplied/0330-Do-not-allow-bees-to-load-chunks-for-beehives.patch diff --git a/patches/server/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch b/patches/unapplied/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch similarity index 100% rename from patches/server/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch rename to patches/unapplied/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch diff --git a/patches/server/0332-Don-t-tick-dead-players.patch b/patches/unapplied/0332-Don-t-tick-dead-players.patch similarity index 100% rename from patches/server/0332-Don-t-tick-dead-players.patch rename to patches/unapplied/0332-Don-t-tick-dead-players.patch diff --git a/patches/server/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch b/patches/unapplied/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch similarity index 100% rename from patches/server/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch rename to patches/unapplied/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch diff --git a/patches/server/0334-Don-t-move-existing-players-to-world-spawn.patch b/patches/unapplied/0334-Don-t-move-existing-players-to-world-spawn.patch similarity index 100% rename from patches/server/0334-Don-t-move-existing-players-to-world-spawn.patch rename to patches/unapplied/0334-Don-t-move-existing-players-to-world-spawn.patch diff --git a/patches/server/0335-Optimize-Pathfinding.patch b/patches/unapplied/0335-Optimize-Pathfinding.patch similarity index 100% rename from patches/server/0335-Optimize-Pathfinding.patch rename to patches/unapplied/0335-Optimize-Pathfinding.patch diff --git a/patches/server/0336-Reduce-Either-Optional-allocation.patch b/patches/unapplied/0336-Reduce-Either-Optional-allocation.patch similarity index 100% rename from patches/server/0336-Reduce-Either-Optional-allocation.patch rename to patches/unapplied/0336-Reduce-Either-Optional-allocation.patch diff --git a/patches/server/0337-Reduce-memory-footprint-of-CompoundTag.patch b/patches/unapplied/0337-Reduce-memory-footprint-of-CompoundTag.patch similarity index 100% rename from patches/server/0337-Reduce-memory-footprint-of-CompoundTag.patch rename to patches/unapplied/0337-Reduce-memory-footprint-of-CompoundTag.patch diff --git a/patches/server/0338-Prevent-opening-inventories-when-frozen.patch b/patches/unapplied/0338-Prevent-opening-inventories-when-frozen.patch similarity index 100% rename from patches/server/0338-Prevent-opening-inventories-when-frozen.patch rename to patches/unapplied/0338-Prevent-opening-inventories-when-frozen.patch diff --git a/patches/server/0339-Don-t-run-entity-collision-code-if-not-needed.patch b/patches/unapplied/0339-Don-t-run-entity-collision-code-if-not-needed.patch similarity index 100% rename from patches/server/0339-Don-t-run-entity-collision-code-if-not-needed.patch rename to patches/unapplied/0339-Don-t-run-entity-collision-code-if-not-needed.patch diff --git a/patches/server/0340-Implement-Player-Client-Options-API.patch b/patches/unapplied/0340-Implement-Player-Client-Options-API.patch similarity index 100% rename from patches/server/0340-Implement-Player-Client-Options-API.patch rename to patches/unapplied/0340-Implement-Player-Client-Options-API.patch diff --git a/patches/server/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch b/patches/unapplied/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch similarity index 100% rename from patches/server/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch rename to patches/unapplied/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch diff --git a/patches/server/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch b/patches/unapplied/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch similarity index 100% rename from patches/server/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch rename to patches/unapplied/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch diff --git a/patches/server/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch b/patches/unapplied/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch similarity index 100% rename from patches/server/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch rename to patches/unapplied/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch diff --git a/patches/server/0344-Add-PlayerAttackEntityCooldownResetEvent.patch b/patches/unapplied/0344-Add-PlayerAttackEntityCooldownResetEvent.patch similarity index 100% rename from patches/server/0344-Add-PlayerAttackEntityCooldownResetEvent.patch rename to patches/unapplied/0344-Add-PlayerAttackEntityCooldownResetEvent.patch diff --git a/patches/server/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch b/patches/unapplied/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch similarity index 100% rename from patches/server/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch rename to patches/unapplied/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch diff --git a/patches/server/0346-Add-phantom-creative-and-insomniac-controls.patch b/patches/unapplied/0346-Add-phantom-creative-and-insomniac-controls.patch similarity index 100% rename from patches/server/0346-Add-phantom-creative-and-insomniac-controls.patch rename to patches/unapplied/0346-Add-phantom-creative-and-insomniac-controls.patch diff --git a/patches/server/0347-Fix-item-duplication-and-teleport-issues.patch b/patches/unapplied/0347-Fix-item-duplication-and-teleport-issues.patch similarity index 100% rename from patches/server/0347-Fix-item-duplication-and-teleport-issues.patch rename to patches/unapplied/0347-Fix-item-duplication-and-teleport-issues.patch diff --git a/patches/server/0348-Villager-Restocks-API.patch b/patches/unapplied/0348-Villager-Restocks-API.patch similarity index 100% rename from patches/server/0348-Villager-Restocks-API.patch rename to patches/unapplied/0348-Villager-Restocks-API.patch diff --git a/patches/server/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch b/patches/unapplied/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch similarity index 100% rename from patches/server/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch rename to patches/unapplied/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch diff --git a/patches/server/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch b/patches/unapplied/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch similarity index 100% rename from patches/server/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch rename to patches/unapplied/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch diff --git a/patches/server/0351-misc-debugging-dumps.patch b/patches/unapplied/0351-misc-debugging-dumps.patch similarity index 100% rename from patches/server/0351-misc-debugging-dumps.patch rename to patches/unapplied/0351-misc-debugging-dumps.patch diff --git a/patches/server/0352-Prevent-teleporting-dead-entities.patch b/patches/unapplied/0352-Prevent-teleporting-dead-entities.patch similarity index 100% rename from patches/server/0352-Prevent-teleporting-dead-entities.patch rename to patches/unapplied/0352-Prevent-teleporting-dead-entities.patch diff --git a/patches/server/0353-Implement-Mob-Goal-API.patch b/patches/unapplied/0353-Implement-Mob-Goal-API.patch similarity index 100% rename from patches/server/0353-Implement-Mob-Goal-API.patch rename to patches/unapplied/0353-Implement-Mob-Goal-API.patch diff --git a/patches/server/0354-Add-villager-reputation-API.patch b/patches/unapplied/0354-Add-villager-reputation-API.patch similarity index 100% rename from patches/server/0354-Add-villager-reputation-API.patch rename to patches/unapplied/0354-Add-villager-reputation-API.patch diff --git a/patches/server/0355-ExperienceOrb-merging-stacking-API-and-fixes.patch b/patches/unapplied/0355-ExperienceOrb-merging-stacking-API-and-fixes.patch similarity index 100% rename from patches/server/0355-ExperienceOrb-merging-stacking-API-and-fixes.patch rename to patches/unapplied/0355-ExperienceOrb-merging-stacking-API-and-fixes.patch diff --git a/patches/server/0356-Fix-PotionEffect-ignores-icon-flag.patch b/patches/unapplied/0356-Fix-PotionEffect-ignores-icon-flag.patch similarity index 100% rename from patches/server/0356-Fix-PotionEffect-ignores-icon-flag.patch rename to patches/unapplied/0356-Fix-PotionEffect-ignores-icon-flag.patch diff --git a/patches/server/0357-Potential-bed-API.patch b/patches/unapplied/0357-Potential-bed-API.patch similarity index 100% rename from patches/server/0357-Potential-bed-API.patch rename to patches/unapplied/0357-Potential-bed-API.patch diff --git a/patches/server/0358-Wait-for-Async-Tasks-during-shutdown.patch b/patches/unapplied/0358-Wait-for-Async-Tasks-during-shutdown.patch similarity index 100% rename from patches/server/0358-Wait-for-Async-Tasks-during-shutdown.patch rename to patches/unapplied/0358-Wait-for-Async-Tasks-during-shutdown.patch diff --git a/patches/server/0359-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch b/patches/unapplied/0359-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch similarity index 100% rename from patches/server/0359-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch rename to patches/unapplied/0359-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch diff --git a/patches/server/0360-Add-option-for-console-having-all-permissions.patch b/patches/unapplied/0360-Add-option-for-console-having-all-permissions.patch similarity index 100% rename from patches/server/0360-Add-option-for-console-having-all-permissions.patch rename to patches/unapplied/0360-Add-option-for-console-having-all-permissions.patch diff --git a/patches/server/0361-Fix-villager-trading-demand-MC-163962.patch b/patches/unapplied/0361-Fix-villager-trading-demand-MC-163962.patch similarity index 100% rename from patches/server/0361-Fix-villager-trading-demand-MC-163962.patch rename to patches/unapplied/0361-Fix-villager-trading-demand-MC-163962.patch diff --git a/patches/server/0362-Maps-shouldn-t-load-chunks.patch b/patches/unapplied/0362-Maps-shouldn-t-load-chunks.patch similarity index 100% rename from patches/server/0362-Maps-shouldn-t-load-chunks.patch rename to patches/unapplied/0362-Maps-shouldn-t-load-chunks.patch diff --git a/patches/server/0363-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch b/patches/unapplied/0363-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch similarity index 100% rename from patches/server/0363-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch rename to patches/unapplied/0363-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch diff --git a/patches/server/0364-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch b/patches/unapplied/0364-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch similarity index 100% rename from patches/server/0364-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch rename to patches/unapplied/0364-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch diff --git a/patches/server/0365-Fix-piston-physics-inconsistency-MC-188840.patch b/patches/unapplied/0365-Fix-piston-physics-inconsistency-MC-188840.patch similarity index 100% rename from patches/server/0365-Fix-piston-physics-inconsistency-MC-188840.patch rename to patches/unapplied/0365-Fix-piston-physics-inconsistency-MC-188840.patch diff --git a/patches/server/0366-Fix-missing-chunks-due-to-integer-overflow.patch b/patches/unapplied/0366-Fix-missing-chunks-due-to-integer-overflow.patch similarity index 100% rename from patches/server/0366-Fix-missing-chunks-due-to-integer-overflow.patch rename to patches/unapplied/0366-Fix-missing-chunks-due-to-integer-overflow.patch diff --git a/patches/server/0367-Prevent-position-desync-causing-tp-exploit.patch b/patches/unapplied/0367-Prevent-position-desync-causing-tp-exploit.patch similarity index 100% rename from patches/server/0367-Prevent-position-desync-causing-tp-exploit.patch rename to patches/unapplied/0367-Prevent-position-desync-causing-tp-exploit.patch diff --git a/patches/server/0368-Inventory-getHolder-method-without-block-snapshot.patch b/patches/unapplied/0368-Inventory-getHolder-method-without-block-snapshot.patch similarity index 100% rename from patches/server/0368-Inventory-getHolder-method-without-block-snapshot.patch rename to patches/unapplied/0368-Inventory-getHolder-method-without-block-snapshot.patch diff --git a/patches/server/0369-Add-PlayerRecipeBookClickEvent.patch b/patches/unapplied/0369-Add-PlayerRecipeBookClickEvent.patch similarity index 100% rename from patches/server/0369-Add-PlayerRecipeBookClickEvent.patch rename to patches/unapplied/0369-Add-PlayerRecipeBookClickEvent.patch diff --git a/patches/server/0370-Hide-sync-chunk-writes-behind-flag.patch b/patches/unapplied/0370-Hide-sync-chunk-writes-behind-flag.patch similarity index 100% rename from patches/server/0370-Hide-sync-chunk-writes-behind-flag.patch rename to patches/unapplied/0370-Hide-sync-chunk-writes-behind-flag.patch diff --git a/patches/server/0371-Add-permission-for-command-blocks.patch b/patches/unapplied/0371-Add-permission-for-command-blocks.patch similarity index 100% rename from patches/server/0371-Add-permission-for-command-blocks.patch rename to patches/unapplied/0371-Add-permission-for-command-blocks.patch diff --git a/patches/server/0372-Ensure-Entity-position-and-AABB-are-never-invalid.patch b/patches/unapplied/0372-Ensure-Entity-position-and-AABB-are-never-invalid.patch similarity index 100% rename from patches/server/0372-Ensure-Entity-position-and-AABB-are-never-invalid.patch rename to patches/unapplied/0372-Ensure-Entity-position-and-AABB-are-never-invalid.patch diff --git a/patches/server/0373-Fix-Per-World-Difficulty-Remembering-Difficulty.patch b/patches/unapplied/0373-Fix-Per-World-Difficulty-Remembering-Difficulty.patch similarity index 100% rename from patches/server/0373-Fix-Per-World-Difficulty-Remembering-Difficulty.patch rename to patches/unapplied/0373-Fix-Per-World-Difficulty-Remembering-Difficulty.patch diff --git a/patches/server/0374-Paper-dumpitem-command.patch b/patches/unapplied/0374-Paper-dumpitem-command.patch similarity index 100% rename from patches/server/0374-Paper-dumpitem-command.patch rename to patches/unapplied/0374-Paper-dumpitem-command.patch diff --git a/patches/server/0375-Improve-Legacy-Component-serialization-size.patch b/patches/unapplied/0375-Improve-Legacy-Component-serialization-size.patch similarity index 100% rename from patches/server/0375-Improve-Legacy-Component-serialization-size.patch rename to patches/unapplied/0375-Improve-Legacy-Component-serialization-size.patch diff --git a/patches/server/0376-Add-Plugin-Tickets-to-API-Chunk-Methods.patch b/patches/unapplied/0376-Add-Plugin-Tickets-to-API-Chunk-Methods.patch similarity index 100% rename from patches/server/0376-Add-Plugin-Tickets-to-API-Chunk-Methods.patch rename to patches/unapplied/0376-Add-Plugin-Tickets-to-API-Chunk-Methods.patch diff --git a/patches/server/0377-Add-BlockStateMeta-clearBlockState.patch b/patches/unapplied/0377-Add-BlockStateMeta-clearBlockState.patch similarity index 100% rename from patches/server/0377-Add-BlockStateMeta-clearBlockState.patch rename to patches/unapplied/0377-Add-BlockStateMeta-clearBlockState.patch diff --git a/patches/server/0378-Convert-legacy-attributes-in-Item-Meta.patch b/patches/unapplied/0378-Convert-legacy-attributes-in-Item-Meta.patch similarity index 100% rename from patches/server/0378-Convert-legacy-attributes-in-Item-Meta.patch rename to patches/unapplied/0378-Convert-legacy-attributes-in-Item-Meta.patch diff --git a/patches/server/0379-Do-not-accept-invalid-client-settings.patch b/patches/unapplied/0379-Do-not-accept-invalid-client-settings.patch similarity index 100% rename from patches/server/0379-Do-not-accept-invalid-client-settings.patch rename to patches/unapplied/0379-Do-not-accept-invalid-client-settings.patch diff --git a/patches/server/0380-Improve-fix-EntityTargetLivingEntityEvent.patch b/patches/unapplied/0380-Improve-fix-EntityTargetLivingEntityEvent.patch similarity index 100% rename from patches/server/0380-Improve-fix-EntityTargetLivingEntityEvent.patch rename to patches/unapplied/0380-Improve-fix-EntityTargetLivingEntityEvent.patch diff --git a/patches/server/0381-Add-entity-liquid-API.patch b/patches/unapplied/0381-Add-entity-liquid-API.patch similarity index 100% rename from patches/server/0381-Add-entity-liquid-API.patch rename to patches/unapplied/0381-Add-entity-liquid-API.patch diff --git a/patches/server/0382-Add-PrepareResultEvent.patch b/patches/unapplied/0382-Add-PrepareResultEvent.patch similarity index 100% rename from patches/server/0382-Add-PrepareResultEvent.patch rename to patches/unapplied/0382-Add-PrepareResultEvent.patch diff --git a/patches/server/0383-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch b/patches/unapplied/0383-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch similarity index 100% rename from patches/server/0383-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch rename to patches/unapplied/0383-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch diff --git a/patches/server/0384-Fix-arrows-never-despawning-MC-125757.patch b/patches/unapplied/0384-Fix-arrows-never-despawning-MC-125757.patch similarity index 100% rename from patches/server/0384-Fix-arrows-never-despawning-MC-125757.patch rename to patches/unapplied/0384-Fix-arrows-never-despawning-MC-125757.patch diff --git a/patches/server/0385-Thread-Safe-Vanilla-Command-permission-checking.patch b/patches/unapplied/0385-Thread-Safe-Vanilla-Command-permission-checking.patch similarity index 100% rename from patches/server/0385-Thread-Safe-Vanilla-Command-permission-checking.patch rename to patches/unapplied/0385-Thread-Safe-Vanilla-Command-permission-checking.patch diff --git a/patches/server/0386-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch b/patches/unapplied/0386-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch similarity index 100% rename from patches/server/0386-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch rename to patches/unapplied/0386-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch diff --git a/patches/server/0387-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch b/patches/unapplied/0387-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch similarity index 100% rename from patches/server/0387-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch rename to patches/unapplied/0387-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch diff --git a/patches/server/0388-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch b/patches/unapplied/0388-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch similarity index 100% rename from patches/server/0388-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch rename to patches/unapplied/0388-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch diff --git a/patches/server/0389-Optimize-NetworkManager-Exception-Handling.patch b/patches/unapplied/0389-Optimize-NetworkManager-Exception-Handling.patch similarity index 100% rename from patches/server/0389-Optimize-NetworkManager-Exception-Handling.patch rename to patches/unapplied/0389-Optimize-NetworkManager-Exception-Handling.patch diff --git a/patches/server/0390-Fix-some-rails-connecting-improperly.patch b/patches/unapplied/0390-Fix-some-rails-connecting-improperly.patch similarity index 100% rename from patches/server/0390-Fix-some-rails-connecting-improperly.patch rename to patches/unapplied/0390-Fix-some-rails-connecting-improperly.patch diff --git a/patches/server/0391-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch b/patches/unapplied/0391-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch similarity index 100% rename from patches/server/0391-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch rename to patches/unapplied/0391-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch diff --git a/patches/server/0392-Brand-support.patch b/patches/unapplied/0392-Brand-support.patch similarity index 100% rename from patches/server/0392-Brand-support.patch rename to patches/unapplied/0392-Brand-support.patch diff --git a/patches/server/0393-Add-playPickupItemAnimation-to-LivingEntity.patch b/patches/unapplied/0393-Add-playPickupItemAnimation-to-LivingEntity.patch similarity index 100% rename from patches/server/0393-Add-playPickupItemAnimation-to-LivingEntity.patch rename to patches/unapplied/0393-Add-playPickupItemAnimation-to-LivingEntity.patch diff --git a/patches/server/0394-Don-t-require-FACING-data.patch b/patches/unapplied/0394-Don-t-require-FACING-data.patch similarity index 100% rename from patches/server/0394-Don-t-require-FACING-data.patch rename to patches/unapplied/0394-Don-t-require-FACING-data.patch diff --git a/patches/server/0395-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch b/patches/unapplied/0395-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch similarity index 100% rename from patches/server/0395-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch rename to patches/unapplied/0395-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch diff --git a/patches/server/0396-Add-moon-phase-API.patch b/patches/unapplied/0396-Add-moon-phase-API.patch similarity index 100% rename from patches/server/0396-Add-moon-phase-API.patch rename to patches/unapplied/0396-Add-moon-phase-API.patch diff --git a/patches/server/0397-Do-not-let-the-server-load-chunks-from-newer-version.patch b/patches/unapplied/0397-Do-not-let-the-server-load-chunks-from-newer-version.patch similarity index 100% rename from patches/server/0397-Do-not-let-the-server-load-chunks-from-newer-version.patch rename to patches/unapplied/0397-Do-not-let-the-server-load-chunks-from-newer-version.patch diff --git a/patches/server/0398-Prevent-headless-pistons-from-being-created.patch b/patches/unapplied/0398-Prevent-headless-pistons-from-being-created.patch similarity index 100% rename from patches/server/0398-Prevent-headless-pistons-from-being-created.patch rename to patches/unapplied/0398-Prevent-headless-pistons-from-being-created.patch diff --git a/patches/server/0399-Add-BellRingEvent.patch b/patches/unapplied/0399-Add-BellRingEvent.patch similarity index 100% rename from patches/server/0399-Add-BellRingEvent.patch rename to patches/unapplied/0399-Add-BellRingEvent.patch diff --git a/patches/server/0400-Add-zombie-targets-turtle-egg-config.patch b/patches/unapplied/0400-Add-zombie-targets-turtle-egg-config.patch similarity index 100% rename from patches/server/0400-Add-zombie-targets-turtle-egg-config.patch rename to patches/unapplied/0400-Add-zombie-targets-turtle-egg-config.patch diff --git a/patches/server/0401-Buffer-joins-to-world.patch b/patches/unapplied/0401-Buffer-joins-to-world.patch similarity index 100% rename from patches/server/0401-Buffer-joins-to-world.patch rename to patches/unapplied/0401-Buffer-joins-to-world.patch diff --git a/patches/server/0402-Fix-hex-colors-not-working-in-some-kick-messages.patch b/patches/unapplied/0402-Fix-hex-colors-not-working-in-some-kick-messages.patch similarity index 100% rename from patches/server/0402-Fix-hex-colors-not-working-in-some-kick-messages.patch rename to patches/unapplied/0402-Fix-hex-colors-not-working-in-some-kick-messages.patch diff --git a/patches/server/0403-Add-more-Evoker-API.patch b/patches/unapplied/0403-Add-more-Evoker-API.patch similarity index 100% rename from patches/server/0403-Add-more-Evoker-API.patch rename to patches/unapplied/0403-Add-more-Evoker-API.patch diff --git a/patches/server/0404-Add-methods-to-get-translation-keys.patch b/patches/unapplied/0404-Add-methods-to-get-translation-keys.patch similarity index 100% rename from patches/server/0404-Add-methods-to-get-translation-keys.patch rename to patches/unapplied/0404-Add-methods-to-get-translation-keys.patch diff --git a/patches/server/0405-Create-HoverEvent-from-ItemStack-Entity.patch b/patches/unapplied/0405-Create-HoverEvent-from-ItemStack-Entity.patch similarity index 100% rename from patches/server/0405-Create-HoverEvent-from-ItemStack-Entity.patch rename to patches/unapplied/0405-Create-HoverEvent-from-ItemStack-Entity.patch diff --git a/patches/server/0406-Cache-block-data-strings.patch b/patches/unapplied/0406-Cache-block-data-strings.patch similarity index 100% rename from patches/server/0406-Cache-block-data-strings.patch rename to patches/unapplied/0406-Cache-block-data-strings.patch diff --git a/patches/server/0407-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch b/patches/unapplied/0407-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch similarity index 100% rename from patches/server/0407-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch rename to patches/unapplied/0407-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch diff --git a/patches/server/0408-Add-additional-open-container-api-to-HumanEntity.patch b/patches/unapplied/0408-Add-additional-open-container-api-to-HumanEntity.patch similarity index 100% rename from patches/server/0408-Add-additional-open-container-api-to-HumanEntity.patch rename to patches/unapplied/0408-Add-additional-open-container-api-to-HumanEntity.patch diff --git a/patches/server/0409-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch b/patches/unapplied/0409-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch similarity index 100% rename from patches/server/0409-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch rename to patches/unapplied/0409-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch diff --git a/patches/server/0410-Extend-block-drop-capture-to-capture-all-items-added.patch b/patches/unapplied/0410-Extend-block-drop-capture-to-capture-all-items-added.patch similarity index 100% rename from patches/server/0410-Extend-block-drop-capture-to-capture-all-items-added.patch rename to patches/unapplied/0410-Extend-block-drop-capture-to-capture-all-items-added.patch diff --git a/patches/server/0411-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch b/patches/unapplied/0411-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch similarity index 100% rename from patches/server/0411-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch rename to patches/unapplied/0411-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch diff --git a/patches/server/0412-Lazily-track-plugin-scoreboards-by-default.patch b/patches/unapplied/0412-Lazily-track-plugin-scoreboards-by-default.patch similarity index 100% rename from patches/server/0412-Lazily-track-plugin-scoreboards-by-default.patch rename to patches/unapplied/0412-Lazily-track-plugin-scoreboards-by-default.patch diff --git a/patches/server/0413-Entity-isTicking.patch b/patches/unapplied/0413-Entity-isTicking.patch similarity index 100% rename from patches/server/0413-Entity-isTicking.patch rename to patches/unapplied/0413-Entity-isTicking.patch diff --git a/patches/server/0414-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch b/patches/unapplied/0414-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch similarity index 100% rename from patches/server/0414-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch rename to patches/unapplied/0414-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch diff --git a/patches/server/0415-Fix-Concurrency-issue-in-ShufflingList.patch b/patches/unapplied/0415-Fix-Concurrency-issue-in-ShufflingList.patch similarity index 100% rename from patches/server/0415-Fix-Concurrency-issue-in-ShufflingList.patch rename to patches/unapplied/0415-Fix-Concurrency-issue-in-ShufflingList.patch diff --git a/patches/server/0416-Reset-Ender-Crystals-on-Dragon-Spawn.patch b/patches/unapplied/0416-Reset-Ender-Crystals-on-Dragon-Spawn.patch similarity index 100% rename from patches/server/0416-Reset-Ender-Crystals-on-Dragon-Spawn.patch rename to patches/unapplied/0416-Reset-Ender-Crystals-on-Dragon-Spawn.patch diff --git a/patches/server/0417-Fix-for-large-move-vectors-crashing-server.patch b/patches/unapplied/0417-Fix-for-large-move-vectors-crashing-server.patch similarity index 100% rename from patches/server/0417-Fix-for-large-move-vectors-crashing-server.patch rename to patches/unapplied/0417-Fix-for-large-move-vectors-crashing-server.patch diff --git a/patches/server/0418-Optimise-getType-calls.patch b/patches/unapplied/0418-Optimise-getType-calls.patch similarity index 100% rename from patches/server/0418-Optimise-getType-calls.patch rename to patches/unapplied/0418-Optimise-getType-calls.patch diff --git a/patches/server/0419-Villager-resetOffers.patch b/patches/unapplied/0419-Villager-resetOffers.patch similarity index 100% rename from patches/server/0419-Villager-resetOffers.patch rename to patches/unapplied/0419-Villager-resetOffers.patch diff --git a/patches/server/0420-Retain-block-place-order-when-capturing-blockstates.patch b/patches/unapplied/0420-Retain-block-place-order-when-capturing-blockstates.patch similarity index 100% rename from patches/server/0420-Retain-block-place-order-when-capturing-blockstates.patch rename to patches/unapplied/0420-Retain-block-place-order-when-capturing-blockstates.patch diff --git a/patches/server/0421-Fix-item-locations-dropped-from-campfires.patch b/patches/unapplied/0421-Fix-item-locations-dropped-from-campfires.patch similarity index 100% rename from patches/server/0421-Fix-item-locations-dropped-from-campfires.patch rename to patches/unapplied/0421-Fix-item-locations-dropped-from-campfires.patch diff --git a/patches/server/0422-Fix-bell-block-entity-memory-leak.patch b/patches/unapplied/0422-Fix-bell-block-entity-memory-leak.patch similarity index 100% rename from patches/server/0422-Fix-bell-block-entity-memory-leak.patch rename to patches/unapplied/0422-Fix-bell-block-entity-memory-leak.patch diff --git a/patches/server/0423-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch b/patches/unapplied/0423-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch similarity index 100% rename from patches/server/0423-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch rename to patches/unapplied/0423-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch diff --git a/patches/server/0424-Add-getOfflinePlayerIfCached-String.patch b/patches/unapplied/0424-Add-getOfflinePlayerIfCached-String.patch similarity index 100% rename from patches/server/0424-Add-getOfflinePlayerIfCached-String.patch rename to patches/unapplied/0424-Add-getOfflinePlayerIfCached-String.patch diff --git a/patches/server/0425-Add-ignore-discounts-API.patch b/patches/unapplied/0425-Add-ignore-discounts-API.patch similarity index 100% rename from patches/server/0425-Add-ignore-discounts-API.patch rename to patches/unapplied/0425-Add-ignore-discounts-API.patch diff --git a/patches/server/0426-Toggle-for-removing-existing-dragon.patch b/patches/unapplied/0426-Toggle-for-removing-existing-dragon.patch similarity index 100% rename from patches/server/0426-Toggle-for-removing-existing-dragon.patch rename to patches/unapplied/0426-Toggle-for-removing-existing-dragon.patch diff --git a/patches/server/0427-Fix-client-lag-on-advancement-loading.patch b/patches/unapplied/0427-Fix-client-lag-on-advancement-loading.patch similarity index 100% rename from patches/server/0427-Fix-client-lag-on-advancement-loading.patch rename to patches/unapplied/0427-Fix-client-lag-on-advancement-loading.patch diff --git a/patches/server/0428-Item-no-age-no-player-pickup.patch b/patches/unapplied/0428-Item-no-age-no-player-pickup.patch similarity index 100% rename from patches/server/0428-Item-no-age-no-player-pickup.patch rename to patches/unapplied/0428-Item-no-age-no-player-pickup.patch diff --git a/patches/server/0429-Beacon-API-custom-effect-ranges.patch b/patches/unapplied/0429-Beacon-API-custom-effect-ranges.patch similarity index 100% rename from patches/server/0429-Beacon-API-custom-effect-ranges.patch rename to patches/unapplied/0429-Beacon-API-custom-effect-ranges.patch diff --git a/patches/server/0430-Add-API-for-quit-reason.patch b/patches/unapplied/0430-Add-API-for-quit-reason.patch similarity index 100% rename from patches/server/0430-Add-API-for-quit-reason.patch rename to patches/unapplied/0430-Add-API-for-quit-reason.patch diff --git a/patches/server/0431-Add-Wandering-Trader-spawn-rate-config-options.patch b/patches/unapplied/0431-Add-Wandering-Trader-spawn-rate-config-options.patch similarity index 100% rename from patches/server/0431-Add-Wandering-Trader-spawn-rate-config-options.patch rename to patches/unapplied/0431-Add-Wandering-Trader-spawn-rate-config-options.patch diff --git a/patches/server/0432-Add-Destroy-Speed-API.patch b/patches/unapplied/0432-Add-Destroy-Speed-API.patch similarity index 100% rename from patches/server/0432-Add-Destroy-Speed-API.patch rename to patches/unapplied/0432-Add-Destroy-Speed-API.patch diff --git a/patches/server/0433-Fix-Player-spawnParticle-x-y-z-precision-loss.patch b/patches/unapplied/0433-Fix-Player-spawnParticle-x-y-z-precision-loss.patch similarity index 100% rename from patches/server/0433-Fix-Player-spawnParticle-x-y-z-precision-loss.patch rename to patches/unapplied/0433-Fix-Player-spawnParticle-x-y-z-precision-loss.patch diff --git a/patches/server/0434-Add-LivingEntity-clearActiveItem.patch b/patches/unapplied/0434-Add-LivingEntity-clearActiveItem.patch similarity index 100% rename from patches/server/0434-Add-LivingEntity-clearActiveItem.patch rename to patches/unapplied/0434-Add-LivingEntity-clearActiveItem.patch diff --git a/patches/server/0435-Add-PlayerItemCooldownEvent.patch b/patches/unapplied/0435-Add-PlayerItemCooldownEvent.patch similarity index 100% rename from patches/server/0435-Add-PlayerItemCooldownEvent.patch rename to patches/unapplied/0435-Add-PlayerItemCooldownEvent.patch diff --git a/patches/server/0436-Significantly-improve-performance-of-the-end-generat.patch b/patches/unapplied/0436-Significantly-improve-performance-of-the-end-generat.patch similarity index 100% rename from patches/server/0436-Significantly-improve-performance-of-the-end-generat.patch rename to patches/unapplied/0436-Significantly-improve-performance-of-the-end-generat.patch diff --git a/patches/server/0437-More-lightning-API.patch b/patches/unapplied/0437-More-lightning-API.patch similarity index 100% rename from patches/server/0437-More-lightning-API.patch rename to patches/unapplied/0437-More-lightning-API.patch diff --git a/patches/server/0438-Climbing-should-not-bypass-cramming-gamerule.patch b/patches/unapplied/0438-Climbing-should-not-bypass-cramming-gamerule.patch similarity index 100% rename from patches/server/0438-Climbing-should-not-bypass-cramming-gamerule.patch rename to patches/unapplied/0438-Climbing-should-not-bypass-cramming-gamerule.patch diff --git a/patches/server/0439-Add-missing-default-perms-for-commands.patch b/patches/unapplied/0439-Add-missing-default-perms-for-commands.patch similarity index 100% rename from patches/server/0439-Add-missing-default-perms-for-commands.patch rename to patches/unapplied/0439-Add-missing-default-perms-for-commands.patch diff --git a/patches/server/0440-Add-PlayerShearBlockEvent.patch b/patches/unapplied/0440-Add-PlayerShearBlockEvent.patch similarity index 100% rename from patches/server/0440-Add-PlayerShearBlockEvent.patch rename to patches/unapplied/0440-Add-PlayerShearBlockEvent.patch diff --git a/patches/server/0441-Limit-recipe-packets.patch b/patches/unapplied/0441-Limit-recipe-packets.patch similarity index 100% rename from patches/server/0441-Limit-recipe-packets.patch rename to patches/unapplied/0441-Limit-recipe-packets.patch diff --git a/patches/server/0442-Fix-CraftSound-backwards-compatibility.patch b/patches/unapplied/0442-Fix-CraftSound-backwards-compatibility.patch similarity index 100% rename from patches/server/0442-Fix-CraftSound-backwards-compatibility.patch rename to patches/unapplied/0442-Fix-CraftSound-backwards-compatibility.patch diff --git a/patches/server/0443-Player-Chunk-Load-Unload-Events.patch b/patches/unapplied/0443-Player-Chunk-Load-Unload-Events.patch similarity index 100% rename from patches/server/0443-Player-Chunk-Load-Unload-Events.patch rename to patches/unapplied/0443-Player-Chunk-Load-Unload-Events.patch diff --git a/patches/server/0444-Optimize-Dynamic-get-Missing-Keys.patch b/patches/unapplied/0444-Optimize-Dynamic-get-Missing-Keys.patch similarity index 100% rename from patches/server/0444-Optimize-Dynamic-get-Missing-Keys.patch rename to patches/unapplied/0444-Optimize-Dynamic-get-Missing-Keys.patch diff --git a/patches/server/0445-Expose-LivingEntity-hurt-direction.patch b/patches/unapplied/0445-Expose-LivingEntity-hurt-direction.patch similarity index 100% rename from patches/server/0445-Expose-LivingEntity-hurt-direction.patch rename to patches/unapplied/0445-Expose-LivingEntity-hurt-direction.patch diff --git a/patches/server/0446-Add-OBSTRUCTED-reason-to-BedEnterResult.patch b/patches/unapplied/0446-Add-OBSTRUCTED-reason-to-BedEnterResult.patch similarity index 100% rename from patches/server/0446-Add-OBSTRUCTED-reason-to-BedEnterResult.patch rename to patches/unapplied/0446-Add-OBSTRUCTED-reason-to-BedEnterResult.patch diff --git a/patches/server/0447-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch b/patches/unapplied/0447-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch similarity index 100% rename from patches/server/0447-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch rename to patches/unapplied/0447-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch diff --git a/patches/server/0448-Add-TargetHitEvent.patch b/patches/unapplied/0448-Add-TargetHitEvent.patch similarity index 100% rename from patches/server/0448-Add-TargetHitEvent.patch rename to patches/unapplied/0448-Add-TargetHitEvent.patch diff --git a/patches/server/0449-MC-4-Fix-item-position-desync.patch b/patches/unapplied/0449-MC-4-Fix-item-position-desync.patch similarity index 100% rename from patches/server/0449-MC-4-Fix-item-position-desync.patch rename to patches/unapplied/0449-MC-4-Fix-item-position-desync.patch diff --git a/patches/server/0450-Additional-Block-Material-API.patch b/patches/unapplied/0450-Additional-Block-Material-API.patch similarity index 100% rename from patches/server/0450-Additional-Block-Material-API.patch rename to patches/unapplied/0450-Additional-Block-Material-API.patch diff --git a/patches/server/0451-Fix-harming-potion-dupe.patch b/patches/unapplied/0451-Fix-harming-potion-dupe.patch similarity index 100% rename from patches/server/0451-Fix-harming-potion-dupe.patch rename to patches/unapplied/0451-Fix-harming-potion-dupe.patch diff --git a/patches/server/0452-API-to-get-Material-from-Boats-and-Minecarts.patch b/patches/unapplied/0452-API-to-get-Material-from-Boats-and-Minecarts.patch similarity index 100% rename from patches/server/0452-API-to-get-Material-from-Boats-and-Minecarts.patch rename to patches/unapplied/0452-API-to-get-Material-from-Boats-and-Minecarts.patch diff --git a/patches/server/0453-Allow-disabling-mob-spawner-spawn-egg-transformation.patch b/patches/unapplied/0453-Allow-disabling-mob-spawner-spawn-egg-transformation.patch similarity index 100% rename from patches/server/0453-Allow-disabling-mob-spawner-spawn-egg-transformation.patch rename to patches/unapplied/0453-Allow-disabling-mob-spawner-spawn-egg-transformation.patch diff --git a/patches/server/0454-Fix-Not-a-string-Map-Conversion-spam.patch b/patches/unapplied/0454-Fix-Not-a-string-Map-Conversion-spam.patch similarity index 100% rename from patches/server/0454-Fix-Not-a-string-Map-Conversion-spam.patch rename to patches/unapplied/0454-Fix-Not-a-string-Map-Conversion-spam.patch diff --git a/patches/server/0455-Add-PlayerFlowerPotManipulateEvent.patch b/patches/unapplied/0455-Add-PlayerFlowerPotManipulateEvent.patch similarity index 100% rename from patches/server/0455-Add-PlayerFlowerPotManipulateEvent.patch rename to patches/unapplied/0455-Add-PlayerFlowerPotManipulateEvent.patch diff --git a/patches/server/0456-Fix-interact-event-not-being-called-sometimes.patch b/patches/unapplied/0456-Fix-interact-event-not-being-called-sometimes.patch similarity index 100% rename from patches/server/0456-Fix-interact-event-not-being-called-sometimes.patch rename to patches/unapplied/0456-Fix-interact-event-not-being-called-sometimes.patch diff --git a/patches/server/0457-Zombie-API-breaking-doors.patch b/patches/unapplied/0457-Zombie-API-breaking-doors.patch similarity index 100% rename from patches/server/0457-Zombie-API-breaking-doors.patch rename to patches/unapplied/0457-Zombie-API-breaking-doors.patch diff --git a/patches/server/0458-Fix-nerfed-slime-when-splitting.patch b/patches/unapplied/0458-Fix-nerfed-slime-when-splitting.patch similarity index 100% rename from patches/server/0458-Fix-nerfed-slime-when-splitting.patch rename to patches/unapplied/0458-Fix-nerfed-slime-when-splitting.patch diff --git a/patches/server/0459-Add-EntityLoadCrossbowEvent.patch b/patches/unapplied/0459-Add-EntityLoadCrossbowEvent.patch similarity index 100% rename from patches/server/0459-Add-EntityLoadCrossbowEvent.patch rename to patches/unapplied/0459-Add-EntityLoadCrossbowEvent.patch diff --git a/patches/server/0460-Add-WorldGameRuleChangeEvent.patch b/patches/unapplied/0460-Add-WorldGameRuleChangeEvent.patch similarity index 100% rename from patches/server/0460-Add-WorldGameRuleChangeEvent.patch rename to patches/unapplied/0460-Add-WorldGameRuleChangeEvent.patch diff --git a/patches/server/0461-Add-ServerResourcesReloadedEvent.patch b/patches/unapplied/0461-Add-ServerResourcesReloadedEvent.patch similarity index 100% rename from patches/server/0461-Add-ServerResourcesReloadedEvent.patch rename to patches/unapplied/0461-Add-ServerResourcesReloadedEvent.patch diff --git a/patches/server/0462-Add-world-settings-for-mobs-picking-up-loot.patch b/patches/unapplied/0462-Add-world-settings-for-mobs-picking-up-loot.patch similarity index 100% rename from patches/server/0462-Add-world-settings-for-mobs-picking-up-loot.patch rename to patches/unapplied/0462-Add-world-settings-for-mobs-picking-up-loot.patch diff --git a/patches/server/0463-Add-BlockFailedDispenseEvent.patch b/patches/unapplied/0463-Add-BlockFailedDispenseEvent.patch similarity index 100% rename from patches/server/0463-Add-BlockFailedDispenseEvent.patch rename to patches/unapplied/0463-Add-BlockFailedDispenseEvent.patch diff --git a/patches/server/0464-Add-PlayerLecternPageChangeEvent.patch b/patches/unapplied/0464-Add-PlayerLecternPageChangeEvent.patch similarity index 100% rename from patches/server/0464-Add-PlayerLecternPageChangeEvent.patch rename to patches/unapplied/0464-Add-PlayerLecternPageChangeEvent.patch diff --git a/patches/server/0465-Add-PlayerLoomPatternSelectEvent.patch b/patches/unapplied/0465-Add-PlayerLoomPatternSelectEvent.patch similarity index 100% rename from patches/server/0465-Add-PlayerLoomPatternSelectEvent.patch rename to patches/unapplied/0465-Add-PlayerLoomPatternSelectEvent.patch diff --git a/patches/server/0466-Configurable-door-breaking-difficulty.patch b/patches/unapplied/0466-Configurable-door-breaking-difficulty.patch similarity index 100% rename from patches/server/0466-Configurable-door-breaking-difficulty.patch rename to patches/unapplied/0466-Configurable-door-breaking-difficulty.patch diff --git a/patches/server/0467-Empty-commands-shall-not-be-dispatched.patch b/patches/unapplied/0467-Empty-commands-shall-not-be-dispatched.patch similarity index 100% rename from patches/server/0467-Empty-commands-shall-not-be-dispatched.patch rename to patches/unapplied/0467-Empty-commands-shall-not-be-dispatched.patch diff --git a/patches/server/0468-Remove-stale-POIs.patch b/patches/unapplied/0468-Remove-stale-POIs.patch similarity index 100% rename from patches/server/0468-Remove-stale-POIs.patch rename to patches/unapplied/0468-Remove-stale-POIs.patch diff --git a/patches/server/0469-Fix-villager-boat-exploit.patch b/patches/unapplied/0469-Fix-villager-boat-exploit.patch similarity index 100% rename from patches/server/0469-Fix-villager-boat-exploit.patch rename to patches/unapplied/0469-Fix-villager-boat-exploit.patch diff --git a/patches/server/0470-Add-sendOpLevel-API.patch b/patches/unapplied/0470-Add-sendOpLevel-API.patch similarity index 100% rename from patches/server/0470-Add-sendOpLevel-API.patch rename to patches/unapplied/0470-Add-sendOpLevel-API.patch diff --git a/patches/server/0471-Add-RegistryAccess-for-managing-Registries.patch b/patches/unapplied/0471-Add-RegistryAccess-for-managing-Registries.patch similarity index 100% rename from patches/server/0471-Add-RegistryAccess-for-managing-Registries.patch rename to patches/unapplied/0471-Add-RegistryAccess-for-managing-Registries.patch diff --git a/patches/server/0472-Add-StructuresLocateEvent.patch b/patches/unapplied/0472-Add-StructuresLocateEvent.patch similarity index 100% rename from patches/server/0472-Add-StructuresLocateEvent.patch rename to patches/unapplied/0472-Add-StructuresLocateEvent.patch diff --git a/patches/server/0473-Collision-option-for-requiring-a-player-participant.patch b/patches/unapplied/0473-Collision-option-for-requiring-a-player-participant.patch similarity index 100% rename from patches/server/0473-Collision-option-for-requiring-a-player-participant.patch rename to patches/unapplied/0473-Collision-option-for-requiring-a-player-participant.patch diff --git a/patches/server/0474-Return-chat-component-with-empty-text-instead-of-thr.patch b/patches/unapplied/0474-Return-chat-component-with-empty-text-instead-of-thr.patch similarity index 100% rename from patches/server/0474-Return-chat-component-with-empty-text-instead-of-thr.patch rename to patches/unapplied/0474-Return-chat-component-with-empty-text-instead-of-thr.patch diff --git a/patches/server/0475-Make-schedule-command-per-world.patch b/patches/unapplied/0475-Make-schedule-command-per-world.patch similarity index 100% rename from patches/server/0475-Make-schedule-command-per-world.patch rename to patches/unapplied/0475-Make-schedule-command-per-world.patch diff --git a/patches/server/0476-Configurable-max-leash-distance.patch b/patches/unapplied/0476-Configurable-max-leash-distance.patch similarity index 100% rename from patches/server/0476-Configurable-max-leash-distance.patch rename to patches/unapplied/0476-Configurable-max-leash-distance.patch diff --git a/patches/server/0477-Add-BlockPreDispenseEvent.patch b/patches/unapplied/0477-Add-BlockPreDispenseEvent.patch similarity index 100% rename from patches/server/0477-Add-BlockPreDispenseEvent.patch rename to patches/unapplied/0477-Add-BlockPreDispenseEvent.patch diff --git a/patches/server/0478-Add-PlayerChangeBeaconEffectEvent.patch b/patches/unapplied/0478-Add-PlayerChangeBeaconEffectEvent.patch similarity index 100% rename from patches/server/0478-Add-PlayerChangeBeaconEffectEvent.patch rename to patches/unapplied/0478-Add-PlayerChangeBeaconEffectEvent.patch diff --git a/patches/server/0479-Add-toggle-for-always-placing-the-dragon-egg.patch b/patches/unapplied/0479-Add-toggle-for-always-placing-the-dragon-egg.patch similarity index 100% rename from patches/server/0479-Add-toggle-for-always-placing-the-dragon-egg.patch rename to patches/unapplied/0479-Add-toggle-for-always-placing-the-dragon-egg.patch diff --git a/patches/server/0480-Add-PlayerStonecutterRecipeSelectEvent.patch b/patches/unapplied/0480-Add-PlayerStonecutterRecipeSelectEvent.patch similarity index 100% rename from patches/server/0480-Add-PlayerStonecutterRecipeSelectEvent.patch rename to patches/unapplied/0480-Add-PlayerStonecutterRecipeSelectEvent.patch diff --git a/patches/server/0481-Expand-EntityUnleashEvent.patch b/patches/unapplied/0481-Expand-EntityUnleashEvent.patch similarity index 100% rename from patches/server/0481-Expand-EntityUnleashEvent.patch rename to patches/unapplied/0481-Expand-EntityUnleashEvent.patch diff --git a/patches/server/0482-Reset-shield-blocking-on-dimension-change.patch b/patches/unapplied/0482-Reset-shield-blocking-on-dimension-change.patch similarity index 100% rename from patches/server/0482-Reset-shield-blocking-on-dimension-change.patch rename to patches/unapplied/0482-Reset-shield-blocking-on-dimension-change.patch diff --git a/patches/server/0483-Add-DragonEggFormEvent.patch b/patches/unapplied/0483-Add-DragonEggFormEvent.patch similarity index 100% rename from patches/server/0483-Add-DragonEggFormEvent.patch rename to patches/unapplied/0483-Add-DragonEggFormEvent.patch diff --git a/patches/server/0484-Add-EntityMoveEvent.patch b/patches/unapplied/0484-Add-EntityMoveEvent.patch similarity index 100% rename from patches/server/0484-Add-EntityMoveEvent.patch rename to patches/unapplied/0484-Add-EntityMoveEvent.patch diff --git a/patches/server/0485-added-option-to-disable-pathfinding-updates-on-block.patch b/patches/unapplied/0485-added-option-to-disable-pathfinding-updates-on-block.patch similarity index 100% rename from patches/server/0485-added-option-to-disable-pathfinding-updates-on-block.patch rename to patches/unapplied/0485-added-option-to-disable-pathfinding-updates-on-block.patch diff --git a/patches/server/0486-Inline-shift-direction-fields.patch b/patches/unapplied/0486-Inline-shift-direction-fields.patch similarity index 100% rename from patches/server/0486-Inline-shift-direction-fields.patch rename to patches/unapplied/0486-Inline-shift-direction-fields.patch diff --git a/patches/server/0487-Allow-adding-items-to-BlockDropItemEvent.patch b/patches/unapplied/0487-Allow-adding-items-to-BlockDropItemEvent.patch similarity index 100% rename from patches/server/0487-Allow-adding-items-to-BlockDropItemEvent.patch rename to patches/unapplied/0487-Allow-adding-items-to-BlockDropItemEvent.patch diff --git a/patches/server/0488-Add-getMainThreadExecutor-to-BukkitScheduler.patch b/patches/unapplied/0488-Add-getMainThreadExecutor-to-BukkitScheduler.patch similarity index 100% rename from patches/server/0488-Add-getMainThreadExecutor-to-BukkitScheduler.patch rename to patches/unapplied/0488-Add-getMainThreadExecutor-to-BukkitScheduler.patch diff --git a/patches/server/0489-living-entity-allow-attribute-registration.patch b/patches/unapplied/0489-living-entity-allow-attribute-registration.patch similarity index 100% rename from patches/server/0489-living-entity-allow-attribute-registration.patch rename to patches/unapplied/0489-living-entity-allow-attribute-registration.patch diff --git a/patches/server/0490-fix-dead-slime-setSize-invincibility.patch b/patches/unapplied/0490-fix-dead-slime-setSize-invincibility.patch similarity index 100% rename from patches/server/0490-fix-dead-slime-setSize-invincibility.patch rename to patches/unapplied/0490-fix-dead-slime-setSize-invincibility.patch diff --git a/patches/server/0491-Merchant-getRecipes-should-return-an-immutable-list.patch b/patches/unapplied/0491-Merchant-getRecipes-should-return-an-immutable-list.patch similarity index 100% rename from patches/server/0491-Merchant-getRecipes-should-return-an-immutable-list.patch rename to patches/unapplied/0491-Merchant-getRecipes-should-return-an-immutable-list.patch diff --git a/patches/server/0492-Expose-Tracked-Players.patch b/patches/unapplied/0492-Expose-Tracked-Players.patch similarity index 100% rename from patches/server/0492-Expose-Tracked-Players.patch rename to patches/unapplied/0492-Expose-Tracked-Players.patch diff --git a/patches/server/0493-Improve-ServerGUI.patch b/patches/unapplied/0493-Improve-ServerGUI.patch similarity index 100% rename from patches/server/0493-Improve-ServerGUI.patch rename to patches/unapplied/0493-Improve-ServerGUI.patch diff --git a/patches/server/0494-fix-converting-txt-to-json-file.patch b/patches/unapplied/0494-fix-converting-txt-to-json-file.patch similarity index 100% rename from patches/server/0494-fix-converting-txt-to-json-file.patch rename to patches/unapplied/0494-fix-converting-txt-to-json-file.patch diff --git a/patches/server/0495-Add-worldborder-events.patch b/patches/unapplied/0495-Add-worldborder-events.patch similarity index 100% rename from patches/server/0495-Add-worldborder-events.patch rename to patches/unapplied/0495-Add-worldborder-events.patch diff --git a/patches/server/0496-Add-PlayerNameEntityEvent.patch b/patches/unapplied/0496-Add-PlayerNameEntityEvent.patch similarity index 100% rename from patches/server/0496-Add-PlayerNameEntityEvent.patch rename to patches/unapplied/0496-Add-PlayerNameEntityEvent.patch diff --git a/patches/server/0497-Add-recipe-to-cook-events.patch b/patches/unapplied/0497-Add-recipe-to-cook-events.patch similarity index 100% rename from patches/server/0497-Add-recipe-to-cook-events.patch rename to patches/unapplied/0497-Add-recipe-to-cook-events.patch diff --git a/patches/server/0498-Add-Block-isValidTool.patch b/patches/unapplied/0498-Add-Block-isValidTool.patch similarity index 100% rename from patches/server/0498-Add-Block-isValidTool.patch rename to patches/unapplied/0498-Add-Block-isValidTool.patch diff --git a/patches/server/0499-Allow-using-signs-inside-spawn-protection.patch b/patches/unapplied/0499-Allow-using-signs-inside-spawn-protection.patch similarity index 100% rename from patches/server/0499-Allow-using-signs-inside-spawn-protection.patch rename to patches/unapplied/0499-Allow-using-signs-inside-spawn-protection.patch diff --git a/patches/server/0500-Expand-world-key-API.patch b/patches/unapplied/0500-Expand-world-key-API.patch similarity index 100% rename from patches/server/0500-Expand-world-key-API.patch rename to patches/unapplied/0500-Expand-world-key-API.patch diff --git a/patches/server/0501-Add-fast-alternative-constructor-for-Rotations.patch b/patches/unapplied/0501-Add-fast-alternative-constructor-for-Rotations.patch similarity index 100% rename from patches/server/0501-Add-fast-alternative-constructor-for-Rotations.patch rename to patches/unapplied/0501-Add-fast-alternative-constructor-for-Rotations.patch diff --git a/patches/server/0502-Drop-carried-item-when-player-has-disconnected.patch b/patches/unapplied/0502-Drop-carried-item-when-player-has-disconnected.patch similarity index 100% rename from patches/server/0502-Drop-carried-item-when-player-has-disconnected.patch rename to patches/unapplied/0502-Drop-carried-item-when-player-has-disconnected.patch diff --git a/patches/server/0503-forced-whitelist-use-configurable-kick-message.patch b/patches/unapplied/0503-forced-whitelist-use-configurable-kick-message.patch similarity index 100% rename from patches/server/0503-forced-whitelist-use-configurable-kick-message.patch rename to patches/unapplied/0503-forced-whitelist-use-configurable-kick-message.patch diff --git a/patches/server/0504-Don-t-ignore-result-of-PlayerEditBookEvent.patch b/patches/unapplied/0504-Don-t-ignore-result-of-PlayerEditBookEvent.patch similarity index 100% rename from patches/server/0504-Don-t-ignore-result-of-PlayerEditBookEvent.patch rename to patches/unapplied/0504-Don-t-ignore-result-of-PlayerEditBookEvent.patch diff --git a/patches/server/0505-Expose-protocol-version.patch b/patches/unapplied/0505-Expose-protocol-version.patch similarity index 100% rename from patches/server/0505-Expose-protocol-version.patch rename to patches/unapplied/0505-Expose-protocol-version.patch diff --git a/patches/server/0506-Enhance-console-tab-completions-for-brigadier-comman.patch b/patches/unapplied/0506-Enhance-console-tab-completions-for-brigadier-comman.patch similarity index 100% rename from patches/server/0506-Enhance-console-tab-completions-for-brigadier-comman.patch rename to patches/unapplied/0506-Enhance-console-tab-completions-for-brigadier-comman.patch diff --git a/patches/server/0507-Fix-PlayerItemConsumeEvent-cancelling-properly.patch b/patches/unapplied/0507-Fix-PlayerItemConsumeEvent-cancelling-properly.patch similarity index 100% rename from patches/server/0507-Fix-PlayerItemConsumeEvent-cancelling-properly.patch rename to patches/unapplied/0507-Fix-PlayerItemConsumeEvent-cancelling-properly.patch diff --git a/patches/server/0508-Add-bypass-host-check.patch b/patches/unapplied/0508-Add-bypass-host-check.patch similarity index 100% rename from patches/server/0508-Add-bypass-host-check.patch rename to patches/unapplied/0508-Add-bypass-host-check.patch diff --git a/patches/server/0509-Set-area-affect-cloud-rotation.patch b/patches/unapplied/0509-Set-area-affect-cloud-rotation.patch similarity index 100% rename from patches/server/0509-Set-area-affect-cloud-rotation.patch rename to patches/unapplied/0509-Set-area-affect-cloud-rotation.patch diff --git a/patches/server/0510-add-isDeeplySleeping-to-HumanEntity.patch b/patches/unapplied/0510-add-isDeeplySleeping-to-HumanEntity.patch similarity index 100% rename from patches/server/0510-add-isDeeplySleeping-to-HumanEntity.patch rename to patches/unapplied/0510-add-isDeeplySleeping-to-HumanEntity.patch diff --git a/patches/server/0511-add-consumeFuel-to-FurnaceBurnEvent.patch b/patches/unapplied/0511-add-consumeFuel-to-FurnaceBurnEvent.patch similarity index 100% rename from patches/server/0511-add-consumeFuel-to-FurnaceBurnEvent.patch rename to patches/unapplied/0511-add-consumeFuel-to-FurnaceBurnEvent.patch diff --git a/patches/server/0512-add-get-set-drop-chance-to-EntityEquipment.patch b/patches/unapplied/0512-add-get-set-drop-chance-to-EntityEquipment.patch similarity index 100% rename from patches/server/0512-add-get-set-drop-chance-to-EntityEquipment.patch rename to patches/unapplied/0512-add-get-set-drop-chance-to-EntityEquipment.patch diff --git a/patches/server/0513-fix-PigZombieAngerEvent-cancellation.patch b/patches/unapplied/0513-fix-PigZombieAngerEvent-cancellation.patch similarity index 100% rename from patches/server/0513-fix-PigZombieAngerEvent-cancellation.patch rename to patches/unapplied/0513-fix-PigZombieAngerEvent-cancellation.patch diff --git a/patches/server/0514-fix-PlayerItemHeldEvent-firing-twice.patch b/patches/unapplied/0514-fix-PlayerItemHeldEvent-firing-twice.patch similarity index 100% rename from patches/server/0514-fix-PlayerItemHeldEvent-firing-twice.patch rename to patches/unapplied/0514-fix-PlayerItemHeldEvent-firing-twice.patch diff --git a/patches/server/0515-Add-PlayerDeepSleepEvent.patch b/patches/unapplied/0515-Add-PlayerDeepSleepEvent.patch similarity index 100% rename from patches/server/0515-Add-PlayerDeepSleepEvent.patch rename to patches/unapplied/0515-Add-PlayerDeepSleepEvent.patch diff --git a/patches/server/0516-More-World-API.patch b/patches/unapplied/0516-More-World-API.patch similarity index 100% rename from patches/server/0516-More-World-API.patch rename to patches/unapplied/0516-More-World-API.patch diff --git a/patches/server/0517-Add-PlayerBedFailEnterEvent.patch b/patches/unapplied/0517-Add-PlayerBedFailEnterEvent.patch similarity index 100% rename from patches/server/0517-Add-PlayerBedFailEnterEvent.patch rename to patches/unapplied/0517-Add-PlayerBedFailEnterEvent.patch diff --git a/patches/server/0518-Implement-methods-to-convert-between-Component-and-B.patch b/patches/unapplied/0518-Implement-methods-to-convert-between-Component-and-B.patch similarity index 100% rename from patches/server/0518-Implement-methods-to-convert-between-Component-and-B.patch rename to patches/unapplied/0518-Implement-methods-to-convert-between-Component-and-B.patch diff --git a/patches/server/0519-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch b/patches/unapplied/0519-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch similarity index 100% rename from patches/server/0519-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch rename to patches/unapplied/0519-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch diff --git a/patches/server/0520-Introduce-beacon-activation-deactivation-events.patch b/patches/unapplied/0520-Introduce-beacon-activation-deactivation-events.patch similarity index 100% rename from patches/server/0520-Introduce-beacon-activation-deactivation-events.patch rename to patches/unapplied/0520-Introduce-beacon-activation-deactivation-events.patch diff --git a/patches/server/0521-Add-Channel-initialization-listeners.patch b/patches/unapplied/0521-Add-Channel-initialization-listeners.patch similarity index 100% rename from patches/server/0521-Add-Channel-initialization-listeners.patch rename to patches/unapplied/0521-Add-Channel-initialization-listeners.patch diff --git a/patches/server/0522-Send-empty-commands-if-tab-completion-is-disabled.patch b/patches/unapplied/0522-Send-empty-commands-if-tab-completion-is-disabled.patch similarity index 100% rename from patches/server/0522-Send-empty-commands-if-tab-completion-is-disabled.patch rename to patches/unapplied/0522-Send-empty-commands-if-tab-completion-is-disabled.patch diff --git a/patches/server/0523-Add-more-WanderingTrader-API.patch b/patches/unapplied/0523-Add-more-WanderingTrader-API.patch similarity index 100% rename from patches/server/0523-Add-more-WanderingTrader-API.patch rename to patches/unapplied/0523-Add-more-WanderingTrader-API.patch diff --git a/patches/server/0524-Add-EntityBlockStorage-clearEntities.patch b/patches/unapplied/0524-Add-EntityBlockStorage-clearEntities.patch similarity index 100% rename from patches/server/0524-Add-EntityBlockStorage-clearEntities.patch rename to patches/unapplied/0524-Add-EntityBlockStorage-clearEntities.patch diff --git a/patches/server/0525-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch b/patches/unapplied/0525-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch similarity index 100% rename from patches/server/0525-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch rename to patches/unapplied/0525-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch diff --git a/patches/server/0526-Add-HiddenPotionEffect-API.patch b/patches/unapplied/0526-Add-HiddenPotionEffect-API.patch similarity index 100% rename from patches/server/0526-Add-HiddenPotionEffect-API.patch rename to patches/unapplied/0526-Add-HiddenPotionEffect-API.patch diff --git a/patches/server/0527-Inventory-close.patch b/patches/unapplied/0527-Inventory-close.patch similarity index 100% rename from patches/server/0527-Inventory-close.patch rename to patches/unapplied/0527-Inventory-close.patch diff --git a/patches/server/0528-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch b/patches/unapplied/0528-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch similarity index 100% rename from patches/server/0528-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch rename to patches/unapplied/0528-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch diff --git a/patches/server/0529-Add-basic-Datapack-API.patch b/patches/unapplied/0529-Add-basic-Datapack-API.patch similarity index 100% rename from patches/server/0529-Add-basic-Datapack-API.patch rename to patches/unapplied/0529-Add-basic-Datapack-API.patch diff --git a/patches/server/0530-Add-environment-variable-to-disable-server-gui.patch b/patches/unapplied/0530-Add-environment-variable-to-disable-server-gui.patch similarity index 100% rename from patches/server/0530-Add-environment-variable-to-disable-server-gui.patch rename to patches/unapplied/0530-Add-environment-variable-to-disable-server-gui.patch diff --git a/patches/server/0531-Expand-PlayerGameModeChangeEvent.patch b/patches/unapplied/0531-Expand-PlayerGameModeChangeEvent.patch similarity index 100% rename from patches/server/0531-Expand-PlayerGameModeChangeEvent.patch rename to patches/unapplied/0531-Expand-PlayerGameModeChangeEvent.patch diff --git a/patches/server/0532-ItemStack-repair-check-API.patch b/patches/unapplied/0532-ItemStack-repair-check-API.patch similarity index 100% rename from patches/server/0532-ItemStack-repair-check-API.patch rename to patches/unapplied/0532-ItemStack-repair-check-API.patch diff --git a/patches/server/0533-More-Enchantment-API.patch b/patches/unapplied/0533-More-Enchantment-API.patch similarity index 100% rename from patches/server/0533-More-Enchantment-API.patch rename to patches/unapplied/0533-More-Enchantment-API.patch diff --git a/patches/server/0534-Move-range-check-for-block-placing-up.patch b/patches/unapplied/0534-Move-range-check-for-block-placing-up.patch similarity index 100% rename from patches/server/0534-Move-range-check-for-block-placing-up.patch rename to patches/unapplied/0534-Move-range-check-for-block-placing-up.patch diff --git a/patches/server/0535-Add-Mob-lookAt-API.patch b/patches/unapplied/0535-Add-Mob-lookAt-API.patch similarity index 100% rename from patches/server/0535-Add-Mob-lookAt-API.patch rename to patches/unapplied/0535-Add-Mob-lookAt-API.patch diff --git a/patches/server/0536-Correctly-check-if-bucket-dispenses-will-succeed-for.patch b/patches/unapplied/0536-Correctly-check-if-bucket-dispenses-will-succeed-for.patch similarity index 100% rename from patches/server/0536-Correctly-check-if-bucket-dispenses-will-succeed-for.patch rename to patches/unapplied/0536-Correctly-check-if-bucket-dispenses-will-succeed-for.patch diff --git a/patches/server/0537-Add-Unix-domain-socket-support.patch b/patches/unapplied/0537-Add-Unix-domain-socket-support.patch similarity index 100% rename from patches/server/0537-Add-Unix-domain-socket-support.patch rename to patches/unapplied/0537-Add-Unix-domain-socket-support.patch diff --git a/patches/server/0538-Add-EntityInsideBlockEvent.patch b/patches/unapplied/0538-Add-EntityInsideBlockEvent.patch similarity index 100% rename from patches/server/0538-Add-EntityInsideBlockEvent.patch rename to patches/unapplied/0538-Add-EntityInsideBlockEvent.patch diff --git a/patches/server/0539-Improve-item-default-attribute-API.patch b/patches/unapplied/0539-Improve-item-default-attribute-API.patch similarity index 100% rename from patches/server/0539-Improve-item-default-attribute-API.patch rename to patches/unapplied/0539-Improve-item-default-attribute-API.patch diff --git a/patches/server/0540-Add-cause-to-Weather-ThunderChangeEvents.patch b/patches/unapplied/0540-Add-cause-to-Weather-ThunderChangeEvents.patch similarity index 100% rename from patches/server/0540-Add-cause-to-Weather-ThunderChangeEvents.patch rename to patches/unapplied/0540-Add-cause-to-Weather-ThunderChangeEvents.patch diff --git a/patches/server/0541-More-Lidded-Block-API.patch b/patches/unapplied/0541-More-Lidded-Block-API.patch similarity index 100% rename from patches/server/0541-More-Lidded-Block-API.patch rename to patches/unapplied/0541-More-Lidded-Block-API.patch diff --git a/patches/server/0542-Limit-item-frame-cursors-on-maps.patch b/patches/unapplied/0542-Limit-item-frame-cursors-on-maps.patch similarity index 100% rename from patches/server/0542-Limit-item-frame-cursors-on-maps.patch rename to patches/unapplied/0542-Limit-item-frame-cursors-on-maps.patch diff --git a/patches/server/0543-Add-PlayerKickEvent-causes.patch b/patches/unapplied/0543-Add-PlayerKickEvent-causes.patch similarity index 100% rename from patches/server/0543-Add-PlayerKickEvent-causes.patch rename to patches/unapplied/0543-Add-PlayerKickEvent-causes.patch diff --git a/patches/server/0544-Add-PufferFishStateChangeEvent.patch b/patches/unapplied/0544-Add-PufferFishStateChangeEvent.patch similarity index 100% rename from patches/server/0544-Add-PufferFishStateChangeEvent.patch rename to patches/unapplied/0544-Add-PufferFishStateChangeEvent.patch diff --git a/patches/server/0545-Fix-PlayerBucketEmptyEvent-result-itemstack.patch b/patches/unapplied/0545-Fix-PlayerBucketEmptyEvent-result-itemstack.patch similarity index 100% rename from patches/server/0545-Fix-PlayerBucketEmptyEvent-result-itemstack.patch rename to patches/unapplied/0545-Fix-PlayerBucketEmptyEvent-result-itemstack.patch diff --git a/patches/server/0546-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch b/patches/unapplied/0546-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch similarity index 100% rename from patches/server/0546-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch rename to patches/unapplied/0546-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch diff --git a/patches/server/0547-Add-option-to-fix-items-merging-through-walls.patch b/patches/unapplied/0547-Add-option-to-fix-items-merging-through-walls.patch similarity index 100% rename from patches/server/0547-Add-option-to-fix-items-merging-through-walls.patch rename to patches/unapplied/0547-Add-option-to-fix-items-merging-through-walls.patch diff --git a/patches/server/0548-Add-BellRevealRaiderEvent.patch b/patches/unapplied/0548-Add-BellRevealRaiderEvent.patch similarity index 100% rename from patches/server/0548-Add-BellRevealRaiderEvent.patch rename to patches/unapplied/0548-Add-BellRevealRaiderEvent.patch diff --git a/patches/server/0549-Fix-invulnerable-end-crystals.patch b/patches/unapplied/0549-Fix-invulnerable-end-crystals.patch similarity index 100% rename from patches/server/0549-Fix-invulnerable-end-crystals.patch rename to patches/unapplied/0549-Fix-invulnerable-end-crystals.patch diff --git a/patches/server/0550-Add-ElderGuardianAppearanceEvent.patch b/patches/unapplied/0550-Add-ElderGuardianAppearanceEvent.patch similarity index 100% rename from patches/server/0550-Add-ElderGuardianAppearanceEvent.patch rename to patches/unapplied/0550-Add-ElderGuardianAppearanceEvent.patch diff --git a/patches/server/0551-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch b/patches/unapplied/0551-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch similarity index 100% rename from patches/server/0551-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch rename to patches/unapplied/0551-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch diff --git a/patches/server/0552-Line-Of-Sight-Changes.patch b/patches/unapplied/0552-Line-Of-Sight-Changes.patch similarity index 100% rename from patches/server/0552-Line-Of-Sight-Changes.patch rename to patches/unapplied/0552-Line-Of-Sight-Changes.patch diff --git a/patches/server/0553-add-per-world-spawn-limits.patch b/patches/unapplied/0553-add-per-world-spawn-limits.patch similarity index 100% rename from patches/server/0553-add-per-world-spawn-limits.patch rename to patches/unapplied/0553-add-per-world-spawn-limits.patch diff --git a/patches/server/0554-Fix-potions-splash-events.patch b/patches/unapplied/0554-Fix-potions-splash-events.patch similarity index 100% rename from patches/server/0554-Fix-potions-splash-events.patch rename to patches/unapplied/0554-Fix-potions-splash-events.patch diff --git a/patches/server/0555-Add-more-LimitedRegion-API.patch b/patches/unapplied/0555-Add-more-LimitedRegion-API.patch similarity index 100% rename from patches/server/0555-Add-more-LimitedRegion-API.patch rename to patches/unapplied/0555-Add-more-LimitedRegion-API.patch diff --git a/patches/server/0556-Fix-PlayerDropItemEvent-using-wrong-item.patch b/patches/unapplied/0556-Fix-PlayerDropItemEvent-using-wrong-item.patch similarity index 100% rename from patches/server/0556-Fix-PlayerDropItemEvent-using-wrong-item.patch rename to patches/unapplied/0556-Fix-PlayerDropItemEvent-using-wrong-item.patch diff --git a/patches/server/0557-Missing-Entity-API.patch b/patches/unapplied/0557-Missing-Entity-API.patch similarity index 100% rename from patches/server/0557-Missing-Entity-API.patch rename to patches/unapplied/0557-Missing-Entity-API.patch diff --git a/patches/server/0558-Fix-return-value-of-Block-applyBoneMeal-always-being.patch b/patches/unapplied/0558-Fix-return-value-of-Block-applyBoneMeal-always-being.patch similarity index 100% rename from patches/server/0558-Fix-return-value-of-Block-applyBoneMeal-always-being.patch rename to patches/unapplied/0558-Fix-return-value-of-Block-applyBoneMeal-always-being.patch diff --git a/patches/server/0559-Use-getChunkIfLoadedImmediately-in-places.patch b/patches/unapplied/0559-Use-getChunkIfLoadedImmediately-in-places.patch similarity index 100% rename from patches/server/0559-Use-getChunkIfLoadedImmediately-in-places.patch rename to patches/unapplied/0559-Use-getChunkIfLoadedImmediately-in-places.patch diff --git a/patches/server/0560-Fix-commands-from-signs-not-firing-command-events.patch b/patches/unapplied/0560-Fix-commands-from-signs-not-firing-command-events.patch similarity index 100% rename from patches/server/0560-Fix-commands-from-signs-not-firing-command-events.patch rename to patches/unapplied/0560-Fix-commands-from-signs-not-firing-command-events.patch diff --git a/patches/server/0561-Add-PlayerArmSwingEvent.patch b/patches/unapplied/0561-Add-PlayerArmSwingEvent.patch similarity index 100% rename from patches/server/0561-Add-PlayerArmSwingEvent.patch rename to patches/unapplied/0561-Add-PlayerArmSwingEvent.patch diff --git a/patches/server/0562-Fix-kick-event-leave-message-not-being-sent.patch b/patches/unapplied/0562-Fix-kick-event-leave-message-not-being-sent.patch similarity index 100% rename from patches/server/0562-Fix-kick-event-leave-message-not-being-sent.patch rename to patches/unapplied/0562-Fix-kick-event-leave-message-not-being-sent.patch diff --git a/patches/server/0563-Don-t-apply-cramming-damage-to-players.patch b/patches/unapplied/0563-Don-t-apply-cramming-damage-to-players.patch similarity index 100% rename from patches/server/0563-Don-t-apply-cramming-damage-to-players.patch rename to patches/unapplied/0563-Don-t-apply-cramming-damage-to-players.patch diff --git a/patches/server/0564-Rate-options-and-timings-for-sensors-and-behaviors.patch b/patches/unapplied/0564-Rate-options-and-timings-for-sensors-and-behaviors.patch similarity index 100% rename from patches/server/0564-Rate-options-and-timings-for-sensors-and-behaviors.patch rename to patches/unapplied/0564-Rate-options-and-timings-for-sensors-and-behaviors.patch diff --git a/patches/server/0565-Add-missing-forceDrop-toggles.patch b/patches/unapplied/0565-Add-missing-forceDrop-toggles.patch similarity index 100% rename from patches/server/0565-Add-missing-forceDrop-toggles.patch rename to patches/unapplied/0565-Add-missing-forceDrop-toggles.patch diff --git a/patches/server/0566-Stinger-API.patch b/patches/unapplied/0566-Stinger-API.patch similarity index 100% rename from patches/server/0566-Stinger-API.patch rename to patches/unapplied/0566-Stinger-API.patch diff --git a/patches/server/0567-Add-System.out-err-catcher.patch b/patches/unapplied/0567-Add-System.out-err-catcher.patch similarity index 100% rename from patches/server/0567-Add-System.out-err-catcher.patch rename to patches/unapplied/0567-Add-System.out-err-catcher.patch diff --git a/patches/server/0568-Prevent-AFK-kick-while-watching-end-credits.patch b/patches/unapplied/0568-Prevent-AFK-kick-while-watching-end-credits.patch similarity index 100% rename from patches/server/0568-Prevent-AFK-kick-while-watching-end-credits.patch rename to patches/unapplied/0568-Prevent-AFK-kick-while-watching-end-credits.patch diff --git a/patches/server/0569-Allow-skipping-writing-of-comments-to-server.propert.patch b/patches/unapplied/0569-Allow-skipping-writing-of-comments-to-server.propert.patch similarity index 100% rename from patches/server/0569-Allow-skipping-writing-of-comments-to-server.propert.patch rename to patches/unapplied/0569-Allow-skipping-writing-of-comments-to-server.propert.patch diff --git a/patches/server/0570-Add-PlayerSetSpawnEvent.patch b/patches/unapplied/0570-Add-PlayerSetSpawnEvent.patch similarity index 100% rename from patches/server/0570-Add-PlayerSetSpawnEvent.patch rename to patches/unapplied/0570-Add-PlayerSetSpawnEvent.patch diff --git a/patches/server/0571-Make-hoppers-respect-inventory-max-stack-size.patch b/patches/unapplied/0571-Make-hoppers-respect-inventory-max-stack-size.patch similarity index 100% rename from patches/server/0571-Make-hoppers-respect-inventory-max-stack-size.patch rename to patches/unapplied/0571-Make-hoppers-respect-inventory-max-stack-size.patch diff --git a/patches/server/0572-Optimize-entity-tracker-passenger-checks.patch b/patches/unapplied/0572-Optimize-entity-tracker-passenger-checks.patch similarity index 100% rename from patches/server/0572-Optimize-entity-tracker-passenger-checks.patch rename to patches/unapplied/0572-Optimize-entity-tracker-passenger-checks.patch diff --git a/patches/server/0573-Config-option-for-Piglins-guarding-chests.patch b/patches/unapplied/0573-Config-option-for-Piglins-guarding-chests.patch similarity index 100% rename from patches/server/0573-Config-option-for-Piglins-guarding-chests.patch rename to patches/unapplied/0573-Config-option-for-Piglins-guarding-chests.patch diff --git a/patches/server/0574-Add-EntityDamageItemEvent.patch b/patches/unapplied/0574-Add-EntityDamageItemEvent.patch similarity index 100% rename from patches/server/0574-Add-EntityDamageItemEvent.patch rename to patches/unapplied/0574-Add-EntityDamageItemEvent.patch diff --git a/patches/server/0575-Optimize-indirect-passenger-iteration.patch b/patches/unapplied/0575-Optimize-indirect-passenger-iteration.patch similarity index 100% rename from patches/server/0575-Optimize-indirect-passenger-iteration.patch rename to patches/unapplied/0575-Optimize-indirect-passenger-iteration.patch diff --git a/patches/server/0576-Configurable-item-frame-map-cursor-update-interval.patch b/patches/unapplied/0576-Configurable-item-frame-map-cursor-update-interval.patch similarity index 100% rename from patches/server/0576-Configurable-item-frame-map-cursor-update-interval.patch rename to patches/unapplied/0576-Configurable-item-frame-map-cursor-update-interval.patch diff --git a/patches/server/0577-Change-EnderEye-target-without-changing-other-things.patch b/patches/unapplied/0577-Change-EnderEye-target-without-changing-other-things.patch similarity index 100% rename from patches/server/0577-Change-EnderEye-target-without-changing-other-things.patch rename to patches/unapplied/0577-Change-EnderEye-target-without-changing-other-things.patch diff --git a/patches/server/0578-Add-BlockBreakBlockEvent.patch b/patches/unapplied/0578-Add-BlockBreakBlockEvent.patch similarity index 100% rename from patches/server/0578-Add-BlockBreakBlockEvent.patch rename to patches/unapplied/0578-Add-BlockBreakBlockEvent.patch diff --git a/patches/server/0579-Option-to-prevent-data-components-copy-in-smithing-r.patch b/patches/unapplied/0579-Option-to-prevent-data-components-copy-in-smithing-r.patch similarity index 100% rename from patches/server/0579-Option-to-prevent-data-components-copy-in-smithing-r.patch rename to patches/unapplied/0579-Option-to-prevent-data-components-copy-in-smithing-r.patch diff --git a/patches/server/0580-More-CommandBlock-API.patch b/patches/unapplied/0580-More-CommandBlock-API.patch similarity index 100% rename from patches/server/0580-More-CommandBlock-API.patch rename to patches/unapplied/0580-More-CommandBlock-API.patch diff --git a/patches/server/0581-Add-missing-team-sidebar-display-slots.patch b/patches/unapplied/0581-Add-missing-team-sidebar-display-slots.patch similarity index 100% rename from patches/server/0581-Add-missing-team-sidebar-display-slots.patch rename to patches/unapplied/0581-Add-missing-team-sidebar-display-slots.patch diff --git a/patches/server/0582-Add-back-EntityPortalExitEvent.patch b/patches/unapplied/0582-Add-back-EntityPortalExitEvent.patch similarity index 100% rename from patches/server/0582-Add-back-EntityPortalExitEvent.patch rename to patches/unapplied/0582-Add-back-EntityPortalExitEvent.patch diff --git a/patches/server/0583-Add-methods-to-find-targets-for-lightning-strikes.patch b/patches/unapplied/0583-Add-methods-to-find-targets-for-lightning-strikes.patch similarity index 100% rename from patches/server/0583-Add-methods-to-find-targets-for-lightning-strikes.patch rename to patches/unapplied/0583-Add-methods-to-find-targets-for-lightning-strikes.patch diff --git a/patches/server/0584-Get-entity-default-attributes.patch b/patches/unapplied/0584-Get-entity-default-attributes.patch similarity index 100% rename from patches/server/0584-Get-entity-default-attributes.patch rename to patches/unapplied/0584-Get-entity-default-attributes.patch diff --git a/patches/server/0585-Left-handed-API.patch b/patches/unapplied/0585-Left-handed-API.patch similarity index 100% rename from patches/server/0585-Left-handed-API.patch rename to patches/unapplied/0585-Left-handed-API.patch diff --git a/patches/server/0586-Add-more-advancement-API.patch b/patches/unapplied/0586-Add-more-advancement-API.patch similarity index 100% rename from patches/server/0586-Add-more-advancement-API.patch rename to patches/unapplied/0586-Add-more-advancement-API.patch diff --git a/patches/server/0587-Add-ItemFactory-getSpawnEgg-API.patch b/patches/unapplied/0587-Add-ItemFactory-getSpawnEgg-API.patch similarity index 100% rename from patches/server/0587-Add-ItemFactory-getSpawnEgg-API.patch rename to patches/unapplied/0587-Add-ItemFactory-getSpawnEgg-API.patch diff --git a/patches/server/0588-Add-critical-damage-API.patch b/patches/unapplied/0588-Add-critical-damage-API.patch similarity index 100% rename from patches/server/0588-Add-critical-damage-API.patch rename to patches/unapplied/0588-Add-critical-damage-API.patch diff --git a/patches/server/0589-Fix-issues-with-mob-conversion.patch b/patches/unapplied/0589-Fix-issues-with-mob-conversion.patch similarity index 100% rename from patches/server/0589-Fix-issues-with-mob-conversion.patch rename to patches/unapplied/0589-Fix-issues-with-mob-conversion.patch diff --git a/patches/server/0590-Add-hasCollision-methods-to-various-places.patch b/patches/unapplied/0590-Add-hasCollision-methods-to-various-places.patch similarity index 100% rename from patches/server/0590-Add-hasCollision-methods-to-various-places.patch rename to patches/unapplied/0590-Add-hasCollision-methods-to-various-places.patch diff --git a/patches/server/0591-Goat-ram-API.patch b/patches/unapplied/0591-Goat-ram-API.patch similarity index 100% rename from patches/server/0591-Goat-ram-API.patch rename to patches/unapplied/0591-Goat-ram-API.patch diff --git a/patches/server/0592-Add-API-for-resetting-a-single-score.patch b/patches/unapplied/0592-Add-API-for-resetting-a-single-score.patch similarity index 100% rename from patches/server/0592-Add-API-for-resetting-a-single-score.patch rename to patches/unapplied/0592-Add-API-for-resetting-a-single-score.patch diff --git a/patches/server/0593-Add-Raw-Byte-Entity-Serialization.patch b/patches/unapplied/0593-Add-Raw-Byte-Entity-Serialization.patch similarity index 100% rename from patches/server/0593-Add-Raw-Byte-Entity-Serialization.patch rename to patches/unapplied/0593-Add-Raw-Byte-Entity-Serialization.patch diff --git a/patches/server/0594-Vanilla-command-permission-fixes.patch b/patches/unapplied/0594-Vanilla-command-permission-fixes.patch similarity index 100% rename from patches/server/0594-Vanilla-command-permission-fixes.patch rename to patches/unapplied/0594-Vanilla-command-permission-fixes.patch diff --git a/patches/server/0595-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch b/patches/unapplied/0595-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch similarity index 100% rename from patches/server/0595-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch rename to patches/unapplied/0595-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch diff --git a/patches/server/0596-Fix-GameProfileCache-concurrency.patch b/patches/unapplied/0596-Fix-GameProfileCache-concurrency.patch similarity index 100% rename from patches/server/0596-Fix-GameProfileCache-concurrency.patch rename to patches/unapplied/0596-Fix-GameProfileCache-concurrency.patch diff --git a/patches/server/0597-Improve-and-expand-AsyncCatcher.patch b/patches/unapplied/0597-Improve-and-expand-AsyncCatcher.patch similarity index 100% rename from patches/server/0597-Improve-and-expand-AsyncCatcher.patch rename to patches/unapplied/0597-Improve-and-expand-AsyncCatcher.patch diff --git a/patches/server/0598-Add-paper-mobcaps-and-paper-playermobcaps.patch b/patches/unapplied/0598-Add-paper-mobcaps-and-paper-playermobcaps.patch similarity index 100% rename from patches/server/0598-Add-paper-mobcaps-and-paper-playermobcaps.patch rename to patches/unapplied/0598-Add-paper-mobcaps-and-paper-playermobcaps.patch diff --git a/patches/server/0599-Sanitize-ResourceLocation-error-logging.patch b/patches/unapplied/0599-Sanitize-ResourceLocation-error-logging.patch similarity index 100% rename from patches/server/0599-Sanitize-ResourceLocation-error-logging.patch rename to patches/unapplied/0599-Sanitize-ResourceLocation-error-logging.patch diff --git a/patches/server/0600-Manually-inline-methods-in-BlockPosition.patch b/patches/unapplied/0600-Manually-inline-methods-in-BlockPosition.patch similarity index 100% rename from patches/server/0600-Manually-inline-methods-in-BlockPosition.patch rename to patches/unapplied/0600-Manually-inline-methods-in-BlockPosition.patch diff --git a/patches/server/0601-Name-craft-scheduler-threads-according-to-the-plugin.patch b/patches/unapplied/0601-Name-craft-scheduler-threads-according-to-the-plugin.patch similarity index 100% rename from patches/server/0601-Name-craft-scheduler-threads-according-to-the-plugin.patch rename to patches/unapplied/0601-Name-craft-scheduler-threads-according-to-the-plugin.patch diff --git a/patches/server/0602-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch b/patches/unapplied/0602-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch similarity index 100% rename from patches/server/0602-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch rename to patches/unapplied/0602-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch diff --git a/patches/server/0603-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch b/patches/unapplied/0603-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch similarity index 100% rename from patches/server/0603-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch rename to patches/unapplied/0603-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch diff --git a/patches/server/0604-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch b/patches/unapplied/0604-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch similarity index 100% rename from patches/server/0604-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch rename to patches/unapplied/0604-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch diff --git a/patches/server/0605-Time-scoreboard-search.patch b/patches/unapplied/0605-Time-scoreboard-search.patch similarity index 100% rename from patches/server/0605-Time-scoreboard-search.patch rename to patches/unapplied/0605-Time-scoreboard-search.patch diff --git a/patches/server/0606-Oprimise-map-impl-for-tracked-players.patch b/patches/unapplied/0606-Oprimise-map-impl-for-tracked-players.patch similarity index 100% rename from patches/server/0606-Oprimise-map-impl-for-tracked-players.patch rename to patches/unapplied/0606-Oprimise-map-impl-for-tracked-players.patch diff --git a/patches/server/0607-Add-missing-InventoryType.patch b/patches/unapplied/0607-Add-missing-InventoryType.patch similarity index 100% rename from patches/server/0607-Add-missing-InventoryType.patch rename to patches/unapplied/0607-Add-missing-InventoryType.patch diff --git a/patches/server/0608-Optimise-BlockSoil-nearby-water-lookup.patch b/patches/unapplied/0608-Optimise-BlockSoil-nearby-water-lookup.patch similarity index 100% rename from patches/server/0608-Optimise-BlockSoil-nearby-water-lookup.patch rename to patches/unapplied/0608-Optimise-BlockSoil-nearby-water-lookup.patch diff --git a/patches/server/0609-Fix-merchant-inventory-not-closing-on-entity-removal.patch b/patches/unapplied/0609-Fix-merchant-inventory-not-closing-on-entity-removal.patch similarity index 100% rename from patches/server/0609-Fix-merchant-inventory-not-closing-on-entity-removal.patch rename to patches/unapplied/0609-Fix-merchant-inventory-not-closing-on-entity-removal.patch diff --git a/patches/server/0610-Check-requirement-before-suggesting-root-nodes.patch b/patches/unapplied/0610-Check-requirement-before-suggesting-root-nodes.patch similarity index 100% rename from patches/server/0610-Check-requirement-before-suggesting-root-nodes.patch rename to patches/unapplied/0610-Check-requirement-before-suggesting-root-nodes.patch diff --git a/patches/server/0611-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch b/patches/unapplied/0611-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch similarity index 100% rename from patches/server/0611-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch rename to patches/unapplied/0611-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch diff --git a/patches/server/0612-Add-packet-limiter-config.patch b/patches/unapplied/0612-Add-packet-limiter-config.patch similarity index 100% rename from patches/server/0612-Add-packet-limiter-config.patch rename to patches/unapplied/0612-Add-packet-limiter-config.patch diff --git a/patches/server/0613-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch b/patches/unapplied/0613-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch similarity index 100% rename from patches/server/0613-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch rename to patches/unapplied/0613-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch diff --git a/patches/server/0614-Ensure-valid-vehicle-status.patch b/patches/unapplied/0614-Ensure-valid-vehicle-status.patch similarity index 100% rename from patches/server/0614-Ensure-valid-vehicle-status.patch rename to patches/unapplied/0614-Ensure-valid-vehicle-status.patch diff --git a/patches/server/0615-Prevent-softlocked-end-exit-portal-generation.patch b/patches/unapplied/0615-Prevent-softlocked-end-exit-portal-generation.patch similarity index 100% rename from patches/server/0615-Prevent-softlocked-end-exit-portal-generation.patch rename to patches/unapplied/0615-Prevent-softlocked-end-exit-portal-generation.patch diff --git a/patches/server/0616-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch b/patches/unapplied/0616-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch similarity index 100% rename from patches/server/0616-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch rename to patches/unapplied/0616-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch diff --git a/patches/server/0617-Don-t-log-debug-logging-being-disabled.patch b/patches/unapplied/0617-Don-t-log-debug-logging-being-disabled.patch similarity index 100% rename from patches/server/0617-Don-t-log-debug-logging-being-disabled.patch rename to patches/unapplied/0617-Don-t-log-debug-logging-being-disabled.patch diff --git a/patches/server/0618-fix-various-menus-with-empty-level-accesses.patch b/patches/unapplied/0618-fix-various-menus-with-empty-level-accesses.patch similarity index 100% rename from patches/server/0618-fix-various-menus-with-empty-level-accesses.patch rename to patches/unapplied/0618-fix-various-menus-with-empty-level-accesses.patch diff --git a/patches/server/0619-Preserve-overstacked-loot.patch b/patches/unapplied/0619-Preserve-overstacked-loot.patch similarity index 100% rename from patches/server/0619-Preserve-overstacked-loot.patch rename to patches/unapplied/0619-Preserve-overstacked-loot.patch diff --git a/patches/server/0620-Update-head-rotation-in-missing-places.patch b/patches/unapplied/0620-Update-head-rotation-in-missing-places.patch similarity index 100% rename from patches/server/0620-Update-head-rotation-in-missing-places.patch rename to patches/unapplied/0620-Update-head-rotation-in-missing-places.patch diff --git a/patches/server/0621-prevent-unintended-light-block-manipulation.patch b/patches/unapplied/0621-prevent-unintended-light-block-manipulation.patch similarity index 100% rename from patches/server/0621-prevent-unintended-light-block-manipulation.patch rename to patches/unapplied/0621-prevent-unintended-light-block-manipulation.patch diff --git a/patches/server/0622-Fix-CraftCriteria-defaults-map.patch b/patches/unapplied/0622-Fix-CraftCriteria-defaults-map.patch similarity index 100% rename from patches/server/0622-Fix-CraftCriteria-defaults-map.patch rename to patches/unapplied/0622-Fix-CraftCriteria-defaults-map.patch diff --git a/patches/server/0623-Fix-upstreams-block-state-factories.patch b/patches/unapplied/0623-Fix-upstreams-block-state-factories.patch similarity index 100% rename from patches/server/0623-Fix-upstreams-block-state-factories.patch rename to patches/unapplied/0623-Fix-upstreams-block-state-factories.patch diff --git a/patches/server/0624-Configurable-feature-seeds.patch b/patches/unapplied/0624-Configurable-feature-seeds.patch similarity index 100% rename from patches/server/0624-Configurable-feature-seeds.patch rename to patches/unapplied/0624-Configurable-feature-seeds.patch diff --git a/patches/server/0625-Add-root-admin-user-detection.patch b/patches/unapplied/0625-Add-root-admin-user-detection.patch similarity index 100% rename from patches/server/0625-Add-root-admin-user-detection.patch rename to patches/unapplied/0625-Add-root-admin-user-detection.patch diff --git a/patches/server/0626-don-t-attempt-to-teleport-dead-entities.patch b/patches/unapplied/0626-don-t-attempt-to-teleport-dead-entities.patch similarity index 100% rename from patches/server/0626-don-t-attempt-to-teleport-dead-entities.patch rename to patches/unapplied/0626-don-t-attempt-to-teleport-dead-entities.patch diff --git a/patches/server/0627-Prevent-excessive-velocity-through-repeated-crits.patch b/patches/unapplied/0627-Prevent-excessive-velocity-through-repeated-crits.patch similarity index 100% rename from patches/server/0627-Prevent-excessive-velocity-through-repeated-crits.patch rename to patches/unapplied/0627-Prevent-excessive-velocity-through-repeated-crits.patch diff --git a/patches/server/0628-Remove-client-side-code-using-deprecated-for-removal.patch b/patches/unapplied/0628-Remove-client-side-code-using-deprecated-for-removal.patch similarity index 100% rename from patches/server/0628-Remove-client-side-code-using-deprecated-for-removal.patch rename to patches/unapplied/0628-Remove-client-side-code-using-deprecated-for-removal.patch diff --git a/patches/server/0629-Fix-Spigot-growth-modifiers.patch b/patches/unapplied/0629-Fix-Spigot-growth-modifiers.patch similarity index 100% rename from patches/server/0629-Fix-Spigot-growth-modifiers.patch rename to patches/unapplied/0629-Fix-Spigot-growth-modifiers.patch diff --git a/patches/server/0630-Prevent-ContainerOpenersCounter-openCount-from-going.patch b/patches/unapplied/0630-Prevent-ContainerOpenersCounter-openCount-from-going.patch similarity index 100% rename from patches/server/0630-Prevent-ContainerOpenersCounter-openCount-from-going.patch rename to patches/unapplied/0630-Prevent-ContainerOpenersCounter-openCount-from-going.patch diff --git a/patches/server/0631-Add-PlayerItemFrameChangeEvent.patch b/patches/unapplied/0631-Add-PlayerItemFrameChangeEvent.patch similarity index 100% rename from patches/server/0631-Add-PlayerItemFrameChangeEvent.patch rename to patches/unapplied/0631-Add-PlayerItemFrameChangeEvent.patch diff --git a/patches/server/0632-Optimize-HashMapPalette.patch b/patches/unapplied/0632-Optimize-HashMapPalette.patch similarity index 100% rename from patches/server/0632-Optimize-HashMapPalette.patch rename to patches/unapplied/0632-Optimize-HashMapPalette.patch diff --git a/patches/server/0633-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch b/patches/unapplied/0633-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch similarity index 100% rename from patches/server/0633-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch rename to patches/unapplied/0633-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch diff --git a/patches/server/0634-Add-more-Campfire-API.patch b/patches/unapplied/0634-Add-more-Campfire-API.patch similarity index 100% rename from patches/server/0634-Add-more-Campfire-API.patch rename to patches/unapplied/0634-Add-more-Campfire-API.patch diff --git a/patches/server/0635-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch b/patches/unapplied/0635-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch similarity index 100% rename from patches/server/0635-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch rename to patches/unapplied/0635-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch diff --git a/patches/server/0636-Forward-CraftEntity-in-teleport-command.patch b/patches/unapplied/0636-Forward-CraftEntity-in-teleport-command.patch similarity index 100% rename from patches/server/0636-Forward-CraftEntity-in-teleport-command.patch rename to patches/unapplied/0636-Forward-CraftEntity-in-teleport-command.patch diff --git a/patches/server/0637-Improve-scoreboard-entries.patch b/patches/unapplied/0637-Improve-scoreboard-entries.patch similarity index 100% rename from patches/server/0637-Improve-scoreboard-entries.patch rename to patches/unapplied/0637-Improve-scoreboard-entries.patch diff --git a/patches/server/0638-Entity-powdered-snow-API.patch b/patches/unapplied/0638-Entity-powdered-snow-API.patch similarity index 100% rename from patches/server/0638-Entity-powdered-snow-API.patch rename to patches/unapplied/0638-Entity-powdered-snow-API.patch diff --git a/patches/server/0639-Add-API-for-item-entity-health.patch b/patches/unapplied/0639-Add-API-for-item-entity-health.patch similarity index 100% rename from patches/server/0639-Add-API-for-item-entity-health.patch rename to patches/unapplied/0639-Add-API-for-item-entity-health.patch diff --git a/patches/server/0640-Configurable-max-block-light-for-monster-spawning.patch b/patches/unapplied/0640-Configurable-max-block-light-for-monster-spawning.patch similarity index 100% rename from patches/server/0640-Configurable-max-block-light-for-monster-spawning.patch rename to patches/unapplied/0640-Configurable-max-block-light-for-monster-spawning.patch diff --git a/patches/server/0641-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch b/patches/unapplied/0641-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch similarity index 100% rename from patches/server/0641-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch rename to patches/unapplied/0641-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch diff --git a/patches/server/0642-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch b/patches/unapplied/0642-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch similarity index 100% rename from patches/server/0642-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch rename to patches/unapplied/0642-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch diff --git a/patches/server/0643-Bucketable-API.patch b/patches/unapplied/0643-Bucketable-API.patch similarity index 100% rename from patches/server/0643-Bucketable-API.patch rename to patches/unapplied/0643-Bucketable-API.patch diff --git a/patches/server/0644-Validate-usernames.patch b/patches/unapplied/0644-Validate-usernames.patch similarity index 100% rename from patches/server/0644-Validate-usernames.patch rename to patches/unapplied/0644-Validate-usernames.patch diff --git a/patches/server/0645-Make-water-animal-spawn-height-configurable.patch b/patches/unapplied/0645-Make-water-animal-spawn-height-configurable.patch similarity index 100% rename from patches/server/0645-Make-water-animal-spawn-height-configurable.patch rename to patches/unapplied/0645-Make-water-animal-spawn-height-configurable.patch diff --git a/patches/server/0646-Expose-vanilla-BiomeProvider-from-WorldInfo.patch b/patches/unapplied/0646-Expose-vanilla-BiomeProvider-from-WorldInfo.patch similarity index 100% rename from patches/server/0646-Expose-vanilla-BiomeProvider-from-WorldInfo.patch rename to patches/unapplied/0646-Expose-vanilla-BiomeProvider-from-WorldInfo.patch diff --git a/patches/server/0647-Add-config-option-for-worlds-affected-by-time-cmd.patch b/patches/unapplied/0647-Add-config-option-for-worlds-affected-by-time-cmd.patch similarity index 100% rename from patches/server/0647-Add-config-option-for-worlds-affected-by-time-cmd.patch rename to patches/unapplied/0647-Add-config-option-for-worlds-affected-by-time-cmd.patch diff --git a/patches/server/0648-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch b/patches/unapplied/0648-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch similarity index 100% rename from patches/server/0648-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch rename to patches/unapplied/0648-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch diff --git a/patches/server/0649-Multiple-Entries-with-Scoreboards.patch b/patches/unapplied/0649-Multiple-Entries-with-Scoreboards.patch similarity index 100% rename from patches/server/0649-Multiple-Entries-with-Scoreboards.patch rename to patches/unapplied/0649-Multiple-Entries-with-Scoreboards.patch diff --git a/patches/server/0650-Reset-placed-block-on-exception.patch b/patches/unapplied/0650-Reset-placed-block-on-exception.patch similarity index 100% rename from patches/server/0650-Reset-placed-block-on-exception.patch rename to patches/unapplied/0650-Reset-placed-block-on-exception.patch diff --git a/patches/server/0651-Add-configurable-height-for-slime-spawn.patch b/patches/unapplied/0651-Add-configurable-height-for-slime-spawn.patch similarity index 100% rename from patches/server/0651-Add-configurable-height-for-slime-spawn.patch rename to patches/unapplied/0651-Add-configurable-height-for-slime-spawn.patch diff --git a/patches/server/0652-Fix-xp-reward-for-baby-zombies.patch b/patches/unapplied/0652-Fix-xp-reward-for-baby-zombies.patch similarity index 100% rename from patches/server/0652-Fix-xp-reward-for-baby-zombies.patch rename to patches/unapplied/0652-Fix-xp-reward-for-baby-zombies.patch diff --git a/patches/server/0653-Multi-Block-Change-API-Implementation.patch b/patches/unapplied/0653-Multi-Block-Change-API-Implementation.patch similarity index 100% rename from patches/server/0653-Multi-Block-Change-API-Implementation.patch rename to patches/unapplied/0653-Multi-Block-Change-API-Implementation.patch diff --git a/patches/server/0654-Fix-NotePlayEvent.patch b/patches/unapplied/0654-Fix-NotePlayEvent.patch similarity index 100% rename from patches/server/0654-Fix-NotePlayEvent.patch rename to patches/unapplied/0654-Fix-NotePlayEvent.patch diff --git a/patches/server/0655-Freeze-Tick-Lock-API.patch b/patches/unapplied/0655-Freeze-Tick-Lock-API.patch similarity index 100% rename from patches/server/0655-Freeze-Tick-Lock-API.patch rename to patches/unapplied/0655-Freeze-Tick-Lock-API.patch diff --git a/patches/server/0656-More-PotionEffectType-API.patch b/patches/unapplied/0656-More-PotionEffectType-API.patch similarity index 100% rename from patches/server/0656-More-PotionEffectType-API.patch rename to patches/unapplied/0656-More-PotionEffectType-API.patch diff --git a/patches/server/0657-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch b/patches/unapplied/0657-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch similarity index 100% rename from patches/server/0657-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch rename to patches/unapplied/0657-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch diff --git a/patches/server/0658-API-for-creating-command-sender-which-forwards-feedb.patch b/patches/unapplied/0658-API-for-creating-command-sender-which-forwards-feedb.patch similarity index 100% rename from patches/server/0658-API-for-creating-command-sender-which-forwards-feedb.patch rename to patches/unapplied/0658-API-for-creating-command-sender-which-forwards-feedb.patch diff --git a/patches/server/0659-Add-missing-structure-set-seed-configs.patch b/patches/unapplied/0659-Add-missing-structure-set-seed-configs.patch similarity index 100% rename from patches/server/0659-Add-missing-structure-set-seed-configs.patch rename to patches/unapplied/0659-Add-missing-structure-set-seed-configs.patch diff --git a/patches/server/0660-Fix-cancelled-powdered-snow-bucket-placement.patch b/patches/unapplied/0660-Fix-cancelled-powdered-snow-bucket-placement.patch similarity index 100% rename from patches/server/0660-Fix-cancelled-powdered-snow-bucket-placement.patch rename to patches/unapplied/0660-Fix-cancelled-powdered-snow-bucket-placement.patch diff --git a/patches/server/0661-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch b/patches/unapplied/0661-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch similarity index 100% rename from patches/server/0661-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch rename to patches/unapplied/0661-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch diff --git a/patches/server/0662-Add-GameEvent-tags.patch b/patches/unapplied/0662-Add-GameEvent-tags.patch similarity index 100% rename from patches/server/0662-Add-GameEvent-tags.patch rename to patches/unapplied/0662-Add-GameEvent-tags.patch diff --git a/patches/server/0663-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch b/patches/unapplied/0663-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch similarity index 100% rename from patches/server/0663-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch rename to patches/unapplied/0663-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch diff --git a/patches/server/0664-Furnace-RecipesUsed-API.patch b/patches/unapplied/0664-Furnace-RecipesUsed-API.patch similarity index 100% rename from patches/server/0664-Furnace-RecipesUsed-API.patch rename to patches/unapplied/0664-Furnace-RecipesUsed-API.patch diff --git a/patches/server/0665-Configurable-sculk-sensor-listener-range.patch b/patches/unapplied/0665-Configurable-sculk-sensor-listener-range.patch similarity index 100% rename from patches/server/0665-Configurable-sculk-sensor-listener-range.patch rename to patches/unapplied/0665-Configurable-sculk-sensor-listener-range.patch diff --git a/patches/server/0666-Add-missing-block-data-API.patch b/patches/unapplied/0666-Add-missing-block-data-API.patch similarity index 100% rename from patches/server/0666-Add-missing-block-data-API.patch rename to patches/unapplied/0666-Add-missing-block-data-API.patch diff --git a/patches/server/0667-Option-to-have-default-CustomSpawners-in-custom-worl.patch b/patches/unapplied/0667-Option-to-have-default-CustomSpawners-in-custom-worl.patch similarity index 100% rename from patches/server/0667-Option-to-have-default-CustomSpawners-in-custom-worl.patch rename to patches/unapplied/0667-Option-to-have-default-CustomSpawners-in-custom-worl.patch diff --git a/patches/server/0668-Put-world-into-worldlist-before-initing-the-world.patch b/patches/unapplied/0668-Put-world-into-worldlist-before-initing-the-world.patch similarity index 100% rename from patches/server/0668-Put-world-into-worldlist-before-initing-the-world.patch rename to patches/unapplied/0668-Put-world-into-worldlist-before-initing-the-world.patch diff --git a/patches/server/0669-Custom-Potion-Mixes.patch b/patches/unapplied/0669-Custom-Potion-Mixes.patch similarity index 100% rename from patches/server/0669-Custom-Potion-Mixes.patch rename to patches/unapplied/0669-Custom-Potion-Mixes.patch diff --git a/patches/server/0670-Force-close-world-loading-screen.patch b/patches/unapplied/0670-Force-close-world-loading-screen.patch similarity index 100% rename from patches/server/0670-Force-close-world-loading-screen.patch rename to patches/unapplied/0670-Force-close-world-loading-screen.patch diff --git a/patches/server/0671-Fix-falling-block-spawn-methods.patch b/patches/unapplied/0671-Fix-falling-block-spawn-methods.patch similarity index 100% rename from patches/server/0671-Fix-falling-block-spawn-methods.patch rename to patches/unapplied/0671-Fix-falling-block-spawn-methods.patch diff --git a/patches/server/0672-Expose-furnace-minecart-push-values.patch b/patches/unapplied/0672-Expose-furnace-minecart-push-values.patch similarity index 100% rename from patches/server/0672-Expose-furnace-minecart-push-values.patch rename to patches/unapplied/0672-Expose-furnace-minecart-push-values.patch diff --git a/patches/server/0673-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch b/patches/unapplied/0673-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch similarity index 100% rename from patches/server/0673-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch rename to patches/unapplied/0673-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch diff --git a/patches/server/0674-More-Projectile-API.patch b/patches/unapplied/0674-More-Projectile-API.patch similarity index 100% rename from patches/server/0674-More-Projectile-API.patch rename to patches/unapplied/0674-More-Projectile-API.patch diff --git a/patches/server/0675-Fix-swamp-hut-cat-generation-deadlock.patch b/patches/unapplied/0675-Fix-swamp-hut-cat-generation-deadlock.patch similarity index 100% rename from patches/server/0675-Fix-swamp-hut-cat-generation-deadlock.patch rename to patches/unapplied/0675-Fix-swamp-hut-cat-generation-deadlock.patch diff --git a/patches/server/0676-Don-t-allow-vehicle-movement-from-players-while-tele.patch b/patches/unapplied/0676-Don-t-allow-vehicle-movement-from-players-while-tele.patch similarity index 100% rename from patches/server/0676-Don-t-allow-vehicle-movement-from-players-while-tele.patch rename to patches/unapplied/0676-Don-t-allow-vehicle-movement-from-players-while-tele.patch diff --git a/patches/server/0677-Implement-getComputedBiome-API.patch b/patches/unapplied/0677-Implement-getComputedBiome-API.patch similarity index 100% rename from patches/server/0677-Implement-getComputedBiome-API.patch rename to patches/unapplied/0677-Implement-getComputedBiome-API.patch diff --git a/patches/server/0678-Make-some-itemstacks-nonnull.patch b/patches/unapplied/0678-Make-some-itemstacks-nonnull.patch similarity index 100% rename from patches/server/0678-Make-some-itemstacks-nonnull.patch rename to patches/unapplied/0678-Make-some-itemstacks-nonnull.patch diff --git a/patches/server/0679-Implement-enchantWithLevels-API.patch b/patches/unapplied/0679-Implement-enchantWithLevels-API.patch similarity index 100% rename from patches/server/0679-Implement-enchantWithLevels-API.patch rename to patches/unapplied/0679-Implement-enchantWithLevels-API.patch diff --git a/patches/server/0680-Fix-saving-in-unloadWorld.patch b/patches/unapplied/0680-Fix-saving-in-unloadWorld.patch similarity index 100% rename from patches/server/0680-Fix-saving-in-unloadWorld.patch rename to patches/unapplied/0680-Fix-saving-in-unloadWorld.patch diff --git a/patches/server/0681-Buffer-OOB-setBlock-calls.patch b/patches/unapplied/0681-Buffer-OOB-setBlock-calls.patch similarity index 100% rename from patches/server/0681-Buffer-OOB-setBlock-calls.patch rename to patches/unapplied/0681-Buffer-OOB-setBlock-calls.patch diff --git a/patches/server/0682-Add-TameableDeathMessageEvent.patch b/patches/unapplied/0682-Add-TameableDeathMessageEvent.patch similarity index 100% rename from patches/server/0682-Add-TameableDeathMessageEvent.patch rename to patches/unapplied/0682-Add-TameableDeathMessageEvent.patch diff --git a/patches/server/0683-Fix-new-block-data-for-EntityChangeBlockEvent.patch b/patches/unapplied/0683-Fix-new-block-data-for-EntityChangeBlockEvent.patch similarity index 100% rename from patches/server/0683-Fix-new-block-data-for-EntityChangeBlockEvent.patch rename to patches/unapplied/0683-Fix-new-block-data-for-EntityChangeBlockEvent.patch diff --git a/patches/server/0684-fix-player-loottables-running-when-mob-loot-gamerule.patch b/patches/unapplied/0684-fix-player-loottables-running-when-mob-loot-gamerule.patch similarity index 100% rename from patches/server/0684-fix-player-loottables-running-when-mob-loot-gamerule.patch rename to patches/unapplied/0684-fix-player-loottables-running-when-mob-loot-gamerule.patch diff --git a/patches/server/0685-Ensure-entity-passenger-world-matches-ridden-entity.patch b/patches/unapplied/0685-Ensure-entity-passenger-world-matches-ridden-entity.patch similarity index 100% rename from patches/server/0685-Ensure-entity-passenger-world-matches-ridden-entity.patch rename to patches/unapplied/0685-Ensure-entity-passenger-world-matches-ridden-entity.patch diff --git a/patches/server/0686-Cache-resource-keys-and-optimize-reference-Holder-ta.patch b/patches/unapplied/0686-Cache-resource-keys-and-optimize-reference-Holder-ta.patch similarity index 100% rename from patches/server/0686-Cache-resource-keys-and-optimize-reference-Holder-ta.patch rename to patches/unapplied/0686-Cache-resource-keys-and-optimize-reference-Holder-ta.patch diff --git a/patches/server/0687-Allow-changing-the-EnderDragon-podium.patch b/patches/unapplied/0687-Allow-changing-the-EnderDragon-podium.patch similarity index 100% rename from patches/server/0687-Allow-changing-the-EnderDragon-podium.patch rename to patches/unapplied/0687-Allow-changing-the-EnderDragon-podium.patch diff --git a/patches/server/0688-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch b/patches/unapplied/0688-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch similarity index 100% rename from patches/server/0688-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch rename to patches/unapplied/0688-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch diff --git a/patches/server/0689-Prevent-tile-entity-copies-loading-chunks.patch b/patches/unapplied/0689-Prevent-tile-entity-copies-loading-chunks.patch similarity index 100% rename from patches/server/0689-Prevent-tile-entity-copies-loading-chunks.patch rename to patches/unapplied/0689-Prevent-tile-entity-copies-loading-chunks.patch diff --git a/patches/server/0690-Use-username-instead-of-display-name-in-PlayerList-g.patch b/patches/unapplied/0690-Use-username-instead-of-display-name-in-PlayerList-g.patch similarity index 100% rename from patches/server/0690-Use-username-instead-of-display-name-in-PlayerList-g.patch rename to patches/unapplied/0690-Use-username-instead-of-display-name-in-PlayerList-g.patch diff --git a/patches/server/0691-Expand-PlayerItemDamageEvent.patch b/patches/unapplied/0691-Expand-PlayerItemDamageEvent.patch similarity index 100% rename from patches/server/0691-Expand-PlayerItemDamageEvent.patch rename to patches/unapplied/0691-Expand-PlayerItemDamageEvent.patch diff --git a/patches/server/0692-WorldCreator-keepSpawnLoaded.patch b/patches/unapplied/0692-WorldCreator-keepSpawnLoaded.patch similarity index 100% rename from patches/server/0692-WorldCreator-keepSpawnLoaded.patch rename to patches/unapplied/0692-WorldCreator-keepSpawnLoaded.patch diff --git a/patches/server/0693-Fix-CME-in-CraftPersistentDataTypeRegistry.patch b/patches/unapplied/0693-Fix-CME-in-CraftPersistentDataTypeRegistry.patch similarity index 100% rename from patches/server/0693-Fix-CME-in-CraftPersistentDataTypeRegistry.patch rename to patches/unapplied/0693-Fix-CME-in-CraftPersistentDataTypeRegistry.patch diff --git a/patches/server/0694-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch b/patches/unapplied/0694-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch similarity index 100% rename from patches/server/0694-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch rename to patches/unapplied/0694-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch diff --git a/patches/server/0695-Add-EntityDyeEvent-and-CollarColorable-interface.patch b/patches/unapplied/0695-Add-EntityDyeEvent-and-CollarColorable-interface.patch similarity index 100% rename from patches/server/0695-Add-EntityDyeEvent-and-CollarColorable-interface.patch rename to patches/unapplied/0695-Add-EntityDyeEvent-and-CollarColorable-interface.patch diff --git a/patches/server/0696-Fire-CauldronLevelChange-on-initial-fill.patch b/patches/unapplied/0696-Fire-CauldronLevelChange-on-initial-fill.patch similarity index 100% rename from patches/server/0696-Fire-CauldronLevelChange-on-initial-fill.patch rename to patches/unapplied/0696-Fire-CauldronLevelChange-on-initial-fill.patch diff --git a/patches/server/0697-fix-powder-snow-cauldrons-not-turning-to-water.patch b/patches/unapplied/0697-fix-powder-snow-cauldrons-not-turning-to-water.patch similarity index 100% rename from patches/server/0697-fix-powder-snow-cauldrons-not-turning-to-water.patch rename to patches/unapplied/0697-fix-powder-snow-cauldrons-not-turning-to-water.patch diff --git a/patches/server/0698-Add-PlayerStopUsingItemEvent.patch b/patches/unapplied/0698-Add-PlayerStopUsingItemEvent.patch similarity index 100% rename from patches/server/0698-Add-PlayerStopUsingItemEvent.patch rename to patches/unapplied/0698-Add-PlayerStopUsingItemEvent.patch diff --git a/patches/server/0699-Don-t-tick-markers.patch b/patches/unapplied/0699-Don-t-tick-markers.patch similarity index 100% rename from patches/server/0699-Don-t-tick-markers.patch rename to patches/unapplied/0699-Don-t-tick-markers.patch diff --git a/patches/server/0700-Expand-FallingBlock-API.patch b/patches/unapplied/0700-Expand-FallingBlock-API.patch similarity index 100% rename from patches/server/0700-Expand-FallingBlock-API.patch rename to patches/unapplied/0700-Expand-FallingBlock-API.patch diff --git a/patches/server/0701-Add-support-for-Proxy-Protocol.patch b/patches/unapplied/0701-Add-support-for-Proxy-Protocol.patch similarity index 100% rename from patches/server/0701-Add-support-for-Proxy-Protocol.patch rename to patches/unapplied/0701-Add-support-for-Proxy-Protocol.patch diff --git a/patches/server/0702-Fix-OfflinePlayer-getBedSpawnLocation.patch b/patches/unapplied/0702-Fix-OfflinePlayer-getBedSpawnLocation.patch similarity index 100% rename from patches/server/0702-Fix-OfflinePlayer-getBedSpawnLocation.patch rename to patches/unapplied/0702-Fix-OfflinePlayer-getBedSpawnLocation.patch diff --git a/patches/server/0703-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch b/patches/unapplied/0703-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch similarity index 100% rename from patches/server/0703-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch rename to patches/unapplied/0703-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch diff --git a/patches/server/0704-Sanitize-sent-BlockEntity-NBT.patch b/patches/unapplied/0704-Sanitize-sent-BlockEntity-NBT.patch similarity index 100% rename from patches/server/0704-Sanitize-sent-BlockEntity-NBT.patch rename to patches/unapplied/0704-Sanitize-sent-BlockEntity-NBT.patch diff --git a/patches/server/0705-Disable-component-selector-resolving-in-books-by-def.patch b/patches/unapplied/0705-Disable-component-selector-resolving-in-books-by-def.patch similarity index 100% rename from patches/server/0705-Disable-component-selector-resolving-in-books-by-def.patch rename to patches/unapplied/0705-Disable-component-selector-resolving-in-books-by-def.patch diff --git a/patches/server/0706-Prevent-entity-loading-causing-async-lookups.patch b/patches/unapplied/0706-Prevent-entity-loading-causing-async-lookups.patch similarity index 100% rename from patches/server/0706-Prevent-entity-loading-causing-async-lookups.patch rename to patches/unapplied/0706-Prevent-entity-loading-causing-async-lookups.patch diff --git a/patches/server/0707-Throw-exception-on-world-create-while-being-ticked.patch b/patches/unapplied/0707-Throw-exception-on-world-create-while-being-ticked.patch similarity index 100% rename from patches/server/0707-Throw-exception-on-world-create-while-being-ticked.patch rename to patches/unapplied/0707-Throw-exception-on-world-create-while-being-ticked.patch diff --git a/patches/server/0708-Dont-resent-entity-on-art-update.patch b/patches/unapplied/0708-Dont-resent-entity-on-art-update.patch similarity index 100% rename from patches/server/0708-Dont-resent-entity-on-art-update.patch rename to patches/unapplied/0708-Dont-resent-entity-on-art-update.patch diff --git a/patches/server/0709-Add-WardenAngerChangeEvent.patch b/patches/unapplied/0709-Add-WardenAngerChangeEvent.patch similarity index 100% rename from patches/server/0709-Add-WardenAngerChangeEvent.patch rename to patches/unapplied/0709-Add-WardenAngerChangeEvent.patch diff --git a/patches/server/0710-Add-option-for-strict-advancement-dimension-checks.patch b/patches/unapplied/0710-Add-option-for-strict-advancement-dimension-checks.patch similarity index 100% rename from patches/server/0710-Add-option-for-strict-advancement-dimension-checks.patch rename to patches/unapplied/0710-Add-option-for-strict-advancement-dimension-checks.patch diff --git a/patches/server/0711-Add-missing-important-BlockStateListPopulator-method.patch b/patches/unapplied/0711-Add-missing-important-BlockStateListPopulator-method.patch similarity index 100% rename from patches/server/0711-Add-missing-important-BlockStateListPopulator-method.patch rename to patches/unapplied/0711-Add-missing-important-BlockStateListPopulator-method.patch diff --git a/patches/server/0712-Nameable-Banner-API.patch b/patches/unapplied/0712-Nameable-Banner-API.patch similarity index 100% rename from patches/server/0712-Nameable-Banner-API.patch rename to patches/unapplied/0712-Nameable-Banner-API.patch diff --git a/patches/server/0713-Don-t-broadcast-messages-to-command-blocks.patch b/patches/unapplied/0713-Don-t-broadcast-messages-to-command-blocks.patch similarity index 100% rename from patches/server/0713-Don-t-broadcast-messages-to-command-blocks.patch rename to patches/unapplied/0713-Don-t-broadcast-messages-to-command-blocks.patch diff --git a/patches/server/0714-Prevent-empty-items-from-being-added-to-world.patch b/patches/unapplied/0714-Prevent-empty-items-from-being-added-to-world.patch similarity index 100% rename from patches/server/0714-Prevent-empty-items-from-being-added-to-world.patch rename to patches/unapplied/0714-Prevent-empty-items-from-being-added-to-world.patch diff --git a/patches/server/0715-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch b/patches/unapplied/0715-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch similarity index 100% rename from patches/server/0715-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch rename to patches/unapplied/0715-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch diff --git a/patches/server/0716-Add-Player-getFishHook.patch b/patches/unapplied/0716-Add-Player-getFishHook.patch similarity index 100% rename from patches/server/0716-Add-Player-getFishHook.patch rename to patches/unapplied/0716-Add-Player-getFishHook.patch diff --git a/patches/server/0717-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch b/patches/unapplied/0717-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch similarity index 100% rename from patches/server/0717-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch rename to patches/unapplied/0717-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch diff --git a/patches/server/0718-Add-various-missing-EntityDropItemEvent-calls.patch b/patches/unapplied/0718-Add-various-missing-EntityDropItemEvent-calls.patch similarity index 100% rename from patches/server/0718-Add-various-missing-EntityDropItemEvent-calls.patch rename to patches/unapplied/0718-Add-various-missing-EntityDropItemEvent-calls.patch diff --git a/patches/server/0719-Fix-Bee-flower-NPE.patch b/patches/unapplied/0719-Fix-Bee-flower-NPE.patch similarity index 100% rename from patches/server/0719-Fix-Bee-flower-NPE.patch rename to patches/unapplied/0719-Fix-Bee-flower-NPE.patch diff --git a/patches/server/0720-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch b/patches/unapplied/0720-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch similarity index 100% rename from patches/server/0720-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch rename to patches/unapplied/0720-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch diff --git a/patches/server/0721-More-Teleport-API.patch b/patches/unapplied/0721-More-Teleport-API.patch similarity index 100% rename from patches/server/0721-More-Teleport-API.patch rename to patches/unapplied/0721-More-Teleport-API.patch diff --git a/patches/server/0722-Add-EntityPortalReadyEvent.patch b/patches/unapplied/0722-Add-EntityPortalReadyEvent.patch similarity index 100% rename from patches/server/0722-Add-EntityPortalReadyEvent.patch rename to patches/unapplied/0722-Add-EntityPortalReadyEvent.patch diff --git a/patches/server/0723-Don-t-use-level-random-in-entity-constructors.patch b/patches/unapplied/0723-Don-t-use-level-random-in-entity-constructors.patch similarity index 100% rename from patches/server/0723-Don-t-use-level-random-in-entity-constructors.patch rename to patches/unapplied/0723-Don-t-use-level-random-in-entity-constructors.patch diff --git a/patches/server/0724-Send-block-entities-after-destroy-prediction.patch b/patches/unapplied/0724-Send-block-entities-after-destroy-prediction.patch similarity index 100% rename from patches/server/0724-Send-block-entities-after-destroy-prediction.patch rename to patches/unapplied/0724-Send-block-entities-after-destroy-prediction.patch diff --git a/patches/server/0725-Warn-on-plugins-accessing-faraway-chunks.patch b/patches/unapplied/0725-Warn-on-plugins-accessing-faraway-chunks.patch similarity index 100% rename from patches/server/0725-Warn-on-plugins-accessing-faraway-chunks.patch rename to patches/unapplied/0725-Warn-on-plugins-accessing-faraway-chunks.patch diff --git a/patches/server/0726-Custom-Chat-Completion-Suggestions-API.patch b/patches/unapplied/0726-Custom-Chat-Completion-Suggestions-API.patch similarity index 100% rename from patches/server/0726-Custom-Chat-Completion-Suggestions-API.patch rename to patches/unapplied/0726-Custom-Chat-Completion-Suggestions-API.patch diff --git a/patches/server/0727-Add-and-fix-missing-BlockFadeEvents.patch b/patches/unapplied/0727-Add-and-fix-missing-BlockFadeEvents.patch similarity index 100% rename from patches/server/0727-Add-and-fix-missing-BlockFadeEvents.patch rename to patches/unapplied/0727-Add-and-fix-missing-BlockFadeEvents.patch diff --git a/patches/server/0728-Collision-API.patch b/patches/unapplied/0728-Collision-API.patch similarity index 100% rename from patches/server/0728-Collision-API.patch rename to patches/unapplied/0728-Collision-API.patch diff --git a/patches/server/0729-Fix-suggest-command-message-for-brigadier-syntax-exc.patch b/patches/unapplied/0729-Fix-suggest-command-message-for-brigadier-syntax-exc.patch similarity index 100% rename from patches/server/0729-Fix-suggest-command-message-for-brigadier-syntax-exc.patch rename to patches/unapplied/0729-Fix-suggest-command-message-for-brigadier-syntax-exc.patch diff --git a/patches/server/0730-Block-Ticking-API.patch b/patches/unapplied/0730-Block-Ticking-API.patch similarity index 100% rename from patches/server/0730-Block-Ticking-API.patch rename to patches/unapplied/0730-Block-Ticking-API.patch diff --git a/patches/server/0731-Add-Velocity-IP-Forwarding-Support.patch b/patches/unapplied/0731-Add-Velocity-IP-Forwarding-Support.patch similarity index 100% rename from patches/server/0731-Add-Velocity-IP-Forwarding-Support.patch rename to patches/unapplied/0731-Add-Velocity-IP-Forwarding-Support.patch diff --git a/patches/server/0732-Add-NamespacedKey-biome-methods.patch b/patches/unapplied/0732-Add-NamespacedKey-biome-methods.patch similarity index 100% rename from patches/server/0732-Add-NamespacedKey-biome-methods.patch rename to patches/unapplied/0732-Add-NamespacedKey-biome-methods.patch diff --git a/patches/server/0733-Fix-plugin-loggers-on-server-shutdown.patch b/patches/unapplied/0733-Fix-plugin-loggers-on-server-shutdown.patch similarity index 100% rename from patches/server/0733-Fix-plugin-loggers-on-server-shutdown.patch rename to patches/unapplied/0733-Fix-plugin-loggers-on-server-shutdown.patch diff --git a/patches/server/0734-Stop-large-look-changes-from-crashing-the-server.patch b/patches/unapplied/0734-Stop-large-look-changes-from-crashing-the-server.patch similarity index 100% rename from patches/server/0734-Stop-large-look-changes-from-crashing-the-server.patch rename to patches/unapplied/0734-Stop-large-look-changes-from-crashing-the-server.patch diff --git a/patches/server/0735-Fire-EntityChangeBlockEvent-in-more-places.patch b/patches/unapplied/0735-Fire-EntityChangeBlockEvent-in-more-places.patch similarity index 100% rename from patches/server/0735-Fire-EntityChangeBlockEvent-in-more-places.patch rename to patches/unapplied/0735-Fire-EntityChangeBlockEvent-in-more-places.patch diff --git a/patches/server/0736-Missing-eating-regain-reason.patch b/patches/unapplied/0736-Missing-eating-regain-reason.patch similarity index 100% rename from patches/server/0736-Missing-eating-regain-reason.patch rename to patches/unapplied/0736-Missing-eating-regain-reason.patch diff --git a/patches/server/0737-Missing-effect-cause.patch b/patches/unapplied/0737-Missing-effect-cause.patch similarity index 100% rename from patches/server/0737-Missing-effect-cause.patch rename to patches/unapplied/0737-Missing-effect-cause.patch diff --git a/patches/server/0738-Added-byte-array-serialization-deserialization-for-P.patch b/patches/unapplied/0738-Added-byte-array-serialization-deserialization-for-P.patch similarity index 100% rename from patches/server/0738-Added-byte-array-serialization-deserialization-for-P.patch rename to patches/unapplied/0738-Added-byte-array-serialization-deserialization-for-P.patch diff --git a/patches/server/0739-Call-BlockPhysicsEvent-more-often.patch b/patches/unapplied/0739-Call-BlockPhysicsEvent-more-often.patch similarity index 100% rename from patches/server/0739-Call-BlockPhysicsEvent-more-often.patch rename to patches/unapplied/0739-Call-BlockPhysicsEvent-more-often.patch diff --git a/patches/server/0740-Configurable-chat-thread-limit.patch b/patches/unapplied/0740-Configurable-chat-thread-limit.patch similarity index 100% rename from patches/server/0740-Configurable-chat-thread-limit.patch rename to patches/unapplied/0740-Configurable-chat-thread-limit.patch diff --git a/patches/server/0741-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch b/patches/unapplied/0741-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch similarity index 100% rename from patches/server/0741-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch rename to patches/unapplied/0741-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch diff --git a/patches/server/0742-fix-Jigsaw-block-kicking-user.patch b/patches/unapplied/0742-fix-Jigsaw-block-kicking-user.patch similarity index 100% rename from patches/server/0742-fix-Jigsaw-block-kicking-user.patch rename to patches/unapplied/0742-fix-Jigsaw-block-kicking-user.patch diff --git a/patches/server/0743-use-BlockFormEvent-for-mud-converting-into-clay.patch b/patches/unapplied/0743-use-BlockFormEvent-for-mud-converting-into-clay.patch similarity index 100% rename from patches/server/0743-use-BlockFormEvent-for-mud-converting-into-clay.patch rename to patches/unapplied/0743-use-BlockFormEvent-for-mud-converting-into-clay.patch diff --git a/patches/server/0744-Add-getDrops-to-BlockState.patch b/patches/unapplied/0744-Add-getDrops-to-BlockState.patch similarity index 100% rename from patches/server/0744-Add-getDrops-to-BlockState.patch rename to patches/unapplied/0744-Add-getDrops-to-BlockState.patch diff --git a/patches/server/0745-Fix-a-bunch-of-vanilla-bugs.patch b/patches/unapplied/0745-Fix-a-bunch-of-vanilla-bugs.patch similarity index 100% rename from patches/server/0745-Fix-a-bunch-of-vanilla-bugs.patch rename to patches/unapplied/0745-Fix-a-bunch-of-vanilla-bugs.patch diff --git a/patches/server/0746-Remove-unnecessary-onTrackingStart-during-navigation.patch b/patches/unapplied/0746-Remove-unnecessary-onTrackingStart-during-navigation.patch similarity index 100% rename from patches/server/0746-Remove-unnecessary-onTrackingStart-during-navigation.patch rename to patches/unapplied/0746-Remove-unnecessary-onTrackingStart-during-navigation.patch diff --git a/patches/server/0747-Fix-custom-piglin-loved-items.patch b/patches/unapplied/0747-Fix-custom-piglin-loved-items.patch similarity index 100% rename from patches/server/0747-Fix-custom-piglin-loved-items.patch rename to patches/unapplied/0747-Fix-custom-piglin-loved-items.patch diff --git a/patches/server/0748-EntityPickupItemEvent-fixes.patch b/patches/unapplied/0748-EntityPickupItemEvent-fixes.patch similarity index 100% rename from patches/server/0748-EntityPickupItemEvent-fixes.patch rename to patches/unapplied/0748-EntityPickupItemEvent-fixes.patch diff --git a/patches/server/0749-Correctly-handle-interactions-with-items-on-cooldown.patch b/patches/unapplied/0749-Correctly-handle-interactions-with-items-on-cooldown.patch similarity index 100% rename from patches/server/0749-Correctly-handle-interactions-with-items-on-cooldown.patch rename to patches/unapplied/0749-Correctly-handle-interactions-with-items-on-cooldown.patch diff --git a/patches/server/0750-Add-PlayerInventorySlotChangeEvent.patch b/patches/unapplied/0750-Add-PlayerInventorySlotChangeEvent.patch similarity index 100% rename from patches/server/0750-Add-PlayerInventorySlotChangeEvent.patch rename to patches/unapplied/0750-Add-PlayerInventorySlotChangeEvent.patch diff --git a/patches/server/0751-Elder-Guardian-appearance-API.patch b/patches/unapplied/0751-Elder-Guardian-appearance-API.patch similarity index 100% rename from patches/server/0751-Elder-Guardian-appearance-API.patch rename to patches/unapplied/0751-Elder-Guardian-appearance-API.patch diff --git a/patches/server/0752-Add-entity-knockback-API.patch b/patches/unapplied/0752-Add-entity-knockback-API.patch similarity index 100% rename from patches/server/0752-Add-entity-knockback-API.patch rename to patches/unapplied/0752-Add-entity-knockback-API.patch diff --git a/patches/server/0753-Detect-headless-JREs.patch b/patches/unapplied/0753-Detect-headless-JREs.patch similarity index 100% rename from patches/server/0753-Detect-headless-JREs.patch rename to patches/unapplied/0753-Detect-headless-JREs.patch diff --git a/patches/server/0754-fix-entity-vehicle-collision-event-not-called.patch b/patches/unapplied/0754-fix-entity-vehicle-collision-event-not-called.patch similarity index 100% rename from patches/server/0754-fix-entity-vehicle-collision-event-not-called.patch rename to patches/unapplied/0754-fix-entity-vehicle-collision-event-not-called.patch diff --git a/patches/server/0755-Add-EntityToggleSitEvent.patch b/patches/unapplied/0755-Add-EntityToggleSitEvent.patch similarity index 100% rename from patches/server/0755-Add-EntityToggleSitEvent.patch rename to patches/unapplied/0755-Add-EntityToggleSitEvent.patch diff --git a/patches/server/0756-Add-fire-tick-delay-option.patch b/patches/unapplied/0756-Add-fire-tick-delay-option.patch similarity index 100% rename from patches/server/0756-Add-fire-tick-delay-option.patch rename to patches/unapplied/0756-Add-fire-tick-delay-option.patch diff --git a/patches/server/0757-Add-Moving-Piston-API.patch b/patches/unapplied/0757-Add-Moving-Piston-API.patch similarity index 100% rename from patches/server/0757-Add-Moving-Piston-API.patch rename to patches/unapplied/0757-Add-Moving-Piston-API.patch diff --git a/patches/server/0758-Ignore-impossible-spawn-tick.patch b/patches/unapplied/0758-Ignore-impossible-spawn-tick.patch similarity index 100% rename from patches/server/0758-Ignore-impossible-spawn-tick.patch rename to patches/unapplied/0758-Ignore-impossible-spawn-tick.patch diff --git a/patches/server/0759-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch b/patches/unapplied/0759-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch similarity index 100% rename from patches/server/0759-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch rename to patches/unapplied/0759-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch diff --git a/patches/server/0760-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch b/patches/unapplied/0760-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch similarity index 100% rename from patches/server/0760-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch rename to patches/unapplied/0760-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch diff --git a/patches/server/0761-Add-PrePlayerAttackEntityEvent.patch b/patches/unapplied/0761-Add-PrePlayerAttackEntityEvent.patch similarity index 100% rename from patches/server/0761-Add-PrePlayerAttackEntityEvent.patch rename to patches/unapplied/0761-Add-PrePlayerAttackEntityEvent.patch diff --git a/patches/server/0762-ensure-reset-EnderDragon-boss-event-name.patch b/patches/unapplied/0762-ensure-reset-EnderDragon-boss-event-name.patch similarity index 100% rename from patches/server/0762-ensure-reset-EnderDragon-boss-event-name.patch rename to patches/unapplied/0762-ensure-reset-EnderDragon-boss-event-name.patch diff --git a/patches/server/0763-Add-Player-Warden-Warning-API.patch b/patches/unapplied/0763-Add-Player-Warden-Warning-API.patch similarity index 100% rename from patches/server/0763-Add-Player-Warden-Warning-API.patch rename to patches/unapplied/0763-Add-Player-Warden-Warning-API.patch diff --git a/patches/server/0764-More-vanilla-friendly-methods-to-update-trades.patch b/patches/unapplied/0764-More-vanilla-friendly-methods-to-update-trades.patch similarity index 100% rename from patches/server/0764-More-vanilla-friendly-methods-to-update-trades.patch rename to patches/unapplied/0764-More-vanilla-friendly-methods-to-update-trades.patch diff --git a/patches/server/0765-Add-paper-dumplisteners-command.patch b/patches/unapplied/0765-Add-paper-dumplisteners-command.patch similarity index 100% rename from patches/server/0765-Add-paper-dumplisteners-command.patch rename to patches/unapplied/0765-Add-paper-dumplisteners-command.patch diff --git a/patches/server/0766-check-global-player-list-where-appropriate.patch b/patches/unapplied/0766-check-global-player-list-where-appropriate.patch similarity index 100% rename from patches/server/0766-check-global-player-list-where-appropriate.patch rename to patches/unapplied/0766-check-global-player-list-where-appropriate.patch diff --git a/patches/server/0767-Fix-async-entity-add-due-to-fungus-trees.patch b/patches/unapplied/0767-Fix-async-entity-add-due-to-fungus-trees.patch similarity index 100% rename from patches/server/0767-Fix-async-entity-add-due-to-fungus-trees.patch rename to patches/unapplied/0767-Fix-async-entity-add-due-to-fungus-trees.patch diff --git a/patches/server/0768-ItemStack-damage-API.patch b/patches/unapplied/0768-ItemStack-damage-API.patch similarity index 100% rename from patches/server/0768-ItemStack-damage-API.patch rename to patches/unapplied/0768-ItemStack-damage-API.patch diff --git a/patches/server/0769-Friction-API.patch b/patches/unapplied/0769-Friction-API.patch similarity index 100% rename from patches/server/0769-Friction-API.patch rename to patches/unapplied/0769-Friction-API.patch diff --git a/patches/server/0770-Ability-to-control-player-s-insomnia-and-phantoms.patch b/patches/unapplied/0770-Ability-to-control-player-s-insomnia-and-phantoms.patch similarity index 100% rename from patches/server/0770-Ability-to-control-player-s-insomnia-and-phantoms.patch rename to patches/unapplied/0770-Ability-to-control-player-s-insomnia-and-phantoms.patch diff --git a/patches/server/0771-Fix-premature-player-kicks-on-shutdown.patch b/patches/unapplied/0771-Fix-premature-player-kicks-on-shutdown.patch similarity index 100% rename from patches/server/0771-Fix-premature-player-kicks-on-shutdown.patch rename to patches/unapplied/0771-Fix-premature-player-kicks-on-shutdown.patch diff --git a/patches/server/0772-Sync-offhand-slot-in-menus.patch b/patches/unapplied/0772-Sync-offhand-slot-in-menus.patch similarity index 100% rename from patches/server/0772-Sync-offhand-slot-in-menus.patch rename to patches/unapplied/0772-Sync-offhand-slot-in-menus.patch diff --git a/patches/server/0773-Player-Entity-Tracking-Events.patch b/patches/unapplied/0773-Player-Entity-Tracking-Events.patch similarity index 100% rename from patches/server/0773-Player-Entity-Tracking-Events.patch rename to patches/unapplied/0773-Player-Entity-Tracking-Events.patch diff --git a/patches/server/0774-Limit-pet-look-distance.patch b/patches/unapplied/0774-Limit-pet-look-distance.patch similarity index 100% rename from patches/server/0774-Limit-pet-look-distance.patch rename to patches/unapplied/0774-Limit-pet-look-distance.patch diff --git a/patches/server/0775-fix-Instruments.patch b/patches/unapplied/0775-fix-Instruments.patch similarity index 100% rename from patches/server/0775-fix-Instruments.patch rename to patches/unapplied/0775-fix-Instruments.patch diff --git a/patches/server/0776-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch b/patches/unapplied/0776-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch similarity index 100% rename from patches/server/0776-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch rename to patches/unapplied/0776-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch diff --git a/patches/server/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch b/patches/unapplied/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch similarity index 100% rename from patches/server/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch rename to patches/unapplied/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch diff --git a/patches/server/0778-Add-BlockLockCheckEvent.patch b/patches/unapplied/0778-Add-BlockLockCheckEvent.patch similarity index 100% rename from patches/server/0778-Add-BlockLockCheckEvent.patch rename to patches/unapplied/0778-Add-BlockLockCheckEvent.patch diff --git a/patches/server/0779-Add-Sneaking-API-for-Entities.patch b/patches/unapplied/0779-Add-Sneaking-API-for-Entities.patch similarity index 100% rename from patches/server/0779-Add-Sneaking-API-for-Entities.patch rename to patches/unapplied/0779-Add-Sneaking-API-for-Entities.patch diff --git a/patches/server/0780-Improve-logging-and-errors.patch b/patches/unapplied/0780-Improve-logging-and-errors.patch similarity index 100% rename from patches/server/0780-Improve-logging-and-errors.patch rename to patches/unapplied/0780-Improve-logging-and-errors.patch diff --git a/patches/server/0781-Improve-PortalEvents.patch b/patches/unapplied/0781-Improve-PortalEvents.patch similarity index 100% rename from patches/server/0781-Improve-PortalEvents.patch rename to patches/unapplied/0781-Improve-PortalEvents.patch diff --git a/patches/server/0782-Add-config-option-for-spider-worldborder-climbing.patch b/patches/unapplied/0782-Add-config-option-for-spider-worldborder-climbing.patch similarity index 100% rename from patches/server/0782-Add-config-option-for-spider-worldborder-climbing.patch rename to patches/unapplied/0782-Add-config-option-for-spider-worldborder-climbing.patch diff --git a/patches/server/0783-Add-missing-SpigotConfig-logCommands-check.patch b/patches/unapplied/0783-Add-missing-SpigotConfig-logCommands-check.patch similarity index 100% rename from patches/server/0783-Add-missing-SpigotConfig-logCommands-check.patch rename to patches/unapplied/0783-Add-missing-SpigotConfig-logCommands-check.patch diff --git a/patches/server/0784-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch b/patches/unapplied/0784-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch similarity index 100% rename from patches/server/0784-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch rename to patches/unapplied/0784-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch diff --git a/patches/server/0785-Flying-Fall-Damage.patch b/patches/unapplied/0785-Flying-Fall-Damage.patch similarity index 100% rename from patches/server/0785-Flying-Fall-Damage.patch rename to patches/unapplied/0785-Flying-Fall-Damage.patch diff --git a/patches/server/0786-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch b/patches/unapplied/0786-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch similarity index 100% rename from patches/server/0786-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch rename to patches/unapplied/0786-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch diff --git a/patches/server/0787-config-for-disabling-entity-tag-tags.patch b/patches/unapplied/0787-config-for-disabling-entity-tag-tags.patch similarity index 100% rename from patches/server/0787-config-for-disabling-entity-tag-tags.patch rename to patches/unapplied/0787-config-for-disabling-entity-tag-tags.patch diff --git a/patches/server/0788-Use-single-player-info-update-packet-on-join.patch b/patches/unapplied/0788-Use-single-player-info-update-packet-on-join.patch similarity index 100% rename from patches/server/0788-Use-single-player-info-update-packet-on-join.patch rename to patches/unapplied/0788-Use-single-player-info-update-packet-on-join.patch diff --git a/patches/server/0789-Correctly-shrink-items-during-EntityResurrectEvent.patch b/patches/unapplied/0789-Correctly-shrink-items-during-EntityResurrectEvent.patch similarity index 100% rename from patches/server/0789-Correctly-shrink-items-during-EntityResurrectEvent.patch rename to patches/unapplied/0789-Correctly-shrink-items-during-EntityResurrectEvent.patch diff --git a/patches/server/0790-Win-Screen-API.patch b/patches/unapplied/0790-Win-Screen-API.patch similarity index 100% rename from patches/server/0790-Win-Screen-API.patch rename to patches/unapplied/0790-Win-Screen-API.patch diff --git a/patches/server/0791-Remove-CraftItemStack-setAmount-null-assignment.patch b/patches/unapplied/0791-Remove-CraftItemStack-setAmount-null-assignment.patch similarity index 100% rename from patches/server/0791-Remove-CraftItemStack-setAmount-null-assignment.patch rename to patches/unapplied/0791-Remove-CraftItemStack-setAmount-null-assignment.patch diff --git a/patches/server/0792-Fix-force-opening-enchantment-tables.patch b/patches/unapplied/0792-Fix-force-opening-enchantment-tables.patch similarity index 100% rename from patches/server/0792-Fix-force-opening-enchantment-tables.patch rename to patches/unapplied/0792-Fix-force-opening-enchantment-tables.patch diff --git a/patches/server/0793-Add-Entity-Body-Yaw-API.patch b/patches/unapplied/0793-Add-Entity-Body-Yaw-API.patch similarity index 100% rename from patches/server/0793-Add-Entity-Body-Yaw-API.patch rename to patches/unapplied/0793-Add-Entity-Body-Yaw-API.patch diff --git a/patches/server/0794-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch b/patches/unapplied/0794-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch similarity index 100% rename from patches/server/0794-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch rename to patches/unapplied/0794-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch diff --git a/patches/server/0795-Add-EntityFertilizeEggEvent.patch b/patches/unapplied/0795-Add-EntityFertilizeEggEvent.patch similarity index 100% rename from patches/server/0795-Add-EntityFertilizeEggEvent.patch rename to patches/unapplied/0795-Add-EntityFertilizeEggEvent.patch diff --git a/patches/server/0796-Fix-HumanEntity-drop-not-updating-the-client-inv.patch b/patches/unapplied/0796-Fix-HumanEntity-drop-not-updating-the-client-inv.patch similarity index 100% rename from patches/server/0796-Fix-HumanEntity-drop-not-updating-the-client-inv.patch rename to patches/unapplied/0796-Fix-HumanEntity-drop-not-updating-the-client-inv.patch diff --git a/patches/server/0797-Add-CompostItemEvent-and-EntityCompostItemEvent.patch b/patches/unapplied/0797-Add-CompostItemEvent-and-EntityCompostItemEvent.patch similarity index 100% rename from patches/server/0797-Add-CompostItemEvent-and-EntityCompostItemEvent.patch rename to patches/unapplied/0797-Add-CompostItemEvent-and-EntityCompostItemEvent.patch diff --git a/patches/server/0798-Correctly-handle-ArmorStand-invisibility.patch b/patches/unapplied/0798-Correctly-handle-ArmorStand-invisibility.patch similarity index 100% rename from patches/server/0798-Correctly-handle-ArmorStand-invisibility.patch rename to patches/unapplied/0798-Correctly-handle-ArmorStand-invisibility.patch diff --git a/patches/server/0799-Fix-advancement-triggers-for-entity-damage.patch b/patches/unapplied/0799-Fix-advancement-triggers-for-entity-damage.patch similarity index 100% rename from patches/server/0799-Fix-advancement-triggers-for-entity-damage.patch rename to patches/unapplied/0799-Fix-advancement-triggers-for-entity-damage.patch diff --git a/patches/server/0800-Fix-text-display-error-on-spawn.patch b/patches/unapplied/0800-Fix-text-display-error-on-spawn.patch similarity index 100% rename from patches/server/0800-Fix-text-display-error-on-spawn.patch rename to patches/unapplied/0800-Fix-text-display-error-on-spawn.patch diff --git a/patches/server/0801-Fix-inventories-returning-null-Locations.patch b/patches/unapplied/0801-Fix-inventories-returning-null-Locations.patch similarity index 100% rename from patches/server/0801-Fix-inventories-returning-null-Locations.patch rename to patches/unapplied/0801-Fix-inventories-returning-null-Locations.patch diff --git a/patches/server/0802-Add-Shearable-API.patch b/patches/unapplied/0802-Add-Shearable-API.patch similarity index 100% rename from patches/server/0802-Add-Shearable-API.patch rename to patches/unapplied/0802-Add-Shearable-API.patch diff --git a/patches/server/0803-Fix-SpawnEggMeta-get-setSpawnedType.patch b/patches/unapplied/0803-Fix-SpawnEggMeta-get-setSpawnedType.patch similarity index 100% rename from patches/server/0803-Fix-SpawnEggMeta-get-setSpawnedType.patch rename to patches/unapplied/0803-Fix-SpawnEggMeta-get-setSpawnedType.patch diff --git a/patches/server/0804-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch b/patches/unapplied/0804-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch similarity index 100% rename from patches/server/0804-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch rename to patches/unapplied/0804-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch diff --git a/patches/server/0805-Treat-sequence-violations-like-they-should-be.patch b/patches/unapplied/0805-Treat-sequence-violations-like-they-should-be.patch similarity index 100% rename from patches/server/0805-Treat-sequence-violations-like-they-should-be.patch rename to patches/unapplied/0805-Treat-sequence-violations-like-they-should-be.patch diff --git a/patches/server/0806-Prevent-causing-expired-keys-from-impacting-new-join.patch b/patches/unapplied/0806-Prevent-causing-expired-keys-from-impacting-new-join.patch similarity index 100% rename from patches/server/0806-Prevent-causing-expired-keys-from-impacting-new-join.patch rename to patches/unapplied/0806-Prevent-causing-expired-keys-from-impacting-new-join.patch diff --git a/patches/server/0807-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch b/patches/unapplied/0807-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch similarity index 100% rename from patches/server/0807-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch rename to patches/unapplied/0807-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch diff --git a/patches/server/0808-Use-array-for-gamerule-storage.patch b/patches/unapplied/0808-Use-array-for-gamerule-storage.patch similarity index 100% rename from patches/server/0808-Use-array-for-gamerule-storage.patch rename to patches/unapplied/0808-Use-array-for-gamerule-storage.patch diff --git a/patches/server/0809-Fix-a-couple-of-upstream-bed-issues.patch b/patches/unapplied/0809-Fix-a-couple-of-upstream-bed-issues.patch similarity index 100% rename from patches/server/0809-Fix-a-couple-of-upstream-bed-issues.patch rename to patches/unapplied/0809-Fix-a-couple-of-upstream-bed-issues.patch diff --git a/patches/server/0810-Fix-demo-flag-not-enabling-demo-mode.patch b/patches/unapplied/0810-Fix-demo-flag-not-enabling-demo-mode.patch similarity index 100% rename from patches/server/0810-Fix-demo-flag-not-enabling-demo-mode.patch rename to patches/unapplied/0810-Fix-demo-flag-not-enabling-demo-mode.patch diff --git a/patches/server/0811-Add-Mob-Experience-reward-API.patch b/patches/unapplied/0811-Add-Mob-Experience-reward-API.patch similarity index 100% rename from patches/server/0811-Add-Mob-Experience-reward-API.patch rename to patches/unapplied/0811-Add-Mob-Experience-reward-API.patch diff --git a/patches/server/0812-Break-redstone-on-top-of-trap-doors-early.patch b/patches/unapplied/0812-Break-redstone-on-top-of-trap-doors-early.patch similarity index 100% rename from patches/server/0812-Break-redstone-on-top-of-trap-doors-early.patch rename to patches/unapplied/0812-Break-redstone-on-top-of-trap-doors-early.patch diff --git a/patches/server/0813-Avoid-Lazy-Initialization-for-Enum-Fields.patch b/patches/unapplied/0813-Avoid-Lazy-Initialization-for-Enum-Fields.patch similarity index 100% rename from patches/server/0813-Avoid-Lazy-Initialization-for-Enum-Fields.patch rename to patches/unapplied/0813-Avoid-Lazy-Initialization-for-Enum-Fields.patch diff --git a/patches/server/0814-More-accurate-isInOpenWater-impl.patch b/patches/unapplied/0814-More-accurate-isInOpenWater-impl.patch similarity index 100% rename from patches/server/0814-More-accurate-isInOpenWater-impl.patch rename to patches/unapplied/0814-More-accurate-isInOpenWater-impl.patch diff --git a/patches/server/0815-Expand-PlayerItemMendEvent.patch b/patches/unapplied/0815-Expand-PlayerItemMendEvent.patch similarity index 100% rename from patches/server/0815-Expand-PlayerItemMendEvent.patch rename to patches/unapplied/0815-Expand-PlayerItemMendEvent.patch diff --git a/patches/server/0816-Refresh-ProjectileSource-for-projectiles.patch b/patches/unapplied/0816-Refresh-ProjectileSource-for-projectiles.patch similarity index 100% rename from patches/server/0816-Refresh-ProjectileSource-for-projectiles.patch rename to patches/unapplied/0816-Refresh-ProjectileSource-for-projectiles.patch diff --git a/patches/server/0817-Add-transient-modifier-API.patch b/patches/unapplied/0817-Add-transient-modifier-API.patch similarity index 100% rename from patches/server/0817-Add-transient-modifier-API.patch rename to patches/unapplied/0817-Add-transient-modifier-API.patch diff --git a/patches/server/0818-Fix-block-place-logic.patch b/patches/unapplied/0818-Fix-block-place-logic.patch similarity index 100% rename from patches/server/0818-Fix-block-place-logic.patch rename to patches/unapplied/0818-Fix-block-place-logic.patch diff --git a/patches/server/0819-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch b/patches/unapplied/0819-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch similarity index 100% rename from patches/server/0819-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch rename to patches/unapplied/0819-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch diff --git a/patches/server/0820-Call-BlockGrowEvent-for-missing-blocks.patch b/patches/unapplied/0820-Call-BlockGrowEvent-for-missing-blocks.patch similarity index 100% rename from patches/server/0820-Call-BlockGrowEvent-for-missing-blocks.patch rename to patches/unapplied/0820-Call-BlockGrowEvent-for-missing-blocks.patch diff --git a/patches/server/0821-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch b/patches/unapplied/0821-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch similarity index 100% rename from patches/server/0821-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch rename to patches/unapplied/0821-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch diff --git a/patches/server/0822-fix-MapLike-spam-for-missing-key-selector.patch b/patches/unapplied/0822-fix-MapLike-spam-for-missing-key-selector.patch similarity index 100% rename from patches/server/0822-fix-MapLike-spam-for-missing-key-selector.patch rename to patches/unapplied/0822-fix-MapLike-spam-for-missing-key-selector.patch diff --git a/patches/server/0823-Fix-sniffer-removeExploredLocation.patch b/patches/unapplied/0823-Fix-sniffer-removeExploredLocation.patch similarity index 100% rename from patches/server/0823-Fix-sniffer-removeExploredLocation.patch rename to patches/unapplied/0823-Fix-sniffer-removeExploredLocation.patch diff --git a/patches/server/0824-Add-method-to-remove-all-active-potion-effects.patch b/patches/unapplied/0824-Add-method-to-remove-all-active-potion-effects.patch similarity index 100% rename from patches/server/0824-Add-method-to-remove-all-active-potion-effects.patch rename to patches/unapplied/0824-Add-method-to-remove-all-active-potion-effects.patch diff --git a/patches/server/0825-Fix-incorrect-crafting-result-amount-for-fireworks.patch b/patches/unapplied/0825-Fix-incorrect-crafting-result-amount-for-fireworks.patch similarity index 100% rename from patches/server/0825-Fix-incorrect-crafting-result-amount-for-fireworks.patch rename to patches/unapplied/0825-Fix-incorrect-crafting-result-amount-for-fireworks.patch diff --git a/patches/server/0826-Add-event-for-player-editing-sign.patch b/patches/unapplied/0826-Add-event-for-player-editing-sign.patch similarity index 100% rename from patches/server/0826-Add-event-for-player-editing-sign.patch rename to patches/unapplied/0826-Add-event-for-player-editing-sign.patch diff --git a/patches/server/0827-Only-tick-item-frames-if-players-can-see-it.patch b/patches/unapplied/0827-Only-tick-item-frames-if-players-can-see-it.patch similarity index 100% rename from patches/server/0827-Only-tick-item-frames-if-players-can-see-it.patch rename to patches/unapplied/0827-Only-tick-item-frames-if-players-can-see-it.patch diff --git a/patches/server/0828-Fix-cmd-permission-levels-for-command-blocks.patch b/patches/unapplied/0828-Fix-cmd-permission-levels-for-command-blocks.patch similarity index 100% rename from patches/server/0828-Fix-cmd-permission-levels-for-command-blocks.patch rename to patches/unapplied/0828-Fix-cmd-permission-levels-for-command-blocks.patch diff --git a/patches/server/0829-Add-option-to-disable-block-updates.patch b/patches/unapplied/0829-Add-option-to-disable-block-updates.patch similarity index 100% rename from patches/server/0829-Add-option-to-disable-block-updates.patch rename to patches/unapplied/0829-Add-option-to-disable-block-updates.patch diff --git a/patches/server/0830-Call-missing-BlockDispenseEvent.patch b/patches/unapplied/0830-Call-missing-BlockDispenseEvent.patch similarity index 100% rename from patches/server/0830-Call-missing-BlockDispenseEvent.patch rename to patches/unapplied/0830-Call-missing-BlockDispenseEvent.patch diff --git a/patches/server/0831-Don-t-load-chunks-for-supporting-block-checks.patch b/patches/unapplied/0831-Don-t-load-chunks-for-supporting-block-checks.patch similarity index 100% rename from patches/server/0831-Don-t-load-chunks-for-supporting-block-checks.patch rename to patches/unapplied/0831-Don-t-load-chunks-for-supporting-block-checks.patch diff --git a/patches/server/0832-Optimize-player-lookups-for-beacons.patch b/patches/unapplied/0832-Optimize-player-lookups-for-beacons.patch similarity index 100% rename from patches/server/0832-Optimize-player-lookups-for-beacons.patch rename to patches/unapplied/0832-Optimize-player-lookups-for-beacons.patch diff --git a/patches/server/0833-More-Sign-Block-API.patch b/patches/unapplied/0833-More-Sign-Block-API.patch similarity index 100% rename from patches/server/0833-More-Sign-Block-API.patch rename to patches/unapplied/0833-More-Sign-Block-API.patch diff --git a/patches/server/0834-fix-item-meta-for-tadpole-buckets.patch b/patches/unapplied/0834-fix-item-meta-for-tadpole-buckets.patch similarity index 100% rename from patches/server/0834-fix-item-meta-for-tadpole-buckets.patch rename to patches/unapplied/0834-fix-item-meta-for-tadpole-buckets.patch diff --git a/patches/server/0835-Fix-BanList-API.patch b/patches/unapplied/0835-Fix-BanList-API.patch similarity index 100% rename from patches/server/0835-Fix-BanList-API.patch rename to patches/unapplied/0835-Fix-BanList-API.patch diff --git a/patches/server/0836-Determine-lava-and-water-fluid-explosion-resistance-.patch b/patches/unapplied/0836-Determine-lava-and-water-fluid-explosion-resistance-.patch similarity index 100% rename from patches/server/0836-Determine-lava-and-water-fluid-explosion-resistance-.patch rename to patches/unapplied/0836-Determine-lava-and-water-fluid-explosion-resistance-.patch diff --git a/patches/server/0837-Fix-possible-NPE-on-painting-creation.patch b/patches/unapplied/0837-Fix-possible-NPE-on-painting-creation.patch similarity index 100% rename from patches/server/0837-Fix-possible-NPE-on-painting-creation.patch rename to patches/unapplied/0837-Fix-possible-NPE-on-painting-creation.patch diff --git a/patches/server/0838-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch b/patches/unapplied/0838-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch similarity index 100% rename from patches/server/0838-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch rename to patches/unapplied/0838-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch diff --git a/patches/server/0839-ExperienceOrb-should-call-EntitySpawnEvent.patch b/patches/unapplied/0839-ExperienceOrb-should-call-EntitySpawnEvent.patch similarity index 100% rename from patches/server/0839-ExperienceOrb-should-call-EntitySpawnEvent.patch rename to patches/unapplied/0839-ExperienceOrb-should-call-EntitySpawnEvent.patch diff --git a/patches/server/0840-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch b/patches/unapplied/0840-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch similarity index 100% rename from patches/server/0840-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch rename to patches/unapplied/0840-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch diff --git a/patches/server/0841-Add-whitelist-events.patch b/patches/unapplied/0841-Add-whitelist-events.patch similarity index 100% rename from patches/server/0841-Add-whitelist-events.patch rename to patches/unapplied/0841-Add-whitelist-events.patch diff --git a/patches/server/0842-Implement-PlayerFailMoveEvent.patch b/patches/unapplied/0842-Implement-PlayerFailMoveEvent.patch similarity index 100% rename from patches/server/0842-Implement-PlayerFailMoveEvent.patch rename to patches/unapplied/0842-Implement-PlayerFailMoveEvent.patch diff --git a/patches/server/0843-Folia-scheduler-and-owned-region-API.patch b/patches/unapplied/0843-Folia-scheduler-and-owned-region-API.patch similarity index 100% rename from patches/server/0843-Folia-scheduler-and-owned-region-API.patch rename to patches/unapplied/0843-Folia-scheduler-and-owned-region-API.patch diff --git a/patches/server/0844-Only-erase-allay-memory-on-non-item-targets.patch b/patches/unapplied/0844-Only-erase-allay-memory-on-non-item-targets.patch similarity index 100% rename from patches/server/0844-Only-erase-allay-memory-on-non-item-targets.patch rename to patches/unapplied/0844-Only-erase-allay-memory-on-non-item-targets.patch diff --git a/patches/server/0845-API-for-updating-recipes-on-clients.patch b/patches/unapplied/0845-API-for-updating-recipes-on-clients.patch similarity index 100% rename from patches/server/0845-API-for-updating-recipes-on-clients.patch rename to patches/unapplied/0845-API-for-updating-recipes-on-clients.patch diff --git a/patches/server/0846-Fix-rotation-when-spawning-display-entities.patch b/patches/unapplied/0846-Fix-rotation-when-spawning-display-entities.patch similarity index 100% rename from patches/server/0846-Fix-rotation-when-spawning-display-entities.patch rename to patches/unapplied/0846-Fix-rotation-when-spawning-display-entities.patch diff --git a/patches/server/0847-Only-capture-actual-tree-growth.patch b/patches/unapplied/0847-Only-capture-actual-tree-growth.patch similarity index 100% rename from patches/server/0847-Only-capture-actual-tree-growth.patch rename to patches/unapplied/0847-Only-capture-actual-tree-growth.patch diff --git a/patches/server/0848-Use-correct-source-for-mushroom-block-spread-event.patch b/patches/unapplied/0848-Use-correct-source-for-mushroom-block-spread-event.patch similarity index 100% rename from patches/server/0848-Use-correct-source-for-mushroom-block-spread-event.patch rename to patches/unapplied/0848-Use-correct-source-for-mushroom-block-spread-event.patch diff --git a/patches/server/0849-Respect-randomizeData-on-more-entities-when-spawning.patch b/patches/unapplied/0849-Respect-randomizeData-on-more-entities-when-spawning.patch similarity index 100% rename from patches/server/0849-Respect-randomizeData-on-more-entities-when-spawning.patch rename to patches/unapplied/0849-Respect-randomizeData-on-more-entities-when-spawning.patch diff --git a/patches/server/0850-Use-correct-seed-on-api-world-load.patch b/patches/unapplied/0850-Use-correct-seed-on-api-world-load.patch similarity index 100% rename from patches/server/0850-Use-correct-seed-on-api-world-load.patch rename to patches/unapplied/0850-Use-correct-seed-on-api-world-load.patch diff --git a/patches/server/0851-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch b/patches/unapplied/0851-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch similarity index 100% rename from patches/server/0851-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch rename to patches/unapplied/0851-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch diff --git a/patches/server/0852-Cache-map-ids-on-item-frames.patch b/patches/unapplied/0852-Cache-map-ids-on-item-frames.patch similarity index 100% rename from patches/server/0852-Cache-map-ids-on-item-frames.patch rename to patches/unapplied/0852-Cache-map-ids-on-item-frames.patch diff --git a/patches/server/0853-Fix-custom-statistic-criteria-creation.patch b/patches/unapplied/0853-Fix-custom-statistic-criteria-creation.patch similarity index 100% rename from patches/server/0853-Fix-custom-statistic-criteria-creation.patch rename to patches/unapplied/0853-Fix-custom-statistic-criteria-creation.patch diff --git a/patches/server/0854-Bandaid-fix-for-Effect.patch b/patches/unapplied/0854-Bandaid-fix-for-Effect.patch similarity index 100% rename from patches/server/0854-Bandaid-fix-for-Effect.patch rename to patches/unapplied/0854-Bandaid-fix-for-Effect.patch diff --git a/patches/server/0855-SculkCatalyst-bloom-API.patch b/patches/unapplied/0855-SculkCatalyst-bloom-API.patch similarity index 100% rename from patches/server/0855-SculkCatalyst-bloom-API.patch rename to patches/unapplied/0855-SculkCatalyst-bloom-API.patch diff --git a/patches/server/0856-API-for-an-entity-s-scoreboard-name.patch b/patches/unapplied/0856-API-for-an-entity-s-scoreboard-name.patch similarity index 100% rename from patches/server/0856-API-for-an-entity-s-scoreboard-name.patch rename to patches/unapplied/0856-API-for-an-entity-s-scoreboard-name.patch diff --git a/patches/server/0857-Deprecate-and-replace-methods-with-old-StructureType.patch b/patches/unapplied/0857-Deprecate-and-replace-methods-with-old-StructureType.patch similarity index 100% rename from patches/server/0857-Deprecate-and-replace-methods-with-old-StructureType.patch rename to patches/unapplied/0857-Deprecate-and-replace-methods-with-old-StructureType.patch diff --git a/patches/server/0858-Don-t-tab-complete-namespaced-commands-if-send-names.patch b/patches/unapplied/0858-Don-t-tab-complete-namespaced-commands-if-send-names.patch similarity index 100% rename from patches/server/0858-Don-t-tab-complete-namespaced-commands-if-send-names.patch rename to patches/unapplied/0858-Don-t-tab-complete-namespaced-commands-if-send-names.patch diff --git a/patches/server/0859-Properly-handle-BlockBreakEvent-isDropItems.patch b/patches/unapplied/0859-Properly-handle-BlockBreakEvent-isDropItems.patch similarity index 100% rename from patches/server/0859-Properly-handle-BlockBreakEvent-isDropItems.patch rename to patches/unapplied/0859-Properly-handle-BlockBreakEvent-isDropItems.patch diff --git a/patches/server/0860-Fire-entity-death-event-for-ender-dragon.patch b/patches/unapplied/0860-Fire-entity-death-event-for-ender-dragon.patch similarity index 100% rename from patches/server/0860-Fire-entity-death-event-for-ender-dragon.patch rename to patches/unapplied/0860-Fire-entity-death-event-for-ender-dragon.patch diff --git a/patches/server/0861-Configurable-entity-tracking-range-by-Y-coordinate.patch b/patches/unapplied/0861-Configurable-entity-tracking-range-by-Y-coordinate.patch similarity index 100% rename from patches/server/0861-Configurable-entity-tracking-range-by-Y-coordinate.patch rename to patches/unapplied/0861-Configurable-entity-tracking-range-by-Y-coordinate.patch diff --git a/patches/server/0862-Add-Listing-API-for-Player.patch b/patches/unapplied/0862-Add-Listing-API-for-Player.patch similarity index 100% rename from patches/server/0862-Add-Listing-API-for-Player.patch rename to patches/unapplied/0862-Add-Listing-API-for-Player.patch diff --git a/patches/server/0863-Configurable-Region-Compression-Format.patch b/patches/unapplied/0863-Configurable-Region-Compression-Format.patch similarity index 100% rename from patches/server/0863-Configurable-Region-Compression-Format.patch rename to patches/unapplied/0863-Configurable-Region-Compression-Format.patch diff --git a/patches/server/0864-Add-BlockFace-to-BlockDamageEvent.patch b/patches/unapplied/0864-Add-BlockFace-to-BlockDamageEvent.patch similarity index 100% rename from patches/server/0864-Add-BlockFace-to-BlockDamageEvent.patch rename to patches/unapplied/0864-Add-BlockFace-to-BlockDamageEvent.patch diff --git a/patches/server/0865-Fix-NPE-on-Boat-getStatus.patch b/patches/unapplied/0865-Fix-NPE-on-Boat-getStatus.patch similarity index 100% rename from patches/server/0865-Fix-NPE-on-Boat-getStatus.patch rename to patches/unapplied/0865-Fix-NPE-on-Boat-getStatus.patch diff --git a/patches/server/0866-Expand-Pose-API.patch b/patches/unapplied/0866-Expand-Pose-API.patch similarity index 100% rename from patches/server/0866-Expand-Pose-API.patch rename to patches/unapplied/0866-Expand-Pose-API.patch diff --git a/patches/server/0867-More-DragonBattle-API.patch b/patches/unapplied/0867-More-DragonBattle-API.patch similarity index 100% rename from patches/server/0867-More-DragonBattle-API.patch rename to patches/unapplied/0867-More-DragonBattle-API.patch diff --git a/patches/server/0868-Add-PlayerPickItemEvent.patch b/patches/unapplied/0868-Add-PlayerPickItemEvent.patch similarity index 100% rename from patches/server/0868-Add-PlayerPickItemEvent.patch rename to patches/unapplied/0868-Add-PlayerPickItemEvent.patch diff --git a/patches/server/0869-Allow-trident-custom-damage.patch b/patches/unapplied/0869-Allow-trident-custom-damage.patch similarity index 100% rename from patches/server/0869-Allow-trident-custom-damage.patch rename to patches/unapplied/0869-Allow-trident-custom-damage.patch diff --git a/patches/server/0870-Expose-hand-in-BlockCanBuildEvent.patch b/patches/unapplied/0870-Expose-hand-in-BlockCanBuildEvent.patch similarity index 100% rename from patches/server/0870-Expose-hand-in-BlockCanBuildEvent.patch rename to patches/unapplied/0870-Expose-hand-in-BlockCanBuildEvent.patch diff --git a/patches/server/0871-Optimize-nearest-structure-border-iteration.patch b/patches/unapplied/0871-Optimize-nearest-structure-border-iteration.patch similarity index 100% rename from patches/server/0871-Optimize-nearest-structure-border-iteration.patch rename to patches/unapplied/0871-Optimize-nearest-structure-border-iteration.patch diff --git a/patches/server/0872-Implement-OfflinePlayer-isConnected.patch b/patches/unapplied/0872-Implement-OfflinePlayer-isConnected.patch similarity index 100% rename from patches/server/0872-Implement-OfflinePlayer-isConnected.patch rename to patches/unapplied/0872-Implement-OfflinePlayer-isConnected.patch diff --git a/patches/server/0873-Fix-slot-desync.patch b/patches/unapplied/0873-Fix-slot-desync.patch similarity index 100% rename from patches/server/0873-Fix-slot-desync.patch rename to patches/unapplied/0873-Fix-slot-desync.patch diff --git a/patches/server/0874-Add-titleOverride-to-InventoryOpenEvent.patch b/patches/unapplied/0874-Add-titleOverride-to-InventoryOpenEvent.patch similarity index 100% rename from patches/server/0874-Add-titleOverride-to-InventoryOpenEvent.patch rename to patches/unapplied/0874-Add-titleOverride-to-InventoryOpenEvent.patch diff --git a/patches/server/0875-Configure-sniffer-egg-hatch-time.patch b/patches/unapplied/0875-Configure-sniffer-egg-hatch-time.patch similarity index 100% rename from patches/server/0875-Configure-sniffer-egg-hatch-time.patch rename to patches/unapplied/0875-Configure-sniffer-egg-hatch-time.patch diff --git a/patches/server/0876-Do-crystal-portal-proximity-check-before-entity-look.patch b/patches/unapplied/0876-Do-crystal-portal-proximity-check-before-entity-look.patch similarity index 100% rename from patches/server/0876-Do-crystal-portal-proximity-check-before-entity-look.patch rename to patches/unapplied/0876-Do-crystal-portal-proximity-check-before-entity-look.patch diff --git a/patches/server/0877-Skip-POI-finding-if-stuck-in-vehicle.patch b/patches/unapplied/0877-Skip-POI-finding-if-stuck-in-vehicle.patch similarity index 100% rename from patches/server/0877-Skip-POI-finding-if-stuck-in-vehicle.patch rename to patches/unapplied/0877-Skip-POI-finding-if-stuck-in-vehicle.patch diff --git a/patches/server/0878-Add-slot-sanity-checks-in-container-clicks.patch b/patches/unapplied/0878-Add-slot-sanity-checks-in-container-clicks.patch similarity index 100% rename from patches/server/0878-Add-slot-sanity-checks-in-container-clicks.patch rename to patches/unapplied/0878-Add-slot-sanity-checks-in-container-clicks.patch diff --git a/patches/server/0879-Call-BlockRedstoneEvents-for-lecterns.patch b/patches/unapplied/0879-Call-BlockRedstoneEvents-for-lecterns.patch similarity index 100% rename from patches/server/0879-Call-BlockRedstoneEvents-for-lecterns.patch rename to patches/unapplied/0879-Call-BlockRedstoneEvents-for-lecterns.patch diff --git a/patches/server/0880-Allow-proper-checking-of-empty-item-stacks.patch b/patches/unapplied/0880-Allow-proper-checking-of-empty-item-stacks.patch similarity index 100% rename from patches/server/0880-Allow-proper-checking-of-empty-item-stacks.patch rename to patches/unapplied/0880-Allow-proper-checking-of-empty-item-stacks.patch diff --git a/patches/server/0881-Fix-silent-equipment-change-for-mobs.patch b/patches/unapplied/0881-Fix-silent-equipment-change-for-mobs.patch similarity index 100% rename from patches/server/0881-Fix-silent-equipment-change-for-mobs.patch rename to patches/unapplied/0881-Fix-silent-equipment-change-for-mobs.patch diff --git a/patches/server/0882-Fix-spigot-s-Forced-Stats.patch b/patches/unapplied/0882-Fix-spigot-s-Forced-Stats.patch similarity index 100% rename from patches/server/0882-Fix-spigot-s-Forced-Stats.patch rename to patches/unapplied/0882-Fix-spigot-s-Forced-Stats.patch diff --git a/patches/server/0883-Add-missing-InventoryHolders-to-inventories.patch b/patches/unapplied/0883-Add-missing-InventoryHolders-to-inventories.patch similarity index 100% rename from patches/server/0883-Add-missing-InventoryHolders-to-inventories.patch rename to patches/unapplied/0883-Add-missing-InventoryHolders-to-inventories.patch diff --git a/patches/server/0884-Do-not-read-tile-entities-in-chunks-that-are-positio.patch b/patches/unapplied/0884-Do-not-read-tile-entities-in-chunks-that-are-positio.patch similarity index 100% rename from patches/server/0884-Do-not-read-tile-entities-in-chunks-that-are-positio.patch rename to patches/unapplied/0884-Do-not-read-tile-entities-in-chunks-that-are-positio.patch diff --git a/patches/server/0885-Add-missing-logs-for-log-ips-config-option.patch b/patches/unapplied/0885-Add-missing-logs-for-log-ips-config-option.patch similarity index 100% rename from patches/server/0885-Add-missing-logs-for-log-ips-config-option.patch rename to patches/unapplied/0885-Add-missing-logs-for-log-ips-config-option.patch diff --git a/patches/server/0886-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch b/patches/unapplied/0886-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch similarity index 100% rename from patches/server/0886-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch rename to patches/unapplied/0886-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch diff --git a/patches/server/0887-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch b/patches/unapplied/0887-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch similarity index 100% rename from patches/server/0887-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch rename to patches/unapplied/0887-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch diff --git a/patches/server/0888-Fix-team-sidebar-objectives-not-being-cleared.patch b/patches/unapplied/0888-Fix-team-sidebar-objectives-not-being-cleared.patch similarity index 100% rename from patches/server/0888-Fix-team-sidebar-objectives-not-being-cleared.patch rename to patches/unapplied/0888-Fix-team-sidebar-objectives-not-being-cleared.patch diff --git a/patches/server/0889-Fix-missing-map-initialize-event-call.patch b/patches/unapplied/0889-Fix-missing-map-initialize-event-call.patch similarity index 100% rename from patches/server/0889-Fix-missing-map-initialize-event-call.patch rename to patches/unapplied/0889-Fix-missing-map-initialize-event-call.patch diff --git a/patches/server/0890-Update-entity-data-when-attaching-firework-to-entity.patch b/patches/unapplied/0890-Update-entity-data-when-attaching-firework-to-entity.patch similarity index 100% rename from patches/server/0890-Update-entity-data-when-attaching-firework-to-entity.patch rename to patches/unapplied/0890-Update-entity-data-when-attaching-firework-to-entity.patch diff --git a/patches/server/0891-Fix-UnsafeValues-loadAdvancement.patch b/patches/unapplied/0891-Fix-UnsafeValues-loadAdvancement.patch similarity index 100% rename from patches/server/0891-Fix-UnsafeValues-loadAdvancement.patch rename to patches/unapplied/0891-Fix-UnsafeValues-loadAdvancement.patch diff --git a/patches/server/0892-Add-player-idle-duration-API.patch b/patches/unapplied/0892-Add-player-idle-duration-API.patch similarity index 100% rename from patches/server/0892-Add-player-idle-duration-API.patch rename to patches/unapplied/0892-Add-player-idle-duration-API.patch diff --git a/patches/server/0893-Don-t-check-if-we-can-see-non-visible-entities.patch b/patches/unapplied/0893-Don-t-check-if-we-can-see-non-visible-entities.patch similarity index 100% rename from patches/server/0893-Don-t-check-if-we-can-see-non-visible-entities.patch rename to patches/unapplied/0893-Don-t-check-if-we-can-see-non-visible-entities.patch diff --git a/patches/server/0894-Fix-NPE-in-SculkBloomEvent-world-access.patch b/patches/unapplied/0894-Fix-NPE-in-SculkBloomEvent-world-access.patch similarity index 100% rename from patches/server/0894-Fix-NPE-in-SculkBloomEvent-world-access.patch rename to patches/unapplied/0894-Fix-NPE-in-SculkBloomEvent-world-access.patch diff --git a/patches/server/0895-Allow-null-itemstack-for-Player-sendEquipmentChange.patch b/patches/unapplied/0895-Allow-null-itemstack-for-Player-sendEquipmentChange.patch similarity index 100% rename from patches/server/0895-Allow-null-itemstack-for-Player-sendEquipmentChange.patch rename to patches/unapplied/0895-Allow-null-itemstack-for-Player-sendEquipmentChange.patch diff --git a/patches/server/0896-Optimize-VarInts.patch b/patches/unapplied/0896-Optimize-VarInts.patch similarity index 100% rename from patches/server/0896-Optimize-VarInts.patch rename to patches/unapplied/0896-Optimize-VarInts.patch diff --git a/patches/server/0897-Add-API-to-get-the-collision-shape-of-a-block-before.patch b/patches/unapplied/0897-Add-API-to-get-the-collision-shape-of-a-block-before.patch similarity index 100% rename from patches/server/0897-Add-API-to-get-the-collision-shape-of-a-block-before.patch rename to patches/unapplied/0897-Add-API-to-get-the-collision-shape-of-a-block-before.patch diff --git a/patches/server/0898-Add-predicate-for-blocks-when-raytracing.patch b/patches/unapplied/0898-Add-predicate-for-blocks-when-raytracing.patch similarity index 100% rename from patches/server/0898-Add-predicate-for-blocks-when-raytracing.patch rename to patches/unapplied/0898-Add-predicate-for-blocks-when-raytracing.patch diff --git a/patches/server/0899-Broadcast-take-item-packets-with-collector-as-source.patch b/patches/unapplied/0899-Broadcast-take-item-packets-with-collector-as-source.patch similarity index 100% rename from patches/server/0899-Broadcast-take-item-packets-with-collector-as-source.patch rename to patches/unapplied/0899-Broadcast-take-item-packets-with-collector-as-source.patch diff --git a/patches/server/0900-Expand-LingeringPotion-API.patch b/patches/unapplied/0900-Expand-LingeringPotion-API.patch similarity index 100% rename from patches/server/0900-Expand-LingeringPotion-API.patch rename to patches/unapplied/0900-Expand-LingeringPotion-API.patch diff --git a/patches/server/0901-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch b/patches/unapplied/0901-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch similarity index 100% rename from patches/server/0901-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch rename to patches/unapplied/0901-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch diff --git a/patches/server/0902-Add-hand-to-fish-event-for-all-player-interactions.patch b/patches/unapplied/0902-Add-hand-to-fish-event-for-all-player-interactions.patch similarity index 100% rename from patches/server/0902-Add-hand-to-fish-event-for-all-player-interactions.patch rename to patches/unapplied/0902-Add-hand-to-fish-event-for-all-player-interactions.patch diff --git a/patches/server/0903-Fix-several-issues-with-EntityBreedEvent.patch b/patches/unapplied/0903-Fix-several-issues-with-EntityBreedEvent.patch similarity index 100% rename from patches/server/0903-Fix-several-issues-with-EntityBreedEvent.patch rename to patches/unapplied/0903-Fix-several-issues-with-EntityBreedEvent.patch diff --git a/patches/server/0904-Add-UUID-attribute-modifier-API.patch b/patches/unapplied/0904-Add-UUID-attribute-modifier-API.patch similarity index 100% rename from patches/server/0904-Add-UUID-attribute-modifier-API.patch rename to patches/unapplied/0904-Add-UUID-attribute-modifier-API.patch diff --git a/patches/server/0905-Fix-missing-event-call-for-entity-teleport-API.patch b/patches/unapplied/0905-Fix-missing-event-call-for-entity-teleport-API.patch similarity index 100% rename from patches/server/0905-Fix-missing-event-call-for-entity-teleport-API.patch rename to patches/unapplied/0905-Fix-missing-event-call-for-entity-teleport-API.patch diff --git a/patches/server/0906-Lazily-create-LootContext-for-criterions.patch b/patches/unapplied/0906-Lazily-create-LootContext-for-criterions.patch similarity index 100% rename from patches/server/0906-Lazily-create-LootContext-for-criterions.patch rename to patches/unapplied/0906-Lazily-create-LootContext-for-criterions.patch diff --git a/patches/server/0907-Don-t-fire-sync-events-during-worldgen.patch b/patches/unapplied/0907-Don-t-fire-sync-events-during-worldgen.patch similarity index 100% rename from patches/server/0907-Don-t-fire-sync-events-during-worldgen.patch rename to patches/unapplied/0907-Don-t-fire-sync-events-during-worldgen.patch diff --git a/patches/server/0908-Add-Structure-check-API.patch b/patches/unapplied/0908-Add-Structure-check-API.patch similarity index 100% rename from patches/server/0908-Add-Structure-check-API.patch rename to patches/unapplied/0908-Add-Structure-check-API.patch diff --git a/patches/server/0909-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch b/patches/unapplied/0909-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch similarity index 100% rename from patches/server/0909-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch rename to patches/unapplied/0909-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch diff --git a/patches/server/0910-Restore-vanilla-entity-drops-behavior.patch b/patches/unapplied/0910-Restore-vanilla-entity-drops-behavior.patch similarity index 100% rename from patches/server/0910-Restore-vanilla-entity-drops-behavior.patch rename to patches/unapplied/0910-Restore-vanilla-entity-drops-behavior.patch diff --git a/patches/server/0911-Dont-resend-blocks-on-interactions.patch b/patches/unapplied/0911-Dont-resend-blocks-on-interactions.patch similarity index 100% rename from patches/server/0911-Dont-resend-blocks-on-interactions.patch rename to patches/unapplied/0911-Dont-resend-blocks-on-interactions.patch diff --git a/patches/server/0912-add-more-scoreboard-API.patch b/patches/unapplied/0912-add-more-scoreboard-API.patch similarity index 100% rename from patches/server/0912-add-more-scoreboard-API.patch rename to patches/unapplied/0912-add-more-scoreboard-API.patch diff --git a/patches/server/0913-Improve-Registry.patch b/patches/unapplied/0913-Improve-Registry.patch similarity index 100% rename from patches/server/0913-Improve-Registry.patch rename to patches/unapplied/0913-Improve-Registry.patch diff --git a/patches/server/0914-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch b/patches/unapplied/0914-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch similarity index 100% rename from patches/server/0914-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch rename to patches/unapplied/0914-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch diff --git a/patches/server/0915-Add-experience-points-API.patch b/patches/unapplied/0915-Add-experience-points-API.patch similarity index 100% rename from patches/server/0915-Add-experience-points-API.patch rename to patches/unapplied/0915-Add-experience-points-API.patch diff --git a/patches/server/0916-Add-drops-to-shear-events.patch b/patches/unapplied/0916-Add-drops-to-shear-events.patch similarity index 100% rename from patches/server/0916-Add-drops-to-shear-events.patch rename to patches/unapplied/0916-Add-drops-to-shear-events.patch diff --git a/patches/server/0917-Add-PlayerShieldDisableEvent.patch b/patches/unapplied/0917-Add-PlayerShieldDisableEvent.patch similarity index 100% rename from patches/server/0917-Add-PlayerShieldDisableEvent.patch rename to patches/unapplied/0917-Add-PlayerShieldDisableEvent.patch diff --git a/patches/server/0918-Validate-ResourceLocation-in-NBT-reading.patch b/patches/unapplied/0918-Validate-ResourceLocation-in-NBT-reading.patch similarity index 100% rename from patches/server/0918-Validate-ResourceLocation-in-NBT-reading.patch rename to patches/unapplied/0918-Validate-ResourceLocation-in-NBT-reading.patch diff --git a/patches/server/0919-Properly-handle-experience-dropping-on-block-break.patch b/patches/unapplied/0919-Properly-handle-experience-dropping-on-block-break.patch similarity index 100% rename from patches/server/0919-Properly-handle-experience-dropping-on-block-break.patch rename to patches/unapplied/0919-Properly-handle-experience-dropping-on-block-break.patch diff --git a/patches/server/0920-Fixup-NamespacedKey-handling.patch b/patches/unapplied/0920-Fixup-NamespacedKey-handling.patch similarity index 100% rename from patches/server/0920-Fixup-NamespacedKey-handling.patch rename to patches/unapplied/0920-Fixup-NamespacedKey-handling.patch diff --git a/patches/server/0921-Expose-LootTable-of-DecoratedPot.patch b/patches/unapplied/0921-Expose-LootTable-of-DecoratedPot.patch similarity index 100% rename from patches/server/0921-Expose-LootTable-of-DecoratedPot.patch rename to patches/unapplied/0921-Expose-LootTable-of-DecoratedPot.patch diff --git a/patches/server/0922-Reduce-allocation-of-Vec3D-by-entity-tracker.patch b/patches/unapplied/0922-Reduce-allocation-of-Vec3D-by-entity-tracker.patch similarity index 100% rename from patches/server/0922-Reduce-allocation-of-Vec3D-by-entity-tracker.patch rename to patches/unapplied/0922-Reduce-allocation-of-Vec3D-by-entity-tracker.patch diff --git a/patches/server/0923-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch b/patches/unapplied/0923-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch similarity index 100% rename from patches/server/0923-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch rename to patches/unapplied/0923-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch diff --git a/patches/server/0924-Add-ShulkerDuplicateEvent.patch b/patches/unapplied/0924-Add-ShulkerDuplicateEvent.patch similarity index 100% rename from patches/server/0924-Add-ShulkerDuplicateEvent.patch rename to patches/unapplied/0924-Add-ShulkerDuplicateEvent.patch diff --git a/patches/server/0925-Add-api-for-spawn-egg-texture-colors.patch b/patches/unapplied/0925-Add-api-for-spawn-egg-texture-colors.patch similarity index 100% rename from patches/server/0925-Add-api-for-spawn-egg-texture-colors.patch rename to patches/unapplied/0925-Add-api-for-spawn-egg-texture-colors.patch diff --git a/patches/server/0926-Add-Lifecycle-Event-system.patch b/patches/unapplied/0926-Add-Lifecycle-Event-system.patch similarity index 100% rename from patches/server/0926-Add-Lifecycle-Event-system.patch rename to patches/unapplied/0926-Add-Lifecycle-Event-system.patch diff --git a/patches/server/0927-ItemStack-Tooltip-API.patch b/patches/unapplied/0927-ItemStack-Tooltip-API.patch similarity index 100% rename from patches/server/0927-ItemStack-Tooltip-API.patch rename to patches/unapplied/0927-ItemStack-Tooltip-API.patch diff --git a/patches/server/0928-Add-getChunkSnapshot-includeLightData-parameter.patch b/patches/unapplied/0928-Add-getChunkSnapshot-includeLightData-parameter.patch similarity index 100% rename from patches/server/0928-Add-getChunkSnapshot-includeLightData-parameter.patch rename to patches/unapplied/0928-Add-getChunkSnapshot-includeLightData-parameter.patch diff --git a/patches/server/0929-Add-FluidState-API.patch b/patches/unapplied/0929-Add-FluidState-API.patch similarity index 100% rename from patches/server/0929-Add-FluidState-API.patch rename to patches/unapplied/0929-Add-FluidState-API.patch diff --git a/patches/server/0930-add-number-format-api.patch b/patches/unapplied/0930-add-number-format-api.patch similarity index 100% rename from patches/server/0930-add-number-format-api.patch rename to patches/unapplied/0930-add-number-format-api.patch diff --git a/patches/server/0931-improve-BanList-types.patch b/patches/unapplied/0931-improve-BanList-types.patch similarity index 100% rename from patches/server/0931-improve-BanList-types.patch rename to patches/unapplied/0931-improve-BanList-types.patch diff --git a/patches/server/0932-Expanded-Hopper-API.patch b/patches/unapplied/0932-Expanded-Hopper-API.patch similarity index 100% rename from patches/server/0932-Expanded-Hopper-API.patch rename to patches/unapplied/0932-Expanded-Hopper-API.patch diff --git a/patches/server/0933-Add-BlockBreakProgressUpdateEvent.patch b/patches/unapplied/0933-Add-BlockBreakProgressUpdateEvent.patch similarity index 100% rename from patches/server/0933-Add-BlockBreakProgressUpdateEvent.patch rename to patches/unapplied/0933-Add-BlockBreakProgressUpdateEvent.patch diff --git a/patches/server/0934-Deprecate-ItemStack-setType.patch b/patches/unapplied/0934-Deprecate-ItemStack-setType.patch similarity index 100% rename from patches/server/0934-Deprecate-ItemStack-setType.patch rename to patches/unapplied/0934-Deprecate-ItemStack-setType.patch diff --git a/patches/server/0935-Add-CartographyItemEvent.patch b/patches/unapplied/0935-Add-CartographyItemEvent.patch similarity index 100% rename from patches/server/0935-Add-CartographyItemEvent.patch rename to patches/unapplied/0935-Add-CartographyItemEvent.patch diff --git a/patches/server/0936-More-Raid-API.patch b/patches/unapplied/0936-More-Raid-API.patch similarity index 100% rename from patches/server/0936-More-Raid-API.patch rename to patches/unapplied/0936-More-Raid-API.patch diff --git a/patches/server/0937-Add-onboarding-message-for-initial-server-start.patch b/patches/unapplied/0937-Add-onboarding-message-for-initial-server-start.patch similarity index 100% rename from patches/server/0937-Add-onboarding-message-for-initial-server-start.patch rename to patches/unapplied/0937-Add-onboarding-message-for-initial-server-start.patch diff --git a/patches/server/0938-Configurable-max-block-fluid-ticks.patch b/patches/unapplied/0938-Configurable-max-block-fluid-ticks.patch similarity index 100% rename from patches/server/0938-Configurable-max-block-fluid-ticks.patch rename to patches/unapplied/0938-Configurable-max-block-fluid-ticks.patch diff --git a/patches/server/0939-Fix-bees-aging-inside-hives.patch b/patches/unapplied/0939-Fix-bees-aging-inside-hives.patch similarity index 100% rename from patches/server/0939-Fix-bees-aging-inside-hives.patch rename to patches/unapplied/0939-Fix-bees-aging-inside-hives.patch diff --git a/patches/server/0940-Disable-memory-reserve-allocating.patch b/patches/unapplied/0940-Disable-memory-reserve-allocating.patch similarity index 100% rename from patches/server/0940-Disable-memory-reserve-allocating.patch rename to patches/unapplied/0940-Disable-memory-reserve-allocating.patch diff --git a/patches/server/0941-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch b/patches/unapplied/0941-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch similarity index 100% rename from patches/server/0941-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch rename to patches/unapplied/0941-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch diff --git a/patches/server/0942-Fix-DamageSource-API.patch b/patches/unapplied/0942-Fix-DamageSource-API.patch similarity index 100% rename from patches/server/0942-Fix-DamageSource-API.patch rename to patches/unapplied/0942-Fix-DamageSource-API.patch diff --git a/patches/server/0943-Fix-creation-of-invalid-block-entity-during-world-ge.patch b/patches/unapplied/0943-Fix-creation-of-invalid-block-entity-during-world-ge.patch similarity index 100% rename from patches/server/0943-Fix-creation-of-invalid-block-entity-during-world-ge.patch rename to patches/unapplied/0943-Fix-creation-of-invalid-block-entity-during-world-ge.patch diff --git a/patches/server/0944-Fix-possible-StackOverflowError-for-some-dispenses.patch b/patches/unapplied/0944-Fix-possible-StackOverflowError-for-some-dispenses.patch similarity index 100% rename from patches/server/0944-Fix-possible-StackOverflowError-for-some-dispenses.patch rename to patches/unapplied/0944-Fix-possible-StackOverflowError-for-some-dispenses.patch diff --git a/patches/server/0945-Improve-tag-parser-handling.patch b/patches/unapplied/0945-Improve-tag-parser-handling.patch similarity index 100% rename from patches/server/0945-Improve-tag-parser-handling.patch rename to patches/unapplied/0945-Improve-tag-parser-handling.patch diff --git a/patches/server/0946-Item-Mutation-Fixes.patch b/patches/unapplied/0946-Item-Mutation-Fixes.patch similarity index 100% rename from patches/server/0946-Item-Mutation-Fixes.patch rename to patches/unapplied/0946-Item-Mutation-Fixes.patch diff --git a/patches/server/0947-Per-world-ticks-per-spawn-settings.patch b/patches/unapplied/0947-Per-world-ticks-per-spawn-settings.patch similarity index 100% rename from patches/server/0947-Per-world-ticks-per-spawn-settings.patch rename to patches/unapplied/0947-Per-world-ticks-per-spawn-settings.patch diff --git a/patches/server/0948-Properly-track-the-changed-item-from-dispense-events.patch b/patches/unapplied/0948-Properly-track-the-changed-item-from-dispense-events.patch similarity index 100% rename from patches/server/0948-Properly-track-the-changed-item-from-dispense-events.patch rename to patches/unapplied/0948-Properly-track-the-changed-item-from-dispense-events.patch diff --git a/patches/server/0949-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch b/patches/unapplied/0949-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch similarity index 100% rename from patches/server/0949-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch rename to patches/unapplied/0949-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch diff --git a/patches/server/0950-Fix-tripwire-disarming-not-working-as-intended.patch b/patches/unapplied/0950-Fix-tripwire-disarming-not-working-as-intended.patch similarity index 100% rename from patches/server/0950-Fix-tripwire-disarming-not-working-as-intended.patch rename to patches/unapplied/0950-Fix-tripwire-disarming-not-working-as-intended.patch diff --git a/patches/server/0951-Add-config-for-mobs-immune-to-default-effects.patch b/patches/unapplied/0951-Add-config-for-mobs-immune-to-default-effects.patch similarity index 100% rename from patches/server/0951-Add-config-for-mobs-immune-to-default-effects.patch rename to patches/unapplied/0951-Add-config-for-mobs-immune-to-default-effects.patch diff --git a/patches/server/0952-Deep-clone-nbt-tags-in-PDC.patch b/patches/unapplied/0952-Deep-clone-nbt-tags-in-PDC.patch similarity index 100% rename from patches/server/0952-Deep-clone-nbt-tags-in-PDC.patch rename to patches/unapplied/0952-Deep-clone-nbt-tags-in-PDC.patch diff --git a/patches/server/0953-Support-old-UUID-format-for-NBT.patch b/patches/unapplied/0953-Support-old-UUID-format-for-NBT.patch similarity index 100% rename from patches/server/0953-Support-old-UUID-format-for-NBT.patch rename to patches/unapplied/0953-Support-old-UUID-format-for-NBT.patch diff --git a/patches/server/0954-Fix-shield-disable-inconsistency.patch b/patches/unapplied/0954-Fix-shield-disable-inconsistency.patch similarity index 100% rename from patches/server/0954-Fix-shield-disable-inconsistency.patch rename to patches/unapplied/0954-Fix-shield-disable-inconsistency.patch diff --git a/patches/server/0955-Handle-Large-Packets-disconnecting-client.patch b/patches/unapplied/0955-Handle-Large-Packets-disconnecting-client.patch similarity index 100% rename from patches/server/0955-Handle-Large-Packets-disconnecting-client.patch rename to patches/unapplied/0955-Handle-Large-Packets-disconnecting-client.patch diff --git a/patches/server/0956-Fix-ItemFlags.patch b/patches/unapplied/0956-Fix-ItemFlags.patch similarity index 100% rename from patches/server/0956-Fix-ItemFlags.patch rename to patches/unapplied/0956-Fix-ItemFlags.patch diff --git a/patches/server/0957-Fix-helmet-damage-reduction-inconsistencies.patch b/patches/unapplied/0957-Fix-helmet-damage-reduction-inconsistencies.patch similarity index 100% rename from patches/server/0957-Fix-helmet-damage-reduction-inconsistencies.patch rename to patches/unapplied/0957-Fix-helmet-damage-reduction-inconsistencies.patch diff --git a/patches/server/0958-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch b/patches/unapplied/0958-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch similarity index 100% rename from patches/server/0958-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch rename to patches/unapplied/0958-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch diff --git a/patches/server/0959-improve-checking-handled-tags-in-itemmeta.patch b/patches/unapplied/0959-improve-checking-handled-tags-in-itemmeta.patch similarity index 100% rename from patches/server/0959-improve-checking-handled-tags-in-itemmeta.patch rename to patches/unapplied/0959-improve-checking-handled-tags-in-itemmeta.patch diff --git a/patches/server/0960-General-ItemMeta-fixes.patch b/patches/unapplied/0960-General-ItemMeta-fixes.patch similarity index 100% rename from patches/server/0960-General-ItemMeta-fixes.patch rename to patches/unapplied/0960-General-ItemMeta-fixes.patch diff --git a/patches/server/0961-Expose-hasColor-to-leather-armor.patch b/patches/unapplied/0961-Expose-hasColor-to-leather-armor.patch similarity index 100% rename from patches/server/0961-Expose-hasColor-to-leather-armor.patch rename to patches/unapplied/0961-Expose-hasColor-to-leather-armor.patch diff --git a/patches/server/0962-Added-API-to-get-player-ha-proxy-address.patch b/patches/unapplied/0962-Added-API-to-get-player-ha-proxy-address.patch similarity index 100% rename from patches/server/0962-Added-API-to-get-player-ha-proxy-address.patch rename to patches/unapplied/0962-Added-API-to-get-player-ha-proxy-address.patch diff --git a/patches/server/0963-More-Chest-Block-API.patch b/patches/unapplied/0963-More-Chest-Block-API.patch similarity index 100% rename from patches/server/0963-More-Chest-Block-API.patch rename to patches/unapplied/0963-More-Chest-Block-API.patch diff --git a/patches/server/0964-Print-data-component-type-on-encoding-error.patch b/patches/unapplied/0964-Print-data-component-type-on-encoding-error.patch similarity index 100% rename from patches/server/0964-Print-data-component-type-on-encoding-error.patch rename to patches/unapplied/0964-Print-data-component-type-on-encoding-error.patch diff --git a/patches/server/0965-Brigadier-based-command-API.patch b/patches/unapplied/0965-Brigadier-based-command-API.patch similarity index 100% rename from patches/server/0965-Brigadier-based-command-API.patch rename to patches/unapplied/0965-Brigadier-based-command-API.patch diff --git a/patches/server/0966-Fix-issues-with-Recipe-API.patch b/patches/unapplied/0966-Fix-issues-with-Recipe-API.patch similarity index 100% rename from patches/server/0966-Fix-issues-with-Recipe-API.patch rename to patches/unapplied/0966-Fix-issues-with-Recipe-API.patch diff --git a/patches/server/0967-Fix-equipment-slot-and-group-API.patch b/patches/unapplied/0967-Fix-equipment-slot-and-group-API.patch similarity index 100% rename from patches/server/0967-Fix-equipment-slot-and-group-API.patch rename to patches/unapplied/0967-Fix-equipment-slot-and-group-API.patch diff --git a/patches/server/0968-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch b/patches/unapplied/0968-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch similarity index 100% rename from patches/server/0968-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch rename to patches/unapplied/0968-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch diff --git a/patches/server/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch b/patches/unapplied/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch similarity index 100% rename from patches/server/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch rename to patches/unapplied/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch diff --git a/patches/server/0970-Prevent-NPE-if-hooked-entity-was-cleared.patch b/patches/unapplied/0970-Prevent-NPE-if-hooked-entity-was-cleared.patch similarity index 100% rename from patches/server/0970-Prevent-NPE-if-hooked-entity-was-cleared.patch rename to patches/unapplied/0970-Prevent-NPE-if-hooked-entity-was-cleared.patch diff --git a/patches/server/0971-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch b/patches/unapplied/0971-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch similarity index 100% rename from patches/server/0971-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch rename to patches/unapplied/0971-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch diff --git a/patches/server/0972-Add-missing-fishing-event-state.patch b/patches/unapplied/0972-Add-missing-fishing-event-state.patch similarity index 100% rename from patches/server/0972-Add-missing-fishing-event-state.patch rename to patches/unapplied/0972-Add-missing-fishing-event-state.patch diff --git a/patches/server/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch b/patches/unapplied/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch similarity index 100% rename from patches/server/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch rename to patches/unapplied/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch diff --git a/patches/server/0974-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch b/patches/unapplied/0974-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch similarity index 100% rename from patches/server/0974-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch rename to patches/unapplied/0974-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch diff --git a/patches/server/0975-Adopt-MaterialRerouting.patch b/patches/unapplied/0975-Adopt-MaterialRerouting.patch similarity index 100% rename from patches/server/0975-Adopt-MaterialRerouting.patch rename to patches/unapplied/0975-Adopt-MaterialRerouting.patch diff --git a/patches/server/0976-Suspicious-Effect-Entry-API.patch b/patches/unapplied/0976-Suspicious-Effect-Entry-API.patch similarity index 100% rename from patches/server/0976-Suspicious-Effect-Entry-API.patch rename to patches/unapplied/0976-Suspicious-Effect-Entry-API.patch diff --git a/patches/server/0977-check-if-itemstack-is-stackable-first.patch b/patches/unapplied/0977-check-if-itemstack-is-stackable-first.patch similarity index 100% rename from patches/server/0977-check-if-itemstack-is-stackable-first.patch rename to patches/unapplied/0977-check-if-itemstack-is-stackable-first.patch diff --git a/patches/server/0978-Fix-removing-recipes-from-RecipeIterator.patch b/patches/unapplied/0978-Fix-removing-recipes-from-RecipeIterator.patch similarity index 100% rename from patches/server/0978-Fix-removing-recipes-from-RecipeIterator.patch rename to patches/unapplied/0978-Fix-removing-recipes-from-RecipeIterator.patch diff --git a/patches/server/0979-Configurable-damage-tick-when-blocking-with-shield.patch b/patches/unapplied/0979-Configurable-damage-tick-when-blocking-with-shield.patch similarity index 100% rename from patches/server/0979-Configurable-damage-tick-when-blocking-with-shield.patch rename to patches/unapplied/0979-Configurable-damage-tick-when-blocking-with-shield.patch diff --git a/patches/server/0980-Properly-remove-the-experimental-smithing-inventory-.patch b/patches/unapplied/0980-Properly-remove-the-experimental-smithing-inventory-.patch similarity index 100% rename from patches/server/0980-Properly-remove-the-experimental-smithing-inventory-.patch rename to patches/unapplied/0980-Properly-remove-the-experimental-smithing-inventory-.patch diff --git a/patches/server/0981-Moonrise-optimisation-patches.patch b/patches/unapplied/0981-Moonrise-optimisation-patches.patch similarity index 100% rename from patches/server/0981-Moonrise-optimisation-patches.patch rename to patches/unapplied/0981-Moonrise-optimisation-patches.patch diff --git a/patches/server/0982-Rewrite-dataconverter-system.patch b/patches/unapplied/0982-Rewrite-dataconverter-system.patch similarity index 100% rename from patches/server/0982-Rewrite-dataconverter-system.patch rename to patches/unapplied/0982-Rewrite-dataconverter-system.patch diff --git a/patches/server/0983-disable-forced-empty-world-ticks.patch b/patches/unapplied/0983-disable-forced-empty-world-ticks.patch similarity index 100% rename from patches/server/0983-disable-forced-empty-world-ticks.patch rename to patches/unapplied/0983-disable-forced-empty-world-ticks.patch diff --git a/patches/server/0984-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch b/patches/unapplied/0984-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch similarity index 100% rename from patches/server/0984-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch rename to patches/unapplied/0984-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch diff --git a/patches/server/0985-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/patches/unapplied/0985-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch similarity index 100% rename from patches/server/0985-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch rename to patches/unapplied/0985-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch diff --git a/patches/server/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch b/patches/unapplied/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch similarity index 100% rename from patches/server/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch rename to patches/unapplied/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch diff --git a/patches/server/0987-Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/patches/unapplied/0987-Optimize-Network-Manager-and-add-advanced-packet-sup.patch similarity index 100% rename from patches/server/0987-Optimize-Network-Manager-and-add-advanced-packet-sup.patch rename to patches/unapplied/0987-Optimize-Network-Manager-and-add-advanced-packet-sup.patch diff --git a/patches/server/0988-Allow-Saving-of-Oversized-Chunks.patch b/patches/unapplied/0988-Allow-Saving-of-Oversized-Chunks.patch similarity index 100% rename from patches/server/0988-Allow-Saving-of-Oversized-Chunks.patch rename to patches/unapplied/0988-Allow-Saving-of-Oversized-Chunks.patch diff --git a/patches/server/0989-Flat-bedrock-generator-settings.patch b/patches/unapplied/0989-Flat-bedrock-generator-settings.patch similarity index 100% rename from patches/server/0989-Flat-bedrock-generator-settings.patch rename to patches/unapplied/0989-Flat-bedrock-generator-settings.patch diff --git a/patches/server/0990-Entity-Activation-Range-2.0.patch b/patches/unapplied/0990-Entity-Activation-Range-2.0.patch similarity index 100% rename from patches/server/0990-Entity-Activation-Range-2.0.patch rename to patches/unapplied/0990-Entity-Activation-Range-2.0.patch diff --git a/patches/server/0991-Optional-per-player-mob-spawns.patch b/patches/unapplied/0991-Optional-per-player-mob-spawns.patch similarity index 100% rename from patches/server/0991-Optional-per-player-mob-spawns.patch rename to patches/unapplied/0991-Optional-per-player-mob-spawns.patch diff --git a/patches/server/0992-Anti-Xray.patch b/patches/unapplied/0992-Anti-Xray.patch similarity index 100% rename from patches/server/0992-Anti-Xray.patch rename to patches/unapplied/0992-Anti-Xray.patch diff --git a/patches/server/0993-Eigencraft-redstone-implementation.patch b/patches/unapplied/0993-Eigencraft-redstone-implementation.patch similarity index 100% rename from patches/server/0993-Eigencraft-redstone-implementation.patch rename to patches/unapplied/0993-Eigencraft-redstone-implementation.patch diff --git a/patches/server/0994-Add-Alternate-Current-redstone-implementation.patch b/patches/unapplied/0994-Add-Alternate-Current-redstone-implementation.patch similarity index 100% rename from patches/server/0994-Add-Alternate-Current-redstone-implementation.patch rename to patches/unapplied/0994-Add-Alternate-Current-redstone-implementation.patch diff --git a/patches/server/0995-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch b/patches/unapplied/0995-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch similarity index 100% rename from patches/server/0995-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch rename to patches/unapplied/0995-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch diff --git a/patches/server/0996-Use-Velocity-compression-and-cipher-natives.patch b/patches/unapplied/0996-Use-Velocity-compression-and-cipher-natives.patch similarity index 100% rename from patches/server/0996-Use-Velocity-compression-and-cipher-natives.patch rename to patches/unapplied/0996-Use-Velocity-compression-and-cipher-natives.patch diff --git a/patches/server/0997-Optimize-Collision-to-not-load-chunks.patch b/patches/unapplied/0997-Optimize-Collision-to-not-load-chunks.patch similarity index 100% rename from patches/server/0997-Optimize-Collision-to-not-load-chunks.patch rename to patches/unapplied/0997-Optimize-Collision-to-not-load-chunks.patch diff --git a/patches/server/0998-Optimize-GoalSelector-Goal.Flag-Set-operations.patch b/patches/unapplied/0998-Optimize-GoalSelector-Goal.Flag-Set-operations.patch similarity index 100% rename from patches/server/0998-Optimize-GoalSelector-Goal.Flag-Set-operations.patch rename to patches/unapplied/0998-Optimize-GoalSelector-Goal.Flag-Set-operations.patch diff --git a/patches/server/0999-Optimize-Hoppers.patch b/patches/unapplied/0999-Optimize-Hoppers.patch similarity index 100% rename from patches/server/0999-Optimize-Hoppers.patch rename to patches/unapplied/0999-Optimize-Hoppers.patch diff --git a/patches/server/1000-Entity-load-save-limit-per-chunk.patch b/patches/unapplied/1000-Entity-load-save-limit-per-chunk.patch similarity index 100% rename from patches/server/1000-Entity-load-save-limit-per-chunk.patch rename to patches/unapplied/1000-Entity-load-save-limit-per-chunk.patch diff --git a/patches/server/1001-Optimize-Voxel-Shape-Merging.patch b/patches/unapplied/1001-Optimize-Voxel-Shape-Merging.patch similarity index 100% rename from patches/server/1001-Optimize-Voxel-Shape-Merging.patch rename to patches/unapplied/1001-Optimize-Voxel-Shape-Merging.patch diff --git a/patches/server/1002-Optimize-Bit-Operations-by-inlining.patch b/patches/unapplied/1002-Optimize-Bit-Operations-by-inlining.patch similarity index 100% rename from patches/server/1002-Optimize-Bit-Operations-by-inlining.patch rename to patches/unapplied/1002-Optimize-Bit-Operations-by-inlining.patch diff --git a/patches/server/1003-Remove-streams-from-hot-code.patch b/patches/unapplied/1003-Remove-streams-from-hot-code.patch similarity index 100% rename from patches/server/1003-Remove-streams-from-hot-code.patch rename to patches/unapplied/1003-Remove-streams-from-hot-code.patch diff --git a/patches/server/1004-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch b/patches/unapplied/1004-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch similarity index 100% rename from patches/server/1004-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch rename to patches/unapplied/1004-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch diff --git a/patches/server/1005-Custom-table-implementation-for-blockstate-state-loo.patch b/patches/unapplied/1005-Custom-table-implementation-for-blockstate-state-loo.patch similarity index 100% rename from patches/server/1005-Custom-table-implementation-for-blockstate-state-loo.patch rename to patches/unapplied/1005-Custom-table-implementation-for-blockstate-state-loo.patch diff --git a/patches/server/1006-Fix-entity-type-tags-suggestions-in-selectors.patch b/patches/unapplied/1006-Fix-entity-type-tags-suggestions-in-selectors.patch similarity index 100% rename from patches/server/1006-Fix-entity-type-tags-suggestions-in-selectors.patch rename to patches/unapplied/1006-Fix-entity-type-tags-suggestions-in-selectors.patch diff --git a/patches/server/1007-Handle-Oversized-block-entities-in-chunks.patch b/patches/unapplied/1007-Handle-Oversized-block-entities-in-chunks.patch similarity index 100% rename from patches/server/1007-Handle-Oversized-block-entities-in-chunks.patch rename to patches/unapplied/1007-Handle-Oversized-block-entities-in-chunks.patch diff --git a/patches/server/1008-API-for-checking-sent-chunks.patch b/patches/unapplied/1008-API-for-checking-sent-chunks.patch similarity index 100% rename from patches/server/1008-API-for-checking-sent-chunks.patch rename to patches/unapplied/1008-API-for-checking-sent-chunks.patch diff --git a/patches/server/1009-Check-distance-in-entity-interactions.patch b/patches/unapplied/1009-Check-distance-in-entity-interactions.patch similarity index 100% rename from patches/server/1009-Check-distance-in-entity-interactions.patch rename to patches/unapplied/1009-Check-distance-in-entity-interactions.patch diff --git a/patches/server/1010-Configurable-Sand-Duping.patch b/patches/unapplied/1010-Configurable-Sand-Duping.patch similarity index 100% rename from patches/server/1010-Configurable-Sand-Duping.patch rename to patches/unapplied/1010-Configurable-Sand-Duping.patch diff --git a/patches/server/1011-Optimise-general-POI-access.patch b/patches/unapplied/1011-Optimise-general-POI-access.patch similarity index 100% rename from patches/server/1011-Optimise-general-POI-access.patch rename to patches/unapplied/1011-Optimise-general-POI-access.patch diff --git a/patches/server/1012-Improve-performance-of-mass-crafts.patch b/patches/unapplied/1012-Improve-performance-of-mass-crafts.patch similarity index 100% rename from patches/server/1012-Improve-performance-of-mass-crafts.patch rename to patches/unapplied/1012-Improve-performance-of-mass-crafts.patch diff --git a/patches/server/1013-Properly-resend-entities.patch b/patches/unapplied/1013-Properly-resend-entities.patch similarity index 100% rename from patches/server/1013-Properly-resend-entities.patch rename to patches/unapplied/1013-Properly-resend-entities.patch diff --git a/patches/server/1014-Registry-Modification-API.patch b/patches/unapplied/1014-Registry-Modification-API.patch similarity index 100% rename from patches/server/1014-Registry-Modification-API.patch rename to patches/unapplied/1014-Registry-Modification-API.patch diff --git a/patches/server/1015-Add-registry-entry-and-builders.patch b/patches/unapplied/1015-Add-registry-entry-and-builders.patch similarity index 100% rename from patches/server/1015-Add-registry-entry-and-builders.patch rename to patches/unapplied/1015-Add-registry-entry-and-builders.patch diff --git a/patches/server/1016-Improved-Watchdog-Support.patch b/patches/unapplied/1016-Improved-Watchdog-Support.patch similarity index 100% rename from patches/server/1016-Improved-Watchdog-Support.patch rename to patches/unapplied/1016-Improved-Watchdog-Support.patch diff --git a/patches/server/1017-Proxy-ItemStack-to-CraftItemStack.patch b/patches/unapplied/1017-Proxy-ItemStack-to-CraftItemStack.patch similarity index 100% rename from patches/server/1017-Proxy-ItemStack-to-CraftItemStack.patch rename to patches/unapplied/1017-Proxy-ItemStack-to-CraftItemStack.patch diff --git a/patches/server/1018-Make-a-PDC-view-accessible-directly-from-ItemStack.patch b/patches/unapplied/1018-Make-a-PDC-view-accessible-directly-from-ItemStack.patch similarity index 100% rename from patches/server/1018-Make-a-PDC-view-accessible-directly-from-ItemStack.patch rename to patches/unapplied/1018-Make-a-PDC-view-accessible-directly-from-ItemStack.patch diff --git a/patches/server/1019-Prioritize-Minecraft-commands-in-function-parsing-an.patch b/patches/unapplied/1019-Prioritize-Minecraft-commands-in-function-parsing-an.patch similarity index 100% rename from patches/server/1019-Prioritize-Minecraft-commands-in-function-parsing-an.patch rename to patches/unapplied/1019-Prioritize-Minecraft-commands-in-function-parsing-an.patch diff --git a/patches/server/1020-optimize-dirt-and-snow-spreading.patch b/patches/unapplied/1020-optimize-dirt-and-snow-spreading.patch similarity index 100% rename from patches/server/1020-optimize-dirt-and-snow-spreading.patch rename to patches/unapplied/1020-optimize-dirt-and-snow-spreading.patch diff --git a/patches/server/1021-Fix-NPE-for-Jukebox-setRecord.patch b/patches/unapplied/1021-Fix-NPE-for-Jukebox-setRecord.patch similarity index 100% rename from patches/server/1021-Fix-NPE-for-Jukebox-setRecord.patch rename to patches/unapplied/1021-Fix-NPE-for-Jukebox-setRecord.patch diff --git a/patches/server/1022-Fix-CraftWorld-isChunkGenerated.patch b/patches/unapplied/1022-Fix-CraftWorld-isChunkGenerated.patch similarity index 100% rename from patches/server/1022-Fix-CraftWorld-isChunkGenerated.patch rename to patches/unapplied/1022-Fix-CraftWorld-isChunkGenerated.patch diff --git a/patches/server/1023-fix-horse-inventories.patch b/patches/unapplied/1023-fix-horse-inventories.patch similarity index 100% rename from patches/server/1023-fix-horse-inventories.patch rename to patches/unapplied/1023-fix-horse-inventories.patch diff --git a/patches/server/1024-Only-call-EntityDamageEvents-before-actuallyHurt.patch b/patches/unapplied/1024-Only-call-EntityDamageEvents-before-actuallyHurt.patch similarity index 100% rename from patches/server/1024-Only-call-EntityDamageEvents-before-actuallyHurt.patch rename to patches/unapplied/1024-Only-call-EntityDamageEvents-before-actuallyHurt.patch diff --git a/patches/server/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch b/patches/unapplied/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch similarity index 100% rename from patches/server/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch rename to patches/unapplied/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch diff --git a/patches/server/1026-Lag-compensation-ticks.patch b/patches/unapplied/1026-Lag-compensation-ticks.patch similarity index 100% rename from patches/server/1026-Lag-compensation-ticks.patch rename to patches/unapplied/1026-Lag-compensation-ticks.patch diff --git a/patches/server/1027-Detail-more-information-in-watchdog-dumps.patch b/patches/unapplied/1027-Detail-more-information-in-watchdog-dumps.patch similarity index 100% rename from patches/server/1027-Detail-more-information-in-watchdog-dumps.patch rename to patches/unapplied/1027-Detail-more-information-in-watchdog-dumps.patch diff --git a/patches/server/1028-Write-SavedData-IO-async.patch b/patches/unapplied/1028-Write-SavedData-IO-async.patch similarity index 100% rename from patches/server/1028-Write-SavedData-IO-async.patch rename to patches/unapplied/1028-Write-SavedData-IO-async.patch diff --git a/patches/server/1029-Add-ItemType-getItemRarity.patch b/patches/unapplied/1029-Add-ItemType-getItemRarity.patch similarity index 100% rename from patches/server/1029-Add-ItemType-getItemRarity.patch rename to patches/unapplied/1029-Add-ItemType-getItemRarity.patch diff --git a/patches/server/1030-Incremental-chunk-and-player-saving.patch b/patches/unapplied/1030-Incremental-chunk-and-player-saving.patch similarity index 100% rename from patches/server/1030-Incremental-chunk-and-player-saving.patch rename to patches/unapplied/1030-Incremental-chunk-and-player-saving.patch diff --git a/patches/server/1031-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch b/patches/unapplied/1031-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch similarity index 100% rename from patches/server/1031-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch rename to patches/unapplied/1031-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch diff --git a/patches/server/1032-Bundle-spark.patch b/patches/unapplied/1032-Bundle-spark.patch similarity index 100% rename from patches/server/1032-Bundle-spark.patch rename to patches/unapplied/1032-Bundle-spark.patch diff --git a/patches/server/1033-Add-plugin-info-at-startup.patch b/patches/unapplied/1033-Add-plugin-info-at-startup.patch similarity index 100% rename from patches/server/1033-Add-plugin-info-at-startup.patch rename to patches/unapplied/1033-Add-plugin-info-at-startup.patch diff --git a/patches/server/1034-Make-interaction-leniency-distance-configurable.patch b/patches/unapplied/1034-Make-interaction-leniency-distance-configurable.patch similarity index 100% rename from patches/server/1034-Make-interaction-leniency-distance-configurable.patch rename to patches/unapplied/1034-Make-interaction-leniency-distance-configurable.patch diff --git a/patches/server/1035-Fix-PickupStatus-getting-reset.patch b/patches/unapplied/1035-Fix-PickupStatus-getting-reset.patch similarity index 100% rename from patches/server/1035-Fix-PickupStatus-getting-reset.patch rename to patches/unapplied/1035-Fix-PickupStatus-getting-reset.patch diff --git a/patches/server/1036-Check-for-block-type-in-SculkSensorBlock-canActivate.patch b/patches/unapplied/1036-Check-for-block-type-in-SculkSensorBlock-canActivate.patch similarity index 100% rename from patches/server/1036-Check-for-block-type-in-SculkSensorBlock-canActivate.patch rename to patches/unapplied/1036-Check-for-block-type-in-SculkSensorBlock-canActivate.patch diff --git a/patches/server/1037-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch b/patches/unapplied/1037-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch similarity index 100% rename from patches/server/1037-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch rename to patches/unapplied/1037-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch diff --git a/patches/server/1038-Configuration-for-horizontal-only-item-merging.patch b/patches/unapplied/1038-Configuration-for-horizontal-only-item-merging.patch similarity index 100% rename from patches/server/1038-Configuration-for-horizontal-only-item-merging.patch rename to patches/unapplied/1038-Configuration-for-horizontal-only-item-merging.patch diff --git a/patches/server/1039-Optimise-collision-checking-in-player-move-packet-ha.patch b/patches/unapplied/1039-Optimise-collision-checking-in-player-move-packet-ha.patch similarity index 100% rename from patches/server/1039-Optimise-collision-checking-in-player-move-packet-ha.patch rename to patches/unapplied/1039-Optimise-collision-checking-in-player-move-packet-ha.patch diff --git a/patches/server/1040-Add-skipping-world-symlink-scan.patch b/patches/unapplied/1040-Add-skipping-world-symlink-scan.patch similarity index 100% rename from patches/server/1040-Add-skipping-world-symlink-scan.patch rename to patches/unapplied/1040-Add-skipping-world-symlink-scan.patch diff --git a/patches/server/1041-Add-even-more-Enchantment-API.patch b/patches/unapplied/1041-Add-even-more-Enchantment-API.patch similarity index 100% rename from patches/server/1041-Add-even-more-Enchantment-API.patch rename to patches/unapplied/1041-Add-even-more-Enchantment-API.patch diff --git a/patches/server/1042-Leashable-API.patch b/patches/unapplied/1042-Leashable-API.patch similarity index 100% rename from patches/server/1042-Leashable-API.patch rename to patches/unapplied/1042-Leashable-API.patch diff --git a/patches/server/1043-Fix-CraftBukkit-drag-system.patch b/patches/unapplied/1043-Fix-CraftBukkit-drag-system.patch similarity index 100% rename from patches/server/1043-Fix-CraftBukkit-drag-system.patch rename to patches/unapplied/1043-Fix-CraftBukkit-drag-system.patch diff --git a/patches/server/1044-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch b/patches/unapplied/1044-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch similarity index 100% rename from patches/server/1044-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch rename to patches/unapplied/1044-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch diff --git a/patches/server/1045-Remove-set-damage-lootable-item-function-from-compas.patch b/patches/unapplied/1045-Remove-set-damage-lootable-item-function-from-compas.patch similarity index 100% rename from patches/server/1045-Remove-set-damage-lootable-item-function-from-compas.patch rename to patches/unapplied/1045-Remove-set-damage-lootable-item-function-from-compas.patch diff --git a/patches/server/1046-Properly-destroy-placed-blocks-on-the-end-platform.patch b/patches/unapplied/1046-Properly-destroy-placed-blocks-on-the-end-platform.patch similarity index 100% rename from patches/server/1046-Properly-destroy-placed-blocks-on-the-end-platform.patch rename to patches/unapplied/1046-Properly-destroy-placed-blocks-on-the-end-platform.patch diff --git a/patches/server/1047-Add-enchantment-seed-update-API.patch b/patches/unapplied/1047-Add-enchantment-seed-update-API.patch similarity index 100% rename from patches/server/1047-Add-enchantment-seed-update-API.patch rename to patches/unapplied/1047-Add-enchantment-seed-update-API.patch diff --git a/patches/server/1048-Fix-synchronise-sending-chat-to-client-with-updating.patch b/patches/unapplied/1048-Fix-synchronise-sending-chat-to-client-with-updating.patch similarity index 100% rename from patches/server/1048-Fix-synchronise-sending-chat-to-client-with-updating.patch rename to patches/unapplied/1048-Fix-synchronise-sending-chat-to-client-with-updating.patch diff --git a/patches/server/1049-Fix-InventoryOpenEvent-cancellation.patch b/patches/unapplied/1049-Fix-InventoryOpenEvent-cancellation.patch similarity index 100% rename from patches/server/1049-Fix-InventoryOpenEvent-cancellation.patch rename to patches/unapplied/1049-Fix-InventoryOpenEvent-cancellation.patch diff --git a/patches/server/1050-Fire-BlockExpEvent-on-grindstone-use.patch b/patches/unapplied/1050-Fire-BlockExpEvent-on-grindstone-use.patch similarity index 100% rename from patches/server/1050-Fire-BlockExpEvent-on-grindstone-use.patch rename to patches/unapplied/1050-Fire-BlockExpEvent-on-grindstone-use.patch diff --git a/patches/server/1051-Check-dead-flag-in-isAlive.patch b/patches/unapplied/1051-Check-dead-flag-in-isAlive.patch similarity index 100% rename from patches/server/1051-Check-dead-flag-in-isAlive.patch rename to patches/unapplied/1051-Check-dead-flag-in-isAlive.patch diff --git a/patches/server/1052-Add-FeatureFlag-API.patch b/patches/unapplied/1052-Add-FeatureFlag-API.patch similarity index 100% rename from patches/server/1052-Add-FeatureFlag-API.patch rename to patches/unapplied/1052-Add-FeatureFlag-API.patch diff --git a/patches/server/1053-Tag-Lifecycle-Events.patch b/patches/unapplied/1053-Tag-Lifecycle-Events.patch similarity index 100% rename from patches/server/1053-Tag-Lifecycle-Events.patch rename to patches/unapplied/1053-Tag-Lifecycle-Events.patch diff --git a/patches/server/1054-Item-serialization-as-json.patch b/patches/unapplied/1054-Item-serialization-as-json.patch similarity index 100% rename from patches/server/1054-Item-serialization-as-json.patch rename to patches/unapplied/1054-Item-serialization-as-json.patch diff --git a/patches/server/1055-Validate-slot-in-PlayerInventory-setSlot.patch b/patches/unapplied/1055-Validate-slot-in-PlayerInventory-setSlot.patch similarity index 100% rename from patches/server/1055-Validate-slot-in-PlayerInventory-setSlot.patch rename to patches/unapplied/1055-Validate-slot-in-PlayerInventory-setSlot.patch diff --git a/patches/server/1056-Remove-wall-time-unused-skip-tick-protection.patch b/patches/unapplied/1056-Remove-wall-time-unused-skip-tick-protection.patch similarity index 100% rename from patches/server/1056-Remove-wall-time-unused-skip-tick-protection.patch rename to patches/unapplied/1056-Remove-wall-time-unused-skip-tick-protection.patch diff --git a/patches/server/1057-Disable-pretty-printing-for-advancement-saving.patch b/patches/unapplied/1057-Disable-pretty-printing-for-advancement-saving.patch similarity index 100% rename from patches/server/1057-Disable-pretty-printing-for-advancement-saving.patch rename to patches/unapplied/1057-Disable-pretty-printing-for-advancement-saving.patch diff --git a/patches/server/1058-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch b/patches/unapplied/1058-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch similarity index 100% rename from patches/server/1058-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch rename to patches/unapplied/1058-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch diff --git a/patches/server/1059-Add-enchantWithLevels-with-enchantment-registry-set.patch b/patches/unapplied/1059-Add-enchantWithLevels-with-enchantment-registry-set.patch similarity index 100% rename from patches/server/1059-Add-enchantWithLevels-with-enchantment-registry-set.patch rename to patches/unapplied/1059-Add-enchantWithLevels-with-enchantment-registry-set.patch diff --git a/patches/server/1060-Improve-entity-effect-API.patch b/patches/unapplied/1060-Improve-entity-effect-API.patch similarity index 100% rename from patches/server/1060-Improve-entity-effect-API.patch rename to patches/unapplied/1060-Improve-entity-effect-API.patch diff --git a/patches/server/1061-Add-recipeBrewTime.patch b/patches/unapplied/1061-Add-recipeBrewTime.patch similarity index 100% rename from patches/server/1061-Add-recipeBrewTime.patch rename to patches/unapplied/1061-Add-recipeBrewTime.patch diff --git a/patches/server/1062-Call-bucket-events-for-cauldrons.patch b/patches/unapplied/1062-Call-bucket-events-for-cauldrons.patch similarity index 100% rename from patches/server/1062-Call-bucket-events-for-cauldrons.patch rename to patches/unapplied/1062-Call-bucket-events-for-cauldrons.patch diff --git a/patches/server/1063-Add-PlayerInsertLecternBookEvent.patch b/patches/unapplied/1063-Add-PlayerInsertLecternBookEvent.patch similarity index 100% rename from patches/server/1063-Add-PlayerInsertLecternBookEvent.patch rename to patches/unapplied/1063-Add-PlayerInsertLecternBookEvent.patch diff --git a/patches/server/1064-Void-damage-configuration-API.patch b/patches/unapplied/1064-Void-damage-configuration-API.patch similarity index 100% rename from patches/server/1064-Void-damage-configuration-API.patch rename to patches/unapplied/1064-Void-damage-configuration-API.patch diff --git a/patches/server/1065-Add-Offline-PDC-API.patch b/patches/unapplied/1065-Add-Offline-PDC-API.patch similarity index 100% rename from patches/server/1065-Add-Offline-PDC-API.patch rename to patches/unapplied/1065-Add-Offline-PDC-API.patch diff --git a/patches/server/1066-Add-AnvilView-bypassEnchantmentLevelRestriction.patch b/patches/unapplied/1066-Add-AnvilView-bypassEnchantmentLevelRestriction.patch similarity index 100% rename from patches/server/1066-Add-AnvilView-bypassEnchantmentLevelRestriction.patch rename to patches/unapplied/1066-Add-AnvilView-bypassEnchantmentLevelRestriction.patch diff --git a/patches/server/1067-Add-proper-async-player-disconnections.patch b/patches/unapplied/1067-Add-proper-async-player-disconnections.patch similarity index 100% rename from patches/server/1067-Add-proper-async-player-disconnections.patch rename to patches/unapplied/1067-Add-proper-async-player-disconnections.patch diff --git a/patches/server/1068-Always-send-Banner-patterns-to-the-client.patch b/patches/unapplied/1068-Always-send-Banner-patterns-to-the-client.patch similarity index 100% rename from patches/server/1068-Always-send-Banner-patterns-to-the-client.patch rename to patches/unapplied/1068-Always-send-Banner-patterns-to-the-client.patch diff --git a/patches/unapplied/server/1036-Optimise-nearby-player-retrieval.patch b/patches/unapplied/9999-Optimise-nearby-player-retrieval.patch similarity index 100% rename from patches/unapplied/server/1036-Optimise-nearby-player-retrieval.patch rename to patches/unapplied/9999-Optimise-nearby-player-retrieval.patch diff --git a/work/BuildData b/work/BuildData index 533b02cd6ba8..0ea6fcc9bc8a 160000 --- a/work/BuildData +++ b/work/BuildData @@ -1 +1 @@ -Subproject commit 533b02cd6ba8dbf8c8607250b02bf2d8c36421e8 +Subproject commit 0ea6fcc9bc8ad9e7c729f5031123bcc69ce2b033 diff --git a/work/Bukkit b/work/Bukkit index bb4e97c60d29..f6ac70751dbb 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit bb4e97c60d2978a1d008f21295a5234228341e14 +Subproject commit f6ac70751dbb9d2280a14b3706248987c243e313 diff --git a/work/CraftBukkit b/work/CraftBukkit index 0a7bd6c81a33..459c38af3079 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 0a7bd6c81a33cfaaa2f4d2456c6b237792f38fe6 +Subproject commit 459c38af307944fbf03a472cba33c71d93287d33 diff --git a/work/Spigot b/work/Spigot index a759b629cbf8..a084d85da860 160000 --- a/work/Spigot +++ b/work/Spigot @@ -1 +1 @@ -Subproject commit a759b629cbf86401aab56b8c3f21a635e9e76c15 +Subproject commit a084d85da8604d468f81091f56dc81166d912931 From d0028b77c7b8fdfe39fe43628713baee7a158a62 Mon Sep 17 00:00:00 2001 From: Noah van der Aa Date: Tue, 22 Oct 2024 18:32:41 +0200 Subject: [PATCH 002/119] you saw nothing --- ...0428-Experimental-annotations-change.patch | 9 +++--- patches/api/0430-Improve-Registry.patch | 4 +-- .../0457-Fix-SpawnerEntry-Equipment-API.patch | 28 ++----------------- 3 files changed, 9 insertions(+), 32 deletions(-) diff --git a/patches/api/0428-Experimental-annotations-change.patch b/patches/api/0428-Experimental-annotations-change.patch index 2bf2c2cd371d..d096bbb35b5d 100644 --- a/patches/api/0428-Experimental-annotations-change.patch +++ b/patches/api/0428-Experimental-annotations-change.patch @@ -44,10 +44,10 @@ index 615eb24ffdd8f6d55ccd4f21760b809c1098bc68..f4ccb19107464e92744fbf66d55bf81f WHITE_BUNDLE(12072, 1), ORANGE_BUNDLE(18288, 1), diff --git a/src/main/java/org/bukkit/Sound.java b/src/main/java/org/bukkit/Sound.java -index cf17af024b1953b6f21f18885411ea6a0baa1d4c..544d5bf9fafe91e81314c75114a8a3516808db1d 100644 +index cf17af024b1953b6f21f18885411ea6a0baa1d4c..2f951b0aa7e383a89e3e4244ffcae4e1b3a108e7 100644 --- a/src/main/java/org/bukkit/Sound.java +++ b/src/main/java/org/bukkit/Sound.java -@@ -1530,9 +1530,18 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa +@@ -1530,9 +1530,17 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa ITEM_BUCKET_FILL_LAVA("item.bucket.fill_lava"), ITEM_BUCKET_FILL_POWDER_SNOW("item.bucket.fill_powder_snow"), ITEM_BUCKET_FILL_TADPOLE("item.bucket.fill_tadpole"), @@ -57,12 +57,11 @@ index cf17af024b1953b6f21f18885411ea6a0baa1d4c..544d5bf9fafe91e81314c75114a8a351 + @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation + @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation ITEM_BUNDLE_INSERT("item.bundle.insert"), -+<<<<<<< HEAD ++ @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation ++ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation ITEM_BUNDLE_INSERT_FAIL("item.bundle.insert_fail"), -+======= + @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation + @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation -+>>>>>>> Experimental annotations change ITEM_BUNDLE_REMOVE_ONE("item.bundle.remove_one"), ITEM_CHORUS_FRUIT_TELEPORT("item.chorus_fruit.teleport"), ITEM_CROP_PLANT("item.crop.plant"), diff --git a/patches/api/0430-Improve-Registry.patch b/patches/api/0430-Improve-Registry.patch index 22a37762fcfb..605294e92678 100644 --- a/patches/api/0430-Improve-Registry.patch +++ b/patches/api/0430-Improve-Registry.patch @@ -146,10 +146,10 @@ index 6112db5d1153d045f2271038bada6b46d1a6a051..67cf3fcad21a8977d6fad172cc776b62 } } diff --git a/src/main/java/org/bukkit/Sound.java b/src/main/java/org/bukkit/Sound.java -index 544d5bf9fafe91e81314c75114a8a3516808db1d..a52c8a0bd030265567b7c1aa80b04eced37fcbbf 100644 +index 2f951b0aa7e383a89e3e4244ffcae4e1b3a108e7..c866613ee1fb47daf89179dd30d74489c90be96d 100644 --- a/src/main/java/org/bukkit/Sound.java +++ b/src/main/java/org/bukkit/Sound.java -@@ -1664,6 +1664,13 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa +@@ -1663,6 +1663,13 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa this.key = NamespacedKey.minecraft(key); } diff --git a/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch b/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch index c860be02a467..64ee6e4eec03 100644 --- a/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch +++ b/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch @@ -4,30 +4,11 @@ Date: Fri, 26 Apr 2024 17:00:00 -0700 Subject: [PATCH] Fix SpawnerEntry$Equipment API -diff --git a/src/main/java/org/bukkit/Sound.java b/src/main/java/org/bukkit/Sound.java -index a52c8a0bd030265567b7c1aa80b04eced37fcbbf..c866613ee1fb47daf89179dd30d74489c90be96d 100644 ---- a/src/main/java/org/bukkit/Sound.java -+++ b/src/main/java/org/bukkit/Sound.java -@@ -1536,12 +1536,11 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa - @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation - @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation - ITEM_BUNDLE_INSERT("item.bundle.insert"), --<<<<<<< HEAD -+ @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation -+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation - ITEM_BUNDLE_INSERT_FAIL("item.bundle.insert_fail"), --======= - @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation - @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation -->>>>>>> Experimental annotations change - ITEM_BUNDLE_REMOVE_ONE("item.bundle.remove_one"), - ITEM_CHORUS_FRUIT_TELEPORT("item.chorus_fruit.teleport"), - ITEM_CROP_PLANT("item.crop.plant"), diff --git a/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java b/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java -index fc1c0435dfea121923eb1fe0182880752f321143..4f00ebb78f7549aed0a250f494222b97b830d0f3 100644 +index fc1c0435dfea121923eb1fe0182880752f321143..5cb482d42b0babd5a40598dc7fcf79c7d8c63655 100644 --- a/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java +++ b/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java -@@ -120,27 +120,33 @@ public class SpawnerEntry { +@@ -120,27 +120,29 @@ public class SpawnerEntry { private final Map dropChances; public Equipment(@NotNull LootTable equipmentLootTable, @NotNull Map dropChances) { @@ -40,11 +21,8 @@ index fc1c0435dfea121923eb1fe0182880752f321143..4f00ebb78f7549aed0a250f494222b97 - * Set the loot table for the entity. + * Set the loot table for the spawned entity's equipment slots. *
    -+<<<<<<< HEAD - * To remove a loot table use null. -+======= +- * To remove a loot table use null. + * To remove a loot table use {@link LootTables#EMPTY}. -+>>>>>>> Fix SpawnerEntry$Equipment API * * @param table this {@link org.bukkit.entity.Mob} will have. */ From e080b20c45281d4da8c8e8c4d79c2cd32a7a3a24 Mon Sep 17 00:00:00 2001 From: Noah van der Aa Date: Tue, 22 Oct 2024 18:43:46 +0200 Subject: [PATCH 003/119] Bundles are no longer experimental (thanks lynx) --- patches/api/0004-Code-Generation.patch | 4 +- ...0428-Experimental-annotations-change.patch | 47 ------------------- patches/api/0430-Improve-Registry.patch | 4 +- 3 files changed, 4 insertions(+), 51 deletions(-) diff --git a/patches/api/0004-Code-Generation.patch b/patches/api/0004-Code-Generation.patch index fd41f2bc506f..a53a0638102c 100644 --- a/patches/api/0004-Code-Generation.patch +++ b/patches/api/0004-Code-Generation.patch @@ -366,13 +366,13 @@ index 0000000000000000000000000000000000000000..99375deaa6b90b33cd6a77e0df651236 +record TypedKeyImpl(Key key, RegistryKey registryKey) implements TypedKey { +} diff --git a/src/main/java/org/bukkit/MinecraftExperimental.java b/src/main/java/org/bukkit/MinecraftExperimental.java -index b7845523e8587e13b86516c0012fe097d904846c..08d1deb42b17987b24699aa42d1166e08fbe846e 100644 +index b7845523e8587e13b86516c0012fe097d904846c..765a691f5b4f91425bb3057ceb4bbff06c6df1e8 100644 --- a/src/main/java/org/bukkit/MinecraftExperimental.java +++ b/src/main/java/org/bukkit/MinecraftExperimental.java @@ -48,5 +48,6 @@ public @interface MinecraftExperimental { public enum Requires { WINTER_DROP, -+ BUNDLE, TRADE_REBALANCE // Paper ++ TRADE_REBALANCE // Paper } } diff --git a/patches/api/0428-Experimental-annotations-change.patch b/patches/api/0428-Experimental-annotations-change.patch index d096bbb35b5d..e00991155315 100644 --- a/patches/api/0428-Experimental-annotations-change.patch +++ b/patches/api/0428-Experimental-annotations-change.patch @@ -30,41 +30,6 @@ index 710f8e6242eab7b638e4f42e4e9790007f4c67b7..82f9ba32256bfc1125ee970a7fed0895 public static final FeatureFlag MINECART_IMPROVEMENTS = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("minecart_improvements")); } -diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java -index 615eb24ffdd8f6d55ccd4f21760b809c1098bc68..f4ccb19107464e92744fbf66d55bf81fd50dfcc3 100644 ---- a/src/main/java/org/bukkit/Material.java -+++ b/src/main/java/org/bukkit/Material.java -@@ -2631,6 +2631,8 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla - EGG(21603, 16), - COMPASS(24139), - RECOVERY_COMPASS(12710), -+ @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation -+ @ApiStatus.Experimental // Paper - add missing annotation - BUNDLE(16835, 1), - WHITE_BUNDLE(12072, 1), - ORANGE_BUNDLE(18288, 1), -diff --git a/src/main/java/org/bukkit/Sound.java b/src/main/java/org/bukkit/Sound.java -index cf17af024b1953b6f21f18885411ea6a0baa1d4c..2f951b0aa7e383a89e3e4244ffcae4e1b3a108e7 100644 ---- a/src/main/java/org/bukkit/Sound.java -+++ b/src/main/java/org/bukkit/Sound.java -@@ -1530,9 +1530,17 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa - ITEM_BUCKET_FILL_LAVA("item.bucket.fill_lava"), - ITEM_BUCKET_FILL_POWDER_SNOW("item.bucket.fill_powder_snow"), - ITEM_BUCKET_FILL_TADPOLE("item.bucket.fill_tadpole"), -+ @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation -+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation - ITEM_BUNDLE_DROP_CONTENTS("item.bundle.drop_contents"), -+ @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation -+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation - ITEM_BUNDLE_INSERT("item.bundle.insert"), -+ @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation -+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation - ITEM_BUNDLE_INSERT_FAIL("item.bundle.insert_fail"), -+ @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation -+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation - ITEM_BUNDLE_REMOVE_ONE("item.bundle.remove_one"), - ITEM_CHORUS_FRUIT_TELEPORT("item.chorus_fruit.teleport"), - ITEM_CROP_PLANT("item.crop.plant"), diff --git a/src/main/java/org/bukkit/block/Crafter.java b/src/main/java/org/bukkit/block/Crafter.java index 8d2dd78fc588a6817dfede8040b9909a7d5bde67..f737a2aae3f57a1bfe4cf68ea66f603da4eebd47 100644 --- a/src/main/java/org/bukkit/block/Crafter.java @@ -192,18 +157,6 @@ index bb1fb5e0518c6a62ef8b206733ee51d831f1f85b..49d0a37bbeb0b8fa9207164c74245ef0 */ -@ApiStatus.Experimental public interface CrafterInventory extends Inventory { } -diff --git a/src/main/java/org/bukkit/inventory/meta/BundleMeta.java b/src/main/java/org/bukkit/inventory/meta/BundleMeta.java -index e404cd1e2ba44e4c2d09524bc7cf730d8ffbdabd..cea0ebf50876dd32ab7fba6025b30f297d0a69c4 100644 ---- a/src/main/java/org/bukkit/inventory/meta/BundleMeta.java -+++ b/src/main/java/org/bukkit/inventory/meta/BundleMeta.java -@@ -6,6 +6,7 @@ import org.jetbrains.annotations.ApiStatus; - import org.jetbrains.annotations.NotNull; - import org.jetbrains.annotations.Nullable; - -+@org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation - @ApiStatus.Experimental - public interface BundleMeta extends ItemMeta { - diff --git a/src/main/java/org/bukkit/map/MapCursor.java b/src/main/java/org/bukkit/map/MapCursor.java index 0899981b9ab1f98dacc617156d12779421e4c275..6c33fbf720a2e11655e254aeb516e08831c2adf4 100644 --- a/src/main/java/org/bukkit/map/MapCursor.java diff --git a/patches/api/0430-Improve-Registry.patch b/patches/api/0430-Improve-Registry.patch index 605294e92678..607568bd87a0 100644 --- a/patches/api/0430-Improve-Registry.patch +++ b/patches/api/0430-Improve-Registry.patch @@ -146,10 +146,10 @@ index 6112db5d1153d045f2271038bada6b46d1a6a051..67cf3fcad21a8977d6fad172cc776b62 } } diff --git a/src/main/java/org/bukkit/Sound.java b/src/main/java/org/bukkit/Sound.java -index 2f951b0aa7e383a89e3e4244ffcae4e1b3a108e7..c866613ee1fb47daf89179dd30d74489c90be96d 100644 +index cf17af024b1953b6f21f18885411ea6a0baa1d4c..f32a035317f3f8e200bb8076e6a326cb1e87cfe1 100644 --- a/src/main/java/org/bukkit/Sound.java +++ b/src/main/java/org/bukkit/Sound.java -@@ -1663,6 +1663,13 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa +@@ -1655,6 +1655,13 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa this.key = NamespacedKey.minecraft(key); } From d280061a1a038ef5b24fa3d036819ef034b958db Mon Sep 17 00:00:00 2001 From: Noah van der Aa Date: Tue, 22 Oct 2024 19:28:57 +0200 Subject: [PATCH 004/119] First batch of server patches --- build.gradle.kts | 2 +- .../server/0001-Setup-Gradle-project.patch | 115 ++++- .../0002-Remap-fixes.patch | 12 +- .../0003-Build-system-changes.patch | 12 +- .../0004-Test-changes.patch | 38 +- .../0005-Paper-config-files.patch | 50 +-- .../0006-MC-Dev-fixes.patch | 30 +- .../0007-ConcurrentUtil.patch | 0 .../{unapplied => server}/0008-CB-fixes.patch | 16 +- .../{unapplied => server}/0009-MC-Utils.patch | 275 ++++++------ .../0010-Adventure.patch | 231 +++++----- ...oleAppender-for-console-improvements.patch | 38 +- ...n-prefixes-using-Log4J-configuration.patch | 2 +- ...e-Log4J-Configuration-Plugin-Loggers.patch | 0 ...r-to-keep-logging-IO-off-main-thread.patch | 6 +- ...ktraces-in-log-messages-crash-report.patch | 8 +- ...s-to-contain-the-source-jars-in-stac.patch | 0 .../0017-Paper-command.patch | 10 +- .../0018-Paper-Metrics.patch | 6 +- .../0019-Paper-Plugins.patch | 28 +- .../0020-Plugin-remapping.patch | 20 +- .../0021-Hook-into-CB-plugin-rewrites.patch | 0 ...ion-calls-in-plugins-using-internals.patch | 8 +- .../0023-Timings-v2.patch | 394 +++++++++--------- ...024-Further-improve-server-tick-loop.patch | 22 +- ...-option-to-load-extra-plugin-jars-no.patch | 6 +- .../0026-Support-components-in-ItemMeta.patch | 10 +- ...cactus-bamboo-and-reed-growth-height.patch | 18 +- ...figurable-baby-zombie-movement-speed.patch | 6 +- ...029-Configurable-fishing-time-ranges.patch | 8 +- .../0030-Allow-nerfed-mobs-to-jump.patch | 8 +- ...onfigurable-entity-despawn-distances.patch | 0 ...ck-and-tnt-entities-at-the-specified.patch | 0 ...0033-Expose-server-build-information.patch | 0 .../0034-Player-affects-spawning-API.patch | 0 ...035-Only-refresh-abilities-if-needed.patch | 0 .../{ => server}/0036-Entity-Origin-API.patch | 0 ...vent-block-entity-and-entity-crashes.patch | 0 ...nfigurable-top-of-nether-void-damage.patch | 0 ...e-before-converting-and-renaming-pla.patch | 0 ...ties-to-activation-range-ignore-list.patch | 0 .../0041-Configurable-end-credits.patch | 0 ...-explosions-processing-dead-entities.patch | 0 .../0043-Optimize-explosions.patch | 0 .../0044-Disable-explosion-knockback.patch | 0 .../{ => server}/0045-Disable-thunder.patch | 0 .../0046-Disable-ice-and-snow.patch | 0 ...7-Configurable-mob-spawner-tick-rate.patch | 0 .../0048-Use-null-Locale-by-default.patch | 0 .../0049-Add-BeaconEffectEvent.patch | 0 ...figurable-container-update-tick-rate.patch | 0 .../0051-Use-UserCache-for-player-heads.patch | 0 .../0052-Disable-spigot-tick-limiters.patch | 0 ...awn-location-event-changing-location.patch | 0 ...urable-Disabling-Cat-Chest-Detection.patch | 0 ...055-Improve-Player-chat-API-handling.patch | 0 ...chunks-are-slime-spawn-chunks-toggle.patch | 0 .../0057-Expose-server-CommandMap.patch | 0 ...e-informative-in-maxHealth-exception.patch | 0 .../0059-Player-Tab-List-and-Title-APIs.patch | 0 ...dd-configurable-portal-search-radius.patch | 0 .../0061-Add-velocity-warnings.patch | 0 .../0062-Add-exception-reporting-event.patch | 0 ...oreboards-for-non-players-by-default.patch | 0 ...working-with-arrows-stuck-in-living-.patch | 0 .../0065-Chunk-Save-Reattempt.patch | 0 .../0066-Complete-resource-pack-API.patch | 0 ...ading-permissions.yml-before-plugins.patch | 0 ...llow-Reloading-of-Custom-Permissions.patch | 0 .../0069-Remove-Metadata-on-reload.patch | 0 ...070-Handle-Item-Meta-Inconsistencies.patch | 0 ...urable-Non-Player-Arrow-Despawn-Rate.patch | 0 .../0072-Add-World-Util-Methods.patch | 0 ...3-Custom-replacement-for-eaten-items.patch | 0 ...th-absorb-values-and-repair-bad-data.patch | 0 ...075-Use-a-Shared-Random-for-Entities.patch | 0 ...le-spawn-chances-for-skeleton-horses.patch | 0 ...ckPhysicsEvent-if-a-plugin-has-a-lis.patch | 0 ...Entity-AddTo-RemoveFrom-World-Events.patch | 0 ...79-Configurable-Chunk-Inhabited-Time.patch | 0 .../0080-EntityPathfindEvent.patch | 0 ...egionFileCache-and-make-configurable.patch | 0 ...2-Do-not-load-chunks-for-Pathfinding.patch | 0 ...0083-Add-PlayerUseUnknownEntityEvent.patch | 0 ...gurable-random-tick-rates-for-blocks.patch | 0 ...g-BlockPlaceEvent-triggering-physics.patch | 0 .../{ => server}/0086-Optimize-DataBits.patch | 0 ...nilla-per-world-scoreboard-coloring-.patch | 0 .../0088-Configurable-Player-Collision.patch | 0 ...ent-to-allow-plugins-to-handle-clien.patch | 0 .../0090-Configurable-RCON-IP-address.patch | 0 ...ityRegainHealthEvent-isFastRegen-API.patch | 0 ...-to-configure-frosted_ice-properties.patch | 0 ...-possibility-for-getServer-singleton.patch | 0 ...y-scoreboard-teams-to-scoreboard.dat.patch | 0 ...able-API-and-replenishable-lootables.patch | 0 ...tem-property-for-disabling-watchdoge.patch | 0 .../0097-Async-GameProfileCache-saving.patch | 0 ...8-Optional-TNT-doesn-t-move-in-water.patch | 0 ...r-redstone-torch-rapid-clock-removal.patch | 0 .../0100-Add-server-name-parameter.patch | 0 .../0101-Fix-global-sound-handling.patch | 0 ...blocking-on-Network-Manager-creation.patch | 0 ...e-profiles-that-have-no-UUID-and-no-.patch | 0 ...setting-for-proxy-online-mode-status.patch | 0 ...ptimise-BlockState-s-hashCode-equals.patch | 0 ...onfigurable-packet-in-spam-threshold.patch | 0 ...07-Configurable-flying-kick-messages.patch | 0 .../0108-Add-EntityZapEvent.patch | 0 ...-entity-nbt-data-from-falling-blocks.patch | 0 ...110-Cache-user-authenticator-threads.patch | 0 ...1-Allow-Reloading-of-Command-Aliases.patch | 0 ...2-Add-source-to-PlayerExpChangeEvent.patch | 0 .../0113-Add-ProjectileCollideEvent.patch | 0 ...vent-Pathfinding-out-of-World-Border.patch | 0 ...ize-Level.hasChunkAt-BlockPosition-Z.patch | 0 ...-Bound-Treasure-Maps-to-World-Border.patch | 0 ...figurable-Cartographer-Treasure-Maps.patch | 0 ...-to-control-if-armor-stands-can-move.patch | 0 .../0119-String-based-Action-Bar-API.patch | 0 ...20-Properly-fix-item-duplication-bug.patch | 0 .../{ => server}/0121-Firework-API-s.patch | 0 .../0122-PlayerTeleportEndGatewayEvent.patch | 0 ...rovide-E-TE-Chunk-count-stat-methods.patch | 0 .../0124-Enforce-Sync-Player-Saves.patch | 0 ...PI-for-Reason-Source-Triggering-play.patch | 0 .../0126-Cap-Entity-Collisions.patch | 0 ...e-CraftScheduler-Async-Task-Debugger.patch | 0 ...le-async-calls-to-restart-the-server.patch | 0 ...ke-parrots-stay-on-shoulders-despite.patch | 0 ...n-option-to-prevent-player-names-fro.patch | 0 ...urable-option-to-disable-creeper-lin.patch | 0 .../0132-Item-canEntityPickup.patch | 0 ...PlayerPickupItemEvent-setFlyAtPlayer.patch | 0 .../0134-PlayerAttemptPickupItemEvent.patch | 0 ...-profile-lookups-to-worldgen-threads.patch | 0 .../0136-Basic-PlayerProfile-API.patch | 0 .../0137-Add-UnknownCommandEvent.patch | 0 .../0138-Shoulder-Entities-Release-API.patch | 0 .../0139-Profile-Lookup-Events.patch | 0 ...player-logins-during-server-shutdown.patch | 0 .../0141-Entity-fromMobSpawner.patch | 0 ...42-Improve-the-Saddle-API-for-Horses.patch | 0 .../0143-ensureServerConversions-API.patch | 0 .../0144-Implement-getI18NDisplayName.patch | 0 .../0145-ProfileWhitelistVerifyEvent.patch | 0 .../0146-Fix-this-stupid-bullshit.patch | 0 .../0147-LivingEntity-setKiller.patch | 0 ...awns-should-honor-nametags-and-leash.patch | 0 ...imer-when-spawner-event-is-cancelled.patch | 0 ...-a-custom-authentication-servers-dow.patch | 0 .../0151-Add-PlayerJumpEvent.patch | 0 ...dle-ServerboundKeepAlivePacket-async.patch | 0 ...nt-protocol-version-and-virtual-host.patch | 0 ...rt-serverside-behavior-of-keepalives.patch | 0 ...dEffects-only-to-players-who-can-see.patch | 0 .../0156-Add-PlayerArmorChangeEvent.patch | 0 ...rom-being-processed-when-the-player-.patch | 0 ...117075-Block-entity-unload-lag-spike.patch | 0 ...e-implementations-for-captured-block.patch | 0 ...-get-a-BlockState-without-a-snapshot.patch | 0 .../0161-AsyncTabCompleteEvent.patch | 0 .../0162-PlayerPickupExperienceEvent.patch | 0 ...3-Ability-to-apply-mending-to-XP-API.patch | 0 ...4-PlayerNaturallySpawnCreaturesEvent.patch | 0 ...-Add-setPlayerProfile-API-for-Skulls.patch | 0 .../0166-PreCreatureSpawnEvent.patch | 0 .../0167-Fill-Profile-Property-Events.patch | 0 ...PlayerAdvancementCriterionGrantEvent.patch | 0 .../0169-Add-ArmorStand-Item-Meta.patch | 0 ...-Extend-Player-Interact-cancellation.patch | 0 .../0171-Tameable-getOwnerUniqueId-API.patch | 0 .../0172-Toggleable-player-crits.patch | 0 ...le-Explicit-Network-Manager-Flushing.patch | 0 ...nt-extended-PaperServerListPingEvent.patch | 0 ...dd-more-fields-to-AsyncPreLoginEvent.patch | 0 .../0176-Player.setPlayerProfile-API.patch | 0 .../0177-getPlayerUniqueId-API.patch | 0 .../0178-Improved-Async-Task-Scheduler.patch | 0 ...ke-legacy-ping-handler-more-reliable.patch | 0 ...ServerListPingEvent-for-legacy-pings.patch | 0 ...81-Flag-to-disable-the-channel-limit.patch | 0 ...2-Add-openSign-method-to-HumanEntity.patch | 0 ...urable-sprint-interruption-on-attack.patch | 0 .../0184-EndermanEscapeEvent.patch | 0 .../0185-Enderman.teleportRandomly.patch | 0 ...0186-Block-Enderpearl-Travel-Exploit.patch | 0 ...ld.spawnParticle-API-and-add-Builder.patch | 0 ...-allowed-colored-signs-to-be-created.patch | 0 .../0189-EndermanAttackPlayerEvent.patch | 0 .../0190-WitchConsumePotionEvent.patch | 0 .../0191-WitchThrowPotionEvent.patch | 0 .../0192-WitchReadyPotionEvent.patch | 0 ...0193-ItemStack-getMaxItemUseDuration.patch | 0 ...94-Add-EntityTeleportEndGatewayEvent.patch | 0 ...ed-flag-on-cancel-of-Explosion-Event.patch | 0 .../0196-Fix-CraftEntity-hashCode.patch | 0 ...7-Configurable-LootPool-luck-formula.patch | 0 ...ils-when-failing-to-save-player-data.patch | 0 ...e-shield-blocking-delay-configurable.patch | 0 .../0200-Improve-EntityShootBowEvent.patch | 0 .../0201-PlayerReadyArrowEvent.patch | 0 .../0202-Add-entity-knockback-events.patch | 0 .../0203-Expand-Explosions-API.patch | 0 .../0204-LivingEntity-Active-Item-API.patch | 0 .../{ => server}/0205-RangedEntity-API.patch | 0 ...to-disable-ender-dragon-legacy-check.patch | 0 ...7-Implement-World.getEntity-UUID-API.patch | 0 .../0208-InventoryCloseEvent-Reason-API.patch | 0 .../0209-Vex-get-setSummoner-API.patch | 0 ...-more-information-to-Entity.toString.patch | 0 .../0211-EnderDragon-Events.patch | 0 .../0212-PlayerElytraBoostEvent.patch | 0 .../0213-PlayerLaunchProjectileEvent.patch | 0 .../0214-Improve-BlockPosition-inlining.patch | 0 ...t-armor-stands-from-doing-entity-loo.patch | 0 ...6-Vanished-players-don-t-have-rights.patch | 0 ...-Allow-disabling-armor-stand-ticking.patch | 0 .../0218-SkeletonHorse-Additions.patch | 0 .../0219-Expand-ArmorStand-API.patch | 0 .../{ => server}/0220-AnvilDamageEvent.patch | 0 .../{ => server}/0221-Add-TNTPrimeEvent.patch | 0 ...nd-make-tab-spam-limits-configurable.patch | 0 .../0223-Fix-NBT-type-issues.patch | 0 ...Remove-unnecessary-itemmeta-handling.patch | 0 ...ies-option-to-debug-dupe-uuid-issues.patch | 0 ...dd-Early-Warning-Feature-to-WatchDog.patch | 0 ...27-Use-ConcurrentHashMap-in-JsonList.patch | 0 ...28-Use-a-Queue-for-Queueing-Commands.patch | 0 ...lock-entities-from-a-chunk-without-s.patch | 0 ...ptimize-BlockPosition-helper-methods.patch | 0 ...default-mob-spawn-range-and-water-an.patch | 0 .../0232-Slime-Pathfinder-Events.patch | 0 ...le-speed-for-water-flowing-over-lava.patch | 0 ...234-Optimize-CraftBlockData-Creation.patch | 0 .../0235-Optimize-MappedRegistry.patch | 0 .../0236-Add-PhantomPreSpawnEvent.patch | 0 .../0237-Add-More-Creeper-API.patch | 0 .../0238-Inventory-removeItemAnySlot.patch | 0 ...loadChunk-int-int-false-load-unconve.patch | 0 ...-ray-tracing-methods-to-LivingEntity.patch | 0 ...e-attack-cooldown-methods-for-Player.patch | 0 .../0242-Improve-death-events.patch | 0 ...ow-chests-to-be-placed-with-NBT-data.patch | 0 .../0244-Mob-Pathfinding-API.patch | 0 ...interactions-from-causing-chunk-load.patch | 0 ...wning-from-loading-generating-chunks.patch | 0 ...nt-furnace-cook-speed-multiplier-API.patch | 0 .../0248-Honor-EntityAgeable.ageLock.patch | 0 ...ble-connection-throttle-kick-message.patch | 0 ...ent-chunk-loading-from-Fluid-Flowing.patch | 0 .../0251-PreSpawnerSpawnEvent.patch | 0 ...252-Add-LivingEntity-getTargetEntity.patch | 0 .../0253-Add-sun-related-API.patch | 0 .../{ => server}/0254-Turtle-API.patch | 0 ...tator-target-events-and-improve-impl.patch | 0 .../0256-Add-more-Witch-API.patch | 0 ...owned-for-Villager-Aggression-Config.patch | 0 ...event-players-from-moving-into-unloa.patch | 0 ...59-Reset-players-airTicks-on-respawn.patch | 0 ...-after-profile-lookups-if-not-needed.patch | 0 ...er-Thread-Pool-and-Thread-Priorities.patch | 0 .../0262-Optimize-World-Time-Updates.patch | 0 ...store-custom-InventoryHolder-support.patch | 0 .../0264-Fix-SpongeAbsortEvent-handling.patch | 0 ...t-allow-digging-into-unloaded-chunks.patch | 0 ...ault-permission-message-configurable.patch | 0 ...entity-dismount-during-teleportation.patch | 0 .../0268-Add-more-Zombie-API.patch | 0 .../{ => server}/0269-Book-size-limits.patch | 0 .../0270-Add-PlayerConnectionCloseEvent.patch | 0 ...-Replace-OfflinePlayer-getLastPlayed.patch | 0 ...vehicle-tracking-issue-on-disconnect.patch | 0 ...r-remove-if-the-handle-is-a-custom-p.patch | 0 .../{ => server}/0274-BlockDestroyEvent.patch | 0 .../0275-Async-command-map-building.patch | 0 .../0276-Brigadier-Mojang-API.patch | 0 ...rove-exact-choice-recipe-ingredients.patch | 0 .../0278-Limit-Client-Sign-length-more.patch | 0 ...oggleEvent-when-whitelist-is-toggled.patch | 0 ...nd-additions-to-the-spawn-reason-API.patch | 0 .../0281-Fire-event-on-GS4-query.patch | 0 .../0282-Add-PlayerPostRespawnEvent.patch | 0 .../0283-Server-Tick-Events.patch | 0 ...0284-PlayerDeathEvent-getItemsToKeep.patch | 0 ...Optimize-Captured-BlockEntity-Lookup.patch | 0 .../0286-Mob-Spawner-API-Enhancements.patch | 0 ...l-to-changed-postToMainThread-method.patch | 0 ...n-item-frames-are-modified-MC-123450.patch | 0 .../0289-Implement-CraftBlockSoundGroup.patch | 0 ...290-Expose-the-internal-current-tick.patch | 0 ...ate-location-if-we-failed-to-read-it.patch | 0 ...al-Spawned-mobs-towards-natural-spaw.patch | 0 ...gurable-projectile-relative-velocity.patch | 0 .../0294-offset-item-frame-ticking.patch | 0 ...revent-consuming-the-wrong-itemstack.patch | 0 ...96-Dont-send-unnecessary-sign-update.patch | 0 ...d-option-to-disable-pillager-patrols.patch | 0 ...nk-loads-when-villagers-try-to-find-.patch | 0 ...5656-Fix-Follow-Range-Initial-Target.patch | 0 .../0300-Duplicate-UUID-Resolve-Option.patch | 0 ...layerDeathEvent-shouldDropExperience.patch | 0 ...oading-chunks-checking-hive-position.patch | 0 ...Chunks-from-Hoppers-and-other-things.patch | 0 ...ptimise-EntityGetter-getPlayerByUUID.patch | 0 ...0305-Fix-items-not-falling-correctly.patch | 0 ...mize-call-to-getFluid-for-explosions.patch | 0 ...rializing-mismatching-chunk-coordina.patch | 0 .../0308-Alternative-item-despawn-rate.patch | 0 .../0309-Tracking-Range-Improvements.patch | 0 ...get-gravity-in-void.-Fixes-MC-167279.patch | 0 ...311-Improve-Block-breakNaturally-API.patch | 0 ...e-getChunkAt-calls-for-loaded-chunks.patch | 0 .../0313-Add-debug-for-sync-chunk-loads.patch | 0 .../0314-Improve-java-version-check.patch | 0 .../0315-Add-ThrownEggHatchEvent.patch | 0 .../{ => server}/0316-Entity-Jump-API.patch | 0 ...n-to-nerf-pigmen-from-nether-portals.patch | 0 .../0318-Make-the-GUI-graph-fancier.patch | 0 ...319-add-hand-to-BlockMultiPlaceEvent.patch | 0 ...ripwire-hook-placement-before-update.patch | 0 ...to-allow-iron-golems-to-spawn-in-air.patch | 0 ...-chance-of-villager-zombie-infection.patch | 0 .../0323-Optimise-Chunk-getFluid.patch | 0 ...erbose-world-setting-to-false-by-def.patch | 0 ...-Add-tick-times-API-and-mspt-command.patch | 0 ...326-Expose-MinecraftServer-isRunning.patch | 0 ...Add-Raw-Byte-ItemStack-Serialization.patch | 0 ...spawn-settings-and-per-player-option.patch | 0 ...nnections-shouldn-t-hold-up-shutdown.patch | 0 ...low-bees-to-load-chunks-for-beehives.patch | 0 ...-PlayerChunkMap-adds-crashing-server.patch | 0 .../0332-Don-t-tick-dead-players.patch | 0 ...d-Player-s-shouldn-t-be-able-to-move.patch | 0 ...move-existing-players-to-world-spawn.patch | 0 .../0335-Optimize-Pathfinding.patch | 0 ...36-Reduce-Either-Optional-allocation.patch | 0 ...duce-memory-footprint-of-CompoundTag.patch | 0 ...vent-opening-inventories-when-frozen.patch | 0 ...-entity-collision-code-if-not-needed.patch | 0 ...-Implement-Player-Client-Options-API.patch | 0 ...layer-is-attempted-to-be-removed-fro.patch | 0 ...nEvent-when-Player-is-actually-ready.patch | 0 ...pawn-point-if-spawn-in-unloaded-worl.patch | 0 ...PlayerAttackEntityCooldownResetEvent.patch | 0 ...t-fire-BlockFade-on-worldgen-threads.patch | 0 ...ntom-creative-and-insomniac-controls.patch | 0 ...item-duplication-and-teleport-issues.patch | 0 .../0348-Villager-Restocks-API.patch | 0 ...PickItem-Packet-and-kick-for-invalid.patch | 0 ...-per-thread-native-byte-buffer-cache.patch | 0 .../0351-misc-debugging-dumps.patch | 0 ...52-Prevent-teleporting-dead-entities.patch | 0 .../0353-Implement-Mob-Goal-API.patch | 0 .../0354-Add-villager-reputation-API.patch | 0 ...ceOrb-merging-stacking-API-and-fixes.patch | 0 ...6-Fix-PotionEffect-ignores-icon-flag.patch | 0 .../{ => server}/0357-Potential-bed-API.patch | 0 ...Wait-for-Async-Tasks-during-shutdown.patch | 0 ...der-respects-game-and-entity-rules-f.patch | 0 ...n-for-console-having-all-permissions.patch | 0 ...ix-villager-trading-demand-MC-163962.patch | 0 .../0362-Maps-shouldn-t-load-chunks.patch | 0 ...ookup-for-Treasure-Maps-Fixes-lag-fr.patch | 0 ...er-runTaskTimerAsynchronously-Plugin.patch | 0 ...ston-physics-inconsistency-MC-188840.patch | 0 ...ssing-chunks-due-to-integer-overflow.patch | 0 ...t-position-desync-causing-tp-exploit.patch | 0 ...Holder-method-without-block-snapshot.patch | 0 .../0369-Add-PlayerRecipeBookClickEvent.patch | 0 ...0-Hide-sync-chunk-writes-behind-flag.patch | 0 ...71-Add-permission-for-command-blocks.patch | 0 ...-position-and-AABB-are-never-invalid.patch | 0 ...ld-Difficulty-Remembering-Difficulty.patch | 0 .../0374-Paper-dumpitem-command.patch | 0 ...-Legacy-Component-serialization-size.patch | 0 ...-Plugin-Tickets-to-API-Chunk-Methods.patch | 0 ...7-Add-BlockStateMeta-clearBlockState.patch | 0 ...nvert-legacy-attributes-in-Item-Meta.patch | 0 ...o-not-accept-invalid-client-settings.patch | 0 ...ve-fix-EntityTargetLivingEntityEvent.patch | 0 .../0381-Add-entity-liquid-API.patch | 0 .../0382-Add-PrepareResultEvent.patch | 0 ...k-for-portal-on-world-gen-entity-add.patch | 0 ...ix-arrows-never-despawning-MC-125757.patch | 0 ...-Vanilla-Command-permission-checking.patch | 0 ...4-Bukkit-world-container-is-not-used.patch | 0 ...-5885-Unable-to-disable-advancements.patch | 0 ...ataPlayer-leak-due-from-quitting-ear.patch | 0 ...ze-NetworkManager-Exception-Handling.patch | 0 ...Fix-some-rails-connecting-improperly.patch | 0 ...istake-in-CB-NBT-int-deserialization.patch | 0 .../{ => server}/0392-Brand-support.patch | 0 ...yPickupItemAnimation-to-LivingEntity.patch | 0 .../0394-Don-t-require-FACING-data.patch | 0 ...geEvent-not-firing-for-all-use-cases.patch | 0 .../0396-Add-moon-phase-API.patch | 0 ...erver-load-chunks-from-newer-version.patch | 0 ...-headless-pistons-from-being-created.patch | 0 .../{ => server}/0399-Add-BellRingEvent.patch | 0 ...Add-zombie-targets-turtle-egg-config.patch | 0 .../0401-Buffer-joins-to-world.patch | 0 ...rs-not-working-in-some-kick-messages.patch | 0 .../0403-Add-more-Evoker-API.patch | 0 ...-Add-methods-to-get-translation-keys.patch | 0 ...ate-HoverEvent-from-ItemStack-Entity.patch | 0 .../0406-Cache-block-data-strings.patch | 0 ...ortation-and-cancel-velocity-if-tele.patch | 0 ...al-open-container-api-to-HumanEntity.patch | 0 ...taFixerUpper-Rewrite-Rules-on-demand.patch | 0 ...p-capture-to-capture-all-items-added.patch | 0 ...y-Counter-to-allow-plugins-to-use-va.patch | 0 ...-track-plugin-scoreboards-by-default.patch | 0 .../{ => server}/0413-Entity-isTicking.patch | 0 ...-non-whitelisted-player-when-white-l.patch | 0 ...x-Concurrency-issue-in-ShufflingList.patch | 0 ...Reset-Ender-Crystals-on-Dragon-Spawn.patch | 0 ...r-large-move-vectors-crashing-server.patch | 0 .../0418-Optimise-getType-calls.patch | 0 .../0419-Villager-resetOffers.patch | 0 ...ace-order-when-capturing-blockstates.patch | 0 ...tem-locations-dropped-from-campfires.patch | 0 ...22-Fix-bell-block-entity-memory-leak.patch | 0 ...ling-up-when-item-stack-is-empty-in-.patch | 0 ...-Add-getOfflinePlayerIfCached-String.patch | 0 .../0425-Add-ignore-discounts-API.patch | 0 ...-Toggle-for-removing-existing-dragon.patch | 0 ...ix-client-lag-on-advancement-loading.patch | 0 .../0428-Item-no-age-no-player-pickup.patch | 0 ...0429-Beacon-API-custom-effect-ranges.patch | 0 .../0430-Add-API-for-quit-reason.patch | 0 ...ing-Trader-spawn-rate-config-options.patch | 0 .../0432-Add-Destroy-Speed-API.patch | 0 ...r-spawnParticle-x-y-z-precision-loss.patch | 0 ...434-Add-LivingEntity-clearActiveItem.patch | 0 .../0435-Add-PlayerItemCooldownEvent.patch | 0 ...prove-performance-of-the-end-generat.patch | 0 .../0437-More-lightning-API.patch | 0 ...-should-not-bypass-cramming-gamerule.patch | 0 ...d-missing-default-perms-for-commands.patch | 0 .../0440-Add-PlayerShearBlockEvent.patch | 0 .../0441-Limit-recipe-packets.patch | 0 ...x-CraftSound-backwards-compatibility.patch | 0 ...0443-Player-Chunk-Load-Unload-Events.patch | 0 ...44-Optimize-Dynamic-get-Missing-Keys.patch | 0 ...5-Expose-LivingEntity-hurt-direction.patch | 0 ...-OBSTRUCTED-reason-to-BedEnterResult.patch | 0 ...nvalid-ingredient-lists-in-VillagerA.patch | 0 .../0448-Add-TargetHitEvent.patch | 0 .../0449-MC-4-Fix-item-position-desync.patch | 0 .../0450-Additional-Block-Material-API.patch | 0 .../0451-Fix-harming-potion-dupe.patch | 0 ...et-Material-from-Boats-and-Minecarts.patch | 0 ...mob-spawner-spawn-egg-transformation.patch | 0 ...Fix-Not-a-string-Map-Conversion-spam.patch | 0 ...5-Add-PlayerFlowerPotManipulateEvent.patch | 0 ...act-event-not-being-called-sometimes.patch | 0 .../0457-Zombie-API-breaking-doors.patch | 0 ...0458-Fix-nerfed-slime-when-splitting.patch | 0 .../0459-Add-EntityLoadCrossbowEvent.patch | 0 .../0460-Add-WorldGameRuleChangeEvent.patch | 0 ...461-Add-ServerResourcesReloadedEvent.patch | 0 ...ld-settings-for-mobs-picking-up-loot.patch | 0 .../0463-Add-BlockFailedDispenseEvent.patch | 0 ...464-Add-PlayerLecternPageChangeEvent.patch | 0 ...465-Add-PlayerLoomPatternSelectEvent.patch | 0 ...onfigurable-door-breaking-difficulty.patch | 0 ...pty-commands-shall-not-be-dispatched.patch | 0 .../{ => server}/0468-Remove-stale-POIs.patch | 0 .../0469-Fix-villager-boat-exploit.patch | 0 .../0470-Add-sendOpLevel-API.patch | 0 ...gistryAccess-for-managing-Registries.patch | 0 .../0472-Add-StructuresLocateEvent.patch | 0 ...n-for-requiring-a-player-participant.patch | 0 ...onent-with-empty-text-instead-of-thr.patch | 0 ...0475-Make-schedule-command-per-world.patch | 0 ...0476-Configurable-max-leash-distance.patch | 0 .../0477-Add-BlockPreDispenseEvent.patch | 0 ...78-Add-PlayerChangeBeaconEffectEvent.patch | 0 ...le-for-always-placing-the-dragon-egg.patch | 0 ...d-PlayerStonecutterRecipeSelectEvent.patch | 0 .../0481-Expand-EntityUnleashEvent.patch | 0 ...-shield-blocking-on-dimension-change.patch | 0 .../0483-Add-DragonEggFormEvent.patch | 0 .../0484-Add-EntityMoveEvent.patch | 0 ...disable-pathfinding-updates-on-block.patch | 0 .../0486-Inline-shift-direction-fields.patch | 0 ...w-adding-items-to-BlockDropItemEvent.patch | 0 ...ainThreadExecutor-to-BukkitScheduler.patch | 0 ...-entity-allow-attribute-registration.patch | 0 ...fix-dead-slime-setSize-invincibility.patch | 0 ...ipes-should-return-an-immutable-list.patch | 0 .../0492-Expose-Tracked-Players.patch | 0 .../{ => server}/0493-Improve-ServerGUI.patch | 0 ...0494-fix-converting-txt-to-json-file.patch | 0 .../0495-Add-worldborder-events.patch | 0 .../0496-Add-PlayerNameEntityEvent.patch | 0 .../0497-Add-recipe-to-cook-events.patch | 0 .../0498-Add-Block-isValidTool.patch | 0 ...-using-signs-inside-spawn-protection.patch | 0 .../0500-Expand-world-key-API.patch | 0 ...lternative-constructor-for-Rotations.patch | 0 ...ed-item-when-player-has-disconnected.patch | 0 ...telist-use-configurable-kick-message.patch | 0 ...ignore-result-of-PlayerEditBookEvent.patch | 0 .../0505-Expose-protocol-version.patch | 0 ...tab-completions-for-brigadier-comman.patch | 0 ...ItemConsumeEvent-cancelling-properly.patch | 0 .../0508-Add-bypass-host-check.patch | 0 .../0509-Set-area-affect-cloud-rotation.patch | 0 ...-add-isDeeplySleeping-to-HumanEntity.patch | 0 ...-add-consumeFuel-to-FurnaceBurnEvent.patch | 0 ...t-set-drop-chance-to-EntityEquipment.patch | 0 ...fix-PigZombieAngerEvent-cancellation.patch | 0 ...fix-PlayerItemHeldEvent-firing-twice.patch | 0 .../0515-Add-PlayerDeepSleepEvent.patch | 0 .../{ => server}/0516-More-World-API.patch | 0 .../0517-Add-PlayerBedFailEnterEvent.patch | 0 ...s-to-convert-between-Component-and-B.patch | 0 ...pawnEvent-fix-passed-parameter-issue.patch | 0 ...eacon-activation-deactivation-events.patch | 0 ...Add-Channel-initialization-listeners.patch | 0 ...mmands-if-tab-completion-is-disabled.patch | 0 .../0523-Add-more-WanderingTrader-API.patch | 0 ...Add-EntityBlockStorage-clearEntities.patch | 0 ...essage-to-PlayerAdvancementDoneEvent.patch | 0 .../0526-Add-HiddenPotionEffect-API.patch | 0 .../{ => server}/0527-Inventory-close.patch | 0 ...n-in-sunlight-API-for-Phantoms-and-S.patch | 0 .../0529-Add-basic-Datapack-API.patch | 0 ...nment-variable-to-disable-server-gui.patch | 0 ...531-Expand-PlayerGameModeChangeEvent.patch | 0 .../0532-ItemStack-repair-check-API.patch | 0 .../0533-More-Enchantment-API.patch | 0 ...ove-range-check-for-block-placing-up.patch | 0 .../0535-Add-Mob-lookAt-API.patch | 0 ...if-bucket-dispenses-will-succeed-for.patch | 0 .../0537-Add-Unix-domain-socket-support.patch | 0 .../0538-Add-EntityInsideBlockEvent.patch | 0 ...9-Improve-item-default-attribute-API.patch | 0 ...cause-to-Weather-ThunderChangeEvents.patch | 0 .../0541-More-Lidded-Block-API.patch | 0 ...542-Limit-item-frame-cursors-on-maps.patch | 0 .../0543-Add-PlayerKickEvent-causes.patch | 0 .../0544-Add-PufferFishStateChangeEvent.patch | 0 ...yerBucketEmptyEvent-result-itemstack.patch | 0 ...ttedContainer-instead-of-ThreadingDe.patch | 0 ...n-to-fix-items-merging-through-walls.patch | 0 .../0548-Add-BellRevealRaiderEvent.patch | 0 .../0549-Fix-invulnerable-end-crystals.patch | 0 ...550-Add-ElderGuardianAppearanceEvent.patch | 0 ...e-Biome-Mob-Lookups-for-Mob-Spawning.patch | 0 .../0552-Line-Of-Sight-Changes.patch | 0 .../0553-add-per-world-spawn-limits.patch | 0 .../0554-Fix-potions-splash-events.patch | 0 .../0555-Add-more-LimitedRegion-API.patch | 0 ...PlayerDropItemEvent-using-wrong-item.patch | 0 .../0557-Missing-Entity-API.patch | 0 ...-of-Block-applyBoneMeal-always-being.patch | 0 ...etChunkIfLoadedImmediately-in-places.patch | 0 ...from-signs-not-firing-command-events.patch | 0 .../0561-Add-PlayerArmSwingEvent.patch | 0 ...k-event-leave-message-not-being-sent.patch | 0 ...n-t-apply-cramming-damage-to-players.patch | 0 ...nd-timings-for-sensors-and-behaviors.patch | 0 .../0565-Add-missing-forceDrop-toggles.patch | 0 .../{ => server}/0566-Stinger-API.patch | 0 .../0567-Add-System.out-err-catcher.patch | 0 ...-AFK-kick-while-watching-end-credits.patch | 0 ...riting-of-comments-to-server.propert.patch | 0 .../0570-Add-PlayerSetSpawnEvent.patch | 0 ...ers-respect-inventory-max-stack-size.patch | 0 ...mize-entity-tracker-passenger-checks.patch | 0 ...g-option-for-Piglins-guarding-chests.patch | 0 .../0574-Add-EntityDamageItemEvent.patch | 0 ...ptimize-indirect-passenger-iteration.patch | 0 ...tem-frame-map-cursor-update-interval.patch | 0 ...target-without-changing-other-things.patch | 0 .../0578-Add-BlockBreakBlockEvent.patch | 0 ...t-data-components-copy-in-smithing-r.patch | 0 .../0580-More-CommandBlock-API.patch | 0 ...d-missing-team-sidebar-display-slots.patch | 0 .../0582-Add-back-EntityPortalExitEvent.patch | 0 ...o-find-targets-for-lightning-strikes.patch | 0 .../0584-Get-entity-default-attributes.patch | 0 .../{ => server}/0585-Left-handed-API.patch | 0 .../0586-Add-more-advancement-API.patch | 0 ...0587-Add-ItemFactory-getSpawnEgg-API.patch | 0 .../0588-Add-critical-damage-API.patch | 0 .../0589-Fix-issues-with-mob-conversion.patch | 0 ...sCollision-methods-to-various-places.patch | 0 .../{ => server}/0591-Goat-ram-API.patch | 0 ...Add-API-for-resetting-a-single-score.patch | 0 ...93-Add-Raw-Byte-Entity-Serialization.patch | 0 ...594-Vanilla-command-permission-fixes.patch | 0 ...-logic-for-inventories-on-chunk-unlo.patch | 0 ...596-Fix-GameProfileCache-concurrency.patch | 0 ...0597-Improve-and-expand-AsyncCatcher.patch | 0 ...aper-mobcaps-and-paper-playermobcaps.patch | 0 ...itize-ResourceLocation-error-logging.patch | 0 ...ally-inline-methods-in-BlockPosition.patch | 0 ...uler-threads-according-to-the-plugin.patch | 0 ...d-getChunkAt-has-inlined-logic-for-l.patch | 0 ...bour-chunk-data-off-disk-when-conver.patch | 0 ...id-state-when-raytracing-skip-air-bl.patch | 0 .../0605-Time-scoreboard-search.patch | 0 ...primise-map-impl-for-tracked-players.patch | 0 .../0607-Add-missing-InventoryType.patch | 0 ...timise-BlockSoil-nearby-water-lookup.patch | 0 ...entory-not-closing-on-entity-removal.patch | 0 ...irement-before-suggesting-root-nodes.patch | 0 ...-ServerboundCommandSuggestionPacket-.patch | 0 .../0612-Add-packet-limiter-config.patch | 0 ...rnColor-on-tropical-fish-bucket-meta.patch | 0 .../0614-Ensure-valid-vehicle-status.patch | 0 ...oftlocked-end-exit-portal-generation.patch | 0 ...or-causing-a-crash-when-trying-to-ge.patch | 0 ...n-t-log-debug-logging-being-disabled.patch | 0 ...ious-menus-with-empty-level-accesses.patch | 0 .../0619-Preserve-overstacked-loot.patch | 0 ...date-head-rotation-in-missing-places.patch | 0 ...-unintended-light-block-manipulation.patch | 0 .../0622-Fix-CraftCriteria-defaults-map.patch | 0 ...-Fix-upstreams-block-state-factories.patch | 0 .../0624-Configurable-feature-seeds.patch | 0 .../0625-Add-root-admin-user-detection.patch | 0 ...-t-attempt-to-teleport-dead-entities.patch | 0 ...sive-velocity-through-repeated-crits.patch | 0 ...de-code-using-deprecated-for-removal.patch | 0 .../0629-Fix-Spigot-growth-modifiers.patch | 0 ...rOpenersCounter-openCount-from-going.patch | 0 .../0631-Add-PlayerItemFrameChangeEvent.patch | 0 .../0632-Optimize-HashMapPalette.patch | 0 ...t-isSectionEmpty-int-and-optimize-Pa.patch | 0 .../0634-Add-more-Campfire-API.patch | 0 ...-data-to-disk-if-it-serializes-witho.patch | 0 ...ward-CraftEntity-in-teleport-command.patch | 0 .../0637-Improve-scoreboard-entries.patch | 0 .../0638-Entity-powdered-snow-API.patch | 0 .../0639-Add-API-for-item-entity-health.patch | 0 ...max-block-light-for-monster-spawning.patch | 0 ...-pistons-and-BlockPistonRetractEvent.patch | 0 ...d-canSmelt-methods-to-FurnaceInvento.patch | 0 .../{ => server}/0643-Bucketable-API.patch | 0 .../0644-Validate-usernames.patch | 0 ...ter-animal-spawn-height-configurable.patch | 0 ...vanilla-BiomeProvider-from-WorldInfo.patch | 0 ...tion-for-worlds-affected-by-time-cmd.patch | 0 ...check-for-PersistentDataContainer-ha.patch | 0 ...49-Multiple-Entries-with-Scoreboards.patch | 0 ...0650-Reset-placed-block-on-exception.patch | 0 ...-configurable-height-for-slime-spawn.patch | 0 .../0652-Fix-xp-reward-for-baby-zombies.patch | 0 ...ulti-Block-Change-API-Implementation.patch | 0 .../{ => server}/0654-Fix-NotePlayEvent.patch | 0 .../0655-Freeze-Tick-Lock-API.patch | 0 .../0656-More-PotionEffectType-API.patch | 0 ...-for-StructureTemplate.Pallete-cache.patch | 0 ...-command-sender-which-forwards-feedb.patch | 0 ...d-missing-structure-set-seed-configs.patch | 0 ...elled-powdered-snow-bucket-placement.patch | 0 ...date-calls-to-CraftServer-getSpawnLi.patch | 0 .../0662-Add-GameEvent-tags.patch | 0 ...sks-fairly-for-worlds-while-waiting-.patch | 0 .../0664-Furnace-RecipesUsed-API.patch | 0 ...igurable-sculk-sensor-listener-range.patch | 0 .../0666-Add-missing-block-data-API.patch | 0 ...efault-CustomSpawners-in-custom-worl.patch | 0 ...o-worldlist-before-initing-the-world.patch | 0 .../0669-Custom-Potion-Mixes.patch | 0 ...670-Force-close-world-loading-screen.patch | 0 ...0671-Fix-falling-block-spawn-methods.patch | 0 ...-Expose-furnace-minecart-push-values.patch | 0 ...rojectileHitEvent-for-piercing-arrow.patch | 0 .../0674-More-Projectile-API.patch | 0 ...ix-swamp-hut-cat-generation-deadlock.patch | 0 ...cle-movement-from-players-while-tele.patch | 0 .../0677-Implement-getComputedBiome-API.patch | 0 .../0678-Make-some-itemstacks-nonnull.patch | 0 ...0679-Implement-enchantWithLevels-API.patch | 0 .../0680-Fix-saving-in-unloadWorld.patch | 0 .../0681-Buffer-OOB-setBlock-calls.patch | 0 .../0682-Add-TameableDeathMessageEvent.patch | 0 ...lock-data-for-EntityChangeBlockEvent.patch | 0 ...ables-running-when-mob-loot-gamerule.patch | 0 ...assenger-world-matches-ridden-entity.patch | 0 ...eys-and-optimize-reference-Holder-ta.patch | 0 ...llow-changing-the-EnderDragon-podium.patch | 0 ...verriding-a-block-entity-during-worl.patch | 0 ...nt-tile-entity-copies-loading-chunks.patch | 0 ...tead-of-display-name-in-PlayerList-g.patch | 0 .../0691-Expand-PlayerItemDamageEvent.patch | 0 .../0692-WorldCreator-keepSpawnLoaded.patch | 0 ...E-in-CraftPersistentDataTypeRegistry.patch | 0 ..._destroyed-trigger-in-the-correct-pl.patch | 0 ...eEvent-and-CollarColorable-interface.patch | 0 ...-CauldronLevelChange-on-initial-fill.patch | 0 ...-snow-cauldrons-not-turning-to-water.patch | 0 .../0698-Add-PlayerStopUsingItemEvent.patch | 0 .../0699-Don-t-tick-markers.patch | 0 .../0700-Expand-FallingBlock-API.patch | 0 .../0701-Add-support-for-Proxy-Protocol.patch | 0 ...ix-OfflinePlayer-getBedSpawnLocation.patch | 0 ...ntory-for-smokers-and-blast-furnaces.patch | 0 .../0704-Sanitize-sent-BlockEntity-NBT.patch | 0 ...t-selector-resolving-in-books-by-def.patch | 0 ...entity-loading-causing-async-lookups.patch | 0 ...n-on-world-create-while-being-ticked.patch | 0 ...708-Dont-resent-entity-on-art-update.patch | 0 .../0709-Add-WardenAngerChangeEvent.patch | 0 ...-strict-advancement-dimension-checks.patch | 0 ...rtant-BlockStateListPopulator-method.patch | 0 .../0712-Nameable-Banner-API.patch | 0 ...broadcast-messages-to-command-blocks.patch | 0 ...mpty-items-from-being-added-to-world.patch | 0 ...shPotion-and-LingeringPotion-spawnin.patch | 0 .../0716-Add-Player-getFishHook.patch | 0 ...-chunk-for-dynamic-game-event-listen.patch | 0 ...us-missing-EntityDropItemEvent-calls.patch | 0 .../0719-Fix-Bee-flower-NPE.patch | 0 ...g-not-using-commands.spam-exclusions.patch | 0 .../{ => server}/0721-More-Teleport-API.patch | 0 .../0722-Add-EntityPortalReadyEvent.patch | 0 ...-level-random-in-entity-constructors.patch | 0 ...ck-entities-after-destroy-prediction.patch | 0 ...-on-plugins-accessing-faraway-chunks.patch | 0 ...stom-Chat-Completion-Suggestions-API.patch | 0 ...-Add-and-fix-missing-BlockFadeEvents.patch | 0 .../{ => server}/0728-Collision-API.patch | 0 ...and-message-for-brigadier-syntax-exc.patch | 0 .../{ => server}/0730-Block-Ticking-API.patch | 0 ...1-Add-Velocity-IP-Forwarding-Support.patch | 0 ...0732-Add-NamespacedKey-biome-methods.patch | 0 ...ix-plugin-loggers-on-server-shutdown.patch | 0 ...ook-changes-from-crashing-the-server.patch | 0 ...ntityChangeBlockEvent-in-more-places.patch | 0 .../0736-Missing-eating-regain-reason.patch | 0 .../0737-Missing-effect-cause.patch | 0 ...-serialization-deserialization-for-P.patch | 0 ...39-Call-BlockPhysicsEvent-more-often.patch | 0 .../0740-Configurable-chat-thread-limit.patch | 0 ...-of-WorldCreator-keepSpawnLoaded-ret.patch | 0 .../0742-fix-Jigsaw-block-kicking-user.patch | 0 ...rmEvent-for-mud-converting-into-clay.patch | 0 .../0744-Add-getDrops-to-BlockState.patch | 0 .../0745-Fix-a-bunch-of-vanilla-bugs.patch | 0 ...ry-onTrackingStart-during-navigation.patch | 0 .../0747-Fix-custom-piglin-loved-items.patch | 0 .../0748-EntityPickupItemEvent-fixes.patch | 0 ...-interactions-with-items-on-cooldown.patch | 0 ...0-Add-PlayerInventorySlotChangeEvent.patch | 0 .../0751-Elder-Guardian-appearance-API.patch | 0 .../0752-Add-entity-knockback-API.patch | 0 .../0753-Detect-headless-JREs.patch | 0 ...y-vehicle-collision-event-not-called.patch | 0 .../0755-Add-EntityToggleSitEvent.patch | 0 .../0756-Add-fire-tick-delay-option.patch | 0 .../0757-Add-Moving-Piston-API.patch | 0 .../0758-Ignore-impossible-spawn-tick.patch | 0 ...nt-and-EntitySelectorParser-permissi.patch | 0 ...tEvent-cancellation-cant-fully-preve.patch | 0 .../0761-Add-PrePlayerAttackEntityEvent.patch | 0 ...re-reset-EnderDragon-boss-event-name.patch | 0 .../0763-Add-Player-Warden-Warning-API.patch | 0 ...la-friendly-methods-to-update-trades.patch | 0 ...0765-Add-paper-dumplisteners-command.patch | 0 ...global-player-list-where-appropriate.patch | 0 ...async-entity-add-due-to-fungus-trees.patch | 0 .../0768-ItemStack-damage-API.patch | 0 .../{ => server}/0769-Friction-API.patch | 0 ...ntrol-player-s-insomnia-and-phantoms.patch | 0 ...x-premature-player-kicks-on-shutdown.patch | 0 .../0772-Sync-offhand-slot-in-menus.patch | 0 .../0773-Player-Entity-Tracking-Events.patch | 0 .../0774-Limit-pet-look-distance.patch | 0 .../{ => server}/0775-fix-Instruments.patch | 0 ...-for-some-hot-BlockBehavior-and-Flui.patch | 0 ...ies-in-dispense-events-regarding-sta.patch | 0 .../0778-Add-BlockLockCheckEvent.patch | 0 .../0779-Add-Sneaking-API-for-Entities.patch | 0 .../0780-Improve-logging-and-errors.patch | 0 .../0781-Improve-PortalEvents.patch | 0 ...tion-for-spider-worldborder-climbing.patch | 0 ...ssing-SpigotConfig-logCommands-check.patch | 0 ...-Allay-stopDancing-while-not-dancing.patch | 0 .../0785-Flying-Fall-Damage.patch | 0 ...sion-moving-velocity-to-VehicleBlock.patch | 0 ...config-for-disabling-entity-tag-tags.patch | 0 ...le-player-info-update-packet-on-join.patch | 0 ...nk-items-during-EntityResurrectEvent.patch | 0 .../{ => server}/0790-Win-Screen-API.patch | 0 ...tItemStack-setAmount-null-assignment.patch | 0 ...Fix-force-opening-enchantment-tables.patch | 0 .../0793-Add-Entity-Body-Yaw-API.patch | 0 ...event-sleeping-villagers-moving-towa.patch | 0 .../0795-Add-EntityFertilizeEggEvent.patch | 0 ...ity-drop-not-updating-the-client-inv.patch | 0 ...ItemEvent-and-EntityCompostItemEvent.patch | 0 ...ectly-handle-ArmorStand-invisibility.patch | 0 ...vancement-triggers-for-entity-damage.patch | 0 ...0800-Fix-text-display-error-on-spawn.patch | 0 ...inventories-returning-null-Locations.patch | 0 .../{ => server}/0802-Add-Shearable-API.patch | 0 ...-Fix-SpawnEggMeta-get-setSpawnedType.patch | 0 ...ng-to-bad-recipes-in-furnace-like-ti.patch | 0 ...uence-violations-like-they-should-be.patch | 0 ...expired-keys-from-impacting-new-join.patch | 0 ...nts-being-fired-from-unloaded-chunks.patch | 0 .../0808-Use-array-for-gamerule-storage.patch | 0 ...-Fix-a-couple-of-upstream-bed-issues.patch | 0 ...Fix-demo-flag-not-enabling-demo-mode.patch | 0 .../0811-Add-Mob-Experience-reward-API.patch | 0 ...-redstone-on-top-of-trap-doors-early.patch | 0 ...-Lazy-Initialization-for-Enum-Fields.patch | 0 ...814-More-accurate-isInOpenWater-impl.patch | 0 .../0815-Expand-PlayerItemMendEvent.patch | 0 ...esh-ProjectileSource-for-projectiles.patch | 0 .../0817-Add-transient-modifier-API.patch | 0 .../0818-Fix-block-place-logic.patch | 0 ...und-playing-for-BlockItem-ItemStacks.patch | 0 ...ll-BlockGrowEvent-for-missing-blocks.patch | 0 ...anhasbukkit-default-if-alias-block-e.patch | 0 ...apLike-spam-for-missing-key-selector.patch | 0 ...3-Fix-sniffer-removeExploredLocation.patch | 0 ...-to-remove-all-active-potion-effects.patch | 0 ...crafting-result-amount-for-fireworks.patch | 0 ...26-Add-event-for-player-editing-sign.patch | 0 ...ck-item-frames-if-players-can-see-it.patch | 0 ...permission-levels-for-command-blocks.patch | 0 ...-Add-option-to-disable-block-updates.patch | 0 ...0830-Call-missing-BlockDispenseEvent.patch | 0 ...d-chunks-for-supporting-block-checks.patch | 0 ...-Optimize-player-lookups-for-beacons.patch | 0 .../0833-More-Sign-Block-API.patch | 0 ...34-fix-item-meta-for-tadpole-buckets.patch | 0 .../{ => server}/0835-Fix-BanList-API.patch | 0 ...nd-water-fluid-explosion-resistance-.patch | 0 ...ix-possible-NPE-on-painting-creation.patch | 0 ...Timer-for-Wandering-Traders-spawned-.patch | 0 ...enceOrb-should-call-EntitySpawnEvent.patch | 0 ...st-throw-both-Spread-and-Grow-Events.patch | 0 .../0841-Add-whitelist-events.patch | 0 .../0842-Implement-PlayerFailMoveEvent.patch | 0 ...Folia-scheduler-and-owned-region-API.patch | 0 ...ase-allay-memory-on-non-item-targets.patch | 0 ...-API-for-updating-recipes-on-clients.patch | 0 ...ation-when-spawning-display-entities.patch | 0 ...0847-Only-capture-actual-tree-growth.patch | 0 ...urce-for-mushroom-block-spread-event.patch | 0 ...eData-on-more-entities-when-spawning.patch | 0 ...0-Use-correct-seed-on-api-world-load.patch | 0 ...ata-neighbour-ticks-outside-of-range.patch | 0 .../0852-Cache-map-ids-on-item-frames.patch | 0 ...x-custom-statistic-criteria-creation.patch | 0 .../0854-Bandaid-fix-for-Effect.patch | 0 .../0855-SculkCatalyst-bloom-API.patch | 0 ...-API-for-an-entity-s-scoreboard-name.patch | 0 ...place-methods-with-old-StructureType.patch | 0 ...te-namespaced-commands-if-send-names.patch | 0 ...y-handle-BlockBreakEvent-isDropItems.patch | 0 ...-entity-death-event-for-ender-dragon.patch | 0 ...ntity-tracking-range-by-Y-coordinate.patch | 0 .../0862-Add-Listing-API-for-Player.patch | 0 ...nfigurable-Region-Compression-Format.patch | 0 ...64-Add-BlockFace-to-BlockDamageEvent.patch | 0 .../0865-Fix-NPE-on-Boat-getStatus.patch | 0 .../{ => server}/0866-Expand-Pose-API.patch | 0 .../0867-More-DragonBattle-API.patch | 0 .../0868-Add-PlayerPickItemEvent.patch | 0 .../0869-Allow-trident-custom-damage.patch | 0 ...70-Expose-hand-in-BlockCanBuildEvent.patch | 0 ...e-nearest-structure-border-iteration.patch | 0 ...-Implement-OfflinePlayer-isConnected.patch | 0 .../{ => server}/0873-Fix-slot-desync.patch | 0 ...-titleOverride-to-InventoryOpenEvent.patch | 0 ...875-Configure-sniffer-egg-hatch-time.patch | 0 ...l-proximity-check-before-entity-look.patch | 0 ...Skip-POI-finding-if-stuck-in-vehicle.patch | 0 ...ot-sanity-checks-in-container-clicks.patch | 0 ...all-BlockRedstoneEvents-for-lecterns.patch | 0 ...proper-checking-of-empty-item-stacks.patch | 0 ...Fix-silent-equipment-change-for-mobs.patch | 0 .../0882-Fix-spigot-s-Forced-Stats.patch | 0 ...sing-InventoryHolders-to-inventories.patch | 0 ...-entities-in-chunks-that-are-positio.patch | 0 ...ssing-logs-for-log-ips-config-option.patch | 0 ...on-on-UpgradeData.BlockFixers-class-.patch | 0 ...n-AdvancementProgress-getDateAwarded.patch | 0 ...sidebar-objectives-not-being-cleared.patch | 0 ...ix-missing-map-initialize-event-call.patch | 0 ...ta-when-attaching-firework-to-entity.patch | 0 ...891-Fix-UnsafeValues-loadAdvancement.patch | 0 .../0892-Add-player-idle-duration-API.patch | 0 ...k-if-we-can-see-non-visible-entities.patch | 0 ...-NPE-in-SculkBloomEvent-world-access.patch | 0 ...stack-for-Player-sendEquipmentChange.patch | 0 .../{ => server}/0896-Optimize-VarInts.patch | 0 ...he-collision-shape-of-a-block-before.patch | 0 ...predicate-for-blocks-when-raytracing.patch | 0 ...tem-packets-with-collector-as-source.patch | 0 .../0900-Expand-LingeringPotion-API.patch | 0 ...ingEffect-powers-lightning-rods-and-.patch | 0 ...sh-event-for-all-player-interactions.patch | 0 ...several-issues-with-EntityBreedEvent.patch | 0 ...0904-Add-UUID-attribute-modifier-API.patch | 0 ...g-event-call-for-entity-teleport-API.patch | 0 ...ly-create-LootContext-for-criterions.patch | 0 ...n-t-fire-sync-events-during-worldgen.patch | 0 .../0908-Add-Structure-check-API.patch | 0 ...m-getAttributeModifier-duplication-c.patch | 0 ...estore-vanilla-entity-drops-behavior.patch | 0 ...1-Dont-resend-blocks-on-interactions.patch | 0 .../0912-add-more-scoreboard-API.patch | 0 .../{ => server}/0913-Improve-Registry.patch | 0 ...-on-null-loc-for-EntityTeleportEvent.patch | 0 .../0915-Add-experience-points-API.patch | 0 .../0916-Add-drops-to-shear-events.patch | 0 .../0917-Add-PlayerShieldDisableEvent.patch | 0 ...date-ResourceLocation-in-NBT-reading.patch | 0 ...e-experience-dropping-on-block-break.patch | 0 .../0920-Fixup-NamespacedKey-handling.patch | 0 ...921-Expose-LootTable-of-DecoratedPot.patch | 0 ...llocation-of-Vec3D-by-entity-tracker.patch | 0 ...erTradeEvent-and-PlayerPurchaseEvent.patch | 0 .../0924-Add-ShulkerDuplicateEvent.patch | 0 ...Add-api-for-spawn-egg-texture-colors.patch | 0 .../0926-Add-Lifecycle-Event-system.patch | 0 .../0927-ItemStack-Tooltip-API.patch | 0 ...kSnapshot-includeLightData-parameter.patch | 0 .../0929-Add-FluidState-API.patch | 0 .../0930-add-number-format-api.patch | 0 .../0931-improve-BanList-types.patch | 0 .../0932-Expanded-Hopper-API.patch | 0 ...33-Add-BlockBreakProgressUpdateEvent.patch | 0 .../0934-Deprecate-ItemStack-setType.patch | 0 .../0935-Add-CartographyItemEvent.patch | 0 .../{ => server}/0936-More-Raid-API.patch | 0 ...ing-message-for-initial-server-start.patch | 0 ...8-Configurable-max-block-fluid-ticks.patch | 0 .../0939-Fix-bees-aging-inside-hives.patch | 0 ...40-Disable-memory-reserve-allocating.patch | 0 ...eByEntityEvent-for-unowned-wither-sk.patch | 0 .../0942-Fix-DamageSource-API.patch | 0 ...invalid-block-entity-during-world-ge.patch | 0 ...tackOverflowError-for-some-dispenses.patch | 0 .../0945-Improve-tag-parser-handling.patch | 0 .../0946-Item-Mutation-Fixes.patch | 0 ...7-Per-world-ticks-per-spawn-settings.patch | 0 ...he-changed-item-from-dispense-events.patch | 0 ...and-End-Portal-Frames-from-being-des.patch | 0 ...re-disarming-not-working-as-intended.patch | 0 ...g-for-mobs-immune-to-default-effects.patch | 0 .../0952-Deep-clone-nbt-tags-in-PDC.patch | 0 ...0953-Support-old-UUID-format-for-NBT.patch | 0 ...954-Fix-shield-disable-inconsistency.patch | 0 ...e-Large-Packets-disconnecting-client.patch | 0 .../{ => server}/0956-Fix-ItemFlags.patch | 0 ...met-damage-reduction-inconsistencies.patch | 0 ...a-handling-of-LivingEntity-actuallyH.patch | 0 ...ve-checking-handled-tags-in-itemmeta.patch | 0 .../0960-General-ItemMeta-fixes.patch | 0 ...961-Expose-hasColor-to-leather-armor.patch | 0 ...d-API-to-get-player-ha-proxy-address.patch | 0 .../0963-More-Chest-Block-API.patch | 0 ...ata-component-type-on-encoding-error.patch | 0 .../0965-Brigadier-based-command-API.patch | 0 .../0966-Fix-issues-with-Recipe-API.patch | 0 ...967-Fix-equipment-slot-and-group-API.patch | 0 ...plugin-to-use-Paper-PluginLoader-API.patch | 0 ...oversized-item-data-in-equipment-and.patch | 0 ...ent-NPE-if-hooked-entity-was-cleared.patch | 0 ...ing-BlockPlaceEvent-calling-onRemove.patch | 0 ...0972-Add-missing-fishing-event-state.patch | 0 ...cate-InvAction-HOTBAR_MOVE_AND_READD.patch | 0 ...onnect-packet-in-phases-where-it-doe.patch | 0 .../0975-Adopt-MaterialRerouting.patch | 0 .../0976-Suspicious-Effect-Entry-API.patch | 0 ...heck-if-itemstack-is-stackable-first.patch | 0 ...removing-recipes-from-RecipeIterator.patch | 0 ...amage-tick-when-blocking-with-shield.patch | 0 ...the-experimental-smithing-inventory-.patch | 0 .../0981-Moonrise-optimisation-patches.patch | 0 .../0982-Rewrite-dataconverter-system.patch | 0 ...983-disable-forced-empty-world-ticks.patch | 0 ...ldBounds-and-getBlockState-for-inlin.patch | 0 ...item-frames-performance-and-bug-fixe.patch | 0 ...cing-for-EntityLiving-hasLineOfSight.patch | 0 ...-Manager-and-add-advanced-packet-sup.patch | 0 ...988-Allow-Saving-of-Oversized-Chunks.patch | 0 ...0989-Flat-bedrock-generator-settings.patch | 0 .../0990-Entity-Activation-Range-2.0.patch | 0 .../0991-Optional-per-player-mob-spawns.patch | 0 .../{ => server}/0992-Anti-Xray.patch | 0 ...3-Eigencraft-redstone-implementation.patch | 0 ...nate-Current-redstone-implementation.patch | 0 ...ng-PreCreatureSpawnEvent-with-per-pl.patch | 0 ...ocity-compression-and-cipher-natives.patch | 0 ...ptimize-Collision-to-not-load-chunks.patch | 0 ...oalSelector-Goal.Flag-Set-operations.patch | 0 .../{ => server}/0999-Optimize-Hoppers.patch | 0 ...000-Entity-load-save-limit-per-chunk.patch | 0 .../1001-Optimize-Voxel-Shape-Merging.patch | 0 ...-Optimize-Bit-Operations-by-inlining.patch | 0 .../1003-Remove-streams-from-hot-code.patch | 0 ...der-Remove-Streams-Optimized-collect.patch | 0 ...lementation-for-blockstate-state-loo.patch | 0 ...y-type-tags-suggestions-in-selectors.patch | 0 ...e-Oversized-block-entities-in-chunks.patch | 0 .../1008-API-for-checking-sent-chunks.patch | 0 ...heck-distance-in-entity-interactions.patch | 0 .../1010-Configurable-Sand-Duping.patch | 0 .../1011-Optimise-general-POI-access.patch | 0 ...2-Improve-performance-of-mass-crafts.patch | 0 .../1013-Properly-resend-entities.patch | 0 .../1014-Registry-Modification-API.patch | 0 ...1015-Add-registry-entry-and-builders.patch | 0 .../1016-Improved-Watchdog-Support.patch | 0 ...17-Proxy-ItemStack-to-CraftItemStack.patch | 0 ...w-accessible-directly-from-ItemStack.patch | 0 ...raft-commands-in-function-parsing-an.patch | 0 ...020-optimize-dirt-and-snow-spreading.patch | 0 .../1021-Fix-NPE-for-Jukebox-setRecord.patch | 0 ...1022-Fix-CraftWorld-isChunkGenerated.patch | 0 .../1023-fix-horse-inventories.patch | 0 ...tityDamageEvents-before-actuallyHurt.patch | 0 ...er-desync-when-new-players-are-added.patch | 0 .../1026-Lag-compensation-ticks.patch | 0 ...l-more-information-in-watchdog-dumps.patch | 0 .../1028-Write-SavedData-IO-async.patch | 0 .../1029-Add-ItemType-getItemRarity.patch | 0 ...-Incremental-chunk-and-player-saving.patch | 0 ...culate-regionfile-header-if-it-is-co.patch | 0 .../{ => server}/1032-Bundle-spark.patch | 0 .../1033-Add-plugin-info-at-startup.patch | 0 ...ction-leniency-distance-configurable.patch | 0 .../1035-Fix-PickupStatus-getting-reset.patch | 0 ...type-in-SculkSensorBlock-canActivate.patch | 0 ...CanPlaceOn-and-CanDestroy-NBT-values.patch | 0 ...ion-for-horizontal-only-item-merging.patch | 0 ...on-checking-in-player-move-packet-ha.patch | 0 ...1040-Add-skipping-world-symlink-scan.patch | 0 .../1041-Add-even-more-Enchantment-API.patch | 0 .../{ => server}/1042-Leashable-API.patch | 0 .../1043-Fix-CraftBukkit-drag-system.patch | 0 ...vent-firing-for-block-entity-loading.patch | 0 ...e-lootable-item-function-from-compas.patch | 0 ...oy-placed-blocks-on-the-end-platform.patch | 0 ...1047-Add-enchantment-seed-update-API.patch | 0 ...sending-chat-to-client-with-updating.patch | 0 ...-Fix-InventoryOpenEvent-cancellation.patch | 0 ...Fire-BlockExpEvent-on-grindstone-use.patch | 0 .../1051-Check-dead-flag-in-isAlive.patch | 0 .../1052-Add-FeatureFlag-API.patch | 0 .../1053-Tag-Lifecycle-Events.patch | 0 .../1054-Item-serialization-as-json.patch | 0 ...date-slot-in-PlayerInventory-setSlot.patch | 0 ...all-time-unused-skip-tick-protection.patch | 0 ...etty-printing-for-advancement-saving.patch | 0 ...ndPreprocessEvent-on-signed-commands.patch | 0 ...Levels-with-enchantment-registry-set.patch | 0 .../1060-Improve-entity-effect-API.patch | 0 .../1061-Add-recipeBrewTime.patch | 0 ...062-Call-bucket-events-for-cauldrons.patch | 0 ...063-Add-PlayerInsertLecternBookEvent.patch | 0 .../1064-Void-damage-configuration-API.patch | 0 .../1065-Add-Offline-PDC-API.patch | 0 ...ew-bypassEnchantmentLevelRestriction.patch | 0 ...d-proper-async-player-disconnections.patch | 0 ...s-send-Banner-patterns-to-the-client.patch | 0 ...999-Optimise-nearby-player-retrieval.patch | 0 todo.txt | 1 + 1071 files changed, 729 insertions(+), 651 deletions(-) rename patches/{unapplied => server}/0002-Remap-fixes.patch (95%) rename patches/{unapplied => server}/0003-Build-system-changes.patch (95%) rename patches/{unapplied => server}/0004-Test-changes.patch (89%) rename patches/{unapplied => server}/0005-Paper-config-files.patch (98%) rename patches/{unapplied => server}/0006-MC-Dev-fixes.patch (85%) rename patches/{unapplied => server}/0007-ConcurrentUtil.patch (100%) rename patches/{unapplied => server}/0008-CB-fixes.patch (92%) rename patches/{unapplied => server}/0009-MC-Utils.patch (95%) rename patches/{unapplied => server}/0010-Adventure.patch (97%) rename patches/{unapplied => server}/0011-Use-TerminalConsoleAppender-for-console-improvements.patch (96%) rename patches/{unapplied => server}/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch (97%) rename patches/{unapplied => server}/0013-Improve-Log4J-Configuration-Plugin-Loggers.patch (100%) rename patches/{unapplied => server}/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch (89%) rename patches/{unapplied => server}/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch (98%) rename patches/{unapplied => server}/0016-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch (100%) rename patches/{unapplied => server}/0017-Paper-command.patch (98%) rename patches/{unapplied => server}/0018-Paper-Metrics.patch (99%) rename patches/{unapplied => server}/0019-Paper-Plugins.patch (99%) rename patches/{unapplied => server}/0020-Plugin-remapping.patch (99%) rename patches/{unapplied => server}/0021-Hook-into-CB-plugin-rewrites.patch (100%) rename patches/{unapplied => server}/0022-Remap-reflection-calls-in-plugins-using-internals.patch (98%) rename patches/{unapplied => server}/0023-Timings-v2.patch (87%) rename patches/{unapplied => server}/0024-Further-improve-server-tick-loop.patch (94%) rename patches/{unapplied => server}/0025-Add-command-line-option-to-load-extra-plugin-jars-no.patch (92%) rename patches/{unapplied => server}/0026-Support-components-in-ItemMeta.patch (89%) rename patches/{unapplied => server}/0027-Configurable-cactus-bamboo-and-reed-growth-height.patch (89%) rename patches/{unapplied => server}/0028-Configurable-baby-zombie-movement-speed.patch (91%) rename patches/{unapplied => server}/0029-Configurable-fishing-time-ranges.patch (83%) rename patches/{unapplied => server}/0030-Allow-nerfed-mobs-to-jump.patch (87%) rename patches/unapplied/{ => server}/0031-Add-configurable-entity-despawn-distances.patch (100%) rename patches/unapplied/{ => server}/0032-Drop-falling-block-and-tnt-entities-at-the-specified.patch (100%) rename patches/unapplied/{ => server}/0033-Expose-server-build-information.patch (100%) rename patches/unapplied/{ => server}/0034-Player-affects-spawning-API.patch (100%) rename patches/unapplied/{ => server}/0035-Only-refresh-abilities-if-needed.patch (100%) rename patches/unapplied/{ => server}/0036-Entity-Origin-API.patch (100%) rename patches/unapplied/{ => server}/0037-Prevent-block-entity-and-entity-crashes.patch (100%) rename patches/unapplied/{ => server}/0038-Configurable-top-of-nether-void-damage.patch (100%) rename patches/unapplied/{ => server}/0039-Check-online-mode-before-converting-and-renaming-pla.patch (100%) rename patches/unapplied/{ => server}/0040-Add-more-entities-to-activation-range-ignore-list.patch (100%) rename patches/unapplied/{ => server}/0041-Configurable-end-credits.patch (100%) rename patches/unapplied/{ => server}/0042-Fix-lag-from-explosions-processing-dead-entities.patch (100%) rename patches/unapplied/{ => server}/0043-Optimize-explosions.patch (100%) rename patches/unapplied/{ => server}/0044-Disable-explosion-knockback.patch (100%) rename patches/unapplied/{ => server}/0045-Disable-thunder.patch (100%) rename patches/unapplied/{ => server}/0046-Disable-ice-and-snow.patch (100%) rename patches/unapplied/{ => server}/0047-Configurable-mob-spawner-tick-rate.patch (100%) rename patches/unapplied/{ => server}/0048-Use-null-Locale-by-default.patch (100%) rename patches/unapplied/{ => server}/0049-Add-BeaconEffectEvent.patch (100%) rename patches/unapplied/{ => server}/0050-Configurable-container-update-tick-rate.patch (100%) rename patches/unapplied/{ => server}/0051-Use-UserCache-for-player-heads.patch (100%) rename patches/unapplied/{ => server}/0052-Disable-spigot-tick-limiters.patch (100%) rename patches/unapplied/{ => server}/0053-Fix-spawn-location-event-changing-location.patch (100%) rename patches/unapplied/{ => server}/0054-Configurable-Disabling-Cat-Chest-Detection.patch (100%) rename patches/unapplied/{ => server}/0055-Improve-Player-chat-API-handling.patch (100%) rename patches/unapplied/{ => server}/0056-All-chunks-are-slime-spawn-chunks-toggle.patch (100%) rename patches/unapplied/{ => server}/0057-Expose-server-CommandMap.patch (100%) rename patches/unapplied/{ => server}/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch (100%) rename patches/unapplied/{ => server}/0059-Player-Tab-List-and-Title-APIs.patch (100%) rename patches/unapplied/{ => server}/0060-Add-configurable-portal-search-radius.patch (100%) rename patches/unapplied/{ => server}/0061-Add-velocity-warnings.patch (100%) rename patches/unapplied/{ => server}/0062-Add-exception-reporting-event.patch (100%) rename patches/unapplied/{ => server}/0063-Disable-Scoreboards-for-non-players-by-default.patch (100%) rename patches/unapplied/{ => server}/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch (100%) rename patches/unapplied/{ => server}/0065-Chunk-Save-Reattempt.patch (100%) rename patches/unapplied/{ => server}/0066-Complete-resource-pack-API.patch (100%) rename patches/unapplied/{ => server}/0067-Default-loading-permissions.yml-before-plugins.patch (100%) rename patches/unapplied/{ => server}/0068-Allow-Reloading-of-Custom-Permissions.patch (100%) rename patches/unapplied/{ => server}/0069-Remove-Metadata-on-reload.patch (100%) rename patches/unapplied/{ => server}/0070-Handle-Item-Meta-Inconsistencies.patch (100%) rename patches/unapplied/{ => server}/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch (100%) rename patches/unapplied/{ => server}/0072-Add-World-Util-Methods.patch (100%) rename patches/unapplied/{ => server}/0073-Custom-replacement-for-eaten-items.patch (100%) rename patches/unapplied/{ => server}/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch (100%) rename patches/unapplied/{ => server}/0075-Use-a-Shared-Random-for-Entities.patch (100%) rename patches/unapplied/{ => server}/0076-Configurable-spawn-chances-for-skeleton-horses.patch (100%) rename patches/unapplied/{ => server}/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch (100%) rename patches/unapplied/{ => server}/0078-Entity-AddTo-RemoveFrom-World-Events.patch (100%) rename patches/unapplied/{ => server}/0079-Configurable-Chunk-Inhabited-Time.patch (100%) rename patches/unapplied/{ => server}/0080-EntityPathfindEvent.patch (100%) rename patches/unapplied/{ => server}/0081-Sanitise-RegionFileCache-and-make-configurable.patch (100%) rename patches/unapplied/{ => server}/0082-Do-not-load-chunks-for-Pathfinding.patch (100%) rename patches/unapplied/{ => server}/0083-Add-PlayerUseUnknownEntityEvent.patch (100%) rename patches/unapplied/{ => server}/0084-Configurable-random-tick-rates-for-blocks.patch (100%) rename patches/unapplied/{ => server}/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch (100%) rename patches/unapplied/{ => server}/0086-Optimize-DataBits.patch (100%) rename patches/unapplied/{ => server}/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch (100%) rename patches/unapplied/{ => server}/0088-Configurable-Player-Collision.patch (100%) rename patches/unapplied/{ => server}/0089-Add-handshake-event-to-allow-plugins-to-handle-clien.patch (100%) rename patches/unapplied/{ => server}/0090-Configurable-RCON-IP-address.patch (100%) rename patches/unapplied/{ => server}/0091-EntityRegainHealthEvent-isFastRegen-API.patch (100%) rename patches/unapplied/{ => server}/0092-Add-ability-to-configure-frosted_ice-properties.patch (100%) rename patches/unapplied/{ => server}/0093-remove-null-possibility-for-getServer-singleton.patch (100%) rename patches/unapplied/{ => server}/0094-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch (100%) rename patches/unapplied/{ => server}/0095-LootTable-API-and-replenishable-lootables.patch (100%) rename patches/unapplied/{ => server}/0096-System-property-for-disabling-watchdoge.patch (100%) rename patches/unapplied/{ => server}/0097-Async-GameProfileCache-saving.patch (100%) rename patches/unapplied/{ => server}/0098-Optional-TNT-doesn-t-move-in-water.patch (100%) rename patches/unapplied/{ => server}/0099-Faster-redstone-torch-rapid-clock-removal.patch (100%) rename patches/unapplied/{ => server}/0100-Add-server-name-parameter.patch (100%) rename patches/unapplied/{ => server}/0101-Fix-global-sound-handling.patch (100%) rename patches/unapplied/{ => server}/0102-Avoid-blocking-on-Network-Manager-creation.patch (100%) rename patches/unapplied/{ => server}/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch (100%) rename patches/unapplied/{ => server}/0104-Add-setting-for-proxy-online-mode-status.patch (100%) rename patches/unapplied/{ => server}/0105-Optimise-BlockState-s-hashCode-equals.patch (100%) rename patches/unapplied/{ => server}/0106-Configurable-packet-in-spam-threshold.patch (100%) rename patches/unapplied/{ => server}/0107-Configurable-flying-kick-messages.patch (100%) rename patches/unapplied/{ => server}/0108-Add-EntityZapEvent.patch (100%) rename patches/unapplied/{ => server}/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch (100%) rename patches/unapplied/{ => server}/0110-Cache-user-authenticator-threads.patch (100%) rename patches/unapplied/{ => server}/0111-Allow-Reloading-of-Command-Aliases.patch (100%) rename patches/unapplied/{ => server}/0112-Add-source-to-PlayerExpChangeEvent.patch (100%) rename patches/unapplied/{ => server}/0113-Add-ProjectileCollideEvent.patch (100%) rename patches/unapplied/{ => server}/0114-Prevent-Pathfinding-out-of-World-Border.patch (100%) rename patches/unapplied/{ => server}/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch (100%) rename patches/unapplied/{ => server}/0116-Bound-Treasure-Maps-to-World-Border.patch (100%) rename patches/unapplied/{ => server}/0117-Configurable-Cartographer-Treasure-Maps.patch (100%) rename patches/unapplied/{ => server}/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch (100%) rename patches/unapplied/{ => server}/0119-String-based-Action-Bar-API.patch (100%) rename patches/unapplied/{ => server}/0120-Properly-fix-item-duplication-bug.patch (100%) rename patches/unapplied/{ => server}/0121-Firework-API-s.patch (100%) rename patches/unapplied/{ => server}/0122-PlayerTeleportEndGatewayEvent.patch (100%) rename patches/unapplied/{ => server}/0123-Provide-E-TE-Chunk-count-stat-methods.patch (100%) rename patches/unapplied/{ => server}/0124-Enforce-Sync-Player-Saves.patch (100%) rename patches/unapplied/{ => server}/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch (100%) rename patches/unapplied/{ => server}/0126-Cap-Entity-Collisions.patch (100%) rename patches/unapplied/{ => server}/0127-Remove-CraftScheduler-Async-Task-Debugger.patch (100%) rename patches/unapplied/{ => server}/0128-Properly-handle-async-calls-to-restart-the-server.patch (100%) rename patches/unapplied/{ => server}/0129-Add-option-to-make-parrots-stay-on-shoulders-despite.patch (100%) rename patches/unapplied/{ => server}/0130-Add-configuration-option-to-prevent-player-names-fro.patch (100%) rename patches/unapplied/{ => server}/0131-provide-a-configurable-option-to-disable-creeper-lin.patch (100%) rename patches/unapplied/{ => server}/0132-Item-canEntityPickup.patch (100%) rename patches/unapplied/{ => server}/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch (100%) rename patches/unapplied/{ => server}/0134-PlayerAttemptPickupItemEvent.patch (100%) rename patches/unapplied/{ => server}/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch (100%) rename patches/unapplied/{ => server}/0136-Basic-PlayerProfile-API.patch (100%) rename patches/unapplied/{ => server}/0137-Add-UnknownCommandEvent.patch (100%) rename patches/unapplied/{ => server}/0138-Shoulder-Entities-Release-API.patch (100%) rename patches/unapplied/{ => server}/0139-Profile-Lookup-Events.patch (100%) rename patches/unapplied/{ => server}/0140-Block-player-logins-during-server-shutdown.patch (100%) rename patches/unapplied/{ => server}/0141-Entity-fromMobSpawner.patch (100%) rename patches/unapplied/{ => server}/0142-Improve-the-Saddle-API-for-Horses.patch (100%) rename patches/unapplied/{ => server}/0143-ensureServerConversions-API.patch (100%) rename patches/unapplied/{ => server}/0144-Implement-getI18NDisplayName.patch (100%) rename patches/unapplied/{ => server}/0145-ProfileWhitelistVerifyEvent.patch (100%) rename patches/unapplied/{ => server}/0146-Fix-this-stupid-bullshit.patch (100%) rename patches/unapplied/{ => server}/0147-LivingEntity-setKiller.patch (100%) rename patches/unapplied/{ => server}/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch (100%) rename patches/unapplied/{ => server}/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch (100%) rename patches/unapplied/{ => server}/0150-Allow-specifying-a-custom-authentication-servers-dow.patch (100%) rename patches/unapplied/{ => server}/0151-Add-PlayerJumpEvent.patch (100%) rename patches/unapplied/{ => server}/0152-handle-ServerboundKeepAlivePacket-async.patch (100%) rename patches/unapplied/{ => server}/0153-Expose-client-protocol-version-and-virtual-host.patch (100%) rename patches/unapplied/{ => server}/0154-revert-serverside-behavior-of-keepalives.patch (100%) rename patches/unapplied/{ => server}/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch (100%) rename patches/unapplied/{ => server}/0156-Add-PlayerArmorChangeEvent.patch (100%) rename patches/unapplied/{ => server}/0157-Prevent-logins-from-being-processed-when-the-player-.patch (100%) rename patches/unapplied/{ => server}/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch (100%) rename patches/unapplied/{ => server}/0159-use-CB-BlockState-implementations-for-captured-block.patch (100%) rename patches/unapplied/{ => server}/0160-API-to-get-a-BlockState-without-a-snapshot.patch (100%) rename patches/unapplied/{ => server}/0161-AsyncTabCompleteEvent.patch (100%) rename patches/unapplied/{ => server}/0162-PlayerPickupExperienceEvent.patch (100%) rename patches/unapplied/{ => server}/0163-Ability-to-apply-mending-to-XP-API.patch (100%) rename patches/unapplied/{ => server}/0164-PlayerNaturallySpawnCreaturesEvent.patch (100%) rename patches/unapplied/{ => server}/0165-Add-setPlayerProfile-API-for-Skulls.patch (100%) rename patches/unapplied/{ => server}/0166-PreCreatureSpawnEvent.patch (100%) rename patches/unapplied/{ => server}/0167-Fill-Profile-Property-Events.patch (100%) rename patches/unapplied/{ => server}/0168-Add-PlayerAdvancementCriterionGrantEvent.patch (100%) rename patches/unapplied/{ => server}/0169-Add-ArmorStand-Item-Meta.patch (100%) rename patches/unapplied/{ => server}/0170-Extend-Player-Interact-cancellation.patch (100%) rename patches/unapplied/{ => server}/0171-Tameable-getOwnerUniqueId-API.patch (100%) rename patches/unapplied/{ => server}/0172-Toggleable-player-crits.patch (100%) rename patches/unapplied/{ => server}/0173-Disable-Explicit-Network-Manager-Flushing.patch (100%) rename patches/unapplied/{ => server}/0174-Implement-extended-PaperServerListPingEvent.patch (100%) rename patches/unapplied/{ => server}/0175-Add-more-fields-to-AsyncPreLoginEvent.patch (100%) rename patches/unapplied/{ => server}/0176-Player.setPlayerProfile-API.patch (100%) rename patches/unapplied/{ => server}/0177-getPlayerUniqueId-API.patch (100%) rename patches/unapplied/{ => server}/0178-Improved-Async-Task-Scheduler.patch (100%) rename patches/unapplied/{ => server}/0179-Make-legacy-ping-handler-more-reliable.patch (100%) rename patches/unapplied/{ => server}/0180-Call-PaperServerListPingEvent-for-legacy-pings.patch (100%) rename patches/unapplied/{ => server}/0181-Flag-to-disable-the-channel-limit.patch (100%) rename patches/unapplied/{ => server}/0182-Add-openSign-method-to-HumanEntity.patch (100%) rename patches/unapplied/{ => server}/0183-Configurable-sprint-interruption-on-attack.patch (100%) rename patches/unapplied/{ => server}/0184-EndermanEscapeEvent.patch (100%) rename patches/unapplied/{ => server}/0185-Enderman.teleportRandomly.patch (100%) rename patches/unapplied/{ => server}/0186-Block-Enderpearl-Travel-Exploit.patch (100%) rename patches/unapplied/{ => server}/0187-Expand-World.spawnParticle-API-and-add-Builder.patch (100%) rename patches/unapplied/{ => server}/0188-Fix-exploit-that-allowed-colored-signs-to-be-created.patch (100%) rename patches/unapplied/{ => server}/0189-EndermanAttackPlayerEvent.patch (100%) rename patches/unapplied/{ => server}/0190-WitchConsumePotionEvent.patch (100%) rename patches/unapplied/{ => server}/0191-WitchThrowPotionEvent.patch (100%) rename patches/unapplied/{ => server}/0192-WitchReadyPotionEvent.patch (100%) rename patches/unapplied/{ => server}/0193-ItemStack-getMaxItemUseDuration.patch (100%) rename patches/unapplied/{ => server}/0194-Add-EntityTeleportEndGatewayEvent.patch (100%) rename patches/unapplied/{ => server}/0195-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch (100%) rename patches/unapplied/{ => server}/0196-Fix-CraftEntity-hashCode.patch (100%) rename patches/unapplied/{ => server}/0197-Configurable-LootPool-luck-formula.patch (100%) rename patches/unapplied/{ => server}/0198-Print-Error-details-when-failing-to-save-player-data.patch (100%) rename patches/unapplied/{ => server}/0199-Make-shield-blocking-delay-configurable.patch (100%) rename patches/unapplied/{ => server}/0200-Improve-EntityShootBowEvent.patch (100%) rename patches/unapplied/{ => server}/0201-PlayerReadyArrowEvent.patch (100%) rename patches/unapplied/{ => server}/0202-Add-entity-knockback-events.patch (100%) rename patches/unapplied/{ => server}/0203-Expand-Explosions-API.patch (100%) rename patches/unapplied/{ => server}/0204-LivingEntity-Active-Item-API.patch (100%) rename patches/unapplied/{ => server}/0205-RangedEntity-API.patch (100%) rename patches/unapplied/{ => server}/0206-Add-config-to-disable-ender-dragon-legacy-check.patch (100%) rename patches/unapplied/{ => server}/0207-Implement-World.getEntity-UUID-API.patch (100%) rename patches/unapplied/{ => server}/0208-InventoryCloseEvent-Reason-API.patch (100%) rename patches/unapplied/{ => server}/0209-Vex-get-setSummoner-API.patch (100%) rename patches/unapplied/{ => server}/0210-add-more-information-to-Entity.toString.patch (100%) rename patches/unapplied/{ => server}/0211-EnderDragon-Events.patch (100%) rename patches/unapplied/{ => server}/0212-PlayerElytraBoostEvent.patch (100%) rename patches/unapplied/{ => server}/0213-PlayerLaunchProjectileEvent.patch (100%) rename patches/unapplied/{ => server}/0214-Improve-BlockPosition-inlining.patch (100%) rename patches/unapplied/{ => server}/0215-Option-to-prevent-armor-stands-from-doing-entity-loo.patch (100%) rename patches/unapplied/{ => server}/0216-Vanished-players-don-t-have-rights.patch (100%) rename patches/unapplied/{ => server}/0217-Allow-disabling-armor-stand-ticking.patch (100%) rename patches/unapplied/{ => server}/0218-SkeletonHorse-Additions.patch (100%) rename patches/unapplied/{ => server}/0219-Expand-ArmorStand-API.patch (100%) rename patches/unapplied/{ => server}/0220-AnvilDamageEvent.patch (100%) rename patches/unapplied/{ => server}/0221-Add-TNTPrimeEvent.patch (100%) rename patches/unapplied/{ => server}/0222-Break-up-and-make-tab-spam-limits-configurable.patch (100%) rename patches/unapplied/{ => server}/0223-Fix-NBT-type-issues.patch (100%) rename patches/unapplied/{ => server}/0224-Remove-unnecessary-itemmeta-handling.patch (100%) rename patches/unapplied/{ => server}/0225-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch (100%) rename patches/unapplied/{ => server}/0226-Add-Early-Warning-Feature-to-WatchDog.patch (100%) rename patches/unapplied/{ => server}/0227-Use-ConcurrentHashMap-in-JsonList.patch (100%) rename patches/unapplied/{ => server}/0228-Use-a-Queue-for-Queueing-Commands.patch (100%) rename patches/unapplied/{ => server}/0229-Ability-to-get-block-entities-from-a-chunk-without-s.patch (100%) rename patches/unapplied/{ => server}/0230-Optimize-BlockPosition-helper-methods.patch (100%) rename patches/unapplied/{ => server}/0231-Restore-vanilla-default-mob-spawn-range-and-water-an.patch (100%) rename patches/unapplied/{ => server}/0232-Slime-Pathfinder-Events.patch (100%) rename patches/unapplied/{ => server}/0233-Configurable-speed-for-water-flowing-over-lava.patch (100%) rename patches/unapplied/{ => server}/0234-Optimize-CraftBlockData-Creation.patch (100%) rename patches/unapplied/{ => server}/0235-Optimize-MappedRegistry.patch (100%) rename patches/unapplied/{ => server}/0236-Add-PhantomPreSpawnEvent.patch (100%) rename patches/unapplied/{ => server}/0237-Add-More-Creeper-API.patch (100%) rename patches/unapplied/{ => server}/0238-Inventory-removeItemAnySlot.patch (100%) rename patches/unapplied/{ => server}/0239-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch (100%) rename patches/unapplied/{ => server}/0240-Add-ray-tracing-methods-to-LivingEntity.patch (100%) rename patches/unapplied/{ => server}/0241-Expose-attack-cooldown-methods-for-Player.patch (100%) rename patches/unapplied/{ => server}/0242-Improve-death-events.patch (100%) rename patches/unapplied/{ => server}/0243-Allow-chests-to-be-placed-with-NBT-data.patch (100%) rename patches/unapplied/{ => server}/0244-Mob-Pathfinding-API.patch (100%) rename patches/unapplied/{ => server}/0245-Prevent-various-interactions-from-causing-chunk-load.patch (100%) rename patches/unapplied/{ => server}/0246-Prevent-mob-spawning-from-loading-generating-chunks.patch (100%) rename patches/unapplied/{ => server}/0247-Implement-furnace-cook-speed-multiplier-API.patch (100%) rename patches/unapplied/{ => server}/0248-Honor-EntityAgeable.ageLock.patch (100%) rename patches/unapplied/{ => server}/0249-Configurable-connection-throttle-kick-message.patch (100%) rename patches/unapplied/{ => server}/0250-Prevent-chunk-loading-from-Fluid-Flowing.patch (100%) rename patches/unapplied/{ => server}/0251-PreSpawnerSpawnEvent.patch (100%) rename patches/unapplied/{ => server}/0252-Add-LivingEntity-getTargetEntity.patch (100%) rename patches/unapplied/{ => server}/0253-Add-sun-related-API.patch (100%) rename patches/unapplied/{ => server}/0254-Turtle-API.patch (100%) rename patches/unapplied/{ => server}/0255-Call-player-spectator-target-events-and-improve-impl.patch (100%) rename patches/unapplied/{ => server}/0256-Add-more-Witch-API.patch (100%) rename patches/unapplied/{ => server}/0257-Check-Drowned-for-Villager-Aggression-Config.patch (100%) rename patches/unapplied/{ => server}/0258-Add-option-to-prevent-players-from-moving-into-unloa.patch (100%) rename patches/unapplied/{ => server}/0259-Reset-players-airTicks-on-respawn.patch (100%) rename patches/unapplied/{ => server}/0260-Don-t-sleep-after-profile-lookups-if-not-needed.patch (100%) rename patches/unapplied/{ => server}/0261-Improve-Server-Thread-Pool-and-Thread-Priorities.patch (100%) rename patches/unapplied/{ => server}/0262-Optimize-World-Time-Updates.patch (100%) rename patches/unapplied/{ => server}/0263-Restore-custom-InventoryHolder-support.patch (100%) rename patches/unapplied/{ => server}/0264-Fix-SpongeAbsortEvent-handling.patch (100%) rename patches/unapplied/{ => server}/0265-Don-t-allow-digging-into-unloaded-chunks.patch (100%) rename patches/unapplied/{ => server}/0266-Make-the-default-permission-message-configurable.patch (100%) rename patches/unapplied/{ => server}/0267-force-entity-dismount-during-teleportation.patch (100%) rename patches/unapplied/{ => server}/0268-Add-more-Zombie-API.patch (100%) rename patches/unapplied/{ => server}/0269-Book-size-limits.patch (100%) rename patches/unapplied/{ => server}/0270-Add-PlayerConnectionCloseEvent.patch (100%) rename patches/unapplied/{ => server}/0271-Replace-OfflinePlayer-getLastPlayed.patch (100%) rename patches/unapplied/{ => server}/0272-Workaround-for-vehicle-tracking-issue-on-disconnect.patch (100%) rename patches/unapplied/{ => server}/0273-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch (100%) rename patches/unapplied/{ => server}/0274-BlockDestroyEvent.patch (100%) rename patches/unapplied/{ => server}/0275-Async-command-map-building.patch (100%) rename patches/unapplied/{ => server}/0276-Brigadier-Mojang-API.patch (100%) rename patches/unapplied/{ => server}/0277-Improve-exact-choice-recipe-ingredients.patch (100%) rename patches/unapplied/{ => server}/0278-Limit-Client-Sign-length-more.patch (100%) rename patches/unapplied/{ => server}/0279-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch (100%) rename patches/unapplied/{ => server}/0280-Fixes-and-additions-to-the-spawn-reason-API.patch (100%) rename patches/unapplied/{ => server}/0281-Fire-event-on-GS4-query.patch (100%) rename patches/unapplied/{ => server}/0282-Add-PlayerPostRespawnEvent.patch (100%) rename patches/unapplied/{ => server}/0283-Server-Tick-Events.patch (100%) rename patches/unapplied/{ => server}/0284-PlayerDeathEvent-getItemsToKeep.patch (100%) rename patches/unapplied/{ => server}/0285-Optimize-Captured-BlockEntity-Lookup.patch (100%) rename patches/unapplied/{ => server}/0286-Mob-Spawner-API-Enhancements.patch (100%) rename patches/unapplied/{ => server}/0287-Fix-CB-call-to-changed-postToMainThread-method.patch (100%) rename patches/unapplied/{ => server}/0288-Fix-sounds-when-item-frames-are-modified-MC-123450.patch (100%) rename patches/unapplied/{ => server}/0289-Implement-CraftBlockSoundGroup.patch (100%) rename patches/unapplied/{ => server}/0290-Expose-the-internal-current-tick.patch (100%) rename patches/unapplied/{ => server}/0291-Show-blockstate-location-if-we-failed-to-read-it.patch (100%) rename patches/unapplied/{ => server}/0292-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch (100%) rename patches/unapplied/{ => server}/0293-Configurable-projectile-relative-velocity.patch (100%) rename patches/unapplied/{ => server}/0294-offset-item-frame-ticking.patch (100%) rename patches/unapplied/{ => server}/0295-Prevent-consuming-the-wrong-itemstack.patch (100%) rename patches/unapplied/{ => server}/0296-Dont-send-unnecessary-sign-update.patch (100%) rename patches/unapplied/{ => server}/0297-Add-option-to-disable-pillager-patrols.patch (100%) rename patches/unapplied/{ => server}/0298-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch (100%) rename patches/unapplied/{ => server}/0299-MC-145656-Fix-Follow-Range-Initial-Target.patch (100%) rename patches/unapplied/{ => server}/0300-Duplicate-UUID-Resolve-Option.patch (100%) rename patches/unapplied/{ => server}/0301-PlayerDeathEvent-shouldDropExperience.patch (100%) rename patches/unapplied/{ => server}/0302-Prevent-bees-loading-chunks-checking-hive-position.patch (100%) rename patches/unapplied/{ => server}/0303-Don-t-load-Chunks-from-Hoppers-and-other-things.patch (100%) rename patches/unapplied/{ => server}/0304-Optimise-EntityGetter-getPlayerByUUID.patch (100%) rename patches/unapplied/{ => server}/0305-Fix-items-not-falling-correctly.patch (100%) rename patches/unapplied/{ => server}/0306-Optimize-call-to-getFluid-for-explosions.patch (100%) rename patches/unapplied/{ => server}/0307-Guard-against-serializing-mismatching-chunk-coordina.patch (100%) rename patches/unapplied/{ => server}/0308-Alternative-item-despawn-rate.patch (100%) rename patches/unapplied/{ => server}/0309-Tracking-Range-Improvements.patch (100%) rename patches/unapplied/{ => server}/0310-Bees-get-gravity-in-void.-Fixes-MC-167279.patch (100%) rename patches/unapplied/{ => server}/0311-Improve-Block-breakNaturally-API.patch (100%) rename patches/unapplied/{ => server}/0312-Optimise-getChunkAt-calls-for-loaded-chunks.patch (100%) rename patches/unapplied/{ => server}/0313-Add-debug-for-sync-chunk-loads.patch (100%) rename patches/unapplied/{ => server}/0314-Improve-java-version-check.patch (100%) rename patches/unapplied/{ => server}/0315-Add-ThrownEggHatchEvent.patch (100%) rename patches/unapplied/{ => server}/0316-Entity-Jump-API.patch (100%) rename patches/unapplied/{ => server}/0317-Add-option-to-nerf-pigmen-from-nether-portals.patch (100%) rename patches/unapplied/{ => server}/0318-Make-the-GUI-graph-fancier.patch (100%) rename patches/unapplied/{ => server}/0319-add-hand-to-BlockMultiPlaceEvent.patch (100%) rename patches/unapplied/{ => server}/0320-Validate-tripwire-hook-placement-before-update.patch (100%) rename patches/unapplied/{ => server}/0321-Add-option-to-allow-iron-golems-to-spawn-in-air.patch (100%) rename patches/unapplied/{ => server}/0322-Configurable-chance-of-villager-zombie-infection.patch (100%) rename patches/unapplied/{ => server}/0323-Optimise-Chunk-getFluid.patch (100%) rename patches/unapplied/{ => server}/0324-Set-spigots-verbose-world-setting-to-false-by-def.patch (100%) rename patches/unapplied/{ => server}/0325-Add-tick-times-API-and-mspt-command.patch (100%) rename patches/unapplied/{ => server}/0326-Expose-MinecraftServer-isRunning.patch (100%) rename patches/unapplied/{ => server}/0327-Add-Raw-Byte-ItemStack-Serialization.patch (100%) rename patches/unapplied/{ => server}/0328-Pillager-patrol-spawn-settings-and-per-player-option.patch (100%) rename patches/unapplied/{ => server}/0329-Remote-Connections-shouldn-t-hold-up-shutdown.patch (100%) rename patches/unapplied/{ => server}/0330-Do-not-allow-bees-to-load-chunks-for-beehives.patch (100%) rename patches/unapplied/{ => server}/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch (100%) rename patches/unapplied/{ => server}/0332-Don-t-tick-dead-players.patch (100%) rename patches/unapplied/{ => server}/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch (100%) rename patches/unapplied/{ => server}/0334-Don-t-move-existing-players-to-world-spawn.patch (100%) rename patches/unapplied/{ => server}/0335-Optimize-Pathfinding.patch (100%) rename patches/unapplied/{ => server}/0336-Reduce-Either-Optional-allocation.patch (100%) rename patches/unapplied/{ => server}/0337-Reduce-memory-footprint-of-CompoundTag.patch (100%) rename patches/unapplied/{ => server}/0338-Prevent-opening-inventories-when-frozen.patch (100%) rename patches/unapplied/{ => server}/0339-Don-t-run-entity-collision-code-if-not-needed.patch (100%) rename patches/unapplied/{ => server}/0340-Implement-Player-Client-Options-API.patch (100%) rename patches/unapplied/{ => server}/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch (100%) rename patches/unapplied/{ => server}/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch (100%) rename patches/unapplied/{ => server}/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch (100%) rename patches/unapplied/{ => server}/0344-Add-PlayerAttackEntityCooldownResetEvent.patch (100%) rename patches/unapplied/{ => server}/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch (100%) rename patches/unapplied/{ => server}/0346-Add-phantom-creative-and-insomniac-controls.patch (100%) rename patches/unapplied/{ => server}/0347-Fix-item-duplication-and-teleport-issues.patch (100%) rename patches/unapplied/{ => server}/0348-Villager-Restocks-API.patch (100%) rename patches/unapplied/{ => server}/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch (100%) rename patches/unapplied/{ => server}/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch (100%) rename patches/unapplied/{ => server}/0351-misc-debugging-dumps.patch (100%) rename patches/unapplied/{ => server}/0352-Prevent-teleporting-dead-entities.patch (100%) rename patches/unapplied/{ => server}/0353-Implement-Mob-Goal-API.patch (100%) rename patches/unapplied/{ => server}/0354-Add-villager-reputation-API.patch (100%) rename patches/unapplied/{ => server}/0355-ExperienceOrb-merging-stacking-API-and-fixes.patch (100%) rename patches/unapplied/{ => server}/0356-Fix-PotionEffect-ignores-icon-flag.patch (100%) rename patches/unapplied/{ => server}/0357-Potential-bed-API.patch (100%) rename patches/unapplied/{ => server}/0358-Wait-for-Async-Tasks-during-shutdown.patch (100%) rename patches/unapplied/{ => server}/0359-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch (100%) rename patches/unapplied/{ => server}/0360-Add-option-for-console-having-all-permissions.patch (100%) rename patches/unapplied/{ => server}/0361-Fix-villager-trading-demand-MC-163962.patch (100%) rename patches/unapplied/{ => server}/0362-Maps-shouldn-t-load-chunks.patch (100%) rename patches/unapplied/{ => server}/0363-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch (100%) rename patches/unapplied/{ => server}/0364-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch (100%) rename patches/unapplied/{ => server}/0365-Fix-piston-physics-inconsistency-MC-188840.patch (100%) rename patches/unapplied/{ => server}/0366-Fix-missing-chunks-due-to-integer-overflow.patch (100%) rename patches/unapplied/{ => server}/0367-Prevent-position-desync-causing-tp-exploit.patch (100%) rename patches/unapplied/{ => server}/0368-Inventory-getHolder-method-without-block-snapshot.patch (100%) rename patches/unapplied/{ => server}/0369-Add-PlayerRecipeBookClickEvent.patch (100%) rename patches/unapplied/{ => server}/0370-Hide-sync-chunk-writes-behind-flag.patch (100%) rename patches/unapplied/{ => server}/0371-Add-permission-for-command-blocks.patch (100%) rename patches/unapplied/{ => server}/0372-Ensure-Entity-position-and-AABB-are-never-invalid.patch (100%) rename patches/unapplied/{ => server}/0373-Fix-Per-World-Difficulty-Remembering-Difficulty.patch (100%) rename patches/unapplied/{ => server}/0374-Paper-dumpitem-command.patch (100%) rename patches/unapplied/{ => server}/0375-Improve-Legacy-Component-serialization-size.patch (100%) rename patches/unapplied/{ => server}/0376-Add-Plugin-Tickets-to-API-Chunk-Methods.patch (100%) rename patches/unapplied/{ => server}/0377-Add-BlockStateMeta-clearBlockState.patch (100%) rename patches/unapplied/{ => server}/0378-Convert-legacy-attributes-in-Item-Meta.patch (100%) rename patches/unapplied/{ => server}/0379-Do-not-accept-invalid-client-settings.patch (100%) rename patches/unapplied/{ => server}/0380-Improve-fix-EntityTargetLivingEntityEvent.patch (100%) rename patches/unapplied/{ => server}/0381-Add-entity-liquid-API.patch (100%) rename patches/unapplied/{ => server}/0382-Add-PrepareResultEvent.patch (100%) rename patches/unapplied/{ => server}/0383-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch (100%) rename patches/unapplied/{ => server}/0384-Fix-arrows-never-despawning-MC-125757.patch (100%) rename patches/unapplied/{ => server}/0385-Thread-Safe-Vanilla-Command-permission-checking.patch (100%) rename patches/unapplied/{ => server}/0386-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch (100%) rename patches/unapplied/{ => server}/0387-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch (100%) rename patches/unapplied/{ => server}/0388-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch (100%) rename patches/unapplied/{ => server}/0389-Optimize-NetworkManager-Exception-Handling.patch (100%) rename patches/unapplied/{ => server}/0390-Fix-some-rails-connecting-improperly.patch (100%) rename patches/unapplied/{ => server}/0391-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch (100%) rename patches/unapplied/{ => server}/0392-Brand-support.patch (100%) rename patches/unapplied/{ => server}/0393-Add-playPickupItemAnimation-to-LivingEntity.patch (100%) rename patches/unapplied/{ => server}/0394-Don-t-require-FACING-data.patch (100%) rename patches/unapplied/{ => server}/0395-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch (100%) rename patches/unapplied/{ => server}/0396-Add-moon-phase-API.patch (100%) rename patches/unapplied/{ => server}/0397-Do-not-let-the-server-load-chunks-from-newer-version.patch (100%) rename patches/unapplied/{ => server}/0398-Prevent-headless-pistons-from-being-created.patch (100%) rename patches/unapplied/{ => server}/0399-Add-BellRingEvent.patch (100%) rename patches/unapplied/{ => server}/0400-Add-zombie-targets-turtle-egg-config.patch (100%) rename patches/unapplied/{ => server}/0401-Buffer-joins-to-world.patch (100%) rename patches/unapplied/{ => server}/0402-Fix-hex-colors-not-working-in-some-kick-messages.patch (100%) rename patches/unapplied/{ => server}/0403-Add-more-Evoker-API.patch (100%) rename patches/unapplied/{ => server}/0404-Add-methods-to-get-translation-keys.patch (100%) rename patches/unapplied/{ => server}/0405-Create-HoverEvent-from-ItemStack-Entity.patch (100%) rename patches/unapplied/{ => server}/0406-Cache-block-data-strings.patch (100%) rename patches/unapplied/{ => server}/0407-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch (100%) rename patches/unapplied/{ => server}/0408-Add-additional-open-container-api-to-HumanEntity.patch (100%) rename patches/unapplied/{ => server}/0409-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch (100%) rename patches/unapplied/{ => server}/0410-Extend-block-drop-capture-to-capture-all-items-added.patch (100%) rename patches/unapplied/{ => server}/0411-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch (100%) rename patches/unapplied/{ => server}/0412-Lazily-track-plugin-scoreboards-by-default.patch (100%) rename patches/unapplied/{ => server}/0413-Entity-isTicking.patch (100%) rename patches/unapplied/{ => server}/0414-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch (100%) rename patches/unapplied/{ => server}/0415-Fix-Concurrency-issue-in-ShufflingList.patch (100%) rename patches/unapplied/{ => server}/0416-Reset-Ender-Crystals-on-Dragon-Spawn.patch (100%) rename patches/unapplied/{ => server}/0417-Fix-for-large-move-vectors-crashing-server.patch (100%) rename patches/unapplied/{ => server}/0418-Optimise-getType-calls.patch (100%) rename patches/unapplied/{ => server}/0419-Villager-resetOffers.patch (100%) rename patches/unapplied/{ => server}/0420-Retain-block-place-order-when-capturing-blockstates.patch (100%) rename patches/unapplied/{ => server}/0421-Fix-item-locations-dropped-from-campfires.patch (100%) rename patches/unapplied/{ => server}/0422-Fix-bell-block-entity-memory-leak.patch (100%) rename patches/unapplied/{ => server}/0423-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch (100%) rename patches/unapplied/{ => server}/0424-Add-getOfflinePlayerIfCached-String.patch (100%) rename patches/unapplied/{ => server}/0425-Add-ignore-discounts-API.patch (100%) rename patches/unapplied/{ => server}/0426-Toggle-for-removing-existing-dragon.patch (100%) rename patches/unapplied/{ => server}/0427-Fix-client-lag-on-advancement-loading.patch (100%) rename patches/unapplied/{ => server}/0428-Item-no-age-no-player-pickup.patch (100%) rename patches/unapplied/{ => server}/0429-Beacon-API-custom-effect-ranges.patch (100%) rename patches/unapplied/{ => server}/0430-Add-API-for-quit-reason.patch (100%) rename patches/unapplied/{ => server}/0431-Add-Wandering-Trader-spawn-rate-config-options.patch (100%) rename patches/unapplied/{ => server}/0432-Add-Destroy-Speed-API.patch (100%) rename patches/unapplied/{ => server}/0433-Fix-Player-spawnParticle-x-y-z-precision-loss.patch (100%) rename patches/unapplied/{ => server}/0434-Add-LivingEntity-clearActiveItem.patch (100%) rename patches/unapplied/{ => server}/0435-Add-PlayerItemCooldownEvent.patch (100%) rename patches/unapplied/{ => server}/0436-Significantly-improve-performance-of-the-end-generat.patch (100%) rename patches/unapplied/{ => server}/0437-More-lightning-API.patch (100%) rename patches/unapplied/{ => server}/0438-Climbing-should-not-bypass-cramming-gamerule.patch (100%) rename patches/unapplied/{ => server}/0439-Add-missing-default-perms-for-commands.patch (100%) rename patches/unapplied/{ => server}/0440-Add-PlayerShearBlockEvent.patch (100%) rename patches/unapplied/{ => server}/0441-Limit-recipe-packets.patch (100%) rename patches/unapplied/{ => server}/0442-Fix-CraftSound-backwards-compatibility.patch (100%) rename patches/unapplied/{ => server}/0443-Player-Chunk-Load-Unload-Events.patch (100%) rename patches/unapplied/{ => server}/0444-Optimize-Dynamic-get-Missing-Keys.patch (100%) rename patches/unapplied/{ => server}/0445-Expose-LivingEntity-hurt-direction.patch (100%) rename patches/unapplied/{ => server}/0446-Add-OBSTRUCTED-reason-to-BedEnterResult.patch (100%) rename patches/unapplied/{ => server}/0447-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch (100%) rename patches/unapplied/{ => server}/0448-Add-TargetHitEvent.patch (100%) rename patches/unapplied/{ => server}/0449-MC-4-Fix-item-position-desync.patch (100%) rename patches/unapplied/{ => server}/0450-Additional-Block-Material-API.patch (100%) rename patches/unapplied/{ => server}/0451-Fix-harming-potion-dupe.patch (100%) rename patches/unapplied/{ => server}/0452-API-to-get-Material-from-Boats-and-Minecarts.patch (100%) rename patches/unapplied/{ => server}/0453-Allow-disabling-mob-spawner-spawn-egg-transformation.patch (100%) rename patches/unapplied/{ => server}/0454-Fix-Not-a-string-Map-Conversion-spam.patch (100%) rename patches/unapplied/{ => server}/0455-Add-PlayerFlowerPotManipulateEvent.patch (100%) rename patches/unapplied/{ => server}/0456-Fix-interact-event-not-being-called-sometimes.patch (100%) rename patches/unapplied/{ => server}/0457-Zombie-API-breaking-doors.patch (100%) rename patches/unapplied/{ => server}/0458-Fix-nerfed-slime-when-splitting.patch (100%) rename patches/unapplied/{ => server}/0459-Add-EntityLoadCrossbowEvent.patch (100%) rename patches/unapplied/{ => server}/0460-Add-WorldGameRuleChangeEvent.patch (100%) rename patches/unapplied/{ => server}/0461-Add-ServerResourcesReloadedEvent.patch (100%) rename patches/unapplied/{ => server}/0462-Add-world-settings-for-mobs-picking-up-loot.patch (100%) rename patches/unapplied/{ => server}/0463-Add-BlockFailedDispenseEvent.patch (100%) rename patches/unapplied/{ => server}/0464-Add-PlayerLecternPageChangeEvent.patch (100%) rename patches/unapplied/{ => server}/0465-Add-PlayerLoomPatternSelectEvent.patch (100%) rename patches/unapplied/{ => server}/0466-Configurable-door-breaking-difficulty.patch (100%) rename patches/unapplied/{ => server}/0467-Empty-commands-shall-not-be-dispatched.patch (100%) rename patches/unapplied/{ => server}/0468-Remove-stale-POIs.patch (100%) rename patches/unapplied/{ => server}/0469-Fix-villager-boat-exploit.patch (100%) rename patches/unapplied/{ => server}/0470-Add-sendOpLevel-API.patch (100%) rename patches/unapplied/{ => server}/0471-Add-RegistryAccess-for-managing-Registries.patch (100%) rename patches/unapplied/{ => server}/0472-Add-StructuresLocateEvent.patch (100%) rename patches/unapplied/{ => server}/0473-Collision-option-for-requiring-a-player-participant.patch (100%) rename patches/unapplied/{ => server}/0474-Return-chat-component-with-empty-text-instead-of-thr.patch (100%) rename patches/unapplied/{ => server}/0475-Make-schedule-command-per-world.patch (100%) rename patches/unapplied/{ => server}/0476-Configurable-max-leash-distance.patch (100%) rename patches/unapplied/{ => server}/0477-Add-BlockPreDispenseEvent.patch (100%) rename patches/unapplied/{ => server}/0478-Add-PlayerChangeBeaconEffectEvent.patch (100%) rename patches/unapplied/{ => server}/0479-Add-toggle-for-always-placing-the-dragon-egg.patch (100%) rename patches/unapplied/{ => server}/0480-Add-PlayerStonecutterRecipeSelectEvent.patch (100%) rename patches/unapplied/{ => server}/0481-Expand-EntityUnleashEvent.patch (100%) rename patches/unapplied/{ => server}/0482-Reset-shield-blocking-on-dimension-change.patch (100%) rename patches/unapplied/{ => server}/0483-Add-DragonEggFormEvent.patch (100%) rename patches/unapplied/{ => server}/0484-Add-EntityMoveEvent.patch (100%) rename patches/unapplied/{ => server}/0485-added-option-to-disable-pathfinding-updates-on-block.patch (100%) rename patches/unapplied/{ => server}/0486-Inline-shift-direction-fields.patch (100%) rename patches/unapplied/{ => server}/0487-Allow-adding-items-to-BlockDropItemEvent.patch (100%) rename patches/unapplied/{ => server}/0488-Add-getMainThreadExecutor-to-BukkitScheduler.patch (100%) rename patches/unapplied/{ => server}/0489-living-entity-allow-attribute-registration.patch (100%) rename patches/unapplied/{ => server}/0490-fix-dead-slime-setSize-invincibility.patch (100%) rename patches/unapplied/{ => server}/0491-Merchant-getRecipes-should-return-an-immutable-list.patch (100%) rename patches/unapplied/{ => server}/0492-Expose-Tracked-Players.patch (100%) rename patches/unapplied/{ => server}/0493-Improve-ServerGUI.patch (100%) rename patches/unapplied/{ => server}/0494-fix-converting-txt-to-json-file.patch (100%) rename patches/unapplied/{ => server}/0495-Add-worldborder-events.patch (100%) rename patches/unapplied/{ => server}/0496-Add-PlayerNameEntityEvent.patch (100%) rename patches/unapplied/{ => server}/0497-Add-recipe-to-cook-events.patch (100%) rename patches/unapplied/{ => server}/0498-Add-Block-isValidTool.patch (100%) rename patches/unapplied/{ => server}/0499-Allow-using-signs-inside-spawn-protection.patch (100%) rename patches/unapplied/{ => server}/0500-Expand-world-key-API.patch (100%) rename patches/unapplied/{ => server}/0501-Add-fast-alternative-constructor-for-Rotations.patch (100%) rename patches/unapplied/{ => server}/0502-Drop-carried-item-when-player-has-disconnected.patch (100%) rename patches/unapplied/{ => server}/0503-forced-whitelist-use-configurable-kick-message.patch (100%) rename patches/unapplied/{ => server}/0504-Don-t-ignore-result-of-PlayerEditBookEvent.patch (100%) rename patches/unapplied/{ => server}/0505-Expose-protocol-version.patch (100%) rename patches/unapplied/{ => server}/0506-Enhance-console-tab-completions-for-brigadier-comman.patch (100%) rename patches/unapplied/{ => server}/0507-Fix-PlayerItemConsumeEvent-cancelling-properly.patch (100%) rename patches/unapplied/{ => server}/0508-Add-bypass-host-check.patch (100%) rename patches/unapplied/{ => server}/0509-Set-area-affect-cloud-rotation.patch (100%) rename patches/unapplied/{ => server}/0510-add-isDeeplySleeping-to-HumanEntity.patch (100%) rename patches/unapplied/{ => server}/0511-add-consumeFuel-to-FurnaceBurnEvent.patch (100%) rename patches/unapplied/{ => server}/0512-add-get-set-drop-chance-to-EntityEquipment.patch (100%) rename patches/unapplied/{ => server}/0513-fix-PigZombieAngerEvent-cancellation.patch (100%) rename patches/unapplied/{ => server}/0514-fix-PlayerItemHeldEvent-firing-twice.patch (100%) rename patches/unapplied/{ => server}/0515-Add-PlayerDeepSleepEvent.patch (100%) rename patches/unapplied/{ => server}/0516-More-World-API.patch (100%) rename patches/unapplied/{ => server}/0517-Add-PlayerBedFailEnterEvent.patch (100%) rename patches/unapplied/{ => server}/0518-Implement-methods-to-convert-between-Component-and-B.patch (100%) rename patches/unapplied/{ => server}/0519-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch (100%) rename patches/unapplied/{ => server}/0520-Introduce-beacon-activation-deactivation-events.patch (100%) rename patches/unapplied/{ => server}/0521-Add-Channel-initialization-listeners.patch (100%) rename patches/unapplied/{ => server}/0522-Send-empty-commands-if-tab-completion-is-disabled.patch (100%) rename patches/unapplied/{ => server}/0523-Add-more-WanderingTrader-API.patch (100%) rename patches/unapplied/{ => server}/0524-Add-EntityBlockStorage-clearEntities.patch (100%) rename patches/unapplied/{ => server}/0525-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch (100%) rename patches/unapplied/{ => server}/0526-Add-HiddenPotionEffect-API.patch (100%) rename patches/unapplied/{ => server}/0527-Inventory-close.patch (100%) rename patches/unapplied/{ => server}/0528-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch (100%) rename patches/unapplied/{ => server}/0529-Add-basic-Datapack-API.patch (100%) rename patches/unapplied/{ => server}/0530-Add-environment-variable-to-disable-server-gui.patch (100%) rename patches/unapplied/{ => server}/0531-Expand-PlayerGameModeChangeEvent.patch (100%) rename patches/unapplied/{ => server}/0532-ItemStack-repair-check-API.patch (100%) rename patches/unapplied/{ => server}/0533-More-Enchantment-API.patch (100%) rename patches/unapplied/{ => server}/0534-Move-range-check-for-block-placing-up.patch (100%) rename patches/unapplied/{ => server}/0535-Add-Mob-lookAt-API.patch (100%) rename patches/unapplied/{ => server}/0536-Correctly-check-if-bucket-dispenses-will-succeed-for.patch (100%) rename patches/unapplied/{ => server}/0537-Add-Unix-domain-socket-support.patch (100%) rename patches/unapplied/{ => server}/0538-Add-EntityInsideBlockEvent.patch (100%) rename patches/unapplied/{ => server}/0539-Improve-item-default-attribute-API.patch (100%) rename patches/unapplied/{ => server}/0540-Add-cause-to-Weather-ThunderChangeEvents.patch (100%) rename patches/unapplied/{ => server}/0541-More-Lidded-Block-API.patch (100%) rename patches/unapplied/{ => server}/0542-Limit-item-frame-cursors-on-maps.patch (100%) rename patches/unapplied/{ => server}/0543-Add-PlayerKickEvent-causes.patch (100%) rename patches/unapplied/{ => server}/0544-Add-PufferFishStateChangeEvent.patch (100%) rename patches/unapplied/{ => server}/0545-Fix-PlayerBucketEmptyEvent-result-itemstack.patch (100%) rename patches/unapplied/{ => server}/0546-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch (100%) rename patches/unapplied/{ => server}/0547-Add-option-to-fix-items-merging-through-walls.patch (100%) rename patches/unapplied/{ => server}/0548-Add-BellRevealRaiderEvent.patch (100%) rename patches/unapplied/{ => server}/0549-Fix-invulnerable-end-crystals.patch (100%) rename patches/unapplied/{ => server}/0550-Add-ElderGuardianAppearanceEvent.patch (100%) rename patches/unapplied/{ => server}/0551-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch (100%) rename patches/unapplied/{ => server}/0552-Line-Of-Sight-Changes.patch (100%) rename patches/unapplied/{ => server}/0553-add-per-world-spawn-limits.patch (100%) rename patches/unapplied/{ => server}/0554-Fix-potions-splash-events.patch (100%) rename patches/unapplied/{ => server}/0555-Add-more-LimitedRegion-API.patch (100%) rename patches/unapplied/{ => server}/0556-Fix-PlayerDropItemEvent-using-wrong-item.patch (100%) rename patches/unapplied/{ => server}/0557-Missing-Entity-API.patch (100%) rename patches/unapplied/{ => server}/0558-Fix-return-value-of-Block-applyBoneMeal-always-being.patch (100%) rename patches/unapplied/{ => server}/0559-Use-getChunkIfLoadedImmediately-in-places.patch (100%) rename patches/unapplied/{ => server}/0560-Fix-commands-from-signs-not-firing-command-events.patch (100%) rename patches/unapplied/{ => server}/0561-Add-PlayerArmSwingEvent.patch (100%) rename patches/unapplied/{ => server}/0562-Fix-kick-event-leave-message-not-being-sent.patch (100%) rename patches/unapplied/{ => server}/0563-Don-t-apply-cramming-damage-to-players.patch (100%) rename patches/unapplied/{ => server}/0564-Rate-options-and-timings-for-sensors-and-behaviors.patch (100%) rename patches/unapplied/{ => server}/0565-Add-missing-forceDrop-toggles.patch (100%) rename patches/unapplied/{ => server}/0566-Stinger-API.patch (100%) rename patches/unapplied/{ => server}/0567-Add-System.out-err-catcher.patch (100%) rename patches/unapplied/{ => server}/0568-Prevent-AFK-kick-while-watching-end-credits.patch (100%) rename patches/unapplied/{ => server}/0569-Allow-skipping-writing-of-comments-to-server.propert.patch (100%) rename patches/unapplied/{ => server}/0570-Add-PlayerSetSpawnEvent.patch (100%) rename patches/unapplied/{ => server}/0571-Make-hoppers-respect-inventory-max-stack-size.patch (100%) rename patches/unapplied/{ => server}/0572-Optimize-entity-tracker-passenger-checks.patch (100%) rename patches/unapplied/{ => server}/0573-Config-option-for-Piglins-guarding-chests.patch (100%) rename patches/unapplied/{ => server}/0574-Add-EntityDamageItemEvent.patch (100%) rename patches/unapplied/{ => server}/0575-Optimize-indirect-passenger-iteration.patch (100%) rename patches/unapplied/{ => server}/0576-Configurable-item-frame-map-cursor-update-interval.patch (100%) rename patches/unapplied/{ => server}/0577-Change-EnderEye-target-without-changing-other-things.patch (100%) rename patches/unapplied/{ => server}/0578-Add-BlockBreakBlockEvent.patch (100%) rename patches/unapplied/{ => server}/0579-Option-to-prevent-data-components-copy-in-smithing-r.patch (100%) rename patches/unapplied/{ => server}/0580-More-CommandBlock-API.patch (100%) rename patches/unapplied/{ => server}/0581-Add-missing-team-sidebar-display-slots.patch (100%) rename patches/unapplied/{ => server}/0582-Add-back-EntityPortalExitEvent.patch (100%) rename patches/unapplied/{ => server}/0583-Add-methods-to-find-targets-for-lightning-strikes.patch (100%) rename patches/unapplied/{ => server}/0584-Get-entity-default-attributes.patch (100%) rename patches/unapplied/{ => server}/0585-Left-handed-API.patch (100%) rename patches/unapplied/{ => server}/0586-Add-more-advancement-API.patch (100%) rename patches/unapplied/{ => server}/0587-Add-ItemFactory-getSpawnEgg-API.patch (100%) rename patches/unapplied/{ => server}/0588-Add-critical-damage-API.patch (100%) rename patches/unapplied/{ => server}/0589-Fix-issues-with-mob-conversion.patch (100%) rename patches/unapplied/{ => server}/0590-Add-hasCollision-methods-to-various-places.patch (100%) rename patches/unapplied/{ => server}/0591-Goat-ram-API.patch (100%) rename patches/unapplied/{ => server}/0592-Add-API-for-resetting-a-single-score.patch (100%) rename patches/unapplied/{ => server}/0593-Add-Raw-Byte-Entity-Serialization.patch (100%) rename patches/unapplied/{ => server}/0594-Vanilla-command-permission-fixes.patch (100%) rename patches/unapplied/{ => server}/0595-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch (100%) rename patches/unapplied/{ => server}/0596-Fix-GameProfileCache-concurrency.patch (100%) rename patches/unapplied/{ => server}/0597-Improve-and-expand-AsyncCatcher.patch (100%) rename patches/unapplied/{ => server}/0598-Add-paper-mobcaps-and-paper-playermobcaps.patch (100%) rename patches/unapplied/{ => server}/0599-Sanitize-ResourceLocation-error-logging.patch (100%) rename patches/unapplied/{ => server}/0600-Manually-inline-methods-in-BlockPosition.patch (100%) rename patches/unapplied/{ => server}/0601-Name-craft-scheduler-threads-according-to-the-plugin.patch (100%) rename patches/unapplied/{ => server}/0602-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch (100%) rename patches/unapplied/{ => server}/0603-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch (100%) rename patches/unapplied/{ => server}/0604-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch (100%) rename patches/unapplied/{ => server}/0605-Time-scoreboard-search.patch (100%) rename patches/unapplied/{ => server}/0606-Oprimise-map-impl-for-tracked-players.patch (100%) rename patches/unapplied/{ => server}/0607-Add-missing-InventoryType.patch (100%) rename patches/unapplied/{ => server}/0608-Optimise-BlockSoil-nearby-water-lookup.patch (100%) rename patches/unapplied/{ => server}/0609-Fix-merchant-inventory-not-closing-on-entity-removal.patch (100%) rename patches/unapplied/{ => server}/0610-Check-requirement-before-suggesting-root-nodes.patch (100%) rename patches/unapplied/{ => server}/0611-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch (100%) rename patches/unapplied/{ => server}/0612-Add-packet-limiter-config.patch (100%) rename patches/unapplied/{ => server}/0613-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch (100%) rename patches/unapplied/{ => server}/0614-Ensure-valid-vehicle-status.patch (100%) rename patches/unapplied/{ => server}/0615-Prevent-softlocked-end-exit-portal-generation.patch (100%) rename patches/unapplied/{ => server}/0616-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch (100%) rename patches/unapplied/{ => server}/0617-Don-t-log-debug-logging-being-disabled.patch (100%) rename patches/unapplied/{ => server}/0618-fix-various-menus-with-empty-level-accesses.patch (100%) rename patches/unapplied/{ => server}/0619-Preserve-overstacked-loot.patch (100%) rename patches/unapplied/{ => server}/0620-Update-head-rotation-in-missing-places.patch (100%) rename patches/unapplied/{ => server}/0621-prevent-unintended-light-block-manipulation.patch (100%) rename patches/unapplied/{ => server}/0622-Fix-CraftCriteria-defaults-map.patch (100%) rename patches/unapplied/{ => server}/0623-Fix-upstreams-block-state-factories.patch (100%) rename patches/unapplied/{ => server}/0624-Configurable-feature-seeds.patch (100%) rename patches/unapplied/{ => server}/0625-Add-root-admin-user-detection.patch (100%) rename patches/unapplied/{ => server}/0626-don-t-attempt-to-teleport-dead-entities.patch (100%) rename patches/unapplied/{ => server}/0627-Prevent-excessive-velocity-through-repeated-crits.patch (100%) rename patches/unapplied/{ => server}/0628-Remove-client-side-code-using-deprecated-for-removal.patch (100%) rename patches/unapplied/{ => server}/0629-Fix-Spigot-growth-modifiers.patch (100%) rename patches/unapplied/{ => server}/0630-Prevent-ContainerOpenersCounter-openCount-from-going.patch (100%) rename patches/unapplied/{ => server}/0631-Add-PlayerItemFrameChangeEvent.patch (100%) rename patches/unapplied/{ => server}/0632-Optimize-HashMapPalette.patch (100%) rename patches/unapplied/{ => server}/0633-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch (100%) rename patches/unapplied/{ => server}/0634-Add-more-Campfire-API.patch (100%) rename patches/unapplied/{ => server}/0635-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch (100%) rename patches/unapplied/{ => server}/0636-Forward-CraftEntity-in-teleport-command.patch (100%) rename patches/unapplied/{ => server}/0637-Improve-scoreboard-entries.patch (100%) rename patches/unapplied/{ => server}/0638-Entity-powdered-snow-API.patch (100%) rename patches/unapplied/{ => server}/0639-Add-API-for-item-entity-health.patch (100%) rename patches/unapplied/{ => server}/0640-Configurable-max-block-light-for-monster-spawning.patch (100%) rename patches/unapplied/{ => server}/0641-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch (100%) rename patches/unapplied/{ => server}/0642-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch (100%) rename patches/unapplied/{ => server}/0643-Bucketable-API.patch (100%) rename patches/unapplied/{ => server}/0644-Validate-usernames.patch (100%) rename patches/unapplied/{ => server}/0645-Make-water-animal-spawn-height-configurable.patch (100%) rename patches/unapplied/{ => server}/0646-Expose-vanilla-BiomeProvider-from-WorldInfo.patch (100%) rename patches/unapplied/{ => server}/0647-Add-config-option-for-worlds-affected-by-time-cmd.patch (100%) rename patches/unapplied/{ => server}/0648-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch (100%) rename patches/unapplied/{ => server}/0649-Multiple-Entries-with-Scoreboards.patch (100%) rename patches/unapplied/{ => server}/0650-Reset-placed-block-on-exception.patch (100%) rename patches/unapplied/{ => server}/0651-Add-configurable-height-for-slime-spawn.patch (100%) rename patches/unapplied/{ => server}/0652-Fix-xp-reward-for-baby-zombies.patch (100%) rename patches/unapplied/{ => server}/0653-Multi-Block-Change-API-Implementation.patch (100%) rename patches/unapplied/{ => server}/0654-Fix-NotePlayEvent.patch (100%) rename patches/unapplied/{ => server}/0655-Freeze-Tick-Lock-API.patch (100%) rename patches/unapplied/{ => server}/0656-More-PotionEffectType-API.patch (100%) rename patches/unapplied/{ => server}/0657-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch (100%) rename patches/unapplied/{ => server}/0658-API-for-creating-command-sender-which-forwards-feedb.patch (100%) rename patches/unapplied/{ => server}/0659-Add-missing-structure-set-seed-configs.patch (100%) rename patches/unapplied/{ => server}/0660-Fix-cancelled-powdered-snow-bucket-placement.patch (100%) rename patches/unapplied/{ => server}/0661-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch (100%) rename patches/unapplied/{ => server}/0662-Add-GameEvent-tags.patch (100%) rename patches/unapplied/{ => server}/0663-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch (100%) rename patches/unapplied/{ => server}/0664-Furnace-RecipesUsed-API.patch (100%) rename patches/unapplied/{ => server}/0665-Configurable-sculk-sensor-listener-range.patch (100%) rename patches/unapplied/{ => server}/0666-Add-missing-block-data-API.patch (100%) rename patches/unapplied/{ => server}/0667-Option-to-have-default-CustomSpawners-in-custom-worl.patch (100%) rename patches/unapplied/{ => server}/0668-Put-world-into-worldlist-before-initing-the-world.patch (100%) rename patches/unapplied/{ => server}/0669-Custom-Potion-Mixes.patch (100%) rename patches/unapplied/{ => server}/0670-Force-close-world-loading-screen.patch (100%) rename patches/unapplied/{ => server}/0671-Fix-falling-block-spawn-methods.patch (100%) rename patches/unapplied/{ => server}/0672-Expose-furnace-minecart-push-values.patch (100%) rename patches/unapplied/{ => server}/0673-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch (100%) rename patches/unapplied/{ => server}/0674-More-Projectile-API.patch (100%) rename patches/unapplied/{ => server}/0675-Fix-swamp-hut-cat-generation-deadlock.patch (100%) rename patches/unapplied/{ => server}/0676-Don-t-allow-vehicle-movement-from-players-while-tele.patch (100%) rename patches/unapplied/{ => server}/0677-Implement-getComputedBiome-API.patch (100%) rename patches/unapplied/{ => server}/0678-Make-some-itemstacks-nonnull.patch (100%) rename patches/unapplied/{ => server}/0679-Implement-enchantWithLevels-API.patch (100%) rename patches/unapplied/{ => server}/0680-Fix-saving-in-unloadWorld.patch (100%) rename patches/unapplied/{ => server}/0681-Buffer-OOB-setBlock-calls.patch (100%) rename patches/unapplied/{ => server}/0682-Add-TameableDeathMessageEvent.patch (100%) rename patches/unapplied/{ => server}/0683-Fix-new-block-data-for-EntityChangeBlockEvent.patch (100%) rename patches/unapplied/{ => server}/0684-fix-player-loottables-running-when-mob-loot-gamerule.patch (100%) rename patches/unapplied/{ => server}/0685-Ensure-entity-passenger-world-matches-ridden-entity.patch (100%) rename patches/unapplied/{ => server}/0686-Cache-resource-keys-and-optimize-reference-Holder-ta.patch (100%) rename patches/unapplied/{ => server}/0687-Allow-changing-the-EnderDragon-podium.patch (100%) rename patches/unapplied/{ => server}/0688-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch (100%) rename patches/unapplied/{ => server}/0689-Prevent-tile-entity-copies-loading-chunks.patch (100%) rename patches/unapplied/{ => server}/0690-Use-username-instead-of-display-name-in-PlayerList-g.patch (100%) rename patches/unapplied/{ => server}/0691-Expand-PlayerItemDamageEvent.patch (100%) rename patches/unapplied/{ => server}/0692-WorldCreator-keepSpawnLoaded.patch (100%) rename patches/unapplied/{ => server}/0693-Fix-CME-in-CraftPersistentDataTypeRegistry.patch (100%) rename patches/unapplied/{ => server}/0694-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch (100%) rename patches/unapplied/{ => server}/0695-Add-EntityDyeEvent-and-CollarColorable-interface.patch (100%) rename patches/unapplied/{ => server}/0696-Fire-CauldronLevelChange-on-initial-fill.patch (100%) rename patches/unapplied/{ => server}/0697-fix-powder-snow-cauldrons-not-turning-to-water.patch (100%) rename patches/unapplied/{ => server}/0698-Add-PlayerStopUsingItemEvent.patch (100%) rename patches/unapplied/{ => server}/0699-Don-t-tick-markers.patch (100%) rename patches/unapplied/{ => server}/0700-Expand-FallingBlock-API.patch (100%) rename patches/unapplied/{ => server}/0701-Add-support-for-Proxy-Protocol.patch (100%) rename patches/unapplied/{ => server}/0702-Fix-OfflinePlayer-getBedSpawnLocation.patch (100%) rename patches/unapplied/{ => server}/0703-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch (100%) rename patches/unapplied/{ => server}/0704-Sanitize-sent-BlockEntity-NBT.patch (100%) rename patches/unapplied/{ => server}/0705-Disable-component-selector-resolving-in-books-by-def.patch (100%) rename patches/unapplied/{ => server}/0706-Prevent-entity-loading-causing-async-lookups.patch (100%) rename patches/unapplied/{ => server}/0707-Throw-exception-on-world-create-while-being-ticked.patch (100%) rename patches/unapplied/{ => server}/0708-Dont-resent-entity-on-art-update.patch (100%) rename patches/unapplied/{ => server}/0709-Add-WardenAngerChangeEvent.patch (100%) rename patches/unapplied/{ => server}/0710-Add-option-for-strict-advancement-dimension-checks.patch (100%) rename patches/unapplied/{ => server}/0711-Add-missing-important-BlockStateListPopulator-method.patch (100%) rename patches/unapplied/{ => server}/0712-Nameable-Banner-API.patch (100%) rename patches/unapplied/{ => server}/0713-Don-t-broadcast-messages-to-command-blocks.patch (100%) rename patches/unapplied/{ => server}/0714-Prevent-empty-items-from-being-added-to-world.patch (100%) rename patches/unapplied/{ => server}/0715-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch (100%) rename patches/unapplied/{ => server}/0716-Add-Player-getFishHook.patch (100%) rename patches/unapplied/{ => server}/0717-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch (100%) rename patches/unapplied/{ => server}/0718-Add-various-missing-EntityDropItemEvent-calls.patch (100%) rename patches/unapplied/{ => server}/0719-Fix-Bee-flower-NPE.patch (100%) rename patches/unapplied/{ => server}/0720-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch (100%) rename patches/unapplied/{ => server}/0721-More-Teleport-API.patch (100%) rename patches/unapplied/{ => server}/0722-Add-EntityPortalReadyEvent.patch (100%) rename patches/unapplied/{ => server}/0723-Don-t-use-level-random-in-entity-constructors.patch (100%) rename patches/unapplied/{ => server}/0724-Send-block-entities-after-destroy-prediction.patch (100%) rename patches/unapplied/{ => server}/0725-Warn-on-plugins-accessing-faraway-chunks.patch (100%) rename patches/unapplied/{ => server}/0726-Custom-Chat-Completion-Suggestions-API.patch (100%) rename patches/unapplied/{ => server}/0727-Add-and-fix-missing-BlockFadeEvents.patch (100%) rename patches/unapplied/{ => server}/0728-Collision-API.patch (100%) rename patches/unapplied/{ => server}/0729-Fix-suggest-command-message-for-brigadier-syntax-exc.patch (100%) rename patches/unapplied/{ => server}/0730-Block-Ticking-API.patch (100%) rename patches/unapplied/{ => server}/0731-Add-Velocity-IP-Forwarding-Support.patch (100%) rename patches/unapplied/{ => server}/0732-Add-NamespacedKey-biome-methods.patch (100%) rename patches/unapplied/{ => server}/0733-Fix-plugin-loggers-on-server-shutdown.patch (100%) rename patches/unapplied/{ => server}/0734-Stop-large-look-changes-from-crashing-the-server.patch (100%) rename patches/unapplied/{ => server}/0735-Fire-EntityChangeBlockEvent-in-more-places.patch (100%) rename patches/unapplied/{ => server}/0736-Missing-eating-regain-reason.patch (100%) rename patches/unapplied/{ => server}/0737-Missing-effect-cause.patch (100%) rename patches/unapplied/{ => server}/0738-Added-byte-array-serialization-deserialization-for-P.patch (100%) rename patches/unapplied/{ => server}/0739-Call-BlockPhysicsEvent-more-often.patch (100%) rename patches/unapplied/{ => server}/0740-Configurable-chat-thread-limit.patch (100%) rename patches/unapplied/{ => server}/0741-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch (100%) rename patches/unapplied/{ => server}/0742-fix-Jigsaw-block-kicking-user.patch (100%) rename patches/unapplied/{ => server}/0743-use-BlockFormEvent-for-mud-converting-into-clay.patch (100%) rename patches/unapplied/{ => server}/0744-Add-getDrops-to-BlockState.patch (100%) rename patches/unapplied/{ => server}/0745-Fix-a-bunch-of-vanilla-bugs.patch (100%) rename patches/unapplied/{ => server}/0746-Remove-unnecessary-onTrackingStart-during-navigation.patch (100%) rename patches/unapplied/{ => server}/0747-Fix-custom-piglin-loved-items.patch (100%) rename patches/unapplied/{ => server}/0748-EntityPickupItemEvent-fixes.patch (100%) rename patches/unapplied/{ => server}/0749-Correctly-handle-interactions-with-items-on-cooldown.patch (100%) rename patches/unapplied/{ => server}/0750-Add-PlayerInventorySlotChangeEvent.patch (100%) rename patches/unapplied/{ => server}/0751-Elder-Guardian-appearance-API.patch (100%) rename patches/unapplied/{ => server}/0752-Add-entity-knockback-API.patch (100%) rename patches/unapplied/{ => server}/0753-Detect-headless-JREs.patch (100%) rename patches/unapplied/{ => server}/0754-fix-entity-vehicle-collision-event-not-called.patch (100%) rename patches/unapplied/{ => server}/0755-Add-EntityToggleSitEvent.patch (100%) rename patches/unapplied/{ => server}/0756-Add-fire-tick-delay-option.patch (100%) rename patches/unapplied/{ => server}/0757-Add-Moving-Piston-API.patch (100%) rename patches/unapplied/{ => server}/0758-Ignore-impossible-spawn-tick.patch (100%) rename patches/unapplied/{ => server}/0759-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch (100%) rename patches/unapplied/{ => server}/0760-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch (100%) rename patches/unapplied/{ => server}/0761-Add-PrePlayerAttackEntityEvent.patch (100%) rename patches/unapplied/{ => server}/0762-ensure-reset-EnderDragon-boss-event-name.patch (100%) rename patches/unapplied/{ => server}/0763-Add-Player-Warden-Warning-API.patch (100%) rename patches/unapplied/{ => server}/0764-More-vanilla-friendly-methods-to-update-trades.patch (100%) rename patches/unapplied/{ => server}/0765-Add-paper-dumplisteners-command.patch (100%) rename patches/unapplied/{ => server}/0766-check-global-player-list-where-appropriate.patch (100%) rename patches/unapplied/{ => server}/0767-Fix-async-entity-add-due-to-fungus-trees.patch (100%) rename patches/unapplied/{ => server}/0768-ItemStack-damage-API.patch (100%) rename patches/unapplied/{ => server}/0769-Friction-API.patch (100%) rename patches/unapplied/{ => server}/0770-Ability-to-control-player-s-insomnia-and-phantoms.patch (100%) rename patches/unapplied/{ => server}/0771-Fix-premature-player-kicks-on-shutdown.patch (100%) rename patches/unapplied/{ => server}/0772-Sync-offhand-slot-in-menus.patch (100%) rename patches/unapplied/{ => server}/0773-Player-Entity-Tracking-Events.patch (100%) rename patches/unapplied/{ => server}/0774-Limit-pet-look-distance.patch (100%) rename patches/unapplied/{ => server}/0775-fix-Instruments.patch (100%) rename patches/unapplied/{ => server}/0776-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch (100%) rename patches/unapplied/{ => server}/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch (100%) rename patches/unapplied/{ => server}/0778-Add-BlockLockCheckEvent.patch (100%) rename patches/unapplied/{ => server}/0779-Add-Sneaking-API-for-Entities.patch (100%) rename patches/unapplied/{ => server}/0780-Improve-logging-and-errors.patch (100%) rename patches/unapplied/{ => server}/0781-Improve-PortalEvents.patch (100%) rename patches/unapplied/{ => server}/0782-Add-config-option-for-spider-worldborder-climbing.patch (100%) rename patches/unapplied/{ => server}/0783-Add-missing-SpigotConfig-logCommands-check.patch (100%) rename patches/unapplied/{ => server}/0784-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch (100%) rename patches/unapplied/{ => server}/0785-Flying-Fall-Damage.patch (100%) rename patches/unapplied/{ => server}/0786-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch (100%) rename patches/unapplied/{ => server}/0787-config-for-disabling-entity-tag-tags.patch (100%) rename patches/unapplied/{ => server}/0788-Use-single-player-info-update-packet-on-join.patch (100%) rename patches/unapplied/{ => server}/0789-Correctly-shrink-items-during-EntityResurrectEvent.patch (100%) rename patches/unapplied/{ => server}/0790-Win-Screen-API.patch (100%) rename patches/unapplied/{ => server}/0791-Remove-CraftItemStack-setAmount-null-assignment.patch (100%) rename patches/unapplied/{ => server}/0792-Fix-force-opening-enchantment-tables.patch (100%) rename patches/unapplied/{ => server}/0793-Add-Entity-Body-Yaw-API.patch (100%) rename patches/unapplied/{ => server}/0794-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch (100%) rename patches/unapplied/{ => server}/0795-Add-EntityFertilizeEggEvent.patch (100%) rename patches/unapplied/{ => server}/0796-Fix-HumanEntity-drop-not-updating-the-client-inv.patch (100%) rename patches/unapplied/{ => server}/0797-Add-CompostItemEvent-and-EntityCompostItemEvent.patch (100%) rename patches/unapplied/{ => server}/0798-Correctly-handle-ArmorStand-invisibility.patch (100%) rename patches/unapplied/{ => server}/0799-Fix-advancement-triggers-for-entity-damage.patch (100%) rename patches/unapplied/{ => server}/0800-Fix-text-display-error-on-spawn.patch (100%) rename patches/unapplied/{ => server}/0801-Fix-inventories-returning-null-Locations.patch (100%) rename patches/unapplied/{ => server}/0802-Add-Shearable-API.patch (100%) rename patches/unapplied/{ => server}/0803-Fix-SpawnEggMeta-get-setSpawnedType.patch (100%) rename patches/unapplied/{ => server}/0804-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch (100%) rename patches/unapplied/{ => server}/0805-Treat-sequence-violations-like-they-should-be.patch (100%) rename patches/unapplied/{ => server}/0806-Prevent-causing-expired-keys-from-impacting-new-join.patch (100%) rename patches/unapplied/{ => server}/0807-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch (100%) rename patches/unapplied/{ => server}/0808-Use-array-for-gamerule-storage.patch (100%) rename patches/unapplied/{ => server}/0809-Fix-a-couple-of-upstream-bed-issues.patch (100%) rename patches/unapplied/{ => server}/0810-Fix-demo-flag-not-enabling-demo-mode.patch (100%) rename patches/unapplied/{ => server}/0811-Add-Mob-Experience-reward-API.patch (100%) rename patches/unapplied/{ => server}/0812-Break-redstone-on-top-of-trap-doors-early.patch (100%) rename patches/unapplied/{ => server}/0813-Avoid-Lazy-Initialization-for-Enum-Fields.patch (100%) rename patches/unapplied/{ => server}/0814-More-accurate-isInOpenWater-impl.patch (100%) rename patches/unapplied/{ => server}/0815-Expand-PlayerItemMendEvent.patch (100%) rename patches/unapplied/{ => server}/0816-Refresh-ProjectileSource-for-projectiles.patch (100%) rename patches/unapplied/{ => server}/0817-Add-transient-modifier-API.patch (100%) rename patches/unapplied/{ => server}/0818-Fix-block-place-logic.patch (100%) rename patches/unapplied/{ => server}/0819-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch (100%) rename patches/unapplied/{ => server}/0820-Call-BlockGrowEvent-for-missing-blocks.patch (100%) rename patches/unapplied/{ => server}/0821-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch (100%) rename patches/unapplied/{ => server}/0822-fix-MapLike-spam-for-missing-key-selector.patch (100%) rename patches/unapplied/{ => server}/0823-Fix-sniffer-removeExploredLocation.patch (100%) rename patches/unapplied/{ => server}/0824-Add-method-to-remove-all-active-potion-effects.patch (100%) rename patches/unapplied/{ => server}/0825-Fix-incorrect-crafting-result-amount-for-fireworks.patch (100%) rename patches/unapplied/{ => server}/0826-Add-event-for-player-editing-sign.patch (100%) rename patches/unapplied/{ => server}/0827-Only-tick-item-frames-if-players-can-see-it.patch (100%) rename patches/unapplied/{ => server}/0828-Fix-cmd-permission-levels-for-command-blocks.patch (100%) rename patches/unapplied/{ => server}/0829-Add-option-to-disable-block-updates.patch (100%) rename patches/unapplied/{ => server}/0830-Call-missing-BlockDispenseEvent.patch (100%) rename patches/unapplied/{ => server}/0831-Don-t-load-chunks-for-supporting-block-checks.patch (100%) rename patches/unapplied/{ => server}/0832-Optimize-player-lookups-for-beacons.patch (100%) rename patches/unapplied/{ => server}/0833-More-Sign-Block-API.patch (100%) rename patches/unapplied/{ => server}/0834-fix-item-meta-for-tadpole-buckets.patch (100%) rename patches/unapplied/{ => server}/0835-Fix-BanList-API.patch (100%) rename patches/unapplied/{ => server}/0836-Determine-lava-and-water-fluid-explosion-resistance-.patch (100%) rename patches/unapplied/{ => server}/0837-Fix-possible-NPE-on-painting-creation.patch (100%) rename patches/unapplied/{ => server}/0838-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch (100%) rename patches/unapplied/{ => server}/0839-ExperienceOrb-should-call-EntitySpawnEvent.patch (100%) rename patches/unapplied/{ => server}/0840-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch (100%) rename patches/unapplied/{ => server}/0841-Add-whitelist-events.patch (100%) rename patches/unapplied/{ => server}/0842-Implement-PlayerFailMoveEvent.patch (100%) rename patches/unapplied/{ => server}/0843-Folia-scheduler-and-owned-region-API.patch (100%) rename patches/unapplied/{ => server}/0844-Only-erase-allay-memory-on-non-item-targets.patch (100%) rename patches/unapplied/{ => server}/0845-API-for-updating-recipes-on-clients.patch (100%) rename patches/unapplied/{ => server}/0846-Fix-rotation-when-spawning-display-entities.patch (100%) rename patches/unapplied/{ => server}/0847-Only-capture-actual-tree-growth.patch (100%) rename patches/unapplied/{ => server}/0848-Use-correct-source-for-mushroom-block-spread-event.patch (100%) rename patches/unapplied/{ => server}/0849-Respect-randomizeData-on-more-entities-when-spawning.patch (100%) rename patches/unapplied/{ => server}/0850-Use-correct-seed-on-api-world-load.patch (100%) rename patches/unapplied/{ => server}/0851-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch (100%) rename patches/unapplied/{ => server}/0852-Cache-map-ids-on-item-frames.patch (100%) rename patches/unapplied/{ => server}/0853-Fix-custom-statistic-criteria-creation.patch (100%) rename patches/unapplied/{ => server}/0854-Bandaid-fix-for-Effect.patch (100%) rename patches/unapplied/{ => server}/0855-SculkCatalyst-bloom-API.patch (100%) rename patches/unapplied/{ => server}/0856-API-for-an-entity-s-scoreboard-name.patch (100%) rename patches/unapplied/{ => server}/0857-Deprecate-and-replace-methods-with-old-StructureType.patch (100%) rename patches/unapplied/{ => server}/0858-Don-t-tab-complete-namespaced-commands-if-send-names.patch (100%) rename patches/unapplied/{ => server}/0859-Properly-handle-BlockBreakEvent-isDropItems.patch (100%) rename patches/unapplied/{ => server}/0860-Fire-entity-death-event-for-ender-dragon.patch (100%) rename patches/unapplied/{ => server}/0861-Configurable-entity-tracking-range-by-Y-coordinate.patch (100%) rename patches/unapplied/{ => server}/0862-Add-Listing-API-for-Player.patch (100%) rename patches/unapplied/{ => server}/0863-Configurable-Region-Compression-Format.patch (100%) rename patches/unapplied/{ => server}/0864-Add-BlockFace-to-BlockDamageEvent.patch (100%) rename patches/unapplied/{ => server}/0865-Fix-NPE-on-Boat-getStatus.patch (100%) rename patches/unapplied/{ => server}/0866-Expand-Pose-API.patch (100%) rename patches/unapplied/{ => server}/0867-More-DragonBattle-API.patch (100%) rename patches/unapplied/{ => server}/0868-Add-PlayerPickItemEvent.patch (100%) rename patches/unapplied/{ => server}/0869-Allow-trident-custom-damage.patch (100%) rename patches/unapplied/{ => server}/0870-Expose-hand-in-BlockCanBuildEvent.patch (100%) rename patches/unapplied/{ => server}/0871-Optimize-nearest-structure-border-iteration.patch (100%) rename patches/unapplied/{ => server}/0872-Implement-OfflinePlayer-isConnected.patch (100%) rename patches/unapplied/{ => server}/0873-Fix-slot-desync.patch (100%) rename patches/unapplied/{ => server}/0874-Add-titleOverride-to-InventoryOpenEvent.patch (100%) rename patches/unapplied/{ => server}/0875-Configure-sniffer-egg-hatch-time.patch (100%) rename patches/unapplied/{ => server}/0876-Do-crystal-portal-proximity-check-before-entity-look.patch (100%) rename patches/unapplied/{ => server}/0877-Skip-POI-finding-if-stuck-in-vehicle.patch (100%) rename patches/unapplied/{ => server}/0878-Add-slot-sanity-checks-in-container-clicks.patch (100%) rename patches/unapplied/{ => server}/0879-Call-BlockRedstoneEvents-for-lecterns.patch (100%) rename patches/unapplied/{ => server}/0880-Allow-proper-checking-of-empty-item-stacks.patch (100%) rename patches/unapplied/{ => server}/0881-Fix-silent-equipment-change-for-mobs.patch (100%) rename patches/unapplied/{ => server}/0882-Fix-spigot-s-Forced-Stats.patch (100%) rename patches/unapplied/{ => server}/0883-Add-missing-InventoryHolders-to-inventories.patch (100%) rename patches/unapplied/{ => server}/0884-Do-not-read-tile-entities-in-chunks-that-are-positio.patch (100%) rename patches/unapplied/{ => server}/0885-Add-missing-logs-for-log-ips-config-option.patch (100%) rename patches/unapplied/{ => server}/0886-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch (100%) rename patches/unapplied/{ => server}/0887-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch (100%) rename patches/unapplied/{ => server}/0888-Fix-team-sidebar-objectives-not-being-cleared.patch (100%) rename patches/unapplied/{ => server}/0889-Fix-missing-map-initialize-event-call.patch (100%) rename patches/unapplied/{ => server}/0890-Update-entity-data-when-attaching-firework-to-entity.patch (100%) rename patches/unapplied/{ => server}/0891-Fix-UnsafeValues-loadAdvancement.patch (100%) rename patches/unapplied/{ => server}/0892-Add-player-idle-duration-API.patch (100%) rename patches/unapplied/{ => server}/0893-Don-t-check-if-we-can-see-non-visible-entities.patch (100%) rename patches/unapplied/{ => server}/0894-Fix-NPE-in-SculkBloomEvent-world-access.patch (100%) rename patches/unapplied/{ => server}/0895-Allow-null-itemstack-for-Player-sendEquipmentChange.patch (100%) rename patches/unapplied/{ => server}/0896-Optimize-VarInts.patch (100%) rename patches/unapplied/{ => server}/0897-Add-API-to-get-the-collision-shape-of-a-block-before.patch (100%) rename patches/unapplied/{ => server}/0898-Add-predicate-for-blocks-when-raytracing.patch (100%) rename patches/unapplied/{ => server}/0899-Broadcast-take-item-packets-with-collector-as-source.patch (100%) rename patches/unapplied/{ => server}/0900-Expand-LingeringPotion-API.patch (100%) rename patches/unapplied/{ => server}/0901-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch (100%) rename patches/unapplied/{ => server}/0902-Add-hand-to-fish-event-for-all-player-interactions.patch (100%) rename patches/unapplied/{ => server}/0903-Fix-several-issues-with-EntityBreedEvent.patch (100%) rename patches/unapplied/{ => server}/0904-Add-UUID-attribute-modifier-API.patch (100%) rename patches/unapplied/{ => server}/0905-Fix-missing-event-call-for-entity-teleport-API.patch (100%) rename patches/unapplied/{ => server}/0906-Lazily-create-LootContext-for-criterions.patch (100%) rename patches/unapplied/{ => server}/0907-Don-t-fire-sync-events-during-worldgen.patch (100%) rename patches/unapplied/{ => server}/0908-Add-Structure-check-API.patch (100%) rename patches/unapplied/{ => server}/0909-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch (100%) rename patches/unapplied/{ => server}/0910-Restore-vanilla-entity-drops-behavior.patch (100%) rename patches/unapplied/{ => server}/0911-Dont-resend-blocks-on-interactions.patch (100%) rename patches/unapplied/{ => server}/0912-add-more-scoreboard-API.patch (100%) rename patches/unapplied/{ => server}/0913-Improve-Registry.patch (100%) rename patches/unapplied/{ => server}/0914-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch (100%) rename patches/unapplied/{ => server}/0915-Add-experience-points-API.patch (100%) rename patches/unapplied/{ => server}/0916-Add-drops-to-shear-events.patch (100%) rename patches/unapplied/{ => server}/0917-Add-PlayerShieldDisableEvent.patch (100%) rename patches/unapplied/{ => server}/0918-Validate-ResourceLocation-in-NBT-reading.patch (100%) rename patches/unapplied/{ => server}/0919-Properly-handle-experience-dropping-on-block-break.patch (100%) rename patches/unapplied/{ => server}/0920-Fixup-NamespacedKey-handling.patch (100%) rename patches/unapplied/{ => server}/0921-Expose-LootTable-of-DecoratedPot.patch (100%) rename patches/unapplied/{ => server}/0922-Reduce-allocation-of-Vec3D-by-entity-tracker.patch (100%) rename patches/unapplied/{ => server}/0923-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch (100%) rename patches/unapplied/{ => server}/0924-Add-ShulkerDuplicateEvent.patch (100%) rename patches/unapplied/{ => server}/0925-Add-api-for-spawn-egg-texture-colors.patch (100%) rename patches/unapplied/{ => server}/0926-Add-Lifecycle-Event-system.patch (100%) rename patches/unapplied/{ => server}/0927-ItemStack-Tooltip-API.patch (100%) rename patches/unapplied/{ => server}/0928-Add-getChunkSnapshot-includeLightData-parameter.patch (100%) rename patches/unapplied/{ => server}/0929-Add-FluidState-API.patch (100%) rename patches/unapplied/{ => server}/0930-add-number-format-api.patch (100%) rename patches/unapplied/{ => server}/0931-improve-BanList-types.patch (100%) rename patches/unapplied/{ => server}/0932-Expanded-Hopper-API.patch (100%) rename patches/unapplied/{ => server}/0933-Add-BlockBreakProgressUpdateEvent.patch (100%) rename patches/unapplied/{ => server}/0934-Deprecate-ItemStack-setType.patch (100%) rename patches/unapplied/{ => server}/0935-Add-CartographyItemEvent.patch (100%) rename patches/unapplied/{ => server}/0936-More-Raid-API.patch (100%) rename patches/unapplied/{ => server}/0937-Add-onboarding-message-for-initial-server-start.patch (100%) rename patches/unapplied/{ => server}/0938-Configurable-max-block-fluid-ticks.patch (100%) rename patches/unapplied/{ => server}/0939-Fix-bees-aging-inside-hives.patch (100%) rename patches/unapplied/{ => server}/0940-Disable-memory-reserve-allocating.patch (100%) rename patches/unapplied/{ => server}/0941-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch (100%) rename patches/unapplied/{ => server}/0942-Fix-DamageSource-API.patch (100%) rename patches/unapplied/{ => server}/0943-Fix-creation-of-invalid-block-entity-during-world-ge.patch (100%) rename patches/unapplied/{ => server}/0944-Fix-possible-StackOverflowError-for-some-dispenses.patch (100%) rename patches/unapplied/{ => server}/0945-Improve-tag-parser-handling.patch (100%) rename patches/unapplied/{ => server}/0946-Item-Mutation-Fixes.patch (100%) rename patches/unapplied/{ => server}/0947-Per-world-ticks-per-spawn-settings.patch (100%) rename patches/unapplied/{ => server}/0948-Properly-track-the-changed-item-from-dispense-events.patch (100%) rename patches/unapplied/{ => server}/0949-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch (100%) rename patches/unapplied/{ => server}/0950-Fix-tripwire-disarming-not-working-as-intended.patch (100%) rename patches/unapplied/{ => server}/0951-Add-config-for-mobs-immune-to-default-effects.patch (100%) rename patches/unapplied/{ => server}/0952-Deep-clone-nbt-tags-in-PDC.patch (100%) rename patches/unapplied/{ => server}/0953-Support-old-UUID-format-for-NBT.patch (100%) rename patches/unapplied/{ => server}/0954-Fix-shield-disable-inconsistency.patch (100%) rename patches/unapplied/{ => server}/0955-Handle-Large-Packets-disconnecting-client.patch (100%) rename patches/unapplied/{ => server}/0956-Fix-ItemFlags.patch (100%) rename patches/unapplied/{ => server}/0957-Fix-helmet-damage-reduction-inconsistencies.patch (100%) rename patches/unapplied/{ => server}/0958-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch (100%) rename patches/unapplied/{ => server}/0959-improve-checking-handled-tags-in-itemmeta.patch (100%) rename patches/unapplied/{ => server}/0960-General-ItemMeta-fixes.patch (100%) rename patches/unapplied/{ => server}/0961-Expose-hasColor-to-leather-armor.patch (100%) rename patches/unapplied/{ => server}/0962-Added-API-to-get-player-ha-proxy-address.patch (100%) rename patches/unapplied/{ => server}/0963-More-Chest-Block-API.patch (100%) rename patches/unapplied/{ => server}/0964-Print-data-component-type-on-encoding-error.patch (100%) rename patches/unapplied/{ => server}/0965-Brigadier-based-command-API.patch (100%) rename patches/unapplied/{ => server}/0966-Fix-issues-with-Recipe-API.patch (100%) rename patches/unapplied/{ => server}/0967-Fix-equipment-slot-and-group-API.patch (100%) rename patches/unapplied/{ => server}/0968-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch (100%) rename patches/unapplied/{ => server}/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch (100%) rename patches/unapplied/{ => server}/0970-Prevent-NPE-if-hooked-entity-was-cleared.patch (100%) rename patches/unapplied/{ => server}/0971-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch (100%) rename patches/unapplied/{ => server}/0972-Add-missing-fishing-event-state.patch (100%) rename patches/unapplied/{ => server}/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch (100%) rename patches/unapplied/{ => server}/0974-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch (100%) rename patches/unapplied/{ => server}/0975-Adopt-MaterialRerouting.patch (100%) rename patches/unapplied/{ => server}/0976-Suspicious-Effect-Entry-API.patch (100%) rename patches/unapplied/{ => server}/0977-check-if-itemstack-is-stackable-first.patch (100%) rename patches/unapplied/{ => server}/0978-Fix-removing-recipes-from-RecipeIterator.patch (100%) rename patches/unapplied/{ => server}/0979-Configurable-damage-tick-when-blocking-with-shield.patch (100%) rename patches/unapplied/{ => server}/0980-Properly-remove-the-experimental-smithing-inventory-.patch (100%) rename patches/unapplied/{ => server}/0981-Moonrise-optimisation-patches.patch (100%) rename patches/unapplied/{ => server}/0982-Rewrite-dataconverter-system.patch (100%) rename patches/unapplied/{ => server}/0983-disable-forced-empty-world-ticks.patch (100%) rename patches/unapplied/{ => server}/0984-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch (100%) rename patches/unapplied/{ => server}/0985-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch (100%) rename patches/unapplied/{ => server}/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch (100%) rename patches/unapplied/{ => server}/0987-Optimize-Network-Manager-and-add-advanced-packet-sup.patch (100%) rename patches/unapplied/{ => server}/0988-Allow-Saving-of-Oversized-Chunks.patch (100%) rename patches/unapplied/{ => server}/0989-Flat-bedrock-generator-settings.patch (100%) rename patches/unapplied/{ => server}/0990-Entity-Activation-Range-2.0.patch (100%) rename patches/unapplied/{ => server}/0991-Optional-per-player-mob-spawns.patch (100%) rename patches/unapplied/{ => server}/0992-Anti-Xray.patch (100%) rename patches/unapplied/{ => server}/0993-Eigencraft-redstone-implementation.patch (100%) rename patches/unapplied/{ => server}/0994-Add-Alternate-Current-redstone-implementation.patch (100%) rename patches/unapplied/{ => server}/0995-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch (100%) rename patches/unapplied/{ => server}/0996-Use-Velocity-compression-and-cipher-natives.patch (100%) rename patches/unapplied/{ => server}/0997-Optimize-Collision-to-not-load-chunks.patch (100%) rename patches/unapplied/{ => server}/0998-Optimize-GoalSelector-Goal.Flag-Set-operations.patch (100%) rename patches/unapplied/{ => server}/0999-Optimize-Hoppers.patch (100%) rename patches/unapplied/{ => server}/1000-Entity-load-save-limit-per-chunk.patch (100%) rename patches/unapplied/{ => server}/1001-Optimize-Voxel-Shape-Merging.patch (100%) rename patches/unapplied/{ => server}/1002-Optimize-Bit-Operations-by-inlining.patch (100%) rename patches/unapplied/{ => server}/1003-Remove-streams-from-hot-code.patch (100%) rename patches/unapplied/{ => server}/1004-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch (100%) rename patches/unapplied/{ => server}/1005-Custom-table-implementation-for-blockstate-state-loo.patch (100%) rename patches/unapplied/{ => server}/1006-Fix-entity-type-tags-suggestions-in-selectors.patch (100%) rename patches/unapplied/{ => server}/1007-Handle-Oversized-block-entities-in-chunks.patch (100%) rename patches/unapplied/{ => server}/1008-API-for-checking-sent-chunks.patch (100%) rename patches/unapplied/{ => server}/1009-Check-distance-in-entity-interactions.patch (100%) rename patches/unapplied/{ => server}/1010-Configurable-Sand-Duping.patch (100%) rename patches/unapplied/{ => server}/1011-Optimise-general-POI-access.patch (100%) rename patches/unapplied/{ => server}/1012-Improve-performance-of-mass-crafts.patch (100%) rename patches/unapplied/{ => server}/1013-Properly-resend-entities.patch (100%) rename patches/unapplied/{ => server}/1014-Registry-Modification-API.patch (100%) rename patches/unapplied/{ => server}/1015-Add-registry-entry-and-builders.patch (100%) rename patches/unapplied/{ => server}/1016-Improved-Watchdog-Support.patch (100%) rename patches/unapplied/{ => server}/1017-Proxy-ItemStack-to-CraftItemStack.patch (100%) rename patches/unapplied/{ => server}/1018-Make-a-PDC-view-accessible-directly-from-ItemStack.patch (100%) rename patches/unapplied/{ => server}/1019-Prioritize-Minecraft-commands-in-function-parsing-an.patch (100%) rename patches/unapplied/{ => server}/1020-optimize-dirt-and-snow-spreading.patch (100%) rename patches/unapplied/{ => server}/1021-Fix-NPE-for-Jukebox-setRecord.patch (100%) rename patches/unapplied/{ => server}/1022-Fix-CraftWorld-isChunkGenerated.patch (100%) rename patches/unapplied/{ => server}/1023-fix-horse-inventories.patch (100%) rename patches/unapplied/{ => server}/1024-Only-call-EntityDamageEvents-before-actuallyHurt.patch (100%) rename patches/unapplied/{ => server}/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch (100%) rename patches/unapplied/{ => server}/1026-Lag-compensation-ticks.patch (100%) rename patches/unapplied/{ => server}/1027-Detail-more-information-in-watchdog-dumps.patch (100%) rename patches/unapplied/{ => server}/1028-Write-SavedData-IO-async.patch (100%) rename patches/unapplied/{ => server}/1029-Add-ItemType-getItemRarity.patch (100%) rename patches/unapplied/{ => server}/1030-Incremental-chunk-and-player-saving.patch (100%) rename patches/unapplied/{ => server}/1031-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch (100%) rename patches/unapplied/{ => server}/1032-Bundle-spark.patch (100%) rename patches/unapplied/{ => server}/1033-Add-plugin-info-at-startup.patch (100%) rename patches/unapplied/{ => server}/1034-Make-interaction-leniency-distance-configurable.patch (100%) rename patches/unapplied/{ => server}/1035-Fix-PickupStatus-getting-reset.patch (100%) rename patches/unapplied/{ => server}/1036-Check-for-block-type-in-SculkSensorBlock-canActivate.patch (100%) rename patches/unapplied/{ => server}/1037-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch (100%) rename patches/unapplied/{ => server}/1038-Configuration-for-horizontal-only-item-merging.patch (100%) rename patches/unapplied/{ => server}/1039-Optimise-collision-checking-in-player-move-packet-ha.patch (100%) rename patches/unapplied/{ => server}/1040-Add-skipping-world-symlink-scan.patch (100%) rename patches/unapplied/{ => server}/1041-Add-even-more-Enchantment-API.patch (100%) rename patches/unapplied/{ => server}/1042-Leashable-API.patch (100%) rename patches/unapplied/{ => server}/1043-Fix-CraftBukkit-drag-system.patch (100%) rename patches/unapplied/{ => server}/1044-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch (100%) rename patches/unapplied/{ => server}/1045-Remove-set-damage-lootable-item-function-from-compas.patch (100%) rename patches/unapplied/{ => server}/1046-Properly-destroy-placed-blocks-on-the-end-platform.patch (100%) rename patches/unapplied/{ => server}/1047-Add-enchantment-seed-update-API.patch (100%) rename patches/unapplied/{ => server}/1048-Fix-synchronise-sending-chat-to-client-with-updating.patch (100%) rename patches/unapplied/{ => server}/1049-Fix-InventoryOpenEvent-cancellation.patch (100%) rename patches/unapplied/{ => server}/1050-Fire-BlockExpEvent-on-grindstone-use.patch (100%) rename patches/unapplied/{ => server}/1051-Check-dead-flag-in-isAlive.patch (100%) rename patches/unapplied/{ => server}/1052-Add-FeatureFlag-API.patch (100%) rename patches/unapplied/{ => server}/1053-Tag-Lifecycle-Events.patch (100%) rename patches/unapplied/{ => server}/1054-Item-serialization-as-json.patch (100%) rename patches/unapplied/{ => server}/1055-Validate-slot-in-PlayerInventory-setSlot.patch (100%) rename patches/unapplied/{ => server}/1056-Remove-wall-time-unused-skip-tick-protection.patch (100%) rename patches/unapplied/{ => server}/1057-Disable-pretty-printing-for-advancement-saving.patch (100%) rename patches/unapplied/{ => server}/1058-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch (100%) rename patches/unapplied/{ => server}/1059-Add-enchantWithLevels-with-enchantment-registry-set.patch (100%) rename patches/unapplied/{ => server}/1060-Improve-entity-effect-API.patch (100%) rename patches/unapplied/{ => server}/1061-Add-recipeBrewTime.patch (100%) rename patches/unapplied/{ => server}/1062-Call-bucket-events-for-cauldrons.patch (100%) rename patches/unapplied/{ => server}/1063-Add-PlayerInsertLecternBookEvent.patch (100%) rename patches/unapplied/{ => server}/1064-Void-damage-configuration-API.patch (100%) rename patches/unapplied/{ => server}/1065-Add-Offline-PDC-API.patch (100%) rename patches/unapplied/{ => server}/1066-Add-AnvilView-bypassEnchantmentLevelRestriction.patch (100%) rename patches/unapplied/{ => server}/1067-Add-proper-async-player-disconnections.patch (100%) rename patches/unapplied/{ => server}/1068-Always-send-Banner-patterns-to-the-client.patch (100%) rename patches/unapplied/{ => server}/9999-Optimise-nearby-player-retrieval.patch (100%) create mode 100644 todo.txt diff --git a/build.gradle.kts b/build.gradle.kts index c3d335bfce18..0182b94ed1e4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -67,7 +67,7 @@ repositories { } dependencies { - paramMappings("net.fabricmc:yarn:1.21.1+build.3:mergedv2") + paramMappings("net.fabricmc:yarn:1.21.2+build.1:mergedv2") remapper("net.fabricmc:tiny-remapper:0.10.3:fat") decompiler("org.vineflower:vineflower:1.10.1") spigotDecompiler("io.papermc:patched-spigot-fernflower:0.1+build.13") diff --git a/patches/server/0001-Setup-Gradle-project.patch b/patches/server/0001-Setup-Gradle-project.patch index 6ff6ed67af70..7a3394e24690 100644 --- a/patches/server/0001-Setup-Gradle-project.patch +++ b/patches/server/0001-Setup-Gradle-project.patch @@ -28,7 +28,7 @@ index 37dab9e868dbfb019c271a547d975a48ad1cb571..3811c0d849a3eb028ed1a6b7a2d4747f +/.factorypath diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 -index 0000000000000000000000000000000000000000..82b298d454dee6a6d996aa7822dd745e70a8da74 +index 0000000000000000000000000000000000000000..6ef457b8ea6ff9b89cb74ecbdca20731d9f94e97 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,131 @@ @@ -47,8 +47,8 @@ index 0000000000000000000000000000000000000000..82b298d454dee6a6d996aa7822dd745e + } + implementation("org.ow2.asm:asm-commons:9.7.1") + implementation("commons-lang:commons-lang:2.6") -+ runtimeOnly("org.xerial:sqlite-jdbc:3.46.0.0") -+ runtimeOnly("com.mysql:mysql-connector-j:8.4.0") ++ runtimeOnly("org.xerial:sqlite-jdbc:3.46.1.3") ++ runtimeOnly("com.mysql:mysql-connector-j:9.1.0") + + runtimeOnly("org.apache.maven:maven-resolver-provider:3.9.6") + runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18") @@ -62,7 +62,7 @@ index 0000000000000000000000000000000000000000..82b298d454dee6a6d996aa7822dd745e +} + +paperweight { -+ craftBukkitPackageVersion.set("v1_21_R1") // also needs to be updated in MappingEnvironment ++ craftBukkitPackageVersion.set("v1_21_R2") // also needs to be updated in MappingEnvironment +} + +tasks.jar { @@ -165,10 +165,10 @@ index 0000000000000000000000000000000000000000..82b298d454dee6a6d996aa7822dd745e +} diff --git a/pom.xml b/pom.xml deleted file mode 100644 -index 71a22e50d5e543d41b0d285fabfa0965a393ab2e..0000000000000000000000000000000000000000 +index da3dad9b745635f2f4b3dd30350070cace3dfc48..0000000000000000000000000000000000000000 --- a/pom.xml +++ /dev/null -@@ -1,612 +0,0 @@ +@@ -1,691 +0,0 @@ - - 4.0.0 @@ -192,7 +192,7 @@ index 71a22e50d5e543d41b0d285fabfa0965a393ab2e..00000000000000000000000000000000 - UTF-8 - unknown - git -- 1_21_R1 +- 1_21_R2 - 21 - - @@ -235,7 +235,25 @@ index 71a22e50d5e543d41b0d285fabfa0965a393ab2e..00000000000000000000000000000000 - 9.7.1 - compile - -- +- +- +- com.fasterxml.jackson.core +- jackson-annotations +- 2.13.4 +- compile +- +- +- com.fasterxml.jackson.core +- jackson-core +- 2.13.4 +- compile +- +- +- com.fasterxml.jackson.core +- jackson-databind +- 2.13.4.2 +- compile +- - - com.github.oshi - oshi-core @@ -243,15 +261,27 @@ index 71a22e50d5e543d41b0d285fabfa0965a393ab2e..00000000000000000000000000000000 - compile - - +- com.github.stephenc.jcip +- jcip-annotations +- 1.0-1 +- compile +- +- +- com.microsoft.azure +- msal4j +- 1.15.0 +- compile +- +- - com.mojang - authlib -- 6.0.54 +- 6.0.55 - compile - - - com.mojang - brigadier -- 1.2.9 +- 1.3.10 - compile - - @@ -262,8 +292,38 @@ index 71a22e50d5e543d41b0d285fabfa0965a393ab2e..00000000000000000000000000000000 - - - com.mojang +- jtracy +- 1.0.29 +- compile +- +- +- com.mojang - logging -- 1.2.7 +- 1.4.9 +- compile +- +- +- com.nimbusds +- content-type +- 2.3 +- compile +- +- +- com.nimbusds +- lang-tag +- 1.7 +- compile +- +- +- com.nimbusds +- nimbus-jose-jwt +- 9.37.3 +- compile +- +- +- com.nimbusds +- oauth2-oidc-sdk +- 11.9.1 - compile - - @@ -353,6 +413,18 @@ index 71a22e50d5e543d41b0d285fabfa0965a393ab2e..00000000000000000000000000000000 - compile - - +- net.minidev +- accessors-smart +- 2.5.0 +- compile +- +- +- net.minidev +- json-smart +- 2.5.0 +- compile +- +- - net.sf.jopt-simple - jopt-simple - 5.0.4 @@ -366,20 +438,20 @@ index 71a22e50d5e543d41b0d285fabfa0965a393ab2e..00000000000000000000000000000000 - - - org.apache.logging.log4j -- log4j-core +- log4j-api - 2.22.1 - compile - - - org.apache.logging.log4j -- log4j-slf4j2-impl +- log4j-core - 2.22.1 - compile - - -- org.slf4j -- slf4j-api -- 2.0.9 +- org.apache.logging.log4j +- log4j-slf4j2-impl +- 2.22.1 - compile - - @@ -388,6 +460,13 @@ index 71a22e50d5e543d41b0d285fabfa0965a393ab2e..00000000000000000000000000000000 - 1.8.0 - compile - +- +- org.slf4j +- slf4j-api +- 2.0.9 +- compile +- +- - - - commons-lang @@ -411,13 +490,13 @@ index 71a22e50d5e543d41b0d285fabfa0965a393ab2e..00000000000000000000000000000000 - - org.xerial - sqlite-jdbc -- 3.46.0.0 +- 3.46.1.3 - runtime - - - com.mysql - mysql-connector-j -- 8.4.0 +- 9.1.0 - runtime - - diff --git a/patches/unapplied/0002-Remap-fixes.patch b/patches/server/0002-Remap-fixes.patch similarity index 95% rename from patches/unapplied/0002-Remap-fixes.patch rename to patches/server/0002-Remap-fixes.patch index d128af05d76f..50ea8b2aa780 100644 --- a/patches/unapplied/0002-Remap-fixes.patch +++ b/patches/server/0002-Remap-fixes.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Remap fixes diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java -index 766006fe7ff965d6ca17df1df457ecc629b3be18..0ef1a7b2a17e81144d594f29f7b5e54d5038dcf4 100644 +index e8b604659cec5a1b09e93dd7c5166d627aa2fe3d..115cb27d3233863692553f8e07238c74b0fcb61c 100644 --- a/src/main/java/net/minecraft/core/BlockPos.java +++ b/src/main/java/net/minecraft/core/BlockPos.java @@ -323,9 +323,11 @@ public class BlockPos extends Vec3i { @@ -59,7 +59,7 @@ index 7344cff32fa6fe3dedb74ed98126072c55b0abd2..d98b28e9488a5a7736719cf656736bb0 } else { entityliving1 = null; diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java b/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java -index 9051f0186c09eeb8ecccf62b0116f6da1800a1df..b231f90317fe7df9133674b12d47873520b481cb 100644 +index f3a2612f0e27c36d5206334307eac1880ce8c4b7..4d4d413b8527e1a109276928611b8c857ad6f6aa 100644 --- a/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java +++ b/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java @@ -259,8 +259,8 @@ public class LootTable { @@ -70,7 +70,7 @@ index 9051f0186c09eeb8ecccf62b0116f6da1800a1df..b231f90317fe7df9133674b12d478735 - private final Builder functions = ImmutableList.builder(); + private final ImmutableList.Builder pools = ImmutableList.builder(); + private final ImmutableList.Builder functions = ImmutableList.builder(); - private LootContextParamSet paramSet; + private ContextKeySet paramSet; private Optional randomSequence; diff --git a/src/test/java/org/bukkit/DyeColorsTest.java b/src/test/java/org/bukkit/DyeColorsTest.java @@ -104,10 +104,10 @@ index e96d821da0698dd42651500fb97a0856a9e9ce02..fb7d40181abdaa5b2ce607db47c09d0d } } diff --git a/src/test/java/org/bukkit/ParticleTest.java b/src/test/java/org/bukkit/ParticleTest.java -index 688c5bae8146f6fc8cddb2632e9cbf304f0745fb..1b0df6220682328b8f1d03416cb8df2f6662a1cf 100644 +index ab72aeeec64c284ea42ac1542f55fd33d314effb..e2a03301073aced927244b07fe86f2de043e40a3 100644 --- a/src/test/java/org/bukkit/ParticleTest.java +++ b/src/test/java/org/bukkit/ParticleTest.java -@@ -251,7 +251,7 @@ public class ParticleTest { +@@ -279,7 +279,7 @@ public class ParticleTest { Check in CraftParticle if the conversion is still correct. """, bukkit.getKey())); @@ -172,7 +172,7 @@ index 4a3ac959f0dcc35f80371443383be1f8b42b6d95..e8520f541fda2d1cd9677f3fc7d7d295 assertNotNull(bukkit, "Bukkit gene null for " + gene); diff --git a/src/test/java/org/bukkit/registry/RegistryConstantsTest.java b/src/test/java/org/bukkit/registry/RegistryConstantsTest.java -index a382ca7c6e0f96e5d8be37fa8139360db13f9c2f..8fb906c77070eedec8cde263154eaf4610ad3197 100644 +index 9654a6b8d583c9c8842b14298e2f697761bdd705..dbd5b8684d4c86ff5a6f20f53fe30d0b30c384bf 100644 --- a/src/test/java/org/bukkit/registry/RegistryConstantsTest.java +++ b/src/test/java/org/bukkit/registry/RegistryConstantsTest.java @@ -31,17 +31,17 @@ public class RegistryConstantsTest { diff --git a/patches/unapplied/0003-Build-system-changes.patch b/patches/server/0003-Build-system-changes.patch similarity index 95% rename from patches/unapplied/0003-Build-system-changes.patch rename to patches/server/0003-Build-system-changes.patch index 4e78b9dbf694..31918d8713cb 100644 --- a/patches/unapplied/0003-Build-system-changes.patch +++ b/patches/server/0003-Build-system-changes.patch @@ -9,7 +9,7 @@ public net.minecraft.server.packs.VanillaPackResourcesBuilder safeGetPath(Ljava/ Co-authored-by: Jake Potrebic diff --git a/build.gradle.kts b/build.gradle.kts -index 82b298d454dee6a6d996aa7822dd745e70a8da74..ef88afa5fe914ae3fef9ffb1a971dabf568f75f3 100644 +index 6ef457b8ea6ff9b89cb74ecbdca20731d9f94e97..d4a5229b4df544ff60cdaee80c8ae301faf2a235 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,9 +8,7 @@ plugins { @@ -22,7 +22,7 @@ index 82b298d454dee6a6d996aa7822dd745e70a8da74..ef88afa5fe914ae3fef9ffb1a971dabf + implementation("org.apache.logging.log4j:log4j-iostreams:2.22.1") // Paper - remove exclusion implementation("org.ow2.asm:asm-commons:9.7.1") implementation("commons-lang:commons-lang:2.6") - runtimeOnly("org.xerial:sqlite-jdbc:3.46.0.0") + runtimeOnly("org.xerial:sqlite-jdbc:3.46.1.3") @@ -39,6 +37,7 @@ tasks.jar { val gitHash = git("rev-parse", "--short=7", "HEAD").getText().trim() val implementationVersion = System.getenv("BUILD_NUMBER") ?: "\"$gitHash\"" @@ -131,7 +131,7 @@ index feca36209fd2405fab70f564f63e627b8b78ac18..396ec10a76bdadbf5be2f0e15e88eed4 public static PackRepository createPackRepository(Path dataPacksPath, DirectoryValidator symlinkFinder) { diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index dd64f5c16560d2ce6255c8319ddd0f5157237f0f..4566237fa1d49a559b2df806f9a318be46a6eade 100644 +index ec2854226de69ce87e1a9bb0b5483775ed192044..17e10c4373b4281cc74b748c4a1e173e36eb9196 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -199,7 +199,7 @@ public class Main { @@ -142,7 +142,7 @@ index dd64f5c16560d2ce6255c8319ddd0f5157237f0f..4566237fa1d49a559b2df806f9a318be + Date buildDate = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z").parse(Main.class.getPackage().getImplementationVendor()); // Paper Calendar deadline = Calendar.getInstance(); - deadline.add(Calendar.DAY_OF_YEAR, -28); + deadline.add(Calendar.DAY_OF_YEAR, -3); diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java index 93046379d0cefd5d3236fc59e698809acdc18f80..774556a62eb240da42e84db4502e2ed43495be17 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java @@ -172,10 +172,10 @@ index 0000000000000000000000000000000000000000..288fbe68c6053f40e72f0feedef0ae0f + } +} diff --git a/src/test/java/org/bukkit/support/RegistryHelper.java b/src/test/java/org/bukkit/support/RegistryHelper.java -index e5dbcdcbd4187c724c3c6a3b8141a3796710c7a8..73645ea2e5c17e973ed3b888aab56f733f9c87a3 100644 +index f9ed3fd96cb7474785610fe0f87e550456349287..5781c2fab2d407b4a22d5fc80e1c03e907617316 100644 --- a/src/test/java/org/bukkit/support/RegistryHelper.java +++ b/src/test/java/org/bukkit/support/RegistryHelper.java -@@ -58,6 +58,7 @@ public final class RegistryHelper { +@@ -70,6 +70,7 @@ public final class RegistryHelper { } public static void setup(FeatureFlagSet featureFlagSet) { diff --git a/patches/unapplied/0004-Test-changes.patch b/patches/server/0004-Test-changes.patch similarity index 89% rename from patches/unapplied/0004-Test-changes.patch rename to patches/server/0004-Test-changes.patch index 85407ece86ce..adf6660553f9 100644 --- a/patches/unapplied/0004-Test-changes.patch +++ b/patches/server/0004-Test-changes.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Test changes Co-authored-by: yannnicklamprecht diff --git a/build.gradle.kts b/build.gradle.kts -index ef88afa5fe914ae3fef9ffb1a971dabf568f75f3..3c1770864ab3e8708bab6cd50d6ffb5e19af5399 100644 +index d4a5229b4df544ff60cdaee80c8ae301faf2a235..41b000aaa71dca3fb392ae657be16e05bd37a178 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -23,6 +23,7 @@ dependencies { @@ -352,7 +352,7 @@ index ee5ab15bb0bfeb0ff6fa0d720eeff086d92cb459..7419ea2f68607aad27929a608c402bd4 @Test diff --git a/src/test/java/org/bukkit/registry/RegistryClassTest.java b/src/test/java/org/bukkit/registry/RegistryClassTest.java -index 740073ddd99b5e6aba056b99d5ed3e2a94a13b6c..575a06125e0b60b5bb8b6f85131f7d6cf86f5083 100644 +index 297700b237bbd8d5ff9116919f203c82b4037968..ea3d37f387bdb0dd5ae3fba9231ace31d0cebd64 100644 --- a/src/test/java/org/bukkit/registry/RegistryClassTest.java +++ b/src/test/java/org/bukkit/registry/RegistryClassTest.java @@ -57,6 +57,7 @@ import org.objectweb.asm.Type; @@ -364,7 +364,7 @@ index 740073ddd99b5e6aba056b99d5ed3e2a94a13b6c..575a06125e0b60b5bb8b6f85131f7d6c private static final Map, Data> INIT_DATA = new HashMap<>(); diff --git a/src/test/java/org/bukkit/registry/RegistryConstantsTest.java b/src/test/java/org/bukkit/registry/RegistryConstantsTest.java -index 8fb906c77070eedec8cde263154eaf4610ad3197..8705ee2a28d5dba7bb579eae1436451502e1e3c2 100644 +index dbd5b8684d4c86ff5a6f20f53fe30d0b30c384bf..7848c3bb78356f74e7e2cb708308626baa708b1f 100644 --- a/src/test/java/org/bukkit/registry/RegistryConstantsTest.java +++ b/src/test/java/org/bukkit/registry/RegistryConstantsTest.java @@ -26,7 +26,7 @@ public class RegistryConstantsTest { @@ -377,7 +377,7 @@ index 8fb906c77070eedec8cde263154eaf4610ad3197..8705ee2a28d5dba7bb579eae14364515 @Test diff --git a/src/test/java/org/bukkit/support/DummyServerHelper.java b/src/test/java/org/bukkit/support/DummyServerHelper.java -index 6ecafd167d4d8c79f2cbc43ea9da98a5d61d8751..f81f86cf05a8c6816d356185af6d0d84a0474dd2 100644 +index a678510df2b999b78d0b4d233fd15bf444c97080..0a6ba289a94468b67d282a199250142e1e86f075 100644 --- a/src/test/java/org/bukkit/support/DummyServerHelper.java +++ b/src/test/java/org/bukkit/support/DummyServerHelper.java @@ -47,7 +47,7 @@ public final class DummyServerHelper { @@ -395,7 +395,7 @@ index 6ecafd167d4d8c79f2cbc43ea9da98a5d61d8751..f81f86cf05a8c6816d356185af6d0d84 Preconditions.checkArgument(clazz == org.bukkit.Fluid.class, "Fluid namespace must have fluid type"); - TagKey fluidTagKey = TagKey.create(Registries.FLUID, key); + TagKey fluidTagKey = TagKey.create(Registries.FLUID, key); // Paper - address remapping issues - if (BuiltInRegistries.FLUID.getTag(fluidTagKey).isPresent()) { + if (BuiltInRegistries.FLUID.get(fluidTagKey).isPresent()) { return new CraftFluidTag(BuiltInRegistries.FLUID, fluidTagKey); } } @@ -403,7 +403,7 @@ index 6ecafd167d4d8c79f2cbc43ea9da98a5d61d8751..f81f86cf05a8c6816d356185af6d0d84 Preconditions.checkArgument(clazz == org.bukkit.entity.EntityType.class, "Entity type namespace must have entity type"); - TagKey> entityTagKey = TagKey.create(Registries.ENTITY_TYPE, key); + TagKey> entityTagKey = TagKey.create(Registries.ENTITY_TYPE, key); // Paper - address remapping issues - if (BuiltInRegistries.ENTITY_TYPE.getTag(entityTagKey).isPresent()) { + if (BuiltInRegistries.ENTITY_TYPE.get(entityTagKey).isPresent()) { return new CraftEntityTag(BuiltInRegistries.ENTITY_TYPE, entityTagKey); } } @@ -425,18 +425,30 @@ index 6ecafd167d4d8c79f2cbc43ea9da98a5d61d8751..f81f86cf05a8c6816d356185af6d0d84 } } diff --git a/src/test/java/org/bukkit/support/RegistryHelper.java b/src/test/java/org/bukkit/support/RegistryHelper.java -index 73645ea2e5c17e973ed3b888aab56f733f9c87a3..4d169ff3541044d447de519d2b0973da98b0bd53 100644 +index 5781c2fab2d407b4a22d5fc80e1c03e907617316..68ae998b30bbcacae3604fb6581ceca3da1eda18 100644 --- a/src/test/java/org/bukkit/support/RegistryHelper.java +++ b/src/test/java/org/bukkit/support/RegistryHelper.java -@@ -98,6 +98,11 @@ public final class RegistryHelper { - private static LayeredRegistryAccess createLayers(MultiPackResourceManager resourceManager) { - // add tags and loot tables for unit tests - LayeredRegistryAccess layers = RegistryLayer.createRegistryAccess(); +@@ -65,6 +65,11 @@ public final class RegistryHelper { + List> list1 = TagLoader.buildUpdatedLookups(iregistrycustom_dimension, list); + RegistryAccess.Frozen iregistrycustom_dimension1 = RegistryDataLoader.load((ResourceManager) ireloadableresourcemanager, list1, RegistryDataLoader.WORLDGEN_REGISTRIES); + LayeredRegistryAccess layers = layeredregistryaccess.replaceFrom(RegistryLayer.WORLDGEN, iregistrycustom_dimension1); + // Paper start - load registry here to ensure bukkit object registry are correctly delayed if needed + try { + Class.forName("org.bukkit.Registry"); + } catch (final ClassNotFoundException ignored) {} + // Paper end - load registry here to ensure bukkit object registry are correctly delayed if needed - layers = WorldLoader.loadAndReplaceLayer(resourceManager, layers, RegistryLayer.WORLDGEN, RegistryDataLoader.WORLDGEN_REGISTRIES); - return layers; + return layers.compositeAccess().freeze(); + } +@@ -82,6 +87,11 @@ public final class RegistryHelper { + List> list1 = TagLoader.buildUpdatedLookups(iregistrycustom_dimension, list); + RegistryAccess.Frozen iregistrycustom_dimension1 = RegistryDataLoader.load((ResourceManager) ireloadableresourcemanager, list1, RegistryDataLoader.WORLDGEN_REGISTRIES); + LayeredRegistryAccess layers = layeredregistryaccess.replaceFrom(RegistryLayer.WORLDGEN, iregistrycustom_dimension1); ++ // Paper start - load registry here to ensure bukkit object registry are correctly delayed if needed ++ try { ++ Class.forName("org.bukkit.Registry"); ++ } catch (final ClassNotFoundException ignored) {} ++ // Paper end - load registry here to ensure bukkit object registry are correctly delayed if needed + RegistryHelper.registry = layers.compositeAccess().freeze(); + // Register vanilla pack + RegistryHelper.dataPack = ReloadableServerResources.loadResources(ireloadableresourcemanager, layers, list, featureFlagSet, Commands.CommandSelection.DEDICATED, 0, MoreExecutors.directExecutor(), MoreExecutors.directExecutor()).join(); diff --git a/patches/unapplied/0005-Paper-config-files.patch b/patches/server/0005-Paper-config-files.patch similarity index 98% rename from patches/unapplied/0005-Paper-config-files.patch rename to patches/server/0005-Paper-config-files.patch index ecc645f20648..e7ff1d0a2216 100644 --- a/patches/unapplied/0005-Paper-config-files.patch +++ b/patches/server/0005-Paper-config-files.patch @@ -15,7 +15,7 @@ public net.minecraft.server.dedicated.DedicatedServerProperties reload(Lnet/mine public net.minecraft.world.level.NaturalSpawner SPAWNING_CATEGORIES diff --git a/build.gradle.kts b/build.gradle.kts -index 2233e51bfab4ac36977984e8fe7fddb04120dddd..7f7b7f0b29107375b2438e3af0bc0f40390db4fa 100644 +index 41b000aaa71dca3fb392ae657be16e05bd37a178..da6b4787fa787e098e4031790e955ce616593ee9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,6 +10,7 @@ dependencies { @@ -24,8 +24,8 @@ index 2233e51bfab4ac36977984e8fe7fddb04120dddd..7f7b7f0b29107375b2438e3af0bc0f40 implementation("org.ow2.asm:asm-commons:9.7.1") + implementation("org.spongepowered:configurate-yaml:4.2.0-SNAPSHOT") // Paper - config files implementation("commons-lang:commons-lang:2.6") - runtimeOnly("org.xerial:sqlite-jdbc:3.46.0.0") - runtimeOnly("com.mysql:mysql-connector-j:8.4.0") + runtimeOnly("org.xerial:sqlite-jdbc:3.46.1.3") + runtimeOnly("com.mysql:mysql-connector-j:9.1.0") diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..ef41cf3a7d1e6f2bfe81e0fb865d2f969bbc77c1 @@ -5074,7 +5074,7 @@ index 0000000000000000000000000000000000000000..614aba60bb07946a144650fd3aedb316 + protected abstract boolean belowZero(O value); +} diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index b334265d4015fec13d7fedbffba2b6c22f4c8bc8..5b4ac7b4fd0077e900e9f788963f1613bbc9a5d0 100644 +index fc5c42e77a76b0ca946b13435144584b9c4bfafa..9bd6056bba6ba48bada7e9cd5883b0a171b0bbc4 100644 --- a/src/main/java/net/minecraft/server/Main.java +++ b/src/main/java/net/minecraft/server/Main.java @@ -129,6 +129,10 @@ public class Main { @@ -5098,10 +5098,10 @@ index b334265d4015fec13d7fedbffba2b6c22f4c8bc8..5b4ac7b4fd0077e900e9f788963f1613 String s = (String) Optional.ofNullable((String) optionset.valueOf("world")).orElse(dedicatedserversettings.getProperties().levelName); LevelStorageSource convertable = LevelStorageSource.createDefault(file.toPath()); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index db2031ffbc802bd850ab40acaec2a9624b753f4c..299afe72a2fc2affca196f2fdfbf27e5533c51a6 100644 +index c54fae06acd566742cea3aef537ad1b4e2b7414a..3fc0abef2c4e2c8ceb3b8c4f02c59700aa3d0803 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -309,6 +309,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); -@@ -405,6 +406,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules()))); // Paper - create paper world configs + // Add env and gen to constructor, IWorldDataServer -> WorldDataServer + public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { +- super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env); ++ super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules()))); // Paper - create paper world configs this.pvpMode = minecraftserver.isPvpAllowed(); this.convertable = convertable_conversionsession; this.uuid = WorldUUID.getUUID(convertable_conversionsession.levelDirectory.path().toFile()); diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index e433037a03ffafabb952887ae3980e1d51411d4c..c061813d275fbc48d7629cc59d90dbb4c347516c 100644 +index 9cf0c141fefe67893828e300cba4f8a8545ba25f..c8e49c1904c80c4ede40ca5c26efad9b12e247d1 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -156,6 +156,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -157,6 +157,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public final it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap ticksPerSpawnCategory = new it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<>(); public boolean populating; public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot @@ -5214,31 +5214,31 @@ index e433037a03ffafabb952887ae3980e1d51411d4c..c061813d275fbc48d7629cc59d90dbb4 public final SpigotTimings.WorldTimingsHandler timings; // Spigot public static BlockPos lastPhysicsProblem; // Spigot -@@ -173,8 +179,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -174,8 +180,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public abstract ResourceKey getTypeKey(); -- protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env) { -+ protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator) { // Paper - create paper world config +- protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env) { ++ protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator) { // Paper - create paper world config this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot + this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config this.generator = gen; this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 357c948dd66644497583996f211f25cbe5c78828..d0c41302478bd9b0ec65020e7ef520bd3ff1f347 100644 +index c48b1d5fc73a98eb4967632d8e6e0744961a688f..3882ae04173cd125fe490692a6bc2b4d8b20ff7b 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -964,6 +964,7 @@ public final class CraftServer implements Server { +@@ -967,6 +967,7 @@ public final class CraftServer implements Server { } org.spigotmc.SpigotConfig.init((File) this.console.options.valueOf("spigot-settings")); // Spigot + this.console.paperConfigurations.reloadConfigs(this.console); for (ServerLevel world : this.console.getAllLevels()) { world.serverLevelData.setDifficulty(config.difficulty); - world.setSpawnSettings(config.spawnMonsters, config.spawnAnimals); + world.setSpawnSettings(config.spawnMonsters); diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 4566237fa1d49a559b2df806f9a318be46a6eade..0ea2d13ab80559472513c6df362583b8371a9532 100644 +index 17e10c4373b4281cc74b748c4a1e173e36eb9196..755b1d77418ecae0dc9ec5197275d0cd914e7bee 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -142,6 +142,19 @@ public class Main { @@ -5363,7 +5363,7 @@ index 0000000000000000000000000000000000000000..0396589795da1f83ddf62426236dde9a + } +} diff --git a/src/test/java/org/bukkit/support/DummyServerHelper.java b/src/test/java/org/bukkit/support/DummyServerHelper.java -index f81f86cf05a8c6816d356185af6d0d84a0474dd2..ba0a2ab9de34fa40dd90cecaeec4a5e54fe3e2d8 100644 +index 0a6ba289a94468b67d282a199250142e1e86f075..bdfa164ea21cba91b30b965d65d47112111a1209 100644 --- a/src/test/java/org/bukkit/support/DummyServerHelper.java +++ b/src/test/java/org/bukkit/support/DummyServerHelper.java @@ -91,6 +91,7 @@ public final class DummyServerHelper { diff --git a/patches/unapplied/0006-MC-Dev-fixes.patch b/patches/server/0006-MC-Dev-fixes.patch similarity index 85% rename from patches/unapplied/0006-MC-Dev-fixes.patch rename to patches/server/0006-MC-Dev-fixes.patch index 168146736c83..2f90f68dd262 100644 --- a/patches/unapplied/0006-MC-Dev-fixes.patch +++ b/patches/server/0006-MC-Dev-fixes.patch @@ -17,10 +17,10 @@ index 643bb8860962ad691b11073f6dbf406bf7ec5fb1..9b8ec1fd158f6e51779be263fd56b911 } } diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java -index 0ef1a7b2a17e81144d594f29f7b5e54d5038dcf4..8994a381b05dcdd1163d2e7a0b63a8875b6063ed 100644 +index 115cb27d3233863692553f8e07238c74b0fcb61c..83e7c141d947f8f8096fed1da716560494bc5c62 100644 --- a/src/main/java/net/minecraft/core/BlockPos.java +++ b/src/main/java/net/minecraft/core/BlockPos.java -@@ -439,12 +439,12 @@ public class BlockPos extends Vec3i { +@@ -445,12 +445,12 @@ public class BlockPos extends Vec3i { if (this.index == l) { return this.endOfData(); } else { @@ -39,11 +39,11 @@ index 0ef1a7b2a17e81144d594f29f7b5e54d5038dcf4..8994a381b05dcdd1163d2e7a0b63a887 } }; diff --git a/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java b/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java -index a467eb6b3b74cdb5378ff5f3043efbe6f4a6f06e..34b3b3251da21bce616870d312fd42fd58ba7881 100644 +index 69993496b6328a963288e11d193d36bd7decfcba..f66a2154486b6d3b5873da043e51df91cd396c72 100644 --- a/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java +++ b/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java -@@ -317,7 +317,7 @@ public class BuiltInRegistries { - Bootstrap.checkBootstrapCalled(() -> "registry " + key); +@@ -325,7 +325,7 @@ public class BuiltInRegistries { + Bootstrap.checkBootstrapCalled(() -> "registry " + key.location()); ResourceLocation resourceLocation = key.location(); LOADERS.put(resourceLocation, () -> initializer.run(registry)); - WRITABLE_REGISTRY.register((ResourceKey>)key, registry, RegistrationInfo.BUILT_IN); @@ -71,10 +71,10 @@ index a614e960fcd5958ad17b679eee8a8e6926f58e62..da101bca71f4710812621b98f0a0d8ca if (!this.hasElementSeparator()) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 299afe72a2fc2affca196f2fdfbf27e5533c51a6..40adb6117b9e0d5f70103113202a07715e403e2a 100644 +index 3fc0abef2c4e2c8ceb3b8c4f02c59700aa3d0803..8e16bc7da15824723f1d7d4bff87fac181978500 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1952,7 +1952,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoopmap(resourcepackrepository::getPack).filter(Objects::nonNull).map(Pack::open).collect(ImmutableList.toImmutableList()); // CraftBukkit - decompile error // Paper - decompile error // todo: is this needed anymore? }, this).thenCompose((immutablelist) -> { MultiPackResourceManager resourcemanager = new MultiPackResourceManager(PackType.SERVER_DATA, immutablelist); - + List> list = TagLoader.loadTagsForExistingRegistries(resourcemanager, this.registries.compositeAccess()); diff --git a/src/main/java/net/minecraft/util/SortedArraySet.java b/src/main/java/net/minecraft/util/SortedArraySet.java index 661a6274a800ca9b91bdb809d026972d23c3b263..ea72dcb064a35bc6245bc5c94d592efedd8faf41 100644 --- a/src/main/java/net/minecraft/util/SortedArraySet.java @@ -97,25 +97,25 @@ index 661a6274a800ca9b91bdb809d026972d23c3b263..ea72dcb064a35bc6245bc5c94d592efe public static SortedArraySet create(Comparator comparator) { diff --git a/src/main/java/net/minecraft/world/entity/monster/Pillager.java b/src/main/java/net/minecraft/world/entity/monster/Pillager.java -index 8eb1aca72df0bca292473e90ecb74159db4fe034..4b4dcee6abe7a6db43638d04665125eec560496e 100644 +index cf025d7a4392213db3cf04e7ace3e2b166e710eb..3e8631c7bd1e7591051ca21c6ae7acd87d3c7529 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Pillager.java +++ b/src/main/java/net/minecraft/world/entity/monster/Pillager.java -@@ -66,7 +66,7 @@ public class Pillager extends AbstractIllager implements CrossbowAttackMob, Inve - protected void registerGoals() { +@@ -69,7 +69,7 @@ public class Pillager extends AbstractIllager implements CrossbowAttackMob, Inve super.registerGoals(); this.goalSelector.addGoal(0, new FloatGoal(this)); + this.goalSelector.addGoal(1, new AvoidEntityGoal<>(this, Creaking.class, 8.0F, 1.0D, 1.2D)); - this.goalSelector.addGoal(2, new Raider.HoldGroundAttackGoal(this, this, 10.0F)); + this.goalSelector.addGoal(2, new Raider.HoldGroundAttackGoal(this, 10.0F)); // Paper - decomp fix this.goalSelector.addGoal(3, new RangedCrossbowAttackGoal<>(this, 1.0D, 8.0F)); this.goalSelector.addGoal(8, new RandomStrollGoal(this, 0.6D)); this.goalSelector.addGoal(9, new LookAtPlayerGoal(this, Player.class, 15.0F, 1.0F)); diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -index e2b72817857a7a203aae4c9de4e01ba1396dc95b..82fc5133325a127890984d51c1381883759eb444 100644 +index 5fa94fd51027901591e40cabdacfd61d16a58585..3f552ee8f90566edddb5943311a14309e4bebb61 100644 --- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java +++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -@@ -153,7 +153,7 @@ public class ChunkStatusTasks { - if (protochunk instanceof ImposterProtoChunk) { - chunk1 = ((ImposterProtoChunk) protochunk).getWrapped(); +@@ -151,7 +151,7 @@ public class ChunkStatusTasks { + if (protochunk instanceof ImposterProtoChunk protochunkextension) { + chunk1 = protochunkextension.getWrapped(); } else { - chunk1 = new LevelChunk(worldserver, protochunk, (chunk1) -> { + chunk1 = new LevelChunk(worldserver, protochunk, ($) -> { // Paper - decompile fix diff --git a/patches/unapplied/0007-ConcurrentUtil.patch b/patches/server/0007-ConcurrentUtil.patch similarity index 100% rename from patches/unapplied/0007-ConcurrentUtil.patch rename to patches/server/0007-ConcurrentUtil.patch diff --git a/patches/unapplied/0008-CB-fixes.patch b/patches/server/0008-CB-fixes.patch similarity index 92% rename from patches/unapplied/0008-CB-fixes.patch rename to patches/server/0008-CB-fixes.patch index 50bdb07720be..ce987eb9e72b 100644 --- a/patches/unapplied/0008-CB-fixes.patch +++ b/patches/server/0008-CB-fixes.patch @@ -19,10 +19,10 @@ Subject: [PATCH] CB fixes Co-authored-by: Spottedleaf diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index a696a0d168987aaa4e59c471a23eeb48d683c1b2..9d11fcb3df12182ae00ce73f7e30091fd199a341 100644 +index a17846ccd8581c3d6da962e977623aaab8314ec7..f6a3606b972064c4ec78487374e6197c0c447e27 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -303,7 +303,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -293,7 +293,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe long l = minecraftserver.getWorldData().worldGenOptions().seed(); @@ -32,7 +32,7 @@ index a696a0d168987aaa4e59c471a23eeb48d683c1b2..9d11fcb3df12182ae00ce73f7e30091f if ((this.dimension() == Level.END && this.dimensionTypeRegistration().is(BuiltinDimensionTypes.END)) || env == org.bukkit.World.Environment.THE_END) { // CraftBukkit - Allow to create EnderDragonBattle in default and custom END this.dragonFight = new EndDragonFight(this, this.serverLevelData.worldGenOptions().seed(), this.serverLevelData.endDragonFightData()); // CraftBukkit diff --git a/src/main/java/net/minecraft/world/item/enchantment/effects/SummonEntityEffect.java b/src/main/java/net/minecraft/world/item/enchantment/effects/SummonEntityEffect.java -index d927357d541cf206bb3019b2fda3473a77b44ec4..4601c7069ba82ccfe87e9dc304b6f3262f7bbfbf 100644 +index ed78039b89884c41ce10d520786c5b56f7d9b154..0239495abcc7b796864976b37ece184efa9a747e 100644 --- a/src/main/java/net/minecraft/world/item/enchantment/effects/SummonEntityEffect.java +++ b/src/main/java/net/minecraft/world/item/enchantment/effects/SummonEntityEffect.java @@ -54,7 +54,7 @@ public record SummonEntityEffect(HolderSet> entityTypes, boolean j @@ -45,7 +45,7 @@ index d927357d541cf206bb3019b2fda3473a77b44ec4..4601c7069ba82ccfe87e9dc304b6f326 } diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java b/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java -index 0dc7f88877020bddd5a84db51d349f52b673048e..aae73586265593ee7830fb8dd5c2e3d7560057f0 100644 +index 4f68394a94308513269f0a4c749b6a36738e3ca0..953ab7638f7242b5a11dd1de8786172443a0558c 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java +++ b/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java @@ -40,7 +40,7 @@ public class StructureCheck { @@ -67,7 +67,7 @@ index 0dc7f88877020bddd5a84db51d349f52b673048e..aae73586265593ee7830fb8dd5c2e3d7 RandomState noiseConfig, LevelHeightAccessor world, diff --git a/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java b/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java -index 85c7f3027978b1d7d6c31b7ad21b3377cdda5925..e34deaf398dc6722c3128bdd6b9bc16da2d33bf7 100644 +index a70e6872add1c952a89e74be0e6d09a53cc16559..90b82ad996b2b85628c9a5ddeef9410150b7f70c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java @@ -187,4 +187,11 @@ public class CraftLootTable implements org.bukkit.loot.LootTable { @@ -83,7 +83,7 @@ index 85c7f3027978b1d7d6c31b7ad21b3377cdda5925..e34deaf398dc6722c3128bdd6b9bc16d + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 0ea2d13ab80559472513c6df362583b8371a9532..13c37384defda4475de584f33d1860a2d53ce05e 100644 +index 755b1d77418ecae0dc9ec5197275d0cd914e7bee..94004204b6cdbbbf35263faae56e3e06cb6b650c 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -123,6 +123,7 @@ public class Main { @@ -95,7 +95,7 @@ index 0ea2d13ab80559472513c6df362583b8371a9532..13c37384defda4475de584f33d1860a2 this.acceptsAll(Main.asList("nojline"), "Disables jline and emulates the vanilla console"); diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -index 905adf97c0d1f0d1c774a6835a5dffcfea884e58..c017ce2ca1bc535795c958a2e509af2adf88efa9 100644 +index 163d54a8bf4cedbd1471e86b7ab1a1b850ed3f39..6effe47b32a8551aa6f6b11bc0315714a119e199 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java @@ -26,6 +26,7 @@ import org.bukkit.scheduler.BukkitWorker; @@ -115,7 +115,7 @@ index 905adf97c0d1f0d1c774a6835a5dffcfea884e58..c017ce2ca1bc535795c958a2e509af2a public class CraftScheduler implements BukkitScheduler { diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index a0f228ee83fd3a913666f88381c946f8a6340644..60dc550431fa4641f8c6d964329b0e2698d1fdd6 100644 +index fc444b734aad2c23f0808cd66fca23fc350d9e10..2392aa50aec6468f2f498e0a806f65013ce963d1 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -246,7 +246,7 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/unapplied/0009-MC-Utils.patch b/patches/server/0009-MC-Utils.patch similarity index 95% rename from patches/unapplied/0009-MC-Utils.patch rename to patches/server/0009-MC-Utils.patch index 59c2e99b59a1..5c84ecfe2d17 100644 --- a/patches/unapplied/0009-MC-Utils.patch +++ b/patches/server/0009-MC-Utils.patch @@ -4288,10 +4288,10 @@ index 0000000000000000000000000000000000000000..f7114d5b8f2f93f62883e24da29afaf9 + } +} diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java -index 5135cd504ec5864a4603c004e748947a7d88d2b4..396f368a7e21a7c7b1630b4e20cdbc452c4b0f84 100644 +index 5b9ca3d968fd4884b1b7f2c06477ae00c09f202e..5d0ef11671beb2381e0e1959f5e5f845789a2982 100644 --- a/src/main/java/net/minecraft/Util.java +++ b/src/main/java/net/minecraft/Util.java -@@ -133,7 +133,7 @@ public class Util { +@@ -136,7 +136,7 @@ public class Util { } public static long getNanos() { @@ -4416,10 +4416,18 @@ index 3e5a85a7ad6149b04622c254fbc2e174896a4128..3f662692ed4846e026a9d48595e7b3b2 + } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 40adb6117b9e0d5f70103113202a07715e403e2a..c9cab509796599b13ca3422de1049aed78348704 100644 +index 8e16bc7da15824723f1d7d4bff87fac181978500..83b32b2963febf8af9ccd7df666cbaccc62f1313 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -973,6 +973,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 4) { + thread.setPriority(8); + } +- + S s0 = serverFactory.apply(thread); // CraftBukkit - decompile error + + atomicreference.set(s0); +@@ -988,6 +987,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory, int viewDistance, boolean dsync) { super(new RegionStorageInfo(session.getLevelId(), world.dimension(), "chunk"), session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync); this.visibleChunkMap = this.updatingChunkMap.clone(); -@@ -223,6 +229,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - this.worldGenContext = new WorldGenContext(world, chunkGenerator, structureTemplateManager, this.lightEngine, this.mainThreadMailbox); +@@ -229,6 +235,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + this.chunksToEagerlySave.add(pos.toLong()); } + // Paper start @@ -4575,7 +4575,7 @@ index 5b920beb39dad8d392b4e5e12a89880720e41942..449608e60f3900778247101581ff598f protected ChunkGenerator generator() { return this.worldGenContext.generator(); } -@@ -378,9 +390,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -385,9 +397,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider }; stringbuilder.append("Updating:").append(System.lineSeparator()); @@ -4587,17 +4587,17 @@ index 5b920beb39dad8d392b4e5e12a89880720e41942..449608e60f3900778247101581ff598f CrashReport crashreport = CrashReport.forThrowable(exception, "Chunk loading"); CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Chunk loading"); -@@ -422,6 +434,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -429,6 +441,9 @@ 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); + holder = new ChunkHolder(new ChunkPos(pos), level, this.level, this.lightEngine, this::onLevelChange, this); + // Paper start + ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderCreate(this.level, holder); + // Paper end } this.updatingChunkMap.put(pos, holder); -@@ -445,7 +460,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -458,7 +473,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider protected void saveAllChunks(boolean flush) { if (flush) { @@ -4606,50 +4606,44 @@ index 5b920beb39dad8d392b4e5e12a89880720e41942..449608e60f3900778247101581ff598f MutableBoolean mutableboolean = new MutableBoolean(); do { -@@ -468,7 +483,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - }); - this.flushWorker(); +@@ -484,7 +499,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } else { -- this.visibleChunkMap.values().forEach(this::saveChunkIfNeeded); -+ ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).forEach(this::saveChunkIfNeeded); - } + this.nextChunkSaveTime.clear(); + long i = Util.getMillis(); +- ObjectIterator objectiterator = this.visibleChunkMap.values().iterator(); ++ Iterator objectiterator = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper - } -@@ -487,7 +502,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + while (objectiterator.hasNext()) { + ChunkHolder playerchunk = (ChunkHolder) objectiterator.next(); +@@ -509,7 +524,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() || ca.spottedleaf.moonrise.common.util.ChunkSystem.hasAnyChunkHolders(this.level) || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); // Paper +- return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || !this.updatingChunkMap.isEmpty() || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.worldgenTaskDispatcher.hasWork() || this.lightTaskDispatcher.hasWork() || this.distanceManager.hasTickets(); ++ return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || ca.spottedleaf.moonrise.common.util.ChunkSystem.hasAnyChunkHolders(this.level) || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.lightTaskDispatcher.hasWork() || this.distanceManager.hasTickets(); // Paper } private void processUnloads(BooleanSupplier shouldKeepTicking) { -@@ -523,7 +538,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - - int l = 0; -- ObjectIterator objectiterator = this.visibleChunkMap.values().iterator(); -+ Iterator objectiterator = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper - - while (l < 20 && shouldKeepTicking.getAsBoolean() && objectiterator.hasNext()) { - if (this.saveChunkIfNeeded((ChunkHolder) objectiterator.next())) { -@@ -541,7 +556,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -568,9 +583,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + this.scheduleUnload(pos, chunk); } else { - ChunkAccess ichunkaccess = holder.getLatestChunk(); - -- if (this.pendingUnloads.remove(pos, holder) && ichunkaccess != null) { + ChunkAccess ichunkaccess = chunk.getLatestChunk(); +- +- if (this.pendingUnloads.remove(pos, chunk) && ichunkaccess != null) { +- LevelChunk chunk1; + // Paper start + boolean removed; -+ if ((removed = this.pendingUnloads.remove(pos, holder)) && ichunkaccess != null) { -+ ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, holder); ++ if ((removed = this.pendingUnloads.remove(pos, chunk)) && ichunkaccess != null) { ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, chunk); + // Paper end - LevelChunk chunk; ++ LevelChunk chunk; if (ichunkaccess instanceof LevelChunk) { -@@ -559,7 +578,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + chunk1 = (LevelChunk) ichunkaccess; +@@ -587,7 +605,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()); + this.nextChunkSaveTime.remove(ichunkaccess.getPos().toLong()); - } + } else if (removed) { // Paper start + ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, holder); @@ -4657,7 +4651,7 @@ index 5b920beb39dad8d392b4e5e12a89880720e41942..449608e60f3900778247101581ff598f } }; -@@ -896,7 +917,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -936,7 +956,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } } @@ -4666,7 +4660,7 @@ index 5b920beb39dad8d392b4e5e12a89880720e41942..449608e60f3900778247101581ff598f int j = Mth.clamp(watchDistance, 2, 32); if (j != this.serverViewDistance) { -@@ -913,7 +934,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -953,7 +973,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } @@ -4675,7 +4669,7 @@ index 5b920beb39dad8d392b4e5e12a89880720e41942..449608e60f3900778247101581ff598f return Mth.clamp(player.requestedViewDistance(), 2, this.serverViewDistance); } -@@ -942,7 +963,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -982,7 +1002,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public int size() { @@ -4684,7 +4678,7 @@ index 5b920beb39dad8d392b4e5e12a89880720e41942..449608e60f3900778247101581ff598f } public DistanceManager getDistanceManager() { -@@ -950,19 +971,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -990,19 +1010,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } protected Iterable getChunks() { @@ -4709,7 +4703,7 @@ index 5b920beb39dad8d392b4e5e12a89880720e41942..449608e60f3900778247101581ff598f Optional optional = Optional.ofNullable(playerchunk.getLatestChunk()); Optional optional1 = optional.flatMap((ichunkaccess) -> { return ichunkaccess instanceof LevelChunk ? Optional.of((LevelChunk) ichunkaccess) : Optional.empty(); -@@ -1385,7 +1406,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1445,7 +1465,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider }); } @@ -4719,10 +4713,10 @@ index 5b920beb39dad8d392b4e5e12a89880720e41942..449608e60f3900778247101581ff598f protected ChunkDistanceManager(final Executor workerExecutor, final Executor mainThreadExecutor) { super(workerExecutor, mainThreadExecutor); diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java -index d3769ad50ddb556cff515ea8cf853d28e490ca94..dfa0456f352ce25bc4edd1b0f04ca5a14434d7fa 100644 +index 019228b1809e3816b0b4dfb9f19b8d42876cc240..6c2339d6a93172e25040c4868a3a47473a1f5336 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java -@@ -370,7 +370,7 @@ public abstract class DistanceManager { +@@ -385,7 +385,7 @@ public abstract class DistanceManager { } public void removeTicketsOnClosing() { @@ -4732,18 +4726,10 @@ index d3769ad50ddb556cff515ea8cf853d28e490ca94..dfa0456f352ce25bc4edd1b0f04ca5a1 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 d39268911ed7c4d60ee6a82178be23245aae58c4..cf94dd9ddcc1eabcf3fd336e70720f4ed3e52175 100644 +index 9cdcab885a915990a679f3fc9ae6885f7d125bfd..c615510f3f59292715bcff1bd9e4e896c9733436 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -48,6 +48,7 @@ import net.minecraft.world.level.storage.LevelStorageSource; - - public class ServerChunkCache extends ChunkSource { - -+ public static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); // Paper - private static final List CHUNK_STATUSES = ChunkStatus.getStatusList(); - private final DistanceManager distanceManager; - final ServerLevel level; -@@ -66,6 +67,10 @@ public class ServerChunkCache extends ChunkSource { +@@ -74,6 +74,10 @@ public class ServerChunkCache extends ChunkSource { @Nullable @VisibleForDebug private NaturalSpawner.SpawnState lastSpawnState; @@ -4754,7 +4740,7 @@ index d39268911ed7c4d60ee6a82178be23245aae58c4..cf94dd9ddcc1eabcf3fd336e70720f4e 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 persistentStateManagerFactory) { this.level = world; -@@ -91,6 +96,54 @@ public class ServerChunkCache extends ChunkSource { +@@ -104,6 +108,54 @@ public class ServerChunkCache extends ChunkSource { return chunk.getFullChunkNow() != null; } // CraftBukkit end @@ -4809,7 +4795,7 @@ index d39268911ed7c4d60ee6a82178be23245aae58c4..cf94dd9ddcc1eabcf3fd336e70720f4e @Override public ThreadedLevelLightEngine getLightEngine() { -@@ -286,7 +339,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -299,7 +351,7 @@ public class ServerChunkCache extends ChunkSource { return this.mainThreadProcessor.pollTask(); } @@ -4818,7 +4804,7 @@ index d39268911ed7c4d60ee6a82178be23245aae58c4..cf94dd9ddcc1eabcf3fd336e70720f4e boolean flag = this.distanceManager.runAllUpdates(this.chunkMap); boolean flag1 = this.chunkMap.promoteChunkMap(); -@@ -299,6 +352,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -312,6 +364,12 @@ public class ServerChunkCache extends ChunkSource { } } @@ -4829,13 +4815,13 @@ index d39268911ed7c4d60ee6a82178be23245aae58c4..cf94dd9ddcc1eabcf3fd336e70720f4e + // Paper end + public boolean isPositionTicking(long pos) { - ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos); - + if (!this.level.shouldTickBlocksAt(pos)) { + return false; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 9d11fcb3df12182ae00ce73f7e30091fd199a341..4c39d9e0466240b5cd459ee649a22fe3a72bf9f0 100644 +index f6a3606b972064c4ec78487374e6197c0c447e27..6fe373de360570b528b8133043ef3bb9ba12529d 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -236,6 +236,98 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -239,6 +239,98 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return this.convertable.dimensionType; } @@ -4933,12 +4919,12 @@ index 9d11fcb3df12182ae00ce73f7e30091fd199a341..4c39d9e0466240b5cd459ee649a22fe3 + // Add env and gen to constructor, IWorldDataServer -> WorldDataServer public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { - // IRegistryCustom.Dimension iregistrycustom_dimension = minecraftserver.registryAccess(); // CraftBukkit - decompile error + super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules()))); // Paper - create paper world configs diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index ff1a8e62d2bb3de62e0c27b2335cb512ea91dedd..cb136a30287a17947ed018cdc48e6f91ed904072 100644 +index 0c211366be68e33b24da2b055142626968ed6b0b..32e7c6e6f09e53fe8b5ade22dad8142cd09e0163 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -281,6 +281,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -309,6 +309,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { public boolean sentListPacket = false; public String kickLeaveMessage = null; // SPIGOT-3034: Forward leave message to PlayerQuitEvent // CraftBukkit end @@ -4947,7 +4933,7 @@ index ff1a8e62d2bb3de62e0c27b2335cb512ea91dedd..cb136a30287a17947ed018cdc48e6f91 public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) { super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java -index 045b754b5b70bbd1e7732ad2142dfadd6cc2305c..f56e5c0f53f9b52a9247b9be9265b949494fc924 100644 +index 011eeab289d68b9b535c6438016f1244d0666286..e701f57ac8b0efdf739389f9be7a255220bb3e21 100644 --- a/src/main/java/net/minecraft/server/level/TicketType.java +++ b/src/main/java/net/minecraft/server/level/TicketType.java @@ -7,6 +7,7 @@ import net.minecraft.util.Unit; @@ -4959,7 +4945,7 @@ index 045b754b5b70bbd1e7732ad2142dfadd6cc2305c..f56e5c0f53f9b52a9247b9be9265b949 private final String name; private final Comparator comparator; diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java -index 7d69da7e761ccfe736656e8c89dd1ae08956695f..421f146ea9c35b852251c0ddb29856c13e11aef3 100644 +index a1f4ebcd0877a6d0c41493eff5d70a408bf98e59..f1725ef766c35aa623ace58fe8bf31fc9b2bb6b3 100644 --- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java +++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java @@ -169,6 +169,26 @@ public class WorldGenRegion implements WorldGenLevel { @@ -4990,10 +4976,10 @@ index 7d69da7e761ccfe736656e8c89dd1ae08956695f..421f146ea9c35b852251c0ddb29856c1 public BlockState getBlockState(BlockPos pos) { return this.getChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ())).getBlockState(pos); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 0914b2f9fef1f49df9f0ce7c85cdde94c2c39b6c..6abe921099ff00ecfaf0f423ef27d708420f6f48 100644 +index 23a611c9a83d1cea5ab2f64cdbd696c39872477d..bf660a057d135563b47e7b74d927a82a20b8ef75 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -180,6 +180,7 @@ public abstract class PlayerList { +@@ -181,6 +181,7 @@ public abstract class PlayerList { } public void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie clientData) { @@ -5002,10 +4988,10 @@ index 0914b2f9fef1f49df9f0ce7c85cdde94c2c39b6c..6abe921099ff00ecfaf0f423ef27d708 GameProfileCache usercache = this.server.getProfileCache(); // Optional optional; // CraftBukkit - decompile error diff --git a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java -index aede9b65e799a1f123f71f9390fb05acddda676b..ca94a1aaccdcc9f28b5f7936b871216a75ab762a 100644 +index ae25aec117a7272735c824a00c1ed117fa52a921..f877bc637fef7f446b328381316f1431b3a5dee8 100644 --- a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java +++ b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java -@@ -79,6 +79,13 @@ public abstract class BlockableEventLoop implements Profiler +@@ -82,6 +82,13 @@ public abstract class BlockableEventLoop implements Profiler runnable.run(); } } @@ -5018,12 +5004,12 @@ index aede9b65e799a1f123f71f9390fb05acddda676b..ca94a1aaccdcc9f28b5f7936b871216a + // Paper end @Override - public void tell(R runnable) { + public void schedule(R runnable) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 05a4056b242159b1c85aa6ebf43b69cf85c00021..06cbe7a7ea131a8bead857cbfbd27810a9093320 100644 +index 1631ea62aab53d6e5e0ae44f63367416ac424410..c010d18061f58a583c69e85fc29305497523f569 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -339,6 +339,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -342,6 +342,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this.level.hasChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); } // CraftBukkit end @@ -5036,10 +5022,10 @@ index 05a4056b242159b1c85aa6ebf43b69cf85c00021..06cbe7a7ea131a8bead857cbfbd27810 public Entity(EntityType type, Level world) { this.id = Entity.ENTITY_COUNTER.incrementAndGet(); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index c1db114edd9e31273b76374cbd19710b01cada2b..26064174397dc95f9b117d901e22c55abebf3c39 100644 +index 47712d062ece9914de058153272ab1fa535af372..9aa4e70f1d1c4de2138d31701dceaed25062e69c 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -282,6 +282,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -296,6 +296,7 @@ public abstract class LivingEntity extends Entity implements Attackable { public boolean collides = true; public Set collidableExemptions = new HashSet<>(); public boolean bukkitPickUpLoot; @@ -5048,10 +5034,10 @@ index c1db114edd9e31273b76374cbd19710b01cada2b..26064174397dc95f9b117d901e22c55a @Override public float getBukkitYaw() { diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 3e00b12d166c5a6a82e61574bfefd5973ffcbb59..142d762750b9745428ae27802f7a428147a74771 100644 +index 0495b02157a40742ebf6817841010aacea179806..b0e45e28d17780b760a81ccbff61581274e033df 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -953,6 +953,25 @@ public final class ItemStack implements DataComponentHolder { +@@ -1025,6 +1025,25 @@ public final class ItemStack implements DataComponentHolder { } } @@ -5077,7 +5063,7 @@ index 3e00b12d166c5a6a82e61574bfefd5973ffcbb59..142d762750b9745428ae27802f7a4281 public void applyComponents(DataComponentPatch changes) { this.components.applyPatch(changes); this.getItem().verifyComponentsAfterLoad(this); -@@ -1219,6 +1238,7 @@ public final class ItemStack implements DataComponentHolder { +@@ -1300,6 +1319,7 @@ public final class ItemStack implements DataComponentHolder { // CraftBukkit start @Deprecated public void setItem(Item item) { @@ -5086,10 +5072,10 @@ index 3e00b12d166c5a6a82e61574bfefd5973ffcbb59..142d762750b9745428ae27802f7a4281 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java -index 1c71d2c1b16bdba1e14a8230787e4cb4ad530163..d6d8bbc98fc71997cb52521d59ebb59d727d3c22 100644 +index 1a69fa49d43c904d0f762159129b8ed1eea36a43..6850ac324ee4d202f112dbd057ea1bde9de17ea9 100644 --- a/src/main/java/net/minecraft/world/level/BlockGetter.java +++ b/src/main/java/net/minecraft/world/level/BlockGetter.java -@@ -9,6 +9,7 @@ import javax.annotation.Nullable; +@@ -12,6 +12,7 @@ import javax.annotation.Nullable; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.util.Mth; @@ -5097,7 +5083,7 @@ index 1c71d2c1b16bdba1e14a8230787e4cb4ad530163..d6d8bbc98fc71997cb52521d59ebb59d import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; -@@ -30,6 +31,15 @@ public interface BlockGetter extends LevelHeightAccessor { +@@ -35,6 +36,15 @@ public interface BlockGetter extends LevelHeightAccessor { } BlockState getBlockState(BlockPos pos); @@ -5114,10 +5100,10 @@ index 1c71d2c1b16bdba1e14a8230787e4cb4ad530163..d6d8bbc98fc71997cb52521d59ebb59d FluidState getFluidState(BlockPos pos); diff --git a/src/main/java/net/minecraft/world/level/ChunkPos.java b/src/main/java/net/minecraft/world/level/ChunkPos.java -index 171c9c4ab2d1a7988935e09b49286f30e36741e2..fa58eeec2b652f0fa251eedf11cfabde5fd3198b 100644 +index a59d3f56859ba7c07dcb45b1e199e3a7132dcff7..0639e4565c3324d757dec1226adb4e99d841f2c0 100644 --- a/src/main/java/net/minecraft/world/level/ChunkPos.java +++ b/src/main/java/net/minecraft/world/level/ChunkPos.java -@@ -20,6 +20,7 @@ public class ChunkPos { +@@ -46,6 +46,7 @@ public class ChunkPos { public static final int REGION_MAX_INDEX = 31; public final int x; public final int z; @@ -5125,7 +5111,7 @@ index 171c9c4ab2d1a7988935e09b49286f30e36741e2..fa58eeec2b652f0fa251eedf11cfabde private static final int HASH_A = 1664525; private static final int HASH_C = 1013904223; private static final int HASH_Z_XOR = -559038737; -@@ -27,16 +28,19 @@ public class ChunkPos { +@@ -53,16 +54,19 @@ public class ChunkPos { public ChunkPos(int x, int z) { this.x = x; this.z = z; @@ -5145,7 +5131,7 @@ index 171c9c4ab2d1a7988935e09b49286f30e36741e2..fa58eeec2b652f0fa251eedf11cfabde } public static ChunkPos minFromRegion(int x, int z) { -@@ -48,7 +52,7 @@ public class ChunkPos { +@@ -74,7 +78,7 @@ public class ChunkPos { } public long toLong() { @@ -5155,7 +5141,7 @@ index 171c9c4ab2d1a7988935e09b49286f30e36741e2..fa58eeec2b652f0fa251eedf11cfabde public static long asLong(int chunkX, int chunkZ) { diff --git a/src/main/java/net/minecraft/world/level/EmptyBlockGetter.java b/src/main/java/net/minecraft/world/level/EmptyBlockGetter.java -index 3c707d6674b2594b09503b959a31c1f4ad3981e6..db61b6b0158a9bcc0e1d735e34fe3671f8c89e21 100644 +index 8741264b0a9529b40c41a4b9bf25b50d27c830bc..87af0b3cfd3a3170955894028fd667f108ea8121 100644 --- a/src/main/java/net/minecraft/world/level/EmptyBlockGetter.java +++ b/src/main/java/net/minecraft/world/level/EmptyBlockGetter.java @@ -17,6 +17,18 @@ public enum EmptyBlockGetter implements BlockGetter { @@ -5178,10 +5164,10 @@ index 3c707d6674b2594b09503b959a31c1f4ad3981e6..db61b6b0158a9bcc0e1d735e34fe3671 public BlockState getBlockState(BlockPos pos) { return Blocks.AIR.defaultBlockState(); diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index c061813d275fbc48d7629cc59d90dbb4c347516c..2bc1d0d3ea8a6e3327e9c11bd1f0666d210e9bbe 100644 +index c8e49c1904c80c4ede40ca5c26efad9b12e247d1..3fb17bbcecf6dc4af3b231835adff25f86e1379f 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -95,6 +95,7 @@ import org.bukkit.craftbukkit.CraftServer; +@@ -97,6 +97,7 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.SpigotTimings; // Spigot import org.bukkit.craftbukkit.block.CapturedBlockState; @@ -5259,7 +5245,7 @@ index c061813d275fbc48d7629cc59d90dbb4c347516c..2bc1d0d3ea8a6e3327e9c11bd1f0666d ChunkAccess ichunkaccess = this.getChunkSource().getChunk(chunkX, chunkZ, leastStatus, create); if (ichunkaccess == null && create) { -@@ -551,7 +593,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -553,7 +595,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { if (this.isOutsideBuildHeight(pos)) { return Blocks.VOID_AIR.defaultBlockState(); } else { @@ -5269,7 +5255,7 @@ index c061813d275fbc48d7629cc59d90dbb4c347516c..2bc1d0d3ea8a6e3327e9c11bd1f0666d return chunk.getBlockState(pos); } diff --git a/src/main/java/net/minecraft/world/level/LevelReader.java b/src/main/java/net/minecraft/world/level/LevelReader.java -index 749e4ea1be56b393877b5fdd72dc3669dbf5a3dd..a0ae26d6197e1069ca09982b4f8b706c55ae8491 100644 +index 35b338fed1df844846ecc876cbbab19e0efbfcb0..5eb8982678110fabb82a93c5ec67c666b7fde017 100644 --- a/src/main/java/net/minecraft/world/level/LevelReader.java +++ b/src/main/java/net/minecraft/world/level/LevelReader.java @@ -26,6 +26,9 @@ public interface LevelReader extends BlockAndTintGetter, CollisionGetter, Signal @@ -5283,18 +5269,18 @@ index 749e4ea1be56b393877b5fdd72dc3669dbf5a3dd..a0ae26d6197e1069ca09982b4f8b706c boolean hasChunk(int chunkX, int chunkZ); diff --git a/src/main/java/net/minecraft/world/level/PathNavigationRegion.java b/src/main/java/net/minecraft/world/level/PathNavigationRegion.java -index 497792978bdf0e6a53d772304770e8df3e7416ea..c5454b92ca2565461c799d7340160f9fb72c1b0f 100644 +index b682c7c51204f727e21bfc20c691837deb7137ba..5375ea8dee8f74c843964824ad1a374e15711b60 100644 --- a/src/main/java/net/minecraft/world/level/PathNavigationRegion.java +++ b/src/main/java/net/minecraft/world/level/PathNavigationRegion.java -@@ -9,6 +9,7 @@ import net.minecraft.core.Holder; +@@ -8,6 +8,7 @@ import net.minecraft.core.BlockPos; + import net.minecraft.core.Holder; import net.minecraft.core.SectionPos; import net.minecraft.core.registries.Registries; - import net.minecraft.util.profiling.ProfilerFiller; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biomes; -@@ -67,7 +68,7 @@ public class PathNavigationRegion implements BlockGetter, CollisionGetter { +@@ -66,7 +67,7 @@ public class PathNavigationRegion implements CollisionGetter { private ChunkAccess getChunk(int chunkX, int chunkZ) { int i = chunkX - this.centerX; int j = chunkZ - this.centerZ; @@ -5303,7 +5289,7 @@ index 497792978bdf0e6a53d772304770e8df3e7416ea..c5454b92ca2565461c799d7340160f9f ChunkAccess chunkAccess = this.chunks[i][j]; return (ChunkAccess)(chunkAccess != null ? chunkAccess : new EmptyLevelChunk(this.level, new ChunkPos(chunkX, chunkZ), this.plains.get())); } else { -@@ -75,6 +76,30 @@ public class PathNavigationRegion implements BlockGetter, CollisionGetter { +@@ -74,6 +75,30 @@ public class PathNavigationRegion implements CollisionGetter { } } @@ -5335,10 +5321,10 @@ index 497792978bdf0e6a53d772304770e8df3e7416ea..c5454b92ca2565461c799d7340160f9f public WorldBorder getWorldBorder() { return this.level.getWorldBorder(); diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -index e0594a1c381487b43bfc55212044e1b3122cee66..59fcaca90b67c03e1a6799e58061dbae3b1f1ceb 100644 +index 107d387f0f81e1a1400cefbec4758b743a64ca3b..0bae4e8d1e9fcc4608b3ef1c981c65f3b03de22b 100644 --- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -@@ -841,12 +841,14 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -883,12 +883,14 @@ public abstract class BlockBehaviour implements FeatureElement { } } @@ -5352,9 +5338,9 @@ index e0594a1c381487b43bfc55212044e1b3122cee66..59fcaca90b67c03e1a6799e58061dbae + this.shapeExceedsCube = this.cache == null || this.cache.largeCollisionShape; // Paper - moved from actual method to here this.legacySolid = this.calculateSolid(); - } -@@ -893,8 +895,8 @@ public abstract class BlockBehaviour implements FeatureElement { - return this.getBlock().getOcclusionShape(this.asState(), world, pos); + this.occlusionShape = this.canOcclude ? ((Block) this.owner).getOcclusionShape(this.asState()) : Shapes.empty(); +@@ -955,8 +957,8 @@ public abstract class BlockBehaviour implements FeatureElement { + return this.occlusionShape; } - public boolean hasLargeCollisionShape() { @@ -5365,19 +5351,19 @@ index e0594a1c381487b43bfc55212044e1b3122cee66..59fcaca90b67c03e1a6799e58061dbae public boolean useShapeForLightOcclusion() { diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -index 35c4bf87870c0dfa1f648547115238dacbb87426..db4d95ce98eb1490d5306d1f74b282d27264871a 100644 +index 15e3b8c8a850039d0adda3c345bd5b9288d06299..37795b9e264c571efe9c718fa9996197dca4ed54 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -@@ -65,7 +65,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom +@@ -65,7 +65,7 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh protected final ShortList[] postProcessing; - protected volatile boolean unsaved; + private volatile boolean unsaved; private volatile boolean isLightCorrect; - protected final ChunkPos chunkPos; + protected final ChunkPos chunkPos; public final long coordinateKey; public final int locX; public final int locZ; // Paper - cache coordinate key private long inhabitedTime; /** @deprecated */ @Nullable -@@ -91,7 +91,8 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom +@@ -91,7 +91,8 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh // CraftBukkit end public ChunkAccess(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor heightLimitView, Registry biomeRegistry, long inhabitedTime, @Nullable LevelChunkSection[] sectionArray, @Nullable BlendingData blendingData) { @@ -5405,10 +5391,10 @@ index a52077f0d93c94b0ea644bc14b9b28e84fd1b154..dcc0acd259920463a4464213b9a5e793 @Nullable @Override 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 5b73fcfe278f57de249f3a96da58dc08eda7aff6..25380a44e5cc94f3924cfee6a03c3091fea04ae2 100644 +index 7252096639078cd0b16997354530bf181a61e999..d76591694c3b167b8b8f17b61a373a43140a8b68 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -116,6 +116,10 @@ public class LevelChunk extends ChunkAccess { +@@ -120,6 +120,10 @@ public class LevelChunk extends ChunkAccess { public boolean needsDecoration; // CraftBukkit end @@ -5419,7 +5405,7 @@ index 5b73fcfe278f57de249f3a96da58dc08eda7aff6..25380a44e5cc94f3924cfee6a03c3091 public LevelChunk(ServerLevel world, ProtoChunk protoChunk, @Nullable LevelChunk.PostLoadProcessor entityLoader) { this(world, protoChunk.getPos(), protoChunk.getUpgradeData(), protoChunk.unpackBlockTicks(), protoChunk.unpackFluidTicks(), protoChunk.getInhabitedTime(), protoChunk.getSections(), entityLoader, protoChunk.getBlendingData()); Iterator iterator = protoChunk.getBlockEntities().values().iterator(); -@@ -181,8 +185,25 @@ public class LevelChunk extends ChunkAccess { +@@ -204,8 +208,25 @@ public class LevelChunk extends ChunkAccess { } } @@ -5445,7 +5431,7 @@ index 5b73fcfe278f57de249f3a96da58dc08eda7aff6..25380a44e5cc94f3924cfee6a03c3091 int i = pos.getX(); int j = pos.getY(); int k = pos.getZ(); -@@ -224,6 +245,18 @@ public class LevelChunk extends ChunkAccess { +@@ -247,6 +268,18 @@ public class LevelChunk extends ChunkAccess { } } @@ -5464,7 +5450,7 @@ index 5b73fcfe278f57de249f3a96da58dc08eda7aff6..25380a44e5cc94f3924cfee6a03c3091 @Override public FluidState getFluidState(BlockPos pos) { return this.getFluidState(pos.getX(), pos.getY(), pos.getZ()); -@@ -554,7 +587,11 @@ public class LevelChunk extends ChunkAccess { +@@ -579,7 +612,11 @@ public class LevelChunk extends ChunkAccess { // CraftBukkit start public void loadCallback() { @@ -5476,7 +5462,7 @@ index 5b73fcfe278f57de249f3a96da58dc08eda7aff6..25380a44e5cc94f3924cfee6a03c3091 if (server != null) { /* * If it's a new world, the first few chunks are generated inside -@@ -595,6 +632,10 @@ public class LevelChunk extends ChunkAccess { +@@ -620,6 +657,10 @@ public class LevelChunk extends ChunkAccess { server.getPluginManager().callEvent(unloadEvent); // note: saving can be prevented, but not forced if no saving is actually required this.mustNotSave = !unloadEvent.isSaveChunk(); @@ -5488,7 +5474,7 @@ index 5b73fcfe278f57de249f3a96da58dc08eda7aff6..25380a44e5cc94f3924cfee6a03c3091 @Override diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -index ca4c8f74a1ab2a8b36e193a2c40c3bd76565d258..2c153af611399e884752f8256bee4fe32de5c572 100644 +index 0cf916776ce8735dcfa4c765b18e77037501a322..771529ba28a16664ad19ed9c0f4bf95eeb7da76b 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java @@ -19,7 +19,7 @@ public class LevelChunkSection { @@ -5501,11 +5487,11 @@ index ca4c8f74a1ab2a8b36e193a2c40c3bd76565d258..2c153af611399e884752f8256bee4fe3 private short tickingFluidCount; public final PalettedContainer states; diff --git a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java -index ae16b014abd52ee10d523fb003cce166b846b222..7f302405a88766c2112539d24d3dd2e513f94985 100644 +index 8bd5fb4971be46a51534c202e10a362723ad8664..5321109ca638036572df9a7e17eafcef2b4f5112 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java @@ -83,6 +83,18 @@ public class ProtoChunk extends ChunkAccess { - return new ChunkAccess.TicksToSave(this.blockTicks, this.fluidTicks); + return new ChunkAccess.PackedTicks(this.blockTicks.pack(time), this.fluidTicks.pack(time)); } + // Paper start - If loaded util @@ -5547,10 +5533,10 @@ index 34933c5324126f9afdc5cba9dea997ace8f01806..1cfc906317f07a44f06a4adf021c44e3 return false; } else { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index d0c41302478bd9b0ec65020e7ef520bd3ff1f347..99178e22846c41f1d800b69d4fed064088bbe92c 100644 +index 3882ae04173cd125fe490692a6bc2b4d8b20ff7b..eb61712ea067b277e7f32f887e3528faca275450 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2600,4 +2600,9 @@ public final class CraftServer implements Server { +@@ -2617,4 +2617,9 @@ public final class CraftServer implements Server { return this.spigot; } // Spigot end @@ -5561,10 +5547,10 @@ index d0c41302478bd9b0ec65020e7ef520bd3ff1f347..99178e22846c41f1d800b69d4fed0640 + } } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 07012c01e1d8eacf37b8a86a5e4e56fb0d81c989..ac6d4c8ac26696a0c6dfa471eee764b871dd2029 100644 +index 799444e4101283c972a160742a9e2548e604173f..456c58877490feab6be3577d34c89ea776568617 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -252,8 +252,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -256,8 +256,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public Chunk[] getLoadedChunks() { @@ -5575,7 +5561,7 @@ index 07012c01e1d8eacf37b8a86a5e4e56fb0d81c989..ac6d4c8ac26696a0c6dfa471eee764b8 } @Override -@@ -328,7 +328,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -334,7 +334,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean refreshChunk(int x, int z) { @@ -5584,7 +5570,7 @@ index 07012c01e1d8eacf37b8a86a5e4e56fb0d81c989..ac6d4c8ac26696a0c6dfa471eee764b8 if (playerChunk == null) return false; playerChunk.getTickingChunkFuture().thenAccept(either -> { -@@ -2100,4 +2100,55 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2110,4 +2110,55 @@ public class CraftWorld extends CraftRegionAccessor implements World { return this.spigot; } // Spigot end @@ -5641,10 +5627,10 @@ index 07012c01e1d8eacf37b8a86a5e4e56fb0d81c989..ac6d4c8ac26696a0c6dfa471eee764b8 + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 4cbf0d797fc2d57c822877c111698b2077399d32..9cd22b09b295ecd95d17d1dd5edb96f916eb6c09 100644 +index 8ad04c031656d8a676687001b8e9cdc9a1b3bd70..1f013a6eb2088eccb3aea1a5ecd8aac8cc9597d9 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2420,4 +2420,34 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2433,4 +2433,34 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.spigot; } // Spigot end @@ -5680,10 +5666,10 @@ index 4cbf0d797fc2d57c822877c111698b2077399d32..9cd22b09b295ecd95d17d1dd5edb96f9 + } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index 952c6ebde7031dc060efe98992f82c02bf3534ea..17fa2d3db112762bcb8b941b69b8ddcc53f47224 100644 +index f6e6f0ddef6693c58f28b89cf3df005a8d47e08d..101eea3452c9e387e770b716543c3a4f17b9a737 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -@@ -23,6 +23,20 @@ import org.jetbrains.annotations.ApiStatus; +@@ -31,6 +31,20 @@ import org.jetbrains.annotations.ApiStatus; @DelegateDeserialization(ItemStack.class) public final class CraftItemStack extends ItemStack { @@ -5705,10 +5691,10 @@ index 952c6ebde7031dc060efe98992f82c02bf3534ea..17fa2d3db112762bcb8b941b69b8ddcc if (original instanceof CraftItemStack) { CraftItemStack stack = (CraftItemStack) original; diff --git a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java -index 5fd6eb754c4edebed6798c65b06507a4e89ca48f..524b51a0ab808a0629c871ad813115abd4b49dbd 100644 +index b8a865305cc61954aeebff4a7cd1d1973c5f46ab..e444662ee4d9405eeea7caa41b9cd6b36586d840 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java +++ b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java -@@ -58,6 +58,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; +@@ -56,6 +56,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.ticks.LevelTickAccess; import net.minecraft.world.ticks.TickPriority; import org.bukkit.event.entity.CreatureSpawnEvent; @@ -5716,9 +5702,9 @@ index 5fd6eb754c4edebed6798c65b06507a4e89ca48f..524b51a0ab808a0629c871ad813115ab public abstract class DelegatedGeneratorAccess implements WorldGenLevel { -@@ -807,4 +808,24 @@ public abstract class DelegatedGeneratorAccess implements WorldGenLevel { - public int getMoonPhase() { - return this.handle.getMoonPhase(); +@@ -788,4 +789,25 @@ public abstract class DelegatedGeneratorAccess implements WorldGenLevel { + public boolean isFluidAtPosition(BlockPos pos, Predicate state) { + return this.handle.isFluidAtPosition(pos, state); } + + // Paper start @@ -5741,6 +5727,7 @@ index 5fd6eb754c4edebed6798c65b06507a4e89ca48f..524b51a0ab808a0629c871ad813115ab + } + // Paper end } ++ diff --git a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java index e837d76e833d73d888bc1dad3515c2b82bc0e437..4705aed1dd98378c146bf9e346df1a17f719ad36 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java @@ -5770,7 +5757,7 @@ index e837d76e833d73d888bc1dad3515c2b82bc0e437..4705aed1dd98378c146bf9e346df1a17 public WorldBorder getWorldBorder() { throw new UnsupportedOperationException("Not supported yet."); diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 0c7c97f27853843ec714e47f5b570f9d09bbba14..ff422d4d4f2b764370f0ee2af13034853c1d3fe1 100644 +index 1bf87b4915edf341ad55f8274cef324e0bc28547..3591b79481ac17bd02e59ac3c623d1c6991abd84 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -34,6 +34,9 @@ public class ActivationRange diff --git a/patches/unapplied/0010-Adventure.patch b/patches/server/0010-Adventure.patch similarity index 97% rename from patches/unapplied/0010-Adventure.patch rename to patches/server/0010-Adventure.patch index d9da34e2e729..f5cbd123cd2d 100644 --- a/patches/unapplied/0010-Adventure.patch +++ b/patches/server/0010-Adventure.patch @@ -2179,10 +2179,10 @@ index 08dcd817bfe1ba0121d4ce701825e4aee384db85..d5f63d06d921d731b4e64b3822837771 public static ChatFormatting getById(int colorIndex) { if (colorIndex < 0) { diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java -index f30cdfa5fd294479e35680b2f758b3295f659b74..ec34e402104d7a696ea95e0b11ee70189b678ab9 100644 +index d6ea21d6d33b701f249a8acd3e7304eb2c02e1ca..2fbd7f7c976fb55b7238f1e512afad79e52a5b2c 100644 --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java +++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java -@@ -65,6 +65,7 @@ public class CommandSourceStack implements ExecutionCommandSource implements ServerInfo, ChunkIOErrorReporter, CommandSource, AutoCloseable { +@@ -208,6 +208,7 @@ import org.bukkit.craftbukkit.SpigotTimings; // Spigot + public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource { public static final Logger LOGGER = LogUtils.getLogger(); + public static final net.kyori.adventure.text.logger.slf4j.ComponentLogger COMPONENT_LOGGER = net.kyori.adventure.text.logger.slf4j.ComponentLogger.logger(LOGGER.getName()); // Paper public static final String VANILLA_BRAND = "vanilla"; private static final float AVERAGE_TICK_TIME_SMOOTHING = 0.8F; private static final int TICK_STATS_SPAN = 100; -@@ -251,8 +252,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { boolean flag1 = true; -@@ -2025,8 +2024,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2288,8 +2287,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } public void sendChatMessage(OutgoingChatMessage message, boolean filterMaskEnabled, ChatType.Bound params) { @@ -2777,7 +2777,7 @@ index cb136a30287a17947ed018cdc48e6f91ed904072..ee5188f3aa2ff71306f5af8046e8ddf9 } } -@@ -2053,6 +2057,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2316,6 +2320,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } // CraftBukkit end this.language = clientOptions.language(); @@ -2786,10 +2786,10 @@ index cb136a30287a17947ed018cdc48e6f91ed904072..ee5188f3aa2ff71306f5af8046e8ddf9 this.chatVisibility = clientOptions.chatVisibility(); this.canChatColor = clientOptions.chatColors(); diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 16320a5fccc7faf7ceac95d471532104a61d27a5..b2bddc6183204b9f519549073e38741e1a9322c4 100644 +index 64b13cc2f32ab59dd6bea6d33c475228384b7c3e..99f89854e43ed6742dc9ac1624fa7140b4594b3b 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -72,7 +72,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -73,7 +73,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack private static final Component TIMEOUT_DISCONNECTION_MESSAGE = Component.translatable("disconnect.timeout"); static final Component DISCONNECT_UNEXPECTED_QUERY = Component.translatable("multiplayer.disconnect.unexpected_query_response"); protected final MinecraftServer server; @@ -2798,7 +2798,7 @@ index 16320a5fccc7faf7ceac95d471532104a61d27a5..b2bddc6183204b9f519549073e38741e private final boolean transferred; private long keepAliveTime; private boolean keepAlivePending; -@@ -81,6 +81,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -82,6 +82,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack private boolean closed = false; private int latency; private volatile boolean suspendFlushingOnServerThread = false; @@ -2806,7 +2806,7 @@ index 16320a5fccc7faf7ceac95d471532104a61d27a5..b2bddc6183204b9f519549073e38741e public ServerCommonPacketListenerImpl(MinecraftServer minecraftserver, Connection networkmanager, CommonListenerCookie commonlistenercookie, ServerPlayer player) { // CraftBukkit this.server = minecraftserver; -@@ -194,6 +195,18 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -201,6 +202,18 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack ServerCommonPacketListenerImpl.LOGGER.info("Disconnecting {} due to resource pack {} rejection", this.playerProfile().getName(), packet.id()); this.disconnect((Component) Component.translatable("multiplayer.requiredTexturePrompt.disconnect")); } @@ -2825,7 +2825,7 @@ index 16320a5fccc7faf7ceac95d471532104a61d27a5..b2bddc6183204b9f519549073e38741e this.cserver.getPluginManager().callEvent(new PlayerResourcePackStatusEvent(this.getCraftPlayer(), packet.id(), PlayerResourcePackStatusEvent.Status.values()[packet.action().ordinal()])); // CraftBukkit } -@@ -280,6 +293,12 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -287,6 +300,12 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } } @@ -2838,7 +2838,7 @@ index 16320a5fccc7faf7ceac95d471532104a61d27a5..b2bddc6183204b9f519549073e38741e public void disconnect(Component reason) { this.disconnect(new DisconnectionDetails(reason)); } -@@ -310,9 +329,9 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -317,9 +336,9 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack return; } @@ -2850,7 +2850,7 @@ index 16320a5fccc7faf7ceac95d471532104a61d27a5..b2bddc6183204b9f519549073e38741e if (this.cserver.getServer().isRunning()) { this.cserver.getPluginManager().callEvent(event); -@@ -324,7 +343,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -331,7 +350,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } this.player.kickLeaveMessage = event.getLeaveMessage(); // CraftBukkit - SPIGOT-3034: Forward leave message to PlayerQuitEvent // Send the possibly modified leave message @@ -2872,7 +2872,7 @@ index e7c407039fef88ef01ba9b6be9ae5bcc3edc026f..5457358bc76889153036818fdfd70a04 @Override diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 2de70e3a3038b2d2bb47b58f0e14d937c35d55ba..4acee8121ff62413dbbf2294d17da3bd2f974d5a 100644 +index 2a2197f30db99542cb7d2f99dc1377160ba2dc64..eed5dd58fc37c137c87bf3e55e1e033b74002110 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -45,6 +45,7 @@ import net.minecraft.nbt.CompoundTag; @@ -2883,7 +2883,7 @@ index 2de70e3a3038b2d2bb47b58f0e14d937c35d55ba..4acee8121ff62413dbbf2294d17da3bd import net.minecraft.network.chat.ChatType; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.LastSeenMessages; -@@ -195,6 +196,8 @@ import net.minecraft.world.phys.shapes.VoxelShape; +@@ -201,6 +202,8 @@ import net.minecraft.world.phys.shapes.VoxelShape; import org.slf4j.Logger; // CraftBukkit start @@ -2892,7 +2892,7 @@ index 2de70e3a3038b2d2bb47b58f0e14d937c35d55ba..4acee8121ff62413dbbf2294d17da3bd import com.mojang.datafixers.util.Pair; import java.util.Arrays; import java.util.concurrent.ExecutionException; -@@ -1728,9 +1731,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1739,9 +1742,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl */ this.player.disconnect(); @@ -2907,7 +2907,7 @@ index 2de70e3a3038b2d2bb47b58f0e14d937c35d55ba..4acee8121ff62413dbbf2294d17da3bd } // CraftBukkit end this.player.getTextFilter().leave(); -@@ -1791,10 +1796,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1802,10 +1807,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } CompletableFuture completablefuture = this.filterTextPacket(playerchatmessage.signedContent()).thenApplyAsync(Function.identity(), this.server.chatExecutor); // CraftBukkit - async chat @@ -2921,7 +2921,7 @@ index 2de70e3a3038b2d2bb47b58f0e14d937c35d55ba..4acee8121ff62413dbbf2294d17da3bd this.broadcastChatMessage(playerchatmessage1); }); -@@ -2014,7 +2019,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2025,7 +2030,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.handleCommand(s); } else if (this.player.getChatVisibility() == ChatVisiblity.SYSTEM) { // Do nothing, this is coming from a plugin @@ -2938,7 +2938,7 @@ index 2de70e3a3038b2d2bb47b58f0e14d937c35d55ba..4acee8121ff62413dbbf2294d17da3bd Player player = this.getCraftPlayer(); AsyncPlayerChatEvent event = new AsyncPlayerChatEvent(async, player, s, new LazyPlayerSet(this.server)); String originalFormat = event.getFormat(), originalMessage = event.getMessage(); -@@ -3011,6 +3024,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3058,6 +3071,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void handleClientInformation(ServerboundClientInformationPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); this.player.updateOptions(packet.information()); @@ -2947,7 +2947,7 @@ index 2de70e3a3038b2d2bb47b58f0e14d937c35d55ba..4acee8121ff62413dbbf2294d17da3bd @Override diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index b53e3e5e02ed501d30c3fca4c3130263c32cd2f5..b2f7c76207f2dc0c62f608f21aba4b531f8f523f 100644 +index c209ac2be7fabcd36cfcc0400308e44a26d78263..8cf3b9f1b7eef2d6278830e21ae012852687e02b 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -338,7 +338,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, @@ -2988,10 +2988,10 @@ index 3848cc836785829c5aa82bdb5d37d36a97f94a04..f08700abb005f487aca95c0457c09cef @Override diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 6abe921099ff00ecfaf0f423ef27d708420f6f48..e9109526880159e2341cc97b53939ba2bcfaeaf9 100644 +index bf660a057d135563b47e7b74d927a82a20b8ef75..a70e0ecedc7b70031334bc7fee981bd790ce26a4 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -271,7 +271,7 @@ public abstract class PlayerList { +@@ -274,7 +274,7 @@ public abstract class PlayerList { } // CraftBukkit start ichatmutablecomponent.withStyle(ChatFormatting.YELLOW); @@ -3000,7 +3000,7 @@ index 6abe921099ff00ecfaf0f423ef27d708420f6f48..e9109526880159e2341cc97b53939ba2 playerconnection.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot()); ServerStatus serverping = this.server.getStatus(); -@@ -292,19 +292,18 @@ public abstract class PlayerList { +@@ -295,19 +295,18 @@ public abstract class PlayerList { // Ensure that player inventory is populated with its viewer player.containerMenu.transferTo(player.containerMenu, bukkitPlayer); @@ -3025,7 +3025,7 @@ index 6abe921099ff00ecfaf0f423ef27d708420f6f48..e9109526880159e2341cc97b53939ba2 } // CraftBukkit end -@@ -492,7 +491,7 @@ public abstract class PlayerList { +@@ -451,7 +450,7 @@ public abstract class PlayerList { } @@ -3034,7 +3034,7 @@ index 6abe921099ff00ecfaf0f423ef27d708420f6f48..e9109526880159e2341cc97b53939ba2 ServerLevel worldserver = entityplayer.serverLevel(); entityplayer.awardStat(Stats.LEAVE_GAME); -@@ -503,7 +502,7 @@ public abstract class PlayerList { +@@ -462,7 +461,7 @@ public abstract class PlayerList { entityplayer.closeContainer(); } @@ -3043,7 +3043,7 @@ index 6abe921099ff00ecfaf0f423ef27d708420f6f48..e9109526880159e2341cc97b53939ba2 this.cserver.getPluginManager().callEvent(playerQuitEvent); entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage()); -@@ -556,7 +555,7 @@ public abstract class PlayerList { +@@ -523,7 +522,7 @@ public abstract class PlayerList { this.cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity()); // CraftBukkit end @@ -3052,7 +3052,7 @@ index 6abe921099ff00ecfaf0f423ef27d708420f6f48..e9109526880159e2341cc97b53939ba2 } // CraftBukkit start - Whole method, SocketAddress to LoginListener, added hostname to signature, return EntityPlayer -@@ -603,11 +602,11 @@ public abstract class PlayerList { +@@ -570,11 +569,11 @@ public abstract class PlayerList { } // return chatmessage; @@ -3067,7 +3067,7 @@ index 6abe921099ff00ecfaf0f423ef27d708420f6f48..e9109526880159e2341cc97b53939ba2 IpBanListEntry ipbanentry = this.ipBans.get(socketaddress); ichatmutablecomponent = Component.translatable("multiplayer.disconnect.banned_ip.reason", ipbanentry.getReason()); -@@ -616,17 +615,17 @@ public abstract class PlayerList { +@@ -583,17 +582,17 @@ public abstract class PlayerList { } // return chatmessage; @@ -3088,7 +3088,7 @@ index 6abe921099ff00ecfaf0f423ef27d708420f6f48..e9109526880159e2341cc97b53939ba2 return null; } return entity; -@@ -1122,7 +1121,7 @@ public abstract class PlayerList { +@@ -1091,7 +1090,7 @@ public abstract class PlayerList { public void removeAll() { // CraftBukkit start - disconnect safely for (ServerPlayer player : this.players) { @@ -3097,7 +3097,7 @@ index 6abe921099ff00ecfaf0f423ef27d708420f6f48..e9109526880159e2341cc97b53939ba2 } // CraftBukkit end -@@ -1163,24 +1162,43 @@ public abstract class PlayerList { +@@ -1132,24 +1131,43 @@ public abstract class PlayerList { } public void broadcastChatMessage(PlayerChatMessage message, ServerPlayer sender, ChatType.Bound params) { @@ -3144,7 +3144,7 @@ index 6abe921099ff00ecfaf0f423ef27d708420f6f48..e9109526880159e2341cc97b53939ba2 } if (flag1 && sender != null) { -@@ -1189,7 +1207,7 @@ public abstract class PlayerList { +@@ -1158,7 +1176,7 @@ public abstract class PlayerList { } @@ -3242,7 +3242,7 @@ index ed54c81a3269360acce674aa4e1d54ccb2461841..c9c849534c3998cfcab7ddcb12a71ccb } diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 142d762750b9745428ae27802f7a428147a74771..d0c946b0383dbd8242a554a92bc70dcc2f5cccc6 100644 +index b0e45e28d17780b760a81ccbff61581274e033df..1ebaedc9617e5b79458fa119887fd72cb1f39852 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java @@ -183,7 +183,15 @@ public final class ItemStack implements DataComponentHolder { @@ -3262,10 +3262,10 @@ index 142d762750b9745428ae27802f7a428147a74771..d0c946b0383dbd8242a554a92bc70dcc } }; diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java -index 8ec376f453ac1f4c9423483f5ae1625b295858c7..e535fb3b5194b8412c0c26c0799340916c7542eb 100644 +index 657b5bab0d9e513e52b511e8a1b8fac5799f2281..cdaa050f237c6d6d5a0df0faf23daf3775249451 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java -@@ -210,22 +210,22 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C +@@ -210,22 +210,22 @@ public class SignBlockEntity extends BlockEntity { // CraftBukkit start Player player = ((ServerPlayer) entityhuman).getBukkitEntity(); @@ -3294,10 +3294,10 @@ index 8ec376f453ac1f4c9423483f5ae1625b295858c7..e535fb3b5194b8412c0c26c079934091 } } diff --git a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java -index 6acee03278c8005a06d9cd2577761f2f5355a7ec..5e469bd4d9ca428abdd9d758993164635dc86f27 100644 +index 2decbf562161fa51b931fcb208a3503d7663bb2e..c21ae4975206398e7d20b37a749b830b9219c746 100644 --- a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java +++ b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java -@@ -45,6 +45,7 @@ import net.minecraft.world.level.saveddata.SavedData; +@@ -48,6 +48,7 @@ import net.minecraft.world.level.saveddata.SavedData; import org.slf4j.Logger; // CraftBukkit start @@ -3305,7 +3305,7 @@ index 6acee03278c8005a06d9cd2577761f2f5355a7ec..5e469bd4d9ca428abdd9d75899316463 import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.CraftServer; -@@ -615,7 +616,7 @@ public class MapItemSavedData extends SavedData { +@@ -650,7 +651,7 @@ public class MapItemSavedData extends SavedData { for (org.bukkit.map.MapCursor cursor : render.cursors) { if (cursor.isVisible()) { @@ -3327,10 +3327,10 @@ index 49c037e961c5ca5ba8d6a870cb32ffe8719adc91..2772c19f58a35713d61aab24f6f0d6f5 } } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 99178e22846c41f1d800b69d4fed064088bbe92c..9f7634053ddfc4fc67f89cc99524e9ebd6096f46 100644 +index eb61712ea067b277e7f32f887e3528faca275450..16a9142bdbbfbbbb69d1486bd119dc610094484b 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -645,8 +645,10 @@ public final class CraftServer implements Server { +@@ -648,8 +648,10 @@ public final class CraftServer implements Server { } @Override @@ -3341,7 +3341,7 @@ index 99178e22846c41f1d800b69d4fed064088bbe92c..9f7634053ddfc4fc67f89cc99524e9eb } @Override -@@ -1623,7 +1625,15 @@ public final class CraftServer implements Server { +@@ -1627,7 +1629,15 @@ public final class CraftServer implements Server { return this.configuration.getInt("settings.spawn-radius", -1); } @@ -3357,7 +3357,7 @@ index 99178e22846c41f1d800b69d4fed064088bbe92c..9f7634053ddfc4fc67f89cc99524e9eb public String getShutdownMessage() { return this.configuration.getString("settings.shutdown-message"); } -@@ -1797,7 +1807,20 @@ public final class CraftServer implements Server { +@@ -1801,7 +1811,20 @@ public final class CraftServer implements Server { } @Override @@ -3378,7 +3378,7 @@ index 99178e22846c41f1d800b69d4fed064088bbe92c..9f7634053ddfc4fc67f89cc99524e9eb Set recipients = new HashSet<>(); for (Permissible permissible : this.getPluginManager().getPermissionSubscriptions(permission)) { if (permissible instanceof CommandSender && permissible.hasPermission(permission)) { -@@ -1805,14 +1828,14 @@ public final class CraftServer implements Server { +@@ -1809,14 +1832,14 @@ public final class CraftServer implements Server { } } @@ -3395,7 +3395,7 @@ index 99178e22846c41f1d800b69d4fed064088bbe92c..9f7634053ddfc4fc67f89cc99524e9eb for (CommandSender recipient : recipients) { recipient.sendMessage(message); -@@ -2074,6 +2097,14 @@ public final class CraftServer implements Server { +@@ -2078,6 +2101,14 @@ public final class CraftServer implements Server { return CraftInventoryCreator.INSTANCE.createInventory(owner, type); } @@ -3410,7 +3410,7 @@ index 99178e22846c41f1d800b69d4fed064088bbe92c..9f7634053ddfc4fc67f89cc99524e9eb @Override public Inventory createInventory(InventoryHolder owner, InventoryType type, String title) { Preconditions.checkArgument(type != null, "InventoryType cannot be null"); -@@ -2088,13 +2119,28 @@ public final class CraftServer implements Server { +@@ -2092,13 +2123,28 @@ public final class CraftServer implements Server { return CraftInventoryCreator.INSTANCE.createInventory(owner, size); } @@ -3439,7 +3439,7 @@ index 99178e22846c41f1d800b69d4fed064088bbe92c..9f7634053ddfc4fc67f89cc99524e9eb public Merchant createMerchant(String title) { return new CraftMerchantCustom(title == null ? InventoryType.MERCHANT.getDefaultTitle() : title); } -@@ -2159,6 +2205,17 @@ public final class CraftServer implements Server { +@@ -2163,6 +2209,17 @@ public final class CraftServer implements Server { return Thread.currentThread().equals(this.console.serverThread) || this.console.hasStopped() || !org.spigotmc.AsyncCatcher.enabled; // All bets are off if we have shut down (e.g. due to watchdog) } @@ -3457,7 +3457,7 @@ index 99178e22846c41f1d800b69d4fed064088bbe92c..9f7634053ddfc4fc67f89cc99524e9eb @Override public String getMotd() { return this.console.getMotd(); -@@ -2605,4 +2662,57 @@ public final class CraftServer implements Server { +@@ -2622,4 +2679,57 @@ public final class CraftServer implements Server { public double[] getTPS() { return new double[]{0, 0, 0}; // TODO } @@ -3554,10 +3554,10 @@ index cbdb1a56a97150c164515a4ce6d3ba06428bf321..b214e7b302abbfe1641485a05f1371ac public URI getUrl() { return this.handle.link(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index ac6d4c8ac26696a0c6dfa471eee764b871dd2029..85c99c3b23df1c4fd8721e7676d8e6b82f9e6abf 100644 +index 456c58877490feab6be3577d34c89ea776568617..274c9cc32d7f65456d184db7f61bc4b159f890f8 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -162,6 +162,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -166,6 +166,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { private final BlockMetadataStore blockMetadata = new BlockMetadataStore(this); private final Object2IntOpenHashMap spawnCategoryLimit = new Object2IntOpenHashMap<>(); private final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(CraftWorld.DATA_TYPE_REGISTRY); @@ -3565,7 +3565,7 @@ index ac6d4c8ac26696a0c6dfa471eee764b871dd2029..85c99c3b23df1c4fd8721e7676d8e6b8 private static final Random rand = new Random(); -@@ -1709,6 +1710,42 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1705,6 +1706,15 @@ public class CraftWorld extends CraftRegionAccessor implements World { entityTracker.broadcastAndSend(packet); } } @@ -3578,7 +3578,13 @@ index ac6d4c8ac26696a0c6dfa471eee764b871dd2029..85c99c3b23df1c4fd8721e7676d8e6b8 + player.connection.send(io.papermc.paper.adventure.PaperAdventure.asSoundPacket(sound, player.getX(), player.getY(), player.getZ(), seed, null)); + } + } -+ + + @Override + public void playSound(Entity entity, String sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) { +@@ -1717,6 +1727,33 @@ public class CraftWorld extends CraftRegionAccessor implements World { + } + } + + @Override + public void playSound(final net.kyori.adventure.sound.Sound sound, final double x, final double y, final double z) { + org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper @@ -3604,11 +3610,12 @@ index ac6d4c8ac26696a0c6dfa471eee764b871dd2029..85c99c3b23df1c4fd8721e7676d8e6b8 + private java.util.function.BiConsumer, Float> playSound0(final double x, final double y, final double z) { + return (packet, distance) -> this.world.getServer().getPlayerList().broadcast(null, x, y, z, distance, this.world.dimension(), packet); + } -+ // Paper end - - private static Map> gamerules; - public static synchronized Map> getGameRulesNMS() { -@@ -2150,5 +2187,18 @@ public class CraftWorld extends CraftRegionAccessor implements World { ++ // Paper end - Adventure ++ + private Map> gamerules; + public synchronized Map> getGameRulesNMS() { + if (this.gamerules != null) { +@@ -2160,5 +2197,18 @@ public class CraftWorld extends CraftRegionAccessor implements World { public void setSendViewDistance(final int viewDistance) { throw new UnsupportedOperationException("Not implemented yet"); } @@ -3628,7 +3635,7 @@ index ac6d4c8ac26696a0c6dfa471eee764b871dd2029..85c99c3b23df1c4fd8721e7676d8e6b8 // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 13c37384defda4475de584f33d1860a2d53ce05e..3b0370256b4d8c96053b340a657c6bcc6be6c9de 100644 +index 94004204b6cdbbbf35263faae56e3e06cb6b650c..2e33acc428dbfd3e123dfd6ef90bc020b8a08daf 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -20,6 +20,12 @@ public class Main { @@ -3645,10 +3652,10 @@ index 13c37384defda4475de584f33d1860a2d53ce05e..3b0370256b4d8c96053b340a657c6bcc OptionParser parser = new OptionParser() { { diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java -index 9ef8b0327e377817faaf58b82a8fdfa5e801eac8..2dfbe061a064b0c79b96f644a1c3639bb900eca4 100644 +index 0949f9e6bcb66da94c30439ce4ed4c8415537526..8021ac39cb9c1ff45123d51e6f13b840d1290bb2 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java -@@ -72,6 +72,19 @@ public class CraftBeacon extends CraftBlockEntityState implem +@@ -81,6 +81,19 @@ public class CraftBeacon extends CraftBlockEntityState implem this.getSnapshot().secondaryPower = (effect != null) ? CraftPotionEffectType.bukkitToMinecraftHolder(effect) : null; } @@ -3690,11 +3697,11 @@ index f9b89a7c6ac9f7fdbd29567a5b6550398dbc7345..f5b0bec4c1164fe7ef6da1f19a6ce9bb + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftContainer.java b/src/main/java/org/bukkit/craftbukkit/block/CraftContainer.java -index 007b6d66dd837ca6352c0fba5c2399139f6b5425..513402b61e6b8388b7bc163d98e54ffae0e18254 100644 +index 32f3c1f1903baf26c69b1262ff2956d7dcb84a90..76888df4b47ee0d134bca4a3aecddbb1bf4c09b0 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftContainer.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftContainer.java -@@ -32,6 +32,19 @@ public abstract class CraftContainer extends - this.getSnapshot().lockKey = (key == null) ? LockCode.NO_LOCK : new LockCode(key); +@@ -57,6 +57,19 @@ public abstract class CraftContainer extends + } } + // Paper start @@ -4033,10 +4040,10 @@ index 2d0c82ca240e371a756d71f28e2e04d1aa8e6ad2..f73017bff613bd62b86c974b29576e24 @Override public String getTranslationKey() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index d09102fe44dffa61dff883488f47715effaa8211..269326e7689eba91bcfd3475006e8cbf8f5694ef 100644 +index 8b53a3c4f4285321b12ac0d51f94c04f39cc8ec8..978397e517a6fdb24c7d2b3f242545af07deeab0 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -69,6 +69,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -70,6 +70,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { private final EntityType entityType; private EntityDamageEvent lastDamageEvent; private final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(CraftEntity.DATA_TYPE_REGISTRY); @@ -4044,7 +4051,7 @@ index d09102fe44dffa61dff883488f47715effaa8211..269326e7689eba91bcfd3475006e8cbf public CraftEntity(final CraftServer server, final Entity entity) { this.server = server; -@@ -525,6 +526,32 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -526,6 +527,32 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return this.getHandle().getVehicle().getBukkitEntity(); } @@ -4077,7 +4084,7 @@ index d09102fe44dffa61dff883488f47715effaa8211..269326e7689eba91bcfd3475006e8cbf @Override public void setCustomName(String name) { // sane limit for name length -@@ -621,6 +648,17 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -622,6 +649,17 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { public String getName() { return CraftChatMessage.fromComponent(this.getHandle().getName()); } @@ -4096,10 +4103,10 @@ index d09102fe44dffa61dff883488f47715effaa8211..269326e7689eba91bcfd3475006e8cbf @Override public boolean isPermissionSet(String name) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index f77f14d549479a5e6d4ef823c137954de746a5ce..a93895a6e656c25e819354ecf5c73ff4bae83675 100644 +index 3091c174f7f8454035d015e96278e87284d5f399..bfa44c4e37618df3f745bccc6e775ce16c19490d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -@@ -329,9 +329,12 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { +@@ -330,9 +330,12 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { container = CraftEventFactory.callInventoryOpenEvent(player, container); if (container == null) return; @@ -4114,7 +4121,7 @@ index f77f14d549479a5e6d4ef823c137954de746a5ce..a93895a6e656c25e819354ecf5c73ff4 player.containerMenu = container; player.initMenu(container); } -@@ -401,8 +404,12 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { +@@ -402,8 +405,12 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { // Now open the window MenuType windowType = CraftContainer.getNotchInventoryType(inventory.getTopInventory()); @@ -4148,10 +4155,10 @@ index 55945b83a5426b352bad9507cc9e94afb1278032..9ea1537408ff2d790747b6e5a681d917 public boolean isOp() { return true; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 9cd22b09b295ecd95d17d1dd5edb96f916eb6c09..69b8d0f73ced69cd88029a5d7e11aca40d70f9d1 100644 +index 1f013a6eb2088eccb3aea1a5ecd8aac8cc9597d9..c02ab554fe6e1b7eb01bbd1824a86ff4de1db2f0 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -390,14 +390,40 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -391,14 +391,40 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public String getDisplayName() { @@ -4192,7 +4199,7 @@ index 9cd22b09b295ecd95d17d1dd5edb96f916eb6c09..69b8d0f73ced69cd88029a5d7e11aca4 @Override public String getPlayerListName() { return this.getHandle().listName == null ? this.getName() : CraftChatMessage.fromComponent(this.getHandle().listName); -@@ -409,6 +435,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -410,6 +436,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { name = this.getName(); } this.getHandle().listName = name.equals(this.getName()) ? null : CraftChatMessage.fromStringOrNull(name); @@ -4200,8 +4207,8 @@ index 9cd22b09b295ecd95d17d1dd5edb96f916eb6c09..69b8d0f73ced69cd88029a5d7e11aca4 for (ServerPlayer player : (List) this.server.getHandle().players) { if (player.getBukkitEntity().canSee(this)) { player.connection.send(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME, this.getHandle())); -@@ -416,42 +443,42 @@ public class CraftPlayer extends CraftHumanEntity implements Player { - } +@@ -429,42 +456,42 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + this.getHandle().listOrder = order; } - private Component playerListHeader; @@ -4252,7 +4259,7 @@ index 9cd22b09b295ecd95d17d1dd5edb96f916eb6c09..69b8d0f73ced69cd88029a5d7e11aca4 this.getHandle().connection.send(packet); } -@@ -481,6 +508,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -494,6 +521,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().transferCookieConnection.kickPlayer(CraftChatMessage.fromStringOrEmpty(message, true)); } @@ -4276,7 +4283,7 @@ index 9cd22b09b295ecd95d17d1dd5edb96f916eb6c09..69b8d0f73ced69cd88029a5d7e11aca4 @Override public void setCompassTarget(Location loc) { Preconditions.checkArgument(loc != null, "Location cannot be null"); -@@ -777,6 +821,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -790,6 +834,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().connection.send(packet); } @@ -4301,7 +4308,7 @@ index 9cd22b09b295ecd95d17d1dd5edb96f916eb6c09..69b8d0f73ced69cd88029a5d7e11aca4 @Override public void sendSignChange(Location loc, String[] lines) { this.sendSignChange(loc, lines, DyeColor.BLACK); -@@ -800,6 +862,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -813,6 +875,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { if (this.getHandle().connection == null) return; Component[] components = CraftSign.sanitizeLines(lines); @@ -4314,7 +4321,7 @@ index 9cd22b09b295ecd95d17d1dd5edb96f916eb6c09..69b8d0f73ced69cd88029a5d7e11aca4 SignBlockEntity sign = new SignBlockEntity(CraftLocation.toBlockPosition(loc), Blocks.OAK_SIGN.defaultBlockState()); SignText text = sign.getFrontText(); text = text.setColor(net.minecraft.world.item.DyeColor.byId(dyeColor.getWoolData())); -@@ -1816,7 +1884,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1829,7 +1897,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setResourcePack(String url) { @@ -4323,7 +4330,7 @@ index 9cd22b09b295ecd95d17d1dd5edb96f916eb6c09..69b8d0f73ced69cd88029a5d7e11aca4 } @Override -@@ -1831,7 +1899,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1844,7 +1912,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setResourcePack(String url, byte[] hash, boolean force) { @@ -4332,7 +4339,7 @@ index 9cd22b09b295ecd95d17d1dd5edb96f916eb6c09..69b8d0f73ced69cd88029a5d7e11aca4 } @Override -@@ -1868,6 +1936,59 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1881,6 +1949,59 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.handlePushResourcePack(new ClientboundResourcePackPushPacket(id, url, hashStr, force, CraftChatMessage.fromStringOrOptional(prompt, true)), false); } @@ -4392,7 +4399,7 @@ index 9cd22b09b295ecd95d17d1dd5edb96f916eb6c09..69b8d0f73ced69cd88029a5d7e11aca4 @Override public void removeResourcePack(UUID id) { Preconditions.checkArgument(id != null, "Resource pack id cannot be null"); -@@ -2288,6 +2409,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2301,6 +2422,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return (this.getHandle().requestedViewDistance() == 0) ? Bukkit.getViewDistance() : this.getHandle().requestedViewDistance(); } @@ -4405,7 +4412,7 @@ index 9cd22b09b295ecd95d17d1dd5edb96f916eb6c09..69b8d0f73ced69cd88029a5d7e11aca4 @Override public int getPing() { return this.getHandle().connection.latency(); -@@ -2338,6 +2465,248 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2351,6 +2478,248 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.getHandle().allowsListing(); } @@ -4677,10 +4684,10 @@ index 5725b0281ac53a2354b233223259d6784353bc6e..9ef939b76d06874b856e0c850addb364 @Override public int getLineWidth() { diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 7719afbb1af4091f688a75c92ee8cae8669974ff..34636f7a05d868c4df86316a65c4e008f54db634 100644 +index b5034787283b5a0403c11281895563372fccb5d2..8ea4d63833cd1500d7f413f761aa9a7cf26520c0 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -917,7 +917,7 @@ public class CraftEventFactory { +@@ -915,7 +915,7 @@ public class CraftEventFactory { return event; } @@ -4688,8 +4695,8 @@ index 7719afbb1af4091f688a75c92ee8cae8669974ff..34636f7a05d868c4df86316a65c4e008 + public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure CraftPlayer entity = victim.getBukkitEntity(); CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource); - PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(damageSource.getEntity()), 0, deathMessage); -@@ -950,7 +950,7 @@ public class CraftEventFactory { + PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage); +@@ -948,7 +948,7 @@ public class CraftEventFactory { * Server methods */ public static ServerListPingEvent callServerListPingEvent(SocketAddress address, String motd, int numPlayers, int maxPlayers) { @@ -4821,11 +4828,11 @@ index d89b178dc82c7e2ad6d586217c5a039688563e29..d674289b07748022b94cc6a7e6c6eb45 public String getTitle() { return this.title; diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -index 500bfe5dd745327f953a314e863f7318953bf3bc..e2daeeba1bacbb5c5ca2aa922fa67b02cd050755 100644 +index 6e111222e251e2f7959390e9fa0c31a163207c14..5d7e6b61102a6244c5426917c4ff280fa9e12cf1 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -@@ -206,4 +206,21 @@ public final class CraftItemFactory implements ItemFactory { - Optional> optional = (allowTreasures) ? Optional.empty() : registry.registryOrThrow(Registries.ENCHANTMENT).getTag(EnchantmentTags.IN_ENCHANTING_TABLE); +@@ -209,4 +209,21 @@ public final class CraftItemFactory implements ItemFactory { + Optional> optional = (allowTreasures) ? Optional.empty() : registry.lookupOrThrow(Registries.ENCHANTMENT).get(EnchantmentTags.IN_ENCHANTING_TABLE); return CraftItemStack.asCraftMirror(EnchantmentHelper.enchantItem(source, craft.handle, level, registry, optional)); } + @@ -5191,11 +5198,11 @@ index c71a4971f127fdfc753306019313ce1a31201120..fd3b12477c30d1eabdbe57ea77902793 + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index 8bba749bce211814f51af8a33f2ed60ba7a8b52d..0c73854243f7fa21d1ffdb3b4c85ee0a69c9c5e4 100644 +index bc68a45af66699f013851869646a2c11d5a871ee..626fe2af05fecd41b777b5dd5decbedb2f17b43a 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -@@ -961,6 +961,18 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.removedTags.isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasTool() || this.hasJukeboxPlayable() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null); +@@ -1097,6 +1097,18 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasEnchantable() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.removedTags.isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.hasTooltipStyle() || this.hasItemModel() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isGlider() || this.hasDamageResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasUseRemainder() || this.hasUseCooldown() || this.hasFood() || this.hasTool() || this.hasJukeboxPlayable() || this.hasEquippable() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null); } + // Paper start @@ -5213,7 +5220,7 @@ index 8bba749bce211814f51af8a33f2ed60ba7a8b52d..0c73854243f7fa21d1ffdb3b4c85ee0a @Override public String getDisplayName() { return CraftChatMessage.fromComponent(this.displayName); -@@ -991,6 +1003,18 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1127,6 +1139,18 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { return this.itemName != null; } @@ -5232,7 +5239,7 @@ index 8bba749bce211814f51af8a33f2ed60ba7a8b52d..0c73854243f7fa21d1ffdb3b4c85ee0a @Override public String getLocalizedName() { return this.getDisplayName(); -@@ -1010,6 +1034,18 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1146,6 +1170,18 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { return this.lore != null && !this.lore.isEmpty(); } @@ -5252,7 +5259,7 @@ index 8bba749bce211814f51af8a33f2ed60ba7a8b52d..0c73854243f7fa21d1ffdb3b4c85ee0a public boolean hasRepairCost() { return this.repairCost > 0; diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java b/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java -index 8952e5526cfe90ad16a7af28b0a8d9c65b159f90..cd3e35867075e65f46051fb88d8a2460a8bb4b53 100644 +index 38fb47bbfcec739be795b46cfb7c2c41a8379fea..caf7e4312e95e90dd0822355c8832006e69a2700 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java @@ -60,6 +60,14 @@ public class CraftTrimMaterial implements TrimMaterial, Handleable diff --git a/build.gradle.kts b/build.gradle.kts -index c4572c0a6d9695088613d158838f236fe64efb48..83daf789efc4ce90ff54420e040b783569eb5cab 100644 +index da6b4787fa787e098e4031790e955ce616593ee9..02a3dd42d82df410b6a6d22c0350fa3e44ccf70f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,9 +5,29 @@ plugins { @@ -260,10 +260,10 @@ index 8323f135d6bf2e1f12525e05094ffa3f2420e7e1..a143ea1e58464a3122fbd8ccafe417bd } } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 387552877ac82baa3af0da723dbb7c331fad6cf4..b334cfc9b98d96f9bfba1d5b14c03c336d30ff23 100644 +index 775f68ce2b402d86a83ab2307f38963ade731ef0..11832f0d93ae86cb3d54bd82f9377b915b4365d3 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -154,7 +154,7 @@ import com.mojang.serialization.Dynamic; +@@ -161,7 +161,7 @@ import com.mojang.serialization.Dynamic; import com.mojang.serialization.Lifecycle; import java.io.File; import java.util.Random; @@ -272,7 +272,7 @@ index 387552877ac82baa3af0da723dbb7c331fad6cf4..b334cfc9b98d96f9bfba1d5b14c03c33 import joptsimple.OptionSet; import net.minecraft.nbt.NbtException; import net.minecraft.nbt.ReportedNbtException; -@@ -296,7 +296,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; -@@ -383,7 +382,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0) { // Trim to filter lines which are just spaces @@ -340,7 +340,7 @@ index cd26616aba6abd44abc5eb8b01cc96f29248aecd..b41eb920b5665b7a1b7cd9f38955c31e } // CraftBukkit end } -@@ -151,6 +154,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -150,6 +153,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface DedicatedServer.LOGGER.error("Exception handling console input", ioexception); } @@ -349,7 +349,7 @@ index cd26616aba6abd44abc5eb8b01cc96f29248aecd..b41eb920b5665b7a1b7cd9f38955c31e } }; -@@ -162,6 +167,9 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -161,6 +166,9 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface } global.addHandler(new org.bukkit.craftbukkit.util.ForwardLogHandler()); @@ -359,7 +359,7 @@ index cd26616aba6abd44abc5eb8b01cc96f29248aecd..b41eb920b5665b7a1b7cd9f38955c31e final org.apache.logging.log4j.core.Logger logger = ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()); for (org.apache.logging.log4j.core.Appender appender : logger.getAppenders().values()) { if (appender instanceof org.apache.logging.log4j.core.appender.ConsoleAppender) { -@@ -172,6 +180,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -171,6 +179,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface TerminalConsoleWriterThread writerThread = new TerminalConsoleWriterThread(System.out, this.reader); this.reader.setCompletionHandler(new TerminalCompletionHandler(writerThread, this.reader.getCompletionHandler())); writerThread.start(); @@ -382,10 +382,10 @@ index 3d92c61f7781221cfdc0324d11bd0088954e4a68..84a2c6c397604279ba821286f5c3c855 if (!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeLater(() -> { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index e9109526880159e2341cc97b53939ba2bcfaeaf9..9dcfcea63f57f45a5584bb80c34fe445d65849e8 100644 +index a70e0ecedc7b70031334bc7fee981bd790ce26a4..56f046bac04205a813441907058c4ce21982d927 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -161,8 +161,7 @@ public abstract class PlayerList { +@@ -162,8 +162,7 @@ public abstract class PlayerList { public PlayerList(MinecraftServer server, LayeredRegistryAccess registryManager, PlayerDataStorage saveHandler, int maxPlayers) { this.cserver = server.server = new CraftServer((DedicatedServer) server, this); @@ -396,7 +396,7 @@ index e9109526880159e2341cc97b53939ba2bcfaeaf9..9dcfcea63f57f45a5584bb80c34fe445 this.bans = new UserBanList(PlayerList.USERBANLIST_FILE); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 9f7634053ddfc4fc67f89cc99524e9ebd6096f46..752933ceabd7ebe7b1e9f7d41198128f6f2182a6 100644 +index 16a9142bdbbfbbbb69d1486bd119dc610094484b..2affb23b83e4368a94345b36410f23139f5d36c8 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -43,7 +43,7 @@ import java.util.logging.Level; @@ -408,7 +408,7 @@ index 9f7634053ddfc4fc67f89cc99524e9ebd6096f46..752933ceabd7ebe7b1e9f7d41198128f import net.minecraft.advancements.AdvancementHolder; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; -@@ -1356,9 +1356,13 @@ public final class CraftServer implements Server { +@@ -1359,9 +1359,13 @@ public final class CraftServer implements Server { return this.logger; } @@ -423,7 +423,7 @@ index 9f7634053ddfc4fc67f89cc99524e9ebd6096f46..752933ceabd7ebe7b1e9f7d41198128f @Override public PluginCommand getPluginCommand(String name) { diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 3b0370256b4d8c96053b340a657c6bcc6be6c9de..bdb8e882ec1efbe5afec9ec5a5df57bf38d4ba2b 100644 +index 2e33acc428dbfd3e123dfd6ef90bc020b8a08daf..4a99cf5a146abe0d2b40ffc1189fdc5540f14d55 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -13,7 +13,6 @@ import java.util.logging.Logger; diff --git a/patches/unapplied/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch b/patches/server/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch similarity index 97% rename from patches/unapplied/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch rename to patches/server/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch index 8128ee5424c7..8fbbff759a3e 100644 --- a/patches/unapplied/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch +++ b/patches/server/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch @@ -15,7 +15,7 @@ This may cause additional prefixes to be disabled for plugins bypassing the plugin logger. diff --git a/build.gradle.kts b/build.gradle.kts -index 0a05e753ff5e7b1d741c7719524715d7364cac4f..d82d1e90cbda544b3d20edcc13d1cb955c48f731 100644 +index 02a3dd42d82df410b6a6d22c0350fa3e44ccf70f..a6fafa32af547efd912468ca3a5c76d8d193651d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -23,7 +23,7 @@ dependencies { diff --git a/patches/unapplied/0013-Improve-Log4J-Configuration-Plugin-Loggers.patch b/patches/server/0013-Improve-Log4J-Configuration-Plugin-Loggers.patch similarity index 100% rename from patches/unapplied/0013-Improve-Log4J-Configuration-Plugin-Loggers.patch rename to patches/server/0013-Improve-Log4J-Configuration-Plugin-Loggers.patch diff --git a/patches/unapplied/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch b/patches/server/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch similarity index 89% rename from patches/unapplied/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch rename to patches/server/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch index 1d920095cb46..6c4c11016c03 100644 --- a/patches/unapplied/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch +++ b/patches/server/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch @@ -5,13 +5,13 @@ Subject: [PATCH] Use AsyncAppender to keep logging IO off main thread diff --git a/build.gradle.kts b/build.gradle.kts -index d82d1e90cbda544b3d20edcc13d1cb955c48f731..3bd5c2a2add9b462523beb9dfaf2eb5a00d470b9 100644 +index a6fafa32af547efd912468ca3a5c76d8d193651d..b36f2e9e9980f6d2596c57791e0769c6ce734d11 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -34,6 +34,7 @@ dependencies { implementation("commons-lang:commons-lang:2.6") - runtimeOnly("org.xerial:sqlite-jdbc:3.46.0.0") - runtimeOnly("com.mysql:mysql-connector-j:8.4.0") + runtimeOnly("org.xerial:sqlite-jdbc:3.46.1.3") + runtimeOnly("com.mysql:mysql-connector-j:9.1.0") + runtimeOnly("com.lmax:disruptor:3.4.4") // Paper runtimeOnly("org.apache.maven:maven-resolver-provider:3.9.6") diff --git a/patches/unapplied/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch b/patches/server/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch similarity index 98% rename from patches/unapplied/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch rename to patches/server/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch index a6358b2bba66..2c9e91fed774 100644 --- a/patches/unapplied/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch +++ b/patches/server/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Deobfuscate stacktraces in log messages, crash reports, and diff --git a/build.gradle.kts b/build.gradle.kts -index 7c81605648c6ba1360936faae25ef5fc11f0bcb4..4838ca75b9536ce5fd30906b51bdab86789668ec 100644 +index b36f2e9e9980f6d2596c57791e0769c6ce734d11..c73ab51caa985089ade4df0616ee8d3333632980 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -46,6 +46,7 @@ dependencies { @@ -454,7 +454,7 @@ index 1938ae691dafec1fc1e5a68792d1191bd52b4e5c..268310642181a715815d3b2d1c0f090e this.exception = cause; this.systemReport.setDetail("CraftBukkit Information", new org.bukkit.craftbukkit.CraftCrashReport()); // CraftBukkit diff --git a/src/main/java/net/minecraft/CrashReportCategory.java b/src/main/java/net/minecraft/CrashReportCategory.java -index f367ba058018074bfe6e4fe88bcc875ea9794d9e..2176171954609fd88f97f93408e14e018c1d6eaa 100644 +index 81831a061d7fbf513f4aa7880e3b18ef3fdc05d7..1e9873d7b258ce1f0b2437cb1e487157a16f6834 100644 --- a/src/main/java/net/minecraft/CrashReportCategory.java +++ b/src/main/java/net/minecraft/CrashReportCategory.java @@ -110,6 +110,7 @@ public class CrashReportCategory { @@ -496,10 +496,10 @@ index 77985072928a1b892fb4f7dec1d0899324780082..f5e6610d271ef2c997fb3d1a5f65e0bf protected void channelRead0(ChannelHandlerContext channelhandlercontext, Packet packet) { diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index b41eb920b5665b7a1b7cd9f38955c31eeb350847..bb59986c211f7d6ea50b1ad4bd5565227bec8a6c 100644 +index dcb9258d3fbdfdfd41065d4c0919ed4300eac3ae..a61a92078a8bb4979f231c02ef5aa990b8ab57ad 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -210,6 +210,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -209,6 +209,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface org.spigotmc.SpigotConfig.init((java.io.File) this.options.valueOf("spigot-settings")); org.spigotmc.SpigotConfig.registerCommands(); // Spigot end diff --git a/patches/unapplied/0016-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch b/patches/server/0016-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch similarity index 100% rename from patches/unapplied/0016-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch rename to patches/server/0016-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch diff --git a/patches/unapplied/0017-Paper-command.patch b/patches/server/0017-Paper-command.patch similarity index 98% rename from patches/unapplied/0017-Paper-command.patch rename to patches/server/0017-Paper-command.patch index 4d47273f6565..4b47a9acbbb3 100644 --- a/patches/unapplied/0017-Paper-command.patch +++ b/patches/server/0017-Paper-command.patch @@ -605,10 +605,10 @@ index 0000000000000000000000000000000000000000..ae60bd96b5284d54676d8e7e4dd5d170 + } +} diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index bb59986c211f7d6ea50b1ad4bd5565227bec8a6c..9c950fc1de15b5039e34a9fdf893e97a8cc13237 100644 +index a61a92078a8bb4979f231c02ef5aa990b8ab57ad..cd9e4bfdb3f335213001ced27540bb7efbc04130 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -215,6 +215,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -214,6 +214,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface this.paperConfigurations.initializeGlobalConfiguration(this.registryAccess()); this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess()); // Paper end - initialize global and world-defaults configuration @@ -617,10 +617,10 @@ index bb59986c211f7d6ea50b1ad4bd5565227bec8a6c..9c950fc1de15b5039e34a9fdf893e97a this.setPvpAllowed(dedicatedserverproperties.pvp); this.setFlightAllowed(dedicatedserverproperties.allowFlight); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 752933ceabd7ebe7b1e9f7d41198128f6f2182a6..492af80bc4a252ad3b82aef0c46c3e6625ec9146 100644 +index 2affb23b83e4368a94345b36410f23139f5d36c8..1b66c5173dd37433d895c0d804257141a3a8c588 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -988,6 +988,7 @@ public final class CraftServer implements Server { +@@ -991,6 +991,7 @@ public final class CraftServer implements Server { this.commandMap.clearCommands(); this.reloadData(); org.spigotmc.SpigotConfig.registerCommands(); // Spigot @@ -628,7 +628,7 @@ index 752933ceabd7ebe7b1e9f7d41198128f6f2182a6..492af80bc4a252ad3b82aef0c46c3e66 this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*"); this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions"); -@@ -2710,6 +2711,34 @@ public final class CraftServer implements Server { +@@ -2727,6 +2728,34 @@ public final class CraftServer implements Server { // Paper end // Paper start diff --git a/patches/unapplied/0018-Paper-Metrics.patch b/patches/server/0018-Paper-Metrics.patch similarity index 99% rename from patches/unapplied/0018-Paper-Metrics.patch rename to patches/server/0018-Paper-Metrics.patch index 46c111b03f3e..9ad0f5d70ea5 100644 --- a/patches/unapplied/0018-Paper-Metrics.patch +++ b/patches/server/0018-Paper-Metrics.patch @@ -698,10 +698,10 @@ index 0000000000000000000000000000000000000000..6aaed8e8bf8c721fc834da5c76ac72a4 + } +} diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 9c950fc1de15b5039e34a9fdf893e97a8cc13237..6ba90739c20995362a5275e2259cac9e17fbcf59 100644 +index cd9e4bfdb3f335213001ced27540bb7efbc04130..3b403e9edf4e860160dd230977870f21a0e32a7a 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -216,6 +216,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -215,6 +215,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess()); // Paper end - initialize global and world-defaults configuration io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command @@ -710,7 +710,7 @@ index 9c950fc1de15b5039e34a9fdf893e97a8cc13237..6ba90739c20995362a5275e2259cac9e this.setPvpAllowed(dedicatedserverproperties.pvp); this.setFlightAllowed(dedicatedserverproperties.allowFlight); diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java -index b717c9d8b6edc2cafc9281140913b7bdb6108cf0..ba621fdc82896245f6ce448e084847edc4d3fe08 100644 +index 744edd40128c910c3ad2f3657bde995612e0a1e4..d9e73e37b54e2f6e13313977c76cb4212c240992 100644 --- a/src/main/java/org/spigotmc/SpigotConfig.java +++ b/src/main/java/org/spigotmc/SpigotConfig.java @@ -83,6 +83,7 @@ public class SpigotConfig diff --git a/patches/unapplied/0019-Paper-Plugins.patch b/patches/server/0019-Paper-Plugins.patch similarity index 99% rename from patches/unapplied/0019-Paper-Plugins.patch rename to patches/server/0019-Paper-Plugins.patch index 1fdf462bb383..f473973b3c6d 100644 --- a/patches/unapplied/0019-Paper-Plugins.patch +++ b/patches/server/0019-Paper-Plugins.patch @@ -7203,10 +7203,10 @@ index f7114d5b8f2f93f62883e24da29afaf9f74ee1a6..8bf0630c0e06950cd99b7ae9898137f7 return foundFrame.orElse(null); diff --git a/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java b/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java -index 34b3b3251da21bce616870d312fd42fd58ba7881..cbc1658e0df4070605a6b2fbe99167b3bc001223 100644 +index f66a2154486b6d3b5873da043e51df91cd396c72..3f72e30b57fb2a4231e22a2234729408c1240af4 100644 --- a/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java +++ b/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java -@@ -322,7 +322,13 @@ public class BuiltInRegistries { +@@ -330,7 +330,13 @@ public class BuiltInRegistries { } public static void bootStrap() { @@ -7221,10 +7221,10 @@ index 34b3b3251da21bce616870d312fd42fd58ba7881..cbc1658e0df4070605a6b2fbe99167b3 validate(REGISTRY); } diff --git a/src/main/java/net/minecraft/server/Bootstrap.java b/src/main/java/net/minecraft/server/Bootstrap.java -index 394792291e3b89e5fd757907eecd85ccc71183e2..8f1992188f7fd9e735569e099b36a7eafed47aae 100644 +index aa38282b0f5461fc623a69d9860523a678a6bcd6..9abd1dea58ffc612114d5fd8e8944d4aa8c68236 100644 --- a/src/main/java/net/minecraft/server/Bootstrap.java +++ b/src/main/java/net/minecraft/server/Bootstrap.java -@@ -62,6 +62,7 @@ public class Bootstrap { +@@ -63,6 +63,7 @@ public class Bootstrap { Bootstrap.isBootstrapped = true; Instant instant = Instant.now(); @@ -7232,7 +7232,7 @@ index 394792291e3b89e5fd757907eecd85ccc71183e2..8f1992188f7fd9e735569e099b36a7ea if (BuiltInRegistries.REGISTRY.keySet().isEmpty()) { throw new IllegalStateException("Unable to load registries"); } else { -@@ -73,7 +74,10 @@ public class Bootstrap { +@@ -74,7 +75,10 @@ public class Bootstrap { EntitySelectorOptions.bootStrap(); DispenseItemBehavior.bootStrap(); CauldronInteraction.bootStrap(); @@ -7245,7 +7245,7 @@ index 394792291e3b89e5fd757907eecd85ccc71183e2..8f1992188f7fd9e735569e099b36a7ea Bootstrap.wrapStreams(); Bootstrap.bootstrapDuration.set(Duration.between(instant, Instant.now()).toMillis()); diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index 5b4ac7b4fd0077e900e9f788963f1613bbc9a5d0..6afede80c10503a261d0f735c351d943597be9ff 100644 +index 9bd6056bba6ba48bada7e9cd5883b0a171b0bbc4..7399358f18dc7869fbfe414186cf18414c1eaafc 100644 --- a/src/main/java/net/minecraft/server/Main.java +++ b/src/main/java/net/minecraft/server/Main.java @@ -119,6 +119,7 @@ public class Main { @@ -7257,10 +7257,10 @@ index 5b4ac7b4fd0077e900e9f788963f1613bbc9a5d0..6afede80c10503a261d0f735c351d943 Bootstrap.validate(); Util.startTimerHackThread(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 492af80bc4a252ad3b82aef0c46c3e6625ec9146..3d98004af5c872f8a183476183d1cc89a2aac4b6 100644 +index 1b66c5173dd37433d895c0d804257141a3a8c588..e8c1ceed228a1dfb9f3c76b54a91d712c511ffb5 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -277,7 +277,8 @@ public final class CraftServer implements Server { +@@ -280,7 +280,8 @@ public final class CraftServer implements Server { private final CraftCommandMap commandMap = new CraftCommandMap(this); private final SimpleHelpMap helpMap = new SimpleHelpMap(this); private final StandardMessenger messenger = new StandardMessenger(); @@ -7270,7 +7270,7 @@ index 492af80bc4a252ad3b82aef0c46c3e6625ec9146..3d98004af5c872f8a183476183d1cc89 private final StructureManager structureManager; protected final DedicatedServer console; protected final DedicatedPlayerList playerList; -@@ -455,24 +456,7 @@ public final class CraftServer implements Server { +@@ -458,24 +459,7 @@ public final class CraftServer implements Server { } public void loadPlugins() { @@ -7296,7 +7296,7 @@ index 492af80bc4a252ad3b82aef0c46c3e6625ec9146..3d98004af5c872f8a183476183d1cc89 } public void enablePlugins(PluginLoadOrder type) { -@@ -561,15 +545,17 @@ public final class CraftServer implements Server { +@@ -564,15 +548,17 @@ public final class CraftServer implements Server { private void enablePlugin(Plugin plugin) { try { List perms = plugin.getDescription().getPermissions(); @@ -7320,7 +7320,7 @@ index 492af80bc4a252ad3b82aef0c46c3e6625ec9146..3d98004af5c872f8a183476183d1cc89 this.pluginManager.enablePlugin(plugin); } catch (Throwable ex) { -@@ -1012,6 +998,7 @@ public final class CraftServer implements Server { +@@ -1015,6 +1001,7 @@ public final class CraftServer implements Server { "This plugin is not properly shutting down its async tasks when it is being reloaded. This may cause conflicts with the newly loaded version of the plugin" )); } @@ -7329,12 +7329,12 @@ index 492af80bc4a252ad3b82aef0c46c3e6625ec9146..3d98004af5c872f8a183476183d1cc89 this.enablePlugins(PluginLoadOrder.STARTUP); this.enablePlugins(PluginLoadOrder.POSTWORLD); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 655ceaa92b9979fe29725f9812507731bb0bb484..a339a0aa6fd7cc7be810e93bc9eb192437519c75 100644 +index e04586249625dc8d77ad5eecd06b8b88fa288503..1aae364ee6c67b6c89a59ad6cab83bb921645453 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -401,6 +401,16 @@ public final class CraftMagicNumbers implements UnsafeValues { net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack); - return nmsItemStack.getItem().getDescriptionId(nmsItemStack); + return nmsItemStack.getItem().getDescriptionId(); } + // Paper start + @Override @@ -8154,7 +8154,7 @@ index 0000000000000000000000000000000000000000..ba271c35eb2804f94cfc893bf94affb9 + } +} diff --git a/src/test/java/org/bukkit/support/DummyServerHelper.java b/src/test/java/org/bukkit/support/DummyServerHelper.java -index ba0a2ab9de34fa40dd90cecaeec4a5e54fe3e2d8..5d24b95e3eec351ec1e9444533dd5f9d376ec4c6 100644 +index bdfa164ea21cba91b30b965d65d47112111a1209..2fed099bc91a8591a2415493b333f9c18bfe35f6 100644 --- a/src/test/java/org/bukkit/support/DummyServerHelper.java +++ b/src/test/java/org/bukkit/support/DummyServerHelper.java @@ -87,7 +87,7 @@ public final class DummyServerHelper { diff --git a/patches/unapplied/0020-Plugin-remapping.patch b/patches/server/0020-Plugin-remapping.patch similarity index 99% rename from patches/unapplied/0020-Plugin-remapping.patch rename to patches/server/0020-Plugin-remapping.patch index b3cdef4eca93..d0b034e9a9a4 100644 --- a/patches/unapplied/0020-Plugin-remapping.patch +++ b/patches/server/0020-Plugin-remapping.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Plugin remapping Co-authored-by: Nassim Jahnke diff --git a/build.gradle.kts b/build.gradle.kts -index 3c9a9d2c44a3b177408ddfb3cad1e09169bf148b..ccf6e24f016991ac5987b5872037bf44d17e698f 100644 +index c73ab51caa985089ade4df0616ee8d3333632980..9086a65f5d593eea72a89d1153f6d353dfac1619 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -47,6 +47,7 @@ dependencies { @@ -1553,10 +1553,10 @@ index 0000000000000000000000000000000000000000..badff5d6ae6dd8d209c82bc7e8afe370 + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index b334cfc9b98d96f9bfba1d5b14c03c336d30ff23..e880543e94189fea3ba62eb7fb05ff48bc425299 100644 +index 11832f0d93ae86cb3d54bd82f9377b915b4365d3..3d1e9f24b83513c9f499471e7eefaf639f9097ec 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -642,6 +642,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop diff --git a/build.gradle.kts b/build.gradle.kts -index 381a4885c4f52c1e094af350fcb7e04b590f849a..6d8f4c3b290609d60dbcabe3d2c8274b017246c8 100644 +index 9086a65f5d593eea72a89d1153f6d353dfac1619..e1cfa2188dbe583a0180be2243a7a554dc5412d7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -48,6 +48,12 @@ dependencies { @@ -608,7 +608,7 @@ index 0000000000000000000000000000000000000000..a3045afbc0cc057e99189b909367b21c + } +} diff --git a/src/main/java/io/papermc/paper/util/MappingEnvironment.java b/src/main/java/io/papermc/paper/util/MappingEnvironment.java -index 8e4229634d41a42b3d93948eebb77def7c0c72b1..fb6aa9e2575b22e3089ea7fb32e6abfa6bb07d18 100644 +index 8e4229634d41a42b3d93948eebb77def7c0c72b1..4477944f632a6b3936960ee80f9d898d3b7eed19 100644 --- a/src/main/java/io/papermc/paper/util/MappingEnvironment.java +++ b/src/main/java/io/papermc/paper/util/MappingEnvironment.java @@ -10,6 +10,8 @@ import org.checkerframework.framework.qual.DefaultQualifier; @@ -616,7 +616,7 @@ index 8e4229634d41a42b3d93948eebb77def7c0c72b1..fb6aa9e2575b22e3089ea7fb32e6abfa @DefaultQualifier(NonNull.class) public final class MappingEnvironment { + public static final boolean DISABLE_PLUGIN_REMAPPING = Boolean.getBoolean("paper.disablePluginRemapping"); -+ public static final String LEGACY_CB_VERSION = "v1_21_R1"; ++ public static final String LEGACY_CB_VERSION = "v1_21_R2"; private static final @Nullable String MAPPINGS_HASH = readMappingsHash(); private static final boolean REOBF = checkReobf(); @@ -705,7 +705,7 @@ index 2a29f60c3e82239ab7acd85242fc3390cb9129cd..91c6721201b095eb32c5fd5a1aaf2cbc final Set rerouteMethodData = new HashSet<>(); String className; diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index a339a0aa6fd7cc7be810e93bc9eb192437519c75..33d3085d0d44d748fcb1fc203dfd14c9e1b4aff0 100644 +index 1aae364ee6c67b6c89a59ad6cab83bb921645453..a45c08c423248a60f9d5822046014427a6dadd12 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -74,6 +74,7 @@ import org.bukkit.potion.PotionType; diff --git a/patches/unapplied/0023-Timings-v2.patch b/patches/server/0023-Timings-v2.patch similarity index 87% rename from patches/unapplied/0023-Timings-v2.patch rename to patches/server/0023-Timings-v2.patch index 61ba53e72285..710f9d8a42d8 100644 --- a/patches/unapplied/0023-Timings-v2.patch +++ b/patches/server/0023-Timings-v2.patch @@ -714,19 +714,19 @@ index f7197f1347251a37dd0f6d9ffa2f09bc3a4e1233..d0d36a57ec4896bcb74970f8fb24d8f3 } catch (Exception exception) { if (exception instanceof ReportedException) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index e880543e94189fea3ba62eb7fb05ff48bc425299..49de4625c57689a3624ed421c0b03512507c97c3 100644 +index 3d1e9f24b83513c9f499471e7eefaf639f9097ec..4502e2cf565b7b0547a1963b1119d7810b7a0bcb 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -196,7 +196,7 @@ import org.bukkit.craftbukkit.Main; +@@ -203,7 +203,7 @@ import org.bukkit.craftbukkit.Main; import org.bukkit.event.server.ServerLoadEvent; // CraftBukkit end -import org.bukkit.craftbukkit.SpigotTimings; // Spigot +import co.aikar.timings.MinecraftTimings; // Paper - public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource, AutoCloseable { + public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource { -@@ -911,6 +911,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -- return !this.haveTime(); -+ return !this.canSleepForTickNoOversleep(); // Paper - move oversleep into full server tick - }); - } ++ //this.runAllTasks(); // Paper - move this into the tick method for timings + this.waitingForNextTick = true; -@@ -1321,9 +1334,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { +- return !this.haveTime(); ++ return !this.canSleepForTickNoOversleep(); // Paper - move oversleep into full server tick + }); + } finally { + this.waitingForNextTick = false; +@@ -1369,7 +1382,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { @@ -787,53 +796,58 @@ index e880543e94189fea3ba62eb7fb05ff48bc425299..49de4625c57689a3624ed421c0b03512 ++this.tickCount; this.tickRateManager.tick(); this.tickChildren(shouldKeepTicking); -@@ -1337,14 +1358,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0 && this.ticksUntilAutosave <= 0) { - this.ticksUntilAutosave = this.autosavePeriod; - // CraftBukkit end -- SpigotTimings.worldSaveTimer.startTiming(); // Spigot - MinecraftServer.LOGGER.debug("Autosave started"); - this.profiler.push("save"); - this.saveEverything(true, false, false); - this.profiler.pop(); - MinecraftServer.LOGGER.debug("Autosave finished"); -- SpigotTimings.worldSaveTimer.stopTiming(); // Spigot - } +@@ -1408,6 +1428,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { entityplayer.connection.suspendFlushing(); }); - SpigotTimings.schedulerTimer.startTiming(); // Spigot + MinecraftTimings.bukkitSchedulerTimer.startTiming(); // Spigot // Paper - this.server.getScheduler().mainThreadHeartbeat(this.tickCount); // CraftBukkit + this.server.getScheduler().mainThreadHeartbeat(); // CraftBukkit - SpigotTimings.schedulerTimer.stopTiming(); // Spigot + MinecraftTimings.bukkitSchedulerTimer.stopTiming(); // Spigot // Paper io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.CALLBACK_MANAGER.handleQueue(this.tickCount); // Paper - this.profiler.push("commandFunctions"); + gameprofilerfiller.push("commandFunctions"); - SpigotTimings.commandFunctionsTimer.startTiming(); // Spigot + MinecraftTimings.commandFunctionsTimer.startTiming(); // Spigot // Paper this.getFunctions().tick(); - SpigotTimings.commandFunctionsTimer.stopTiming(); // Spigot + MinecraftTimings.commandFunctionsTimer.stopTiming(); // Spigot // Paper - this.profiler.popPush("levels"); + gameprofilerfiller.popPush("levels"); Iterator iterator = this.getAllLevels().iterator(); // CraftBukkit start @@ -851,8 +865,8 @@ index e880543e94189fea3ba62eb7fb05ff48bc425299..49de4625c57689a3624ed421c0b03512 // Send time updates to everyone, it will get the right time from the world the player is in. if (this.tickCount % 20 == 0) { for (int i = 0; i < this.getPlayerList().players.size(); ++i) { -@@ -1455,7 +1478,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { CommandSourceStack wrapper = rconConsoleSource.createCommandSourceStack(); RemoteServerCommandEvent event = new RemoteServerCommandEvent(rconConsoleSource.getBukkitSender(wrapper), s); -@@ -720,9 +723,39 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -702,9 +705,39 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface if (event.isCancelled()) { return; } @@ -977,7 +991,7 @@ index d38ecbc208c34509eaf77751ac45d9ef51a5dce8..b51c3f8c485496734ea58c15377a1215 // CraftBukkit end } diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 449608e60f3900778247101581ff598f1637499b..bb5115b3593c314f5edfb5947a3c35a489bf71af 100644 +index b6fb3921b7df9748e38df494fd0012f45d97ac4b..5c9ed5091d61418d99582cb5a7242b5e10126dc5 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 @@ @@ -991,7 +1005,7 @@ index 449608e60f3900778247101581ff598f1637499b..bb5115b3593c314f5edfb5947a3c35a4 import com.google.common.collect.Lists; import com.google.common.collect.Queues; import com.google.common.collect.Sets; -@@ -1296,6 +1298,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1355,6 +1357,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider List list = Lists.newArrayList(); List list1 = this.level.players(); ObjectIterator objectiterator = this.entityMap.values().iterator(); @@ -999,7 +1013,7 @@ index 449608e60f3900778247101581ff598f1637499b..bb5115b3593c314f5edfb5947a3c35a4 ChunkMap.TrackedEntity playerchunkmap_entitytracker; -@@ -1320,14 +1323,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1379,14 +1382,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider playerchunkmap_entitytracker.serverEntity.sendChanges(); } } @@ -1018,10 +1032,10 @@ index 449608e60f3900778247101581ff598f1637499b..bb5115b3593c314f5edfb5947a3c35a4 } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index cf94dd9ddcc1eabcf3fd336e70720f4ed3e52175..e0c8b89767087cba34fc3c3809db4c386dacb193 100644 +index c615510f3f59292715bcff1bd9e4e896c9733436..a29598ae54d5d20740a105f81bcaec2a152fe4ba 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -195,13 +195,15 @@ public class ServerChunkCache extends ChunkSource { +@@ -207,13 +207,15 @@ public class ServerChunkCache extends ChunkSource { } gameprofilerfiller.incrementCounter("getChunkCacheMiss"); @@ -1039,7 +1053,7 @@ index cf94dd9ddcc1eabcf3fd336e70720f4ed3e52175..e0c8b89767087cba34fc3c3809db4c38 ChunkResult chunkresult = (ChunkResult) completablefuture.join(); ChunkAccess ichunkaccess1 = (ChunkAccess) chunkresult.orElse(null); // CraftBukkit - decompile error -@@ -366,7 +368,9 @@ public class ServerChunkCache extends ChunkSource { +@@ -382,7 +384,9 @@ public class ServerChunkCache extends ChunkSource { public void save(boolean flush) { this.runDistanceManagerUpdates(); @@ -1049,9 +1063,9 @@ index cf94dd9ddcc1eabcf3fd336e70720f4ed3e52175..e0c8b89767087cba34fc3c3809db4c38 } @Override -@@ -408,10 +412,10 @@ public class ServerChunkCache extends ChunkSource { +@@ -429,10 +433,10 @@ public class ServerChunkCache extends ChunkSource { this.level.timings.doChunkMap.stopTiming(); // Spigot - this.level.getProfiler().popPush("chunks"); + gameprofilerfiller.popPush("chunks"); if (tickChunks) { + this.level.timings.chunks.startTiming(); // Paper - timings this.tickChunks(); @@ -1062,55 +1076,57 @@ index cf94dd9ddcc1eabcf3fd336e70720f4ed3e52175..e0c8b89767087cba34fc3c3809db4c38 } this.level.timings.doChunkUnload.startTiming(); // Spigot -@@ -434,6 +438,7 @@ public class ServerChunkCache extends ChunkSource { - gameprofilerfiller.push("filteringLoadedChunks"); - List list = Lists.newArrayListWithCapacity(this.chunkMap.size()); - Iterator iterator = this.chunkMap.getChunks().iterator(); +@@ -442,6 +446,7 @@ public class ServerChunkCache extends ChunkSource { + gameprofilerfiller.pop(); + this.clearCache(); + } + if (this.level.getServer().tickRateManager().runsNormally()) this.level.timings.chunkTicks.startTiming(); // Paper - while (iterator.hasNext()) { - ChunkHolder playerchunk = (ChunkHolder) iterator.next(); -@@ -446,8 +451,10 @@ public class ServerChunkCache extends ChunkSource { + private void tickChunks() { + long i = this.level.getGameTime(); +@@ -481,7 +486,9 @@ public class ServerChunkCache extends ChunkSource { + LevelChunk chunk = playerchunk.getTickingChunk(); - if (this.level.tickRateManager().runsNormally()) { - gameprofilerfiller.popPush("naturalSpawnCount"); -+ this.level.timings.countNaturalMobs.startTiming(); // Paper - timings - int k = this.distanceManager.getNaturalSpawnChunkCount(); - NaturalSpawner.SpawnState spawnercreature_d = NaturalSpawner.createState(k, this.level.getAllEntities(), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap)); -+ this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings + if (chunk != null) { ++ this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing + playerchunk.broadcastChanges(chunk); ++ this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing + } + } - this.lastSpawnState = spawnercreature_d; - gameprofilerfiller.popPush("spawnAndTick"); -@@ -470,22 +477,25 @@ public class ServerChunkCache extends ChunkSource { - } +@@ -502,8 +509,10 @@ public class ServerChunkCache extends ChunkSource { - if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { -- this.level.timings.doTickTiles.startTiming(); // Spigot - this.level.tickChunk(chunk1, l); -- this.level.timings.doTickTiles.stopTiming(); // Spigot - } - } - } -+ this.level.timings.chunkTicks.stopTiming(); // Paper + private void tickChunks(ProfilerFiller profiler, long timeDelta, List chunks) { + profiler.popPush("naturalSpawnCount"); ++ this.level.timings.countNaturalMobs.startTiming(); // Paper - timings + int j = this.distanceManager.getNaturalSpawnChunkCount(); + NaturalSpawner.SpawnState spawnercreature_d = NaturalSpawner.createState(j, this.level.getAllEntities(), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap)); ++ this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings - gameprofilerfiller.popPush("customSpawners"); - if (flag) { -+ try (co.aikar.timings.Timing ignored = this.level.timings.miscMobSpawning.startTiming()) { // Paper - timings - this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies); -+ } // Paper - timings - } + this.lastSpawnState = spawnercreature_d; + profiler.popPush("spawnAndTick"); +@@ -531,15 +540,17 @@ public class ServerChunkCache extends ChunkSource { } - gameprofilerfiller.popPush("broadcast"); - list.forEach((chunkproviderserver_a1) -> { -+ this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing - chunkproviderserver_a1.holder.broadcastChanges(chunkproviderserver_a1.chunk); -+ this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing - }); - gameprofilerfiller.pop(); - gameprofilerfiller.pop(); + if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { +- this.level.timings.doTickTiles.startTiming(); // Spigot + this.level.tickChunk(chunk, k); +- this.level.timings.doTickTiles.stopTiming(); // Spigot + } + } + ++ this.level.timings.chunkTicks.stopTiming(); // Paper ++ + profiler.popPush("customSpawners"); + if (flag) { ++ try (co.aikar.timings.Timing ignored = this.level.timings.miscMobSpawning.startTiming()) { // Paper - timings + this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies); ++ } + } + + } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 4c39d9e0466240b5cd459ee649a22fe3a72bf9f0..eb98bb1bd76869fd76b34885223c8e57a04e0c51 100644 +index 6fe373de360570b528b8133043ef3bb9ba12529d..d82f4255faac84ce6af47e86707f5c035529ab5d 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 @@ @@ -1122,7 +1138,7 @@ index 4c39d9e0466240b5cd459ee649a22fe3a72bf9f0..eb98bb1bd76869fd76b34885223c8e57 import com.google.common.collect.Lists; import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.util.Pair; -@@ -173,7 +175,6 @@ import net.minecraft.world.ticks.LevelTicks; +@@ -176,7 +178,6 @@ import net.minecraft.world.ticks.LevelTicks; import org.slf4j.Logger; import org.bukkit.Bukkit; import org.bukkit.WeatherType; @@ -1130,16 +1146,16 @@ index 4c39d9e0466240b5cd459ee649a22fe3a72bf9f0..eb98bb1bd76869fd76b34885223c8e57 import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.craftbukkit.generator.CustomWorldChunkManager; import org.bukkit.craftbukkit.util.WorldUUID; -@@ -478,7 +479,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -469,7 +470,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } - gameprofilerfiller.popPush("tickPending"); + gameprofilerfiller.push("tickPending"); - this.timings.doTickPending.startTiming(); // Spigot + this.timings.scheduledBlocks.startTiming(); // Paper if (!this.isDebug() && flag) { j = this.getGameTime(); gameprofilerfiller.push("blockTicks"); -@@ -487,15 +488,19 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -478,15 +479,19 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.fluidTicks.tick(j, 65536, this::tickFluid); gameprofilerfiller.pop(); } @@ -1160,7 +1176,7 @@ index 4c39d9e0466240b5cd459ee649a22fe3a72bf9f0..eb98bb1bd76869fd76b34885223c8e57 gameprofilerfiller.popPush("blockEvents"); if (flag) { this.timings.doSounds.startTiming(); // Spigot -@@ -648,6 +653,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -635,6 +640,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } gameprofilerfiller.popPush("tickBlocks"); @@ -1168,7 +1184,7 @@ index 4c39d9e0466240b5cd459ee649a22fe3a72bf9f0..eb98bb1bd76869fd76b34885223c8e57 if (randomTickSpeed > 0) { LevelChunkSection[] achunksection = chunk.getSections(); -@@ -680,6 +686,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -667,6 +673,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } } @@ -1176,7 +1192,7 @@ index 4c39d9e0466240b5cd459ee649a22fe3a72bf9f0..eb98bb1bd76869fd76b34885223c8e57 gameprofilerfiller.pop(); } -@@ -956,14 +963,22 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -944,14 +951,22 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } public void tickNonPassenger(Entity entity) { @@ -1198,9 +1214,9 @@ index 4c39d9e0466240b5cd459ee649a22fe3a72bf9f0..eb98bb1bd76869fd76b34885223c8e57 + try { + // Paper end - timings entity.setOldPosAndRot(); - ProfilerFiller gameprofilerfiller = this.getProfiler(); + ProfilerFiller gameprofilerfiller = Profiler.get(); -@@ -982,7 +997,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -970,7 +985,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.tickPassenger(entity, entity1); } @@ -1209,7 +1225,7 @@ index 4c39d9e0466240b5cd459ee649a22fe3a72bf9f0..eb98bb1bd76869fd76b34885223c8e57 } -@@ -1024,6 +1039,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1012,6 +1027,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (!savingDisabled) { org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(this.getWorld())); // CraftBukkit @@ -1217,7 +1233,7 @@ index 4c39d9e0466240b5cd459ee649a22fe3a72bf9f0..eb98bb1bd76869fd76b34885223c8e57 if (progressListener != null) { progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel")); } -@@ -1033,7 +1049,10 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1021,7 +1037,10 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe progressListener.progressStage(Component.translatable("menu.savingChunks")); } @@ -1229,10 +1245,10 @@ index 4c39d9e0466240b5cd459ee649a22fe3a72bf9f0..eb98bb1bd76869fd76b34885223c8e57 this.entityManager.saveAll(); } else { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 4acee8121ff62413dbbf2294d17da3bd2f974d5a..3a67b2b6a6d3204b2a7bbe8adbf2b0ecf7898551 100644 +index eed5dd58fc37c137c87bf3e55e1e033b74002110..7a130da1b50a67331a862f96934739845c7b2d67 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -330,7 +330,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -337,7 +337,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void tick() { @@ -1240,7 +1256,7 @@ index 4acee8121ff62413dbbf2294d17da3bd2f974d5a..3a67b2b6a6d3204b2a7bbe8adbf2b0ec if (this.ackBlockChangesUpTo > -1) { this.send(new ClientboundBlockChangedAckPacket(this.ackBlockChangesUpTo)); this.ackBlockChangesUpTo = -1; -@@ -397,7 +396,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -393,7 +392,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 this.disconnect((Component) Component.translatable("multiplayer.disconnect.idling")); } @@ -1248,7 +1264,7 @@ index 4acee8121ff62413dbbf2294d17da3bd2f974d5a..3a67b2b6a6d3204b2a7bbe8adbf2b0ec } -@@ -2103,7 +2101,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2114,7 +2112,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } private void handleCommand(String s) { @@ -1257,7 +1273,7 @@ index 4acee8121ff62413dbbf2294d17da3bd2f974d5a..3a67b2b6a6d3204b2a7bbe8adbf2b0ec if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s); -@@ -2113,7 +2111,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2124,7 +2122,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.cserver.getPluginManager().callEvent(event); if (event.isCancelled()) { @@ -1266,7 +1282,7 @@ index 4acee8121ff62413dbbf2294d17da3bd2f974d5a..3a67b2b6a6d3204b2a7bbe8adbf2b0ec return; } -@@ -2126,7 +2124,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2137,7 +2135,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl java.util.logging.Logger.getLogger(ServerGamePacketListenerImpl.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); return; } finally { @@ -1276,7 +1292,7 @@ index 4acee8121ff62413dbbf2294d17da3bd2f974d5a..3a67b2b6a6d3204b2a7bbe8adbf2b0ec } // 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 9dcfcea63f57f45a5584bb80c34fe445d65849e8..765c412cd0c5cd410c224b4bc55dbf431fd6617b 100644 +index 56f046bac04205a813441907058c4ce21982d927..b103d49458330be9f7fb3382c764b204a02a925a 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -1,5 +1,6 @@ @@ -1286,7 +1302,7 @@ index 9dcfcea63f57f45a5584bb80c34fe445d65849e8..765c412cd0c5cd410c224b4bc55dbf43 import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -@@ -1007,10 +1008,11 @@ public abstract class PlayerList { +@@ -976,10 +977,11 @@ public abstract class PlayerList { } public void saveAll() { @@ -1300,10 +1316,10 @@ index 9dcfcea63f57f45a5584bb80c34fe445d65849e8..765c412cd0c5cd410c224b4bc55dbf43 public UserWhiteList getWhiteList() { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 06cbe7a7ea131a8bead857cbfbd27810a9093320..0a3ed94165430774c7037e78fd7bffc205c6f72f 100644 +index c010d18061f58a583c69e85fc29305497523f569..c8b8102d84119dfb6093f4b79aa3124c594f9a88 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -140,7 +140,6 @@ import org.bukkit.command.CommandSender; +@@ -148,7 +148,6 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Hanging; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Vehicle; @@ -1311,7 +1327,7 @@ index 06cbe7a7ea131a8bead857cbfbd27810a9093320..0a3ed94165430774c7037e78fd7bffc2 import org.bukkit.event.entity.EntityCombustByEntityEvent; import org.bukkit.event.hanging.HangingBreakByEntityEvent; import org.bukkit.event.vehicle.VehicleBlockCollisionEvent; -@@ -323,7 +322,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -326,7 +325,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // Marks an entity, that it was removed by a plugin via Entity#remove // Main use case currently is for SPIGOT-7487, preventing dropping of leash when leash is removed public boolean pluginRemoved = false; @@ -1319,30 +1335,30 @@ index 06cbe7a7ea131a8bead857cbfbd27810a9093320..0a3ed94165430774c7037e78fd7bffc2 // Spigot start public final org.spigotmc.ActivationRange.ActivationType activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this); public final boolean defaultActivationState; -@@ -840,7 +838,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -866,7 +864,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } - public void move(MoverType movementType, Vec3 movement) { + public void move(MoverType type, Vec3 movement) { - org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.startTiming(); // Spigot if (this.noPhysics) { this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z); } else { -@@ -1001,7 +998,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - this.level().getProfiler().pop(); +@@ -978,7 +975,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + gameprofilerfiller.pop(); } } - org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.stopTiming(); // Spigot } - private boolean isStateClimbable(BlockState state) { + private void applyMovementEmissionAndPlaySound(Entity.MovementEmission moveEffect, Vec3 movement, BlockPos landingPos, BlockState landingState) { diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index e465aaa4fd29b4966ea8d88316c6d8f217da2e73..474f020371bb9e5fd2c5b22e44d7902977c4fc18 100644 +index 17ab230c95901f0533997ac117d5b3d852fcd467..0782b2b58ed30d4ef2598e4b89f338a94a62bbe5 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -339,6 +339,15 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -413,6 +413,16 @@ public class EntityType implements FeatureElement, EntityTypeT } - public EntityType(EntityType.EntityFactory factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet canSpawnInside, EntityDimensions dimensions, float spawnBoxScale, int maxTrackDistance, int trackTickInterval, FeatureFlagSet requiredFeatures) { + public EntityType(EntityType.EntityFactory factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet canSpawnInside, EntityDimensions dimensions, float spawnBoxScale, int maxTrackDistance, int trackTickInterval, String translationKey, Optional> lootTable, FeatureFlagSet requiredFeatures) { + // Paper start + this(factory, spawnGroup, saveable, summonable, fireImmune, spawnableFarFromPlayer, canSpawnInside, dimensions, spawnBoxScale, maxTrackDistance, trackTickInterval, requiredFeatures, "custom"); + } @@ -1351,11 +1367,12 @@ index e465aaa4fd29b4966ea8d88316c6d8f217da2e73..474f020371bb9e5fd2c5b22e44d79029 + this.inactiveTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "inactiveTick"); + this.passengerTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "passengerTick"); + this.passengerInactiveTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "passengerInactiveTick"); ++ this.id = id; + // Paper end this.builtInRegistryHolder = BuiltInRegistries.ENTITY_TYPE.createIntrusiveHolder(this); this.factory = factory; this.category = spawnGroup; -@@ -654,6 +663,12 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -720,6 +730,13 @@ public class EntityType implements FeatureElement, EntityTypeT return this.updateInterval; } @@ -1364,24 +1381,25 @@ index e465aaa4fd29b4966ea8d88316c6d8f217da2e73..474f020371bb9e5fd2c5b22e44d79029 + public final co.aikar.timings.Timing inactiveTickTimer; + public final co.aikar.timings.Timing passengerTickTimer; + public final co.aikar.timings.Timing passengerInactiveTickTimer; ++ private final String id; + // Paper end public boolean trackDeltas() { return this != EntityType.PLAYER && this != EntityType.LLAMA_SPIT && this != EntityType.WITHER && this != EntityType.BAT && this != EntityType.ITEM_FRAME && this != EntityType.GLOW_ITEM_FRAME && this != EntityType.LEASH_KNOT && this != EntityType.PAINTING && this != EntityType.END_CRYSTAL && this != EntityType.EVOKER_FANGS; } -@@ -823,7 +838,7 @@ public class EntityType implements FeatureElement, EntityTypeT - Util.fetchChoiceType(References.ENTITY_TREE, id); +@@ -926,7 +943,7 @@ public class EntityType implements FeatureElement, EntityTypeT + Util.fetchChoiceType(References.ENTITY_TREE, registryKey.location().toString()); } -- return new EntityType<>(this.factory, this.category, this.serialize, this.summon, this.fireImmune, this.canSpawnFarFromPlayer, this.immuneTo, this.dimensions.withAttachments(this.attachments), this.spawnDimensionsScale, this.clientTrackingRange, this.updateInterval, this.requiredFeatures); -+ return new EntityType<>(this.factory, this.category, this.serialize, this.summon, this.fireImmune, this.canSpawnFarFromPlayer, this.immuneTo, this.dimensions.withAttachments(this.attachments), this.spawnDimensionsScale, this.clientTrackingRange, this.updateInterval, this.requiredFeatures, id); // Paper - add id +- return new EntityType<>(this.factory, this.category, this.serialize, this.summon, this.fireImmune, this.canSpawnFarFromPlayer, this.immuneTo, this.dimensions.withAttachments(this.attachments), this.spawnDimensionsScale, this.clientTrackingRange, this.updateInterval, (String) this.descriptionId.get(registryKey), (Optional) this.lootTable.get(registryKey), this.requiredFeatures); ++ return new EntityType<>(this.factory, this.category, this.serialize, this.summon, this.fireImmune, this.canSpawnFarFromPlayer, this.immuneTo, this.dimensions.withAttachments(this.attachments), this.spawnDimensionsScale, this.clientTrackingRange, this.updateInterval, (String) this.descriptionId.get(registryKey), (Optional) this.lootTable.get(registryKey), this.requiredFeatures, this.id); // Paper - add id } } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 26064174397dc95f9b117d901e22c55abebf3c39..d1e042ec0c1a818d713b31c3d81b48327c3578d5 100644 +index 9aa4e70f1d1c4de2138d31701dceaed25062e69c..6cc86412d45186dff312d9b1246fd1d03dbc15d8 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -156,7 +156,7 @@ import org.bukkit.event.entity.EntityTeleportEvent; +@@ -162,7 +162,7 @@ import org.bukkit.event.entity.EntityTeleportEvent; import org.bukkit.event.player.PlayerItemConsumeEvent; // CraftBukkit end @@ -1390,7 +1408,7 @@ index 26064174397dc95f9b117d901e22c55abebf3c39..d1e042ec0c1a818d713b31c3d81b4832 public abstract class LivingEntity extends Entity implements Attackable { -@@ -2977,7 +2977,6 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3090,7 +3090,6 @@ public abstract class LivingEntity extends Entity implements Attackable { @Override public void tick() { @@ -1398,7 +1416,7 @@ index 26064174397dc95f9b117d901e22c55abebf3c39..d1e042ec0c1a818d713b31c3d81b4832 super.tick(); this.updatingUsingItem(); this.updateSwimAmount(); -@@ -3019,9 +3018,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3132,9 +3131,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } if (!this.isRemoved()) { @@ -1408,61 +1426,61 @@ index 26064174397dc95f9b117d901e22c55abebf3c39..d1e042ec0c1a818d713b31c3d81b4832 } double d0 = this.getX() - this.xo; -@@ -3112,7 +3109,6 @@ public abstract class LivingEntity extends Entity implements Attackable { - this.refreshDimensions(); +@@ -3228,7 +3225,6 @@ public abstract class LivingEntity extends Entity implements Attackable { } + this.elytraAnimationState.tick(); - SpigotTimings.timerEntityTickRest.stopTiming(); // Spigot } public void detectEquipmentUpdatesPublic() { // CraftBukkit -@@ -3328,7 +3324,6 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3435,7 +3431,6 @@ public abstract class LivingEntity extends Entity implements Attackable { + ProfilerFiller gameprofilerfiller = Profiler.get(); - this.setDeltaMovement(d0, d1, d2); - this.level().getProfiler().push("ai"); + gameprofilerfiller.push("ai"); - SpigotTimings.timerEntityAI.startTiming(); // Spigot if (this.isImmobile()) { this.jumping = false; this.xxa = 0.0F; -@@ -3338,7 +3333,6 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3445,7 +3440,6 @@ public abstract class LivingEntity extends Entity implements Attackable { this.serverAiStep(); - this.level().getProfiler().pop(); + gameprofilerfiller.pop(); } - SpigotTimings.timerEntityAI.stopTiming(); // Spigot - this.level().getProfiler().pop(); - this.level().getProfiler().push("jump"); -@@ -3378,7 +3372,6 @@ public abstract class LivingEntity extends Entity implements Attackable { + gameprofilerfiller.pop(); + gameprofilerfiller.push("jump"); +@@ -3488,7 +3482,6 @@ public abstract class LivingEntity extends Entity implements Attackable { this.resetFallDistance(); } - SpigotTimings.timerEntityAIMove.startTiming(); // Spigot - label104: + label112: { LivingEntity entityliving = this.getControllingPassenger(); -@@ -3392,7 +3385,6 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3502,7 +3495,6 @@ public abstract class LivingEntity extends Entity implements Attackable { this.travel(vec3d1); } - SpigotTimings.timerEntityAIMove.stopTiming(); // Spigot - this.level().getProfiler().pop(); - this.level().getProfiler().push("freezing"); -@@ -3419,9 +3411,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + if (!this.level().isClientSide() || this.isControlledByLocalInstance()) { + this.applyEffectsFromBlocks(); +@@ -3538,9 +3530,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.checkAutoSpinAttack(axisalignedbb, this.getBoundingBox()); } - SpigotTimings.timerEntityAICollision.startTiming(); // Spigot this.pushEntities(); - SpigotTimings.timerEntityAICollision.stopTiming(); // Spigot - this.level().getProfiler().pop(); - if (!this.level().isClientSide && this.isSensitiveToWater() && this.isInWaterRainOrBubble()) { - this.hurt(this.damageSources().drown(), 1.0F); + gameprofilerfiller.pop(); + world = this.level(); + if (world instanceof ServerLevel worldserver) { diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 2bc1d0d3ea8a6e3327e9c11bd1f0666d210e9bbe..79d5423be919dfe4db75ad7dd0ce403ad0214462 100644 +index 3fb17bbcecf6dc4af3b231835adff25f86e1379f..5df862e026e15e10e2fcc7c5a49e8a8022125579 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -93,7 +93,6 @@ import net.minecraft.network.protocol.game.ClientboundSetBorderWarningDistancePa +@@ -95,7 +95,6 @@ import net.minecraft.network.protocol.game.ClientboundSetBorderWarningDistancePa import org.bukkit.Bukkit; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.CraftWorld; @@ -1470,7 +1488,7 @@ index 2bc1d0d3ea8a6e3327e9c11bd1f0666d210e9bbe..79d5423be919dfe4db75ad7dd0ce403a import org.bukkit.craftbukkit.block.CapturedBlockState; import org.bukkit.craftbukkit.block.CraftBlockState; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@@ -164,7 +163,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -165,7 +164,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } // Paper end - add paper world config @@ -1488,7 +1506,7 @@ index 2bc1d0d3ea8a6e3327e9c11bd1f0666d210e9bbe..79d5423be919dfe4db75ad7dd0ce403a this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime); this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); } -@@ -723,15 +722,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -725,15 +724,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.timings.tileEntityTick.stopTiming(); // Spigot this.tickingBlockEntities = false; @@ -1506,7 +1524,7 @@ index 2bc1d0d3ea8a6e3327e9c11bd1f0666d210e9bbe..79d5423be919dfe4db75ad7dd0ce403a CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking entity"); CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being ticked"); diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index d1cfcc8a36964f006f1af6764c52b5ca458b478d..def3e28edc206e0ba41111e26332db468223fb2e 100644 +index 27cbec37c6ea278232970ae035795fdecca71735..3cefda12d4c2ca2c4e9ef97eff961a55af164d6b 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java @@ -88,6 +88,15 @@ public class Block extends BlockBehaviour implements ItemLike { @@ -1523,10 +1541,10 @@ index d1cfcc8a36964f006f1af6764c52b5ca458b478d..def3e28edc206e0ba41111e26332db46 + } + // Paper end @Nullable - private String descriptionId; - @Nullable + private Item item; + private static final int CACHE_SIZE = 256; diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index 6a4e5bfa70b31311a9076eb314c0a0146d5b08a5..17cda4c8b61efd99c1a43f921ed604827bb064f3 100644 +index 4c3bc3a495990bc486fce7ba1758bf731c3baf02..9afe509b3455a7aabd11976fb8a7430d1bce065d 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java @@ -34,10 +34,12 @@ import org.bukkit.inventory.InventoryHolder; @@ -1544,10 +1562,10 @@ index 6a4e5bfa70b31311a9076eb314c0a0146d5b08a5..17cda4c8b61efd99c1a43f921ed60482 private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); public CraftPersistentDataContainer persistentDataContainer; 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 25380a44e5cc94f3924cfee6a03c3091fea04ae2..418ba374886d93f69afd614e4be05f6561e1f897 100644 +index d76591694c3b167b8b8f17b61a373a43140a8b68..717e4bf9f5ee0ec2c3a0b5cc65a50b0f6d649a8d 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -602,6 +602,7 @@ public class LevelChunk extends ChunkAccess { +@@ -627,6 +627,7 @@ public class LevelChunk extends ChunkAccess { server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(bukkitChunk, this.needsDecoration)); if (this.needsDecoration) { @@ -1555,7 +1573,7 @@ index 25380a44e5cc94f3924cfee6a03c3091fea04ae2..418ba374886d93f69afd614e4be05f65 this.needsDecoration = false; java.util.Random random = new java.util.Random(); random.setSeed(this.level.getSeed()); -@@ -621,6 +622,7 @@ public class LevelChunk extends ChunkAccess { +@@ -646,6 +647,7 @@ public class LevelChunk extends ChunkAccess { } } server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(bukkitChunk)); @@ -1563,37 +1581,11 @@ index 25380a44e5cc94f3924cfee6a03c3091fea04ae2..418ba374886d93f69afd614e4be05f65 } } } -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index 46a090123e205394791cdbde2af84c58ce55f7e1..47f5f3d58bb3bf85cf35f9baae77df7fab5c844f 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -@@ -472,13 +472,10 @@ public class ChunkSerializer { - ListTag nbttaglist1 = ChunkSerializer.getListOfCompoundsOrNull(nbt, "block_entities"); - - return nbttaglist == null && nbttaglist1 == null ? null : (chunk) -> { -- world.timings.syncChunkLoadEntitiesTimer.startTiming(); // Spigot - if (nbttaglist != null) { - world.addLegacyChunkEntities(EntityType.loadEntitiesRecursive(nbttaglist, world)); - } -- world.timings.syncChunkLoadEntitiesTimer.stopTiming(); // Spigot - -- world.timings.syncChunkLoadTileEntitiesTimer.startTiming(); // Spigot - if (nbttaglist1 != null) { - for (int i = 0; i < nbttaglist1.size(); ++i) { - CompoundTag nbttagcompound1 = nbttaglist1.getCompound(i); -@@ -496,7 +493,6 @@ public class ChunkSerializer { - } - } - } -- world.timings.syncChunkLoadTileEntitiesTimer.stopTiming(); // Spigot - - }; - } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index cd6b6109ea3844f7d78ad7a1cbd6cf5dc3d90b5c..0fda501dedcc1f3f7d35e3b66a4b40394c4b3cb5 100644 +index 9bf8c4d9154c433e586f59587e8d7db7c310bb9c..232a21080ff416ac5b9fdf913f6784eb3bcdacfa 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -376,7 +376,7 @@ public final class CraftServer implements Server { +@@ -379,7 +379,7 @@ public final class CraftServer implements Server { this.saveCommandsConfig(); this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*"); this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions"); @@ -1602,7 +1594,7 @@ index cd6b6109ea3844f7d78ad7a1cbd6cf5dc3d90b5c..0fda501dedcc1f3f7d35e3b66a4b4039 this.overrideSpawnLimits(); console.autosavePeriod = this.configuration.getInt("ticks-per.autosave"); this.warningState = WarningState.value(this.configuration.getString("settings.deprecated-verbose")); -@@ -2619,12 +2619,31 @@ public final class CraftServer implements Server { +@@ -2636,12 +2636,31 @@ public final class CraftServer implements Server { private final org.bukkit.Server.Spigot spigot = new org.bukkit.Server.Spigot() { @@ -1804,10 +1796,10 @@ index b0ffa23faf62629043dfd613315eaf9c5fcc2cfe..00000000000000000000000000000000 - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 69b8d0f73ced69cd88029a5d7e11aca40d70f9d1..e4ea877228102ccf93fe8c92b0cec8ebd89771a0 100644 +index c02ab554fe6e1b7eb01bbd1824a86ff4de1db2f0..dafd4105f4ad4729c7637a7b0e5606ff0ec326d1 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2782,6 +2782,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2795,6 +2795,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { CraftPlayer.this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundSystemChatPacket(components, position == net.md_5.bungee.api.ChatMessageType.ACTION_BAR)); } @@ -1823,7 +1815,7 @@ index 69b8d0f73ced69cd88029a5d7e11aca40d70f9d1..e4ea877228102ccf93fe8c92b0cec8eb public Player.Spigot spigot() diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -index c017ce2ca1bc535795c958a2e509af2adf88efa9..6c0debe3f3b693ed90dd2a39f481cccd8e4f7634 100644 +index 6effe47b32a8551aa6f6b11bc0315714a119e199..4c376f67ae311b4fedea27b3475f9fb56054aec2 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java @@ -1,5 +1,6 @@ @@ -1869,7 +1861,7 @@ index c017ce2ca1bc535795c958a2e509af2adf88efa9..6c0debe3f3b693ed90dd2a39f481cccd this.pending.addAll(temp); temp.clear(); + MinecraftTimings.bukkitSchedulerFinishTimer.stopTiming(); // Paper - this.debugHead = this.debugHead.getNextHead(currentTick); + this.debugHead = this.debugHead.getNextHead(this.currentTick); } @@ -480,6 +481,7 @@ public class CraftScheduler implements BukkitScheduler { @@ -1985,7 +1977,7 @@ index f97eccb6a17c7876e1e002d798eb67bbe80571a0..76effc345d362047e64d064eb64a5222 + } // Paper } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 33d3085d0d44d748fcb1fc203dfd14c9e1b4aff0..f7b80cf8c89ae5eb9d8f0893e05ffc753fdace19 100644 +index a45c08c423248a60f9d5822046014427a6dadd12..1e8b13096b0ebed35290c9cbe6b8fb8f4b054b34 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -199,6 +199,12 @@ public final class CraftMagicNumbers implements UnsafeValues { @@ -2015,7 +2007,7 @@ index 33d3085d0d44d748fcb1fc203dfd14c9e1b4aff0..f7b80cf8c89ae5eb9d8f0893e05ffc75 @Override public String get(Class aClass, String s) { diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index ff422d4d4f2b764370f0ee2af13034853c1d3fe1..a5da6c1cae0afbde684be250e2fc3c0c32a1265b 100644 +index 3591b79481ac17bd02e59ac3c623d1c6991abd84..2122e044d99902d2aff86693aaa424a50b9f8a13 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -27,7 +27,7 @@ import net.minecraft.world.entity.projectile.ThrownTrident; diff --git a/patches/unapplied/0024-Further-improve-server-tick-loop.patch b/patches/server/0024-Further-improve-server-tick-loop.patch similarity index 94% rename from patches/unapplied/0024-Further-improve-server-tick-loop.patch rename to patches/server/0024-Further-improve-server-tick-loop.patch index 6cd0eb9aee1c..a5a6fbafa83c 100644 --- a/patches/unapplied/0024-Further-improve-server-tick-loop.patch +++ b/patches/server/0024-Further-improve-server-tick-loop.patch @@ -12,10 +12,10 @@ 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 49de4625c57689a3624ed421c0b03512507c97c3..46e03617bb32e4037d700c1b3698d397bd75de5c 100644 +index 4502e2cf565b7b0547a1963b1119d7810b7a0bcb..36a3fa8847afc0d0831054958886a04a1d847596 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -296,7 +296,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; public Commands vanillaCommandDispatcher; -@@ -305,7 +305,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop(Lists.transform(this.lore, CraftChatMessage::fromComponent)); } @@ -47,7 +47,7 @@ index 0c73854243f7fa21d1ffdb3b4c85ee0a69c9c5e4..f6ac13f91f08498a8adda7d34518a5cf @Override public void setLore(List lore) { if (lore == null || lore.isEmpty()) { -@@ -1170,6 +1190,21 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1306,6 +1326,21 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { } } @@ -69,7 +69,7 @@ index 0c73854243f7fa21d1ffdb3b4c85ee0a69c9c5e4..f6ac13f91f08498a8adda7d34518a5cf @Override public boolean hasCustomModelData() { return this.customModelData != null; -@@ -1882,6 +1917,11 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2188,6 +2223,11 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { } for (Object object : addFrom) { diff --git a/patches/unapplied/0027-Configurable-cactus-bamboo-and-reed-growth-height.patch b/patches/server/0027-Configurable-cactus-bamboo-and-reed-growth-height.patch similarity index 89% rename from patches/unapplied/0027-Configurable-cactus-bamboo-and-reed-growth-height.patch rename to patches/server/0027-Configurable-cactus-bamboo-and-reed-growth-height.patch index d25f48a93d78..e5e4b807eed1 100644 --- a/patches/unapplied/0027-Configurable-cactus-bamboo-and-reed-growth-height.patch +++ b/patches/server/0027-Configurable-cactus-bamboo-and-reed-growth-height.patch @@ -7,7 +7,7 @@ Bamboo - Both the minimum fully-grown height and the maximum are configurable - Machine_Maker diff --git a/src/main/java/net/minecraft/world/level/block/BambooStalkBlock.java b/src/main/java/net/minecraft/world/level/block/BambooStalkBlock.java -index eda75b316acd09120539c92ff8adb97d92e9523f..e2951dd077441fe9cda461a2d3ef0c0671308316 100644 +index 80bf98e7681cfde3a41ce5676425d5e96089500d..5e88bd02f5c53124f1aeec3eae727a1f83cc8238 100644 --- a/src/main/java/net/minecraft/world/level/block/BambooStalkBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BambooStalkBlock.java @@ -137,7 +137,7 @@ public class BambooStalkBlock extends Block implements BonemealableBlock { @@ -19,7 +19,7 @@ index eda75b316acd09120539c92ff8adb97d92e9523f..e2951dd077441fe9cda461a2d3ef0c06 this.growBamboo(state, world, pos, random, i); } } -@@ -168,7 +168,7 @@ public class BambooStalkBlock extends Block implements BonemealableBlock { +@@ -164,7 +164,7 @@ public class BambooStalkBlock extends Block implements BonemealableBlock { int i = this.getHeightAboveUpToMax(world, pos); int j = this.getHeightBelowUpToMax(world, pos); @@ -28,7 +28,7 @@ index eda75b316acd09120539c92ff8adb97d92e9523f..e2951dd077441fe9cda461a2d3ef0c06 } @Override -@@ -187,7 +187,7 @@ public class BambooStalkBlock extends Block implements BonemealableBlock { +@@ -183,7 +183,7 @@ public class BambooStalkBlock extends Block implements BonemealableBlock { BlockPos blockposition1 = pos.above(i); BlockState iblockdata1 = world.getBlockState(blockposition1); @@ -37,7 +37,7 @@ index eda75b316acd09120539c92ff8adb97d92e9523f..e2951dd077441fe9cda461a2d3ef0c06 return; } -@@ -228,7 +228,7 @@ public class BambooStalkBlock extends Block implements BonemealableBlock { +@@ -224,7 +224,7 @@ public class BambooStalkBlock extends Block implements BonemealableBlock { } int j = (Integer) state.getValue(BambooStalkBlock.AGE) != 1 && !iblockdata2.is(Blocks.BAMBOO) ? 0 : 1; @@ -46,7 +46,7 @@ index eda75b316acd09120539c92ff8adb97d92e9523f..e2951dd077441fe9cda461a2d3ef0c06 // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, pos, pos.above(), (BlockState) ((BlockState) ((BlockState) this.defaultBlockState().setValue(BambooStalkBlock.AGE, j)).setValue(BambooStalkBlock.LEAVES, blockpropertybamboosize)).setValue(BambooStalkBlock.STAGE, k), 3)) { -@@ -243,7 +243,7 @@ public class BambooStalkBlock extends Block implements BonemealableBlock { +@@ -239,7 +239,7 @@ public class BambooStalkBlock extends Block implements BonemealableBlock { protected int getHeightAboveUpToMax(BlockGetter world, BlockPos pos) { int i; @@ -55,7 +55,7 @@ index eda75b316acd09120539c92ff8adb97d92e9523f..e2951dd077441fe9cda461a2d3ef0c06 ; } -@@ -253,7 +253,7 @@ public class BambooStalkBlock extends Block implements BonemealableBlock { +@@ -249,7 +249,7 @@ public class BambooStalkBlock extends Block implements BonemealableBlock { protected int getHeightBelowUpToMax(BlockGetter world, BlockPos pos) { int i; @@ -65,10 +65,10 @@ index eda75b316acd09120539c92ff8adb97d92e9523f..e2951dd077441fe9cda461a2d3ef0c06 } diff --git a/src/main/java/net/minecraft/world/level/block/CactusBlock.java b/src/main/java/net/minecraft/world/level/block/CactusBlock.java -index c7e462a187196da906aec3b528f7945afec9f6b0..fd344c5cf0d6d523abe34d5e3f8d939106942cbb 100644 +index de3df6606979171fd39fa6c5207fd9b0b668ba4e..de1b64e0cbe7f2de63f04262428c9e6ec340916e 100644 --- a/src/main/java/net/minecraft/world/level/block/CactusBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CactusBlock.java -@@ -61,7 +61,7 @@ public class CactusBlock extends Block { +@@ -62,7 +62,7 @@ public class CactusBlock extends Block { ; } @@ -78,7 +78,7 @@ index c7e462a187196da906aec3b528f7945afec9f6b0..fd344c5cf0d6d523abe34d5e3f8d9391 int modifier = world.spigotConfig.cactusModifier; // Spigot - SPIGOT-7159: Better modifier resolution diff --git a/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java b/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java -index f034a7dbc0124353f8cb9b2c841226e73d83423a..c48c622e92cedeaa46b929c7adfedec98dd5a3fb 100644 +index 161f70de43105c0b49b6c4d0a371dc6036c6813c..547ea09ed84595286c97c128b3b96f6d387ae25f 100644 --- a/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java @@ -59,7 +59,7 @@ public class SugarCaneBlock extends Block { diff --git a/patches/unapplied/0028-Configurable-baby-zombie-movement-speed.patch b/patches/server/0028-Configurable-baby-zombie-movement-speed.patch similarity index 91% rename from patches/unapplied/0028-Configurable-baby-zombie-movement-speed.patch rename to patches/server/0028-Configurable-baby-zombie-movement-speed.patch index a55a0a394400..a7c6ba5835a4 100644 --- a/patches/unapplied/0028-Configurable-baby-zombie-movement-speed.patch +++ b/patches/server/0028-Configurable-baby-zombie-movement-speed.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Configurable baby zombie movement speed diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index 60a9db4131bcf69a33003b83db6117c9a7a83276..393a9c704f4637a0e8031328d2a0facef4723dd8 100644 +index 6845a8e13cdc9dd03015ac53b2a62dd706def5cd..3836d9255ac326a7220e1decd2e9d98be7884c17 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -@@ -75,7 +75,7 @@ import org.bukkit.event.entity.EntityTransformEvent; +@@ -77,7 +77,7 @@ import org.bukkit.event.entity.EntityTransformEvent; public class Zombie extends Monster { private static final ResourceLocation SPEED_MODIFIER_BABY_ID = ResourceLocation.withDefaultNamespace("baby"); @@ -17,7 +17,7 @@ index 60a9db4131bcf69a33003b83db6117c9a7a83276..393a9c704f4637a0e8031328d2a0face private static final ResourceLocation REINFORCEMENT_CALLER_CHARGE_ID = ResourceLocation.withDefaultNamespace("reinforcement_caller_charge"); private static final AttributeModifier ZOMBIE_REINFORCEMENT_CALLEE_CHARGE = new AttributeModifier(ResourceLocation.withDefaultNamespace("reinforcement_callee_charge"), -0.05000000074505806D, AttributeModifier.Operation.ADD_VALUE); private static final ResourceLocation LEADER_ZOMBIE_BONUS_ID = ResourceLocation.withDefaultNamespace("leader_zombie_bonus"); -@@ -188,9 +188,9 @@ public class Zombie extends Monster { +@@ -186,9 +186,9 @@ public class Zombie extends Monster { if (this.level() != null && !this.level().isClientSide) { AttributeInstance attributemodifiable = this.getAttribute(Attributes.MOVEMENT_SPEED); diff --git a/patches/unapplied/0029-Configurable-fishing-time-ranges.patch b/patches/server/0029-Configurable-fishing-time-ranges.patch similarity index 83% rename from patches/unapplied/0029-Configurable-fishing-time-ranges.patch rename to patches/server/0029-Configurable-fishing-time-ranges.patch index 90d886761f89..4599ac587dab 100644 --- a/patches/unapplied/0029-Configurable-fishing-time-ranges.patch +++ b/patches/server/0029-Configurable-fishing-time-ranges.patch @@ -5,11 +5,11 @@ Subject: [PATCH] Configurable fishing time ranges diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -index 0acb45014039d4392988c7d853595f96e856af4a..ed43ad94ca007a54e3c32d5e17c141048eeb5835 100644 +index 0f3e3f1b918ed2971440b7414ae62ee018a85b3e..ed378bc8135c329cb7423da06eb26fff69ee4954 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java +++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -@@ -94,6 +94,10 @@ public class FishingHook extends Projectile { - this.noCulling = true; +@@ -93,6 +93,10 @@ public class FishingHook extends Projectile { + this.currentState = FishingHook.FishHookState.FLYING; this.luck = Math.max(0, luckBonus); this.lureSpeed = Math.max(0, waitTimeReductionTicks); + // Paper start - Configurable fishing time ranges @@ -19,7 +19,7 @@ index 0acb45014039d4392988c7d853595f96e856af4a..ed43ad94ca007a54e3c32d5e17c14104 } public FishingHook(EntityType type, Level world) { -@@ -411,7 +415,7 @@ public class FishingHook extends Projectile { +@@ -416,7 +420,7 @@ public class FishingHook extends Projectile { } else { // CraftBukkit start - logic to modify fishing wait time this.timeUntilLured = Mth.nextInt(this.random, this.minWaitTime, this.maxWaitTime); diff --git a/patches/unapplied/0030-Allow-nerfed-mobs-to-jump.patch b/patches/server/0030-Allow-nerfed-mobs-to-jump.patch similarity index 87% rename from patches/unapplied/0030-Allow-nerfed-mobs-to-jump.patch rename to patches/server/0030-Allow-nerfed-mobs-to-jump.patch index a43842f5bcb1..9aa6c3381e44 100644 --- a/patches/unapplied/0030-Allow-nerfed-mobs-to-jump.patch +++ b/patches/server/0030-Allow-nerfed-mobs-to-jump.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Allow nerfed mobs to jump diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 930b5002aa6eaa1137314f7b38fad99778b6edaa..0593d828c911c94c9833bf12b9c294e5dac1f4e8 100644 +index 02a2fdf2a4bdfb390d23bf45211b71798de422fa..9b26f6a7526f875535738b1f22d9aa458845eb8e 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -124,6 +124,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -127,6 +127,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab private final BodyRotationControl bodyRotationControl; protected PathNavigation navigation; public GoalSelector goalSelector; @@ -16,7 +16,7 @@ index 930b5002aa6eaa1137314f7b38fad99778b6edaa..0593d828c911c94c9833bf12b9c294e5 public GoalSelector targetSelector; @Nullable private LivingEntity target; -@@ -888,7 +889,15 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -886,7 +887,15 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab @Override protected final void serverAiStep() { ++this.noActionTime; @@ -30,7 +30,7 @@ index 930b5002aa6eaa1137314f7b38fad99778b6edaa..0593d828c911c94c9833bf12b9c294e5 + return; + } + // Paper end - Allow nerfed mobs to jump and float - ProfilerFiller gameprofilerfiller = this.level().getProfiler(); + ProfilerFiller gameprofilerfiller = Profiler.get(); gameprofilerfiller.push("sensing"); diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/FloatGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/FloatGoal.java diff --git a/patches/unapplied/0031-Add-configurable-entity-despawn-distances.patch b/patches/unapplied/server/0031-Add-configurable-entity-despawn-distances.patch similarity index 100% rename from patches/unapplied/0031-Add-configurable-entity-despawn-distances.patch rename to patches/unapplied/server/0031-Add-configurable-entity-despawn-distances.patch diff --git a/patches/unapplied/0032-Drop-falling-block-and-tnt-entities-at-the-specified.patch b/patches/unapplied/server/0032-Drop-falling-block-and-tnt-entities-at-the-specified.patch similarity index 100% rename from patches/unapplied/0032-Drop-falling-block-and-tnt-entities-at-the-specified.patch rename to patches/unapplied/server/0032-Drop-falling-block-and-tnt-entities-at-the-specified.patch diff --git a/patches/unapplied/0033-Expose-server-build-information.patch b/patches/unapplied/server/0033-Expose-server-build-information.patch similarity index 100% rename from patches/unapplied/0033-Expose-server-build-information.patch rename to patches/unapplied/server/0033-Expose-server-build-information.patch diff --git a/patches/unapplied/0034-Player-affects-spawning-API.patch b/patches/unapplied/server/0034-Player-affects-spawning-API.patch similarity index 100% rename from patches/unapplied/0034-Player-affects-spawning-API.patch rename to patches/unapplied/server/0034-Player-affects-spawning-API.patch diff --git a/patches/unapplied/0035-Only-refresh-abilities-if-needed.patch b/patches/unapplied/server/0035-Only-refresh-abilities-if-needed.patch similarity index 100% rename from patches/unapplied/0035-Only-refresh-abilities-if-needed.patch rename to patches/unapplied/server/0035-Only-refresh-abilities-if-needed.patch diff --git a/patches/unapplied/0036-Entity-Origin-API.patch b/patches/unapplied/server/0036-Entity-Origin-API.patch similarity index 100% rename from patches/unapplied/0036-Entity-Origin-API.patch rename to patches/unapplied/server/0036-Entity-Origin-API.patch diff --git a/patches/unapplied/0037-Prevent-block-entity-and-entity-crashes.patch b/patches/unapplied/server/0037-Prevent-block-entity-and-entity-crashes.patch similarity index 100% rename from patches/unapplied/0037-Prevent-block-entity-and-entity-crashes.patch rename to patches/unapplied/server/0037-Prevent-block-entity-and-entity-crashes.patch diff --git a/patches/unapplied/0038-Configurable-top-of-nether-void-damage.patch b/patches/unapplied/server/0038-Configurable-top-of-nether-void-damage.patch similarity index 100% rename from patches/unapplied/0038-Configurable-top-of-nether-void-damage.patch rename to patches/unapplied/server/0038-Configurable-top-of-nether-void-damage.patch diff --git a/patches/unapplied/0039-Check-online-mode-before-converting-and-renaming-pla.patch b/patches/unapplied/server/0039-Check-online-mode-before-converting-and-renaming-pla.patch similarity index 100% rename from patches/unapplied/0039-Check-online-mode-before-converting-and-renaming-pla.patch rename to patches/unapplied/server/0039-Check-online-mode-before-converting-and-renaming-pla.patch diff --git a/patches/unapplied/0040-Add-more-entities-to-activation-range-ignore-list.patch b/patches/unapplied/server/0040-Add-more-entities-to-activation-range-ignore-list.patch similarity index 100% rename from patches/unapplied/0040-Add-more-entities-to-activation-range-ignore-list.patch rename to patches/unapplied/server/0040-Add-more-entities-to-activation-range-ignore-list.patch diff --git a/patches/unapplied/0041-Configurable-end-credits.patch b/patches/unapplied/server/0041-Configurable-end-credits.patch similarity index 100% rename from patches/unapplied/0041-Configurable-end-credits.patch rename to patches/unapplied/server/0041-Configurable-end-credits.patch diff --git a/patches/unapplied/0042-Fix-lag-from-explosions-processing-dead-entities.patch b/patches/unapplied/server/0042-Fix-lag-from-explosions-processing-dead-entities.patch similarity index 100% rename from patches/unapplied/0042-Fix-lag-from-explosions-processing-dead-entities.patch rename to patches/unapplied/server/0042-Fix-lag-from-explosions-processing-dead-entities.patch diff --git a/patches/unapplied/0043-Optimize-explosions.patch b/patches/unapplied/server/0043-Optimize-explosions.patch similarity index 100% rename from patches/unapplied/0043-Optimize-explosions.patch rename to patches/unapplied/server/0043-Optimize-explosions.patch diff --git a/patches/unapplied/0044-Disable-explosion-knockback.patch b/patches/unapplied/server/0044-Disable-explosion-knockback.patch similarity index 100% rename from patches/unapplied/0044-Disable-explosion-knockback.patch rename to patches/unapplied/server/0044-Disable-explosion-knockback.patch diff --git a/patches/unapplied/0045-Disable-thunder.patch b/patches/unapplied/server/0045-Disable-thunder.patch similarity index 100% rename from patches/unapplied/0045-Disable-thunder.patch rename to patches/unapplied/server/0045-Disable-thunder.patch diff --git a/patches/unapplied/0046-Disable-ice-and-snow.patch b/patches/unapplied/server/0046-Disable-ice-and-snow.patch similarity index 100% rename from patches/unapplied/0046-Disable-ice-and-snow.patch rename to patches/unapplied/server/0046-Disable-ice-and-snow.patch diff --git a/patches/unapplied/0047-Configurable-mob-spawner-tick-rate.patch b/patches/unapplied/server/0047-Configurable-mob-spawner-tick-rate.patch similarity index 100% rename from patches/unapplied/0047-Configurable-mob-spawner-tick-rate.patch rename to patches/unapplied/server/0047-Configurable-mob-spawner-tick-rate.patch diff --git a/patches/unapplied/0048-Use-null-Locale-by-default.patch b/patches/unapplied/server/0048-Use-null-Locale-by-default.patch similarity index 100% rename from patches/unapplied/0048-Use-null-Locale-by-default.patch rename to patches/unapplied/server/0048-Use-null-Locale-by-default.patch diff --git a/patches/unapplied/0049-Add-BeaconEffectEvent.patch b/patches/unapplied/server/0049-Add-BeaconEffectEvent.patch similarity index 100% rename from patches/unapplied/0049-Add-BeaconEffectEvent.patch rename to patches/unapplied/server/0049-Add-BeaconEffectEvent.patch diff --git a/patches/unapplied/0050-Configurable-container-update-tick-rate.patch b/patches/unapplied/server/0050-Configurable-container-update-tick-rate.patch similarity index 100% rename from patches/unapplied/0050-Configurable-container-update-tick-rate.patch rename to patches/unapplied/server/0050-Configurable-container-update-tick-rate.patch diff --git a/patches/unapplied/0051-Use-UserCache-for-player-heads.patch b/patches/unapplied/server/0051-Use-UserCache-for-player-heads.patch similarity index 100% rename from patches/unapplied/0051-Use-UserCache-for-player-heads.patch rename to patches/unapplied/server/0051-Use-UserCache-for-player-heads.patch diff --git a/patches/unapplied/0052-Disable-spigot-tick-limiters.patch b/patches/unapplied/server/0052-Disable-spigot-tick-limiters.patch similarity index 100% rename from patches/unapplied/0052-Disable-spigot-tick-limiters.patch rename to patches/unapplied/server/0052-Disable-spigot-tick-limiters.patch diff --git a/patches/unapplied/0053-Fix-spawn-location-event-changing-location.patch b/patches/unapplied/server/0053-Fix-spawn-location-event-changing-location.patch similarity index 100% rename from patches/unapplied/0053-Fix-spawn-location-event-changing-location.patch rename to patches/unapplied/server/0053-Fix-spawn-location-event-changing-location.patch diff --git a/patches/unapplied/0054-Configurable-Disabling-Cat-Chest-Detection.patch b/patches/unapplied/server/0054-Configurable-Disabling-Cat-Chest-Detection.patch similarity index 100% rename from patches/unapplied/0054-Configurable-Disabling-Cat-Chest-Detection.patch rename to patches/unapplied/server/0054-Configurable-Disabling-Cat-Chest-Detection.patch diff --git a/patches/unapplied/0055-Improve-Player-chat-API-handling.patch b/patches/unapplied/server/0055-Improve-Player-chat-API-handling.patch similarity index 100% rename from patches/unapplied/0055-Improve-Player-chat-API-handling.patch rename to patches/unapplied/server/0055-Improve-Player-chat-API-handling.patch diff --git a/patches/unapplied/0056-All-chunks-are-slime-spawn-chunks-toggle.patch b/patches/unapplied/server/0056-All-chunks-are-slime-spawn-chunks-toggle.patch similarity index 100% rename from patches/unapplied/0056-All-chunks-are-slime-spawn-chunks-toggle.patch rename to patches/unapplied/server/0056-All-chunks-are-slime-spawn-chunks-toggle.patch diff --git a/patches/unapplied/0057-Expose-server-CommandMap.patch b/patches/unapplied/server/0057-Expose-server-CommandMap.patch similarity index 100% rename from patches/unapplied/0057-Expose-server-CommandMap.patch rename to patches/unapplied/server/0057-Expose-server-CommandMap.patch diff --git a/patches/unapplied/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch b/patches/unapplied/server/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch similarity index 100% rename from patches/unapplied/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch rename to patches/unapplied/server/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch diff --git a/patches/unapplied/0059-Player-Tab-List-and-Title-APIs.patch b/patches/unapplied/server/0059-Player-Tab-List-and-Title-APIs.patch similarity index 100% rename from patches/unapplied/0059-Player-Tab-List-and-Title-APIs.patch rename to patches/unapplied/server/0059-Player-Tab-List-and-Title-APIs.patch diff --git a/patches/unapplied/0060-Add-configurable-portal-search-radius.patch b/patches/unapplied/server/0060-Add-configurable-portal-search-radius.patch similarity index 100% rename from patches/unapplied/0060-Add-configurable-portal-search-radius.patch rename to patches/unapplied/server/0060-Add-configurable-portal-search-radius.patch diff --git a/patches/unapplied/0061-Add-velocity-warnings.patch b/patches/unapplied/server/0061-Add-velocity-warnings.patch similarity index 100% rename from patches/unapplied/0061-Add-velocity-warnings.patch rename to patches/unapplied/server/0061-Add-velocity-warnings.patch diff --git a/patches/unapplied/0062-Add-exception-reporting-event.patch b/patches/unapplied/server/0062-Add-exception-reporting-event.patch similarity index 100% rename from patches/unapplied/0062-Add-exception-reporting-event.patch rename to patches/unapplied/server/0062-Add-exception-reporting-event.patch diff --git a/patches/unapplied/0063-Disable-Scoreboards-for-non-players-by-default.patch b/patches/unapplied/server/0063-Disable-Scoreboards-for-non-players-by-default.patch similarity index 100% rename from patches/unapplied/0063-Disable-Scoreboards-for-non-players-by-default.patch rename to patches/unapplied/server/0063-Disable-Scoreboards-for-non-players-by-default.patch diff --git a/patches/unapplied/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch b/patches/unapplied/server/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch similarity index 100% rename from patches/unapplied/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch rename to patches/unapplied/server/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch diff --git a/patches/unapplied/0065-Chunk-Save-Reattempt.patch b/patches/unapplied/server/0065-Chunk-Save-Reattempt.patch similarity index 100% rename from patches/unapplied/0065-Chunk-Save-Reattempt.patch rename to patches/unapplied/server/0065-Chunk-Save-Reattempt.patch diff --git a/patches/unapplied/0066-Complete-resource-pack-API.patch b/patches/unapplied/server/0066-Complete-resource-pack-API.patch similarity index 100% rename from patches/unapplied/0066-Complete-resource-pack-API.patch rename to patches/unapplied/server/0066-Complete-resource-pack-API.patch diff --git a/patches/unapplied/0067-Default-loading-permissions.yml-before-plugins.patch b/patches/unapplied/server/0067-Default-loading-permissions.yml-before-plugins.patch similarity index 100% rename from patches/unapplied/0067-Default-loading-permissions.yml-before-plugins.patch rename to patches/unapplied/server/0067-Default-loading-permissions.yml-before-plugins.patch diff --git a/patches/unapplied/0068-Allow-Reloading-of-Custom-Permissions.patch b/patches/unapplied/server/0068-Allow-Reloading-of-Custom-Permissions.patch similarity index 100% rename from patches/unapplied/0068-Allow-Reloading-of-Custom-Permissions.patch rename to patches/unapplied/server/0068-Allow-Reloading-of-Custom-Permissions.patch diff --git a/patches/unapplied/0069-Remove-Metadata-on-reload.patch b/patches/unapplied/server/0069-Remove-Metadata-on-reload.patch similarity index 100% rename from patches/unapplied/0069-Remove-Metadata-on-reload.patch rename to patches/unapplied/server/0069-Remove-Metadata-on-reload.patch diff --git a/patches/unapplied/0070-Handle-Item-Meta-Inconsistencies.patch b/patches/unapplied/server/0070-Handle-Item-Meta-Inconsistencies.patch similarity index 100% rename from patches/unapplied/0070-Handle-Item-Meta-Inconsistencies.patch rename to patches/unapplied/server/0070-Handle-Item-Meta-Inconsistencies.patch diff --git a/patches/unapplied/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch b/patches/unapplied/server/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch similarity index 100% rename from patches/unapplied/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch rename to patches/unapplied/server/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch diff --git a/patches/unapplied/0072-Add-World-Util-Methods.patch b/patches/unapplied/server/0072-Add-World-Util-Methods.patch similarity index 100% rename from patches/unapplied/0072-Add-World-Util-Methods.patch rename to patches/unapplied/server/0072-Add-World-Util-Methods.patch diff --git a/patches/unapplied/0073-Custom-replacement-for-eaten-items.patch b/patches/unapplied/server/0073-Custom-replacement-for-eaten-items.patch similarity index 100% rename from patches/unapplied/0073-Custom-replacement-for-eaten-items.patch rename to patches/unapplied/server/0073-Custom-replacement-for-eaten-items.patch diff --git a/patches/unapplied/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch b/patches/unapplied/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch similarity index 100% rename from patches/unapplied/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch rename to patches/unapplied/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch diff --git a/patches/unapplied/0075-Use-a-Shared-Random-for-Entities.patch b/patches/unapplied/server/0075-Use-a-Shared-Random-for-Entities.patch similarity index 100% rename from patches/unapplied/0075-Use-a-Shared-Random-for-Entities.patch rename to patches/unapplied/server/0075-Use-a-Shared-Random-for-Entities.patch diff --git a/patches/unapplied/0076-Configurable-spawn-chances-for-skeleton-horses.patch b/patches/unapplied/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch similarity index 100% rename from patches/unapplied/0076-Configurable-spawn-chances-for-skeleton-horses.patch rename to patches/unapplied/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch diff --git a/patches/unapplied/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch b/patches/unapplied/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch similarity index 100% rename from patches/unapplied/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch rename to patches/unapplied/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch diff --git a/patches/unapplied/0078-Entity-AddTo-RemoveFrom-World-Events.patch b/patches/unapplied/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch similarity index 100% rename from patches/unapplied/0078-Entity-AddTo-RemoveFrom-World-Events.patch rename to patches/unapplied/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch diff --git a/patches/unapplied/0079-Configurable-Chunk-Inhabited-Time.patch b/patches/unapplied/server/0079-Configurable-Chunk-Inhabited-Time.patch similarity index 100% rename from patches/unapplied/0079-Configurable-Chunk-Inhabited-Time.patch rename to patches/unapplied/server/0079-Configurable-Chunk-Inhabited-Time.patch diff --git a/patches/unapplied/0080-EntityPathfindEvent.patch b/patches/unapplied/server/0080-EntityPathfindEvent.patch similarity index 100% rename from patches/unapplied/0080-EntityPathfindEvent.patch rename to patches/unapplied/server/0080-EntityPathfindEvent.patch diff --git a/patches/unapplied/0081-Sanitise-RegionFileCache-and-make-configurable.patch b/patches/unapplied/server/0081-Sanitise-RegionFileCache-and-make-configurable.patch similarity index 100% rename from patches/unapplied/0081-Sanitise-RegionFileCache-and-make-configurable.patch rename to patches/unapplied/server/0081-Sanitise-RegionFileCache-and-make-configurable.patch diff --git a/patches/unapplied/0082-Do-not-load-chunks-for-Pathfinding.patch b/patches/unapplied/server/0082-Do-not-load-chunks-for-Pathfinding.patch similarity index 100% rename from patches/unapplied/0082-Do-not-load-chunks-for-Pathfinding.patch rename to patches/unapplied/server/0082-Do-not-load-chunks-for-Pathfinding.patch diff --git a/patches/unapplied/0083-Add-PlayerUseUnknownEntityEvent.patch b/patches/unapplied/server/0083-Add-PlayerUseUnknownEntityEvent.patch similarity index 100% rename from patches/unapplied/0083-Add-PlayerUseUnknownEntityEvent.patch rename to patches/unapplied/server/0083-Add-PlayerUseUnknownEntityEvent.patch diff --git a/patches/unapplied/0084-Configurable-random-tick-rates-for-blocks.patch b/patches/unapplied/server/0084-Configurable-random-tick-rates-for-blocks.patch similarity index 100% rename from patches/unapplied/0084-Configurable-random-tick-rates-for-blocks.patch rename to patches/unapplied/server/0084-Configurable-random-tick-rates-for-blocks.patch diff --git a/patches/unapplied/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch b/patches/unapplied/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch similarity index 100% rename from patches/unapplied/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch rename to patches/unapplied/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch diff --git a/patches/unapplied/0086-Optimize-DataBits.patch b/patches/unapplied/server/0086-Optimize-DataBits.patch similarity index 100% rename from patches/unapplied/0086-Optimize-DataBits.patch rename to patches/unapplied/server/0086-Optimize-DataBits.patch diff --git a/patches/unapplied/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch b/patches/unapplied/server/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch similarity index 100% rename from patches/unapplied/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch rename to patches/unapplied/server/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch diff --git a/patches/unapplied/0088-Configurable-Player-Collision.patch b/patches/unapplied/server/0088-Configurable-Player-Collision.patch similarity index 100% rename from patches/unapplied/0088-Configurable-Player-Collision.patch rename to patches/unapplied/server/0088-Configurable-Player-Collision.patch diff --git a/patches/unapplied/0089-Add-handshake-event-to-allow-plugins-to-handle-clien.patch b/patches/unapplied/server/0089-Add-handshake-event-to-allow-plugins-to-handle-clien.patch similarity index 100% rename from patches/unapplied/0089-Add-handshake-event-to-allow-plugins-to-handle-clien.patch rename to patches/unapplied/server/0089-Add-handshake-event-to-allow-plugins-to-handle-clien.patch diff --git a/patches/unapplied/0090-Configurable-RCON-IP-address.patch b/patches/unapplied/server/0090-Configurable-RCON-IP-address.patch similarity index 100% rename from patches/unapplied/0090-Configurable-RCON-IP-address.patch rename to patches/unapplied/server/0090-Configurable-RCON-IP-address.patch diff --git a/patches/unapplied/0091-EntityRegainHealthEvent-isFastRegen-API.patch b/patches/unapplied/server/0091-EntityRegainHealthEvent-isFastRegen-API.patch similarity index 100% rename from patches/unapplied/0091-EntityRegainHealthEvent-isFastRegen-API.patch rename to patches/unapplied/server/0091-EntityRegainHealthEvent-isFastRegen-API.patch diff --git a/patches/unapplied/0092-Add-ability-to-configure-frosted_ice-properties.patch b/patches/unapplied/server/0092-Add-ability-to-configure-frosted_ice-properties.patch similarity index 100% rename from patches/unapplied/0092-Add-ability-to-configure-frosted_ice-properties.patch rename to patches/unapplied/server/0092-Add-ability-to-configure-frosted_ice-properties.patch diff --git a/patches/unapplied/0093-remove-null-possibility-for-getServer-singleton.patch b/patches/unapplied/server/0093-remove-null-possibility-for-getServer-singleton.patch similarity index 100% rename from patches/unapplied/0093-remove-null-possibility-for-getServer-singleton.patch rename to patches/unapplied/server/0093-remove-null-possibility-for-getServer-singleton.patch diff --git a/patches/unapplied/0094-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch b/patches/unapplied/server/0094-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch similarity index 100% rename from patches/unapplied/0094-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch rename to patches/unapplied/server/0094-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch diff --git a/patches/unapplied/0095-LootTable-API-and-replenishable-lootables.patch b/patches/unapplied/server/0095-LootTable-API-and-replenishable-lootables.patch similarity index 100% rename from patches/unapplied/0095-LootTable-API-and-replenishable-lootables.patch rename to patches/unapplied/server/0095-LootTable-API-and-replenishable-lootables.patch diff --git a/patches/unapplied/0096-System-property-for-disabling-watchdoge.patch b/patches/unapplied/server/0096-System-property-for-disabling-watchdoge.patch similarity index 100% rename from patches/unapplied/0096-System-property-for-disabling-watchdoge.patch rename to patches/unapplied/server/0096-System-property-for-disabling-watchdoge.patch diff --git a/patches/unapplied/0097-Async-GameProfileCache-saving.patch b/patches/unapplied/server/0097-Async-GameProfileCache-saving.patch similarity index 100% rename from patches/unapplied/0097-Async-GameProfileCache-saving.patch rename to patches/unapplied/server/0097-Async-GameProfileCache-saving.patch diff --git a/patches/unapplied/0098-Optional-TNT-doesn-t-move-in-water.patch b/patches/unapplied/server/0098-Optional-TNT-doesn-t-move-in-water.patch similarity index 100% rename from patches/unapplied/0098-Optional-TNT-doesn-t-move-in-water.patch rename to patches/unapplied/server/0098-Optional-TNT-doesn-t-move-in-water.patch diff --git a/patches/unapplied/0099-Faster-redstone-torch-rapid-clock-removal.patch b/patches/unapplied/server/0099-Faster-redstone-torch-rapid-clock-removal.patch similarity index 100% rename from patches/unapplied/0099-Faster-redstone-torch-rapid-clock-removal.patch rename to patches/unapplied/server/0099-Faster-redstone-torch-rapid-clock-removal.patch diff --git a/patches/unapplied/0100-Add-server-name-parameter.patch b/patches/unapplied/server/0100-Add-server-name-parameter.patch similarity index 100% rename from patches/unapplied/0100-Add-server-name-parameter.patch rename to patches/unapplied/server/0100-Add-server-name-parameter.patch diff --git a/patches/unapplied/0101-Fix-global-sound-handling.patch b/patches/unapplied/server/0101-Fix-global-sound-handling.patch similarity index 100% rename from patches/unapplied/0101-Fix-global-sound-handling.patch rename to patches/unapplied/server/0101-Fix-global-sound-handling.patch diff --git a/patches/unapplied/0102-Avoid-blocking-on-Network-Manager-creation.patch b/patches/unapplied/server/0102-Avoid-blocking-on-Network-Manager-creation.patch similarity index 100% rename from patches/unapplied/0102-Avoid-blocking-on-Network-Manager-creation.patch rename to patches/unapplied/server/0102-Avoid-blocking-on-Network-Manager-creation.patch diff --git a/patches/unapplied/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch b/patches/unapplied/server/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch similarity index 100% rename from patches/unapplied/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch rename to patches/unapplied/server/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch diff --git a/patches/unapplied/0104-Add-setting-for-proxy-online-mode-status.patch b/patches/unapplied/server/0104-Add-setting-for-proxy-online-mode-status.patch similarity index 100% rename from patches/unapplied/0104-Add-setting-for-proxy-online-mode-status.patch rename to patches/unapplied/server/0104-Add-setting-for-proxy-online-mode-status.patch diff --git a/patches/unapplied/0105-Optimise-BlockState-s-hashCode-equals.patch b/patches/unapplied/server/0105-Optimise-BlockState-s-hashCode-equals.patch similarity index 100% rename from patches/unapplied/0105-Optimise-BlockState-s-hashCode-equals.patch rename to patches/unapplied/server/0105-Optimise-BlockState-s-hashCode-equals.patch diff --git a/patches/unapplied/0106-Configurable-packet-in-spam-threshold.patch b/patches/unapplied/server/0106-Configurable-packet-in-spam-threshold.patch similarity index 100% rename from patches/unapplied/0106-Configurable-packet-in-spam-threshold.patch rename to patches/unapplied/server/0106-Configurable-packet-in-spam-threshold.patch diff --git a/patches/unapplied/0107-Configurable-flying-kick-messages.patch b/patches/unapplied/server/0107-Configurable-flying-kick-messages.patch similarity index 100% rename from patches/unapplied/0107-Configurable-flying-kick-messages.patch rename to patches/unapplied/server/0107-Configurable-flying-kick-messages.patch diff --git a/patches/unapplied/0108-Add-EntityZapEvent.patch b/patches/unapplied/server/0108-Add-EntityZapEvent.patch similarity index 100% rename from patches/unapplied/0108-Add-EntityZapEvent.patch rename to patches/unapplied/server/0108-Add-EntityZapEvent.patch diff --git a/patches/unapplied/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch b/patches/unapplied/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch similarity index 100% rename from patches/unapplied/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch rename to patches/unapplied/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch diff --git a/patches/unapplied/0110-Cache-user-authenticator-threads.patch b/patches/unapplied/server/0110-Cache-user-authenticator-threads.patch similarity index 100% rename from patches/unapplied/0110-Cache-user-authenticator-threads.patch rename to patches/unapplied/server/0110-Cache-user-authenticator-threads.patch diff --git a/patches/unapplied/0111-Allow-Reloading-of-Command-Aliases.patch b/patches/unapplied/server/0111-Allow-Reloading-of-Command-Aliases.patch similarity index 100% rename from patches/unapplied/0111-Allow-Reloading-of-Command-Aliases.patch rename to patches/unapplied/server/0111-Allow-Reloading-of-Command-Aliases.patch diff --git a/patches/unapplied/0112-Add-source-to-PlayerExpChangeEvent.patch b/patches/unapplied/server/0112-Add-source-to-PlayerExpChangeEvent.patch similarity index 100% rename from patches/unapplied/0112-Add-source-to-PlayerExpChangeEvent.patch rename to patches/unapplied/server/0112-Add-source-to-PlayerExpChangeEvent.patch diff --git a/patches/unapplied/0113-Add-ProjectileCollideEvent.patch b/patches/unapplied/server/0113-Add-ProjectileCollideEvent.patch similarity index 100% rename from patches/unapplied/0113-Add-ProjectileCollideEvent.patch rename to patches/unapplied/server/0113-Add-ProjectileCollideEvent.patch diff --git a/patches/unapplied/0114-Prevent-Pathfinding-out-of-World-Border.patch b/patches/unapplied/server/0114-Prevent-Pathfinding-out-of-World-Border.patch similarity index 100% rename from patches/unapplied/0114-Prevent-Pathfinding-out-of-World-Border.patch rename to patches/unapplied/server/0114-Prevent-Pathfinding-out-of-World-Border.patch diff --git a/patches/unapplied/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch b/patches/unapplied/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch similarity index 100% rename from patches/unapplied/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch rename to patches/unapplied/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch diff --git a/patches/unapplied/0116-Bound-Treasure-Maps-to-World-Border.patch b/patches/unapplied/server/0116-Bound-Treasure-Maps-to-World-Border.patch similarity index 100% rename from patches/unapplied/0116-Bound-Treasure-Maps-to-World-Border.patch rename to patches/unapplied/server/0116-Bound-Treasure-Maps-to-World-Border.patch diff --git a/patches/unapplied/0117-Configurable-Cartographer-Treasure-Maps.patch b/patches/unapplied/server/0117-Configurable-Cartographer-Treasure-Maps.patch similarity index 100% rename from patches/unapplied/0117-Configurable-Cartographer-Treasure-Maps.patch rename to patches/unapplied/server/0117-Configurable-Cartographer-Treasure-Maps.patch diff --git a/patches/unapplied/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch b/patches/unapplied/server/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch similarity index 100% rename from patches/unapplied/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch rename to patches/unapplied/server/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch diff --git a/patches/unapplied/0119-String-based-Action-Bar-API.patch b/patches/unapplied/server/0119-String-based-Action-Bar-API.patch similarity index 100% rename from patches/unapplied/0119-String-based-Action-Bar-API.patch rename to patches/unapplied/server/0119-String-based-Action-Bar-API.patch diff --git a/patches/unapplied/0120-Properly-fix-item-duplication-bug.patch b/patches/unapplied/server/0120-Properly-fix-item-duplication-bug.patch similarity index 100% rename from patches/unapplied/0120-Properly-fix-item-duplication-bug.patch rename to patches/unapplied/server/0120-Properly-fix-item-duplication-bug.patch diff --git a/patches/unapplied/0121-Firework-API-s.patch b/patches/unapplied/server/0121-Firework-API-s.patch similarity index 100% rename from patches/unapplied/0121-Firework-API-s.patch rename to patches/unapplied/server/0121-Firework-API-s.patch diff --git a/patches/unapplied/0122-PlayerTeleportEndGatewayEvent.patch b/patches/unapplied/server/0122-PlayerTeleportEndGatewayEvent.patch similarity index 100% rename from patches/unapplied/0122-PlayerTeleportEndGatewayEvent.patch rename to patches/unapplied/server/0122-PlayerTeleportEndGatewayEvent.patch diff --git a/patches/unapplied/0123-Provide-E-TE-Chunk-count-stat-methods.patch b/patches/unapplied/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch similarity index 100% rename from patches/unapplied/0123-Provide-E-TE-Chunk-count-stat-methods.patch rename to patches/unapplied/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch diff --git a/patches/unapplied/0124-Enforce-Sync-Player-Saves.patch b/patches/unapplied/server/0124-Enforce-Sync-Player-Saves.patch similarity index 100% rename from patches/unapplied/0124-Enforce-Sync-Player-Saves.patch rename to patches/unapplied/server/0124-Enforce-Sync-Player-Saves.patch diff --git a/patches/unapplied/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch b/patches/unapplied/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch similarity index 100% rename from patches/unapplied/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch rename to patches/unapplied/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch diff --git a/patches/unapplied/0126-Cap-Entity-Collisions.patch b/patches/unapplied/server/0126-Cap-Entity-Collisions.patch similarity index 100% rename from patches/unapplied/0126-Cap-Entity-Collisions.patch rename to patches/unapplied/server/0126-Cap-Entity-Collisions.patch diff --git a/patches/unapplied/0127-Remove-CraftScheduler-Async-Task-Debugger.patch b/patches/unapplied/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch similarity index 100% rename from patches/unapplied/0127-Remove-CraftScheduler-Async-Task-Debugger.patch rename to patches/unapplied/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch diff --git a/patches/unapplied/0128-Properly-handle-async-calls-to-restart-the-server.patch b/patches/unapplied/server/0128-Properly-handle-async-calls-to-restart-the-server.patch similarity index 100% rename from patches/unapplied/0128-Properly-handle-async-calls-to-restart-the-server.patch rename to patches/unapplied/server/0128-Properly-handle-async-calls-to-restart-the-server.patch diff --git a/patches/unapplied/0129-Add-option-to-make-parrots-stay-on-shoulders-despite.patch b/patches/unapplied/server/0129-Add-option-to-make-parrots-stay-on-shoulders-despite.patch similarity index 100% rename from patches/unapplied/0129-Add-option-to-make-parrots-stay-on-shoulders-despite.patch rename to patches/unapplied/server/0129-Add-option-to-make-parrots-stay-on-shoulders-despite.patch diff --git a/patches/unapplied/0130-Add-configuration-option-to-prevent-player-names-fro.patch b/patches/unapplied/server/0130-Add-configuration-option-to-prevent-player-names-fro.patch similarity index 100% rename from patches/unapplied/0130-Add-configuration-option-to-prevent-player-names-fro.patch rename to patches/unapplied/server/0130-Add-configuration-option-to-prevent-player-names-fro.patch diff --git a/patches/unapplied/0131-provide-a-configurable-option-to-disable-creeper-lin.patch b/patches/unapplied/server/0131-provide-a-configurable-option-to-disable-creeper-lin.patch similarity index 100% rename from patches/unapplied/0131-provide-a-configurable-option-to-disable-creeper-lin.patch rename to patches/unapplied/server/0131-provide-a-configurable-option-to-disable-creeper-lin.patch diff --git a/patches/unapplied/0132-Item-canEntityPickup.patch b/patches/unapplied/server/0132-Item-canEntityPickup.patch similarity index 100% rename from patches/unapplied/0132-Item-canEntityPickup.patch rename to patches/unapplied/server/0132-Item-canEntityPickup.patch diff --git a/patches/unapplied/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch b/patches/unapplied/server/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch similarity index 100% rename from patches/unapplied/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch rename to patches/unapplied/server/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch diff --git a/patches/unapplied/0134-PlayerAttemptPickupItemEvent.patch b/patches/unapplied/server/0134-PlayerAttemptPickupItemEvent.patch similarity index 100% rename from patches/unapplied/0134-PlayerAttemptPickupItemEvent.patch rename to patches/unapplied/server/0134-PlayerAttemptPickupItemEvent.patch diff --git a/patches/unapplied/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch b/patches/unapplied/server/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch similarity index 100% rename from patches/unapplied/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch rename to patches/unapplied/server/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch diff --git a/patches/unapplied/0136-Basic-PlayerProfile-API.patch b/patches/unapplied/server/0136-Basic-PlayerProfile-API.patch similarity index 100% rename from patches/unapplied/0136-Basic-PlayerProfile-API.patch rename to patches/unapplied/server/0136-Basic-PlayerProfile-API.patch diff --git a/patches/unapplied/0137-Add-UnknownCommandEvent.patch b/patches/unapplied/server/0137-Add-UnknownCommandEvent.patch similarity index 100% rename from patches/unapplied/0137-Add-UnknownCommandEvent.patch rename to patches/unapplied/server/0137-Add-UnknownCommandEvent.patch diff --git a/patches/unapplied/0138-Shoulder-Entities-Release-API.patch b/patches/unapplied/server/0138-Shoulder-Entities-Release-API.patch similarity index 100% rename from patches/unapplied/0138-Shoulder-Entities-Release-API.patch rename to patches/unapplied/server/0138-Shoulder-Entities-Release-API.patch diff --git a/patches/unapplied/0139-Profile-Lookup-Events.patch b/patches/unapplied/server/0139-Profile-Lookup-Events.patch similarity index 100% rename from patches/unapplied/0139-Profile-Lookup-Events.patch rename to patches/unapplied/server/0139-Profile-Lookup-Events.patch diff --git a/patches/unapplied/0140-Block-player-logins-during-server-shutdown.patch b/patches/unapplied/server/0140-Block-player-logins-during-server-shutdown.patch similarity index 100% rename from patches/unapplied/0140-Block-player-logins-during-server-shutdown.patch rename to patches/unapplied/server/0140-Block-player-logins-during-server-shutdown.patch diff --git a/patches/unapplied/0141-Entity-fromMobSpawner.patch b/patches/unapplied/server/0141-Entity-fromMobSpawner.patch similarity index 100% rename from patches/unapplied/0141-Entity-fromMobSpawner.patch rename to patches/unapplied/server/0141-Entity-fromMobSpawner.patch diff --git a/patches/unapplied/0142-Improve-the-Saddle-API-for-Horses.patch b/patches/unapplied/server/0142-Improve-the-Saddle-API-for-Horses.patch similarity index 100% rename from patches/unapplied/0142-Improve-the-Saddle-API-for-Horses.patch rename to patches/unapplied/server/0142-Improve-the-Saddle-API-for-Horses.patch diff --git a/patches/unapplied/0143-ensureServerConversions-API.patch b/patches/unapplied/server/0143-ensureServerConversions-API.patch similarity index 100% rename from patches/unapplied/0143-ensureServerConversions-API.patch rename to patches/unapplied/server/0143-ensureServerConversions-API.patch diff --git a/patches/unapplied/0144-Implement-getI18NDisplayName.patch b/patches/unapplied/server/0144-Implement-getI18NDisplayName.patch similarity index 100% rename from patches/unapplied/0144-Implement-getI18NDisplayName.patch rename to patches/unapplied/server/0144-Implement-getI18NDisplayName.patch diff --git a/patches/unapplied/0145-ProfileWhitelistVerifyEvent.patch b/patches/unapplied/server/0145-ProfileWhitelistVerifyEvent.patch similarity index 100% rename from patches/unapplied/0145-ProfileWhitelistVerifyEvent.patch rename to patches/unapplied/server/0145-ProfileWhitelistVerifyEvent.patch diff --git a/patches/unapplied/0146-Fix-this-stupid-bullshit.patch b/patches/unapplied/server/0146-Fix-this-stupid-bullshit.patch similarity index 100% rename from patches/unapplied/0146-Fix-this-stupid-bullshit.patch rename to patches/unapplied/server/0146-Fix-this-stupid-bullshit.patch diff --git a/patches/unapplied/0147-LivingEntity-setKiller.patch b/patches/unapplied/server/0147-LivingEntity-setKiller.patch similarity index 100% rename from patches/unapplied/0147-LivingEntity-setKiller.patch rename to patches/unapplied/server/0147-LivingEntity-setKiller.patch diff --git a/patches/unapplied/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch b/patches/unapplied/server/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch similarity index 100% rename from patches/unapplied/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch rename to patches/unapplied/server/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch diff --git a/patches/unapplied/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch b/patches/unapplied/server/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch similarity index 100% rename from patches/unapplied/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch rename to patches/unapplied/server/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch diff --git a/patches/unapplied/0150-Allow-specifying-a-custom-authentication-servers-dow.patch b/patches/unapplied/server/0150-Allow-specifying-a-custom-authentication-servers-dow.patch similarity index 100% rename from patches/unapplied/0150-Allow-specifying-a-custom-authentication-servers-dow.patch rename to patches/unapplied/server/0150-Allow-specifying-a-custom-authentication-servers-dow.patch diff --git a/patches/unapplied/0151-Add-PlayerJumpEvent.patch b/patches/unapplied/server/0151-Add-PlayerJumpEvent.patch similarity index 100% rename from patches/unapplied/0151-Add-PlayerJumpEvent.patch rename to patches/unapplied/server/0151-Add-PlayerJumpEvent.patch diff --git a/patches/unapplied/0152-handle-ServerboundKeepAlivePacket-async.patch b/patches/unapplied/server/0152-handle-ServerboundKeepAlivePacket-async.patch similarity index 100% rename from patches/unapplied/0152-handle-ServerboundKeepAlivePacket-async.patch rename to patches/unapplied/server/0152-handle-ServerboundKeepAlivePacket-async.patch diff --git a/patches/unapplied/0153-Expose-client-protocol-version-and-virtual-host.patch b/patches/unapplied/server/0153-Expose-client-protocol-version-and-virtual-host.patch similarity index 100% rename from patches/unapplied/0153-Expose-client-protocol-version-and-virtual-host.patch rename to patches/unapplied/server/0153-Expose-client-protocol-version-and-virtual-host.patch diff --git a/patches/unapplied/0154-revert-serverside-behavior-of-keepalives.patch b/patches/unapplied/server/0154-revert-serverside-behavior-of-keepalives.patch similarity index 100% rename from patches/unapplied/0154-revert-serverside-behavior-of-keepalives.patch rename to patches/unapplied/server/0154-revert-serverside-behavior-of-keepalives.patch diff --git a/patches/unapplied/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch b/patches/unapplied/server/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch similarity index 100% rename from patches/unapplied/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch rename to patches/unapplied/server/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch diff --git a/patches/unapplied/0156-Add-PlayerArmorChangeEvent.patch b/patches/unapplied/server/0156-Add-PlayerArmorChangeEvent.patch similarity index 100% rename from patches/unapplied/0156-Add-PlayerArmorChangeEvent.patch rename to patches/unapplied/server/0156-Add-PlayerArmorChangeEvent.patch diff --git a/patches/unapplied/0157-Prevent-logins-from-being-processed-when-the-player-.patch b/patches/unapplied/server/0157-Prevent-logins-from-being-processed-when-the-player-.patch similarity index 100% rename from patches/unapplied/0157-Prevent-logins-from-being-processed-when-the-player-.patch rename to patches/unapplied/server/0157-Prevent-logins-from-being-processed-when-the-player-.patch diff --git a/patches/unapplied/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch b/patches/unapplied/server/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch similarity index 100% rename from patches/unapplied/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch rename to patches/unapplied/server/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch diff --git a/patches/unapplied/0159-use-CB-BlockState-implementations-for-captured-block.patch b/patches/unapplied/server/0159-use-CB-BlockState-implementations-for-captured-block.patch similarity index 100% rename from patches/unapplied/0159-use-CB-BlockState-implementations-for-captured-block.patch rename to patches/unapplied/server/0159-use-CB-BlockState-implementations-for-captured-block.patch diff --git a/patches/unapplied/0160-API-to-get-a-BlockState-without-a-snapshot.patch b/patches/unapplied/server/0160-API-to-get-a-BlockState-without-a-snapshot.patch similarity index 100% rename from patches/unapplied/0160-API-to-get-a-BlockState-without-a-snapshot.patch rename to patches/unapplied/server/0160-API-to-get-a-BlockState-without-a-snapshot.patch diff --git a/patches/unapplied/0161-AsyncTabCompleteEvent.patch b/patches/unapplied/server/0161-AsyncTabCompleteEvent.patch similarity index 100% rename from patches/unapplied/0161-AsyncTabCompleteEvent.patch rename to patches/unapplied/server/0161-AsyncTabCompleteEvent.patch diff --git a/patches/unapplied/0162-PlayerPickupExperienceEvent.patch b/patches/unapplied/server/0162-PlayerPickupExperienceEvent.patch similarity index 100% rename from patches/unapplied/0162-PlayerPickupExperienceEvent.patch rename to patches/unapplied/server/0162-PlayerPickupExperienceEvent.patch diff --git a/patches/unapplied/0163-Ability-to-apply-mending-to-XP-API.patch b/patches/unapplied/server/0163-Ability-to-apply-mending-to-XP-API.patch similarity index 100% rename from patches/unapplied/0163-Ability-to-apply-mending-to-XP-API.patch rename to patches/unapplied/server/0163-Ability-to-apply-mending-to-XP-API.patch diff --git a/patches/unapplied/0164-PlayerNaturallySpawnCreaturesEvent.patch b/patches/unapplied/server/0164-PlayerNaturallySpawnCreaturesEvent.patch similarity index 100% rename from patches/unapplied/0164-PlayerNaturallySpawnCreaturesEvent.patch rename to patches/unapplied/server/0164-PlayerNaturallySpawnCreaturesEvent.patch diff --git a/patches/unapplied/0165-Add-setPlayerProfile-API-for-Skulls.patch b/patches/unapplied/server/0165-Add-setPlayerProfile-API-for-Skulls.patch similarity index 100% rename from patches/unapplied/0165-Add-setPlayerProfile-API-for-Skulls.patch rename to patches/unapplied/server/0165-Add-setPlayerProfile-API-for-Skulls.patch diff --git a/patches/unapplied/0166-PreCreatureSpawnEvent.patch b/patches/unapplied/server/0166-PreCreatureSpawnEvent.patch similarity index 100% rename from patches/unapplied/0166-PreCreatureSpawnEvent.patch rename to patches/unapplied/server/0166-PreCreatureSpawnEvent.patch diff --git a/patches/unapplied/0167-Fill-Profile-Property-Events.patch b/patches/unapplied/server/0167-Fill-Profile-Property-Events.patch similarity index 100% rename from patches/unapplied/0167-Fill-Profile-Property-Events.patch rename to patches/unapplied/server/0167-Fill-Profile-Property-Events.patch diff --git a/patches/unapplied/0168-Add-PlayerAdvancementCriterionGrantEvent.patch b/patches/unapplied/server/0168-Add-PlayerAdvancementCriterionGrantEvent.patch similarity index 100% rename from patches/unapplied/0168-Add-PlayerAdvancementCriterionGrantEvent.patch rename to patches/unapplied/server/0168-Add-PlayerAdvancementCriterionGrantEvent.patch diff --git a/patches/unapplied/0169-Add-ArmorStand-Item-Meta.patch b/patches/unapplied/server/0169-Add-ArmorStand-Item-Meta.patch similarity index 100% rename from patches/unapplied/0169-Add-ArmorStand-Item-Meta.patch rename to patches/unapplied/server/0169-Add-ArmorStand-Item-Meta.patch diff --git a/patches/unapplied/0170-Extend-Player-Interact-cancellation.patch b/patches/unapplied/server/0170-Extend-Player-Interact-cancellation.patch similarity index 100% rename from patches/unapplied/0170-Extend-Player-Interact-cancellation.patch rename to patches/unapplied/server/0170-Extend-Player-Interact-cancellation.patch diff --git a/patches/unapplied/0171-Tameable-getOwnerUniqueId-API.patch b/patches/unapplied/server/0171-Tameable-getOwnerUniqueId-API.patch similarity index 100% rename from patches/unapplied/0171-Tameable-getOwnerUniqueId-API.patch rename to patches/unapplied/server/0171-Tameable-getOwnerUniqueId-API.patch diff --git a/patches/unapplied/0172-Toggleable-player-crits.patch b/patches/unapplied/server/0172-Toggleable-player-crits.patch similarity index 100% rename from patches/unapplied/0172-Toggleable-player-crits.patch rename to patches/unapplied/server/0172-Toggleable-player-crits.patch diff --git a/patches/unapplied/0173-Disable-Explicit-Network-Manager-Flushing.patch b/patches/unapplied/server/0173-Disable-Explicit-Network-Manager-Flushing.patch similarity index 100% rename from patches/unapplied/0173-Disable-Explicit-Network-Manager-Flushing.patch rename to patches/unapplied/server/0173-Disable-Explicit-Network-Manager-Flushing.patch diff --git a/patches/unapplied/0174-Implement-extended-PaperServerListPingEvent.patch b/patches/unapplied/server/0174-Implement-extended-PaperServerListPingEvent.patch similarity index 100% rename from patches/unapplied/0174-Implement-extended-PaperServerListPingEvent.patch rename to patches/unapplied/server/0174-Implement-extended-PaperServerListPingEvent.patch diff --git a/patches/unapplied/0175-Add-more-fields-to-AsyncPreLoginEvent.patch b/patches/unapplied/server/0175-Add-more-fields-to-AsyncPreLoginEvent.patch similarity index 100% rename from patches/unapplied/0175-Add-more-fields-to-AsyncPreLoginEvent.patch rename to patches/unapplied/server/0175-Add-more-fields-to-AsyncPreLoginEvent.patch diff --git a/patches/unapplied/0176-Player.setPlayerProfile-API.patch b/patches/unapplied/server/0176-Player.setPlayerProfile-API.patch similarity index 100% rename from patches/unapplied/0176-Player.setPlayerProfile-API.patch rename to patches/unapplied/server/0176-Player.setPlayerProfile-API.patch diff --git a/patches/unapplied/0177-getPlayerUniqueId-API.patch b/patches/unapplied/server/0177-getPlayerUniqueId-API.patch similarity index 100% rename from patches/unapplied/0177-getPlayerUniqueId-API.patch rename to patches/unapplied/server/0177-getPlayerUniqueId-API.patch diff --git a/patches/unapplied/0178-Improved-Async-Task-Scheduler.patch b/patches/unapplied/server/0178-Improved-Async-Task-Scheduler.patch similarity index 100% rename from patches/unapplied/0178-Improved-Async-Task-Scheduler.patch rename to patches/unapplied/server/0178-Improved-Async-Task-Scheduler.patch diff --git a/patches/unapplied/0179-Make-legacy-ping-handler-more-reliable.patch b/patches/unapplied/server/0179-Make-legacy-ping-handler-more-reliable.patch similarity index 100% rename from patches/unapplied/0179-Make-legacy-ping-handler-more-reliable.patch rename to patches/unapplied/server/0179-Make-legacy-ping-handler-more-reliable.patch diff --git a/patches/unapplied/0180-Call-PaperServerListPingEvent-for-legacy-pings.patch b/patches/unapplied/server/0180-Call-PaperServerListPingEvent-for-legacy-pings.patch similarity index 100% rename from patches/unapplied/0180-Call-PaperServerListPingEvent-for-legacy-pings.patch rename to patches/unapplied/server/0180-Call-PaperServerListPingEvent-for-legacy-pings.patch diff --git a/patches/unapplied/0181-Flag-to-disable-the-channel-limit.patch b/patches/unapplied/server/0181-Flag-to-disable-the-channel-limit.patch similarity index 100% rename from patches/unapplied/0181-Flag-to-disable-the-channel-limit.patch rename to patches/unapplied/server/0181-Flag-to-disable-the-channel-limit.patch diff --git a/patches/unapplied/0182-Add-openSign-method-to-HumanEntity.patch b/patches/unapplied/server/0182-Add-openSign-method-to-HumanEntity.patch similarity index 100% rename from patches/unapplied/0182-Add-openSign-method-to-HumanEntity.patch rename to patches/unapplied/server/0182-Add-openSign-method-to-HumanEntity.patch diff --git a/patches/unapplied/0183-Configurable-sprint-interruption-on-attack.patch b/patches/unapplied/server/0183-Configurable-sprint-interruption-on-attack.patch similarity index 100% rename from patches/unapplied/0183-Configurable-sprint-interruption-on-attack.patch rename to patches/unapplied/server/0183-Configurable-sprint-interruption-on-attack.patch diff --git a/patches/unapplied/0184-EndermanEscapeEvent.patch b/patches/unapplied/server/0184-EndermanEscapeEvent.patch similarity index 100% rename from patches/unapplied/0184-EndermanEscapeEvent.patch rename to patches/unapplied/server/0184-EndermanEscapeEvent.patch diff --git a/patches/unapplied/0185-Enderman.teleportRandomly.patch b/patches/unapplied/server/0185-Enderman.teleportRandomly.patch similarity index 100% rename from patches/unapplied/0185-Enderman.teleportRandomly.patch rename to patches/unapplied/server/0185-Enderman.teleportRandomly.patch diff --git a/patches/unapplied/0186-Block-Enderpearl-Travel-Exploit.patch b/patches/unapplied/server/0186-Block-Enderpearl-Travel-Exploit.patch similarity index 100% rename from patches/unapplied/0186-Block-Enderpearl-Travel-Exploit.patch rename to patches/unapplied/server/0186-Block-Enderpearl-Travel-Exploit.patch diff --git a/patches/unapplied/0187-Expand-World.spawnParticle-API-and-add-Builder.patch b/patches/unapplied/server/0187-Expand-World.spawnParticle-API-and-add-Builder.patch similarity index 100% rename from patches/unapplied/0187-Expand-World.spawnParticle-API-and-add-Builder.patch rename to patches/unapplied/server/0187-Expand-World.spawnParticle-API-and-add-Builder.patch diff --git a/patches/unapplied/0188-Fix-exploit-that-allowed-colored-signs-to-be-created.patch b/patches/unapplied/server/0188-Fix-exploit-that-allowed-colored-signs-to-be-created.patch similarity index 100% rename from patches/unapplied/0188-Fix-exploit-that-allowed-colored-signs-to-be-created.patch rename to patches/unapplied/server/0188-Fix-exploit-that-allowed-colored-signs-to-be-created.patch diff --git a/patches/unapplied/0189-EndermanAttackPlayerEvent.patch b/patches/unapplied/server/0189-EndermanAttackPlayerEvent.patch similarity index 100% rename from patches/unapplied/0189-EndermanAttackPlayerEvent.patch rename to patches/unapplied/server/0189-EndermanAttackPlayerEvent.patch diff --git a/patches/unapplied/0190-WitchConsumePotionEvent.patch b/patches/unapplied/server/0190-WitchConsumePotionEvent.patch similarity index 100% rename from patches/unapplied/0190-WitchConsumePotionEvent.patch rename to patches/unapplied/server/0190-WitchConsumePotionEvent.patch diff --git a/patches/unapplied/0191-WitchThrowPotionEvent.patch b/patches/unapplied/server/0191-WitchThrowPotionEvent.patch similarity index 100% rename from patches/unapplied/0191-WitchThrowPotionEvent.patch rename to patches/unapplied/server/0191-WitchThrowPotionEvent.patch diff --git a/patches/unapplied/0192-WitchReadyPotionEvent.patch b/patches/unapplied/server/0192-WitchReadyPotionEvent.patch similarity index 100% rename from patches/unapplied/0192-WitchReadyPotionEvent.patch rename to patches/unapplied/server/0192-WitchReadyPotionEvent.patch diff --git a/patches/unapplied/0193-ItemStack-getMaxItemUseDuration.patch b/patches/unapplied/server/0193-ItemStack-getMaxItemUseDuration.patch similarity index 100% rename from patches/unapplied/0193-ItemStack-getMaxItemUseDuration.patch rename to patches/unapplied/server/0193-ItemStack-getMaxItemUseDuration.patch diff --git a/patches/unapplied/0194-Add-EntityTeleportEndGatewayEvent.patch b/patches/unapplied/server/0194-Add-EntityTeleportEndGatewayEvent.patch similarity index 100% rename from patches/unapplied/0194-Add-EntityTeleportEndGatewayEvent.patch rename to patches/unapplied/server/0194-Add-EntityTeleportEndGatewayEvent.patch diff --git a/patches/unapplied/0195-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch b/patches/unapplied/server/0195-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch similarity index 100% rename from patches/unapplied/0195-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch rename to patches/unapplied/server/0195-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch diff --git a/patches/unapplied/0196-Fix-CraftEntity-hashCode.patch b/patches/unapplied/server/0196-Fix-CraftEntity-hashCode.patch similarity index 100% rename from patches/unapplied/0196-Fix-CraftEntity-hashCode.patch rename to patches/unapplied/server/0196-Fix-CraftEntity-hashCode.patch diff --git a/patches/unapplied/0197-Configurable-LootPool-luck-formula.patch b/patches/unapplied/server/0197-Configurable-LootPool-luck-formula.patch similarity index 100% rename from patches/unapplied/0197-Configurable-LootPool-luck-formula.patch rename to patches/unapplied/server/0197-Configurable-LootPool-luck-formula.patch diff --git a/patches/unapplied/0198-Print-Error-details-when-failing-to-save-player-data.patch b/patches/unapplied/server/0198-Print-Error-details-when-failing-to-save-player-data.patch similarity index 100% rename from patches/unapplied/0198-Print-Error-details-when-failing-to-save-player-data.patch rename to patches/unapplied/server/0198-Print-Error-details-when-failing-to-save-player-data.patch diff --git a/patches/unapplied/0199-Make-shield-blocking-delay-configurable.patch b/patches/unapplied/server/0199-Make-shield-blocking-delay-configurable.patch similarity index 100% rename from patches/unapplied/0199-Make-shield-blocking-delay-configurable.patch rename to patches/unapplied/server/0199-Make-shield-blocking-delay-configurable.patch diff --git a/patches/unapplied/0200-Improve-EntityShootBowEvent.patch b/patches/unapplied/server/0200-Improve-EntityShootBowEvent.patch similarity index 100% rename from patches/unapplied/0200-Improve-EntityShootBowEvent.patch rename to patches/unapplied/server/0200-Improve-EntityShootBowEvent.patch diff --git a/patches/unapplied/0201-PlayerReadyArrowEvent.patch b/patches/unapplied/server/0201-PlayerReadyArrowEvent.patch similarity index 100% rename from patches/unapplied/0201-PlayerReadyArrowEvent.patch rename to patches/unapplied/server/0201-PlayerReadyArrowEvent.patch diff --git a/patches/unapplied/0202-Add-entity-knockback-events.patch b/patches/unapplied/server/0202-Add-entity-knockback-events.patch similarity index 100% rename from patches/unapplied/0202-Add-entity-knockback-events.patch rename to patches/unapplied/server/0202-Add-entity-knockback-events.patch diff --git a/patches/unapplied/0203-Expand-Explosions-API.patch b/patches/unapplied/server/0203-Expand-Explosions-API.patch similarity index 100% rename from patches/unapplied/0203-Expand-Explosions-API.patch rename to patches/unapplied/server/0203-Expand-Explosions-API.patch diff --git a/patches/unapplied/0204-LivingEntity-Active-Item-API.patch b/patches/unapplied/server/0204-LivingEntity-Active-Item-API.patch similarity index 100% rename from patches/unapplied/0204-LivingEntity-Active-Item-API.patch rename to patches/unapplied/server/0204-LivingEntity-Active-Item-API.patch diff --git a/patches/unapplied/0205-RangedEntity-API.patch b/patches/unapplied/server/0205-RangedEntity-API.patch similarity index 100% rename from patches/unapplied/0205-RangedEntity-API.patch rename to patches/unapplied/server/0205-RangedEntity-API.patch diff --git a/patches/unapplied/0206-Add-config-to-disable-ender-dragon-legacy-check.patch b/patches/unapplied/server/0206-Add-config-to-disable-ender-dragon-legacy-check.patch similarity index 100% rename from patches/unapplied/0206-Add-config-to-disable-ender-dragon-legacy-check.patch rename to patches/unapplied/server/0206-Add-config-to-disable-ender-dragon-legacy-check.patch diff --git a/patches/unapplied/0207-Implement-World.getEntity-UUID-API.patch b/patches/unapplied/server/0207-Implement-World.getEntity-UUID-API.patch similarity index 100% rename from patches/unapplied/0207-Implement-World.getEntity-UUID-API.patch rename to patches/unapplied/server/0207-Implement-World.getEntity-UUID-API.patch diff --git a/patches/unapplied/0208-InventoryCloseEvent-Reason-API.patch b/patches/unapplied/server/0208-InventoryCloseEvent-Reason-API.patch similarity index 100% rename from patches/unapplied/0208-InventoryCloseEvent-Reason-API.patch rename to patches/unapplied/server/0208-InventoryCloseEvent-Reason-API.patch diff --git a/patches/unapplied/0209-Vex-get-setSummoner-API.patch b/patches/unapplied/server/0209-Vex-get-setSummoner-API.patch similarity index 100% rename from patches/unapplied/0209-Vex-get-setSummoner-API.patch rename to patches/unapplied/server/0209-Vex-get-setSummoner-API.patch diff --git a/patches/unapplied/0210-add-more-information-to-Entity.toString.patch b/patches/unapplied/server/0210-add-more-information-to-Entity.toString.patch similarity index 100% rename from patches/unapplied/0210-add-more-information-to-Entity.toString.patch rename to patches/unapplied/server/0210-add-more-information-to-Entity.toString.patch diff --git a/patches/unapplied/0211-EnderDragon-Events.patch b/patches/unapplied/server/0211-EnderDragon-Events.patch similarity index 100% rename from patches/unapplied/0211-EnderDragon-Events.patch rename to patches/unapplied/server/0211-EnderDragon-Events.patch diff --git a/patches/unapplied/0212-PlayerElytraBoostEvent.patch b/patches/unapplied/server/0212-PlayerElytraBoostEvent.patch similarity index 100% rename from patches/unapplied/0212-PlayerElytraBoostEvent.patch rename to patches/unapplied/server/0212-PlayerElytraBoostEvent.patch diff --git a/patches/unapplied/0213-PlayerLaunchProjectileEvent.patch b/patches/unapplied/server/0213-PlayerLaunchProjectileEvent.patch similarity index 100% rename from patches/unapplied/0213-PlayerLaunchProjectileEvent.patch rename to patches/unapplied/server/0213-PlayerLaunchProjectileEvent.patch diff --git a/patches/unapplied/0214-Improve-BlockPosition-inlining.patch b/patches/unapplied/server/0214-Improve-BlockPosition-inlining.patch similarity index 100% rename from patches/unapplied/0214-Improve-BlockPosition-inlining.patch rename to patches/unapplied/server/0214-Improve-BlockPosition-inlining.patch diff --git a/patches/unapplied/0215-Option-to-prevent-armor-stands-from-doing-entity-loo.patch b/patches/unapplied/server/0215-Option-to-prevent-armor-stands-from-doing-entity-loo.patch similarity index 100% rename from patches/unapplied/0215-Option-to-prevent-armor-stands-from-doing-entity-loo.patch rename to patches/unapplied/server/0215-Option-to-prevent-armor-stands-from-doing-entity-loo.patch diff --git a/patches/unapplied/0216-Vanished-players-don-t-have-rights.patch b/patches/unapplied/server/0216-Vanished-players-don-t-have-rights.patch similarity index 100% rename from patches/unapplied/0216-Vanished-players-don-t-have-rights.patch rename to patches/unapplied/server/0216-Vanished-players-don-t-have-rights.patch diff --git a/patches/unapplied/0217-Allow-disabling-armor-stand-ticking.patch b/patches/unapplied/server/0217-Allow-disabling-armor-stand-ticking.patch similarity index 100% rename from patches/unapplied/0217-Allow-disabling-armor-stand-ticking.patch rename to patches/unapplied/server/0217-Allow-disabling-armor-stand-ticking.patch diff --git a/patches/unapplied/0218-SkeletonHorse-Additions.patch b/patches/unapplied/server/0218-SkeletonHorse-Additions.patch similarity index 100% rename from patches/unapplied/0218-SkeletonHorse-Additions.patch rename to patches/unapplied/server/0218-SkeletonHorse-Additions.patch diff --git a/patches/unapplied/0219-Expand-ArmorStand-API.patch b/patches/unapplied/server/0219-Expand-ArmorStand-API.patch similarity index 100% rename from patches/unapplied/0219-Expand-ArmorStand-API.patch rename to patches/unapplied/server/0219-Expand-ArmorStand-API.patch diff --git a/patches/unapplied/0220-AnvilDamageEvent.patch b/patches/unapplied/server/0220-AnvilDamageEvent.patch similarity index 100% rename from patches/unapplied/0220-AnvilDamageEvent.patch rename to patches/unapplied/server/0220-AnvilDamageEvent.patch diff --git a/patches/unapplied/0221-Add-TNTPrimeEvent.patch b/patches/unapplied/server/0221-Add-TNTPrimeEvent.patch similarity index 100% rename from patches/unapplied/0221-Add-TNTPrimeEvent.patch rename to patches/unapplied/server/0221-Add-TNTPrimeEvent.patch diff --git a/patches/unapplied/0222-Break-up-and-make-tab-spam-limits-configurable.patch b/patches/unapplied/server/0222-Break-up-and-make-tab-spam-limits-configurable.patch similarity index 100% rename from patches/unapplied/0222-Break-up-and-make-tab-spam-limits-configurable.patch rename to patches/unapplied/server/0222-Break-up-and-make-tab-spam-limits-configurable.patch diff --git a/patches/unapplied/0223-Fix-NBT-type-issues.patch b/patches/unapplied/server/0223-Fix-NBT-type-issues.patch similarity index 100% rename from patches/unapplied/0223-Fix-NBT-type-issues.patch rename to patches/unapplied/server/0223-Fix-NBT-type-issues.patch diff --git a/patches/unapplied/0224-Remove-unnecessary-itemmeta-handling.patch b/patches/unapplied/server/0224-Remove-unnecessary-itemmeta-handling.patch similarity index 100% rename from patches/unapplied/0224-Remove-unnecessary-itemmeta-handling.patch rename to patches/unapplied/server/0224-Remove-unnecessary-itemmeta-handling.patch diff --git a/patches/unapplied/0225-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch b/patches/unapplied/server/0225-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch similarity index 100% rename from patches/unapplied/0225-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch rename to patches/unapplied/server/0225-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch diff --git a/patches/unapplied/0226-Add-Early-Warning-Feature-to-WatchDog.patch b/patches/unapplied/server/0226-Add-Early-Warning-Feature-to-WatchDog.patch similarity index 100% rename from patches/unapplied/0226-Add-Early-Warning-Feature-to-WatchDog.patch rename to patches/unapplied/server/0226-Add-Early-Warning-Feature-to-WatchDog.patch diff --git a/patches/unapplied/0227-Use-ConcurrentHashMap-in-JsonList.patch b/patches/unapplied/server/0227-Use-ConcurrentHashMap-in-JsonList.patch similarity index 100% rename from patches/unapplied/0227-Use-ConcurrentHashMap-in-JsonList.patch rename to patches/unapplied/server/0227-Use-ConcurrentHashMap-in-JsonList.patch diff --git a/patches/unapplied/0228-Use-a-Queue-for-Queueing-Commands.patch b/patches/unapplied/server/0228-Use-a-Queue-for-Queueing-Commands.patch similarity index 100% rename from patches/unapplied/0228-Use-a-Queue-for-Queueing-Commands.patch rename to patches/unapplied/server/0228-Use-a-Queue-for-Queueing-Commands.patch diff --git a/patches/unapplied/0229-Ability-to-get-block-entities-from-a-chunk-without-s.patch b/patches/unapplied/server/0229-Ability-to-get-block-entities-from-a-chunk-without-s.patch similarity index 100% rename from patches/unapplied/0229-Ability-to-get-block-entities-from-a-chunk-without-s.patch rename to patches/unapplied/server/0229-Ability-to-get-block-entities-from-a-chunk-without-s.patch diff --git a/patches/unapplied/0230-Optimize-BlockPosition-helper-methods.patch b/patches/unapplied/server/0230-Optimize-BlockPosition-helper-methods.patch similarity index 100% rename from patches/unapplied/0230-Optimize-BlockPosition-helper-methods.patch rename to patches/unapplied/server/0230-Optimize-BlockPosition-helper-methods.patch diff --git a/patches/unapplied/0231-Restore-vanilla-default-mob-spawn-range-and-water-an.patch b/patches/unapplied/server/0231-Restore-vanilla-default-mob-spawn-range-and-water-an.patch similarity index 100% rename from patches/unapplied/0231-Restore-vanilla-default-mob-spawn-range-and-water-an.patch rename to patches/unapplied/server/0231-Restore-vanilla-default-mob-spawn-range-and-water-an.patch diff --git a/patches/unapplied/0232-Slime-Pathfinder-Events.patch b/patches/unapplied/server/0232-Slime-Pathfinder-Events.patch similarity index 100% rename from patches/unapplied/0232-Slime-Pathfinder-Events.patch rename to patches/unapplied/server/0232-Slime-Pathfinder-Events.patch diff --git a/patches/unapplied/0233-Configurable-speed-for-water-flowing-over-lava.patch b/patches/unapplied/server/0233-Configurable-speed-for-water-flowing-over-lava.patch similarity index 100% rename from patches/unapplied/0233-Configurable-speed-for-water-flowing-over-lava.patch rename to patches/unapplied/server/0233-Configurable-speed-for-water-flowing-over-lava.patch diff --git a/patches/unapplied/0234-Optimize-CraftBlockData-Creation.patch b/patches/unapplied/server/0234-Optimize-CraftBlockData-Creation.patch similarity index 100% rename from patches/unapplied/0234-Optimize-CraftBlockData-Creation.patch rename to patches/unapplied/server/0234-Optimize-CraftBlockData-Creation.patch diff --git a/patches/unapplied/0235-Optimize-MappedRegistry.patch b/patches/unapplied/server/0235-Optimize-MappedRegistry.patch similarity index 100% rename from patches/unapplied/0235-Optimize-MappedRegistry.patch rename to patches/unapplied/server/0235-Optimize-MappedRegistry.patch diff --git a/patches/unapplied/0236-Add-PhantomPreSpawnEvent.patch b/patches/unapplied/server/0236-Add-PhantomPreSpawnEvent.patch similarity index 100% rename from patches/unapplied/0236-Add-PhantomPreSpawnEvent.patch rename to patches/unapplied/server/0236-Add-PhantomPreSpawnEvent.patch diff --git a/patches/unapplied/0237-Add-More-Creeper-API.patch b/patches/unapplied/server/0237-Add-More-Creeper-API.patch similarity index 100% rename from patches/unapplied/0237-Add-More-Creeper-API.patch rename to patches/unapplied/server/0237-Add-More-Creeper-API.patch diff --git a/patches/unapplied/0238-Inventory-removeItemAnySlot.patch b/patches/unapplied/server/0238-Inventory-removeItemAnySlot.patch similarity index 100% rename from patches/unapplied/0238-Inventory-removeItemAnySlot.patch rename to patches/unapplied/server/0238-Inventory-removeItemAnySlot.patch diff --git a/patches/unapplied/0239-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch b/patches/unapplied/server/0239-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch similarity index 100% rename from patches/unapplied/0239-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch rename to patches/unapplied/server/0239-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch diff --git a/patches/unapplied/0240-Add-ray-tracing-methods-to-LivingEntity.patch b/patches/unapplied/server/0240-Add-ray-tracing-methods-to-LivingEntity.patch similarity index 100% rename from patches/unapplied/0240-Add-ray-tracing-methods-to-LivingEntity.patch rename to patches/unapplied/server/0240-Add-ray-tracing-methods-to-LivingEntity.patch diff --git a/patches/unapplied/0241-Expose-attack-cooldown-methods-for-Player.patch b/patches/unapplied/server/0241-Expose-attack-cooldown-methods-for-Player.patch similarity index 100% rename from patches/unapplied/0241-Expose-attack-cooldown-methods-for-Player.patch rename to patches/unapplied/server/0241-Expose-attack-cooldown-methods-for-Player.patch diff --git a/patches/unapplied/0242-Improve-death-events.patch b/patches/unapplied/server/0242-Improve-death-events.patch similarity index 100% rename from patches/unapplied/0242-Improve-death-events.patch rename to patches/unapplied/server/0242-Improve-death-events.patch diff --git a/patches/unapplied/0243-Allow-chests-to-be-placed-with-NBT-data.patch b/patches/unapplied/server/0243-Allow-chests-to-be-placed-with-NBT-data.patch similarity index 100% rename from patches/unapplied/0243-Allow-chests-to-be-placed-with-NBT-data.patch rename to patches/unapplied/server/0243-Allow-chests-to-be-placed-with-NBT-data.patch diff --git a/patches/unapplied/0244-Mob-Pathfinding-API.patch b/patches/unapplied/server/0244-Mob-Pathfinding-API.patch similarity index 100% rename from patches/unapplied/0244-Mob-Pathfinding-API.patch rename to patches/unapplied/server/0244-Mob-Pathfinding-API.patch diff --git a/patches/unapplied/0245-Prevent-various-interactions-from-causing-chunk-load.patch b/patches/unapplied/server/0245-Prevent-various-interactions-from-causing-chunk-load.patch similarity index 100% rename from patches/unapplied/0245-Prevent-various-interactions-from-causing-chunk-load.patch rename to patches/unapplied/server/0245-Prevent-various-interactions-from-causing-chunk-load.patch diff --git a/patches/unapplied/0246-Prevent-mob-spawning-from-loading-generating-chunks.patch b/patches/unapplied/server/0246-Prevent-mob-spawning-from-loading-generating-chunks.patch similarity index 100% rename from patches/unapplied/0246-Prevent-mob-spawning-from-loading-generating-chunks.patch rename to patches/unapplied/server/0246-Prevent-mob-spawning-from-loading-generating-chunks.patch diff --git a/patches/unapplied/0247-Implement-furnace-cook-speed-multiplier-API.patch b/patches/unapplied/server/0247-Implement-furnace-cook-speed-multiplier-API.patch similarity index 100% rename from patches/unapplied/0247-Implement-furnace-cook-speed-multiplier-API.patch rename to patches/unapplied/server/0247-Implement-furnace-cook-speed-multiplier-API.patch diff --git a/patches/unapplied/0248-Honor-EntityAgeable.ageLock.patch b/patches/unapplied/server/0248-Honor-EntityAgeable.ageLock.patch similarity index 100% rename from patches/unapplied/0248-Honor-EntityAgeable.ageLock.patch rename to patches/unapplied/server/0248-Honor-EntityAgeable.ageLock.patch diff --git a/patches/unapplied/0249-Configurable-connection-throttle-kick-message.patch b/patches/unapplied/server/0249-Configurable-connection-throttle-kick-message.patch similarity index 100% rename from patches/unapplied/0249-Configurable-connection-throttle-kick-message.patch rename to patches/unapplied/server/0249-Configurable-connection-throttle-kick-message.patch diff --git a/patches/unapplied/0250-Prevent-chunk-loading-from-Fluid-Flowing.patch b/patches/unapplied/server/0250-Prevent-chunk-loading-from-Fluid-Flowing.patch similarity index 100% rename from patches/unapplied/0250-Prevent-chunk-loading-from-Fluid-Flowing.patch rename to patches/unapplied/server/0250-Prevent-chunk-loading-from-Fluid-Flowing.patch diff --git a/patches/unapplied/0251-PreSpawnerSpawnEvent.patch b/patches/unapplied/server/0251-PreSpawnerSpawnEvent.patch similarity index 100% rename from patches/unapplied/0251-PreSpawnerSpawnEvent.patch rename to patches/unapplied/server/0251-PreSpawnerSpawnEvent.patch diff --git a/patches/unapplied/0252-Add-LivingEntity-getTargetEntity.patch b/patches/unapplied/server/0252-Add-LivingEntity-getTargetEntity.patch similarity index 100% rename from patches/unapplied/0252-Add-LivingEntity-getTargetEntity.patch rename to patches/unapplied/server/0252-Add-LivingEntity-getTargetEntity.patch diff --git a/patches/unapplied/0253-Add-sun-related-API.patch b/patches/unapplied/server/0253-Add-sun-related-API.patch similarity index 100% rename from patches/unapplied/0253-Add-sun-related-API.patch rename to patches/unapplied/server/0253-Add-sun-related-API.patch diff --git a/patches/unapplied/0254-Turtle-API.patch b/patches/unapplied/server/0254-Turtle-API.patch similarity index 100% rename from patches/unapplied/0254-Turtle-API.patch rename to patches/unapplied/server/0254-Turtle-API.patch diff --git a/patches/unapplied/0255-Call-player-spectator-target-events-and-improve-impl.patch b/patches/unapplied/server/0255-Call-player-spectator-target-events-and-improve-impl.patch similarity index 100% rename from patches/unapplied/0255-Call-player-spectator-target-events-and-improve-impl.patch rename to patches/unapplied/server/0255-Call-player-spectator-target-events-and-improve-impl.patch diff --git a/patches/unapplied/0256-Add-more-Witch-API.patch b/patches/unapplied/server/0256-Add-more-Witch-API.patch similarity index 100% rename from patches/unapplied/0256-Add-more-Witch-API.patch rename to patches/unapplied/server/0256-Add-more-Witch-API.patch diff --git a/patches/unapplied/0257-Check-Drowned-for-Villager-Aggression-Config.patch b/patches/unapplied/server/0257-Check-Drowned-for-Villager-Aggression-Config.patch similarity index 100% rename from patches/unapplied/0257-Check-Drowned-for-Villager-Aggression-Config.patch rename to patches/unapplied/server/0257-Check-Drowned-for-Villager-Aggression-Config.patch diff --git a/patches/unapplied/0258-Add-option-to-prevent-players-from-moving-into-unloa.patch b/patches/unapplied/server/0258-Add-option-to-prevent-players-from-moving-into-unloa.patch similarity index 100% rename from patches/unapplied/0258-Add-option-to-prevent-players-from-moving-into-unloa.patch rename to patches/unapplied/server/0258-Add-option-to-prevent-players-from-moving-into-unloa.patch diff --git a/patches/unapplied/0259-Reset-players-airTicks-on-respawn.patch b/patches/unapplied/server/0259-Reset-players-airTicks-on-respawn.patch similarity index 100% rename from patches/unapplied/0259-Reset-players-airTicks-on-respawn.patch rename to patches/unapplied/server/0259-Reset-players-airTicks-on-respawn.patch diff --git a/patches/unapplied/0260-Don-t-sleep-after-profile-lookups-if-not-needed.patch b/patches/unapplied/server/0260-Don-t-sleep-after-profile-lookups-if-not-needed.patch similarity index 100% rename from patches/unapplied/0260-Don-t-sleep-after-profile-lookups-if-not-needed.patch rename to patches/unapplied/server/0260-Don-t-sleep-after-profile-lookups-if-not-needed.patch diff --git a/patches/unapplied/0261-Improve-Server-Thread-Pool-and-Thread-Priorities.patch b/patches/unapplied/server/0261-Improve-Server-Thread-Pool-and-Thread-Priorities.patch similarity index 100% rename from patches/unapplied/0261-Improve-Server-Thread-Pool-and-Thread-Priorities.patch rename to patches/unapplied/server/0261-Improve-Server-Thread-Pool-and-Thread-Priorities.patch diff --git a/patches/unapplied/0262-Optimize-World-Time-Updates.patch b/patches/unapplied/server/0262-Optimize-World-Time-Updates.patch similarity index 100% rename from patches/unapplied/0262-Optimize-World-Time-Updates.patch rename to patches/unapplied/server/0262-Optimize-World-Time-Updates.patch diff --git a/patches/unapplied/0263-Restore-custom-InventoryHolder-support.patch b/patches/unapplied/server/0263-Restore-custom-InventoryHolder-support.patch similarity index 100% rename from patches/unapplied/0263-Restore-custom-InventoryHolder-support.patch rename to patches/unapplied/server/0263-Restore-custom-InventoryHolder-support.patch diff --git a/patches/unapplied/0264-Fix-SpongeAbsortEvent-handling.patch b/patches/unapplied/server/0264-Fix-SpongeAbsortEvent-handling.patch similarity index 100% rename from patches/unapplied/0264-Fix-SpongeAbsortEvent-handling.patch rename to patches/unapplied/server/0264-Fix-SpongeAbsortEvent-handling.patch diff --git a/patches/unapplied/0265-Don-t-allow-digging-into-unloaded-chunks.patch b/patches/unapplied/server/0265-Don-t-allow-digging-into-unloaded-chunks.patch similarity index 100% rename from patches/unapplied/0265-Don-t-allow-digging-into-unloaded-chunks.patch rename to patches/unapplied/server/0265-Don-t-allow-digging-into-unloaded-chunks.patch diff --git a/patches/unapplied/0266-Make-the-default-permission-message-configurable.patch b/patches/unapplied/server/0266-Make-the-default-permission-message-configurable.patch similarity index 100% rename from patches/unapplied/0266-Make-the-default-permission-message-configurable.patch rename to patches/unapplied/server/0266-Make-the-default-permission-message-configurable.patch diff --git a/patches/unapplied/0267-force-entity-dismount-during-teleportation.patch b/patches/unapplied/server/0267-force-entity-dismount-during-teleportation.patch similarity index 100% rename from patches/unapplied/0267-force-entity-dismount-during-teleportation.patch rename to patches/unapplied/server/0267-force-entity-dismount-during-teleportation.patch diff --git a/patches/unapplied/0268-Add-more-Zombie-API.patch b/patches/unapplied/server/0268-Add-more-Zombie-API.patch similarity index 100% rename from patches/unapplied/0268-Add-more-Zombie-API.patch rename to patches/unapplied/server/0268-Add-more-Zombie-API.patch diff --git a/patches/unapplied/0269-Book-size-limits.patch b/patches/unapplied/server/0269-Book-size-limits.patch similarity index 100% rename from patches/unapplied/0269-Book-size-limits.patch rename to patches/unapplied/server/0269-Book-size-limits.patch diff --git a/patches/unapplied/0270-Add-PlayerConnectionCloseEvent.patch b/patches/unapplied/server/0270-Add-PlayerConnectionCloseEvent.patch similarity index 100% rename from patches/unapplied/0270-Add-PlayerConnectionCloseEvent.patch rename to patches/unapplied/server/0270-Add-PlayerConnectionCloseEvent.patch diff --git a/patches/unapplied/0271-Replace-OfflinePlayer-getLastPlayed.patch b/patches/unapplied/server/0271-Replace-OfflinePlayer-getLastPlayed.patch similarity index 100% rename from patches/unapplied/0271-Replace-OfflinePlayer-getLastPlayed.patch rename to patches/unapplied/server/0271-Replace-OfflinePlayer-getLastPlayed.patch diff --git a/patches/unapplied/0272-Workaround-for-vehicle-tracking-issue-on-disconnect.patch b/patches/unapplied/server/0272-Workaround-for-vehicle-tracking-issue-on-disconnect.patch similarity index 100% rename from patches/unapplied/0272-Workaround-for-vehicle-tracking-issue-on-disconnect.patch rename to patches/unapplied/server/0272-Workaround-for-vehicle-tracking-issue-on-disconnect.patch diff --git a/patches/unapplied/0273-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch b/patches/unapplied/server/0273-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch similarity index 100% rename from patches/unapplied/0273-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch rename to patches/unapplied/server/0273-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch diff --git a/patches/unapplied/0274-BlockDestroyEvent.patch b/patches/unapplied/server/0274-BlockDestroyEvent.patch similarity index 100% rename from patches/unapplied/0274-BlockDestroyEvent.patch rename to patches/unapplied/server/0274-BlockDestroyEvent.patch diff --git a/patches/unapplied/0275-Async-command-map-building.patch b/patches/unapplied/server/0275-Async-command-map-building.patch similarity index 100% rename from patches/unapplied/0275-Async-command-map-building.patch rename to patches/unapplied/server/0275-Async-command-map-building.patch diff --git a/patches/unapplied/0276-Brigadier-Mojang-API.patch b/patches/unapplied/server/0276-Brigadier-Mojang-API.patch similarity index 100% rename from patches/unapplied/0276-Brigadier-Mojang-API.patch rename to patches/unapplied/server/0276-Brigadier-Mojang-API.patch diff --git a/patches/unapplied/0277-Improve-exact-choice-recipe-ingredients.patch b/patches/unapplied/server/0277-Improve-exact-choice-recipe-ingredients.patch similarity index 100% rename from patches/unapplied/0277-Improve-exact-choice-recipe-ingredients.patch rename to patches/unapplied/server/0277-Improve-exact-choice-recipe-ingredients.patch diff --git a/patches/unapplied/0278-Limit-Client-Sign-length-more.patch b/patches/unapplied/server/0278-Limit-Client-Sign-length-more.patch similarity index 100% rename from patches/unapplied/0278-Limit-Client-Sign-length-more.patch rename to patches/unapplied/server/0278-Limit-Client-Sign-length-more.patch diff --git a/patches/unapplied/0279-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch b/patches/unapplied/server/0279-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch similarity index 100% rename from patches/unapplied/0279-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch rename to patches/unapplied/server/0279-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch diff --git a/patches/unapplied/0280-Fixes-and-additions-to-the-spawn-reason-API.patch b/patches/unapplied/server/0280-Fixes-and-additions-to-the-spawn-reason-API.patch similarity index 100% rename from patches/unapplied/0280-Fixes-and-additions-to-the-spawn-reason-API.patch rename to patches/unapplied/server/0280-Fixes-and-additions-to-the-spawn-reason-API.patch diff --git a/patches/unapplied/0281-Fire-event-on-GS4-query.patch b/patches/unapplied/server/0281-Fire-event-on-GS4-query.patch similarity index 100% rename from patches/unapplied/0281-Fire-event-on-GS4-query.patch rename to patches/unapplied/server/0281-Fire-event-on-GS4-query.patch diff --git a/patches/unapplied/0282-Add-PlayerPostRespawnEvent.patch b/patches/unapplied/server/0282-Add-PlayerPostRespawnEvent.patch similarity index 100% rename from patches/unapplied/0282-Add-PlayerPostRespawnEvent.patch rename to patches/unapplied/server/0282-Add-PlayerPostRespawnEvent.patch diff --git a/patches/unapplied/0283-Server-Tick-Events.patch b/patches/unapplied/server/0283-Server-Tick-Events.patch similarity index 100% rename from patches/unapplied/0283-Server-Tick-Events.patch rename to patches/unapplied/server/0283-Server-Tick-Events.patch diff --git a/patches/unapplied/0284-PlayerDeathEvent-getItemsToKeep.patch b/patches/unapplied/server/0284-PlayerDeathEvent-getItemsToKeep.patch similarity index 100% rename from patches/unapplied/0284-PlayerDeathEvent-getItemsToKeep.patch rename to patches/unapplied/server/0284-PlayerDeathEvent-getItemsToKeep.patch diff --git a/patches/unapplied/0285-Optimize-Captured-BlockEntity-Lookup.patch b/patches/unapplied/server/0285-Optimize-Captured-BlockEntity-Lookup.patch similarity index 100% rename from patches/unapplied/0285-Optimize-Captured-BlockEntity-Lookup.patch rename to patches/unapplied/server/0285-Optimize-Captured-BlockEntity-Lookup.patch diff --git a/patches/unapplied/0286-Mob-Spawner-API-Enhancements.patch b/patches/unapplied/server/0286-Mob-Spawner-API-Enhancements.patch similarity index 100% rename from patches/unapplied/0286-Mob-Spawner-API-Enhancements.patch rename to patches/unapplied/server/0286-Mob-Spawner-API-Enhancements.patch diff --git a/patches/unapplied/0287-Fix-CB-call-to-changed-postToMainThread-method.patch b/patches/unapplied/server/0287-Fix-CB-call-to-changed-postToMainThread-method.patch similarity index 100% rename from patches/unapplied/0287-Fix-CB-call-to-changed-postToMainThread-method.patch rename to patches/unapplied/server/0287-Fix-CB-call-to-changed-postToMainThread-method.patch diff --git a/patches/unapplied/0288-Fix-sounds-when-item-frames-are-modified-MC-123450.patch b/patches/unapplied/server/0288-Fix-sounds-when-item-frames-are-modified-MC-123450.patch similarity index 100% rename from patches/unapplied/0288-Fix-sounds-when-item-frames-are-modified-MC-123450.patch rename to patches/unapplied/server/0288-Fix-sounds-when-item-frames-are-modified-MC-123450.patch diff --git a/patches/unapplied/0289-Implement-CraftBlockSoundGroup.patch b/patches/unapplied/server/0289-Implement-CraftBlockSoundGroup.patch similarity index 100% rename from patches/unapplied/0289-Implement-CraftBlockSoundGroup.patch rename to patches/unapplied/server/0289-Implement-CraftBlockSoundGroup.patch diff --git a/patches/unapplied/0290-Expose-the-internal-current-tick.patch b/patches/unapplied/server/0290-Expose-the-internal-current-tick.patch similarity index 100% rename from patches/unapplied/0290-Expose-the-internal-current-tick.patch rename to patches/unapplied/server/0290-Expose-the-internal-current-tick.patch diff --git a/patches/unapplied/0291-Show-blockstate-location-if-we-failed-to-read-it.patch b/patches/unapplied/server/0291-Show-blockstate-location-if-we-failed-to-read-it.patch similarity index 100% rename from patches/unapplied/0291-Show-blockstate-location-if-we-failed-to-read-it.patch rename to patches/unapplied/server/0291-Show-blockstate-location-if-we-failed-to-read-it.patch diff --git a/patches/unapplied/0292-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch b/patches/unapplied/server/0292-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch similarity index 100% rename from patches/unapplied/0292-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch rename to patches/unapplied/server/0292-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch diff --git a/patches/unapplied/0293-Configurable-projectile-relative-velocity.patch b/patches/unapplied/server/0293-Configurable-projectile-relative-velocity.patch similarity index 100% rename from patches/unapplied/0293-Configurable-projectile-relative-velocity.patch rename to patches/unapplied/server/0293-Configurable-projectile-relative-velocity.patch diff --git a/patches/unapplied/0294-offset-item-frame-ticking.patch b/patches/unapplied/server/0294-offset-item-frame-ticking.patch similarity index 100% rename from patches/unapplied/0294-offset-item-frame-ticking.patch rename to patches/unapplied/server/0294-offset-item-frame-ticking.patch diff --git a/patches/unapplied/0295-Prevent-consuming-the-wrong-itemstack.patch b/patches/unapplied/server/0295-Prevent-consuming-the-wrong-itemstack.patch similarity index 100% rename from patches/unapplied/0295-Prevent-consuming-the-wrong-itemstack.patch rename to patches/unapplied/server/0295-Prevent-consuming-the-wrong-itemstack.patch diff --git a/patches/unapplied/0296-Dont-send-unnecessary-sign-update.patch b/patches/unapplied/server/0296-Dont-send-unnecessary-sign-update.patch similarity index 100% rename from patches/unapplied/0296-Dont-send-unnecessary-sign-update.patch rename to patches/unapplied/server/0296-Dont-send-unnecessary-sign-update.patch diff --git a/patches/unapplied/0297-Add-option-to-disable-pillager-patrols.patch b/patches/unapplied/server/0297-Add-option-to-disable-pillager-patrols.patch similarity index 100% rename from patches/unapplied/0297-Add-option-to-disable-pillager-patrols.patch rename to patches/unapplied/server/0297-Add-option-to-disable-pillager-patrols.patch diff --git a/patches/unapplied/0298-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch b/patches/unapplied/server/0298-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch similarity index 100% rename from patches/unapplied/0298-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch rename to patches/unapplied/server/0298-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch diff --git a/patches/unapplied/0299-MC-145656-Fix-Follow-Range-Initial-Target.patch b/patches/unapplied/server/0299-MC-145656-Fix-Follow-Range-Initial-Target.patch similarity index 100% rename from patches/unapplied/0299-MC-145656-Fix-Follow-Range-Initial-Target.patch rename to patches/unapplied/server/0299-MC-145656-Fix-Follow-Range-Initial-Target.patch diff --git a/patches/unapplied/0300-Duplicate-UUID-Resolve-Option.patch b/patches/unapplied/server/0300-Duplicate-UUID-Resolve-Option.patch similarity index 100% rename from patches/unapplied/0300-Duplicate-UUID-Resolve-Option.patch rename to patches/unapplied/server/0300-Duplicate-UUID-Resolve-Option.patch diff --git a/patches/unapplied/0301-PlayerDeathEvent-shouldDropExperience.patch b/patches/unapplied/server/0301-PlayerDeathEvent-shouldDropExperience.patch similarity index 100% rename from patches/unapplied/0301-PlayerDeathEvent-shouldDropExperience.patch rename to patches/unapplied/server/0301-PlayerDeathEvent-shouldDropExperience.patch diff --git a/patches/unapplied/0302-Prevent-bees-loading-chunks-checking-hive-position.patch b/patches/unapplied/server/0302-Prevent-bees-loading-chunks-checking-hive-position.patch similarity index 100% rename from patches/unapplied/0302-Prevent-bees-loading-chunks-checking-hive-position.patch rename to patches/unapplied/server/0302-Prevent-bees-loading-chunks-checking-hive-position.patch diff --git a/patches/unapplied/0303-Don-t-load-Chunks-from-Hoppers-and-other-things.patch b/patches/unapplied/server/0303-Don-t-load-Chunks-from-Hoppers-and-other-things.patch similarity index 100% rename from patches/unapplied/0303-Don-t-load-Chunks-from-Hoppers-and-other-things.patch rename to patches/unapplied/server/0303-Don-t-load-Chunks-from-Hoppers-and-other-things.patch diff --git a/patches/unapplied/0304-Optimise-EntityGetter-getPlayerByUUID.patch b/patches/unapplied/server/0304-Optimise-EntityGetter-getPlayerByUUID.patch similarity index 100% rename from patches/unapplied/0304-Optimise-EntityGetter-getPlayerByUUID.patch rename to patches/unapplied/server/0304-Optimise-EntityGetter-getPlayerByUUID.patch diff --git a/patches/unapplied/0305-Fix-items-not-falling-correctly.patch b/patches/unapplied/server/0305-Fix-items-not-falling-correctly.patch similarity index 100% rename from patches/unapplied/0305-Fix-items-not-falling-correctly.patch rename to patches/unapplied/server/0305-Fix-items-not-falling-correctly.patch diff --git a/patches/unapplied/0306-Optimize-call-to-getFluid-for-explosions.patch b/patches/unapplied/server/0306-Optimize-call-to-getFluid-for-explosions.patch similarity index 100% rename from patches/unapplied/0306-Optimize-call-to-getFluid-for-explosions.patch rename to patches/unapplied/server/0306-Optimize-call-to-getFluid-for-explosions.patch diff --git a/patches/unapplied/0307-Guard-against-serializing-mismatching-chunk-coordina.patch b/patches/unapplied/server/0307-Guard-against-serializing-mismatching-chunk-coordina.patch similarity index 100% rename from patches/unapplied/0307-Guard-against-serializing-mismatching-chunk-coordina.patch rename to patches/unapplied/server/0307-Guard-against-serializing-mismatching-chunk-coordina.patch diff --git a/patches/unapplied/0308-Alternative-item-despawn-rate.patch b/patches/unapplied/server/0308-Alternative-item-despawn-rate.patch similarity index 100% rename from patches/unapplied/0308-Alternative-item-despawn-rate.patch rename to patches/unapplied/server/0308-Alternative-item-despawn-rate.patch diff --git a/patches/unapplied/0309-Tracking-Range-Improvements.patch b/patches/unapplied/server/0309-Tracking-Range-Improvements.patch similarity index 100% rename from patches/unapplied/0309-Tracking-Range-Improvements.patch rename to patches/unapplied/server/0309-Tracking-Range-Improvements.patch diff --git a/patches/unapplied/0310-Bees-get-gravity-in-void.-Fixes-MC-167279.patch b/patches/unapplied/server/0310-Bees-get-gravity-in-void.-Fixes-MC-167279.patch similarity index 100% rename from patches/unapplied/0310-Bees-get-gravity-in-void.-Fixes-MC-167279.patch rename to patches/unapplied/server/0310-Bees-get-gravity-in-void.-Fixes-MC-167279.patch diff --git a/patches/unapplied/0311-Improve-Block-breakNaturally-API.patch b/patches/unapplied/server/0311-Improve-Block-breakNaturally-API.patch similarity index 100% rename from patches/unapplied/0311-Improve-Block-breakNaturally-API.patch rename to patches/unapplied/server/0311-Improve-Block-breakNaturally-API.patch diff --git a/patches/unapplied/0312-Optimise-getChunkAt-calls-for-loaded-chunks.patch b/patches/unapplied/server/0312-Optimise-getChunkAt-calls-for-loaded-chunks.patch similarity index 100% rename from patches/unapplied/0312-Optimise-getChunkAt-calls-for-loaded-chunks.patch rename to patches/unapplied/server/0312-Optimise-getChunkAt-calls-for-loaded-chunks.patch diff --git a/patches/unapplied/0313-Add-debug-for-sync-chunk-loads.patch b/patches/unapplied/server/0313-Add-debug-for-sync-chunk-loads.patch similarity index 100% rename from patches/unapplied/0313-Add-debug-for-sync-chunk-loads.patch rename to patches/unapplied/server/0313-Add-debug-for-sync-chunk-loads.patch diff --git a/patches/unapplied/0314-Improve-java-version-check.patch b/patches/unapplied/server/0314-Improve-java-version-check.patch similarity index 100% rename from patches/unapplied/0314-Improve-java-version-check.patch rename to patches/unapplied/server/0314-Improve-java-version-check.patch diff --git a/patches/unapplied/0315-Add-ThrownEggHatchEvent.patch b/patches/unapplied/server/0315-Add-ThrownEggHatchEvent.patch similarity index 100% rename from patches/unapplied/0315-Add-ThrownEggHatchEvent.patch rename to patches/unapplied/server/0315-Add-ThrownEggHatchEvent.patch diff --git a/patches/unapplied/0316-Entity-Jump-API.patch b/patches/unapplied/server/0316-Entity-Jump-API.patch similarity index 100% rename from patches/unapplied/0316-Entity-Jump-API.patch rename to patches/unapplied/server/0316-Entity-Jump-API.patch diff --git a/patches/unapplied/0317-Add-option-to-nerf-pigmen-from-nether-portals.patch b/patches/unapplied/server/0317-Add-option-to-nerf-pigmen-from-nether-portals.patch similarity index 100% rename from patches/unapplied/0317-Add-option-to-nerf-pigmen-from-nether-portals.patch rename to patches/unapplied/server/0317-Add-option-to-nerf-pigmen-from-nether-portals.patch diff --git a/patches/unapplied/0318-Make-the-GUI-graph-fancier.patch b/patches/unapplied/server/0318-Make-the-GUI-graph-fancier.patch similarity index 100% rename from patches/unapplied/0318-Make-the-GUI-graph-fancier.patch rename to patches/unapplied/server/0318-Make-the-GUI-graph-fancier.patch diff --git a/patches/unapplied/0319-add-hand-to-BlockMultiPlaceEvent.patch b/patches/unapplied/server/0319-add-hand-to-BlockMultiPlaceEvent.patch similarity index 100% rename from patches/unapplied/0319-add-hand-to-BlockMultiPlaceEvent.patch rename to patches/unapplied/server/0319-add-hand-to-BlockMultiPlaceEvent.patch diff --git a/patches/unapplied/0320-Validate-tripwire-hook-placement-before-update.patch b/patches/unapplied/server/0320-Validate-tripwire-hook-placement-before-update.patch similarity index 100% rename from patches/unapplied/0320-Validate-tripwire-hook-placement-before-update.patch rename to patches/unapplied/server/0320-Validate-tripwire-hook-placement-before-update.patch diff --git a/patches/unapplied/0321-Add-option-to-allow-iron-golems-to-spawn-in-air.patch b/patches/unapplied/server/0321-Add-option-to-allow-iron-golems-to-spawn-in-air.patch similarity index 100% rename from patches/unapplied/0321-Add-option-to-allow-iron-golems-to-spawn-in-air.patch rename to patches/unapplied/server/0321-Add-option-to-allow-iron-golems-to-spawn-in-air.patch diff --git a/patches/unapplied/0322-Configurable-chance-of-villager-zombie-infection.patch b/patches/unapplied/server/0322-Configurable-chance-of-villager-zombie-infection.patch similarity index 100% rename from patches/unapplied/0322-Configurable-chance-of-villager-zombie-infection.patch rename to patches/unapplied/server/0322-Configurable-chance-of-villager-zombie-infection.patch diff --git a/patches/unapplied/0323-Optimise-Chunk-getFluid.patch b/patches/unapplied/server/0323-Optimise-Chunk-getFluid.patch similarity index 100% rename from patches/unapplied/0323-Optimise-Chunk-getFluid.patch rename to patches/unapplied/server/0323-Optimise-Chunk-getFluid.patch diff --git a/patches/unapplied/0324-Set-spigots-verbose-world-setting-to-false-by-def.patch b/patches/unapplied/server/0324-Set-spigots-verbose-world-setting-to-false-by-def.patch similarity index 100% rename from patches/unapplied/0324-Set-spigots-verbose-world-setting-to-false-by-def.patch rename to patches/unapplied/server/0324-Set-spigots-verbose-world-setting-to-false-by-def.patch diff --git a/patches/unapplied/0325-Add-tick-times-API-and-mspt-command.patch b/patches/unapplied/server/0325-Add-tick-times-API-and-mspt-command.patch similarity index 100% rename from patches/unapplied/0325-Add-tick-times-API-and-mspt-command.patch rename to patches/unapplied/server/0325-Add-tick-times-API-and-mspt-command.patch diff --git a/patches/unapplied/0326-Expose-MinecraftServer-isRunning.patch b/patches/unapplied/server/0326-Expose-MinecraftServer-isRunning.patch similarity index 100% rename from patches/unapplied/0326-Expose-MinecraftServer-isRunning.patch rename to patches/unapplied/server/0326-Expose-MinecraftServer-isRunning.patch diff --git a/patches/unapplied/0327-Add-Raw-Byte-ItemStack-Serialization.patch b/patches/unapplied/server/0327-Add-Raw-Byte-ItemStack-Serialization.patch similarity index 100% rename from patches/unapplied/0327-Add-Raw-Byte-ItemStack-Serialization.patch rename to patches/unapplied/server/0327-Add-Raw-Byte-ItemStack-Serialization.patch diff --git a/patches/unapplied/0328-Pillager-patrol-spawn-settings-and-per-player-option.patch b/patches/unapplied/server/0328-Pillager-patrol-spawn-settings-and-per-player-option.patch similarity index 100% rename from patches/unapplied/0328-Pillager-patrol-spawn-settings-and-per-player-option.patch rename to patches/unapplied/server/0328-Pillager-patrol-spawn-settings-and-per-player-option.patch diff --git a/patches/unapplied/0329-Remote-Connections-shouldn-t-hold-up-shutdown.patch b/patches/unapplied/server/0329-Remote-Connections-shouldn-t-hold-up-shutdown.patch similarity index 100% rename from patches/unapplied/0329-Remote-Connections-shouldn-t-hold-up-shutdown.patch rename to patches/unapplied/server/0329-Remote-Connections-shouldn-t-hold-up-shutdown.patch diff --git a/patches/unapplied/0330-Do-not-allow-bees-to-load-chunks-for-beehives.patch b/patches/unapplied/server/0330-Do-not-allow-bees-to-load-chunks-for-beehives.patch similarity index 100% rename from patches/unapplied/0330-Do-not-allow-bees-to-load-chunks-for-beehives.patch rename to patches/unapplied/server/0330-Do-not-allow-bees-to-load-chunks-for-beehives.patch diff --git a/patches/unapplied/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch b/patches/unapplied/server/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch similarity index 100% rename from patches/unapplied/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch rename to patches/unapplied/server/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch diff --git a/patches/unapplied/0332-Don-t-tick-dead-players.patch b/patches/unapplied/server/0332-Don-t-tick-dead-players.patch similarity index 100% rename from patches/unapplied/0332-Don-t-tick-dead-players.patch rename to patches/unapplied/server/0332-Don-t-tick-dead-players.patch diff --git a/patches/unapplied/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch b/patches/unapplied/server/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch similarity index 100% rename from patches/unapplied/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch rename to patches/unapplied/server/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch diff --git a/patches/unapplied/0334-Don-t-move-existing-players-to-world-spawn.patch b/patches/unapplied/server/0334-Don-t-move-existing-players-to-world-spawn.patch similarity index 100% rename from patches/unapplied/0334-Don-t-move-existing-players-to-world-spawn.patch rename to patches/unapplied/server/0334-Don-t-move-existing-players-to-world-spawn.patch diff --git a/patches/unapplied/0335-Optimize-Pathfinding.patch b/patches/unapplied/server/0335-Optimize-Pathfinding.patch similarity index 100% rename from patches/unapplied/0335-Optimize-Pathfinding.patch rename to patches/unapplied/server/0335-Optimize-Pathfinding.patch diff --git a/patches/unapplied/0336-Reduce-Either-Optional-allocation.patch b/patches/unapplied/server/0336-Reduce-Either-Optional-allocation.patch similarity index 100% rename from patches/unapplied/0336-Reduce-Either-Optional-allocation.patch rename to patches/unapplied/server/0336-Reduce-Either-Optional-allocation.patch diff --git a/patches/unapplied/0337-Reduce-memory-footprint-of-CompoundTag.patch b/patches/unapplied/server/0337-Reduce-memory-footprint-of-CompoundTag.patch similarity index 100% rename from patches/unapplied/0337-Reduce-memory-footprint-of-CompoundTag.patch rename to patches/unapplied/server/0337-Reduce-memory-footprint-of-CompoundTag.patch diff --git a/patches/unapplied/0338-Prevent-opening-inventories-when-frozen.patch b/patches/unapplied/server/0338-Prevent-opening-inventories-when-frozen.patch similarity index 100% rename from patches/unapplied/0338-Prevent-opening-inventories-when-frozen.patch rename to patches/unapplied/server/0338-Prevent-opening-inventories-when-frozen.patch diff --git a/patches/unapplied/0339-Don-t-run-entity-collision-code-if-not-needed.patch b/patches/unapplied/server/0339-Don-t-run-entity-collision-code-if-not-needed.patch similarity index 100% rename from patches/unapplied/0339-Don-t-run-entity-collision-code-if-not-needed.patch rename to patches/unapplied/server/0339-Don-t-run-entity-collision-code-if-not-needed.patch diff --git a/patches/unapplied/0340-Implement-Player-Client-Options-API.patch b/patches/unapplied/server/0340-Implement-Player-Client-Options-API.patch similarity index 100% rename from patches/unapplied/0340-Implement-Player-Client-Options-API.patch rename to patches/unapplied/server/0340-Implement-Player-Client-Options-API.patch diff --git a/patches/unapplied/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch b/patches/unapplied/server/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch similarity index 100% rename from patches/unapplied/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch rename to patches/unapplied/server/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch diff --git a/patches/unapplied/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch b/patches/unapplied/server/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch similarity index 100% rename from patches/unapplied/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch rename to patches/unapplied/server/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch diff --git a/patches/unapplied/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch b/patches/unapplied/server/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch similarity index 100% rename from patches/unapplied/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch rename to patches/unapplied/server/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch diff --git a/patches/unapplied/0344-Add-PlayerAttackEntityCooldownResetEvent.patch b/patches/unapplied/server/0344-Add-PlayerAttackEntityCooldownResetEvent.patch similarity index 100% rename from patches/unapplied/0344-Add-PlayerAttackEntityCooldownResetEvent.patch rename to patches/unapplied/server/0344-Add-PlayerAttackEntityCooldownResetEvent.patch diff --git a/patches/unapplied/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch b/patches/unapplied/server/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch similarity index 100% rename from patches/unapplied/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch rename to patches/unapplied/server/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch diff --git a/patches/unapplied/0346-Add-phantom-creative-and-insomniac-controls.patch b/patches/unapplied/server/0346-Add-phantom-creative-and-insomniac-controls.patch similarity index 100% rename from patches/unapplied/0346-Add-phantom-creative-and-insomniac-controls.patch rename to patches/unapplied/server/0346-Add-phantom-creative-and-insomniac-controls.patch diff --git a/patches/unapplied/0347-Fix-item-duplication-and-teleport-issues.patch b/patches/unapplied/server/0347-Fix-item-duplication-and-teleport-issues.patch similarity index 100% rename from patches/unapplied/0347-Fix-item-duplication-and-teleport-issues.patch rename to patches/unapplied/server/0347-Fix-item-duplication-and-teleport-issues.patch diff --git a/patches/unapplied/0348-Villager-Restocks-API.patch b/patches/unapplied/server/0348-Villager-Restocks-API.patch similarity index 100% rename from patches/unapplied/0348-Villager-Restocks-API.patch rename to patches/unapplied/server/0348-Villager-Restocks-API.patch diff --git a/patches/unapplied/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch b/patches/unapplied/server/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch similarity index 100% rename from patches/unapplied/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch rename to patches/unapplied/server/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch diff --git a/patches/unapplied/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch b/patches/unapplied/server/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch similarity index 100% rename from patches/unapplied/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch rename to patches/unapplied/server/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch diff --git a/patches/unapplied/0351-misc-debugging-dumps.patch b/patches/unapplied/server/0351-misc-debugging-dumps.patch similarity index 100% rename from patches/unapplied/0351-misc-debugging-dumps.patch rename to patches/unapplied/server/0351-misc-debugging-dumps.patch diff --git a/patches/unapplied/0352-Prevent-teleporting-dead-entities.patch b/patches/unapplied/server/0352-Prevent-teleporting-dead-entities.patch similarity index 100% rename from patches/unapplied/0352-Prevent-teleporting-dead-entities.patch rename to patches/unapplied/server/0352-Prevent-teleporting-dead-entities.patch diff --git a/patches/unapplied/0353-Implement-Mob-Goal-API.patch b/patches/unapplied/server/0353-Implement-Mob-Goal-API.patch similarity index 100% rename from patches/unapplied/0353-Implement-Mob-Goal-API.patch rename to patches/unapplied/server/0353-Implement-Mob-Goal-API.patch diff --git a/patches/unapplied/0354-Add-villager-reputation-API.patch b/patches/unapplied/server/0354-Add-villager-reputation-API.patch similarity index 100% rename from patches/unapplied/0354-Add-villager-reputation-API.patch rename to patches/unapplied/server/0354-Add-villager-reputation-API.patch diff --git a/patches/unapplied/0355-ExperienceOrb-merging-stacking-API-and-fixes.patch b/patches/unapplied/server/0355-ExperienceOrb-merging-stacking-API-and-fixes.patch similarity index 100% rename from patches/unapplied/0355-ExperienceOrb-merging-stacking-API-and-fixes.patch rename to patches/unapplied/server/0355-ExperienceOrb-merging-stacking-API-and-fixes.patch diff --git a/patches/unapplied/0356-Fix-PotionEffect-ignores-icon-flag.patch b/patches/unapplied/server/0356-Fix-PotionEffect-ignores-icon-flag.patch similarity index 100% rename from patches/unapplied/0356-Fix-PotionEffect-ignores-icon-flag.patch rename to patches/unapplied/server/0356-Fix-PotionEffect-ignores-icon-flag.patch diff --git a/patches/unapplied/0357-Potential-bed-API.patch b/patches/unapplied/server/0357-Potential-bed-API.patch similarity index 100% rename from patches/unapplied/0357-Potential-bed-API.patch rename to patches/unapplied/server/0357-Potential-bed-API.patch diff --git a/patches/unapplied/0358-Wait-for-Async-Tasks-during-shutdown.patch b/patches/unapplied/server/0358-Wait-for-Async-Tasks-during-shutdown.patch similarity index 100% rename from patches/unapplied/0358-Wait-for-Async-Tasks-during-shutdown.patch rename to patches/unapplied/server/0358-Wait-for-Async-Tasks-during-shutdown.patch diff --git a/patches/unapplied/0359-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch b/patches/unapplied/server/0359-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch similarity index 100% rename from patches/unapplied/0359-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch rename to patches/unapplied/server/0359-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch diff --git a/patches/unapplied/0360-Add-option-for-console-having-all-permissions.patch b/patches/unapplied/server/0360-Add-option-for-console-having-all-permissions.patch similarity index 100% rename from patches/unapplied/0360-Add-option-for-console-having-all-permissions.patch rename to patches/unapplied/server/0360-Add-option-for-console-having-all-permissions.patch diff --git a/patches/unapplied/0361-Fix-villager-trading-demand-MC-163962.patch b/patches/unapplied/server/0361-Fix-villager-trading-demand-MC-163962.patch similarity index 100% rename from patches/unapplied/0361-Fix-villager-trading-demand-MC-163962.patch rename to patches/unapplied/server/0361-Fix-villager-trading-demand-MC-163962.patch diff --git a/patches/unapplied/0362-Maps-shouldn-t-load-chunks.patch b/patches/unapplied/server/0362-Maps-shouldn-t-load-chunks.patch similarity index 100% rename from patches/unapplied/0362-Maps-shouldn-t-load-chunks.patch rename to patches/unapplied/server/0362-Maps-shouldn-t-load-chunks.patch diff --git a/patches/unapplied/0363-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch b/patches/unapplied/server/0363-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch similarity index 100% rename from patches/unapplied/0363-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch rename to patches/unapplied/server/0363-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch diff --git a/patches/unapplied/0364-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch b/patches/unapplied/server/0364-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch similarity index 100% rename from patches/unapplied/0364-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch rename to patches/unapplied/server/0364-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch diff --git a/patches/unapplied/0365-Fix-piston-physics-inconsistency-MC-188840.patch b/patches/unapplied/server/0365-Fix-piston-physics-inconsistency-MC-188840.patch similarity index 100% rename from patches/unapplied/0365-Fix-piston-physics-inconsistency-MC-188840.patch rename to patches/unapplied/server/0365-Fix-piston-physics-inconsistency-MC-188840.patch diff --git a/patches/unapplied/0366-Fix-missing-chunks-due-to-integer-overflow.patch b/patches/unapplied/server/0366-Fix-missing-chunks-due-to-integer-overflow.patch similarity index 100% rename from patches/unapplied/0366-Fix-missing-chunks-due-to-integer-overflow.patch rename to patches/unapplied/server/0366-Fix-missing-chunks-due-to-integer-overflow.patch diff --git a/patches/unapplied/0367-Prevent-position-desync-causing-tp-exploit.patch b/patches/unapplied/server/0367-Prevent-position-desync-causing-tp-exploit.patch similarity index 100% rename from patches/unapplied/0367-Prevent-position-desync-causing-tp-exploit.patch rename to patches/unapplied/server/0367-Prevent-position-desync-causing-tp-exploit.patch diff --git a/patches/unapplied/0368-Inventory-getHolder-method-without-block-snapshot.patch b/patches/unapplied/server/0368-Inventory-getHolder-method-without-block-snapshot.patch similarity index 100% rename from patches/unapplied/0368-Inventory-getHolder-method-without-block-snapshot.patch rename to patches/unapplied/server/0368-Inventory-getHolder-method-without-block-snapshot.patch diff --git a/patches/unapplied/0369-Add-PlayerRecipeBookClickEvent.patch b/patches/unapplied/server/0369-Add-PlayerRecipeBookClickEvent.patch similarity index 100% rename from patches/unapplied/0369-Add-PlayerRecipeBookClickEvent.patch rename to patches/unapplied/server/0369-Add-PlayerRecipeBookClickEvent.patch diff --git a/patches/unapplied/0370-Hide-sync-chunk-writes-behind-flag.patch b/patches/unapplied/server/0370-Hide-sync-chunk-writes-behind-flag.patch similarity index 100% rename from patches/unapplied/0370-Hide-sync-chunk-writes-behind-flag.patch rename to patches/unapplied/server/0370-Hide-sync-chunk-writes-behind-flag.patch diff --git a/patches/unapplied/0371-Add-permission-for-command-blocks.patch b/patches/unapplied/server/0371-Add-permission-for-command-blocks.patch similarity index 100% rename from patches/unapplied/0371-Add-permission-for-command-blocks.patch rename to patches/unapplied/server/0371-Add-permission-for-command-blocks.patch diff --git a/patches/unapplied/0372-Ensure-Entity-position-and-AABB-are-never-invalid.patch b/patches/unapplied/server/0372-Ensure-Entity-position-and-AABB-are-never-invalid.patch similarity index 100% rename from patches/unapplied/0372-Ensure-Entity-position-and-AABB-are-never-invalid.patch rename to patches/unapplied/server/0372-Ensure-Entity-position-and-AABB-are-never-invalid.patch diff --git a/patches/unapplied/0373-Fix-Per-World-Difficulty-Remembering-Difficulty.patch b/patches/unapplied/server/0373-Fix-Per-World-Difficulty-Remembering-Difficulty.patch similarity index 100% rename from patches/unapplied/0373-Fix-Per-World-Difficulty-Remembering-Difficulty.patch rename to patches/unapplied/server/0373-Fix-Per-World-Difficulty-Remembering-Difficulty.patch diff --git a/patches/unapplied/0374-Paper-dumpitem-command.patch b/patches/unapplied/server/0374-Paper-dumpitem-command.patch similarity index 100% rename from patches/unapplied/0374-Paper-dumpitem-command.patch rename to patches/unapplied/server/0374-Paper-dumpitem-command.patch diff --git a/patches/unapplied/0375-Improve-Legacy-Component-serialization-size.patch b/patches/unapplied/server/0375-Improve-Legacy-Component-serialization-size.patch similarity index 100% rename from patches/unapplied/0375-Improve-Legacy-Component-serialization-size.patch rename to patches/unapplied/server/0375-Improve-Legacy-Component-serialization-size.patch diff --git a/patches/unapplied/0376-Add-Plugin-Tickets-to-API-Chunk-Methods.patch b/patches/unapplied/server/0376-Add-Plugin-Tickets-to-API-Chunk-Methods.patch similarity index 100% rename from patches/unapplied/0376-Add-Plugin-Tickets-to-API-Chunk-Methods.patch rename to patches/unapplied/server/0376-Add-Plugin-Tickets-to-API-Chunk-Methods.patch diff --git a/patches/unapplied/0377-Add-BlockStateMeta-clearBlockState.patch b/patches/unapplied/server/0377-Add-BlockStateMeta-clearBlockState.patch similarity index 100% rename from patches/unapplied/0377-Add-BlockStateMeta-clearBlockState.patch rename to patches/unapplied/server/0377-Add-BlockStateMeta-clearBlockState.patch diff --git a/patches/unapplied/0378-Convert-legacy-attributes-in-Item-Meta.patch b/patches/unapplied/server/0378-Convert-legacy-attributes-in-Item-Meta.patch similarity index 100% rename from patches/unapplied/0378-Convert-legacy-attributes-in-Item-Meta.patch rename to patches/unapplied/server/0378-Convert-legacy-attributes-in-Item-Meta.patch diff --git a/patches/unapplied/0379-Do-not-accept-invalid-client-settings.patch b/patches/unapplied/server/0379-Do-not-accept-invalid-client-settings.patch similarity index 100% rename from patches/unapplied/0379-Do-not-accept-invalid-client-settings.patch rename to patches/unapplied/server/0379-Do-not-accept-invalid-client-settings.patch diff --git a/patches/unapplied/0380-Improve-fix-EntityTargetLivingEntityEvent.patch b/patches/unapplied/server/0380-Improve-fix-EntityTargetLivingEntityEvent.patch similarity index 100% rename from patches/unapplied/0380-Improve-fix-EntityTargetLivingEntityEvent.patch rename to patches/unapplied/server/0380-Improve-fix-EntityTargetLivingEntityEvent.patch diff --git a/patches/unapplied/0381-Add-entity-liquid-API.patch b/patches/unapplied/server/0381-Add-entity-liquid-API.patch similarity index 100% rename from patches/unapplied/0381-Add-entity-liquid-API.patch rename to patches/unapplied/server/0381-Add-entity-liquid-API.patch diff --git a/patches/unapplied/0382-Add-PrepareResultEvent.patch b/patches/unapplied/server/0382-Add-PrepareResultEvent.patch similarity index 100% rename from patches/unapplied/0382-Add-PrepareResultEvent.patch rename to patches/unapplied/server/0382-Add-PrepareResultEvent.patch diff --git a/patches/unapplied/0383-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch b/patches/unapplied/server/0383-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch similarity index 100% rename from patches/unapplied/0383-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch rename to patches/unapplied/server/0383-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch diff --git a/patches/unapplied/0384-Fix-arrows-never-despawning-MC-125757.patch b/patches/unapplied/server/0384-Fix-arrows-never-despawning-MC-125757.patch similarity index 100% rename from patches/unapplied/0384-Fix-arrows-never-despawning-MC-125757.patch rename to patches/unapplied/server/0384-Fix-arrows-never-despawning-MC-125757.patch diff --git a/patches/unapplied/0385-Thread-Safe-Vanilla-Command-permission-checking.patch b/patches/unapplied/server/0385-Thread-Safe-Vanilla-Command-permission-checking.patch similarity index 100% rename from patches/unapplied/0385-Thread-Safe-Vanilla-Command-permission-checking.patch rename to patches/unapplied/server/0385-Thread-Safe-Vanilla-Command-permission-checking.patch diff --git a/patches/unapplied/0386-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch b/patches/unapplied/server/0386-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch similarity index 100% rename from patches/unapplied/0386-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch rename to patches/unapplied/server/0386-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch diff --git a/patches/unapplied/0387-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch b/patches/unapplied/server/0387-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch similarity index 100% rename from patches/unapplied/0387-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch rename to patches/unapplied/server/0387-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch diff --git a/patches/unapplied/0388-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch b/patches/unapplied/server/0388-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch similarity index 100% rename from patches/unapplied/0388-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch rename to patches/unapplied/server/0388-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch diff --git a/patches/unapplied/0389-Optimize-NetworkManager-Exception-Handling.patch b/patches/unapplied/server/0389-Optimize-NetworkManager-Exception-Handling.patch similarity index 100% rename from patches/unapplied/0389-Optimize-NetworkManager-Exception-Handling.patch rename to patches/unapplied/server/0389-Optimize-NetworkManager-Exception-Handling.patch diff --git a/patches/unapplied/0390-Fix-some-rails-connecting-improperly.patch b/patches/unapplied/server/0390-Fix-some-rails-connecting-improperly.patch similarity index 100% rename from patches/unapplied/0390-Fix-some-rails-connecting-improperly.patch rename to patches/unapplied/server/0390-Fix-some-rails-connecting-improperly.patch diff --git a/patches/unapplied/0391-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch b/patches/unapplied/server/0391-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch similarity index 100% rename from patches/unapplied/0391-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch rename to patches/unapplied/server/0391-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch diff --git a/patches/unapplied/0392-Brand-support.patch b/patches/unapplied/server/0392-Brand-support.patch similarity index 100% rename from patches/unapplied/0392-Brand-support.patch rename to patches/unapplied/server/0392-Brand-support.patch diff --git a/patches/unapplied/0393-Add-playPickupItemAnimation-to-LivingEntity.patch b/patches/unapplied/server/0393-Add-playPickupItemAnimation-to-LivingEntity.patch similarity index 100% rename from patches/unapplied/0393-Add-playPickupItemAnimation-to-LivingEntity.patch rename to patches/unapplied/server/0393-Add-playPickupItemAnimation-to-LivingEntity.patch diff --git a/patches/unapplied/0394-Don-t-require-FACING-data.patch b/patches/unapplied/server/0394-Don-t-require-FACING-data.patch similarity index 100% rename from patches/unapplied/0394-Don-t-require-FACING-data.patch rename to patches/unapplied/server/0394-Don-t-require-FACING-data.patch diff --git a/patches/unapplied/0395-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch b/patches/unapplied/server/0395-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch similarity index 100% rename from patches/unapplied/0395-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch rename to patches/unapplied/server/0395-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch diff --git a/patches/unapplied/0396-Add-moon-phase-API.patch b/patches/unapplied/server/0396-Add-moon-phase-API.patch similarity index 100% rename from patches/unapplied/0396-Add-moon-phase-API.patch rename to patches/unapplied/server/0396-Add-moon-phase-API.patch diff --git a/patches/unapplied/0397-Do-not-let-the-server-load-chunks-from-newer-version.patch b/patches/unapplied/server/0397-Do-not-let-the-server-load-chunks-from-newer-version.patch similarity index 100% rename from patches/unapplied/0397-Do-not-let-the-server-load-chunks-from-newer-version.patch rename to patches/unapplied/server/0397-Do-not-let-the-server-load-chunks-from-newer-version.patch diff --git a/patches/unapplied/0398-Prevent-headless-pistons-from-being-created.patch b/patches/unapplied/server/0398-Prevent-headless-pistons-from-being-created.patch similarity index 100% rename from patches/unapplied/0398-Prevent-headless-pistons-from-being-created.patch rename to patches/unapplied/server/0398-Prevent-headless-pistons-from-being-created.patch diff --git a/patches/unapplied/0399-Add-BellRingEvent.patch b/patches/unapplied/server/0399-Add-BellRingEvent.patch similarity index 100% rename from patches/unapplied/0399-Add-BellRingEvent.patch rename to patches/unapplied/server/0399-Add-BellRingEvent.patch diff --git a/patches/unapplied/0400-Add-zombie-targets-turtle-egg-config.patch b/patches/unapplied/server/0400-Add-zombie-targets-turtle-egg-config.patch similarity index 100% rename from patches/unapplied/0400-Add-zombie-targets-turtle-egg-config.patch rename to patches/unapplied/server/0400-Add-zombie-targets-turtle-egg-config.patch diff --git a/patches/unapplied/0401-Buffer-joins-to-world.patch b/patches/unapplied/server/0401-Buffer-joins-to-world.patch similarity index 100% rename from patches/unapplied/0401-Buffer-joins-to-world.patch rename to patches/unapplied/server/0401-Buffer-joins-to-world.patch diff --git a/patches/unapplied/0402-Fix-hex-colors-not-working-in-some-kick-messages.patch b/patches/unapplied/server/0402-Fix-hex-colors-not-working-in-some-kick-messages.patch similarity index 100% rename from patches/unapplied/0402-Fix-hex-colors-not-working-in-some-kick-messages.patch rename to patches/unapplied/server/0402-Fix-hex-colors-not-working-in-some-kick-messages.patch diff --git a/patches/unapplied/0403-Add-more-Evoker-API.patch b/patches/unapplied/server/0403-Add-more-Evoker-API.patch similarity index 100% rename from patches/unapplied/0403-Add-more-Evoker-API.patch rename to patches/unapplied/server/0403-Add-more-Evoker-API.patch diff --git a/patches/unapplied/0404-Add-methods-to-get-translation-keys.patch b/patches/unapplied/server/0404-Add-methods-to-get-translation-keys.patch similarity index 100% rename from patches/unapplied/0404-Add-methods-to-get-translation-keys.patch rename to patches/unapplied/server/0404-Add-methods-to-get-translation-keys.patch diff --git a/patches/unapplied/0405-Create-HoverEvent-from-ItemStack-Entity.patch b/patches/unapplied/server/0405-Create-HoverEvent-from-ItemStack-Entity.patch similarity index 100% rename from patches/unapplied/0405-Create-HoverEvent-from-ItemStack-Entity.patch rename to patches/unapplied/server/0405-Create-HoverEvent-from-ItemStack-Entity.patch diff --git a/patches/unapplied/0406-Cache-block-data-strings.patch b/patches/unapplied/server/0406-Cache-block-data-strings.patch similarity index 100% rename from patches/unapplied/0406-Cache-block-data-strings.patch rename to patches/unapplied/server/0406-Cache-block-data-strings.patch diff --git a/patches/unapplied/0407-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch b/patches/unapplied/server/0407-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch similarity index 100% rename from patches/unapplied/0407-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch rename to patches/unapplied/server/0407-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch diff --git a/patches/unapplied/0408-Add-additional-open-container-api-to-HumanEntity.patch b/patches/unapplied/server/0408-Add-additional-open-container-api-to-HumanEntity.patch similarity index 100% rename from patches/unapplied/0408-Add-additional-open-container-api-to-HumanEntity.patch rename to patches/unapplied/server/0408-Add-additional-open-container-api-to-HumanEntity.patch diff --git a/patches/unapplied/0409-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch b/patches/unapplied/server/0409-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch similarity index 100% rename from patches/unapplied/0409-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch rename to patches/unapplied/server/0409-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch diff --git a/patches/unapplied/0410-Extend-block-drop-capture-to-capture-all-items-added.patch b/patches/unapplied/server/0410-Extend-block-drop-capture-to-capture-all-items-added.patch similarity index 100% rename from patches/unapplied/0410-Extend-block-drop-capture-to-capture-all-items-added.patch rename to patches/unapplied/server/0410-Extend-block-drop-capture-to-capture-all-items-added.patch diff --git a/patches/unapplied/0411-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch b/patches/unapplied/server/0411-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch similarity index 100% rename from patches/unapplied/0411-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch rename to patches/unapplied/server/0411-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch diff --git a/patches/unapplied/0412-Lazily-track-plugin-scoreboards-by-default.patch b/patches/unapplied/server/0412-Lazily-track-plugin-scoreboards-by-default.patch similarity index 100% rename from patches/unapplied/0412-Lazily-track-plugin-scoreboards-by-default.patch rename to patches/unapplied/server/0412-Lazily-track-plugin-scoreboards-by-default.patch diff --git a/patches/unapplied/0413-Entity-isTicking.patch b/patches/unapplied/server/0413-Entity-isTicking.patch similarity index 100% rename from patches/unapplied/0413-Entity-isTicking.patch rename to patches/unapplied/server/0413-Entity-isTicking.patch diff --git a/patches/unapplied/0414-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch b/patches/unapplied/server/0414-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch similarity index 100% rename from patches/unapplied/0414-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch rename to patches/unapplied/server/0414-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch diff --git a/patches/unapplied/0415-Fix-Concurrency-issue-in-ShufflingList.patch b/patches/unapplied/server/0415-Fix-Concurrency-issue-in-ShufflingList.patch similarity index 100% rename from patches/unapplied/0415-Fix-Concurrency-issue-in-ShufflingList.patch rename to patches/unapplied/server/0415-Fix-Concurrency-issue-in-ShufflingList.patch diff --git a/patches/unapplied/0416-Reset-Ender-Crystals-on-Dragon-Spawn.patch b/patches/unapplied/server/0416-Reset-Ender-Crystals-on-Dragon-Spawn.patch similarity index 100% rename from patches/unapplied/0416-Reset-Ender-Crystals-on-Dragon-Spawn.patch rename to patches/unapplied/server/0416-Reset-Ender-Crystals-on-Dragon-Spawn.patch diff --git a/patches/unapplied/0417-Fix-for-large-move-vectors-crashing-server.patch b/patches/unapplied/server/0417-Fix-for-large-move-vectors-crashing-server.patch similarity index 100% rename from patches/unapplied/0417-Fix-for-large-move-vectors-crashing-server.patch rename to patches/unapplied/server/0417-Fix-for-large-move-vectors-crashing-server.patch diff --git a/patches/unapplied/0418-Optimise-getType-calls.patch b/patches/unapplied/server/0418-Optimise-getType-calls.patch similarity index 100% rename from patches/unapplied/0418-Optimise-getType-calls.patch rename to patches/unapplied/server/0418-Optimise-getType-calls.patch diff --git a/patches/unapplied/0419-Villager-resetOffers.patch b/patches/unapplied/server/0419-Villager-resetOffers.patch similarity index 100% rename from patches/unapplied/0419-Villager-resetOffers.patch rename to patches/unapplied/server/0419-Villager-resetOffers.patch diff --git a/patches/unapplied/0420-Retain-block-place-order-when-capturing-blockstates.patch b/patches/unapplied/server/0420-Retain-block-place-order-when-capturing-blockstates.patch similarity index 100% rename from patches/unapplied/0420-Retain-block-place-order-when-capturing-blockstates.patch rename to patches/unapplied/server/0420-Retain-block-place-order-when-capturing-blockstates.patch diff --git a/patches/unapplied/0421-Fix-item-locations-dropped-from-campfires.patch b/patches/unapplied/server/0421-Fix-item-locations-dropped-from-campfires.patch similarity index 100% rename from patches/unapplied/0421-Fix-item-locations-dropped-from-campfires.patch rename to patches/unapplied/server/0421-Fix-item-locations-dropped-from-campfires.patch diff --git a/patches/unapplied/0422-Fix-bell-block-entity-memory-leak.patch b/patches/unapplied/server/0422-Fix-bell-block-entity-memory-leak.patch similarity index 100% rename from patches/unapplied/0422-Fix-bell-block-entity-memory-leak.patch rename to patches/unapplied/server/0422-Fix-bell-block-entity-memory-leak.patch diff --git a/patches/unapplied/0423-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch b/patches/unapplied/server/0423-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch similarity index 100% rename from patches/unapplied/0423-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch rename to patches/unapplied/server/0423-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch diff --git a/patches/unapplied/0424-Add-getOfflinePlayerIfCached-String.patch b/patches/unapplied/server/0424-Add-getOfflinePlayerIfCached-String.patch similarity index 100% rename from patches/unapplied/0424-Add-getOfflinePlayerIfCached-String.patch rename to patches/unapplied/server/0424-Add-getOfflinePlayerIfCached-String.patch diff --git a/patches/unapplied/0425-Add-ignore-discounts-API.patch b/patches/unapplied/server/0425-Add-ignore-discounts-API.patch similarity index 100% rename from patches/unapplied/0425-Add-ignore-discounts-API.patch rename to patches/unapplied/server/0425-Add-ignore-discounts-API.patch diff --git a/patches/unapplied/0426-Toggle-for-removing-existing-dragon.patch b/patches/unapplied/server/0426-Toggle-for-removing-existing-dragon.patch similarity index 100% rename from patches/unapplied/0426-Toggle-for-removing-existing-dragon.patch rename to patches/unapplied/server/0426-Toggle-for-removing-existing-dragon.patch diff --git a/patches/unapplied/0427-Fix-client-lag-on-advancement-loading.patch b/patches/unapplied/server/0427-Fix-client-lag-on-advancement-loading.patch similarity index 100% rename from patches/unapplied/0427-Fix-client-lag-on-advancement-loading.patch rename to patches/unapplied/server/0427-Fix-client-lag-on-advancement-loading.patch diff --git a/patches/unapplied/0428-Item-no-age-no-player-pickup.patch b/patches/unapplied/server/0428-Item-no-age-no-player-pickup.patch similarity index 100% rename from patches/unapplied/0428-Item-no-age-no-player-pickup.patch rename to patches/unapplied/server/0428-Item-no-age-no-player-pickup.patch diff --git a/patches/unapplied/0429-Beacon-API-custom-effect-ranges.patch b/patches/unapplied/server/0429-Beacon-API-custom-effect-ranges.patch similarity index 100% rename from patches/unapplied/0429-Beacon-API-custom-effect-ranges.patch rename to patches/unapplied/server/0429-Beacon-API-custom-effect-ranges.patch diff --git a/patches/unapplied/0430-Add-API-for-quit-reason.patch b/patches/unapplied/server/0430-Add-API-for-quit-reason.patch similarity index 100% rename from patches/unapplied/0430-Add-API-for-quit-reason.patch rename to patches/unapplied/server/0430-Add-API-for-quit-reason.patch diff --git a/patches/unapplied/0431-Add-Wandering-Trader-spawn-rate-config-options.patch b/patches/unapplied/server/0431-Add-Wandering-Trader-spawn-rate-config-options.patch similarity index 100% rename from patches/unapplied/0431-Add-Wandering-Trader-spawn-rate-config-options.patch rename to patches/unapplied/server/0431-Add-Wandering-Trader-spawn-rate-config-options.patch diff --git a/patches/unapplied/0432-Add-Destroy-Speed-API.patch b/patches/unapplied/server/0432-Add-Destroy-Speed-API.patch similarity index 100% rename from patches/unapplied/0432-Add-Destroy-Speed-API.patch rename to patches/unapplied/server/0432-Add-Destroy-Speed-API.patch diff --git a/patches/unapplied/0433-Fix-Player-spawnParticle-x-y-z-precision-loss.patch b/patches/unapplied/server/0433-Fix-Player-spawnParticle-x-y-z-precision-loss.patch similarity index 100% rename from patches/unapplied/0433-Fix-Player-spawnParticle-x-y-z-precision-loss.patch rename to patches/unapplied/server/0433-Fix-Player-spawnParticle-x-y-z-precision-loss.patch diff --git a/patches/unapplied/0434-Add-LivingEntity-clearActiveItem.patch b/patches/unapplied/server/0434-Add-LivingEntity-clearActiveItem.patch similarity index 100% rename from patches/unapplied/0434-Add-LivingEntity-clearActiveItem.patch rename to patches/unapplied/server/0434-Add-LivingEntity-clearActiveItem.patch diff --git a/patches/unapplied/0435-Add-PlayerItemCooldownEvent.patch b/patches/unapplied/server/0435-Add-PlayerItemCooldownEvent.patch similarity index 100% rename from patches/unapplied/0435-Add-PlayerItemCooldownEvent.patch rename to patches/unapplied/server/0435-Add-PlayerItemCooldownEvent.patch diff --git a/patches/unapplied/0436-Significantly-improve-performance-of-the-end-generat.patch b/patches/unapplied/server/0436-Significantly-improve-performance-of-the-end-generat.patch similarity index 100% rename from patches/unapplied/0436-Significantly-improve-performance-of-the-end-generat.patch rename to patches/unapplied/server/0436-Significantly-improve-performance-of-the-end-generat.patch diff --git a/patches/unapplied/0437-More-lightning-API.patch b/patches/unapplied/server/0437-More-lightning-API.patch similarity index 100% rename from patches/unapplied/0437-More-lightning-API.patch rename to patches/unapplied/server/0437-More-lightning-API.patch diff --git a/patches/unapplied/0438-Climbing-should-not-bypass-cramming-gamerule.patch b/patches/unapplied/server/0438-Climbing-should-not-bypass-cramming-gamerule.patch similarity index 100% rename from patches/unapplied/0438-Climbing-should-not-bypass-cramming-gamerule.patch rename to patches/unapplied/server/0438-Climbing-should-not-bypass-cramming-gamerule.patch diff --git a/patches/unapplied/0439-Add-missing-default-perms-for-commands.patch b/patches/unapplied/server/0439-Add-missing-default-perms-for-commands.patch similarity index 100% rename from patches/unapplied/0439-Add-missing-default-perms-for-commands.patch rename to patches/unapplied/server/0439-Add-missing-default-perms-for-commands.patch diff --git a/patches/unapplied/0440-Add-PlayerShearBlockEvent.patch b/patches/unapplied/server/0440-Add-PlayerShearBlockEvent.patch similarity index 100% rename from patches/unapplied/0440-Add-PlayerShearBlockEvent.patch rename to patches/unapplied/server/0440-Add-PlayerShearBlockEvent.patch diff --git a/patches/unapplied/0441-Limit-recipe-packets.patch b/patches/unapplied/server/0441-Limit-recipe-packets.patch similarity index 100% rename from patches/unapplied/0441-Limit-recipe-packets.patch rename to patches/unapplied/server/0441-Limit-recipe-packets.patch diff --git a/patches/unapplied/0442-Fix-CraftSound-backwards-compatibility.patch b/patches/unapplied/server/0442-Fix-CraftSound-backwards-compatibility.patch similarity index 100% rename from patches/unapplied/0442-Fix-CraftSound-backwards-compatibility.patch rename to patches/unapplied/server/0442-Fix-CraftSound-backwards-compatibility.patch diff --git a/patches/unapplied/0443-Player-Chunk-Load-Unload-Events.patch b/patches/unapplied/server/0443-Player-Chunk-Load-Unload-Events.patch similarity index 100% rename from patches/unapplied/0443-Player-Chunk-Load-Unload-Events.patch rename to patches/unapplied/server/0443-Player-Chunk-Load-Unload-Events.patch diff --git a/patches/unapplied/0444-Optimize-Dynamic-get-Missing-Keys.patch b/patches/unapplied/server/0444-Optimize-Dynamic-get-Missing-Keys.patch similarity index 100% rename from patches/unapplied/0444-Optimize-Dynamic-get-Missing-Keys.patch rename to patches/unapplied/server/0444-Optimize-Dynamic-get-Missing-Keys.patch diff --git a/patches/unapplied/0445-Expose-LivingEntity-hurt-direction.patch b/patches/unapplied/server/0445-Expose-LivingEntity-hurt-direction.patch similarity index 100% rename from patches/unapplied/0445-Expose-LivingEntity-hurt-direction.patch rename to patches/unapplied/server/0445-Expose-LivingEntity-hurt-direction.patch diff --git a/patches/unapplied/0446-Add-OBSTRUCTED-reason-to-BedEnterResult.patch b/patches/unapplied/server/0446-Add-OBSTRUCTED-reason-to-BedEnterResult.patch similarity index 100% rename from patches/unapplied/0446-Add-OBSTRUCTED-reason-to-BedEnterResult.patch rename to patches/unapplied/server/0446-Add-OBSTRUCTED-reason-to-BedEnterResult.patch diff --git a/patches/unapplied/0447-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch b/patches/unapplied/server/0447-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch similarity index 100% rename from patches/unapplied/0447-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch rename to patches/unapplied/server/0447-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch diff --git a/patches/unapplied/0448-Add-TargetHitEvent.patch b/patches/unapplied/server/0448-Add-TargetHitEvent.patch similarity index 100% rename from patches/unapplied/0448-Add-TargetHitEvent.patch rename to patches/unapplied/server/0448-Add-TargetHitEvent.patch diff --git a/patches/unapplied/0449-MC-4-Fix-item-position-desync.patch b/patches/unapplied/server/0449-MC-4-Fix-item-position-desync.patch similarity index 100% rename from patches/unapplied/0449-MC-4-Fix-item-position-desync.patch rename to patches/unapplied/server/0449-MC-4-Fix-item-position-desync.patch diff --git a/patches/unapplied/0450-Additional-Block-Material-API.patch b/patches/unapplied/server/0450-Additional-Block-Material-API.patch similarity index 100% rename from patches/unapplied/0450-Additional-Block-Material-API.patch rename to patches/unapplied/server/0450-Additional-Block-Material-API.patch diff --git a/patches/unapplied/0451-Fix-harming-potion-dupe.patch b/patches/unapplied/server/0451-Fix-harming-potion-dupe.patch similarity index 100% rename from patches/unapplied/0451-Fix-harming-potion-dupe.patch rename to patches/unapplied/server/0451-Fix-harming-potion-dupe.patch diff --git a/patches/unapplied/0452-API-to-get-Material-from-Boats-and-Minecarts.patch b/patches/unapplied/server/0452-API-to-get-Material-from-Boats-and-Minecarts.patch similarity index 100% rename from patches/unapplied/0452-API-to-get-Material-from-Boats-and-Minecarts.patch rename to patches/unapplied/server/0452-API-to-get-Material-from-Boats-and-Minecarts.patch diff --git a/patches/unapplied/0453-Allow-disabling-mob-spawner-spawn-egg-transformation.patch b/patches/unapplied/server/0453-Allow-disabling-mob-spawner-spawn-egg-transformation.patch similarity index 100% rename from patches/unapplied/0453-Allow-disabling-mob-spawner-spawn-egg-transformation.patch rename to patches/unapplied/server/0453-Allow-disabling-mob-spawner-spawn-egg-transformation.patch diff --git a/patches/unapplied/0454-Fix-Not-a-string-Map-Conversion-spam.patch b/patches/unapplied/server/0454-Fix-Not-a-string-Map-Conversion-spam.patch similarity index 100% rename from patches/unapplied/0454-Fix-Not-a-string-Map-Conversion-spam.patch rename to patches/unapplied/server/0454-Fix-Not-a-string-Map-Conversion-spam.patch diff --git a/patches/unapplied/0455-Add-PlayerFlowerPotManipulateEvent.patch b/patches/unapplied/server/0455-Add-PlayerFlowerPotManipulateEvent.patch similarity index 100% rename from patches/unapplied/0455-Add-PlayerFlowerPotManipulateEvent.patch rename to patches/unapplied/server/0455-Add-PlayerFlowerPotManipulateEvent.patch diff --git a/patches/unapplied/0456-Fix-interact-event-not-being-called-sometimes.patch b/patches/unapplied/server/0456-Fix-interact-event-not-being-called-sometimes.patch similarity index 100% rename from patches/unapplied/0456-Fix-interact-event-not-being-called-sometimes.patch rename to patches/unapplied/server/0456-Fix-interact-event-not-being-called-sometimes.patch diff --git a/patches/unapplied/0457-Zombie-API-breaking-doors.patch b/patches/unapplied/server/0457-Zombie-API-breaking-doors.patch similarity index 100% rename from patches/unapplied/0457-Zombie-API-breaking-doors.patch rename to patches/unapplied/server/0457-Zombie-API-breaking-doors.patch diff --git a/patches/unapplied/0458-Fix-nerfed-slime-when-splitting.patch b/patches/unapplied/server/0458-Fix-nerfed-slime-when-splitting.patch similarity index 100% rename from patches/unapplied/0458-Fix-nerfed-slime-when-splitting.patch rename to patches/unapplied/server/0458-Fix-nerfed-slime-when-splitting.patch diff --git a/patches/unapplied/0459-Add-EntityLoadCrossbowEvent.patch b/patches/unapplied/server/0459-Add-EntityLoadCrossbowEvent.patch similarity index 100% rename from patches/unapplied/0459-Add-EntityLoadCrossbowEvent.patch rename to patches/unapplied/server/0459-Add-EntityLoadCrossbowEvent.patch diff --git a/patches/unapplied/0460-Add-WorldGameRuleChangeEvent.patch b/patches/unapplied/server/0460-Add-WorldGameRuleChangeEvent.patch similarity index 100% rename from patches/unapplied/0460-Add-WorldGameRuleChangeEvent.patch rename to patches/unapplied/server/0460-Add-WorldGameRuleChangeEvent.patch diff --git a/patches/unapplied/0461-Add-ServerResourcesReloadedEvent.patch b/patches/unapplied/server/0461-Add-ServerResourcesReloadedEvent.patch similarity index 100% rename from patches/unapplied/0461-Add-ServerResourcesReloadedEvent.patch rename to patches/unapplied/server/0461-Add-ServerResourcesReloadedEvent.patch diff --git a/patches/unapplied/0462-Add-world-settings-for-mobs-picking-up-loot.patch b/patches/unapplied/server/0462-Add-world-settings-for-mobs-picking-up-loot.patch similarity index 100% rename from patches/unapplied/0462-Add-world-settings-for-mobs-picking-up-loot.patch rename to patches/unapplied/server/0462-Add-world-settings-for-mobs-picking-up-loot.patch diff --git a/patches/unapplied/0463-Add-BlockFailedDispenseEvent.patch b/patches/unapplied/server/0463-Add-BlockFailedDispenseEvent.patch similarity index 100% rename from patches/unapplied/0463-Add-BlockFailedDispenseEvent.patch rename to patches/unapplied/server/0463-Add-BlockFailedDispenseEvent.patch diff --git a/patches/unapplied/0464-Add-PlayerLecternPageChangeEvent.patch b/patches/unapplied/server/0464-Add-PlayerLecternPageChangeEvent.patch similarity index 100% rename from patches/unapplied/0464-Add-PlayerLecternPageChangeEvent.patch rename to patches/unapplied/server/0464-Add-PlayerLecternPageChangeEvent.patch diff --git a/patches/unapplied/0465-Add-PlayerLoomPatternSelectEvent.patch b/patches/unapplied/server/0465-Add-PlayerLoomPatternSelectEvent.patch similarity index 100% rename from patches/unapplied/0465-Add-PlayerLoomPatternSelectEvent.patch rename to patches/unapplied/server/0465-Add-PlayerLoomPatternSelectEvent.patch diff --git a/patches/unapplied/0466-Configurable-door-breaking-difficulty.patch b/patches/unapplied/server/0466-Configurable-door-breaking-difficulty.patch similarity index 100% rename from patches/unapplied/0466-Configurable-door-breaking-difficulty.patch rename to patches/unapplied/server/0466-Configurable-door-breaking-difficulty.patch diff --git a/patches/unapplied/0467-Empty-commands-shall-not-be-dispatched.patch b/patches/unapplied/server/0467-Empty-commands-shall-not-be-dispatched.patch similarity index 100% rename from patches/unapplied/0467-Empty-commands-shall-not-be-dispatched.patch rename to patches/unapplied/server/0467-Empty-commands-shall-not-be-dispatched.patch diff --git a/patches/unapplied/0468-Remove-stale-POIs.patch b/patches/unapplied/server/0468-Remove-stale-POIs.patch similarity index 100% rename from patches/unapplied/0468-Remove-stale-POIs.patch rename to patches/unapplied/server/0468-Remove-stale-POIs.patch diff --git a/patches/unapplied/0469-Fix-villager-boat-exploit.patch b/patches/unapplied/server/0469-Fix-villager-boat-exploit.patch similarity index 100% rename from patches/unapplied/0469-Fix-villager-boat-exploit.patch rename to patches/unapplied/server/0469-Fix-villager-boat-exploit.patch diff --git a/patches/unapplied/0470-Add-sendOpLevel-API.patch b/patches/unapplied/server/0470-Add-sendOpLevel-API.patch similarity index 100% rename from patches/unapplied/0470-Add-sendOpLevel-API.patch rename to patches/unapplied/server/0470-Add-sendOpLevel-API.patch diff --git a/patches/unapplied/0471-Add-RegistryAccess-for-managing-Registries.patch b/patches/unapplied/server/0471-Add-RegistryAccess-for-managing-Registries.patch similarity index 100% rename from patches/unapplied/0471-Add-RegistryAccess-for-managing-Registries.patch rename to patches/unapplied/server/0471-Add-RegistryAccess-for-managing-Registries.patch diff --git a/patches/unapplied/0472-Add-StructuresLocateEvent.patch b/patches/unapplied/server/0472-Add-StructuresLocateEvent.patch similarity index 100% rename from patches/unapplied/0472-Add-StructuresLocateEvent.patch rename to patches/unapplied/server/0472-Add-StructuresLocateEvent.patch diff --git a/patches/unapplied/0473-Collision-option-for-requiring-a-player-participant.patch b/patches/unapplied/server/0473-Collision-option-for-requiring-a-player-participant.patch similarity index 100% rename from patches/unapplied/0473-Collision-option-for-requiring-a-player-participant.patch rename to patches/unapplied/server/0473-Collision-option-for-requiring-a-player-participant.patch diff --git a/patches/unapplied/0474-Return-chat-component-with-empty-text-instead-of-thr.patch b/patches/unapplied/server/0474-Return-chat-component-with-empty-text-instead-of-thr.patch similarity index 100% rename from patches/unapplied/0474-Return-chat-component-with-empty-text-instead-of-thr.patch rename to patches/unapplied/server/0474-Return-chat-component-with-empty-text-instead-of-thr.patch diff --git a/patches/unapplied/0475-Make-schedule-command-per-world.patch b/patches/unapplied/server/0475-Make-schedule-command-per-world.patch similarity index 100% rename from patches/unapplied/0475-Make-schedule-command-per-world.patch rename to patches/unapplied/server/0475-Make-schedule-command-per-world.patch diff --git a/patches/unapplied/0476-Configurable-max-leash-distance.patch b/patches/unapplied/server/0476-Configurable-max-leash-distance.patch similarity index 100% rename from patches/unapplied/0476-Configurable-max-leash-distance.patch rename to patches/unapplied/server/0476-Configurable-max-leash-distance.patch diff --git a/patches/unapplied/0477-Add-BlockPreDispenseEvent.patch b/patches/unapplied/server/0477-Add-BlockPreDispenseEvent.patch similarity index 100% rename from patches/unapplied/0477-Add-BlockPreDispenseEvent.patch rename to patches/unapplied/server/0477-Add-BlockPreDispenseEvent.patch diff --git a/patches/unapplied/0478-Add-PlayerChangeBeaconEffectEvent.patch b/patches/unapplied/server/0478-Add-PlayerChangeBeaconEffectEvent.patch similarity index 100% rename from patches/unapplied/0478-Add-PlayerChangeBeaconEffectEvent.patch rename to patches/unapplied/server/0478-Add-PlayerChangeBeaconEffectEvent.patch diff --git a/patches/unapplied/0479-Add-toggle-for-always-placing-the-dragon-egg.patch b/patches/unapplied/server/0479-Add-toggle-for-always-placing-the-dragon-egg.patch similarity index 100% rename from patches/unapplied/0479-Add-toggle-for-always-placing-the-dragon-egg.patch rename to patches/unapplied/server/0479-Add-toggle-for-always-placing-the-dragon-egg.patch diff --git a/patches/unapplied/0480-Add-PlayerStonecutterRecipeSelectEvent.patch b/patches/unapplied/server/0480-Add-PlayerStonecutterRecipeSelectEvent.patch similarity index 100% rename from patches/unapplied/0480-Add-PlayerStonecutterRecipeSelectEvent.patch rename to patches/unapplied/server/0480-Add-PlayerStonecutterRecipeSelectEvent.patch diff --git a/patches/unapplied/0481-Expand-EntityUnleashEvent.patch b/patches/unapplied/server/0481-Expand-EntityUnleashEvent.patch similarity index 100% rename from patches/unapplied/0481-Expand-EntityUnleashEvent.patch rename to patches/unapplied/server/0481-Expand-EntityUnleashEvent.patch diff --git a/patches/unapplied/0482-Reset-shield-blocking-on-dimension-change.patch b/patches/unapplied/server/0482-Reset-shield-blocking-on-dimension-change.patch similarity index 100% rename from patches/unapplied/0482-Reset-shield-blocking-on-dimension-change.patch rename to patches/unapplied/server/0482-Reset-shield-blocking-on-dimension-change.patch diff --git a/patches/unapplied/0483-Add-DragonEggFormEvent.patch b/patches/unapplied/server/0483-Add-DragonEggFormEvent.patch similarity index 100% rename from patches/unapplied/0483-Add-DragonEggFormEvent.patch rename to patches/unapplied/server/0483-Add-DragonEggFormEvent.patch diff --git a/patches/unapplied/0484-Add-EntityMoveEvent.patch b/patches/unapplied/server/0484-Add-EntityMoveEvent.patch similarity index 100% rename from patches/unapplied/0484-Add-EntityMoveEvent.patch rename to patches/unapplied/server/0484-Add-EntityMoveEvent.patch diff --git a/patches/unapplied/0485-added-option-to-disable-pathfinding-updates-on-block.patch b/patches/unapplied/server/0485-added-option-to-disable-pathfinding-updates-on-block.patch similarity index 100% rename from patches/unapplied/0485-added-option-to-disable-pathfinding-updates-on-block.patch rename to patches/unapplied/server/0485-added-option-to-disable-pathfinding-updates-on-block.patch diff --git a/patches/unapplied/0486-Inline-shift-direction-fields.patch b/patches/unapplied/server/0486-Inline-shift-direction-fields.patch similarity index 100% rename from patches/unapplied/0486-Inline-shift-direction-fields.patch rename to patches/unapplied/server/0486-Inline-shift-direction-fields.patch diff --git a/patches/unapplied/0487-Allow-adding-items-to-BlockDropItemEvent.patch b/patches/unapplied/server/0487-Allow-adding-items-to-BlockDropItemEvent.patch similarity index 100% rename from patches/unapplied/0487-Allow-adding-items-to-BlockDropItemEvent.patch rename to patches/unapplied/server/0487-Allow-adding-items-to-BlockDropItemEvent.patch diff --git a/patches/unapplied/0488-Add-getMainThreadExecutor-to-BukkitScheduler.patch b/patches/unapplied/server/0488-Add-getMainThreadExecutor-to-BukkitScheduler.patch similarity index 100% rename from patches/unapplied/0488-Add-getMainThreadExecutor-to-BukkitScheduler.patch rename to patches/unapplied/server/0488-Add-getMainThreadExecutor-to-BukkitScheduler.patch diff --git a/patches/unapplied/0489-living-entity-allow-attribute-registration.patch b/patches/unapplied/server/0489-living-entity-allow-attribute-registration.patch similarity index 100% rename from patches/unapplied/0489-living-entity-allow-attribute-registration.patch rename to patches/unapplied/server/0489-living-entity-allow-attribute-registration.patch diff --git a/patches/unapplied/0490-fix-dead-slime-setSize-invincibility.patch b/patches/unapplied/server/0490-fix-dead-slime-setSize-invincibility.patch similarity index 100% rename from patches/unapplied/0490-fix-dead-slime-setSize-invincibility.patch rename to patches/unapplied/server/0490-fix-dead-slime-setSize-invincibility.patch diff --git a/patches/unapplied/0491-Merchant-getRecipes-should-return-an-immutable-list.patch b/patches/unapplied/server/0491-Merchant-getRecipes-should-return-an-immutable-list.patch similarity index 100% rename from patches/unapplied/0491-Merchant-getRecipes-should-return-an-immutable-list.patch rename to patches/unapplied/server/0491-Merchant-getRecipes-should-return-an-immutable-list.patch diff --git a/patches/unapplied/0492-Expose-Tracked-Players.patch b/patches/unapplied/server/0492-Expose-Tracked-Players.patch similarity index 100% rename from patches/unapplied/0492-Expose-Tracked-Players.patch rename to patches/unapplied/server/0492-Expose-Tracked-Players.patch diff --git a/patches/unapplied/0493-Improve-ServerGUI.patch b/patches/unapplied/server/0493-Improve-ServerGUI.patch similarity index 100% rename from patches/unapplied/0493-Improve-ServerGUI.patch rename to patches/unapplied/server/0493-Improve-ServerGUI.patch diff --git a/patches/unapplied/0494-fix-converting-txt-to-json-file.patch b/patches/unapplied/server/0494-fix-converting-txt-to-json-file.patch similarity index 100% rename from patches/unapplied/0494-fix-converting-txt-to-json-file.patch rename to patches/unapplied/server/0494-fix-converting-txt-to-json-file.patch diff --git a/patches/unapplied/0495-Add-worldborder-events.patch b/patches/unapplied/server/0495-Add-worldborder-events.patch similarity index 100% rename from patches/unapplied/0495-Add-worldborder-events.patch rename to patches/unapplied/server/0495-Add-worldborder-events.patch diff --git a/patches/unapplied/0496-Add-PlayerNameEntityEvent.patch b/patches/unapplied/server/0496-Add-PlayerNameEntityEvent.patch similarity index 100% rename from patches/unapplied/0496-Add-PlayerNameEntityEvent.patch rename to patches/unapplied/server/0496-Add-PlayerNameEntityEvent.patch diff --git a/patches/unapplied/0497-Add-recipe-to-cook-events.patch b/patches/unapplied/server/0497-Add-recipe-to-cook-events.patch similarity index 100% rename from patches/unapplied/0497-Add-recipe-to-cook-events.patch rename to patches/unapplied/server/0497-Add-recipe-to-cook-events.patch diff --git a/patches/unapplied/0498-Add-Block-isValidTool.patch b/patches/unapplied/server/0498-Add-Block-isValidTool.patch similarity index 100% rename from patches/unapplied/0498-Add-Block-isValidTool.patch rename to patches/unapplied/server/0498-Add-Block-isValidTool.patch diff --git a/patches/unapplied/0499-Allow-using-signs-inside-spawn-protection.patch b/patches/unapplied/server/0499-Allow-using-signs-inside-spawn-protection.patch similarity index 100% rename from patches/unapplied/0499-Allow-using-signs-inside-spawn-protection.patch rename to patches/unapplied/server/0499-Allow-using-signs-inside-spawn-protection.patch diff --git a/patches/unapplied/0500-Expand-world-key-API.patch b/patches/unapplied/server/0500-Expand-world-key-API.patch similarity index 100% rename from patches/unapplied/0500-Expand-world-key-API.patch rename to patches/unapplied/server/0500-Expand-world-key-API.patch diff --git a/patches/unapplied/0501-Add-fast-alternative-constructor-for-Rotations.patch b/patches/unapplied/server/0501-Add-fast-alternative-constructor-for-Rotations.patch similarity index 100% rename from patches/unapplied/0501-Add-fast-alternative-constructor-for-Rotations.patch rename to patches/unapplied/server/0501-Add-fast-alternative-constructor-for-Rotations.patch diff --git a/patches/unapplied/0502-Drop-carried-item-when-player-has-disconnected.patch b/patches/unapplied/server/0502-Drop-carried-item-when-player-has-disconnected.patch similarity index 100% rename from patches/unapplied/0502-Drop-carried-item-when-player-has-disconnected.patch rename to patches/unapplied/server/0502-Drop-carried-item-when-player-has-disconnected.patch diff --git a/patches/unapplied/0503-forced-whitelist-use-configurable-kick-message.patch b/patches/unapplied/server/0503-forced-whitelist-use-configurable-kick-message.patch similarity index 100% rename from patches/unapplied/0503-forced-whitelist-use-configurable-kick-message.patch rename to patches/unapplied/server/0503-forced-whitelist-use-configurable-kick-message.patch diff --git a/patches/unapplied/0504-Don-t-ignore-result-of-PlayerEditBookEvent.patch b/patches/unapplied/server/0504-Don-t-ignore-result-of-PlayerEditBookEvent.patch similarity index 100% rename from patches/unapplied/0504-Don-t-ignore-result-of-PlayerEditBookEvent.patch rename to patches/unapplied/server/0504-Don-t-ignore-result-of-PlayerEditBookEvent.patch diff --git a/patches/unapplied/0505-Expose-protocol-version.patch b/patches/unapplied/server/0505-Expose-protocol-version.patch similarity index 100% rename from patches/unapplied/0505-Expose-protocol-version.patch rename to patches/unapplied/server/0505-Expose-protocol-version.patch diff --git a/patches/unapplied/0506-Enhance-console-tab-completions-for-brigadier-comman.patch b/patches/unapplied/server/0506-Enhance-console-tab-completions-for-brigadier-comman.patch similarity index 100% rename from patches/unapplied/0506-Enhance-console-tab-completions-for-brigadier-comman.patch rename to patches/unapplied/server/0506-Enhance-console-tab-completions-for-brigadier-comman.patch diff --git a/patches/unapplied/0507-Fix-PlayerItemConsumeEvent-cancelling-properly.patch b/patches/unapplied/server/0507-Fix-PlayerItemConsumeEvent-cancelling-properly.patch similarity index 100% rename from patches/unapplied/0507-Fix-PlayerItemConsumeEvent-cancelling-properly.patch rename to patches/unapplied/server/0507-Fix-PlayerItemConsumeEvent-cancelling-properly.patch diff --git a/patches/unapplied/0508-Add-bypass-host-check.patch b/patches/unapplied/server/0508-Add-bypass-host-check.patch similarity index 100% rename from patches/unapplied/0508-Add-bypass-host-check.patch rename to patches/unapplied/server/0508-Add-bypass-host-check.patch diff --git a/patches/unapplied/0509-Set-area-affect-cloud-rotation.patch b/patches/unapplied/server/0509-Set-area-affect-cloud-rotation.patch similarity index 100% rename from patches/unapplied/0509-Set-area-affect-cloud-rotation.patch rename to patches/unapplied/server/0509-Set-area-affect-cloud-rotation.patch diff --git a/patches/unapplied/0510-add-isDeeplySleeping-to-HumanEntity.patch b/patches/unapplied/server/0510-add-isDeeplySleeping-to-HumanEntity.patch similarity index 100% rename from patches/unapplied/0510-add-isDeeplySleeping-to-HumanEntity.patch rename to patches/unapplied/server/0510-add-isDeeplySleeping-to-HumanEntity.patch diff --git a/patches/unapplied/0511-add-consumeFuel-to-FurnaceBurnEvent.patch b/patches/unapplied/server/0511-add-consumeFuel-to-FurnaceBurnEvent.patch similarity index 100% rename from patches/unapplied/0511-add-consumeFuel-to-FurnaceBurnEvent.patch rename to patches/unapplied/server/0511-add-consumeFuel-to-FurnaceBurnEvent.patch diff --git a/patches/unapplied/0512-add-get-set-drop-chance-to-EntityEquipment.patch b/patches/unapplied/server/0512-add-get-set-drop-chance-to-EntityEquipment.patch similarity index 100% rename from patches/unapplied/0512-add-get-set-drop-chance-to-EntityEquipment.patch rename to patches/unapplied/server/0512-add-get-set-drop-chance-to-EntityEquipment.patch diff --git a/patches/unapplied/0513-fix-PigZombieAngerEvent-cancellation.patch b/patches/unapplied/server/0513-fix-PigZombieAngerEvent-cancellation.patch similarity index 100% rename from patches/unapplied/0513-fix-PigZombieAngerEvent-cancellation.patch rename to patches/unapplied/server/0513-fix-PigZombieAngerEvent-cancellation.patch diff --git a/patches/unapplied/0514-fix-PlayerItemHeldEvent-firing-twice.patch b/patches/unapplied/server/0514-fix-PlayerItemHeldEvent-firing-twice.patch similarity index 100% rename from patches/unapplied/0514-fix-PlayerItemHeldEvent-firing-twice.patch rename to patches/unapplied/server/0514-fix-PlayerItemHeldEvent-firing-twice.patch diff --git a/patches/unapplied/0515-Add-PlayerDeepSleepEvent.patch b/patches/unapplied/server/0515-Add-PlayerDeepSleepEvent.patch similarity index 100% rename from patches/unapplied/0515-Add-PlayerDeepSleepEvent.patch rename to patches/unapplied/server/0515-Add-PlayerDeepSleepEvent.patch diff --git a/patches/unapplied/0516-More-World-API.patch b/patches/unapplied/server/0516-More-World-API.patch similarity index 100% rename from patches/unapplied/0516-More-World-API.patch rename to patches/unapplied/server/0516-More-World-API.patch diff --git a/patches/unapplied/0517-Add-PlayerBedFailEnterEvent.patch b/patches/unapplied/server/0517-Add-PlayerBedFailEnterEvent.patch similarity index 100% rename from patches/unapplied/0517-Add-PlayerBedFailEnterEvent.patch rename to patches/unapplied/server/0517-Add-PlayerBedFailEnterEvent.patch diff --git a/patches/unapplied/0518-Implement-methods-to-convert-between-Component-and-B.patch b/patches/unapplied/server/0518-Implement-methods-to-convert-between-Component-and-B.patch similarity index 100% rename from patches/unapplied/0518-Implement-methods-to-convert-between-Component-and-B.patch rename to patches/unapplied/server/0518-Implement-methods-to-convert-between-Component-and-B.patch diff --git a/patches/unapplied/0519-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch b/patches/unapplied/server/0519-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch similarity index 100% rename from patches/unapplied/0519-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch rename to patches/unapplied/server/0519-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch diff --git a/patches/unapplied/0520-Introduce-beacon-activation-deactivation-events.patch b/patches/unapplied/server/0520-Introduce-beacon-activation-deactivation-events.patch similarity index 100% rename from patches/unapplied/0520-Introduce-beacon-activation-deactivation-events.patch rename to patches/unapplied/server/0520-Introduce-beacon-activation-deactivation-events.patch diff --git a/patches/unapplied/0521-Add-Channel-initialization-listeners.patch b/patches/unapplied/server/0521-Add-Channel-initialization-listeners.patch similarity index 100% rename from patches/unapplied/0521-Add-Channel-initialization-listeners.patch rename to patches/unapplied/server/0521-Add-Channel-initialization-listeners.patch diff --git a/patches/unapplied/0522-Send-empty-commands-if-tab-completion-is-disabled.patch b/patches/unapplied/server/0522-Send-empty-commands-if-tab-completion-is-disabled.patch similarity index 100% rename from patches/unapplied/0522-Send-empty-commands-if-tab-completion-is-disabled.patch rename to patches/unapplied/server/0522-Send-empty-commands-if-tab-completion-is-disabled.patch diff --git a/patches/unapplied/0523-Add-more-WanderingTrader-API.patch b/patches/unapplied/server/0523-Add-more-WanderingTrader-API.patch similarity index 100% rename from patches/unapplied/0523-Add-more-WanderingTrader-API.patch rename to patches/unapplied/server/0523-Add-more-WanderingTrader-API.patch diff --git a/patches/unapplied/0524-Add-EntityBlockStorage-clearEntities.patch b/patches/unapplied/server/0524-Add-EntityBlockStorage-clearEntities.patch similarity index 100% rename from patches/unapplied/0524-Add-EntityBlockStorage-clearEntities.patch rename to patches/unapplied/server/0524-Add-EntityBlockStorage-clearEntities.patch diff --git a/patches/unapplied/0525-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch b/patches/unapplied/server/0525-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch similarity index 100% rename from patches/unapplied/0525-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch rename to patches/unapplied/server/0525-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch diff --git a/patches/unapplied/0526-Add-HiddenPotionEffect-API.patch b/patches/unapplied/server/0526-Add-HiddenPotionEffect-API.patch similarity index 100% rename from patches/unapplied/0526-Add-HiddenPotionEffect-API.patch rename to patches/unapplied/server/0526-Add-HiddenPotionEffect-API.patch diff --git a/patches/unapplied/0527-Inventory-close.patch b/patches/unapplied/server/0527-Inventory-close.patch similarity index 100% rename from patches/unapplied/0527-Inventory-close.patch rename to patches/unapplied/server/0527-Inventory-close.patch diff --git a/patches/unapplied/0528-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch b/patches/unapplied/server/0528-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch similarity index 100% rename from patches/unapplied/0528-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch rename to patches/unapplied/server/0528-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch diff --git a/patches/unapplied/0529-Add-basic-Datapack-API.patch b/patches/unapplied/server/0529-Add-basic-Datapack-API.patch similarity index 100% rename from patches/unapplied/0529-Add-basic-Datapack-API.patch rename to patches/unapplied/server/0529-Add-basic-Datapack-API.patch diff --git a/patches/unapplied/0530-Add-environment-variable-to-disable-server-gui.patch b/patches/unapplied/server/0530-Add-environment-variable-to-disable-server-gui.patch similarity index 100% rename from patches/unapplied/0530-Add-environment-variable-to-disable-server-gui.patch rename to patches/unapplied/server/0530-Add-environment-variable-to-disable-server-gui.patch diff --git a/patches/unapplied/0531-Expand-PlayerGameModeChangeEvent.patch b/patches/unapplied/server/0531-Expand-PlayerGameModeChangeEvent.patch similarity index 100% rename from patches/unapplied/0531-Expand-PlayerGameModeChangeEvent.patch rename to patches/unapplied/server/0531-Expand-PlayerGameModeChangeEvent.patch diff --git a/patches/unapplied/0532-ItemStack-repair-check-API.patch b/patches/unapplied/server/0532-ItemStack-repair-check-API.patch similarity index 100% rename from patches/unapplied/0532-ItemStack-repair-check-API.patch rename to patches/unapplied/server/0532-ItemStack-repair-check-API.patch diff --git a/patches/unapplied/0533-More-Enchantment-API.patch b/patches/unapplied/server/0533-More-Enchantment-API.patch similarity index 100% rename from patches/unapplied/0533-More-Enchantment-API.patch rename to patches/unapplied/server/0533-More-Enchantment-API.patch diff --git a/patches/unapplied/0534-Move-range-check-for-block-placing-up.patch b/patches/unapplied/server/0534-Move-range-check-for-block-placing-up.patch similarity index 100% rename from patches/unapplied/0534-Move-range-check-for-block-placing-up.patch rename to patches/unapplied/server/0534-Move-range-check-for-block-placing-up.patch diff --git a/patches/unapplied/0535-Add-Mob-lookAt-API.patch b/patches/unapplied/server/0535-Add-Mob-lookAt-API.patch similarity index 100% rename from patches/unapplied/0535-Add-Mob-lookAt-API.patch rename to patches/unapplied/server/0535-Add-Mob-lookAt-API.patch diff --git a/patches/unapplied/0536-Correctly-check-if-bucket-dispenses-will-succeed-for.patch b/patches/unapplied/server/0536-Correctly-check-if-bucket-dispenses-will-succeed-for.patch similarity index 100% rename from patches/unapplied/0536-Correctly-check-if-bucket-dispenses-will-succeed-for.patch rename to patches/unapplied/server/0536-Correctly-check-if-bucket-dispenses-will-succeed-for.patch diff --git a/patches/unapplied/0537-Add-Unix-domain-socket-support.patch b/patches/unapplied/server/0537-Add-Unix-domain-socket-support.patch similarity index 100% rename from patches/unapplied/0537-Add-Unix-domain-socket-support.patch rename to patches/unapplied/server/0537-Add-Unix-domain-socket-support.patch diff --git a/patches/unapplied/0538-Add-EntityInsideBlockEvent.patch b/patches/unapplied/server/0538-Add-EntityInsideBlockEvent.patch similarity index 100% rename from patches/unapplied/0538-Add-EntityInsideBlockEvent.patch rename to patches/unapplied/server/0538-Add-EntityInsideBlockEvent.patch diff --git a/patches/unapplied/0539-Improve-item-default-attribute-API.patch b/patches/unapplied/server/0539-Improve-item-default-attribute-API.patch similarity index 100% rename from patches/unapplied/0539-Improve-item-default-attribute-API.patch rename to patches/unapplied/server/0539-Improve-item-default-attribute-API.patch diff --git a/patches/unapplied/0540-Add-cause-to-Weather-ThunderChangeEvents.patch b/patches/unapplied/server/0540-Add-cause-to-Weather-ThunderChangeEvents.patch similarity index 100% rename from patches/unapplied/0540-Add-cause-to-Weather-ThunderChangeEvents.patch rename to patches/unapplied/server/0540-Add-cause-to-Weather-ThunderChangeEvents.patch diff --git a/patches/unapplied/0541-More-Lidded-Block-API.patch b/patches/unapplied/server/0541-More-Lidded-Block-API.patch similarity index 100% rename from patches/unapplied/0541-More-Lidded-Block-API.patch rename to patches/unapplied/server/0541-More-Lidded-Block-API.patch diff --git a/patches/unapplied/0542-Limit-item-frame-cursors-on-maps.patch b/patches/unapplied/server/0542-Limit-item-frame-cursors-on-maps.patch similarity index 100% rename from patches/unapplied/0542-Limit-item-frame-cursors-on-maps.patch rename to patches/unapplied/server/0542-Limit-item-frame-cursors-on-maps.patch diff --git a/patches/unapplied/0543-Add-PlayerKickEvent-causes.patch b/patches/unapplied/server/0543-Add-PlayerKickEvent-causes.patch similarity index 100% rename from patches/unapplied/0543-Add-PlayerKickEvent-causes.patch rename to patches/unapplied/server/0543-Add-PlayerKickEvent-causes.patch diff --git a/patches/unapplied/0544-Add-PufferFishStateChangeEvent.patch b/patches/unapplied/server/0544-Add-PufferFishStateChangeEvent.patch similarity index 100% rename from patches/unapplied/0544-Add-PufferFishStateChangeEvent.patch rename to patches/unapplied/server/0544-Add-PufferFishStateChangeEvent.patch diff --git a/patches/unapplied/0545-Fix-PlayerBucketEmptyEvent-result-itemstack.patch b/patches/unapplied/server/0545-Fix-PlayerBucketEmptyEvent-result-itemstack.patch similarity index 100% rename from patches/unapplied/0545-Fix-PlayerBucketEmptyEvent-result-itemstack.patch rename to patches/unapplied/server/0545-Fix-PlayerBucketEmptyEvent-result-itemstack.patch diff --git a/patches/unapplied/0546-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch b/patches/unapplied/server/0546-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch similarity index 100% rename from patches/unapplied/0546-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch rename to patches/unapplied/server/0546-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch diff --git a/patches/unapplied/0547-Add-option-to-fix-items-merging-through-walls.patch b/patches/unapplied/server/0547-Add-option-to-fix-items-merging-through-walls.patch similarity index 100% rename from patches/unapplied/0547-Add-option-to-fix-items-merging-through-walls.patch rename to patches/unapplied/server/0547-Add-option-to-fix-items-merging-through-walls.patch diff --git a/patches/unapplied/0548-Add-BellRevealRaiderEvent.patch b/patches/unapplied/server/0548-Add-BellRevealRaiderEvent.patch similarity index 100% rename from patches/unapplied/0548-Add-BellRevealRaiderEvent.patch rename to patches/unapplied/server/0548-Add-BellRevealRaiderEvent.patch diff --git a/patches/unapplied/0549-Fix-invulnerable-end-crystals.patch b/patches/unapplied/server/0549-Fix-invulnerable-end-crystals.patch similarity index 100% rename from patches/unapplied/0549-Fix-invulnerable-end-crystals.patch rename to patches/unapplied/server/0549-Fix-invulnerable-end-crystals.patch diff --git a/patches/unapplied/0550-Add-ElderGuardianAppearanceEvent.patch b/patches/unapplied/server/0550-Add-ElderGuardianAppearanceEvent.patch similarity index 100% rename from patches/unapplied/0550-Add-ElderGuardianAppearanceEvent.patch rename to patches/unapplied/server/0550-Add-ElderGuardianAppearanceEvent.patch diff --git a/patches/unapplied/0551-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch b/patches/unapplied/server/0551-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch similarity index 100% rename from patches/unapplied/0551-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch rename to patches/unapplied/server/0551-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch diff --git a/patches/unapplied/0552-Line-Of-Sight-Changes.patch b/patches/unapplied/server/0552-Line-Of-Sight-Changes.patch similarity index 100% rename from patches/unapplied/0552-Line-Of-Sight-Changes.patch rename to patches/unapplied/server/0552-Line-Of-Sight-Changes.patch diff --git a/patches/unapplied/0553-add-per-world-spawn-limits.patch b/patches/unapplied/server/0553-add-per-world-spawn-limits.patch similarity index 100% rename from patches/unapplied/0553-add-per-world-spawn-limits.patch rename to patches/unapplied/server/0553-add-per-world-spawn-limits.patch diff --git a/patches/unapplied/0554-Fix-potions-splash-events.patch b/patches/unapplied/server/0554-Fix-potions-splash-events.patch similarity index 100% rename from patches/unapplied/0554-Fix-potions-splash-events.patch rename to patches/unapplied/server/0554-Fix-potions-splash-events.patch diff --git a/patches/unapplied/0555-Add-more-LimitedRegion-API.patch b/patches/unapplied/server/0555-Add-more-LimitedRegion-API.patch similarity index 100% rename from patches/unapplied/0555-Add-more-LimitedRegion-API.patch rename to patches/unapplied/server/0555-Add-more-LimitedRegion-API.patch diff --git a/patches/unapplied/0556-Fix-PlayerDropItemEvent-using-wrong-item.patch b/patches/unapplied/server/0556-Fix-PlayerDropItemEvent-using-wrong-item.patch similarity index 100% rename from patches/unapplied/0556-Fix-PlayerDropItemEvent-using-wrong-item.patch rename to patches/unapplied/server/0556-Fix-PlayerDropItemEvent-using-wrong-item.patch diff --git a/patches/unapplied/0557-Missing-Entity-API.patch b/patches/unapplied/server/0557-Missing-Entity-API.patch similarity index 100% rename from patches/unapplied/0557-Missing-Entity-API.patch rename to patches/unapplied/server/0557-Missing-Entity-API.patch diff --git a/patches/unapplied/0558-Fix-return-value-of-Block-applyBoneMeal-always-being.patch b/patches/unapplied/server/0558-Fix-return-value-of-Block-applyBoneMeal-always-being.patch similarity index 100% rename from patches/unapplied/0558-Fix-return-value-of-Block-applyBoneMeal-always-being.patch rename to patches/unapplied/server/0558-Fix-return-value-of-Block-applyBoneMeal-always-being.patch diff --git a/patches/unapplied/0559-Use-getChunkIfLoadedImmediately-in-places.patch b/patches/unapplied/server/0559-Use-getChunkIfLoadedImmediately-in-places.patch similarity index 100% rename from patches/unapplied/0559-Use-getChunkIfLoadedImmediately-in-places.patch rename to patches/unapplied/server/0559-Use-getChunkIfLoadedImmediately-in-places.patch diff --git a/patches/unapplied/0560-Fix-commands-from-signs-not-firing-command-events.patch b/patches/unapplied/server/0560-Fix-commands-from-signs-not-firing-command-events.patch similarity index 100% rename from patches/unapplied/0560-Fix-commands-from-signs-not-firing-command-events.patch rename to patches/unapplied/server/0560-Fix-commands-from-signs-not-firing-command-events.patch diff --git a/patches/unapplied/0561-Add-PlayerArmSwingEvent.patch b/patches/unapplied/server/0561-Add-PlayerArmSwingEvent.patch similarity index 100% rename from patches/unapplied/0561-Add-PlayerArmSwingEvent.patch rename to patches/unapplied/server/0561-Add-PlayerArmSwingEvent.patch diff --git a/patches/unapplied/0562-Fix-kick-event-leave-message-not-being-sent.patch b/patches/unapplied/server/0562-Fix-kick-event-leave-message-not-being-sent.patch similarity index 100% rename from patches/unapplied/0562-Fix-kick-event-leave-message-not-being-sent.patch rename to patches/unapplied/server/0562-Fix-kick-event-leave-message-not-being-sent.patch diff --git a/patches/unapplied/0563-Don-t-apply-cramming-damage-to-players.patch b/patches/unapplied/server/0563-Don-t-apply-cramming-damage-to-players.patch similarity index 100% rename from patches/unapplied/0563-Don-t-apply-cramming-damage-to-players.patch rename to patches/unapplied/server/0563-Don-t-apply-cramming-damage-to-players.patch diff --git a/patches/unapplied/0564-Rate-options-and-timings-for-sensors-and-behaviors.patch b/patches/unapplied/server/0564-Rate-options-and-timings-for-sensors-and-behaviors.patch similarity index 100% rename from patches/unapplied/0564-Rate-options-and-timings-for-sensors-and-behaviors.patch rename to patches/unapplied/server/0564-Rate-options-and-timings-for-sensors-and-behaviors.patch diff --git a/patches/unapplied/0565-Add-missing-forceDrop-toggles.patch b/patches/unapplied/server/0565-Add-missing-forceDrop-toggles.patch similarity index 100% rename from patches/unapplied/0565-Add-missing-forceDrop-toggles.patch rename to patches/unapplied/server/0565-Add-missing-forceDrop-toggles.patch diff --git a/patches/unapplied/0566-Stinger-API.patch b/patches/unapplied/server/0566-Stinger-API.patch similarity index 100% rename from patches/unapplied/0566-Stinger-API.patch rename to patches/unapplied/server/0566-Stinger-API.patch diff --git a/patches/unapplied/0567-Add-System.out-err-catcher.patch b/patches/unapplied/server/0567-Add-System.out-err-catcher.patch similarity index 100% rename from patches/unapplied/0567-Add-System.out-err-catcher.patch rename to patches/unapplied/server/0567-Add-System.out-err-catcher.patch diff --git a/patches/unapplied/0568-Prevent-AFK-kick-while-watching-end-credits.patch b/patches/unapplied/server/0568-Prevent-AFK-kick-while-watching-end-credits.patch similarity index 100% rename from patches/unapplied/0568-Prevent-AFK-kick-while-watching-end-credits.patch rename to patches/unapplied/server/0568-Prevent-AFK-kick-while-watching-end-credits.patch diff --git a/patches/unapplied/0569-Allow-skipping-writing-of-comments-to-server.propert.patch b/patches/unapplied/server/0569-Allow-skipping-writing-of-comments-to-server.propert.patch similarity index 100% rename from patches/unapplied/0569-Allow-skipping-writing-of-comments-to-server.propert.patch rename to patches/unapplied/server/0569-Allow-skipping-writing-of-comments-to-server.propert.patch diff --git a/patches/unapplied/0570-Add-PlayerSetSpawnEvent.patch b/patches/unapplied/server/0570-Add-PlayerSetSpawnEvent.patch similarity index 100% rename from patches/unapplied/0570-Add-PlayerSetSpawnEvent.patch rename to patches/unapplied/server/0570-Add-PlayerSetSpawnEvent.patch diff --git a/patches/unapplied/0571-Make-hoppers-respect-inventory-max-stack-size.patch b/patches/unapplied/server/0571-Make-hoppers-respect-inventory-max-stack-size.patch similarity index 100% rename from patches/unapplied/0571-Make-hoppers-respect-inventory-max-stack-size.patch rename to patches/unapplied/server/0571-Make-hoppers-respect-inventory-max-stack-size.patch diff --git a/patches/unapplied/0572-Optimize-entity-tracker-passenger-checks.patch b/patches/unapplied/server/0572-Optimize-entity-tracker-passenger-checks.patch similarity index 100% rename from patches/unapplied/0572-Optimize-entity-tracker-passenger-checks.patch rename to patches/unapplied/server/0572-Optimize-entity-tracker-passenger-checks.patch diff --git a/patches/unapplied/0573-Config-option-for-Piglins-guarding-chests.patch b/patches/unapplied/server/0573-Config-option-for-Piglins-guarding-chests.patch similarity index 100% rename from patches/unapplied/0573-Config-option-for-Piglins-guarding-chests.patch rename to patches/unapplied/server/0573-Config-option-for-Piglins-guarding-chests.patch diff --git a/patches/unapplied/0574-Add-EntityDamageItemEvent.patch b/patches/unapplied/server/0574-Add-EntityDamageItemEvent.patch similarity index 100% rename from patches/unapplied/0574-Add-EntityDamageItemEvent.patch rename to patches/unapplied/server/0574-Add-EntityDamageItemEvent.patch diff --git a/patches/unapplied/0575-Optimize-indirect-passenger-iteration.patch b/patches/unapplied/server/0575-Optimize-indirect-passenger-iteration.patch similarity index 100% rename from patches/unapplied/0575-Optimize-indirect-passenger-iteration.patch rename to patches/unapplied/server/0575-Optimize-indirect-passenger-iteration.patch diff --git a/patches/unapplied/0576-Configurable-item-frame-map-cursor-update-interval.patch b/patches/unapplied/server/0576-Configurable-item-frame-map-cursor-update-interval.patch similarity index 100% rename from patches/unapplied/0576-Configurable-item-frame-map-cursor-update-interval.patch rename to patches/unapplied/server/0576-Configurable-item-frame-map-cursor-update-interval.patch diff --git a/patches/unapplied/0577-Change-EnderEye-target-without-changing-other-things.patch b/patches/unapplied/server/0577-Change-EnderEye-target-without-changing-other-things.patch similarity index 100% rename from patches/unapplied/0577-Change-EnderEye-target-without-changing-other-things.patch rename to patches/unapplied/server/0577-Change-EnderEye-target-without-changing-other-things.patch diff --git a/patches/unapplied/0578-Add-BlockBreakBlockEvent.patch b/patches/unapplied/server/0578-Add-BlockBreakBlockEvent.patch similarity index 100% rename from patches/unapplied/0578-Add-BlockBreakBlockEvent.patch rename to patches/unapplied/server/0578-Add-BlockBreakBlockEvent.patch diff --git a/patches/unapplied/0579-Option-to-prevent-data-components-copy-in-smithing-r.patch b/patches/unapplied/server/0579-Option-to-prevent-data-components-copy-in-smithing-r.patch similarity index 100% rename from patches/unapplied/0579-Option-to-prevent-data-components-copy-in-smithing-r.patch rename to patches/unapplied/server/0579-Option-to-prevent-data-components-copy-in-smithing-r.patch diff --git a/patches/unapplied/0580-More-CommandBlock-API.patch b/patches/unapplied/server/0580-More-CommandBlock-API.patch similarity index 100% rename from patches/unapplied/0580-More-CommandBlock-API.patch rename to patches/unapplied/server/0580-More-CommandBlock-API.patch diff --git a/patches/unapplied/0581-Add-missing-team-sidebar-display-slots.patch b/patches/unapplied/server/0581-Add-missing-team-sidebar-display-slots.patch similarity index 100% rename from patches/unapplied/0581-Add-missing-team-sidebar-display-slots.patch rename to patches/unapplied/server/0581-Add-missing-team-sidebar-display-slots.patch diff --git a/patches/unapplied/0582-Add-back-EntityPortalExitEvent.patch b/patches/unapplied/server/0582-Add-back-EntityPortalExitEvent.patch similarity index 100% rename from patches/unapplied/0582-Add-back-EntityPortalExitEvent.patch rename to patches/unapplied/server/0582-Add-back-EntityPortalExitEvent.patch diff --git a/patches/unapplied/0583-Add-methods-to-find-targets-for-lightning-strikes.patch b/patches/unapplied/server/0583-Add-methods-to-find-targets-for-lightning-strikes.patch similarity index 100% rename from patches/unapplied/0583-Add-methods-to-find-targets-for-lightning-strikes.patch rename to patches/unapplied/server/0583-Add-methods-to-find-targets-for-lightning-strikes.patch diff --git a/patches/unapplied/0584-Get-entity-default-attributes.patch b/patches/unapplied/server/0584-Get-entity-default-attributes.patch similarity index 100% rename from patches/unapplied/0584-Get-entity-default-attributes.patch rename to patches/unapplied/server/0584-Get-entity-default-attributes.patch diff --git a/patches/unapplied/0585-Left-handed-API.patch b/patches/unapplied/server/0585-Left-handed-API.patch similarity index 100% rename from patches/unapplied/0585-Left-handed-API.patch rename to patches/unapplied/server/0585-Left-handed-API.patch diff --git a/patches/unapplied/0586-Add-more-advancement-API.patch b/patches/unapplied/server/0586-Add-more-advancement-API.patch similarity index 100% rename from patches/unapplied/0586-Add-more-advancement-API.patch rename to patches/unapplied/server/0586-Add-more-advancement-API.patch diff --git a/patches/unapplied/0587-Add-ItemFactory-getSpawnEgg-API.patch b/patches/unapplied/server/0587-Add-ItemFactory-getSpawnEgg-API.patch similarity index 100% rename from patches/unapplied/0587-Add-ItemFactory-getSpawnEgg-API.patch rename to patches/unapplied/server/0587-Add-ItemFactory-getSpawnEgg-API.patch diff --git a/patches/unapplied/0588-Add-critical-damage-API.patch b/patches/unapplied/server/0588-Add-critical-damage-API.patch similarity index 100% rename from patches/unapplied/0588-Add-critical-damage-API.patch rename to patches/unapplied/server/0588-Add-critical-damage-API.patch diff --git a/patches/unapplied/0589-Fix-issues-with-mob-conversion.patch b/patches/unapplied/server/0589-Fix-issues-with-mob-conversion.patch similarity index 100% rename from patches/unapplied/0589-Fix-issues-with-mob-conversion.patch rename to patches/unapplied/server/0589-Fix-issues-with-mob-conversion.patch diff --git a/patches/unapplied/0590-Add-hasCollision-methods-to-various-places.patch b/patches/unapplied/server/0590-Add-hasCollision-methods-to-various-places.patch similarity index 100% rename from patches/unapplied/0590-Add-hasCollision-methods-to-various-places.patch rename to patches/unapplied/server/0590-Add-hasCollision-methods-to-various-places.patch diff --git a/patches/unapplied/0591-Goat-ram-API.patch b/patches/unapplied/server/0591-Goat-ram-API.patch similarity index 100% rename from patches/unapplied/0591-Goat-ram-API.patch rename to patches/unapplied/server/0591-Goat-ram-API.patch diff --git a/patches/unapplied/0592-Add-API-for-resetting-a-single-score.patch b/patches/unapplied/server/0592-Add-API-for-resetting-a-single-score.patch similarity index 100% rename from patches/unapplied/0592-Add-API-for-resetting-a-single-score.patch rename to patches/unapplied/server/0592-Add-API-for-resetting-a-single-score.patch diff --git a/patches/unapplied/0593-Add-Raw-Byte-Entity-Serialization.patch b/patches/unapplied/server/0593-Add-Raw-Byte-Entity-Serialization.patch similarity index 100% rename from patches/unapplied/0593-Add-Raw-Byte-Entity-Serialization.patch rename to patches/unapplied/server/0593-Add-Raw-Byte-Entity-Serialization.patch diff --git a/patches/unapplied/0594-Vanilla-command-permission-fixes.patch b/patches/unapplied/server/0594-Vanilla-command-permission-fixes.patch similarity index 100% rename from patches/unapplied/0594-Vanilla-command-permission-fixes.patch rename to patches/unapplied/server/0594-Vanilla-command-permission-fixes.patch diff --git a/patches/unapplied/0595-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch b/patches/unapplied/server/0595-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch similarity index 100% rename from patches/unapplied/0595-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch rename to patches/unapplied/server/0595-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch diff --git a/patches/unapplied/0596-Fix-GameProfileCache-concurrency.patch b/patches/unapplied/server/0596-Fix-GameProfileCache-concurrency.patch similarity index 100% rename from patches/unapplied/0596-Fix-GameProfileCache-concurrency.patch rename to patches/unapplied/server/0596-Fix-GameProfileCache-concurrency.patch diff --git a/patches/unapplied/0597-Improve-and-expand-AsyncCatcher.patch b/patches/unapplied/server/0597-Improve-and-expand-AsyncCatcher.patch similarity index 100% rename from patches/unapplied/0597-Improve-and-expand-AsyncCatcher.patch rename to patches/unapplied/server/0597-Improve-and-expand-AsyncCatcher.patch diff --git a/patches/unapplied/0598-Add-paper-mobcaps-and-paper-playermobcaps.patch b/patches/unapplied/server/0598-Add-paper-mobcaps-and-paper-playermobcaps.patch similarity index 100% rename from patches/unapplied/0598-Add-paper-mobcaps-and-paper-playermobcaps.patch rename to patches/unapplied/server/0598-Add-paper-mobcaps-and-paper-playermobcaps.patch diff --git a/patches/unapplied/0599-Sanitize-ResourceLocation-error-logging.patch b/patches/unapplied/server/0599-Sanitize-ResourceLocation-error-logging.patch similarity index 100% rename from patches/unapplied/0599-Sanitize-ResourceLocation-error-logging.patch rename to patches/unapplied/server/0599-Sanitize-ResourceLocation-error-logging.patch diff --git a/patches/unapplied/0600-Manually-inline-methods-in-BlockPosition.patch b/patches/unapplied/server/0600-Manually-inline-methods-in-BlockPosition.patch similarity index 100% rename from patches/unapplied/0600-Manually-inline-methods-in-BlockPosition.patch rename to patches/unapplied/server/0600-Manually-inline-methods-in-BlockPosition.patch diff --git a/patches/unapplied/0601-Name-craft-scheduler-threads-according-to-the-plugin.patch b/patches/unapplied/server/0601-Name-craft-scheduler-threads-according-to-the-plugin.patch similarity index 100% rename from patches/unapplied/0601-Name-craft-scheduler-threads-according-to-the-plugin.patch rename to patches/unapplied/server/0601-Name-craft-scheduler-threads-according-to-the-plugin.patch diff --git a/patches/unapplied/0602-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch b/patches/unapplied/server/0602-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch similarity index 100% rename from patches/unapplied/0602-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch rename to patches/unapplied/server/0602-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch diff --git a/patches/unapplied/0603-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch b/patches/unapplied/server/0603-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch similarity index 100% rename from patches/unapplied/0603-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch rename to patches/unapplied/server/0603-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch diff --git a/patches/unapplied/0604-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch b/patches/unapplied/server/0604-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch similarity index 100% rename from patches/unapplied/0604-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch rename to patches/unapplied/server/0604-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch diff --git a/patches/unapplied/0605-Time-scoreboard-search.patch b/patches/unapplied/server/0605-Time-scoreboard-search.patch similarity index 100% rename from patches/unapplied/0605-Time-scoreboard-search.patch rename to patches/unapplied/server/0605-Time-scoreboard-search.patch diff --git a/patches/unapplied/0606-Oprimise-map-impl-for-tracked-players.patch b/patches/unapplied/server/0606-Oprimise-map-impl-for-tracked-players.patch similarity index 100% rename from patches/unapplied/0606-Oprimise-map-impl-for-tracked-players.patch rename to patches/unapplied/server/0606-Oprimise-map-impl-for-tracked-players.patch diff --git a/patches/unapplied/0607-Add-missing-InventoryType.patch b/patches/unapplied/server/0607-Add-missing-InventoryType.patch similarity index 100% rename from patches/unapplied/0607-Add-missing-InventoryType.patch rename to patches/unapplied/server/0607-Add-missing-InventoryType.patch diff --git a/patches/unapplied/0608-Optimise-BlockSoil-nearby-water-lookup.patch b/patches/unapplied/server/0608-Optimise-BlockSoil-nearby-water-lookup.patch similarity index 100% rename from patches/unapplied/0608-Optimise-BlockSoil-nearby-water-lookup.patch rename to patches/unapplied/server/0608-Optimise-BlockSoil-nearby-water-lookup.patch diff --git a/patches/unapplied/0609-Fix-merchant-inventory-not-closing-on-entity-removal.patch b/patches/unapplied/server/0609-Fix-merchant-inventory-not-closing-on-entity-removal.patch similarity index 100% rename from patches/unapplied/0609-Fix-merchant-inventory-not-closing-on-entity-removal.patch rename to patches/unapplied/server/0609-Fix-merchant-inventory-not-closing-on-entity-removal.patch diff --git a/patches/unapplied/0610-Check-requirement-before-suggesting-root-nodes.patch b/patches/unapplied/server/0610-Check-requirement-before-suggesting-root-nodes.patch similarity index 100% rename from patches/unapplied/0610-Check-requirement-before-suggesting-root-nodes.patch rename to patches/unapplied/server/0610-Check-requirement-before-suggesting-root-nodes.patch diff --git a/patches/unapplied/0611-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch b/patches/unapplied/server/0611-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch similarity index 100% rename from patches/unapplied/0611-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch rename to patches/unapplied/server/0611-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch diff --git a/patches/unapplied/0612-Add-packet-limiter-config.patch b/patches/unapplied/server/0612-Add-packet-limiter-config.patch similarity index 100% rename from patches/unapplied/0612-Add-packet-limiter-config.patch rename to patches/unapplied/server/0612-Add-packet-limiter-config.patch diff --git a/patches/unapplied/0613-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch b/patches/unapplied/server/0613-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch similarity index 100% rename from patches/unapplied/0613-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch rename to patches/unapplied/server/0613-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch diff --git a/patches/unapplied/0614-Ensure-valid-vehicle-status.patch b/patches/unapplied/server/0614-Ensure-valid-vehicle-status.patch similarity index 100% rename from patches/unapplied/0614-Ensure-valid-vehicle-status.patch rename to patches/unapplied/server/0614-Ensure-valid-vehicle-status.patch diff --git a/patches/unapplied/0615-Prevent-softlocked-end-exit-portal-generation.patch b/patches/unapplied/server/0615-Prevent-softlocked-end-exit-portal-generation.patch similarity index 100% rename from patches/unapplied/0615-Prevent-softlocked-end-exit-portal-generation.patch rename to patches/unapplied/server/0615-Prevent-softlocked-end-exit-portal-generation.patch diff --git a/patches/unapplied/0616-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch b/patches/unapplied/server/0616-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch similarity index 100% rename from patches/unapplied/0616-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch rename to patches/unapplied/server/0616-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch diff --git a/patches/unapplied/0617-Don-t-log-debug-logging-being-disabled.patch b/patches/unapplied/server/0617-Don-t-log-debug-logging-being-disabled.patch similarity index 100% rename from patches/unapplied/0617-Don-t-log-debug-logging-being-disabled.patch rename to patches/unapplied/server/0617-Don-t-log-debug-logging-being-disabled.patch diff --git a/patches/unapplied/0618-fix-various-menus-with-empty-level-accesses.patch b/patches/unapplied/server/0618-fix-various-menus-with-empty-level-accesses.patch similarity index 100% rename from patches/unapplied/0618-fix-various-menus-with-empty-level-accesses.patch rename to patches/unapplied/server/0618-fix-various-menus-with-empty-level-accesses.patch diff --git a/patches/unapplied/0619-Preserve-overstacked-loot.patch b/patches/unapplied/server/0619-Preserve-overstacked-loot.patch similarity index 100% rename from patches/unapplied/0619-Preserve-overstacked-loot.patch rename to patches/unapplied/server/0619-Preserve-overstacked-loot.patch diff --git a/patches/unapplied/0620-Update-head-rotation-in-missing-places.patch b/patches/unapplied/server/0620-Update-head-rotation-in-missing-places.patch similarity index 100% rename from patches/unapplied/0620-Update-head-rotation-in-missing-places.patch rename to patches/unapplied/server/0620-Update-head-rotation-in-missing-places.patch diff --git a/patches/unapplied/0621-prevent-unintended-light-block-manipulation.patch b/patches/unapplied/server/0621-prevent-unintended-light-block-manipulation.patch similarity index 100% rename from patches/unapplied/0621-prevent-unintended-light-block-manipulation.patch rename to patches/unapplied/server/0621-prevent-unintended-light-block-manipulation.patch diff --git a/patches/unapplied/0622-Fix-CraftCriteria-defaults-map.patch b/patches/unapplied/server/0622-Fix-CraftCriteria-defaults-map.patch similarity index 100% rename from patches/unapplied/0622-Fix-CraftCriteria-defaults-map.patch rename to patches/unapplied/server/0622-Fix-CraftCriteria-defaults-map.patch diff --git a/patches/unapplied/0623-Fix-upstreams-block-state-factories.patch b/patches/unapplied/server/0623-Fix-upstreams-block-state-factories.patch similarity index 100% rename from patches/unapplied/0623-Fix-upstreams-block-state-factories.patch rename to patches/unapplied/server/0623-Fix-upstreams-block-state-factories.patch diff --git a/patches/unapplied/0624-Configurable-feature-seeds.patch b/patches/unapplied/server/0624-Configurable-feature-seeds.patch similarity index 100% rename from patches/unapplied/0624-Configurable-feature-seeds.patch rename to patches/unapplied/server/0624-Configurable-feature-seeds.patch diff --git a/patches/unapplied/0625-Add-root-admin-user-detection.patch b/patches/unapplied/server/0625-Add-root-admin-user-detection.patch similarity index 100% rename from patches/unapplied/0625-Add-root-admin-user-detection.patch rename to patches/unapplied/server/0625-Add-root-admin-user-detection.patch diff --git a/patches/unapplied/0626-don-t-attempt-to-teleport-dead-entities.patch b/patches/unapplied/server/0626-don-t-attempt-to-teleport-dead-entities.patch similarity index 100% rename from patches/unapplied/0626-don-t-attempt-to-teleport-dead-entities.patch rename to patches/unapplied/server/0626-don-t-attempt-to-teleport-dead-entities.patch diff --git a/patches/unapplied/0627-Prevent-excessive-velocity-through-repeated-crits.patch b/patches/unapplied/server/0627-Prevent-excessive-velocity-through-repeated-crits.patch similarity index 100% rename from patches/unapplied/0627-Prevent-excessive-velocity-through-repeated-crits.patch rename to patches/unapplied/server/0627-Prevent-excessive-velocity-through-repeated-crits.patch diff --git a/patches/unapplied/0628-Remove-client-side-code-using-deprecated-for-removal.patch b/patches/unapplied/server/0628-Remove-client-side-code-using-deprecated-for-removal.patch similarity index 100% rename from patches/unapplied/0628-Remove-client-side-code-using-deprecated-for-removal.patch rename to patches/unapplied/server/0628-Remove-client-side-code-using-deprecated-for-removal.patch diff --git a/patches/unapplied/0629-Fix-Spigot-growth-modifiers.patch b/patches/unapplied/server/0629-Fix-Spigot-growth-modifiers.patch similarity index 100% rename from patches/unapplied/0629-Fix-Spigot-growth-modifiers.patch rename to patches/unapplied/server/0629-Fix-Spigot-growth-modifiers.patch diff --git a/patches/unapplied/0630-Prevent-ContainerOpenersCounter-openCount-from-going.patch b/patches/unapplied/server/0630-Prevent-ContainerOpenersCounter-openCount-from-going.patch similarity index 100% rename from patches/unapplied/0630-Prevent-ContainerOpenersCounter-openCount-from-going.patch rename to patches/unapplied/server/0630-Prevent-ContainerOpenersCounter-openCount-from-going.patch diff --git a/patches/unapplied/0631-Add-PlayerItemFrameChangeEvent.patch b/patches/unapplied/server/0631-Add-PlayerItemFrameChangeEvent.patch similarity index 100% rename from patches/unapplied/0631-Add-PlayerItemFrameChangeEvent.patch rename to patches/unapplied/server/0631-Add-PlayerItemFrameChangeEvent.patch diff --git a/patches/unapplied/0632-Optimize-HashMapPalette.patch b/patches/unapplied/server/0632-Optimize-HashMapPalette.patch similarity index 100% rename from patches/unapplied/0632-Optimize-HashMapPalette.patch rename to patches/unapplied/server/0632-Optimize-HashMapPalette.patch diff --git a/patches/unapplied/0633-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch b/patches/unapplied/server/0633-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch similarity index 100% rename from patches/unapplied/0633-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch rename to patches/unapplied/server/0633-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch diff --git a/patches/unapplied/0634-Add-more-Campfire-API.patch b/patches/unapplied/server/0634-Add-more-Campfire-API.patch similarity index 100% rename from patches/unapplied/0634-Add-more-Campfire-API.patch rename to patches/unapplied/server/0634-Add-more-Campfire-API.patch diff --git a/patches/unapplied/0635-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch b/patches/unapplied/server/0635-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch similarity index 100% rename from patches/unapplied/0635-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch rename to patches/unapplied/server/0635-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch diff --git a/patches/unapplied/0636-Forward-CraftEntity-in-teleport-command.patch b/patches/unapplied/server/0636-Forward-CraftEntity-in-teleport-command.patch similarity index 100% rename from patches/unapplied/0636-Forward-CraftEntity-in-teleport-command.patch rename to patches/unapplied/server/0636-Forward-CraftEntity-in-teleport-command.patch diff --git a/patches/unapplied/0637-Improve-scoreboard-entries.patch b/patches/unapplied/server/0637-Improve-scoreboard-entries.patch similarity index 100% rename from patches/unapplied/0637-Improve-scoreboard-entries.patch rename to patches/unapplied/server/0637-Improve-scoreboard-entries.patch diff --git a/patches/unapplied/0638-Entity-powdered-snow-API.patch b/patches/unapplied/server/0638-Entity-powdered-snow-API.patch similarity index 100% rename from patches/unapplied/0638-Entity-powdered-snow-API.patch rename to patches/unapplied/server/0638-Entity-powdered-snow-API.patch diff --git a/patches/unapplied/0639-Add-API-for-item-entity-health.patch b/patches/unapplied/server/0639-Add-API-for-item-entity-health.patch similarity index 100% rename from patches/unapplied/0639-Add-API-for-item-entity-health.patch rename to patches/unapplied/server/0639-Add-API-for-item-entity-health.patch diff --git a/patches/unapplied/0640-Configurable-max-block-light-for-monster-spawning.patch b/patches/unapplied/server/0640-Configurable-max-block-light-for-monster-spawning.patch similarity index 100% rename from patches/unapplied/0640-Configurable-max-block-light-for-monster-spawning.patch rename to patches/unapplied/server/0640-Configurable-max-block-light-for-monster-spawning.patch diff --git a/patches/unapplied/0641-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch b/patches/unapplied/server/0641-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch similarity index 100% rename from patches/unapplied/0641-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch rename to patches/unapplied/server/0641-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch diff --git a/patches/unapplied/0642-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch b/patches/unapplied/server/0642-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch similarity index 100% rename from patches/unapplied/0642-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch rename to patches/unapplied/server/0642-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch diff --git a/patches/unapplied/0643-Bucketable-API.patch b/patches/unapplied/server/0643-Bucketable-API.patch similarity index 100% rename from patches/unapplied/0643-Bucketable-API.patch rename to patches/unapplied/server/0643-Bucketable-API.patch diff --git a/patches/unapplied/0644-Validate-usernames.patch b/patches/unapplied/server/0644-Validate-usernames.patch similarity index 100% rename from patches/unapplied/0644-Validate-usernames.patch rename to patches/unapplied/server/0644-Validate-usernames.patch diff --git a/patches/unapplied/0645-Make-water-animal-spawn-height-configurable.patch b/patches/unapplied/server/0645-Make-water-animal-spawn-height-configurable.patch similarity index 100% rename from patches/unapplied/0645-Make-water-animal-spawn-height-configurable.patch rename to patches/unapplied/server/0645-Make-water-animal-spawn-height-configurable.patch diff --git a/patches/unapplied/0646-Expose-vanilla-BiomeProvider-from-WorldInfo.patch b/patches/unapplied/server/0646-Expose-vanilla-BiomeProvider-from-WorldInfo.patch similarity index 100% rename from patches/unapplied/0646-Expose-vanilla-BiomeProvider-from-WorldInfo.patch rename to patches/unapplied/server/0646-Expose-vanilla-BiomeProvider-from-WorldInfo.patch diff --git a/patches/unapplied/0647-Add-config-option-for-worlds-affected-by-time-cmd.patch b/patches/unapplied/server/0647-Add-config-option-for-worlds-affected-by-time-cmd.patch similarity index 100% rename from patches/unapplied/0647-Add-config-option-for-worlds-affected-by-time-cmd.patch rename to patches/unapplied/server/0647-Add-config-option-for-worlds-affected-by-time-cmd.patch diff --git a/patches/unapplied/0648-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch b/patches/unapplied/server/0648-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch similarity index 100% rename from patches/unapplied/0648-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch rename to patches/unapplied/server/0648-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch diff --git a/patches/unapplied/0649-Multiple-Entries-with-Scoreboards.patch b/patches/unapplied/server/0649-Multiple-Entries-with-Scoreboards.patch similarity index 100% rename from patches/unapplied/0649-Multiple-Entries-with-Scoreboards.patch rename to patches/unapplied/server/0649-Multiple-Entries-with-Scoreboards.patch diff --git a/patches/unapplied/0650-Reset-placed-block-on-exception.patch b/patches/unapplied/server/0650-Reset-placed-block-on-exception.patch similarity index 100% rename from patches/unapplied/0650-Reset-placed-block-on-exception.patch rename to patches/unapplied/server/0650-Reset-placed-block-on-exception.patch diff --git a/patches/unapplied/0651-Add-configurable-height-for-slime-spawn.patch b/patches/unapplied/server/0651-Add-configurable-height-for-slime-spawn.patch similarity index 100% rename from patches/unapplied/0651-Add-configurable-height-for-slime-spawn.patch rename to patches/unapplied/server/0651-Add-configurable-height-for-slime-spawn.patch diff --git a/patches/unapplied/0652-Fix-xp-reward-for-baby-zombies.patch b/patches/unapplied/server/0652-Fix-xp-reward-for-baby-zombies.patch similarity index 100% rename from patches/unapplied/0652-Fix-xp-reward-for-baby-zombies.patch rename to patches/unapplied/server/0652-Fix-xp-reward-for-baby-zombies.patch diff --git a/patches/unapplied/0653-Multi-Block-Change-API-Implementation.patch b/patches/unapplied/server/0653-Multi-Block-Change-API-Implementation.patch similarity index 100% rename from patches/unapplied/0653-Multi-Block-Change-API-Implementation.patch rename to patches/unapplied/server/0653-Multi-Block-Change-API-Implementation.patch diff --git a/patches/unapplied/0654-Fix-NotePlayEvent.patch b/patches/unapplied/server/0654-Fix-NotePlayEvent.patch similarity index 100% rename from patches/unapplied/0654-Fix-NotePlayEvent.patch rename to patches/unapplied/server/0654-Fix-NotePlayEvent.patch diff --git a/patches/unapplied/0655-Freeze-Tick-Lock-API.patch b/patches/unapplied/server/0655-Freeze-Tick-Lock-API.patch similarity index 100% rename from patches/unapplied/0655-Freeze-Tick-Lock-API.patch rename to patches/unapplied/server/0655-Freeze-Tick-Lock-API.patch diff --git a/patches/unapplied/0656-More-PotionEffectType-API.patch b/patches/unapplied/server/0656-More-PotionEffectType-API.patch similarity index 100% rename from patches/unapplied/0656-More-PotionEffectType-API.patch rename to patches/unapplied/server/0656-More-PotionEffectType-API.patch diff --git a/patches/unapplied/0657-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch b/patches/unapplied/server/0657-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch similarity index 100% rename from patches/unapplied/0657-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch rename to patches/unapplied/server/0657-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch diff --git a/patches/unapplied/0658-API-for-creating-command-sender-which-forwards-feedb.patch b/patches/unapplied/server/0658-API-for-creating-command-sender-which-forwards-feedb.patch similarity index 100% rename from patches/unapplied/0658-API-for-creating-command-sender-which-forwards-feedb.patch rename to patches/unapplied/server/0658-API-for-creating-command-sender-which-forwards-feedb.patch diff --git a/patches/unapplied/0659-Add-missing-structure-set-seed-configs.patch b/patches/unapplied/server/0659-Add-missing-structure-set-seed-configs.patch similarity index 100% rename from patches/unapplied/0659-Add-missing-structure-set-seed-configs.patch rename to patches/unapplied/server/0659-Add-missing-structure-set-seed-configs.patch diff --git a/patches/unapplied/0660-Fix-cancelled-powdered-snow-bucket-placement.patch b/patches/unapplied/server/0660-Fix-cancelled-powdered-snow-bucket-placement.patch similarity index 100% rename from patches/unapplied/0660-Fix-cancelled-powdered-snow-bucket-placement.patch rename to patches/unapplied/server/0660-Fix-cancelled-powdered-snow-bucket-placement.patch diff --git a/patches/unapplied/0661-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch b/patches/unapplied/server/0661-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch similarity index 100% rename from patches/unapplied/0661-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch rename to patches/unapplied/server/0661-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch diff --git a/patches/unapplied/0662-Add-GameEvent-tags.patch b/patches/unapplied/server/0662-Add-GameEvent-tags.patch similarity index 100% rename from patches/unapplied/0662-Add-GameEvent-tags.patch rename to patches/unapplied/server/0662-Add-GameEvent-tags.patch diff --git a/patches/unapplied/0663-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch b/patches/unapplied/server/0663-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch similarity index 100% rename from patches/unapplied/0663-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch rename to patches/unapplied/server/0663-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch diff --git a/patches/unapplied/0664-Furnace-RecipesUsed-API.patch b/patches/unapplied/server/0664-Furnace-RecipesUsed-API.patch similarity index 100% rename from patches/unapplied/0664-Furnace-RecipesUsed-API.patch rename to patches/unapplied/server/0664-Furnace-RecipesUsed-API.patch diff --git a/patches/unapplied/0665-Configurable-sculk-sensor-listener-range.patch b/patches/unapplied/server/0665-Configurable-sculk-sensor-listener-range.patch similarity index 100% rename from patches/unapplied/0665-Configurable-sculk-sensor-listener-range.patch rename to patches/unapplied/server/0665-Configurable-sculk-sensor-listener-range.patch diff --git a/patches/unapplied/0666-Add-missing-block-data-API.patch b/patches/unapplied/server/0666-Add-missing-block-data-API.patch similarity index 100% rename from patches/unapplied/0666-Add-missing-block-data-API.patch rename to patches/unapplied/server/0666-Add-missing-block-data-API.patch diff --git a/patches/unapplied/0667-Option-to-have-default-CustomSpawners-in-custom-worl.patch b/patches/unapplied/server/0667-Option-to-have-default-CustomSpawners-in-custom-worl.patch similarity index 100% rename from patches/unapplied/0667-Option-to-have-default-CustomSpawners-in-custom-worl.patch rename to patches/unapplied/server/0667-Option-to-have-default-CustomSpawners-in-custom-worl.patch diff --git a/patches/unapplied/0668-Put-world-into-worldlist-before-initing-the-world.patch b/patches/unapplied/server/0668-Put-world-into-worldlist-before-initing-the-world.patch similarity index 100% rename from patches/unapplied/0668-Put-world-into-worldlist-before-initing-the-world.patch rename to patches/unapplied/server/0668-Put-world-into-worldlist-before-initing-the-world.patch diff --git a/patches/unapplied/0669-Custom-Potion-Mixes.patch b/patches/unapplied/server/0669-Custom-Potion-Mixes.patch similarity index 100% rename from patches/unapplied/0669-Custom-Potion-Mixes.patch rename to patches/unapplied/server/0669-Custom-Potion-Mixes.patch diff --git a/patches/unapplied/0670-Force-close-world-loading-screen.patch b/patches/unapplied/server/0670-Force-close-world-loading-screen.patch similarity index 100% rename from patches/unapplied/0670-Force-close-world-loading-screen.patch rename to patches/unapplied/server/0670-Force-close-world-loading-screen.patch diff --git a/patches/unapplied/0671-Fix-falling-block-spawn-methods.patch b/patches/unapplied/server/0671-Fix-falling-block-spawn-methods.patch similarity index 100% rename from patches/unapplied/0671-Fix-falling-block-spawn-methods.patch rename to patches/unapplied/server/0671-Fix-falling-block-spawn-methods.patch diff --git a/patches/unapplied/0672-Expose-furnace-minecart-push-values.patch b/patches/unapplied/server/0672-Expose-furnace-minecart-push-values.patch similarity index 100% rename from patches/unapplied/0672-Expose-furnace-minecart-push-values.patch rename to patches/unapplied/server/0672-Expose-furnace-minecart-push-values.patch diff --git a/patches/unapplied/0673-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch b/patches/unapplied/server/0673-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch similarity index 100% rename from patches/unapplied/0673-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch rename to patches/unapplied/server/0673-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch diff --git a/patches/unapplied/0674-More-Projectile-API.patch b/patches/unapplied/server/0674-More-Projectile-API.patch similarity index 100% rename from patches/unapplied/0674-More-Projectile-API.patch rename to patches/unapplied/server/0674-More-Projectile-API.patch diff --git a/patches/unapplied/0675-Fix-swamp-hut-cat-generation-deadlock.patch b/patches/unapplied/server/0675-Fix-swamp-hut-cat-generation-deadlock.patch similarity index 100% rename from patches/unapplied/0675-Fix-swamp-hut-cat-generation-deadlock.patch rename to patches/unapplied/server/0675-Fix-swamp-hut-cat-generation-deadlock.patch diff --git a/patches/unapplied/0676-Don-t-allow-vehicle-movement-from-players-while-tele.patch b/patches/unapplied/server/0676-Don-t-allow-vehicle-movement-from-players-while-tele.patch similarity index 100% rename from patches/unapplied/0676-Don-t-allow-vehicle-movement-from-players-while-tele.patch rename to patches/unapplied/server/0676-Don-t-allow-vehicle-movement-from-players-while-tele.patch diff --git a/patches/unapplied/0677-Implement-getComputedBiome-API.patch b/patches/unapplied/server/0677-Implement-getComputedBiome-API.patch similarity index 100% rename from patches/unapplied/0677-Implement-getComputedBiome-API.patch rename to patches/unapplied/server/0677-Implement-getComputedBiome-API.patch diff --git a/patches/unapplied/0678-Make-some-itemstacks-nonnull.patch b/patches/unapplied/server/0678-Make-some-itemstacks-nonnull.patch similarity index 100% rename from patches/unapplied/0678-Make-some-itemstacks-nonnull.patch rename to patches/unapplied/server/0678-Make-some-itemstacks-nonnull.patch diff --git a/patches/unapplied/0679-Implement-enchantWithLevels-API.patch b/patches/unapplied/server/0679-Implement-enchantWithLevels-API.patch similarity index 100% rename from patches/unapplied/0679-Implement-enchantWithLevels-API.patch rename to patches/unapplied/server/0679-Implement-enchantWithLevels-API.patch diff --git a/patches/unapplied/0680-Fix-saving-in-unloadWorld.patch b/patches/unapplied/server/0680-Fix-saving-in-unloadWorld.patch similarity index 100% rename from patches/unapplied/0680-Fix-saving-in-unloadWorld.patch rename to patches/unapplied/server/0680-Fix-saving-in-unloadWorld.patch diff --git a/patches/unapplied/0681-Buffer-OOB-setBlock-calls.patch b/patches/unapplied/server/0681-Buffer-OOB-setBlock-calls.patch similarity index 100% rename from patches/unapplied/0681-Buffer-OOB-setBlock-calls.patch rename to patches/unapplied/server/0681-Buffer-OOB-setBlock-calls.patch diff --git a/patches/unapplied/0682-Add-TameableDeathMessageEvent.patch b/patches/unapplied/server/0682-Add-TameableDeathMessageEvent.patch similarity index 100% rename from patches/unapplied/0682-Add-TameableDeathMessageEvent.patch rename to patches/unapplied/server/0682-Add-TameableDeathMessageEvent.patch diff --git a/patches/unapplied/0683-Fix-new-block-data-for-EntityChangeBlockEvent.patch b/patches/unapplied/server/0683-Fix-new-block-data-for-EntityChangeBlockEvent.patch similarity index 100% rename from patches/unapplied/0683-Fix-new-block-data-for-EntityChangeBlockEvent.patch rename to patches/unapplied/server/0683-Fix-new-block-data-for-EntityChangeBlockEvent.patch diff --git a/patches/unapplied/0684-fix-player-loottables-running-when-mob-loot-gamerule.patch b/patches/unapplied/server/0684-fix-player-loottables-running-when-mob-loot-gamerule.patch similarity index 100% rename from patches/unapplied/0684-fix-player-loottables-running-when-mob-loot-gamerule.patch rename to patches/unapplied/server/0684-fix-player-loottables-running-when-mob-loot-gamerule.patch diff --git a/patches/unapplied/0685-Ensure-entity-passenger-world-matches-ridden-entity.patch b/patches/unapplied/server/0685-Ensure-entity-passenger-world-matches-ridden-entity.patch similarity index 100% rename from patches/unapplied/0685-Ensure-entity-passenger-world-matches-ridden-entity.patch rename to patches/unapplied/server/0685-Ensure-entity-passenger-world-matches-ridden-entity.patch diff --git a/patches/unapplied/0686-Cache-resource-keys-and-optimize-reference-Holder-ta.patch b/patches/unapplied/server/0686-Cache-resource-keys-and-optimize-reference-Holder-ta.patch similarity index 100% rename from patches/unapplied/0686-Cache-resource-keys-and-optimize-reference-Holder-ta.patch rename to patches/unapplied/server/0686-Cache-resource-keys-and-optimize-reference-Holder-ta.patch diff --git a/patches/unapplied/0687-Allow-changing-the-EnderDragon-podium.patch b/patches/unapplied/server/0687-Allow-changing-the-EnderDragon-podium.patch similarity index 100% rename from patches/unapplied/0687-Allow-changing-the-EnderDragon-podium.patch rename to patches/unapplied/server/0687-Allow-changing-the-EnderDragon-podium.patch diff --git a/patches/unapplied/0688-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch b/patches/unapplied/server/0688-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch similarity index 100% rename from patches/unapplied/0688-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch rename to patches/unapplied/server/0688-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch diff --git a/patches/unapplied/0689-Prevent-tile-entity-copies-loading-chunks.patch b/patches/unapplied/server/0689-Prevent-tile-entity-copies-loading-chunks.patch similarity index 100% rename from patches/unapplied/0689-Prevent-tile-entity-copies-loading-chunks.patch rename to patches/unapplied/server/0689-Prevent-tile-entity-copies-loading-chunks.patch diff --git a/patches/unapplied/0690-Use-username-instead-of-display-name-in-PlayerList-g.patch b/patches/unapplied/server/0690-Use-username-instead-of-display-name-in-PlayerList-g.patch similarity index 100% rename from patches/unapplied/0690-Use-username-instead-of-display-name-in-PlayerList-g.patch rename to patches/unapplied/server/0690-Use-username-instead-of-display-name-in-PlayerList-g.patch diff --git a/patches/unapplied/0691-Expand-PlayerItemDamageEvent.patch b/patches/unapplied/server/0691-Expand-PlayerItemDamageEvent.patch similarity index 100% rename from patches/unapplied/0691-Expand-PlayerItemDamageEvent.patch rename to patches/unapplied/server/0691-Expand-PlayerItemDamageEvent.patch diff --git a/patches/unapplied/0692-WorldCreator-keepSpawnLoaded.patch b/patches/unapplied/server/0692-WorldCreator-keepSpawnLoaded.patch similarity index 100% rename from patches/unapplied/0692-WorldCreator-keepSpawnLoaded.patch rename to patches/unapplied/server/0692-WorldCreator-keepSpawnLoaded.patch diff --git a/patches/unapplied/0693-Fix-CME-in-CraftPersistentDataTypeRegistry.patch b/patches/unapplied/server/0693-Fix-CME-in-CraftPersistentDataTypeRegistry.patch similarity index 100% rename from patches/unapplied/0693-Fix-CME-in-CraftPersistentDataTypeRegistry.patch rename to patches/unapplied/server/0693-Fix-CME-in-CraftPersistentDataTypeRegistry.patch diff --git a/patches/unapplied/0694-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch b/patches/unapplied/server/0694-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch similarity index 100% rename from patches/unapplied/0694-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch rename to patches/unapplied/server/0694-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch diff --git a/patches/unapplied/0695-Add-EntityDyeEvent-and-CollarColorable-interface.patch b/patches/unapplied/server/0695-Add-EntityDyeEvent-and-CollarColorable-interface.patch similarity index 100% rename from patches/unapplied/0695-Add-EntityDyeEvent-and-CollarColorable-interface.patch rename to patches/unapplied/server/0695-Add-EntityDyeEvent-and-CollarColorable-interface.patch diff --git a/patches/unapplied/0696-Fire-CauldronLevelChange-on-initial-fill.patch b/patches/unapplied/server/0696-Fire-CauldronLevelChange-on-initial-fill.patch similarity index 100% rename from patches/unapplied/0696-Fire-CauldronLevelChange-on-initial-fill.patch rename to patches/unapplied/server/0696-Fire-CauldronLevelChange-on-initial-fill.patch diff --git a/patches/unapplied/0697-fix-powder-snow-cauldrons-not-turning-to-water.patch b/patches/unapplied/server/0697-fix-powder-snow-cauldrons-not-turning-to-water.patch similarity index 100% rename from patches/unapplied/0697-fix-powder-snow-cauldrons-not-turning-to-water.patch rename to patches/unapplied/server/0697-fix-powder-snow-cauldrons-not-turning-to-water.patch diff --git a/patches/unapplied/0698-Add-PlayerStopUsingItemEvent.patch b/patches/unapplied/server/0698-Add-PlayerStopUsingItemEvent.patch similarity index 100% rename from patches/unapplied/0698-Add-PlayerStopUsingItemEvent.patch rename to patches/unapplied/server/0698-Add-PlayerStopUsingItemEvent.patch diff --git a/patches/unapplied/0699-Don-t-tick-markers.patch b/patches/unapplied/server/0699-Don-t-tick-markers.patch similarity index 100% rename from patches/unapplied/0699-Don-t-tick-markers.patch rename to patches/unapplied/server/0699-Don-t-tick-markers.patch diff --git a/patches/unapplied/0700-Expand-FallingBlock-API.patch b/patches/unapplied/server/0700-Expand-FallingBlock-API.patch similarity index 100% rename from patches/unapplied/0700-Expand-FallingBlock-API.patch rename to patches/unapplied/server/0700-Expand-FallingBlock-API.patch diff --git a/patches/unapplied/0701-Add-support-for-Proxy-Protocol.patch b/patches/unapplied/server/0701-Add-support-for-Proxy-Protocol.patch similarity index 100% rename from patches/unapplied/0701-Add-support-for-Proxy-Protocol.patch rename to patches/unapplied/server/0701-Add-support-for-Proxy-Protocol.patch diff --git a/patches/unapplied/0702-Fix-OfflinePlayer-getBedSpawnLocation.patch b/patches/unapplied/server/0702-Fix-OfflinePlayer-getBedSpawnLocation.patch similarity index 100% rename from patches/unapplied/0702-Fix-OfflinePlayer-getBedSpawnLocation.patch rename to patches/unapplied/server/0702-Fix-OfflinePlayer-getBedSpawnLocation.patch diff --git a/patches/unapplied/0703-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch b/patches/unapplied/server/0703-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch similarity index 100% rename from patches/unapplied/0703-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch rename to patches/unapplied/server/0703-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch diff --git a/patches/unapplied/0704-Sanitize-sent-BlockEntity-NBT.patch b/patches/unapplied/server/0704-Sanitize-sent-BlockEntity-NBT.patch similarity index 100% rename from patches/unapplied/0704-Sanitize-sent-BlockEntity-NBT.patch rename to patches/unapplied/server/0704-Sanitize-sent-BlockEntity-NBT.patch diff --git a/patches/unapplied/0705-Disable-component-selector-resolving-in-books-by-def.patch b/patches/unapplied/server/0705-Disable-component-selector-resolving-in-books-by-def.patch similarity index 100% rename from patches/unapplied/0705-Disable-component-selector-resolving-in-books-by-def.patch rename to patches/unapplied/server/0705-Disable-component-selector-resolving-in-books-by-def.patch diff --git a/patches/unapplied/0706-Prevent-entity-loading-causing-async-lookups.patch b/patches/unapplied/server/0706-Prevent-entity-loading-causing-async-lookups.patch similarity index 100% rename from patches/unapplied/0706-Prevent-entity-loading-causing-async-lookups.patch rename to patches/unapplied/server/0706-Prevent-entity-loading-causing-async-lookups.patch diff --git a/patches/unapplied/0707-Throw-exception-on-world-create-while-being-ticked.patch b/patches/unapplied/server/0707-Throw-exception-on-world-create-while-being-ticked.patch similarity index 100% rename from patches/unapplied/0707-Throw-exception-on-world-create-while-being-ticked.patch rename to patches/unapplied/server/0707-Throw-exception-on-world-create-while-being-ticked.patch diff --git a/patches/unapplied/0708-Dont-resent-entity-on-art-update.patch b/patches/unapplied/server/0708-Dont-resent-entity-on-art-update.patch similarity index 100% rename from patches/unapplied/0708-Dont-resent-entity-on-art-update.patch rename to patches/unapplied/server/0708-Dont-resent-entity-on-art-update.patch diff --git a/patches/unapplied/0709-Add-WardenAngerChangeEvent.patch b/patches/unapplied/server/0709-Add-WardenAngerChangeEvent.patch similarity index 100% rename from patches/unapplied/0709-Add-WardenAngerChangeEvent.patch rename to patches/unapplied/server/0709-Add-WardenAngerChangeEvent.patch diff --git a/patches/unapplied/0710-Add-option-for-strict-advancement-dimension-checks.patch b/patches/unapplied/server/0710-Add-option-for-strict-advancement-dimension-checks.patch similarity index 100% rename from patches/unapplied/0710-Add-option-for-strict-advancement-dimension-checks.patch rename to patches/unapplied/server/0710-Add-option-for-strict-advancement-dimension-checks.patch diff --git a/patches/unapplied/0711-Add-missing-important-BlockStateListPopulator-method.patch b/patches/unapplied/server/0711-Add-missing-important-BlockStateListPopulator-method.patch similarity index 100% rename from patches/unapplied/0711-Add-missing-important-BlockStateListPopulator-method.patch rename to patches/unapplied/server/0711-Add-missing-important-BlockStateListPopulator-method.patch diff --git a/patches/unapplied/0712-Nameable-Banner-API.patch b/patches/unapplied/server/0712-Nameable-Banner-API.patch similarity index 100% rename from patches/unapplied/0712-Nameable-Banner-API.patch rename to patches/unapplied/server/0712-Nameable-Banner-API.patch diff --git a/patches/unapplied/0713-Don-t-broadcast-messages-to-command-blocks.patch b/patches/unapplied/server/0713-Don-t-broadcast-messages-to-command-blocks.patch similarity index 100% rename from patches/unapplied/0713-Don-t-broadcast-messages-to-command-blocks.patch rename to patches/unapplied/server/0713-Don-t-broadcast-messages-to-command-blocks.patch diff --git a/patches/unapplied/0714-Prevent-empty-items-from-being-added-to-world.patch b/patches/unapplied/server/0714-Prevent-empty-items-from-being-added-to-world.patch similarity index 100% rename from patches/unapplied/0714-Prevent-empty-items-from-being-added-to-world.patch rename to patches/unapplied/server/0714-Prevent-empty-items-from-being-added-to-world.patch diff --git a/patches/unapplied/0715-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch b/patches/unapplied/server/0715-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch similarity index 100% rename from patches/unapplied/0715-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch rename to patches/unapplied/server/0715-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch diff --git a/patches/unapplied/0716-Add-Player-getFishHook.patch b/patches/unapplied/server/0716-Add-Player-getFishHook.patch similarity index 100% rename from patches/unapplied/0716-Add-Player-getFishHook.patch rename to patches/unapplied/server/0716-Add-Player-getFishHook.patch diff --git a/patches/unapplied/0717-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch b/patches/unapplied/server/0717-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch similarity index 100% rename from patches/unapplied/0717-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch rename to patches/unapplied/server/0717-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch diff --git a/patches/unapplied/0718-Add-various-missing-EntityDropItemEvent-calls.patch b/patches/unapplied/server/0718-Add-various-missing-EntityDropItemEvent-calls.patch similarity index 100% rename from patches/unapplied/0718-Add-various-missing-EntityDropItemEvent-calls.patch rename to patches/unapplied/server/0718-Add-various-missing-EntityDropItemEvent-calls.patch diff --git a/patches/unapplied/0719-Fix-Bee-flower-NPE.patch b/patches/unapplied/server/0719-Fix-Bee-flower-NPE.patch similarity index 100% rename from patches/unapplied/0719-Fix-Bee-flower-NPE.patch rename to patches/unapplied/server/0719-Fix-Bee-flower-NPE.patch diff --git a/patches/unapplied/0720-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch b/patches/unapplied/server/0720-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch similarity index 100% rename from patches/unapplied/0720-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch rename to patches/unapplied/server/0720-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch diff --git a/patches/unapplied/0721-More-Teleport-API.patch b/patches/unapplied/server/0721-More-Teleport-API.patch similarity index 100% rename from patches/unapplied/0721-More-Teleport-API.patch rename to patches/unapplied/server/0721-More-Teleport-API.patch diff --git a/patches/unapplied/0722-Add-EntityPortalReadyEvent.patch b/patches/unapplied/server/0722-Add-EntityPortalReadyEvent.patch similarity index 100% rename from patches/unapplied/0722-Add-EntityPortalReadyEvent.patch rename to patches/unapplied/server/0722-Add-EntityPortalReadyEvent.patch diff --git a/patches/unapplied/0723-Don-t-use-level-random-in-entity-constructors.patch b/patches/unapplied/server/0723-Don-t-use-level-random-in-entity-constructors.patch similarity index 100% rename from patches/unapplied/0723-Don-t-use-level-random-in-entity-constructors.patch rename to patches/unapplied/server/0723-Don-t-use-level-random-in-entity-constructors.patch diff --git a/patches/unapplied/0724-Send-block-entities-after-destroy-prediction.patch b/patches/unapplied/server/0724-Send-block-entities-after-destroy-prediction.patch similarity index 100% rename from patches/unapplied/0724-Send-block-entities-after-destroy-prediction.patch rename to patches/unapplied/server/0724-Send-block-entities-after-destroy-prediction.patch diff --git a/patches/unapplied/0725-Warn-on-plugins-accessing-faraway-chunks.patch b/patches/unapplied/server/0725-Warn-on-plugins-accessing-faraway-chunks.patch similarity index 100% rename from patches/unapplied/0725-Warn-on-plugins-accessing-faraway-chunks.patch rename to patches/unapplied/server/0725-Warn-on-plugins-accessing-faraway-chunks.patch diff --git a/patches/unapplied/0726-Custom-Chat-Completion-Suggestions-API.patch b/patches/unapplied/server/0726-Custom-Chat-Completion-Suggestions-API.patch similarity index 100% rename from patches/unapplied/0726-Custom-Chat-Completion-Suggestions-API.patch rename to patches/unapplied/server/0726-Custom-Chat-Completion-Suggestions-API.patch diff --git a/patches/unapplied/0727-Add-and-fix-missing-BlockFadeEvents.patch b/patches/unapplied/server/0727-Add-and-fix-missing-BlockFadeEvents.patch similarity index 100% rename from patches/unapplied/0727-Add-and-fix-missing-BlockFadeEvents.patch rename to patches/unapplied/server/0727-Add-and-fix-missing-BlockFadeEvents.patch diff --git a/patches/unapplied/0728-Collision-API.patch b/patches/unapplied/server/0728-Collision-API.patch similarity index 100% rename from patches/unapplied/0728-Collision-API.patch rename to patches/unapplied/server/0728-Collision-API.patch diff --git a/patches/unapplied/0729-Fix-suggest-command-message-for-brigadier-syntax-exc.patch b/patches/unapplied/server/0729-Fix-suggest-command-message-for-brigadier-syntax-exc.patch similarity index 100% rename from patches/unapplied/0729-Fix-suggest-command-message-for-brigadier-syntax-exc.patch rename to patches/unapplied/server/0729-Fix-suggest-command-message-for-brigadier-syntax-exc.patch diff --git a/patches/unapplied/0730-Block-Ticking-API.patch b/patches/unapplied/server/0730-Block-Ticking-API.patch similarity index 100% rename from patches/unapplied/0730-Block-Ticking-API.patch rename to patches/unapplied/server/0730-Block-Ticking-API.patch diff --git a/patches/unapplied/0731-Add-Velocity-IP-Forwarding-Support.patch b/patches/unapplied/server/0731-Add-Velocity-IP-Forwarding-Support.patch similarity index 100% rename from patches/unapplied/0731-Add-Velocity-IP-Forwarding-Support.patch rename to patches/unapplied/server/0731-Add-Velocity-IP-Forwarding-Support.patch diff --git a/patches/unapplied/0732-Add-NamespacedKey-biome-methods.patch b/patches/unapplied/server/0732-Add-NamespacedKey-biome-methods.patch similarity index 100% rename from patches/unapplied/0732-Add-NamespacedKey-biome-methods.patch rename to patches/unapplied/server/0732-Add-NamespacedKey-biome-methods.patch diff --git a/patches/unapplied/0733-Fix-plugin-loggers-on-server-shutdown.patch b/patches/unapplied/server/0733-Fix-plugin-loggers-on-server-shutdown.patch similarity index 100% rename from patches/unapplied/0733-Fix-plugin-loggers-on-server-shutdown.patch rename to patches/unapplied/server/0733-Fix-plugin-loggers-on-server-shutdown.patch diff --git a/patches/unapplied/0734-Stop-large-look-changes-from-crashing-the-server.patch b/patches/unapplied/server/0734-Stop-large-look-changes-from-crashing-the-server.patch similarity index 100% rename from patches/unapplied/0734-Stop-large-look-changes-from-crashing-the-server.patch rename to patches/unapplied/server/0734-Stop-large-look-changes-from-crashing-the-server.patch diff --git a/patches/unapplied/0735-Fire-EntityChangeBlockEvent-in-more-places.patch b/patches/unapplied/server/0735-Fire-EntityChangeBlockEvent-in-more-places.patch similarity index 100% rename from patches/unapplied/0735-Fire-EntityChangeBlockEvent-in-more-places.patch rename to patches/unapplied/server/0735-Fire-EntityChangeBlockEvent-in-more-places.patch diff --git a/patches/unapplied/0736-Missing-eating-regain-reason.patch b/patches/unapplied/server/0736-Missing-eating-regain-reason.patch similarity index 100% rename from patches/unapplied/0736-Missing-eating-regain-reason.patch rename to patches/unapplied/server/0736-Missing-eating-regain-reason.patch diff --git a/patches/unapplied/0737-Missing-effect-cause.patch b/patches/unapplied/server/0737-Missing-effect-cause.patch similarity index 100% rename from patches/unapplied/0737-Missing-effect-cause.patch rename to patches/unapplied/server/0737-Missing-effect-cause.patch diff --git a/patches/unapplied/0738-Added-byte-array-serialization-deserialization-for-P.patch b/patches/unapplied/server/0738-Added-byte-array-serialization-deserialization-for-P.patch similarity index 100% rename from patches/unapplied/0738-Added-byte-array-serialization-deserialization-for-P.patch rename to patches/unapplied/server/0738-Added-byte-array-serialization-deserialization-for-P.patch diff --git a/patches/unapplied/0739-Call-BlockPhysicsEvent-more-often.patch b/patches/unapplied/server/0739-Call-BlockPhysicsEvent-more-often.patch similarity index 100% rename from patches/unapplied/0739-Call-BlockPhysicsEvent-more-often.patch rename to patches/unapplied/server/0739-Call-BlockPhysicsEvent-more-often.patch diff --git a/patches/unapplied/0740-Configurable-chat-thread-limit.patch b/patches/unapplied/server/0740-Configurable-chat-thread-limit.patch similarity index 100% rename from patches/unapplied/0740-Configurable-chat-thread-limit.patch rename to patches/unapplied/server/0740-Configurable-chat-thread-limit.patch diff --git a/patches/unapplied/0741-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch b/patches/unapplied/server/0741-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch similarity index 100% rename from patches/unapplied/0741-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch rename to patches/unapplied/server/0741-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch diff --git a/patches/unapplied/0742-fix-Jigsaw-block-kicking-user.patch b/patches/unapplied/server/0742-fix-Jigsaw-block-kicking-user.patch similarity index 100% rename from patches/unapplied/0742-fix-Jigsaw-block-kicking-user.patch rename to patches/unapplied/server/0742-fix-Jigsaw-block-kicking-user.patch diff --git a/patches/unapplied/0743-use-BlockFormEvent-for-mud-converting-into-clay.patch b/patches/unapplied/server/0743-use-BlockFormEvent-for-mud-converting-into-clay.patch similarity index 100% rename from patches/unapplied/0743-use-BlockFormEvent-for-mud-converting-into-clay.patch rename to patches/unapplied/server/0743-use-BlockFormEvent-for-mud-converting-into-clay.patch diff --git a/patches/unapplied/0744-Add-getDrops-to-BlockState.patch b/patches/unapplied/server/0744-Add-getDrops-to-BlockState.patch similarity index 100% rename from patches/unapplied/0744-Add-getDrops-to-BlockState.patch rename to patches/unapplied/server/0744-Add-getDrops-to-BlockState.patch diff --git a/patches/unapplied/0745-Fix-a-bunch-of-vanilla-bugs.patch b/patches/unapplied/server/0745-Fix-a-bunch-of-vanilla-bugs.patch similarity index 100% rename from patches/unapplied/0745-Fix-a-bunch-of-vanilla-bugs.patch rename to patches/unapplied/server/0745-Fix-a-bunch-of-vanilla-bugs.patch diff --git a/patches/unapplied/0746-Remove-unnecessary-onTrackingStart-during-navigation.patch b/patches/unapplied/server/0746-Remove-unnecessary-onTrackingStart-during-navigation.patch similarity index 100% rename from patches/unapplied/0746-Remove-unnecessary-onTrackingStart-during-navigation.patch rename to patches/unapplied/server/0746-Remove-unnecessary-onTrackingStart-during-navigation.patch diff --git a/patches/unapplied/0747-Fix-custom-piglin-loved-items.patch b/patches/unapplied/server/0747-Fix-custom-piglin-loved-items.patch similarity index 100% rename from patches/unapplied/0747-Fix-custom-piglin-loved-items.patch rename to patches/unapplied/server/0747-Fix-custom-piglin-loved-items.patch diff --git a/patches/unapplied/0748-EntityPickupItemEvent-fixes.patch b/patches/unapplied/server/0748-EntityPickupItemEvent-fixes.patch similarity index 100% rename from patches/unapplied/0748-EntityPickupItemEvent-fixes.patch rename to patches/unapplied/server/0748-EntityPickupItemEvent-fixes.patch diff --git a/patches/unapplied/0749-Correctly-handle-interactions-with-items-on-cooldown.patch b/patches/unapplied/server/0749-Correctly-handle-interactions-with-items-on-cooldown.patch similarity index 100% rename from patches/unapplied/0749-Correctly-handle-interactions-with-items-on-cooldown.patch rename to patches/unapplied/server/0749-Correctly-handle-interactions-with-items-on-cooldown.patch diff --git a/patches/unapplied/0750-Add-PlayerInventorySlotChangeEvent.patch b/patches/unapplied/server/0750-Add-PlayerInventorySlotChangeEvent.patch similarity index 100% rename from patches/unapplied/0750-Add-PlayerInventorySlotChangeEvent.patch rename to patches/unapplied/server/0750-Add-PlayerInventorySlotChangeEvent.patch diff --git a/patches/unapplied/0751-Elder-Guardian-appearance-API.patch b/patches/unapplied/server/0751-Elder-Guardian-appearance-API.patch similarity index 100% rename from patches/unapplied/0751-Elder-Guardian-appearance-API.patch rename to patches/unapplied/server/0751-Elder-Guardian-appearance-API.patch diff --git a/patches/unapplied/0752-Add-entity-knockback-API.patch b/patches/unapplied/server/0752-Add-entity-knockback-API.patch similarity index 100% rename from patches/unapplied/0752-Add-entity-knockback-API.patch rename to patches/unapplied/server/0752-Add-entity-knockback-API.patch diff --git a/patches/unapplied/0753-Detect-headless-JREs.patch b/patches/unapplied/server/0753-Detect-headless-JREs.patch similarity index 100% rename from patches/unapplied/0753-Detect-headless-JREs.patch rename to patches/unapplied/server/0753-Detect-headless-JREs.patch diff --git a/patches/unapplied/0754-fix-entity-vehicle-collision-event-not-called.patch b/patches/unapplied/server/0754-fix-entity-vehicle-collision-event-not-called.patch similarity index 100% rename from patches/unapplied/0754-fix-entity-vehicle-collision-event-not-called.patch rename to patches/unapplied/server/0754-fix-entity-vehicle-collision-event-not-called.patch diff --git a/patches/unapplied/0755-Add-EntityToggleSitEvent.patch b/patches/unapplied/server/0755-Add-EntityToggleSitEvent.patch similarity index 100% rename from patches/unapplied/0755-Add-EntityToggleSitEvent.patch rename to patches/unapplied/server/0755-Add-EntityToggleSitEvent.patch diff --git a/patches/unapplied/0756-Add-fire-tick-delay-option.patch b/patches/unapplied/server/0756-Add-fire-tick-delay-option.patch similarity index 100% rename from patches/unapplied/0756-Add-fire-tick-delay-option.patch rename to patches/unapplied/server/0756-Add-fire-tick-delay-option.patch diff --git a/patches/unapplied/0757-Add-Moving-Piston-API.patch b/patches/unapplied/server/0757-Add-Moving-Piston-API.patch similarity index 100% rename from patches/unapplied/0757-Add-Moving-Piston-API.patch rename to patches/unapplied/server/0757-Add-Moving-Piston-API.patch diff --git a/patches/unapplied/0758-Ignore-impossible-spawn-tick.patch b/patches/unapplied/server/0758-Ignore-impossible-spawn-tick.patch similarity index 100% rename from patches/unapplied/0758-Ignore-impossible-spawn-tick.patch rename to patches/unapplied/server/0758-Ignore-impossible-spawn-tick.patch diff --git a/patches/unapplied/0759-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch b/patches/unapplied/server/0759-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch similarity index 100% rename from patches/unapplied/0759-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch rename to patches/unapplied/server/0759-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch diff --git a/patches/unapplied/0760-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch b/patches/unapplied/server/0760-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch similarity index 100% rename from patches/unapplied/0760-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch rename to patches/unapplied/server/0760-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch diff --git a/patches/unapplied/0761-Add-PrePlayerAttackEntityEvent.patch b/patches/unapplied/server/0761-Add-PrePlayerAttackEntityEvent.patch similarity index 100% rename from patches/unapplied/0761-Add-PrePlayerAttackEntityEvent.patch rename to patches/unapplied/server/0761-Add-PrePlayerAttackEntityEvent.patch diff --git a/patches/unapplied/0762-ensure-reset-EnderDragon-boss-event-name.patch b/patches/unapplied/server/0762-ensure-reset-EnderDragon-boss-event-name.patch similarity index 100% rename from patches/unapplied/0762-ensure-reset-EnderDragon-boss-event-name.patch rename to patches/unapplied/server/0762-ensure-reset-EnderDragon-boss-event-name.patch diff --git a/patches/unapplied/0763-Add-Player-Warden-Warning-API.patch b/patches/unapplied/server/0763-Add-Player-Warden-Warning-API.patch similarity index 100% rename from patches/unapplied/0763-Add-Player-Warden-Warning-API.patch rename to patches/unapplied/server/0763-Add-Player-Warden-Warning-API.patch diff --git a/patches/unapplied/0764-More-vanilla-friendly-methods-to-update-trades.patch b/patches/unapplied/server/0764-More-vanilla-friendly-methods-to-update-trades.patch similarity index 100% rename from patches/unapplied/0764-More-vanilla-friendly-methods-to-update-trades.patch rename to patches/unapplied/server/0764-More-vanilla-friendly-methods-to-update-trades.patch diff --git a/patches/unapplied/0765-Add-paper-dumplisteners-command.patch b/patches/unapplied/server/0765-Add-paper-dumplisteners-command.patch similarity index 100% rename from patches/unapplied/0765-Add-paper-dumplisteners-command.patch rename to patches/unapplied/server/0765-Add-paper-dumplisteners-command.patch diff --git a/patches/unapplied/0766-check-global-player-list-where-appropriate.patch b/patches/unapplied/server/0766-check-global-player-list-where-appropriate.patch similarity index 100% rename from patches/unapplied/0766-check-global-player-list-where-appropriate.patch rename to patches/unapplied/server/0766-check-global-player-list-where-appropriate.patch diff --git a/patches/unapplied/0767-Fix-async-entity-add-due-to-fungus-trees.patch b/patches/unapplied/server/0767-Fix-async-entity-add-due-to-fungus-trees.patch similarity index 100% rename from patches/unapplied/0767-Fix-async-entity-add-due-to-fungus-trees.patch rename to patches/unapplied/server/0767-Fix-async-entity-add-due-to-fungus-trees.patch diff --git a/patches/unapplied/0768-ItemStack-damage-API.patch b/patches/unapplied/server/0768-ItemStack-damage-API.patch similarity index 100% rename from patches/unapplied/0768-ItemStack-damage-API.patch rename to patches/unapplied/server/0768-ItemStack-damage-API.patch diff --git a/patches/unapplied/0769-Friction-API.patch b/patches/unapplied/server/0769-Friction-API.patch similarity index 100% rename from patches/unapplied/0769-Friction-API.patch rename to patches/unapplied/server/0769-Friction-API.patch diff --git a/patches/unapplied/0770-Ability-to-control-player-s-insomnia-and-phantoms.patch b/patches/unapplied/server/0770-Ability-to-control-player-s-insomnia-and-phantoms.patch similarity index 100% rename from patches/unapplied/0770-Ability-to-control-player-s-insomnia-and-phantoms.patch rename to patches/unapplied/server/0770-Ability-to-control-player-s-insomnia-and-phantoms.patch diff --git a/patches/unapplied/0771-Fix-premature-player-kicks-on-shutdown.patch b/patches/unapplied/server/0771-Fix-premature-player-kicks-on-shutdown.patch similarity index 100% rename from patches/unapplied/0771-Fix-premature-player-kicks-on-shutdown.patch rename to patches/unapplied/server/0771-Fix-premature-player-kicks-on-shutdown.patch diff --git a/patches/unapplied/0772-Sync-offhand-slot-in-menus.patch b/patches/unapplied/server/0772-Sync-offhand-slot-in-menus.patch similarity index 100% rename from patches/unapplied/0772-Sync-offhand-slot-in-menus.patch rename to patches/unapplied/server/0772-Sync-offhand-slot-in-menus.patch diff --git a/patches/unapplied/0773-Player-Entity-Tracking-Events.patch b/patches/unapplied/server/0773-Player-Entity-Tracking-Events.patch similarity index 100% rename from patches/unapplied/0773-Player-Entity-Tracking-Events.patch rename to patches/unapplied/server/0773-Player-Entity-Tracking-Events.patch diff --git a/patches/unapplied/0774-Limit-pet-look-distance.patch b/patches/unapplied/server/0774-Limit-pet-look-distance.patch similarity index 100% rename from patches/unapplied/0774-Limit-pet-look-distance.patch rename to patches/unapplied/server/0774-Limit-pet-look-distance.patch diff --git a/patches/unapplied/0775-fix-Instruments.patch b/patches/unapplied/server/0775-fix-Instruments.patch similarity index 100% rename from patches/unapplied/0775-fix-Instruments.patch rename to patches/unapplied/server/0775-fix-Instruments.patch diff --git a/patches/unapplied/0776-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch b/patches/unapplied/server/0776-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch similarity index 100% rename from patches/unapplied/0776-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch rename to patches/unapplied/server/0776-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch diff --git a/patches/unapplied/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch b/patches/unapplied/server/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch similarity index 100% rename from patches/unapplied/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch rename to patches/unapplied/server/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch diff --git a/patches/unapplied/0778-Add-BlockLockCheckEvent.patch b/patches/unapplied/server/0778-Add-BlockLockCheckEvent.patch similarity index 100% rename from patches/unapplied/0778-Add-BlockLockCheckEvent.patch rename to patches/unapplied/server/0778-Add-BlockLockCheckEvent.patch diff --git a/patches/unapplied/0779-Add-Sneaking-API-for-Entities.patch b/patches/unapplied/server/0779-Add-Sneaking-API-for-Entities.patch similarity index 100% rename from patches/unapplied/0779-Add-Sneaking-API-for-Entities.patch rename to patches/unapplied/server/0779-Add-Sneaking-API-for-Entities.patch diff --git a/patches/unapplied/0780-Improve-logging-and-errors.patch b/patches/unapplied/server/0780-Improve-logging-and-errors.patch similarity index 100% rename from patches/unapplied/0780-Improve-logging-and-errors.patch rename to patches/unapplied/server/0780-Improve-logging-and-errors.patch diff --git a/patches/unapplied/0781-Improve-PortalEvents.patch b/patches/unapplied/server/0781-Improve-PortalEvents.patch similarity index 100% rename from patches/unapplied/0781-Improve-PortalEvents.patch rename to patches/unapplied/server/0781-Improve-PortalEvents.patch diff --git a/patches/unapplied/0782-Add-config-option-for-spider-worldborder-climbing.patch b/patches/unapplied/server/0782-Add-config-option-for-spider-worldborder-climbing.patch similarity index 100% rename from patches/unapplied/0782-Add-config-option-for-spider-worldborder-climbing.patch rename to patches/unapplied/server/0782-Add-config-option-for-spider-worldborder-climbing.patch diff --git a/patches/unapplied/0783-Add-missing-SpigotConfig-logCommands-check.patch b/patches/unapplied/server/0783-Add-missing-SpigotConfig-logCommands-check.patch similarity index 100% rename from patches/unapplied/0783-Add-missing-SpigotConfig-logCommands-check.patch rename to patches/unapplied/server/0783-Add-missing-SpigotConfig-logCommands-check.patch diff --git a/patches/unapplied/0784-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch b/patches/unapplied/server/0784-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch similarity index 100% rename from patches/unapplied/0784-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch rename to patches/unapplied/server/0784-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch diff --git a/patches/unapplied/0785-Flying-Fall-Damage.patch b/patches/unapplied/server/0785-Flying-Fall-Damage.patch similarity index 100% rename from patches/unapplied/0785-Flying-Fall-Damage.patch rename to patches/unapplied/server/0785-Flying-Fall-Damage.patch diff --git a/patches/unapplied/0786-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch b/patches/unapplied/server/0786-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch similarity index 100% rename from patches/unapplied/0786-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch rename to patches/unapplied/server/0786-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch diff --git a/patches/unapplied/0787-config-for-disabling-entity-tag-tags.patch b/patches/unapplied/server/0787-config-for-disabling-entity-tag-tags.patch similarity index 100% rename from patches/unapplied/0787-config-for-disabling-entity-tag-tags.patch rename to patches/unapplied/server/0787-config-for-disabling-entity-tag-tags.patch diff --git a/patches/unapplied/0788-Use-single-player-info-update-packet-on-join.patch b/patches/unapplied/server/0788-Use-single-player-info-update-packet-on-join.patch similarity index 100% rename from patches/unapplied/0788-Use-single-player-info-update-packet-on-join.patch rename to patches/unapplied/server/0788-Use-single-player-info-update-packet-on-join.patch diff --git a/patches/unapplied/0789-Correctly-shrink-items-during-EntityResurrectEvent.patch b/patches/unapplied/server/0789-Correctly-shrink-items-during-EntityResurrectEvent.patch similarity index 100% rename from patches/unapplied/0789-Correctly-shrink-items-during-EntityResurrectEvent.patch rename to patches/unapplied/server/0789-Correctly-shrink-items-during-EntityResurrectEvent.patch diff --git a/patches/unapplied/0790-Win-Screen-API.patch b/patches/unapplied/server/0790-Win-Screen-API.patch similarity index 100% rename from patches/unapplied/0790-Win-Screen-API.patch rename to patches/unapplied/server/0790-Win-Screen-API.patch diff --git a/patches/unapplied/0791-Remove-CraftItemStack-setAmount-null-assignment.patch b/patches/unapplied/server/0791-Remove-CraftItemStack-setAmount-null-assignment.patch similarity index 100% rename from patches/unapplied/0791-Remove-CraftItemStack-setAmount-null-assignment.patch rename to patches/unapplied/server/0791-Remove-CraftItemStack-setAmount-null-assignment.patch diff --git a/patches/unapplied/0792-Fix-force-opening-enchantment-tables.patch b/patches/unapplied/server/0792-Fix-force-opening-enchantment-tables.patch similarity index 100% rename from patches/unapplied/0792-Fix-force-opening-enchantment-tables.patch rename to patches/unapplied/server/0792-Fix-force-opening-enchantment-tables.patch diff --git a/patches/unapplied/0793-Add-Entity-Body-Yaw-API.patch b/patches/unapplied/server/0793-Add-Entity-Body-Yaw-API.patch similarity index 100% rename from patches/unapplied/0793-Add-Entity-Body-Yaw-API.patch rename to patches/unapplied/server/0793-Add-Entity-Body-Yaw-API.patch diff --git a/patches/unapplied/0794-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch b/patches/unapplied/server/0794-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch similarity index 100% rename from patches/unapplied/0794-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch rename to patches/unapplied/server/0794-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch diff --git a/patches/unapplied/0795-Add-EntityFertilizeEggEvent.patch b/patches/unapplied/server/0795-Add-EntityFertilizeEggEvent.patch similarity index 100% rename from patches/unapplied/0795-Add-EntityFertilizeEggEvent.patch rename to patches/unapplied/server/0795-Add-EntityFertilizeEggEvent.patch diff --git a/patches/unapplied/0796-Fix-HumanEntity-drop-not-updating-the-client-inv.patch b/patches/unapplied/server/0796-Fix-HumanEntity-drop-not-updating-the-client-inv.patch similarity index 100% rename from patches/unapplied/0796-Fix-HumanEntity-drop-not-updating-the-client-inv.patch rename to patches/unapplied/server/0796-Fix-HumanEntity-drop-not-updating-the-client-inv.patch diff --git a/patches/unapplied/0797-Add-CompostItemEvent-and-EntityCompostItemEvent.patch b/patches/unapplied/server/0797-Add-CompostItemEvent-and-EntityCompostItemEvent.patch similarity index 100% rename from patches/unapplied/0797-Add-CompostItemEvent-and-EntityCompostItemEvent.patch rename to patches/unapplied/server/0797-Add-CompostItemEvent-and-EntityCompostItemEvent.patch diff --git a/patches/unapplied/0798-Correctly-handle-ArmorStand-invisibility.patch b/patches/unapplied/server/0798-Correctly-handle-ArmorStand-invisibility.patch similarity index 100% rename from patches/unapplied/0798-Correctly-handle-ArmorStand-invisibility.patch rename to patches/unapplied/server/0798-Correctly-handle-ArmorStand-invisibility.patch diff --git a/patches/unapplied/0799-Fix-advancement-triggers-for-entity-damage.patch b/patches/unapplied/server/0799-Fix-advancement-triggers-for-entity-damage.patch similarity index 100% rename from patches/unapplied/0799-Fix-advancement-triggers-for-entity-damage.patch rename to patches/unapplied/server/0799-Fix-advancement-triggers-for-entity-damage.patch diff --git a/patches/unapplied/0800-Fix-text-display-error-on-spawn.patch b/patches/unapplied/server/0800-Fix-text-display-error-on-spawn.patch similarity index 100% rename from patches/unapplied/0800-Fix-text-display-error-on-spawn.patch rename to patches/unapplied/server/0800-Fix-text-display-error-on-spawn.patch diff --git a/patches/unapplied/0801-Fix-inventories-returning-null-Locations.patch b/patches/unapplied/server/0801-Fix-inventories-returning-null-Locations.patch similarity index 100% rename from patches/unapplied/0801-Fix-inventories-returning-null-Locations.patch rename to patches/unapplied/server/0801-Fix-inventories-returning-null-Locations.patch diff --git a/patches/unapplied/0802-Add-Shearable-API.patch b/patches/unapplied/server/0802-Add-Shearable-API.patch similarity index 100% rename from patches/unapplied/0802-Add-Shearable-API.patch rename to patches/unapplied/server/0802-Add-Shearable-API.patch diff --git a/patches/unapplied/0803-Fix-SpawnEggMeta-get-setSpawnedType.patch b/patches/unapplied/server/0803-Fix-SpawnEggMeta-get-setSpawnedType.patch similarity index 100% rename from patches/unapplied/0803-Fix-SpawnEggMeta-get-setSpawnedType.patch rename to patches/unapplied/server/0803-Fix-SpawnEggMeta-get-setSpawnedType.patch diff --git a/patches/unapplied/0804-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch b/patches/unapplied/server/0804-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch similarity index 100% rename from patches/unapplied/0804-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch rename to patches/unapplied/server/0804-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch diff --git a/patches/unapplied/0805-Treat-sequence-violations-like-they-should-be.patch b/patches/unapplied/server/0805-Treat-sequence-violations-like-they-should-be.patch similarity index 100% rename from patches/unapplied/0805-Treat-sequence-violations-like-they-should-be.patch rename to patches/unapplied/server/0805-Treat-sequence-violations-like-they-should-be.patch diff --git a/patches/unapplied/0806-Prevent-causing-expired-keys-from-impacting-new-join.patch b/patches/unapplied/server/0806-Prevent-causing-expired-keys-from-impacting-new-join.patch similarity index 100% rename from patches/unapplied/0806-Prevent-causing-expired-keys-from-impacting-new-join.patch rename to patches/unapplied/server/0806-Prevent-causing-expired-keys-from-impacting-new-join.patch diff --git a/patches/unapplied/0807-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch b/patches/unapplied/server/0807-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch similarity index 100% rename from patches/unapplied/0807-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch rename to patches/unapplied/server/0807-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch diff --git a/patches/unapplied/0808-Use-array-for-gamerule-storage.patch b/patches/unapplied/server/0808-Use-array-for-gamerule-storage.patch similarity index 100% rename from patches/unapplied/0808-Use-array-for-gamerule-storage.patch rename to patches/unapplied/server/0808-Use-array-for-gamerule-storage.patch diff --git a/patches/unapplied/0809-Fix-a-couple-of-upstream-bed-issues.patch b/patches/unapplied/server/0809-Fix-a-couple-of-upstream-bed-issues.patch similarity index 100% rename from patches/unapplied/0809-Fix-a-couple-of-upstream-bed-issues.patch rename to patches/unapplied/server/0809-Fix-a-couple-of-upstream-bed-issues.patch diff --git a/patches/unapplied/0810-Fix-demo-flag-not-enabling-demo-mode.patch b/patches/unapplied/server/0810-Fix-demo-flag-not-enabling-demo-mode.patch similarity index 100% rename from patches/unapplied/0810-Fix-demo-flag-not-enabling-demo-mode.patch rename to patches/unapplied/server/0810-Fix-demo-flag-not-enabling-demo-mode.patch diff --git a/patches/unapplied/0811-Add-Mob-Experience-reward-API.patch b/patches/unapplied/server/0811-Add-Mob-Experience-reward-API.patch similarity index 100% rename from patches/unapplied/0811-Add-Mob-Experience-reward-API.patch rename to patches/unapplied/server/0811-Add-Mob-Experience-reward-API.patch diff --git a/patches/unapplied/0812-Break-redstone-on-top-of-trap-doors-early.patch b/patches/unapplied/server/0812-Break-redstone-on-top-of-trap-doors-early.patch similarity index 100% rename from patches/unapplied/0812-Break-redstone-on-top-of-trap-doors-early.patch rename to patches/unapplied/server/0812-Break-redstone-on-top-of-trap-doors-early.patch diff --git a/patches/unapplied/0813-Avoid-Lazy-Initialization-for-Enum-Fields.patch b/patches/unapplied/server/0813-Avoid-Lazy-Initialization-for-Enum-Fields.patch similarity index 100% rename from patches/unapplied/0813-Avoid-Lazy-Initialization-for-Enum-Fields.patch rename to patches/unapplied/server/0813-Avoid-Lazy-Initialization-for-Enum-Fields.patch diff --git a/patches/unapplied/0814-More-accurate-isInOpenWater-impl.patch b/patches/unapplied/server/0814-More-accurate-isInOpenWater-impl.patch similarity index 100% rename from patches/unapplied/0814-More-accurate-isInOpenWater-impl.patch rename to patches/unapplied/server/0814-More-accurate-isInOpenWater-impl.patch diff --git a/patches/unapplied/0815-Expand-PlayerItemMendEvent.patch b/patches/unapplied/server/0815-Expand-PlayerItemMendEvent.patch similarity index 100% rename from patches/unapplied/0815-Expand-PlayerItemMendEvent.patch rename to patches/unapplied/server/0815-Expand-PlayerItemMendEvent.patch diff --git a/patches/unapplied/0816-Refresh-ProjectileSource-for-projectiles.patch b/patches/unapplied/server/0816-Refresh-ProjectileSource-for-projectiles.patch similarity index 100% rename from patches/unapplied/0816-Refresh-ProjectileSource-for-projectiles.patch rename to patches/unapplied/server/0816-Refresh-ProjectileSource-for-projectiles.patch diff --git a/patches/unapplied/0817-Add-transient-modifier-API.patch b/patches/unapplied/server/0817-Add-transient-modifier-API.patch similarity index 100% rename from patches/unapplied/0817-Add-transient-modifier-API.patch rename to patches/unapplied/server/0817-Add-transient-modifier-API.patch diff --git a/patches/unapplied/0818-Fix-block-place-logic.patch b/patches/unapplied/server/0818-Fix-block-place-logic.patch similarity index 100% rename from patches/unapplied/0818-Fix-block-place-logic.patch rename to patches/unapplied/server/0818-Fix-block-place-logic.patch diff --git a/patches/unapplied/0819-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch b/patches/unapplied/server/0819-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch similarity index 100% rename from patches/unapplied/0819-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch rename to patches/unapplied/server/0819-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch diff --git a/patches/unapplied/0820-Call-BlockGrowEvent-for-missing-blocks.patch b/patches/unapplied/server/0820-Call-BlockGrowEvent-for-missing-blocks.patch similarity index 100% rename from patches/unapplied/0820-Call-BlockGrowEvent-for-missing-blocks.patch rename to patches/unapplied/server/0820-Call-BlockGrowEvent-for-missing-blocks.patch diff --git a/patches/unapplied/0821-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch b/patches/unapplied/server/0821-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch similarity index 100% rename from patches/unapplied/0821-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch rename to patches/unapplied/server/0821-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch diff --git a/patches/unapplied/0822-fix-MapLike-spam-for-missing-key-selector.patch b/patches/unapplied/server/0822-fix-MapLike-spam-for-missing-key-selector.patch similarity index 100% rename from patches/unapplied/0822-fix-MapLike-spam-for-missing-key-selector.patch rename to patches/unapplied/server/0822-fix-MapLike-spam-for-missing-key-selector.patch diff --git a/patches/unapplied/0823-Fix-sniffer-removeExploredLocation.patch b/patches/unapplied/server/0823-Fix-sniffer-removeExploredLocation.patch similarity index 100% rename from patches/unapplied/0823-Fix-sniffer-removeExploredLocation.patch rename to patches/unapplied/server/0823-Fix-sniffer-removeExploredLocation.patch diff --git a/patches/unapplied/0824-Add-method-to-remove-all-active-potion-effects.patch b/patches/unapplied/server/0824-Add-method-to-remove-all-active-potion-effects.patch similarity index 100% rename from patches/unapplied/0824-Add-method-to-remove-all-active-potion-effects.patch rename to patches/unapplied/server/0824-Add-method-to-remove-all-active-potion-effects.patch diff --git a/patches/unapplied/0825-Fix-incorrect-crafting-result-amount-for-fireworks.patch b/patches/unapplied/server/0825-Fix-incorrect-crafting-result-amount-for-fireworks.patch similarity index 100% rename from patches/unapplied/0825-Fix-incorrect-crafting-result-amount-for-fireworks.patch rename to patches/unapplied/server/0825-Fix-incorrect-crafting-result-amount-for-fireworks.patch diff --git a/patches/unapplied/0826-Add-event-for-player-editing-sign.patch b/patches/unapplied/server/0826-Add-event-for-player-editing-sign.patch similarity index 100% rename from patches/unapplied/0826-Add-event-for-player-editing-sign.patch rename to patches/unapplied/server/0826-Add-event-for-player-editing-sign.patch diff --git a/patches/unapplied/0827-Only-tick-item-frames-if-players-can-see-it.patch b/patches/unapplied/server/0827-Only-tick-item-frames-if-players-can-see-it.patch similarity index 100% rename from patches/unapplied/0827-Only-tick-item-frames-if-players-can-see-it.patch rename to patches/unapplied/server/0827-Only-tick-item-frames-if-players-can-see-it.patch diff --git a/patches/unapplied/0828-Fix-cmd-permission-levels-for-command-blocks.patch b/patches/unapplied/server/0828-Fix-cmd-permission-levels-for-command-blocks.patch similarity index 100% rename from patches/unapplied/0828-Fix-cmd-permission-levels-for-command-blocks.patch rename to patches/unapplied/server/0828-Fix-cmd-permission-levels-for-command-blocks.patch diff --git a/patches/unapplied/0829-Add-option-to-disable-block-updates.patch b/patches/unapplied/server/0829-Add-option-to-disable-block-updates.patch similarity index 100% rename from patches/unapplied/0829-Add-option-to-disable-block-updates.patch rename to patches/unapplied/server/0829-Add-option-to-disable-block-updates.patch diff --git a/patches/unapplied/0830-Call-missing-BlockDispenseEvent.patch b/patches/unapplied/server/0830-Call-missing-BlockDispenseEvent.patch similarity index 100% rename from patches/unapplied/0830-Call-missing-BlockDispenseEvent.patch rename to patches/unapplied/server/0830-Call-missing-BlockDispenseEvent.patch diff --git a/patches/unapplied/0831-Don-t-load-chunks-for-supporting-block-checks.patch b/patches/unapplied/server/0831-Don-t-load-chunks-for-supporting-block-checks.patch similarity index 100% rename from patches/unapplied/0831-Don-t-load-chunks-for-supporting-block-checks.patch rename to patches/unapplied/server/0831-Don-t-load-chunks-for-supporting-block-checks.patch diff --git a/patches/unapplied/0832-Optimize-player-lookups-for-beacons.patch b/patches/unapplied/server/0832-Optimize-player-lookups-for-beacons.patch similarity index 100% rename from patches/unapplied/0832-Optimize-player-lookups-for-beacons.patch rename to patches/unapplied/server/0832-Optimize-player-lookups-for-beacons.patch diff --git a/patches/unapplied/0833-More-Sign-Block-API.patch b/patches/unapplied/server/0833-More-Sign-Block-API.patch similarity index 100% rename from patches/unapplied/0833-More-Sign-Block-API.patch rename to patches/unapplied/server/0833-More-Sign-Block-API.patch diff --git a/patches/unapplied/0834-fix-item-meta-for-tadpole-buckets.patch b/patches/unapplied/server/0834-fix-item-meta-for-tadpole-buckets.patch similarity index 100% rename from patches/unapplied/0834-fix-item-meta-for-tadpole-buckets.patch rename to patches/unapplied/server/0834-fix-item-meta-for-tadpole-buckets.patch diff --git a/patches/unapplied/0835-Fix-BanList-API.patch b/patches/unapplied/server/0835-Fix-BanList-API.patch similarity index 100% rename from patches/unapplied/0835-Fix-BanList-API.patch rename to patches/unapplied/server/0835-Fix-BanList-API.patch diff --git a/patches/unapplied/0836-Determine-lava-and-water-fluid-explosion-resistance-.patch b/patches/unapplied/server/0836-Determine-lava-and-water-fluid-explosion-resistance-.patch similarity index 100% rename from patches/unapplied/0836-Determine-lava-and-water-fluid-explosion-resistance-.patch rename to patches/unapplied/server/0836-Determine-lava-and-water-fluid-explosion-resistance-.patch diff --git a/patches/unapplied/0837-Fix-possible-NPE-on-painting-creation.patch b/patches/unapplied/server/0837-Fix-possible-NPE-on-painting-creation.patch similarity index 100% rename from patches/unapplied/0837-Fix-possible-NPE-on-painting-creation.patch rename to patches/unapplied/server/0837-Fix-possible-NPE-on-painting-creation.patch diff --git a/patches/unapplied/0838-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch b/patches/unapplied/server/0838-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch similarity index 100% rename from patches/unapplied/0838-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch rename to patches/unapplied/server/0838-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch diff --git a/patches/unapplied/0839-ExperienceOrb-should-call-EntitySpawnEvent.patch b/patches/unapplied/server/0839-ExperienceOrb-should-call-EntitySpawnEvent.patch similarity index 100% rename from patches/unapplied/0839-ExperienceOrb-should-call-EntitySpawnEvent.patch rename to patches/unapplied/server/0839-ExperienceOrb-should-call-EntitySpawnEvent.patch diff --git a/patches/unapplied/0840-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch b/patches/unapplied/server/0840-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch similarity index 100% rename from patches/unapplied/0840-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch rename to patches/unapplied/server/0840-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch diff --git a/patches/unapplied/0841-Add-whitelist-events.patch b/patches/unapplied/server/0841-Add-whitelist-events.patch similarity index 100% rename from patches/unapplied/0841-Add-whitelist-events.patch rename to patches/unapplied/server/0841-Add-whitelist-events.patch diff --git a/patches/unapplied/0842-Implement-PlayerFailMoveEvent.patch b/patches/unapplied/server/0842-Implement-PlayerFailMoveEvent.patch similarity index 100% rename from patches/unapplied/0842-Implement-PlayerFailMoveEvent.patch rename to patches/unapplied/server/0842-Implement-PlayerFailMoveEvent.patch diff --git a/patches/unapplied/0843-Folia-scheduler-and-owned-region-API.patch b/patches/unapplied/server/0843-Folia-scheduler-and-owned-region-API.patch similarity index 100% rename from patches/unapplied/0843-Folia-scheduler-and-owned-region-API.patch rename to patches/unapplied/server/0843-Folia-scheduler-and-owned-region-API.patch diff --git a/patches/unapplied/0844-Only-erase-allay-memory-on-non-item-targets.patch b/patches/unapplied/server/0844-Only-erase-allay-memory-on-non-item-targets.patch similarity index 100% rename from patches/unapplied/0844-Only-erase-allay-memory-on-non-item-targets.patch rename to patches/unapplied/server/0844-Only-erase-allay-memory-on-non-item-targets.patch diff --git a/patches/unapplied/0845-API-for-updating-recipes-on-clients.patch b/patches/unapplied/server/0845-API-for-updating-recipes-on-clients.patch similarity index 100% rename from patches/unapplied/0845-API-for-updating-recipes-on-clients.patch rename to patches/unapplied/server/0845-API-for-updating-recipes-on-clients.patch diff --git a/patches/unapplied/0846-Fix-rotation-when-spawning-display-entities.patch b/patches/unapplied/server/0846-Fix-rotation-when-spawning-display-entities.patch similarity index 100% rename from patches/unapplied/0846-Fix-rotation-when-spawning-display-entities.patch rename to patches/unapplied/server/0846-Fix-rotation-when-spawning-display-entities.patch diff --git a/patches/unapplied/0847-Only-capture-actual-tree-growth.patch b/patches/unapplied/server/0847-Only-capture-actual-tree-growth.patch similarity index 100% rename from patches/unapplied/0847-Only-capture-actual-tree-growth.patch rename to patches/unapplied/server/0847-Only-capture-actual-tree-growth.patch diff --git a/patches/unapplied/0848-Use-correct-source-for-mushroom-block-spread-event.patch b/patches/unapplied/server/0848-Use-correct-source-for-mushroom-block-spread-event.patch similarity index 100% rename from patches/unapplied/0848-Use-correct-source-for-mushroom-block-spread-event.patch rename to patches/unapplied/server/0848-Use-correct-source-for-mushroom-block-spread-event.patch diff --git a/patches/unapplied/0849-Respect-randomizeData-on-more-entities-when-spawning.patch b/patches/unapplied/server/0849-Respect-randomizeData-on-more-entities-when-spawning.patch similarity index 100% rename from patches/unapplied/0849-Respect-randomizeData-on-more-entities-when-spawning.patch rename to patches/unapplied/server/0849-Respect-randomizeData-on-more-entities-when-spawning.patch diff --git a/patches/unapplied/0850-Use-correct-seed-on-api-world-load.patch b/patches/unapplied/server/0850-Use-correct-seed-on-api-world-load.patch similarity index 100% rename from patches/unapplied/0850-Use-correct-seed-on-api-world-load.patch rename to patches/unapplied/server/0850-Use-correct-seed-on-api-world-load.patch diff --git a/patches/unapplied/0851-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch b/patches/unapplied/server/0851-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch similarity index 100% rename from patches/unapplied/0851-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch rename to patches/unapplied/server/0851-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch diff --git a/patches/unapplied/0852-Cache-map-ids-on-item-frames.patch b/patches/unapplied/server/0852-Cache-map-ids-on-item-frames.patch similarity index 100% rename from patches/unapplied/0852-Cache-map-ids-on-item-frames.patch rename to patches/unapplied/server/0852-Cache-map-ids-on-item-frames.patch diff --git a/patches/unapplied/0853-Fix-custom-statistic-criteria-creation.patch b/patches/unapplied/server/0853-Fix-custom-statistic-criteria-creation.patch similarity index 100% rename from patches/unapplied/0853-Fix-custom-statistic-criteria-creation.patch rename to patches/unapplied/server/0853-Fix-custom-statistic-criteria-creation.patch diff --git a/patches/unapplied/0854-Bandaid-fix-for-Effect.patch b/patches/unapplied/server/0854-Bandaid-fix-for-Effect.patch similarity index 100% rename from patches/unapplied/0854-Bandaid-fix-for-Effect.patch rename to patches/unapplied/server/0854-Bandaid-fix-for-Effect.patch diff --git a/patches/unapplied/0855-SculkCatalyst-bloom-API.patch b/patches/unapplied/server/0855-SculkCatalyst-bloom-API.patch similarity index 100% rename from patches/unapplied/0855-SculkCatalyst-bloom-API.patch rename to patches/unapplied/server/0855-SculkCatalyst-bloom-API.patch diff --git a/patches/unapplied/0856-API-for-an-entity-s-scoreboard-name.patch b/patches/unapplied/server/0856-API-for-an-entity-s-scoreboard-name.patch similarity index 100% rename from patches/unapplied/0856-API-for-an-entity-s-scoreboard-name.patch rename to patches/unapplied/server/0856-API-for-an-entity-s-scoreboard-name.patch diff --git a/patches/unapplied/0857-Deprecate-and-replace-methods-with-old-StructureType.patch b/patches/unapplied/server/0857-Deprecate-and-replace-methods-with-old-StructureType.patch similarity index 100% rename from patches/unapplied/0857-Deprecate-and-replace-methods-with-old-StructureType.patch rename to patches/unapplied/server/0857-Deprecate-and-replace-methods-with-old-StructureType.patch diff --git a/patches/unapplied/0858-Don-t-tab-complete-namespaced-commands-if-send-names.patch b/patches/unapplied/server/0858-Don-t-tab-complete-namespaced-commands-if-send-names.patch similarity index 100% rename from patches/unapplied/0858-Don-t-tab-complete-namespaced-commands-if-send-names.patch rename to patches/unapplied/server/0858-Don-t-tab-complete-namespaced-commands-if-send-names.patch diff --git a/patches/unapplied/0859-Properly-handle-BlockBreakEvent-isDropItems.patch b/patches/unapplied/server/0859-Properly-handle-BlockBreakEvent-isDropItems.patch similarity index 100% rename from patches/unapplied/0859-Properly-handle-BlockBreakEvent-isDropItems.patch rename to patches/unapplied/server/0859-Properly-handle-BlockBreakEvent-isDropItems.patch diff --git a/patches/unapplied/0860-Fire-entity-death-event-for-ender-dragon.patch b/patches/unapplied/server/0860-Fire-entity-death-event-for-ender-dragon.patch similarity index 100% rename from patches/unapplied/0860-Fire-entity-death-event-for-ender-dragon.patch rename to patches/unapplied/server/0860-Fire-entity-death-event-for-ender-dragon.patch diff --git a/patches/unapplied/0861-Configurable-entity-tracking-range-by-Y-coordinate.patch b/patches/unapplied/server/0861-Configurable-entity-tracking-range-by-Y-coordinate.patch similarity index 100% rename from patches/unapplied/0861-Configurable-entity-tracking-range-by-Y-coordinate.patch rename to patches/unapplied/server/0861-Configurable-entity-tracking-range-by-Y-coordinate.patch diff --git a/patches/unapplied/0862-Add-Listing-API-for-Player.patch b/patches/unapplied/server/0862-Add-Listing-API-for-Player.patch similarity index 100% rename from patches/unapplied/0862-Add-Listing-API-for-Player.patch rename to patches/unapplied/server/0862-Add-Listing-API-for-Player.patch diff --git a/patches/unapplied/0863-Configurable-Region-Compression-Format.patch b/patches/unapplied/server/0863-Configurable-Region-Compression-Format.patch similarity index 100% rename from patches/unapplied/0863-Configurable-Region-Compression-Format.patch rename to patches/unapplied/server/0863-Configurable-Region-Compression-Format.patch diff --git a/patches/unapplied/0864-Add-BlockFace-to-BlockDamageEvent.patch b/patches/unapplied/server/0864-Add-BlockFace-to-BlockDamageEvent.patch similarity index 100% rename from patches/unapplied/0864-Add-BlockFace-to-BlockDamageEvent.patch rename to patches/unapplied/server/0864-Add-BlockFace-to-BlockDamageEvent.patch diff --git a/patches/unapplied/0865-Fix-NPE-on-Boat-getStatus.patch b/patches/unapplied/server/0865-Fix-NPE-on-Boat-getStatus.patch similarity index 100% rename from patches/unapplied/0865-Fix-NPE-on-Boat-getStatus.patch rename to patches/unapplied/server/0865-Fix-NPE-on-Boat-getStatus.patch diff --git a/patches/unapplied/0866-Expand-Pose-API.patch b/patches/unapplied/server/0866-Expand-Pose-API.patch similarity index 100% rename from patches/unapplied/0866-Expand-Pose-API.patch rename to patches/unapplied/server/0866-Expand-Pose-API.patch diff --git a/patches/unapplied/0867-More-DragonBattle-API.patch b/patches/unapplied/server/0867-More-DragonBattle-API.patch similarity index 100% rename from patches/unapplied/0867-More-DragonBattle-API.patch rename to patches/unapplied/server/0867-More-DragonBattle-API.patch diff --git a/patches/unapplied/0868-Add-PlayerPickItemEvent.patch b/patches/unapplied/server/0868-Add-PlayerPickItemEvent.patch similarity index 100% rename from patches/unapplied/0868-Add-PlayerPickItemEvent.patch rename to patches/unapplied/server/0868-Add-PlayerPickItemEvent.patch diff --git a/patches/unapplied/0869-Allow-trident-custom-damage.patch b/patches/unapplied/server/0869-Allow-trident-custom-damage.patch similarity index 100% rename from patches/unapplied/0869-Allow-trident-custom-damage.patch rename to patches/unapplied/server/0869-Allow-trident-custom-damage.patch diff --git a/patches/unapplied/0870-Expose-hand-in-BlockCanBuildEvent.patch b/patches/unapplied/server/0870-Expose-hand-in-BlockCanBuildEvent.patch similarity index 100% rename from patches/unapplied/0870-Expose-hand-in-BlockCanBuildEvent.patch rename to patches/unapplied/server/0870-Expose-hand-in-BlockCanBuildEvent.patch diff --git a/patches/unapplied/0871-Optimize-nearest-structure-border-iteration.patch b/patches/unapplied/server/0871-Optimize-nearest-structure-border-iteration.patch similarity index 100% rename from patches/unapplied/0871-Optimize-nearest-structure-border-iteration.patch rename to patches/unapplied/server/0871-Optimize-nearest-structure-border-iteration.patch diff --git a/patches/unapplied/0872-Implement-OfflinePlayer-isConnected.patch b/patches/unapplied/server/0872-Implement-OfflinePlayer-isConnected.patch similarity index 100% rename from patches/unapplied/0872-Implement-OfflinePlayer-isConnected.patch rename to patches/unapplied/server/0872-Implement-OfflinePlayer-isConnected.patch diff --git a/patches/unapplied/0873-Fix-slot-desync.patch b/patches/unapplied/server/0873-Fix-slot-desync.patch similarity index 100% rename from patches/unapplied/0873-Fix-slot-desync.patch rename to patches/unapplied/server/0873-Fix-slot-desync.patch diff --git a/patches/unapplied/0874-Add-titleOverride-to-InventoryOpenEvent.patch b/patches/unapplied/server/0874-Add-titleOverride-to-InventoryOpenEvent.patch similarity index 100% rename from patches/unapplied/0874-Add-titleOverride-to-InventoryOpenEvent.patch rename to patches/unapplied/server/0874-Add-titleOverride-to-InventoryOpenEvent.patch diff --git a/patches/unapplied/0875-Configure-sniffer-egg-hatch-time.patch b/patches/unapplied/server/0875-Configure-sniffer-egg-hatch-time.patch similarity index 100% rename from patches/unapplied/0875-Configure-sniffer-egg-hatch-time.patch rename to patches/unapplied/server/0875-Configure-sniffer-egg-hatch-time.patch diff --git a/patches/unapplied/0876-Do-crystal-portal-proximity-check-before-entity-look.patch b/patches/unapplied/server/0876-Do-crystal-portal-proximity-check-before-entity-look.patch similarity index 100% rename from patches/unapplied/0876-Do-crystal-portal-proximity-check-before-entity-look.patch rename to patches/unapplied/server/0876-Do-crystal-portal-proximity-check-before-entity-look.patch diff --git a/patches/unapplied/0877-Skip-POI-finding-if-stuck-in-vehicle.patch b/patches/unapplied/server/0877-Skip-POI-finding-if-stuck-in-vehicle.patch similarity index 100% rename from patches/unapplied/0877-Skip-POI-finding-if-stuck-in-vehicle.patch rename to patches/unapplied/server/0877-Skip-POI-finding-if-stuck-in-vehicle.patch diff --git a/patches/unapplied/0878-Add-slot-sanity-checks-in-container-clicks.patch b/patches/unapplied/server/0878-Add-slot-sanity-checks-in-container-clicks.patch similarity index 100% rename from patches/unapplied/0878-Add-slot-sanity-checks-in-container-clicks.patch rename to patches/unapplied/server/0878-Add-slot-sanity-checks-in-container-clicks.patch diff --git a/patches/unapplied/0879-Call-BlockRedstoneEvents-for-lecterns.patch b/patches/unapplied/server/0879-Call-BlockRedstoneEvents-for-lecterns.patch similarity index 100% rename from patches/unapplied/0879-Call-BlockRedstoneEvents-for-lecterns.patch rename to patches/unapplied/server/0879-Call-BlockRedstoneEvents-for-lecterns.patch diff --git a/patches/unapplied/0880-Allow-proper-checking-of-empty-item-stacks.patch b/patches/unapplied/server/0880-Allow-proper-checking-of-empty-item-stacks.patch similarity index 100% rename from patches/unapplied/0880-Allow-proper-checking-of-empty-item-stacks.patch rename to patches/unapplied/server/0880-Allow-proper-checking-of-empty-item-stacks.patch diff --git a/patches/unapplied/0881-Fix-silent-equipment-change-for-mobs.patch b/patches/unapplied/server/0881-Fix-silent-equipment-change-for-mobs.patch similarity index 100% rename from patches/unapplied/0881-Fix-silent-equipment-change-for-mobs.patch rename to patches/unapplied/server/0881-Fix-silent-equipment-change-for-mobs.patch diff --git a/patches/unapplied/0882-Fix-spigot-s-Forced-Stats.patch b/patches/unapplied/server/0882-Fix-spigot-s-Forced-Stats.patch similarity index 100% rename from patches/unapplied/0882-Fix-spigot-s-Forced-Stats.patch rename to patches/unapplied/server/0882-Fix-spigot-s-Forced-Stats.patch diff --git a/patches/unapplied/0883-Add-missing-InventoryHolders-to-inventories.patch b/patches/unapplied/server/0883-Add-missing-InventoryHolders-to-inventories.patch similarity index 100% rename from patches/unapplied/0883-Add-missing-InventoryHolders-to-inventories.patch rename to patches/unapplied/server/0883-Add-missing-InventoryHolders-to-inventories.patch diff --git a/patches/unapplied/0884-Do-not-read-tile-entities-in-chunks-that-are-positio.patch b/patches/unapplied/server/0884-Do-not-read-tile-entities-in-chunks-that-are-positio.patch similarity index 100% rename from patches/unapplied/0884-Do-not-read-tile-entities-in-chunks-that-are-positio.patch rename to patches/unapplied/server/0884-Do-not-read-tile-entities-in-chunks-that-are-positio.patch diff --git a/patches/unapplied/0885-Add-missing-logs-for-log-ips-config-option.patch b/patches/unapplied/server/0885-Add-missing-logs-for-log-ips-config-option.patch similarity index 100% rename from patches/unapplied/0885-Add-missing-logs-for-log-ips-config-option.patch rename to patches/unapplied/server/0885-Add-missing-logs-for-log-ips-config-option.patch diff --git a/patches/unapplied/0886-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch b/patches/unapplied/server/0886-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch similarity index 100% rename from patches/unapplied/0886-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch rename to patches/unapplied/server/0886-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch diff --git a/patches/unapplied/0887-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch b/patches/unapplied/server/0887-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch similarity index 100% rename from patches/unapplied/0887-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch rename to patches/unapplied/server/0887-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch diff --git a/patches/unapplied/0888-Fix-team-sidebar-objectives-not-being-cleared.patch b/patches/unapplied/server/0888-Fix-team-sidebar-objectives-not-being-cleared.patch similarity index 100% rename from patches/unapplied/0888-Fix-team-sidebar-objectives-not-being-cleared.patch rename to patches/unapplied/server/0888-Fix-team-sidebar-objectives-not-being-cleared.patch diff --git a/patches/unapplied/0889-Fix-missing-map-initialize-event-call.patch b/patches/unapplied/server/0889-Fix-missing-map-initialize-event-call.patch similarity index 100% rename from patches/unapplied/0889-Fix-missing-map-initialize-event-call.patch rename to patches/unapplied/server/0889-Fix-missing-map-initialize-event-call.patch diff --git a/patches/unapplied/0890-Update-entity-data-when-attaching-firework-to-entity.patch b/patches/unapplied/server/0890-Update-entity-data-when-attaching-firework-to-entity.patch similarity index 100% rename from patches/unapplied/0890-Update-entity-data-when-attaching-firework-to-entity.patch rename to patches/unapplied/server/0890-Update-entity-data-when-attaching-firework-to-entity.patch diff --git a/patches/unapplied/0891-Fix-UnsafeValues-loadAdvancement.patch b/patches/unapplied/server/0891-Fix-UnsafeValues-loadAdvancement.patch similarity index 100% rename from patches/unapplied/0891-Fix-UnsafeValues-loadAdvancement.patch rename to patches/unapplied/server/0891-Fix-UnsafeValues-loadAdvancement.patch diff --git a/patches/unapplied/0892-Add-player-idle-duration-API.patch b/patches/unapplied/server/0892-Add-player-idle-duration-API.patch similarity index 100% rename from patches/unapplied/0892-Add-player-idle-duration-API.patch rename to patches/unapplied/server/0892-Add-player-idle-duration-API.patch diff --git a/patches/unapplied/0893-Don-t-check-if-we-can-see-non-visible-entities.patch b/patches/unapplied/server/0893-Don-t-check-if-we-can-see-non-visible-entities.patch similarity index 100% rename from patches/unapplied/0893-Don-t-check-if-we-can-see-non-visible-entities.patch rename to patches/unapplied/server/0893-Don-t-check-if-we-can-see-non-visible-entities.patch diff --git a/patches/unapplied/0894-Fix-NPE-in-SculkBloomEvent-world-access.patch b/patches/unapplied/server/0894-Fix-NPE-in-SculkBloomEvent-world-access.patch similarity index 100% rename from patches/unapplied/0894-Fix-NPE-in-SculkBloomEvent-world-access.patch rename to patches/unapplied/server/0894-Fix-NPE-in-SculkBloomEvent-world-access.patch diff --git a/patches/unapplied/0895-Allow-null-itemstack-for-Player-sendEquipmentChange.patch b/patches/unapplied/server/0895-Allow-null-itemstack-for-Player-sendEquipmentChange.patch similarity index 100% rename from patches/unapplied/0895-Allow-null-itemstack-for-Player-sendEquipmentChange.patch rename to patches/unapplied/server/0895-Allow-null-itemstack-for-Player-sendEquipmentChange.patch diff --git a/patches/unapplied/0896-Optimize-VarInts.patch b/patches/unapplied/server/0896-Optimize-VarInts.patch similarity index 100% rename from patches/unapplied/0896-Optimize-VarInts.patch rename to patches/unapplied/server/0896-Optimize-VarInts.patch diff --git a/patches/unapplied/0897-Add-API-to-get-the-collision-shape-of-a-block-before.patch b/patches/unapplied/server/0897-Add-API-to-get-the-collision-shape-of-a-block-before.patch similarity index 100% rename from patches/unapplied/0897-Add-API-to-get-the-collision-shape-of-a-block-before.patch rename to patches/unapplied/server/0897-Add-API-to-get-the-collision-shape-of-a-block-before.patch diff --git a/patches/unapplied/0898-Add-predicate-for-blocks-when-raytracing.patch b/patches/unapplied/server/0898-Add-predicate-for-blocks-when-raytracing.patch similarity index 100% rename from patches/unapplied/0898-Add-predicate-for-blocks-when-raytracing.patch rename to patches/unapplied/server/0898-Add-predicate-for-blocks-when-raytracing.patch diff --git a/patches/unapplied/0899-Broadcast-take-item-packets-with-collector-as-source.patch b/patches/unapplied/server/0899-Broadcast-take-item-packets-with-collector-as-source.patch similarity index 100% rename from patches/unapplied/0899-Broadcast-take-item-packets-with-collector-as-source.patch rename to patches/unapplied/server/0899-Broadcast-take-item-packets-with-collector-as-source.patch diff --git a/patches/unapplied/0900-Expand-LingeringPotion-API.patch b/patches/unapplied/server/0900-Expand-LingeringPotion-API.patch similarity index 100% rename from patches/unapplied/0900-Expand-LingeringPotion-API.patch rename to patches/unapplied/server/0900-Expand-LingeringPotion-API.patch diff --git a/patches/unapplied/0901-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch b/patches/unapplied/server/0901-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch similarity index 100% rename from patches/unapplied/0901-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch rename to patches/unapplied/server/0901-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch diff --git a/patches/unapplied/0902-Add-hand-to-fish-event-for-all-player-interactions.patch b/patches/unapplied/server/0902-Add-hand-to-fish-event-for-all-player-interactions.patch similarity index 100% rename from patches/unapplied/0902-Add-hand-to-fish-event-for-all-player-interactions.patch rename to patches/unapplied/server/0902-Add-hand-to-fish-event-for-all-player-interactions.patch diff --git a/patches/unapplied/0903-Fix-several-issues-with-EntityBreedEvent.patch b/patches/unapplied/server/0903-Fix-several-issues-with-EntityBreedEvent.patch similarity index 100% rename from patches/unapplied/0903-Fix-several-issues-with-EntityBreedEvent.patch rename to patches/unapplied/server/0903-Fix-several-issues-with-EntityBreedEvent.patch diff --git a/patches/unapplied/0904-Add-UUID-attribute-modifier-API.patch b/patches/unapplied/server/0904-Add-UUID-attribute-modifier-API.patch similarity index 100% rename from patches/unapplied/0904-Add-UUID-attribute-modifier-API.patch rename to patches/unapplied/server/0904-Add-UUID-attribute-modifier-API.patch diff --git a/patches/unapplied/0905-Fix-missing-event-call-for-entity-teleport-API.patch b/patches/unapplied/server/0905-Fix-missing-event-call-for-entity-teleport-API.patch similarity index 100% rename from patches/unapplied/0905-Fix-missing-event-call-for-entity-teleport-API.patch rename to patches/unapplied/server/0905-Fix-missing-event-call-for-entity-teleport-API.patch diff --git a/patches/unapplied/0906-Lazily-create-LootContext-for-criterions.patch b/patches/unapplied/server/0906-Lazily-create-LootContext-for-criterions.patch similarity index 100% rename from patches/unapplied/0906-Lazily-create-LootContext-for-criterions.patch rename to patches/unapplied/server/0906-Lazily-create-LootContext-for-criterions.patch diff --git a/patches/unapplied/0907-Don-t-fire-sync-events-during-worldgen.patch b/patches/unapplied/server/0907-Don-t-fire-sync-events-during-worldgen.patch similarity index 100% rename from patches/unapplied/0907-Don-t-fire-sync-events-during-worldgen.patch rename to patches/unapplied/server/0907-Don-t-fire-sync-events-during-worldgen.patch diff --git a/patches/unapplied/0908-Add-Structure-check-API.patch b/patches/unapplied/server/0908-Add-Structure-check-API.patch similarity index 100% rename from patches/unapplied/0908-Add-Structure-check-API.patch rename to patches/unapplied/server/0908-Add-Structure-check-API.patch diff --git a/patches/unapplied/0909-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch b/patches/unapplied/server/0909-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch similarity index 100% rename from patches/unapplied/0909-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch rename to patches/unapplied/server/0909-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch diff --git a/patches/unapplied/0910-Restore-vanilla-entity-drops-behavior.patch b/patches/unapplied/server/0910-Restore-vanilla-entity-drops-behavior.patch similarity index 100% rename from patches/unapplied/0910-Restore-vanilla-entity-drops-behavior.patch rename to patches/unapplied/server/0910-Restore-vanilla-entity-drops-behavior.patch diff --git a/patches/unapplied/0911-Dont-resend-blocks-on-interactions.patch b/patches/unapplied/server/0911-Dont-resend-blocks-on-interactions.patch similarity index 100% rename from patches/unapplied/0911-Dont-resend-blocks-on-interactions.patch rename to patches/unapplied/server/0911-Dont-resend-blocks-on-interactions.patch diff --git a/patches/unapplied/0912-add-more-scoreboard-API.patch b/patches/unapplied/server/0912-add-more-scoreboard-API.patch similarity index 100% rename from patches/unapplied/0912-add-more-scoreboard-API.patch rename to patches/unapplied/server/0912-add-more-scoreboard-API.patch diff --git a/patches/unapplied/0913-Improve-Registry.patch b/patches/unapplied/server/0913-Improve-Registry.patch similarity index 100% rename from patches/unapplied/0913-Improve-Registry.patch rename to patches/unapplied/server/0913-Improve-Registry.patch diff --git a/patches/unapplied/0914-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch b/patches/unapplied/server/0914-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch similarity index 100% rename from patches/unapplied/0914-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch rename to patches/unapplied/server/0914-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch diff --git a/patches/unapplied/0915-Add-experience-points-API.patch b/patches/unapplied/server/0915-Add-experience-points-API.patch similarity index 100% rename from patches/unapplied/0915-Add-experience-points-API.patch rename to patches/unapplied/server/0915-Add-experience-points-API.patch diff --git a/patches/unapplied/0916-Add-drops-to-shear-events.patch b/patches/unapplied/server/0916-Add-drops-to-shear-events.patch similarity index 100% rename from patches/unapplied/0916-Add-drops-to-shear-events.patch rename to patches/unapplied/server/0916-Add-drops-to-shear-events.patch diff --git a/patches/unapplied/0917-Add-PlayerShieldDisableEvent.patch b/patches/unapplied/server/0917-Add-PlayerShieldDisableEvent.patch similarity index 100% rename from patches/unapplied/0917-Add-PlayerShieldDisableEvent.patch rename to patches/unapplied/server/0917-Add-PlayerShieldDisableEvent.patch diff --git a/patches/unapplied/0918-Validate-ResourceLocation-in-NBT-reading.patch b/patches/unapplied/server/0918-Validate-ResourceLocation-in-NBT-reading.patch similarity index 100% rename from patches/unapplied/0918-Validate-ResourceLocation-in-NBT-reading.patch rename to patches/unapplied/server/0918-Validate-ResourceLocation-in-NBT-reading.patch diff --git a/patches/unapplied/0919-Properly-handle-experience-dropping-on-block-break.patch b/patches/unapplied/server/0919-Properly-handle-experience-dropping-on-block-break.patch similarity index 100% rename from patches/unapplied/0919-Properly-handle-experience-dropping-on-block-break.patch rename to patches/unapplied/server/0919-Properly-handle-experience-dropping-on-block-break.patch diff --git a/patches/unapplied/0920-Fixup-NamespacedKey-handling.patch b/patches/unapplied/server/0920-Fixup-NamespacedKey-handling.patch similarity index 100% rename from patches/unapplied/0920-Fixup-NamespacedKey-handling.patch rename to patches/unapplied/server/0920-Fixup-NamespacedKey-handling.patch diff --git a/patches/unapplied/0921-Expose-LootTable-of-DecoratedPot.patch b/patches/unapplied/server/0921-Expose-LootTable-of-DecoratedPot.patch similarity index 100% rename from patches/unapplied/0921-Expose-LootTable-of-DecoratedPot.patch rename to patches/unapplied/server/0921-Expose-LootTable-of-DecoratedPot.patch diff --git a/patches/unapplied/0922-Reduce-allocation-of-Vec3D-by-entity-tracker.patch b/patches/unapplied/server/0922-Reduce-allocation-of-Vec3D-by-entity-tracker.patch similarity index 100% rename from patches/unapplied/0922-Reduce-allocation-of-Vec3D-by-entity-tracker.patch rename to patches/unapplied/server/0922-Reduce-allocation-of-Vec3D-by-entity-tracker.patch diff --git a/patches/unapplied/0923-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch b/patches/unapplied/server/0923-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch similarity index 100% rename from patches/unapplied/0923-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch rename to patches/unapplied/server/0923-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch diff --git a/patches/unapplied/0924-Add-ShulkerDuplicateEvent.patch b/patches/unapplied/server/0924-Add-ShulkerDuplicateEvent.patch similarity index 100% rename from patches/unapplied/0924-Add-ShulkerDuplicateEvent.patch rename to patches/unapplied/server/0924-Add-ShulkerDuplicateEvent.patch diff --git a/patches/unapplied/0925-Add-api-for-spawn-egg-texture-colors.patch b/patches/unapplied/server/0925-Add-api-for-spawn-egg-texture-colors.patch similarity index 100% rename from patches/unapplied/0925-Add-api-for-spawn-egg-texture-colors.patch rename to patches/unapplied/server/0925-Add-api-for-spawn-egg-texture-colors.patch diff --git a/patches/unapplied/0926-Add-Lifecycle-Event-system.patch b/patches/unapplied/server/0926-Add-Lifecycle-Event-system.patch similarity index 100% rename from patches/unapplied/0926-Add-Lifecycle-Event-system.patch rename to patches/unapplied/server/0926-Add-Lifecycle-Event-system.patch diff --git a/patches/unapplied/0927-ItemStack-Tooltip-API.patch b/patches/unapplied/server/0927-ItemStack-Tooltip-API.patch similarity index 100% rename from patches/unapplied/0927-ItemStack-Tooltip-API.patch rename to patches/unapplied/server/0927-ItemStack-Tooltip-API.patch diff --git a/patches/unapplied/0928-Add-getChunkSnapshot-includeLightData-parameter.patch b/patches/unapplied/server/0928-Add-getChunkSnapshot-includeLightData-parameter.patch similarity index 100% rename from patches/unapplied/0928-Add-getChunkSnapshot-includeLightData-parameter.patch rename to patches/unapplied/server/0928-Add-getChunkSnapshot-includeLightData-parameter.patch diff --git a/patches/unapplied/0929-Add-FluidState-API.patch b/patches/unapplied/server/0929-Add-FluidState-API.patch similarity index 100% rename from patches/unapplied/0929-Add-FluidState-API.patch rename to patches/unapplied/server/0929-Add-FluidState-API.patch diff --git a/patches/unapplied/0930-add-number-format-api.patch b/patches/unapplied/server/0930-add-number-format-api.patch similarity index 100% rename from patches/unapplied/0930-add-number-format-api.patch rename to patches/unapplied/server/0930-add-number-format-api.patch diff --git a/patches/unapplied/0931-improve-BanList-types.patch b/patches/unapplied/server/0931-improve-BanList-types.patch similarity index 100% rename from patches/unapplied/0931-improve-BanList-types.patch rename to patches/unapplied/server/0931-improve-BanList-types.patch diff --git a/patches/unapplied/0932-Expanded-Hopper-API.patch b/patches/unapplied/server/0932-Expanded-Hopper-API.patch similarity index 100% rename from patches/unapplied/0932-Expanded-Hopper-API.patch rename to patches/unapplied/server/0932-Expanded-Hopper-API.patch diff --git a/patches/unapplied/0933-Add-BlockBreakProgressUpdateEvent.patch b/patches/unapplied/server/0933-Add-BlockBreakProgressUpdateEvent.patch similarity index 100% rename from patches/unapplied/0933-Add-BlockBreakProgressUpdateEvent.patch rename to patches/unapplied/server/0933-Add-BlockBreakProgressUpdateEvent.patch diff --git a/patches/unapplied/0934-Deprecate-ItemStack-setType.patch b/patches/unapplied/server/0934-Deprecate-ItemStack-setType.patch similarity index 100% rename from patches/unapplied/0934-Deprecate-ItemStack-setType.patch rename to patches/unapplied/server/0934-Deprecate-ItemStack-setType.patch diff --git a/patches/unapplied/0935-Add-CartographyItemEvent.patch b/patches/unapplied/server/0935-Add-CartographyItemEvent.patch similarity index 100% rename from patches/unapplied/0935-Add-CartographyItemEvent.patch rename to patches/unapplied/server/0935-Add-CartographyItemEvent.patch diff --git a/patches/unapplied/0936-More-Raid-API.patch b/patches/unapplied/server/0936-More-Raid-API.patch similarity index 100% rename from patches/unapplied/0936-More-Raid-API.patch rename to patches/unapplied/server/0936-More-Raid-API.patch diff --git a/patches/unapplied/0937-Add-onboarding-message-for-initial-server-start.patch b/patches/unapplied/server/0937-Add-onboarding-message-for-initial-server-start.patch similarity index 100% rename from patches/unapplied/0937-Add-onboarding-message-for-initial-server-start.patch rename to patches/unapplied/server/0937-Add-onboarding-message-for-initial-server-start.patch diff --git a/patches/unapplied/0938-Configurable-max-block-fluid-ticks.patch b/patches/unapplied/server/0938-Configurable-max-block-fluid-ticks.patch similarity index 100% rename from patches/unapplied/0938-Configurable-max-block-fluid-ticks.patch rename to patches/unapplied/server/0938-Configurable-max-block-fluid-ticks.patch diff --git a/patches/unapplied/0939-Fix-bees-aging-inside-hives.patch b/patches/unapplied/server/0939-Fix-bees-aging-inside-hives.patch similarity index 100% rename from patches/unapplied/0939-Fix-bees-aging-inside-hives.patch rename to patches/unapplied/server/0939-Fix-bees-aging-inside-hives.patch diff --git a/patches/unapplied/0940-Disable-memory-reserve-allocating.patch b/patches/unapplied/server/0940-Disable-memory-reserve-allocating.patch similarity index 100% rename from patches/unapplied/0940-Disable-memory-reserve-allocating.patch rename to patches/unapplied/server/0940-Disable-memory-reserve-allocating.patch diff --git a/patches/unapplied/0941-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch b/patches/unapplied/server/0941-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch similarity index 100% rename from patches/unapplied/0941-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch rename to patches/unapplied/server/0941-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch diff --git a/patches/unapplied/0942-Fix-DamageSource-API.patch b/patches/unapplied/server/0942-Fix-DamageSource-API.patch similarity index 100% rename from patches/unapplied/0942-Fix-DamageSource-API.patch rename to patches/unapplied/server/0942-Fix-DamageSource-API.patch diff --git a/patches/unapplied/0943-Fix-creation-of-invalid-block-entity-during-world-ge.patch b/patches/unapplied/server/0943-Fix-creation-of-invalid-block-entity-during-world-ge.patch similarity index 100% rename from patches/unapplied/0943-Fix-creation-of-invalid-block-entity-during-world-ge.patch rename to patches/unapplied/server/0943-Fix-creation-of-invalid-block-entity-during-world-ge.patch diff --git a/patches/unapplied/0944-Fix-possible-StackOverflowError-for-some-dispenses.patch b/patches/unapplied/server/0944-Fix-possible-StackOverflowError-for-some-dispenses.patch similarity index 100% rename from patches/unapplied/0944-Fix-possible-StackOverflowError-for-some-dispenses.patch rename to patches/unapplied/server/0944-Fix-possible-StackOverflowError-for-some-dispenses.patch diff --git a/patches/unapplied/0945-Improve-tag-parser-handling.patch b/patches/unapplied/server/0945-Improve-tag-parser-handling.patch similarity index 100% rename from patches/unapplied/0945-Improve-tag-parser-handling.patch rename to patches/unapplied/server/0945-Improve-tag-parser-handling.patch diff --git a/patches/unapplied/0946-Item-Mutation-Fixes.patch b/patches/unapplied/server/0946-Item-Mutation-Fixes.patch similarity index 100% rename from patches/unapplied/0946-Item-Mutation-Fixes.patch rename to patches/unapplied/server/0946-Item-Mutation-Fixes.patch diff --git a/patches/unapplied/0947-Per-world-ticks-per-spawn-settings.patch b/patches/unapplied/server/0947-Per-world-ticks-per-spawn-settings.patch similarity index 100% rename from patches/unapplied/0947-Per-world-ticks-per-spawn-settings.patch rename to patches/unapplied/server/0947-Per-world-ticks-per-spawn-settings.patch diff --git a/patches/unapplied/0948-Properly-track-the-changed-item-from-dispense-events.patch b/patches/unapplied/server/0948-Properly-track-the-changed-item-from-dispense-events.patch similarity index 100% rename from patches/unapplied/0948-Properly-track-the-changed-item-from-dispense-events.patch rename to patches/unapplied/server/0948-Properly-track-the-changed-item-from-dispense-events.patch diff --git a/patches/unapplied/0949-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch b/patches/unapplied/server/0949-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch similarity index 100% rename from patches/unapplied/0949-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch rename to patches/unapplied/server/0949-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch diff --git a/patches/unapplied/0950-Fix-tripwire-disarming-not-working-as-intended.patch b/patches/unapplied/server/0950-Fix-tripwire-disarming-not-working-as-intended.patch similarity index 100% rename from patches/unapplied/0950-Fix-tripwire-disarming-not-working-as-intended.patch rename to patches/unapplied/server/0950-Fix-tripwire-disarming-not-working-as-intended.patch diff --git a/patches/unapplied/0951-Add-config-for-mobs-immune-to-default-effects.patch b/patches/unapplied/server/0951-Add-config-for-mobs-immune-to-default-effects.patch similarity index 100% rename from patches/unapplied/0951-Add-config-for-mobs-immune-to-default-effects.patch rename to patches/unapplied/server/0951-Add-config-for-mobs-immune-to-default-effects.patch diff --git a/patches/unapplied/0952-Deep-clone-nbt-tags-in-PDC.patch b/patches/unapplied/server/0952-Deep-clone-nbt-tags-in-PDC.patch similarity index 100% rename from patches/unapplied/0952-Deep-clone-nbt-tags-in-PDC.patch rename to patches/unapplied/server/0952-Deep-clone-nbt-tags-in-PDC.patch diff --git a/patches/unapplied/0953-Support-old-UUID-format-for-NBT.patch b/patches/unapplied/server/0953-Support-old-UUID-format-for-NBT.patch similarity index 100% rename from patches/unapplied/0953-Support-old-UUID-format-for-NBT.patch rename to patches/unapplied/server/0953-Support-old-UUID-format-for-NBT.patch diff --git a/patches/unapplied/0954-Fix-shield-disable-inconsistency.patch b/patches/unapplied/server/0954-Fix-shield-disable-inconsistency.patch similarity index 100% rename from patches/unapplied/0954-Fix-shield-disable-inconsistency.patch rename to patches/unapplied/server/0954-Fix-shield-disable-inconsistency.patch diff --git a/patches/unapplied/0955-Handle-Large-Packets-disconnecting-client.patch b/patches/unapplied/server/0955-Handle-Large-Packets-disconnecting-client.patch similarity index 100% rename from patches/unapplied/0955-Handle-Large-Packets-disconnecting-client.patch rename to patches/unapplied/server/0955-Handle-Large-Packets-disconnecting-client.patch diff --git a/patches/unapplied/0956-Fix-ItemFlags.patch b/patches/unapplied/server/0956-Fix-ItemFlags.patch similarity index 100% rename from patches/unapplied/0956-Fix-ItemFlags.patch rename to patches/unapplied/server/0956-Fix-ItemFlags.patch diff --git a/patches/unapplied/0957-Fix-helmet-damage-reduction-inconsistencies.patch b/patches/unapplied/server/0957-Fix-helmet-damage-reduction-inconsistencies.patch similarity index 100% rename from patches/unapplied/0957-Fix-helmet-damage-reduction-inconsistencies.patch rename to patches/unapplied/server/0957-Fix-helmet-damage-reduction-inconsistencies.patch diff --git a/patches/unapplied/0958-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch b/patches/unapplied/server/0958-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch similarity index 100% rename from patches/unapplied/0958-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch rename to patches/unapplied/server/0958-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch diff --git a/patches/unapplied/0959-improve-checking-handled-tags-in-itemmeta.patch b/patches/unapplied/server/0959-improve-checking-handled-tags-in-itemmeta.patch similarity index 100% rename from patches/unapplied/0959-improve-checking-handled-tags-in-itemmeta.patch rename to patches/unapplied/server/0959-improve-checking-handled-tags-in-itemmeta.patch diff --git a/patches/unapplied/0960-General-ItemMeta-fixes.patch b/patches/unapplied/server/0960-General-ItemMeta-fixes.patch similarity index 100% rename from patches/unapplied/0960-General-ItemMeta-fixes.patch rename to patches/unapplied/server/0960-General-ItemMeta-fixes.patch diff --git a/patches/unapplied/0961-Expose-hasColor-to-leather-armor.patch b/patches/unapplied/server/0961-Expose-hasColor-to-leather-armor.patch similarity index 100% rename from patches/unapplied/0961-Expose-hasColor-to-leather-armor.patch rename to patches/unapplied/server/0961-Expose-hasColor-to-leather-armor.patch diff --git a/patches/unapplied/0962-Added-API-to-get-player-ha-proxy-address.patch b/patches/unapplied/server/0962-Added-API-to-get-player-ha-proxy-address.patch similarity index 100% rename from patches/unapplied/0962-Added-API-to-get-player-ha-proxy-address.patch rename to patches/unapplied/server/0962-Added-API-to-get-player-ha-proxy-address.patch diff --git a/patches/unapplied/0963-More-Chest-Block-API.patch b/patches/unapplied/server/0963-More-Chest-Block-API.patch similarity index 100% rename from patches/unapplied/0963-More-Chest-Block-API.patch rename to patches/unapplied/server/0963-More-Chest-Block-API.patch diff --git a/patches/unapplied/0964-Print-data-component-type-on-encoding-error.patch b/patches/unapplied/server/0964-Print-data-component-type-on-encoding-error.patch similarity index 100% rename from patches/unapplied/0964-Print-data-component-type-on-encoding-error.patch rename to patches/unapplied/server/0964-Print-data-component-type-on-encoding-error.patch diff --git a/patches/unapplied/0965-Brigadier-based-command-API.patch b/patches/unapplied/server/0965-Brigadier-based-command-API.patch similarity index 100% rename from patches/unapplied/0965-Brigadier-based-command-API.patch rename to patches/unapplied/server/0965-Brigadier-based-command-API.patch diff --git a/patches/unapplied/0966-Fix-issues-with-Recipe-API.patch b/patches/unapplied/server/0966-Fix-issues-with-Recipe-API.patch similarity index 100% rename from patches/unapplied/0966-Fix-issues-with-Recipe-API.patch rename to patches/unapplied/server/0966-Fix-issues-with-Recipe-API.patch diff --git a/patches/unapplied/0967-Fix-equipment-slot-and-group-API.patch b/patches/unapplied/server/0967-Fix-equipment-slot-and-group-API.patch similarity index 100% rename from patches/unapplied/0967-Fix-equipment-slot-and-group-API.patch rename to patches/unapplied/server/0967-Fix-equipment-slot-and-group-API.patch diff --git a/patches/unapplied/0968-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch b/patches/unapplied/server/0968-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch similarity index 100% rename from patches/unapplied/0968-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch rename to patches/unapplied/server/0968-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch diff --git a/patches/unapplied/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch b/patches/unapplied/server/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch similarity index 100% rename from patches/unapplied/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch rename to patches/unapplied/server/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch diff --git a/patches/unapplied/0970-Prevent-NPE-if-hooked-entity-was-cleared.patch b/patches/unapplied/server/0970-Prevent-NPE-if-hooked-entity-was-cleared.patch similarity index 100% rename from patches/unapplied/0970-Prevent-NPE-if-hooked-entity-was-cleared.patch rename to patches/unapplied/server/0970-Prevent-NPE-if-hooked-entity-was-cleared.patch diff --git a/patches/unapplied/0971-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch b/patches/unapplied/server/0971-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch similarity index 100% rename from patches/unapplied/0971-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch rename to patches/unapplied/server/0971-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch diff --git a/patches/unapplied/0972-Add-missing-fishing-event-state.patch b/patches/unapplied/server/0972-Add-missing-fishing-event-state.patch similarity index 100% rename from patches/unapplied/0972-Add-missing-fishing-event-state.patch rename to patches/unapplied/server/0972-Add-missing-fishing-event-state.patch diff --git a/patches/unapplied/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch b/patches/unapplied/server/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch similarity index 100% rename from patches/unapplied/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch rename to patches/unapplied/server/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch diff --git a/patches/unapplied/0974-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch b/patches/unapplied/server/0974-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch similarity index 100% rename from patches/unapplied/0974-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch rename to patches/unapplied/server/0974-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch diff --git a/patches/unapplied/0975-Adopt-MaterialRerouting.patch b/patches/unapplied/server/0975-Adopt-MaterialRerouting.patch similarity index 100% rename from patches/unapplied/0975-Adopt-MaterialRerouting.patch rename to patches/unapplied/server/0975-Adopt-MaterialRerouting.patch diff --git a/patches/unapplied/0976-Suspicious-Effect-Entry-API.patch b/patches/unapplied/server/0976-Suspicious-Effect-Entry-API.patch similarity index 100% rename from patches/unapplied/0976-Suspicious-Effect-Entry-API.patch rename to patches/unapplied/server/0976-Suspicious-Effect-Entry-API.patch diff --git a/patches/unapplied/0977-check-if-itemstack-is-stackable-first.patch b/patches/unapplied/server/0977-check-if-itemstack-is-stackable-first.patch similarity index 100% rename from patches/unapplied/0977-check-if-itemstack-is-stackable-first.patch rename to patches/unapplied/server/0977-check-if-itemstack-is-stackable-first.patch diff --git a/patches/unapplied/0978-Fix-removing-recipes-from-RecipeIterator.patch b/patches/unapplied/server/0978-Fix-removing-recipes-from-RecipeIterator.patch similarity index 100% rename from patches/unapplied/0978-Fix-removing-recipes-from-RecipeIterator.patch rename to patches/unapplied/server/0978-Fix-removing-recipes-from-RecipeIterator.patch diff --git a/patches/unapplied/0979-Configurable-damage-tick-when-blocking-with-shield.patch b/patches/unapplied/server/0979-Configurable-damage-tick-when-blocking-with-shield.patch similarity index 100% rename from patches/unapplied/0979-Configurable-damage-tick-when-blocking-with-shield.patch rename to patches/unapplied/server/0979-Configurable-damage-tick-when-blocking-with-shield.patch diff --git a/patches/unapplied/0980-Properly-remove-the-experimental-smithing-inventory-.patch b/patches/unapplied/server/0980-Properly-remove-the-experimental-smithing-inventory-.patch similarity index 100% rename from patches/unapplied/0980-Properly-remove-the-experimental-smithing-inventory-.patch rename to patches/unapplied/server/0980-Properly-remove-the-experimental-smithing-inventory-.patch diff --git a/patches/unapplied/0981-Moonrise-optimisation-patches.patch b/patches/unapplied/server/0981-Moonrise-optimisation-patches.patch similarity index 100% rename from patches/unapplied/0981-Moonrise-optimisation-patches.patch rename to patches/unapplied/server/0981-Moonrise-optimisation-patches.patch diff --git a/patches/unapplied/0982-Rewrite-dataconverter-system.patch b/patches/unapplied/server/0982-Rewrite-dataconverter-system.patch similarity index 100% rename from patches/unapplied/0982-Rewrite-dataconverter-system.patch rename to patches/unapplied/server/0982-Rewrite-dataconverter-system.patch diff --git a/patches/unapplied/0983-disable-forced-empty-world-ticks.patch b/patches/unapplied/server/0983-disable-forced-empty-world-ticks.patch similarity index 100% rename from patches/unapplied/0983-disable-forced-empty-world-ticks.patch rename to patches/unapplied/server/0983-disable-forced-empty-world-ticks.patch diff --git a/patches/unapplied/0984-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch b/patches/unapplied/server/0984-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch similarity index 100% rename from patches/unapplied/0984-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch rename to patches/unapplied/server/0984-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch diff --git a/patches/unapplied/0985-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/patches/unapplied/server/0985-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch similarity index 100% rename from patches/unapplied/0985-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch rename to patches/unapplied/server/0985-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch diff --git a/patches/unapplied/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch b/patches/unapplied/server/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch similarity index 100% rename from patches/unapplied/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch rename to patches/unapplied/server/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch diff --git a/patches/unapplied/0987-Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/patches/unapplied/server/0987-Optimize-Network-Manager-and-add-advanced-packet-sup.patch similarity index 100% rename from patches/unapplied/0987-Optimize-Network-Manager-and-add-advanced-packet-sup.patch rename to patches/unapplied/server/0987-Optimize-Network-Manager-and-add-advanced-packet-sup.patch diff --git a/patches/unapplied/0988-Allow-Saving-of-Oversized-Chunks.patch b/patches/unapplied/server/0988-Allow-Saving-of-Oversized-Chunks.patch similarity index 100% rename from patches/unapplied/0988-Allow-Saving-of-Oversized-Chunks.patch rename to patches/unapplied/server/0988-Allow-Saving-of-Oversized-Chunks.patch diff --git a/patches/unapplied/0989-Flat-bedrock-generator-settings.patch b/patches/unapplied/server/0989-Flat-bedrock-generator-settings.patch similarity index 100% rename from patches/unapplied/0989-Flat-bedrock-generator-settings.patch rename to patches/unapplied/server/0989-Flat-bedrock-generator-settings.patch diff --git a/patches/unapplied/0990-Entity-Activation-Range-2.0.patch b/patches/unapplied/server/0990-Entity-Activation-Range-2.0.patch similarity index 100% rename from patches/unapplied/0990-Entity-Activation-Range-2.0.patch rename to patches/unapplied/server/0990-Entity-Activation-Range-2.0.patch diff --git a/patches/unapplied/0991-Optional-per-player-mob-spawns.patch b/patches/unapplied/server/0991-Optional-per-player-mob-spawns.patch similarity index 100% rename from patches/unapplied/0991-Optional-per-player-mob-spawns.patch rename to patches/unapplied/server/0991-Optional-per-player-mob-spawns.patch diff --git a/patches/unapplied/0992-Anti-Xray.patch b/patches/unapplied/server/0992-Anti-Xray.patch similarity index 100% rename from patches/unapplied/0992-Anti-Xray.patch rename to patches/unapplied/server/0992-Anti-Xray.patch diff --git a/patches/unapplied/0993-Eigencraft-redstone-implementation.patch b/patches/unapplied/server/0993-Eigencraft-redstone-implementation.patch similarity index 100% rename from patches/unapplied/0993-Eigencraft-redstone-implementation.patch rename to patches/unapplied/server/0993-Eigencraft-redstone-implementation.patch diff --git a/patches/unapplied/0994-Add-Alternate-Current-redstone-implementation.patch b/patches/unapplied/server/0994-Add-Alternate-Current-redstone-implementation.patch similarity index 100% rename from patches/unapplied/0994-Add-Alternate-Current-redstone-implementation.patch rename to patches/unapplied/server/0994-Add-Alternate-Current-redstone-implementation.patch diff --git a/patches/unapplied/0995-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch b/patches/unapplied/server/0995-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch similarity index 100% rename from patches/unapplied/0995-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch rename to patches/unapplied/server/0995-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch diff --git a/patches/unapplied/0996-Use-Velocity-compression-and-cipher-natives.patch b/patches/unapplied/server/0996-Use-Velocity-compression-and-cipher-natives.patch similarity index 100% rename from patches/unapplied/0996-Use-Velocity-compression-and-cipher-natives.patch rename to patches/unapplied/server/0996-Use-Velocity-compression-and-cipher-natives.patch diff --git a/patches/unapplied/0997-Optimize-Collision-to-not-load-chunks.patch b/patches/unapplied/server/0997-Optimize-Collision-to-not-load-chunks.patch similarity index 100% rename from patches/unapplied/0997-Optimize-Collision-to-not-load-chunks.patch rename to patches/unapplied/server/0997-Optimize-Collision-to-not-load-chunks.patch diff --git a/patches/unapplied/0998-Optimize-GoalSelector-Goal.Flag-Set-operations.patch b/patches/unapplied/server/0998-Optimize-GoalSelector-Goal.Flag-Set-operations.patch similarity index 100% rename from patches/unapplied/0998-Optimize-GoalSelector-Goal.Flag-Set-operations.patch rename to patches/unapplied/server/0998-Optimize-GoalSelector-Goal.Flag-Set-operations.patch diff --git a/patches/unapplied/0999-Optimize-Hoppers.patch b/patches/unapplied/server/0999-Optimize-Hoppers.patch similarity index 100% rename from patches/unapplied/0999-Optimize-Hoppers.patch rename to patches/unapplied/server/0999-Optimize-Hoppers.patch diff --git a/patches/unapplied/1000-Entity-load-save-limit-per-chunk.patch b/patches/unapplied/server/1000-Entity-load-save-limit-per-chunk.patch similarity index 100% rename from patches/unapplied/1000-Entity-load-save-limit-per-chunk.patch rename to patches/unapplied/server/1000-Entity-load-save-limit-per-chunk.patch diff --git a/patches/unapplied/1001-Optimize-Voxel-Shape-Merging.patch b/patches/unapplied/server/1001-Optimize-Voxel-Shape-Merging.patch similarity index 100% rename from patches/unapplied/1001-Optimize-Voxel-Shape-Merging.patch rename to patches/unapplied/server/1001-Optimize-Voxel-Shape-Merging.patch diff --git a/patches/unapplied/1002-Optimize-Bit-Operations-by-inlining.patch b/patches/unapplied/server/1002-Optimize-Bit-Operations-by-inlining.patch similarity index 100% rename from patches/unapplied/1002-Optimize-Bit-Operations-by-inlining.patch rename to patches/unapplied/server/1002-Optimize-Bit-Operations-by-inlining.patch diff --git a/patches/unapplied/1003-Remove-streams-from-hot-code.patch b/patches/unapplied/server/1003-Remove-streams-from-hot-code.patch similarity index 100% rename from patches/unapplied/1003-Remove-streams-from-hot-code.patch rename to patches/unapplied/server/1003-Remove-streams-from-hot-code.patch diff --git a/patches/unapplied/1004-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch b/patches/unapplied/server/1004-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch similarity index 100% rename from patches/unapplied/1004-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch rename to patches/unapplied/server/1004-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch diff --git a/patches/unapplied/1005-Custom-table-implementation-for-blockstate-state-loo.patch b/patches/unapplied/server/1005-Custom-table-implementation-for-blockstate-state-loo.patch similarity index 100% rename from patches/unapplied/1005-Custom-table-implementation-for-blockstate-state-loo.patch rename to patches/unapplied/server/1005-Custom-table-implementation-for-blockstate-state-loo.patch diff --git a/patches/unapplied/1006-Fix-entity-type-tags-suggestions-in-selectors.patch b/patches/unapplied/server/1006-Fix-entity-type-tags-suggestions-in-selectors.patch similarity index 100% rename from patches/unapplied/1006-Fix-entity-type-tags-suggestions-in-selectors.patch rename to patches/unapplied/server/1006-Fix-entity-type-tags-suggestions-in-selectors.patch diff --git a/patches/unapplied/1007-Handle-Oversized-block-entities-in-chunks.patch b/patches/unapplied/server/1007-Handle-Oversized-block-entities-in-chunks.patch similarity index 100% rename from patches/unapplied/1007-Handle-Oversized-block-entities-in-chunks.patch rename to patches/unapplied/server/1007-Handle-Oversized-block-entities-in-chunks.patch diff --git a/patches/unapplied/1008-API-for-checking-sent-chunks.patch b/patches/unapplied/server/1008-API-for-checking-sent-chunks.patch similarity index 100% rename from patches/unapplied/1008-API-for-checking-sent-chunks.patch rename to patches/unapplied/server/1008-API-for-checking-sent-chunks.patch diff --git a/patches/unapplied/1009-Check-distance-in-entity-interactions.patch b/patches/unapplied/server/1009-Check-distance-in-entity-interactions.patch similarity index 100% rename from patches/unapplied/1009-Check-distance-in-entity-interactions.patch rename to patches/unapplied/server/1009-Check-distance-in-entity-interactions.patch diff --git a/patches/unapplied/1010-Configurable-Sand-Duping.patch b/patches/unapplied/server/1010-Configurable-Sand-Duping.patch similarity index 100% rename from patches/unapplied/1010-Configurable-Sand-Duping.patch rename to patches/unapplied/server/1010-Configurable-Sand-Duping.patch diff --git a/patches/unapplied/1011-Optimise-general-POI-access.patch b/patches/unapplied/server/1011-Optimise-general-POI-access.patch similarity index 100% rename from patches/unapplied/1011-Optimise-general-POI-access.patch rename to patches/unapplied/server/1011-Optimise-general-POI-access.patch diff --git a/patches/unapplied/1012-Improve-performance-of-mass-crafts.patch b/patches/unapplied/server/1012-Improve-performance-of-mass-crafts.patch similarity index 100% rename from patches/unapplied/1012-Improve-performance-of-mass-crafts.patch rename to patches/unapplied/server/1012-Improve-performance-of-mass-crafts.patch diff --git a/patches/unapplied/1013-Properly-resend-entities.patch b/patches/unapplied/server/1013-Properly-resend-entities.patch similarity index 100% rename from patches/unapplied/1013-Properly-resend-entities.patch rename to patches/unapplied/server/1013-Properly-resend-entities.patch diff --git a/patches/unapplied/1014-Registry-Modification-API.patch b/patches/unapplied/server/1014-Registry-Modification-API.patch similarity index 100% rename from patches/unapplied/1014-Registry-Modification-API.patch rename to patches/unapplied/server/1014-Registry-Modification-API.patch diff --git a/patches/unapplied/1015-Add-registry-entry-and-builders.patch b/patches/unapplied/server/1015-Add-registry-entry-and-builders.patch similarity index 100% rename from patches/unapplied/1015-Add-registry-entry-and-builders.patch rename to patches/unapplied/server/1015-Add-registry-entry-and-builders.patch diff --git a/patches/unapplied/1016-Improved-Watchdog-Support.patch b/patches/unapplied/server/1016-Improved-Watchdog-Support.patch similarity index 100% rename from patches/unapplied/1016-Improved-Watchdog-Support.patch rename to patches/unapplied/server/1016-Improved-Watchdog-Support.patch diff --git a/patches/unapplied/1017-Proxy-ItemStack-to-CraftItemStack.patch b/patches/unapplied/server/1017-Proxy-ItemStack-to-CraftItemStack.patch similarity index 100% rename from patches/unapplied/1017-Proxy-ItemStack-to-CraftItemStack.patch rename to patches/unapplied/server/1017-Proxy-ItemStack-to-CraftItemStack.patch diff --git a/patches/unapplied/1018-Make-a-PDC-view-accessible-directly-from-ItemStack.patch b/patches/unapplied/server/1018-Make-a-PDC-view-accessible-directly-from-ItemStack.patch similarity index 100% rename from patches/unapplied/1018-Make-a-PDC-view-accessible-directly-from-ItemStack.patch rename to patches/unapplied/server/1018-Make-a-PDC-view-accessible-directly-from-ItemStack.patch diff --git a/patches/unapplied/1019-Prioritize-Minecraft-commands-in-function-parsing-an.patch b/patches/unapplied/server/1019-Prioritize-Minecraft-commands-in-function-parsing-an.patch similarity index 100% rename from patches/unapplied/1019-Prioritize-Minecraft-commands-in-function-parsing-an.patch rename to patches/unapplied/server/1019-Prioritize-Minecraft-commands-in-function-parsing-an.patch diff --git a/patches/unapplied/1020-optimize-dirt-and-snow-spreading.patch b/patches/unapplied/server/1020-optimize-dirt-and-snow-spreading.patch similarity index 100% rename from patches/unapplied/1020-optimize-dirt-and-snow-spreading.patch rename to patches/unapplied/server/1020-optimize-dirt-and-snow-spreading.patch diff --git a/patches/unapplied/1021-Fix-NPE-for-Jukebox-setRecord.patch b/patches/unapplied/server/1021-Fix-NPE-for-Jukebox-setRecord.patch similarity index 100% rename from patches/unapplied/1021-Fix-NPE-for-Jukebox-setRecord.patch rename to patches/unapplied/server/1021-Fix-NPE-for-Jukebox-setRecord.patch diff --git a/patches/unapplied/1022-Fix-CraftWorld-isChunkGenerated.patch b/patches/unapplied/server/1022-Fix-CraftWorld-isChunkGenerated.patch similarity index 100% rename from patches/unapplied/1022-Fix-CraftWorld-isChunkGenerated.patch rename to patches/unapplied/server/1022-Fix-CraftWorld-isChunkGenerated.patch diff --git a/patches/unapplied/1023-fix-horse-inventories.patch b/patches/unapplied/server/1023-fix-horse-inventories.patch similarity index 100% rename from patches/unapplied/1023-fix-horse-inventories.patch rename to patches/unapplied/server/1023-fix-horse-inventories.patch diff --git a/patches/unapplied/1024-Only-call-EntityDamageEvents-before-actuallyHurt.patch b/patches/unapplied/server/1024-Only-call-EntityDamageEvents-before-actuallyHurt.patch similarity index 100% rename from patches/unapplied/1024-Only-call-EntityDamageEvents-before-actuallyHurt.patch rename to patches/unapplied/server/1024-Only-call-EntityDamageEvents-before-actuallyHurt.patch diff --git a/patches/unapplied/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch b/patches/unapplied/server/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch similarity index 100% rename from patches/unapplied/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch rename to patches/unapplied/server/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch diff --git a/patches/unapplied/1026-Lag-compensation-ticks.patch b/patches/unapplied/server/1026-Lag-compensation-ticks.patch similarity index 100% rename from patches/unapplied/1026-Lag-compensation-ticks.patch rename to patches/unapplied/server/1026-Lag-compensation-ticks.patch diff --git a/patches/unapplied/1027-Detail-more-information-in-watchdog-dumps.patch b/patches/unapplied/server/1027-Detail-more-information-in-watchdog-dumps.patch similarity index 100% rename from patches/unapplied/1027-Detail-more-information-in-watchdog-dumps.patch rename to patches/unapplied/server/1027-Detail-more-information-in-watchdog-dumps.patch diff --git a/patches/unapplied/1028-Write-SavedData-IO-async.patch b/patches/unapplied/server/1028-Write-SavedData-IO-async.patch similarity index 100% rename from patches/unapplied/1028-Write-SavedData-IO-async.patch rename to patches/unapplied/server/1028-Write-SavedData-IO-async.patch diff --git a/patches/unapplied/1029-Add-ItemType-getItemRarity.patch b/patches/unapplied/server/1029-Add-ItemType-getItemRarity.patch similarity index 100% rename from patches/unapplied/1029-Add-ItemType-getItemRarity.patch rename to patches/unapplied/server/1029-Add-ItemType-getItemRarity.patch diff --git a/patches/unapplied/1030-Incremental-chunk-and-player-saving.patch b/patches/unapplied/server/1030-Incremental-chunk-and-player-saving.patch similarity index 100% rename from patches/unapplied/1030-Incremental-chunk-and-player-saving.patch rename to patches/unapplied/server/1030-Incremental-chunk-and-player-saving.patch diff --git a/patches/unapplied/1031-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch b/patches/unapplied/server/1031-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch similarity index 100% rename from patches/unapplied/1031-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch rename to patches/unapplied/server/1031-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch diff --git a/patches/unapplied/1032-Bundle-spark.patch b/patches/unapplied/server/1032-Bundle-spark.patch similarity index 100% rename from patches/unapplied/1032-Bundle-spark.patch rename to patches/unapplied/server/1032-Bundle-spark.patch diff --git a/patches/unapplied/1033-Add-plugin-info-at-startup.patch b/patches/unapplied/server/1033-Add-plugin-info-at-startup.patch similarity index 100% rename from patches/unapplied/1033-Add-plugin-info-at-startup.patch rename to patches/unapplied/server/1033-Add-plugin-info-at-startup.patch diff --git a/patches/unapplied/1034-Make-interaction-leniency-distance-configurable.patch b/patches/unapplied/server/1034-Make-interaction-leniency-distance-configurable.patch similarity index 100% rename from patches/unapplied/1034-Make-interaction-leniency-distance-configurable.patch rename to patches/unapplied/server/1034-Make-interaction-leniency-distance-configurable.patch diff --git a/patches/unapplied/1035-Fix-PickupStatus-getting-reset.patch b/patches/unapplied/server/1035-Fix-PickupStatus-getting-reset.patch similarity index 100% rename from patches/unapplied/1035-Fix-PickupStatus-getting-reset.patch rename to patches/unapplied/server/1035-Fix-PickupStatus-getting-reset.patch diff --git a/patches/unapplied/1036-Check-for-block-type-in-SculkSensorBlock-canActivate.patch b/patches/unapplied/server/1036-Check-for-block-type-in-SculkSensorBlock-canActivate.patch similarity index 100% rename from patches/unapplied/1036-Check-for-block-type-in-SculkSensorBlock-canActivate.patch rename to patches/unapplied/server/1036-Check-for-block-type-in-SculkSensorBlock-canActivate.patch diff --git a/patches/unapplied/1037-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch b/patches/unapplied/server/1037-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch similarity index 100% rename from patches/unapplied/1037-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch rename to patches/unapplied/server/1037-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch diff --git a/patches/unapplied/1038-Configuration-for-horizontal-only-item-merging.patch b/patches/unapplied/server/1038-Configuration-for-horizontal-only-item-merging.patch similarity index 100% rename from patches/unapplied/1038-Configuration-for-horizontal-only-item-merging.patch rename to patches/unapplied/server/1038-Configuration-for-horizontal-only-item-merging.patch diff --git a/patches/unapplied/1039-Optimise-collision-checking-in-player-move-packet-ha.patch b/patches/unapplied/server/1039-Optimise-collision-checking-in-player-move-packet-ha.patch similarity index 100% rename from patches/unapplied/1039-Optimise-collision-checking-in-player-move-packet-ha.patch rename to patches/unapplied/server/1039-Optimise-collision-checking-in-player-move-packet-ha.patch diff --git a/patches/unapplied/1040-Add-skipping-world-symlink-scan.patch b/patches/unapplied/server/1040-Add-skipping-world-symlink-scan.patch similarity index 100% rename from patches/unapplied/1040-Add-skipping-world-symlink-scan.patch rename to patches/unapplied/server/1040-Add-skipping-world-symlink-scan.patch diff --git a/patches/unapplied/1041-Add-even-more-Enchantment-API.patch b/patches/unapplied/server/1041-Add-even-more-Enchantment-API.patch similarity index 100% rename from patches/unapplied/1041-Add-even-more-Enchantment-API.patch rename to patches/unapplied/server/1041-Add-even-more-Enchantment-API.patch diff --git a/patches/unapplied/1042-Leashable-API.patch b/patches/unapplied/server/1042-Leashable-API.patch similarity index 100% rename from patches/unapplied/1042-Leashable-API.patch rename to patches/unapplied/server/1042-Leashable-API.patch diff --git a/patches/unapplied/1043-Fix-CraftBukkit-drag-system.patch b/patches/unapplied/server/1043-Fix-CraftBukkit-drag-system.patch similarity index 100% rename from patches/unapplied/1043-Fix-CraftBukkit-drag-system.patch rename to patches/unapplied/server/1043-Fix-CraftBukkit-drag-system.patch diff --git a/patches/unapplied/1044-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch b/patches/unapplied/server/1044-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch similarity index 100% rename from patches/unapplied/1044-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch rename to patches/unapplied/server/1044-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch diff --git a/patches/unapplied/1045-Remove-set-damage-lootable-item-function-from-compas.patch b/patches/unapplied/server/1045-Remove-set-damage-lootable-item-function-from-compas.patch similarity index 100% rename from patches/unapplied/1045-Remove-set-damage-lootable-item-function-from-compas.patch rename to patches/unapplied/server/1045-Remove-set-damage-lootable-item-function-from-compas.patch diff --git a/patches/unapplied/1046-Properly-destroy-placed-blocks-on-the-end-platform.patch b/patches/unapplied/server/1046-Properly-destroy-placed-blocks-on-the-end-platform.patch similarity index 100% rename from patches/unapplied/1046-Properly-destroy-placed-blocks-on-the-end-platform.patch rename to patches/unapplied/server/1046-Properly-destroy-placed-blocks-on-the-end-platform.patch diff --git a/patches/unapplied/1047-Add-enchantment-seed-update-API.patch b/patches/unapplied/server/1047-Add-enchantment-seed-update-API.patch similarity index 100% rename from patches/unapplied/1047-Add-enchantment-seed-update-API.patch rename to patches/unapplied/server/1047-Add-enchantment-seed-update-API.patch diff --git a/patches/unapplied/1048-Fix-synchronise-sending-chat-to-client-with-updating.patch b/patches/unapplied/server/1048-Fix-synchronise-sending-chat-to-client-with-updating.patch similarity index 100% rename from patches/unapplied/1048-Fix-synchronise-sending-chat-to-client-with-updating.patch rename to patches/unapplied/server/1048-Fix-synchronise-sending-chat-to-client-with-updating.patch diff --git a/patches/unapplied/1049-Fix-InventoryOpenEvent-cancellation.patch b/patches/unapplied/server/1049-Fix-InventoryOpenEvent-cancellation.patch similarity index 100% rename from patches/unapplied/1049-Fix-InventoryOpenEvent-cancellation.patch rename to patches/unapplied/server/1049-Fix-InventoryOpenEvent-cancellation.patch diff --git a/patches/unapplied/1050-Fire-BlockExpEvent-on-grindstone-use.patch b/patches/unapplied/server/1050-Fire-BlockExpEvent-on-grindstone-use.patch similarity index 100% rename from patches/unapplied/1050-Fire-BlockExpEvent-on-grindstone-use.patch rename to patches/unapplied/server/1050-Fire-BlockExpEvent-on-grindstone-use.patch diff --git a/patches/unapplied/1051-Check-dead-flag-in-isAlive.patch b/patches/unapplied/server/1051-Check-dead-flag-in-isAlive.patch similarity index 100% rename from patches/unapplied/1051-Check-dead-flag-in-isAlive.patch rename to patches/unapplied/server/1051-Check-dead-flag-in-isAlive.patch diff --git a/patches/unapplied/1052-Add-FeatureFlag-API.patch b/patches/unapplied/server/1052-Add-FeatureFlag-API.patch similarity index 100% rename from patches/unapplied/1052-Add-FeatureFlag-API.patch rename to patches/unapplied/server/1052-Add-FeatureFlag-API.patch diff --git a/patches/unapplied/1053-Tag-Lifecycle-Events.patch b/patches/unapplied/server/1053-Tag-Lifecycle-Events.patch similarity index 100% rename from patches/unapplied/1053-Tag-Lifecycle-Events.patch rename to patches/unapplied/server/1053-Tag-Lifecycle-Events.patch diff --git a/patches/unapplied/1054-Item-serialization-as-json.patch b/patches/unapplied/server/1054-Item-serialization-as-json.patch similarity index 100% rename from patches/unapplied/1054-Item-serialization-as-json.patch rename to patches/unapplied/server/1054-Item-serialization-as-json.patch diff --git a/patches/unapplied/1055-Validate-slot-in-PlayerInventory-setSlot.patch b/patches/unapplied/server/1055-Validate-slot-in-PlayerInventory-setSlot.patch similarity index 100% rename from patches/unapplied/1055-Validate-slot-in-PlayerInventory-setSlot.patch rename to patches/unapplied/server/1055-Validate-slot-in-PlayerInventory-setSlot.patch diff --git a/patches/unapplied/1056-Remove-wall-time-unused-skip-tick-protection.patch b/patches/unapplied/server/1056-Remove-wall-time-unused-skip-tick-protection.patch similarity index 100% rename from patches/unapplied/1056-Remove-wall-time-unused-skip-tick-protection.patch rename to patches/unapplied/server/1056-Remove-wall-time-unused-skip-tick-protection.patch diff --git a/patches/unapplied/1057-Disable-pretty-printing-for-advancement-saving.patch b/patches/unapplied/server/1057-Disable-pretty-printing-for-advancement-saving.patch similarity index 100% rename from patches/unapplied/1057-Disable-pretty-printing-for-advancement-saving.patch rename to patches/unapplied/server/1057-Disable-pretty-printing-for-advancement-saving.patch diff --git a/patches/unapplied/1058-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch b/patches/unapplied/server/1058-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch similarity index 100% rename from patches/unapplied/1058-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch rename to patches/unapplied/server/1058-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch diff --git a/patches/unapplied/1059-Add-enchantWithLevels-with-enchantment-registry-set.patch b/patches/unapplied/server/1059-Add-enchantWithLevels-with-enchantment-registry-set.patch similarity index 100% rename from patches/unapplied/1059-Add-enchantWithLevels-with-enchantment-registry-set.patch rename to patches/unapplied/server/1059-Add-enchantWithLevels-with-enchantment-registry-set.patch diff --git a/patches/unapplied/1060-Improve-entity-effect-API.patch b/patches/unapplied/server/1060-Improve-entity-effect-API.patch similarity index 100% rename from patches/unapplied/1060-Improve-entity-effect-API.patch rename to patches/unapplied/server/1060-Improve-entity-effect-API.patch diff --git a/patches/unapplied/1061-Add-recipeBrewTime.patch b/patches/unapplied/server/1061-Add-recipeBrewTime.patch similarity index 100% rename from patches/unapplied/1061-Add-recipeBrewTime.patch rename to patches/unapplied/server/1061-Add-recipeBrewTime.patch diff --git a/patches/unapplied/1062-Call-bucket-events-for-cauldrons.patch b/patches/unapplied/server/1062-Call-bucket-events-for-cauldrons.patch similarity index 100% rename from patches/unapplied/1062-Call-bucket-events-for-cauldrons.patch rename to patches/unapplied/server/1062-Call-bucket-events-for-cauldrons.patch diff --git a/patches/unapplied/1063-Add-PlayerInsertLecternBookEvent.patch b/patches/unapplied/server/1063-Add-PlayerInsertLecternBookEvent.patch similarity index 100% rename from patches/unapplied/1063-Add-PlayerInsertLecternBookEvent.patch rename to patches/unapplied/server/1063-Add-PlayerInsertLecternBookEvent.patch diff --git a/patches/unapplied/1064-Void-damage-configuration-API.patch b/patches/unapplied/server/1064-Void-damage-configuration-API.patch similarity index 100% rename from patches/unapplied/1064-Void-damage-configuration-API.patch rename to patches/unapplied/server/1064-Void-damage-configuration-API.patch diff --git a/patches/unapplied/1065-Add-Offline-PDC-API.patch b/patches/unapplied/server/1065-Add-Offline-PDC-API.patch similarity index 100% rename from patches/unapplied/1065-Add-Offline-PDC-API.patch rename to patches/unapplied/server/1065-Add-Offline-PDC-API.patch diff --git a/patches/unapplied/1066-Add-AnvilView-bypassEnchantmentLevelRestriction.patch b/patches/unapplied/server/1066-Add-AnvilView-bypassEnchantmentLevelRestriction.patch similarity index 100% rename from patches/unapplied/1066-Add-AnvilView-bypassEnchantmentLevelRestriction.patch rename to patches/unapplied/server/1066-Add-AnvilView-bypassEnchantmentLevelRestriction.patch diff --git a/patches/unapplied/1067-Add-proper-async-player-disconnections.patch b/patches/unapplied/server/1067-Add-proper-async-player-disconnections.patch similarity index 100% rename from patches/unapplied/1067-Add-proper-async-player-disconnections.patch rename to patches/unapplied/server/1067-Add-proper-async-player-disconnections.patch diff --git a/patches/unapplied/1068-Always-send-Banner-patterns-to-the-client.patch b/patches/unapplied/server/1068-Always-send-Banner-patterns-to-the-client.patch similarity index 100% rename from patches/unapplied/1068-Always-send-Banner-patterns-to-the-client.patch rename to patches/unapplied/server/1068-Always-send-Banner-patterns-to-the-client.patch diff --git a/patches/unapplied/9999-Optimise-nearby-player-retrieval.patch b/patches/unapplied/server/9999-Optimise-nearby-player-retrieval.patch similarity index 100% rename from patches/unapplied/9999-Optimise-nearby-player-retrieval.patch rename to patches/unapplied/server/9999-Optimise-nearby-player-retrieval.patch diff --git a/todo.txt b/todo.txt new file mode 100644 index 000000000000..8cb87a4cf78d --- /dev/null +++ b/todo.txt @@ -0,0 +1 @@ +MCUTILS: look at chunkmap changes around line 555. I removed our changes because I wasn't sure what changed, needs to be looked at! From 35854343828f944f7823d135eb49fe4c9d9da6c5 Mon Sep 17 00:00:00 2001 From: Noah van der Aa Date: Tue, 22 Oct 2024 20:04:31 +0200 Subject: [PATCH 005/119] first 100! --- patches/server/0009-MC-Utils.patch | 16 +-- patches/server/0010-Adventure.patch | 10 +- ...oleAppender-for-console-improvements.patch | 10 +- patches/server/0020-Plugin-remapping.patch | 6 +- patches/server/0023-Timings-v2.patch | 54 ++++++-- ...024-Further-improve-server-tick-loop.patch | 10 +- ...onfigurable-entity-despawn-distances.patch | 4 +- ...ck-and-tnt-entities-at-the-specified.patch | 20 +-- ...0033-Expose-server-build-information.patch | 32 ++--- .../0034-Player-affects-spawning-API.patch | 50 ++++---- ...035-Only-refresh-abilities-if-needed.patch | 4 +- .../server/0036-Entity-Origin-API.patch | 16 +-- ...vent-block-entity-and-entity-crashes.patch | 12 +- ...nfigurable-top-of-nether-void-damage.patch | 12 +- ...e-before-converting-and-renaming-pla.patch | 0 ...ties-to-activation-range-ignore-list.patch | 2 +- .../0041-Configurable-end-credits.patch | 4 +- ...-explosions-processing-dead-entities.patch | 19 +++ .../server/0043-Optimize-explosions.patch | 71 +++++----- .../0044-Disable-explosion-knockback.patch | 20 +-- .../server/0045-Disable-thunder.patch | 6 +- .../server/0046-Disable-ice-and-snow.patch | 4 +- ...7-Configurable-mob-spawner-tick-rate.patch | 2 +- .../0048-Use-null-Locale-by-default.patch | 14 +- .../server/0049-Add-BeaconEffectEvent.patch | 2 +- ...figurable-container-update-tick-rate.patch | 8 +- .../0051-Use-UserCache-for-player-heads.patch | 0 .../0052-Disable-spigot-tick-limiters.patch | 4 +- ...awn-location-event-changing-location.patch | 4 +- ...urable-Disabling-Cat-Chest-Detection.patch | 4 +- ...055-Improve-Player-chat-API-handling.patch | 14 +- ...chunks-are-slime-spawn-chunks-toggle.patch | 16 +-- .../0057-Expose-server-CommandMap.patch | 4 +- ...e-informative-in-maxHealth-exception.patch | 4 +- .../0059-Player-Tab-List-and-Title-APIs.patch | 4 +- ...dd-configurable-portal-search-radius.patch | 6 +- .../server/0061-Add-velocity-warnings.patch | 8 +- .../0062-Add-exception-reporting-event.patch | 26 ++-- ...oreboards-for-non-players-by-default.patch | 8 +- ...working-with-arrows-stuck-in-living-.patch | 8 +- .../server/0065-Chunk-Save-Reattempt.patch | 0 .../0066-Complete-resource-pack-API.patch | 10 +- ...ading-permissions.yml-before-plugins.patch | 6 +- ...llow-Reloading-of-Custom-Permissions.patch | 4 +- .../0069-Remove-Metadata-on-reload.patch | 4 +- ...070-Handle-Item-Meta-Inconsistencies.patch | 34 ++--- ...urable-Non-Player-Arrow-Despawn-Rate.patch | 4 +- .../server/0072-Add-World-Util-Methods.patch | 2 +- ...3-Custom-replacement-for-eaten-items.patch | 10 +- ...th-absorb-values-and-repair-bad-data.patch | 12 +- ...075-Use-a-Shared-Random-for-Entities.patch | 10 +- ...le-spawn-chances-for-skeleton-horses.patch | 6 +- ...ckPhysicsEvent-if-a-plugin-has-a-lis.patch | 26 ++-- ...Entity-AddTo-RemoveFrom-World-Events.patch | 6 +- ...79-Configurable-Chunk-Inhabited-Time.patch | 6 +- .../server/0080-EntityPathfindEvent.patch | 42 +++--- ...egionFileCache-and-make-configurable.patch | 0 ...2-Do-not-load-chunks-for-Pathfinding.patch | 2 +- ...0083-Add-PlayerUseUnknownEntityEvent.patch | 8 +- ...gurable-random-tick-rates-for-blocks.patch | 4 +- ...g-BlockPlaceEvent-triggering-physics.patch | 14 +- .../server/0086-Optimize-DataBits.patch | 0 ...nilla-per-world-scoreboard-coloring-.patch | 0 .../0088-Configurable-Player-Collision.patch | 20 +-- ...ent-to-allow-plugins-to-handle-clien.patch | 0 .../0090-Configurable-RCON-IP-address.patch | 4 +- ...ityRegainHealthEvent-isFastRegen-API.patch | 8 +- ...-to-configure-frosted_ice-properties.patch | 8 +- ...-possibility-for-getServer-singleton.patch | 12 +- ...y-scoreboard-teams-to-scoreboard.dat.patch | 2 +- ...able-API-and-replenishable-lootables.patch | 121 +++++++++--------- ...tem-property-for-disabling-watchdoge.patch | 0 .../0097-Async-GameProfileCache-saving.patch | 10 +- ...8-Optional-TNT-doesn-t-move-in-water.patch | 28 ++-- ...r-redstone-torch-rapid-clock-removal.patch | 14 +- .../0100-Add-server-name-parameter.patch | 2 +- ...-explosions-processing-dead-entities.patch | 19 --- 77 files changed, 508 insertions(+), 468 deletions(-) rename patches/{unapplied => }/server/0031-Add-configurable-entity-despawn-distances.patch (94%) rename patches/{unapplied => }/server/0032-Drop-falling-block-and-tnt-entities-at-the-specified.patch (80%) rename patches/{unapplied => }/server/0033-Expose-server-build-information.patch (96%) rename patches/{unapplied => }/server/0034-Player-affects-spawning-API.patch (75%) rename patches/{unapplied => }/server/0035-Only-refresh-abilities-if-needed.patch (87%) rename patches/{unapplied => }/server/0036-Entity-Origin-API.patch (88%) rename patches/{unapplied => }/server/0037-Prevent-block-entity-and-entity-crashes.patch (89%) rename patches/{unapplied => }/server/0038-Configurable-top-of-nether-void-damage.patch (83%) rename patches/{unapplied => }/server/0039-Check-online-mode-before-converting-and-renaming-pla.patch (100%) rename patches/{unapplied => }/server/0040-Add-more-entities-to-activation-range-ignore-list.patch (92%) rename patches/{unapplied => }/server/0041-Configurable-end-credits.patch (85%) create mode 100644 patches/server/0042-Fix-lag-from-explosions-processing-dead-entities.patch rename patches/{unapplied => }/server/0043-Optimize-explosions.patch (69%) rename patches/{unapplied => }/server/0044-Disable-explosion-knockback.patch (52%) rename patches/{unapplied => }/server/0045-Disable-thunder.patch (80%) rename patches/{unapplied => }/server/0046-Disable-ice-and-snow.patch (83%) rename patches/{unapplied => }/server/0047-Configurable-mob-spawner-tick-rate.patch (94%) rename patches/{unapplied => }/server/0048-Use-null-Locale-by-default.patch (83%) rename patches/{unapplied => }/server/0049-Add-BeaconEffectEvent.patch (97%) rename patches/{unapplied => }/server/0050-Configurable-container-update-tick-rate.patch (83%) rename patches/{unapplied => }/server/0051-Use-UserCache-for-player-heads.patch (100%) rename patches/{unapplied => }/server/0052-Disable-spigot-tick-limiters.patch (88%) rename patches/{unapplied => }/server/0053-Fix-spawn-location-event-changing-location.patch (87%) rename patches/{unapplied => }/server/0054-Configurable-Disabling-Cat-Chest-Detection.patch (88%) rename patches/{unapplied => }/server/0055-Improve-Player-chat-API-handling.patch (88%) rename patches/{unapplied => }/server/0056-All-chunks-are-slime-spawn-chunks-toggle.patch (69%) rename patches/{unapplied => }/server/0057-Expose-server-CommandMap.patch (78%) rename patches/{unapplied => }/server/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch (89%) rename patches/{unapplied => }/server/0059-Player-Tab-List-and-Title-APIs.patch (96%) rename patches/{unapplied => }/server/0060-Add-configurable-portal-search-radius.patch (91%) rename patches/{unapplied => }/server/0061-Add-velocity-warnings.patch (93%) rename patches/{unapplied => }/server/0062-Add-exception-reporting-event.patch (92%) rename patches/{unapplied => }/server/0063-Disable-Scoreboards-for-non-players-by-default.patch (85%) rename patches/{unapplied => }/server/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch (88%) rename patches/{unapplied => }/server/0065-Chunk-Save-Reattempt.patch (100%) rename patches/{unapplied => }/server/0066-Complete-resource-pack-API.patch (87%) rename patches/{unapplied => }/server/0067-Default-loading-permissions.yml-before-plugins.patch (89%) rename patches/{unapplied => }/server/0068-Allow-Reloading-of-Custom-Permissions.patch (90%) rename patches/{unapplied => }/server/0069-Remove-Metadata-on-reload.patch (88%) rename patches/{unapplied => }/server/0070-Handle-Item-Meta-Inconsistencies.patch (93%) rename patches/{unapplied => }/server/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch (89%) rename patches/{unapplied => }/server/0072-Add-World-Util-Methods.patch (94%) rename patches/{unapplied => }/server/0073-Custom-replacement-for-eaten-items.patch (87%) rename patches/{unapplied => }/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch (85%) rename patches/{unapplied => }/server/0075-Use-a-Shared-Random-for-Entities.patch (91%) rename patches/{unapplied => }/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch (83%) rename patches/{unapplied => }/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch (74%) rename patches/{unapplied => }/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch (79%) rename patches/{unapplied => }/server/0079-Configurable-Chunk-Inhabited-Time.patch (81%) rename patches/{unapplied => }/server/0080-EntityPathfindEvent.patch (81%) rename patches/{unapplied => }/server/0081-Sanitise-RegionFileCache-and-make-configurable.patch (100%) rename patches/{unapplied => }/server/0082-Do-not-load-chunks-for-Pathfinding.patch (91%) rename patches/{unapplied => }/server/0083-Add-PlayerUseUnknownEntityEvent.patch (92%) rename patches/{unapplied => }/server/0084-Configurable-random-tick-rates-for-blocks.patch (93%) rename patches/{unapplied => }/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch (54%) rename patches/{unapplied => }/server/0086-Optimize-DataBits.patch (100%) rename patches/{unapplied => }/server/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch (100%) rename patches/{unapplied => }/server/0088-Configurable-Player-Collision.patch (91%) rename patches/{unapplied => }/server/0089-Add-handshake-event-to-allow-plugins-to-handle-clien.patch (100%) rename patches/{unapplied => }/server/0090-Configurable-RCON-IP-address.patch (94%) rename patches/{unapplied => }/server/0091-EntityRegainHealthEvent-isFastRegen-API.patch (88%) rename patches/{unapplied => }/server/0092-Add-ability-to-configure-frosted_ice-properties.patch (87%) rename patches/{unapplied => }/server/0093-remove-null-possibility-for-getServer-singleton.patch (83%) rename patches/{unapplied => }/server/0094-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch (92%) rename patches/{unapplied => }/server/0095-LootTable-API-and-replenishable-lootables.patch (92%) rename patches/{unapplied => }/server/0096-System-property-for-disabling-watchdoge.patch (100%) rename patches/{unapplied => }/server/0097-Async-GameProfileCache-saving.patch (89%) rename patches/{unapplied => }/server/0098-Optional-TNT-doesn-t-move-in-water.patch (67%) rename patches/{unapplied => }/server/0099-Faster-redstone-torch-rapid-clock-removal.patch (86%) rename patches/{unapplied => }/server/0100-Add-server-name-parameter.patch (90%) delete mode 100644 patches/unapplied/server/0042-Fix-lag-from-explosions-processing-dead-entities.patch diff --git a/patches/server/0009-MC-Utils.patch b/patches/server/0009-MC-Utils.patch index 5c84ecfe2d17..3535d37a4567 100644 --- a/patches/server/0009-MC-Utils.patch +++ b/patches/server/0009-MC-Utils.patch @@ -4416,18 +4416,10 @@ index 3e5a85a7ad6149b04622c254fbc2e174896a4128..3f662692ed4846e026a9d48595e7b3b2 + } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 8e16bc7da15824723f1d7d4bff87fac181978500..83b32b2963febf8af9ccd7df666cbaccc62f1313 100644 +index 8e16bc7da15824723f1d7d4bff87fac181978500..709330ca9caa82a6de71767b3d5c32f97ea1d68b 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -334,7 +334,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 4) { - thread.setPriority(8); - } -- - S s0 = serverFactory.apply(thread); // CraftBukkit - decompile error - - atomicreference.set(s0); -@@ -988,6 +987,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; -@@ -397,7 +396,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource { -@@ -925,6 +925,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { entityplayer.connection.suspendFlushing(); }); @@ -865,7 +865,7 @@ index 3d1e9f24b83513c9f499471e7eefaf639f9097ec..4502e2cf565b7b0547a1963b1119d781 // Send time updates to everyone, it will get the right time from the world the player is in. if (this.tickCount % 20 == 0) { for (int i = 0; i < this.getPlayerList().players.size(); ++i) { -@@ -1532,7 +1554,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop biomeRegistry, ChunkPos chun + @Nullable + private static LevelChunk.PostLoadProcessor postLoadChunk(ServerLevel world, List entities, List blockEntities) { + return entities.isEmpty() && blockEntities.isEmpty() ? null : (chunk) -> { +- world.timings.syncChunkLoadEntitiesTimer.startTiming(); // Spigot + if (!entities.isEmpty()) { + world.addLegacyChunkEntities(EntityType.loadEntitiesRecursive(entities, world, EntitySpawnReason.LOAD)); + } +- world.timings.syncChunkLoadEntitiesTimer.stopTiming(); // Spigot + + Iterator iterator = blockEntities.iterator(); + +- world.timings.syncChunkLoadTileEntitiesTimer.startTiming(); // Spigot + while (iterator.hasNext()) { + CompoundTag nbttagcompound = (CompoundTag) iterator.next(); + boolean flag = nbttagcompound.getBoolean("keepPacked"); +@@ -600,7 +597,6 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + } + } + } +- world.timings.syncChunkLoadTileEntitiesTimer.stopTiming(); // Spigot + + }; + } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 9bf8c4d9154c433e586f59587e8d7db7c310bb9c..232a21080ff416ac5b9fdf913f6784eb3bcdacfa 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/patches/server/0024-Further-improve-server-tick-loop.patch b/patches/server/0024-Further-improve-server-tick-loop.patch index a5a6fbafa83c..a22f901b49bd 100644 --- a/patches/server/0024-Further-improve-server-tick-loop.patch +++ b/patches/server/0024-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 4502e2cf565b7b0547a1963b1119d7810b7a0bcb..36a3fa8847afc0d0831054958886a04a1d847596 100644 +index 638d648be24c9907bab6dcb671f42c4cf569e2d7..95e8d720ae23fb54b2253588cdf90ced4904066f 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -307,7 +307,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java -index a4e8fa5267b8853603e4683bf9d002db7465e4b6..c3a16691e8a843c02e0aea6469822cd8869ad593 100644 +index e9e8ad33371749f52a88a0ee089540eb26fb0f28..5ed77cc6c8b0459691d8044232d9972e4278964b 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java -@@ -149,6 +149,16 @@ public class FallingBlockEntity extends Entity { - ++this.time; +@@ -159,6 +159,16 @@ public class FallingBlockEntity extends Entity { this.applyGravity(); this.move(MoverType.SELF, this.getDeltaMovement()); + this.applyEffectsFromBlocks(); + // Paper start - Configurable falling blocks height nerf + if (this.level().paperConfig().fixes.fallingBlockHeightNerf.test(v -> this.getY() > v)) { + if (this.dropItem && this.level().getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { @@ -24,16 +24,16 @@ index a4e8fa5267b8853603e4683bf9d002db7465e4b6..c3a16691e8a843c02e0aea6469822cd8 + } + // Paper end - Configurable falling blocks height nerf this.handlePortal(); - if (!this.level().isClientSide && (this.isAlive() || this.forceTickAfterTeleportToDuplicate)) { - BlockPos blockposition = this.blockPosition(); + Level world = this.level(); + diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -index 8f693bb45099124bca62849528c81d717131a48c..15432b512fc0d0d38bf28499e2afa5e48fec7aaa 100644 +index 91381122b5b63139be880f80dadde4d8cf31a260..3d489fdc14b3e29bab63f330d5edbbc1d354382a 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -@@ -99,6 +99,12 @@ public class PrimedTnt extends Entity implements TraceableEntity { - this.handlePortal(); +@@ -106,6 +106,12 @@ public class PrimedTnt extends Entity implements TraceableEntity { this.applyGravity(); this.move(MoverType.SELF, this.getDeltaMovement()); + this.applyEffectsFromBlocks(); + // Paper start - Configurable TNT height nerf + if (this.level().paperConfig().fixes.tntEntityHeightNerf.test(v -> this.getY() > v)) { + this.discard(EntityRemoveEvent.Cause.OUT_OF_WORLD); @@ -44,10 +44,10 @@ index 8f693bb45099124bca62849528c81d717131a48c..15432b512fc0d0d38bf28499e2afa5e4 if (this.onGround()) { this.setDeltaMovement(this.getDeltaMovement().multiply(0.7D, -0.5D, 0.7D)); diff --git a/src/main/java/net/minecraft/world/entity/vehicle/MinecartTNT.java b/src/main/java/net/minecraft/world/entity/vehicle/MinecartTNT.java -index c112c4b103c34e05f4de973eec94a969f60b085e..b7036f8399e2500ba01736c6006b972f7ca4838e 100644 +index ef87b0b4dbf4f08b7ec00eed0eb4df2e3f13d4a7..0652494dc5f3d999116d4380032dea0e7402caec 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/MinecartTNT.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/MinecartTNT.java -@@ -54,6 +54,12 @@ public class MinecartTNT extends AbstractMinecart { +@@ -52,6 +52,12 @@ public class MinecartTNT extends AbstractMinecart { public void tick() { super.tick(); if (this.fuse > 0) { diff --git a/patches/unapplied/server/0033-Expose-server-build-information.patch b/patches/server/0033-Expose-server-build-information.patch similarity index 96% rename from patches/unapplied/server/0033-Expose-server-build-information.patch rename to patches/server/0033-Expose-server-build-information.patch index 3dfb0b097f86..d38434d30412 100644 --- a/patches/unapplied/server/0033-Expose-server-build-information.patch +++ b/patches/server/0033-Expose-server-build-information.patch @@ -11,7 +11,7 @@ Co-authored-by: Jake Potrebic Co-authored-by: masmc05 diff --git a/build.gradle.kts b/build.gradle.kts -index 6d8f4c3b290609d60dbcabe3d2c8274b017246c8..0c349354ba76dfd2c5f16fb232263b18e77a9a40 100644 +index e1cfa2188dbe583a0180be2243a7a554dc5412d7..da2f9c5afb2994f403a1128af0f7acbd6b73b862 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,5 @@ @@ -533,18 +533,18 @@ index 0000000000000000000000000000000000000000..790bad0494454ca12ee152e3de6da3da + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 46e03617bb32e4037d700c1b3698d397bd75de5c..2f57739431eb695149019724e2923f0d02e88d07 100644 +index 95e8d720ae23fb54b2253588cdf90ced4904066f..f9ff8b922c47a8a59b9be55a9f3498e2ba68ac44 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -43,7 +43,6 @@ import java.util.Set; +@@ -45,7 +45,6 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; -import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.atomic.AtomicReference; + import java.util.concurrent.locks.LockSupport; import java.util.function.BooleanSupplier; - import java.util.function.Consumer; -@@ -191,8 +190,6 @@ import net.minecraft.world.phys.Vec2; +@@ -198,8 +197,6 @@ import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.CraftRegistry; @@ -553,7 +553,7 @@ index 46e03617bb32e4037d700c1b3698d397bd75de5c..2f57739431eb695149019724e2923f0d import org.bukkit.event.server.ServerLoadEvent; // CraftBukkit end -@@ -1700,7 +1697,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop getOnlinePlayers() { return this.playerView; diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 034d68c2715b6a90f31e56f949ff3d27235a26eb..a7fbbe40f2382e7af185c4bfdd451fc1998b3636 100644 +index 03790abcc3474999db6d8986e50ebc2caf6eba0c..13f811173c67533ee02f70cc4b6b398cd527c84b 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -15,6 +15,7 @@ import joptsimple.OptionSet; @@ -671,7 +671,7 @@ index 034d68c2715b6a90f31e56f949ff3d27235a26eb..a7fbbe40f2382e7af185c4bfdd451fc1 public static boolean useConsole = true; @@ -241,15 +242,17 @@ public class Main { - deadline.add(Calendar.DAY_OF_YEAR, -28); + deadline.add(Calendar.DAY_OF_YEAR, -3); if (buildDate.before(deadline.getTime())) { System.err.println("*** Error, this build is outdated ***"); - System.err.println("*** Please download a new build as per instructions from https://www.spigotmc.org/go/outdated-spigot ***"); @@ -692,7 +692,7 @@ index 034d68c2715b6a90f31e56f949ff3d27235a26eb..a7fbbe40f2382e7af185c4bfdd451fc1 t.printStackTrace(); } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index f7b80cf8c89ae5eb9d8f0893e05ffc753fdace19..432f019afff36aa6143c052f7387a6c275a09de8 100644 +index 1e8b13096b0ebed35290c9cbe6b8fb8f4b054b34..d5038fb8720bfe39ffaf3fdea072c01487d315f9 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -459,6 +459,11 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/unapplied/server/0034-Player-affects-spawning-API.patch b/patches/server/0034-Player-affects-spawning-API.patch similarity index 75% rename from patches/unapplied/server/0034-Player-affects-spawning-API.patch rename to patches/server/0034-Player-affects-spawning-API.patch index 654234cc3612..d5b03dc4aa51 100644 --- a/patches/unapplied/server/0034-Player-affects-spawning-API.patch +++ b/patches/server/0034-Player-affects-spawning-API.patch @@ -5,11 +5,11 @@ Subject: [PATCH] Player affects spawning API diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java -index 3126e8cab3c40e3af47f4c8925e1c6a9523309ba..3207166061bf9c4d7bf3f38e5a9f7aff23ccd5c1 100644 +index 048c8af16fad8708a486bb29304db22e2fb1ecb3..a617ea34cfc28cefd68dd14ffbb334b87f98f65c 100644 --- a/src/main/java/net/minecraft/world/entity/EntitySelector.java +++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java -@@ -30,6 +30,11 @@ public final class EntitySelector { - public static final Predicate CAN_BE_COLLIDED_WITH = EntitySelector.NO_SPECTATORS.and(Entity::canBeCollidedWith); +@@ -29,6 +29,11 @@ public final class EntitySelector { + public static final Predicate CAN_BE_PICKED = EntitySelector.NO_SPECTATORS.and(Entity::isPickable); private EntitySelector() {} + // Paper start - Affects Spawning API @@ -21,10 +21,10 @@ index 3126e8cab3c40e3af47f4c8925e1c6a9523309ba..3207166061bf9c4d7bf3f38e5a9f7aff public static Predicate withinDistance(double x, double y, double z, double max) { double d4 = max * max; diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 4ce1586351b417aede1fd401907388b5fa0e9fd6..d8beadc96a7f779c39c8e22ffe52d872ac49a0ad 100644 +index efa1d813699286c0a2632f44c4d7eecd06e8aa64..9655466953cf850b82716246821a3ebb968a5478 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -860,7 +860,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -858,7 +858,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) { this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } else if (!this.isPersistenceRequired() && !this.requiresCustomPersistence()) { @@ -34,7 +34,7 @@ index 4ce1586351b417aede1fd401907388b5fa0e9fd6..d8beadc96a7f779c39c8e22ffe52d872 if (entityhuman != null) { // Paper start - Configurable despawn distances diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java -index 3b7fc11b7832a72fb9b0806fe9847f4e30759e7b..3cb84856c10347162a8736ae1ef65165183ec8fe 100644 +index c86e2d75ac627e9c92a6e006cb4c06ec6a2cb91e..521b09ac14372f524b06ffdce57932d0a590700b 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java @@ -27,7 +27,7 @@ public class SkeletonTrapGoal extends Goal { @@ -47,33 +47,33 @@ index 3b7fc11b7832a72fb9b0806fe9847f4e30759e7b..3cb84856c10347162a8736ae1ef65165 @Override diff --git a/src/main/java/net/minecraft/world/entity/monster/Silverfish.java b/src/main/java/net/minecraft/world/entity/monster/Silverfish.java -index 95e9d38dbccbd1c43ababd707e18dfe6779256c1..9ff42b0ae2b82dc3092e38e1439d89b4ab554b17 100644 +index 0594b6adcb849bba2c810de245a3bdaeeca0be60..52d8ea3e40cdb01eab428f5d3d945c0c9f6088ce 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Silverfish.java +++ b/src/main/java/net/minecraft/world/entity/monster/Silverfish.java -@@ -118,7 +118,7 @@ public class Silverfish extends Monster { - if (checkAnyLightMonsterSpawnRules(type, world, spawnReason, pos, random)) { +@@ -123,7 +123,7 @@ public class Silverfish extends Monster { + } else { Player entityhuman = world.getNearestPlayer((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, 5.0D, true); - return entityhuman == null; + return !(entityhuman != null && !entityhuman.affectsSpawning) && entityhuman == null; // Paper - Affects Spawning API - } else { - return false; } + } + diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index 393a9c704f4637a0e8031328d2a0facef4723dd8..d97c3c139f10a45febc0cfb1057ff6e33266228e 100644 +index 3836d9255ac326a7220e1decd2e9d98be7884c17..ab7500864e3a77444212bce4eb6ea75976f5ee5a 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -@@ -328,7 +328,7 @@ public class Zombie extends Monster { +@@ -349,7 +349,7 @@ public class Zombie extends Monster { - if (SpawnPlacements.isSpawnPositionOk(entitytypes, this.level(), blockposition) && SpawnPlacements.checkSpawnRules(entitytypes, worldserver, MobSpawnType.REINFORCEMENT, blockposition, this.level().random)) { + if (SpawnPlacements.isSpawnPositionOk(entitytypes, world, blockposition) && SpawnPlacements.checkSpawnRules(entitytypes, world, EntitySpawnReason.REINFORCEMENT, blockposition, world.random)) { entityzombie.setPos((double) i1, (double) j1, (double) k1); -- if (!this.level().hasNearbyAlivePlayer((double) i1, (double) j1, (double) k1, 7.0D) && this.level().isUnobstructed(entityzombie) && this.level().noCollision((Entity) entityzombie) && !this.level().containsAnyLiquid(entityzombie.getBoundingBox())) { -+ if (!this.level().hasNearbyAlivePlayerThatAffectsSpawning((double) i1, (double) j1, (double) k1, 7.0D) && this.level().isUnobstructed(entityzombie) && this.level().noCollision((Entity) entityzombie) && !this.level().containsAnyLiquid(entityzombie.getBoundingBox())) { // Paper - Affects Spawning API +- if (!world.hasNearbyAlivePlayer((double) i1, (double) j1, (double) k1, 7.0D) && world.isUnobstructed(entityzombie) && world.noCollision((Entity) entityzombie) && (entityzombie.canSpawnInLiquids() || !world.containsAnyLiquid(entityzombie.getBoundingBox()))) { ++ if (!world.hasNearbyAlivePlayerhasNearbyAlivePlayerThatAffectsSpawning((double) i1, (double) j1, (double) k1, 7.0D) && world.isUnobstructed(entityzombie) && world.noCollision((Entity) entityzombie) && (entityzombie.canSpawnInLiquids() || !world.containsAnyLiquid(entityzombie.getBoundingBox()))) { // Paper - affects spawning api entityzombie.setTarget(entityliving, EntityTargetEvent.TargetReason.REINFORCEMENT_TARGET, true); // CraftBukkit - entityzombie.finalizeSpawn(worldserver, this.level().getCurrentDifficultyAt(entityzombie.blockPosition()), MobSpawnType.REINFORCEMENT, (SpawnGroupData) null); - worldserver.addFreshEntityWithPassengers(entityzombie, CreatureSpawnEvent.SpawnReason.REINFORCEMENTS); // CraftBukkit + entityzombie.finalizeSpawn(world, world.getCurrentDifficultyAt(entityzombie.blockPosition()), EntitySpawnReason.REINFORCEMENT, (SpawnGroupData) null); + world.addFreshEntityWithPassengers(entityzombie, CreatureSpawnEvent.SpawnReason.REINFORCEMENTS); // CraftBukkit diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index 56f4d85d0d2014dfe4fb2598fa813ffc4a768d25..ba279ab6ec0ab41309607333b62a941e35dbf581 100644 +index a879d715a78ff32cfb377dd29cd9facaf21b3f32..b953b8e7e184c0c0eb7231564ad120765d66823a 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java @@ -195,6 +195,7 @@ public abstract class Player extends LivingEntity { @@ -85,7 +85,7 @@ index 56f4d85d0d2014dfe4fb2598fa813ffc4a768d25..ba279ab6ec0ab41309607333b62a941e // CraftBukkit start public boolean fauxSleeping; diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index cc54da2987fafcbd69153c33033a6f272dd3be66..418e29971326008ebca0cc4b696a41a49c1c7bb7 100644 +index b2bed46f809abee056aa99f39f26f8c0fbf0036c..366661561544f8e99f238583259991e9fcbab8af 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java @@ -58,7 +58,7 @@ public abstract class BaseSpawner { @@ -98,10 +98,10 @@ index cc54da2987fafcbd69153c33033a6f272dd3be66..418e29971326008ebca0cc4b696a41a4 public void clientTick(Level world, BlockPos pos) { diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java -index f38f62e777d88a783e1e3b7e1a48da921cc67cf4..77ae7882a08441d9a80b50492be5e48487a2fdab 100644 +index f689b2ca0ebc15c099f36ebfd14e455bda540296..fb043d67eaa6336fc0b5d62774b8f1107f9dfa1e 100644 --- a/src/main/java/net/minecraft/world/level/EntityGetter.java +++ b/src/main/java/net/minecraft/world/level/EntityGetter.java -@@ -74,6 +74,11 @@ public interface EntityGetter { +@@ -71,6 +71,11 @@ public interface EntityGetter { } } @@ -113,7 +113,7 @@ index f38f62e777d88a783e1e3b7e1a48da921cc67cf4..77ae7882a08441d9a80b50492be5e484 @Nullable default Player getNearestPlayer(double x, double y, double z, double maxDistance, @Nullable Predicate targetPredicate) { double d = -1.0; -@@ -103,6 +108,20 @@ public interface EntityGetter { +@@ -100,6 +105,20 @@ public interface EntityGetter { return this.getNearestPlayer(x, y, z, maxDistance, predicate); } @@ -135,10 +135,10 @@ index f38f62e777d88a783e1e3b7e1a48da921cc67cf4..77ae7882a08441d9a80b50492be5e484 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 68b9b4aba7dba31e4526165e6efb8c40f9e841bc..1b2ead250233d9f228bfe8e79f988026506895f9 100644 +index dafd4105f4ad4729c7637a7b0e5606ff0ec326d1..b5f69a6beaf42abf25463530870c2d7311b18571 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2425,6 +2425,17 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2438,6 +2438,17 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.getHandle().language; } diff --git a/patches/unapplied/server/0035-Only-refresh-abilities-if-needed.patch b/patches/server/0035-Only-refresh-abilities-if-needed.patch similarity index 87% rename from patches/unapplied/server/0035-Only-refresh-abilities-if-needed.patch rename to patches/server/0035-Only-refresh-abilities-if-needed.patch index 3af5f88628f1..2f754caff980 100644 --- a/patches/unapplied/server/0035-Only-refresh-abilities-if-needed.patch +++ b/patches/server/0035-Only-refresh-abilities-if-needed.patch @@ -5,10 +5,10 @@ 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 4cc6b3162cea049134f194ed84a7552830cb85af..c2be21491183f5f113dbfc71a7e0ccd195679296 100644 +index b5f69a6beaf42abf25463530870c2d7311b18571..2a6db82c926bb5551035f4b040502215d35355fb 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2093,12 +2093,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2106,12 +2106,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setFlying(boolean value) { diff --git a/patches/unapplied/server/0036-Entity-Origin-API.patch b/patches/server/0036-Entity-Origin-API.patch similarity index 88% rename from patches/unapplied/server/0036-Entity-Origin-API.patch rename to patches/server/0036-Entity-Origin-API.patch index eaf335d0d358..0762019efff1 100644 --- a/patches/unapplied/server/0036-Entity-Origin-API.patch +++ b/patches/server/0036-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 eb98bb1bd76869fd76b34885223c8e57a04e0c51..754045e71f180862fa57fd1c97e5d7deb1d788e6 100644 +index d82f4255faac84ce6af47e86707f5c035529ab5d..a31371dd479f5d87ff62728504563815bb5e22f8 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2141,6 +2141,15 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2212,6 +2212,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe entity.updateDynamicGameEventListener(DynamicGameEventListener::add); entity.inWorld = true; // CraftBukkit - Mark entity as in world entity.valid = true; // CraftBukkit @@ -25,10 +25,10 @@ index eb98bb1bd76869fd76b34885223c8e57a04e0c51..754045e71f180862fa57fd1c97e5d7de 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 63f45a77c8511e05954030cf117c5e4cda0a518f..dbe5239b1a1769ef9f2ef66c32b1a68cd684428e 100644 +index c8b8102d84119dfb6093f4b79aa3124c594f9a88..e97853cbfa6da8ecdb4c92cf634831492e1fc7e3 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -328,7 +328,27 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -331,7 +331,27 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public long activatedTick = Integer.MIN_VALUE; public void inactiveTick() { } // Spigot end @@ -56,7 +56,7 @@ index 63f45a77c8511e05954030cf117c5e4cda0a518f..dbe5239b1a1769ef9f2ef66c32b1a68c public float getBukkitYaw() { return this.yRot; } -@@ -2153,6 +2173,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2269,6 +2289,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.bukkitEntity.storeBukkitValues(nbttagcompound); } // CraftBukkit end @@ -72,7 +72,7 @@ index 63f45a77c8511e05954030cf117c5e4cda0a518f..dbe5239b1a1769ef9f2ef66c32b1a68c return nbttagcompound; } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT"); -@@ -2280,6 +2309,20 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2397,6 +2426,20 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } // CraftBukkit end @@ -94,10 +94,10 @@ index 63f45a77c8511e05954030cf117c5e4cda0a518f..dbe5239b1a1769ef9f2ef66c32b1a68c CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT"); CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being loaded"); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 269326e7689eba91bcfd3475006e8cbf8f5694ef..7b45a1216ff824f1b528bb5759d10b70858832a1 100644 +index 978397e517a6fdb24c7d2b3f242545af07deeab0..ea27931d01c1f3c721b2f7ec12d41ea843fa158a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -963,4 +963,21 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -964,4 +964,21 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return this.spigot; } // Spigot end diff --git a/patches/unapplied/server/0037-Prevent-block-entity-and-entity-crashes.patch b/patches/server/0037-Prevent-block-entity-and-entity-crashes.patch similarity index 89% rename from patches/unapplied/server/0037-Prevent-block-entity-and-entity-crashes.patch rename to patches/server/0037-Prevent-block-entity-and-entity-crashes.patch index 59cb59cc0fe8..01c8a71861fd 100644 --- a/patches/unapplied/server/0037-Prevent-block-entity-and-entity-crashes.patch +++ b/patches/server/0037-Prevent-block-entity-and-entity-crashes.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent block entity and entity crashes diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 79d5423be919dfe4db75ad7dd0ce403ad0214462..e8b8475dd6fd7b89651f744da2cb9696c73ddc3e 100644 +index 5df862e026e15e10e2fcc7c5a49e8a8022125579..d15c7ed69068ba5832c92860cae56ff4a96cd398 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -731,11 +731,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -733,11 +733,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { try { tickConsumer.accept(entity); } catch (Throwable throwable) { @@ -26,10 +26,10 @@ index 79d5423be919dfe4db75ad7dd0ce403ad0214462..e8b8475dd6fd7b89651f744da2cb9696 } diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index 17cda4c8b61efd99c1a43f921ed604827bb064f3..d6ad310d3b472c40c128cfb459171d9f48e50915 100644 +index 9afe509b3455a7aabd11976fb8a7430d1bce065d..4536632687e71b02d5945cac3816b72ac540935e 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -272,7 +272,12 @@ public abstract class BlockEntity { +@@ -273,7 +273,12 @@ public abstract class BlockEntity { public void fillCrashReportCategory(CrashReportCategory crashReportSection) { crashReportSection.setDetail("Name", this::getNameForReporting); if (this.level != null) { @@ -44,10 +44,10 @@ index 17cda4c8b61efd99c1a43f921ed604827bb064f3..d6ad310d3b472c40c128cfb459171d9f } } 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 418ba374886d93f69afd614e4be05f6561e1f897..6889991885cc2075e0936b2c480befeef30d308c 100644 +index 717e4bf9f5ee0ec2c3a0b5cc65a50b0f6d649a8d..e1cd7497b1355030bf44b53aa30400604dff9aca 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -953,11 +953,11 @@ public class LevelChunk extends ChunkAccess { +@@ -986,11 +986,11 @@ public class LevelChunk extends ChunkAccess { gameprofilerfiller.pop(); } catch (Throwable throwable) { diff --git a/patches/unapplied/server/0038-Configurable-top-of-nether-void-damage.patch b/patches/server/0038-Configurable-top-of-nether-void-damage.patch similarity index 83% rename from patches/unapplied/server/0038-Configurable-top-of-nether-void-damage.patch rename to patches/server/0038-Configurable-top-of-nether-void-damage.patch index 8a30b0f3c310..5f97b3e150aa 100644 --- a/patches/unapplied/server/0038-Configurable-top-of-nether-void-damage.patch +++ b/patches/server/0038-Configurable-top-of-nether-void-damage.patch @@ -6,16 +6,16 @@ Subject: [PATCH] Configurable top of nether void damage Co-authored-by: Jake Potrebic diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index dbe5239b1a1769ef9f2ef66c32b1a68cd684428e..d5f5864b7c1ad4c30f37b360b317b63c129e3a3f 100644 +index e97853cbfa6da8ecdb4c92cf634831492e1fc7e3..49df5f4b09926556986e3a45d52ff299b878af76 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -706,7 +706,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -720,7 +720,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public void checkBelowWorld() { -- if (this.getY() < (double) (this.level().getMinBuildHeight() - 64)) { +- if (this.getY() < (double) (this.level().getMinY() - 64)) { + // Paper start - Configurable nether ceiling damage -+ if (this.getY() < (double) (this.level.getMinBuildHeight() - 64) || (this.level.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER ++ if (this.getY() < (double) (this.level.getMinY() - 64) || (this.level.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER + && this.level.paperConfig().environment.netherCeilingVoidDamageHeight.test(v -> this.getY() >= v) + && (!(this instanceof Player player) || !player.getAbilities().invulnerable))) { + // Paper end - Configurable nether ceiling damage @@ -23,7 +23,7 @@ index dbe5239b1a1769ef9f2ef66c32b1a68cd684428e..d5f5864b7c1ad4c30f37b360b317b63c } diff --git a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java -index 46448259cd60ea5e2e08fb58cd2b2b7f8a4ec3cc..aef1dd28da7e0c0a13a0a7a5b52daa27635c48ea 100644 +index 36accb58ed269a129f92d2b64f5a0b14416de735..355f1ce10f9564c7c0be505a5af849e0428fec17 100644 --- a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java +++ b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java @@ -58,7 +58,7 @@ public class PortalForcer { @@ -38,7 +38,7 @@ index 46448259cd60ea5e2e08fb58cd2b2b7f8a4ec3cc..aef1dd28da7e0c0a13a0a7a5b52daa27 @@ -79,6 +79,11 @@ public class PortalForcer { BlockPos blockposition2 = null; WorldBorder worldborder = this.level.getWorldBorder(); - int i = Math.min(this.level.getMaxBuildHeight(), this.level.getMinBuildHeight() + this.level.getLogicalHeight()) - 1; + int i = Math.min(this.level.getMaxY(), this.level.getMinY() + this.level.getLogicalHeight() - 1); + // Paper start - Configurable nether ceiling damage; make sure the max height doesn't exceed the void damage height + if (this.level.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.NETHER && this.level.paperConfig().environment.netherCeilingVoidDamageHeight.enabled()) { + i = Math.min(i, this.level.paperConfig().environment.netherCeilingVoidDamageHeight.intValue() - 1); diff --git a/patches/unapplied/server/0039-Check-online-mode-before-converting-and-renaming-pla.patch b/patches/server/0039-Check-online-mode-before-converting-and-renaming-pla.patch similarity index 100% rename from patches/unapplied/server/0039-Check-online-mode-before-converting-and-renaming-pla.patch rename to patches/server/0039-Check-online-mode-before-converting-and-renaming-pla.patch diff --git a/patches/unapplied/server/0040-Add-more-entities-to-activation-range-ignore-list.patch b/patches/server/0040-Add-more-entities-to-activation-range-ignore-list.patch similarity index 92% rename from patches/unapplied/server/0040-Add-more-entities-to-activation-range-ignore-list.patch rename to patches/server/0040-Add-more-entities-to-activation-range-ignore-list.patch index c402bdafa28a..9eaf33d852ef 100644 --- a/patches/unapplied/server/0040-Add-more-entities-to-activation-range-ignore-list.patch +++ b/patches/server/0040-Add-more-entities-to-activation-range-ignore-list.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add more entities to activation range ignore list diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index a5da6c1cae0afbde684be250e2fc3c0c32a1265b..6d51464f6368151e8acc532414ee223714584e96 100644 +index 2122e044d99902d2aff86693aaa424a50b9f8a13..5dac9bdb23de3d143cd678e583eaf6e8095bb209 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -92,6 +92,9 @@ public class ActivationRange diff --git a/patches/unapplied/server/0041-Configurable-end-credits.patch b/patches/server/0041-Configurable-end-credits.patch similarity index 85% rename from patches/unapplied/server/0041-Configurable-end-credits.patch rename to patches/server/0041-Configurable-end-credits.patch index 65f5ee3bd5b5..3514b6e2efe4 100644 --- a/patches/unapplied/server/0041-Configurable-end-credits.patch +++ b/patches/server/0041-Configurable-end-credits.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Configurable end credits diff --git a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java -index e2d6693da4abe6204c0ecb5e924a3903fa80ab7d..a9c7a74b38a57c118c1ad67a77ba6f2e5c05d91e 100644 +index 8bea909328bc15eb6af739850db13d624270dee4..5744944455b08d45a7c0fe2289414b50b6c0d66a 100644 --- a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java +++ b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java -@@ -71,6 +71,7 @@ public class EndPortalBlock extends BaseEntityBlock implements Portal { +@@ -76,6 +76,7 @@ public class EndPortalBlock extends BaseEntityBlock implements Portal { if (!world.isClientSide && world.dimension() == Level.END && entity instanceof ServerPlayer) { ServerPlayer entityplayer = (ServerPlayer) entity; diff --git a/patches/server/0042-Fix-lag-from-explosions-processing-dead-entities.patch b/patches/server/0042-Fix-lag-from-explosions-processing-dead-entities.patch new file mode 100644 index 000000000000..9dc78a5f91dd --- /dev/null +++ b/patches/server/0042-Fix-lag-from-explosions-processing-dead-entities.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Iceee +Date: Wed, 2 Mar 2016 01:39:52 -0600 +Subject: [PATCH] Fix lag from explosions processing dead entities + + +diff --git a/src/main/java/net/minecraft/world/level/ServerExplosion.java b/src/main/java/net/minecraft/world/level/ServerExplosion.java +index 1df33018470136344d8843e5e429aa7f9b40b750..0eb25fabfff0e8a050c6dfb8cd24e703f679db76 100644 +--- a/src/main/java/net/minecraft/world/level/ServerExplosion.java ++++ b/src/main/java/net/minecraft/world/level/ServerExplosion.java +@@ -185,7 +185,7 @@ public class ServerExplosion implements Explosion { + int l = Mth.floor(this.center.y + (double) f + 1.0D); + int i1 = Mth.floor(this.center.z - (double) f - 1.0D); + int j1 = Mth.floor(this.center.z + (double) f + 1.0D); +- List list = this.level.getEntities(this.source, new AABB((double) i, (double) k, (double) i1, (double) j, (double) l, (double) j1)); ++ List list = this.level.getEntities(this.source, new AABB((double) i, (double) k, (double) i1, (double) j, (double) l, (double) j1), (com.google.common.base.Predicate) entity -> entity.isAlive() && !entity.isSpectator()); // Paper - Fix lag from explosions processing dead entities + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { diff --git a/patches/unapplied/server/0043-Optimize-explosions.patch b/patches/server/0043-Optimize-explosions.patch similarity index 69% rename from patches/unapplied/server/0043-Optimize-explosions.patch rename to patches/server/0043-Optimize-explosions.patch index 7aea454fd3c1..3117449ae65b 100644 --- a/patches/unapplied/server/0043-Optimize-explosions.patch +++ b/patches/server/0043-Optimize-explosions.patch @@ -10,34 +10,47 @@ 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 2f57739431eb695149019724e2923f0d02e88d07..1ba2b1aaf0936963aca73a43632f978c95bf95e6 100644 +index f9ff8b922c47a8a59b9be55a9f3498e2ba68ac44..254e34f80ed0d06f200a78c60f34b4ffc5e5ed85 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1571,6 +1571,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions -- double d12 = (1.0D - d7) * (double) Explosion.getSeenPercent(vec3d, entity) * (double) this.damageCalculator.getKnockbackMultiplier(entity); -+ double d12 = (1.0D - d7) * this.getBlockDensity(vec3d, entity) * (double) this.damageCalculator.getKnockbackMultiplier(entity); // Paper - Optimize explosions - double d13; + public CraftWorld getWorld() { + return this.world; +diff --git a/src/main/java/net/minecraft/world/level/ServerExplosion.java b/src/main/java/net/minecraft/world/level/ServerExplosion.java +index 0eb25fabfff0e8a050c6dfb8cd24e703f679db76..f4b5c81d0daae24e06ba6409fc4584b4f1406fd2 100644 +--- a/src/main/java/net/minecraft/world/level/ServerExplosion.java ++++ b/src/main/java/net/minecraft/world/level/ServerExplosion.java +@@ -206,7 +206,7 @@ public class ServerExplosion implements Explosion { + d3 /= d4; + boolean flag = this.damageCalculator.shouldDamageEntity(this, entity); + float f1 = this.damageCalculator.getKnockbackMultiplier(entity); +- float f2 = !flag && f1 == 0.0F ? 0.0F : ServerExplosion.getSeenPercent(this.center, entity); ++ float f2 = !flag && f1 == 0.0F ? 0.0F : this.getBlockDensity(this.center, entity); // Paper - Optimize explosions - if (entity instanceof LivingEntity) { -@@ -536,4 +536,84 @@ public class Explosion { + if (flag) { + // CraftBukkit start +@@ -483,4 +483,85 @@ public class ServerExplosion implements Explosion { - private BlockInteraction() {} + } } ++ + // Paper start - Optimize explosions + private float getBlockDensity(Vec3 vec3d, Entity entity) { + if (!this.level.paperConfig().environment.optimizeExplosions) { @@ -60,10 +73,10 @@ index 35d541c549cb07508e68388b18f38a4ffd788176..23a0a8d9beb7ca400134fb6a65b3133b + private final double maxX, maxY, maxZ; + + public CacheKey(Explosion explosion, AABB aabb) { -+ this.world = explosion.level; -+ this.posX = explosion.x; -+ this.posY = explosion.y; -+ this.posZ = explosion.z; ++ this.world = explosion.level(); ++ this.posX = explosion.center().x; ++ this.posY = explosion.center().y; ++ this.posZ = explosion.center().z; + this.minX = aabb.minX; + this.minY = aabb.minY; + this.minZ = aabb.minZ; @@ -119,15 +132,3 @@ index 35d541c549cb07508e68388b18f38a4ffd788176..23a0a8d9beb7ca400134fb6a65b3133b + } + // Paper end } -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index e8b8475dd6fd7b89651f744da2cb9696c73ddc3e..a272aaff11ac077853c06f729a5d8b09f866e0f8 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -168,6 +168,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - private org.spigotmc.TickLimiter entityLimiter; - private org.spigotmc.TickLimiter tileLimiter; - private int tileTickPosition; -+ public final Map explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions - - public CraftWorld getWorld() { - return this.world; diff --git a/patches/unapplied/server/0044-Disable-explosion-knockback.patch b/patches/server/0044-Disable-explosion-knockback.patch similarity index 52% rename from patches/unapplied/server/0044-Disable-explosion-knockback.patch rename to patches/server/0044-Disable-explosion-knockback.patch index 233aa3058123..21d2161c676e 100644 --- a/patches/unapplied/server/0044-Disable-explosion-knockback.patch +++ b/patches/server/0044-Disable-explosion-knockback.patch @@ -4,25 +4,25 @@ Date: Wed, 2 Mar 2016 14:48:03 -0600 Subject: [PATCH] Disable explosion knockback -diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index 55d66aa8264d5b444a23e2132206bcc9835cfe00..d93ed33d5ae72e9dd3e6cf044ef79e4b9689dc1c 100644 ---- a/src/main/java/net/minecraft/world/level/Explosion.java -+++ b/src/main/java/net/minecraft/world/level/Explosion.java -@@ -285,7 +285,7 @@ public class Explosion { +diff --git a/src/main/java/net/minecraft/world/level/ServerExplosion.java b/src/main/java/net/minecraft/world/level/ServerExplosion.java +index f4b5c81d0daae24e06ba6409fc4584b4f1406fd2..3afacd201683f46fd75cd6f9a7f3d43a7050cf4a 100644 +--- a/src/main/java/net/minecraft/world/level/ServerExplosion.java ++++ b/src/main/java/net/minecraft/world/level/ServerExplosion.java +@@ -246,7 +246,7 @@ public class ServerExplosion implements Explosion { if (entity instanceof LivingEntity) { LivingEntity entityliving = (LivingEntity) entity; -- d13 = d12 * (1.0D - entityliving.getAttributeValue(Attributes.EXPLOSION_KNOCKBACK_RESISTANCE)); -+ d13 = entity instanceof Player && this.level.paperConfig().environment.disableExplosionKnockback ? 0 : d12 * (1.0D - entityliving.getAttributeValue(Attributes.EXPLOSION_KNOCKBACK_RESISTANCE)); +- d6 = d5 * (1.0D - entityliving.getAttributeValue(Attributes.EXPLOSION_KNOCKBACK_RESISTANCE)); ++ d6 = entity instanceof Player && this.level.paperConfig().environment.disableExplosionKnockback ? 0 : d5 * (1.0D - entityliving.getAttributeValue(Attributes.EXPLOSION_KNOCKBACK_RESISTANCE)); // Paper } else { - d13 = d12; + d6 = d5; } -@@ -310,7 +310,7 @@ public class Explosion { +@@ -271,7 +271,7 @@ public class ServerExplosion implements Explosion { if (entity instanceof Player) { Player entityhuman = (Player) entity; - if (!entityhuman.isSpectator() && (!entityhuman.isCreative() || !entityhuman.getAbilities().flying)) { + if (!entityhuman.isSpectator() && (!entityhuman.isCreative() || !entityhuman.getAbilities().flying) && !level.paperConfig().environment.disableExplosionKnockback) { // Paper - Option to disable explosion knockback - this.hitPlayers.put(entityhuman, vec3d1); + this.hitPlayers.put(entityhuman, vec3d); } } diff --git a/patches/unapplied/server/0045-Disable-thunder.patch b/patches/server/0045-Disable-thunder.patch similarity index 80% rename from patches/unapplied/server/0045-Disable-thunder.patch rename to patches/server/0045-Disable-thunder.patch index de8845153827..ab1379c28eba 100644 --- a/patches/unapplied/server/0045-Disable-thunder.patch +++ b/patches/server/0045-Disable-thunder.patch @@ -5,11 +5,11 @@ 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 754045e71f180862fa57fd1c97e5d7deb1d788e6..aca595551c90d5515309c9c82ad6ffcfa1d680c8 100644 +index a31371dd479f5d87ff62728504563815bb5e22f8..f1145c190b8cb50a800d9324b25aa884b7de9606 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -616,7 +616,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - ProfilerFiller gameprofilerfiller = this.getProfiler(); +@@ -603,7 +603,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + ProfilerFiller gameprofilerfiller = Profiler.get(); gameprofilerfiller.push("thunder"); - if (flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot diff --git a/patches/unapplied/server/0046-Disable-ice-and-snow.patch b/patches/server/0046-Disable-ice-and-snow.patch similarity index 83% rename from patches/unapplied/server/0046-Disable-ice-and-snow.patch rename to patches/server/0046-Disable-ice-and-snow.patch index ae60e5cb8ca4..7f43a10174d5 100644 --- a/patches/unapplied/server/0046-Disable-ice-and-snow.patch +++ b/patches/server/0046-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 aca595551c90d5515309c9c82ad6ffcfa1d680c8..6d89dc22e28a9c3557d9972be0935d75719e7f7d 100644 +index f1145c190b8cb50a800d9324b25aa884b7de9606..77d61f16b5b45fbe78deaf90f4ae4b126546c3e9 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -646,11 +646,13 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -633,11 +633,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe gameprofilerfiller.popPush("iceandsnow"); diff --git a/patches/unapplied/server/0047-Configurable-mob-spawner-tick-rate.patch b/patches/server/0047-Configurable-mob-spawner-tick-rate.patch similarity index 94% rename from patches/unapplied/server/0047-Configurable-mob-spawner-tick-rate.patch rename to patches/server/0047-Configurable-mob-spawner-tick-rate.patch index deb1ddde3f00..a3dc9ff7d3c4 100644 --- a/patches/unapplied/server/0047-Configurable-mob-spawner-tick-rate.patch +++ b/patches/server/0047-Configurable-mob-spawner-tick-rate.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Configurable mob spawner tick rate diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index 418e29971326008ebca0cc4b696a41a49c1c7bb7..aa54237205989f619ac6a3faa2e4285427b9e31d 100644 +index 366661561544f8e99f238583259991e9fcbab8af..7b918001d36a8f14ed0d3ee4d6783588f48eb78f 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java @@ -49,6 +49,7 @@ public abstract class BaseSpawner { diff --git a/patches/unapplied/server/0048-Use-null-Locale-by-default.patch b/patches/server/0048-Use-null-Locale-by-default.patch similarity index 83% rename from patches/unapplied/server/0048-Use-null-Locale-by-default.patch rename to patches/server/0048-Use-null-Locale-by-default.patch index 3fcadee5b58b..8d9a04746040 100644 --- a/patches/unapplied/server/0048-Use-null-Locale-by-default.patch +++ b/patches/server/0048-Use-null-Locale-by-default.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Use null Locale by default diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index ee5188f3aa2ff71306f5af8046e8ddf919c8601b..13a069483db22f25008bf4081d4aa2b36a75bc68 100644 +index 4303bde198050cd037f006234d269af406606eff..911ec630c5925b160cc05f99f0d5bb5ac46384bb 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -237,7 +237,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -261,7 +261,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { private int levitationStartTime; private boolean disconnected; private int requestedViewDistance; @@ -17,16 +17,16 @@ index ee5188f3aa2ff71306f5af8046e8ddf919c8601b..13a069483db22f25008bf4081d4aa2b3 public java.util.Locale adventure$locale = java.util.Locale.US; // Paper @Nullable private Vec3 startingToFallPosition; -@@ -293,7 +293,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -321,7 +321,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { + this.canChatColor = true; this.lastActionTime = Util.getMillis(); - this.recipeBook = new ServerRecipeBook(); this.requestedViewDistance = 2; - this.language = "en_us"; + this.language = null; // Paper - default to null this.lastSectionPos = SectionPos.of(0, 0, 0); this.chunkTrackingView = ChunkTrackingView.EMPTY; this.respawnDimension = Level.OVERWORLD; -@@ -2051,7 +2051,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2314,7 +2314,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(this.getBukkitEntity(), this.getMainArm() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT); this.server.server.getPluginManager().callEvent(event); } @@ -36,10 +36,10 @@ index ee5188f3aa2ff71306f5af8046e8ddf919c8601b..13a069483db22f25008bf4081d4aa2b3 this.server.server.getPluginManager().callEvent(event); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 1a003335a4f3cc2fdeadca9c0c6cdafa61a6a1ac..fb5548b92a0fe7866cf98e25293c4b0702344c9b 100644 +index 2a6db82c926bb5551035f4b040502215d35355fb..955dda9db5f2142a7cb9634a298a4b30d18dbf3c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2423,7 +2423,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2436,7 +2436,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public String getLocale() { diff --git a/patches/unapplied/server/0049-Add-BeaconEffectEvent.patch b/patches/server/0049-Add-BeaconEffectEvent.patch similarity index 97% rename from patches/unapplied/server/0049-Add-BeaconEffectEvent.patch rename to patches/server/0049-Add-BeaconEffectEvent.patch index f26dbf1ae4bc..ce80109f252b 100644 --- a/patches/unapplied/server/0049-Add-BeaconEffectEvent.patch +++ b/patches/server/0049-Add-BeaconEffectEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add BeaconEffectEvent diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -index 9fc5f72ac2d23a03584d3c0357bc1a55ea40bab3..fc915797d2a085447747d9ce23a5a354fb3eb6b6 100644 +index 94fcd67edd81120d56478ffd30f3c1d7dee955e6..8332296663b845df1d09d403b49a4769b2d54afc 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java @@ -1,5 +1,6 @@ diff --git a/patches/unapplied/server/0050-Configurable-container-update-tick-rate.patch b/patches/server/0050-Configurable-container-update-tick-rate.patch similarity index 83% rename from patches/unapplied/server/0050-Configurable-container-update-tick-rate.patch rename to patches/server/0050-Configurable-container-update-tick-rate.patch index 290d38244cd2..02f5fc8fd0e4 100644 --- a/patches/unapplied/server/0050-Configurable-container-update-tick-rate.patch +++ b/patches/server/0050-Configurable-container-update-tick-rate.patch @@ -5,18 +5,18 @@ 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 e61460a06708429738e0ed5f903a4226158aa334..ed920ed90569b7b8886a09a1c3772fd7147d44f9 100644 +index 911ec630c5925b160cc05f99f0d5bb5ac46384bb..78e4f07019e3231fbaa3f23bcdc8846e2d79ae18 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -268,6 +268,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { - public final Object object; +@@ -295,6 +295,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { + private final CommandSource commandSource; private int containerCounter; public boolean wonGame; + private int containerUpdateDelay; // Paper - Configurable container update tick rate // CraftBukkit start public CraftPlayer.TransferCookieConnection transferCookieConnection; -@@ -696,7 +697,12 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -924,7 +925,12 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { --this.invulnerableTime; } diff --git a/patches/unapplied/server/0051-Use-UserCache-for-player-heads.patch b/patches/server/0051-Use-UserCache-for-player-heads.patch similarity index 100% rename from patches/unapplied/server/0051-Use-UserCache-for-player-heads.patch rename to patches/server/0051-Use-UserCache-for-player-heads.patch diff --git a/patches/unapplied/server/0052-Disable-spigot-tick-limiters.patch b/patches/server/0052-Disable-spigot-tick-limiters.patch similarity index 88% rename from patches/unapplied/server/0052-Disable-spigot-tick-limiters.patch rename to patches/server/0052-Disable-spigot-tick-limiters.patch index 2e19fda1e14f..a588d23369b9 100644 --- a/patches/unapplied/server/0052-Disable-spigot-tick-limiters.patch +++ b/patches/server/0052-Disable-spigot-tick-limiters.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Disable spigot tick limiters diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index da7b1b705da9f17de858f72a20d3a932cd8f7fad..68436413645e0e33f22cdee0ea101ca01b343d75 100644 +index a0b89abe50f4cea64f29e8957c535400658d4524..5fe8726af73eb5334f47046c93096341e987269b 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -704,9 +704,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -706,9 +706,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { boolean flag = this.tickRateManager().runsNormally(); int tilesThisCycle = 0; diff --git a/patches/unapplied/server/0053-Fix-spawn-location-event-changing-location.patch b/patches/server/0053-Fix-spawn-location-event-changing-location.patch similarity index 87% rename from patches/unapplied/server/0053-Fix-spawn-location-event-changing-location.patch rename to patches/server/0053-Fix-spawn-location-event-changing-location.patch index e9256b27836b..07448453cfe5 100644 --- a/patches/unapplied/server/0053-Fix-spawn-location-event-changing-location.patch +++ b/patches/server/0053-Fix-spawn-location-event-changing-location.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Fix spawn location event changing location public net.minecraft.world.entity.Entity setRot(FF)V diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 765c412cd0c5cd410c224b4bc55dbf431fd6617b..8a91a44e46a2d49e2f4b9e9970c2b77f2e87767e 100644 +index b103d49458330be9f7fb3382c764b204a02a925a..2af4b853fde493c1fa5c8d530aae4d68b79f7ba0 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -234,7 +234,10 @@ public abstract class PlayerList { +@@ -235,7 +235,10 @@ public abstract class PlayerList { player.spawnIn(worldserver1); player.gameMode.setLevel((ServerLevel) player.level()); diff --git a/patches/unapplied/server/0054-Configurable-Disabling-Cat-Chest-Detection.patch b/patches/server/0054-Configurable-Disabling-Cat-Chest-Detection.patch similarity index 88% rename from patches/unapplied/server/0054-Configurable-Disabling-Cat-Chest-Detection.patch rename to patches/server/0054-Configurable-Disabling-Cat-Chest-Detection.patch index 232eb8f5f4fe..410ee5115f41 100644 --- a/patches/unapplied/server/0054-Configurable-Disabling-Cat-Chest-Detection.patch +++ b/patches/server/0054-Configurable-Disabling-Cat-Chest-Detection.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Configurable Disabling Cat Chest Detection Offers a gameplay feature to stop cats from blocking chests diff --git a/src/main/java/net/minecraft/world/level/block/ChestBlock.java b/src/main/java/net/minecraft/world/level/block/ChestBlock.java -index e197891f61580f92787d9400ff486439a92a54c7..8fbfd18b3caeed769396b3ffb1b1778b2f38edc0 100644 +index 62440d5985341d6c1b9ec5f6cce81a5ad6bd9040..590837cb242eda62dca3c937a26b8ba26c41850c 100644 --- a/src/main/java/net/minecraft/world/level/block/ChestBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ChestBlock.java -@@ -349,6 +349,11 @@ public class ChestBlock extends AbstractChestBlock implements +@@ -348,6 +348,11 @@ public class ChestBlock extends AbstractChestBlock implements } private static boolean isCatSittingOnChest(LevelAccessor world, BlockPos pos) { diff --git a/patches/unapplied/server/0055-Improve-Player-chat-API-handling.patch b/patches/server/0055-Improve-Player-chat-API-handling.patch similarity index 88% rename from patches/unapplied/server/0055-Improve-Player-chat-API-handling.patch rename to patches/server/0055-Improve-Player-chat-API-handling.patch index 05814e9ee54a..248a889b8cb9 100644 --- a/patches/unapplied/server/0055-Improve-Player-chat-API-handling.patch +++ b/patches/server/0055-Improve-Player-chat-API-handling.patch @@ -17,10 +17,10 @@ Co-authored-by: Jake Potrebic Co-authored-by: SoSeDiK diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 3a67b2b6a6d3204b2a7bbe8adbf2b0ecf7898551..02b9e1ed57f5d65698c461387ff7d48450e6a70f 100644 +index 7a130da1b50a67331a862f96934739845c7b2d67..6b3023fbbac8ba7d0d0e2968c406b908d81ef7dc 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2013,7 +2013,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2024,7 +2024,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } OutgoingChatMessage outgoing = OutgoingChatMessage.create(original); @@ -29,7 +29,7 @@ index 3a67b2b6a6d3204b2a7bbe8adbf2b0ecf7898551..02b9e1ed57f5d65698c461387ff7d484 this.handleCommand(s); } else if (this.player.getChatVisibility() == ChatVisiblity.SYSTEM) { // Do nothing, this is coming from a plugin -@@ -2100,7 +2100,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2111,7 +2111,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } @@ -40,10 +40,10 @@ index 3a67b2b6a6d3204b2a7bbe8adbf2b0ecf7898551..02b9e1ed57f5d65698c461387ff7d484 if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 8f79d7611c3ee1c817d5671152e459ec4f413418..441a8d3355e0db773a5da330bf9361234da1ca89 100644 +index 9683759c36de3b9d791e56dc1fb993087c1bc37c..3b58cc979c4e2fb5382f0c67ccfaa8440e9c785b 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -934,7 +934,7 @@ public final class CraftServer implements Server { +@@ -937,7 +937,7 @@ public final class CraftServer implements Server { public boolean dispatchCommand(CommandSender sender, String commandLine) { Preconditions.checkArgument(sender != null, "sender cannot be null"); Preconditions.checkArgument(commandLine != null, "commandLine cannot be null"); @@ -53,10 +53,10 @@ index 8f79d7611c3ee1c817d5671152e459ec4f413418..441a8d3355e0db773a5da330bf936123 if (this.commandMap.dispatch(sender, commandLine)) { return true; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 545da59af2436b9a4363ec459456c8f15650b79f..9751cace64d9ad2b8b55080b13834e8ccb056b42 100644 +index 955dda9db5f2142a7cb9634a298a4b30d18dbf3c..631ebc76f14482b38374fb2a9cdfe12ea15176e2 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -546,7 +546,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -559,7 +559,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player { if (this.getHandle().connection == null) return; diff --git a/patches/unapplied/server/0056-All-chunks-are-slime-spawn-chunks-toggle.patch b/patches/server/0056-All-chunks-are-slime-spawn-chunks-toggle.patch similarity index 69% rename from patches/unapplied/server/0056-All-chunks-are-slime-spawn-chunks-toggle.patch rename to patches/server/0056-All-chunks-are-slime-spawn-chunks-toggle.patch index 3cded231dd0e..7afface4f663 100644 --- a/patches/unapplied/server/0056-All-chunks-are-slime-spawn-chunks-toggle.patch +++ b/patches/server/0056-All-chunks-are-slime-spawn-chunks-toggle.patch @@ -5,20 +5,20 @@ Subject: [PATCH] All chunks are slime spawn chunks toggle diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java -index b7e6f6e195d8b947c06e2bf58f4c644bda8eba99..b1f7ea02e533660322675e1bddb070f0a41084f2 100644 +index 7b45d1b706550d7d0a0267f30fb0b86813edfeb3..131fce812eb0dcdebab02b529ed18e81eb1861eb 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Slime.java +++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java -@@ -350,7 +350,7 @@ public class Slime extends Mob implements Enemy { - } +@@ -342,7 +342,7 @@ public class Slime extends Mob implements Enemy { + } - ChunkPos chunkcoordintpair = new ChunkPos(pos); -- boolean flag = WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot + ChunkPos chunkcoordintpair = new ChunkPos(pos); +- boolean flag = WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot + boolean flag = world.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper - if (random.nextInt(10) == 0 && flag && pos.getY() < 40) { - return checkMobSpawnRules(type, world, spawnReason, pos, random); + if (random.nextInt(10) == 0 && flag && pos.getY() < 40) { + return checkMobSpawnRules(type, world, spawnReason, pos, random); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java -index 5db1be69f0c4ef6976789587866c7a9bb6d19b0d..e37dae711e7059834612ead5f4fcea9f28ad436f 100644 +index 19f165b855a0ca10732fd43c7ee093b11e535471..91d2b6eaa2af0abb1bdf11849f0fd59660f765dd 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -218,7 +218,7 @@ public class CraftChunk implements Chunk { diff --git a/patches/unapplied/server/0057-Expose-server-CommandMap.patch b/patches/server/0057-Expose-server-CommandMap.patch similarity index 78% rename from patches/unapplied/server/0057-Expose-server-CommandMap.patch rename to patches/server/0057-Expose-server-CommandMap.patch index 3b09e092796b..b491a4208321 100644 --- a/patches/unapplied/server/0057-Expose-server-CommandMap.patch +++ b/patches/server/0057-Expose-server-CommandMap.patch @@ -5,10 +5,10 @@ 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 441a8d3355e0db773a5da330bf9361234da1ca89..32d1e4bc8279a9adb83501c99fc7ff33d4c7f81c 100644 +index 3b58cc979c4e2fb5382f0c67ccfaa8440e9c785b..89778f8df5a4b639bb0fe5e7a0164ef55b96041a 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2179,6 +2179,7 @@ public final class CraftServer implements Server { +@@ -2183,6 +2183,7 @@ public final class CraftServer implements Server { return this.helpMap; } diff --git a/patches/unapplied/server/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch b/patches/server/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch similarity index 89% rename from patches/unapplied/server/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch rename to patches/server/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch index 4490b5096c73..dc513f3e9610 100644 --- a/patches/unapplied/server/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch +++ b/patches/server/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Be a bit more informative in maxHealth exception diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 5ce03fa25e0a03025501a7f86a8f3c64f3fd7c77..ff2118fb463168e061ca9152183e19d593b476e9 100644 +index 8146e3df0fbcdb5f7e474167814bfbd569984fa0..ea7cbb5b5e7f140c06029ef05a01567d51b39f91 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -103,7 +103,12 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -108,7 +108,12 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { @Override public void setHealth(double health) { health = (float) health; diff --git a/patches/unapplied/server/0059-Player-Tab-List-and-Title-APIs.patch b/patches/server/0059-Player-Tab-List-and-Title-APIs.patch similarity index 96% rename from patches/unapplied/server/0059-Player-Tab-List-and-Title-APIs.patch rename to patches/server/0059-Player-Tab-List-and-Title-APIs.patch index 93c3f67151c8..633d3c5d5cc3 100644 --- a/patches/unapplied/server/0059-Player-Tab-List-and-Title-APIs.patch +++ b/patches/server/0059-Player-Tab-List-and-Title-APIs.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Player Tab List and Title APIs diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 9751cace64d9ad2b8b55080b13834e8ccb056b42..951b89ced33b2a12dff90e32201643bee64962e1 100644 +index 631ebc76f14482b38374fb2a9cdfe12ea15176e2..49befbbd27fb44d564663c140dd594e0f35526f3 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -388,6 +388,98 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -389,6 +389,98 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } } diff --git a/patches/unapplied/server/0060-Add-configurable-portal-search-radius.patch b/patches/server/0060-Add-configurable-portal-search-radius.patch similarity index 91% rename from patches/unapplied/server/0060-Add-configurable-portal-search-radius.patch rename to patches/server/0060-Add-configurable-portal-search-radius.patch index 9ba19afb3eed..9307176401b7 100644 --- a/patches/unapplied/server/0060-Add-configurable-portal-search-radius.patch +++ b/patches/server/0060-Add-configurable-portal-search-radius.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add configurable portal search radius diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java -index 462afb22cce2376789e44283032e63a6264cf851..8072e67f7b2f5944670159d3de1b01090bd1019d 100644 +index 5244f272947a4eb600f5ba183db2bb17824784ce..5d4c0d7fec42bf843b11875f7a09bcb9279b3b54 100644 --- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java -@@ -139,8 +139,14 @@ public class NetherPortalBlock extends Block implements Portal { +@@ -145,8 +145,14 @@ public class NetherPortalBlock extends Block implements Portal { WorldBorder worldborder = worldserver1.getWorldBorder(); double d0 = DimensionType.getTeleportationScale(world.dimensionType(), worldserver1.dimensionType()); BlockPos blockposition1 = worldborder.clampToBounds(entity.getX() * d0, entity.getY(), entity.getZ() * d0); @@ -25,7 +25,7 @@ index 462afb22cce2376789e44283032e63a6264cf851..8072e67f7b2f5944670159d3de1b0109 return null; } diff --git a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java -index aef1dd28da7e0c0a13a0a7a5b52daa27635c48ea..5c4b2a33d4007c36aef68604bca40a4eba510b4e 100644 +index 355f1ce10f9564c7c0be505a5af849e0428fec17..eb409fb5e673d2a343813946cc59cb5da2328eec 100644 --- a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java +++ b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java @@ -42,6 +42,7 @@ public class PortalForcer { diff --git a/patches/unapplied/server/0061-Add-velocity-warnings.patch b/patches/server/0061-Add-velocity-warnings.patch similarity index 93% rename from patches/unapplied/server/0061-Add-velocity-warnings.patch rename to patches/server/0061-Add-velocity-warnings.patch index 996e71c32283..a8358fe2a49e 100644 --- a/patches/unapplied/server/0061-Add-velocity-warnings.patch +++ b/patches/server/0061-Add-velocity-warnings.patch @@ -5,10 +5,10 @@ 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 4bfb836513d5194be271f4a82990ace98de69640..fd31d0e76d1a953b128e777b1bc27e24b1e03ed7 100644 +index 89778f8df5a4b639bb0fe5e7a0164ef55b96041a..c80fe475edffce53363dfea658b9f13a2c6de1ca 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -302,6 +302,7 @@ public final class CraftServer implements Server { +@@ -305,6 +305,7 @@ public final class CraftServer implements Server { private final List playerView; public int reloadCount; public Set activeCompatibilities = Collections.emptySet(); @@ -17,10 +17,10 @@ index 4bfb836513d5194be271f4a82990ace98de69640..fd31d0e76d1a953b128e777b1bc27e24 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 7b45a1216ff824f1b528bb5759d10b70858832a1..df6da730134da754d0ff23bd1b57c82486b9ab73 100644 +index ea27931d01c1f3c721b2f7ec12d41ea843fa158a..0bec53dc1be4aa997be9f03bc3cde30d22cc8160 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -131,10 +131,40 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -132,10 +132,40 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { public void setVelocity(Vector velocity) { Preconditions.checkArgument(velocity != null, "velocity"); velocity.checkFinite(); diff --git a/patches/unapplied/server/0062-Add-exception-reporting-event.patch b/patches/server/0062-Add-exception-reporting-event.patch similarity index 92% rename from patches/unapplied/server/0062-Add-exception-reporting-event.patch rename to patches/server/0062-Add-exception-reporting-event.patch index 36051c183577..17d813039c60 100644 --- a/patches/unapplied/server/0062-Add-exception-reporting-event.patch +++ b/patches/server/0062-Add-exception-reporting-event.patch @@ -79,11 +79,11 @@ index 68551947f5b7d3471f15bd74ccd86519ab34c1c1..a0b0614ac7d2009db5c6c10ab4a5f09d } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/ai/village/VillageSiege.java b/src/main/java/net/minecraft/world/entity/ai/village/VillageSiege.java -index 8183c26b4a5ad169a53702b8c45fd05cda934e80..36dec6cd78a0990ba3c09a4a748c259ef5c0a2ff 100644 +index a5b18a04f482d05d3ca74918a580499b21c2fc3c..bd3f71c3eaa33258ff56062ea3a2099cef310b7a 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/VillageSiege.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/VillageSiege.java @@ -117,6 +117,7 @@ public class VillageSiege implements CustomSpawner { - entityzombie.finalizeSpawn(world, world.getCurrentDifficultyAt(entityzombie.blockPosition()), MobSpawnType.EVENT, (SpawnGroupData) null); + entityzombie.finalizeSpawn(world, world.getCurrentDifficultyAt(entityzombie.blockPosition()), EntitySpawnReason.EVENT, (SpawnGroupData) null); } catch (Exception exception) { VillageSiege.LOGGER.warn("Failed to create zombie for village siege at {}", vec3d, exception); + com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception); // Paper - ServerExceptionEvent @@ -91,10 +91,10 @@ index 8183c26b4a5ad169a53702b8c45fd05cda934e80..36dec6cd78a0990ba3c09a4a748c259e } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index b4293991dddc9039c26106ac8c047e5aeec35a56..32b42d25631aecdd31db4954a8bbf38bcda98d6b 100644 +index 5fe8726af73eb5334f47046c93096341e987269b..574d8d311001ce15c2a2391caaec0a0b0b1653b5 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -733,6 +733,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -735,6 +735,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Paper start - Prevent block entity and entity crashes 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); @@ -103,10 +103,10 @@ index b4293991dddc9039c26106ac8c047e5aeec35a56..32b42d25631aecdd31db4954a8bbf38b // Paper end - Prevent block entity and entity crashes } diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 6a80479554f0c860a8dd6baa1a6506858fca83e3..6324689f52363f19501143c1649f0885684cb796 100644 +index 1fe93e01c5e37397aded5d1f99214bf1bffe70b7..400166ad0199dd4b96684904ef4748cdb72381bb 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -274,6 +274,7 @@ public final class NaturalSpawner { +@@ -296,6 +296,7 @@ public final class NaturalSpawner { NaturalSpawner.LOGGER.warn("Can't spawn entity of type: {}", BuiltInRegistries.ENTITY_TYPE.getKey(type)); } catch (Exception exception) { NaturalSpawner.LOGGER.warn("Failed to create mob", exception); @@ -114,8 +114,8 @@ index 6a80479554f0c860a8dd6baa1a6506858fca83e3..6324689f52363f19501143c1649f0885 } return null; -@@ -362,6 +363,7 @@ public final class NaturalSpawner { - entity = biomesettingsmobs_c.type.create(world.getLevel()); +@@ -384,6 +385,7 @@ public final class NaturalSpawner { + entity = biomesettingsmobs_c.type.create(world.getLevel(), EntitySpawnReason.NATURAL); } catch (Exception exception) { NaturalSpawner.LOGGER.warn("Failed to create mob", exception); + com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception); // Paper - ServerExceptionEvent @@ -123,10 +123,10 @@ index 6a80479554f0c860a8dd6baa1a6506858fca83e3..6324689f52363f19501143c1649f0885 } 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 6889991885cc2075e0936b2c480befeef30d308c..4495c5051b0c7a04d433c39d91f74cb7924d3ff2 100644 +index e1cd7497b1355030bf44b53aa30400604dff9aca..401f18deb9e9f019ea17ad684f2d5c4ea5e7ef97 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -471,8 +471,13 @@ public class LevelChunk extends ChunkAccess { +@@ -496,8 +496,13 @@ public class LevelChunk extends ChunkAccess { BlockState iblockdata = this.getBlockState(blockposition); if (!iblockdata.hasBlockEntity()) { @@ -142,7 +142,7 @@ index 6889991885cc2075e0936b2c480befeef30d308c..4495c5051b0c7a04d433c39d91f74cb7 } else { BlockState iblockdata1 = blockEntity.getBlockState(); -@@ -956,6 +961,7 @@ public class LevelChunk extends ChunkAccess { +@@ -989,6 +994,7 @@ public class LevelChunk extends ChunkAccess { // Paper start - Prevent block 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); @@ -171,7 +171,7 @@ index 15f273aa592828719de6e092d79a407dc8652dfe..b24e8255ab18eb5b2e4968aa62aa3d72 try { filechannel.close(); diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -index 6c0debe3f3b693ed90dd2a39f481cccd8e4f7634..cf9f04e005940f5dd7baf50435f3703fa7c2d4f0 100644 +index 4c376f67ae311b4fedea27b3475f9fb56054aec2..22ddc74d85efb4e80e6f06acdf93341a122804fc 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java @@ -416,20 +416,25 @@ public class CraftScheduler implements BukkitScheduler { @@ -199,7 +199,7 @@ index 6c0debe3f3b693ed90dd2a39f481cccd8e4f7634..cf9f04e005940f5dd7baf50435f3703f } this.parsePending(); } else { - this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); + this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(this.currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); - this.executor.execute(task); + this.executor.execute(new com.destroystokyo.paper.ServerSchedulerReportingWrapper(task)); // Paper // We don't need to parse pending diff --git a/patches/unapplied/server/0063-Disable-Scoreboards-for-non-players-by-default.patch b/patches/server/0063-Disable-Scoreboards-for-non-players-by-default.patch similarity index 85% rename from patches/unapplied/server/0063-Disable-Scoreboards-for-non-players-by-default.patch rename to patches/server/0063-Disable-Scoreboards-for-non-players-by-default.patch index ba39658f013e..e5db1eccb030 100644 --- a/patches/unapplied/server/0063-Disable-Scoreboards-for-non-players-by-default.patch +++ b/patches/server/0063-Disable-Scoreboards-for-non-players-by-default.patch @@ -11,10 +11,10 @@ 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 d5f5864b7c1ad4c30f37b360b317b63c129e3a3f..82e57978b79b5275b98a1fa7731c6a23ee861a2f 100644 +index 49df5f4b09926556986e3a45d52ff299b878af76..8a61ca3cba2888e03e440519714705fe50b81267 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -2934,6 +2934,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3057,6 +3057,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Nullable public PlayerTeam getTeam() { @@ -23,10 +23,10 @@ index d5f5864b7c1ad4c30f37b360b317b63c129e3a3f..82e57978b79b5275b98a1fa7731c6a23 } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 97ad63aad3c559feb1e762af1e00fd550aa5b251..ba194f42217f1176ac08123d3bb5cb24e1a6c119 100644 +index 6cc86412d45186dff312d9b1246fd1d03dbc15d8..b3f7d20c7853afaa396a90fbe23ed33d03fda8eb 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -848,6 +848,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -873,6 +873,7 @@ public abstract class LivingEntity extends Entity implements Attackable { String s = nbt.getString("Team"); Scoreboard scoreboard = this.level().getScoreboard(); PlayerTeam scoreboardteam = scoreboard.getPlayerTeam(s); diff --git a/patches/unapplied/server/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch b/patches/server/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch similarity index 88% rename from patches/unapplied/server/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch rename to patches/server/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch index dc2456c4af06..6da97b4baac7 100644 --- a/patches/unapplied/server/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch +++ b/patches/server/0064-Add-methods-for-working-with-arrows-stuck-in-living-.patch @@ -7,10 +7,10 @@ Upstream added methods for this, original methods are now deprecated diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index ff2118fb463168e061ca9152183e19d593b476e9..5ba4105356e4a4808293e86c679d08a3c4cdd245 100644 +index ea7cbb5b5e7f140c06029ef05a01567d51b39f91..6bb32e4eab357c5f67a3daafa2de035b0d125635 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -284,10 +284,29 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -289,10 +289,29 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { } @Override @@ -40,8 +40,8 @@ index ff2118fb463168e061ca9152183e19d593b476e9..5ba4105356e4a4808293e86c679d08a3 + // Paper end - Add methods for working with arrows stuck in living entities @Override - public void damage(double amount) { -@@ -813,4 +832,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { + public boolean isInvulnerable() { +@@ -833,4 +852,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { this.getHandle().persistentInvisibility = invisible; this.getHandle().setSharedFlag(5, invisible); } diff --git a/patches/unapplied/server/0065-Chunk-Save-Reattempt.patch b/patches/server/0065-Chunk-Save-Reattempt.patch similarity index 100% rename from patches/unapplied/server/0065-Chunk-Save-Reattempt.patch rename to patches/server/0065-Chunk-Save-Reattempt.patch diff --git a/patches/unapplied/server/0066-Complete-resource-pack-API.patch b/patches/server/0066-Complete-resource-pack-API.patch similarity index 87% rename from patches/unapplied/server/0066-Complete-resource-pack-API.patch rename to patches/server/0066-Complete-resource-pack-API.patch index 64768be860b5..745d62228341 100644 --- a/patches/unapplied/server/0066-Complete-resource-pack-API.patch +++ b/patches/server/0066-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/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index b2bddc6183204b9f519549073e38741e1a9322c4..9bfdcdf427f7c0689d346d17942b5902a9138a4e 100644 +index 99f89854e43ed6742dc9ac1624fa7140b4594b3b..d4527831f66bf1c55e6273c7f8923d6efbbf100f 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -207,7 +207,11 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -214,7 +214,11 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack callback.packEventReceived(packet.id(), net.kyori.adventure.resource.ResourcePackStatus.valueOf(packet.action().name()), this.getCraftPlayer()); } // Paper end @@ -22,10 +22,10 @@ index b2bddc6183204b9f519549073e38741e1a9322c4..9bfdcdf427f7c0689d346d17942b5902 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 951b89ced33b2a12dff90e32201643bee64962e1..a19e1c7821c6abfa4288d8a16e30b2160be742f5 100644 +index 49befbbd27fb44d564663c140dd594e0f35526f3..69459b11c77bd0a6d9584f868773dba92f73aa36 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -208,6 +208,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -209,6 +209,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { private double healthScale = 20; private CraftWorldBorder clientWorldBorder = null; private BorderChangeListener clientWorldBorderListener = this.createWorldBorderListener(); @@ -33,7 +33,7 @@ index 951b89ced33b2a12dff90e32201643bee64962e1..a19e1c7821c6abfa4288d8a16e30b216 public CraftPlayer(CraftServer server, ServerPlayer entity) { super(server, entity); -@@ -2094,6 +2095,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2107,6 +2108,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end - adventure diff --git a/patches/unapplied/server/0067-Default-loading-permissions.yml-before-plugins.patch b/patches/server/0067-Default-loading-permissions.yml-before-plugins.patch similarity index 89% rename from patches/unapplied/server/0067-Default-loading-permissions.yml-before-plugins.patch rename to patches/server/0067-Default-loading-permissions.yml-before-plugins.patch index 09d482562060..8cf22bcec703 100644 --- a/patches/unapplied/server/0067-Default-loading-permissions.yml-before-plugins.patch +++ b/patches/server/0067-Default-loading-permissions.yml-before-plugins.patch @@ -16,10 +16,10 @@ 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 3043ec179592606050deede2874b0e251b859892..dfd8776ff6cd8be750e77dc4c30f59c28ff1732a 100644 +index c80fe475edffce53363dfea658b9f13a2c6de1ca..bd18711474807518ceefa9d097d94a78b9e66158 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -488,6 +488,7 @@ public final class CraftServer implements Server { +@@ -491,6 +491,7 @@ public final class CraftServer implements Server { if (type == PluginLoadOrder.STARTUP) { this.helpMap.clear(); this.helpMap.initializeGeneralTopics(); @@ -27,7 +27,7 @@ index 3043ec179592606050deede2874b0e251b859892..dfd8776ff6cd8be750e77dc4c30f59c2 } Plugin[] plugins = this.pluginManager.getPlugins(); -@@ -507,7 +508,7 @@ public final class CraftServer implements Server { +@@ -510,7 +511,7 @@ public final class CraftServer implements Server { this.commandMap.registerServerAliases(); DefaultPermissions.registerCorePermissions(); CraftDefaultPermissions.registerCorePermissions(); diff --git a/patches/unapplied/server/0068-Allow-Reloading-of-Custom-Permissions.patch b/patches/server/0068-Allow-Reloading-of-Custom-Permissions.patch similarity index 90% rename from patches/unapplied/server/0068-Allow-Reloading-of-Custom-Permissions.patch rename to patches/server/0068-Allow-Reloading-of-Custom-Permissions.patch index c66e0d8e2656..b7b06d1ab87c 100644 --- a/patches/unapplied/server/0068-Allow-Reloading-of-Custom-Permissions.patch +++ b/patches/server/0068-Allow-Reloading-of-Custom-Permissions.patch @@ -6,10 +6,10 @@ 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 dfd8776ff6cd8be750e77dc4c30f59c28ff1732a..2b0f69b89d69258a1e9a6a81db5c9d4497417cd7 100644 +index bd18711474807518ceefa9d097d94a78b9e66158..2cc9faa6c560ceb8e50984e01a8f5caa042b62ba 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2792,5 +2792,23 @@ public final class CraftServer implements Server { +@@ -2809,5 +2809,23 @@ public final class CraftServer implements Server { } return this.adventure$audiences; } diff --git a/patches/unapplied/server/0069-Remove-Metadata-on-reload.patch b/patches/server/0069-Remove-Metadata-on-reload.patch similarity index 88% rename from patches/unapplied/server/0069-Remove-Metadata-on-reload.patch rename to patches/server/0069-Remove-Metadata-on-reload.patch index 6754fe94caa1..ec1a1512d4b9 100644 --- a/patches/unapplied/server/0069-Remove-Metadata-on-reload.patch +++ b/patches/server/0069-Remove-Metadata-on-reload.patch @@ -7,10 +7,10 @@ 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 2b0f69b89d69258a1e9a6a81db5c9d4497417cd7..b7539a5f7bc20f20f3cd7fb30d87ab7ffc1133c3 100644 +index 2cc9faa6c560ceb8e50984e01a8f5caa042b62ba..e9e612581683b27f35c0ef7adaae8e8b7eb677ec 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1003,8 +1003,16 @@ public final class CraftServer implements Server { +@@ -1006,8 +1006,16 @@ public final class CraftServer implements Server { world.spigotConfig.init(); // Spigot } diff --git a/patches/unapplied/server/0070-Handle-Item-Meta-Inconsistencies.patch b/patches/server/0070-Handle-Item-Meta-Inconsistencies.patch similarity index 93% rename from patches/unapplied/server/0070-Handle-Item-Meta-Inconsistencies.patch rename to patches/server/0070-Handle-Item-Meta-Inconsistencies.patch index b282519efe64..e6681a5fd83f 100644 --- a/patches/unapplied/server/0070-Handle-Item-Meta-Inconsistencies.patch +++ b/patches/server/0070-Handle-Item-Meta-Inconsistencies.patch @@ -18,7 +18,7 @@ For consistency, the old API methods now forward to use the ItemMeta API equivalents, and should deprecate the old API's. diff --git a/src/main/java/net/minecraft/world/item/enchantment/ItemEnchantments.java b/src/main/java/net/minecraft/world/item/enchantment/ItemEnchantments.java -index a4f8cb2c9dc464e94483f5574cddab85ef407048..8ac485d82c2d2b32f4d54e02c18c2cb2c3df4fa4 100644 +index bc6c2c24174181315c5622ba0dbe578b4dbcc627..cfc6a657cae92c68868a76c1b7b1febe2a16e9f4 100644 --- a/src/main/java/net/minecraft/world/item/enchantment/ItemEnchantments.java +++ b/src/main/java/net/minecraft/world/item/enchantment/ItemEnchantments.java @@ -26,12 +26,25 @@ import net.minecraft.tags.TagKey; @@ -35,7 +35,7 @@ index a4f8cb2c9dc464e94483f5574cddab85ef407048..8ac485d82c2d2b32f4d54e02c18c2cb2 + private static final java.util.Comparator> ENCHANTMENT_ORDER = java.util.Comparator.comparing(Holder::getRegisteredName); + public static final ItemEnchantments EMPTY = new ItemEnchantments(new Object2IntAVLTreeMap<>(ENCHANTMENT_ORDER), true); + // Paper end - private static final Codec LEVEL_CODEC = Codec.intRange(0, 255); + private static final Codec LEVEL_CODEC = Codec.intRange(1, 255); - private static final Codec>> LEVELS_CODEC = Codec.unboundedMap(Enchantment.CODEC, LEVEL_CODEC) - .xmap(Object2IntOpenHashMap::new, Function.identity()); + private static final Codec>> LEVELS_CODEC = Codec.unboundedMap( @@ -70,7 +70,7 @@ index a4f8cb2c9dc464e94483f5574cddab85ef407048..8ac485d82c2d2b32f4d54e02c18c2cb2 this.enchantments = enchantments; this.showInTooltip = showInTooltip; -@@ -141,7 +154,7 @@ public class ItemEnchantments implements TooltipProvider { +@@ -139,7 +152,7 @@ public class ItemEnchantments implements TooltipProvider { } public static class Mutable { @@ -80,10 +80,10 @@ index a4f8cb2c9dc464e94483f5574cddab85ef407048..8ac485d82c2d2b32f4d54e02c18c2cb2 public Mutable(ItemEnchantments enchantmentsComponent) { diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index 17fa2d3db112762bcb8b941b69b8ddcc53f47224..6c76aeddb34239a5acc204a17b2aa2d80e6b2c88 100644 +index 101eea3452c9e387e770b716543c3a4f17b9a737..aea09533fada5bd3d42e2cc147921167a5e7c1a5 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -@@ -214,16 +214,13 @@ public final class CraftItemStack extends ItemStack { +@@ -229,16 +229,13 @@ public final class CraftItemStack extends ItemStack { public void addUnsafeEnchantment(Enchantment ench, int level) { Preconditions.checkArgument(ench != null, "Enchantment cannot be null"); @@ -106,7 +106,7 @@ index 17fa2d3db112762bcb8b941b69b8ddcc53f47224..6c76aeddb34239a5acc204a17b2aa2d8 } static boolean makeTag(net.minecraft.world.item.ItemStack item) { -@@ -252,24 +249,15 @@ public final class CraftItemStack extends ItemStack { +@@ -267,24 +264,15 @@ public final class CraftItemStack extends ItemStack { public int removeEnchantment(Enchantment ench) { Preconditions.checkArgument(ench != null, "Enchantment cannot be null"); @@ -139,7 +139,7 @@ index 17fa2d3db112762bcb8b941b69b8ddcc53f47224..6c76aeddb34239a5acc204a17b2aa2d8 return level; } -@@ -281,7 +269,7 @@ public final class CraftItemStack extends ItemStack { +@@ -296,7 +284,7 @@ public final class CraftItemStack extends ItemStack { @Override public Map getEnchantments() { @@ -149,7 +149,7 @@ index 17fa2d3db112762bcb8b941b69b8ddcc53f47224..6c76aeddb34239a5acc204a17b2aa2d8 static Map getEnchantments(net.minecraft.world.item.ItemStack item) { diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index f6ac13f91f08498a8adda7d34518a5cfe34c15b2..9ab1abd4414a0a40284e12dfebff37e21e7f150f 100644 +index 1c943638bfbda8281d2c9038e9024591823e2b5e..b2683d6efd53b03d7043098b19a1504885a5b3c7 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -6,6 +6,7 @@ import com.google.common.collect.ImmutableList; @@ -168,16 +168,16 @@ index f6ac13f91f08498a8adda7d34518a5cfe34c15b2..9ab1abd4414a0a40284e12dfebff37e2 import java.util.EnumSet; import java.util.HashMap; import java.util.Iterator; -@@ -250,7 +252,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - private List lore; // null and empty are two different states internally +@@ -281,7 +283,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { private Integer customModelData; + private Integer enchantableValue; private Map blockData; - private Map enchantments; + private EnchantmentMap enchantments; // Paper private Multimap attributeModifiers; private int repairCost; private int hideFlag; -@@ -292,7 +294,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -330,7 +332,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { this.blockData = meta.blockData; if (meta.enchantments != null) { @@ -186,7 +186,7 @@ index f6ac13f91f08498a8adda7d34518a5cfe34c15b2..9ab1abd4414a0a40284e12dfebff37e2 } if (meta.hasAttributeModifiers()) { -@@ -438,8 +440,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -509,8 +511,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { } } @@ -197,7 +197,7 @@ index f6ac13f91f08498a8adda7d34518a5cfe34c15b2..9ab1abd4414a0a40284e12dfebff37e2 tag.entrySet().forEach((entry) -> { Holder id = entry.getKey(); -@@ -736,13 +738,13 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -844,13 +846,13 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { return modifiers; } @@ -213,7 +213,7 @@ index f6ac13f91f08498a8adda7d34518a5cfe34c15b2..9ab1abd4414a0a40284e12dfebff37e2 for (Map.Entry entry : ench.entrySet()) { Enchantment enchantment = CraftEnchantment.stringToBukkit(entry.getKey().toString()); if ((enchantment != null) && (entry.getValue() instanceof Integer)) { -@@ -1081,14 +1083,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1217,14 +1219,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public Map getEnchants() { @@ -230,8 +230,8 @@ index f6ac13f91f08498a8adda7d34518a5cfe34c15b2..9ab1abd4414a0a40284e12dfebff37e2 } if (ignoreRestrictions || level >= ench.getStartLevel() && level <= ench.getMaxLevel()) { -@@ -1688,7 +1690,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - clone.customModelData = this.customModelData; +@@ -1955,7 +1957,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + clone.enchantableValue = this.enchantableValue; clone.blockData = this.blockData; if (this.enchantments != null) { - clone.enchantments = new LinkedHashMap(this.enchantments); @@ -239,7 +239,7 @@ index f6ac13f91f08498a8adda7d34518a5cfe34c15b2..9ab1abd4414a0a40284e12dfebff37e2 } if (this.hasAttributeModifiers()) { clone.attributeModifiers = LinkedHashMultimap.create(this.attributeModifiers); -@@ -2038,4 +2040,22 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2351,4 +2353,22 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { return (result != null) ? result : Optional.empty(); } diff --git a/patches/unapplied/server/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch b/patches/server/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch similarity index 89% rename from patches/unapplied/server/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch rename to patches/server/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch index e1e0b3df9cb3..f59a8a6609bd 100644 --- a/patches/unapplied/server/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch +++ b/patches/server/0071-Configurable-Non-Player-Arrow-Despawn-Rate.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Configurable Non Player Arrow Despawn Rate Can set a much shorter despawn rate for arrows that players can not pick up. diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -index 89eebea583550fe703005e5a7020fa4063778a4a..230040bef7d2cf9a463cfd9cb3b1b1aa208a7119 100644 +index a4a932c9b0ad8f83c32bb06428c74d5b4c1741d1..a1b1c6385d3a1fbe38f5ae4471b8e4f6ef2c80b3 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -@@ -356,7 +356,7 @@ public abstract class AbstractArrow extends Projectile { +@@ -379,7 +379,7 @@ public abstract class AbstractArrow extends Projectile { protected void tickDespawn() { ++this.life; diff --git a/patches/unapplied/server/0072-Add-World-Util-Methods.patch b/patches/server/0072-Add-World-Util-Methods.patch similarity index 94% rename from patches/unapplied/server/0072-Add-World-Util-Methods.patch rename to patches/server/0072-Add-World-Util-Methods.patch index a0b554c53b60..11bb708681e6 100644 --- a/patches/unapplied/server/0072-Add-World-Util-Methods.patch +++ b/patches/server/0072-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/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 32b42d25631aecdd31db4954a8bbf38bcda98d6b..dfb349ed8a0fb981b3234baf040bd3297a555ebf 100644 +index 574d8d311001ce15c2a2391caaec0a0b0b1653b5..b37aeadf48e112170d64adc7587fdacbf6466aee 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -341,6 +341,22 @@ public abstract class Level implements LevelAccessor, AutoCloseable { diff --git a/patches/unapplied/server/0073-Custom-replacement-for-eaten-items.patch b/patches/server/0073-Custom-replacement-for-eaten-items.patch similarity index 87% rename from patches/unapplied/server/0073-Custom-replacement-for-eaten-items.patch rename to patches/server/0073-Custom-replacement-for-eaten-items.patch index c7a07a43588b..04ecd8892577 100644 --- a/patches/unapplied/server/0073-Custom-replacement-for-eaten-items.patch +++ b/patches/server/0073-Custom-replacement-for-eaten-items.patch @@ -5,11 +5,11 @@ Subject: [PATCH] Custom replacement for eaten items diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index a5f7289158623c8fb9fd02beecc2ce9f2057a00c..b8a69688bcc69dff11e4bceb06ab435bfc6b3fc9 100644 +index b3f7d20c7853afaa396a90fbe23ed33d03fda8eb..4fa5e7127549e090338b11e6493413a3fab254a0 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3858,10 +3858,11 @@ public abstract class LivingEntity extends Entity implements Attackable { - this.triggerItemUseEffects(this.useItem, 16); +@@ -3984,10 +3984,11 @@ public abstract class LivingEntity extends Entity implements Attackable { + if (!this.useItem.isEmpty() && this.isUsingItem()) { // CraftBukkit start - fire PlayerItemConsumeEvent ItemStack itemstack; + PlayerItemConsumeEvent event = null; // Paper @@ -21,7 +21,7 @@ index a5f7289158623c8fb9fd02beecc2ce9f2057a00c..b8a69688bcc69dff11e4bceb06ab435b this.level().getCraftServer().getPluginManager().callEvent(event); if (event.isCancelled()) { -@@ -3878,6 +3879,12 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4005,6 +4006,12 @@ public abstract class LivingEntity extends Entity implements Attackable { } else { itemstack = this.useItem.finishUsingItem(this.level(), this); } @@ -34,7 +34,7 @@ index a5f7289158623c8fb9fd02beecc2ce9f2057a00c..b8a69688bcc69dff11e4bceb06ab435b // CraftBukkit end if (itemstack != this.useItem) { -@@ -3885,6 +3892,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4012,6 +4019,11 @@ public abstract class LivingEntity extends Entity implements Attackable { } this.stopUsingItem(); diff --git a/patches/unapplied/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch b/patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch similarity index 85% rename from patches/unapplied/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch rename to patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch index 1d38bc8302cb..a547f5a1766e 100644 --- a/patches/unapplied/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch +++ b/patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch @@ -5,10 +5,10 @@ Subject: [PATCH] handle NaN health/absorb values and repair bad data diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index e7b308ba4a253b270aebebd19e2671514c5357ca..fae7c493c9be741f019fc49f45a59976e6b01ed7 100644 +index 4fa5e7127549e090338b11e6493413a3fab254a0..14d9e62c86309676ddd7eed19cce2f4b30a59b94 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -808,7 +808,13 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -833,7 +833,13 @@ public abstract class LivingEntity extends Entity implements Attackable { @Override public void readAdditionalSaveData(CompoundTag nbt) { @@ -23,7 +23,7 @@ index e7b308ba4a253b270aebebd19e2671514c5357ca..fae7c493c9be741f019fc49f45a59976 if (nbt.contains("attributes", 9) && this.level() != null && !this.level().isClientSide) { this.getAttributes().load(nbt.getList("attributes", 10)); } -@@ -1342,6 +1348,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1373,6 +1379,10 @@ public abstract class LivingEntity extends Entity implements Attackable { } public void setHealth(float health) { @@ -34,7 +34,7 @@ index e7b308ba4a253b270aebebd19e2671514c5357ca..fae7c493c9be741f019fc49f45a59976 // CraftBukkit start - Handle scaled health if (this instanceof ServerPlayer) { org.bukkit.craftbukkit.entity.CraftPlayer player = ((ServerPlayer) this).getBukkitEntity(); -@@ -3688,7 +3698,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3841,7 +3851,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } public final void setAbsorptionAmount(float absorptionAmount) { @@ -44,10 +44,10 @@ index e7b308ba4a253b270aebebd19e2671514c5357ca..fae7c493c9be741f019fc49f45a59976 protected void internalSetAbsorptionAmount(float absorptionAmount) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 174c86a7213ecf3c8dc03aeaf55c56a4c4ce55ad..c399264ccffe646be10b3f13ebe0c0103d97f62c 100644 +index 69459b11c77bd0a6d9584f868773dba92f73aa36..ca6194580c10cc864430b859a2c60d0b2e6a9a16 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2338,6 +2338,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2351,6 +2351,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } public void setRealHealth(double health) { diff --git a/patches/unapplied/server/0075-Use-a-Shared-Random-for-Entities.patch b/patches/server/0075-Use-a-Shared-Random-for-Entities.patch similarity index 91% rename from patches/unapplied/server/0075-Use-a-Shared-Random-for-Entities.patch rename to patches/server/0075-Use-a-Shared-Random-for-Entities.patch index 0dc711a42bc2..b053616a5f74 100644 --- a/patches/unapplied/server/0075-Use-a-Shared-Random-for-Entities.patch +++ b/patches/server/0075-Use-a-Shared-Random-for-Entities.patch @@ -6,10 +6,10 @@ 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 82e57978b79b5275b98a1fa7731c6a23ee861a2f..bd17157631a74f80e3b5ce50bb1f681abe1dd6a7 100644 +index 8a61ca3cba2888e03e440519714705fe50b81267..847fd720f11e89d906430c820bc92afe0454761d 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -175,6 +175,79 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -183,6 +183,79 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return tag.contains("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level; } @@ -89,7 +89,7 @@ index 82e57978b79b5275b98a1fa7731c6a23ee861a2f..bd17157631a74f80e3b5ce50bb1f681a private CraftEntity bukkitEntity; public CraftEntity getBukkitEntity() { -@@ -370,7 +443,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -373,7 +446,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.bb = Entity.INITIAL_AABB; this.stuckSpeedMultiplier = Vec3.ZERO; this.nextStep = 1.0F; @@ -99,10 +99,10 @@ index 82e57978b79b5275b98a1fa7731c6a23ee861a2f..bd17157631a74f80e3b5ce50bb1f681a this.fluidHeight = new Object2DoubleArrayMap(2); this.fluidOnEyes = new HashSet(); diff --git a/src/main/java/net/minecraft/world/entity/animal/Squid.java b/src/main/java/net/minecraft/world/entity/animal/Squid.java -index 97d5bc9bab95c21afb3b95d2a7eb7df0b64698ed..42f4e544fe7fbc342f15eacb5e38d40849e3c419 100644 +index bcccd7d808a3bef4acafe2e6b484ba0ed8059507..f9fdc600dc680c55219fcbf9bc8f151a733a093c 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Squid.java +++ b/src/main/java/net/minecraft/world/entity/animal/Squid.java -@@ -41,7 +41,7 @@ public class Squid extends WaterAnimal { +@@ -46,7 +46,7 @@ public class Squid extends AgeableWaterCreature { public Squid(EntityType type, Level world) { super(type, world); diff --git a/patches/unapplied/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch b/patches/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch similarity index 83% rename from patches/unapplied/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch rename to patches/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch index 5d754792063d..3a7066283ff9 100644 --- a/patches/unapplied/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch +++ b/patches/server/0076-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 6d89dc22e28a9c3557d9972be0935d75719e7f7d..de1708e5d39561115d2825eea4a5f6e1f1f4e5b8 100644 +index 77d61f16b5b45fbe78deaf90f4ae4b126546c3e9..63f99fb1dde13854ad9be1a57441bd1b1a40c8d6 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -621,7 +621,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -608,7 +608,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (this.isRainingAt(blockposition)) { DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition); @@ -16,4 +16,4 @@ index 6d89dc22e28a9c3557d9972be0935d75719e7f7d..de1708e5d39561115d2825eea4a5f6e1 + 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 - Configurable spawn chances for skeleton horses if (flag1) { - SkeletonHorse entityhorseskeleton = (SkeletonHorse) EntityType.SKELETON_HORSE.create(this); + SkeletonHorse entityhorseskeleton = (SkeletonHorse) EntityType.SKELETON_HORSE.create(this, EntitySpawnReason.EVENT); diff --git a/patches/unapplied/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch b/patches/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch similarity index 74% rename from patches/unapplied/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch rename to patches/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch index 8730c44f6b2b..07883924deb9 100644 --- a/patches/unapplied/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch +++ b/patches/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch @@ -6,22 +6,22 @@ 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 1ba2b1aaf0936963aca73a43632f978c95bf95e6..639dd562b7eda25004ea10d6c481173afb214773 100644 +index 254e34f80ed0d06f200a78c60f34b4ffc5e5ed85..b8a60520cc10383f22d810ca8061ed25b962a233 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1542,6 +1542,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent - this.profiler.push(() -> { + gameprofilerfiller.push(() -> { String s = String.valueOf(worldserver); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index de1708e5d39561115d2825eea4a5f6e1f1f4e5b8..1e5b42fc3903b14537d232c8adbbaf79078d8d8e 100644 +index 63f99fb1dde13854ad9be1a57441bd1b1a40c8d6..9aa60bb30ce5f2deddcb8b228ebafac766f02f93 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -227,6 +227,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -230,6 +230,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // CraftBukkit start public final LevelStorageSource.LevelStorageAccess convertable; public final UUID uuid; @@ -30,7 +30,7 @@ index de1708e5d39561115d2825eea4a5f6e1f1f4e5b8..1e5b42fc3903b14537d232c8adbbaf79 public LevelChunk getChunkIfLoaded(int x, int z) { return this.chunkSource.getChunk(x, z, false); diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index dfb349ed8a0fb981b3234baf040bd3297a555ebf..024da1029baecae639d7c05b5f7c30dbaa67b006 100644 +index b37aeadf48e112170d64adc7587fdacbf6466aee..9ad531912c4298658915b45b2870539059e8aadd 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -491,7 +491,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -43,23 +43,23 @@ index dfb349ed8a0fb981b3234baf040bd3297a555ebf..024da1029baecae639d7c05b5f7c30db this.getCraftServer().getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/world/level/block/BushBlock.java b/src/main/java/net/minecraft/world/level/block/BushBlock.java -index 75109c79daa724340268438725bbf6d39b955691..a7b4b5600e3c889c69ac22294899713d50b5fe5c 100644 +index 4db8f94dc279d05ed1cdf52e49ef780025828067..eb324fda54ada3ed7941713a784ed2d686ec8c4b 100644 --- a/src/main/java/net/minecraft/world/level/block/BushBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BushBlock.java -@@ -28,7 +28,7 @@ public abstract class BushBlock extends Block { - protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { +@@ -31,7 +31,7 @@ public abstract class BushBlock extends Block { // CraftBukkit start if (!state.canSurvive(world, pos)) { -- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, pos).isCancelled()) { -+ if (!(world instanceof net.minecraft.server.level.ServerLevel && ((net.minecraft.server.level.ServerLevel) world).hasPhysicsEvent) || !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, pos).isCancelled()) { // Paper + // Suppress during worldgen +- if (!(world instanceof Level world1) || !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world1, pos).isCancelled()) { ++ if (!(world instanceof net.minecraft.server.level.ServerLevel world1 && world1.hasPhysicsEvent) || !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world1, pos).isCancelled()) { // Paper return Blocks.AIR.defaultBlockState(); } } diff --git a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java -index cb76568cd1f97024c7a40328d9d72dd8a3e72e8b..7fdf744a2be55313cc75c1322f6534f55cf463f5 100644 +index 46047e0567af62612aad479fff6bea88903f108a..edb3b6cdb617c48140539728af1373993e78648f 100644 --- a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java -@@ -102,7 +102,7 @@ public class DoublePlantBlock extends BushBlock { +@@ -104,7 +104,7 @@ public class DoublePlantBlock extends BushBlock { protected static void preventDropFromBottomPart(Level world, BlockPos pos, BlockState state, Player player) { // CraftBukkit start diff --git a/patches/unapplied/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch b/patches/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch similarity index 79% rename from patches/unapplied/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch rename to patches/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch index 83aad502c32e..5171c96a5209 100644 --- a/patches/unapplied/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch +++ b/patches/server/0078-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 1e5b42fc3903b14537d232c8adbbaf79078d8d8e..e6cf145fa7a2968c70e9e467e3927fd38e199e06 100644 +index 9aa60bb30ce5f2deddcb8b228ebafac766f02f93..d773a56d2bea90669f0b65908d990c2fc5313652 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2153,6 +2153,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2224,6 +2224,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe entity.setOrigin(entity.getOriginVector().toLocation(getWorld())); } // Paper end - Entity origin API @@ -16,7 +16,7 @@ index 1e5b42fc3903b14537d232c8adbbaf79078d8d8e..e6cf145fa7a2968c70e9e467e3927fd3 } public void onTrackingEnd(Entity entity) { -@@ -2223,6 +2224,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2294,6 +2295,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } } // CraftBukkit end diff --git a/patches/unapplied/server/0079-Configurable-Chunk-Inhabited-Time.patch b/patches/server/0079-Configurable-Chunk-Inhabited-Time.patch similarity index 81% rename from patches/unapplied/server/0079-Configurable-Chunk-Inhabited-Time.patch rename to patches/server/0079-Configurable-Chunk-Inhabited-Time.patch index 9eb058e66940..5a4d79299411 100644 --- a/patches/unapplied/server/0079-Configurable-Chunk-Inhabited-Time.patch +++ b/patches/server/0079-Configurable-Chunk-Inhabited-Time.patch @@ -11,11 +11,11 @@ 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 fb953b2172c322e8abf5aa50060adbc00fe92832..a0f9fb2ac15f2fa51a3bbe915550155ac2e76649 100644 +index 401f18deb9e9f019ea17ad684f2d5c4ea5e7ef97..add5ec0f8e8bd0b89511dcb656e1d4cda702a86b 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -172,6 +172,13 @@ public class LevelChunk extends ChunkAccess { - return new ChunkAccess.TicksToSave(this.blockTicks, this.fluidTicks); +@@ -195,6 +195,13 @@ public class LevelChunk extends ChunkAccess { + return new ChunkAccess.PackedTicks(this.blockTicks.pack(time), this.fluidTicks.pack(time)); } + // Paper start diff --git a/patches/unapplied/server/0080-EntityPathfindEvent.patch b/patches/server/0080-EntityPathfindEvent.patch similarity index 81% rename from patches/unapplied/server/0080-EntityPathfindEvent.patch rename to patches/server/0080-EntityPathfindEvent.patch index e29cff85e675..f852d81661da 100644 --- a/patches/unapplied/server/0080-EntityPathfindEvent.patch +++ b/patches/server/0080-EntityPathfindEvent.patch @@ -19,10 +19,10 @@ index d3a279a1a14f99aee8dd516552e5c60de92b4969..a3e0c5af4cc9323c02e88e768cbda9e4 @Override diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java -index f1a63db8dac13efcfd73b59c7074f6817cc5dbde..62634bedd97c5be9ecce24ab0cff205715a68da8 100644 +index d41ff85a96df07e4d6d9844289379bd3f0c38dc4..f73b559b8e60859020f762dab88b67b8c912bf8f 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java -@@ -41,7 +41,7 @@ public class GroundPathNavigation extends PathNavigation { +@@ -42,7 +42,7 @@ public class GroundPathNavigation extends PathNavigation { } @Override @@ -31,30 +31,30 @@ index f1a63db8dac13efcfd73b59c7074f6817cc5dbde..62634bedd97c5be9ecce24ab0cff2057 LevelChunk levelChunk = this.level .getChunkSource() .getChunkNow(SectionPos.blockToSectionCoord(target.getX()), SectionPos.blockToSectionCoord(target.getZ())); -@@ -56,7 +56,7 @@ public class GroundPathNavigation extends PathNavigation { +@@ -57,7 +57,7 @@ public class GroundPathNavigation extends PathNavigation { } - if (blockPos.getY() > this.level.getMinBuildHeight()) { -- return super.createPath(blockPos.above(), distance); -+ return super.createPath(blockPos.above(), entity, distance); // Paper - EntityPathfindEvent + if (mutableBlockPos.getY() > this.level.getMinY()) { +- return super.createPath(mutableBlockPos.above(), distance); ++ return super.createPath(mutableBlockPos.above(), entity, distance); // Paper - EntityPathfindEvent } - while (blockPos.getY() < this.level.getMaxBuildHeight() && levelChunk.getBlockState(blockPos).isAir()) { -@@ -67,7 +67,7 @@ public class GroundPathNavigation extends PathNavigation { + mutableBlockPos.setY(target.getY() + 1); +@@ -70,7 +70,7 @@ public class GroundPathNavigation extends PathNavigation { } if (!levelChunk.getBlockState(target).isSolid()) { - return super.createPath(target, distance); + return super.createPath(target, entity, distance); // Paper - EntityPathfindEvent } else { - BlockPos blockPos2 = target.above(); + BlockPos.MutableBlockPos mutableBlockPos2 = target.mutable().move(Direction.UP); -@@ -75,14 +75,14 @@ public class GroundPathNavigation extends PathNavigation { - blockPos2 = blockPos2.above(); +@@ -78,14 +78,14 @@ public class GroundPathNavigation extends PathNavigation { + mutableBlockPos2.move(Direction.UP); } -- return super.createPath(blockPos2, distance); -+ return super.createPath(blockPos2, entity, distance); // Paper - EntityPathfindEvent +- return super.createPath(mutableBlockPos2.immutable(), distance); ++ return super.createPath(mutableBlockPos2.immutable(), entity, distance); // Paper - EntityPathfindEvent } } } @@ -67,10 +67,10 @@ index f1a63db8dac13efcfd73b59c7074f6817cc5dbde..62634bedd97c5be9ecce24ab0cff2057 private int getSurfaceY() { diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java -index 92addc1d3e7d0630c5db76e2a00d61b95b1430cc..21bbc98b26b270b3ad6a3b34d6e50dfb796c3d5a 100644 +index 7d3cb358fe543253e988531df3434ae1274814d3..1d5ce4caf99a3fb376b350968a6bd1ac8471ffec 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java -@@ -109,7 +109,13 @@ public abstract class PathNavigation { +@@ -125,7 +125,13 @@ public abstract class PathNavigation { @Nullable public Path createPath(BlockPos target, int distance) { @@ -85,7 +85,7 @@ index 92addc1d3e7d0630c5db76e2a00d61b95b1430cc..21bbc98b26b270b3ad6a3b34d6e50dfb } @Nullable -@@ -119,7 +125,7 @@ public abstract class PathNavigation { +@@ -135,7 +141,7 @@ public abstract class PathNavigation { @Nullable public Path createPath(Entity entity, int distance) { @@ -94,7 +94,7 @@ index 92addc1d3e7d0630c5db76e2a00d61b95b1430cc..21bbc98b26b270b3ad6a3b34d6e50dfb } @Nullable -@@ -129,6 +135,17 @@ public abstract class PathNavigation { +@@ -145,6 +151,17 @@ public abstract class PathNavigation { @Nullable protected Path createPath(Set positions, int range, boolean useHeadPos, int distance, float followRange) { @@ -111,8 +111,8 @@ index 92addc1d3e7d0630c5db76e2a00d61b95b1430cc..21bbc98b26b270b3ad6a3b34d6e50dfb + // Paper end - EntityPathfindEvent if (positions.isEmpty()) { return null; - } else if (this.mob.getY() < (double)this.level.getMinBuildHeight()) { -@@ -138,6 +155,23 @@ public abstract class PathNavigation { + } else if (this.mob.getY() < (double)this.level.getMinY()) { +@@ -154,6 +171,23 @@ public abstract class PathNavigation { } else if (this.path != null && !this.path.isDone() && positions.contains(this.targetPos)) { return this.path; } else { @@ -133,9 +133,9 @@ index 92addc1d3e7d0630c5db76e2a00d61b95b1430cc..21bbc98b26b270b3ad6a3b34d6e50dfb + } + } + // Paper end - EntityPathfindEvent - this.level.getProfiler().push("pathfind"); + ProfilerFiller profilerFiller = Profiler.get(); + profilerFiller.push("pathfind"); BlockPos blockPos = useHeadPos ? this.mob.blockPosition().above() : this.mob.blockPosition(); - int i = (int)(followRange + (float)range); diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/WallClimberNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/WallClimberNavigation.java index 1a1bc30b425858d82dbfb84b4a94d7793cab7125..5bbfa43d1e97970f035fcb101c3252c01ffead0d 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/WallClimberNavigation.java diff --git a/patches/unapplied/server/0081-Sanitise-RegionFileCache-and-make-configurable.patch b/patches/server/0081-Sanitise-RegionFileCache-and-make-configurable.patch similarity index 100% rename from patches/unapplied/server/0081-Sanitise-RegionFileCache-and-make-configurable.patch rename to patches/server/0081-Sanitise-RegionFileCache-and-make-configurable.patch diff --git a/patches/unapplied/server/0082-Do-not-load-chunks-for-Pathfinding.patch b/patches/server/0082-Do-not-load-chunks-for-Pathfinding.patch similarity index 91% rename from patches/unapplied/server/0082-Do-not-load-chunks-for-Pathfinding.patch rename to patches/server/0082-Do-not-load-chunks-for-Pathfinding.patch index 76cfe02b0f87..f67f87234bfe 100644 --- a/patches/unapplied/server/0082-Do-not-load-chunks-for-Pathfinding.patch +++ b/patches/server/0082-Do-not-load-chunks-for-Pathfinding.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Do not load chunks for Pathfinding diff --git a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java -index 6a8f44600a426041e3974aa52bdec0cc35e26591..d5004290e40a1ff5e0fcfe75f8da34ae15962359 100644 +index 448e4d68790e795e1848236e700bf6955098e0d9..c84fd369d92932903c76bb2012602617d3e2d213 100644 --- a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java +++ b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java @@ -478,7 +478,12 @@ public class WalkNodeEvaluator extends NodeEvaluator { diff --git a/patches/unapplied/server/0083-Add-PlayerUseUnknownEntityEvent.patch b/patches/server/0083-Add-PlayerUseUnknownEntityEvent.patch similarity index 92% rename from patches/unapplied/server/0083-Add-PlayerUseUnknownEntityEvent.patch rename to patches/server/0083-Add-PlayerUseUnknownEntityEvent.patch index 99eaab4c612a..b5de8e9c2a90 100644 --- a/patches/unapplied/server/0083-Add-PlayerUseUnknownEntityEvent.patch +++ b/patches/server/0083-Add-PlayerUseUnknownEntityEvent.patch @@ -28,10 +28,10 @@ index 1e9c68cd1868d083e6a790d56006dd4aa432010a..8a0ee9564fc36a2badf1357f7e6c47b5 + // Paper end - PlayerUseUnknownEntityEvent } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 02b9e1ed57f5d65698c461387ff7d48450e6a70f..0d18b12d0755c14bd041e0f98177469612262fde 100644 +index 6b3023fbbac8ba7d0d0e2968c406b908d81ef7dc..0ddc79be416161d89c9f333ef79a16f079ba6e1d 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2493,7 +2493,26 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2505,7 +2505,26 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl }); } } @@ -59,10 +59,10 @@ index 02b9e1ed57f5d65698c461387ff7d48450e6a70f..0d18b12d0755c14bd041e0f981774696 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 8f468a3bfa8ef381eabb45ebb3dd9a4942e98dd5..96e0fc5c8a018fd579f24529175decdac634cfa1 100644 +index 8ea4d63833cd1500d7f413f761aa9a7cf26520c0..9100ea65e85a0e55cad736634fa63815366334a8 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1931,4 +1931,13 @@ public class CraftEventFactory { +@@ -1929,4 +1929,13 @@ public class CraftEventFactory { Bukkit.getPluginManager().callEvent(new EntityRemoveEvent(entity.getBukkitEntity(), cause)); } diff --git a/patches/unapplied/server/0084-Configurable-random-tick-rates-for-blocks.patch b/patches/server/0084-Configurable-random-tick-rates-for-blocks.patch similarity index 93% rename from patches/unapplied/server/0084-Configurable-random-tick-rates-for-blocks.patch rename to patches/server/0084-Configurable-random-tick-rates-for-blocks.patch index c936bd291e11..f55ff2c3104f 100644 --- a/patches/unapplied/server/0084-Configurable-random-tick-rates-for-blocks.patch +++ b/patches/server/0084-Configurable-random-tick-rates-for-blocks.patch @@ -9,7 +9,7 @@ of a variety of blocks that are random ticked. Co-authored-by: MrPowerGamerBR diff --git a/src/main/java/net/minecraft/world/level/block/FarmBlock.java b/src/main/java/net/minecraft/world/level/block/FarmBlock.java -index a88aa3150552cea020589dd9fabf0535cec816bc..529f9f57249bd1ffa2698da76ffa9d4a284088db 100644 +index 38b3c14d393137026720f42bd9f14b856b8377d0..a87f8345aa5520a867a8dd769b43526b20b8c16a 100644 --- a/src/main/java/net/minecraft/world/level/block/FarmBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FarmBlock.java @@ -93,6 +93,8 @@ public class FarmBlock extends Block { @@ -22,7 +22,7 @@ index a88aa3150552cea020589dd9fabf0535cec816bc..529f9f57249bd1ffa2698da76ffa9d4a if (!FarmBlock.isNearWater(world, pos) && !world.isRainingAt(pos.above())) { if (i > 0) { diff --git a/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java b/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java -index 7a47a3c9a56bcd3c1e817c6a7db8db8465c484e1..5a39e8d359dc13383711e49ffb2d1294dad26192 100644 +index df77ac357d645a574814014ce69413a674b81bfc..b4b826c53548bcf6952f6d0ee8037975ceb8c6e1 100644 --- a/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java @@ -43,6 +43,7 @@ public abstract class SpreadingSnowyDirtBlock extends SnowyDirtBlock { diff --git a/patches/unapplied/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch b/patches/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch similarity index 54% rename from patches/unapplied/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch rename to patches/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch index ab40c40da1b5..a2348e6b778a 100644 --- a/patches/unapplied/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch +++ b/patches/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch @@ -5,14 +5,20 @@ 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 e6cf145fa7a2968c70e9e467e3927fd38e199e06..223f8d9be5d73e296f5815db7123b95c3b345162 100644 +index d773a56d2bea90669f0b65908d990c2fc5313652..8dc2b2d8ba32aefc11eb23054b902650fac76adf 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1389,6 +1389,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1402,11 +1402,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override - public void updateNeighborsAt(BlockPos pos, Block sourceBlock) { + public void updateNeighborsAt(BlockPos pos, Block block) { + if (captureBlockStates) { return; } // Paper - Cancel all physics during placement - this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, (Direction) null); + this.updateNeighborsAt(pos, block, ExperimentalRedstoneUtils.initialOrientation(this, (Direction) null, (Direction) null)); + } + + @Override + public void updateNeighborsAt(BlockPos pos, Block sourceBlock, @Nullable Orientation orientation) { ++ if (captureBlockStates) { return; } // Paper - Cancel all physics during placement + this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, (Direction) null, orientation); } diff --git a/patches/unapplied/server/0086-Optimize-DataBits.patch b/patches/server/0086-Optimize-DataBits.patch similarity index 100% rename from patches/unapplied/server/0086-Optimize-DataBits.patch rename to patches/server/0086-Optimize-DataBits.patch diff --git a/patches/unapplied/server/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch b/patches/server/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch similarity index 100% rename from patches/unapplied/server/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch rename to patches/server/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch diff --git a/patches/unapplied/server/0088-Configurable-Player-Collision.patch b/patches/server/0088-Configurable-Player-Collision.patch similarity index 91% rename from patches/unapplied/server/0088-Configurable-Player-Collision.patch rename to patches/server/0088-Configurable-Player-Collision.patch index d8b666b4b6b0..9c3726671330 100644 --- a/patches/unapplied/server/0088-Configurable-Player-Collision.patch +++ b/patches/server/0088-Configurable-Player-Collision.patch @@ -18,10 +18,10 @@ index 9a1a961eabd4362c171da78c6be82c867f3696a4..1d0c473442b5c72245c356054440323e ComponentSerialization.TRUSTED_STREAM_CODEC.encode(buf, this.playerPrefix); ComponentSerialization.TRUSTED_STREAM_CODEC.encode(buf, this.playerSuffix); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 639dd562b7eda25004ea10d6c481173afb214773..30fbbe053ee325f4b9f7722416fb5fb92121e2ad 100644 +index b8a60520cc10383f22d810ca8061ed25b962a233..4a2ed2990e126dcf9a0c11258150958226e0cc48 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -639,6 +639,20 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop playersByName = new java.util.HashMap<>(); @@ -54,8 +54,8 @@ index 8a91a44e46a2d49e2f4b9e9970c2b77f2e87767e..98862db2334508ee1a783aeabfb14675 public PlayerList(MinecraftServer server, LayeredRegistryAccess registryManager, PlayerDataStorage saveHandler, int maxPlayers) { this.cserver = server.server = new CraftServer((DedicatedServer) server, this); -@@ -390,6 +391,13 @@ public abstract class PlayerList { - +@@ -349,6 +350,13 @@ public abstract class PlayerList { + player.loadAndSpawnParentVehicle(optional); player.initInventoryMenu(); // CraftBukkit - Moved from above, added world + // Paper start - Configurable player collision; Add to collideRule team if needed @@ -68,7 +68,7 @@ index 8a91a44e46a2d49e2f4b9e9970c2b77f2e87767e..98862db2334508ee1a783aeabfb14675 PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ()); } -@@ -512,6 +520,16 @@ public abstract class PlayerList { +@@ -471,6 +479,16 @@ public abstract class PlayerList { entityplayer.doTick(); // SPIGOT-924 // CraftBukkit end @@ -85,7 +85,7 @@ index 8a91a44e46a2d49e2f4b9e9970c2b77f2e87767e..98862db2334508ee1a783aeabfb14675 this.save(entityplayer); if (entityplayer.isPassenger()) { Entity entity = entityplayer.getRootVehicle(); -@@ -1129,6 +1147,13 @@ public abstract class PlayerList { +@@ -1098,6 +1116,13 @@ public abstract class PlayerList { } // CraftBukkit end @@ -100,10 +100,10 @@ index 8a91a44e46a2d49e2f4b9e9970c2b77f2e87767e..98862db2334508ee1a783aeabfb14675 // CraftBukkit start diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java -index 3207166061bf9c4d7bf3f38e5a9f7aff23ccd5c1..f7014bf5faae03a04c31cbdaeb27188c47156c2d 100644 +index a617ea34cfc28cefd68dd14ffbb334b87f98f65c..3a4c1d4afddd7d8d1f43554a7a08855686cadf56 100644 --- a/src/main/java/net/minecraft/world/entity/EntitySelector.java +++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java -@@ -51,7 +51,7 @@ public final class EntitySelector { +@@ -50,7 +50,7 @@ public final class EntitySelector { return (Predicate) (scoreboardteambase_enumteampush == Team.CollisionRule.NEVER ? Predicates.alwaysFalse() : EntitySelector.NO_SPECTATORS.and((entity1) -> { if (!entity1.canCollideWithBukkit(entity) || !entity.canCollideWithBukkit(entity1)) { // CraftBukkit - collidable API return false; diff --git a/patches/unapplied/server/0089-Add-handshake-event-to-allow-plugins-to-handle-clien.patch b/patches/server/0089-Add-handshake-event-to-allow-plugins-to-handle-clien.patch similarity index 100% rename from patches/unapplied/server/0089-Add-handshake-event-to-allow-plugins-to-handle-clien.patch rename to patches/server/0089-Add-handshake-event-to-allow-plugins-to-handle-clien.patch diff --git a/patches/unapplied/server/0090-Configurable-RCON-IP-address.patch b/patches/server/0090-Configurable-RCON-IP-address.patch similarity index 94% rename from patches/unapplied/server/0090-Configurable-RCON-IP-address.patch rename to patches/server/0090-Configurable-RCON-IP-address.patch index 96c8df2d2c87..2d1bfec9fe8d 100644 --- a/patches/unapplied/server/0090-Configurable-RCON-IP-address.patch +++ b/patches/server/0090-Configurable-RCON-IP-address.patch @@ -9,7 +9,7 @@ For servers with multiple IP's, ability to bind to a specific interface. public net.minecraft.server.dedicated.Settings getStringRaw(Ljava/lang/String;)Ljava/lang/String; diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java -index 36a0a8b5f85edad4dcfcdc75c4db2aa69261eae6..eb27ef574445e1311b763d84aa1b37128baa75f7 100644 +index 341123c078e97862ca8895534e85c324f256f4d6..47835226b61b726c750fe192fd94d3f8ba47565c 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java @@ -110,6 +110,8 @@ public class DedicatedServerProperties extends Settings= this.saturatedRegenRate) { // CraftBukkit float f = Math.min(this.saturationLevel, 6.0F); diff --git a/patches/unapplied/server/0092-Add-ability-to-configure-frosted_ice-properties.patch b/patches/server/0092-Add-ability-to-configure-frosted_ice-properties.patch similarity index 87% rename from patches/unapplied/server/0092-Add-ability-to-configure-frosted_ice-properties.patch rename to patches/server/0092-Add-ability-to-configure-frosted_ice-properties.patch index 5470fbc9aba1..5fe3cf9edead 100644 --- a/patches/unapplied/server/0092-Add-ability-to-configure-frosted_ice-properties.patch +++ b/patches/server/0092-Add-ability-to-configure-frosted_ice-properties.patch @@ -5,18 +5,18 @@ Subject: [PATCH] Add ability to configure frosted_ice properties diff --git a/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java b/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java -index cdf3cc2a08c52d0e5e5efd5c798f6dc156c0df55..ae6a952e49d20b7c6ad753169608794abe720ee0 100644 +index 39f4eeb965655b8495802608ad9de4ce2ea42ad0..2e47d1a37b783264ec139536b7dc89b8a55046a6 100644 --- a/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java -@@ -40,6 +40,7 @@ public class FrostedIceBlock extends IceBlock { +@@ -42,6 +42,7 @@ public class FrostedIceBlock extends IceBlock { @Override protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + if (!world.paperConfig().environment.frostedIce.enabled) return; // Paper - Frosted ice options if ((random.nextInt(3) == 0 || this.fewerNeigboursThan(world, pos, 4)) - && world.getMaxLocalRawBrightness(pos) > 11 - state.getValue(AGE) - state.getLightBlock(world, pos) + && world.getMaxLocalRawBrightness(pos) > 11 - state.getValue(AGE) - state.getLightBlock() && this.slightlyMelt(state, world, pos)) { -@@ -49,11 +50,11 @@ public class FrostedIceBlock extends IceBlock { +@@ -51,11 +52,11 @@ public class FrostedIceBlock extends IceBlock { mutableBlockPos.setWithOffset(pos, direction); BlockState blockState = world.getBlockState(mutableBlockPos); if (blockState.is(this) && !this.slightlyMelt(blockState, world, mutableBlockPos)) { diff --git a/patches/unapplied/server/0093-remove-null-possibility-for-getServer-singleton.patch b/patches/server/0093-remove-null-possibility-for-getServer-singleton.patch similarity index 83% rename from patches/unapplied/server/0093-remove-null-possibility-for-getServer-singleton.patch rename to patches/server/0093-remove-null-possibility-for-getServer-singleton.patch index 471757470725..cb0a32571ba7 100644 --- a/patches/unapplied/server/0093-remove-null-possibility-for-getServer-singleton.patch +++ b/patches/server/0093-remove-null-possibility-for-getServer-singleton.patch @@ -6,26 +6,26 @@ 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 30fbbe053ee325f4b9f7722416fb5fb92121e2ad..f16ade2019e58a9374a550f58113313c118c2f2b 100644 +index 4a2ed2990e126dcf9a0c11258150958226e0cc48..fe59a95cf4f9750ce6ea8bbc98622ee42e37148a 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -197,6 +197,7 @@ import co.aikar.timings.MinecraftTimings; // Paper +@@ -204,6 +204,7 @@ import co.aikar.timings.MinecraftTimings; // Paper - public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource, AutoCloseable { + public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource { + private static MinecraftServer SERVER; // Paper public static final Logger LOGGER = LogUtils.getLogger(); public static final net.kyori.adventure.text.logger.slf4j.ComponentLogger COMPONENT_LOGGER = net.kyori.adventure.text.logger.slf4j.ComponentLogger.logger(LOGGER.getName()); // Paper public static final String VANILLA_BRAND = "vanilla"; -@@ -330,6 +331,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -@@ -2546,9 +2548,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop lootTable; - public long lootTableSeed; +diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractChestBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractChestBoat.java +index 9c871c74ddc9983f6b4df27c7614f7224b682269..8033abfd77bcc20326b992a9d81e2faa9582fb83 100644 +--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractChestBoat.java ++++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractChestBoat.java +@@ -181,7 +181,7 @@ public abstract class AbstractChestBoat extends AbstractBoat implements HasCusto + @Nullable + @Override + public AbstractContainerMenu createMenu(int syncId, Inventory playerInventory, Player player) { +- if (this.lootTable != null && player.isSpectator()) { ++ if (this.lootTable != null && player.isSpectator()) { // Paper - LootTable API (TODO spectators can open chests that aren't ready to be re-generated but this doesn't support that) + return null; + } else { + this.unpackLootTable(playerInventory.player); +@@ -229,6 +229,14 @@ public abstract class AbstractChestBoat extends AbstractBoat implements HasCusto + this.level().gameEvent((Holder) GameEvent.CONTAINER_CLOSE, this.position(), GameEvent.Context.of((Entity) player)); + } + // Paper start - LootTable API + final com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData = new com.destroystokyo.paper.loottable.PaperLootableInventoryData(); @@ -627,22 +636,13 @@ index 67840327e934b631a85cf2d64911f5cfab4402b1..9549eee0d92f322bd5232abd7e695213 // CraftBukkit start public List transaction = new java.util.ArrayList(); private int maxStack = MAX_STACK; -diff --git a/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java -index 42f8e2d961f83c3e9ce384158b9dfc4014eb0a5f..4cdf3b54187ebcb1f5ddfa6114386127a2846f01 100644 ---- a/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java -+++ b/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java -@@ -217,7 +217,7 @@ public class ChestBoat extends Boat implements HasCustomInventoryScreen, Contain - @Nullable - @Override - public AbstractContainerMenu createMenu(int syncId, Inventory playerInventory, Player player) { -- if (this.lootTable != null && player.isSpectator()) { -+ if (this.lootTable != null && player.isSpectator()) { // Paper - LootTable API (TODO spectators can open chests that aren't ready to be re-generated but this doesn't support that) - return null; - } else { - this.unpackLootTable(playerInventory.player); -@@ -265,6 +265,14 @@ public class ChestBoat extends Boat implements HasCustomInventoryScreen, Contain - this.level().gameEvent((Holder) GameEvent.CONTAINER_CLOSE, this.position(), GameEvent.Context.of((Entity) player)); - } +diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java +index a4be7b19b626957efdf2f2507121f0085ba1da50..d528e8e4aea266c495377365f01e314001eb1970 100644 +--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java ++++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java +@@ -36,6 +36,14 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme + public ResourceKey lootTable; + public long lootTableSeed; + // Paper start - LootTable API + final com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData = new com.destroystokyo.paper.loottable.PaperLootableInventoryData(); @@ -656,61 +656,62 @@ index 42f8e2d961f83c3e9ce384158b9dfc4014eb0a5f..4cdf3b54187ebcb1f5ddfa6114386127 public List transaction = new java.util.ArrayList(); private int maxStack = MAX_STACK; diff --git a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java -index 3ee99193de5deb6a38d6ded561fe8f2fbf711327..ccc7367ab2740bea0f2b907223a0920b11665092 100644 +index beba927cffdeedcd68d8048708f5bf1a409ff965..5c78e33d4d369700a5fa6eb3cbbe85756465a063 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java @@ -62,22 +62,26 @@ public interface ContainerEntity extends Container, MenuProvider { - default void addChestVehicleSaveData(CompoundTag nbt, HolderLookup.Provider registriesLookup) { - if (this.getLootTable() != null) { - nbt.putString("LootTable", this.getLootTable().location().toString()); + default void addChestVehicleSaveData(CompoundTag nbt, HolderLookup.Provider registries) { + if (this.getContainerLootTable() != null) { + nbt.putString("LootTable", this.getContainerLootTable().location().toString()); + this.lootableData().saveNbt(nbt); // Paper - if (this.getLootTableSeed() != 0L) { - nbt.putLong("LootTableSeed", this.getLootTableSeed()); + if (this.getContainerLootTableSeed() != 0L) { + nbt.putLong("LootTableSeed", this.getContainerLootTableSeed()); } - } else { -- ContainerHelper.saveAllItems(nbt, this.getItemStacks(), registriesLookup); +- ContainerHelper.saveAllItems(nbt, this.getItemStacks(), registries); } -+ ContainerHelper.saveAllItems(nbt, this.getItemStacks(), registriesLookup); // Paper - always save the items, table may still remain ++ ContainerHelper.saveAllItems(nbt, this.getItemStacks(), registries); // Paper - always save the items, table may still remain } - default void readChestVehicleSaveData(CompoundTag nbt, HolderLookup.Provider registriesLookup) { + default void readChestVehicleSaveData(CompoundTag nbt, HolderLookup.Provider registries) { this.clearItemStacks(); if (nbt.contains("LootTable", 8)) { - this.setLootTable(ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(nbt.getString("LootTable")))); + this.setContainerLootTable(ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(nbt.getString("LootTable")))); + // Paper start - LootTable API + if (this.getLootTable() != null) { + this.lootableData().loadNbt(nbt); + } + // Paper end - LootTable API - this.setLootTableSeed(nbt.getLong("LootTableSeed")); + this.setContainerLootTableSeed(nbt.getLong("LootTableSeed")); - } else { -- ContainerHelper.loadAllItems(nbt, this.getItemStacks(), registriesLookup); +- ContainerHelper.loadAllItems(nbt, this.getItemStacks(), registries); } -+ ContainerHelper.loadAllItems(nbt, this.getItemStacks(), registriesLookup); // Paper - always save the items, table may still remain ++ ContainerHelper.loadAllItems(nbt, this.getItemStacks(), registries); // Paper - always save the items, table may still remain } - default void chestVehicleDestroyed(DamageSource source, Level world, Entity vehicle) { -@@ -99,13 +103,17 @@ public interface ContainerEntity extends Container, MenuProvider { + default void chestVehicleDestroyed(DamageSource source, ServerLevel world, Entity vehicle) { +@@ -97,13 +101,18 @@ public interface ContainerEntity extends Container, MenuProvider { default void unpackChestVehicleLootTable(@Nullable Player player) { MinecraftServer minecraftServer = this.level().getServer(); -- if (this.getLootTable() != null && minecraftServer != null) { +- if (this.getContainerLootTable() != null && minecraftServer != null) { + if (minecraftServer != null && this.lootableData().shouldReplenish(this, com.destroystokyo.paper.loottable.PaperLootableInventoryData.ENTITY, player)) { // Paper - LootTable API - LootTable lootTable = minecraftServer.reloadableRegistries().getLootTable(this.getLootTable()); + LootTable lootTable = minecraftServer.reloadableRegistries().getLootTable(this.getContainerLootTable()); if (player != null) { - CriteriaTriggers.GENERATE_LOOT.trigger((ServerPlayer)player, this.getLootTable()); + CriteriaTriggers.GENERATE_LOOT.trigger((ServerPlayer)player, this.getContainerLootTable()); } -- this.setLootTable(null); +- this.setContainerLootTable(null); + // Paper start - LootTable API + if (this.lootableData().shouldClearLootTable(this, com.destroystokyo.paper.loottable.PaperLootableInventoryData.ENTITY, player)) { -+ this.setLootTable(null); ++ this.setContainerLootTable(null); + } + // Paper end - LootTable API ++ LootParams.Builder builder = new LootParams.Builder((ServerLevel)this.level()).withParameter(LootContextParams.ORIGIN, this.position()); if (player != null) { builder.withLuck(player.getLuck()).withParameter(LootContextParams.THIS_ENTITY, player); -@@ -175,4 +183,14 @@ public interface ContainerEntity extends Container, MenuProvider { +@@ -173,4 +182,14 @@ public interface ContainerEntity extends Container, MenuProvider { default boolean isChestVehicleStillValid(Player player) { return !this.isRemoved() && player.canInteractWithEntity(this.getBoundingBox(), 4.0); } @@ -726,10 +727,10 @@ index 3ee99193de5deb6a38d6ded561fe8f2fbf711327..ccc7367ab2740bea0f2b907223a0920b + // Paper end - LootTable API } diff --git a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java -index d85da0661096a3587917c6636728bfd2e3eb90a2..6323c96d9b0cd14f89609b38da37d7fcc12d211b 100644 +index 5fd4594c26ef13ddef79cc4d4c8b446fdd3ba1f1..a0607cb6c6f74285363dfbd49033a8bde5ca6ae3 100644 --- a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java -@@ -148,7 +148,7 @@ public class ShulkerBoxBlock extends BaseEntityBlock { +@@ -143,7 +143,7 @@ public class ShulkerBoxBlock extends BaseEntityBlock { itemEntity.setDefaultPickUpDelay(); world.addFreshEntity(itemEntity); } else { @@ -738,7 +739,7 @@ index d85da0661096a3587917c6636728bfd2e3eb90a2..6323c96d9b0cd14f89609b38da37d7fc } } -@@ -158,7 +158,15 @@ public class ShulkerBoxBlock extends BaseEntityBlock { +@@ -153,7 +153,15 @@ public class ShulkerBoxBlock extends BaseEntityBlock { @Override protected List getDrops(BlockState state, LootParams.Builder builder) { BlockEntity blockEntity = builder.getOptionalParameter(LootContextParams.BLOCK_ENTITY); @@ -754,7 +755,7 @@ index d85da0661096a3587917c6636728bfd2e3eb90a2..6323c96d9b0cd14f89609b38da37d7fc builder = builder.withDynamicDrop(CONTENTS, lootConsumer -> { for (int i = 0; i < shulkerBoxBlockEntity.getContainerSize(); i++) { lootConsumer.accept(shulkerBoxBlockEntity.getItem(i)); -@@ -166,7 +174,13 @@ public class ShulkerBoxBlock extends BaseEntityBlock { +@@ -161,7 +169,13 @@ public class ShulkerBoxBlock extends BaseEntityBlock { }); } @@ -769,7 +770,7 @@ index d85da0661096a3587917c6636728bfd2e3eb90a2..6323c96d9b0cd14f89609b38da37d7fc @Override diff --git a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java -index c2493c15d8fe4587d6ee2db100cc13303b66b39b..13c9a68b604d4c7c6e09e72b3cea7ab2214b06ab 100644 +index 74c833e589160f0fe31f3b5e515f3515201159bd..fc657b6052d4310ad9c28988042c2cf37cf5d213 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java @@ -115,4 +115,13 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc @@ -850,20 +851,20 @@ index 74315a46f6101775321b1cf4944c124c69aed182..f23fbb8ed39a754b36d2eb162358877e @Override public abstract CraftLootable copy(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftChestBoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftChestBoat.java -index cfde210ea9d4b62fe514d3ab0dbab2f43eda0c7a..e4f899a6a1d055b3ea17d1114ed0228fbba53352 100644 +index 62accb551344c41671fc22b15d7b25b6fc97d915..a1e04bb965f18ffd07e2f5bf827c5e4ddd6aeeda 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftChestBoat.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftChestBoat.java @@ -7,8 +7,7 @@ import org.bukkit.craftbukkit.inventory.CraftInventory; import org.bukkit.inventory.Inventory; import org.bukkit.loot.LootTable; --public class CraftChestBoat extends CraftBoat implements org.bukkit.entity.ChestBoat { +-public abstract class CraftChestBoat extends CraftBoat implements org.bukkit.entity.ChestBoat { - -+public class CraftChestBoat extends CraftBoat implements org.bukkit.entity.ChestBoat, com.destroystokyo.paper.loottable.PaperLootableEntityInventory { // Paper ++public abstract class CraftChestBoat extends CraftBoat implements org.bukkit.entity.ChestBoat, com.destroystokyo.paper.loottable.PaperLootableEntityInventory { // Paper private final Inventory inventory; - public CraftChestBoat(CraftServer server, ChestBoat entity) { -@@ -31,28 +30,5 @@ public class CraftChestBoat extends CraftBoat implements org.bukkit.entity.Chest + public CraftChestBoat(CraftServer server, AbstractChestBoat entity) { +@@ -31,28 +30,6 @@ public abstract class CraftChestBoat extends CraftBoat implements org.bukkit.ent return this.inventory; } @@ -871,10 +872,11 @@ index cfde210ea9d4b62fe514d3ab0dbab2f43eda0c7a..e4f899a6a1d055b3ea17d1114ed0228f - public void setLootTable(LootTable table) { - this.setLootTable(table, this.getSeed()); - } -- ++ // Paper - moved loot table logic to PaperLootableEntityInventory + - @Override - public LootTable getLootTable() { -- return CraftLootTable.minecraftToBukkit(this.getHandle().getLootTable()); +- return CraftLootTable.minecraftToBukkit(this.getHandle().getContainerLootTable()); - } - - @Override @@ -884,14 +886,13 @@ index cfde210ea9d4b62fe514d3ab0dbab2f43eda0c7a..e4f899a6a1d055b3ea17d1114ed0228f - - @Override - public long getSeed() { -- return this.getHandle().getLootTableSeed(); +- return this.getHandle().getContainerLootTableSeed(); - } - - private void setLootTable(LootTable table, long seed) { -- this.getHandle().setLootTable(CraftLootTable.bukkitToMinecraft(table)); -- this.getHandle().setLootTableSeed(seed); +- this.getHandle().setContainerLootTable(CraftLootTable.bukkitToMinecraft(table)); +- this.getHandle().setContainerLootTableSeed(seed); - } -+ // Paper - moved loot table logic to PaperLootableEntityInventory } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java index fd42f0b20132d08039ca7735d31a61806a6b07dc..b1a708de6790bbe336202b13ab862ced78de084f 100644 diff --git a/patches/unapplied/server/0096-System-property-for-disabling-watchdoge.patch b/patches/server/0096-System-property-for-disabling-watchdoge.patch similarity index 100% rename from patches/unapplied/server/0096-System-property-for-disabling-watchdoge.patch rename to patches/server/0096-System-property-for-disabling-watchdoge.patch diff --git a/patches/unapplied/server/0097-Async-GameProfileCache-saving.patch b/patches/server/0097-Async-GameProfileCache-saving.patch similarity index 89% rename from patches/unapplied/server/0097-Async-GameProfileCache-saving.patch rename to patches/server/0097-Async-GameProfileCache-saving.patch index b2368721938c..5db06bd67873 100644 --- a/patches/unapplied/server/0097-Async-GameProfileCache-saving.patch +++ b/patches/server/0097-Async-GameProfileCache-saving.patch @@ -5,10 +5,10 @@ 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 f16ade2019e58a9374a550f58113313c118c2f2b..10d69b48158460e5739d1e41a83fcaeec819fac6 100644 +index fe59a95cf4f9750ce6ea8bbc98622ee42e37148a..23bf747bf268bd1100d8eadb81751ce72ef927ed 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -998,7 +998,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0 && ++this.level().spigotConfig.currentPrimedTnt > this.level().spigotConfig.maxTntTicksPerTick) { return; } // Spigot ++ if (this.level().spigotConfig.maxTntTicksPerTick > 0 && ++this.level().spigotConfig.currentPrimedTnt > this.level().spigotConfig.maxTntTicksPerTick) { ++ return; ++ } // Spigot + this.handlePortal(); + this.applyGravity(); + this.move(MoverType.SELF, this.getDeltaMovement()); +@@ -135,6 +137,27 @@ public class PrimedTnt extends Entity implements TraceableEntity { } } @@ -19,7 +30,7 @@ index 15432b512fc0d0d38bf28499e2afa5e48fec7aaa..47f2a480f6a4b15e55cedbfa8a58459d + */ + // Send position and velocity updates to nearby players on every tick while the TNT is in water. + // This does pretty well at keeping their clients in sync with the server. -+ net.minecraft.server.level.ChunkMap.TrackedEntity ete = ((net.minecraft.server.level.ServerLevel)this.level()).getChunkSource().chunkMap.entityMap.get(this.getId()); ++ net.minecraft.server.level.ChunkMap.TrackedEntity ete = ((net.minecraft.server.level.ServerLevel) this.level()).getChunkSource().chunkMap.entityMap.get(this.getId()); + if (ete != null) { + net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket velocityPacket = new net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket(this); + net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket positionPacket = new net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket(this); @@ -36,15 +47,16 @@ index 15432b512fc0d0d38bf28499e2afa5e48fec7aaa..47f2a480f6a4b15e55cedbfa8a58459d } private void explode() { -@@ -202,4 +223,11 @@ public class PrimedTnt extends Entity implements TraceableEntity { - +@@ -217,8 +240,10 @@ public class PrimedTnt extends Entity implements TraceableEntity { return entity; } -+ + + // Paper start - Option to prevent TNT from moving in water -+ @Override + @Override +- public final boolean hurtServer(ServerLevel world, DamageSource source, float amount) { +- return false; + public boolean isPushedByFluid() { + return !level().paperConfig().fixes.preventTntFromMovingInWater && super.isPushedByFluid(); -+ } + } + // Paper end - Option to prevent TNT from moving in water } diff --git a/patches/unapplied/server/0099-Faster-redstone-torch-rapid-clock-removal.patch b/patches/server/0099-Faster-redstone-torch-rapid-clock-removal.patch similarity index 86% rename from patches/unapplied/server/0099-Faster-redstone-torch-rapid-clock-removal.patch rename to patches/server/0099-Faster-redstone-torch-rapid-clock-removal.patch index 18322dc88fce..8316a2f0e549 100644 --- a/patches/unapplied/server/0099-Faster-redstone-torch-rapid-clock-removal.patch +++ b/patches/server/0099-Faster-redstone-torch-rapid-clock-removal.patch @@ -6,22 +6,22 @@ Subject: [PATCH] Faster redstone torch rapid clock removal Only resize the the redstone torch list once, since resizing arrays / lists is costly diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 622ecc1aeb9140d5c0d181fa472d123c42e5c5f4..4abb586f964e342425c7cf0384ab8bf8cdedaea3 100644 +index 9ad531912c4298658915b45b2870539059e8aadd..529b6eccb634f1f4677118c48e174b42eead2c0b 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -169,6 +169,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -170,6 +170,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { private org.spigotmc.TickLimiter tileLimiter; private int tileTickPosition; - public final Map explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions + public final Map explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions + public java.util.ArrayDeque redstoneUpdateInfos; // Paper - Faster redstone torch rapid clock removal; Move from Map in BlockRedstoneTorch to here public CraftWorld getWorld() { return this.world; diff --git a/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java b/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java -index 20d20db2639030c103e9d1b3c8da0f51344b81c2..ceba9617748a8b4f3a9bd459475952c9c6c9ed7c 100644 +index ca09910f87b69f6a4af7e3d9da4ad8f917acd66f..26319e8247e9dfa2068700d7fadc21ea5f715561 100644 --- a/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java +++ b/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java -@@ -24,7 +24,7 @@ public class RedstoneTorchBlock extends BaseTorchBlock { +@@ -28,7 +28,7 @@ public class RedstoneTorchBlock extends BaseTorchBlock { public static final MapCodec CODEC = simpleCodec(RedstoneTorchBlock::new); public static final BooleanProperty LIT = BlockStateProperties.LIT; @@ -30,7 +30,7 @@ index 20d20db2639030c103e9d1b3c8da0f51344b81c2..ceba9617748a8b4f3a9bd459475952c9 public static final int RECENT_TOGGLE_TIMER = 60; public static final int MAX_RECENT_TOGGLES = 8; public static final int RESTART_DELAY = 160; -@@ -80,11 +80,15 @@ public class RedstoneTorchBlock extends BaseTorchBlock { +@@ -81,11 +81,15 @@ public class RedstoneTorchBlock extends BaseTorchBlock { @Override protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { boolean flag = this.hasNeighborSignal(world, pos, state); @@ -50,7 +50,7 @@ index 20d20db2639030c103e9d1b3c8da0f51344b81c2..ceba9617748a8b4f3a9bd459475952c9 // CraftBukkit start org.bukkit.plugin.PluginManager manager = world.getCraftServer().getPluginManager(); -@@ -160,9 +164,12 @@ public class RedstoneTorchBlock extends BaseTorchBlock { +@@ -161,9 +165,12 @@ public class RedstoneTorchBlock extends BaseTorchBlock { } private static boolean isToggledTooFrequently(Level world, BlockPos pos, boolean addNew) { diff --git a/patches/unapplied/server/0100-Add-server-name-parameter.patch b/patches/server/0100-Add-server-name-parameter.patch similarity index 90% rename from patches/unapplied/server/0100-Add-server-name-parameter.patch rename to patches/server/0100-Add-server-name-parameter.patch index 5ff9f1d96102..32b0259d08d2 100644 --- a/patches/unapplied/server/0100-Add-server-name-parameter.patch +++ b/patches/server/0100-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 14f63c179428bee61d3b931ea309f4c94b89a6cc..75a3c7ed5500f0451c9c1efdfc3cb809445c8acf 100644 +index 13f811173c67533ee02f70cc4b6b398cd527c84b..fc9e56427dc04a6ef7286bf027fef6b7ff0bac0c 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -168,6 +168,14 @@ public class Main { diff --git a/patches/unapplied/server/0042-Fix-lag-from-explosions-processing-dead-entities.patch b/patches/unapplied/server/0042-Fix-lag-from-explosions-processing-dead-entities.patch deleted file mode 100644 index ae3fb7c15b5d..000000000000 --- a/patches/unapplied/server/0042-Fix-lag-from-explosions-processing-dead-entities.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Iceee -Date: Wed, 2 Mar 2016 01:39:52 -0600 -Subject: [PATCH] Fix lag from explosions processing dead entities - - -diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index 4a30928cd11f528f8ac06950b8052ebb7f2dd33c..458020575050284544761ec61c52abac7bfd15be 100644 ---- a/src/main/java/net/minecraft/world/level/Explosion.java -+++ b/src/main/java/net/minecraft/world/level/Explosion.java -@@ -227,7 +227,7 @@ public class Explosion { - int i1 = Mth.floor(this.y + (double) f2 + 1.0D); - int j1 = Mth.floor(this.z - (double) f2 - 1.0D); - int k1 = Mth.floor(this.z + (double) f2 + 1.0D); -- List list = this.level.getEntities(this.source, new AABB((double) i, (double) l, (double) j1, (double) j, (double) i1, (double) k1)); -+ List list = this.level.getEntities(this.source, new AABB((double) i, (double) l, (double) j1, (double) j, (double) i1, (double) k1), (com.google.common.base.Predicate) entity -> entity.isAlive() && !entity.isSpectator()); // Paper - Fix lag from explosions processing dead entities - Vec3 vec3d = new Vec3(this.x, this.y, this.z); - Iterator iterator = list.iterator(); - From 6b27267fb7cab462298b0523846f633974775f53 Mon Sep 17 00:00:00 2001 From: Noah van der Aa Date: Tue, 22 Oct 2024 20:09:28 +0200 Subject: [PATCH 006/119] oops --- ...8-Optional-TNT-doesn-t-move-in-water.patch | 28 ++++++------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/patches/server/0098-Optional-TNT-doesn-t-move-in-water.patch b/patches/server/0098-Optional-TNT-doesn-t-move-in-water.patch index 2cc5fa672c7d..6c39d5db19f7 100644 --- a/patches/server/0098-Optional-TNT-doesn-t-move-in-water.patch +++ b/patches/server/0098-Optional-TNT-doesn-t-move-in-water.patch @@ -5,21 +5,10 @@ Subject: [PATCH] Optional TNT doesn't move in water diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -index 3d489fdc14b3e29bab63f330d5edbbc1d354382a..fb631a01e6560632d49d4f59d37ff3bf771da18a 100644 +index 3d489fdc14b3e29bab63f330d5edbbc1d354382a..f45a466120291103e4501276b3d8f97d79070360 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -@@ -101,7 +101,9 @@ public class PrimedTnt extends Entity implements TraceableEntity { - - @Override - public void tick() { -- if (this.level().spigotConfig.maxTntTicksPerTick > 0 && ++this.level().spigotConfig.currentPrimedTnt > this.level().spigotConfig.maxTntTicksPerTick) { return; } // Spigot -+ if (this.level().spigotConfig.maxTntTicksPerTick > 0 && ++this.level().spigotConfig.currentPrimedTnt > this.level().spigotConfig.maxTntTicksPerTick) { -+ return; -+ } // Spigot - this.handlePortal(); - this.applyGravity(); - this.move(MoverType.SELF, this.getDeltaMovement()); -@@ -135,6 +137,27 @@ public class PrimedTnt extends Entity implements TraceableEntity { +@@ -135,6 +135,27 @@ public class PrimedTnt extends Entity implements TraceableEntity { } } @@ -47,16 +36,15 @@ index 3d489fdc14b3e29bab63f330d5edbbc1d354382a..fb631a01e6560632d49d4f59d37ff3bf } private void explode() { -@@ -217,8 +240,10 @@ public class PrimedTnt extends Entity implements TraceableEntity { - return entity; +@@ -221,4 +242,11 @@ public class PrimedTnt extends Entity implements TraceableEntity { + public final boolean hurtServer(ServerLevel world, DamageSource source, float amount) { + return false; } - ++ + // Paper start - Option to prevent TNT from moving in water - @Override -- public final boolean hurtServer(ServerLevel world, DamageSource source, float amount) { -- return false; ++ @Override + public boolean isPushedByFluid() { + return !level().paperConfig().fixes.preventTntFromMovingInWater && super.isPushedByFluid(); - } ++ } + // Paper end - Option to prevent TNT from moving in water } From 152e82ceec622ab38be10cc4281cf4b36766023c Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Tue, 22 Oct 2024 22:00:33 +0200 Subject: [PATCH 007/119] Some work --- .../0101-Fix-global-sound-handling.patch | 81 +++++++------- ...blocking-on-Network-Manager-creation.patch | 0 ...e-profiles-that-have-no-UUID-and-no-.patch | 2 +- ...setting-for-proxy-online-mode-status.patch | 10 +- ...ptimise-BlockState-s-hashCode-equals.patch | 28 ++--- ...onfigurable-packet-in-spam-threshold.patch | 4 +- ...07-Configurable-flying-kick-messages.patch | 6 +- patches/server/0108-Add-EntityZapEvent.patch | 103 ++++++++++++++++++ ...-entity-nbt-data-from-falling-blocks.patch | 4 +- ...110-Cache-user-authenticator-threads.patch | 2 +- ...1-Allow-Reloading-of-Command-Aliases.patch | 4 +- ...2-Add-source-to-PlayerExpChangeEvent.patch | 8 +- .../0113-Add-ProjectileCollideEvent.patch | 6 +- ...vent-Pathfinding-out-of-World-Border.patch | 4 +- ...ize-Level.hasChunkAt-BlockPosition-Z.patch | 2 +- ...-Bound-Treasure-Maps-to-World-Border.patch | 4 +- ...figurable-Cartographer-Treasure-Maps.patch | 10 +- ...-to-control-if-armor-stands-can-move.patch | 10 +- .../0119-String-based-Action-Bar-API.patch | 4 +- ...20-Properly-fix-item-duplication-bug.patch | 8 +- .../server/0121-Firework-API-s.patch | 36 +++--- .../server/0108-Add-EntityZapEvent.patch | 48 -------- 22 files changed, 213 insertions(+), 171 deletions(-) rename patches/{unapplied => }/server/0101-Fix-global-sound-handling.patch (65%) rename patches/{unapplied => }/server/0102-Avoid-blocking-on-Network-Manager-creation.patch (100%) rename patches/{unapplied => }/server/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch (90%) rename patches/{unapplied => }/server/0104-Add-setting-for-proxy-online-mode-status.patch (91%) rename patches/{unapplied => }/server/0105-Optimise-BlockState-s-hashCode-equals.patch (61%) rename patches/{unapplied => }/server/0106-Configurable-packet-in-spam-threshold.patch (91%) rename patches/{unapplied => }/server/0107-Configurable-flying-kick-messages.patch (89%) create mode 100644 patches/server/0108-Add-EntityZapEvent.patch rename patches/{unapplied => }/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch (86%) rename patches/{unapplied => }/server/0110-Cache-user-authenticator-threads.patch (97%) rename patches/{unapplied => }/server/0111-Allow-Reloading-of-Command-Aliases.patch (90%) rename patches/{unapplied => }/server/0112-Add-source-to-PlayerExpChangeEvent.patch (87%) rename patches/{unapplied => }/server/0113-Add-ProjectileCollideEvent.patch (91%) rename patches/{unapplied => }/server/0114-Prevent-Pathfinding-out-of-World-Border.patch (91%) rename patches/{unapplied => }/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch (92%) rename patches/{unapplied => }/server/0116-Bound-Treasure-Maps-to-World-Border.patch (93%) rename patches/{unapplied => }/server/0117-Configurable-Cartographer-Treasure-Maps.patch (89%) rename patches/{unapplied => }/server/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch (82%) rename patches/{unapplied => }/server/0119-String-based-Action-Bar-API.patch (91%) rename patches/{unapplied => }/server/0120-Properly-fix-item-duplication-bug.patch (82%) rename patches/{unapplied => }/server/0121-Firework-API-s.patch (75%) delete mode 100644 patches/unapplied/server/0108-Add-EntityZapEvent.patch diff --git a/patches/unapplied/server/0101-Fix-global-sound-handling.patch b/patches/server/0101-Fix-global-sound-handling.patch similarity index 65% rename from patches/unapplied/server/0101-Fix-global-sound-handling.patch rename to patches/server/0101-Fix-global-sound-handling.patch index 8f4acbadadf7..68b8b9a1b89f 100644 --- a/patches/unapplied/server/0101-Fix-global-sound-handling.patch +++ b/patches/server/0101-Fix-global-sound-handling.patch @@ -11,10 +11,10 @@ Co-authored-by: lexikiq Co-authored-by: Aikar diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 223f8d9be5d73e296f5815db7123b95c3b345162..d728afbe1d6882f1ace4ead9d87f4b7d2af43ba2 100644 +index 8dc2b2d8ba32aefc11eb23054b902650fac76adf..21c3d771a3dd921767c2cba1e11583d015879ca9 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1322,7 +1322,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1335,7 +1335,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public void levelEvent(@Nullable Player player, int eventId, BlockPos pos, int data) { @@ -23,50 +23,68 @@ index 223f8d9be5d73e296f5815db7123b95c3b345162..d728afbe1d6882f1ace4ead9d87f4b7d } public int getLogicalHeight() { +@@ -2152,6 +2152,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + return this.serverLevelData.getGameRules(); + } + ++ // Paper start - respect global sound events gamerule ++ public List getPlayersForGlobalSoundGamerule() { ++ return this.getGameRules().getBoolean(GameRules.RULE_GLOBAL_SOUND_EVENTS) ? ((ServerLevel) this).getServer().getPlayerList().players : ((ServerLevel) this).players(); ++ } ++ ++ public double getGlobalSoundRangeSquared(java.util.function.Function rangeFunction) { ++ final double range = rangeFunction.apply(this.spigotConfig); ++ return range <= 0 ? 64.0 * 64.0 : range * range; // 64 is taken from default in ServerLevel#levelEvent ++ } ++ // Paper end - respect global sound events gamerule ++ + @Override + public CrashReportCategory fillReportDetails(CrashReport report) { + CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report); diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -index 0be5ae83d2fa86142e3404393729039c51ae0639..25a429a2d1725d562a28b9d07dba630cfe49d32a 100644 +index 2bb62325d30ac509583de50407ea21f562f6e74f..95d69e3ca1a9095dfb340e9be0ec322ab6c5eb5e 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -@@ -695,11 +695,12 @@ public class EnderDragon extends Mob implements Enemy { +@@ -666,11 +666,12 @@ public class EnderDragon extends Mob implements Enemy { // CraftBukkit start - Use relative location for far away sounds - // this.level().globalLevelEvent(1028, this.blockPosition(), 0); - int viewDistance = ((ServerLevel) this.level()).getCraftServer().getViewDistance() * 16; -- for (net.minecraft.server.level.ServerPlayer player : this.level().getServer().getPlayerList().players) { -+ for (net.minecraft.server.level.ServerPlayer player : this.level().getPlayersForGlobalSoundGamerule()) { // Paper - respect global sound events gamerule + // worldserver.globalLevelEvent(1028, this.blockPosition(), 0); + int viewDistance = worldserver.getCraftServer().getViewDistance() * 16; +- for (net.minecraft.server.level.ServerPlayer player : worldserver.getServer().getPlayerList().players) { ++ for (net.minecraft.server.level.ServerPlayer player : worldserver.getPlayersForGlobalSoundGamerule()) { // Paper - respect global sound events gamerule double deltaX = this.getX() - player.getX(); double deltaZ = this.getZ() - player.getZ(); double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; -- if ( this.level().spigotConfig.dragonDeathSoundRadius > 0 && distanceSquared > this.level().spigotConfig.dragonDeathSoundRadius * this.level().spigotConfig.dragonDeathSoundRadius ) continue; // Spigot -+ final double soundRadiusSquared = this.level().getGlobalSoundRangeSquared(config -> config.dragonDeathSoundRadius); // Paper - respect global sound events gamerule -+ if ( !this.level().getGameRules().getBoolean(GameRules.RULE_GLOBAL_SOUND_EVENTS) && distanceSquared > soundRadiusSquared ) continue; // Spigot // Paper - respect global sound events gamerule +- if ( worldserver.spigotConfig.dragonDeathSoundRadius > 0 && distanceSquared > worldserver.spigotConfig.dragonDeathSoundRadius * worldserver.spigotConfig.dragonDeathSoundRadius ) continue; // Spigot ++ final double soundRadiusSquared = worldserver.getGlobalSoundRangeSquared(config -> config.dragonDeathSoundRadius); // Paper - respect global sound events gamerule ++ if ( !worldserver.getGameRules().getBoolean(GameRules.RULE_GLOBAL_SOUND_EVENTS) && distanceSquared > soundRadiusSquared ) continue; // Spigot // Paper - respect global sound events gamerule if (distanceSquared > viewDistance * viewDistance) { double deltaLength = Math.sqrt(distanceSquared); double relativeX = player.getX() + (deltaX / deltaLength) * viewDistance; diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java -index d288bc209a0b0fdf2d73197a8e7d179e8e8c31e7..3ee24382ef3614ff0c5d5cdc614a41286ba4af5e 100644 +index 4c284ccd5b2eb05f487aba18e1daa0b59c3e8129..10c79cbc25383c0b65fb22a7347513134b7dee1d 100644 --- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java +++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java -@@ -278,11 +278,12 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -276,11 +276,12 @@ public class WitherBoss extends Monster implements RangedAttackMob { // CraftBukkit start - Use relative location for far away sounds - // this.level().globalLevelEvent(1023, new BlockPosition(this), 0); - int viewDistance = ((ServerLevel) this.level()).getCraftServer().getViewDistance() * 16; + // worldserver.globalLevelEvent(1023, new BlockPosition(this), 0); + int viewDistance = world.getCraftServer().getViewDistance() * 16; - for (ServerPlayer player : (List) MinecraftServer.getServer().getPlayerList().players) { -+ for (ServerPlayer player : this.level().getPlayersForGlobalSoundGamerule()) { // Paper - respect global sound events gamerule ++ for (ServerPlayer player : world.getPlayersForGlobalSoundGamerule()) { // Paper - respect global sound events gamerule double deltaX = this.getX() - player.getX(); double deltaZ = this.getZ() - player.getZ(); double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; -- if ( this.level().spigotConfig.witherSpawnSoundRadius > 0 && distanceSquared > this.level().spigotConfig.witherSpawnSoundRadius * this.level().spigotConfig.witherSpawnSoundRadius ) continue; // Spigot -+ final double soundRadiusSquared = this.level().getGlobalSoundRangeSquared(config -> config.witherSpawnSoundRadius); // Paper - respect global sound events gamerule -+ if ( !this.level().getGameRules().getBoolean(GameRules.RULE_GLOBAL_SOUND_EVENTS) && distanceSquared > soundRadiusSquared ) continue; // Spigot // Paper - respect global sound events gamerule +- if ( world.spigotConfig.witherSpawnSoundRadius > 0 && distanceSquared > world.spigotConfig.witherSpawnSoundRadius * world.spigotConfig.witherSpawnSoundRadius ) continue; // Spigot ++ final double soundRadiusSquared = world.getGlobalSoundRangeSquared(config -> config.witherSpawnSoundRadius); // Paper - respect global sound events gamerule ++ if ( !world.getGameRules().getBoolean(GameRules.RULE_GLOBAL_SOUND_EVENTS) && distanceSquared > soundRadiusSquared ) continue; // Spigot // Paper - respect global sound events gamerule if (distanceSquared > viewDistance * viewDistance) { double deltaLength = Math.sqrt(distanceSquared); double relativeX = player.getX() + (deltaX / deltaLength) * viewDistance; diff --git a/src/main/java/net/minecraft/world/item/EnderEyeItem.java b/src/main/java/net/minecraft/world/item/EnderEyeItem.java -index 0224a0e901f9430ef06c30432a7988149a67037d..391579b515c5a07066f82b33c4f9ef8ee1d05530 100644 +index 04fce5cc4350df81c7ea103b74b845313dd6cc37..770467bd319f8e2fdf3d713591368aa825cfa5ae 100644 --- a/src/main/java/net/minecraft/world/item/EnderEyeItem.java +++ b/src/main/java/net/minecraft/world/item/EnderEyeItem.java -@@ -67,11 +67,12 @@ public class EnderEyeItem extends Item { - // world.b(1038, blockposition1.c(1, 0, 1), 0); +@@ -66,11 +66,12 @@ public class EnderEyeItem extends Item { + // world.globalLevelEvent(1038, blockposition1.offset(1, 0, 1), 0); int viewDistance = world.getCraftServer().getViewDistance() * 16; BlockPos soundPos = blockposition1.offset(1, 0, 1); - for (ServerPlayer player : world.getServer().getPlayerList().players) { @@ -80,22 +98,3 @@ index 0224a0e901f9430ef06c30432a7988149a67037d..391579b515c5a07066f82b33c4f9ef8e if (distanceSquared > viewDistance * viewDistance) { double deltaLength = Math.sqrt(distanceSquared); double relativeX = player.getX() + (deltaX / deltaLength) * viewDistance; -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 240db0aae0b0e306c90bcc4a537c9afcb290acb3..59992bea10218e48397fa781f895d36e0e1df46e 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -1277,4 +1277,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - return this.id; - } - } -+ // Paper start - respect global sound events gamerule -+ public List getPlayersForGlobalSoundGamerule() { -+ return this.getGameRules().getBoolean(GameRules.RULE_GLOBAL_SOUND_EVENTS) ? ((ServerLevel) this).getServer().getPlayerList().players : ((ServerLevel) this).players(); -+ } -+ -+ public double getGlobalSoundRangeSquared(java.util.function.Function rangeFunction) { -+ final double range = rangeFunction.apply(this.spigotConfig); -+ return range <= 0 ? 64.0 * 64.0 : range * range; // 64 is taken from default in ServerLevel#levelEvent -+ } -+ // Paper end - respect global sound events gamerule - } diff --git a/patches/unapplied/server/0102-Avoid-blocking-on-Network-Manager-creation.patch b/patches/server/0102-Avoid-blocking-on-Network-Manager-creation.patch similarity index 100% rename from patches/unapplied/server/0102-Avoid-blocking-on-Network-Manager-creation.patch rename to patches/server/0102-Avoid-blocking-on-Network-Manager-creation.patch diff --git a/patches/unapplied/server/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch b/patches/server/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch similarity index 90% rename from patches/unapplied/server/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch rename to patches/server/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch index 82dc93463f67..d99e7ec08b84 100644 --- a/patches/unapplied/server/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch +++ b/patches/server/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Don't lookup game profiles that have no UUID and no name diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java -index 5b219b5eee0c5958b80093c9223feeed0dec830b..bc7143ad915f001726e8558c8ca4160f3f9ace68 100644 +index 197e2ec9f1445a8184d0dde0e9b02b39e3302b91..22ed1e67ccb358655fe74cd1b1e19415f4e5bdd7 100644 --- a/src/main/java/net/minecraft/server/players/GameProfileCache.java +++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java @@ -89,6 +89,7 @@ public class GameProfileCache { diff --git a/patches/unapplied/server/0104-Add-setting-for-proxy-online-mode-status.patch b/patches/server/0104-Add-setting-for-proxy-online-mode-status.patch similarity index 91% rename from patches/unapplied/server/0104-Add-setting-for-proxy-online-mode-status.patch rename to patches/server/0104-Add-setting-for-proxy-online-mode-status.patch index e08249957a39..8158eb6cc79e 100644 --- a/patches/unapplied/server/0104-Add-setting-for-proxy-online-mode-status.patch +++ b/patches/server/0104-Add-setting-for-proxy-online-mode-status.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add setting for proxy online mode status TODO: Add isProxyOnlineMode check to Metrics diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index c1f41dcf49c75c3d69485c0e1ec821205438ed1e..c466ec011d059b9960606ef2ee51ea3a3a65f8d0 100644 +index 07969f82a3df1b71bee275a99ef9170a4f9bbbb0..a5880be1ec88c70f7ee46225036b04dac87943d4 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -593,7 +593,11 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -575,7 +575,11 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface public boolean enforceSecureProfile() { DedicatedServerProperties dedicatedserverproperties = this.getProperties(); @@ -23,7 +23,7 @@ index c1f41dcf49c75c3d69485c0e1ec821205438ed1e..c466ec011d059b9960606ef2ee51ea3a @Override diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java -index bc7143ad915f001726e8558c8ca4160f3f9ace68..aeb0c7ce9b6f93dadd407dbdefba053568f2e2fe 100644 +index 22ed1e67ccb358655fe74cd1b1e19415f4e5bdd7..c89f4a885982f06823886c81fd386b8de029a3dd 100644 --- a/src/main/java/net/minecraft/server/players/GameProfileCache.java +++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java @@ -89,7 +89,8 @@ public class GameProfileCache { @@ -60,10 +60,10 @@ index a0b0614ac7d2009db5c6c10ab4a5f09dd447c635..653856d0b8dcf2baf4cc77a276f17c8c } 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 b7539a5f7bc20f20f3cd7fb30d87ab7ffc1133c3..b125872e57e15081d6f5a7b3e108f7633046b228 100644 +index e9e612581683b27f35c0ef7adaae8e8b7eb677ec..e04c3f623a316ac3a7b3700cfd5165e799bc0afc 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1888,7 +1888,7 @@ public final class CraftServer implements Server { +@@ -1892,7 +1892,7 @@ public final class CraftServer implements Server { if (result == null) { GameProfile profile = null; // Only fetch an online UUID in online mode diff --git a/patches/unapplied/server/0105-Optimise-BlockState-s-hashCode-equals.patch b/patches/server/0105-Optimise-BlockState-s-hashCode-equals.patch similarity index 61% rename from patches/unapplied/server/0105-Optimise-BlockState-s-hashCode-equals.patch rename to patches/server/0105-Optimise-BlockState-s-hashCode-equals.patch index 348097f8cebe..057a037d8969 100644 --- a/patches/unapplied/server/0105-Optimise-BlockState-s-hashCode-equals.patch +++ b/patches/server/0105-Optimise-BlockState-s-hashCode-equals.patch @@ -8,26 +8,12 @@ object identity checks safely. Use a simpler optimized hashcode -diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java -index ee2f1bff22fed14cda434173dc6286e4d4520822..b63116b333b6e06494091a82588acfb639bddb71 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java -+++ b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java -@@ -30,8 +30,7 @@ public class BooleanProperty extends Property { - return value.toString(); - } - -- @Override -- public boolean equals(Object object) { -+ public boolean equals_unused(Object object) { // Paper - Perf: Optimize hashCode/equals - if (this == object) { - return true; - } else { diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java -index f4d9856420a6e7e857fc9b9cb6182a54fe341568..3097298fe356df98967cf4bdeaaede69dfe8a441 100644 +index e0259a3f66248b011276b6bc5135c5fc96446640..85a197232be9377c0313ec00e8f935551e2c60e0 100644 --- a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java +++ b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java -@@ -44,8 +44,7 @@ public class EnumProperty & StringRepresentable> extends Prope - return value.getSerializedName(); +@@ -59,8 +59,7 @@ public final class EnumProperty & StringRepresentable> extends + return this.ordinalToIndex[enum_.ordinal()]; } - @Override @@ -37,10 +23,10 @@ index f4d9856420a6e7e857fc9b9cb6182a54fe341568..3097298fe356df98967cf4bdeaaede69 return true; } else { diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java -index 3c590d400032d8266de63aae301fedbd83d37a1d..3a850321a4bcc68058483b5fd53e829c425a68af 100644 +index 96798f09abe9676679bb25c74942810919e71924..55a87592a99105dbf57b26fb6ccba695295fce24 100644 --- a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java +++ b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java -@@ -35,8 +35,7 @@ public class IntegerProperty extends Property { +@@ -28,8 +28,7 @@ public final class IntegerProperty extends Property { return this.values; } @@ -51,10 +37,10 @@ index 3c590d400032d8266de63aae301fedbd83d37a1d..3a850321a4bcc68058483b5fd53e829c return true; } else { diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java -index 7cbc5e6e75f389f47ef07045f9876cec192f14e4..9055f15af0cae55effa6942913a9d7edf3857e07 100644 +index e2bf1055d9ee09c29884505112ccc748cc049bfc..fcf04c5c58ff35d38c5bf0df562ae2f8dc98a0ee 100644 --- a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java +++ b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java -@@ -70,7 +70,7 @@ public abstract class Property> { +@@ -72,7 +72,7 @@ public abstract class Property> { @Override public boolean equals(Object object) { diff --git a/patches/unapplied/server/0106-Configurable-packet-in-spam-threshold.patch b/patches/server/0106-Configurable-packet-in-spam-threshold.patch similarity index 91% rename from patches/unapplied/server/0106-Configurable-packet-in-spam-threshold.patch rename to patches/server/0106-Configurable-packet-in-spam-threshold.patch index 65d911de77c1..dea882c5593c 100644 --- a/patches/unapplied/server/0106-Configurable-packet-in-spam-threshold.patch +++ b/patches/server/0106-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 14a821bfc6b20475889d3138b8da9e6bfaf1787c..905a7941597306b0cd23ec9a883ef3ee9a684788 100644 +index 0ddc79be416161d89c9f333ef79a16f079ba6e1d..9646788fc1313467e5a93f923109d412d6c44a77 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1534,13 +1534,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1537,13 +1537,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Spigot start - limit place/interactions private int limitedPackets; private long lastLimitedPacket = -1; diff --git a/patches/unapplied/server/0107-Configurable-flying-kick-messages.patch b/patches/server/0107-Configurable-flying-kick-messages.patch similarity index 89% rename from patches/unapplied/server/0107-Configurable-flying-kick-messages.patch rename to patches/server/0107-Configurable-flying-kick-messages.patch index 7a80c997cc37..e6b2f214c4cf 100644 --- a/patches/unapplied/server/0107-Configurable-flying-kick-messages.patch +++ b/patches/server/0107-Configurable-flying-kick-messages.patch @@ -5,10 +5,10 @@ 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 905a7941597306b0cd23ec9a883ef3ee9a684788..34aeb823950fac8eaef3f38b302c1585a45f7498 100644 +index 9646788fc1313467e5a93f923109d412d6c44a77..9289df9663a2dfbc28c2c6dd8c31bf516a6229ae 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -346,7 +346,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -353,7 +353,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (this.clientIsFloating && !this.player.isSleeping() && !this.player.isPassenger() && !this.player.isDeadOrDying()) { if (++this.aboveGroundTickCount > this.getMaximumFlyingTicks(this.player)) { ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked for floating too long!", this.player.getName().getString()); @@ -17,7 +17,7 @@ index 905a7941597306b0cd23ec9a883ef3ee9a684788..34aeb823950fac8eaef3f38b302c1585 return; } } else { -@@ -365,7 +365,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -372,7 +372,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (this.clientVehicleIsFloating && this.lastVehicle.getControllingPassenger() == this.player) { if (++this.aboveGroundVehicleTickCount > this.getMaximumFlyingTicks(this.lastVehicle)) { ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked for floating a vehicle too long!", this.player.getName().getString()); diff --git a/patches/server/0108-Add-EntityZapEvent.patch b/patches/server/0108-Add-EntityZapEvent.patch new file mode 100644 index 000000000000..c788e393ecf2 --- /dev/null +++ b/patches/server/0108-Add-EntityZapEvent.patch @@ -0,0 +1,103 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: AlphaBlend +Date: Sun, 16 Oct 2016 23:19:30 -0700 +Subject: [PATCH] Add EntityZapEvent + + +diff --git a/src/main/java/net/minecraft/world/entity/ConversionParams.java b/src/main/java/net/minecraft/world/entity/ConversionParams.java +index 3300104ad3e1f1e39cbe928ec6ad635e6ab76327..c18bc54721e90ed67312cd8baf52ccc8fe04d4cb 100644 +--- a/src/main/java/net/minecraft/world/entity/ConversionParams.java ++++ b/src/main/java/net/minecraft/world/entity/ConversionParams.java +@@ -12,4 +12,11 @@ public record ConversionParams(ConversionType type, boolean keepEquipment, boole + public interface AfterConversion { + void finalizeConversion(T convertedEntity); + } ++ ++ // Paper start - entity zap event - allow conversion to be cancelled during finalization ++ @FunctionalInterface ++ public interface CancellingAfterConversion { ++ boolean finalizeConversionOrCancel(final T convertedEntity); ++ } ++ // Paper start - entity zap event - allow conversion to be cancelled during finalization + } +diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java +index 9655466953cf850b82716246821a3ebb968a5478..03d289abc30927793aa00f6758ed9db6fb765999 100644 +--- a/src/main/java/net/minecraft/world/entity/Mob.java ++++ b/src/main/java/net/minecraft/world/entity/Mob.java +@@ -1498,6 +1498,12 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab + + @Nullable + public T convertTo(EntityType entitytypes, ConversionParams conversionparams, EntitySpawnReason entityspawnreason, ConversionParams.AfterConversion conversionparams_a, EntityTransformEvent.TransformReason transformReason, CreatureSpawnEvent.SpawnReason spawnReason) { ++ // Paper start - entity zap event - allow cancellation of conversion post creation ++ return this.convertTo(entitytypes, conversionparams, entityspawnreason, e -> { conversionparams_a.finalizeConversion(e); return true; }, transformReason, spawnReason); ++ } ++ @Nullable ++ public T convertTo(EntityType entitytypes, ConversionParams conversionparams, EntitySpawnReason entityspawnreason, ConversionParams.CancellingAfterConversion conversionparams_a, EntityTransformEvent.TransformReason transformReason, CreatureSpawnEvent.SpawnReason spawnReason) { ++ // Paper end - entity zap event - allow cancellation of conversion post creation + // CraftBukkit end + if (this.isRemoved()) { + return null; +@@ -1508,7 +1514,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab + return null; + } else { + conversionparams.type().convert(this, t0, conversionparams); +- conversionparams_a.finalizeConversion(t0); ++ if (!conversionparams_a.finalizeConversionOrCancel(t0)) return null; // Paper - entity zap event - return null if conversion was cancelled + Level world = this.level(); + + // CraftBukkit start +@@ -1544,6 +1550,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab + + @Nullable + public T convertTo(EntityType entitytypes, ConversionParams conversionparams, ConversionParams.AfterConversion conversionparams_a, EntityTransformEvent.TransformReason transformReason, CreatureSpawnEvent.SpawnReason spawnReason) { ++ // Paper start - entity zap event - allow cancellation of conversion post creation ++ return this.convertTo(entitytypes, conversionparams, e -> { conversionparams_a.finalizeConversion(e); return true; }, transformReason, spawnReason); ++ } ++ public T convertTo(EntityType entitytypes, ConversionParams conversionparams, ConversionParams.CancellingAfterConversion conversionparams_a, EntityTransformEvent.TransformReason transformReason, CreatureSpawnEvent.SpawnReason spawnReason) { ++ // Paper start - entity zap event - allow cancellation of conversion post creation + return this.convertTo(entitytypes, conversionparams, EntitySpawnReason.CONVERSION, conversionparams_a, transformReason, spawnReason); + // CraftBukkit end + } +diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java +index e52487a3537db6c7d6845f972355f8f437ea9156..624f06d630b55cdcaa97cb66736b69c7ad45dd83 100644 +--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java ++++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java +@@ -834,11 +834,18 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + @Override + public void thunderHit(ServerLevel world, LightningBolt lightning) { + if (world.getDifficulty() != Difficulty.PEACEFUL) { +- Villager.LOGGER.info("Villager {} was struck by lightning {}.", this, lightning); ++ // Paper - Add EntityZapEvent; move log down, event can cancel + Witch entitywitch = (Witch) this.convertTo(EntityType.WITCH, ConversionParams.single(this, false, false), (entitywitch1) -> { ++ // Paper start - Add EntityZapEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityZapEvent(this, lightning, entitywitch1).isCancelled()) { ++ return false; ++ } ++ if (org.spigotmc.SpigotConfig.logVillagerDeaths) Villager.LOGGER.info("Villager {} was struck by lightning {}.", this, lightning); // Move down ++ // Paper end - Add EntityZapEvent + entitywitch1.finalizeSpawn(world, world.getCurrentDifficultyAt(entitywitch1.blockPosition()), EntitySpawnReason.CONVERSION, (SpawnGroupData) null); + entitywitch1.setPersistenceRequired(); + this.releaseAllPois(); ++ return true; // Paper start - Add EntityZapEvent + }, EntityTransformEvent.TransformReason.LIGHTNING, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); // CraftBukkit + + if (entitywitch == null) { +diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +index 9100ea65e85a0e55cad736634fa63815366334a8..40c298cf4444e7f458cb99b81d64ee6d58a2f128 100644 +--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java ++++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +@@ -1215,6 +1215,14 @@ public class CraftEventFactory { + return !event.isCancelled(); + } + ++ // Paper start ++ public static com.destroystokyo.paper.event.entity.EntityZapEvent callEntityZapEvent(Entity entity, Entity lightning, Entity changedEntity) { ++ com.destroystokyo.paper.event.entity.EntityZapEvent event = new com.destroystokyo.paper.event.entity.EntityZapEvent(entity.getBukkitEntity(), (LightningStrike) lightning.getBukkitEntity(), changedEntity.getBukkitEntity()); ++ entity.getBukkitEntity().getServer().getPluginManager().callEvent(event); ++ return event; ++ } ++ // Paper end ++ + public static boolean callEntityChangeBlockEvent(Entity entity, BlockPos position, net.minecraft.world.level.block.state.BlockState newBlock) { + return CraftEventFactory.callEntityChangeBlockEvent(entity, position, newBlock, false); + } diff --git a/patches/unapplied/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch b/patches/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch similarity index 86% rename from patches/unapplied/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch rename to patches/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch index 00673bc0e766..55202f63eb4e 100644 --- a/patches/unapplied/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch +++ b/patches/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Filter bad block entity nbt data from falling blocks diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java -index c3a16691e8a843c02e0aea6469822cd8869ad593..01ac7bb0ef8ab13e7c4b5b56b768b7c0a642b300 100644 +index 5ed77cc6c8b0459691d8044232d9972e4278964b..84d9ae7be1bc9b2c4940cc69de24abf7e4c228b3 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java -@@ -340,7 +340,7 @@ public class FallingBlockEntity extends Entity { +@@ -356,7 +356,7 @@ public class FallingBlockEntity extends Entity { this.dropItem = nbt.getBoolean("DropItem"); } diff --git a/patches/unapplied/server/0110-Cache-user-authenticator-threads.patch b/patches/server/0110-Cache-user-authenticator-threads.patch similarity index 97% rename from patches/unapplied/server/0110-Cache-user-authenticator-threads.patch rename to patches/server/0110-Cache-user-authenticator-threads.patch index f16083a26ef9..471804336aec 100644 --- a/patches/unapplied/server/0110-Cache-user-authenticator-threads.patch +++ b/patches/server/0110-Cache-user-authenticator-threads.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Cache user authenticator threads diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index b2f7c76207f2dc0c62f608f21aba4b531f8f523f..e65c582635317b9f8a1af4e6f6a5fb916f73cc35 100644 +index 8cf3b9f1b7eef2d6278830e21ae012852687e02b..80ac468321a9ccb3486e97b3448dd3fccd8e766e 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -76,6 +76,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, diff --git a/patches/unapplied/server/0111-Allow-Reloading-of-Command-Aliases.patch b/patches/server/0111-Allow-Reloading-of-Command-Aliases.patch similarity index 90% rename from patches/unapplied/server/0111-Allow-Reloading-of-Command-Aliases.patch rename to patches/server/0111-Allow-Reloading-of-Command-Aliases.patch index 9bf9ad3da9e7..a4e93d3f78fd 100644 --- a/patches/unapplied/server/0111-Allow-Reloading-of-Command-Aliases.patch +++ b/patches/server/0111-Allow-Reloading-of-Command-Aliases.patch @@ -6,10 +6,10 @@ 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 b125872e57e15081d6f5a7b3e108f7633046b228..8e951ed126453cf1ffa81e5c8aa6e6ea5db03089 100644 +index e04c3f623a316ac3a7b3700cfd5165e799bc0afc..1f028c40dbe159f836e255ec52287903bca9fab8 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2818,5 +2818,24 @@ public final class CraftServer implements Server { +@@ -2835,5 +2835,24 @@ public final class CraftServer implements Server { DefaultPermissions.registerCorePermissions(); CraftDefaultPermissions.registerCorePermissions(); } diff --git a/patches/unapplied/server/0112-Add-source-to-PlayerExpChangeEvent.patch b/patches/server/0112-Add-source-to-PlayerExpChangeEvent.patch similarity index 87% rename from patches/unapplied/server/0112-Add-source-to-PlayerExpChangeEvent.patch rename to patches/server/0112-Add-source-to-PlayerExpChangeEvent.patch index 539523b8dd39..cb2ac725a281 100644 --- a/patches/unapplied/server/0112-Add-source-to-PlayerExpChangeEvent.patch +++ b/patches/server/0112-Add-source-to-PlayerExpChangeEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add source to PlayerExpChangeEvent diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -index 56402312e44d12c859e2c4b39902d31b7cfd1573..25a45e680f9fdea90f43d59de87a3a500f4ee8c0 100644 +index 8254f76a386bd6791b844a35b146370e817b09ad..7f3ac3e8631e30c968ef664f994ad208d05eb4a3 100644 --- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java +++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -@@ -264,7 +264,7 @@ public class ExperienceOrb extends Entity { +@@ -268,7 +268,7 @@ public class ExperienceOrb extends Entity { int i = this.repairPlayerItems(entityplayer, this.value); if (i > 0) { @@ -18,10 +18,10 @@ index 56402312e44d12c859e2c4b39902d31b7cfd1573..25a45e680f9fdea90f43d59de87a3a50 --this.count; diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 50f33c6029c190f947b6bf6215004416b034c0cc..d36e039aa5f1cf84179def5df5addaf448f54bd2 100644 +index 40c298cf4444e7f458cb99b81d64ee6d58a2f128..00267c18a1a6fba610b271770112a55efe732955 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1170,6 +1170,17 @@ public class CraftEventFactory { +@@ -1168,6 +1168,17 @@ public class CraftEventFactory { return event; } diff --git a/patches/unapplied/server/0113-Add-ProjectileCollideEvent.patch b/patches/server/0113-Add-ProjectileCollideEvent.patch similarity index 91% rename from patches/unapplied/server/0113-Add-ProjectileCollideEvent.patch rename to patches/server/0113-Add-ProjectileCollideEvent.patch index f2c7317621b9..2b0113c50b86 100644 --- a/patches/unapplied/server/0113-Add-ProjectileCollideEvent.patch +++ b/patches/server/0113-Add-ProjectileCollideEvent.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add ProjectileCollideEvent Deprecated now and replaced with ProjectileHitEvent diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index d36e039aa5f1cf84179def5df5addaf448f54bd2..91180d7ad705ca97c0df43debc14b204127165d0 100644 +index 00267c18a1a6fba610b271770112a55efe732955..0a3c89dba691760c7e0be58914003cc438269a03 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1323,6 +1323,16 @@ public class CraftEventFactory { +@@ -1321,6 +1321,16 @@ public class CraftEventFactory { Bukkit.getPluginManager().callEvent(crafterCraftEvent); return crafterCraftEvent; } @@ -26,7 +26,7 @@ index d36e039aa5f1cf84179def5df5addaf448f54bd2..91180d7ad705ca97c0df43debc14b204 public static ProjectileLaunchEvent callProjectileLaunchEvent(Entity entity) { Projectile bukkitEntity = (Projectile) entity.getBukkitEntity(); -@@ -1348,8 +1358,15 @@ public class CraftEventFactory { +@@ -1346,8 +1356,15 @@ public class CraftEventFactory { if (position.getType() == HitResult.Type.ENTITY) { hitEntity = ((EntityHitResult) position).getEntity().getBukkitEntity(); } diff --git a/patches/unapplied/server/0114-Prevent-Pathfinding-out-of-World-Border.patch b/patches/server/0114-Prevent-Pathfinding-out-of-World-Border.patch similarity index 91% rename from patches/unapplied/server/0114-Prevent-Pathfinding-out-of-World-Border.patch rename to patches/server/0114-Prevent-Pathfinding-out-of-World-Border.patch index ce3053228da4..21235871ad7a 100644 --- a/patches/unapplied/server/0114-Prevent-Pathfinding-out-of-World-Border.patch +++ b/patches/server/0114-Prevent-Pathfinding-out-of-World-Border.patch @@ -13,10 +13,10 @@ by adding code to all overrides in: to return BLOCKED if it is outside the world border. diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java -index 21bbc98b26b270b3ad6a3b34d6e50dfb796c3d5a..188904c9f0f81db1d63eec953d6746f2dc23dc81 100644 +index 1d5ce4caf99a3fb376b350968a6bd1ac8471ffec..436812c3bfe53358b4d76bb72d777d6661bb6d60 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java -@@ -158,7 +158,7 @@ public abstract class PathNavigation { +@@ -174,7 +174,7 @@ public abstract class PathNavigation { // Paper start - EntityPathfindEvent boolean copiedSet = false; for (BlockPos possibleTarget : positions) { diff --git a/patches/unapplied/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch b/patches/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch similarity index 92% rename from patches/unapplied/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch rename to patches/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch index ee46f05dc04c..2fc9b6d3419d 100644 --- a/patches/unapplied/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch +++ b/patches/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Optimize Level.hasChunkAt(BlockPosition)Z Reduce method invocations for World.isLoaded(BlockPosition)Z diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 008be3aad044d20be14da3a9e96933d265104587..03b0720c6ebf1a876d56d18a941e0a06ed26dbf0 100644 +index 529b6eccb634f1f4677118c48e174b42eead2c0b..658ceb9c43bb48f88596cd7270e276a369a3937e 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -342,6 +342,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { diff --git a/patches/unapplied/server/0116-Bound-Treasure-Maps-to-World-Border.patch b/patches/server/0116-Bound-Treasure-Maps-to-World-Border.patch similarity index 93% rename from patches/unapplied/server/0116-Bound-Treasure-Maps-to-World-Border.patch rename to patches/server/0116-Bound-Treasure-Maps-to-World-Border.patch index b4596cd20bfc..0444bae2bab0 100644 --- a/patches/unapplied/server/0116-Bound-Treasure-Maps-to-World-Border.patch +++ b/patches/server/0116-Bound-Treasure-Maps-to-World-Border.patch @@ -11,7 +11,7 @@ that is outside happens to be closer, but unreachable, yet another reachable one is in border that would of been missed. diff --git a/src/main/java/net/minecraft/world/level/border/WorldBorder.java b/src/main/java/net/minecraft/world/level/border/WorldBorder.java -index a3ba3a09378e3bd0517464130ad2c702b0b0165d..3442e33a1146318228c4727a2a5afde685f69bf7 100644 +index 5aa04c48e04c067a366383b252a7b713d85eaee9..b50090df116697a12f5498d65dd2e5d6d5297fb5 100644 --- a/src/main/java/net/minecraft/world/level/border/WorldBorder.java +++ b/src/main/java/net/minecraft/world/level/border/WorldBorder.java @@ -46,6 +46,18 @@ public class WorldBorder { @@ -34,7 +34,7 @@ index a3ba3a09378e3bd0517464130ad2c702b0b0165d..3442e33a1146318228c4727a2a5afde6 return this.isWithinBounds(box.minX, box.minZ, box.maxX - 9.999999747378752E-6D, box.maxZ - 9.999999747378752E-6D); } diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index a53fa9bebdd46939a710e46466ca9a350ecefb27..0a779632c9d11496fcfc147870fba2699d9cc274 100644 +index a84434a95dbe3c458f358d9824de87c503a8b1dc..115deba41ec48143570489e8494785a3a48cd789 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -222,6 +222,7 @@ public abstract class ChunkGenerator { diff --git a/patches/unapplied/server/0117-Configurable-Cartographer-Treasure-Maps.patch b/patches/server/0117-Configurable-Cartographer-Treasure-Maps.patch similarity index 89% rename from patches/unapplied/server/0117-Configurable-Cartographer-Treasure-Maps.patch rename to patches/server/0117-Configurable-Cartographer-Treasure-Maps.patch index a93dd268ae06..1ca587b32ee0 100644 --- a/patches/unapplied/server/0117-Configurable-Cartographer-Treasure-Maps.patch +++ b/patches/server/0117-Configurable-Cartographer-Treasure-Maps.patch @@ -9,10 +9,10 @@ Also allow turning off treasure maps all together as they can eat up Map ID's which are limited in quantity. diff --git a/src/main/java/net/minecraft/world/entity/npc/VillagerTrades.java b/src/main/java/net/minecraft/world/entity/npc/VillagerTrades.java -index 9358498491cd25ef760527ebd83188b76f8458f1..73a222d91dab1d5d1390b018f9537624aaff0798 100644 +index 914134d274c4a484c99bbe59521e30881c120799..a20c23db72f207b069f4ae0eb83ab6b6dca12072 100644 --- a/src/main/java/net/minecraft/world/entity/npc/VillagerTrades.java +++ b/src/main/java/net/minecraft/world/entity/npc/VillagerTrades.java -@@ -1828,7 +1828,8 @@ public class VillagerTrades { +@@ -1826,7 +1826,8 @@ public class VillagerTrades { return null; } else { ServerLevel serverLevel = (ServerLevel)entity.level(); @@ -23,11 +23,11 @@ index 9358498491cd25ef760527ebd83188b76f8458f1..73a222d91dab1d5d1390b018f9537624 ItemStack itemStack = MapItem.create(serverLevel, blockPos.getX(), blockPos.getZ(), (byte)2, true, true); MapItem.renderBiomePreviewMap(serverLevel, itemStack); diff --git a/src/main/java/net/minecraft/world/level/storage/loot/functions/ExplorationMapFunction.java b/src/main/java/net/minecraft/world/level/storage/loot/functions/ExplorationMapFunction.java -index e7f2cc799e7c50a9525845347a3f235f7bfefe41..709bc6838d20c420c5a4b3a994a041e594bd6210 100644 +index 4a4a692686159a295aeae94daa8e55bcaa503e0d..c30943031db0e72c8a412552d0706d4da9e9cebc 100644 --- a/src/main/java/net/minecraft/world/level/storage/loot/functions/ExplorationMapFunction.java +++ b/src/main/java/net/minecraft/world/level/storage/loot/functions/ExplorationMapFunction.java -@@ -84,8 +84,17 @@ public class ExplorationMapFunction extends LootItemConditionalFunction { - Vec3 vec3 = context.getParamOrNull(LootContextParams.ORIGIN); +@@ -83,8 +83,17 @@ public class ExplorationMapFunction extends LootItemConditionalFunction { + Vec3 vec3 = context.getOptionalParameter(LootContextParams.ORIGIN); if (vec3 != null) { ServerLevel serverLevel = context.getLevel(); + // Paper start - Configurable cartographer treasure maps diff --git a/patches/unapplied/server/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch b/patches/server/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch similarity index 82% rename from patches/unapplied/server/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch rename to patches/server/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch index ace73cb96950..e79a04b269a1 100644 --- a/patches/unapplied/server/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch +++ b/patches/server/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add API methods to control if armor stands can move diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -index af954b2c0c7106a231fb15172da3fa8e1d281d56..dae6835696e90bc5a541cacd37ea7aa88c60f4f4 100644 +index c3a4b967a73a1a04192850a6880d42ebd22c2a14..aea97a30a9226275f8fbf9cb2c15d5ddf36371ac 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -95,6 +95,7 @@ public class ArmorStand extends LivingEntity { +@@ -107,6 +107,7 @@ public class ArmorStand extends LivingEntity { public Rotations rightArmPose; public Rotations leftLegPose; public Rotations rightLegPose; @@ -16,7 +16,7 @@ index af954b2c0c7106a231fb15172da3fa8e1d281d56..dae6835696e90bc5a541cacd37ea7aa8 public ArmorStand(EntityType type, Level world) { super(type, world); -@@ -949,4 +950,13 @@ public class ArmorStand extends LivingEntity { +@@ -946,4 +947,13 @@ public class ArmorStand extends LivingEntity { public boolean canBeSeenByAnyone() { return !this.isInvisible() && !this.isMarker(); } @@ -31,12 +31,12 @@ index af954b2c0c7106a231fb15172da3fa8e1d281d56..dae6835696e90bc5a541cacd37ea7aa8 + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java -index 04a7735d278c9e610a33294e65a17796e120fe7e..52ffc401bbb9fa768534a4b871f9cc7dbebb8b20 100644 +index 9ed8d228729d067f21f34224458d141988845348..56fcd9dd40e6a63e1af5fbd470ece0d6100292a2 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java @@ -222,4 +222,15 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { public boolean hasEquipmentLock(EquipmentSlot equipmentSlot, LockType lockType) { - return (this.getHandle().disabledSlots & (1 << CraftEquipmentSlot.getNMS(equipmentSlot).getFilterFlag() + lockType.ordinal() * 8)) != 0; + return (this.getHandle().disabledSlots & (1 << CraftEquipmentSlot.getNMS(equipmentSlot).getFilterBit(lockType.ordinal() * 8))) != 0; } + // Paper start + @Override diff --git a/patches/unapplied/server/0119-String-based-Action-Bar-API.patch b/patches/server/0119-String-based-Action-Bar-API.patch similarity index 91% rename from patches/unapplied/server/0119-String-based-Action-Bar-API.patch rename to patches/server/0119-String-based-Action-Bar-API.patch index 31024a0f8e48..69c90a6791be 100644 --- a/patches/unapplied/server/0119-String-based-Action-Bar-API.patch +++ b/patches/server/0119-String-based-Action-Bar-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] String based Action Bar API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index cdcb2fb6229277872db36b6a4c439080f083f64c..258808bcb6f853c5679476305074823a7bb8b379 100644 +index ca6194580c10cc864430b859a2c60d0b2e6a9a16..5085da38a278d8f978e19a5b8df7a8e3d087d753 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -390,6 +390,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -391,6 +391,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper start diff --git a/patches/unapplied/server/0120-Properly-fix-item-duplication-bug.patch b/patches/server/0120-Properly-fix-item-duplication-bug.patch similarity index 82% rename from patches/unapplied/server/0120-Properly-fix-item-duplication-bug.patch rename to patches/server/0120-Properly-fix-item-duplication-bug.patch index 9fb45d2886f8..bfc6ea0e9e37 100644 --- a/patches/unapplied/server/0120-Properly-fix-item-duplication-bug.patch +++ b/patches/server/0120-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 984dc7f7f7315b8a8cdb9744ef8454a330888ba7..f067b10e13f01e751fc4ebf088740c7d40afcb99 100644 +index 78e4f07019e3231fbaa3f23bcdc8846e2d79ae18..5890aa22912eed9d645393f5a7189d6884fb2c66 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -2627,7 +2627,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2982,7 +2982,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { @Override public boolean isImmobile() { @@ -19,10 +19,10 @@ index 984dc7f7f7315b8a8cdb9744ef8454a330888ba7..f067b10e13f01e751fc4ebf088740c7d @Override diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 9bfdcdf427f7c0689d346d17942b5902a9138a4e..5f3b3f03936cfe23ed792c57d342a9932ea2e962 100644 +index d4527831f66bf1c55e6273c7f8923d6efbbf100f..04ada45eabd5a6c752c320cdff1a65c7ac83eb22 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -184,7 +184,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -191,7 +191,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } public final boolean isDisconnected() { diff --git a/patches/unapplied/server/0121-Firework-API-s.patch b/patches/server/0121-Firework-API-s.patch similarity index 75% rename from patches/unapplied/server/0121-Firework-API-s.patch rename to patches/server/0121-Firework-API-s.patch index c86538a2cf8b..5efca78eb3bf 100644 --- a/patches/unapplied/server/0121-Firework-API-s.patch +++ b/patches/server/0121-Firework-API-s.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Firework API's public net.minecraft.world.entity.projectile.FireworkRocketEntity attachedToEntity diff --git a/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java b/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java -index cc99d67bc52c89b50171b6c808c6e3bf293999f5..09d465947a5720e05c350d455c86002682104079 100644 +index e5d245c71ce2b2a1fe7f156e69831dec73354221..8a4e7e1c0c4919d2ee34121c14f9665b9ad95273 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java +++ b/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java -@@ -44,6 +44,7 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier { +@@ -45,6 +45,7 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier { public int lifetime; @Nullable public LivingEntity attachedToEntity; @@ -18,7 +18,7 @@ index cc99d67bc52c89b50171b6c808c6e3bf293999f5..09d465947a5720e05c350d455c860026 public FireworkRocketEntity(EntityType type, Level world) { super(type, world); -@@ -301,6 +302,11 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier { +@@ -324,6 +325,11 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier { nbt.putInt("LifeTime", this.lifetime); nbt.put("FireworksItem", this.getItem().save(this.registryAccess())); nbt.putBoolean("ShotAtAngle", (Boolean) this.entityData.get(FireworkRocketEntity.DATA_SHOT_AT_ANGLE)); @@ -30,7 +30,7 @@ index cc99d67bc52c89b50171b6c808c6e3bf293999f5..09d465947a5720e05c350d455c860026 } @Override -@@ -317,7 +323,11 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier { +@@ -340,7 +346,11 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier { if (nbt.contains("ShotAtAngle")) { this.entityData.set(FireworkRocketEntity.DATA_SHOT_AT_ANGLE, nbt.getBoolean("ShotAtAngle")); } @@ -44,10 +44,10 @@ index cc99d67bc52c89b50171b6c808c6e3bf293999f5..09d465947a5720e05c350d455c860026 private List getExplosions() { diff --git a/src/main/java/net/minecraft/world/item/CrossbowItem.java b/src/main/java/net/minecraft/world/item/CrossbowItem.java -index 99a39f05e7aeefa2ea4372159b4837d80963eabf..f64cdfac1fc1333845ea4ea5efb7922f0ae39619 100644 +index 40cae3332a18e3f7be890d2ba8014bfe3d2d1c0e..710181cf04563f06690eee5b46a5a0d84844ac29 100644 --- a/src/main/java/net/minecraft/world/item/CrossbowItem.java +++ b/src/main/java/net/minecraft/world/item/CrossbowItem.java -@@ -160,7 +160,11 @@ public class CrossbowItem extends ProjectileWeaponItem { +@@ -163,7 +163,11 @@ public class CrossbowItem extends ProjectileWeaponItem { @Override protected Projectile createProjectile(Level world, LivingEntity shooter, ItemStack weaponStack, ItemStack projectileStack, boolean critical) { if (projectileStack.is(Items.FIREWORK_ROCKET)) { @@ -61,25 +61,27 @@ index 99a39f05e7aeefa2ea4372159b4837d80963eabf..f64cdfac1fc1333845ea4ea5efb7922f Projectile projectile = super.createProjectile(world, shooter, weaponStack, projectileStack, critical); if (projectile instanceof AbstractArrow abstractArrow) { diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java -index da89ccaf91e2baa7caa15681c113bc283f40cd21..38b33eb92d21d0099285a304c6e064bbf56db4eb 100644 +index 100a66b9211429b5c32f9ed226c7ddafb9c7df81..3929cb76f1c98c0a22eb2ab64c2ed09805ffe448 100644 --- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java +++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java -@@ -42,6 +42,7 @@ public class FireworkRocketItem extends Item implements ProjectileItem { - vec3.z + (double)direction.getStepZ() * 0.15, - itemStack +@@ -43,7 +43,7 @@ public class FireworkRocketItem extends Item implements ProjectileItem { + itemStack + ), + serverLevel, +- itemStack ++ itemStack, f -> f.spawningEntity = context.getPlayer() == null ? null : context.getPlayer().getUUID() // Paper - firework api - assign spawning entity uuid ); -+ fireworkRocketEntity.spawningEntity = context.getPlayer() == null ? null : context.getPlayer().getUUID(); // Paper - level.addFreshEntity(fireworkRocketEntity); itemStack.shrink(1); } -@@ -55,6 +56,7 @@ public class FireworkRocketItem extends Item implements ProjectileItem { +@@ -56,7 +56,7 @@ public class FireworkRocketItem extends Item implements ProjectileItem { + if (user.isFallFlying()) { ItemStack itemStack = user.getItemInHand(hand); - if (!world.isClientSide) { - FireworkRocketEntity fireworkRocketEntity = new FireworkRocketEntity(world, itemStack, user); -+ fireworkRocketEntity.spawningEntity = user.getUUID(); // Paper - world.addFreshEntity(fireworkRocketEntity); + if (world instanceof ServerLevel serverLevel) { +- Projectile.spawnProjectile(new FireworkRocketEntity(world, itemStack, user), serverLevel, itemStack); ++ Projectile.spawnProjectile(new FireworkRocketEntity(world, itemStack, user), serverLevel, itemStack, f -> f.spawningEntity = user.getUUID()); // Paper - firework api - assign spawning entity uuid itemStack.consume(1, user); user.awardStat(Stats.ITEM_USED.get(this)); + } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java index 5ae87c370e47c545cef27a36e40da137e1ec656b..c9e15a9d82dee935293b2e7e233f5b9b2d822448 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java diff --git a/patches/unapplied/server/0108-Add-EntityZapEvent.patch b/patches/unapplied/server/0108-Add-EntityZapEvent.patch deleted file mode 100644 index cb6ab1da64c7..000000000000 --- a/patches/unapplied/server/0108-Add-EntityZapEvent.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AlphaBlend -Date: Sun, 16 Oct 2016 23:19:30 -0700 -Subject: [PATCH] Add EntityZapEvent - - -diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java -index 63c10be6eacd7108b8b4795d76bf624e0614440a..243eb1e54293c763a06febff551c051398d43535 100644 ---- a/src/main/java/net/minecraft/world/entity/npc/Villager.java -+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java -@@ -846,10 +846,17 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - @Override - public void thunderHit(ServerLevel world, LightningBolt lightning) { - if (world.getDifficulty() != Difficulty.PEACEFUL) { -- Villager.LOGGER.info("Villager {} was struck by lightning {}.", this, lightning); -+ // Paper - Add EntityZapEvent; move log down, event can cancel - Witch entitywitch = (Witch) EntityType.WITCH.create(world); - - if (entitywitch != null) { -+ // Paper start - Add EntityZapEvent -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityZapEvent(this, lightning, entitywitch).isCancelled()) { -+ return; -+ } -+ if (org.spigotmc.SpigotConfig.logVillagerDeaths) Villager.LOGGER.info("Villager {} was struck by lightning {}.", this, lightning); // Move down -+ // Paper end - Add EntityZapEvent -+ - entitywitch.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot()); - entitywitch.finalizeSpawn(world, world.getCurrentDifficultyAt(entitywitch.blockPosition()), MobSpawnType.CONVERSION, (SpawnGroupData) null); - entitywitch.setNoAi(this.isNoAi()); -diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 96e0fc5c8a018fd579f24529175decdac634cfa1..50f33c6029c190f947b6bf6215004416b034c0cc 100644 ---- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1217,6 +1217,14 @@ public class CraftEventFactory { - return !event.isCancelled(); - } - -+ // Paper start -+ public static com.destroystokyo.paper.event.entity.EntityZapEvent callEntityZapEvent(Entity entity, Entity lightning, Entity changedEntity) { -+ com.destroystokyo.paper.event.entity.EntityZapEvent event = new com.destroystokyo.paper.event.entity.EntityZapEvent(entity.getBukkitEntity(), (LightningStrike) lightning.getBukkitEntity(), changedEntity.getBukkitEntity()); -+ entity.getBukkitEntity().getServer().getPluginManager().callEvent(event); -+ return event; -+ } -+ // Paper end -+ - public static boolean callEntityChangeBlockEvent(Entity entity, BlockPos position, net.minecraft.world.level.block.state.BlockState newBlock) { - return CraftEventFactory.callEntityChangeBlockEvent(entity, position, newBlock, false); - } From 9e92fed7a2c0d0f46b714bec84c5bc4d46c83cfb Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Tue, 22 Oct 2024 22:38:26 +0200 Subject: [PATCH 008/119] More work? --- .../0122-PlayerTeleportEndGatewayEvent.patch | 24 +++++ ...rovide-E-TE-Chunk-count-stat-methods.patch | 8 +- .../0124-Enforce-Sync-Player-Saves.patch | 4 +- ...PI-for-Reason-Source-Triggering-play.patch | 98 +++++++++---------- .../server/0126-Cap-Entity-Collisions.patch | 8 +- ...e-CraftScheduler-Async-Task-Debugger.patch | 10 +- ...le-async-calls-to-restart-the-server.patch | 12 +-- ...ke-parrots-stay-on-shoulders-despite.patch | 8 +- ...n-option-to-prevent-player-names-fro.patch | 4 +- ...urable-option-to-disable-creeper-lin.patch | 4 +- .../server/0132-Item-canEntityPickup.patch | 24 ++--- ...PlayerPickupItemEvent-setFlyAtPlayer.patch | 8 +- .../0134-PlayerAttemptPickupItemEvent.patch | 4 +- ...-profile-lookups-to-worldgen-threads.patch | 20 ++-- .../server/0136-Basic-PlayerProfile-API.patch | 10 +- .../server/0137-Add-UnknownCommandEvent.patch | 18 ++-- .../0138-Shoulder-Entities-Release-API.patch | 31 +++--- .../0122-PlayerTeleportEndGatewayEvent.patch | 35 ------- 18 files changed, 158 insertions(+), 172 deletions(-) create mode 100644 patches/server/0122-PlayerTeleportEndGatewayEvent.patch rename patches/{unapplied => }/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch (91%) rename patches/{unapplied => }/server/0124-Enforce-Sync-Player-Saves.patch (87%) rename patches/{unapplied => }/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch (81%) rename patches/{unapplied => }/server/0126-Cap-Entity-Collisions.patch (86%) rename patches/{unapplied => }/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch (81%) rename patches/{unapplied => }/server/0128-Properly-handle-async-calls-to-restart-the-server.patch (96%) rename patches/{unapplied => }/server/0129-Add-option-to-make-parrots-stay-on-shoulders-despite.patch (88%) rename patches/{unapplied => }/server/0130-Add-configuration-option-to-prevent-player-names-fro.patch (83%) rename patches/{unapplied => }/server/0131-provide-a-configurable-option-to-disable-creeper-lin.patch (85%) rename patches/{unapplied => }/server/0132-Item-canEntityPickup.patch (70%) rename patches/{unapplied => }/server/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch (87%) rename patches/{unapplied => }/server/0134-PlayerAttemptPickupItemEvent.patch (91%) rename patches/{unapplied => }/server/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch (84%) rename patches/{unapplied => }/server/0136-Basic-PlayerProfile-API.patch (98%) rename patches/{unapplied => }/server/0137-Add-UnknownCommandEvent.patch (90%) rename patches/{unapplied => }/server/0138-Shoulder-Entities-Release-API.patch (73%) delete mode 100644 patches/unapplied/server/0122-PlayerTeleportEndGatewayEvent.patch diff --git a/patches/server/0122-PlayerTeleportEndGatewayEvent.patch b/patches/server/0122-PlayerTeleportEndGatewayEvent.patch new file mode 100644 index 000000000000..0c781b1e9def --- /dev/null +++ b/patches/server/0122-PlayerTeleportEndGatewayEvent.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sat, 31 Dec 2016 21:44:50 -0500 +Subject: [PATCH] PlayerTeleportEndGatewayEvent + +Allows you to access the Gateway being used in a teleport event +Fix the offset used for player teleportation + +diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java +index 5890aa22912eed9d645393f5a7189d6884fb2c66..b99bd43bf5185bed21fad7dac31baf1a30bdd1fe 100644 +--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java ++++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +@@ -1455,6 +1455,11 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { + PositionMoveRotation absolutePosition = PositionMoveRotation.calculateAbsolute(PositionMoveRotation.of(this), PositionMoveRotation.of(teleportTarget), teleportTarget.relatives()); + Location exit = (worldserver == null) ? null : CraftLocation.toBukkit(absolutePosition.position(), worldserver.getWorld(), absolutePosition.yRot(), absolutePosition.xRot()); + PlayerTeleportEvent tpEvent = new PlayerTeleportEvent(this.getBukkitEntity(), enter, exit, teleportTarget.cause()); ++ // Paper start - gateway-specific teleport event ++ if (this.portalProcess != null && this.portalProcess.isSamePortal(((net.minecraft.world.level.block.EndGatewayBlock) net.minecraft.world.level.block.Blocks.END_GATEWAY)) && this.serverLevel().getBlockEntity(this.portalProcess.getEntryPosition()) instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity theEndGatewayBlockEntity) { ++ tpEvent = new com.destroystokyo.paper.event.player.PlayerTeleportEndGatewayEvent(this.getBukkitEntity(), enter, exit, new org.bukkit.craftbukkit.block.CraftEndGateway(this.serverLevel().getWorld(), theEndGatewayBlockEntity)); ++ } ++ // Paper end - gateway-specific teleport event + Bukkit.getServer().getPluginManager().callEvent(tpEvent); + Location newExit = tpEvent.getTo(); + if (tpEvent.isCancelled() || newExit == null) { diff --git a/patches/unapplied/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch b/patches/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch similarity index 91% rename from patches/unapplied/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch rename to patches/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch index f1025e5537da..00007012a24c 100644 --- a/patches/unapplied/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch +++ b/patches/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch @@ -7,10 +7,10 @@ Provides counts without the ineffeciency of using .getEntities().size() which creates copy of the collections. diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 03b0720c6ebf1a876d56d18a941e0a06ed26dbf0..4fcbea7b8b12be10157da0c1f35c06e47c0334ad 100644 +index 658ceb9c43bb48f88596cd7270e276a369a3937e..b34663ba24a0925c7fe65b354f4029c51ecc3bd1 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -114,7 +114,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -116,7 +116,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public static final int TICKS_PER_DAY = 24000; public static final int MAX_ENTITY_SPAWN_Y = 20000000; public static final int MIN_ENTITY_SPAWN_Y = -20000000; @@ -20,10 +20,10 @@ index 03b0720c6ebf1a876d56d18a941e0a06ed26dbf0..4fcbea7b8b12be10157da0c1f35c06e4 private final List 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 4878a1b085a83dd4a8ffdc86250b8fb4fbac5192..1b7660a2d003bfb19ef80ba8066b6417f85328ec 100644 +index 274c9cc32d7f65456d184db7f61bc4b159f890f8..8cf4ecc5065ade18f0d13eaf0a786912ecb4dd08 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -164,6 +164,56 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -168,6 +168,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 diff --git a/patches/unapplied/server/0124-Enforce-Sync-Player-Saves.patch b/patches/server/0124-Enforce-Sync-Player-Saves.patch similarity index 87% rename from patches/unapplied/server/0124-Enforce-Sync-Player-Saves.patch rename to patches/server/0124-Enforce-Sync-Player-Saves.patch index 5211b4bc78e0..7278b203686e 100644 --- a/patches/unapplied/server/0124-Enforce-Sync-Player-Saves.patch +++ b/patches/server/0124-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 98862db2334508ee1a783aeabfb146751552a4d9..e17f4f3882ae77a67e8bfad04646f02c2bbb6669 100644 +index 04e25dba87cc1531898bdf9640d6da44ee3bf410..18d4ee1e1fb37848ac6587a0a68785be1851b1e8 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1029,11 +1029,13 @@ public abstract class PlayerList { +@@ -998,11 +998,13 @@ public abstract class PlayerList { } public void saveAll() { diff --git a/patches/unapplied/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch b/patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch similarity index 81% rename from patches/unapplied/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch rename to patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch index 1ec647cf88db..54243150fc94 100644 --- a/patches/unapplied/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch +++ b/patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch @@ -8,10 +8,10 @@ Adds lots of information about why this orb exists. Replaces isFromBottle() with logic that persists entity reloads too. diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index 99771070840a545537fe352bda1c4aaeedd638ca..2fab84c5e2dc4de39281956390588a9a71d02f68 100644 +index 0de7b8b8d2670c6ec50eb56348ca28a315b961e5..73b6aa34ad2579d79f388c5660cdfbef41a769f2 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -435,7 +435,7 @@ public class ServerPlayerGameMode { +@@ -433,7 +433,7 @@ public class ServerPlayerGameMode { // Drop event experience if (flag && event != null) { @@ -21,7 +21,7 @@ index 99771070840a545537fe352bda1c4aaeedd638ca..2fab84c5e2dc4de39281956390588a9a return true; diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -index 25a45e680f9fdea90f43d59de87a3a500f4ee8c0..0330a62a6a0060d2a96de191db68774588fc7ae5 100644 +index 7f3ac3e8631e30c968ef664f994ad208d05eb4a3..b9160ebca0d11dbbf96da5f0f5810d302cfcea9a 100644 --- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java +++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java @@ -44,9 +44,63 @@ public class ExperienceOrb extends Entity { @@ -88,7 +88,7 @@ index 25a45e680f9fdea90f43d59de87a3a500f4ee8c0..0330a62a6a0060d2a96de191db687745 this.setPos(x, y, z); this.setYRot((float) (this.random.nextDouble() * 360.0D)); this.setDeltaMovement((this.random.nextDouble() * 0.20000000298023224D - 0.10000000149011612D) * 2.0D, this.random.nextDouble() * 0.2D * 2.0D, (this.random.nextDouble() * 0.20000000298023224D - 0.10000000149011612D) * 2.0D); -@@ -170,12 +224,20 @@ public class ExperienceOrb extends Entity { +@@ -171,12 +225,20 @@ public class ExperienceOrb extends Entity { } public static void award(ServerLevel world, Vec3 pos, int amount) { @@ -110,7 +110,7 @@ index 25a45e680f9fdea90f43d59de87a3a500f4ee8c0..0330a62a6a0060d2a96de191db687745 } } -@@ -245,6 +307,7 @@ public class ExperienceOrb extends Entity { +@@ -249,6 +311,7 @@ public class ExperienceOrb extends Entity { nbt.putShort("Age", (short) this.age); nbt.putShort("Value", (short) this.value); nbt.putInt("Count", this.count); @@ -118,7 +118,7 @@ index 25a45e680f9fdea90f43d59de87a3a500f4ee8c0..0330a62a6a0060d2a96de191db687745 } @Override -@@ -253,6 +316,7 @@ public class ExperienceOrb extends Entity { +@@ -257,6 +320,7 @@ public class ExperienceOrb extends Entity { this.age = nbt.getShort("Age"); this.value = nbt.getShort("Value"); this.count = Math.max(nbt.getInt("Count"), 1); @@ -127,23 +127,23 @@ index 25a45e680f9fdea90f43d59de87a3a500f4ee8c0..0330a62a6a0060d2a96de191db687745 @Override diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 16d611e09cbe56525cde0e0dced93b7f09c12158..b6a7c9ee6e6885e0cc44e2f2ff3ea7bba9cb8f3d 100644 +index 6ea3488a578a7464bd34df265742a777575c9029..237025be183b3cc93920430075edcc0bb2899b68 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1799,7 +1799,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - protected void dropExperience(@Nullable Entity attacker) { +@@ -1837,7 +1837,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + protected void dropExperience(ServerLevel world, @Nullable Entity attacker) { // CraftBukkit start - Update getExpReward() above if the removed if() changes! if (!(this instanceof net.minecraft.world.entity.boss.enderdragon.EnderDragon)) { // CraftBukkit - SPIGOT-2420: Special case ender dragon will drop the xp over time -- ExperienceOrb.award((ServerLevel) this.level(), this.position(), this.expToDrop); -+ ExperienceOrb.award((ServerLevel) this.level(), this.position(), this.expToDrop, this instanceof ServerPlayer ? org.bukkit.entity.ExperienceOrb.SpawnReason.PLAYER_DEATH : org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, attacker, this); // Paper +- ExperienceOrb.award(world, this.position(), this.expToDrop); ++ ExperienceOrb.award(world, this.position(), this.expToDrop, this instanceof ServerPlayer ? org.bukkit.entity.ExperienceOrb.SpawnReason.PLAYER_DEATH : org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, attacker, this); // Paper this.expToDrop = 0; } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/animal/Animal.java b/src/main/java/net/minecraft/world/entity/animal/Animal.java -index 48d0cbe7859c62bbf281a7b43ef9af658667cb7b..b46352b328178df2a48d1c9e895bed3fabd2c292 100644 +index e359bb8e6366b0c695fe3bb14967556a875524f4..775bfac26aaa6db998c2647ec81247b67d0bf784 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Animal.java +++ b/src/main/java/net/minecraft/world/entity/animal/Animal.java -@@ -251,12 +251,14 @@ public abstract class Animal extends AgeableMob { +@@ -277,12 +277,14 @@ public abstract class Animal extends AgeableMob { public void finalizeSpawnChildFromBreeding(ServerLevel worldserver, Animal entityanimal, @Nullable AgeableMob entityageable, int experience) { // CraftBukkit end @@ -162,7 +162,7 @@ index 48d0cbe7859c62bbf281a7b43ef9af658667cb7b..b46352b328178df2a48d1c9e895bed3f this.setAge(6000); entityanimal.setAge(6000); this.resetLove(); -@@ -265,7 +267,7 @@ public abstract class Animal extends AgeableMob { +@@ -291,7 +293,7 @@ public abstract class Animal extends AgeableMob { if (worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // CraftBukkit start - use event experience if (experience > 0) { @@ -172,11 +172,11 @@ index 48d0cbe7859c62bbf281a7b43ef9af658667cb7b..b46352b328178df2a48d1c9e895bed3f // CraftBukkit end } diff --git a/src/main/java/net/minecraft/world/entity/animal/Fox.java b/src/main/java/net/minecraft/world/entity/animal/Fox.java -index de2a25db9465bc4ae3cbf7ff6d3af756df679f4a..a6788da1505f9e119c03b94488f5e006da13e918 100644 +index 258fad440d4d2402a273c761da57130a57202b3c..faffc3a9ed8bc306277cad37bc43af2ef7303493 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Fox.java +++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java -@@ -897,7 +897,7 @@ public class Fox extends Animal implements VariantHolder { - if (this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { +@@ -882,7 +882,7 @@ public class Fox extends Animal implements VariantHolder { + if (worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // CraftBukkit start - use event experience if (experience > 0) { - this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), experience)); @@ -185,45 +185,45 @@ index de2a25db9465bc4ae3cbf7ff6d3af756df679f4a..a6788da1505f9e119c03b94488f5e006 // CraftBukkit end } diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java -index d4659ce017692c6f8cabb56137a231bc566614b0..6f90ee749aed98b97868aa40fc233d164ddc2ef6 100644 +index 81982515b7757febb964627e9c5046d52bf5edf5..a2c5042e99a8f4cd45d502320cf1c06e8af0bd0e 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java +++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java -@@ -455,7 +455,7 @@ public class Turtle extends Animal { +@@ -462,7 +462,7 @@ public class Turtle extends Animal { RandomSource randomsource = this.animal.getRandom(); - if (this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { + if (getServerLevel((Level) this.level).getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { - this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), randomsource.nextInt(7) + 1)); + this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), randomsource.nextInt(7) + 1, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer)); // Paper; } } diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -index 25a429a2d1725d562a28b9d07dba630cfe49d32a..f8283405b3c5bd43746a5738be55f600beea40e3 100644 +index 95d69e3ca1a9095dfb340e9be0ec322ab6c5eb5e..0012ab1f56180081d210c8836e2a59d543b950b8 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -@@ -688,7 +688,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -659,7 +659,7 @@ public class EnderDragon extends Mob implements Enemy { - if (this.level() instanceof ServerLevel) { + if (world instanceof ServerLevel worldserver) { if (this.dragonDeathTime > 150 && this.dragonDeathTime % 5 == 0 && true) { // CraftBukkit - SPIGOT-2420: Already checked for the game rule when calculating the xp -- ExperienceOrb.award((ServerLevel) this.level(), this.position(), Mth.floor((float) short0 * 0.08F)); -+ ExperienceOrb.award((ServerLevel) this.level(), this.position(), Mth.floor((float) short0 * 0.08F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, this.lastHurtByPlayer, this); // Paper +- ExperienceOrb.award(worldserver, this.position(), Mth.floor((float) short0 * 0.08F)); ++ ExperienceOrb.award(worldserver, this.position(), Mth.floor((float) short0 * 0.08F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, this.lastHurtByPlayer, this); // Paper } if (this.dragonDeathTime == 1 && !this.isSilent()) { -@@ -717,7 +717,7 @@ public class EnderDragon extends Mob implements Enemy { - this.move(MoverType.SELF, new Vec3(0.0D, 0.10000000149011612D, 0.0D)); - if (this.dragonDeathTime == 200 && this.level() instanceof ServerLevel) { - if (true) { // CraftBukkit - SPIGOT-2420: Already checked for the game rule when calculating the xp -- ExperienceOrb.award((ServerLevel) this.level(), this.position(), Mth.floor((float) short0 * 0.2F)); -+ ExperienceOrb.award((ServerLevel) this.level(), this.position(), Mth.floor((float) short0 * 0.2F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, this.lastHurtByPlayer, this); // Paper - } +@@ -691,7 +691,7 @@ public class EnderDragon extends Mob implements Enemy { + if (world instanceof ServerLevel) { + ServerLevel worldserver = (ServerLevel) world; // CraftBukkit - decompile error + if (true) { // CraftBukkit - SPIGOT-2420: Already checked for the game rule when calculating the xp +- ExperienceOrb.award(worldserver, this.position(), Mth.floor((float) short0 * 0.2F)); ++ ExperienceOrb.award(worldserver, this.position(), Mth.floor((float) short0 * 0.2F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, this.lastHurtByPlayer, this); // Paper + } - if (this.dragonFight != null) { + if (this.dragonFight != null) { diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java -index 243eb1e54293c763a06febff551c051398d43535..79fdc8284f57a4f11e1954936ad574f7b8df5435 100644 +index 624f06d630b55cdcaa97cb66736b69c7ad45dd83..83bb48891d03534468d61cf7683438b3efb131cf 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java -@@ -634,7 +634,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -630,7 +630,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } if (offer.shouldRewardExp()) { @@ -233,10 +233,10 @@ index 243eb1e54293c763a06febff551c051398d43535..79fdc8284f57a4f11e1954936ad574f7 } diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java -index 0f2e2e42e732e942664d70a72dd9c4e47c7e95b6..e51cb9c96e1bd13c00bf938436f4fc26d80055a1 100644 +index 380a876b3cbd660b34dd504cd20f6031b35a613a..8034588a9a87b907c35e28e220280d463f34554e 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java -@@ -207,7 +207,7 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill +@@ -208,7 +208,7 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill if (offer.shouldRewardExp()) { int i = 3 + this.random.nextInt(4); @@ -246,10 +246,10 @@ index 0f2e2e42e732e942664d70a72dd9c4e47c7e95b6..e51cb9c96e1bd13c00bf938436f4fc26 } diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -index ed43ad94ca007a54e3c32d5e17c141048eeb5835..0b4c67b9de6893601f032a8fae103e8a98f2c767 100644 +index ed378bc8135c329cb7423da06eb26fff69ee4954..9d24d4c3802c525546dae92530c9c5b3cf77924e 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java +++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -@@ -525,7 +525,7 @@ public class FishingHook extends Projectile { +@@ -530,7 +530,7 @@ public class FishingHook extends Projectile { this.level().addFreshEntity(entityitem); // CraftBukkit start - this.random.nextInt(6) + 1 -> playerFishEvent.getExpToDrop() if (playerFishEvent.getExpToDrop() > 0) { @@ -259,10 +259,10 @@ index ed43ad94ca007a54e3c32d5e17c141048eeb5835..0b4c67b9de6893601f032a8fae103e8a // CraftBukkit end if (itemstack1.is(ItemTags.FISHES)) { diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java -index 9963db38420b91ae817a18ff084311cb45c0edee..70ceef96c6305324aef3b006f6603817ef187e9f 100644 +index 89292bd47e80f7c8bd6a382a44b912a43037b58e..268e46777bdea5b539b0c6833eee08ea8a6c61c2 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java -@@ -54,7 +54,7 @@ public class ThrownExperienceBottle extends ThrowableItemProjectile { +@@ -55,7 +55,7 @@ public class ThrownExperienceBottle extends ThrowableItemProjectile { } // CraftBukkit end @@ -272,7 +272,7 @@ index 9963db38420b91ae817a18ff084311cb45c0edee..70ceef96c6305324aef3b006f6603817 } diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java -index 1c0a9ca0ccfd89dd26736012ce1c329dffb7f913..637d77d6b07ff9ee5ac1cb0470cbefcba5c7495e 100644 +index 56d8ed71861b0a47692fde4c5acc97aaba8166da..13bc52bc856031c930370828b0381e43920aabd2 100644 --- a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java +++ b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java @@ -98,7 +98,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { @@ -285,10 +285,10 @@ index 1c0a9ca0ccfd89dd26736012ce1c329dffb7f913..637d77d6b07ff9ee5ac1cb0470cbefcb world.levelEvent(1042, blockposition, 0); diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index def3e28edc206e0ba41111e26332db468223fb2e..6d0a90e9c637edff5c5ce1355a3b45f0fb7f4154 100644 +index 3cefda12d4c2ca2c4e9ef97eff961a55af164d6b..43c2b411115d3a8a0e47d3e2277789b2667897af 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -360,8 +360,13 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -363,8 +363,13 @@ public class Block extends BlockBehaviour implements ItemLike { } public void popExperience(ServerLevel world, BlockPos pos, int size) { @@ -304,10 +304,10 @@ index def3e28edc206e0ba41111e26332db468223fb2e..6d0a90e9c637edff5c5ce1355a3b45f0 } diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index c0dea02bb38dffb5003293c2d91e28e998da0a9c..e2a587ca5b732c62c4956e6f39ad795cd1411cc4 100644 +index bddbb351ef676a86edb5da74a2a656c7da2ecb5d..62c49afd4da165d0cb4156f106e6e5480d267d4e 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -@@ -633,7 +633,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -517,7 +517,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit j = event.getExpToDrop(); // CraftBukkit end @@ -317,10 +317,10 @@ index c0dea02bb38dffb5003293c2d91e28e998da0a9c..e2a587ca5b732c62c4956e6f39ad795c @Override diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java -index 5b7bdf06ae6df1eeccb5a8da143745235f58e07e..9b2b0bbb1755b6be1c23cf56e29a68b0002fd755 100644 +index 3dc11c82e4ccdb57a5e7510bddc5247869075d3e..1c3aacda9242444c0c7bd92cb391e6fff963bb79 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java -@@ -372,7 +372,7 @@ public final class CraftEntityTypes { +@@ -426,7 +426,7 @@ public final class CraftEntityTypes { return item; })); register(new EntityTypeData<>(EntityType.EXPERIENCE_ORB, ExperienceOrb.class, CraftExperienceOrb::new, @@ -328,7 +328,7 @@ index 5b7bdf06ae6df1eeccb5a8da143745235f58e07e..9b2b0bbb1755b6be1c23cf56e29a68b0 + spawnData -> new net.minecraft.world.entity.ExperienceOrb(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), 0, org.bukkit.entity.ExperienceOrb.SpawnReason.CUSTOM, null, null) // Paper )); register(new EntityTypeData<>(EntityType.AREA_EFFECT_CLOUD, AreaEffectCloud.class, CraftAreaEffectCloud::new, spawnData -> new net.minecraft.world.entity.AreaEffectCloud(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z()))); - register(new EntityTypeData<>(EntityType.EGG, Egg.class, CraftEgg::new, spawnData -> new ThrownEgg(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z()))); + register(new EntityTypeData<>(EntityType.EGG, Egg.class, CraftEgg::new, spawnData -> new ThrownEgg(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), new net.minecraft.world.item.ItemStack(Items.EGG)))); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java index 9231511af4cba747594000364f0b8fceeeab4819..5a7d314ec0562e472f5dc45924a7b24841cff126 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java diff --git a/patches/unapplied/server/0126-Cap-Entity-Collisions.patch b/patches/server/0126-Cap-Entity-Collisions.patch similarity index 86% rename from patches/unapplied/server/0126-Cap-Entity-Collisions.patch rename to patches/server/0126-Cap-Entity-Collisions.patch index 8feda191fe79..c5acd9fe9a1f 100644 --- a/patches/unapplied/server/0126-Cap-Entity-Collisions.patch +++ b/patches/server/0126-Cap-Entity-Collisions.patch @@ -12,10 +12,10 @@ 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 bd17157631a74f80e3b5ce50bb1f681abe1dd6a7..46a21ed2408a42aafd16647e17e556730e799cbd 100644 +index 847fd720f11e89d906430c820bc92afe0454761d..b1b26e7c0f66f0697bcfe9eb045d45f31cd9ab06 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -401,6 +401,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -404,6 +404,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public long activatedTick = Integer.MIN_VALUE; public void inactiveTick() { } // Spigot end @@ -24,10 +24,10 @@ index bd17157631a74f80e3b5ce50bb1f681abe1dd6a7..46a21ed2408a42aafd16647e17e55673 @javax.annotation.Nullable private org.bukkit.util.Vector origin; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index b6a7c9ee6e6885e0cc44e2f2ff3ea7bba9cb8f3d..f297b2227d0793f44cb5770aa24a474ec7283b15 100644 +index 237025be183b3cc93920430075edcc0bb2899b68..f2f8fbc8a8cf32bcba0ad7ac9b6cdd75468e062a 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3502,10 +3502,12 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3642,10 +3642,12 @@ public abstract class LivingEntity extends Entity implements Attackable { } Iterator iterator1 = list.iterator(); diff --git a/patches/unapplied/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch b/patches/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch similarity index 81% rename from patches/unapplied/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch rename to patches/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch index eff18e42d8c7..8c7d283f779a 100644 --- a/patches/unapplied/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch +++ b/patches/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch @@ -9,15 +9,15 @@ One report of a suspected memory leak with the system. This adds additional overhead to asynchronous task dispatching diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -index cf9f04e005940f5dd7baf50435f3703fa7c2d4f0..f1145585eed18be0aa5c795a50589103fdc9cc2f 100644 +index 22ddc74d85efb4e80e6f06acdf93341a122804fc..0e7f402a7b841c5f6f5a4b699b7bb3d9f46b1af6 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java @@ -433,7 +433,7 @@ public class CraftScheduler implements BukkitScheduler { } this.parsePending(); } else { -- this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); -+ // this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); // Paper +- this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(this.currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); ++ // this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(this.currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); // Paper this.executor.execute(new com.destroystokyo.paper.ServerSchedulerReportingWrapper(task)); // Paper // We don't need to parse pending // (async tasks must live with race-conditions if they attempt to cancel between these few lines of code) @@ -25,8 +25,8 @@ index cf9f04e005940f5dd7baf50435f3703fa7c2d4f0..f1145585eed18be0aa5c795a50589103 this.pending.addAll(temp); temp.clear(); MinecraftTimings.bukkitSchedulerFinishTimer.stopTiming(); // Paper -- this.debugHead = this.debugHead.getNextHead(currentTick); -+ //this.debugHead = this.debugHead.getNextHead(currentTick); // Paper +- this.debugHead = this.debugHead.getNextHead(this.currentTick); ++ //this.debugHead = this.debugHead.getNextHead(this.currentTick); // Paper } private void addTask(final CraftTask task) { diff --git a/patches/unapplied/server/0128-Properly-handle-async-calls-to-restart-the-server.patch b/patches/server/0128-Properly-handle-async-calls-to-restart-the-server.patch similarity index 96% rename from patches/unapplied/server/0128-Properly-handle-async-calls-to-restart-the-server.patch rename to patches/server/0128-Properly-handle-async-calls-to-restart-the-server.patch index f9160abe0034..5744f3fde00e 100644 --- a/patches/unapplied/server/0128-Properly-handle-async-calls-to-restart-the-server.patch +++ b/patches/server/0128-Properly-handle-async-calls-to-restart-the-server.patch @@ -30,10 +30,10 @@ 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 10d69b48158460e5739d1e41a83fcaeec819fac6..5d03477919ce892f6dfb4b2304c03733e10e3721 100644 +index 23bf747bf268bd1100d8eadb81751ce72ef927ed..835bbd873ec04954024ae8649e6bc9a4557b11c5 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -242,6 +242,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop, ServerLevel> levels; private PlayerList playerList; private volatile boolean running; @@ -41,7 +41,7 @@ index 10d69b48158460e5739d1e41a83fcaeec819fac6..5d03477919ce892f6dfb4b2304c03733 private boolean stopped; private int tickCount; private int ticksUntilAutosave; -@@ -937,7 +938,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0.5F || this.isInWater()) || this.abilities.flying || this.isSleeping() || this.isInPowderSnow) { diff --git a/patches/unapplied/server/0130-Add-configuration-option-to-prevent-player-names-fro.patch b/patches/server/0130-Add-configuration-option-to-prevent-player-names-fro.patch similarity index 83% rename from patches/unapplied/server/0130-Add-configuration-option-to-prevent-player-names-fro.patch rename to patches/server/0130-Add-configuration-option-to-prevent-player-names-fro.patch index 84c423eeac72..af19ed2453fe 100644 --- a/patches/unapplied/server/0130-Add-configuration-option-to-prevent-player-names-fro.patch +++ b/patches/server/0130-Add-configuration-option-to-prevent-player-names-fro.patch @@ -6,10 +6,10 @@ 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 8e951ed126453cf1ffa81e5c8aa6e6ea5db03089..cfc59f1fb52dffb13fb214dd7c9cf71d40354ef0 100644 +index 1f028c40dbe159f836e255ec52287903bca9fab8..271f299823495fd92c49a1fbb04e1daa501fafb0 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2837,5 +2837,10 @@ public final class CraftServer implements Server { +@@ -2854,5 +2854,10 @@ public final class CraftServer implements Server { commandMap.registerServerAliases(); return true; } diff --git a/patches/unapplied/server/0131-provide-a-configurable-option-to-disable-creeper-lin.patch b/patches/server/0131-provide-a-configurable-option-to-disable-creeper-lin.patch similarity index 85% rename from patches/unapplied/server/0131-provide-a-configurable-option-to-disable-creeper-lin.patch rename to patches/server/0131-provide-a-configurable-option-to-disable-creeper-lin.patch index 8c1151fd1ba8..c55f4a428dc8 100644 --- a/patches/unapplied/server/0131-provide-a-configurable-option-to-disable-creeper-lin.patch +++ b/patches/server/0131-provide-a-configurable-option-to-disable-creeper-lin.patch @@ -6,10 +6,10 @@ Subject: [PATCH] provide a configurable option to disable creeper lingering 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 976de2547f654bec58f53a4eff54df5176e815aa..39486215ac080220a6018a35a8437092dbc8fe9d 100644 +index 71ea942d663a15a45c97b9b6d5c7519ec5a828d7..31405c3a95e8e8217a6efede1e4599c14583081f 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java +++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java -@@ -287,7 +287,7 @@ public class Creeper extends Monster implements PowerableMob { +@@ -287,7 +287,7 @@ public class Creeper extends Monster { private void spawnLingeringCloud() { Collection collection = this.getActiveEffects(); diff --git a/patches/unapplied/server/0132-Item-canEntityPickup.patch b/patches/server/0132-Item-canEntityPickup.patch similarity index 70% rename from patches/unapplied/server/0132-Item-canEntityPickup.patch rename to patches/server/0132-Item-canEntityPickup.patch index 58d3e70770c2..d68202e1be15 100644 --- a/patches/unapplied/server/0132-Item-canEntityPickup.patch +++ b/patches/server/0132-Item-canEntityPickup.patch @@ -5,23 +5,23 @@ Subject: [PATCH] Item#canEntityPickup diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index d8beadc96a7f779c39c8e22ffe52d872ac49a0ad..fe00b73b0aeac4e4c1496dcaf81595f57a4a073f 100644 +index 03d289abc30927793aa00f6758ed9db6fb765999..51381c32c8650400331a122a4b6c8d95c9d0632b 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -673,6 +673,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab - ItemEntity entityitem = (ItemEntity) iterator.next(); +@@ -672,6 +672,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab + ItemEntity entityitem = (ItemEntity) iterator.next(); - if (!entityitem.isRemoved() && !entityitem.getItem().isEmpty() && !entityitem.hasPickUpDelay() && this.wantsToPickUp(entityitem.getItem())) { -+ // Paper start - Item#canEntityPickup -+ if (!entityitem.canMobPickup) { -+ continue; -+ } -+ // Paper end - Item#canEntityPickup - this.pickUpItem(entityitem); + if (!entityitem.isRemoved() && !entityitem.getItem().isEmpty() && !entityitem.hasPickUpDelay() && this.wantsToPickUp(worldserver, entityitem.getItem())) { ++ // Paper start - Item#canEntityPickup ++ if (!entityitem.canMobPickup) { ++ continue; ++ } ++ // Paper end - Item#canEntityPickup + this.pickUpItem(worldserver, entityitem); + } } - } diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index c4cd7cf1567cdf57bfe9f2d80cd4a613efe10dc7..759c246540bbd5cb99c78a722c39b72fbc1951d4 100644 +index c1859488af5a3a5c7a5a70e6789b40ee44e1d01e..95d43e451f3343a9a9488b23695908235b55d6c5 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -60,6 +60,7 @@ public class ItemEntity extends Entity implements TraceableEntity { diff --git a/patches/unapplied/server/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch b/patches/server/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch similarity index 87% rename from patches/unapplied/server/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch rename to patches/server/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch index 282fdd4f1e76..081b08fc3a35 100644 --- a/patches/unapplied/server/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch +++ b/patches/server/0133-PlayerPickupItemEvent-setFlyAtPlayer.patch @@ -5,10 +5,10 @@ Subject: [PATCH] PlayerPickupItemEvent#setFlyAtPlayer diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index 759c246540bbd5cb99c78a722c39b72fbc1951d4..f51f04758e135294bab5c7d1f891a8d67fea78f5 100644 +index 95d43e451f3343a9a9488b23695908235b55d6c5..92b52ccca3ec7aaab1ffcdc1b85bf6b3e507087f 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -436,6 +436,7 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -452,6 +452,7 @@ public class ItemEntity extends Entity implements TraceableEntity { // CraftBukkit start - fire PlayerPickupItemEvent int canHold = player.getInventory().canHold(itemstack); int remaining = i - canHold; @@ -16,7 +16,7 @@ index 759c246540bbd5cb99c78a722c39b72fbc1951d4..f51f04758e135294bab5c7d1f891a8d6 if (this.pickupDelay <= 0 && canHold > 0) { itemstack.setCount(canHold); -@@ -443,8 +444,14 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -459,8 +460,14 @@ public class ItemEntity extends Entity implements TraceableEntity { PlayerPickupItemEvent playerEvent = new PlayerPickupItemEvent((Player) player.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining); playerEvent.setCancelled(!playerEvent.getPlayer().getCanPickupItems()); this.level().getCraftServer().getPluginManager().callEvent(playerEvent); @@ -31,7 +31,7 @@ index 759c246540bbd5cb99c78a722c39b72fbc1951d4..f51f04758e135294bab5c7d1f891a8d6 return; } -@@ -474,6 +481,7 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -490,6 +497,7 @@ public class ItemEntity extends Entity implements TraceableEntity { // CraftBukkit end if (this.pickupDelay == 0 && (this.target == null || this.target.equals(player.getUUID())) && player.getInventory().add(itemstack)) { diff --git a/patches/unapplied/server/0134-PlayerAttemptPickupItemEvent.patch b/patches/server/0134-PlayerAttemptPickupItemEvent.patch similarity index 91% rename from patches/unapplied/server/0134-PlayerAttemptPickupItemEvent.patch rename to patches/server/0134-PlayerAttemptPickupItemEvent.patch index 50726dbd1762..11b2bbe0782f 100644 --- a/patches/unapplied/server/0134-PlayerAttemptPickupItemEvent.patch +++ b/patches/server/0134-PlayerAttemptPickupItemEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] PlayerAttemptPickupItemEvent diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index f51f04758e135294bab5c7d1f891a8d67fea78f5..f9dfd6e7b610cfee75524a525ab0e72bed5522da 100644 +index 92b52ccca3ec7aaab1ffcdc1b85bf6b3e507087f..75ebf09777e19645eee296a9edabac39c858ffb9 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -40,6 +40,7 @@ import org.bukkit.event.entity.EntityPickupItemEvent; @@ -16,7 +16,7 @@ index f51f04758e135294bab5c7d1f891a8d67fea78f5..f9dfd6e7b610cfee75524a525ab0e72b public class ItemEntity extends Entity implements TraceableEntity { -@@ -438,6 +439,22 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -454,6 +455,22 @@ public class ItemEntity extends Entity implements TraceableEntity { int remaining = i - canHold; boolean flyAtPlayer = false; // Paper diff --git a/patches/unapplied/server/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch b/patches/server/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch similarity index 84% rename from patches/unapplied/server/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch rename to patches/server/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch index 415b98a1a9e8..572b69e96e22 100644 --- a/patches/unapplied/server/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch +++ b/patches/server/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch @@ -10,13 +10,13 @@ out due to a sync load, as the worldgen threads will be stalling on profile lookups. diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java -index 396f368a7e21a7c7b1630b4e20cdbc452c4b0f84..54562fa04d14a937451ea7aa9d80194f2c31b471 100644 +index 5d0ef11671beb2381e0e1959f5e5f845789a2982..b87d3ac2700eedb492bd55a631c60630c2f9c96c 100644 --- a/src/main/java/net/minecraft/Util.java +++ b/src/main/java/net/minecraft/Util.java -@@ -92,6 +92,22 @@ public class Util { - private static final ExecutorService BACKGROUND_EXECUTOR = makeExecutor("Main"); - private static final ExecutorService IO_POOL = makeIoExecutor("IO-Worker-", false); - private static final ExecutorService DOWNLOAD_POOL = makeIoExecutor("Download-", true); +@@ -95,6 +95,22 @@ public class Util { + private static final TracingExecutor BACKGROUND_EXECUTOR = makeExecutor("Main"); + private static final TracingExecutor IO_POOL = makeIoExecutor("IO-Worker-", false); + private static final TracingExecutor DOWNLOAD_POOL = makeIoExecutor("Download-", true); + // Paper start - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread + public static final ExecutorService PROFILE_EXECUTOR = Executors.newFixedThreadPool(2, new java.util.concurrent.ThreadFactory() { + @@ -37,33 +37,33 @@ index 396f368a7e21a7c7b1630b4e20cdbc452c4b0f84..54562fa04d14a937451ea7aa9d80194f public static final int LINEAR_LOOKUP_THRESHOLD = 8; private static final Set ALLOWED_UNTRUSTED_LINK_PROTOCOLS = Set.of("http", "https"); diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java -index aeb0c7ce9b6f93dadd407dbdefba053568f2e2fe..416b26c2ab62b29d640169166980e398d5824b14 100644 +index c89f4a885982f06823886c81fd386b8de029a3dd..416b26c2ab62b29d640169166980e398d5824b14 100644 --- a/src/main/java/net/minecraft/server/players/GameProfileCache.java +++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java @@ -169,7 +169,7 @@ public class GameProfileCache { } else { CompletableFuture> completablefuture1 = CompletableFuture.supplyAsync(() -> { return this.get(username); -- }, Util.backgroundExecutor()).whenCompleteAsync((optional, throwable) -> { +- }, Util.backgroundExecutor().forName("getProfile")).whenCompleteAsync((optional, throwable) -> { + }, Util.PROFILE_EXECUTOR).whenCompleteAsync((optional, throwable) -> { // Paper - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread this.requests.remove(username); }, this.executor); diff --git a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java -index f720c5ef71edd65de76bcac9632173184576ea9e..c278caa030ceccec8e2721068848a34be513de88 100644 +index 59187889db52ccb132460b0e937d0bd5cbeb77f4..4b7176779c455a876419a497a8178163a68553fc 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java @@ -105,7 +105,7 @@ public class SkullBlockEntity extends BlockEntity { ProfileResult profileResult = apiServices.sessionService().fetchProfile(uuid, true); return Optional.ofNullable(profileResult).map(ProfileResult::profile); } -- }, Util.backgroundExecutor()); +- }, Util.backgroundExecutor().forName("fetchProfile")); + }, Util.PROFILE_EXECUTOR); // Paper - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread } public static void clear() { diff --git a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java b/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java -index 56a71862eac5c45fde2e1d9e96e763d9dbf24cc4..0c250e5b0bd3232d829b0c028f237e6bf5fd334d 100644 +index 26a7c2d37e6a8284ab444a9edad967bdcad1e5a3..210fdad5f2041368fc359b275f1cbf05b70b6989 100644 --- a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java +++ b/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java @@ -161,7 +161,7 @@ public final class CraftPlayerProfile implements PlayerProfile { diff --git a/patches/unapplied/server/0136-Basic-PlayerProfile-API.patch b/patches/server/0136-Basic-PlayerProfile-API.patch similarity index 98% rename from patches/unapplied/server/0136-Basic-PlayerProfile-API.patch rename to patches/server/0136-Basic-PlayerProfile-API.patch index d0564f4df66c..b9e446f05625 100644 --- a/patches/unapplied/server/0136-Basic-PlayerProfile-API.patch +++ b/patches/server/0136-Basic-PlayerProfile-API.patch @@ -591,7 +591,7 @@ index 0000000000000000000000000000000000000000..332700f84c5587e47a4d2056bfbb5413 + @NotNull ResolvableProfile buildResolvableProfile(); +} diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index 6afede80c10503a261d0f735c351d943597be9ff..993296f9c2457809bd6b844c309895f417eb42a5 100644 +index 7399358f18dc7869fbfe414186cf18414c1eaafc..a9dadd106ff0ac0f788c16048a73dfc3320b4944 100644 --- a/src/main/java/net/minecraft/server/Main.java +++ b/src/main/java/net/minecraft/server/Main.java @@ -168,7 +168,7 @@ public class Main { @@ -626,10 +626,10 @@ index 416b26c2ab62b29d640169166980e398d5824b14..774d81c702edb76a2f6184d4dc53687d 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 cfc59f1fb52dffb13fb214dd7c9cf71d40354ef0..f2b2a352cdc0301601ffd4b4fb7a99304ba526e5 100644 +index 271f299823495fd92c49a1fbb04e1daa501fafb0..d18228961bfd201e922e1bd1ab41bb6b53124c5c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -262,6 +262,9 @@ import org.yaml.snakeyaml.error.MarkedYAMLException; +@@ -265,6 +265,9 @@ import org.yaml.snakeyaml.error.MarkedYAMLException; import net.md_5.bungee.api.chat.BaseComponent; // Spigot @@ -639,7 +639,7 @@ index cfc59f1fb52dffb13fb214dd7c9cf71d40354ef0..f2b2a352cdc0301601ffd4b4fb7a9930 public final class CraftServer implements Server { private final String serverName = io.papermc.paper.ServerBuildInfo.buildInfo().brandName(); // Paper private final String serverVersion; -@@ -307,6 +310,7 @@ public final class CraftServer implements Server { +@@ -310,6 +313,7 @@ public final class CraftServer implements Server { static { ConfigurationSerialization.registerClass(CraftOfflinePlayer.class); ConfigurationSerialization.registerClass(CraftPlayerProfile.class); @@ -647,7 +647,7 @@ index cfc59f1fb52dffb13fb214dd7c9cf71d40354ef0..f2b2a352cdc0301601ffd4b4fb7a9930 CraftItemFactory.instance(); CraftEntityFactory.instance(); } -@@ -2842,5 +2846,39 @@ public final class CraftServer implements Server { +@@ -2859,5 +2863,39 @@ public final class CraftServer implements Server { public boolean suggestPlayerNamesWhenNullTabCompletions() { return io.papermc.paper.configuration.GlobalConfiguration.get().commands.suggestPlayerNamesWhenNullTabCompletions; } diff --git a/patches/unapplied/server/0137-Add-UnknownCommandEvent.patch b/patches/server/0137-Add-UnknownCommandEvent.patch similarity index 90% rename from patches/unapplied/server/0137-Add-UnknownCommandEvent.patch rename to patches/server/0137-Add-UnknownCommandEvent.patch index 25a7aa2070d6..a49ad284ae55 100644 --- a/patches/unapplied/server/0137-Add-UnknownCommandEvent.patch +++ b/patches/server/0137-Add-UnknownCommandEvent.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add UnknownCommandEvent Co-authored-by: Jake Potrebic diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java -index ec34e402104d7a696ea95e0b11ee70189b678ab9..d9fc3c25bef251df6a53ee47ec224b07240a931c 100644 +index 2fbd7f7c976fb55b7238f1e512afad79e52a5b2c..4d5f1dd1c3bd742b1bc5e3914101a699041caa7e 100644 --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java +++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java -@@ -330,8 +330,13 @@ public class CommandSourceStack implements ExecutionCommandSource { +@@ -334,7 +334,7 @@ public class Commands { + Profiler.get().push(() -> { return "/" + s; }); - ContextChain contextchain = Commands.finishParsing(parseresults, s, commandlistenerwrapper, label); // CraftBukkit @@ -37,7 +37,7 @@ index f94c0106b44d614483184e372c01c1504cb886b0..72756ef14b8ec8afd80313b9f6aaf767 try { if (contextchain != null) { -@@ -363,14 +363,18 @@ public class Commands { +@@ -368,14 +368,18 @@ public class Commands { } @Nullable @@ -58,7 +58,7 @@ index f94c0106b44d614483184e372c01c1504cb886b0..72756ef14b8ec8afd80313b9f6aaf767 if (commandsyntaxexception.getInput() != null && commandsyntaxexception.getCursor() >= 0) { int i = Math.min(commandsyntaxexception.getInput().length(), commandsyntaxexception.getCursor()); MutableComponent ichatmutablecomponent = Component.empty().withStyle(ChatFormatting.GRAY).withStyle((chatmodifier) -> { -@@ -389,7 +393,17 @@ public class Commands { +@@ -394,7 +398,17 @@ public class Commands { } ichatmutablecomponent.append((Component) Component.translatable("command.context.here").withStyle(ChatFormatting.RED, ChatFormatting.ITALIC)); @@ -78,10 +78,10 @@ index f94c0106b44d614483184e372c01c1504cb886b0..72756ef14b8ec8afd80313b9f6aaf767 return null; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index f2b2a352cdc0301601ffd4b4fb7a99304ba526e5..31f87ce0865dd7560cd9ba634855a1defdc80df2 100644 +index d18228961bfd201e922e1bd1ab41bb6b53124c5c..fa6284ebe3bdbf97b40a2ab61ba94062cdcf045e 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -948,7 +948,13 @@ public final class CraftServer implements Server { +@@ -951,7 +951,13 @@ public final class CraftServer implements Server { // Spigot start if (!org.spigotmc.SpigotConfig.unknownCommandMessage.isEmpty()) { diff --git a/patches/unapplied/server/0138-Shoulder-Entities-Release-API.patch b/patches/server/0138-Shoulder-Entities-Release-API.patch similarity index 73% rename from patches/unapplied/server/0138-Shoulder-Entities-Release-API.patch rename to patches/server/0138-Shoulder-Entities-Release-API.patch index c169c6edc622..3c6d15f32361 100644 --- a/patches/unapplied/server/0138-Shoulder-Entities-Release-API.patch +++ b/patches/server/0138-Shoulder-Entities-Release-API.patch @@ -5,14 +5,14 @@ Subject: [PATCH] Shoulder Entities Release API diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index 7995a4626b3ed68234d468418408b9a8e179b6f6..362d75522aaa721e9fb1d12a149d0efec1ac17b1 100644 +index fb6b7be09fffbb9ffefba3f0c0c97b0f90ff6a94..357c71409af5f67a0a6aaa0cb08fd93a4a4f99de 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -1995,20 +1995,45 @@ public abstract class Player extends LivingEntity { +@@ -1948,7 +1948,31 @@ public abstract class Player extends LivingEntity { } -+ // Paper start ++ // Paper start - release entity api + public Entity releaseLeftShoulderEntity() { + Entity entity = this.respawnEntityOnShoulder0(this.getShoulderEntityLeft()); + if (entity != null) { @@ -28,42 +28,39 @@ index 7995a4626b3ed68234d468418408b9a8e179b6f6..362d75522aaa721e9fb1d12a149d0efe + } + return entity; + } -+ // Paper - maintain old signature ++ // Paper end - release entity api + private boolean respawnEntityOnShoulder(CompoundTag nbttagcompound) { // CraftBukkit void->boolean -- if (!this.level().isClientSide && !nbttagcompound.isEmpty()) { ++ // Paper start - release entity api - return entity - overload + return this.respawnEntityOnShoulder0(nbttagcompound) != null; + } + -+ // Paper - return entity + private Entity respawnEntityOnShoulder0(CompoundTag nbttagcompound) { // CraftBukkit void->boolean -+ if (!this.level().isClientSide && nbttagcompound != null && !nbttagcompound.isEmpty()) { - return EntityType.create(nbttagcompound, this.level()).map((entity) -> { // CraftBukkit ++ // Paper end - release entity api - return entity - overload + if (!this.level().isClientSide && !nbttagcompound.isEmpty()) { + return EntityType.create(nbttagcompound, this.level(), EntitySpawnReason.LOAD).map((entity) -> { // CraftBukkit if (entity instanceof TamableAnimal) { - ((TamableAnimal) entity).setOwnerUUID(this.uuid); +@@ -1956,11 +1980,11 @@ public abstract class Player extends LivingEntity { } entity.setPos(this.getX(), this.getY() + 0.699999988079071D, this.getZ()); - return ((ServerLevel) this.level()).addWithUUID(entity, CreatureSpawnEvent.SpawnReason.SHOULDER_ENTITY); // CraftBukkit - }).orElse(true); // CraftBukkit -+ boolean addedToWorld = ((ServerLevel) this.level()).addWithUUID(entity, CreatureSpawnEvent.SpawnReason.SHOULDER_ENTITY); // CraftBukkit -+ return addedToWorld ? entity : null; -+ }).orElse(null); // CraftBukkit // Paper - true -> null ++ return ((ServerLevel) this.level()).addWithUUID(entity, CreatureSpawnEvent.SpawnReason.SHOULDER_ENTITY) ? entity : null; // CraftBukkit // Paper start - release entity api - return entity ++ }).orElse(null); // CraftBukkit // Paper end - release entity api - return entity } - return true; // CraftBukkit + return null; // Paper - return null } -+ // Paper end @Override - public abstract boolean isSpectator(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index a93895a6e656c25e819354ecf5c73ff4bae83675..f0efea03165039525a98dc30c34d876972d9fe71 100644 +index bfa44c4e37618df3f745bccc6e775ce16c19490d..768a6e3f5d75d37ae114ffcf2b090fe9de769381 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -@@ -520,6 +520,32 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { - this.getHandle().getCooldowns().addCooldown(CraftItemType.bukkitToMinecraft(material), ticks); +@@ -544,6 +544,32 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { + this.getHandle().getCooldowns().addCooldown(CraftItemStack.asNMSCopy(item), ticks); } + // Paper start diff --git a/patches/unapplied/server/0122-PlayerTeleportEndGatewayEvent.patch b/patches/unapplied/server/0122-PlayerTeleportEndGatewayEvent.patch deleted file mode 100644 index 69691d86303b..000000000000 --- a/patches/unapplied/server/0122-PlayerTeleportEndGatewayEvent.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Sat, 31 Dec 2016 21:44:50 -0500 -Subject: [PATCH] PlayerTeleportEndGatewayEvent - -Allows you to access the Gateway being used in a teleport event -Fix the offset used for player teleportation - -diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index f067b10e13f01e751fc4ebf088740c7d40afcb99..e13692373d0efba9402c35ae5cce615dce0a5e1e 100644 ---- a/src/main/java/net/minecraft/server/level/ServerPlayer.java -+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1192,11 +1192,22 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { - ResourceKey resourcekey = worldserver1.getTypeKey(); - - if (worldserver != null && worldserver.dimension() == worldserver1.dimension()) { // CraftBukkit -+ // Paper start - gateway-specific teleport event -+ if (this.portalProcess != null && this.portalProcess.isSamePortal(((net.minecraft.world.level.block.EndGatewayBlock) net.minecraft.world.level.block.Blocks.END_GATEWAY)) && this.serverLevel().getBlockEntity(this.portalProcess.getEntryPosition()) instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity theEndGatewayBlockEntity) { -+ Location to = CraftLocation.toBukkit(teleportTarget.pos(), this.serverLevel().getWorld(), teleportTarget.yRot(), teleportTarget.xRot()); -+ final com.destroystokyo.paper.event.player.PlayerTeleportEndGatewayEvent event = new com.destroystokyo.paper.event.player.PlayerTeleportEndGatewayEvent(this.getBukkitEntity(), this.getBukkitEntity().getLocation(), to, new org.bukkit.craftbukkit.block.CraftEndGateway(to.getWorld(), theEndGatewayBlockEntity)); -+ if (!event.callEvent() || event.getTo() == null) { -+ return null; -+ } -+ this.connection.teleport(event.getTo()); -+ } else { -+ // Paper end - gateway-specific teleport event - boolean result = this.connection.teleport(teleportTarget.pos().x, teleportTarget.pos().y, teleportTarget.pos().z, teleportTarget.yRot(), teleportTarget.xRot(), teleportTarget.cause()); - if (!result) { - return null; - } - // CraftBukkit end -+ } // Paper - this.connection.resetPosition(); - teleportTarget.postDimensionTransition().onTransition(this); - return this; From f1649d702bc5711635ea18c7e90270956f57aa66 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Tue, 22 Oct 2024 23:30:51 +0200 Subject: [PATCH 009/119] Work it --- ...0186-Block-Enderpearl-Travel-Exploit.patch | 16 ++-- .../server/0139-Profile-Lookup-Events.patch | 0 ...player-logins-during-server-shutdown.patch | 2 +- .../server/0141-Entity-fromMobSpawner.patch | 16 ++-- ...42-Improve-the-Saddle-API-for-Horses.patch | 0 .../0143-ensureServerConversions-API.patch | 4 +- .../0144-Implement-getI18NDisplayName.patch | 4 +- .../0145-ProfileWhitelistVerifyEvent.patch | 6 +- .../0146-Fix-this-stupid-bullshit.patch | 10 +-- .../server/0147-LivingEntity-setKiller.patch | 4 +- ...awns-should-honor-nametags-and-leash.patch | 4 +- ...imer-when-spawner-event-is-cancelled.patch | 2 +- ...-a-custom-authentication-servers-dow.patch | 2 +- .../server/0151-Add-PlayerJumpEvent.patch | 4 +- ...dle-ServerboundKeepAlivePacket-async.patch | 4 +- ...nt-protocol-version-and-virtual-host.patch | 4 +- ...rt-serverside-behavior-of-keepalives.patch | 12 +-- ...dEffects-only-to-players-who-can-see.patch | 12 +-- .../0156-Add-PlayerArmorChangeEvent.patch | 8 +- ...rom-being-processed-when-the-player-.patch | 2 +- ...117075-Block-entity-unload-lag-spike.patch | 6 +- ...e-implementations-for-captured-block.patch | 6 +- ...-get-a-BlockState-without-a-snapshot.patch | 12 +-- .../server/0161-AsyncTabCompleteEvent.patch | 10 +-- .../0162-PlayerPickupExperienceEvent.patch | 4 +- ...3-Ability-to-apply-mending-to-XP-API.patch | 4 +- ...4-PlayerNaturallySpawnCreaturesEvent.patch | 73 +++++++++++++++++++ ...-Add-setPlayerProfile-API-for-Skulls.patch | 0 .../server/0166-PreCreatureSpawnEvent.patch | 48 ++++++------ .../0167-Fill-Profile-Property-Events.patch | 2 +- ...PlayerAdvancementCriterionGrantEvent.patch | 2 +- .../0169-Add-ArmorStand-Item-Meta.patch | 4 +- ...-Extend-Player-Interact-cancellation.patch | 4 +- .../0171-Tameable-getOwnerUniqueId-API.patch | 0 .../server/0172-Toggleable-player-crits.patch | 4 +- ...le-Explicit-Network-Manager-Flushing.patch | 0 ...nt-extended-PaperServerListPingEvent.patch | 4 +- ...dd-more-fields-to-AsyncPreLoginEvent.patch | 2 +- .../0176-Player.setPlayerProfile-API.patch | 35 +++------ .../server/0177-getPlayerUniqueId-API.patch | 4 +- .../0178-Improved-Async-Task-Scheduler.patch | 22 +++--- ...ke-legacy-ping-handler-more-reliable.patch | 0 ...ServerListPingEvent-for-legacy-pings.patch | 0 ...81-Flag-to-disable-the-channel-limit.patch | 6 +- ...2-Add-openSign-method-to-HumanEntity.patch | 4 +- ...urable-sprint-interruption-on-attack.patch | 4 +- .../server/0184-EndermanEscapeEvent.patch | 18 ++--- .../0185-Enderman.teleportRandomly.patch | 0 ...4-PlayerNaturallySpawnCreaturesEvent.patch | 73 ------------------- 49 files changed, 229 insertions(+), 238 deletions(-) rename patches/{unapplied/server => removed/1.21.2}/0186-Block-Enderpearl-Travel-Exploit.patch (75%) rename patches/{unapplied => }/server/0139-Profile-Lookup-Events.patch (100%) rename patches/{unapplied => }/server/0140-Block-player-logins-during-server-shutdown.patch (93%) rename patches/{unapplied => }/server/0141-Entity-fromMobSpawner.patch (85%) rename patches/{unapplied => }/server/0142-Improve-the-Saddle-API-for-Horses.patch (100%) rename patches/{unapplied => }/server/0143-ensureServerConversions-API.patch (87%) rename patches/{unapplied => }/server/0144-Implement-getI18NDisplayName.patch (89%) rename patches/{unapplied => }/server/0145-ProfileWhitelistVerifyEvent.patch (94%) rename patches/{unapplied => }/server/0146-Fix-this-stupid-bullshit.patch (88%) rename patches/{unapplied => }/server/0147-LivingEntity-setKiller.patch (89%) rename patches/{unapplied => }/server/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch (84%) rename patches/{unapplied => }/server/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch (92%) rename patches/{unapplied => }/server/0150-Allow-specifying-a-custom-authentication-servers-dow.patch (94%) rename patches/{unapplied => }/server/0151-Add-PlayerJumpEvent.patch (94%) rename patches/{unapplied => }/server/0152-handle-ServerboundKeepAlivePacket-async.patch (93%) rename patches/{unapplied => }/server/0153-Expose-client-protocol-version-and-virtual-host.patch (96%) rename patches/{unapplied => }/server/0154-revert-serverside-behavior-of-keepalives.patch (91%) rename patches/{unapplied => }/server/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch (92%) rename patches/{unapplied => }/server/0156-Add-PlayerArmorChangeEvent.patch (94%) rename patches/{unapplied => }/server/0157-Prevent-logins-from-being-processed-when-the-player-.patch (92%) rename patches/{unapplied => }/server/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch (89%) rename patches/{unapplied => }/server/0159-use-CB-BlockState-implementations-for-captured-block.patch (94%) rename patches/{unapplied => }/server/0160-API-to-get-a-BlockState-without-a-snapshot.patch (94%) rename patches/{unapplied => }/server/0161-AsyncTabCompleteEvent.patch (95%) rename patches/{unapplied => }/server/0162-PlayerPickupExperienceEvent.patch (88%) rename patches/{unapplied => }/server/0163-Ability-to-apply-mending-to-XP-API.patch (95%) create mode 100644 patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch rename patches/{unapplied => }/server/0165-Add-setPlayerProfile-API-for-Skulls.patch (100%) rename patches/{unapplied => }/server/0166-PreCreatureSpawnEvent.patch (76%) rename patches/{unapplied => }/server/0167-Fill-Profile-Property-Events.patch (98%) rename patches/{unapplied => }/server/0168-Add-PlayerAdvancementCriterionGrantEvent.patch (92%) rename patches/{unapplied => }/server/0169-Add-ArmorStand-Item-Meta.patch (98%) rename patches/{unapplied => }/server/0170-Extend-Player-Interact-cancellation.patch (92%) rename patches/{unapplied => }/server/0171-Tameable-getOwnerUniqueId-API.patch (100%) rename patches/{unapplied => }/server/0172-Toggleable-player-crits.patch (86%) rename patches/{unapplied => }/server/0173-Disable-Explicit-Network-Manager-Flushing.patch (100%) rename patches/{unapplied => }/server/0174-Implement-extended-PaperServerListPingEvent.patch (98%) rename patches/{unapplied => }/server/0175-Add-more-fields-to-AsyncPreLoginEvent.patch (98%) rename patches/{unapplied => }/server/0176-Player.setPlayerProfile-API.patch (85%) rename patches/{unapplied => }/server/0177-getPlayerUniqueId-API.patch (90%) rename patches/{unapplied => }/server/0178-Improved-Async-Task-Scheduler.patch (94%) rename patches/{unapplied => }/server/0179-Make-legacy-ping-handler-more-reliable.patch (100%) rename patches/{unapplied => }/server/0180-Call-PaperServerListPingEvent-for-legacy-pings.patch (100%) rename patches/{unapplied => }/server/0181-Flag-to-disable-the-channel-limit.patch (89%) rename patches/{unapplied => }/server/0182-Add-openSign-method-to-HumanEntity.patch (86%) rename patches/{unapplied => }/server/0183-Configurable-sprint-interruption-on-attack.patch (87%) rename patches/{unapplied => }/server/0184-EndermanEscapeEvent.patch (72%) rename patches/{unapplied => }/server/0185-Enderman.teleportRandomly.patch (100%) delete mode 100644 patches/unapplied/server/0164-PlayerNaturallySpawnCreaturesEvent.patch diff --git a/patches/unapplied/server/0186-Block-Enderpearl-Travel-Exploit.patch b/patches/removed/1.21.2/0186-Block-Enderpearl-Travel-Exploit.patch similarity index 75% rename from patches/unapplied/server/0186-Block-Enderpearl-Travel-Exploit.patch rename to patches/removed/1.21.2/0186-Block-Enderpearl-Travel-Exploit.patch index c538b3c38a80..677f86fec00c 100644 --- a/patches/unapplied/server/0186-Block-Enderpearl-Travel-Exploit.patch +++ b/patches/removed/1.21.2/0186-Block-Enderpearl-Travel-Exploit.patch @@ -11,15 +11,19 @@ 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. +Note: Currently removed as enderpearls are ticked as long as their owner is online in 1.21.2. +Might be worth to re-add once an option to disable the above vanilla mechanic is added, to +fully prevent enderpearl travel exploits. + == AT == public net.minecraft.world.entity.projectile.Projectile cachedOwner public net.minecraft.world.entity.projectile.Projectile ownerUUID diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index d728afbe1d6882f1ace4ead9d87f4b7d2af43ba2..7c6b094de5e29cb2663e8a7072a27d7adbceb4b2 100644 +index 21c3d771a3dd921767c2cba1e11583d015879ca9..332d378979925f1197f4218919442688a4c47c23 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2111,6 +2111,12 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2194,6 +2194,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public void onTickingEnd(Entity entity) { ServerLevel.this.entityTickList.remove(entity); @@ -33,13 +37,13 @@ index d728afbe1d6882f1ace4ead9d87f4b7d2af43ba2..7c6b094de5e29cb2663e8a7072a27d7a public void onTrackingStart(Entity entity) { diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index add45e6e95688649ba4b8d67747f763a261da51e..a39de724848d6dc796dd99dde5206f20e513fd18 100644 +index fed01aea47090b990939becde837add6c36bf418..a1840bb4a3307492f80f93c4433eec3be7f862f1 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -108,6 +108,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -116,6 +116,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { + protected void readAdditionalSaveData(CompoundTag nbt) { if (nbt.hasUUID("Owner")) { - this.ownerUUID = nbt.getUUID("Owner"); - this.cachedOwner = null; + this.setOwnerThroughUUID(nbt.getUUID("Owner")); + if (this instanceof ThrownEnderpearl && this.level() != null && this.level().paperConfig().fixes.disableUnloadedChunkEnderpearlExploit) { this.ownerUUID = null; } // Paper - Reset pearls when they stop being ticked; Don't store shooter name for pearls to block enderpearl travel exploit } diff --git a/patches/unapplied/server/0139-Profile-Lookup-Events.patch b/patches/server/0139-Profile-Lookup-Events.patch similarity index 100% rename from patches/unapplied/server/0139-Profile-Lookup-Events.patch rename to patches/server/0139-Profile-Lookup-Events.patch diff --git a/patches/unapplied/server/0140-Block-player-logins-during-server-shutdown.patch b/patches/server/0140-Block-player-logins-during-server-shutdown.patch similarity index 93% rename from patches/unapplied/server/0140-Block-player-logins-during-server-shutdown.patch rename to patches/server/0140-Block-player-logins-during-server-shutdown.patch index 5609f8375723..d3fdf86a5866 100644 --- a/patches/unapplied/server/0140-Block-player-logins-during-server-shutdown.patch +++ b/patches/server/0140-Block-player-logins-during-server-shutdown.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Block player logins during server shutdown diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index e65c582635317b9f8a1af4e6f6a5fb916f73cc35..0c2137dda44f2341bffe0928dc77be8ca6371bc9 100644 +index 80ac468321a9ccb3486e97b3448dd3fccd8e766e..ca4c054f17a79bfe0f4f49783a13e30eb0f3e2ff 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -102,6 +102,12 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, diff --git a/patches/unapplied/server/0141-Entity-fromMobSpawner.patch b/patches/server/0141-Entity-fromMobSpawner.patch similarity index 85% rename from patches/unapplied/server/0141-Entity-fromMobSpawner.patch rename to patches/server/0141-Entity-fromMobSpawner.patch index 8c8147c6ec17..4d78b98a0b6d 100644 --- a/patches/unapplied/server/0141-Entity-fromMobSpawner.patch +++ b/patches/server/0141-Entity-fromMobSpawner.patch @@ -5,10 +5,10 @@ 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 85d8c4865b65792b99f812b579d7c23823d76e52..0e800e3aeeec84f5f7ed0a391c9b66ae5689bd40 100644 +index b1b26e7c0f66f0697bcfe9eb045d45f31cd9ab06..99794276626d26849150d4956abbbc2296543907 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -402,6 +402,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -405,6 +405,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public void inactiveTick() { } // Spigot end protected int numCollisions = 0; // Paper - Cap entity collisions @@ -16,7 +16,7 @@ index 85d8c4865b65792b99f812b579d7c23823d76e52..0e800e3aeeec84f5f7ed0a391c9b66ae // Paper start - Entity origin API @javax.annotation.Nullable private org.bukkit.util.Vector origin; -@@ -2259,6 +2260,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2375,6 +2376,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } nbttagcompound.put("Paper.Origin", this.newDoubleList(origin.getX(), origin.getY(), origin.getZ())); } @@ -27,7 +27,7 @@ index 85d8c4865b65792b99f812b579d7c23823d76e52..0e800e3aeeec84f5f7ed0a391c9b66ae // Paper end return nbttagcompound; } catch (Throwable throwable) { -@@ -2399,6 +2404,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2516,6 +2521,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.originWorld = originWorld; origin = new org.bukkit.util.Vector(originTag.getDouble(0), originTag.getDouble(1), originTag.getDouble(2)); } @@ -37,7 +37,7 @@ index 85d8c4865b65792b99f812b579d7c23823d76e52..0e800e3aeeec84f5f7ed0a391c9b66ae } catch (Throwable throwable) { diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index aa54237205989f619ac6a3faa2e4285427b9e31d..43d399e1a0ba2fb0541f851a28032fa60fc01b33 100644 +index 7b918001d36a8f14ed0d3ee4d6783588f48eb78f..e424c23c22809a307175b5dcc7f7b0084464493f 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java @@ -176,6 +176,7 @@ public abstract class BaseSpawner { @@ -49,7 +49,7 @@ index aa54237205989f619ac6a3faa2e4285427b9e31d..43d399e1a0ba2fb0541f851a28032fa6 if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) { continue; diff --git a/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java b/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java -index 55d63de57ec740fc4ea5faa3db9a092b8e4fed95..c3f6522a7dc0777c5b3fa2bac63a8901f96d9f38 100644 +index 28c8b8cd2ad0a368f7856a407d91742978490728..f0163b7fa8b27823db9df5b8d2b6adcb63023164 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java +++ b/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java @@ -230,6 +230,7 @@ public final class TrialSpawner { @@ -61,10 +61,10 @@ index 55d63de57ec740fc4ea5faa3db9a092b8e4fed95..c3f6522a7dc0777c5b3fa2bac63a8901 if (org.bukkit.craftbukkit.event.CraftEventFactory.callTrialSpawnerSpawnEvent(entity, pos).isCancelled()) { return Optional.empty(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index df6da730134da754d0ff23bd1b57c82486b9ab73..69b5946625a53a1351ffc4bdf61c6874949bbeae 100644 +index 0bec53dc1be4aa997be9f03bc3cde30d22cc8160..0480fbeffd19011d3cd63021225f376c464b480c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1010,4 +1010,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1011,4 +1011,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return originVector.toLocation(world); } // Paper end - entity origin API diff --git a/patches/unapplied/server/0142-Improve-the-Saddle-API-for-Horses.patch b/patches/server/0142-Improve-the-Saddle-API-for-Horses.patch similarity index 100% rename from patches/unapplied/server/0142-Improve-the-Saddle-API-for-Horses.patch rename to patches/server/0142-Improve-the-Saddle-API-for-Horses.patch diff --git a/patches/unapplied/server/0143-ensureServerConversions-API.patch b/patches/server/0143-ensureServerConversions-API.patch similarity index 87% rename from patches/unapplied/server/0143-ensureServerConversions-API.patch rename to patches/server/0143-ensureServerConversions-API.patch index ba8fe15e57ae..8c69d762bca7 100644 --- a/patches/unapplied/server/0143-ensureServerConversions-API.patch +++ b/patches/server/0143-ensureServerConversions-API.patch @@ -7,10 +7,10 @@ This will take a Bukkit ItemStack and run it through any conversions a server pr to ensure it meets latest minecraft expectations. diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -index e2daeeba1bacbb5c5ca2aa922fa67b02cd050755..07df02997d95275cbf26ab9b76eb587da7117d37 100644 +index 5d7e6b61102a6244c5426917c4ff280fa9e12cf1..91010267b8c4df582415a8f7cd7386723b556cc0 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -@@ -223,4 +223,12 @@ public final class CraftItemFactory implements ItemFactory { +@@ -226,4 +226,12 @@ public final class CraftItemFactory implements ItemFactory { return io.papermc.paper.adventure.PaperAdventure.asAdventure(CraftItemStack.asNMSCopy(itemStack).getDisplayName()); } // Paper end - Adventure diff --git a/patches/unapplied/server/0144-Implement-getI18NDisplayName.patch b/patches/server/0144-Implement-getI18NDisplayName.patch similarity index 89% rename from patches/unapplied/server/0144-Implement-getI18NDisplayName.patch rename to patches/server/0144-Implement-getI18NDisplayName.patch index 6dfc69b23c28..8ade912d8fd5 100644 --- a/patches/unapplied/server/0144-Implement-getI18NDisplayName.patch +++ b/patches/server/0144-Implement-getI18NDisplayName.patch @@ -8,10 +8,10 @@ Currently the server only supports the English language. To override this, You must replace the language file embedded in the server jar. diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -index 07df02997d95275cbf26ab9b76eb587da7117d37..fd0df053cd5e8802991e665185e7f90f8001d80c 100644 +index 91010267b8c4df582415a8f7cd7386723b556cc0..685aa3c35dc593b1d923a31967649b468df8a238 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -@@ -231,4 +231,19 @@ public final class CraftItemFactory implements ItemFactory { +@@ -234,4 +234,19 @@ public final class CraftItemFactory implements ItemFactory { return CraftItemStack.asCraftMirror(CraftItemStack.asNMSCopy(item)); } // Paper end - ensure server conversions API diff --git a/patches/unapplied/server/0145-ProfileWhitelistVerifyEvent.patch b/patches/server/0145-ProfileWhitelistVerifyEvent.patch similarity index 94% rename from patches/unapplied/server/0145-ProfileWhitelistVerifyEvent.patch rename to patches/server/0145-ProfileWhitelistVerifyEvent.patch index ab82c08f0748..9f002f8ecd24 100644 --- a/patches/unapplied/server/0145-ProfileWhitelistVerifyEvent.patch +++ b/patches/server/0145-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 d5f17d7e3b56ca87ec9070b69265ce098de61f69..c08ffdbc9afb2fe7abbf5567dc1fb1e2bcb01b96 100644 +index 0a63e32b4e51500dd808ad2360d0521bf9632180..61687b2dce3964afc588e792cf765717b6d066dc 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -624,9 +624,9 @@ public abstract class PlayerList { +@@ -591,9 +591,9 @@ public abstract class PlayerList { // return chatmessage; event.disallow(PlayerLoginEvent.Result.KICK_BANNED, io.papermc.paper.adventure.PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure @@ -21,7 +21,7 @@ index d5f17d7e3b56ca87ec9070b69265ce098de61f69..c08ffdbc9afb2fe7abbf5567dc1fb1e2 } else if (this.getIpBans().isBanned(socketaddress) && !this.getIpBans().get(socketaddress).hasExpired()) { IpBanListEntry ipbanentry = this.ipBans.get(socketaddress); -@@ -993,7 +993,25 @@ public abstract class PlayerList { +@@ -962,7 +962,25 @@ public abstract class PlayerList { } public boolean isWhiteListed(GameProfile profile) { diff --git a/patches/unapplied/server/0146-Fix-this-stupid-bullshit.patch b/patches/server/0146-Fix-this-stupid-bullshit.patch similarity index 88% rename from patches/unapplied/server/0146-Fix-this-stupid-bullshit.patch rename to patches/server/0146-Fix-this-stupid-bullshit.patch index 6b9e17c4d047..fbc9a69c3579 100644 --- a/patches/unapplied/server/0146-Fix-this-stupid-bullshit.patch +++ b/patches/server/0146-Fix-this-stupid-bullshit.patch @@ -9,10 +9,10 @@ modified in order to prevent merge conflicts when Spigot changes/disables the wa and to provide some level of hint without being disruptive. diff --git a/src/main/java/net/minecraft/server/Bootstrap.java b/src/main/java/net/minecraft/server/Bootstrap.java -index 8f1992188f7fd9e735569e099b36a7eafed47aae..061c89b985dafc79c808dd5f0e296b9fbac2fdfc 100644 +index 9abd1dea58ffc612114d5fd8e8944d4aa8c68236..4840893082cbcd9b00f79149df1a7805af279dcb 100644 --- a/src/main/java/net/minecraft/server/Bootstrap.java +++ b/src/main/java/net/minecraft/server/Bootstrap.java -@@ -43,7 +43,7 @@ public class Bootstrap { +@@ -44,7 +44,7 @@ public class Bootstrap { public static void bootStrap() { if (!Bootstrap.isBootstrapped) { // CraftBukkit start @@ -21,7 +21,7 @@ index 8f1992188f7fd9e735569e099b36a7eafed47aae..061c89b985dafc79c808dd5f0e296b9f switch (name) { case "DispenserRegistry": break; -@@ -57,7 +57,7 @@ public class Bootstrap { +@@ -58,7 +58,7 @@ public class Bootstrap { System.err.println("*** WARNING: This server jar is unsupported, use at your own risk. ***"); System.err.println("**********************************************************************"); break; @@ -31,12 +31,12 @@ index 8f1992188f7fd9e735569e099b36a7eafed47aae..061c89b985dafc79c808dd5f0e296b9f Bootstrap.isBootstrapped = true; Instant instant = Instant.now(); diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index a41674e0965a13acd2ec2fcc431a2baa26fc4361..bcc9d3b1503b1be1841c9ab40e879a1cbb0549f2 100644 +index fc9e56427dc04a6ef7286bf027fef6b7ff0bac0c..1efb42f7ad357f9b4185dea79106ccd38c9f5325 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -249,10 +249,12 @@ public class Main { Calendar deadline = Calendar.getInstance(); - deadline.add(Calendar.DAY_OF_YEAR, -28); + deadline.add(Calendar.DAY_OF_YEAR, -3); if (buildDate.before(deadline.getTime())) { - System.err.println("*** Error, this build is outdated ***"); + // Paper start - This is some stupid bullshit diff --git a/patches/unapplied/server/0147-LivingEntity-setKiller.patch b/patches/server/0147-LivingEntity-setKiller.patch similarity index 89% rename from patches/unapplied/server/0147-LivingEntity-setKiller.patch rename to patches/server/0147-LivingEntity-setKiller.patch index a75578ad0685..1a07e6b288a1 100644 --- a/patches/unapplied/server/0147-LivingEntity-setKiller.patch +++ b/patches/server/0147-LivingEntity-setKiller.patch @@ -7,10 +7,10 @@ Subject: [PATCH] LivingEntity#setKiller public net.minecraft.world.entity.LivingEntity lastHurtByPlayerTime diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 5ba4105356e4a4808293e86c679d08a3c4cdd245..7a01569f62b3b27a9eb6def0e2ec72e1d392258d 100644 +index 6bb32e4eab357c5f67a3daafa2de035b0d125635..452fe788152f7c38ab4b6c627e3ba37da3d9b9d9 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -407,6 +407,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -417,6 +417,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return this.getHandle().lastHurtByPlayer == null ? null : (Player) this.getHandle().lastHurtByPlayer.getBukkitEntity(); } diff --git a/patches/unapplied/server/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch b/patches/server/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch similarity index 84% rename from patches/unapplied/server/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch rename to patches/server/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch index a61d1533c3fd..ac704548ec28 100644 --- a/patches/unapplied/server/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch +++ b/patches/server/0148-Ocelot-despawns-should-honor-nametags-and-leash.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Ocelot despawns should honor nametags and leash diff --git a/src/main/java/net/minecraft/world/entity/animal/Ocelot.java b/src/main/java/net/minecraft/world/entity/animal/Ocelot.java -index 695f057d05d6651860d8d15be5a2b48a18a35d22..97f4cc522706ec5914672aa4fdfbc35edc94aeb6 100644 +index d97bc15010a488839e0c063a9ae4a725d4d2b9e9..0554ee499c452db6c1e6852f5022b1f197adb024 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Ocelot.java +++ b/src/main/java/net/minecraft/world/entity/animal/Ocelot.java -@@ -133,7 +133,7 @@ public class Ocelot extends Animal { +@@ -132,7 +132,7 @@ public class Ocelot extends Animal { @Override public boolean removeWhenFarAway(double distanceSquared) { diff --git a/patches/unapplied/server/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch b/patches/server/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch similarity index 92% rename from patches/unapplied/server/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch rename to patches/server/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch index 129e8461dc46..e27bff4361a8 100644 --- a/patches/unapplied/server/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch +++ b/patches/server/0149-Reset-spawner-timer-when-spawner-event-is-cancelled.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Reset spawner timer when spawner event is cancelled diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index 43d399e1a0ba2fb0541f851a28032fa60fc01b33..31fe2faf9137ac8b1acca9a5ffc5bbcc8aab16c1 100644 +index e424c23c22809a307175b5dcc7f7b0084464493f..6c29e55239fdcf8df3b9dc012aa80cebcd3a837a 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java @@ -177,6 +177,7 @@ public abstract class BaseSpawner { diff --git a/patches/unapplied/server/0150-Allow-specifying-a-custom-authentication-servers-dow.patch b/patches/server/0150-Allow-specifying-a-custom-authentication-servers-dow.patch similarity index 94% rename from patches/unapplied/server/0150-Allow-specifying-a-custom-authentication-servers-dow.patch rename to patches/server/0150-Allow-specifying-a-custom-authentication-servers-dow.patch index 062c5f0c8d00..49defd6c9004 100644 --- a/patches/unapplied/server/0150-Allow-specifying-a-custom-authentication-servers-dow.patch +++ b/patches/server/0150-Allow-specifying-a-custom-authentication-servers-dow.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Allow specifying a custom "authentication servers down" kick diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 0c2137dda44f2341bffe0928dc77be8ca6371bc9..0d995abe33f41b96823d3e5a51e33f3dcb11d564 100644 +index ca4c054f17a79bfe0f4f49783a13e30eb0f3e2ff..f489ac450dd0275805d0cc8616050f0331f4c39a 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -308,7 +308,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, diff --git a/patches/unapplied/server/0151-Add-PlayerJumpEvent.patch b/patches/server/0151-Add-PlayerJumpEvent.patch similarity index 94% rename from patches/unapplied/server/0151-Add-PlayerJumpEvent.patch rename to patches/server/0151-Add-PlayerJumpEvent.patch index 2e506e2c59f2..884503c5127c 100644 --- a/patches/unapplied/server/0151-Add-PlayerJumpEvent.patch +++ b/patches/server/0151-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 44cc60d92c6e83ecfa2c232b59986968d0161672..7906e163f8d03ba39480526d0293ad48534f11bf 100644 +index 2cc5663878a7c0f4b4d5f4b9a0f69de2326bf415..73d9451f4419dfe47620aed0edc7bd386a2c87da 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1199,7 +1199,34 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1201,7 +1201,34 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl boolean flag1 = d7 > 0.0D; if (this.player.onGround() && !packet.isOnGround() && flag1) { diff --git a/patches/unapplied/server/0152-handle-ServerboundKeepAlivePacket-async.patch b/patches/server/0152-handle-ServerboundKeepAlivePacket-async.patch similarity index 93% rename from patches/unapplied/server/0152-handle-ServerboundKeepAlivePacket-async.patch rename to patches/server/0152-handle-ServerboundKeepAlivePacket-async.patch index f3e7e73c5c55..db2c92f2c340 100644 --- a/patches/unapplied/server/0152-handle-ServerboundKeepAlivePacket-async.patch +++ b/patches/server/0152-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/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 5f3b3f03936cfe23ed792c57d342a9932ea2e962..5e5e669f564c6130d1dea004ae8810939954da98 100644 +index 04ada45eabd5a6c752c320cdff1a65c7ac83eb22..6fd8204a8d66d26c3011d197c004398d320dc469 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -122,14 +122,18 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -129,14 +129,18 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack @Override public void handleKeepAlive(ServerboundKeepAlivePacket packet) { diff --git a/patches/unapplied/server/0153-Expose-client-protocol-version-and-virtual-host.patch b/patches/server/0153-Expose-client-protocol-version-and-virtual-host.patch similarity index 96% rename from patches/unapplied/server/0153-Expose-client-protocol-version-and-virtual-host.patch rename to patches/server/0153-Expose-client-protocol-version-and-virtual-host.patch index 9dfb157c0319..fba936bcfec4 100644 --- a/patches/unapplied/server/0153-Expose-client-protocol-version-and-virtual-host.patch +++ b/patches/server/0153-Expose-client-protocol-version-and-virtual-host.patch @@ -90,10 +90,10 @@ index 7ae4279768b70a4fdc8f4438898871a17c8fe402..582bbb376c75ab5bf737f3015ce8ad45 private void beginLogin(ClientIntentionPacket packet, boolean transfer) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 258808bcb6f853c5679476305074823a7bb8b379..d099b898208392f380eb9ccd49bf84d54c194e67 100644 +index 5085da38a278d8f978e19a5b8df7a8e3d087d753..0b18ef707349c086cd670b3c145144eda64df3fd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -336,6 +336,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -337,6 +337,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().transferCookieConnection.sendPacket(new ClientboundTransferPacket(host, port)); } diff --git a/patches/unapplied/server/0154-revert-serverside-behavior-of-keepalives.patch b/patches/server/0154-revert-serverside-behavior-of-keepalives.patch similarity index 91% rename from patches/unapplied/server/0154-revert-serverside-behavior-of-keepalives.patch rename to patches/server/0154-revert-serverside-behavior-of-keepalives.patch index ee6e8a16c50d..78c569400ba8 100644 --- a/patches/unapplied/server/0154-revert-serverside-behavior-of-keepalives.patch +++ b/patches/server/0154-revert-serverside-behavior-of-keepalives.patch @@ -17,10 +17,10 @@ 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/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 5e5e669f564c6130d1dea004ae8810939954da98..9b1df397e1d2d8ca04b34012808be2110526f401 100644 +index 6fd8204a8d66d26c3011d197c004398d320dc469..b36528ad18c8603994c6a821b19b99581717b44c 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -74,7 +74,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -75,7 +75,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack protected final MinecraftServer server; public final Connection connection; // Paper private final boolean transferred; @@ -29,7 +29,7 @@ index 5e5e669f564c6130d1dea004ae8810939954da98..9b1df397e1d2d8ca04b34012808be211 private boolean keepAlivePending; private long keepAliveChallenge; private long closedListenerTime; -@@ -82,6 +82,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -83,6 +83,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack private int latency; private volatile boolean suspendFlushingOnServerThread = false; public final java.util.Map packCallbacks = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - adventure resource pack callbacks @@ -37,10 +37,10 @@ index 5e5e669f564c6130d1dea004ae8810939954da98..9b1df397e1d2d8ca04b34012808be211 public ServerCommonPacketListenerImpl(MinecraftServer minecraftserver, Connection networkmanager, CommonListenerCookie commonlistenercookie, ServerPlayer player) { // CraftBukkit this.server = minecraftserver; -@@ -232,18 +233,22 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -239,18 +240,22 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack protected void keepConnectionAlive() { - this.server.getProfiler().push("keepAlive"); + Profiler.get().push("keepAlive"); - long i = Util.getMillis(); + // Paper start - give clients a longer time to respond to pings as per pre 1.12.2 timings + // This should effectively place the keepalive handling back to "as it was" before 1.12.2 @@ -64,5 +64,5 @@ index 5e5e669f564c6130d1dea004ae8810939954da98..9b1df397e1d2d8ca04b34012808be211 } + // Paper end - give clients a longer time to respond to pings as per pre 1.12.2 timings - this.server.getProfiler().pop(); + Profiler.get().pop(); } diff --git a/patches/unapplied/server/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch b/patches/server/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch similarity index 92% rename from patches/unapplied/server/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch rename to patches/server/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch index f4f07b3245b9..af858331064f 100644 --- a/patches/unapplied/server/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch +++ b/patches/server/0155-Send-attack-SoundEffects-only-to-players-who-can-see.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Send attack SoundEffects only to players who can see the diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index 362d75522aaa721e9fb1d12a149d0efec1ac17b1..34654395536ea022848db3d9f0291512081fc558 100644 +index 357c71409af5f67a0a6aaa0cb08fd93a4a4f99de..1cc11284b0e155ea41c198641b3644028adda97d 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -1257,7 +1257,7 @@ public abstract class Player extends LivingEntity { +@@ -1227,7 +1227,7 @@ public abstract class Player extends LivingEntity { boolean flag1; if (this.isSprinting() && flag) { @@ -18,7 +18,7 @@ index 362d75522aaa721e9fb1d12a149d0efec1ac17b1..34654395536ea022848db3d9f0291512 flag1 = true; } else { flag1 = false; -@@ -1338,7 +1338,7 @@ public abstract class Player extends LivingEntity { +@@ -1308,7 +1308,7 @@ public abstract class Player extends LivingEntity { } } @@ -27,7 +27,7 @@ index 362d75522aaa721e9fb1d12a149d0efec1ac17b1..34654395536ea022848db3d9f0291512 this.sweepAttack(); } -@@ -1366,15 +1366,15 @@ public abstract class Player extends LivingEntity { +@@ -1336,15 +1336,15 @@ public abstract class Player extends LivingEntity { } if (flag2) { @@ -46,7 +46,7 @@ index 362d75522aaa721e9fb1d12a149d0efec1ac17b1..34654395536ea022848db3d9f0291512 } } -@@ -1430,7 +1430,7 @@ public abstract class Player extends LivingEntity { +@@ -1400,7 +1400,7 @@ public abstract class Player extends LivingEntity { this.causeFoodExhaustion(this.level().spigotConfig.combatExhaustion, EntityExhaustionEvent.ExhaustionReason.ATTACK); // CraftBukkit - EntityExhaustionEvent // Spigot - Change to use configurable value } else { @@ -55,7 +55,7 @@ index 362d75522aaa721e9fb1d12a149d0efec1ac17b1..34654395536ea022848db3d9f0291512 // CraftBukkit start - resync on cancelled event if (this instanceof ServerPlayer) { ((ServerPlayer) this).getBukkitEntity().updateInventory(); -@@ -1825,6 +1825,14 @@ public abstract class Player extends LivingEntity { +@@ -1784,6 +1784,14 @@ public abstract class Player extends LivingEntity { public int getXpNeededForNextLevel() { return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2); } diff --git a/patches/unapplied/server/0156-Add-PlayerArmorChangeEvent.patch b/patches/server/0156-Add-PlayerArmorChangeEvent.patch similarity index 94% rename from patches/unapplied/server/0156-Add-PlayerArmorChangeEvent.patch rename to patches/server/0156-Add-PlayerArmorChangeEvent.patch index 9eb204ce612d..cd684e2357ca 100644 --- a/patches/unapplied/server/0156-Add-PlayerArmorChangeEvent.patch +++ b/patches/server/0156-Add-PlayerArmorChangeEvent.patch @@ -5,13 +5,13 @@ Subject: [PATCH] Add PlayerArmorChangeEvent diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 021c72410c7580d659bfaa1e327fae3727acabd2..7a7c404778757e6778305c9f8334a4fba1f466a6 100644 +index f2f8fbc8a8cf32bcba0ad7ac9b6cdd75468e062a..76b71af07a311bc415b36f517afab31505a14483 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3168,6 +3168,13 @@ public abstract class LivingEntity extends Entity implements Attackable { - ItemStack itemstack2 = this.getItemBySlot(enumitemslot); +@@ -3285,6 +3285,13 @@ public abstract class LivingEntity extends Entity implements Attackable { - if (this.equipmentHasChanged(itemstack1, itemstack2)) { + itemstack = this.getItemBySlot(enumitemslot); + if (this.equipmentHasChanged(itemstack2, itemstack)) { + // Paper start - PlayerArmorChangeEvent + if (this instanceof ServerPlayer && enumitemslot.getType() == EquipmentSlot.Type.HUMANOID_ARMOR) { + final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemstack1); diff --git a/patches/unapplied/server/0157-Prevent-logins-from-being-processed-when-the-player-.patch b/patches/server/0157-Prevent-logins-from-being-processed-when-the-player-.patch similarity index 92% rename from patches/unapplied/server/0157-Prevent-logins-from-being-processed-when-the-player-.patch rename to patches/server/0157-Prevent-logins-from-being-processed-when-the-player-.patch index 5d453de7b929..95804a7b7c93 100644 --- a/patches/unapplied/server/0157-Prevent-logins-from-being-processed-when-the-player-.patch +++ b/patches/server/0157-Prevent-logins-from-being-processed-when-the-player-.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Prevent logins from being processed when the player has diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 0d995abe33f41b96823d3e5a51e33f3dcb11d564..bfda68254b39f301ba2d3d70beeb35317d262c43 100644 +index f489ac450dd0275805d0cc8616050f0331f4c39a..c5737e1c8cb82f282bab2e6b7b6c26aa077801f3 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -109,7 +109,9 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, diff --git a/patches/unapplied/server/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch b/patches/server/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch similarity index 89% rename from patches/unapplied/server/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch rename to patches/server/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch index 88b000fa9fda..c3de85edca1b 100644 --- a/patches/unapplied/server/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch +++ b/patches/server/0158-Fix-MC-117075-Block-entity-unload-lag-spike.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix MC-117075: Block entity unload lag spike diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 4fcbea7b8b12be10157da0c1f35c06e47c0334ad..ab511f4c056f07aa79aab7b662073bb8db4b1526 100644 +index b34663ba24a0925c7fe65b354f4029c51ecc3bd1..106f4dd7f49d3b81a9bc08cd034cccac90042f84 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -726,6 +726,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -728,6 +728,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { boolean flag = this.tickRateManager().runsNormally(); int tilesThisCycle = 0; @@ -17,7 +17,7 @@ index 4fcbea7b8b12be10157da0c1f35c06e47c0334ad..ab511f4c056f07aa79aab7b662073bb8 for (tileTickPosition = 0; tileTickPosition < this.blockEntityTickers.size(); tileTickPosition++) { // Paper - Disable tick limiters this.tileTickPosition = (this.tileTickPosition < this.blockEntityTickers.size()) ? this.tileTickPosition : 0; TickingBlockEntity tickingblockentity = (TickingBlockEntity) this.blockEntityTickers.get(this.tileTickPosition); -@@ -734,12 +736,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -736,12 +738,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { if (tickingblockentity.isRemoved()) { // Spigot start tilesThisCycle--; diff --git a/patches/unapplied/server/0159-use-CB-BlockState-implementations-for-captured-block.patch b/patches/server/0159-use-CB-BlockState-implementations-for-captured-block.patch similarity index 94% rename from patches/unapplied/server/0159-use-CB-BlockState-implementations-for-captured-block.patch rename to patches/server/0159-use-CB-BlockState-implementations-for-captured-block.patch index eb8b3bd4dc87..a31f1f1496ae 100644 --- a/patches/unapplied/server/0159-use-CB-BlockState-implementations-for-captured-block.patch +++ b/patches/server/0159-use-CB-BlockState-implementations-for-captured-block.patch @@ -18,10 +18,10 @@ the blockstate that will be valid for restoration, as opposed to dropping information on restoration when the event is cancelled. diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index ab511f4c056f07aa79aab7b662073bb8db4b1526..27e2718124aad69546c1d9adb9c8e69fa4a43ca7 100644 +index 106f4dd7f49d3b81a9bc08cd034cccac90042f84..c628524274110bcad175472dbcb82e6c62476a12 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -150,7 +150,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -151,7 +151,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public boolean preventPoiUpdated = false; // CraftBukkit - SPIGOT-5710 public boolean captureBlockStates = false; public boolean captureTreeGeneration = false; @@ -49,7 +49,7 @@ index ab511f4c056f07aa79aab7b662073bb8db4b1526..27e2718124aad69546c1d9adb9c8e69f this.capturedBlockStates.put(pos.immutable(), blockstate); captured = true; } -@@ -606,7 +607,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -608,7 +609,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public BlockState getBlockState(BlockPos pos) { // CraftBukkit start - tree generation if (this.captureTreeGeneration) { diff --git a/patches/unapplied/server/0160-API-to-get-a-BlockState-without-a-snapshot.patch b/patches/server/0160-API-to-get-a-BlockState-without-a-snapshot.patch similarity index 94% rename from patches/unapplied/server/0160-API-to-get-a-BlockState-without-a-snapshot.patch rename to patches/server/0160-API-to-get-a-BlockState-without-a-snapshot.patch index cd8d24869a3c..3b12a520095a 100644 --- a/patches/unapplied/server/0160-API-to-get-a-BlockState-without-a-snapshot.patch +++ b/patches/server/0160-API-to-get-a-BlockState-without-a-snapshot.patch @@ -13,7 +13,7 @@ also Avoid NPE during CraftBlockEntityState load if could not get TE If Tile Entity was null, correct Sign to return empty lines instead of null diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index d6ad310d3b472c40c128cfb459171d9f48e50915..48bee70ba4188a4a55beb6584224b0f23784dd88 100644 +index 4536632687e71b02d5945cac3816b72ac540935e..46a831f86b512f4228be8ccee40fb0f7bf0d6df6 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java @@ -59,6 +59,7 @@ public abstract class BlockEntity { @@ -27,13 +27,13 @@ index d6ad310d3b472c40c128cfb459171d9f48e50915..48bee70ba4188a4a55beb6584224b0f2 @@ -92,7 +93,7 @@ public abstract class BlockEntity { // CraftBukkit start - read container - protected void loadAdditional(CompoundTag nbt, HolderLookup.Provider registryLookup) { + protected void loadAdditional(CompoundTag nbt, HolderLookup.Provider registries) { - this.persistentDataContainer = new CraftPersistentDataContainer(BlockEntity.DATA_TYPE_REGISTRY); + this.persistentDataContainer.clear(); // Paper - clear instead of init net.minecraft.nbt.Tag persistentDataTag = nbt.get("PublicBukkitValues"); if (persistentDataTag instanceof CompoundTag) { -@@ -379,8 +380,15 @@ public abstract class BlockEntity { +@@ -380,8 +381,15 @@ public abstract class BlockEntity { // CraftBukkit start - add method public InventoryHolder getOwner() { @@ -51,7 +51,7 @@ index d6ad310d3b472c40c128cfb459171d9f48e50915..48bee70ba4188a4a55beb6584224b0f2 return null; } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index a1c1a101aa424e74309f6f4c0a53a6a8db5df441..013298c424025cd88f15d61e50d196f70fa4c58b 100644 +index c9b1167b15990235e72d68ba6d1d2f0385eb5755..e163ff416f19766132d73fff2c8eb7f3f098f8c6 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -328,6 +328,13 @@ public class CraftBlock implements Block { @@ -114,10 +114,10 @@ index 483a89ba477506ae108f680e586b37c142119696..80418a05d53516d2c539383aa9994099 + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java -index 0173a8eac2153d889536e48970f967040490e4b7..83ac5fc6cbbd249b5865ab203b150f53f01c9f05 100644 +index b849ed6eefbc73a86d4dd823bbc5bbb2321c330f..1a8dcde39a252a45046866349b848d79e1b13260 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java -@@ -387,15 +387,30 @@ public final class CraftBlockStates { +@@ -393,15 +393,30 @@ public final class CraftBlockStates { } public static BlockState getBlockState(Block block) { diff --git a/patches/unapplied/server/0161-AsyncTabCompleteEvent.patch b/patches/server/0161-AsyncTabCompleteEvent.patch similarity index 95% rename from patches/unapplied/server/0161-AsyncTabCompleteEvent.patch rename to patches/server/0161-AsyncTabCompleteEvent.patch index ca24a4366fd1..864c8ee1f1fa 100644 --- a/patches/unapplied/server/0161-AsyncTabCompleteEvent.patch +++ b/patches/server/0161-AsyncTabCompleteEvent.patch @@ -16,10 +16,10 @@ Also adds isCommand and getLocation to the sync TabCompleteEvent Co-authored-by: Aikar diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 87f56f9c14e3a827d0afc03591bfce8cbf61e307..6cdbd0281e38d7107f239e6e052c08e4ab12b552 100644 +index 73d9451f4419dfe47620aed0edc7bd386a2c87da..0cce81cb61665b2dbd445fa9a0fcfeb42ce3be2c 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -711,21 +711,58 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -714,21 +714,58 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } @@ -32,7 +32,7 @@ index 87f56f9c14e3a827d0afc03591bfce8cbf61e307..6cdbd0281e38d7107f239e6e052c08e4 - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async // CraftBukkit start - if (this.chatSpamTickCount.addAndGet(1) > 500 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { + if (!this.chatSpamThrottler.isIncrementAndUnderThreshold(1, 500) && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { this.disconnect(Component.translatable("disconnect.spam")); return; } @@ -80,10 +80,10 @@ index 87f56f9c14e3a827d0afc03591bfce8cbf61e307..6cdbd0281e38d7107f239e6e052c08e4 this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 31f87ce0865dd7560cd9ba634855a1defdc80df2..39e3730eae983c20522b97fcd547823cd192cb2d 100644 +index fa6284ebe3bdbf97b40a2ab61ba94062cdcf045e..367ecbb023ddfbadb92aa4351ff601a3ed58a358 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2294,7 +2294,7 @@ public final class CraftServer implements Server { +@@ -2298,7 +2298,7 @@ public final class CraftServer implements Server { offers = this.tabCompleteChat(player, message); } diff --git a/patches/unapplied/server/0162-PlayerPickupExperienceEvent.patch b/patches/server/0162-PlayerPickupExperienceEvent.patch similarity index 88% rename from patches/unapplied/server/0162-PlayerPickupExperienceEvent.patch rename to patches/server/0162-PlayerPickupExperienceEvent.patch index 591fd50b0205..a07fa0d16024 100644 --- a/patches/unapplied/server/0162-PlayerPickupExperienceEvent.patch +++ b/patches/server/0162-PlayerPickupExperienceEvent.patch @@ -6,10 +6,10 @@ Subject: [PATCH] PlayerPickupExperienceEvent Allows plugins to cancel a player picking up an experience orb diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -index 0330a62a6a0060d2a96de191db68774588fc7ae5..2d438cd3e69503fdc45a706f25c219af6f7a5db3 100644 +index b9160ebca0d11dbbf96da5f0f5810d302cfcea9a..74a0bebbf829fdb2bbae87100c4e2523c34f95a0 100644 --- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java +++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -@@ -322,7 +322,7 @@ public class ExperienceOrb extends Entity { +@@ -326,7 +326,7 @@ public class ExperienceOrb extends Entity { @Override public void playerTouch(Player player) { if (player instanceof ServerPlayer entityplayer) { diff --git a/patches/unapplied/server/0163-Ability-to-apply-mending-to-XP-API.patch b/patches/server/0163-Ability-to-apply-mending-to-XP-API.patch similarity index 95% rename from patches/unapplied/server/0163-Ability-to-apply-mending-to-XP-API.patch rename to patches/server/0163-Ability-to-apply-mending-to-XP-API.patch index aacf03b70085..501c3bc45cc4 100644 --- a/patches/unapplied/server/0163-Ability-to-apply-mending-to-XP-API.patch +++ b/patches/server/0163-Ability-to-apply-mending-to-XP-API.patch @@ -14,10 +14,10 @@ public net.minecraft.world.entity.ExperienceOrb durabilityToXp(I)I public net.minecraft.world.entity.ExperienceOrb xpToDurability(I)I diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index f53504221e660bfe86220a8cc1ae28750794f0cf..93550342c6f181b7622f5d649cd3e5075a464e55 100644 +index 0b18ef707349c086cd670b3c145144eda64df3fd..18c0f0550cd6b41fa394e36ee5eb9ee48138dc0b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1638,7 +1638,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1651,7 +1651,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override diff --git a/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch b/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch new file mode 100644 index 000000000000..a6fcccab1af7 --- /dev/null +++ b/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch @@ -0,0 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sun, 14 Jan 2018 17:36:02 -0500 +Subject: [PATCH] PlayerNaturallySpawnCreaturesEvent + +This event can be used for when you want to exclude a certain player +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 84ea1974445fc7be80ed474d8a2133b58ee4c8fe..aa3155bb57c09895d13914b46c77de78a90f250a 100644 +--- a/src/main/java/net/minecraft/server/level/ChunkMap.java ++++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +@@ -1100,7 +1100,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + chunkRange = (chunkRange > this.level.spigotConfig.viewDistance) ? (byte) this.level.spigotConfig.viewDistance : chunkRange; + chunkRange = (chunkRange > 8) ? 8 : chunkRange; + +- double blockRange = (reducedRange) ? Math.pow(chunkRange << 4, 2) : 16384.0D; ++ final int finalChunkRange = chunkRange; // Paper for lambda below ++ //double blockRange = (reducedRange) ? Math.pow(chunkRange << 4, 2) : 16384.0D; // Paper - use from event ++ double blockRange = 16384.0D; // Paper + // Spigot end + Iterator iterator = this.playerMap.getAllPlayers().iterator(); + +@@ -1112,6 +1114,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + } + + entityplayer = (ServerPlayer) iterator.next(); ++ // Paper start - PlayerNaturallySpawnCreaturesEvent ++ com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event; ++ blockRange = 16384.0D; ++ if (reducedRange) { ++ event = entityplayer.playerNaturallySpawnedEvent; ++ if (event == null || event.isCancelled()) return false; ++ blockRange = (double) ((event.getSpawnRadius() << 4) * (event.getSpawnRadius() << 4)); ++ } ++ // Paper end - PlayerNaturallySpawnCreaturesEvent + } while (!this.playerIsCloseEnoughForSpawning(entityplayer, chunkcoordintpair, blockRange)); // Spigot + + 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 a29598ae54d5d20740a105f81bcaec2a152fe4ba..3bbc7aa52a2ee797d6033684e73d6b307c2fadcc 100644 +--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java ++++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +@@ -521,6 +521,15 @@ public class ServerChunkCache extends ChunkSource { + List list1; + + if (flag && (this.spawnEnemies || this.spawnFriendlies)) { ++ // Paper start - PlayerNaturallySpawnCreaturesEvent ++ int chunkRange = level.spigotConfig.mobSpawnRange; ++ chunkRange = (chunkRange > level.spigotConfig.viewDistance) ? (byte) level.spigotConfig.viewDistance : chunkRange; ++ chunkRange = Math.min(chunkRange, 8); ++ for (ServerPlayer entityPlayer : this.level.players()) { ++ entityPlayer.playerNaturallySpawnedEvent = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(entityPlayer.getBukkitEntity(), (byte) chunkRange); ++ entityPlayer.playerNaturallySpawnedEvent.callEvent(); ++ } ++ // Paper end - PlayerNaturallySpawnCreaturesEvent + boolean flag1 = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && this.level.getLevelData().getGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit + + list1 = NaturalSpawner.getFilteredSpawningCategories(spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1, this.level); // CraftBukkit +diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java +index b99bd43bf5185bed21fad7dac31baf1a30bdd1fe..98aeafcc51e23a7534c8d57e4db0eb58abb3f30b 100644 +--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java ++++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +@@ -314,6 +314,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { + public String kickLeaveMessage = null; // SPIGOT-3034: Forward leave message to PlayerQuitEvent + // CraftBukkit end + public boolean isRealPlayer; // Paper ++ public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent + + public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) { + super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); diff --git a/patches/unapplied/server/0165-Add-setPlayerProfile-API-for-Skulls.patch b/patches/server/0165-Add-setPlayerProfile-API-for-Skulls.patch similarity index 100% rename from patches/unapplied/server/0165-Add-setPlayerProfile-API-for-Skulls.patch rename to patches/server/0165-Add-setPlayerProfile-API-for-Skulls.patch diff --git a/patches/unapplied/server/0166-PreCreatureSpawnEvent.patch b/patches/server/0166-PreCreatureSpawnEvent.patch similarity index 76% rename from patches/unapplied/server/0166-PreCreatureSpawnEvent.patch rename to patches/server/0166-PreCreatureSpawnEvent.patch index 0f4459f539a5..e9253fbfd99e 100644 --- a/patches/unapplied/server/0166-PreCreatureSpawnEvent.patch +++ b/patches/server/0166-PreCreatureSpawnEvent.patch @@ -15,23 +15,23 @@ instead and save a lot of server resources. See: https://github.com/PaperMC/Paper/issues/917 diff --git a/src/main/java/net/minecraft/util/SpawnUtil.java b/src/main/java/net/minecraft/util/SpawnUtil.java -index 3f2cad4c9c0400bf93932cb7f7219c2185fc7370..5c8e36ea8287029b1789719c687bac1a2c4c3a69 100644 +index e139ed6bc6f2dd07fe546588b31309ba30ed9755..34c3bf85473b3ad89355ebc21b68c59b3c683b84 100644 --- a/src/main/java/net/minecraft/util/SpawnUtil.java +++ b/src/main/java/net/minecraft/util/SpawnUtil.java -@@ -21,10 +21,10 @@ public class SpawnUtil { +@@ -22,10 +22,10 @@ public class SpawnUtil { - public static Optional trySpawnMob(EntityType entityType, MobSpawnType reason, ServerLevel world, BlockPos pos, int tries, int horizontalRange, int verticalRange, SpawnUtil.Strategy requirements) { + public static Optional trySpawnMob(EntityType entityType, EntitySpawnReason reason, ServerLevel world, BlockPos pos, int tries, int horizontalRange, int verticalRange, SpawnUtil.Strategy requirements) { // CraftBukkit start - return SpawnUtil.trySpawnMob(entityType, reason, world, pos, tries, horizontalRange, verticalRange, requirements, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT); + return SpawnUtil.trySpawnMob(entityType, reason, world, pos, tries, horizontalRange, verticalRange, requirements, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT, null); // Paper } -- public static Optional trySpawnMob(EntityType entitytypes, MobSpawnType enummobspawn, ServerLevel worldserver, BlockPos blockposition, int i, int j, int k, SpawnUtil.Strategy spawnutil_a, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { -+ public static Optional trySpawnMob(EntityType entitytypes, MobSpawnType enummobspawn, ServerLevel worldserver, BlockPos blockposition, int i, int j, int k, SpawnUtil.Strategy spawnutil_a, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason, @javax.annotation.Nullable Runnable onAbort) { // Paper +- public static Optional trySpawnMob(EntityType entitytypes, EntitySpawnReason entityspawnreason, ServerLevel worldserver, BlockPos blockposition, int i, int j, int k, SpawnUtil.Strategy spawnutil_a, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { ++ public static Optional trySpawnMob(EntityType entitytypes, EntitySpawnReason entityspawnreason, ServerLevel worldserver, BlockPos blockposition, int i, int j, int k, SpawnUtil.Strategy spawnutil_a, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason, @javax.annotation.Nullable Runnable onAbort) { // Paper - pre creature spawn event // CraftBukkit end BlockPos.MutableBlockPos blockposition_mutableblockposition = blockposition.mutable(); -@@ -34,6 +34,22 @@ public class SpawnUtil { +@@ -35,6 +35,22 @@ public class SpawnUtil { blockposition_mutableblockposition.setWithOffset(blockposition, i1, k, j1); if (worldserver.getWorldBorder().isWithinBounds((BlockPos) blockposition_mutableblockposition) && SpawnUtil.moveToPossibleSpawnPosition(worldserver, k, blockposition_mutableblockposition, spawnutil_a)) { @@ -51,16 +51,16 @@ index 3f2cad4c9c0400bf93932cb7f7219c2185fc7370..5c8e36ea8287029b1789719c687bac1a + break; + } + // Paper end - PreCreatureSpawnEvent - T t0 = entitytypes.create(worldserver, (Consumer) null, blockposition_mutableblockposition, enummobspawn, false, false); // CraftBukkit - decompile error + T t0 = entitytypes.create(worldserver, (Consumer) null, blockposition_mutableblockposition, entityspawnreason, false, false); // CraftBukkit - decompile error if (t0 != null) { diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 474f020371bb9e5fd2c5b22e44d7902977c4fc18..69a661f01e43d17262fd2845dde5528416bbe456 100644 +index 0782b2b58ed30d4ef2598e4b89f338a94a62bbe5..7fb2155b8d320f8871556083aef9ed8e1e91e6e7 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -430,6 +430,16 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -507,6 +507,16 @@ public class EntityType implements FeatureElement, EntityTypeT @Nullable - public T spawn(ServerLevel worldserver, @Nullable Consumer consumer, BlockPos blockposition, MobSpawnType enummobspawn, boolean flag, boolean flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { + public T spawn(ServerLevel worldserver, @Nullable Consumer consumer, BlockPos blockposition, EntitySpawnReason entityspawnreason, boolean flag, boolean flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { // CraftBukkit end + // Paper start - PreCreatureSpawnEvent + com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent( @@ -72,28 +72,28 @@ index 474f020371bb9e5fd2c5b22e44d7902977c4fc18..69a661f01e43d17262fd2845dde55284 + return null; + } + // Paper end - PreCreatureSpawnEvent - T t0 = this.create(worldserver, consumer, blockposition, enummobspawn, flag, flag1); + T t0 = this.create(worldserver, consumer, blockposition, entityspawnreason, flag, flag1); if (t0 != null) { diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java -index 79fdc8284f57a4f11e1954936ad574f7b8df5435..e23674dd5db3c429efd3b7c71fe36b420494c03a 100644 +index 83bb48891d03534468d61cf7683438b3efb131cf..82ed0ce824e84ea09ea963caa61fbb75f6ce6fe7 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java -@@ -970,7 +970,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - }).limit(5L).collect(Collectors.toList()); +@@ -944,7 +944,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + }).limit(5L).toList(); if (list1.size() >= requiredCount) { -- if (!SpawnUtil.trySpawnMob(EntityType.IRON_GOLEM, MobSpawnType.MOB_SUMMONED, world, this.blockPosition(), 10, 8, 6, SpawnUtil.Strategy.LEGACY_IRON_GOLEM, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE).isEmpty()) { // CraftBukkit -+ if (SpawnUtil.trySpawnMob(EntityType.IRON_GOLEM, MobSpawnType.MOB_SUMMONED, world, this.blockPosition(), 10, 8, 6, SpawnUtil.Strategy.LEGACY_IRON_GOLEM, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE, () -> {GolemSensor.golemDetected(this);}).isPresent()) { // CraftBukkit // Paper - Set Golem Last Seen to stop it from spawning another one +- if (!SpawnUtil.trySpawnMob(EntityType.IRON_GOLEM, EntitySpawnReason.MOB_SUMMONED, world, this.blockPosition(), 10, 8, 6, SpawnUtil.Strategy.LEGACY_IRON_GOLEM, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE).isEmpty()) { // CraftBukkit ++ if (SpawnUtil.trySpawnMob(EntityType.IRON_GOLEM, EntitySpawnReason.MOB_SUMMONED, world, this.blockPosition(), 10, 8, 6, SpawnUtil.Strategy.LEGACY_IRON_GOLEM, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE, () -> {GolemSensor.golemDetected(this);}).isPresent()) { // CraftBukkit // Paper - Set Golem Last Seen to stop it from spawning another one list.forEach(GolemSensor::golemDetected); } } diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index 31fe2faf9137ac8b1acca9a5ffc5bbcc8aab16c1..d13abdcc7a54bdecf853c883911ef535733610b4 100644 +index 6c29e55239fdcf8df3b9dc012aa80cebcd3a837a..bb3f3bec350dda43dbf5eda0a8c8057a413694b2 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java @@ -132,6 +132,20 @@ public abstract class BaseSpawner { - } else if (!SpawnPlacements.checkSpawnRules((EntityType) optional.get(), world, MobSpawnType.SPAWNER, blockposition1, world.getRandom())) { + } else if (!SpawnPlacements.checkSpawnRules((EntityType) optional.get(), world, EntitySpawnReason.SPAWNER, blockposition1, world.getRandom())) { continue; } + // Paper start - PreCreatureSpawnEvent @@ -111,13 +111,13 @@ index 31fe2faf9137ac8b1acca9a5ffc5bbcc8aab16c1..d13abdcc7a54bdecf853c883911ef535 + } + // Paper end - PreCreatureSpawnEvent - Entity entity = EntityType.loadEntityRecursive(nbttagcompound, world, (entity1) -> { + Entity entity = EntityType.loadEntityRecursive(nbttagcompound, world, EntitySpawnReason.SPAWNER, (entity1) -> { entity1.moveTo(d0, d1, d2, entity1.getYRot(), entity1.getXRot()); diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 6324689f52363f19501143c1649f0885684cb796..bce78beaadbfd0e400457bd14bcf6538be702879 100644 +index 400166ad0199dd4b96684904ef4748cdb72381bb..0b41149ae134084cef4016241ce923dac0349846 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -208,7 +208,13 @@ public final class NaturalSpawner { +@@ -230,7 +230,13 @@ public final class NaturalSpawner { j1 = biomesettingsmobs_c.minCount + world.random.nextInt(1 + biomesettingsmobs_c.maxCount - biomesettingsmobs_c.minCount); } @@ -132,7 +132,7 @@ index 6324689f52363f19501143c1649f0885684cb796..bce78beaadbfd0e400457bd14bcf6538 Mob entityinsentient = NaturalSpawner.getMobForSpawn(world, biomesettingsmobs_c.type); if (entityinsentient == null) { -@@ -256,10 +262,31 @@ public final class NaturalSpawner { +@@ -278,10 +284,31 @@ public final class NaturalSpawner { return squaredDistance <= 576.0D ? false : (world.getSharedSpawnPos().closerToCenterThan(new Vec3((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D), 24.0D) ? false : Objects.equals(new ChunkPos(pos), chunk.getPos()) || world.isNaturalSpawningAllowed((BlockPos) pos)); } @@ -148,7 +148,7 @@ index 6324689f52363f19501143c1649f0885684cb796..bce78beaadbfd0e400457bd14bcf6538 + // Paper end - PreCreatureSpawnEvent EntityType entitytypes = spawnEntry.type; -- return entitytypes.getCategory() == MobCategory.MISC ? false : (!entitytypes.canSpawnFarFromPlayer() && squaredDistance > (double) (entitytypes.getCategory().getDespawnDistance() * entitytypes.getCategory().getDespawnDistance()) ? false : (entitytypes.canSummon() && NaturalSpawner.canSpawnMobAt(world, structureAccessor, chunkGenerator, group, spawnEntry, pos) ? (!SpawnPlacements.isSpawnPositionOk(entitytypes, world, pos) ? false : (!SpawnPlacements.checkSpawnRules(entitytypes, world, MobSpawnType.NATURAL, pos, world.random) ? false : world.noCollision(entitytypes.getSpawnAABB((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D)))) : false)); +- return entitytypes.getCategory() == MobCategory.MISC ? false : (!entitytypes.canSpawnFarFromPlayer() && squaredDistance > (double) (entitytypes.getCategory().getDespawnDistance() * entitytypes.getCategory().getDespawnDistance()) ? false : (entitytypes.canSummon() && NaturalSpawner.canSpawnMobAt(world, structureAccessor, chunkGenerator, group, spawnEntry, pos) ? (!SpawnPlacements.isSpawnPositionOk(entitytypes, world, pos) ? false : (!SpawnPlacements.checkSpawnRules(entitytypes, world, EntitySpawnReason.NATURAL, pos, world.random) ? false : world.noCollision(entitytypes.getSpawnAABB((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D)))) : false)); + // Paper start - PreCreatureSpawnEvent + com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent( + io.papermc.paper.util.MCUtil.toLocation(world, pos), @@ -162,7 +162,7 @@ index 6324689f52363f19501143c1649f0885684cb796..bce78beaadbfd0e400457bd14bcf6538 + } + // Paper end - PreCreatureSpawnEvent + -+ return entitytypes.getCategory() == MobCategory.MISC ? PreSpawnStatus.FAIL : (!entitytypes.canSpawnFarFromPlayer() && squaredDistance > (double) (entitytypes.getCategory().getDespawnDistance() * entitytypes.getCategory().getDespawnDistance()) ? PreSpawnStatus.FAIL : (entitytypes.canSummon() && NaturalSpawner.canSpawnMobAt(world, structureAccessor, chunkGenerator, group, spawnEntry, pos) ? (!SpawnPlacements.isSpawnPositionOk(entitytypes, world, pos) ? PreSpawnStatus.FAIL : (!SpawnPlacements.checkSpawnRules(entitytypes, world, MobSpawnType.NATURAL, pos, world.random) ? PreSpawnStatus.FAIL : world.noCollision(entitytypes.getSpawnAABB((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D)) ? PreSpawnStatus.SUCCESS : PreSpawnStatus.FAIL)) : PreSpawnStatus.FAIL)); // Paper - PreCreatureSpawnEvent ++ return entitytypes.getCategory() == MobCategory.MISC ? PreSpawnStatus.FAIL : (!entitytypes.canSpawnFarFromPlayer() && squaredDistance > (double) (entitytypes.getCategory().getDespawnDistance() * entitytypes.getCategory().getDespawnDistance()) ? PreSpawnStatus.FAIL : (entitytypes.canSummon() && NaturalSpawner.canSpawnMobAt(world, structureAccessor, chunkGenerator, group, spawnEntry, pos) ? (!SpawnPlacements.isSpawnPositionOk(entitytypes, world, pos) ? PreSpawnStatus.FAIL : (!SpawnPlacements.checkSpawnRules(entitytypes, world, EntitySpawnReason.NATURAL, pos, world.random) ? PreSpawnStatus.FAIL : world.noCollision(entitytypes.getSpawnAABB((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D)) ? PreSpawnStatus.SUCCESS : PreSpawnStatus.FAIL)) : PreSpawnStatus.FAIL)); // Paper - PreCreatureSpawnEvent } @Nullable diff --git a/patches/unapplied/server/0167-Fill-Profile-Property-Events.patch b/patches/server/0167-Fill-Profile-Property-Events.patch similarity index 98% rename from patches/unapplied/server/0167-Fill-Profile-Property-Events.patch rename to patches/server/0167-Fill-Profile-Property-Events.patch index 4a73aa80a3d9..0c89bc936ac3 100644 --- a/patches/unapplied/server/0167-Fill-Profile-Property-Events.patch +++ b/patches/server/0167-Fill-Profile-Property-Events.patch @@ -59,7 +59,7 @@ index d8ed3404e8c3c61b2daff110ef32ef890a77a461..78863e72239a0f3535bc85758479da84 return new ResolvableProfile(gameProfile); }) : SkullBlockEntity.fetchGameProfile(this.name.orElseThrow()).thenApply(profile -> { diff --git a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java -index c278caa030ceccec8e2721068848a34be513de88..26e92e208ddd3122da6d44767b8841d7a8b90d98 100644 +index 4b7176779c455a876419a497a8178163a68553fc..43ddf23db92c7bfd29da4ab79538fc9a5765232e 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java @@ -41,7 +41,7 @@ public class SkullBlockEntity extends BlockEntity { diff --git a/patches/unapplied/server/0168-Add-PlayerAdvancementCriterionGrantEvent.patch b/patches/server/0168-Add-PlayerAdvancementCriterionGrantEvent.patch similarity index 92% rename from patches/unapplied/server/0168-Add-PlayerAdvancementCriterionGrantEvent.patch rename to patches/server/0168-Add-PlayerAdvancementCriterionGrantEvent.patch index ddac15d31104..af41f90a899f 100644 --- a/patches/unapplied/server/0168-Add-PlayerAdvancementCriterionGrantEvent.patch +++ b/patches/server/0168-Add-PlayerAdvancementCriterionGrantEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerAdvancementCriterionGrantEvent diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java -index 81bef7427478fe911e81f024102654d8d540dbb7..4c85abf29441645039b6a554a50e1d3274229de6 100644 +index 18a700ffb88f0c60beb2ba4d6e3554ef762a9455..0542b61053ed7039e54856eab86ba5842403e4fc 100644 --- a/src/main/java/net/minecraft/server/PlayerAdvancements.java +++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java @@ -225,6 +225,12 @@ public class PlayerAdvancements { diff --git a/patches/unapplied/server/0169-Add-ArmorStand-Item-Meta.patch b/patches/server/0169-Add-ArmorStand-Item-Meta.patch similarity index 98% rename from patches/unapplied/server/0169-Add-ArmorStand-Item-Meta.patch rename to patches/server/0169-Add-ArmorStand-Item-Meta.patch index 490b0155ea39..7e6ae430c931 100644 --- a/patches/unapplied/server/0169-Add-ArmorStand-Item-Meta.patch +++ b/patches/server/0169-Add-ArmorStand-Item-Meta.patch @@ -13,7 +13,7 @@ starting point for future additions in this area. Fixes GH-559 diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java -index eef3517833ff5c0cf41b89973ebc972b8ed31e0f..c9fbc01be0b0e7fd1cafb091d06496f4ba1e7c2c 100644 +index 7e3199567f25cc65046ba7374fe1a83fd2e5b191..4f5568707d725195ee19b65274454fec8bf99d64 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java @@ -1,5 +1,6 @@ @@ -23,7 +23,7 @@ index eef3517833ff5c0cf41b89973ebc972b8ed31e0f..c9fbc01be0b0e7fd1cafb091d06496f4 import java.util.function.BiFunction; import java.util.function.Function; import net.minecraft.world.item.BannerItem; -@@ -102,7 +103,7 @@ public final class CraftItemMetas { +@@ -103,7 +104,7 @@ public final class CraftItemMetas { item -> new CraftMetaSpawnEgg(item.getComponentsPatch()), (type, meta) -> meta instanceof CraftMetaSpawnEgg spawnEgg ? spawnEgg : new CraftMetaSpawnEgg(meta)); diff --git a/patches/unapplied/server/0170-Extend-Player-Interact-cancellation.patch b/patches/server/0170-Extend-Player-Interact-cancellation.patch similarity index 92% rename from patches/unapplied/server/0170-Extend-Player-Interact-cancellation.patch rename to patches/server/0170-Extend-Player-Interact-cancellation.patch index 0317d6e0e452..430e2a5e628b 100644 --- a/patches/unapplied/server/0170-Extend-Player-Interact-cancellation.patch +++ b/patches/server/0170-Extend-Player-Interact-cancellation.patch @@ -10,10 +10,10 @@ Flower pots are also not updated on the client when interaction is cancelled, th also resolves this. diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index 2fab84c5e2dc4de39281956390588a9a71d02f68..a5b0efd6142075ca1ecb604afbc1d0162199e7a4 100644 +index 73b6aa34ad2579d79f388c5660cdfbef41a769f2..4c8189a2a7edea824545a24dccb376b8eceac001 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -519,7 +519,11 @@ public class ServerPlayerGameMode { +@@ -525,7 +525,11 @@ public class ServerPlayerGameMode { // send a correcting update to the client for the block above as well, this because of replaceable blocks (such as grass, sea grass etc) player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.above())); diff --git a/patches/unapplied/server/0171-Tameable-getOwnerUniqueId-API.patch b/patches/server/0171-Tameable-getOwnerUniqueId-API.patch similarity index 100% rename from patches/unapplied/server/0171-Tameable-getOwnerUniqueId-API.patch rename to patches/server/0171-Tameable-getOwnerUniqueId-API.patch diff --git a/patches/unapplied/server/0172-Toggleable-player-crits.patch b/patches/server/0172-Toggleable-player-crits.patch similarity index 86% rename from patches/unapplied/server/0172-Toggleable-player-crits.patch rename to patches/server/0172-Toggleable-player-crits.patch index 03d3f5c4f1e0..3a3f237d5736 100644 --- a/patches/unapplied/server/0172-Toggleable-player-crits.patch +++ b/patches/server/0172-Toggleable-player-crits.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Toggleable player crits diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index 34654395536ea022848db3d9f0291512081fc558..3f0425f6c1a8d5ad4df9d837490c09e175d0df4b 100644 +index 1cc11284b0e155ea41c198641b3644028adda97d..35cb06706e1584cd6d25aa68ff5c9b40a5768e03 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -1266,6 +1266,7 @@ public abstract class Player extends LivingEntity { +@@ -1236,6 +1236,7 @@ public abstract class Player extends LivingEntity { f += itemstack.getItem().getAttackDamageBonus(target, f, damagesource); boolean flag2 = flag && this.fallDistance > 0.0F && !this.onGround() && !this.onClimbable() && !this.isInWater() && !this.hasEffect(MobEffects.BLINDNESS) && !this.isPassenger() && target instanceof LivingEntity && !this.isSprinting(); diff --git a/patches/unapplied/server/0173-Disable-Explicit-Network-Manager-Flushing.patch b/patches/server/0173-Disable-Explicit-Network-Manager-Flushing.patch similarity index 100% rename from patches/unapplied/server/0173-Disable-Explicit-Network-Manager-Flushing.patch rename to patches/server/0173-Disable-Explicit-Network-Manager-Flushing.patch diff --git a/patches/unapplied/server/0174-Implement-extended-PaperServerListPingEvent.patch b/patches/server/0174-Implement-extended-PaperServerListPingEvent.patch similarity index 98% rename from patches/unapplied/server/0174-Implement-extended-PaperServerListPingEvent.patch rename to patches/server/0174-Implement-extended-PaperServerListPingEvent.patch index 79d1bf0a285d..8a616b45aad3 100644 --- a/patches/unapplied/server/0174-Implement-extended-PaperServerListPingEvent.patch +++ b/patches/server/0174-Implement-extended-PaperServerListPingEvent.patch @@ -170,7 +170,7 @@ index 0000000000000000000000000000000000000000..30a19d10869f73d67b794e8e4c035bc5 + +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 5d03477919ce892f6dfb4b2304c03733e10e3721..cc0968182ab597892dbae8dd9b3e803fb62b7065 100644 +index 835bbd873ec04954024ae8649e6bc9a4557b11c5..6abcb987109c01d012c70c4c3b411f91b7630bb4 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -3,6 +3,9 @@ package net.minecraft.server; @@ -183,7 +183,7 @@ index 5d03477919ce892f6dfb4b2304c03733e10e3721..cc0968182ab597892dbae8dd9b3e803f import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -@@ -1515,7 +1518,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Co-authored-by: MCMDEV diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index bfda68254b39f301ba2d3d70beeb35317d262c43..30e55f693b963496b85afa32da9c15cacb738836 100644 +index c5737e1c8cb82f282bab2e6b7b6c26aa077801f3..4a62c1abc6f3c48bbda40325b4ce46632db3f28d 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -191,7 +191,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, diff --git a/patches/unapplied/server/0176-Player.setPlayerProfile-API.patch b/patches/server/0176-Player.setPlayerProfile-API.patch similarity index 85% rename from patches/unapplied/server/0176-Player.setPlayerProfile-API.patch rename to patches/server/0176-Player.setPlayerProfile-API.patch index b118853bc7f8..8c5b6401bd8a 100644 --- a/patches/unapplied/server/0176-Player.setPlayerProfile-API.patch +++ b/patches/server/0176-Player.setPlayerProfile-API.patch @@ -8,21 +8,8 @@ This can be useful for changing name or skins after a player has logged in. == AT == public-f net.minecraft.world.entity.player.Player gameProfile -diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 6cdbd0281e38d7107f239e6e052c08e4ab12b552..0073c6c5433be3193a01257a26c7035e544f37dd 100644 ---- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1472,7 +1472,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - this.internalTeleport(dest.getX(), dest.getY(), dest.getZ(), dest.getYaw(), dest.getPitch(), Collections.emptySet()); - } - -- private void internalTeleport(double d0, double d1, double d2, float f, float f1, Set set) { -+ public void internalTeleport(double d0, double d1, double d2, float f, float f1, Set set) { // Paper - // CraftBukkit start - if (Float.isNaN(f)) { - f = 0; diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 30e55f693b963496b85afa32da9c15cacb738836..636b8aef2348fa4cfe63a9b7d77a64b14dc7a42c 100644 +index 4a62c1abc6f3c48bbda40325b4ce46632db3f28d..bab8c53041afb9606db55923e5466eab25640226 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -341,11 +341,11 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, @@ -40,10 +27,10 @@ index 30e55f693b963496b85afa32da9c15cacb738836..636b8aef2348fa4cfe63a9b7d77a64b1 playerName = gameprofile.getName(); uniqueId = gameprofile.getId(); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index c08ffdbc9afb2fe7abbf5567dc1fb1e2bcb01b96..3ee00025eb9d936b9780b25fdc25d144acc496cd 100644 +index 61687b2dce3964afc588e792cf765717b6d066dc..95b9341859ba6da6945faebf8430a044cc1ee828 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -831,10 +831,16 @@ public abstract class PlayerList { +@@ -800,10 +800,16 @@ public abstract class PlayerList { } public void sendPlayerPermissionLevel(ServerPlayer player) { @@ -77,10 +64,10 @@ index 818df09e9245b5d89b4180b1eaa51470b7539341..f6b2ca92fd3510a76cbf56d0ea55aa6c public Server getServer() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 8521f728088d16ecbaa0119983a9f12a649ac847..9136feac48244dc68bff92b52643f2adefba5205 100644 +index 18c0f0550cd6b41fa394e36ee5eb9ee48138dc0b..356681047e34b577f51a4f90ebc8892cb1e6eaa8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -249,11 +249,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -250,11 +250,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.server.getPlayer(this.getUniqueId()) != null; } @@ -92,7 +79,7 @@ index 8521f728088d16ecbaa0119983a9f12a649ac847..9136feac48244dc68bff92b52643f2ad @Override public InetSocketAddress getAddress() { if (this.getHandle().connection.protocol() == null) return null; -@@ -1792,8 +1787,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1805,8 +1800,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { private void untrackAndHideEntity(org.bukkit.entity.Entity entity) { // Remove this entity from the hidden player's EntityTrackerEntry @@ -109,7 +96,7 @@ index 8521f728088d16ecbaa0119983a9f12a649ac847..9136feac48244dc68bff92b52643f2ad ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId()); if (entry != null) { entry.removePlayer(this.getHandle()); -@@ -1806,8 +1808,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1819,8 +1821,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().connection.send(new ClientboundPlayerInfoRemovePacket(List.of(otherPlayer.getUUID()))); } } @@ -118,7 +105,7 @@ index 8521f728088d16ecbaa0119983a9f12a649ac847..9136feac48244dc68bff92b52643f2ad } void resetAndHideEntity(org.bukkit.entity.Entity entity) { -@@ -1872,12 +1872,25 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1885,12 +1885,25 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } private void trackAndShowEntity(org.bukkit.entity.Entity entity) { @@ -144,7 +131,7 @@ index 8521f728088d16ecbaa0119983a9f12a649ac847..9136feac48244dc68bff92b52643f2ad } ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId()); -@@ -1887,6 +1900,39 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1900,6 +1913,39 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.server.getPluginManager().callEvent(new PlayerShowEntityEvent(this, entity)); } @@ -184,7 +171,7 @@ index 8521f728088d16ecbaa0119983a9f12a649ac847..9136feac48244dc68bff92b52643f2ad void resetAndShowEntity(org.bukkit.entity.Entity entity) { // SPIGOT-7312: Can't show/hide self -@@ -1898,6 +1944,34 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1911,6 +1957,34 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.trackAndShowEntity(entity); } } @@ -203,7 +190,7 @@ index 8521f728088d16ecbaa0119983a9f12a649ac847..9136feac48244dc68bff92b52643f2ad + ServerLevel worldserver = handle.serverLevel(); + connection.send(new net.minecraft.network.protocol.game.ClientboundRespawnPacket(handle.createCommonSpawnInfo(worldserver), net.minecraft.network.protocol.game.ClientboundRespawnPacket.KEEP_ALL_DATA)); + handle.onUpdateAbilities(); -+ connection.internalTeleport(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch(), java.util.Collections.emptySet()); ++ connection.internalTeleport(net.minecraft.world.entity.PositionMoveRotation.of(this.getHandle()), java.util.Collections.emptySet()); + net.minecraft.server.players.PlayerList playerList = handle.server.getPlayerList(); + playerList.sendPlayerPermissionLevel(handle, false); + playerList.sendLevelInfo(handle, worldserver); diff --git a/patches/unapplied/server/0177-getPlayerUniqueId-API.patch b/patches/server/0177-getPlayerUniqueId-API.patch similarity index 90% rename from patches/unapplied/server/0177-getPlayerUniqueId-API.patch rename to patches/server/0177-getPlayerUniqueId-API.patch index 968566c3a4af..1b24d383a2a8 100644 --- a/patches/unapplied/server/0177-getPlayerUniqueId-API.patch +++ b/patches/server/0177-getPlayerUniqueId-API.patch @@ -9,10 +9,10 @@ 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 39e3730eae983c20522b97fcd547823cd192cb2d..a94b972e328d2eff635de95847dc622c3a58fd9f 100644 +index 367ecbb023ddfbadb92aa4351ff601a3ed58a358..b4f8482dd92f33111600ae64834abefbda9e696d 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1888,6 +1888,25 @@ public final class CraftServer implements Server { +@@ -1892,6 +1892,25 @@ public final class CraftServer implements Server { return recipients.size(); } diff --git a/patches/unapplied/server/0178-Improved-Async-Task-Scheduler.patch b/patches/server/0178-Improved-Async-Task-Scheduler.patch similarity index 94% rename from patches/unapplied/server/0178-Improved-Async-Task-Scheduler.patch rename to patches/server/0178-Improved-Async-Task-Scheduler.patch index a1211ae89e80..40c95c45399a 100644 --- a/patches/unapplied/server/0178-Improved-Async-Task-Scheduler.patch +++ b/patches/server/0178-Improved-Async-Task-Scheduler.patch @@ -32,7 +32,7 @@ operations are decoupled from the sync tasks queue. diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java new file mode 100644 -index 0000000000000000000000000000000000000000..3c1992e212a6d6f1db4d5b807b38d71913619fc0 +index 0000000000000000000000000000000000000000..0ca279fb71d39c81b1f608e0ee9ba3e498d55fa3 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java @@ -0,0 +1,122 @@ @@ -106,8 +106,8 @@ index 0000000000000000000000000000000000000000..3c1992e212a6d6f1db4d5b807b38d719 + } + + @Override -+ public void mainThreadHeartbeat(int currentTick) { -+ this.currentTick = currentTick; ++ public void mainThreadHeartbeat() { ++ this.currentTick++; + this.management.execute(() -> this.runTasks(currentTick)); + } + @@ -159,7 +159,7 @@ index 0000000000000000000000000000000000000000..3c1992e212a6d6f1db4d5b807b38d719 + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -index f1145585eed18be0aa5c795a50589103fdc9cc2f..02835e4f0a0b262af27acff0939c981cae728db4 100644 +index 0e7f402a7b841c5f6f5a4b699b7bb3d9f46b1af6..fd5a058dd802599598a64467cf25f08329df9e99 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java @@ -76,7 +76,7 @@ public class CraftScheduler implements BukkitScheduler { @@ -303,29 +303,29 @@ index f1145585eed18be0aa5c795a50589103fdc9cc2f..02835e4f0a0b262af27acff0939c981c return pending; } -@@ -399,6 +452,11 @@ public class CraftScheduler implements BukkitScheduler { - * This method is designed to never block or wait for locks; an immediate execution of all current tasks. +@@ -400,6 +453,11 @@ public class CraftScheduler implements BukkitScheduler { */ - public void mainThreadHeartbeat(final int currentTick) { + public void mainThreadHeartbeat() { + this.currentTick++; + // Paper start + if (!this.isAsyncScheduler) { -+ this.asyncScheduler.mainThreadHeartbeat(currentTick); ++ this.asyncScheduler.mainThreadHeartbeat(); + } + // Paper end - this.currentTick = currentTick; final List temp = this.temp; this.parsePending(); + while (this.isReady(this.currentTick)) { @@ -434,7 +492,7 @@ public class CraftScheduler implements BukkitScheduler { this.parsePending(); } else { - // this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); // Paper + // this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(this.currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); // Paper - this.executor.execute(new com.destroystokyo.paper.ServerSchedulerReportingWrapper(task)); // Paper + task.getOwner().getLogger().log(Level.SEVERE, "Unexpected Async Task in the Sync Scheduler. Report this to Paper"); // Paper // We don't need to parse pending // (async tasks must live with race-conditions if they attempt to cancel between these few lines of code) } @@ -453,7 +511,7 @@ public class CraftScheduler implements BukkitScheduler { - //this.debugHead = this.debugHead.getNextHead(currentTick); // Paper + //this.debugHead = this.debugHead.getNextHead(this.currentTick); // Paper } - private void addTask(final CraftTask task) { diff --git a/patches/unapplied/server/0179-Make-legacy-ping-handler-more-reliable.patch b/patches/server/0179-Make-legacy-ping-handler-more-reliable.patch similarity index 100% rename from patches/unapplied/server/0179-Make-legacy-ping-handler-more-reliable.patch rename to patches/server/0179-Make-legacy-ping-handler-more-reliable.patch diff --git a/patches/unapplied/server/0180-Call-PaperServerListPingEvent-for-legacy-pings.patch b/patches/server/0180-Call-PaperServerListPingEvent-for-legacy-pings.patch similarity index 100% rename from patches/unapplied/server/0180-Call-PaperServerListPingEvent-for-legacy-pings.patch rename to patches/server/0180-Call-PaperServerListPingEvent-for-legacy-pings.patch diff --git a/patches/unapplied/server/0181-Flag-to-disable-the-channel-limit.patch b/patches/server/0181-Flag-to-disable-the-channel-limit.patch similarity index 89% rename from patches/unapplied/server/0181-Flag-to-disable-the-channel-limit.patch rename to patches/server/0181-Flag-to-disable-the-channel-limit.patch index 0745b45aae29..1950fdda934d 100644 --- a/patches/unapplied/server/0181-Flag-to-disable-the-channel-limit.patch +++ b/patches/server/0181-Flag-to-disable-the-channel-limit.patch @@ -9,10 +9,10 @@ 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 422c25577a0d95b31b5528fad8fc9b3ae97fa7f0..4e5dba1da323f12d77a36635c9227b1239856254 100644 +index 356681047e34b577f51a4f90ebc8892cb1e6eaa8..e7477aaad01c26e56e3d5e90bd403311deae8d59 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -209,6 +209,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -210,6 +210,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { private CraftWorldBorder clientWorldBorder = null; private BorderChangeListener clientWorldBorderListener = this.createWorldBorderListener(); public org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus; // Paper - more resource pack API @@ -20,7 +20,7 @@ index 422c25577a0d95b31b5528fad8fc9b3ae97fa7f0..4e5dba1da323f12d77a36635c9227b12 public CraftPlayer(CraftServer server, ServerPlayer entity) { super(server, entity); -@@ -2269,7 +2270,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2282,7 +2283,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } public void addChannel(String channel) { diff --git a/patches/unapplied/server/0182-Add-openSign-method-to-HumanEntity.patch b/patches/server/0182-Add-openSign-method-to-HumanEntity.patch similarity index 86% rename from patches/unapplied/server/0182-Add-openSign-method-to-HumanEntity.patch rename to patches/server/0182-Add-openSign-method-to-HumanEntity.patch index 51a6489c0670..c90098c049bc 100644 --- a/patches/unapplied/server/0182-Add-openSign-method-to-HumanEntity.patch +++ b/patches/server/0182-Add-openSign-method-to-HumanEntity.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add openSign method to HumanEntity diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index f0efea03165039525a98dc30c34d876972d9fe71..e59fee587c2d90df5a6aa7a3df0eefc0cb5165ac 100644 +index 768a6e3f5d75d37ae114ffcf2b090fe9de769381..6d4e0a90c70f7a66450cbb18ebec1d7bf9200af2 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -@@ -630,6 +630,12 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { +@@ -654,6 +654,12 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { } } diff --git a/patches/unapplied/server/0183-Configurable-sprint-interruption-on-attack.patch b/patches/server/0183-Configurable-sprint-interruption-on-attack.patch similarity index 87% rename from patches/unapplied/server/0183-Configurable-sprint-interruption-on-attack.patch rename to patches/server/0183-Configurable-sprint-interruption-on-attack.patch index 65dd42f5eb59..1fe54fe26f90 100644 --- a/patches/unapplied/server/0183-Configurable-sprint-interruption-on-attack.patch +++ b/patches/server/0183-Configurable-sprint-interruption-on-attack.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Configurable sprint interruption on attack If the sprint interruption is disabled players continue sprinting when they attack entities. diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index 3f0425f6c1a8d5ad4df9d837490c09e175d0df4b..00fecf255214d87837867b8743cc8f161ebfcb4c 100644 +index 35cb06706e1584cd6d25aa68ff5c9b40a5768e03..605f043bb132b21ff263ba7ab31a0f468a912d13 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -1307,7 +1307,11 @@ public abstract class Player extends LivingEntity { +@@ -1277,7 +1277,11 @@ public abstract class Player extends LivingEntity { } this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D)); diff --git a/patches/unapplied/server/0184-EndermanEscapeEvent.patch b/patches/server/0184-EndermanEscapeEvent.patch similarity index 72% rename from patches/unapplied/server/0184-EndermanEscapeEvent.patch rename to patches/server/0184-EndermanEscapeEvent.patch index 9a4685f86876..cd9bf53000c6 100644 --- a/patches/unapplied/server/0184-EndermanEscapeEvent.patch +++ b/patches/server/0184-EndermanEscapeEvent.patch @@ -8,7 +8,7 @@ Fires an event anytime an enderman intends to teleport away from the player You may cancel this, enabling ranged attacks to damage the enderman for example. diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -index bbe024a88d0feeb02a5cc4248f4bcdd3a06daf04..51e9988685b1a9a3d4d2effec63560b0ae9e8d3a 100644 +index a6c9ca2928216ed89f69c1d140590d3368b354d6..d7145b3a19402a03d0af02822ffcb0ef07eaa663 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java @@ -121,6 +121,12 @@ public class EnderMan extends Monster implements NeutralMob { @@ -24,18 +24,18 @@ index bbe024a88d0feeb02a5cc4248f4bcdd3a06daf04..51e9988685b1a9a3d4d2effec63560b0 @Override public boolean setTarget(LivingEntity entityliving, EntityTargetEvent.TargetReason reason, boolean fireEvent) { if (!super.setTarget(entityliving, reason, fireEvent)) { -@@ -270,7 +276,7 @@ public class EnderMan extends Monster implements NeutralMob { - if (this.level().isDay() && this.tickCount >= this.targetChangeTime + 600) { +@@ -257,7 +263,7 @@ public class EnderMan extends Monster implements NeutralMob { + if (world.isDay() && this.tickCount >= this.targetChangeTime + 600) { float f = this.getLightLevelDependentMagicValue(); -- if (f > 0.5F && this.level().canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F) { -+ if (f > 0.5F && this.level().canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper - EndermanEscapeEvent +- if (f > 0.5F && world.canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F) { ++ if (f > 0.5F && world.canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper - EndermanEscapeEvent this.setTarget((LivingEntity) null); this.teleport(); } -@@ -396,11 +402,13 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -383,11 +389,13 @@ public class EnderMan extends Monster implements NeutralMob { } else { - flag1 = flag && this.hurtWithCleanWater(source, (ThrownPotion) source.getDirectEntity(), amount); + flag1 = flag && this.hurtWithCleanWater(world, source, (ThrownPotion) source.getDirectEntity(), amount); + if (this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.INDIRECT)) { // Paper - EndermanEscapeEvent for (int i = 0; i < 64; ++i) { @@ -47,10 +47,10 @@ index bbe024a88d0feeb02a5cc4248f4bcdd3a06daf04..51e9988685b1a9a3d4d2effec63560b0 return flag1; } -@@ -625,7 +633,7 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -612,7 +620,7 @@ public class EnderMan extends Monster implements NeutralMob { } else { if (this.target != null && !this.enderman.isPassenger()) { - if (this.enderman.isLookingAtMe((Player) this.target)) { + if (this.enderman.isBeingStaredBy((Player) this.target)) { - if (this.target.distanceToSqr((Entity) this.enderman) < 16.0D) { + if (this.target.distanceToSqr((Entity) this.enderman) < 16.0D && this.enderman.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.STARE)) { // Paper - EndermanEscapeEvent this.enderman.teleport(); diff --git a/patches/unapplied/server/0185-Enderman.teleportRandomly.patch b/patches/server/0185-Enderman.teleportRandomly.patch similarity index 100% rename from patches/unapplied/server/0185-Enderman.teleportRandomly.patch rename to patches/server/0185-Enderman.teleportRandomly.patch diff --git a/patches/unapplied/server/0164-PlayerNaturallySpawnCreaturesEvent.patch b/patches/unapplied/server/0164-PlayerNaturallySpawnCreaturesEvent.patch deleted file mode 100644 index 2b8c16af6b11..000000000000 --- a/patches/unapplied/server/0164-PlayerNaturallySpawnCreaturesEvent.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Sun, 14 Jan 2018 17:36:02 -0500 -Subject: [PATCH] PlayerNaturallySpawnCreaturesEvent - -This event can be used for when you want to exclude a certain player -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 d60c70d59d0a6ef21224c597c9015cb3f51dabb8..63bcd7698fdb86366441dacedbb616771f6b1a3d 100644 ---- a/src/main/java/net/minecraft/server/level/ChunkMap.java -+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1037,7 +1037,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - chunkRange = (chunkRange > this.level.spigotConfig.viewDistance) ? (byte) this.level.spigotConfig.viewDistance : chunkRange; - chunkRange = (chunkRange > 8) ? 8 : chunkRange; - -- double blockRange = (reducedRange) ? Math.pow(chunkRange << 4, 2) : 16384.0D; -+ final int finalChunkRange = chunkRange; // Paper for lambda below -+ //double blockRange = (reducedRange) ? Math.pow(chunkRange << 4, 2) : 16384.0D; // Paper - use from event -+ double blockRange = 16384.0D; // Paper - // Spigot end - if (!this.distanceManager.hasPlayersNearby(chunkcoordintpair.toLong())) { - return false; -@@ -1052,6 +1054,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - - entityplayer = (ServerPlayer) iterator.next(); -+ // Paper start - PlayerNaturallySpawnCreaturesEvent -+ com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event; -+ blockRange = 16384.0D; -+ if (reducedRange) { -+ event = entityplayer.playerNaturallySpawnedEvent; -+ if (event == null || event.isCancelled()) return false; -+ blockRange = (double) ((event.getSpawnRadius() << 4) * (event.getSpawnRadius() << 4)); -+ } -+ // Paper end - PlayerNaturallySpawnCreaturesEvent - } while (!this.playerIsCloseEnoughForSpawning(entityplayer, chunkcoordintpair, blockRange)); // Spigot - - 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 e0c8b89767087cba34fc3c3809db4c386dacb193..a939bad7da9c852827a2d67d9ace5d0df4911a31 100644 ---- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java -+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -461,6 +461,15 @@ public class ServerChunkCache extends ChunkSource { - boolean flag = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit - - Util.shuffle(list, this.level.random); -+ // Paper start - PlayerNaturallySpawnCreaturesEvent -+ int chunkRange = level.spigotConfig.mobSpawnRange; -+ chunkRange = (chunkRange > level.spigotConfig.viewDistance) ? (byte) level.spigotConfig.viewDistance : chunkRange; -+ chunkRange = Math.min(chunkRange, 8); -+ for (ServerPlayer entityPlayer : this.level.players()) { -+ entityPlayer.playerNaturallySpawnedEvent = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(entityPlayer.getBukkitEntity(), (byte) chunkRange); -+ entityPlayer.playerNaturallySpawnedEvent.callEvent(); -+ } -+ // Paper end - PlayerNaturallySpawnCreaturesEvent - int l = this.level.getGameRules().getInt(GameRules.RULE_RANDOMTICKING); - boolean flag1 = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && this.level.getLevelData().getGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit - Iterator iterator1 = list.iterator(); -diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index a049a54ee70839706787f8de661ca6e6b1f54071..db72318d822b876eb937f0f0f7f2b2139fb77df7 100644 ---- a/src/main/java/net/minecraft/server/level/ServerPlayer.java -+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -286,6 +286,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { - public String kickLeaveMessage = null; // SPIGOT-3034: Forward leave message to PlayerQuitEvent - // CraftBukkit end - public boolean isRealPlayer; // Paper -+ public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent - - public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) { - super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); From 9d63c814c2bdb27e7b7063f0c95465dcd059c5d1 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Wed, 23 Oct 2024 00:02:50 +0200 Subject: [PATCH 010/119] Work work work --- ...d.spawnParticle-API-and-add-Builder.patch} | 8 +-- ...allowed-colored-signs-to-be-created.patch} | 4 +- .../0188-EndermanAttackPlayerEvent.patch} | 18 +++---- .../0189-WitchConsumePotionEvent.patch} | 4 +- .../server/0190-WitchThrowPotionEvent.patch | 25 +++++++++ .../0191-WitchReadyPotionEvent.patch} | 8 +-- ...0192-ItemStack-getMaxItemUseDuration.patch | 33 ++++++++++++ ...3-Add-EntityTeleportEndGatewayEvent.patch} | 10 ++-- ...d-flag-on-cancel-of-Explosion-Event.patch} | 4 +- .../0195-Fix-CraftEntity-hashCode.patch} | 4 +- ...-Configurable-LootPool-luck-formula.patch} | 0 ...ls-when-failing-to-save-player-data.patch} | 2 +- ...-shield-blocking-delay-configurable.patch} | 14 ++--- .../0199-Improve-EntityShootBowEvent.patch | 45 ++++++++++++++++ .../server/0191-WitchThrowPotionEvent.patch | 30 ----------- ...0193-ItemStack-getMaxItemUseDuration.patch | 51 ------------------- .../0200-Improve-EntityShootBowEvent.patch | 47 ----------------- 17 files changed, 140 insertions(+), 167 deletions(-) rename patches/{unapplied/server/0187-Expand-World.spawnParticle-API-and-add-Builder.patch => server/0186-Expand-World.spawnParticle-API-and-add-Builder.patch} (91%) rename patches/{unapplied/server/0188-Fix-exploit-that-allowed-colored-signs-to-be-created.patch => server/0187-Fix-exploit-that-allowed-colored-signs-to-be-created.patch} (92%) rename patches/{unapplied/server/0189-EndermanAttackPlayerEvent.patch => server/0188-EndermanAttackPlayerEvent.patch} (61%) rename patches/{unapplied/server/0190-WitchConsumePotionEvent.patch => server/0189-WitchConsumePotionEvent.patch} (91%) create mode 100644 patches/server/0190-WitchThrowPotionEvent.patch rename patches/{unapplied/server/0192-WitchReadyPotionEvent.patch => server/0191-WitchReadyPotionEvent.patch} (87%) create mode 100644 patches/server/0192-ItemStack-getMaxItemUseDuration.patch rename patches/{unapplied/server/0194-Add-EntityTeleportEndGatewayEvent.patch => server/0193-Add-EntityTeleportEndGatewayEvent.patch} (75%) rename patches/{unapplied/server/0195-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch => server/0194-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch} (80%) rename patches/{unapplied/server/0196-Fix-CraftEntity-hashCode.patch => server/0195-Fix-CraftEntity-hashCode.patch} (91%) rename patches/{unapplied/server/0197-Configurable-LootPool-luck-formula.patch => server/0196-Configurable-LootPool-luck-formula.patch} (100%) rename patches/{unapplied/server/0198-Print-Error-details-when-failing-to-save-player-data.patch => server/0197-Print-Error-details-when-failing-to-save-player-data.patch} (90%) rename patches/{unapplied/server/0199-Make-shield-blocking-delay-configurable.patch => server/0198-Make-shield-blocking-delay-configurable.patch} (70%) create mode 100644 patches/server/0199-Improve-EntityShootBowEvent.patch delete mode 100644 patches/unapplied/server/0191-WitchThrowPotionEvent.patch delete mode 100644 patches/unapplied/server/0193-ItemStack-getMaxItemUseDuration.patch delete mode 100644 patches/unapplied/server/0200-Improve-EntityShootBowEvent.patch diff --git a/patches/unapplied/server/0187-Expand-World.spawnParticle-API-and-add-Builder.patch b/patches/server/0186-Expand-World.spawnParticle-API-and-add-Builder.patch similarity index 91% rename from patches/unapplied/server/0187-Expand-World.spawnParticle-API-and-add-Builder.patch rename to patches/server/0186-Expand-World.spawnParticle-API-and-add-Builder.patch index d98048d69b7a..bc692b5fa693 100644 --- a/patches/unapplied/server/0187-Expand-World.spawnParticle-API-and-add-Builder.patch +++ b/patches/server/0186-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 7c6b094de5e29cb2663e8a7072a27d7adbceb4b2..1fac100819e59d00f50e530d3a4157b56d966dba 100644 +index 21c3d771a3dd921767c2cba1e11583d015879ca9..252f1deea98a6eb83ac99adea3ea7a3c229c0f07 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1508,12 +1508,17 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1566,12 +1566,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } public 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 7c6b094de5e29cb2663e8a7072a27d7adbceb4b2..1fac100819e59d00f50e530d3a4157b5 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 1b7660a2d003bfb19ef80ba8066b6417f85328ec..3c00eaf52ab04d1396f226cc074d9dd013c57027 100644 +index 8cf4ecc5065ade18f0d13eaf0a786912ecb4dd08..4b2742c0841bd686ee637e1d6dc011e13b0df192 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -1982,8 +1982,19 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1992,8 +1992,19 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public 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/unapplied/server/0188-Fix-exploit-that-allowed-colored-signs-to-be-created.patch b/patches/server/0187-Fix-exploit-that-allowed-colored-signs-to-be-created.patch similarity index 92% rename from patches/unapplied/server/0188-Fix-exploit-that-allowed-colored-signs-to-be-created.patch rename to patches/server/0187-Fix-exploit-that-allowed-colored-signs-to-be-created.patch index 5f4980ec0474..9b28d06fce16 100644 --- a/patches/unapplied/server/0188-Fix-exploit-that-allowed-colored-signs-to-be-created.patch +++ b/patches/server/0187-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/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java -index e535fb3b5194b8412c0c26c0799340916c7542eb..394d0b03f18d55b43f091a9ae1a47e06a6fa4c0d 100644 +index cdaa050f237c6d6d5a0df0faf23daf3775249451..469d0046ba98289e98aa0f3f66e3ed27026a98a2 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java -@@ -202,9 +202,9 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C +@@ -202,9 +202,9 @@ public class SignBlockEntity extends BlockEntity { Style chatmodifier = signtext.getMessage(i, entityhuman.isTextFilteringEnabled()).getStyle(); if (entityhuman.isTextFilteringEnabled()) { diff --git a/patches/unapplied/server/0189-EndermanAttackPlayerEvent.patch b/patches/server/0188-EndermanAttackPlayerEvent.patch similarity index 61% rename from patches/unapplied/server/0189-EndermanAttackPlayerEvent.patch rename to patches/server/0188-EndermanAttackPlayerEvent.patch index a4e97fbce346..7ec73bf7df77 100644 --- a/patches/unapplied/server/0189-EndermanAttackPlayerEvent.patch +++ b/patches/server/0188-EndermanAttackPlayerEvent.patch @@ -8,23 +8,21 @@ Allow control over whether or not an enderman aggros a player. This allows you to override/extend the pumpkin/stare logic. diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -index 51e9988685b1a9a3d4d2effec63560b0ae9e8d3a..70888dd25b6a1d1ab7702d73a64a47eebafe76fe 100644 +index d7145b3a19402a03d0af02822ffcb0ef07eaa663..5f1bbb4302013c2c1788db6b64eafba2a11a373a 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -@@ -233,7 +233,15 @@ public class EnderMan extends Monster implements NeutralMob { - this.readPersistentAngerSaveData(this.level(), nbt); +@@ -234,6 +234,14 @@ public class EnderMan extends Monster implements NeutralMob { } -- boolean isLookingAtMe(Player player) { + boolean isBeingStaredBy(Player player) { + // Paper start - EndermanAttackPlayerEvent -+ private boolean isLookingAtMe(Player player) { -+ boolean shouldAttack = isLookingAtMe_check(player); ++ boolean shouldAttack = isBeingStaredBy0(player); + com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent event = new com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent((org.bukkit.entity.Enderman) getBukkitEntity(), (org.bukkit.entity.Player) player.getBukkitEntity()); + event.setCancelled(!shouldAttack); + return event.callEvent(); + } -+ private boolean isLookingAtMe_check(Player player) { -+ // Paper end - EndermanAttackPlayerEvent - ItemStack itemstack = (ItemStack) player.getInventory().armor.get(3); ++ private boolean isBeingStaredBy0(Player player) { ++ // Paper end - EndermanAttackPlayerEvent + return this.isLookingAtMe(player, 0.025D, true, false, LivingEntity.PLAYER_NOT_WEARING_DISGUISE_ITEM, new DoubleSupplier[]{this::getEyeY}); + } - if (itemstack.is(Blocks.CARVED_PUMPKIN.asItem())) { diff --git a/patches/unapplied/server/0190-WitchConsumePotionEvent.patch b/patches/server/0189-WitchConsumePotionEvent.patch similarity index 91% rename from patches/unapplied/server/0190-WitchConsumePotionEvent.patch rename to patches/server/0189-WitchConsumePotionEvent.patch index fead120a99f4..d63befdcdb85 100644 --- a/patches/unapplied/server/0190-WitchConsumePotionEvent.patch +++ b/patches/server/0189-WitchConsumePotionEvent.patch @@ -6,10 +6,10 @@ Subject: [PATCH] WitchConsumePotionEvent Fires when a witch consumes the potion in their hand diff --git a/src/main/java/net/minecraft/world/entity/monster/Witch.java b/src/main/java/net/minecraft/world/entity/monster/Witch.java -index a4d10409f06316ee628b683b231b3cc2a08bf593..f9cd71379a1d195731e7348ac6928372a4b2c29c 100644 +index 4fe13665f298503d28d866551fa7871437ca683b..93cc6a6345d8b9c349eba8bc5ba3d23cb36d76cc 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Witch.java +++ b/src/main/java/net/minecraft/world/entity/monster/Witch.java -@@ -123,6 +123,12 @@ public class Witch extends Raider implements RangedAttackMob { +@@ -124,6 +124,12 @@ public class Witch extends Raider implements RangedAttackMob { this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY); PotionContents potioncontents = (PotionContents) itemstack.get(DataComponents.POTION_CONTENTS); diff --git a/patches/server/0190-WitchThrowPotionEvent.patch b/patches/server/0190-WitchThrowPotionEvent.patch new file mode 100644 index 000000000000..fc4a2c07db53 --- /dev/null +++ b/patches/server/0190-WitchThrowPotionEvent.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Wed, 16 May 2018 20:44:58 -0400 +Subject: [PATCH] WitchThrowPotionEvent + +Fired when a witch throws a potion at a player + +diff --git a/src/main/java/net/minecraft/world/entity/monster/Witch.java b/src/main/java/net/minecraft/world/entity/monster/Witch.java +index 93cc6a6345d8b9c349eba8bc5ba3d23cb36d76cc..52475eb5fd0240e80826a52d6cd10bc1fbe8f903 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/Witch.java ++++ b/src/main/java/net/minecraft/world/entity/monster/Witch.java +@@ -237,6 +237,13 @@ public class Witch extends Raider implements RangedAttackMob { + ServerLevel worldserver = (ServerLevel) world; + ItemStack itemstack = PotionContents.createItemStack(Items.SPLASH_POTION, holder); + ++ // Paper start - WitchThrowPotionEvent ++ com.destroystokyo.paper.event.entity.WitchThrowPotionEvent event = new com.destroystokyo.paper.event.entity.WitchThrowPotionEvent((org.bukkit.entity.Witch) this.getBukkitEntity(), (org.bukkit.entity.LivingEntity) target.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); ++ if (!event.callEvent()) { ++ return; ++ } ++ itemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getPotion()); ++ // Paper end - WitchThrowPotionEvent + Projectile.spawnProjectileUsingShoot(ThrownPotion::new, worldserver, itemstack, this, d0, d1 + d3 * 0.2D, d2, 0.75F, 8.0F); + } + diff --git a/patches/unapplied/server/0192-WitchReadyPotionEvent.patch b/patches/server/0191-WitchReadyPotionEvent.patch similarity index 87% rename from patches/unapplied/server/0192-WitchReadyPotionEvent.patch rename to patches/server/0191-WitchReadyPotionEvent.patch index 8cad7e440983..5275662a1d55 100644 --- a/patches/unapplied/server/0192-WitchReadyPotionEvent.patch +++ b/patches/server/0191-WitchReadyPotionEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] WitchReadyPotionEvent diff --git a/src/main/java/net/minecraft/world/entity/monster/Witch.java b/src/main/java/net/minecraft/world/entity/monster/Witch.java -index a14e00d55930628333cc63b18727ea56dbdc4ee3..f6d01d21745391595d61b191832be4c28a3e58cb 100644 +index 52475eb5fd0240e80826a52d6cd10bc1fbe8f903..120f0c729c48ddfa598472029cdfbab3dc6db50f 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Witch.java +++ b/src/main/java/net/minecraft/world/entity/monster/Witch.java -@@ -151,7 +151,11 @@ public class Witch extends Raider implements RangedAttackMob { +@@ -152,7 +152,11 @@ public class Witch extends Raider implements RangedAttackMob { } if (holder != null) { @@ -22,10 +22,10 @@ index a14e00d55930628333cc63b18727ea56dbdc4ee3..f6d01d21745391595d61b191832be4c2 this.setUsingItem(true); if (!this.isSilent()) { diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 91180d7ad705ca97c0df43debc14b204127165d0..e3af0db8082e4e90902197f96f1c833405bf5f63 100644 +index 0a3c89dba691760c7e0be58914003cc438269a03..f05a19f868be0d685c4fbf64e1dfbefda71131ac 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1976,4 +1976,14 @@ public class CraftEventFactory { +@@ -1974,4 +1974,14 @@ public class CraftEventFactory { ).callEvent(); } // Paper end - PlayerUseUnknownEntityEvent diff --git a/patches/server/0192-ItemStack-getMaxItemUseDuration.patch b/patches/server/0192-ItemStack-getMaxItemUseDuration.patch new file mode 100644 index 000000000000..d3f513e3a92f --- /dev/null +++ b/patches/server/0192-ItemStack-getMaxItemUseDuration.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Tue, 5 Jun 2018 23:00:29 -0400 +Subject: [PATCH] ItemStack#getMaxItemUseDuration + +Allows you to determine how long it takes to use a usable/consumable item + +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +index aea09533fada5bd3d42e2cc147921167a5e7c1a5..60062ea5b18b95a14c459f2f3a0743c1e1ac0f12 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +@@ -225,6 +225,21 @@ public final class CraftItemStack extends ItemStack { + return (this.handle == null) ? Material.AIR.getMaxStackSize() : this.handle.getMaxStackSize(); + } + ++ // Paper start ++ @Override ++ public int getMaxItemUseDuration(final org.bukkit.entity.LivingEntity entity) { ++ if (handle == null) { ++ return 0; ++ } ++ ++ // Make sure plugins calling the old method don't blow up ++ if (entity == null && (handle.is(net.minecraft.world.item.Items.CROSSBOW) || handle.is(net.minecraft.world.item.Items.GOAT_HORN))) { ++ throw new UnsupportedOperationException("This item requires an entity to determine the max use duration"); ++ } ++ return handle.getUseDuration(entity != null ? ((org.bukkit.craftbukkit.entity.CraftLivingEntity) entity).getHandle() : null); ++ } ++ // Paper end ++ + @Override + public void addUnsafeEnchantment(Enchantment ench, int level) { + Preconditions.checkArgument(ench != null, "Enchantment cannot be null"); diff --git a/patches/unapplied/server/0194-Add-EntityTeleportEndGatewayEvent.patch b/patches/server/0193-Add-EntityTeleportEndGatewayEvent.patch similarity index 75% rename from patches/unapplied/server/0194-Add-EntityTeleportEndGatewayEvent.patch rename to patches/server/0193-Add-EntityTeleportEndGatewayEvent.patch index 56df3551eaa2..2a5ab478ab9b 100644 --- a/patches/unapplied/server/0194-Add-EntityTeleportEndGatewayEvent.patch +++ b/patches/server/0193-Add-EntityTeleportEndGatewayEvent.patch @@ -5,13 +5,13 @@ Subject: [PATCH] Add EntityTeleportEndGatewayEvent diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 946f289e0e681524c6fde696921965dbdedda372..d6017d9d71fb4b3a3df6eaa44da0ebda54c83da4 100644 +index 99794276626d26849150d4956abbbc2296543907..087f030985180b91a809fb45244e23106da62e34 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -3301,8 +3301,16 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - if (!this.isRemoved()) { +@@ -3429,8 +3429,16 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // CraftBukkit start - Location to = new Location(teleportTarget.newLevel().getWorld(), teleportTarget.pos().x, teleportTarget.pos().y, teleportTarget.pos().z, teleportTarget.yRot(), teleportTarget.xRot()); + PositionMoveRotation absolutePosition = PositionMoveRotation.calculateAbsolute(PositionMoveRotation.of(this), PositionMoveRotation.of(teleportTarget), teleportTarget.relatives()); + Location to = CraftLocation.toBukkit(absolutePosition.position(), teleportTarget.newLevel().getWorld(), absolutePosition.yRot(), absolutePosition.xRot()); - EntityTeleportEvent teleEvent = CraftEventFactory.callEntityTeleportEvent(this, to); - if (teleEvent.isCancelled()) { + // Paper start - gateway-specific teleport event @@ -26,4 +26,4 @@ index 946f289e0e681524c6fde696921965dbdedda372..d6017d9d71fb4b3a3df6eaa44da0ebda + if (teleEvent.isCancelled() || teleEvent.getTo() == null) { return null; } - to = teleEvent.getTo(); + if (!to.equals(teleEvent.getTo())) { diff --git a/patches/unapplied/server/0195-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch b/patches/server/0194-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch similarity index 80% rename from patches/unapplied/server/0195-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch rename to patches/server/0194-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch index 100c67ec88f1..70526b8bcbbb 100644 --- a/patches/unapplied/server/0195-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch +++ b/patches/server/0194-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Unset Ignited flag on cancel of Explosion Event Otherwise the creeper infinite explodes 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 39486215ac080220a6018a35a8437092dbc8fe9d..95df4ac539ec284654c53d39955870a46478c27d 100644 +index 31405c3a95e8e8217a6efede1e4599c14583081f..0552cc23391ec305754339d000630ccab0729100 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java +++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java -@@ -278,6 +278,7 @@ public class Creeper extends Monster implements PowerableMob { +@@ -278,6 +278,7 @@ public class Creeper extends Monster { // CraftBukkit start } else { this.swell = 0; diff --git a/patches/unapplied/server/0196-Fix-CraftEntity-hashCode.patch b/patches/server/0195-Fix-CraftEntity-hashCode.patch similarity index 91% rename from patches/unapplied/server/0196-Fix-CraftEntity-hashCode.patch rename to patches/server/0195-Fix-CraftEntity-hashCode.patch index 56dcc01026c3..aa86c5b03608 100644 --- a/patches/unapplied/server/0196-Fix-CraftEntity-hashCode.patch +++ b/patches/server/0195-Fix-CraftEntity-hashCode.patch @@ -21,10 +21,10 @@ 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 69b5946625a53a1351ffc4bdf61c6874949bbeae..bddf98bdf60473eb1d2e533cf533ed7eee797aaa 100644 +index 0480fbeffd19011d3cd63021225f376c464b480c..0e5cc680ee2418ec2af5fc3e215618ad4e768ed0 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -502,14 +502,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -503,14 +503,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return false; } final CraftEntity other = (CraftEntity) obj; diff --git a/patches/unapplied/server/0197-Configurable-LootPool-luck-formula.patch b/patches/server/0196-Configurable-LootPool-luck-formula.patch similarity index 100% rename from patches/unapplied/server/0197-Configurable-LootPool-luck-formula.patch rename to patches/server/0196-Configurable-LootPool-luck-formula.patch diff --git a/patches/unapplied/server/0198-Print-Error-details-when-failing-to-save-player-data.patch b/patches/server/0197-Print-Error-details-when-failing-to-save-player-data.patch similarity index 90% rename from patches/unapplied/server/0198-Print-Error-details-when-failing-to-save-player-data.patch rename to patches/server/0197-Print-Error-details-when-failing-to-save-player-data.patch index 19f2e71553a0..0885ca8d10ba 100644 --- a/patches/unapplied/server/0198-Print-Error-details-when-failing-to-save-player-data.patch +++ b/patches/server/0197-Print-Error-details-when-failing-to-save-player-data.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Print Error details when failing to save player data diff --git a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java -index e11c8523e633d2a8e3cea7ecd54978b2958b9684..1d287dd7379e56f7fd4b425880b850cd843f5789 100644 +index cd013567dd6224c86c0f1813d8a3d5fb7b8cabb5..b54a3741cd3ba615c83c98985cb4b3c4c586ed7a 100644 --- a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java +++ b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java @@ -47,7 +47,7 @@ public class PlayerDataStorage { diff --git a/patches/unapplied/server/0199-Make-shield-blocking-delay-configurable.patch b/patches/server/0198-Make-shield-blocking-delay-configurable.patch similarity index 70% rename from patches/unapplied/server/0199-Make-shield-blocking-delay-configurable.patch rename to patches/server/0198-Make-shield-blocking-delay-configurable.patch index c9b6092f8f7d..8bd30c1391bf 100644 --- a/patches/unapplied/server/0199-Make-shield-blocking-delay-configurable.patch +++ b/patches/server/0198-Make-shield-blocking-delay-configurable.patch @@ -5,17 +5,17 @@ Subject: [PATCH] Make shield blocking delay configurable diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 7a7c404778757e6778305c9f8334a4fba1f466a6..d58439f85f4d3a9b863ecadb3b42b2ee3270a772 100644 +index 76b71af07a311bc415b36f517afab31505a14483..0a4d2abc5b70c5e4e93dc06fe112e2398d9916e7 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3969,12 +3969,24 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4103,12 +4103,24 @@ public abstract class LivingEntity extends Entity implements Attackable { if (this.isUsingItem() && !this.useItem.isEmpty()) { Item item = this.useItem.getItem(); -- return item.getUseAnimation(this.useItem) != UseAnim.BLOCK ? false : item.getUseDuration(this.useItem, this) - this.useItemRemaining >= 5; -+ return item.getUseAnimation(this.useItem) != UseAnim.BLOCK ? false : item.getUseDuration(this.useItem, this) - this.useItemRemaining >= getShieldBlockingDelay(); // Paper - Make shield blocking delay configurable +- return item.getUseAnimation(this.useItem) != ItemUseAnimation.BLOCK ? null : (item.getUseDuration(this.useItem, this) - this.useItemRemaining < 5 ? null : this.useItem); ++ return item.getUseAnimation(this.useItem) != ItemUseAnimation.BLOCK ? null : (item.getUseDuration(this.useItem, this) - this.useItemRemaining < getShieldBlockingDelay() ? null : this.useItem); // Paper - Make shield blocking delay configurable } else { - return false; + return null; } } @@ -35,10 +35,10 @@ index 7a7c404778757e6778305c9f8334a4fba1f466a6..d58439f85f4d3a9b863ecadb3b42b2ee return this.isShiftKeyDown(); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 7a01569f62b3b27a9eb6def0e2ec72e1d392258d..73c72b8cdece357193afb3c5f474e055086311ea 100644 +index 452fe788152f7c38ab4b6c627e3ba37da3d9b9d9..e5186fbd4030d7b39443090b711e855dcbc39426 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -853,5 +853,15 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -873,5 +873,15 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { public void setArrowsStuck(final int arrows) { this.getHandle().setArrowCount(arrows); } diff --git a/patches/server/0199-Improve-EntityShootBowEvent.patch b/patches/server/0199-Improve-EntityShootBowEvent.patch new file mode 100644 index 000000000000..213e6f61c1f2 --- /dev/null +++ b/patches/server/0199-Improve-EntityShootBowEvent.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sat, 15 Jun 2013 19:51:17 -0400 +Subject: [PATCH] Improve EntityShootBowEvent + +Adds missing call to Illagers and also adds Arrow ItemStack to skeletons + +== AT == +public net.minecraft.world.entity.projectile.AbstractArrow getPickupItem()Lnet.minecraft.world.item.ItemStack; + +diff --git a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java +index b16979ae9ad9636d91d3f2cd80baf01250ec534d..8f63e27d904abb33492daf627d48d33d1193deef 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java ++++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java +@@ -208,7 +208,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo + + if (world instanceof ServerLevel worldserver) { + // CraftBukkit start +- org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), null, entityarrow, net.minecraft.world.InteractionHand.MAIN_HAND, 0.8F, true); ++ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), entityarrow.getPickupItem(), entityarrow, net.minecraft.world.InteractionHand.MAIN_HAND, 0.8F, true); // Paper - improve entity shhot bow event - add arrow stack to event + if (event.isCancelled()) { + event.getProjectile().remove(); + return; +diff --git a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java +index 60388ab18d7a4ecb235e54ecfdb4088b690a6178..db3aac9ba711dcd18ffc35c4a745ecaec89d0166 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java ++++ b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java +@@ -184,7 +184,17 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob { + Level world = this.level(); + + if (world instanceof ServerLevel worldserver) { ++ // Paper start - EntityShootBowEvent ++ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), entityarrow.getPickupItem(), entityarrow, target.getUsedItemHand(), 0.8F, true); ++ if (event.isCancelled()) { ++ event.getProjectile().remove(); ++ return; ++ } ++ ++ if (event.getProjectile() == entityarrow.getBukkitEntity()) { + Projectile.spawnProjectileUsingShoot(entityarrow, worldserver, itemstack1, d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, (float) (14 - worldserver.getDifficulty().getId() * 4)); ++ } ++ // Paper end - EntityShootBowEvent + } + + this.playSound(SoundEvents.SKELETON_SHOOT, 1.0F, 1.0F / (this.getRandom().nextFloat() * 0.4F + 0.8F)); diff --git a/patches/unapplied/server/0191-WitchThrowPotionEvent.patch b/patches/unapplied/server/0191-WitchThrowPotionEvent.patch deleted file mode 100644 index d6be87ca72d7..000000000000 --- a/patches/unapplied/server/0191-WitchThrowPotionEvent.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Wed, 16 May 2018 20:44:58 -0400 -Subject: [PATCH] WitchThrowPotionEvent - -Fired when a witch throws a potion at a player - -diff --git a/src/main/java/net/minecraft/world/entity/monster/Witch.java b/src/main/java/net/minecraft/world/entity/monster/Witch.java -index f9cd71379a1d195731e7348ac6928372a4b2c29c..a14e00d55930628333cc63b18727ea56dbdc4ee3 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/Witch.java -+++ b/src/main/java/net/minecraft/world/entity/monster/Witch.java -@@ -230,9 +230,16 @@ public class Witch extends Raider implements RangedAttackMob { - holder = Potions.WEAKNESS; - } - -+ // Paper start - WitchThrowPotionEvent -+ ItemStack potion = PotionContents.createItemStack(Items.SPLASH_POTION, holder); -+ com.destroystokyo.paper.event.entity.WitchThrowPotionEvent event = new com.destroystokyo.paper.event.entity.WitchThrowPotionEvent((org.bukkit.entity.Witch) this.getBukkitEntity(), (org.bukkit.entity.LivingEntity) target.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(potion)); -+ if (!event.callEvent()) { -+ return; -+ } -+ potion = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getPotion()); - ThrownPotion entitypotion = new ThrownPotion(this.level(), this); -- -- entitypotion.setItem(PotionContents.createItemStack(Items.SPLASH_POTION, holder)); -+ entitypotion.setItem(potion); -+ // Paper end - WitchThrowPotionEvent - entitypotion.setXRot(entitypotion.getXRot() - -20.0F); - entitypotion.shoot(d0, d1 + d3 * 0.2D, d2, 0.75F, 8.0F); - if (!this.isSilent()) { diff --git a/patches/unapplied/server/0193-ItemStack-getMaxItemUseDuration.patch b/patches/unapplied/server/0193-ItemStack-getMaxItemUseDuration.patch deleted file mode 100644 index 67996fcc593d..000000000000 --- a/patches/unapplied/server/0193-ItemStack-getMaxItemUseDuration.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Tue, 5 Jun 2018 23:00:29 -0400 -Subject: [PATCH] ItemStack#getMaxItemUseDuration - -Allows you to determine how long it takes to use a usable/consumable item - -diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index 6c76aeddb34239a5acc204a17b2aa2d80e6b2c88..e8a455eb5e17bcfcae3f03664f2b47773fbdf37e 100644 ---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -@@ -7,14 +7,17 @@ import net.minecraft.core.Holder; - import net.minecraft.core.component.DataComponentPatch; - import net.minecraft.core.component.DataComponents; - import net.minecraft.world.item.Item; -+import net.minecraft.world.item.Items; - import net.minecraft.world.item.enchantment.EnchantmentHelper; - import net.minecraft.world.item.enchantment.ItemEnchantments; - import org.bukkit.Material; - import org.bukkit.configuration.serialization.DelegateDeserialization; - import org.bukkit.craftbukkit.enchantments.CraftEnchantment; -+import org.bukkit.craftbukkit.entity.CraftLivingEntity; - import org.bukkit.craftbukkit.util.CraftLegacy; - import org.bukkit.craftbukkit.util.CraftMagicNumbers; - import org.bukkit.enchantments.Enchantment; -+import org.bukkit.entity.LivingEntity; - import org.bukkit.inventory.ItemStack; - import org.bukkit.inventory.meta.ItemMeta; - import org.bukkit.material.MaterialData; -@@ -210,6 +213,21 @@ public final class CraftItemStack extends ItemStack { - return (this.handle == null) ? Material.AIR.getMaxStackSize() : this.handle.getMaxStackSize(); - } - -+ // Paper start -+ @Override -+ public int getMaxItemUseDuration(final LivingEntity entity) { -+ if (handle == null) { -+ return 0; -+ } -+ -+ // Make sure plugins calling the old method don't blow up -+ if (entity == null && handle.is(Items.CROSSBOW)) { -+ throw new UnsupportedOperationException("This item requires an entity to determine the max use duration"); -+ } -+ return handle.getUseDuration(entity != null ? ((CraftLivingEntity) entity).getHandle() : null); -+ } -+ // Paper end -+ - @Override - public void addUnsafeEnchantment(Enchantment ench, int level) { - Preconditions.checkArgument(ench != null, "Enchantment cannot be null"); diff --git a/patches/unapplied/server/0200-Improve-EntityShootBowEvent.patch b/patches/unapplied/server/0200-Improve-EntityShootBowEvent.patch deleted file mode 100644 index cf1605426243..000000000000 --- a/patches/unapplied/server/0200-Improve-EntityShootBowEvent.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Sat, 15 Jun 2013 19:51:17 -0400 -Subject: [PATCH] Improve EntityShootBowEvent - -Adds missing call to Illagers and also adds Arrow ItemStack to skeletons - -== AT == -public net.minecraft.world.entity.projectile.AbstractArrow getPickupItem()Lnet.minecraft.world.item.ItemStack; - -diff --git a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java -index 1bf013a10502395d9f432f80c517d5c9a50f5eab..aec440d32eb97fa8ce738b98dae1cdc346e8a59b 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java -+++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java -@@ -205,7 +205,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo - - entityarrow.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, (float) (14 - this.level().getDifficulty().getId() * 4)); - // CraftBukkit start -- org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), null, entityarrow, net.minecraft.world.InteractionHand.MAIN_HAND, 0.8F, true); -+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), entityarrow.getPickupItem(), entityarrow, net.minecraft.world.InteractionHand.MAIN_HAND, 0.8F, true); // Paper - if (event.isCancelled()) { - event.getProjectile().remove(); - return; -diff --git a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java -index 93e3454de0b0d62895f165b0772526f3eae1e333..c858556ea457931aa14e338e20672cb50cb19f0e 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java -+++ b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java -@@ -185,8 +185,18 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob { - double d3 = Math.sqrt(d0 * d0 + d2 * d2); - - entityarrow.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, (float) (14 - this.level().getDifficulty().getId() * 4)); -+ // Paper start - EntityShootBowEvent -+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), entityarrow.getPickupItem(), entityarrow, target.getUsedItemHand(), 0.8F, true); -+ if (event.isCancelled()) { -+ event.getProjectile().remove(); -+ return; -+ } -+ -+ if (event.getProjectile() == entityarrow.getBukkitEntity()) { -+ this.level().addFreshEntity(entityarrow); -+ } -+ // Paper end - EntityShootBowEvent - this.playSound(SoundEvents.SKELETON_SHOOT, 1.0F, 1.0F / (this.getRandom().nextFloat() * 0.4F + 0.8F)); -- this.level().addFreshEntity(entityarrow); - } - - @Override From dc5af4848a4c391d3622ae7b2c9549b8a753b6c7 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Wed, 23 Oct 2024 11:04:00 +0200 Subject: [PATCH 011/119] Breakpoint before projectile mess --- .../0200-PlayerReadyArrowEvent.patch} | 4 +- .../0201-Add-entity-knockback-events.patch} | 98 +++++++-------- .../server/0202-Expand-Explosions-API.patch | 87 +++++++++++++ .../0203-LivingEntity-Active-Item-API.patch} | 4 +- .../0204-RangedEntity-API.patch} | 0 ...o-disable-ender-dragon-legacy-check.patch} | 4 +- ...-Implement-World.getEntity-UUID-API.patch} | 4 +- ...0207-InventoryCloseEvent-Reason-API.patch} | 44 +++---- .../0208-Vex-get-setSummoner-API.patch} | 0 ...more-information-to-Entity.toString.patch} | 6 +- .../0210-EnderDragon-Events.patch} | 18 +-- .../server/0203-Expand-Explosions-API.patch | 116 ------------------ 12 files changed, 178 insertions(+), 207 deletions(-) rename patches/{unapplied/server/0201-PlayerReadyArrowEvent.patch => server/0200-PlayerReadyArrowEvent.patch} (93%) rename patches/{unapplied/server/0202-Add-entity-knockback-events.patch => server/0201-Add-entity-knockback-events.patch} (83%) create mode 100644 patches/server/0202-Expand-Explosions-API.patch rename patches/{unapplied/server/0204-LivingEntity-Active-Item-API.patch => server/0203-LivingEntity-Active-Item-API.patch} (94%) rename patches/{unapplied/server/0205-RangedEntity-API.patch => server/0204-RangedEntity-API.patch} (100%) rename patches/{unapplied/server/0206-Add-config-to-disable-ender-dragon-legacy-check.patch => server/0205-Add-config-to-disable-ender-dragon-legacy-check.patch} (89%) rename patches/{unapplied/server/0207-Implement-World.getEntity-UUID-API.patch => server/0206-Implement-World.getEntity-UUID-API.patch} (85%) rename patches/{unapplied/server/0208-InventoryCloseEvent-Reason-API.patch => server/0207-InventoryCloseEvent-Reason-API.patch} (87%) rename patches/{unapplied/server/0209-Vex-get-setSummoner-API.patch => server/0208-Vex-get-setSummoner-API.patch} (100%) rename patches/{unapplied/server/0210-add-more-information-to-Entity.toString.patch => server/0209-add-more-information-to-Entity.toString.patch} (88%) rename patches/{unapplied/server/0211-EnderDragon-Events.patch => server/0210-EnderDragon-Events.patch} (83%) delete mode 100644 patches/unapplied/server/0203-Expand-Explosions-API.patch diff --git a/patches/unapplied/server/0201-PlayerReadyArrowEvent.patch b/patches/server/0200-PlayerReadyArrowEvent.patch similarity index 93% rename from patches/unapplied/server/0201-PlayerReadyArrowEvent.patch rename to patches/server/0200-PlayerReadyArrowEvent.patch index 37f2fbca4e11..8d16572d48da 100644 --- a/patches/unapplied/server/0201-PlayerReadyArrowEvent.patch +++ b/patches/server/0200-PlayerReadyArrowEvent.patch @@ -7,10 +7,10 @@ Called when a player is firing a bow and the server is choosing an arrow to use. Plugins can skip selection of certain arrows and control which is used. diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index 00fecf255214d87837867b8743cc8f161ebfcb4c..d6bbeaf3833a4c44ed05243445edd813e3f15dcb 100644 +index 605f043bb132b21ff263ba7ab31a0f468a912d13..df0cfd316d24e285f927c713ab1f9a912857928c 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -2232,18 +2232,29 @@ public abstract class Player extends LivingEntity { +@@ -2185,18 +2185,29 @@ public abstract class Player extends LivingEntity { return ImmutableList.of(Pose.STANDING, Pose.CROUCHING, Pose.SWIMMING); } diff --git a/patches/unapplied/server/0202-Add-entity-knockback-events.patch b/patches/server/0201-Add-entity-knockback-events.patch similarity index 83% rename from patches/unapplied/server/0202-Add-entity-knockback-events.patch rename to patches/server/0201-Add-entity-knockback-events.patch index 699b9c97039b..c41689a1967c 100644 --- a/patches/unapplied/server/0202-Add-entity-knockback-events.patch +++ b/patches/server/0201-Add-entity-knockback-events.patch @@ -11,10 +11,10 @@ Co-authored-by: aerulion Co-authored-by: Jake Potrebic diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index fd49b9d739b1bbab8cf110659cb83bad03b56102..a2b727dea997ed0d7b1ef677a94b5957f12d5abb 100644 +index 087f030985180b91a809fb45244e23106da62e34..011006bc2e88a9fec98796f939c07d884b92126b 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -1962,7 +1962,21 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2050,7 +2050,21 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public void push(double deltaX, double deltaY, double deltaZ) { @@ -38,10 +38,10 @@ index fd49b9d739b1bbab8cf110659cb83bad03b56102..a2b727dea997ed0d7b1ef677a94b5957 } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index cccc60602360f25f0aeddbd16dad2bb63a1728a8..ada79af49d1cafe25ca6c1fb456e1c4c3a42cb73 100644 +index 0a4d2abc5b70c5e4e93dc06fe112e2398d9916e7..c9d7589a18e9cee204f4e52368a60aa421c1e150 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1528,7 +1528,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1565,7 +1565,7 @@ public abstract class LivingEntity extends Entity implements Attackable { d1 = source.getSourcePosition().z() - this.getZ(); } @@ -50,7 +50,7 @@ index cccc60602360f25f0aeddbd16dad2bb63a1728a8..ada79af49d1cafe25ca6c1fb456e1c4c if (!flag) { this.indicateDamage(d0, d1); } -@@ -1581,7 +1581,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1622,7 +1622,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } protected void blockedByShield(LivingEntity target) { @@ -59,7 +59,7 @@ index cccc60602360f25f0aeddbd16dad2bb63a1728a8..ada79af49d1cafe25ca6c1fb456e1c4c } private boolean checkTotemDeathProtection(DamageSource source) { -@@ -1842,10 +1842,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1908,10 +1908,10 @@ public abstract class LivingEntity extends Entity implements Attackable { public void knockback(double strength, double x, double z) { // CraftBukkit start - EntityKnockbackEvent @@ -72,7 +72,7 @@ index cccc60602360f25f0aeddbd16dad2bb63a1728a8..ada79af49d1cafe25ca6c1fb456e1c4c d0 *= 1.0D - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE); if (true || d0 > 0.0D) { // CraftBukkit - Call event even when force is 0 //this.hasImpulse = true; // CraftBukkit - Move down -@@ -1858,13 +1858,17 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1924,13 +1924,17 @@ public abstract class LivingEntity extends Entity implements Attackable { Vec3 vec3d1 = (new Vec3(d1, 0.0D, d2)).normalize().scale(d0); @@ -93,20 +93,20 @@ index cccc60602360f25f0aeddbd16dad2bb63a1728a8..ada79af49d1cafe25ca6c1fb456e1c4c } } diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 62c3b3d992aff2aa20857e2b3bee464a377a0857..25a71cc5ca8cf8a5070cd24eb56fe0d79e765669 100644 +index 51381c32c8650400331a122a4b6c8d95c9d0632b..2b8bfccbf520f9a356f816522ac3a5caa51e44e1 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -1695,7 +1695,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab - if (f1 > 0.0F && target instanceof LivingEntity) { - LivingEntity entityliving = (LivingEntity) target; +@@ -1685,7 +1685,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab + if (f1 > 0.0F && target instanceof LivingEntity) { + entityliving = (LivingEntity) target; - entityliving.knockback((double) (f1 * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this, org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause.ENTITY_ATTACK); // CraftBukkit + entityliving.knockback((double) (f1 * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // CraftBukkit // Paper - knockback events this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D)); } diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java b/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java -index a7601321fd2cbf62b45162a2d3ee9d59c2f7d077..2d0ca87649702437aa2d7acd8d2cbb57231c77de 100644 +index 8bf5f18b5835ac97114dfea7dde3876c13433ab4..de81e34cf65318fa5e3034405719ff2a2b05458c 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java @@ -89,7 +89,7 @@ public class RamTarget extends Behavior { @@ -119,11 +119,11 @@ index a7601321fd2cbf62b45162a2d3ee9d59c2f7d077..2d0ca87649702437aa2d7acd8d2cbb57 world.playSound(null, entity, this.getImpactSound.apply(entity), SoundSource.NEUTRAL, 1.0F, 1.0F); } else if (this.hasRammedHornBreakingBlock(world, entity)) { diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java b/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java -index aa8909498c26f095060a1df364b9e20d964a6cc3..30502849f79ce0f472e4289043c7d8ec460d3f20 100644 +index dbae113f3447f66e154b302ce0634b0fe446381c..d0fb32feb10f75444e3ed0a50c70ef6f12fb8e18 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java @@ -83,7 +83,7 @@ public class SonicBoom extends Behavior { - if (target.hurt(world.damageSources().sonicBoom(entity), 10.0F)) { + if (target.hurtServer(world, world.damageSources().sonicBoom(entity), 10.0F)) { double d = 0.5 * (1.0 - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE)); double e = 2.5 * (1.0 - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE)); - target.push(vec33.x() * e, vec33.y() * d, vec33.z() * e); @@ -132,10 +132,10 @@ index aa8909498c26f095060a1df364b9e20d964a6cc3..30502849f79ce0f472e4289043c7d8ec }); } diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -index f8283405b3c5bd43746a5738be55f600beea40e3..b02a77b486f8d5eee31850de4a1b033fe6a107c7 100644 +index 0012ab1f56180081d210c8836e2a59d543b950b8..ba1bb0f82634054e02c5f4bc062c1822a356e2a6 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -@@ -465,7 +465,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -441,7 +441,7 @@ public class EnderDragon extends Mob implements Enemy { double d3 = entity.getZ() - d1; double d4 = Math.max(d2 * d2 + d3 * d3, 0.1D); @@ -145,23 +145,23 @@ index f8283405b3c5bd43746a5738be55f600beea40e3..b02a77b486f8d5eee31850de4a1b033f DamageSource damagesource = this.damageSources().mobAttack(this); diff --git a/src/main/java/net/minecraft/world/entity/decoration/BlockAttachedEntity.java b/src/main/java/net/minecraft/world/entity/decoration/BlockAttachedEntity.java -index cf65d8ef8d69a24ceb44d2a5d84c83dfee322a1d..e4eece7bbd14514ec60da26a8744672baa8956f9 100644 +index 19f9f4bceca158d9b35be2cdc4d7aa502f44a4b9..cd0a2270b58b6c0dba67270e7e1d1ba253eb7953 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/BlockAttachedEntity.java +++ b/src/main/java/net/minecraft/world/entity/decoration/BlockAttachedEntity.java -@@ -142,7 +142,7 @@ public abstract class BlockAttachedEntity extends Entity { +@@ -161,7 +161,7 @@ public abstract class BlockAttachedEntity extends Entity { } @Override - public void push(double deltaX, double deltaY, double deltaZ) { + public void push(double deltaX, double deltaY, double deltaZ, @Nullable Entity pushingEntity) { // Paper - override correct overload - if (false && !this.level().isClientSide && !this.isRemoved() && deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ > 0.0D) { // CraftBukkit - not needed - this.kill(); - this.dropItem((Entity) null); + Level world = this.level(); + + if (world instanceof ServerLevel worldserver) { diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -index c6e1e1cb3bf36e86dd910037dc7e70498c1c311f..84dcd662981b1eeb03128e7717f6af44c2b9cff6 100644 +index 6a90feef8eb2d65c925c44bc97305a51e3fb7cf0..7dfbcb2ed831cff5d002d79fb81514e6abf587a4 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -@@ -128,9 +128,9 @@ public class ItemFrame extends HangingEntity { +@@ -129,9 +129,9 @@ public class ItemFrame extends HangingEntity { } @Override @@ -174,10 +174,10 @@ index c6e1e1cb3bf36e86dd910037dc7e70498c1c311f..84dcd662981b1eeb03128e7717f6af44 } diff --git a/src/main/java/net/minecraft/world/entity/monster/Ravager.java b/src/main/java/net/minecraft/world/entity/monster/Ravager.java -index 1954c95e65abd98973393c636f5257b2a9f27377..4d91bc4b90a208fec789325dbcec8cc56d1a2a8b 100644 +index c4397afa53a36ecf867525c4dcf2231a52d058dd..32973d9c7bf4c4105d7bd82d3723e0b70cd79644 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Ravager.java +++ b/src/main/java/net/minecraft/world/entity/monster/Ravager.java -@@ -258,7 +258,7 @@ public class Ravager extends Raider { +@@ -292,7 +292,7 @@ public class Ravager extends Raider { double d1 = entity.getZ() - this.getZ(); double d2 = Math.max(d0 * d0 + d1 * d1, 0.001D); @@ -187,10 +187,10 @@ index 1954c95e65abd98973393c636f5257b2a9f27377..4d91bc4b90a208fec789325dbcec8cc5 @Override diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java -index a6c33abcbbfc0851c8fa979163de145a578f97a6..18389b3befe31b224010e55244fbcb7c2802845e 100644 +index 8b80f5c2749106f634d962fd0f381aa20e7ef335..a1e3375519fe676b14788d6729a7e71d089cca37 100644 --- a/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java +++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java -@@ -47,7 +47,7 @@ public interface HoglinBase { +@@ -45,7 +45,7 @@ public interface HoglinBase { double j = f * (double)(attacker.level().random.nextFloat() * 0.5F + 0.2F); Vec3 vec3 = new Vec3(g, 0.0, h).normalize().scale(j).yRot(i); double k = f * (double)attacker.level().random.nextFloat() * 0.5; @@ -200,10 +200,10 @@ index a6c33abcbbfc0851c8fa979163de145a578f97a6..18389b3befe31b224010e55244fbcb7c } } diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index d6bbeaf3833a4c44ed05243445edd813e3f15dcb..1b13096da1f0bc49efe25677ec24e6abe7ff2879 100644 +index df0cfd316d24e285f927c713ab1f9a912857928c..ba0ea4d6b67c9c52f170e0235e4b972aad3ce211 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -1301,9 +1301,9 @@ public abstract class Player extends LivingEntity { +@@ -1271,9 +1271,9 @@ public abstract class Player extends LivingEntity { if (target instanceof LivingEntity) { LivingEntity entityliving1 = (LivingEntity) target; @@ -215,7 +215,7 @@ index d6bbeaf3833a4c44ed05243445edd813e3f15dcb..1b13096da1f0bc49efe25677ec24e6ab } this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D)); -@@ -1331,7 +1331,7 @@ public abstract class Player extends LivingEntity { +@@ -1301,7 +1301,7 @@ public abstract class Player extends LivingEntity { continue; } // CraftBukkit end @@ -225,10 +225,10 @@ index d6bbeaf3833a4c44ed05243445edd813e3f15dcb..1b13096da1f0bc49efe25677ec24e6ab Level world = this.level(); diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -index 230040bef7d2cf9a463cfd9cb3b1b1aa208a7119..6c79997ba46e641de5aa12ff8a3d790d04a5a475 100644 +index a1b1c6385d3a1fbe38f5ae4471b8e4f6ef2c80b3..78053060dbff7f8a859f9fecb356491f497eed7e 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -@@ -519,7 +519,7 @@ public abstract class AbstractArrow extends Projectile { +@@ -553,7 +553,7 @@ public abstract class AbstractArrow extends Projectile { Vec3 vec3d = this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D).normalize().scale(d0 * 0.6D * d1); if (vec3d.lengthSqr() > 0.0D) { @@ -238,10 +238,10 @@ index 230040bef7d2cf9a463cfd9cb3b1b1aa208a7119..6c79997ba46e641de5aa12ff8a3d790d } diff --git a/src/main/java/net/minecraft/world/entity/projectile/windcharge/AbstractWindCharge.java b/src/main/java/net/minecraft/world/entity/projectile/windcharge/AbstractWindCharge.java -index de2bc78415ab4efb651030be6560d9c9778a1d17..1e00df3fa3c3b61daa3d59ee1173269a6eae3a43 100644 +index 6541ab0d8da28785b19fa50d18d6a484ea38cef8..a325a223d06e155c01f664562db0edd0b180e356 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/windcharge/AbstractWindCharge.java +++ b/src/main/java/net/minecraft/world/entity/projectile/windcharge/AbstractWindCharge.java -@@ -103,7 +103,7 @@ public abstract class AbstractWindCharge extends AbstractHurtingProjectile imple +@@ -101,7 +101,7 @@ public abstract class AbstractWindCharge extends AbstractHurtingProjectile imple } @Override @@ -250,33 +250,33 @@ index de2bc78415ab4efb651030be6560d9c9778a1d17..1e00df3fa3c3b61daa3d59ee1173269a public abstract void explode(Vec3 pos); -diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index 6476c644d3da824c5ee4190cb45cde678ff1188f..b216140a8be65e210250358af8daf49344850f20 100644 ---- a/src/main/java/net/minecraft/world/level/Explosion.java -+++ b/src/main/java/net/minecraft/world/level/Explosion.java -@@ -297,13 +297,10 @@ public class Explosion { +diff --git a/src/main/java/net/minecraft/world/level/ServerExplosion.java b/src/main/java/net/minecraft/world/level/ServerExplosion.java +index 3afacd201683f46fd75cd6f9a7f3d43a7050cf4a..9f37d7284c81d529551107e2836627977efabd65 100644 +--- a/src/main/java/net/minecraft/world/level/ServerExplosion.java ++++ b/src/main/java/net/minecraft/world/level/ServerExplosion.java +@@ -258,13 +258,10 @@ public class ServerExplosion implements Explosion { // CraftBukkit start - Call EntityKnockbackEvent if (entity instanceof LivingEntity) { -- Vec3 result = entity.getDeltaMovement().add(vec3d1); -- org.bukkit.event.entity.EntityKnockbackEvent event = CraftEventFactory.callEntityKnockbackEvent((org.bukkit.craftbukkit.entity.CraftLivingEntity) entity.getBukkitEntity(), this.source, org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause.EXPLOSION, d13, vec3d1, result.x, result.y, result.z); +- Vec3 result = entity.getDeltaMovement().add(vec3d); +- org.bukkit.event.entity.EntityKnockbackEvent event = CraftEventFactory.callEntityKnockbackEvent((org.bukkit.craftbukkit.entity.CraftLivingEntity) entity.getBukkitEntity(), this.source, org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause.EXPLOSION, d6, vec3d, result.x, result.y, result.z); - - // SPIGOT-7640: Need to subtract entity movement from the event result, - // since the code below (the setDeltaMovement call as well as the hitPlayers map) - // want the vector to be the relative velocity will the event provides the absolute velocity -- vec3d1 = (event.isCancelled()) ? Vec3.ZERO : new Vec3(event.getFinalKnockback().getX(), event.getFinalKnockback().getY(), event.getFinalKnockback().getZ()).subtract(entity.getDeltaMovement()); -+ // Paper start - knockback events -+ io.papermc.paper.event.entity.EntityKnockbackEvent event = CraftEventFactory.callEntityKnockbackEvent((org.bukkit.craftbukkit.entity.CraftLivingEntity) entity.getBukkitEntity(), this.source, this.damageSource.getEntity() != null ? this.damageSource.getEntity() : this.source, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.EXPLOSION, d13, vec3d1); -+ vec3d1 = event.isCancelled() ? Vec3.ZERO : org.bukkit.craftbukkit.util.CraftVector.toNMS(event.getKnockback()); -+ // Paper end - knockback events +- vec3d = (event.isCancelled()) ? Vec3.ZERO : new Vec3(event.getFinalKnockback().getX(), event.getFinalKnockback().getY(), event.getFinalKnockback().getZ()).subtract(entity.getDeltaMovement()); ++ // Paper start - knockback events ++ io.papermc.paper.event.entity.EntityKnockbackEvent event = CraftEventFactory.callEntityKnockbackEvent((org.bukkit.craftbukkit.entity.CraftLivingEntity) entity.getBukkitEntity(), this.source, this.damageSource.getEntity() != null ? this.damageSource.getEntity() : this.source, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.EXPLOSION, d6, vec3d); ++ vec3d = event.isCancelled() ? Vec3.ZERO : org.bukkit.craftbukkit.util.CraftVector.toNMS(event.getKnockback()); ++ // Paper end - knockback events } // CraftBukkit end - entity.setDeltaMovement(entity.getDeltaMovement().add(vec3d1)); + entity.setDeltaMovement(entity.getDeltaMovement().add(vec3d)); diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index e3af0db8082e4e90902197f96f1c833405bf5f63..3059a21b554db99af96c76f72dd08591c00e3e08 100644 +index f05a19f868be0d685c4fbf64e1dfbefda71131ac..60a16ac62a27a92b763bf90e72fab4ed01aeb592 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1938,19 +1938,33 @@ public class CraftEventFactory { +@@ -1936,19 +1936,33 @@ public class CraftEventFactory { return event; } diff --git a/patches/server/0202-Expand-Explosions-API.patch b/patches/server/0202-Expand-Explosions-API.patch new file mode 100644 index 000000000000..b454b3ebcf59 --- /dev/null +++ b/patches/server/0202-Expand-Explosions-API.patch @@ -0,0 +1,87 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Wed, 20 Jun 2018 23:17:24 -0400 +Subject: [PATCH] Expand Explosions API + +Add Entity as a Source capability, and add more API choices, and on Location. + +Co-authored-by: Esoteric Enderman <90862990+EsotericEnderman@users.noreply.github.com> +Co-authored-by: Bjarne Koll + +diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java +index 252f1deea98a6eb83ac99adea3ea7a3c229c0f07..a4709b08ea90e15533a3e1b1d22d16e004556243 100644 +--- a/src/main/java/net/minecraft/server/level/ServerLevel.java ++++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +@@ -1449,6 +1449,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + } + + public ServerExplosion explode0(@Nullable Entity entity, @Nullable DamageSource damagesource, @Nullable ExplosionDamageCalculator explosiondamagecalculator, double d0, double d1, double d2, float f, boolean flag, Level.ExplosionInteraction world_a, ParticleOptions particleparam, ParticleOptions particleparam1, Holder holder) { ++ // Paper start - Allow explosions to damage source ++ return this.explode0(entity, damagesource, explosiondamagecalculator, d0, d1, d2, f, flag, world_a, particleparam, particleparam1, holder, null); ++ } ++ public ServerExplosion explode0(@Nullable Entity entity, @Nullable DamageSource damagesource, @Nullable ExplosionDamageCalculator explosiondamagecalculator, double d0, double d1, double d2, float f, boolean flag, Level.ExplosionInteraction world_a, ParticleOptions particleparam, ParticleOptions particleparam1, Holder holder, java.util.function.Consumer configurator) { ++ // Paper end - Allow explosions to damage source + // CraftBukkit end + Explosion.BlockInteraction explosion_effect; + +@@ -1480,6 +1485,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + Explosion.BlockInteraction explosion_effect1 = explosion_effect; + Vec3 vec3d = new Vec3(d0, d1, d2); + ServerExplosion serverexplosion = new ServerExplosion(this, entity, damagesource, explosiondamagecalculator, vec3d, f, flag, explosion_effect1); ++ if (configurator != null) configurator.accept(serverexplosion);// Paper - Allow explosions to damage source + + serverexplosion.explode(); + // CraftBukkit start +diff --git a/src/main/java/net/minecraft/world/level/ServerExplosion.java b/src/main/java/net/minecraft/world/level/ServerExplosion.java +index 9f37d7284c81d529551107e2836627977efabd65..d1878f597c3d8119e9b248f4fe8af435ce8c9710 100644 +--- a/src/main/java/net/minecraft/world/level/ServerExplosion.java ++++ b/src/main/java/net/minecraft/world/level/ServerExplosion.java +@@ -63,6 +63,7 @@ public class ServerExplosion implements Explosion { + public boolean wasCanceled = false; + public float yield; + // CraftBukkit end ++ public boolean excludeSourceFromDamage = true; // Paper - Allow explosions to damage source + + public ServerExplosion(ServerLevel world, @Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, Vec3 pos, float power, boolean createFire, Explosion.BlockInteraction destructionType) { + this.level = world; +@@ -185,7 +186,7 @@ public class ServerExplosion implements Explosion { + int l = Mth.floor(this.center.y + (double) f + 1.0D); + int i1 = Mth.floor(this.center.z - (double) f - 1.0D); + int j1 = Mth.floor(this.center.z + (double) f + 1.0D); +- List list = this.level.getEntities(this.source, new AABB((double) i, (double) k, (double) i1, (double) j, (double) l, (double) j1), (com.google.common.base.Predicate) entity -> entity.isAlive() && !entity.isSpectator()); // Paper - Fix lag from explosions processing dead entities ++ List list = this.level.getEntities(excludeSourceFromDamage ? this.source : null, new AABB((double) i, (double) k, (double) i1, (double) j, (double) l, (double) j1), (com.google.common.base.Predicate) entity -> entity.isAlive() && !entity.isSpectator()); // Paper - Fix lag from explosions processing dead entities, Allow explosions to damage source + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index 4b2742c0841bd686ee637e1d6dc011e13b0df192..22543e032f9202d590ac3924b537bb43efba9c93 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -784,6 +784,11 @@ public class CraftWorld extends CraftRegionAccessor implements World { + + @Override + public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks, Entity source) { ++ // Paper start - expand explosion API ++ return this.createExplosion(x, y, z, power, setFire, breakBlocks, source, null); ++ } ++ public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks, Entity source, Consumer configurator) { ++ // Paper end - expand explosion API + net.minecraft.world.level.Level.ExplosionInteraction explosionType; + if (!breakBlocks) { + explosionType = net.minecraft.world.level.Level.ExplosionInteraction.NONE; // Don't break blocks +@@ -794,8 +799,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { + } + + net.minecraft.world.entity.Entity entity = (source == null) ? null : ((CraftEntity) source).getHandle(); +- return !this.world.explode0(entity, Explosion.getDefaultDamageSource(this.world, entity), null, x, y, z, power, setFire, explosionType, ParticleTypes.EXPLOSION, ParticleTypes.EXPLOSION_EMITTER, SoundEvents.GENERIC_EXPLODE).wasCanceled; ++ return !this.world.explode0(entity, Explosion.getDefaultDamageSource(this.world, entity), null, x, y, z, power, setFire, explosionType, ParticleTypes.EXPLOSION, ParticleTypes.EXPLOSION_EMITTER, SoundEvents.GENERIC_EXPLODE, configurator).wasCanceled; // Paper - expand explosion API + } ++ // Paper start ++ @Override ++ public boolean createExplosion(Entity source, Location loc, float power, boolean setFire, boolean breakBlocks, boolean excludeSourceFromDamage) { ++ return this.createExplosion(loc.x(), loc.getY(), loc.getZ(), power, setFire, breakBlocks, source, e -> e.excludeSourceFromDamage = excludeSourceFromDamage); ++ } ++ // Paper end + + @Override + public boolean createExplosion(Location loc, float power) { diff --git a/patches/unapplied/server/0204-LivingEntity-Active-Item-API.patch b/patches/server/0203-LivingEntity-Active-Item-API.patch similarity index 94% rename from patches/unapplied/server/0204-LivingEntity-Active-Item-API.patch rename to patches/server/0203-LivingEntity-Active-Item-API.patch index aeca01c5eb16..f7de817b6bbb 100644 --- a/patches/unapplied/server/0204-LivingEntity-Active-Item-API.patch +++ b/patches/server/0203-LivingEntity-Active-Item-API.patch @@ -13,10 +13,10 @@ public net/minecraft/server/level/ServerPlayer completeUsingItem()V Co-authored-by: Jake Potrebic diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 73c72b8cdece357193afb3c5f474e055086311ea..2612e5016646591bb65ac255804b612b348a32fd 100644 +index e5186fbd4030d7b39443090b711e855dcbc39426..2033354daafc739a8bd9ddf4a6128d3204d32094 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -864,4 +864,53 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -884,4 +884,53 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { getHandle().setShieldBlockingDelay(delay); } // Paper end diff --git a/patches/unapplied/server/0205-RangedEntity-API.patch b/patches/server/0204-RangedEntity-API.patch similarity index 100% rename from patches/unapplied/server/0205-RangedEntity-API.patch rename to patches/server/0204-RangedEntity-API.patch diff --git a/patches/unapplied/server/0206-Add-config-to-disable-ender-dragon-legacy-check.patch b/patches/server/0205-Add-config-to-disable-ender-dragon-legacy-check.patch similarity index 89% rename from patches/unapplied/server/0206-Add-config-to-disable-ender-dragon-legacy-check.patch rename to patches/server/0205-Add-config-to-disable-ender-dragon-legacy-check.patch index 0d69ebd2b471..7c711b2484fc 100644 --- a/patches/unapplied/server/0206-Add-config-to-disable-ender-dragon-legacy-check.patch +++ b/patches/server/0205-Add-config-to-disable-ender-dragon-legacy-check.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add config to disable ender dragon legacy check diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -index 1a56247191172622f2bde6d799bc44f70b9ce3ae..93337fd026fefb76c8a288674fed05cb3c1eca38 100644 +index 3fa3dae36bcf66dfdc8a279d37fb60a624c1ae96..a16229f5eaa9e8320751e4fd1faf016f796d3414 100644 --- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java +++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -@@ -116,6 +116,12 @@ public class EndDragonFight { +@@ -117,6 +117,12 @@ public class EndDragonFight { if (data.isRespawning) { this.respawnStage = DragonRespawnAnimation.START; } diff --git a/patches/unapplied/server/0207-Implement-World.getEntity-UUID-API.patch b/patches/server/0206-Implement-World.getEntity-UUID-API.patch similarity index 85% rename from patches/unapplied/server/0207-Implement-World.getEntity-UUID-API.patch rename to patches/server/0206-Implement-World.getEntity-UUID-API.patch index 24247c437d41..cb1b631e5dc1 100644 --- a/patches/unapplied/server/0207-Implement-World.getEntity-UUID-API.patch +++ b/patches/server/0206-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 2c13ece6592700126365a155f104d6971aab4ede..f54038554bc184ecefbd32c69c234db8aada0309 100644 +index 22543e032f9202d590ac3924b537bb43efba9c93..1982385aa0e4984544d2aef88f5cafd5c0d5a49a 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -1127,6 +1127,15 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1137,6 +1137,15 @@ public class CraftWorld extends CraftRegionAccessor implements World { return list; } diff --git a/patches/unapplied/server/0208-InventoryCloseEvent-Reason-API.patch b/patches/server/0207-InventoryCloseEvent-Reason-API.patch similarity index 87% rename from patches/unapplied/server/0208-InventoryCloseEvent-Reason-API.patch rename to patches/server/0207-InventoryCloseEvent-Reason-API.patch index c932aab48fab..9c9fca780715 100644 --- a/patches/unapplied/server/0208-InventoryCloseEvent-Reason-API.patch +++ b/patches/server/0207-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 f2e75b36cbceb9cfa0755bd045f23073712d0e8a..480025bb35a838cc05022e3e316f8536c47dd87b 100644 +index a4709b08ea90e15533a3e1b1d22d16e004556243..438c936fceede5b21435e1f37f2372072a9d4571 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1239,7 +1239,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1234,7 +1234,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe 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 f2e75b36cbceb9cfa0755bd045f23073712d0e8a..480025bb35a838cc05022e3e316f8536 } } } -@@ -2198,7 +2198,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2279,7 +2279,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // 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 f2e75b36cbceb9cfa0755bd045f23073712d0e8a..480025bb35a838cc05022e3e316f8536 } // 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 fb5130b6378554ccb23fb7992e408497ca093ff3..0dee94f1dd27a0d7e709367450c5ef7956e27217 100644 +index 98aeafcc51e23a7534c8d57e4db0eb58abb3f30b..29b836a75b835f0d5233db419fc5ca8dde885fdb 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -705,7 +705,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -933,7 +933,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } // Paper end - Configurable container update tick rate if (!this.level().isClientSide && !this.containerMenu.stillValid(this)) { @@ -41,7 +41,7 @@ index fb5130b6378554ccb23fb7992e408497ca093ff3..0dee94f1dd27a0d7e709367450c5ef79 this.containerMenu = this.inventoryMenu; } -@@ -925,7 +925,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1185,7 +1185,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { // SPIGOT-943 - only call if they have an inventory open if (this.containerMenu != this.inventoryMenu) { @@ -50,7 +50,7 @@ index fb5130b6378554ccb23fb7992e408497ca093ff3..0dee94f1dd27a0d7e709367450c5ef79 } net.kyori.adventure.text.Component deathMessage = event.deathMessage() != null ? event.deathMessage() : net.kyori.adventure.text.Component.empty(); // Paper - Adventure -@@ -1591,7 +1591,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1859,7 +1859,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } // CraftBukkit end if (this.containerMenu != this.inventoryMenu) { @@ -59,7 +59,7 @@ index fb5130b6378554ccb23fb7992e408497ca093ff3..0dee94f1dd27a0d7e709367450c5ef79 } // this.nextContainerCounter(); // CraftBukkit - moved up -@@ -1621,7 +1621,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1889,7 +1889,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { @Override public void closeContainer() { @@ -75,10 +75,10 @@ index fb5130b6378554ccb23fb7992e408497ca093ff3..0dee94f1dd27a0d7e709367450c5ef79 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 0073c6c5433be3193a01257a26c7035e544f37dd..0321128ab745250e79fa5f66079c9aeb7f394cc0 100644 +index 0cce81cb61665b2dbd445fa9a0fcfeb42ce3be2c..bcceb9d18524ddcf7cdf2ab6dcb95a67f1155414 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2619,10 +2619,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2633,10 +2633,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleContainerClose(ServerboundContainerClosePacket packet) { @@ -96,10 +96,10 @@ index 0073c6c5433be3193a01257a26c7035e544f37dd..0321128ab745250e79fa5f66079c9aeb 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 26cee48ea3650aaf87fd2ba9c70d4ca9a88e2d87..25dee4848c8b2cff74075c6d26d384e71f706627 100644 +index 95b9341859ba6da6945faebf8430a044cc1ee828..038c5f16e60f0e182774e6df5b6c5359153a4b07 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -510,7 +510,7 @@ public abstract class PlayerList { +@@ -469,7 +469,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) { @@ -109,7 +109,7 @@ index 26cee48ea3650aaf87fd2ba9c70d4ca9a88e2d87..25dee4848c8b2cff74075c6d26d384e7 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() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName()))); // Paper - Adventure diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index 1b13096da1f0bc49efe25677ec24e6abe7ff2879..b70fbc1a93271bbf28402afbe9c6e538a4b6e9aa 100644 +index ba0ea4d6b67c9c52f170e0235e4b972aad3ce211..7eb4563299e7c54ec4df53c966f6d1a86fb2ec4e 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java @@ -279,7 +279,7 @@ public abstract class Player extends LivingEntity { @@ -121,7 +121,7 @@ index 1b13096da1f0bc49efe25677ec24e6abe7ff2879..b70fbc1a93271bbf28402afbe9c6e538 this.containerMenu = this.inventoryMenu; } -@@ -497,6 +497,13 @@ public abstract class Player extends LivingEntity { +@@ -531,6 +531,13 @@ public abstract class Player extends LivingEntity { } @@ -136,10 +136,10 @@ index 1b13096da1f0bc49efe25677ec24e6abe7ff2879..b70fbc1a93271bbf28402afbe9c6e538 this.containerMenu = this.inventoryMenu; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index e59fee587c2d90df5a6aa7a3df0eefc0cb5165ac..ee7cf7f1d491ffdf26c3f156d299e2f517a05608 100644 +index 6d4e0a90c70f7a66450cbb18ebec1d7bf9200af2..5ff159be1a6dfb4b1a5b9aa1e435d294f205215e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -@@ -386,7 +386,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { +@@ -387,7 +387,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { if (((ServerPlayer) this.getHandle()).connection == null) return; if (this.getHandle().containerMenu != this.getHandle().inventoryMenu) { // fire INVENTORY_CLOSE if one already open @@ -148,7 +148,7 @@ index e59fee587c2d90df5a6aa7a3df0eefc0cb5165ac..ee7cf7f1d491ffdf26c3f156d299e2f5 } ServerPlayer player = (ServerPlayer) this.getHandle(); AbstractContainerMenu container; -@@ -456,8 +456,14 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { +@@ -457,8 +457,14 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @Override public void closeInventory() { @@ -165,10 +165,10 @@ index e59fee587c2d90df5a6aa7a3df0eefc0cb5165ac..ee7cf7f1d491ffdf26c3f156d299e2f5 @Override public boolean isBlocking() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 18bcc27d07d7ab4b57148521891670ab61d6432c..35addb8d7620eeeede31c4831983a2c8bfb23ef5 100644 +index e7477aaad01c26e56e3d5e90bd403311deae8d59..ad75996926b7e054f1053d07fb978ac745f22ce6 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1273,7 +1273,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1286,7 +1286,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Close any foreign inventory if (this.getHandle().containerMenu != this.getHandle().inventoryMenu) { @@ -178,10 +178,10 @@ index 18bcc27d07d7ab4b57148521891670ab61d6432c..35addb8d7620eeeede31c4831983a2c8 // Check if the fromWorld and toWorld are the same. diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 7b1f55d02c2c1f3598b7b67c4c3d26c11c7450ae..889a2094850e6c5bda1efeac2e26bf77a007f4f3 100644 +index 60a16ac62a27a92b763bf90e72fab4ed01aeb592..41c6a7260317ed575a3320ac36b0f2be22c120aa 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1283,7 +1283,7 @@ public class CraftEventFactory { +@@ -1281,7 +1281,7 @@ public class CraftEventFactory { public static AbstractContainerMenu callInventoryOpenEvent(ServerPlayer player, AbstractContainerMenu container, boolean cancelled) { if (player.containerMenu != player.inventoryMenu) { // fire INVENTORY_CLOSE if one already open @@ -190,7 +190,7 @@ index 7b1f55d02c2c1f3598b7b67c4c3d26c11c7450ae..889a2094850e6c5bda1efeac2e26bf77 } CraftServer server = player.level().getCraftServer(); -@@ -1479,8 +1479,18 @@ public class CraftEventFactory { +@@ -1477,8 +1477,18 @@ public class CraftEventFactory { return event; } diff --git a/patches/unapplied/server/0209-Vex-get-setSummoner-API.patch b/patches/server/0208-Vex-get-setSummoner-API.patch similarity index 100% rename from patches/unapplied/server/0209-Vex-get-setSummoner-API.patch rename to patches/server/0208-Vex-get-setSummoner-API.patch diff --git a/patches/unapplied/server/0210-add-more-information-to-Entity.toString.patch b/patches/server/0209-add-more-information-to-Entity.toString.patch similarity index 88% rename from patches/unapplied/server/0210-add-more-information-to-Entity.toString.patch rename to patches/server/0209-add-more-information-to-Entity.toString.patch index b104bbec151a..a7a8976cca3c 100644 --- a/patches/unapplied/server/0210-add-more-information-to-Entity.toString.patch +++ b/patches/server/0209-add-more-information-to-Entity.toString.patch @@ -6,10 +6,10 @@ 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 a2b727dea997ed0d7b1ef677a94b5957f12d5abb..7fd1a75ba0068ee3ca6c29a550a9a1b33c5cacc5 100644 +index 011006bc2e88a9fec98796f939c07d884b92126b..79a3d586ddf404c449b7c0aa1996e9b9897b2383 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -3279,7 +3279,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3406,7 +3406,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public String toString() { String s = this.level() == null ? "~NULL~" : this.level().toString(); @@ -17,4 +17,4 @@ index a2b727dea997ed0d7b1ef677a94b5957f12d5abb..7fd1a75ba0068ee3ca6c29a550a9a1b3 + return this.removalReason != null ? String.format(Locale.ROOT, "%s['%s'/%d, uuid='%s', l='%s', x=%.2f, y=%.2f, z=%.2f, cpos=%s, tl=%d, v=%b, removed=%s]", this.getClass().getSimpleName(), this.getName().getString(), this.id, this.uuid, s, this.getX(), this.getY(), this.getZ(), this.chunkPosition(), this.tickCount, this.valid, this.removalReason) : String.format(Locale.ROOT, "%s['%s'/%d, uuid='%s', l='%s', x=%.2f, y=%.2f, z=%.2f, cpos=%s, tl=%d, v=%b]", this.getClass().getSimpleName(), this.getName().getString(), this.id, this.uuid, s, this.getX(), this.getY(), this.getZ(), this.chunkPosition(), this.tickCount, this.valid); // Paper - add more info } - public boolean isInvulnerableTo(DamageSource damageSource) { + public final boolean isInvulnerableToBase(DamageSource damageSource) { diff --git a/patches/unapplied/server/0211-EnderDragon-Events.patch b/patches/server/0210-EnderDragon-Events.patch similarity index 83% rename from patches/unapplied/server/0211-EnderDragon-Events.patch rename to patches/server/0210-EnderDragon-Events.patch index 73e0d7b16911..f78c44aab2eb 100644 --- a/patches/unapplied/server/0211-EnderDragon-Events.patch +++ b/patches/server/0210-EnderDragon-Events.patch @@ -5,15 +5,15 @@ Subject: [PATCH] EnderDragon Events diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java -index 3eaf64a6f66c6a844e30967e6b87432e559a59e7..5c5c71db73a2bfebbb33cebd6325a0f4fef1f239 100644 +index fe625faf0120b72e892542e4bb5ecea4b73becc7..55b66d3e0d7394a017fb1cdd87e45d7f4eb84976 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java -@@ -88,7 +88,13 @@ public class DragonSittingFlamingPhase extends AbstractDragonSittingPhase { +@@ -89,7 +89,13 @@ public class DragonSittingFlamingPhase extends AbstractDragonSittingPhase { this.flame.setDuration(200); this.flame.setParticle(ParticleTypes.DRAGON_BREATH); this.flame.addEffect(new MobEffectInstance(MobEffects.HARM)); + if (new com.destroystokyo.paper.event.entity.EnderDragonFlameEvent((org.bukkit.entity.EnderDragon) this.dragon.getBukkitEntity(), (org.bukkit.entity.AreaEffectCloud) this.flame.getBukkitEntity()).callEvent()) { // Paper - EnderDragon Events - this.dragon.level().addFreshEntity(this.flame); + world.addFreshEntity(this.flame); + // Paper start - EnderDragon Events + } else { + this.end(); @@ -23,24 +23,24 @@ index 3eaf64a6f66c6a844e30967e6b87432e559a59e7..5c5c71db73a2bfebbb33cebd6325a0f4 } diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java -index e5c896409536b7fb908590d02e40923d5979841f..a28e6b6a50cfd9191732ad2e4aca5f639a1fae75 100644 +index 68b7bfc139e928192005df8339be371ed8b2a9be..2db75673e525708d04bda9f6c9af80e7f8d361e6 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java -@@ -79,7 +79,9 @@ public class DragonStrafePlayerPhase extends AbstractDragonPhaseInstance { +@@ -80,7 +80,9 @@ public class DragonStrafePlayerPhase extends AbstractDragonPhaseInstance { - DragonFireball dragonFireball = new DragonFireball(this.dragon.level(), this.dragon, vec34.normalize()); + DragonFireball dragonFireball = new DragonFireball(world, this.dragon, vec34.normalize()); dragonFireball.moveTo(o, p, q, 0.0F, 0.0F); + if (new com.destroystokyo.paper.event.entity.EnderDragonShootFireballEvent((org.bukkit.entity.EnderDragon) dragon.getBukkitEntity(), (org.bukkit.entity.DragonFireball) dragonFireball.getBukkitEntity()).callEvent()) // Paper - EnderDragon Events - this.dragon.level().addFreshEntity(dragonFireball); + world.addFreshEntity(dragonFireball); + else dragonFireball.discard(null); // Paper - EnderDragon Events this.fireballCharge = 0; if (this.currentPath != null) { while (!this.currentPath.isDone()) { diff --git a/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java b/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java -index 3c77515f6b7f1ff89325afba214e9a8e5f536158..1dade7a4fbdf190661e4431496349444467509cc 100644 +index 5b8f3cf80b4fb425bdd0e3b9a431128536c7f1b1..2eecdcbea3d51b1fb6e0c3db0667464a699ca0df 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java +++ b/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java -@@ -63,8 +63,10 @@ public class DragonFireball extends AbstractHurtingProjectile { +@@ -62,8 +62,10 @@ public class DragonFireball extends AbstractHurtingProjectile { } } diff --git a/patches/unapplied/server/0203-Expand-Explosions-API.patch b/patches/unapplied/server/0203-Expand-Explosions-API.patch deleted file mode 100644 index cdd902874622..000000000000 --- a/patches/unapplied/server/0203-Expand-Explosions-API.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Wed, 20 Jun 2018 23:17:24 -0400 -Subject: [PATCH] Expand Explosions API - -Add Entity as a Source capability, and add more API choices, and on Location. - -Co-authored-by: Esoteric Enderman <90862990+EsotericEnderman@users.noreply.github.com> -Co-authored-by: Bjarne Koll - -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 1fac100819e59d00f50e530d3a4157b56d966dba..f2e75b36cbceb9cfa0755bd045f23073712d0e8a 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1424,8 +1424,10 @@ public class ServerLevel extends Level implements WorldGenLevel { - } - - @Override -- public Explosion explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, ParticleOptions particle, ParticleOptions emitterParticle, Holder soundEvent) { -- Explosion explosion = this.explode(entity, damageSource, behavior, x, y, z, power, createFire, explosionSourceType, false, particle, emitterParticle, soundEvent); -+ // Paper start - Allow explosions to damage source -+ public Explosion explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, ParticleOptions particle, ParticleOptions emitterParticle, Holder soundEvent, java.util.function.Consumer configurator) { -+ Explosion explosion = this.explode(entity, damageSource, behavior, x, y, z, power, createFire, explosionSourceType, false, particle, emitterParticle, soundEvent, configurator); -+ // Paper end - Allow explosions to damage source - // CraftBukkit start - if (explosion.wasCanceled) { - return explosion; -diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index b216140a8be65e210250358af8daf49344850f20..ce8ac06b47e81161ad5ff6cc865ad6d3d59807c1 100644 ---- a/src/main/java/net/minecraft/world/level/Explosion.java -+++ b/src/main/java/net/minecraft/world/level/Explosion.java -@@ -74,6 +74,7 @@ public class Explosion { - public boolean wasCanceled = false; - public float yield; - // CraftBukkit end -+ public boolean excludeSourceFromDamage = true; // Paper - Allow explosions to damage source - - public static DamageSource getDefaultDamageSource(Level world, @Nullable Entity source) { - return world.damageSources().explosion(source, Explosion.getIndirectSourceEntityInternal(source)); -@@ -227,7 +228,7 @@ public class Explosion { - int i1 = Mth.floor(this.y + (double) f2 + 1.0D); - int j1 = Mth.floor(this.z - (double) f2 - 1.0D); - int k1 = Mth.floor(this.z + (double) f2 + 1.0D); -- List list = this.level.getEntities(this.source, new AABB((double) i, (double) l, (double) j1, (double) j, (double) i1, (double) k1), (com.google.common.base.Predicate) entity -> entity.isAlive() && !entity.isSpectator()); // Paper - Fix lag from explosions processing dead entities -+ List list = this.level.getEntities(excludeSourceFromDamage ? this.source : null, new AABB((double) i, (double) l, (double) j1, (double) j, (double) i1, (double) k1), (com.google.common.base.Predicate) entity -> entity.isAlive() && !entity.isSpectator()); // Paper - Fix lag from explosions processing dead entities, Allow explosions to damage source - Vec3 vec3d = new Vec3(this.x, this.y, this.z); - Iterator iterator = list.iterator(); - -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 6944c0b0cfcde9fa4dd78742aee3e3b87d679abf..7138fb36062eceaf92ae8513f9b8aef3d1238656 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -782,7 +782,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - } - - public Explosion explode(@Nullable Entity entity, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType) { -- return this.explode(entity, Explosion.getDefaultDamageSource(this, entity), (ExplosionDamageCalculator) null, x, y, z, power, createFire, explosionSourceType, ParticleTypes.EXPLOSION, ParticleTypes.EXPLOSION_EMITTER, SoundEvents.GENERIC_EXPLODE); -+ // Paper start - Allow explosions to damage source -+ return this.explode(entity, x, y, z, power, createFire, explosionSourceType, null); -+ } -+ public Explosion explode(@Nullable Entity entity, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, @Nullable Consumer configurator) { -+ return this.explode(entity, Explosion.getDefaultDamageSource(this, entity), (ExplosionDamageCalculator) null, x, y, z, power, createFire, explosionSourceType, ParticleTypes.EXPLOSION, ParticleTypes.EXPLOSION_EMITTER, SoundEvents.GENERIC_EXPLODE, configurator); -+ // Paper end - Allow explosions to damage source - } - - public Explosion explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, Vec3 pos, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType) { -@@ -794,10 +799,21 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - } - - public Explosion explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, ParticleOptions particle, ParticleOptions emitterParticle, Holder soundEvent) { -- return this.explode(entity, damageSource, behavior, x, y, z, power, createFire, explosionSourceType, true, particle, emitterParticle, soundEvent); -+ // Paper start - Allow explosions to damage source -+ return this.explode(entity, damageSource, behavior, x, y, z, power, createFire, explosionSourceType, particle, emitterParticle, soundEvent, null); -+ } -+ -+ public Explosion explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, ParticleOptions particle, ParticleOptions emitterParticle, Holder soundEvent, @Nullable Consumer configurator) { -+ return this.explode(entity, damageSource, behavior, x, y, z, power, createFire, explosionSourceType, true, particle, emitterParticle, soundEvent, configurator); -+ // Paper end - Allow explosions to damage source - } - - public Explosion explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, boolean particles, ParticleOptions particle, ParticleOptions emitterParticle, Holder soundEvent) { -+ // Paper start - Allow explosions to damage source -+ return this.explode(entity, damageSource, behavior, x, y, z, power, createFire, explosionSourceType, particle, emitterParticle, soundEvent, null); -+ } -+ public Explosion explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, boolean particles, ParticleOptions particle, ParticleOptions emitterParticle, Holder soundEvent, @Nullable Consumer configurator) { -+ // Paper end - Allow explosions to damage source - Explosion.BlockInteraction explosion_effect; - - switch (explosionSourceType.ordinal()) { -@@ -827,6 +843,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - - Explosion.BlockInteraction explosion_effect1 = explosion_effect; - Explosion explosion = new Explosion(this, entity, damageSource, behavior, x, y, z, power, createFire, explosion_effect1, particle, emitterParticle, soundEvent); -+ if (configurator != null) configurator.accept(explosion); // Paper - Allow explosions to damage source - - explosion.explode(); - explosion.finalizeExplosion(particles); -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 3c00eaf52ab04d1396f226cc074d9dd013c57027..2c13ece6592700126365a155f104d6971aab4ede 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -789,6 +789,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { - - return !this.world.explode(source == null ? null : ((CraftEntity) source).getHandle(), x, y, z, power, setFire, explosionType).wasCanceled; - } -+ // Paper start -+ @Override -+ public boolean createExplosion(Entity source, Location loc, float power, boolean setFire, boolean breakBlocks, boolean excludeSourceFromDamage) { -+ return !world.explode(source != null ? ((org.bukkit.craftbukkit.entity.CraftEntity) source).getHandle() : null, loc.getX(), loc.getY(), loc.getZ(), power, setFire, breakBlocks ? net.minecraft.world.level.Level.ExplosionInteraction.MOB : net.minecraft.world.level.Level.ExplosionInteraction.NONE, explosion -> { -+ explosion.excludeSourceFromDamage = excludeSourceFromDamage; -+ }).wasCanceled; -+ } -+ // Paper end - - @Override - public boolean createExplosion(Location loc, float power) { From 7c04a31c9ff36c9bb82f603eeeba63c9d161be8f Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Wed, 23 Oct 2024 12:02:36 +0200 Subject: [PATCH 012/119] Update projectile launch to 1.21.2 --- .../server/0211-PlayerElytraBoostEvent.patch | 75 ++++ .../0212-PlayerLaunchProjectileEvent.patch | 377 ++++++++++++++++++ .../server/0212-PlayerElytraBoostEvent.patch | 33 -- .../0213-PlayerLaunchProjectileEvent.patch | 363 ----------------- 4 files changed, 452 insertions(+), 396 deletions(-) create mode 100644 patches/server/0211-PlayerElytraBoostEvent.patch create mode 100644 patches/server/0212-PlayerLaunchProjectileEvent.patch delete mode 100644 patches/unapplied/server/0212-PlayerElytraBoostEvent.patch delete mode 100644 patches/unapplied/server/0213-PlayerLaunchProjectileEvent.patch diff --git a/patches/server/0211-PlayerElytraBoostEvent.patch b/patches/server/0211-PlayerElytraBoostEvent.patch new file mode 100644 index 000000000000..53897d0ae43e --- /dev/null +++ b/patches/server/0211-PlayerElytraBoostEvent.patch @@ -0,0 +1,75 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: BillyGalbreath +Date: Sat, 21 Jul 2018 01:59:59 -0500 +Subject: [PATCH] PlayerElytraBoostEvent + + +diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +index 3b0b543a1bf8b190620fd4385751f05db74a47f1..9a6701f4ceed680ee12224802f01ce399798b6e1 100644 +--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java ++++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +@@ -219,11 +219,34 @@ public abstract class Projectile extends Entity implements TraceableEntity { + }); + } + ++ // Paper start - delayed projectile spawning ++ public record Delayed( ++ T projectile, ++ ServerLevel world, ++ ItemStack projectileStack ++ ) { ++ // Taken from net.minecraft.world.entity.projectile.Projectile.spawnProjectile(T, net.minecraft.server.level.ServerLevel, net.minecraft.world.item.ItemStack, java.util.function.Consumer) ++ public boolean attemptSpawn() { ++ if (!world.addFreshEntity(projectile)) return false; ++ projectile.applyOnProjectileSpawned(this.world, this.projectileStack); ++ return true; ++ } ++ ++ public T spawn() { ++ this.attemptSpawn(); ++ return projectile(); ++ } ++ } ++ // Paper end - delayed projectile spawning ++ + public static T spawnProjectile(T projectile, ServerLevel world, ItemStack projectileStack, Consumer beforeSpawn) { ++ // Paper start - delayed projectile spawning ++ return spawnProjectileDelayed(projectile, world, projectileStack, beforeSpawn).spawn(); ++ } ++ public static Delayed spawnProjectileDelayed(T projectile, ServerLevel world, ItemStack projectileStack, Consumer beforeSpawn) { ++ // Paper end - delayed projectile spawning + beforeSpawn.accept(projectile); +- if (world.addFreshEntity(projectile)) // CraftBukkit +- projectile.applyOnProjectileSpawned(world, projectileStack); +- return projectile; ++ return new Delayed<>(projectile, world, projectileStack); // Paper - delayed projectile spawning + } + + public void applyOnProjectileSpawned(ServerLevel world, ItemStack projectileStack) { +diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java +index 3929cb76f1c98c0a22eb2ab64c2ed09805ffe448..400ad0fa1d07c8b120e3c3b5488dfa315aa2d23f 100644 +--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java ++++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java +@@ -56,9 +56,19 @@ public class FireworkRocketItem extends Item implements ProjectileItem { + if (user.isFallFlying()) { + ItemStack itemStack = user.getItemInHand(hand); + if (world instanceof ServerLevel serverLevel) { +- Projectile.spawnProjectile(new FireworkRocketEntity(world, itemStack, user), serverLevel, itemStack, f -> f.spawningEntity = user.getUUID()); // Paper - firework api - assign spawning entity uuid +- itemStack.consume(1, user); +- user.awardStat(Stats.ITEM_USED.get(this)); ++ // Paper start - PlayerElytraBoostEvent ++ final Projectile.Delayed delayed = Projectile.spawnProjectileDelayed(new FireworkRocketEntity(world, itemStack, user), serverLevel, itemStack, f -> f.spawningEntity = user.getUUID()); // Paper - firework api - assign spawning entity uuid ++ com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) delayed.projectile().getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand)); ++ if (event.callEvent() && delayed.attemptSpawn()) { ++ user.awardStat(Stats.ITEM_USED.get(this)); // Moved up from below ++ if (event.shouldConsume() && !user.hasInfiniteMaterials()) { ++ itemStack.shrink(1); // Moved up from below ++ } else ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); ++ } else { ++ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); ++ } ++ // Moved up consume/stat ++ // Paper end - PlayerElytraBoostEvent + } + + return InteractionResult.SUCCESS; diff --git a/patches/server/0212-PlayerLaunchProjectileEvent.patch b/patches/server/0212-PlayerLaunchProjectileEvent.patch new file mode 100644 index 000000000000..14e01c4e3f84 --- /dev/null +++ b/patches/server/0212-PlayerLaunchProjectileEvent.patch @@ -0,0 +1,377 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: BillyGalbreath +Date: Sat, 21 Jul 2018 03:11:03 -0500 +Subject: [PATCH] PlayerLaunchProjectileEvent + + +diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +index 9a6701f4ceed680ee12224802f01ce399798b6e1..55c0d23ea68cd328881bd40d6bfd12d58477d15b 100644 +--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java ++++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +@@ -197,7 +197,12 @@ public abstract class Projectile extends Entity implements TraceableEntity { + } + + public static T spawnProjectileFromRotation(Projectile.ProjectileFactory creator, ServerLevel world, ItemStack projectileStack, LivingEntity shooter, float roll, float power, float divergence) { +- return Projectile.spawnProjectile(creator.create(world, shooter, projectileStack), world, projectileStack, (iprojectile) -> { ++ // Paper start - PlayerLaunchProjectileEvent ++ return spawnProjectileFromRotationDelayed(creator, world, projectileStack, shooter, roll, power, divergence).spawn(); ++ } ++ public static Delayed spawnProjectileFromRotationDelayed(Projectile.ProjectileFactory creator, ServerLevel world, ItemStack projectileStack, LivingEntity shooter, float roll, float power, float divergence) { ++ return Projectile.spawnProjectileDelayed(creator.create(world, shooter, projectileStack), world, projectileStack, (iprojectile) -> { ++ // Paper end - PlayerLaunchProjectileEvent + iprojectile.shootFromRotation(shooter, shooter.getXRot(), shooter.getYRot(), roll, power, divergence); + }); + } +diff --git a/src/main/java/net/minecraft/world/item/EggItem.java b/src/main/java/net/minecraft/world/item/EggItem.java +index 8ddc1fa76244265616309322170c3a1b821c5092..3ddd34e5d05fa1355a2affd329d72dea216cd0e4 100644 +--- a/src/main/java/net/minecraft/world/item/EggItem.java ++++ b/src/main/java/net/minecraft/world/item/EggItem.java +@@ -26,7 +26,19 @@ public class EggItem extends Item implements ProjectileItem { + // world.playSound((EntityHuman) null, entityhuman.getX(), entityhuman.getY(), entityhuman.getZ(), SoundEffects.EGG_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); // CraftBukkit - moved down + if (world instanceof ServerLevel worldserver) { + // CraftBukkit start +- if (Projectile.spawnProjectileFromRotation(ThrownEgg::new, worldserver, itemstack, user, 0.0F, 1.5F, 1.0F).isRemoved()) { ++ // Paper start - PlayerLaunchProjectileEvent ++ final Projectile.Delayed thrownEgg = Projectile.spawnProjectileFromRotationDelayed(ThrownEgg::new, worldserver, itemstack, user, 0.0F, 1.5F, 1.0F); ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) thrownEgg.projectile().getBukkitEntity()); ++ if (event.callEvent() && thrownEgg.attemptSpawn()) { ++ if (event.shouldConsume()) { ++ itemstack.consume(1, user); ++ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); ++ } ++ ++ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EGG_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); ++ user.awardStat(Stats.ITEM_USED.get(this)); ++ } else { + if (user instanceof net.minecraft.server.level.ServerPlayer) { + ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); + } +@@ -35,9 +47,7 @@ public class EggItem extends Item implements ProjectileItem { + // CraftBukkit end + } + world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EGG_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); +- +- user.awardStat(Stats.ITEM_USED.get(this)); +- itemstack.consume(1, user); ++ // Paper - PlayerLaunchProjectileEvent - moved up + return InteractionResult.SUCCESS; + } + +diff --git a/src/main/java/net/minecraft/world/item/EnderpearlItem.java b/src/main/java/net/minecraft/world/item/EnderpearlItem.java +index b9e24451a8f87479377e3324b3a956c0efc3e53c..b232390d8ee8e449e61c0ea7f3af60df507abb97 100644 +--- a/src/main/java/net/minecraft/world/item/EnderpearlItem.java ++++ b/src/main/java/net/minecraft/world/item/EnderpearlItem.java +@@ -23,7 +23,20 @@ public class EnderpearlItem extends Item { + + if (world instanceof ServerLevel worldserver) { + // CraftBukkit start +- if (Projectile.spawnProjectileFromRotation(ThrownEnderpearl::new, worldserver, itemstack, user, 0.0F, 1.5F, 1.0F).isRemoved()) { ++ // Paper start - PlayerLaunchProjectileEvent ++ final Projectile.Delayed thrownEnderpearl = Projectile.spawnProjectileFromRotationDelayed(ThrownEnderpearl::new, worldserver, itemstack, user, 0.0F, 1.5F, 1.0F); ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) thrownEnderpearl.projectile().getBukkitEntity()); ++ if (event.callEvent() && thrownEnderpearl.attemptSpawn()) { ++ if (event.shouldConsume()) { ++ itemstack.consume(1, user); ++ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); ++ } ++ ++ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); ++ user.awardStat(Stats.ITEM_USED.get(this)); ++ } else { ++ // Paper end - PlayerLaunchProjectileEvent + if (user instanceof net.minecraft.server.level.ServerPlayer) { + ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); + } +@@ -33,8 +46,7 @@ public class EnderpearlItem extends Item { + world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); + // CraftBukkit end + +- user.awardStat(Stats.ITEM_USED.get(this)); +- itemstack.consume(1, user); ++ // Paper - PlayerLaunchProjectileEvent - moved up + return InteractionResult.SUCCESS; + } + } +diff --git a/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java b/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java +index b255e40277585928a767e5efd4b61708e13dab50..dfa3f9534159400e539ee61debedffb5f978aae8 100644 +--- a/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java ++++ b/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java +@@ -21,22 +21,38 @@ public class ExperienceBottleItem extends Item implements ProjectileItem { + @Override + public InteractionResult use(Level world, Player user, InteractionHand hand) { + ItemStack itemStack = user.getItemInHand(hand); +- world.playSound( +- null, +- user.getX(), +- user.getY(), +- user.getZ(), +- SoundEvents.EXPERIENCE_BOTTLE_THROW, +- SoundSource.NEUTRAL, +- 0.5F, +- 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) +- ); ++ // Paper - PlayerLaunchProjectileEvent - moved down + if (world instanceof ServerLevel serverLevel) { +- Projectile.spawnProjectileFromRotation(ThrownExperienceBottle::new, serverLevel, itemStack, user, -20.0F, 0.7F, 1.0F); ++ // Paper start - PlayerLaunchProjectileEvent ++ final Projectile.Delayed thrownExperienceBottle = Projectile.spawnProjectileFromRotationDelayed(ThrownExperienceBottle::new, serverLevel, itemStack, user, -20.0F, 0.7F, 1.0F); ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownExperienceBottle.projectile().getBukkitEntity()); ++ if (event.callEvent() && thrownExperienceBottle.attemptSpawn()) { ++ if (event.shouldConsume()) { ++ itemStack.consume(1, user); ++ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); ++ } ++ ++ world.playSound( ++ null, ++ user.getX(), ++ user.getY(), ++ user.getZ(), ++ SoundEvents.EXPERIENCE_BOTTLE_THROW, ++ SoundSource.NEUTRAL, ++ 0.5F, ++ 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) ++ ); ++ } else { ++ if (user instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); ++ } ++ return InteractionResult.FAIL; ++ } ++ // Paper end - PlayerLaunchProjectileEvent + } + +- user.awardStat(Stats.ITEM_USED.get(this)); +- itemStack.consume(1, user); ++ // Paper - PlayerLaunchProjectileEvent - moved up + return InteractionResult.SUCCESS; + } + +diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java +index 400ad0fa1d07c8b120e3c3b5488dfa315aa2d23f..7e308b364227dedc2d05496f5e0c90573f4a53f7 100644 +--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java ++++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java +@@ -33,7 +33,7 @@ public class FireworkRocketItem extends Item implements ProjectileItem { + ItemStack itemStack = context.getItemInHand(); + Vec3 vec3 = context.getClickLocation(); + Direction direction = context.getClickedFace(); +- Projectile.spawnProjectile( ++ final Projectile.Delayed fireworkRocketEntity = Projectile.spawnProjectileDelayed( // Paper - PlayerLaunchProjectileEvent + new FireworkRocketEntity( + level, + context.getPlayer(), +@@ -45,7 +45,12 @@ public class FireworkRocketItem extends Item implements ProjectileItem { + serverLevel, + itemStack, f -> f.spawningEntity = context.getPlayer() == null ? null : context.getPlayer().getUUID() // Paper - firework api - assign spawning entity uuid + ); +- itemStack.shrink(1); ++ // Paper start - PlayerLaunchProjectileEvent ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.projectile().getBukkitEntity()); ++ if (!event.callEvent() || fireworkRocketEntity.attemptSpawn()) return InteractionResult.PASS; ++ if (event.shouldConsume() && !context.getPlayer().hasInfiniteMaterials()) itemStack.shrink(1); ++ else if (context.getPlayer() instanceof net.minecraft.server.level.ServerPlayer) ((net.minecraft.server.level.ServerPlayer) context.getPlayer()).getBukkitEntity().updateInventory(); ++ // Paper end - PlayerLaunchProjectileEvent + } + + return InteractionResult.SUCCESS; +diff --git a/src/main/java/net/minecraft/world/item/LingeringPotionItem.java b/src/main/java/net/minecraft/world/item/LingeringPotionItem.java +index 7a5045469bc2d383ed087dcc094b6f97df4ec7ab..fa92a1346825f00a585503d0a0825711fe3f754e 100644 +--- a/src/main/java/net/minecraft/world/item/LingeringPotionItem.java ++++ b/src/main/java/net/minecraft/world/item/LingeringPotionItem.java +@@ -24,6 +24,10 @@ public class LingeringPotionItem extends ThrowablePotionItem { + + @Override + public InteractionResult use(Level world, Player user, InteractionHand hand) { ++ // Paper start - PlayerLaunchProjectileEvent ++ final InteractionResult wrapper = super.use(world, user, hand); ++ if (wrapper instanceof InteractionResult.Fail) return wrapper; ++ // Paper end - PlayerLaunchProjectileEvent + world.playSound( + null, + user.getX(), +@@ -34,6 +38,6 @@ public class LingeringPotionItem extends ThrowablePotionItem { + 0.5F, + 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) + ); +- return super.use(world, user, hand); ++ return wrapper; // Paper - PlayerLaunchProjectileEvent + } + } +diff --git a/src/main/java/net/minecraft/world/item/SnowballItem.java b/src/main/java/net/minecraft/world/item/SnowballItem.java +index ada9bc42a788b5f472324a0765edf5766d729784..1e996276a80b34e353c6a7c7fee765c9db7123ea 100644 +--- a/src/main/java/net/minecraft/world/item/SnowballItem.java ++++ b/src/main/java/net/minecraft/world/item/SnowballItem.java +@@ -26,17 +26,26 @@ public class SnowballItem extends Item implements ProjectileItem { + // CraftBukkit start - moved down + // world.playSound((EntityHuman) null, entityhuman.getX(), entityhuman.getY(), entityhuman.getZ(), SoundEffects.SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); + if (world instanceof ServerLevel worldserver) { +- if (Projectile.spawnProjectileFromRotation(Snowball::new, worldserver, itemstack, user, 0.0F, 1.5F, 1.0F).isAlive()) { +- itemstack.consume(1, user); ++ // Paper start - PlayerLaunchProjectileEvent ++ final Projectile.Delayed snowball = Projectile.spawnProjectileFromRotationDelayed(Snowball::new, worldserver, itemstack, user, 0.0F, 1.5F, 1.0F); ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitysnowball.getBukkitEntity()); ++ if (event.callEvent() && snowball.attemptSpawn()) { ++ user.awardStat(Stats.ITEM_USED.get(this)); ++ if (event.shouldConsume()) { ++ itemstack.consume(1, user); ++ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); ++ } ++ // Paper end - PlayerLaunchProjectileEvent + + world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.SNOWBALL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); +- } else if (user instanceof net.minecraft.server.level.ServerPlayer) { ++ } else { if (user instanceof net.minecraft.server.level.ServerPlayer) { // Paper - PlayerLaunchProjectileEvent - return fail + ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); +- } ++ } return InteractionResult.FAIL; } // Paper - PlayerLaunchProjectileEvent - return fail + // CraftBukkit end + } + +- user.awardStat(Stats.ITEM_USED.get(this)); ++ // Paper - PlayerLaunchProjectileEvent - moved up + // itemstack.consume(1, entityhuman); // CraftBukkit - moved up + return InteractionResult.SUCCESS; + } +diff --git a/src/main/java/net/minecraft/world/item/SplashPotionItem.java b/src/main/java/net/minecraft/world/item/SplashPotionItem.java +index 6d622d276a632c9c29ab04a01fbe7adbf10c35cd..577e66a7ff64d9569ee2402ecc26b0aa1105fe9a 100644 +--- a/src/main/java/net/minecraft/world/item/SplashPotionItem.java ++++ b/src/main/java/net/minecraft/world/item/SplashPotionItem.java +@@ -14,6 +14,10 @@ public class SplashPotionItem extends ThrowablePotionItem { + + @Override + public InteractionResult use(Level world, Player user, InteractionHand hand) { ++ // Paper start - PlayerLaunchProjectileEvent ++ final InteractionResult wrapper = super.use(world, user, hand); ++ if (wrapper instanceof InteractionResult.Fail) return wrapper; ++ // Paper end - PlayerLaunchProjectileEvent + world.playSound( + null, + user.getX(), +@@ -24,6 +28,6 @@ public class SplashPotionItem extends ThrowablePotionItem { + 0.5F, + 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) + ); +- return super.use(world, user, hand); ++ return wrapper; // Paper - PlayerLaunchProjectileEvent + } + } +diff --git a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java +index e3eb733f18c23ae3fcc4c271843d285b217d1a7d..fa9d2ae44fcdd06f8f33cd14ffca422b20a01451 100644 +--- a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java ++++ b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java +@@ -20,11 +20,28 @@ public class ThrowablePotionItem extends PotionItem implements ProjectileItem { + public InteractionResult use(Level world, Player user, InteractionHand hand) { + ItemStack itemStack = user.getItemInHand(hand); + if (world instanceof ServerLevel serverLevel) { +- Projectile.spawnProjectileFromRotation(ThrownPotion::new, serverLevel, itemStack, user, -20.0F, 0.5F, 1.0F); ++ // Paper start - PlayerLaunchProjectileEvent ++ final Projectile.Delayed thrownPotion = Projectile.spawnProjectileFromRotationDelayed(ThrownPotion::new, serverLevel, itemStack, user, -20.0F, 0.5F, 1.0F); ++ // Paper start - PlayerLaunchProjectileEvent ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownPotion.projectile().getBukkitEntity()); ++ if (event.callEvent() && thrownPotion.attemptSpawn()) { ++ if (event.shouldConsume()) { ++ itemStack.consume(1, user); ++ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); ++ } ++ ++ user.awardStat(Stats.ITEM_USED.get(this)); ++ } else { ++ if (user instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); ++ } ++ return InteractionResult.FAIL; ++ } ++ // Paper end - PlayerLaunchProjectileEvent + } + +- user.awardStat(Stats.ITEM_USED.get(this)); +- itemStack.consume(1, user); ++ // Paper - PlayerLaunchProjectileEvent - move up + return InteractionResult.SUCCESS; + } + +diff --git a/src/main/java/net/minecraft/world/item/TridentItem.java b/src/main/java/net/minecraft/world/item/TridentItem.java +index 22aa715c4ef615c2c9d795cc2e11b7099d5167da..8b9a93ef71164cce8a616735b71d96d37e83b1a8 100644 +--- a/src/main/java/net/minecraft/world/item/TridentItem.java ++++ b/src/main/java/net/minecraft/world/item/TridentItem.java +@@ -87,21 +87,26 @@ public class TridentItem extends Item implements ProjectileItem { + + // itemstack.hurtWithoutBreaking(1, entityhuman); // CraftBukkit - moved down + if (f == 0.0F) { +- ThrownTrident entitythrowntrident = (ThrownTrident) Projectile.spawnProjectileFromRotation(ThrownTrident::new, worldserver, stack, entityhuman, 0.0F, 2.5F, 1.0F); +- // CraftBukkit start +- if (entitythrowntrident.isRemoved()) { ++ // Paper start - PlayerLaunchProjectileEvent ++ Projectile.Delayed tridentDelayed = Projectile.spawnProjectileFromRotationDelayed(ThrownTrident::new, worldserver, stack, entityhuman, 0.0F, 2.5F, 1.0F); ++ // Paper start - PlayerLaunchProjectileEvent ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), (org.bukkit.entity.Projectile) tridentDelayed.projectile().getBukkitEntity()); ++ if (!event.callEvent() || !tridentDelayed.attemptSpawn()) { ++ // CraftBukkit start ++ // Paper end - PlayerLaunchProjectileEvent + if (entityhuman instanceof net.minecraft.server.level.ServerPlayer) { + ((net.minecraft.server.level.ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); + } + return false; + } +- stack.hurtWithoutBreaking(1, entityhuman); ++ ThrownTrident entitythrowntrident = tridentDelayed.projectile(); // Paper - PlayerLaunchProjectileEvent ++ if (event.shouldConsume()) stack.hurtWithoutBreaking(1, entityhuman); // Paper - PlayerLaunchProjectileEvent + entitythrowntrident.pickupItemStack = stack.copy(); // SPIGOT-4511 update since damage call moved + // CraftBukkit end + + if (entityhuman.hasInfiniteMaterials()) { + entitythrowntrident.pickup = AbstractArrow.Pickup.CREATIVE_ONLY; +- } else { ++ } else if (event.shouldConsume()) { // Paper - PlayerLaunchProjectileEvent + entityhuman.getInventory().removeItem(stack); + } + +diff --git a/src/main/java/net/minecraft/world/item/WindChargeItem.java b/src/main/java/net/minecraft/world/item/WindChargeItem.java +index 79fdb78a4c3c7e324f0ed84a3dad9a3a80a6456a..0ce52d239b5bfb63e09cf5df679eee177f7bc5b0 100644 +--- a/src/main/java/net/minecraft/world/item/WindChargeItem.java ++++ b/src/main/java/net/minecraft/world/item/WindChargeItem.java +@@ -25,7 +25,7 @@ public class WindChargeItem extends Item implements ProjectileItem { + public InteractionResult use(Level world, Player user, InteractionHand hand) { + ItemStack itemStack = user.getItemInHand(hand); + if (world instanceof ServerLevel serverLevel) { +- Projectile.spawnProjectileFromRotation( ++ final Projectile.Delayed windCharge = Projectile.spawnProjectileFromRotationDelayed( // Paper - PlayerLaunchProjectileEvent + (world2, shooter, stack) -> new WindCharge(user, world, user.position().x(), user.getEyePosition().y(), user.position().z()), + serverLevel, + itemStack, +@@ -34,6 +34,21 @@ public class WindChargeItem extends Item implements ProjectileItem { + 1.5F, + 1.0F + ); ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) windCharge.projectile().getBukkitEntity()); ++ if (!event.callEvent() || !windCharge.attemptSpawn()) { ++ user.containerMenu.sendAllDataToRemote(); ++ if (user instanceof net.minecraft.server.level.ServerPlayer player) { ++ player.connection.send(new net.minecraft.network.protocol.game.ClientboundCooldownPacket(user.getCooldowns().getCooldownGroup(itemStack), 0)); // prevent visual desync of cooldown on the slot ++ } ++ return InteractionResult.FAIL; ++ } ++ ++ user.awardStat(Stats.ITEM_USED.get(this)); ++ if (event.shouldConsume()) itemStack.consume(1, user); ++ else if (!user.hasInfiniteMaterials()) { ++ user.containerMenu.sendAllDataToRemote(); ++ } ++ // Paper end - PlayerLaunchProjectileEvent + } + + world.playSound( +@@ -46,8 +61,6 @@ public class WindChargeItem extends Item implements ProjectileItem { + 0.5F, + 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) + ); +- user.awardStat(Stats.ITEM_USED.get(this)); +- itemStack.consume(1, user); + return InteractionResult.SUCCESS; + } + diff --git a/patches/unapplied/server/0212-PlayerElytraBoostEvent.patch b/patches/unapplied/server/0212-PlayerElytraBoostEvent.patch deleted file mode 100644 index 0581d2cd0a3b..000000000000 --- a/patches/unapplied/server/0212-PlayerElytraBoostEvent.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: BillyGalbreath -Date: Sat, 21 Jul 2018 01:59:59 -0500 -Subject: [PATCH] PlayerElytraBoostEvent - - -diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java -index 38b33eb92d21d0099285a304c6e064bbf56db4eb..16da60b7ecf2e0d4a49804dfa1ad47d4ae672571 100644 ---- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java -+++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java -@@ -57,9 +57,19 @@ public class FireworkRocketItem extends Item implements ProjectileItem { - if (!world.isClientSide) { - FireworkRocketEntity fireworkRocketEntity = new FireworkRocketEntity(world, itemStack, user); - fireworkRocketEntity.spawningEntity = user.getUUID(); // Paper -- world.addFreshEntity(fireworkRocketEntity); -- itemStack.consume(1, user); -- user.awardStat(Stats.ITEM_USED.get(this)); -+ // Paper start - PlayerElytraBoostEvent -+ com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand)); -+ if (event.callEvent() && world.addFreshEntity(fireworkRocketEntity)) { -+ user.awardStat(Stats.ITEM_USED.get(this)); -+ if (event.shouldConsume() && !user.hasInfiniteMaterials()) { -+ itemStack.shrink(1); -+ } else ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ // Paper end - PlayerElytraBoostEvent -+ } -+ -+ // user.awardStat(Stats.ITEM_USED.get(this)); // Paper - PlayerElytraBoostEvent; move up - } - - return InteractionResultHolder.sidedSuccess(user.getItemInHand(hand), world.isClientSide()); diff --git a/patches/unapplied/server/0213-PlayerLaunchProjectileEvent.patch b/patches/unapplied/server/0213-PlayerLaunchProjectileEvent.patch deleted file mode 100644 index be34c111d31a..000000000000 --- a/patches/unapplied/server/0213-PlayerLaunchProjectileEvent.patch +++ /dev/null @@ -1,363 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: BillyGalbreath -Date: Sat, 21 Jul 2018 03:11:03 -0500 -Subject: [PATCH] PlayerLaunchProjectileEvent - - -diff --git a/src/main/java/net/minecraft/world/item/EggItem.java b/src/main/java/net/minecraft/world/item/EggItem.java -index be7d1bfb13cf0afb80ba98f3b56602bccebeab64..4ebd634cff286b10868e26eeb3ecf34abdcab22e 100644 ---- a/src/main/java/net/minecraft/world/item/EggItem.java -+++ b/src/main/java/net/minecraft/world/item/EggItem.java -@@ -28,19 +28,31 @@ public class EggItem extends Item implements ProjectileItem { - - entityegg.setItem(itemstack); - entityegg.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F); -- // CraftBukkit start -- if (!world.addFreshEntity(entityegg)) { -+ // Paper start - PlayerLaunchProjectileEvent -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entityegg.getBukkitEntity()); -+ if (event.callEvent() && world.addFreshEntity(entityegg)) { -+ if (event.shouldConsume()) { -+ itemstack.consume(1, user); -+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ } -+ -+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), net.minecraft.sounds.SoundEvents.EGG_THROW, net.minecraft.sounds.SoundSource.PLAYERS, 0.5F, 0.4F / (net.minecraft.world.entity.Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F)); -+ user.awardStat(Stats.ITEM_USED.get(this)); -+ } else { - if (user instanceof net.minecraft.server.level.ServerPlayer) { - ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); - } - return InteractionResultHolder.fail(itemstack); - } -- // CraftBukkit end -+ // Paper end - PlayerLaunchProjectileEvent - } - world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EGG_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); - -+ /* // Paper start - PlayerLaunchProjectileEvent; moved up - user.awardStat(Stats.ITEM_USED.get(this)); - itemstack.consume(1, user); -+ */ // Paper end - PlayerLaunchProjectileEvent - return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide()); - } - -diff --git a/src/main/java/net/minecraft/world/item/EnderpearlItem.java b/src/main/java/net/minecraft/world/item/EnderpearlItem.java -index 48048204b619dd515253c8ffb05a0f7105ef7718..20a91d798d31a71b3c05efa2cc5bda55494e26cc 100644 ---- a/src/main/java/net/minecraft/world/item/EnderpearlItem.java -+++ b/src/main/java/net/minecraft/world/item/EnderpearlItem.java -@@ -25,7 +25,20 @@ public class EnderpearlItem extends Item { - - entityenderpearl.setItem(itemstack); - entityenderpearl.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F); -- if (!world.addFreshEntity(entityenderpearl)) { -+ // Paper start - PlayerLaunchProjectileEvent -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entityenderpearl.getBukkitEntity()); -+ if (event.callEvent() && world.addFreshEntity(entityenderpearl)) { -+ if (event.shouldConsume()) { -+ itemstack.consume(1, user); -+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ } -+ -+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (net.minecraft.world.entity.Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F)); -+ user.awardStat(Stats.ITEM_USED.get(this)); -+ user.getCooldowns().addCooldown(this, 20); -+ } else { -+ // Paper end - PlayerLaunchProjectileEvent - if (user instanceof net.minecraft.server.level.ServerPlayer) { - ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); - } -@@ -33,12 +46,14 @@ public class EnderpearlItem extends Item { - } - } - -+ /* // Paper start - PlayerLaunchProjectileEvent; moved up - world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); - user.getCooldowns().addCooldown(this, 20); - // CraftBukkit end - - user.awardStat(Stats.ITEM_USED.get(this)); - itemstack.consume(1, user); -+ */ // Paper end - PlayerLaunchProjectileEvent; moved up - return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide()); - } - } -diff --git a/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java b/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java -index 686f0fd87e06fa7552d66fd3e38a3e059c22f180..7448309b6dca619b6366aa55fe3a395a830ffbdd 100644 ---- a/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java -+++ b/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java -@@ -20,25 +20,44 @@ public class ExperienceBottleItem extends Item implements ProjectileItem { - @Override - public InteractionResultHolder use(Level world, Player user, InteractionHand hand) { - ItemStack itemStack = user.getItemInHand(hand); -- world.playSound( -- null, -- user.getX(), -- user.getY(), -- user.getZ(), -- SoundEvents.EXPERIENCE_BOTTLE_THROW, -- SoundSource.NEUTRAL, -- 0.5F, -- 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) -- ); -+ // Paper - PlayerLaunchProjectileEvent; moved down - if (!world.isClientSide) { - ThrownExperienceBottle thrownExperienceBottle = new ThrownExperienceBottle(world, user); - thrownExperienceBottle.setItem(itemStack); - thrownExperienceBottle.shootFromRotation(user, user.getXRot(), user.getYRot(), -20.0F, 0.7F, 1.0F); -- world.addFreshEntity(thrownExperienceBottle); -+ // Paper start - PlayerLaunchProjectileEvent -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownExperienceBottle.getBukkitEntity()); -+ if (event.callEvent() && world.addFreshEntity(thrownExperienceBottle)) { -+ if (event.shouldConsume()) { -+ itemStack.consume(1, user); -+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ } -+ -+ world.playSound( -+ null, -+ user.getX(), -+ user.getY(), -+ user.getZ(), -+ SoundEvents.EXPERIENCE_BOTTLE_THROW, -+ SoundSource.NEUTRAL, -+ 0.5F, -+ 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) -+ ); -+ user.awardStat(Stats.ITEM_USED.get(this)); -+ } else { -+ if (user instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ } -+ return InteractionResultHolder.fail(itemStack); -+ } -+ // Paper end - PlayerLaunchProjectileEvent - } - -+ /* // Paper start - PlayerLaunchProjectileEvent; moved up - user.awardStat(Stats.ITEM_USED.get(this)); - itemStack.consume(1, user); -+ */ // Paper end - PlayerLaunchProjectileEvent - return InteractionResultHolder.sidedSuccess(itemStack, world.isClientSide()); - } - -diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java -index 16da60b7ecf2e0d4a49804dfa1ad47d4ae672571..218f2f085309f04438f8b07bc41cf242583db2dc 100644 ---- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java -+++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java -@@ -43,8 +43,12 @@ public class FireworkRocketItem extends Item implements ProjectileItem { - itemStack - ); - fireworkRocketEntity.spawningEntity = context.getPlayer() == null ? null : context.getPlayer().getUUID(); // Paper -- level.addFreshEntity(fireworkRocketEntity); -- itemStack.shrink(1); -+ // Paper start - PlayerLaunchProjectileEvent -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.getBukkitEntity()); -+ if (!event.callEvent() || !level.addFreshEntity(fireworkRocketEntity)) return InteractionResult.PASS; -+ if (event.shouldConsume() && !context.getPlayer().getAbilities().instabuild) itemStack.shrink(1); -+ else if (context.getPlayer() instanceof net.minecraft.server.level.ServerPlayer) ((net.minecraft.server.level.ServerPlayer) context.getPlayer()).getBukkitEntity().updateInventory(); -+ // Paper end - PlayerLaunchProjectileEvent - } - - return InteractionResult.sidedSuccess(level.isClientSide); -diff --git a/src/main/java/net/minecraft/world/item/LingeringPotionItem.java b/src/main/java/net/minecraft/world/item/LingeringPotionItem.java -index b94888d359ec92bf7ef77b0610f41ba75185a26e..c9b511cc4f2499ca13e3cd8f1cdabdc225f66b9c 100644 ---- a/src/main/java/net/minecraft/world/item/LingeringPotionItem.java -+++ b/src/main/java/net/minecraft/world/item/LingeringPotionItem.java -@@ -24,6 +24,10 @@ public class LingeringPotionItem extends ThrowablePotionItem { - - @Override - public InteractionResultHolder use(Level world, Player user, InteractionHand hand) { -+ // Paper start - PlayerLaunchProjectileEvent -+ InteractionResultHolder wrapper = super.use(world, user, hand); -+ if (wrapper.getResult() != net.minecraft.world.InteractionResult.FAIL) { -+ // Paper end - PlayerLaunchProjectileEvent - world.playSound( - null, - user.getX(), -@@ -34,6 +38,9 @@ public class LingeringPotionItem extends ThrowablePotionItem { - 0.5F, - 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) - ); -- return super.use(world, user, hand); -+ // Paper start - PlayerLaunchProjectileEvent -+ } -+ return wrapper; -+ // Paper end - PlayerLaunchProjectileEvent - } - } -diff --git a/src/main/java/net/minecraft/world/item/SnowballItem.java b/src/main/java/net/minecraft/world/item/SnowballItem.java -index 2ae40936b31012fab0c7c42a7dea13b01ec6068f..32b170551a2f5bdc88d29f4d03750bfe3974e71b 100644 ---- a/src/main/java/net/minecraft/world/item/SnowballItem.java -+++ b/src/main/java/net/minecraft/world/item/SnowballItem.java -@@ -29,17 +29,26 @@ public class SnowballItem extends Item implements ProjectileItem { - - entitysnowball.setItem(itemstack); - entitysnowball.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F); -- if (world.addFreshEntity(entitysnowball)) { -- itemstack.consume(1, user); -+ // Paper start - PlayerLaunchProjectileEvent -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitysnowball.getBukkitEntity()); -+ if (event.callEvent() && world.addFreshEntity(entitysnowball)) { -+ user.awardStat(Stats.ITEM_USED.get(this)); -+ if (event.shouldConsume()) { -+ // Paper end - PlayerLaunchProjectileEvent -+ itemstack.consume(1, user); -+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { // Paper - PlayerLaunchProjectileEvent -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); // Paper - PlayerLaunchProjectileEvent -+ } - - world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.SNOWBALL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); -- } else if (user instanceof net.minecraft.server.level.ServerPlayer) { -- ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ } else { // Paper - PlayerLaunchProjectileEvent -+ if (user instanceof net.minecraft.server.level.ServerPlayer) ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); // Paper - PlayerLaunchProjectileEvent -+ return InteractionResultHolder.fail(itemstack); // Paper - PlayerLaunchProjectileEvent - } - } - // CraftBukkit end - -- user.awardStat(Stats.ITEM_USED.get(this)); -+ // user.awardStat(Stats.ITEM_USED.get(this)); // Paper - PlayerLaunchProjectileEvent; moved up - // itemstack.consume(1, entityhuman); // CraftBukkit - moved up - return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide()); - } -diff --git a/src/main/java/net/minecraft/world/item/SplashPotionItem.java b/src/main/java/net/minecraft/world/item/SplashPotionItem.java -index 935c34ba7eb14348becdd3ac0c29766abf7ca614..73bac60b3bf6d20d415a8250d0426251c0c3265b 100644 ---- a/src/main/java/net/minecraft/world/item/SplashPotionItem.java -+++ b/src/main/java/net/minecraft/world/item/SplashPotionItem.java -@@ -14,6 +14,10 @@ public class SplashPotionItem extends ThrowablePotionItem { - - @Override - public InteractionResultHolder use(Level world, Player user, InteractionHand hand) { -+ // Paper start - PlayerLaunchProjectileEvent -+ InteractionResultHolder wrapper = super.use(world, user, hand); -+ if (wrapper.getResult() != net.minecraft.world.InteractionResult.FAIL) { -+ // Paper end - PlayerLaunchProjectileEvent - world.playSound( - null, - user.getX(), -@@ -24,6 +28,9 @@ public class SplashPotionItem extends ThrowablePotionItem { - 0.5F, - 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) - ); -- return super.use(world, user, hand); -+ // Paper start - PlayerLaunchProjectileEvent -+ } -+ return wrapper; -+ // Paper end - PlayerLaunchProjectileEvent - } - } -diff --git a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java -index 12795451393e48f5c9ab4b1dfd9369e1ee6e0367..369955746f4b51f69fa01103e3771dd74fc6c8f0 100644 ---- a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java -+++ b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java -@@ -22,11 +22,29 @@ public class ThrowablePotionItem extends PotionItem implements ProjectileItem { - ThrownPotion thrownPotion = new ThrownPotion(world, user); - thrownPotion.setItem(itemStack); - thrownPotion.shootFromRotation(user, user.getXRot(), user.getYRot(), -20.0F, 0.5F, 1.0F); -- world.addFreshEntity(thrownPotion); -+ // Paper start - PlayerLaunchProjectileEvent -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownPotion.getBukkitEntity()); -+ if (event.callEvent() && world.addFreshEntity(thrownPotion)) { -+ if (event.shouldConsume()) { -+ itemStack.consume(1, user); -+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ } -+ -+ user.awardStat(Stats.ITEM_USED.get(this)); -+ } else { -+ if (user instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ } -+ return InteractionResultHolder.fail(itemStack); -+ } -+ // Paper end - PlayerLaunchProjectileEvent - } - -+ /* // Paper start - PlayerLaunchProjectileEvent; moved up - user.awardStat(Stats.ITEM_USED.get(this)); - itemStack.consume(1, user); -+ */ // Paper end - return InteractionResultHolder.sidedSuccess(itemStack, world.isClientSide()); - } - -diff --git a/src/main/java/net/minecraft/world/item/TridentItem.java b/src/main/java/net/minecraft/world/item/TridentItem.java -index 2d34f206b4b02d5f2ee35101233afc6b4f58a579..f1b2d388a1a40a1d909a2e726f32d6c15e1eb0eb 100644 ---- a/src/main/java/net/minecraft/world/item/TridentItem.java -+++ b/src/main/java/net/minecraft/world/item/TridentItem.java -@@ -87,19 +87,24 @@ public class TridentItem extends Item implements ProjectileItem { - } - - // CraftBukkit start -- if (!world.addFreshEntity(entitythrowntrident)) { -+ // Paper start - PlayerLaunchProjectileEvent -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), (org.bukkit.entity.Projectile) entitythrowntrident.getBukkitEntity()); -+ if (!event.callEvent() || !world.addFreshEntity(entitythrowntrident)) { -+ // Paper end - PlayerLaunchProjectileEvent - if (entityhuman instanceof net.minecraft.server.level.ServerPlayer) { - ((net.minecraft.server.level.ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); - } - return; - } - -+ if (event.shouldConsume()) { // Paper - PlayerLaunchProjectileEvent - stack.hurtAndBreak(1, entityhuman, LivingEntity.getSlotForHand(user.getUsedItemHand())); -+ } // Paper - PlayerLaunchProjectileEvent - entitythrowntrident.pickupItemStack = stack.copy(); // SPIGOT-4511 update since damage call moved - // CraftBukkit end - - world.playSound((Player) null, (Entity) entitythrowntrident, (SoundEvent) holder.value(), SoundSource.PLAYERS, 1.0F, 1.0F); -- if (!entityhuman.hasInfiniteMaterials()) { -+ if (event.shouldConsume() && !entityhuman.hasInfiniteMaterials()) { // Paper - PlayerLaunchProjectileEvent - entityhuman.getInventory().removeItem(stack); - } - // CraftBukkit start - SPIGOT-5458 also need in this branch :( -diff --git a/src/main/java/net/minecraft/world/item/WindChargeItem.java b/src/main/java/net/minecraft/world/item/WindChargeItem.java -index 6222e867bb959fab05bcd8f2114ab00b26847c3e..eed0d754e9a3c7c94614e0fd54651500e0612ea8 100644 ---- a/src/main/java/net/minecraft/world/item/WindChargeItem.java -+++ b/src/main/java/net/minecraft/world/item/WindChargeItem.java -@@ -24,10 +24,26 @@ public class WindChargeItem extends Item implements ProjectileItem { - - @Override - public InteractionResultHolder use(Level world, Player user, InteractionHand hand) { -+ ItemStack itemStack = user.getItemInHand(hand); // Paper - PlayerLaunchProjectileEvent; moved from below -+ boolean shouldConsume = true; // Paper - PlayerLaunchProjectileEvent - if (!world.isClientSide()) { - WindCharge windCharge = new WindCharge(user, world, user.position().x(), user.getEyePosition().y(), user.position().z()); - windCharge.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F); -- world.addFreshEntity(windCharge); -+ // Paper start - PlayerLaunchProjectileEvent -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) windCharge.getBukkitEntity()); -+ if (!event.callEvent() || !world.addFreshEntity(windCharge)) { -+ user.containerMenu.sendAllDataToRemote(); -+ if (user instanceof net.minecraft.server.level.ServerPlayer player) { -+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundCooldownPacket(this, 0)); // prevent visual desync of cooldown on the slot -+ } -+ return InteractionResultHolder.fail(itemStack); -+ } -+ -+ shouldConsume = event.shouldConsume(); -+ if (!shouldConsume && !user.hasInfiniteMaterials()) { -+ user.containerMenu.sendAllDataToRemote(); -+ } -+ // Paper end - PlayerLaunchProjectileEvent - } - - world.playSound( -@@ -40,10 +56,9 @@ public class WindChargeItem extends Item implements ProjectileItem { - 0.5F, - 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) - ); -- ItemStack itemStack = user.getItemInHand(hand); - user.getCooldowns().addCooldown(this, 10); - user.awardStat(Stats.ITEM_USED.get(this)); -- itemStack.consume(1, user); -+ if (shouldConsume) itemStack.consume(1, user); // Paper - PlayerLaunchProjectileEvent - return InteractionResultHolder.sidedSuccess(itemStack, world.isClientSide()); - } - From a400929816ca74a5b100da0aadc5793699f867bf Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Wed, 23 Oct 2024 12:32:08 +0200 Subject: [PATCH 013/119] 242 --- ...0213-Improve-BlockPosition-inlining.patch} | 2 +- ...-armor-stands-from-doing-entity-loo.patch} | 8 +- ...-Vanished-players-don-t-have-rights.patch} | 14 +- ...Allow-disabling-armor-stand-ticking.patch} | 16 +- .../0217-SkeletonHorse-Additions.patch} | 6 +- .../0218-Expand-ArmorStand-API.patch} | 2 +- .../0219-AnvilDamageEvent.patch} | 4 +- .../0220-Add-TNTPrimeEvent.patch} | 46 ++--- ...d-make-tab-spam-limits-configurable.patch} | 42 +++-- .../0222-Fix-NBT-type-issues.patch} | 10 +- ...emove-unnecessary-itemmeta-handling.patch} | 2 +- ...es-option-to-debug-dupe-uuid-issues.patch} | 4 +- ...d-Early-Warning-Feature-to-WatchDog.patch} | 14 +- ...6-Use-ConcurrentHashMap-in-JsonList.patch} | 4 +- ...7-Use-a-Queue-for-Queueing-Commands.patch} | 6 +- ...ock-entities-from-a-chunk-without-s.patch} | 2 +- ...timize-BlockPosition-helper-methods.patch} | 2 +- ...efault-mob-spawn-range-and-water-an.patch} | 0 .../0231-Slime-Pathfinder-Events.patch} | 22 +-- ...e-speed-for-water-flowing-over-lava.patch} | 10 +- ...33-Optimize-CraftBlockData-Creation.patch} | 8 +- .../0234-Optimize-MappedRegistry.patch} | 12 +- .../0235-Add-PhantomPreSpawnEvent.patch} | 14 +- .../0236-Add-More-Creeper-API.patch} | 6 +- .../0237-Inventory-removeItemAnySlot.patch} | 0 ...oadChunk-int-int-false-load-unconve.patch} | 4 +- ...ray-tracing-methods-to-LivingEntity.patch} | 8 +- ...-attack-cooldown-methods-for-Player.patch} | 4 +- .../0241-Improve-death-events.patch} | 170 +++++++++--------- 29 files changed, 223 insertions(+), 219 deletions(-) rename patches/{unapplied/server/0214-Improve-BlockPosition-inlining.patch => server/0213-Improve-BlockPosition-inlining.patch} (96%) rename patches/{unapplied/server/0215-Option-to-prevent-armor-stands-from-doing-entity-loo.patch => server/0214-Option-to-prevent-armor-stands-from-doing-entity-loo.patch} (85%) rename patches/{unapplied/server/0216-Vanished-players-don-t-have-rights.patch => server/0215-Vanished-players-don-t-have-rights.patch} (91%) rename patches/{unapplied/server/0217-Allow-disabling-armor-stand-ticking.patch => server/0216-Allow-disabling-armor-stand-ticking.patch} (90%) rename patches/{unapplied/server/0218-SkeletonHorse-Additions.patch => server/0217-SkeletonHorse-Additions.patch} (94%) rename patches/{unapplied/server/0219-Expand-ArmorStand-API.patch => server/0218-Expand-ArmorStand-API.patch} (98%) rename patches/{unapplied/server/0220-AnvilDamageEvent.patch => server/0219-AnvilDamageEvent.patch} (91%) rename patches/{unapplied/server/0221-Add-TNTPrimeEvent.patch => server/0220-Add-TNTPrimeEvent.patch} (76%) rename patches/{unapplied/server/0222-Break-up-and-make-tab-spam-limits-configurable.patch => server/0221-Break-up-and-make-tab-spam-limits-configurable.patch} (50%) rename patches/{unapplied/server/0223-Fix-NBT-type-issues.patch => server/0222-Fix-NBT-type-issues.patch} (83%) rename patches/{unapplied/server/0224-Remove-unnecessary-itemmeta-handling.patch => server/0223-Remove-unnecessary-itemmeta-handling.patch} (94%) rename patches/{unapplied/server/0225-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch => server/0224-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch} (92%) rename patches/{unapplied/server/0226-Add-Early-Warning-Feature-to-WatchDog.patch => server/0225-Add-Early-Warning-Feature-to-WatchDog.patch} (94%) rename patches/{unapplied/server/0227-Use-ConcurrentHashMap-in-JsonList.patch => server/0226-Use-ConcurrentHashMap-in-JsonList.patch} (97%) rename patches/{unapplied/server/0228-Use-a-Queue-for-Queueing-Commands.patch => server/0227-Use-a-Queue-for-Queueing-Commands.patch} (90%) rename patches/{unapplied/server/0229-Ability-to-get-block-entities-from-a-chunk-without-s.patch => server/0228-Ability-to-get-block-entities-from-a-chunk-without-s.patch} (95%) rename patches/{unapplied/server/0230-Optimize-BlockPosition-helper-methods.patch => server/0229-Optimize-BlockPosition-helper-methods.patch} (97%) rename patches/{unapplied/server/0231-Restore-vanilla-default-mob-spawn-range-and-water-an.patch => server/0230-Restore-vanilla-default-mob-spawn-range-and-water-an.patch} (100%) rename patches/{unapplied/server/0232-Slime-Pathfinder-Events.patch => server/0231-Slime-Pathfinder-Events.patch} (90%) rename patches/{unapplied/server/0233-Configurable-speed-for-water-flowing-over-lava.patch => server/0232-Configurable-speed-for-water-flowing-over-lava.patch} (82%) rename patches/{unapplied/server/0234-Optimize-CraftBlockData-Creation.patch => server/0233-Optimize-CraftBlockData-Creation.patch} (89%) rename patches/{unapplied/server/0235-Optimize-MappedRegistry.patch => server/0234-Optimize-MappedRegistry.patch} (81%) rename patches/{unapplied/server/0236-Add-PhantomPreSpawnEvent.patch => server/0235-Add-PhantomPreSpawnEvent.patch} (89%) rename patches/{unapplied/server/0237-Add-More-Creeper-API.patch => server/0236-Add-More-Creeper-API.patch} (89%) rename patches/{unapplied/server/0238-Inventory-removeItemAnySlot.patch => server/0237-Inventory-removeItemAnySlot.patch} (100%) rename patches/{unapplied/server/0239-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch => server/0238-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch} (87%) rename patches/{unapplied/server/0240-Add-ray-tracing-methods-to-LivingEntity.patch => server/0239-Add-ray-tracing-methods-to-LivingEntity.patch} (91%) rename patches/{unapplied/server/0241-Expose-attack-cooldown-methods-for-Player.patch => server/0240-Expose-attack-cooldown-methods-for-Player.patch} (86%) rename patches/{unapplied/server/0242-Improve-death-events.patch => server/0241-Improve-death-events.patch} (78%) diff --git a/patches/unapplied/server/0214-Improve-BlockPosition-inlining.patch b/patches/server/0213-Improve-BlockPosition-inlining.patch similarity index 96% rename from patches/unapplied/server/0214-Improve-BlockPosition-inlining.patch rename to patches/server/0213-Improve-BlockPosition-inlining.patch index 469c5f739033..e1e44f61f0c1 100644 --- a/patches/unapplied/server/0214-Improve-BlockPosition-inlining.patch +++ b/patches/server/0213-Improve-BlockPosition-inlining.patch @@ -21,7 +21,7 @@ This is based upon conclusions drawn from inspecting the assenmbly generated byt They had 'callq' (invoke) instead of 'mov' (get from memory) instructions. diff --git a/src/main/java/net/minecraft/core/Vec3i.java b/src/main/java/net/minecraft/core/Vec3i.java -index ea4660fe600db94e97a5dd335135f76dd5951468..df4c9b275752ad97a4efe9380ae0d511ee760695 100644 +index 671550477476a7252a52686aa60fe6454eda2055..7d5f99cac756c54e5922bf85d5d359edcc21f1e8 100644 --- a/src/main/java/net/minecraft/core/Vec3i.java +++ b/src/main/java/net/minecraft/core/Vec3i.java @@ -35,12 +35,12 @@ public class Vec3i implements Comparable { diff --git a/patches/unapplied/server/0215-Option-to-prevent-armor-stands-from-doing-entity-loo.patch b/patches/server/0214-Option-to-prevent-armor-stands-from-doing-entity-loo.patch similarity index 85% rename from patches/unapplied/server/0215-Option-to-prevent-armor-stands-from-doing-entity-loo.patch rename to patches/server/0214-Option-to-prevent-armor-stands-from-doing-entity-loo.patch index fbe09d503180..db5ae6ef6478 100644 --- a/patches/unapplied/server/0215-Option-to-prevent-armor-stands-from-doing-entity-loo.patch +++ b/patches/server/0214-Option-to-prevent-armor-stands-from-doing-entity-loo.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Option to prevent armor stands from doing entity lookups diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -index dae6835696e90bc5a541cacd37ea7aa88c60f4f4..1057679ceec86898a3e62bd183c6944f561aa7fd 100644 +index aea97a30a9226275f8fbf9cb2c15d5ddf36371ac..e9d6211eb0f955eb95d2f73ad96799ef4740d506 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -343,6 +343,7 @@ public class ArmorStand extends LivingEntity { +@@ -348,6 +348,7 @@ public class ArmorStand extends LivingEntity { @Override protected void pushEntities() { @@ -17,10 +17,10 @@ index dae6835696e90bc5a541cacd37ea7aa88c60f4f4..1057679ceec86898a3e62bd183c6944f Iterator iterator = list.iterator(); diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 6944c0b0cfcde9fa4dd78742aee3e3b87d679abf..a9227581ec78a56e96dc3a342006e4a649906326 100644 +index c628524274110bcad175472dbcb82e6c62476a12..3ccd28193bec6363eb87f916589310ee8b45dd3a 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -764,6 +764,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -766,6 +766,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Paper end - Prevent block entity and entity crashes } } diff --git a/patches/unapplied/server/0216-Vanished-players-don-t-have-rights.patch b/patches/server/0215-Vanished-players-don-t-have-rights.patch similarity index 91% rename from patches/unapplied/server/0216-Vanished-players-don-t-have-rights.patch rename to patches/server/0215-Vanished-players-don-t-have-rights.patch index 5820c721da9c..59109ecdaa09 100644 --- a/patches/unapplied/server/0216-Vanished-players-don-t-have-rights.patch +++ b/patches/server/0215-Vanished-players-don-t-have-rights.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Vanished players don't have rights diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index a39de724848d6dc796dd99dde5206f20e513fd18..30eb86b52f00cfa61af4f93aca50ffc3547c95e8 100644 +index 55c0d23ea68cd328881bd40d6bfd12d58477d15b..e7fe338572a8bb740d6023c688d8c84ea04a2169 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -288,6 +288,15 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -387,6 +387,15 @@ public abstract class Projectile extends Entity implements TraceableEntity { } else { Entity entity1 = this.getOwner(); @@ -25,10 +25,10 @@ index a39de724848d6dc796dd99dde5206f20e513fd18..30eb86b52f00cfa61af4f93aca50ffc3 } } diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java -index 6ca74a5cf691ee92c84bd031e875f72440df6b32..cee3f1200af602b5dfd0b27d05eb01826c5bbb1d 100644 +index 752929f3bcd6404b08dad1c67e9a0023b671f10d..407f5db0a4b3884440bc49bf4f00d9c035899e86 100644 --- a/src/main/java/net/minecraft/world/item/BlockItem.java +++ b/src/main/java/net/minecraft/world/item/BlockItem.java -@@ -174,7 +174,8 @@ public class BlockItem extends Item { +@@ -168,7 +168,8 @@ public class BlockItem extends Item { Player entityhuman = context.getPlayer(); CollisionContext voxelshapecollision = entityhuman == null ? CollisionContext.empty() : CollisionContext.of(entityhuman); // CraftBukkit start - store default return @@ -39,7 +39,7 @@ index 6ca74a5cf691ee92c84bd031e875f72440df6b32..cee3f1200af602b5dfd0b27d05eb0182 BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(context.getLevel(), context.getClickedPos()), player, CraftBlockData.fromData(state), defaultReturn); diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index a9227581ec78a56e96dc3a342006e4a649906326..5929b450a26e7c3cf63de3dc1d0e67cb781b24c7 100644 +index 3ccd28193bec6363eb87f916589310ee8b45dd3a..cf422de89f0ed81e7c9759328e28ca6b190283ef 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -265,6 +265,45 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -89,10 +89,10 @@ index a9227581ec78a56e96dc3a342006e4a649906326..5929b450a26e7c3cf63de3dc1d0e67cb public boolean isClientSide() { return this.isClientSide; diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 9b6607700ed23b97755a2171a49b22d498a60626..0613bdf3c2325d5cab64783af7211b07fcf5124a 100644 +index 41c6a7260317ed575a3320ac36b0f2be22c120aa..474f330f381aa74e9f2fd0accdbaf2617ec1c557 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1329,6 +1329,14 @@ public class CraftEventFactory { +@@ -1327,6 +1327,14 @@ public class CraftEventFactory { Projectile projectile = (Projectile) entity.getBukkitEntity(); org.bukkit.entity.Entity collided = position.getEntity().getBukkitEntity(); com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = new com.destroystokyo.paper.event.entity.ProjectileCollideEvent(projectile, collided); diff --git a/patches/unapplied/server/0217-Allow-disabling-armor-stand-ticking.patch b/patches/server/0216-Allow-disabling-armor-stand-ticking.patch similarity index 90% rename from patches/unapplied/server/0217-Allow-disabling-armor-stand-ticking.patch rename to patches/server/0216-Allow-disabling-armor-stand-ticking.patch index bf0bbc008ecd..52031cba6b57 100644 --- a/patches/unapplied/server/0217-Allow-disabling-armor-stand-ticking.patch +++ b/patches/server/0216-Allow-disabling-armor-stand-ticking.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Allow disabling armor stand ticking diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -index 1057679ceec86898a3e62bd183c6944f561aa7fd..ee3902cbada46ffb78c42dbf6f00c859546c76e1 100644 +index e9d6211eb0f955eb95d2f73ad96799ef4740d506..2caba38a50b7ea535337a3540aa5272d4a9f1878 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -96,9 +96,16 @@ public class ArmorStand extends LivingEntity { +@@ -108,9 +108,16 @@ public class ArmorStand extends LivingEntity { public Rotations leftLegPose; public Rotations rightLegPose; public boolean canMove = true; // Paper @@ -25,7 +25,7 @@ index 1057679ceec86898a3e62bd183c6944f561aa7fd..ee3902cbada46ffb78c42dbf6f00c859 this.handItems = NonNullList.withSize(2, ItemStack.EMPTY); this.armorItems = NonNullList.withSize(4, ItemStack.EMPTY); this.headPose = ArmorStand.DEFAULT_HEAD_POSE; -@@ -201,6 +208,7 @@ public class ArmorStand extends LivingEntity { +@@ -213,6 +220,7 @@ public class ArmorStand extends LivingEntity { this.onEquipItem(enumitemslot, (ItemStack) this.armorItems.set(enumitemslot.getIndex(), itemstack), itemstack, silent); // CraftBukkit } @@ -33,7 +33,7 @@ index 1057679ceec86898a3e62bd183c6944f561aa7fd..ee3902cbada46ffb78c42dbf6f00c859 } @Override -@@ -243,6 +251,7 @@ public class ArmorStand extends LivingEntity { +@@ -248,6 +256,7 @@ public class ArmorStand extends LivingEntity { } nbt.put("Pose", this.writePose()); @@ -41,7 +41,7 @@ index 1057679ceec86898a3e62bd183c6944f561aa7fd..ee3902cbada46ffb78c42dbf6f00c859 } @Override -@@ -277,6 +286,12 @@ public class ArmorStand extends LivingEntity { +@@ -282,6 +291,12 @@ public class ArmorStand extends LivingEntity { this.setNoBasePlate(nbt.getBoolean("NoBasePlate")); this.setMarker(nbt.getBoolean("Marker")); this.noPhysics = !this.hasPhysics(); @@ -54,7 +54,7 @@ index 1057679ceec86898a3e62bd183c6944f561aa7fd..ee3902cbada46ffb78c42dbf6f00c859 CompoundTag nbttagcompound2 = nbt.getCompound("Pose"); this.readPose(nbttagcompound2); -@@ -664,7 +679,29 @@ public class ArmorStand extends LivingEntity { +@@ -661,7 +676,29 @@ public class ArmorStand extends LivingEntity { @Override public void tick() { @@ -84,7 +84,7 @@ index 1057679ceec86898a3e62bd183c6944f561aa7fd..ee3902cbada46ffb78c42dbf6f00c859 Rotations vector3f = (Rotations) this.entityData.get(ArmorStand.DATA_HEAD_POSE); if (!this.headPose.equals(vector3f)) { -@@ -799,31 +836,37 @@ public class ArmorStand extends LivingEntity { +@@ -796,31 +833,37 @@ public class ArmorStand extends LivingEntity { public void setHeadPose(Rotations angle) { this.headPose = angle; this.entityData.set(ArmorStand.DATA_HEAD_POSE, angle); @@ -123,7 +123,7 @@ index 1057679ceec86898a3e62bd183c6944f561aa7fd..ee3902cbada46ffb78c42dbf6f00c859 public Rotations getHeadPose() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java -index 52ffc401bbb9fa768534a4b871f9cc7dbebb8b20..9923cea74ba39a774d6b16a225bc3e455e54c418 100644 +index 56fcd9dd40e6a63e1af5fbd470ece0d6100292a2..1bb080a8af45411b68a0f2a3c40718d60fdc9d97 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java @@ -232,5 +232,16 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { diff --git a/patches/unapplied/server/0218-SkeletonHorse-Additions.patch b/patches/server/0217-SkeletonHorse-Additions.patch similarity index 94% rename from patches/unapplied/server/0218-SkeletonHorse-Additions.patch rename to patches/server/0217-SkeletonHorse-Additions.patch index 3d2b910a9bb2..2b721231ef21 100644 --- a/patches/unapplied/server/0218-SkeletonHorse-Additions.patch +++ b/patches/server/0217-SkeletonHorse-Additions.patch @@ -5,7 +5,7 @@ Subject: [PATCH] SkeletonHorse Additions diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java -index 3cb84856c10347162a8736ae1ef65165183ec8fe..5042d1d10061d611c6d283a1a1ba9f94c5ba1db5 100644 +index 521b09ac14372f524b06ffdce57932d0a590700b..b782fd54d94d1a1704ddc8e7bfda03d3aefbccbe 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java @@ -20,6 +20,7 @@ import net.minecraft.world.item.enchantment.providers.VanillaEnchantmentProvider @@ -32,10 +32,10 @@ index 3cb84856c10347162a8736ae1ef65165183ec8fe..5042d1d10061d611c6d283a1a1ba9f94 this.horse.setTrap(false); diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java -index 77ae7882a08441d9a80b50492be5e48487a2fdab..d465fb01af4c8610f83ecb9c68b83127cf7e95ae 100644 +index fb043d67eaa6336fc0b5d62774b8f1107f9dfa1e..dac8305f1c897e6f82a2dde67c5b1b6b8b649b19 100644 --- a/src/main/java/net/minecraft/world/level/EntityGetter.java +++ b/src/main/java/net/minecraft/world/level/EntityGetter.java -@@ -97,6 +97,28 @@ public interface EntityGetter { +@@ -94,6 +94,28 @@ public interface EntityGetter { return player; } diff --git a/patches/unapplied/server/0219-Expand-ArmorStand-API.patch b/patches/server/0218-Expand-ArmorStand-API.patch similarity index 98% rename from patches/unapplied/server/0219-Expand-ArmorStand-API.patch rename to patches/server/0218-Expand-ArmorStand-API.patch index d68ca34219b0..c5c95632422d 100644 --- a/patches/unapplied/server/0219-Expand-ArmorStand-API.patch +++ b/patches/server/0218-Expand-ArmorStand-API.patch @@ -14,7 +14,7 @@ public net.minecraft.world.entity.decoration.ArmorStand isDisabled(Lnet/minecraf Co-authored-by: SoSeDiK diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java -index 9923cea74ba39a774d6b16a225bc3e455e54c418..1087840331f68ffe79e79f6493137b2b894832f9 100644 +index 1bb080a8af45411b68a0f2a3c40718d60fdc9d97..e1cedcb95e9b2e2e9587b623256b5cffa7b08ce4 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java @@ -233,6 +233,149 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { diff --git a/patches/unapplied/server/0220-AnvilDamageEvent.patch b/patches/server/0219-AnvilDamageEvent.patch similarity index 91% rename from patches/unapplied/server/0220-AnvilDamageEvent.patch rename to patches/server/0219-AnvilDamageEvent.patch index 7437518ee295..8e5891eb7c10 100644 --- a/patches/unapplied/server/0220-AnvilDamageEvent.patch +++ b/patches/server/0219-AnvilDamageEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] AnvilDamageEvent diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java -index 4a6295c0133606131c2b2b881b4dbe7f1e3e47b0..ffda2c984c5683edb38a56f04c53b0ea339e08fc 100644 +index ab59f5cdd5ce76a0408f4b6ce907e7be103d7950..126565e673e94b9c66aa4547596bbf198c57c7ad 100644 --- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java -@@ -110,6 +110,16 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -111,6 +111,16 @@ public class AnvilMenu extends ItemCombinerMenu { if (!player.hasInfiniteMaterials() && iblockdata.is(BlockTags.ANVIL) && player.getRandom().nextFloat() < 0.12F) { BlockState iblockdata1 = AnvilBlock.damage(iblockdata); diff --git a/patches/unapplied/server/0221-Add-TNTPrimeEvent.patch b/patches/server/0220-Add-TNTPrimeEvent.patch similarity index 76% rename from patches/unapplied/server/0221-Add-TNTPrimeEvent.patch rename to patches/server/0220-Add-TNTPrimeEvent.patch index 1dc0962e1dee..4cf9d4305050 100644 --- a/patches/unapplied/server/0221-Add-TNTPrimeEvent.patch +++ b/patches/server/0220-Add-TNTPrimeEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add TNTPrimeEvent diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -index b02a77b486f8d5eee31850de4a1b033fe6a107c7..a2cde7b1b316e43382cb1639ffccf29d89f5ebfc 100644 +index ba1bb0f82634054e02c5f4bc062c1822a356e2a6..25d2226c2a5dda411a9e35f7a0e3ab183110c227 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -@@ -573,6 +573,11 @@ public class EnderDragon extends Mob implements Enemy { +@@ -543,6 +543,11 @@ public class EnderDragon extends Mob implements Enemy { }); craftBlock.getNMS().spawnAfterBreak((ServerLevel) this.level(), blockposition, ItemStack.EMPTY, false); } @@ -17,11 +17,11 @@ index b02a77b486f8d5eee31850de4a1b033fe6a107c7..a2cde7b1b316e43382cb1639ffccf29d + if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.EXPLOSION, explosionSource.getIndirectSourceEntity().getBukkitEntity()).callEvent()) + continue; + // Paper end - TNTPrimeEvent - nmsBlock.wasExploded(this.level(), blockposition, this.explosionSource); + nmsBlock.wasExploded((ServerLevel) this.level(), blockposition, this.explosionSource); this.level().removeBlock(blockposition, false); diff --git a/src/main/java/net/minecraft/world/level/block/FireBlock.java b/src/main/java/net/minecraft/world/level/block/FireBlock.java -index b288db03dd5385a8a9cc49a8a7d89a9fab7224a7..c1111bd8065b53cb140e4289cb72985f03e6f549 100644 +index 88976aa06028adcb8f0c91e32b794887d0b55308..f44457c0d75efe323cc8242ef5173a3d5067fad0 100644 --- a/src/main/java/net/minecraft/world/level/block/FireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java @@ -302,12 +302,19 @@ public class FireBlock extends BaseFireBlock { @@ -46,10 +46,10 @@ index b288db03dd5385a8a9cc49a8a7d89a9fab7224a7..c1111bd8065b53cb140e4289cb72985f } } diff --git a/src/main/java/net/minecraft/world/level/block/TntBlock.java b/src/main/java/net/minecraft/world/level/block/TntBlock.java -index d80b4b3b38069016a5238f619fa3b156f576d9ae..4896ddca849646135ae101236e534ab8f59bd617 100644 +index 5e14568b325dc805e507d23ae66e789fc35ec3df..d256b0f3998028709334dd6c394d184f2c36efce 100644 --- a/src/main/java/net/minecraft/world/level/block/TntBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TntBlock.java -@@ -50,6 +50,12 @@ public class TntBlock extends Block { +@@ -52,6 +52,12 @@ public class TntBlock extends Block { protected void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { if (!oldState.is(state.getBlock())) { if (world.hasNeighborSignal(pos) && CraftEventFactory.callTNTPrimeEvent(world, pos, PrimeCause.REDSTONE, null, null)) { // CraftBukkit - TNTPrimeEvent @@ -62,10 +62,10 @@ index d80b4b3b38069016a5238f619fa3b156f576d9ae..4896ddca849646135ae101236e534ab8 TntBlock.explode(world, pos); world.removeBlock(pos, false); } -@@ -60,6 +66,12 @@ public class TntBlock extends Block { +@@ -62,6 +68,12 @@ public class TntBlock extends Block { @Override - protected void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) { - if (world.hasNeighborSignal(pos) && CraftEventFactory.callTNTPrimeEvent(world, pos, PrimeCause.REDSTONE, null, sourcePos)) { // CraftBukkit - TNTPrimeEvent + protected void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, @Nullable Orientation wireOrientation, boolean notify) { + if (world.hasNeighborSignal(pos) && CraftEventFactory.callTNTPrimeEvent(world, pos, PrimeCause.REDSTONE, null, null)) { // CraftBukkit - TNTPrimeEvent + // Paper start - TNTPrimeEvent + org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos); + if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) { @@ -75,28 +75,28 @@ index d80b4b3b38069016a5238f619fa3b156f576d9ae..4896ddca849646135ae101236e534ab8 TntBlock.explode(world, pos); world.removeBlock(pos, false); } -@@ -78,6 +90,13 @@ public class TntBlock extends Block { +@@ -79,6 +91,13 @@ public class TntBlock extends Block { + @Override - public void wasExploded(Level world, BlockPos pos, Explosion explosion) { - if (!world.isClientSide) { -+ // Paper start - TNTPrimeEvent -+ org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos); -+ org.bukkit.entity.Entity source = explosion.source != null ? explosion.source.getBukkitEntity() : null; -+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.EXPLOSION, source).callEvent()) { -+ return; -+ } -+ // Paper end - TNTPrimeEvent - PrimedTnt entitytntprimed = new PrimedTnt(world, (double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D, explosion.getIndirectSourceEntity()); - int i = entitytntprimed.getFuse(); + public void wasExploded(ServerLevel world, BlockPos pos, Explosion explosion) { ++ // Paper start - TNTPrimeEvent ++ org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos); ++ org.bukkit.entity.Entity source = explosion.getDirectSourceEntity() != null ? explosion.getDirectSourceEntity().getBukkitEntity() : null; ++ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.EXPLOSION, source).callEvent()) { ++ return; ++ } ++ // Paper end - TNTPrimeEvent + PrimedTnt entitytntprimed = new PrimedTnt(world, (double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D, explosion.getIndirectSourceEntity()); + int i = entitytntprimed.getFuse(); @@ -110,6 +129,12 @@ public class TntBlock extends Block { - return ItemInteractionResult.CONSUME; + return InteractionResult.CONSUME; } // CraftBukkit end + // Paper start - TNTPrimeEvent + org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos); + if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.ITEM, player.getBukkitEntity()).callEvent()) { -+ return ItemInteractionResult.FAIL; ++ return InteractionResult.FAIL; + } + // Paper end - TNTPrimeEvent TntBlock.explode(world, pos, player); diff --git a/patches/unapplied/server/0222-Break-up-and-make-tab-spam-limits-configurable.patch b/patches/server/0221-Break-up-and-make-tab-spam-limits-configurable.patch similarity index 50% rename from patches/unapplied/server/0222-Break-up-and-make-tab-spam-limits-configurable.patch rename to patches/server/0221-Break-up-and-make-tab-spam-limits-configurable.patch index 504d5c5e397a..2320ac4554c6 100644 --- a/patches/unapplied/server/0222-Break-up-and-make-tab-spam-limits-configurable.patch +++ b/patches/server/0221-Break-up-and-make-tab-spam-limits-configurable.patch @@ -22,31 +22,39 @@ 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 0321128ab745250e79fa5f66079c9aeb7f394cc0..5ed35d744a87290a03e9bf58143b5650501af0e6 100644 +index bcceb9d18524ddcf7cdf2ab6dcb95a67f1155414..816b53894c6420a6b1603252e53facacecc07c52 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -265,6 +265,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -7,6 +7,7 @@ import com.mojang.brigadier.ParseResults; + import com.mojang.brigadier.StringReader; + import com.mojang.brigadier.suggestion.Suggestions; + import com.mojang.logging.LogUtils; ++import io.papermc.paper.configuration.GlobalConfiguration; + import it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry; + import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; + import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +@@ -272,6 +273,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + private int tickCount; private int ackBlockChangesUpTo = -1; - // CraftBukkit start - multithreaded fields - private final AtomicInteger chatSpamTickCount = new AtomicInteger(); -+ private final java.util.concurrent.atomic.AtomicInteger tabSpamLimiter = new java.util.concurrent.atomic.AtomicInteger(); // Paper - configurable tab spam limits - // CraftBukkit end - private int dropSpamTickCount; + private final TickThrottler chatSpamThrottler = new TickThrottler(20, 200); ++ private final TickThrottler tabSpamThrottler = new TickThrottler(GlobalConfiguration.get().spamLimiter.tabSpamIncrement, GlobalConfiguration.get().spamLimiter.tabSpamLimit); // Paper - configurable tab spam limits + private final TickThrottler dropSpamThrottler = new TickThrottler(20, 1480); private double firstGoodX; -@@ -381,6 +382,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + private double firstGoodY; +@@ -387,6 +389,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + this.keepConnectionAlive(); - // CraftBukkit start - for (int spam; (spam = this.chatSpamTickCount.get()) > 0 && !this.chatSpamTickCount.compareAndSet(spam, spam - 1); ) ; -+ if (tabSpamLimiter.get() > 0) tabSpamLimiter.getAndDecrement(); // Paper - configurable tab spam limits - /* Use thread-safe field access instead - if (this.chatSpamTickCount > 0) { - --this.chatSpamTickCount; -@@ -719,7 +721,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + this.chatSpamThrottler.tick(); ++ this.tabSpamThrottler.tick(); // Paper - configurable tab spam limits + this.dropSpamThrottler.tick(); + if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L) { + this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 +@@ -722,7 +725,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) { // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async // CraftBukkit start -- if (this.chatSpamTickCount.addAndGet(1) > 500 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { -+ if (this.chatSpamTickCount.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamLimit && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { // Paper - configurable tab spam limits +- if (!this.chatSpamThrottler.isIncrementAndUnderThreshold(1, 500) && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { ++ if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - configurable tab spam limits this.disconnect(Component.translatable("disconnect.spam")); return; } diff --git a/patches/unapplied/server/0223-Fix-NBT-type-issues.patch b/patches/server/0222-Fix-NBT-type-issues.patch similarity index 83% rename from patches/unapplied/server/0223-Fix-NBT-type-issues.patch rename to patches/server/0222-Fix-NBT-type-issues.patch index 7444db91d20e..bae1fe439363 100644 --- a/patches/unapplied/server/0223-Fix-NBT-type-issues.patch +++ b/patches/server/0222-Fix-NBT-type-issues.patch @@ -8,10 +8,10 @@ Addresses two issues: - Allay duplication cooldown is saved and exposed as a long, but loaded as an int diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -index 2d438cd3e69503fdc45a706f25c219af6f7a5db3..0916e24271d07ad5db51c5bc68791722b0f69c2b 100644 +index 74a0bebbf829fdb2bbae87100c4e2523c34f95a0..9d9e3daebc5da0af627c3d3cdb50029aacbc587b 100644 --- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java +++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -@@ -305,7 +305,7 @@ public class ExperienceOrb extends Entity { +@@ -309,7 +309,7 @@ public class ExperienceOrb extends Entity { public void addAdditionalSaveData(CompoundTag nbt) { nbt.putShort("Health", (short) this.health); nbt.putShort("Age", (short) this.age); @@ -20,7 +20,7 @@ index 2d438cd3e69503fdc45a706f25c219af6f7a5db3..0916e24271d07ad5db51c5bc68791722 nbt.putInt("Count", this.count); this.savePaperNBT(nbt); // Paper } -@@ -314,7 +314,7 @@ public class ExperienceOrb extends Entity { +@@ -318,7 +318,7 @@ public class ExperienceOrb extends Entity { public void readAdditionalSaveData(CompoundTag nbt) { this.health = nbt.getShort("Health"); this.age = nbt.getShort("Age"); @@ -30,10 +30,10 @@ index 2d438cd3e69503fdc45a706f25c219af6f7a5db3..0916e24271d07ad5db51c5bc68791722 this.loadPaperNBT(nbt); // Paper } diff --git a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java -index 56b9123b42d05e0fb20763b8988aa68583a36781..69986f75d3cf729204cca0c7e5428536af31f695 100644 +index c0c054b604cdf87591e4ce7c9f15baa5c942aadc..05c3d43fafc781e2c2d762dd5f509753df8da3b3 100644 --- a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java +++ b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java -@@ -489,7 +489,7 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS +@@ -495,7 +495,7 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS }); } diff --git a/patches/unapplied/server/0224-Remove-unnecessary-itemmeta-handling.patch b/patches/server/0223-Remove-unnecessary-itemmeta-handling.patch similarity index 94% rename from patches/unapplied/server/0224-Remove-unnecessary-itemmeta-handling.patch rename to patches/server/0223-Remove-unnecessary-itemmeta-handling.patch index 787fe866f3bf..d573a1e6f964 100644 --- a/patches/unapplied/server/0224-Remove-unnecessary-itemmeta-handling.patch +++ b/patches/server/0223-Remove-unnecessary-itemmeta-handling.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Remove unnecessary itemmeta handling diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 1138d238caa18171b6562cc748c92cec03bfbb97..b0d0e08e81e3b87e5d4faf62e9afe9606c254115 100644 +index 1ebaedc9617e5b79458fa119887fd72cb1f39852..957c112b4145fda5078a6f8f1689935fa0290806 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java @@ -165,7 +165,7 @@ public final class ItemStack implements DataComponentHolder { diff --git a/patches/unapplied/server/0225-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch b/patches/server/0224-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch similarity index 92% rename from patches/unapplied/server/0225-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch rename to patches/server/0224-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch index 07722aef159f..c1032d9949c9 100644 --- a/patches/unapplied/server/0225-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch +++ b/patches/server/0224-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Debug Entities option to debug dupe uuid issues diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 4f777c9d8c3052f68bc0465c8a7386b8fb486c83..e9d08662c065d04a67918f0aa2cd4fde5798f2a6 100644 +index 438c936fceede5b21435e1f37f2372072a9d4571..3f4d3e2f45c2b2228a333076ec1f34228560593e 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1201,6 +1201,12 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1196,6 +1196,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // CraftBukkit start private boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) { org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot diff --git a/patches/unapplied/server/0226-Add-Early-Warning-Feature-to-WatchDog.patch b/patches/server/0225-Add-Early-Warning-Feature-to-WatchDog.patch similarity index 94% rename from patches/unapplied/server/0226-Add-Early-Warning-Feature-to-WatchDog.patch rename to patches/server/0225-Add-Early-Warning-Feature-to-WatchDog.patch index babdb2e00b00..86e962e7dfc8 100644 --- a/patches/unapplied/server/0226-Add-Early-Warning-Feature-to-WatchDog.patch +++ b/patches/server/0225-Add-Early-Warning-Feature-to-WatchDog.patch @@ -9,10 +9,10 @@ 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 cc0968182ab597892dbae8dd9b3e803fb62b7065..2d5ae71c143556a938f078d2fb84cab7bd4f789b 100644 +index 6abcb987109c01d012c70c4c3b411f91b7630bb4..cc15ec47155ee16377a65c9f56a62339dc0a129d 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1107,6 +1107,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements WritableRegistry { - private static final Logger LOGGER = LogUtils.getLogger(); - final ResourceKey> key; +@@ -33,11 +33,11 @@ import net.minecraft.util.RandomSource; + public class MappedRegistry implements WritableRegistry { + private final ResourceKey> key; private final ObjectList> byId = new ObjectArrayList<>(256); - private final Reference2IntMap toId = Util.make(new Reference2IntOpenHashMap<>(), map -> map.defaultReturnValue(-1)); - private final Map> byLocation = new HashMap<>(); @@ -26,5 +26,5 @@ index 1dcbde18bd9c462cca48887b904a9c43261e1854..edbbafd1705345282e5e6251eb71bfde + private final Map> byValue = new IdentityHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions + private final Map, RegistrationInfo> registrationInfos = new IdentityHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions private Lifecycle registryLifecycle; - private volatile Map, HolderSet.Named> tags = new IdentityHashMap<>(); - private boolean frozen; + private final Map, HolderSet.Named> frozenTags = new IdentityHashMap<>(); + MappedRegistry.TagSet allTags = MappedRegistry.TagSet.unbound(); diff --git a/patches/unapplied/server/0236-Add-PhantomPreSpawnEvent.patch b/patches/server/0235-Add-PhantomPreSpawnEvent.patch similarity index 89% rename from patches/unapplied/server/0236-Add-PhantomPreSpawnEvent.patch rename to patches/server/0235-Add-PhantomPreSpawnEvent.patch index 42c7ae9133a3..3398693ce432 100644 --- a/patches/unapplied/server/0236-Add-PhantomPreSpawnEvent.patch +++ b/patches/server/0235-Add-PhantomPreSpawnEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PhantomPreSpawnEvent diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java -index 81e75e9d6619f7108fd769e462f24d72cbd5a73c..3c3f70d05fb51b530b792adf84c324840bd03c14 100644 +index d9d374e18b1cacf0b04e6e02f3a94b145f4052fb..748f07c7036fe5955d76e28c4e7d23f8c0235d5f 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java +++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java -@@ -165,6 +165,11 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -161,6 +161,11 @@ public class Phantom extends FlyingMob implements Enemy { } this.setPhantomSize(nbt.getInt("Size")); @@ -20,7 +20,7 @@ index 81e75e9d6619f7108fd769e462f24d72cbd5a73c..3c3f70d05fb51b530b792adf84c32484 } @Override -@@ -174,6 +179,11 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -170,6 +175,11 @@ public class Phantom extends FlyingMob implements Enemy { nbt.putInt("AY", this.anchorPoint.getY()); nbt.putInt("AZ", this.anchorPoint.getZ()); nbt.putInt("Size", this.getPhantomSize()); @@ -33,7 +33,7 @@ index 81e75e9d6619f7108fd769e462f24d72cbd5a73c..3c3f70d05fb51b530b792adf84c32484 @Override @@ -219,6 +229,17 @@ public class Phantom extends FlyingMob implements Enemy { - return entitysize.scale(1.0F + 0.15F * (float) i); + return predicate.test(world, this, target); } + // Paper start @@ -51,7 +51,7 @@ index 81e75e9d6619f7108fd769e462f24d72cbd5a73c..3c3f70d05fb51b530b792adf84c32484 CIRCLE, SWOOP; diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java -index 9d28e3855a9b150534ef8b6c89e186f5c4c47694..bb7f2d3ff7fc6f5cadb4ab24efb5a3a2f5bdc33f 100644 +index 1ef81620541c97dce0fca4d85951202e9532e733..499b124f905ffa8e375efa354a3f2240997ddea5 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java +++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java @@ -69,9 +69,19 @@ public class PhantomSpawner implements CustomSpawner { @@ -67,12 +67,12 @@ index 9d28e3855a9b150534ef8b6c89e186f5c4c47694..bb7f2d3ff7fc6f5cadb4ab24efb5a3a2 + continue; + } + // Paper end - PhantomPreSpawnEvent - Phantom entityphantom = (Phantom) EntityType.PHANTOM.create(world); + Phantom entityphantom = (Phantom) EntityType.PHANTOM.create(world, EntitySpawnReason.NATURAL); if (entityphantom != null) { + entityphantom.setSpawningEntity(entityplayer.getUUID()); // Paper - PhantomPreSpawnEvent entityphantom.moveTo(blockposition1, 0.0F, 0.0F); - groupdataentity = entityphantom.finalizeSpawn(world, difficultydamagescaler, MobSpawnType.NATURAL, groupdataentity); + groupdataentity = entityphantom.finalizeSpawn(world, difficultydamagescaler, EntitySpawnReason.NATURAL, groupdataentity); world.addFreshEntityWithPassengers(entityphantom, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java index 0359c161448941f1b9fdac545a5c47a68f19b760..305a635b049741ac5e2670060c6818cb2c07e5ab 100644 diff --git a/patches/unapplied/server/0237-Add-More-Creeper-API.patch b/patches/server/0236-Add-More-Creeper-API.patch similarity index 89% rename from patches/unapplied/server/0237-Add-More-Creeper-API.patch rename to patches/server/0236-Add-More-Creeper-API.patch index 931f2b615897..04605aa213e3 100644 --- a/patches/unapplied/server/0237-Add-More-Creeper-API.patch +++ b/patches/server/0236-Add-More-Creeper-API.patch @@ -5,10 +5,10 @@ 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 95df4ac539ec284654c53d39955870a46478c27d..9bf11a8b44e696b6587bc775904a836d390e437b 100644 +index 0552cc23391ec305754339d000630ccab0729100..7a18dc59aed5294cd442994aa2d34ea00b877f46 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java +++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java -@@ -134,7 +134,7 @@ public class Creeper extends Monster implements PowerableMob { +@@ -133,7 +133,7 @@ public class Creeper extends Monster { } if (nbt.getBoolean("ignited")) { @@ -17,7 +17,7 @@ index 95df4ac539ec284654c53d39955870a46478c27d..9bf11a8b44e696b6587bc775904a836d } } -@@ -315,7 +315,18 @@ public class Creeper extends Monster implements PowerableMob { +@@ -315,7 +315,18 @@ public class Creeper extends Monster { } public void ignite() { diff --git a/patches/unapplied/server/0238-Inventory-removeItemAnySlot.patch b/patches/server/0237-Inventory-removeItemAnySlot.patch similarity index 100% rename from patches/unapplied/server/0238-Inventory-removeItemAnySlot.patch rename to patches/server/0237-Inventory-removeItemAnySlot.patch diff --git a/patches/unapplied/server/0239-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch b/patches/server/0238-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch similarity index 87% rename from patches/unapplied/server/0239-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch rename to patches/server/0238-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch index 911ca5db1fb1..79a35711a9cb 100644 --- a/patches/unapplied/server/0239-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch +++ b/patches/server/0238-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 281fa67cb5c95e6016c7220c0ef912bbfd28cd9f..333e3109d19c867e8a74f20693952bdb3df804e4 100644 +index 1982385aa0e4984544d2aef88f5cafd5c0d5a49a..0a53b01094bd8070e57fb3c967c1129a53bd7ff8 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -432,7 +432,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -438,7 +438,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/unapplied/server/0240-Add-ray-tracing-methods-to-LivingEntity.patch b/patches/server/0239-Add-ray-tracing-methods-to-LivingEntity.patch similarity index 91% rename from patches/unapplied/server/0240-Add-ray-tracing-methods-to-LivingEntity.patch rename to patches/server/0239-Add-ray-tracing-methods-to-LivingEntity.patch index 0962c2d288b7..8ec63c01c889 100644 --- a/patches/unapplied/server/0240-Add-ray-tracing-methods-to-LivingEntity.patch +++ b/patches/server/0239-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/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index d90e74b7323a60e781d942baffe9b4bdb8ae2943..08f756b4fbb4732d73ca281b7006024b21504880 100644 +index c9d7589a18e9cee204f4e52368a60aa421c1e150..35dfaf46429f5478049835e1a5e4b03c362a64e8 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3980,6 +3980,19 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4114,6 +4114,19 @@ public abstract class LivingEntity extends Entity implements Attackable { } // Paper start - Make shield blocking delay configurable @@ -29,10 +29,10 @@ index d90e74b7323a60e781d942baffe9b4bdb8ae2943..08f756b4fbb4732d73ca281b7006024b public int getShieldBlockingDelay() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 2612e5016646591bb65ac255804b612b348a32fd..c8ac50351b7b1b2f4afc138570b8098a3c0ce1ba 100644 +index 2033354daafc739a8bd9ddf4a6128d3204d32094..0c7bf4124d67258ebca9b9b73b92c2e0efbdaa86 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -202,6 +202,33 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -207,6 +207,33 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return blocks.get(0); } diff --git a/patches/unapplied/server/0241-Expose-attack-cooldown-methods-for-Player.patch b/patches/server/0240-Expose-attack-cooldown-methods-for-Player.patch similarity index 86% rename from patches/unapplied/server/0241-Expose-attack-cooldown-methods-for-Player.patch rename to patches/server/0240-Expose-attack-cooldown-methods-for-Player.patch index 0d19ca5bf3d6..889ae1c62326 100644 --- a/patches/unapplied/server/0241-Expose-attack-cooldown-methods-for-Player.patch +++ b/patches/server/0240-Expose-attack-cooldown-methods-for-Player.patch @@ -5,10 +5,10 @@ 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 12c61db6d4b1284765f9bed3ae26131a118b318e..a7e611aaeb457820ad303b95822d8ea86b060477 100644 +index ad75996926b7e054f1053d07fb978ac745f22ce6..535e0438b02fd7c10aee0d24786a6e38c6e48359 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2980,6 +2980,21 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2993,6 +2993,21 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.adventure$pointers; } diff --git a/patches/unapplied/server/0242-Improve-death-events.patch b/patches/server/0241-Improve-death-events.patch similarity index 78% rename from patches/unapplied/server/0242-Improve-death-events.patch rename to patches/server/0241-Improve-death-events.patch index 32eb4bc818c5..26de33a12c1a 100644 --- a/patches/unapplied/server/0242-Improve-death-events.patch +++ b/patches/server/0241-Improve-death-events.patch @@ -19,10 +19,10 @@ public net.minecraft.world.entity.LivingEntity getDeathSound()Lnet/minecraft/sou public net.minecraft.world.entity.LivingEntity getSoundVolume()F diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 0dee94f1dd27a0d7e709367450c5ef7956e27217..fa8640f961b93dc811296131dfda58faa1908add 100644 +index 29b836a75b835f0d5233db419fc5ca8dde885fdb..2bd97344502a63173de923542f27759d7e98b6cc 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -269,6 +269,10 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -296,6 +296,10 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { private int containerCounter; public boolean wonGame; private int containerUpdateDelay; // Paper - Configurable container update tick rate @@ -33,16 +33,16 @@ index 0dee94f1dd27a0d7e709367450c5ef7956e27217..fa8640f961b93dc811296131dfda58fa // CraftBukkit start public CraftPlayer.TransferCookieConnection transferCookieConnection; -@@ -894,7 +898,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1154,7 +1158,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { @Override public void die(DamageSource damageSource) { - this.gameEvent(GameEvent.ENTITY_DIE); + // this.gameEvent(GameEvent.ENTITY_DIE); // Paper - move below event cancellation check - boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); + boolean flag = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); // CraftBukkit start - fire PlayerDeathEvent if (this.isRemoved()) { -@@ -922,6 +926,16 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1182,6 +1186,16 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { String deathmessage = defaultMessage.getString(); this.keepLevel = keepInventory; // SPIGOT-2222: pre-set keepLevel org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, damageSource, loot, PaperAdventure.asAdventure(defaultMessage), keepInventory); // Paper - Adventure @@ -59,16 +59,15 @@ index 0dee94f1dd27a0d7e709367450c5ef7956e27217..fa8640f961b93dc811296131dfda58fa // SPIGOT-943 - only call if they have an inventory open if (this.containerMenu != this.inventoryMenu) { -@@ -1070,8 +1084,17 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { - } +@@ -1331,7 +1345,17 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } } -- -- return super.hurt(source, amount); + +- return super.hurtServer(world, source, amount); + // Paper start - cancellable death events + //return super.hurt(source, amount); + this.queueHealthUpdatePacket = true; -+ boolean damaged = super.hurt(source, amount); ++ boolean damaged = super.hurtServer(world, source, amount); + this.queueHealthUpdatePacket = false; + if (this.queuedHealthUpdatePacket != null) { + this.connection.send(this.queuedHealthUpdatePacket); @@ -80,10 +79,10 @@ index 0dee94f1dd27a0d7e709367450c5ef7956e27217..fa8640f961b93dc811296131dfda58fa } } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 39dff0a38b53624c935f27cc86ff036c831f407f..bdee5725029eda3a0e7bee407286480c0bb47db1 100644 +index 35dfaf46429f5478049835e1a5e4b03c362a64e8..a7e950bc5aa827c1b137a12c9eaaf7eac867bdc3 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -283,6 +283,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -297,6 +297,7 @@ public abstract class LivingEntity extends Entity implements Attackable { public Set collidableExemptions = new HashSet<>(); public boolean bukkitPickUpLoot; public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper @@ -91,7 +90,7 @@ index 39dff0a38b53624c935f27cc86ff036c831f407f..bdee5725029eda3a0e7bee407286480c @Override public float getBukkitYaw() { -@@ -1537,11 +1538,12 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1574,11 +1575,12 @@ public abstract class LivingEntity extends Entity implements Attackable { if (this.isDeadOrDying()) { if (!this.checkTotemDeathProtection(source)) { @@ -107,7 +106,7 @@ index 39dff0a38b53624c935f27cc86ff036c831f407f..bdee5725029eda3a0e7bee407286480c } } else if (flag1) { this.playHurtSound(source); -@@ -1700,6 +1702,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1740,6 +1742,7 @@ public abstract class LivingEntity extends Entity implements Attackable { Entity entity = damageSource.getEntity(); LivingEntity entityliving = this.getKillCredit(); @@ -115,7 +114,7 @@ index 39dff0a38b53624c935f27cc86ff036c831f407f..bdee5725029eda3a0e7bee407286480c if (this.deathScore >= 0 && entityliving != null) { entityliving.awardKillScore(this, this.deathScore, damageSource); } -@@ -1711,24 +1714,59 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1751,24 +1754,59 @@ public abstract class LivingEntity extends Entity implements Attackable { if (!this.level().isClientSide && this.hasCustomName()) { if (org.spigotmc.SpigotConfig.logNamedDeaths) LivingEntity.LOGGER.info("Named entity {} died: {}", this, this.getCombatTracker().getDeathMessage().getString()); // Spigot } @@ -179,16 +178,16 @@ index 39dff0a38b53624c935f27cc86ff036c831f407f..bdee5725029eda3a0e7bee407286480c } } -@@ -1736,7 +1774,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - if (!this.level().isClientSide) { +@@ -1778,7 +1816,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + if (world instanceof ServerLevel worldserver) { boolean flag = false; - if (adversary instanceof WitherBoss) { + if (this.dead && adversary instanceof WitherBoss) { // Paper - if (this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { + if (worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { BlockPos blockposition = this.blockPosition(); BlockState iblockdata = Blocks.WITHER_ROSE.defaultBlockState(); -@@ -1765,24 +1803,37 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1807,24 +1845,37 @@ public abstract class LivingEntity extends Entity implements Attackable { } } @@ -200,9 +199,9 @@ index 39dff0a38b53624c935f27cc86ff036c831f407f..bdee5725029eda3a0e7bee407286480c + // Paper end boolean flag = this.lastHurtByPlayerTime > 0; - this.dropEquipment(); // CraftBukkit - from below + this.dropEquipment(world); // CraftBukkit - from below if (this.shouldDropLoot() && world.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { - this.dropFromLootTable(damageSource, flag); + this.dropFromLootTable(world, damageSource, flag); + // Paper start + final boolean prev = this.clearEquipmentSlots; + this.clearEquipmentSlots = false; @@ -218,21 +217,21 @@ index 39dff0a38b53624c935f27cc86ff036c831f407f..bdee5725029eda3a0e7bee407286480c this.drops = new ArrayList<>(); // CraftBukkit end - // this.dropEquipment();// CraftBukkit - moved up - this.dropExperience(damageSource.getEntity()); + // this.dropEquipment(worldserver);// CraftBukkit - moved up + this.dropExperience(world, damageSource.getEntity()); + return deathEvent; // Paper } - protected void dropEquipment() {} + protected void dropEquipment(ServerLevel world) {} + protected void postDeathDropItems(org.bukkit.event.entity.EntityDeathEvent event) {} // Paper - method for post death logic that cannot be ran before the event is potentially cancelled - public int getExpReward(@Nullable Entity entity) { // CraftBukkit - Level world = this.level(); + public int getExpReward(ServerLevel worldserver, @Nullable Entity entity) { // CraftBukkit + if (!this.wasExperienceConsumed() && (this.isAlwaysExperienceDropper() || this.lastHurtByPlayerTime > 0 && this.shouldDropExperience() && worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT))) { diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 25a71cc5ca8cf8a5070cd24eb56fe0d79e765669..b46572f6e3b52f498b395d3b8c5def2aa799ff03 100644 +index 2b8bfccbf520f9a356f816522ac3a5caa51e44e1..a8ab3c03a6f96658ce2a3f5758225954a36de6a9 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -1123,6 +1123,12 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -1117,6 +1117,12 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab } @@ -245,18 +244,18 @@ index 25a71cc5ca8cf8a5070cd24eb56fe0d79e765669..b46572f6e3b52f498b395d3b8c5def2a @Override protected void dropCustomDeathLoot(ServerLevel world, DamageSource source, boolean causedByPlayer) { super.dropCustomDeathLoot(world, source, causedByPlayer); -@@ -1131,6 +1137,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -1124,6 +1130,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab - for (int j = 0; j < i; ++j) { - EquipmentSlot enumitemslot = aenumitemslot[j]; + while (iterator.hasNext()) { + EquipmentSlot enumitemslot = (EquipmentSlot) iterator.next(); + if (this.shouldSkipLoot(enumitemslot)) continue; // Paper ItemStack itemstack = this.getItemBySlot(enumitemslot); float f = this.getEquipmentDropChance(enumitemslot); -@@ -1155,7 +1162,13 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -1148,7 +1155,13 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab } - this.spawnAtLocation(itemstack); + this.spawnAtLocation(world, itemstack); + if (this.clearEquipmentSlots) { // Paper this.setItemSlot(enumitemslot, ItemStack.EMPTY); + // Paper start @@ -268,10 +267,10 @@ index 25a71cc5ca8cf8a5070cd24eb56fe0d79e765669..b46572f6e3b52f498b395d3b8c5def2a } } diff --git a/src/main/java/net/minecraft/world/entity/animal/Fox.java b/src/main/java/net/minecraft/world/entity/animal/Fox.java -index a6788da1505f9e119c03b94488f5e006da13e918..e46c8231ee318eda0512afbb6343b426b4838643 100644 +index faffc3a9ed8bc306277cad37bc43af2ef7303493..205aefd38a185fa411ff17cfb0155769de8fc2fd 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Fox.java +++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java -@@ -704,16 +704,38 @@ public class Fox extends Animal implements VariantHolder { +@@ -689,16 +689,38 @@ public class Fox extends Animal implements VariantHolder { return this.getTrustedUUIDs().contains(uuid); } @@ -290,8 +289,8 @@ index a6788da1505f9e119c03b94488f5e006da13e918..e46c8231ee318eda0512afbb6343b426 - if (!itemstack.isEmpty()) { + boolean releaseMouth = false; -+ if (!itemstack.isEmpty() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Fix MC-153010 - this.spawnAtLocation(itemstack); ++ if (!itemstack.isEmpty() && world.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Fix MC-153010 + this.spawnAtLocation(world, itemstack); + releaseMouth = true; + } + @@ -314,17 +313,16 @@ index a6788da1505f9e119c03b94488f5e006da13e918..e46c8231ee318eda0512afbb6343b426 public static boolean isPathClear(Fox fox, LivingEntity chasedEntity) { diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java -index 767817fb1418958c89d0db9da4ae7eb8a5a16076..5654c614f07f07ff642ba4851b0cb6fa185924ae 100644 +index dd7ef4c873d5e06eb5be3abc8049bf8acbd5a3fb..112b82ba7709b36e996e2f984c72ce40ca718720 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java -@@ -71,9 +71,17 @@ public abstract class AbstractChestedHorse extends AbstractHorse { - this.spawnAtLocation(Blocks.CHEST); - } - +@@ -69,9 +69,16 @@ public abstract class AbstractChestedHorse extends AbstractHorse { + super.dropEquipment(world); + if (this.hasChest()) { + this.spawnAtLocation(world, Blocks.CHEST); + //this.setChest(false); // Paper - moved to post death logic + } + } -+ + // Paper start + protected void postDeathDropItems(org.bukkit.event.entity.EntityDeathEvent event) { + if (this.hasChest() && (event == null || !event.isCancelled())) { @@ -336,40 +334,39 @@ index 767817fb1418958c89d0db9da4ae7eb8a5a16076..5654c614f07f07ff642ba4851b0cb6fa @Override public void addAdditionalSaveData(CompoundTag nbt) { diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -index ee3902cbada46ffb78c42dbf6f00c859546c76e1..92bb0c63330ad3a4cb13b2dc655020714e9b1ffd 100644 +index 2caba38a50b7ea535337a3540aa5272d4a9f1878..e20565cf256aacd012a1722c5ebbf9016bc82e42 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -505,8 +505,10 @@ public class ArmorStand extends LivingEntity { - } - // CraftBukkit end - if (source.is(DamageTypeTags.IS_EXPLOSION)) { -- this.brokenByAnything(worldserver, source); -- this.kill(source); // CraftBukkit -+ // Paper start - avoid duplicate event call -+ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByAnything(worldserver, source); -+ if (!event.isCancelled()) this.kill(source, false); // CraftBukkit -+ // Paper end - return false; - } else if (source.is(DamageTypeTags.IGNITES_ARMOR_STANDS)) { - if (this.isOnFire()) { -@@ -549,9 +551,9 @@ public class ArmorStand extends LivingEntity { - this.gameEvent(GameEvent.ENTITY_DAMAGE, source.getEntity()); - this.lastHit = i; - } else { -- this.brokenByPlayer(worldserver, source); -+ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByPlayer(worldserver, source); // Paper - this.showBreakingParticles(); -- this.discard(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - SPIGOT-4890: remain as this.discard() since above damagesource method will call death event -+ if (!event.isCancelled()) this.kill(source, false); // Paper - we still need to kill to follow vanilla logic (emit the game event etc...) - } - - return true; -@@ -604,8 +606,10 @@ public class ArmorStand extends LivingEntity { +@@ -506,8 +506,10 @@ public class ArmorStand extends LivingEntity { + } + // CraftBukkit end + if (source.is(DamageTypeTags.IS_EXPLOSION)) { +- this.brokenByAnything(world, source); +- this.kill(world, source); // CraftBukkit ++ // Paper start - avoid duplicate event call ++ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByAnything(world, source); ++ if (!event.isCancelled()) this.kill(source, false); // CraftBukkit ++ // Paper end + return false; + } else if (source.is(DamageTypeTags.IGNITES_ARMOR_STANDS)) { + if (this.isOnFire()) { +@@ -550,9 +552,9 @@ public class ArmorStand extends LivingEntity { + this.gameEvent(GameEvent.ENTITY_DAMAGE, source.getEntity()); + this.lastHit = i; + } else { +- this.brokenByPlayer(world, source); ++ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByPlayer(world, source); // Paper + this.showBreakingParticles(); +- this.discard(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - SPIGOT-4890: remain as this.discard() since above damagesource method will call death event ++ if (!event.isCancelled()) this.kill(source, false); // Paper - we still need to kill to follow vanilla logic (emit the game event etc...) + } + return true; +@@ -602,7 +604,10 @@ public class ArmorStand extends LivingEntity { f1 -= amount; if (f1 <= 0.5F) { -- this.brokenByAnything(world, damageSource); -- this.kill(damageSource); // CraftBukkit + this.brokenByAnything(world, damageSource); +- this.kill(world, damageSource); // CraftBukkit + // Paper start - avoid duplicate event call + org.bukkit.event.entity.EntityDeathEvent event = this.brokenByAnything(world, damageSource); + if (!event.isCancelled()) this.kill(damageSource, false); // CraftBukkit @@ -377,7 +374,7 @@ index ee3902cbada46ffb78c42dbf6f00c859546c76e1..92bb0c63330ad3a4cb13b2dc65502071 } else { this.setHealth(f1); this.gameEvent(GameEvent.ENTITY_DAMAGE, damageSource.getEntity()); -@@ -613,15 +617,15 @@ public class ArmorStand extends LivingEntity { +@@ -610,15 +615,15 @@ public class ArmorStand extends LivingEntity { } @@ -396,7 +393,7 @@ index ee3902cbada46ffb78c42dbf6f00c859546c76e1..92bb0c63330ad3a4cb13b2dc65502071 this.playBrokenSound(); // this.dropAllDeathLoot(worldserver, damagesource); // CraftBukkit - moved down -@@ -643,7 +647,7 @@ public class ArmorStand extends LivingEntity { +@@ -640,7 +645,7 @@ public class ArmorStand extends LivingEntity { this.armorItems.set(i, ItemStack.EMPTY); } } @@ -405,10 +402,10 @@ index ee3902cbada46ffb78c42dbf6f00c859546c76e1..92bb0c63330ad3a4cb13b2dc65502071 } -@@ -770,7 +774,15 @@ public class ArmorStand extends LivingEntity { +@@ -767,7 +772,15 @@ public class ArmorStand extends LivingEntity { } - public void kill(DamageSource damageSource) { + public void kill(ServerLevel worldserver, DamageSource damageSource) { - org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, (damageSource == null ? this.damageSources().genericKill() : damageSource), this.drops); // CraftBukkit - call event + // Paper start - make cancellable + this.kill(damageSource, true); @@ -423,10 +420,10 @@ index ee3902cbada46ffb78c42dbf6f00c859546c76e1..92bb0c63330ad3a4cb13b2dc65502071 // CraftBukkit end 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 a7e611aaeb457820ad303b95822d8ea86b060477..004ac565d4124f6059d530034cf0c9a28f0be467 100644 +index 535e0438b02fd7c10aee0d24786a6e38c6e48359..c132b4d4d871eaeadec78921a99ba7066c59ddda 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2517,7 +2517,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2530,7 +2530,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void sendHealthUpdate() { FoodData foodData = this.getHandle().getFoodData(); @@ -443,15 +440,14 @@ index a7e611aaeb457820ad303b95822d8ea86b060477..004ac565d4124f6059d530034cf0c9a2 public void injectScaledMaxHealth(Collection collection, boolean force) { diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 0613bdf3c2325d5cab64783af7211b07fcf5124a..6a018f9c289a539b07855d75e4cc2d3c2828ded1 100644 +index 474f330f381aa74e9f2fd0accdbaf2617ec1c557..834516cac1f3ac5f078dd4e4dfa449f39462658c 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -903,9 +903,16 @@ public class CraftEventFactory { - CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity(); +@@ -902,8 +902,15 @@ public class CraftEventFactory { CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource); - EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(damageSource.getEntity())); -+ populateFields(victim, event); // Paper - make cancellable CraftWorld world = (CraftWorld) entity.getWorld(); + EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(world.getHandle(), damageSource.getEntity())); ++ populateFields(victim, event); // Paper - make cancellable Bukkit.getServer().getPluginManager().callEvent(event); + // Paper start - make cancellable @@ -463,11 +459,11 @@ index 0613bdf3c2325d5cab64783af7211b07fcf5124a..6a018f9c289a539b07855d75e4cc2d3c victim.expToDrop = event.getDroppedExp(); for (org.bukkit.inventory.ItemStack stack : event.getDrops()) { -@@ -923,7 +930,14 @@ public class CraftEventFactory { - PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(damageSource.getEntity()), 0, deathMessage); +@@ -921,7 +928,14 @@ public class CraftEventFactory { + PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage); event.setKeepInventory(keepInventory); event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel -+ populateFields(victim, event); // Paper - make cancellable ++populateFields(victim, event); // Paper - make cancellable Bukkit.getServer().getPluginManager().callEvent(event); + // Paper start - make cancellable + if (event.isCancelled()) { @@ -478,7 +474,7 @@ index 0613bdf3c2325d5cab64783af7211b07fcf5124a..6a018f9c289a539b07855d75e4cc2d3c victim.keepLevel = event.getKeepLevel(); victim.newLevel = event.getNewLevel(); -@@ -946,6 +960,31 @@ public class CraftEventFactory { +@@ -944,6 +958,31 @@ public class CraftEventFactory { return event; } From 8851d25a4df4fed9547c990fc834c83f77675e59 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Wed, 23 Oct 2024 13:13:00 +0200 Subject: [PATCH 014/119] Fluid Flowing ifLoaded patch --- ...w-chests-to-be-placed-with-NBT-data.patch} | 18 ++-- .../0243-Mob-Pathfinding-API.patch} | 6 +- ...nteractions-from-causing-chunk-load.patch} | 18 ++-- ...ning-from-loading-generating-chunks.patch} | 6 +- ...t-furnace-cook-speed-multiplier-API.patch} | 71 ++++++++------- .../0247-Honor-EntityAgeable.ageLock.patch} | 10 +-- ...le-connection-throttle-kick-message.patch} | 0 ...ent-chunk-loading-from-Fluid-Flowing.patch | 88 +++++++++++++++++++ ...ent-chunk-loading-from-Fluid-Flowing.patch | 75 ---------------- 9 files changed, 154 insertions(+), 138 deletions(-) rename patches/{unapplied/server/0243-Allow-chests-to-be-placed-with-NBT-data.patch => server/0242-Allow-chests-to-be-placed-with-NBT-data.patch} (64%) rename patches/{unapplied/server/0244-Mob-Pathfinding-API.patch => server/0243-Mob-Pathfinding-API.patch} (97%) rename patches/{unapplied/server/0245-Prevent-various-interactions-from-causing-chunk-load.patch => server/0244-Prevent-various-interactions-from-causing-chunk-load.patch} (90%) rename patches/{unapplied/server/0246-Prevent-mob-spawning-from-loading-generating-chunks.patch => server/0245-Prevent-mob-spawning-from-loading-generating-chunks.patch} (90%) rename patches/{unapplied/server/0247-Implement-furnace-cook-speed-multiplier-API.patch => server/0246-Implement-furnace-cook-speed-multiplier-API.patch} (68%) rename patches/{unapplied/server/0248-Honor-EntityAgeable.ageLock.patch => server/0247-Honor-EntityAgeable.ageLock.patch} (78%) rename patches/{unapplied/server/0249-Configurable-connection-throttle-kick-message.patch => server/0248-Configurable-connection-throttle-kick-message.patch} (100%) create mode 100644 patches/server/0249-Prevent-chunk-loading-from-Fluid-Flowing.patch delete mode 100644 patches/unapplied/server/0250-Prevent-chunk-loading-from-Fluid-Flowing.patch diff --git a/patches/unapplied/server/0243-Allow-chests-to-be-placed-with-NBT-data.patch b/patches/server/0242-Allow-chests-to-be-placed-with-NBT-data.patch similarity index 64% rename from patches/unapplied/server/0243-Allow-chests-to-be-placed-with-NBT-data.patch rename to patches/server/0242-Allow-chests-to-be-placed-with-NBT-data.patch index 92d7a5d3fce5..4b282589d9b7 100644 --- a/patches/unapplied/server/0243-Allow-chests-to-be-placed-with-NBT-data.patch +++ b/patches/server/0242-Allow-chests-to-be-placed-with-NBT-data.patch @@ -5,19 +5,19 @@ Subject: [PATCH] Allow chests to be placed with NBT data diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index b0d0e08e81e3b87e5d4faf62e9afe9606c254115..2ee949e1b0015c62499c557d5e359df4b9de6027 100644 +index 957c112b4145fda5078a6f8f1689935fa0290806..f00b756fe5dad616323e3b11e35e27353f347042 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -490,6 +490,7 @@ public final class ItemStack implements DataComponentHolder { - enuminteractionresult = InteractionResult.FAIL; // cancel placement - // PAIL: Remove this when MC-99075 fixed - placeEvent.getPlayer().updateInventory(); +@@ -496,6 +496,7 @@ public final class ItemStack implements DataComponentHolder { + enuminteractionresult = InteractionResult.FAIL; // cancel placement + // PAIL: Remove this when MC-99075 fixed + placeEvent.getPlayer().updateInventory(); + world.capturedTileEntities.clear(); // Paper - Allow chests to be placed with NBT data; clear out block entities as chests and such will pop loot - // revert back all captured blocks - world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710 - for (BlockState blockstate : blocks) { + // revert back all captured blocks + world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710 + for (BlockState blockstate : blocks) { diff --git a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java -index 9d6262e286a00f840d88d6eb6bfdb304467466e3..b88aa184cd06a0485146f58a5b61a56a50911209 100644 +index a3cdb4af2b7a3c7f884c8af2cba0d3d5e1c184a6..8847617f6a23e6d2fe9bf7444a2072dc53f741b8 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java @@ -238,7 +238,7 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement diff --git a/patches/unapplied/server/0244-Mob-Pathfinding-API.patch b/patches/server/0243-Mob-Pathfinding-API.patch similarity index 97% rename from patches/unapplied/server/0244-Mob-Pathfinding-API.patch rename to patches/server/0243-Mob-Pathfinding-API.patch index 427d08a15744..638eb9310c7d 100644 --- a/patches/unapplied/server/0244-Mob-Pathfinding-API.patch +++ b/patches/server/0243-Mob-Pathfinding-API.patch @@ -177,10 +177,10 @@ index f6419f3b345e9e21a05b315aa4669090d7da4194..d9d0fff9962131808d54cca20f209df5 public Path(List nodes, BlockPos target, boolean reachesTarget) { this.nodes = nodes; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java -index 58e690a91aea9ea294f8e4ec9861aa92bc6060a0..d597eea5d5c2f223e87bff06f292619657596f1f 100644 +index 31f7b19b8978d941df801c97ad8989ef18d9fe2d..26c9bc53fe50636ca1eb32144c648f382d4172ff 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java -@@ -13,8 +13,11 @@ import org.bukkit.loot.LootTable; +@@ -14,8 +14,11 @@ import org.bukkit.loot.LootTable; public abstract class CraftMob extends CraftLivingEntity implements Mob { public CraftMob(CraftServer server, net.minecraft.world.entity.Mob entity) { super(server, entity); @@ -192,7 +192,7 @@ index 58e690a91aea9ea294f8e4ec9861aa92bc6060a0..d597eea5d5c2f223e87bff06f2926196 @Override public void setTarget(LivingEntity target) { Preconditions.checkState(!this.getHandle().generation, "Cannot set target during world generation"); -@@ -55,6 +58,14 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob { +@@ -56,6 +59,14 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob { return (net.minecraft.world.entity.Mob) this.entity; } diff --git a/patches/unapplied/server/0245-Prevent-various-interactions-from-causing-chunk-load.patch b/patches/server/0244-Prevent-various-interactions-from-causing-chunk-load.patch similarity index 90% rename from patches/unapplied/server/0245-Prevent-various-interactions-from-causing-chunk-load.patch rename to patches/server/0244-Prevent-various-interactions-from-causing-chunk-load.patch index 01a574e73c4a..b7f9185ebb14 100644 --- a/patches/unapplied/server/0245-Prevent-various-interactions-from-causing-chunk-load.patch +++ b/patches/server/0244-Prevent-various-interactions-from-causing-chunk-load.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Prevent various interactions from causing chunk loads Co-authored-by: Shane Freeder diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java -index da5373d8eb4643414a0f2c699044fde93715c258..6634228ef002cbef67980272a26be4a75c954116 100644 +index 90f61511429799b1e852326d0d014551e5c35d5d..9d245d08be61d7edee9138196ae3bf52023e3993 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java -@@ -126,7 +126,9 @@ public class RemoveBlockGoal extends MoveToBlockGoal { +@@ -127,7 +127,9 @@ public class RemoveBlockGoal extends MoveToBlockGoal { @Nullable private BlockPos getPosWithBlock(BlockPos pos, BlockGetter world) { @@ -20,7 +20,7 @@ index da5373d8eb4643414a0f2c699044fde93715c258..6634228ef002cbef67980272a26be4a7 return pos; } else { BlockPos[] ablockposition = new BlockPos[]{pos.below(), pos.west(), pos.east(), pos.north(), pos.south(), pos.below().below()}; -@@ -136,7 +138,8 @@ public class RemoveBlockGoal extends MoveToBlockGoal { +@@ -137,7 +139,8 @@ public class RemoveBlockGoal extends MoveToBlockGoal { for (int j = 0; j < i; ++j) { BlockPos blockposition1 = ablockposition1[j]; @@ -30,7 +30,7 @@ index da5373d8eb4643414a0f2c699044fde93715c258..6634228ef002cbef67980272a26be4a7 return blockposition1; } } -@@ -147,7 +150,7 @@ public class RemoveBlockGoal extends MoveToBlockGoal { +@@ -148,7 +151,7 @@ public class RemoveBlockGoal extends MoveToBlockGoal { @Override protected boolean isValidTarget(LevelReader world, BlockPos pos) { @@ -40,10 +40,10 @@ index da5373d8eb4643414a0f2c699044fde93715c258..6634228ef002cbef67980272a26be4a7 return ichunkaccess == null ? false : ichunkaccess.getBlockState(pos).is(this.blockToRemove) && ichunkaccess.getBlockState(pos.above()).isAir() && ichunkaccess.getBlockState(pos.above(2)).isAir(); } diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -index 70888dd25b6a1d1ab7702d73a64a47eebafe76fe..0214e8bbcaefdd92ee3719d9a570f9d256ee29ba 100644 +index 5f1bbb4302013c2c1788db6b64eafba2a11a373a..512de8e79a842d4389e8528983b94af4843ffd11 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -@@ -502,7 +502,8 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -489,7 +489,8 @@ public class EnderMan extends Monster implements NeutralMob { int j = Mth.floor(this.enderman.getY() + randomsource.nextDouble() * 2.0D); int k = Mth.floor(this.enderman.getZ() - 1.0D + randomsource.nextDouble() * 2.0D); BlockPos blockposition = new BlockPos(i, j, k); @@ -53,7 +53,7 @@ index 70888dd25b6a1d1ab7702d73a64a47eebafe76fe..0214e8bbcaefdd92ee3719d9a570f9d2 BlockPos blockposition1 = blockposition.below(); BlockState iblockdata1 = world.getBlockState(blockposition1); BlockState iblockdata2 = this.enderman.getCarriedBlock(); -@@ -546,7 +547,8 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -533,7 +534,8 @@ public class EnderMan extends Monster implements NeutralMob { int j = Mth.floor(this.enderman.getY() + randomsource.nextDouble() * 3.0D); int k = Mth.floor(this.enderman.getZ() - 2.0D + randomsource.nextDouble() * 4.0D); BlockPos blockposition = new BlockPos(i, j, k); @@ -77,10 +77,10 @@ index c02a2f9e1b4e727b1deeb73377e1f7193f5ee072..cdd1f6939ce33e62f6609f7eb3a5dff5 : new LodestoneTracker(Optional.empty(), true); } diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java -index d6d8bbc98fc71997cb52521d59ebb59d727d3c22..c3760e0c8ac0b3ea200f4e1c237e250137a78caf 100644 +index 6850ac324ee4d202f112dbd057ea1bde9de17ea9..8e58efd0d8010a3499a1eb1add9fa976aa2b0a3e 100644 --- a/src/main/java/net/minecraft/world/level/BlockGetter.java +++ b/src/main/java/net/minecraft/world/level/BlockGetter.java -@@ -70,7 +70,15 @@ public interface BlockGetter extends LevelHeightAccessor { +@@ -71,7 +71,15 @@ public interface BlockGetter extends LevelHeightAccessor { // CraftBukkit start - moved block handling into separate method for use by Block#rayTrace default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) { diff --git a/patches/unapplied/server/0246-Prevent-mob-spawning-from-loading-generating-chunks.patch b/patches/server/0245-Prevent-mob-spawning-from-loading-generating-chunks.patch similarity index 90% rename from patches/unapplied/server/0246-Prevent-mob-spawning-from-loading-generating-chunks.patch rename to patches/server/0245-Prevent-mob-spawning-from-loading-generating-chunks.patch index 1ca48ef5a81d..1908c1da0cd8 100644 --- a/patches/unapplied/server/0246-Prevent-mob-spawning-from-loading-generating-chunks.patch +++ b/patches/server/0245-Prevent-mob-spawning-from-loading-generating-chunks.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Prevent mob spawning from loading/generating chunks also prevents if out of world border bounds diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index bce78beaadbfd0e400457bd14bcf6538be702879..41eef8bfd1572aecaf086bfbec300abeae2df794 100644 +index 0b41149ae134084cef4016241ce923dac0349846..be2412ef8f8c331a881e442577cf05aec43f52bb 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -165,9 +165,9 @@ public final class NaturalSpawner { +@@ -187,9 +187,9 @@ public final class NaturalSpawner { StructureManager structuremanager = world.structureManager(); ChunkGenerator chunkgenerator = world.getChunkSource().getGenerator(); int i = pos.getY(); @@ -21,7 +21,7 @@ index bce78beaadbfd0e400457bd14bcf6538be702879..41eef8bfd1572aecaf086bfbec300abe BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); int j = 0; int k = 0; -@@ -196,7 +196,7 @@ public final class NaturalSpawner { +@@ -218,7 +218,7 @@ public final class NaturalSpawner { if (entityhuman != null) { double d2 = entityhuman.distanceToSqr(d0, (double) i, d1); diff --git a/patches/unapplied/server/0247-Implement-furnace-cook-speed-multiplier-API.patch b/patches/server/0246-Implement-furnace-cook-speed-multiplier-API.patch similarity index 68% rename from patches/unapplied/server/0247-Implement-furnace-cook-speed-multiplier-API.patch rename to patches/server/0246-Implement-furnace-cook-speed-multiplier-API.patch index 24067a522fce..1f16e2891306 100644 --- a/patches/unapplied/server/0247-Implement-furnace-cook-speed-multiplier-API.patch +++ b/patches/server/0246-Implement-furnace-cook-speed-multiplier-API.patch @@ -9,35 +9,33 @@ to the nearest Integer when updating its current cook time. Co-authored-by: Eric Su diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index e2a587ca5b732c62c4956e6f39ad795cd1411cc4..5ea2b05961590732a43bb5a1abf00bf8a00c72c2 100644 +index 62c49afd4da165d0cb4156f106e6e5480d267d4e..b9dd5f710533b156311cac2c020fd0d5f64b6265 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -@@ -79,6 +79,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -74,11 +74,13 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit protected NonNullList items; public int litTime; int litDuration; + public double cookSpeedMultiplier = 1.0; // Paper - cook speed multiplier API public int cookingProgress; public int cookingTotalTime; - @Nullable -@@ -86,6 +87,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit protected final ContainerData dataAccess; - public final Object2IntOpenHashMap recipesUsed; + public final Reference2IntOpenHashMap>> recipesUsed; private final RecipeManager.CachedCheck quickCheck; + public final RecipeType recipeType; // Paper - cook speed multiplier API protected AbstractFurnaceBlockEntity(BlockEntityType blockEntityType, BlockPos pos, BlockState state, RecipeType recipeType) { super(blockEntityType, pos, state); -@@ -132,6 +134,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -126,6 +128,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit }; - this.recipesUsed = new Object2IntOpenHashMap(); + this.recipesUsed = new Reference2IntOpenHashMap(); this.quickCheck = RecipeManager.createCheck((RecipeType) recipeType); // CraftBukkit - decompile error // Eclipse fail + this.recipeType = recipeType; // Paper - cook speed multiplier API } - public static void invalidateCache() { -@@ -295,6 +298,11 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit - this.recipesUsed.put(ResourceLocation.parse(s), nbttagcompound1.getInt(s)); + // CraftBukkit start - add fields and methods +@@ -180,6 +183,11 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit + this.recipesUsed.put(ResourceKey.create(Registries.RECIPE, ResourceLocation.parse(s)), nbttagcompound1.getInt(s)); } + // Paper start - cook speed multiplier API @@ -48,24 +46,24 @@ index e2a587ca5b732c62c4956e6f39ad795cd1411cc4..5ea2b05961590732a43bb5a1abf00bf8 } @Override -@@ -303,6 +311,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -188,6 +196,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit nbt.putShort("BurnTime", (short) this.litTime); nbt.putShort("CookTime", (short) this.cookingProgress); nbt.putShort("CookTimeTotal", (short) this.cookingTotalTime); + nbt.putDouble("Paper.CookSpeedMultiplier", this.cookSpeedMultiplier); // Paper - cook speed multiplier API - ContainerHelper.saveAllItems(nbt, this.items, registryLookup); + ContainerHelper.saveAllItems(nbt, this.items, registries); CompoundTag nbttagcompound1 = new CompoundTag(); -@@ -375,7 +384,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -263,7 +272,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit CraftItemStack source = CraftItemStack.asCraftMirror(blockEntity.items.get(0)); CookingRecipe recipe = (CookingRecipe) recipeholder.toBukkitRecipe(); - FurnaceStartSmeltEvent event = new FurnaceStartSmeltEvent(CraftBlock.at(world, pos), source, recipe); -+ FurnaceStartSmeltEvent event = new FurnaceStartSmeltEvent(CraftBlock.at(world, pos), source, recipe, AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity.recipeType, blockEntity, blockEntity.cookSpeedMultiplier)); // Paper - cook speed multiplier API ++ FurnaceStartSmeltEvent event = new FurnaceStartSmeltEvent(CraftBlock.at(world, pos), source, recipe, AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity, blockEntity.recipeType, blockEntity.cookSpeedMultiplier)); // Paper - cook speed multiplier API world.getCraftServer().getPluginManager().callEvent(event); blockEntity.cookingTotalTime = event.getTotalCookTime(); -@@ -383,9 +392,9 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -271,9 +280,9 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit // CraftBukkit end ++blockEntity.cookingProgress; @@ -73,44 +71,49 @@ index e2a587ca5b732c62c4956e6f39ad795cd1411cc4..5ea2b05961590732a43bb5a1abf00bf8 + if (blockEntity.cookingProgress >= blockEntity.cookingTotalTime) { // Paper - cook speed multiplier API blockEntity.cookingProgress = 0; - blockEntity.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity); -+ blockEntity.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity.recipeType, blockEntity, blockEntity.cookSpeedMultiplier); // Paper - cook speed multiplier API - if (AbstractFurnaceBlockEntity.burn(blockEntity.level, blockEntity.worldPosition, world.registryAccess(), recipeholder, blockEntity.items, i)) { // CraftBukkit ++ blockEntity.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity, blockEntity.recipeType, blockEntity.cookSpeedMultiplier); // Paper - cook speed multiplier API + if (AbstractFurnaceBlockEntity.burn(blockEntity.level, blockEntity.worldPosition, world.registryAccess(), recipeholder, singlerecipeinput, blockEntity.items, i)) { // CraftBukkit blockEntity.setRecipeUsed(recipeholder); } -@@ -485,13 +494,14 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit - } +@@ -367,13 +376,14 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit + return fuelRegistry.burnDuration(stack); } -- private static int getTotalCookTime(Level world, AbstractFurnaceBlockEntity furnace) { +- private static int getTotalCookTime(ServerLevel world, AbstractFurnaceBlockEntity furnace) { - if (world == null) return 200; // CraftBukkit - SPIGOT-4302 -+ public static int getTotalCookTime(@Nullable Level world, RecipeType recipeType, AbstractFurnaceBlockEntity furnace, double cookSpeedMultiplier) { // Paper - cook speed multiplier API ++ private static int getTotalCookTime(@Nullable ServerLevel world, AbstractFurnaceBlockEntity furnace, RecipeType recipeType, double cookSpeedMultiplier) { // Paper - cook speed multiplier API SingleRecipeInput singlerecipeinput = new SingleRecipeInput(furnace.getItem(0)); - return (Integer) furnace.quickCheck.getRecipeFor(singlerecipeinput, world).map((recipeholder) -> { -- return ((AbstractCookingRecipe) recipeholder.value()).getCookingTime(); +- return ((AbstractCookingRecipe) recipeholder.value()).cookingTime(); - }).orElse(200); + // Paper start - cook speed multiplier API + /* Scale the recipe's cooking time to the current cookSpeedMultiplier */ -+ int cookTime = world != null ? furnace.quickCheck.getRecipeFor(singlerecipeinput, world).map(holder -> holder.value().getCookingTime()).orElse(200) : (net.minecraft.server.MinecraftServer.getServer().getRecipeManager().getRecipeFor(recipeType, singlerecipeinput, world /* passing a null level here is safe. world is only used for map extending recipes which won't happen here */).map(holder -> holder.value().getCookingTime()).orElse(200)); ++ int cookTime = world != null ? furnace.quickCheck.getRecipeFor(singlerecipeinput, world).map(holder -> holder.value().cookingTime()).orElse(200) : (net.minecraft.server.MinecraftServer.getServer().getRecipeManager().getRecipeFor(recipeType, singlerecipeinput, world /* passing a null level here is safe. world is only used for map extending recipes which won't happen here */).map(holder -> holder.value().cookingTime()).orElse(200)); + return (int) Math.ceil (cookTime / cookSpeedMultiplier); + // Paper end - cook speed multiplier API } - public static boolean isFuel(ItemStack stack) { -@@ -536,7 +546,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit - this.items.set(slot, stack); - stack.limitSize(this.getMaxStackSize(stack)); - if (slot == 0 && !flag) { -- this.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.level, this); -+ this.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.level, this.recipeType, this, this.cookSpeedMultiplier); // Paper - cook speed multiplier API - this.cookingProgress = 0; - this.setChanged(); + @Override +@@ -419,12 +429,11 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit + if (world instanceof ServerLevel) { + ServerLevel worldserver = (ServerLevel) world; + +- this.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(worldserver, this); ++ this.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(worldserver, this, this.recipeType, this.cookSpeedMultiplier); // Paper - cook speed multiplier API + this.cookingProgress = 0; + this.setChanged(); + } } +- + } + + @Override diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java -index 46a1c96efc5ffb5c8d6c20af758bdca5bb4a5049..ddbbf977c8f536a156ff6b2462353f7be5ab5742 100644 +index 7ed43bc29a4bc0f6db2cabd3cd4c8489ed81ee81..0ec30feb68efc1747e489ee4bb60e6a503cb31c4 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java -@@ -89,4 +89,20 @@ public abstract class CraftFurnace extends +@@ -88,4 +88,20 @@ public abstract class CraftFurnace extends @Override public abstract CraftFurnace copy(Location location); diff --git a/patches/unapplied/server/0248-Honor-EntityAgeable.ageLock.patch b/patches/server/0247-Honor-EntityAgeable.ageLock.patch similarity index 78% rename from patches/unapplied/server/0248-Honor-EntityAgeable.ageLock.patch rename to patches/server/0247-Honor-EntityAgeable.ageLock.patch index 1522ccc88216..aaaf81b8948e 100644 --- a/patches/unapplied/server/0248-Honor-EntityAgeable.ageLock.patch +++ b/patches/server/0247-Honor-EntityAgeable.ageLock.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Honor EntityAgeable.ageLock diff --git a/src/main/java/net/minecraft/world/entity/AgeableMob.java b/src/main/java/net/minecraft/world/entity/AgeableMob.java -index f07cf6d91e0cbad80c3c630c0d505820e701ce81..3dc3609d13a7b823d15384d1c385b68eeb933d26 100644 +index d7020068a9ea3e5e1cacfe53ef19a88139687205..119856b22df5bbcd4e5bf5f95645156f774c6168 100644 --- a/src/main/java/net/minecraft/world/entity/AgeableMob.java +++ b/src/main/java/net/minecraft/world/entity/AgeableMob.java -@@ -85,6 +85,7 @@ public abstract class AgeableMob extends PathfinderMob { +@@ -86,6 +86,7 @@ public abstract class AgeableMob extends PathfinderMob { } public void ageUp(int age, boolean overGrow) { @@ -17,10 +17,10 @@ index f07cf6d91e0cbad80c3c630c0d505820e701ce81..3dc3609d13a7b823d15384d1c385b68e int k = j; diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java -index 4ee7a4e5637fe36eb50e8ec9186d72d1253bfd98..b345403cdf5b2828f99708fef65136594a3331c3 100644 +index f3687ecd2d757b22b224346bbb8342d83221efdb..0fab8826e14af9184f07bc1262555a71effcd84b 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java -@@ -446,6 +446,7 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -447,6 +447,7 @@ public class BeehiveBlockEntity extends BlockEntity { } private static void setBeeReleaseData(int ticksInHive, Bee beeEntity) { @@ -28,7 +28,7 @@ index 4ee7a4e5637fe36eb50e8ec9186d72d1253bfd98..b345403cdf5b2828f99708fef6513659 int j = beeEntity.getAge(); if (j < 0) { -@@ -455,6 +456,7 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -456,6 +457,7 @@ public class BeehiveBlockEntity extends BlockEntity { } beeEntity.setInLoveTime(Math.max(0, beeEntity.getInLoveTime() - ticksInHive)); diff --git a/patches/unapplied/server/0249-Configurable-connection-throttle-kick-message.patch b/patches/server/0248-Configurable-connection-throttle-kick-message.patch similarity index 100% rename from patches/unapplied/server/0249-Configurable-connection-throttle-kick-message.patch rename to patches/server/0248-Configurable-connection-throttle-kick-message.patch diff --git a/patches/server/0249-Prevent-chunk-loading-from-Fluid-Flowing.patch b/patches/server/0249-Prevent-chunk-loading-from-Fluid-Flowing.patch new file mode 100644 index 000000000000..8426fd78fd9a --- /dev/null +++ b/patches/server/0249-Prevent-chunk-loading-from-Fluid-Flowing.patch @@ -0,0 +1,88 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Mon, 10 Sep 2018 23:36:16 -0400 +Subject: [PATCH] Prevent chunk loading from Fluid Flowing + + +diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +index 2053d1e0b7577ec99958bae828b4c219b835edfc..83dc8bcd9e2b8ecbd32225e4e10aec392ef28325 100644 +--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java ++++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +@@ -184,6 +184,8 @@ public abstract class FlowingFluid extends Fluid { + Direction enumdirection = (Direction) entry.getKey(); + FluidState fluid1 = (FluidState) entry.getValue(); + BlockPos blockposition1 = pos.relative(enumdirection); ++ final BlockState blockStateIfLoaded = world.getBlockStateIfLoaded(blockposition1); // Paper - Prevent chunk loading from fluid flowing ++ if (blockStateIfLoaded == null) continue; // Paper - Prevent chunk loading from fluid flowing + + // CraftBukkit start + org.bukkit.block.Block source = CraftBlock.at(world, pos); +@@ -194,7 +196,7 @@ public abstract class FlowingFluid extends Fluid { + continue; + } + // CraftBukkit end +- this.spreadTo(world, blockposition1, world.getBlockState(blockposition1), enumdirection, fluid1); ++ this.spreadTo(world, blockposition1, blockStateIfLoaded, enumdirection, fluid1); // Paper - Prevent chunk loading from fluid flowing + } + + } +@@ -209,7 +211,8 @@ public abstract class FlowingFluid extends Fluid { + while (iterator.hasNext()) { + Direction enumdirection = (Direction) iterator.next(); + BlockPos.MutableBlockPos blockposition_mutableblockposition1 = blockposition_mutableblockposition.setWithOffset(pos, enumdirection); +- BlockState iblockdata1 = world.getBlockState(blockposition_mutableblockposition1); ++ BlockState iblockdata1 = world.getBlockStateIfLoaded(blockposition_mutableblockposition1); // Paper - Prevent chunk loading from fluid flowing ++ if (iblockdata1 == null) continue; // Paper - Prevent chunk loading from fluid flowing + FluidState fluid = iblockdata1.getFluidState(); + + if (fluid.getType().isSame(this) && FlowingFluid.canPassThroughWall(enumdirection, world, pos, state, blockposition_mutableblockposition1, iblockdata1)) { +@@ -332,7 +335,8 @@ public abstract class FlowingFluid extends Fluid { + + if (enumdirection1 != direction) { + BlockPos blockposition1 = pos.relative(enumdirection1); +- BlockState iblockdata1 = spreadCache.getBlockState(blockposition1); ++ BlockState iblockdata1 = spreadCache.getBlockStateIfLoaded(blockposition1); // Paper - Prevent chunk loading from fluid flowing ++ if (iblockdata1 == null) continue; // Paper - Prevent chunk loading from fluid flowing + FluidState fluid = iblockdata1.getFluidState(); + + if (this.canPassThrough(world, this.getFlowing(), pos, state, enumdirection1, blockposition1, iblockdata1, fluid)) { +@@ -398,7 +402,8 @@ public abstract class FlowingFluid extends Fluid { + while (iterator.hasNext()) { + Direction enumdirection = (Direction) iterator.next(); + BlockPos blockposition1 = pos.relative(enumdirection); +- BlockState iblockdata1 = world.getBlockState(blockposition1); ++ BlockState iblockdata1 = world.getBlockStateIfLoaded(blockposition1); // Paper - Prevent chunk loading from fluid flowing ++ if (iblockdata1 == null) continue; // Paper - Prevent chunk loading from fluid flowing + FluidState fluid = iblockdata1.getFluidState(); + + if (this.canMaybePassThrough(world, pos, state, enumdirection, blockposition1, iblockdata1, fluid)) { +@@ -564,11 +569,26 @@ public abstract class FlowingFluid extends Fluid { + public BlockState getBlockState(BlockPos pos) { + return this.getBlockState(pos, this.getCacheKey(pos)); + } ++ // Paper start - Prevent chunk loading from fluid flowing ++ public @javax.annotation.Nullable BlockState getBlockStateIfLoaded(BlockPos pos) { ++ return this.getBlockState(pos, this.getCacheKey(pos), false); ++ } ++ // Paper end - Prevent chunk loading from fluid flowing + + private BlockState getBlockState(BlockPos pos, short packed) { +- return (BlockState) this.stateCache.computeIfAbsent(packed, (short1) -> { +- return this.level.getBlockState(pos); +- }); ++ // Paper start - Prevent chunk loading from fluid flowing ++ return getBlockState(pos, packed, true); ++ } ++ private @javax.annotation.Nullable BlockState getBlockState(BlockPos pos, short packed, boolean load) { ++ BlockState blockState = this.stateCache.get(packed); ++ if (blockState == null) { ++ blockState = load ? level.getBlockState(pos) : level.getBlockStateIfLoaded(pos); ++ if (blockState != null) { ++ this.stateCache.put(packed, blockState); ++ } ++ } ++ return blockState; ++ // Paper end - Prevent chunk loading from fluid flowing + } + + public boolean isHole(BlockPos pos) { diff --git a/patches/unapplied/server/0250-Prevent-chunk-loading-from-Fluid-Flowing.patch b/patches/unapplied/server/0250-Prevent-chunk-loading-from-Fluid-Flowing.patch deleted file mode 100644 index 50c82e5d54ce..000000000000 --- a/patches/unapplied/server/0250-Prevent-chunk-loading-from-Fluid-Flowing.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Mon, 10 Sep 2018 23:36:16 -0400 -Subject: [PATCH] Prevent chunk loading from Fluid Flowing - - -diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -index b67bc6d6a02fdac377f32a766fd8cc2c5fc43488..3a2ae2bca410708736da64560e74b8010444f2dc 100644 ---- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -+++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -@@ -176,7 +176,8 @@ public abstract class FlowingFluid extends Fluid { - Direction enumdirection = (Direction) entry.getKey(); - FluidState fluid1 = (FluidState) entry.getValue(); - BlockPos blockposition1 = pos.relative(enumdirection); -- BlockState iblockdata1 = world.getBlockState(blockposition1); -+ BlockState iblockdata1 = world.getBlockStateIfLoaded(blockposition1); // Paper - Prevent chunk loading from fluid flowing -+ if (iblockdata1 == null) continue; // Paper - Prevent chunk loading from fluid flowing - - if (this.canSpreadTo(world, pos, blockState, enumdirection, blockposition1, iblockdata1, world.getFluidState(blockposition1), fluid1.getType())) { - // CraftBukkit start -@@ -203,7 +204,8 @@ public abstract class FlowingFluid extends Fluid { - while (iterator.hasNext()) { - Direction enumdirection = (Direction) iterator.next(); - BlockPos blockposition1 = pos.relative(enumdirection); -- BlockState iblockdata1 = world.getBlockState(blockposition1); -+ BlockState iblockdata1 = world.getBlockStateIfLoaded(blockposition1); // Paper - Prevent chunk loading from fluid flowing -+ if (iblockdata1 == null) continue; // Paper - Prevent chunk loading from fluid flowing - FluidState fluid = iblockdata1.getFluidState(); - - if (fluid.getType().isSame(this) && this.canPassThroughWall(enumdirection, world, pos, state, blockposition1, iblockdata1)) { -@@ -320,11 +322,18 @@ public abstract class FlowingFluid extends Fluid { - if (enumdirection1 != direction) { - BlockPos blockposition2 = pos.relative(enumdirection1); - short short0 = FlowingFluid.getCacheKey(fromPos, blockposition2); -- Pair pair = (Pair) stateCache.computeIfAbsent(short0, (short1) -> { -- BlockState iblockdata1 = world.getBlockState(blockposition2); -+ // Paper start - Prevent chunk loading from fluid flowing -+ Pair pair = stateCache.get(short0); -+ if (pair == null) { -+ BlockState iblockdatax = world.getBlockStateIfLoaded(blockposition2); -+ if (iblockdatax == null) { -+ continue; -+ } - -- return Pair.of(iblockdata1, iblockdata1.getFluidState()); -- }); -+ pair = Pair.of(iblockdatax, iblockdatax.getFluidState()); -+ stateCache.put(short0, pair); -+ } -+ // Paper end - Prevent chunk loading from fluid flowing - BlockState iblockdata1 = (BlockState) pair.getFirst(); - FluidState fluid = (FluidState) pair.getSecond(); - -@@ -396,11 +405,16 @@ public abstract class FlowingFluid extends Fluid { - Direction enumdirection = (Direction) iterator.next(); - BlockPos blockposition1 = pos.relative(enumdirection); - short short0 = FlowingFluid.getCacheKey(pos, blockposition1); -- Pair pair = (Pair) short2objectmap.computeIfAbsent(short0, (short1) -> { -- BlockState iblockdata1 = world.getBlockState(blockposition1); -- -- return Pair.of(iblockdata1, iblockdata1.getFluidState()); -- }); -+ // Paper start - Prevent chunk loading from fluid flowing -+ Pair pair = (Pair) short2objectmap.get(short0); -+ if (pair == null) { -+ BlockState iblockdatax = world.getBlockStateIfLoaded(blockposition1); -+ if (iblockdatax == null) continue; -+ -+ pair = Pair.of(iblockdatax, iblockdatax.getFluidState()); -+ short2objectmap.put(short0, pair); -+ } -+ // Paper end - Prevent chunk loading from fluid flowing - BlockState iblockdata1 = (BlockState) pair.getFirst(); - FluidState fluid = (FluidState) pair.getSecond(); - FluidState fluid1 = this.getNewLiquid(world, blockposition1, iblockdata1); From f677393a88e07be9cc13949eb508e6f92562d980 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Wed, 23 Oct 2024 14:12:17 +0200 Subject: [PATCH 015/119] Skip Improve-exact-choice-recipe-ingredients for now --- ...rove-exact-choice-recipe-ingredients.patch | 0 .../0250-PreSpawnerSpawnEvent.patch} | 2 +- ...51-Add-LivingEntity-getTargetEntity.patch} | 33 +++++---------- .../0252-Add-sun-related-API.patch} | 8 ++-- .../0253-Turtle-API.patch} | 6 +-- ...ator-target-events-and-improve-impl.patch} | 4 +- .../0255-Add-more-Witch-API.patch} | 6 +-- ...wned-for-Villager-Aggression-Config.patch} | 12 +++--- ...vent-players-from-moving-into-unloa.patch} | 14 +++---- ...8-Reset-players-airTicks-on-respawn.patch} | 6 +-- ...after-profile-lookups-if-not-needed.patch} | 0 ...r-Thread-Pool-and-Thread-Priorities.patch} | 40 ++++++++++--------- .../0261-Optimize-World-Time-Updates.patch} | 6 +-- ...tore-custom-InventoryHolder-support.patch} | 0 ...0263-Fix-SpongeAbsortEvent-handling.patch} | 4 +- ...-allow-digging-into-unloaded-chunks.patch} | 18 ++++----- ...ult-permission-message-configurable.patch} | 4 +- ...ntity-dismount-during-teleportation.patch} | 26 ++++++------ .../0267-Add-more-Zombie-API.patch} | 16 ++++---- .../0268-Book-size-limits.patch} | 20 +--------- ...0269-Add-PlayerConnectionCloseEvent.patch} | 2 +- ...Replace-OfflinePlayer-getLastPlayed.patch} | 20 +++++----- ...ehicle-tracking-issue-on-disconnect.patch} | 4 +- ...-remove-if-the-handle-is-a-custom-p.patch} | 4 +- .../0273-BlockDestroyEvent.patch} | 4 +- .../0274-Async-command-map-building.patch} | 10 ++--- .../0275-Brigadier-Mojang-API.patch} | 18 ++++----- 27 files changed, 129 insertions(+), 158 deletions(-) rename patches/{unapplied/server => later}/0277-Improve-exact-choice-recipe-ingredients.patch (100%) rename patches/{unapplied/server/0251-PreSpawnerSpawnEvent.patch => server/0250-PreSpawnerSpawnEvent.patch} (94%) rename patches/{unapplied/server/0252-Add-LivingEntity-getTargetEntity.patch => server/0251-Add-LivingEntity-getTargetEntity.patch} (73%) rename patches/{unapplied/server/0253-Add-sun-related-API.patch => server/0252-Add-sun-related-API.patch} (80%) rename patches/{unapplied/server/0254-Turtle-API.patch => server/0253-Turtle-API.patch} (96%) rename patches/{unapplied/server/0255-Call-player-spectator-target-events-and-improve-impl.patch => server/0254-Call-player-spectator-target-events-and-improve-impl.patch} (93%) rename patches/{unapplied/server/0256-Add-more-Witch-API.patch => server/0255-Add-more-Witch-API.patch} (95%) rename patches/{unapplied/server/0257-Check-Drowned-for-Villager-Aggression-Config.patch => server/0256-Check-Drowned-for-Villager-Aggression-Config.patch} (71%) rename patches/{unapplied/server/0258-Add-option-to-prevent-players-from-moving-into-unloa.patch => server/0257-Add-option-to-prevent-players-from-moving-into-unloa.patch} (86%) rename patches/{unapplied/server/0259-Reset-players-airTicks-on-respawn.patch => server/0258-Reset-players-airTicks-on-respawn.patch} (79%) rename patches/{unapplied/server/0260-Don-t-sleep-after-profile-lookups-if-not-needed.patch => server/0259-Don-t-sleep-after-profile-lookups-if-not-needed.patch} (100%) rename patches/{unapplied/server/0261-Improve-Server-Thread-Pool-and-Thread-Priorities.patch => server/0260-Improve-Server-Thread-Pool-and-Thread-Priorities.patch} (77%) rename patches/{unapplied/server/0262-Optimize-World-Time-Updates.patch => server/0261-Optimize-World-Time-Updates.patch} (89%) rename patches/{unapplied/server/0263-Restore-custom-InventoryHolder-support.patch => server/0262-Restore-custom-InventoryHolder-support.patch} (100%) rename patches/{unapplied/server/0264-Fix-SpongeAbsortEvent-handling.patch => server/0263-Fix-SpongeAbsortEvent-handling.patch} (89%) rename patches/{unapplied/server/0265-Don-t-allow-digging-into-unloaded-chunks.patch => server/0264-Don-t-allow-digging-into-unloaded-chunks.patch} (88%) rename patches/{unapplied/server/0266-Make-the-default-permission-message-configurable.patch => server/0265-Make-the-default-permission-message-configurable.patch} (92%) rename patches/{unapplied/server/0267-force-entity-dismount-during-teleportation.patch => server/0266-force-entity-dismount-during-teleportation.patch} (88%) rename patches/{unapplied/server/0268-Add-more-Zombie-API.patch => server/0267-Add-more-Zombie-API.patch} (88%) rename patches/{unapplied/server/0269-Book-size-limits.patch => server/0268-Book-size-limits.patch} (65%) rename patches/{unapplied/server/0270-Add-PlayerConnectionCloseEvent.patch => server/0269-Add-PlayerConnectionCloseEvent.patch} (98%) rename patches/{unapplied/server/0271-Replace-OfflinePlayer-getLastPlayed.patch => server/0270-Replace-OfflinePlayer-getLastPlayed.patch} (89%) rename patches/{unapplied/server/0272-Workaround-for-vehicle-tracking-issue-on-disconnect.patch => server/0271-Workaround-for-vehicle-tracking-issue-on-disconnect.patch} (86%) rename patches/{unapplied/server/0273-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch => server/0272-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch} (87%) rename patches/{unapplied/server/0274-BlockDestroyEvent.patch => server/0273-BlockDestroyEvent.patch} (94%) rename patches/{unapplied/server/0275-Async-command-map-building.patch => server/0274-Async-command-map-building.patch} (90%) rename patches/{unapplied/server/0276-Brigadier-Mojang-API.patch => server/0275-Brigadier-Mojang-API.patch} (95%) diff --git a/patches/unapplied/server/0277-Improve-exact-choice-recipe-ingredients.patch b/patches/later/0277-Improve-exact-choice-recipe-ingredients.patch similarity index 100% rename from patches/unapplied/server/0277-Improve-exact-choice-recipe-ingredients.patch rename to patches/later/0277-Improve-exact-choice-recipe-ingredients.patch diff --git a/patches/unapplied/server/0251-PreSpawnerSpawnEvent.patch b/patches/server/0250-PreSpawnerSpawnEvent.patch similarity index 94% rename from patches/unapplied/server/0251-PreSpawnerSpawnEvent.patch rename to patches/server/0250-PreSpawnerSpawnEvent.patch index 3512bab510e8..d10c136bb81d 100644 --- a/patches/unapplied/server/0251-PreSpawnerSpawnEvent.patch +++ b/patches/server/0250-PreSpawnerSpawnEvent.patch @@ -9,7 +9,7 @@ SpawnerSpawnEvent gets called instead of the CreatureSpawnEvent for spawners. diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index d13abdcc7a54bdecf853c883911ef535733610b4..ee897b8c9462dbb3d7be9a2994753155065ce205 100644 +index bb3f3bec350dda43dbf5eda0a8c8057a413694b2..261de9ea37d22023da6a306b58b1b62a54dc03da 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java @@ -133,10 +133,10 @@ public abstract class BaseSpawner { diff --git a/patches/unapplied/server/0252-Add-LivingEntity-getTargetEntity.patch b/patches/server/0251-Add-LivingEntity-getTargetEntity.patch similarity index 73% rename from patches/unapplied/server/0252-Add-LivingEntity-getTargetEntity.patch rename to patches/server/0251-Add-LivingEntity-getTargetEntity.patch index 7b66e0ad7524..5b17b5d4ffa8 100644 --- a/patches/unapplied/server/0252-Add-LivingEntity-getTargetEntity.patch +++ b/patches/server/0251-Add-LivingEntity-getTargetEntity.patch @@ -5,22 +5,14 @@ Subject: [PATCH] Add LivingEntity#getTargetEntity diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 64aa52c2d1fe50d304d75ebb197e8a834016c3cf..7bc0a66602d77902d83d6ca515da48e3453de900 100644 +index a7e950bc5aa827c1b137a12c9eaaf7eac867bdc3..b87b59a2ead87b6bda8a8c5bcfd63b128c88f626 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -127,6 +127,7 @@ import net.minecraft.world.level.storage.loot.LootTable; - import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; - import net.minecraft.world.level.storage.loot.parameters.LootContextParams; - import net.minecraft.world.phys.AABB; -+import net.minecraft.world.phys.EntityHitResult; - import net.minecraft.world.phys.HitResult; - import net.minecraft.world.phys.Vec3; - import net.minecraft.world.scores.PlayerTeam; -@@ -4044,6 +4045,38 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4178,6 +4178,38 @@ public abstract class LivingEntity extends Entity implements Attackable { return this.level().clip(raytrace); } -+ public @Nullable EntityHitResult getTargetEntity(int maxDistance) { ++ public @Nullable net.minecraft.world.phys.EntityHitResult getTargetEntity(int maxDistance) { + if (maxDistance < 1 || maxDistance > 120) { + throw new IllegalArgumentException("maxDistance must be between 1-120"); + } @@ -32,7 +24,7 @@ index 64aa52c2d1fe50d304d75ebb197e8a834016c3cf..7bc0a66602d77902d83d6ca515da48e3 + List entityList = this.level().getEntities(this, getBoundingBox().expandTowards(direction.x * maxDistance, direction.y * maxDistance, direction.z * maxDistance).inflate(1.0D, 1.0D, 1.0D), EntitySelector.NO_SPECTATORS.and(Entity::isPickable)); + + double distance = 0.0D; -+ EntityHitResult result = null; ++ net.minecraft.world.phys.EntityHitResult result = null; + + for (Entity entity : entityList) { + final double inflationAmount = (double) entity.getPickRadius(); @@ -43,7 +35,7 @@ index 64aa52c2d1fe50d304d75ebb197e8a834016c3cf..7bc0a66602d77902d83d6ca515da48e3 + Vec3 rayTrace = rayTraceResult.get(); + double distanceTo = start.distanceToSqr(rayTrace); + if (distanceTo < distance || distance == 0.0D) { -+ result = new EntityHitResult(entity, rayTrace); ++ result = new net.minecraft.world.phys.EntityHitResult(entity, rayTrace); + distance = distanceTo; + } + } @@ -56,17 +48,10 @@ index 64aa52c2d1fe50d304d75ebb197e8a834016c3cf..7bc0a66602d77902d83d6ca515da48e3 public int getShieldBlockingDelay() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index c8ac50351b7b1b2f4afc138570b8098a3c0ce1ba..c0684f1864ece26b4f337ac615db04f615957c13 100644 +index 0c7bf4124d67258ebca9b9b73b92c2e0efbdaa86..c4c83b4e17aac23794fdb51acfba4e7ef8451e2c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -1,5 +1,6 @@ - package org.bukkit.craftbukkit.entity; - -+import com.destroystokyo.paper.entity.TargetEntityInfo; - import com.google.common.base.Preconditions; - import com.google.common.collect.Sets; - import java.util.ArrayList; -@@ -227,6 +228,39 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -232,6 +232,39 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { } return null; } @@ -76,9 +61,9 @@ index c8ac50351b7b1b2f4afc138570b8098a3c0ce1ba..c0684f1864ece26b4f337ac615db04f6 + return rayTrace == null ? null : rayTrace.getEntity().getBukkitEntity(); + } + -+ public TargetEntityInfo getTargetEntityInfo(int maxDistance, boolean ignoreBlocks) { ++ public com.destroystokyo.paper.entity.TargetEntityInfo getTargetEntityInfo(int maxDistance, boolean ignoreBlocks) { + net.minecraft.world.phys.EntityHitResult rayTrace = rayTraceEntity(maxDistance, ignoreBlocks); -+ return rayTrace == null ? null : new TargetEntityInfo(rayTrace.getEntity().getBukkitEntity(), new org.bukkit.util.Vector(rayTrace.getLocation().x, rayTrace.getLocation().y, rayTrace.getLocation().z)); ++ return rayTrace == null ? null : new com.destroystokyo.paper.entity.TargetEntityInfo(rayTrace.getEntity().getBukkitEntity(), new org.bukkit.util.Vector(rayTrace.getLocation().x, rayTrace.getLocation().y, rayTrace.getLocation().z)); + } + + @Override diff --git a/patches/unapplied/server/0253-Add-sun-related-API.patch b/patches/server/0252-Add-sun-related-API.patch similarity index 80% rename from patches/unapplied/server/0253-Add-sun-related-API.patch rename to patches/server/0252-Add-sun-related-API.patch index 01cd62209b1e..63382c55de54 100644 --- a/patches/unapplied/server/0253-Add-sun-related-API.patch +++ b/patches/server/0252-Add-sun-related-API.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Add sun related API public net.minecraft.world.entity.Mob isSunBurnTick()Z diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 333e3109d19c867e8a74f20693952bdb3df804e4..20bb365b188c7081123db87186f0e1a999758817 100644 +index 0a53b01094bd8070e57fb3c967c1129a53bd7ff8..d723486f1582b232fbf78898a56caa3a13954417 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -756,6 +756,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -762,6 +762,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { } } @@ -25,10 +25,10 @@ index 333e3109d19c867e8a74f20693952bdb3df804e4..20bb365b188c7081123db87186f0e1a9 public long getGameTime() { return this.world.levelData.getGameTime(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java -index d597eea5d5c2f223e87bff06f292619657596f1f..2a8596e4f9d7be966c18e867c2c7b5bfbea9742c 100644 +index 26c9bc53fe50636ca1eb32144c648f382d4172ff..c67673772c876dab7c015dcdfb75b297d3c4fbad 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java -@@ -90,4 +90,11 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob { +@@ -91,4 +91,11 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob { public long getSeed() { return this.getHandle().lootTableSeed; } diff --git a/patches/unapplied/server/0254-Turtle-API.patch b/patches/server/0253-Turtle-API.patch similarity index 96% rename from patches/unapplied/server/0254-Turtle-API.patch rename to patches/server/0253-Turtle-API.patch index efd6b79262ac..bf96743cf230 100644 --- a/patches/unapplied/server/0254-Turtle-API.patch +++ b/patches/server/0253-Turtle-API.patch @@ -12,10 +12,10 @@ public net.minecraft.world.entity.animal.Turtle isTravelling()Z public net.minecraft.world.entity.animal.Turtle setTravelling(Z)V diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java -index 6f90ee749aed98b97868aa40fc233d164ddc2ef6..34e6bf677a9f4548f3febe6d57e6af9602530271 100644 +index a2c5042e99a8f4cd45d502320cf1c06e8af0bd0e..ed7f5eb9b3b700c2f817d61ee0bf8a6952731510 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java +++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java -@@ -487,14 +487,17 @@ public class Turtle extends Animal { +@@ -494,14 +494,17 @@ public class Turtle extends Animal { if (!this.turtle.isInWater() && this.isReachedTarget()) { if (this.turtle.layEggCounter < 1) { @@ -36,7 +36,7 @@ index 6f90ee749aed98b97868aa40fc233d164ddc2ef6..34e6bf677a9f4548f3febe6d57e6af96 world.setBlock(blockposition1, iblockdata, 3); world.gameEvent((Holder) GameEvent.BLOCK_PLACE, blockposition1, GameEvent.Context.of(this.turtle, iblockdata)); -@@ -564,7 +567,7 @@ public class Turtle extends Animal { +@@ -571,7 +574,7 @@ public class Turtle extends Animal { @Override public boolean canUse() { diff --git a/patches/unapplied/server/0255-Call-player-spectator-target-events-and-improve-impl.patch b/patches/server/0254-Call-player-spectator-target-events-and-improve-impl.patch similarity index 93% rename from patches/unapplied/server/0255-Call-player-spectator-target-events-and-improve-impl.patch rename to patches/server/0254-Call-player-spectator-target-events-and-improve-impl.patch index b29358d325b3..e23eee6ec8d3 100644 --- a/patches/unapplied/server/0255-Call-player-spectator-target-events-and-improve-impl.patch +++ b/patches/server/0254-Call-player-spectator-target-events-and-improve-impl.patch @@ -19,10 +19,10 @@ spectate the target entity. Co-authored-by: Spottedleaf diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index fa8640f961b93dc811296131dfda58faa1908add..15328d344a26f5c40011ee6ba0bc54dd5ab0b87b 100644 +index 2bd97344502a63173de923542f27759d7e98b6cc..c533098740bbf5d8e27011fa9593a0fa274e6600 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -2182,6 +2182,21 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2441,6 +2441,21 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.camera = (Entity) (entity == null ? this : entity); if (entity1 != this.camera) { diff --git a/patches/unapplied/server/0256-Add-more-Witch-API.patch b/patches/server/0255-Add-more-Witch-API.patch similarity index 95% rename from patches/unapplied/server/0256-Add-more-Witch-API.patch rename to patches/server/0255-Add-more-Witch-API.patch index ead3a185c684..c250557de6fe 100644 --- a/patches/unapplied/server/0256-Add-more-Witch-API.patch +++ b/patches/server/0255-Add-more-Witch-API.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Add more Witch API public net.minecraft.world.entity.monster.Witch usingTime diff --git a/src/main/java/net/minecraft/world/entity/monster/Witch.java b/src/main/java/net/minecraft/world/entity/monster/Witch.java -index f6d01d21745391595d61b191832be4c28a3e58cb..b8ff1e3d280171378fe383bcc7c6a855d20ae5d1 100644 +index 120f0c729c48ddfa598472029cdfbab3dc6db50f..a03fa8a3e648532a7ffaaf523ca87c13e8af4c0a 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Witch.java +++ b/src/main/java/net/minecraft/world/entity/monster/Witch.java -@@ -151,21 +151,7 @@ public class Witch extends Raider implements RangedAttackMob { +@@ -152,21 +152,7 @@ public class Witch extends Raider implements RangedAttackMob { } if (holder != null) { @@ -33,7 +33,7 @@ index f6d01d21745391595d61b191832be4c28a3e58cb..b8ff1e3d280171378fe383bcc7c6a855 } } -@@ -177,6 +163,23 @@ public class Witch extends Raider implements RangedAttackMob { +@@ -178,6 +164,23 @@ public class Witch extends Raider implements RangedAttackMob { super.aiStep(); } diff --git a/patches/unapplied/server/0257-Check-Drowned-for-Villager-Aggression-Config.patch b/patches/server/0256-Check-Drowned-for-Villager-Aggression-Config.patch similarity index 71% rename from patches/unapplied/server/0257-Check-Drowned-for-Villager-Aggression-Config.patch rename to patches/server/0256-Check-Drowned-for-Villager-Aggression-Config.patch index efafeb919ce5..34b444c1096e 100644 --- a/patches/unapplied/server/0257-Check-Drowned-for-Villager-Aggression-Config.patch +++ b/patches/server/0256-Check-Drowned-for-Villager-Aggression-Config.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Check Drowned for Villager Aggression Config diff --git a/src/main/java/net/minecraft/world/entity/monster/Drowned.java b/src/main/java/net/minecraft/world/entity/monster/Drowned.java -index d4b3ce2bb2021625c90a3f51c6f9da6056b2e2ff..cff1b5e0e3fd32d82157d5f13d83d4abdfad7378 100644 +index 95e0a5d464398c17dfaa2f919a17f63c63925551..2e73917ce9270de7483bb1d4e9bf312a31ec9b1e 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Drowned.java +++ b/src/main/java/net/minecraft/world/entity/monster/Drowned.java -@@ -81,7 +81,7 @@ public class Drowned extends Zombie implements RangedAttackMob { - this.goalSelector.addGoal(7, new RandomStrollGoal(this, 1.0D)); - this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[]{Drowned.class})).setAlertOthers(ZombifiedPiglin.class)); - this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::okTarget)); +@@ -82,7 +82,7 @@ public class Drowned extends Zombie implements RangedAttackMob { + this.goalSelector.addGoal(7, new RandomStrollGoal(this, 1.0)); + this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Drowned.class).setAlertOthers(ZombifiedPiglin.class)); + this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (target, world) -> this.okTarget(target))); - this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)); -+ if (this.level().spigotConfig.zombieAggressiveTowardsVillager) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)); // Paper - Check drowned for villager aggression config ++ if (this.level().spigotConfig.zombieAggressiveTowardsVillager) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)); // Paper - Check drowned for villager aggression config this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Axolotl.class, true, false)); this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, true, false, Turtle.BABY_ON_LAND_SELECTOR)); diff --git a/patches/unapplied/server/0258-Add-option-to-prevent-players-from-moving-into-unloa.patch b/patches/server/0257-Add-option-to-prevent-players-from-moving-into-unloa.patch similarity index 86% rename from patches/unapplied/server/0258-Add-option-to-prevent-players-from-moving-into-unloa.patch rename to patches/server/0257-Add-option-to-prevent-players-from-moving-into-unloa.patch index c62badf3b150..e09aa1791124 100644 --- a/patches/unapplied/server/0258-Add-option-to-prevent-players-from-moving-into-unloa.patch +++ b/patches/server/0257-Add-option-to-prevent-players-from-moving-into-unloa.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add option to prevent players from moving into unloaded diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 5ed35d744a87290a03e9bf58143b5650501af0e6..6cf68d7173bc23c39261856f11cbd42de387bd60 100644 +index 816b53894c6420a6b1603252e53facacecc07c52..825e181edc612daa2deaee2977d82a0d048720e7 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -494,9 +494,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -491,9 +491,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl double d0 = entity.getX(); double d1 = entity.getY(); double d2 = entity.getZ(); @@ -22,7 +22,7 @@ index 5ed35d744a87290a03e9bf58143b5650501af0e6..6cf68d7173bc23c39261856f11cbd42d float f = Mth.wrapDegrees(packet.getYRot()); float f1 = Mth.wrapDegrees(packet.getXRot()); double d6 = d3 - this.vehicleFirstGoodX; -@@ -530,6 +530,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -527,6 +527,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } speed *= 2f; // TODO: Get the speed of the vehicle instead of the player @@ -39,7 +39,7 @@ index 5ed35d744a87290a03e9bf58143b5650501af0e6..6cf68d7173bc23c39261856f11cbd42d if (d10 - d9 > Math.max(100.0D, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { // CraftBukkit end ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", new Object[]{entity.getName().getString(), this.player.getName().getString(), d6, d7, d8}); -@@ -1157,9 +1167,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1160,9 +1170,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } if (!this.updateAwaitingTeleport()) { @@ -52,16 +52,16 @@ index 5ed35d744a87290a03e9bf58143b5650501af0e6..6cf68d7173bc23c39261856f11cbd42d float f = Mth.wrapDegrees(packet.getYRot(this.player.getYRot())); float f1 = Mth.wrapDegrees(packet.getXRot(this.player.getXRot())); -@@ -1217,6 +1227,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1220,6 +1230,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } else { speed = this.player.getAbilities().walkingSpeed * 10f; } + // Paper start - Prevent moving into unloaded chunks + if (this.player.level().paperConfig().chunks.preventMovingIntoUnloadedChunks && (this.player.getX() != toX || this.player.getZ() != toZ) && !worldserver.areChunksLoadedForMove(this.player.getBoundingBox().expandTowards(new Vec3(toX, toY, toZ).subtract(this.player.position())))) { -+ this.internalTeleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot(), Collections.emptySet()); ++ this.internalTeleport(PositionMoveRotation.of(this.player), Collections.emptySet()); + return; + } + // Paper end - Prevent moving into unloaded chunks - if (!this.player.isChangingDimension() && (!this.player.level().getGameRules().getBoolean(GameRules.RULE_DISABLE_ELYTRA_MOVEMENT_CHECK) || !flag)) { + if (this.shouldCheckPlayerMovement(flag)) { float f2 = flag ? 300.0F : 100.0F; diff --git a/patches/unapplied/server/0259-Reset-players-airTicks-on-respawn.patch b/patches/server/0258-Reset-players-airTicks-on-respawn.patch similarity index 79% rename from patches/unapplied/server/0259-Reset-players-airTicks-on-respawn.patch rename to patches/server/0258-Reset-players-airTicks-on-respawn.patch index 0669db4de0c0..601a3944c079 100644 --- a/patches/unapplied/server/0259-Reset-players-airTicks-on-respawn.patch +++ b/patches/server/0258-Reset-players-airTicks-on-respawn.patch @@ -5,14 +5,14 @@ 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 15328d344a26f5c40011ee6ba0bc54dd5ab0b87b..7cca5c778f9d20cfa6cb543c9afcf74779aaa355 100644 +index c533098740bbf5d8e27011fa9593a0fa274e6600..cef054ba95ed7d2b0e2ee575edae3e94b77f58b6 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -2703,6 +2703,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -3052,6 +3052,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.setHealth(this.getMaxHealth()); this.stopUsingItem(); // CraftBukkit - SPIGOT-6682: Clear active item on reset + this.setAirSupply(this.getMaxAirSupply()); // Paper - Reset players airTicks on respawn this.setRemainingFireTicks(0); this.fallDistance = 0; - this.foodData = new FoodData(this); + this.foodData = new FoodData(); diff --git a/patches/unapplied/server/0260-Don-t-sleep-after-profile-lookups-if-not-needed.patch b/patches/server/0259-Don-t-sleep-after-profile-lookups-if-not-needed.patch similarity index 100% rename from patches/unapplied/server/0260-Don-t-sleep-after-profile-lookups-if-not-needed.patch rename to patches/server/0259-Don-t-sleep-after-profile-lookups-if-not-needed.patch diff --git a/patches/unapplied/server/0261-Improve-Server-Thread-Pool-and-Thread-Priorities.patch b/patches/server/0260-Improve-Server-Thread-Pool-and-Thread-Priorities.patch similarity index 77% rename from patches/unapplied/server/0261-Improve-Server-Thread-Pool-and-Thread-Priorities.patch rename to patches/server/0260-Improve-Server-Thread-Pool-and-Thread-Priorities.patch index 588ca7240f46..7ea32f4967db 100644 --- a/patches/unapplied/server/0261-Improve-Server-Thread-Pool-and-Thread-Priorities.patch +++ b/patches/server/0260-Improve-Server-Thread-Pool-and-Thread-Priorities.patch @@ -38,25 +38,25 @@ index 0000000000000000000000000000000000000000..b60f59cf5cc8eb84a6055b7861857dec + } +} diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java -index 54562fa04d14a937451ea7aa9d80194f2c31b471..4cf88f6d815d60cfbf8e4ecf9d96d0cfadd0620b 100644 +index b87d3ac2700eedb492bd55a631c60630c2f9c96c..0fbe4ea495a8101f6bc1b9830ce3f47af2aa5be4 100644 --- a/src/main/java/net/minecraft/Util.java +++ b/src/main/java/net/minecraft/Util.java -@@ -89,7 +89,7 @@ public class Util { +@@ -92,7 +92,7 @@ public class Util { private static final int DEFAULT_MAX_THREADS = 255; private static final int DEFAULT_SAFE_FILE_OPERATION_RETRIES = 10; private static final String MAX_THREADS_SYSTEM_PROPERTY = "max.bg.threads"; -- private static final ExecutorService BACKGROUND_EXECUTOR = makeExecutor("Main"); -+ private static final ExecutorService BACKGROUND_EXECUTOR = makeExecutor("Main", -1); // Paper - Perf: add priority - private static final ExecutorService IO_POOL = makeIoExecutor("IO-Worker-", false); - private static final ExecutorService DOWNLOAD_POOL = makeIoExecutor("Download-", true); +- private static final TracingExecutor BACKGROUND_EXECUTOR = makeExecutor("Main"); ++ private static final TracingExecutor BACKGROUND_EXECUTOR = makeExecutor("Main", -1); // Paper - Perf: add priority + private static final TracingExecutor IO_POOL = makeIoExecutor("IO-Worker-", false); + private static final TracingExecutor DOWNLOAD_POOL = makeIoExecutor("Download-", true); // Paper start - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread -@@ -160,15 +160,27 @@ public class Util { +@@ -163,15 +163,28 @@ public class Util { return FILENAME_DATE_TIME_FORMATTER.format(ZonedDateTime.now()); } -- private static ExecutorService makeExecutor(String name) { +- private static TracingExecutor makeExecutor(String name) { - int i = Mth.clamp(Runtime.getRuntime().availableProcessors() - 1, 1, getMaxThreads()); -+ private static ExecutorService makeExecutor(String s, int priorityModifier) { // Paper - Perf: add priority ++ private static TracingExecutor makeExecutor(String s, final int priorityModifier) { // Paper - Perf: add priority + // Paper start - Perf: use simpler thread pool that allows 1 thread and reduce worldgen thread worker count for low core count CPUs + int cpus = Runtime.getRuntime().availableProcessors() / 2; + int i; @@ -70,32 +70,34 @@ index 54562fa04d14a937451ea7aa9d80194f2c31b471..4cf88f6d815d60cfbf8e4ecf9d96d0cf + } + i = Math.min(8, i); + i = Integer.getInteger("Paper.WorkerThreadCount", i); ++ ExecutorService executorService; if (i <= 0) { executorService = MoreExecutors.newDirectExecutorService(); } else { - AtomicInteger atomicInteger = new AtomicInteger(1); - executorService = new ForkJoinPool(i, pool -> { -- ForkJoinWorkerThread forkJoinWorkerThread = new ForkJoinWorkerThread(pool) { +- final String string2 = "Worker-" + name + "-" + atomicInteger.getAndIncrement(); + executorService = new java.util.concurrent.ThreadPoolExecutor(i, i,0L, TimeUnit.MILLISECONDS, new java.util.concurrent.LinkedBlockingQueue<>(), target -> new io.papermc.paper.util.ServerWorkerThread(target, s, priorityModifier)); + } -+ /* ++ /* final String string2 = "Worker-" + name + "-" + atomicInteger.getAndIncrement(); + ForkJoinWorkerThread forkJoinWorkerThread = new ForkJoinWorkerThread(pool) { @Override - protected void onTermination(Throwable throwable) { - if (throwable != null) { -@@ -184,6 +196,7 @@ public class Util { + protected void onStart() { +@@ -193,7 +206,7 @@ public class Util { + forkJoinWorkerThread.setName(string2); return forkJoinWorkerThread; }, Util::onThreadException, true); - } -+ }*/ // Paper end - Perf: use simpler thread pool +- } ++ }*/ - return executorService; + return new TracingExecutor(executorService); } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 2d5ae71c143556a938f078d2fb84cab7bd4f789b..f3f3f80f14bc1df13b80033aa143fcccab6f3a31 100644 +index cc15ec47155ee16377a65c9f56a62339dc0a129d..a35e1a741f042d7ac8a21ef24f04fbef96e87825 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -322,6 +322,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { MinecraftServer.LOGGER.error("Uncaught exception in server thread", throwable); }); diff --git a/patches/unapplied/server/0262-Optimize-World-Time-Updates.patch b/patches/server/0261-Optimize-World-Time-Updates.patch similarity index 89% rename from patches/unapplied/server/0262-Optimize-World-Time-Updates.patch rename to patches/server/0261-Optimize-World-Time-Updates.patch index ab47d03d570e..2854e7e919e2 100644 --- a/patches/unapplied/server/0262-Optimize-World-Time-Updates.patch +++ b/patches/server/0261-Optimize-World-Time-Updates.patch @@ -8,17 +8,17 @@ 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 f3f3f80f14bc1df13b80033aa143fcccab6f3a31..699191356a9d873fa6bbe04ea3e5db91eb2db41d 100644 +index a35e1a741f042d7ac8a21ef24f04fbef96e87825..b2b41148b4bfdbdfb1f717e8aabaa7fa3c99e737 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1560,12 +1560,24 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop= worldHeight) { + } else if (pos.getY() > worldHeight) { this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos))); -@@ -307,10 +314,12 @@ public class ServerPlayerGameMode { +@@ -305,10 +312,12 @@ public class ServerPlayerGameMode { this.debugLogging(pos, true, sequence, "stopped destroying"); } else if (action == ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK) { this.isDestroyingBlock = false; @@ -59,10 +59,10 @@ index a5b0efd6142075ca1ecb604afbc1d0162199e7a4..da9e864520150acd8027545672aa476b this.level.destroyBlockProgress(this.player.getId(), pos, -1); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 6cf68d7173bc23c39261856f11cbd42de387bd60..4942aa857ecc5762c9b0b1662eefaeae4daab80d 100644 +index 825e181edc612daa2deaee2977d82a0d048720e7..5b5c5864fa1ad96946b0892998284fab26e54095 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1595,6 +1595,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1599,6 +1599,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl case START_DESTROY_BLOCK: case ABORT_DESTROY_BLOCK: case STOP_DESTROY_BLOCK: @@ -72,6 +72,6 @@ index 6cf68d7173bc23c39261856f11cbd42de387bd60..4942aa857ecc5762c9b0b1662eefaeae + return; + } + // Paper end - Don't allow digging into unloaded chunks - this.player.gameMode.handleBlockBreakAction(blockposition, packetplayinblockdig_enumplayerdigtype, packet.getDirection(), this.player.level().getMaxBuildHeight(), packet.getSequence()); + this.player.gameMode.handleBlockBreakAction(blockposition, packetplayinblockdig_enumplayerdigtype, packet.getDirection(), this.player.level().getMaxY(), packet.getSequence()); this.player.connection.ackBlockChangesUpTo(packet.getSequence()); return; diff --git a/patches/unapplied/server/0266-Make-the-default-permission-message-configurable.patch b/patches/server/0265-Make-the-default-permission-message-configurable.patch similarity index 92% rename from patches/unapplied/server/0266-Make-the-default-permission-message-configurable.patch rename to patches/server/0265-Make-the-default-permission-message-configurable.patch index a1ea906d4dcb..9705f52a0b2b 100644 --- a/patches/unapplied/server/0266-Make-the-default-permission-message-configurable.patch +++ b/patches/server/0265-Make-the-default-permission-message-configurable.patch @@ -18,10 +18,10 @@ index 5b070d158760789bbcaa984426a55d20767abe4a..e1820a339452cd3388dd7cbb928c5f58 } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 954b3725d4f702f284cd8712305a3f97fb90b9c1..7407d9f3480e0e44be44c84831864e511dfdebc2 100644 +index d7e944c9f688221958bdd78913ddc649b21d714e..cd60f4db64b709c5ae23cafa45b8c0422e6c1c85 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2874,6 +2874,16 @@ public final class CraftServer implements Server { +@@ -2891,6 +2891,16 @@ public final class CraftServer implements Server { return io.papermc.paper.configuration.GlobalConfiguration.get().commands.suggestPlayerNamesWhenNullTabCompletions; } diff --git a/patches/unapplied/server/0267-force-entity-dismount-during-teleportation.patch b/patches/server/0266-force-entity-dismount-during-teleportation.patch similarity index 88% rename from patches/unapplied/server/0267-force-entity-dismount-during-teleportation.patch rename to patches/server/0266-force-entity-dismount-during-teleportation.patch index a91a738571ab..4db1978c1876 100644 --- a/patches/unapplied/server/0267-force-entity-dismount-during-teleportation.patch +++ b/patches/server/0266-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 7cca5c778f9d20cfa6cb543c9afcf74779aaa355..c2571855ca6a8ecd144b8fbb97d601d1808e8d61 100644 +index cef054ba95ed7d2b0e2ee575edae3e94b77f58b6..8d958ac09bd9484d879eee6acb6aaea20f4f8339 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -2522,9 +2522,15 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2826,9 +2826,15 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { @Override public void stopRiding() { @@ -41,10 +41,10 @@ index 7cca5c778f9d20cfa6cb543c9afcf74779aaa355..c2571855ca6a8ecd144b8fbb97d601d1 Iterator iterator = entityliving.getActiveEffects().iterator(); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 7fd1a75ba0068ee3ca6c29a550a9a1b33c5cacc5..f330ddca00ed11bf76ae825820423b94920013b9 100644 +index 79a3d586ddf404c449b7c0aa1996e9b9897b2383..5d551a50e1043e369ebf3ddfe181be1e24cfd068 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -2704,17 +2704,28 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2821,17 +2821,28 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public void removeVehicle() { @@ -75,7 +75,7 @@ index 7fd1a75ba0068ee3ca6c29a550a9a1b33c5cacc5..f330ddca00ed11bf76ae825820423b94 } protected void addPassenger(Entity passenger) { -@@ -2739,7 +2750,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2856,7 +2867,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } } @@ -87,7 +87,7 @@ index 7fd1a75ba0068ee3ca6c29a550a9a1b33c5cacc5..f330ddca00ed11bf76ae825820423b94 if (entity.getVehicle() == this) { throw new IllegalStateException("Use x.stopRiding(y), not y.removePassenger(x)"); } else { -@@ -2749,7 +2763,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2866,7 +2880,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess if (this.getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity) { VehicleExitEvent event = new VehicleExitEvent( (Vehicle) this.getBukkitEntity(), @@ -96,7 +96,7 @@ index 7fd1a75ba0068ee3ca6c29a550a9a1b33c5cacc5..f330ddca00ed11bf76ae825820423b94 ); // Suppress during worldgen if (this.valid) { -@@ -2762,7 +2776,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2879,7 +2893,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } } @@ -106,10 +106,10 @@ index 7fd1a75ba0068ee3ca6c29a550a9a1b33c5cacc5..f330ddca00ed11bf76ae825820423b94 if (this.valid) { Bukkit.getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 689aaf4ceedc598fe71db726215cceae6cc97296..fad0445628499ac14cd9d8ab7f618c490885e798 100644 +index b87b59a2ead87b6bda8a8c5bcfd63b128c88f626..34f66931dec00809ed58569e24431762a1acd56f 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3619,9 +3619,15 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3758,9 +3758,15 @@ public abstract class LivingEntity extends Entity implements Attackable { @Override public void stopRiding() { @@ -127,10 +127,10 @@ index 689aaf4ceedc598fe71db726215cceae6cc97296..fad0445628499ac14cd9d8ab7f618c49 this.dismountVehicle(entity); } diff --git a/src/main/java/net/minecraft/world/entity/monster/Shulker.java b/src/main/java/net/minecraft/world/entity/monster/Shulker.java -index 882236c8ebad90ed2adc873de4dda3b7f3f869d9..632b74e84d6ee58da8806e30b75e16fb864afa64 100644 +index 04e973430bf5706d5264423c24d73b903bc3f0aa..dc1870baf172982ebb34eccd4ee79497f48f8050 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Shulker.java +++ b/src/main/java/net/minecraft/world/entity/monster/Shulker.java -@@ -288,7 +288,13 @@ public class Shulker extends AbstractGolem implements VariantHolder type, Level world) { super(type, world); -@@ -267,6 +268,12 @@ public class Zombie extends Monster { +@@ -265,6 +266,12 @@ public class Zombie extends Monster { super.aiStep(); } @@ -31,7 +31,7 @@ index d97c3c139f10a45febc0cfb1057ff6e33266228e..d981f8679149669f6ca4ea950d744149 public void startUnderWaterConversion(int ticksUntilWaterConversion) { this.lastTick = MinecraftServer.currentTick; // CraftBukkit this.conversionTime = ticksUntilWaterConversion; -@@ -296,9 +303,15 @@ public class Zombie extends Monster { +@@ -316,9 +323,15 @@ public class Zombie extends Monster { } public boolean isSunSensitive() { @@ -46,9 +46,9 @@ index d97c3c139f10a45febc0cfb1057ff6e33266228e..d981f8679149669f6ca4ea950d744149 + // Paper end - Add more Zombie API + @Override - public boolean hurt(DamageSource source, float amount) { - if (!super.hurt(source, amount)) { -@@ -417,6 +430,7 @@ public class Zombie extends Monster { + public boolean hurtServer(ServerLevel world, DamageSource source, float amount) { + if (!super.hurtServer(world, source, amount)) { +@@ -447,6 +460,7 @@ public class Zombie extends Monster { nbt.putBoolean("CanBreakDoors", this.canBreakDoors()); nbt.putInt("InWaterTime", this.isInWater() ? this.inWaterTime : -1); nbt.putInt("DrownedConversionTime", this.isUnderWaterConverting() ? this.conversionTime : -1); @@ -56,7 +56,7 @@ index d97c3c139f10a45febc0cfb1057ff6e33266228e..d981f8679149669f6ca4ea950d744149 } @Override -@@ -428,6 +442,11 @@ public class Zombie extends Monster { +@@ -458,6 +472,11 @@ public class Zombie extends Monster { if (nbt.contains("DrownedConversionTime", 99) && nbt.getInt("DrownedConversionTime") > -1) { this.startUnderWaterConversion(nbt.getInt("DrownedConversionTime")); } diff --git a/patches/unapplied/server/0269-Book-size-limits.patch b/patches/server/0268-Book-size-limits.patch similarity index 65% rename from patches/unapplied/server/0269-Book-size-limits.patch rename to patches/server/0268-Book-size-limits.patch index 964cf927a74f..73f2ff470b65 100644 --- a/patches/unapplied/server/0269-Book-size-limits.patch +++ b/patches/server/0268-Book-size-limits.patch @@ -5,27 +5,11 @@ Subject: [PATCH] Book size limits Puts some limits on the size of books. -diff --git a/src/main/java/net/minecraft/network/protocol/game/ServerboundEditBookPacket.java b/src/main/java/net/minecraft/network/protocol/game/ServerboundEditBookPacket.java -index ed61767a64cdce37dc7c226ebd0d693a60de24a9..f634a830a2b58a419e84f969bd53eeae4f4513bb 100644 ---- a/src/main/java/net/minecraft/network/protocol/game/ServerboundEditBookPacket.java -+++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundEditBookPacket.java -@@ -16,9 +16,9 @@ public record ServerboundEditBookPacket(int slot, List pages, Optional STREAM_CODEC = StreamCodec.composite( - ByteBufCodecs.VAR_INT, - ServerboundEditBookPacket::slot, -- ByteBufCodecs.stringUtf8(8192).apply(ByteBufCodecs.list(200)), -+ ByteBufCodecs.stringUtf8(net.minecraft.world.item.component.WritableBookContent.PAGE_EDIT_LENGTH).apply(ByteBufCodecs.list(net.minecraft.world.item.component.WritableBookContent.MAX_PAGES)), // Paper - limit books - ServerboundEditBookPacket::pages, -- ByteBufCodecs.stringUtf8(128).apply(ByteBufCodecs::optional), -+ ByteBufCodecs.stringUtf8(net.minecraft.world.item.component.WrittenBookContent.TITLE_MAX_LENGTH).apply(ByteBufCodecs::optional), // Paper - limit books - ServerboundEditBookPacket::title, - ServerboundEditBookPacket::new - ); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 4942aa857ecc5762c9b0b1662eefaeae4daab80d..577f0e290f66afd2ded18714fb8b5f62a7a9aa71 100644 +index 5b5c5864fa1ad96946b0892998284fab26e54095..9c04eb00c80a343502ece3001a6b21382d011d30 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1043,6 +1043,44 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1049,6 +1049,44 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleEditBook(ServerboundEditBookPacket packet) { diff --git a/patches/unapplied/server/0270-Add-PlayerConnectionCloseEvent.patch b/patches/server/0269-Add-PlayerConnectionCloseEvent.patch similarity index 98% rename from patches/unapplied/server/0270-Add-PlayerConnectionCloseEvent.patch rename to patches/server/0269-Add-PlayerConnectionCloseEvent.patch index fd1a1d334b90..30540debeaa6 100644 --- a/patches/unapplied/server/0270-Add-PlayerConnectionCloseEvent.patch +++ b/patches/server/0269-Add-PlayerConnectionCloseEvent.patch @@ -69,7 +69,7 @@ index c45b8b2c89ffec7bd6a6875963c61f11185d3ee1..38947f40864f3661df2eb4baa0aef574 } } diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 636b8aef2348fa4cfe63a9b7d77a64b14dc7a42c..de25b9ea8aa4b7d6fd3fed12cdd16be9ddfcbfff 100644 +index bab8c53041afb9606db55923e5466eab25640226..fd9e6781a18d41ca3982788711749d11575566d0 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -86,7 +86,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, diff --git a/patches/unapplied/server/0271-Replace-OfflinePlayer-getLastPlayed.patch b/patches/server/0270-Replace-OfflinePlayer-getLastPlayed.patch similarity index 89% rename from patches/unapplied/server/0271-Replace-OfflinePlayer-getLastPlayed.patch rename to patches/server/0270-Replace-OfflinePlayer-getLastPlayed.patch index be356006816b..5b71e0546e1f 100644 --- a/patches/unapplied/server/0271-Replace-OfflinePlayer-getLastPlayed.patch +++ b/patches/server/0270-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 c2571855ca6a8ecd144b8fbb97d601d1808e8d61..bd130d3a4d0cfe431be627c3f4d85bb394fe099b 100644 +index 8d958ac09bd9484d879eee6acb6aaea20f4f8339..3e0ddfe11d74ce47a023837b2ee472f0bc4c48c3 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -269,6 +269,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -296,6 +296,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { private int containerCounter; public boolean wonGame; private int containerUpdateDelay; // Paper - Configurable container update tick rate @@ -28,10 +28,10 @@ index c2571855ca6a8ecd144b8fbb97d601d1808e8d61..bd130d3a4d0cfe431be627c3f4d85bb3 public boolean queueHealthUpdatePacket; 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 5fc76fd70f98fe874b38d8da08017fdadbd115e5..cdd1d8222ad1796abd0858b9ed0e2ddc9be83c93 100644 +index 9294ab23940cb2a822ba760052e3ad369abdfed6..d013e72511d1763a55e5e0837b682d02f87aff63 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -182,6 +182,7 @@ public abstract class PlayerList { +@@ -183,6 +183,7 @@ public abstract class PlayerList { public void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie clientData) { player.isRealPlayer = true; // Paper @@ -40,7 +40,7 @@ index 5fc76fd70f98fe874b38d8da08017fdadbd115e5..cdd1d8222ad1796abd0858b9ed0e2ddc GameProfileCache usercache = this.server.getProfileCache(); // Optional optional; // CraftBukkit - decompile error diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java -index 461656e1cb095243bfe7a9ee2906e5b00574ae78..411b280ac3e27e72091db813c0c9b69b62df6097 100644 +index f6b2ca92fd3510a76cbf56d0ea55aa6caaf12ba1..e0d342a0ddd140b342f7af138c71596c6d718788 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java @@ -262,6 +262,61 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa @@ -106,10 +106,10 @@ index 461656e1cb095243bfe7a9ee2906e5b00574ae78..411b280ac3e27e72091db813c0c9b69b 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 004ac565d4124f6059d530034cf0c9a28f0be467..6a3bf3f34ff36e0b11bb3c250074f672b1e81b4f 100644 +index c132b4d4d871eaeadec78921a99ba7066c59ddda..da5fbeaea4bbb4fd3cac2eb4ff31bd3849754280 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -210,6 +210,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -211,6 +211,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { private BorderChangeListener clientWorldBorderListener = this.createWorldBorderListener(); public org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus; // Paper - more resource pack API private static final boolean DISABLE_CHANNEL_LIMIT = System.getProperty("paper.disableChannelLimit") != null; // Paper - add a flag to disable the channel limit @@ -117,7 +117,7 @@ index 004ac565d4124f6059d530034cf0c9a28f0be467..6a3bf3f34ff36e0b11bb3c250074f672 public CraftPlayer(CraftServer server, ServerPlayer entity) { super(server, entity); -@@ -2049,6 +2050,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2062,6 +2063,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.firstPlayed = firstPlayed; } @@ -136,7 +136,7 @@ index 004ac565d4124f6059d530034cf0c9a28f0be467..6a3bf3f34ff36e0b11bb3c250074f672 public void readExtraData(CompoundTag nbttagcompound) { this.hasPlayedBefore = true; if (nbttagcompound.contains("bukkit")) { -@@ -2071,6 +2084,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2084,6 +2097,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } public void setExtraData(CompoundTag nbttagcompound) { @@ -145,7 +145,7 @@ index 004ac565d4124f6059d530034cf0c9a28f0be467..6a3bf3f34ff36e0b11bb3c250074f672 if (!nbttagcompound.contains("bukkit")) { nbttagcompound.put("bukkit", new CompoundTag()); } -@@ -2085,6 +2100,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2098,6 +2113,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { data.putLong("firstPlayed", this.getFirstPlayed()); data.putLong("lastPlayed", System.currentTimeMillis()); data.putString("lastKnownName", handle.getScoreboardName()); diff --git a/patches/unapplied/server/0272-Workaround-for-vehicle-tracking-issue-on-disconnect.patch b/patches/server/0271-Workaround-for-vehicle-tracking-issue-on-disconnect.patch similarity index 86% rename from patches/unapplied/server/0272-Workaround-for-vehicle-tracking-issue-on-disconnect.patch rename to patches/server/0271-Workaround-for-vehicle-tracking-issue-on-disconnect.patch index a8477b17860f..8be3eeac381a 100644 --- a/patches/unapplied/server/0272-Workaround-for-vehicle-tracking-issue-on-disconnect.patch +++ b/patches/server/0271-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 bd130d3a4d0cfe431be627c3f4d85bb394fe099b..ad2b8ea068469f2b0597c0e0436ad3c94dcb62ea 100644 +index 3e0ddfe11d74ce47a023837b2ee472f0bc4c48c3..9cfd0b457f6c462921667b9439a7b3e32d019758 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1833,6 +1833,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2078,6 +2078,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { public void disconnect() { this.disconnected = true; this.ejectPassengers(); diff --git a/patches/unapplied/server/0273-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch b/patches/server/0272-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch similarity index 87% rename from patches/unapplied/server/0273-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch rename to patches/server/0272-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch index 4869ad5e17f1..2f17f2f3abba 100644 --- a/patches/unapplied/server/0273-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch +++ b/patches/server/0272-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch @@ -8,10 +8,10 @@ We just add a check to ensure that the CraftPlayer's handle is a ServerPlayer diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 6a3bf3f34ff36e0b11bb3c250074f672b1e81b4f..d0af4b838bd43ef2388e918ac14e7acec71b63ef 100644 +index da5fbeaea4bbb4fd3cac2eb4ff31bd3849754280..df99bc022b25e61dc8827c67fb4eb2909bba097f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -224,8 +224,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -225,8 +225,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void remove() { diff --git a/patches/unapplied/server/0274-BlockDestroyEvent.patch b/patches/server/0273-BlockDestroyEvent.patch similarity index 94% rename from patches/unapplied/server/0274-BlockDestroyEvent.patch rename to patches/server/0273-BlockDestroyEvent.patch index c156645f0255..90ba6f9a119c 100644 --- a/patches/unapplied/server/0274-BlockDestroyEvent.patch +++ b/patches/server/0273-BlockDestroyEvent.patch @@ -11,10 +11,10 @@ floating in the air. This can replace many uses of BlockPhysicsEvent diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 5929b450a26e7c3cf63de3dc1d0e67cb781b24c7..4c4449f7dee8695a362f83b9356e5754244fff18 100644 +index cf422de89f0ed81e7c9759328e28ca6b190283ef..70b6d75daa9a9305041a565808f0dae84696d10f 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -25,6 +25,7 @@ import net.minecraft.core.registries.Registries; +@@ -24,6 +24,7 @@ import net.minecraft.core.registries.Registries; import net.minecraft.network.protocol.Packet; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; diff --git a/patches/unapplied/server/0275-Async-command-map-building.patch b/patches/server/0274-Async-command-map-building.patch similarity index 90% rename from patches/unapplied/server/0275-Async-command-map-building.patch rename to patches/server/0274-Async-command-map-building.patch index b202de9d2432..3c35f0e2ff5d 100644 --- a/patches/unapplied/server/0275-Async-command-map-building.patch +++ b/patches/server/0274-Async-command-map-building.patch @@ -9,10 +9,10 @@ commands if the server is restarting. Using the default async pool caused issues due to the shutdown logic generally being much later. diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index 72756ef14b8ec8afd80313b9f6aaf76722cb18cf..a05aea8561ac102476ee1b3068942b095950a86a 100644 +index 2008fd542eaf1c2fac776ae1751c227a3b6dde4b..e812cc865baaa1ee03872f7969ee98600b82483b 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -450,6 +450,24 @@ public class Commands { +@@ -455,6 +455,24 @@ public class Commands { if ( org.spigotmc.SpigotConfig.tabComplete < 0 ) return; // Spigot // CraftBukkit start // Register Vanilla commands into builtRoot as before @@ -37,7 +37,7 @@ index 72756ef14b8ec8afd80313b9f6aaf76722cb18cf..a05aea8561ac102476ee1b3068942b09 Map, CommandNode> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues RootCommandNode vanillaRoot = new RootCommandNode(); -@@ -467,7 +485,14 @@ public class Commands { +@@ -472,7 +490,14 @@ public class Commands { for (CommandNode node : rootcommandnode.getChildren()) { bukkit.add(node.getName()); } @@ -53,10 +53,10 @@ index 72756ef14b8ec8afd80313b9f6aaf76722cb18cf..a05aea8561ac102476ee1b3068942b09 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 699191356a9d873fa6bbe04ea3e5db91eb2db41d..8ecfd7a3daa99dabe796d28d27790fb8b45c628b 100644 +index b2b41148b4bfdbdfb1f717e8aabaa7fa3c99e737..8030c00bc3783582aafbda934bb653b0b21d1fb9 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -930,6 +930,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { runSync(player, bukkit, rootcommandnode); }); -@@ -493,6 +494,7 @@ public class Commands { +@@ -498,6 +499,7 @@ public class Commands { private void runSync(ServerPlayer player, Collection bukkit, RootCommandNode rootcommandnode) { // Paper end - Perf: Async command map building @@ -106,7 +106,7 @@ index a05aea8561ac102476ee1b3068942b095950a86a..e25fc35716aff1d1805884b18f67b0eb PlayerCommandSendEvent event = new PlayerCommandSendEvent(player.getBukkitEntity(), new LinkedHashSet<>(bukkit)); event.getPlayer().getServer().getPluginManager().callEvent(event); -@@ -511,6 +513,11 @@ public class Commands { +@@ -516,6 +518,11 @@ public class Commands { while (iterator.hasNext()) { CommandNode commandnode2 = (CommandNode) iterator.next(); @@ -119,10 +119,10 @@ index a05aea8561ac102476ee1b3068942b095950a86a..e25fc35716aff1d1805884b18f67b0eb if (commandnode2.canUse(source)) { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 577f0e290f66afd2ded18714fb8b5f62a7a9aa71..e786d4b940a6fcd6d5ce66c5e13f52ff001b8367 100644 +index 9c04eb00c80a343502ece3001a6b21382d011d30..0552007b5f12055b72b01ddeef17c30236642eaf 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -769,19 +769,34 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -773,19 +773,34 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl builder.suggest(completion.suggestion(), PaperAdventure.asVanilla(completion.tooltip())); } } From 5e262c16917bde3168c601024ce21a2076bc8018 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Wed, 23 Oct 2024 15:02:51 +0200 Subject: [PATCH 016/119] 298 --- patches/server/0005-Paper-config-files.patch | 12 +- .../0276-Limit-Client-Sign-length-more.patch} | 6 +- ...ggleEvent-when-whitelist-is-toggled.patch} | 4 +- ...d-additions-to-the-spawn-reason-API.patch} | 148 ++++++++++++------ .../0279-Fire-event-on-GS4-query.patch} | 0 .../0280-Add-PlayerPostRespawnEvent.patch} | 32 ++-- .../0281-Server-Tick-Events.patch} | 12 +- ...282-PlayerDeathEvent-getItemsToKeep.patch} | 8 +- ...ptimize-Captured-BlockEntity-Lookup.patch} | 4 +- .../0284-Mob-Spawner-API-Enhancements.patch} | 2 +- ...-to-changed-postToMainThread-method.patch} | 4 +- ...-item-frames-are-modified-MC-123450.patch} | 4 +- ...0287-Implement-CraftBlockSoundGroup.patch} | 2 +- ...88-Expose-the-internal-current-tick.patch} | 4 +- ...te-location-if-we-failed-to-read-it.patch} | 2 +- ...l-Spawned-mobs-towards-natural-spaw.patch} | 4 +- ...urable-projectile-relative-velocity.patch} | 6 +- .../0292-offset-item-frame-ticking.patch} | 4 +- ...event-consuming-the-wrong-itemstack.patch} | 10 +- ...4-Dont-send-unnecessary-sign-update.patch} | 4 +- ...-option-to-disable-pillager-patrols.patch} | 2 +- ...k-loads-when-villagers-try-to-find-.patch} | 0 .../0297-Duplicate-UUID-Resolve-Option.patch} | 4 +- ...ayerDeathEvent-shouldDropExperience.patch} | 8 +- ...5656-Fix-Follow-Range-Initial-Target.patch | 50 ------ 25 files changed, 172 insertions(+), 164 deletions(-) rename patches/{unapplied/server/0278-Limit-Client-Sign-length-more.patch => server/0276-Limit-Client-Sign-length-more.patch} (92%) rename patches/{unapplied/server/0279-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch => server/0277-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch} (83%) rename patches/{unapplied/server/0280-Fixes-and-additions-to-the-spawn-reason-API.patch => server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch} (59%) rename patches/{unapplied/server/0281-Fire-event-on-GS4-query.patch => server/0279-Fire-event-on-GS4-query.patch} (100%) rename patches/{unapplied/server/0282-Add-PlayerPostRespawnEvent.patch => server/0280-Add-PlayerPostRespawnEvent.patch} (58%) rename patches/{unapplied/server/0283-Server-Tick-Events.patch => server/0281-Server-Tick-Events.patch} (78%) rename patches/{unapplied/server/0284-PlayerDeathEvent-getItemsToKeep.patch => server/0282-PlayerDeathEvent-getItemsToKeep.patch} (89%) rename patches/{unapplied/server/0285-Optimize-Captured-BlockEntity-Lookup.patch => server/0283-Optimize-Captured-BlockEntity-Lookup.patch} (90%) rename patches/{unapplied/server/0286-Mob-Spawner-API-Enhancements.patch => server/0284-Mob-Spawner-API-Enhancements.patch} (99%) rename patches/{unapplied/server/0287-Fix-CB-call-to-changed-postToMainThread-method.patch => server/0285-Fix-CB-call-to-changed-postToMainThread-method.patch} (85%) rename patches/{unapplied/server/0288-Fix-sounds-when-item-frames-are-modified-MC-123450.patch => server/0286-Fix-sounds-when-item-frames-are-modified-MC-123450.patch} (85%) rename patches/{unapplied/server/0289-Implement-CraftBlockSoundGroup.patch => server/0287-Implement-CraftBlockSoundGroup.patch} (96%) rename patches/{unapplied/server/0290-Expose-the-internal-current-tick.patch => server/0288-Expose-the-internal-current-tick.patch} (82%) rename patches/{unapplied/server/0291-Show-blockstate-location-if-we-failed-to-read-it.patch => server/0289-Show-blockstate-location-if-we-failed-to-read-it.patch} (94%) rename patches/{unapplied/server/0292-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch => server/0290-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch} (91%) rename patches/{unapplied/server/0293-Configurable-projectile-relative-velocity.patch => server/0291-Configurable-projectile-relative-velocity.patch} (85%) rename patches/{unapplied/server/0294-offset-item-frame-ticking.patch => server/0292-offset-item-frame-ticking.patch} (85%) rename patches/{unapplied/server/0295-Prevent-consuming-the-wrong-itemstack.patch => server/0293-Prevent-consuming-the-wrong-itemstack.patch} (86%) rename patches/{unapplied/server/0296-Dont-send-unnecessary-sign-update.patch => server/0294-Dont-send-unnecessary-sign-update.patch} (89%) rename patches/{unapplied/server/0297-Add-option-to-disable-pillager-patrols.patch => server/0295-Add-option-to-disable-pillager-patrols.patch} (91%) rename patches/{unapplied/server/0298-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch => server/0296-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch} (100%) rename patches/{unapplied/server/0300-Duplicate-UUID-Resolve-Option.patch => server/0297-Duplicate-UUID-Resolve-Option.patch} (96%) rename patches/{unapplied/server/0301-PlayerDeathEvent-shouldDropExperience.patch => server/0298-PlayerDeathEvent-shouldDropExperience.patch} (69%) delete mode 100644 patches/unapplied/server/0299-MC-145656-Fix-Follow-Range-Initial-Target.patch diff --git a/patches/server/0005-Paper-config-files.patch b/patches/server/0005-Paper-config-files.patch index e7ff1d0a2216..eb69aa8d12b0 100644 --- a/patches/server/0005-Paper-config-files.patch +++ b/patches/server/0005-Paper-config-files.patch @@ -1335,10 +1335,10 @@ index 0000000000000000000000000000000000000000..1029b6de6f36b08bf634b4056ef57013 +} diff --git a/src/main/java/io/papermc/paper/configuration/RemovedConfigurations.java b/src/main/java/io/papermc/paper/configuration/RemovedConfigurations.java new file mode 100644 -index 0000000000000000000000000000000000000000..990d1bb46e0f9719f4e9af928d80ac6f8dff23b5 +index 0000000000000000000000000000000000000000..279b24c689b9979884b65df7eb1f059024f0feac --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/RemovedConfigurations.java -@@ -0,0 +1,82 @@ +@@ -0,0 +1,83 @@ +package io.papermc.paper.configuration; + +import org.spongepowered.configurate.NodePath; @@ -1393,7 +1393,8 @@ index 0000000000000000000000000000000000000000..990d1bb46e0f9719f4e9af928d80ac6f + path("entities", "spawning", "despawn-ranges", "soft"), + path("entities", "spawning", "despawn-ranges", "hard"), + path("fixes", "fix-curing-zombie-villager-discount-exploit"), -+ path("entities", "mob-effects", "undead-immune-to-certain-effects") ++ path("entities", "mob-effects", "undead-immune-to-certain-effects"), ++ path("entities", "entities-target-with-follow-range") + }; + // spawn.keep-spawn-loaded and spawn.keep-spawn-loaded-range are no longer used, but kept + // in the world default config for compatibility with old worlds being migrated to use the gamerule @@ -1423,10 +1424,10 @@ index 0000000000000000000000000000000000000000..990d1bb46e0f9719f4e9af928d80ac6f +} diff --git a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java new file mode 100644 -index 0000000000000000000000000000000000000000..fd3b1c10695634f65c7291016bf671c084bc4d57 +index 0000000000000000000000000000000000000000..a81a332ffb80e67d7f886295099b5cd2ae8994c5 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java -@@ -0,0 +1,581 @@ +@@ -0,0 +1,580 @@ +package io.papermc.paper.configuration; + +import com.google.common.collect.HashBasedTable; @@ -1568,7 +1569,6 @@ index 0000000000000000000000000000000000000000..fd3b1c10695634f65c7291016bf671c0 + public Entities entities; + + public class Entities extends ConfigurationPart { -+ public boolean entitiesTargetWithFollowRange = false; + public MobEffects mobEffects; + + public class MobEffects extends ConfigurationPart { diff --git a/patches/unapplied/server/0278-Limit-Client-Sign-length-more.patch b/patches/server/0276-Limit-Client-Sign-length-more.patch similarity index 92% rename from patches/unapplied/server/0278-Limit-Client-Sign-length-more.patch rename to patches/server/0276-Limit-Client-Sign-length-more.patch index a5c3397ebe62..082d51bacd8d 100644 --- a/patches/unapplied/server/0278-Limit-Client-Sign-length-more.patch +++ b/patches/server/0276-Limit-Client-Sign-length-more.patch @@ -22,10 +22,10 @@ it only impacts data sent from the client. Set -DPaper.maxSignLength=XX to change limit or -1 to disable diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index e786d4b940a6fcd6d5ce66c5e13f52ff001b8367..0ed2d0f5ec9d107e8049aa9e803479ffd341639f 100644 +index 0552007b5f12055b72b01ddeef17c30236642eaf..0b7e47418aa7a9891ee4a070430de6b2599f66e3 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -299,6 +299,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -307,6 +307,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private final MessageSignatureCache messageSignatureCache = MessageSignatureCache.createDefault(); private final FutureChain chatMessageChain; private boolean waitingForSwitchToConfig; @@ -33,7 +33,7 @@ index e786d4b940a6fcd6d5ce66c5e13f52ff001b8367..0ed2d0f5ec9d107e8049aa9e803479ff public ServerGamePacketListenerImpl(MinecraftServer server, Connection connection, ServerPlayer player, CommonListenerCookie clientData) { super(server, connection, clientData, player); // CraftBukkit -@@ -3149,7 +3150,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3197,7 +3198,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleSignUpdate(ServerboundSignUpdatePacket packet) { diff --git a/patches/unapplied/server/0279-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch b/patches/server/0277-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch similarity index 83% rename from patches/unapplied/server/0279-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch rename to patches/server/0277-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch index 36ca904431c7..9ca53b7c59d1 100644 --- a/patches/unapplied/server/0279-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch +++ b/patches/server/0277-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 7f8081446704ea9642275cb2bc139fed174a2f1f..0bac75f111398fd22df978a09dcd4cdc22998894 100644 +index d013e72511d1763a55e5e0837b682d02f87aff63..ceaf7bfbe4bf686780135c5c5dfe75d852fcb6cf 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 { +@@ -1097,6 +1097,7 @@ public abstract class PlayerList { } public void setUsingWhiteList(boolean whitelistEnabled) { diff --git a/patches/unapplied/server/0280-Fixes-and-additions-to-the-spawn-reason-API.patch b/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch similarity index 59% rename from patches/unapplied/server/0280-Fixes-and-additions-to-the-spawn-reason-API.patch rename to patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch index a8fda4a8d70e..6dc2b28b312d 100644 --- a/patches/unapplied/server/0280-Fixes-and-additions-to-the-spawn-reason-API.patch +++ b/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch @@ -14,22 +14,22 @@ Co-authored-by: Jake Potrebic Co-authored-by: Doc diff --git a/src/main/java/net/minecraft/server/commands/SummonCommand.java b/src/main/java/net/minecraft/server/commands/SummonCommand.java -index bf72cf288ade52ee8cc41ca978f368b3ad575951..798999be50d26be357ef3c6d5b9383ce4d1048c1 100644 +index f55832ce841621daab4d3a910650ab6562cefcda..f635da34335cd2901adf975fcd74c5c6f9785836 100644 --- a/src/main/java/net/minecraft/server/commands/SummonCommand.java +++ b/src/main/java/net/minecraft/server/commands/SummonCommand.java @@ -57,6 +57,7 @@ public class SummonCommand { ServerLevel worldserver = source.getLevel(); - Entity entity = EntityType.loadEntityRecursive(nbttagcompound1, worldserver, (entity1) -> { + Entity entity = EntityType.loadEntityRecursive(nbttagcompound1, worldserver, EntitySpawnReason.COMMAND, (entity1) -> { entity1.moveTo(pos.x, pos.y, pos.z, entity1.getYRot(), entity1.getXRot()); + entity1.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.COMMAND; // Paper - Entity#getEntitySpawnReason return entity1; }); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index e9d08662c065d04a67918f0aa2cd4fde5798f2a6..a6a21def1ae0d35fa106da6242c49a0928e4eda5 100644 +index 3f4d3e2f45c2b2228a333076ec1f34228560593e..64c1fd62a865adb1e11edd326a1a5ccdc98f13ed 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1207,6 +1207,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1202,6 +1202,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return true; } // Paper end - extra debug info @@ -37,11 +37,24 @@ index e9d08662c065d04a67918f0aa2cd4fde5798f2a6..a6a21def1ae0d35fa106da6242c49a09 if (entity.isRemoved()) { // WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getKey(entity.getType())); // CraftBukkit return false; +diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java +index 9cfd0b457f6c462921667b9439a7b3e32d019758..62412b37d4f7d37b3fec0966ab700c2ae4d8cada 100644 +--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java ++++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +@@ -716,7 +716,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { + ServerLevel worldserver = (ServerLevel) world; + CompoundTag nbttagcompound = ((CompoundTag) nbt.get()).getCompound("RootVehicle"); + Entity entity = EntityType.loadEntityRecursive(nbttagcompound.getCompound("Entity"), worldserver, EntitySpawnReason.LOAD, (entity1) -> { +- return !worldserver.addWithUUID(entity1) ? null : entity1; ++ return !worldserver.addWithUUID(entity1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity1; // CraftBukkit - decompile error // Paper - Entity#getEntitySpawnReason + }); + + if (entity == null) { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 2f1d075b8dbcf173c51f3e6396ccbc61b64f75df..79203d0e5cdb86d9e2fb22cdaeb8cf3a93e43dcc 100644 +index ceaf7bfbe4bf686780135c5c5dfe75d852fcb6cf..dffc7f0c9c730bc629ee169eca3a7a997c2cc7b1 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -223,6 +223,11 @@ public abstract class PlayerList { +@@ -224,6 +224,11 @@ public abstract class PlayerList { worldserver1 = worldserver; } @@ -53,20 +66,11 @@ index 2f1d075b8dbcf173c51f3e6396ccbc61b64f75df..79203d0e5cdb86d9e2fb22cdaeb8cf3a player.setServerLevel(worldserver1); String s1 = connection.getLoggableAddress(this.server.logIPs()); -@@ -348,7 +353,7 @@ public abstract class PlayerList { - CompoundTag nbttagcompound = ((CompoundTag) optional.get()).getCompound("RootVehicle"); - ServerLevel finalWorldServer = worldserver1; // CraftBukkit - decompile error - Entity entity = EntityType.loadEntityRecursive(nbttagcompound.getCompound("Entity"), worldserver1, (entity1) -> { -- return !finalWorldServer.addWithUUID(entity1) ? null : entity1; // CraftBukkit - decompile error -+ return !finalWorldServer.addWithUUID(entity1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity1; // CraftBukkit - decompile error // Paper - Entity#getEntitySpawnReason - }); - - if (entity != null) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index f330ddca00ed11bf76ae825820423b94920013b9..9d56aff2766b684f0fb20e93d504de1a7a564b11 100644 +index 5d551a50e1043e369ebf3ddfe181be1e24cfd068..463d34e7b54efd503c4879d1386b2439474863dd 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -247,6 +247,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -255,6 +255,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } } // Paper end - Share random for entities to make them more random @@ -74,7 +78,7 @@ index f330ddca00ed11bf76ae825820423b94920013b9..9d56aff2766b684f0fb20e93d504de1a private CraftEntity bukkitEntity; -@@ -2274,6 +2275,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2390,6 +2391,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } nbttagcompound.put("Paper.Origin", this.newDoubleList(origin.getX(), origin.getY(), origin.getZ())); } @@ -84,7 +88,7 @@ index f330ddca00ed11bf76ae825820423b94920013b9..9d56aff2766b684f0fb20e93d504de1a // Save entity's from mob spawner status if (spawnedViaMobSpawner) { nbttagcompound.putBoolean("Paper.FromMobSpawner", true); -@@ -2420,6 +2424,26 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2537,6 +2541,26 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } spawnedViaMobSpawner = nbt.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status @@ -112,36 +116,54 @@ index f330ddca00ed11bf76ae825820423b94920013b9..9d56aff2766b684f0fb20e93d504de1a } catch (Throwable throwable) { diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 69a661f01e43d17262fd2845dde5528416bbe456..c0062c8f83641ff30e79a309c0bb9930ba4b422a 100644 +index 7fb2155b8d320f8871556083aef9ed8e1e91e6e7..ab02f4ca0bb8cd4939f167b410db208e38f7102b 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -366,7 +366,7 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -443,7 +443,7 @@ public class EntityType implements FeatureElement, EntityTypeT @Nullable - public T spawn(ServerLevel world, @Nullable ItemStack stack, @Nullable Player player, BlockPos pos, MobSpawnType spawnReason, boolean alignPosition, boolean invertY) { + public T spawn(ServerLevel world, @Nullable ItemStack stack, @Nullable Player player, BlockPos pos, EntitySpawnReason spawnReason, boolean alignPosition, boolean invertY) { // CraftBukkit start - return this.spawn(world, stack, player, pos, spawnReason, alignPosition, invertY, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); -+ return this.spawn(world, stack, player, pos, spawnReason, alignPosition, invertY, spawnReason == MobSpawnType.DISPENSER ? org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DISPENSE_EGG : org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); // Paper - use correct spawn reason for dispenser spawn eggs ++ return this.spawn(world, stack, player, pos, spawnReason, alignPosition, invertY, spawnReason == EntitySpawnReason.DISPENSER ? org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DISPENSE_EGG : org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); // Paper - use correct spawn reason for dispenser spawn eggs } @Nullable diff --git a/src/main/java/net/minecraft/world/entity/OminousItemSpawner.java b/src/main/java/net/minecraft/world/entity/OminousItemSpawner.java -index 146cbec9e64b6c77759aadd0d0c4e989018e9aef..4c4545b3732d4c08afdb7bc1913169a96e82825c 100644 +index 1fc9f883305e150f4bdf478bf0f43e301460cbf2..7b75dbb79e0d2a92cc10838a6e4da973e69125fb 100644 --- a/src/main/java/net/minecraft/world/entity/OminousItemSpawner.java +++ b/src/main/java/net/minecraft/world/entity/OminousItemSpawner.java -@@ -89,7 +89,7 @@ public class OminousItemSpawner extends Entity { - entity = new ItemEntity(level, this.getX(), this.getY(), this.getZ(), itemStack); - } +@@ -76,7 +76,7 @@ public class OminousItemSpawner extends Entity { + entity = this.spawnProjectile(serverLevel, projectileItem, itemStack); + } else { + entity = new ItemEntity(serverLevel, this.getX(), this.getY(), this.getZ(), itemStack); +- serverLevel.addFreshEntity(entity); ++ serverLevel.addFreshEntity(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.OMINOUS_ITEM_SPAWNER); // Paper - fixes and addition to spawn reason API + } -- level.addFreshEntity(entity); -+ level.addFreshEntity(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.OMINOUS_ITEM_SPAWNER); // Paper - Fixes and additions to the SpawnReason API - level.levelEvent(3021, this.blockPosition(), 1); - level.gameEvent(entity, GameEvent.ENTITY_PLACE, this.position()); - this.setItem(ItemStack.EMPTY); + serverLevel.levelEvent(3021, this.blockPosition(), 1); +@@ -90,7 +90,7 @@ public class OminousItemSpawner extends Entity { + ProjectileItem.DispenseConfig dispenseConfig = item.createDispenseConfig(); + dispenseConfig.overrideDispenseEvent().ifPresent(dispenseEvent -> world.levelEvent(dispenseEvent, this.blockPosition(), 0)); + Direction direction = Direction.DOWN; +- Projectile projectile = Projectile.spawnProjectileUsingShoot( ++ Projectile projectile = Projectile.spawnProjectileUsingShootDelayed( // Paper - fixes and addition to spawn reason API + item.asProjectile(world, this.position(), stack, direction), + world, + stack, +@@ -99,7 +99,7 @@ public class OminousItemSpawner extends Entity { + (double)direction.getStepZ(), + dispenseConfig.power(), + dispenseConfig.uncertainty() +- ); ++ ).spawn(org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.OMINOUS_ITEM_SPAWNER); // Paper - fixes and addition to spawn reason API + projectile.setOwner(this); + return projectile; + } diff --git a/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java b/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java -index 1dade7a4fbdf190661e4431496349444467509cc..3e869620db35d38db39fbeed715b898ef9d2743c 100644 +index 2eecdcbea3d51b1fb6e0c3db0667464a699ca0df..c68ddccd5fbe27f6a62cedbdc2337f1b6e4d3273 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java +++ b/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java -@@ -65,7 +65,7 @@ public class DragonFireball extends AbstractHurtingProjectile { +@@ -64,7 +64,7 @@ public class DragonFireball extends AbstractHurtingProjectile { if (new com.destroystokyo.paper.event.entity.EnderDragonFireballHitEvent((org.bukkit.entity.DragonFireball) this.getBukkitEntity(), list.stream().map(LivingEntity::getBukkitLivingEntity).collect(java.util.stream.Collectors.toList()), (org.bukkit.entity.AreaEffectCloud) entityareaeffectcloud.getBukkitEntity()).callEvent()) { // Paper - EnderDragon Events this.level().levelEvent(2006, this.blockPosition(), this.isSilent() ? -1 : 1); @@ -150,8 +172,44 @@ index 1dade7a4fbdf190661e4431496349444467509cc..3e869620db35d38db39fbeed715b898e } else entityareaeffectcloud.discard(null); // Paper - EnderDragon Events this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause } +diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +index e7fe338572a8bb740d6023c688d8c84ea04a2169..7c8f92b7e5eb66d26e6c46dc2ed86c68dbe97ae9 100644 +--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java ++++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +@@ -214,7 +214,12 @@ public abstract class Projectile extends Entity implements TraceableEntity { + } + + public static T spawnProjectileUsingShoot(T projectile, ServerLevel world, ItemStack projectileStack, double velocityX, double velocityY, double velocityZ, float power, float divergence) { +- return Projectile.spawnProjectile(projectile, world, projectileStack, (iprojectile) -> { ++ // Paper start - fixes and addition to spawn reason API ++ return spawnProjectileUsingShootDelayed(projectile, world, projectileStack, velocityX, velocityY, velocityZ, power, divergence).spawn(); ++ } ++ public static Delayed spawnProjectileUsingShootDelayed(T projectile, ServerLevel world, ItemStack projectileStack, double velocityX, double velocityY, double velocityZ, float power, float divergence) { ++ return Projectile.spawnProjectileDelayed(projectile, world, projectileStack, (iprojectile) -> { ++ // Paper end - fixes and addition to spawn reason API + projectile.shoot(velocityX, velocityY, velocityZ, power, divergence); + }); + } +@@ -241,6 +246,17 @@ public abstract class Projectile extends Entity implements TraceableEntity { + this.attemptSpawn(); + return projectile(); + } ++ ++ public boolean attemptSpawn(final org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { ++ if (!world.addFreshEntity(projectile, reason)) return false; ++ projectile.applyOnProjectileSpawned(this.world, this.projectileStack); ++ return true; ++ } ++ ++ public T spawn(final org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { ++ this.attemptSpawn(reason); ++ return projectile(); ++ } + } + // Paper end - delayed projectile spawning + diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index ee897b8c9462dbb3d7be9a2994753155065ce205..1d0964a7f544735a0213d5c7832c71f53db139a9 100644 +index 261de9ea37d22023da6a306b58b1b62a54dc03da..299137519dba07c8b2cb35437742b5d40eb9e5d2 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java @@ -191,6 +191,7 @@ public abstract class BaseSpawner { @@ -163,10 +221,10 @@ index ee897b8c9462dbb3d7be9a2994753155065ce205..1d0964a7f544735a0213d5c7832c71f5 // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) { diff --git a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java -index 211b7809f099678bc3bd64bd29fd9c4d19e3ab0d..b968129b9a93fdf771caba5f768456070543ba6a 100644 +index 524f94a00f7b76a3847b68f0ab0cf82cc524b01e..aee71779f31def5f1ef7438cf06219d1de7092ec 100644 --- a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java -@@ -111,7 +111,7 @@ public class FrogspawnBlock extends Block { +@@ -121,7 +121,7 @@ public class FrogspawnBlock extends Block { int k = random.nextInt(1, 361); tadpole.moveTo(d, (double)pos.getY() - 0.5, e, (float)k, 0.0F); tadpole.setPersistenceRequired(); @@ -176,10 +234,10 @@ index 211b7809f099678bc3bd64bd29fd9c4d19e3ab0d..b968129b9a93fdf771caba5f76845607 } } diff --git a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java -index 1eda49c9ce8ee009cb08b18f02f59b37c2118628..14a5cd54820243f4ca59857b0d67c1e86457d590 100644 +index fc26713a869d0c1fad1634ef4a6c6282fef5aa31..4f8224841865f956aaa969ab7f543c80b3c24319 100644 --- a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java -@@ -73,7 +73,7 @@ public class SnifferEggBlock extends Block { +@@ -74,7 +74,7 @@ public class SnifferEggBlock extends Block { Vec3 vec3 = pos.getCenter(); sniffer.setBaby(true); sniffer.moveTo(vec3.x(), vec3.y(), vec3.z(), Mth.wrapDegrees(world.random.nextFloat() * 360.0F), 0.0F); @@ -189,20 +247,20 @@ index 1eda49c9ce8ee009cb08b18f02f59b37c2118628..14a5cd54820243f4ca59857b0d67c1e8 } } diff --git a/src/main/java/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java -index dbc0b69603dcffbf3d41d79719aa0f2b7da4a131..dd86f5ec5b2051aeea4e19ff97146362b1e8d019 100644 +index dc6b18527222d23e9719e2210b684a1aa797c70d..ea53c25c350c0cf8e0360ea409cd1f69a62054a8 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java @@ -189,7 +189,7 @@ public class SculkShriekerBlockEntity extends BlockEntity implements GameEventLi private boolean trySummonWarden(ServerLevel world) { return this.warningLevel >= 4 -- && SpawnUtil.trySpawnMob(EntityType.WARDEN, MobSpawnType.TRIGGERED, world, this.getBlockPos(), 20, 5, 6, SpawnUtil.Strategy.ON_TOP_OF_COLLIDER) -+ && SpawnUtil.trySpawnMob(EntityType.WARDEN, MobSpawnType.TRIGGERED, world, this.getBlockPos(), 20, 5, 6, SpawnUtil.Strategy.ON_TOP_OF_COLLIDER, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL, null) // Paper - Entity#getEntitySpawnReason +- && SpawnUtil.trySpawnMob(EntityType.WARDEN, EntitySpawnReason.TRIGGERED, world, this.getBlockPos(), 20, 5, 6, SpawnUtil.Strategy.ON_TOP_OF_COLLIDER) ++ && SpawnUtil.trySpawnMob(EntityType.WARDEN, EntitySpawnReason.TRIGGERED, world, this.getBlockPos(), 20, 5, 6, SpawnUtil.Strategy.ON_TOP_OF_COLLIDER, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL, null) // Paper - Entity#getEntitySpawnReason .isPresent(); } diff --git a/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java b/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java -index c3f6522a7dc0777c5b3fa2bac63a8901f96d9f38..9b336f651ead8111a0b2c0fedad9331f594b2990 100644 +index f0163b7fa8b27823db9df5b8d2b6adcb63023164..de9d00ec932c8d07b28dd68ac9b8e6d5b94f7a8d 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java +++ b/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java @@ -231,6 +231,7 @@ public final class TrialSpawner { @@ -214,10 +272,10 @@ index c3f6522a7dc0777c5b3fa2bac63a8901f96d9f38..9b336f651ead8111a0b2c0fedad9331f if (org.bukkit.craftbukkit.event.CraftEventFactory.callTrialSpawnerSpawnEvent(entity, pos).isCancelled()) { return Optional.empty(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index bddf98bdf60473eb1d2e533cf533ed7eee797aaa..ce70c8fddbe63d0af2b1f988ce9a2b40c5d48066 100644 +index 0e5cc680ee2418ec2af5fc3e215618ad4e768ed0..7fb04535b8c0744d0fa4b0c0a933234134486956 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1018,4 +1018,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1019,4 +1019,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return this.getHandle().spawnedViaMobSpawner; } // Paper end - Entity#fromMobSpawner diff --git a/patches/unapplied/server/0281-Fire-event-on-GS4-query.patch b/patches/server/0279-Fire-event-on-GS4-query.patch similarity index 100% rename from patches/unapplied/server/0281-Fire-event-on-GS4-query.patch rename to patches/server/0279-Fire-event-on-GS4-query.patch diff --git a/patches/unapplied/server/0282-Add-PlayerPostRespawnEvent.patch b/patches/server/0280-Add-PlayerPostRespawnEvent.patch similarity index 58% rename from patches/unapplied/server/0282-Add-PlayerPostRespawnEvent.patch rename to patches/server/0280-Add-PlayerPostRespawnEvent.patch index 946a6be171bd..5adb0c50ef42 100644 --- a/patches/unapplied/server/0282-Add-PlayerPostRespawnEvent.patch +++ b/patches/server/0280-Add-PlayerPostRespawnEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerPostRespawnEvent diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 79203d0e5cdb86d9e2fb22cdaeb8cf3a93e43dcc..8cd80ea83ddcfd5052c8d8c19d3edb42538d1e15 100644 +index dffc7f0c9c730bc629ee169eca3a7a997c2cc7b1..29110c0b950c3073ab699d8ad1523ece2e8d3408 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -738,6 +738,10 @@ public abstract class PlayerList { +@@ -705,6 +705,10 @@ public abstract class PlayerList { entityplayer1.addTag(s); } @@ -18,38 +18,38 @@ index 79203d0e5cdb86d9e2fb22cdaeb8cf3a93e43dcc..8cd80ea83ddcfd5052c8d8c19d3edb42 + // Paper end - Add PlayerPostRespawnEvent // CraftBukkit start - fire PlayerRespawnEvent - DimensionTransition dimensiontransition; -@@ -745,11 +749,16 @@ public abstract class PlayerList { - dimensiontransition = entityplayer.findRespawnPositionAndUseSpawnBlock(flag, DimensionTransition.DO_NOTHING, reason); + TeleportTransition teleporttransition; +@@ -712,11 +716,16 @@ public abstract class PlayerList { + teleporttransition = entityplayer.findRespawnPositionAndUseSpawnBlock(!flag, TeleportTransition.DO_NOTHING, reason); if (!flag) entityplayer.reset(); // SPIGOT-4785 -+ // Paper start - Add PlayerPostRespawnEvent -+ if (dimensiontransition == null) return entityplayer; // Early exit, mirrors belows early return for disconnected players in respawn event -+ isRespawn = true; -+ location = CraftLocation.toBukkit(dimensiontransition.pos(), dimensiontransition.newLevel().getWorld(), dimensiontransition.yRot(), dimensiontransition.xRot()); -+ // Paper end - Add PlayerPostRespawnEvent ++ // Paper start - Add PlayerPostRespawnEvent ++ if (teleporttransition == null) return entityplayer; // Early exit, mirrors belows early return for disconnected players in respawn event ++ isRespawn = true; ++ location = CraftLocation.toBukkit(teleporttransition.position(), teleporttransition.newLevel().getWorld(), teleporttransition.yRot(), teleporttransition.xRot()); ++ // Paper end - Add PlayerPostRespawnEvent } else { - dimensiontransition = new DimensionTransition(((CraftWorld) location.getWorld()).getHandle(), CraftLocation.toVec3D(location), Vec3.ZERO, location.getYaw(), location.getPitch(), DimensionTransition.DO_NOTHING); + teleporttransition = new TeleportTransition(((CraftWorld) location.getWorld()).getHandle(), CraftLocation.toVec3D(location), Vec3.ZERO, location.getYaw(), location.getPitch(), TeleportTransition.DO_NOTHING); } // Spigot Start -- if (dimensiontransition == null) { -+ if (dimensiontransition == null) { // Paper - Add PlayerPostRespawnEvent - diff on change - spigot early returns if respawn pos is null, that is how they handle disconnected player in respawn event +- if (teleporttransition == null) { ++ if (teleporttransition == null) { // Paper - Add PlayerPostRespawnEvent - diff on change - spigot early returns if respawn pos is null, that is how they handle disconnected player in respawn event return entityplayer; } // Spigot End -@@ -795,6 +804,11 @@ public abstract class PlayerList { +@@ -764,6 +773,11 @@ public abstract class PlayerList { if (iblockdata.is(Blocks.RESPAWN_ANCHOR)) { entityplayer1.connection.send(new ClientboundSoundPacket(SoundEvents.RESPAWN_ANCHOR_DEPLETE, SoundSource.BLOCKS, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 1.0F, 1.0F, worldserver.getRandom().nextLong())); } + // Paper start - Add PlayerPostRespawnEvent -+ if (iblockdata.is(net.minecraft.tags.BlockTags.BEDS) && !dimensiontransition.missingRespawnBlock()) { ++ if (iblockdata.is(net.minecraft.tags.BlockTags.BEDS) && !teleporttransition.missingRespawnBlock()) { + isBedSpawn = true; + } + // Paper end - Add PlayerPostRespawnEvent } // Added from changeDimension this.sendAllPlayerInfo(entityplayer); // Update health, etc... -@@ -816,6 +830,13 @@ public abstract class PlayerList { +@@ -785,6 +799,13 @@ public abstract class PlayerList { if (entityplayer.connection.isDisconnected()) { this.save(entityplayer); } diff --git a/patches/unapplied/server/0283-Server-Tick-Events.patch b/patches/server/0281-Server-Tick-Events.patch similarity index 78% rename from patches/unapplied/server/0283-Server-Tick-Events.patch rename to patches/server/0281-Server-Tick-Events.patch index 5c5d419332e1..20aa43f7b468 100644 --- a/patches/unapplied/server/0283-Server-Tick-Events.patch +++ b/patches/server/0281-Server-Tick-Events.patch @@ -6,10 +6,10 @@ 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 8ecfd7a3daa99dabe796d28d27790fb8b45c628b..ddc3da84c5a55d2cd977fcdb18121351606a6b3c 100644 +index 8030c00bc3783582aafbda934bb653b0b21d1fb9..5f84618775d66d50557fa71f77fa322c2d1da791 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1433,6 +1433,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop extends CraftBlockStat diff --git a/patches/unapplied/server/0292-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch b/patches/server/0290-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch similarity index 91% rename from patches/unapplied/server/0292-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch rename to patches/server/0290-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch index cb2e502f7154..6f292a58b461 100644 --- a/patches/unapplied/server/0292-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch +++ b/patches/server/0290-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch @@ -17,10 +17,10 @@ This should fully solve all of the issues around it so that only natural influences natural spawns. diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 41eef8bfd1572aecaf086bfbec300abeae2df794..58ea6a1f95a09c22125a8262b1b221004ebce0e4 100644 +index be2412ef8f8c331a881e442577cf05aec43f52bb..485c6044d603f15878f9413a644a538dab68db3e 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -83,6 +83,13 @@ public final class NaturalSpawner { +@@ -87,6 +87,13 @@ public final class NaturalSpawner { MobCategory enumcreaturetype = entity.getType().getCategory(); if (enumcreaturetype != MobCategory.MISC) { diff --git a/patches/unapplied/server/0293-Configurable-projectile-relative-velocity.patch b/patches/server/0291-Configurable-projectile-relative-velocity.patch similarity index 85% rename from patches/unapplied/server/0293-Configurable-projectile-relative-velocity.patch rename to patches/server/0291-Configurable-projectile-relative-velocity.patch index 29613c9f0028..3ca413377fd6 100644 --- a/patches/unapplied/server/0293-Configurable-projectile-relative-velocity.patch +++ b/patches/server/0291-Configurable-projectile-relative-velocity.patch @@ -25,10 +25,10 @@ P3) Solutions for 1) and especially 2) might not be future-proof, while this server-internal fix makes this change future-proof. diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 30eb86b52f00cfa61af4f93aca50ffc3547c95e8..d27e17ebf25cd842a943cf82bde05b2248c74414 100644 +index 7c8f92b7e5eb66d26e6c46dc2ed86c68dbe97ae9..2cb77d0b6e6ba880a2a76488a870a20ed883b15a 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -182,8 +182,11 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -192,8 +192,11 @@ public abstract class Projectile extends Entity implements TraceableEntity { this.shoot((double) f5, (double) f6, (double) f7, speed, divergence); Vec3 vec3d = shooter.getKnownMovement(); @@ -40,4 +40,4 @@ index 30eb86b52f00cfa61af4f93aca50ffc3547c95e8..d27e17ebf25cd842a943cf82bde05b22 + // Paper end - allow disabling relative velocity } - // CraftBukkit start - call projectile hit event + public static T spawnProjectileFromRotation(Projectile.ProjectileFactory creator, ServerLevel world, ItemStack projectileStack, LivingEntity shooter, float roll, float power, float divergence) { diff --git a/patches/unapplied/server/0294-offset-item-frame-ticking.patch b/patches/server/0292-offset-item-frame-ticking.patch similarity index 85% rename from patches/unapplied/server/0294-offset-item-frame-ticking.patch rename to patches/server/0292-offset-item-frame-ticking.patch index 3db1ffe3056a..f8748a09cc34 100644 --- a/patches/unapplied/server/0294-offset-item-frame-ticking.patch +++ b/patches/server/0292-offset-item-frame-ticking.patch @@ -5,10 +5,10 @@ Subject: [PATCH] offset item frame ticking diff --git a/src/main/java/net/minecraft/world/entity/decoration/BlockAttachedEntity.java b/src/main/java/net/minecraft/world/entity/decoration/BlockAttachedEntity.java -index e4eece7bbd14514ec60da26a8744672baa8956f9..7bc612890f941177da11da0ce047d5a74d8ebb33 100644 +index cd0a2270b58b6c0dba67270e7e1d1ba253eb7953..608acb4f3cb8f9a0dc10b819ed4bf577c229dd2c 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/BlockAttachedEntity.java +++ b/src/main/java/net/minecraft/world/entity/decoration/BlockAttachedEntity.java -@@ -26,7 +26,7 @@ import org.bukkit.event.hanging.HangingBreakEvent; +@@ -29,7 +29,7 @@ import org.bukkit.event.hanging.HangingBreakEvent; public abstract class BlockAttachedEntity extends Entity { private static final Logger LOGGER = LogUtils.getLogger(); diff --git a/patches/unapplied/server/0295-Prevent-consuming-the-wrong-itemstack.patch b/patches/server/0293-Prevent-consuming-the-wrong-itemstack.patch similarity index 86% rename from patches/unapplied/server/0295-Prevent-consuming-the-wrong-itemstack.patch rename to patches/server/0293-Prevent-consuming-the-wrong-itemstack.patch index c0dbff9a6b8f..87d7bf2e2844 100644 --- a/patches/unapplied/server/0295-Prevent-consuming-the-wrong-itemstack.patch +++ b/patches/server/0293-Prevent-consuming-the-wrong-itemstack.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent consuming the wrong itemstack diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index a23baa42fd3bb09f619fd6528a8a4f97d189cde6..8ee6d25c3860fe7f2e5039c74c736d82eefda237 100644 +index 34f66931dec00809ed58569e24431762a1acd56f..f720d4d93ed13b1b9287a1ee7dc8bc4794834e1a 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3855,9 +3855,14 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3995,9 +3995,14 @@ public abstract class LivingEntity extends Entity implements Attackable { } public void startUsingItem(InteractionHand hand) { @@ -24,15 +24,15 @@ index a23baa42fd3bb09f619fd6528a8a4f97d189cde6..8ee6d25c3860fe7f2e5039c74c736d82 this.useItem = itemstack; this.useItemRemaining = itemstack.getUseDuration(this); if (!this.level().isClientSide) { -@@ -3942,6 +3947,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4068,6 +4073,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.releaseUsingItem(); } else { if (!this.useItem.isEmpty() && this.isUsingItem()) { + this.startUsingItem(this.getUsedItemHand(), true); // Paper - Prevent consuming the wrong itemstack - this.triggerItemUseEffects(this.useItem, 16); // CraftBukkit start - fire PlayerItemConsumeEvent ItemStack itemstack; -@@ -3979,8 +3985,8 @@ public abstract class LivingEntity extends Entity implements Attackable { + PlayerItemConsumeEvent event = null; // Paper +@@ -4105,8 +4111,8 @@ public abstract class LivingEntity extends Entity implements Attackable { } this.stopUsingItem(); diff --git a/patches/unapplied/server/0296-Dont-send-unnecessary-sign-update.patch b/patches/server/0294-Dont-send-unnecessary-sign-update.patch similarity index 89% rename from patches/unapplied/server/0296-Dont-send-unnecessary-sign-update.patch rename to patches/server/0294-Dont-send-unnecessary-sign-update.patch index afca8562dbfb..cccd627a78f7 100644 --- a/patches/unapplied/server/0296-Dont-send-unnecessary-sign-update.patch +++ b/patches/server/0294-Dont-send-unnecessary-sign-update.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Dont send unnecessary sign update diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java -index 394d0b03f18d55b43f091a9ae1a47e06a6fa4c0d..87e272cfb145c37d26b0bf56f97ec784a9bfd98e 100644 +index 469d0046ba98289e98aa0f3f66e3ed27026a98a2..3339130f3a02e6e395bcd8e3047b35f6f4eca9a9 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java -@@ -185,6 +185,7 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C +@@ -185,6 +185,7 @@ public class SignBlockEntity extends BlockEntity { this.level.sendBlockUpdated(this.getBlockPos(), this.getBlockState(), this.getBlockState(), 3); } else { SignBlockEntity.LOGGER.warn("Player {} just tried to change non-editable sign", player.getName().getString()); diff --git a/patches/unapplied/server/0297-Add-option-to-disable-pillager-patrols.patch b/patches/server/0295-Add-option-to-disable-pillager-patrols.patch similarity index 91% rename from patches/unapplied/server/0297-Add-option-to-disable-pillager-patrols.patch rename to patches/server/0295-Add-option-to-disable-pillager-patrols.patch index 3021a1f6c83a..dd3c57ff12bf 100644 --- a/patches/unapplied/server/0297-Add-option-to-disable-pillager-patrols.patch +++ b/patches/server/0295-Add-option-to-disable-pillager-patrols.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add option to disable pillager patrols diff --git a/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java -index 7522c40ab352d3b3ce1540f043b4b5f0d411060b..7b5db53d4cf97e41175896de47303526198fb8f6 100644 +index 04e108633068c2a1a88a35995c2999701ef7bc3b..8837db46ced2412942949a3c6f81ec7d9a0bacda 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java +++ b/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java @@ -24,6 +24,7 @@ public class PatrolSpawner implements CustomSpawner { diff --git a/patches/unapplied/server/0298-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch b/patches/server/0296-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch similarity index 100% rename from patches/unapplied/server/0298-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch rename to patches/server/0296-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch diff --git a/patches/unapplied/server/0300-Duplicate-UUID-Resolve-Option.patch b/patches/server/0297-Duplicate-UUID-Resolve-Option.patch similarity index 96% rename from patches/unapplied/server/0300-Duplicate-UUID-Resolve-Option.patch rename to patches/server/0297-Duplicate-UUID-Resolve-Option.patch index 0139752e8eee..502d6dcc289c 100644 --- a/patches/unapplied/server/0300-Duplicate-UUID-Resolve-Option.patch +++ b/patches/server/0297-Duplicate-UUID-Resolve-Option.patch @@ -33,10 +33,10 @@ 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/world/level/chunk/status/ChunkStatusTasks.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -index 82fc5133325a127890984d51c1381883759eb444..ae16cf5c803caae636860dd9b1a83abe479ca5a4 100644 +index 3f552ee8f90566edddb5943311a14309e4bebb61..f18c2b85ed9541f646f157184221e333d0ae58bd 100644 --- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java +++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -@@ -189,10 +189,51 @@ public class ChunkStatusTasks { +@@ -178,10 +178,51 @@ public class ChunkStatusTasks { entity.discard(null); // CraftBukkit - add Bukkit remove cause needsRemoval = true; } diff --git a/patches/unapplied/server/0301-PlayerDeathEvent-shouldDropExperience.patch b/patches/server/0298-PlayerDeathEvent-shouldDropExperience.patch similarity index 69% rename from patches/unapplied/server/0301-PlayerDeathEvent-shouldDropExperience.patch rename to patches/server/0298-PlayerDeathEvent-shouldDropExperience.patch index b48dcea61d16..22cdda6c7901 100644 --- a/patches/unapplied/server/0301-PlayerDeathEvent-shouldDropExperience.patch +++ b/patches/server/0298-PlayerDeathEvent-shouldDropExperience.patch @@ -5,15 +5,15 @@ 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 cba123f40d72ebd39305a76694be508510997d1e..4ccb5ba03d19223d25aee4cebd4b8bec2838a3e0 100644 +index c5eb4766d95b1ed91be8e8631200f56096a17766..099a9aa7e64da22e720fa527cac8750991ee8562 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1018,7 +1018,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1278,7 +1278,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.tellNeutralMobsThatIDied(); } // SPIGOT-5478 must be called manually now -- this.dropExperience(damageSource.getEntity()); -+ if (event.shouldDropExperience()) this.dropExperience(damageSource.getEntity()); // Paper - tie to event +- this.dropExperience(this.serverLevel(), damageSource.getEntity()); ++ if (event.shouldDropExperience()) this.dropExperience(this.serverLevel(), damageSource.getEntity()); // Paper - tie to event // we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory. if (!event.getKeepInventory()) { // Paper start - PlayerDeathEvent#getItemsToKeep diff --git a/patches/unapplied/server/0299-MC-145656-Fix-Follow-Range-Initial-Target.patch b/patches/unapplied/server/0299-MC-145656-Fix-Follow-Range-Initial-Target.patch deleted file mode 100644 index 528cf153ea7a..000000000000 --- a/patches/unapplied/server/0299-MC-145656-Fix-Follow-Range-Initial-Target.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Wed, 18 Dec 2019 22:21:35 -0600 -Subject: [PATCH] MC-145656 Fix Follow Range Initial Target - - -diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/target/NearestAttackableTargetGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/target/NearestAttackableTargetGoal.java -index 0dad5be671f990d0edf0a155e2534b3812438902..175ba1184fc997f562f0834b172e17dc1b5b3027 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/goal/target/NearestAttackableTargetGoal.java -+++ b/src/main/java/net/minecraft/world/entity/ai/goal/target/NearestAttackableTargetGoal.java -@@ -38,6 +38,7 @@ public class NearestAttackableTargetGoal extends TargetG - this.randomInterval = reducedTickDelay(reciprocalChance); - this.setFlags(EnumSet.of(Goal.Flag.TARGET)); - this.targetConditions = TargetingConditions.forCombat().range(this.getFollowDistance()).selector(targetPredicate); -+ if (mob.level().paperConfig().entities.entitiesTargetWithFollowRange) this.targetConditions.useFollowRange(); // Paper - Fix MC-145656 - } - - @Override -diff --git a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java -index bc4b9a46056e83762e29bb04485ad7c754a20336..aecb0ad814586bfc5e56755ee14379a69388b38c 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java -+++ b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java -@@ -77,7 +77,7 @@ public class TargetingConditions { - - if (this.range > 0.0) { - double d = this.testInvisible ? targetEntity.getVisibilityPercent(baseEntity) : 1.0; -- double e = Math.max(this.range * d, 2.0); -+ double e = Math.max((this.useFollowRange ? this.getFollowRange(baseEntity) : this.range) * d, 2.0); // Paper - Fix MC-145656 - double f = baseEntity.distanceToSqr(targetEntity.getX(), targetEntity.getY(), targetEntity.getZ()); - if (f > e * e) { - return false; -@@ -92,4 +92,18 @@ public class TargetingConditions { - return true; - } - } -+ -+ // Paper start - Fix MC-145656 -+ private boolean useFollowRange = false; -+ -+ public TargetingConditions useFollowRange() { -+ this.useFollowRange = true; -+ return this; -+ } -+ -+ private double getFollowRange(LivingEntity entityliving) { -+ net.minecraft.world.entity.ai.attributes.AttributeInstance attributeinstance = entityliving.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.FOLLOW_RANGE); -+ return attributeinstance == null ? 16.0D : attributeinstance.getValue(); -+ } -+ // Paper end - Fix MC-145656 - } From aa37f7250d168e94318e975d3c6d1002e7b82c29 Mon Sep 17 00:00:00 2001 From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Date: Wed, 23 Oct 2024 09:54:09 -0400 Subject: [PATCH 017/119] Patches --- ...oading-chunks-checking-hive-position.patch | 24 +++++++ ...hunks-from-Hoppers-and-other-things.patch} | 2 +- ...timise-EntityGetter-getPlayerByUUID.patch} | 6 +- ...302-Fix-items-not-falling-correctly.patch} | 6 +- ...ize-call-to-getFluid-for-explosions.patch} | 10 +-- ...rializing-mismatching-chunk-coordina.patch | 63 +++++++++++++++++++ .../0305-Alternative-item-despawn-rate.patch} | 14 ++--- .../0306-Tracking-Range-Improvements.patch} | 4 +- ...et-gravity-in-void.-Fixes-MC-167279.patch} | 4 +- ...08-Improve-Block-breakNaturally-API.patch} | 6 +- ...-getChunkAt-calls-for-loaded-chunks.patch} | 10 +-- ...0310-Add-debug-for-sync-chunk-loads.patch} | 8 +-- .../0311-Improve-java-version-check.patch} | 2 +- .../0312-Add-ThrownEggHatchEvent.patch} | 4 +- .../0313-Entity-Jump-API.patch} | 28 ++++----- ...-to-nerf-pigmen-from-nether-portals.patch} | 24 +++---- .../0315-Make-the-GUI-graph-fancier.patch} | 0 ...16-add-hand-to-BlockMultiPlaceEvent.patch} | 4 +- ...ipwire-hook-placement-before-update.patch} | 4 +- ...o-allow-iron-golems-to-spawn-in-air.patch} | 4 +- ...chance-of-villager-zombie-infection.patch} | 10 +-- .../0320-Optimise-Chunk-getFluid.patch} | 10 +-- ...rbose-world-setting-to-false-by-def.patch} | 0 ...Add-tick-times-API-and-mspt-command.patch} | 24 +++---- ...23-Expose-MinecraftServer-isRunning.patch} | 4 +- ...dd-Raw-Byte-ItemStack-Serialization.patch} | 2 +- ...pawn-settings-and-per-player-option.patch} | 6 +- ...nections-shouldn-t-hold-up-shutdown.patch} | 4 +- ...27-Do-not-allow-Vexes-to-load-chunks.patch | 22 +++++++ ...oading-chunks-checking-hive-position.patch | 18 ------ ...rializing-mismatching-chunk-coordina.patch | 52 --------------- ...low-bees-to-load-chunks-for-beehives.patch | 58 ----------------- 32 files changed, 211 insertions(+), 226 deletions(-) create mode 100644 patches/server/0299-Prevent-bees-loading-chunks-checking-hive-position.patch rename patches/{unapplied/server/0303-Don-t-load-Chunks-from-Hoppers-and-other-things.patch => server/0300-Don-t-load-Chunks-from-Hoppers-and-other-things.patch} (95%) rename patches/{unapplied/server/0304-Optimise-EntityGetter-getPlayerByUUID.patch => server/0301-Optimise-EntityGetter-getPlayerByUUID.patch} (66%) rename patches/{unapplied/server/0305-Fix-items-not-falling-correctly.patch => server/0302-Fix-items-not-falling-correctly.patch} (90%) rename patches/{unapplied/server/0306-Optimize-call-to-getFluid-for-explosions.patch => server/0303-Optimize-call-to-getFluid-for-explosions.patch} (64%) create mode 100644 patches/server/0304-Guard-against-serializing-mismatching-chunk-coordina.patch rename patches/{unapplied/server/0308-Alternative-item-despawn-rate.patch => server/0305-Alternative-item-despawn-rate.patch} (87%) rename patches/{unapplied/server/0309-Tracking-Range-Improvements.patch => server/0306-Tracking-Range-Improvements.patch} (95%) rename patches/{unapplied/server/0310-Bees-get-gravity-in-void.-Fixes-MC-167279.patch => server/0307-Bees-get-gravity-in-void.-Fixes-MC-167279.patch} (90%) rename patches/{unapplied/server/0311-Improve-Block-breakNaturally-API.patch => server/0308-Improve-Block-breakNaturally-API.patch} (95%) rename patches/{unapplied/server/0312-Optimise-getChunkAt-calls-for-loaded-chunks.patch => server/0309-Optimise-getChunkAt-calls-for-loaded-chunks.patch} (86%) rename patches/{unapplied/server/0313-Add-debug-for-sync-chunk-loads.patch => server/0310-Add-debug-for-sync-chunk-loads.patch} (97%) rename patches/{unapplied/server/0314-Improve-java-version-check.patch => server/0311-Improve-java-version-check.patch} (95%) rename patches/{unapplied/server/0315-Add-ThrownEggHatchEvent.patch => server/0312-Add-ThrownEggHatchEvent.patch} (90%) rename patches/{unapplied/server/0316-Entity-Jump-API.patch => server/0313-Entity-Jump-API.patch} (75%) rename patches/{unapplied/server/0317-Add-option-to-nerf-pigmen-from-nether-portals.patch => server/0314-Add-option-to-nerf-pigmen-from-nether-portals.patch} (73%) rename patches/{unapplied/server/0318-Make-the-GUI-graph-fancier.patch => server/0315-Make-the-GUI-graph-fancier.patch} (100%) rename patches/{unapplied/server/0319-add-hand-to-BlockMultiPlaceEvent.patch => server/0316-add-hand-to-BlockMultiPlaceEvent.patch} (89%) rename patches/{unapplied/server/0320-Validate-tripwire-hook-placement-before-update.patch => server/0317-Validate-tripwire-hook-placement-before-update.patch} (86%) rename patches/{unapplied/server/0321-Add-option-to-allow-iron-golems-to-spawn-in-air.patch => server/0318-Add-option-to-allow-iron-golems-to-spawn-in-air.patch} (86%) rename patches/{unapplied/server/0322-Configurable-chance-of-villager-zombie-infection.patch => server/0319-Configurable-chance-of-villager-zombie-infection.patch} (81%) rename patches/{unapplied/server/0323-Optimise-Chunk-getFluid.patch => server/0320-Optimise-Chunk-getFluid.patch} (88%) rename patches/{unapplied/server/0324-Set-spigots-verbose-world-setting-to-false-by-def.patch => server/0321-Set-spigots-verbose-world-setting-to-false-by-def.patch} (100%) rename patches/{unapplied/server/0325-Add-tick-times-API-and-mspt-command.patch => server/0322-Add-tick-times-API-and-mspt-command.patch} (91%) rename patches/{unapplied/server/0326-Expose-MinecraftServer-isRunning.patch => server/0323-Expose-MinecraftServer-isRunning.patch} (83%) rename patches/{unapplied/server/0327-Add-Raw-Byte-ItemStack-Serialization.patch => server/0324-Add-Raw-Byte-ItemStack-Serialization.patch} (97%) rename patches/{unapplied/server/0328-Pillager-patrol-spawn-settings-and-per-player-option.patch => server/0325-Pillager-patrol-spawn-settings-and-per-player-option.patch} (95%) rename patches/{unapplied/server/0329-Remote-Connections-shouldn-t-hold-up-shutdown.patch => server/0326-Remote-Connections-shouldn-t-hold-up-shutdown.patch} (92%) create mode 100644 patches/server/0327-Do-not-allow-Vexes-to-load-chunks.patch delete mode 100644 patches/unapplied/server/0302-Prevent-bees-loading-chunks-checking-hive-position.patch delete mode 100644 patches/unapplied/server/0307-Guard-against-serializing-mismatching-chunk-coordina.patch delete mode 100644 patches/unapplied/server/0330-Do-not-allow-bees-to-load-chunks-for-beehives.patch diff --git a/patches/server/0299-Prevent-bees-loading-chunks-checking-hive-position.patch b/patches/server/0299-Prevent-bees-loading-chunks-checking-hive-position.patch new file mode 100644 index 000000000000..ce7ab4dd4d0e --- /dev/null +++ b/patches/server/0299-Prevent-bees-loading-chunks-checking-hive-position.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Sun, 5 Jan 2020 17:24:34 -0600 +Subject: [PATCH] Prevent bees loading chunks checking hive position + + +diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java +index b1a72ed404f4bc31f32dd771dd320b7c783c9651..310a2aa23365f9a8a8b7b6fa2323aed792f95adb 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/Bee.java ++++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java +@@ -514,7 +514,12 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { + + @Nullable + BeehiveBlockEntity getBeehiveBlockEntity() { +- return this.hivePos == null ? null : (this.isTooFarAway(this.hivePos) ? null : (BeehiveBlockEntity) this.level().getBlockEntity(this.hivePos, BlockEntityType.BEEHIVE).orElse(null)); // CraftBukkit - decompile error ++ // Paper start - move over logic to accommodate isTooFarAway with chunk load check ++ if (this.hivePos != null && !this.isTooFarAway(this.hivePos) && this.level().getChunkIfLoadedImmediately(this.hivePos.getX() >> 4, this.hivePos.getZ() >> 4) != null) { ++ return (BeehiveBlockEntity) this.level().getBlockEntity(this.hivePos, BlockEntityType.BEEHIVE).orElse(null); ++ } ++ return null; ++ // Paper end + } + + boolean isHiveValid() { diff --git a/patches/unapplied/server/0303-Don-t-load-Chunks-from-Hoppers-and-other-things.patch b/patches/server/0300-Don-t-load-Chunks-from-Hoppers-and-other-things.patch similarity index 95% rename from patches/unapplied/server/0303-Don-t-load-Chunks-from-Hoppers-and-other-things.patch rename to patches/server/0300-Don-t-load-Chunks-from-Hoppers-and-other-things.patch index 3b189be4e438..cf3afd704034 100644 --- a/patches/unapplied/server/0303-Don-t-load-Chunks-from-Hoppers-and-other-things.patch +++ b/patches/server/0300-Don-t-load-Chunks-from-Hoppers-and-other-things.patch @@ -13,7 +13,7 @@ This of course is undesirable, so just return the loaded side as "primary" and treat it as a single chest if the other sides are unloaded diff --git a/src/main/java/net/minecraft/world/level/block/DoubleBlockCombiner.java b/src/main/java/net/minecraft/world/level/block/DoubleBlockCombiner.java -index 963092cd5a4e756ad6a471379a81d8996cc2b091..20c9921339ec6b5127fbadcedc19577f3906074d 100644 +index cccdaa29ea97ec1d9e79f5a4811884d54e641677..b5025914678484cc615dc1982762d5d7f55a4557 100644 --- a/src/main/java/net/minecraft/world/level/block/DoubleBlockCombiner.java +++ b/src/main/java/net/minecraft/world/level/block/DoubleBlockCombiner.java @@ -34,7 +34,12 @@ public class DoubleBlockCombiner { diff --git a/patches/unapplied/server/0304-Optimise-EntityGetter-getPlayerByUUID.patch b/patches/server/0301-Optimise-EntityGetter-getPlayerByUUID.patch similarity index 66% rename from patches/unapplied/server/0304-Optimise-EntityGetter-getPlayerByUUID.patch rename to patches/server/0301-Optimise-EntityGetter-getPlayerByUUID.patch index 6ffcd9f3c3bf..e0992abebba1 100644 --- a/patches/unapplied/server/0304-Optimise-EntityGetter-getPlayerByUUID.patch +++ b/patches/server/0301-Optimise-EntityGetter-getPlayerByUUID.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Optimise EntityGetter#getPlayerByUUID Use the PlayerList 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 a6a21def1ae0d35fa106da6242c49a0928e4eda5..c85d5b941b5cb1c37cd2619d419006c5956f6eaf 100644 +index 64c1fd62a865adb1e11edd326a1a5ccdc98f13ed..c7a1328e6642ad6c76179bddec117c4281577e86 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -330,6 +330,15 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -333,6 +333,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } // Paper end @@ -24,4 +24,4 @@ index a6a21def1ae0d35fa106da6242c49a0928e4eda5..c85d5b941b5cb1c37cd2619d419006c5 + // Add env and gen to constructor, IWorldDataServer -> WorldDataServer public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { - // IRegistryCustom.Dimension iregistrycustom_dimension = minecraftserver.registryAccess(); // CraftBukkit - decompile error + super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules()))); // Paper - create paper world configs diff --git a/patches/unapplied/server/0305-Fix-items-not-falling-correctly.patch b/patches/server/0302-Fix-items-not-falling-correctly.patch similarity index 90% rename from patches/unapplied/server/0305-Fix-items-not-falling-correctly.patch rename to patches/server/0302-Fix-items-not-falling-correctly.patch index 5be02c3b7bd1..d7e28fecdfd5 100644 --- a/patches/unapplied/server/0305-Fix-items-not-falling-correctly.patch +++ b/patches/server/0302-Fix-items-not-falling-correctly.patch @@ -15,7 +15,7 @@ This patch resolves the conflict by offsetting checking Spigot's entity activation range check from an item's move method. diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index f9dfd6e7b610cfee75524a525ab0e72bed5522da..e110296a95441a13ec431d897796326b0277edb1 100644 +index 75ebf09777e19645eee296a9edabac39c858ffb9..c390d8b3a706d0177b9f3105a7b9a84265688ece 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -175,7 +175,7 @@ public class ItemEntity extends Entity implements TraceableEntity { @@ -25,10 +25,10 @@ index f9dfd6e7b610cfee75524a525ab0e72bed5522da..e110296a95441a13ec431d897796326b - if (!this.onGround() || this.getDeltaMovement().horizontalDistanceSqr() > 9.999999747378752E-6D || (this.tickCount + this.getId()) % 4 == 0) { + if (!this.onGround() || this.getDeltaMovement().horizontalDistanceSqr() > 9.999999747378752E-6D || (this.tickCount + this.getId()) % 4 == 0) { // Paper - Diff on change this.move(MoverType.SELF, this.getDeltaMovement()); + this.applyEffectsFromBlocks(); float f = 0.98F; - diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 6d51464f6368151e8acc532414ee223714584e96..9fb9fa62c32445ac3c3883a6433759c86dcfc428 100644 +index 5dac9bdb23de3d143cd678e583eaf6e8095bb209..ad15c7db36bdeadaa8f2ec8f15f41d6f3395bd55 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -256,7 +256,7 @@ public class ActivationRange diff --git a/patches/unapplied/server/0306-Optimize-call-to-getFluid-for-explosions.patch b/patches/server/0303-Optimize-call-to-getFluid-for-explosions.patch similarity index 64% rename from patches/unapplied/server/0306-Optimize-call-to-getFluid-for-explosions.patch rename to patches/server/0303-Optimize-call-to-getFluid-for-explosions.patch index 7a9152c9ec21..b6eb87bb5e74 100644 --- a/patches/unapplied/server/0306-Optimize-call-to-getFluid-for-explosions.patch +++ b/patches/server/0303-Optimize-call-to-getFluid-for-explosions.patch @@ -4,11 +4,11 @@ Date: Tue, 14 Jan 2020 17:49:03 -0500 Subject: [PATCH] Optimize call to getFluid for explosions -diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index ce8ac06b47e81161ad5ff6cc865ad6d3d59807c1..d4fe425954d36f0baddb256e3c83009a84084b72 100644 ---- a/src/main/java/net/minecraft/world/level/Explosion.java -+++ b/src/main/java/net/minecraft/world/level/Explosion.java -@@ -194,7 +194,7 @@ public class Explosion { +diff --git a/src/main/java/net/minecraft/world/level/ServerExplosion.java b/src/main/java/net/minecraft/world/level/ServerExplosion.java +index d1878f597c3d8119e9b248f4fe8af435ce8c9710..d3d74a7f306d88b0d5cd83893b3ee5e750fd4caf 100644 +--- a/src/main/java/net/minecraft/world/level/ServerExplosion.java ++++ b/src/main/java/net/minecraft/world/level/ServerExplosion.java +@@ -150,7 +150,7 @@ public class ServerExplosion implements Explosion { for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) { BlockPos blockposition = BlockPos.containing(d4, d5, d6); BlockState iblockdata = this.level.getBlockState(blockposition); diff --git a/patches/server/0304-Guard-against-serializing-mismatching-chunk-coordina.patch b/patches/server/0304-Guard-against-serializing-mismatching-chunk-coordina.patch new file mode 100644 index 000000000000..26436c7223e1 --- /dev/null +++ b/patches/server/0304-Guard-against-serializing-mismatching-chunk-coordina.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Fri, 27 Dec 2019 09:42:26 -0800 +Subject: [PATCH] Guard against serializing mismatching chunk coordinate + +Should help if something dumb happens + +diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java +index 329e7eb1c3e92445b3fae9e1e79d0497b7e3e3f2..909acbf5b8c6edcb4529647c11464d911d6f8c15 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java ++++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java +@@ -172,8 +172,19 @@ public class ChunkStorage implements AutoCloseable { + } + + public CompletableFuture write(ChunkPos chunkPos, Supplier nbtSupplier) { ++ // Paper start - guard against possible chunk pos desync ++ final Supplier guardedPosCheck = () -> { ++ CompoundTag nbt = nbtSupplier.get(); ++ if (nbt != null && !chunkPos.equals(SerializableChunkData.getChunkCoordinate(nbt))) { ++ final String world = (ChunkStorage.this instanceof net.minecraft.server.level.ChunkMap) ? ((net.minecraft.server.level.ChunkMap) ChunkStorage.this).level.getWorld().getName() : null; ++ throw new IllegalArgumentException("Chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + chunkPos ++ + " but compound says coordinate is " + SerializableChunkData.getChunkCoordinate(nbt) + (world == null ? " for an unknown world" : (" for world: " + world))); ++ } ++ return nbt; ++ }; ++ // Paper end - guard against possible chunk pos desync + this.handleLegacyStructureIndex(chunkPos); +- return this.worker.store(chunkPos, nbtSupplier); ++ return this.worker.store(chunkPos, guardedPosCheck); // Paper - guard against possible chunk pos desync + } + + protected void handleLegacyStructureIndex(ChunkPos chunkPos) { +diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +index 4367ccc628bb4f404d6a081083002518442f462b..92ad7704a77c024afe090488764eaf59a4f7505f 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java ++++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +@@ -91,13 +91,25 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + public static final String SECTIONS_TAG = "sections"; + public static final String BLOCK_LIGHT_TAG = "BlockLight"; + public static final String SKY_LIGHT_TAG = "SkyLight"; ++ // Paper start - guard against serializing mismatching coordinates ++ // TODO Note: This needs to be re-checked each update ++ public static ChunkPos getChunkCoordinate(final CompoundTag chunkData) { ++ final int dataVersion = ChunkStorage.getVersion(chunkData); ++ if (dataVersion < 2842) { // Level tag is removed after this version ++ final CompoundTag levelData = chunkData.getCompound("Level"); ++ return new ChunkPos(levelData.getInt("xPos"), levelData.getInt("zPos")); ++ } else { ++ return new ChunkPos(chunkData.getInt("xPos"), chunkData.getInt("zPos")); ++ } ++ } ++ // Paper end - guard against serializing mismatching coordinates + + @Nullable + public static SerializableChunkData parse(LevelHeightAccessor world, RegistryAccess registryManager, CompoundTag nbt) { + if (!nbt.contains("Status", 8)) { + return null; + } else { +- ChunkPos chunkcoordintpair = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos")); ++ ChunkPos chunkcoordintpair = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos")); // Paper - guard against serializing mismatching coordinates; diff on change, see ChunkSerializer#getChunkCoordinate + long i = nbt.getLong("LastUpdate"); + long j = nbt.getLong("InhabitedTime"); + ChunkStatus chunkstatus = ChunkStatus.byName(nbt.getString("Status")); diff --git a/patches/unapplied/server/0308-Alternative-item-despawn-rate.patch b/patches/server/0305-Alternative-item-despawn-rate.patch similarity index 87% rename from patches/unapplied/server/0308-Alternative-item-despawn-rate.patch rename to patches/server/0305-Alternative-item-despawn-rate.patch index d4e1a80c7c9d..d9614e183d55 100644 --- a/patches/unapplied/server/0308-Alternative-item-despawn-rate.patch +++ b/patches/server/0305-Alternative-item-despawn-rate.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Alternative item-despawn-rate Co-authored-by: Noah van der Aa diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index e110296a95441a13ec431d897796326b0277edb1..c724359995d65c88e7f365eea55f3e4382a46ddd 100644 +index c390d8b3a706d0177b9f3105a7b9a84265688ece..65deb4568a80577f67f39de3af9fb568975a649d 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -62,6 +62,7 @@ public class ItemEntity extends Entity implements TraceableEntity { @@ -17,7 +17,7 @@ index e110296a95441a13ec431d897796326b0277edb1..c724359995d65c88e7f365eea55f3e43 public ItemEntity(EntityType type, Level world) { super(type, world); -@@ -215,7 +216,7 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -216,7 +217,7 @@ public class ItemEntity extends Entity implements TraceableEntity { } } @@ -26,7 +26,7 @@ index e110296a95441a13ec431d897796326b0277edb1..c724359995d65c88e7f365eea55f3e43 // CraftBukkit start - fire ItemDespawnEvent if (CraftEventFactory.callItemDespawnEvent(this).isCancelled()) { this.age = 0; -@@ -238,7 +239,7 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -239,7 +240,7 @@ public class ItemEntity extends Entity implements TraceableEntity { this.lastTick = MinecraftServer.currentTick; // CraftBukkit end @@ -35,7 +35,7 @@ index e110296a95441a13ec431d897796326b0277edb1..c724359995d65c88e7f365eea55f3e43 // CraftBukkit start - fire ItemDespawnEvent if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) { this.age = 0; -@@ -294,7 +295,7 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -297,7 +298,7 @@ public class ItemEntity extends Entity implements TraceableEntity { private boolean isMergable() { ItemStack itemstack = this.getItem(); @@ -44,7 +44,7 @@ index e110296a95441a13ec431d897796326b0277edb1..c724359995d65c88e7f365eea55f3e43 } private void tryToMerge(ItemEntity other) { -@@ -542,6 +543,7 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -558,6 +559,7 @@ public class ItemEntity extends Entity implements TraceableEntity { public void setItem(ItemStack stack) { this.getEntityData().set(ItemEntity.DATA_ITEM, stack); @@ -52,7 +52,7 @@ index e110296a95441a13ec431d897796326b0277edb1..c724359995d65c88e7f365eea55f3e43 } @Override -@@ -596,7 +598,7 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -612,7 +614,7 @@ public class ItemEntity extends Entity implements TraceableEntity { public void makeFakeItem() { this.setNeverPickUp(); @@ -60,4 +60,4 @@ index e110296a95441a13ec431d897796326b0277edb1..c724359995d65c88e7f365eea55f3e43 + this.age = this.despawnRate - 1; // Spigot // Paper - Alternative item-despawn-rate } - public float getSpin(float tickDelta) { + public static float getSpin(float f, float f1) { diff --git a/patches/unapplied/server/0309-Tracking-Range-Improvements.patch b/patches/server/0306-Tracking-Range-Improvements.patch similarity index 95% rename from patches/unapplied/server/0309-Tracking-Range-Improvements.patch rename to patches/server/0306-Tracking-Range-Improvements.patch index 845b77df2ee9..45bbbb2ad5b5 100644 --- a/patches/unapplied/server/0309-Tracking-Range-Improvements.patch +++ b/patches/server/0306-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 5573a5d0d0e10e3c584e821d3e8e7ba64a41a627..ee54706b36bd227edacea2a1b6099009bd652039 100644 +index aa3155bb57c09895d13914b46c77de78a90f250a..b849d24144dc9f7d24484398cec3b2b90befb507 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1545,6 +1545,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1604,6 +1604,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/unapplied/server/0310-Bees-get-gravity-in-void.-Fixes-MC-167279.patch b/patches/server/0307-Bees-get-gravity-in-void.-Fixes-MC-167279.patch similarity index 90% rename from patches/unapplied/server/0310-Bees-get-gravity-in-void.-Fixes-MC-167279.patch rename to patches/server/0307-Bees-get-gravity-in-void.-Fixes-MC-167279.patch index 9ea731b674e7..f91f8b04220c 100644 --- a/patches/unapplied/server/0310-Bees-get-gravity-in-void.-Fixes-MC-167279.patch +++ b/patches/server/0307-Bees-get-gravity-in-void.-Fixes-MC-167279.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Bees get gravity in void. Fixes MC-167279 diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java -index 58536ee8707c5ad0625cae2f26a58cf03b3f85d7..4134ee48909110f8c338f5d553d4cc1e9e31aaba 100644 +index 310a2aa23365f9a8a8b7b6fa2323aed792f95adb..8c7943fdb56cd75c362e47e6c934bde5a714adaa 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Bee.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java -@@ -144,7 +144,22 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -150,7 +150,22 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { public Bee(EntityType type, Level world) { super(type, world); this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(this.random, 20, 60); diff --git a/patches/unapplied/server/0311-Improve-Block-breakNaturally-API.patch b/patches/server/0308-Improve-Block-breakNaturally-API.patch similarity index 95% rename from patches/unapplied/server/0311-Improve-Block-breakNaturally-API.patch rename to patches/server/0308-Improve-Block-breakNaturally-API.patch index b478ee5bb4fa..55dcdabf6445 100644 --- a/patches/unapplied/server/0311-Improve-Block-breakNaturally-API.patch +++ b/patches/server/0308-Improve-Block-breakNaturally-API.patch @@ -18,10 +18,10 @@ public net.minecraft.world.level.block.TurtleEggBlock decreaseEggs(Lnet/minecraf Co-authored-by: William Blake Galbreath diff --git a/src/main/java/net/minecraft/world/level/block/IceBlock.java b/src/main/java/net/minecraft/world/level/block/IceBlock.java -index 363dd6ab9c7b650913795ef350374d5c4e7e4925..e862814c1e54776f11050623b52476accc2f1f79 100644 +index 6a4cc64068f67ee18a9e505888edb3874597b98a..067a2d969ca0979ae67b600e303deec93eda0251 100644 --- a/src/main/java/net/minecraft/world/level/block/IceBlock.java +++ b/src/main/java/net/minecraft/world/level/block/IceBlock.java -@@ -35,6 +35,11 @@ public class IceBlock extends HalfTransparentBlock { +@@ -36,6 +36,11 @@ public class IceBlock extends HalfTransparentBlock { @Override public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) { super.playerDestroy(world, player, pos, state, blockEntity, tool); @@ -34,7 +34,7 @@ index 363dd6ab9c7b650913795ef350374d5c4e7e4925..e862814c1e54776f11050623b52476ac if (world.dimensionType().ultraWarm()) { world.removeBlock(pos, false); diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index d4e14ac1514e2d8b87b4667a91c90eded3ba6636..f041b5d80bff9c022b007e04ef1558e9116acc6b 100644 +index e5ac2d79b21db4e9a92b739e39d41a22deee175b..aae00320ab8003420bae5de7df47f553b62c5aab 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -452,6 +452,18 @@ public class CraftBlock implements Block { diff --git a/patches/unapplied/server/0312-Optimise-getChunkAt-calls-for-loaded-chunks.patch b/patches/server/0309-Optimise-getChunkAt-calls-for-loaded-chunks.patch similarity index 86% rename from patches/unapplied/server/0312-Optimise-getChunkAt-calls-for-loaded-chunks.patch rename to patches/server/0309-Optimise-getChunkAt-calls-for-loaded-chunks.patch index d1fed5285fcf..8a7a3106660d 100644 --- a/patches/unapplied/server/0312-Optimise-getChunkAt-calls-for-loaded-chunks.patch +++ b/patches/server/0309-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 a939bad7da9c852827a2d67d9ace5d0df4911a31..1049452baaf0381ffbf15b30da956c2a1994da35 100644 +index 3bbc7aa52a2ee797d6033684e73d6b307c2fadcc..4302d5119c43eb8de0c026162fc62ddeb5ab87cb 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -179,6 +179,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -191,6 +191,12 @@ public class ServerChunkCache extends ChunkSource { return this.getChunk(x, z, leastStatus, create); }, this.mainThreadProcessor).join(); } else { @@ -20,14 +20,14 @@ index a939bad7da9c852827a2d67d9ace5d0df4911a31..1049452baaf0381ffbf15b30da956c2a + return ifLoaded; + } + // Paper end - Perf: Optimise getChunkAt calls for loaded chunks - ProfilerFiller gameprofilerfiller = this.level.getProfiler(); + ProfilerFiller gameprofilerfiller = Profiler.get(); gameprofilerfiller.incrementCounter("getChunk"); -@@ -222,33 +228,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -234,33 +240,7 @@ public class ServerChunkCache extends ChunkSource { if (Thread.currentThread() != this.mainThread) { return null; } else { -- this.level.getProfiler().incrementCounter("getChunkNow"); +- Profiler.get().incrementCounter("getChunkNow"); - long k = ChunkPos.asLong(chunkX, chunkZ); - - ChunkAccess ichunkaccess; diff --git a/patches/unapplied/server/0313-Add-debug-for-sync-chunk-loads.patch b/patches/server/0310-Add-debug-for-sync-chunk-loads.patch similarity index 97% rename from patches/unapplied/server/0313-Add-debug-for-sync-chunk-loads.patch rename to patches/server/0310-Add-debug-for-sync-chunk-loads.patch index bf5532d58e85..73dc4103ebbe 100644 --- a/patches/unapplied/server/0313-Add-debug-for-sync-chunk-loads.patch +++ b/patches/server/0310-Add-debug-for-sync-chunk-loads.patch @@ -302,10 +302,10 @@ index 0000000000000000000000000000000000000000..95d6022c9cfb2e36ec5a71be6e343540 + } +} diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 1049452baaf0381ffbf15b30da956c2a1994da35..60f678c26fb5144386d8697ddfd5b6d841563b6f 100644 +index 4302d5119c43eb8de0c026162fc62ddeb5ab87cb..7e5714fea4cda68b9ae21031c0e0d39061b07e2f 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -206,6 +206,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -218,6 +218,7 @@ public class ServerChunkCache extends ChunkSource { Objects.requireNonNull(completablefuture); if (!completablefuture.isDone()) { // Paper @@ -314,10 +314,10 @@ index 1049452baaf0381ffbf15b30da956c2a1994da35..60f678c26fb5144386d8697ddfd5b6d8 chunkproviderserver_b.managedBlock(completablefuture::isDone); this.level.timings.syncChunkLoad.stopTiming(); // Paper diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index c85d5b941b5cb1c37cd2619d419006c5956f6eaf..f1fa4cb11f69e248dd55b8aa69f5d07268f182a1 100644 +index c7a1328e6642ad6c76179bddec117c4281577e86..e2984ccee4e01b260109d038969f9ff3ea21b87f 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -422,6 +422,13 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -412,6 +412,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit } diff --git a/patches/unapplied/server/0314-Improve-java-version-check.patch b/patches/server/0311-Improve-java-version-check.patch similarity index 95% rename from patches/unapplied/server/0314-Improve-java-version-check.patch rename to patches/server/0311-Improve-java-version-check.patch index 7814ffea5aa6..90af2b3b154a 100644 --- a/patches/unapplied/server/0314-Improve-java-version-check.patch +++ b/patches/server/0311-Improve-java-version-check.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Improve java version check Co-Authored-By: MiniDigger diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index bcc9d3b1503b1be1841c9ab40e879a1cbb0549f2..224b7f5394a568a3982f1e9a554e72af969fbe43 100644 +index 1efb42f7ad357f9b4185dea79106ccd38c9f5325..c618934b5cf66d9625c7be2ac114f1a1ca629d33 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -203,11 +203,20 @@ public class Main { diff --git a/patches/unapplied/server/0315-Add-ThrownEggHatchEvent.patch b/patches/server/0312-Add-ThrownEggHatchEvent.patch similarity index 90% rename from patches/unapplied/server/0315-Add-ThrownEggHatchEvent.patch rename to patches/server/0312-Add-ThrownEggHatchEvent.patch index 21fd12f38043..4f5c62f3e678 100644 --- a/patches/unapplied/server/0315-Add-ThrownEggHatchEvent.patch +++ b/patches/server/0312-Add-ThrownEggHatchEvent.patch @@ -7,10 +7,10 @@ Adds a new event similar to PlayerEggThrowEvent, but without the Player requirem (dispensers can throw eggs to hatch them, too). diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java -index 62850e899955732afdd255ea1e55fc84b7c6c96b..dbd60cc8c39f5d2d4c77e2de4f2567e7fa456cd2 100644 +index eb197a719177dcc1605ee0ff3c471ba91783f040..155c2bbd35adacb7c3668fbe81a7c454e5102c8b 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java -@@ -86,6 +86,13 @@ public class ThrownEgg extends ThrowableItemProjectile { +@@ -88,6 +88,13 @@ public class ThrownEgg extends ThrowableItemProjectile { } } // CraftBukkit end diff --git a/patches/unapplied/server/0316-Entity-Jump-API.patch b/patches/server/0313-Entity-Jump-API.patch similarity index 75% rename from patches/unapplied/server/0316-Entity-Jump-API.patch rename to patches/server/0313-Entity-Jump-API.patch index 9e2cba6a0a81..290c2cea302e 100644 --- a/patches/unapplied/server/0316-Entity-Jump-API.patch +++ b/patches/server/0313-Entity-Jump-API.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Entity Jump API public net.minecraft.world.entity.LivingEntity jumping diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 8ee6d25c3860fe7f2e5039c74c736d82eefda237..4c32b26e29ca3db0a2f62052e14bcc3e4c1cdea5 100644 +index f720d4d93ed13b1b9287a1ee7dc8bc4794834e1a..304a401fb1f378ff2cbfd888acf56a8516f79310 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3433,8 +3433,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3539,8 +3539,10 @@ public abstract class LivingEntity extends Entity implements Attackable { } else if (this.isInLava() && (!this.onGround() || d3 > d4)) { this.jumpInLiquid(FluidTags.LAVA); } else if ((this.onGround() || flag && d3 <= d4) && this.noJumpDelay == 0) { @@ -22,10 +22,10 @@ index 8ee6d25c3860fe7f2e5039c74c736d82eefda237..4c32b26e29ca3db0a2f62052e14bcc3e } else { this.noJumpDelay = 0; diff --git a/src/main/java/net/minecraft/world/entity/animal/Panda.java b/src/main/java/net/minecraft/world/entity/animal/Panda.java -index 228cfb77e12ed5979e422dc5dbb5e8dcf363b509..8df42121aa22ec9f95a1b8627b64b0ff71e36314 100644 +index 0b0887b7d2c69138617bee6ec3145f0a83b8734d..705c26ceff9371b09311bd7fa796c0efde7ebfee 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Panda.java +++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java -@@ -541,7 +541,9 @@ public class Panda extends Animal { +@@ -530,7 +530,9 @@ public class Panda extends Animal { Panda entitypanda = (Panda) iterator.next(); if (!entitypanda.isBaby() && entitypanda.onGround() && !entitypanda.isInWater() && entitypanda.canPerformAction()) { @@ -36,24 +36,24 @@ index 228cfb77e12ed5979e422dc5dbb5e8dcf363b509..8df42121aa22ec9f95a1b8627b64b0ff } diff --git a/src/main/java/net/minecraft/world/entity/monster/Ravager.java b/src/main/java/net/minecraft/world/entity/monster/Ravager.java -index 4d91bc4b90a208fec789325dbcec8cc56d1a2a8b..aa4111eef22546f8aa630228c51ef5761c9b373b 100644 +index 32973d9c7bf4c4105d7bd82d3723e0b70cd79644..c661ae4e5c07494c7de852cc8d01f0f9839c1590 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Ravager.java +++ b/src/main/java/net/minecraft/world/entity/monster/Ravager.java -@@ -160,7 +160,9 @@ public class Ravager extends Raider { - } +@@ -174,7 +174,9 @@ public class Ravager extends Raider { + } - if (!flag && this.onGround()) { -+ if (new com.destroystokyo.paper.event.entity.EntityJumpEvent(getBukkitLivingEntity()).callEvent()) { // Paper - Entity Jump API - this.jumpFromGround(); -+ } else { this.setJumping(false); } // Paper - Entity Jump API; setJumping(false) stops a potential loop + if (!flag && this.onGround()) { ++ if (new com.destroystokyo.paper.event.entity.EntityJumpEvent(getBukkitLivingEntity()).callEvent()) { // Paper - Entity Jump API + this.jumpFromGround(); ++ } else { this.setJumping(false); } // Paper - Entity Jump API; setJumping(false) stops a potential loop + } } } - diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index c0684f1864ece26b4f337ac615db04f615957c13..05ba1654ec02ff2b518251c128661e3d8dfa4c6d 100644 +index c4c83b4e17aac23794fdb51acfba4e7ef8451e2c..81034513faa3bd4f306430bc48532ba671a7b94b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -974,4 +974,20 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -993,4 +993,20 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(this.getHandle().getUsedItemHand()); } // Paper end - active item API diff --git a/patches/unapplied/server/0317-Add-option-to-nerf-pigmen-from-nether-portals.patch b/patches/server/0314-Add-option-to-nerf-pigmen-from-nether-portals.patch similarity index 73% rename from patches/unapplied/server/0317-Add-option-to-nerf-pigmen-from-nether-portals.patch rename to patches/server/0314-Add-option-to-nerf-pigmen-from-nether-portals.patch index 18fff797e7a3..81ec1db92d1f 100644 --- a/patches/unapplied/server/0317-Add-option-to-nerf-pigmen-from-nether-portals.patch +++ b/patches/server/0314-Add-option-to-nerf-pigmen-from-nether-portals.patch @@ -5,10 +5,10 @@ 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 9d56aff2766b684f0fb20e93d504de1a7a564b11..94242c19740ae6ab2c86e3949bab6cee631b938f 100644 +index 463d34e7b54efd503c4879d1386b2439474863dd..fa80b6220aba144521dc0a2a35914c10046c1963 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -403,6 +403,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -406,6 +406,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public void inactiveTick() { } // Spigot end protected int numCollisions = 0; // Paper - Cap entity collisions @@ -16,7 +16,7 @@ index 9d56aff2766b684f0fb20e93d504de1a7a564b11..94242c19740ae6ab2c86e3949bab6cee public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one // Paper start - Entity origin API @javax.annotation.Nullable -@@ -2282,6 +2283,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2398,6 +2399,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess if (spawnedViaMobSpawner) { nbttagcompound.putBoolean("Paper.FromMobSpawner", true); } @@ -26,7 +26,7 @@ index 9d56aff2766b684f0fb20e93d504de1a7a564b11..94242c19740ae6ab2c86e3949bab6cee // Paper end return nbttagcompound; } catch (Throwable throwable) { -@@ -2424,6 +2428,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2541,6 +2545,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } spawnedViaMobSpawner = nbt.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status @@ -35,15 +35,17 @@ index 9d56aff2766b684f0fb20e93d504de1a7a564b11..94242c19740ae6ab2c86e3949bab6cee String spawnReasonName = nbt.getString("Paper.SpawnReason"); try { diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java -index 8072e67f7b2f5944670159d3de1b01090bd1019d..a4e1c878dc7677e8ccc7c568ab455e85513d86cb 100644 +index 5d4c0d7fec42bf843b11875f7a09bcb9279b3b54..dea13596eb8a3b7bc69c19545b2227b4c45ed241 100644 --- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java -@@ -88,6 +88,8 @@ public class NetherPortalBlock extends Block implements Portal { +@@ -89,6 +89,10 @@ public class NetherPortalBlock extends Block implements Portal { if (entity != null) { entity.setPortalCooldown(); -+ entity.fromNetherPortal = true; // Paper - Add option to nerf pigmen from nether portals -+ if (world.paperConfig().entities.behavior.nerfPigmenFromNetherPortals) ((net.minecraft.world.entity.Mob) entity).aware = false; // Paper - Add option to nerf pigmen from nether portals - } - } - } ++ // Paper start - Add option to nerf pigmen from nether portals ++ entity.fromNetherPortal = true; ++ if (world.paperConfig().entities.behavior.nerfPigmenFromNetherPortals) ((net.minecraft.world.entity.Mob) entity).aware = false; ++ // Paper end - Add option to nerf pigmen from nether portals + Entity entity1 = entity.getVehicle(); + + if (entity1 != null) { diff --git a/patches/unapplied/server/0318-Make-the-GUI-graph-fancier.patch b/patches/server/0315-Make-the-GUI-graph-fancier.patch similarity index 100% rename from patches/unapplied/server/0318-Make-the-GUI-graph-fancier.patch rename to patches/server/0315-Make-the-GUI-graph-fancier.patch diff --git a/patches/unapplied/server/0319-add-hand-to-BlockMultiPlaceEvent.patch b/patches/server/0316-add-hand-to-BlockMultiPlaceEvent.patch similarity index 89% rename from patches/unapplied/server/0319-add-hand-to-BlockMultiPlaceEvent.patch rename to patches/server/0316-add-hand-to-BlockMultiPlaceEvent.patch index 078a0ba255de..d0fe787da6ad 100644 --- a/patches/unapplied/server/0319-add-hand-to-BlockMultiPlaceEvent.patch +++ b/patches/server/0316-add-hand-to-BlockMultiPlaceEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] add hand to BlockMultiPlaceEvent diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 8172a75aef7c3dcdd92817f148466a4cad4c78ed..235ac5c12dab593da3a40e348a010ff626ce74a3 100644 +index 834516cac1f3ac5f078dd4e4dfa449f39462658c..41f23ce732b6e90828b1bbda7f4b3470cd462c4a 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -412,13 +412,18 @@ public class CraftEventFactory { +@@ -411,13 +411,18 @@ public class CraftEventFactory { } org.bukkit.inventory.ItemStack item; diff --git a/patches/unapplied/server/0320-Validate-tripwire-hook-placement-before-update.patch b/patches/server/0317-Validate-tripwire-hook-placement-before-update.patch similarity index 86% rename from patches/unapplied/server/0320-Validate-tripwire-hook-placement-before-update.patch rename to patches/server/0317-Validate-tripwire-hook-placement-before-update.patch index bc1125b169f9..b607c1afe96f 100644 --- a/patches/unapplied/server/0320-Validate-tripwire-hook-placement-before-update.patch +++ b/patches/server/0317-Validate-tripwire-hook-placement-before-update.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Validate tripwire hook placement before update diff --git a/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java b/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java -index bc4d324f086d815c139408629a561ea4d94c839b..8614fad5b3df7a6030384b108b1689bf6b9f1209 100644 +index 1240f18b3d40f8bde2346c893304ae340a727e24..c2589f42c467ca672417c24076313da51bb2dcbb 100644 --- a/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java -@@ -189,6 +189,7 @@ public class TripWireHookBlock extends Block { +@@ -191,6 +191,7 @@ public class TripWireHookBlock extends Block { TripWireHookBlock.emitState(world, pos, flag4, flag5, flag2, flag3); if (!flag) { diff --git a/patches/unapplied/server/0321-Add-option-to-allow-iron-golems-to-spawn-in-air.patch b/patches/server/0318-Add-option-to-allow-iron-golems-to-spawn-in-air.patch similarity index 86% rename from patches/unapplied/server/0321-Add-option-to-allow-iron-golems-to-spawn-in-air.patch rename to patches/server/0318-Add-option-to-allow-iron-golems-to-spawn-in-air.patch index 75d1d9c02bdc..8991de1b700c 100644 --- a/patches/unapplied/server/0321-Add-option-to-allow-iron-golems-to-spawn-in-air.patch +++ b/patches/server/0318-Add-option-to-allow-iron-golems-to-spawn-in-air.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add option to allow iron golems to spawn in air diff --git a/src/main/java/net/minecraft/world/entity/animal/IronGolem.java b/src/main/java/net/minecraft/world/entity/animal/IronGolem.java -index 615be0b85fb3d28a044c6bae6a0fe93ec4fca061..1807da10d07d1f6e4ddbc0fa1b8da34a688d67c3 100644 +index dac63f51fc23cc7f35ee299d1e04c96c210db52b..e07b79ef172095c1800c88342b3ac8dc7703aea2 100644 --- a/src/main/java/net/minecraft/world/entity/animal/IronGolem.java +++ b/src/main/java/net/minecraft/world/entity/animal/IronGolem.java -@@ -325,7 +325,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { +@@ -319,7 +319,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { BlockPos blockposition1 = blockposition.below(); BlockState iblockdata = world.getBlockState(blockposition1); diff --git a/patches/unapplied/server/0322-Configurable-chance-of-villager-zombie-infection.patch b/patches/server/0319-Configurable-chance-of-villager-zombie-infection.patch similarity index 81% rename from patches/unapplied/server/0322-Configurable-chance-of-villager-zombie-infection.patch rename to patches/server/0319-Configurable-chance-of-villager-zombie-infection.patch index 217787cdc98a..d71db6d82415 100644 --- a/patches/unapplied/server/0322-Configurable-chance-of-villager-zombie-infection.patch +++ b/patches/server/0319-Configurable-chance-of-villager-zombie-infection.patch @@ -8,10 +8,10 @@ This allows you to solve an issue in vanilla behavior where: * On normal difficulty they will have a 50% of getting infected or dying. diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index d981f8679149669f6ca4ea950d744149974532b2..e2a3978899497b6622829d6577cfaa723092da9d 100644 +index 81d27114bd081096612e50a8cb93cae772cf46eb..2ed71c9a091bedea276f9043fb0c082dd250cdae 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -@@ -454,10 +454,8 @@ public class Zombie extends Monster { +@@ -484,10 +484,8 @@ public class Zombie extends Monster { public boolean killedEntity(ServerLevel world, LivingEntity other) { boolean flag = super.killedEntity(world, other); @@ -21,6 +21,6 @@ index d981f8679149669f6ca4ea950d744149974532b2..e2a3978899497b6622829d6577cfaa72 - } + final double fallbackChance = world.getDifficulty() == Difficulty.HARD ? 100d : world.getDifficulty() == Difficulty.NORMAL ? 50d : 0d; // Paper - Configurable chance of villager zombie infection + if (this.random.nextDouble() * 100 < world.paperConfig().entities.behavior.zombieVillagerInfectionChance.or(fallbackChance) && other instanceof Villager entityvillager) { // Paper - Configurable chance of villager zombie infection - // CraftBukkit start - flag = Zombie.zombifyVillager(world, entityvillager, this.blockPosition(), this.isSilent(), CreatureSpawnEvent.SpawnReason.INFECTION) == null; - } + + if (this.convertVillagerToZombieVillager(world, entityvillager)) { + flag = false; diff --git a/patches/unapplied/server/0323-Optimise-Chunk-getFluid.patch b/patches/server/0320-Optimise-Chunk-getFluid.patch similarity index 88% rename from patches/unapplied/server/0323-Optimise-Chunk-getFluid.patch rename to patches/server/0320-Optimise-Chunk-getFluid.patch index 8142952ce69e..1126b881da2f 100644 --- a/patches/unapplied/server/0323-Optimise-Chunk-getFluid.patch +++ b/patches/server/0320-Optimise-Chunk-getFluid.patch @@ -8,10 +8,10 @@ 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 6775217c065026aa61fce56a17c93010209b6941..59f9ff720e92c69e11afe7f6ccecd81b0e54a74d 100644 +index add5ec0f8e8bd0b89511dcb656e1d4cda702a86b..7181acfafad91aa5f6ab7ce663d9be4a1b65b02a 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -270,18 +270,20 @@ public class LevelChunk extends ChunkAccess { +@@ -293,18 +293,20 @@ public class LevelChunk extends ChunkAccess { } public FluidState getFluidState(int x, int y, int z) { @@ -38,7 +38,7 @@ index 6775217c065026aa61fce56a17c93010209b6941..59f9ff720e92c69e11afe7f6ccecd81b } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Getting fluid state"); CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Block being got"); -@@ -291,6 +293,7 @@ public class LevelChunk extends ChunkAccess { +@@ -314,6 +316,7 @@ public class LevelChunk extends ChunkAccess { }); throw new ReportedException(crashreport); } @@ -47,10 +47,10 @@ index 6775217c065026aa61fce56a17c93010209b6941..59f9ff720e92c69e11afe7f6ccecd81b // CraftBukkit start diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -index 2c153af611399e884752f8256bee4fe32de5c572..90d1c3e23e753c29660f7d993b3c90ac022941c3 100644 +index 771529ba28a16664ad19ed9c0f4bf95eeb7da76b..52f44f14bbda60fe771c351e01e6ff470d7371e6 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -@@ -43,7 +43,7 @@ public class LevelChunkSection { +@@ -49,7 +49,7 @@ public class LevelChunkSection { } public FluidState getFluidState(int x, int y, int z) { diff --git a/patches/unapplied/server/0324-Set-spigots-verbose-world-setting-to-false-by-def.patch b/patches/server/0321-Set-spigots-verbose-world-setting-to-false-by-def.patch similarity index 100% rename from patches/unapplied/server/0324-Set-spigots-verbose-world-setting-to-false-by-def.patch rename to patches/server/0321-Set-spigots-verbose-world-setting-to-false-by-def.patch diff --git a/patches/unapplied/server/0325-Add-tick-times-API-and-mspt-command.patch b/patches/server/0322-Add-tick-times-API-and-mspt-command.patch similarity index 91% rename from patches/unapplied/server/0325-Add-tick-times-API-and-mspt-command.patch rename to patches/server/0322-Add-tick-times-API-and-mspt-command.patch index b8fd4a8f65e7..d0480d54b792 100644 --- a/patches/unapplied/server/0325-Add-tick-times-API-and-mspt-command.patch +++ b/patches/server/0322-Add-tick-times-API-and-mspt-command.patch @@ -125,10 +125,10 @@ index 72f2e81b9905a0d57ed8e2a88578f62d5235c456..7b58b2d6297800c2dcdbf7539e5ab8e7 public static void registerCommands(final MinecraftServer server) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index ddc3da84c5a55d2cd977fcdb18121351606a6b3c..53bb62c1dcb487be915759d22e06aea80be54f36 100644 +index 5f84618775d66d50557fa71f77fa322c2d1da791..708552756a33339ce9eefe48c9999a2ec08f7e1c 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -258,6 +258,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop +Date: Tue, 17 Mar 2020 14:18:50 -0500 +Subject: [PATCH] Do not allow Vexes to load chunks + + +diff --git a/src/main/java/net/minecraft/world/entity/monster/Vex.java b/src/main/java/net/minecraft/world/entity/monster/Vex.java +index 1a5a61f3c6587992acadc83d5dff97ae2fe53235..183a33b7d666d652b455baa7e8339e9c4a870a58 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/Vex.java ++++ b/src/main/java/net/minecraft/world/entity/monster/Vex.java +@@ -354,7 +354,10 @@ public class Vex extends Monster implements TraceableEntity { + for (int i = 0; i < 3; ++i) { + BlockPos blockposition1 = blockposition.offset(Vex.this.random.nextInt(15) - 7, Vex.this.random.nextInt(11) - 5, Vex.this.random.nextInt(15) - 7); + +- if (Vex.this.level().isEmptyBlock(blockposition1)) { ++ // Paper start - Don't load chunks ++ final net.minecraft.world.level.block.state.BlockState blockState = Vex.this.level().getBlockStateIfLoaded(blockposition1); ++ if (blockState != null && blockState.isAir()) { ++ // Paper end - Don't load chunks + Vex.this.moveControl.setWantedPosition((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.5D, (double) blockposition1.getZ() + 0.5D, 0.25D); + if (Vex.this.getTarget() == null) { + Vex.this.getLookControl().setLookAt((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.5D, (double) blockposition1.getZ() + 0.5D, 180.0F, 20.0F); diff --git a/patches/unapplied/server/0302-Prevent-bees-loading-chunks-checking-hive-position.patch b/patches/unapplied/server/0302-Prevent-bees-loading-chunks-checking-hive-position.patch deleted file mode 100644 index e933516d42fc..000000000000 --- a/patches/unapplied/server/0302-Prevent-bees-loading-chunks-checking-hive-position.patch +++ /dev/null @@ -1,18 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sun, 5 Jan 2020 17:24:34 -0600 -Subject: [PATCH] Prevent bees loading chunks checking hive position - - -diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java -index 048d03c8ef3ef865641b2276477cf84e8d4397a1..58536ee8707c5ad0625cae2f26a58cf03b3f85d7 100644 ---- a/src/main/java/net/minecraft/world/entity/animal/Bee.java -+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java -@@ -510,6 +510,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { - } else if (this.isTooFarAway(this.hivePos)) { - return false; - } else { -+ if (this.level().getChunkIfLoadedImmediately(this.hivePos.getX() >> 4, this.hivePos.getZ() >> 4) == null) return true; // Paper - just assume the hive is still there, no need to load the chunk(s) - BlockEntity tileentity = this.level().getBlockEntity(this.hivePos); - - return tileentity != null && tileentity.getType() == BlockEntityType.BEEHIVE; diff --git a/patches/unapplied/server/0307-Guard-against-serializing-mismatching-chunk-coordina.patch b/patches/unapplied/server/0307-Guard-against-serializing-mismatching-chunk-coordina.patch deleted file mode 100644 index 6752b44617db..000000000000 --- a/patches/unapplied/server/0307-Guard-against-serializing-mismatching-chunk-coordina.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Fri, 27 Dec 2019 09:42:26 -0800 -Subject: [PATCH] Guard against serializing mismatching chunk coordinate - -Should help if something dumb happens - -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index 47f5f3d58bb3bf85cf35f9baae77df7fab5c844f..0dd6f1bce4913cb84ba21a20df5573bab3a64645 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -@@ -88,8 +88,21 @@ public class ChunkSerializer { - - public ChunkSerializer() {} - -+ // Paper start - guard against serializing mismatching coordinates -+ // TODO Note: This needs to be re-checked each update -+ public static ChunkPos getChunkCoordinate(final CompoundTag chunkData) { -+ final int dataVersion = ChunkStorage.getVersion(chunkData); -+ if (dataVersion < 2842) { // Level tag is removed after this version -+ final CompoundTag levelData = chunkData.getCompound("Level"); -+ return new ChunkPos(levelData.getInt("xPos"), levelData.getInt("zPos")); -+ } else { -+ return new ChunkPos(chunkData.getInt("xPos"), chunkData.getInt("zPos")); -+ } -+ } -+ // Paper end - guard against serializing mismatching coordinates -+ - public static ProtoChunk read(ServerLevel world, PoiManager poiStorage, RegionStorageInfo key, ChunkPos chunkPos, CompoundTag nbt) { -- ChunkPos chunkcoordintpair1 = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos")); -+ ChunkPos chunkcoordintpair1 = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos")); // Paper - guard against serializing mismatching coordinates; diff on change, see ChunkSerializer#getChunkCoordinate - - if (!Objects.equals(chunkPos, chunkcoordintpair1)) { - ChunkSerializer.LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", new Object[]{chunkPos, chunkPos, chunkcoordintpair1}); -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -index 3e194944e50f8395074d68d4abe4c084c3fadcc1..9aa9ab894080a5819fc45698771afd034906d36a 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -@@ -172,6 +172,13 @@ public class ChunkStorage implements AutoCloseable { - } - - public CompletableFuture write(ChunkPos chunkPos, CompoundTag nbt) { -+ // Paper start - guard against serializing mismatching coordinates -+ if (nbt != null && !chunkPos.equals(ChunkSerializer.getChunkCoordinate(nbt))) { -+ final String world = (this instanceof net.minecraft.server.level.ChunkMap) ? ((net.minecraft.server.level.ChunkMap) this).level.getWorld().getName() : null; -+ throw new IllegalArgumentException("Chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + chunkPos -+ + " but compound says coordinate is " + ChunkSerializer.getChunkCoordinate(nbt) + (world == null ? " for an unknown world" : (" for world: " + world))); -+ } -+ // Paper end - guard against serializing mismatching coordinates - this.handleLegacyStructureIndex(chunkPos); - return this.worker.store(chunkPos, nbt); - } diff --git a/patches/unapplied/server/0330-Do-not-allow-bees-to-load-chunks-for-beehives.patch b/patches/unapplied/server/0330-Do-not-allow-bees-to-load-chunks-for-beehives.patch deleted file mode 100644 index f361af6e505e..000000000000 --- a/patches/unapplied/server/0330-Do-not-allow-bees-to-load-chunks-for-beehives.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: chickeneer -Date: Tue, 17 Mar 2020 14:18:50 -0500 -Subject: [PATCH] Do not allow bees to load chunks for beehives - - -diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java -index 4134ee48909110f8c338f5d553d4cc1e9e31aaba..615b57fac9def18d9dcaefcfe397c74c11cac627 100644 ---- a/src/main/java/net/minecraft/world/entity/animal/Bee.java -+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java -@@ -421,6 +421,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { - if (this.hivePos == null) { - return false; - } else { -+ if (!this.level().isLoadedAndInBounds(this.hivePos)) return false; // Paper - Do not allow bees to load chunks for beehives - BlockEntity tileentity = this.level().getBlockEntity(this.hivePos); - - return tileentity instanceof BeehiveBlockEntity && ((BeehiveBlockEntity) tileentity).isFireNearby(); -@@ -454,6 +455,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { - } - - private boolean doesHiveHaveSpace(BlockPos pos) { -+ if (!this.level().isLoadedAndInBounds(pos)) return false; // Paper - Do not allow bees to load chunks for beehives - BlockEntity tileentity = this.level().getBlockEntity(pos); - - return tileentity instanceof BeehiveBlockEntity ? !((BeehiveBlockEntity) tileentity).isFull() : false; -@@ -924,6 +926,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { - @Override - public boolean canBeeUse() { - if (Bee.this.hasHive() && Bee.this.wantsToEnterHive() && Bee.this.hivePos.closerToCenterThan(Bee.this.position(), 2.0D)) { -+ if (!Bee.this.level().isLoadedAndInBounds(Bee.this.hivePos)) return false; // Paper - Do not allow bees to load chunks for beehives - BlockEntity tileentity = Bee.this.level().getBlockEntity(Bee.this.hivePos); - - if (tileentity instanceof BeehiveBlockEntity) { -@@ -947,6 +950,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { - - @Override - public void start() { -+ if (!Bee.this.level().isLoadedAndInBounds(Bee.this.hivePos)) return; // Paper - Do not allow bees to load chunks for beehives - BlockEntity tileentity = Bee.this.level().getBlockEntity(Bee.this.hivePos); - - if (tileentity instanceof BeehiveBlockEntity tileentitybeehive) { -diff --git a/src/main/java/net/minecraft/world/entity/monster/Vex.java b/src/main/java/net/minecraft/world/entity/monster/Vex.java -index d6f73c719d58970c6d13340f78c3303916b46546..2985296a9a034e535157f55e322fc8c107827752 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/Vex.java -+++ b/src/main/java/net/minecraft/world/entity/monster/Vex.java -@@ -356,7 +356,10 @@ public class Vex extends Monster implements TraceableEntity { - for (int i = 0; i < 3; ++i) { - BlockPos blockposition1 = blockposition.offset(Vex.this.random.nextInt(15) - 7, Vex.this.random.nextInt(11) - 5, Vex.this.random.nextInt(15) - 7); - -- if (Vex.this.level().isEmptyBlock(blockposition1)) { -+ // Paper start - Don't load chunks -+ final net.minecraft.world.level.block.state.BlockState blockState = Vex.this.level().getBlockStateIfLoaded(blockposition1); -+ if (blockState != null && blockState.isAir()) { -+ // Paper end - Don't load chunks - Vex.this.moveControl.setWantedPosition((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.5D, (double) blockposition1.getZ() + 0.5D, 0.25D); - if (Vex.this.getTarget() == null) { - Vex.this.getLookControl().setLookAt((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.5D, (double) blockposition1.getZ() + 0.5D, 180.0F, 20.0F); From af125d26a94147ff40555819d5a9687d24b65d50 Mon Sep 17 00:00:00 2001 From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Date: Wed, 23 Oct 2024 10:04:01 -0400 Subject: [PATCH 018/119] Patch --- ...PlayerChunkMap-adds-crashing-server.patch} | 10 +-- .../0329-Don-t-tick-dead-players.patch} | 4 +- ...-Player-s-shouldn-t-be-able-to-move.patch} | 4 +- ...ove-existing-players-to-world-spawn.patch} | 10 +-- .../0332-Optimize-Pathfinding.patch} | 4 +- ...3-Reduce-Either-Optional-allocation.patch} | 0 ...uce-memory-footprint-of-CompoundTag.patch} | 0 ...ent-opening-inventories-when-frozen.patch} | 12 ++-- ...entity-collision-code-if-not-needed.patch} | 10 +-- ...Implement-Player-Client-Options-API.patch} | 12 ++-- ...ayer-is-attempted-to-be-removed-fro.patch} | 4 +- ...Event-when-Player-is-actually-ready.patch} | 38 ++++------- ...awn-point-if-spawn-in-unloaded-worl.patch} | 12 ++-- ...layerAttackEntityCooldownResetEvent.patch} | 4 +- ...-fire-BlockFade-on-worldgen-threads.patch} | 6 +- ...tom-creative-and-insomniac-controls.patch} | 14 ++-- ...tem-duplication-and-teleport-issues.patch} | 66 +++++++++---------- .../0345-Villager-Restocks-API.patch} | 4 +- ...ickItem-Packet-and-kick-for-invalid.patch} | 10 +-- ...per-thread-native-byte-buffer-cache.patch} | 2 +- .../0348-misc-debugging-dumps.patch} | 16 ++--- ...9-Prevent-teleporting-dead-entities.patch} | 12 ++-- 22 files changed, 120 insertions(+), 134 deletions(-) rename patches/{unapplied/server/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch => server/0328-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch} (86%) rename patches/{unapplied/server/0332-Don-t-tick-dead-players.patch => server/0329-Don-t-tick-dead-players.patch} (85%) rename patches/{unapplied/server/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch => server/0330-Dead-Player-s-shouldn-t-be-able-to-move.patch} (84%) rename patches/{unapplied/server/0334-Don-t-move-existing-players-to-world-spawn.patch => server/0331-Don-t-move-existing-players-to-world-spawn.patch} (87%) rename patches/{unapplied/server/0335-Optimize-Pathfinding.patch => server/0332-Optimize-Pathfinding.patch} (92%) rename patches/{unapplied/server/0336-Reduce-Either-Optional-allocation.patch => server/0333-Reduce-Either-Optional-allocation.patch} (100%) rename patches/{unapplied/server/0337-Reduce-memory-footprint-of-CompoundTag.patch => server/0334-Reduce-memory-footprint-of-CompoundTag.patch} (100%) rename patches/{unapplied/server/0338-Prevent-opening-inventories-when-frozen.patch => server/0335-Prevent-opening-inventories-when-frozen.patch} (89%) rename patches/{unapplied/server/0339-Don-t-run-entity-collision-code-if-not-needed.patch => server/0336-Don-t-run-entity-collision-code-if-not-needed.patch} (82%) rename patches/{unapplied/server/0340-Implement-Player-Client-Options-API.patch => server/0337-Implement-Player-Client-Options-API.patch} (95%) rename patches/{unapplied/server/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch => server/0338-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch} (88%) rename patches/{unapplied/server/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch => server/0339-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch} (73%) rename patches/{unapplied/server/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch => server/0340-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch} (93%) rename patches/{unapplied/server/0344-Add-PlayerAttackEntityCooldownResetEvent.patch => server/0341-Add-PlayerAttackEntityCooldownResetEvent.patch} (92%) rename patches/{unapplied/server/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch => server/0342-Don-t-fire-BlockFade-on-worldgen-threads.patch} (79%) rename patches/{unapplied/server/0346-Add-phantom-creative-and-insomniac-controls.patch => server/0343-Add-phantom-creative-and-insomniac-controls.patch} (82%) rename patches/{unapplied/server/0347-Fix-item-duplication-and-teleport-issues.patch => server/0344-Fix-item-duplication-and-teleport-issues.patch} (76%) rename patches/{unapplied/server/0348-Villager-Restocks-API.patch => server/0345-Villager-Restocks-API.patch} (87%) rename patches/{unapplied/server/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch => server/0346-Validate-PickItem-Packet-and-kick-for-invalid.patch} (68%) rename patches/{unapplied/server/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch => server/0347-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch} (93%) rename patches/{unapplied/server/0351-misc-debugging-dumps.patch => server/0348-misc-debugging-dumps.patch} (91%) rename patches/{unapplied/server/0352-Prevent-teleporting-dead-entities.patch => server/0349-Prevent-teleporting-dead-entities.patch} (67%) diff --git a/patches/unapplied/server/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch b/patches/server/0328-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch similarity index 86% rename from patches/unapplied/server/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch rename to patches/server/0328-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch index e7c3500d183d..538add849398 100644 --- a/patches/unapplied/server/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch +++ b/patches/server/0328-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 ee54706b36bd227edacea2a1b6099009bd652039..8206ec366b429858d9582e437781191e5aa0fa02 100644 +index b849d24144dc9f7d24484398cec3b2b90befb507..f3b99cd96672363e0d60e56b744f0bea8fa00c3f 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1241,6 +1241,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1300,6 +1300,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider public void addEntity(Entity entity) { org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot @@ -25,10 +25,10 @@ index ee54706b36bd227edacea2a1b6099009bd652039..8206ec366b429858d9582e437781191e 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 b465f05d78e79ffbf70114b18204d85d32761c67..5b89d834a7c01530807e61ea25af2b01f004ce86 100644 +index e2984ccee4e01b260109d038969f9ff3ea21b87f..090d2fde891346ee634a8964b562715f4dd206d0 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2151,7 +2151,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2232,7 +2232,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public void onTrackingStart(Entity entity) { org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot @@ -37,7 +37,7 @@ index b465f05d78e79ffbf70114b18204d85d32761c67..5b89d834a7c01530807e61ea25af2b01 if (entity instanceof ServerPlayer entityplayer) { ServerLevel.this.players.add(entityplayer); ServerLevel.this.updateSleepingPlayerList(); -@@ -2181,6 +2181,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2262,6 +2262,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe entity.updateDynamicGameEventListener(DynamicGameEventListener::add); entity.inWorld = true; // CraftBukkit - Mark entity as in world entity.valid = true; // CraftBukkit diff --git a/patches/unapplied/server/0332-Don-t-tick-dead-players.patch b/patches/server/0329-Don-t-tick-dead-players.patch similarity index 85% rename from patches/unapplied/server/0332-Don-t-tick-dead-players.patch rename to patches/server/0329-Don-t-tick-dead-players.patch index 0633c8502c6d..511d5ca03749 100644 --- a/patches/unapplied/server/0332-Don-t-tick-dead-players.patch +++ b/patches/server/0329-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 d4bda65d10bee880a341196364db63523f36e380..47982f87ce93658c73ee3d7a5f7dd680e2f9aa36 100644 +index ea8279637a2af4d18c9decbf3342b058edeffd73..965ca28a8877f5e541741c45bace7075d15a77d7 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -765,7 +765,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -993,7 +993,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { public void doTick() { try { diff --git a/patches/unapplied/server/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch b/patches/server/0330-Dead-Player-s-shouldn-t-be-able-to-move.patch similarity index 84% rename from patches/unapplied/server/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch rename to patches/server/0330-Dead-Player-s-shouldn-t-be-able-to-move.patch index d10a5a50c4a5..068a5a06f9b9 100644 --- a/patches/unapplied/server/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch +++ b/patches/server/0330-Dead-Player-s-shouldn-t-be-able-to-move.patch @@ -7,10 +7,10 @@ This fixes a lot of game state issues where packets were delayed for processing due to 1.15's new queue but processed while dead. diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index fa906334a1c569748d3f2dc073ec03a85bd09d3b..cb89b020d93ac838843ec2cbad562326a1e4257b 100644 +index 4d8929a1f5390af10fbde1dcc13c0136b0a3a745..917ac21794f1aabc6e95ab2fff2ea7547b9778a8 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -1173,7 +1173,7 @@ public abstract class Player extends LivingEntity { +@@ -1143,7 +1143,7 @@ public abstract class Player extends LivingEntity { @Override protected boolean isImmobile() { diff --git a/patches/unapplied/server/0334-Don-t-move-existing-players-to-world-spawn.patch b/patches/server/0331-Don-t-move-existing-players-to-world-spawn.patch similarity index 87% rename from patches/unapplied/server/0334-Don-t-move-existing-players-to-world-spawn.patch rename to patches/server/0331-Don-t-move-existing-players-to-world-spawn.patch index 4c59557ecb19..6750b4fb1af6 100644 --- a/patches/unapplied/server/0334-Don-t-move-existing-players-to-world-spawn.patch +++ b/patches/server/0331-Don-t-move-existing-players-to-world-spawn.patch @@ -13,10 +13,10 @@ By skipping this, we avoid potential for a large spike on server start. public net.minecraft.server.level.ServerPlayer fudgeSpawnLocation(Lnet/minecraft/server/level/ServerLevel;)V diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 47982f87ce93658c73ee3d7a5f7dd680e2f9aa36..f8d4bd18f98ed914e116d0cc4a80140e4e8d759f 100644 +index 965ca28a8877f5e541741c45bace7075d15a77d7..adbc8e74f0b454403bc682de11bd0342e9bb6c2c 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -358,7 +358,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -419,7 +419,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.server = server; this.stats = server.getPlayerList().getPlayerStats(this); this.advancements = server.getPlayerList().getPlayerAdvancements(this); @@ -25,7 +25,7 @@ index 47982f87ce93658c73ee3d7a5f7dd680e2f9aa36..f8d4bd18f98ed914e116d0cc4a80140e this.updateOptions(clientOptions); this.object = null; -@@ -628,7 +628,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -856,7 +856,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { position = Vec3.atCenterOf(world.getSharedSpawnPos()); } this.setLevel(world); @@ -35,10 +35,10 @@ index 47982f87ce93658c73ee3d7a5f7dd680e2f9aa36..f8d4bd18f98ed914e116d0cc4a80140e 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 8cd80ea83ddcfd5052c8d8c19d3edb42538d1e15..2cbdcdf0349e7efa797802d0d339d158153690af 100644 +index 29110c0b950c3073ab699d8ad1523ece2e8d3408..074f3518b060c4aa079b1d311b7fcb10d4a95981 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -226,6 +226,7 @@ public abstract class PlayerList { +@@ -227,6 +227,7 @@ public abstract class PlayerList { // Paper start - Entity#getEntitySpawnReason if (optional.isEmpty()) { player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login diff --git a/patches/unapplied/server/0335-Optimize-Pathfinding.patch b/patches/server/0332-Optimize-Pathfinding.patch similarity index 92% rename from patches/unapplied/server/0335-Optimize-Pathfinding.patch rename to patches/server/0332-Optimize-Pathfinding.patch index 281988ce371e..76c7c6e42333 100644 --- a/patches/unapplied/server/0335-Optimize-Pathfinding.patch +++ b/patches/server/0332-Optimize-Pathfinding.patch @@ -7,10 +7,10 @@ Prevents pathfinding from spamming failures for things such as arrow attacks. diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java -index 188904c9f0f81db1d63eec953d6746f2dc23dc81..2e9991e6b3c05584002744a2ee2579b1dba218b2 100644 +index 436812c3bfe53358b4d76bb72d777d6661bb6d60..48c0de870a5bbf647309e69361dfb10ab56c65ab 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java -@@ -192,13 +192,33 @@ public abstract class PathNavigation { +@@ -209,13 +209,33 @@ public abstract class PathNavigation { return this.moveTo(this.createPath(x, y, z, 1), speed); } diff --git a/patches/unapplied/server/0336-Reduce-Either-Optional-allocation.patch b/patches/server/0333-Reduce-Either-Optional-allocation.patch similarity index 100% rename from patches/unapplied/server/0336-Reduce-Either-Optional-allocation.patch rename to patches/server/0333-Reduce-Either-Optional-allocation.patch diff --git a/patches/unapplied/server/0337-Reduce-memory-footprint-of-CompoundTag.patch b/patches/server/0334-Reduce-memory-footprint-of-CompoundTag.patch similarity index 100% rename from patches/unapplied/server/0337-Reduce-memory-footprint-of-CompoundTag.patch rename to patches/server/0334-Reduce-memory-footprint-of-CompoundTag.patch diff --git a/patches/unapplied/server/0338-Prevent-opening-inventories-when-frozen.patch b/patches/server/0335-Prevent-opening-inventories-when-frozen.patch similarity index 89% rename from patches/unapplied/server/0338-Prevent-opening-inventories-when-frozen.patch rename to patches/server/0335-Prevent-opening-inventories-when-frozen.patch index 3f6f9857e63f..de2065861e64 100644 --- a/patches/unapplied/server/0338-Prevent-opening-inventories-when-frozen.patch +++ b/patches/server/0335-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 f8d4bd18f98ed914e116d0cc4a80140e4e8d759f..7daa310dd5d3eb1befb9983ce85e0354771af71d 100644 +index adbc8e74f0b454403bc682de11bd0342e9bb6c2c..363175d3325c012f31ba84060bb0bfac694f6ab8 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -710,7 +710,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -938,7 +938,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { containerUpdateDelay = this.level().paperConfig().tickRates.containerUpdate; } // Paper end - Configurable container update tick rate @@ -17,7 +17,7 @@ index f8d4bd18f98ed914e116d0cc4a80140e4e8d759f..7daa310dd5d3eb1befb9983ce85e0354 this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper - Inventory close reason this.containerMenu = this.inventoryMenu; } -@@ -1634,7 +1634,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1903,7 +1903,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } else { // CraftBukkit start this.containerMenu = container; @@ -27,10 +27,10 @@ index f8d4bd18f98ed914e116d0cc4a80140e4e8d759f..7daa310dd5d3eb1befb9983ce85e0354 this.initMenu(container); return OptionalInt.of(this.containerCounter); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index ee7cf7f1d491ffdf26c3f156d299e2f517a05608..ba63c58d40cb3b8655fdb8177c423c67ac7cc3ef 100644 +index 5ff159be1a6dfb4b1a5b9aa1e435d294f205215e..6ec6b80d224e2402054afb85b78c793942a58bbf 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -@@ -334,7 +334,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { +@@ -335,7 +335,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { if (adventure$title == null) adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(container.getBukkitView().getTitle()); // Paper //player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment @@ -39,7 +39,7 @@ index ee7cf7f1d491ffdf26c3f156d299e2f517a05608..ba63c58d40cb3b8655fdb8177c423c67 player.containerMenu = container; player.initMenu(container); } -@@ -409,7 +409,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { +@@ -410,7 +410,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { net.kyori.adventure.text.Component adventure$title = inventory.title(); // Paper if (adventure$title == null) adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(inventory.getTitle()); // Paper //player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment diff --git a/patches/unapplied/server/0339-Don-t-run-entity-collision-code-if-not-needed.patch b/patches/server/0336-Don-t-run-entity-collision-code-if-not-needed.patch similarity index 82% rename from patches/unapplied/server/0339-Don-t-run-entity-collision-code-if-not-needed.patch rename to patches/server/0336-Don-t-run-entity-collision-code-if-not-needed.patch index 4e134e507c1a..43b1d500a9d4 100644 --- a/patches/unapplied/server/0339-Don-t-run-entity-collision-code-if-not-needed.patch +++ b/patches/server/0336-Don-t-run-entity-collision-code-if-not-needed.patch @@ -12,11 +12,11 @@ The entity's current team collision rule causes them to NEVER collide. Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 4c32b26e29ca3db0a2f62052e14bcc3e4c1cdea5..cf18f17f181bc94a2b5f4ac6926c2388ec3178c8 100644 +index 304a401fb1f378ff2cbfd888acf56a8516f79310..6ff464fef1f79cff9212135a30adcc6cb8792ed6 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3544,10 +3544,24 @@ public abstract class LivingEntity extends Entity implements Attackable { - if (this.level().isClientSide()) { +@@ -3683,10 +3683,24 @@ public abstract class LivingEntity extends Entity implements Attackable { + if (!(world instanceof ServerLevel worldserver)) { this.level().getEntities(EntityTypeTest.forClass(net.minecraft.world.entity.player.Player.class), this.getBoundingBox(), EntitySelector.pushableBy(this)).forEach(this::doPush); } else { + // Paper start - don't run getEntities if we're not going to use its result @@ -33,10 +33,10 @@ index 4c32b26e29ca3db0a2f62052e14bcc3e4c1cdea5..cf18f17f181bc94a2b5f4ac6926c2388 + return; + } + // Paper end - don't run getEntities if we're not going to use its result - List list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushableBy(this)); + List list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushableBy(this)); if (!list.isEmpty()) { -- int i = this.level().getGameRules().getInt(GameRules.RULE_MAX_ENTITY_CRAMMING); +- int i = worldserver.getGameRules().getInt(GameRules.RULE_MAX_ENTITY_CRAMMING); + // Paper - don't run getEntities if we're not going to use its result; moved up if (i > 0 && list.size() > i - 1 && this.random.nextInt(4) == 0) { diff --git a/patches/unapplied/server/0340-Implement-Player-Client-Options-API.patch b/patches/server/0337-Implement-Player-Client-Options-API.patch similarity index 95% rename from patches/unapplied/server/0340-Implement-Player-Client-Options-API.patch rename to patches/server/0337-Implement-Player-Client-Options-API.patch index d190884bb0d1..943a64b447f7 100644 --- a/patches/unapplied/server/0340-Implement-Player-Client-Options-API.patch +++ b/patches/server/0337-Implement-Player-Client-Options-API.patch @@ -87,10 +87,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 7daa310dd5d3eb1befb9983ce85e0354771af71d..8938f90c53de8aef71aa70522a66a69edb467e73 100644 +index 363175d3325c012f31ba84060bb0bfac694f6ab8..9911e231ad021286f2da90057b06874f7b4e3b4d 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -359,7 +359,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -420,7 +420,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.stats = server.getPlayerList().getPlayerStats(this); this.advancements = server.getPlayerList().getPlayerAdvancements(this); // this.moveTo(this.adjustSpawnLocation(world, world.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F); // Paper - Don't move existing players to world spawn @@ -99,7 +99,7 @@ index 7daa310dd5d3eb1befb9983ce85e0354771af71d..8938f90c53de8aef71aa70522a66a69e this.object = null; // CraftBukkit start -@@ -2146,7 +2146,23 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2404,7 +2404,23 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } } @@ -123,7 +123,7 @@ index 7daa310dd5d3eb1befb9983ce85e0354771af71d..8938f90c53de8aef71aa70522a66a69e // CraftBukkit start if (this.getMainArm() != clientOptions.mainHand()) { PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(this.getBukkitEntity(), this.getMainArm() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT); -@@ -2157,6 +2173,11 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2415,6 +2431,11 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.server.server.getPluginManager().callEvent(event); } // CraftBukkit end @@ -136,10 +136,10 @@ index 7daa310dd5d3eb1befb9983ce85e0354771af71d..8938f90c53de8aef71aa70522a66a69e this.adventure$locale = java.util.Objects.requireNonNullElse(net.kyori.adventure.translation.Translator.parseLocale(this.language), java.util.Locale.US); // Paper this.requestedViewDistance = clientOptions.viewDistance(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 1959e2af13daa06293c10ea2a4f68e319fac26ad..068ff2c228308ec87fcc6d1352bd63b91bd34a93 100644 +index df99bc022b25e61dc8827c67fb4eb2909bba097f..f836a65db1028b51ebd425251ca37e0c439d4ad6 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -653,6 +653,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -666,6 +666,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { connection.disconnect(message == null ? net.kyori.adventure.text.Component.empty() : message); } } diff --git a/patches/unapplied/server/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch b/patches/server/0338-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch similarity index 88% rename from patches/unapplied/server/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch rename to patches/server/0338-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch index 9d20799a092c..0db5556d5a10 100644 --- a/patches/unapplied/server/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch +++ b/patches/server/0338-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 dfa0456f352ce25bc4edd1b0f04ca5a14434d7fa..1e7b440cc2c1bf53210069b38286f67a7b97041b 100644 +index 6c2339d6a93172e25040c4868a3a47473a1f5336..f7c2c03749d6be25bf33afd61e1da120770b3432 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java -@@ -275,8 +275,8 @@ public abstract class DistanceManager { +@@ -281,8 +281,8 @@ public abstract class DistanceManager { ObjectSet objectset = (ObjectSet) this.playersPerChunk.get(i); if (objectset == null) return; // CraftBukkit - SPIGOT-6208 diff --git a/patches/unapplied/server/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch b/patches/server/0339-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch similarity index 73% rename from patches/unapplied/server/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch rename to patches/server/0339-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch index fda85df8ca64..7d3cdd3d1cad 100644 --- a/patches/unapplied/server/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch +++ b/patches/server/0339-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch @@ -31,10 +31,10 @@ delays anymore. public net.minecraft.server.level.ChunkMap addEntity(Lnet/minecraft/world/entity/Entity;)V diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 8206ec366b429858d9582e437781191e5aa0fa02..d91279f3bd009e1542e73354aadd6a16c80965e2 100644 +index f3b99cd96672363e0d60e56b744f0bea8fa00c3f..8121f7f5fb4dadb1c929b3d81121e3649981bfac 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1248,6 +1248,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1307,6 +1307,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider return; } // Paper end - ignore and warn about illegal addEntity calls instead of crashing server @@ -43,10 +43,10 @@ index 8206ec366b429858d9582e437781191e5aa0fa02..d91279f3bd009e1542e73354aadd6a16 EntityType entitytypes = entity.getType(); int i = entitytypes.clientTrackingRange() * 16; diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 8938f90c53de8aef71aa70522a66a69edb467e73..e6e7dc17d1196a8211a565355f34b5dcfd478852 100644 +index 9911e231ad021286f2da90057b06874f7b4e3b4d..807068fc6065f71961d34cb4f18b6eb39ae49637 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -289,6 +289,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -317,6 +317,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { public double maxHealthCache; public boolean joining = true; public boolean sentListPacket = false; @@ -55,10 +55,10 @@ index 8938f90c53de8aef71aa70522a66a69edb467e73..e6e7dc17d1196a8211a565355f34b5dc // CraftBukkit end public boolean isRealPlayer; // Paper diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 2cbdcdf0349e7efa797802d0d339d158153690af..5390ce62ec8afd24d2e028ea04d2ef3029a125f9 100644 +index 074f3518b060c4aa079b1d311b7fcb10d4a95981..ec5673ff22706006a2bcfb5f5a9e8840ee27ac45 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -297,6 +297,12 @@ public abstract class PlayerList { +@@ -300,6 +300,13 @@ public abstract class PlayerList { this.playersByUUID.put(player.getUUID(), player); // this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(entityplayer))); // CraftBukkit - replaced with loop below @@ -66,12 +66,13 @@ index 2cbdcdf0349e7efa797802d0d339d158153690af..5390ce62ec8afd24d2e028ea04d2ef30 + player.supressTrackerForLogin = true; + worldserver1.addNewPlayer(player); + this.server.getCustomBossEvents().onPlayerConnect(player); // see commented out section below worldserver.addPlayerJoin(entityplayer); -+ this.mountSavedVehicle(player, worldserver1, optional); ++ player.loadAndSpawnEnderpearls(optional); ++ player.loadAndSpawnParentVehicle(optional); + // Paper end - Fire PlayerJoinEvent when Player is actually ready // CraftBukkit start CraftPlayer bukkitPlayer = player.getBukkitEntity(); -@@ -335,6 +341,8 @@ public abstract class PlayerList { +@@ -338,6 +345,8 @@ public abstract class PlayerList { player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(entityplayer1))); } player.sentListPacket = true; @@ -80,26 +81,13 @@ index 2cbdcdf0349e7efa797802d0d339d158153690af..5390ce62ec8afd24d2e028ea04d2ef30 // CraftBukkit end player.refreshEntityData(player); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn -@@ -350,6 +358,11 @@ public abstract class PlayerList { +@@ -353,8 +362,7 @@ public abstract class PlayerList { worldserver1 = player.serverLevel(); // CraftBukkit - Update in case join event changed it // CraftBukkit end this.sendActivePlayerEffects(player); -+ // Paper start - Fire PlayerJoinEvent when Player is actually ready; move vehicle into method so it can be called above - short circuit around that code -+ this.onPlayerJoinFinish(player, worldserver1, s1); -+ } -+ private void mountSavedVehicle(ServerPlayer player, ServerLevel worldserver1, Optional optional) { -+ // Paper end - Fire PlayerJoinEvent when Player is actually ready - if (optional.isPresent() && ((CompoundTag) optional.get()).contains("RootVehicle", 10)) { - CompoundTag nbttagcompound = ((CompoundTag) optional.get()).getCompound("RootVehicle"); - ServerLevel finalWorldServer = worldserver1; // CraftBukkit - decompile error -@@ -396,6 +409,10 @@ public abstract class PlayerList { - } - } - -+ // Paper start - Fire PlayerJoinEvent when Player is actually ready -+ } -+ public void onPlayerJoinFinish(ServerPlayer player, ServerLevel worldserver1, String s1) { -+ // Paper end - Fire PlayerJoinEvent when Player is actually ready +- player.loadAndSpawnEnderpearls(optional); +- player.loadAndSpawnParentVehicle(optional); ++ // Paper - move loading pearls / parent vehicle up player.initInventoryMenu(); // CraftBukkit - Moved from above, added world // Paper start - Configurable player collision; Add to collideRule team if needed diff --git a/patches/unapplied/server/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch b/patches/server/0340-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch similarity index 93% rename from patches/unapplied/server/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch rename to patches/server/0340-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch index b739652ade17..270260266ebf 100644 --- a/patches/unapplied/server/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch +++ b/patches/server/0340-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch @@ -10,10 +10,10 @@ Co-authored-by: Wyatt Childers Co-authored-by: Jake Potrebic diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 5390ce62ec8afd24d2e028ea04d2ef3029a125f9..6f587c4bb4704d93552ba61335d87b1852fc169c 100644 +index ec5673ff22706006a2bcfb5f5a9e8840ee27ac45..c8c27311ade7d4a70d5398b3a4cb50eedd02a2f9 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -197,6 +197,7 @@ public abstract class PlayerList { +@@ -198,6 +198,7 @@ public abstract class PlayerList { } Optional optional = this.load(player); // CraftBukkit - decompile error @@ -21,7 +21,7 @@ index 5390ce62ec8afd24d2e028ea04d2ef3029a125f9..6f587c4bb4704d93552ba61335d87b18 // CraftBukkit start - Better rename detection if (optional.isPresent()) { CompoundTag nbttagcompound = optional.get(); -@@ -206,19 +207,47 @@ public abstract class PlayerList { +@@ -207,19 +208,47 @@ public abstract class PlayerList { } } // CraftBukkit end @@ -72,7 +72,7 @@ index 5390ce62ec8afd24d2e028ea04d2ef3029a125f9..6f587c4bb4704d93552ba61335d87b18 } else { worldserver1 = worldserver; } -@@ -226,6 +255,10 @@ public abstract class PlayerList { +@@ -227,6 +256,10 @@ public abstract class PlayerList { // Paper start - Entity#getEntitySpawnReason if (optional.isEmpty()) { player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login @@ -84,10 +84,10 @@ index 5390ce62ec8afd24d2e028ea04d2ef3029a125f9..6f587c4bb4704d93552ba61335d87b18 } // Paper end - Entity#getEntitySpawnReason diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 94242c19740ae6ab2c86e3949bab6cee631b938f..d80fd4e2f41583f83c9527ccf4ce80afe851276a 100644 +index fa80b6220aba144521dc0a2a35914c10046c1963..5b8e264098f1b713de15f714bae59d3efda365cf 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -2385,27 +2385,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2502,27 +2502,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } // CraftBukkit end diff --git a/patches/unapplied/server/0344-Add-PlayerAttackEntityCooldownResetEvent.patch b/patches/server/0341-Add-PlayerAttackEntityCooldownResetEvent.patch similarity index 92% rename from patches/unapplied/server/0344-Add-PlayerAttackEntityCooldownResetEvent.patch rename to patches/server/0341-Add-PlayerAttackEntityCooldownResetEvent.patch index 3348155d8568..72ccb53f47da 100644 --- a/patches/unapplied/server/0344-Add-PlayerAttackEntityCooldownResetEvent.patch +++ b/patches/server/0341-Add-PlayerAttackEntityCooldownResetEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerAttackEntityCooldownResetEvent diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index cf18f17f181bc94a2b5f4ac6926c2388ec3178c8..42c4adabe451cd32aa362075395a9fcc384ea788 100644 +index 6ff464fef1f79cff9212135a30adcc6cb8792ed6..68e5f6f7013d6a014b9014d945cf3f7dc7a37cb2 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2277,7 +2277,17 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2354,7 +2354,17 @@ public abstract class LivingEntity extends Entity implements Attackable { } if (damagesource.getEntity() instanceof net.minecraft.world.entity.player.Player) { diff --git a/patches/unapplied/server/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch b/patches/server/0342-Don-t-fire-BlockFade-on-worldgen-threads.patch similarity index 79% rename from patches/unapplied/server/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch rename to patches/server/0342-Don-t-fire-BlockFade-on-worldgen-threads.patch index a909ceca1272..cafa4896dfb7 100644 --- a/patches/unapplied/server/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch +++ b/patches/server/0342-Don-t-fire-BlockFade-on-worldgen-threads.patch @@ -5,17 +5,17 @@ Subject: [PATCH] Don't fire BlockFade on worldgen threads diff --git a/src/main/java/net/minecraft/world/level/block/FireBlock.java b/src/main/java/net/minecraft/world/level/block/FireBlock.java -index c1111bd8065b53cb140e4289cb72985f03e6f549..9db6df5f28be559a324ead2fcfbe189eac076e2e 100644 +index f44457c0d75efe323cc8242ef5173a3d5067fad0..065d6164b5c9d65d20e7790c607d77e9ad70dfef 100644 --- a/src/main/java/net/minecraft/world/level/block/FireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java @@ -108,6 +108,7 @@ public class FireBlock extends BaseFireBlock { @Override - protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { + protected BlockState updateShape(BlockState state, LevelReader world, ScheduledTickAccess tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, RandomSource random) { // CraftBukkit start + if (!(world instanceof ServerLevel)) return this.canSurvive(state, world, pos) ? (BlockState) this.getStateWithAge(world, pos, (Integer) state.getValue(FireBlock.AGE)) : Blocks.AIR.defaultBlockState(); // Paper - don't fire events in world generation if (!this.canSurvive(state, world, pos)) { // Suppress during worldgen - if (!(world instanceof Level)) { + if (!(world instanceof Level world1)) { @@ -123,7 +124,7 @@ public class FireBlock extends BaseFireBlock { return blockState.getHandle(); } diff --git a/patches/unapplied/server/0346-Add-phantom-creative-and-insomniac-controls.patch b/patches/server/0343-Add-phantom-creative-and-insomniac-controls.patch similarity index 82% rename from patches/unapplied/server/0346-Add-phantom-creative-and-insomniac-controls.patch rename to patches/server/0343-Add-phantom-creative-and-insomniac-controls.patch index 0eea572994f7..eed8a10b78ae 100644 --- a/patches/unapplied/server/0346-Add-phantom-creative-and-insomniac-controls.patch +++ b/patches/server/0343-Add-phantom-creative-and-insomniac-controls.patch @@ -5,31 +5,31 @@ Subject: [PATCH] Add phantom creative and insomniac controls diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java -index f7014bf5faae03a04c31cbdaeb27188c47156c2d..eb425fac573881f3aad09ae75a32184fb0e325a6 100644 +index 3a4c1d4afddd7d8d1f43554a7a08855686cadf56..b8d57e25851dd7da905100dfd4022e4b99fd7f02 100644 --- a/src/main/java/net/minecraft/world/entity/EntitySelector.java +++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java -@@ -28,6 +28,7 @@ public final class EntitySelector { - return !entity.isSpectator(); +@@ -27,6 +27,7 @@ public final class EntitySelector { }; public static final Predicate CAN_BE_COLLIDED_WITH = EntitySelector.NO_SPECTATORS.and(Entity::canBeCollidedWith); + public static final Predicate CAN_BE_PICKED = EntitySelector.NO_SPECTATORS.and(Entity::isPickable); + public static Predicate IS_INSOMNIAC = (player) -> net.minecraft.util.Mth.clamp(((net.minecraft.server.level.ServerPlayer) player).getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper - Add phantom creative and insomniac controls private EntitySelector() {} // Paper start - Affects Spawning API diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java -index 3c3f70d05fb51b530b792adf84c324840bd03c14..4b3bec32921feb1dcf71abf5e8d34fcbbc59baf5 100644 +index 748f07c7036fe5955d76e28c4e7d23f8c0235d5f..d0820b3a561db7e1e5667594b2b6ea13214dfa58 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java +++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java -@@ -549,6 +549,7 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -550,6 +550,7 @@ public class Phantom extends FlyingMob implements Enemy { Player entityhuman = (Player) iterator.next(); - if (Phantom.this.canAttack(entityhuman, TargetingConditions.DEFAULT)) { + if (Phantom.this.canAttack(worldserver, entityhuman, TargetingConditions.DEFAULT)) { + if (!level().paperConfig().entities.behavior.phantomsOnlyAttackInsomniacs || EntitySelector.IS_INSOMNIAC.test(entityhuman)) // Paper - Add phantom creative and insomniac controls Phantom.this.setTarget(entityhuman, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true); // CraftBukkit - reason return true; } diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java -index bb7f2d3ff7fc6f5cadb4ab24efb5a3a2f5bdc33f..f74d41e57570a40cd5ce4da3076f3210b6594a63 100644 +index 499b124f905ffa8e375efa354a3f2240997ddea5..7d407a7597f3ae576ac7e94bc2eb96d9dcd78dd3 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java +++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java @@ -48,7 +48,7 @@ public class PhantomSpawner implements CustomSpawner { diff --git a/patches/unapplied/server/0347-Fix-item-duplication-and-teleport-issues.patch b/patches/server/0344-Fix-item-duplication-and-teleport-issues.patch similarity index 76% rename from patches/unapplied/server/0347-Fix-item-duplication-and-teleport-issues.patch rename to patches/server/0344-Fix-item-duplication-and-teleport-issues.patch index 86f3c094a3fa..1e7965da69d9 100644 --- a/patches/unapplied/server/0347-Fix-item-duplication-and-teleport-issues.patch +++ b/patches/server/0344-Fix-item-duplication-and-teleport-issues.patch @@ -16,10 +16,10 @@ 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 d80fd4e2f41583f83c9527ccf4ce80afe851276a..10015beb7a2de890fe27bffde8f55c1dd78ce344 100644 +index 5b8e264098f1b713de15f714bae59d3efda365cf..4faba83eb73e0d313e9131794962b727f7628a50 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -2515,11 +2515,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2630,11 +2630,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } else { // CraftBukkit start - Capture drops for death event if (this instanceof net.minecraft.world.entity.LivingEntity && !((net.minecraft.world.entity.LivingEntity) this).forceDrops) { @@ -28,14 +28,13 @@ index d80fd4e2f41583f83c9527ccf4ce80afe851276a..10015beb7a2de890fe27bffde8f55c1d return null; } // CraftBukkit end -- ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY() + (double) yOffset, this.getZ(), stack); -+ ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY() + (double) yOffset, this.getZ(), stack.copy()); // Paper - copy so we can destroy original + ItemEntity entityitem = new ItemEntity(world, this.getX(), this.getY() + (double) yOffset, this.getZ(), stack); + stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe entityitem.setDefaultPickUpDelay(); // CraftBukkit start -@@ -3335,6 +3336,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - public Entity changeDimension(DimensionTransition teleportTarget) { +@@ -3462,6 +3463,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + public Entity teleport(TeleportTransition teleportTarget) { Level world = this.level(); + // Paper start - Fix item duplication and teleport issues @@ -47,32 +46,31 @@ index d80fd4e2f41583f83c9527ccf4ce80afe851276a..10015beb7a2de890fe27bffde8f55c1d if (world instanceof ServerLevel worldserver) { if (!this.isRemoved()) { // CraftBukkit start -@@ -3377,6 +3384,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - - if (entity2 != null) { - if (this != entity2) { -+ // Paper start - Fix item duplication and teleport issues -+ if (this instanceof Leashable leashable) { -+ leashable.dropLeash(true, true); // Paper drop lead -+ } -+ // Paper end - Fix item duplication and teleport issues - entity2.restoreFrom(this); - this.removeAfterChangingDimensions(); - // CraftBukkit start - Forward the CraftEntity to the new entity -@@ -3452,7 +3464,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3550,6 +3557,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + gameprofilerfiller.pop(); + return null; + } else { ++ // Paper start - Fix item duplication and teleport issues ++ if (this instanceof Leashable leashable) { ++ leashable.dropLeash(true, true); // Paper drop lead ++ } ++ // Paper end - Fix item duplication and teleport issues + entity.restoreFrom(this); + this.removeAfterChangingDimensions(); + // CraftBukkit start - Forward the CraftEntity to the new entity +@@ -3662,6 +3674,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } - public boolean canChangeDimensions(Level from, Level to) { -- return true; -+ return this.isAlive() && this.valid; // Paper - Fix item duplication and teleport issues - } + public boolean canTeleport(Level from, Level to) { ++ if (!this.isAlive() || !this.valid) return false; // Paper - Fix item duplication and teleport issues + if (from.dimension() == Level.END && to.dimension() == Level.OVERWORLD) { + Iterator iterator = this.getPassengers().iterator(); - public float getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState, float max) { diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 42c4adabe451cd32aa362075395a9fcc384ea788..8920099eb488c37b036b7bd97fbd4f7db505c77c 100644 +index 68e5f6f7013d6a014b9014d945cf3f7dc7a37cb2..65909e0a8f8b68f9a4dacefda9069c8263a96ada 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1728,9 +1728,9 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1767,9 +1767,9 @@ public abstract class LivingEntity extends Entity implements Attackable { // Paper start org.bukkit.event.entity.EntityDeathEvent deathEvent = this.dropAllDeathLoot(worldserver, damageSource); if (deathEvent == null || !deathEvent.isCancelled()) { @@ -85,7 +83,7 @@ index 42c4adabe451cd32aa362075395a9fcc384ea788..8920099eb488c37b036b7bd97fbd4f7d // Paper start - clear equipment if event is not cancelled if (this instanceof Mob) { for (EquipmentSlot slot : this.clearedEquipmentSlots) { -@@ -1822,8 +1822,13 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1863,8 +1863,13 @@ public abstract class LivingEntity extends Entity implements Attackable { this.dropCustomDeathLoot(world, damageSource, flag); this.clearEquipmentSlots = prev; // Paper } @@ -102,10 +100,10 @@ index 42c4adabe451cd32aa362075395a9fcc384ea788..8920099eb488c37b036b7bd97fbd4f7d this.drops = new ArrayList<>(); // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -index 92bb0c63330ad3a4cb13b2dc655020714e9b1ffd..cc1189c2d7dc57ba8f29aad4ba5d2a07362bcd5b 100644 +index e20565cf256aacd012a1722c5ebbf9016bc82e42..59fbfe8de2dc5ec020dd61a5e446b0b6f67d76e4 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -635,7 +635,7 @@ public class ArmorStand extends LivingEntity { +@@ -633,7 +633,7 @@ public class ArmorStand extends LivingEntity { for (i = 0; i < this.handItems.size(); ++i) { itemstack = (ItemStack) this.handItems.get(i); if (!itemstack.isEmpty()) { @@ -114,7 +112,7 @@ index 92bb0c63330ad3a4cb13b2dc655020714e9b1ffd..cc1189c2d7dc57ba8f29aad4ba5d2a07 this.handItems.set(i, ItemStack.EMPTY); } } -@@ -643,7 +643,7 @@ public class ArmorStand extends LivingEntity { +@@ -641,7 +641,7 @@ public class ArmorStand extends LivingEntity { for (i = 0; i < this.armorItems.size(); ++i) { itemstack = (ItemStack) this.armorItems.get(i); if (!itemstack.isEmpty()) { @@ -124,10 +122,10 @@ index 92bb0c63330ad3a4cb13b2dc655020714e9b1ffd..cc1189c2d7dc57ba8f29aad4ba5d2a07 } } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 235ac5c12dab593da3a40e348a010ff626ce74a3..26f8a8cb18205bfb9fe9dc557097946987ddcb18 100644 +index 41f23ce732b6e90828b1bbda7f4b3470cd462c4a..0b9c96105bea9a0d1af17b7ecf4479d3596faa80 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -905,6 +905,11 @@ public class CraftEventFactory { +@@ -903,6 +903,11 @@ public class CraftEventFactory { } public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List drops) { @@ -138,8 +136,8 @@ index 235ac5c12dab593da3a40e348a010ff626ce74a3..26f8a8cb18205bfb9fe9dc5570979469 + // Paper end CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity(); CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource); - EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(damageSource.getEntity())); -@@ -919,11 +924,13 @@ public class CraftEventFactory { + CraftWorld world = (CraftWorld) entity.getWorld(); +@@ -917,11 +922,13 @@ public class CraftEventFactory { playDeathSound(victim, event); // Paper end victim.expToDrop = event.getDroppedExp(); diff --git a/patches/unapplied/server/0348-Villager-Restocks-API.patch b/patches/server/0345-Villager-Restocks-API.patch similarity index 87% rename from patches/unapplied/server/0348-Villager-Restocks-API.patch rename to patches/server/0345-Villager-Restocks-API.patch index 1f7c26de9d24..4ad766705c0e 100644 --- a/patches/unapplied/server/0348-Villager-Restocks-API.patch +++ b/patches/server/0345-Villager-Restocks-API.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Villager Restocks API public net.minecraft.world.entity.npc.Villager numberOfRestocksToday diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java -index 1b97755b42aaa6cc27b79f0b6369955e9a17c4d4..957c9ec21c7a9888b3038402b0111c68f816f968 100644 +index 1a7b666f9795e72022a60d14bfd405ae3165e292..ded319d10a5907b96abfd5620036b66a9aa3b3f7 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java -@@ -89,6 +89,18 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { +@@ -90,6 +90,18 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { this.getHandle().setVillagerXp(experience); } diff --git a/patches/unapplied/server/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch b/patches/server/0346-Validate-PickItem-Packet-and-kick-for-invalid.patch similarity index 68% rename from patches/unapplied/server/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch rename to patches/server/0346-Validate-PickItem-Packet-and-kick-for-invalid.patch index 774f59a11577..9f4314b9de66 100644 --- a/patches/unapplied/server/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch +++ b/patches/server/0346-Validate-PickItem-Packet-and-kick-for-invalid.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Validate PickItem Packet and kick for invalid diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 0ed2d0f5ec9d107e8049aa9e803479ffd341639f..119b9b2c45e3321b4197f3e6a34037e3fa99622d 100644 +index 0b7e47418aa7a9891ee4a070430de6b2599f66e3..01dbc23369661e141ee81a2357f7b0b5602b56d5 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -895,7 +895,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -899,7 +899,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handlePickItem(ServerboundPickItemPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); @@ -21,6 +21,6 @@ index 0ed2d0f5ec9d107e8049aa9e803479ffd341639f..119b9b2c45e3321b4197f3e6a34037e3 + } + this.player.getInventory().pickSlot(packet.getSlot()); // Paper - Diff above if changed + // Paper end - validate pick item position - this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, 0, this.player.getInventory().selected, this.player.getInventory().getItem(this.player.getInventory().selected))); - this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, 0, packet.getSlot(), this.player.getInventory().getItem(packet.getSlot()))); - this.player.connection.send(new ClientboundSetCarriedItemPacket(this.player.getInventory().selected)); + int i = this.player.getInventory().selected; + + this.player.connection.send(this.player.getInventory().createInventoryUpdatePacket(i)); diff --git a/patches/unapplied/server/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch b/patches/server/0347-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch similarity index 93% rename from patches/unapplied/server/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch rename to patches/server/0347-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch index 46f51a9f451e..e325a1d81095 100644 --- a/patches/unapplied/server/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch +++ b/patches/server/0347-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch @@ -17,7 +17,7 @@ keeping long lived large direct buffers in cache. Set system properly at server startup if not set already to help protect from this. diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index ed167d0d399924d54d9ff99c10ab8ee093efc149..168cbb239ac5d632908f2b0aca82cbcfdc35651f 100644 +index c618934b5cf66d9625c7be2ac114f1a1ca629d33..124aeebbbae7dc8cea1260bf3134a339c2e152ed 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -27,6 +27,7 @@ public class Main { diff --git a/patches/unapplied/server/0351-misc-debugging-dumps.patch b/patches/server/0348-misc-debugging-dumps.patch similarity index 91% rename from patches/unapplied/server/0351-misc-debugging-dumps.patch rename to patches/server/0348-misc-debugging-dumps.patch index b339217a999b..6d514c8e3888 100644 --- a/patches/unapplied/server/0351-misc-debugging-dumps.patch +++ b/patches/server/0348-misc-debugging-dumps.patch @@ -36,10 +36,10 @@ index 0000000000000000000000000000000000000000..479bb92d159f33c54c2d9c39d8a63aa9 + } +} diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index e25fc35716aff1d1805884b18f67b0eb33d8c05c..8ca9ac8eff9d605baa878ca24e165ac5642bf160 100644 +index c847fbdb6f52386570eb4c070fcc01d39cc52151..a7eb2a37a81a414dcb19319c075faefe0382aeba 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -340,7 +340,7 @@ public class Commands { +@@ -345,7 +345,7 @@ public class Commands { } catch (Exception exception) { MutableComponent ichatmutablecomponent = Component.literal(exception.getMessage() == null ? exception.getClass().getName() : exception.getMessage()); @@ -49,10 +49,10 @@ index e25fc35716aff1d1805884b18f67b0eb33d8c05c..8ca9ac8eff9d605baa878ca24e165ac5 StackTraceElement[] astacktraceelement = exception.getStackTrace(); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 53bb62c1dcb487be915759d22e06aea80be54f36..8b17df3d18fe9acc1a7b10c6809886da0143f8c5 100644 +index 708552756a33339ce9eefe48c9999a2ec08f7e1c..a08cebda577223184af8b42a90eb3559e419438e 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -915,6 +915,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop set) { // Paper + public void internalTeleport(PositionMoveRotation positionmoverotation, Set set) { + // Paper start - Prevent teleporting dead entities + if (player.isRemoved()) { + LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName()); @@ -19,6 +19,6 @@ index 119b9b2c45e3321b4197f3e6a34037e3fa99622d..c6bcde25b476ef2362f469bd7cba82ce + return; + } + // Paper end - Prevent teleporting dead entities - // CraftBukkit start - if (Float.isNaN(f)) { - f = 0; + if (Float.isNaN(positionmoverotation.yRot())) { + positionmoverotation = new PositionMoveRotation(positionmoverotation.position(), positionmoverotation.deltaMovement(), 0, positionmoverotation.xRot()); + } From 6bfc6db99e975c997a2ef5dfdbc3c7050895faa0 Mon Sep 17 00:00:00 2001 From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Date: Wed, 23 Oct 2024 10:08:40 -0400 Subject: [PATCH 019/119] Patch --- .../0350-Implement-Mob-Goal-API.patch} | 12 ++++++------ .../0351-Add-villager-reputation-API.patch} | 8 ++++---- ...enceOrb-merging-stacking-API-and-fixes.patch} | 12 ++++++------ ...353-Fix-PotionEffect-ignores-icon-flag.patch} | 8 ++++---- .../0354-Potential-bed-API.patch} | 14 +++----------- ...5-Wait-for-Async-Tasks-during-shutdown.patch} | 8 ++++---- ...aider-respects-game-and-entity-rules-f.patch} | 14 +++++++------- ...ion-for-console-having-all-permissions.patch} | 0 ...-Fix-villager-trading-demand-MC-163962.patch} | 0 .../0359-Maps-shouldn-t-load-chunks.patch} | 4 ++-- ...-lookup-for-Treasure-Maps-Fixes-lag-fr.patch} | 4 ++-- ...uler-runTaskTimerAsynchronously-Plugin.patch} | 2 +- ...piston-physics-inconsistency-MC-188840.patch} | 16 +++++++--------- ...missing-chunks-due-to-integer-overflow.patch} | 0 ...ent-position-desync-causing-tp-exploit.patch} | 4 ++-- 15 files changed, 48 insertions(+), 58 deletions(-) rename patches/{unapplied/server/0353-Implement-Mob-Goal-API.patch => server/0350-Implement-Mob-Goal-API.patch} (98%) rename patches/{unapplied/server/0354-Add-villager-reputation-API.patch => server/0351-Add-villager-reputation-API.patch} (95%) rename patches/{unapplied/server/0355-ExperienceOrb-merging-stacking-API-and-fixes.patch => server/0352-ExperienceOrb-merging-stacking-API-and-fixes.patch} (93%) rename patches/{unapplied/server/0356-Fix-PotionEffect-ignores-icon-flag.patch => server/0353-Fix-PotionEffect-ignores-icon-flag.patch} (92%) rename patches/{unapplied/server/0357-Potential-bed-API.patch => server/0354-Potential-bed-API.patch} (68%) rename patches/{unapplied/server/0358-Wait-for-Async-Tasks-during-shutdown.patch => server/0355-Wait-for-Async-Tasks-during-shutdown.patch} (90%) rename patches/{unapplied/server/0359-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch => server/0356-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch} (57%) rename patches/{unapplied/server/0360-Add-option-for-console-having-all-permissions.patch => server/0357-Add-option-for-console-having-all-permissions.patch} (100%) rename patches/{unapplied/server/0361-Fix-villager-trading-demand-MC-163962.patch => server/0358-Fix-villager-trading-demand-MC-163962.patch} (100%) rename patches/{unapplied/server/0362-Maps-shouldn-t-load-chunks.patch => server/0359-Maps-shouldn-t-load-chunks.patch} (92%) rename patches/{unapplied/server/0363-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch => server/0360-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch} (86%) rename patches/{unapplied/server/0364-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch => server/0361-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch} (91%) rename patches/{unapplied/server/0365-Fix-piston-physics-inconsistency-MC-188840.patch => server/0362-Fix-piston-physics-inconsistency-MC-188840.patch} (86%) rename patches/{unapplied/server/0366-Fix-missing-chunks-due-to-integer-overflow.patch => server/0363-Fix-missing-chunks-due-to-integer-overflow.patch} (100%) rename patches/{unapplied/server/0367-Prevent-position-desync-causing-tp-exploit.patch => server/0364-Prevent-position-desync-causing-tp-exploit.patch} (91%) diff --git a/patches/unapplied/server/0353-Implement-Mob-Goal-API.patch b/patches/server/0350-Implement-Mob-Goal-API.patch similarity index 98% rename from patches/unapplied/server/0353-Implement-Mob-Goal-API.patch rename to patches/server/0350-Implement-Mob-Goal-API.patch index 5706a5b6b878..0c648f76d45b 100644 --- a/patches/unapplied/server/0353-Implement-Mob-Goal-API.patch +++ b/patches/server/0350-Implement-Mob-Goal-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Implement Mob Goal API diff --git a/build.gradle.kts b/build.gradle.kts -index 0c349354ba76dfd2c5f16fb232263b18e77a9a40..6c3ed9e685473d7f555ae0e34fb9d4f3873f109a 100644 +index da2f9c5afb2994f403a1128af0f7acbd6b73b862..38585b7f0b8e1e287b37820924a1b0d464fe9e99 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -41,6 +41,7 @@ dependencies { @@ -758,11 +758,11 @@ index 0000000000000000000000000000000000000000..b5c594a5499556ad452d9939c75e150a + } +} diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java -index 6667ecc4b7eded4e20a415cef1e1b1179e6710b8..16f9a98b8a939e5ca7e2dc04f87134a7ed66736b 100644 +index a8d6d7054110b5d95830296699f004418dae10db..acc25b08ed3b9f978229fa017d23f9fa0da519e3 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java -@@ -51,7 +51,19 @@ public abstract class Goal { - return Mth.positiveCeilDiv(serverTicks, 2); +@@ -62,7 +62,19 @@ public abstract class Goal { + return (ServerLevel)world; } + // Paper start - Mob goal api @@ -782,10 +782,10 @@ index 6667ecc4b7eded4e20a415cef1e1b1179e6710b8..16f9a98b8a939e5ca7e2dc04f87134a7 LOOK, JUMP, diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 75ea1d68c4be6f73ad05cd53b4e4c0182832395c..2b3eaeea881b12fe7e4c5150815ad00fe9f026e0 100644 +index 0d36eb7ae9d07d51449a4a15a6474c3f4befec94..aa7e0c08552ba476cfb266ad474eaecb9cc21a96 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2938,5 +2938,11 @@ public final class CraftServer implements Server { +@@ -2957,5 +2957,11 @@ public final class CraftServer implements Server { public boolean isStopping() { return net.minecraft.server.MinecraftServer.getServer().hasStopped(); } diff --git a/patches/unapplied/server/0354-Add-villager-reputation-API.patch b/patches/server/0351-Add-villager-reputation-API.patch similarity index 95% rename from patches/unapplied/server/0354-Add-villager-reputation-API.patch rename to patches/server/0351-Add-villager-reputation-API.patch index cf69cd346a19..f08d60eeaede 100644 --- a/patches/unapplied/server/0354-Add-villager-reputation-API.patch +++ b/patches/server/0351-Add-villager-reputation-API.patch @@ -57,12 +57,12 @@ index f06a5f0d9c5c877ddf963254d3124f5fe2d67282..aa32804bc9affe9a615d3ffaa513f6f0 static record GossipEntry(UUID target, GossipType type, int value) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java -index 957c9ec21c7a9888b3038402b0111c68f816f968..52312bec840322d32ea845f0bd64eb3ca1380854 100644 +index ded319d10a5907b96abfd5620036b66a9aa3b3f7..45c44c46edee9f46b8e197f1f54ea2779bf1184c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java -@@ -20,6 +20,13 @@ import org.bukkit.entity.Villager; - import org.bukkit.entity.ZombieVillager; +@@ -21,6 +21,13 @@ import org.bukkit.entity.ZombieVillager; import org.bukkit.event.entity.CreatureSpawnEvent; + import org.bukkit.event.entity.EntityTransformEvent; +// Paper start +import com.destroystokyo.paper.entity.villager.Reputation; @@ -74,7 +74,7 @@ index 957c9ec21c7a9888b3038402b0111c68f816f968..52312bec840322d32ea845f0bd64eb3c public class CraftVillager extends CraftAbstractVillager implements Villager { public CraftVillager(CraftServer server, net.minecraft.world.entity.npc.Villager entity) { -@@ -298,4 +305,45 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { +@@ -299,4 +306,45 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { return this.getKey().hashCode(); } } diff --git a/patches/unapplied/server/0355-ExperienceOrb-merging-stacking-API-and-fixes.patch b/patches/server/0352-ExperienceOrb-merging-stacking-API-and-fixes.patch similarity index 93% rename from patches/unapplied/server/0355-ExperienceOrb-merging-stacking-API-and-fixes.patch rename to patches/server/0352-ExperienceOrb-merging-stacking-API-and-fixes.patch index 369ade07202d..67ca8599bb15 100644 --- a/patches/unapplied/server/0355-ExperienceOrb-merging-stacking-API-and-fixes.patch +++ b/patches/server/0352-ExperienceOrb-merging-stacking-API-and-fixes.patch @@ -21,10 +21,10 @@ Co-authored-by: Aikar Co-authored-by: Jake Potrebic diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -index 0916e24271d07ad5db51c5bc68791722b0f69c2b..a758b2456acac23095fe4619ae10300a034cb460 100644 +index 9d9e3daebc5da0af627c3d3cdb50029aacbc587b..3a7af27bb1ce0cbe56bd3760cd400083daf98d4c 100644 --- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java +++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -@@ -244,6 +244,7 @@ public class ExperienceOrb extends Entity { +@@ -245,6 +245,7 @@ public class ExperienceOrb extends Entity { } private static boolean tryMergeToExisting(ServerLevel world, Vec3 pos, int amount) { @@ -32,7 +32,7 @@ index 0916e24271d07ad5db51c5bc68791722b0f69c2b..a758b2456acac23095fe4619ae10300a AABB axisalignedbb = AABB.ofSize(pos, 1.0D, 1.0D, 1.0D); int j = world.getRandom().nextInt(40); List list = world.getEntities(EntityTypeTest.forClass(ExperienceOrb.class), axisalignedbb, (entityexperienceorb) -> { -@@ -270,6 +271,11 @@ public class ExperienceOrb extends Entity { +@@ -271,6 +272,11 @@ public class ExperienceOrb extends Entity { } private void merge(ExperienceOrb other) { @@ -44,7 +44,7 @@ index 0916e24271d07ad5db51c5bc68791722b0f69c2b..a758b2456acac23095fe4619ae10300a this.count += other.count; this.age = Math.min(this.age, other.age); other.discard(EntityRemoveEvent.Cause.MERGE); // CraftBukkit - add Bukkit remove cause -@@ -360,7 +366,7 @@ public class ExperienceOrb extends Entity { +@@ -364,7 +370,7 @@ public class ExperienceOrb extends Entity { int l = amount - k * amount / j; if (l > 0) { @@ -77,10 +77,10 @@ index 5a7d314ec0562e472f5dc45924a7b24841cff126..650e4a01cecc4cc08e7ff9ebcc4c3670 public java.util.UUID getTriggerEntityId() { return getHandle().triggerEntityId; diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 26f8a8cb18205bfb9fe9dc557097946987ddcb18..f3ec3d14e66b9c1dff32088d4aef57e21265048c 100644 +index 0b9c96105bea9a0d1af17b7ecf4479d3596faa80..b40117e9940ab493ea4a945dbd9754a38b1159b9 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -714,15 +714,29 @@ public class CraftEventFactory { +@@ -712,15 +712,29 @@ public class CraftEventFactory { if (entity instanceof net.minecraft.world.entity.ExperienceOrb xp) { double radius = world.spigotConfig.expMerge; if (radius > 0) { diff --git a/patches/unapplied/server/0356-Fix-PotionEffect-ignores-icon-flag.patch b/patches/server/0353-Fix-PotionEffect-ignores-icon-flag.patch similarity index 92% rename from patches/unapplied/server/0356-Fix-PotionEffect-ignores-icon-flag.patch rename to patches/server/0353-Fix-PotionEffect-ignores-icon-flag.patch index 28f3888cb2b5..9dff9c741c77 100644 --- a/patches/unapplied/server/0356-Fix-PotionEffect-ignores-icon-flag.patch +++ b/patches/server/0353-Fix-PotionEffect-ignores-icon-flag.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Fix PotionEffect ignores icon flag Co-authored-by: Tamion <70228790+notTamion@users.noreply.github.com> diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 05ba1654ec02ff2b518251c128661e3d8dfa4c6d..733c69a2cfa60fb8c920400e3d9acfc2465090e5 100644 +index 81034513faa3bd4f306430bc48532ba671a7b94b..35130dc4e20ef644b5764091fcbccda2e4da780b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -485,7 +485,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -494,7 +494,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { @Override public boolean addPotionEffect(PotionEffect effect, boolean force) { @@ -18,7 +18,7 @@ index 05ba1654ec02ff2b518251c128661e3d8dfa4c6d..733c69a2cfa60fb8c920400e3d9acfc2 return true; } -@@ -506,7 +506,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -515,7 +515,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { @Override public PotionEffect getPotionEffect(PotionEffectType type) { MobEffectInstance handle = this.getHandle().getEffect(CraftPotionEffectType.bukkitToMinecraftHolder(type)); @@ -27,7 +27,7 @@ index 05ba1654ec02ff2b518251c128661e3d8dfa4c6d..733c69a2cfa60fb8c920400e3d9acfc2 } @Override -@@ -518,7 +518,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -527,7 +527,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { public Collection getActivePotionEffects() { List effects = new ArrayList(); for (MobEffectInstance handle : this.getHandle().activeEffects.values()) { diff --git a/patches/unapplied/server/0357-Potential-bed-API.patch b/patches/server/0354-Potential-bed-API.patch similarity index 68% rename from patches/unapplied/server/0357-Potential-bed-API.patch rename to patches/server/0354-Potential-bed-API.patch index 899b989746eb..e4dbfa304f45 100644 --- a/patches/unapplied/server/0357-Potential-bed-API.patch +++ b/patches/server/0354-Potential-bed-API.patch @@ -8,18 +8,10 @@ Adds a new method to fetch the location of a player's bed without generating any getPotentialBedLocation - Gets the last known location of a player's bed. This does not preform any check if the bed is still valid and does not load any chunks. diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index ba63c58d40cb3b8655fdb8177c423c67ac7cc3ef..c17dd4205983855615289cf0a5619056d237f325 100644 +index 6ec6b80d224e2402054afb85b78c793942a58bbf..b2ab430392fc0f214ba8c5383e3f3ad5c548bda2 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -@@ -12,6 +12,7 @@ import net.minecraft.nbt.CompoundTag; - import net.minecraft.network.chat.Component; - import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; - import net.minecraft.network.protocol.game.ServerboundContainerClosePacket; -+import net.minecraft.server.level.ServerLevel; - import net.minecraft.server.level.ServerPlayer; - import net.minecraft.world.MenuProvider; - import net.minecraft.world.entity.Entity; -@@ -129,6 +130,22 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { +@@ -130,6 +130,22 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { return this.getHandle().sleepCounter; } @@ -32,7 +24,7 @@ index ba63c58d40cb3b8655fdb8177c423c67ac7cc3ef..c17dd4205983855615289cf0a5619056 + return null; + } + -+ ServerLevel worldServer = handle.server.getLevel(handle.getRespawnDimension()); ++ net.minecraft.server.level.ServerLevel worldServer = handle.server.getLevel(handle.getRespawnDimension()); + if (worldServer == null) { + return null; + } diff --git a/patches/unapplied/server/0358-Wait-for-Async-Tasks-during-shutdown.patch b/patches/server/0355-Wait-for-Async-Tasks-during-shutdown.patch similarity index 90% rename from patches/unapplied/server/0358-Wait-for-Async-Tasks-during-shutdown.patch rename to patches/server/0355-Wait-for-Async-Tasks-during-shutdown.patch index fb2ca753f18f..ed26c62ef239 100644 --- a/patches/unapplied/server/0358-Wait-for-Async-Tasks-during-shutdown.patch +++ b/patches/server/0355-Wait-for-Async-Tasks-during-shutdown.patch @@ -10,10 +10,10 @@ 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 8b17df3d18fe9acc1a7b10c6809886da0143f8c5..0370d26bd1e1d2fe1d640b052aca8a9c05dcb9dc 100644 +index a08cebda577223184af8b42a90eb3559e419438e..b4eff440e3d9489f99e10a73611421ef877aa871 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -942,6 +942,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop multiset = LinkedHashMultiset.create(); diff --git a/patches/unapplied/server/0363-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch b/patches/server/0360-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch similarity index 86% rename from patches/unapplied/server/0363-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch rename to patches/server/0360-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch index 27672e59d75d..fa9145353c8b 100644 --- a/patches/unapplied/server/0363-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch +++ b/patches/server/0360-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Use seed based lookup for Treasure Maps - Fixes lag from diff --git a/src/main/java/net/minecraft/world/item/MapItem.java b/src/main/java/net/minecraft/world/item/MapItem.java -index 36de7c63370c529579d31ba1d77ec12b754ef313..ce461b1a8d7fab87ae28e30205f6fab67f1808b6 100644 +index af78d15aead7a2dc8304c541e37e306215b761be..571f2540a1e9422025efe651167e26b44b437daa 100644 --- a/src/main/java/net/minecraft/world/item/MapItem.java +++ b/src/main/java/net/minecraft/world/item/MapItem.java -@@ -206,7 +206,7 @@ public class MapItem extends ComplexItem { +@@ -205,7 +205,7 @@ public class MapItem extends Item { for (int n = 0; n < 128; n++) { for (int o = 0; o < 128; o++) { diff --git a/patches/unapplied/server/0364-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch b/patches/server/0361-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch similarity index 91% rename from patches/unapplied/server/0364-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch rename to patches/server/0361-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch index f3c979276054..906b73e4779c 100644 --- a/patches/unapplied/server/0364-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch +++ b/patches/server/0361-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Fix CraftScheduler#runTaskTimerAsynchronously(Plugin, diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -index 02835e4f0a0b262af27acff0939c981cae728db4..d7c2d8993a172e343669228cf24a58d8992a1c10 100644 +index fd5a058dd802599598a64467cf25f08329df9e99..fdfdcac6644e5343fb1f1cbe5d9aa76a79627046 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java @@ -197,7 +197,7 @@ public class CraftScheduler implements BukkitScheduler { diff --git a/patches/unapplied/server/0365-Fix-piston-physics-inconsistency-MC-188840.patch b/patches/server/0362-Fix-piston-physics-inconsistency-MC-188840.patch similarity index 86% rename from patches/unapplied/server/0365-Fix-piston-physics-inconsistency-MC-188840.patch rename to patches/server/0362-Fix-piston-physics-inconsistency-MC-188840.patch index 44f85960c4ed..60773947a868 100644 --- a/patches/unapplied/server/0365-Fix-piston-physics-inconsistency-MC-188840.patch +++ b/patches/server/0362-Fix-piston-physics-inconsistency-MC-188840.patch @@ -32,11 +32,11 @@ This patch fixes https://bugs.mojang.com/browse/MC-188840 This patch also fixes rail duping and carpet duping. diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java -index 530b6af1ca2e0ac81c0a8a55dbc7cf5c796c93ce..4aa34b7df734bb755906b228e0df9eb629569ea0 100644 +index 0b80940ed23a35e0412957a50d04907b676b0aca..e84501fdce7b94300b1f5d6d20e2db90b175454d 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java +++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java -@@ -414,14 +414,26 @@ public class PistonBaseBlock extends DirectionalBlock { - } +@@ -419,13 +419,25 @@ public class PistonBaseBlock extends DirectionalBlock { + BlockState iblockdata2; for (j = list.size() - 1; j >= 0; --j) { - blockposition3 = (BlockPos) list.get(j); @@ -48,16 +48,14 @@ index 530b6af1ca2e0ac81c0a8a55dbc7cf5c796c93ce..4aa34b7df734bb755906b228e0df9eb6 + // Paper end - fix a variety of piston desync dupes blockposition3 = blockposition3.relative(enumdirection1); map.remove(blockposition3); - BlockState iblockdata2 = (BlockState) Blocks.MOVING_PISTON.defaultBlockState().setValue(PistonBaseBlock.FACING, dir); - + iblockdata2 = (BlockState) Blocks.MOVING_PISTON.defaultBlockState().setValue(PistonBaseBlock.FACING, dir); world.setBlock(blockposition3, iblockdata2, 68); -- world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(blockposition3, iblockdata2, (BlockState) list1.get(j), dir, retract, false)); + // Paper start - fix a variety of piston desync dupes + if (!allowDesync) { + iblockdata1 = world.getBlockState(oldPos); + map.replace(oldPos, iblockdata1); + } -+ world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(blockposition3, iblockdata2, allowDesync ? list1.get(j) : iblockdata1, dir, retract, false)); + world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(blockposition3, iblockdata2, (BlockState) list1.get(j), dir, extend, false)); + if (!allowDesync) { + world.setBlock(oldPos, Blocks.AIR.defaultBlockState(), Block.UPDATE_CLIENTS | Block.UPDATE_KNOWN_SHAPE | Block.UPDATE_MOVE_BY_PISTON | 1024); // set air to prevent later physics updates from seeing this block + } @@ -66,10 +64,10 @@ index 530b6af1ca2e0ac81c0a8a55dbc7cf5c796c93ce..4aa34b7df734bb755906b228e0df9eb6 } diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -index 8ea7d7da26e7d5644a8ee1a8d9e4c828c6b70a00..d7b963571c900f0f68005d6954bcd9ef1d9e0b7c 100644 +index 53d0057e123540162852cb10fba1b7f7ac8388ad..46afba838cf12eeb1bbccaa260131a76f090364b 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -@@ -297,7 +297,7 @@ public class PistonMovingBlockEntity extends BlockEntity { +@@ -306,7 +306,7 @@ public class PistonMovingBlockEntity extends BlockEntity { if (world.getBlockState(pos).is(Blocks.MOVING_PISTON)) { BlockState blockState = Block.updateFromNeighbourShapes(blockEntity.movedState, world, pos); if (blockState.isAir()) { diff --git a/patches/unapplied/server/0366-Fix-missing-chunks-due-to-integer-overflow.patch b/patches/server/0363-Fix-missing-chunks-due-to-integer-overflow.patch similarity index 100% rename from patches/unapplied/server/0366-Fix-missing-chunks-due-to-integer-overflow.patch rename to patches/server/0363-Fix-missing-chunks-due-to-integer-overflow.patch diff --git a/patches/unapplied/server/0367-Prevent-position-desync-causing-tp-exploit.patch b/patches/server/0364-Prevent-position-desync-causing-tp-exploit.patch similarity index 91% rename from patches/unapplied/server/0367-Prevent-position-desync-causing-tp-exploit.patch rename to patches/server/0364-Prevent-position-desync-causing-tp-exploit.patch index 0bd37ce94ec9..29816e7a496f 100644 --- a/patches/unapplied/server/0367-Prevent-position-desync-causing-tp-exploit.patch +++ b/patches/server/0364-Prevent-position-desync-causing-tp-exploit.patch @@ -13,10 +13,10 @@ behaviour, we need to move all of this dangerous logic outside of the move call and into an appropriate place in the tick method. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index c6bcde25b476ef2362f469bd7cba82ce97cb300c..3455781a47fbececab33406e829ceb392c72a113 100644 +index 7b8aaf763020cf7be7114f329f22af75f7a80ef0..e329503681961566a76a383245303e88acef37a4 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1349,6 +1349,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1352,6 +1352,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.move(MoverType.PLAYER, new Vec3(d6, d7, d8)); this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move From 09b625eccfc38c4c08b4b4d15d79dfd2bba75e33 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Wed, 23 Oct 2024 16:55:24 +0200 Subject: [PATCH 020/119] 400 --- ...older-method-without-block-snapshot.patch} | 0 .../0366-Add-PlayerRecipeBookClickEvent.patch | 65 +++++++++++++++++++ ...-Hide-sync-chunk-writes-behind-flag.patch} | 2 +- ...8-Add-permission-for-command-blocks.patch} | 18 ++--- ...position-and-AABB-are-never-invalid.patch} | 8 +-- ...d-Difficulty-Remembering-Difficulty.patch} | 36 +++++----- .../0371-Paper-dumpitem-command.patch} | 0 ...Legacy-Component-serialization-size.patch} | 2 +- ...Plugin-Tickets-to-API-Chunk-Methods.patch} | 18 ++--- ...-Add-BlockStateMeta-clearBlockState.patch} | 0 ...vert-legacy-attributes-in-Item-Meta.patch} | 4 +- ...-not-accept-invalid-client-settings.patch} | 4 +- ...e-fix-EntityTargetLivingEntityEvent.patch} | 6 +- .../0378-Add-entity-liquid-API.patch} | 4 +- .../0379-Add-PrepareResultEvent.patch} | 42 ++++++------ ...-for-portal-on-world-gen-entity-add.patch} | 4 +- ...x-arrows-never-despawning-MC-125757.patch} | 6 +- ...Vanilla-Command-permission-checking.patch} | 6 +- ...-Bukkit-world-container-is-not-used.patch} | 2 +- ...5885-Unable-to-disable-advancements.patch} | 2 +- ...taPlayer-leak-due-from-quitting-ear.patch} | 2 +- ...e-NetworkManager-Exception-Handling.patch} | 0 ...ix-some-rails-connecting-improperly.patch} | 10 +-- ...stake-in-CB-NBT-int-deserialization.patch} | 0 .../0389-Brand-support.patch} | 16 ++--- ...PickupItemAnimation-to-LivingEntity.patch} | 4 +- .../0391-Don-t-require-FACING-data.patch} | 0 ...eEvent-not-firing-for-all-use-cases.patch} | 8 +-- .../0393-Add-moon-phase-API.patch} | 2 +- ...erver-load-chunks-from-newer-version.patch | 40 ++++++++++++ ...headless-pistons-from-being-created.patch} | 14 ++-- .../0396-Add-BellRingEvent.patch} | 4 +- ...dd-zombie-targets-turtle-egg-config.patch} | 4 +- .../0398-Buffer-joins-to-world.patch} | 0 ...s-not-working-in-some-kick-messages.patch} | 2 +- .../0400-Add-more-Evoker-API.patch} | 0 ...Add-methods-to-get-translation-keys.patch} | 6 +- ...te-HoverEvent-from-ItemStack-Entity.patch} | 4 +- .../0403-Cache-block-data-strings.patch} | 12 ++-- ...rtation-and-cancel-velocity-if-tele.patch} | 37 ++++------- .../0369-Add-PlayerRecipeBookClickEvent.patch | 55 ---------------- ...erver-load-chunks-from-newer-version.patch | 41 ------------ 42 files changed, 245 insertions(+), 245 deletions(-) rename patches/{unapplied/server/0368-Inventory-getHolder-method-without-block-snapshot.patch => server/0365-Inventory-getHolder-method-without-block-snapshot.patch} (100%) create mode 100644 patches/server/0366-Add-PlayerRecipeBookClickEvent.patch rename patches/{unapplied/server/0370-Hide-sync-chunk-writes-behind-flag.patch => server/0367-Hide-sync-chunk-writes-behind-flag.patch} (93%) rename patches/{unapplied/server/0371-Add-permission-for-command-blocks.patch => server/0368-Add-permission-for-command-blocks.patch} (89%) rename patches/{unapplied/server/0372-Ensure-Entity-position-and-AABB-are-never-invalid.patch => server/0369-Ensure-Entity-position-and-AABB-are-never-invalid.patch} (91%) rename patches/{unapplied/server/0373-Fix-Per-World-Difficulty-Remembering-Difficulty.patch => server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch} (79%) rename patches/{unapplied/server/0374-Paper-dumpitem-command.patch => server/0371-Paper-dumpitem-command.patch} (100%) rename patches/{unapplied/server/0375-Improve-Legacy-Component-serialization-size.patch => server/0372-Improve-Legacy-Component-serialization-size.patch} (97%) rename patches/{unapplied/server/0376-Add-Plugin-Tickets-to-API-Chunk-Methods.patch => server/0373-Add-Plugin-Tickets-to-API-Chunk-Methods.patch} (89%) rename patches/{unapplied/server/0377-Add-BlockStateMeta-clearBlockState.patch => server/0374-Add-BlockStateMeta-clearBlockState.patch} (100%) rename patches/{unapplied/server/0378-Convert-legacy-attributes-in-Item-Meta.patch => server/0375-Convert-legacy-attributes-in-Item-Meta.patch} (95%) rename patches/{unapplied/server/0379-Do-not-accept-invalid-client-settings.patch => server/0376-Do-not-accept-invalid-client-settings.patch} (90%) rename patches/{unapplied/server/0380-Improve-fix-EntityTargetLivingEntityEvent.patch => server/0377-Improve-fix-EntityTargetLivingEntityEvent.patch} (91%) rename patches/{unapplied/server/0381-Add-entity-liquid-API.patch => server/0378-Add-entity-liquid-API.patch} (90%) rename patches/{unapplied/server/0382-Add-PrepareResultEvent.patch => server/0379-Add-PrepareResultEvent.patch} (83%) rename patches/{unapplied/server/0383-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch => server/0380-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch} (85%) rename patches/{unapplied/server/0384-Fix-arrows-never-despawning-MC-125757.patch => server/0381-Fix-arrows-never-despawning-MC-125757.patch} (83%) rename patches/{unapplied/server/0385-Thread-Safe-Vanilla-Command-permission-checking.patch => server/0382-Thread-Safe-Vanilla-Command-permission-checking.patch} (93%) rename patches/{unapplied/server/0386-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch => server/0383-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch} (97%) rename patches/{unapplied/server/0387-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch => server/0384-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch} (89%) rename patches/{unapplied/server/0388-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch => server/0385-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch} (97%) rename patches/{unapplied/server/0389-Optimize-NetworkManager-Exception-Handling.patch => server/0386-Optimize-NetworkManager-Exception-Handling.patch} (100%) rename patches/{unapplied/server/0390-Fix-some-rails-connecting-improperly.patch => server/0387-Fix-some-rails-connecting-improperly.patch} (91%) rename patches/{unapplied/server/0391-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch => server/0388-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch} (100%) rename patches/{unapplied/server/0392-Brand-support.patch => server/0389-Brand-support.patch} (87%) rename patches/{unapplied/server/0393-Add-playPickupItemAnimation-to-LivingEntity.patch => server/0390-Add-playPickupItemAnimation-to-LivingEntity.patch} (81%) rename patches/{unapplied/server/0394-Don-t-require-FACING-data.patch => server/0391-Don-t-require-FACING-data.patch} (100%) rename patches/{unapplied/server/0395-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch => server/0392-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch} (86%) rename patches/{unapplied/server/0396-Add-moon-phase-API.patch => server/0393-Add-moon-phase-API.patch} (90%) create mode 100644 patches/server/0394-Do-not-let-the-server-load-chunks-from-newer-version.patch rename patches/{unapplied/server/0398-Prevent-headless-pistons-from-being-created.patch => server/0395-Prevent-headless-pistons-from-being-created.patch} (65%) rename patches/{unapplied/server/0399-Add-BellRingEvent.patch => server/0396-Add-BellRingEvent.patch} (90%) rename patches/{unapplied/server/0400-Add-zombie-targets-turtle-egg-config.patch => server/0397-Add-zombie-targets-turtle-egg-config.patch} (87%) rename patches/{unapplied/server/0401-Buffer-joins-to-world.patch => server/0398-Buffer-joins-to-world.patch} (100%) rename patches/{unapplied/server/0402-Fix-hex-colors-not-working-in-some-kick-messages.patch => server/0399-Fix-hex-colors-not-working-in-some-kick-messages.patch} (97%) rename patches/{unapplied/server/0403-Add-more-Evoker-API.patch => server/0400-Add-more-Evoker-API.patch} (100%) rename patches/{unapplied/server/0404-Add-methods-to-get-translation-keys.patch => server/0401-Add-methods-to-get-translation-keys.patch} (97%) rename patches/{unapplied/server/0405-Create-HoverEvent-from-ItemStack-Entity.patch => server/0402-Create-HoverEvent-from-ItemStack-Entity.patch} (94%) rename patches/{unapplied/server/0406-Cache-block-data-strings.patch => server/0403-Cache-block-data-strings.patch} (86%) rename patches/{unapplied/server/0407-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch => server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch} (78%) delete mode 100644 patches/unapplied/server/0369-Add-PlayerRecipeBookClickEvent.patch delete mode 100644 patches/unapplied/server/0397-Do-not-let-the-server-load-chunks-from-newer-version.patch diff --git a/patches/unapplied/server/0368-Inventory-getHolder-method-without-block-snapshot.patch b/patches/server/0365-Inventory-getHolder-method-without-block-snapshot.patch similarity index 100% rename from patches/unapplied/server/0368-Inventory-getHolder-method-without-block-snapshot.patch rename to patches/server/0365-Inventory-getHolder-method-without-block-snapshot.patch diff --git a/patches/server/0366-Add-PlayerRecipeBookClickEvent.patch b/patches/server/0366-Add-PlayerRecipeBookClickEvent.patch new file mode 100644 index 000000000000..e2e9336c486d --- /dev/null +++ b/patches/server/0366-Add-PlayerRecipeBookClickEvent.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: JRoy +Date: Fri, 5 Jun 2020 18:24:06 -0400 +Subject: [PATCH] Add PlayerRecipeBookClickEvent + + +diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index e329503681961566a76a383245303e88acef37a4..5b1c8fb2765407cab1ca41d8d2fce83df1cc5fe1 100644 +--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -200,6 +200,7 @@ import net.minecraft.world.phys.Vec3; + import net.minecraft.world.phys.shapes.BooleanOp; + import net.minecraft.world.phys.shapes.Shapes; + import net.minecraft.world.phys.shapes.VoxelShape; ++import org.bukkit.NamespacedKey; + import org.slf4j.Logger; + + // CraftBukkit start +@@ -3086,21 +3087,41 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + ServerGamePacketListenerImpl.LOGGER.debug("Player {} tried to place impossible recipe {}", this.player, recipeholder.id().location()); + return; + } ++ // Paper start - Add PlayerRecipeBookClickEvent ++ NamespacedKey recipeName = org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(recipeholder.id().location()); ++ boolean makeAll = packet.useMaxItems(); ++ com.destroystokyo.paper.event.player.PlayerRecipeBookClickEvent paperEvent = new com.destroystokyo.paper.event.player.PlayerRecipeBookClickEvent( ++ this.player.getBukkitEntity(), recipeName, makeAll ++ ); ++ if (!paperEvent.callEvent()) { ++ return; ++ } ++ recipeName = paperEvent.getRecipe(); ++ makeAll = paperEvent.isMakeAll(); ++ if (org.bukkit.event.player.PlayerRecipeBookClickEvent.getHandlerList().getRegisteredListeners().length > 0) { ++ // Paper end - Add PlayerRecipeBookClickEvent + + // CraftBukkit start - implement PlayerRecipeBookClickEvent +- org.bukkit.inventory.Recipe recipe = recipeholder.toBukkitRecipe(); ++ org.bukkit.inventory.Recipe recipe = this.cserver.getRecipe(recipeName); // Paper - Add PlayerRecipeBookClickEvent - forward to legacy event + if (recipe == null) { + return; + } +- org.bukkit.event.player.PlayerRecipeBookClickEvent event = CraftEventFactory.callRecipeBookClickEvent(this.player, recipe, packet.useMaxItems()); ++ // Paper start - Add PlayerRecipeBookClickEvent - forward to legacy event ++ org.bukkit.event.player.PlayerRecipeBookClickEvent event = CraftEventFactory.callRecipeBookClickEvent(this.player, recipe, makeAll); ++ recipeName = ((org.bukkit.Keyed) event.getRecipe()).getKey(); ++ makeAll = event.isShiftClick(); ++ } ++ if (!(this.player.containerMenu instanceof RecipeBookMenu)) { ++ return; ++ } ++ // Paper end - Add PlayerRecipeBookClickEvent - forward to legacy event + + // Cast to keyed should be safe as the recipe will never be a MerchantRecipe. +- recipeholder = this.server.getRecipeManager().byKey(CraftRecipe.toMinecraft(((org.bukkit.Keyed) event.getRecipe()).getKey())).orElse(null); ++ recipeholder = this.server.getRecipeManager().byKey(net.minecraft.resources.ResourceKey.create(net.minecraft.core.registries.Registries.RECIPE, org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(recipeName))).orElse(null); // Paper - Add PlayerRecipeBookClickEvent - forward to legacy event + if (recipeholder == null) { + return; + } +- +- RecipeBookMenu.PostPlaceAction containerrecipebook_a = containerrecipebook.handlePlacement(event.isShiftClick(), this.player.isCreative(), recipeholder, this.player.serverLevel(), this.player.getInventory()); ++ RecipeBookMenu.PostPlaceAction containerrecipebook_a = containerrecipebook.handlePlacement(makeAll, this.player.isCreative(), recipeholder, this.player.serverLevel(), this.player.getInventory()); + // CraftBukkit end + + if (containerrecipebook_a == RecipeBookMenu.PostPlaceAction.PLACE_GHOST_RECIPE) { diff --git a/patches/unapplied/server/0370-Hide-sync-chunk-writes-behind-flag.patch b/patches/server/0367-Hide-sync-chunk-writes-behind-flag.patch similarity index 93% rename from patches/unapplied/server/0370-Hide-sync-chunk-writes-behind-flag.patch rename to patches/server/0367-Hide-sync-chunk-writes-behind-flag.patch index e8889b31d8b0..c0da32d0ed51 100644 --- a/patches/unapplied/server/0370-Hide-sync-chunk-writes-behind-flag.patch +++ b/patches/server/0367-Hide-sync-chunk-writes-behind-flag.patch @@ -9,7 +9,7 @@ on harddrives. -DPaper.enable-sync-chunk-writes=true to enable diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java -index eb27ef574445e1311b763d84aa1b37128baa75f7..d6431376184e5650b370cbab204e28bc31f4dac6 100644 +index 47835226b61b726c750fe192fd94d3f8ba47565c..52e61f75f922a075ccc745198f4ba6ad8fa58ea2 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java @@ -146,7 +146,7 @@ public class DedicatedServerProperties extends Settings diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 10015beb7a2de890fe27bffde8f55c1dd78ce344..9d08d0610be1741b4cd18a1454e538f46928fd94 100644 +index 4faba83eb73e0d313e9131794962b727f7628a50..7fdfe1dd09812df1d8d7e5f95bcaf1b48c814e22 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -669,8 +669,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -677,8 +677,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public void setPos(double x, double y, double z) { @@ -20,7 +20,7 @@ index 10015beb7a2de890fe27bffde8f55c1dd78ce344..9d08d0610be1741b4cd18a1454e538f4 } protected AABB makeBoundingBox() { -@@ -4223,7 +4223,29 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4412,7 +4412,29 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this.getZ((2.0D * this.random.nextDouble() - 1.0D) * widthScale); } @@ -50,7 +50,7 @@ index 10015beb7a2de890fe27bffde8f55c1dd78ce344..9d08d0610be1741b4cd18a1454e538f4 if (this.position.x != x || this.position.y != y || this.position.z != z) { this.position = new Vec3(x, y, z); int i = Mth.floor(x); -@@ -4241,6 +4263,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4430,6 +4452,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.levelCallback.onMove(); } diff --git a/patches/unapplied/server/0373-Fix-Per-World-Difficulty-Remembering-Difficulty.patch b/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch similarity index 79% rename from patches/unapplied/server/0373-Fix-Per-World-Difficulty-Remembering-Difficulty.patch rename to patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch index 3fec1cd01408..d6a667ddb78b 100644 --- a/patches/unapplied/server/0373-Fix-Per-World-Difficulty-Remembering-Difficulty.patch +++ b/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch @@ -8,19 +8,19 @@ makes it so that the server keeps the last difficulty used instead of restoring the server.properties every single load. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 0370d26bd1e1d2fe1d640b052aca8a9c05dcb9dc..dd5f74fe4c8ca81b1d1102805ea8acb9087ba91e 100644 +index b4eff440e3d9489f99e10a73611421ef877aa871..9109628a48026ceca9dd53a3e75f79510e56c95c 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -836,7 +836,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> { net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk)c; diff --git a/patches/unapplied/server/0377-Add-BlockStateMeta-clearBlockState.patch b/patches/server/0374-Add-BlockStateMeta-clearBlockState.patch similarity index 100% rename from patches/unapplied/server/0377-Add-BlockStateMeta-clearBlockState.patch rename to patches/server/0374-Add-BlockStateMeta-clearBlockState.patch diff --git a/patches/unapplied/server/0378-Convert-legacy-attributes-in-Item-Meta.patch b/patches/server/0375-Convert-legacy-attributes-in-Item-Meta.patch similarity index 95% rename from patches/unapplied/server/0378-Convert-legacy-attributes-in-Item-Meta.patch rename to patches/server/0375-Convert-legacy-attributes-in-Item-Meta.patch index 76437f1a9bc3..87efb884b240 100644 --- a/patches/unapplied/server/0378-Convert-legacy-attributes-in-Item-Meta.patch +++ b/patches/server/0375-Convert-legacy-attributes-in-Item-Meta.patch @@ -30,10 +30,10 @@ index de40e522960469b98f987bd688489740446d9f85..5678d2007d5adf45dec0638c5dd848b6 public CraftAttributeMap(AttributeMap handle) { this.handle = handle; diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index 97c40582bca095532fff9a81515f38ea4ac527e0..5c76ba7f9ceb285d27e18369172612205be96224 100644 +index b2683d6efd53b03d7043098b19a1504885a5b3c7..af78e73755743fb2db7a99b834affc963b44bc10 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -@@ -702,7 +702,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -810,7 +810,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { AttributeModifier attribMod = CraftAttributeInstance.convert(nmsModifier); diff --git a/patches/unapplied/server/0379-Do-not-accept-invalid-client-settings.patch b/patches/server/0376-Do-not-accept-invalid-client-settings.patch similarity index 90% rename from patches/unapplied/server/0379-Do-not-accept-invalid-client-settings.patch rename to patches/server/0376-Do-not-accept-invalid-client-settings.patch index e0e0f8912eb7..65e274aa2bd0 100644 --- a/patches/unapplied/server/0379-Do-not-accept-invalid-client-settings.patch +++ b/patches/server/0376-Do-not-accept-invalid-client-settings.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Do not accept invalid client settings diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index d2eb8c619905d87a38820a4c1179ad93093c0ac3..90e5f263dcb8033dae3ca32cbf5dbd332a109282 100644 +index 510c97062d77541425aed6ddaaad58be4290967b..09bb38460ab6fa7b6132e245d52b60244bd248eb 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3251,6 +3251,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3296,6 +3296,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleClientInformation(ServerboundClientInformationPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); diff --git a/patches/unapplied/server/0380-Improve-fix-EntityTargetLivingEntityEvent.patch b/patches/server/0377-Improve-fix-EntityTargetLivingEntityEvent.patch similarity index 91% rename from patches/unapplied/server/0380-Improve-fix-EntityTargetLivingEntityEvent.patch rename to patches/server/0377-Improve-fix-EntityTargetLivingEntityEvent.patch index 29703174a113..2777b41e1167 100644 --- a/patches/unapplied/server/0380-Improve-fix-EntityTargetLivingEntityEvent.patch +++ b/patches/server/0377-Improve-fix-EntityTargetLivingEntityEvent.patch @@ -5,11 +5,11 @@ Subject: [PATCH] Improve/fix EntityTargetLivingEntityEvent diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java b/src/main/java/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java -index cc7d161b53a2295fa1745254eafb8a70c7b6c7b2..508d4f391fe563453d7bf6782b3082741c358006 100644 +index 70df68169b17fa5f732e4c73a86376ba6eb9ca13..b31f6ccc95132a7dd022b454d28814b684d99d4c 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/StopAttackingIfTargetInvalid.java -@@ -47,9 +47,22 @@ public class StopAttackingIfTargetInvalid { - if (entityinsentient.canAttack(entityliving) && (!shouldForgetIfTargetUnreachable || !StopAttackingIfTargetInvalid.isTiredOfTryingToReachTarget(entityinsentient, behaviorbuilder_b.tryGet(memoryaccessor1))) && entityliving.isAlive() && entityliving.level() == entityinsentient.level() && !alternativeCondition.test(entityliving)) { +@@ -46,9 +46,22 @@ public class StopAttackingIfTargetInvalid { + if (entityinsentient.canAttack(entityliving) && (!shouldForgetIfTargetUnreachable || !StopAttackingIfTargetInvalid.isTiredOfTryingToReachTarget(entityinsentient, behaviorbuilder_b.tryGet(memoryaccessor1))) && entityliving.isAlive() && entityliving.level() == entityinsentient.level() && !condition.test(worldserver, entityliving)) { return true; } else { + // Paper start - better track target change reason diff --git a/patches/unapplied/server/0381-Add-entity-liquid-API.patch b/patches/server/0378-Add-entity-liquid-API.patch similarity index 90% rename from patches/unapplied/server/0381-Add-entity-liquid-API.patch rename to patches/server/0378-Add-entity-liquid-API.patch index 51765a7f3a58..849eeec01f02 100644 --- a/patches/unapplied/server/0381-Add-entity-liquid-API.patch +++ b/patches/server/0378-Add-entity-liquid-API.patch @@ -8,10 +8,10 @@ public net.minecraft.world.entity.Entity isInRain()Z public net.minecraft.world.entity.Entity isInBubbleColumn()Z diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index ce70c8fddbe63d0af2b1f988ce9a2b40c5d48066..34321f095e12ea0cca34ff1ec00819c6350205a8 100644 +index 7fb04535b8c0744d0fa4b0c0a933234134486956..b001284e368f64871824c1f961999bb3f726de57 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1025,4 +1025,41 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1026,4 +1026,41 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return getHandle().spawnReason; } // Paper end - entity spawn reason API diff --git a/patches/unapplied/server/0382-Add-PrepareResultEvent.patch b/patches/server/0379-Add-PrepareResultEvent.patch similarity index 83% rename from patches/unapplied/server/0382-Add-PrepareResultEvent.patch rename to patches/server/0379-Add-PrepareResultEvent.patch index 985e40f2aeb9..9fb630a728a6 100644 --- a/patches/unapplied/server/0382-Add-PrepareResultEvent.patch +++ b/patches/server/0379-Add-PrepareResultEvent.patch @@ -8,10 +8,10 @@ Adds a new event for all crafting stations that generate a result slot item Anvil, Grindstone and Smithing now extend this event diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java -index ffda2c984c5683edb38a56f04c53b0ea339e08fc..d685511104ac552dfc9ae2111e1bfb60fa812102 100644 +index 126565e673e94b9c66aa4547596bbf198c57c7ad..cc5aae32f34305965847ade8b530272b1126b5c9 100644 --- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java -@@ -327,6 +327,7 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -333,6 +333,7 @@ public class AnvilMenu extends ItemCombinerMenu { } this.createResult(); @@ -20,10 +20,10 @@ index ffda2c984c5683edb38a56f04c53b0ea339e08fc..d685511104ac552dfc9ae2111e1bfb60 } else { return false; diff --git a/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java -index 11d7bf4f90083991cfc8c6c5f9a1e8ad6a162843..c52c4c4210bc6ae082443318d9795c48c816aba6 100644 +index 5b31d09b158c694b3e54ab3a228817accaa00a0c..8b72d1fd551dcb113f4137aee441a9531c00288a 100644 --- a/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java +++ b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java -@@ -152,6 +152,7 @@ public class CartographyTableMenu extends AbstractContainerMenu { +@@ -140,6 +140,7 @@ public class CartographyTableMenu extends AbstractContainerMenu { this.setupResultSlot(itemstack, itemstack1, itemstack2); } @@ -32,10 +32,10 @@ index 11d7bf4f90083991cfc8c6c5f9a1e8ad6a162843..c52c4c4210bc6ae082443318d9795c48 private void setupResultSlot(ItemStack map, ItemStack item, ItemStack oldResult) { diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java -index 637d77d6b07ff9ee5ac1cb0470cbefcba5c7495e..15ec798e149d80aace186f84b9236ddeaba690c3 100644 +index 13bc52bc856031c930370828b0381e43920aabd2..8e58dbb4b110338dfe8add26697d0b1c9ec5fa9c 100644 --- a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java +++ b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java -@@ -160,6 +160,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { +@@ -148,6 +148,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { super.slotsChanged(inventory); if (inventory == this.repairSlots) { this.createResult(); @@ -44,10 +44,10 @@ index 637d77d6b07ff9ee5ac1cb0470cbefcba5c7495e..15ec798e149d80aace186f84b9236dde } diff --git a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java -index 62432c347b86fc79ab529a7dde66bef32d0424dd..be840717e180b6b5abd14db6cc9263349737f9a3 100644 +index 594a387d7e3a67da02ea54b4f259426df2eb21a2..4734dd90f2a66e1ac7a64b35ecd62a630108cf07 100644 --- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java -@@ -110,6 +110,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { +@@ -96,6 +96,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { super.slotsChanged(inventory); if (inventory == this.inputSlots) { this.createResult(); @@ -56,10 +56,10 @@ index 62432c347b86fc79ab529a7dde66bef32d0424dd..be840717e180b6b5abd14db6cc926334 } diff --git a/src/main/java/net/minecraft/world/inventory/LoomMenu.java b/src/main/java/net/minecraft/world/inventory/LoomMenu.java -index 69ed0753c224cb7746762b4b94c4d79d608951b8..2de558dd205a1078fdcac1bce256d059b9bf5d5f 100644 +index d988747ccb81ca74db8ce14fea49d13c9c1b4476..58470d8e9a4ceb1eca05b342481ed8260588e225 100644 --- a/src/main/java/net/minecraft/world/inventory/LoomMenu.java +++ b/src/main/java/net/minecraft/world/inventory/LoomMenu.java -@@ -249,7 +249,8 @@ public class LoomMenu extends AbstractContainerMenu { +@@ -237,7 +237,8 @@ public class LoomMenu extends AbstractContainerMenu { this.resultSlot.set(ItemStack.EMPTY); } @@ -70,11 +70,11 @@ index 69ed0753c224cb7746762b4b94c4d79d608951b8..2de558dd205a1078fdcac1bce256d059 this.resultSlot.set(ItemStack.EMPTY); this.selectablePatterns = List.of(); diff --git a/src/main/java/net/minecraft/world/inventory/SmithingMenu.java b/src/main/java/net/minecraft/world/inventory/SmithingMenu.java -index 0735705def4f9505b7f16df2497cc78bbf5a8373..86e51fcce767d265ee0d3beb611be2119085830b 100644 +index 4b0d07a22cb922aa5ef0c99279663158a5918f1f..89d2f26504bb072c2d75af4ec600ca123e10a600 100644 --- a/src/main/java/net/minecraft/world/inventory/SmithingMenu.java +++ b/src/main/java/net/minecraft/world/inventory/SmithingMenu.java -@@ -121,6 +121,7 @@ public class SmithingMenu extends ItemCombinerMenu { - } +@@ -115,6 +115,7 @@ public class SmithingMenu extends ItemCombinerMenu { + this.hasRecipeError.set(flag ? 1 : 0); } + org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareResultEvent(this, RESULT_SLOT); // Paper - Add PrepareResultEvent @@ -82,22 +82,22 @@ index 0735705def4f9505b7f16df2497cc78bbf5a8373..86e51fcce767d265ee0d3beb611be211 @Override diff --git a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java -index 30ea1f9e97db86a2ad7baeea4f5a76c821874daa..5b4f03128499b0c1a4b8c5f5ccd17e4bdb391e81 100644 +index 0fb0ee5b22dc96c48d68e4391fd71b03d4e799f0..97837d1baf6b929a50e5562ef466050e70c2c8b1 100644 --- a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java +++ b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java -@@ -182,6 +182,7 @@ public class StonecutterMenu extends AbstractContainerMenu { - this.setupRecipeList(inventory, itemstack); +@@ -170,6 +170,7 @@ public class StonecutterMenu extends AbstractContainerMenu { + this.setupRecipeList(itemstack); } + org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareResultEvent(this, RESULT_SLOT); // Paper - Add PrepareResultEvent } - private static SingleRecipeInput createRecipeInput(Container inventory) { + private void setupRecipeList(ItemStack stack) { diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index f3ec3d14e66b9c1dff32088d4aef57e21265048c..f633d08b35bf9018367a449cc000c6c6ca5a44cd 100644 +index b40117e9940ab493ea4a945dbd9754a38b1159b9..62f4fd6553ab0310e2c0dde1d917c63679365798 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1681,6 +1681,12 @@ public class CraftEventFactory { +@@ -1679,6 +1679,12 @@ populateFields(victim, event); // Paper - make cancellable } public static PrepareAnvilEvent callPrepareAnvilEvent(AnvilView view, ItemStack item) { @@ -110,7 +110,7 @@ index f3ec3d14e66b9c1dff32088d4aef57e21265048c..f633d08b35bf9018367a449cc000c6c6 PrepareAnvilEvent event = new PrepareAnvilEvent(view, CraftItemStack.asCraftMirror(item).clone()); event.getView().getPlayer().getServer().getPluginManager().callEvent(event); event.getInventory().setItem(2, event.getResult()); -@@ -1688,6 +1694,12 @@ public class CraftEventFactory { +@@ -1686,6 +1692,12 @@ populateFields(victim, event); // Paper - make cancellable } public static PrepareGrindstoneEvent callPrepareGrindstoneEvent(InventoryView view, ItemStack item) { @@ -123,7 +123,7 @@ index f3ec3d14e66b9c1dff32088d4aef57e21265048c..f633d08b35bf9018367a449cc000c6c6 PrepareGrindstoneEvent event = new PrepareGrindstoneEvent(view, CraftItemStack.asCraftMirror(item).clone()); event.getView().getPlayer().getServer().getPluginManager().callEvent(event); event.getInventory().setItem(2, event.getResult()); -@@ -1695,12 +1707,39 @@ public class CraftEventFactory { +@@ -1693,12 +1705,39 @@ populateFields(victim, event); // Paper - make cancellable } public static PrepareSmithingEvent callPrepareSmithingEvent(InventoryView view, ItemStack item) { diff --git a/patches/unapplied/server/0383-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch b/patches/server/0380-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch similarity index 85% rename from patches/unapplied/server/0383-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch rename to patches/server/0380-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch index 24d5f2e649b8..e97a181c5326 100644 --- a/patches/unapplied/server/0383-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch +++ b/patches/server/0380-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Don't check chunk for portal on world gen entity add diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 8920099eb488c37b036b7bd97fbd4f7db505c77c..906e8589483b93bcdb55677f7f942f6c7a89caf8 100644 +index 65909e0a8f8b68f9a4dacefda9069c8263a96ada..91a5166e69a03d846a1b396ba964003c12a0dcdb 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3659,7 +3659,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3798,7 +3798,7 @@ public abstract class LivingEntity extends Entity implements Attackable { Entity entity = this.getVehicle(); super.stopRiding(suppressCancellation); // Paper - Force entity dismount during teleportation diff --git a/patches/unapplied/server/0384-Fix-arrows-never-despawning-MC-125757.patch b/patches/server/0381-Fix-arrows-never-despawning-MC-125757.patch similarity index 83% rename from patches/unapplied/server/0384-Fix-arrows-never-despawning-MC-125757.patch rename to patches/server/0381-Fix-arrows-never-despawning-MC-125757.patch index dbcb4ce450dd..ed2c8a340960 100644 --- a/patches/unapplied/server/0384-Fix-arrows-never-despawning-MC-125757.patch +++ b/patches/server/0381-Fix-arrows-never-despawning-MC-125757.patch @@ -9,12 +9,12 @@ instead of getting stuck in a never despawn state (bubble columns, etc). diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -index 6c79997ba46e641de5aa12ff8a3d790d04a5a475..746bb8a36bd6c6ef953289576af499caad588d79 100644 +index 78053060dbff7f8a859f9fecb356491f497eed7e..bc167c21f82ad09952f6cdbf1016523062890f8b 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -@@ -238,6 +238,7 @@ public abstract class AbstractArrow extends Projectile { +@@ -242,6 +242,7 @@ public abstract class AbstractArrow extends Projectile { + } - ++this.inGroundTime; } else { + if (tickCount > 200) this.tickDespawn(); // Paper - tick despawnCounter regardless after 10 seconds this.inGroundTime = 0; diff --git a/patches/unapplied/server/0385-Thread-Safe-Vanilla-Command-permission-checking.patch b/patches/server/0382-Thread-Safe-Vanilla-Command-permission-checking.patch similarity index 93% rename from patches/unapplied/server/0385-Thread-Safe-Vanilla-Command-permission-checking.patch rename to patches/server/0382-Thread-Safe-Vanilla-Command-permission-checking.patch index a210e43dce33..475b27747071 100644 --- a/patches/unapplied/server/0385-Thread-Safe-Vanilla-Command-permission-checking.patch +++ b/patches/server/0382-Thread-Safe-Vanilla-Command-permission-checking.patch @@ -26,10 +26,10 @@ index 14ccd0c8f721e9be7dca8a5dcb8ef95b5cd82731..1f4963bf4681a771130abc1da1798196 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java -index 2a22827f44dd0d524c22264447959a6979e9f0de..f3c83bb20a73b489f1fb6bacb69388902b1b6fe7 100644 +index 5316f148f3f9128690f019d544e462b042d8d797..f31c5d665678c3163ed4469f8e9d395b890c1bbe 100644 --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java +++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java -@@ -64,7 +64,7 @@ public class CommandSourceStack implements ExecutionCommandSource> list = null; diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java -index 4c85abf29441645039b6a554a50e1d3274229de6..d85fb1e2ea0eaef81e9039b47d18f83507e05a59 100644 +index 0542b61053ed7039e54856eab86ba5842403e4fc..0fe941b0802f2966ad55509baac124f56ecef999 100644 --- a/src/main/java/net/minecraft/server/PlayerAdvancements.java +++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java @@ -63,6 +63,7 @@ public class PlayerAdvancements { diff --git a/patches/unapplied/server/0389-Optimize-NetworkManager-Exception-Handling.patch b/patches/server/0386-Optimize-NetworkManager-Exception-Handling.patch similarity index 100% rename from patches/unapplied/server/0389-Optimize-NetworkManager-Exception-Handling.patch rename to patches/server/0386-Optimize-NetworkManager-Exception-Handling.patch diff --git a/patches/unapplied/server/0390-Fix-some-rails-connecting-improperly.patch b/patches/server/0387-Fix-some-rails-connecting-improperly.patch similarity index 91% rename from patches/unapplied/server/0390-Fix-some-rails-connecting-improperly.patch rename to patches/server/0387-Fix-some-rails-connecting-improperly.patch index 4f5cd8653888..c22d4e1fdf89 100644 --- a/patches/unapplied/server/0390-Fix-some-rails-connecting-improperly.patch +++ b/patches/server/0387-Fix-some-rails-connecting-improperly.patch @@ -5,22 +5,22 @@ Subject: [PATCH] Fix some rails connecting improperly diff --git a/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java b/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java -index f9b6db516fa0788a6d4d40fa7ea2039cd3282b24..0961f6f5e627debe0bf02670d922e6d3388ba631 100644 +index 4a5badc4bb1e2c29016735e9df93c7ac4d3f363d..f9a55f76fed8609bca167b2ea37464e8079de0c0 100644 --- a/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BaseRailBlock.java -@@ -68,6 +68,7 @@ public abstract class BaseRailBlock extends Block implements SimpleWaterloggedBl +@@ -71,6 +71,7 @@ public abstract class BaseRailBlock extends Block implements SimpleWaterloggedBl state = this.updateDir(world, pos, state, true); if (this.isStraight) { - world.neighborChanged(state, pos, this, pos, notify); + world.neighborChanged(state, pos, this, null, notify); + state = world.getBlockState(pos); // Paper - Fix some rails connecting improperly } return state; diff --git a/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java b/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java -index e5534fd35a8f9736cc25471e9f0feaa8da88c85d..55a97da8786ec0ae98abe56876c00f4678ba0007 100644 +index 3de30845aae143e5be5db921004142792522607d..1e2f56b5c40c3dc72bc38354160f8e7de1f4f5cf 100644 --- a/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java -@@ -77,6 +77,7 @@ public class DetectorRailBlock extends BaseRailBlock { +@@ -78,6 +78,7 @@ public class DetectorRailBlock extends BaseRailBlock { private void checkPressed(Level world, BlockPos pos, BlockState state) { if (this.canSurvive(state, world, pos)) { diff --git a/patches/unapplied/server/0391-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch b/patches/server/0388-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch similarity index 100% rename from patches/unapplied/server/0391-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch rename to patches/server/0388-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch diff --git a/patches/unapplied/server/0392-Brand-support.patch b/patches/server/0389-Brand-support.patch similarity index 87% rename from patches/unapplied/server/0392-Brand-support.patch rename to patches/server/0389-Brand-support.patch index af42b533fd93..74047404172e 100644 --- a/patches/unapplied/server/0392-Brand-support.patch +++ b/patches/server/0389-Brand-support.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Brand support diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index e6e7dc17d1196a8211a565355f34b5dcfd478852..45181bc9c422507682d479e4d43177ecd3253971 100644 +index 807068fc6065f71961d34cb4f18b6eb39ae49637..c468947990cf05e554006e51d87b72fad7c28e55 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -294,6 +294,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -322,6 +322,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { // CraftBukkit end public boolean isRealPlayer; // Paper public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent @@ -17,10 +17,10 @@ index e6e7dc17d1196a8211a565355f34b5dcfd478852..45181bc9c422507682d479e4d43177ec public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) { super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 4f62abfe62c951b7a1df36ece34747100d6a4ff7..48085b2e7197dc44e76b812bdd514af729e21e83 100644 +index b9fbaddcc8239bf737fdea51790f678306e511eb..9a8b08d4b70b8890961e4af7ce6e870aa1c7c810 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -83,6 +83,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -84,6 +84,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack private volatile boolean suspendFlushingOnServerThread = false; public final java.util.Map packCallbacks = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - adventure resource pack callbacks private static final long KEEPALIVE_LIMIT = Long.getLong("paper.playerconnection.keepalive", 30) * 1000; // Paper - provide property to set keepalive limit @@ -28,7 +28,7 @@ index 4f62abfe62c951b7a1df36ece34747100d6a4ff7..48085b2e7197dc44e76b812bdd514af7 public ServerCommonPacketListenerImpl(MinecraftServer minecraftserver, Connection networkmanager, CommonListenerCookie commonlistenercookie, ServerPlayer player) { // CraftBukkit this.server = minecraftserver; -@@ -148,6 +149,11 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -155,6 +156,11 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack @Override public void handleCustomPayload(ServerboundCustomPayloadPacket packet) { @@ -40,7 +40,7 @@ index 4f62abfe62c951b7a1df36ece34747100d6a4ff7..48085b2e7197dc44e76b812bdd514af7 if (!(packet.payload() instanceof DiscardedPayload)) { return; } -@@ -179,6 +185,15 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -186,6 +192,15 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack try { byte[] data = new byte[payload.readableBytes()]; payload.readBytes(data); @@ -57,10 +57,10 @@ index 4f62abfe62c951b7a1df36ece34747100d6a4ff7..48085b2e7197dc44e76b812bdd514af7 } catch (Exception ex) { ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t dispatch custom payload", ex); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 068ff2c228308ec87fcc6d1352bd63b91bd34a93..854533854dfba24b59a15265ac759331e3ddfc74 100644 +index f836a65db1028b51ebd425251ca37e0c439d4ad6..eb2954c9b51d4fd76cf5aec17899218f4de7076d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3139,6 +3139,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3152,6 +3152,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Paper end }; diff --git a/patches/unapplied/server/0393-Add-playPickupItemAnimation-to-LivingEntity.patch b/patches/server/0390-Add-playPickupItemAnimation-to-LivingEntity.patch similarity index 81% rename from patches/unapplied/server/0393-Add-playPickupItemAnimation-to-LivingEntity.patch rename to patches/server/0390-Add-playPickupItemAnimation-to-LivingEntity.patch index e66408f81493..64c59dce175c 100644 --- a/patches/unapplied/server/0393-Add-playPickupItemAnimation-to-LivingEntity.patch +++ b/patches/server/0390-Add-playPickupItemAnimation-to-LivingEntity.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add playPickupItemAnimation to LivingEntity diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 733c69a2cfa60fb8c920400e3d9acfc2465090e5..fad7d8130f6db70c7bfca9d02027d8a41f5309c1 100644 +index 35130dc4e20ef644b5764091fcbccda2e4da780b..5beee554567d36f2a3b871cf6ec3ecb3d2353592 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -990,4 +990,11 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -1009,4 +1009,11 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { } } // Paper end - entity jump API diff --git a/patches/unapplied/server/0394-Don-t-require-FACING-data.patch b/patches/server/0391-Don-t-require-FACING-data.patch similarity index 100% rename from patches/unapplied/server/0394-Don-t-require-FACING-data.patch rename to patches/server/0391-Don-t-require-FACING-data.patch diff --git a/patches/unapplied/server/0395-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch b/patches/server/0392-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch similarity index 86% rename from patches/unapplied/server/0395-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch rename to patches/server/0392-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch index b202f0e93428..44e149484c9b 100644 --- a/patches/unapplied/server/0395-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch +++ b/patches/server/0392-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 5b89d834a7c01530807e61ea25af2b01f004ce86..50d2e628590e8563d2ef5b987f764cf1785e3b50 100644 +index 090d2fde891346ee634a8964b562715f4dd206d0..465b6a1bbdbb193c6ecf5fd1598e1e4a4f8dbbbc 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1668,7 +1668,9 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1730,7 +1730,9 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe float f1 = this.levelData.getSpawnAngle(); if (!blockposition1.equals(pos) || f1 != angle) { @@ -19,10 +19,10 @@ index 5b89d834a7c01530807e61ea25af2b01f004ce86..50d2e628590e8563d2ef5b987f764cf1 } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index c35fd2fcb6ced6a16816637353d03c88f1d49d1b..99fccedaab2600881683140e10ee17377375b911 100644 +index 3ea157df3df6f590195191f2c24faead703a0bf8..04ef1c3433d3ac8a58f0d460877e176668e0fc8f 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -246,12 +246,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -250,12 +250,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean setSpawnLocation(int x, int y, int z, float angle) { try { diff --git a/patches/unapplied/server/0396-Add-moon-phase-API.patch b/patches/server/0393-Add-moon-phase-API.patch similarity index 90% rename from patches/unapplied/server/0396-Add-moon-phase-API.patch rename to patches/server/0393-Add-moon-phase-API.patch index 539ccca6de1b..be42d9302bc9 100644 --- a/patches/unapplied/server/0396-Add-moon-phase-API.patch +++ b/patches/server/0393-Add-moon-phase-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add moon phase API diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index 454f3a08c4d319f3d3fe2b1209c4d8b9fa9d4d08..1963e826548c5a8859c50f57654784c3aef50e44 100644 +index 2b5e8d01a31de154faa18c55cdddd3bd7f462891..93dadbf659e41c923268d8ec782fcbdc8aaeff68 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java @@ -509,4 +509,11 @@ public abstract class CraftRegionAccessor implements RegionAccessor { diff --git a/patches/server/0394-Do-not-let-the-server-load-chunks-from-newer-version.patch b/patches/server/0394-Do-not-let-the-server-load-chunks-from-newer-version.patch new file mode 100644 index 000000000000..3bdfea31f7f8 --- /dev/null +++ b/patches/server/0394-Do-not-let-the-server-load-chunks-from-newer-version.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Zach Brown +Date: Tue, 23 Jul 2019 20:44:47 -0500 +Subject: [PATCH] Do not let the server load chunks from newer versions + +If the server attempts to load a chunk generated by a newer version of +the game, immediately stop the server to prevent data corruption. + +You can override this functionality at your own peril. + +diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +index 92ad7704a77c024afe090488764eaf59a4f7505f..d7a204216332ccbd6bece23bd507be0366ea4d61 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java ++++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +@@ -104,11 +104,25 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + } + // Paper end - guard against serializing mismatching coordinates + ++ // Paper start - Do not let the server load chunks from newer versions ++ private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().getDataVersion().getVersion(); ++ private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion"); ++ // Paper end - Do not let the server load chunks from newer versions ++ + @Nullable + public static SerializableChunkData parse(LevelHeightAccessor world, RegistryAccess registryManager, CompoundTag nbt) { + if (!nbt.contains("Status", 8)) { + return null; + } else { ++ // Paper start - Do not let the server load chunks from newer versions ++ if (nbt.contains("DataVersion", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC)) { ++ final int dataVersion = nbt.getInt("DataVersion"); ++ if (!JUST_CORRUPT_IT && dataVersion > CURRENT_DATA_VERSION) { ++ new RuntimeException("Server attempted to load chunk saved with newer version of minecraft! " + dataVersion + " > " + CURRENT_DATA_VERSION).printStackTrace(); ++ System.exit(1); ++ } ++ } ++ // Paper end - Do not let the server load chunks from newer versions + ChunkPos chunkcoordintpair = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos")); // Paper - guard against serializing mismatching coordinates; diff on change, see ChunkSerializer#getChunkCoordinate + long i = nbt.getLong("LastUpdate"); + long j = nbt.getLong("InhabitedTime"); diff --git a/patches/unapplied/server/0398-Prevent-headless-pistons-from-being-created.patch b/patches/server/0395-Prevent-headless-pistons-from-being-created.patch similarity index 65% rename from patches/unapplied/server/0398-Prevent-headless-pistons-from-being-created.patch rename to patches/server/0395-Prevent-headless-pistons-from-being-created.patch index 9b5071ea2f2b..1cbd0b1c6c33 100644 --- a/patches/unapplied/server/0398-Prevent-headless-pistons-from-being-created.patch +++ b/patches/server/0395-Prevent-headless-pistons-from-being-created.patch @@ -5,11 +5,11 @@ Subject: [PATCH] Prevent headless pistons from being created Prevent headless pistons from being created by explosions or tree/mushroom growth. -diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index d4fe425954d36f0baddb256e3c83009a84084b72..edcc9d53ad81e2b2444335ac79abde5a4e2d9d47 100644 ---- a/src/main/java/net/minecraft/world/level/Explosion.java -+++ b/src/main/java/net/minecraft/world/level/Explosion.java -@@ -208,6 +208,15 @@ public class Explosion { +diff --git a/src/main/java/net/minecraft/world/level/ServerExplosion.java b/src/main/java/net/minecraft/world/level/ServerExplosion.java +index d3d74a7f306d88b0d5cd83893b3ee5e750fd4caf..86656de31b1e33381eddd3ef210122118b31e620 100644 +--- a/src/main/java/net/minecraft/world/level/ServerExplosion.java ++++ b/src/main/java/net/minecraft/world/level/ServerExplosion.java +@@ -164,6 +164,15 @@ public class ServerExplosion implements Explosion { if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this, this.level, blockposition, iblockdata, f)) { set.add(blockposition); @@ -17,8 +17,8 @@ index d4fe425954d36f0baddb256e3c83009a84084b72..edcc9d53ad81e2b2444335ac79abde5a + if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowHeadlessPistons && iblockdata.getBlock() == Blocks.MOVING_PISTON) { + net.minecraft.world.level.block.entity.BlockEntity extension = this.level.getBlockEntity(blockposition); + if (extension instanceof net.minecraft.world.level.block.piston.PistonMovingBlockEntity blockEntity && blockEntity.isSourcePiston()) { -+ net.minecraft.core.Direction direction = iblockdata.getValue(net.minecraft.world.level.block.piston.PistonHeadBlock.FACING); -+ set.add(blockposition.relative(direction.getOpposite())); ++ net.minecraft.core.Direction direction = iblockdata.getValue(net.minecraft.world.level.block.piston.PistonHeadBlock.FACING); ++ set.add(blockposition.relative(direction.getOpposite())); + } + } + // Paper end - prevent headless pistons from forming diff --git a/patches/unapplied/server/0399-Add-BellRingEvent.patch b/patches/server/0396-Add-BellRingEvent.patch similarity index 90% rename from patches/unapplied/server/0399-Add-BellRingEvent.patch rename to patches/server/0396-Add-BellRingEvent.patch index 6a7c834c6a71..9c5162d578d0 100644 --- a/patches/unapplied/server/0399-Add-BellRingEvent.patch +++ b/patches/server/0396-Add-BellRingEvent.patch @@ -7,10 +7,10 @@ Add a new event, BellRingEvent, to trigger whenever a player rings a village bell. Passes along the bell block and the player who rang it. diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index f633d08b35bf9018367a449cc000c6c6ca5a44cd..dbe7931dd7eb43f9381463d3a57ba1eb53820985 100644 +index 62f4fd6553ab0310e2c0dde1d917c63679365798..c7d78f54694b464696c0f1edd0b135d1d5bcde3e 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -378,10 +378,11 @@ public class CraftEventFactory { +@@ -377,10 +377,11 @@ public class CraftEventFactory { return tradeSelectEvent; } diff --git a/patches/unapplied/server/0400-Add-zombie-targets-turtle-egg-config.patch b/patches/server/0397-Add-zombie-targets-turtle-egg-config.patch similarity index 87% rename from patches/unapplied/server/0400-Add-zombie-targets-turtle-egg-config.patch rename to patches/server/0397-Add-zombie-targets-turtle-egg-config.patch index 56529e1fd417..2fb3a9a22c9d 100644 --- a/patches/unapplied/server/0400-Add-zombie-targets-turtle-egg-config.patch +++ b/patches/server/0397-Add-zombie-targets-turtle-egg-config.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add zombie targets turtle egg config diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index e2a3978899497b6622829d6577cfaa723092da9d..78254df3e5fbcb0a90c2f9eb9c9343792238f685 100644 +index 2ed71c9a091bedea276f9043fb0c082dd250cdae..9adcaa646dff7f5415a467a2bfe5b817e17f5640 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -@@ -110,7 +110,7 @@ public class Zombie extends Monster { +@@ -112,7 +112,7 @@ public class Zombie extends Monster { @Override protected void registerGoals() { diff --git a/patches/unapplied/server/0401-Buffer-joins-to-world.patch b/patches/server/0398-Buffer-joins-to-world.patch similarity index 100% rename from patches/unapplied/server/0401-Buffer-joins-to-world.patch rename to patches/server/0398-Buffer-joins-to-world.patch diff --git a/patches/unapplied/server/0402-Fix-hex-colors-not-working-in-some-kick-messages.patch b/patches/server/0399-Fix-hex-colors-not-working-in-some-kick-messages.patch similarity index 97% rename from patches/unapplied/server/0402-Fix-hex-colors-not-working-in-some-kick-messages.patch rename to patches/server/0399-Fix-hex-colors-not-working-in-some-kick-messages.patch index 6124f3252909..1cafcc355b50 100644 --- a/patches/unapplied/server/0402-Fix-hex-colors-not-working-in-some-kick-messages.patch +++ b/patches/server/0399-Fix-hex-colors-not-working-in-some-kick-messages.patch @@ -29,7 +29,7 @@ index 946b423d2184f903dc29c923d7dbe05aaa469c09..0c1bdf2329936ce479a2cc53e8a46bd2 this.connection.disconnect((Component) ichatmutablecomponent); } else { diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index de25b9ea8aa4b7d6fd3fed12cdd16be9ddfcbfff..d2d153e587e624025ef01fbe3dcfa4bf06f1a06b 100644 +index fd9e6781a18d41ca3982788711749d11575566d0..9d5723cdfdbf6257a71e57842aea9ba317fc049a 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -133,7 +133,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, diff --git a/patches/unapplied/server/0403-Add-more-Evoker-API.patch b/patches/server/0400-Add-more-Evoker-API.patch similarity index 100% rename from patches/unapplied/server/0403-Add-more-Evoker-API.patch rename to patches/server/0400-Add-more-Evoker-API.patch diff --git a/patches/unapplied/server/0404-Add-methods-to-get-translation-keys.patch b/patches/server/0401-Add-methods-to-get-translation-keys.patch similarity index 97% rename from patches/unapplied/server/0404-Add-methods-to-get-translation-keys.patch rename to patches/server/0401-Add-methods-to-get-translation-keys.patch index 00eaa98c22c9..bc50b97d021a 100644 --- a/patches/unapplied/server/0404-Add-methods-to-get-translation-keys.patch +++ b/patches/server/0401-Add-methods-to-get-translation-keys.patch @@ -11,7 +11,7 @@ public org.bukkit.craftbukkit.inventory.CraftMetaFirework getNBT(Lorg/bukkit/Fir Co-authored-by: MeFisto94 diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index f041b5d80bff9c022b007e04ef1558e9116acc6b..a586442422a2b2c06b785af0d261d3e19eb1d59b 100644 +index aae00320ab8003420bae5de7df47f553b62c5aab..3fa3de9a89550ec2fcb8ca663742826c0c3136b6 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -669,5 +669,10 @@ public class CraftBlock implements Block { @@ -64,10 +64,10 @@ index f73017bff613bd62b86c974b29576e241c24c927..59c9c970b83f62245d860994c4ac0c21 public String getTranslationKey() { return Util.makeDescriptionId("enchantment", this.handle.unwrapKey().get().location()); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java -index d20fdd4f06faa09c7d9f9e04f379cf0fa68db9bb..66d773cadb74f9176e6cf68a565568034f52ec63 100644 +index 0e9d3d823608a694ef1de5c4fec593951d678c1a..68756419ac6ee292db9569eab380a5c14d748002 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java -@@ -240,4 +240,11 @@ public class CraftItemType implements ItemType.Typed, Han +@@ -237,4 +237,11 @@ public class CraftItemType implements ItemType.Typed, Han public Material asMaterial() { return Registry.MATERIAL.get(this.key); } diff --git a/patches/unapplied/server/0405-Create-HoverEvent-from-ItemStack-Entity.patch b/patches/server/0402-Create-HoverEvent-from-ItemStack-Entity.patch similarity index 94% rename from patches/unapplied/server/0405-Create-HoverEvent-from-ItemStack-Entity.patch rename to patches/server/0402-Create-HoverEvent-from-ItemStack-Entity.patch index 081d6c07e520..ff6ef6b1cc9d 100644 --- a/patches/unapplied/server/0405-Create-HoverEvent-from-ItemStack-Entity.patch +++ b/patches/server/0402-Create-HoverEvent-from-ItemStack-Entity.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Create HoverEvent from ItemStack Entity diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -index fd0df053cd5e8802991e665185e7f90f8001d80c..eabb8b42b890224dd19b879ff276e9908674310d 100644 +index 685aa3c35dc593b1d923a31967649b468df8a238..19c1faecb398f5b91dd04827b66038c352e5b4e4 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -@@ -246,4 +246,44 @@ public final class CraftItemFactory implements ItemFactory { +@@ -249,4 +249,44 @@ public final class CraftItemFactory implements ItemFactory { return nms != null ? net.minecraft.locale.Language.getInstance().getOrDefault(nms.getItem().getDescriptionId(nms)) : null; } // Paper end - add getI18NDisplayName diff --git a/patches/unapplied/server/0406-Cache-block-data-strings.patch b/patches/server/0403-Cache-block-data-strings.patch similarity index 86% rename from patches/unapplied/server/0406-Cache-block-data-strings.patch rename to patches/server/0403-Cache-block-data-strings.patch index d9ac173303b3..c1650c08a169 100644 --- a/patches/unapplied/server/0406-Cache-block-data-strings.patch +++ b/patches/server/0403-Cache-block-data-strings.patch @@ -5,22 +5,22 @@ Subject: [PATCH] Cache block data strings diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index dd5f74fe4c8ca81b1d1102805ea8acb9087ba91e..d2866b9f7e6c8f0ca30d451c93c56caefb2c1b5c 100644 +index 9109628a48026ceca9dd53a3e75f79510e56c95c..b1447fb684f5cbdc9106363870f5551ee9e1342c 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2145,6 +2145,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop%s", nms, bukkit); } diff --git a/patches/unapplied/server/0407-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch b/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch similarity index 78% rename from patches/unapplied/server/0407-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch rename to patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch index a480b44af125..254c21a45fdc 100644 --- a/patches/unapplied/server/0407-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch +++ b/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch @@ -9,10 +9,10 @@ as this is how Vanilla teleports entities. Cancel any pending motion when teleported. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 90e5f263dcb8033dae3ca32cbf5dbd332a109282..82f49aad1d0ce2d62bf61aa634ebef3711d4d930 100644 +index 09bb38460ab6fa7b6132e245d52b60244bd248eb..319717d5b67b9bc2a261bc69679c2e6634d7696c 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -679,7 +679,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -678,7 +678,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return; } @@ -21,20 +21,11 @@ index 90e5f263dcb8033dae3ca32cbf5dbd332a109282..82f49aad1d0ce2d62bf61aa634ebef37 this.lastGoodX = this.awaitingPositionFromClient.x; this.lastGoodY = this.awaitingPositionFromClient.y; this.lastGoodZ = this.awaitingPositionFromClient.z; -@@ -1594,7 +1594,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - // CraftBukkit end - - this.awaitingTeleportTime = this.tickCount; -- this.player.absMoveTo(d0, d1, d2, f, f1); -+ this.player.moveTo(d0, d1, d2, f, f1); // Paper - Fix Entity Teleportation and cancel velocity if teleported - this.player.connection.send(new ClientboundPlayerPositionPacket(d0 - d3, d1 - d4, d2 - d5, f - f2, f1 - f3, set, this.awaitingTeleport)); - } - diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 9d08d0610be1741b4cd18a1454e538f46928fd94..f1383906dbd16e088f57c9c77c051c8501b155cc 100644 +index 7fdfe1dd09812df1d8d7e5f95bcaf1b48c814e22..f8fd729d53248c7598a118d89fedf340f82cdd61 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -171,6 +171,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -179,6 +179,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // CraftBukkit start private static final int CURRENT_LEVEL = 2; @@ -42,7 +33,7 @@ index 9d08d0610be1741b4cd18a1454e538f46928fd94..f1383906dbd16e088f57c9c77c051c85 static boolean isLevelAtLeast(CompoundTag tag, int level) { return tag.contains("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level; } -@@ -1873,6 +1874,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1943,6 +1944,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public void moveTo(double x, double y, double z, float yaw, float pitch) { @@ -57,19 +48,19 @@ index 9d08d0610be1741b4cd18a1454e538f46928fd94..f1383906dbd16e088f57c9c77c051c85 this.setYRot(yaw); this.setXRot(pitch); diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java -index a28e6b6a50cfd9191732ad2e4aca5f639a1fae75..244e328c6f67cfa543ee283715bb3b89dbaa0f0c 100644 +index 2db75673e525708d04bda9f6c9af80e7f8d361e6..be2b5f56f6f29c82c4fa9df33287d0ddb589f383 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java -@@ -78,6 +78,7 @@ public class DragonStrafePlayerPhase extends AbstractDragonPhaseInstance { +@@ -79,6 +79,7 @@ public class DragonStrafePlayerPhase extends AbstractDragonPhaseInstance { } - DragonFireball dragonFireball = new DragonFireball(this.dragon.level(), this.dragon, vec34.normalize()); + DragonFireball dragonFireball = new DragonFireball(world, this.dragon, vec34.normalize()); + dragonFireball.preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported dragonFireball.moveTo(o, p, q, 0.0F, 0.0F); if (new com.destroystokyo.paper.event.entity.EnderDragonShootFireballEvent((org.bukkit.entity.EnderDragon) dragon.getBukkitEntity(), (org.bukkit.entity.DragonFireball) dragonFireball.getBukkitEntity()).callEvent()) // Paper - EnderDragon Events - this.dragon.level().addFreshEntity(dragonFireball); + world.addFreshEntity(dragonFireball); diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index b90127f9f805fdb5bb43a4b8ad2b10499b0b6b78..8efc06d29c62fa2be8515ed3359d52a6d4b807d2 100644 +index 56dbe701a93eb9f1309bec92e5d3b310860a4dc5..1b6ec72f59504d2f420d6d5dcbed4d3b9115e3d8 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java @@ -164,6 +164,7 @@ public abstract class BaseSpawner { @@ -81,10 +72,10 @@ index b90127f9f805fdb5bb43a4b8ad2b10499b0b6b78..8efc06d29c62fa2be8515ed3359d52a6 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 34321f095e12ea0cca34ff1ec00819c6350205a8..5f5788a502642463091fb76e98703aaec7a86836 100644 +index b001284e368f64871824c1f961999bb3f726de57..abecb0235eee3e62a84f15f2ef100efcf3fcbf2a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -240,7 +240,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -241,7 +241,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } // entity.setLocation() throws no event, and so cannot be cancelled @@ -94,10 +85,10 @@ index 34321f095e12ea0cca34ff1ec00819c6350205a8..5f5788a502642463091fb76e98703aae this.entity.setYHeadRot(location.getYaw()); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index fad7d8130f6db70c7bfca9d02027d8a41f5309c1..8a8189e8f2f201880748eb79805bb0b33688e814 100644 +index 5beee554567d36f2a3b871cf6ec3ecb3d2353592..db15382f35464de43a2fe0a41aca070a8c834777 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -596,6 +596,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -603,6 +603,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { } ((AbstractHurtingProjectile) launch).projectileSource = this; diff --git a/patches/unapplied/server/0369-Add-PlayerRecipeBookClickEvent.patch b/patches/unapplied/server/0369-Add-PlayerRecipeBookClickEvent.patch deleted file mode 100644 index add0eaf3d46f..000000000000 --- a/patches/unapplied/server/0369-Add-PlayerRecipeBookClickEvent.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: JRoy -Date: Fri, 5 Jun 2020 18:24:06 -0400 -Subject: [PATCH] Add PlayerRecipeBookClickEvent - - -diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 3455781a47fbececab33406e829ceb392c72a113..b4af560246c1fe102bae9ec9383cbef385bb1887 100644 ---- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3056,16 +3056,40 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - if (!this.player.containerMenu.stillValid(this.player)) { - ServerGamePacketListenerImpl.LOGGER.debug("Player {} interacted with invalid menu {}", this.player, this.player.containerMenu); - } else { -+ // Paper start - Add PlayerRecipeBookClickEvent -+ ResourceLocation recipeName = packet.getRecipe(); -+ boolean makeAll = packet.isShiftDown(); -+ com.destroystokyo.paper.event.player.PlayerRecipeBookClickEvent paperEvent = new com.destroystokyo.paper.event.player.PlayerRecipeBookClickEvent( -+ this.player.getBukkitEntity(), org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(recipeName), makeAll -+ ); -+ if (!paperEvent.callEvent()) { -+ return; -+ } -+ recipeName = CraftNamespacedKey.toMinecraft(paperEvent.getRecipe()); -+ makeAll = paperEvent.isMakeAll(); -+ if (org.bukkit.event.player.PlayerRecipeBookClickEvent.getHandlerList().getRegisteredListeners().length > 0) { -+ // Paper end - Add PlayerRecipeBookClickEvent - // CraftBukkit start - implement PlayerRecipeBookClickEvent -- org.bukkit.inventory.Recipe recipe = this.cserver.getRecipe(CraftNamespacedKey.fromMinecraft(packet.getRecipe())); -+ org.bukkit.inventory.Recipe recipe = this.cserver.getRecipe(CraftNamespacedKey.fromMinecraft(recipeName)); // Paper - if (recipe == null) { - return; - } -- org.bukkit.event.player.PlayerRecipeBookClickEvent event = CraftEventFactory.callRecipeBookClickEvent(this.player, recipe, packet.isShiftDown()); -+ // Paper start - Add PlayerRecipeBookClickEvent -+ org.bukkit.event.player.PlayerRecipeBookClickEvent event = CraftEventFactory.callRecipeBookClickEvent(this.player, recipe, makeAll); -+ recipeName = CraftNamespacedKey.toMinecraft(((org.bukkit.Keyed) event.getRecipe()).getKey()); -+ makeAll = event.isShiftClick(); -+ } -+ if (!(this.player.containerMenu instanceof RecipeBookMenu recipeBookMenu)) { -+ return; -+ } -+ // Paper end - Add PlayerRecipeBookClickEvent - - // Cast to keyed should be safe as the recipe will never be a MerchantRecipe. -- this.server.getRecipeManager().byKey(CraftNamespacedKey.toMinecraft(((org.bukkit.Keyed) event.getRecipe()).getKey())).ifPresent((recipeholder) -> { -- ((RecipeBookMenu) this.player.containerMenu).handlePlacement(event.isShiftClick(), recipeholder, this.player); -+ // Paper start - Add PlayerRecipeBookClickEvent -+ final boolean finalMakeAll = makeAll; -+ this.server.getRecipeManager().byKey(recipeName).ifPresent((recipeholder) -> { -+ recipeBookMenu.handlePlacement(finalMakeAll, recipeholder, this.player); -+ // Paper end - Add PlayerRecipeBookClickEvent - }); - // CraftBukkit end - } diff --git a/patches/unapplied/server/0397-Do-not-let-the-server-load-chunks-from-newer-version.patch b/patches/unapplied/server/0397-Do-not-let-the-server-load-chunks-from-newer-version.patch deleted file mode 100644 index 9ada63fcdfd2..000000000000 --- a/patches/unapplied/server/0397-Do-not-let-the-server-load-chunks-from-newer-version.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zach Brown -Date: Tue, 23 Jul 2019 20:44:47 -0500 -Subject: [PATCH] Do not let the server load chunks from newer versions - -If the server attempts to load a chunk generated by a newer version of -the game, immediately stop the server to prevent data corruption. - -You can override this functionality at your own peril. - -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index 0dd6f1bce4913cb84ba21a20df5573bab3a64645..5e1a68e3a920aab10a459b9b54f6abd59e7855e0 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -@@ -86,6 +86,10 @@ public class ChunkSerializer { - public static final String BLOCK_LIGHT_TAG = "BlockLight"; - public static final String SKY_LIGHT_TAG = "SkyLight"; - -+ // Paper start - Do not let the server load chunks from newer versions -+ private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().getDataVersion().getVersion(); -+ private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion"); -+ // Paper end - Do not let the server load chunks from newer versions - public ChunkSerializer() {} - - // Paper start - guard against serializing mismatching coordinates -@@ -102,6 +106,15 @@ public class ChunkSerializer { - // Paper end - guard against serializing mismatching coordinates - - public static ProtoChunk read(ServerLevel world, PoiManager poiStorage, RegionStorageInfo key, ChunkPos chunkPos, CompoundTag nbt) { -+ // Paper start - Do not let the server load chunks from newer versions -+ if (nbt.contains("DataVersion", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC)) { -+ final int dataVersion = nbt.getInt("DataVersion"); -+ if (!JUST_CORRUPT_IT && dataVersion > CURRENT_DATA_VERSION) { -+ new RuntimeException("Server attempted to load chunk saved with newer version of minecraft! " + dataVersion + " > " + CURRENT_DATA_VERSION).printStackTrace(); -+ System.exit(1); -+ } -+ } -+ // Paper end - Do not let the server load chunks from newer versions - ChunkPos chunkcoordintpair1 = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos")); // Paper - guard against serializing mismatching coordinates; diff on change, see ChunkSerializer#getChunkCoordinate - - if (!Objects.equals(chunkPos, chunkcoordintpair1)) { From 1f8b53733f4e42ae6cf0c2b8d3e65078f11ae575 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Wed, 23 Oct 2024 17:13:43 +0200 Subject: [PATCH 021/119] 440 --- patches/server/0151-Add-PlayerJumpEvent.patch | 4 +- .../server/0161-AsyncTabCompleteEvent.patch | 2 +- .../0207-InventoryCloseEvent-Reason-API.patch | 2 +- ...nd-make-tab-spam-limits-configurable.patch | 18 ++----- ...event-players-from-moving-into-unloa.patch | 10 ++-- ...t-allow-digging-into-unloaded-chunks.patch | 4 +- patches/server/0268-Book-size-limits.patch | 4 +- .../server/0275-Brigadier-Mojang-API.patch | 4 +- .../0276-Limit-Client-Sign-length-more.patch | 6 +-- ...PickItem-Packet-and-kick-for-invalid.patch | 4 +- ...49-Prevent-teleporting-dead-entities.patch | 4 +- ...t-position-desync-causing-tp-exploit.patch | 4 +- .../0366-Add-PlayerRecipeBookClickEvent.patch | 6 +-- ...68-Add-permission-for-command-blocks.patch | 6 +-- ...ld-Difficulty-Remembering-Difficulty.patch | 4 +- ...o-not-accept-invalid-client-settings.patch | 4 +- ...ortation-and-cancel-velocity-if-tele.patch | 4 +- ...l-open-container-api-to-HumanEntity.patch} | 2 +- ...aFixerUpper-Rewrite-Rules-on-demand.patch} | 0 ...-capture-to-capture-all-items-added.patch} | 8 +-- ...-Counter-to-allow-plugins-to-use-va.patch} | 6 +-- ...track-plugin-scoreboards-by-default.patch} | 0 .../0410-Entity-isTicking.patch} | 8 +-- ...non-whitelisted-player-when-white-l.patch} | 4 +- ...-Concurrency-issue-in-ShufflingList.patch} | 0 ...eset-Ender-Crystals-on-Dragon-Spawn.patch} | 4 +- ...-large-move-vectors-crashing-server.patch} | 12 ++--- .../0415-Optimise-getType-calls.patch} | 10 ++-- .../0416-Villager-resetOffers.patch} | 2 +- ...ce-order-when-capturing-blockstates.patch} | 4 +- ...em-locations-dropped-from-campfires.patch} | 6 +-- ...9-Fix-bell-block-entity-memory-leak.patch} | 0 ...ing-up-when-item-stack-is-empty-in-.patch} | 6 +-- ...Add-getOfflinePlayerIfCached-String.patch} | 4 +- .../0422-Add-ignore-discounts-API.patch} | 6 +-- ...Toggle-for-removing-existing-dragon.patch} | 4 +- ...x-client-lag-on-advancement-loading.patch} | 2 +- .../0425-Item-no-age-no-player-pickup.patch} | 0 ...426-Beacon-API-custom-effect-ranges.patch} | 12 ++--- .../0427-Add-API-for-quit-reason.patch} | 12 ++--- ...ng-Trader-spawn-rate-config-options.patch} | 2 +- .../0429-Add-Destroy-Speed-API.patch} | 8 +-- ...-spawnParticle-x-y-z-precision-loss.patch} | 4 +- ...31-Add-LivingEntity-clearActiveItem.patch} | 4 +- .../0432-Add-PlayerItemCooldownEvent.patch} | 8 +-- ...rove-performance-of-the-end-generat.patch} | 0 .../0434-More-lightning-API.patch} | 0 ...should-not-bypass-cramming-gamerule.patch} | 54 +++++++++---------- ...-missing-default-perms-for-commands.patch} | 0 .../0437-Add-PlayerShearBlockEvent.patch} | 14 ++--- .../server/0438-Limit-recipe-packets.patch | 41 ++++++++++++++ ...-CraftSound-backwards-compatibility.patch} | 0 ...440-Player-Chunk-Load-Unload-Events.patch} | 0 ...1-Optimize-Dynamic-get-Missing-Keys.patch} | 0 ...-Expose-LivingEntity-hurt-direction.patch} | 8 +-- ...OBSTRUCTED-reason-to-BedEnterResult.patch} | 4 +- ...valid-ingredient-lists-in-VillagerA.patch} | 2 +- .../server/0441-Limit-recipe-packets.patch | 41 -------------- 58 files changed, 192 insertions(+), 200 deletions(-) rename patches/{unapplied/server/0408-Add-additional-open-container-api-to-HumanEntity.patch => server/0405-Add-additional-open-container-api-to-HumanEntity.patch} (97%) rename patches/{unapplied/server/0409-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch => server/0406-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch} (100%) rename patches/{unapplied/server/0410-Extend-block-drop-capture-to-capture-all-items-added.patch => server/0407-Extend-block-drop-capture-to-capture-all-items-added.patch} (88%) rename patches/{unapplied/server/0411-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch => server/0408-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch} (85%) rename patches/{unapplied/server/0412-Lazily-track-plugin-scoreboards-by-default.patch => server/0409-Lazily-track-plugin-scoreboards-by-default.patch} (100%) rename patches/{unapplied/server/0413-Entity-isTicking.patch => server/0410-Entity-isTicking.patch} (80%) rename patches/{unapplied/server/0414-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch => server/0411-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch} (90%) rename patches/{unapplied/server/0415-Fix-Concurrency-issue-in-ShufflingList.patch => server/0412-Fix-Concurrency-issue-in-ShufflingList.patch} (100%) rename patches/{unapplied/server/0416-Reset-Ender-Crystals-on-Dragon-Spawn.patch => server/0413-Reset-Ender-Crystals-on-Dragon-Spawn.patch} (88%) rename patches/{unapplied/server/0417-Fix-for-large-move-vectors-crashing-server.patch => server/0414-Fix-for-large-move-vectors-crashing-server.patch} (93%) rename patches/{unapplied/server/0418-Optimise-getType-calls.patch => server/0415-Optimise-getType-calls.patch} (91%) rename patches/{unapplied/server/0419-Villager-resetOffers.patch => server/0416-Villager-resetOffers.patch} (94%) rename patches/{unapplied/server/0420-Retain-block-place-order-when-capturing-blockstates.patch => server/0417-Retain-block-place-order-when-capturing-blockstates.patch} (89%) rename patches/{unapplied/server/0421-Fix-item-locations-dropped-from-campfires.patch => server/0418-Fix-item-locations-dropped-from-campfires.patch} (89%) rename patches/{unapplied/server/0422-Fix-bell-block-entity-memory-leak.patch => server/0419-Fix-bell-block-entity-memory-leak.patch} (100%) rename patches/{unapplied/server/0423-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch => server/0420-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch} (93%) rename patches/{unapplied/server/0424-Add-getOfflinePlayerIfCached-String.patch => server/0421-Add-getOfflinePlayerIfCached-String.patch} (89%) rename patches/{unapplied/server/0425-Add-ignore-discounts-API.patch => server/0422-Add-ignore-discounts-API.patch} (97%) rename patches/{unapplied/server/0426-Toggle-for-removing-existing-dragon.patch => server/0423-Toggle-for-removing-existing-dragon.patch} (88%) rename patches/{unapplied/server/0427-Fix-client-lag-on-advancement-loading.patch => server/0424-Fix-client-lag-on-advancement-loading.patch} (95%) rename patches/{unapplied/server/0428-Item-no-age-no-player-pickup.patch => server/0425-Item-no-age-no-player-pickup.patch} (100%) rename patches/{unapplied/server/0429-Beacon-API-custom-effect-ranges.patch => server/0426-Beacon-API-custom-effect-ranges.patch} (93%) rename patches/{unapplied/server/0430-Add-API-for-quit-reason.patch => server/0427-Add-API-for-quit-reason.patch} (91%) rename patches/{unapplied/server/0431-Add-Wandering-Trader-spawn-rate-config-options.patch => server/0428-Add-Wandering-Trader-spawn-rate-config-options.patch} (98%) rename patches/{unapplied/server/0432-Add-Destroy-Speed-API.patch => server/0429-Add-Destroy-Speed-API.patch} (97%) rename patches/{unapplied/server/0433-Fix-Player-spawnParticle-x-y-z-precision-loss.patch => server/0430-Fix-Player-spawnParticle-x-y-z-precision-loss.patch} (89%) rename patches/{unapplied/server/0434-Add-LivingEntity-clearActiveItem.patch => server/0431-Add-LivingEntity-clearActiveItem.patch} (84%) rename patches/{unapplied/server/0435-Add-PlayerItemCooldownEvent.patch => server/0432-Add-PlayerItemCooldownEvent.patch} (78%) rename patches/{unapplied/server/0436-Significantly-improve-performance-of-the-end-generat.patch => server/0433-Significantly-improve-performance-of-the-end-generat.patch} (100%) rename patches/{unapplied/server/0437-More-lightning-API.patch => server/0434-More-lightning-API.patch} (100%) rename patches/{unapplied/server/0438-Climbing-should-not-bypass-cramming-gamerule.patch => server/0435-Climbing-should-not-bypass-cramming-gamerule.patch} (75%) rename patches/{unapplied/server/0439-Add-missing-default-perms-for-commands.patch => server/0436-Add-missing-default-perms-for-commands.patch} (100%) rename patches/{unapplied/server/0440-Add-PlayerShearBlockEvent.patch => server/0437-Add-PlayerShearBlockEvent.patch} (90%) create mode 100644 patches/server/0438-Limit-recipe-packets.patch rename patches/{unapplied/server/0442-Fix-CraftSound-backwards-compatibility.patch => server/0439-Fix-CraftSound-backwards-compatibility.patch} (100%) rename patches/{unapplied/server/0443-Player-Chunk-Load-Unload-Events.patch => server/0440-Player-Chunk-Load-Unload-Events.patch} (100%) rename patches/{unapplied/server/0444-Optimize-Dynamic-get-Missing-Keys.patch => server/0441-Optimize-Dynamic-get-Missing-Keys.patch} (100%) rename patches/{unapplied/server/0445-Expose-LivingEntity-hurt-direction.patch => server/0442-Expose-LivingEntity-hurt-direction.patch} (86%) rename patches/{unapplied/server/0446-Add-OBSTRUCTED-reason-to-BedEnterResult.patch => server/0443-Add-OBSTRUCTED-reason-to-BedEnterResult.patch} (86%) rename patches/{unapplied/server/0447-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch => server/0444-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch} (93%) delete mode 100644 patches/unapplied/server/0441-Limit-recipe-packets.patch diff --git a/patches/server/0151-Add-PlayerJumpEvent.patch b/patches/server/0151-Add-PlayerJumpEvent.patch index 884503c5127c..aed4af669be0 100644 --- a/patches/server/0151-Add-PlayerJumpEvent.patch +++ b/patches/server/0151-Add-PlayerJumpEvent.patch @@ -5,7 +5,7 @@ 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 2cc5663878a7c0f4b4d5f4b9a0f69de2326bf415..73d9451f4419dfe47620aed0edc7bd386a2c87da 100644 +index 2cc5663878a7c0f4b4d5f4b9a0f69de2326bf415..f80bf569089bdc049f861f876ab91183a1860d54 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1201,7 +1201,34 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -37,7 +37,7 @@ index 2cc5663878a7c0f4b4d5f4b9a0f69de2326bf415..73d9451f4419dfe47620aed0edc7bd38 + this.player.jumpFromGround(); + } else { + from = event.getFrom(); -+ this.internalTeleport(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch(), Collections.emptySet()); ++ this.internalTeleport(new PositionMoveRotation(org.bukkit.craftbukkit.util.CraftLocation.toVec3D(from), Vec3.ZERO, from.getYaw(), from.getPitch()), Collections.emptySet()); + return; + } + // Paper end - Add PlayerJumpEvent diff --git a/patches/server/0161-AsyncTabCompleteEvent.patch b/patches/server/0161-AsyncTabCompleteEvent.patch index 864c8ee1f1fa..fba56c021a78 100644 --- a/patches/server/0161-AsyncTabCompleteEvent.patch +++ b/patches/server/0161-AsyncTabCompleteEvent.patch @@ -16,7 +16,7 @@ Also adds isCommand and getLocation to the sync TabCompleteEvent Co-authored-by: Aikar diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 73d9451f4419dfe47620aed0edc7bd386a2c87da..0cce81cb61665b2dbd445fa9a0fcfeb42ce3be2c 100644 +index f80bf569089bdc049f861f876ab91183a1860d54..fd5ce79bb1e976dac5109be12aa4b9b550e94f41 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -714,21 +714,58 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0207-InventoryCloseEvent-Reason-API.patch b/patches/server/0207-InventoryCloseEvent-Reason-API.patch index 9c9fca780715..94f20cfc2c07 100644 --- a/patches/server/0207-InventoryCloseEvent-Reason-API.patch +++ b/patches/server/0207-InventoryCloseEvent-Reason-API.patch @@ -75,7 +75,7 @@ index 98aeafcc51e23a7534c8d57e4db0eb58abb3f30b..29b836a75b835f0d5233db419fc5ca8d 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 0cce81cb61665b2dbd445fa9a0fcfeb42ce3be2c..bcceb9d18524ddcf7cdf2ab6dcb95a67f1155414 100644 +index fd5ce79bb1e976dac5109be12aa4b9b550e94f41..9033c0e720a432d9abffdd7aebee2d26e595ee93 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -2633,10 +2633,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0221-Break-up-and-make-tab-spam-limits-configurable.patch b/patches/server/0221-Break-up-and-make-tab-spam-limits-configurable.patch index 2320ac4554c6..25b1469681b4 100644 --- a/patches/server/0221-Break-up-and-make-tab-spam-limits-configurable.patch +++ b/patches/server/0221-Break-up-and-make-tab-spam-limits-configurable.patch @@ -22,26 +22,18 @@ 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 bcceb9d18524ddcf7cdf2ab6dcb95a67f1155414..816b53894c6420a6b1603252e53facacecc07c52 100644 +index 9033c0e720a432d9abffdd7aebee2d26e595ee93..c20ae23e4ca340cd5ec093578f88d16529c3523a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -7,6 +7,7 @@ import com.mojang.brigadier.ParseResults; - import com.mojang.brigadier.StringReader; - import com.mojang.brigadier.suggestion.Suggestions; - import com.mojang.logging.LogUtils; -+import io.papermc.paper.configuration.GlobalConfiguration; - import it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry; - import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; - import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -@@ -272,6 +273,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -272,6 +272,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private int tickCount; private int ackBlockChangesUpTo = -1; private final TickThrottler chatSpamThrottler = new TickThrottler(20, 200); -+ private final TickThrottler tabSpamThrottler = new TickThrottler(GlobalConfiguration.get().spamLimiter.tabSpamIncrement, GlobalConfiguration.get().spamLimiter.tabSpamLimit); // Paper - configurable tab spam limits ++ private final TickThrottler tabSpamThrottler = new TickThrottler(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamIncrement, io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamLimit); // Paper - configurable tab spam limits private final TickThrottler dropSpamThrottler = new TickThrottler(20, 1480); private double firstGoodX; private double firstGoodY; -@@ -387,6 +389,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -387,6 +388,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.keepConnectionAlive(); this.chatSpamThrottler.tick(); @@ -49,7 +41,7 @@ index bcceb9d18524ddcf7cdf2ab6dcb95a67f1155414..816b53894c6420a6b1603252e53facac this.dropSpamThrottler.tick(); if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L) { this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 -@@ -722,7 +725,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -722,7 +724,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) { // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async // CraftBukkit start diff --git a/patches/server/0257-Add-option-to-prevent-players-from-moving-into-unloa.patch b/patches/server/0257-Add-option-to-prevent-players-from-moving-into-unloa.patch index e09aa1791124..15dac08b6658 100644 --- a/patches/server/0257-Add-option-to-prevent-players-from-moving-into-unloa.patch +++ b/patches/server/0257-Add-option-to-prevent-players-from-moving-into-unloa.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add option to prevent players from moving into unloaded diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 816b53894c6420a6b1603252e53facacecc07c52..825e181edc612daa2deaee2977d82a0d048720e7 100644 +index c20ae23e4ca340cd5ec093578f88d16529c3523a..ff378b29a2dfec293f7a926d1e8383627795303a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -491,9 +491,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -490,9 +490,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl double d0 = entity.getX(); double d1 = entity.getY(); double d2 = entity.getZ(); @@ -22,7 +22,7 @@ index 816b53894c6420a6b1603252e53facacecc07c52..825e181edc612daa2deaee2977d82a0d float f = Mth.wrapDegrees(packet.getYRot()); float f1 = Mth.wrapDegrees(packet.getXRot()); double d6 = d3 - this.vehicleFirstGoodX; -@@ -527,6 +527,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -526,6 +526,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } speed *= 2f; // TODO: Get the speed of the vehicle instead of the player @@ -39,7 +39,7 @@ index 816b53894c6420a6b1603252e53facacecc07c52..825e181edc612daa2deaee2977d82a0d if (d10 - d9 > Math.max(100.0D, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { // CraftBukkit end ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", new Object[]{entity.getName().getString(), this.player.getName().getString(), d6, d7, d8}); -@@ -1160,9 +1170,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1159,9 +1169,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } if (!this.updateAwaitingTeleport()) { @@ -52,7 +52,7 @@ index 816b53894c6420a6b1603252e53facacecc07c52..825e181edc612daa2deaee2977d82a0d float f = Mth.wrapDegrees(packet.getYRot(this.player.getYRot())); float f1 = Mth.wrapDegrees(packet.getXRot(this.player.getXRot())); -@@ -1220,6 +1230,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1219,6 +1229,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } else { speed = this.player.getAbilities().walkingSpeed * 10f; } diff --git a/patches/server/0264-Don-t-allow-digging-into-unloaded-chunks.patch b/patches/server/0264-Don-t-allow-digging-into-unloaded-chunks.patch index 15b8e300bbf8..1ec1ba0901e5 100644 --- a/patches/server/0264-Don-t-allow-digging-into-unloaded-chunks.patch +++ b/patches/server/0264-Don-t-allow-digging-into-unloaded-chunks.patch @@ -59,10 +59,10 @@ index 4c8189a2a7edea824545a24dccb376b8eceac001..4623c8acd125dff4919c4e2045b84831 this.level.destroyBlockProgress(this.player.getId(), pos, -1); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 825e181edc612daa2deaee2977d82a0d048720e7..5b5c5864fa1ad96946b0892998284fab26e54095 100644 +index ff378b29a2dfec293f7a926d1e8383627795303a..3f9025405e90ebcbab5ce4c1edef55fe74e529c6 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1599,6 +1599,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1598,6 +1598,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl case START_DESTROY_BLOCK: case ABORT_DESTROY_BLOCK: case STOP_DESTROY_BLOCK: diff --git a/patches/server/0268-Book-size-limits.patch b/patches/server/0268-Book-size-limits.patch index 73f2ff470b65..9f5460577420 100644 --- a/patches/server/0268-Book-size-limits.patch +++ b/patches/server/0268-Book-size-limits.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Book size limits Puts some limits on the size of books. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 5b5c5864fa1ad96946b0892998284fab26e54095..9c04eb00c80a343502ece3001a6b21382d011d30 100644 +index 3f9025405e90ebcbab5ce4c1edef55fe74e529c6..c234ee2b72249accbaee4f8005fa4c2f1be0fdc8 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1049,6 +1049,44 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1048,6 +1048,44 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleEditBook(ServerboundEditBookPacket packet) { diff --git a/patches/server/0275-Brigadier-Mojang-API.patch b/patches/server/0275-Brigadier-Mojang-API.patch index 993a47ccdbac..080f3c0fe575 100644 --- a/patches/server/0275-Brigadier-Mojang-API.patch +++ b/patches/server/0275-Brigadier-Mojang-API.patch @@ -119,10 +119,10 @@ index e812cc865baaa1ee03872f7969ee98600b82483b..c847fbdb6f52386570eb4c070fcc01d3 if (commandnode2.canUse(source)) { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 9c04eb00c80a343502ece3001a6b21382d011d30..0552007b5f12055b72b01ddeef17c30236642eaf 100644 +index c234ee2b72249accbaee4f8005fa4c2f1be0fdc8..77e111973ae33389315af72eb950b6f9d9abee12 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -773,19 +773,34 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -772,19 +772,34 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl builder.suggest(completion.suggestion(), PaperAdventure.asVanilla(completion.tooltip())); } } diff --git a/patches/server/0276-Limit-Client-Sign-length-more.patch b/patches/server/0276-Limit-Client-Sign-length-more.patch index 082d51bacd8d..0cbe0df00cdd 100644 --- a/patches/server/0276-Limit-Client-Sign-length-more.patch +++ b/patches/server/0276-Limit-Client-Sign-length-more.patch @@ -22,10 +22,10 @@ it only impacts data sent from the client. Set -DPaper.maxSignLength=XX to change limit or -1 to disable diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 0552007b5f12055b72b01ddeef17c30236642eaf..0b7e47418aa7a9891ee4a070430de6b2599f66e3 100644 +index 77e111973ae33389315af72eb950b6f9d9abee12..fd5ad700154a7b75f2ecff6a8d47f6d75ac789e4 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -307,6 +307,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -306,6 +306,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private final MessageSignatureCache messageSignatureCache = MessageSignatureCache.createDefault(); private final FutureChain chatMessageChain; private boolean waitingForSwitchToConfig; @@ -33,7 +33,7 @@ index 0552007b5f12055b72b01ddeef17c30236642eaf..0b7e47418aa7a9891ee4a070430de6b2 public ServerGamePacketListenerImpl(MinecraftServer server, Connection connection, ServerPlayer player, CommonListenerCookie clientData) { super(server, connection, clientData, player); // CraftBukkit -@@ -3197,7 +3198,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3196,7 +3197,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleSignUpdate(ServerboundSignUpdatePacket packet) { diff --git a/patches/server/0346-Validate-PickItem-Packet-and-kick-for-invalid.patch b/patches/server/0346-Validate-PickItem-Packet-and-kick-for-invalid.patch index 9f4314b9de66..324c88b6988c 100644 --- a/patches/server/0346-Validate-PickItem-Packet-and-kick-for-invalid.patch +++ b/patches/server/0346-Validate-PickItem-Packet-and-kick-for-invalid.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Validate PickItem Packet and kick for invalid diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 0b7e47418aa7a9891ee4a070430de6b2599f66e3..01dbc23369661e141ee81a2357f7b0b5602b56d5 100644 +index fd5ad700154a7b75f2ecff6a8d47f6d75ac789e4..7d3a64ad036470e9cd540131c2c3a58d871bc392 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -899,7 +899,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -898,7 +898,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handlePickItem(ServerboundPickItemPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); diff --git a/patches/server/0349-Prevent-teleporting-dead-entities.patch b/patches/server/0349-Prevent-teleporting-dead-entities.patch index dffc39239253..8016bc245489 100644 --- a/patches/server/0349-Prevent-teleporting-dead-entities.patch +++ b/patches/server/0349-Prevent-teleporting-dead-entities.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent teleporting dead entities diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 01dbc23369661e141ee81a2357f7b0b5602b56d5..7b8aaf763020cf7be7114f329f22af75f7a80ef0 100644 +index 7d3a64ad036470e9cd540131c2c3a58d871bc392..452fdd64669765d5dc73faa90d94bf474cbe1a07 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1564,6 +1564,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1563,6 +1563,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } public void internalTeleport(PositionMoveRotation positionmoverotation, Set set) { diff --git a/patches/server/0364-Prevent-position-desync-causing-tp-exploit.patch b/patches/server/0364-Prevent-position-desync-causing-tp-exploit.patch index 29816e7a496f..9acb04239e17 100644 --- a/patches/server/0364-Prevent-position-desync-causing-tp-exploit.patch +++ b/patches/server/0364-Prevent-position-desync-causing-tp-exploit.patch @@ -13,10 +13,10 @@ behaviour, we need to move all of this dangerous logic outside of the move call and into an appropriate place in the tick method. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 7b8aaf763020cf7be7114f329f22af75f7a80ef0..e329503681961566a76a383245303e88acef37a4 100644 +index 452fdd64669765d5dc73faa90d94bf474cbe1a07..4ac071f31583cd7fa0d80d8bbaddd3f5de8d648c 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1352,6 +1352,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1351,6 +1351,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.move(MoverType.PLAYER, new Vec3(d6, d7, d8)); this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move diff --git a/patches/server/0366-Add-PlayerRecipeBookClickEvent.patch b/patches/server/0366-Add-PlayerRecipeBookClickEvent.patch index e2e9336c486d..e6174267bc27 100644 --- a/patches/server/0366-Add-PlayerRecipeBookClickEvent.patch +++ b/patches/server/0366-Add-PlayerRecipeBookClickEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerRecipeBookClickEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index e329503681961566a76a383245303e88acef37a4..5b1c8fb2765407cab1ca41d8d2fce83df1cc5fe1 100644 +index 4ac071f31583cd7fa0d80d8bbaddd3f5de8d648c..b180bc19f4a8fa413a84429895bcd5d0f6a30a43 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -200,6 +200,7 @@ import net.minecraft.world.phys.Vec3; +@@ -199,6 +199,7 @@ import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.BooleanOp; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; @@ -16,7 +16,7 @@ index e329503681961566a76a383245303e88acef37a4..5b1c8fb2765407cab1ca41d8d2fce83d import org.slf4j.Logger; // CraftBukkit start -@@ -3086,21 +3087,41 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3085,21 +3086,41 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl ServerGamePacketListenerImpl.LOGGER.debug("Player {} tried to place impossible recipe {}", this.player, recipeholder.id().location()); return; } diff --git a/patches/server/0368-Add-permission-for-command-blocks.patch b/patches/server/0368-Add-permission-for-command-blocks.patch index 9a0f36109669..f7d0a92c42cd 100644 --- a/patches/server/0368-Add-permission-for-command-blocks.patch +++ b/patches/server/0368-Add-permission-for-command-blocks.patch @@ -18,10 +18,10 @@ index 4623c8acd125dff4919c4e2045b848310d785da5..86e4559da2344f228ef4d1c4ac3c115f return false; } else if (this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 5b1c8fb2765407cab1ca41d8d2fce83df1cc5fe1..fc595e04191ffe3434d54156e924cec0f4b19cee 100644 +index b180bc19f4a8fa413a84429895bcd5d0f6a30a43..ac073dab2d2552f9bb0394379a237a4dc37c8fb2 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -811,7 +811,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -810,7 +810,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (!this.server.isCommandBlockEnabled()) { this.player.sendSystemMessage(Component.translatable("advMode.notEnabled")); @@ -30,7 +30,7 @@ index 5b1c8fb2765407cab1ca41d8d2fce83df1cc5fe1..fc595e04191ffe3434d54156e924cec0 this.player.sendSystemMessage(Component.translatable("advMode.notAllowed")); } else { BaseCommandBlock commandblocklistenerabstract = null; -@@ -878,7 +878,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -877,7 +877,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (!this.server.isCommandBlockEnabled()) { this.player.sendSystemMessage(Component.translatable("advMode.notEnabled")); diff --git a/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch b/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch index d6a667ddb78b..b0483140f364 100644 --- a/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch +++ b/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch @@ -76,10 +76,10 @@ index 82d5f1235d158326ce6fb1eb6d481c00f57467d3..20a3138c6c2a6c8ada8b6008913abae0 @Override diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index fc595e04191ffe3434d54156e924cec0f4b19cee..510c97062d77541425aed6ddaaad58be4290967b 100644 +index ac073dab2d2552f9bb0394379a237a4dc37c8fb2..7865ff33b0163460a9ffdb7ed4bb3970b5674344 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3304,7 +3304,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3303,7 +3303,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void handleChangeDifficulty(ServerboundChangeDifficultyPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (this.player.hasPermissions(2) || this.isSingleplayerOwner()) { diff --git a/patches/server/0376-Do-not-accept-invalid-client-settings.patch b/patches/server/0376-Do-not-accept-invalid-client-settings.patch index 65e274aa2bd0..590c7811c869 100644 --- a/patches/server/0376-Do-not-accept-invalid-client-settings.patch +++ b/patches/server/0376-Do-not-accept-invalid-client-settings.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Do not accept invalid client settings diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 510c97062d77541425aed6ddaaad58be4290967b..09bb38460ab6fa7b6132e245d52b60244bd248eb 100644 +index 7865ff33b0163460a9ffdb7ed4bb3970b5674344..f146787c935287eb5cc545643036eeb2a2d7dc9b 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3296,6 +3296,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3295,6 +3295,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleClientInformation(ServerboundClientInformationPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); diff --git a/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch b/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch index 254c21a45fdc..2cb92d0cf82b 100644 --- a/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch +++ b/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch @@ -9,10 +9,10 @@ as this is how Vanilla teleports entities. Cancel any pending motion when teleported. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 09bb38460ab6fa7b6132e245d52b60244bd248eb..319717d5b67b9bc2a261bc69679c2e6634d7696c 100644 +index f146787c935287eb5cc545643036eeb2a2d7dc9b..c430434485baa7fc5a213efd9523cee8c2c46b44 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -678,7 +678,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -677,7 +677,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return; } diff --git a/patches/unapplied/server/0408-Add-additional-open-container-api-to-HumanEntity.patch b/patches/server/0405-Add-additional-open-container-api-to-HumanEntity.patch similarity index 97% rename from patches/unapplied/server/0408-Add-additional-open-container-api-to-HumanEntity.patch rename to patches/server/0405-Add-additional-open-container-api-to-HumanEntity.patch index 15f9a92e4435..4f9cf8d9d9a1 100644 --- a/patches/unapplied/server/0408-Add-additional-open-container-api-to-HumanEntity.patch +++ b/patches/server/0405-Add-additional-open-container-api-to-HumanEntity.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Add additional open container api to HumanEntity public net/minecraft/world/level/block/state/BlockBehaviour getMenuProvider(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/MenuProvider; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index c17dd4205983855615289cf0a5619056d237f325..6cda13df52ee4d56dd1d3c213307bfd38175584c 100644 +index b2ab430392fc0f214ba8c5383e3f3ad5c548bda2..9022555db0df8c269fc039c895422cf36c08097e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -471,6 +471,70 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { diff --git a/patches/unapplied/server/0409-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch b/patches/server/0406-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch similarity index 100% rename from patches/unapplied/server/0409-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch rename to patches/server/0406-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch diff --git a/patches/unapplied/server/0410-Extend-block-drop-capture-to-capture-all-items-added.patch b/patches/server/0407-Extend-block-drop-capture-to-capture-all-items-added.patch similarity index 88% rename from patches/unapplied/server/0410-Extend-block-drop-capture-to-capture-all-items-added.patch rename to patches/server/0407-Extend-block-drop-capture-to-capture-all-items-added.patch index 9cb478d12045..12a14918c34e 100644 --- a/patches/unapplied/server/0410-Extend-block-drop-capture-to-capture-all-items-added.patch +++ b/patches/server/0407-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 9114ba1742a4fc8683848d431fa92046a85fe871..c60967b7833a23cff0305219b02b308d92448109 100644 +index 465b6a1bbdbb193c6ecf5fd1598e1e4a4f8dbbbc..a3ce6feff0826dcfb2a11b0f6cd01a5368c2de3a 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1228,6 +1228,12 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1223,6 +1223,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getKey(entity.getType())); // CraftBukkit return false; } else { @@ -23,10 +23,10 @@ index 9114ba1742a4fc8683848d431fa92046a85fe871..c60967b7833a23cff0305219b02b308d if (spawnReason != null && !CraftEventFactory.doEntityAddEventCalling(this, entity, spawnReason)) { return false; diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index d4bd44210d58b30696feeea48e1909472a546702..5de472df78940d1b8320f73d18b2edf3a796227e 100644 +index 86e4559da2344f228ef4d1c4ac3c115fa0266d23..546be40a8e4470fb5a6686072cdd342cdaa6fe15 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -437,10 +437,12 @@ public class ServerPlayerGameMode { +@@ -435,10 +435,12 @@ public class ServerPlayerGameMode { // return true; // CraftBukkit } // CraftBukkit start diff --git a/patches/unapplied/server/0411-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch b/patches/server/0408-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch similarity index 85% rename from patches/unapplied/server/0411-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch rename to patches/server/0408-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch index 587ee1ed675d..a9c355af5979 100644 --- a/patches/unapplied/server/0411-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch +++ b/patches/server/0408-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Expose the Entity Counter to allow plugins to use valid and diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index f1383906dbd16e088f57c9c77c051c8501b155cc..c01a9305eb1c3e2ee5effab1e11980c2540d3c2a 100644 +index f8fd729d53248c7598a118d89fedf340f82cdd61..ac1b2b3982e5ceb8fecf20867dd2ac6e143463c3 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -4508,4 +4508,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4704,4 +4704,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess void accept(Entity entity, double x, double y, double z); } @@ -21,7 +21,7 @@ index f1383906dbd16e088f57c9c77c051c8501b155cc..c01a9305eb1c3e2ee5effab1e11980c2 + // Paper end - Expose entity id counter } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 8b11f5f8cec74c57d614d73233a449c97cd56d18..d7e8663e21ade1b53d4b936147f57b632f67a156 100644 +index 180259d1e5401777e121a8c1ec95034afbc0917b..3448ada171a9fb8c8294b0ba93eb2c846788a679 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -511,6 +511,11 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/unapplied/server/0412-Lazily-track-plugin-scoreboards-by-default.patch b/patches/server/0409-Lazily-track-plugin-scoreboards-by-default.patch similarity index 100% rename from patches/unapplied/server/0412-Lazily-track-plugin-scoreboards-by-default.patch rename to patches/server/0409-Lazily-track-plugin-scoreboards-by-default.patch diff --git a/patches/unapplied/server/0413-Entity-isTicking.patch b/patches/server/0410-Entity-isTicking.patch similarity index 80% rename from patches/unapplied/server/0413-Entity-isTicking.patch rename to patches/server/0410-Entity-isTicking.patch index 502eb209370d..e90c16901da5 100644 --- a/patches/unapplied/server/0413-Entity-isTicking.patch +++ b/patches/server/0410-Entity-isTicking.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Entity#isTicking diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index c01a9305eb1c3e2ee5effab1e11980c2540d3c2a..6ab665efcac4c2543bab9d95472026e0ec8580c5 100644 +index ac1b2b3982e5ceb8fecf20867dd2ac6e143463c3..0bd608894ab596c773570f92b4662aee5a6934cc 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -4513,5 +4513,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4709,5 +4709,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public static int nextEntityId() { return ENTITY_COUNTER.incrementAndGet(); } @@ -19,10 +19,10 @@ index c01a9305eb1c3e2ee5effab1e11980c2540d3c2a..6ab665efcac4c2543bab9d95472026e0 // Paper end - Expose entity id counter } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 5f5788a502642463091fb76e98703aaec7a86836..98e8ad81b8c9c0636abe59f70ce891fe926a37fe 100644 +index abecb0235eee3e62a84f15f2ef100efcf3fcbf2a..925626b74005ec9c031c3773171f7684ecc9ccd3 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1062,4 +1062,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1063,4 +1063,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return getHandle().isInLava(); } // Paper end - entity liquid API diff --git a/patches/unapplied/server/0414-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch b/patches/server/0411-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch similarity index 90% rename from patches/unapplied/server/0414-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch rename to patches/server/0411-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch index 284340c436f7..ebe55acb10f0 100644 --- a/patches/unapplied/server/0414-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch +++ b/patches/server/0411-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Fix deop kicking non-whitelisted player when white list is diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index d2866b9f7e6c8f0ca30d451c93c56caefb2c1b5c..05aa3323e9ae971fba5ab8c6c319c7805a3808aa 100644 +index b1447fb684f5cbdc9106363870f5551ee9e1342c..263ed74fd8a8a53ce6d676201f75c5b334345c84 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2270,13 +2270,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 1.0D) { -@@ -1309,9 +1327,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1312,9 +1330,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl AABB axisalignedbb = this.player.getBoundingBox(); diff --git a/patches/unapplied/server/0418-Optimise-getType-calls.patch b/patches/server/0415-Optimise-getType-calls.patch similarity index 91% rename from patches/unapplied/server/0418-Optimise-getType-calls.patch rename to patches/server/0415-Optimise-getType-calls.patch index 1b14b0202bb4..07a3b551c2d3 100644 --- a/patches/unapplied/server/0418-Optimise-getType-calls.patch +++ b/patches/server/0415-Optimise-getType-calls.patch @@ -27,10 +27,10 @@ index 065d140ca4f987e14138a37f4c7d60879dd7b6e1..601135f3368272bf1ca3a43ec9c199e3 super(block, propertyMap, codec); } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java -index f2ce97e46cdbda0f8960eed9b601c797d8eaef48..85029f1acfdbb411d9ebdf95838d6db3898f4e58 100644 +index a845ebd6262e05a1395c9a503480319e4b4a65ce..c88e4ba701b2a2325b76478b7f47278157afd2ef 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java -@@ -99,7 +99,7 @@ public class CraftChunkSnapshot implements ChunkSnapshot { +@@ -100,7 +100,7 @@ public class CraftChunkSnapshot implements ChunkSnapshot { public Material getBlockType(int x, int y, int z) { this.validateChunkCoordinates(x, y, z); @@ -40,7 +40,7 @@ index f2ce97e46cdbda0f8960eed9b601c797d8eaef48..85029f1acfdbb411d9ebdf95838d6db3 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index a586442422a2b2c06b785af0d261d3e19eb1d59b..aa644231425b9622437538b5c092d4064a40cced 100644 +index 3fa3de9a89550ec2fcb8ca663742826c0c3136b6..5f4dcf6d86db66186dc31075bdb739f5dbae6480 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -220,7 +220,7 @@ public class CraftBlock implements Block { @@ -66,10 +66,10 @@ index fabdec2d66cc6d676ed58fa570e2c318ab0927e2..1002123cd0c6f57cecc4e80f5f21cc6f public void setFlag(int flag) { diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java -index 67ff2241aa8869b41abb0a93467b8694618264e2..9953b6b36cbcbfd1756bac478b568ca5700fc898 100644 +index f73858663162cb594db382d584b6500bb03e74b1..7f0d87bd43a54885fc521068116888083327f37e 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java +++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java -@@ -61,7 +61,7 @@ public class CraftBlockData implements BlockData { +@@ -63,7 +63,7 @@ public class CraftBlockData implements BlockData { @Override public Material getMaterial() { diff --git a/patches/unapplied/server/0419-Villager-resetOffers.patch b/patches/server/0416-Villager-resetOffers.patch similarity index 94% rename from patches/unapplied/server/0419-Villager-resetOffers.patch rename to patches/server/0416-Villager-resetOffers.patch index ce8f9949cd51..2b919a864638 100644 --- a/patches/unapplied/server/0419-Villager-resetOffers.patch +++ b/patches/server/0416-Villager-resetOffers.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Villager#resetOffers diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java -index 89e14bb2662fe03b4661aaa54fd65af41b1d438b..fcb3b66617150ad503bffe65de4900b1e3af8764 100644 +index 3cdd48c35d50fa3107e0f2bf439e75b7f306b3d1..c8231e421e6c3f1cf8a5aaf8cc64741abe868f41 100644 --- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java +++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java @@ -114,6 +114,13 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa diff --git a/patches/unapplied/server/0420-Retain-block-place-order-when-capturing-blockstates.patch b/patches/server/0417-Retain-block-place-order-when-capturing-blockstates.patch similarity index 89% rename from patches/unapplied/server/0420-Retain-block-place-order-when-capturing-blockstates.patch rename to patches/server/0417-Retain-block-place-order-when-capturing-blockstates.patch index bac1a1074bfb..7bb12e9275d3 100644 --- a/patches/unapplied/server/0420-Retain-block-place-order-when-capturing-blockstates.patch +++ b/patches/server/0417-Retain-block-place-order-when-capturing-blockstates.patch @@ -10,10 +10,10 @@ In general, look at making this logic more robust (i.e properly handling cases where a captured entry is overriden) - but for now this will do. diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 60b04a16c6cb0a7109bda5c16e23c1d56ab7afad..144d243e0d6ba3ae3f0b0bf457fa516e2b4f416f 100644 +index dc38a23f027b4fe516f3963632d01f66c02b0681..aff89d2e3274b91238989fc1e7d8c119c2a3c097 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -152,7 +152,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -153,7 +153,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public boolean captureBlockStates = false; public boolean captureTreeGeneration = false; public Map capturedBlockStates = new java.util.LinkedHashMap<>(); // Paper diff --git a/patches/unapplied/server/0421-Fix-item-locations-dropped-from-campfires.patch b/patches/server/0418-Fix-item-locations-dropped-from-campfires.patch similarity index 89% rename from patches/unapplied/server/0421-Fix-item-locations-dropped-from-campfires.patch rename to patches/server/0418-Fix-item-locations-dropped-from-campfires.patch index 26a43eb1862e..df4949c1b82a 100644 --- a/patches/unapplied/server/0421-Fix-item-locations-dropped-from-campfires.patch +++ b/patches/server/0418-Fix-item-locations-dropped-from-campfires.patch @@ -7,10 +7,10 @@ Fixes #4259 by not flooring the blockposition among other weirdness Vanilla Issue: MC-267622 diff --git a/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java -index 391acc9dadc653e9e1285a71b4f1e7c063e8ca49..80f911692c97585a696a19ebbe616d6aa312b2d9 100644 +index 0694b2a041c0012bbb7ab5c4c787c1e08db7757c..30035d534e144bf31f94073c57b0195be7e62772 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java -@@ -86,7 +86,14 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { +@@ -85,7 +85,14 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { result = blockCookEvent.getResult(); itemstack1 = CraftItemStack.asNMSCopy(result); // CraftBukkit end @@ -23,6 +23,6 @@ index 391acc9dadc653e9e1285a71b4f1e7c063e8ca49..80f911692c97585a696a19ebbe616d6a + world.addFreshEntity(droppedItem); + } + // Paper end - Fix item locations dropped from campfires - campfire.items.set(i, ItemStack.EMPTY); + blockEntity.items.set(i, ItemStack.EMPTY); world.sendBlockUpdated(pos, state, state, 3); world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(state)); diff --git a/patches/unapplied/server/0422-Fix-bell-block-entity-memory-leak.patch b/patches/server/0419-Fix-bell-block-entity-memory-leak.patch similarity index 100% rename from patches/unapplied/server/0422-Fix-bell-block-entity-memory-leak.patch rename to patches/server/0419-Fix-bell-block-entity-memory-leak.patch diff --git a/patches/unapplied/server/0423-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch b/patches/server/0420-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch similarity index 93% rename from patches/unapplied/server/0423-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch rename to patches/server/0420-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch index 6ab78855c47b..67b54defcacc 100644 --- a/patches/unapplied/server/0423-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch +++ b/patches/server/0420-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch @@ -8,10 +8,10 @@ This can realistically only happen if there's custom loot active on fishing which can return 0 items. This would disconnect the player who's fishing. diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -index 0b4c67b9de6893601f032a8fae103e8a98f2c767..5b7734020b496ade3740d92908ad2d399bfd55e6 100644 +index 9d24d4c3802c525546dae92530c9c5b3cf77924e..536196a740f607adda2a5ae7f644981ac26bef98 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java +++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -@@ -506,9 +506,15 @@ public class FishingHook extends Projectile { +@@ -511,9 +511,15 @@ public class FishingHook extends Projectile { while (iterator.hasNext()) { ItemStack itemstack1 = (ItemStack) iterator.next(); @@ -29,7 +29,7 @@ index 0b4c67b9de6893601f032a8fae103e8a98f2c767..5b7734020b496ade3740d92908ad2d39 playerFishEvent.setExpToDrop(this.random.nextInt(6) + 1); this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent); -@@ -521,8 +527,12 @@ public class FishingHook extends Projectile { +@@ -526,8 +532,12 @@ public class FishingHook extends Projectile { double d2 = entityhuman.getZ() - this.getZ(); double d3 = 0.1D; diff --git a/patches/unapplied/server/0424-Add-getOfflinePlayerIfCached-String.patch b/patches/server/0421-Add-getOfflinePlayerIfCached-String.patch similarity index 89% rename from patches/unapplied/server/0424-Add-getOfflinePlayerIfCached-String.patch rename to patches/server/0421-Add-getOfflinePlayerIfCached-String.patch index 5eeace36f69d..83fd69cf3dee 100644 --- a/patches/unapplied/server/0424-Add-getOfflinePlayerIfCached-String.patch +++ b/patches/server/0421-Add-getOfflinePlayerIfCached-String.patch @@ -5,10 +5,10 @@ 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 42ec4aed187b41729a3c985ae440097db0388d3c..25bfb93568ea0a6c0b827c6d6a736f950981144e 100644 +index dfe625f406ac323ede270d3773e71b09a3ba0054..dd3940c2aacfa835b528a882f3ec5dd4d98bd59f 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1965,6 +1965,28 @@ public final class CraftServer implements Server { +@@ -1969,6 +1969,28 @@ public final class CraftServer implements Server { return result; } diff --git a/patches/unapplied/server/0425-Add-ignore-discounts-API.patch b/patches/server/0422-Add-ignore-discounts-API.patch similarity index 97% rename from patches/unapplied/server/0425-Add-ignore-discounts-API.patch rename to patches/server/0422-Add-ignore-discounts-API.patch index b2ed91d9bf4b..84103c5a2e78 100644 --- a/patches/unapplied/server/0425-Add-ignore-discounts-API.patch +++ b/patches/server/0422-Add-ignore-discounts-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add ignore discounts API diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java -index e23674dd5db3c429efd3b7c71fe36b420494c03a..9d5a5a7fff7f75871e167f83edb0e9d5348748d7 100644 +index 82ed0ce824e84ea09ea963caa61fbb75f6ce6fe7..f51078e4b9e6267fa43795d009f5d149b86acb5a 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java -@@ -493,6 +493,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -490,6 +490,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler while (iterator.hasNext()) { MerchantOffer merchantrecipe = (MerchantOffer) iterator.next(); @@ -16,7 +16,7 @@ index e23674dd5db3c429efd3b7c71fe36b420494c03a..9d5a5a7fff7f75871e167f83edb0e9d5 merchantrecipe.addToSpecialPriceDiff(-Mth.floor((float) i * merchantrecipe.getPriceMultiplier())); } -@@ -505,6 +506,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -502,6 +503,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler while (iterator1.hasNext()) { MerchantOffer merchantrecipe1 = (MerchantOffer) iterator1.next(); diff --git a/patches/unapplied/server/0426-Toggle-for-removing-existing-dragon.patch b/patches/server/0423-Toggle-for-removing-existing-dragon.patch similarity index 88% rename from patches/unapplied/server/0426-Toggle-for-removing-existing-dragon.patch rename to patches/server/0423-Toggle-for-removing-existing-dragon.patch index 26ae1ded8a1f..5efff5ff3f38 100644 --- a/patches/unapplied/server/0426-Toggle-for-removing-existing-dragon.patch +++ b/patches/server/0423-Toggle-for-removing-existing-dragon.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Toggle for removing existing dragon diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -index a12299604ea88c268db5065191d641eb7d52c3e3..d6deedb96583c19eeb27e671289c4edc8a9245b4 100644 +index 0f34a5ce0352f627099a719b78e530e5e572581a..323fbf684b7062c1b9084f1718538a3b3414d5bf 100644 --- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java +++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -@@ -211,7 +211,7 @@ public class EndDragonFight { +@@ -212,7 +212,7 @@ public class EndDragonFight { this.dragonUUID = entityenderdragon.getUUID(); EndDragonFight.LOGGER.info("Found that there's a dragon still alive ({})", entityenderdragon); this.dragonKilled = false; diff --git a/patches/unapplied/server/0427-Fix-client-lag-on-advancement-loading.patch b/patches/server/0424-Fix-client-lag-on-advancement-loading.patch similarity index 95% rename from patches/unapplied/server/0427-Fix-client-lag-on-advancement-loading.patch rename to patches/server/0424-Fix-client-lag-on-advancement-loading.patch index 5cc82219f2c6..e62e28f8d522 100644 --- a/patches/unapplied/server/0427-Fix-client-lag-on-advancement-loading.patch +++ b/patches/server/0424-Fix-client-lag-on-advancement-loading.patch @@ -15,7 +15,7 @@ manually reload the advancement data for all players, which normally takes place as a part of the datapack reloading. diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index d7e8663e21ade1b53d4b936147f57b632f67a156..66249c5caefb0879e13c02d5553b09b4122418b9 100644 +index 3448ada171a9fb8c8294b0ba93eb2c846788a679..ea9c9ae832c4044a2eccbf901e20ff042df68bf3 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -323,7 +323,13 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/unapplied/server/0428-Item-no-age-no-player-pickup.patch b/patches/server/0425-Item-no-age-no-player-pickup.patch similarity index 100% rename from patches/unapplied/server/0428-Item-no-age-no-player-pickup.patch rename to patches/server/0425-Item-no-age-no-player-pickup.patch diff --git a/patches/unapplied/server/0429-Beacon-API-custom-effect-ranges.patch b/patches/server/0426-Beacon-API-custom-effect-ranges.patch similarity index 93% rename from patches/unapplied/server/0429-Beacon-API-custom-effect-ranges.patch rename to patches/server/0426-Beacon-API-custom-effect-ranges.patch index b80f1772cda1..6afe0e8f7ce2 100644 --- a/patches/unapplied/server/0429-Beacon-API-custom-effect-ranges.patch +++ b/patches/server/0426-Beacon-API-custom-effect-ranges.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Beacon API - custom effect ranges diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -index fc915797d2a085447747d9ce23a5a354fb3eb6b6..52776ce9b7b4edd1eb474f14705d7fd83f5a66ca 100644 +index 8332296663b845df1d09d403b49a4769b2d54afc..dc3171b1493d7c4c8ddf1c79587c4e27bd819c17 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java @@ -86,6 +86,26 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name @@ -81,7 +81,7 @@ index fc915797d2a085447747d9ce23a5a354fb3eb6b6..52776ce9b7b4edd1eb474f14705d7fd8 @@ -395,6 +425,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name } - this.lockKey = LockCode.fromTag(nbt); + this.lockKey = LockCode.fromTag(nbt, registries); + this.effectRange = nbt.contains(PAPER_RANGE_TAG, 6) ? nbt.getDouble(PAPER_RANGE_TAG) : -1; // Paper - Custom beacon ranges } @@ -89,16 +89,16 @@ index fc915797d2a085447747d9ce23a5a354fb3eb6b6..52776ce9b7b4edd1eb474f14705d7fd8 @@ -408,6 +439,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name } - this.lockKey.addToTag(nbt); + this.lockKey.addToTag(nbt, registries); + nbt.putDouble(PAPER_RANGE_TAG, this.effectRange); // Paper - Custom beacon ranges } public void setCustomName(@Nullable Component customName) { diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java -index 2dfbe061a064b0c79b96f644a1c3639bb900eca4..3f1bb225c4e6acdd9104e856d6a11d519119c9f4 100644 +index 8021ac39cb9c1ff45123d51e6f13b840d1290bb2..275d4f9e07ff7383b18238071e067b7f44483ece 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java -@@ -33,7 +33,7 @@ public class CraftBeacon extends CraftBlockEntityState implem +@@ -42,7 +42,7 @@ public class CraftBeacon extends CraftBlockEntityState implem if (tileEntity instanceof BeaconBlockEntity) { BeaconBlockEntity beacon = (BeaconBlockEntity) tileEntity; @@ -107,7 +107,7 @@ index 2dfbe061a064b0c79b96f644a1c3639bb900eca4..3f1bb225c4e6acdd9104e856d6a11d51 Collection bukkit = new ArrayList(nms.size()); for (Player human : nms) { -@@ -120,4 +120,21 @@ public class CraftBeacon extends CraftBlockEntityState implem +@@ -145,4 +145,21 @@ public class CraftBeacon extends CraftBlockEntityState implem public CraftBeacon copy(Location location) { return new CraftBeacon(this, location); } diff --git a/patches/unapplied/server/0430-Add-API-for-quit-reason.patch b/patches/server/0427-Add-API-for-quit-reason.patch similarity index 91% rename from patches/unapplied/server/0430-Add-API-for-quit-reason.patch rename to patches/server/0427-Add-API-for-quit-reason.patch index c4ed7bf11f36..fe4c28762dcd 100644 --- a/patches/unapplied/server/0430-Add-API-for-quit-reason.patch +++ b/patches/server/0427-Add-API-for-quit-reason.patch @@ -28,10 +28,10 @@ index 134810ac91d828d67759cd1ed56f11b71e292917..ba41646a5edb57c4d9766df08bbc5701 Connection.LOGGER.debug("Failed to sent packet", throwable); if (this.getSending() == PacketFlow.CLIENTBOUND) { diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 45181bc9c422507682d479e4d43177ecd3253971..2ea613f818403f8e8ece4b36891738139345cf89 100644 +index c468947990cf05e554006e51d87b72fad7c28e55..0ae490bb9b4cd781876054d0824c5392060208eb 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -295,6 +295,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -323,6 +323,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { public boolean isRealPlayer; // Paper public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent public @Nullable String clientBrandName = null; // Paper - Brand support @@ -40,10 +40,10 @@ index 45181bc9c422507682d479e4d43177ecd3253971..2ea613f818403f8e8ece4b3689173813 public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) { super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 48085b2e7197dc44e76b812bdd514af729e21e83..a1124405412cdac673f34a63988e7be957506dba 100644 +index 9a8b08d4b70b8890961e4af7ce6e870aa1c7c810..f8ae8c8eff73e4e87eb34d0f2635517f1688a6f1 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -376,6 +376,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -383,6 +383,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack private void disconnect0(DisconnectionDetails disconnectiondetails) { // CraftBukkit end @@ -52,10 +52,10 @@ index 48085b2e7197dc44e76b812bdd514af729e21e83..a1124405412cdac673f34a63988e7be9 this.connection.disconnect(disconnectiondetails); })); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 6f587c4bb4704d93552ba61335d87b1852fc169c..98eb00a8ee23543714d424d3ff5ca19887d6db19 100644 +index c8c27311ade7d4a70d5398b3a4cb50eedd02a2f9..4975b4222d52eddbb42e9c9cd08eef56859080c8 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -570,7 +570,7 @@ public abstract class PlayerList { +@@ -520,7 +520,7 @@ public abstract class PlayerList { entityplayer.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DISCONNECT); // Paper - Inventory close reason } diff --git a/patches/unapplied/server/0431-Add-Wandering-Trader-spawn-rate-config-options.patch b/patches/server/0428-Add-Wandering-Trader-spawn-rate-config-options.patch similarity index 98% rename from patches/unapplied/server/0431-Add-Wandering-Trader-spawn-rate-config-options.patch rename to patches/server/0428-Add-Wandering-Trader-spawn-rate-config-options.patch index 98525387d730..30e4e03f249d 100644 --- a/patches/unapplied/server/0431-Add-Wandering-Trader-spawn-rate-config-options.patch +++ b/patches/server/0428-Add-Wandering-Trader-spawn-rate-config-options.patch @@ -11,7 +11,7 @@ in IWorldServerData are removed as they were only used in certain places, with h values used in other places. diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java -index 4b7e9bc8aa253d0eb12a2195416c618cccdc8690..d5d27b0d352ca3fd57a26605cb35c499e88b57fc 100644 +index cfa1787b955fd9b80bf9906b88d423cb59b12ff1..08a3c7140867f339dd99a95094ed0fd8ff344fca 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java @@ -40,43 +40,53 @@ public class WanderingTraderSpawner implements CustomSpawner { diff --git a/patches/unapplied/server/0432-Add-Destroy-Speed-API.patch b/patches/server/0429-Add-Destroy-Speed-API.patch similarity index 97% rename from patches/unapplied/server/0432-Add-Destroy-Speed-API.patch rename to patches/server/0429-Add-Destroy-Speed-API.patch index 22e992d6a9fe..2274f8a5d44f 100644 --- a/patches/unapplied/server/0432-Add-Destroy-Speed-API.patch +++ b/patches/server/0429-Add-Destroy-Speed-API.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add Destroy Speed API Co-authored-by: Jake Potrebic diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeInstance.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeInstance.java -index 36c943d709c1c0ae49ec0baf0ccf7b6cb9a2ecf3..d28f9e077a50122e86848cfa9db83f6b0e8eef6c 100644 +index a2fe7149a837040cf9f23eb426d398a5f90be394..27a7852a5d3f8c8960f098646ff5587c50556aa5 100644 --- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeInstance.java +++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeInstance.java -@@ -143,20 +143,20 @@ public class AttributeInstance { +@@ -153,20 +153,20 @@ public class AttributeInstance { double d = this.getBaseValue(); for (AttributeModifier attributeModifier : this.getModifiersOrEmpty(AttributeModifier.Operation.ADD_VALUE)) { @@ -35,10 +35,10 @@ index 36c943d709c1c0ae49ec0baf0ccf7b6cb9a2ecf3..d28f9e077a50122e86848cfa9db83f6b private Collection getModifiersOrEmpty(AttributeModifier.Operation operation) { diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java -index 9953b6b36cbcbfd1756bac478b568ca5700fc898..33869e725c3b3f2120fa36ca468019a78321e862 100644 +index 7f0d87bd43a54885fc521068116888083327f37e..a17c1d1651d4d36c40ef97c1cf0b1e0d61f53418 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java +++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java -@@ -721,4 +721,35 @@ public class CraftBlockData implements BlockData { +@@ -725,4 +725,35 @@ public class CraftBlockData implements BlockData { public BlockState createBlockState() { return CraftBlockStates.getBlockState(this.state, null); } diff --git a/patches/unapplied/server/0433-Fix-Player-spawnParticle-x-y-z-precision-loss.patch b/patches/server/0430-Fix-Player-spawnParticle-x-y-z-precision-loss.patch similarity index 89% rename from patches/unapplied/server/0433-Fix-Player-spawnParticle-x-y-z-precision-loss.patch rename to patches/server/0430-Fix-Player-spawnParticle-x-y-z-precision-loss.patch index e34ff10d4d2f..185bc677aca8 100644 --- a/patches/unapplied/server/0433-Fix-Player-spawnParticle-x-y-z-precision-loss.patch +++ b/patches/server/0430-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 854533854dfba24b59a15265ac759331e3ddfc74..73fde8be0098238582fb3661ae67d4139be417dc 100644 +index eb2954c9b51d4fd76cf5aec17899218f4de7076d..786b8c10a647d777b951b760e4c51eef057b2edd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2707,7 +2707,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2720,7 +2720,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public 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/unapplied/server/0434-Add-LivingEntity-clearActiveItem.patch b/patches/server/0431-Add-LivingEntity-clearActiveItem.patch similarity index 84% rename from patches/unapplied/server/0434-Add-LivingEntity-clearActiveItem.patch rename to patches/server/0431-Add-LivingEntity-clearActiveItem.patch index c22e85e85866..3c6621ccfabf 100644 --- a/patches/unapplied/server/0434-Add-LivingEntity-clearActiveItem.patch +++ b/patches/server/0431-Add-LivingEntity-clearActiveItem.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add LivingEntity#clearActiveItem diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 8a8189e8f2f201880748eb79805bb0b33688e814..925c842fcf546ad270641b3be7e8a8c432571501 100644 +index db15382f35464de43a2fe0a41aca070a8c834777..de41ee2cc1be6ef412ec15c79a65cbca653b35d3 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -948,6 +948,13 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -967,6 +967,13 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return this.getHandle().getUseItem().asBukkitMirror(); } diff --git a/patches/unapplied/server/0435-Add-PlayerItemCooldownEvent.patch b/patches/server/0432-Add-PlayerItemCooldownEvent.patch similarity index 78% rename from patches/unapplied/server/0435-Add-PlayerItemCooldownEvent.patch rename to patches/server/0432-Add-PlayerItemCooldownEvent.patch index 4b90903dd251..70845dd2e6fe 100644 --- a/patches/unapplied/server/0435-Add-PlayerItemCooldownEvent.patch +++ b/patches/server/0432-Add-PlayerItemCooldownEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerItemCooldownEvent diff --git a/src/main/java/net/minecraft/world/item/ServerItemCooldowns.java b/src/main/java/net/minecraft/world/item/ServerItemCooldowns.java -index 47283d2a49209839002212e663a503a82ea86587..e0c4c0a9bab0bbc32358030a482aa04c2e1d3894 100644 +index 3a45a149ec4a28f25ea9e45803ecbb7392b63f86..872813ef19fc08cad93786367e15f59400825c33 100644 --- a/src/main/java/net/minecraft/world/item/ServerItemCooldowns.java +++ b/src/main/java/net/minecraft/world/item/ServerItemCooldowns.java -@@ -10,6 +10,16 @@ public class ServerItemCooldowns extends ItemCooldowns { +@@ -11,6 +11,16 @@ public class ServerItemCooldowns extends ItemCooldowns { this.player = player; } @@ -23,5 +23,5 @@ index 47283d2a49209839002212e663a503a82ea86587..e0c4c0a9bab0bbc32358030a482aa04c + // Paper end - Add PlayerItemCooldownEvent + @Override - protected void onCooldownStarted(Item item, int duration) { - super.onCooldownStarted(item, duration); + protected void onCooldownStarted(ResourceLocation groupId, int duration) { + super.onCooldownStarted(groupId, duration); diff --git a/patches/unapplied/server/0436-Significantly-improve-performance-of-the-end-generat.patch b/patches/server/0433-Significantly-improve-performance-of-the-end-generat.patch similarity index 100% rename from patches/unapplied/server/0436-Significantly-improve-performance-of-the-end-generat.patch rename to patches/server/0433-Significantly-improve-performance-of-the-end-generat.patch diff --git a/patches/unapplied/server/0437-More-lightning-API.patch b/patches/server/0434-More-lightning-API.patch similarity index 100% rename from patches/unapplied/server/0437-More-lightning-API.patch rename to patches/server/0434-More-lightning-API.patch diff --git a/patches/unapplied/server/0438-Climbing-should-not-bypass-cramming-gamerule.patch b/patches/server/0435-Climbing-should-not-bypass-cramming-gamerule.patch similarity index 75% rename from patches/unapplied/server/0438-Climbing-should-not-bypass-cramming-gamerule.patch rename to patches/server/0435-Climbing-should-not-bypass-cramming-gamerule.patch index 0f9101c994d3..e27625ee8ef0 100644 --- a/patches/unapplied/server/0438-Climbing-should-not-bypass-cramming-gamerule.patch +++ b/patches/server/0435-Climbing-should-not-bypass-cramming-gamerule.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Climbing should not bypass cramming gamerule diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 6ab665efcac4c2543bab9d95472026e0ec8580c5..dae7643897b47dba304cbea56112445df2736cff 100644 +index 0bd608894ab596c773570f92b4662aee5a6934cc..25f625e28c8c9f63a1b2207d5e8d1a48e2fea039 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -2079,6 +2079,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2195,6 +2195,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public boolean isPushable() { @@ -22,10 +22,10 @@ index 6ab665efcac4c2543bab9d95472026e0ec8580c5..dae7643897b47dba304cbea56112445d } diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java -index eb425fac573881f3aad09ae75a32184fb0e325a6..302decdccd37c5579473c8fc33adda3956be7603 100644 +index b8d57e25851dd7da905100dfd4022e4b99fd7f02..721321a19ce056f82de2bef44a8791dc9d5b3418 100644 --- a/src/main/java/net/minecraft/world/entity/EntitySelector.java +++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java -@@ -46,11 +46,16 @@ public final class EntitySelector { +@@ -45,11 +45,16 @@ public final class EntitySelector { } public static Predicate pushableBy(Entity entity) { @@ -44,19 +44,19 @@ index eb425fac573881f3aad09ae75a32184fb0e325a6..302decdccd37c5579473c8fc33adda39 } else if (entity1 instanceof Player && entity instanceof Player && !io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions) { // Paper - Configurable player collision return false; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 906e8589483b93bcdb55677f7f942f6c7a89caf8..d94c3e86885c5a8ba636988d29f98b496e13b627 100644 +index 91a5166e69a03d846a1b396ba964003c12a0dcdb..7ea58478d3cde175a056f41cf945636a04128828 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3573,7 +3573,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3712,7 +3712,7 @@ public abstract class LivingEntity extends Entity implements Attackable { return; } // Paper end - don't run getEntities if we're not going to use its result -- List list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushableBy(this)); -+ List list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushable(this, this.level().paperConfig().collisions.fixClimbingBypassingCrammingRule)); // Paper - Climbing should not bypass cramming gamerule +- List list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushableBy(this)); ++ List list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushable(this, this.level().paperConfig().collisions.fixClimbingBypassingCrammingRule)); // Paper - Climbing should not bypass cramming gamerule if (!list.isEmpty()) { // Paper - don't run getEntities if we're not going to use its result; moved up -@@ -3765,9 +3765,16 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3917,9 +3917,16 @@ public abstract class LivingEntity extends Entity implements Attackable { return !this.isRemoved() && this.collides; // CraftBukkit } @@ -75,10 +75,10 @@ index 906e8589483b93bcdb55677f7f942f6c7a89caf8..d94c3e86885c5a8ba636988d29f98b49 // CraftBukkit start - collidable API diff --git a/src/main/java/net/minecraft/world/entity/ambient/Bat.java b/src/main/java/net/minecraft/world/entity/ambient/Bat.java -index 934fa26b8f347b8b2d90f79370b62165c0cdc312..dc27ddf5131e7398a5390a5187261d4c7fb6ccaa 100644 +index d8a2fbb33f4b77ffb1b3c928a369c2824ad815d7..60c2868f255d372226e0c1389caaa5477bbef41e 100644 --- a/src/main/java/net/minecraft/world/entity/ambient/Bat.java +++ b/src/main/java/net/minecraft/world/entity/ambient/Bat.java -@@ -88,7 +88,7 @@ public class Bat extends AmbientCreature { +@@ -91,7 +91,7 @@ public class Bat extends AmbientCreature { } @Override @@ -88,10 +88,10 @@ index 934fa26b8f347b8b2d90f79370b62165c0cdc312..dc27ddf5131e7398a5390a5187261d4c } diff --git a/src/main/java/net/minecraft/world/entity/animal/Parrot.java b/src/main/java/net/minecraft/world/entity/animal/Parrot.java -index 12b2267cba476547d510d9161b25a28f4f5c798e..97931bfd360725945ab9606ff698b518ae101076 100644 +index 9a187b9b20e4e5ee4cdb7df31629faee9d3ebb60..8883894da73c7d5975a8826d23ee7f542db98b0b 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Parrot.java +++ b/src/main/java/net/minecraft/world/entity/animal/Parrot.java -@@ -362,8 +362,8 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder()); @@ -68,7 +68,7 @@ index aa8667f0b14dc8944dd3457b431162e59bf54ada..5f5b2dd2bb45a0d3ae7de063b3bc611d ); itemEntity.setDeltaMovement( 0.05 * (double)direction2.getStepX() + world.random.nextDouble() * 0.02, -@@ -57,6 +65,7 @@ public class PumpkinBlock extends Block { +@@ -55,6 +63,7 @@ public class PumpkinBlock extends Block { 0.05 * (double)direction2.getStepZ() + world.random.nextDouble() * 0.02 ); world.addFreshEntity(itemEntity); diff --git a/patches/server/0438-Limit-recipe-packets.patch b/patches/server/0438-Limit-recipe-packets.patch new file mode 100644 index 000000000000..5ce5387ca5c6 --- /dev/null +++ b/patches/server/0438-Limit-recipe-packets.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Shane Freeder +Date: Sat, 12 Dec 2020 23:45:28 +0000 +Subject: [PATCH] Limit recipe packets + + +diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index e3e43c361d8612dbc79fe88730a3794eb44d85e4..b61cb778196a31df2139deb31dfd924abc6e5d1c 100644 +--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -275,6 +275,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + private final TickThrottler chatSpamThrottler = new TickThrottler(20, 200); + private final TickThrottler tabSpamThrottler = new TickThrottler(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamIncrement, io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamLimit); // Paper - configurable tab spam limits + private final TickThrottler dropSpamThrottler = new TickThrottler(20, 1480); ++ private final TickThrottler recipeSpamPackets = new TickThrottler(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamIncrement, io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamLimit); + private double firstGoodX; + private double firstGoodY; + private double firstGoodZ; +@@ -391,6 +392,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + this.keepConnectionAlive(); + this.chatSpamThrottler.tick(); + this.tabSpamThrottler.tick(); // Paper - configurable tab spam limits ++ this.recipeSpamPackets.tick(); // Paper - auto recipe limit + this.dropSpamThrottler.tick(); + if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L) { + this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 +@@ -3083,6 +3085,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + + @Override + public void handlePlaceRecipe(ServerboundPlaceRecipePacket packet) { ++ // Paper start - auto recipe limit ++ if (!org.bukkit.Bukkit.isPrimaryThread()) { ++ if (!this.recipeSpamPackets.isIncrementAndUnderThreshold()) { ++ this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam")); ++ return; ++ } ++ } ++ // Paper end - auto recipe limit + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + this.player.resetLastActionTime(); + if (!this.player.isSpectator() && this.player.containerMenu.containerId == packet.containerId()) { diff --git a/patches/unapplied/server/0442-Fix-CraftSound-backwards-compatibility.patch b/patches/server/0439-Fix-CraftSound-backwards-compatibility.patch similarity index 100% rename from patches/unapplied/server/0442-Fix-CraftSound-backwards-compatibility.patch rename to patches/server/0439-Fix-CraftSound-backwards-compatibility.patch diff --git a/patches/unapplied/server/0443-Player-Chunk-Load-Unload-Events.patch b/patches/server/0440-Player-Chunk-Load-Unload-Events.patch similarity index 100% rename from patches/unapplied/server/0443-Player-Chunk-Load-Unload-Events.patch rename to patches/server/0440-Player-Chunk-Load-Unload-Events.patch diff --git a/patches/unapplied/server/0444-Optimize-Dynamic-get-Missing-Keys.patch b/patches/server/0441-Optimize-Dynamic-get-Missing-Keys.patch similarity index 100% rename from patches/unapplied/server/0444-Optimize-Dynamic-get-Missing-Keys.patch rename to patches/server/0441-Optimize-Dynamic-get-Missing-Keys.patch diff --git a/patches/unapplied/server/0445-Expose-LivingEntity-hurt-direction.patch b/patches/server/0442-Expose-LivingEntity-hurt-direction.patch similarity index 86% rename from patches/unapplied/server/0445-Expose-LivingEntity-hurt-direction.patch rename to patches/server/0442-Expose-LivingEntity-hurt-direction.patch index 5df6e30894b5..86eb7976a72b 100644 --- a/patches/unapplied/server/0445-Expose-LivingEntity-hurt-direction.patch +++ b/patches/server/0442-Expose-LivingEntity-hurt-direction.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Expose LivingEntity hurt direction diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index cb89b020d93ac838843ec2cbad562326a1e4257b..513e6505706e64f9410fa190014976dc469793af 100644 +index 917ac21794f1aabc6e95ab2fff2ea7547b9778a8..78bb666dbc5ccd84820e1c7b382249510dd5795c 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java @@ -188,7 +188,7 @@ public abstract class Player extends LivingEntity { @@ -18,7 +18,7 @@ index cb89b020d93ac838843ec2cbad562326a1e4257b..513e6505706e64f9410fa190014976dc public Vec3 currentImpulseImpactPos; @Nullable diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index 6cda13df52ee4d56dd1d3c213307bfd38175584c..24aa891ffa9115c05439b06aece85df7a382b7c4 100644 +index 9022555db0df8c269fc039c895422cf36c08097e..cb56c75be83e839bafdae4356f85d33499d01d8a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -125,6 +125,13 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @@ -36,10 +36,10 @@ index 6cda13df52ee4d56dd1d3c213307bfd38175584c..24aa891ffa9115c05439b06aece85df7 public int getSleepTicks() { return this.getHandle().sleepCounter; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 925c842fcf546ad270641b3be7e8a8c432571501..10f3defa8f4b57fb45cf7de06d415b72102e47d5 100644 +index de41ee2cc1be6ef412ec15c79a65cbca653b35d3..ff3b53eff8f5fc1e02e7b30d59ff27dfe8f5d431 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -1005,4 +1005,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -1024,4 +1024,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { this.getHandle().take(((CraftItem) item).getHandle(), quantity); } // Paper end - pickup animation API diff --git a/patches/unapplied/server/0446-Add-OBSTRUCTED-reason-to-BedEnterResult.patch b/patches/server/0443-Add-OBSTRUCTED-reason-to-BedEnterResult.patch similarity index 86% rename from patches/unapplied/server/0446-Add-OBSTRUCTED-reason-to-BedEnterResult.patch rename to patches/server/0443-Add-OBSTRUCTED-reason-to-BedEnterResult.patch index f1f4c227eea8..dde19c16cae0 100644 --- a/patches/unapplied/server/0446-Add-OBSTRUCTED-reason-to-BedEnterResult.patch +++ b/patches/server/0443-Add-OBSTRUCTED-reason-to-BedEnterResult.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add OBSTRUCTED reason to BedEnterResult diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index dbe7931dd7eb43f9381463d3a57ba1eb53820985..24fcb0eb139174671ffb7a8e5222ec9833835f87 100644 +index c7d78f54694b464696c0f1edd0b135d1d5bcde3e..9e3037ac041da5ec2e15a4cd475ec52fee591aac 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -313,6 +313,10 @@ public class CraftEventFactory { +@@ -312,6 +312,10 @@ public class CraftEventFactory { return BedEnterResult.TOO_FAR_AWAY; case NOT_SAFE: return BedEnterResult.NOT_SAFE; diff --git a/patches/unapplied/server/0447-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch b/patches/server/0444-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch similarity index 93% rename from patches/unapplied/server/0447-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch rename to patches/server/0444-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch index 7ac0fb0202e3..8c0b0c171bbd 100644 --- a/patches/unapplied/server/0447-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch +++ b/patches/server/0444-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Fix crash from invalid ingredient lists in diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java -index fcb3b66617150ad503bffe65de4900b1e3af8764..2a155d3611ca2370830ca763d40074df6641958f 100644 +index c8231e421e6c3f1cf8a5aaf8cc64741abe868f41..39cb40b077e9c07471437d5bec16ba9a7e6bce52 100644 --- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java +++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java @@ -273,7 +273,11 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa diff --git a/patches/unapplied/server/0441-Limit-recipe-packets.patch b/patches/unapplied/server/0441-Limit-recipe-packets.patch deleted file mode 100644 index a18fe7565015..000000000000 --- a/patches/unapplied/server/0441-Limit-recipe-packets.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Shane Freeder -Date: Sat, 12 Dec 2020 23:45:28 +0000 -Subject: [PATCH] Limit recipe packets - - -diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index d33cf08f7c47111823abbce481505946db249577..57063f01993445a9965976332306c7f2ab20ed1f 100644 ---- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -266,6 +266,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - // CraftBukkit start - multithreaded fields - private final AtomicInteger chatSpamTickCount = new AtomicInteger(); - private final java.util.concurrent.atomic.AtomicInteger tabSpamLimiter = new java.util.concurrent.atomic.AtomicInteger(); // Paper - configurable tab spam limits -+ private final java.util.concurrent.atomic.AtomicInteger recipeSpamPackets = new java.util.concurrent.atomic.AtomicInteger(); // Paper - auto recipe limit - // CraftBukkit end - private int dropSpamTickCount; - private double firstGoodX; -@@ -384,6 +385,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - // CraftBukkit start - for (int spam; (spam = this.chatSpamTickCount.get()) > 0 && !this.chatSpamTickCount.compareAndSet(spam, spam - 1); ) ; - if (tabSpamLimiter.get() > 0) tabSpamLimiter.getAndDecrement(); // Paper - configurable tab spam limits -+ if (recipeSpamPackets.get() > 0) recipeSpamPackets.getAndDecrement(); // Paper - auto recipe limit - /* Use thread-safe field access instead - if (this.chatSpamTickCount > 0) { - --this.chatSpamTickCount; -@@ -3068,6 +3070,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - - @Override - public void handlePlaceRecipe(ServerboundPlaceRecipePacket packet) { -+ // Paper start - auto recipe limit -+ if (!org.bukkit.Bukkit.isPrimaryThread()) { -+ if (this.recipeSpamPackets.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamLimit) { -+ this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam")); -+ return; -+ } -+ } -+ // Paper end - auto recipe limit - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); - this.player.resetLastActionTime(); - if (!this.player.isSpectator() && this.player.containerMenu.containerId == packet.getContainerId() && this.player.containerMenu instanceof RecipeBookMenu) { From f5177aa12138b4341241c73aab85782f2512ba58 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Wed, 23 Oct 2024 17:58:11 +0200 Subject: [PATCH 022/119] Some more work --- .../0451-Fix-harming-potion-dupe.patch | 0 .../0445-Add-TargetHitEvent.patch} | 0 .../0446-MC-4-Fix-item-position-desync.patch} | 4 +-- .../0447-Additional-Block-Material-API.patch} | 2 +- ...t-Material-from-Boats-and-Minecarts.patch} | 4 +-- ...ob-spawner-spawn-egg-transformation.patch} | 4 +-- ...ix-Not-a-string-Map-Conversion-spam.patch} | 23 +++++---------- ...-Add-PlayerFlowerPotManipulateEvent.patch} | 8 +++--- ...ct-event-not-being-called-sometimes.patch} | 18 ++++++------ .../0453-Zombie-API-breaking-doors.patch} | 0 ...0454-Fix-nerfed-slime-when-splitting.patch | 18 ++++++++++++ .../0455-Add-EntityLoadCrossbowEvent.patch} | 14 +++++----- .../0456-Add-WorldGameRuleChangeEvent.patch} | 28 ++++++++++--------- ...57-Add-ServerResourcesReloadedEvent.patch} | 8 +++--- ...d-settings-for-mobs-picking-up-loot.patch} | 18 ++++++------ .../0459-Add-BlockFailedDispenseEvent.patch} | 8 +++--- ...60-Add-PlayerLecternPageChangeEvent.patch} | 0 ...61-Add-PlayerLoomPatternSelectEvent.patch} | 4 +-- ...nfigurable-door-breaking-difficulty.patch} | 8 +++--- ...ty-commands-shall-not-be-dispatched.patch} | 4 +-- ...0458-Fix-nerfed-slime-when-splitting.patch | 18 ------------ 21 files changed, 92 insertions(+), 99 deletions(-) rename patches/{unapplied/server => later}/0451-Fix-harming-potion-dupe.patch (100%) rename patches/{unapplied/server/0448-Add-TargetHitEvent.patch => server/0445-Add-TargetHitEvent.patch} (100%) rename patches/{unapplied/server/0449-MC-4-Fix-item-position-desync.patch => server/0446-MC-4-Fix-item-position-desync.patch} (93%) rename patches/{unapplied/server/0450-Additional-Block-Material-API.patch => server/0447-Additional-Block-Material-API.patch} (93%) rename patches/{unapplied/server/0452-API-to-get-Material-from-Boats-and-Minecarts.patch => server/0448-API-to-get-Material-from-Boats-and-Minecarts.patch} (93%) rename patches/{unapplied/server/0453-Allow-disabling-mob-spawner-spawn-egg-transformation.patch => server/0449-Allow-disabling-mob-spawner-spawn-egg-transformation.patch} (84%) rename patches/{unapplied/server/0454-Fix-Not-a-string-Map-Conversion-spam.patch => server/0450-Fix-Not-a-string-Map-Conversion-spam.patch} (65%) rename patches/{unapplied/server/0455-Add-PlayerFlowerPotManipulateEvent.patch => server/0451-Add-PlayerFlowerPotManipulateEvent.patch} (90%) rename patches/{unapplied/server/0456-Fix-interact-event-not-being-called-sometimes.patch => server/0452-Fix-interact-event-not-being-called-sometimes.patch} (80%) rename patches/{unapplied/server/0457-Zombie-API-breaking-doors.patch => server/0453-Zombie-API-breaking-doors.patch} (100%) create mode 100644 patches/server/0454-Fix-nerfed-slime-when-splitting.patch rename patches/{unapplied/server/0459-Add-EntityLoadCrossbowEvent.patch => server/0455-Add-EntityLoadCrossbowEvent.patch} (87%) rename patches/{unapplied/server/0460-Add-WorldGameRuleChangeEvent.patch => server/0456-Add-WorldGameRuleChangeEvent.patch} (86%) rename patches/{unapplied/server/0461-Add-ServerResourcesReloadedEvent.patch => server/0457-Add-ServerResourcesReloadedEvent.patch} (90%) rename patches/{unapplied/server/0462-Add-world-settings-for-mobs-picking-up-loot.patch => server/0458-Add-world-settings-for-mobs-picking-up-loot.patch} (68%) rename patches/{unapplied/server/0463-Add-BlockFailedDispenseEvent.patch => server/0459-Add-BlockFailedDispenseEvent.patch} (89%) rename patches/{unapplied/server/0464-Add-PlayerLecternPageChangeEvent.patch => server/0460-Add-PlayerLecternPageChangeEvent.patch} (100%) rename patches/{unapplied/server/0465-Add-PlayerLoomPatternSelectEvent.patch => server/0461-Add-PlayerLoomPatternSelectEvent.patch} (94%) rename patches/{unapplied/server/0466-Configurable-door-breaking-difficulty.patch => server/0462-Configurable-door-breaking-difficulty.patch} (86%) rename patches/{unapplied/server/0467-Empty-commands-shall-not-be-dispatched.patch => server/0463-Empty-commands-shall-not-be-dispatched.patch} (84%) delete mode 100644 patches/unapplied/server/0458-Fix-nerfed-slime-when-splitting.patch diff --git a/patches/unapplied/server/0451-Fix-harming-potion-dupe.patch b/patches/later/0451-Fix-harming-potion-dupe.patch similarity index 100% rename from patches/unapplied/server/0451-Fix-harming-potion-dupe.patch rename to patches/later/0451-Fix-harming-potion-dupe.patch diff --git a/patches/unapplied/server/0448-Add-TargetHitEvent.patch b/patches/server/0445-Add-TargetHitEvent.patch similarity index 100% rename from patches/unapplied/server/0448-Add-TargetHitEvent.patch rename to patches/server/0445-Add-TargetHitEvent.patch diff --git a/patches/unapplied/server/0449-MC-4-Fix-item-position-desync.patch b/patches/server/0446-MC-4-Fix-item-position-desync.patch similarity index 93% rename from patches/unapplied/server/0449-MC-4-Fix-item-position-desync.patch rename to patches/server/0446-MC-4-Fix-item-position-desync.patch index 3f4003c4f5b2..26cf19c2b634 100644 --- a/patches/unapplied/server/0449-MC-4-Fix-item-position-desync.patch +++ b/patches/server/0446-MC-4-Fix-item-position-desync.patch @@ -28,10 +28,10 @@ index 488ebd443903af812913437f1ade3002093f2470..a043ac10834562d357ef0b5aded2e916 public Vec3 decode(long x, long y, long z) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index dae7643897b47dba304cbea56112445df2736cff..bed376337035545e7ec677f2f7fe3372a3c9ea25 100644 +index 25f625e28c8c9f63a1b2207d5e8d1a48e2fea039..ad34a525f54a157140323a26752a420a8e348a55 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -4260,6 +4260,16 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4449,6 +4449,16 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return; } // Paper end - Block invalid positions and bounding box diff --git a/patches/unapplied/server/0450-Additional-Block-Material-API.patch b/patches/server/0447-Additional-Block-Material-API.patch similarity index 93% rename from patches/unapplied/server/0450-Additional-Block-Material-API.patch rename to patches/server/0447-Additional-Block-Material-API.patch index 81728edf4850..19f5b4b7ef3f 100644 --- a/patches/unapplied/server/0450-Additional-Block-Material-API.patch +++ b/patches/server/0447-Additional-Block-Material-API.patch @@ -9,7 +9,7 @@ process to do this in the Bukkit API Adds API for buildable, replaceable, burnable too. diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index aa644231425b9622437538b5c092d4064a40cced..98e87dc15e2ed23f6897ba6359846ff5bc32b655 100644 +index 5f4dcf6d86db66186dc31075bdb739f5dbae6480..1595e877b02b447b36f5c316ae70d4023b78a862 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -440,6 +440,25 @@ public class CraftBlock implements Block { diff --git a/patches/unapplied/server/0452-API-to-get-Material-from-Boats-and-Minecarts.patch b/patches/server/0448-API-to-get-Material-from-Boats-and-Minecarts.patch similarity index 93% rename from patches/unapplied/server/0452-API-to-get-Material-from-Boats-and-Minecarts.patch rename to patches/server/0448-API-to-get-Material-from-Boats-and-Minecarts.patch index 9bcb17ad1410..8462025bf835 100644 --- a/patches/unapplied/server/0452-API-to-get-Material-from-Boats-and-Minecarts.patch +++ b/patches/server/0448-API-to-get-Material-from-Boats-and-Minecarts.patch @@ -5,10 +5,10 @@ Subject: [PATCH] API to get Material from Boats and Minecarts diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java -index f332bd4e6f663147c9ef6ce03d926feb74b55e93..d161cbf9c83cd78593864850b98f688da2c85aa5 100644 +index eaa46bf5954ed7c2be6d4b3772b5f2e971505c78..5de1ada561d11c247a597effab1e0aa363b7c90f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java -@@ -79,6 +79,13 @@ public class CraftBoat extends CraftVehicle implements Boat { +@@ -78,6 +78,13 @@ public abstract class CraftBoat extends CraftVehicle implements Boat { this.getHandle().landBoats = workOnLand; } diff --git a/patches/unapplied/server/0453-Allow-disabling-mob-spawner-spawn-egg-transformation.patch b/patches/server/0449-Allow-disabling-mob-spawner-spawn-egg-transformation.patch similarity index 84% rename from patches/unapplied/server/0453-Allow-disabling-mob-spawner-spawn-egg-transformation.patch rename to patches/server/0449-Allow-disabling-mob-spawner-spawn-egg-transformation.patch index da8441444c48..893e6ffe6020 100644 --- a/patches/unapplied/server/0453-Allow-disabling-mob-spawner-spawn-egg-transformation.patch +++ b/patches/server/0449-Allow-disabling-mob-spawner-spawn-egg-transformation.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Allow disabling mob spawner spawn egg transformation diff --git a/src/main/java/net/minecraft/world/item/SpawnEggItem.java b/src/main/java/net/minecraft/world/item/SpawnEggItem.java -index 6e91fec416493b2fabe1e8a6214ab7673212e451..9cea8da84f39bb3f687139ef213ccea358724dee 100644 +index ac35651e4f415243a0f84cca9a4f776b1f1623a5..9956ed42df55daa6d97fd6e3ab5368dad91cfaf0 100644 --- a/src/main/java/net/minecraft/world/item/SpawnEggItem.java +++ b/src/main/java/net/minecraft/world/item/SpawnEggItem.java -@@ -69,6 +69,8 @@ public class SpawnEggItem extends Item { +@@ -68,6 +68,8 @@ public class SpawnEggItem extends Item { EntityType entitytypes; if (tileentity instanceof Spawner) { diff --git a/patches/unapplied/server/0454-Fix-Not-a-string-Map-Conversion-spam.patch b/patches/server/0450-Fix-Not-a-string-Map-Conversion-spam.patch similarity index 65% rename from patches/unapplied/server/0454-Fix-Not-a-string-Map-Conversion-spam.patch rename to patches/server/0450-Fix-Not-a-string-Map-Conversion-spam.patch index 5b2328afe8a1..8952de76333c 100644 --- a/patches/unapplied/server/0454-Fix-Not-a-string-Map-Conversion-spam.patch +++ b/patches/server/0450-Fix-Not-a-string-Map-Conversion-spam.patch @@ -12,26 +12,17 @@ requesting the world. Track spigot issue to see when fixed: https://hub.spigotmc.org/jira/browse/SPIGOT-6181 diff --git a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java -index 5e469bd4d9ca428abdd9d758993164635dc86f27..d6a0a882331226c3ae4ced09e449eb7931740f8f 100644 +index c21ae4975206398e7d20b37a749b830b9219c746..a89f0b652c515efbc24ffc9af47fa65082946e54 100644 --- a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java +++ b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java -@@ -21,6 +21,8 @@ import net.minecraft.core.component.DataComponents; - import net.minecraft.nbt.CompoundTag; - import net.minecraft.nbt.ListTag; - import net.minecraft.nbt.NbtOps; -+import net.minecraft.nbt.NumericTag; -+import net.minecraft.nbt.StringTag; - import net.minecraft.nbt.Tag; - import net.minecraft.network.FriendlyByteBuf; - import net.minecraft.network.chat.Component; -@@ -121,7 +123,26 @@ public class MapItemSavedData extends SavedData { +@@ -123,7 +123,26 @@ public class MapItemSavedData extends SavedData { } - public static MapItemSavedData load(CompoundTag nbt, HolderLookup.Provider registryLookup) { + public static MapItemSavedData load(CompoundTag nbt, HolderLookup.Provider registries) { - DataResult> dataresult = DimensionType.parseLegacy(new Dynamic(NbtOps.INSTANCE, nbt.get("dimension"))); // CraftBukkit - decompile error + // Paper start - fix "Not a string" spam + Tag dimension = nbt.get("dimension"); -+ if (dimension instanceof NumericTag && ((NumericTag) dimension).getAsInt() >= CraftWorld.CUSTOM_DIMENSION_OFFSET) { ++ if (dimension instanceof final net.minecraft.nbt.NumericTag numericTag && numericTag.getAsInt() >= CraftWorld.CUSTOM_DIMENSION_OFFSET) { + long least = nbt.getLong("UUIDLeast"); + long most = nbt.getLong("UUIDMost"); + @@ -39,12 +30,12 @@ index 5e469bd4d9ca428abdd9d758993164635dc86f27..d6a0a882331226c3ae4ced09e449eb79 + UUID uuid = new UUID(most, least); + CraftWorld world = (CraftWorld) Bukkit.getWorld(uuid); + if (world != null) { -+ dimension = StringTag.valueOf("minecraft:" + world.getName().toLowerCase(java.util.Locale.ENGLISH)); ++ dimension = net.minecraft.nbt.StringTag.valueOf("minecraft:" + world.getName().toLowerCase(java.util.Locale.ENGLISH)); + } else { -+ dimension = StringTag.valueOf("bukkit:_invalidworld_"); ++ dimension = net.minecraft.nbt.StringTag.valueOf("bukkit:_invalidworld_"); + } + } else { -+ dimension = StringTag.valueOf("bukkit:_invalidworld_"); ++ dimension = net.minecraft.nbt.StringTag.valueOf("bukkit:_invalidworld_"); + } + } + DataResult> dataresult = DimensionType.parseLegacy(new Dynamic(NbtOps.INSTANCE, dimension)); // CraftBukkit - decompile error diff --git a/patches/unapplied/server/0455-Add-PlayerFlowerPotManipulateEvent.patch b/patches/server/0451-Add-PlayerFlowerPotManipulateEvent.patch similarity index 90% rename from patches/unapplied/server/0455-Add-PlayerFlowerPotManipulateEvent.patch rename to patches/server/0451-Add-PlayerFlowerPotManipulateEvent.patch index 8b61833059ca..aa78c43c602b 100644 --- a/patches/unapplied/server/0455-Add-PlayerFlowerPotManipulateEvent.patch +++ b/patches/server/0451-Add-PlayerFlowerPotManipulateEvent.patch @@ -5,12 +5,12 @@ Subject: [PATCH] Add PlayerFlowerPotManipulateEvent diff --git a/src/main/java/net/minecraft/world/level/block/FlowerPotBlock.java b/src/main/java/net/minecraft/world/level/block/FlowerPotBlock.java -index b0c950fa7426dc762b99080d98831b961fc19da2..7194565ad1a910fe300d8664a30b35c4eff18cb7 100644 +index c6de1b6587b300404c38c27f566c80de11bc0814..863eec736b4941930c62ca357703a56d4d21c950 100644 --- a/src/main/java/net/minecraft/world/level/block/FlowerPotBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FlowerPotBlock.java -@@ -63,6 +63,18 @@ public class FlowerPotBlock extends Block { +@@ -61,6 +61,18 @@ public class FlowerPotBlock extends Block { } else if (!this.isEmpty()) { - return ItemInteractionResult.CONSUME; + return InteractionResult.CONSUME; } else { + // Paper start - Add PlayerFlowerPotManipulateEvent + org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos); @@ -27,7 +27,7 @@ index b0c950fa7426dc762b99080d98831b961fc19da2..7194565ad1a910fe300d8664a30b35c4 world.setBlock(pos, blockState, 3); world.gameEvent(player, GameEvent.BLOCK_CHANGE, pos); player.awardStat(Stats.POT_FLOWER); -@@ -77,6 +89,18 @@ public class FlowerPotBlock extends Block { +@@ -75,6 +87,18 @@ public class FlowerPotBlock extends Block { return InteractionResult.CONSUME; } else { ItemStack itemStack = new ItemStack(this.potted); diff --git a/patches/unapplied/server/0456-Fix-interact-event-not-being-called-sometimes.patch b/patches/server/0452-Fix-interact-event-not-being-called-sometimes.patch similarity index 80% rename from patches/unapplied/server/0456-Fix-interact-event-not-being-called-sometimes.patch rename to patches/server/0452-Fix-interact-event-not-being-called-sometimes.patch index fc4bcdc2d173..9aa0d988fa1b 100644 --- a/patches/unapplied/server/0456-Fix-interact-event-not-being-called-sometimes.patch +++ b/patches/server/0452-Fix-interact-event-not-being-called-sometimes.patch @@ -11,19 +11,19 @@ Subject: [PATCH] Fix interact event not being called sometimes Co-authored-by: Moulberry diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 57063f01993445a9965976332306c7f2ab20ed1f..d7d36b5148f2e7280816cc70b300b9b10720f751 100644 +index b61cb778196a31df2139deb31dfd924abc6e5d1c..0c413f4981038c5c3f12ba17309ce354c3f13ec6 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1770,7 +1770,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - MutableComponent ichatmutablecomponent = Component.translatable("build.tooHigh", i - 1).withStyle(ChatFormatting.RED); +@@ -1777,7 +1777,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + } else if (enuminteractionresult instanceof InteractionResult.Success) { + InteractionResult.Success enuminteractionresult_d = (InteractionResult.Success) enuminteractionresult; - this.player.sendSystemMessage(ichatmutablecomponent, true); -- } else if (enuminteractionresult.shouldSwing()) { -+ } else if (enuminteractionresult.shouldSwing() && !this.player.gameMode.interactResult) { // Paper - Call interact event - this.player.swing(enumhand, true); +- if (enuminteractionresult_d.swingSource() == InteractionResult.SwingSource.SERVER) { ++ if (enuminteractionresult_d.swingSource() == InteractionResult.SwingSource.SERVER && !this.player.gameMode.interactResult) { + this.player.swing(enumhand, true); + } } - } -@@ -2391,13 +2391,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2401,13 +2401,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl double d3 = Math.max(this.player.blockInteractionRange(), this.player.entityInteractionRange()); // SPIGOT-5607: Only call interact event if no block or entity is being clicked. Use bukkit ray trace method, because it handles blocks and entities at the same time // SPIGOT-7429: Make sure to call PlayerInteractEvent for spectators and non-pickable entities diff --git a/patches/unapplied/server/0457-Zombie-API-breaking-doors.patch b/patches/server/0453-Zombie-API-breaking-doors.patch similarity index 100% rename from patches/unapplied/server/0457-Zombie-API-breaking-doors.patch rename to patches/server/0453-Zombie-API-breaking-doors.patch diff --git a/patches/server/0454-Fix-nerfed-slime-when-splitting.patch b/patches/server/0454-Fix-nerfed-slime-when-splitting.patch new file mode 100644 index 000000000000..c35358b895cf --- /dev/null +++ b/patches/server/0454-Fix-nerfed-slime-when-splitting.patch @@ -0,0 +1,18 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Mon, 24 Aug 2020 08:39:06 -0700 +Subject: [PATCH] Fix nerfed slime when splitting + + +diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java +index 26f4db572dc6c25a9815b8f352d8829e252fa1a2..129f0cbc0469cb2804db6088b53347d88d91f4eb 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java ++++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java +@@ -250,6 +250,7 @@ public class Slime extends Mob implements Enemy { + float f3 = ((float) (l / 2) - 0.5F) * f1; + + Slime converted = this.convertTo(this.getType(), new ConversionParams(ConversionType.SPLIT_ON_DEATH, false, false, scoreboardteam), EntitySpawnReason.TRIGGERED, (entityslime) -> { // CraftBukkit ++ entityslime.aware = this.aware; // Paper - Fix nerfed slime when splitting + entityslime.setSize(j, true); + entityslime.moveTo(this.getX() + (double) f2, this.getY() + 0.5D, this.getZ() + (double) f3, this.random.nextFloat() * 360.0F, 0.0F); + // CraftBukkit start diff --git a/patches/unapplied/server/0459-Add-EntityLoadCrossbowEvent.patch b/patches/server/0455-Add-EntityLoadCrossbowEvent.patch similarity index 87% rename from patches/unapplied/server/0459-Add-EntityLoadCrossbowEvent.patch rename to patches/server/0455-Add-EntityLoadCrossbowEvent.patch index a2f95139f888..72ec5141a02a 100644 --- a/patches/unapplied/server/0459-Add-EntityLoadCrossbowEvent.patch +++ b/patches/server/0455-Add-EntityLoadCrossbowEvent.patch @@ -5,11 +5,11 @@ Subject: [PATCH] Add EntityLoadCrossbowEvent diff --git a/src/main/java/net/minecraft/world/item/CrossbowItem.java b/src/main/java/net/minecraft/world/item/CrossbowItem.java -index f64cdfac1fc1333845ea4ea5efb7922f0ae39619..c39fa953accd6cf35672f452052cca42fe6f29d0 100644 +index 710181cf04563f06690eee5b46a5a0d84844ac29..52c40eafc77e50a6fd21b9a7a250cea501f11690 100644 --- a/src/main/java/net/minecraft/world/item/CrossbowItem.java +++ b/src/main/java/net/minecraft/world/item/CrossbowItem.java @@ -89,7 +89,14 @@ public class CrossbowItem extends ProjectileWeaponItem { - public void releaseUsing(ItemStack stack, Level world, LivingEntity user, int remainingUseTicks) { + public boolean releaseUsing(ItemStack stack, Level world, LivingEntity user, int remainingUseTicks) { int i = this.getUseDuration(stack, user) - remainingUseTicks; float f = getPowerForTime(i, stack, user); - if (f >= 1.0F && !isCharged(stack) && tryLoadProjectiles(user, stack)) { @@ -18,13 +18,13 @@ index f64cdfac1fc1333845ea4ea5efb7922f0ae39619..c39fa953accd6cf35672f452052cca42 + final io.papermc.paper.event.entity.EntityLoadCrossbowEvent event = new io.papermc.paper.event.entity.EntityLoadCrossbowEvent(user.getBukkitLivingEntity(), stack.asBukkitMirror(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(user.getUsedItemHand())); + if (!event.callEvent() || !tryLoadProjectiles(user, stack, event.shouldConsumeItem()) || !event.shouldConsumeItem()) { + if (user instanceof ServerPlayer player) player.containerMenu.sendAllDataToRemote(); -+ return; ++ return false; + } + // Paper end - Add EntityLoadCrossbowEvent CrossbowItem.ChargingSounds chargingSounds = this.getChargingSounds(stack); chargingSounds.end() .ifPresent( -@@ -107,8 +114,14 @@ public class CrossbowItem extends ProjectileWeaponItem { +@@ -110,8 +117,14 @@ public class CrossbowItem extends ProjectileWeaponItem { } } @@ -42,10 +42,10 @@ index f64cdfac1fc1333845ea4ea5efb7922f0ae39619..c39fa953accd6cf35672f452052cca42 crossbow.set(DataComponents.CHARGED_PROJECTILES, ChargedProjectiles.of(list)); return true; diff --git a/src/main/java/net/minecraft/world/item/ProjectileWeaponItem.java b/src/main/java/net/minecraft/world/item/ProjectileWeaponItem.java -index 56595dd3a0b7df4b5f9819ade797212278c8fd40..32dd0b13a0819f597d8a93c6bc3a155781067544 100644 +index a7d0ac6513fd888e222b3128afc1a227ea91f1d2..78ba170a83f8c026bd110eae494c52577182ed61 100644 --- a/src/main/java/net/minecraft/world/item/ProjectileWeaponItem.java +++ b/src/main/java/net/minecraft/world/item/ProjectileWeaponItem.java -@@ -114,6 +114,11 @@ public abstract class ProjectileWeaponItem extends Item { +@@ -109,6 +109,11 @@ public abstract class ProjectileWeaponItem extends Item { } protected static List draw(ItemStack stack, ItemStack projectileStack, LivingEntity shooter) { @@ -57,7 +57,7 @@ index 56595dd3a0b7df4b5f9819ade797212278c8fd40..32dd0b13a0819f597d8a93c6bc3a1557 if (projectileStack.isEmpty()) { return List.of(); } else { -@@ -133,7 +138,7 @@ public abstract class ProjectileWeaponItem extends Item { +@@ -128,7 +133,7 @@ public abstract class ProjectileWeaponItem extends Item { ItemStack itemstack2 = projectileStack.copy(); for (int k = 0; k < j; ++k) { diff --git a/patches/unapplied/server/0460-Add-WorldGameRuleChangeEvent.patch b/patches/server/0456-Add-WorldGameRuleChangeEvent.patch similarity index 86% rename from patches/unapplied/server/0460-Add-WorldGameRuleChangeEvent.patch rename to patches/server/0456-Add-WorldGameRuleChangeEvent.patch index 25259dc06e37..7925a1810ace 100644 --- a/patches/unapplied/server/0460-Add-WorldGameRuleChangeEvent.patch +++ b/patches/server/0456-Add-WorldGameRuleChangeEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add WorldGameRuleChangeEvent diff --git a/src/main/java/net/minecraft/server/commands/GameRuleCommand.java b/src/main/java/net/minecraft/server/commands/GameRuleCommand.java -index c8c358531dbc167e249bac2af246c5e34fbdd4df..10c1790226e25da3b9b599c9a40de57d5727ddc4 100644 +index 6fc70f07f9ba964ff6f5176367dab788decfc917..da0600ab3b0a983ac36cb777d21160bdaced7c52 100644 --- a/src/main/java/net/minecraft/server/commands/GameRuleCommand.java +++ b/src/main/java/net/minecraft/server/commands/GameRuleCommand.java -@@ -33,7 +33,7 @@ public class GameRuleCommand { +@@ -36,7 +36,7 @@ public class GameRuleCommand { CommandSourceStack commandlistenerwrapper = (CommandSourceStack) context.getSource(); T t0 = commandlistenerwrapper.getLevel().getGameRules().getRule(key); // CraftBukkit @@ -18,10 +18,10 @@ index c8c358531dbc167e249bac2af246c5e34fbdd4df..10c1790226e25da3b9b599c9a40de57d return Component.translatable("commands.gamerule.set", key.getId(), t0.toString()); }, true); diff --git a/src/main/java/net/minecraft/world/level/GameRules.java b/src/main/java/net/minecraft/world/level/GameRules.java -index 0b46ad360be919e4aeb0ffc0eebae9fe712fb861..51e560d7856f230c5aa2dc32706c3a4996720aa5 100644 +index 7ea92a0b0f5d4eb6bd873e61c42bc0499d5d2028..09299e45552eb998fd02123c3921c0653f85083d 100644 --- a/src/main/java/net/minecraft/world/level/GameRules.java +++ b/src/main/java/net/minecraft/world/level/GameRules.java -@@ -293,10 +293,10 @@ public class GameRules { +@@ -322,10 +322,10 @@ public class GameRules { this.type = type; } @@ -35,7 +35,7 @@ index 0b46ad360be919e4aeb0ffc0eebae9fe712fb861..51e560d7856f230c5aa2dc32706c3a49 this.onChanged(((CommandSourceStack) context.getSource()).getLevel()); // CraftBukkit - per-world } -@@ -354,8 +354,11 @@ public class GameRules { +@@ -383,8 +383,11 @@ public class GameRules { } @Override @@ -49,7 +49,7 @@ index 0b46ad360be919e4aeb0ffc0eebae9fe712fb861..51e560d7856f230c5aa2dc32706c3a49 } public boolean get() { -@@ -427,8 +430,11 @@ public class GameRules { +@@ -456,8 +459,11 @@ public class GameRules { } @Override @@ -64,33 +64,35 @@ index 0b46ad360be919e4aeb0ffc0eebae9fe712fb861..51e560d7856f230c5aa2dc32706c3a49 public int get() { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 99fccedaab2600881683140e10ee17377375b911..f698ac90bd3086519f49e92451228415efaf5530 100644 +index 04ef1c3433d3ac8a58f0d460877e176668e0fc8f..5541a9f197777124dd908e3f56050b49df821acc 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -1887,8 +1887,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1899,9 +1899,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { + if (rule == null || value == null) return false; if (!this.isGameRule(rule)) return false; - + // Paper start - Add WorldGameRuleChangeEvent + GameRule gameRule = GameRule.getByName(rule); + io.papermc.paper.event.world.WorldGameRuleChangeEvent event = new io.papermc.paper.event.world.WorldGameRuleChangeEvent(this, null, gameRule, value); + if (!event.callEvent()) return false; + // Paper end - Add WorldGameRuleChangeEvent - GameRules.Value handle = this.getHandle().getGameRules().getRule(CraftWorld.getGameRulesNMS().get(rule)); + + GameRules.Value handle = this.getHandle().getGameRules().getRule(this.getGameRulesNMS().get(rule)); - handle.deserialize(value); + handle.deserialize(event.getValue()); // Paper - Add WorldGameRuleChangeEvent handle.onChanged(this.getHandle()); return true; } -@@ -1924,8 +1929,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1936,9 +1941,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { + Preconditions.checkArgument(newValue != null, "GameRule value cannot be null"); if (!this.isGameRule(rule.getName())) return false; - + // Paper start - Add WorldGameRuleChangeEvent + io.papermc.paper.event.world.WorldGameRuleChangeEvent event = new io.papermc.paper.event.world.WorldGameRuleChangeEvent(this, null, rule, String.valueOf(newValue)); + if (!event.callEvent()) return false; + // Paper end - Add WorldGameRuleChangeEvent - GameRules.Value handle = this.getHandle().getGameRules().getRule(CraftWorld.getGameRulesNMS().get(rule.getName())); + + GameRules.Value handle = this.getHandle().getGameRules().getRule(this.getGameRulesNMS().get(rule.getName())); - handle.deserialize(newValue.toString()); + handle.deserialize(event.getValue()); // Paper - Add WorldGameRuleChangeEvent handle.onChanged(this.getHandle()); diff --git a/patches/unapplied/server/0461-Add-ServerResourcesReloadedEvent.patch b/patches/server/0457-Add-ServerResourcesReloadedEvent.patch similarity index 90% rename from patches/unapplied/server/0461-Add-ServerResourcesReloadedEvent.patch rename to patches/server/0457-Add-ServerResourcesReloadedEvent.patch index 830f76c6157d..faae21851f33 100644 --- a/patches/unapplied/server/0461-Add-ServerResourcesReloadedEvent.patch +++ b/patches/server/0457-Add-ServerResourcesReloadedEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add ServerResourcesReloadedEvent diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 05aa3323e9ae971fba5ab8c6c319c7805a3808aa..39ce74bc3fbb282f56028273d53f980171bdb464 100644 +index 263ed74fd8a8a53ce6d676201f75c5b334345c84..058719f8b768b5a1227a19927d0f632815190a91 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2114,7 +2114,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop completablefuture = CompletableFuture.supplyAsync(() -> { Stream stream = dataPacks.stream(); // CraftBukkit - decompile error PackRepository resourcepackrepository = this.packRepository; -@@ -2146,6 +2152,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop= 0 && id < this.selectablePatterns.size()) { diff --git a/patches/unapplied/server/0466-Configurable-door-breaking-difficulty.patch b/patches/server/0462-Configurable-door-breaking-difficulty.patch similarity index 86% rename from patches/unapplied/server/0466-Configurable-door-breaking-difficulty.patch rename to patches/server/0462-Configurable-door-breaking-difficulty.patch index 679bb5f5e745..76df839d0d77 100644 --- a/patches/unapplied/server/0466-Configurable-door-breaking-difficulty.patch +++ b/patches/server/0462-Configurable-door-breaking-difficulty.patch @@ -10,10 +10,10 @@ public net.minecraft.world.entity.monster.Zombie DOOR_BREAKING_PREDICATE Co-authored-by: Doc diff --git a/src/main/java/net/minecraft/world/entity/monster/Vindicator.java b/src/main/java/net/minecraft/world/entity/monster/Vindicator.java -index 7c3aff97ba777af131d7efad0b08b844bf6e8946..0615bb305d70f660a6baa7f78078990d6db227d3 100644 +index b06eedb1cb13771bbc7d0b812a9df864d1f73142..96b105697c91314148fd1b783501389214b1a3f0 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Vindicator.java +++ b/src/main/java/net/minecraft/world/entity/monster/Vindicator.java -@@ -179,7 +179,7 @@ public class Vindicator extends AbstractIllager { +@@ -184,7 +184,7 @@ public class Vindicator extends AbstractIllager { static class VindicatorBreakDoorGoal extends BreakDoorGoal { public VindicatorBreakDoorGoal(Mob mob) { @@ -23,10 +23,10 @@ index 7c3aff97ba777af131d7efad0b08b844bf6e8946..0615bb305d70f660a6baa7f78078990d } diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index 5908f1646b542d61b5a2b23b284b1532e4b276c1..fd304e7d8305877d56de7a38b8664e5a70bf0c33 100644 +index 4477d1a82a49e391760689eb991d1595995914f5..6dc9fc3451edec01f11f526c05d84138c46a3a8e 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -@@ -101,7 +101,7 @@ public class Zombie extends Monster { +@@ -103,7 +103,7 @@ public class Zombie extends Monster { public Zombie(EntityType type, Level world) { super(type, world); diff --git a/patches/unapplied/server/0467-Empty-commands-shall-not-be-dispatched.patch b/patches/server/0463-Empty-commands-shall-not-be-dispatched.patch similarity index 84% rename from patches/unapplied/server/0467-Empty-commands-shall-not-be-dispatched.patch rename to patches/server/0463-Empty-commands-shall-not-be-dispatched.patch index f58be08904c8..ca4dd56d56bd 100644 --- a/patches/unapplied/server/0467-Empty-commands-shall-not-be-dispatched.patch +++ b/patches/server/0463-Empty-commands-shall-not-be-dispatched.patch @@ -5,10 +5,10 @@ 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 8ca9ac8eff9d605baa878ca24e165ac5642bf160..f52e9732524b62b0fecdc48e099163f31fe367b4 100644 +index a7eb2a37a81a414dcb19319c075faefe0382aeba..e38f1d972d87f33a5f28459aa988e09f24614453 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -286,6 +286,7 @@ public class Commands { +@@ -291,6 +291,7 @@ public class Commands { command = event.getCommand(); String[] args = command.split(" "); diff --git a/patches/unapplied/server/0458-Fix-nerfed-slime-when-splitting.patch b/patches/unapplied/server/0458-Fix-nerfed-slime-when-splitting.patch deleted file mode 100644 index a32a88f5ad3e..000000000000 --- a/patches/unapplied/server/0458-Fix-nerfed-slime-when-splitting.patch +++ /dev/null @@ -1,18 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Mon, 24 Aug 2020 08:39:06 -0700 -Subject: [PATCH] Fix nerfed slime when splitting - - -diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java -index ef27b0af849f071f79271689783b7a557e6d660a..b54c30ba73b6ab069c0c7c1cd2b193090da79667 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/Slime.java -+++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java -@@ -254,6 +254,7 @@ public class Slime extends Mob implements Enemy { - entityslime.setPersistenceRequired(); - } - -+ entityslime.aware = this.aware; // Paper - Fix nerfed slime when splitting - entityslime.setCustomName(ichatbasecomponent); - entityslime.setNoAi(flag); - entityslime.setInvulnerable(this.isInvulnerable()); From 2810f50ca27ee3477a79628dc5d2295a0989cc8a Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Wed, 23 Oct 2024 19:46:06 +0200 Subject: [PATCH 023/119] 503 --- .../0464-Remove-stale-POIs.patch} | 4 +- .../0465-Fix-villager-boat-exploit.patch} | 4 +- .../0466-Add-sendOpLevel-API.patch} | 10 +-- ...istryAccess-for-managing-Registries.patch} | 90 +++++++++---------- .../0468-Add-StructuresLocateEvent.patch} | 2 +- ...-for-requiring-a-player-participant.patch} | 32 +++---- ...nent-with-empty-text-instead-of-thr.patch} | 4 +- ...471-Make-schedule-command-per-world.patch} | 8 +- ...472-Configurable-max-leash-distance.patch} | 8 +- .../0473-Add-BlockPreDispenseEvent.patch} | 8 +- ...4-Add-PlayerChangeBeaconEffectEvent.patch} | 4 +- ...e-for-always-placing-the-dragon-egg.patch} | 4 +- ...-PlayerStonecutterRecipeSelectEvent.patch} | 23 +++-- .../0477-Expand-EntityUnleashEvent.patch} | 35 ++++---- ...shield-blocking-on-dimension-change.patch} | 4 +- .../0479-Add-DragonEggFormEvent.patch} | 4 +- .../0480-Add-EntityMoveEvent.patch} | 22 ++--- ...isable-pathfinding-updates-on-block.patch} | 6 +- .../0482-Inline-shift-direction-fields.patch} | 10 +-- ...-adding-items-to-BlockDropItemEvent.patch} | 4 +- ...inThreadExecutor-to-BukkitScheduler.patch} | 2 +- ...entity-allow-attribute-registration.patch} | 8 +- ...ix-dead-slime-setSize-invincibility.patch} | 0 ...pes-should-return-an-immutable-list.patch} | 0 .../0488-Expose-Tracked-Players.patch} | 4 +- .../0489-Improve-ServerGUI.patch} | 0 ...490-fix-converting-txt-to-json-file.patch} | 10 +-- .../0491-Add-worldborder-events.patch} | 10 +-- .../0492-Add-PlayerNameEntityEvent.patch} | 4 +- .../0493-Add-recipe-to-cook-events.patch} | 20 ++--- .../0494-Add-Block-isValidTool.patch} | 2 +- ...using-signs-inside-spawn-protection.patch} | 11 ++- .../0496-Expand-world-key-API.patch} | 12 +-- ...ternative-constructor-for-Rotations.patch} | 0 ...d-item-when-player-has-disconnected.patch} | 4 +- ...elist-use-configurable-kick-message.patch} | 4 +- ...gnore-result-of-PlayerEditBookEvent.patch} | 4 +- .../0501-Expose-protocol-version.patch} | 2 +- ...ab-completions-for-brigadier-comman.patch} | 6 +- ...temConsumeEvent-cancelling-properly.patch} | 8 +- 40 files changed, 200 insertions(+), 197 deletions(-) rename patches/{unapplied/server/0468-Remove-stale-POIs.patch => server/0464-Remove-stale-POIs.patch} (83%) rename patches/{unapplied/server/0469-Fix-villager-boat-exploit.patch => server/0465-Fix-villager-boat-exploit.patch} (89%) rename patches/{unapplied/server/0470-Add-sendOpLevel-API.patch => server/0466-Add-sendOpLevel-API.patch} (85%) rename patches/{unapplied/server/0471-Add-RegistryAccess-for-managing-Registries.patch => server/0467-Add-RegistryAccess-for-managing-Registries.patch} (94%) rename patches/{unapplied/server/0472-Add-StructuresLocateEvent.patch => server/0468-Add-StructuresLocateEvent.patch} (96%) rename patches/{unapplied/server/0473-Collision-option-for-requiring-a-player-participant.patch => server/0469-Collision-option-for-requiring-a-player-participant.patch} (73%) rename patches/{unapplied/server/0474-Return-chat-component-with-empty-text-instead-of-thr.patch => server/0470-Return-chat-component-with-empty-text-instead-of-thr.patch} (87%) rename patches/{unapplied/server/0475-Make-schedule-command-per-world.patch => server/0471-Make-schedule-command-per-world.patch} (82%) rename patches/{unapplied/server/0476-Configurable-max-leash-distance.patch => server/0472-Configurable-max-leash-distance.patch} (83%) rename patches/{unapplied/server/0477-Add-BlockPreDispenseEvent.patch => server/0473-Add-BlockPreDispenseEvent.patch} (89%) rename patches/{unapplied/server/0478-Add-PlayerChangeBeaconEffectEvent.patch => server/0474-Add-PlayerChangeBeaconEffectEvent.patch} (94%) rename patches/{unapplied/server/0479-Add-toggle-for-always-placing-the-dragon-egg.patch => server/0475-Add-toggle-for-always-placing-the-dragon-egg.patch} (88%) rename patches/{unapplied/server/0480-Add-PlayerStonecutterRecipeSelectEvent.patch => server/0476-Add-PlayerStonecutterRecipeSelectEvent.patch} (68%) rename patches/{unapplied/server/0481-Expand-EntityUnleashEvent.patch => server/0477-Expand-EntityUnleashEvent.patch} (84%) rename patches/{unapplied/server/0482-Reset-shield-blocking-on-dimension-change.patch => server/0478-Reset-shield-blocking-on-dimension-change.patch} (86%) rename patches/{unapplied/server/0483-Add-DragonEggFormEvent.patch => server/0479-Add-DragonEggFormEvent.patch} (93%) rename patches/{unapplied/server/0484-Add-EntityMoveEvent.patch => server/0480-Add-EntityMoveEvent.patch} (80%) rename patches/{unapplied/server/0485-added-option-to-disable-pathfinding-updates-on-block.patch => server/0481-added-option-to-disable-pathfinding-updates-on-block.patch} (76%) rename patches/{unapplied/server/0486-Inline-shift-direction-fields.patch => server/0482-Inline-shift-direction-fields.patch} (84%) rename patches/{unapplied/server/0487-Allow-adding-items-to-BlockDropItemEvent.patch => server/0483-Allow-adding-items-to-BlockDropItemEvent.patch} (93%) rename patches/{unapplied/server/0488-Add-getMainThreadExecutor-to-BukkitScheduler.patch => server/0484-Add-getMainThreadExecutor-to-BukkitScheduler.patch} (92%) rename patches/{unapplied/server/0489-living-entity-allow-attribute-registration.patch => server/0485-living-entity-allow-attribute-registration.patch} (89%) rename patches/{unapplied/server/0490-fix-dead-slime-setSize-invincibility.patch => server/0486-fix-dead-slime-setSize-invincibility.patch} (100%) rename patches/{unapplied/server/0491-Merchant-getRecipes-should-return-an-immutable-list.patch => server/0487-Merchant-getRecipes-should-return-an-immutable-list.patch} (100%) rename patches/{unapplied/server/0492-Expose-Tracked-Players.patch => server/0488-Expose-Tracked-Players.patch} (89%) rename patches/{unapplied/server/0493-Improve-ServerGUI.patch => server/0489-Improve-ServerGUI.patch} (100%) rename patches/{unapplied/server/0494-fix-converting-txt-to-json-file.patch => server/0490-fix-converting-txt-to-json-file.patch} (90%) rename patches/{unapplied/server/0495-Add-worldborder-events.patch => server/0491-Add-worldborder-events.patch} (93%) rename patches/{unapplied/server/0496-Add-PlayerNameEntityEvent.patch => server/0492-Add-PlayerNameEntityEvent.patch} (91%) rename patches/{unapplied/server/0497-Add-recipe-to-cook-events.patch => server/0493-Add-recipe-to-cook-events.patch} (75%) rename patches/{unapplied/server/0498-Add-Block-isValidTool.patch => server/0494-Add-Block-isValidTool.patch} (88%) rename patches/{unapplied/server/0499-Allow-using-signs-inside-spawn-protection.patch => server/0495-Allow-using-signs-inside-spawn-protection.patch} (75%) rename patches/{unapplied/server/0500-Expand-world-key-API.patch => server/0496-Expand-world-key-API.patch} (88%) rename patches/{unapplied/server/0501-Add-fast-alternative-constructor-for-Rotations.patch => server/0497-Add-fast-alternative-constructor-for-Rotations.patch} (100%) rename patches/{unapplied/server/0502-Drop-carried-item-when-player-has-disconnected.patch => server/0498-Drop-carried-item-when-player-has-disconnected.patch} (89%) rename patches/{unapplied/server/0503-forced-whitelist-use-configurable-kick-message.patch => server/0499-forced-whitelist-use-configurable-kick-message.patch} (87%) rename patches/{unapplied/server/0504-Don-t-ignore-result-of-PlayerEditBookEvent.patch => server/0500-Don-t-ignore-result-of-PlayerEditBookEvent.patch} (87%) rename patches/{unapplied/server/0505-Expose-protocol-version.patch => server/0501-Expose-protocol-version.patch} (90%) rename patches/{unapplied/server/0506-Enhance-console-tab-completions-for-brigadier-comman.patch => server/0502-Enhance-console-tab-completions-for-brigadier-comman.patch} (99%) rename patches/{unapplied/server/0507-Fix-PlayerItemConsumeEvent-cancelling-properly.patch => server/0503-Fix-PlayerItemConsumeEvent-cancelling-properly.patch} (72%) diff --git a/patches/unapplied/server/0468-Remove-stale-POIs.patch b/patches/server/0464-Remove-stale-POIs.patch similarity index 83% rename from patches/unapplied/server/0468-Remove-stale-POIs.patch rename to patches/server/0464-Remove-stale-POIs.patch index 15a12eff2dd7..70792fa6b322 100644 --- a/patches/unapplied/server/0468-Remove-stale-POIs.patch +++ b/patches/server/0464-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 fdcc744cd210535067a69362411305e23f0e4273..85c83c900c33d139072d17e1850e95d86da324a7 100644 +index a3ce6feff0826dcfb2a11b0f6cd01a5368c2de3a..d62d6a345837e1b63c1a1393f18e367ac0ef4c30 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1743,6 +1743,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1805,6 +1805,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe }); optional1.ifPresent((holder) -> { this.getServer().execute(() -> { diff --git a/patches/unapplied/server/0469-Fix-villager-boat-exploit.patch b/patches/server/0465-Fix-villager-boat-exploit.patch similarity index 89% rename from patches/unapplied/server/0469-Fix-villager-boat-exploit.patch rename to patches/server/0465-Fix-villager-boat-exploit.patch index 5856a8c32b7f..f35fe8a11e7b 100644 --- a/patches/unapplied/server/0469-Fix-villager-boat-exploit.patch +++ b/patches/server/0465-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 98eb00a8ee23543714d424d3ff5ca19887d6db19..9436a9614dea81d14c4f77cc21ca91f85ca87152 100644 +index 4975b4222d52eddbb42e9c9cd08eef56859080c8..70b7871091ab9b64d2a5503620a71c3d5585c25d 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -595,6 +595,14 @@ public abstract class PlayerList { +@@ -545,6 +545,14 @@ public abstract class PlayerList { PlayerList.LOGGER.debug("Removing player mount"); entityplayer.stopRiding(); entity.getPassengersAndSelf().forEach((entity1) -> { diff --git a/patches/unapplied/server/0470-Add-sendOpLevel-API.patch b/patches/server/0466-Add-sendOpLevel-API.patch similarity index 85% rename from patches/unapplied/server/0470-Add-sendOpLevel-API.patch rename to patches/server/0466-Add-sendOpLevel-API.patch index 77f057bbd2aa..e37d133769b0 100644 --- a/patches/unapplied/server/0470-Add-sendOpLevel-API.patch +++ b/patches/server/0466-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 9436a9614dea81d14c4f77cc21ca91f85ca87152..9b94ca912f99a3a465f30130b24347fc9aca72ff 100644 +index 70b7871091ab9b64d2a5503620a71c3d5585c25d..7676dbe55b4bf6e0472dc0190c01e6ecfcbb464e 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1066,6 +1066,11 @@ public abstract class PlayerList { +@@ -1026,6 +1026,11 @@ public abstract class PlayerList { } private void sendPlayerPermissionLevel(ServerPlayer player, int permissionLevel) { @@ -20,7 +20,7 @@ index 9436a9614dea81d14c4f77cc21ca91f85ca87152..9b94ca912f99a3a465f30130b24347fc if (player.connection != null) { byte b0; -@@ -1080,8 +1085,10 @@ public abstract class PlayerList { +@@ -1040,8 +1045,10 @@ public abstract class PlayerList { player.connection.send(new ClientboundEntityEventPacket(player, b0)); } @@ -32,10 +32,10 @@ index 9436a9614dea81d14c4f77cc21ca91f85ca87152..9b94ca912f99a3a465f30130b24347fc 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 73fde8be0098238582fb3661ae67d4139be417dc..7de53f6750d478a052bc8ade6edac056565fe068 100644 +index 786b8c10a647d777b951b760e4c51eef057b2edd..678099cdcf418b9e3eafed965384e6dcdd9404e3 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -677,6 +677,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -690,6 +690,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end diff --git a/patches/unapplied/server/0471-Add-RegistryAccess-for-managing-Registries.patch b/patches/server/0467-Add-RegistryAccess-for-managing-Registries.patch similarity index 94% rename from patches/unapplied/server/0471-Add-RegistryAccess-for-managing-Registries.patch rename to patches/server/0467-Add-RegistryAccess-for-managing-Registries.patch index 54c9cc8744a3..2dfbc6b5603a 100644 --- a/patches/unapplied/server/0471-Add-RegistryAccess-for-managing-Registries.patch +++ b/patches/server/0467-Add-RegistryAccess-for-managing-Registries.patch @@ -707,22 +707,22 @@ index 0000000000000000000000000000000000000000..4396982af55872fafbfeaf8161ad6f39 +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; diff --git a/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java b/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java -index cbc1658e0df4070605a6b2fbe99167b3bc001223..44b7927081b476813505cab6b3a2da2ec2942c54 100644 +index 3f72e30b57fb2a4231e22a2234729408c1240af4..4638ba98dbbdb0f880337347be85a6e0fbed2191 100644 --- a/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java +++ b/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java -@@ -315,6 +315,7 @@ public class BuiltInRegistries { +@@ -323,6 +323,7 @@ public class BuiltInRegistries { ResourceKey> key, R registry, BuiltInRegistries.RegistryBootstrap initializer ) { - Bootstrap.checkBootstrapCalled(() -> "registry " + key); + Bootstrap.checkBootstrapCalled(() -> "registry " + key.location()); + io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(registry.key(), registry); // Paper - initialize API registry ResourceLocation resourceLocation = key.location(); LOADERS.put(resourceLocation, () -> initializer.run(registry)); WRITABLE_REGISTRY.register((ResourceKey)key, registry, RegistrationInfo.BUILT_IN); // Paper - decompile fix diff --git a/src/main/java/net/minecraft/resources/RegistryDataLoader.java b/src/main/java/net/minecraft/resources/RegistryDataLoader.java -index deaf62913850a0e0fdffd3d52fd383bcdda979af..abadf4abe08dc3bb6612b42cbb3f7df3ffa28ce9 100644 +index f4f1a99d53ffb953beb2a944f54d28fa6349fa29..144a6f5b0c53110804d6d099fe857d25f107d938 100644 --- a/src/main/java/net/minecraft/resources/RegistryDataLoader.java +++ b/src/main/java/net/minecraft/resources/RegistryDataLoader.java -@@ -299,6 +299,7 @@ public class RegistryDataLoader { +@@ -351,6 +351,7 @@ public class RegistryDataLoader { RegistryDataLoader.Loader create(Lifecycle lifecycle, Map, Exception> errors) { WritableRegistry writableRegistry = new MappedRegistry<>(this.key, lifecycle); @@ -731,19 +731,19 @@ index deaf62913850a0e0fdffd3d52fd383bcdda979af..abadf4abe08dc3bb6612b42cbb3f7df3 } diff --git a/src/main/java/net/minecraft/server/ReloadableServerRegistries.java b/src/main/java/net/minecraft/server/ReloadableServerRegistries.java -index 1dd22f11b7e2983a3069dea94c0f02b43ff1f736..397bdacab9517354875ebc0bc68d35059b3c318b 100644 +index 8e8d6214adbd21a221147f0fc0d91cd9c06a080c..6fddef967b6314ca0158f5bd4b8898670ea5e9ec 100644 --- a/src/main/java/net/minecraft/server/ReloadableServerRegistries.java +++ b/src/main/java/net/minecraft/server/ReloadableServerRegistries.java -@@ -60,6 +60,7 @@ public class ReloadableServerRegistries { - return CompletableFuture.supplyAsync( - () -> { - WritableRegistry writableRegistry = new MappedRegistry<>(type.registryKey(), Lifecycle.experimental()); -+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerReloadableRegistry(type.registryKey(), writableRegistry); // Paper - register reloadable registry - Map map = new HashMap<>(); - String string = Registries.elementsDirPath(type.registryKey()); - SimpleJsonResourceReloadListener.scanDirectory(resourceManager, string, GSON, map); +@@ -64,6 +64,7 @@ public class ReloadableServerRegistries { + ) { + return CompletableFuture.supplyAsync(() -> { + WritableRegistry writableRegistry = new MappedRegistry<>(type.registryKey(), Lifecycle.experimental()); ++ io.papermc.paper.registry.PaperRegistryAccess.instance().registerReloadableRegistry(type.registryKey(), writableRegistry); // Paper - register reloadable registry + Map map = new HashMap<>(); + String string = Registries.elementsDirPath(type.registryKey()); + SimpleJsonResourceReloadListener.scanDirectory(resourceManager, string, ops, type.codec(), map); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java -index 6216db1811565e0d25b0d63f579f0a5ba69876a7..3dbdfc2fb973c3c9aecc6582451071e8a939f5f0 100644 +index b4ed857f2437759b71b75d7ab36c986a2fd71dbc..09929f580164abcd1c04061d04c6aa992767e256 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java @@ -122,81 +122,12 @@ public class CraftRegistry implements Registry { @@ -759,64 +759,64 @@ index 6216db1811565e0d25b0d63f579f0a5ba69876a7..3dbdfc2fb973c3c9aecc6582451071e8 - */ - public static Registry createRegistry(Class bukkitClass, RegistryAccess registryHolder) { - if (bukkitClass == Enchantment.class) { -- return new CraftRegistry<>(Enchantment.class, registryHolder.registryOrThrow(Registries.ENCHANTMENT), CraftEnchantment::new, FieldRename.ENCHANTMENT_RENAME); +- return new CraftRegistry<>(Enchantment.class, registryHolder.lookupOrThrow(Registries.ENCHANTMENT), CraftEnchantment::new, FieldRename.ENCHANTMENT_RENAME); - } - if (bukkitClass == GameEvent.class) { -- return new CraftRegistry<>(GameEvent.class, registryHolder.registryOrThrow(Registries.GAME_EVENT), CraftGameEvent::new, FieldRename.NONE); +- return new CraftRegistry<>(GameEvent.class, registryHolder.lookupOrThrow(Registries.GAME_EVENT), CraftGameEvent::new, FieldRename.NONE); - } - if (bukkitClass == MusicInstrument.class) { -- return new CraftRegistry<>(MusicInstrument.class, registryHolder.registryOrThrow(Registries.INSTRUMENT), CraftMusicInstrument::new, FieldRename.NONE); +- return new CraftRegistry<>(MusicInstrument.class, registryHolder.lookupOrThrow(Registries.INSTRUMENT), CraftMusicInstrument::new, FieldRename.NONE); - } - if (bukkitClass == MenuType.class) { -- return new CraftRegistry<>(MenuType.class, registryHolder.registryOrThrow(Registries.MENU), CraftMenuType::new, FieldRename.NONE); +- return new CraftRegistry<>(MenuType.class, registryHolder.lookupOrThrow(Registries.MENU), CraftMenuType::new, FieldRename.NONE); - } - if (bukkitClass == PotionEffectType.class) { -- return new CraftRegistry<>(PotionEffectType.class, registryHolder.registryOrThrow(Registries.MOB_EFFECT), CraftPotionEffectType::new, FieldRename.NONE); +- return new CraftRegistry<>(PotionEffectType.class, registryHolder.lookupOrThrow(Registries.MOB_EFFECT), CraftPotionEffectType::new, FieldRename.NONE); - } - if (bukkitClass == Structure.class) { -- return new CraftRegistry<>(Structure.class, registryHolder.registryOrThrow(Registries.STRUCTURE), CraftStructure::new, FieldRename.NONE); +- return new CraftRegistry<>(Structure.class, registryHolder.lookupOrThrow(Registries.STRUCTURE), CraftStructure::new, FieldRename.NONE); - } - if (bukkitClass == StructureType.class) { -- return new CraftRegistry<>(StructureType.class, registryHolder.registryOrThrow(Registries.STRUCTURE_TYPE), CraftStructureType::new, FieldRename.NONE); +- return new CraftRegistry<>(StructureType.class, registryHolder.lookupOrThrow(Registries.STRUCTURE_TYPE), CraftStructureType::new, FieldRename.NONE); - } - if (bukkitClass == Villager.Type.class) { -- return new CraftRegistry<>(Villager.Type.class, registryHolder.registryOrThrow(Registries.VILLAGER_TYPE), CraftVillager.CraftType::new, FieldRename.NONE); +- return new CraftRegistry<>(Villager.Type.class, registryHolder.lookupOrThrow(Registries.VILLAGER_TYPE), CraftVillager.CraftType::new, FieldRename.NONE); - } - if (bukkitClass == Villager.Profession.class) { -- return new CraftRegistry<>(Villager.Profession.class, registryHolder.registryOrThrow(Registries.VILLAGER_PROFESSION), CraftVillager.CraftProfession::new, FieldRename.NONE); +- return new CraftRegistry<>(Villager.Profession.class, registryHolder.lookupOrThrow(Registries.VILLAGER_PROFESSION), CraftVillager.CraftProfession::new, FieldRename.NONE); - } - if (bukkitClass == TrimMaterial.class) { -- return new CraftRegistry<>(TrimMaterial.class, registryHolder.registryOrThrow(Registries.TRIM_MATERIAL), CraftTrimMaterial::new, FieldRename.NONE); +- return new CraftRegistry<>(TrimMaterial.class, registryHolder.lookupOrThrow(Registries.TRIM_MATERIAL), CraftTrimMaterial::new, FieldRename.NONE); - } - if (bukkitClass == TrimPattern.class) { -- return new CraftRegistry<>(TrimPattern.class, registryHolder.registryOrThrow(Registries.TRIM_PATTERN), CraftTrimPattern::new, FieldRename.NONE); +- return new CraftRegistry<>(TrimPattern.class, registryHolder.lookupOrThrow(Registries.TRIM_PATTERN), CraftTrimPattern::new, FieldRename.NONE); - } - if (bukkitClass == DamageType.class) { -- return new CraftRegistry<>(DamageType.class, registryHolder.registryOrThrow(Registries.DAMAGE_TYPE), CraftDamageType::new, FieldRename.NONE); +- return new CraftRegistry<>(DamageType.class, registryHolder.lookupOrThrow(Registries.DAMAGE_TYPE), CraftDamageType::new, FieldRename.NONE); - } - if (bukkitClass == JukeboxSong.class) { -- return new CraftRegistry<>(JukeboxSong.class, registryHolder.registryOrThrow(Registries.JUKEBOX_SONG), CraftJukeboxSong::new, FieldRename.NONE); +- return new CraftRegistry<>(JukeboxSong.class, registryHolder.lookupOrThrow(Registries.JUKEBOX_SONG), CraftJukeboxSong::new, FieldRename.NONE); - } - if (bukkitClass == Wolf.Variant.class) { -- return new CraftRegistry<>(Wolf.Variant.class, registryHolder.registryOrThrow(Registries.WOLF_VARIANT), CraftWolf.CraftVariant::new, FieldRename.NONE); +- return new CraftRegistry<>(Wolf.Variant.class, registryHolder.lookupOrThrow(Registries.WOLF_VARIANT), CraftWolf.CraftVariant::new, FieldRename.NONE); - } - if (bukkitClass == BlockType.class) { -- return new CraftRegistry<>(BlockType.class, registryHolder.registryOrThrow(Registries.BLOCK), CraftBlockType::new, FieldRename.NONE); +- return new CraftRegistry<>(BlockType.class, registryHolder.lookupOrThrow(Registries.BLOCK), CraftBlockType::new, FieldRename.NONE); - } - if (bukkitClass == ItemType.class) { -- return new CraftRegistry<>(ItemType.class, registryHolder.registryOrThrow(Registries.ITEM), CraftItemType::new, FieldRename.NONE); +- return new CraftRegistry<>(ItemType.class, registryHolder.lookupOrThrow(Registries.ITEM), CraftItemType::new, FieldRename.NONE); - } - if (bukkitClass == Frog.Variant.class) { -- return new CraftRegistry<>(Frog.Variant.class, registryHolder.registryOrThrow(Registries.FROG_VARIANT), CraftFrog.CraftVariant::new, FieldRename.NONE); +- return new CraftRegistry<>(Frog.Variant.class, registryHolder.lookupOrThrow(Registries.FROG_VARIANT), CraftFrog.CraftVariant::new, FieldRename.NONE); - } - if (bukkitClass == Cat.Type.class) { -- return new CraftRegistry<>(Cat.Type.class, registryHolder.registryOrThrow(Registries.CAT_VARIANT), CraftCat.CraftType::new, FieldRename.NONE); +- return new CraftRegistry<>(Cat.Type.class, registryHolder.lookupOrThrow(Registries.CAT_VARIANT), CraftCat.CraftType::new, FieldRename.NONE); - } - if (bukkitClass == MapCursor.Type.class) { -- return new CraftRegistry<>(MapCursor.Type.class, registryHolder.registryOrThrow(Registries.MAP_DECORATION_TYPE), CraftMapCursor.CraftType::new, FieldRename.NONE); +- return new CraftRegistry<>(MapCursor.Type.class, registryHolder.lookupOrThrow(Registries.MAP_DECORATION_TYPE), CraftMapCursor.CraftType::new, FieldRename.NONE); - } - if (bukkitClass == PatternType.class) { -- return new CraftRegistry<>(PatternType.class, registryHolder.registryOrThrow(Registries.BANNER_PATTERN), CraftPatternType::new, FieldRename.NONE); +- return new CraftRegistry<>(PatternType.class, registryHolder.lookupOrThrow(Registries.BANNER_PATTERN), CraftPatternType::new, FieldRename.NONE); - } - - return null; @@ -861,10 +861,10 @@ index 6216db1811565e0d25b0d63f579f0a5ba69876a7..3dbdfc2fb973c3c9aecc6582451071e8 @Override public B get(NamespacedKey namespacedKey) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 25bfb93568ea0a6c0b827c6d6a736f950981144e..f402ef662779e096ee354b9edd66cca785b85f33 100644 +index dd3940c2aacfa835b528a882f3ec5dd4d98bd59f..ee231d93d216571a45b11b49663b2ea91c47a1c7 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -281,7 +281,7 @@ public final class CraftServer implements Server { +@@ -284,7 +284,7 @@ public final class CraftServer implements Server { protected final DedicatedServer console; protected final DedicatedPlayerList playerList; private final Map worlds = new LinkedHashMap(); @@ -873,7 +873,7 @@ index 25bfb93568ea0a6c0b827c6d6a736f950981144e..f402ef662779e096ee354b9edd66cca7 private YamlConfiguration configuration; private YamlConfiguration commandsConfiguration; private final Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions())); -@@ -429,6 +429,7 @@ public final class CraftServer implements Server { +@@ -432,6 +432,7 @@ public final class CraftServer implements Server { } private void loadCompatibilities() { @@ -881,7 +881,7 @@ index 25bfb93568ea0a6c0b827c6d6a736f950981144e..f402ef662779e096ee354b9edd66cca7 ConfigurationSection compatibilities = this.configuration.getConfigurationSection("settings.compatibility"); if (compatibilities == null) { this.activeCompatibilities = Collections.emptySet(); -@@ -2728,7 +2729,7 @@ public final class CraftServer implements Server { +@@ -2745,7 +2746,7 @@ public final class CraftServer implements Server { @Override public Registry getRegistry(Class aClass) { @@ -891,7 +891,7 @@ index 25bfb93568ea0a6c0b827c6d6a736f950981144e..f402ef662779e096ee354b9edd66cca7 @Deprecated diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java b/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java -index 1f58b92c17d28e14621e8dc28042a5368f1f4a1f..ef80e6b4dff557daaab1b9fde4d8d40171017e6c 100644 +index c1023eff9f391c07b57e57450b756fe16299f723..b5e0023e431f9fb43c93a3f977144b03545322bb 100644 --- a/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java +++ b/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java @@ -51,11 +51,14 @@ public class FieldRename { @@ -1244,7 +1244,7 @@ index bbd5dd5b27937ddc3d8c57f2b604331495b0f311..626c3033e36897846fe84a77d05e2e91 CraftRegistry.setMinecraftRegistry(RegistryHelper.getRegistry()); } diff --git a/src/test/java/org/bukkit/support/provider/RegistriesArgumentProvider.java b/src/test/java/org/bukkit/support/provider/RegistriesArgumentProvider.java -index 185f219b23ac57e15f8d0167b0077b7103a2f3f9..f4ba15a1b4b43822bd81b513af56c6667237c327 100644 +index 47f3b79d76399ff2185ea753260a702441ecadf5..eb3974690fb12ffe678522ed47e0f730712db016 100644 --- a/src/test/java/org/bukkit/support/provider/RegistriesArgumentProvider.java +++ b/src/test/java/org/bukkit/support/provider/RegistriesArgumentProvider.java @@ -1,6 +1,7 @@ @@ -1269,8 +1269,8 @@ index 185f219b23ac57e15f8d0167b0077b7103a2f3f9..f4ba15a1b4b43822bd81b513af56c666 - register(StructureType.class, Registries.STRUCTURE_TYPE, CraftStructureType.class, net.minecraft.world.level.levelgen.structure.StructureType.class); - register(Villager.Type.class, Registries.VILLAGER_TYPE, CraftVillager.CraftType.class, VillagerType.class); - register(Villager.Profession.class, Registries.VILLAGER_PROFESSION, CraftVillager.CraftProfession.class, VillagerProfession.class); -- register(TrimMaterial.class, Registries.TRIM_MATERIAL, CraftTrimMaterial.class, net.minecraft.world.item.armortrim.TrimMaterial.class); -- register(TrimPattern.class, Registries.TRIM_PATTERN, CraftTrimPattern.class, net.minecraft.world.item.armortrim.TrimPattern.class); +- register(TrimMaterial.class, Registries.TRIM_MATERIAL, CraftTrimMaterial.class, net.minecraft.world.item.equipment.trim.TrimMaterial.class); +- register(TrimPattern.class, Registries.TRIM_PATTERN, CraftTrimPattern.class, net.minecraft.world.item.equipment.trim.TrimPattern.class); - register(DamageType.class, Registries.DAMAGE_TYPE, CraftDamageType.class, net.minecraft.world.damagesource.DamageType.class); - register(JukeboxSong.class, Registries.JUKEBOX_SONG, CraftJukeboxSong.class, net.minecraft.world.item.JukeboxSong.class); - register(Wolf.Variant.class, Registries.WOLF_VARIANT, CraftWolf.CraftVariant.class, WolfVariant.class); @@ -1290,8 +1290,8 @@ index 185f219b23ac57e15f8d0167b0077b7103a2f3f9..f4ba15a1b4b43822bd81b513af56c666 + register(RegistryKey.STRUCTURE_TYPE, StructureType.class, Registries.STRUCTURE_TYPE, CraftStructureType.class, net.minecraft.world.level.levelgen.structure.StructureType.class); + register(RegistryKey.VILLAGER_TYPE, Villager.Type.class, Registries.VILLAGER_TYPE, CraftVillager.CraftType.class, VillagerType.class); + register(RegistryKey.VILLAGER_PROFESSION, Villager.Profession.class, Registries.VILLAGER_PROFESSION, CraftVillager.CraftProfession.class, VillagerProfession.class); -+ register(RegistryKey.TRIM_MATERIAL, TrimMaterial.class, Registries.TRIM_MATERIAL, CraftTrimMaterial.class, net.minecraft.world.item.armortrim.TrimMaterial.class); -+ register(RegistryKey.TRIM_PATTERN, TrimPattern.class, Registries.TRIM_PATTERN, CraftTrimPattern.class, net.minecraft.world.item.armortrim.TrimPattern.class); ++ register(RegistryKey.TRIM_MATERIAL, TrimMaterial.class, Registries.TRIM_MATERIAL, CraftTrimMaterial.class, net.minecraft.world.item.equipment.trim.TrimMaterial.class); ++ register(RegistryKey.TRIM_PATTERN, TrimPattern.class, Registries.TRIM_PATTERN, CraftTrimPattern.class, net.minecraft.world.item.equipment.trim.TrimPattern.class); + register(RegistryKey.DAMAGE_TYPE, DamageType.class, Registries.DAMAGE_TYPE, CraftDamageType.class, net.minecraft.world.damagesource.DamageType.class); + register(RegistryKey.JUKEBOX_SONG, JukeboxSong.class, Registries.JUKEBOX_SONG, CraftJukeboxSong.class, net.minecraft.world.item.JukeboxSong.class); + register(RegistryKey.WOLF_VARIANT, Wolf.Variant.class, Registries.WOLF_VARIANT, CraftWolf.CraftVariant.class, WolfVariant.class); diff --git a/patches/unapplied/server/0472-Add-StructuresLocateEvent.patch b/patches/server/0468-Add-StructuresLocateEvent.patch similarity index 96% rename from patches/unapplied/server/0472-Add-StructuresLocateEvent.patch rename to patches/server/0468-Add-StructuresLocateEvent.patch index d8c688e2ae97..5312adefad7b 100644 --- a/patches/unapplied/server/0472-Add-StructuresLocateEvent.patch +++ b/patches/server/0468-Add-StructuresLocateEvent.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add StructuresLocateEvent Co-authored-by: Jake Potrebic diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index 0a779632c9d11496fcfc147870fba2699d9cc274..5adc1952504b26772116b55a5144b7704136edfa 100644 +index 115deba41ec48143570489e8494785a3a48cd789..fd2dd6d25b8d6f3066c60a7f30a58a72cb418b85 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -126,6 +126,24 @@ public abstract class ChunkGenerator { diff --git a/patches/unapplied/server/0473-Collision-option-for-requiring-a-player-participant.patch b/patches/server/0469-Collision-option-for-requiring-a-player-participant.patch similarity index 73% rename from patches/unapplied/server/0473-Collision-option-for-requiring-a-player-participant.patch rename to patches/server/0469-Collision-option-for-requiring-a-player-participant.patch index 28b12f77f8a2..a1b916f2ada2 100644 --- a/patches/unapplied/server/0473-Collision-option-for-requiring-a-player-participant.patch +++ b/patches/server/0469-Collision-option-for-requiring-a-player-participant.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Collision option for requiring a player participant diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index bed376337035545e7ec677f2f7fe3372a3c9ea25..7d131f3b3f5739468aa3115e97ed28b6bfeca33d 100644 +index ad34a525f54a157140323a26752a420a8e348a55..1d2f0f8756addf0db7356b47ea8a1eddd2c4503d 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -1936,6 +1936,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2024,6 +2024,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public void push(Entity entity) { if (!this.isPassengerOfSameVehicle(entity)) { if (!entity.noPhysics && !this.noPhysics) { @@ -16,11 +16,23 @@ index bed376337035545e7ec677f2f7fe3372a3c9ea25..7d131f3b3f5739468aa3115e97ed28b6 double d0 = entity.getX() - this.getX(); double d1 = entity.getZ() - this.getZ(); double d2 = Mth.absMax(d0, d1); +diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java +index a4eab65c280e493889621e62d8fc94158b930c96..57ea01469ddd180a0c2121cce2807bcccf93bf48 100644 +--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java ++++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java +@@ -196,6 +196,7 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable { + + @Override + public void push(Entity entity) { ++ if (!this.level().paperConfig().collisions.allowVehicleCollisions && this.level().paperConfig().collisions.onlyPlayersCollide && !(entity instanceof Player)) return; // Paper - Collision option for requiring a player participant + if (entity instanceof AbstractBoat) { + if (entity.getBoundingBox().minY < this.getBoundingBox().maxY) { + // CraftBukkit start diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java -index 4d8c14d3a42f3e4b963cf5f8fa764df79813912b..93634fb01962ca7a35026e3c365f2a7f6b258a39 100644 +index 50c0055d80735313c280821991bd2a76e427f082..ee7350e19a86ffa115e4bce6b186a2422951e89b 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java -@@ -799,6 +799,7 @@ public abstract class AbstractMinecart extends VehicleEntity { +@@ -562,6 +562,7 @@ public abstract class AbstractMinecart extends VehicleEntity { public void push(Entity entity) { if (!this.level().isClientSide) { if (!entity.noPhysics && !this.noPhysics) { @@ -28,15 +40,3 @@ index 4d8c14d3a42f3e4b963cf5f8fa764df79813912b..93634fb01962ca7a35026e3c365f2a7f if (!this.hasPassenger(entity)) { // CraftBukkit start VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent((Vehicle) this.getBukkitEntity(), entity.getBukkitEntity()); -diff --git a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java -index 2cb535639bff0e867c1b1e845fee6e34bb237044..907f751c859855484151fb5d607acee2f2a35076 100644 ---- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java -+++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java -@@ -204,6 +204,7 @@ public class Boat extends VehicleEntity implements Leashable, VariantHolder SUGGEST_SCHEDULE = (commandcontext, suggestionsbuilder) -> { - return SharedSuggestionProvider.suggest((Iterable) ((CommandSourceStack) commandcontext.getSource()).getServer().getWorldData().overworldData().getScheduledEvents().getEventsIds(), suggestionsbuilder); + return SharedSuggestionProvider.suggest((Iterable) ((net.minecraft.commands.CommandSourceStack) commandcontext.getSource()).getLevel().serverLevelData.getScheduledEvents().getEventsIds(), suggestionsbuilder); // Paper - Make schedule command per-world }; public ScheduleCommand() {} -@@ -85,7 +85,7 @@ public class ScheduleCommand { +@@ -93,7 +93,7 @@ public class ScheduleCommand { } private static int remove(CommandSourceStack source, String eventName) throws CommandSyntaxException { diff --git a/patches/unapplied/server/0476-Configurable-max-leash-distance.patch b/patches/server/0472-Configurable-max-leash-distance.patch similarity index 83% rename from patches/unapplied/server/0476-Configurable-max-leash-distance.patch rename to patches/server/0472-Configurable-max-leash-distance.patch index d2f544737b2f..625e1c156b27 100644 --- a/patches/unapplied/server/0476-Configurable-max-leash-distance.patch +++ b/patches/server/0472-Configurable-max-leash-distance.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Configurable max leash distance diff --git a/src/main/java/net/minecraft/world/entity/Leashable.java b/src/main/java/net/minecraft/world/entity/Leashable.java -index 1f2d04a456c383815b0c5ef331471593556fd128..5c51dd5229689cba459655d488aee59bd159a414 100644 +index e53c3b53ea9c0932f0f049bf76f1f6de0432506a..dc39ecc3e1aada638337d31bfe68b400c6454af7 100644 --- a/src/main/java/net/minecraft/world/entity/Leashable.java +++ b/src/main/java/net/minecraft/world/entity/Leashable.java -@@ -179,7 +179,7 @@ public interface Leashable { +@@ -180,7 +180,7 @@ public interface Leashable { return; } @@ -18,10 +18,10 @@ index 1f2d04a456c383815b0c5ef331471593556fd128..5c51dd5229689cba459655d488aee59b } else if ((double) f > 6.0D) { ((Leashable) entity).elasticRangeLeashBehaviour(entity1, f); diff --git a/src/main/java/net/minecraft/world/entity/TamableAnimal.java b/src/main/java/net/minecraft/world/entity/TamableAnimal.java -index f2d311a5450eb684603580bbf7e9e7fc73fc2f5c..bf2c9134c7d9d5926add36b55e3cfea79e8c8243 100644 +index f239ab65d914ee9ec819e112f0a0466a06a77929..d2785628368b65854b6e1f35005c478d490a2f8c 100644 --- a/src/main/java/net/minecraft/world/entity/TamableAnimal.java +++ b/src/main/java/net/minecraft/world/entity/TamableAnimal.java -@@ -97,7 +97,7 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity { +@@ -98,7 +98,7 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity { @Override public boolean handleLeashAtDistance(Entity leashHolder, float distance) { if (this.isInSittingPose()) { diff --git a/patches/unapplied/server/0477-Add-BlockPreDispenseEvent.patch b/patches/server/0473-Add-BlockPreDispenseEvent.patch similarity index 89% rename from patches/unapplied/server/0477-Add-BlockPreDispenseEvent.patch rename to patches/server/0473-Add-BlockPreDispenseEvent.patch index 6e9bb3b21683..ae0c60a3b459 100644 --- a/patches/unapplied/server/0477-Add-BlockPreDispenseEvent.patch +++ b/patches/server/0473-Add-BlockPreDispenseEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add BlockPreDispenseEvent diff --git a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java -index 94bcbaf7daf7dfe566f508d1170a433930d9d49a..f6edfea463b3725d3a79aca38825e86dbf82175c 100644 +index f4853a5ff8a45efcda2d7781c1fa897c47d8ea46..a02f24448b002824b068278fa427003008c0d0f1 100644 --- a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java -@@ -110,6 +110,7 @@ public class DispenserBlock extends BaseEntityBlock { +@@ -107,6 +107,7 @@ public class DispenserBlock extends BaseEntityBlock { DispenseItemBehavior idispensebehavior = this.getDispenseMethod(world, itemstack); if (idispensebehavior != DispenseItemBehavior.NOOP) { @@ -29,10 +29,10 @@ index 91b514967405115f22edf4255775361a672e5c2f..ddecf443df3679e3098eb54edd19585a } else { // CraftBukkit start - Fire event when pushing items into other inventories diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 9e67dc35ea12149265517b951a96828460b2ca67..251b605396b77b0c449972c1da75978f57587e1a 100644 +index 4d7ac961b35b747ba5369ec1bdb6a9d78281f5d7..12aeb922c8a53eff9ba8e2c765d87df497611362 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -2134,5 +2134,11 @@ public class CraftEventFactory { +@@ -2132,5 +2132,11 @@ populateFields(victim, event); // Paper - make cancellable io.papermc.paper.event.block.BlockFailedDispenseEvent event = new io.papermc.paper.event.block.BlockFailedDispenseEvent(block); return event.callEvent(); } diff --git a/patches/unapplied/server/0478-Add-PlayerChangeBeaconEffectEvent.patch b/patches/server/0474-Add-PlayerChangeBeaconEffectEvent.patch similarity index 94% rename from patches/unapplied/server/0478-Add-PlayerChangeBeaconEffectEvent.patch rename to patches/server/0474-Add-PlayerChangeBeaconEffectEvent.patch index 1903c21ba88d..0b8263f96e46 100644 --- a/patches/unapplied/server/0478-Add-PlayerChangeBeaconEffectEvent.patch +++ b/patches/server/0474-Add-PlayerChangeBeaconEffectEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerChangeBeaconEffectEvent diff --git a/src/main/java/net/minecraft/world/inventory/BeaconMenu.java b/src/main/java/net/minecraft/world/inventory/BeaconMenu.java -index 7c4d2c184d9a1e4a1856e6771d39db384381e300..396559c281eee9e8c677cb222721414e8d9e12a2 100644 +index a191cef8037d94c7e93f79b86fc26ebefae95d8f..cad0b581c992edc5cd312a727695a443e26e96d8 100644 --- a/src/main/java/net/minecraft/world/inventory/BeaconMenu.java +++ b/src/main/java/net/minecraft/world/inventory/BeaconMenu.java -@@ -171,12 +171,25 @@ public class BeaconMenu extends AbstractContainerMenu { +@@ -157,12 +157,25 @@ public class BeaconMenu extends AbstractContainerMenu { return BeaconMenu.decodeEffect(this.beaconData.get(2)); } diff --git a/patches/unapplied/server/0479-Add-toggle-for-always-placing-the-dragon-egg.patch b/patches/server/0475-Add-toggle-for-always-placing-the-dragon-egg.patch similarity index 88% rename from patches/unapplied/server/0479-Add-toggle-for-always-placing-the-dragon-egg.patch rename to patches/server/0475-Add-toggle-for-always-placing-the-dragon-egg.patch index ccbab4766ec2..0b28271dd1b2 100644 --- a/patches/unapplied/server/0479-Add-toggle-for-always-placing-the-dragon-egg.patch +++ b/patches/server/0475-Add-toggle-for-always-placing-the-dragon-egg.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add toggle for always placing the dragon egg diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -index d6deedb96583c19eeb27e671289c4edc8a9245b4..4f3fdc6ea0cafd61f778edb6a967bd0eb00abdb9 100644 +index 323fbf684b7062c1b9084f1718538a3b3414d5bf..0e1eceb2b83aaafccbb5d58cf5098cfbc6f25a54 100644 --- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java +++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -@@ -409,7 +409,7 @@ public class EndDragonFight { +@@ -410,7 +410,7 @@ public class EndDragonFight { this.dragonEvent.setVisible(false); this.spawnExitPortal(true); this.spawnNewGateway(); diff --git a/patches/unapplied/server/0480-Add-PlayerStonecutterRecipeSelectEvent.patch b/patches/server/0476-Add-PlayerStonecutterRecipeSelectEvent.patch similarity index 68% rename from patches/unapplied/server/0480-Add-PlayerStonecutterRecipeSelectEvent.patch rename to patches/server/0476-Add-PlayerStonecutterRecipeSelectEvent.patch index 0c96d8fa15f5..8a5e50313f5b 100644 --- a/patches/unapplied/server/0480-Add-PlayerStonecutterRecipeSelectEvent.patch +++ b/patches/server/0476-Add-PlayerStonecutterRecipeSelectEvent.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add PlayerStonecutterRecipeSelectEvent Co-Authored-By: MiniDigger diff --git a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java -index 5b4f03128499b0c1a4b8c5f5ccd17e4bdb391e81..37e75c02c374314372630f4bda0b92519809f2a4 100644 +index 97837d1baf6b929a50e5562ef466050e70c2c8b1..a93870952e2ef674028b8a20aa52a685c743e7ea 100644 --- a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java +++ b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java @@ -64,7 +64,7 @@ public class StonecutterMenu extends AbstractContainerMenu { @@ -15,29 +15,33 @@ index 5b4f03128499b0c1a4b8c5f5ccd17e4bdb391e81..37e75c02c374314372630f4bda0b9251 super(MenuType.STONECUTTER, syncId); - this.selectedRecipeIndex = DataSlot.standalone(); + this.selectedRecipeIndex = DataSlot.shared(new int[1], 0); // Paper - Add PlayerStonecutterRecipeSelectEvent - this.recipes = Lists.newArrayList(); + this.recipesForInput = SelectableRecipe.SingleInputSet.empty(); this.input = ItemStack.EMPTY; this.slotUpdateListener = () -> { -@@ -162,7 +162,30 @@ public class StonecutterMenu extends AbstractContainerMenu { +@@ -150,8 +150,34 @@ public class StonecutterMenu extends AbstractContainerMenu { @Override public boolean clickMenuButton(net.minecraft.world.entity.player.Player player, int id) { if (this.isValidRecipeIndex(id)) { - this.selectedRecipeIndex.set(id); +- this.setupResultSlot(id); + // Paper start - Add PlayerStonecutterRecipeSelectEvent + int recipeIndex = id; + this.selectedRecipeIndex.set(recipeIndex); + this.selectedRecipeIndex.checkAndClearUpdateFlag(); // mark as changed -+ if (this.isValidRecipeIndex(id)) { -+ io.papermc.paper.event.player.PlayerStonecutterRecipeSelectEvent event = new io.papermc.paper.event.player.PlayerStonecutterRecipeSelectEvent((Player) player.getBukkitEntity(), (org.bukkit.inventory.StonecutterInventory) getBukkitView().getTopInventory(), (org.bukkit.inventory.StonecuttingRecipe) this.getRecipes().get(id).toBukkitRecipe()); ++ paperEventBlock: if (this.isValidRecipeIndex(id)) { ++ final Optional> recipe = this.recipesForInput.entries().get(id).recipe().recipe(); ++ if (recipe.isEmpty()) break paperEventBlock; // The recipe selected does not have an actual server recipe (presumably its the empty one). Cannot call the event, just break. ++ ++ io.papermc.paper.event.player.PlayerStonecutterRecipeSelectEvent event = new io.papermc.paper.event.player.PlayerStonecutterRecipeSelectEvent((Player) player.getBukkitEntity(), getBukkitView().getTopInventory(), (org.bukkit.inventory.StonecuttingRecipe) recipe.get().toBukkitRecipe()); + if (!event.callEvent()) { + player.containerMenu.sendAllDataToRemote(); + return false; + } + + net.minecraft.resources.ResourceLocation key = org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(event.getStonecuttingRecipe().getKey()); -+ if (!this.getRecipes().get(recipeIndex).id().equals(key)) { // If the recipe did NOT stay the same -+ for (int newRecipeIndex = 0; newRecipeIndex < this.getRecipes().size(); newRecipeIndex++) { -+ if (this.getRecipes().get(newRecipeIndex).id().equals(key)) { ++ if (!recipe.get().id().location().equals(key)) { // If the recipe did NOT stay the same ++ for (int newRecipeIndex = 0; newRecipeIndex < this.recipesForInput.entries().size(); newRecipeIndex++) { ++ if (this.recipesForInput.entries().get(newRecipeIndex).recipe().recipe().filter(r -> r.id().location().equals(key)).isPresent()) { + recipeIndex = newRecipeIndex; + break; + } @@ -46,7 +50,8 @@ index 5b4f03128499b0c1a4b8c5f5ccd17e4bdb391e81..37e75c02c374314372630f4bda0b9251 + } + player.containerMenu.sendAllDataToRemote(); + this.selectedRecipeIndex.set(recipeIndex); // set new index, so that listeners can read it ++ this.setupResultSlot(recipeIndex); + // Paper end - Add PlayerStonecutterRecipeSelectEvent - this.setupResultSlot(); } + return true; diff --git a/patches/unapplied/server/0481-Expand-EntityUnleashEvent.patch b/patches/server/0477-Expand-EntityUnleashEvent.patch similarity index 84% rename from patches/unapplied/server/0481-Expand-EntityUnleashEvent.patch rename to patches/server/0477-Expand-EntityUnleashEvent.patch index 39bfff38111e..fceff6d94abc 100644 --- a/patches/unapplied/server/0481-Expand-EntityUnleashEvent.patch +++ b/patches/server/0477-Expand-EntityUnleashEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Expand EntityUnleashEvent diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 7d131f3b3f5739468aa3115e97ed28b6bfeca33d..da184893d617311a43f9ce176a965f8417a2876d 100644 +index 1d2f0f8756addf0db7356b47ea8a1eddd2c4503d..42004784a5421bd27d0a4a2bf1c17d14341fc5a4 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -2574,12 +2574,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2689,12 +2689,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess if (leashable.getLeashHolder() == player) { if (!this.level().isClientSide()) { // CraftBukkit start - fire PlayerUnleashEntityEvent @@ -26,7 +26,7 @@ index 7d131f3b3f5739468aa3115e97ed28b6bfeca33d..da184893d617311a43f9ce176a965f84 this.gameEvent(GameEvent.ENTITY_INTERACT, player); } -@@ -3449,9 +3452,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3659,9 +3662,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess protected void removeAfterChangingDimensions() { this.setRemoved(Entity.RemovalReason.CHANGED_DIMENSION, null); // CraftBukkit - add Bukkit remove cause @@ -43,24 +43,23 @@ index 7d131f3b3f5739468aa3115e97ed28b6bfeca33d..da184893d617311a43f9ce176a965f84 } diff --git a/src/main/java/net/minecraft/world/entity/Leashable.java b/src/main/java/net/minecraft/world/entity/Leashable.java -index 5c51dd5229689cba459655d488aee59bd159a414..e7535f15be3cc1537aafee53779ccfb4f21d1f38 100644 +index dc39ecc3e1aada638337d31bfe68b400c6454af7..1a6448cccf79a94013f9f44c3067d91da3da1f7e 100644 --- a/src/main/java/net/minecraft/world/entity/Leashable.java +++ b/src/main/java/net/minecraft/world/entity/Leashable.java -@@ -166,8 +166,11 @@ public interface Leashable { +@@ -167,8 +167,11 @@ public interface Leashable { if (leashable_a != null && leashable_a.leashHolder != null) { if (!entity.isAlive() || !leashable_a.leashHolder.isAlive()) { -- entity.level().getCraftServer().getPluginManager().callEvent(new EntityUnleashEvent(entity.getBukkitEntity(), (!entity.isAlive()) ? UnleashReason.PLAYER_UNLEASH : UnleashReason.HOLDER_GONE)); // CraftBukkit -- Leashable.dropLeash(entity, true, !entity.pluginRemoved); // CraftBukkit - SPIGOT-7487: Don't drop leash, when the holder was removed by a plugin +- world.getCraftServer().getPluginManager().callEvent(new EntityUnleashEvent(entity.getBukkitEntity(), (!entity.isAlive()) ? UnleashReason.PLAYER_UNLEASH : UnleashReason.HOLDER_GONE)); // CraftBukkit + // Paper start - Expand EntityUnleashEvent -+ final EntityUnleashEvent event = new EntityUnleashEvent(entity.getBukkitEntity(), (!entity.isAlive()) ? UnleashReason.PLAYER_UNLEASH : UnleashReason.HOLDER_GONE, !entity.pluginRemoved); ++ final EntityUnleashEvent event = new EntityUnleashEvent(entity.getBukkitEntity(), (!entity.isAlive()) ? UnleashReason.PLAYER_UNLEASH : UnleashReason.HOLDER_GONE, world.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS) && !entity.pluginRemoved); + event.callEvent(); -+ Leashable.dropLeash(entity, true, event.isDropLeash()); // CraftBukkit - SPIGOT-7487: Don't drop leash, when the holder was removed by a plugin + Leashable.dropLeash(entity, true, world.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS) && !entity.pluginRemoved); // CraftBukkit - SPIGOT-7487: Don't drop leash, when the holder was removed by a plugin + // Paper end - Expand EntityUnleashEvent } Entity entity1 = ((Leashable) entity).getLeashHolder(); -@@ -198,11 +201,16 @@ public interface Leashable { +@@ -199,11 +202,16 @@ public interface Leashable { default void leashTooFarBehaviour() { // CraftBukkit start @@ -80,10 +79,10 @@ index 5c51dd5229689cba459655d488aee59bd159a414..e7535f15be3cc1537aafee53779ccfb4 default void closeRangeLeashBehaviour(Entity entity) {} diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index b46572f6e3b52f498b395d3b8c5def2aa799ff03..e87360e21e6eb7b0161c34a3ac6cb83d18bcd1e8 100644 +index a8ab3c03a6f96658ce2a3f5758225954a36de6a9..ac7a52e77fd2fcbe9f95709b95ba54f8c2a6514b 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -1621,8 +1621,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -1613,8 +1613,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab boolean flag1 = super.startRiding(entity, force); if (flag1 && this.isLeashed()) { @@ -98,10 +97,10 @@ index b46572f6e3b52f498b395d3b8c5def2aa799ff03..e87360e21e6eb7b0161c34a3ac6cb83d return flag1; diff --git a/src/main/java/net/minecraft/world/entity/TamableAnimal.java b/src/main/java/net/minecraft/world/entity/TamableAnimal.java -index bf2c9134c7d9d5926add36b55e3cfea79e8c8243..7b7bc1a205dfacbe5709011b6b6799e75af9e4cc 100644 +index d2785628368b65854b6e1f35005c478d490a2f8c..cd565d1a8dab8d45196e4d29cab3d93a3ca619eb 100644 --- a/src/main/java/net/minecraft/world/entity/TamableAnimal.java +++ b/src/main/java/net/minecraft/world/entity/TamableAnimal.java -@@ -98,7 +98,11 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity { +@@ -99,7 +99,11 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity { public boolean handleLeashAtDistance(Entity leashHolder, float distance) { if (this.isInSittingPose()) { if (distance > (float) this.level().paperConfig().misc.maxLeashDistance.or(Leashable.LEASH_TOO_FAR_DIST)) { // Paper - Configurable max leash distance @@ -115,10 +114,10 @@ index bf2c9134c7d9d5926add36b55e3cfea79e8c8243..7b7bc1a205dfacbe5709011b6b6799e7 return false; diff --git a/src/main/java/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java b/src/main/java/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java -index 3c0af74ed65610b1d5e3b72fdcf28c5a3423f0da..01173fc7177d78588978e087e63efda0b0527c2f 100644 +index 4b44830ef5d08887274ebb39e2780606fe3a76b4..d3a7953a3f42a0020342845e9107c6991637b050 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java +++ b/src/main/java/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java -@@ -118,13 +118,18 @@ public class LeashFenceKnotEntity extends BlockAttachedEntity { +@@ -119,13 +119,18 @@ public class LeashFenceKnotEntity extends BlockAttachedEntity { if (leashable1.isLeashed() && leashable1.getLeashHolder() == this) { // CraftBukkit start @@ -140,10 +139,10 @@ index 3c0af74ed65610b1d5e3b72fdcf28c5a3423f0da..01173fc7177d78588978e087e63efda0 flag1 = true; } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 251b605396b77b0c449972c1da75978f57587e1a..c48a9026c4db2005b67c5f70e9e1fa95b7820bc0 100644 +index 12aeb922c8a53eff9ba8e2c765d87df497611362..cee72eb02ebba4f50a117876351b8f516ba12057 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1598,8 +1598,10 @@ public class CraftEventFactory { +@@ -1596,8 +1596,10 @@ populateFields(victim, event); // Paper - make cancellable Bukkit.getPluginManager().callEvent(new PlayerRecipeBookSettingsChangeEvent(player.getBukkitEntity(), bukkitType, open, filter)); } diff --git a/patches/unapplied/server/0482-Reset-shield-blocking-on-dimension-change.patch b/patches/server/0478-Reset-shield-blocking-on-dimension-change.patch similarity index 86% rename from patches/unapplied/server/0482-Reset-shield-blocking-on-dimension-change.patch rename to patches/server/0478-Reset-shield-blocking-on-dimension-change.patch index f0f37986b6c8..c1bc7de4e19d 100644 --- a/patches/unapplied/server/0482-Reset-shield-blocking-on-dimension-change.patch +++ b/patches/server/0478-Reset-shield-blocking-on-dimension-change.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Reset shield blocking on dimension change diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 2ea613f818403f8e8ece4b36891738139345cf89..fffd3ae6c4fc0b86057cd915bb4f0987f41a64d0 100644 +index 0ae490bb9b4cd781876054d0824c5392060208eb..3a2a4f6bc1de45c0dc2020357ee308064666f8d5 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1349,6 +1349,11 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1613,6 +1613,11 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent(this.getBukkitEntity(), worldserver1.getWorld()); this.level().getCraftServer().getPluginManager().callEvent(changeEvent); // CraftBukkit end diff --git a/patches/unapplied/server/0483-Add-DragonEggFormEvent.patch b/patches/server/0479-Add-DragonEggFormEvent.patch similarity index 93% rename from patches/unapplied/server/0483-Add-DragonEggFormEvent.patch rename to patches/server/0479-Add-DragonEggFormEvent.patch index 8a1ea595343e..34506b3c79d0 100644 --- a/patches/unapplied/server/0483-Add-DragonEggFormEvent.patch +++ b/patches/server/0479-Add-DragonEggFormEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add DragonEggFormEvent diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -index 4f3fdc6ea0cafd61f778edb6a967bd0eb00abdb9..460744ec3a1abe9a2d9d16c2ec521c52c7f8db95 100644 +index 0e1eceb2b83aaafccbb5d58cf5098cfbc6f25a54..3d1a49d865e17a61ff74c6fe0efbd908447ee730 100644 --- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java +++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -@@ -409,8 +409,22 @@ public class EndDragonFight { +@@ -410,8 +410,22 @@ public class EndDragonFight { this.dragonEvent.setVisible(false); this.spawnExitPortal(true); this.spawnNewGateway(); diff --git a/patches/unapplied/server/0484-Add-EntityMoveEvent.patch b/patches/server/0480-Add-EntityMoveEvent.patch similarity index 80% rename from patches/unapplied/server/0484-Add-EntityMoveEvent.patch rename to patches/server/0480-Add-EntityMoveEvent.patch index 9b7d66dfba07..7eb0eacb2e9d 100644 --- a/patches/unapplied/server/0484-Add-EntityMoveEvent.patch +++ b/patches/server/0480-Add-EntityMoveEvent.patch @@ -5,22 +5,22 @@ Subject: [PATCH] Add EntityMoveEvent diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 39ce74bc3fbb282f56028273d53f980171bdb464..43b28b56c7949f95af5b7e99b04b93ed711d8880 100644 +index 058719f8b768b5a1227a19927d0f632815190a91..985f345cdf9f69140df9210be6eca477d911f8a9 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1605,6 +1605,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent + worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent - this.profiler.push(() -> { + gameprofilerfiller.push(() -> { String s = String.valueOf(worldserver); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 373560fc82e491e6c8b755fecfe78d49a2fc3e2f..644341b8bc3079c6f092226acd11667f64bd55a1 100644 +index d62d6a345837e1b63c1a1393f18e367ac0ef4c30..b91ed08e8d9fbd399834d19ef01ebe5692d1ee4a 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -228,6 +228,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -231,6 +231,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public final LevelStorageSource.LevelStorageAccess convertable; public final UUID uuid; public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent @@ -29,13 +29,13 @@ index 373560fc82e491e6c8b755fecfe78d49a2fc3e2f..644341b8bc3079c6f092226acd11667f public LevelChunk getChunkIfLoaded(int x, int z) { return this.chunkSource.getChunk(x, z, false); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index d94c3e86885c5a8ba636988d29f98b496e13b627..a89c6ba4140f15e7f68f0df5cf64a176d350123b 100644 +index 7ea58478d3cde175a056f41cf945636a04128828..293490d124bc06c4a06b9f4a7f77a9c25a8d7d39 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3510,6 +3510,20 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3628,6 +3628,20 @@ public abstract class LivingEntity extends Entity implements Attackable { this.pushEntities(); - this.level().getProfiler().pop(); + gameprofilerfiller.pop(); + // Paper start - Add EntityMoveEvent + if (((ServerLevel) this.level()).hasEntityMoveEvent && !(this instanceof net.minecraft.world.entity.player.Player)) { + if (this.xo != this.getX() || this.yo != this.getY() || this.zo != this.getZ() || this.yRotO != this.getYRot() || this.xRotO != this.getXRot()) { @@ -50,6 +50,6 @@ index d94c3e86885c5a8ba636988d29f98b496e13b627..a89c6ba4140f15e7f68f0df5cf64a176 + } + } + // Paper end - Add EntityMoveEvent - if (!this.level().isClientSide && this.isSensitiveToWater() && this.isInWaterRainOrBubble()) { - this.hurt(this.damageSources().drown(), 1.0F); - } + world = this.level(); + if (world instanceof ServerLevel worldserver) { + if (this.isSensitiveToWater() && this.isInWaterRainOrBubble()) { diff --git a/patches/unapplied/server/0485-added-option-to-disable-pathfinding-updates-on-block.patch b/patches/server/0481-added-option-to-disable-pathfinding-updates-on-block.patch similarity index 76% rename from patches/unapplied/server/0485-added-option-to-disable-pathfinding-updates-on-block.patch rename to patches/server/0481-added-option-to-disable-pathfinding-updates-on-block.patch index e40ef31e1624..385032783495 100644 --- a/patches/unapplied/server/0485-added-option-to-disable-pathfinding-updates-on-block.patch +++ b/patches/server/0481-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 644341b8bc3079c6f092226acd11667f64bd55a1..1fe013b94cf1b5332f1e4645dd35df01e11fe0d9 100644 +index b91ed08e8d9fbd399834d19ef01ebe5692d1ee4a..d696ec118367f64fa7151189a4ace58287329851 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1374,6 +1374,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1387,6 +1387,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.getChunkSource().blockChanged(pos); this.pathTypesByPosCache.invalidate(pos); @@ -16,7 +16,7 @@ index 644341b8bc3079c6f092226acd11667f64bd55a1..1fe013b94cf1b5332f1e4645dd35df01 VoxelShape voxelshape = oldState.getCollisionShape(this, pos); VoxelShape voxelshape1 = newState.getCollisionShape(this, pos); -@@ -1415,6 +1416,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1428,6 +1429,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } } diff --git a/patches/unapplied/server/0486-Inline-shift-direction-fields.patch b/patches/server/0482-Inline-shift-direction-fields.patch similarity index 84% rename from patches/unapplied/server/0486-Inline-shift-direction-fields.patch rename to patches/server/0482-Inline-shift-direction-fields.patch index 910b881e3a64..22234bc09a89 100644 --- a/patches/unapplied/server/0486-Inline-shift-direction-fields.patch +++ b/patches/server/0482-Inline-shift-direction-fields.patch @@ -7,10 +7,10 @@ Removes a layer of indirection for EnumDirection.getAdjacent(X|Y|Z)(), which is critical section for much of the server, including the lighting engine. diff --git a/src/main/java/net/minecraft/core/Direction.java b/src/main/java/net/minecraft/core/Direction.java -index c47e6acbd36737aa7af13b452f51b3f017d324f4..03c45ee77276462818a6f774b5945b25924aa3f0 100644 +index 69ccada8ea78c05d3fb886222698c07dee421506..3fde5abde736b2c19d8819d9aec0397a0245ccd1 100644 --- a/src/main/java/net/minecraft/core/Direction.java +++ b/src/main/java/net/minecraft/core/Direction.java -@@ -55,6 +55,12 @@ public enum Direction implements StringRepresentable { +@@ -57,6 +57,12 @@ public enum Direction implements StringRepresentable { .sorted(Comparator.comparingInt(direction -> direction.data2d)) .toArray(Direction[]::new); @@ -23,10 +23,10 @@ index c47e6acbd36737aa7af13b452f51b3f017d324f4..03c45ee77276462818a6f774b5945b25 private Direction( final int id, final int idOpposite, -@@ -71,6 +77,11 @@ public enum Direction implements StringRepresentable { - this.axis = axis; +@@ -74,6 +80,11 @@ public enum Direction implements StringRepresentable { this.axisDirection = direction; this.normal = vector; + this.normalVec3 = Vec3.atLowerCornerOf(vector); + // Paper start - Perf: Inline shift direction fields + this.adjX = vector.getX(); + this.adjY = vector.getY(); @@ -35,7 +35,7 @@ index c47e6acbd36737aa7af13b452f51b3f017d324f4..03c45ee77276462818a6f774b5945b25 } public static Direction[] orderedByNearest(Entity entity) { -@@ -234,15 +245,15 @@ public enum Direction implements StringRepresentable { +@@ -247,15 +258,15 @@ public enum Direction implements StringRepresentable { } public int getStepX() { diff --git a/patches/unapplied/server/0487-Allow-adding-items-to-BlockDropItemEvent.patch b/patches/server/0483-Allow-adding-items-to-BlockDropItemEvent.patch similarity index 93% rename from patches/unapplied/server/0487-Allow-adding-items-to-BlockDropItemEvent.patch rename to patches/server/0483-Allow-adding-items-to-BlockDropItemEvent.patch index 4753f93e4114..4f9534949b80 100644 --- a/patches/unapplied/server/0487-Allow-adding-items-to-BlockDropItemEvent.patch +++ b/patches/server/0483-Allow-adding-items-to-BlockDropItemEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Allow adding items to BlockDropItemEvent diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index c48a9026c4db2005b67c5f70e9e1fa95b7820bc0..36adcab02e97cae2d087bae74cc4ceaf3052a9f8 100644 +index cee72eb02ebba4f50a117876351b8f516ba12057..1ce637a2b80dfc5c3da20f7bd95b97f4718a07d4 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -462,13 +462,30 @@ public class CraftEventFactory { +@@ -461,13 +461,30 @@ public class CraftEventFactory { } public static void handleBlockDropItemEvent(Block block, BlockState state, ServerPlayer player, List items) { diff --git a/patches/unapplied/server/0488-Add-getMainThreadExecutor-to-BukkitScheduler.patch b/patches/server/0484-Add-getMainThreadExecutor-to-BukkitScheduler.patch similarity index 92% rename from patches/unapplied/server/0488-Add-getMainThreadExecutor-to-BukkitScheduler.patch rename to patches/server/0484-Add-getMainThreadExecutor-to-BukkitScheduler.patch index 6ae0c8d11ba0..e2b8629ca85e 100644 --- a/patches/unapplied/server/0488-Add-getMainThreadExecutor-to-BukkitScheduler.patch +++ b/patches/server/0484-Add-getMainThreadExecutor-to-BukkitScheduler.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add getMainThreadExecutor to BukkitScheduler diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -index d7c2d8993a172e343669228cf24a58d8992a1c10..2f4d6b56301195f8d39ed50dffe842464065bfe1 100644 +index fdfdcac6644e5343fb1f1cbe5d9aa76a79627046..5fc88196b2c873427c817e9802ad3b12009f265f 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java @@ -642,4 +642,15 @@ public class CraftScheduler implements BukkitScheduler { diff --git a/patches/unapplied/server/0489-living-entity-allow-attribute-registration.patch b/patches/server/0485-living-entity-allow-attribute-registration.patch similarity index 89% rename from patches/unapplied/server/0489-living-entity-allow-attribute-registration.patch rename to patches/server/0485-living-entity-allow-attribute-registration.patch index 77576f8436eb..e9e4ab2f4883 100644 --- a/patches/unapplied/server/0489-living-entity-allow-attribute-registration.patch +++ b/patches/server/0485-living-entity-allow-attribute-registration.patch @@ -5,10 +5,10 @@ Subject: [PATCH] living entity allow attribute registration diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java -index cd03d705337a0ea34c7c06a581294112433afb50..69992ebc999ea3ff9e47e4e049bcc514c01150ca 100644 +index 3a6c55a7f07e8871a77c91679732dd63db604004..94d04a20f97405e02d7cccaabadc7a7e86e336f7 100644 --- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java +++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java -@@ -140,4 +140,12 @@ public class AttributeMap { +@@ -149,4 +149,12 @@ public class AttributeMap { } } } @@ -38,10 +38,10 @@ index 5678d2007d5adf45dec0638c5dd848b601801814..0a7ed5a4f1644a70d8f98ad7a6962b81 + // Paper end - living entity allow attribute registration } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 10f3defa8f4b57fb45cf7de06d415b72102e47d5..e56a0d8928e3c0e27b1acd171162e4a53b70d925 100644 +index ff3b53eff8f5fc1e02e7b30d59ff27dfe8f5d431..5749e2b5174be23633c8a811baec8c05da12e3e2 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -768,6 +768,13 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -775,6 +775,13 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return this.getHandle().craftAttributes.getAttribute(attribute); } diff --git a/patches/unapplied/server/0490-fix-dead-slime-setSize-invincibility.patch b/patches/server/0486-fix-dead-slime-setSize-invincibility.patch similarity index 100% rename from patches/unapplied/server/0490-fix-dead-slime-setSize-invincibility.patch rename to patches/server/0486-fix-dead-slime-setSize-invincibility.patch diff --git a/patches/unapplied/server/0491-Merchant-getRecipes-should-return-an-immutable-list.patch b/patches/server/0487-Merchant-getRecipes-should-return-an-immutable-list.patch similarity index 100% rename from patches/unapplied/server/0491-Merchant-getRecipes-should-return-an-immutable-list.patch rename to patches/server/0487-Merchant-getRecipes-should-return-an-immutable-list.patch diff --git a/patches/unapplied/server/0492-Expose-Tracked-Players.patch b/patches/server/0488-Expose-Tracked-Players.patch similarity index 89% rename from patches/unapplied/server/0492-Expose-Tracked-Players.patch rename to patches/server/0488-Expose-Tracked-Players.patch index d8ca4c111c4b..28357313028b 100644 --- a/patches/unapplied/server/0492-Expose-Tracked-Players.patch +++ b/patches/server/0488-Expose-Tracked-Players.patch @@ -5,10 +5,10 @@ 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 98e8ad81b8c9c0636abe59f70ce891fe926a37fe..96201ea45f8b53dcadb1a8732b1d49b1e8d1d7df 100644 +index 925626b74005ec9c031c3773171f7684ecc9ccd3..06fda053874e7ef0c8995b1a55e5f518b28eebc9 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1069,4 +1069,21 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1070,4 +1070,21 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return getHandle().isTicking(); } // Paper end - isTicking API diff --git a/patches/unapplied/server/0493-Improve-ServerGUI.patch b/patches/server/0489-Improve-ServerGUI.patch similarity index 100% rename from patches/unapplied/server/0493-Improve-ServerGUI.patch rename to patches/server/0489-Improve-ServerGUI.patch diff --git a/patches/unapplied/server/0494-fix-converting-txt-to-json-file.patch b/patches/server/0490-fix-converting-txt-to-json-file.patch similarity index 90% rename from patches/unapplied/server/0494-fix-converting-txt-to-json-file.patch rename to patches/server/0490-fix-converting-txt-to-json-file.patch index 2134c10628bd..19ad56834740 100644 --- a/patches/unapplied/server/0494-fix-converting-txt-to-json-file.patch +++ b/patches/server/0490-fix-converting-txt-to-json-file.patch @@ -21,10 +21,10 @@ index 929f59bce01c8e6ed4b0b551744d42e131b8fc80..22c4f8dea99f92a1eb3da2baf0a15bf9 this.saveUserBanList(); this.loadIpBanList(); diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 2b1d7a2360a9ee7bca9d93a2dc8c61d1648a8348..d5153f804cfcfd1a70c46975e3fb1e50c8a82999 100644 +index 20a3138c6c2a6c8ada8b6008913abae0eea76f2d..e95d592b6001dd4320c58133d841359f99c2d9c4 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -216,6 +216,12 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -215,6 +215,12 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface this.paperConfigurations.initializeGlobalConfiguration(this.registryAccess()); this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess()); // Paper end - initialize global and world-defaults configuration @@ -37,7 +37,7 @@ index 2b1d7a2360a9ee7bca9d93a2dc8c61d1648a8348..d5153f804cfcfd1a70c46975e3fb1e50 org.spigotmc.WatchdogThread.doStart(org.spigotmc.SpigotConfig.timeoutTime, org.spigotmc.SpigotConfig.restartOnCrash); // Paper - start watchdog thread io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics -@@ -270,9 +276,6 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -269,9 +275,6 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface DedicatedServer.LOGGER.warn("To change this, set \"online-mode\" to \"true\" in the server.properties file."); } @@ -48,10 +48,10 @@ index 2b1d7a2360a9ee7bca9d93a2dc8c61d1648a8348..d5153f804cfcfd1a70c46975e3fb1e50 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 9b94ca912f99a3a465f30130b24347fc9aca72ff..123fe4f5b98a7483af86695ec82987abd45eafb2 100644 +index 7676dbe55b4bf6e0472dc0190c01e6ecfcbb464e..26e0414645f7ab11ca3e77c7c5e458612625aee9 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 { +@@ -180,6 +180,7 @@ public abstract class PlayerList { this.maxPlayers = maxPlayers; this.playerIo = saveHandler; } diff --git a/patches/unapplied/server/0495-Add-worldborder-events.patch b/patches/server/0491-Add-worldborder-events.patch similarity index 93% rename from patches/unapplied/server/0495-Add-worldborder-events.patch rename to patches/server/0491-Add-worldborder-events.patch index 44a467547c80..014dba4c88d2 100644 --- a/patches/unapplied/server/0495-Add-worldborder-events.patch +++ b/patches/server/0491-Add-worldborder-events.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add worldborder events diff --git a/src/main/java/net/minecraft/world/level/border/WorldBorder.java b/src/main/java/net/minecraft/world/level/border/WorldBorder.java -index 3442e33a1146318228c4727a2a5afde685f69bf7..04e62c54f224f7949fde9ceded208e700db55aa1 100644 +index b50090df116697a12f5498d65dd2e5d6d5297fb5..807a097a7b6399f24ede741f94ce98eb67e55add 100644 --- a/src/main/java/net/minecraft/world/level/border/WorldBorder.java +++ b/src/main/java/net/minecraft/world/level/border/WorldBorder.java -@@ -140,6 +140,14 @@ public class WorldBorder { +@@ -148,6 +148,14 @@ public class WorldBorder { } public void setCenter(double x, double z) { @@ -23,7 +23,7 @@ index 3442e33a1146318228c4727a2a5afde685f69bf7..04e62c54f224f7949fde9ceded208e70 this.centerX = x; this.centerZ = z; this.extent.onCenterChange(); -@@ -166,6 +174,17 @@ public class WorldBorder { +@@ -174,6 +182,17 @@ public class WorldBorder { } public void setSize(double size) { @@ -41,7 +41,7 @@ index 3442e33a1146318228c4727a2a5afde685f69bf7..04e62c54f224f7949fde9ceded208e70 this.extent = new WorldBorder.StaticBorderExtent(size); Iterator iterator = this.getListeners().iterator(); -@@ -178,6 +197,20 @@ public class WorldBorder { +@@ -186,6 +205,20 @@ public class WorldBorder { } public void lerpSizeBetween(double fromSize, double toSize, long time) { @@ -62,7 +62,7 @@ index 3442e33a1146318228c4727a2a5afde685f69bf7..04e62c54f224f7949fde9ceded208e70 this.extent = (WorldBorder.BorderExtent) (fromSize == toSize ? new WorldBorder.StaticBorderExtent(toSize) : new WorldBorder.MovingBorderExtent(fromSize, toSize, time)); Iterator iterator = this.getListeners().iterator(); -@@ -489,6 +522,7 @@ public class WorldBorder { +@@ -497,6 +530,7 @@ public class WorldBorder { @Override public WorldBorder.BorderExtent update() { diff --git a/patches/unapplied/server/0496-Add-PlayerNameEntityEvent.patch b/patches/server/0492-Add-PlayerNameEntityEvent.patch similarity index 91% rename from patches/unapplied/server/0496-Add-PlayerNameEntityEvent.patch rename to patches/server/0492-Add-PlayerNameEntityEvent.patch index 9287edc1b759..4215e4291d03 100644 --- a/patches/unapplied/server/0496-Add-PlayerNameEntityEvent.patch +++ b/patches/server/0492-Add-PlayerNameEntityEvent.patch @@ -5,12 +5,12 @@ Subject: [PATCH] Add PlayerNameEntityEvent diff --git a/src/main/java/net/minecraft/world/item/NameTagItem.java b/src/main/java/net/minecraft/world/item/NameTagItem.java -index 3ce8c725270510dbaaf2c1edc895d37ea9ca424c..774c982f28b4f127fc3f036c19dfb47fb9ae3264 100644 +index dd5aa4bbf2e7bab3be1c3582b090fdf0fa3fb0df..000d1863bfba98b5132dfc6743362d687b2f54f3 100644 --- a/src/main/java/net/minecraft/world/item/NameTagItem.java +++ b/src/main/java/net/minecraft/world/item/NameTagItem.java @@ -18,8 +18,13 @@ public class NameTagItem extends Item { Component component = stack.get(DataComponents.CUSTOM_NAME); - if (component != null && !(entity instanceof Player)) { + if (component != null && entity.getType().canSerialize()) { if (!user.level().isClientSide && entity.isAlive()) { - entity.setCustomName(component); - if (entity instanceof Mob mob) { diff --git a/patches/unapplied/server/0497-Add-recipe-to-cook-events.patch b/patches/server/0493-Add-recipe-to-cook-events.patch similarity index 75% rename from patches/unapplied/server/0497-Add-recipe-to-cook-events.patch rename to patches/server/0493-Add-recipe-to-cook-events.patch index 6fe8720d2101..737ce3caf898 100644 --- a/patches/unapplied/server/0497-Add-recipe-to-cook-events.patch +++ b/patches/server/0493-Add-recipe-to-cook-events.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add recipe to cook events diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index 5ea2b05961590732a43bb5a1abf00bf8a00c72c2..84a3130a31f7a0fd5a8ae1b293dd3f2ca07c86d3 100644 +index b9dd5f710533b156311cac2c020fd0d5f64b6265..2ec1c00eb77051c622fedec1ebeba2953886ace4 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -@@ -444,7 +444,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -332,7 +332,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit CraftItemStack source = CraftItemStack.asCraftMirror(itemstack); org.bukkit.inventory.ItemStack result = CraftItemStack.asBukkitCopy(itemstack1); @@ -18,22 +18,22 @@ index 5ea2b05961590732a43bb5a1abf00bf8a00c72c2..84a3130a31f7a0fd5a8ae1b293dd3f2c if (furnaceSmeltEvent.isCancelled()) { diff --git a/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java -index 80f911692c97585a696a19ebbe616d6aa312b2d9..0c20a334be4b1c4cf7999826f8d9bff5e36bc2b8 100644 +index 30035d534e144bf31f94073c57b0195be7e62772..7fa1aea7942a1bc4d9779a9f8ab020ccd5566923 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java -@@ -67,7 +67,10 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { +@@ -66,7 +66,10 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { - if (campfire.cookingProgress[i] >= campfire.cookingTime[i]) { + if (blockEntity.cookingProgress[i] >= blockEntity.cookingTime[i]) { SingleRecipeInput singlerecipeinput = new SingleRecipeInput(itemstack); -- ItemStack itemstack1 = (ItemStack) campfire.quickCheck.getRecipeFor(singlerecipeinput, world).map((recipeholder) -> { +- ItemStack itemstack1 = (ItemStack) recipeMatchGetter.getRecipeFor(singlerecipeinput, world).map((recipeholder) -> { + // Paper start - add recipe to cook events -+ Optional> recipeHolderOptional = campfire.quickCheck.getRecipeFor(singlerecipeinput, world); -+ ItemStack itemstack1 = recipeHolderOptional.map((recipeholder) -> { -+ // Paper end - Add recipe to cook events ++ final Optional> recipeHolderOptional = recipeMatchGetter.getRecipeFor(singlerecipeinput, world); ++ ItemStack itemstack1 = (ItemStack) recipeHolderOptional.map((recipeholder) -> { ++ // Paper end - add recipe to cook events return ((CampfireCookingRecipe) recipeholder.value()).assemble(singlerecipeinput, world.registryAccess()); }).orElse(itemstack); -@@ -76,7 +79,7 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { +@@ -75,7 +78,7 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { CraftItemStack source = CraftItemStack.asCraftMirror(itemstack); org.bukkit.inventory.ItemStack result = CraftItemStack.asBukkitCopy(itemstack1); diff --git a/patches/unapplied/server/0498-Add-Block-isValidTool.patch b/patches/server/0494-Add-Block-isValidTool.patch similarity index 88% rename from patches/unapplied/server/0498-Add-Block-isValidTool.patch rename to patches/server/0494-Add-Block-isValidTool.patch index 5f36fb047c0c..e0c42e8e3762 100644 --- a/patches/unapplied/server/0498-Add-Block-isValidTool.patch +++ b/patches/server/0494-Add-Block-isValidTool.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add Block#isValidTool diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index 98e87dc15e2ed23f6897ba6359846ff5bc32b655..2034858a53c4c887da334cdc7713997daa01124f 100644 +index 1595e877b02b447b36f5c316ae70d4023b78a862..54fb380a6896731a18c0100722d12099e590cbc9 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -693,5 +693,9 @@ public class CraftBlock implements Block { diff --git a/patches/unapplied/server/0499-Allow-using-signs-inside-spawn-protection.patch b/patches/server/0495-Allow-using-signs-inside-spawn-protection.patch similarity index 75% rename from patches/unapplied/server/0499-Allow-using-signs-inside-spawn-protection.patch rename to patches/server/0495-Allow-using-signs-inside-spawn-protection.patch index 9f0399c60f80..84ca07a4a1fc 100644 --- a/patches/unapplied/server/0499-Allow-using-signs-inside-spawn-protection.patch +++ b/patches/server/0495-Allow-using-signs-inside-spawn-protection.patch @@ -5,16 +5,15 @@ Subject: [PATCH] Allow using signs inside spawn protection diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index d7d36b5148f2e7280816cc70b300b9b10720f751..25d060e8d77b1e8ea2ac951d2b25d60a984398cd 100644 +index 0c413f4981038c5c3f12ba17309ce354c3f13ec6..628260aa644539a966e4cc5acf8da34144fcabd0 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1758,8 +1758,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - int i = this.player.level().getMaxBuildHeight(); +@@ -1762,7 +1762,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + int i = this.player.level().getMaxY(); - if (blockposition.getY() < i) { + if (blockposition.getY() <= i) { - if (this.awaitingPositionFromClient == null && worldserver.mayInteract(this.player, blockposition)) { -- this.player.stopUsingItem(); // CraftBukkit - SPIGOT-4706 + if (this.awaitingPositionFromClient == null && (worldserver.mayInteract(this.player, blockposition) || (worldserver.paperConfig().spawn.allowUsingSignsInsideSpawnProtection && worldserver.getBlockState(blockposition).getBlock() instanceof net.minecraft.world.level.block.SignBlock))) { // Paper - Allow using signs inside spawn protection + this.player.stopUsingItem(); // CraftBukkit - SPIGOT-4706 InteractionResult enuminteractionresult = this.player.gameMode.useItemOn(this.player, worldserver, itemstack, enumhand, movingobjectpositionblock); - if (enuminteractionresult.consumesAction()) { diff --git a/patches/unapplied/server/0500-Expand-world-key-API.patch b/patches/server/0496-Expand-world-key-API.patch similarity index 88% rename from patches/unapplied/server/0500-Expand-world-key-API.patch rename to patches/server/0496-Expand-world-key-API.patch index d2ccfa3efb0c..beef58646723 100644 --- a/patches/unapplied/server/0500-Expand-world-key-API.patch +++ b/patches/server/0496-Expand-world-key-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Expand world key API diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index 1963e826548c5a8859c50f57654784c3aef50e44..04a39cb6c13c26e2cb1d73a9da98df5d04df69bc 100644 +index 93dadbf659e41c923268d8ec782fcbdc8aaeff68..21e5dd6624e50dec35859b7d1be4a304e4427883 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java @@ -515,5 +515,10 @@ public abstract class CraftRegionAccessor implements RegionAccessor { @@ -20,10 +20,10 @@ index 1963e826548c5a8859c50f57654784c3aef50e44..04a39cb6c13c26e2cb1d73a9da98df5d // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index f402ef662779e096ee354b9edd66cca785b85f33..a9c6f53c7e828a4b7d0cefbaa98e50ff1db9354a 100644 +index ee231d93d216571a45b11b49663b2ea91c47a1c7..dc20a383950a72aba5d056912d257912d3c0e808 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1183,9 +1183,15 @@ public final class CraftServer implements Server { +@@ -1186,9 +1186,15 @@ public final class CraftServer implements Server { File folder = new File(this.getWorldContainer(), name); World world = this.getWorld(name); @@ -41,7 +41,7 @@ index f402ef662779e096ee354b9edd66cca785b85f33..a9c6f53c7e828a4b7d0cefbaa98e50ff if (folder.exists()) { Preconditions.checkArgument(folder.isDirectory(), "File (%s) exists and isn't a folder", name); -@@ -1311,7 +1317,7 @@ public final class CraftServer implements Server { +@@ -1314,7 +1320,7 @@ public final class CraftServer implements Server { } else if (name.equals(levelName + "_the_end")) { worldKey = net.minecraft.world.level.Level.END; } else { @@ -50,7 +50,7 @@ index f402ef662779e096ee354b9edd66cca785b85f33..a9c6f53c7e828a4b7d0cefbaa98e50ff } // If set to not keep spawn in memory (changed from default) then adjust rule accordingly -@@ -1407,6 +1413,15 @@ public final class CraftServer implements Server { +@@ -1410,6 +1416,15 @@ public final class CraftServer implements Server { return null; } @@ -67,7 +67,7 @@ index f402ef662779e096ee354b9edd66cca785b85f33..a9c6f53c7e828a4b7d0cefbaa98e50ff // Check if a World already exists with the UID. if (this.getWorld(world.getUID()) != null) { diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 66249c5caefb0879e13c02d5553b09b4122418b9..79915a93b36ddf2925444369a5df4e8f4fd5610e 100644 +index ea9c9ae832c4044a2eccbf901e20ff042df68bf3..407fa9f1f3d418597eb490e2cf41aee39c715d3a 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -522,6 +522,11 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/unapplied/server/0501-Add-fast-alternative-constructor-for-Rotations.patch b/patches/server/0497-Add-fast-alternative-constructor-for-Rotations.patch similarity index 100% rename from patches/unapplied/server/0501-Add-fast-alternative-constructor-for-Rotations.patch rename to patches/server/0497-Add-fast-alternative-constructor-for-Rotations.patch diff --git a/patches/unapplied/server/0502-Drop-carried-item-when-player-has-disconnected.patch b/patches/server/0498-Drop-carried-item-when-player-has-disconnected.patch similarity index 89% rename from patches/unapplied/server/0502-Drop-carried-item-when-player-has-disconnected.patch rename to patches/server/0498-Drop-carried-item-when-player-has-disconnected.patch index ababb3984cb6..a13f458eea40 100644 --- a/patches/unapplied/server/0502-Drop-carried-item-when-player-has-disconnected.patch +++ b/patches/server/0498-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 123fe4f5b98a7483af86695ec82987abd45eafb2..bbc6f64a3b2c0702a0a752acd48145cdcafd742e 100644 +index 26e0414645f7ab11ca3e77c7c5e458612625aee9..6f7807cc0da427485037b3a72a9c60c81a858294 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -588,6 +588,14 @@ public abstract class PlayerList { +@@ -538,6 +538,14 @@ public abstract class PlayerList { } // Paper end - Configurable player collision diff --git a/patches/unapplied/server/0503-forced-whitelist-use-configurable-kick-message.patch b/patches/server/0499-forced-whitelist-use-configurable-kick-message.patch similarity index 87% rename from patches/unapplied/server/0503-forced-whitelist-use-configurable-kick-message.patch rename to patches/server/0499-forced-whitelist-use-configurable-kick-message.patch index 96926fac4a85..aed5bbf27da6 100644 --- a/patches/unapplied/server/0503-forced-whitelist-use-configurable-kick-message.patch +++ b/patches/server/0499-forced-whitelist-use-configurable-kick-message.patch @@ -5,10 +5,10 @@ Subject: [PATCH] forced whitelist: use configurable kick message diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 43b28b56c7949f95af5b7e99b04b93ed711d8880..6651afa50cfaf53959f89108904d4bf65a0fc495 100644 +index 985f345cdf9f69140df9210be6eca477d911f8a9..42429684bd732d0094ad0db346d2a656871aabff 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2286,7 +2286,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> list1 = pages.stream().map(this::filterableFromOutgoing).toList(); itemstack.set(DataComponents.WRITABLE_BOOK_CONTENT, new WritableBookContent(list1)); diff --git a/patches/unapplied/server/0505-Expose-protocol-version.patch b/patches/server/0501-Expose-protocol-version.patch similarity index 90% rename from patches/unapplied/server/0505-Expose-protocol-version.patch rename to patches/server/0501-Expose-protocol-version.patch index d47bd22bc7c5..1cc14ceba20b 100644 --- a/patches/unapplied/server/0505-Expose-protocol-version.patch +++ b/patches/server/0501-Expose-protocol-version.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Expose protocol version diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 79915a93b36ddf2925444369a5df4e8f4fd5610e..09fa524fa1155d53d988c15c1af551f73c96ede5 100644 +index 407fa9f1f3d418597eb490e2cf41aee39c715d3a..2f7cb2bd5998204d61c9d758224b3a2e3351de48 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -527,6 +527,11 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/unapplied/server/0506-Enhance-console-tab-completions-for-brigadier-comman.patch b/patches/server/0502-Enhance-console-tab-completions-for-brigadier-comman.patch similarity index 99% rename from patches/unapplied/server/0506-Enhance-console-tab-completions-for-brigadier-comman.patch rename to patches/server/0502-Enhance-console-tab-completions-for-brigadier-comman.patch index 596d2d9d6d15..15098cf64c6b 100644 --- a/patches/unapplied/server/0506-Enhance-console-tab-completions-for-brigadier-comman.patch +++ b/patches/server/0502-Enhance-console-tab-completions-for-brigadier-comman.patch @@ -358,10 +358,10 @@ index 0000000000000000000000000000000000000000..8239a8ba57f856cbbee237a601b3cabf + } +} diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index d5153f804cfcfd1a70c46975e3fb1e50c8a82999..764395fe8e49d811294ca82887fee91ca6cd01fc 100644 +index e95d592b6001dd4320c58133d841359f99c2d9c4..17b15bef9ad8edddc2e1f2a617a1ab4bd5b53347 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -190,7 +190,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -189,7 +189,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface thread.setDaemon(true); thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(DedicatedServer.LOGGER)); @@ -370,7 +370,7 @@ index d5153f804cfcfd1a70c46975e3fb1e50c8a82999..764395fe8e49d811294ca82887fee91c DedicatedServer.LOGGER.info("Starting minecraft server version {}", SharedConstants.getCurrentVersion().getName()); if (Runtime.getRuntime().maxMemory() / 1024L / 1024L < 512L) { DedicatedServer.LOGGER.warn("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\""); -@@ -223,6 +223,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -222,6 +222,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface this.getPlayerList().loadAndSaveFiles(); // Must be after convertNames // Paper end - fix converting txt to json file org.spigotmc.WatchdogThread.doStart(org.spigotmc.SpigotConfig.timeoutTime, org.spigotmc.SpigotConfig.restartOnCrash); // Paper - start watchdog thread diff --git a/patches/unapplied/server/0507-Fix-PlayerItemConsumeEvent-cancelling-properly.patch b/patches/server/0503-Fix-PlayerItemConsumeEvent-cancelling-properly.patch similarity index 72% rename from patches/unapplied/server/0507-Fix-PlayerItemConsumeEvent-cancelling-properly.patch rename to patches/server/0503-Fix-PlayerItemConsumeEvent-cancelling-properly.patch index a47593aa71ca..a1da72f4992e 100644 --- a/patches/unapplied/server/0507-Fix-PlayerItemConsumeEvent-cancelling-properly.patch +++ b/patches/server/0503-Fix-PlayerItemConsumeEvent-cancelling-properly.patch @@ -9,14 +9,14 @@ till their item is switched. This patch clears the active item when the event is cancelled diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index a89c6ba4140f15e7f68f0df5cf64a176d350123b..afa2d3f5199fcac5c83639bb87e31425da4c5310 100644 +index 293490d124bc06c4a06b9f4a7f77a9c25a8d7d39..b7cc3d84c724772e3e1250c5e99bb32e01112220 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -4011,6 +4011,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4136,6 +4136,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.level().getCraftServer().getPluginManager().callEvent(event); if (event.isCancelled()) { + this.stopUsingItem(); // Paper - event is using an item, clear active item to reset its use // Update client - if (this.useItem.getItem() instanceof net.minecraft.world.item.SuspiciousStewItem itemSuspiciousStew) { - itemSuspiciousStew.cancelUsingItem(entityPlayer, this.useItem); + Consumable consumable = this.useItem.get(DataComponents.CONSUMABLE); + if (consumable != null) { From 0bb4d1d660b328272cb5ebf633d87ec54c8b96ef Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Wed, 23 Oct 2024 20:15:25 +0200 Subject: [PATCH 024/119] 553 --- .../0504-Add-bypass-host-check.patch} | 0 ...0505-Set-area-affect-cloud-rotation.patch} | 8 +- ...add-isDeeplySleeping-to-HumanEntity.patch} | 2 +- ...add-consumeFuel-to-FurnaceBurnEvent.patch} | 4 +- ...-set-drop-chance-to-EntityEquipment.patch} | 2 +- ...ix-PigZombieAngerEvent-cancellation.patch} | 2 +- ...ix-PlayerItemHeldEvent-firing-twice.patch} | 4 +- .../0511-Add-PlayerDeepSleepEvent.patch} | 2 +- .../0512-More-World-API.patch} | 4 +- .../0513-Add-PlayerBedFailEnterEvent.patch} | 6 +- ...-to-convert-between-Component-and-B.patch} | 4 +- ...awnEvent-fix-passed-parameter-issue.patch} | 6 +- ...acon-activation-deactivation-events.patch} | 4 +- ...dd-Channel-initialization-listeners.patch} | 0 ...mands-if-tab-completion-is-disabled.patch} | 4 +- .../0519-Add-more-WanderingTrader-API.patch} | 6 +- ...dd-EntityBlockStorage-clearEntities.patch} | 4 +- ...ssage-to-PlayerAdvancementDoneEvent.patch} | 6 +- .../0522-Add-HiddenPotionEffect-API.patch} | 0 .../0523-Inventory-close.patch} | 0 ...-in-sunlight-API-for-Phantoms-and-S.patch} | 14 +- .../0525-Add-basic-Datapack-API.patch} | 8 +- ...ment-variable-to-disable-server-gui.patch} | 2 +- ...27-Expand-PlayerGameModeChangeEvent.patch} | 26 ++-- .../0528-ItemStack-repair-check-API.patch} | 2 +- .../0529-More-Enchantment-API.patch} | 0 ...ve-range-check-for-block-placing-up.patch} | 4 +- .../0531-Add-Mob-lookAt-API.patch} | 4 +- ...f-bucket-dispenses-will-succeed-for.patch} | 4 +- ...0533-Add-Unix-domain-socket-support.patch} | 10 +- .../0534-Add-EntityInsideBlockEvent.patch} | 120 +++++++++--------- ...-Improve-item-default-attribute-API.patch} | 9 +- ...ause-to-Weather-ThunderChangeEvents.patch} | 16 +-- .../0537-More-Lidded-Block-API.patch} | 0 ...38-Limit-item-frame-cursors-on-maps.patch} | 6 +- .../0539-Add-PlayerKickEvent-causes.patch} | 104 +++++++-------- ...0540-Add-PufferFishStateChangeEvent.patch} | 4 +- ...erBucketEmptyEvent-result-itemstack.patch} | 2 +- ...tedContainer-instead-of-ThreadingDe.patch} | 14 +- ...-to-fix-items-merging-through-walls.patch} | 4 +- .../0544-Add-BellRevealRaiderEvent.patch} | 0 .../0545-Fix-invulnerable-end-crystals.patch} | 6 +- ...46-Add-ElderGuardianAppearanceEvent.patch} | 8 +- ...-Biome-Mob-Lookups-for-Mob-Spawning.patch} | 0 .../0548-Line-Of-Sight-Changes.patch} | 16 +-- .../0549-add-per-world-spawn-limits.patch} | 4 +- .../0550-Fix-potions-splash-events.patch} | 38 +++--- .../0551-Add-more-LimitedRegion-API.patch} | 4 +- ...layerDropItemEvent-using-wrong-item.patch} | 22 ++-- .../0553-Missing-Entity-API.patch} | 83 ++++++------ 50 files changed, 298 insertions(+), 304 deletions(-) rename patches/{unapplied/server/0508-Add-bypass-host-check.patch => server/0504-Add-bypass-host-check.patch} (100%) rename patches/{unapplied/server/0509-Set-area-affect-cloud-rotation.patch => server/0505-Set-area-affect-cloud-rotation.patch} (84%) rename patches/{unapplied/server/0510-add-isDeeplySleeping-to-HumanEntity.patch => server/0506-add-isDeeplySleeping-to-HumanEntity.patch} (90%) rename patches/{unapplied/server/0511-add-consumeFuel-to-FurnaceBurnEvent.patch => server/0507-add-consumeFuel-to-FurnaceBurnEvent.patch} (86%) rename patches/{unapplied/server/0512-add-get-set-drop-chance-to-EntityEquipment.patch => server/0508-add-get-set-drop-chance-to-EntityEquipment.patch} (97%) rename patches/{unapplied/server/0513-fix-PigZombieAngerEvent-cancellation.patch => server/0509-fix-PigZombieAngerEvent-cancellation.patch} (95%) rename patches/{unapplied/server/0514-fix-PlayerItemHeldEvent-firing-twice.patch => server/0510-fix-PlayerItemHeldEvent-firing-twice.patch} (88%) rename patches/{unapplied/server/0515-Add-PlayerDeepSleepEvent.patch => server/0511-Add-PlayerDeepSleepEvent.patch} (92%) rename patches/{unapplied/server/0516-More-World-API.patch => server/0512-More-World-API.patch} (94%) rename patches/{unapplied/server/0517-Add-PlayerBedFailEnterEvent.patch => server/0513-Add-PlayerBedFailEnterEvent.patch} (91%) rename patches/{unapplied/server/0518-Implement-methods-to-convert-between-Component-and-B.patch => server/0514-Implement-methods-to-convert-between-Component-and-B.patch} (94%) rename patches/{unapplied/server/0519-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch => server/0515-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch} (81%) rename patches/{unapplied/server/0520-Introduce-beacon-activation-deactivation-events.patch => server/0516-Introduce-beacon-activation-deactivation-events.patch} (92%) rename patches/{unapplied/server/0521-Add-Channel-initialization-listeners.patch => server/0517-Add-Channel-initialization-listeners.patch} (100%) rename patches/{unapplied/server/0522-Send-empty-commands-if-tab-completion-is-disabled.patch => server/0518-Send-empty-commands-if-tab-completion-is-disabled.patch} (88%) rename patches/{unapplied/server/0523-Add-more-WanderingTrader-API.patch => server/0519-Add-more-WanderingTrader-API.patch} (93%) rename patches/{unapplied/server/0524-Add-EntityBlockStorage-clearEntities.patch => server/0520-Add-EntityBlockStorage-clearEntities.patch} (91%) rename patches/{unapplied/server/0525-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch => server/0521-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch} (90%) rename patches/{unapplied/server/0526-Add-HiddenPotionEffect-API.patch => server/0522-Add-HiddenPotionEffect-API.patch} (100%) rename patches/{unapplied/server/0527-Inventory-close.patch => server/0523-Inventory-close.patch} (100%) rename patches/{unapplied/server/0528-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch => server/0524-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch} (91%) rename patches/{unapplied/server/0529-Add-basic-Datapack-API.patch => server/0525-Add-basic-Datapack-API.patch} (96%) rename patches/{unapplied/server/0530-Add-environment-variable-to-disable-server-gui.patch => server/0526-Add-environment-variable-to-disable-server-gui.patch} (90%) rename patches/{unapplied/server/0531-Expand-PlayerGameModeChangeEvent.patch => server/0527-Expand-PlayerGameModeChangeEvent.patch} (89%) rename patches/{unapplied/server/0532-ItemStack-repair-check-API.patch => server/0528-ItemStack-repair-check-API.patch} (96%) rename patches/{unapplied/server/0533-More-Enchantment-API.patch => server/0529-More-Enchantment-API.patch} (100%) rename patches/{unapplied/server/0534-Move-range-check-for-block-placing-up.patch => server/0530-Move-range-check-for-block-placing-up.patch} (88%) rename patches/{unapplied/server/0535-Add-Mob-lookAt-API.patch => server/0531-Add-Mob-lookAt-API.patch} (95%) rename patches/{unapplied/server/0536-Correctly-check-if-bucket-dispenses-will-succeed-for.patch => server/0532-Correctly-check-if-bucket-dispenses-will-succeed-for.patch} (93%) rename patches/{unapplied/server/0537-Add-Unix-domain-socket-support.patch => server/0533-Add-Unix-domain-socket-support.patch} (95%) rename patches/{unapplied/server/0538-Add-EntityInsideBlockEvent.patch => server/0534-Add-EntityInsideBlockEvent.patch} (79%) rename patches/{unapplied/server/0539-Improve-item-default-attribute-API.patch => server/0535-Improve-item-default-attribute-API.patch} (92%) rename patches/{unapplied/server/0540-Add-cause-to-Weather-ThunderChangeEvents.patch => server/0536-Add-cause-to-Weather-ThunderChangeEvents.patch} (90%) rename patches/{unapplied/server/0541-More-Lidded-Block-API.patch => server/0537-More-Lidded-Block-API.patch} (100%) rename patches/{unapplied/server/0542-Limit-item-frame-cursors-on-maps.patch => server/0538-Limit-item-frame-cursors-on-maps.patch} (89%) rename patches/{unapplied/server/0543-Add-PlayerKickEvent-causes.patch => server/0539-Add-PlayerKickEvent-causes.patch} (90%) rename patches/{unapplied/server/0544-Add-PufferFishStateChangeEvent.patch => server/0540-Add-PufferFishStateChangeEvent.patch} (95%) rename patches/{unapplied/server/0545-Fix-PlayerBucketEmptyEvent-result-itemstack.patch => server/0541-Fix-PlayerBucketEmptyEvent-result-itemstack.patch} (95%) rename patches/{unapplied/server/0546-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch => server/0542-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch} (88%) rename patches/{unapplied/server/0547-Add-option-to-fix-items-merging-through-walls.patch => server/0543-Add-option-to-fix-items-merging-through-walls.patch} (89%) rename patches/{unapplied/server/0548-Add-BellRevealRaiderEvent.patch => server/0544-Add-BellRevealRaiderEvent.patch} (100%) rename patches/{unapplied/server/0549-Fix-invulnerable-end-crystals.patch => server/0545-Fix-invulnerable-end-crystals.patch} (93%) rename patches/{unapplied/server/0550-Add-ElderGuardianAppearanceEvent.patch => server/0546-Add-ElderGuardianAppearanceEvent.patch} (83%) rename patches/{unapplied/server/0551-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch => server/0547-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch} (100%) rename patches/{unapplied/server/0552-Line-Of-Sight-Changes.patch => server/0548-Line-Of-Sight-Changes.patch} (82%) rename patches/{unapplied/server/0553-add-per-world-spawn-limits.patch => server/0549-add-per-world-spawn-limits.patch} (85%) rename patches/{unapplied/server/0554-Fix-potions-splash-events.patch => server/0550-Fix-potions-splash-events.patch} (80%) rename patches/{unapplied/server/0555-Add-more-LimitedRegion-API.patch => server/0551-Add-more-LimitedRegion-API.patch} (93%) rename patches/{unapplied/server/0556-Fix-PlayerDropItemEvent-using-wrong-item.patch => server/0552-Fix-PlayerDropItemEvent-using-wrong-item.patch} (79%) rename patches/{unapplied/server/0557-Missing-Entity-API.patch => server/0553-Missing-Entity-API.patch} (94%) diff --git a/patches/unapplied/server/0508-Add-bypass-host-check.patch b/patches/server/0504-Add-bypass-host-check.patch similarity index 100% rename from patches/unapplied/server/0508-Add-bypass-host-check.patch rename to patches/server/0504-Add-bypass-host-check.patch diff --git a/patches/unapplied/server/0509-Set-area-affect-cloud-rotation.patch b/patches/server/0505-Set-area-affect-cloud-rotation.patch similarity index 84% rename from patches/unapplied/server/0509-Set-area-affect-cloud-rotation.patch rename to patches/server/0505-Set-area-affect-cloud-rotation.patch index 18167918366f..2d17a3c0fc9a 100644 --- a/patches/unapplied/server/0509-Set-area-affect-cloud-rotation.patch +++ b/patches/server/0505-Set-area-affect-cloud-rotation.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Set area affect cloud rotation diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java -index 9b2b0bbb1755b6be1c23cf56e29a68b0002fd755..481f0c62fcd4435d655cfe2f94f46262b24a7144 100644 +index 1c3aacda9242444c0c7bd92cb391e6fff963bb79..42ecef3dbb888ba716b6f63335efca6fb0f27457 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java -@@ -374,7 +374,7 @@ public final class CraftEntityTypes { +@@ -428,7 +428,7 @@ public final class CraftEntityTypes { register(new EntityTypeData<>(EntityType.EXPERIENCE_ORB, ExperienceOrb.class, CraftExperienceOrb::new, spawnData -> new net.minecraft.world.entity.ExperienceOrb(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), 0, org.bukkit.entity.ExperienceOrb.SpawnReason.CUSTOM, null, null) // Paper )); - register(new EntityTypeData<>(EntityType.AREA_EFFECT_CLOUD, AreaEffectCloud.class, CraftAreaEffectCloud::new, spawnData -> new net.minecraft.world.entity.AreaEffectCloud(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z()))); + register(new EntityTypeData<>(EntityType.AREA_EFFECT_CLOUD, AreaEffectCloud.class, CraftAreaEffectCloud::new, createAndMove(net.minecraft.world.entity.EntityType.AREA_EFFECT_CLOUD))); // Paper - set area effect cloud rotation - register(new EntityTypeData<>(EntityType.EGG, Egg.class, CraftEgg::new, spawnData -> new ThrownEgg(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z()))); + register(new EntityTypeData<>(EntityType.EGG, Egg.class, CraftEgg::new, spawnData -> new ThrownEgg(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), new net.minecraft.world.item.ItemStack(Items.EGG)))); register(new EntityTypeData<>(EntityType.LEASH_KNOT, LeashHitch.class, CraftLeash::new, spawnData -> new LeashFenceKnotEntity(spawnData.minecraftWorld(), BlockPos.containing(spawnData.x(), spawnData.y(), spawnData.z())))); // SPIGOT-5732: LeashHitch has no direction and is always centered at a block - register(new EntityTypeData<>(EntityType.SNOWBALL, Snowball.class, CraftSnowball::new, spawnData -> new net.minecraft.world.entity.projectile.Snowball(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z()))); + register(new EntityTypeData<>(EntityType.SNOWBALL, Snowball.class, CraftSnowball::new, spawnData -> new net.minecraft.world.entity.projectile.Snowball(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), new net.minecraft.world.item.ItemStack(Items.SNOWBALL)))); diff --git a/patches/unapplied/server/0510-add-isDeeplySleeping-to-HumanEntity.patch b/patches/server/0506-add-isDeeplySleeping-to-HumanEntity.patch similarity index 90% rename from patches/unapplied/server/0510-add-isDeeplySleeping-to-HumanEntity.patch rename to patches/server/0506-add-isDeeplySleeping-to-HumanEntity.patch index eaac6f65d83f..0bb00244804b 100644 --- a/patches/unapplied/server/0510-add-isDeeplySleeping-to-HumanEntity.patch +++ b/patches/server/0506-add-isDeeplySleeping-to-HumanEntity.patch @@ -5,7 +5,7 @@ Subject: [PATCH] add isDeeplySleeping to HumanEntity diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index 24aa891ffa9115c05439b06aece85df7a382b7c4..0222b6c68112551336f17a722fc3399898cdc7bb 100644 +index cb56c75be83e839bafdae4356f85d33499d01d8a..1e49eae80730aa9d2e49cd92759d899deb49fb90 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -132,6 +132,13 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { diff --git a/patches/unapplied/server/0511-add-consumeFuel-to-FurnaceBurnEvent.patch b/patches/server/0507-add-consumeFuel-to-FurnaceBurnEvent.patch similarity index 86% rename from patches/unapplied/server/0511-add-consumeFuel-to-FurnaceBurnEvent.patch rename to patches/server/0507-add-consumeFuel-to-FurnaceBurnEvent.patch index 1938dc07ed9f..7beadf8d5ca8 100644 --- a/patches/unapplied/server/0511-add-consumeFuel-to-FurnaceBurnEvent.patch +++ b/patches/server/0507-add-consumeFuel-to-FurnaceBurnEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] add consumeFuel to FurnaceBurnEvent diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index 84a3130a31f7a0fd5a8ae1b293dd3f2ca07c86d3..aa59a45bcbe652996eddb80a3187618b7f6d1234 100644 +index 2ec1c00eb77051c622fedec1ebeba2953886ace4..a23a87da259ab8d28dd8d8513098cd0730e72e0c 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -@@ -365,7 +365,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -255,7 +255,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit if (blockEntity.isLit() && furnaceBurnEvent.isBurning()) { // CraftBukkit end flag1 = true; diff --git a/patches/unapplied/server/0512-add-get-set-drop-chance-to-EntityEquipment.patch b/patches/server/0508-add-get-set-drop-chance-to-EntityEquipment.patch similarity index 97% rename from patches/unapplied/server/0512-add-get-set-drop-chance-to-EntityEquipment.patch rename to patches/server/0508-add-get-set-drop-chance-to-EntityEquipment.patch index 746b41078474..0b6de6ac3adf 100644 --- a/patches/unapplied/server/0512-add-get-set-drop-chance-to-EntityEquipment.patch +++ b/patches/server/0508-add-get-set-drop-chance-to-EntityEquipment.patch @@ -51,7 +51,7 @@ index cb704cef3845727c465fe3ea7210a11545da56c8..fdcc414f4fa246082ad0732133c870d9 } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java -index 23abd543cd8e3cbb49e4927aef59ed95d3465360..972fe4237461f07f78b60845b2ebfefb06698ded 100644 +index b6dbdabcf0fbf9fae8d995fef291ae0aaaa92d2c..5e40faa88c51b0ebd76493fd1731d16ca1051f4a 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java @@ -353,4 +353,15 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i diff --git a/patches/unapplied/server/0513-fix-PigZombieAngerEvent-cancellation.patch b/patches/server/0509-fix-PigZombieAngerEvent-cancellation.patch similarity index 95% rename from patches/unapplied/server/0513-fix-PigZombieAngerEvent-cancellation.patch rename to patches/server/0509-fix-PigZombieAngerEvent-cancellation.patch index 3f0d89aea9e3..040d076f37cf 100644 --- a/patches/unapplied/server/0513-fix-PigZombieAngerEvent-cancellation.patch +++ b/patches/server/0509-fix-PigZombieAngerEvent-cancellation.patch @@ -5,7 +5,7 @@ Subject: [PATCH] fix PigZombieAngerEvent cancellation diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java -index f4adf67392402faedd47c4a759fa2c13d85a1c26..10388cf33f6f33070aa84b3b2d7bd14fc50ceea8 100644 +index faaaee79e14adb62e810641ccc8f51428d39883d..03e3cbe73119ca76417d4dd192e1560bdfc373ec 100644 --- a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java @@ -56,6 +56,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { diff --git a/patches/unapplied/server/0514-fix-PlayerItemHeldEvent-firing-twice.patch b/patches/server/0510-fix-PlayerItemHeldEvent-firing-twice.patch similarity index 88% rename from patches/unapplied/server/0514-fix-PlayerItemHeldEvent-firing-twice.patch rename to patches/server/0510-fix-PlayerItemHeldEvent-firing-twice.patch index 9bb8e4f1e164..d089fabba84d 100644 --- a/patches/unapplied/server/0514-fix-PlayerItemHeldEvent-firing-twice.patch +++ b/patches/server/0510-fix-PlayerItemHeldEvent-firing-twice.patch @@ -5,10 +5,10 @@ Subject: [PATCH] fix PlayerItemHeldEvent firing twice diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 403b2499374906daa0ca2bb774522f92e186e6d5..276c0b017452a1d7b60a2a8e779f2f3fcf4960cc 100644 +index ed6c07cfa69788eb6adcaf8293b2ca2040f057a0..04fed7cee8ea816c194dc1d38f82c2c04d2abc23 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1933,6 +1933,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1946,6 +1946,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (this.player.isImmobile()) return; // CraftBukkit if (packet.getSlot() >= 0 && packet.getSlot() < Inventory.getSelectionSize()) { diff --git a/patches/unapplied/server/0515-Add-PlayerDeepSleepEvent.patch b/patches/server/0511-Add-PlayerDeepSleepEvent.patch similarity index 92% rename from patches/unapplied/server/0515-Add-PlayerDeepSleepEvent.patch rename to patches/server/0511-Add-PlayerDeepSleepEvent.patch index c348ba15bc5b..2f01c63a54ad 100644 --- a/patches/unapplied/server/0515-Add-PlayerDeepSleepEvent.patch +++ b/patches/server/0511-Add-PlayerDeepSleepEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerDeepSleepEvent diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index 513e6505706e64f9410fa190014976dc469793af..b444b24a92bd2209ee4104ae82c7cfa9c876c910 100644 +index 78bb666dbc5ccd84820e1c7b382249510dd5795c..57850f16a681af4fc302895c7608247675b44ab4 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java @@ -262,6 +262,13 @@ public abstract class Player extends LivingEntity { diff --git a/patches/unapplied/server/0516-More-World-API.patch b/patches/server/0512-More-World-API.patch similarity index 94% rename from patches/unapplied/server/0516-More-World-API.patch rename to patches/server/0512-More-World-API.patch index fde155962872..856b959ad86b 100644 --- a/patches/unapplied/server/0516-More-World-API.patch +++ b/patches/server/0512-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 f698ac90bd3086519f49e92451228415efaf5530..e882bc363f02b3acac489589e78b38468dfcaaa4 100644 +index 5541a9f197777124dd908e3f56050b49df821acc..48e47b5a21f49e9341f1e4d68b86507e2e924f2d 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2132,6 +2132,28 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2145,6 +2145,28 @@ public class CraftWorld extends CraftRegionAccessor implements World { return new CraftStructureSearchResult(CraftStructure.minecraftToBukkit(found.getSecond().value()), CraftLocation.toBukkit(found.getFirst(), this)); } diff --git a/patches/unapplied/server/0517-Add-PlayerBedFailEnterEvent.patch b/patches/server/0513-Add-PlayerBedFailEnterEvent.patch similarity index 91% rename from patches/unapplied/server/0517-Add-PlayerBedFailEnterEvent.patch rename to patches/server/0513-Add-PlayerBedFailEnterEvent.patch index feffef2aecf7..a592f428c225 100644 --- a/patches/unapplied/server/0517-Add-PlayerBedFailEnterEvent.patch +++ b/patches/server/0513-Add-PlayerBedFailEnterEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerBedFailEnterEvent diff --git a/src/main/java/net/minecraft/world/level/block/BedBlock.java b/src/main/java/net/minecraft/world/level/block/BedBlock.java -index 4eb1a77e2a85a242dd5342a500763d87dbe7655e..18b9a62613c08eb5bf63ae26565b0e91e1f44d39 100644 +index bee869b62af5fc845425458b713d1efaf8b28b51..b09fa473426a6c7e006a071827e5a68560d6c685 100644 --- a/src/main/java/net/minecraft/world/level/block/BedBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java -@@ -118,14 +118,23 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock +@@ -120,14 +120,23 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock BlockPos finalblockposition = pos; // CraftBukkit end player.startSleepInBed(pos).ifLeft((entityhuman_enumbedresult) -> { @@ -33,4 +33,4 @@ index 4eb1a77e2a85a242dd5342a500763d87dbe7655e..18b9a62613c08eb5bf63ae26565b0e91 + } // Paper - PlayerBedFailEnterEvent }); - return InteractionResult.SUCCESS; + return InteractionResult.SUCCESS_SERVER; diff --git a/patches/unapplied/server/0518-Implement-methods-to-convert-between-Component-and-B.patch b/patches/server/0514-Implement-methods-to-convert-between-Component-and-B.patch similarity index 94% rename from patches/unapplied/server/0518-Implement-methods-to-convert-between-Component-and-B.patch rename to patches/server/0514-Implement-methods-to-convert-between-Component-and-B.patch index 614386ecdece..648d3ec28515 100644 --- a/patches/unapplied/server/0518-Implement-methods-to-convert-between-Component-and-B.patch +++ b/patches/server/0514-Implement-methods-to-convert-between-Component-and-B.patch @@ -42,10 +42,10 @@ index 0000000000000000000000000000000000000000..dd6012b6a097575b2d1471be5069ecce + } +} diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 764395fe8e49d811294ca82887fee91ca6cd01fc..4057ade698a227b4f6efd3aa30b16d78c777be83 100644 +index 17b15bef9ad8edddc2e1f2a617a1ab4bd5b53347..cbff8de02006b65f6d58416fc0950741cc14908d 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -227,6 +227,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -226,6 +226,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now diff --git a/patches/unapplied/server/0519-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch b/patches/server/0515-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch similarity index 81% rename from patches/unapplied/server/0519-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch rename to patches/server/0515-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch index 7d836d530743..8ba5f2f2a0f6 100644 --- a/patches/unapplied/server/0519-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch +++ b/patches/server/0515-Expand-PlayerRespawnEvent-fix-passed-parameter-issue.patch @@ -6,12 +6,12 @@ Subject: [PATCH] Expand PlayerRespawnEvent, fix passed parameter issues Co-authored-by: Jake Potrebic diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index fffd3ae6c4fc0b86057cd915bb4f0987f41a64d0..52a5274fb811870481a48bf0505769d7ac5df31f 100644 +index 3a2a4f6bc1de45c0dc2020357ee308064666f8d5..262aa389b58708ed35ee88569be804c524f6e635 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1195,7 +1195,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1456,7 +1456,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { Player respawnPlayer = this.getBukkitEntity(); - Location location = CraftLocation.toBukkit(dimensionTransition.pos(), dimensionTransition.newLevel().getWorld(), dimensionTransition.yRot(), dimensionTransition.xRot()); + Location location = CraftLocation.toBukkit(teleportTransition.position(), teleportTransition.newLevel().getWorld(), teleportTransition.yRot(), teleportTransition.xRot()); - PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(respawnPlayer, location, isBedSpawn, isAnchorSpawn, reason); + // Paper start - respawn flags diff --git a/patches/unapplied/server/0520-Introduce-beacon-activation-deactivation-events.patch b/patches/server/0516-Introduce-beacon-activation-deactivation-events.patch similarity index 92% rename from patches/unapplied/server/0520-Introduce-beacon-activation-deactivation-events.patch rename to patches/server/0516-Introduce-beacon-activation-deactivation-events.patch index 6d74a805c199..336acbe811d8 100644 --- a/patches/unapplied/server/0520-Introduce-beacon-activation-deactivation-events.patch +++ b/patches/server/0516-Introduce-beacon-activation-deactivation-events.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Introduce beacon activation/deactivation events diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -index 52776ce9b7b4edd1eb474f14705d7fd83f5a66ca..e124f040386e130aebd7135434c4f06d130d28f6 100644 +index dc3171b1493d7c4c8ddf1c79587c4e27bd819c17..8aab6f68f576fb022eb59798585e264f5aafbc69 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java @@ -225,6 +225,15 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name @@ -23,7 +23,7 @@ index 52776ce9b7b4edd1eb474f14705d7fd83f5a66ca..e124f040386e130aebd7135434c4f06d + // Paper end - beacon activation/deactivation events if (blockEntity.lastCheckY >= l) { - blockEntity.lastCheckY = world.getMinBuildHeight() - 1; + blockEntity.lastCheckY = world.getMinY() - 1; @@ -282,6 +291,10 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name @Override diff --git a/patches/unapplied/server/0521-Add-Channel-initialization-listeners.patch b/patches/server/0517-Add-Channel-initialization-listeners.patch similarity index 100% rename from patches/unapplied/server/0521-Add-Channel-initialization-listeners.patch rename to patches/server/0517-Add-Channel-initialization-listeners.patch diff --git a/patches/unapplied/server/0522-Send-empty-commands-if-tab-completion-is-disabled.patch b/patches/server/0518-Send-empty-commands-if-tab-completion-is-disabled.patch similarity index 88% rename from patches/unapplied/server/0522-Send-empty-commands-if-tab-completion-is-disabled.patch rename to patches/server/0518-Send-empty-commands-if-tab-completion-is-disabled.patch index daa33fbefc81..58cea72f9bcf 100644 --- a/patches/unapplied/server/0522-Send-empty-commands-if-tab-completion-is-disabled.patch +++ b/patches/server/0518-Send-empty-commands-if-tab-completion-is-disabled.patch @@ -5,10 +5,10 @@ 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 f52e9732524b62b0fecdc48e099163f31fe367b4..c5c9fb28fe858e2900e43f8aafccddf63f09676e 100644 +index e38f1d972d87f33a5f28459aa988e09f24614453..7acd7f60327106d55e8f48247650bc0064dd1b58 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -448,7 +448,12 @@ public class Commands { +@@ -453,7 +453,12 @@ public class Commands { } public void sendCommands(ServerPlayer player) { diff --git a/patches/unapplied/server/0523-Add-more-WanderingTrader-API.patch b/patches/server/0519-Add-more-WanderingTrader-API.patch similarity index 93% rename from patches/unapplied/server/0523-Add-more-WanderingTrader-API.patch rename to patches/server/0519-Add-more-WanderingTrader-API.patch index 0ce65786dc8d..4221f2801547 100644 --- a/patches/unapplied/server/0523-Add-more-WanderingTrader-API.patch +++ b/patches/server/0519-Add-more-WanderingTrader-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add more WanderingTrader API diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java -index e51cb9c96e1bd13c00bf938436f4fc26d80055a1..856a93324f5ac411713851ccfb38dba52fb0af5e 100644 +index 8034588a9a87b907c35e28e220280d463f34554e..a65fba5621c067c453858efb7fee64cbee1e7916 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java -@@ -61,6 +61,10 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill +@@ -62,6 +62,10 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill @Nullable private BlockPos wanderTarget; private int despawnDelay; @@ -19,7 +19,7 @@ index e51cb9c96e1bd13c00bf938436f4fc26d80055a1..856a93324f5ac411713851ccfb38dba5 public WanderingTrader(EntityType type, Level world) { super(type, world); -@@ -71,10 +75,10 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill +@@ -72,10 +76,10 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); this.goalSelector.addGoal(0, new UseItemGoal<>(this, PotionContents.createItemStack(Items.POTION, Potions.INVISIBILITY), SoundEvents.WANDERING_TRADER_DISAPPEARED, (entityvillagertrader) -> { diff --git a/patches/unapplied/server/0524-Add-EntityBlockStorage-clearEntities.patch b/patches/server/0520-Add-EntityBlockStorage-clearEntities.patch similarity index 91% rename from patches/unapplied/server/0524-Add-EntityBlockStorage-clearEntities.patch rename to patches/server/0520-Add-EntityBlockStorage-clearEntities.patch index b19812d9899f..c37749bd5663 100644 --- a/patches/unapplied/server/0524-Add-EntityBlockStorage-clearEntities.patch +++ b/patches/server/0520-Add-EntityBlockStorage-clearEntities.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add EntityBlockStorage#clearEntities() diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java -index b345403cdf5b2828f99708fef65136594a3331c3..ef8a0236ab4fb648c4bb2a8cfc90e3cefe8f9f1d 100644 +index 0fab8826e14af9184f07bc1262555a71effcd84b..8224d5bddb7f7893dee09222a673af54791abcfa 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java -@@ -151,6 +151,11 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -152,6 +152,11 @@ public class BeehiveBlockEntity extends BlockEntity { return this.stored.size(); } diff --git a/patches/unapplied/server/0525-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch b/patches/server/0521-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch similarity index 90% rename from patches/unapplied/server/0525-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch rename to patches/server/0521-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch index c0fd5f11dbf4..9df7276feb98 100644 --- a/patches/unapplied/server/0525-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch +++ b/patches/server/0521-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add Adventure message to PlayerAdvancementDoneEvent diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java -index d85fb1e2ea0eaef81e9039b47d18f83507e05a59..9fabf9322acd663c4452b562494e74aa42eb19da 100644 +index 0fe941b0802f2966ad55509baac124f56ecef999..1dcb8a287be7df2a59b5b4c1345be80637a7f679 100644 --- a/src/main/java/net/minecraft/server/PlayerAdvancements.java +++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java @@ -236,11 +236,21 @@ public class PlayerAdvancements { @@ -24,10 +24,10 @@ index d85fb1e2ea0eaef81e9039b47d18f83507e05a59..9fabf9322acd663c4452b562494e74aa + // Paper end advancement.value().rewards().grant(this.player); advancement.value().display().ifPresent((advancementdisplay) -> { -- if (advancementdisplay.shouldAnnounceChat() && this.player.level().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) { +- if (advancementdisplay.shouldAnnounceChat() && this.player.serverLevel().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) { - this.playerList.broadcastSystemMessage(advancementdisplay.getType().createAnnouncement(advancement, this.player), false); + // Paper start - Add Adventure message to PlayerAdvancementDoneEvent -+ if (event.message() != null && this.player.level().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) { ++ if (event.message() != null && this.player.serverLevel().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) { + this.playerList.broadcastSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.message()), false); + // Paper end } diff --git a/patches/unapplied/server/0526-Add-HiddenPotionEffect-API.patch b/patches/server/0522-Add-HiddenPotionEffect-API.patch similarity index 100% rename from patches/unapplied/server/0526-Add-HiddenPotionEffect-API.patch rename to patches/server/0522-Add-HiddenPotionEffect-API.patch diff --git a/patches/unapplied/server/0527-Inventory-close.patch b/patches/server/0523-Inventory-close.patch similarity index 100% rename from patches/unapplied/server/0527-Inventory-close.patch rename to patches/server/0523-Inventory-close.patch diff --git a/patches/unapplied/server/0528-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch b/patches/server/0524-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch similarity index 91% rename from patches/unapplied/server/0528-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch rename to patches/server/0524-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch index d5f2f9db1f88..ca5b9a4b8ad0 100644 --- a/patches/unapplied/server/0528-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch +++ b/patches/server/0524-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add a "should burn in sunlight" API for Phantoms and diff --git a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java -index a5593ac33878efc970c1bdd6f636438d160e9d50..6627126ab02dbd5e9d1de6b186d75d850ef11280 100644 +index 723a098eabcc632caeb096f39c90e4e0581edc35..0cb179bc28cc863b09a079b37b957744f26f3e1d 100644 --- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java +++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java -@@ -93,9 +93,15 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo +@@ -95,9 +95,15 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo abstract SoundEvent getStepSound(); @@ -26,7 +26,7 @@ index a5593ac33878efc970c1bdd6f636438d160e9d50..6627126ab02dbd5e9d1de6b186d75d85 if (flag) { ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD); -@@ -232,7 +238,20 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo +@@ -236,7 +242,20 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo public void readAdditionalSaveData(CompoundTag nbt) { super.readAdditionalSaveData(nbt); this.reassessWeaponGoal(); @@ -48,10 +48,10 @@ index a5593ac33878efc970c1bdd6f636438d160e9d50..6627126ab02dbd5e9d1de6b186d75d85 @Override public void setItemSlot(EquipmentSlot slot, ItemStack stack) { diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java -index 4b3bec32921feb1dcf71abf5e8d34fcbbc59baf5..c277dac448a64809e93dd7a447ee3dc2a86c860e 100644 +index d0820b3a561db7e1e5667594b2b6ea13214dfa58..150fd890ac65097b5434fd88e8d2b24a89dca79a 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java +++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java -@@ -138,7 +138,7 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -139,7 +139,7 @@ public class Phantom extends FlyingMob implements Enemy { @Override public void aiStep() { @@ -60,7 +60,7 @@ index 4b3bec32921feb1dcf71abf5e8d34fcbbc59baf5..c277dac448a64809e93dd7a447ee3dc2 this.igniteForSeconds(8.0F); } -@@ -169,6 +169,9 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -165,6 +165,9 @@ public class Phantom extends FlyingMob implements Enemy { if (nbt.hasUUID("Paper.SpawningEntity")) { this.spawningEntity = nbt.getUUID("Paper.SpawningEntity"); } @@ -70,7 +70,7 @@ index 4b3bec32921feb1dcf71abf5e8d34fcbbc59baf5..c277dac448a64809e93dd7a447ee3dc2 // Paper end } -@@ -183,6 +186,7 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -179,6 +182,7 @@ public class Phantom extends FlyingMob implements Enemy { if (this.spawningEntity != null) { nbt.putUUID("Paper.SpawningEntity", this.spawningEntity); } diff --git a/patches/unapplied/server/0529-Add-basic-Datapack-API.patch b/patches/server/0525-Add-basic-Datapack-API.patch similarity index 96% rename from patches/unapplied/server/0529-Add-basic-Datapack-API.patch rename to patches/server/0525-Add-basic-Datapack-API.patch index f34fd37d42ab..7dda1478e1db 100644 --- a/patches/unapplied/server/0529-Add-basic-Datapack-API.patch +++ b/patches/server/0525-Add-basic-Datapack-API.patch @@ -176,10 +176,10 @@ index 0000000000000000000000000000000000000000..caa41c525d2b36b5a9f9942380f06c97 + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index a9c6f53c7e828a4b7d0cefbaa98e50ff1db9354a..a142c62a51ddf59e968c3ddb401dc137c4c07ef6 100644 +index dc20a383950a72aba5d056912d257912d3c0e808..d921b15100b83cb7073d79f2a1b2bfbdc7b745ca 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -305,6 +305,7 @@ public final class CraftServer implements Server { +@@ -308,6 +308,7 @@ public final class CraftServer implements Server { private final List playerView; public int reloadCount; public Set activeCompatibilities = Collections.emptySet(); @@ -187,7 +187,7 @@ index a9c6f53c7e828a4b7d0cefbaa98e50ff1db9354a..a142c62a51ddf59e968c3ddb401dc137 public static Exception excessiveVelEx; // Paper - Velocity warnings static { -@@ -390,6 +391,7 @@ public final class CraftServer implements Server { +@@ -393,6 +394,7 @@ public final class CraftServer implements Server { if (this.configuration.getBoolean("settings.use-map-color-cache")) { MapPalette.setMapColorCache(new CraftMapColorCache(this.logger)); } @@ -195,7 +195,7 @@ index a9c6f53c7e828a4b7d0cefbaa98e50ff1db9354a..a142c62a51ddf59e968c3ddb401dc137 } public boolean getCommandBlockOverride(String command) { -@@ -3008,5 +3010,11 @@ public final class CraftServer implements Server { +@@ -3027,5 +3029,11 @@ public final class CraftServer implements Server { public com.destroystokyo.paper.entity.ai.MobGoals getMobGoals() { return mobGoals; } diff --git a/patches/unapplied/server/0530-Add-environment-variable-to-disable-server-gui.patch b/patches/server/0526-Add-environment-variable-to-disable-server-gui.patch similarity index 90% rename from patches/unapplied/server/0530-Add-environment-variable-to-disable-server-gui.patch rename to patches/server/0526-Add-environment-variable-to-disable-server-gui.patch index e4de8ec4779d..5afe5fb870c6 100644 --- a/patches/unapplied/server/0530-Add-environment-variable-to-disable-server-gui.patch +++ b/patches/server/0526-Add-environment-variable-to-disable-server-gui.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add environment variable to disable server gui diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index ded1b7ab4ca1ae3a2d799fe31d05bd6a0c27dcb7..467b8ca8007c5d3a7b72b88e3a979bdf09f1a283 100644 +index 59d623dd45c395552ffd99e6fa744c0f71d94998..cf071610ed662c4a309cc26ee73a74fa490d846f 100644 --- a/src/main/java/net/minecraft/server/Main.java +++ b/src/main/java/net/minecraft/server/Main.java @@ -318,6 +318,7 @@ public class Main { diff --git a/patches/unapplied/server/0531-Expand-PlayerGameModeChangeEvent.patch b/patches/server/0527-Expand-PlayerGameModeChangeEvent.patch similarity index 89% rename from patches/unapplied/server/0531-Expand-PlayerGameModeChangeEvent.patch rename to patches/server/0527-Expand-PlayerGameModeChangeEvent.patch index 08394e448a18..af1d58d2f529 100644 --- a/patches/unapplied/server/0531-Expand-PlayerGameModeChangeEvent.patch +++ b/patches/server/0527-Expand-PlayerGameModeChangeEvent.patch @@ -45,10 +45,10 @@ index 7f09119bc7d661e08a960dd2bd46006efe752d3e..d1da3600dc07107309b20ebe6e7c0c4d } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 52a5274fb811870481a48bf0505769d7ac5df31f..42df8d45ceb963043cf6467b8fc47272ce0873da 100644 +index 262aa389b58708ed35ee88569be804c524f6e635..a022f0aee638bb12967b5fd20847fe20e6b286f3 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -2084,10 +2084,18 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2335,10 +2335,18 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } public boolean setGameMode(GameType gameMode) { @@ -69,7 +69,7 @@ index 52a5274fb811870481a48bf0505769d7ac5df31f..42df8d45ceb963043cf6467b8fc47272 } else { this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, (float) gameMode.getId())); if (gameMode == GameType.SPECTATOR) { -@@ -2103,7 +2111,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2354,7 +2362,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.onUpdateAbilities(); this.updateEffectVisibility(); @@ -78,7 +78,7 @@ index 52a5274fb811870481a48bf0505769d7ac5df31f..42df8d45ceb963043cf6467b8fc47272 } } -@@ -2509,6 +2517,16 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2806,6 +2814,16 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } public void loadGameTypes(@Nullable CompoundTag nbt) { @@ -96,10 +96,10 @@ index 52a5274fb811870481a48bf0505769d7ac5df31f..42df8d45ceb963043cf6467b8fc47272 } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index 5de472df78940d1b8320f73d18b2edf3a796227e..073cf184a0e7af41048ae67a9b17b4cdfcc43c35 100644 +index 546be40a8e4470fb5a6686072cdd342cdaa6fe15..e000a918230187f6841b03b7b0dd73687f3cc15e 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -74,14 +74,21 @@ public class ServerPlayerGameMode { +@@ -72,14 +72,21 @@ public class ServerPlayerGameMode { } public boolean changeGameModeForPlayer(GameType gameMode) { @@ -124,7 +124,7 @@ index 5de472df78940d1b8320f73d18b2edf3a796227e..073cf184a0e7af41048ae67a9b17b4cd } // CraftBukkit end this.setGameModeForPlayer(gameMode, this.previousGameModeForPlayer); -@@ -92,7 +99,7 @@ public class ServerPlayerGameMode { +@@ -90,7 +97,7 @@ public class ServerPlayerGameMode { this.player.resetCurrentImpulseContext(); } @@ -134,23 +134,23 @@ index 5de472df78940d1b8320f73d18b2edf3a796227e..073cf184a0e7af41048ae67a9b17b4cd } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 276c0b017452a1d7b60a2a8e779f2f3fcf4960cc..9781047aa5e0a6e6bc9f9c43a1eb347b6ecdff66 100644 +index 04fed7cee8ea816c194dc1d38f82c2c04d2abc23..e07f859a407bdf799bfd79f4bec3c7c4f505c4b8 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2730,7 +2730,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - +@@ -2746,7 +2746,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player = this.server.getPlayerList().respawn(this.player, false, Entity.RemovalReason.KILLED, RespawnReason.DEATH); // CraftBukkit + this.resetPosition(); if (this.server.isHardcore()) { - this.player.setGameMode(GameType.SPECTATOR); + this.player.setGameMode(GameType.SPECTATOR, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.HARDCORE_DEATH, null); // Paper - Expand PlayerGameModeChangeEvent - ((GameRules.BooleanValue) this.player.level().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS)).set(false, this.player.serverLevel()); // CraftBukkit - per-world + ((GameRules.BooleanValue) this.player.serverLevel().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS)).set(false, this.player.serverLevel()); // CraftBukkit - per-world } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 7de53f6750d478a052bc8ade6edac056565fe068..a85983b947147a1557908846b8773aab29c17fae 100644 +index 678099cdcf418b9e3eafed965384e6dcdd9404e3..b54b773a4e1472f94c5c28188f706fbeb2cfb067 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1654,7 +1654,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1667,7 +1667,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { Preconditions.checkArgument(mode != null, "GameMode cannot be null"); if (this.getHandle().connection == null) return; diff --git a/patches/unapplied/server/0532-ItemStack-repair-check-API.patch b/patches/server/0528-ItemStack-repair-check-API.patch similarity index 96% rename from patches/unapplied/server/0532-ItemStack-repair-check-API.patch rename to patches/server/0528-ItemStack-repair-check-API.patch index 75f490441ebf..14d115481919 100644 --- a/patches/unapplied/server/0532-ItemStack-repair-check-API.patch +++ b/patches/server/0528-ItemStack-repair-check-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] ItemStack repair check API diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 09fa524fa1155d53d988c15c1af551f73c96ede5..78d1b33a554ac8ca0f76585c6b97e35c2d337293 100644 +index 2f7cb2bd5998204d61c9d758224b3a2e3351de48..b791cb8c78b92163cf261a460b39b724e568013c 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -532,6 +532,14 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/unapplied/server/0533-More-Enchantment-API.patch b/patches/server/0529-More-Enchantment-API.patch similarity index 100% rename from patches/unapplied/server/0533-More-Enchantment-API.patch rename to patches/server/0529-More-Enchantment-API.patch diff --git a/patches/unapplied/server/0534-Move-range-check-for-block-placing-up.patch b/patches/server/0530-Move-range-check-for-block-placing-up.patch similarity index 88% rename from patches/unapplied/server/0534-Move-range-check-for-block-placing-up.patch rename to patches/server/0530-Move-range-check-for-block-placing-up.patch index 4269998b6e44..a6de02452f99 100644 --- a/patches/unapplied/server/0534-Move-range-check-for-block-placing-up.patch +++ b/patches/server/0530-Move-range-check-for-block-placing-up.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Move range check for block placing up diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 9781047aa5e0a6e6bc9f9c43a1eb347b6ecdff66..39e74591d3aaa7fecb0ed6f4213a5f4c60360b0e 100644 +index e07f859a407bdf799bfd79f4bec3c7c4f505c4b8..8080ef483a49bfeeaad8d69276684ee08198b1e9 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1745,6 +1745,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1749,6 +1749,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (itemstack.isItemEnabled(worldserver.enabledFeatures())) { BlockHitResult movingobjectpositionblock = packet.getHitResult(); Vec3 vec3d = movingobjectpositionblock.getLocation(); diff --git a/patches/unapplied/server/0535-Add-Mob-lookAt-API.patch b/patches/server/0531-Add-Mob-lookAt-API.patch similarity index 95% rename from patches/unapplied/server/0535-Add-Mob-lookAt-API.patch rename to patches/server/0531-Add-Mob-lookAt-API.patch index 3139490a6152..8a8ba9fdcd60 100644 --- a/patches/unapplied/server/0535-Add-Mob-lookAt-API.patch +++ b/patches/server/0531-Add-Mob-lookAt-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Mob#lookAt API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java -index 2a8596e4f9d7be966c18e867c2c7b5bfbea9742c..60d09655c5b8b9ff289291ee6badfb5aadf8533e 100644 +index c67673772c876dab7c015dcdfb75b297d3c4fbad..bd739428a7e5e35ebcdb70cd187379b3d222339b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java -@@ -96,5 +96,53 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob { +@@ -97,5 +97,53 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob { public boolean isInDaylight() { return getHandle().isSunBurnTick(); } diff --git a/patches/unapplied/server/0536-Correctly-check-if-bucket-dispenses-will-succeed-for.patch b/patches/server/0532-Correctly-check-if-bucket-dispenses-will-succeed-for.patch similarity index 93% rename from patches/unapplied/server/0536-Correctly-check-if-bucket-dispenses-will-succeed-for.patch rename to patches/server/0532-Correctly-check-if-bucket-dispenses-will-succeed-for.patch index 5a8b0c1cb53e..85ef521c40df 100644 --- a/patches/unapplied/server/0536-Correctly-check-if-bucket-dispenses-will-succeed-for.patch +++ b/patches/server/0532-Correctly-check-if-bucket-dispenses-will-succeed-for.patch @@ -8,10 +8,10 @@ in order to fire the BlockDispenseEvent. This patch corrects that. diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -index 32f06b29930906cdb6d3ceefa609c1a45518f80f..fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b 100644 +index c63a86af95849cacdfed3b061122b90651fd5bdf..5793569ae8a088f21b0d8d6771a5099b1e88be09 100644 --- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -405,7 +405,13 @@ public interface DispenseItemBehavior { +@@ -330,7 +330,13 @@ public interface DispenseItemBehavior { int y = blockposition.getY(); int z = blockposition.getZ(); BlockState iblockdata = worldserver.getBlockState(blockposition); diff --git a/patches/unapplied/server/0537-Add-Unix-domain-socket-support.patch b/patches/server/0533-Add-Unix-domain-socket-support.patch similarity index 95% rename from patches/unapplied/server/0537-Add-Unix-domain-socket-support.patch rename to patches/server/0533-Add-Unix-domain-socket-support.patch index 7c44f07cea27..de6a5f626d93 100644 --- a/patches/unapplied/server/0537-Add-Unix-domain-socket-support.patch +++ b/patches/server/0533-Add-Unix-domain-socket-support.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Unix domain socket support diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 4057ade698a227b4f6efd3aa30b16d78c777be83..adbd61c41cc30afa89c6ee3544c562b351304a01 100644 +index cbff8de02006b65f6d58416fc0950741cc14908d..e30a5ad17d7ba8bcec8911a72281830c419b0288 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -236,6 +236,20 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -235,6 +235,20 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface this.setEnforceWhitelist(dedicatedserverproperties.enforceWhitelist); // this.worldData.setGameType(dedicatedserverproperties.gamemode); // CraftBukkit - moved to world loading DedicatedServer.LOGGER.info("Default game type: {}", dedicatedserverproperties.gamemode); @@ -29,7 +29,7 @@ index 4057ade698a227b4f6efd3aa30b16d78c777be83..adbd61c41cc30afa89c6ee3544c562b3 InetAddress inetaddress = null; if (!this.getLocalIp().isEmpty()) { -@@ -245,12 +259,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -244,12 +258,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface if (this.getPort() < 0) { this.setPort(dedicatedserverproperties.serverPort); } @@ -87,10 +87,10 @@ index d6d7f1c446ba5507f67038ff27775ba75156f4a7..c63c194c44646e6bc1a5942655278701 } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 39e74591d3aaa7fecb0ed6f4213a5f4c60360b0e..568f5d7165521304c7a92f32984a1d605d545ad5 100644 +index 8080ef483a49bfeeaad8d69276684ee08198b1e9..7990bd0279839558bed18a3dca7739ef74ecb74a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2550,6 +2550,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2561,6 +2561,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Spigot Start public SocketAddress getRawAddress() { diff --git a/patches/unapplied/server/0538-Add-EntityInsideBlockEvent.patch b/patches/server/0534-Add-EntityInsideBlockEvent.patch similarity index 79% rename from patches/unapplied/server/0538-Add-EntityInsideBlockEvent.patch rename to patches/server/0534-Add-EntityInsideBlockEvent.patch index 0b2938737cb8..0009e3fbdfdc 100644 --- a/patches/unapplied/server/0538-Add-EntityInsideBlockEvent.patch +++ b/patches/server/0534-Add-EntityInsideBlockEvent.patch @@ -5,19 +5,19 @@ Subject: [PATCH] Add EntityInsideBlockEvent diff --git a/src/main/java/net/minecraft/world/level/block/BaseFireBlock.java b/src/main/java/net/minecraft/world/level/block/BaseFireBlock.java -index 779d188bac9744889c1f4f554b300311e0effa29..0c5409af685ef1f251db3d9f9e21295c82a1e02a 100644 +index 7f0811bc22d78cdc0aca4c6869c90252d8a59eed..c8ca41cd81a72f9bff40f5c1b3bfc1189bf51f98 100644 --- a/src/main/java/net/minecraft/world/level/block/BaseFireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BaseFireBlock.java -@@ -125,6 +125,7 @@ public abstract class BaseFireBlock extends Block { +@@ -128,6 +128,7 @@ public abstract class BaseFireBlock extends Block { @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent if (!entity.fireImmune()) { - entity.setRemainingFireTicks(entity.getRemainingFireTicks() + 1); - if (entity.getRemainingFireTicks() == 0) { + if (entity.getRemainingFireTicks() < 0) { + entity.setRemainingFireTicks(entity.getRemainingFireTicks() + 1); diff --git a/src/main/java/net/minecraft/world/level/block/BasePressurePlateBlock.java b/src/main/java/net/minecraft/world/level/block/BasePressurePlateBlock.java -index 2b6e126f57cf67cd719f67e925fee97b2485f73f..8b33e35c843e5c0b8988a2ef2a38a2673035292f 100644 +index cd3d9e69653afba51a55a3dfc6764b712b8df859..9afa811579ac2e556b5c5c23b3b49587439dfadc 100644 --- a/src/main/java/net/minecraft/world/level/block/BasePressurePlateBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BasePressurePlateBlock.java @@ -77,6 +77,7 @@ public abstract class BasePressurePlateBlock extends Block { @@ -29,10 +29,10 @@ index 2b6e126f57cf67cd719f67e925fee97b2485f73f..8b33e35c843e5c0b8988a2ef2a38a267 int i = this.getSignalForState(state); diff --git a/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java b/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java -index c1f020efdc5a1170fc43b2579531be8bdcacc83b..8240c32d676a88aa23dcd052ee0136767e54fb0d 100644 +index 87083f7de53e32713b54315803ccd414db2debc8..9e3f1441d62128535112621bf259c24f1a90595b 100644 --- a/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java -@@ -178,6 +178,7 @@ public class BigDripleafBlock extends HorizontalDirectionalBlock implements Bone +@@ -180,6 +180,7 @@ public class BigDripleafBlock extends HorizontalDirectionalBlock implements Bone @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { @@ -41,10 +41,10 @@ index c1f020efdc5a1170fc43b2579531be8bdcacc83b..8240c32d676a88aa23dcd052ee013676 if (state.getValue(BigDripleafBlock.TILT) == Tilt.NONE && BigDripleafBlock.canEntityTilt(pos, entity) && !world.hasNeighborSignal(pos)) { // CraftBukkit start - tilt dripleaf diff --git a/src/main/java/net/minecraft/world/level/block/BubbleColumnBlock.java b/src/main/java/net/minecraft/world/level/block/BubbleColumnBlock.java -index 7c70c98ee27a6a09e73942ff4dc0f88ceb77936f..4c1f20fafdbd86011959cc2d4983b6c2f8e87a5f 100644 +index c2d8caee4acb878aaa43c0cdc6f6a37555b69a12..385da0585f409ee453f10d45f5837cdc09adc21b 100644 --- a/src/main/java/net/minecraft/world/level/block/BubbleColumnBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BubbleColumnBlock.java -@@ -47,6 +47,7 @@ public class BubbleColumnBlock extends Block implements BucketPickup { +@@ -48,6 +48,7 @@ public class BubbleColumnBlock extends Block implements BucketPickup { @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { @@ -53,10 +53,10 @@ index 7c70c98ee27a6a09e73942ff4dc0f88ceb77936f..4c1f20fafdbd86011959cc2d4983b6c2 if (blockState.isAir()) { entity.onAboveBubbleCol(state.getValue(DRAG_DOWN)); diff --git a/src/main/java/net/minecraft/world/level/block/ButtonBlock.java b/src/main/java/net/minecraft/world/level/block/ButtonBlock.java -index 4a58bf1081e57bd34858481dee824e2a75120281..4c37d9ebd74b32b9ad6dc46d000afc7a7d1bb4a3 100644 +index e210c210b733fc968b9c3816bb1f9755d76660ef..061a8f8b58d9fa7959333e2f59d3b7ee03cbf92d 100644 --- a/src/main/java/net/minecraft/world/level/block/ButtonBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ButtonBlock.java -@@ -206,6 +206,7 @@ public class ButtonBlock extends FaceAttachedHorizontalDirectionalBlock { +@@ -208,6 +208,7 @@ public class ButtonBlock extends FaceAttachedHorizontalDirectionalBlock { @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { @@ -65,10 +65,10 @@ index 4a58bf1081e57bd34858481dee824e2a75120281..4c37d9ebd74b32b9ad6dc46d000afc7a this.checkPressed(state, world, pos); } diff --git a/src/main/java/net/minecraft/world/level/block/CactusBlock.java b/src/main/java/net/minecraft/world/level/block/CactusBlock.java -index fd344c5cf0d6d523abe34d5e3f8d939106942cbb..ff4dda48116a2969704b355ff96407ba869b466e 100644 +index de1b64e0cbe7f2de63f04262428c9e6ec340916e..c045b1cccf0047dbef8c04d5a28d31d53389054f 100644 --- a/src/main/java/net/minecraft/world/level/block/CactusBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CactusBlock.java -@@ -121,6 +121,7 @@ public class CactusBlock extends Block { +@@ -122,6 +122,7 @@ public class CactusBlock extends Block { @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { @@ -77,10 +77,10 @@ index fd344c5cf0d6d523abe34d5e3f8d939106942cbb..ff4dda48116a2969704b355ff96407ba } diff --git a/src/main/java/net/minecraft/world/level/block/CampfireBlock.java b/src/main/java/net/minecraft/world/level/block/CampfireBlock.java -index e81bf62cf9dbc27391deaad46d2098e81f746746..7f6058f4def83867971121751acd51c398583651 100644 +index 1cc807a7a73ea35919259d7d8370fa3bcc44fb2f..18d4020017d76303d3179fad8974574777ea6305 100644 --- a/src/main/java/net/minecraft/world/level/block/CampfireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CampfireBlock.java -@@ -104,6 +104,7 @@ public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedB +@@ -112,6 +112,7 @@ public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedB @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { @@ -89,7 +89,7 @@ index e81bf62cf9dbc27391deaad46d2098e81f746746..7f6058f4def83867971121751acd51c3 entity.hurt(world.damageSources().campfire().directBlock(world, pos), (float) this.fireDamage); // CraftBukkit } diff --git a/src/main/java/net/minecraft/world/level/block/CropBlock.java b/src/main/java/net/minecraft/world/level/block/CropBlock.java -index fcaf6b4bb7371ce9f00a7d4306f7b2b6884b7c4c..73595922dcff8e7a8595fcf033ab238bc4096630 100644 +index 93c9f093eef0568a3816412fa497c12487ff04e3..79ebc37a779bf6cba66a34a7604f819e95fd86a2 100644 --- a/src/main/java/net/minecraft/world/level/block/CropBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CropBlock.java @@ -174,6 +174,7 @@ public class CropBlock extends BushBlock implements BonemealableBlock { @@ -97,14 +97,14 @@ index fcaf6b4bb7371ce9f00a7d4306f7b2b6884b7c4c..73595922dcff8e7a8595fcf033ab238b @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (entity instanceof Ravager && CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit - world.destroyBlock(pos, true, entity); - } + if (world instanceof ServerLevel worldserver) { + if (entity instanceof Ravager && CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit + worldserver.destroyBlock(pos, true, entity); diff --git a/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java b/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java -index 55a97da8786ec0ae98abe56876c00f4678ba0007..9d69e439ff853465303c2abd896e6c5314752e1e 100644 +index 1e2f56b5c40c3dc72bc38354160f8e7de1f4f5cf..fa1c4defd0d4e4cd888eb26eed131539d0ed573f 100644 --- a/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java -@@ -51,6 +51,7 @@ public class DetectorRailBlock extends BaseRailBlock { +@@ -52,6 +52,7 @@ public class DetectorRailBlock extends BaseRailBlock { @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { @@ -113,10 +113,10 @@ index 55a97da8786ec0ae98abe56876c00f4678ba0007..9d69e439ff853465303c2abd896e6c53 if (!(Boolean) state.getValue(DetectorRailBlock.POWERED)) { this.checkPressed(world, pos, state); diff --git a/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java -index 2ad77d7666cc9a5101b3da58f07f497409676a26..11486419dd98a013c7387d3d73f322a95a18c574 100644 +index ae32d7819ee45d6d334be19c78f8150d104fb787..bb4800c60ac05f2db8821737b2b884ea99b64799 100644 --- a/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java +++ b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java -@@ -90,6 +90,7 @@ public class EndGatewayBlock extends BaseEntityBlock implements Portal { +@@ -92,6 +92,7 @@ public class EndGatewayBlock extends BaseEntityBlock implements Portal { @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { @@ -125,22 +125,22 @@ index 2ad77d7666cc9a5101b3da58f07f497409676a26..11486419dd98a013c7387d3d73f322a9 BlockEntity tileentity = world.getBlockEntity(pos); diff --git a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java -index a9c7a74b38a57c118c1ad67a77ba6f2e5c05d91e..28fba1448309805fc3d687de6bc8454d2c85fcd3 100644 +index 5744944455b08d45a7c0fe2289414b50b6c0d66a..6ed6c2123ed4c54f191ed8cf6da72109fb95eb69 100644 --- a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java +++ b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java -@@ -63,6 +63,7 @@ public class EndPortalBlock extends BaseEntityBlock implements Portal { +@@ -68,6 +68,7 @@ public class EndPortalBlock extends BaseEntityBlock implements Portal { @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (entity.canUsePortal(false) && Shapes.joinIsNotEmpty(Shapes.create(entity.getBoundingBox().move((double) (-pos.getX()), (double) (-pos.getY()), (double) (-pos.getZ()))), state.getShape(world, pos), BooleanOp.AND)) { + if (entity.canUsePortal(false)) { // CraftBukkit start - Entity in portal EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ())); diff --git a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java -index b968129b9a93fdf771caba5f768456070543ba6a..669234bca9fa50548447f77dc5f314df8d9dd7c9 100644 +index aee71779f31def5f1ef7438cf06219d1de7092ec..34be6b349722240e99f91d28067578aa0b4bd1fe 100644 --- a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java -@@ -79,6 +79,7 @@ public class FrogspawnBlock extends Block { +@@ -89,6 +89,7 @@ public class FrogspawnBlock extends Block { @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { @@ -149,7 +149,7 @@ index b968129b9a93fdf771caba5f768456070543ba6a..669234bca9fa50548447f77dc5f314df this.destroyBlock(world, pos); } diff --git a/src/main/java/net/minecraft/world/level/block/HoneyBlock.java b/src/main/java/net/minecraft/world/level/block/HoneyBlock.java -index 1ed883c62be357d32365ef182e391e96172d2b56..c6f7815b5fad3aad4635208aa2e5c6739e13cb45 100644 +index 3ddf43a8afe8f00ca910d7838356dfc6d007a4f9..5c360c6768582c1a35431739613e9b406875cc21 100644 --- a/src/main/java/net/minecraft/world/level/block/HoneyBlock.java +++ b/src/main/java/net/minecraft/world/level/block/HoneyBlock.java @@ -60,6 +60,7 @@ public class HoneyBlock extends HalfTransparentBlock { @@ -161,10 +161,10 @@ index 1ed883c62be357d32365ef182e391e96172d2b56..c6f7815b5fad3aad4635208aa2e5c673 this.maybeDoSlideAchievement(entity, pos); this.doSlideMovement(entity); diff --git a/src/main/java/net/minecraft/world/level/block/HopperBlock.java b/src/main/java/net/minecraft/world/level/block/HopperBlock.java -index 089ead2d55c4fbe361255391f553822715269c38..86e5617d445ce762aa374e236a0ccdfe5901fce5 100644 +index 19ace6115a80f2696746bd98a5465259e4f1a633..b61324fe162f32817b87e4adb80df57b9433259f 100644 --- a/src/main/java/net/minecraft/world/level/block/HopperBlock.java +++ b/src/main/java/net/minecraft/world/level/block/HopperBlock.java -@@ -187,6 +187,7 @@ public class HopperBlock extends BaseEntityBlock { +@@ -183,6 +183,7 @@ public class HopperBlock extends BaseEntityBlock { @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { @@ -185,22 +185,22 @@ index 7bf2c33a194517d4e52511fe32a8434cbed0361f..d29a62775913922ffb8e3c58ae0db7e3 entity.lavaHurt(); } diff --git a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java -index 5f778ea22efa76ced1ba4455d50b94b3519113fc..7c67efa6e344870b764eb39d5508190349e2e911 100644 +index c088d713e80f16ead333ea5283f7f95a2de08523..4ab73a083eba2ad3e12526af0a0dbcfba5cf6c14 100644 --- a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java +++ b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java -@@ -66,6 +66,7 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock { +@@ -67,6 +67,7 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock { @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (!world.isClientSide && entity.isOnFire() && this.isEntityInsideContent(state, pos, entity)) { - // CraftBukkit start - if (entity.mayInteract(world, pos)) { + if (world instanceof ServerLevel worldserver) { + if (entity.isOnFire() && this.isEntityInsideContent(state, pos, entity)) { + // CraftBukkit start - moved down diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java -index a4e1c878dc7677e8ccc7c568ab455e85513d86cb..e2969b49494c55c3705312361ee8083b05ef569e 100644 +index dea13596eb8a3b7bc69c19545b2227b4c45ed241..c00507fa7af579263caed67dafc2ea9eba09512b 100644 --- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java -@@ -107,6 +107,7 @@ public class NetherPortalBlock extends Block implements Portal { +@@ -115,6 +115,7 @@ public class NetherPortalBlock extends Block implements Portal { @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { @@ -209,22 +209,22 @@ index a4e1c878dc7677e8ccc7c568ab455e85513d86cb..e2969b49494c55c3705312361ee8083b // CraftBukkit start - Entity in portal EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ())); diff --git a/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java b/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java -index 15696602249465fa1d13eaec3b8b06574ec06f07..c9ed129db2cadd0a33d69993961f43088725c3cb 100644 +index 3825b25c7417e4c2e5a25154879199b155a4921f..972d8833127090c01d620cab10b3eca3d3601710 100644 --- a/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java -@@ -98,6 +98,7 @@ public class PitcherCropBlock extends DoublePlantBlock implements BonemealableBl +@@ -107,6 +107,7 @@ public class PitcherCropBlock extends DoublePlantBlock implements BonemealableBl @Override public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (entity instanceof Ravager && world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { - world.destroyBlock(pos, true, entity); + if (world instanceof ServerLevel serverLevel && entity instanceof Ravager && serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { + serverLevel.destroyBlock(pos, true, entity); } diff --git a/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java b/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java -index 1f9cab69fb19c96fb01fff0d7a5ecfdfff46a5d4..a6e6545402904141ffc6218a0158b0e9c67217c8 100644 +index aaf9350a096022c87ccb788d657c1ae6a7b53a47..53f1a7ed6b4bd6e2d8460531226aabf249994c02 100644 --- a/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java -@@ -63,6 +63,7 @@ public class PowderSnowBlock extends Block implements BucketPickup { +@@ -59,6 +59,7 @@ public class PowderSnowBlock extends Block implements BucketPickup { @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { @@ -233,41 +233,41 @@ index 1f9cab69fb19c96fb01fff0d7a5ecfdfff46a5d4..a6e6545402904141ffc6218a0158b0e9 entity.makeStuckInBlock(state, new Vec3(0.8999999761581421D, 1.5D, 0.8999999761581421D)); if (world.isClientSide) { diff --git a/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java b/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java -index 49fce6000ffafc6f53767c971db951b20261b91d..6008c634c408c4eed563815da4d57b2eef69835c 100644 +index 3cd04097fc698d29d395c0ee28aadaec7c87b5a2..d61173ae5818fe6b507823fd9ddc0584cd5809b9 100644 --- a/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java -@@ -85,6 +85,7 @@ public class SweetBerryBushBlock extends BushBlock implements BonemealableBlock +@@ -84,6 +84,7 @@ public class SweetBerryBushBlock extends BushBlock implements BonemealableBlock @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent if (entity instanceof LivingEntity && entity.getType() != EntityType.FOX && entity.getType() != EntityType.BEE) { entity.makeStuckInBlock(state, new Vec3(0.800000011920929D, 0.75D, 0.800000011920929D)); - if (!world.isClientSide && (Integer) state.getValue(SweetBerryBushBlock.AGE) > 0 && (entity.xOld != entity.getX() || entity.zOld != entity.getZ())) { + if (world instanceof ServerLevel) { diff --git a/src/main/java/net/minecraft/world/level/block/TripWireBlock.java b/src/main/java/net/minecraft/world/level/block/TripWireBlock.java -index 65b30286020b65e23d05307aade344cde827fcf2..e032d8907045c653c3dd449f65e93e40fd0bb6be 100644 +index 93777f83cdd2de30ccf597fadd8418853954d1ce..f079e5a9aa098225acf09ed9b4aa7ddbc2381270 100644 --- a/src/main/java/net/minecraft/world/level/block/TripWireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TripWireBlock.java -@@ -135,6 +135,7 @@ public class TripWireBlock extends Block { +@@ -141,6 +141,7 @@ public class TripWireBlock extends Block { @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent if (!world.isClientSide) { if (!(Boolean) state.getValue(TripWireBlock.POWERED)) { - this.checkPressed(world, pos); + this.checkPressed(world, pos, List.of(entity)); diff --git a/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java b/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java -index 7f5e092e400c3a8422b677ca246031a945a0d359..edc20745649b0837f1371c8d29e71fc0c8e5528f 100644 +index 34599b88011aff718f5a6373229489ea3d947ff7..674d710ff88db5eced9e017284d1b7ec7a4fe7cd 100644 --- a/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java +++ b/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java -@@ -34,6 +34,7 @@ public class WaterlilyBlock extends BushBlock { +@@ -33,6 +33,7 @@ public class WaterlilyBlock extends BushBlock { + @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { - super.entityInside(state, world, pos, entity); + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (world instanceof ServerLevel && entity instanceof Boat) { + super.entityInside(state, world, pos, entity); + if (world instanceof ServerLevel && entity instanceof AbstractBoat) { // CraftBukkit start - if (!CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState())) { diff --git a/src/main/java/net/minecraft/world/level/block/WebBlock.java b/src/main/java/net/minecraft/world/level/block/WebBlock.java index 4b621793da3d6fbc44f90df863b099ba992930fb..fc209fab3ed1ccb35706a5529ec23ad8b902e491 100644 --- a/src/main/java/net/minecraft/world/level/block/WebBlock.java @@ -281,14 +281,14 @@ index 4b621793da3d6fbc44f90df863b099ba992930fb..fc209fab3ed1ccb35706a5529ec23ad8 if (entity instanceof LivingEntity livingEntity && livingEntity.hasEffect(MobEffects.WEAVING)) { vec3 = new Vec3(0.5, 0.25, 0.5); diff --git a/src/main/java/net/minecraft/world/level/block/WitherRoseBlock.java b/src/main/java/net/minecraft/world/level/block/WitherRoseBlock.java -index e861cf48aae27a8299437d76f6a84336cdcaddb7..3445916c2915b42967eb396b50b62d1912e3a49f 100644 +index 2f67e26b4c030c1747346f6d02076bd21f11d32e..b481d67e3646242b8eb1b9890e09b56b9406fecb 100644 --- a/src/main/java/net/minecraft/world/level/block/WitherRoseBlock.java +++ b/src/main/java/net/minecraft/world/level/block/WitherRoseBlock.java -@@ -62,6 +62,7 @@ public class WitherRoseBlock extends FlowerBlock { +@@ -63,6 +63,7 @@ public class WitherRoseBlock extends FlowerBlock { @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (!world.isClientSide && world.getDifficulty() != Difficulty.PEACEFUL) { - if (entity instanceof LivingEntity) { - LivingEntity entityliving = (LivingEntity) entity; + if (world instanceof ServerLevel worldserver) { + if (world.getDifficulty() != Difficulty.PEACEFUL && entity instanceof LivingEntity entityliving) { + if (!entityliving.isInvulnerableTo(worldserver, world.damageSources().wither())) { diff --git a/patches/unapplied/server/0539-Improve-item-default-attribute-API.patch b/patches/server/0535-Improve-item-default-attribute-API.patch similarity index 92% rename from patches/unapplied/server/0539-Improve-item-default-attribute-API.patch rename to patches/server/0535-Improve-item-default-attribute-API.patch index 9cb4f56ce338..3eca60ef25d1 100644 --- a/patches/unapplied/server/0539-Improve-item-default-attribute-API.patch +++ b/patches/server/0535-Improve-item-default-attribute-API.patch @@ -19,10 +19,10 @@ index de0eba19c0c963adb4f17cea22333240021fd801..3b171a08bd0bedfe224905feb5838d25 } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java -index 66d773cadb74f9176e6cf68a565568034f52ec63..a1f2b9d40d374e8cdbaf916b25fa74b6c0970f81 100644 +index 68756419ac6ee292db9569eab380a5c14d748002..6d76cc1db3ac3f1ae74c13511937fb86082a0b3d 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java -@@ -197,19 +197,36 @@ public class CraftItemType implements ItemType.Typed, Han +@@ -197,16 +197,33 @@ public class CraftItemType implements ItemType.Typed, Han // return CraftEquipmentSlot.getSlot(EntityInsentient.getEquipmentSlotForItem(CraftItemStack.asNMSCopy(ItemStack.of(this)))); // } @@ -45,9 +45,6 @@ index 66d773cadb74f9176e6cf68a565568034f52ec63..a1f2b9d40d374e8cdbaf916b25fa74b6 ImmutableMultimap.Builder defaultAttributes = ImmutableMultimap.builder(); ItemAttributeModifiers nmsDefaultAttributes = this.item.components().getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY); - if (nmsDefaultAttributes.modifiers().isEmpty()) { - nmsDefaultAttributes = this.item.getDefaultAttributeModifiers(); - } - - nmsDefaultAttributes.forEach(CraftEquipmentSlot.getNMS(slot), (key, value) -> { - Attribute attribute = CraftAttribute.minecraftToBukkit(key.value()); @@ -65,7 +62,7 @@ index 66d773cadb74f9176e6cf68a565568034f52ec63..a1f2b9d40d374e8cdbaf916b25fa74b6 return defaultAttributes.build(); } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 78d1b33a554ac8ca0f76585c6b97e35c2d337293..5e8081350b2ec375373d8197bd1f3196652ec9d9 100644 +index b791cb8c78b92163cf261a460b39b724e568013c..821f9a2780dc6fa9926fadbec18b51a915767730 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -391,7 +391,11 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/unapplied/server/0540-Add-cause-to-Weather-ThunderChangeEvents.patch b/patches/server/0536-Add-cause-to-Weather-ThunderChangeEvents.patch similarity index 90% rename from patches/unapplied/server/0540-Add-cause-to-Weather-ThunderChangeEvents.patch rename to patches/server/0536-Add-cause-to-Weather-ThunderChangeEvents.patch index f1396c14e285..c5a830259732 100644 --- a/patches/unapplied/server/0540-Add-cause-to-Weather-ThunderChangeEvents.patch +++ b/patches/server/0536-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 b877884ef4adf82d5ca9c56277ef27a79773b711..08d25d41641cd031d2d84843268b13e650d8fb00 100644 +index d696ec118367f64fa7151189a4ace58287329851..355b60f8d0d600973da673db5a954345f3a0094d 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -441,8 +441,8 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -431,8 +431,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.serverLevelData.setClearWeatherTime(clearDuration); this.serverLevelData.setRainTime(rainDuration); this.serverLevelData.setThunderTime(rainDuration); @@ -19,7 +19,7 @@ index b877884ef4adf82d5ca9c56277ef27a79773b711..08d25d41641cd031d2d84843268b13e6 } @Override -@@ -875,8 +875,8 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -862,8 +862,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.serverLevelData.setThunderTime(j); this.serverLevelData.setRainTime(k); this.serverLevelData.setClearWeatherTime(i); @@ -30,7 +30,7 @@ index b877884ef4adf82d5ca9c56277ef27a79773b711..08d25d41641cd031d2d84843268b13e6 } this.oThunderLevel = this.thunderLevel; -@@ -943,14 +943,14 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -930,14 +930,14 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @VisibleForTesting public void resetWeatherCycle() { // CraftBukkit start @@ -48,7 +48,7 @@ index b877884ef4adf82d5ca9c56277ef27a79773b711..08d25d41641cd031d2d84843268b13e6 // If we stop due to everyone sleeping we should reset the weather duration to some other random value. // Not that everyone ever manages to get the whole server to sleep at the same time.... diff --git a/src/main/java/net/minecraft/world/level/storage/PrimaryLevelData.java b/src/main/java/net/minecraft/world/level/storage/PrimaryLevelData.java -index e50ad48658193f889d65d37c57b1e30ce46758b7..efd0bcfebb3b4f63018d4e20a6a89f79192898d1 100644 +index 6a3959095e57f76b3a092b32d26ff91cf1c5e068..0fa16ff37f09ecfda104b751e48bf246820afc98 100644 --- a/src/main/java/net/minecraft/world/level/storage/PrimaryLevelData.java +++ b/src/main/java/net/minecraft/world/level/storage/PrimaryLevelData.java @@ -337,6 +337,11 @@ public class PrimaryLevelData implements ServerLevelData, WorldData { @@ -95,10 +95,10 @@ index e50ad48658193f889d65d37c57b1e30ce46758b7..efd0bcfebb3b4f63018d4e20a6a89f79 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 e882bc363f02b3acac489589e78b38468dfcaaa4..1cafba435f53762cd5790998b0d96e1e743612b5 100644 +index 48e47b5a21f49e9341f1e4d68b86507e2e924f2d..5948e80ad35b9b12d6eded02549bf17be7de1fa7 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -1210,7 +1210,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1220,7 +1220,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setStorm(boolean hasStorm) { @@ -107,7 +107,7 @@ index e882bc363f02b3acac489589e78b38468dfcaaa4..1cafba435f53762cd5790998b0d96e1e this.setWeatherDuration(0); // Reset weather duration (legacy behaviour) this.setClearWeatherDuration(0); // Reset clear weather duration (reset "/weather clear" commands) } -@@ -1232,7 +1232,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1242,7 +1242,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setThundering(boolean thundering) { diff --git a/patches/unapplied/server/0541-More-Lidded-Block-API.patch b/patches/server/0537-More-Lidded-Block-API.patch similarity index 100% rename from patches/unapplied/server/0541-More-Lidded-Block-API.patch rename to patches/server/0537-More-Lidded-Block-API.patch diff --git a/patches/unapplied/server/0542-Limit-item-frame-cursors-on-maps.patch b/patches/server/0538-Limit-item-frame-cursors-on-maps.patch similarity index 89% rename from patches/unapplied/server/0542-Limit-item-frame-cursors-on-maps.patch rename to patches/server/0538-Limit-item-frame-cursors-on-maps.patch index d710b596857f..a55a4490c0e5 100644 --- a/patches/unapplied/server/0542-Limit-item-frame-cursors-on-maps.patch +++ b/patches/server/0538-Limit-item-frame-cursors-on-maps.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Limit item frame cursors on maps diff --git a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java -index d6a0a882331226c3ae4ced09e449eb7931740f8f..a43544704109f21bab230dd9bf0401e28f878582 100644 +index a89f0b652c515efbc24ffc9af47fa65082946e54..2d5e7380e8a14cbc01ba48cd05deccc0c7f53430 100644 --- a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java +++ b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java -@@ -322,8 +322,10 @@ public class MapItemSavedData extends SavedData { +@@ -326,8 +326,10 @@ public class MapItemSavedData extends SavedData { MapFrame worldmapframe1 = new MapFrame(blockposition, entityitemframe.getDirection().get2DDataValue() * 90, entityitemframe.getId()); @@ -19,7 +19,7 @@ index d6a0a882331226c3ae4ced09e449eb7931740f8f..a43544704109f21bab230dd9bf0401e2 } MapDecorations mapdecorations = (MapDecorations) stack.getOrDefault(DataComponents.MAP_DECORATIONS, MapDecorations.EMPTY); -@@ -488,7 +490,7 @@ public class MapItemSavedData extends SavedData { +@@ -520,7 +522,7 @@ public class MapItemSavedData extends SavedData { return true; } diff --git a/patches/unapplied/server/0543-Add-PlayerKickEvent-causes.patch b/patches/server/0539-Add-PlayerKickEvent-causes.patch similarity index 90% rename from patches/unapplied/server/0543-Add-PlayerKickEvent-causes.patch rename to patches/server/0539-Add-PlayerKickEvent-causes.patch index 62954e6153eb..16f523acdd20 100644 --- a/patches/unapplied/server/0543-Add-PlayerKickEvent-causes.patch +++ b/patches/server/0539-Add-PlayerKickEvent-causes.patch @@ -43,10 +43,10 @@ index dbcf183483766f39334d7f7e8336033906625f3f..300929a406905f5ff1ede664d5b99fb0 } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 6651afa50cfaf53959f89108904d4bf65a0fc495..56589fee8dd09783e01f2ae290ffacb5dff3f05f 100644 +index 42429684bd732d0094ad0db346d2a656871aabff..7e1b74547c691de5fa2fac6e515394e267c57036 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2286,7 +2286,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { @@ -118,7 +118,7 @@ index a1124405412cdac673f34a63988e7be957506dba..64450024ce8094874875321537ddab71 }); // Paper end - This needs to be handled on the main thread for plugins } -@@ -169,7 +169,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -176,7 +176,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } } catch (Exception ex) { ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t register custom payload", ex); @@ -127,7 +127,7 @@ index a1124405412cdac673f34a63988e7be957506dba..64450024ce8094874875321537ddab71 } } else if (identifier.equals(ServerCommonPacketListenerImpl.CUSTOM_UNREGISTER)) { try { -@@ -179,7 +179,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -186,7 +186,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } } catch (Exception ex) { ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t unregister custom payload", ex); @@ -136,7 +136,7 @@ index a1124405412cdac673f34a63988e7be957506dba..64450024ce8094874875321537ddab71 } } else { try { -@@ -197,7 +197,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -204,7 +204,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack this.cserver.getMessenger().dispatchIncomingMessage(this.player.getBukkitEntity(), identifier.toString(), data); } catch (Exception ex) { ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t dispatch custom payload", ex); @@ -145,7 +145,7 @@ index a1124405412cdac673f34a63988e7be957506dba..64450024ce8094874875321537ddab71 } } -@@ -213,7 +213,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -220,7 +220,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack PacketUtils.ensureRunningOnSameThread(packet, this, (BlockableEventLoop) this.server); if (packet.action() == ServerboundResourcePackPacket.Action.DECLINED && this.server.isResourcePackRequired()) { ServerCommonPacketListenerImpl.LOGGER.info("Disconnecting {} due to resource pack {} rejection", this.playerProfile().getName(), packet.id()); @@ -154,7 +154,7 @@ index a1124405412cdac673f34a63988e7be957506dba..64450024ce8094874875321537ddab71 } // Paper start - adventure pack callbacks // call the callbacks before the previously-existing event so the event has final say -@@ -243,7 +243,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -250,7 +250,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack return; } // CraftBukkit end @@ -163,7 +163,7 @@ index a1124405412cdac673f34a63988e7be957506dba..64450024ce8094874875321537ddab71 } protected void keepConnectionAlive() { -@@ -255,7 +255,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -262,7 +262,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack if (!this.isSingleplayerOwner() && elapsedTime >= 15000L) { // Paper - use vanilla's 15000L between keep alive packets if (this.keepAlivePending && !this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // Paper - check keepalive limit, don't fire if already disconnected @@ -172,7 +172,7 @@ index a1124405412cdac673f34a63988e7be957506dba..64450024ce8094874875321537ddab71 } else if (this.checkIfClosed(currentTime)) { // Paper this.keepAlivePending = true; this.keepAliveTime = currentTime; -@@ -271,7 +271,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -278,7 +278,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack private boolean checkIfClosed(long time) { if (this.closed) { if (time - this.closedListenerTime >= 15000L) { @@ -181,7 +181,7 @@ index a1124405412cdac673f34a63988e7be957506dba..64450024ce8094874875321537ddab71 } return false; -@@ -323,15 +323,25 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -330,15 +330,25 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack // Paper start - adventure public void disconnect(final net.kyori.adventure.text.Component reason) { @@ -210,7 +210,7 @@ index a1124405412cdac673f34a63988e7be957506dba..64450024ce8094874875321537ddab71 // CraftBukkit start - fire PlayerKickEvent if (this.processedDisconnect) { return; -@@ -340,7 +350,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -347,7 +357,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack Waitable waitable = new Waitable() { @Override protected Object evaluate() { @@ -219,7 +219,7 @@ index a1124405412cdac673f34a63988e7be957506dba..64450024ce8094874875321537ddab71 return null; } }; -@@ -359,7 +369,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -366,7 +376,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack net.kyori.adventure.text.Component leaveMessage = net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? this.player.getBukkitEntity().displayName() : net.kyori.adventure.text.Component.text(this.player.getScoreboardName())); // Paper - Adventure @@ -229,10 +229,10 @@ index a1124405412cdac673f34a63988e7be957506dba..64450024ce8094874875321537ddab71 if (this.cserver.getServer().isRunning()) { this.cserver.getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca45977855e 100644 +index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146ed4bd2b52 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -349,7 +349,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -357,7 +357,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (this.clientIsFloating && !this.player.isSleeping() && !this.player.isPassenger() && !this.player.isDeadOrDying()) { if (++this.aboveGroundTickCount > this.getMaximumFlyingTicks(this.player)) { ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked for floating too long!", this.player.getName().getString()); @@ -241,7 +241,7 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 return; } } else { -@@ -368,7 +368,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -376,7 +376,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (this.clientVehicleIsFloating && this.lastVehicle.getControllingPassenger() == this.player) { if (++this.aboveGroundVehicleTickCount > this.getMaximumFlyingTicks(this.lastVehicle)) { ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked for floating a vehicle too long!", this.player.getName().getString()); @@ -250,8 +250,8 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 return; } } else { -@@ -399,7 +399,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - +@@ -396,7 +396,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + this.dropSpamThrottler.tick(); if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L) { this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 - this.disconnect((Component) Component.translatable("multiplayer.disconnect.idling")); @@ -259,7 +259,7 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 } } -@@ -481,7 +481,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -478,7 +478,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void handleMoveVehicle(ServerboundMoveVehiclePacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (ServerGamePacketListenerImpl.containsInvalidValues(packet.getX(), packet.getY(), packet.getZ(), packet.getYRot(), packet.getXRot())) { @@ -268,7 +268,7 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 } else if (!this.updateAwaitingTeleport()) { Entity entity = this.player.getRootVehicle(); -@@ -686,7 +686,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -684,7 +684,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (packet.getId() == this.awaitingTeleport) { if (this.awaitingPositionFromClient == null) { @@ -277,16 +277,16 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 return; } -@@ -744,7 +744,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -748,7 +748,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async // CraftBukkit start - if (this.chatSpamTickCount.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamLimit && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { // Paper - configurable tab spam limits + if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - configurable tab spam limits - this.disconnect(Component.translatable("disconnect.spam")); + this.disconnect(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - Kick event cause return; } // CraftBukkit end -@@ -909,7 +909,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -913,7 +913,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Paper start - validate pick item position if (!(packet.getSlot() >= 0 && packet.getSlot() < this.player.getInventory().items.size())) { ServerGamePacketListenerImpl.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString()); @@ -295,7 +295,7 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 return; } this.player.getInventory().pickSlot(packet.getSlot()); // Paper - Diff above if changed -@@ -1110,14 +1110,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1116,14 +1116,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (byteTotal > byteAllowed) { ServerGamePacketListenerImpl.LOGGER.warn("{} tried to send a book too large. Book size: {} - Allowed: {} - Pages: {}", this.player.getScoreboardName(), byteTotal, byteAllowed, pageList.size()); @@ -312,7 +312,7 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 return; } this.lastBookTick = MinecraftServer.currentTick; -@@ -1229,7 +1229,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1232,7 +1232,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void handleMovePlayer(ServerboundMovePlayerPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (ServerGamePacketListenerImpl.containsInvalidValues(packet.getX(0.0D), packet.getY(0.0D), packet.getZ(0.0D), packet.getYRot(0.0F), packet.getXRot(0.0F))) { @@ -321,7 +321,7 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 } else { ServerLevel worldserver = this.player.serverLevel(); -@@ -1667,7 +1667,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1671,7 +1671,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.dropCount++; if (this.dropCount >= 20) { ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " dropped their items too quickly!"); @@ -330,7 +330,7 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 return; } } -@@ -1955,7 +1955,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1968,7 +1968,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.resetLastActionTime(); } else { ServerGamePacketListenerImpl.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString()); @@ -339,7 +339,7 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 } } -@@ -2153,7 +2153,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2166,7 +2166,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private void tryHandleChat(String s, Runnable runnable, boolean sync) { // CraftBukkit if (ServerGamePacketListenerImpl.isChatMessageIllegal(s)) { @@ -348,7 +348,7 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 } else if (this.player.isRemoved() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) { // CraftBukkit - dead men tell no tales this.send(new ClientboundSystemChatPacket(Component.translatable("chat.disabled.options").withStyle(ChatFormatting.RED), false)); } else { -@@ -2176,7 +2176,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2189,7 +2189,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (optional.isEmpty()) { ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString()); @@ -357,16 +357,16 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 } return optional; -@@ -2362,7 +2362,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - // this.chatSpamTickCount += 20; - if (this.chatSpamTickCount.addAndGet(20) > 200 && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { +@@ -2373,7 +2373,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + // this.chatSpamThrottler.increment(); + if (!this.chatSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // CraftBukkit end - this.disconnect((Component) Component.translatable("disconnect.spam")); + this.disconnect((Component) Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause } } -@@ -2374,7 +2374,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2385,7 +2385,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl synchronized (this.lastSeenMessages) { if (!this.lastSeenMessages.applyOffset(packet.offset())) { ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString()); @@ -375,7 +375,7 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 } } -@@ -2522,7 +2522,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2533,7 +2533,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } if (i > 4096) { @@ -384,7 +384,7 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 } } -@@ -2580,7 +2580,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2591,7 +2591,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Spigot Start if ( entity == this.player && !this.player.isSpectator() ) { @@ -393,7 +393,7 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 return; } // Spigot End -@@ -2693,7 +2693,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2707,7 +2707,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } @@ -402,16 +402,16 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 ServerGamePacketListenerImpl.LOGGER.warn("Player {} tried to attack an invalid entity", ServerGamePacketListenerImpl.this.player.getName().getString()); } }); -@@ -3090,7 +3090,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3106,7 +3106,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Paper start - auto recipe limit if (!org.bukkit.Bukkit.isPrimaryThread()) { - if (this.recipeSpamPackets.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamLimit) { + if (!this.recipeSpamPackets.isIncrementAndUnderThreshold()) { - this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam")); + this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause return; } } -@@ -3332,7 +3332,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3377,7 +3377,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (!Objects.equals(profilepublickey_a, profilepublickey_a1)) { if (profilepublickey_a != null && profilepublickey_a1.expiresAt().isBefore(profilepublickey_a.expiresAt())) { @@ -420,7 +420,7 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 } else { try { SignatureValidator signaturevalidator = this.server.getProfileKeySignatureValidator(); -@@ -3345,7 +3345,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3390,7 +3390,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.resetPlayerChatState(remotechatsession_a.validate(this.player.getGameProfile(), signaturevalidator)); } catch (ProfilePublicKey.ValidationException profilepublickey_b) { ServerGamePacketListenerImpl.LOGGER.error("Failed to validate profile key: {}", profilepublickey_b.getMessage()); @@ -430,7 +430,7 @@ index 568f5d7165521304c7a92f32984a1d605d545ad5..b30c71ad0cc2602d2c026433a94c9ca4 } diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index d2d153e587e624025ef01fbe3dcfa4bf06f1a06b..e0a10f1d8bf2c0df66e62bdf2a174ce6a66bbd6d 100644 +index 9d5723cdfdbf6257a71e57842aea9ba317fc049a..1e4b288f20153ce0c91fabf164c5c8320c90ba7d 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -70,7 +70,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, @@ -443,10 +443,10 @@ index d2d153e587e624025ef01fbe3dcfa4bf06f1a06b..e0a10f1d8bf2c0df66e62bdf2a174ce6 } // 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 f7e442cd5eff3d7c6932d16c93a7a097f11251f9..393a93198b3a1d95a6cc5eb1d19e392f9ab7e2b9 100644 +index 6f7807cc0da427485037b3a72a9c60c81a858294..3ec8d38ca514048d94d24424d2132a90c10f529f 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -675,7 +675,7 @@ public abstract class PlayerList { +@@ -633,7 +633,7 @@ public abstract class PlayerList { while (iterator.hasNext()) { entityplayer = (ServerPlayer) iterator.next(); this.save(entityplayer); // CraftBukkit - Force the player's inventory to be saved @@ -455,7 +455,7 @@ index f7e442cd5eff3d7c6932d16c93a7a097f11251f9..393a93198b3a1d95a6cc5eb1d19e392f } // Instead of kicking then returning, we need to store the kick reason -@@ -1278,7 +1278,7 @@ public abstract class PlayerList { +@@ -1238,7 +1238,7 @@ public abstract class PlayerList { // Paper end // CraftBukkit start - disconnect safely for (ServerPlayer player : this.players) { @@ -465,7 +465,7 @@ index f7e442cd5eff3d7c6932d16c93a7a097f11251f9..393a93198b3a1d95a6cc5eb1d19e392f } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/player/ProfilePublicKey.java b/src/main/java/net/minecraft/world/entity/player/ProfilePublicKey.java -index f472dea0bd4f834c0c8f0aa59ae7cdae082b14af..2fa51c3a70f43cd23b8f494fc643d66cecfda7d2 100644 +index 9e2ad78b12cadbf0e2bda1e12fe844120529c347..6a7d7fad990fc44fdda6849d43dad141e61f7f37 100644 --- a/src/main/java/net/minecraft/world/entity/player/ProfilePublicKey.java +++ b/src/main/java/net/minecraft/world/entity/player/ProfilePublicKey.java @@ -24,7 +24,7 @@ public record ProfilePublicKey(ProfilePublicKey.Data data) { @@ -495,10 +495,10 @@ index f472dea0bd4f834c0c8f0aa59ae7cdae082b14af..2fa51c3a70f43cd23b8f494fc643d66c } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index a85983b947147a1557908846b8773aab29c17fae..b747df28b862990d5db08329149272c67eb17d94 100644 +index b54b773a4e1472f94c5c28188f706fbeb2cfb067..5347ad30130d598644902cdc8902e0b77ac4dfb1 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -275,7 +275,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -276,7 +276,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { void sendPacket(Packet packet); @@ -507,7 +507,7 @@ index a85983b947147a1557908846b8773aab29c17fae..b747df28b862990d5db08329149272c6 } public record CookieFuture(ResourceLocation key, CompletableFuture future) { -@@ -635,7 +635,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -648,7 +648,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void kickPlayer(String message) { org.spigotmc.AsyncCatcher.catchOp("player kick"); // Spigot @@ -516,7 +516,7 @@ index a85983b947147a1557908846b8773aab29c17fae..b747df28b862990d5db08329149272c6 } // Paper start -@@ -647,10 +647,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -660,10 +660,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void kick(final net.kyori.adventure.text.Component message) { @@ -533,7 +533,7 @@ index a85983b947147a1557908846b8773aab29c17fae..b747df28b862990d5db08329149272c6 } } -@@ -709,7 +714,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -722,7 +727,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Paper start - Improve chat handling if (ServerGamePacketListenerImpl.isChatMessageIllegal(msg)) { diff --git a/patches/unapplied/server/0544-Add-PufferFishStateChangeEvent.patch b/patches/server/0540-Add-PufferFishStateChangeEvent.patch similarity index 95% rename from patches/unapplied/server/0544-Add-PufferFishStateChangeEvent.patch rename to patches/server/0540-Add-PufferFishStateChangeEvent.patch index 87e61bb2a359..0574c7ed8c10 100644 --- a/patches/unapplied/server/0544-Add-PufferFishStateChangeEvent.patch +++ b/patches/server/0540-Add-PufferFishStateChangeEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PufferFishStateChangeEvent diff --git a/src/main/java/net/minecraft/world/entity/animal/Pufferfish.java b/src/main/java/net/minecraft/world/entity/animal/Pufferfish.java -index 9498bac12196637c187961424ef23ecb77eddff8..3f0fad476fe573c3ba946a9436d1b3f7c5260ee2 100644 +index 6c5fa151867eb2b15b9aaf94eb4f5309c415a92b..cdb74f86ee92ee143af29962a85d45ca585cee44 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Pufferfish.java +++ b/src/main/java/net/minecraft/world/entity/animal/Pufferfish.java -@@ -101,25 +101,39 @@ public class Pufferfish extends AbstractFish { +@@ -102,25 +102,39 @@ public class Pufferfish extends AbstractFish { public void tick() { if (!this.level().isClientSide && this.isAlive() && this.isEffectiveAi()) { if (this.inflateCounter > 0) { diff --git a/patches/unapplied/server/0545-Fix-PlayerBucketEmptyEvent-result-itemstack.patch b/patches/server/0541-Fix-PlayerBucketEmptyEvent-result-itemstack.patch similarity index 95% rename from patches/unapplied/server/0545-Fix-PlayerBucketEmptyEvent-result-itemstack.patch rename to patches/server/0541-Fix-PlayerBucketEmptyEvent-result-itemstack.patch index 12c519eefe5b..646e52a326b5 100644 --- a/patches/unapplied/server/0545-Fix-PlayerBucketEmptyEvent-result-itemstack.patch +++ b/patches/server/0541-Fix-PlayerBucketEmptyEvent-result-itemstack.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Fix PlayerBucketEmptyEvent result itemstack Fixes SPIGOT-2560: https://hub.spigotmc.org/jira/projects/SPIGOT/issues/SPIGOT-2560 diff --git a/src/main/java/net/minecraft/world/item/BucketItem.java b/src/main/java/net/minecraft/world/item/BucketItem.java -index 7617b6a0ad44e8b135d071836dc30df5ad062c42..6caed156ed0cfe0017d578f58cb963ee68272d78 100644 +index a6aaef9de23bf8084ab13c8f704e9f59de3acdcf..002e2f8e956b2631529e2189be225385dfb501df 100644 --- a/src/main/java/net/minecraft/world/item/BucketItem.java +++ b/src/main/java/net/minecraft/world/item/BucketItem.java @@ -40,6 +40,8 @@ import org.bukkit.event.player.PlayerBucketFillEvent; diff --git a/patches/unapplied/server/0546-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch b/patches/server/0542-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch similarity index 88% rename from patches/unapplied/server/0546-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch rename to patches/server/0542-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch index 04a6d787b62e..ee4d412a1c21 100644 --- a/patches/unapplied/server/0546-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch +++ b/patches/server/0542-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch @@ -14,7 +14,7 @@ contention situations. And this is extremely a low contention situation. diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -index 2e5afbd2a69c4eeabd9a48bff6a37a7004565716..2fa0097a9374a89177e4f1068d1bfed30b8ff122 100644 +index 8c318c5f9eaaae1e961ff24247283c232fa84c20..112d1259dd37743076ff6c67ffd711d084ba8698 100644 --- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java @@ -30,14 +30,14 @@ public class PalettedContainer implements PaletteResize, PalettedContainer @@ -35,7 +35,7 @@ index 2e5afbd2a69c4eeabd9a48bff6a37a7004565716..2fa0097a9374a89177e4f1068d1bfed3 } public static Codec> codecRW(IdMap idList, Codec entryCodec, PalettedContainer.Strategy paletteProvider, T defaultValue) { -@@ -104,7 +104,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -110,7 +110,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer } @Override @@ -44,7 +44,7 @@ index 2e5afbd2a69c4eeabd9a48bff6a37a7004565716..2fa0097a9374a89177e4f1068d1bfed3 PalettedContainer.Data data = this.data; PalettedContainer.Data data2 = this.createOrReuseData(data, newBits); data2.copyFrom(data.palette, data.storage); -@@ -129,7 +129,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -135,7 +135,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer return this.getAndSet(this.strategy.getIndex(x, y, z), value); } @@ -53,7 +53,7 @@ index 2e5afbd2a69c4eeabd9a48bff6a37a7004565716..2fa0097a9374a89177e4f1068d1bfed3 int i = this.data.palette.idFor(value); int j = this.data.storage.getAndSet(index, i); return this.data.palette.valueFor(j); -@@ -145,7 +145,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -151,7 +151,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer } } @@ -62,7 +62,7 @@ index 2e5afbd2a69c4eeabd9a48bff6a37a7004565716..2fa0097a9374a89177e4f1068d1bfed3 int i = this.data.palette.idFor(value); this.data.storage.set(index, i); } -@@ -168,7 +168,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -174,7 +174,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer intSet.forEach(id -> action.accept(palette.valueFor(id))); } @@ -71,7 +71,7 @@ index 2e5afbd2a69c4eeabd9a48bff6a37a7004565716..2fa0097a9374a89177e4f1068d1bfed3 this.acquire(); try { -@@ -183,7 +183,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -189,7 +189,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer } @Override @@ -80,7 +80,7 @@ index 2e5afbd2a69c4eeabd9a48bff6a37a7004565716..2fa0097a9374a89177e4f1068d1bfed3 this.acquire(); try { -@@ -231,7 +231,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -237,7 +237,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer } @Override diff --git a/patches/unapplied/server/0547-Add-option-to-fix-items-merging-through-walls.patch b/patches/server/0543-Add-option-to-fix-items-merging-through-walls.patch similarity index 89% rename from patches/unapplied/server/0547-Add-option-to-fix-items-merging-through-walls.patch rename to patches/server/0543-Add-option-to-fix-items-merging-through-walls.patch index ba1a219b4969..e0dd59d329b7 100644 --- a/patches/unapplied/server/0547-Add-option-to-fix-items-merging-through-walls.patch +++ b/patches/server/0543-Add-option-to-fix-items-merging-through-walls.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add option to fix items merging through walls diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index c724359995d65c88e7f365eea55f3e4382a46ddd..df90d5b934f41f5d8c232e93830d6690b6ccf401 100644 +index 65deb4568a80577f67f39de3af9fb568975a649d..6b19689a19465554b943470fc6f959e48169ac5b 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -282,6 +282,14 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -285,6 +285,14 @@ public class ItemEntity extends Entity implements TraceableEntity { ItemEntity entityitem = (ItemEntity) iterator.next(); if (entityitem.isMergable()) { diff --git a/patches/unapplied/server/0548-Add-BellRevealRaiderEvent.patch b/patches/server/0544-Add-BellRevealRaiderEvent.patch similarity index 100% rename from patches/unapplied/server/0548-Add-BellRevealRaiderEvent.patch rename to patches/server/0544-Add-BellRevealRaiderEvent.patch diff --git a/patches/unapplied/server/0549-Fix-invulnerable-end-crystals.patch b/patches/server/0545-Fix-invulnerable-end-crystals.patch similarity index 93% rename from patches/unapplied/server/0549-Fix-invulnerable-end-crystals.patch rename to patches/server/0545-Fix-invulnerable-end-crystals.patch index 57cba1965662..4349e5a8ad5b 100644 --- a/patches/unapplied/server/0549-Fix-invulnerable-end-crystals.patch +++ b/patches/server/0545-Fix-invulnerable-end-crystals.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Fix invulnerable end crystals MC-108513 diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java -index 6f8d4584aae56fc7fbcbc38b1291ea415208fd5e..a33d89fe9ca9e343edab8bb1cc88c54130ddb4a7 100644 +index 671e8aa7ecc2b3fcc98af62356ff690a2604bcb0..7cb3d69a69e0e3ef4b7f9f9c8b1eb67edb5d116d 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java @@ -30,6 +30,7 @@ public class EndCrystal extends Entity { @@ -52,10 +52,10 @@ index 6f8d4584aae56fc7fbcbc38b1291ea415208fd5e..a33d89fe9ca9e343edab8bb1cc88c541 } diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/SpikeFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/SpikeFeature.java -index c3bf90178abe89ccc987718237d472ed10c70d69..260c3a7dc592fba220ad4a7febb43ee2c9279115 100644 +index 6f0cd7121bf191d8fd01baf4c9b87df7f4f44564..fe5b2bcfaa243c3089f3df83ec1ae0948a63d1eb 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/feature/SpikeFeature.java +++ b/src/main/java/net/minecraft/world/level/levelgen/feature/SpikeFeature.java -@@ -114,6 +114,7 @@ public class SpikeFeature extends Feature { +@@ -115,6 +115,7 @@ public class SpikeFeature extends Feature { endCrystal.moveTo( (double)spike.getCenterX() + 0.5, (double)(spike.getHeight() + 1), (double)spike.getCenterZ() + 0.5, random.nextFloat() * 360.0F, 0.0F ); diff --git a/patches/unapplied/server/0550-Add-ElderGuardianAppearanceEvent.patch b/patches/server/0546-Add-ElderGuardianAppearanceEvent.patch similarity index 83% rename from patches/unapplied/server/0550-Add-ElderGuardianAppearanceEvent.patch rename to patches/server/0546-Add-ElderGuardianAppearanceEvent.patch index d9bc14356d26..e28248ff5de3 100644 --- a/patches/unapplied/server/0550-Add-ElderGuardianAppearanceEvent.patch +++ b/patches/server/0546-Add-ElderGuardianAppearanceEvent.patch @@ -34,15 +34,15 @@ index f8026eb1d9b10e468d28ee2e1296653e873c87db..23977c2074b920b646a639bef79c0f62 list.forEach((entityplayer) -> { diff --git a/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java b/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java -index 4e4b68904151d0d851b13f14f89c1c305e95fd5a..fd995b1f29c47884e9db2cb92f1dd615d62ae032 100644 +index 9290f43b4b37a7fa2afae81f8351ea76b7ee7de0..378694a38115c012978e1fea59d049d1ebd04110 100644 --- a/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java +++ b/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java @@ -67,7 +67,7 @@ public class ElderGuardian extends Guardian { - super.customServerAiStep(); + super.customServerAiStep(world); if ((this.tickCount + this.getId()) % 1200 == 0) { MobEffectInstance mobeffect = new MobEffectInstance(MobEffects.DIG_SLOWDOWN, 6000, 2); -- List list = MobEffectUtil.addEffectToPlayersAround((ServerLevel) this.level(), this, this.position(), 50.0D, mobeffect, 1200, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit -+ List list = MobEffectUtil.addEffectToPlayersAround((ServerLevel) this.level(), this, this.position(), 50.0D, mobeffect, 1200, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK, (player) -> new io.papermc.paper.event.entity.ElderGuardianAppearanceEvent((org.bukkit.entity.ElderGuardian) this.getBukkitEntity(), player.getBukkitEntity()).callEvent()); // CraftBukkit // Paper - Add ElderGuardianAppearanceEvent +- List list = MobEffectUtil.addEffectToPlayersAround(world, this, this.position(), 50.0D, mobeffect, 1200, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit ++ List list = MobEffectUtil.addEffectToPlayersAround(world, this, this.position(), 50.0D, mobeffect, 1200, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK, (player) -> new io.papermc.paper.event.entity.ElderGuardianAppearanceEvent((org.bukkit.entity.ElderGuardian) this.getBukkitEntity(), player.getBukkitEntity()).callEvent()); // CraftBukkit // Paper - Add ElderGuardianAppearanceEvent list.forEach((entityplayer) -> { entityplayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.GUARDIAN_ELDER_EFFECT, this.isSilent() ? 0.0F : 1.0F)); diff --git a/patches/unapplied/server/0551-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch b/patches/server/0547-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch similarity index 100% rename from patches/unapplied/server/0551-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch rename to patches/server/0547-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch diff --git a/patches/unapplied/server/0552-Line-Of-Sight-Changes.patch b/patches/server/0548-Line-Of-Sight-Changes.patch similarity index 82% rename from patches/unapplied/server/0552-Line-Of-Sight-Changes.patch rename to patches/server/0548-Line-Of-Sight-Changes.patch index 1cf3200c8195..08eb10296bd0 100644 --- a/patches/unapplied/server/0552-Line-Of-Sight-Changes.patch +++ b/patches/server/0548-Line-Of-Sight-Changes.patch @@ -5,21 +5,21 @@ Subject: [PATCH] Line Of Sight Changes diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index afa2d3f5199fcac5c83639bb87e31425da4c5310..e56ae5170526fdc9d4e6f8b94a1e6ebc77cae582 100644 +index b7cc3d84c724772e3e1250c5e99bb32e01112220..eeed7d1d4b7fee0e8ab1f43f9b7ec6f74a01330d 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3755,7 +3755,8 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3907,7 +3907,8 @@ public abstract class LivingEntity extends Entity implements Attackable { Vec3 vec3d = new Vec3(this.getX(), this.getEyeY(), this.getZ()); - Vec3 vec3d1 = new Vec3(entity.getX(), entity.getEyeY(), entity.getZ()); + Vec3 vec3d1 = new Vec3(entity.getX(), entityY.getAsDouble(), entity.getZ()); -- return vec3d1.distanceTo(vec3d) > 128.0D ? false : this.level().clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS; +- return vec3d1.distanceTo(vec3d) > 128.0D ? false : this.level().clip(new ClipContext(vec3d, vec3d1, shapeType, fluidHandling, this)).getType() == HitResult.Type.MISS; + // Paper - diff on change - used in CraftLivingEntity#hasLineOfSight(Location) and CraftWorld#lineOfSightExists -+ return vec3d1.distanceToSqr(vec3d) > 128.0D * 128.0D ? false : this.level().clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS; // Paper - Perf: Use distance squared ++ return vec3d1.distanceToSqr(vec3d) > 128.0D * 128.0D ? false : this.level().clip(new ClipContext(vec3d, vec3d1, shapeType, fluidHandling, this)).getType() == HitResult.Type.MISS; // Paper - Perf: Use distance squared } } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index 04a39cb6c13c26e2cb1d73a9da98df5d04df69bc..5d137f8c42356359701e1bea7525f82c018b502c 100644 +index 21e5dd6624e50dec35859b7d1be4a304e4427883..123824f6b8306900ed5c0b3addb884301dbcab7e 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java @@ -520,5 +520,21 @@ public abstract class CraftRegionAccessor implements RegionAccessor { @@ -45,10 +45,10 @@ index 04a39cb6c13c26e2cb1d73a9da98df5d04df69bc..5d137f8c42356359701e1bea7525f82c // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index e56a0d8928e3c0e27b1acd171162e4a53b70d925..637bac756a8f41ed4abd8e3828886c561513e384 100644 +index 5749e2b5174be23633c8a811baec8c05da12e3e2..b5830f31c3444fcc6fea83a3b71a05bf07ce379d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -636,6 +636,23 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -643,6 +643,23 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return this.getHandle().hasLineOfSight(((CraftEntity) other).getHandle()); } diff --git a/patches/unapplied/server/0553-add-per-world-spawn-limits.patch b/patches/server/0549-add-per-world-spawn-limits.patch similarity index 85% rename from patches/unapplied/server/0553-add-per-world-spawn-limits.patch rename to patches/server/0549-add-per-world-spawn-limits.patch index 2af34cd4398f..c43feed3bb78 100644 --- a/patches/unapplied/server/0553-add-per-world-spawn-limits.patch +++ b/patches/server/0549-add-per-world-spawn-limits.patch @@ -5,10 +5,10 @@ Subject: [PATCH] add per world spawn limits diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index dc16ed952719a5203b1b9a61e0ad2bd39021e8f1..a41c6705aa7e04ad32395f89b95ca76617c9416d 100644 +index 5948e80ad35b9b12d6eded02549bf17be7de1fa7..1d7865e6de190f7321846bdac52da36a908c7a3d 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -222,6 +222,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -226,6 +226,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { this.biomeProvider = biomeProvider; this.environment = env; diff --git a/patches/unapplied/server/0554-Fix-potions-splash-events.patch b/patches/server/0550-Fix-potions-splash-events.patch similarity index 80% rename from patches/unapplied/server/0554-Fix-potions-splash-events.patch rename to patches/server/0550-Fix-potions-splash-events.patch index 38cfaf97698b..d71c03a5dc23 100644 --- a/patches/unapplied/server/0554-Fix-potions-splash-events.patch +++ b/patches/server/0550-Fix-potions-splash-events.patch @@ -8,39 +8,39 @@ Fixes SPIGOT-6221: https://hub.spigotmc.org/jira/projects/SPIGOT/issues/SPIGOT-6 Fix splash events cancellation that still show particles/sound diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java -index be787a5b52e90796d4f06e17e564f4324807c3e6..cb34cc9443da56c0497c7a0192c8b8363c3426fe 100644 +index 224e768963d6969f25608065d37ad72d82acda68..d6ac07d9d5ee0430a1d91b7084b378aac1d047e5 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java -@@ -106,55 +106,76 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie +@@ -109,55 +109,76 @@ public class ThrownPotion extends ThrowableItemProjectile { ItemStack itemstack = this.getItem(); PotionContents potioncontents = (PotionContents) itemstack.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY); + boolean showParticles = true; // Paper - Fix potions splash events if (potioncontents.is(Potions.WATER)) { -- this.applyWater(); -+ showParticles = this.applyWater(hitResult); // Paper - Fix potions splash events +- this.applyWater(worldserver); ++ showParticles = this.applyWater(worldserver, hitResult); // Paper - Fix potions splash events } else if (true || potioncontents.hasEffects()) { // CraftBukkit - Call event even if no effects to apply if (this.isLingering()) { - this.makeAreaOfEffectCloud(potioncontents, hitResult); // CraftBukkit - Pass MovingObjectPosition + showParticles = this.makeAreaOfEffectCloud(potioncontents, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper } else { -- this.applySplash(potioncontents.getAllEffects(), hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition -+ showParticles = this.applySplash(potioncontents.getAllEffects(), hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper +- this.applySplash(worldserver, potioncontents.getAllEffects(), hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition ++ showParticles = this.applySplash(worldserver, potioncontents.getAllEffects(), hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper } } + if (showParticles) { // Paper - Fix potions splash events int i = potioncontents.potion().isPresent() && ((Potion) ((Holder) potioncontents.potion().get()).value()).hasInstantEffects() ? 2007 : 2002; - this.level().levelEvent(i, this.blockPosition(), potioncontents.getColor()); + worldserver.levelEvent(i, this.blockPosition(), potioncontents.getColor()); + } // Paper - Fix potions splash events this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause } } -- private void applyWater() { +- private void applyWater(ServerLevel world) { + private static final Predicate APPLY_WATER_GET_ENTITIES_PREDICATE = ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE.or(Axolotl.class::isInstance); // Paper - Fix potions splash events -+ private boolean applyWater(@Nullable HitResult hitResult) { // Paper - Fix potions splash events ++ private boolean applyWater(ServerLevel world, @Nullable HitResult hitResult) { // Paper - Fix potions splash events AABB axisalignedbb = this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D); - List list = this.level().getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb, ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE); + // Paper start - Fix potions splash events @@ -59,7 +59,7 @@ index be787a5b52e90796d4f06e17e564f4324807c3e6..cb34cc9443da56c0497c7a0192c8b836 if (d0 < 16.0D) { if (entityliving.isSensitiveToWater()) { -- entityliving.hurt(this.damageSources().indirectMagic(this, this.getOwner()), 1.0F); +- entityliving.hurtServer(world, this.damageSources().indirectMagic(this, this.getOwner()), 1.0F); + affected.put(entityliving.getBukkitLivingEntity(), 1.0); } @@ -82,7 +82,7 @@ index be787a5b52e90796d4f06e17e564f4324807c3e6..cb34cc9443da56c0497c7a0192c8b836 + ); + if (!event.isCancelled()) { + for (LivingEntity affectedEntity : event.getToDamage()) { -+ ((CraftLivingEntity) affectedEntity).getHandle().hurt(this.damageSources().indirectMagic(this, this.getOwner()), 1.0F); ++ ((CraftLivingEntity) affectedEntity).getHandle().hurtServer(world, this.damageSources().indirectMagic(this, this.getOwner()), 1.0F); + } + for (LivingEntity toExtinguish : event.getToExtinguish()) { + ((CraftLivingEntity) toExtinguish).getHandle().extinguishFire(); @@ -98,12 +98,12 @@ index be787a5b52e90796d4f06e17e564f4324807c3e6..cb34cc9443da56c0497c7a0192c8b836 } -- private void applySplash(Iterable iterable, @Nullable Entity entity, HitResult position) { // CraftBukkit - Pass MovingObjectPosition -+ private boolean applySplash(Iterable iterable, @Nullable Entity entity, HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events +- private void applySplash(ServerLevel worldserver, Iterable iterable, @Nullable Entity entity, HitResult position) { // CraftBukkit - Pass MovingObjectPosition ++ private boolean applySplash(ServerLevel worldserver, Iterable iterable, @Nullable Entity entity, HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events AABB axisalignedbb = this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D); - List list = this.level().getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb); + List list = worldserver.getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb); Map affected = new HashMap(); // CraftBukkit -@@ -172,6 +193,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie +@@ -175,6 +196,7 @@ public class ThrownPotion extends ThrowableItemProjectile { if (d0 < 16.0D) { double d1; @@ -111,7 +111,7 @@ index be787a5b52e90796d4f06e17e564f4324807c3e6..cb34cc9443da56c0497c7a0192c8b836 if (entityliving == entity) { d1 = 1.0D; } else { -@@ -227,10 +249,11 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie +@@ -230,10 +252,11 @@ public class ThrownPotion extends ThrowableItemProjectile { } } } @@ -124,7 +124,7 @@ index be787a5b52e90796d4f06e17e564f4324807c3e6..cb34cc9443da56c0497c7a0192c8b836 AreaEffectCloud entityareaeffectcloud = new AreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ()); Entity entity = this.getOwner(); -@@ -243,14 +266,16 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie +@@ -246,14 +269,16 @@ public class ThrownPotion extends ThrowableItemProjectile { entityareaeffectcloud.setWaitTime(10); entityareaeffectcloud.setRadiusPerTick(-entityareaeffectcloud.getRadius() / (float) entityareaeffectcloud.getDuration()); entityareaeffectcloud.setPotionContents(potioncontents); @@ -143,10 +143,10 @@ index be787a5b52e90796d4f06e17e564f4324807c3e6..cb34cc9443da56c0497c7a0192c8b836 public boolean isLingering() { diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 36adcab02e97cae2d087bae74cc4ceaf3052a9f8..b93fa1ea73f0b218e6c6bed8bd36694e26544ab0 100644 +index 1ce637a2b80dfc5c3da20f7bd95b97f4718a07d4..83648509a5b90daa4b072650cbc3215b64659a86 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -886,6 +886,32 @@ public class CraftEventFactory { +@@ -884,6 +884,32 @@ public class CraftEventFactory { return event; } diff --git a/patches/unapplied/server/0555-Add-more-LimitedRegion-API.patch b/patches/server/0551-Add-more-LimitedRegion-API.patch similarity index 93% rename from patches/unapplied/server/0555-Add-more-LimitedRegion-API.patch rename to patches/server/0551-Add-more-LimitedRegion-API.patch index 6e183e954e83..f46a2383c8db 100644 --- a/patches/unapplied/server/0555-Add-more-LimitedRegion-API.patch +++ b/patches/server/0551-Add-more-LimitedRegion-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add more LimitedRegion API diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java -index e7266835946c3bf49dbd83fe677481e8eddd16e5..7d6ee60b1d3e023e1eabc59eb591c3ae3d8ac043 100644 +index ca250dba422f8092b99f72b322147061a7541d14..2c7b64bd7071cb803a042152d497982d753e0b5d 100644 --- a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java +++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java -@@ -254,4 +254,45 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe +@@ -255,4 +255,45 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe public void addEntityWithPassengers(net.minecraft.world.entity.Entity entity, CreatureSpawnEvent.SpawnReason reason) { this.entities.add(entity); } diff --git a/patches/unapplied/server/0556-Fix-PlayerDropItemEvent-using-wrong-item.patch b/patches/server/0552-Fix-PlayerDropItemEvent-using-wrong-item.patch similarity index 79% rename from patches/unapplied/server/0556-Fix-PlayerDropItemEvent-using-wrong-item.patch rename to patches/server/0552-Fix-PlayerDropItemEvent-using-wrong-item.patch index 8f8228a1d434..c6491e489853 100644 --- a/patches/unapplied/server/0556-Fix-PlayerDropItemEvent-using-wrong-item.patch +++ b/patches/server/0552-Fix-PlayerDropItemEvent-using-wrong-item.patch @@ -31,10 +31,10 @@ index c81fd3e1108fb0a02f9240263404af2b968c8494..0d9de4c61c7b26a6ff37c12fde629161 } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 42df8d45ceb963043cf6467b8fc47272ce0873da..f20019261a09f425137731f7a4b92e889b617334 100644 +index a022f0aee638bb12967b5fd20847fe20e6b286f3..7bcb3ef3cb498114428782848e0370ac2497ccdc 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -2486,7 +2486,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2747,7 +2747,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { if (flag1) { if (!itemstack1.isEmpty()) { @@ -43,19 +43,15 @@ index 42df8d45ceb963043cf6467b8fc47272ce0873da..f20019261a09f425137731f7a4b92e88 } this.awardStat(Stats.DROP); -diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index b444b24a92bd2209ee4104ae82c7cfa9c876c910..7fee6ffeb8ccde965fcc1454eb0d8c6b3637da41 100644 ---- a/src/main/java/net/minecraft/world/entity/player/Player.java -+++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -745,6 +745,11 @@ public abstract class Player extends LivingEntity { - } - +@@ -2763,6 +2763,11 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { + return null; + } else { double d0 = this.getEyeY() - 0.30000001192092896D; + // Paper start -+ ItemStack tmp = itemstack.copy(); -+ itemstack.setCount(0); -+ itemstack = tmp; ++ ItemStack tmp = stack.copy(); ++ stack.setCount(0); ++ stack = tmp; + // Paper end - ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), d0, this.getZ(), itemstack); + ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), d0, this.getZ(), stack); entityitem.setPickUpDelay(40); diff --git a/patches/unapplied/server/0557-Missing-Entity-API.patch b/patches/server/0553-Missing-Entity-API.patch similarity index 94% rename from patches/unapplied/server/0557-Missing-Entity-API.patch rename to patches/server/0553-Missing-Entity-API.patch index 971be97b6363..564422f36b7e 100644 --- a/patches/unapplied/server/0557-Missing-Entity-API.patch +++ b/patches/server/0553-Missing-Entity-API.patch @@ -116,7 +116,7 @@ index 0000000000000000000000000000000000000000..41bf71d116ffc5431586ce54abba7f8d + } +} diff --git a/src/main/java/net/minecraft/world/entity/animal/AbstractSchoolingFish.java b/src/main/java/net/minecraft/world/entity/animal/AbstractSchoolingFish.java -index 2cd61138dfaa82fa698ef8d32d690f51f621ee3b..957eb2ba3f647f70522243fedf36b921e58142bd 100644 +index 30095df7b64cfda4931dbfa22549ff5abefd53e0..c8ae49f58c254119c0e64a4e1501ebc5a70f9a46 100644 --- a/src/main/java/net/minecraft/world/entity/animal/AbstractSchoolingFish.java +++ b/src/main/java/net/minecraft/world/entity/animal/AbstractSchoolingFish.java @@ -51,6 +51,7 @@ public abstract class AbstractSchoolingFish extends AbstractFish { @@ -128,10 +128,10 @@ index 2cd61138dfaa82fa698ef8d32d690f51f621ee3b..957eb2ba3f647f70522243fedf36b921 this.leader = null; } diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java -index 615b57fac9def18d9dcaefcfe397c74c11cac627..f933654b66f7474dc071da5f10cf1684fdac367a 100644 +index 8c7943fdb56cd75c362e47e6c934bde5a714adaa..63e068c1a2d98c9c07dbabd1fa574d6b44e1a2fb 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Bee.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java -@@ -554,11 +554,13 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -561,11 +561,13 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.setFlag(4, hasStung); } @@ -146,7 +146,7 @@ index 615b57fac9def18d9dcaefcfe397c74c11cac627..f933654b66f7474dc071da5f10cf1684 } diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java -index b06d39d3bd39a4dc4f273a359a89592d3b8cf184..43046f4a0cff620834ac4647efdcde227185b2ff 100644 +index b9d7aa4aa0fc3472a2a0700e526778daf62bdc6f..48ac8c3f6e00c3c2dc67b6c994be7c0ac6dfcf81 100644 --- a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java +++ b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java @@ -50,6 +50,7 @@ public class Tadpole extends AbstractFish { @@ -157,7 +157,7 @@ index b06d39d3bd39a4dc4f273a359a89592d3b8cf184..43046f4a0cff620834ac4647efdcde22 public Tadpole(EntityType type, Level world) { super(type, world); -@@ -100,7 +101,7 @@ public class Tadpole extends AbstractFish { +@@ -102,7 +103,7 @@ public class Tadpole extends AbstractFish { @Override public void aiStep() { super.aiStep(); @@ -166,7 +166,7 @@ index b06d39d3bd39a4dc4f273a359a89592d3b8cf184..43046f4a0cff620834ac4647efdcde22 this.setAge(this.age + 1); } -@@ -110,12 +111,14 @@ public class Tadpole extends AbstractFish { +@@ -112,12 +113,14 @@ public class Tadpole extends AbstractFish { public void addAdditionalSaveData(CompoundTag nbt) { super.addAdditionalSaveData(nbt); nbt.putInt("Age", this.age); @@ -181,7 +181,7 @@ index b06d39d3bd39a4dc4f273a359a89592d3b8cf184..43046f4a0cff620834ac4647efdcde22 } @Nullable -@@ -167,6 +170,7 @@ public class Tadpole extends AbstractFish { +@@ -169,6 +172,7 @@ public class Tadpole extends AbstractFish { Bucketable.saveDefaultDataToBucketTag(this, stack); CustomData.update(DataComponents.BUCKET_ENTITY_DATA, stack, (nbttagcompound) -> { nbttagcompound.putInt("Age", this.getAge()); @@ -189,7 +189,7 @@ index b06d39d3bd39a4dc4f273a359a89592d3b8cf184..43046f4a0cff620834ac4647efdcde22 }); } -@@ -177,6 +181,7 @@ public class Tadpole extends AbstractFish { +@@ -179,6 +183,7 @@ public class Tadpole extends AbstractFish { this.setAge(nbt.getInt("Age")); } @@ -197,7 +197,7 @@ index b06d39d3bd39a4dc4f273a359a89592d3b8cf184..43046f4a0cff620834ac4647efdcde22 } @Override -@@ -208,6 +213,7 @@ public class Tadpole extends AbstractFish { +@@ -210,6 +215,7 @@ public class Tadpole extends AbstractFish { } private void ageUp(int seconds) { @@ -206,10 +206,10 @@ index b06d39d3bd39a4dc4f273a359a89592d3b8cf184..43046f4a0cff620834ac4647efdcde22 } diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java -index affa2e133611b7a045a99bac801398263d114ba7..f1e43254936feedfe0ffbf77071505f3a65e5053 100644 +index 709237639ef0ec1cb623f270302a27b0072e8685..74151d69380e4adede40c7d7fc20834553706730 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java -@@ -760,6 +760,15 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, +@@ -779,6 +779,15 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, } @@ -225,7 +225,7 @@ index affa2e133611b7a045a99bac801398263d114ba7..f1e43254936feedfe0ffbf77071505f3 @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { if (!this.isVehicle() && !this.isBaby()) { -@@ -802,6 +811,11 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, +@@ -821,6 +830,11 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, this.setFlag(16, eatingGrass); } @@ -238,10 +238,10 @@ index affa2e133611b7a045a99bac801398263d114ba7..f1e43254936feedfe0ffbf77071505f3 if (angry) { this.setEating(false); diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java -index 8afd453deda455bd486c9a4a69790151f5012f62..33b7e578f39608d522a9c270cac69be44a34456b 100644 +index 04842dd7b9beabcecbd492d0b98faaebeea1a5d9..d5808d0c190877554a4a8191f68e8b4a36f2ff46 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java -@@ -74,10 +74,11 @@ public class Llama extends AbstractChestedHorse implements VariantHolder type, Level world) { super(type, world); + this.getNavigation().setRequiredPathLength(40.0F); + this.maxDomestication = 30; // Paper - Missing entity API; configure max temper instead of a hardcoded value } public boolean isTraderLlama() { -@@ -313,7 +314,7 @@ public class Llama extends AbstractChestedHorse implements VariantHolder type, Level world) { super(type, world); -@@ -595,7 +600,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -592,7 +597,7 @@ public class WitherBoss extends Monster implements RangedAttackMob { @Override public boolean canUsePortal(boolean allowVehicles) { @@ -289,10 +290,10 @@ index 3ee24382ef3614ff0c5d5cdc614a41286ba4af5e..3cd4a744c3e3aeba90f342de9dea67ef @Override diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -index 0214e8bbcaefdd92ee3719d9a570f9d256ee29ba..7caa5469a4daa5d0c569f446ff2d597a9f10e8ac 100644 +index 512de8e79a842d4389e8528983b94af4843ffd11..0e8349aa6cb23860a4dd884e730ac8f22d422205 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -@@ -442,6 +442,16 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -429,6 +429,16 @@ public class EnderMan extends Monster implements NeutralMob { this.entityData.set(EnderMan.DATA_STARED_AT, true); } @@ -310,10 +311,10 @@ index 0214e8bbcaefdd92ee3719d9a570f9d256ee29ba..7caa5469a4daa5d0c569f446ff2d597a public boolean requiresCustomPersistence() { return super.requiresCustomPersistence() || this.getCarriedBlock() != null; diff --git a/src/main/java/net/minecraft/world/entity/monster/Ghast.java b/src/main/java/net/minecraft/world/entity/monster/Ghast.java -index 603e948583ce0a99fc0061a85f495e8262659035..a836a902bebf318ceabaed4e98fab1141b46a28b 100644 +index 71259b92a01a4feca270a250b1964f25f6da2d33..a8c8c03e972aa6352843cf4c3e4aebfb8f493125 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Ghast.java +++ b/src/main/java/net/minecraft/world/entity/monster/Ghast.java -@@ -65,6 +65,12 @@ public class Ghast extends FlyingMob implements Enemy { +@@ -66,6 +66,12 @@ public class Ghast extends FlyingMob implements Enemy { return this.explosionPower; } @@ -327,10 +328,10 @@ index 603e948583ce0a99fc0061a85f495e8262659035..a836a902bebf318ceabaed4e98fab114 protected boolean shouldDespawnInPeaceful() { return true; diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java -index 9cf453248b6ee9e1af9f5945b1e515a9ad7ff236..f8c733961015ace508bfe14fd61d5188ca9d551b 100644 +index 69af895863a2d0fa25a128518bda99d1754f9ac0..533cb2eff3d56e7e8a70aba5e1047250e192bf2c 100644 --- a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java +++ b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java -@@ -205,6 +205,12 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { +@@ -207,6 +207,12 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { } public void startConverting(@Nullable UUID uuid, int delay) { @@ -343,7 +344,7 @@ index 9cf453248b6ee9e1af9f5945b1e515a9ad7ff236..f8c733961015ace508bfe14fd61d5188 this.conversionStarter = uuid; this.villagerConversionTime = delay; this.getEntityData().set(ZombieVillager.DATA_CONVERTING_ID, true); -@@ -212,7 +218,7 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { +@@ -214,7 +220,7 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { this.removeEffect(MobEffects.WEAKNESS, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.CONVERSION); this.addEffect(new MobEffectInstance(MobEffects.DAMAGE_BOOST, delay, Math.min(this.level().getDifficulty().getId() - 1, 0)), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.CONVERSION); // CraftBukkit end @@ -353,10 +354,10 @@ index 9cf453248b6ee9e1af9f5945b1e515a9ad7ff236..f8c733961015ace508bfe14fd61d5188 @Override diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java -index 46b67c38dccf911973e6a7643f06972019073eb2..e45c3a9805d9fac1fabe6d891c817743acd9969e 100644 +index c26ef5e3ed4bb0e0729585167d696226f312c214..248410547de380e3195bbdc8b7b39cff908a0c32 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java -@@ -106,6 +106,20 @@ public class ThrownTrident extends AbstractArrow { +@@ -113,6 +113,20 @@ public class ThrownTrident extends AbstractArrow { return (Boolean) this.entityData.get(ThrownTrident.ID_FOIL); } @@ -419,7 +420,7 @@ index 3952e52b94c1cc97e1d2d3885f59d7690efb74ad..9bcc0931510607b8fbd01233e2b3c346 + // Paper end - Horse API } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java -index 2f99fc44de05bfbb5c9a8c859312cb7d32310d62..81f5e1d866128af8fb2acc13aca715580fdf9886 100644 +index 17bffb45453f15328ca91794e26f6be1defef700..6591513bb62226b6f85fd2ef9f6ebe376f0f7362 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java @@ -229,4 +229,17 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud @@ -593,10 +594,10 @@ index fa0bf7db880063427ba12df1df1c72240fff93e9..63e6b07e3b159c74d9ef17be20b5ab43 public CraftCod(CraftServer server, net.minecraft.world.entity.animal.Cod entity) { super(server, entity); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java -index af432f9a1d255a56c31c3b97aeb4457d17f37e3e..f93f8f6509b12eb9b1e07c829278bb0822dd7988 100644 +index 5bae70ad160d0d0912aa9ef054c5515812957289..83867b9c5497e6e793b21c482646cc419587e182 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java -@@ -18,4 +18,36 @@ public class CraftDolphin extends CraftWaterMob implements Dolphin { +@@ -18,4 +18,36 @@ public class CraftDolphin extends CraftAgeable implements Dolphin { public String toString() { return "CraftDolphin"; } @@ -705,10 +706,10 @@ index fc0f0e841dc974d080e1abb9bbafb5165801131f..d657fd2c507a5b215aeab0a5f3e9c2ee + // 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 96201ea45f8b53dcadb1a8732b1d49b1e8d1d7df..7c04eb9e7eb5ff728465b46e3739eb2598ef1204 100644 +index 06fda053874e7ef0c8995b1a55e5f518b28eebc9..0c1c9033646dedcf1d11dee74d6965683adadf0a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1086,4 +1086,27 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1087,4 +1087,27 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return set; } // Paper end - tracked players API @@ -760,7 +761,7 @@ index 142f3e3257afebb2e831fd0970678123d99a1717..1b084d63bdbb24dad45d28eed1693eb6 public AbstractHurtingProjectile getHandle() { return (AbstractHurtingProjectile) this.entity; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java -index 17164811bbcf983bef62c47bc99330074762267b..c455deb4fd2a7684bcc01a8212c362a2375c190b 100644 +index dd912be2933864236cd4fb35631d505972082d77..bb2b59ce9775a0d1dd9828885e57c14cf40d9f04 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java @@ -113,4 +113,41 @@ public class CraftFox extends CraftAnimals implements Fox { @@ -828,10 +829,10 @@ index 2cec61a1bb050c1ef81c5fc3d0afafe9ff29d459..97fa4e1e70203194bd939618b2fad926 + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 637bac756a8f41ed4abd8e3828886c561513e384..19fb8acf614da707f49d922e520e4be93237b2cc 100644 +index b5830f31c3444fcc6fea83a3b71a05bf07ce379d..00db6ba96bda7ceaae8bc69a6b3a42e7a3929485 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -124,6 +124,13 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -128,6 +128,13 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { } } @@ -845,7 +846,7 @@ index 637bac756a8f41ed4abd8e3828886c561513e384..19fb8acf614da707f49d922e520e4be9 @Override public double getAbsorptionAmount() { return this.getHandle().getAbsorptionAmount(); -@@ -920,14 +927,29 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -939,14 +946,29 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { @Override public boolean isInvisible() { @@ -945,10 +946,10 @@ index 17f5684cba9d3ed22d9925d1951520cc4751dfe2..3a3563a1bdbc0d84d973b3a04b50b78b + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java -index 60d09655c5b8b9ff289291ee6badfb5aadf8533e..fb29afb6517b009b81285adc9e6dca2eb7f74aee 100644 +index bd739428a7e5e35ebcdb70cd187379b3d222339b..7cf42f62d91c131b1cab576979f85c58c3cecb3b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java -@@ -145,4 +145,16 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob { +@@ -146,4 +146,16 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob { return getHandle().getMaxHeadXRot(); } // Paper end @@ -1154,10 +1155,10 @@ index cae59f77c704a5b9515dc4917ed5fdc89631ecfb..09796ce15658e3f7c223a265a547a51e + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSalmon.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSalmon.java -index b8140aa25a25870259b5644091c6643da1e14b54..d4d8ce60098c74508e2de9541bf6534988779764 100644 +index 551c30cb0fb41dfe4a03663d34ecf9764566c215..7660cc21e936002ebb23510f0ec2b58d71e5157d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSalmon.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSalmon.java -@@ -3,7 +3,7 @@ package org.bukkit.craftbukkit.entity; +@@ -4,7 +4,7 @@ import com.google.common.base.Preconditions; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Salmon; @@ -1167,7 +1168,7 @@ index b8140aa25a25870259b5644091c6643da1e14b54..d4d8ce60098c74508e2de9541bf65349 public CraftSalmon(CraftServer server, net.minecraft.world.entity.animal.Salmon entity) { super(server, entity); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java -index 3f32c683ddc6999b89f2e4051eb6ae784b296b8f..dac3d34677688ac560bc1be2087a08479ef71b87 100644 +index 36ab282e2c4060bdea4e57f3ab9dfef9f6cd622c..a61aec087fa7cec27a803668bdc1b9e6eb336755 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java @@ -67,4 +67,17 @@ public class CraftTNTPrimed extends CraftEntity implements TNTPrimed { From 4db250389ed341ade9e41d2760ce08965d375a46 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Wed, 23 Oct 2024 20:50:46 +0200 Subject: [PATCH 025/119] Work work work work --- ...of-Block-applyBoneMeal-always-being.patch} | 2 +- ...tChunkIfLoadedImmediately-in-places.patch} | 10 +- ...rom-signs-not-firing-command-events.patch} | 19 ++-- .../0557-Add-PlayerArmSwingEvent.patch} | 4 +- ...-event-leave-message-not-being-sent.patch} | 22 ++--- ...n-t-apply-cramming-damage-to-players.patch | 25 +++++ ...d-timings-for-sensors-and-behaviors.patch} | 7 +- .../0561-Add-missing-forceDrop-toggles.patch} | 78 ++++++++------- .../0562-Stinger-API.patch} | 19 ++-- .../0563-Add-System.out-err-catcher.patch} | 4 +- ...AFK-kick-while-watching-end-credits.patch} | 10 +- ...iting-of-comments-to-server.propert.patch} | 0 .../0566-Add-PlayerSetSpawnEvent.patch} | 24 ++--- ...rs-respect-inventory-max-stack-size.patch} | 2 +- ...ize-entity-tracker-passenger-checks.patch} | 4 +- ...-option-for-Piglins-guarding-chests.patch} | 6 +- .../0570-Add-EntityDamageItemEvent.patch | 94 +++++++++++++++++++ ...timize-indirect-passenger-iteration.patch} | 6 +- ...em-frame-map-cursor-update-interval.patch} | 4 +- ...arget-without-changing-other-things.patch} | 6 +- ...n-t-apply-cramming-damage-to-players.patch | 33 ------- .../0574-Add-EntityDamageItemEvent.patch | 89 ------------------ 22 files changed, 229 insertions(+), 239 deletions(-) rename patches/{unapplied/server/0558-Fix-return-value-of-Block-applyBoneMeal-always-being.patch => server/0554-Fix-return-value-of-Block-applyBoneMeal-always-being.patch} (90%) rename patches/{unapplied/server/0559-Use-getChunkIfLoadedImmediately-in-places.patch => server/0555-Use-getChunkIfLoadedImmediately-in-places.patch} (75%) rename patches/{unapplied/server/0560-Fix-commands-from-signs-not-firing-command-events.patch => server/0556-Fix-commands-from-signs-not-firing-command-events.patch} (90%) rename patches/{unapplied/server/0561-Add-PlayerArmSwingEvent.patch => server/0557-Add-PlayerArmSwingEvent.patch} (88%) rename patches/{unapplied/server/0562-Fix-kick-event-leave-message-not-being-sent.patch => server/0558-Fix-kick-event-leave-message-not-being-sent.patch} (90%) create mode 100644 patches/server/0559-Don-t-apply-cramming-damage-to-players.patch rename patches/{unapplied/server/0564-Rate-options-and-timings-for-sensors-and-behaviors.patch => server/0560-Rate-options-and-timings-for-sensors-and-behaviors.patch} (96%) rename patches/{unapplied/server/0565-Add-missing-forceDrop-toggles.patch => server/0561-Add-missing-forceDrop-toggles.patch} (56%) rename patches/{unapplied/server/0566-Stinger-API.patch => server/0562-Stinger-API.patch} (74%) rename patches/{unapplied/server/0567-Add-System.out-err-catcher.patch => server/0563-Add-System.out-err-catcher.patch} (97%) rename patches/{unapplied/server/0568-Prevent-AFK-kick-while-watching-end-credits.patch => server/0564-Prevent-AFK-kick-while-watching-end-credits.patch} (79%) rename patches/{unapplied/server/0569-Allow-skipping-writing-of-comments-to-server.propert.patch => server/0565-Allow-skipping-writing-of-comments-to-server.propert.patch} (100%) rename patches/{unapplied/server/0570-Add-PlayerSetSpawnEvent.patch => server/0566-Add-PlayerSetSpawnEvent.patch} (93%) rename patches/{unapplied/server/0571-Make-hoppers-respect-inventory-max-stack-size.patch => server/0567-Make-hoppers-respect-inventory-max-stack-size.patch} (94%) rename patches/{unapplied/server/0572-Optimize-entity-tracker-passenger-checks.patch => server/0568-Optimize-entity-tracker-passenger-checks.patch} (85%) rename patches/{unapplied/server/0573-Config-option-for-Piglins-guarding-chests.patch => server/0569-Config-option-for-Piglins-guarding-chests.patch} (78%) create mode 100644 patches/server/0570-Add-EntityDamageItemEvent.patch rename patches/{unapplied/server/0575-Optimize-indirect-passenger-iteration.patch => server/0571-Optimize-indirect-passenger-iteration.patch} (91%) rename patches/{unapplied/server/0576-Configurable-item-frame-map-cursor-update-interval.patch => server/0572-Configurable-item-frame-map-cursor-update-interval.patch} (90%) rename patches/{unapplied/server/0577-Change-EnderEye-target-without-changing-other-things.patch => server/0573-Change-EnderEye-target-without-changing-other-things.patch} (91%) delete mode 100644 patches/unapplied/server/0563-Don-t-apply-cramming-damage-to-players.patch delete mode 100644 patches/unapplied/server/0574-Add-EntityDamageItemEvent.patch diff --git a/patches/unapplied/server/0558-Fix-return-value-of-Block-applyBoneMeal-always-being.patch b/patches/server/0554-Fix-return-value-of-Block-applyBoneMeal-always-being.patch similarity index 90% rename from patches/unapplied/server/0558-Fix-return-value-of-Block-applyBoneMeal-always-being.patch rename to patches/server/0554-Fix-return-value-of-Block-applyBoneMeal-always-being.patch index a5c4eefb9aa2..40cc161932c9 100644 --- a/patches/unapplied/server/0558-Fix-return-value-of-Block-applyBoneMeal-always-being.patch +++ b/patches/server/0554-Fix-return-value-of-Block-applyBoneMeal-always-being.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix return value of Block#applyBoneMeal always being false diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index 2034858a53c4c887da334cdc7713997daa01124f..ce297420f695404356655b1df2847a32fb98ec59 100644 +index 54fb380a6896731a18c0100722d12099e590cbc9..9c8aac69f01db647e20d49d272ccc107a7edceaf 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -558,7 +558,7 @@ public class CraftBlock implements Block { diff --git a/patches/unapplied/server/0559-Use-getChunkIfLoadedImmediately-in-places.patch b/patches/server/0555-Use-getChunkIfLoadedImmediately-in-places.patch similarity index 75% rename from patches/unapplied/server/0559-Use-getChunkIfLoadedImmediately-in-places.patch rename to patches/server/0555-Use-getChunkIfLoadedImmediately-in-places.patch index b2446b7c2b8b..54ff2754886f 100644 --- a/patches/unapplied/server/0559-Use-getChunkIfLoadedImmediately-in-places.patch +++ b/patches/server/0555-Use-getChunkIfLoadedImmediately-in-places.patch @@ -8,10 +8,10 @@ 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 055650b315d53b56798ded7af2054c3e8e3ee319..c72687fb23e8d01639cce7d79e3f97805d51e01f 100644 +index 355b60f8d0d600973da673db5a954345f3a0094d..83f3f05ffe61d77417bce50ce7ae6a8671605e9e 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -231,7 +231,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -234,7 +234,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent public LevelChunk getChunkIfLoaded(int x, int z) { @@ -21,13 +21,13 @@ index 055650b315d53b56798ded7af2054c3e8e3ee319..c72687fb23e8d01639cce7d79e3f9780 @Override diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 144d243e0d6ba3ae3f0b0bf457fa516e2b4f416f..20a14b4163807b806bf2ce5a88d3c35098bed929 100644 +index aff89d2e3274b91238989fc1e7d8c119c2a3c097..560777a99b58c4f82cc0e8fb087de04a564163b5 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -180,6 +180,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + public CraftServer getCraftServer() { return (CraftServer) Bukkit.getServer(); } - + // Paper start - Use getChunkIfLoadedImmediately + @Override + public boolean hasChunk(int chunkX, int chunkZ) { @@ -35,9 +35,9 @@ index 144d243e0d6ba3ae3f0b0bf457fa516e2b4f416f..20a14b4163807b806bf2ce5a88d3c350 + } + // Paper end - Use getChunkIfLoadedImmediately + + public abstract ResourceKey getTypeKey(); - protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator) { // Paper - create paper world config diff --git a/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java b/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java index 13b34e89bd3e55df1bb1d4d0cf013bafae43f502..df6c97be1b278c97a20390be5d3e60f429383702 100644 --- a/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java diff --git a/patches/unapplied/server/0560-Fix-commands-from-signs-not-firing-command-events.patch b/patches/server/0556-Fix-commands-from-signs-not-firing-command-events.patch similarity index 90% rename from patches/unapplied/server/0560-Fix-commands-from-signs-not-firing-command-events.patch rename to patches/server/0556-Fix-commands-from-signs-not-firing-command-events.patch index b86e34135933..aa87a425fd3a 100644 --- a/patches/unapplied/server/0560-Fix-commands-from-signs-not-firing-command-events.patch +++ b/patches/server/0556-Fix-commands-from-signs-not-firing-command-events.patch @@ -58,10 +58,10 @@ index 0000000000000000000000000000000000000000..01a2bc1feec808790bb93618ce46adb9 + } +} diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java -index 87e272cfb145c37d26b0bf56f97ec784a9bfd98e..bfe8029852385875af4ebe73c63e688f61042021 100644 +index 3339130f3a02e6e395bcd8e3047b35f6f4eca9a9..a34c2fc6ac1418a89d789b8945ca3dad57f64151 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java -@@ -274,7 +274,17 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C +@@ -274,7 +274,17 @@ public class SignBlockEntity extends BlockEntity { ClickEvent chatclickable = chatmodifier.getClickEvent(); if (chatclickable != null && chatclickable.getAction() == ClickEvent.Action.RUN_COMMAND) { @@ -80,16 +80,18 @@ index 87e272cfb145c37d26b0bf56f97ec784a9bfd98e..bfe8029852385875af4ebe73c63e688f flag1 = true; } } -@@ -311,8 +321,23 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C +@@ -314,8 +324,23 @@ public class SignBlockEntity extends BlockEntity { String s = player == null ? "Sign" : player.getName().getString(); Object object = player == null ? Component.literal("Sign") : player.getDisplayName(); +- // CraftBukkit - commandSource +- return new CommandSourceStack(this.commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel) world, 2, s, (Component) object, world.getServer(), player); + // Paper start - Fix commands from signs not firing command events -+ CommandSource commandSource = this.level.paperConfig().misc.showSignClickCommandFailureMsgsToPlayer ? new io.papermc.paper.commands.DelegatingCommandSource(this) { ++ CommandSource commandSource = this.level.paperConfig().misc.showSignClickCommandFailureMsgsToPlayer ? new io.papermc.paper.commands.DelegatingCommandSource(this.commandSource) { + @Override + public void sendSystemMessage(Component message) { -+ if (player != null) { -+ player.sendSystemMessage(message); ++ if (player instanceof final ServerPlayer serverPlayer) { ++ serverPlayer.sendSystemMessage(message); + } + } + @@ -97,10 +99,9 @@ index 87e272cfb145c37d26b0bf56f97ec784a9bfd98e..bfe8029852385875af4ebe73c63e688f + public boolean acceptsFailure() { + return true; + } -+ } : this; ++ } : this.commandSource; + // Paper end - Fix commands from signs not firing command events - // CraftBukkit - this -- return new CommandSourceStack(this, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel) world, 2, s, (Component) object, world.getServer(), player); ++ // CraftBukkit - this + return new CommandSourceStack(commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel) world, 2, s, (Component) object, world.getServer(), player); // Paper - Fix commands from signs not firing command events } diff --git a/patches/unapplied/server/0561-Add-PlayerArmSwingEvent.patch b/patches/server/0557-Add-PlayerArmSwingEvent.patch similarity index 88% rename from patches/unapplied/server/0561-Add-PlayerArmSwingEvent.patch rename to patches/server/0557-Add-PlayerArmSwingEvent.patch index 8e77eadc2373..0b60bfb4b9e5 100644 --- a/patches/unapplied/server/0561-Add-PlayerArmSwingEvent.patch +++ b/patches/server/0557-Add-PlayerArmSwingEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerArmSwingEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index b30c71ad0cc2602d2c026433a94c9ca45977855e..3b20dce53403e241261f270f0a9e32f12b9e368a 100644 +index f4d92374f7865a39a0442d79eb5f146ed4bd2b52..c8ab002ddfcea910f916ee503e930085f6c5cb5a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2412,7 +2412,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2423,7 +2423,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // Paper end - Call interact event // Arm swing animation diff --git a/patches/unapplied/server/0562-Fix-kick-event-leave-message-not-being-sent.patch b/patches/server/0558-Fix-kick-event-leave-message-not-being-sent.patch similarity index 90% rename from patches/unapplied/server/0562-Fix-kick-event-leave-message-not-being-sent.patch rename to patches/server/0558-Fix-kick-event-leave-message-not-being-sent.patch index 461885e49a28..837a22ba70f1 100644 --- a/patches/unapplied/server/0562-Fix-kick-event-leave-message-not-being-sent.patch +++ b/patches/server/0558-Fix-kick-event-leave-message-not-being-sent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix kick event leave message not being sent diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index f20019261a09f425137731f7a4b92e889b617334..9982940af7d10ca7799e2c21ac994ea3afa0b805 100644 +index 7bcb3ef3cb498114428782848e0370ac2497ccdc..99a634760cd04d5e3182254b1d0b817baf1cf87a 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -290,7 +290,6 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -318,7 +318,6 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { public boolean joining = true; public boolean sentListPacket = false; public boolean supressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready @@ -17,10 +17,10 @@ index f20019261a09f425137731f7a4b92e889b617334..9982940af7d10ca7799e2c21ac994ea3 public boolean isRealPlayer; // Paper public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 64450024ce8094874875321537ddab71ab5206fa..6998f32f8d79dbdb6b31ffaa126602fc4a428616 100644 +index 59d20fd62e850a38380d877cef95ed69cb46ecbd..fc242acade3ff06c9213428cde103cf078216382 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -115,6 +115,11 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -116,6 +116,11 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack @Override public void onDisconnect(DisconnectionDetails info) { @@ -32,7 +32,7 @@ index 64450024ce8094874875321537ddab71ab5206fa..6998f32f8d79dbdb6b31ffaa126602fc if (this.isSingleplayerOwner()) { ServerCommonPacketListenerImpl.LOGGER.info("Stopping singleplayer server as player logged out"); this.server.halt(false); -@@ -379,18 +384,17 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -386,18 +391,17 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack // Do not kick the player return; } @@ -55,10 +55,10 @@ index 64450024ce8094874875321537ddab71ab5206fa..6998f32f8d79dbdb6b31ffaa126602fc MinecraftServer minecraftserver = this.server; Connection networkmanager = this.connection; diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 3b20dce53403e241261f270f0a9e32f12b9e368a..08c4d0b79dc1c6e51105487b96e9333a5dd904d7 100644 +index c8ab002ddfcea910f916ee503e930085f6c5cb5a..e9e5b35cd09fe50ce4f2116ca5c38137408105bf 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1894,6 +1894,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1907,6 +1907,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void onDisconnect(DisconnectionDetails info) { @@ -71,7 +71,7 @@ index 3b20dce53403e241261f270f0a9e32f12b9e368a..08c4d0b79dc1c6e51105487b96e9333a // CraftBukkit start - Rarely it would send a disconnect line twice if (this.processedDisconnect) { return; -@@ -1902,11 +1908,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1915,11 +1921,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // CraftBukkit end ServerGamePacketListenerImpl.LOGGER.info("{} lost connection: {}", this.player.getName().getString(), info.reason().getString()); @@ -91,7 +91,7 @@ index 3b20dce53403e241261f270f0a9e32f12b9e368a..08c4d0b79dc1c6e51105487b96e9333a this.chatMessageChain.close(); // CraftBukkit start - Replace vanilla quit message handling with our own. /* -@@ -1916,7 +1928,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1929,7 +1941,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.disconnect(); // Paper start - Adventure @@ -101,10 +101,10 @@ index 3b20dce53403e241261f270f0a9e32f12b9e368a..08c4d0b79dc1c6e51105487b96e9333a 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 55a2f234436808258ef59f889a9b253fe79b82e8..2b0eed116327e74ff66aa065e42899e74b90abf1 100644 +index 3ec8d38ca514048d94d24424d2132a90c10f529f..55e1e8ab83e8ca44735a0b1a7365526d0a3b24e7 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -561,6 +561,11 @@ public abstract class PlayerList { +@@ -511,6 +511,11 @@ public abstract class PlayerList { } public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer) { // CraftBukkit - return string // Paper - return Component diff --git a/patches/server/0559-Don-t-apply-cramming-damage-to-players.patch b/patches/server/0559-Don-t-apply-cramming-damage-to-players.patch new file mode 100644 index 000000000000..a1e4db537b25 --- /dev/null +++ b/patches/server/0559-Don-t-apply-cramming-damage-to-players.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Phoenix616 +Date: Sun, 20 Jun 2021 16:35:42 +0100 +Subject: [PATCH] Don't apply cramming damage to players + +It does not make a lot of sense to damage players if they get crammed, + especially as the usecase of teleporting lots of players to the same + location isn't too uncommon and killing all those players isn't + really what one would expect to happen. + +For those who really want it a config option is provided. + +diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java +index 99a634760cd04d5e3182254b1d0b817baf1cf87a..94cc69ed1ccbcfcc8f431762fef641c313b2f634 100644 +--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java ++++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +@@ -1814,7 +1814,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { + + @Override + public boolean isInvulnerableTo(ServerLevel world, DamageSource source) { +- return super.isInvulnerableTo(world, source) || this.isChangingDimension() && !source.is(DamageTypes.ENDER_PEARL); ++ return super.isInvulnerableTo(world, source) || (this.isChangingDimension() && !source.is(DamageTypes.ENDER_PEARL)) || (!this.level().paperConfig().collisions.allowPlayerCrammingDamage && source.is(DamageTypes.CRAMMING)); // Paper - disable player cramming; + } + + @Override diff --git a/patches/unapplied/server/0564-Rate-options-and-timings-for-sensors-and-behaviors.patch b/patches/server/0560-Rate-options-and-timings-for-sensors-and-behaviors.patch similarity index 96% rename from patches/unapplied/server/0564-Rate-options-and-timings-for-sensors-and-behaviors.patch rename to patches/server/0560-Rate-options-and-timings-for-sensors-and-behaviors.patch index d74af14524dc..3f0d6720edae 100644 --- a/patches/unapplied/server/0564-Rate-options-and-timings-for-sensors-and-behaviors.patch +++ b/patches/server/0560-Rate-options-and-timings-for-sensors-and-behaviors.patch @@ -93,10 +93,10 @@ index f639cafa64d98a001e622882c647701547f5c3ac..9379dd4056018b52c93ed4888dcdc945 protected void tick(ServerLevel world, E entity, long time) { diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java -index 671fc7725d7c801a2ba009da5bd1bc1a9530f187..85b4b24361e785acf75571ff98f924c00ae80748 100644 +index 4d451f6cb5862411848bb9b6b5692ab512dcaa25..8bc7979fb9c2a796921a2a279b78294809f2ed03 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java -@@ -26,8 +26,21 @@ public abstract class Sensor { +@@ -29,8 +29,21 @@ public abstract class Sensor { .ignoreInvisibilityTesting(); private final int scanRate; private long timeToTick; @@ -118,7 +118,7 @@ index 671fc7725d7c801a2ba009da5bd1bc1a9530f187..85b4b24361e785acf75571ff98f924c0 this.scanRate = senseInterval; this.timeToTick = (long)RANDOM.nextInt(senseInterval); } -@@ -38,8 +51,12 @@ public abstract class Sensor { +@@ -41,9 +54,13 @@ public abstract class Sensor { public final void tick(ServerLevel world, E entity) { if (--this.timeToTick <= 0L) { @@ -126,6 +126,7 @@ index 671fc7725d7c801a2ba009da5bd1bc1a9530f187..85b4b24361e785acf75571ff98f924c0 + // Paper start - configurable sensor tick rate and timings + this.timeToTick = java.util.Objects.requireNonNullElse(world.paperConfig().tickRates.sensor.get(entity.getType(), this.configKey), this.scanRate); + this.timing.startTiming(); + this.updateTargetingConditionRanges(entity); + // Paper end this.doTick(world, entity); + this.timing.stopTiming(); // Paper - sensor timings diff --git a/patches/unapplied/server/0565-Add-missing-forceDrop-toggles.patch b/patches/server/0561-Add-missing-forceDrop-toggles.patch similarity index 56% rename from patches/unapplied/server/0565-Add-missing-forceDrop-toggles.patch rename to patches/server/0561-Add-missing-forceDrop-toggles.patch index e11380293a31..b718ecea36d1 100644 --- a/patches/unapplied/server/0565-Add-missing-forceDrop-toggles.patch +++ b/patches/server/0561-Add-missing-forceDrop-toggles.patch @@ -5,106 +5,104 @@ Subject: [PATCH] Add missing forceDrop toggles diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java b/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java -index b9c2b41d9c46c871bab44cfb1d454f4141f1627b..d975b349aa81327c6b6c23e83e9552159217f11e 100644 +index 4ec1f881c05d96d72814ac3dffd3b4bef40c1bce..c34cb8c918e400636856317cc58356d2677e1d52 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java @@ -86,7 +86,9 @@ public class WorkAtComposter extends WorkAtPoi { simpleContainer.removeItemType(Items.WHEAT, m); ItemStack itemStack = simpleContainer.addItem(new ItemStack(Items.BREAD, l)); if (!itemStack.isEmpty()) { -+ entity.forceDrops = true; // Paper - Add missing forceDrop toggles - entity.spawnAtLocation(itemStack, 0.5F); -+ entity.forceDrops = false; // Paper - Add missing forceDrop toggles ++ villager.forceDrops = true; // Paper - Add missing forceDrop toggles + villager.spawnAtLocation(world, itemStack, 0.5F); ++ villager.forceDrops = false; // Paper - Add missing forceDrop toggles } } } diff --git a/src/main/java/net/minecraft/world/entity/animal/Panda.java b/src/main/java/net/minecraft/world/entity/animal/Panda.java -index 8df42121aa22ec9f95a1b8627b64b0ff71e36314..7b3d5322611990406028e59b1409907291e27b21 100644 +index 705c26ceff9371b09311bd7fa796c0efde7ebfee..4f04170b3ec4ff59358e10ccfd0799af3ab590c3 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Panda.java +++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java -@@ -554,11 +554,13 @@ public class Panda extends Animal { - List list1 = loottable.getRandomItems(lootparams); - Iterator iterator1 = list1.iterator(); +@@ -540,7 +540,9 @@ public class Panda extends Animal { -+ this.forceDrops = true; // Paper - Add missing forceDrop toggles - while (iterator1.hasNext()) { - ItemStack itemstack = (ItemStack) iterator1.next(); - - this.spawnAtLocation(itemstack); + if (world1 instanceof ServerLevel worldserver) { + if (worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { ++ this.forceDrops = true; // Paper - Add missing forceDrop toggles + this.dropFromGiftLootTable(worldserver, BuiltInLootTables.PANDA_SNEEZE, this::spawnAtLocation); ++ this.forceDrops = false; // Paper - Add missing forceDrop toggles } -+ this.forceDrops = false; // Paper - Add missing forceDrop toggles } - } -@@ -682,7 +684,9 @@ public class Panda extends Animal { - ItemStack itemstack1 = this.getItemBySlot(EquipmentSlot.MAINHAND); +@@ -664,7 +666,9 @@ public class Panda extends Animal { + ItemStack itemstack1 = this.getItemBySlot(EquipmentSlot.MAINHAND); - if (!itemstack1.isEmpty() && !player.hasInfiniteMaterials()) { -+ this.forceDrops = true; // Paper - Add missing forceDrop toggles - this.spawnAtLocation(itemstack1); -+ this.forceDrops = false; // Paper - Add missing forceDrop toggles - } + if (!itemstack1.isEmpty() && !player.hasInfiniteMaterials()) { ++ this.forceDrops = true; // Paper - Add missing forceDrop toggles + this.spawnAtLocation(worldserver, itemstack1); ++ this.forceDrops = false; // Paper - Add missing forceDrop toggles + } - this.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(itemstack.getItem(), 1)); -@@ -959,7 +963,9 @@ public class Panda extends Animal { + this.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(itemstack.getItem(), 1)); +@@ -942,7 +946,9 @@ public class Panda extends Animal { ItemStack itemstack = Panda.this.getItemBySlot(EquipmentSlot.MAINHAND); if (!itemstack.isEmpty()) { + Panda.this.forceDrops = true; // Paper - Add missing forceDrop toggles - Panda.this.spawnAtLocation(itemstack); + Panda.this.spawnAtLocation(getServerLevel(Panda.this.level()), itemstack); + Panda.this.forceDrops = false; // Paper - Add missing forceDrop toggles Panda.this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY); int i = Panda.this.isLazy() ? Panda.this.random.nextInt(50) + 10 : Panda.this.random.nextInt(150) + 10; diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java -index 691d23bcd3e34a89e14c2e124595e076325dedbc..d2dfa49e124460f4762b950f9ded106d2ec15dc2 100644 +index ec733e71e41a4c89ed9f35ad1d9d4fa912160d27..15a49e3541c8b45db5e472a64fa0cb94c5a72f67 100644 --- a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java -@@ -310,7 +310,9 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento +@@ -323,9 +323,11 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento @Override protected void finishConversion(ServerLevel world) { - PiglinAi.cancelAdmiring(this); + PiglinAi.cancelAdmiring(world, this); + this.forceDrops = true; // Paper - Add missing forceDrop toggles - this.inventory.removeAllItems().forEach(this::spawnAtLocation); + this.inventory.removeAllItems().forEach((itemstack) -> { + this.spawnAtLocation(world, itemstack); + }); + this.forceDrops = false; // Paper - Add missing forceDrop toggles super.finishConversion(world); } diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java -index 545e20e558d3bb934ec4bf32847c9fd83edfd85e..3ca643747535bf7b71e5877ca47f730a2aca4ba5 100644 +index 42b1bd58c6e2c3bd1170171eabfefe315202f340..55868c82bf8bd61ce3494aa9f363c20c88ec6aa6 100644 --- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java +++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java -@@ -271,7 +271,9 @@ public class PiglinAi { +@@ -273,7 +273,9 @@ public class PiglinAi { - private static void holdInOffhand(Piglin piglin, ItemStack stack) { + private static void holdInOffhand(ServerLevel world, Piglin piglin, ItemStack stack) { if (PiglinAi.isHoldingItemInOffHand(piglin)) { + piglin.forceDrops = true; // Paper - Add missing forceDrop toggles - piglin.spawnAtLocation(piglin.getItemInHand(InteractionHand.OFF_HAND)); + piglin.spawnAtLocation(world, piglin.getItemInHand(InteractionHand.OFF_HAND)); + piglin.forceDrops = false; // Paper - Add missing forceDrop toggles } piglin.holdInOffHand(stack); -@@ -331,7 +333,9 @@ public class PiglinAi { +@@ -333,7 +335,9 @@ public class PiglinAi { - protected static void cancelAdmiring(Piglin piglin) { + protected static void cancelAdmiring(ServerLevel world, Piglin piglin) { if (PiglinAi.isAdmiringItem(piglin) && !piglin.getOffhandItem().isEmpty()) { + piglin.forceDrops = true; // Paper - Add missing forceDrop toggles - piglin.spawnAtLocation(piglin.getOffhandItem()); + piglin.spawnAtLocation(world, piglin.getOffhandItem()); + piglin.forceDrops = false; // Paper - Add missing forceDrop toggles piglin.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY); } diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java -index f9bd6f5e54bdb4e2fe4cc73e54961721f440ef07..174d246b0a4d0fc9d769aad08da627ca8487bdf2 100644 +index 4b9b961b1b910775788f85b13ee48abcc474daca..69a0a8aa7eec0a68a1460f6d6a4b604963b884c4 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raider.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java -@@ -230,7 +230,9 @@ public abstract class Raider extends PatrollingMonster { +@@ -233,7 +233,9 @@ public abstract class Raider extends PatrollingMonster { double d0 = (double) this.getEquipmentDropChance(enumitemslot); if (!itemstack1.isEmpty() && (double) Math.max(this.random.nextFloat() - 0.1F, 0.0F) < d0) { + this.forceDrops = true; // Paper - Add missing forceDrop toggles - this.spawnAtLocation(itemstack1); + this.spawnAtLocation(world, itemstack1); + this.forceDrops = false; // Paper - Add missing forceDrop toggles } - this.onItemPickup(item); + this.onItemPickup(itemEntity); diff --git a/patches/unapplied/server/0566-Stinger-API.patch b/patches/server/0562-Stinger-API.patch similarity index 74% rename from patches/unapplied/server/0566-Stinger-API.patch rename to patches/server/0562-Stinger-API.patch index d19c93fe47f8..6b8d804d91f8 100644 --- a/patches/unapplied/server/0566-Stinger-API.patch +++ b/patches/server/0562-Stinger-API.patch @@ -5,25 +5,19 @@ Subject: [PATCH] Stinger API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 19fb8acf614da707f49d922e520e4be93237b2cc..efac0d3ed78c621a52f905b5d7f267b4fb180e65 100644 +index 00db6ba96bda7ceaae8bc69a6b3a42e7a3929485..9870222cc1c46bcc37f9d3d44881606f2b9d038e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -362,6 +362,11 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { - } - // Paper end +@@ -384,6 +384,39 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { + public boolean isInvulnerable() { + return this.getHandle().isInvulnerableTo((ServerLevel) this.getHandle().level(), this.getHandle().damageSources().generic()); } + // Paper start - Bee Stinger API + @Override + public int getBeeStingerCooldown() { + return getHandle().removeStingerTime; + } - - // Paper start - Add methods for working with arrows stuck in living entities - @Override -@@ -376,6 +381,34 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { - } - // Paper end - Add methods for working with arrows stuck in living entities - ++ + @Override + public void setBeeStingerCooldown(int ticks) { + getHandle().removeStingerTime = ticks; @@ -51,7 +45,6 @@ index 19fb8acf614da707f49d922e520e4be93237b2cc..efac0d3ed78c621a52f905b5d7f267b4 + return this.getHandle().removeStingerTime; + } + // Paper end - Bee Stinger API -+ + @Override public void damage(double amount) { - this.damage(amount, this.getHandle().damageSources().generic()); diff --git a/patches/unapplied/server/0567-Add-System.out-err-catcher.patch b/patches/server/0563-Add-System.out-err-catcher.patch similarity index 97% rename from patches/unapplied/server/0567-Add-System.out-err-catcher.patch rename to patches/server/0563-Add-System.out-err-catcher.patch index 139b410ef1f8..c975b94d8f26 100644 --- a/patches/unapplied/server/0567-Add-System.out-err-catcher.patch +++ b/patches/server/0563-Add-System.out-err-catcher.patch @@ -105,10 +105,10 @@ index 0000000000000000000000000000000000000000..a8e813ca89b033f061e695288b3383bd + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 1b320ab17379da9b82320e63babb0f395d4b85a8..e09b0a624a80216db5b6f7882c3765f2eb967b06 100644 +index d921b15100b83cb7073d79f2a1b2bfbdc7b745ca..35e5a3dc58f93b85f93ec5301cc9b5c7505503bc 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -307,6 +307,7 @@ public final class CraftServer implements Server { +@@ -310,6 +310,7 @@ public final class CraftServer implements Server { public Set activeCompatibilities = Collections.emptySet(); private final io.papermc.paper.datapack.PaperDatapackManager datapackManager; // Paper public static Exception excessiveVelEx; // Paper - Velocity warnings diff --git a/patches/unapplied/server/0568-Prevent-AFK-kick-while-watching-end-credits.patch b/patches/server/0564-Prevent-AFK-kick-while-watching-end-credits.patch similarity index 79% rename from patches/unapplied/server/0568-Prevent-AFK-kick-while-watching-end-credits.patch rename to patches/server/0564-Prevent-AFK-kick-while-watching-end-credits.patch index 42e8c37d20ec..a717ad883a1e 100644 --- a/patches/unapplied/server/0568-Prevent-AFK-kick-while-watching-end-credits.patch +++ b/patches/server/0564-Prevent-AFK-kick-while-watching-end-credits.patch @@ -5,13 +5,13 @@ Subject: [PATCH] Prevent AFK kick while watching end credits diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 08c4d0b79dc1c6e51105487b96e9333a5dd904d7..44d1cd3e6047590a989a2b85c759be4c64125a47 100644 +index e9e5b35cd09fe50ce4f2116ca5c38137408105bf..74b21852d9346708a62033c78fac04050b98c80b 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -397,7 +397,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - --this.dropSpamTickCount; - } - +@@ -394,7 +394,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + this.tabSpamThrottler.tick(); // Paper - configurable tab spam limits + this.recipeSpamPackets.tick(); // Paper - auto recipe limit + this.dropSpamThrottler.tick(); - if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L) { + if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L && !this.player.wonGame) { // Paper - Prevent AFK kick while watching end credits this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 diff --git a/patches/unapplied/server/0569-Allow-skipping-writing-of-comments-to-server.propert.patch b/patches/server/0565-Allow-skipping-writing-of-comments-to-server.propert.patch similarity index 100% rename from patches/unapplied/server/0569-Allow-skipping-writing-of-comments-to-server.propert.patch rename to patches/server/0565-Allow-skipping-writing-of-comments-to-server.propert.patch diff --git a/patches/unapplied/server/0570-Add-PlayerSetSpawnEvent.patch b/patches/server/0566-Add-PlayerSetSpawnEvent.patch similarity index 93% rename from patches/unapplied/server/0570-Add-PlayerSetSpawnEvent.patch rename to patches/server/0566-Add-PlayerSetSpawnEvent.patch index 28e265e4064c..11ac225f5643 100644 --- a/patches/unapplied/server/0570-Add-PlayerSetSpawnEvent.patch +++ b/patches/server/0566-Add-PlayerSetSpawnEvent.patch @@ -49,10 +49,10 @@ index a2d0699e8427b2262a2396495111125eccafbb66..15db9368227dbc29d07d74e85bd126b3 } } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index d1b21afe48dbe1e53d4a046434336be580497165..2dd10cada8d36ed5565481f3f5a5fba168ba9b26 100644 +index 94cc69ed1ccbcfcc8f431762fef641c313b2f634..c680b311760601bb539d685bceddba6712d141d4 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1422,7 +1422,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1690,7 +1690,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } else if (this.bedBlocked(blockposition, enumdirection)) { return Either.left(net.minecraft.world.entity.player.Player.BedSleepingProblem.OBSTRUCTED); } else { @@ -61,7 +61,7 @@ index d1b21afe48dbe1e53d4a046434336be580497165..2dd10cada8d36ed5565481f3f5a5fba1 if (this.level().isDay()) { return Either.left(net.minecraft.world.entity.player.Player.BedSleepingProblem.NOT_POSSIBLE_NOW); } else { -@@ -2399,44 +2399,50 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2640,44 +2640,50 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.setRespawnPosition(player.getRespawnDimension(), player.getRespawnPosition(), player.getRespawnAngle(), player.isRespawnForced(), false); } @@ -145,7 +145,7 @@ index d1b21afe48dbe1e53d4a046434336be580497165..2dd10cada8d36ed5565481f3f5a5fba1 } else { this.respawnPosition = null; this.respawnDimension = Level.OVERWORLD; -@@ -2444,6 +2450,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2685,6 +2691,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.respawnForced = false; } @@ -154,12 +154,12 @@ index d1b21afe48dbe1e53d4a046434336be580497165..2dd10cada8d36ed5565481f3f5a5fba1 public SectionPos getLastSectionPos() { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 2b0eed116327e74ff66aa065e42899e74b90abf1..c7dc335d6da208c224d94256eab11b2c3c63745f 100644 +index 55e1e8ab83e8ca44735a0b1a7365526d0a3b24e7..1b6540ae28d73501c59581b1864f0e01ab53e365 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -845,7 +845,7 @@ public abstract class PlayerList { +@@ -803,7 +803,7 @@ public abstract class PlayerList { // CraftBukkit end - if (dimensiontransition.missingRespawnBlock()) { + if (teleporttransition.missingRespawnBlock()) { entityplayer1.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0F)); - entityplayer1.setRespawnPosition(null, null, 0f, false, false, PlayerSpawnChangeEvent.Cause.RESET); // CraftBukkit - SPIGOT-5988: Clear respawn location when obstructed + entityplayer1.setRespawnPosition(null, null, 0f, false, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLAYER_RESPAWN); // CraftBukkit - SPIGOT-5988: Clear respawn location when obstructed // Paper - PlayerSetSpawnEvent @@ -167,17 +167,17 @@ index 2b0eed116327e74ff66aa065e42899e74b90abf1..c7dc335d6da208c224d94256eab11b2c int i = flag ? 1 : 0; diff --git a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java -index ba22ad1e4253477572d10d71db6db0ebc14d6755..94d067e9eeee73183de25165d8c97043fe256103 100644 +index db26b5a0464bd6087eeacaf6dd61eba37365df92..9117c035d5a6ff114b028fad3380ceb1fc2b9691 100644 --- a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java +++ b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java -@@ -89,9 +89,14 @@ public class RespawnAnchorBlock extends Block { +@@ -88,9 +88,14 @@ public class RespawnAnchorBlock extends Block { ServerPlayer entityplayer = (ServerPlayer) player; if (entityplayer.getRespawnDimension() != world.dimension() || !pos.equals(entityplayer.getRespawnPosition())) { - entityplayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true, org.bukkit.event.player.PlayerSpawnChangeEvent.Cause.RESPAWN_ANCHOR); // CraftBukkit + if (entityplayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.RESPAWN_ANCHOR)) { // Paper - Add PlayerSetSpawnEvent world.playSound((Player) null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, SoundEvents.RESPAWN_ANCHOR_SET_SPAWN, SoundSource.BLOCKS, 1.0F, 1.0F); - return InteractionResult.SUCCESS; + return InteractionResult.SUCCESS_SERVER; + // Paper start - Add PlayerSetSpawnEvent + } else { + return InteractionResult.FAIL; @@ -187,10 +187,10 @@ index ba22ad1e4253477572d10d71db6db0ebc14d6755..94d067e9eeee73183de25165d8c97043 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index b747df28b862990d5db08329149272c67eb17d94..bc0d63f90e352ad4158d1dcc0f21a34954279095 100644 +index 5347ad30130d598644902cdc8902e0b77ac4dfb1..b3efe7391b7e43327bcca419efe72811574c0664 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1413,9 +1413,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1426,9 +1426,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setRespawnLocation(Location location, boolean override) { if (location == null) { diff --git a/patches/unapplied/server/0571-Make-hoppers-respect-inventory-max-stack-size.patch b/patches/server/0567-Make-hoppers-respect-inventory-max-stack-size.patch similarity index 94% rename from patches/unapplied/server/0571-Make-hoppers-respect-inventory-max-stack-size.patch rename to patches/server/0567-Make-hoppers-respect-inventory-max-stack-size.patch index c5b4e6692664..fc01c5cad413 100644 --- a/patches/unapplied/server/0571-Make-hoppers-respect-inventory-max-stack-size.patch +++ b/patches/server/0567-Make-hoppers-respect-inventory-max-stack-size.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Make hoppers respect inventory max stack size diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index 1c8a08e317591413426285874de74f4de54efa07..542a5501ac94f57810d34e0f769a9a7855604f91 100644 +index 8913f434967457a16dd708252834ba001ada1a03..b35b44f0776aeb95ef0eda666ba0b652c5e90274 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java @@ -495,15 +495,17 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen diff --git a/patches/unapplied/server/0572-Optimize-entity-tracker-passenger-checks.patch b/patches/server/0568-Optimize-entity-tracker-passenger-checks.patch similarity index 85% rename from patches/unapplied/server/0572-Optimize-entity-tracker-passenger-checks.patch rename to patches/server/0568-Optimize-entity-tracker-passenger-checks.patch index 0dd7d25ba340..0b928beb6190 100644 --- a/patches/unapplied/server/0572-Optimize-entity-tracker-passenger-checks.patch +++ b/patches/server/0568-Optimize-entity-tracker-passenger-checks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Optimize entity tracker passenger checks diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index 9f04dc7817909d81f387b03bfc57d2d9a1d63478..7e8a43ea1b32f444fb66e270a5f6b48bf7bcd2a0 100644 +index 52fcf6df392aaa795335ee9bb7ae406009e2fda1..cfb58901476b1f9bbffd205e82c92d39d587afab 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -71,7 +71,7 @@ public class ServerEntity { +@@ -75,7 +75,7 @@ public class ServerEntity { private Vec3 lastSentMovement; private int tickCount; private int teleportDelay; diff --git a/patches/unapplied/server/0573-Config-option-for-Piglins-guarding-chests.patch b/patches/server/0569-Config-option-for-Piglins-guarding-chests.patch similarity index 78% rename from patches/unapplied/server/0573-Config-option-for-Piglins-guarding-chests.patch rename to patches/server/0569-Config-option-for-Piglins-guarding-chests.patch index 8e2094a53deb..32c61a7ec024 100644 --- a/patches/unapplied/server/0573-Config-option-for-Piglins-guarding-chests.patch +++ b/patches/server/0569-Config-option-for-Piglins-guarding-chests.patch @@ -5,13 +5,13 @@ Subject: [PATCH] Config option for Piglins guarding chests diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java -index 3ca643747535bf7b71e5877ca47f730a2aca4ba5..d601bff8e8f62af78791ad357b51b92faf04e55f 100644 +index 55868c82bf8bd61ce3494aa9f363c20c88ec6aa6..4f3048615a34fc2c067e09aec76af94cde6a74e0 100644 --- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java +++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java -@@ -476,6 +476,7 @@ public class PiglinAi { +@@ -478,6 +478,7 @@ public class PiglinAi { } - public static void angerNearbyPiglins(Player player, boolean blockOpen) { + public static void angerNearbyPiglins(ServerLevel world, Player player, boolean blockOpen) { + if (!player.level().paperConfig().entities.behavior.piglinsGuardChests) return; // Paper - Config option for Piglins guarding chests List list = player.level().getEntitiesOfClass(Piglin.class, player.getBoundingBox().inflate(16.0D)); diff --git a/patches/server/0570-Add-EntityDamageItemEvent.patch b/patches/server/0570-Add-EntityDamageItemEvent.patch new file mode 100644 index 000000000000..e6822b715e6b --- /dev/null +++ b/patches/server/0570-Add-EntityDamageItemEvent.patch @@ -0,0 +1,94 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Tue, 22 Dec 2020 13:52:48 -0800 +Subject: [PATCH] Add EntityDamageItemEvent + + +diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java +index f00b756fe5dad616323e3b11e35e27353f347042..8c9ae9ac38def29ae4cd8944395e566e434d46d0 100644 +--- a/src/main/java/net/minecraft/world/item/ItemStack.java ++++ b/src/main/java/net/minecraft/world/item/ItemStack.java +@@ -692,11 +692,11 @@ public final class ItemStack implements DataComponentHolder { + return this.isDamageableItem() && this.getDamageValue() >= this.getMaxDamage() - 1; + } + +- public void hurtAndBreak(int amount, ServerLevel world, @Nullable ServerPlayer player, Consumer breakCallback) { ++ public void hurtAndBreak(int amount, ServerLevel world, @Nullable LivingEntity player, Consumer breakCallback) { // Paper - Add EntityDamageItemEvent + int j = this.processDurabilityChange(amount, world, player); + // CraftBukkit start +- if (player != null) { +- PlayerItemDamageEvent event = new PlayerItemDamageEvent(player.getBukkitEntity(), CraftItemStack.asCraftMirror(this), j); ++ if (player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent ++ PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), j); // Paper - Add EntityDamageItemEvent + event.getPlayer().getServer().getPluginManager().callEvent(event); + + if (j != event.getDamage() || event.isCancelled()) { +@@ -707,6 +707,14 @@ public final class ItemStack implements DataComponentHolder { + } + + j = event.getDamage(); ++ // Paper start - Add EntityDamageItemEvent ++ } else if (player != null) { ++ io.papermc.paper.event.entity.EntityDamageItemEvent event = new io.papermc.paper.event.entity.EntityDamageItemEvent(player.getBukkitLivingEntity(), CraftItemStack.asCraftMirror(this), amount); ++ if (!event.callEvent()) { ++ return; ++ } ++ j = event.getDamage(); ++ // Paper end - Add EntityDamageItemEvent + } + // CraftBukkit end + +@@ -716,21 +724,21 @@ public final class ItemStack implements DataComponentHolder { + + } + +- private int processDurabilityChange(int baseDamage, ServerLevel world, @Nullable ServerPlayer player) { +- return !this.isDamageableItem() ? 0 : (player != null && player.hasInfiniteMaterials() ? 0 : (baseDamage > 0 ? EnchantmentHelper.processDurabilityChange(world, this, baseDamage) : baseDamage)); ++ private int processDurabilityChange(int baseDamage, ServerLevel world, @Nullable LivingEntity player) { // Paper - Add EntityDamageItemEvent ++ return !this.isDamageableItem() ? 0 : (player instanceof ServerPlayer && player.hasInfiniteMaterials() ? 0 : (baseDamage > 0 ? EnchantmentHelper.processDurabilityChange(world, this, baseDamage) : baseDamage)); // Paper - Add EntityDamageItemEvent + } + +- private void applyDamage(int damage, @Nullable ServerPlayer player, Consumer breakCallback) { +- if (player != null) { +- CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(player, this, damage); ++ private void applyDamage(int damage, @Nullable LivingEntity player, Consumer breakCallback) { // Paper - Add EntityDamageItemEvent ++ if (player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent ++ CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(serverPlayer, this, damage); // Paper - Add EntityDamageItemEvent + } + + this.setDamageValue(damage); + if (this.isBroken()) { + Item item = this.getItem(); + // CraftBukkit start - Check for item breaking +- if (this.count == 1 && player != null) { +- org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent(player, this); ++ if (this.count == 1 && player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent ++ org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent(serverPlayer, this); // Paper - Add EntityDamageItemEvent + } + // CraftBukkit end + +@@ -768,7 +776,7 @@ public final class ItemStack implements DataComponentHolder { + entityplayer = null; + } + +- this.hurtAndBreak(amount, worldserver, entityplayer, (item) -> { ++ this.hurtAndBreak(amount, worldserver, entity, (item) -> { // Paper - Add EntityDamageItemEvent + entity.onEquippedItemBroken(item, slot); + }); + } +diff --git a/src/main/java/net/minecraft/world/item/enchantment/effects/ChangeItemDamage.java b/src/main/java/net/minecraft/world/item/enchantment/effects/ChangeItemDamage.java +index 0019c8548aa4901b248ced32cc1475ad14b725bf..7e21c8b10debd70c35a138c14b9b177ef6fff37a 100644 +--- a/src/main/java/net/minecraft/world/item/enchantment/effects/ChangeItemDamage.java ++++ b/src/main/java/net/minecraft/world/item/enchantment/effects/ChangeItemDamage.java +@@ -21,9 +21,9 @@ public record ChangeItemDamage(LevelBasedValue amount) implements EnchantmentEnt + public void apply(ServerLevel world, int level, EnchantedItemInUse context, Entity user, Vec3 pos) { + ItemStack itemStack = context.itemStack(); + if (itemStack.has(DataComponents.MAX_DAMAGE) && itemStack.has(DataComponents.DAMAGE)) { +- ServerPlayer serverPlayer2 = context.owner() instanceof ServerPlayer serverPlayer ? serverPlayer : null; ++ // ServerPlayer serverPlayer2 = context.owner() instanceof ServerPlayer serverPlayer ? serverPlayer : null; // Paper - EntityDamageItemEvent - always pass in entity + int i = (int)this.amount.calculate(level); +- itemStack.hurtAndBreak(i, world, serverPlayer2, context.onBreak()); ++ itemStack.hurtAndBreak(i, world, context.owner(), context.onBreak()); // Paper - EntityDamageItemEvent - always pass in entity + } + } + diff --git a/patches/unapplied/server/0575-Optimize-indirect-passenger-iteration.patch b/patches/server/0571-Optimize-indirect-passenger-iteration.patch similarity index 91% rename from patches/unapplied/server/0575-Optimize-indirect-passenger-iteration.patch rename to patches/server/0571-Optimize-indirect-passenger-iteration.patch index dc1758edec89..3d3851641848 100644 --- a/patches/unapplied/server/0575-Optimize-indirect-passenger-iteration.patch +++ b/patches/server/0571-Optimize-indirect-passenger-iteration.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Optimize indirect passenger iteration diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index da184893d617311a43f9ce176a965f8417a2876d..9844550e4ed6c150250b165acc26d52ec9401184 100644 +index 42004784a5421bd27d0a4a2bf1c17d14341fc5a4..ea1492559653063bb14b934f4d40d910b81d8801 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -3889,20 +3889,34 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4087,20 +4087,34 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } private Stream getIndirectPassengersStream() { @@ -43,7 +43,7 @@ index da184893d617311a43f9ce176a965f8417a2876d..9844550e4ed6c150250b165acc26d52e return () -> { return this.getIndirectPassengersStream().iterator(); }; -@@ -3915,6 +3929,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4113,6 +4127,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public boolean hasExactlyOnePlayerPassenger() { diff --git a/patches/unapplied/server/0576-Configurable-item-frame-map-cursor-update-interval.patch b/patches/server/0572-Configurable-item-frame-map-cursor-update-interval.patch similarity index 90% rename from patches/unapplied/server/0576-Configurable-item-frame-map-cursor-update-interval.patch rename to patches/server/0572-Configurable-item-frame-map-cursor-update-interval.patch index a6389cdcbb0d..98f717ebc173 100644 --- a/patches/unapplied/server/0576-Configurable-item-frame-map-cursor-update-interval.patch +++ b/patches/server/0572-Configurable-item-frame-map-cursor-update-interval.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Configurable item frame map cursor update interval diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index 7e8a43ea1b32f444fb66e270a5f6b48bf7bcd2a0..f3f93710846ce0f6d53845e0b49331646a4e8332 100644 +index cfb58901476b1f9bbffd205e82c92d39d587afab..bc0f1aa61e68d2a8638d89c10bc5c71922d057f9 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -116,7 +116,7 @@ public class ServerEntity { +@@ -120,7 +120,7 @@ public class ServerEntity { if (true || this.tickCount % 10 == 0) { // CraftBukkit - Moved below, should always enter this block ItemStack itemstack = entityitemframe.getItem(); diff --git a/patches/unapplied/server/0577-Change-EnderEye-target-without-changing-other-things.patch b/patches/server/0573-Change-EnderEye-target-without-changing-other-things.patch similarity index 91% rename from patches/unapplied/server/0577-Change-EnderEye-target-without-changing-other-things.patch rename to patches/server/0573-Change-EnderEye-target-without-changing-other-things.patch index 53d06a36ec9d..5612422ea7d8 100644 --- a/patches/unapplied/server/0577-Change-EnderEye-target-without-changing-other-things.patch +++ b/patches/server/0573-Change-EnderEye-target-without-changing-other-things.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Change EnderEye target without changing other things diff --git a/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java b/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java -index 8b0ccd1aa0f2f1d2326c6071f16e641afc101751..fca3786d0a3f99a3e61e7a4b2251361276eff9d7 100644 +index 573b96c9e0c89860c3da031c5aa239f6a7ad0c6e..fd1f5de7dc151dfd187d23e022b2c5435ed8accc 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java +++ b/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java -@@ -69,6 +69,11 @@ public class EyeOfEnder extends Entity implements ItemSupplier { +@@ -76,6 +76,11 @@ public class EyeOfEnder extends Entity implements ItemSupplier { } public void signalTo(BlockPos pos) { @@ -20,7 +20,7 @@ index 8b0ccd1aa0f2f1d2326c6071f16e641afc101751..fca3786d0a3f99a3e61e7a4b22513612 double d0 = (double) pos.getX(); int i = pos.getY(); double d1 = (double) pos.getZ(); -@@ -86,8 +91,10 @@ public class EyeOfEnder extends Entity implements ItemSupplier { +@@ -93,8 +98,10 @@ public class EyeOfEnder extends Entity implements ItemSupplier { this.tz = d1; } diff --git a/patches/unapplied/server/0563-Don-t-apply-cramming-damage-to-players.patch b/patches/unapplied/server/0563-Don-t-apply-cramming-damage-to-players.patch deleted file mode 100644 index f23c0c584fa6..000000000000 --- a/patches/unapplied/server/0563-Don-t-apply-cramming-damage-to-players.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Phoenix616 -Date: Sun, 20 Jun 2021 16:35:42 +0100 -Subject: [PATCH] Don't apply cramming damage to players - -It does not make a lot of sense to damage players if they get crammed, - especially as the usecase of teleporting lots of players to the same - location isn't too uncommon and killing all those players isn't - really what one would expect to happen. - -For those who really want it a config option is provided. - -diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 9982940af7d10ca7799e2c21ac994ea3afa0b805..d1b21afe48dbe1e53d4a046434336be580497165 100644 ---- a/src/main/java/net/minecraft/server/level/ServerPlayer.java -+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -95,6 +95,7 @@ import net.minecraft.util.Mth; - import net.minecraft.util.RandomSource; - import net.minecraft.util.Unit; - import net.minecraft.world.damagesource.DamageSource; -+import net.minecraft.world.damagesource.DamageSources; - import net.minecraft.world.effect.MobEffectInstance; - import net.minecraft.world.effect.MobEffects; - import net.minecraft.world.entity.Entity; -@@ -1545,7 +1546,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { - - @Override - public boolean isInvulnerableTo(DamageSource damageSource) { -- return super.isInvulnerableTo(damageSource) || this.isChangingDimension(); -+ return super.isInvulnerableTo(damageSource) || this.isChangingDimension() || !this.level().paperConfig().collisions.allowPlayerCrammingDamage && damageSource == damageSources().cramming(); // Paper - disable player cramming - } - - @Override diff --git a/patches/unapplied/server/0574-Add-EntityDamageItemEvent.patch b/patches/unapplied/server/0574-Add-EntityDamageItemEvent.patch deleted file mode 100644 index fc8649b86d92..000000000000 --- a/patches/unapplied/server/0574-Add-EntityDamageItemEvent.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Tue, 22 Dec 2020 13:52:48 -0800 -Subject: [PATCH] Add EntityDamageItemEvent - - -diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index d1eac70fbfe2d863d3a342ed0e83223c65c36c03..a98d76c90cd855e723e7a8d810eee88a882d8b5c 100644 ---- a/src/main/java/net/minecraft/world/item/ItemStack.java -+++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -646,14 +646,14 @@ public final class ItemStack implements DataComponentHolder { - return (Integer) this.getOrDefault(DataComponents.MAX_DAMAGE, 0); - } - -- public void hurtAndBreak(int amount, ServerLevel world, @Nullable ServerPlayer player, Consumer breakCallback) { -+ public void hurtAndBreak(int amount, ServerLevel world, @Nullable LivingEntity player, Consumer breakCallback) { // Paper - Add EntityDamageItemEvent - if (this.isDamageableItem()) { - if (player == null || !player.hasInfiniteMaterials()) { - if (amount > 0) { - amount = EnchantmentHelper.processDurabilityChange(world, this, amount); - // CraftBukkit start -- if (player != null) { -- PlayerItemDamageEvent event = new PlayerItemDamageEvent(player.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount); -+ if (player instanceof ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent -+ PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount); // Paper - Add EntityDamageItemEvent - event.getPlayer().getServer().getPluginManager().callEvent(event); - - if (amount != event.getDamage() || event.isCancelled()) { -@@ -664,6 +664,14 @@ public final class ItemStack implements DataComponentHolder { - } - - amount = event.getDamage(); -+ // Paper start - Add EntityDamageItemEvent -+ } else if (player != null) { -+ io.papermc.paper.event.entity.EntityDamageItemEvent event = new io.papermc.paper.event.entity.EntityDamageItemEvent(player.getBukkitLivingEntity(), CraftItemStack.asCraftMirror(this), amount); -+ if (!event.callEvent()) { -+ return; -+ } -+ amount = event.getDamage(); -+ // Paper end - Add EntityDamageItemEvent - } - // CraftBukkit end - if (amount <= 0) { -@@ -671,8 +679,8 @@ public final class ItemStack implements DataComponentHolder { - } - } - -- if (player != null && amount != 0) { -- CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(player, this, this.getDamageValue() + amount); -+ if (player instanceof ServerPlayer serverPlayer && amount != 0) { // Paper - Add EntityDamageItemEvent -+ CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(serverPlayer, this, this.getDamageValue() + amount); // Paper - Add EntityDamageItemEvent - } - - int j = this.getDamageValue() + amount; -@@ -681,8 +689,8 @@ public final class ItemStack implements DataComponentHolder { - if (j >= this.getMaxDamage()) { - Item item = this.getItem(); - // CraftBukkit start - Check for item breaking -- if (this.count == 1 && player != null) { -- org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent(player, this); -+ if (this.count == 1 && player != null && player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent -+ org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent(serverPlayer, this); // Paper - Add EntityDamageItemEvent - } - // CraftBukkit end - -@@ -706,7 +714,7 @@ public final class ItemStack implements DataComponentHolder { - entityplayer = null; - } - -- this.hurtAndBreak(amount, worldserver, entityplayer, (item) -> { -+ this.hurtAndBreak(amount, worldserver, entity, (item) -> { // Paper - Add EntityDamageItemEvent - entity.onEquippedItemBroken(item, slot); - }); - } -diff --git a/src/main/java/net/minecraft/world/item/enchantment/effects/DamageItem.java b/src/main/java/net/minecraft/world/item/enchantment/effects/DamageItem.java -index 70796eef426eece0bc93a173f54e90645377b502..82ac989ca836e3beef7c3773db0183a7e51780e0 100644 ---- a/src/main/java/net/minecraft/world/item/enchantment/effects/DamageItem.java -+++ b/src/main/java/net/minecraft/world/item/enchantment/effects/DamageItem.java -@@ -16,8 +16,8 @@ public record DamageItem(LevelBasedValue amount) implements EnchantmentEntityEff - - @Override - public void apply(ServerLevel world, int level, EnchantedItemInUse context, Entity user, Vec3 pos) { -- ServerPlayer serverPlayer2 = context.owner() instanceof ServerPlayer serverPlayer ? serverPlayer : null; -- context.itemStack().hurtAndBreak((int)this.amount.calculate(level), world, serverPlayer2, context.onBreak()); -+ // ServerPlayer serverPlayer2 = context.owner() instanceof ServerPlayer serverPlayer ? serverPlayer : null; // Paper - always pass in entity -+ context.itemStack().hurtAndBreak((int)this.amount.calculate(level), world, context.owner(), context.onBreak()); // Paper - always pass in entity - } - - @Override From cbf64163ba640ce1f6e5f6c6efc7d6ac676cdc89 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Wed, 23 Oct 2024 20:43:06 +0100 Subject: [PATCH 026/119] A bunch of patches --- .../0574-Add-BlockBreakBlockEvent.patch} | 22 ++--- ...-data-components-copy-in-smithing-r.patch} | 81 ++++++++++-------- .../0576-More-CommandBlock-API.patch} | 0 ...-missing-team-sidebar-display-slots.patch} | 2 +- ...0578-Add-back-EntityPortalExitEvent.patch} | 23 +++-- ...-find-targets-for-lightning-strikes.patch} | 12 +-- .../0580-Get-entity-default-attributes.patch} | 2 +- .../0581-Left-handed-API.patch} | 4 +- .../0582-Add-more-advancement-API.patch} | 0 ...583-Add-ItemFactory-getSpawnEgg-API.patch} | 4 +- .../0584-Add-critical-damage-API.patch} | 22 ++--- .../0585-Fix-issues-with-mob-conversion.patch | 83 +++++++++++++++++++ ...Collision-methods-to-various-places.patch} | 2 +- .../0587-Goat-ram-API.patch} | 6 +- ...dd-API-for-resetting-a-single-score.patch} | 0 ...9-Add-Raw-Byte-Entity-Serialization.patch} | 10 +-- ...90-Vanilla-command-permission-fixes.patch} | 6 +- ...logic-for-inventories-on-chunk-unlo.patch} | 12 +-- ...92-Fix-GameProfileCache-concurrency.patch} | 0 ...593-Improve-and-expand-AsyncCatcher.patch} | 24 +++--- .../0589-Fix-issues-with-mob-conversion.patch | 59 ------------- 21 files changed, 205 insertions(+), 169 deletions(-) rename patches/{unapplied/server/0578-Add-BlockBreakBlockEvent.patch => server/0574-Add-BlockBreakBlockEvent.patch} (84%) rename patches/{unapplied/server/0579-Option-to-prevent-data-components-copy-in-smithing-r.patch => server/0575-Option-to-prevent-data-components-copy-in-smithing-r.patch} (61%) rename patches/{unapplied/server/0580-More-CommandBlock-API.patch => server/0576-More-CommandBlock-API.patch} (100%) rename patches/{unapplied/server/0581-Add-missing-team-sidebar-display-slots.patch => server/0577-Add-missing-team-sidebar-display-slots.patch} (98%) rename patches/{unapplied/server/0582-Add-back-EntityPortalExitEvent.patch => server/0578-Add-back-EntityPortalExitEvent.patch} (57%) rename patches/{unapplied/server/0583-Add-methods-to-find-targets-for-lightning-strikes.patch => server/0579-Add-methods-to-find-targets-for-lightning-strikes.patch} (84%) rename patches/{unapplied/server/0584-Get-entity-default-attributes.patch => server/0580-Get-entity-default-attributes.patch} (98%) rename patches/{unapplied/server/0585-Left-handed-API.patch => server/0581-Left-handed-API.patch} (84%) rename patches/{unapplied/server/0586-Add-more-advancement-API.patch => server/0582-Add-more-advancement-API.patch} (100%) rename patches/{unapplied/server/0587-Add-ItemFactory-getSpawnEgg-API.patch => server/0583-Add-ItemFactory-getSpawnEgg-API.patch} (95%) rename patches/{unapplied/server/0588-Add-critical-damage-API.patch => server/0584-Add-critical-damage-API.patch} (85%) create mode 100644 patches/server/0585-Fix-issues-with-mob-conversion.patch rename patches/{unapplied/server/0590-Add-hasCollision-methods-to-various-places.patch => server/0586-Add-hasCollision-methods-to-various-places.patch} (96%) rename patches/{unapplied/server/0591-Goat-ram-API.patch => server/0587-Goat-ram-API.patch} (88%) rename patches/{unapplied/server/0592-Add-API-for-resetting-a-single-score.patch => server/0588-Add-API-for-resetting-a-single-score.patch} (100%) rename patches/{unapplied/server/0593-Add-Raw-Byte-Entity-Serialization.patch => server/0589-Add-Raw-Byte-Entity-Serialization.patch} (92%) rename patches/{unapplied/server/0594-Vanilla-command-permission-fixes.patch => server/0590-Vanilla-command-permission-fixes.patch} (94%) rename patches/{unapplied/server/0595-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch => server/0591-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch} (87%) rename patches/{unapplied/server/0596-Fix-GameProfileCache-concurrency.patch => server/0592-Fix-GameProfileCache-concurrency.patch} (100%) rename patches/{unapplied/server/0597-Improve-and-expand-AsyncCatcher.patch => server/0593-Improve-and-expand-AsyncCatcher.patch} (92%) delete mode 100644 patches/unapplied/server/0589-Fix-issues-with-mob-conversion.patch diff --git a/patches/unapplied/server/0578-Add-BlockBreakBlockEvent.patch b/patches/server/0574-Add-BlockBreakBlockEvent.patch similarity index 84% rename from patches/unapplied/server/0578-Add-BlockBreakBlockEvent.patch rename to patches/server/0574-Add-BlockBreakBlockEvent.patch index 4bc0c5116fcb..a5e51ea2aa64 100644 --- a/patches/unapplied/server/0578-Add-BlockBreakBlockEvent.patch +++ b/patches/server/0574-Add-BlockBreakBlockEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add BlockBreakBlockEvent diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index 6d0a90e9c637edff5c5ce1355a3b45f0fb7f4154..232e6216dc36aa698047fc0badf78c347414b3a5 100644 +index 43c2b411115d3a8a0e47d3e2277789b2667897af..4d140bd83ca0e1554afad80ec4fc6186188a79d8 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -305,6 +305,24 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -304,6 +304,24 @@ public class Block extends BlockBehaviour implements ItemLike { } @@ -34,10 +34,10 @@ index 6d0a90e9c637edff5c5ce1355a3b45f0fb7f4154..232e6216dc36aa698047fc0badf78c34 if (world instanceof ServerLevel) { Block.getDrops(state, (ServerLevel) world, pos, blockEntity, entity, tool).forEach((itemstack1) -> { diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java -index 4aa34b7df734bb755906b228e0df9eb629569ea0..2f2c9fb65d4cc8bd40303216e03c5c1956305ff4 100644 +index e84501fdce7b94300b1f5d6d20e2db90b175454d..560797552799f7874133fd4aaf6e421609a54dbf 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java +++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java -@@ -403,7 +403,7 @@ public class PistonBaseBlock extends DirectionalBlock { +@@ -406,7 +406,7 @@ public class PistonBaseBlock extends DirectionalBlock { iblockdata1 = world.getBlockState(blockposition3); BlockEntity tileentity = iblockdata1.hasBlockEntity() ? world.getBlockEntity(blockposition3) : null; @@ -47,11 +47,11 @@ index 4aa34b7df734bb755906b228e0df9eb629569ea0..2f2c9fb65d4cc8bd40303216e03c5c19 world.gameEvent((Holder) GameEvent.BLOCK_DESTROY, blockposition3, GameEvent.Context.of(iblockdata1)); if (!iblockdata1.is(BlockTags.FIRE)) { diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -index 3a2ae2bca410708736da64560e74b8010444f2dc..1c0712295695727ee9c4d430d4157b8e17cbd71f 100644 +index 83dc8bcd9e2b8ecbd32225e4e10aec392ef28325..261e5994d13f8bc30490b86691c80c0a21e7640a 100644 --- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -@@ -295,7 +295,7 @@ public abstract class FlowingFluid extends Fluid { - ((LiquidBlockContainer) state.getBlock()).placeLiquid(world, pos, state, fluidState); +@@ -316,7 +316,7 @@ public abstract class FlowingFluid extends Fluid { + ifluidcontainer.placeLiquid(world, pos, state, fluidState); } else { if (!state.isAir()) { - this.beforeDestroyingBlock(world, pos, state); @@ -59,19 +59,19 @@ index 3a2ae2bca410708736da64560e74b8010444f2dc..1c0712295695727ee9c4d430d4157b8e } world.setBlock(pos, fluidState.createLegacyBlock(), 3); -@@ -303,6 +303,7 @@ public abstract class FlowingFluid extends Fluid { +@@ -324,6 +324,7 @@ public abstract class FlowingFluid extends Fluid { } + protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) { beforeDestroyingBlock(world, pos, state); } // Paper - Add BlockBreakBlockEvent protected abstract void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state); - private static short getCacheKey(BlockPos from, BlockPos to) { + protected int getSlopeDistance(LevelReader world, BlockPos pos, int i, Direction direction, BlockState state, FlowingFluid.SpreadContext spreadCache) { diff --git a/src/main/java/net/minecraft/world/level/material/WaterFluid.java b/src/main/java/net/minecraft/world/level/material/WaterFluid.java -index 7f40e8196cb966424ae63043d1f54e661dbce715..21b4afd053e01073eb514264d4960f0f3b1ee3d8 100644 +index 421f5d9a57d87a87a801213d562ad5fe244e7b65..0a7c05c08bf8c6c331b91e399dc4103a91dc20fe 100644 --- a/src/main/java/net/minecraft/world/level/material/WaterFluid.java +++ b/src/main/java/net/minecraft/world/level/material/WaterFluid.java -@@ -80,6 +80,13 @@ public abstract class WaterFluid extends FlowingFluid { +@@ -81,6 +81,13 @@ public abstract class WaterFluid extends FlowingFluid { return world.getGameRules().getBoolean(GameRules.RULE_WATER_SOURCE_CONVERSION); } diff --git a/patches/unapplied/server/0579-Option-to-prevent-data-components-copy-in-smithing-r.patch b/patches/server/0575-Option-to-prevent-data-components-copy-in-smithing-r.patch similarity index 61% rename from patches/unapplied/server/0579-Option-to-prevent-data-components-copy-in-smithing-r.patch rename to patches/server/0575-Option-to-prevent-data-components-copy-in-smithing-r.patch index b7f49fa1dfd5..47046be6aed4 100644 --- a/patches/unapplied/server/0579-Option-to-prevent-data-components-copy-in-smithing-r.patch +++ b/patches/server/0575-Option-to-prevent-data-components-copy-in-smithing-r.patch @@ -5,27 +5,26 @@ Subject: [PATCH] Option to prevent data components copy in smithing recipes diff --git a/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java b/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java -index 83b77e170f2945e9b40f302c4cf65efb1628c84a..d64a1c1e146d5d9aa940a37dbee16889c9bab783 100644 +index fa003ce16020eaab554bfd833ace779c8cefc617..d432b91b4051036d8b339a6418cdbce5c371bc1b 100644 --- a/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java +++ b/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java -@@ -22,8 +22,15 @@ public class SmithingTransformRecipe implements SmithingRecipe { - final Ingredient base; - final Ingredient addition; +@@ -30,8 +30,14 @@ public class SmithingTransformRecipe implements SmithingRecipe { final ItemStack result; + @Nullable + private PlacementInfo placementInfo; + final boolean copyDataComponents; // Paper - Option to prevent data components copy - public SmithingTransformRecipe(Ingredient template, Ingredient base, Ingredient addition, ItemStack result) { -+ // Paper start - Option to prevent data components copy + public SmithingTransformRecipe(Optional template, Optional base, Optional addition, ItemStack result) { + this(template, base, addition, result, true); + } -+ public SmithingTransformRecipe(Ingredient template, Ingredient base, Ingredient addition, ItemStack result, boolean copyDataComponents) { ++ public SmithingTransformRecipe(Optional template, Optional base, Optional addition, ItemStack result, boolean copyDataComponents) { + this.copyDataComponents = copyDataComponents; + // Paper end - Option to prevent data components copy this.template = template; this.base = base; this.addition = addition; -@@ -37,7 +44,9 @@ public class SmithingTransformRecipe implements SmithingRecipe { - public ItemStack assemble(SmithingRecipeInput input, HolderLookup.Provider lookup) { +@@ -41,7 +47,9 @@ public class SmithingTransformRecipe implements SmithingRecipe { + public ItemStack assemble(SmithingRecipeInput input, HolderLookup.Provider registries) { ItemStack itemstack = input.base().transmuteCopy(this.result.getItem(), this.result.getCount()); + if (this.copyDataComponents) { // Paper - Option to prevent data components copy @@ -34,7 +33,7 @@ index 83b77e170f2945e9b40f302c4cf65efb1628c84a..d64a1c1e146d5d9aa940a37dbee16889 return itemstack; } -@@ -76,7 +85,7 @@ public class SmithingTransformRecipe implements SmithingRecipe { +@@ -84,7 +92,7 @@ public class SmithingTransformRecipe implements SmithingRecipe { public Recipe toBukkitRecipe(NamespacedKey id) { CraftItemStack result = CraftItemStack.asCraftMirror(this.result); @@ -44,35 +43,49 @@ index 83b77e170f2945e9b40f302c4cf65efb1628c84a..d64a1c1e146d5d9aa940a37dbee16889 return recipe; } diff --git a/src/main/java/net/minecraft/world/item/crafting/SmithingTrimRecipe.java b/src/main/java/net/minecraft/world/item/crafting/SmithingTrimRecipe.java -index 4ea43872f9da72ed959dd0709f959402d01d5fe0..f6f10da21a752e927409ea16076701c4ec403a0e 100644 +index a5adce474b2e78233c39cbed367e3d14515923b1..7209170454f10225d7d4a4a107e6717fc18a02ad 100644 --- a/src/main/java/net/minecraft/world/item/crafting/SmithingTrimRecipe.java +++ b/src/main/java/net/minecraft/world/item/crafting/SmithingTrimRecipe.java -@@ -30,8 +30,15 @@ public class SmithingTrimRecipe implements SmithingRecipe { - final Ingredient template; - final Ingredient base; - final Ingredient addition; +@@ -35,18 +35,28 @@ public class SmithingTrimRecipe implements SmithingRecipe { + final Optional addition; + @Nullable + private PlacementInfo placementInfo; + final boolean copyDataComponents; // Paper - Option to prevent data components copy - public SmithingTrimRecipe(Ingredient template, Ingredient base, Ingredient addition) { + public SmithingTrimRecipe(Optional template, Optional base, Optional addition) { + // Paper start - Option to prevent data components copy + this(template, base, addition, true); + } -+ public SmithingTrimRecipe(Ingredient template, Ingredient base, Ingredient addition, boolean copyDataComponents) { ++ public SmithingTrimRecipe(Optional template, Optional base, Optional addition, boolean copyDataComponents) { + this.copyDataComponents = copyDataComponents; + // Paper end - Option to prevent data components copy this.template = template; this.base = base; this.addition = addition; -@@ -55,7 +62,7 @@ public class SmithingTrimRecipe implements SmithingRecipe { - return ItemStack.EMPTY; - } + } + + public ItemStack assemble(SmithingRecipeInput input, HolderLookup.Provider registries) { +- return SmithingTrimRecipe.applyTrim(registries, input.base(), input.addition(), input.template()); ++ return SmithingTrimRecipe.applyTrim(registries, input.base(), input.addition(), input.template(), this.copyDataComponents); + } + + public static ItemStack applyTrim(HolderLookup.Provider registries, ItemStack base, ItemStack addition, ItemStack template) { ++ return applyTrim(registries, base, addition, template, true); ++ } ++ public static ItemStack applyTrim(HolderLookup.Provider registries, ItemStack base, ItemStack addition, ItemStack template, boolean copyDataComponents) { + Optional> optional = TrimMaterials.getFromIngredient(registries, addition); + Optional> optional1 = TrimPatterns.getFromTemplate(registries, template); -- ItemStack itemstack1 = itemstack.copyWithCount(1); -+ ItemStack itemstack1 = this.copyDataComponents ? itemstack.copyWithCount(1) : new ItemStack(itemstack.getItem(), 1); // Paper - Option to prevent data components copy +@@ -56,7 +66,7 @@ public class SmithingTrimRecipe implements SmithingRecipe { + if (armortrim != null && armortrim.hasPatternAndMaterial((Holder) optional1.get(), (Holder) optional.get())) { + return ItemStack.EMPTY; + } else { +- ItemStack itemstack3 = base.copyWithCount(1); ++ ItemStack itemstack3 = copyDataComponents ? base.copyWithCount(1) : new ItemStack(base.getItem(), 1); // Paper - Option to prevent data components copy - itemstack1.set(DataComponents.TRIM, new ArmorTrim((Holder) optional.get(), (Holder) optional1.get())); - return itemstack1; -@@ -106,7 +113,7 @@ public class SmithingTrimRecipe implements SmithingRecipe { + itemstack3.set(DataComponents.TRIM, new ArmorTrim((Holder) optional.get(), (Holder) optional1.get())); + return itemstack3; +@@ -107,7 +117,7 @@ public class SmithingTrimRecipe implements SmithingRecipe { // CraftBukkit start @Override public Recipe toBukkitRecipe(NamespacedKey id) { @@ -82,10 +95,10 @@ index 4ea43872f9da72ed959dd0709f959402d01d5fe0..f6f10da21a752e927409ea16076701c4 // CraftBukkit end diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java -index 09f86aec08ec958b8e3015020e9ae213db27d85c..37b39a2c696a59b0f52324cc222b83c0c9f341e6 100644 +index 0dc2be8f502a50f13d8fe860c209ebfa43a931ea..af6c1ccdf2b91b1284daee5552eb44cc9a34cd5f 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java -@@ -12,12 +12,17 @@ public class CraftSmithingTransformRecipe extends SmithingTransformRecipe implem +@@ -11,12 +11,17 @@ public class CraftSmithingTransformRecipe extends SmithingTransformRecipe implem public CraftSmithingTransformRecipe(NamespacedKey key, ItemStack result, RecipeChoice template, RecipeChoice base, RecipeChoice addition) { super(key, result, template, base, addition); } @@ -104,19 +117,19 @@ index 09f86aec08ec958b8e3015020e9ae213db27d85c..37b39a2c696a59b0f52324cc222b83c0 return ret; } -@@ -25,6 +30,6 @@ public class CraftSmithingTransformRecipe extends SmithingTransformRecipe implem +@@ -24,6 +29,6 @@ public class CraftSmithingTransformRecipe extends SmithingTransformRecipe implem public void addToCraftingManager() { ItemStack result = this.getResult(); -- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), CraftItemStack.asNMSCopy(result)))); -+ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), CraftItemStack.asNMSCopy(result), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy +- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftRecipe.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMSOptional(this.getTemplate(), false), this.toNMSOptional(this.getBase(), false), this.toNMSOptional(this.getAddition(), false), CraftItemStack.asNMSCopy(result)))); ++ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftRecipe.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMSOptional(this.getTemplate(), false), this.toNMSOptional(this.getBase(), false), this.toNMSOptional(this.getAddition(), false), CraftItemStack.asNMSCopy(result), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java -index 8245b728d341a64f25357edbd2c3c447b6c0a0cf..389fa313f811279091cace76faaabf8bdb0fc94c 100644 +index 202963e2f53b5e7d6fd43c58b27ad49ce009cc3c..fb710aa6dc416a3423345ad5b6e9494507eb0cb4 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java -@@ -12,17 +12,22 @@ public class CraftSmithingTrimRecipe extends SmithingTrimRecipe implements Craft +@@ -11,17 +11,22 @@ public class CraftSmithingTrimRecipe extends SmithingTrimRecipe implements Craft public CraftSmithingTrimRecipe(NamespacedKey key, RecipeChoice template, RecipeChoice base, RecipeChoice addition) { super(key, template, base, addition); } @@ -137,7 +150,7 @@ index 8245b728d341a64f25357edbd2c3c447b6c0a0cf..389fa313f811279091cace76faaabf8b @Override public void addToCraftingManager() { -- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false)))); -+ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy +- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftRecipe.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMSOptional(this.getTemplate(), false), this.toNMSOptional(this.getBase(), false), this.toNMSOptional(this.getAddition(), false)))); ++ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftRecipe.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMSOptional(this.getTemplate(), false), this.toNMSOptional(this.getBase(), false), this.toNMSOptional(this.getAddition(), false), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy } } diff --git a/patches/unapplied/server/0580-More-CommandBlock-API.patch b/patches/server/0576-More-CommandBlock-API.patch similarity index 100% rename from patches/unapplied/server/0580-More-CommandBlock-API.patch rename to patches/server/0576-More-CommandBlock-API.patch diff --git a/patches/unapplied/server/0581-Add-missing-team-sidebar-display-slots.patch b/patches/server/0577-Add-missing-team-sidebar-display-slots.patch similarity index 98% rename from patches/unapplied/server/0581-Add-missing-team-sidebar-display-slots.patch rename to patches/server/0577-Add-missing-team-sidebar-display-slots.patch index b248d7c5226e..1306837f9f5f 100644 --- a/patches/unapplied/server/0581-Add-missing-team-sidebar-display-slots.patch +++ b/patches/server/0577-Add-missing-team-sidebar-display-slots.patch @@ -9,7 +9,7 @@ public org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations toBukkitSlo public org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations fromBukkitSlot(Lorg/bukkit/scoreboard/DisplaySlot;)Lnet/minecraft/world/scores/DisplaySlot; diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java b/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java -index ef80e6b4dff557daaab1b9fde4d8d40171017e6c..271aad69af4db015970aad842a7bb34dcb6bfd0e 100644 +index b5e0023e431f9fb43c93a3f977144b03545322bb..3ecb1dd1a835efd7026af45562cd3394417130aa 100644 --- a/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java +++ b/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java @@ -35,6 +35,7 @@ public class FieldRename { diff --git a/patches/unapplied/server/0582-Add-back-EntityPortalExitEvent.patch b/patches/server/0578-Add-back-EntityPortalExitEvent.patch similarity index 57% rename from patches/unapplied/server/0582-Add-back-EntityPortalExitEvent.patch rename to patches/server/0578-Add-back-EntityPortalExitEvent.patch index b39d47b31a90..6c0fdf2ce99b 100644 --- a/patches/unapplied/server/0582-Add-back-EntityPortalExitEvent.patch +++ b/patches/server/0578-Add-back-EntityPortalExitEvent.patch @@ -5,27 +5,26 @@ Subject: [PATCH] Add back EntityPortalExitEvent diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 9844550e4ed6c150250b165acc26d52ec9401184..65b1833125ce4b1190bf276a69ad4c0c88875d58 100644 +index ea1492559653063bb14b934f4d40d910b81d8801..0fd652a60bf9bedda903b734f4fd39153a9c418c 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -3363,7 +3363,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - if (world instanceof ServerLevel worldserver) { +@@ -3491,7 +3491,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess if (!this.isRemoved()) { // CraftBukkit start -- Location to = new Location(teleportTarget.newLevel().getWorld(), teleportTarget.pos().x, teleportTarget.pos().y, teleportTarget.pos().z, teleportTarget.yRot(), teleportTarget.xRot()); -+ Location to = new Location(teleportTarget.newLevel().getWorld(), teleportTarget.pos().x, teleportTarget.pos().y, teleportTarget.pos().z, teleportTarget.yRot(), this.getXRot()); // Paper - use getXRot (doesn't respect DimensionTransition pitch) + PositionMoveRotation absolutePosition = PositionMoveRotation.calculateAbsolute(PositionMoveRotation.of(this), PositionMoveRotation.of(teleportTarget), teleportTarget.relatives()); +- Location to = CraftLocation.toBukkit(absolutePosition.position(), teleportTarget.newLevel().getWorld(), absolutePosition.yRot(), absolutePosition.xRot()); ++ Location to = CraftLocation.toBukkit(absolutePosition.position(), teleportTarget.newLevel().getWorld(), absolutePosition.yRot(), this.getXRot()); // Paper - use getXRot (doesn't respect DimensionTransition pitch) // Why? // Paper start - gateway-specific teleport event final EntityTeleportEvent teleEvent; if (this.portalProcess != null && this.portalProcess.isSamePortal(((net.minecraft.world.level.block.EndGatewayBlock) net.minecraft.world.level.block.Blocks.END_GATEWAY)) && this.level.getBlockEntity(this.portalProcess.getEntryPosition()) instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity theEndGatewayBlockEntity) { -@@ -3377,7 +3377,27 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - return null; +@@ -3508,6 +3508,27 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + to = teleEvent.getTo(); + teleportTarget = new TeleportTransition(((CraftWorld) to.getWorld()).getHandle(), CraftLocation.toVec3D(to), Vec3.ZERO, to.getYaw(), to.getPitch(), teleportTarget.missingRespawnBlock(), teleportTarget.asPassenger(), Set.of(), teleportTarget.postTeleportTransition(), teleportTarget.cause()); } - to = teleEvent.getTo(); -- teleportTarget = new DimensionTransition(((CraftWorld) to.getWorld()).getHandle(), CraftLocation.toVec3D(to), teleportTarget.speed(), to.getYaw(), to.getPitch(), teleportTarget.missingRespawnBlock(), teleportTarget.postDimensionTransition(), teleportTarget.cause()); + // Paper start - Call EntityPortalExitEvent + if (this.portalProcess != null) { // if in a portal + CraftEntity bukkitEntity = this.getBukkitEntity(); -+ Vec3 velocity = teleportTarget.speed(); ++ Vec3 velocity = teleportTarget.deltaMovement(); + org.bukkit.event.entity.EntityPortalExitEvent event = new org.bukkit.event.entity.EntityPortalExitEvent( + bukkitEntity, + bukkitEntity.getLocation(), to.clone(), @@ -37,7 +36,7 @@ index 9844550e4ed6c150250b165acc26d52ec9401184..65b1833125ce4b1190bf276a69ad4c0c + to = event.getTo().clone(); + velocity = org.bukkit.craftbukkit.util.CraftVector.toNMS(event.getAfter()); + } -+ teleportTarget = new DimensionTransition(((CraftWorld) to.getWorld()).getHandle(), CraftLocation.toVec3D(to), velocity, to.getYaw(), to.getPitch(), teleportTarget.missingRespawnBlock(), teleportTarget.postDimensionTransition(), teleportTarget.cause()); ++ teleportTarget = new TeleportTransition(((CraftWorld) to.getWorld()).getHandle(), CraftLocation.toVec3D(to), velocity, to.getYaw(), to.getPitch(), teleportTarget.missingRespawnBlock(), teleportTarget.asPassenger(), Set.of(), teleportTarget.postTeleportTransition(), teleportTarget.cause()); + } + if (this.isRemoved()) { + return null; @@ -45,4 +44,4 @@ index 9844550e4ed6c150250b165acc26d52ec9401184..65b1833125ce4b1190bf276a69ad4c0c + // Paper end - Call EntityPortalExitEvent // CraftBukkit end ServerLevel worldserver1 = teleportTarget.newLevel(); - List list = this.getPassengers(); + boolean flag = worldserver1.dimension() != worldserver.dimension(); diff --git a/patches/unapplied/server/0583-Add-methods-to-find-targets-for-lightning-strikes.patch b/patches/server/0579-Add-methods-to-find-targets-for-lightning-strikes.patch similarity index 84% rename from patches/unapplied/server/0583-Add-methods-to-find-targets-for-lightning-strikes.patch rename to patches/server/0579-Add-methods-to-find-targets-for-lightning-strikes.patch index ca096b9dd97c..556a36744869 100644 --- a/patches/unapplied/server/0583-Add-methods-to-find-targets-for-lightning-strikes.patch +++ b/patches/server/0579-Add-methods-to-find-targets-for-lightning-strikes.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Add methods to find targets for lightning strikes public net.minecraft.server.level.ServerLevel findLightningRod(Lnet/minecraft/core/BlockPos;)Ljava/util/Optional; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index c72687fb23e8d01639cce7d79e3f97805d51e01f..778d3f3ea2247be5bd6edd382b872f6de5bc359c 100644 +index 83f3f05ffe61d77417bce50ce7ae6a8671605e9e..bd99c1ca778270dc80ba83b46dbd178890dd7b53 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -764,6 +764,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -751,6 +751,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } protected BlockPos findLightningTargetAround(BlockPos pos) { @@ -22,19 +22,19 @@ index c72687fb23e8d01639cce7d79e3f97805d51e01f..778d3f3ea2247be5bd6edd382b872f6d BlockPos blockposition1 = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, pos); Optional optional = this.findLightningRod(blockposition1); -@@ -778,6 +783,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -765,6 +770,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (!list.isEmpty()) { return ((LivingEntity) list.get(this.random.nextInt(list.size()))).blockPosition(); } else { + if (returnNullWhenNoTarget) return null; // Paper - Add methods to find targets for lightning strikes - if (blockposition1.getY() == this.getMinBuildHeight() - 1) { + if (blockposition1.getY() == this.getMinY() - 1) { 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 a41c6705aa7e04ad32395f89b95ca76617c9416d..390cacc7916d1322a7e1e8bff004d415e9fa5622 100644 +index 1d7865e6de190f7321846bdac52da36a908c7a3d..c2af72ffbe3e58db0b9915f4016811b82313dfdb 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -689,6 +689,23 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -695,6 +695,23 @@ public class CraftWorld extends CraftRegionAccessor implements World { return (LightningStrike) lightning.getBukkitEntity(); } diff --git a/patches/unapplied/server/0584-Get-entity-default-attributes.patch b/patches/server/0580-Get-entity-default-attributes.patch similarity index 98% rename from patches/unapplied/server/0584-Get-entity-default-attributes.patch rename to patches/server/0580-Get-entity-default-attributes.patch index fb93fa58062e..0c9552e4ca6c 100644 --- a/patches/unapplied/server/0584-Get-entity-default-attributes.patch +++ b/patches/server/0580-Get-entity-default-attributes.patch @@ -81,7 +81,7 @@ index 0000000000000000000000000000000000000000..ec9ebd2d539333293c51b7edfa18f18b + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 5e8081350b2ec375373d8197bd1f3196652ec9d9..70c06eb6e743232d0e8243b12a927084c6c9414b 100644 +index 821f9a2780dc6fa9926fadbec18b51a915767730..d6e9eccd5edce73c9be99e1b9becadf89c593035 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -544,6 +544,18 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/unapplied/server/0585-Left-handed-API.patch b/patches/server/0581-Left-handed-API.patch similarity index 84% rename from patches/unapplied/server/0585-Left-handed-API.patch rename to patches/server/0581-Left-handed-API.patch index 643df451a4a6..50bb0d4ebea4 100644 --- a/patches/unapplied/server/0585-Left-handed-API.patch +++ b/patches/server/0581-Left-handed-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Left handed API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java -index fb29afb6517b009b81285adc9e6dca2eb7f74aee..921594a78ea511337434b29b5bc1a037eb30992c 100644 +index 7cf42f62d91c131b1cab576979f85c58c3cecb3b..e226a99d00c990a4ca4f21b93fcae7a556e01dbb 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java -@@ -144,6 +144,16 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob { +@@ -145,6 +145,16 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob { public int getMaxHeadPitch() { return getHandle().getMaxHeadXRot(); } diff --git a/patches/unapplied/server/0586-Add-more-advancement-API.patch b/patches/server/0582-Add-more-advancement-API.patch similarity index 100% rename from patches/unapplied/server/0586-Add-more-advancement-API.patch rename to patches/server/0582-Add-more-advancement-API.patch diff --git a/patches/unapplied/server/0587-Add-ItemFactory-getSpawnEgg-API.patch b/patches/server/0583-Add-ItemFactory-getSpawnEgg-API.patch similarity index 95% rename from patches/unapplied/server/0587-Add-ItemFactory-getSpawnEgg-API.patch rename to patches/server/0583-Add-ItemFactory-getSpawnEgg-API.patch index 04c5e3b925ec..c0f37d4a0b2d 100644 --- a/patches/unapplied/server/0587-Add-ItemFactory-getSpawnEgg-API.patch +++ b/patches/server/0583-Add-ItemFactory-getSpawnEgg-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add ItemFactory#getSpawnEgg API diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -index eabb8b42b890224dd19b879ff276e9908674310d..803a19063c03627dbea79cb1c395ae35aaef2834 100644 +index 19c1faecb398f5b91dd04827b66038c352e5b4e4..237df8b37ee8cf5b15e8e6d30fa3b51ef394434d 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java @@ -9,6 +9,7 @@ import net.minecraft.core.HolderSet; @@ -16,7 +16,7 @@ index eabb8b42b890224dd19b879ff276e9908674310d..803a19063c03627dbea79cb1c395ae35 import net.minecraft.server.MinecraftServer; import net.minecraft.tags.EnchantmentTags; import net.minecraft.util.RandomSource; -@@ -286,4 +287,19 @@ public final class CraftItemFactory implements ItemFactory { +@@ -289,4 +290,19 @@ public final class CraftItemFactory implements ItemFactory { new net.md_5.bungee.api.chat.TextComponent(customName)); } // Paper end - bungee hover events diff --git a/patches/unapplied/server/0588-Add-critical-damage-API.patch b/patches/server/0584-Add-critical-damage-API.patch similarity index 85% rename from patches/unapplied/server/0588-Add-critical-damage-API.patch rename to patches/server/0584-Add-critical-damage-API.patch index 554a8471d917..66ddf0b45881 100644 --- a/patches/unapplied/server/0588-Add-critical-damage-API.patch +++ b/patches/server/0584-Add-critical-damage-API.patch @@ -28,10 +28,10 @@ index c1d121d83591ca1b5bf9d9406c9622b4f24eafef..aee26dd78953ff43306aaa64161f5b9e + // Paper end - add critical damage API } diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index 7fee6ffeb8ccde965fcc1454eb0d8c6b3637da41..e772b6a501b225f13399365ad743cabe5f6f792e 100644 +index 57850f16a681af4fc302895c7608247675b44ab4..68a6b1508ce4544fe8b18746d440944d41a2fe5b 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -1293,6 +1293,7 @@ public abstract class Player extends LivingEntity { +@@ -1258,6 +1258,7 @@ public abstract class Player extends LivingEntity { flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits if (flag2) { @@ -39,20 +39,20 @@ index 7fee6ffeb8ccde965fcc1454eb0d8c6b3637da41..e772b6a501b225f13399365ad743cabe f *= 1.5F; } -@@ -1352,7 +1353,7 @@ public abstract class Player extends LivingEntity { +@@ -1317,7 +1318,7 @@ public abstract class Player extends LivingEntity { float f7 = this.getEnchantedDamage(entityliving2, f6, damagesource) * f2; // CraftBukkit start - Only apply knockback if the damage hits -- if (!entityliving2.hurt(this.damageSources().playerAttack(this).sweep(), f7)) { -+ if (!entityliving2.hurt(this.damageSources().playerAttack(this).sweep().critical(flag2), f7)) { // Paper - add critical damage API +- if (!entityliving2.hurtServer((ServerLevel) this.level(), this.damageSources().playerAttack(this).sweep(), f7)) { ++ if (!entityliving2.hurtServer((ServerLevel) this.level(), this.damageSources().playerAttack(this).sweep().critical(flag2), f7)) { // Paper - add critical damage API continue; } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -index 746bb8a36bd6c6ef953289576af499caad588d79..57ebb96707748e90810dc07471f9769f1317df9d 100644 +index bc167c21f82ad09952f6cdbf1016523062890f8b..44bcb1117cfa4d66c500011489ae193a0d1e7d78 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -@@ -422,6 +422,7 @@ public abstract class AbstractArrow extends Projectile { +@@ -450,6 +450,7 @@ public abstract class AbstractArrow extends Projectile { entityliving.setLastHurtMob(entity); } @@ -61,10 +61,10 @@ index 746bb8a36bd6c6ef953289576af499caad588d79..57ebb96707748e90810dc07471f9769f int k = entity.getRemainingFireTicks(); diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index b93fa1ea73f0b218e6c6bed8bd36694e26544ab0..5fc6ef13cdc9df11b0fd2b0baf3cec862ccb5e37 100644 +index 83648509a5b90daa4b072650cbc3215b64659a86..376563ea6990aef558a34e4f5889125412b734df 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1080,7 +1080,7 @@ public class CraftEventFactory { +@@ -1078,7 +1078,7 @@ populateFields(victim, event); // Paper - make cancellable return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled); } DamageCause damageCause = (damager.getBukkitEntity() instanceof org.bukkit.entity.TNTPrimed) ? DamageCause.BLOCK_EXPLOSION : DamageCause.ENTITY_EXPLOSION; @@ -73,7 +73,7 @@ index b93fa1ea73f0b218e6c6bed8bd36694e26544ab0..5fc6ef13cdc9df11b0fd2b0baf3cec86 } else if (damager != null || source.getDirectEntity() != null) { DamageCause cause = (source.isSweep()) ? DamageCause.ENTITY_SWEEP_ATTACK : DamageCause.ENTITY_ATTACK; -@@ -1106,7 +1106,7 @@ public class CraftEventFactory { +@@ -1104,7 +1104,7 @@ populateFields(victim, event); // Paper - make cancellable cause = DamageCause.MAGIC; } @@ -82,7 +82,7 @@ index b93fa1ea73f0b218e6c6bed8bd36694e26544ab0..5fc6ef13cdc9df11b0fd2b0baf3cec86 } else if (source.is(DamageTypes.FELL_OUT_OF_WORLD)) { return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.VOID, bukkitDamageSource, modifiers, modifierFunctions, cancelled); } else if (source.is(DamageTypes.LAVA)) { -@@ -1166,13 +1166,13 @@ public class CraftEventFactory { +@@ -1164,13 +1164,13 @@ populateFields(victim, event); // Paper - make cancellable cause = DamageCause.CUSTOM; } diff --git a/patches/server/0585-Fix-issues-with-mob-conversion.patch b/patches/server/0585-Fix-issues-with-mob-conversion.patch new file mode 100644 index 000000000000..bfafca2b4efa --- /dev/null +++ b/patches/server/0585-Fix-issues-with-mob-conversion.patch @@ -0,0 +1,83 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sun, 24 Oct 2021 20:29:45 -0700 +Subject: [PATCH] Fix issues with mob conversion + + +diff --git a/src/main/java/net/minecraft/world/entity/monster/Skeleton.java b/src/main/java/net/minecraft/world/entity/monster/Skeleton.java +index 6f6454bcec7e0d1cefbf818fc2fc6eb90adeec83..6d176ab1eee654411918e0ee64306d280c7ae816 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/Skeleton.java ++++ b/src/main/java/net/minecraft/world/entity/monster/Skeleton.java +@@ -16,6 +16,8 @@ import net.minecraft.world.entity.player.Player; + import net.minecraft.world.item.Items; + import net.minecraft.world.level.ItemLike; + import net.minecraft.world.level.Level; ++import org.bukkit.event.entity.CreatureSpawnEvent; ++import org.bukkit.event.entity.EntityTransformEvent; + + public class Skeleton extends AbstractSkeleton { + +@@ -94,12 +96,19 @@ public class Skeleton extends AbstractSkeleton { + } + + protected void doFreezeConversion() { +- this.convertTo(EntityType.STRAY, ConversionParams.single(this, true, true), (entityskeletonstray) -> { ++ final Stray stray = this.convertTo(EntityType.STRAY, ConversionParams.single(this, true, true), (entityskeletonstray) -> { // Paper - Fix issues with mob conversion; reset conversion time to prevent event spam + if (!this.isSilent()) { + this.level().levelEvent((Player) null, 1048, this.blockPosition(), 0); + } + +- }, org.bukkit.event.entity.EntityTransformEvent.TransformReason.FROZEN, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.FROZEN); // CraftBukkit - add spawn and transform reasons ++ }, EntityTransformEvent.TransformReason.FROZEN, CreatureSpawnEvent.SpawnReason.FROZEN);// CraftBukkit - add spawn and transform reasons ++ ++ // Paper start - Fix issues with mob conversion; reset conversion time to prevent event spam ++ if (stray == null) { ++ this.conversionTime = 300; ++ } ++ // Paper end - Fix issues with mob conversion ++ + } + + @Override +diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java +index d51acb788803048c0eacd762a2fd311115ac0970..6ea90e54759dbeab025e0a1896ee834ea9986427 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java ++++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java +@@ -260,9 +260,15 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { + } + + private void finishConversion() { +- this.convertTo( ++ net.minecraft.world.entity.Entity converted = this.convertTo( // Paper - Fix issues with mob conversion; reset to prevent event spam + EntityType.ZOGLIN, ConversionParams.single(this, true, false), zoglin -> zoglin.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0)) + ); ++ ++ // Paper start - Fix issues with mob conversion; reset to prevent event spam ++ if (converted == null) { ++ this.timeInOverworld = 0; ++ } ++ // Paper end - Fix issues with mob conversion + } + + @Override +diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java +index e2075fb22596b6dc4dbbb9c20c91c63f0ddb7ba7..e3a8aa0ae0d1fa6f2b697e20464224f8b8c6b8ea 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java ++++ b/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java +@@ -100,9 +100,15 @@ public abstract class AbstractPiglin extends Monster { + } + + protected void finishConversion(ServerLevel world) { +- this.convertTo(EntityType.ZOMBIFIED_PIGLIN, ConversionParams.single(this, true, true), (entitypigzombie) -> { ++ net.minecraft.world.entity.Entity converted = this.convertTo(EntityType.ZOMBIFIED_PIGLIN, ConversionParams.single(this, true, true), (entitypigzombie) -> { // Paper - Fix issues with mob conversion; reset to prevent event spam + entitypigzombie.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0)); + }, org.bukkit.event.entity.EntityTransformEvent.TransformReason.PIGLIN_ZOMBIFIED, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.PIGLIN_ZOMBIFIED); // CraftBukkit - add spawn and transform reasons ++ ++ // Paper start - Fix issues with mob conversion; reset to prevent event spam ++ if (converted == null) { ++ this.timeInOverworld = 0; ++ } ++ // Paper end - Fix issues with mob conversion + } + + public boolean isAdult() { diff --git a/patches/unapplied/server/0590-Add-hasCollision-methods-to-various-places.patch b/patches/server/0586-Add-hasCollision-methods-to-various-places.patch similarity index 96% rename from patches/unapplied/server/0590-Add-hasCollision-methods-to-various-places.patch rename to patches/server/0586-Add-hasCollision-methods-to-various-places.patch index 1acc4729a74f..421b0ba92e96 100644 --- a/patches/unapplied/server/0590-Add-hasCollision-methods-to-various-places.patch +++ b/patches/server/0586-Add-hasCollision-methods-to-various-places.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Add hasCollision methods to various places public net.minecraft.world.level.block.state.BlockBehaviour hasCollision diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index ce297420f695404356655b1df2847a32fb98ec59..068b3735b6c50a7a2053c7dc39856f728fb7218a 100644 +index 9c8aac69f01db647e20d49d272ccc107a7edceaf..d5b495b5a3ca7f4411d1a700f7149042a16509f1 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -457,6 +457,11 @@ public class CraftBlock implements Block { diff --git a/patches/unapplied/server/0591-Goat-ram-API.patch b/patches/server/0587-Goat-ram-API.patch similarity index 88% rename from patches/unapplied/server/0591-Goat-ram-API.patch rename to patches/server/0587-Goat-ram-API.patch index 2f5ccdfed4f5..21d6196f4c5e 100644 --- a/patches/unapplied/server/0591-Goat-ram-API.patch +++ b/patches/server/0587-Goat-ram-API.patch @@ -5,11 +5,11 @@ Subject: [PATCH] Goat ram API diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java -index fa380dcfa16f5d872c9d29d6fab9f9cf095f3791..3b2cf9ca8447321d64ffdb4fdb9569d736d63dbb 100644 +index cccf0084d273eaded91abe249d39a843f11d351b..14e02f9b0169db8388c515a68315ad5cc3f13d22 100644 --- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java +++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java -@@ -391,4 +391,15 @@ public class Goat extends Animal { - public static boolean checkGoatSpawnRules(EntityType entityType, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) { +@@ -395,4 +395,15 @@ public class Goat extends Animal { + public static boolean checkGoatSpawnRules(EntityType entityType, LevelAccessor world, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random) { return world.getBlockState(pos.below()).is(BlockTags.GOATS_SPAWNABLE_ON) && isBrightEnoughToSpawn(world, pos); } + diff --git a/patches/unapplied/server/0592-Add-API-for-resetting-a-single-score.patch b/patches/server/0588-Add-API-for-resetting-a-single-score.patch similarity index 100% rename from patches/unapplied/server/0592-Add-API-for-resetting-a-single-score.patch rename to patches/server/0588-Add-API-for-resetting-a-single-score.patch diff --git a/patches/unapplied/server/0593-Add-Raw-Byte-Entity-Serialization.patch b/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch similarity index 92% rename from patches/unapplied/server/0593-Add-Raw-Byte-Entity-Serialization.patch rename to patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch index 0613f5b2e244..7519082dc250 100644 --- a/patches/unapplied/server/0593-Add-Raw-Byte-Entity-Serialization.patch +++ b/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Add Raw Byte Entity Serialization public net.minecraft.world.entity.Entity setLevel(Lnet/minecraft/world/level/Level;)V diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 65b1833125ce4b1190bf276a69ad4c0c88875d58..4c36bb6f61a75f20df911cd0a8a6ddc84800edd0 100644 +index 0fd652a60bf9bedda903b734f4fd39153a9c418c..92c743a354e95c8e12fc21673ee172aed07fe1fb 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -2144,6 +2144,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2260,6 +2260,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } } @@ -27,10 +27,10 @@ index 65b1833125ce4b1190bf276a69ad4c0c88875d58..4c36bb6f61a75f20df911cd0a8a6ddc8 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 7c04eb9e7eb5ff728465b46e3739eb2598ef1204..6fab713531665298d3b03e7960a17ecb1471a6d7 100644 +index 0c1c9033646dedcf1d11dee74d6965683adadf0a..1ed01978611cddb2558e441863dadc468bc07c3d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1087,6 +1087,18 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1088,6 +1088,18 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } // Paper end - tracked players API @@ -50,7 +50,7 @@ index 7c04eb9e7eb5ff728465b46e3739eb2598ef1204..6fab713531665298d3b03e7960a17ecb @Override public boolean isInvisible() { // Paper - moved up from LivingEntity diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 70c06eb6e743232d0e8243b12a927084c6c9414b..c10273445c4b5ef089f86fc08a944da69d708244 100644 +index d6e9eccd5edce73c9be99e1b9becadf89c593035..98bbbdbf8fd067df936655334ad5ea25ec07daef 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -494,7 +494,33 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/unapplied/server/0594-Vanilla-command-permission-fixes.patch b/patches/server/0590-Vanilla-command-permission-fixes.patch similarity index 94% rename from patches/unapplied/server/0594-Vanilla-command-permission-fixes.patch rename to patches/server/0590-Vanilla-command-permission-fixes.patch index a9f23f8a53a6..4c4787c7fc42 100644 --- a/patches/unapplied/server/0594-Vanilla-command-permission-fixes.patch +++ b/patches/server/0590-Vanilla-command-permission-fixes.patch @@ -33,10 +33,10 @@ index 899008b2980d13f1be6280cd8cb959c53a29bebf..d5f7da3502575f6847f3c22ab0e94284 private RedirectModifier 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 c5c9fb28fe858e2900e43f8aafccddf63f09676e..64656e69dbeb6a1cf399ca143a2d7e0a1ee85957 100644 +index 7acd7f60327106d55e8f48247650bc0064dd1b58..bee79fab7f8195e14f6bd22d9cd59bfc704bf903 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -256,6 +256,13 @@ public class Commands { +@@ -261,6 +261,13 @@ public class Commands { PublishCommand.register(this.dispatcher); } @@ -51,7 +51,7 @@ index c5c9fb28fe858e2900e43f8aafccddf63f09676e..64656e69dbeb6a1cf399ca143a2d7e0a } diff --git a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java -index 5e6645e16b185aaa6f719055ddbf670b8741fead..98d314cd293d462ef109e952f3239e08e14dda59 100644 +index 87c93ee9bbbfff785b7b6a1f0c4b932e36362943..4e81c26fdbd089961b2577168c716bf29d504d40 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java +++ b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java @@ -86,7 +86,21 @@ public final class VanillaCommandWrapper extends BukkitCommand { diff --git a/patches/unapplied/server/0595-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch b/patches/server/0591-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch similarity index 87% rename from patches/unapplied/server/0595-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch rename to patches/server/0591-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch index 22f86aa476d1..eefcbc16a90a 100644 --- a/patches/unapplied/server/0595-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch +++ b/patches/server/0591-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 778d3f3ea2247be5bd6edd382b872f6de5bc359c..de154106419d57a6b6c410fedc29cec1dbe532de 100644 +index bd99c1ca778270dc80ba83b46dbd178890dd7b53..cf2b5de61eae020513c50e0903637c55b711fd1b 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1274,9 +1274,13 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1269,9 +1269,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // Spigot Start for (net.minecraft.world.level.block.entity.BlockEntity tileentity : chunk.getBlockEntities().values()) { if (tileentity instanceof net.minecraft.world.Container) { @@ -28,10 +28,10 @@ index 778d3f3ea2247be5bd6edd382b872f6de5bc359c..de154106419d57a6b6c410fedc29cec1 } // 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 2dd10cada8d36ed5565481f3f5a5fba168ba9b26..6648af4d8d795637fae444dc85803b399592fd7d 100644 +index c680b311760601bb539d685bceddba6712d141d4..d2fbbdbb451d6c54d847b4ba125397ad41c4f7b4 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1715,6 +1715,18 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1983,6 +1983,18 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId)); this.doCloseContainer(); } @@ -51,10 +51,10 @@ index 2dd10cada8d36ed5565481f3f5a5fba168ba9b26..6648af4d8d795637fae444dc85803b39 @Override public void doCloseContainer() { diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index e772b6a501b225f13399365ad743cabe5f6f792e..fab56040ecf496e74f583ec5d6c6c9861cfa4e13 100644 +index 68a6b1508ce4544fe8b18746d440944d41a2fe5b..b8edbd23d547d7189ec64c5d3a8cd1d51859ce23 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -510,6 +510,11 @@ public abstract class Player extends LivingEntity { +@@ -544,6 +544,11 @@ public abstract class Player extends LivingEntity { this.containerMenu = this.inventoryMenu; } // Paper end - Inventory close reason diff --git a/patches/unapplied/server/0596-Fix-GameProfileCache-concurrency.patch b/patches/server/0592-Fix-GameProfileCache-concurrency.patch similarity index 100% rename from patches/unapplied/server/0596-Fix-GameProfileCache-concurrency.patch rename to patches/server/0592-Fix-GameProfileCache-concurrency.patch diff --git a/patches/unapplied/server/0597-Improve-and-expand-AsyncCatcher.patch b/patches/server/0593-Improve-and-expand-AsyncCatcher.patch similarity index 92% rename from patches/unapplied/server/0597-Improve-and-expand-AsyncCatcher.patch rename to patches/server/0593-Improve-and-expand-AsyncCatcher.patch index c36c1b44ca33..136d3b3fdbc1 100644 --- a/patches/unapplied/server/0597-Improve-and-expand-AsyncCatcher.patch +++ b/patches/server/0593-Improve-and-expand-AsyncCatcher.patch @@ -17,22 +17,22 @@ Async catch modifications to critical entity state Co-authored-by: Jake Potrebic diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 44d1cd3e6047590a989a2b85c759be4c64125a47..926c0a5f4eaaa8fb650905216d2303fb476d3fa5 100644 +index 74b21852d9346708a62033c78fac04050b98c80b..020aed78c0eb1fdb9fd0d633bf2fe45bb9eb7532 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1577,6 +1577,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1589,6 +1589,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } - public void internalTeleport(double d0, double d1, double d2, float f, float f1, Set set) { // Paper + public void internalTeleport(PositionMoveRotation positionmoverotation, Set set) { + org.spigotmc.AsyncCatcher.catchOp("teleport"); // Paper // Paper start - Prevent teleporting dead entities if (player.isRemoved()) { LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName()); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index e56ae5170526fdc9d4e6f8b94a1e6ebc77cae582..4132b5dfbc6a7693f0bb923a8b14ded571560030 100644 +index eeed7d1d4b7fee0e8ab1f43f9b7ec6f74a01330d..f7e14d9668c74e20bc327b05cf84c8203e4e590b 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1122,7 +1122,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1145,7 +1145,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } public boolean addEffect(MobEffectInstance mobeffect, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause) { @@ -166,10 +166,10 @@ index 1cfc906317f07a44f06a4adf021c44e34a2f1d07..6baa313b8201ed23193d7885c85606b0 PersistentEntitySectionManager.LOGGER.warn("Entity {} wasn't found in section {} (destroying due to {})", new Object[]{this.entity, SectionPos.of(this.currentSectionKey), reason}); } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 16e715c48acc882a9b355d885e181f1dd916fa76..bf4be21f24af1e569267be6413dbee533c153fc5 100644 +index c2af72ffbe3e58db0b9915f4016811b82313dfdb..890d3b648b1b991e351538088c06ed93686e35f5 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -1760,6 +1760,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1770,6 +1770,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void playSound(Location loc, Sound sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) { @@ -177,7 +177,7 @@ index 16e715c48acc882a9b355d885e181f1dd916fa76..bf4be21f24af1e569267be6413dbee53 if (loc == null || sound == null || category == null) return; double x = loc.getX(); -@@ -1771,6 +1772,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1781,6 +1782,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void playSound(Location loc, String sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) { @@ -185,7 +185,7 @@ index 16e715c48acc882a9b355d885e181f1dd916fa76..bf4be21f24af1e569267be6413dbee53 if (loc == null || sound == null || category == null) return; double x = loc.getX(); -@@ -1803,6 +1805,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1813,6 +1815,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void playSound(Entity entity, Sound sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) { @@ -193,7 +193,7 @@ index 16e715c48acc882a9b355d885e181f1dd916fa76..bf4be21f24af1e569267be6413dbee53 if (!(entity instanceof CraftEntity craftEntity) || entity.getWorld() != this || sound == null || category == null) return; ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(CraftSound.bukkitToMinecraftHolder(sound), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, seed); -@@ -1814,6 +1817,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1833,6 +1836,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void playSound(Entity entity, String sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) { @@ -202,10 +202,10 @@ index 16e715c48acc882a9b355d885e181f1dd916fa76..bf4be21f24af1e569267be6413dbee53 ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(Holder.direct(SoundEvent.createVariableRangeEvent(ResourceLocation.parse(sound))), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, seed); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index efac0d3ed78c621a52f905b5d7f267b4fb180e65..0ed2910e64b6efdb4180c5bc23a146aced87c3d9 100644 +index 9870222cc1c46bcc37f9d3d44881606f2b9d038e..e148239d4930e5cbb000beed4de386f992f28d88 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -525,6 +525,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -534,6 +534,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { @Override public boolean addPotionEffect(PotionEffect effect, boolean force) { diff --git a/patches/unapplied/server/0589-Fix-issues-with-mob-conversion.patch b/patches/unapplied/server/0589-Fix-issues-with-mob-conversion.patch deleted file mode 100644 index 1b4597fe009c..000000000000 --- a/patches/unapplied/server/0589-Fix-issues-with-mob-conversion.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sun, 24 Oct 2021 20:29:45 -0700 -Subject: [PATCH] Fix issues with mob conversion - - -diff --git a/src/main/java/net/minecraft/world/entity/monster/Skeleton.java b/src/main/java/net/minecraft/world/entity/monster/Skeleton.java -index 44313973318cc330bb0288ec5b857c61d4c8f9be..cee42ae2b75c29c89e7fc5b1c77d3b45ce40e9ba 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/Skeleton.java -+++ b/src/main/java/net/minecraft/world/entity/monster/Skeleton.java -@@ -91,10 +91,15 @@ public class Skeleton extends AbstractSkeleton { - } - - protected void doFreezeConversion() { -- this.convertTo(EntityType.STRAY, true, org.bukkit.event.entity.EntityTransformEvent.TransformReason.FROZEN, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.FROZEN); // CraftBukkit - add spawn and transform reasons -+ Stray stray = this.convertTo(EntityType.STRAY, true, org.bukkit.event.entity.EntityTransformEvent.TransformReason.FROZEN, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.FROZEN); // CraftBukkit - add spawn and transform reasons // Paper - Fix issues with mob conversion - if (!this.isSilent()) { - this.level().levelEvent((Player) null, 1048, this.blockPosition(), 0); - } -+ // Paper start - Fix issues with mob conversion; reset conversion time to prevent event spam -+ if (stray == null) { -+ this.conversionTime = 300; -+ } -+ // Paper end - Fix issues with mob conversion - - } - -diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java -index d35214c485dfc3abdb3f2d6683c9293b3b5f035d..d5e0c493f4c348724958193795ceb987765a465f 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java -+++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java -@@ -258,6 +258,11 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { - if (zoglin != null) { - zoglin.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0)); - } -+ // Paper start - Fix issues with mob conversion; reset to prevent event spam -+ else { -+ this.timeInOverworld = 0; -+ } -+ // Paper end - Fix issues with mob conversion - } - - @Override -diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java -index 4e4cfbcaa5c236969da288b9d6f9cd7773bf4687..dedbf88e03d5840fa9f5c5198033379701a9a29e 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java -+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java -@@ -99,6 +99,11 @@ public abstract class AbstractPiglin extends Monster { - if (entitypigzombie != null) { - entitypigzombie.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0)); - } -+ // Paper start - Fix issues with mob conversion; reset to prevent event spam -+ else { -+ this.timeInOverworld = 0; -+ } -+ // Paper end - Fix issues with mob conversion - - } - From 6456b5dea8a841ff96553c6189a9f919a6e76600 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Wed, 23 Oct 2024 21:10:14 +0100 Subject: [PATCH 027/119] A bunch more 637 --- ...t-data-components-copy-in-smithing-r.patch | 9 +++-- .../0585-Fix-issues-with-mob-conversion.patch | 15 ++------ ...per-mobcaps-and-paper-playermobcaps.patch} | 14 +++---- ...tize-ResourceLocation-error-logging.patch} | 0 ...lly-inline-methods-in-BlockPosition.patch} | 8 ++-- ...ler-threads-according-to-the-plugin.patch} | 0 ...-getChunkAt-has-inlined-logic-for-l.patch} | 2 +- ...our-chunk-data-off-disk-when-conver.patch} | 2 +- ...d-state-when-raytracing-skip-air-bl.patch} | 4 +- .../0601-Time-scoreboard-search.patch} | 0 ...rimise-map-impl-for-tracked-players.patch} | 4 +- .../0603-Add-missing-InventoryType.patch} | 0 ...imise-BlockSoil-nearby-water-lookup.patch} | 4 +- ...ntory-not-closing-on-entity-removal.patch} | 4 +- ...rement-before-suggesting-root-nodes.patch} | 0 ...ServerboundCommandSuggestionPacket-.patch} | 4 +- .../0608-Add-packet-limiter-config.patch} | 0 ...nColor-on-tropical-fish-bucket-meta.patch} | 0 .../0610-Ensure-valid-vehicle-status.patch} | 6 +-- ...ftlocked-end-exit-portal-generation.patch} | 4 +- ...r-causing-a-crash-when-trying-to-ge.patch} | 0 ...-t-log-debug-logging-being-disabled.patch} | 0 ...ous-menus-with-empty-level-accesses.patch} | 0 .../0615-Preserve-overstacked-loot.patch} | 2 +- ...ate-head-rotation-in-missing-places.patch} | 6 +-- ...unintended-light-block-manipulation.patch} | 4 +- ...0618-Fix-CraftCriteria-defaults-map.patch} | 0 ...Fix-upstreams-block-state-factories.patch} | 26 ++++++++----- .../0620-Configurable-feature-seeds.patch} | 2 +- .../0621-Add-root-admin-user-detection.patch} | 4 +- ...t-attempt-to-teleport-dead-entities.patch} | 4 +- ...ive-velocity-through-repeated-crits.patch} | 6 +-- ...e-code-using-deprecated-for-removal.patch} | 4 +- .../0625-Fix-Spigot-growth-modifiers.patch} | 16 ++++---- ...OpenersCounter-openCount-from-going.patch} | 0 ...0627-Add-PlayerItemFrameChangeEvent.patch} | 37 ++++++++++--------- .../0628-Optimize-HashMapPalette.patch} | 2 +- ...-isSectionEmpty-int-and-optimize-Pa.patch} | 12 +++--- .../0630-Add-more-Campfire-API.patch} | 25 ++++++------- ...data-to-disk-if-it-serializes-witho.patch} | 0 ...ard-CraftEntity-in-teleport-command.patch} | 26 ++++++------- .../0633-Improve-scoreboard-entries.patch} | 0 42 files changed, 128 insertions(+), 128 deletions(-) rename patches/{unapplied/server/0598-Add-paper-mobcaps-and-paper-playermobcaps.patch => server/0594-Add-paper-mobcaps-and-paper-playermobcaps.patch} (96%) rename patches/{unapplied/server/0599-Sanitize-ResourceLocation-error-logging.patch => server/0595-Sanitize-ResourceLocation-error-logging.patch} (100%) rename patches/{unapplied/server/0600-Manually-inline-methods-in-BlockPosition.patch => server/0596-Manually-inline-methods-in-BlockPosition.patch} (88%) rename patches/{unapplied/server/0601-Name-craft-scheduler-threads-according-to-the-plugin.patch => server/0597-Name-craft-scheduler-threads-according-to-the-plugin.patch} (100%) rename patches/{unapplied/server/0602-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch => server/0598-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch} (94%) rename patches/{unapplied/server/0603-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch => server/0599-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch} (93%) rename patches/{unapplied/server/0604-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch => server/0600-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch} (90%) rename patches/{unapplied/server/0605-Time-scoreboard-search.patch => server/0601-Time-scoreboard-search.patch} (100%) rename patches/{unapplied/server/0606-Oprimise-map-impl-for-tracked-players.patch => server/0602-Oprimise-map-impl-for-tracked-players.patch} (87%) rename patches/{unapplied/server/0607-Add-missing-InventoryType.patch => server/0603-Add-missing-InventoryType.patch} (100%) rename patches/{unapplied/server/0608-Optimise-BlockSoil-nearby-water-lookup.patch => server/0604-Optimise-BlockSoil-nearby-water-lookup.patch} (92%) rename patches/{unapplied/server/0609-Fix-merchant-inventory-not-closing-on-entity-removal.patch => server/0605-Fix-merchant-inventory-not-closing-on-entity-removal.patch} (88%) rename patches/{unapplied/server/0610-Check-requirement-before-suggesting-root-nodes.patch => server/0606-Check-requirement-before-suggesting-root-nodes.patch} (100%) rename patches/{unapplied/server/0611-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch => server/0607-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch} (86%) rename patches/{unapplied/server/0612-Add-packet-limiter-config.patch => server/0608-Add-packet-limiter-config.patch} (100%) rename patches/{unapplied/server/0613-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch => server/0609-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch} (100%) rename patches/{unapplied/server/0614-Ensure-valid-vehicle-status.patch => server/0610-Ensure-valid-vehicle-status.patch} (80%) rename patches/{unapplied/server/0615-Prevent-softlocked-end-exit-portal-generation.patch => server/0611-Prevent-softlocked-end-exit-portal-generation.patch} (88%) rename patches/{unapplied/server/0616-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch => server/0612-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch} (100%) rename patches/{unapplied/server/0617-Don-t-log-debug-logging-being-disabled.patch => server/0613-Don-t-log-debug-logging-being-disabled.patch} (100%) rename patches/{unapplied/server/0618-fix-various-menus-with-empty-level-accesses.patch => server/0614-fix-various-menus-with-empty-level-accesses.patch} (100%) rename patches/{unapplied/server/0619-Preserve-overstacked-loot.patch => server/0615-Preserve-overstacked-loot.patch} (94%) rename patches/{unapplied/server/0620-Update-head-rotation-in-missing-places.patch => server/0616-Update-head-rotation-in-missing-places.patch} (84%) rename patches/{unapplied/server/0621-prevent-unintended-light-block-manipulation.patch => server/0617-prevent-unintended-light-block-manipulation.patch} (90%) rename patches/{unapplied/server/0622-Fix-CraftCriteria-defaults-map.patch => server/0618-Fix-CraftCriteria-defaults-map.patch} (100%) rename patches/{unapplied/server/0623-Fix-upstreams-block-state-factories.patch => server/0619-Fix-upstreams-block-state-factories.patch} (96%) rename patches/{unapplied/server/0624-Configurable-feature-seeds.patch => server/0620-Configurable-feature-seeds.patch} (96%) rename patches/{unapplied/server/0625-Add-root-admin-user-detection.patch => server/0621-Add-root-admin-user-detection.patch} (95%) rename patches/{unapplied/server/0626-don-t-attempt-to-teleport-dead-entities.patch => server/0622-don-t-attempt-to-teleport-dead-entities.patch} (84%) rename patches/{unapplied/server/0627-Prevent-excessive-velocity-through-repeated-crits.patch => server/0623-Prevent-excessive-velocity-through-repeated-crits.patch} (88%) rename patches/{unapplied/server/0628-Remove-client-side-code-using-deprecated-for-removal.patch => server/0624-Remove-client-side-code-using-deprecated-for-removal.patch} (90%) rename patches/{unapplied/server/0629-Fix-Spigot-growth-modifiers.patch => server/0625-Fix-Spigot-growth-modifiers.patch} (92%) rename patches/{unapplied/server/0630-Prevent-ContainerOpenersCounter-openCount-from-going.patch => server/0626-Prevent-ContainerOpenersCounter-openCount-from-going.patch} (100%) rename patches/{unapplied/server/0631-Add-PlayerItemFrameChangeEvent.patch => server/0627-Add-PlayerItemFrameChangeEvent.patch} (63%) rename patches/{unapplied/server/0632-Optimize-HashMapPalette.patch => server/0628-Optimize-HashMapPalette.patch} (97%) rename patches/{unapplied/server/0633-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch => server/0629-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch} (79%) rename patches/{unapplied/server/0634-Add-more-Campfire-API.patch => server/0630-Add-more-Campfire-API.patch} (81%) rename patches/{unapplied/server/0635-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch => server/0631-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch} (100%) rename patches/{unapplied/server/0636-Forward-CraftEntity-in-teleport-command.patch => server/0632-Forward-CraftEntity-in-teleport-command.patch} (51%) rename patches/{unapplied/server/0637-Improve-scoreboard-entries.patch => server/0633-Improve-scoreboard-entries.patch} (100%) diff --git a/patches/server/0575-Option-to-prevent-data-components-copy-in-smithing-r.patch b/patches/server/0575-Option-to-prevent-data-components-copy-in-smithing-r.patch index 47046be6aed4..1c9a4f5da547 100644 --- a/patches/server/0575-Option-to-prevent-data-components-copy-in-smithing-r.patch +++ b/patches/server/0575-Option-to-prevent-data-components-copy-in-smithing-r.patch @@ -5,16 +5,17 @@ Subject: [PATCH] Option to prevent data components copy in smithing recipes diff --git a/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java b/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java -index fa003ce16020eaab554bfd833ace779c8cefc617..d432b91b4051036d8b339a6418cdbce5c371bc1b 100644 +index fa003ce16020eaab554bfd833ace779c8cefc617..017748b26590364d846a5cddaa3490b2293ad276 100644 --- a/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java +++ b/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java -@@ -30,8 +30,14 @@ public class SmithingTransformRecipe implements SmithingRecipe { +@@ -30,8 +30,15 @@ public class SmithingTransformRecipe implements SmithingRecipe { final ItemStack result; @Nullable private PlacementInfo placementInfo; + final boolean copyDataComponents; // Paper - Option to prevent data components copy public SmithingTransformRecipe(Optional template, Optional base, Optional addition, ItemStack result) { ++ // Paper start - Option to prevent data components copy + this(template, base, addition, result, true); + } + public SmithingTransformRecipe(Optional template, Optional base, Optional addition, ItemStack result, boolean copyDataComponents) { @@ -23,7 +24,7 @@ index fa003ce16020eaab554bfd833ace779c8cefc617..d432b91b4051036d8b339a6418cdbce5 this.template = template; this.base = base; this.addition = addition; -@@ -41,7 +47,9 @@ public class SmithingTransformRecipe implements SmithingRecipe { +@@ -41,7 +48,9 @@ public class SmithingTransformRecipe implements SmithingRecipe { public ItemStack assemble(SmithingRecipeInput input, HolderLookup.Provider registries) { ItemStack itemstack = input.base().transmuteCopy(this.result.getItem(), this.result.getCount()); @@ -33,7 +34,7 @@ index fa003ce16020eaab554bfd833ace779c8cefc617..d432b91b4051036d8b339a6418cdbce5 return itemstack; } -@@ -84,7 +92,7 @@ public class SmithingTransformRecipe implements SmithingRecipe { +@@ -84,7 +93,7 @@ public class SmithingTransformRecipe implements SmithingRecipe { public Recipe toBukkitRecipe(NamespacedKey id) { CraftItemStack result = CraftItemStack.asCraftMirror(this.result); diff --git a/patches/server/0585-Fix-issues-with-mob-conversion.patch b/patches/server/0585-Fix-issues-with-mob-conversion.patch index bfafca2b4efa..281a6e42c558 100644 --- a/patches/server/0585-Fix-issues-with-mob-conversion.patch +++ b/patches/server/0585-Fix-issues-with-mob-conversion.patch @@ -5,19 +5,10 @@ Subject: [PATCH] Fix issues with mob conversion diff --git a/src/main/java/net/minecraft/world/entity/monster/Skeleton.java b/src/main/java/net/minecraft/world/entity/monster/Skeleton.java -index 6f6454bcec7e0d1cefbf818fc2fc6eb90adeec83..6d176ab1eee654411918e0ee64306d280c7ae816 100644 +index 6f6454bcec7e0d1cefbf818fc2fc6eb90adeec83..3972e2ed0554e2550519e994888e068df0a151e5 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Skeleton.java +++ b/src/main/java/net/minecraft/world/entity/monster/Skeleton.java -@@ -16,6 +16,8 @@ import net.minecraft.world.entity.player.Player; - import net.minecraft.world.item.Items; - import net.minecraft.world.level.ItemLike; - import net.minecraft.world.level.Level; -+import org.bukkit.event.entity.CreatureSpawnEvent; -+import org.bukkit.event.entity.EntityTransformEvent; - - public class Skeleton extends AbstractSkeleton { - -@@ -94,12 +96,19 @@ public class Skeleton extends AbstractSkeleton { +@@ -94,12 +94,19 @@ public class Skeleton extends AbstractSkeleton { } protected void doFreezeConversion() { @@ -28,7 +19,7 @@ index 6f6454bcec7e0d1cefbf818fc2fc6eb90adeec83..6d176ab1eee654411918e0ee64306d28 } - }, org.bukkit.event.entity.EntityTransformEvent.TransformReason.FROZEN, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.FROZEN); // CraftBukkit - add spawn and transform reasons -+ }, EntityTransformEvent.TransformReason.FROZEN, CreatureSpawnEvent.SpawnReason.FROZEN);// CraftBukkit - add spawn and transform reasons ++ }, org.bukkit.event.entity.EntityTransformEvent.TransformReason.FROZEN, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.FROZEN);// CraftBukkit - add spawn and transform reasons + + // Paper start - Fix issues with mob conversion; reset conversion time to prevent event spam + if (stray == null) { diff --git a/patches/unapplied/server/0598-Add-paper-mobcaps-and-paper-playermobcaps.patch b/patches/server/0594-Add-paper-mobcaps-and-paper-playermobcaps.patch similarity index 96% rename from patches/unapplied/server/0598-Add-paper-mobcaps-and-paper-playermobcaps.patch rename to patches/server/0594-Add-paper-mobcaps-and-paper-playermobcaps.patch index d2bd8ad4d665..57982e8056c5 100644 --- a/patches/unapplied/server/0598-Add-paper-mobcaps-and-paper-playermobcaps.patch +++ b/patches/server/0594-Add-paper-mobcaps-and-paper-playermobcaps.patch @@ -257,11 +257,11 @@ index 0000000000000000000000000000000000000000..d3b39d88a72ca25057fd8574d32f28db + } +} diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 58ea6a1f95a09c22125a8262b1b221004ebce0e4..ea6533c1ac218aa075da3401807a06fcb7892321 100644 +index 485c6044d603f15878f9413a644a538dab68db3e..6eb69ebe688c1c52d5a5986dfc63cdd42e66687e 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -152,6 +152,16 @@ public final class NaturalSpawner { - world.getProfiler().pop(); +@@ -174,6 +174,16 @@ public final class NaturalSpawner { + gameprofilerfiller.pop(); } + // Paper start - Add mobcaps commands @@ -278,10 +278,10 @@ index 58ea6a1f95a09c22125a8262b1b221004ebce0e4..ea6533c1ac218aa075da3401807a06fc BlockPos blockposition = NaturalSpawner.getRandomPosWithin(world, chunk); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 36a1b2704debdb8a2f247180d263a1a95bcba24b..b638ccf0e46eeb375a59a42d6f29edd3f084fa17 100644 +index 35e5a3dc58f93b85f93ec5301cc9b5c7505503bc..f69504676d2f48f3778f489ec1e08e2b3dec85cc 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2331,6 +2331,11 @@ public final class CraftServer implements Server { +@@ -2335,6 +2335,11 @@ public final class CraftServer implements Server { @Override public int getSpawnLimit(SpawnCategory spawnCategory) { @@ -294,10 +294,10 @@ index 36a1b2704debdb8a2f247180d263a1a95bcba24b..b638ccf0e46eeb375a59a42d6f29edd3 } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index bf4be21f24af1e569267be6413dbee533c153fc5..838ffddba99964748dfe95d68ca93b578bc3292b 100644 +index 890d3b648b1b991e351538088c06ed93686e35f5..0e5b673cee93525c1ba87d5b5e48def351ce8db8 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -1718,9 +1718,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1728,9 +1728,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { Preconditions.checkArgument(spawnCategory != null, "SpawnCategory cannot be null"); Preconditions.checkArgument(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory.%s are not supported", spawnCategory); diff --git a/patches/unapplied/server/0599-Sanitize-ResourceLocation-error-logging.patch b/patches/server/0595-Sanitize-ResourceLocation-error-logging.patch similarity index 100% rename from patches/unapplied/server/0599-Sanitize-ResourceLocation-error-logging.patch rename to patches/server/0595-Sanitize-ResourceLocation-error-logging.patch diff --git a/patches/unapplied/server/0600-Manually-inline-methods-in-BlockPosition.patch b/patches/server/0596-Manually-inline-methods-in-BlockPosition.patch similarity index 88% rename from patches/unapplied/server/0600-Manually-inline-methods-in-BlockPosition.patch rename to patches/server/0596-Manually-inline-methods-in-BlockPosition.patch index 77b9a47ac100..90699bfbcfd1 100644 --- a/patches/unapplied/server/0600-Manually-inline-methods-in-BlockPosition.patch +++ b/patches/server/0596-Manually-inline-methods-in-BlockPosition.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Manually inline methods in BlockPosition diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java -index 73d7b5148e3a92c085b08303589827a6f0ae8d07..12ff8886bb53ca15db745989c25b9bd2f45335e4 100644 +index eea8bea0f40db8d36c59e628babf788fa920df94..0d51fb4be8b49e3b57c3c55aff6bcf13d5c78ddd 100644 --- a/src/main/java/net/minecraft/core/BlockPos.java +++ b/src/main/java/net/minecraft/core/BlockPos.java -@@ -570,9 +570,9 @@ public class BlockPos extends Vec3i { +@@ -576,9 +576,9 @@ public class BlockPos extends Vec3i { } public BlockPos.MutableBlockPos set(int x, int y, int z) { @@ -21,7 +21,7 @@ index 73d7b5148e3a92c085b08303589827a6f0ae8d07..12ff8886bb53ca15db745989c25b9bd2 return this; } -@@ -637,19 +637,19 @@ public class BlockPos extends Vec3i { +@@ -643,19 +643,19 @@ public class BlockPos extends Vec3i { @Override public BlockPos.MutableBlockPos setX(int i) { @@ -45,7 +45,7 @@ index 73d7b5148e3a92c085b08303589827a6f0ae8d07..12ff8886bb53ca15db745989c25b9bd2 } diff --git a/src/main/java/net/minecraft/core/Vec3i.java b/src/main/java/net/minecraft/core/Vec3i.java -index df4c9b275752ad97a4efe9380ae0d511ee760695..02367ef1371dde94ff6c4cd40bd32e800d6ccaaf 100644 +index 7d5f99cac756c54e5922bf85d5d359edcc21f1e8..2f2bcc1b9b32e58bf70ae6c171177ceb333ed6cd 100644 --- a/src/main/java/net/minecraft/core/Vec3i.java +++ b/src/main/java/net/minecraft/core/Vec3i.java @@ -16,9 +16,9 @@ public class Vec3i implements Comparable { diff --git a/patches/unapplied/server/0601-Name-craft-scheduler-threads-according-to-the-plugin.patch b/patches/server/0597-Name-craft-scheduler-threads-according-to-the-plugin.patch similarity index 100% rename from patches/unapplied/server/0601-Name-craft-scheduler-threads-according-to-the-plugin.patch rename to patches/server/0597-Name-craft-scheduler-threads-according-to-the-plugin.patch diff --git a/patches/unapplied/server/0602-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch b/patches/server/0598-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch similarity index 94% rename from patches/unapplied/server/0602-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch rename to patches/server/0598-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch index 23f6d7b2458a..e87128411d00 100644 --- a/patches/unapplied/server/0602-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch +++ b/patches/server/0598-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch @@ -10,7 +10,7 @@ chunks did get inlined, but the standard CPS.getChunkAt method was not inlined. diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 20a14b4163807b806bf2ce5a88d3c35098bed929..b4111bcc6a676dc42b233761aa667708669c2ab8 100644 +index 560777a99b58c4f82cc0e8fb087de04a564163b5..8269bf24f5e17f9e3936659aa0cbc9d4f95fb665 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -352,7 +352,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { diff --git a/patches/unapplied/server/0603-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch b/patches/server/0599-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch similarity index 93% rename from patches/unapplied/server/0603-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch rename to patches/server/0599-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch index 48449be461ae..eff1d0a95f92 100644 --- a/patches/unapplied/server/0603-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch +++ b/patches/server/0599-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch @@ -8,7 +8,7 @@ Lighting is purged on update anyways, so let's not add more into the conversion process diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -index 9aa9ab894080a5819fc45698771afd034906d36a..f0f5e9bb5ac65250f0a151f9f90b58468335a8c2 100644 +index 909acbf5b8c6edcb4529647c11464d911d6f8c15..7d5e2e6e96ea9017334dddade54a9dcb37518642 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java @@ -47,6 +47,7 @@ public class ChunkStorage implements AutoCloseable { diff --git a/patches/unapplied/server/0604-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch b/patches/server/0600-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch similarity index 90% rename from patches/unapplied/server/0604-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch rename to patches/server/0600-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch index 0ab3e48f486d..96945dc00175 100644 --- a/patches/unapplied/server/0604-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch +++ b/patches/server/0600-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch @@ -11,10 +11,10 @@ easy win. The remaining problems with this function are mostly with the block getting itself. diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java -index c3760e0c8ac0b3ea200f4e1c237e250137a78caf..c978f3b2d42f512e982f289e76c2422e41b7eec6 100644 +index 8e58efd0d8010a3499a1eb1add9fa976aa2b0a3e..cc9ae2122b563d7b583c7335d0a8ce227f9b1af4 100644 --- a/src/main/java/net/minecraft/world/level/BlockGetter.java +++ b/src/main/java/net/minecraft/world/level/BlockGetter.java -@@ -79,7 +79,8 @@ public interface BlockGetter extends LevelHeightAccessor { +@@ -80,7 +80,8 @@ public interface BlockGetter extends LevelHeightAccessor { return BlockHitResult.miss(raytrace1.getTo(), Direction.getNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(raytrace1.getTo())); } // Paper end - Prevent raytrace from loading chunks diff --git a/patches/unapplied/server/0605-Time-scoreboard-search.patch b/patches/server/0601-Time-scoreboard-search.patch similarity index 100% rename from patches/unapplied/server/0605-Time-scoreboard-search.patch rename to patches/server/0601-Time-scoreboard-search.patch diff --git a/patches/unapplied/server/0606-Oprimise-map-impl-for-tracked-players.patch b/patches/server/0602-Oprimise-map-impl-for-tracked-players.patch similarity index 87% rename from patches/unapplied/server/0606-Oprimise-map-impl-for-tracked-players.patch rename to patches/server/0602-Oprimise-map-impl-for-tracked-players.patch index dcfacfefe7fe..fb3f23985694 100644 --- a/patches/unapplied/server/0606-Oprimise-map-impl-for-tracked-players.patch +++ b/patches/server/0602-Oprimise-map-impl-for-tracked-players.patch @@ -7,10 +7,10 @@ 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 d91279f3bd009e1542e73354aadd6a16c80965e2..071e9ef3680c5dc492c6142ccd05f6788ebc3035 100644 +index 8121f7f5fb4dadb1c929b3d81121e3649981bfac..7f18146c0dea654c62b3e01e6848fd1c05f87946 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1461,7 +1461,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1520,7 +1520,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider final Entity entity; private final int range; SectionPos lastSectionPos; diff --git a/patches/unapplied/server/0607-Add-missing-InventoryType.patch b/patches/server/0603-Add-missing-InventoryType.patch similarity index 100% rename from patches/unapplied/server/0607-Add-missing-InventoryType.patch rename to patches/server/0603-Add-missing-InventoryType.patch diff --git a/patches/unapplied/server/0608-Optimise-BlockSoil-nearby-water-lookup.patch b/patches/server/0604-Optimise-BlockSoil-nearby-water-lookup.patch similarity index 92% rename from patches/unapplied/server/0608-Optimise-BlockSoil-nearby-water-lookup.patch rename to patches/server/0604-Optimise-BlockSoil-nearby-water-lookup.patch index 81b199a2436b..4a5d6c5b9dca 100644 --- a/patches/unapplied/server/0608-Optimise-BlockSoil-nearby-water-lookup.patch +++ b/patches/server/0604-Optimise-BlockSoil-nearby-water-lookup.patch @@ -7,10 +7,10 @@ Apparently the abstract block iteration was taking about 75% of the method call. diff --git a/src/main/java/net/minecraft/world/level/block/FarmBlock.java b/src/main/java/net/minecraft/world/level/block/FarmBlock.java -index 529f9f57249bd1ffa2698da76ffa9d4a284088db..d59e33e7326489c6d55d316d0130f22235f4c63c 100644 +index a87f8345aa5520a867a8dd769b43526b20b8c16a..c3dba0c2c94f3804338f86621dc42405e380a6b3 100644 --- a/src/main/java/net/minecraft/world/level/block/FarmBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FarmBlock.java -@@ -152,19 +152,28 @@ public class FarmBlock extends Block { +@@ -154,19 +154,28 @@ public class FarmBlock extends Block { } private static boolean isNearWater(LevelReader world, BlockPos pos) { diff --git a/patches/unapplied/server/0609-Fix-merchant-inventory-not-closing-on-entity-removal.patch b/patches/server/0605-Fix-merchant-inventory-not-closing-on-entity-removal.patch similarity index 88% rename from patches/unapplied/server/0609-Fix-merchant-inventory-not-closing-on-entity-removal.patch rename to patches/server/0605-Fix-merchant-inventory-not-closing-on-entity-removal.patch index 7a31528cdd3f..0969b0e6445a 100644 --- a/patches/unapplied/server/0609-Fix-merchant-inventory-not-closing-on-entity-removal.patch +++ b/patches/server/0605-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 dba04a8de93b9afe8b51e473de9e1d485c93987e..a473993ea48afd05a884e3ffcbdd15abe74580d2 100644 +index cf2b5de61eae020513c50e0903637c55b711fd1b..0fbd077c1d3dddc97c8c99effa936470562b02a4 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2247,6 +2247,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2328,6 +2328,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // 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/unapplied/server/0610-Check-requirement-before-suggesting-root-nodes.patch b/patches/server/0606-Check-requirement-before-suggesting-root-nodes.patch similarity index 100% rename from patches/unapplied/server/0610-Check-requirement-before-suggesting-root-nodes.patch rename to patches/server/0606-Check-requirement-before-suggesting-root-nodes.patch diff --git a/patches/unapplied/server/0611-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch b/patches/server/0607-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch similarity index 86% rename from patches/unapplied/server/0611-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch rename to patches/server/0607-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch index 39f096a88d74..e07fa22e0550 100644 --- a/patches/unapplied/server/0611-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch +++ b/patches/server/0607-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Don't respond to ServerboundCommandSuggestionPacket when diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 926c0a5f4eaaa8fb650905216d2303fb476d3fa5..1e806fd16ca5f90bdb4f71dea008d7936eb82562 100644 +index 020aed78c0eb1fdb9fd0d633bf2fe45bb9eb7532..7b858178ce7d0e33fec17311f1710bead5f0837d 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -748,6 +748,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -752,6 +752,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return; } // CraftBukkit end diff --git a/patches/unapplied/server/0612-Add-packet-limiter-config.patch b/patches/server/0608-Add-packet-limiter-config.patch similarity index 100% rename from patches/unapplied/server/0612-Add-packet-limiter-config.patch rename to patches/server/0608-Add-packet-limiter-config.patch diff --git a/patches/unapplied/server/0613-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch b/patches/server/0609-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch similarity index 100% rename from patches/unapplied/server/0613-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch rename to patches/server/0609-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch diff --git a/patches/unapplied/server/0614-Ensure-valid-vehicle-status.patch b/patches/server/0610-Ensure-valid-vehicle-status.patch similarity index 80% rename from patches/unapplied/server/0614-Ensure-valid-vehicle-status.patch rename to patches/server/0610-Ensure-valid-vehicle-status.patch index f8ce44340df6..c4359b205488 100644 --- a/patches/unapplied/server/0614-Ensure-valid-vehicle-status.patch +++ b/patches/server/0610-Ensure-valid-vehicle-status.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Ensure valid vehicle status diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 6648af4d8d795637fae444dc85803b399592fd7d..25ca370c0b19eca529fc2c980c50e899013f0897 100644 +index d2fbbdbb451d6c54d847b4ba125397ad41c4f7b4..f72ab5e4e743cb0758ebca28e81f97c143c91b42 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -574,7 +574,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -698,7 +698,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } } - if (persistVehicle && entity1 != null && entity != this && entity.hasExactlyOnePlayerPassenger()) { + if (persistVehicle && entity1 != null && entity != this && entity.hasExactlyOnePlayerPassenger() && !entity.isRemoved()) { // Paper - Ensure valid vehicle status // CraftBukkit end + CompoundTag nbttagcompound1 = new CompoundTag(); CompoundTag nbttagcompound2 = new CompoundTag(); - CompoundTag nbttagcompound3 = new CompoundTag(); diff --git a/patches/unapplied/server/0615-Prevent-softlocked-end-exit-portal-generation.patch b/patches/server/0611-Prevent-softlocked-end-exit-portal-generation.patch similarity index 88% rename from patches/unapplied/server/0615-Prevent-softlocked-end-exit-portal-generation.patch rename to patches/server/0611-Prevent-softlocked-end-exit-portal-generation.patch index 9e8d9491cb87..bf268188ab67 100644 --- a/patches/unapplied/server/0615-Prevent-softlocked-end-exit-portal-generation.patch +++ b/patches/server/0611-Prevent-softlocked-end-exit-portal-generation.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent softlocked end exit portal generation diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -index 460744ec3a1abe9a2d9d16c2ec521c52c7f8db95..98d1c097fdbbc8080624f365634e0812a5eea5ac 100644 +index 3d1a49d865e17a61ff74c6fe0efbd908447ee730..8d0014b0db5ab42321150938fef98458fee84b17 100644 --- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java +++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -@@ -468,6 +468,11 @@ public class EndDragonFight { +@@ -469,6 +469,11 @@ public class EndDragonFight { } } diff --git a/patches/unapplied/server/0616-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch b/patches/server/0612-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch similarity index 100% rename from patches/unapplied/server/0616-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch rename to patches/server/0612-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch diff --git a/patches/unapplied/server/0617-Don-t-log-debug-logging-being-disabled.patch b/patches/server/0613-Don-t-log-debug-logging-being-disabled.patch similarity index 100% rename from patches/unapplied/server/0617-Don-t-log-debug-logging-being-disabled.patch rename to patches/server/0613-Don-t-log-debug-logging-being-disabled.patch diff --git a/patches/unapplied/server/0618-fix-various-menus-with-empty-level-accesses.patch b/patches/server/0614-fix-various-menus-with-empty-level-accesses.patch similarity index 100% rename from patches/unapplied/server/0618-fix-various-menus-with-empty-level-accesses.patch rename to patches/server/0614-fix-various-menus-with-empty-level-accesses.patch diff --git a/patches/unapplied/server/0619-Preserve-overstacked-loot.patch b/patches/server/0615-Preserve-overstacked-loot.patch similarity index 94% rename from patches/unapplied/server/0619-Preserve-overstacked-loot.patch rename to patches/server/0615-Preserve-overstacked-loot.patch index bd657ec90674..db50d2fd8a3e 100644 --- a/patches/unapplied/server/0619-Preserve-overstacked-loot.patch +++ b/patches/server/0615-Preserve-overstacked-loot.patch @@ -10,7 +10,7 @@ chunk bans via the large amount of NBT created by unstacking the items. Fixes GH-5140 and GH-4748. diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java b/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java -index b231f90317fe7df9133674b12d47873520b481cb..edaf7f1692ae059581f3abc24bb228874e6d114b 100644 +index 4d4d413b8527e1a109276928611b8c857ad6f6aa..c2bded5094097f5615a2ddb0718942486ede93b5 100644 --- a/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java +++ b/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java @@ -72,9 +72,10 @@ public class LootTable { diff --git a/patches/unapplied/server/0620-Update-head-rotation-in-missing-places.patch b/patches/server/0616-Update-head-rotation-in-missing-places.patch similarity index 84% rename from patches/unapplied/server/0620-Update-head-rotation-in-missing-places.patch rename to patches/server/0616-Update-head-rotation-in-missing-places.patch index a1c7566dc673..190dc41a6dab 100644 --- a/patches/unapplied/server/0620-Update-head-rotation-in-missing-places.patch +++ b/patches/server/0616-Update-head-rotation-in-missing-places.patch @@ -8,10 +8,10 @@ This is because bukkit uses a separate head rotation field for yaw. This issue only applies to players. diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index f21bf6c8bbf30c59f1588c2105dbd7f80c07a0f1..e34260c80d19869c9bec5ba67f7ce7db9d13a1f1 100644 +index 92c743a354e95c8e12fc21673ee172aed07fe1fb..b54dcebbd5d2f920efcf91ff2de485493dd2f487 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -1844,6 +1844,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1914,6 +1914,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.setXRot(Mth.clamp(pitch, -90.0F, 90.0F) % 360.0F); this.yRotO = this.getYRot(); this.xRotO = this.getXRot(); @@ -19,7 +19,7 @@ index f21bf6c8bbf30c59f1588c2105dbd7f80c07a0f1..e34260c80d19869c9bec5ba67f7ce7db } public void absMoveTo(double x, double y, double z) { -@@ -1886,6 +1887,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1956,6 +1957,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.setXRot(pitch); this.setOldPosAndRot(); this.reapplyPosition(); diff --git a/patches/unapplied/server/0621-prevent-unintended-light-block-manipulation.patch b/patches/server/0617-prevent-unintended-light-block-manipulation.patch similarity index 90% rename from patches/unapplied/server/0621-prevent-unintended-light-block-manipulation.patch rename to patches/server/0617-prevent-unintended-light-block-manipulation.patch index bff44792dce8..824f2a8ab9b2 100644 --- a/patches/unapplied/server/0621-prevent-unintended-light-block-manipulation.patch +++ b/patches/server/0617-prevent-unintended-light-block-manipulation.patch @@ -5,10 +5,10 @@ Subject: [PATCH] prevent unintended light block manipulation diff --git a/src/main/java/net/minecraft/world/level/block/LightBlock.java b/src/main/java/net/minecraft/world/level/block/LightBlock.java -index 01722473a4861533dba0ab6edf3982c0278c41e1..2b3c395529a15c9f07a4c0cff7f82199298bcb6d 100644 +index 6c3ca57a29d3c5ad1add1cf2f707b930dfc422ea..71a1a152dca41ba9100bd38efd6758a42bab9f5d 100644 --- a/src/main/java/net/minecraft/world/level/block/LightBlock.java +++ b/src/main/java/net/minecraft/world/level/block/LightBlock.java -@@ -49,6 +49,14 @@ public class LightBlock extends Block implements SimpleWaterloggedBlock { +@@ -50,6 +50,14 @@ public class LightBlock extends Block implements SimpleWaterloggedBlock { builder.add(LEVEL, WATERLOGGED); } diff --git a/patches/unapplied/server/0622-Fix-CraftCriteria-defaults-map.patch b/patches/server/0618-Fix-CraftCriteria-defaults-map.patch similarity index 100% rename from patches/unapplied/server/0622-Fix-CraftCriteria-defaults-map.patch rename to patches/server/0618-Fix-CraftCriteria-defaults-map.patch diff --git a/patches/unapplied/server/0623-Fix-upstreams-block-state-factories.patch b/patches/server/0619-Fix-upstreams-block-state-factories.patch similarity index 96% rename from patches/unapplied/server/0623-Fix-upstreams-block-state-factories.patch rename to patches/server/0619-Fix-upstreams-block-state-factories.patch index 0607b0976836..bca94bd673c9 100644 --- a/patches/unapplied/server/0623-Fix-upstreams-block-state-factories.patch +++ b/patches/server/0619-Fix-upstreams-block-state-factories.patch @@ -13,10 +13,10 @@ the material type of the block at that location. public net.minecraft.world.level.block.entity.BlockEntityType validBlocks diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index 48bee70ba4188a4a55beb6584224b0f23784dd88..cbb777f499a4e8a447153c04d09c0c71321c663c 100644 +index 46a831f86b512f4228be8ccee40fb0f7bf0d6df6..3de01d92e1c97e287a1f0d1f8de81b4f530b4a84 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -387,7 +387,7 @@ public abstract class BlockEntity { +@@ -388,7 +388,7 @@ public abstract class BlockEntity { // Paper end if (this.level == null) return null; org.bukkit.block.Block block = this.level.getWorld().getBlockAt(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ()); @@ -56,7 +56,7 @@ index 80bd6e8a6dadb74356a9fa9aa394efbd31c49c37..fe7e3e0628783d8d1be9635b689da8a9 // Paper start @Override diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java -index 83ac5fc6cbbd249b5865ab203b150f53f01c9f05..b7ff7af2513204b151340538d50a65c850bdb75f 100644 +index 1a8dcde39a252a45046866349b848d79e1b13260..56453454cbd4b9e9270fc833f8ab38d5fa7a3763 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java @@ -22,6 +22,7 @@ import net.minecraft.world.level.block.entity.BeehiveBlockEntity; @@ -67,7 +67,7 @@ index 83ac5fc6cbbd249b5865ab203b150f53f01c9f05..b7ff7af2513204b151340538d50a65c8 import net.minecraft.world.level.block.entity.BrewingStandBlockEntity; import net.minecraft.world.level.block.entity.BrushableBlockEntity; import net.minecraft.world.level.block.entity.CalibratedSculkSensorBlockEntity; -@@ -87,9 +88,9 @@ public final class CraftBlockStates { +@@ -88,9 +89,9 @@ public final class CraftBlockStates { private static class BlockEntityStateFactory> extends BlockStateFactory { private final BiFunction blockStateConstructor; @@ -79,7 +79,7 @@ index 83ac5fc6cbbd249b5865ab203b150f53f01c9f05..b7ff7af2513204b151340538d50a65c8 super(blockStateType); this.blockStateConstructor = blockStateConstructor; this.tileEntityConstructor = tileEntityConstructor; -@@ -106,7 +107,7 @@ public final class CraftBlockStates { +@@ -107,7 +108,7 @@ public final class CraftBlockStates { } private T createTileEntity(BlockPos blockPosition, net.minecraft.world.level.block.state.BlockState blockData) { @@ -88,7 +88,7 @@ index 83ac5fc6cbbd249b5865ab203b150f53f01c9f05..b7ff7af2513204b151340538d50a65c8 } private B createBlockState(World world, T tileEntity) { -@@ -118,228 +119,65 @@ public final class CraftBlockStates { +@@ -119,233 +120,66 @@ public final class CraftBlockStates { private static final BlockStateFactory DEFAULT_FACTORY = new BlockStateFactory(CraftBlockState.class) { @Override public CraftBlockState createBlockState(World world, BlockPos blockPosition, net.minecraft.world.level.block.state.BlockState blockData, BlockEntity tileEntity) { @@ -130,6 +130,8 @@ index 83ac5fc6cbbd249b5865ab203b150f53f01c9f05..b7ff7af2513204b151340538d50a65c8 - Material.MANGROVE_WALL_SIGN, - Material.OAK_SIGN, - Material.OAK_WALL_SIGN, +- Material.PALE_OAK_SIGN, +- Material.PALE_OAK_WALL_SIGN, - Material.SPRUCE_SIGN, - Material.SPRUCE_WALL_SIGN, - Material.WARPED_SIGN, @@ -157,6 +159,8 @@ index 83ac5fc6cbbd249b5865ab203b150f53f01c9f05..b7ff7af2513204b151340538d50a65c8 - Material.MANGROVE_WALL_HANGING_SIGN, - Material.OAK_HANGING_SIGN, - Material.OAK_WALL_HANGING_SIGN, +- Material.PALE_OAK_HANGING_SIGN, +- Material.PALE_OAK_WALL_HANGING_SIGN, - Material.SPRUCE_HANGING_SIGN, - Material.SPRUCE_WALL_HANGING_SIGN, - Material.WARPED_HANGING_SIGN, @@ -294,6 +298,7 @@ index 83ac5fc6cbbd249b5865ab203b150f53f01c9f05..b7ff7af2513204b151340538d50a65c8 - register(Material.CHISELED_BOOKSHELF, CraftChiseledBookshelf.class, CraftChiseledBookshelf::new, ChiseledBookShelfBlockEntity::new); - register(Material.COMPARATOR, CraftComparator.class, CraftComparator::new, ComparatorBlockEntity::new); - register(Material.CONDUIT, CraftConduit.class, CraftConduit::new, ConduitBlockEntity::new); +- register(Material.CREAKING_HEART, CraftCreakingHeart.class, CraftCreakingHeart::new, CreakingHeartBlockEntity::new); - register(Material.DAYLIGHT_DETECTOR, CraftDaylightDetector.class, CraftDaylightDetector::new, DaylightDetectorBlockEntity::new); - register(Material.DECORATED_POT, CraftDecoratedPot.class, CraftDecoratedPot::new, DecoratedPotBlockEntity::new); - register(Material.DISPENSER, CraftDispenser.class, CraftDispenser::new, DispenserBlockEntity::new); @@ -340,6 +345,7 @@ index 83ac5fc6cbbd249b5865ab203b150f53f01c9f05..b7ff7af2513204b151340538d50a65c8 + register(BlockEntityType.CHISELED_BOOKSHELF, CraftChiseledBookshelf.class, CraftChiseledBookshelf::new); + register(BlockEntityType.COMPARATOR, CraftComparator.class, CraftComparator::new); + register(BlockEntityType.CONDUIT, CraftConduit.class, CraftConduit::new); ++ register(BlockEntityType.CREAKING_HEART, CraftCreakingHeart.class, CraftCreakingHeart::new); + register(BlockEntityType.DAYLIGHT_DETECTOR, CraftDaylightDetector.class, CraftDaylightDetector::new); + register(BlockEntityType.DECORATED_POT, CraftDecoratedPot.class, CraftDecoratedPot::new); + register(BlockEntityType.DISPENSER, CraftDispenser.class, CraftDispenser::new); @@ -370,7 +376,7 @@ index 83ac5fc6cbbd249b5865ab203b150f53f01c9f05..b7ff7af2513204b151340538d50a65c8 } private static void register(Material blockType, BlockStateFactory factory) { -@@ -347,30 +185,33 @@ public final class CraftBlockStates { +@@ -353,30 +187,33 @@ public final class CraftBlockStates { } private static > void register( @@ -419,7 +425,7 @@ index 83ac5fc6cbbd249b5865ab203b150f53f01c9f05..b7ff7af2513204b151340538d50a65c8 public static Class getBlockStateType(Material material) { Preconditions.checkNotNull(material, "material is null"); return CraftBlockStates.getFactory(material).blockStateType; -@@ -386,6 +227,13 @@ public final class CraftBlockStates { +@@ -392,6 +229,13 @@ public final class CraftBlockStates { return null; } @@ -433,7 +439,7 @@ index 83ac5fc6cbbd249b5865ab203b150f53f01c9f05..b7ff7af2513204b151340538d50a65c8 public static BlockState getBlockState(Block block) { // Paper start return CraftBlockStates.getBlockState(block, true); -@@ -453,7 +301,7 @@ public final class CraftBlockStates { +@@ -459,7 +303,7 @@ public final class CraftBlockStates { if (world != null && tileEntity == null && CraftBlockStates.isTileEntityOptional(material)) { factory = CraftBlockStates.DEFAULT_FACTORY; } else { @@ -442,7 +448,7 @@ index 83ac5fc6cbbd249b5865ab203b150f53f01c9f05..b7ff7af2513204b151340538d50a65c8 } return factory.createBlockState(world, blockPosition, blockData, tileEntity); } -@@ -472,6 +320,14 @@ public final class CraftBlockStates { +@@ -478,6 +322,14 @@ public final class CraftBlockStates { return new CraftBlockState(CraftBlock.at(world, pos), flag); } diff --git a/patches/unapplied/server/0624-Configurable-feature-seeds.patch b/patches/server/0620-Configurable-feature-seeds.patch similarity index 96% rename from patches/unapplied/server/0624-Configurable-feature-seeds.patch rename to patches/server/0620-Configurable-feature-seeds.patch index 27997ba7c0ef..9085e326c316 100644 --- a/patches/unapplied/server/0624-Configurable-feature-seeds.patch +++ b/patches/server/0620-Configurable-feature-seeds.patch @@ -19,7 +19,7 @@ index 49028463ba47e760281545c2f7597e3db8d6c453..7620c72a4c243cbeea245203ce03a97c } final Object val = config.get(key); diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index 5adc1952504b26772116b55a5144b7704136edfa..c5dd3aac54aa5936da4bd9f54f0e76ecf8141d27 100644 +index fd2dd6d25b8d6f3066c60a7f30a58a72cb418b85..575fa665ff9c8f52056a0e7305540ec5c3da4785 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -436,7 +436,14 @@ public abstract class ChunkGenerator { diff --git a/patches/unapplied/server/0625-Add-root-admin-user-detection.patch b/patches/server/0621-Add-root-admin-user-detection.patch similarity index 95% rename from patches/unapplied/server/0625-Add-root-admin-user-detection.patch rename to patches/server/0621-Add-root-admin-user-detection.patch index abe2f3b5ae69..af7475ee7fa1 100644 --- a/patches/unapplied/server/0625-Add-root-admin-user-detection.patch +++ b/patches/server/0621-Add-root-admin-user-detection.patch @@ -40,10 +40,10 @@ index 0000000000000000000000000000000000000000..68098dfe716e93aafcca4d8d5b5a81d8 + } +} diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index adbd61c41cc30afa89c6ee3544c562b351304a01..585d3e51b4af87327fc2bc64a49f09732a8c61ab 100644 +index e30a5ad17d7ba8bcec8911a72281830c419b0288..3c3be48b29fcd38c5dea1bfca8d8690850aa948e 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -196,6 +196,16 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -195,6 +195,16 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface DedicatedServer.LOGGER.warn("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\""); } diff --git a/patches/unapplied/server/0626-don-t-attempt-to-teleport-dead-entities.patch b/patches/server/0622-don-t-attempt-to-teleport-dead-entities.patch similarity index 84% rename from patches/unapplied/server/0626-don-t-attempt-to-teleport-dead-entities.patch rename to patches/server/0622-don-t-attempt-to-teleport-dead-entities.patch index 2c5a22066fea..667b51a9572e 100644 --- a/patches/unapplied/server/0626-don-t-attempt-to-teleport-dead-entities.patch +++ b/patches/server/0622-don-t-attempt-to-teleport-dead-entities.patch @@ -5,10 +5,10 @@ Subject: [PATCH] don't attempt to teleport dead entities diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index e34260c80d19869c9bec5ba67f7ce7db9d13a1f1..35c0591f9d981f1cf7da4d1dea108a8bb3e46c7a 100644 +index b54dcebbd5d2f920efcf91ff2de485493dd2f487..e311601d8e39e7ea632bc4805260da6d7d6d6776 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -705,7 +705,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -713,7 +713,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // CraftBukkit start public void postTick() { // No clean way to break out of ticking once the entity has been copied to a new world, so instead we move the portalling later in the tick cycle diff --git a/patches/unapplied/server/0627-Prevent-excessive-velocity-through-repeated-crits.patch b/patches/server/0623-Prevent-excessive-velocity-through-repeated-crits.patch similarity index 88% rename from patches/unapplied/server/0627-Prevent-excessive-velocity-through-repeated-crits.patch rename to patches/server/0623-Prevent-excessive-velocity-through-repeated-crits.patch index 10ce91923a79..8c7b52d7c5f9 100644 --- a/patches/unapplied/server/0627-Prevent-excessive-velocity-through-repeated-crits.patch +++ b/patches/server/0623-Prevent-excessive-velocity-through-repeated-crits.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent excessive velocity through repeated crits diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 4132b5dfbc6a7693f0bb923a8b14ded571560030..ee7bb1a01bf027eb7b28e3795950a17e5f686815 100644 +index f7e14d9668c74e20bc327b05cf84c8203e4e590b..4db8ac288e59c5f14b260686e55a7d48e2f2791d 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2773,17 +2773,29 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2865,17 +2865,29 @@ public abstract class LivingEntity extends Entity implements Attackable { return this.hasEffect(MobEffects.JUMP) ? 0.1F * ((float) this.getEffect(MobEffects.JUMP).getAmplifier() + 1.0F) : 0.0F; } @@ -31,7 +31,7 @@ index 4132b5dfbc6a7693f0bb923a8b14ded571560030..ee7bb1a01bf027eb7b28e3795950a17e + } + // Paper end - Prevent excessive velocity through repeated crits - this.setDeltaMovement(vec3d.x, (double) f, vec3d.z); + this.setDeltaMovement(vec3d.x, Math.max((double) f, vec3d.y), vec3d.z); if (this.isSprinting()) { float f1 = this.getYRot() * 0.017453292F; - diff --git a/patches/unapplied/server/0628-Remove-client-side-code-using-deprecated-for-removal.patch b/patches/server/0624-Remove-client-side-code-using-deprecated-for-removal.patch similarity index 90% rename from patches/unapplied/server/0628-Remove-client-side-code-using-deprecated-for-removal.patch rename to patches/server/0624-Remove-client-side-code-using-deprecated-for-removal.patch index 4aed4f1f3a6a..3640523f9a31 100644 --- a/patches/unapplied/server/0628-Remove-client-side-code-using-deprecated-for-removal.patch +++ b/patches/server/0624-Remove-client-side-code-using-deprecated-for-removal.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Remove client-side code using deprecated for removal Fixes warnings on build diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java -index 4cf88f6d815d60cfbf8e4ecf9d96d0cfadd0620b..42d7ecfab6f72517904451d9df3f0404b176fdb2 100644 +index 0fbe4ea495a8101f6bc1b9830ce3f47af2aa5be4..60e523f4de1cbafc2c58a5d568fe3989b7b07c34 100644 --- a/src/main/java/net/minecraft/Util.java +++ b/src/main/java/net/minecraft/Util.java -@@ -1002,16 +1002,7 @@ public class Util { +@@ -1082,16 +1082,7 @@ public class Util { } public void openUri(URI uri) { diff --git a/patches/unapplied/server/0629-Fix-Spigot-growth-modifiers.patch b/patches/server/0625-Fix-Spigot-growth-modifiers.patch similarity index 92% rename from patches/unapplied/server/0629-Fix-Spigot-growth-modifiers.patch rename to patches/server/0625-Fix-Spigot-growth-modifiers.patch index 35160b163d08..6a24adf1c833 100644 --- a/patches/unapplied/server/0629-Fix-Spigot-growth-modifiers.patch +++ b/patches/server/0625-Fix-Spigot-growth-modifiers.patch @@ -13,10 +13,10 @@ Co-authored-by: Noah van der Aa Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> diff --git a/src/main/java/net/minecraft/world/level/block/CaveVinesBlock.java b/src/main/java/net/minecraft/world/level/block/CaveVinesBlock.java -index 1e7235413fae39dc530eb843f1846f74bb5268b6..635fc086d832c641f840cf36d18cdc0fcc3beef3 100644 +index 437be546cf03b6af0856adabfeaf67bc33ff75d6..c4473c2a778116d48bc3e4796afd901f455070e6 100644 --- a/src/main/java/net/minecraft/world/level/block/CaveVinesBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CaveVinesBlock.java -@@ -50,9 +50,18 @@ public class CaveVinesBlock extends GrowingPlantHeadBlock implements Bonemealabl +@@ -50,9 +50,18 @@ public class CaveVinesBlock extends GrowingPlantHeadBlock implements CaveVines { return to.setValue(BERRIES, from.getValue(BERRIES)); } @@ -37,7 +37,7 @@ index 1e7235413fae39dc530eb843f1846f74bb5268b6..635fc086d832c641f840cf36d18cdc0f @Override diff --git a/src/main/java/net/minecraft/world/level/block/CropBlock.java b/src/main/java/net/minecraft/world/level/block/CropBlock.java -index 73595922dcff8e7a8595fcf033ab238bc4096630..112d2feba5f75a2a873b595617780515945c10e4 100644 +index 79ebc37a779bf6cba66a34a7604f819e95fd86a2..1ada5ed825501666addacf527a513ab7bd4a3a58 100644 --- a/src/main/java/net/minecraft/world/level/block/CropBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CropBlock.java @@ -91,6 +91,10 @@ public class CropBlock extends BushBlock implements BonemealableBlock { @@ -52,7 +52,7 @@ index 73595922dcff8e7a8595fcf033ab238bc4096630..112d2feba5f75a2a873b595617780515 modifier = world.spigotConfig.wheatModifier; } diff --git a/src/main/java/net/minecraft/world/level/block/GrowingPlantHeadBlock.java b/src/main/java/net/minecraft/world/level/block/GrowingPlantHeadBlock.java -index 164a855d99cf36205bd9fce04640109f20a2b96c..cf05da1c86e3018db11dc079bf50317b6639e5cc 100644 +index c527f2d8f594d711d047a2a149efe37caaeb0308..9b424d7661fedf8ee1eb9f3167c62e563f04d4d1 100644 --- a/src/main/java/net/minecraft/world/level/block/GrowingPlantHeadBlock.java +++ b/src/main/java/net/minecraft/world/level/block/GrowingPlantHeadBlock.java @@ -60,12 +60,18 @@ public abstract class GrowingPlantHeadBlock extends GrowingPlantBlock implements @@ -76,10 +76,10 @@ index 164a855d99cf36205bd9fce04640109f20a2b96c..cf05da1c86e3018db11dc079bf50317b return (BlockState) state.cycle(GrowingPlantHeadBlock.AGE); } diff --git a/src/main/java/net/minecraft/world/level/block/MangrovePropaguleBlock.java b/src/main/java/net/minecraft/world/level/block/MangrovePropaguleBlock.java -index fd7f7d58cd159f663f8f474d9c73841c795d2990..b98e17d21d43610fb7a7ce1641c518598ff48cb0 100644 +index 10e2b80b0b6010982258548b5084b9591177b558..6b18db68c8b95480992199126c6063ea728d2314 100644 --- a/src/main/java/net/minecraft/world/level/block/MangrovePropaguleBlock.java +++ b/src/main/java/net/minecraft/world/level/block/MangrovePropaguleBlock.java -@@ -114,7 +114,7 @@ public class MangrovePropaguleBlock extends SaplingBlock implements SimpleWaterl +@@ -123,7 +123,7 @@ public class MangrovePropaguleBlock extends SaplingBlock implements SimpleWaterl @Override protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { if (!isHanging(state)) { @@ -89,10 +89,10 @@ index fd7f7d58cd159f663f8f474d9c73841c795d2990..b98e17d21d43610fb7a7ce1641c51859 } } else { diff --git a/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java b/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java -index c9ed129db2cadd0a33d69993961f43088725c3cb..d06e3892cf42723f8e3f621b5497c5348fa1a715 100644 +index 972d8833127090c01d620cab10b3eca3d3601710..ea6135edc76c06b7cd55930b620dfb05f939e4f6 100644 --- a/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java -@@ -123,7 +123,7 @@ public class PitcherCropBlock extends DoublePlantBlock implements BonemealableBl +@@ -132,7 +132,7 @@ public class PitcherCropBlock extends DoublePlantBlock implements BonemealableBl @Override public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { float f = CropBlock.getGrowthSpeed(this, world, pos); diff --git a/patches/unapplied/server/0630-Prevent-ContainerOpenersCounter-openCount-from-going.patch b/patches/server/0626-Prevent-ContainerOpenersCounter-openCount-from-going.patch similarity index 100% rename from patches/unapplied/server/0630-Prevent-ContainerOpenersCounter-openCount-from-going.patch rename to patches/server/0626-Prevent-ContainerOpenersCounter-openCount-from-going.patch diff --git a/patches/unapplied/server/0631-Add-PlayerItemFrameChangeEvent.patch b/patches/server/0627-Add-PlayerItemFrameChangeEvent.patch similarity index 63% rename from patches/unapplied/server/0631-Add-PlayerItemFrameChangeEvent.patch rename to patches/server/0627-Add-PlayerItemFrameChangeEvent.patch index e04772674000..b7e908ab6eef 100644 --- a/patches/unapplied/server/0631-Add-PlayerItemFrameChangeEvent.patch +++ b/patches/server/0627-Add-PlayerItemFrameChangeEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerItemFrameChangeEvent diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -index fdb6898519acfb27baf25d8bbad2013956c1361f..3c6edc5ea44b7ec15d8fc7a2dca95a11a0d6108a 100644 +index c0deabf9d86d086fbd8cbaac5a02badf5c01c870..30af4cbb17148c247a46c0346419d6c838dbc9d2 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java @@ -1,6 +1,7 @@ @@ -16,7 +16,7 @@ index fdb6898519acfb27baf25d8bbad2013956c1361f..3c6edc5ea44b7ec15d8fc7a2dca95a11 import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.component.DataComponents; -@@ -154,6 +155,13 @@ public class ItemFrame extends HangingEntity { +@@ -166,6 +167,13 @@ public class ItemFrame extends HangingEntity { return true; } // CraftBukkit end @@ -27,23 +27,26 @@ index fdb6898519acfb27baf25d8bbad2013956c1361f..3c6edc5ea44b7ec15d8fc7a2dca95a11 + this.setItem(ItemStack.fromBukkitCopy(event.getItemStack()), false); + } + // Paper end - Add PlayerItemFrameChangeEvent - this.dropItem(source.getEntity(), false); + this.dropItem(world, source.getEntity(), false); this.gameEvent(GameEvent.BLOCK_CHANGE, source.getEntity()); this.playSound(this.getRemoveItemSound(), 1.0F, 1.0F); -@@ -394,11 +402,24 @@ public class ItemFrame extends HangingEntity { - } - } - -- this.setItem(itemstack); -+ // Paper start - Add PlayerItemFrameChangeEvent -+ PlayerItemFrameChangeEvent event = new PlayerItemFrameChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.ItemFrame) this.getBukkitEntity(), itemstack.asBukkitCopy(), PlayerItemFrameChangeEvent.ItemFrameChangeAction.PLACE); -+ if (!event.callEvent()) { -+ return InteractionResult.FAIL; -+ } -+ this.setItem(ItemStack.fromBukkitCopy(event.getItemStack())); -+ // Paper end - Add PlayerItemFrameChangeEvent - this.gameEvent(GameEvent.BLOCK_CHANGE, player); - itemstack.consume(1, player); +@@ -403,7 +411,13 @@ public class ItemFrame extends HangingEntity { + if (worldmap != null && worldmap.isTrackedCountOverLimit(256)) { + return InteractionResult.FAIL; + } else { +- this.setItem(itemstack); ++ // Paper start - Add PlayerItemFrameChangeEvent ++ PlayerItemFrameChangeEvent event = new PlayerItemFrameChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.ItemFrame) this.getBukkitEntity(), itemstack.asBukkitCopy(), PlayerItemFrameChangeEvent.ItemFrameChangeAction.PLACE); ++ if (!event.callEvent()) { ++ return InteractionResult.FAIL; ++ } ++ this.setItem(ItemStack.fromBukkitCopy(event.getItemStack())); ++ // Paper end - Add PlayerItemFrameChangeEvent + this.gameEvent(GameEvent.BLOCK_CHANGE, player); + itemstack.consume(1, player); + return InteractionResult.SUCCESS; +@@ -412,6 +426,13 @@ public class ItemFrame extends HangingEntity { + return InteractionResult.PASS; } } else { + // Paper start - Add PlayerItemFrameChangeEvent diff --git a/patches/unapplied/server/0632-Optimize-HashMapPalette.patch b/patches/server/0628-Optimize-HashMapPalette.patch similarity index 97% rename from patches/unapplied/server/0632-Optimize-HashMapPalette.patch rename to patches/server/0628-Optimize-HashMapPalette.patch index d50159b901f9..a490eb0c2093 100644 --- a/patches/unapplied/server/0632-Optimize-HashMapPalette.patch +++ b/patches/server/0628-Optimize-HashMapPalette.patch @@ -24,7 +24,7 @@ to corrupted data. This is also something that Anti-Xray is currently relying on. diff --git a/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java b/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java -index f80cde264393f3606bc0c54ba2fd6a467f4bcb5a..c5e1040c239874dcf20b79472bf690ee7f0a9e5f 100644 +index ac673cb38755852eef37e915f157f6a702117306..98dbeaf8bde15940e5b5d5d1f13fd4bb32f0a10d 100644 --- a/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java +++ b/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java @@ -20,7 +20,7 @@ public class HashMapPalette implements Palette { diff --git a/patches/unapplied/server/0633-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch b/patches/server/0629-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch similarity index 79% rename from patches/unapplied/server/0633-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch rename to patches/server/0629-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch index 8f7f6be0804c..50968cdc5001 100644 --- a/patches/unapplied/server/0633-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch +++ b/patches/server/0629-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch @@ -6,20 +6,20 @@ Subject: [PATCH] Fix ChunkSnapshot#isSectionEmpty(int) and optimize diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java -index f1d5c2d423dc015cc7720a4544370895f3cc644b..d6eab2a0fdbafc35efa7ed5b404357391565f4f3 100644 +index b2d85abb6c9c725955d972cd6895440849213fdf..887a17a0833064eb5701222e5fb6f5ccf9511588 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -338,14 +338,17 @@ public class CraftChunk implements Chunk { PalettedContainerRO>[] biome = (includeBiome || includeBiomeTempRain) ? new PalettedContainer[cs.length] : null; - Registry iregistry = this.worldServer.registryAccess().registryOrThrow(Registries.BIOME); -- Codec>> biomeCodec = PalettedContainer.codecRO(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getHolderOrThrow(Biomes.PLAINS)); + Registry iregistry = this.worldServer.registryAccess().lookupOrThrow(Registries.BIOME); +- Codec>> biomeCodec = PalettedContainer.codecRO(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getOrThrow(Biomes.PLAINS)); for (int i = 0; i < cs.length; i++) { - CompoundTag data = new CompoundTag(); -- data.put("block_states", ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, cs[i].getStates()).getOrThrow()); -- sectionBlockIDs[i] = ChunkSerializer.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, data.getCompound("block_states")).getOrThrow(ChunkSerializer.ChunkReadException::new); +- data.put("block_states", SerializableChunkData.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, cs[i].getStates()).getOrThrow()); +- sectionBlockIDs[i] = SerializableChunkData.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, data.getCompound("block_states")).getOrThrow(SerializableChunkData.ChunkReadException::new); - sectionEmpty[i] = cs[i].hasOnlyAir(); + // Paper start - Fix ChunkSnapshot#isSectionEmpty(int); and remove codec usage + sectionEmpty[i] = cs[i].hasOnlyAir(); // fix sectionEmpty array not being filled @@ -37,7 +37,7 @@ index f1d5c2d423dc015cc7720a4544370895f3cc644b..d6eab2a0fdbafc35efa7ed5b40435739 if (biome != null) { - data.put("biomes", biomeCodec.encodeStart(NbtOps.INSTANCE, cs[i].getBiomes()).getOrThrow()); -- biome[i] = biomeCodec.parse(NbtOps.INSTANCE, data.getCompound("biomes")).getOrThrow(ChunkSerializer.ChunkReadException::new); +- biome[i] = biomeCodec.parse(NbtOps.INSTANCE, data.getCompound("biomes")).getOrThrow(SerializableChunkData.ChunkReadException::new); + biome[i] = ((PalettedContainer>) cs[i].getBiomes()).copy(); // Paper - Perf: use copy instead of round tripping with codecs } } diff --git a/patches/unapplied/server/0634-Add-more-Campfire-API.patch b/patches/server/0630-Add-more-Campfire-API.patch similarity index 81% rename from patches/unapplied/server/0634-Add-more-Campfire-API.patch rename to patches/server/0630-Add-more-Campfire-API.patch index 012ca1cc7d17..c490c151c3c1 100644 --- a/patches/unapplied/server/0634-Add-more-Campfire-API.patch +++ b/patches/server/0630-Add-more-Campfire-API.patch @@ -5,36 +5,35 @@ Subject: [PATCH] Add more Campfire API diff --git a/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java -index 0c20a334be4b1c4cf7999826f8d9bff5e36bc2b8..6d58a30a588ec98bc343ab0ab82be82d9cf0618c 100644 +index 7fa1aea7942a1bc4d9779a9f8ab020ccd5566923..94072a9b65f69dfc3337907f8573081989467662 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java -@@ -46,6 +46,7 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { +@@ -46,12 +46,14 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { + private final NonNullList items; public final int[] cookingProgress; public final int[] cookingTime; - private final RecipeManager.CachedCheck quickCheck; + public final boolean[] stopCooking; // Paper - Add more Campfire API public CampfireBlockEntity(BlockPos pos, BlockState state) { super(BlockEntityType.CAMPFIRE, pos, state); -@@ -53,6 +54,7 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { + this.items = NonNullList.withSize(4, ItemStack.EMPTY); this.cookingProgress = new int[4]; this.cookingTime = new int[4]; - this.quickCheck = RecipeManager.createCheck(RecipeType.CAMPFIRE_COOKING); + this.stopCooking = new boolean[4]; // Paper - Add more Campfire API } - public static void cookTick(Level world, BlockPos pos, BlockState state, CampfireBlockEntity campfire) { -@@ -63,7 +65,9 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { + public static void cookTick(ServerLevel world, BlockPos pos, BlockState state, CampfireBlockEntity blockEntity, RecipeManager.CachedCheck recipeMatchGetter) { +@@ -62,7 +64,9 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { if (!itemstack.isEmpty()) { flag = true; -+ if (!campfire.stopCooking[i]) { // Paper - Add more Campfire API - int j = campfire.cookingProgress[i]++; ++ if (!blockEntity.stopCooking[i]) { // Paper - Add more Campfire API + int j = blockEntity.cookingProgress[i]++; + } // Paper - Add more Campfire API - if (campfire.cookingProgress[i] >= campfire.cookingTime[i]) { + if (blockEntity.cookingProgress[i] >= blockEntity.cookingTime[i]) { SingleRecipeInput singlerecipeinput = new SingleRecipeInput(itemstack); -@@ -176,6 +180,16 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { +@@ -175,6 +179,16 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { System.arraycopy(aint, 0, this.cookingTime, 0, Math.min(this.cookingTime.length, aint.length)); } @@ -51,8 +50,8 @@ index 0c20a334be4b1c4cf7999826f8d9bff5e36bc2b8..6d58a30a588ec98bc343ab0ab82be82d } @Override -@@ -184,6 +198,13 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { - ContainerHelper.saveAllItems(nbt, this.items, true, registryLookup); +@@ -183,6 +197,13 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { + ContainerHelper.saveAllItems(nbt, this.items, true, registries); nbt.putIntArray("CookingTimes", this.cookingProgress); nbt.putIntArray("CookingTotalTimes", this.cookingTime); + // Paper start - Add more Campfire API diff --git a/patches/unapplied/server/0635-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch b/patches/server/0631-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch similarity index 100% rename from patches/unapplied/server/0635-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch rename to patches/server/0631-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch diff --git a/patches/unapplied/server/0636-Forward-CraftEntity-in-teleport-command.patch b/patches/server/0632-Forward-CraftEntity-in-teleport-command.patch similarity index 51% rename from patches/unapplied/server/0636-Forward-CraftEntity-in-teleport-command.patch rename to patches/server/0632-Forward-CraftEntity-in-teleport-command.patch index 9557e79f3618..b03dbe2831f4 100644 --- a/patches/unapplied/server/0636-Forward-CraftEntity-in-teleport-command.patch +++ b/patches/server/0632-Forward-CraftEntity-in-teleport-command.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Forward CraftEntity in teleport command diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 0d98dcfeab1455931219e498072f7129016f6678..56ce703a3b33e0530eb86389f8290d109d321589 100644 +index e311601d8e39e7ea632bc4805260da6d7d6d6776..1497c3b79e6dc9ecc270c0fd2003e606f967a56e 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -3353,6 +3353,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3480,6 +3480,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public void restoreFrom(Entity original) { @@ -22,14 +22,14 @@ index 0d98dcfeab1455931219e498072f7129016f6678..56ce703a3b33e0530eb86389f8290d10 CompoundTag nbttagcompound = original.saveWithoutId(new CompoundTag()); nbttagcompound.remove("Dimension"); -@@ -3441,8 +3448,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - entity2.restoreFrom(this); - this.removeAfterChangingDimensions(); - // CraftBukkit start - Forward the CraftEntity to the new entity -- this.getBukkitEntity().setHandle(entity2); -- entity2.bukkitEntity = this.getBukkitEntity(); -+ // this.getBukkitEntity().setHandle(entity2); // Paper - forward CraftEntity in teleport command; moved to Entity#restoreFrom -+ // entity2.bukkitEntity = this.getBukkitEntity(); - // CraftBukkit end - } - +@@ -3615,8 +3622,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + entity.restoreFrom(this); + this.removeAfterChangingDimensions(); + // CraftBukkit start - Forward the CraftEntity to the new entity +- this.getBukkitEntity().setHandle(entity); +- entity.bukkitEntity = this.getBukkitEntity(); ++ //this.getBukkitEntity().setHandle(entity); ++ //entity.bukkitEntity = this.getBukkitEntity(); // Paper - forward CraftEntity in teleport command; moved to Entity#restoreFrom + // CraftBukkit end + entity.teleportSetPosition(PositionMoveRotation.of(teleportTarget), teleportTarget.relatives()); + if (this.inWorld) world.addDuringTeleport(entity); // CraftBukkit - Don't spawn the new entity if the current entity isn't spawned diff --git a/patches/unapplied/server/0637-Improve-scoreboard-entries.patch b/patches/server/0633-Improve-scoreboard-entries.patch similarity index 100% rename from patches/unapplied/server/0637-Improve-scoreboard-entries.patch rename to patches/server/0633-Improve-scoreboard-entries.patch From cb79de80c4ae2658f5066a0d5d3e94258765dd96 Mon Sep 17 00:00:00 2001 From: Noah van der Aa Date: Wed, 23 Oct 2024 22:52:43 +0200 Subject: [PATCH 028/119] moooore --- .../0457-Fix-SpawnerEntry-Equipment-API.patch | 4 +- .../0634-Entity-powdered-snow-API.patch} | 4 +- ...0635-Add-API-for-item-entity-health.patch} | 0 ...ax-block-light-for-monster-spawning.patch} | 4 +- ...pistons-and-BlockPistonRetractEvent.patch} | 8 +- ...-canSmelt-methods-to-FurnaceInvento.patch} | 0 .../0639-Bucketable-API.patch} | 0 .../0640-Validate-usernames.patch} | 8 +- ...er-animal-spawn-height-configurable.patch} | 4 +- ...anilla-BiomeProvider-from-WorldInfo.patch} | 24 ++-- ...ion-for-worlds-affected-by-time-cmd.patch} | 0 ...heck-for-PersistentDataContainer-ha.patch} | 0 ...5-Multiple-Entries-with-Scoreboards.patch} | 2 +- ...646-Reset-placed-block-on-exception.patch} | 6 +- ...configurable-height-for-slime-spawn.patch} | 24 ++-- ...0648-Fix-xp-reward-for-baby-zombies.patch} | 10 +- ...lti-Block-Change-API-Implementation.patch} | 4 +- .../0650-Fix-NotePlayEvent.patch} | 8 +- .../0651-Freeze-Tick-Lock-API.patch} | 38 +++---- .../0652-More-PotionEffectType-API.patch} | 0 ...for-StructureTemplate.Pallete-cache.patch} | 8 +- ...command-sender-which-forwards-feedb.patch} | 6 +- ...-missing-structure-set-seed-configs.patch} | 6 +- ...lled-powdered-snow-bucket-placement.patch} | 18 +-- ...ate-calls-to-CraftServer-getSpawnLi.patch} | 4 +- .../0658-Add-GameEvent-tags.patch} | 12 +- ...ks-fairly-for-worlds-while-waiting-.patch} | 6 +- .../0660-Furnace-RecipesUsed-API.patch} | 4 +- ...gurable-sculk-sensor-listener-range.patch} | 6 +- .../0662-Add-missing-block-data-API.patch} | 0 ...fault-CustomSpawners-in-custom-worl.patch} | 4 +- ...-worldlist-before-initing-the-world.patch} | 10 +- .../0665-Custom-Potion-Mixes.patch} | 40 +++---- ...66-Force-close-world-loading-screen.patch} | 14 +-- ...667-Fix-falling-block-spawn-methods.patch} | 10 +- ...Expose-furnace-minecart-push-values.patch} | 0 ...ojectileHitEvent-for-piercing-arrow.patch} | 6 +- .../0670-More-Projectile-API.patch} | 96 ++++++++-------- ...x-swamp-hut-cat-generation-deadlock.patch} | 14 +-- ...le-movement-from-players-while-tele.patch} | 4 +- ...0673-Implement-getComputedBiome-API.patch} | 8 +- .../0674-Make-some-itemstacks-nonnull.patch} | 2 +- ...675-Implement-enchantWithLevels-API.patch} | 4 +- .../0676-Fix-saving-in-unloadWorld.patch} | 4 +- .../0677-Buffer-OOB-setBlock-calls.patch} | 2 +- .../0678-Add-TameableDeathMessageEvent.patch | 24 ++++ ...ock-data-for-EntityChangeBlockEvent.patch} | 104 +++++++++--------- ...bles-running-when-mob-loot-gamerule.patch} | 6 +- ...ssenger-world-matches-ridden-entity.patch} | 4 +- ...ys-and-optimize-reference-Holder-ta.patch} | 10 +- ...low-changing-the-EnderDragon-podium.patch} | 79 ++++++------- ...erriding-a-block-entity-during-worl.patch} | 6 +- ...t-tile-entity-copies-loading-chunks.patch} | 4 +- ...ead-of-display-name-in-PlayerList-g.patch} | 4 +- .../0687-Expand-PlayerItemDamageEvent.patch | 23 ++++ .../0688-WorldCreator-keepSpawnLoaded.patch} | 4 +- ...-in-CraftPersistentDataTypeRegistry.patch} | 0 .../0682-Add-TameableDeathMessageEvent.patch | 24 ---- .../0691-Expand-PlayerItemDamageEvent.patch | 23 ---- 59 files changed, 372 insertions(+), 379 deletions(-) rename patches/{unapplied/server/0638-Entity-powdered-snow-API.patch => server/0634-Entity-powdered-snow-API.patch} (91%) rename patches/{unapplied/server/0639-Add-API-for-item-entity-health.patch => server/0635-Add-API-for-item-entity-health.patch} (100%) rename patches/{unapplied/server/0640-Configurable-max-block-light-for-monster-spawning.patch => server/0636-Configurable-max-block-light-for-monster-spawning.patch} (86%) rename patches/{unapplied/server/0641-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch => server/0637-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch} (94%) rename patches/{unapplied/server/0642-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch => server/0638-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch} (100%) rename patches/{unapplied/server/0643-Bucketable-API.patch => server/0639-Bucketable-API.patch} (100%) rename patches/{unapplied/server/0644-Validate-usernames.patch => server/0640-Validate-usernames.patch} (92%) rename patches/{unapplied/server/0645-Make-water-animal-spawn-height-configurable.patch => server/0641-Make-water-animal-spawn-height-configurable.patch} (87%) rename patches/{unapplied/server/0646-Expose-vanilla-BiomeProvider-from-WorldInfo.patch => server/0642-Expose-vanilla-BiomeProvider-from-WorldInfo.patch} (91%) rename patches/{unapplied/server/0647-Add-config-option-for-worlds-affected-by-time-cmd.patch => server/0643-Add-config-option-for-worlds-affected-by-time-cmd.patch} (100%) rename patches/{unapplied/server/0648-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch => server/0644-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch} (100%) rename patches/{unapplied/server/0649-Multiple-Entries-with-Scoreboards.patch => server/0645-Multiple-Entries-with-Scoreboards.patch} (98%) rename patches/{unapplied/server/0650-Reset-placed-block-on-exception.patch => server/0646-Reset-placed-block-on-exception.patch} (92%) rename patches/{unapplied/server/0651-Add-configurable-height-for-slime-spawn.patch => server/0647-Add-configurable-height-for-slime-spawn.patch} (66%) rename patches/{unapplied/server/0652-Fix-xp-reward-for-baby-zombies.patch => server/0648-Fix-xp-reward-for-baby-zombies.patch} (77%) rename patches/{unapplied/server/0653-Multi-Block-Change-API-Implementation.patch => server/0649-Multi-Block-Change-API-Implementation.patch} (95%) rename patches/{unapplied/server/0654-Fix-NotePlayEvent.patch => server/0650-Fix-NotePlayEvent.patch} (92%) rename patches/{unapplied/server/0655-Freeze-Tick-Lock-API.patch => server/0651-Freeze-Tick-Lock-API.patch} (70%) rename patches/{unapplied/server/0656-More-PotionEffectType-API.patch => server/0652-More-PotionEffectType-API.patch} (100%) rename patches/{unapplied/server/0657-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch => server/0653-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch} (81%) rename patches/{unapplied/server/0658-API-for-creating-command-sender-which-forwards-feedb.patch => server/0654-API-for-creating-command-sender-which-forwards-feedb.patch} (96%) rename patches/{unapplied/server/0659-Add-missing-structure-set-seed-configs.patch => server/0655-Add-missing-structure-set-seed-configs.patch} (98%) rename patches/{unapplied/server/0660-Fix-cancelled-powdered-snow-bucket-placement.patch => server/0656-Fix-cancelled-powdered-snow-bucket-placement.patch} (60%) rename patches/{unapplied/server/0661-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch => server/0657-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch} (86%) rename patches/{unapplied/server/0662-Add-GameEvent-tags.patch => server/0658-Add-GameEvent-tags.patch} (86%) rename patches/{unapplied/server/0663-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch => server/0659-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch} (87%) rename patches/{unapplied/server/0664-Furnace-RecipesUsed-API.patch => server/0660-Furnace-RecipesUsed-API.patch} (94%) rename patches/{unapplied/server/0665-Configurable-sculk-sensor-listener-range.patch => server/0661-Configurable-sculk-sensor-listener-range.patch} (97%) rename patches/{unapplied/server/0666-Add-missing-block-data-API.patch => server/0662-Add-missing-block-data-API.patch} (100%) rename patches/{unapplied/server/0667-Option-to-have-default-CustomSpawners-in-custom-worl.patch => server/0663-Option-to-have-default-CustomSpawners-in-custom-worl.patch} (94%) rename patches/{unapplied/server/0668-Put-world-into-worldlist-before-initing-the-world.patch => server/0664-Put-world-into-worldlist-before-initing-the-world.patch} (84%) rename patches/{unapplied/server/0669-Custom-Potion-Mixes.patch => server/0665-Custom-Potion-Mixes.patch} (89%) rename patches/{unapplied/server/0670-Force-close-world-loading-screen.patch => server/0666-Force-close-world-loading-screen.patch} (73%) rename patches/{unapplied/server/0671-Fix-falling-block-spawn-methods.patch => server/0667-Fix-falling-block-spawn-methods.patch} (91%) rename patches/{unapplied/server/0672-Expose-furnace-minecart-push-values.patch => server/0668-Expose-furnace-minecart-push-values.patch} (100%) rename patches/{unapplied/server/0673-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch => server/0669-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch} (91%) rename patches/{unapplied/server/0674-More-Projectile-API.patch => server/0670-More-Projectile-API.patch} (91%) rename patches/{unapplied/server/0675-Fix-swamp-hut-cat-generation-deadlock.patch => server/0671-Fix-swamp-hut-cat-generation-deadlock.patch} (83%) rename patches/{unapplied/server/0676-Don-t-allow-vehicle-movement-from-players-while-tele.patch => server/0672-Don-t-allow-vehicle-movement-from-players-while-tele.patch} (90%) rename patches/{unapplied/server/0677-Implement-getComputedBiome-API.patch => server/0673-Implement-getComputedBiome-API.patch} (88%) rename patches/{unapplied/server/0678-Make-some-itemstacks-nonnull.patch => server/0674-Make-some-itemstacks-nonnull.patch} (94%) rename patches/{unapplied/server/0679-Implement-enchantWithLevels-API.patch => server/0675-Implement-enchantWithLevels-API.patch} (95%) rename patches/{unapplied/server/0680-Fix-saving-in-unloadWorld.patch => server/0676-Fix-saving-in-unloadWorld.patch} (83%) rename patches/{unapplied/server/0681-Buffer-OOB-setBlock-calls.patch => server/0677-Buffer-OOB-setBlock-calls.patch} (95%) create mode 100644 patches/server/0678-Add-TameableDeathMessageEvent.patch rename patches/{unapplied/server/0683-Fix-new-block-data-for-EntityChangeBlockEvent.patch => server/0679-Fix-new-block-data-for-EntityChangeBlockEvent.patch} (74%) rename patches/{unapplied/server/0684-fix-player-loottables-running-when-mob-loot-gamerule.patch => server/0680-fix-player-loottables-running-when-mob-loot-gamerule.patch} (79%) rename patches/{unapplied/server/0685-Ensure-entity-passenger-world-matches-ridden-entity.patch => server/0681-Ensure-entity-passenger-world-matches-ridden-entity.patch} (85%) rename patches/{unapplied/server/0686-Cache-resource-keys-and-optimize-reference-Holder-ta.patch => server/0682-Cache-resource-keys-and-optimize-reference-Holder-ta.patch} (89%) rename patches/{unapplied/server/0687-Allow-changing-the-EnderDragon-podium.patch => server/0683-Allow-changing-the-EnderDragon-podium.patch} (64%) rename patches/{unapplied/server/0688-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch => server/0684-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch} (92%) rename patches/{unapplied/server/0689-Prevent-tile-entity-copies-loading-chunks.patch => server/0685-Prevent-tile-entity-copies-loading-chunks.patch} (90%) rename patches/{unapplied/server/0690-Use-username-instead-of-display-name-in-PlayerList-g.patch => server/0686-Use-username-instead-of-display-name-in-PlayerList-g.patch} (87%) create mode 100644 patches/server/0687-Expand-PlayerItemDamageEvent.patch rename patches/{unapplied/server/0692-WorldCreator-keepSpawnLoaded.patch => server/0688-WorldCreator-keepSpawnLoaded.patch} (87%) rename patches/{unapplied/server/0693-Fix-CME-in-CraftPersistentDataTypeRegistry.patch => server/0689-Fix-CME-in-CraftPersistentDataTypeRegistry.patch} (100%) delete mode 100644 patches/unapplied/server/0682-Add-TameableDeathMessageEvent.patch delete mode 100644 patches/unapplied/server/0691-Expand-PlayerItemDamageEvent.patch diff --git a/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch b/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch index 64ee6e4eec03..201dc87c4239 100644 --- a/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch +++ b/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix SpawnerEntry$Equipment API diff --git a/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java b/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java -index fc1c0435dfea121923eb1fe0182880752f321143..5cb482d42b0babd5a40598dc7fcf79c7d8c63655 100644 +index fc1c0435dfea121923eb1fe0182880752f321143..e167003cdf014e1ef4c475d1138c4462153fbc85 100644 --- a/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java +++ b/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java @@ -120,27 +120,29 @@ public class SpawnerEntry { @@ -22,7 +22,7 @@ index fc1c0435dfea121923eb1fe0182880752f321143..5cb482d42b0babd5a40598dc7fcf79c7 + * Set the loot table for the spawned entity's equipment slots. *
    - * To remove a loot table use null. -+ * To remove a loot table use {@link LootTables#EMPTY}. ++ * To remove a loot table use {@link org.bukkit.loot.LootTables#EMPTY}. * * @param table this {@link org.bukkit.entity.Mob} will have. */ diff --git a/patches/unapplied/server/0638-Entity-powdered-snow-API.patch b/patches/server/0634-Entity-powdered-snow-API.patch similarity index 91% rename from patches/unapplied/server/0638-Entity-powdered-snow-API.patch rename to patches/server/0634-Entity-powdered-snow-API.patch index 8cba17f5719f..09c93986c1fd 100644 --- a/patches/unapplied/server/0638-Entity-powdered-snow-API.patch +++ b/patches/server/0634-Entity-powdered-snow-API.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Entity powdered snow API public net.minecraft.world.entity.monster.Skeleton inPowderSnowTime diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 6fab713531665298d3b03e7960a17ecb1471a6d7..4ed5647101bbace0005b1ebfb824e4aed48e43cb 100644 +index 1ed01978611cddb2558e441863dadc468bc07c3d..9693656418210957000add9b6670c4bee67f8462 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1099,6 +1099,13 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1100,6 +1100,13 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } // Paper end - raw entity serialization API diff --git a/patches/unapplied/server/0639-Add-API-for-item-entity-health.patch b/patches/server/0635-Add-API-for-item-entity-health.patch similarity index 100% rename from patches/unapplied/server/0639-Add-API-for-item-entity-health.patch rename to patches/server/0635-Add-API-for-item-entity-health.patch diff --git a/patches/unapplied/server/0640-Configurable-max-block-light-for-monster-spawning.patch b/patches/server/0636-Configurable-max-block-light-for-monster-spawning.patch similarity index 86% rename from patches/unapplied/server/0640-Configurable-max-block-light-for-monster-spawning.patch rename to patches/server/0636-Configurable-max-block-light-for-monster-spawning.patch index d0fb0003dcf9..8c19486a5f33 100644 --- a/patches/unapplied/server/0640-Configurable-max-block-light-for-monster-spawning.patch +++ b/patches/server/0636-Configurable-max-block-light-for-monster-spawning.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Configurable max block light for monster spawning diff --git a/src/main/java/net/minecraft/world/entity/monster/Monster.java b/src/main/java/net/minecraft/world/entity/monster/Monster.java -index f73604d762efbac400d40f536ec1782fca584efa..e7bfce0534c7ef3a1480a1082ae8514caf78778b 100644 +index c49853f25bdf1fbc7ec9700d421c6ddccabae05f..e2de074bbe7bab0e5a7aecc1fae4c5914a203dd4 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Monster.java +++ b/src/main/java/net/minecraft/world/entity/monster/Monster.java -@@ -91,7 +91,7 @@ public abstract class Monster extends PathfinderMob implements Enemy { +@@ -92,7 +92,7 @@ public abstract class Monster extends PathfinderMob implements Enemy { return false; } else { DimensionType dimensionType = world.dimensionType(); diff --git a/patches/unapplied/server/0641-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch b/patches/server/0637-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch similarity index 94% rename from patches/unapplied/server/0641-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch rename to patches/server/0637-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch index 2ee001a77ae1..179f6e156598 100644 --- a/patches/unapplied/server/0641-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch +++ b/patches/server/0637-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch @@ -27,10 +27,10 @@ Co-authored-by: Zach Brown Co-authored-by: Madeline Miller diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java -index 2f2c9fb65d4cc8bd40303216e03c5c1956305ff4..e6bfbe2588e0c2a1be14e38d654e889d392ad4db 100644 +index 560797552799f7874133fd4aaf6e421609a54dbf..b27cf7d27672ba9ff8ade84b5a8454b19b935607 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java +++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java -@@ -160,15 +160,15 @@ public class PistonBaseBlock extends DirectionalBlock { +@@ -163,15 +163,15 @@ public class PistonBaseBlock extends DirectionalBlock { } // CraftBukkit start @@ -55,7 +55,7 @@ index 2f2c9fb65d4cc8bd40303216e03c5c1956305ff4..e6bfbe2588e0c2a1be14e38d654e889d // PAIL: checkME - what happened to setTypeAndData? // CraftBukkit end world.blockEvent(pos, this, b0, enumdirection.get3DDataValue()); -@@ -245,6 +245,13 @@ public class PistonBaseBlock extends DirectionalBlock { +@@ -248,6 +248,13 @@ public class PistonBaseBlock extends DirectionalBlock { BlockState iblockdata2 = (BlockState) ((BlockState) Blocks.MOVING_PISTON.defaultBlockState().setValue(MovingPistonBlock.FACING, enumdirection)).setValue(MovingPistonBlock.TYPE, this.isSticky ? PistonType.STICKY : PistonType.DEFAULT); @@ -69,7 +69,7 @@ index 2f2c9fb65d4cc8bd40303216e03c5c1956305ff4..e6bfbe2588e0c2a1be14e38d654e889d world.setBlock(pos, iblockdata2, 20); world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(pos, iblockdata2, (BlockState) this.defaultBlockState().setValue(PistonBaseBlock.FACING, Direction.from3DDataValue(data & 7)), enumdirection, false, true)); world.blockUpdated(pos, iblockdata2.getBlock()); -@@ -271,6 +278,13 @@ public class PistonBaseBlock extends DirectionalBlock { +@@ -274,6 +281,13 @@ public class PistonBaseBlock extends DirectionalBlock { if (type == 1 && !iblockdata3.isAir() && PistonBaseBlock.isPushable(iblockdata3, world, blockposition1, enumdirection.getOpposite(), false, enumdirection) && (iblockdata3.getPistonPushReaction() == PushReaction.NORMAL || iblockdata3.is(Blocks.PISTON) || iblockdata3.is(Blocks.STICKY_PISTON))) { this.moveBlocks(world, pos, enumdirection, false); } else { diff --git a/patches/unapplied/server/0642-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch b/patches/server/0638-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch similarity index 100% rename from patches/unapplied/server/0642-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch rename to patches/server/0638-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch diff --git a/patches/unapplied/server/0643-Bucketable-API.patch b/patches/server/0639-Bucketable-API.patch similarity index 100% rename from patches/unapplied/server/0643-Bucketable-API.patch rename to patches/server/0639-Bucketable-API.patch diff --git a/patches/unapplied/server/0644-Validate-usernames.patch b/patches/server/0640-Validate-usernames.patch similarity index 92% rename from patches/unapplied/server/0644-Validate-usernames.patch rename to patches/server/0640-Validate-usernames.patch index 0735bfd8576e..74facbf23825 100644 --- a/patches/unapplied/server/0644-Validate-usernames.patch +++ b/patches/server/0640-Validate-usernames.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Validate usernames diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index e0a10f1d8bf2c0df66e62bdf2a174ce6a66bbd6d..9c343b579d9735dc59c8c74fde030d981a673c4f 100644 +index 1e4b288f20153ce0c91fabf164c5c8320c90ba7d..cb5dd77892283a1aaec45434fb99bb7f08ee5394 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -90,6 +90,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, @@ -32,10 +32,10 @@ index e0a10f1d8bf2c0df66e62bdf2a174ce6a66bbd6d..9c343b579d9735dc59c8c74fde030d98 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 c7dc335d6da208c224d94256eab11b2c3c63745f..cff45afb90b232a236683bd569d50aab6b701149 100644 +index 1b6540ae28d73501c59581b1864f0e01ab53e365..f34cad30c982f2bb563f0deab030111720858fa8 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -670,7 +670,7 @@ public abstract class PlayerList { +@@ -628,7 +628,7 @@ public abstract class PlayerList { for (int i = 0; i < this.players.size(); ++i) { entityplayer = (ServerPlayer) this.players.get(i); @@ -45,7 +45,7 @@ index c7dc335d6da208c224d94256eab11b2c3c63745f..cff45afb90b232a236683bd569d50aab } } diff --git a/src/main/java/net/minecraft/util/StringUtil.java b/src/main/java/net/minecraft/util/StringUtil.java -index d3fc549a08993376c76c4ebebb788fea3f4ddf69..0bd191acb9596d3aa21c337230d26f09d26f6888 100644 +index e588bd7ef0616dc88ce4c0feeeabadc29dcaa550..6c33002dc8bbb3759c3156302ab7d1f26ce5e8ee 100644 --- a/src/main/java/net/minecraft/util/StringUtil.java +++ b/src/main/java/net/minecraft/util/StringUtil.java @@ -67,6 +67,25 @@ public class StringUtil { diff --git a/patches/unapplied/server/0645-Make-water-animal-spawn-height-configurable.patch b/patches/server/0641-Make-water-animal-spawn-height-configurable.patch similarity index 87% rename from patches/unapplied/server/0645-Make-water-animal-spawn-height-configurable.patch rename to patches/server/0641-Make-water-animal-spawn-height-configurable.patch index 14f75d9b89e9..341b55b1f650 100644 --- a/patches/unapplied/server/0645-Make-water-animal-spawn-height-configurable.patch +++ b/patches/server/0641-Make-water-animal-spawn-height-configurable.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Make water animal spawn height configurable diff --git a/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java b/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java -index ad86b129ffdb9c6358f451fbcc0ae000eb81141d..c9cabb061ebc9172647304431cc3fb2593dd47ba 100644 +index 6a8a90059dcc524a0724264c8d604bf39228a650..8c4532a250f8679d729a35c17e9b5bd339264450 100644 --- a/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java +++ b/src/main/java/net/minecraft/world/entity/animal/WaterAnimal.java -@@ -67,6 +67,10 @@ public abstract class WaterAnimal extends PathfinderMob { +@@ -70,6 +70,10 @@ public abstract class WaterAnimal extends PathfinderMob { ) { int i = world.getSeaLevel(); int j = i - 13; diff --git a/patches/unapplied/server/0646-Expose-vanilla-BiomeProvider-from-WorldInfo.patch b/patches/server/0642-Expose-vanilla-BiomeProvider-from-WorldInfo.patch similarity index 91% rename from patches/unapplied/server/0646-Expose-vanilla-BiomeProvider-from-WorldInfo.patch rename to patches/server/0642-Expose-vanilla-BiomeProvider-from-WorldInfo.patch index 0801289d710d..2efeedd538d5 100644 --- a/patches/unapplied/server/0646-Expose-vanilla-BiomeProvider-from-WorldInfo.patch +++ b/patches/server/0642-Expose-vanilla-BiomeProvider-from-WorldInfo.patch @@ -5,12 +5,12 @@ 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 56589fee8dd09783e01f2ae290ffacb5dff3f05f..718b653a118a1c64d07efab93192f10dfcbf414e 100644 +index 7e1b74547c691de5fa2fac6e515394e267c57036..15382d7da69967c50007f136e9d17dd2f81166e3 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -611,7 +611,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(iworlddataserver)); - LevelStem worlddimension = (LevelStem) dimensions.get(dimensionKey); + LevelStem worlddimension = (LevelStem) dimensions.getValue(dimensionKey); - org.bukkit.generator.WorldInfo worldInfo = new org.bukkit.craftbukkit.generator.CraftWorldInfo(iworlddataserver, worldSession, org.bukkit.World.Environment.getEnvironment(dimension), worlddimension.type().value()); + org.bukkit.generator.WorldInfo worldInfo = new org.bukkit.craftbukkit.generator.CraftWorldInfo(iworlddataserver, worldSession, org.bukkit.World.Environment.getEnvironment(dimension), worlddimension.type().value(), worlddimension.generator(), this.registryAccess()); // Paper - Expose vanilla BiomeProvider from WorldInfo @@ -18,25 +18,25 @@ index 56589fee8dd09783e01f2ae290ffacb5dff3f05f..718b653a118a1c64d07efab93192f10d biomeProvider = gen.getDefaultBiomeProvider(worldInfo); } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index a473993ea48afd05a884e3ffcbdd15abe74580d2..a87a0c9672b53db0e06292c339b3b1e163901942 100644 +index 0fbd077c1d3dddc97c8c99effa936470562b02a4..f46393f68ce7ff45302d6aef78b33b18fd10339b 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -369,7 +369,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -359,7 +359,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.serverLevelData.setWorld(this); if (biomeProvider != null) { -- BiomeSource worldChunkManager = new CustomWorldChunkManager(this.getWorld(), biomeProvider, this.server.registryAccess().registryOrThrow(Registries.BIOME)); -+ BiomeSource worldChunkManager = new CustomWorldChunkManager(this.getWorld(), biomeProvider, this.server.registryAccess().registryOrThrow(Registries.BIOME), chunkgenerator.getBiomeSource()); // Paper - add vanillaBiomeProvider +- BiomeSource worldChunkManager = new CustomWorldChunkManager(this.getWorld(), biomeProvider, this.server.registryAccess().lookupOrThrow(Registries.BIOME)); ++ BiomeSource worldChunkManager = new CustomWorldChunkManager(this.getWorld(), biomeProvider, this.server.registryAccess().lookupOrThrow(Registries.BIOME), chunkgenerator.getBiomeSource()); // Paper - add vanillaBiomeProvider if (chunkgenerator instanceof NoiseBasedChunkGenerator cga) { chunkgenerator = new NoiseBasedChunkGenerator(worldChunkManager, cga.settings); } else if (chunkgenerator instanceof FlatLevelSource cpf) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index b638ccf0e46eeb375a59a42d6f29edd3f084fa17..bb232cd338f94b03f2add34766927ecae019e388 100644 +index f69504676d2f48f3778f489ec1e08e2b3dec85cc..d30c1e853bb2e27922a00d890dffca153cdcbe97 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1308,7 +1308,7 @@ public final class CraftServer implements Server { +@@ -1311,7 +1311,7 @@ public final class CraftServer implements Server { List list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(worlddata)); - LevelStem worlddimension = iregistry.get(actualDimension); + LevelStem worlddimension = iregistry.getValue(actualDimension); - WorldInfo worldInfo = new CraftWorldInfo(worlddata, worldSession, creator.environment(), worlddimension.type().value()); + WorldInfo worldInfo = new CraftWorldInfo(worlddata, worldSession, creator.environment(), worlddimension.type().value(), worlddimension.generator(), this.getHandle().getServer().registryAccess()); // Paper - Expose vanilla BiomeProvider from WorldInfo @@ -44,10 +44,10 @@ index b638ccf0e46eeb375a59a42d6f29edd3f084fa17..bb232cd338f94b03f2add34766927eca 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 838ffddba99964748dfe95d68ca93b578bc3292b..bb837f7fa46a7f5926a67ce3f725a328b9bff415 100644 +index 0e5b673cee93525c1ba87d5b5e48def351ce8db8..7dc167950021371b5cf8a7e1e38f013220e1c8a6 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -212,6 +212,39 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -216,6 +216,39 @@ public class CraftWorld extends CraftRegionAccessor implements World { public int getPlayerCount() { return world.players().size(); } diff --git a/patches/unapplied/server/0647-Add-config-option-for-worlds-affected-by-time-cmd.patch b/patches/server/0643-Add-config-option-for-worlds-affected-by-time-cmd.patch similarity index 100% rename from patches/unapplied/server/0647-Add-config-option-for-worlds-affected-by-time-cmd.patch rename to patches/server/0643-Add-config-option-for-worlds-affected-by-time-cmd.patch diff --git a/patches/unapplied/server/0648-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch b/patches/server/0644-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch similarity index 100% rename from patches/unapplied/server/0648-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch rename to patches/server/0644-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch diff --git a/patches/unapplied/server/0649-Multiple-Entries-with-Scoreboards.patch b/patches/server/0645-Multiple-Entries-with-Scoreboards.patch similarity index 98% rename from patches/unapplied/server/0649-Multiple-Entries-with-Scoreboards.patch rename to patches/server/0645-Multiple-Entries-with-Scoreboards.patch index c286ca9e4b95..558cc93da58e 100644 --- a/patches/unapplied/server/0649-Multiple-Entries-with-Scoreboards.patch +++ b/patches/server/0645-Multiple-Entries-with-Scoreboards.patch @@ -21,7 +21,7 @@ index 1d0c473442b5c72245c356054440323e3c5d4711..f8fe125f12a6a00899d1d6acfa448be8 this.name = buf.readUtf(); this.method = buf.readByte(); diff --git a/src/main/java/net/minecraft/server/ServerScoreboard.java b/src/main/java/net/minecraft/server/ServerScoreboard.java -index 65a206c9969d5c7eee6bd185e398244365b5a809..f180001493146ef0d54079a8b2b47ad7decc24ca 100644 +index f1e72463ca11658390f662efbaf3e551c05fe799..8fd4d8ffcc9e1a0fcf83730d26c3bb9bef0f73f2 100644 --- a/src/main/java/net/minecraft/server/ServerScoreboard.java +++ b/src/main/java/net/minecraft/server/ServerScoreboard.java @@ -106,6 +106,25 @@ public class ServerScoreboard extends Scoreboard { diff --git a/patches/unapplied/server/0650-Reset-placed-block-on-exception.patch b/patches/server/0646-Reset-placed-block-on-exception.patch similarity index 92% rename from patches/unapplied/server/0650-Reset-placed-block-on-exception.patch rename to patches/server/0646-Reset-placed-block-on-exception.patch index c5b6f9f135e8..327d98e29107 100644 --- a/patches/unapplied/server/0650-Reset-placed-block-on-exception.patch +++ b/patches/server/0646-Reset-placed-block-on-exception.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Reset placed block on exception diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java -index cee3f1200af602b5dfd0b27d05eb01826c5bbb1d..7d76cdc59984b156628273c8357485eb10046007 100644 +index 407f5db0a4b3884440bc49bf4f00d9c035899e86..44cc12a3338b5f0448c88192c8674cd36531db34 100644 --- a/src/main/java/net/minecraft/world/item/BlockItem.java +++ b/src/main/java/net/minecraft/world/item/BlockItem.java -@@ -77,6 +77,7 @@ public class BlockItem extends Item { +@@ -71,6 +71,7 @@ public class BlockItem extends Item { if (this instanceof PlaceOnWaterBlockItem || this instanceof SolidBucketItem) { blockstate = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockactioncontext1.getLevel(), blockactioncontext1.getClickedPos()); } @@ -16,7 +16,7 @@ index cee3f1200af602b5dfd0b27d05eb01826c5bbb1d..7d76cdc59984b156628273c8357485eb // CraftBukkit end if (iblockdata == null) { -@@ -92,8 +93,20 @@ public class BlockItem extends Item { +@@ -86,8 +87,20 @@ public class BlockItem extends Item { if (iblockdata1.is(iblockdata.getBlock())) { iblockdata1 = this.updateBlockStateFromTag(blockposition, world, itemstack, iblockdata1); diff --git a/patches/unapplied/server/0651-Add-configurable-height-for-slime-spawn.patch b/patches/server/0647-Add-configurable-height-for-slime-spawn.patch similarity index 66% rename from patches/unapplied/server/0651-Add-configurable-height-for-slime-spawn.patch rename to patches/server/0647-Add-configurable-height-for-slime-spawn.patch index 5ed7f1549da5..dfc8ecb34980 100644 --- a/patches/unapplied/server/0651-Add-configurable-height-for-slime-spawn.patch +++ b/patches/server/0647-Add-configurable-height-for-slime-spawn.patch @@ -5,31 +5,31 @@ Subject: [PATCH] Add configurable height for slime spawn diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java -index b54c30ba73b6ab069c0c7c1cd2b193090da79667..adebb66e550f805f444bec22e9a4dd575a642b43 100644 +index 129f0cbc0469cb2804db6088b53347d88d91f4eb..72346a7e5269c91e3143933ac37e65ad9639b791 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Slime.java +++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java -@@ -348,7 +348,11 @@ public class Slime extends Mob implements Enemy { - return checkMobSpawnRules(type, world, spawnReason, pos, random); - } +@@ -340,7 +340,11 @@ public class Slime extends Mob implements Enemy { + return checkMobSpawnRules(type, world, spawnReason, pos, random); + } -- if (world.getBiome(pos).is(BiomeTags.ALLOWS_SURFACE_SLIME_SPAWNS) && pos.getY() > 50 && pos.getY() < 70 && random.nextFloat() < 0.5F && random.nextFloat() < world.getMoonBrightness() && world.getMaxLocalRawBrightness(pos) <= random.nextInt(8)) { +- if (world.getBiome(pos).is(BiomeTags.ALLOWS_SURFACE_SLIME_SPAWNS) && pos.getY() > 50 && pos.getY() < 70 && random.nextFloat() < 0.5F && random.nextFloat() < world.getMoonBrightness() && world.getMaxLocalRawBrightness(pos) <= random.nextInt(8)) { + // Paper start - Replace rules for Height in Swamp Biome + final double maxHeightSwamp = world.getMinecraftWorld().paperConfig().entities.spawning.slimeSpawnHeight.surfaceBiome.maximum; + final double minHeightSwamp = world.getMinecraftWorld().paperConfig().entities.spawning.slimeSpawnHeight.surfaceBiome.minimum; + if (world.getBiome(pos).is(BiomeTags.ALLOWS_SURFACE_SLIME_SPAWNS) && pos.getY() > minHeightSwamp && pos.getY() < maxHeightSwamp && random.nextFloat() < 0.5F && random.nextFloat() < world.getMoonBrightness() && world.getMaxLocalRawBrightness(pos) <= random.nextInt(8)) { + // Paper end - Replace rules for Height in Swamp Biome - return checkMobSpawnRules(type, world, spawnReason, pos, random); - } + return checkMobSpawnRules(type, world, spawnReason, pos, random); + } -@@ -359,7 +363,10 @@ public class Slime extends Mob implements Enemy { - ChunkPos chunkcoordintpair = new ChunkPos(pos); +@@ -351,7 +355,10 @@ public class Slime extends Mob implements Enemy { + ChunkPos chunkcoordintpair = new ChunkPos(pos); boolean flag = world.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper -- if (random.nextInt(10) == 0 && flag && pos.getY() < 40) { +- if (random.nextInt(10) == 0 && flag && pos.getY() < 40) { + // Paper start - Replace rules for Height in Slime Chunks + final double maxHeightSlimeChunk = world.getMinecraftWorld().paperConfig().entities.spawning.slimeSpawnHeight.slimeChunk.maximum; + if (random.nextInt(10) == 0 && flag && pos.getY() < maxHeightSlimeChunk) { + // Paper end - Replace rules for Height in Slime Chunks - return checkMobSpawnRules(type, world, spawnReason, pos, random); - } + return checkMobSpawnRules(type, world, spawnReason, pos, random); } + } diff --git a/patches/unapplied/server/0652-Fix-xp-reward-for-baby-zombies.patch b/patches/server/0648-Fix-xp-reward-for-baby-zombies.patch similarity index 77% rename from patches/unapplied/server/0652-Fix-xp-reward-for-baby-zombies.patch rename to patches/server/0648-Fix-xp-reward-for-baby-zombies.patch index a4fec4e0f2f1..3c16a1caf672 100644 --- a/patches/unapplied/server/0652-Fix-xp-reward-for-baby-zombies.patch +++ b/patches/server/0648-Fix-xp-reward-for-baby-zombies.patch @@ -9,21 +9,21 @@ so this resets it after each call to Zombie#getExperienceReward diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index fd304e7d8305877d56de7a38b8664e5a70bf0c33..2280004638fd19ed018cb3e77d53a018b34ec516 100644 +index 6dc9fc3451edec01f11f526c05d84138c46a3a8e..17974f85d3c1db549ea11e8809954cd9d2af063e 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -@@ -176,11 +176,16 @@ public class Zombie extends Monster { +@@ -174,11 +174,16 @@ public class Zombie extends Monster { @Override - protected int getBaseExperienceReward() { + protected int getBaseExperienceReward(ServerLevel world) { + final int previousReward = this.xpReward; // Paper - store previous value to reset after calculating XP reward if (this.isBaby()) { this.xpReward = (int) ((double) this.xpReward * 2.5D); } -- return super.getBaseExperienceReward(); +- return super.getBaseExperienceReward(world); + // Paper start - store previous value to reset after calculating XP reward -+ int reward = super.getBaseExperienceReward(); ++ int reward = super.getBaseExperienceReward(world); + this.xpReward = previousReward; + return reward; + // Paper end - store previous value to reset after calculating XP reward diff --git a/patches/unapplied/server/0653-Multi-Block-Change-API-Implementation.patch b/patches/server/0649-Multi-Block-Change-API-Implementation.patch similarity index 95% rename from patches/unapplied/server/0653-Multi-Block-Change-API-Implementation.patch rename to patches/server/0649-Multi-Block-Change-API-Implementation.patch index 740aad5839e3..75fd9baa246a 100644 --- a/patches/unapplied/server/0653-Multi-Block-Change-API-Implementation.patch +++ b/patches/server/0649-Multi-Block-Change-API-Implementation.patch @@ -24,10 +24,10 @@ index 926ff9be3d9e3f5d620e4c7ccb22b9f64865ff8c..1a37654aff9a9c86c9f7af10a1cf7213 buf.writeLong(this.sectionPos.asLong()); buf.writeVarInt(this.positions.length); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index bc0d63f90e352ad4158d1dcc0f21a34954279095..ef289dba67db65a5e43104a4ca68bc03c8c5e4cb 100644 +index b3efe7391b7e43327bcca419efe72811574c0664..2347e260780d4703cff01b84a7971861fd924b20 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -930,6 +930,32 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -943,6 +943,32 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().connection.send(packet); } diff --git a/patches/unapplied/server/0654-Fix-NotePlayEvent.patch b/patches/server/0650-Fix-NotePlayEvent.patch similarity index 92% rename from patches/unapplied/server/0654-Fix-NotePlayEvent.patch rename to patches/server/0650-Fix-NotePlayEvent.patch index 4a601d8f1be6..cdffcd6f0ff0 100644 --- a/patches/unapplied/server/0654-Fix-NotePlayEvent.patch +++ b/patches/server/0650-Fix-NotePlayEvent.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Fix NotePlayEvent public org.bukkit.craftbukkit.block.data.CraftBlockData toNMS(Ljava/lang/Enum;Ljava/lang/Class;)Ljava/lang/Enum; diff --git a/src/main/java/net/minecraft/world/level/block/NoteBlock.java b/src/main/java/net/minecraft/world/level/block/NoteBlock.java -index 6215f096849f48843d6e25875b8b71f6827ec0a5..f77d51d10e01fc4eaf5516c05c8be0ef7a425893 100644 +index 57e13269367a82ec39c2298b20d7595f61326f47..71fd7a467a4cb89cad8d2541366fd4add9115e04 100644 --- a/src/main/java/net/minecraft/world/level/block/NoteBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NoteBlock.java -@@ -94,11 +94,12 @@ public class NoteBlock extends Block { +@@ -96,11 +96,12 @@ public class NoteBlock extends Block { private void playNote(@Nullable Entity entity, BlockState state, Level world, BlockPos pos) { if (((NoteBlockInstrument) state.getValue(NoteBlock.INSTRUMENT)).worksAboveNoteBlock() || world.getBlockState(pos.above()).isAir()) { // CraftBukkit start @@ -27,7 +27,7 @@ index 6215f096849f48843d6e25875b8b71f6827ec0a5..f77d51d10e01fc4eaf5516c05c8be0ef world.blockEvent(pos, this, 0, 0); world.gameEvent(entity, (Holder) GameEvent.NOTE_BLOCK_PLAY, pos); } -@@ -138,10 +139,14 @@ public class NoteBlock extends Block { +@@ -139,10 +140,14 @@ public class NoteBlock extends Block { @Override protected boolean triggerEvent(BlockState state, Level world, BlockPos pos, int type, int data) { NoteBlockInstrument blockpropertyinstrument = (NoteBlockInstrument) state.getValue(NoteBlock.INSTRUMENT); @@ -43,7 +43,7 @@ index 6215f096849f48843d6e25875b8b71f6827ec0a5..f77d51d10e01fc4eaf5516c05c8be0ef f = NoteBlock.getPitchFromNote(k); world.addParticle(ParticleTypes.NOTE, (double) pos.getX() + 0.5D, (double) pos.getY() + 1.2D, (double) pos.getZ() + 0.5D, (double) k / 24.0D, 0.0D, 0.0D); -@@ -160,7 +165,7 @@ public class NoteBlock extends Block { +@@ -161,7 +166,7 @@ public class NoteBlock extends Block { holder = Holder.direct(SoundEvent.createVariableRangeEvent(minecraftkey)); } else { diff --git a/patches/unapplied/server/0655-Freeze-Tick-Lock-API.patch b/patches/server/0651-Freeze-Tick-Lock-API.patch similarity index 70% rename from patches/unapplied/server/0655-Freeze-Tick-Lock-API.patch rename to patches/server/0651-Freeze-Tick-Lock-API.patch index 69adb442ee92..f97861797746 100644 --- a/patches/unapplied/server/0655-Freeze-Tick-Lock-API.patch +++ b/patches/server/0651-Freeze-Tick-Lock-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Freeze Tick Lock API diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 9f40cc481ded9279319d92fe5a0a9278a3f5d9c2..7d9ebc71b794d40246cbd43ff4de5795970e7ebe 100644 +index 1497c3b79e6dc9ecc270c0fd2003e606f967a56e..a41bb1d80a84f487a8fb6fdefd7ccc7631902d04 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -411,6 +411,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -414,6 +414,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess private org.bukkit.util.Vector origin; @javax.annotation.Nullable private UUID originWorld; @@ -16,16 +16,16 @@ index 9f40cc481ded9279319d92fe5a0a9278a3f5d9c2..7d9ebc71b794d40246cbd43ff4de5795 public void setOrigin(@javax.annotation.Nonnull Location location) { this.origin = location.toVector(); -@@ -751,7 +752,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - this.setRemainingFireTicks(this.remainingFireTicks - 1); - } +@@ -759,7 +760,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + this.setRemainingFireTicks(this.remainingFireTicks - 1); + } -- if (this.getTicksFrozen() > 0) { -+ if (this.getTicksFrozen() > 0 && !freezeLocked) { // Paper - Freeze Tick Lock API - this.setTicksFrozen(0); - this.level().levelEvent((Player) null, 1009, this.blockPosition, 1); - } -@@ -2312,6 +2313,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +- if (this.getTicksFrozen() > 0) { ++ if (this.getTicksFrozen() > 0 && !freezeLocked) { // Paper - Freeze Tick Lock API + this.setTicksFrozen(0); + this.level().levelEvent((Player) null, 1009, this.blockPosition, 1); + } +@@ -2428,6 +2429,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess if (fromNetherPortal) { nbttagcompound.putBoolean("Paper.FromNetherPortal", true); } @@ -35,7 +35,7 @@ index 9f40cc481ded9279319d92fe5a0a9278a3f5d9c2..7d9ebc71b794d40246cbd43ff4de5795 // Paper end return nbttagcompound; } catch (Throwable throwable) { -@@ -2456,6 +2460,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2573,6 +2577,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess if (spawnReason == null) { spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; } @@ -46,23 +46,23 @@ index 9f40cc481ded9279319d92fe5a0a9278a3f5d9c2..7d9ebc71b794d40246cbd43ff4de5795 } catch (Throwable throwable) { diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index ee7bb1a01bf027eb7b28e3795950a17e5f686815..01a6e91f1b8f619e99d9bccde12f6e91e6ab5eb8 100644 +index 4db8ac288e59c5f14b260686e55a7d48e2f2791d..6598f119edc5d890dcc9d065478e7c52ac5a5183 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3497,7 +3497,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - - this.level().getProfiler().pop(); - this.level().getProfiler().push("freezing"); +@@ -3611,7 +3611,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + this.calculateEntityAnimation(this instanceof FlyingAnimal); + gameprofilerfiller.pop(); + gameprofilerfiller.push("freezing"); - if (!this.level().isClientSide && !this.isDeadOrDying()) { + if (!this.level().isClientSide && !this.isDeadOrDying() && !this.freezeLocked) { // Paper - Freeze Tick Lock API int i = this.getTicksFrozen(); if (this.isInPowderSnow && this.canFreeze()) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 4ed5647101bbace0005b1ebfb824e4aed48e43cb..4c09f2529dd8eb7ac7d260d177f5292ff2339442 100644 +index 9693656418210957000add9b6670c4bee67f8462..4e6afa243d6108cb946a8a7cf96c4036a3c2ac0c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -323,6 +323,17 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -324,6 +324,17 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return this.getHandle().isFullyFrozen(); } diff --git a/patches/unapplied/server/0656-More-PotionEffectType-API.patch b/patches/server/0652-More-PotionEffectType-API.patch similarity index 100% rename from patches/unapplied/server/0656-More-PotionEffectType-API.patch rename to patches/server/0652-More-PotionEffectType-API.patch diff --git a/patches/unapplied/server/0657-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch b/patches/server/0653-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch similarity index 81% rename from patches/unapplied/server/0657-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch rename to patches/server/0653-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch index 82d25835a60d..027285c2b186 100644 --- a/patches/unapplied/server/0657-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch +++ b/patches/server/0653-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch @@ -6,15 +6,15 @@ Subject: [PATCH] Use a CHM for StructureTemplate.Pallete cache fixes a CME due to this collection being shared across threads diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java -index 02b493435509f7a84a2c26050ca0c732ecf00ca0..33564e62e3181d28b18a957e28b8ec5152d8339f 100644 +index e7900e7e8263cae131dad2427fb2bfdadf5b8d14..b120949667ae0169a667b329b3cabbd79a0a5bda 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java +++ b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java -@@ -859,7 +859,7 @@ public class StructureTemplate { +@@ -889,7 +889,7 @@ public class StructureTemplate { public static final class Palette { private final List blocks; - private final Map> cache = Maps.newHashMap(); + private final Map> cache = Maps.newConcurrentMap(); // Paper - Fix CME due to this collection being shared across threads + @Nullable + private List cachedJigsaws; - Palette(List infos) { - this.blocks = infos; diff --git a/patches/unapplied/server/0658-API-for-creating-command-sender-which-forwards-feedb.patch b/patches/server/0654-API-for-creating-command-sender-which-forwards-feedb.patch similarity index 96% rename from patches/unapplied/server/0658-API-for-creating-command-sender-which-forwards-feedb.patch rename to patches/server/0654-API-for-creating-command-sender-which-forwards-feedb.patch index 477c1e1ddbee..de6e7d281108 100644 --- a/patches/unapplied/server/0658-API-for-creating-command-sender-which-forwards-feedb.patch +++ b/patches/server/0654-API-for-creating-command-sender-which-forwards-feedb.patch @@ -122,10 +122,10 @@ index 0000000000000000000000000000000000000000..e3a5f1ec376319bdfda87fa27ae217bf + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index bb232cd338f94b03f2add34766927ecae019e388..c0eca359919c55ba7b33520277c124eb54d935d7 100644 +index d30c1e853bb2e27922a00d890dffca153cdcbe97..93811e7770546c202085487642699e0c74b9f498 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2162,6 +2162,13 @@ public final class CraftServer implements Server { +@@ -2166,6 +2166,13 @@ public final class CraftServer implements Server { return this.console.console; } @@ -153,7 +153,7 @@ index 7f22950ae61436e91a59cd29a345809c42bbe739..1e3091687735b461d3b6a313ab876112 protected ServerCommandSender() { diff --git a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java -index 98d314cd293d462ef109e952f3239e08e14dda59..2ee33c55890fa659f6d251e486264c85d9e89802 100644 +index 4e81c26fdbd089961b2577168c716bf29d504d40..a35e2d2f53e8308d51e5a07b34c56d05a707bc14 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java +++ b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java @@ -81,6 +81,11 @@ public final class VanillaCommandWrapper extends BukkitCommand { diff --git a/patches/unapplied/server/0659-Add-missing-structure-set-seed-configs.patch b/patches/server/0655-Add-missing-structure-set-seed-configs.patch similarity index 98% rename from patches/unapplied/server/0659-Add-missing-structure-set-seed-configs.patch rename to patches/server/0655-Add-missing-structure-set-seed-configs.patch index 94091f5e9daa..2862998d8470 100644 --- a/patches/unapplied/server/0659-Add-missing-structure-set-seed-configs.patch +++ b/patches/server/0655-Add-missing-structure-set-seed-configs.patch @@ -20,7 +20,7 @@ seeds/salts to the frequency reducer which has a similar effect. Co-authored-by: William Blake Galbreath diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index c5dd3aac54aa5936da4bd9f54f0e76ecf8141d27..102de569415ef011dacdca9a6ea8134d0ef62454 100644 +index 575fa665ff9c8f52056a0e7305540ec5c3da4785..906f56d07c26ef3c2dc1a3b62e9349dd91a37742 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -573,7 +573,7 @@ public abstract class ChunkGenerator { @@ -33,7 +33,7 @@ index c5dd3aac54aa5936da4bd9f54f0e76ecf8141d27..102de569415ef011dacdca9a6ea8134d this.tryGenerateStructure((StructureSet.StructureSelectionEntry) list.get(0), structureAccessor, registryManager, randomstate, structureTemplateManager, placementCalculator.getLevelSeed(), chunk, chunkcoordintpair, sectionposition); } else { diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java -index e6c59f986ae89022bd76463209dfa550a3d4fb59..a6b6e5ea191c0e2cd7a2e4f01b89d8af40a83c1b 100644 +index ed779a03e2ce7684428600dac4f2e92ab002f29f..a20520a6bd28bae1cee82258ac49d9753faba2bd 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java @@ -50,13 +50,14 @@ public class ChunkGeneratorStructureState { @@ -148,7 +148,7 @@ index e6c59f986ae89022bd76463209dfa550a3d4fb59..a6b6e5ea191c0e2cd7a2e4f01b89d8af } } diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java b/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java -index aae73586265593ee7830fb8dd5c2e3d7560057f0..c6181e14d85d454506534f9bbe856156c0d4a062 100644 +index 953ab7638f7242b5a11dd1de8786172443a0558c..5f354b333a39b873915bedd57b647355ae5bdf56 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java +++ b/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java @@ -74,6 +74,20 @@ public class StructureCheck { diff --git a/patches/unapplied/server/0660-Fix-cancelled-powdered-snow-bucket-placement.patch b/patches/server/0656-Fix-cancelled-powdered-snow-bucket-placement.patch similarity index 60% rename from patches/unapplied/server/0660-Fix-cancelled-powdered-snow-bucket-placement.patch rename to patches/server/0656-Fix-cancelled-powdered-snow-bucket-placement.patch index 08a9dbf2e458..d43d65f169ba 100644 --- a/patches/unapplied/server/0660-Fix-cancelled-powdered-snow-bucket-placement.patch +++ b/patches/server/0656-Fix-cancelled-powdered-snow-bucket-placement.patch @@ -8,10 +8,10 @@ snow bucket didn't revert grass that became snowy because of the placement. diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index ad1cb11245108b5cb187b686ed7e6bc769193b52..ec3be7fb4eb4560fe0106ac127f17d7437612157 100644 +index 8c9ae9ac38def29ae4cd8944395e566e434d46d0..9289faebce6b1546af71aeadc6569d2595b486e0 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -422,7 +422,7 @@ public final class ItemStack implements DataComponentHolder { +@@ -425,7 +425,7 @@ public final class ItemStack implements DataComponentHolder { int oldCount = this.getCount(); ServerLevel world = (ServerLevel) context.getLevel(); @@ -20,12 +20,12 @@ index ad1cb11245108b5cb187b686ed7e6bc769193b52..ec3be7fb4eb4560fe0106ac127f17d74 world.captureBlockStates = true; // special case bonemeal if (item == Items.BONE_MEAL) { -@@ -482,7 +482,7 @@ public final class ItemStack implements DataComponentHolder { - world.capturedBlockStates.clear(); - if (blocks.size() > 1) { - placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, enumhand, blocks, blockposition.getX(), blockposition.getY(), blockposition.getZ()); -- } else if (blocks.size() == 1) { +@@ -488,7 +488,7 @@ public final class ItemStack implements DataComponentHolder { + world.capturedBlockStates.clear(); + if (blocks.size() > 1) { + placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, enumhand, blocks, blockposition.getX(), blockposition.getY(), blockposition.getZ()); +- } else if (blocks.size() == 1) { + } else if (blocks.size() == 1 && item != Items.POWDER_SNOW_BUCKET) { // Paper - Fix cancelled powdered snow bucket placement - placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, enumhand, blocks.get(0), blockposition.getX(), blockposition.getY(), blockposition.getZ()); - } + placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, enumhand, blocks.get(0), blockposition.getX(), blockposition.getY(), blockposition.getZ()); + } diff --git a/patches/unapplied/server/0661-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch b/patches/server/0657-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch similarity index 86% rename from patches/unapplied/server/0661-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch rename to patches/server/0657-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch index 604f6800ee50..f3ca4340b021 100644 --- a/patches/unapplied/server/0661-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch +++ b/patches/server/0657-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add missing Validate calls to CraftServer#getSpawnLimit Copies appropriate checks from CraftWorld#getSpawnLimit diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index c0eca359919c55ba7b33520277c124eb54d935d7..1a2081267e85ef5c1edd4808fbda5bb442a00252 100644 +index 93811e7770546c202085487642699e0c74b9f498..8d9816f84e551f1257972f467352e9c9ee09473e 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2339,6 +2339,8 @@ public final class CraftServer implements Server { +@@ -2343,6 +2343,8 @@ public final class CraftServer implements Server { @Override public int getSpawnLimit(SpawnCategory spawnCategory) { // Paper start - Add mobcaps commands diff --git a/patches/unapplied/server/0662-Add-GameEvent-tags.patch b/patches/server/0658-Add-GameEvent-tags.patch similarity index 86% rename from patches/unapplied/server/0662-Add-GameEvent-tags.patch rename to patches/server/0658-Add-GameEvent-tags.patch index d545e402aeaa..d92210881e5d 100644 --- a/patches/unapplied/server/0662-Add-GameEvent-tags.patch +++ b/patches/server/0658-Add-GameEvent-tags.patch @@ -46,11 +46,11 @@ index 0000000000000000000000000000000000000000..e7d9fd2702a1ce96596580fff8f5ee4f + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 1a2081267e85ef5c1edd4808fbda5bb442a00252..8589b0218659ae5ddbaac5437316bf59265324dd 100644 +index 8d9816f84e551f1257972f467352e9c9ee09473e..b18ad8abb5e3c53b0e13544a6833198a670c1f34 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2688,6 +2688,15 @@ public final class CraftServer implements Server { - return (org.bukkit.Tag) new CraftEntityTag(BuiltInRegistries.ENTITY_TYPE, entityTagKey); +@@ -2700,6 +2700,15 @@ public final class CraftServer implements Server { + return (org.bukkit.Tag) new CraftDamageTag(damageRegistry, damageTagKey); } } + // Paper start @@ -65,9 +65,9 @@ index 1a2081267e85ef5c1edd4808fbda5bb442a00252..8589b0218659ae5ddbaac5437316bf59 default -> throw new IllegalArgumentException(); } -@@ -2720,6 +2729,13 @@ public final class CraftServer implements Server { - net.minecraft.core.Registry> entityTags = BuiltInRegistries.ENTITY_TYPE; - return entityTags.getTags().map(pair -> (org.bukkit.Tag) new CraftEntityTag(entityTags, pair.getFirst())).collect(ImmutableList.toImmutableList()); +@@ -2737,6 +2746,13 @@ public final class CraftServer implements Server { + net.minecraft.core.Registry damageTags = CraftRegistry.getMinecraftRegistry(Registries.DAMAGE_TYPE); + return damageTags.getTags().map(pair -> (org.bukkit.Tag) new CraftDamageTag(damageTags, pair.key())).collect(ImmutableList.toImmutableList()); } + // Paper start + case org.bukkit.Tag.REGISTRY_GAME_EVENTS -> { diff --git a/patches/unapplied/server/0663-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch b/patches/server/0659-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch similarity index 87% rename from patches/unapplied/server/0663-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch rename to patches/server/0659-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch index f73960e08f60..b3d65b12d0e4 100644 --- a/patches/unapplied/server/0663-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch +++ b/patches/server/0659-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch @@ -9,10 +9,10 @@ This might result in chunks loading far slower in the nether, for example. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 718b653a118a1c64d07efab93192f10dfcbf414e..d45f234fe389ade739bb13f824a1f650709220b8 100644 +index 15382d7da69967c50007f136e9d17dd2f81166e3..af392711da61a1921be1f82396c2a04dc897d563 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1369,6 +1369,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop extends +@@ -103,5 +103,37 @@ public abstract class CraftFurnace extends snapshot.cookSpeedMultiplier = multiplier; snapshot.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.isPlaced() ? this.world.getHandle() : null, snapshot.recipeType, snapshot, snapshot.cookSpeedMultiplier); // Update the snapshot's current total cook time to scale with the newly set multiplier } diff --git a/patches/unapplied/server/0665-Configurable-sculk-sensor-listener-range.patch b/patches/server/0661-Configurable-sculk-sensor-listener-range.patch similarity index 97% rename from patches/unapplied/server/0665-Configurable-sculk-sensor-listener-range.patch rename to patches/server/0661-Configurable-sculk-sensor-listener-range.patch index 99ff902efa5e..3dd132435490 100644 --- a/patches/unapplied/server/0665-Configurable-sculk-sensor-listener-range.patch +++ b/patches/server/0661-Configurable-sculk-sensor-listener-range.patch @@ -32,7 +32,7 @@ index 41ccbee5fc7767a7d5e1cdca0ec7d9a17ee80a90..1d28f117965da22694b12018923a5f13 } diff --git a/src/main/java/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java -index bbaffdac7c2d3bd646133b36c5d450cba9fc0c07..a943ed46a5f593dfe612c9c797dc961e3e020506 100644 +index 070814eb011ab8e02218c91e1cf75be5501c1a0a..28849cf84afcdc0d9fc245fac1a8d769a2db3b68 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java @@ -26,6 +26,7 @@ public class SculkSensorBlockEntity extends BlockEntity implements GameEventList @@ -58,8 +58,8 @@ index bbaffdac7c2d3bd646133b36c5d450cba9fc0c07..a943ed46a5f593dfe612c9c797dc961e + protected static final String PAPER_LISTENER_RANGE_NBT_KEY = "Paper.ListenerRange"; // Paper - Configurable sculk sensor listener range @Override - protected void saveAdditional(CompoundTag nbt, HolderLookup.Provider registryLookup) { - super.saveAdditional(nbt, registryLookup); + protected void saveAdditional(CompoundTag nbt, HolderLookup.Provider registries) { + super.saveAdditional(nbt, registries); @@ -63,7 +72,13 @@ public class SculkSensorBlockEntity extends BlockEntity implements GameEventList .encodeStart(registryOps, this.vibrationData) .resultOrPartial(string -> LOGGER.error("Failed to encode vibration listener for Sculk Sensor: '{}'", string)) diff --git a/patches/unapplied/server/0666-Add-missing-block-data-API.patch b/patches/server/0662-Add-missing-block-data-API.patch similarity index 100% rename from patches/unapplied/server/0666-Add-missing-block-data-API.patch rename to patches/server/0662-Add-missing-block-data-API.patch diff --git a/patches/unapplied/server/0667-Option-to-have-default-CustomSpawners-in-custom-worl.patch b/patches/server/0663-Option-to-have-default-CustomSpawners-in-custom-worl.patch similarity index 94% rename from patches/unapplied/server/0667-Option-to-have-default-CustomSpawners-in-custom-worl.patch rename to patches/server/0663-Option-to-have-default-CustomSpawners-in-custom-worl.patch index 9093bae5b5c9..94613610ac6c 100644 --- a/patches/unapplied/server/0667-Option-to-have-default-CustomSpawners-in-custom-worl.patch +++ b/patches/server/0663-Option-to-have-default-CustomSpawners-in-custom-worl.patch @@ -10,10 +10,10 @@ just looking at the LevelStem key, look at the DimensionType key which is one level below that. Defaults to off to keep vanilla behavior. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index d45f234fe389ade739bb13f824a1f650709220b8..413a37991d1df6314dd9938e5eb5f28f5b69efb8 100644 +index af392711da61a1921be1f82396c2a04dc897d563..7841421f00a3408e52b8d060674e6a686681210e 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -631,7 +631,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop containers = new ArrayList<>(); private final List> potionMixes = new ArrayList<>(); diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java -index c8f9972ad1c2330908cc840d426f29c20b242ca8..a2fafef89d5354e2cb02f5672810909950a57777 100644 +index e167c2834f1b7899a7d11cef782940deeb739a9c..2bafacd7bc56186d9105d2031180f8c4a6940018 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java -@@ -315,12 +315,12 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements +@@ -316,12 +316,12 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements @Override public boolean canPlaceItem(int slot, ItemStack stack) { @@ -276,16 +276,16 @@ index c8f9972ad1c2330908cc840d426f29c20b242ca8..a2fafef89d5354e2cb02f56728109099 return potionbrewer.isIngredient(stack); } else { -- return slot == 4 ? stack.is(Items.BLAZE_POWDER) : (stack.is(Items.POTION) || stack.is(Items.SPLASH_POTION) || stack.is(Items.LINGERING_POTION) || stack.is(Items.GLASS_BOTTLE)) && this.getItem(slot).isEmpty(); -+ return slot == 4 ? stack.is(Items.BLAZE_POWDER) : (stack.is(Items.POTION) || stack.is(Items.SPLASH_POTION) || stack.is(Items.LINGERING_POTION) || stack.is(Items.GLASS_BOTTLE) || potionbrewer.isCustomInput(stack)) && this.getItem(slot).isEmpty(); // Paper - Custom Potion Mixes +- return slot == 4 ? stack.is(ItemTags.BREWING_FUEL) : (stack.is(Items.POTION) || stack.is(Items.SPLASH_POTION) || stack.is(Items.LINGERING_POTION) || stack.is(Items.GLASS_BOTTLE)) && this.getItem(slot).isEmpty(); ++ return slot == 4 ? stack.is(ItemTags.BREWING_FUEL) : (stack.is(Items.POTION) || stack.is(Items.SPLASH_POTION) || stack.is(Items.LINGERING_POTION) || stack.is(Items.GLASS_BOTTLE) || potionbrewer.isCustomInput(stack)) && this.getItem(slot).isEmpty(); // Paper - Custom Potion Mixes } } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 74d2f6df5a4cdab8a24ca1769c7b7d98ef87bcfe..566ed56de6fcb4dc64e504310b46295466917eee 100644 +index 29a71a050e49f1131ce9945c4275a33909ea3091..f0eb8284b537014b591e45f034f1498e7e687e54 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -308,6 +308,7 @@ public final class CraftServer implements Server { +@@ -311,6 +311,7 @@ public final class CraftServer implements Server { private final io.papermc.paper.datapack.PaperDatapackManager datapackManager; // Paper public static Exception excessiveVelEx; // Paper - Velocity warnings private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); // Paper @@ -293,7 +293,7 @@ index 74d2f6df5a4cdab8a24ca1769c7b7d98ef87bcfe..566ed56de6fcb4dc64e504310b462954 static { ConfigurationSerialization.registerClass(CraftOfflinePlayer.class); -@@ -392,6 +393,7 @@ public final class CraftServer implements Server { +@@ -395,6 +396,7 @@ public final class CraftServer implements Server { if (this.configuration.getBoolean("settings.use-map-color-cache")) { MapPalette.setMapColorCache(new CraftMapColorCache(this.logger)); } @@ -301,7 +301,7 @@ index 74d2f6df5a4cdab8a24ca1769c7b7d98ef87bcfe..566ed56de6fcb4dc64e504310b462954 datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper } -@@ -3048,5 +3050,9 @@ public final class CraftServer implements Server { +@@ -3067,5 +3069,9 @@ public final class CraftServer implements Server { return datapackManager; } @@ -312,11 +312,11 @@ index 74d2f6df5a4cdab8a24ca1769c7b7d98ef87bcfe..566ed56de6fcb4dc64e504310b462954 // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java -index 139dff90561ac6c51954c6289918a07aeea13a1b..6ba29875d78ede4aa7978ff689e588f7fed11528 100644 +index 6f1da5aa8714d64b8454dc79258f941ead986e46..a68e036a12b354c4f04b6596dfb9cd6e7663718b 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java -@@ -15,6 +15,11 @@ public interface CraftRecipe extends Recipe { - void addToCraftingManager(); +@@ -25,6 +25,11 @@ public interface CraftRecipe extends Recipe { + } default Ingredient toNMS(RecipeChoice bukkit, boolean requireNotEmpty) { + // Paper start diff --git a/patches/unapplied/server/0670-Force-close-world-loading-screen.patch b/patches/server/0666-Force-close-world-loading-screen.patch similarity index 73% rename from patches/unapplied/server/0670-Force-close-world-loading-screen.patch rename to patches/server/0666-Force-close-world-loading-screen.patch index 284d51211569..647914a1ef5e 100644 --- a/patches/unapplied/server/0670-Force-close-world-loading-screen.patch +++ b/patches/server/0666-Force-close-world-loading-screen.patch @@ -10,13 +10,13 @@ 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 cff45afb90b232a236683bd569d50aab6b701149..e30ad8c7e85c25f3133bbd23dcbe59ae4c2f8db5 100644 +index f34cad30c982f2bb563f0deab030111720858fa8..f65b583057d37ec64a7cd9ed3ec09448064576db 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -394,6 +394,16 @@ public abstract class PlayerList { - this.sendActivePlayerEffects(player); - // Paper start - Fire PlayerJoinEvent when Player is actually ready; move vehicle into method so it can be called above - short circuit around that code - this.onPlayerJoinFinish(player, worldserver1, s1); +@@ -179,6 +179,16 @@ public abstract class PlayerList { + this.registries = registryManager; + this.maxPlayers = maxPlayers; + this.playerIo = saveHandler; + // Paper start - Send empty chunk, so players aren't stuck in the world loading screen with our chunk system not sending chunks when dead + if (player.isDeadOrDying()) { + net.minecraft.core.Holder plains = worldserver1.registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.BIOME) @@ -28,5 +28,5 @@ index cff45afb90b232a236683bd569d50aab6b701149..e30ad8c7e85c25f3133bbd23dcbe59ae + } + // Paper end - Send empty chunk } - private void mountSavedVehicle(ServerPlayer player, ServerLevel worldserver1, Optional optional) { - // Paper end - Fire PlayerJoinEvent when Player is actually ready + abstract public void loadAndSaveFiles(); // Paper - fix converting txt to json file; moved from DedicatedPlayerList constructor + diff --git a/patches/unapplied/server/0671-Fix-falling-block-spawn-methods.patch b/patches/server/0667-Fix-falling-block-spawn-methods.patch similarity index 91% rename from patches/unapplied/server/0671-Fix-falling-block-spawn-methods.patch rename to patches/server/0667-Fix-falling-block-spawn-methods.patch index 548b96559bf2..46c0f8edfb9d 100644 --- a/patches/unapplied/server/0671-Fix-falling-block-spawn-methods.patch +++ b/patches/server/0667-Fix-falling-block-spawn-methods.patch @@ -11,10 +11,10 @@ Restores the API behavior from previous versions of the server public net.minecraft.world.entity.item.FallingBlockEntity (Lnet/minecraft/world/level/Level;DDDLnet/minecraft/world/level/block/state/BlockState;)V diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index ba011d3b56ed0e5019da61ccfec687042d863beb..20a954c8637c2cf9cc6c0c823e33a44f668cc4f6 100644 +index 7dc167950021371b5cf8a7e1e38f013220e1c8a6..9ea74d52112ab4feea3f4bafd82351a72088cbc5 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -1395,7 +1395,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1405,7 +1405,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { Preconditions.checkArgument(material != null, "Material cannot be null"); Preconditions.checkArgument(material.isBlock(), "Material.%s must be a block", material); @@ -28,7 +28,7 @@ index ba011d3b56ed0e5019da61ccfec687042d863beb..20a954c8637c2cf9cc6c0c823e33a44f return (FallingBlock) entity.getBukkitEntity(); } -@@ -1404,7 +1409,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1414,7 +1419,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { Preconditions.checkArgument(location != null, "Location cannot be null"); Preconditions.checkArgument(data != null, "BlockData cannot be null"); @@ -43,10 +43,10 @@ index ba011d3b56ed0e5019da61ccfec687042d863beb..20a954c8637c2cf9cc6c0c823e33a44f } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java -index 481f0c62fcd4435d655cfe2f94f46262b24a7144..37527713b0afa6db19eefd57aaffcb2fe3544ce6 100644 +index 42ecef3dbb888ba716b6f63335efca6fb0f27457..b79e72a77178f755957ef391b6444a357bdefbd0 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java -@@ -387,7 +387,7 @@ public final class CraftEntityTypes { +@@ -440,7 +440,7 @@ public final class CraftEntityTypes { register(new EntityTypeData<>(EntityType.TNT, TNTPrimed.class, CraftTNTPrimed::new, spawnData -> new PrimedTnt(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), null))); register(new EntityTypeData<>(EntityType.FALLING_BLOCK, FallingBlock.class, CraftFallingBlock::new, spawnData -> { BlockPos pos = BlockPos.containing(spawnData.x(), spawnData.y(), spawnData.z()); diff --git a/patches/unapplied/server/0672-Expose-furnace-minecart-push-values.patch b/patches/server/0668-Expose-furnace-minecart-push-values.patch similarity index 100% rename from patches/unapplied/server/0672-Expose-furnace-minecart-push-values.patch rename to patches/server/0668-Expose-furnace-minecart-push-values.patch diff --git a/patches/unapplied/server/0673-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch b/patches/server/0669-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch similarity index 91% rename from patches/unapplied/server/0673-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch rename to patches/server/0669-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch index 4698298019ab..7a72849b26e5 100644 --- a/patches/unapplied/server/0673-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch +++ b/patches/server/0669-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch @@ -15,11 +15,11 @@ piercing arrows to avoid duplicate damage being applied. protected net.minecraft.world.entity.projectile.Projectile hitCancelled diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -index 57ebb96707748e90810dc07471f9769f1317df9d..10d30304c8c89b1f2a55be8529035311d1424e44 100644 +index 44bcb1117cfa4d66c500011489ae193a0d1e7d78..75cc3db39c974abab8510af4a633fc6812efc647 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -@@ -329,6 +329,19 @@ public abstract class AbstractArrow extends Projectile { - } +@@ -344,6 +344,19 @@ public abstract class AbstractArrow extends Projectile { + } + // Paper start - Fix cancelling ProjectileHitEvent for piercing arrows diff --git a/patches/unapplied/server/0674-More-Projectile-API.patch b/patches/server/0670-More-Projectile-API.patch similarity index 91% rename from patches/unapplied/server/0674-More-Projectile-API.patch rename to patches/server/0670-More-Projectile-API.patch index a58713f20399..db5d86dec1ff 100644 --- a/patches/unapplied/server/0674-More-Projectile-API.patch +++ b/patches/server/0670-More-Projectile-API.patch @@ -28,10 +28,10 @@ Co-authored-by: MelnCat Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -index 5b7734020b496ade3740d92908ad2d399bfd55e6..e70ca1b2e6fbbc1f20e65429298d01b4ebd2dd29 100644 +index 536196a740f607adda2a5ae7f644981ac26bef98..1f95234c0a1457050574aa0f6c4b2a8c91b1f272 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java +++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -@@ -414,13 +414,18 @@ public class FishingHook extends Projectile { +@@ -419,13 +419,18 @@ public class FishingHook extends Projectile { } } else { // CraftBukkit start - logic to modify fishing wait time @@ -53,10 +53,10 @@ index 5b7734020b496ade3740d92908ad2d399bfd55e6..e70ca1b2e6fbbc1f20e65429298d01b4 public boolean calculateOpenWater(BlockPos pos) { FishingHook.OpenWaterType entityfishinghook_waterposition = FishingHook.OpenWaterType.INVALID; diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index d27e17ebf25cd842a943cf82bde05b2248c74414..06ca07edef062f21c51860146086297ca345104d 100644 +index 2cb77d0b6e6ba880a2a76488a870a20ed883b15a..846a108af8bacdcaf3a17db9fb808965ce2581bb 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -190,7 +190,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -288,7 +288,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { } // CraftBukkit start - call projectile hit event @@ -66,10 +66,10 @@ index d27e17ebf25cd842a943cf82bde05b2248c74414..06ca07edef062f21c51860146086297c this.hitCancelled = event != null && event.isCancelled(); if (movingobjectposition.getType() == HitResult.Type.BLOCK || !this.hitCancelled) { diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java -index cb34cc9443da56c0497c7a0192c8b8363c3426fe..58dc69fe319027c2b9ecfb9caf272368e81081df 100644 +index d6ac07d9d5ee0430a1d91b7084b378aac1d047e5..a486466040a646b8a5a5ff2430cdd25b95b7e20f 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java -@@ -102,6 +102,11 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie +@@ -103,8 +103,12 @@ public class ThrownPotion extends ThrowableItemProjectile { @Override protected void onHit(HitResult hitResult) { super.onHit(hitResult); @@ -78,28 +78,30 @@ index cb34cc9443da56c0497c7a0192c8b8363c3426fe..58dc69fe319027c2b9ecfb9caf272368 + } + public void splash(@Nullable HitResult hitResult) { + // Paper end - More projectile API - if (!this.level().isClientSide) { + Level world = this.level(); +- + if (world instanceof ServerLevel worldserver) { ItemStack itemstack = this.getItem(); PotionContents potioncontents = (PotionContents) itemstack.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY); -@@ -113,7 +118,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie +@@ -116,7 +120,7 @@ public class ThrownPotion extends ThrowableItemProjectile { if (this.isLingering()) { showParticles = this.makeAreaOfEffectCloud(potioncontents, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper } else { -- showParticles = this.applySplash(potioncontents.getAllEffects(), hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper -+ showParticles = this.applySplash(potioncontents.getAllEffects(), hitResult != null && hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper - More projectile API +- showParticles = this.applySplash(worldserver, potioncontents.getAllEffects(), hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper ++ showParticles = this.applySplash(worldserver, potioncontents.getAllEffects(), hitResult != null && hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper - More projectile API } } -@@ -175,7 +180,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie +@@ -178,7 +182,7 @@ public class ThrownPotion extends ThrowableItemProjectile { } -- private boolean applySplash(Iterable iterable, @Nullable Entity entity, HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events -+ private boolean applySplash(Iterable iterable, @Nullable Entity entity, @Nullable HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events & More projectile API +- private boolean applySplash(ServerLevel worldserver, Iterable iterable, @Nullable Entity entity, HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events ++ private boolean applySplash(ServerLevel worldserver, Iterable iterable, @Nullable Entity entity, @Nullable HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events & More projectile API AABB axisalignedbb = this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D); - List list = this.level().getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb); + List list = worldserver.getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb); Map affected = new HashMap(); // CraftBukkit -@@ -253,7 +258,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie +@@ -256,7 +260,7 @@ public class ThrownPotion extends ThrowableItemProjectile { } @@ -179,10 +181,10 @@ index 91c2d0b40d3fca86938cd454e1415a4eea3df7c7..de4fb2654c7895cfd83ad694455ee56c + // Paper end - More projectile API } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java -index 329ca9c743a7f2feeabbfb769ff9a71f60165006..faa08ad912fa43e7a6c5a2359e23c04c059c5edf 100644 +index 0f85c1f991469b277bba8b40b087f7224b4b3a85..1f30109abd86b76af343eb5eb75ec3db83ef9417 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java -@@ -58,20 +58,7 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr +@@ -59,20 +59,7 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr this.getHandle().setCritArrow(critical); } @@ -204,7 +206,7 @@ index 329ca9c743a7f2feeabbfb769ff9a71f60165006..faa08ad912fa43e7a6c5a2359e23c04c @Override public boolean isInBlock() { -@@ -130,6 +117,7 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr +@@ -133,6 +120,7 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr @Override public ItemStack getWeapon() { @@ -212,7 +214,7 @@ index 329ca9c743a7f2feeabbfb769ff9a71f60165006..faa08ad912fa43e7a6c5a2359e23c04c return CraftItemStack.asBukkitCopy(this.getHandle().getWeaponItem()); } -@@ -149,4 +137,37 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr +@@ -152,4 +140,37 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr public String toString() { return "CraftArrow"; } @@ -251,7 +253,7 @@ index 329ca9c743a7f2feeabbfb769ff9a71f60165006..faa08ad912fa43e7a6c5a2359e23c04c + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java -index 81f5e1d866128af8fb2acc13aca715580fdf9886..88f2a9f310f30a08893f3fa68af13a54cf72fa7f 100644 +index 6591513bb62226b6f85fd2ef9f6ebe376f0f7362..f9c113dc018702159345240d6d0de85767afa0c3 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java @@ -125,7 +125,7 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud @@ -275,14 +277,14 @@ index 81f5e1d866128af8fb2acc13aca715580fdf9886..88f2a9f310f30a08893f3fa68af13a54 @@ -151,7 +151,7 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud public void clearCustomEffects() { PotionContents old = this.getHandle().potionContents; - this.getHandle().setPotionContents(new PotionContents(old.potion(), old.customColor(), List.of())); + this.getHandle().setPotionContents(new PotionContents(old.potion(), old.customColor(), List.of(), old.customName())); - this.getHandle().updateColor(); + // this.getHandle().updateColor(); // Paper - already done above } @Override diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java -index 5232fbef0d014edd32a5d18d4a1500ab215313f5..071be344c3265a0cd52b31ffbb02ff7a70bdf231 100644 +index 199d5836dc787cca54c6b653a4e67573f2f758a2..15d50a284cafc2eb59239ca00926836526f09e06 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java @@ -43,7 +43,7 @@ public class CraftArrow extends CraftAbstractArrow implements Arrow { @@ -297,7 +299,7 @@ index 5232fbef0d014edd32a5d18d4a1500ab215313f5..071be344c3265a0cd52b31ffbb02ff7a @@ -51,7 +51,7 @@ public class CraftArrow extends CraftAbstractArrow implements Arrow { public void clearCustomEffects() { PotionContents old = this.getHandle().getPotionContents(); - this.getHandle().setPotionContents(new PotionContents(old.potion(), old.customColor(), List.of())); + this.getHandle().setPotionContents(new PotionContents(old.potion(), old.customColor(), List.of(), old.customName())); - this.getHandle().updateColor(); + // this.getHandle().updateColor(); // Paper - already done above } @@ -310,7 +312,7 @@ index 5232fbef0d014edd32a5d18d4a1500ab215313f5..071be344c3265a0cd52b31ffbb02ff7a - int colorRGB = (color == null) ? -1 : color.asRGB(); + int colorRGB = (color == null) ? net.minecraft.world.entity.projectile.Arrow.NO_EFFECT_COLOR : color.asARGB(); // Paper PotionContents old = this.getHandle().getPotionContents(); - this.getHandle().setPotionContents(new PotionContents(old.potion(), Optional.of(colorRGB), old.customEffects())); + this.getHandle().setPotionContents(new PotionContents(old.potion(), Optional.of(colorRGB), old.customEffects(), old.customName())); } @Override @@ -325,18 +327,18 @@ index 5232fbef0d014edd32a5d18d4a1500ab215313f5..071be344c3265a0cd52b31ffbb02ff7a } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java -index 37527713b0afa6db19eefd57aaffcb2fe3544ce6..46a4f31e2b6eee6f8dc5f8fccd7de4c48a698b61 100644 +index b79e72a77178f755957ef391b6444a357bdefbd0..39ea25d2145acaa7c7b458800adc674a3e73e7c1 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java -@@ -389,7 +389,7 @@ public final class CraftEntityTypes { +@@ -442,7 +442,7 @@ public final class CraftEntityTypes { BlockPos pos = BlockPos.containing(spawnData.x(), spawnData.y(), spawnData.z()); return new FallingBlockEntity(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), spawnData.world().getBlockState(pos)); // Paper - create falling block entities correctly })); - register(new EntityTypeData<>(EntityType.FIREWORK_ROCKET, Firework.class, CraftFirework::new, spawnData -> new FireworkRocketEntity(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), net.minecraft.world.item.ItemStack.EMPTY))); + register(new EntityTypeData<>(EntityType.FIREWORK_ROCKET, Firework.class, CraftFirework::new, spawnData -> new FireworkRocketEntity(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), FireworkRocketEntity.getDefaultItem()))); // Paper - pass correct default to rocket for data storage register(new EntityTypeData<>(EntityType.EVOKER_FANGS, EvokerFangs.class, CraftEvokerFangs::new, spawnData -> new net.minecraft.world.entity.projectile.EvokerFangs(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), (float) Math.toRadians(spawnData.yaw()), 0, null))); - register(new EntityTypeData<>(EntityType.COMMAND_BLOCK_MINECART, CommandMinecart.class, CraftMinecartCommand::new, spawnData -> new MinecartCommandBlock(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z()))); - register(new EntityTypeData<>(EntityType.MINECART, RideableMinecart.class, CraftMinecartRideable::new, spawnData -> new Minecart(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z()))); + register(new EntityTypeData<>(EntityType.COMMAND_BLOCK_MINECART, CommandMinecart.class, CraftMinecartCommand::new, createMinecart(net.minecraft.world.entity.EntityType.COMMAND_BLOCK_MINECART))); + register(new EntityTypeData<>(EntityType.MINECART, RideableMinecart.class, CraftMinecartRideable::new, createMinecart(net.minecraft.world.entity.EntityType.MINECART))); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java index 1b084d63bdbb24dad45d28eed1693eb6e26e24dc..43d7bea201a52cfeacf60c75caa28dfd2c4ff164 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java @@ -518,10 +520,10 @@ index 6e2f91423371ead9890095cf4b1e2299c4dcba28..9d8f4b7176e60180565e3134a14ecf19 + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 0ed2910e64b6efdb4180c5bc23a146aced87c3d9..6350d4729fa3fbd9b15f1150cb4322f1c685044a 100644 +index e148239d4930e5cbb000beed4de386f992f28d88..14b4c3835388d957653ba34444968bb718ce7f68 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -570,8 +570,15 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -579,8 +579,15 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { } @Override @@ -538,7 +540,7 @@ index 0ed2910e64b6efdb4180c5bc23a146aced87c3d9..6350d4729fa3fbd9b15f1150cb4322f1 Preconditions.checkState(!this.getHandle().generation, "Cannot launch projectile during world generation"); net.minecraft.world.level.Level world = ((CraftWorld) this.getWorld()).getHandle(); -@@ -597,7 +604,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -606,7 +613,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { } else { launch = new net.minecraft.world.entity.projectile.Arrow(world, this.getHandle(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ARROW), null); } @@ -546,8 +548,8 @@ index 0ed2910e64b6efdb4180c5bc23a146aced87c3d9..6350d4729fa3fbd9b15f1150cb4322f1 + ((net.minecraft.world.entity.projectile.AbstractArrow) launch).shootFromRotation(this.getHandle(), this.getHandle().getXRot(), this.getHandle().getYRot(), 0.0F, Trident.class.isAssignableFrom(projectile) ? net.minecraft.world.item.TridentItem.SHOOT_POWER : 3.0F, 1.0F); // ItemBow // Paper - see TridentItem } else if (ThrownPotion.class.isAssignableFrom(projectile)) { if (LingeringPotion.class.isAssignableFrom(projectile)) { - launch = new net.minecraft.world.entity.projectile.ThrownPotion(world, this.getHandle()); -@@ -656,8 +663,26 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { + launch = new net.minecraft.world.entity.projectile.ThrownPotion(world, this.getHandle(), new net.minecraft.world.item.ItemStack(Items.LINGERING_POTION)); +@@ -663,8 +670,26 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { } else if (Firework.class.isAssignableFrom(projectile)) { Location location = this.getEyeLocation(); @@ -576,7 +578,7 @@ index 0ed2910e64b6efdb4180c5bc23a146aced87c3d9..6350d4729fa3fbd9b15f1150cb4322f1 } Preconditions.checkArgument(launch != null, "Projectile (%s) not supported", projectile.getName()); -@@ -665,6 +690,11 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -672,6 +697,11 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { if (velocity != null) { ((T) launch.getBukkitEntity()).setVelocity(velocity); } @@ -765,10 +767,10 @@ index e374b9f40eddca13b30855d25a2030f8df98138f..4fc893378fb0568ddcffc7593d66df6b // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 5fc6ef13cdc9df11b0fd2b0baf3cec862ccb5e37..eeb326a115020f571e96f3ec85408950b5eb56fb 100644 +index 376563ea6990aef558a34e4f5889125412b734df..412f5e414745123535a275d5670b35fff5b1aaec 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -843,19 +843,19 @@ public class CraftEventFactory { +@@ -841,19 +841,19 @@ public class CraftEventFactory { /** * PotionSplashEvent */ @@ -791,7 +793,7 @@ index 5fc6ef13cdc9df11b0fd2b0baf3cec862ccb5e37..eeb326a115020f571e96f3ec85408950 hitEntity = ((EntityHitResult) position).getEntity().getBukkitEntity(); } -@@ -864,20 +864,20 @@ public class CraftEventFactory { +@@ -862,20 +862,20 @@ public class CraftEventFactory { return event; } @@ -816,10 +818,10 @@ index 5fc6ef13cdc9df11b0fd2b0baf3cec862ccb5e37..eeb326a115020f571e96f3ec85408950 } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index e8a455eb5e17bcfcae3f03664f2b47773fbdf37e..08178a88ba7d0881a6c2843eef24a846cf07adb4 100644 +index 60062ea5b18b95a14c459f2f3a0743c1e1ac0f12..502be683e8b04a9966043c9bee9d9fe793b12ef5 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -@@ -329,12 +329,23 @@ public final class CraftItemStack extends ItemStack { +@@ -341,12 +341,23 @@ public final class CraftItemStack extends ItemStack { public ItemMeta getItemMeta() { return CraftItemStack.getItemMeta(this.handle); } @@ -844,10 +846,10 @@ index e8a455eb5e17bcfcae3f03664f2b47773fbdf37e..08178a88ba7d0881a6c2843eef24a846 } diff --git a/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java b/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java -index 93b9e6b32798e32026492fa3f80de9d4a7b3d9a5..d2329ebf12dbea922fab481cd6822b36682f3461 100644 +index 642f5bf75661eb485558bc227f668e84416f3b5f..76fd4d27730d9139caa67099a6757ea33d681be9 100644 --- a/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java +++ b/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java -@@ -55,7 +55,15 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { +@@ -56,7 +56,15 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { @Override public T launchProjectile(Class projectile, Vector velocity) { @@ -863,7 +865,7 @@ index 93b9e6b32798e32026492fa3f80de9d4a7b3d9a5..d2329ebf12dbea922fab481cd6822b36 // Copied from BlockDispenser.dispense() BlockSource sourceblock = new BlockSource((ServerLevel) this.dispenserBlock.getLevel(), this.dispenserBlock.getBlockPos(), this.dispenserBlock.getBlockState(), this.dispenserBlock); // Copied from DispenseBehaviorProjectile -@@ -67,7 +75,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { +@@ -68,7 +76,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { item = Items.SNOWBALL; } else if (Egg.class.isAssignableFrom(projectile)) { item = Items.EGG; @@ -872,7 +874,7 @@ index 93b9e6b32798e32026492fa3f80de9d4a7b3d9a5..d2329ebf12dbea922fab481cd6822b36 item = Items.ENDER_PEARL; } else if (ThrownExpBottle.class.isAssignableFrom(projectile)) { item = Items.EXPERIENCE_BOTTLE; -@@ -82,20 +90,20 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { +@@ -83,20 +91,20 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { item = Items.TIPPED_ARROW; } else if (SpectralArrow.class.isAssignableFrom(projectile)) { item = Items.SPECTRAL_ARROW; @@ -897,7 +899,7 @@ index 93b9e6b32798e32026492fa3f80de9d4a7b3d9a5..d2329ebf12dbea922fab481cd6822b36 ItemStack itemstack = new ItemStack(item); ProjectileItem projectileItem = (ProjectileItem) item; -@@ -104,7 +112,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { +@@ -105,7 +113,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { Position iposition = dispenseConfig.positionFunction().getDispensePosition(sourceblock, enumdirection); net.minecraft.world.entity.projectile.Projectile launch = projectileItem.asProjectile(world, iposition, itemstack, enumdirection); @@ -905,8 +907,8 @@ index 93b9e6b32798e32026492fa3f80de9d4a7b3d9a5..d2329ebf12dbea922fab481cd6822b36 + if (false && Fireball.class.isAssignableFrom(projectile)) { // Paper - more project API - dispensers cannot launch anything but fire charges. AbstractHurtingProjectile customFireball = null; if (WitherSkull.class.isAssignableFrom(projectile)) { - launch = customFireball = EntityType.WITHER_SKULL.create(world); -@@ -129,7 +137,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { + launch = customFireball = EntityType.WITHER_SKULL.create(world, EntitySpawnReason.TRIGGERED); +@@ -130,7 +138,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { } } @@ -915,7 +917,7 @@ index 93b9e6b32798e32026492fa3f80de9d4a7b3d9a5..d2329ebf12dbea922fab481cd6822b36 arrow.pickup = net.minecraft.world.entity.projectile.AbstractArrow.Pickup.ALLOWED; } launch.projectileSource = this; -@@ -138,6 +146,11 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { +@@ -139,6 +147,11 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { if (velocity != null) { ((T) launch.getBukkitEntity()).setVelocity(velocity); } diff --git a/patches/unapplied/server/0675-Fix-swamp-hut-cat-generation-deadlock.patch b/patches/server/0671-Fix-swamp-hut-cat-generation-deadlock.patch similarity index 83% rename from patches/unapplied/server/0675-Fix-swamp-hut-cat-generation-deadlock.patch rename to patches/server/0671-Fix-swamp-hut-cat-generation-deadlock.patch index 6aa68bdd5ceb..24bfbc0dc7c0 100644 --- a/patches/unapplied/server/0675-Fix-swamp-hut-cat-generation-deadlock.patch +++ b/patches/server/0671-Fix-swamp-hut-cat-generation-deadlock.patch @@ -10,20 +10,20 @@ indefinitely. Instead of using the world state, we use the already supplied ServerLevelAccessor which will always have the chunk available. diff --git a/src/main/java/net/minecraft/world/entity/animal/Cat.java b/src/main/java/net/minecraft/world/entity/animal/Cat.java -index f0e5428394f8de8f7ac05b8cbc34826d153eeaef..d44807c16712afd37efdbf434d1afb12a7c3d343 100644 +index f3a991aa878f3b29fdc525ecdde6766efb5e129c..5a86530c65d7d83e4608600a04ffd931bf59dc4a 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Cat.java +++ b/src/main/java/net/minecraft/world/entity/animal/Cat.java -@@ -357,7 +357,7 @@ public class Cat extends TamableAnimal implements VariantHolder> predicate, @Nullable ServerLevelAccessor levelAccessor) { + // Paper end - Fix swamp hut cat generation deadlock - Registry registry = this.registryAccess().registryOrThrow(Registries.STRUCTURE); + Registry registry = this.registryAccess().lookupOrThrow(Registries.STRUCTURE); for (StructureStart structureStart : this.startsForStructure( -- new ChunkPos(pos), structure -> registry.getHolder(registry.getId(structure)).map(predicate::test).orElse(false) -+ new ChunkPos(pos), structure -> registry.getHolder(registry.getId(structure)).map(predicate::test).orElse(false), levelAccessor // Paper - Fix swamp hut cat generation deadlock +- new ChunkPos(pos), structure -> registry.get(registry.getId(structure)).map(predicate::test).orElse(false) ++ new ChunkPos(pos), structure -> registry.get(registry.getId(structure)).map(predicate::test).orElse(false), levelAccessor // Paper - Fix swamp hut cat generation deadlock )) { if (this.structureHasPieceAt(pos, structureStart)) { return structureStart; diff --git a/patches/unapplied/server/0676-Don-t-allow-vehicle-movement-from-players-while-tele.patch b/patches/server/0672-Don-t-allow-vehicle-movement-from-players-while-tele.patch similarity index 90% rename from patches/unapplied/server/0676-Don-t-allow-vehicle-movement-from-players-while-tele.patch rename to patches/server/0672-Don-t-allow-vehicle-movement-from-players-while-tele.patch index 0ceb6b0ce1ee..b0a250292cc3 100644 --- a/patches/unapplied/server/0676-Don-t-allow-vehicle-movement-from-players-while-tele.patch +++ b/patches/server/0672-Don-t-allow-vehicle-movement-from-players-while-tele.patch @@ -7,10 +7,10 @@ Bring the vehicle move packet behavior in line with the regular player move packet. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 1e806fd16ca5f90bdb4f71dea008d7936eb82562..76c9feb5e1389eb929571de74ececd4a4f384453 100644 +index 7b858178ce7d0e33fec17311f1710bead5f0837d..33f76a6df7997ecdc789004bf0b230e74ad07f5a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -484,6 +484,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -481,6 +481,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.disconnect((Component) Component.translatable("multiplayer.disconnect.invalid_vehicle_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_VEHICLE_MOVEMENT); // Paper - kick event cause } else if (!this.updateAwaitingTeleport()) { Entity entity = this.player.getRootVehicle(); diff --git a/patches/unapplied/server/0677-Implement-getComputedBiome-API.patch b/patches/server/0673-Implement-getComputedBiome-API.patch similarity index 88% rename from patches/unapplied/server/0677-Implement-getComputedBiome-API.patch rename to patches/server/0673-Implement-getComputedBiome-API.patch index 41624673a765..3028eee933bf 100644 --- a/patches/unapplied/server/0677-Implement-getComputedBiome-API.patch +++ b/patches/server/0673-Implement-getComputedBiome-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Implement getComputedBiome API diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index 5d137f8c42356359701e1bea7525f82c018b502c..f6dd8665b9f6e2a8ff396deba8a021e695bedf7e 100644 +index 123824f6b8306900ed5c0b3addb884301dbcab7e..244cff4f84792fd0efe146e6faf47db0b0a0dc87 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java @@ -77,6 +77,13 @@ public abstract class CraftRegionAccessor implements RegionAccessor { @@ -23,7 +23,7 @@ index 5d137f8c42356359701e1bea7525f82c018b502c..f6dd8665b9f6e2a8ff396deba8a021e6 public void setBiome(Location location, Biome biome) { this.setBiome(location.getBlockX(), location.getBlockY(), location.getBlockZ(), biome); diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index 068b3735b6c50a7a2053c7dc39856f728fb7218a..6d10396347b69d9243ab902ecc68ede93fa17b7d 100644 +index d5b495b5a3ca7f4411d1a700f7149042a16509f1..68fcec085334383808b2117a49220f4d8239220b 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -340,6 +340,13 @@ public class CraftBlock implements Block { @@ -41,10 +41,10 @@ index 068b3735b6c50a7a2053c7dc39856f728fb7218a..6d10396347b69d9243ab902ecc68ede9 public void setBiome(Biome bio) { this.getWorld().setBiome(this.getX(), this.getY(), this.getZ(), bio); diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java -index 7d6ee60b1d3e023e1eabc59eb591c3ae3d8ac043..eaa9ba70b0b80d86eb376a0641420093a7c9dfdb 100644 +index 2c7b64bd7071cb803a042152d497982d753e0b5d..a23269e3bdb83f85a1d08d5f7b54742025223ada 100644 --- a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java +++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java -@@ -165,6 +165,14 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe +@@ -166,6 +166,14 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe return super.getBiome(x, y, z); } diff --git a/patches/unapplied/server/0678-Make-some-itemstacks-nonnull.patch b/patches/server/0674-Make-some-itemstacks-nonnull.patch similarity index 94% rename from patches/unapplied/server/0678-Make-some-itemstacks-nonnull.patch rename to patches/server/0674-Make-some-itemstacks-nonnull.patch index 4679d4a859ad..5254271c7e54 100644 --- a/patches/unapplied/server/0678-Make-some-itemstacks-nonnull.patch +++ b/patches/server/0674-Make-some-itemstacks-nonnull.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Make some itemstacks nonnull diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java -index 972fe4237461f07f78b60845b2ebfefb06698ded..9d74577af071954e1e37201a96368c1360076209 100644 +index 5e40faa88c51b0ebd76493fd1731d16ca1051f4a..46d0b324498510c73a8439611f44269edee62313 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java @@ -155,13 +155,13 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i diff --git a/patches/unapplied/server/0679-Implement-enchantWithLevels-API.patch b/patches/server/0675-Implement-enchantWithLevels-API.patch similarity index 95% rename from patches/unapplied/server/0679-Implement-enchantWithLevels-API.patch rename to patches/server/0675-Implement-enchantWithLevels-API.patch index 23f8df750399..08f1ffbe3e63 100644 --- a/patches/unapplied/server/0679-Implement-enchantWithLevels-API.patch +++ b/patches/server/0675-Implement-enchantWithLevels-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Implement enchantWithLevels API diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -index 803a19063c03627dbea79cb1c395ae35aaef2834..fef91dbede067f1ab99a9c7d463a2c55cc6cae3a 100644 +index 237df8b37ee8cf5b15e8e6d30fa3b51ef394434d..944dcc1126c947b4c8c3b4fdd174eb57320abbba 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -@@ -302,4 +302,47 @@ public final class CraftItemFactory implements ItemFactory { +@@ -305,4 +305,47 @@ public final class CraftItemFactory implements ItemFactory { return eggItem == null ? null : new net.minecraft.world.item.ItemStack(eggItem).asBukkitMirror(); } // Paper end - old getSpawnEgg API diff --git a/patches/unapplied/server/0680-Fix-saving-in-unloadWorld.patch b/patches/server/0676-Fix-saving-in-unloadWorld.patch similarity index 83% rename from patches/unapplied/server/0680-Fix-saving-in-unloadWorld.patch rename to patches/server/0676-Fix-saving-in-unloadWorld.patch index 5536c9b21abb..d5a0b6e7c712 100644 --- a/patches/unapplied/server/0680-Fix-saving-in-unloadWorld.patch +++ b/patches/server/0676-Fix-saving-in-unloadWorld.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Fix saving in unloadWorld Change savingDisabled to false to ensure ServerLevel's saving logic gets called when unloadWorld is called with save = true diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 566ed56de6fcb4dc64e504310b46295466917eee..183d9672ad60e2b7db48c283b1ca863df01ad658 100644 +index f0eb8284b537014b591e45f034f1498e7e687e54..cc08b56da8a276202da3e85315fdb2ad530c2545 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1383,7 +1383,7 @@ public final class CraftServer implements Server { +@@ -1386,7 +1386,7 @@ public final class CraftServer implements Server { try { if (save) { diff --git a/patches/unapplied/server/0681-Buffer-OOB-setBlock-calls.patch b/patches/server/0677-Buffer-OOB-setBlock-calls.patch similarity index 95% rename from patches/unapplied/server/0681-Buffer-OOB-setBlock-calls.patch rename to patches/server/0677-Buffer-OOB-setBlock-calls.patch index 7bc7bd4823c3..1b7ba291c41e 100644 --- a/patches/unapplied/server/0681-Buffer-OOB-setBlock-calls.patch +++ b/patches/server/0677-Buffer-OOB-setBlock-calls.patch @@ -13,7 +13,7 @@ we'll also only gen a trace for the first one, I see no real pressing need to generate more, given that that would *massively* negate this patch otherwise diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java -index 421f146ea9c35b852251c0ddb29856c13e11aef3..13229388ddce668061a34c787ab9586d41854d8a 100644 +index f1725ef766c35aa623ace58fe8bf31fc9b2bb6b3..5bf438bb58833c1df3620e82d3d2b90207366372 100644 --- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java +++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java @@ -284,6 +284,7 @@ public class WorldGenRegion implements WorldGenLevel { diff --git a/patches/server/0678-Add-TameableDeathMessageEvent.patch b/patches/server/0678-Add-TameableDeathMessageEvent.patch new file mode 100644 index 000000000000..79f0ebc540e9 --- /dev/null +++ b/patches/server/0678-Add-TameableDeathMessageEvent.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> +Date: Mon, 21 Jun 2021 21:24:45 -0400 +Subject: [PATCH] Add TameableDeathMessageEvent + + +diff --git a/src/main/java/net/minecraft/world/entity/TamableAnimal.java b/src/main/java/net/minecraft/world/entity/TamableAnimal.java +index cd565d1a8dab8d45196e4d29cab3d93a3ca619eb..550c7f3435cc6c3180769e47f05bf693bdc380e3 100644 +--- a/src/main/java/net/minecraft/world/entity/TamableAnimal.java ++++ b/src/main/java/net/minecraft/world/entity/TamableAnimal.java +@@ -250,7 +250,12 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity { + if (entityliving instanceof ServerPlayer) { + ServerPlayer entityplayer = (ServerPlayer) entityliving; + +- entityplayer.sendSystemMessage(this.getCombatTracker().getDeathMessage()); ++ // Paper start - Add TameableDeathMessageEvent ++ io.papermc.paper.event.entity.TameableDeathMessageEvent event = new io.papermc.paper.event.entity.TameableDeathMessageEvent((org.bukkit.entity.Tameable) getBukkitEntity(), io.papermc.paper.adventure.PaperAdventure.asAdventure(this.getCombatTracker().getDeathMessage())); ++ if (event.callEvent()) { ++ entityplayer.sendSystemMessage(this.getCombatTracker().getDeathMessage()); ++ } ++ // Paper end - Add TameableDeathMessageEvent + } + } + } diff --git a/patches/unapplied/server/0683-Fix-new-block-data-for-EntityChangeBlockEvent.patch b/patches/server/0679-Fix-new-block-data-for-EntityChangeBlockEvent.patch similarity index 74% rename from patches/unapplied/server/0683-Fix-new-block-data-for-EntityChangeBlockEvent.patch rename to patches/server/0679-Fix-new-block-data-for-EntityChangeBlockEvent.patch index 6dae9bf4a8ef..93f56e515722 100644 --- a/patches/unapplied/server/0683-Fix-new-block-data-for-EntityChangeBlockEvent.patch +++ b/patches/server/0679-Fix-new-block-data-for-EntityChangeBlockEvent.patch @@ -27,10 +27,10 @@ index 6a7052cd6ec88ed4aaea2fef0ebc750060d1dec0..2ade08d1466660ee1787fa97908002ef } // CraftBukkit } diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java -index 4253b3b1263a7ae5a2f5f3a34674dfea615a81ea..784a894688f98f9d0368a36d456c5c94e1ee3695 100644 +index e2aa6d46375cbc4f4b694888c4f9750eb26e4940..6827426e6e9706909265f84bf97b5fa7105a7fea 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java -@@ -72,7 +72,7 @@ public class BreakDoorGoal extends DoorInteractGoal { +@@ -73,7 +73,7 @@ public class BreakDoorGoal extends DoorInteractGoal { if (this.breakTime == this.getDoorBreakTime() && this.isValidDifficulty(this.mob.level().getDifficulty())) { // CraftBukkit start @@ -40,7 +40,7 @@ index 4253b3b1263a7ae5a2f5f3a34674dfea615a81ea..784a894688f98f9d0368a36d456c5c94 return; } diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java -index f4bc556e245179d0a4710e5255dd289aaafdceb7..d802985f1431be4332c07f0dab88feebedea4ce2 100644 +index dc3602002e60d64cbbe9504c22282a9e65da2c9d..9e6f946e6d2878aa3fa8abe0f6fa4770d18676d3 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java @@ -67,8 +67,9 @@ public class EatBlockGoal extends Goal { @@ -48,10 +48,10 @@ index f4bc556e245179d0a4710e5255dd289aaafdceb7..d802985f1431be4332c07f0dab88feeb BlockPos blockposition = this.mob.blockPosition(); - if (EatBlockGoal.IS_TALL_GRASS.test(this.level.getBlockState(blockposition))) { -- if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition, Blocks.AIR.defaultBlockState(), !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit +- if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition, Blocks.AIR.defaultBlockState(), !getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit + final BlockState blockState = this.level.getBlockState(blockposition); // Paper - fix wrong block state + if (EatBlockGoal.IS_TALL_GRASS.test(blockState)) { // Paper - fix wrong block state -+ if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition, blockState.getFluidState().createLegacyBlock(), !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - fix wrong block state ++ if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition, blockState.getFluidState().createLegacyBlock(), !getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - fix wrong block state this.level.destroyBlock(blockposition, false); } @@ -59,16 +59,16 @@ index f4bc556e245179d0a4710e5255dd289aaafdceb7..d802985f1431be4332c07f0dab88feeb BlockPos blockposition1 = blockposition.below(); if (this.level.getBlockState(blockposition1).is(Blocks.GRASS_BLOCK)) { -- if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition1, Blocks.AIR.defaultBlockState(), !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit -+ if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition1, Blocks.DIRT.defaultBlockState(), !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - Fix wrong block state +- if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition1, Blocks.AIR.defaultBlockState(), !getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit ++ if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition1, Blocks.DIRT.defaultBlockState(), !getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - Fix wrong block state this.level.levelEvent(2001, blockposition1, Block.getId(Blocks.GRASS_BLOCK.defaultBlockState())); this.level.setBlock(blockposition1, Blocks.DIRT.defaultBlockState(), 2); } diff --git a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java -index e5bd3039ef698fcea80a270b6111c2a663e5075c..0109c8ed8bf6a053674456fa4473934e028ca418 100644 +index a2bbb79f2999e719b8c80d33e530391ec3d1d2d2..8cc6022507c97af62fb2b4455198bc35744137c9 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java +++ b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java -@@ -581,7 +581,7 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -580,7 +580,7 @@ public class Rabbit extends Animal implements VariantHolder { if (i == 0) { // CraftBukkit start @@ -78,10 +78,10 @@ index e5bd3039ef698fcea80a270b6111c2a663e5075c..0109c8ed8bf6a053674456fa4473934e } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java -index 3cd4a744c3e3aeba90f342de9dea67ef2f3de626..1b49090a466bc74d9e5f2815314955b6dfbb83dc 100644 +index b145023308e6a2823d83db97ff2d79c38b709ef9..e6b18d7f8922cb42acb9e40bef2f71a56aea8646 100644 --- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java +++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java -@@ -377,7 +377,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -375,7 +375,7 @@ public class WitherBoss extends Monster implements RangedAttackMob { if (WitherBoss.canDestroy(iblockdata)) { // CraftBukkit start @@ -91,10 +91,10 @@ index 3cd4a744c3e3aeba90f342de9dea67ef2f3de626..1b49090a466bc74d9e5f2815314955b6 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -index 7caa5469a4daa5d0c569f446ff2d597a9f10e8ac..828c51477cd8f35d591367b30bf4feef6a250292 100644 +index 0e8349aa6cb23860a4dd884e730ac8f22d422205..48dcd2bc12ce1d08cc5195bff5460dc0dd9902d3 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -@@ -565,7 +565,7 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -552,7 +552,7 @@ public class EnderMan extends Monster implements NeutralMob { boolean flag = movingobjectpositionblock.getBlockPos().equals(blockposition); if (iblockdata.is(BlockTags.ENDERMAN_HOLDABLE) && flag) { @@ -104,23 +104,23 @@ index 7caa5469a4daa5d0c569f446ff2d597a9f10e8ac..828c51477cd8f35d591367b30bf4feef world.gameEvent((Holder) GameEvent.BLOCK_DESTROY, blockposition, GameEvent.Context.of(this.enderman, iblockdata)); this.enderman.setCarriedBlock(iblockdata.getBlock().defaultBlockState()); diff --git a/src/main/java/net/minecraft/world/entity/monster/Ravager.java b/src/main/java/net/minecraft/world/entity/monster/Ravager.java -index aa4111eef22546f8aa630228c51ef5761c9b373b..212d341425c0f93bba0376de69bea61ffcf4dbd6 100644 +index c661ae4e5c07494c7de852cc8d01f0f9839c1590..c96fbfe448b3e7b722a8db0e1688276776abd94e 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Ravager.java +++ b/src/main/java/net/minecraft/world/entity/monster/Ravager.java -@@ -151,7 +151,7 @@ public class Ravager extends Raider { +@@ -165,7 +165,7 @@ public class Ravager extends Raider { - if (block instanceof LeavesBlock) { - // CraftBukkit start -- if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState())) { -+ if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state - continue; - } - // CraftBukkit end + if (block instanceof LeavesBlock) { + // CraftBukkit start +- if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState())) { ++ if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state + continue; + } + // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/monster/Silverfish.java b/src/main/java/net/minecraft/world/entity/monster/Silverfish.java -index 9ff42b0ae2b82dc3092e38e1439d89b4ab554b17..860e385fc83f9787dca92efe35d21fd69c4dd635 100644 +index 52d8ea3e40cdb01eab428f5d3d945c0c9f6088ce..1580c8b93a4ea1a9f2d7bf9c589ef64e070e3f53 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Silverfish.java +++ b/src/main/java/net/minecraft/world/entity/monster/Silverfish.java -@@ -162,7 +162,8 @@ public class Silverfish extends Monster { +@@ -165,7 +165,8 @@ public class Silverfish extends Monster { if (block instanceof InfestedBlock) { // CraftBukkit start @@ -131,10 +131,10 @@ index 9ff42b0ae2b82dc3092e38e1439d89b4ab554b17..860e385fc83f9787dca92efe35d21fd6 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java -index 58dc69fe319027c2b9ecfb9caf272368e81081df..5c6cb752f61c3f3c2960a337173fb7dfe86cc1d3 100644 +index a486466040a646b8a5a5ff2430cdd25b95b7e20f..e78eef3b6fbcd657f9dd180df4cb2eeb55d0814f 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java -@@ -292,7 +292,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie +@@ -294,7 +294,7 @@ public class ThrownPotion extends ThrowableItemProjectile { if (iblockdata.is(BlockTags.FIRE)) { // CraftBukkit start @@ -144,38 +144,38 @@ index 58dc69fe319027c2b9ecfb9caf272368e81081df..5c6cb752f61c3f3c2960a337173fb7df } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/level/block/ChorusFlowerBlock.java b/src/main/java/net/minecraft/world/level/block/ChorusFlowerBlock.java -index bb1487dd2c8e4374f75a102ab5e17ce9b2d31114..6709cb6b657a8612781c2fe4dd76ee38f329c5ba 100644 +index fae574f8617bada96469a2eb1349eaa061f0450f..6d0d13e70a82c4db7848e1007f5b6d670dd5acad 100644 --- a/src/main/java/net/minecraft/world/level/block/ChorusFlowerBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ChorusFlowerBlock.java -@@ -284,7 +284,7 @@ public class ChorusFlowerBlock extends Block { - - if (!world.isClientSide && projectile.mayInteract(world, blockposition) && projectile.mayBreak(world)) { - // CraftBukkit -- if (!CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, Blocks.AIR.defaultBlockState())) { -+ if (!CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, state.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state - return; - } - // CraftBukkit end +@@ -286,7 +286,7 @@ public class ChorusFlowerBlock extends Block { + if (world instanceof ServerLevel worldserver) { + if (projectile.mayInteract(worldserver, blockposition) && projectile.mayBreak(worldserver)) { + // CraftBukkit +- if (!CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, Blocks.AIR.defaultBlockState())) { ++ if (!CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, state.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state + return; + } + // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java -index ec9190abe3edf7c3845156bb967dddf6ae7c30ff..95cb7492ac691a8e8aa9894f701b802a7eda5446 100644 +index 48503f5ba8bccb42ae3b5324a5f65f6c23a8e479..bd38a0a73d543a85bb5c6d50219f5438ce194df3 100644 --- a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java -@@ -134,7 +134,7 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate +@@ -137,7 +137,7 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate - if (projectile.mayInteract(world, blockposition) && projectile.mayBreak(world) && projectile instanceof ThrownTrident && projectile.getDeltaMovement().length() > 0.6D) { - // CraftBukkit start -- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, Blocks.AIR.defaultBlockState())) { -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, state.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state - return; - } - // CraftBukkit end + if (projectile.mayInteract(worldserver, blockposition) && projectile.mayBreak(worldserver) && projectile instanceof ThrownTrident && projectile.getDeltaMovement().length() > 0.6D) { + // CraftBukkit start +- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, Blocks.AIR.defaultBlockState())) { ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, state.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state + return; + } + // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/level/block/TntBlock.java b/src/main/java/net/minecraft/world/level/block/TntBlock.java -index 4896ddca849646135ae101236e534ab8f59bd617..a3525ae6d83591664e1456f20d9732a8de0ec326 100644 +index d256b0f3998028709334dd6c394d184f2c36efce..2cbe2053dd5d0bcdcd89de69762c77b400b8697a 100644 --- a/src/main/java/net/minecraft/world/level/block/TntBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TntBlock.java @@ -158,7 +158,7 @@ public class TntBlock extends Block { - if (projectile.isOnFire() && projectile.mayInteract(world, blockposition)) { + if (projectile.isOnFire() && projectile.mayInteract(worldserver, blockposition)) { // CraftBukkit start - if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, Blocks.AIR.defaultBlockState()) || !CraftEventFactory.callTNTPrimeEvent(world, blockposition, PrimeCause.PROJECTILE, projectile, null)) { + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, state.getFluidState().createLegacyBlock()) || !CraftEventFactory.callTNTPrimeEvent(world, blockposition, PrimeCause.PROJECTILE, projectile, null)) { // Paper - fix wrong block state @@ -183,12 +183,12 @@ index 4896ddca849646135ae101236e534ab8f59bd617..a3525ae6d83591664e1456f20d9732a8 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java b/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java -index edc20745649b0837f1371c8d29e71fc0c8e5528f..932831bb5632ead5850842fc77192c841571162e 100644 +index 674d710ff88db5eced9e017284d1b7ec7a4fe7cd..72320c6099a4b26235bab68570e7b7efad84740f 100644 --- a/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java +++ b/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java @@ -37,7 +37,7 @@ public class WaterlilyBlock extends BushBlock { - if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (world instanceof ServerLevel && entity instanceof Boat) { + super.entityInside(state, world, pos, entity); + if (world instanceof ServerLevel && entity instanceof AbstractBoat) { // CraftBukkit start - if (!CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState())) { + if (!CraftEventFactory.callEntityChangeBlockEvent(entity, pos, state.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state @@ -196,10 +196,10 @@ index edc20745649b0837f1371c8d29e71fc0c8e5528f..932831bb5632ead5850842fc77192c84 } // CraftBukkit end diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index eeb326a115020f571e96f3ec85408950b5eb56fb..ba1599b733946bef468a9b006411f8827844e791 100644 +index 412f5e414745123535a275d5670b35fff5b1aaec..f7e26e381c2a2fec70cc2df01a12e7dbeeab48cd 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1380,11 +1380,11 @@ public class CraftEventFactory { +@@ -1378,11 +1378,11 @@ populateFields(victim, event); // Paper - make cancellable return event; } diff --git a/patches/unapplied/server/0684-fix-player-loottables-running-when-mob-loot-gamerule.patch b/patches/server/0680-fix-player-loottables-running-when-mob-loot-gamerule.patch similarity index 79% rename from patches/unapplied/server/0684-fix-player-loottables-running-when-mob-loot-gamerule.patch rename to patches/server/0680-fix-player-loottables-running-when-mob-loot-gamerule.patch index ad38317db74d..82df4acd2c11 100644 --- a/patches/unapplied/server/0684-fix-player-loottables-running-when-mob-loot-gamerule.patch +++ b/patches/server/0680-fix-player-loottables-running-when-mob-loot-gamerule.patch @@ -5,16 +5,16 @@ Subject: [PATCH] fix player loottables running when mob loot gamerule is false diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 25ca370c0b19eca529fc2c980c50e899013f0897..f31eb944465e9011d8aad398eb60bafb44203ad5 100644 +index f72ab5e4e743cb0758ebca28e81f97c143c91b42..84f4913c06bf9068a3a4d7400055031c474a4f7e 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -959,12 +959,14 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1218,12 +1218,14 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } } } + if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - fix player loottables running when mob loot gamerule is false // SPIGOT-5071: manually add player loot tables (SPIGOT-5195 - ignores keepInventory rule) - this.dropFromLootTable(damageSource, this.lastHurtByPlayerTime > 0); + this.dropFromLootTable(this.serverLevel(), damageSource, this.lastHurtByPlayerTime > 0); this.dropCustomDeathLoot(this.serverLevel(), damageSource, flag); loot.addAll(this.drops); diff --git a/patches/unapplied/server/0685-Ensure-entity-passenger-world-matches-ridden-entity.patch b/patches/server/0681-Ensure-entity-passenger-world-matches-ridden-entity.patch similarity index 85% rename from patches/unapplied/server/0685-Ensure-entity-passenger-world-matches-ridden-entity.patch rename to patches/server/0681-Ensure-entity-passenger-world-matches-ridden-entity.patch index ba6ce8567a41..941971cf97a6 100644 --- a/patches/unapplied/server/0685-Ensure-entity-passenger-world-matches-ridden-entity.patch +++ b/patches/server/0681-Ensure-entity-passenger-world-matches-ridden-entity.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Ensure entity passenger world matches ridden entity Bad plugins doing this would cause some obvious problems... diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 7d9ebc71b794d40246cbd43ff4de5795970e7ebe..3bb7e0f6a02b9b1726b8c878271d89a9c6d56c12 100644 +index a41bb1d80a84f487a8fb6fdefd7ccc7631902d04..325c8b178dfb39727107190e74663113ebb4ab54 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -2687,7 +2687,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2802,7 +2802,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public boolean startRiding(Entity entity, boolean force) { diff --git a/patches/unapplied/server/0686-Cache-resource-keys-and-optimize-reference-Holder-ta.patch b/patches/server/0682-Cache-resource-keys-and-optimize-reference-Holder-ta.patch similarity index 89% rename from patches/unapplied/server/0686-Cache-resource-keys-and-optimize-reference-Holder-ta.patch rename to patches/server/0682-Cache-resource-keys-and-optimize-reference-Holder-ta.patch index ddb3a70fde20..263f5852b348 100644 --- a/patches/unapplied/server/0686-Cache-resource-keys-and-optimize-reference-Holder-ta.patch +++ b/patches/server/0682-Cache-resource-keys-and-optimize-reference-Holder-ta.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Cache resource keys and optimize reference Holder tags set TagKeys are always interned, so we can use a reference hash set for them diff --git a/src/main/java/net/minecraft/core/Holder.java b/src/main/java/net/minecraft/core/Holder.java -index d7bbf60ba94ecd85f991a0c5c70c34fdb00ec9d5..4d2231868b786da9071c3dff2c073b478a486e8a 100644 +index 94671ea227b59a8f820425c401712e6aeb8b2b10..e91c4e26c25980645941ca8fbdcc3a9d02e31063 100644 --- a/src/main/java/net/minecraft/core/Holder.java +++ b/src/main/java/net/minecraft/core/Holder.java -@@ -221,7 +221,7 @@ public interface Holder { +@@ -230,7 +230,7 @@ public interface Holder { } void bindTags(Collection> tags) { @@ -47,10 +47,10 @@ index 95b956802f83b583a823fcd24808363775a56842..33d2e89ac40465b0c4633f9c51378b80 public static Holder bukkitToMinecraftHolder(Biome bukkit) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityType.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityType.java -index fd1aaf8e18d6e3425639b60ce21c5aaf36e0b42a..266b616419a47f518a43b990cc7cbb4516beda03 100644 +index 6cf8af0c85231de9955282d4abaa0607ec9a195c..d230cbc26f61d8ac5880825aca4dfab197c20401 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityType.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityType.java -@@ -24,11 +24,11 @@ public class CraftEntityType { +@@ -25,11 +25,11 @@ public class CraftEntityType { return bukkit; } @@ -63,4 +63,4 @@ index fd1aaf8e18d6e3425639b60ce21c5aaf36e0b42a..266b616419a47f518a43b990cc7cbb45 + .getOptional(KEY_CACHE.computeIfAbsent(bukkit, type -> net.minecraft.resources.ResourceKey.create(Registries.ENTITY_TYPE, CraftNamespacedKey.toMinecraft(type.getKey())))).orElseThrow(); } - public static String bukkitToString(EntityType bukkit) { + public static Holder> bukkitToMinecraftHolder(EntityType bukkit) { diff --git a/patches/unapplied/server/0687-Allow-changing-the-EnderDragon-podium.patch b/patches/server/0683-Allow-changing-the-EnderDragon-podium.patch similarity index 64% rename from patches/unapplied/server/0687-Allow-changing-the-EnderDragon-podium.patch rename to patches/server/0683-Allow-changing-the-EnderDragon-podium.patch index 4c615ac13206..0102f9445352 100644 --- a/patches/unapplied/server/0687-Allow-changing-the-EnderDragon-podium.patch +++ b/patches/server/0683-Allow-changing-the-EnderDragon-podium.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Allow changing the EnderDragon podium diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -index a2cde7b1b316e43382cb1639ffccf29d89f5ebfc..6306f7925ac4852d8eed7508a11764c636dd7d36 100644 +index 25d2226c2a5dda411a9e35f7a0e3ab183110c227..38456d3901e495e4c401cff0de7ae38544c1b2a7 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java @@ -104,6 +104,10 @@ public class EnderDragon extends Mob implements Enemy { @@ -19,7 +19,7 @@ index a2cde7b1b316e43382cb1639ffccf29d89f5ebfc..6306f7925ac4852d8eed7508a11764c6 public EnderDragon(EntityType entitytypes, Level world) { super(EntityType.ENDER_DRAGON, world); -@@ -144,6 +148,19 @@ public class EnderDragon extends Mob implements Enemy { +@@ -143,6 +147,19 @@ public class EnderDragon extends Mob implements Enemy { return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 200.0D); } @@ -39,16 +39,7 @@ index a2cde7b1b316e43382cb1639ffccf29d89f5ebfc..6306f7925ac4852d8eed7508a11764c6 @Override public boolean isFlapping() { float f = Mth.cos(this.flapTime * 6.2831855F); -@@ -1009,7 +1026,7 @@ public class EnderDragon extends Mob implements Enemy { - d0 = segment2[1] - segment1[1]; - } - } else { -- BlockPos blockposition = this.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.fightOrigin)); -+ BlockPos blockposition = this.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.getPodium()); // Paper - Allow changing the EnderDragon podium - double d1 = Math.max(Math.sqrt(blockposition.distToCenterSqr(this.position())) / 4.0D, 1.0D); - - d0 = (double) segmentOffset / d1; -@@ -1036,7 +1053,7 @@ public class EnderDragon extends Mob implements Enemy { +@@ -988,7 +1005,7 @@ public class EnderDragon extends Mob implements Enemy { vec3d = this.getViewVector(tickDelta); } } else { @@ -58,67 +49,67 @@ index a2cde7b1b316e43382cb1639ffccf29d89f5ebfc..6306f7925ac4852d8eed7508a11764c6 f1 = Math.max((float) Math.sqrt(blockposition.distToCenterSqr(this.position())) / 4.0F, 1.0F); float f3 = 6.0F / f1; diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonDeathPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonDeathPhase.java -index 803d227281d70606691eed95c4b10a27ca5d1125..5663f2ff1eba4a5e00c76c9d735cb553faae6a04 100644 +index a897c994423d7d624df6ff3a67789cc2436f0417..29f4acc2943ce009088c61bb32aed330f6e2c051 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonDeathPhase.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonDeathPhase.java -@@ -43,7 +43,7 @@ public class DragonDeathPhase extends AbstractDragonPhaseInstance { +@@ -42,7 +42,7 @@ public class DragonDeathPhase extends AbstractDragonPhaseInstance { + public void doServerTick(ServerLevel world) { + this.time++; if (this.targetLocation == null) { - BlockPos blockPos = this.dragon - .level() -- .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())); -+ .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium +- BlockPos blockPos = world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())); ++ BlockPos blockPos = world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium this.targetLocation = Vec3.atBottomCenterOf(blockPos); } diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java -index 707ef45ccd7fbcbe1947c8941846277f19ee54c9..ddf668205a7cb29b9018bf9eea49667b5fd2d471 100644 +index 2db996f3528c65f5d719cbcfb8ae587ff59c14c1..b8730a0fc759dbacc9b2e737c3e48d3ff9c5d824 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java -@@ -54,7 +54,7 @@ public class DragonHoldingPatternPhase extends AbstractDragonPhaseInstance { +@@ -53,7 +53,7 @@ public class DragonHoldingPatternPhase extends AbstractDragonPhaseInstance { + + private void findNewTarget(ServerLevel world) { if (this.currentPath != null && this.currentPath.isDone()) { - BlockPos blockPos = this.dragon - .level() -- .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, new BlockPos(EndPodiumFeature.getLocation(this.dragon.getFightOrigin()))); -+ .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, new BlockPos(this.dragon.getPodium())); // Paper - Allow changing the EnderDragon podium +- BlockPos blockPos = world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())); ++ BlockPos blockPos = world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, new BlockPos(this.dragon.getPodium())); // Paper - Allow changing the EnderDragon podium int i = this.dragon.getDragonFight() == null ? 0 : this.dragon.getDragonFight().getCrystalsAlive(); if (this.dragon.getRandom().nextInt(i + 3) == 0) { this.dragon.getPhaseManager().setPhase(EnderDragonPhase.LANDING_APPROACH); diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingApproachPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingApproachPhase.java -index e731d0f74692615ce5f42f690e36bd906a39c1dd..557de8a8e21e7f049b6acf27b4ec927ef5a9f9cb 100644 +index 4c28d3c3d601b5316d79c8474d106800abc8e95b..1c4250cc61b770707ad25c0e93caeacbcb0a80b0 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingApproachPhase.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingApproachPhase.java -@@ -53,7 +53,7 @@ public class DragonLandingApproachPhase extends AbstractDragonPhaseInstance { +@@ -52,7 +52,7 @@ public class DragonLandingApproachPhase extends AbstractDragonPhaseInstance { + private void findNewTarget(ServerLevel world) { + if (this.currentPath == null || this.currentPath.isDone()) { int i = this.dragon.findClosestNode(); - BlockPos blockPos = this.dragon - .level() -- .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())); -+ .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium - Player player = this.dragon - .level() - .getNearestPlayer(NEAR_EGG_TARGETING, this.dragon, (double)blockPos.getX(), (double)blockPos.getY(), (double)blockPos.getZ()); +- BlockPos blockPos = world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())); ++ BlockPos blockPos = world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium + Player player = world.getNearestPlayer(NEAR_EGG_TARGETING, this.dragon, (double)blockPos.getX(), (double)blockPos.getY(), (double)blockPos.getZ()); + int j; + if (player != null) { diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingPhase.java -index d913147d692e7e58bec4fac44c7e93a1822e8f65..3b960060f152d0352c2f8cdc1c71543cd7fa0dbd 100644 +index 789df0e05d0cf0df0f66bffc98f587a31770ebea..cfcd3f91517832d26c1177c3715cfa8ebe675193 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingPhase.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingPhase.java -@@ -41,7 +41,7 @@ public class DragonLandingPhase extends AbstractDragonPhaseInstance { - public void doServerTick() { +@@ -42,7 +42,7 @@ public class DragonLandingPhase extends AbstractDragonPhaseInstance { + public void doServerTick(ServerLevel world) { if (this.targetLocation == null) { this.targetLocation = Vec3.atBottomCenterOf( -- this.dragon.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())) -+ this.dragon.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()) // Paper - Allow changing the EnderDragon podium +- world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())) ++ world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()) // Paper - Allow changing the EnderDragon podium ); } diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonTakeoffPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonTakeoffPhase.java -index 8d66284eb96cfc0392c211842e87875a095c3ca2..718bf877179f85ee3f0de384ca3a8aaebaa067a5 100644 +index f942ea2ad87d4ae12921578f7b869f064c8db7b0..5c5b03f612621ec4efd92b78601032b84e6f3c28 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonTakeoffPhase.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonTakeoffPhase.java -@@ -25,7 +25,7 @@ public class DragonTakeoffPhase extends AbstractDragonPhaseInstance { +@@ -24,7 +24,7 @@ public class DragonTakeoffPhase extends AbstractDragonPhaseInstance { + @Override + public void doServerTick(ServerLevel world) { if (!this.firstTick && this.currentPath != null) { - BlockPos blockPos = this.dragon - .level() -- .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())); -+ .getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium +- BlockPos blockPos = world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())); ++ BlockPos blockPos = world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium if (!blockPos.closerToCenterThan(this.dragon.position(), 10.0)) { this.dragon.getPhaseManager().setPhase(EnderDragonPhase.HOLDING_PATTERN); } diff --git a/patches/unapplied/server/0688-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch b/patches/server/0684-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch similarity index 92% rename from patches/unapplied/server/0688-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch rename to patches/server/0684-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch index 265f2bbdbb06..f885dbe8b41b 100644 --- a/patches/unapplied/server/0688-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch +++ b/patches/server/0684-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch @@ -9,10 +9,10 @@ is not a WorldGenRegion, we can bypass the deadlock entirely. See https://bugs.mojang.com/browse/MC-246262 diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java -index 33564e62e3181d28b18a957e28b8ec5152d8339f..cf8258e8d46ca7286a66c38fa24af369bd9a279f 100644 +index b120949667ae0169a667b329b3cabbd79a0a5bda..734f511d197bc6bf2b02588069eb02c0224781f5 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java +++ b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java -@@ -279,7 +279,11 @@ public class StructureTemplate { +@@ -303,7 +303,11 @@ public class StructureTemplate { if (definedstructure_blockinfo.nbt != null) { tileentity = world.getBlockEntity(blockposition2); @@ -25,7 +25,7 @@ index 33564e62e3181d28b18a957e28b8ec5152d8339f..cf8258e8d46ca7286a66c38fa24af369 world.setBlock(blockposition2, Blocks.BARRIER.defaultBlockState(), 20); } // CraftBukkit start -@@ -406,7 +410,11 @@ public class StructureTemplate { +@@ -430,7 +434,11 @@ public class StructureTemplate { if (pair1.getSecond() != null) { tileentity = world.getBlockEntity(blockposition6); if (tileentity != null) { diff --git a/patches/unapplied/server/0689-Prevent-tile-entity-copies-loading-chunks.patch b/patches/server/0685-Prevent-tile-entity-copies-loading-chunks.patch similarity index 90% rename from patches/unapplied/server/0689-Prevent-tile-entity-copies-loading-chunks.patch rename to patches/server/0685-Prevent-tile-entity-copies-loading-chunks.patch index 50f78f59ad8f..cbd52db735ca 100644 --- a/patches/unapplied/server/0689-Prevent-tile-entity-copies-loading-chunks.patch +++ b/patches/server/0685-Prevent-tile-entity-copies-loading-chunks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent tile entity copies loading chunks diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 76c9feb5e1389eb929571de74ececd4a4f384453..7c1a94980cf49d37be442e1b62de36d4395bcf2a 100644 +index 33f76a6df7997ecdc789004bf0b230e74ad07f5a..ffd8e7a537fd8c6276674f5e0034412bb93ca82c 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3200,7 +3200,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3240,7 +3240,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl BlockPos blockposition = BlockEntity.getPosFromTag(customdata.getUnsafe()); if (this.player.level().isLoaded(blockposition)) { diff --git a/patches/unapplied/server/0690-Use-username-instead-of-display-name-in-PlayerList-g.patch b/patches/server/0686-Use-username-instead-of-display-name-in-PlayerList-g.patch similarity index 87% rename from patches/unapplied/server/0690-Use-username-instead-of-display-name-in-PlayerList-g.patch rename to patches/server/0686-Use-username-instead-of-display-name-in-PlayerList-g.patch index 951bce5a9bf1..d19203030936 100644 --- a/patches/unapplied/server/0690-Use-username-instead-of-display-name-in-PlayerList-g.patch +++ b/patches/server/0686-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 06bcc9974b4a63c174c51df332ff9ddd7eb6a159..0bded2c55d6c826e2f3dcb89995712c92348a3c7 100644 +index f65b583057d37ec64a7cd9ed3ec09448064576db..b36edfa81b504107c4225234e3a1d48984e1d241 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1394,7 +1394,7 @@ public abstract class PlayerList { +@@ -1354,7 +1354,7 @@ public abstract class PlayerList { // CraftBukkit start public ServerStatsCounter getPlayerStats(ServerPlayer entityhuman) { ServerStatsCounter serverstatisticmanager = entityhuman.getStats(); diff --git a/patches/server/0687-Expand-PlayerItemDamageEvent.patch b/patches/server/0687-Expand-PlayerItemDamageEvent.patch new file mode 100644 index 000000000000..7bcede06f42c --- /dev/null +++ b/patches/server/0687-Expand-PlayerItemDamageEvent.patch @@ -0,0 +1,23 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: HexedHero <6012891+HexedHero@users.noreply.github.com> +Date: Sun, 10 Apr 2022 06:26:32 +0100 +Subject: [PATCH] Expand PlayerItemDamageEvent + + +diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java +index 9289faebce6b1546af71aeadc6569d2595b486e0..fd49ff4ec22e4bdd3cd1aff0a6a2d2178d773bf2 100644 +--- a/src/main/java/net/minecraft/world/item/ItemStack.java ++++ b/src/main/java/net/minecraft/world/item/ItemStack.java +@@ -693,10 +693,11 @@ public final class ItemStack implements DataComponentHolder { + } + + public void hurtAndBreak(int amount, ServerLevel world, @Nullable LivingEntity player, Consumer breakCallback) { // Paper - Add EntityDamageItemEvent ++ int originalDamage = amount; // Paper - Expand PlayerItemDamageEvent + int j = this.processDurabilityChange(amount, world, player); + // CraftBukkit start + if (player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent +- PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), j); // Paper - Add EntityDamageItemEvent ++ PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), j, originalDamage); // Paper - Add EntityDamageItemEvent + event.getPlayer().getServer().getPluginManager().callEvent(event); + + if (j != event.getDamage() || event.isCancelled()) { diff --git a/patches/unapplied/server/0692-WorldCreator-keepSpawnLoaded.patch b/patches/server/0688-WorldCreator-keepSpawnLoaded.patch similarity index 87% rename from patches/unapplied/server/0692-WorldCreator-keepSpawnLoaded.patch rename to patches/server/0688-WorldCreator-keepSpawnLoaded.patch index 6369ed67aad2..0e11daefe3a8 100644 --- a/patches/unapplied/server/0692-WorldCreator-keepSpawnLoaded.patch +++ b/patches/server/0688-WorldCreator-keepSpawnLoaded.patch @@ -5,10 +5,10 @@ Subject: [PATCH] WorldCreator#keepSpawnLoaded diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 183d9672ad60e2b7db48c283b1ca863df01ad658..cfdfb81bc81382b71131c037ebd56f24573d4e34 100644 +index cc08b56da8a276202da3e85315fdb2ad530c2545..b31f3013ff63bb6ece80a9d10e51641a7e93f3df 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1326,7 +1326,7 @@ public final class CraftServer implements Server { +@@ -1329,7 +1329,7 @@ public final class CraftServer implements Server { } // If set to not keep spawn in memory (changed from default) then adjust rule accordingly diff --git a/patches/unapplied/server/0693-Fix-CME-in-CraftPersistentDataTypeRegistry.patch b/patches/server/0689-Fix-CME-in-CraftPersistentDataTypeRegistry.patch similarity index 100% rename from patches/unapplied/server/0693-Fix-CME-in-CraftPersistentDataTypeRegistry.patch rename to patches/server/0689-Fix-CME-in-CraftPersistentDataTypeRegistry.patch diff --git a/patches/unapplied/server/0682-Add-TameableDeathMessageEvent.patch b/patches/unapplied/server/0682-Add-TameableDeathMessageEvent.patch deleted file mode 100644 index 1531307bd4a7..000000000000 --- a/patches/unapplied/server/0682-Add-TameableDeathMessageEvent.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> -Date: Mon, 21 Jun 2021 21:24:45 -0400 -Subject: [PATCH] Add TameableDeathMessageEvent - - -diff --git a/src/main/java/net/minecraft/world/entity/TamableAnimal.java b/src/main/java/net/minecraft/world/entity/TamableAnimal.java -index 7b7bc1a205dfacbe5709011b6b6799e75af9e4cc..4c5b0b1a71ec5ba0e8dcd5ef52bf667e9bb30be9 100644 ---- a/src/main/java/net/minecraft/world/entity/TamableAnimal.java -+++ b/src/main/java/net/minecraft/world/entity/TamableAnimal.java -@@ -241,7 +241,12 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity { - @Override - public void die(DamageSource damageSource) { - if (!this.level().isClientSide && this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES) && this.getOwner() instanceof ServerPlayer) { -- this.getOwner().sendSystemMessage(this.getCombatTracker().getDeathMessage()); -+ // Paper start - Add TameableDeathMessageEvent -+ io.papermc.paper.event.entity.TameableDeathMessageEvent event = new io.papermc.paper.event.entity.TameableDeathMessageEvent((org.bukkit.entity.Tameable) getBukkitEntity(), io.papermc.paper.adventure.PaperAdventure.asAdventure(this.getCombatTracker().getDeathMessage())); -+ if (event.callEvent()) { -+ this.getOwner().sendSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.deathMessage())); -+ } -+ // Paper end - Add TameableDeathMessageEvent - } - - super.die(damageSource); diff --git a/patches/unapplied/server/0691-Expand-PlayerItemDamageEvent.patch b/patches/unapplied/server/0691-Expand-PlayerItemDamageEvent.patch deleted file mode 100644 index fac811b9d874..000000000000 --- a/patches/unapplied/server/0691-Expand-PlayerItemDamageEvent.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: HexedHero <6012891+HexedHero@users.noreply.github.com> -Date: Sun, 10 Apr 2022 06:26:32 +0100 -Subject: [PATCH] Expand PlayerItemDamageEvent - - -diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index ec3be7fb4eb4560fe0106ac127f17d7437612157..bee59df6a8f30416f94c1a4fbd5e2629336e842f 100644 ---- a/src/main/java/net/minecraft/world/item/ItemStack.java -+++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -650,10 +650,11 @@ public final class ItemStack implements DataComponentHolder { - if (this.isDamageableItem()) { - if (player == null || !player.hasInfiniteMaterials()) { - if (amount > 0) { -+ int originalDamage = amount; // Paper - Expand PlayerItemDamageEvent - amount = EnchantmentHelper.processDurabilityChange(world, this, amount); - // CraftBukkit start - if (player instanceof ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent -- PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount); // Paper - Add EntityDamageItemEvent -+ PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount, originalDamage); // Paper - Add EntityDamageItemEvent & Expand PlayerItemDamageEvent - event.getPlayer().getServer().getPluginManager().callEvent(event); - - if (amount != event.getDamage() || event.isCancelled()) { From 1dc142534d54bd1ae01060948bd1caad572a9724 Mon Sep 17 00:00:00 2001 From: Noah van der Aa Date: Wed, 23 Oct 2024 23:12:09 +0200 Subject: [PATCH 029/119] MOOOOORE --- ...elled-powdered-snow-bucket-placement.patch | 4 +-- ...666-Force-close-world-loading-screen.patch | 20 ++++++------- ...tead-of-display-name-in-PlayerList-g.patch | 2 +- .../0687-Expand-PlayerItemDamageEvent.patch | 2 +- ...destroyed-trigger-in-the-correct-pl.patch} | 10 +++---- ...Event-and-CollarColorable-interface.patch} | 8 ++--- ...CauldronLevelChange-on-initial-fill.patch} | 26 ++++++++-------- ...snow-cauldrons-not-turning-to-water.patch} | 30 +++++++++---------- .../0694-Add-PlayerStopUsingItemEvent.patch} | 4 +-- .../0695-Don-t-tick-markers.patch} | 4 +-- .../0696-Expand-FallingBlock-API.patch} | 22 +++++++------- ...0697-Add-support-for-Proxy-Protocol.patch} | 2 +- ...x-OfflinePlayer-getBedSpawnLocation.patch} | 0 ...tory-for-smokers-and-blast-furnaces.patch} | 0 .../0700-Sanitize-sent-BlockEntity-NBT.patch} | 4 +-- ...-selector-resolving-in-books-by-def.patch} | 4 +-- ...ntity-loading-causing-async-lookups.patch} | 10 +++---- ...-on-world-create-while-being-ticked.patch} | 26 ++++++++-------- ...04-Dont-resent-entity-on-art-update.patch} | 0 .../0705-Add-WardenAngerChangeEvent.patch} | 4 +-- ...strict-advancement-dimension-checks.patch} | 4 +-- ...tant-BlockStateListPopulator-method.patch} | 2 +- .../0708-Nameable-Banner-API.patch} | 2 +- ...roadcast-messages-to-command-blocks.patch} | 6 ++-- ...pty-items-from-being-added-to-world.patch} | 4 +-- ...hPotion-and-LingeringPotion-spawnin.patch} | 0 .../0712-Add-Player-getFishHook.patch} | 2 +- ...chunk-for-dynamic-game-event-listen.patch} | 0 ...s-missing-EntityDropItemEvent-calls.patch} | 22 +++++++------- patches/server/0715-Fix-Bee-flower-NPE.patch | 19 ++++++++++++ ...-not-using-commands.spam-exclusions.patch} | 10 +++---- .../0717-More-Teleport-API.patch} | 26 ++++++++-------- .../0718-Add-EntityPortalReadyEvent.patch} | 6 ++-- ...level-random-in-entity-constructors.patch} | 6 ++-- ...k-entities-after-destroy-prediction.patch} | 16 +++++----- ...on-plugins-accessing-faraway-chunks.patch} | 18 +++++------ ...tom-Chat-Completion-Suggestions-API.patch} | 4 +-- ...Add-and-fix-missing-BlockFadeEvents.patch} | 12 ++++---- .../0724-Collision-API.patch} | 6 ++-- ...nd-message-for-brigadier-syntax-exc.patch} | 4 +-- .../0726-Block-Ticking-API.patch} | 6 ++-- ...-Add-Velocity-IP-Forwarding-Support.patch} | 10 +++---- ...728-Add-NamespacedKey-biome-methods.patch} | 2 +- .../server/0719-Fix-Bee-flower-NPE.patch | 19 ------------ 44 files changed, 194 insertions(+), 194 deletions(-) rename patches/{unapplied/server/0694-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch => server/0690-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch} (89%) rename patches/{unapplied/server/0695-Add-EntityDyeEvent-and-CollarColorable-interface.patch => server/0691-Add-EntityDyeEvent-and-CollarColorable-interface.patch} (89%) rename patches/{unapplied/server/0696-Fire-CauldronLevelChange-on-initial-fill.patch => server/0692-Fire-CauldronLevelChange-on-initial-fill.patch} (89%) rename patches/{unapplied/server/0697-fix-powder-snow-cauldrons-not-turning-to-water.patch => server/0693-fix-powder-snow-cauldrons-not-turning-to-water.patch} (59%) rename patches/{unapplied/server/0698-Add-PlayerStopUsingItemEvent.patch => server/0694-Add-PlayerStopUsingItemEvent.patch} (85%) rename patches/{unapplied/server/0699-Don-t-tick-markers.patch => server/0695-Don-t-tick-markers.patch} (91%) rename patches/{unapplied/server/0700-Expand-FallingBlock-API.patch => server/0696-Expand-FallingBlock-API.patch} (80%) rename patches/{unapplied/server/0701-Add-support-for-Proxy-Protocol.patch => server/0697-Add-support-for-Proxy-Protocol.patch} (97%) rename patches/{unapplied/server/0702-Fix-OfflinePlayer-getBedSpawnLocation.patch => server/0698-Fix-OfflinePlayer-getBedSpawnLocation.patch} (100%) rename patches/{unapplied/server/0703-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch => server/0699-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch} (100%) rename patches/{unapplied/server/0704-Sanitize-sent-BlockEntity-NBT.patch => server/0700-Sanitize-sent-BlockEntity-NBT.patch} (95%) rename patches/{unapplied/server/0705-Disable-component-selector-resolving-in-books-by-def.patch => server/0701-Disable-component-selector-resolving-in-books-by-def.patch} (88%) rename patches/{unapplied/server/0706-Prevent-entity-loading-causing-async-lookups.patch => server/0702-Prevent-entity-loading-causing-async-lookups.patch} (90%) rename patches/{unapplied/server/0707-Throw-exception-on-world-create-while-being-ticked.patch => server/0703-Throw-exception-on-world-create-while-being-ticked.patch} (81%) rename patches/{unapplied/server/0708-Dont-resent-entity-on-art-update.patch => server/0704-Dont-resent-entity-on-art-update.patch} (100%) rename patches/{unapplied/server/0709-Add-WardenAngerChangeEvent.patch => server/0705-Add-WardenAngerChangeEvent.patch} (94%) rename patches/{unapplied/server/0710-Add-option-for-strict-advancement-dimension-checks.patch => server/0706-Add-option-for-strict-advancement-dimension-checks.patch} (94%) rename patches/{unapplied/server/0711-Add-missing-important-BlockStateListPopulator-method.patch => server/0707-Add-missing-important-BlockStateListPopulator-method.patch} (97%) rename patches/{unapplied/server/0712-Nameable-Banner-API.patch => server/0708-Nameable-Banner-API.patch} (96%) rename patches/{unapplied/server/0713-Don-t-broadcast-messages-to-command-blocks.patch => server/0709-Don-t-broadcast-messages-to-command-blocks.patch} (88%) rename patches/{unapplied/server/0714-Prevent-empty-items-from-being-added-to-world.patch => server/0710-Prevent-empty-items-from-being-added-to-world.patch} (87%) rename patches/{unapplied/server/0715-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch => server/0711-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch} (100%) rename patches/{unapplied/server/0716-Add-Player-getFishHook.patch => server/0712-Add-Player-getFishHook.patch} (92%) rename patches/{unapplied/server/0717-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch => server/0713-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch} (100%) rename patches/{unapplied/server/0718-Add-various-missing-EntityDropItemEvent-calls.patch => server/0714-Add-various-missing-EntityDropItemEvent-calls.patch} (86%) create mode 100644 patches/server/0715-Fix-Bee-flower-NPE.patch rename patches/{unapplied/server/0720-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch => server/0716-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch} (54%) rename patches/{unapplied/server/0721-More-Teleport-API.patch => server/0717-More-Teleport-API.patch} (93%) rename patches/{unapplied/server/0722-Add-EntityPortalReadyEvent.patch => server/0718-Add-EntityPortalReadyEvent.patch} (82%) rename patches/{unapplied/server/0723-Don-t-use-level-random-in-entity-constructors.patch => server/0719-Don-t-use-level-random-in-entity-constructors.patch} (90%) rename patches/{unapplied/server/0724-Send-block-entities-after-destroy-prediction.patch => server/0720-Send-block-entities-after-destroy-prediction.patch} (90%) rename patches/{unapplied/server/0725-Warn-on-plugins-accessing-faraway-chunks.patch => server/0721-Warn-on-plugins-accessing-faraway-chunks.patch} (88%) rename patches/{unapplied/server/0726-Custom-Chat-Completion-Suggestions-API.patch => server/0722-Custom-Chat-Completion-Suggestions-API.patch} (90%) rename patches/{unapplied/server/0727-Add-and-fix-missing-BlockFadeEvents.patch => server/0723-Add-and-fix-missing-BlockFadeEvents.patch} (89%) rename patches/{unapplied/server/0728-Collision-API.patch => server/0724-Collision-API.patch} (90%) rename patches/{unapplied/server/0729-Fix-suggest-command-message-for-brigadier-syntax-exc.patch => server/0725-Fix-suggest-command-message-for-brigadier-syntax-exc.patch} (89%) rename patches/{unapplied/server/0730-Block-Ticking-API.patch => server/0726-Block-Ticking-API.patch} (89%) rename patches/{unapplied/server/0731-Add-Velocity-IP-Forwarding-Support.patch => server/0727-Add-Velocity-IP-Forwarding-Support.patch} (97%) rename patches/{unapplied/server/0732-Add-NamespacedKey-biome-methods.patch => server/0728-Add-NamespacedKey-biome-methods.patch} (95%) delete mode 100644 patches/unapplied/server/0719-Fix-Bee-flower-NPE.patch diff --git a/patches/server/0656-Fix-cancelled-powdered-snow-bucket-placement.patch b/patches/server/0656-Fix-cancelled-powdered-snow-bucket-placement.patch index d43d65f169ba..d1a867e6051b 100644 --- a/patches/server/0656-Fix-cancelled-powdered-snow-bucket-placement.patch +++ b/patches/server/0656-Fix-cancelled-powdered-snow-bucket-placement.patch @@ -8,7 +8,7 @@ snow bucket didn't revert grass that became snowy because of the placement. diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 8c9ae9ac38def29ae4cd8944395e566e434d46d0..9289faebce6b1546af71aeadc6569d2595b486e0 100644 +index 8c9ae9ac38def29ae4cd8944395e566e434d46d0..a100c7a53b4b1dac0a01ee65418d44297bcdb93f 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java @@ -425,7 +425,7 @@ public final class ItemStack implements DataComponentHolder { @@ -25,7 +25,7 @@ index 8c9ae9ac38def29ae4cd8944395e566e434d46d0..9289faebce6b1546af71aeadc6569d25 if (blocks.size() > 1) { placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, enumhand, blocks, blockposition.getX(), blockposition.getY(), blockposition.getZ()); - } else if (blocks.size() == 1) { -+ } else if (blocks.size() == 1 && item != Items.POWDER_SNOW_BUCKET) { // Paper - Fix cancelled powdered snow bucket placement ++ } else if (blocks.size() == 1 && item != Items.POWDER_SNOW_BUCKET) { // Paper - Fix cancelled powdered snow bucket placement placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, enumhand, blocks.get(0), blockposition.getX(), blockposition.getY(), blockposition.getZ()); } diff --git a/patches/server/0666-Force-close-world-loading-screen.patch b/patches/server/0666-Force-close-world-loading-screen.patch index 647914a1ef5e..d29eaabc9055 100644 --- a/patches/server/0666-Force-close-world-loading-screen.patch +++ b/patches/server/0666-Force-close-world-loading-screen.patch @@ -10,23 +10,23 @@ 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 f34cad30c982f2bb563f0deab030111720858fa8..f65b583057d37ec64a7cd9ed3ec09448064576db 100644 +index f34cad30c982f2bb563f0deab030111720858fa8..f64a4693855899409a0ba7ec15ca0b0351febdd3 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -179,6 +179,16 @@ public abstract class PlayerList { - this.registries = registryManager; - this.maxPlayers = maxPlayers; - this.playerIo = saveHandler; +@@ -407,6 +407,16 @@ public abstract class PlayerList { + } + // Paper end - Configurable player collision + PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ()); + // Paper start - Send empty chunk, so players aren't stuck in the world loading screen with our chunk system not sending chunks when dead + if (player.isDeadOrDying()) { -+ net.minecraft.core.Holder plains = worldserver1.registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.BIOME) -+ .getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS); ++ net.minecraft.core.Holder plains = worldserver1.registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BIOME) ++ .getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS); + player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket( -+ new net.minecraft.world.level.chunk.EmptyLevelChunk(worldserver1, player.chunkPosition(), plains), -+ worldserver1.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null) ++ new net.minecraft.world.level.chunk.EmptyLevelChunk(worldserver1, player.chunkPosition(), plains), ++ worldserver1.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null) + ); + } + // Paper end - Send empty chunk } - abstract public void loadAndSaveFiles(); // Paper - fix converting txt to json file; moved from DedicatedPlayerList constructor + public void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) { diff --git a/patches/server/0686-Use-username-instead-of-display-name-in-PlayerList-g.patch b/patches/server/0686-Use-username-instead-of-display-name-in-PlayerList-g.patch index d19203030936..cf9ec6d9665e 100644 --- a/patches/server/0686-Use-username-instead-of-display-name-in-PlayerList-g.patch +++ b/patches/server/0686-Use-username-instead-of-display-name-in-PlayerList-g.patch @@ -6,7 +6,7 @@ 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 f65b583057d37ec64a7cd9ed3ec09448064576db..b36edfa81b504107c4225234e3a1d48984e1d241 100644 +index f64a4693855899409a0ba7ec15ca0b0351febdd3..f0ce0041497d038c55019e0f5a8e8b8619cec398 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -1354,7 +1354,7 @@ public abstract class PlayerList { diff --git a/patches/server/0687-Expand-PlayerItemDamageEvent.patch b/patches/server/0687-Expand-PlayerItemDamageEvent.patch index 7bcede06f42c..9659c386596a 100644 --- a/patches/server/0687-Expand-PlayerItemDamageEvent.patch +++ b/patches/server/0687-Expand-PlayerItemDamageEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Expand PlayerItemDamageEvent diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 9289faebce6b1546af71aeadc6569d2595b486e0..fd49ff4ec22e4bdd3cd1aff0a6a2d2178d773bf2 100644 +index a100c7a53b4b1dac0a01ee65418d44297bcdb93f..bcb3a45166e5dd75dd727adf92304b3a75399c8d 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java @@ -693,10 +693,11 @@ public final class ItemStack implements DataComponentHolder { diff --git a/patches/unapplied/server/0694-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch b/patches/server/0690-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch similarity index 89% rename from patches/unapplied/server/0694-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch rename to patches/server/0690-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch index ed6f34442741..3ba905932f5e 100644 --- a/patches/unapplied/server/0694-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch +++ b/patches/server/0690-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Trigger bee_nest_destroyed trigger in the correct place diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index 073cf184a0e7af41048ae67a9b17b4cdfcc43c35..4d024956156aefde7df308642dfd0a40779e0633 100644 +index e000a918230187f6841b03b7b0dd73687f3cc15e..5c3e5c348e6fececccd8097355f423b9e7ad982b 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -429,12 +429,16 @@ public class ServerPlayerGameMode { +@@ -427,12 +427,16 @@ public class ServerPlayerGameMode { block.destroy(this.level, pos, iblockdata1); } @@ -25,7 +25,7 @@ index 073cf184a0e7af41048ae67a9b17b4cdfcc43c35..4d024956156aefde7df308642dfd0a40 itemstack.mineBlock(this.level, iblockdata1, pos, this.player); if (flag && flag1 && event.isDropItems()) { // CraftBukkit - Check if block should drop items -@@ -455,6 +459,13 @@ public class ServerPlayerGameMode { +@@ -453,6 +457,13 @@ public class ServerPlayerGameMode { if (flag && event != null) { iblockdata.getBlock().popExperience(this.level, pos, event.getExpToDrop(), this.player); // Paper } @@ -40,10 +40,10 @@ index 073cf184a0e7af41048ae67a9b17b4cdfcc43c35..4d024956156aefde7df308642dfd0a40 return true; // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java -index 8d6736003934c5958f600660bdee58b386c39da4..c75227b2ea165dcd65c203e60157ac7cdebd4bc6 100644 +index a5b84e6844e16cf1fdfb6f45efb8a7a165757d1c..90f69a0c4d0707fd2319db71aea7dfdc14636d82 100644 --- a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java -@@ -95,7 +95,7 @@ public class BeehiveBlock extends BaseEntityBlock { +@@ -103,7 +103,7 @@ public class BeehiveBlock extends BaseEntityBlock { this.angerNearbyBees(world, pos); } diff --git a/patches/unapplied/server/0695-Add-EntityDyeEvent-and-CollarColorable-interface.patch b/patches/server/0691-Add-EntityDyeEvent-and-CollarColorable-interface.patch similarity index 89% rename from patches/unapplied/server/0695-Add-EntityDyeEvent-and-CollarColorable-interface.patch rename to patches/server/0691-Add-EntityDyeEvent-and-CollarColorable-interface.patch index b73fc3193a41..d50c55e4e37b 100644 --- a/patches/unapplied/server/0695-Add-EntityDyeEvent-and-CollarColorable-interface.patch +++ b/patches/server/0691-Add-EntityDyeEvent-and-CollarColorable-interface.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add EntityDyeEvent and CollarColorable interface diff --git a/src/main/java/net/minecraft/world/entity/animal/Cat.java b/src/main/java/net/minecraft/world/entity/animal/Cat.java -index d44807c16712afd37efdbf434d1afb12a7c3d343..2ed442c8d36f285420cf84a956e90b6036384ce0 100644 +index 5a86530c65d7d83e4608600a04ffd931bf59dc4a..bffc7c21727a6e5ff13a498aa51f6797e4d6d596 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Cat.java +++ b/src/main/java/net/minecraft/world/entity/animal/Cat.java -@@ -378,6 +378,13 @@ public class Cat extends TamableAnimal implements VariantHolder diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java -index 01ac7bb0ef8ab13e7c4b5b56b768b7c0a642b300..caf9273cfafbbaaf8dc95498927383e608773665 100644 +index 84d9ae7be1bc9b2c4940cc69de24abf7e4c228b3..c228ca3ee911d25932932564b73e182840963e7d 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -71,6 +71,7 @@ public class FallingBlockEntity extends Entity { @@ -24,16 +24,16 @@ index 01ac7bb0ef8ab13e7c4b5b56b768b7c0a642b300..caf9273cfafbbaaf8dc95498927383e6 public FallingBlockEntity(EntityType type, Level world) { super(type, world); -@@ -176,7 +177,7 @@ public class FallingBlockEntity extends Entity { - } +@@ -191,7 +192,7 @@ public class FallingBlockEntity extends Entity { + } - if (!this.onGround() && !flag1) { -- if (!this.level().isClientSide && (this.time > 100 && (blockposition.getY() <= this.level().getMinBuildHeight() || blockposition.getY() > this.level().getMaxBuildHeight()) || this.time > 600)) { -+ if (!this.level().isClientSide && ((this.time > 100 && autoExpire) && (blockposition.getY() <= this.level().getMinBuildHeight() || blockposition.getY() > this.level().getMaxBuildHeight()) || (this.time > 600 && autoExpire))) { // Paper - Expand FallingBlock API - if (this.dropItem && this.level().getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { - this.spawnAtLocation((ItemLike) block); - } -@@ -322,6 +323,7 @@ public class FallingBlockEntity extends Entity { + if (!this.onGround() && !flag1) { +- if (this.time > 100 && (blockposition.getY() <= this.level().getMinY() || blockposition.getY() > this.level().getMaxY()) || this.time > 600) { ++ if ((this.time > 100 && autoExpire) && (blockposition.getY() <= this.level().getMinY() || blockposition.getY() > this.level().getMaxY()) || (this.time > 600 && autoExpire)) { // Paper - Expand FallingBlock API + if (this.dropItem && worldserver.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { + this.spawnAtLocation(worldserver, (ItemLike) block); + } +@@ -338,6 +339,7 @@ public class FallingBlockEntity extends Entity { } nbt.putBoolean("CancelDrop", this.cancelDrop); @@ -41,7 +41,7 @@ index 01ac7bb0ef8ab13e7c4b5b56b768b7c0a642b300..caf9273cfafbbaaf8dc95498927383e6 } @Override -@@ -349,6 +351,11 @@ public class FallingBlockEntity extends Entity { +@@ -365,6 +367,11 @@ public class FallingBlockEntity extends Entity { this.blockState = Blocks.SAND.defaultBlockState(); } diff --git a/patches/unapplied/server/0701-Add-support-for-Proxy-Protocol.patch b/patches/server/0697-Add-support-for-Proxy-Protocol.patch similarity index 97% rename from patches/unapplied/server/0701-Add-support-for-Proxy-Protocol.patch rename to patches/server/0697-Add-support-for-Proxy-Protocol.patch index 8ad330c63d02..5d35c10858ca 100644 --- a/patches/unapplied/server/0701-Add-support-for-Proxy-Protocol.patch +++ b/patches/server/0697-Add-support-for-Proxy-Protocol.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add support for Proxy Protocol diff --git a/build.gradle.kts b/build.gradle.kts -index 6c3ed9e685473d7f555ae0e34fb9d4f3873f109a..ec9ae97b4a624bc208a778e63d0f0b86285167a6 100644 +index 38585b7f0b8e1e287b37820924a1b0d464fe9e99..25001d6cf4f70bd01ab304625b49ec45f5b1f525 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -28,6 +28,7 @@ dependencies { diff --git a/patches/unapplied/server/0702-Fix-OfflinePlayer-getBedSpawnLocation.patch b/patches/server/0698-Fix-OfflinePlayer-getBedSpawnLocation.patch similarity index 100% rename from patches/unapplied/server/0702-Fix-OfflinePlayer-getBedSpawnLocation.patch rename to patches/server/0698-Fix-OfflinePlayer-getBedSpawnLocation.patch diff --git a/patches/unapplied/server/0703-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch b/patches/server/0699-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch similarity index 100% rename from patches/unapplied/server/0703-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch rename to patches/server/0699-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch diff --git a/patches/unapplied/server/0704-Sanitize-sent-BlockEntity-NBT.patch b/patches/server/0700-Sanitize-sent-BlockEntity-NBT.patch similarity index 95% rename from patches/unapplied/server/0704-Sanitize-sent-BlockEntity-NBT.patch rename to patches/server/0700-Sanitize-sent-BlockEntity-NBT.patch index 152674ac0661..e9d1e188af5f 100644 --- a/patches/unapplied/server/0704-Sanitize-sent-BlockEntity-NBT.patch +++ b/patches/server/0700-Sanitize-sent-BlockEntity-NBT.patch @@ -30,10 +30,10 @@ index ac900dfdc5c90e9e60d47efa734be8f0a5b20dca..ec1cb034d840633240f2b379b09f7d2f } } diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index cbb777f499a4e8a447153c04d09c0c71321c663c..41f43d7d12a47563360f48a793e63db8cf92ac69 100644 +index 3de01d92e1c97e287a1f0d1f8de81b4f530b4a84..63e234fb72952dcede4eeaa5d3d3390d137d88a2 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -394,6 +394,14 @@ public abstract class BlockEntity { +@@ -395,6 +395,14 @@ public abstract class BlockEntity { } // CraftBukkit end diff --git a/patches/unapplied/server/0705-Disable-component-selector-resolving-in-books-by-def.patch b/patches/server/0701-Disable-component-selector-resolving-in-books-by-def.patch similarity index 88% rename from patches/unapplied/server/0705-Disable-component-selector-resolving-in-books-by-def.patch rename to patches/server/0701-Disable-component-selector-resolving-in-books-by-def.patch index 796fcc7f2a84..7231198032aa 100644 --- a/patches/unapplied/server/0705-Disable-component-selector-resolving-in-books-by-def.patch +++ b/patches/server/0701-Disable-component-selector-resolving-in-books-by-def.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Disable component selector resolving in books by default diff --git a/src/main/java/net/minecraft/world/item/WrittenBookItem.java b/src/main/java/net/minecraft/world/item/WrittenBookItem.java -index 46383a9f8bd1075ea56847f5fd8437df0a5d4941..0a5182c52fe2fef05dabbeb5ed13487f9175efbe 100644 +index a282c1cbbdf8e5ebac547b45a58116f9b4b2d49e..0c54100fb72b79e0eb4bad8f6851648e084d9260 100644 --- a/src/main/java/net/minecraft/world/item/WrittenBookItem.java +++ b/src/main/java/net/minecraft/world/item/WrittenBookItem.java -@@ -54,7 +54,7 @@ public class WrittenBookItem extends Item { +@@ -41,7 +41,7 @@ public class WrittenBookItem extends Item { public static boolean resolveBookComponents(ItemStack book, CommandSourceStack commandSource, @Nullable Player player) { WrittenBookContent writtenBookContent = book.get(DataComponents.WRITTEN_BOOK_CONTENT); diff --git a/patches/unapplied/server/0706-Prevent-entity-loading-causing-async-lookups.patch b/patches/server/0702-Prevent-entity-loading-causing-async-lookups.patch similarity index 90% rename from patches/unapplied/server/0706-Prevent-entity-loading-causing-async-lookups.patch rename to patches/server/0702-Prevent-entity-loading-causing-async-lookups.patch index 52647af7c4fa..342f805e0345 100644 --- a/patches/unapplied/server/0706-Prevent-entity-loading-causing-async-lookups.patch +++ b/patches/server/0702-Prevent-entity-loading-causing-async-lookups.patch @@ -5,19 +5,19 @@ Subject: [PATCH] Prevent entity loading causing async lookups diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 3bb7e0f6a02b9b1726b8c878271d89a9c6d56c12..de483cc77931fcb1d8bb9b1bcfd6606706490fba 100644 +index 325c8b178dfb39727107190e74663113ebb4ab54..71efd269ea055f13e3ca898bad045448e24f73da 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -714,6 +714,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -724,6 +724,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + ProfilerFiller gameprofilerfiller = Profiler.get(); - public void baseTick() { - this.level().getProfiler().push("entityBaseTick"); + gameprofilerfiller.push("entityBaseTick"); + if (firstTick && this instanceof net.minecraft.world.entity.NeutralMob neutralMob) neutralMob.tickInitialPersistentAnger(level); // Paper - Prevent entity loading causing async lookups this.inBlockState = null; if (this.isPassenger() && this.getVehicle().isRemoved()) { this.stopRiding(); diff --git a/src/main/java/net/minecraft/world/entity/NeutralMob.java b/src/main/java/net/minecraft/world/entity/NeutralMob.java -index 3b08905ddc3c2506779ce0eac1a53a4d89442ddc..b55633bf4e26dc00e27ab28c7739c274e48b74c3 100644 +index bf577b06707ff197f13f0b5e16620c09d4a69fa8..053d947c4cc00096dae422df36fb8351b3266215 100644 --- a/src/main/java/net/minecraft/world/entity/NeutralMob.java +++ b/src/main/java/net/minecraft/world/entity/NeutralMob.java @@ -45,24 +45,11 @@ public interface NeutralMob { diff --git a/patches/unapplied/server/0707-Throw-exception-on-world-create-while-being-ticked.patch b/patches/server/0703-Throw-exception-on-world-create-while-being-ticked.patch similarity index 81% rename from patches/unapplied/server/0707-Throw-exception-on-world-create-while-being-ticked.patch rename to patches/server/0703-Throw-exception-on-world-create-while-being-ticked.patch index 8d6f8d9e1def..1661a4705fc7 100644 --- a/patches/unapplied/server/0707-Throw-exception-on-world-create-while-being-ticked.patch +++ b/patches/server/0703-Throw-exception-on-world-create-while-being-ticked.patch @@ -7,10 +7,10 @@ There are no plans to support creating worlds while worlds are being ticked themselvess. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 94aa901b77b19445a33d5b2b24ba2e947d2a6aef..11b9eb8d7d5f9ad736f2c6784c5d9e745a355093 100644 +index 0b9f4541cc0d0f27e811c1a6798d6758a2687b0c..2101c0a3b000a60733ceada248c202e2c4783af5 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -317,6 +317,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); -@@ -1580,7 +1581,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent -@@ -1647,6 +1650,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop(this.worlds.values()); } @@ -60,7 +60,7 @@ index cfdfb81bc81382b71131c037ebd56f24573d4e34..8f8674ccee58f1910ffc3926d4291304 public DedicatedPlayerList getHandle() { return this.playerList; } -@@ -1180,6 +1185,7 @@ public final class CraftServer implements Server { +@@ -1183,6 +1188,7 @@ public final class CraftServer implements Server { @Override public World createWorld(WorldCreator creator) { Preconditions.checkState(this.console.getAllLevels().iterator().hasNext(), "Cannot create additional worlds on STARTUP"); @@ -68,7 +68,7 @@ index cfdfb81bc81382b71131c037ebd56f24573d4e34..8f8674ccee58f1910ffc3926d4291304 Preconditions.checkArgument(creator != null, "WorldCreator cannot be null"); String name = creator.name(); -@@ -1356,6 +1362,7 @@ public final class CraftServer implements Server { +@@ -1359,6 +1365,7 @@ public final class CraftServer implements Server { @Override public boolean unloadWorld(World world, boolean save) { diff --git a/patches/unapplied/server/0708-Dont-resent-entity-on-art-update.patch b/patches/server/0704-Dont-resent-entity-on-art-update.patch similarity index 100% rename from patches/unapplied/server/0708-Dont-resent-entity-on-art-update.patch rename to patches/server/0704-Dont-resent-entity-on-art-update.patch diff --git a/patches/unapplied/server/0709-Add-WardenAngerChangeEvent.patch b/patches/server/0705-Add-WardenAngerChangeEvent.patch similarity index 94% rename from patches/unapplied/server/0709-Add-WardenAngerChangeEvent.patch rename to patches/server/0705-Add-WardenAngerChangeEvent.patch index 41f4251548ef..ca2817ab51ee 100644 --- a/patches/unapplied/server/0709-Add-WardenAngerChangeEvent.patch +++ b/patches/server/0705-Add-WardenAngerChangeEvent.patch @@ -18,10 +18,10 @@ index 27e52ee93ab591e97f37705de64cb5b62c06e253..3d792957f27fd4bdfad8d76262a8e2a2 int j = this.angerByUuid.removeInt(entity.getUUID()); i += j; diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java -index aaa4b5d90e23b09f87847aa52c36548c94ddf548..38bf417a9ad4647f4af24d969f3bf4fed9c4bad7 100644 +index 71311d30459d495c57e6fcf0115e4f34a232f1ad..6180019da58b19d2595da508aed3196af922d587 100644 --- a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java +++ b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java -@@ -479,6 +479,15 @@ public class Warden extends Monster implements VibrationSystem { +@@ -482,6 +482,15 @@ public class Warden extends Monster implements VibrationSystem { @VisibleForTesting public void increaseAngerAt(@Nullable Entity entity, int amount, boolean listening) { if (!this.isNoAi() && this.canTargetEntity(entity)) { diff --git a/patches/unapplied/server/0710-Add-option-for-strict-advancement-dimension-checks.patch b/patches/server/0706-Add-option-for-strict-advancement-dimension-checks.patch similarity index 94% rename from patches/unapplied/server/0710-Add-option-for-strict-advancement-dimension-checks.patch rename to patches/server/0706-Add-option-for-strict-advancement-dimension-checks.patch index 488f84c88426..142cd3de1f80 100644 --- a/patches/unapplied/server/0710-Add-option-for-strict-advancement-dimension-checks.patch +++ b/patches/server/0706-Add-option-for-strict-advancement-dimension-checks.patch @@ -24,10 +24,10 @@ index 01b8f7024fbc965bc6a7f97f79ba3dec964ef769..801823d003a8e28a13fe90db4604cd09 } else { BlockPos blockPos = BlockPos.containing(x, y, z); diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index f31eb944465e9011d8aad398eb60bafb44203ad5..ad3896dd524acb573adffdfb38b13dd699539cef 100644 +index 84f4913c06bf9068a3a4d7400055031c474a4f7e..f87f12666d4708b7fb7ede3eff03570fed8d1f40 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1387,6 +1387,12 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1655,6 +1655,12 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { ResourceKey maindimensionkey = CraftDimensionUtil.getMainDimensionKey(origin); ResourceKey maindimensionkey1 = CraftDimensionUtil.getMainDimensionKey(this.level()); diff --git a/patches/unapplied/server/0711-Add-missing-important-BlockStateListPopulator-method.patch b/patches/server/0707-Add-missing-important-BlockStateListPopulator-method.patch similarity index 97% rename from patches/unapplied/server/0711-Add-missing-important-BlockStateListPopulator-method.patch rename to patches/server/0707-Add-missing-important-BlockStateListPopulator-method.patch index ecf565ebf68a..e0b94dc4ac0d 100644 --- a/patches/unapplied/server/0711-Add-missing-important-BlockStateListPopulator-method.patch +++ b/patches/server/0707-Add-missing-important-BlockStateListPopulator-method.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add missing important BlockStateListPopulator methods Without these methods it causes exceptions due to these being used by certain feature generators. diff --git a/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java b/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java -index ffe6881d93153838cd23f125980b832e6fd1d0eb..f5cbe9ae5802fa48e57092b1e5ca8a5f5f69ee60 100644 +index 072d105f05f3b535d53cfbf8538d1716f9cfcd0e..4d6d637188ef4010a71ea2eb6ea0310aea820511 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java +++ b/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java @@ -129,7 +129,7 @@ public class BlockStateListPopulator extends DummyGeneratorAccess { diff --git a/patches/unapplied/server/0712-Nameable-Banner-API.patch b/patches/server/0708-Nameable-Banner-API.patch similarity index 96% rename from patches/unapplied/server/0712-Nameable-Banner-API.patch rename to patches/server/0708-Nameable-Banner-API.patch index da3d804d8f27..aab360dbed11 100644 --- a/patches/unapplied/server/0712-Nameable-Banner-API.patch +++ b/patches/server/0708-Nameable-Banner-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Nameable Banner API diff --git a/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java -index 925608bfa9c848ed6285de5e35d60aa66e12004a..60c26076e7acf869fa0e20fdc14eeec341387d99 100644 +index 01521f38871d821762ff7ac2d39927f8c6b861bf..98bc87fe5d153cc4927f7e1b4a02f61d9dd019a0 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java @@ -29,7 +29,7 @@ public class BannerBlockEntity extends BlockEntity implements Nameable { diff --git a/patches/unapplied/server/0713-Don-t-broadcast-messages-to-command-blocks.patch b/patches/server/0709-Don-t-broadcast-messages-to-command-blocks.patch similarity index 88% rename from patches/unapplied/server/0713-Don-t-broadcast-messages-to-command-blocks.patch rename to patches/server/0709-Don-t-broadcast-messages-to-command-blocks.patch index 6c746cf029f7..e00b26503811 100644 --- a/patches/unapplied/server/0713-Don-t-broadcast-messages-to-command-blocks.patch +++ b/patches/server/0709-Don-t-broadcast-messages-to-command-blocks.patch @@ -8,7 +8,7 @@ in command blocks, and if called asynchronously, would throw an error diff --git a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java -index 8c2dcc4134d96351cee75773214f3f47e71533e9..e6bfcc50cdf728216084bc00a5bb8b6b3b8f72e4 100644 +index a0e59b236dff1f861a0e987764a77ee203504412..5cb39f95bd2d45b6c18554605f01d2ebf6473428 100644 --- a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java +++ b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java @@ -178,6 +178,7 @@ public abstract class BaseCommandBlock implements CommandSource { @@ -20,10 +20,10 @@ index 8c2dcc4134d96351cee75773214f3f47e71533e9..e6bfcc50cdf728216084bc00a5bb8b6b Date date = new Date(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 8f8674ccee58f1910ffc3926d42913048da1810e..3c5d44499e94bd19e4058eb2bf2d9b5d5890f980 100644 +index 9921c1e03a9e4eb2153fd88d2932f7f4867e0a03..284ffa47223595b42d115533551821f379de6663 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1925,7 +1925,7 @@ public final class CraftServer implements Server { +@@ -1929,7 +1929,7 @@ public final class CraftServer implements Server { // Paper end Set recipients = new HashSet<>(); for (Permissible permissible : this.getPluginManager().getPermissionSubscriptions(permission)) { diff --git a/patches/unapplied/server/0714-Prevent-empty-items-from-being-added-to-world.patch b/patches/server/0710-Prevent-empty-items-from-being-added-to-world.patch similarity index 87% rename from patches/unapplied/server/0714-Prevent-empty-items-from-being-added-to-world.patch rename to patches/server/0710-Prevent-empty-items-from-being-added-to-world.patch index 53f557979168..ce2a1d53592f 100644 --- a/patches/unapplied/server/0714-Prevent-empty-items-from-being-added-to-world.patch +++ b/patches/server/0710-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 492e8a2ff5618c45bfffa3284f03be14ff162ce8..b88a7f580b4138ceb262f3d398e78fdc2e6b018c 100644 +index d226b51933d25f9a31f285d7715d162302835b02..100661b77466152a651d22daa7df992c28fbbecb 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1235,6 +1235,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1230,6 +1230,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // 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/unapplied/server/0715-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch b/patches/server/0711-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch similarity index 100% rename from patches/unapplied/server/0715-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch rename to patches/server/0711-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch diff --git a/patches/unapplied/server/0716-Add-Player-getFishHook.patch b/patches/server/0712-Add-Player-getFishHook.patch similarity index 92% rename from patches/unapplied/server/0716-Add-Player-getFishHook.patch rename to patches/server/0712-Add-Player-getFishHook.patch index 99c85d33b3ac..b2f8e7f0eb41 100644 --- a/patches/unapplied/server/0716-Add-Player-getFishHook.patch +++ b/patches/server/0712-Add-Player-getFishHook.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add Player#getFishHook diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index 0222b6c68112551336f17a722fc3399898cdc7bb..049db909fbd8610ebb688d948f5d03c97ab23495 100644 +index 1e49eae80730aa9d2e49cd92759d899deb49fb90..df9d02eb1ffc3cc669e835e2c08d951283871db3 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -160,6 +160,15 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { diff --git a/patches/unapplied/server/0717-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch b/patches/server/0713-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch similarity index 100% rename from patches/unapplied/server/0717-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch rename to patches/server/0713-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch diff --git a/patches/unapplied/server/0718-Add-various-missing-EntityDropItemEvent-calls.patch b/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch similarity index 86% rename from patches/unapplied/server/0718-Add-various-missing-EntityDropItemEvent-calls.patch rename to patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch index 2f42aa11cb2e..a2575070b946 100644 --- a/patches/unapplied/server/0718-Add-various-missing-EntityDropItemEvent-calls.patch +++ b/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add various missing EntityDropItemEvent calls diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 8b0959050cd5e0ef24347632c3b4184eadf565e6..73a69c35bca89ab82da39149a2a7cb86d4878e3c 100644 +index 71efd269ea055f13e3ca898bad045448e24f73da..44f585b9dc9e3940193f07a2df1205907b4800ba 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -2557,6 +2557,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2672,6 +2672,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe entityitem.setDefaultPickUpDelay(); @@ -24,10 +24,10 @@ index 8b0959050cd5e0ef24347632c3b4184eadf565e6..73a69c35bca89ab82da39149a2a7cb86 EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity()); Bukkit.getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java -index 08823651b0a81b15bc33f86c96d6cc1dc72770f4..da45cc62985f8b67cdfeffc21cb33837db673555 100644 +index 33170f2f1d3f030fbf342e44a1baa109a34c31a7..b99e5878b3094ba25084b756c058510bc39f941a 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java +++ b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java -@@ -576,7 +576,7 @@ public class Dolphin extends WaterAnimal { +@@ -604,7 +604,7 @@ public class Dolphin extends AgeableWaterCreature { float f2 = 0.02F * Dolphin.this.random.nextFloat(); entityitem.setDeltaMovement((double) (0.3F * -Mth.sin(Dolphin.this.getYRot() * 0.017453292F) * Mth.cos(Dolphin.this.getXRot() * 0.017453292F) + Mth.cos(f1) * f2), (double) (0.3F * Mth.sin(Dolphin.this.getXRot() * 0.017453292F) * 1.5F), (double) (0.3F * Mth.cos(Dolphin.this.getYRot() * 0.017453292F) * Mth.cos(Dolphin.this.getXRot() * 0.017453292F) + Mth.sin(f1) * f2)); @@ -37,10 +37,10 @@ index 08823651b0a81b15bc33f86c96d6cc1dc72770f4..da45cc62985f8b67cdfeffc21cb33837 } } diff --git a/src/main/java/net/minecraft/world/entity/animal/Fox.java b/src/main/java/net/minecraft/world/entity/animal/Fox.java -index e46c8231ee318eda0512afbb6343b426b4838643..3265b3b5aede517b6fd8bb836947795bf8881350 100644 +index 205aefd38a185fa411ff17cfb0155769de8fc2fd..ca45a8ccf7f4593d557d157470603e4d233d948d 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Fox.java +++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java -@@ -507,14 +507,14 @@ public class Fox extends Animal implements VariantHolder { +@@ -492,14 +492,14 @@ public class Fox extends Animal implements VariantHolder { entityitem.setPickUpDelay(40); entityitem.setThrower(this); this.playSound(SoundEvents.FOX_SPIT, 1.0F, 1.0F); @@ -58,10 +58,10 @@ index e46c8231ee318eda0512afbb6343b426b4838643..3265b3b5aede517b6fd8bb836947795b @Override diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java -index 3b2cf9ca8447321d64ffdb4fdb9569d736d63dbb..923806900ef6248576e71260d40e9caf2c8943e8 100644 +index 14e02f9b0169db8388c515a68315ad5cc3f13d22..dbcf14f5af9c9c0655a82529ee99450a8da14525 100644 --- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java +++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java -@@ -361,8 +361,7 @@ public class Goat extends Animal { +@@ -365,8 +365,7 @@ public class Goat extends Animal { double d2 = (double) Mth.randomBetween(this.random, -0.2F, 0.2F); ItemEntity entityitem = new ItemEntity(this.level(), vec3d.x(), vec3d.y(), vec3d.z(), itemstack, d0, d1, d2); @@ -72,10 +72,10 @@ index 3b2cf9ca8447321d64ffdb4fdb9569d736d63dbb..923806900ef6248576e71260d40e9caf } diff --git a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java -index 94df94f7acc121201966955a09fb336b0a98e599..d34d8fe70379dcad9540739ec0ae1c94f01fc46b 100644 +index 5e586f174ff4b610a2584f28c9ffdd445ad58bea..0395b120590552518a85f36a46b68532e936de49 100644 --- a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java +++ b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java -@@ -350,8 +350,9 @@ public class Sniffer extends Animal { +@@ -345,8 +345,9 @@ public class Sniffer extends Animal { entityitem.setDefaultPickUpDelay(); this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob) null); @@ -87,7 +87,7 @@ index 94df94f7acc121201966955a09fb336b0a98e599..d34d8fe70379dcad9540739ec0ae1c94 @Override diff --git a/src/main/java/net/minecraft/world/item/ItemUtils.java b/src/main/java/net/minecraft/world/item/ItemUtils.java -index 66f88f44eb74dfbdafe0d6257dc1ef46238aaa92..4901f0d89ae2472bce7f242d9529236674f5d134 100644 +index f4fc17e029407be5df3cfe2dcb6fb2f88234b066..0c4074ed8b4fd9d6fcb838e8843d66f6f286ed5d 100644 --- a/src/main/java/net/minecraft/world/item/ItemUtils.java +++ b/src/main/java/net/minecraft/world/item/ItemUtils.java @@ -41,7 +41,15 @@ public class ItemUtils { diff --git a/patches/server/0715-Fix-Bee-flower-NPE.patch b/patches/server/0715-Fix-Bee-flower-NPE.patch new file mode 100644 index 000000000000..6ac238b67a6c --- /dev/null +++ b/patches/server/0715-Fix-Bee-flower-NPE.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Wed, 6 Jul 2022 14:59:38 -0700 +Subject: [PATCH] Fix Bee flower NPE + + +diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java +index 63e068c1a2d98c9c07dbabd1fa574d6b44e1a2fb..3f775aeed0afb5c4f19cbb17bf7bd9f7cfdc3adb 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/Bee.java ++++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java +@@ -940,7 +940,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { + Bee.this.dropFlower(); + this.pollinating = false; + Bee.this.remainingCooldownBeforeLocatingNewFlower = 200; +- } else { ++ } else if (Bee.this.savedFlowerPos != null) { // Paper - add null check since API can manipulate this + Vec3 vec3d = Vec3.atBottomCenterOf(Bee.this.savedFlowerPos).add(0.0D, 0.6000000238418579D, 0.0D); + + if (vec3d.distanceTo(Bee.this.position()) > 1.0D) { diff --git a/patches/unapplied/server/0720-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch b/patches/server/0716-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch similarity index 54% rename from patches/unapplied/server/0720-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch rename to patches/server/0716-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch index 67b7b9467ec4..710573f4a20e 100644 --- a/patches/unapplied/server/0720-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch +++ b/patches/server/0716-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Fix Spigot Config not using commands.spam-exclusions diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 7c1a94980cf49d37be442e1b62de36d4395bcf2a..4fa49daf58723827366f611e006e77448cc73a0b 100644 +index ffd8e7a537fd8c6276674f5e0034412bb93ca82c..84132f9642f51e1774d6c242330deebc6dfa163a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2383,7 +2383,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2394,7 +2394,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // Spigot end - // this.chatSpamTickCount += 20; -- if (this.chatSpamTickCount.addAndGet(20) > 200 && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { -+ if (counted && this.chatSpamTickCount.addAndGet(20) > 200 && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - exclude from SpigotConfig.spamExclusions + // this.chatSpamThrottler.increment(); +- if (!this.chatSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { ++ if (counted && !this.chatSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - exclude from SpigotConfig.spamExclusions // CraftBukkit end this.disconnect((Component) Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause } diff --git a/patches/unapplied/server/0721-More-Teleport-API.patch b/patches/server/0717-More-Teleport-API.patch similarity index 93% rename from patches/unapplied/server/0721-More-Teleport-API.patch rename to patches/server/0717-More-Teleport-API.patch index 3465cde97df5..0454f4acd212 100644 --- a/patches/unapplied/server/0721-More-Teleport-API.patch +++ b/patches/server/0717-More-Teleport-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] More Teleport API diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 4fa49daf58723827366f611e006e77448cc73a0b..f05297a2b349734b9700a0e977ee9b2bba030d65 100644 +index 84132f9642f51e1774d6c242330deebc6dfa163a..60d3a3497a49c26120650016ffff04123efa1caf 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1565,11 +1565,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1577,11 +1577,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return true; // CraftBukkit - Return event status } @@ -26,13 +26,13 @@ index 4fa49daf58723827366f611e006e77448cc73a0b..f05297a2b349734b9700a0e977ee9b2b - set = Collections.emptySet(); // Can't relative teleport + // set = Collections.emptySet(); // Can't relative teleport // Paper - Teleport API; Now you can! to = event.isCancelled() ? event.getFrom() : event.getTo(); - d0 = to.getX(); - d1 = to.getY(); + positionmoverotation = new PositionMoveRotation(CraftLocation.toVec3D(to), Vec3.ZERO, to.getYaw(), to.getPitch()); + } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 4c09f2529dd8eb7ac7d260d177f5292ff2339442..94051ae8ea93ab144f3767345b1cda0438d2afc6 100644 +index 4e6afa243d6108cb946a8a7cf96c4036a3c2ac0c..43786eacc72cdf3bb209d3dfb1808ea9d021a52e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -221,15 +221,36 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -222,15 +222,36 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { @Override public boolean teleport(Location location, TeleportCause cause) { @@ -71,7 +71,7 @@ index 4c09f2529dd8eb7ac7d260d177f5292ff2339442..94051ae8ea93ab144f3767345b1cda04 // Let the server handle cross world teleports if (location.getWorld() != null && !location.getWorld().equals(this.getWorld())) { -@@ -975,6 +996,39 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -976,6 +997,39 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return CraftEntity.perm; } @@ -112,10 +112,10 @@ index 4c09f2529dd8eb7ac7d260d177f5292ff2339442..94051ae8ea93ab144f3767345b1cda04 private final org.bukkit.entity.Entity.Spigot spigot = new org.bukkit.entity.Entity.Spigot() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index ef289dba67db65a5e43104a4ca68bc03c8c5e4cb..7f47005c08cccbcb8cd5ac56157c4e0d0dfe10b0 100644 +index 2347e260780d4703cff01b84a7971861fd924b20..884b02409968c22b8d0926ffb195ba050f51f9bc 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1286,13 +1286,101 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1299,13 +1299,101 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setRotation(float yaw, float pitch) { @@ -218,7 +218,7 @@ index ef289dba67db65a5e43104a4ca68bc03c8c5e4cb..7f47005c08cccbcb8cd5ac56157c4e0d location.checkFinite(); ServerPlayer entity = this.getHandle(); -@@ -1305,7 +1393,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1318,7 +1406,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return false; } @@ -227,7 +227,7 @@ index ef289dba67db65a5e43104a4ca68bc03c8c5e4cb..7f47005c08cccbcb8cd5ac56157c4e0d return false; } -@@ -1314,7 +1402,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1327,7 +1415,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // To = Players new Location if Teleport is Successful Location to = location; // Create & Call the Teleport Event. @@ -236,7 +236,7 @@ index ef289dba67db65a5e43104a4ca68bc03c8c5e4cb..7f47005c08cccbcb8cd5ac56157c4e0d this.server.getPluginManager().callEvent(event); // Return False to inform the Plugin that the Teleport was unsuccessful/cancelled. -@@ -1323,7 +1411,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1336,7 +1424,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // If this player is riding another entity, we must dismount before teleporting. @@ -245,7 +245,7 @@ index ef289dba67db65a5e43104a4ca68bc03c8c5e4cb..7f47005c08cccbcb8cd5ac56157c4e0d // SPIGOT-5509: Wakeup, similar to riding if (this.isSleeping()) { -@@ -1339,13 +1427,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1352,13 +1440,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { ServerLevel toWorld = ((CraftWorld) to.getWorld()).getHandle(); // Close any foreign inventory diff --git a/patches/unapplied/server/0722-Add-EntityPortalReadyEvent.patch b/patches/server/0718-Add-EntityPortalReadyEvent.patch similarity index 82% rename from patches/unapplied/server/0722-Add-EntityPortalReadyEvent.patch rename to patches/server/0718-Add-EntityPortalReadyEvent.patch index 56705093a314..46f19b8cc87a 100644 --- a/patches/unapplied/server/0722-Add-EntityPortalReadyEvent.patch +++ b/patches/server/0718-Add-EntityPortalReadyEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add EntityPortalReadyEvent diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java -index e2969b49494c55c3705312361ee8083b05ef569e..417a9ab28d247d5fbb3f1097fdeccab7ad2a793b 100644 +index c00507fa7af579263caed67dafc2ea9eba09512b..fb361eac03c16ecee02219ff0524cce2292c7976 100644 --- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java -@@ -133,6 +133,14 @@ public class NetherPortalBlock extends Block implements Portal { +@@ -141,6 +141,14 @@ public class NetherPortalBlock extends Block implements Portal { // CraftBukkit start ResourceKey resourcekey = world.getTypeKey() == LevelStem.NETHER ? Level.OVERWORLD : Level.NETHER; ServerLevel worldserver1 = world.getServer().getLevel(resourcekey); @@ -22,4 +22,4 @@ index e2969b49494c55c3705312361ee8083b05ef569e..417a9ab28d247d5fbb3f1097fdeccab7 + // Paper end - Add EntityPortalReadyEvent if (worldserver1 == null) { - return new DimensionTransition(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL); // always fire event in case plugins wish to change it + return new TeleportTransition(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL); // always fire event in case plugins wish to change it diff --git a/patches/unapplied/server/0723-Don-t-use-level-random-in-entity-constructors.patch b/patches/server/0719-Don-t-use-level-random-in-entity-constructors.patch similarity index 90% rename from patches/unapplied/server/0723-Don-t-use-level-random-in-entity-constructors.patch rename to patches/server/0719-Don-t-use-level-random-in-entity-constructors.patch index ec5bc5264e56..5fab2f6349df 100644 --- a/patches/unapplied/server/0723-Don-t-use-level-random-in-entity-constructors.patch +++ b/patches/server/0719-Don-t-use-level-random-in-entity-constructors.patch @@ -9,7 +9,7 @@ should be supported. Some entities (for whatever reason) use the level's random in some places. diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index df90d5b934f41f5d8c232e93830d6690b6ccf401..446c319524183d6a1b4d0e6f0613a8db690677da 100644 +index 6b19689a19465554b943470fc6f959e48169ac5b..aa41c4cf8d3ae291c4147118c96190ff0bb807b2 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -72,7 +72,12 @@ public class ItemEntity extends Entity implements TraceableEntity { @@ -27,10 +27,10 @@ index df90d5b934f41f5d8c232e93830d6690b6ccf401..446c319524183d6a1b4d0e6f0613a8db public ItemEntity(Level world, double x, double y, double z, ItemStack stack, double velocityX, double velocityY, double velocityZ) { diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -index 47f2a480f6a4b15e55cedbfa8a58459d33516a97..42bd2d9a1528b6210e4dfb56233062fd97c9743b 100644 +index f45a466120291103e4501276b3d8f97d79070360..96453be982623c7eb210a828404122e1d0f78b5d 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -@@ -62,7 +62,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { +@@ -68,7 +68,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { public PrimedTnt(Level world, double x, double y, double z, @Nullable LivingEntity igniter) { this(EntityType.TNT, world); this.setPos(x, y, z); diff --git a/patches/unapplied/server/0724-Send-block-entities-after-destroy-prediction.patch b/patches/server/0720-Send-block-entities-after-destroy-prediction.patch similarity index 90% rename from patches/unapplied/server/0724-Send-block-entities-after-destroy-prediction.patch rename to patches/server/0720-Send-block-entities-after-destroy-prediction.patch index c039e444e14f..2636e599bd6c 100644 --- a/patches/unapplied/server/0724-Send-block-entities-after-destroy-prediction.patch +++ b/patches/server/0720-Send-block-entities-after-destroy-prediction.patch @@ -7,10 +7,10 @@ Minecraft's prediction system does not handle block entities, so if we are manua block breaking we need to set it after the prediction is finished. This fixes block entities not showing when cancelling the BlockBreakEvent. diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index 4d024956156aefde7df308642dfd0a40779e0633..6abecaac8407b992d208a9108e11fd4954a4106f 100644 +index 5c3e5c348e6fececccd8097355f423b9e7ad982b..064a7a3e1c4d192010e072a5e985a54135748d87 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -63,6 +63,8 @@ public class ServerPlayerGameMode { +@@ -61,6 +61,8 @@ public class ServerPlayerGameMode { private BlockPos delayedDestroyPos; private int delayedTickStart; private int lastSentState; @@ -19,7 +19,7 @@ index 4d024956156aefde7df308642dfd0a40779e0633..6abecaac8407b992d208a9108e11fd49 public ServerPlayerGameMode(ServerPlayer player) { this.gameModeForPlayer = GameType.DEFAULT_MODE; -@@ -193,10 +195,7 @@ public class ServerPlayerGameMode { +@@ -191,10 +193,7 @@ public class ServerPlayerGameMode { this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos))); this.debugLogging(pos, false, sequence, "may not interact"); // Update any tile entity data for this block @@ -31,7 +31,7 @@ index 4d024956156aefde7df308642dfd0a40779e0633..6abecaac8407b992d208a9108e11fd49 // CraftBukkit end return; } -@@ -207,10 +206,7 @@ public class ServerPlayerGameMode { +@@ -205,10 +204,7 @@ public class ServerPlayerGameMode { // Let the client know the block still exists this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); // Update any tile entity data for this block @@ -43,7 +43,7 @@ index 4d024956156aefde7df308642dfd0a40779e0633..6abecaac8407b992d208a9108e11fd49 return; } // CraftBukkit end -@@ -395,10 +391,12 @@ public class ServerPlayerGameMode { +@@ -393,10 +389,12 @@ public class ServerPlayerGameMode { } // Update any tile entity data for this block @@ -57,10 +57,10 @@ index 4d024956156aefde7df308642dfd0a40779e0633..6abecaac8407b992d208a9108e11fd49 } } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index f05297a2b349734b9700a0e977ee9b2bba030d65..ca32e5aa6e77ca1bab886e7b6a778ec931ac4e4c 100644 +index 60d3a3497a49c26120650016ffff04123efa1caf..5f567d6a8ac93113c2f57d38736c4891c5f9ae19 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1711,8 +1711,28 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1715,8 +1715,28 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return; } // Paper end - Don't allow digging into unloaded chunks @@ -68,7 +68,7 @@ index f05297a2b349734b9700a0e977ee9b2bba030d65..ca32e5aa6e77ca1bab886e7b6a778ec9 + this.player.gameMode.capturedBlockEntity = false; + this.player.gameMode.captureSentBlockEntities = true; + // Paper end - Send block entities after destroy prediction - this.player.gameMode.handleBlockBreakAction(blockposition, packetplayinblockdig_enumplayerdigtype, packet.getDirection(), this.player.level().getMaxBuildHeight(), packet.getSequence()); + this.player.gameMode.handleBlockBreakAction(blockposition, packetplayinblockdig_enumplayerdigtype, packet.getDirection(), this.player.level().getMaxY(), packet.getSequence()); this.player.connection.ackBlockChangesUpTo(packet.getSequence()); + // Paper start - Send block entities after destroy prediction + this.player.gameMode.captureSentBlockEntities = false; diff --git a/patches/unapplied/server/0725-Warn-on-plugins-accessing-faraway-chunks.patch b/patches/server/0721-Warn-on-plugins-accessing-faraway-chunks.patch similarity index 88% rename from patches/unapplied/server/0725-Warn-on-plugins-accessing-faraway-chunks.patch rename to patches/server/0721-Warn-on-plugins-accessing-faraway-chunks.patch index 1b42817dd995..1528b997056d 100644 --- a/patches/unapplied/server/0725-Warn-on-plugins-accessing-faraway-chunks.patch +++ b/patches/server/0721-Warn-on-plugins-accessing-faraway-chunks.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Warn on plugins accessing faraway chunks diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index f800975068135fb86b025254db6f88f406cf0b65..63beee706d820bba5fb93db0bf53b4a6ecd403a1 100644 +index 8269bf24f5e17f9e3936659aa0cbc9d4f95fb665..a6f538372830f3f80740ef503733736e0561d1bd 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -339,7 +339,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -18,10 +18,10 @@ index f800975068135fb86b025254db6f88f406cf0b65..63beee706d820bba5fb93db0bf53b4a6 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 20a954c8637c2cf9cc6c0c823e33a44f668cc4f6..58cd4ecd5582c01b836814f4151df2538b93143c 100644 +index 9ea74d52112ab4feea3f4bafd82351a72088cbc5..03cef3e33de1cf2a1ad4c7a5ba9a65ee3b69ee52 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -305,9 +305,24 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -309,9 +309,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 20a954c8637c2cf9cc6c0c823e33a44f668cc4f6..58cd4ecd5582c01b836814f4151df253 // Paper start - add ticket to hold chunk for a little while longer if plugin accesses it net.minecraft.world.level.chunk.LevelChunk chunk = this.world.getChunkSource().getChunkAtIfLoadedImmediately(x, z); if (chunk == null) { -@@ -413,6 +428,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -419,6 +434,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { if (!unloadChunk0(x, z, false)) { return false; } @@ -54,7 +54,7 @@ index 20a954c8637c2cf9cc6c0c823e33a44f668cc4f6..58cd4ecd5582c01b836814f4151df253 final long chunkKey = ChunkCoordIntPair.pair(x, z); world.getChunkProvider().unloadQueue.remove(chunkKey); -@@ -486,6 +502,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -492,6 +508,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 20a954c8637c2cf9cc6c0c823e33a44f668cc4f6..58cd4ecd5582c01b836814f4151df253 ChunkAccess chunk = this.world.getChunkSource().getChunk(x, z, generate || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true); // Paper // If generate = false, but the chunk already exists, we will get this back. -@@ -518,6 +535,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -524,6 +541,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean addPluginChunkTicket(int x, int z, Plugin plugin) { @@ -70,7 +70,7 @@ index 20a954c8637c2cf9cc6c0c823e33a44f668cc4f6..58cd4ecd5582c01b836814f4151df253 Preconditions.checkArgument(plugin != null, "null plugin"); Preconditions.checkArgument(plugin.isEnabled(), "plugin is not enabled"); -@@ -618,6 +636,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -624,6 +642,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setChunkForceLoaded(int x, int z, boolean forced) { @@ -78,7 +78,7 @@ index 20a954c8637c2cf9cc6c0c823e33a44f668cc4f6..58cd4ecd5582c01b836814f4151df253 this.getHandle().setChunkForced(x, z, forced); } -@@ -948,6 +967,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -958,6 +977,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public int getHighestBlockYAt(int x, int z, org.bukkit.HeightMap heightMap) { @@ -86,7 +86,7 @@ index 20a954c8637c2cf9cc6c0c823e33a44f668cc4f6..58cd4ecd5582c01b836814f4151df253 // Transient load for this tick return this.world.getChunk(x >> 4, z >> 4).getHeight(CraftHeightMap.toNMS(heightMap), x, z); } -@@ -2345,6 +2365,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2358,6 +2378,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { // Spigot end // Paper start public java.util.concurrent.CompletableFuture getChunkAtAsync(int x, int z, boolean gen, boolean urgent) { diff --git a/patches/unapplied/server/0726-Custom-Chat-Completion-Suggestions-API.patch b/patches/server/0722-Custom-Chat-Completion-Suggestions-API.patch similarity index 90% rename from patches/unapplied/server/0726-Custom-Chat-Completion-Suggestions-API.patch rename to patches/server/0722-Custom-Chat-Completion-Suggestions-API.patch index 13ea62b5e66c..d07b1f664e1b 100644 --- a/patches/unapplied/server/0726-Custom-Chat-Completion-Suggestions-API.patch +++ b/patches/server/0722-Custom-Chat-Completion-Suggestions-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Custom Chat Completion Suggestions API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 7f47005c08cccbcb8cd5ac56157c4e0d0dfe10b0..3374dcd3b1f22b6c1803b9580c4cea6552b6afb1 100644 +index 884b02409968c22b8d0926ffb195ba050f51f9bc..025c392f2ca89a87f6301d4af64c4d7daec58409 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -691,6 +691,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -704,6 +704,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end - Add sendOpLevel API diff --git a/patches/unapplied/server/0727-Add-and-fix-missing-BlockFadeEvents.patch b/patches/server/0723-Add-and-fix-missing-BlockFadeEvents.patch similarity index 89% rename from patches/unapplied/server/0727-Add-and-fix-missing-BlockFadeEvents.patch rename to patches/server/0723-Add-and-fix-missing-BlockFadeEvents.patch index a889bba44742..1ac5d1e5ab42 100644 --- a/patches/unapplied/server/0727-Add-and-fix-missing-BlockFadeEvents.patch +++ b/patches/server/0723-Add-and-fix-missing-BlockFadeEvents.patch @@ -10,10 +10,10 @@ potentially waterlogged block states fading. Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> diff --git a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java -index 669234bca9fa50548447f77dc5f314df8d9dd7c9..f2d4264743b6070f36adb66d00a3de0a72b86846 100644 +index 34be6b349722240e99f91d28067578aa0b4bd1fe..4f53f25d7565eb930f6ae27ca24a6aa0cca571a2 100644 --- a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java -@@ -92,6 +92,11 @@ public class FrogspawnBlock extends Block { +@@ -102,6 +102,11 @@ public class FrogspawnBlock extends Block { } private void hatchFrogspawn(ServerLevel world, BlockPos pos, RandomSource random) { @@ -26,7 +26,7 @@ index 669234bca9fa50548447f77dc5f314df8d9dd7c9..f2d4264743b6070f36adb66d00a3de0a world.playSound(null, pos, SoundEvents.FROGSPAWN_HATCH, SoundSource.BLOCKS, 1.0F, 1.0F); this.spawnTadpoles(world, pos, random); diff --git a/src/main/java/net/minecraft/world/level/block/ScaffoldingBlock.java b/src/main/java/net/minecraft/world/level/block/ScaffoldingBlock.java -index 580c77eeaf88083f2aed2e46e6c57dc1fcf9564c..f4cccbc134b33758cd553a29b9f8e9967517500d 100644 +index fc49230d6b2c13b009724d28081f5e77537d5ab8..2d3f425778302490dd3654d487cfa3cfed6fb9e8 100644 --- a/src/main/java/net/minecraft/world/level/block/ScaffoldingBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ScaffoldingBlock.java @@ -103,7 +103,7 @@ public class ScaffoldingBlock extends Block implements SimpleWaterloggedBlock { @@ -39,10 +39,10 @@ index 580c77eeaf88083f2aed2e46e6c57dc1fcf9564c..f4cccbc134b33758cd553a29b9f8e996 FallingBlockEntity.fall(world, pos, iblockdata1); } else { diff --git a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java -index 14a5cd54820243f4ca59857b0d67c1e86457d590..f53808e200bd83ab80954ec5c1e9c14250302be8 100644 +index 4f8224841865f956aaa969ab7f543c80b3c24319..2df28caefff893f319924ae5fd376c8aeb0a2158 100644 --- a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java -@@ -60,12 +60,26 @@ public class SnifferEggBlock extends Block { +@@ -61,12 +61,26 @@ public class SnifferEggBlock extends Block { return this.getHatchLevel(state) == 2; } @@ -68,4 +68,4 @@ index 14a5cd54820243f4ca59857b0d67c1e86457d590..f53808e200bd83ab80954ec5c1e9c142 + // Paper end - Call BlockFadeEvent world.playSound(null, pos, SoundEvents.SNIFFER_EGG_HATCH, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); world.destroyBlock(pos, false); - Sniffer sniffer = EntityType.SNIFFER.create(world); + Sniffer sniffer = EntityType.SNIFFER.create(world, EntitySpawnReason.BREEDING); diff --git a/patches/unapplied/server/0728-Collision-API.patch b/patches/server/0724-Collision-API.patch similarity index 90% rename from patches/unapplied/server/0728-Collision-API.patch rename to patches/server/0724-Collision-API.patch index f8bf3193f8f7..1d22083ef1e3 100644 --- a/patches/unapplied/server/0728-Collision-API.patch +++ b/patches/server/0724-Collision-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Collision API diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index f6dd8665b9f6e2a8ff396deba8a021e695bedf7e..3c1937b43b6834ae0ffdd8d22ac32a776bc7fb64 100644 +index 244cff4f84792fd0efe146e6faf47db0b0a0dc87..6baa06dc0f102fe83b10015dbbe1410066961c82 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java @@ -543,5 +543,12 @@ public abstract class CraftRegionAccessor implements RegionAccessor { @@ -22,10 +22,10 @@ index f6dd8665b9f6e2a8ff396deba8a021e695bedf7e..3c1937b43b6834ae0ffdd8d22ac32a77 // 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 94051ae8ea93ab144f3767345b1cda0438d2afc6..f950102a324d07aeba260bfa82fe88728f2362e5 100644 +index 43786eacc72cdf3bb209d3dfb1808ea9d021a52e..775675483c1f90fbe8e9e5eadab7d791e81983f5 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1193,4 +1193,20 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1194,4 +1194,20 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return this.getHandle().noPhysics; } // Paper end - missing entity api diff --git a/patches/unapplied/server/0729-Fix-suggest-command-message-for-brigadier-syntax-exc.patch b/patches/server/0725-Fix-suggest-command-message-for-brigadier-syntax-exc.patch similarity index 89% rename from patches/unapplied/server/0729-Fix-suggest-command-message-for-brigadier-syntax-exc.patch rename to patches/server/0725-Fix-suggest-command-message-for-brigadier-syntax-exc.patch index f661ad8722b9..34f5fa3e3d28 100644 --- a/patches/unapplied/server/0729-Fix-suggest-command-message-for-brigadier-syntax-exc.patch +++ b/patches/server/0725-Fix-suggest-command-message-for-brigadier-syntax-exc.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Fix suggest command message for brigadier syntax exceptions This is a bug accidentally introduced in upstream CB diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index 64656e69dbeb6a1cf399ca143a2d7e0a1ee85957..96ca1af97c1f63776b88bc428874742a5114564f 100644 +index bee79fab7f8195e14f6bd22d9cd59bfc704bf903..fd12046fab797fd845ad8521f94147480dfba5da 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -386,7 +386,7 @@ public class Commands { +@@ -391,7 +391,7 @@ public class Commands { if (commandsyntaxexception.getInput() != null && commandsyntaxexception.getCursor() >= 0) { int i = Math.min(commandsyntaxexception.getInput().length(), commandsyntaxexception.getCursor()); MutableComponent ichatmutablecomponent = Component.empty().withStyle(ChatFormatting.GRAY).withStyle((chatmodifier) -> { diff --git a/patches/unapplied/server/0730-Block-Ticking-API.patch b/patches/server/0726-Block-Ticking-API.patch similarity index 89% rename from patches/unapplied/server/0730-Block-Ticking-API.patch rename to patches/server/0726-Block-Ticking-API.patch index 9e5247f35f95..e70fe20cb6d9 100644 --- a/patches/unapplied/server/0730-Block-Ticking-API.patch +++ b/patches/server/0726-Block-Ticking-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Block Ticking API diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index 6d10396347b69d9243ab902ecc68ede93fa17b7d..af219df5267589300f0ad1d30fa5c81a1f50234f 100644 +index 68fcec085334383808b2117a49220f4d8239220b..490a4f023491aaabd3966cb67901335c2b02bb52 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -78,6 +78,12 @@ public class CraftBlock implements Block { @@ -46,10 +46,10 @@ index 6d10396347b69d9243ab902ecc68ede93fa17b7d..af219df5267589300f0ad1d30fa5c81a // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java -index 33869e725c3b3f2120fa36ca468019a78321e862..64ddd6d1c40dc91b6e7fc3118403415bb4533d97 100644 +index a17c1d1651d4d36c40ef97c1cf0b1e0d61f53418..3ec64c995dcb59a758741e32b886925983a8be56 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java +++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java -@@ -752,4 +752,11 @@ public class CraftBlockData implements BlockData { +@@ -756,4 +756,11 @@ public class CraftBlockData implements BlockData { return speed; } // Paper end - destroy speed API diff --git a/patches/unapplied/server/0731-Add-Velocity-IP-Forwarding-Support.patch b/patches/server/0727-Add-Velocity-IP-Forwarding-Support.patch similarity index 97% rename from patches/unapplied/server/0731-Add-Velocity-IP-Forwarding-Support.patch rename to patches/server/0727-Add-Velocity-IP-Forwarding-Support.patch index 72ee3dd6febe..a8e09961bc83 100644 --- a/patches/unapplied/server/0731-Add-Velocity-IP-Forwarding-Support.patch +++ b/patches/server/0727-Add-Velocity-IP-Forwarding-Support.patch @@ -106,10 +106,10 @@ index 0000000000000000000000000000000000000000..1b797955357612a4319452de7461ba04 + } +} diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 585d3e51b4af87327fc2bc64a49f09732a8c61ab..aa39bdb0a4ba8fedf5052ea9700afa7d4d2a4300 100644 +index 3c3be48b29fcd38c5dea1bfca8d8690850aa948e..4037a1057ebc87e3df6333e0d546fc85b5148d2a 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -291,13 +291,20 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -290,13 +290,20 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.STARTUP); // CraftBukkit end @@ -134,7 +134,7 @@ index 585d3e51b4af87327fc2bc64a49f09732a8c61ab..aa39bdb0a4ba8fedf5052ea9700afa7d DedicatedServer.LOGGER.warn("While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose."); } diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 9c343b579d9735dc59c8c74fde030d981a673c4f..35faa10f3b82504ae9d3f923fc04c5a99c1a624a 100644 +index cb5dd77892283a1aaec45434fb99bb7f08ee5394..4a89b73d972f366e70f4d2bd96c6ee413593baba 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -91,6 +91,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, @@ -228,10 +228,10 @@ index 9c343b579d9735dc59c8c74fde030d981a673c4f..35faa10f3b82504ae9d3f923fc04c5a9 } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 3c5d44499e94bd19e4058eb2bf2d9b5d5890f980..96e7bad6620ff6dc17a80af3febcbc4e1623944e 100644 +index 284ffa47223595b42d115533551821f379de6663..f89cbdb157cb56b1b3e0658d80de48695734138d 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -846,7 +846,7 @@ public final class CraftServer implements Server { +@@ -849,7 +849,7 @@ public final class CraftServer implements Server { @Override public long getConnectionThrottle() { // Spigot Start - Automatically set connection throttle for bungee configurations diff --git a/patches/unapplied/server/0732-Add-NamespacedKey-biome-methods.patch b/patches/server/0728-Add-NamespacedKey-biome-methods.patch similarity index 95% rename from patches/unapplied/server/0732-Add-NamespacedKey-biome-methods.patch rename to patches/server/0728-Add-NamespacedKey-biome-methods.patch index 1c393cb89c32..04815e385ef6 100644 --- a/patches/unapplied/server/0732-Add-NamespacedKey-biome-methods.patch +++ b/patches/server/0728-Add-NamespacedKey-biome-methods.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add NamespacedKey biome methods Co-authored-by: Thonk <30448663+ExcessiveAmountsOfZombies@users.noreply.github.com> diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index c10273445c4b5ef089f86fc08a944da69d708244..72c2f70d22c5ac920f13b11badac404dbb15c055 100644 +index 98bbbdbf8fd067df936655334ad5ea25ec07daef..a5a3a0f0460252415c243dfe3019d103b9589c5b 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -584,6 +584,21 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/unapplied/server/0719-Fix-Bee-flower-NPE.patch b/patches/unapplied/server/0719-Fix-Bee-flower-NPE.patch deleted file mode 100644 index db6e1b0ad944..000000000000 --- a/patches/unapplied/server/0719-Fix-Bee-flower-NPE.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Wed, 6 Jul 2022 14:59:38 -0700 -Subject: [PATCH] Fix Bee flower NPE - - -diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java -index f933654b66f7474dc071da5f10cf1684fdac367a..1b3978f4ea7e8491e0c0cb6de23c141f44fab414 100644 ---- a/src/main/java/net/minecraft/world/entity/animal/Bee.java -+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java -@@ -805,7 +805,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { - ++this.pollinatingTicks; - if (this.pollinatingTicks > 600) { - Bee.this.savedFlowerPos = null; -- } else { -+ } else if (Bee.this.savedFlowerPos != null) { // Paper - add null check since API can manipulate this - Vec3 vec3d = Vec3.atBottomCenterOf(Bee.this.savedFlowerPos).add(0.0D, 0.6000000238418579D, 0.0D); - - if (vec3d.distanceTo(Bee.this.position()) > 1.0D) { From d52e2d241da502ffc14b2097e9b6d784a01e899b Mon Sep 17 00:00:00 2001 From: Noah van der Aa Date: Wed, 23 Oct 2024 23:35:21 +0200 Subject: [PATCH 030/119] MOOOOOOOORE --- ...x-plugin-loggers-on-server-shutdown.patch} | 6 +- ...ok-changes-from-crashing-the-server.patch} | 14 +- ...tityChangeBlockEvent-in-more-places.patch} | 85 +++++----- .../0732-Missing-eating-regain-reason.patch} | 14 +- .../server/0733-Missing-effect-cause.patch | 19 +++ ...serialization-deserialization-for-P.patch} | 0 ...5-Call-BlockPhysicsEvent-more-often.patch} | 14 +- ...0736-Configurable-chat-thread-limit.patch} | 0 ...of-WorldCreator-keepSpawnLoaded-ret.patch} | 0 .../0738-fix-Jigsaw-block-kicking-user.patch} | 8 +- ...mEvent-for-mud-converting-into-clay.patch} | 4 +- .../0740-Add-getDrops-to-BlockState.patch} | 0 .../0741-Fix-a-bunch-of-vanilla-bugs.patch} | 153 +++++++----------- ...y-onTrackingStart-during-navigation.patch} | 6 +- .../0743-Fix-custom-piglin-loved-items.patch} | 4 +- .../0744-EntityPickupItemEvent-fixes.patch | 73 +++++++++ ...interactions-with-items-on-cooldown.patch} | 14 +- ...-Add-PlayerInventorySlotChangeEvent.patch} | 8 +- .../0747-Elder-Guardian-appearance-API.patch} | 4 +- .../0748-Add-entity-knockback-API.patch} | 4 +- .../0749-Detect-headless-JREs.patch} | 2 +- ...-vehicle-collision-event-not-called.patch} | 8 +- .../0751-Add-EntityToggleSitEvent.patch} | 26 +-- .../0752-Add-fire-tick-delay-option.patch} | 2 +- .../0753-Add-Moving-Piston-API.patch} | 0 .../0754-Ignore-impossible-spawn-tick.patch} | 2 +- ...t-and-EntitySelectorParser-permissi.patch} | 0 ...Event-cancellation-cant-fully-preve.patch} | 8 +- ...0757-Add-PrePlayerAttackEntityEvent.patch} | 6 +- ...e-reset-EnderDragon-boss-event-name.patch} | 8 +- .../0759-Add-Player-Warden-Warning-API.patch} | 4 +- ...a-friendly-methods-to-update-trades.patch} | 10 +- ...761-Add-paper-dumplisteners-command.patch} | 0 .../server/0737-Missing-effect-cause.patch | 58 ------- .../0748-EntityPickupItemEvent-fixes.patch | 73 --------- todo.txt | 1 - 36 files changed, 281 insertions(+), 357 deletions(-) rename patches/{unapplied/server/0733-Fix-plugin-loggers-on-server-shutdown.patch => server/0729-Fix-plugin-loggers-on-server-shutdown.patch} (90%) rename patches/{unapplied/server/0734-Stop-large-look-changes-from-crashing-the-server.patch => server/0730-Stop-large-look-changes-from-crashing-the-server.patch} (85%) rename patches/{unapplied/server/0735-Fire-EntityChangeBlockEvent-in-more-places.patch => server/0731-Fire-EntityChangeBlockEvent-in-more-places.patch} (83%) rename patches/{unapplied/server/0736-Missing-eating-regain-reason.patch => server/0732-Missing-eating-regain-reason.patch} (78%) create mode 100644 patches/server/0733-Missing-effect-cause.patch rename patches/{unapplied/server/0738-Added-byte-array-serialization-deserialization-for-P.patch => server/0734-Added-byte-array-serialization-deserialization-for-P.patch} (100%) rename patches/{unapplied/server/0739-Call-BlockPhysicsEvent-more-often.patch => server/0735-Call-BlockPhysicsEvent-more-often.patch} (77%) rename patches/{unapplied/server/0740-Configurable-chat-thread-limit.patch => server/0736-Configurable-chat-thread-limit.patch} (100%) rename patches/{unapplied/server/0741-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch => server/0737-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch} (100%) rename patches/{unapplied/server/0742-fix-Jigsaw-block-kicking-user.patch => server/0738-fix-Jigsaw-block-kicking-user.patch} (80%) rename patches/{unapplied/server/0743-use-BlockFormEvent-for-mud-converting-into-clay.patch => server/0739-use-BlockFormEvent-for-mud-converting-into-clay.patch} (92%) rename patches/{unapplied/server/0744-Add-getDrops-to-BlockState.patch => server/0740-Add-getDrops-to-BlockState.patch} (100%) rename patches/{unapplied/server/0745-Fix-a-bunch-of-vanilla-bugs.patch => server/0741-Fix-a-bunch-of-vanilla-bugs.patch} (72%) rename patches/{unapplied/server/0746-Remove-unnecessary-onTrackingStart-during-navigation.patch => server/0742-Remove-unnecessary-onTrackingStart-during-navigation.patch} (84%) rename patches/{unapplied/server/0747-Fix-custom-piglin-loved-items.patch => server/0743-Fix-custom-piglin-loved-items.patch} (90%) create mode 100644 patches/server/0744-EntityPickupItemEvent-fixes.patch rename patches/{unapplied/server/0749-Correctly-handle-interactions-with-items-on-cooldown.patch => server/0745-Correctly-handle-interactions-with-items-on-cooldown.patch} (87%) rename patches/{unapplied/server/0750-Add-PlayerInventorySlotChangeEvent.patch => server/0746-Add-PlayerInventorySlotChangeEvent.patch} (91%) rename patches/{unapplied/server/0751-Elder-Guardian-appearance-API.patch => server/0747-Elder-Guardian-appearance-API.patch} (84%) rename patches/{unapplied/server/0752-Add-entity-knockback-API.patch => server/0748-Add-entity-knockback-API.patch} (86%) rename patches/{unapplied/server/0753-Detect-headless-JREs.patch => server/0749-Detect-headless-JREs.patch} (96%) rename patches/{unapplied/server/0754-fix-entity-vehicle-collision-event-not-called.patch => server/0750-fix-entity-vehicle-collision-event-not-called.patch} (79%) rename patches/{unapplied/server/0755-Add-EntityToggleSitEvent.patch => server/0751-Add-EntityToggleSitEvent.patch} (79%) rename patches/{unapplied/server/0756-Add-fire-tick-delay-option.patch => server/0752-Add-fire-tick-delay-option.patch} (95%) rename patches/{unapplied/server/0757-Add-Moving-Piston-API.patch => server/0753-Add-Moving-Piston-API.patch} (100%) rename patches/{unapplied/server/0758-Ignore-impossible-spawn-tick.patch => server/0754-Ignore-impossible-spawn-tick.patch} (90%) rename patches/{unapplied/server/0759-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch => server/0755-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch} (100%) rename patches/{unapplied/server/0760-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch => server/0756-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch} (84%) rename patches/{unapplied/server/0761-Add-PrePlayerAttackEntityEvent.patch => server/0757-Add-PrePlayerAttackEntityEvent.patch} (81%) rename patches/{unapplied/server/0762-ensure-reset-EnderDragon-boss-event-name.patch => server/0758-ensure-reset-EnderDragon-boss-event-name.patch} (89%) rename patches/{unapplied/server/0763-Add-Player-Warden-Warning-API.patch => server/0759-Add-Player-Warden-Warning-API.patch} (93%) rename patches/{unapplied/server/0764-More-vanilla-friendly-methods-to-update-trades.patch => server/0760-More-vanilla-friendly-methods-to-update-trades.patch} (90%) rename patches/{unapplied/server/0765-Add-paper-dumplisteners-command.patch => server/0761-Add-paper-dumplisteners-command.patch} (100%) delete mode 100644 patches/unapplied/server/0737-Missing-effect-cause.patch delete mode 100644 patches/unapplied/server/0748-EntityPickupItemEvent-fixes.patch delete mode 100644 todo.txt diff --git a/patches/unapplied/server/0733-Fix-plugin-loggers-on-server-shutdown.patch b/patches/server/0729-Fix-plugin-loggers-on-server-shutdown.patch similarity index 90% rename from patches/unapplied/server/0733-Fix-plugin-loggers-on-server-shutdown.patch rename to patches/server/0729-Fix-plugin-loggers-on-server-shutdown.patch index 4a610485e692..6c058f039b4b 100644 --- a/patches/unapplied/server/0733-Fix-plugin-loggers-on-server-shutdown.patch +++ b/patches/server/0729-Fix-plugin-loggers-on-server-shutdown.patch @@ -37,10 +37,10 @@ index 0000000000000000000000000000000000000000..c1d3bac79bb8b4796c013ff4472f75dc + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 11b9eb8d7d5f9ad736f2c6784c5d9e745a355093..bef05e09c654794405832ad75c3471f63399dfee 100644 +index 2101c0a3b000a60733ceada248c202e2c4783af5..027d94dd08e7789b51c8779c65d4ddad4e62f21a 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1237,6 +1237,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 5383d231748f2d30b2f2bf3ce07d3667e4d828e9..e6d20887572817099cb863515978d3f06926be3d 100644 +index 682d0399b9b3729d16978eca258c55c2150afec7..16f349f8ce621c58f36f445016ea25d8af14910d 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3158,37 +3158,15 @@ public abstract class LivingEntity extends Entity implements Attackable { - this.level().getProfiler().pop(); - this.level().getProfiler().push("rangeChecks"); +@@ -3272,37 +3272,15 @@ public abstract class LivingEntity extends Entity implements Attackable { + gameprofilerfiller.pop(); + gameprofilerfiller.push("rangeChecks"); - while (this.getYRot() - this.yRotO < -180.0F) { - this.yRotO -= 360.0F; @@ -51,13 +51,13 @@ index 5383d231748f2d30b2f2bf3ce07d3667e4d828e9..e6d20887572817099cb863515978d3f0 + this.yHeadRotO += Math.round((this.yHeadRot - this.yHeadRotO) / 360.0F) * 360.0F; + // Paper end - this.level().getProfiler().pop(); + gameprofilerfiller.pop(); this.animStep += f2; diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 06ca07edef062f21c51860146086297ca345104d..63ffa02f820d88f865ae604712edcf2ac13f0bff 100644 +index 846a108af8bacdcaf3a17db9fb808965ce2581bb..4d487090a622d280bdfacc18978929c61f74f147 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -313,13 +313,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -428,13 +428,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { } protected static float lerpRotation(float prevRot, float newRot) { diff --git a/patches/unapplied/server/0735-Fire-EntityChangeBlockEvent-in-more-places.patch b/patches/server/0731-Fire-EntityChangeBlockEvent-in-more-places.patch similarity index 83% rename from patches/unapplied/server/0735-Fire-EntityChangeBlockEvent-in-more-places.patch rename to patches/server/0731-Fire-EntityChangeBlockEvent-in-more-places.patch index bafa064971a4..3fab5db6280f 100644 --- a/patches/unapplied/server/0735-Fire-EntityChangeBlockEvent-in-more-places.patch +++ b/patches/server/0731-Fire-EntityChangeBlockEvent-in-more-places.patch @@ -7,23 +7,18 @@ Co-authored-by: ChristopheG <61288881+chrisgdt@users.noreply.github.com> Co-authored-by: maxcom1 <46265094+maxcom1@users.noreply.github.com> diff --git a/src/main/java/net/minecraft/world/effect/WeavingMobEffect.java b/src/main/java/net/minecraft/world/effect/WeavingMobEffect.java -index 6a84eaeddd0d7f050053c8aa0659d6811192aad4..1b2d41a6c6f149701c8a78f3d345f45069f1f857 100644 +index e311f94918fb03e9d202cbae71b0909ea3219180..d090126dbe6b69489490e6b1e2d443fa171ddde6 100644 --- a/src/main/java/net/minecraft/world/effect/WeavingMobEffect.java +++ b/src/main/java/net/minecraft/world/effect/WeavingMobEffect.java -@@ -25,11 +25,11 @@ class WeavingMobEffect extends MobEffect { +@@ -25,7 +25,7 @@ class WeavingMobEffect extends MobEffect { @Override - public void onMobRemoved(LivingEntity entity, int amplifier, Entity.RemovalReason reason) { - if (reason == Entity.RemovalReason.KILLED && (entity instanceof Player || entity.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { -- this.spawnCobwebsRandomlyAround(entity.level(), entity.getRandom(), entity.getOnPos()); -+ this.spawnCobwebsRandomlyAround(entity, entity.level(), entity.getRandom(), entity.getOnPos()); // Paper - Fire EntityChangeBlockEvent in more places + public void onMobRemoved(ServerLevel world, LivingEntity entity, int amplifier, Entity.RemovalReason reason) { + if (reason == Entity.RemovalReason.KILLED && (entity instanceof Player || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { +- this.spawnCobwebsRandomlyAround(world, entity.getRandom(), entity.blockPosition()); ++ this.spawnCobwebsRandomlyAround(entity, world, entity.getRandom(), entity.blockPosition()); // Paper - Fire EntityChangeBlockEvent in more places } } -- private void spawnCobwebsRandomlyAround(Level world, RandomSource random, BlockPos pos) { -+ private void spawnCobwebsRandomlyAround(LivingEntity entity, Level world, RandomSource random, BlockPos pos) { // Paper - Fire EntityChangeBlockEvent in more places - Set set = Sets.newHashSet(); - int i = this.maxCobwebs.applyAsInt(random); - @@ -46,6 +46,7 @@ class WeavingMobEffect extends MobEffect { } @@ -33,10 +28,10 @@ index 6a84eaeddd0d7f050053c8aa0659d6811192aad4..1b2d41a6c6f149701c8a78f3d345f450 world.levelEvent(3018, blockPos3, 0); } diff --git a/src/main/java/net/minecraft/world/entity/LightningBolt.java b/src/main/java/net/minecraft/world/entity/LightningBolt.java -index bf5015c4bb68e5c46313bab1e59c0a4d45053b73..0471d9c85af02133f99cca4e181b83b58a3f1abc 100644 +index 2b09e9efad198ff596d88f97d703a8a00c108608..152ecd38814089333b8d61538297ce720756d2c3 100644 --- a/src/main/java/net/minecraft/world/entity/LightningBolt.java +++ b/src/main/java/net/minecraft/world/entity/LightningBolt.java -@@ -99,7 +99,7 @@ public class LightningBolt extends Entity { +@@ -98,7 +98,7 @@ public class LightningBolt extends Entity { } this.powerLightningRod(); @@ -45,8 +40,8 @@ index bf5015c4bb68e5c46313bab1e59c0a4d45053b73..0471d9c85af02133f99cca4e181b83b5 this.gameEvent(GameEvent.LIGHTNING_STRIKE); } } -@@ -193,7 +193,7 @@ public class LightningBolt extends Entity { - } +@@ -202,7 +202,7 @@ public class LightningBolt extends Entity { + } - private static void clearCopperOnLightningStrike(Level world, BlockPos pos) { @@ -54,7 +49,7 @@ index bf5015c4bb68e5c46313bab1e59c0a4d45053b73..0471d9c85af02133f99cca4e181b83b5 BlockState iblockdata = world.getBlockState(pos); BlockPos blockposition1; BlockState iblockdata1; -@@ -207,24 +207,29 @@ public class LightningBolt extends Entity { +@@ -216,24 +216,29 @@ public class LightningBolt extends Entity { } if (iblockdata1.getBlock() instanceof WeatheringCopper) { @@ -88,7 +83,7 @@ index bf5015c4bb68e5c46313bab1e59c0a4d45053b73..0471d9c85af02133f99cca4e181b83b5 if (optional.isEmpty()) { break; -@@ -235,7 +240,7 @@ public class LightningBolt extends Entity { +@@ -244,7 +249,7 @@ public class LightningBolt extends Entity { } @@ -97,7 +92,7 @@ index bf5015c4bb68e5c46313bab1e59c0a4d45053b73..0471d9c85af02133f99cca4e181b83b5 Iterator iterator = BlockPos.randomInCube(world.random, 10, pos, 1).iterator(); BlockPos blockposition1; -@@ -252,6 +257,7 @@ public class LightningBolt extends Entity { +@@ -261,6 +266,7 @@ public class LightningBolt extends Entity { BlockPos blockposition1Final = blockposition1; // CraftBukkit - decompile error WeatheringCopper.getPrevious(iblockdata).ifPresent((iblockdata1) -> { @@ -106,10 +101,10 @@ index bf5015c4bb68e5c46313bab1e59c0a4d45053b73..0471d9c85af02133f99cca4e181b83b5 }); world.levelEvent(3002, blockposition1, -1); diff --git a/src/main/java/net/minecraft/world/item/AxeItem.java b/src/main/java/net/minecraft/world/item/AxeItem.java -index c227784544e52ee2c75ab1a2181e0b0ba7246f4b..f005ea92449cf5e249ff64f4791c3bc6b8635528 100644 +index 74c9966093377b67e31b50483c2f24b70734faf6..abff08f2d61014944235ffe2f5494a718a28cc10 100644 --- a/src/main/java/net/minecraft/world/item/AxeItem.java +++ b/src/main/java/net/minecraft/world/item/AxeItem.java -@@ -65,6 +65,11 @@ public class AxeItem extends DiggerItem { +@@ -67,6 +67,11 @@ public class AxeItem extends DiggerItem { return InteractionResult.PASS; } else { ItemStack itemStack = context.getItemInHand(); @@ -122,10 +117,10 @@ index c227784544e52ee2c75ab1a2181e0b0ba7246f4b..f005ea92449cf5e249ff64f4791c3bc6 CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, blockPos, itemStack); } diff --git a/src/main/java/net/minecraft/world/item/EnderEyeItem.java b/src/main/java/net/minecraft/world/item/EnderEyeItem.java -index 391579b515c5a07066f82b33c4f9ef8ee1d05530..d8ce44a180f848f4c9c04967470c4359af979b2f 100644 +index 770467bd319f8e2fdf3d713591368aa825cfa5ae..b00a2fe4cefff26b65789829777b25bbc8e024fa 100644 --- a/src/main/java/net/minecraft/world/item/EnderEyeItem.java +++ b/src/main/java/net/minecraft/world/item/EnderEyeItem.java -@@ -46,6 +46,11 @@ public class EnderEyeItem extends Item { +@@ -45,6 +45,11 @@ public class EnderEyeItem extends Item { return InteractionResult.SUCCESS; } else { BlockState iblockdata1 = (BlockState) iblockdata.setValue(EndPortalFrameBlock.HAS_EYE, true); @@ -138,7 +133,7 @@ index 391579b515c5a07066f82b33c4f9ef8ee1d05530..d8ce44a180f848f4c9c04967470c4359 Block.pushEntitiesUp(iblockdata, iblockdata1, world, blockposition); world.setBlock(blockposition, iblockdata1, 2); diff --git a/src/main/java/net/minecraft/world/item/HoneycombItem.java b/src/main/java/net/minecraft/world/item/HoneycombItem.java -index decabf6fccaca3d1bfeba679ac71677d33315f5e..14d37bf64af719eae3ea154ea7f952cc27712b57 100644 +index 6c0fe41692c9d1fa50a4f421eb4735860a9ae0e9..d7924825823b2bf79ca3a26272de11ff8d2ec74c 100644 --- a/src/main/java/net/minecraft/world/item/HoneycombItem.java +++ b/src/main/java/net/minecraft/world/item/HoneycombItem.java @@ -74,6 +74,14 @@ public class HoneycombItem extends Item implements SignApplicator { @@ -153,28 +148,28 @@ index decabf6fccaca3d1bfeba679ac71677d33315f5e..14d37bf64af719eae3ea154ea7f952cc + return InteractionResult.PASS; + } + // Paper end - if (player instanceof ServerPlayer) { - CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, blockPos, itemStack); + if (player instanceof ServerPlayer serverPlayer) { + CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(serverPlayer, blockPos, itemStack); } diff --git a/src/main/java/net/minecraft/world/item/PotionItem.java b/src/main/java/net/minecraft/world/item/PotionItem.java -index 92fa6523f2bba105a74fff228e36e58666ed56ae..d147b24bb57b322d3f5f4a9eb8cfef2acdd9e0f5 100644 +index 1c8fd643c32226d72d51abc869a49e256dd2432b..627439c3aa8171e9a54dbcb8842af50cc58f7f23 100644 --- a/src/main/java/net/minecraft/world/item/PotionItem.java +++ b/src/main/java/net/minecraft/world/item/PotionItem.java -@@ -109,6 +109,12 @@ public class PotionItem extends Item { - BlockState iblockdata = world.getBlockState(blockposition); - - if (context.getClickedFace() != Direction.DOWN && iblockdata.is(BlockTags.CONVERTABLE_TO_MUD) && potioncontents.is(Potions.WATER)) { +@@ -42,6 +42,12 @@ public class PotionItem extends Item { + PotionContents potionContents = itemStack.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY); + BlockState blockState = level.getBlockState(blockPos); + if (context.getClickedFace() != Direction.DOWN && blockState.is(BlockTags.CONVERTABLE_TO_MUD) && potionContents.is(Potions.WATER)) { + // Paper start + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entityhuman, blockposition, Blocks.MUD.defaultBlockState())) { + entityhuman.containerMenu.sendAllDataToRemote(); + return InteractionResult.PASS; + } + // Paper end - world.playSound((Player) null, blockposition, SoundEvents.GENERIC_SPLASH, SoundSource.BLOCKS, 1.0F, 1.0F); - entityhuman.setItemInHand(context.getHand(), ItemUtils.createFilledResult(itemstack, entityhuman, new ItemStack(Items.GLASS_BOTTLE))); - entityhuman.awardStat(Stats.ITEM_USED.get(itemstack.getItem())); + level.playSound(null, blockPos, SoundEvents.GENERIC_SPLASH, SoundSource.BLOCKS, 1.0F, 1.0F); + player.setItemInHand(context.getHand(), ItemUtils.createFilledResult(itemStack, player, new ItemStack(Items.GLASS_BOTTLE))); + player.awardStat(Stats.ITEM_USED.get(itemStack.getItem())); diff --git a/src/main/java/net/minecraft/world/item/ShovelItem.java b/src/main/java/net/minecraft/world/item/ShovelItem.java -index c0e96284bb470353c0e54ad4e0c2205017913e61..24f6a158e4759aac3be8da4cf5e0d40bd295355b 100644 +index c0377341227e8f4f1f7b1448580b3c7bc1b65f48..55c18f182166f4905d623d6f5e909eefd5ed2483 100644 --- a/src/main/java/net/minecraft/world/item/ShovelItem.java +++ b/src/main/java/net/minecraft/world/item/ShovelItem.java @@ -46,20 +46,29 @@ public class ShovelItem extends DiggerItem { @@ -209,10 +204,10 @@ index c0e96284bb470353c0e54ad4e0c2205017913e61..24f6a158e4759aac3be8da4cf5e0d40b level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(player, blockState3)); if (player != null) { diff --git a/src/main/java/net/minecraft/world/level/block/CakeBlock.java b/src/main/java/net/minecraft/world/level/block/CakeBlock.java -index d72f4a01ca07df8a9678b3ca4707e5363e482283..43e306b5ef00b39923c1597f212b4a07fb95f1ca 100644 +index 7629b9212ded7155e94f67ca429f62271e5f5aa0..1104f620a050555f71d058711cc34fadb964222f 100644 --- a/src/main/java/net/minecraft/world/level/block/CakeBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CakeBlock.java -@@ -65,6 +65,12 @@ public class CakeBlock extends Block { +@@ -66,6 +66,12 @@ public class CakeBlock extends Block { if (block instanceof CandleBlock) { CandleBlock candleblock = (CandleBlock) block; @@ -225,7 +220,7 @@ index d72f4a01ca07df8a9678b3ca4707e5363e482283..43e306b5ef00b39923c1597f212b4a07 stack.consume(1, player); world.playSound((Player) null, pos, SoundEvents.CAKE_ADD_CANDLE, SoundSource.BLOCKS, 1.0F, 1.0F); world.setBlockAndUpdate(pos, CandleCakeBlock.byCandle(candleblock)); -@@ -96,6 +102,14 @@ public class CakeBlock extends Block { +@@ -97,6 +103,14 @@ public class CakeBlock extends Block { if (!player.canEat(false)) { return InteractionResult.PASS; } else { @@ -240,7 +235,7 @@ index d72f4a01ca07df8a9678b3ca4707e5363e482283..43e306b5ef00b39923c1597f212b4a07 player.awardStat(Stats.EAT_CAKE_SLICE); // CraftBukkit start // entityhuman.getFoodData().eat(2, 0.1F); -@@ -109,7 +123,7 @@ public class CakeBlock extends Block { +@@ -110,7 +124,7 @@ public class CakeBlock extends Block { ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().sendHealthUpdate(); // CraftBukkit end @@ -250,10 +245,10 @@ index d72f4a01ca07df8a9678b3ca4707e5363e482283..43e306b5ef00b39923c1597f212b4a07 world.gameEvent((Entity) player, (Holder) GameEvent.EAT, pos); if (i < 6) { diff --git a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java -index 804adb5ed92dfcf4c29c756dd95d7164150a9666..19fa8a9f935e9063497f8c0bd7909036fa0af2b7 100644 +index 2bcd246a26dad560cf69682b29983d320ebf1884..60bf63c2cff3ce8a1892ba5c2303738c35b83d79 100644 --- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java -@@ -239,6 +239,11 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -243,6 +243,11 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { if (i < 8 && ComposterBlock.COMPOSTABLES.containsKey(stack.getItem())) { if (i < 7 && !world.isClientSide) { BlockState iblockdata1 = ComposterBlock.addItem(player, state, world, pos, stack); @@ -265,7 +260,7 @@ index 804adb5ed92dfcf4c29c756dd95d7164150a9666..19fa8a9f935e9063497f8c0bd7909036 world.levelEvent(1500, pos, state != iblockdata1 ? 1 : 0); player.awardStat(Stats.ITEM_USED.get(stack.getItem())); -@@ -269,11 +274,16 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -273,11 +278,16 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { if (i < 7 && ComposterBlock.COMPOSTABLES.containsKey(stack.getItem())) { // CraftBukkit start double rand = world.getRandom().nextDouble(); @@ -284,7 +279,7 @@ index 804adb5ed92dfcf4c29c756dd95d7164150a9666..19fa8a9f935e9063497f8c0bd7909036 // CraftBukkit end stack.shrink(1); -@@ -314,11 +324,13 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -318,11 +328,13 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { return iblockdata1; } @@ -298,7 +293,7 @@ index 804adb5ed92dfcf4c29c756dd95d7164150a9666..19fa8a9f935e9063497f8c0bd7909036 static BlockState addItem(@Nullable Entity entity, BlockState iblockdata, LevelAccessor generatoraccess, BlockPos blockposition, ItemStack itemstack, double rand) { // CraftBukkit end int i = (Integer) iblockdata.getValue(ComposterBlock.LEVEL); -@@ -329,6 +341,11 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -333,6 +345,11 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { } else { int j = i + 1; BlockState iblockdata1 = (BlockState) iblockdata.setValue(ComposterBlock.LEVEL, j); @@ -311,10 +306,10 @@ index 804adb5ed92dfcf4c29c756dd95d7164150a9666..19fa8a9f935e9063497f8c0bd7909036 generatoraccess.setBlock(blockposition, iblockdata1, 3); generatoraccess.gameEvent((Holder) GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(entity, iblockdata1)); diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java -index ef8a0236ab4fb648c4bb2a8cfc90e3cefe8f9f1d..1a3d8755c8f6a7cfe06069e2082d8147aaaff097 100644 +index 8224d5bddb7f7893dee09222a673af54791abcfa..f8828dc8334af19d7b2118e8cf34d94be5e09ee8 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java -@@ -259,7 +259,13 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -260,7 +260,13 @@ public class BeehiveBlockEntity extends BlockEntity { --j; } diff --git a/patches/unapplied/server/0736-Missing-eating-regain-reason.patch b/patches/server/0732-Missing-eating-regain-reason.patch similarity index 78% rename from patches/unapplied/server/0736-Missing-eating-regain-reason.patch rename to patches/server/0732-Missing-eating-regain-reason.patch index af804e161b36..38626b635277 100644 --- a/patches/unapplied/server/0736-Missing-eating-regain-reason.patch +++ b/patches/server/0732-Missing-eating-regain-reason.patch @@ -5,23 +5,23 @@ Subject: [PATCH] Missing eating regain reason diff --git a/src/main/java/net/minecraft/world/entity/animal/Cat.java b/src/main/java/net/minecraft/world/entity/animal/Cat.java -index 2ed442c8d36f285420cf84a956e90b6036384ce0..23d4dcc82115fd1a0a77565a0472304042d5f12d 100644 +index bffc7c21727a6e5ff13a498aa51f6797e4d6d596..471d5727b964922d8e898be9e1d5c30f9d3bac97 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Cat.java +++ b/src/main/java/net/minecraft/world/entity/animal/Cat.java -@@ -398,7 +398,7 @@ public class Cat extends TamableAnimal implements VariantHolder 0.0F) { diff --git a/patches/server/0733-Missing-effect-cause.patch b/patches/server/0733-Missing-effect-cause.patch new file mode 100644 index 000000000000..6157121022e5 --- /dev/null +++ b/patches/server/0733-Missing-effect-cause.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> +Date: Tue, 16 Aug 2022 19:44:55 +0200 +Subject: [PATCH] Missing effect cause + + +diff --git a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java +index 068d96cd0bceec79f14fbf3289eeb81533d1ba22..31b10cd404b672d7ce21c2107d8f83e32de26ef4 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java ++++ b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java +@@ -424,7 +424,7 @@ public class Axolotl extends Animal implements VariantHolder, B + player.addEffect(new MobEffectInstance(MobEffects.REGENERATION, j, 0), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.AXOLOTL); // CraftBukkit + } + +- player.removeEffect(MobEffects.DIG_SLOWDOWN); ++ player.removeEffect(MobEffects.DIG_SLOWDOWN, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.AXOLOTL); // Paper - Add missing effect cause + } + + @Override diff --git a/patches/unapplied/server/0738-Added-byte-array-serialization-deserialization-for-P.patch b/patches/server/0734-Added-byte-array-serialization-deserialization-for-P.patch similarity index 100% rename from patches/unapplied/server/0738-Added-byte-array-serialization-deserialization-for-P.patch rename to patches/server/0734-Added-byte-array-serialization-deserialization-for-P.patch diff --git a/patches/unapplied/server/0739-Call-BlockPhysicsEvent-more-often.patch b/patches/server/0735-Call-BlockPhysicsEvent-more-often.patch similarity index 77% rename from patches/unapplied/server/0739-Call-BlockPhysicsEvent-more-often.patch rename to patches/server/0735-Call-BlockPhysicsEvent-more-often.patch index 1839fbe711c4..ad24091f87da 100644 --- a/patches/unapplied/server/0739-Call-BlockPhysicsEvent-more-often.patch +++ b/patches/server/0735-Call-BlockPhysicsEvent-more-often.patch @@ -5,14 +5,14 @@ Subject: [PATCH] Call BlockPhysicsEvent more often diff --git a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java -index 457a963ee6ebd3cf5c3831f6660e3850335af49f..106af2b2c7ff72c7549975aef75cdcff8d9a7d97 100644 +index 5821c802ec880501df025fcd3fbbd98242ed952c..0587f4e5083a6c890a11642284a9c16fb2eb2fe1 100644 --- a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java +++ b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java -@@ -119,7 +119,20 @@ public class CollectingNeighborUpdater implements NeighborUpdater { - public boolean runNext(Level world) { - BlockPos blockPos = this.sourcePos.relative(NeighborUpdater.UPDATE_ORDER[this.idx++]); - BlockState blockState = world.getBlockState(blockPos); -- NeighborUpdater.executeUpdate(world, blockState, blockPos, this.sourceBlock, this.sourcePos, false); +@@ -135,7 +135,20 @@ public class CollectingNeighborUpdater implements NeighborUpdater { + orientation = this.orientation.withFront(direction); + } + +- NeighborUpdater.executeUpdate(world, blockState, blockPos, this.sourceBlock, orientation, false); + // Paper start - Call BlockPhysicsEvent + try { + org.bukkit.event.block.BlockPhysicsEvent event = new org.bukkit.event.block.BlockPhysicsEvent( @@ -21,7 +21,7 @@ index 457a963ee6ebd3cf5c3831f6660e3850335af49f..106af2b2c7ff72c7549975aef75cdcff + org.bukkit.craftbukkit.block.CraftBlock.at(world, this.sourcePos)); + + if (event.callEvent()) { // continue to check for adjacent block (increase idx) -+ NeighborUpdater.executeUpdate(world, blockState, blockPos, this.sourceBlock, this.sourcePos, false); ++ NeighborUpdater.executeUpdate(world, blockState, blockPos, this.sourceBlock, orientation, false); + } + } catch (StackOverflowError ex) { + world.lastPhysicsProblem = blockPos; diff --git a/patches/unapplied/server/0740-Configurable-chat-thread-limit.patch b/patches/server/0736-Configurable-chat-thread-limit.patch similarity index 100% rename from patches/unapplied/server/0740-Configurable-chat-thread-limit.patch rename to patches/server/0736-Configurable-chat-thread-limit.patch diff --git a/patches/unapplied/server/0741-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch b/patches/server/0737-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch similarity index 100% rename from patches/unapplied/server/0741-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch rename to patches/server/0737-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch diff --git a/patches/unapplied/server/0742-fix-Jigsaw-block-kicking-user.patch b/patches/server/0738-fix-Jigsaw-block-kicking-user.patch similarity index 80% rename from patches/unapplied/server/0742-fix-Jigsaw-block-kicking-user.patch rename to patches/server/0738-fix-Jigsaw-block-kicking-user.patch index 6e1aef94c824..a7960e5bc324 100644 --- a/patches/unapplied/server/0742-fix-Jigsaw-block-kicking-user.patch +++ b/patches/server/0738-fix-Jigsaw-block-kicking-user.patch @@ -5,14 +5,14 @@ Subject: [PATCH] fix Jigsaw block kicking user diff --git a/src/main/java/net/minecraft/world/level/block/entity/JigsawBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/JigsawBlockEntity.java -index 0083602f8c8826e247fecbdb5cdb6548ff6180ce..675f6b2932e036d2eedf065fd2db4bf9f0e4250d 100644 +index 42300114e3baf31fd26090fca3b497c8157d4bb9..8fda7f812ba266cf8051f6796d2c35cba197e904 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/JigsawBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/JigsawBlockEntity.java -@@ -137,7 +137,12 @@ public class JigsawBlockEntity extends BlockEntity { +@@ -131,7 +131,12 @@ public class JigsawBlockEntity extends BlockEntity { public void generate(ServerLevel world, int maxDepth, boolean keepJigsaws) { BlockPos blockPos = this.getBlockPos().relative(this.getBlockState().getValue(JigsawBlock.ORIENTATION).front()); - Registry registry = world.registryAccess().registryOrThrow(Registries.TEMPLATE_POOL); -- Holder holder = registry.getHolderOrThrow(this.pool); + Registry registry = world.registryAccess().lookupOrThrow(Registries.TEMPLATE_POOL); +- Holder holder = registry.getOrThrow(this.pool); + // Paper start - Replace getHolderOrThrow with a null check + Holder holder = registry.getHolder(this.pool).orElse(null); + if (holder == null) { diff --git a/patches/unapplied/server/0743-use-BlockFormEvent-for-mud-converting-into-clay.patch b/patches/server/0739-use-BlockFormEvent-for-mud-converting-into-clay.patch similarity index 92% rename from patches/unapplied/server/0743-use-BlockFormEvent-for-mud-converting-into-clay.patch rename to patches/server/0739-use-BlockFormEvent-for-mud-converting-into-clay.patch index 8653ffd78625..3159c4b594c3 100644 --- a/patches/unapplied/server/0743-use-BlockFormEvent-for-mud-converting-into-clay.patch +++ b/patches/server/0739-use-BlockFormEvent-for-mud-converting-into-clay.patch @@ -5,10 +5,10 @@ Subject: [PATCH] use BlockFormEvent for mud converting into clay diff --git a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java -index 95cb7492ac691a8e8aa9894f701b802a7eda5446..a2bd54dae4b0460d200f6d5300194a7ef5a28830 100644 +index bd38a0a73d543a85bb5c6d50219f5438ce194df3..53cea36ec931de89e0060613acf87beb51dc16ec 100644 --- a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java -@@ -215,10 +215,13 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate +@@ -219,10 +219,13 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate if (((PointedDripstoneBlock.FluidInfo) optional.get()).sourceState.is(Blocks.MUD) && fluidtype == Fluids.WATER) { BlockState iblockdata1 = Blocks.CLAY.defaultBlockState(); diff --git a/patches/unapplied/server/0744-Add-getDrops-to-BlockState.patch b/patches/server/0740-Add-getDrops-to-BlockState.patch similarity index 100% rename from patches/unapplied/server/0744-Add-getDrops-to-BlockState.patch rename to patches/server/0740-Add-getDrops-to-BlockState.patch diff --git a/patches/unapplied/server/0745-Fix-a-bunch-of-vanilla-bugs.patch b/patches/server/0741-Fix-a-bunch-of-vanilla-bugs.patch similarity index 72% rename from patches/unapplied/server/0745-Fix-a-bunch-of-vanilla-bugs.patch rename to patches/server/0741-Fix-a-bunch-of-vanilla-bugs.patch index 7813123f4940..f21808be3a25 100644 --- a/patches/unapplied/server/0745-Fix-a-bunch-of-vanilla-bugs.patch +++ b/patches/server/0741-Fix-a-bunch-of-vanilla-bugs.patch @@ -91,11 +91,11 @@ index 6854ca4d4fec2b4fa541c3fabf63787665572609..e7b444a10b244828827b3c66c5346520 } diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 071e9ef3680c5dc492c6142ccd05f6788ebc3035..61fda6927f060cdf8bcfddaaa08bbbe2c514c630 100644 +index 7f18146c0dea654c62b3e01e6848fd1c05f87946..1a724f9bb6ef82a0b5fdd9ade036d7365167f14b 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1027,7 +1027,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - // CraftBukkit end +@@ -1080,7 +1080,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + } - boolean anyPlayerCloseEnoughForSpawning(ChunkPos pos) { @@ -104,12 +104,12 @@ index 071e9ef3680c5dc492c6142ccd05f6788ebc3035..61fda6927f060cdf8bcfddaaa08bbbe2 return this.anyPlayerCloseEnoughForSpawning(pos, false); } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index b88a7f580b4138ceb262f3d398e78fdc2e6b018c..1edad85fc5c199dcab66497fa758e48dd14aec8c 100644 +index 100661b77466152a651d22daa7df992c28fbbecb..79fabd52eb3a08ec9c9ab2ec5d6ff4a31a02a292 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -777,7 +777,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -764,7 +764,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } else { - AABB axisalignedbb = AABB.encapsulatingFullBlocks(blockposition1, new BlockPos(blockposition1.atY(this.getMaxBuildHeight()))).inflate(3.0D); + AABB axisalignedbb = AABB.encapsulatingFullBlocks(blockposition1, blockposition1.atY(this.getMaxY() + 1)).inflate(3.0D); List list = this.getEntitiesOfClass(LivingEntity.class, axisalignedbb, (entityliving) -> { - return entityliving != null && entityliving.isAlive() && this.canSeeSky(entityliving.blockPosition()); + return entityliving != null && entityliving.isAlive() && this.canSeeSky(entityliving.blockPosition()) && !entityliving.isSpectator(); // Paper - Fix lightning being able to hit spectators (MC-262422) @@ -117,10 +117,10 @@ index b88a7f580b4138ceb262f3d398e78fdc2e6b018c..1edad85fc5c199dcab66497fa758e48d if (!list.isEmpty()) { diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index 6abecaac8407b992d208a9108e11fd4954a4106f..03d89f326d320c5d778c3d1e2db7d6b88753faec 100644 +index 064a7a3e1c4d192010e072a5e985a54135748d87..a706f0855fdf88cc9aece3ba00ef574b9cd8bd11 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -93,7 +93,7 @@ public class ServerPlayerGameMode { +@@ -91,7 +91,7 @@ public class ServerPlayerGameMode { return event; // Paper - Expand PlayerGameModeChangeEvent } // CraftBukkit end @@ -130,23 +130,23 @@ index 6abecaac8407b992d208a9108e11fd4954a4106f..03d89f326d320c5d778c3d1e2db7d6b8 this.player.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, this.player), this.player); // CraftBukkit this.level.updateSleepingPlayerList(); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index ca32e5aa6e77ca1bab886e7b6a778ec931ac4e4c..28808ffc6e486f7dc01be370c9eb249dc1f7ea46 100644 +index 5f567d6a8ac93113c2f57d38736c4891c5f9ae19..6c7c6cd7c071b722faf7ec06e022a6ad8b1ecc42 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1814,7 +1814,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - } else if (enuminteractionresult.shouldSwing() && !this.player.gameMode.interactResult) { // Paper - Call interact event - this.player.swing(enumhand, true); +@@ -1823,7 +1823,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + this.player.swing(enumhand, true); + } } - } + } else { this.player.containerMenu.sendAllDataToRemote(); } // Paper - Fix inventory desync; MC-99075 } else { - MutableComponent ichatmutablecomponent1 = Component.translatable("build.tooHigh", i - 1).withStyle(ChatFormatting.RED); + MutableComponent ichatmutablecomponent1 = Component.translatable("build.tooHigh", i).withStyle(ChatFormatting.RED); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 03572023ae7f061bf34fed8ac27852e08d6412c0..38b9ab369e25e4b718418375f76e782283b48411 100644 +index f0ce0041497d038c55019e0f5a8e8b8619cec398..8e71eeb5be2df1352447f3662a6d092a7db9e2d0 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -260,7 +260,7 @@ public abstract class PlayerList { +@@ -261,7 +261,7 @@ public abstract class PlayerList { } if (optional.isEmpty() || invalidPlayerWorld[0]) { // Paper end - reset to main world spawn if first spawn or invalid world @@ -155,7 +155,7 @@ index 03572023ae7f061bf34fed8ac27852e08d6412c0..38b9ab369e25e4b718418375f76e7822 } // Paper end - Entity#getEntitySpawnReason player.setServerLevel(worldserver1); -@@ -703,8 +703,10 @@ public abstract class PlayerList { +@@ -661,8 +661,10 @@ public abstract class PlayerList { Player player = entity.getBukkitEntity(); PlayerLoginEvent event = new PlayerLoginEvent(player, loginlistener.connection.hostname, ((java.net.InetSocketAddress) socketaddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.connection.channel.remoteAddress()).getAddress()); @@ -169,10 +169,10 @@ index 03572023ae7f061bf34fed8ac27852e08d6412c0..38b9ab369e25e4b718418375f76e7822 ichatmutablecomponent = Component.translatable("multiplayer.disconnect.banned.reason", gameprofilebanentry.getReason()); if (gameprofilebanentry.getExpires() != null) { diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java -index 784a894688f98f9d0368a36d456c5c94e1ee3695..a85885ee51df585fa11ae9f8fcd67ff2a71c5a18 100644 +index 6827426e6e9706909265f84bf97b5fa7105a7fea..7324da6b7dd2623ce394e3827ff77ef684a3b98b 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java -@@ -77,9 +77,10 @@ public class BreakDoorGoal extends DoorInteractGoal { +@@ -78,9 +78,10 @@ public class BreakDoorGoal extends DoorInteractGoal { return; } // CraftBukkit end @@ -185,7 +185,7 @@ index 784a894688f98f9d0368a36d456c5c94e1ee3695..a85885ee51df585fa11ae9f8fcd67ff2 } diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java -index d802985f1431be4332c07f0dab88feebedea4ce2..4e2c23ccdf4e4a4d65b291dbe20952bae1838bff 100644 +index 9e6f946e6d2878aa3fa8abe0f6fa4770d18676d3..32bb591371fe78ba10a2bc52389ef33978cbc0eb 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java @@ -31,6 +31,11 @@ public class EatBlockGoal extends Goal { @@ -219,26 +219,26 @@ index ef71b3ef4444c05b4211de87e1c8ec52cbe3e72a..137ec75ee803789deb7b1ca93dd9369c public void start() { this.creeper.getNavigation().stop(); diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java -index 923806900ef6248576e71260d40e9caf2c8943e8..02e49c7ae5e120302b6479cf3e3934b9217eebf0 100644 +index dbcf14f5af9c9c0655a82529ee99450a8da14525..f745a554b9b84a53d9bd942ca9908153fb0a668c 100644 --- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java +++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java -@@ -243,9 +243,10 @@ public class Goat extends Animal { +@@ -247,9 +247,10 @@ public class Goat extends Animal { player.setItemInHand(hand, itemstack1); - return InteractionResult.sidedSuccess(this.level().isClientSide); + return InteractionResult.SUCCESS; } else { + boolean isFood = this.isFood(itemstack); // Paper - track before stack is possibly decreased to 0 (Fixes MC-244739) InteractionResult enuminteractionresult = super.mobInteract(player, hand); - if (enuminteractionresult.consumesAction() && this.isFood(itemstack)) { + if (enuminteractionresult.consumesAction() && isFood) { // Paper - this.level().playSound((Player) null, (Entity) this, this.getEatingSound(itemstack), SoundSource.NEUTRAL, 1.0F, Mth.randomBetween(this.level().random, 0.8F, 1.2F)); + this.playEatingSound(); } diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -index 3c6edc5ea44b7ec15d8fc7a2dca95a11a0d6108a..ba4e0ad7c7c2731d61ec7f60f19d7e9ec31a28ba 100644 +index 30af4cbb17148c247a46c0346419d6c838dbc9d2..07c143c3eac263848fc5daf6f958d16a1a163e92 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -@@ -260,6 +260,14 @@ public class ItemFrame extends HangingEntity { +@@ -272,6 +272,14 @@ public class ItemFrame extends HangingEntity { return (ItemStack) this.getEntityData().get(ItemFrame.DATA_ITEM); } @@ -251,10 +251,10 @@ index 3c6edc5ea44b7ec15d8fc7a2dca95a11a0d6108a..ba4e0ad7c7c2731d61ec7f60f19d7e9e + // Paper end + @Nullable - public MapId getFramedMapId(ItemStack itemstack) { - return (MapId) itemstack.get(DataComponents.MAP_ID); + public MapId getFramedMapId(ItemStack stack) { + return (MapId) stack.get(DataComponents.MAP_ID); diff --git a/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java b/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java -index 08dcc94c9eca9a5fd61055f05b7737ba5840b5bf..e0e5046c84941a8d17e18c177f3daea9cb631940 100644 +index 15a1ea01917ce57c2457094186dde937c21ffb22..b0236c7bf9441aa84d3795ffed05dd6099f29636 100644 --- a/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java +++ b/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java @@ -82,8 +82,8 @@ public class CatSpawner implements CustomSpawner { @@ -262,16 +262,16 @@ index 08dcc94c9eca9a5fd61055f05b7737ba5840b5bf..e0e5046c84941a8d17e18c177f3daea9 return 0; } else { + cat.moveTo(pos, 0.0F, 0.0F); // Paper - move up - Fix MC-147659 - cat.finalizeSpawn(world, world.getCurrentDifficultyAt(pos), MobSpawnType.NATURAL, null); + cat.finalizeSpawn(world, world.getCurrentDifficultyAt(pos), EntitySpawnReason.NATURAL, null); - cat.moveTo(pos, 0.0F, 0.0F); world.addFreshEntityWithPassengers(cat); return 1; } diff --git a/src/main/java/net/minecraft/world/inventory/BeaconMenu.java b/src/main/java/net/minecraft/world/inventory/BeaconMenu.java -index 396559c281eee9e8c677cb222721414e8d9e12a2..8b0ebf659f6b219ce2a5d10b0d79f9b89b47c911 100644 +index cad0b581c992edc5cd312a727695a443e26e96d8..9db647cfbd3f9c884465cf3d3a1b911d46a3da58 100644 --- a/src/main/java/net/minecraft/world/inventory/BeaconMenu.java +++ b/src/main/java/net/minecraft/world/inventory/BeaconMenu.java -@@ -178,6 +178,11 @@ public class BeaconMenu extends AbstractContainerMenu { +@@ -164,6 +164,11 @@ public class BeaconMenu extends AbstractContainerMenu { // Paper end - Add PlayerChangeBeaconEffectEvent public void updateEffects(Optional> primary, Optional> secondary) { @@ -283,43 +283,27 @@ index 396559c281eee9e8c677cb222721414e8d9e12a2..8b0ebf659f6b219ce2a5d10b0d79f9b8 if (this.paymentSlot.hasItem()) { // Paper start - Add PlayerChangeBeaconEffectEvent io.papermc.paper.event.player.PlayerChangeBeaconEffectEvent event = new io.papermc.paper.event.player.PlayerChangeBeaconEffectEvent((org.bukkit.entity.Player) this.player.player.getBukkitEntity(), convert(primary), convert(secondary), this.access.getLocation().getBlock()); -diff --git a/src/main/java/net/minecraft/world/level/block/AzaleaBlock.java b/src/main/java/net/minecraft/world/level/block/AzaleaBlock.java -index cd90129be2cf8095abd80528e5de3bbe05022a9d..fad69dfc20574ab23634b14252b50929cca75b21 100644 ---- a/src/main/java/net/minecraft/world/level/block/AzaleaBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/AzaleaBlock.java -@@ -51,4 +51,11 @@ public class AzaleaBlock extends BushBlock implements BonemealableBlock { - public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { - TreeGrower.AZALEA.growTree(world, world.getChunkSource().getGenerator(), pos, state, random); - } -+ -+ // Paper start - Fix MC-224454 -+ @Override -+ public boolean isPathfindable(BlockState state, net.minecraft.world.level.pathfinder.PathComputationType type) { -+ return false; -+ } -+ // Paper end - } diff --git a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java -index fa5366961861370c2366e6f0ff026a6d65128316..a5c7c2d24498c66159316a4f92677625975ce5ca 100644 +index 7dd6b7c0ea472cfbc7ece55bc64bc5d85be4a6c0..6dcb571e9f35fbae724be69dc113b0c33eca63b3 100644 --- a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java +++ b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java -@@ -69,7 +69,7 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock { - if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (!world.isClientSide && entity.isOnFire() && this.isEntityInsideContent(state, pos, entity)) { - // CraftBukkit start -- if (entity.mayInteract(world, pos)) { -+ if ((entity instanceof net.minecraft.world.entity.player.Player || world.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING)) && entity.mayInteract(world, pos)) { // Paper - Fixes MC-248588 - if (!this.handleEntityOnFireInsideWithEvent(state, world, pos, entity)) { // Paper - fix powdered snow cauldron extinguishing entities - return; - } +@@ -72,7 +72,7 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock { + if (entity.isOnFire() && this.isEntityInsideContent(state, pos, entity)) { + // CraftBukkit start - moved down + // entity.clearFire(); +- if (entity.mayInteract(worldserver, pos)) { ++ if ((entity instanceof net.minecraft.world.entity.player.Player || worldserver.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING)) && entity.mayInteract(worldserver, pos)) { // Paper - Fixes MC-248588 + if (this.handleEntityOnFireInsideWithEvent(state, world, pos, entity)) { // Paper - fix powdered snow cauldron extinguishing entities + entity.clearFire(); + } diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index aa59a45bcbe652996eddb80a3187618b7f6d1234..f1a7054a0ee1842e78338d8984f151b24c352849 100644 +index a23a87da259ab8d28dd8d8513098cd0730e72e0c..18f8b2c469feef659437684ce156a79ec3a3ce83 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -@@ -648,13 +648,10 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -531,13 +531,10 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit @Override - public void fillStackedContents(StackedContents finder) { + public void fillStackedContents(StackedItemContents finder) { - Iterator iterator = this.items.iterator(); - - while (iterator.hasNext()) { @@ -335,7 +319,7 @@ index aa59a45bcbe652996eddb80a3187618b7f6d1234..f1a7054a0ee1842e78338d8984f151b2 } } diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -index e124f040386e130aebd7135434c4f06d130d28f6..f8d432ef21e59796da4b11c9748ba151c54e5e04 100644 +index 8aab6f68f576fb022eb59798585e264f5aafbc69..edd6017937a7f20a1b43fa15204ec130b524b52b 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java @@ -295,7 +295,11 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name @@ -351,35 +335,42 @@ index e124f040386e130aebd7135434c4f06d130d28f6..f8d432ef21e59796da4b11c9748ba151 } diff --git a/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java b/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java -index 055f4b87c01ee7ecf7d2a111b72cc5aa85d9fbe8..6684ded7135f943f8cea954b417f596369215357 100644 +index e64a30577e9000e5c4d22fd3d9cf8a9381c5c459..b9690f31d410e82d833b2ca805df2fa68abcb6d1 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java +++ b/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java -@@ -100,13 +100,13 @@ public class TrialSpawnerData { +@@ -101,17 +101,19 @@ public class TrialSpawnerData { this.ejectingLootTable = rewardLootTable; } - public void reset() { + public void reset(TrialSpawner logic) { // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 + this.currentMobs.clear(); + this.nextSpawnData = Optional.empty(); +- this.resetStatistics(); ++ this.resetStatistics(logic); + } + +- public void resetStatistics() { ++ public void resetStatistics(TrialSpawner logic) { // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 this.detectedPlayers.clear(); this.totalMobsSpawned = 0; this.nextMobSpawnsAt = 0L; this.cooldownEndsAt = 0L; - this.currentMobs.clear(); -- this.nextSpawnData = Optional.empty(); ++ this.nextSpawnData = Optional.empty(); + if (!logic.getConfig().spawnPotentialsDefinition().isEmpty()) this.nextSpawnData = Optional.empty(); // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 } public boolean hasMobToSpawn(TrialSpawner logic, RandomSource random) { diff --git a/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java b/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java -index ffabcfaef8defe932473dee515f05220921904e0..005aea8a747e9cbbc352b8b57c64b84ec71ad321 100644 +index 83cdeee5e2ce115ff696a5afc5465dc4301779b9..027d5c4117feba1e152d0ecf9923aef77ba72207 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java +++ b/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java @@ -68,7 +68,7 @@ public enum TrialSpawnerState implements StringRepresentable { case INACTIVE -> trialSpawnerData.getOrCreateDisplayEntity(logic, world, WAITING_FOR_PLAYERS) == null ? this : WAITING_FOR_PLAYERS; case WAITING_FOR_PLAYERS -> { if (!logic.canSpawnInLevel(world)) { -- trialSpawnerData.reset(); -+ trialSpawnerData.reset(logic); // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 +- trialSpawnerData.resetStatistics(); ++ trialSpawnerData.resetStatistics(logic); // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 yield this; } else if (!trialSpawnerData.hasMobToSpawn(logic, world.random)) { yield INACTIVE; @@ -387,8 +378,8 @@ index ffabcfaef8defe932473dee515f05220921904e0..005aea8a747e9cbbc352b8b57c64b84e } case ACTIVE -> { if (!logic.canSpawnInLevel(world)) { -- trialSpawnerData.reset(); -+ trialSpawnerData.reset(logic); // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 +- trialSpawnerData.resetStatistics(); ++ trialSpawnerData.resetStatistics(logic); // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 yield WAITING_FOR_PLAYERS; } else if (!trialSpawnerData.hasMobToSpawn(logic, world.random)) { yield INACTIVE; @@ -401,25 +392,3 @@ index ffabcfaef8defe932473dee515f05220921904e0..005aea8a747e9cbbc352b8b57c64b84e yield WAITING_FOR_PLAYERS; } else { yield this; -diff --git a/src/main/java/net/minecraft/world/level/portal/DimensionTransition.java b/src/main/java/net/minecraft/world/level/portal/DimensionTransition.java -index 1595a379875abc718659f6b1ce7c64c6383b1bc8..788f79dc38012595b385ee6a449daa0bccf0079a 100644 ---- a/src/main/java/net/minecraft/world/level/portal/DimensionTransition.java -+++ b/src/main/java/net/minecraft/world/level/portal/DimensionTransition.java -@@ -39,7 +39,7 @@ public record DimensionTransition(ServerLevel newLevel, Vec3 pos, Vec3 speed, fl - } - - public DimensionTransition(ServerLevel worldserver, Entity entity, DimensionTransition.PostDimensionTransition dimensiontransition_a, PlayerTeleportEvent.TeleportCause cause) { -- this(worldserver, findAdjustedSharedSpawnPos(worldserver, entity), Vec3.ZERO, 0.0F, 0.0F, false, dimensiontransition_a, cause); -+ this(worldserver, findAdjustedSharedSpawnPos(worldserver, entity), Vec3.ZERO, worldserver.getSharedSpawnAngle(), 0.0F, false, dimensiontransition_a, cause); // Paper - MC-200092 - fix spawn pos yaw being ignored - // CraftBukkit end - } - -@@ -55,7 +55,7 @@ public record DimensionTransition(ServerLevel newLevel, Vec3 pos, Vec3 speed, fl - } - - public static DimensionTransition missingRespawnBlock(ServerLevel world, Entity entity, DimensionTransition.PostDimensionTransition postDimensionTransition) { -- return new DimensionTransition(world, findAdjustedSharedSpawnPos(world, entity), Vec3.ZERO, 0.0F, 0.0F, true, postDimensionTransition); -+ return new DimensionTransition(world, findAdjustedSharedSpawnPos(world, entity), Vec3.ZERO, world.getSharedSpawnAngle(), 0.0F, true, postDimensionTransition); // Paper - MC-200092 - fix spawn pos yaw being ignored - } - - private static Vec3 findAdjustedSharedSpawnPos(ServerLevel world, Entity entity) { diff --git a/patches/unapplied/server/0746-Remove-unnecessary-onTrackingStart-during-navigation.patch b/patches/server/0742-Remove-unnecessary-onTrackingStart-during-navigation.patch similarity index 84% rename from patches/unapplied/server/0746-Remove-unnecessary-onTrackingStart-during-navigation.patch rename to patches/server/0742-Remove-unnecessary-onTrackingStart-during-navigation.patch index 104738383c0a..9cef4dcb920a 100644 --- a/patches/unapplied/server/0746-Remove-unnecessary-onTrackingStart-during-navigation.patch +++ b/patches/server/0742-Remove-unnecessary-onTrackingStart-during-navigation.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Remove unnecessary onTrackingStart during navigation warning diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index d3707c3fabc09068f3b07edebe9a333c153dfab5..4bf6281a75597072b19658208e4447c4d1ee8ba2 100644 +index 79fabd52eb3a08ec9c9ab2ec5d6ff4a31a02a292..4b2309d27867eddc50093e895503e02184e1b825 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2186,7 +2186,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2267,7 +2267,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } if (entity instanceof Mob entityinsentient) { @@ -17,7 +17,7 @@ index d3707c3fabc09068f3b07edebe9a333c153dfab5..4bf6281a75597072b19658208e4447c4 String s = "onTrackingStart called during navigation iteration"; Util.logAndPauseIfInIde("onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")); -@@ -2266,7 +2266,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2347,7 +2347,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } if (entity instanceof Mob entityinsentient) { diff --git a/patches/unapplied/server/0747-Fix-custom-piglin-loved-items.patch b/patches/server/0743-Fix-custom-piglin-loved-items.patch similarity index 90% rename from patches/unapplied/server/0747-Fix-custom-piglin-loved-items.patch rename to patches/server/0743-Fix-custom-piglin-loved-items.patch index a09a51f7ea71..358bd47f1e72 100644 --- a/patches/unapplied/server/0747-Fix-custom-piglin-loved-items.patch +++ b/patches/server/0743-Fix-custom-piglin-loved-items.patch @@ -7,10 +7,10 @@ Upstream didn't modify the isLovedItem check in wantsToPickup so piglins never actually tried to pickup interestItems diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java -index d601bff8e8f62af78791ad357b51b92faf04e55f..d3d50ec0f4466464c048449d8a844569c447d59b 100644 +index 4f3048615a34fc2c067e09aec76af94cde6a74e0..5c26beef2d3f3d4afa51950ddeb7089989218462 100644 --- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java +++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java -@@ -403,7 +403,7 @@ public class PiglinAi { +@@ -405,7 +405,7 @@ public class PiglinAi { } else { boolean flag = piglin.canAddToInventory(stack); diff --git a/patches/server/0744-EntityPickupItemEvent-fixes.patch b/patches/server/0744-EntityPickupItemEvent-fixes.patch new file mode 100644 index 000000000000..6e30e2ebcbe9 --- /dev/null +++ b/patches/server/0744-EntityPickupItemEvent-fixes.patch @@ -0,0 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Mon, 4 Jul 2022 21:45:36 -0700 +Subject: [PATCH] EntityPickupItemEvent fixes + +Fixes double firing of the event in PiglinAi + +Fixes cancelling the event for piglins still triggering the +advancement trigger + +Fires the event when a Raider tries to pick up a raid banner +to become raid leader. + +diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java +index 15a49e3541c8b45db5e472a64fa0cb94c5a72f67..e04d2c5e75dc774fe893a552474fdb8045c32693 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java ++++ b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java +@@ -429,7 +429,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento + + @Override + protected void pickUpItem(ServerLevel world, ItemEntity itemEntity) { +- this.onItemPickup(itemEntity); ++ // this.onItemPickup(itemEntity); // Paper - EntityPickupItemEvent fixes; call in PiglinAi#pickUpItem after EntityPickupItemEvent is fired + PiglinAi.pickUpItem(world, this, itemEntity); + } + +diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java +index 5c26beef2d3f3d4afa51950ddeb7089989218462..e283b1296c1e831376bfe9491cbf02ed4b3fffe4 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java ++++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java +@@ -244,11 +244,16 @@ public class PiglinAi { + ItemStack itemstack; + + // CraftBukkit start +- if (itemEntity.getItem().is(Items.GOLD_NUGGET) && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, itemEntity, 0, false).isCancelled()) { ++ // Paper start - EntityPickupItemEvent fixes; fix event firing twice ++ if (itemEntity.getItem().is(Items.GOLD_NUGGET)/* && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, itemEntity, 0, false).isCancelled()*/) { // Paper ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, itemEntity, 0, false).isCancelled()) return; ++ piglin.onItemPickup(itemEntity); // Paper - moved from Piglin#pickUpItem - call prior to item entity modification ++ // Paper end + piglin.take(itemEntity, itemEntity.getItem().getCount()); + itemstack = itemEntity.getItem(); + itemEntity.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + } else if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, itemEntity, itemEntity.getItem().getCount() - 1, false).isCancelled()) { ++ piglin.onItemPickup(itemEntity); // Paper - EntityPickupItemEvent fixes; moved from Piglin#pickUpItem - call prior to item entity modification + piglin.take(itemEntity, 1); + itemstack = PiglinAi.removeOneItemFromItemEntity(itemEntity); + } else { +@@ -263,7 +268,7 @@ public class PiglinAi { + } else if (PiglinAi.isFood(itemstack) && !PiglinAi.hasEatenRecently(piglin)) { + PiglinAi.eat(piglin); + } else { +- boolean flag = !piglin.equipItemIfPossible(world, itemstack, itemEntity).equals(ItemStack.EMPTY); // CraftBukkit ++ boolean flag = !piglin.equipItemIfPossible(world, itemstack, null).equals(ItemStack.EMPTY); // CraftBukkit // Paper - pass null item entity to prevent duplicate pickup item event call - called above. + + if (!flag) { + PiglinAi.putInInventory(piglin, itemstack); +diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java +index 69a0a8aa7eec0a68a1460f6d6a4b604963b884c4..02f2107285d1bbe2137afd4f94880ad1f9d82fb9 100644 +--- a/src/main/java/net/minecraft/world/entity/raid/Raider.java ++++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java +@@ -228,6 +228,11 @@ public abstract class Raider extends PatrollingMonster { + boolean flag = this.hasActiveRaid() && this.getCurrentRaid().getLeader(this.getWave()) != null; + + if (this.hasActiveRaid() && !flag && ItemStack.matches(itemstack, Raid.getOminousBannerInstance(this.registryAccess().lookupOrThrow(Registries.BANNER_PATTERN)))) { ++ // Paper start - EntityPickupItemEvent fixes ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, item, 0, false).isCancelled()) { ++ return; ++ } ++ // Paper end - EntityPickupItemEvent fixes + EquipmentSlot enumitemslot = EquipmentSlot.HEAD; + ItemStack itemstack1 = this.getItemBySlot(enumitemslot); + double d0 = (double) this.getEquipmentDropChance(enumitemslot); diff --git a/patches/unapplied/server/0749-Correctly-handle-interactions-with-items-on-cooldown.patch b/patches/server/0745-Correctly-handle-interactions-with-items-on-cooldown.patch similarity index 87% rename from patches/unapplied/server/0749-Correctly-handle-interactions-with-items-on-cooldown.patch rename to patches/server/0745-Correctly-handle-interactions-with-items-on-cooldown.patch index b7fa362a4bce..fe489a8bd842 100644 --- a/patches/unapplied/server/0749-Correctly-handle-interactions-with-items-on-cooldown.patch +++ b/patches/server/0745-Correctly-handle-interactions-with-items-on-cooldown.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Correctly handle interactions with items on cooldown diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index 03d89f326d320c5d778c3d1e2db7d6b88753faec..717d015dd4637dd9d568b751be1dc1046b0a0560 100644 +index a706f0855fdf88cc9aece3ba00ef574b9cd8bd11..2aee9c2fbe38076317a3de7c3fdbd6988b64b389 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -514,6 +514,7 @@ public class ServerPlayerGameMode { +@@ -520,6 +520,7 @@ public class ServerPlayerGameMode { BlockPos blockposition = hitResult.getBlockPos(); BlockState iblockdata = world.getBlockState(blockposition); boolean cancelledBlock = false; @@ -16,10 +16,10 @@ index 03d89f326d320c5d778c3d1e2db7d6b88753faec..717d015dd4637dd9d568b751be1dc104 if (!iblockdata.getBlock().isEnabled(world.enabledFeatures())) { return InteractionResult.FAIL; -@@ -523,10 +524,10 @@ public class ServerPlayerGameMode { +@@ -529,10 +530,10 @@ public class ServerPlayerGameMode { } - if (player.getCooldowns().isOnCooldown(stack.getItem())) { + if (player.getCooldowns().isOnCooldown(stack)) { - cancelledBlock = true; + cancelledItem = true; // Paper - correctly handle items on cooldown } @@ -30,10 +30,10 @@ index 03d89f326d320c5d778c3d1e2db7d6b88753faec..717d015dd4637dd9d568b751be1dc104 this.interactResult = event.useItemInHand() == Event.Result.DENY; this.interactPosition = blockposition.immutable(); diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index ba1599b733946bef468a9b006411f8827844e791..b6cca72b4785d5cf009077c81c1cca718d8cfe28 100644 +index f7e26e381c2a2fec70cc2df01a12e7dbeeab48cd..cb05a94f2856a8bfb478bceb7c8712bc5e7ad5c2 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -556,6 +556,12 @@ public class CraftEventFactory { +@@ -555,6 +555,12 @@ public class CraftEventFactory { } public static PlayerInteractEvent callPlayerInteractEvent(net.minecraft.world.entity.player.Player who, Action action, BlockPos position, Direction direction, ItemStack itemstack, boolean cancelledBlock, InteractionHand hand, Vec3 targetPos) { @@ -46,7 +46,7 @@ index ba1599b733946bef468a9b006411f8827844e791..b6cca72b4785d5cf009077c81c1cca71 Player player = (who == null) ? null : (Player) who.getBukkitEntity(); CraftItemStack itemInHand = CraftItemStack.asCraftMirror(itemstack); -@@ -590,6 +596,11 @@ public class CraftEventFactory { +@@ -589,6 +595,11 @@ public class CraftEventFactory { if (cancelledBlock) { event.setUseInteractedBlock(Event.Result.DENY); } diff --git a/patches/unapplied/server/0750-Add-PlayerInventorySlotChangeEvent.patch b/patches/server/0746-Add-PlayerInventorySlotChangeEvent.patch similarity index 91% rename from patches/unapplied/server/0750-Add-PlayerInventorySlotChangeEvent.patch rename to patches/server/0746-Add-PlayerInventorySlotChangeEvent.patch index 0f6a75faa355..74685096a5a8 100644 --- a/patches/unapplied/server/0750-Add-PlayerInventorySlotChangeEvent.patch +++ b/patches/server/0746-Add-PlayerInventorySlotChangeEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerInventorySlotChangeEvent diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index ad3896dd524acb573adffdfb38b13dd699539cef..3dbaa3c6b75a0f8bfdef42d210f2ac6f560cde3d 100644 +index f87f12666d4708b7fb7ede3eff03570fed8d1f40..bb0aaa16f0de18b15764ba39a781e8b86d690bb9 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -352,6 +352,25 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -381,6 +381,25 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } } @@ -35,10 +35,10 @@ index ad3896dd524acb573adffdfb38b13dd699539cef..3dbaa3c6b75a0f8bfdef42d210f2ac6f @Override public void dataChanged(AbstractContainerMenu handler, int property, int value) {} diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -index b8d8aad81f54f7f43c01da075e63ec9173750bec..f7b9849819c185cd89533aca1f6d34398ffc1077 100644 +index 3b92fb173f623a05ae99c86d98f2ecdf907f58c4..d830504d08c9de92797c432a868c1ee9dfc46a91 100644 --- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -@@ -302,7 +302,7 @@ public abstract class AbstractContainerMenu { +@@ -330,7 +330,7 @@ public abstract class AbstractContainerMenu { while (iterator.hasNext()) { ContainerListener icrafting = (ContainerListener) iterator.next(); diff --git a/patches/unapplied/server/0751-Elder-Guardian-appearance-API.patch b/patches/server/0747-Elder-Guardian-appearance-API.patch similarity index 84% rename from patches/unapplied/server/0751-Elder-Guardian-appearance-API.patch rename to patches/server/0747-Elder-Guardian-appearance-API.patch index fd1cef6a094f..c354816072dd 100644 --- a/patches/unapplied/server/0751-Elder-Guardian-appearance-API.patch +++ b/patches/server/0747-Elder-Guardian-appearance-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Elder Guardian appearance API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 3374dcd3b1f22b6c1803b9580c4cea6552b6afb1..1e563ed8f7e85d68682e679b27b0f6100eb10aea 100644 +index 025c392f2ca89a87f6301d4af64c4d7daec58409..1dc5f21c337bc3fb67e5919308228d75b03989d1 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3298,6 +3298,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3311,6 +3311,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end diff --git a/patches/unapplied/server/0752-Add-entity-knockback-API.patch b/patches/server/0748-Add-entity-knockback-API.patch similarity index 86% rename from patches/unapplied/server/0752-Add-entity-knockback-API.patch rename to patches/server/0748-Add-entity-knockback-API.patch index b50878265dbb..71f4427274ab 100644 --- a/patches/unapplied/server/0752-Add-entity-knockback-API.patch +++ b/patches/server/0748-Add-entity-knockback-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add entity knockback API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 877e3d20edba3fe2ea6b51d0b54ec8893bd112ed..2a7fffa71106327d0ffee632408d45faaec76702 100644 +index 14b4c3835388d957653ba34444968bb718ce7f68..4fa19ddb1414282020e118eea298d57d2bf42754 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -1127,4 +1127,12 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -1146,4 +1146,12 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { throw new UnsupportedOperationException("Cannot set the hurt direction on a non player"); } // Paper end - hurt direction API diff --git a/patches/unapplied/server/0753-Detect-headless-JREs.patch b/patches/server/0749-Detect-headless-JREs.patch similarity index 96% rename from patches/unapplied/server/0753-Detect-headless-JREs.patch rename to patches/server/0749-Detect-headless-JREs.patch index 5ba28913a820..e680b6146f85 100644 --- a/patches/unapplied/server/0753-Detect-headless-JREs.patch +++ b/patches/server/0749-Detect-headless-JREs.patch @@ -27,7 +27,7 @@ index 68098dfe716e93aafcca4d8d5b5a81d8648b3654..2b7070e0cefa7cf0777df159693750fe + } } diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index 467b8ca8007c5d3a7b72b88e3a979bdf09f1a283..13e1a914d4523f1c192db2a9a1ee6522e0ee27da 100644 +index cf071610ed662c4a309cc26ee73a74fa490d846f..47cd7c66ac37efebf2f63c49d78dd8fe44a70ef8 100644 --- a/src/main/java/net/minecraft/server/Main.java +++ b/src/main/java/net/minecraft/server/Main.java @@ -167,6 +167,18 @@ public class Main { diff --git a/patches/unapplied/server/0754-fix-entity-vehicle-collision-event-not-called.patch b/patches/server/0750-fix-entity-vehicle-collision-event-not-called.patch similarity index 79% rename from patches/unapplied/server/0754-fix-entity-vehicle-collision-event-not-called.patch rename to patches/server/0750-fix-entity-vehicle-collision-event-not-called.patch index e2f922a2a17c..9b38b3208643 100644 --- a/patches/unapplied/server/0754-fix-entity-vehicle-collision-event-not-called.patch +++ b/patches/server/0750-fix-entity-vehicle-collision-event-not-called.patch @@ -5,16 +5,16 @@ Subject: [PATCH] fix entity vehicle collision event not called diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java -index 93634fb01962ca7a35026e3c365f2a7f6b258a39..a38ce400550893f63640e3bb5bb801ab40f06266 100644 +index ee7350e19a86ffa115e4bce6b186a2422951e89b..d8fcd6d1edec1f31a861fab4b86cbeb15ddc799d 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java -@@ -165,7 +165,15 @@ public abstract class AbstractMinecart extends VehicleEntity { +@@ -157,7 +157,15 @@ public abstract class AbstractMinecart extends VehicleEntity { @Override public boolean canCollideWith(Entity other) { -- return Boat.canVehicleCollide(this, other); +- return AbstractBoat.canVehicleCollide(this, other); + // Paper start - fix VehicleEntityCollisionEvent not called when colliding with player -+ boolean collides = Boat.canVehicleCollide(this, other); ++ boolean collides = AbstractBoat.canVehicleCollide(this, other); + if (!collides) { + return false; + } diff --git a/patches/unapplied/server/0755-Add-EntityToggleSitEvent.patch b/patches/server/0751-Add-EntityToggleSitEvent.patch similarity index 79% rename from patches/unapplied/server/0755-Add-EntityToggleSitEvent.patch rename to patches/server/0751-Add-EntityToggleSitEvent.patch index 0ed0b9556227..8b679dd170a2 100644 --- a/patches/unapplied/server/0755-Add-EntityToggleSitEvent.patch +++ b/patches/server/0751-Add-EntityToggleSitEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add EntityToggleSitEvent diff --git a/src/main/java/net/minecraft/world/entity/TamableAnimal.java b/src/main/java/net/minecraft/world/entity/TamableAnimal.java -index 4c5b0b1a71ec5ba0e8dcd5ef52bf667e9bb30be9..87c669517baa923ffa7392e400e7344e81fc9406 100644 +index 550c7f3435cc6c3180769e47f05bf693bdc380e3..e9e4d6fd69f9eec25a75b2610e15a19f8326f87b 100644 --- a/src/main/java/net/minecraft/world/entity/TamableAnimal.java +++ b/src/main/java/net/minecraft/world/entity/TamableAnimal.java -@@ -86,7 +86,7 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity { +@@ -87,7 +87,7 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity { } this.orderedToSit = nbt.getBoolean("Sitting"); @@ -17,7 +17,7 @@ index 4c5b0b1a71ec5ba0e8dcd5ef52bf667e9bb30be9..87c669517baa923ffa7392e400e7344e } @Override -@@ -166,6 +166,12 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity { +@@ -167,6 +167,12 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity { } public void setInSittingPose(boolean inSittingPose) { @@ -31,19 +31,19 @@ index 4c5b0b1a71ec5ba0e8dcd5ef52bf667e9bb30be9..87c669517baa923ffa7392e400e7344e if (inSittingPose) { diff --git a/src/main/java/net/minecraft/world/entity/animal/Fox.java b/src/main/java/net/minecraft/world/entity/animal/Fox.java -index 3265b3b5aede517b6fd8bb836947795bf8881350..9a0adf65d4d54852301a91b6fe444e4c5a139f5d 100644 +index ca45a8ccf7f4593d557d157470603e4d233d948d..d98e4882dcba8a903bc86c8d30b290e6e967cc75 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Fox.java +++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java -@@ -432,7 +432,7 @@ public class Fox extends Animal implements VariantHolder { +@@ -419,7 +419,7 @@ public class Fox extends Animal implements VariantHolder { this.setSleeping(nbt.getBoolean("Sleeping")); - this.setVariant(Fox.Type.byName(nbt.getString("Type"))); + this.setVariant(Fox.Variant.byName(nbt.getString("Type"))); - this.setSitting(nbt.getBoolean("Sitting")); + this.setSitting(nbt.getBoolean("Sitting"), false); // Paper - Add EntityToggleSitEvent this.setIsCrouching(nbt.getBoolean("Crouching")); if (this.level() instanceof ServerLevel) { this.setTargetGoals(); -@@ -445,6 +445,12 @@ public class Fox extends Animal implements VariantHolder { +@@ -432,6 +432,12 @@ public class Fox extends Animal implements VariantHolder { } public void setSitting(boolean sitting) { @@ -57,10 +57,10 @@ index 3265b3b5aede517b6fd8bb836947795bf8881350..9a0adf65d4d54852301a91b6fe444e4c } diff --git a/src/main/java/net/minecraft/world/entity/animal/Panda.java b/src/main/java/net/minecraft/world/entity/animal/Panda.java -index 7b3d5322611990406028e59b1409907291e27b21..293d6891948e99ac9bd741008f7dcbc5fc1a2e3d 100644 +index 4f04170b3ec4ff59358e10ccfd0799af3ab590c3..b654bec0fbe903fac24f3bb99399455bf367c68a 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Panda.java +++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java -@@ -145,6 +145,7 @@ public class Panda extends Animal { +@@ -134,6 +134,7 @@ public class Panda extends Animal { } public void sit(boolean sitting) { @@ -69,10 +69,10 @@ index 7b3d5322611990406028e59b1409907291e27b21..293d6891948e99ac9bd741008f7dcbc5 } diff --git a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java -index aecd17953dc117d369885d4c8d7b5c7c3a0f8f0f..0388b09e1c4f03958384680ed487792a54007463 100644 +index b6baa40dac6d6bf40c4ee7ee75b8a8e6f60733a1..c99d37a40c63726c11980adccc67d09fd5132885 100644 --- a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java +++ b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java -@@ -570,7 +570,7 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Saddl +@@ -572,7 +572,7 @@ public class Camel extends AbstractHorse { } public void sitDown() { @@ -81,7 +81,7 @@ index aecd17953dc117d369885d4c8d7b5c7c3a0f8f0f..0388b09e1c4f03958384680ed487792a this.makeSound(SoundEvents.CAMEL_SIT); this.setPose(Pose.SITTING); this.gameEvent(GameEvent.ENTITY_ACTION); -@@ -579,7 +579,7 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Saddl +@@ -581,7 +581,7 @@ public class Camel extends AbstractHorse { } public void standUp() { @@ -90,7 +90,7 @@ index aecd17953dc117d369885d4c8d7b5c7c3a0f8f0f..0388b09e1c4f03958384680ed487792a this.makeSound(SoundEvents.CAMEL_STAND); this.setPose(Pose.STANDING); this.gameEvent(GameEvent.ENTITY_ACTION); -@@ -588,6 +588,7 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Saddl +@@ -590,6 +590,7 @@ public class Camel extends AbstractHorse { } public void standUpInstantly() { diff --git a/patches/unapplied/server/0756-Add-fire-tick-delay-option.patch b/patches/server/0752-Add-fire-tick-delay-option.patch similarity index 95% rename from patches/unapplied/server/0756-Add-fire-tick-delay-option.patch rename to patches/server/0752-Add-fire-tick-delay-option.patch index 2ad454d1c6f5..7db107dee97d 100644 --- a/patches/unapplied/server/0756-Add-fire-tick-delay-option.patch +++ b/patches/server/0752-Add-fire-tick-delay-option.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add fire-tick-delay option diff --git a/src/main/java/net/minecraft/world/level/block/FireBlock.java b/src/main/java/net/minecraft/world/level/block/FireBlock.java -index 9db6df5f28be559a324ead2fcfbe189eac076e2e..0a77a470d78f68e8397f29f298e7f52fbd7ba9a2 100644 +index 065d6164b5c9d65d20e7790c607d77e9ad70dfef..0e5a47ab235d99e6cb1468905f791c2c59ac0082 100644 --- a/src/main/java/net/minecraft/world/level/block/FireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java @@ -171,7 +171,7 @@ public class FireBlock extends BaseFireBlock { diff --git a/patches/unapplied/server/0757-Add-Moving-Piston-API.patch b/patches/server/0753-Add-Moving-Piston-API.patch similarity index 100% rename from patches/unapplied/server/0757-Add-Moving-Piston-API.patch rename to patches/server/0753-Add-Moving-Piston-API.patch diff --git a/patches/unapplied/server/0758-Ignore-impossible-spawn-tick.patch b/patches/server/0754-Ignore-impossible-spawn-tick.patch similarity index 90% rename from patches/unapplied/server/0758-Ignore-impossible-spawn-tick.patch rename to patches/server/0754-Ignore-impossible-spawn-tick.patch index f046102ceb4d..ee2750f36df9 100644 --- a/patches/unapplied/server/0758-Ignore-impossible-spawn-tick.patch +++ b/patches/server/0754-Ignore-impossible-spawn-tick.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Ignore impossible spawn tick diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index 8efc06d29c62fa2be8515ed3359d52a6d4b807d2..f57e1b78204dff661ad5d3ee93a88a00330af2dc 100644 +index 1b6ec72f59504d2f420d6d5dcbed4d3b9115e3d8..7de66aa435dd36899b80f4ecc64480680e474d94 100644 --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java @@ -84,6 +84,7 @@ public abstract class BaseSpawner { diff --git a/patches/unapplied/server/0759-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch b/patches/server/0755-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch similarity index 100% rename from patches/unapplied/server/0759-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch rename to patches/server/0755-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch diff --git a/patches/unapplied/server/0760-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch b/patches/server/0756-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch similarity index 84% rename from patches/unapplied/server/0760-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch rename to patches/server/0756-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch index cd0b3b2cc751..45c6c70db5ea 100644 --- a/patches/unapplied/server/0760-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch +++ b/patches/server/0756-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Fix EntityCombustEvent cancellation cant fully prevent diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 180a86c419cad9873c53a49c8881ced647a753e0..1aa3396a33e24f3849725769fe58b57374ee7611 100644 +index 44f585b9dc9e3940193f07a2df1205907b4800ba..24834be9b5596745f9456488076bd89c3c7d2352 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -3193,6 +3193,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3320,6 +3320,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess pluginManager.callEvent(entityCombustEvent); if (!entityCombustEvent.isCancelled()) { this.igniteForSeconds(entityCombustEvent.getDuration(), false); @@ -21,10 +21,10 @@ index 180a86c419cad9873c53a49c8881ced647a753e0..1aa3396a33e24f3849725769fe58b573 // CraftBukkit end } diff --git a/src/main/java/net/minecraft/world/level/block/BaseFireBlock.java b/src/main/java/net/minecraft/world/level/block/BaseFireBlock.java -index 0c5409af685ef1f251db3d9f9e21295c82a1e02a..8b5918dc07f17ae5001c03dc743128fd9520b819 100644 +index c8ca41cd81a72f9bff40f5c1b3bfc1189bf51f98..0cf4133849ed8ff6d4038cc41ede9d3645b31da1 100644 --- a/src/main/java/net/minecraft/world/level/block/BaseFireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BaseFireBlock.java -@@ -135,6 +135,10 @@ public abstract class BaseFireBlock extends Block { +@@ -145,6 +145,10 @@ public abstract class BaseFireBlock extends Block { if (!event.isCancelled()) { entity.igniteForSeconds(event.getDuration(), false); diff --git a/patches/unapplied/server/0761-Add-PrePlayerAttackEntityEvent.patch b/patches/server/0757-Add-PrePlayerAttackEntityEvent.patch similarity index 81% rename from patches/unapplied/server/0761-Add-PrePlayerAttackEntityEvent.patch rename to patches/server/0757-Add-PrePlayerAttackEntityEvent.patch index b0f3a0789006..5a925374e58a 100644 --- a/patches/unapplied/server/0761-Add-PrePlayerAttackEntityEvent.patch +++ b/patches/server/0757-Add-PrePlayerAttackEntityEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PrePlayerAttackEntityEvent diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index fab56040ecf496e74f583ec5d6c6c9861cfa4e13..ad334f149fe1b44d4ebe48489dcd2811ff1b5cd0 100644 +index b8edbd23d547d7189ec64c5d3a8cd1d51859ce23..30e0a5fe3f9bd85d2b702c2c877c5682ed35d461 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -1257,8 +1257,17 @@ public abstract class Player extends LivingEntity { +@@ -1222,8 +1222,17 @@ public abstract class Player extends LivingEntity { } public void attack(Entity target) { @@ -27,4 +27,4 @@ index fab56040ecf496e74f583ec5d6c6c9861cfa4e13..ad334f149fe1b44d4ebe48489dcd2811 + // Paper end - PlayerAttackEntityEvent float f = this.isAutoSpinAttack() ? this.autoSpinAttackDmg : (float) this.getAttributeValue(Attributes.ATTACK_DAMAGE); ItemStack itemstack = this.getWeaponItem(); - DamageSource damagesource = this.damageSources().playerAttack(this); + DamageSource damagesource = (DamageSource) Optional.ofNullable(itemstack.getItem().getDamageSource(this)).orElse(this.damageSources().playerAttack(this)); diff --git a/patches/unapplied/server/0762-ensure-reset-EnderDragon-boss-event-name.patch b/patches/server/0758-ensure-reset-EnderDragon-boss-event-name.patch similarity index 89% rename from patches/unapplied/server/0762-ensure-reset-EnderDragon-boss-event-name.patch rename to patches/server/0758-ensure-reset-EnderDragon-boss-event-name.patch index e2a769583def..24d93dac229e 100644 --- a/patches/unapplied/server/0762-ensure-reset-EnderDragon-boss-event-name.patch +++ b/patches/server/0758-ensure-reset-EnderDragon-boss-event-name.patch @@ -6,10 +6,10 @@ Subject: [PATCH] ensure reset EnderDragon boss event name Fix MC-257487 diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -index 98d1c097fdbbc8080624f365634e0812a5eea5ac..bf39f006efef529db697ed4dccbd1657a2673b79 100644 +index 8d0014b0db5ab42321150938fef98458fee84b17..3701cdc9f0e71d19a1090cf179bac9d5b8c4759a 100644 --- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java +++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -@@ -73,6 +73,7 @@ public class EndDragonFight { +@@ -74,6 +74,7 @@ public class EndDragonFight { private static final int GATEWAY_DISTANCE = 96; public static final int DRAGON_SPAWN_Y = 128; private final Predicate validPlayer; @@ -17,7 +17,7 @@ index 98d1c097fdbbc8080624f365634e0812a5eea5ac..bf39f006efef529db697ed4dccbd1657 public final ServerBossEvent dragonEvent; public final ServerLevel level; private final BlockPos origin; -@@ -101,7 +102,7 @@ public class EndDragonFight { +@@ -102,7 +103,7 @@ public class EndDragonFight { } public EndDragonFight(ServerLevel world, long gatewaysSeed, EndDragonFight.Data data, BlockPos origin) { @@ -26,7 +26,7 @@ index 98d1c097fdbbc8080624f365634e0812a5eea5ac..bf39f006efef529db697ed4dccbd1657 this.gateways = new ObjectArrayList(); this.ticksSinceLastPlayerScan = 21; this.skipArenaLoadedCheck = false; -@@ -505,6 +506,10 @@ public class EndDragonFight { +@@ -506,6 +507,10 @@ public class EndDragonFight { this.ticksSinceDragonSeen = 0; if (dragon.hasCustomName()) { this.dragonEvent.setName(dragon.getDisplayName()); diff --git a/patches/unapplied/server/0763-Add-Player-Warden-Warning-API.patch b/patches/server/0759-Add-Player-Warden-Warning-API.patch similarity index 93% rename from patches/unapplied/server/0763-Add-Player-Warden-Warning-API.patch rename to patches/server/0759-Add-Player-Warden-Warning-API.patch index bbb7bff753d6..1ac290e09b8a 100644 --- a/patches/unapplied/server/0763-Add-Player-Warden-Warning-API.patch +++ b/patches/server/0759-Add-Player-Warden-Warning-API.patch @@ -10,10 +10,10 @@ public net.minecraft.world.entity.monster.warden.WardenSpawnTracker cooldownTick public net.minecraft.world.entity.monster.warden.WardenSpawnTracker increaseWarningLevel()V diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 1e563ed8f7e85d68682e679b27b0f6100eb10aea..922ec82d566fd5ac0b40ed95629e63be3d1bf264 100644 +index 1dc5f21c337bc3fb67e5919308228d75b03989d1..2c38725e6fc0a264df3a0d34c21ab774ad3e2fb5 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3303,6 +3303,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3316,6 +3316,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void showElderGuardian(boolean silent) { if (getHandle().connection != null) getHandle().connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.GUARDIAN_ELDER_EFFECT, silent ? 0F : 1F)); } diff --git a/patches/unapplied/server/0764-More-vanilla-friendly-methods-to-update-trades.patch b/patches/server/0760-More-vanilla-friendly-methods-to-update-trades.patch similarity index 90% rename from patches/unapplied/server/0764-More-vanilla-friendly-methods-to-update-trades.patch rename to patches/server/0760-More-vanilla-friendly-methods-to-update-trades.patch index 5c30d5f82cb8..b3901a0ae782 100644 --- a/patches/unapplied/server/0764-More-vanilla-friendly-methods-to-update-trades.patch +++ b/patches/server/0760-More-vanilla-friendly-methods-to-update-trades.patch @@ -5,10 +5,10 @@ Subject: [PATCH] More vanilla friendly methods to update trades diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java -index 9d5a5a7fff7f75871e167f83edb0e9d5348748d7..393588661c41b490ee6bce2f687962f7ddeff7d4 100644 +index f51078e4b9e6267fa43795d009f5d149b86acb5a..a573aa4d387ad3a4e1017890f2b50b83a3c27ff4 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java -@@ -921,6 +921,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -895,6 +895,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @Override protected void updateTrades() { @@ -21,7 +21,7 @@ index 9d5a5a7fff7f75871e167f83edb0e9d5348748d7..393588661c41b490ee6bce2f687962f7 VillagerData villagerdata = this.getVillagerData(); Int2ObjectMap int2objectmap; -@@ -938,9 +944,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -912,9 +918,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler if (avillagertrades_imerchantrecipeoption != null) { MerchantOffers merchantrecipelist = this.getOffers(); @@ -35,10 +35,10 @@ index 9d5a5a7fff7f75871e167f83edb0e9d5348748d7..393588661c41b490ee6bce2f687962f7 public void gossip(ServerLevel world, Villager villager, long time) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java -index 52312bec840322d32ea845f0bd64eb3ca1380854..bd2987fa1fb194a581567134ed980e8fc043f435 100644 +index 45c44c46edee9f46b8e197f1f54ea2779bf1184c..8e895d6f84f7d84b219f2424909dd42e5f08dec4 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java -@@ -97,6 +97,34 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { +@@ -98,6 +98,34 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { } // Paper start diff --git a/patches/unapplied/server/0765-Add-paper-dumplisteners-command.patch b/patches/server/0761-Add-paper-dumplisteners-command.patch similarity index 100% rename from patches/unapplied/server/0765-Add-paper-dumplisteners-command.patch rename to patches/server/0761-Add-paper-dumplisteners-command.patch diff --git a/patches/unapplied/server/0737-Missing-effect-cause.patch b/patches/unapplied/server/0737-Missing-effect-cause.patch deleted file mode 100644 index e24048113b1d..000000000000 --- a/patches/unapplied/server/0737-Missing-effect-cause.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> -Date: Tue, 16 Aug 2022 19:44:55 +0200 -Subject: [PATCH] Missing effect cause - - -diff --git a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java -index 3dec72f407ca4af53ac5fe32f05326638af05474..01a0731e92d39c8718538244e34a271fb8717fc2 100644 ---- a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java -+++ b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java -@@ -401,7 +401,7 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder -Date: Mon, 4 Jul 2022 21:45:36 -0700 -Subject: [PATCH] EntityPickupItemEvent fixes - -Fixes double firing of the event in PiglinAi - -Fixes cancelling the event for piglins still triggering the -advancement trigger - -Fires the event when a Raider tries to pick up a raid banner -to become raid leader. - -diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java -index d2dfa49e124460f4762b950f9ded106d2ec15dc2..bc58323801ee16fe9b63c21332144ec002a902f2 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java -+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java -@@ -412,7 +412,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento - - @Override - protected void pickUpItem(ItemEntity item) { -- this.onItemPickup(item); -+ // this.onItemPickup(item); // Paper - EntityPickupItemEvent fixes; call in PiglinAi#pickUpItem after EntityPickupItemEvent is fired - PiglinAi.pickUpItem(this, item); - } - -diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java -index d3d50ec0f4466464c048449d8a844569c447d59b..b9810a1f6ac91ae9631dd1ebc225f009d91b7845 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java -+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java -@@ -242,11 +242,16 @@ public class PiglinAi { - ItemStack itemstack; - - // CraftBukkit start -- if (drop.getItem().is(Items.GOLD_NUGGET) && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, drop, 0, false).isCancelled()) { -+ // Paper start - EntityPickupItemEvent fixes; fix event firing twice -+ if (drop.getItem().is(Items.GOLD_NUGGET) /* && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, drop, 0, false).isCancelled() */) { -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, drop, 0, false).isCancelled()) return; -+ piglin.onItemPickup(drop); // Paper - moved from Piglin#pickUpItem - call prior to item entity modification -+ // Paper end - EntityPickupItemEvent fixes - piglin.take(drop, drop.getItem().getCount()); - itemstack = drop.getItem(); - drop.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause - } else if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, drop, drop.getItem().getCount() - 1, false).isCancelled()) { -+ piglin.onItemPickup(drop); // Paper - EntityPickupItemEvent fixes; moved from Piglin#pickUpItem - call prior to item entity modification - piglin.take(drop, 1); - itemstack = PiglinAi.removeOneItemFromItemEntity(drop); - } else { -@@ -261,7 +266,7 @@ public class PiglinAi { - } else if (PiglinAi.isFood(itemstack) && !PiglinAi.hasEatenRecently(piglin)) { - PiglinAi.eat(piglin); - } else { -- boolean flag = !piglin.equipItemIfPossible(itemstack, drop).equals(ItemStack.EMPTY); // CraftBukkit -+ boolean flag = !piglin.equipItemIfPossible(itemstack, null).equals(ItemStack.EMPTY); // CraftBukkit // Paper - pass null item entity to prevent duplicate pickup item event call - called above. - - if (!flag) { - PiglinAi.putInInventory(piglin, itemstack); -diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java -index 174d246b0a4d0fc9d769aad08da627ca8487bdf2..bbf21ea433f9e3963aac0ede597ed8d3c8e50ed8 100644 ---- a/src/main/java/net/minecraft/world/entity/raid/Raider.java -+++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java -@@ -225,6 +225,11 @@ public abstract class Raider extends PatrollingMonster { - boolean flag = this.hasActiveRaid() && this.getCurrentRaid().getLeader(this.getWave()) != null; - - if (this.hasActiveRaid() && !flag && ItemStack.matches(itemstack, Raid.getLeaderBannerInstance(this.registryAccess().lookupOrThrow(Registries.BANNER_PATTERN)))) { -+ // Paper start - EntityPickupItemEvent fixes -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, item, 0, false).isCancelled()) { -+ return; -+ } -+ // Paper end - EntityPickupItemEvent fixes - EquipmentSlot enumitemslot = EquipmentSlot.HEAD; - ItemStack itemstack1 = this.getItemBySlot(enumitemslot); - double d0 = (double) this.getEquipmentDropChance(enumitemslot); diff --git a/todo.txt b/todo.txt deleted file mode 100644 index 8cb87a4cf78d..000000000000 --- a/todo.txt +++ /dev/null @@ -1 +0,0 @@ -MCUTILS: look at chunkmap changes around line 555. I removed our changes because I wasn't sure what changed, needs to be looked at! From 4baf9ab44d4377dc9bcb9c1ce4b8a08f2a4b2dd3 Mon Sep 17 00:00:00 2001 From: Noah van der Aa Date: Thu, 24 Oct 2024 00:08:29 +0200 Subject: [PATCH 031/119] MOOOOOOOOOOORE --- ...ies-in-dispense-events-regarding-sta.patch | 0 ...lobal-player-list-where-appropriate.patch} | 20 +-- ...sync-entity-add-due-to-fungus-trees.patch} | 4 +- .../0764-ItemStack-damage-API.patch} | 43 +++--- .../0765-Friction-API.patch} | 24 ++-- ...trol-player-s-insomnia-and-phantoms.patch} | 8 +- ...-premature-player-kicks-on-shutdown.patch} | 4 +- .../0768-Sync-offhand-slot-in-menus.patch} | 8 +- .../0769-Player-Entity-Tracking-Events.patch} | 8 +- .../0770-Limit-pet-look-distance.patch} | 0 .../0771-fix-Instruments.patch} | 4 +- ...for-some-hot-BlockBehavior-and-Flui.patch} | 16 +-- .../0773-Add-BlockLockCheckEvent.patch} | 4 +- .../0774-Add-Sneaking-API-for-Entities.patch} | 4 +- .../0775-Improve-logging-and-errors.patch} | 27 +--- .../0776-Improve-PortalEvents.patch} | 136 +++++++++++++----- ...ion-for-spider-worldborder-climbing.patch} | 2 +- ...sing-SpigotConfig-logCommands-check.patch} | 6 +- ...Allay-stopDancing-while-not-dancing.patch} | 0 .../0780-Flying-Fall-Damage.patch} | 8 +- ...ion-moving-velocity-to-VehicleBlock.patch} | 8 +- ...onfig-for-disabling-entity-tag-tags.patch} | 4 +- ...e-player-info-update-packet-on-join.patch} | 10 +- ...k-items-during-EntityResurrectEvent.patch} | 4 +- .../0785-Win-Screen-API.patch} | 4 +- ...ItemStack-setAmount-null-assignment.patch} | 4 +- 26 files changed, 212 insertions(+), 148 deletions(-) rename patches/{unapplied/server => later}/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch (100%) rename patches/{unapplied/server/0766-check-global-player-list-where-appropriate.patch => server/0762-check-global-player-list-where-appropriate.patch} (82%) rename patches/{unapplied/server/0767-Fix-async-entity-add-due-to-fungus-trees.patch => server/0763-Fix-async-entity-add-due-to-fungus-trees.patch} (92%) rename patches/{unapplied/server/0768-ItemStack-damage-API.patch => server/0764-ItemStack-damage-API.patch} (67%) rename patches/{unapplied/server/0769-Friction-API.patch => server/0765-Friction-API.patch} (89%) rename patches/{unapplied/server/0770-Ability-to-control-player-s-insomnia-and-phantoms.patch => server/0766-Ability-to-control-player-s-insomnia-and-phantoms.patch} (92%) rename patches/{unapplied/server/0771-Fix-premature-player-kicks-on-shutdown.patch => server/0767-Fix-premature-player-kicks-on-shutdown.patch} (95%) rename patches/{unapplied/server/0772-Sync-offhand-slot-in-menus.patch => server/0768-Sync-offhand-slot-in-menus.patch} (90%) rename patches/{unapplied/server/0773-Player-Entity-Tracking-Events.patch => server/0769-Player-Entity-Tracking-Events.patch} (87%) rename patches/{unapplied/server/0774-Limit-pet-look-distance.patch => server/0770-Limit-pet-look-distance.patch} (100%) rename patches/{unapplied/server/0775-fix-Instruments.patch => server/0771-fix-Instruments.patch} (94%) rename patches/{unapplied/server/0776-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch => server/0772-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch} (84%) rename patches/{unapplied/server/0778-Add-BlockLockCheckEvent.patch => server/0773-Add-BlockLockCheckEvent.patch} (96%) rename patches/{unapplied/server/0779-Add-Sneaking-API-for-Entities.patch => server/0774-Add-Sneaking-API-for-Entities.patch} (85%) rename patches/{unapplied/server/0780-Improve-logging-and-errors.patch => server/0775-Improve-logging-and-errors.patch} (81%) rename patches/{unapplied/server/0781-Improve-PortalEvents.patch => server/0776-Improve-PortalEvents.patch} (51%) rename patches/{unapplied/server/0782-Add-config-option-for-spider-worldborder-climbing.patch => server/0777-Add-config-option-for-spider-worldborder-climbing.patch} (93%) rename patches/{unapplied/server/0783-Add-missing-SpigotConfig-logCommands-check.patch => server/0778-Add-missing-SpigotConfig-logCommands-check.patch} (89%) rename patches/{unapplied/server/0784-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch => server/0779-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch} (100%) rename patches/{unapplied/server/0785-Flying-Fall-Damage.patch => server/0780-Flying-Fall-Damage.patch} (87%) rename patches/{unapplied/server/0786-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch => server/0781-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch} (82%) rename patches/{unapplied/server/0787-config-for-disabling-entity-tag-tags.patch => server/0782-config-for-disabling-entity-tag-tags.patch} (89%) rename patches/{unapplied/server/0788-Use-single-player-info-update-packet-on-join.patch => server/0783-Use-single-player-info-update-packet-on-join.patch} (89%) rename patches/{unapplied/server/0789-Correctly-shrink-items-during-EntityResurrectEvent.patch => server/0784-Correctly-shrink-items-during-EntityResurrectEvent.patch} (92%) rename patches/{unapplied/server/0790-Win-Screen-API.patch => server/0785-Win-Screen-API.patch} (88%) rename patches/{unapplied/server/0791-Remove-CraftItemStack-setAmount-null-assignment.patch => server/0786-Remove-CraftItemStack-setAmount-null-assignment.patch} (88%) diff --git a/patches/unapplied/server/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch b/patches/later/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch similarity index 100% rename from patches/unapplied/server/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch rename to patches/later/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch diff --git a/patches/unapplied/server/0766-check-global-player-list-where-appropriate.patch b/patches/server/0762-check-global-player-list-where-appropriate.patch similarity index 82% rename from patches/unapplied/server/0766-check-global-player-list-where-appropriate.patch rename to patches/server/0762-check-global-player-list-where-appropriate.patch index f777294a4901..f64210126b58 100644 --- a/patches/unapplied/server/0766-check-global-player-list-where-appropriate.patch +++ b/patches/server/0762-check-global-player-list-where-appropriate.patch @@ -7,10 +7,10 @@ Makes certain entities check all players when searching for a player instead of just checking players in their world. diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 4bf6281a75597072b19658208e4447c4d1ee8ba2..688f9f13ae06337250e2e9ac2ddf9ad90d049f9b 100644 +index 4b2309d27867eddc50093e895503e02184e1b825..3eaeeb3ec715d92fe99e14c37e224cb1e80a467b 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2302,4 +2302,12 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2383,4 +2383,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe entity.updateDynamicGameEventListener(DynamicGameEventListener::move); } } @@ -24,10 +24,10 @@ index 4bf6281a75597072b19658208e4447c4d1ee8ba2..688f9f13ae06337250e2e9ac2ddf9ad9 + // Paper end - check global player list where appropriate } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index e6d20887572817099cb863515978d3f06926be3d..f662a791e8cb045903a0de29778e5f30892fb766 100644 +index 16f349f8ce621c58f36f445016ea25d8af14910d..0a52f925b0ef28ca7cee067a40d5dc4d30c224b0 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3723,7 +3723,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3867,7 +3867,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } public void onItemPickup(ItemEntity item) { @@ -37,11 +37,11 @@ index e6d20887572817099cb863515978d3f06926be3d..f662a791e8cb045903a0de29778e5f30 if (entity instanceof ServerPlayer) { CriteriaTriggers.THROWN_ITEM_PICKED_UP_BY_ENTITY.trigger((ServerPlayer) entity, item.getItem(), this); diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java -index f8c733961015ace508bfe14fd61d5188ca9d551b..e0dabbf6d7a87b8722769c78ef0d2ba4353ed2cb 100644 +index 533cb2eff3d56e7e8a70aba5e1047250e192bf2c..18c19e4b675000aacb74344909fc104964231008 100644 --- a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java +++ b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java -@@ -269,7 +269,7 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { - entityvillager.finalizeSpawn(world, world.getCurrentDifficultyAt(entityvillager.blockPosition()), MobSpawnType.CONVERSION, (SpawnGroupData) null); +@@ -262,7 +262,7 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { + entityvillager.finalizeSpawn(world, world.getCurrentDifficultyAt(entityvillager.blockPosition()), EntitySpawnReason.CONVERSION, (SpawnGroupData) null); entityvillager.refreshBrain(world); if (this.conversionStarter != null) { - Player entityhuman = world.getPlayerByUUID(this.conversionStarter); @@ -50,10 +50,10 @@ index f8c733961015ace508bfe14fd61d5188ca9d551b..e0dabbf6d7a87b8722769c78ef0d2ba4 if (entityhuman instanceof ServerPlayer) { CriteriaTriggers.CURED_ZOMBIE_VILLAGER.trigger((ServerPlayer) entityhuman, this, entityvillager); diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java -index d465fb01af4c8610f83ecb9c68b83127cf7e95ae..bd20bea7f76a7307f1698fb2dfef37125032d166 100644 +index dac8305f1c897e6f82a2dde67c5b1b6b8b649b19..e185a33b5b1f8e8e0a0e666b24ba3e9186a8a7ff 100644 --- a/src/main/java/net/minecraft/world/level/EntityGetter.java +++ b/src/main/java/net/minecraft/world/level/EntityGetter.java -@@ -237,4 +237,11 @@ public interface EntityGetter { +@@ -165,4 +165,11 @@ public interface EntityGetter { return null; } @@ -66,7 +66,7 @@ index d465fb01af4c8610f83ecb9c68b83127cf7e95ae..bd20bea7f76a7307f1698fb2dfef3712 + // Paper end - check global player list where appropriate } diff --git a/src/main/java/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java -index dd86f5ec5b2051aeea4e19ff97146362b1e8d019..0c6561e53db1b82f70dec00729d4d8a70c8fd4a1 100644 +index ea53c25c350c0cf8e0360ea409cd1f69a62054a8..275721d8b3d653b38af505dde30396c0b7b6a3da 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java @@ -105,6 +105,13 @@ public class SculkShriekerBlockEntity extends BlockEntity implements GameEventLi diff --git a/patches/unapplied/server/0767-Fix-async-entity-add-due-to-fungus-trees.patch b/patches/server/0763-Fix-async-entity-add-due-to-fungus-trees.patch similarity index 92% rename from patches/unapplied/server/0767-Fix-async-entity-add-due-to-fungus-trees.patch rename to patches/server/0763-Fix-async-entity-add-due-to-fungus-trees.patch index 2a7830d9526f..44c121394e11 100644 --- a/patches/unapplied/server/0767-Fix-async-entity-add-due-to-fungus-trees.patch +++ b/patches/server/0763-Fix-async-entity-add-due-to-fungus-trees.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix async entity add due to fungus trees diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java -index 13229388ddce668061a34c787ab9586d41854d8a..682c8cfbd917c086072f1756861a340800ea40da 100644 +index 5bf438bb58833c1df3620e82d3d2b90207366372..2e72e92762877b28dd908711671e1dfb933de9b0 100644 --- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java +++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java @@ -237,6 +237,7 @@ public class WorldGenRegion implements WorldGenLevel { @@ -17,7 +17,7 @@ index 13229388ddce668061a34c787ab9586d41854d8a..682c8cfbd917c086072f1756861a3408 BlockEntity tileentity = iblockdata.hasBlockEntity() ? this.getBlockEntity(pos) : null; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index 3c1937b43b6834ae0ffdd8d22ac32a776bc7fb64..a14d3e6c43b94c543790571b13808713444a239f 100644 +index 6baa06dc0f102fe83b10015dbbe1410066961c82..29825ea687827c075b87e88c45672e7b0093ed17 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java @@ -261,10 +261,10 @@ public abstract class CraftRegionAccessor implements RegionAccessor { diff --git a/patches/unapplied/server/0768-ItemStack-damage-API.patch b/patches/server/0764-ItemStack-damage-API.patch similarity index 67% rename from patches/unapplied/server/0768-ItemStack-damage-API.patch rename to patches/server/0764-ItemStack-damage-API.patch index 1233d5fea9c0..f6d47719ca45 100644 --- a/patches/unapplied/server/0768-ItemStack-damage-API.patch +++ b/patches/server/0764-ItemStack-damage-API.patch @@ -11,25 +11,36 @@ the logic associated with damaging them public net.minecraft.world.entity.LivingEntity entityEventForEquipmentBreak(Lnet/minecraft/world/entity/EquipmentSlot;)B diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index bee59df6a8f30416f94c1a4fbd5e2629336e842f..e64cc91b416bbbefe6aadf1c6b685346cf258ab4 100644 +index bcb3a45166e5dd75dd727adf92304b3a75399c8d..d8dc3228f3cd8c9efc8359162edac601a87bf762 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -647,8 +647,13 @@ public final class ItemStack implements DataComponentHolder { +@@ -693,8 +693,13 @@ public final class ItemStack implements DataComponentHolder { } - public void hurtAndBreak(int amount, ServerLevel world, @Nullable LivingEntity player, Consumer breakCallback) { // Paper - Add EntityDamageItemEvent -+ // Paper start - add param to skip infinite mats check + public void hurtAndBreak(int amount, ServerLevel world, @Nullable LivingEntity player, Consumer breakCallback) { // Paper - Add EntityDamageItemEvent ++ // Paper start - add force boolean overload + this.hurtAndBreak(amount, world, player, breakCallback, false); + } -+ public void hurtAndBreak(int amount, ServerLevel world, @Nullable LivingEntity player, Consumer breakCallback, boolean force) { -+ // Paper end - add param to skip infinite mats check - if (this.isDamageableItem()) { -- if (player == null || !player.hasInfiniteMaterials()) { -+ if (player == null || !player.hasInfiniteMaterials() || force) { // Paper - if (amount > 0) { - int originalDamage = amount; // Paper - Expand PlayerItemDamageEvent - amount = EnchantmentHelper.processDurabilityChange(world, this, amount); -@@ -704,6 +709,11 @@ public final class ItemStack implements DataComponentHolder { ++ public void hurtAndBreak(int amount, ServerLevel world, @Nullable LivingEntity player, Consumer breakCallback, boolean force) { // Paper - Add EntityDamageItemEvent ++ // Paper end + int originalDamage = amount; // Paper - Expand PlayerItemDamageEvent +- int j = this.processDurabilityChange(amount, world, player); ++ int j = this.processDurabilityChange(amount, world, player, force); // Paper + // CraftBukkit start + if (player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent + PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), j, originalDamage); // Paper - Add EntityDamageItemEvent +@@ -725,8 +730,8 @@ public final class ItemStack implements DataComponentHolder { + + } + +- private int processDurabilityChange(int baseDamage, ServerLevel world, @Nullable LivingEntity player) { // Paper - Add EntityDamageItemEvent +- return !this.isDamageableItem() ? 0 : (player instanceof ServerPlayer && player.hasInfiniteMaterials() ? 0 : (baseDamage > 0 ? EnchantmentHelper.processDurabilityChange(world, this, baseDamage) : baseDamage)); // Paper - Add EntityDamageItemEvent ++ private int processDurabilityChange(int baseDamage, ServerLevel world, @Nullable LivingEntity player, boolean force) { // Paper - Add EntityDamageItemEvent ++ return !this.isDamageableItem() ? 0 : (player instanceof ServerPlayer && player.hasInfiniteMaterials() && !force ? 0 : (baseDamage > 0 ? EnchantmentHelper.processDurabilityChange(world, this, baseDamage) : baseDamage)); // Paper - Add EntityDamageItemEvent + } + + private void applyDamage(int damage, @Nullable LivingEntity player, Consumer breakCallback) { // Paper - Add EntityDamageItemEvent +@@ -766,6 +771,11 @@ public final class ItemStack implements DataComponentHolder { } public void hurtAndBreak(int amount, LivingEntity entity, EquipmentSlot slot) { @@ -41,7 +52,7 @@ index bee59df6a8f30416f94c1a4fbd5e2629336e842f..e64cc91b416bbbefe6aadf1c6b685346 Level world = entity.level(); if (world instanceof ServerLevel worldserver) { -@@ -716,8 +726,8 @@ public final class ItemStack implements DataComponentHolder { +@@ -778,8 +788,8 @@ public final class ItemStack implements DataComponentHolder { } this.hurtAndBreak(amount, worldserver, entity, (item) -> { // Paper - Add EntityDamageItemEvent @@ -53,10 +64,10 @@ index bee59df6a8f30416f94c1a4fbd5e2629336e842f..e64cc91b416bbbefe6aadf1c6b685346 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 2a7fffa71106327d0ffee632408d45faaec76702..2332f40fed84510741e63073aaf0a18aab85303e 100644 +index 4fa19ddb1414282020e118eea298d57d2bf42754..1ceaa081231a617bd87331b308c24d9c7a8dcf2b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -1135,4 +1135,48 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -1154,4 +1154,48 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { this.getHandle().knockback(strength, directionX, directionZ); }; // Paper end - knockback API diff --git a/patches/unapplied/server/0769-Friction-API.patch b/patches/server/0765-Friction-API.patch similarity index 89% rename from patches/unapplied/server/0769-Friction-API.patch rename to patches/server/0765-Friction-API.patch index dc735c46bb67..ff7124236706 100644 --- a/patches/unapplied/server/0769-Friction-API.patch +++ b/patches/server/0765-Friction-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Friction API diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index f662a791e8cb045903a0de29778e5f30892fb766..2bb61084b628582ded44926d7697ee26d0bb1e8e 100644 +index 0a52f925b0ef28ca7cee067a40d5dc4d30c224b0..abcb1065100597f66c9f76fdae5f873fa0d8f315 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -285,6 +285,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -298,6 +298,7 @@ public abstract class LivingEntity extends Entity implements Attackable { public boolean bukkitPickUpLoot; public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper public boolean silentDeath = false; // Paper - mark entity as dying silently for cancellable death event @@ -16,7 +16,7 @@ index f662a791e8cb045903a0de29778e5f30892fb766..2bb61084b628582ded44926d7697ee26 @Override public float getBukkitYaw() { -@@ -706,7 +707,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -724,7 +725,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } public boolean shouldDiscardFriction() { @@ -25,7 +25,7 @@ index f662a791e8cb045903a0de29778e5f30892fb766..2bb61084b628582ded44926d7697ee26 } public void setDiscardFriction(boolean noDrag) { -@@ -774,6 +775,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -798,6 +799,11 @@ public abstract class LivingEntity extends Entity implements Attackable { @Override public void addAdditionalSaveData(CompoundTag nbt) { @@ -37,7 +37,7 @@ index f662a791e8cb045903a0de29778e5f30892fb766..2bb61084b628582ded44926d7697ee26 nbt.putFloat("Health", this.getHealth()); nbt.putShort("HurtTime", (short) this.hurtTime); nbt.putInt("HurtByTimestamp", this.lastHurtByMobTimestamp); -@@ -817,6 +823,16 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -841,6 +847,16 @@ public abstract class LivingEntity extends Entity implements Attackable { } this.internalSetAbsorptionAmount(absorptionAmount); // Paper end - Check for NaN @@ -55,7 +55,7 @@ index f662a791e8cb045903a0de29778e5f30892fb766..2bb61084b628582ded44926d7697ee26 this.getAttributes().load(nbt.getList("attributes", 10)); } diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index 446c319524183d6a1b4d0e6f0613a8db690677da..cbfb07bdf8d5e2e5a462835184be2d47e59d506c 100644 +index aa41c4cf8d3ae291c4147118c96190ff0bb807b2..e83a705f54063a17fc69a22683333aacad5a43ce 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -63,6 +63,7 @@ public class ItemEntity extends Entity implements TraceableEntity { @@ -66,8 +66,8 @@ index 446c319524183d6a1b4d0e6f0613a8db690677da..cbfb07bdf8d5e2e5a462835184be2d47 public ItemEntity(EntityType type, Level world) { super(type, world); -@@ -185,7 +186,11 @@ public class ItemEntity extends Entity implements TraceableEntity { - this.move(MoverType.SELF, this.getDeltaMovement()); +@@ -186,7 +187,11 @@ public class ItemEntity extends Entity implements TraceableEntity { + this.applyEffectsFromBlocks(); float f = 0.98F; - if (this.onGround()) { @@ -79,7 +79,7 @@ index 446c319524183d6a1b4d0e6f0613a8db690677da..cbfb07bdf8d5e2e5a462835184be2d47 f = this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getFriction() * 0.98F; } -@@ -393,6 +398,11 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -409,6 +414,11 @@ public class ItemEntity extends Entity implements TraceableEntity { @Override public void addAdditionalSaveData(CompoundTag nbt) { @@ -91,7 +91,7 @@ index 446c319524183d6a1b4d0e6f0613a8db690677da..cbfb07bdf8d5e2e5a462835184be2d47 nbt.putShort("Health", (short) this.health); nbt.putShort("Age", (short) this.age); nbt.putShort("PickupDelay", (short) this.pickupDelay); -@@ -435,6 +445,17 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -451,6 +461,17 @@ public class ItemEntity extends Entity implements TraceableEntity { this.setItem(ItemStack.EMPTY); } @@ -133,10 +133,10 @@ index 1a291dd8a287db30e71dcb315599fc4b038764c4..30d62ee4d5cd2ddacb8783b5bbbf475d public int getHealth() { return this.getHandle().health; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 2332f40fed84510741e63073aaf0a18aab85303e..516ea1ec9ae5069c3c0e4708f62164a91960b627 100644 +index 1ceaa081231a617bd87331b308c24d9c7a8dcf2b..2fd4a3068d86a37cc18c9203448823c53d590ffb 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -1179,4 +1179,17 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -1198,4 +1198,17 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { nmsStack.hurtAndBreak(amount, this.getHandle(), slot, true); } // Paper end - ItemStack damage API diff --git a/patches/unapplied/server/0770-Ability-to-control-player-s-insomnia-and-phantoms.patch b/patches/server/0766-Ability-to-control-player-s-insomnia-and-phantoms.patch similarity index 92% rename from patches/unapplied/server/0770-Ability-to-control-player-s-insomnia-and-phantoms.patch rename to patches/server/0766-Ability-to-control-player-s-insomnia-and-phantoms.patch index 03be2495a7bb..0b482955d51f 100644 --- a/patches/unapplied/server/0770-Ability-to-control-player-s-insomnia-and-phantoms.patch +++ b/patches/server/0766-Ability-to-control-player-s-insomnia-and-phantoms.patch @@ -5,13 +5,13 @@ Subject: [PATCH] Ability to control player's insomnia and phantoms diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java -index 302decdccd37c5579473c8fc33adda3956be7603..dca7b99e97f21bf6cfae6ee69eeac95d0bcf6863 100644 +index 721321a19ce056f82de2bef44a8791dc9d5b3418..6bf691fcc6486bde73bae30eff09142802c29eda 100644 --- a/src/main/java/net/minecraft/world/entity/EntitySelector.java +++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java -@@ -28,7 +28,18 @@ public final class EntitySelector { - return !entity.isSpectator(); +@@ -27,7 +27,18 @@ public final class EntitySelector { }; public static final Predicate CAN_BE_COLLIDED_WITH = EntitySelector.NO_SPECTATORS.and(Entity::canBeCollidedWith); + public static final Predicate CAN_BE_PICKED = EntitySelector.NO_SPECTATORS.and(Entity::isPickable); - public static Predicate IS_INSOMNIAC = (player) -> net.minecraft.util.Mth.clamp(((net.minecraft.server.level.ServerPlayer) player).getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper - Add phantom creative and insomniac controls + // Paper start - Ability to control player's insomnia and phantoms + public static Predicate IS_INSOMNIAC = (player) -> { @@ -29,7 +29,7 @@ index 302decdccd37c5579473c8fc33adda3956be7603..dca7b99e97f21bf6cfae6ee69eeac95d private EntitySelector() {} // Paper start - Affects Spawning API diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java -index f74d41e57570a40cd5ce4da3076f3210b6594a63..1b1b475ca27e799e251d6f8a8c9fe1a4fd8bae83 100644 +index 7d407a7597f3ae576ac7e94bc2eb96d9dcd78dd3..021221da5d0315f6e371380a705ac6b3f6ac18d3 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java +++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java @@ -32,13 +32,22 @@ public class PhantomSpawner implements CustomSpawner { diff --git a/patches/unapplied/server/0771-Fix-premature-player-kicks-on-shutdown.patch b/patches/server/0767-Fix-premature-player-kicks-on-shutdown.patch similarity index 95% rename from patches/unapplied/server/0771-Fix-premature-player-kicks-on-shutdown.patch rename to patches/server/0767-Fix-premature-player-kicks-on-shutdown.patch index 034840341e4f..0eec1f89003d 100644 --- a/patches/unapplied/server/0771-Fix-premature-player-kicks-on-shutdown.patch +++ b/patches/server/0767-Fix-premature-player-kicks-on-shutdown.patch @@ -47,10 +47,10 @@ index 4d9f1fc884050993287adfa4578a87da710623fb..a8dfe7a4b3d01bf75587be078f471d1e this.disconnect((Component) Component.translatable("multiplayer.disconnect.server_shutdown")); } catch (ClassCastException classcastexception) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index bef05e09c654794405832ad75c3471f63399dfee..2cc22a9a5483c62cdf64870f5ce62b33018bef06 100644 +index 027d94dd08e7789b51c8779c65d4ddad4e62f21a..53c9be615a0f2939cd989e24e304e81e6e27f39d 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2091,7 +2091,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { +@@ -26,9 +26,11 @@ public final class FluidState extends StateHolder { public static final Codec CODEC = codec(BuiltInRegistries.FLUID.byNameCodec(), Fluid::defaultFluidState).stable(); public static final int AMOUNT_MAX = 9; public static final int AMOUNT_FULL = 8; @@ -67,7 +67,7 @@ index 42370e5e6628ebf8216c01521af859706b08834b..14bb12d2a0066e8b020f2e0e670a7a5c } public Fluid getType() { -@@ -43,7 +45,7 @@ public final class FluidState extends StateHolder { +@@ -44,7 +46,7 @@ public final class FluidState extends StateHolder { } public boolean isEmpty() { diff --git a/patches/unapplied/server/0778-Add-BlockLockCheckEvent.patch b/patches/server/0773-Add-BlockLockCheckEvent.patch similarity index 96% rename from patches/unapplied/server/0778-Add-BlockLockCheckEvent.patch rename to patches/server/0773-Add-BlockLockCheckEvent.patch index 31fba739ae23..b06f734eb217 100644 --- a/patches/unapplied/server/0778-Add-BlockLockCheckEvent.patch +++ b/patches/server/0773-Add-BlockLockCheckEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add BlockLockCheckEvent diff --git a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java -index bf9ae460bdfb247456b895f026f6a7a2e162c5f5..2ddf349fde5b310ec3f74baee1f3d33e09d5286c 100644 +index 4f397dd8e5d333cb2561d03d20511a9194314d1c..1f29b2419914ca9257db6553f01b7e7ec49bfc18 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java @@ -73,17 +73,44 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co @@ -56,7 +56,7 @@ index bf9ae460bdfb247456b895f026f6a7a2e162c5f5..2ddf349fde5b310ec3f74baee1f3d33e protected abstract NonNullList getItems(); diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -index f8d432ef21e59796da4b11c9748ba151c54e5e04..b6633ca1ee73ef0f8a220992a2e0424e67dd9758 100644 +index edd6017937a7f20a1b43fa15204ec130b524b52b..2a7d896dd9a02acf6e3596e2e2e7ed50f4b88377 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java @@ -472,7 +472,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name diff --git a/patches/unapplied/server/0779-Add-Sneaking-API-for-Entities.patch b/patches/server/0774-Add-Sneaking-API-for-Entities.patch similarity index 85% rename from patches/unapplied/server/0779-Add-Sneaking-API-for-Entities.patch rename to patches/server/0774-Add-Sneaking-API-for-Entities.patch index aaee22c0564a..27bb5274f83b 100644 --- a/patches/unapplied/server/0779-Add-Sneaking-API-for-Entities.patch +++ b/patches/server/0774-Add-Sneaking-API-for-Entities.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Sneaking API for Entities diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index f950102a324d07aeba260bfa82fe88728f2362e5..ac513d3162a0794f226abc80bff21c799fe5802c 100644 +index 775675483c1f90fbe8e9e5eadab7d791e81983f5..5e413803f9bdc898a9a644cb123363cbdf447ad8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -874,6 +874,18 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -875,6 +875,18 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return Pose.values()[this.getHandle().getPose().ordinal()]; } diff --git a/patches/unapplied/server/0780-Improve-logging-and-errors.patch b/patches/server/0775-Improve-logging-and-errors.patch similarity index 81% rename from patches/unapplied/server/0780-Improve-logging-and-errors.patch rename to patches/server/0775-Improve-logging-and-errors.patch index d2ccc7abedb4..4a5cccd9ae78 100644 --- a/patches/unapplied/server/0780-Improve-logging-and-errors.patch +++ b/patches/server/0775-Improve-logging-and-errors.patch @@ -28,10 +28,10 @@ index 2665170b8391a77d6b3fb7ae7b5ccfc0be65acd7..e00d4e0896c0163c43d79af63338de67 private boolean tryInsert(AdvancementHolder advancement) { diff --git a/src/main/java/net/minecraft/server/ServerAdvancementManager.java b/src/main/java/net/minecraft/server/ServerAdvancementManager.java -index 3255578c8c37d977bb6e89d27194a4dbff822014..2172e23b22b411fe79e930128bd43ac07becb620 100644 +index 0828deee077a08db8e3fe5c870f9c242b4c550cf..5c8cf225d936617b6c8d265527a19bdfa371a93b 100644 --- a/src/main/java/net/minecraft/server/ServerAdvancementManager.java +++ b/src/main/java/net/minecraft/server/ServerAdvancementManager.java -@@ -69,6 +69,7 @@ public class ServerAdvancementManager extends SimpleJsonResourceReloadListener { +@@ -53,6 +53,7 @@ public class ServerAdvancementManager extends SimpleJsonResourceReloadListener { ++ // CraftBukkit end ++ ++ public static final DimensionTransition.PostDimensionTransition DO_NOTHING = (entity) -> { ++ }; ++ public static final DimensionTransition.PostDimensionTransition PLAY_PORTAL_SOUND = DimensionTransition::playPortalSound; ++ public static final DimensionTransition.PostDimensionTransition PLACE_PORTAL_TICKET = DimensionTransition::placePortalTicket; ++ ++ public DimensionTransition(ServerLevel world, Vec3 pos, Vec3 velocity, float yaw, float pitch, DimensionTransition.PostDimensionTransition postDimensionTransition) { ++ // CraftBukkit start ++ this(world, pos, velocity, yaw, pitch, postDimensionTransition, PlayerTeleportEvent.TeleportCause.UNKNOWN); ++ } ++ ++ public DimensionTransition(ServerLevel worldserver, Vec3 vec3d, Vec3 vec3d1, float f, float f1, DimensionTransition.PostDimensionTransition dimensiontransition_a, PlayerTeleportEvent.TeleportCause cause) { ++ this(worldserver, vec3d, vec3d1, f, f1, false, dimensiontransition_a, cause); ++ } ++ ++ public DimensionTransition(ServerLevel world, Entity entity, DimensionTransition.PostDimensionTransition postDimensionTransition) { ++ this(world, entity, postDimensionTransition, PlayerTeleportEvent.TeleportCause.UNKNOWN); ++ } ++ ++ public DimensionTransition(ServerLevel worldserver, Entity entity, DimensionTransition.PostDimensionTransition dimensiontransition_a, PlayerTeleportEvent.TeleportCause cause) { ++ this(worldserver, findAdjustedSharedSpawnPos(worldserver, entity), Vec3.ZERO, worldserver.getSharedSpawnAngle(), 0.0F, false, dimensiontransition_a, cause); // Paper - MC-200092 - fix spawn pos yaw being ignored ++ // CraftBukkit end ++ } ++ ++ private static void playPortalSound(Entity entity) { ++ if (entity instanceof ServerPlayer entityplayer) { ++ entityplayer.connection.send(new ClientboundLevelEventPacket(1032, BlockPos.ZERO, 0, false)); ++ } ++ ++ } ++ ++ private static void placePortalTicket(Entity entity) { ++ entity.placePortalTicket(BlockPos.containing(entity.position())); ++ } ++ ++ public static DimensionTransition missingRespawnBlock(ServerLevel world, Entity entity, DimensionTransition.PostDimensionTransition postDimensionTransition) { ++ return new DimensionTransition(world, findAdjustedSharedSpawnPos(world, entity), Vec3.ZERO, world.getSharedSpawnAngle(), 0.0F, true, postDimensionTransition); // Paper - MC-200092 - fix spawn pos yaw being ignored ++ } ++ ++ private static Vec3 findAdjustedSharedSpawnPos(ServerLevel world, Entity entity) { ++ return entity.adjustSpawnLocation(world, world.getSharedSpawnPos()).getBottomCenter(); ++ } ++ ++ @FunctionalInterface ++ public interface PostDimensionTransition { ++ ++ void onTransition(Entity entity); ++ ++ default DimensionTransition.PostDimensionTransition then(DimensionTransition.PostDimensionTransition next) { ++ return (entity) -> { ++ this.onTransition(entity); ++ next.onTransition(entity); ++ }; ++ } ++ } ++} diff --git a/patches/unapplied/server/0782-Add-config-option-for-spider-worldborder-climbing.patch b/patches/server/0777-Add-config-option-for-spider-worldborder-climbing.patch similarity index 93% rename from patches/unapplied/server/0782-Add-config-option-for-spider-worldborder-climbing.patch rename to patches/server/0777-Add-config-option-for-spider-worldborder-climbing.patch index 71e393975351..6d4efc38b662 100644 --- a/patches/unapplied/server/0782-Add-config-option-for-spider-worldborder-climbing.patch +++ b/patches/server/0777-Add-config-option-for-spider-worldborder-climbing.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add config option for spider worldborder climbing diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java -index c80019f0c9f814c5259b4d3ec2d8a85669dc728f..f91ea9ac5a0d0d3bae5d1eb0c409f4f9c4e5a62b 100644 +index ba4dfa26f4d54abe9ecbacfe1f409a34fb769579..6c2d4c2163cf299c0943af21d4dc367b5677c089 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Spider.java +++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java @@ -82,7 +82,7 @@ public class Spider extends Monster { diff --git a/patches/unapplied/server/0783-Add-missing-SpigotConfig-logCommands-check.patch b/patches/server/0778-Add-missing-SpigotConfig-logCommands-check.patch similarity index 89% rename from patches/unapplied/server/0783-Add-missing-SpigotConfig-logCommands-check.patch rename to patches/server/0778-Add-missing-SpigotConfig-logCommands-check.patch index 9c86e0000a17..2e59f69e0560 100644 --- a/patches/unapplied/server/0783-Add-missing-SpigotConfig-logCommands-check.patch +++ b/patches/server/0778-Add-missing-SpigotConfig-logCommands-check.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add missing SpigotConfig logCommands check Co-authored-by: david diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 6b869ff834af1e02f55683b3399d40bee0518bf1..a2a7d499a68841ecd76ba029298094993a82bf39 100644 +index 1a9003f703f6911e37a086f490d4d65ab9d27014..e29cae56ddeb019d2ffd8dad412fd32e4db67091 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2057,7 +2057,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2070,7 +2070,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private void performUnsignedChatCommand(String command) { // CraftBukkit start String command1 = "/" + command; @@ -19,7 +19,7 @@ index 6b869ff834af1e02f55683b3399d40bee0518bf1..a2a7d499a68841ecd76ba02929809499 PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(this.getCraftPlayer(), command1, new LazyPlayerSet(this.server)); this.cserver.getPluginManager().callEvent(event); -@@ -2097,7 +2099,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2110,7 +2112,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private void performSignedChatCommand(ServerboundChatCommandSignedPacket packet, LastSeenMessages lastSeenMessages) { // CraftBukkit start String command = "/" + packet.command(); diff --git a/patches/unapplied/server/0784-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch b/patches/server/0779-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch similarity index 100% rename from patches/unapplied/server/0784-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch rename to patches/server/0779-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch diff --git a/patches/unapplied/server/0785-Flying-Fall-Damage.patch b/patches/server/0780-Flying-Fall-Damage.patch similarity index 87% rename from patches/unapplied/server/0785-Flying-Fall-Damage.patch rename to patches/server/0780-Flying-Fall-Damage.patch index cee20a07daae..d3c19b0590ff 100644 --- a/patches/unapplied/server/0785-Flying-Fall-Damage.patch +++ b/patches/server/0780-Flying-Fall-Damage.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Flying Fall Damage diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index ad334f149fe1b44d4ebe48489dcd2811ff1b5cd0..950ce40d268d89ff3c503116081db6c9ccd65329 100644 +index 30e0a5fe3f9bd85d2b702c2c877c5682ed35d461..aca888c2f02b09ac6739bdc81b194c4527dd69f5 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java @@ -196,6 +196,7 @@ public abstract class Player extends LivingEntity { @@ -16,7 +16,7 @@ index ad334f149fe1b44d4ebe48489dcd2811ff1b5cd0..950ce40d268d89ff3c503116081db6c9 // CraftBukkit start public boolean fauxSleeping; -@@ -1693,7 +1694,7 @@ public abstract class Player extends LivingEntity { +@@ -1651,7 +1652,7 @@ public abstract class Player extends LivingEntity { @Override public boolean causeFallDamage(float fallDistance, float damageMultiplier, DamageSource damageSource) { @@ -26,10 +26,10 @@ index ad334f149fe1b44d4ebe48489dcd2811ff1b5cd0..950ce40d268d89ff3c503116081db6c9 } else { if (fallDistance >= 2.0F) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 111b90f97f631369acfb76278da26de94a4740bf..fdf6c3f1f8f79dd20e1363ef472f97fe98c9799e 100644 +index 2a0ca017130a76aff3f15064a334cc0be501d782..83a121331e3922ed8b90e530c2495bf19406c08d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2581,6 +2581,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2594,6 +2594,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().onUpdateAbilities(); } diff --git a/patches/unapplied/server/0786-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch b/patches/server/0781-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch similarity index 82% rename from patches/unapplied/server/0786-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch rename to patches/server/0781-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch index 80118a649946..7da0a4ef651d 100644 --- a/patches/unapplied/server/0786-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch +++ b/patches/server/0781-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch @@ -6,18 +6,18 @@ Subject: [PATCH] Expose pre-collision moving velocity to diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 303f3656be5e9049cd195030c457df9a7c718b66..34e175b28f7c9120b58fc8e2b65ca978c7f301b5 100644 +index 960b3541140bfe36fda5cdb43e3408bbc9db5fde..2c959a99376ed479415354c481801643c5f6b1a1 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -942,6 +942,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -968,6 +968,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } - public void move(MoverType movementType, Vec3 movement) { + public void move(MoverType type, Vec3 movement) { + final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity if (this.noPhysics) { this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z); } else { -@@ -1026,7 +1027,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1059,7 +1060,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } if (!bl.getType().isAir()) { diff --git a/patches/unapplied/server/0787-config-for-disabling-entity-tag-tags.patch b/patches/server/0782-config-for-disabling-entity-tag-tags.patch similarity index 89% rename from patches/unapplied/server/0787-config-for-disabling-entity-tag-tags.patch rename to patches/server/0782-config-for-disabling-entity-tag-tags.patch index aabc1e1a31b1..c3be8a0eeae4 100644 --- a/patches/unapplied/server/0787-config-for-disabling-entity-tag-tags.patch +++ b/patches/server/0782-config-for-disabling-entity-tag-tags.patch @@ -5,10 +5,10 @@ Subject: [PATCH] config for disabling entity tag tags diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index c0062c8f83641ff30e79a309c0bb9930ba4b422a..5fb3279342506611882b5780cfbee0371919c93c 100644 +index ab02f4ca0bb8cd4939f167b410db208e38f7102b..6b2f0a4bc911888b72b796099760af38b1e28656 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -502,6 +502,16 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -579,6 +579,16 @@ public class EntityType implements FeatureElement, EntityTypeT if (minecraftserver != null && entity != null) { if (world.isClientSide || !entity.onlyOpCanSetNbt() || player != null && minecraftserver.getPlayerList().isOp(player.getGameProfile())) { diff --git a/patches/unapplied/server/0788-Use-single-player-info-update-packet-on-join.patch b/patches/server/0783-Use-single-player-info-update-packet-on-join.patch similarity index 89% rename from patches/unapplied/server/0788-Use-single-player-info-update-packet-on-join.patch rename to patches/server/0783-Use-single-player-info-update-packet-on-join.patch index bbf87853109c..14893c3080e2 100644 --- a/patches/unapplied/server/0788-Use-single-player-info-update-packet-on-join.patch +++ b/patches/server/0783-Use-single-player-info-update-packet-on-join.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Use single player info update packet on join diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index a2a7d499a68841ecd76ba029298094993a82bf39..a6f58438badb0bdeab67706f4a8e519b202623fe 100644 +index e29cae56ddeb019d2ffd8dad412fd32e4db67091..d77ab963802fcd7551058987a534ba54f080027a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3436,7 +3436,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3481,7 +3481,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.signedMessageDecoder = session.createMessageDecoder(this.player.getUUID()); this.chatMessageChain.append(() -> { this.player.setChatSession(session); @@ -18,10 +18,10 @@ index a2a7d499a68841ecd76ba029298094993a82bf39..a6f58438badb0bdeab67706f4a8e519b } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 38b9ab369e25e4b718418375f76e782283b48411..bd67245393f512264db774e0b855db0ce925a3f4 100644 +index 8e71eeb5be2df1352447f3662a6d092a7db9e2d0..4fe3024e26b56c2d796acf703a1bc200ff309f09 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -361,6 +361,7 @@ public abstract class PlayerList { +@@ -365,6 +365,7 @@ public abstract class PlayerList { // CraftBukkit start - sendAll above replaced with this loop ClientboundPlayerInfoUpdatePacket packet = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player)); @@ -29,7 +29,7 @@ index 38b9ab369e25e4b718418375f76e782283b48411..bd67245393f512264db774e0b855db0c for (int i = 0; i < this.players.size(); ++i) { ServerPlayer entityplayer1 = (ServerPlayer) this.players.get(i); -@@ -368,12 +369,17 @@ public abstract class PlayerList { +@@ -372,12 +373,17 @@ public abstract class PlayerList { entityplayer1.connection.send(packet); } diff --git a/patches/unapplied/server/0789-Correctly-shrink-items-during-EntityResurrectEvent.patch b/patches/server/0784-Correctly-shrink-items-during-EntityResurrectEvent.patch similarity index 92% rename from patches/unapplied/server/0789-Correctly-shrink-items-during-EntityResurrectEvent.patch rename to patches/server/0784-Correctly-shrink-items-during-EntityResurrectEvent.patch index e7b31c3642a8..48eae9b3ecb1 100644 --- a/patches/unapplied/server/0789-Correctly-shrink-items-during-EntityResurrectEvent.patch +++ b/patches/server/0784-Correctly-shrink-items-during-EntityResurrectEvent.patch @@ -22,10 +22,10 @@ This patch corrects this behaviour by only shrinking the item if a totem of undying was found and the event was called uncancelled. diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 2bb61084b628582ded44926d7697ee26d0bb1e8e..9e58a85a7de53b17fa149ae0b4951baa351d99db 100644 +index abcb1065100597f66c9f76fdae5f873fa0d8f315..447fb76a3eb1505b1ef1e1aed8a11239c0124f4f 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1632,7 +1632,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1674,7 +1674,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.level().getCraftServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { diff --git a/patches/unapplied/server/0790-Win-Screen-API.patch b/patches/server/0785-Win-Screen-API.patch similarity index 88% rename from patches/unapplied/server/0790-Win-Screen-API.patch rename to patches/server/0785-Win-Screen-API.patch index 567b2236d934..330a77aa214b 100644 --- a/patches/unapplied/server/0790-Win-Screen-API.patch +++ b/patches/server/0785-Win-Screen-API.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Win Screen API public net.minecraft.server.level.ServerPlayer seenCredits diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index fdf6c3f1f8f79dd20e1363ef472f97fe98c9799e..06a3ccb90f23fc357e5cbc6e9173baab4b218955 100644 +index 83a121331e3922ed8b90e530c2495bf19406c08d..76d8f0d390abf588886b42b6d2e3ed6f79a4d991 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1305,6 +1305,25 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1318,6 +1318,25 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().connection.send(packet); } diff --git a/patches/unapplied/server/0791-Remove-CraftItemStack-setAmount-null-assignment.patch b/patches/server/0786-Remove-CraftItemStack-setAmount-null-assignment.patch similarity index 88% rename from patches/unapplied/server/0791-Remove-CraftItemStack-setAmount-null-assignment.patch rename to patches/server/0786-Remove-CraftItemStack-setAmount-null-assignment.patch index 5b5c421ff26c..aa0acd564ff5 100644 --- a/patches/unapplied/server/0791-Remove-CraftItemStack-setAmount-null-assignment.patch +++ b/patches/server/0786-Remove-CraftItemStack-setAmount-null-assignment.patch @@ -16,10 +16,10 @@ with less than zero amounts, so this code doesn't create a problem with operations on the vanilla ItemStack. diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index 08178a88ba7d0881a6c2843eef24a846cf07adb4..4d29c34e221b749b6972c7ed79ac1f86da999ed7 100644 +index 502be683e8b04a9966043c9bee9d9fe793b12ef5..134db8c2dd72d0651fc889cc8931e7c971f62deb 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -@@ -186,7 +186,7 @@ public final class CraftItemStack extends ItemStack { +@@ -198,7 +198,7 @@ public final class CraftItemStack extends ItemStack { } this.handle.setCount(amount); From dd87f9fe83f98116d2b79102edcd74ab72efd2f4 Mon Sep 17 00:00:00 2001 From: Noah van der Aa Date: Thu, 24 Oct 2024 00:11:28 +0200 Subject: [PATCH 032/119] fix gruesome copyright violation --- .../server/0776-Improve-PortalEvents.patch | 81 ------------------- 1 file changed, 81 deletions(-) diff --git a/patches/server/0776-Improve-PortalEvents.patch b/patches/server/0776-Improve-PortalEvents.patch index f90d31290b95..56e73369b7cb 100644 --- a/patches/server/0776-Improve-PortalEvents.patch +++ b/patches/server/0776-Improve-PortalEvents.patch @@ -101,84 +101,3 @@ index fb361eac03c16ecee02219ff0524cce2292c7976..2b31bf586c1c0bd393d2aa8d0b6635dd } else { boolean flag = worldserver1.getTypeKey() == LevelStem.NETHER; // CraftBukkit end -diff --git a/src/main/java/net/minecraft/world/level/portal/DimensionTransition.java b/src/main/java/net/minecraft/world/level/portal/DimensionTransition.java -new file mode 100644 -index 0000000000000000000000000000000000000000..36c8735312c885eb153f4ffdf0f2a5495e9c9f65 ---- /dev/null -+++ b/src/main/java/net/minecraft/world/level/portal/DimensionTransition.java -@@ -0,0 +1,75 @@ -+package net.minecraft.world.level.portal; -+ -+import net.minecraft.core.BlockPos; -+import net.minecraft.network.protocol.game.ClientboundLevelEventPacket; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.phys.Vec3; -+// CraftBukkit start -+import org.bukkit.event.player.PlayerTeleportEvent; -+ -+public record DimensionTransition(ServerLevel newLevel, Vec3 pos, Vec3 speed, float yRot, float xRot, boolean missingRespawnBlock, DimensionTransition.PostDimensionTransition postDimensionTransition, PlayerTeleportEvent.TeleportCause cause) { -+ -+ public DimensionTransition(ServerLevel newLevel, Vec3 pos, Vec3 speed, float yRot, float xRot, boolean missingRespawnBlock, DimensionTransition.PostDimensionTransition postDimensionTransition) { -+ this(newLevel, pos, speed, yRot, xRot, missingRespawnBlock, postDimensionTransition, PlayerTeleportEvent.TeleportCause.UNKNOWN); -+ } -+ -+ // Paper - remove unused constructor (for safety) -+ // CraftBukkit end -+ -+ public static final DimensionTransition.PostDimensionTransition DO_NOTHING = (entity) -> { -+ }; -+ public static final DimensionTransition.PostDimensionTransition PLAY_PORTAL_SOUND = DimensionTransition::playPortalSound; -+ public static final DimensionTransition.PostDimensionTransition PLACE_PORTAL_TICKET = DimensionTransition::placePortalTicket; -+ -+ public DimensionTransition(ServerLevel world, Vec3 pos, Vec3 velocity, float yaw, float pitch, DimensionTransition.PostDimensionTransition postDimensionTransition) { -+ // CraftBukkit start -+ this(world, pos, velocity, yaw, pitch, postDimensionTransition, PlayerTeleportEvent.TeleportCause.UNKNOWN); -+ } -+ -+ public DimensionTransition(ServerLevel worldserver, Vec3 vec3d, Vec3 vec3d1, float f, float f1, DimensionTransition.PostDimensionTransition dimensiontransition_a, PlayerTeleportEvent.TeleportCause cause) { -+ this(worldserver, vec3d, vec3d1, f, f1, false, dimensiontransition_a, cause); -+ } -+ -+ public DimensionTransition(ServerLevel world, Entity entity, DimensionTransition.PostDimensionTransition postDimensionTransition) { -+ this(world, entity, postDimensionTransition, PlayerTeleportEvent.TeleportCause.UNKNOWN); -+ } -+ -+ public DimensionTransition(ServerLevel worldserver, Entity entity, DimensionTransition.PostDimensionTransition dimensiontransition_a, PlayerTeleportEvent.TeleportCause cause) { -+ this(worldserver, findAdjustedSharedSpawnPos(worldserver, entity), Vec3.ZERO, worldserver.getSharedSpawnAngle(), 0.0F, false, dimensiontransition_a, cause); // Paper - MC-200092 - fix spawn pos yaw being ignored -+ // CraftBukkit end -+ } -+ -+ private static void playPortalSound(Entity entity) { -+ if (entity instanceof ServerPlayer entityplayer) { -+ entityplayer.connection.send(new ClientboundLevelEventPacket(1032, BlockPos.ZERO, 0, false)); -+ } -+ -+ } -+ -+ private static void placePortalTicket(Entity entity) { -+ entity.placePortalTicket(BlockPos.containing(entity.position())); -+ } -+ -+ public static DimensionTransition missingRespawnBlock(ServerLevel world, Entity entity, DimensionTransition.PostDimensionTransition postDimensionTransition) { -+ return new DimensionTransition(world, findAdjustedSharedSpawnPos(world, entity), Vec3.ZERO, world.getSharedSpawnAngle(), 0.0F, true, postDimensionTransition); // Paper - MC-200092 - fix spawn pos yaw being ignored -+ } -+ -+ private static Vec3 findAdjustedSharedSpawnPos(ServerLevel world, Entity entity) { -+ return entity.adjustSpawnLocation(world, world.getSharedSpawnPos()).getBottomCenter(); -+ } -+ -+ @FunctionalInterface -+ public interface PostDimensionTransition { -+ -+ void onTransition(Entity entity); -+ -+ default DimensionTransition.PostDimensionTransition then(DimensionTransition.PostDimensionTransition next) { -+ return (entity) -> { -+ this.onTransition(entity); -+ next.onTransition(entity); -+ }; -+ } -+ } -+} From 5a6011c08c80fb2c7e0c7242bf272f8cde078cb2 Mon Sep 17 00:00:00 2001 From: Noah van der Aa Date: Thu, 24 Oct 2024 00:32:21 +0200 Subject: [PATCH 033/119] MOOOOOOOOOOOOOORE --- ...ix-force-opening-enchantment-tables.patch} | 2 +- .../0788-Add-Entity-Body-Yaw-API.patch} | 8 ++-- ...vent-sleeping-villagers-moving-towa.patch} | 2 +- .../0790-Add-EntityFertilizeEggEvent.patch} | 22 +++++------ ...ty-drop-not-updating-the-client-inv.patch} | 4 +- ...temEvent-and-EntityCompostItemEvent.patch} | 6 +-- ...ctly-handle-ArmorStand-invisibility.patch} | 2 +- ...ancement-triggers-for-entity-damage.patch} | 10 ++--- ...795-Fix-text-display-error-on-spawn.patch} | 4 +- ...nventories-returning-null-Locations.patch} | 4 +- .../0797-Add-Shearable-API.patch} | 2 +- ...Fix-SpawnEggMeta-get-setSpawnedType.patch} | 0 ...g-to-bad-recipes-in-furnace-like-ti.patch} | 10 ++--- ...ence-violations-like-they-should-be.patch} | 4 +- ...xpired-keys-from-impacting-new-join.patch} | 14 +++---- ...ts-being-fired-from-unloaded-chunks.patch} | 4 +- ...0803-Use-array-for-gamerule-storage.patch} | 37 +++++++------------ ...Fix-a-couple-of-upstream-bed-issues.patch} | 8 ++-- ...ix-demo-flag-not-enabling-demo-mode.patch} | 2 +- .../0806-Add-Mob-Experience-reward-API.patch} | 14 ++----- ...redstone-on-top-of-trap-doors-early.patch} | 4 +- ...Lazy-Initialization-for-Enum-Fields.patch} | 0 ...09-More-accurate-isInOpenWater-impl.patch} | 0 .../0810-Expand-PlayerItemMendEvent.patch} | 14 +++---- 24 files changed, 79 insertions(+), 98 deletions(-) rename patches/{unapplied/server/0792-Fix-force-opening-enchantment-tables.patch => server/0787-Fix-force-opening-enchantment-tables.patch} (94%) rename patches/{unapplied/server/0793-Add-Entity-Body-Yaw-API.patch => server/0788-Add-Entity-Body-Yaw-API.patch} (85%) rename patches/{unapplied/server/0794-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch => server/0789-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch} (93%) rename patches/{unapplied/server/0795-Add-EntityFertilizeEggEvent.patch => server/0790-Add-EntityFertilizeEggEvent.patch} (85%) rename patches/{unapplied/server/0796-Fix-HumanEntity-drop-not-updating-the-client-inv.patch => server/0791-Fix-HumanEntity-drop-not-updating-the-client-inv.patch} (90%) rename patches/{unapplied/server/0797-Add-CompostItemEvent-and-EntityCompostItemEvent.patch => server/0792-Add-CompostItemEvent-and-EntityCompostItemEvent.patch} (91%) rename patches/{unapplied/server/0798-Correctly-handle-ArmorStand-invisibility.patch => server/0793-Correctly-handle-ArmorStand-invisibility.patch} (91%) rename patches/{unapplied/server/0799-Fix-advancement-triggers-for-entity-damage.patch => server/0794-Fix-advancement-triggers-for-entity-damage.patch} (88%) rename patches/{unapplied/server/0800-Fix-text-display-error-on-spawn.patch => server/0795-Fix-text-display-error-on-spawn.patch} (85%) rename patches/{unapplied/server/0801-Fix-inventories-returning-null-Locations.patch => server/0796-Fix-inventories-returning-null-Locations.patch} (94%) rename patches/{unapplied/server/0802-Add-Shearable-API.patch => server/0797-Add-Shearable-API.patch} (98%) rename patches/{unapplied/server/0803-Fix-SpawnEggMeta-get-setSpawnedType.patch => server/0798-Fix-SpawnEggMeta-get-setSpawnedType.patch} (100%) rename patches/{unapplied/server/0804-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch => server/0799-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch} (67%) rename patches/{unapplied/server/0805-Treat-sequence-violations-like-they-should-be.patch => server/0800-Treat-sequence-violations-like-they-should-be.patch} (87%) rename patches/{unapplied/server/0806-Prevent-causing-expired-keys-from-impacting-new-join.patch => server/0801-Prevent-causing-expired-keys-from-impacting-new-join.patch} (88%) rename patches/{unapplied/server/0807-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch => server/0802-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch} (83%) rename patches/{unapplied/server/0808-Use-array-for-gamerule-storage.patch => server/0803-Use-array-for-gamerule-storage.patch} (60%) rename patches/{unapplied/server/0809-Fix-a-couple-of-upstream-bed-issues.patch => server/0804-Fix-a-couple-of-upstream-bed-issues.patch} (86%) rename patches/{unapplied/server/0810-Fix-demo-flag-not-enabling-demo-mode.patch => server/0805-Fix-demo-flag-not-enabling-demo-mode.patch} (91%) rename patches/{unapplied/server/0811-Add-Mob-Experience-reward-API.patch => server/0806-Add-Mob-Experience-reward-API.patch} (56%) rename patches/{unapplied/server/0812-Break-redstone-on-top-of-trap-doors-early.patch => server/0807-Break-redstone-on-top-of-trap-doors-early.patch} (93%) rename patches/{unapplied/server/0813-Avoid-Lazy-Initialization-for-Enum-Fields.patch => server/0808-Avoid-Lazy-Initialization-for-Enum-Fields.patch} (100%) rename patches/{unapplied/server/0814-More-accurate-isInOpenWater-impl.patch => server/0809-More-accurate-isInOpenWater-impl.patch} (100%) rename patches/{unapplied/server/0815-Expand-PlayerItemMendEvent.patch => server/0810-Expand-PlayerItemMendEvent.patch} (89%) diff --git a/patches/unapplied/server/0792-Fix-force-opening-enchantment-tables.patch b/patches/server/0787-Fix-force-opening-enchantment-tables.patch similarity index 94% rename from patches/unapplied/server/0792-Fix-force-opening-enchantment-tables.patch rename to patches/server/0787-Fix-force-opening-enchantment-tables.patch index 89326fc719cd..6ddc05bd3fd8 100644 --- a/patches/unapplied/server/0792-Fix-force-opening-enchantment-tables.patch +++ b/patches/server/0787-Fix-force-opening-enchantment-tables.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix force-opening enchantment tables diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index 049db909fbd8610ebb688d948f5d03c97ab23495..1ff114f792ca12bc5408cdd9ab0ad23c3158b99c 100644 +index df9d02eb1ffc3cc669e835e2c08d951283871db3..04fe27a84eb240f8e9bb0ed5b21fd60cfed619ad 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -411,7 +411,18 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { diff --git a/patches/unapplied/server/0793-Add-Entity-Body-Yaw-API.patch b/patches/server/0788-Add-Entity-Body-Yaw-API.patch similarity index 85% rename from patches/unapplied/server/0793-Add-Entity-Body-Yaw-API.patch rename to patches/server/0788-Add-Entity-Body-Yaw-API.patch index c1be71053d18..bac79c9d6914 100644 --- a/patches/unapplied/server/0793-Add-Entity-Body-Yaw-API.patch +++ b/patches/server/0788-Add-Entity-Body-Yaw-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Entity Body Yaw API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index ac513d3162a0794f226abc80bff21c799fe5802c..7c7501b4b21530d0641774f64e87d7d1ca71a33c 100644 +index 5e413803f9bdc898a9a644cb123363cbdf447ad8..f473df7a5aea6a89fb1eed28c9071b7eb3269cf8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1183,6 +1183,33 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1184,6 +1184,33 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } // Paper end - entity powdered snow API @@ -43,10 +43,10 @@ index ac513d3162a0794f226abc80bff21c799fe5802c..7c7501b4b21530d0641774f64e87d7d1 @Override public boolean isInvisible() { // Paper - moved up from LivingEntity diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 516ea1ec9ae5069c3c0e4708f62164a91960b627..a50803a9b41cf3c0b081eb6b786f952dd0ed284f 100644 +index 2fd4a3068d86a37cc18c9203448823c53d590ffb..203e06fdff824ba67dce0e026f7ea5b746d7f258 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -1192,4 +1192,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -1211,4 +1211,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { this.getHandle().frictionState = state; } // Paper end - friction API diff --git a/patches/unapplied/server/0794-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch b/patches/server/0789-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch similarity index 93% rename from patches/unapplied/server/0794-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch rename to patches/server/0789-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch index 962917dab8fd..9c1f7e2d4757 100644 --- a/patches/unapplied/server/0794-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch +++ b/patches/server/0789-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch @@ -10,7 +10,7 @@ https://bugs.mojang.com/browse/MC-157464 https://github.com/PaperMC/Paper/issues/8569 diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java -index 5a18bf854792339fcd54e32f8053d014f3d195a5..f000a6c1e61198e6dd06ae5f084d12fdf309f50a 100644 +index 1c5cec4e3dbf2daf9e06d8d7dfb30b3f7744a1f5..bb65d46967cb04f611b3c9c97d5732cfb21ede9b 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java @@ -38,7 +38,7 @@ public class VillagerGoalPackages { diff --git a/patches/unapplied/server/0795-Add-EntityFertilizeEggEvent.patch b/patches/server/0790-Add-EntityFertilizeEggEvent.patch similarity index 85% rename from patches/unapplied/server/0795-Add-EntityFertilizeEggEvent.patch rename to patches/server/0790-Add-EntityFertilizeEggEvent.patch index 07253994cb05..7b48ce0ca2f4 100644 --- a/patches/unapplied/server/0795-Add-EntityFertilizeEggEvent.patch +++ b/patches/server/0790-Add-EntityFertilizeEggEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add EntityFertilizeEggEvent diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java -index 34e6bf677a9f4548f3febe6d57e6af9602530271..2e5ef2a680e294b49f29e8d7ba8bd0ed023c393c 100644 +index ed7f5eb9b3b700c2f817d61ee0bf8a6952731510..8e91f930e19a91db44274e4ecd98841362867609 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java +++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java -@@ -441,6 +441,10 @@ public class Turtle extends Animal { +@@ -448,6 +448,10 @@ public class Turtle extends Animal { if (entityplayer == null && this.partner.getLoveCause() != null) { entityplayer = this.partner.getLoveCause(); } @@ -19,20 +19,20 @@ index 34e6bf677a9f4548f3febe6d57e6af9602530271..2e5ef2a680e294b49f29e8d7ba8bd0ed if (entityplayer != null) { entityplayer.awardStat(Stats.ANIMALS_BRED); -@@ -455,7 +459,7 @@ public class Turtle extends Animal { +@@ -462,7 +466,7 @@ public class Turtle extends Animal { RandomSource randomsource = this.animal.getRandom(); - if (this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { + if (getServerLevel((Level) this.level).getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { - this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), randomsource.nextInt(7) + 1, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer)); // Paper; -+ if (event.getExperience() > 0) this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), event.getExperience(), org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer)); // Paper - Add EntityFertilizeEggEvent event ++ if (event.getExperience() > 0) this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), randomsource.nextInt(7) + 1, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer)); // Paper - Add EntityFertilizeEggEvent event } } diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java -index a7af50ebc17abd829a7254c03785206da9624060..816977990639ec0559b652fc9666afd5046f0a5d 100644 +index 100be2ed533450eda32d9c4eb9eb1067846d1516..36846ba6b6c7494c745ebd8b221479a9d02ff318 100644 --- a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java +++ b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java -@@ -261,7 +261,12 @@ public class Frog extends Animal implements VariantHolder> { +@@ -270,7 +270,12 @@ public class Frog extends Animal implements VariantHolder> { @Override public void spawnChildFromBreeding(ServerLevel world, Animal other) { @@ -47,10 +47,10 @@ index a7af50ebc17abd829a7254c03785206da9624060..816977990639ec0559b652fc9666afd5 } diff --git a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java -index d34d8fe70379dcad9540739ec0ae1c94f01fc46b..fadd341ff398886a4da102eefa1beb95a63bbd6d 100644 +index 0395b120590552518a85f36a46b68532e936de49..7f70237a274fde0fb97880c1d47246157e3b3415 100644 --- a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java +++ b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java -@@ -345,11 +345,16 @@ public class Sniffer extends Animal { +@@ -340,11 +340,16 @@ public class Sniffer extends Animal { @Override public void spawnChildFromBreeding(ServerLevel world, Animal other) { @@ -69,10 +69,10 @@ index d34d8fe70379dcad9540739ec0ae1c94f01fc46b..fadd341ff398886a4da102eefa1beb95 this.playSound(SoundEvents.SNIFFER_EGG_PLOP, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 0.5F); } // Paper - Call EntityDropItemEvent diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index b6cca72b4785d5cf009077c81c1cca718d8cfe28..a0b387ddf3cc1e3473c6b35175ac8b68c717cfbe 100644 +index cb05a94f2856a8bfb478bceb7c8712bc5e7ad5c2..145a278a1b6d9e79c27136e84d8ccea8834c07bc 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -2197,4 +2197,28 @@ public class CraftEventFactory { +@@ -2195,4 +2195,28 @@ populateFields(victim, event); // Paper - make cancellable return event.callEvent(); } // Paper end diff --git a/patches/unapplied/server/0796-Fix-HumanEntity-drop-not-updating-the-client-inv.patch b/patches/server/0791-Fix-HumanEntity-drop-not-updating-the-client-inv.patch similarity index 90% rename from patches/unapplied/server/0796-Fix-HumanEntity-drop-not-updating-the-client-inv.patch rename to patches/server/0791-Fix-HumanEntity-drop-not-updating-the-client-inv.patch index b804a77828d0..21d4d0ad650a 100644 --- a/patches/unapplied/server/0796-Fix-HumanEntity-drop-not-updating-the-client-inv.patch +++ b/patches/server/0791-Fix-HumanEntity-drop-not-updating-the-client-inv.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Fix HumanEntity#drop not updating the client inv public net.minecraft.server.level.ServerPlayer containerSynchronizer diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index 1ff114f792ca12bc5408cdd9ab0ad23c3158b99c..b782cc64426a058881947ed62316c1cb8d332037 100644 +index 04fe27a84eb240f8e9bb0ed5b21fd60cfed619ad..7dddf4dd090fcd9e86b147d7e4ddeaa99800713e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -@@ -759,8 +759,15 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { +@@ -782,8 +782,15 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { // Paper end @Override public boolean dropItem(boolean dropAll) { diff --git a/patches/unapplied/server/0797-Add-CompostItemEvent-and-EntityCompostItemEvent.patch b/patches/server/0792-Add-CompostItemEvent-and-EntityCompostItemEvent.patch similarity index 91% rename from patches/unapplied/server/0797-Add-CompostItemEvent-and-EntityCompostItemEvent.patch rename to patches/server/0792-Add-CompostItemEvent-and-EntityCompostItemEvent.patch index 85321a4a5ba1..eba5cdc5c9da 100644 --- a/patches/unapplied/server/0797-Add-CompostItemEvent-and-EntityCompostItemEvent.patch +++ b/patches/server/0792-Add-CompostItemEvent-and-EntityCompostItemEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add CompostItemEvent and EntityCompostItemEvent diff --git a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java -index 19fa8a9f935e9063497f8c0bd7909036fa0af2b7..d3d12f9114173f4971f95d7ef895a4374705bd3f 100644 +index 60bf63c2cff3ce8a1892ba5c2303738c35b83d79..2d7712fae0801b6ae48d23cabd46a7700c0c0bec 100644 --- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java -@@ -336,7 +336,21 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -340,7 +340,21 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { int i = (Integer) iblockdata.getValue(ComposterBlock.LEVEL); float f = ComposterBlock.COMPOSTABLES.getFloat(itemstack.getItem()); @@ -31,7 +31,7 @@ index 19fa8a9f935e9063497f8c0bd7909036fa0af2b7..d3d12f9114173f4971f95d7ef895a437 return iblockdata; } else { int j = i + 1; -@@ -485,6 +499,11 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -489,6 +503,11 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { if (!itemstack.isEmpty()) { this.changed = true; BlockState iblockdata = ComposterBlock.addItem((Entity) null, this.state, this.level, this.pos, itemstack); diff --git a/patches/unapplied/server/0798-Correctly-handle-ArmorStand-invisibility.patch b/patches/server/0793-Correctly-handle-ArmorStand-invisibility.patch similarity index 91% rename from patches/unapplied/server/0798-Correctly-handle-ArmorStand-invisibility.patch rename to patches/server/0793-Correctly-handle-ArmorStand-invisibility.patch index 34b66d686a11..c3b0b191aaa7 100644 --- a/patches/unapplied/server/0798-Correctly-handle-ArmorStand-invisibility.patch +++ b/patches/server/0793-Correctly-handle-ArmorStand-invisibility.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Correctly handle ArmorStand invisibility diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java -index 1087840331f68ffe79e79f6493137b2b894832f9..9fe85d6f807e64cf02d8e1921672e3196f6d606f 100644 +index e1cedcb95e9b2e2e9587b623256b5cffa7b08ce4..a2a0064ed86628494e80cb6f6357b4cd9f91f04b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java @@ -152,6 +152,14 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { diff --git a/patches/unapplied/server/0799-Fix-advancement-triggers-for-entity-damage.patch b/patches/server/0794-Fix-advancement-triggers-for-entity-damage.patch similarity index 88% rename from patches/unapplied/server/0799-Fix-advancement-triggers-for-entity-damage.patch rename to patches/server/0794-Fix-advancement-triggers-for-entity-damage.patch index 94c53ab61cd8..fff5e6ce2519 100644 --- a/patches/unapplied/server/0799-Fix-advancement-triggers-for-entity-damage.patch +++ b/patches/server/0794-Fix-advancement-triggers-for-entity-damage.patch @@ -10,10 +10,10 @@ Fixes a couple places where the original damage and modified damage were passed in the reverse order to the advancement triggers diff --git a/src/main/java/net/minecraft/world/entity/Interaction.java b/src/main/java/net/minecraft/world/entity/Interaction.java -index 2ebbf7954dc5e0d6c9d53327d05b725eec310086..c5bd2e90ad74ba08910f65a2e07b6f76435df10f 100644 +index 821bb93e1b055ba38fafe3b7079d79aa062ebe8a..221d73676fe2fd240a47cf312c1179e049298cac 100644 --- a/src/main/java/net/minecraft/world/entity/Interaction.java +++ b/src/main/java/net/minecraft/world/entity/Interaction.java -@@ -156,7 +156,7 @@ public class Interaction extends Entity implements Attackable, Targeting { +@@ -159,7 +159,7 @@ public class Interaction extends Entity implements Attackable, Targeting { // CraftBukkit end this.attack = new Interaction.PlayerAction(entityhuman.getUUID(), this.level().getGameTime()); if (entityhuman instanceof ServerPlayer entityplayer) { @@ -23,10 +23,10 @@ index 2ebbf7954dc5e0d6c9d53327d05b725eec310086..c5bd2e90ad74ba08910f65a2e07b6f76 return !this.getResponse(); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 9e58a85a7de53b17fa149ae0b4951baa351d99db..4e96a65396b687d2823f2229744f5d448ba87512 100644 +index 447fb76a3eb1505b1ef1e1aed8a11239c0124f4f..95bbde31de42e1e12d722de86085e59050f1c3ae 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2388,7 +2388,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2465,7 +2465,7 @@ public abstract class LivingEntity extends Entity implements Attackable { // Duplicate triggers if blocking if (event.getDamage(DamageModifier.BLOCKING) < 0) { if (this instanceof ServerPlayer) { @@ -35,7 +35,7 @@ index 9e58a85a7de53b17fa149ae0b4951baa351d99db..4e96a65396b687d2823f2229744f5d44 f2 = (float) -event.getDamage(DamageModifier.BLOCKING); if (f2 > 0.0F && f2 < 3.4028235E37F) { ((ServerPlayer) this).awardStat(Stats.DAMAGE_BLOCKED_BY_SHIELD, Math.round(originalDamage * 10.0F)); -@@ -2396,7 +2396,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2473,7 +2473,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } if (damagesource.getEntity() instanceof ServerPlayer) { diff --git a/patches/unapplied/server/0800-Fix-text-display-error-on-spawn.patch b/patches/server/0795-Fix-text-display-error-on-spawn.patch similarity index 85% rename from patches/unapplied/server/0800-Fix-text-display-error-on-spawn.patch rename to patches/server/0795-Fix-text-display-error-on-spawn.patch index 7f64cfe6d999..d783ac8eee58 100644 --- a/patches/unapplied/server/0800-Fix-text-display-error-on-spawn.patch +++ b/patches/server/0795-Fix-text-display-error-on-spawn.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix text display error on spawn diff --git a/src/main/java/net/minecraft/world/entity/Display.java b/src/main/java/net/minecraft/world/entity/Display.java -index bd56721485b3b4ac81c97d60fc2a83bfc20977c0..a658943669cdfd49f66ba713505d11b33306ed86 100644 +index d7d940e6b397e52cb7d78bc6f5fc26e8096f9228..e6cbf4506c75046a89fad778e138b448fb4a29a9 100644 --- a/src/main/java/net/minecraft/world/entity/Display.java +++ b/src/main/java/net/minecraft/world/entity/Display.java -@@ -892,7 +892,7 @@ public abstract class Display extends Entity { +@@ -903,7 +903,7 @@ public abstract class Display extends Entity { b = loadFlag(b, nbt, "default_background", (byte)4); Optional optional = Display.TextDisplay.Align.CODEC .decode(NbtOps.INSTANCE, nbt.get("alignment")) diff --git a/patches/unapplied/server/0801-Fix-inventories-returning-null-Locations.patch b/patches/server/0796-Fix-inventories-returning-null-Locations.patch similarity index 94% rename from patches/unapplied/server/0801-Fix-inventories-returning-null-Locations.patch rename to patches/server/0796-Fix-inventories-returning-null-Locations.patch index 23413d6b0304..1a65689fadbb 100644 --- a/patches/unapplied/server/0801-Fix-inventories-returning-null-Locations.patch +++ b/patches/server/0796-Fix-inventories-returning-null-Locations.patch @@ -9,7 +9,7 @@ when a block or entity location is readily available Co-authored-by: Lukas Planz diff --git a/src/main/java/net/minecraft/world/SimpleContainer.java b/src/main/java/net/minecraft/world/SimpleContainer.java -index c26161784359ea167e11de8aa58eda3b4851059c..6632cf24ebe6d147950a1fdb876660937da86b73 100644 +index 13a32ef8f86b678dcce83c41c78b47d9aab9f16b..b0963c534afe5be164701cb283f1849e32ae5a86 100644 --- a/src/main/java/net/minecraft/world/SimpleContainer.java +++ b/src/main/java/net/minecraft/world/SimpleContainer.java @@ -63,6 +63,16 @@ public class SimpleContainer implements Container, StackedContentsCompatible { @@ -30,7 +30,7 @@ index c26161784359ea167e11de8aa58eda3b4851059c..6632cf24ebe6d147950a1fdb87666093 } diff --git a/src/main/java/net/minecraft/world/inventory/BeaconMenu.java b/src/main/java/net/minecraft/world/inventory/BeaconMenu.java -index 8b0ebf659f6b219ce2a5d10b0d79f9b89b47c911..a735aeeb59f79154ce797c6e2f5600305f46d217 100644 +index 9db647cfbd3f9c884465cf3d3a1b911d46a3da58..c0dfa04511110be366ee5b0bd75efc51afcce2e4 100644 --- a/src/main/java/net/minecraft/world/inventory/BeaconMenu.java +++ b/src/main/java/net/minecraft/world/inventory/BeaconMenu.java @@ -52,6 +52,12 @@ public class BeaconMenu extends AbstractContainerMenu { diff --git a/patches/unapplied/server/0802-Add-Shearable-API.patch b/patches/server/0797-Add-Shearable-API.patch similarity index 98% rename from patches/unapplied/server/0802-Add-Shearable-API.patch rename to patches/server/0797-Add-Shearable-API.patch index 3cf9cf301552..5d99e92e0b75 100644 --- a/patches/unapplied/server/0802-Add-Shearable-API.patch +++ b/patches/server/0797-Add-Shearable-API.patch @@ -45,7 +45,7 @@ index 0139e85c0751564bb4d2847b7b2e48f75fee9e53..e8e4704304504e69c7964dcd4df8ce5d public CraftBogged(CraftServer server, net.minecraft.world.entity.monster.Bogged entity) { super(server, entity); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java -index 986f7b18112ef183de3bbff269a92bf6ac945477..9cc81bcccbf1141f66fedada1359b7c0dfa8e22a 100644 +index 901b751c856dea677d5238db1ee70401a9d7bba5..bfe39c7a9d2910bee9b40cf5ab4c154711d5cbb0 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java @@ -14,7 +14,7 @@ import org.bukkit.entity.MushroomCow; diff --git a/patches/unapplied/server/0803-Fix-SpawnEggMeta-get-setSpawnedType.patch b/patches/server/0798-Fix-SpawnEggMeta-get-setSpawnedType.patch similarity index 100% rename from patches/unapplied/server/0803-Fix-SpawnEggMeta-get-setSpawnedType.patch rename to patches/server/0798-Fix-SpawnEggMeta-get-setSpawnedType.patch diff --git a/patches/unapplied/server/0804-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch b/patches/server/0799-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch similarity index 67% rename from patches/unapplied/server/0804-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch rename to patches/server/0799-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch index d90e59989716..05a14ce9774b 100644 --- a/patches/unapplied/server/0804-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch +++ b/patches/server/0799-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch @@ -6,14 +6,14 @@ Subject: [PATCH] Fix crash relating to bad recipes in furnace-like tile diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index f1a7054a0ee1842e78338d8984f151b24c352849..65ab9b22f724877b68f4f25aad2831e2cb080b19 100644 +index 18f8b2c469feef659437684ce156a79ec3a3ce83..ecb9abc570ef87541184a8033cb33c82a4d1daf2 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -@@ -616,6 +616,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit - Entry entry = (Entry) objectiterator.next(); +@@ -499,6 +499,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit + Entry>> entry = (Entry) objectiterator.next(); - worldserver.getRecipeManager().byKey((ResourceLocation) entry.getKey()).ifPresent((recipeholder) -> { + worldserver.recipeAccess().byKey(entry.getKey()).ifPresent((recipeholder) -> { // CraftBukkit - decompile error + if (!(recipeholder.value() instanceof AbstractCookingRecipe)) return; // Paper - don't process non-cooking recipes list.add(recipeholder); - AbstractFurnaceBlockEntity.createExperience(worldserver, vec3d, entry.getIntValue(), ((AbstractCookingRecipe) recipeholder.value()).getExperience(), blockposition, entityplayer, itemstack, amount); // CraftBukkit + AbstractFurnaceBlockEntity.createExperience(worldserver, vec3d, entry.getIntValue(), ((AbstractCookingRecipe) recipeholder.value()).experience(), blockposition, entityplayer, itemstack, amount); // CraftBukkit }); diff --git a/patches/unapplied/server/0805-Treat-sequence-violations-like-they-should-be.patch b/patches/server/0800-Treat-sequence-violations-like-they-should-be.patch similarity index 87% rename from patches/unapplied/server/0805-Treat-sequence-violations-like-they-should-be.patch rename to patches/server/0800-Treat-sequence-violations-like-they-should-be.patch index e0fce8efcebe..3cb7bfe53625 100644 --- a/patches/unapplied/server/0805-Treat-sequence-violations-like-they-should-be.patch +++ b/patches/server/0800-Treat-sequence-violations-like-they-should-be.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Treat sequence violations like they should be diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index a6f58438badb0bdeab67706f4a8e519b202623fe..5a710de60a57c8af4eb083e17f03e801858dc2d9 100644 +index d77ab963802fcd7551058987a534ba54f080027a..74054e0acd2ecdc6d7ccdf035c9ec120872f6ef4 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1976,6 +1976,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1989,6 +1989,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void ackBlockChangesUpTo(int sequence) { if (sequence < 0) { diff --git a/patches/unapplied/server/0806-Prevent-causing-expired-keys-from-impacting-new-join.patch b/patches/server/0801-Prevent-causing-expired-keys-from-impacting-new-join.patch similarity index 88% rename from patches/unapplied/server/0806-Prevent-causing-expired-keys-from-impacting-new-join.patch rename to patches/server/0801-Prevent-causing-expired-keys-from-impacting-new-join.patch index ee811c8ba644..8c461c04b6b1 100644 --- a/patches/unapplied/server/0806-Prevent-causing-expired-keys-from-impacting-new-join.patch +++ b/patches/server/0801-Prevent-causing-expired-keys-from-impacting-new-join.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent causing expired keys from impacting new joins diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java -index 68c062cbaa030d62d97c9c003651f8fc17a00a6b..6247a21c9c391abf1f6db3482c659593e4f29355 100644 +index d0b2a8b5ded71a9a41753f4addea1c49826b34a3..29b465fc1dc50e0e84ddb889c5303e80fe662874 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java -@@ -113,7 +113,15 @@ public class ClientboundPlayerInfoUpdatePacket implements Packet serialized.chatSession = buf.readNullable(RemoteChatSession.Data::read), @@ -26,18 +26,18 @@ index 68c062cbaa030d62d97c9c003651f8fc17a00a6b..6247a21c9c391abf1f6db3482c659593 UPDATE_GAME_MODE((serialized, buf) -> serialized.gameMode = GameType.byId(buf.readVarInt()), (buf, entry) -> buf.writeVarInt(entry.gameMode().getId())), UPDATE_LISTED((serialized, buf) -> serialized.listed = buf.readBoolean(), (buf, entry) -> buf.writeBoolean(entry.listed())), diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 5a710de60a57c8af4eb083e17f03e801858dc2d9..db9c04d74475e00983cc9df74d615e4b68f83688 100644 +index 74054e0acd2ecdc6d7ccdf035c9ec120872f6ef4..5d261106b0cd12e9ed737833b1f6d2572d15ab4e 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -295,6 +295,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - private int knownMovePacketCount; +@@ -303,6 +303,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + private boolean receivedMovementThisTick; @Nullable private RemoteChatSession chatSession; + private boolean hasLoggedExpiry = false; // Paper - Prevent causing expired keys from impacting new joins private SignedMessageChain.Decoder signedMessageDecoder; private final LastSeenMessagesValidator lastSeenMessages = new LastSeenMessagesValidator(20); private final MessageSignatureCache messageSignatureCache = MessageSignatureCache.createDefault(); -@@ -402,6 +403,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -399,6 +400,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.disconnect((Component) Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause } @@ -51,7 +51,7 @@ index 5a710de60a57c8af4eb083e17f03e801858dc2d9..db9c04d74475e00983cc9df74d615e4b } private int getMaximumFlyingTicks(Entity vehicle) { -@@ -3434,6 +3442,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3479,6 +3487,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private void resetPlayerChatState(RemoteChatSession session) { this.chatSession = session; diff --git a/patches/unapplied/server/0807-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch b/patches/server/0802-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch similarity index 83% rename from patches/unapplied/server/0807-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch rename to patches/server/0802-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch index 330616349839..7621693e89ad 100644 --- a/patches/unapplied/server/0807-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch +++ b/patches/server/0802-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent GameEvents being fired from unloaded chunks diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 07f7752651095abdd9e9408a419aed7d78173d3a..fd4d1cab675b7b423ac0fdf9a8c9f472ddc68c36 100644 +index 3eaeeb3ec715d92fe99e14c37e224cb1e80a467b..509a67aff07bcdcad47eb77e923d442349a4f20c 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1372,6 +1372,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1385,6 +1385,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public void gameEvent(Holder event, Vec3 emitterPos, GameEvent.Context emitter) { diff --git a/patches/unapplied/server/0808-Use-array-for-gamerule-storage.patch b/patches/server/0803-Use-array-for-gamerule-storage.patch similarity index 60% rename from patches/unapplied/server/0808-Use-array-for-gamerule-storage.patch rename to patches/server/0803-Use-array-for-gamerule-storage.patch index 194ff8f15b08..efb6cfeb5035 100644 --- a/patches/unapplied/server/0808-Use-array-for-gamerule-storage.patch +++ b/patches/server/0803-Use-array-for-gamerule-storage.patch @@ -5,35 +5,24 @@ Subject: [PATCH] Use array for gamerule storage diff --git a/src/main/java/net/minecraft/world/level/GameRules.java b/src/main/java/net/minecraft/world/level/GameRules.java -index 51e560d7856f230c5aa2dc32706c3a4996720aa5..89e327bc3a45879fe68887c7aadb077f31a770eb 100644 +index 09299e45552eb998fd02123c3921c0653f85083d..4ae47c2c5a6bcfbf932d000a80974463e2d3818d 100644 --- a/src/main/java/net/minecraft/world/level/GameRules.java +++ b/src/main/java/net/minecraft/world/level/GameRules.java -@@ -122,6 +122,7 @@ public class GameRules { - worldserver.setDefaultSpawnPos(worldserver.getSharedSpawnPos(), worldserver.getSharedSpawnAngle()); +@@ -129,6 +129,7 @@ public class GameRules { })); private final Map, GameRules.Value> rules; + private final FeatureFlagSet enabledFeatures; + private final GameRules.Value[] gameruleArray; // Paper - Perf: Use array for gamerule storage private static > GameRules.Key register(String name, GameRules.Category category, GameRules.Type type) { GameRules.Key gamerules_gamerulekey = new GameRules.Key<>(name, category); -@@ -140,17 +141,30 @@ public class GameRules { - } - - public GameRules() { -- this.rules = (Map) GameRules.GAME_RULE_TYPES.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry) -> { -+ // Paper start - Perf: Use array for gamerule storage -+ this((Map) GameRules.GAME_RULE_TYPES.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry) -> { - return ((GameRules.Type) entry.getValue()).createRule(); -- })); -+ }))); -+ // Paper end - Perf: Use array for gamerule storage - } - - private GameRules(Map, GameRules.Value> rules) { +@@ -161,10 +162,21 @@ public class GameRules { + private GameRules(Map, GameRules.Value> rules, FeatureFlagSet enabledFeatures) { this.rules = rules; + this.enabledFeatures = enabledFeatures; + + // Paper start - Perf: Use array for gamerule storage -+ int arraySize = rules.keySet().stream().mapToInt(key -> key.gameRuleIndex).max().orElse(-1) + 1; ++ int arraySize = GameRules.Key.lastGameRuleIndex + 1; + GameRules.Value[] values = new GameRules.Value[arraySize]; + + for (Entry, GameRules.Value> entry : rules.entrySet()) { @@ -45,17 +34,17 @@ index 51e560d7856f230c5aa2dc32706c3a4996720aa5..89e327bc3a45879fe68887c7aadb077f } public > T getRule(GameRules.Key key) { -- return (T) this.rules.get(key); // CraftBukkit - decompile error -+ return key == null ? null : (T) this.gameruleArray[key.gameRuleIndex]; // Paper - Perf: Use array for gamerule storage - } +- T t0 = (T) this.rules.get(key); // CraftBukkit - decompile error ++ T t0 = key == null ? null : (T) this.gameruleArray[key.gameRuleIndex]; // Paper - Perf: Use array for gamerule storage - public CompoundTag createTag() { -@@ -209,6 +223,10 @@ public class GameRules { + if (t0 == null) { + throw new IllegalArgumentException("Tried to access invalid game rule"); +@@ -232,6 +244,10 @@ public class GameRules { } public static final class Key> { + // Paper start - Perf: Use array for gamerule storage -+ private static int lastGameRuleIndex = 0; ++ public static int lastGameRuleIndex = 0; + public final int gameRuleIndex = lastGameRuleIndex++; + // Paper end - Perf: Use array for gamerule storage diff --git a/patches/unapplied/server/0809-Fix-a-couple-of-upstream-bed-issues.patch b/patches/server/0804-Fix-a-couple-of-upstream-bed-issues.patch similarity index 86% rename from patches/unapplied/server/0809-Fix-a-couple-of-upstream-bed-issues.patch rename to patches/server/0804-Fix-a-couple-of-upstream-bed-issues.patch index 665db524c5e1..76cfa7bc0d17 100644 --- a/patches/unapplied/server/0809-Fix-a-couple-of-upstream-bed-issues.patch +++ b/patches/server/0804-Fix-a-couple-of-upstream-bed-issues.patch @@ -10,18 +10,18 @@ but then replaced it with a bed, you could respawn at the bed in that world. diff --git a/src/main/java/net/minecraft/world/level/block/BedBlock.java b/src/main/java/net/minecraft/world/level/block/BedBlock.java -index 18b9a62613c08eb5bf63ae26565b0e91e1f44d39..85d598c3354ee62f0fd1b26e485e0084967c0380 100644 +index b09fa473426a6c7e006a071827e5a68560d6c685..c02c4834ace843633b77fb43eeadd3ddc7b1f743 100644 --- a/src/main/java/net/minecraft/world/level/block/BedBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java -@@ -107,6 +107,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock +@@ -109,6 +109,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); - return InteractionResult.SUCCESS; + return InteractionResult.SUCCESS_SERVER; } else if ((Boolean) state.getValue(BedBlock.OCCUPIED)) { + if (!BedBlock.canSetSpawn(world)) return this.explodeBed(state, world, pos); // Paper - check explode first if (!this.kickVillagerOutOfBed(world, pos)) { player.displayClientMessage(Component.translatable("block.minecraft.bed.occupied"), true); } -@@ -164,8 +165,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock +@@ -166,8 +167,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock // CraftBukkit end public static boolean canSetSpawn(Level world) { diff --git a/patches/unapplied/server/0810-Fix-demo-flag-not-enabling-demo-mode.patch b/patches/server/0805-Fix-demo-flag-not-enabling-demo-mode.patch similarity index 91% rename from patches/unapplied/server/0810-Fix-demo-flag-not-enabling-demo-mode.patch rename to patches/server/0805-Fix-demo-flag-not-enabling-demo-mode.patch index d64dd23e3758..1a725719655c 100644 --- a/patches/unapplied/server/0810-Fix-demo-flag-not-enabling-demo-mode.patch +++ b/patches/server/0805-Fix-demo-flag-not-enabling-demo-mode.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Fix demo flag not enabling demo mode https://github.com/PaperMC/Paper/issues/9046 diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index 13e1a914d4523f1c192db2a9a1ee6522e0ee27da..c33f85b570f159ab465b5a10a8044a81f2797f43 100644 +index 47cd7c66ac37efebf2f63c49d78dd8fe44a70ef8..fc6ce3485dc890f5105a37fe3e344a1460867556 100644 --- a/src/main/java/net/minecraft/server/Main.java +++ b/src/main/java/net/minecraft/server/Main.java @@ -325,7 +325,9 @@ public class Main { diff --git a/patches/unapplied/server/0811-Add-Mob-Experience-reward-API.patch b/patches/server/0806-Add-Mob-Experience-reward-API.patch similarity index 56% rename from patches/unapplied/server/0811-Add-Mob-Experience-reward-API.patch rename to patches/server/0806-Add-Mob-Experience-reward-API.patch index f82f765bebe5..9e59c458f81e 100644 --- a/patches/unapplied/server/0811-Add-Mob-Experience-reward-API.patch +++ b/patches/server/0806-Add-Mob-Experience-reward-API.patch @@ -5,18 +5,10 @@ Subject: [PATCH] Add Mob Experience reward API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java -index 921594a78ea511337434b29b5bc1a037eb30992c..deb66c04abefb4a88521483db1612e494bd27164 100644 +index e226a99d00c990a4ca4f21b93fcae7a556e01dbb..95d7015a61098d1d22a501124d6bb8fba1516fe3 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java -@@ -1,6 +1,7 @@ - package org.bukkit.craftbukkit.entity; - - import com.google.common.base.Preconditions; -+import net.minecraft.server.level.ServerLevel; - import net.minecraft.sounds.SoundEvent; - import org.bukkit.Sound; - import org.bukkit.craftbukkit.CraftLootTable; -@@ -167,4 +168,11 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob { +@@ -168,4 +168,11 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob { this.getHandle().setAggressive(aggressive); } // Paper end @@ -24,7 +16,7 @@ index 921594a78ea511337434b29b5bc1a037eb30992c..deb66c04abefb4a88521483db1612e49 + // Paper start + @Override + public int getPossibleExperienceReward() { -+ return getHandle().getExperienceReward((ServerLevel) this.getHandle().level(), null); ++ return getHandle().getExperienceReward((net.minecraft.server.level.ServerLevel) this.getHandle().level(), null); + } + // Paper end } diff --git a/patches/unapplied/server/0812-Break-redstone-on-top-of-trap-doors-early.patch b/patches/server/0807-Break-redstone-on-top-of-trap-doors-early.patch similarity index 93% rename from patches/unapplied/server/0812-Break-redstone-on-top-of-trap-doors-early.patch rename to patches/server/0807-Break-redstone-on-top-of-trap-doors-early.patch index 11c427e8082f..ded460b32b52 100644 --- a/patches/unapplied/server/0812-Break-redstone-on-top-of-trap-doors-early.patch +++ b/patches/server/0807-Break-redstone-on-top-of-trap-doors-early.patch @@ -7,10 +7,10 @@ This logic hooks into the neighbour update which should be invoked as a result of redstone powering the trap door. diff --git a/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java b/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java -index 82e38b01446d35aa9745be6ff3c7647b46379682..336fcf4af0ffb416b5595a9e65172f36cc36aaa3 100644 +index a7d52f2f9c324c5af979fc39b3662ebc880e36fb..872e52e13293a99d45f93d90d8fa7f6aa99d1f3a 100644 --- a/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java -@@ -153,7 +153,26 @@ public class TrapDoorBlock extends HorizontalDirectionalBlock implements SimpleW +@@ -157,7 +157,26 @@ public class TrapDoorBlock extends HorizontalDirectionalBlock implements SimpleW flag1 = eventRedstone.getNewCurrent() > 0; } // CraftBukkit end diff --git a/patches/unapplied/server/0813-Avoid-Lazy-Initialization-for-Enum-Fields.patch b/patches/server/0808-Avoid-Lazy-Initialization-for-Enum-Fields.patch similarity index 100% rename from patches/unapplied/server/0813-Avoid-Lazy-Initialization-for-Enum-Fields.patch rename to patches/server/0808-Avoid-Lazy-Initialization-for-Enum-Fields.patch diff --git a/patches/unapplied/server/0814-More-accurate-isInOpenWater-impl.patch b/patches/server/0809-More-accurate-isInOpenWater-impl.patch similarity index 100% rename from patches/unapplied/server/0814-More-accurate-isInOpenWater-impl.patch rename to patches/server/0809-More-accurate-isInOpenWater-impl.patch diff --git a/patches/unapplied/server/0815-Expand-PlayerItemMendEvent.patch b/patches/server/0810-Expand-PlayerItemMendEvent.patch similarity index 89% rename from patches/unapplied/server/0815-Expand-PlayerItemMendEvent.patch rename to patches/server/0810-Expand-PlayerItemMendEvent.patch index 289fae7adb7f..965dcf06033a 100644 --- a/patches/unapplied/server/0815-Expand-PlayerItemMendEvent.patch +++ b/patches/server/0810-Expand-PlayerItemMendEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Expand PlayerItemMendEvent diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -index a758b2456acac23095fe4619ae10300a034cb460..a58ff67052fb5f33782f8b5c83465ec03ef1d073 100644 +index 3a7af27bb1ce0cbe56bd3760cd400083daf98d4c..bf0838f574fa3fb9654e087d602b8d380bd7fb28 100644 --- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java +++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java -@@ -354,7 +354,10 @@ public class ExperienceOrb extends Entity { +@@ -358,7 +358,10 @@ public class ExperienceOrb extends Entity { int j = EnchantmentHelper.modifyDurabilityToRepairFromXp(player.serverLevel(), itemstack, amount); int k = Math.min(j, itemstack.getDamageValue()); // CraftBukkit start @@ -20,7 +20,7 @@ index a758b2456acac23095fe4619ae10300a034cb460..a58ff67052fb5f33782f8b5c83465ec0 k = event.getRepairAmount(); if (event.isCancelled()) { return amount; -@@ -363,7 +366,7 @@ public class ExperienceOrb extends Entity { +@@ -367,7 +370,7 @@ public class ExperienceOrb extends Entity { itemstack.setDamageValue(itemstack.getDamageValue() - k); if (k > 0) { @@ -30,10 +30,10 @@ index a758b2456acac23095fe4619ae10300a034cb460..a58ff67052fb5f33782f8b5c83465ec0 if (l > 0) { // this.value = l; // CraftBukkit - update exp value of orb for PlayerItemMendEvent calls // Paper - the value field should not be mutated here because it doesn't take "count" into account diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 06a3ccb90f23fc357e5cbc6e9173baab4b218955..3945a6ab723deee3ec3ebb5fbc726ce16bbca411 100644 +index 76d8f0d390abf588886b42b6d2e3ed6f79a4d991..cdc53abb5572fa57b4ec98a694c5583ad0982a05 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1853,11 +1853,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1866,11 +1866,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { handle.serverLevel(), itemstack, amount ); int i = Math.min(possibleDurabilityFromXp, itemstack.getDamageValue()); @@ -49,10 +49,10 @@ index 06a3ccb90f23fc357e5cbc6e9173baab4b218955..3945a6ab723deee3ec3ebb5fbc726ce1 } } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index a0b387ddf3cc1e3473c6b35175ac8b68c717cfbe..9586837f25464396c0695e87fa278c91ca90183a 100644 +index 145a278a1b6d9e79c27136e84d8ccea8834c07bc..ac25a5c933b8748ca44ca02100058992b1aad358 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1286,10 +1286,10 @@ public class CraftEventFactory { +@@ -1284,10 +1284,10 @@ populateFields(victim, event); // Paper - make cancellable return event; } From 5d19e2b3325e57865950b7fc4d26bb8c8af4d680 Mon Sep 17 00:00:00 2001 From: Noah van der Aa Date: Thu, 24 Oct 2024 00:42:38 +0200 Subject: [PATCH 034/119] good luck americans --- ...sh-ProjectileSource-for-projectiles.patch} | 22 ++++++--------- .../0812-Add-transient-modifier-API.patch} | 0 .../0813-Fix-block-place-logic.patch} | 8 +++--- ...nd-playing-for-BlockItem-ItemStacks.patch} | 14 +++++----- ...l-BlockGrowEvent-for-missing-blocks.patch} | 8 +++--- ...nhasbukkit-default-if-alias-block-e.patch} | 4 +-- ...pLike-spam-for-missing-key-selector.patch} | 0 ...-Fix-sniffer-removeExploredLocation.patch} | 0 ...to-remove-all-active-potion-effects.patch} | 4 +-- ...0-Add-event-for-player-editing-sign.patch} | 28 +++++++++---------- ...crafting-result-amount-for-fireworks.patch | 20 ------------- 11 files changed, 42 insertions(+), 66 deletions(-) rename patches/{unapplied/server/0816-Refresh-ProjectileSource-for-projectiles.patch => server/0811-Refresh-ProjectileSource-for-projectiles.patch} (83%) rename patches/{unapplied/server/0817-Add-transient-modifier-API.patch => server/0812-Add-transient-modifier-API.patch} (100%) rename patches/{unapplied/server/0818-Fix-block-place-logic.patch => server/0813-Fix-block-place-logic.patch} (90%) rename patches/{unapplied/server/0819-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch => server/0814-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch} (57%) rename patches/{unapplied/server/0820-Call-BlockGrowEvent-for-missing-blocks.patch => server/0815-Call-BlockGrowEvent-for-missing-blocks.patch} (88%) rename patches/{unapplied/server/0821-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch => server/0816-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch} (90%) rename patches/{unapplied/server/0822-fix-MapLike-spam-for-missing-key-selector.patch => server/0817-fix-MapLike-spam-for-missing-key-selector.patch} (100%) rename patches/{unapplied/server/0823-Fix-sniffer-removeExploredLocation.patch => server/0818-Fix-sniffer-removeExploredLocation.patch} (100%) rename patches/{unapplied/server/0824-Add-method-to-remove-all-active-potion-effects.patch => server/0819-Add-method-to-remove-all-active-potion-effects.patch} (86%) rename patches/{unapplied/server/0826-Add-event-for-player-editing-sign.patch => server/0820-Add-event-for-player-editing-sign.patch} (81%) delete mode 100644 patches/unapplied/server/0825-Fix-incorrect-crafting-result-amount-for-fireworks.patch diff --git a/patches/unapplied/server/0816-Refresh-ProjectileSource-for-projectiles.patch b/patches/server/0811-Refresh-ProjectileSource-for-projectiles.patch similarity index 83% rename from patches/unapplied/server/0816-Refresh-ProjectileSource-for-projectiles.patch rename to patches/server/0811-Refresh-ProjectileSource-for-projectiles.patch index 59deace23461..7bc80ccda253 100644 --- a/patches/unapplied/server/0816-Refresh-ProjectileSource-for-projectiles.patch +++ b/patches/server/0811-Refresh-ProjectileSource-for-projectiles.patch @@ -14,10 +14,10 @@ clearing the owner. Co-authored-by: Warrior <50800980+Warriorrrr@users.noreply.github.com> diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 34e175b28f7c9120b58fc8e2b65ca978c7f301b5..cd362a91ad31dbae94fdb5a8c71839576f397ea1 100644 +index 2c959a99376ed479415354c481801643c5f6b1a1..8cdef637f6343119fc77f87e7478ee23e9b8efab 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -390,6 +390,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -393,6 +393,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public boolean inWorld = false; public boolean generation; public int maxAirTicks = this.getDefaultMaxAirSupply(); // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir() @@ -26,10 +26,10 @@ index 34e175b28f7c9120b58fc8e2b65ca978c7f301b5..cd362a91ad31dbae94fdb5a8c7183957 public boolean lastDamageCancelled; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled public boolean persistentInvisibility = false; diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 63ffa02f820d88f865ae604712edcf2ac13f0bff..f2bdd95a6ae77400742d87bcae35c09fb8b047ba 100644 +index 4d487090a622d280bdfacc18978929c61f74f147..3982b32cf69250ebd138eff225b65313f75286ea 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -57,14 +57,31 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -63,17 +63,35 @@ public abstract class Projectile extends Entity implements TraceableEntity { this.ownerUUID = entity.getUUID(); this.cachedOwner = entity; } @@ -59,18 +59,14 @@ index 63ffa02f820d88f865ae604712edcf2ac13f0bff..f2bdd95a6ae77400742d87bcae35c09f @Override public Entity getOwner() { if (this.cachedOwner != null && !this.cachedOwner.isRemoved()) { ++ this.refreshProjectileSource(false); // Paper - Refresh ProjectileSource for projectiles + return this.cachedOwner; + } else if (this.ownerUUID != null) { + this.cachedOwner = this.findOwner(this.ownerUUID); + this.refreshProjectileSource(false); // Paper - Refresh ProjectileSource for projectiles return this.cachedOwner; } else { - if (this.ownerUUID != null) { -@@ -74,6 +91,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { - ServerLevel worldserver = (ServerLevel) world; - - this.cachedOwner = worldserver.getEntity(this.ownerUUID); -+ this.refreshProjectileSource(false); // Paper - Refresh ProjectileSource for projectiles - return this.cachedOwner; - } - } + return null; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java index de4fb2654c7895cfd83ad694455ee56cb708c2f2..591af9d0d2fdc9953415979fc97a4a00afd85885 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java diff --git a/patches/unapplied/server/0817-Add-transient-modifier-API.patch b/patches/server/0812-Add-transient-modifier-API.patch similarity index 100% rename from patches/unapplied/server/0817-Add-transient-modifier-API.patch rename to patches/server/0812-Add-transient-modifier-API.patch diff --git a/patches/unapplied/server/0818-Fix-block-place-logic.patch b/patches/server/0813-Fix-block-place-logic.patch similarity index 90% rename from patches/unapplied/server/0818-Fix-block-place-logic.patch rename to patches/server/0813-Fix-block-place-logic.patch index accea4ee7c0b..6f5dfc260e3b 100644 --- a/patches/unapplied/server/0818-Fix-block-place-logic.patch +++ b/patches/server/0813-Fix-block-place-logic.patch @@ -9,10 +9,10 @@ Fix several issues when a player interact with a block: * poi can desync when the BlockPhysicsEvent is cancelled diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java -index 7d76cdc59984b156628273c8357485eb10046007..7180996027f70aef7afe32fb2adfce6431429401 100644 +index 44cc12a3338b5f0448c88192c8674cd36531db34..d59120f0304823361cc4112f5583323945df4229 100644 --- a/src/main/java/net/minecraft/world/item/BlockItem.java +++ b/src/main/java/net/minecraft/world/item/BlockItem.java -@@ -128,7 +128,7 @@ public class BlockItem extends Item { +@@ -122,7 +122,7 @@ public class BlockItem extends Item { SoundType soundeffecttype = iblockdata1.getSoundType(); @@ -20,9 +20,9 @@ index 7d76cdc59984b156628273c8357485eb10046007..7180996027f70aef7afe32fb2adfce64 + if (entityhuman == null) world.playSound(entityhuman, blockposition, this.getPlaceSound(iblockdata1), net.minecraft.sounds.SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F); // Paper - Fix block place logic; reintroduce this for the dispenser (i.e the shulker) world.gameEvent((Holder) GameEvent.BLOCK_PLACE, blockposition, GameEvent.Context.of(entityhuman, iblockdata1)); itemstack.consume(1, entityhuman); - return InteractionResult.sidedSuccess(world.isClientSide); + return InteractionResult.SUCCESS; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index cc92d2e8b77c75da1d8b850c3bc251e8ac221c24..0a3e56302470f239d4840e4e32d2a0ce4611ff65 100644 +index a6f538372830f3f80740ef503733736e0561d1bd..d048d0e4b16459b5bad44ebfa3c6a8f336f6762b 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -552,17 +552,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable { diff --git a/patches/unapplied/server/0819-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch b/patches/server/0814-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch similarity index 57% rename from patches/unapplied/server/0819-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch rename to patches/server/0814-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch index c44ec5216d03..45955c4fa8b9 100644 --- a/patches/unapplied/server/0819-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch +++ b/patches/server/0814-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch @@ -5,19 +5,19 @@ Subject: [PATCH] Fix spigot sound playing for BlockItem ItemStacks diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index e64cc91b416bbbefe6aadf1c6b685346cf258ab4..276858d23be2f9443cc364046a55b9c9a88bf4ea 100644 +index d8dc3228f3cd8c9efc8359162edac601a87bf762..5867a0e3e2ce9be7514771549ad318947e387470 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -571,7 +571,11 @@ public final class ItemStack implements DataComponentHolder { +@@ -577,7 +577,11 @@ public final class ItemStack implements DataComponentHolder { - // SPIGOT-1288 - play sound stripped from ItemBlock - if (this.item instanceof BlockItem) { -- SoundType soundeffecttype = ((BlockItem) this.item).getBlock().defaultBlockState().getSoundType(); // TODO: not strictly correct, however currently only affects decorated pots + // SPIGOT-1288 - play sound stripped from ItemBlock + if (this.item instanceof BlockItem) { +- SoundType soundeffecttype = ((BlockItem) this.item).getBlock().defaultBlockState().getSoundType(); // TODO: not strictly correct, however currently only affects decorated pots + // Paper start - Fix spigot sound playing for BlockItem ItemStacks + BlockPos position = new net.minecraft.world.item.context.BlockPlaceContext(context).getClickedPos(); + net.minecraft.world.level.block.state.BlockState blockData = world.getBlockState(position); + SoundType soundeffecttype = blockData.getSoundType(); + // Paper end - Fix spigot sound playing for BlockItem ItemStacks - world.playSound(entityhuman, blockposition, soundeffecttype.getPlaceSound(), SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F); - } + world.playSound(entityhuman, blockposition, soundeffecttype.getPlaceSound(), SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F); + } diff --git a/patches/unapplied/server/0820-Call-BlockGrowEvent-for-missing-blocks.patch b/patches/server/0815-Call-BlockGrowEvent-for-missing-blocks.patch similarity index 88% rename from patches/unapplied/server/0820-Call-BlockGrowEvent-for-missing-blocks.patch rename to patches/server/0815-Call-BlockGrowEvent-for-missing-blocks.patch index 895a528de8ee..d48638c26137 100644 --- a/patches/unapplied/server/0820-Call-BlockGrowEvent-for-missing-blocks.patch +++ b/patches/server/0815-Call-BlockGrowEvent-for-missing-blocks.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Call BlockGrowEvent for missing blocks Call the event for pitcher crops and sniffer egg diff --git a/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java b/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java -index d06e3892cf42723f8e3f621b5497c5348fa1a715..5f1ec3f69295760b7b8097916c82cbf9ddd49700 100644 +index ea6135edc76c06b7cd55930b620dfb05f939e4f6..640e439524cc1e5960ba99f8bd555c7dee8edbf5 100644 --- a/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java -@@ -133,7 +133,7 @@ public class PitcherCropBlock extends DoublePlantBlock implements BonemealableBl +@@ -142,7 +142,7 @@ public class PitcherCropBlock extends DoublePlantBlock implements BonemealableBl int i = Math.min(state.getValue(AGE) + amount, 4); if (this.canGrow(world, pos, state, i)) { BlockState blockState = state.setValue(AGE, Integer.valueOf(i)); @@ -19,10 +19,10 @@ index d06e3892cf42723f8e3f621b5497c5348fa1a715..5f1ec3f69295760b7b8097916c82cbf9 world.setBlock(pos.above(), blockState.setValue(HALF, DoubleBlockHalf.UPPER), 3); } diff --git a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java -index f53808e200bd83ab80954ec5c1e9c14250302be8..b943384eb6a4612993556036f0d3beec6939a559 100644 +index 2df28caefff893f319924ae5fd376c8aeb0a2158..c6b7cfd78bc0c4cb64eada507876c293541890f4 100644 --- a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java -@@ -71,8 +71,13 @@ public class SnifferEggBlock extends Block { +@@ -72,8 +72,13 @@ public class SnifferEggBlock extends Block { @Override public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { if (!this.isReadyToHatch(state)) { diff --git a/patches/unapplied/server/0821-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch b/patches/server/0816-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch similarity index 90% rename from patches/unapplied/server/0821-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch rename to patches/server/0816-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch index 0eb4dc7f6982..cf58a3ec8549 100644 --- a/patches/unapplied/server/0821-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch +++ b/patches/server/0816-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Don't enforce icanhasbukkit default if alias block exists diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index d0deaa80b404043b8cb3dbc390fd5ec3bff2630b..622fe949819ec80737da21305e1a1e0c46480a63 100644 +index f89cbdb157cb56b1b3e0658d80de48695734138d..f85e8ec660bf588f694aa96e6e2ade478a9696b7 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -355,7 +355,11 @@ public final class CraftServer implements Server { +@@ -358,7 +358,11 @@ public final class CraftServer implements Server { } this.commandsConfiguration = YamlConfiguration.loadConfiguration(this.getCommandsConfigFile()); this.commandsConfiguration.options().copyDefaults(true); diff --git a/patches/unapplied/server/0822-fix-MapLike-spam-for-missing-key-selector.patch b/patches/server/0817-fix-MapLike-spam-for-missing-key-selector.patch similarity index 100% rename from patches/unapplied/server/0822-fix-MapLike-spam-for-missing-key-selector.patch rename to patches/server/0817-fix-MapLike-spam-for-missing-key-selector.patch diff --git a/patches/unapplied/server/0823-Fix-sniffer-removeExploredLocation.patch b/patches/server/0818-Fix-sniffer-removeExploredLocation.patch similarity index 100% rename from patches/unapplied/server/0823-Fix-sniffer-removeExploredLocation.patch rename to patches/server/0818-Fix-sniffer-removeExploredLocation.patch diff --git a/patches/unapplied/server/0824-Add-method-to-remove-all-active-potion-effects.patch b/patches/server/0819-Add-method-to-remove-all-active-potion-effects.patch similarity index 86% rename from patches/unapplied/server/0824-Add-method-to-remove-all-active-potion-effects.patch rename to patches/server/0819-Add-method-to-remove-all-active-potion-effects.patch index 6c4676b8f748..e730bcf1d4b4 100644 --- a/patches/unapplied/server/0824-Add-method-to-remove-all-active-potion-effects.patch +++ b/patches/server/0819-Add-method-to-remove-all-active-potion-effects.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add method to remove all active potion effects diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 4ede706367d00965ac75a6ac95877e862d464f74..fb6465bbb2a8bb7597c15d7ac8375f696b897e43 100644 +index 203e06fdff824ba67dce0e026f7ea5b746d7f258..a62d17b72c675120b447e625cb3dc437681bdf20 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -564,6 +564,13 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -573,6 +573,13 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return effects; } diff --git a/patches/unapplied/server/0826-Add-event-for-player-editing-sign.patch b/patches/server/0820-Add-event-for-player-editing-sign.patch similarity index 81% rename from patches/unapplied/server/0826-Add-event-for-player-editing-sign.patch rename to patches/server/0820-Add-event-for-player-editing-sign.patch index df5567a67f1a..9ea10f844872 100644 --- a/patches/unapplied/server/0826-Add-event-for-player-editing-sign.patch +++ b/patches/server/0820-Add-event-for-player-editing-sign.patch @@ -5,32 +5,32 @@ Subject: [PATCH] Add event for player editing sign diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 276858d23be2f9443cc364046a55b9c9a88bf4ea..10b3e41d589d480046e15a957902c2751b731cec 100644 +index 5867a0e3e2ce9be7514771549ad318947e387470..612eb27b471a9ebfdea29a58e5a32931f869bfb6 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -550,7 +550,7 @@ public final class ItemStack implements DataComponentHolder { - try { - if (world.getBlockEntity(SignItem.openSign) instanceof SignBlockEntity tileentitysign) { - if (world.getBlockState(SignItem.openSign).getBlock() instanceof SignBlock blocksign) { -- blocksign.openTextEdit(entityhuman, tileentitysign, true, org.bukkit.event.player.PlayerSignOpenEvent.Cause.PLACE); // Craftbukkit -+ blocksign.openTextEdit(entityhuman, tileentitysign, true, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.PLACE); // Paper - Add PlayerOpenSignEvent +@@ -556,7 +556,7 @@ public final class ItemStack implements DataComponentHolder { + try { + if (world.getBlockEntity(SignItem.openSign) instanceof SignBlockEntity tileentitysign) { + if (world.getBlockState(SignItem.openSign).getBlock() instanceof SignBlock blocksign) { +- blocksign.openTextEdit(entityhuman, tileentitysign, true, org.bukkit.event.player.PlayerSignOpenEvent.Cause.PLACE); // Craftbukkit ++ blocksign.openTextEdit(entityhuman, tileentitysign, true, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.PLACE); // Craftbukkit // Paper - Add PlayerOpenSignEvent + } } - } - } finally { + } finally { diff --git a/src/main/java/net/minecraft/world/level/block/SignBlock.java b/src/main/java/net/minecraft/world/level/block/SignBlock.java -index e00bfb839a2512f018d874976d6f9607877fc2af..73874cd18a5b335e895ea0b2fefbd521209afe08 100644 +index 725a207f80651939c1d793f8aa4ba27e8e4da568..b212fe323f048dab40c0ccbb9327c9fc73b9e03a 100644 --- a/src/main/java/net/minecraft/world/level/block/SignBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SignBlock.java -@@ -139,7 +139,7 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo +@@ -140,7 +140,7 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo } else if (flag1) { - return InteractionResult.SUCCESS; + return InteractionResult.SUCCESS_SERVER; } else if (!this.otherPlayerIsEditingSign(player, tileentitysign) && player.mayBuild() && this.hasEditableText(player, tileentitysign, flag)) { - this.openTextEdit(player, tileentitysign, flag, org.bukkit.event.player.PlayerSignOpenEvent.Cause.INTERACT); // CraftBukkit + this.openTextEdit(player, tileentitysign, flag, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.INTERACT); // Paper - Add PlayerOpenSignEvent - return InteractionResult.SUCCESS; + return InteractionResult.SUCCESS_SERVER; } else { return InteractionResult.PASS; -@@ -184,16 +184,33 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo +@@ -185,16 +185,33 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo return blockpropertywood; } diff --git a/patches/unapplied/server/0825-Fix-incorrect-crafting-result-amount-for-fireworks.patch b/patches/unapplied/server/0825-Fix-incorrect-crafting-result-amount-for-fireworks.patch deleted file mode 100644 index ed5525cfda57..000000000000 --- a/patches/unapplied/server/0825-Fix-incorrect-crafting-result-amount-for-fireworks.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Redned -Date: Mon, 12 Jun 2023 11:54:12 -0500 -Subject: [PATCH] Fix incorrect crafting result amount for fireworks - -Although vanilla does not specifically call this method anywhere, this fixes a bug where the result using the Bukkit API returns the wrong amount. - -diff --git a/src/main/java/net/minecraft/world/item/crafting/FireworkRocketRecipe.java b/src/main/java/net/minecraft/world/item/crafting/FireworkRocketRecipe.java -index e2a3a4fc2fff21b926a74ed11389333165180fe7..93c2268ea1be1727c2939d5730427e24d4e03e2f 100644 ---- a/src/main/java/net/minecraft/world/item/crafting/FireworkRocketRecipe.java -+++ b/src/main/java/net/minecraft/world/item/crafting/FireworkRocketRecipe.java -@@ -77,7 +77,7 @@ public class FireworkRocketRecipe extends CustomRecipe { - - @Override - public ItemStack getResultItem(HolderLookup.Provider registriesLookup) { -- return new ItemStack(Items.FIREWORK_ROCKET); -+ return new ItemStack(Items.FIREWORK_ROCKET, 3); // Paper - Fix incorrect crafting result amount - } - - @Override From 457d03534dcaaf59d83f4598e5159d4f7d136af4 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Thu, 24 Oct 2024 10:42:29 +0200 Subject: [PATCH 035/119] Patches, patches, patches --- ...-API-for-updating-recipes-on-clients.patch | 0 ...k-item-frames-if-players-can-see-it.patch} | 4 +- ...ermission-levels-for-command-blocks.patch} | 14 ++-- ...Add-option-to-disable-block-updates.patch} | 74 +++++++++---------- ...824-Call-missing-BlockDispenseEvent.patch} | 12 +-- ...-chunks-for-supporting-block-checks.patch} | 4 +- ...Optimize-player-lookups-for-beacons.patch} | 2 +- .../0827-More-Sign-Block-API.patch} | 4 +- ...8-fix-item-meta-for-tadpole-buckets.patch} | 4 +- .../0829-Fix-BanList-API.patch} | 6 +- ...d-water-fluid-explosion-resistance-.patch} | 8 +- ...x-possible-NPE-on-painting-creation.patch} | 6 +- ...imer-for-Wandering-Traders-spawned-.patch} | 10 +-- ...nceOrb-should-call-EntitySpawnEvent.patch} | 4 +- ...t-throw-both-Spread-and-Grow-Events.patch} | 0 .../0835-Add-whitelist-events.patch} | 0 .../0836-Implement-PlayerFailMoveEvent.patch} | 20 ++--- ...olia-scheduler-and-owned-region-API.patch} | 42 +++++------ ...se-allay-memory-on-non-item-targets.patch} | 2 +- ...tion-when-spawning-display-entities.patch} | 6 +- ...840-Only-capture-actual-tree-growth.patch} | 46 ++++++------ ...rce-for-mushroom-block-spread-event.patch} | 2 +- ...Data-on-more-entities-when-spawning.patch} | 16 ++-- ...-Use-correct-seed-on-api-world-load.patch} | 6 +- ...ta-neighbour-ticks-outside-of-range.patch} | 6 +- .../0845-Cache-map-ids-on-item-frames.patch} | 10 +-- ...-custom-statistic-criteria-creation.patch} | 2 +- .../0847-Bandaid-fix-for-Effect.patch} | 8 +- .../0848-SculkCatalyst-bloom-API.patch} | 0 ...API-for-an-entity-s-scoreboard-name.patch} | 4 +- ...lace-methods-with-old-StructureType.patch} | 6 +- ...e-namespaced-commands-if-send-names.patch} | 4 +- ...-handle-BlockBreakEvent-isDropItems.patch} | 24 +++--- ...entity-death-event-for-ender-dragon.patch} | 7 +- ...tity-tracking-range-by-Y-coordinate.patch} | 4 +- .../0855-Add-Listing-API-for-Player.patch} | 29 ++++---- ...figurable-Region-Compression-Format.patch} | 0 ...7-Add-BlockFace-to-BlockDamageEvent.patch} | 8 +- .../0858-Fix-NPE-on-Boat-getStatus.patch} | 4 +- .../0859-Expand-Pose-API.patch} | 12 +-- 40 files changed, 211 insertions(+), 209 deletions(-) rename patches/{unapplied/server => later}/0845-API-for-updating-recipes-on-clients.patch (100%) rename patches/{unapplied/server/0827-Only-tick-item-frames-if-players-can-see-it.patch => server/0821-Only-tick-item-frames-if-players-can-see-it.patch} (89%) rename patches/{unapplied/server/0828-Fix-cmd-permission-levels-for-command-blocks.patch => server/0822-Fix-cmd-permission-levels-for-command-blocks.patch} (91%) rename patches/{unapplied/server/0829-Add-option-to-disable-block-updates.patch => server/0823-Add-option-to-disable-block-updates.patch} (78%) rename patches/{unapplied/server/0830-Call-missing-BlockDispenseEvent.patch => server/0824-Call-missing-BlockDispenseEvent.patch} (91%) rename patches/{unapplied/server/0831-Don-t-load-chunks-for-supporting-block-checks.patch => server/0825-Don-t-load-chunks-for-supporting-block-checks.patch} (84%) rename patches/{unapplied/server/0832-Optimize-player-lookups-for-beacons.patch => server/0826-Optimize-player-lookups-for-beacons.patch} (94%) rename patches/{unapplied/server/0833-More-Sign-Block-API.patch => server/0827-More-Sign-Block-API.patch} (95%) rename patches/{unapplied/server/0834-fix-item-meta-for-tadpole-buckets.patch => server/0828-fix-item-meta-for-tadpole-buckets.patch} (95%) rename patches/{unapplied/server/0835-Fix-BanList-API.patch => server/0829-Fix-BanList-API.patch} (98%) rename patches/{unapplied/server/0836-Determine-lava-and-water-fluid-explosion-resistance-.patch => server/0830-Determine-lava-and-water-fluid-explosion-resistance-.patch} (85%) rename patches/{unapplied/server/0837-Fix-possible-NPE-on-painting-creation.patch => server/0831-Fix-possible-NPE-on-painting-creation.patch} (92%) rename patches/{unapplied/server/0838-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch => server/0832-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch} (76%) rename patches/{unapplied/server/0839-ExperienceOrb-should-call-EntitySpawnEvent.patch => server/0833-ExperienceOrb-should-call-EntitySpawnEvent.patch} (89%) rename patches/{unapplied/server/0840-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch => server/0834-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch} (100%) rename patches/{unapplied/server/0841-Add-whitelist-events.patch => server/0835-Add-whitelist-events.patch} (100%) rename patches/{unapplied/server/0842-Implement-PlayerFailMoveEvent.patch => server/0836-Implement-PlayerFailMoveEvent.patch} (88%) rename patches/{unapplied/server/0843-Folia-scheduler-and-owned-region-API.patch => server/0837-Folia-scheduler-and-owned-region-API.patch} (97%) rename patches/{unapplied/server/0844-Only-erase-allay-memory-on-non-item-targets.patch => server/0838-Only-erase-allay-memory-on-non-item-targets.patch} (94%) rename patches/{unapplied/server/0846-Fix-rotation-when-spawning-display-entities.patch => server/0839-Fix-rotation-when-spawning-display-entities.patch} (92%) rename patches/{unapplied/server/0847-Only-capture-actual-tree-growth.patch => server/0840-Only-capture-actual-tree-growth.patch} (80%) rename patches/{unapplied/server/0848-Use-correct-source-for-mushroom-block-spread-event.patch => server/0841-Use-correct-source-for-mushroom-block-spread-event.patch} (94%) rename patches/{unapplied/server/0849-Respect-randomizeData-on-more-entities-when-spawning.patch => server/0842-Respect-randomizeData-on-more-entities-when-spawning.patch} (85%) rename patches/{unapplied/server/0850-Use-correct-seed-on-api-world-load.patch => server/0843-Use-correct-seed-on-api-world-load.patch} (81%) rename patches/{unapplied/server/0851-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch => server/0844-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch} (91%) rename patches/{unapplied/server/0852-Cache-map-ids-on-item-frames.patch => server/0845-Cache-map-ids-on-item-frames.patch} (85%) rename patches/{unapplied/server/0853-Fix-custom-statistic-criteria-creation.patch => server/0846-Fix-custom-statistic-criteria-creation.patch} (92%) rename patches/{unapplied/server/0854-Bandaid-fix-for-Effect.patch => server/0847-Bandaid-fix-for-Effect.patch} (96%) rename patches/{unapplied/server/0855-SculkCatalyst-bloom-API.patch => server/0848-SculkCatalyst-bloom-API.patch} (100%) rename patches/{unapplied/server/0856-API-for-an-entity-s-scoreboard-name.patch => server/0849-API-for-an-entity-s-scoreboard-name.patch} (86%) rename patches/{unapplied/server/0857-Deprecate-and-replace-methods-with-old-StructureType.patch => server/0850-Deprecate-and-replace-methods-with-old-StructureType.patch} (92%) rename patches/{unapplied/server/0858-Don-t-tab-complete-namespaced-commands-if-send-names.patch => server/0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch} (92%) rename patches/{unapplied/server/0859-Properly-handle-BlockBreakEvent-isDropItems.patch => server/0852-Properly-handle-BlockBreakEvent-isDropItems.patch} (91%) rename patches/{unapplied/server/0860-Fire-entity-death-event-for-ender-dragon.patch => server/0853-Fire-entity-death-event-for-ender-dragon.patch} (86%) rename patches/{unapplied/server/0861-Configurable-entity-tracking-range-by-Y-coordinate.patch => server/0854-Configurable-entity-tracking-range-by-Y-coordinate.patch} (92%) rename patches/{unapplied/server/0862-Add-Listing-API-for-Player.patch => server/0855-Add-Listing-API-for-Player.patch} (90%) rename patches/{unapplied/server/0863-Configurable-Region-Compression-Format.patch => server/0856-Configurable-Region-Compression-Format.patch} (100%) rename patches/{unapplied/server/0864-Add-BlockFace-to-BlockDamageEvent.patch => server/0857-Add-BlockFace-to-BlockDamageEvent.patch} (88%) rename patches/{unapplied/server/0865-Fix-NPE-on-Boat-getStatus.patch => server/0858-Fix-NPE-on-Boat-getStatus.patch} (87%) rename patches/{unapplied/server/0866-Expand-Pose-API.patch => server/0859-Expand-Pose-API.patch} (81%) diff --git a/patches/unapplied/server/0845-API-for-updating-recipes-on-clients.patch b/patches/later/0845-API-for-updating-recipes-on-clients.patch similarity index 100% rename from patches/unapplied/server/0845-API-for-updating-recipes-on-clients.patch rename to patches/later/0845-API-for-updating-recipes-on-clients.patch diff --git a/patches/unapplied/server/0827-Only-tick-item-frames-if-players-can-see-it.patch b/patches/server/0821-Only-tick-item-frames-if-players-can-see-it.patch similarity index 89% rename from patches/unapplied/server/0827-Only-tick-item-frames-if-players-can-see-it.patch rename to patches/server/0821-Only-tick-item-frames-if-players-can-see-it.patch index bf73ba4a5c3d..c7c6cd499f71 100644 --- a/patches/unapplied/server/0827-Only-tick-item-frames-if-players-can-see-it.patch +++ b/patches/server/0821-Only-tick-item-frames-if-players-can-see-it.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Only tick item frames if players can see it In the event that an item frame cannot be seen by any players, ticking the item frame every tick is unnecessary. This can be a very hot section of the entity tracker when lots of item frames are present on a server, so this reduces the logic which speeds it up. diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index f3f93710846ce0f6d53845e0b49331646a4e8332..f010be9605d7458add7e5693ff473fabf679c938 100644 +index bc0f1aa61e68d2a8638d89c10bc5c71922d057f9..3cdcc4f44608d24550f2a8c6f3f5ce675d7777c5 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -112,7 +112,7 @@ public class ServerEntity { +@@ -116,7 +116,7 @@ public class ServerEntity { Entity entity = this.entity; diff --git a/patches/unapplied/server/0828-Fix-cmd-permission-levels-for-command-blocks.patch b/patches/server/0822-Fix-cmd-permission-levels-for-command-blocks.patch similarity index 91% rename from patches/unapplied/server/0828-Fix-cmd-permission-levels-for-command-blocks.patch rename to patches/server/0822-Fix-cmd-permission-levels-for-command-blocks.patch index 5167eee08c9c..aa96a27db68b 100644 --- a/patches/unapplied/server/0828-Fix-cmd-permission-levels-for-command-blocks.patch +++ b/patches/server/0822-Fix-cmd-permission-levels-for-command-blocks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix cmd permission levels for command blocks diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java -index f3c83bb20a73b489f1fb6bacb69388902b1b6fe7..3c0d2332207ba638faaaa4280bce18c334a01271 100644 +index f31c5d665678c3163ed4469f8e9d395b890c1bbe..fc0c60b22844ed010aede2fa125b9fa440d3de80 100644 --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java +++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java -@@ -204,10 +204,29 @@ public class CommandSourceStack implements ExecutionCommandSource= level; } @@ -41,10 +41,10 @@ index f3c83bb20a73b489f1fb6bacb69388902b1b6fe7..3c0d2332207ba638faaaa4280bce18c3 // CraftBukkit end diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index 96ca1af97c1f63776b88bc428874742a5114564f..7b86e064564d3a285e3971fd08ea6168bac0720e 100644 +index fd12046fab797fd845ad8521f94147480dfba5da..fe9f638db3525893beed565ef9b7ac2fc76318bd 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -295,16 +295,7 @@ public class Commands { +@@ -300,16 +300,7 @@ public class Commands { String[] args = command.split(" "); if (args.length == 0) return; // Paper - empty commands shall not be dispatched @@ -63,10 +63,10 @@ index 96ca1af97c1f63776b88bc428874742a5114564f..7b86e064564d3a285e3971fd08ea6168 // Handle vanilla commands; if (sender.getLevel().getCraftServer().getCommandBlockOverride(args[0])) { diff --git a/src/main/java/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java b/src/main/java/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java -index c671b26d7dc70bac1f4bf9a68a264b25865cf7da..83ef2c3e7b06152b9e68f90002c35e77f148347d 100644 +index d7321275cf963ba4fd838226c7f705ea0f2e1ac6..56bae8ea1e7b115e85a701209f3badbd29912b28 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java -@@ -136,7 +136,7 @@ public class MinecartCommandBlock extends AbstractMinecart { +@@ -133,7 +133,7 @@ public class MinecartCommandBlock extends AbstractMinecart { @Override public CommandSourceStack createCommandSourceStack() { @@ -76,7 +76,7 @@ index c671b26d7dc70bac1f4bf9a68a264b25865cf7da..83ef2c3e7b06152b9e68f90002c35e77 @Override diff --git a/src/main/java/net/minecraft/world/level/block/entity/CommandBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/CommandBlockEntity.java -index 4c7d142dc653f3aca82e0563b6ba2e020721eb9b..6c484f3f8f37a19992ebbfe30aba399cac21acfe 100644 +index faa0a3248217fb27dae5b918099f8a63eee6f586..a02c5feb8f2ffe6bb6070650a45762476e1ff9ac 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/CommandBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/CommandBlockEntity.java @@ -58,7 +58,7 @@ public class CommandBlockEntity extends BlockEntity { diff --git a/patches/unapplied/server/0829-Add-option-to-disable-block-updates.patch b/patches/server/0823-Add-option-to-disable-block-updates.patch similarity index 78% rename from patches/unapplied/server/0829-Add-option-to-disable-block-updates.patch rename to patches/server/0823-Add-option-to-disable-block-updates.patch index 8fe599472edd..0ea835ecc917 100644 --- a/patches/unapplied/server/0829-Add-option-to-disable-block-updates.patch +++ b/patches/server/0823-Add-option-to-disable-block-updates.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add option to disable block updates diff --git a/src/main/java/net/minecraft/world/level/block/ChorusPlantBlock.java b/src/main/java/net/minecraft/world/level/block/ChorusPlantBlock.java -index 06f0e5afdab6274154213d82ab3278e08c4ba1b7..8569ad43985fa60d5196ae4bc21646406d8b2adc 100644 +index bf2790fae091ab9d7f4ec4b2ab0f103190c31984..5d3ca961b325a39efcd6b398a27f9a4d300b35e5 100644 --- a/src/main/java/net/minecraft/world/level/block/ChorusPlantBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ChorusPlantBlock.java @@ -38,6 +38,7 @@ public class ChorusPlantBlock extends PipeBlock { @@ -16,15 +16,15 @@ index 06f0e5afdab6274154213d82ab3278e08c4ba1b7..8569ad43985fa60d5196ae4bc2164640 return getStateWithConnections(ctx.getLevel(), ctx.getClickedPos(), this.defaultBlockState()); } -@@ -59,6 +60,7 @@ public class ChorusPlantBlock extends PipeBlock { - - @Override - protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { +@@ -68,6 +69,7 @@ public class ChorusPlantBlock extends PipeBlock { + BlockState neighborState, + RandomSource random + ) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return state; // Paper - add option to disable block updates if (!state.canSurvive(world, pos)) { - world.scheduleTick(pos, this, 1); - return super.updateShape(state, direction, neighborState, world, pos, neighborPos); -@@ -70,6 +72,7 @@ public class ChorusPlantBlock extends PipeBlock { + tickView.scheduleTick(pos, this, 1); + return super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random); +@@ -79,6 +81,7 @@ public class ChorusPlantBlock extends PipeBlock { @Override protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { @@ -32,7 +32,7 @@ index 06f0e5afdab6274154213d82ab3278e08c4ba1b7..8569ad43985fa60d5196ae4bc2164640 if (!state.canSurvive(world, pos)) { world.destroyBlock(pos, true); } -@@ -77,6 +80,7 @@ public class ChorusPlantBlock extends PipeBlock { +@@ -86,6 +89,7 @@ public class ChorusPlantBlock extends PipeBlock { @Override protected boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { @@ -41,10 +41,10 @@ index 06f0e5afdab6274154213d82ab3278e08c4ba1b7..8569ad43985fa60d5196ae4bc2164640 boolean bl = !world.getBlockState(pos.above()).isAir() && !blockState.isAir(); diff --git a/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java b/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java -index 3f45058eee0c78f50c119da5da4c7d2af0251a27..d16aad72c90bbde158b845759eef227546d12e24 100644 +index 0e0441646bd21a14a8bea576e5400ce937ebea01..437ad7051bad2d7dccc1a9ae764bdc5dcbe88612 100644 --- a/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java +++ b/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java -@@ -43,6 +43,7 @@ public class HugeMushroomBlock extends Block { +@@ -45,6 +45,7 @@ public class HugeMushroomBlock extends Block { @Override public BlockState getStateForPlacement(BlockPlaceContext ctx) { @@ -52,15 +52,15 @@ index 3f45058eee0c78f50c119da5da4c7d2af0251a27..d16aad72c90bbde158b845759eef2275 BlockGetter blockGetter = ctx.getLevel(); BlockPos blockPos = ctx.getClickedPos(); return this.defaultBlockState() -@@ -56,6 +57,7 @@ public class HugeMushroomBlock extends Block { - - @Override - protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { +@@ -67,6 +68,7 @@ public class HugeMushroomBlock extends Block { + BlockState neighborState, + RandomSource random + ) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return state; // Paper - add option to disable block updates return neighborState.is(this) ? state.setValue(PROPERTY_BY_DIRECTION.get(direction), Boolean.valueOf(false)) - : super.updateShape(state, direction, neighborState, world, pos, neighborPos); -@@ -63,6 +65,7 @@ public class HugeMushroomBlock extends Block { + : super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random); +@@ -74,6 +76,7 @@ public class HugeMushroomBlock extends Block { @Override protected BlockState rotate(BlockState state, Rotation rotation) { @@ -68,7 +68,7 @@ index 3f45058eee0c78f50c119da5da4c7d2af0251a27..d16aad72c90bbde158b845759eef2275 return state.setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.NORTH)), state.getValue(NORTH)) .setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.SOUTH)), state.getValue(SOUTH)) .setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.EAST)), state.getValue(EAST)) -@@ -73,6 +76,7 @@ public class HugeMushroomBlock extends Block { +@@ -84,6 +87,7 @@ public class HugeMushroomBlock extends Block { @Override protected BlockState mirror(BlockState state, Mirror mirror) { @@ -77,10 +77,10 @@ index 3f45058eee0c78f50c119da5da4c7d2af0251a27..d16aad72c90bbde158b845759eef2275 .setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.SOUTH)), state.getValue(SOUTH)) .setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.EAST)), state.getValue(EAST)) diff --git a/src/main/java/net/minecraft/world/level/block/NoteBlock.java b/src/main/java/net/minecraft/world/level/block/NoteBlock.java -index f77d51d10e01fc4eaf5516c05c8be0ef7a425893..1d82cfe7af0dc42f88901fb0c44896771fdf8a93 100644 +index 71fd7a467a4cb89cad8d2541366fd4add9115e04..6582db84c5307257f16c321453491cf24e40c9c7 100644 --- a/src/main/java/net/minecraft/world/level/block/NoteBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NoteBlock.java -@@ -66,11 +66,13 @@ public class NoteBlock extends Block { +@@ -68,11 +68,13 @@ public class NoteBlock extends Block { @Override public BlockState getStateForPlacement(BlockPlaceContext ctx) { @@ -89,33 +89,33 @@ index f77d51d10e01fc4eaf5516c05c8be0ef7a425893..1d82cfe7af0dc42f88901fb0c4489677 } @Override - protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { + protected BlockState updateShape(BlockState state, LevelReader world, ScheduledTickAccess tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, RandomSource random) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return state; // Paper - prevent noteblock instrument from updating boolean flag = direction.getAxis() == Direction.Axis.Y; - return flag ? this.setInstrument(world, pos, state) : super.updateShape(state, direction, neighborState, world, pos, neighborPos); -@@ -78,6 +80,7 @@ public class NoteBlock extends Block { + return flag ? this.setInstrument(world, pos, state) : super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random); +@@ -80,6 +82,7 @@ public class NoteBlock extends Block { @Override - protected void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) { + protected void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, @Nullable Orientation wireOrientation, boolean notify) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return; // Paper - prevent noteblock powered-state from updating boolean flag1 = world.hasNeighborSignal(pos); if (flag1 != (Boolean) state.getValue(NoteBlock.POWERED)) { @@ -116,7 +119,7 @@ public class NoteBlock extends Block { - if (world.isClientSide) { - return InteractionResult.SUCCESS; - } else { + @Override + protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { + if (!world.isClientSide) { - state = (BlockState) state.cycle(NoteBlock.NOTE); + if (!io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) state = (BlockState) state.cycle(NoteBlock.NOTE); // Paper - prevent noteblock note from updating world.setBlock(pos, state, 3); this.playNote(player, state, world, pos); player.awardStat(Stats.TUNE_NOTEBLOCK); diff --git a/src/main/java/net/minecraft/world/level/block/TripWireBlock.java b/src/main/java/net/minecraft/world/level/block/TripWireBlock.java -index e032d8907045c653c3dd449f65e93e40fd0bb6be..6fe5be785423a35b6ff4e6206ca281b66845b979 100644 +index f079e5a9aa098225acf09ed9b4aa7ddbc2381270..74cce7874809dcbce2718ec3840bb6bb3127e871 100644 --- a/src/main/java/net/minecraft/world/level/block/TripWireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TripWireBlock.java -@@ -67,6 +67,7 @@ public class TripWireBlock extends Block { +@@ -68,6 +68,7 @@ public class TripWireBlock extends Block { @Override public BlockState getStateForPlacement(BlockPlaceContext ctx) { @@ -123,12 +123,12 @@ index e032d8907045c653c3dd449f65e93e40fd0bb6be..6fe5be785423a35b6ff4e6206ca281b6 Level world = ctx.getLevel(); BlockPos blockposition = ctx.getClickedPos(); -@@ -75,11 +76,13 @@ public class TripWireBlock extends Block { +@@ -76,11 +77,13 @@ public class TripWireBlock extends Block { @Override - protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { + protected BlockState updateShape(BlockState state, LevelReader world, ScheduledTickAccess tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, RandomSource random) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return state; // Paper - prevent tripwire from updating - return direction.getAxis().isHorizontal() ? (BlockState) state.setValue((Property) TripWireBlock.PROPERTY_BY_DIRECTION.get(direction), this.shouldConnectTo(neighborState, direction)) : super.updateShape(state, direction, neighborState, world, pos, neighborPos); + return direction.getAxis().isHorizontal() ? (BlockState) state.setValue((Property) TripWireBlock.PROPERTY_BY_DIRECTION.get(direction), this.shouldConnectTo(neighborState, direction)) : super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random); } @Override @@ -137,7 +137,7 @@ index e032d8907045c653c3dd449f65e93e40fd0bb6be..6fe5be785423a35b6ff4e6206ca281b6 if (!oldState.is(state.getBlock())) { this.updateSource(world, pos, state); } -@@ -87,6 +90,7 @@ public class TripWireBlock extends Block { +@@ -88,6 +91,7 @@ public class TripWireBlock extends Block { @Override protected void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moved) { @@ -145,7 +145,7 @@ index e032d8907045c653c3dd449f65e93e40fd0bb6be..6fe5be785423a35b6ff4e6206ca281b6 if (!moved && !state.is(newState.getBlock())) { this.updateSource(world, pos, (BlockState) state.setValue(TripWireBlock.POWERED, true)); } -@@ -94,6 +98,7 @@ public class TripWireBlock extends Block { +@@ -95,6 +99,7 @@ public class TripWireBlock extends Block { @Override public BlockState playerWillDestroy(Level world, BlockPos pos, BlockState state, Player player) { @@ -153,7 +153,7 @@ index e032d8907045c653c3dd449f65e93e40fd0bb6be..6fe5be785423a35b6ff4e6206ca281b6 if (!world.isClientSide && !player.getMainHandItem().isEmpty() && player.getMainHandItem().is(Items.SHEARS)) { world.setBlock(pos, (BlockState) state.setValue(TripWireBlock.DISARMED, true), 4); world.gameEvent((Entity) player, (Holder) GameEvent.SHEAR, pos); -@@ -103,6 +108,7 @@ public class TripWireBlock extends Block { +@@ -104,6 +109,7 @@ public class TripWireBlock extends Block { } private void updateSource(Level world, BlockPos pos, BlockState state) { @@ -161,7 +161,7 @@ index e032d8907045c653c3dd449f65e93e40fd0bb6be..6fe5be785423a35b6ff4e6206ca281b6 Direction[] aenumdirection = new Direction[]{Direction.SOUTH, Direction.WEST}; int i = aenumdirection.length; int j = 0; -@@ -135,6 +141,7 @@ public class TripWireBlock extends Block { +@@ -141,6 +147,7 @@ public class TripWireBlock extends Block { @Override protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { @@ -169,7 +169,7 @@ index e032d8907045c653c3dd449f65e93e40fd0bb6be..6fe5be785423a35b6ff4e6206ca281b6 if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent if (!world.isClientSide) { if (!(Boolean) state.getValue(TripWireBlock.POWERED)) { -@@ -145,6 +152,7 @@ public class TripWireBlock extends Block { +@@ -151,6 +158,7 @@ public class TripWireBlock extends Block { @Override protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { diff --git a/patches/unapplied/server/0830-Call-missing-BlockDispenseEvent.patch b/patches/server/0824-Call-missing-BlockDispenseEvent.patch similarity index 91% rename from patches/unapplied/server/0830-Call-missing-BlockDispenseEvent.patch rename to patches/server/0824-Call-missing-BlockDispenseEvent.patch index ca534e461773..3e96187d8ea5 100644 --- a/patches/unapplied/server/0830-Call-missing-BlockDispenseEvent.patch +++ b/patches/server/0824-Call-missing-BlockDispenseEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Call missing BlockDispenseEvent diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -index 96db0b1041a4c0f054d4f3f2bdced960b119664e..78951f50188528718cdb3dbbaabe3f9f2760ffe3 100644 +index 5793569ae8a088f21b0d8d6771a5099b1e88be09..f8f570a97789ab16e57774f233506a289277d5d9 100644 --- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -867,6 +867,13 @@ public interface DispenseItemBehavior { +@@ -768,6 +768,13 @@ public interface DispenseItemBehavior { this.setSuccess(true); if (iblockdata.is(Blocks.RESPAWN_ANCHOR)) { if ((Integer) iblockdata.getValue(RespawnAnchorBlock.CHARGE) != 4) { @@ -22,7 +22,7 @@ index 96db0b1041a4c0f054d4f3f2bdced960b119664e..78951f50188528718cdb3dbbaabe3f9f RespawnAnchorBlock.charge((Entity) null, worldserver, blockposition, iblockdata); stack.shrink(1); } else { -@@ -944,6 +951,13 @@ public interface DispenseItemBehavior { +@@ -845,6 +852,13 @@ public interface DispenseItemBehavior { Optional optional = HoneycombItem.getWaxed(iblockdata); if (optional.isPresent()) { @@ -36,7 +36,7 @@ index 96db0b1041a4c0f054d4f3f2bdced960b119664e..78951f50188528718cdb3dbbaabe3f9f worldserver.setBlockAndUpdate(blockposition, (BlockState) optional.get()); worldserver.levelEvent(3003, blockposition, 0); stack.shrink(1); -@@ -971,6 +985,12 @@ public interface DispenseItemBehavior { +@@ -872,6 +886,12 @@ public interface DispenseItemBehavior { if (!worldserver.getBlockState(blockposition1).is(BlockTags.CONVERTABLE_TO_MUD)) { return this.defaultDispenseItemBehavior.dispense(pointer, stack); } else { @@ -50,10 +50,10 @@ index 96db0b1041a4c0f054d4f3f2bdced960b119664e..78951f50188528718cdb3dbbaabe3f9f for (int k = 0; k < 5; ++k) { worldserver.sendParticles(ParticleTypes.SPLASH, (double) blockposition.getX() + worldserver.random.nextDouble(), (double) (blockposition.getY() + 1), (double) blockposition.getZ() + worldserver.random.nextDouble(), 1, 0.0D, 0.0D, 0.0D, 1.0D); diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 9586837f25464396c0695e87fa278c91ca90183a..9b3023fdda9d08c0f5489542f644e2ea311af191 100644 +index ac25a5c933b8748ca44ca02100058992b1aad358..22244f38bfee746f14c969de05bc028c934c6d6b 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -2198,6 +2198,32 @@ public class CraftEventFactory { +@@ -2196,6 +2196,32 @@ populateFields(victim, event); // Paper - make cancellable } // Paper end diff --git a/patches/unapplied/server/0831-Don-t-load-chunks-for-supporting-block-checks.patch b/patches/server/0825-Don-t-load-chunks-for-supporting-block-checks.patch similarity index 84% rename from patches/unapplied/server/0831-Don-t-load-chunks-for-supporting-block-checks.patch rename to patches/server/0825-Don-t-load-chunks-for-supporting-block-checks.patch index db2c15729d3c..1feebdd77f80 100644 --- a/patches/unapplied/server/0831-Don-t-load-chunks-for-supporting-block-checks.patch +++ b/patches/server/0825-Don-t-load-chunks-for-supporting-block-checks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Don't load chunks for supporting block checks diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index cd362a91ad31dbae94fdb5a8c71839576f397ea1..8e252b930247293e0fbcf350111403ee716cfffa 100644 +index 8cdef637f6343119fc77f87e7478ee23e9b8efab..3ef1352030bf1d6f4d2053158caea852552e91a7 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -1185,7 +1185,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1228,7 +1228,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } protected BlockPos getOnPos(float offset) { diff --git a/patches/unapplied/server/0832-Optimize-player-lookups-for-beacons.patch b/patches/server/0826-Optimize-player-lookups-for-beacons.patch similarity index 94% rename from patches/unapplied/server/0832-Optimize-player-lookups-for-beacons.patch rename to patches/server/0826-Optimize-player-lookups-for-beacons.patch index 1c203c23a643..7e1285d8913a 100644 --- a/patches/unapplied/server/0832-Optimize-player-lookups-for-beacons.patch +++ b/patches/server/0826-Optimize-player-lookups-for-beacons.patch @@ -7,7 +7,7 @@ For larger ranges, it's better to iterate over the player list than the entity slices. diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -index b6633ca1ee73ef0f8a220992a2e0424e67dd9758..814e70f558d7a6186233da0ff86c94c95d390e09 100644 +index 2a7d896dd9a02acf6e3596e2e2e7ed50f4b88377..0e0d178f2793ab014358f534c8dc53218b89f083 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java @@ -333,7 +333,22 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name diff --git a/patches/unapplied/server/0833-More-Sign-Block-API.patch b/patches/server/0827-More-Sign-Block-API.patch similarity index 95% rename from patches/unapplied/server/0833-More-Sign-Block-API.patch rename to patches/server/0827-More-Sign-Block-API.patch index 3be6f4e3539f..70558b001027 100644 --- a/patches/unapplied/server/0833-More-Sign-Block-API.patch +++ b/patches/server/0827-More-Sign-Block-API.patch @@ -6,10 +6,10 @@ Subject: [PATCH] More Sign Block API Co-authored-by: SoSeDiK diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java -index bfe8029852385875af4ebe73c63e688f61042021..3070cd2b588f5a69fd8c0d3551e16251680d8c27 100644 +index a34c2fc6ac1418a89d789b8945ca3dad57f64151..8ac19e1e052e73ff3fd09089bb8e3fd687390ee4 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java -@@ -68,12 +68,17 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C +@@ -68,12 +68,17 @@ public class SignBlockEntity extends BlockEntity { } public boolean isFacingFrontText(net.minecraft.world.entity.player.Player player) { diff --git a/patches/unapplied/server/0834-fix-item-meta-for-tadpole-buckets.patch b/patches/server/0828-fix-item-meta-for-tadpole-buckets.patch similarity index 95% rename from patches/unapplied/server/0834-fix-item-meta-for-tadpole-buckets.patch rename to patches/server/0828-fix-item-meta-for-tadpole-buckets.patch index 6c9509e2cfaa..04c4b6a87380 100644 --- a/patches/unapplied/server/0834-fix-item-meta-for-tadpole-buckets.patch +++ b/patches/server/0828-fix-item-meta-for-tadpole-buckets.patch @@ -5,10 +5,10 @@ Subject: [PATCH] fix item meta for tadpole buckets diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java -index c9fbc01be0b0e7fd1cafb091d06496f4ba1e7c2c..a4c4ba0d02f9a072236ce86c1e98e2c60b059cb8 100644 +index 4f5568707d725195ee19b65274454fec8bf99d64..d29f4dd9808e2001c79535d663ca77d6840f6092 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java -@@ -263,7 +263,7 @@ public final class CraftItemMetas { +@@ -265,7 +265,7 @@ public final class CraftItemMetas { if (itemType == ItemType.SUSPICIOUS_STEW) { return CraftItemMetas.asType(CraftItemMetas.SUSPICIOUS_STEW_META_DATA); } diff --git a/patches/unapplied/server/0835-Fix-BanList-API.patch b/patches/server/0829-Fix-BanList-API.patch similarity index 98% rename from patches/unapplied/server/0835-Fix-BanList-API.patch rename to patches/server/0829-Fix-BanList-API.patch index 352a89b454ba..aa0028893ca3 100644 --- a/patches/unapplied/server/0835-Fix-BanList-API.patch +++ b/patches/server/0829-Fix-BanList-API.patch @@ -208,10 +208,10 @@ index 172202accf4448a933fcf1ff820316c7910dd7f7..50ee7656580d386db473c054f5c5ec57 return null; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 3945a6ab723deee3ec3ebb5fbc726ce16bbca411..62914bde6f6b045e6b3682581899d756d1b272f1 100644 +index cdc53abb5572fa57b4ec98a694c5583ad0982a05..79e35265978357eeb27c43205433d6b24335f401 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1747,23 +1747,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1760,23 +1760,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override @@ -240,7 +240,7 @@ index 3945a6ab723deee3ec3ebb5fbc726ce16bbca411..62914bde6f6b045e6b3682581899d756 if (kickPlayer) { this.kickPlayer(reason); } -@@ -1771,12 +1771,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1784,12 +1784,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override diff --git a/patches/unapplied/server/0836-Determine-lava-and-water-fluid-explosion-resistance-.patch b/patches/server/0830-Determine-lava-and-water-fluid-explosion-resistance-.patch similarity index 85% rename from patches/unapplied/server/0836-Determine-lava-and-water-fluid-explosion-resistance-.patch rename to patches/server/0830-Determine-lava-and-water-fluid-explosion-resistance-.patch index 5f51eb317c2c..4f2b8e09cd7b 100644 --- a/patches/unapplied/server/0836-Determine-lava-and-water-fluid-explosion-resistance-.patch +++ b/patches/server/0830-Determine-lava-and-water-fluid-explosion-resistance-.patch @@ -9,10 +9,10 @@ When selecting which explosion resistance to use for lava and water, vanilla sel Problems emerge when we want to reduce the explosion resistance of water or lava, since the fluid explosion resistance is hardcoded to return 100.0F and can't be changed by a plugin. This simply makes the fluid explosion resistance the same as the block explosion resistance, which allows plugin to change the value. Since both are the same in vanilla, this has no side effects on servers that do not need to do this. diff --git a/src/main/java/net/minecraft/world/level/material/LavaFluid.java b/src/main/java/net/minecraft/world/level/material/LavaFluid.java -index 72f8b72c6436ca3b8eaeb39c7d3efe2c1462ae1d..3bb4a9a1a6249e8ba2de237f801210e7f4fd5825 100644 +index a27ceed2cac6c16eb4e5f2959db9e482e67e9de6..884db3e64cb22ed765beec8f11ea309fcf810207 100644 --- a/src/main/java/net/minecraft/world/level/material/LavaFluid.java +++ b/src/main/java/net/minecraft/world/level/material/LavaFluid.java -@@ -232,7 +232,7 @@ public abstract class LavaFluid extends FlowingFluid { +@@ -233,7 +233,7 @@ public abstract class LavaFluid extends FlowingFluid { @Override protected float getExplosionResistance() { @@ -22,10 +22,10 @@ index 72f8b72c6436ca3b8eaeb39c7d3efe2c1462ae1d..3bb4a9a1a6249e8ba2de237f801210e7 @Override diff --git a/src/main/java/net/minecraft/world/level/material/WaterFluid.java b/src/main/java/net/minecraft/world/level/material/WaterFluid.java -index 21b4afd053e01073eb514264d4960f0f3b1ee3d8..109f71401c65f476ccf6813137386fc9fef10254 100644 +index 0a7c05c08bf8c6c331b91e399dc4103a91dc20fe..552925ba47c7475e2e1ec2ded0966f28ed3e50a5 100644 --- a/src/main/java/net/minecraft/world/level/material/WaterFluid.java +++ b/src/main/java/net/minecraft/world/level/material/WaterFluid.java -@@ -125,7 +125,7 @@ public abstract class WaterFluid extends FlowingFluid { +@@ -126,7 +126,7 @@ public abstract class WaterFluid extends FlowingFluid { @Override protected float getExplosionResistance() { diff --git a/patches/unapplied/server/0837-Fix-possible-NPE-on-painting-creation.patch b/patches/server/0831-Fix-possible-NPE-on-painting-creation.patch similarity index 92% rename from patches/unapplied/server/0837-Fix-possible-NPE-on-painting-creation.patch rename to patches/server/0831-Fix-possible-NPE-on-painting-creation.patch index dc3838be9485..d5fa31bd07e2 100644 --- a/patches/unapplied/server/0837-Fix-possible-NPE-on-painting-creation.patch +++ b/patches/server/0831-Fix-possible-NPE-on-painting-creation.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix possible NPE on painting creation diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java -index 46a4f31e2b6eee6f8dc5f8fccd7de4c48a698b61..577ed3656480271a491bcd3d346c63854fd840e4 100644 +index 39ea25d2145acaa7c7b458800adc674a3e73e7c1..8715d8e790b6735610e2f880f8c1f88a89967f21 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java -@@ -326,8 +326,13 @@ public final class CraftEntityTypes { +@@ -361,8 +361,13 @@ public final class CraftEntityTypes { // Hanging register(new EntityTypeData<>(EntityType.PAINTING, Painting.class, CraftPainting::new, createHanging(Painting.class, (spawnData, hangingData) -> { if (spawnData.normalWorld && hangingData.randomize()) { @@ -24,7 +24,7 @@ index 46a4f31e2b6eee6f8dc5f8fccd7de4c48a698b61..577ed3656480271a491bcd3d346c6385 net.minecraft.world.entity.decoration.Painting entity = new net.minecraft.world.entity.decoration.Painting(net.minecraft.world.entity.EntityType.PAINTING, spawnData.minecraftWorld()); entity.absMoveTo(spawnData.x(), spawnData.y(), spawnData.z(), spawnData.yaw(), spawnData.pitch()); entity.setDirection(hangingData.direction()); -@@ -466,6 +471,7 @@ public final class CraftEntityTypes { +@@ -523,6 +528,7 @@ public final class CraftEntityTypes { AABB bb = (ItemFrame.class.isAssignableFrom(clazz)) ? net.minecraft.world.entity.decoration.ItemFrame.calculateBoundingBoxStatic(pos, CraftBlock.blockFaceToNotch(dir).getOpposite()) : net.minecraft.world.entity.decoration.Painting.calculateBoundingBoxStatic(pos, CraftBlock.blockFaceToNotch(dir).getOpposite(), width, height); diff --git a/patches/unapplied/server/0838-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch b/patches/server/0832-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch similarity index 76% rename from patches/unapplied/server/0838-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch rename to patches/server/0832-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch index 6785f755abf5..28dc555f0838 100644 --- a/patches/unapplied/server/0838-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch +++ b/patches/server/0832-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Only set despawnTimer for Wandering Traders spawned by diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java -index 856a93324f5ac411713851ccfb38dba52fb0af5e..0af34e0f9c9696fbcb11b12fb27472ef17ad532a 100644 +index a65fba5621c067c453858efb7fee64cbee1e7916..1e77cce428d9e53142aaa2cf780b7f862d536eca 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java -@@ -68,7 +68,7 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill +@@ -69,7 +69,7 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill public WanderingTrader(EntityType type, Level world) { super(type, world); @@ -19,15 +19,15 @@ index 856a93324f5ac411713851ccfb38dba52fb0af5e..0af34e0f9c9696fbcb11b12fb27472ef @Override diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java -index d5d27b0d352ca3fd57a26605cb35c499e88b57fc..c72b6ea5530e54fc373c701028e1c147cea34b59 100644 +index 08a3c7140867f339dd99a95094ed0fd8ff344fca..9d206bed5b982603f39bc1f70ae23ea38e4d9bc9 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java @@ -120,7 +120,7 @@ public class WanderingTraderSpawner implements CustomSpawner { return false; } -- WanderingTrader entityvillagertrader = (WanderingTrader) EntityType.WANDERING_TRADER.spawn(world, blockposition2, MobSpawnType.EVENT, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit -+ WanderingTrader entityvillagertrader = (WanderingTrader) EntityType.WANDERING_TRADER.spawn(world, trader -> trader.setDespawnDelay(48000), blockposition2, MobSpawnType.EVENT, false, false, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit // Paper - set despawnTimer before spawn events called +- WanderingTrader entityvillagertrader = (WanderingTrader) EntityType.WANDERING_TRADER.spawn(world, blockposition2, EntitySpawnReason.EVENT, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit ++ WanderingTrader entityvillagertrader = (WanderingTrader) EntityType.WANDERING_TRADER.spawn(world, trader -> trader.setDespawnDelay(48000), blockposition2, EntitySpawnReason.EVENT, false, false, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBu // Paper - set despawnTimer before spawn events calledkkit if (entityvillagertrader != null) { for (int i = 0; i < 2; ++i) { diff --git a/patches/unapplied/server/0839-ExperienceOrb-should-call-EntitySpawnEvent.patch b/patches/server/0833-ExperienceOrb-should-call-EntitySpawnEvent.patch similarity index 89% rename from patches/unapplied/server/0839-ExperienceOrb-should-call-EntitySpawnEvent.patch rename to patches/server/0833-ExperienceOrb-should-call-EntitySpawnEvent.patch index b70d980d3161..8c098452ae3f 100644 --- a/patches/unapplied/server/0839-ExperienceOrb-should-call-EntitySpawnEvent.patch +++ b/patches/server/0833-ExperienceOrb-should-call-EntitySpawnEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] ExperienceOrb should call EntitySpawnEvent diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 9b3023fdda9d08c0f5489542f644e2ea311af191..907ea60b647d529f133986632d00416269bc311e 100644 +index 22244f38bfee746f14c969de05bc028c934c6d6b..03afabc3ab4b264f84698627b79e58f502a8cea9 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -746,7 +746,8 @@ public class CraftEventFactory { +@@ -744,7 +744,8 @@ public class CraftEventFactory { // Spigot start - SPIGOT-7523: Merge after spawn event and only merge if the event was not cancelled (gets checked above) if (entity instanceof net.minecraft.world.entity.ExperienceOrb xp) { double radius = world.spigotConfig.expMerge; diff --git a/patches/unapplied/server/0840-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch b/patches/server/0834-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch similarity index 100% rename from patches/unapplied/server/0840-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch rename to patches/server/0834-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch diff --git a/patches/unapplied/server/0841-Add-whitelist-events.patch b/patches/server/0835-Add-whitelist-events.patch similarity index 100% rename from patches/unapplied/server/0841-Add-whitelist-events.patch rename to patches/server/0835-Add-whitelist-events.patch diff --git a/patches/unapplied/server/0842-Implement-PlayerFailMoveEvent.patch b/patches/server/0836-Implement-PlayerFailMoveEvent.patch similarity index 88% rename from patches/unapplied/server/0842-Implement-PlayerFailMoveEvent.patch rename to patches/server/0836-Implement-PlayerFailMoveEvent.patch index 6a55a3af38f5..99859fc1437f 100644 --- a/patches/unapplied/server/0842-Implement-PlayerFailMoveEvent.patch +++ b/patches/server/0836-Implement-PlayerFailMoveEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Implement PlayerFailMoveEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index db9c04d74475e00983cc9df74d615e4b68f83688..adcfa6a783222482ce7ec5c7805fe44dd24bf7d0 100644 +index 5d261106b0cd12e9ed737833b1f6d2572d15ab4e..618c620b4bca535c454691f9a87c9b36a36021e2 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1260,8 +1260,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1263,8 +1263,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl double d0 = ServerGamePacketListenerImpl.clampHorizontal(packet.getX(this.player.getX())); final double toX = d0; // Paper - OBFHELPER double d1 = ServerGamePacketListenerImpl.clampVertical(packet.getY(this.player.getY())); final double toY = d1; // Paper - OBFHELPER double d2 = ServerGamePacketListenerImpl.clampHorizontal(packet.getZ(this.player.getZ())); final double toZ = d2; // Paper - OBFHELPER @@ -19,26 +19,26 @@ index db9c04d74475e00983cc9df74d615e4b68f83688..adcfa6a783222482ce7ec5c7805fe44d if (this.player.isPassenger()) { this.player.absMoveTo(this.player.getX(), this.player.getY(), this.player.getZ(), f, f1); -@@ -1328,8 +1328,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1331,8 +1331,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // Paper start - Prevent moving into unloaded chunks if (this.player.level().paperConfig().chunks.preventMovingIntoUnloadedChunks && (this.player.getX() != toX || this.player.getZ() != toZ) && !worldserver.areChunksLoadedForMove(this.player.getBoundingBox().expandTowards(new Vec3(toX, toY, toZ).subtract(this.player.position())))) { -- this.internalTeleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot(), Collections.emptySet()); +- this.internalTeleport(PositionMoveRotation.of(this.player), Collections.emptySet()); - return; + // Paper start - Add fail move event + io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_INTO_UNLOADED_CHUNK, + toX, toY, toZ, toYaw, toPitch, false); + if (!event.isAllowed()) { -+ this.internalTeleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot(), Collections.emptySet()); ++ this.internalTeleport(PositionMoveRotation.of(this.player), Collections.emptySet()); + return; + } + // Paper end - Add fail move event } // Paper end - Prevent moving into unloaded chunks -@@ -1338,9 +1344,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1341,9 +1347,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - if (d10 - d9 > Math.max(f2, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { + if (d10 - d9 > Math.max(f2, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2))) { // CraftBukkit end - ServerGamePacketListenerImpl.LOGGER.warn("{} moved too quickly! {},{},{}", new Object[]{this.player.getName().getString(), d6, d7, d8}); - this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot()); @@ -56,7 +56,7 @@ index db9c04d74475e00983cc9df74d615e4b68f83688..adcfa6a783222482ce7ec5c7805fe44d } } } -@@ -1402,14 +1415,31 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1405,14 +1418,31 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl d8 = d2 - this.player.getZ(); d10 = d6 * d6 + d7 * d7 + d8 * d8; @@ -88,10 +88,10 @@ index db9c04d74475e00983cc9df74d615e4b68f83688..adcfa6a783222482ce7ec5c7805fe44d + } + if (teleportBack) { + // Paper end - Add fail move event - this.internalTeleport(d3, d4, d5, f, f1, Collections.emptySet()); // CraftBukkit - SPIGOT-1807: Don't call teleport event, when the client thinks the player is falling, because the chunks are not loaded on the client yet. + this.internalTeleport(d3, d4, d5, f, f1); // CraftBukkit - SPIGOT-1807: Don't call teleport event, when the client thinks the player is falling, because the chunks are not loaded on the client yet. this.player.doCheckFallDamage(this.player.getX() - d3, this.player.getY() - d4, this.player.getZ() - d5, packet.isOnGround()); } else { -@@ -3465,4 +3495,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3529,4 +3559,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl InteractionResult run(ServerPlayer player, Entity entity, InteractionHand hand); } diff --git a/patches/unapplied/server/0843-Folia-scheduler-and-owned-region-API.patch b/patches/server/0837-Folia-scheduler-and-owned-region-API.patch similarity index 97% rename from patches/unapplied/server/0843-Folia-scheduler-and-owned-region-API.patch rename to patches/server/0837-Folia-scheduler-and-owned-region-API.patch index 811bde5d9a1f..e6316ec4c753 100644 --- a/patches/unapplied/server/0843-Folia-scheduler-and-owned-region-API.patch +++ b/patches/server/0837-Folia-scheduler-and-owned-region-API.patch @@ -1148,12 +1148,12 @@ index 0000000000000000000000000000000000000000..d306f911757a4d556c82c0070d4837db + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 2cc22a9a5483c62cdf64870f5ce62b33018bef06..3ee0e2adf576e312c18da90adc46160ad85179fb 100644 +index 53c9be615a0f2939cd989e24e304e81e6e27f39d..f1b1be0caff83720d77454d333abae4613c66e72 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1576,6 +1576,20 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop, EntityTypeData> CLASS_TYPE_DATA = new HashMap<>(); private static final Map> ENTITY_TYPE_DATA = new HashMap<>(); -@@ -361,10 +362,10 @@ public final class CraftEntityTypes { +@@ -415,10 +416,10 @@ public final class CraftEntityTypes { // Set pos register(new EntityTypeData<>(EntityType.MARKER, Marker.class, CraftMarker::new, createAndSetPos(net.minecraft.world.entity.EntityType.MARKER))); diff --git a/patches/unapplied/server/0847-Only-capture-actual-tree-growth.patch b/patches/server/0840-Only-capture-actual-tree-growth.patch similarity index 80% rename from patches/unapplied/server/0847-Only-capture-actual-tree-growth.patch rename to patches/server/0840-Only-capture-actual-tree-growth.patch index de9896609a0e..a6227217648c 100644 --- a/patches/unapplied/server/0847-Only-capture-actual-tree-growth.patch +++ b/patches/server/0840-Only-capture-actual-tree-growth.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Only capture actual tree growth diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -index 78951f50188528718cdb3dbbaabe3f9f2760ffe3..7826e2a52da47914aca39fef958b8f398a2ff937 100644 +index f8f570a97789ab16e57774f233506a289277d5d9..18304349c9ab24657c4152aff800dba969174665 100644 --- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -634,6 +634,7 @@ public interface DispenseItemBehavior { +@@ -550,6 +550,7 @@ public interface DispenseItemBehavior { if (!fertilizeEvent.isCancelled()) { for (org.bukkit.block.BlockState blockstate : blocks) { blockstate.update(true); @@ -16,28 +16,16 @@ index 78951f50188528718cdb3dbbaabe3f9f2760ffe3..7826e2a52da47914aca39fef958b8f39 } } } -diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 10b3e41d589d480046e15a957902c2751b731cec..87cae96faf33fa0491b13add79e02fc225bd2f70 100644 ---- a/src/main/java/net/minecraft/world/item/ItemStack.java -+++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -466,6 +466,7 @@ public final class ItemStack implements DataComponentHolder { - for (CraftBlockState blockstate : blocks) { - // SPIGOT-7572 - Move fix for SPIGOT-7248 to CapturedBlockState, to allow bees in bee nest - CapturedBlockState.setBlockState(blockstate); -+ world.checkCapturedTreeStateForObserverNotify(blockposition, blockstate); // Paper - notify observers even if grow failed - } - entityhuman.awardStat(Stats.ITEM_USED.get(item)); // SPIGOT-7236 - award stat - } -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index bd909b08b5e604778d35ba6514cf8c353d489228..c8a3e49f08fd0d110ffc3be763cfda4e62f55916 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -1395,4 +1395,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java +index 509a67aff07bcdcad47eb77e923d442349a4f20c..1cb5e107a391ab56942cdb2d1cae7d5646a85ec6 100644 +--- a/src/main/java/net/minecraft/server/level/ServerLevel.java ++++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +@@ -2228,6 +2228,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return range <= 0 ? 64.0 * 64.0 : range * range; // 64 is taken from default in ServerLevel#levelEvent } // Paper end - respect global sound events gamerule + // Paper start - notify observers even if grow failed -+ public void checkCapturedTreeStateForObserverNotify(final BlockPos pos, final CraftBlockState craftBlockState) { ++ public void checkCapturedTreeStateForObserverNotify(final BlockPos pos, final org.bukkit.craftbukkit.block.CraftBlockState craftBlockState) { + // notify observers if the block state is the same and the Y level equals the original y level (for mega trees) + // blocks at the same Y level with the same state can be assumed to be saplings which trigger observers regardless of if the + // tree grew or not @@ -46,7 +34,21 @@ index bd909b08b5e604778d35ba6514cf8c353d489228..c8a3e49f08fd0d110ffc3be763cfda4e + } + } + // Paper end - notify observers even if grow failed - } + + @Override + public CrashReportCategory fillReportDetails(CrashReport report) { +diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java +index 612eb27b471a9ebfdea29a58e5a32931f869bfb6..db971851a9e219ead89d71bb97d65ff73d9fd285 100644 +--- a/src/main/java/net/minecraft/world/item/ItemStack.java ++++ b/src/main/java/net/minecraft/world/item/ItemStack.java +@@ -469,6 +469,7 @@ public final class ItemStack implements DataComponentHolder { + for (CraftBlockState blockstate : blocks) { + // SPIGOT-7572 - Move fix for SPIGOT-7248 to CapturedBlockState, to allow bees in bee nest + CapturedBlockState.setBlockState(blockstate); ++ world.checkCapturedTreeStateForObserverNotify(blockposition, blockstate); // Paper - notify observers even if grow failed + } + entityhuman.awardStat(Stats.ITEM_USED.get(item)); // SPIGOT-7236 - award stat + } diff --git a/src/main/java/net/minecraft/world/level/block/SaplingBlock.java b/src/main/java/net/minecraft/world/level/block/SaplingBlock.java index 2d7290ace5fc8890325a8ec623075ad32f9b1d44..d262a5a6da57ef9ba9a6fe0dfbc88f577105e74f 100644 --- a/src/main/java/net/minecraft/world/level/block/SaplingBlock.java @@ -60,7 +62,7 @@ index 2d7290ace5fc8890325a8ec623075ad32f9b1d44..d262a5a6da57ef9ba9a6fe0dfbc88f57 } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index af219df5267589300f0ad1d30fa5c81a1f50234f..461a66c323a74db5a70981fafc5fa20f54f0f40d 100644 +index 490a4f023491aaabd3966cb67901335c2b02bb52..a34e888f63ead250c41b6bbe6850a5e5b4254c3d 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -572,6 +572,7 @@ public class CraftBlock implements Block { diff --git a/patches/unapplied/server/0848-Use-correct-source-for-mushroom-block-spread-event.patch b/patches/server/0841-Use-correct-source-for-mushroom-block-spread-event.patch similarity index 94% rename from patches/unapplied/server/0848-Use-correct-source-for-mushroom-block-spread-event.patch rename to patches/server/0841-Use-correct-source-for-mushroom-block-spread-event.patch index a295e29bcbb6..658d9ec3761b 100644 --- a/patches/unapplied/server/0848-Use-correct-source-for-mushroom-block-spread-event.patch +++ b/patches/server/0841-Use-correct-source-for-mushroom-block-spread-event.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Use correct source for mushroom block spread event diff --git a/src/main/java/net/minecraft/world/level/block/MushroomBlock.java b/src/main/java/net/minecraft/world/level/block/MushroomBlock.java -index f549cac99a665f20f1cd1d8c807ed3649fed7531..1172d85c5c26ab2142343d91149766e5993cb36a 100644 +index 61fb134686c7cd538ae2f8fefe78fd9618a9990b..7900856c9e86afe907c00c9ac31bec93ece50abe 100644 --- a/src/main/java/net/minecraft/world/level/block/MushroomBlock.java +++ b/src/main/java/net/minecraft/world/level/block/MushroomBlock.java @@ -68,6 +68,7 @@ public class MushroomBlock extends BushBlock implements BonemealableBlock { diff --git a/patches/unapplied/server/0849-Respect-randomizeData-on-more-entities-when-spawning.patch b/patches/server/0842-Respect-randomizeData-on-more-entities-when-spawning.patch similarity index 85% rename from patches/unapplied/server/0849-Respect-randomizeData-on-more-entities-when-spawning.patch rename to patches/server/0842-Respect-randomizeData-on-more-entities-when-spawning.patch index d04e8bf4f636..67a5238077df 100644 --- a/patches/unapplied/server/0849-Respect-randomizeData-on-more-entities-when-spawning.patch +++ b/patches/server/0842-Respect-randomizeData-on-more-entities-when-spawning.patch @@ -9,10 +9,10 @@ Subject: [PATCH] Respect randomizeData on more entities when spawning * ExperienceOrb diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java -index 39aa116193f313f53540b0135d2ab26acb7f1469..afc75ef3fb0fac40673fdfb684bd1f0d0edeb6ce 100644 +index 6cf57640b3bd2bb0417129256ed77d9d67fcf04a..3b5277f90b5bba30d40d79ba67903a8d04d2c0df 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java -@@ -222,6 +222,13 @@ public final class CraftEntityTypes { +@@ -255,6 +255,13 @@ public final class CraftEntityTypes { entity.assignDirectionalMovement(new Vec3(direction.getX(), direction.getY(), direction.getZ()), 1.0); }; private static final BiConsumer ROT = (spawnData, entity) -> entity.setRot(spawnData.yaw(), spawnData.pitch()); // Paper @@ -26,7 +26,7 @@ index 39aa116193f313f53540b0135d2ab26acb7f1469..afc75ef3fb0fac40673fdfb684bd1f0d private static final Map, EntityTypeData> CLASS_TYPE_DATA = new HashMap<>(); private static final Map> ENTITY_TYPE_DATA = new HashMap<>(); -@@ -374,11 +381,12 @@ public final class CraftEntityTypes { +@@ -428,11 +435,12 @@ public final class CraftEntityTypes { net.minecraft.world.item.ItemStack itemStack = new net.minecraft.world.item.ItemStack(Items.STONE); ItemEntity item = new ItemEntity(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), itemStack); item.setPickUpDelay(10); @@ -39,9 +39,9 @@ index 39aa116193f313f53540b0135d2ab26acb7f1469..afc75ef3fb0fac40673fdfb684bd1f0d + combine(combine(spawnData -> new net.minecraft.world.entity.ExperienceOrb(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), 0, org.bukkit.entity.ExperienceOrb.SpawnReason.CUSTOM, null, null), CLEAR_MOVE_IF_NOT_RANDOMIZED), (spawnData, experienceOrb) -> { if (!spawnData.randomizeData()) { experienceOrb.setYRot(0); } }) // Paper - respect randomizeData )); register(new EntityTypeData<>(EntityType.AREA_EFFECT_CLOUD, AreaEffectCloud.class, CraftAreaEffectCloud::new, createAndMove(net.minecraft.world.entity.EntityType.AREA_EFFECT_CLOUD))); // Paper - set area effect cloud rotation - register(new EntityTypeData<>(EntityType.EGG, Egg.class, CraftEgg::new, spawnData -> new ThrownEgg(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z()))); -@@ -390,12 +398,23 @@ public final class CraftEntityTypes { - entity.setItem(CraftItemStack.asNMSCopy(new ItemStack(Material.SPLASH_POTION, 1))); + register(new EntityTypeData<>(EntityType.EGG, Egg.class, CraftEgg::new, spawnData -> new ThrownEgg(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), new net.minecraft.world.item.ItemStack(Items.EGG)))); +@@ -443,12 +451,23 @@ public final class CraftEntityTypes { + net.minecraft.world.entity.projectile.ThrownPotion entity = new net.minecraft.world.entity.projectile.ThrownPotion(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), new net.minecraft.world.item.ItemStack(Items.SPLASH_POTION)); return entity; })); - register(new EntityTypeData<>(EntityType.TNT, TNTPrimed.class, CraftTNTPrimed::new, spawnData -> new PrimedTnt(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), null))); @@ -64,5 +64,5 @@ index 39aa116193f313f53540b0135d2ab26acb7f1469..afc75ef3fb0fac40673fdfb684bd1f0d + })); + // Paper end - respect randomizeData register(new EntityTypeData<>(EntityType.EVOKER_FANGS, EvokerFangs.class, CraftEvokerFangs::new, spawnData -> new net.minecraft.world.entity.projectile.EvokerFangs(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), (float) Math.toRadians(spawnData.yaw()), 0, null))); - register(new EntityTypeData<>(EntityType.COMMAND_BLOCK_MINECART, CommandMinecart.class, CraftMinecartCommand::new, spawnData -> new MinecartCommandBlock(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z()))); - register(new EntityTypeData<>(EntityType.MINECART, RideableMinecart.class, CraftMinecartRideable::new, spawnData -> new Minecart(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z()))); + register(new EntityTypeData<>(EntityType.COMMAND_BLOCK_MINECART, CommandMinecart.class, CraftMinecartCommand::new, createMinecart(net.minecraft.world.entity.EntityType.COMMAND_BLOCK_MINECART))); + register(new EntityTypeData<>(EntityType.MINECART, RideableMinecart.class, CraftMinecartRideable::new, createMinecart(net.minecraft.world.entity.EntityType.MINECART))); diff --git a/patches/unapplied/server/0850-Use-correct-seed-on-api-world-load.patch b/patches/server/0843-Use-correct-seed-on-api-world-load.patch similarity index 81% rename from patches/unapplied/server/0850-Use-correct-seed-on-api-world-load.patch rename to patches/server/0843-Use-correct-seed-on-api-world-load.patch index 58cf8e10f3f7..8be7c2088a4c 100644 --- a/patches/unapplied/server/0850-Use-correct-seed-on-api-world-load.patch +++ b/patches/server/0843-Use-correct-seed-on-api-world-load.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Use correct seed on api world load diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 75c222e592d676e98b293767d00de54a61411ae7..69df0cf285a5af1011cc769a433683489ff3dded 100644 +index b5da166e147bff2ded9d295b1bf84cf71a3e7b8d..6bafb10ddbb1a4a73370b8cefac79e61d0c35ffc 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1398,7 +1398,7 @@ public final class CraftServer implements Server { +@@ -1389,7 +1389,7 @@ public final class CraftServer implements Server { net.minecraft.server.Main.forceUpgrade(worldSession, DataFixers.getDataFixer(), this.console.options.has("eraseCache"), () -> true, iregistrycustom_dimension, this.console.options.has("recreateRegionFiles")); } - long j = BiomeManager.obfuscateSeed(creator.seed()); + long j = BiomeManager.obfuscateSeed(worlddata.worldGenOptions().seed()); // Paper - use world seed List list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(worlddata)); - LevelStem worlddimension = iregistry.get(actualDimension); + LevelStem worlddimension = iregistry.getValue(actualDimension); diff --git a/patches/unapplied/server/0851-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch b/patches/server/0844-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch similarity index 91% rename from patches/unapplied/server/0851-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch rename to patches/server/0844-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch index 2f19c9d94a1e..d87f310ded9b 100644 --- a/patches/unapplied/server/0851-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch +++ b/patches/server/0844-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch @@ -7,10 +7,10 @@ The lists are only supposed to contain ticks for the 1 radius neighbours of the chunk. diff --git a/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java b/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java -index bfb73e016f107fb8da12903bf233a824d062ed73..22b6d0851a51da180cd8fbbe6554c5370f5ac5bd 100644 +index 5c7c8fb3c67047ddc1b92f03e889839b5a303ff4..ce3d79ebc7f933d0b34b3f8f71bbec872076847a 100644 --- a/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java +++ b/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java -@@ -100,6 +100,25 @@ public class UpgradeData { +@@ -113,6 +113,25 @@ public class UpgradeData { } } @@ -36,7 +36,7 @@ index bfb73e016f107fb8da12903bf233a824d062ed73..22b6d0851a51da180cd8fbbe6554c537 public void upgrade(LevelChunk chunk) { this.upgradeInside(chunk); -@@ -107,6 +126,11 @@ public class UpgradeData { +@@ -120,6 +139,11 @@ public class UpgradeData { upgradeSides(chunk, direction8); } diff --git a/patches/unapplied/server/0852-Cache-map-ids-on-item-frames.patch b/patches/server/0845-Cache-map-ids-on-item-frames.patch similarity index 85% rename from patches/unapplied/server/0852-Cache-map-ids-on-item-frames.patch rename to patches/server/0845-Cache-map-ids-on-item-frames.patch index 65e3e3499f44..7b1ac525686f 100644 --- a/patches/unapplied/server/0852-Cache-map-ids-on-item-frames.patch +++ b/patches/server/0845-Cache-map-ids-on-item-frames.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Cache map ids on item frames diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index f010be9605d7458add7e5693ff473fabf679c938..a2fbbbd7a66d4e7b1063638f8467e8887a417282 100644 +index 3cdcc4f44608d24550f2a8c6f3f5ce675d7777c5..7118e1f806af98159ec292f9340d7e4004e2b486 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -117,7 +117,7 @@ public class ServerEntity { +@@ -121,7 +121,7 @@ public class ServerEntity { ItemStack itemstack = entityitemframe.getItem(); if (this.level.paperConfig().maps.itemFrameCursorUpdateInterval > 0 && this.tickCount % this.level.paperConfig().maps.itemFrameCursorUpdateInterval == 0 && itemstack.getItem() instanceof MapItem) { // CraftBukkit - Moved this.tickCounter % 10 logic here so item frames do not enter the other blocks // Paper - Make item frame map cursor update interval configurable @@ -18,10 +18,10 @@ index f010be9605d7458add7e5693ff473fabf679c938..a2fbbbd7a66d4e7b1063638f8467e888 if (worldmap != null) { diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -index ba4e0ad7c7c2731d61ec7f60f19d7e9ec31a28ba..5b7245cd99593ee90e17c97e0104f3aba9ae05ea 100644 +index 07c143c3eac263848fc5daf6f958d16a1a163e92..f046a866215fea7df10963af1a235ba9d04d4242 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -@@ -50,6 +50,7 @@ public class ItemFrame extends HangingEntity { +@@ -51,6 +51,7 @@ public class ItemFrame extends HangingEntity { private static final float HEIGHT = 0.75F; public float dropChance; public boolean fixed; @@ -29,7 +29,7 @@ index ba4e0ad7c7c2731d61ec7f60f19d7e9ec31a28ba..5b7245cd99593ee90e17c97e0104f3ab public ItemFrame(EntityType type, Level world) { super(type, world); -@@ -322,6 +323,7 @@ public class ItemFrame extends HangingEntity { +@@ -334,6 +335,7 @@ public class ItemFrame extends HangingEntity { } private void onItemChanged(ItemStack stack) { diff --git a/patches/unapplied/server/0853-Fix-custom-statistic-criteria-creation.patch b/patches/server/0846-Fix-custom-statistic-criteria-creation.patch similarity index 92% rename from patches/unapplied/server/0853-Fix-custom-statistic-criteria-creation.patch rename to patches/server/0846-Fix-custom-statistic-criteria-creation.patch index 682cc84ee5aa..9301d80ab3f8 100644 --- a/patches/unapplied/server/0853-Fix-custom-statistic-criteria-creation.patch +++ b/patches/server/0846-Fix-custom-statistic-criteria-creation.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix custom statistic criteria creation diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 72c2f70d22c5ac920f13b11badac404dbb15c055..23ed0a130525a0b3a1b41330685476463c81f183 100644 +index a5a3a0f0460252415c243dfe3019d103b9589c5b..a4998c2df341a1b9a337afb24284428cd98e59d8 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -599,6 +599,14 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/unapplied/server/0854-Bandaid-fix-for-Effect.patch b/patches/server/0847-Bandaid-fix-for-Effect.patch similarity index 96% rename from patches/unapplied/server/0854-Bandaid-fix-for-Effect.patch rename to patches/server/0847-Bandaid-fix-for-Effect.patch index 867e3cef97e7..9aec13d2df4f 100644 --- a/patches/unapplied/server/0854-Bandaid-fix-for-Effect.patch +++ b/patches/server/0847-Bandaid-fix-for-Effect.patch @@ -68,10 +68,10 @@ index 71733f918ed84b9879ac1b142ef6205c5e768a9c..c856384019eff2f2d0bb831ebe1ccb0f break; case BONE_MEAL_USE: diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 58cd4ecd5582c01b836814f4151df2538b93143c..cb50fca4867688d2572e8ab5b7fef7243c5b8ba9 100644 +index 03cef3e33de1cf2a1ad4c7a5ba9a65ee3b69ee52..536ad499e893c5b9898fb02582eeca541c917890 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -1372,7 +1372,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1382,7 +1382,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { public void playEffect(Location loc, Effect effect, T data, int radius) { if (data != null) { Preconditions.checkArgument(effect.getData() != null, "Effect.%s does not have a valid Data", effect); @@ -81,10 +81,10 @@ index 58cd4ecd5582c01b836814f4151df2538b93143c..cb50fca4867688d2572e8ab5b7fef724 // Special case: the axis is optional for ELECTRIC_SPARK Preconditions.checkArgument(effect.getData() == null || effect == Effect.ELECTRIC_SPARK, "Wrong kind of data for the %s effect", effect); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 62914bde6f6b045e6b3682581899d756d1b272f1..ccd81bc7279a92f78bb882c9443cf9ca90fd9acf 100644 +index 79e35265978357eeb27c43205433d6b24335f401..e20e8ba103a0ba094e00ef08ff0fc3b741a9bce5 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -917,7 +917,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -930,7 +930,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { Preconditions.checkArgument(effect != null, "Effect cannot be null"); if (data != null) { Preconditions.checkArgument(effect.getData() != null, "Effect.%s does not have a valid Data", effect); diff --git a/patches/unapplied/server/0855-SculkCatalyst-bloom-API.patch b/patches/server/0848-SculkCatalyst-bloom-API.patch similarity index 100% rename from patches/unapplied/server/0855-SculkCatalyst-bloom-API.patch rename to patches/server/0848-SculkCatalyst-bloom-API.patch diff --git a/patches/unapplied/server/0856-API-for-an-entity-s-scoreboard-name.patch b/patches/server/0849-API-for-an-entity-s-scoreboard-name.patch similarity index 86% rename from patches/unapplied/server/0856-API-for-an-entity-s-scoreboard-name.patch rename to patches/server/0849-API-for-an-entity-s-scoreboard-name.patch index ac804a3ed5ae..ac005db8216d 100644 --- a/patches/unapplied/server/0856-API-for-an-entity-s-scoreboard-name.patch +++ b/patches/server/0849-API-for-an-entity-s-scoreboard-name.patch @@ -7,10 +7,10 @@ Was obtainable through different methods, but you had to use different methods depending on the implementation of Entity you were working with. diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index d3ff8015b2f713451b0aeb50e1b4cf81f2bcb7bc..3626fea17527da69e6fbee26f018f52ef036cf90 100644 +index d57798d6a53334eacf8235c0fd0f28d7719593fe..0d2d1b6eab153aea6015bd69f2bad58e67d065c3 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1263,4 +1263,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1264,4 +1264,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return !this.getHandle().level().noCollision(this.getHandle(), aabb); } // Paper end - Collision API diff --git a/patches/unapplied/server/0857-Deprecate-and-replace-methods-with-old-StructureType.patch b/patches/server/0850-Deprecate-and-replace-methods-with-old-StructureType.patch similarity index 92% rename from patches/unapplied/server/0857-Deprecate-and-replace-methods-with-old-StructureType.patch rename to patches/server/0850-Deprecate-and-replace-methods-with-old-StructureType.patch index b9b8b8b88ebd..b0b534680390 100644 --- a/patches/unapplied/server/0857-Deprecate-and-replace-methods-with-old-StructureType.patch +++ b/patches/server/0850-Deprecate-and-replace-methods-with-old-StructureType.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Deprecate and replace methods with old StructureType diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 69df0cf285a5af1011cc769a433683489ff3dded..8b871d29d883119cd8ad9ca134f4c1fce9362705 100644 +index 6bafb10ddbb1a4a73370b8cefac79e61d0c35ffc..2934e232c84603224470fdaba0103d42fc06e8b4 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2003,6 +2003,11 @@ public final class CraftServer implements Server { +@@ -1970,6 +1970,11 @@ public final class CraftServer implements Server { ServerLevel worldServer = ((CraftWorld) world).getHandle(); Location structureLocation = world.locateNearestStructure(location, structureType, radius, findUnexplored); @@ -20,7 +20,7 @@ index 69df0cf285a5af1011cc769a433683489ff3dded..8b871d29d883119cd8ad9ca134f4c1fc BlockPos structurePosition = CraftLocation.toBlockPosition(structureLocation); // Create map with trackPlayer = true, unlimitedTracking = true -@@ -2013,6 +2018,31 @@ public final class CraftServer implements Server { +@@ -1980,6 +1985,31 @@ public final class CraftServer implements Server { return CraftItemStack.asBukkitCopy(stack); } diff --git a/patches/unapplied/server/0858-Don-t-tab-complete-namespaced-commands-if-send-names.patch b/patches/server/0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch similarity index 92% rename from patches/unapplied/server/0858-Don-t-tab-complete-namespaced-commands-if-send-names.patch rename to patches/server/0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch index 5725b805f02a..0e8de9d68d71 100644 --- a/patches/unapplied/server/0858-Don-t-tab-complete-namespaced-commands-if-send-names.patch +++ b/patches/server/0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch @@ -11,10 +11,10 @@ This patch prevents server from sending namespaced commands when player requests tab-complete only commands. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index adcfa6a783222482ce7ec5c7805fe44dd24bf7d0..7750660defe490bcdc24a3b4ad4f495c8a703fed 100644 +index 618c620b4bca535c454691f9a87c9b36a36021e2..f21a5b9de17db9a094b22267b33bbffbf7ef8966 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -820,6 +820,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -824,6 +824,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl ParseResults parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack()); this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { diff --git a/patches/unapplied/server/0859-Properly-handle-BlockBreakEvent-isDropItems.patch b/patches/server/0852-Properly-handle-BlockBreakEvent-isDropItems.patch similarity index 91% rename from patches/unapplied/server/0859-Properly-handle-BlockBreakEvent-isDropItems.patch rename to patches/server/0852-Properly-handle-BlockBreakEvent-isDropItems.patch index 4cd189674296..047d717ba6e0 100644 --- a/patches/unapplied/server/0859-Properly-handle-BlockBreakEvent-isDropItems.patch +++ b/patches/server/0852-Properly-handle-BlockBreakEvent-isDropItems.patch @@ -9,10 +9,10 @@ food consumption, turtle egg count decreases, ice to water conversions and beehive releases diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index 717d015dd4637dd9d568b751be1dc1046b0a0560..c680f081ba548f84f07a968a46811090c53e57e3 100644 +index 2aee9c2fbe38076317a3de7c3fdbd6988b64b389..3bd4ab8161c29bb8df2ba496a4430393b6593476 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -439,8 +439,8 @@ public class ServerPlayerGameMode { +@@ -437,8 +437,8 @@ public class ServerPlayerGameMode { isCorrectTool = flag1; // Paper - Trigger bee_nest_destroyed trigger in the correct place itemstack.mineBlock(this.level, iblockdata1, pos, this.player); @@ -24,10 +24,10 @@ index 717d015dd4637dd9d568b751be1dc1046b0a0560..c680f081ba548f84f07a968a46811090 // return true; // CraftBukkit diff --git a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java -index c75227b2ea165dcd65c203e60157ac7cdebd4bc6..4669b1877be5eecf6738eefd81a35bde531759d6 100644 +index 90f69a0c4d0707fd2319db71aea7dfdc14636d82..9591870420390fe1a69d44855a8f4de779332b7d 100644 --- a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java -@@ -86,8 +86,8 @@ public class BeehiveBlock extends BaseEntityBlock { +@@ -94,8 +94,8 @@ public class BeehiveBlock extends BaseEntityBlock { } @Override @@ -39,10 +39,10 @@ index c75227b2ea165dcd65c203e60157ac7cdebd4bc6..4669b1877be5eecf6738eefd81a35bde if (!EnchantmentHelper.hasTag(tool, EnchantmentTags.PREVENTS_BEE_SPAWNS_WHEN_MINING)) { tileentitybeehive.emptyAllLivingFromHive(player, state, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY); diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index 232e6216dc36aa698047fc0badf78c347414b3a5..c083dc8b2a69c3747b250d13f1a28ad22b5e6119 100644 +index 4d140bd83ca0e1554afad80ec4fc6186188a79d8..6fb3f551f432d7e668c606fb7bd3514408e0478a 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -402,10 +402,18 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -405,10 +405,18 @@ public class Block extends BlockBehaviour implements ItemLike { return this.defaultBlockState(); } @@ -62,10 +62,10 @@ index 232e6216dc36aa698047fc0badf78c347414b3a5..c083dc8b2a69c3747b250d13f1a28ad2 public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {} diff --git a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java -index 7fdf744a2be55313cc75c1322f6534f55cf463f5..f446c40c4d90307c568faa2866800f5326634df6 100644 +index edb3b6cdb617c48140539728af1373993e78648f..4fe83bd0f355549847b66afb7e61f6f2a6d97016 100644 --- a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java -@@ -96,8 +96,8 @@ public class DoublePlantBlock extends BushBlock { +@@ -98,8 +98,8 @@ public class DoublePlantBlock extends BushBlock { } @Override @@ -77,10 +77,10 @@ index 7fdf744a2be55313cc75c1322f6534f55cf463f5..f446c40c4d90307c568faa2866800f53 protected static void preventDropFromBottomPart(Level world, BlockPos pos, BlockState state, Player player) { diff --git a/src/main/java/net/minecraft/world/level/block/IceBlock.java b/src/main/java/net/minecraft/world/level/block/IceBlock.java -index e862814c1e54776f11050623b52476accc2f1f79..ac775afb265430ac202cfa3900a036d11a308b1e 100644 +index 067a2d969ca0979ae67b600e303deec93eda0251..a94762e65853ccad38cf90b0049ca256106c0c9f 100644 --- a/src/main/java/net/minecraft/world/level/block/IceBlock.java +++ b/src/main/java/net/minecraft/world/level/block/IceBlock.java -@@ -33,8 +33,8 @@ public class IceBlock extends HalfTransparentBlock { +@@ -34,8 +34,8 @@ public class IceBlock extends HalfTransparentBlock { } @Override @@ -92,10 +92,10 @@ index e862814c1e54776f11050623b52476accc2f1f79..ac775afb265430ac202cfa3900a036d1 this.afterDestroy(world, pos, tool); } diff --git a/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java b/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java -index bdcb732a31fff0cfc2119132079ce197c7a77c9a..a6f408e56fa6c9de82fd93555fe21e1b11ce1022 100644 +index 85d9829e979ef5f22aee9c346800612f479786b7..953ddb2ea6fd48e57712e30a6addf23e188e5312 100644 --- a/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java -@@ -174,8 +174,8 @@ public class TurtleEggBlock extends Block { +@@ -175,8 +175,8 @@ public class TurtleEggBlock extends Block { } @Override diff --git a/patches/unapplied/server/0860-Fire-entity-death-event-for-ender-dragon.patch b/patches/server/0853-Fire-entity-death-event-for-ender-dragon.patch similarity index 86% rename from patches/unapplied/server/0860-Fire-entity-death-event-for-ender-dragon.patch rename to patches/server/0853-Fire-entity-death-event-for-ender-dragon.patch index 66624e354c18..0efcc781a41b 100644 --- a/patches/unapplied/server/0860-Fire-entity-death-event-for-ender-dragon.patch +++ b/patches/server/0853-Fire-entity-death-event-for-ender-dragon.patch @@ -5,13 +5,13 @@ Subject: [PATCH] Fire entity death event for ender dragon diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -index 6306f7925ac4852d8eed7508a11764c636dd7d36..5868d2e9e05a698c77117cf87c79b636b50fe289 100644 +index 38456d3901e495e4c401cff0de7ae38544c1b2a7..2df8bf818345246cc1f88b93e4a3b62e61772efb 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -@@ -657,6 +657,15 @@ public class EnderDragon extends Mob implements Enemy { +@@ -627,6 +627,14 @@ public class EnderDragon extends Mob implements Enemy { @Override - public void kill() { + public void kill(ServerLevel world) { + // Paper start - Fire entity death event + this.silentDeath = true; + org.bukkit.event.entity.EntityDeathEvent deathEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, this.damageSources().genericKill()); @@ -20,7 +20,6 @@ index 6306f7925ac4852d8eed7508a11764c636dd7d36..5868d2e9e05a698c77117cf87c79b636 + return; + } + // Paper end - Fire entity death event -+ this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause this.gameEvent(GameEvent.ENTITY_DIE); if (this.dragonFight != null) { diff --git a/patches/unapplied/server/0861-Configurable-entity-tracking-range-by-Y-coordinate.patch b/patches/server/0854-Configurable-entity-tracking-range-by-Y-coordinate.patch similarity index 92% rename from patches/unapplied/server/0861-Configurable-entity-tracking-range-by-Y-coordinate.patch rename to patches/server/0854-Configurable-entity-tracking-range-by-Y-coordinate.patch index 4b7085d8317b..6c2edf83e23d 100644 --- a/patches/unapplied/server/0861-Configurable-entity-tracking-range-by-Y-coordinate.patch +++ b/patches/server/0854-Configurable-entity-tracking-range-by-Y-coordinate.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Configurable entity tracking range by Y coordinate Options to configure entity tracking by Y coordinate, also for each entity category. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index dca6087dc4e1c177c3dfdae01f140cf80c179803..57af5d1986021c9a135599c6f55b091aebd3bab7 100644 +index ec19eb88705a07db45f1a3541571fb7f43efb5a9..49d926313b0d0f2ed2e93ca824009c8d0a988f67 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1524,7 +1524,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1583,7 +1583,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider double d0 = (double) Math.min(this.getEffectiveRange(), i * 16); double d1 = vec3d.x * vec3d.x + vec3d.z * vec3d.z; double d2 = d0 * d0; diff --git a/patches/unapplied/server/0862-Add-Listing-API-for-Player.patch b/patches/server/0855-Add-Listing-API-for-Player.patch similarity index 90% rename from patches/unapplied/server/0862-Add-Listing-API-for-Player.patch rename to patches/server/0855-Add-Listing-API-for-Player.patch index bd96c74d581e..d6ed7ccd4724 100644 --- a/patches/unapplied/server/0862-Add-Listing-API-for-Player.patch +++ b/patches/server/0855-Add-Listing-API-for-Player.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add Listing API for Player diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java -index 6247a21c9c391abf1f6db3482c659593e4f29355..9ccca41bf23efadba5329cc584bbcdcacbe09a92 100644 +index 29b465fc1dc50e0e84ddb889c5303e80fe662874..4d67d98257b2cb9045d03c999cfd4ba2caf8453c 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java @@ -37,6 +37,17 @@ public class ClientboundPlayerInfoUpdatePacket implements Packet players) { EnumSet enumSet = EnumSet.of( -@@ -50,6 +61,28 @@ public class ClientboundPlayerInfoUpdatePacket implements Packet { -@@ -158,16 +191,24 @@ public class ClientboundPlayerInfoUpdatePacket implements Packet channels = new HashSet(); private final Map>> invertedVisibilityEntities = new HashMap<>(); @@ -130,7 +133,7 @@ index ccd81bc7279a92f78bb882c9443cf9ca90fd9acf..a3912d4de96a6bb2b9b3977705fa3fac private static final WeakHashMap> pluginWeakReferences = new WeakHashMap<>(); private int hash = 0; private double health = 20; -@@ -2092,7 +2093,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2105,7 +2106,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { otherPlayer.setUUID(uuidOverride); } // Paper end @@ -139,7 +142,7 @@ index ccd81bc7279a92f78bb882c9443cf9ca90fd9acf..a3912d4de96a6bb2b9b3977705fa3fac if (original != null) otherPlayer.setUUID(original); // Paper - uuid override } -@@ -2196,6 +2197,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2209,6 +2210,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return (entity != null) ? this.canSee(entity) : false; // If we can't find it, we can't see it } diff --git a/patches/unapplied/server/0863-Configurable-Region-Compression-Format.patch b/patches/server/0856-Configurable-Region-Compression-Format.patch similarity index 100% rename from patches/unapplied/server/0863-Configurable-Region-Compression-Format.patch rename to patches/server/0856-Configurable-Region-Compression-Format.patch diff --git a/patches/unapplied/server/0864-Add-BlockFace-to-BlockDamageEvent.patch b/patches/server/0857-Add-BlockFace-to-BlockDamageEvent.patch similarity index 88% rename from patches/unapplied/server/0864-Add-BlockFace-to-BlockDamageEvent.patch rename to patches/server/0857-Add-BlockFace-to-BlockDamageEvent.patch index 749d93224ec1..55a882d6f380 100644 --- a/patches/unapplied/server/0864-Add-BlockFace-to-BlockDamageEvent.patch +++ b/patches/server/0857-Add-BlockFace-to-BlockDamageEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add BlockFace to BlockDamageEvent diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index c680f081ba548f84f07a968a46811090c53e57e3..d839f8df658c894f144ba4637d290ffbed77e132 100644 +index 3bd4ab8161c29bb8df2ba496a4430393b6593476..0da6496c18341c01fc4551ead7e740a6037dcf31 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -261,7 +261,7 @@ public class ServerPlayerGameMode { +@@ -259,7 +259,7 @@ public class ServerPlayerGameMode { } return; } @@ -18,10 +18,10 @@ index c680f081ba548f84f07a968a46811090c53e57e3..d839f8df658c894f144ba4637d290ffb if (blockEvent.isCancelled()) { // Let the client know the block still exists diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 907ea60b647d529f133986632d00416269bc311e..6b241ec85f360ec79f18b911175d7092861024a4 100644 +index 03afabc3ab4b264f84698627b79e58f502a8cea9..0bf830b51f078d1a642e1bbec6cd8b6e83501135 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -661,13 +661,13 @@ public class CraftEventFactory { +@@ -660,13 +660,13 @@ public class CraftEventFactory { /** * BlockDamageEvent */ diff --git a/patches/unapplied/server/0865-Fix-NPE-on-Boat-getStatus.patch b/patches/server/0858-Fix-NPE-on-Boat-getStatus.patch similarity index 87% rename from patches/unapplied/server/0865-Fix-NPE-on-Boat-getStatus.patch rename to patches/server/0858-Fix-NPE-on-Boat-getStatus.patch index 70323a435274..b2413997613a 100644 --- a/patches/unapplied/server/0865-Fix-NPE-on-Boat-getStatus.patch +++ b/patches/server/0858-Fix-NPE-on-Boat-getStatus.patch @@ -9,10 +9,10 @@ Boat status is null until the entity is added to the world and the tick() method public net.minecraft.world.entity.vehicle.Boat getStatus()Lnet/minecraft/world/entity/vehicle/Boat$Status; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java -index d161cbf9c83cd78593864850b98f688da2c85aa5..e33b1b6fd50a4eea57500cc00dba20d6edcab75d 100644 +index 5de1ada561d11c247a597effab1e0aa363b7c90f..412fd9e87ec81cf50cb8bc82fe2dad5dd0029039 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java -@@ -88,6 +88,17 @@ public class CraftBoat extends CraftVehicle implements Boat { +@@ -87,6 +87,17 @@ public abstract class CraftBoat extends CraftVehicle implements Boat { @Override public Status getStatus() { diff --git a/patches/unapplied/server/0866-Expand-Pose-API.patch b/patches/server/0859-Expand-Pose-API.patch similarity index 81% rename from patches/unapplied/server/0866-Expand-Pose-API.patch rename to patches/server/0859-Expand-Pose-API.patch index 1a9699d342a3..fb6535a3d5cb 100644 --- a/patches/unapplied/server/0866-Expand-Pose-API.patch +++ b/patches/server/0859-Expand-Pose-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Expand Pose API diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index f81a576084ccceb2b02e8d8cd57442efc7ff1e9f..84d283cd637b5c84a8682acec503b0e3831d1684 100644 +index aeeb90481a9ac0a8ec9e3c5af08a32ca3e32bfb6..a8a5b28d95f7c3ce944f51993dd0c0eb98e3c550 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -425,6 +425,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -427,6 +427,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @javax.annotation.Nullable private UUID originWorld; public boolean freezeLocked = false; // Paper - Freeze Tick Lock API @@ -16,8 +16,8 @@ index f81a576084ccceb2b02e8d8cd57442efc7ff1e9f..84d283cd637b5c84a8682acec503b0e3 public void setOrigin(@javax.annotation.Nonnull Location location) { this.origin = location.toVector(); -@@ -618,6 +619,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - public void onClientRemoval() {} +@@ -625,6 +626,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + public void onRemoval(Entity.RemovalReason reason) {} public void setPose(net.minecraft.world.entity.Pose pose) { + if (this.fixedPose) return; // Paper - Expand Pose API @@ -25,10 +25,10 @@ index f81a576084ccceb2b02e8d8cd57442efc7ff1e9f..84d283cd637b5c84a8682acec503b0e3 if (pose == this.getPose()) { return; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 3626fea17527da69e6fbee26f018f52ef036cf90..580427bf1521ac9fef37f7464e12a7bfe4fbfb10 100644 +index 0d2d1b6eab153aea6015bd69f2bad58e67d065c3..9c8e2731ca37a16cb538da27190c085bbc9791e3 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -899,6 +899,20 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -900,6 +900,20 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { public boolean isSneaking() { return this.getHandle().isShiftKeyDown(); } From 80de05ff33104d1c6c6ddd9a32765c6aee86fd5b Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Thu, 24 Oct 2024 12:11:32 +0200 Subject: [PATCH 036/119] Patch me this, patch me that --- .../server/0241-Improve-death-events.patch | 4 +- ...316-add-hand-to-BlockMultiPlaceEvent.patch | 2 +- ...item-duplication-and-teleport-issues.patch | 2 +- ...ceOrb-merging-stacking-API-and-fixes.patch | 2 +- .../server/0379-Add-PrepareResultEvent.patch | 8 +- patches/server/0396-Add-BellRingEvent.patch | 2 +- ...-OBSTRUCTED-reason-to-BedEnterResult.patch | 2 +- .../0459-Add-BlockFailedDispenseEvent.patch | 4 +- .../0473-Add-BlockPreDispenseEvent.patch | 4 +- .../0477-Expand-EntityUnleashEvent.patch | 4 +- ...w-adding-items-to-BlockDropItemEvent.patch | 2 +- .../0550-Fix-potions-splash-events.patch | 2 +- .../server/0584-Add-critical-damage-API.patch | 8 +- patches/server/0670-More-Projectile-API.patch | 2 +- ...lock-data-for-EntityChangeBlockEvent.patch | 4 +- ...-interactions-with-items-on-cooldown.patch | 2 +- .../0790-Add-EntityFertilizeEggEvent.patch | 4 +- .../0810-Expand-PlayerItemMendEvent.patch | 4 +- ...0824-Call-missing-BlockDispenseEvent.patch | 4 +- ...enceOrb-should-call-EntitySpawnEvent.patch | 2 +- ...57-Add-BlockFace-to-BlockDamageEvent.patch | 2 +- .../0860-More-DragonBattle-API.patch} | 4 +- .../0861-Add-PlayerPickItemEvent.patch} | 20 +- .../0862-Allow-trident-custom-damage.patch} | 4 +- ...3-Expose-hand-in-BlockCanBuildEvent.patch} | 6 +- ...-nearest-structure-border-iteration.patch} | 2 +- ...Implement-OfflinePlayer-isConnected.patch} | 4 +- .../0866-Fix-slot-desync.patch} | 40 +- ...titleOverride-to-InventoryOpenEvent.patch} | 14 +- ...68-Configure-sniffer-egg-hatch-time.patch} | 6 +- ...-proximity-check-before-entity-look.patch} | 8 +- ...kip-POI-finding-if-stuck-in-vehicle.patch} | 0 ...t-sanity-checks-in-container-clicks.patch} | 10 +- ...ll-BlockRedstoneEvents-for-lecterns.patch} | 4 +- ...roper-checking-of-empty-item-stacks.patch} | 4 +- ...ix-silent-equipment-change-for-mobs.patch} | 8 +- .../0875-Fix-spigot-s-Forced-Stats.patch} | 0 ...ing-InventoryHolders-to-inventories.patch} | 56 ++- ...-entities-in-chunks-that-are-positio.patch | 43 ++ ...sing-logs-for-log-ips-config-option.patch} | 0 ...n-on-UpgradeData.BlockFixers-class-.patch} | 4 +- ...-AdvancementProgress-getDateAwarded.patch} | 0 ...idebar-objectives-not-being-cleared.patch} | 0 ...x-missing-map-initialize-event-call.patch} | 4 +- ...a-when-attaching-firework-to-entity.patch} | 0 ...84-Fix-UnsafeValues-loadAdvancement.patch} | 4 +- .../0885-Add-player-idle-duration-API.patch} | 4 +- ...-if-we-can-see-non-visible-entities.patch} | 4 +- ...NPE-in-SculkBloomEvent-world-access.patch} | 2 +- ...tack-for-Player-sendEquipmentChange.patch} | 4 +- .../0889-Optimize-VarInts.patch} | 0 ...e-collision-shape-of-a-block-before.patch} | 4 +- ...redicate-for-blocks-when-raytracing.patch} | 16 +- ...em-packets-with-collector-as-source.patch} | 4 +- .../0893-Expand-LingeringPotion-API.patch} | 4 +- ...ngEffect-powers-lightning-rods-and-.patch} | 24 +- ...h-event-for-all-player-interactions.patch} | 16 +- ...everal-issues-with-EntityBreedEvent.patch} | 47 +- ...897-Add-UUID-attribute-modifier-API.patch} | 0 ...-event-call-for-entity-teleport-API.patch} | 4 +- ...y-create-LootContext-for-criterions.patch} | 0 ...-t-fire-sync-events-during-worldgen.patch} | 62 +-- .../0901-Add-Structure-check-API.patch} | 4 +- ...-getAttributeModifier-duplication-c.patch} | 4 +- ...store-vanilla-entity-drops-behavior.patch} | 75 ++-- ...-Dont-resend-blocks-on-interactions.patch} | 56 +-- .../0905-add-more-scoreboard-API.patch} | 0 .../0906-Improve-Registry.patch} | 6 +- ...on-null-loc-for-EntityTeleportEvent.patch} | 22 +- .../0908-Add-experience-points-API.patch} | 8 +- .../0909-Add-drops-to-shear-events.patch | 398 +++++++++++++++++ ...-entities-in-chunks-that-are-positio.patch | 50 --- .../0916-Add-drops-to-shear-events.patch | 411 ------------------ 73 files changed, 760 insertions(+), 784 deletions(-) rename patches/{unapplied/server/0867-More-DragonBattle-API.patch => server/0860-More-DragonBattle-API.patch} (96%) rename patches/{unapplied/server/0868-Add-PlayerPickItemEvent.patch => server/0861-Add-PlayerPickItemEvent.patch} (73%) rename patches/{unapplied/server/0869-Allow-trident-custom-damage.patch => server/0862-Allow-trident-custom-damage.patch} (93%) rename patches/{unapplied/server/0870-Expose-hand-in-BlockCanBuildEvent.patch => server/0863-Expose-hand-in-BlockCanBuildEvent.patch} (91%) rename patches/{unapplied/server/0871-Optimize-nearest-structure-border-iteration.patch => server/0864-Optimize-nearest-structure-border-iteration.patch} (95%) rename patches/{unapplied/server/0872-Implement-OfflinePlayer-isConnected.patch => server/0865-Implement-OfflinePlayer-isConnected.patch} (90%) rename patches/{unapplied/server/0873-Fix-slot-desync.patch => server/0866-Fix-slot-desync.patch} (84%) rename patches/{unapplied/server/0874-Add-titleOverride-to-InventoryOpenEvent.patch => server/0867-Add-titleOverride-to-InventoryOpenEvent.patch} (94%) rename patches/{unapplied/server/0875-Configure-sniffer-egg-hatch-time.patch => server/0868-Configure-sniffer-egg-hatch-time.patch} (88%) rename patches/{unapplied/server/0876-Do-crystal-portal-proximity-check-before-entity-look.patch => server/0869-Do-crystal-portal-proximity-check-before-entity-look.patch} (93%) rename patches/{unapplied/server/0877-Skip-POI-finding-if-stuck-in-vehicle.patch => server/0870-Skip-POI-finding-if-stuck-in-vehicle.patch} (100%) rename patches/{unapplied/server/0878-Add-slot-sanity-checks-in-container-clicks.patch => server/0871-Add-slot-sanity-checks-in-container-clicks.patch} (87%) rename patches/{unapplied/server/0879-Call-BlockRedstoneEvents-for-lecterns.patch => server/0872-Call-BlockRedstoneEvents-for-lecterns.patch} (89%) rename patches/{unapplied/server/0880-Allow-proper-checking-of-empty-item-stacks.patch => server/0873-Allow-proper-checking-of-empty-item-stacks.patch} (89%) rename patches/{unapplied/server/0881-Fix-silent-equipment-change-for-mobs.patch => server/0874-Fix-silent-equipment-change-for-mobs.patch} (94%) rename patches/{unapplied/server/0882-Fix-spigot-s-Forced-Stats.patch => server/0875-Fix-spigot-s-Forced-Stats.patch} (100%) rename patches/{unapplied/server/0883-Add-missing-InventoryHolders-to-inventories.patch => server/0876-Add-missing-InventoryHolders-to-inventories.patch} (88%) create mode 100644 patches/server/0877-Do-not-read-tile-entities-in-chunks-that-are-positio.patch rename patches/{unapplied/server/0885-Add-missing-logs-for-log-ips-config-option.patch => server/0878-Add-missing-logs-for-log-ips-config-option.patch} (100%) rename patches/{unapplied/server/0886-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch => server/0879-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch} (90%) rename patches/{unapplied/server/0887-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch => server/0880-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch} (100%) rename patches/{unapplied/server/0888-Fix-team-sidebar-objectives-not-being-cleared.patch => server/0881-Fix-team-sidebar-objectives-not-being-cleared.patch} (100%) rename patches/{unapplied/server/0889-Fix-missing-map-initialize-event-call.patch => server/0882-Fix-missing-map-initialize-event-call.patch} (91%) rename patches/{unapplied/server/0890-Update-entity-data-when-attaching-firework-to-entity.patch => server/0883-Update-entity-data-when-attaching-firework-to-entity.patch} (100%) rename patches/{unapplied/server/0891-Fix-UnsafeValues-loadAdvancement.patch => server/0884-Fix-UnsafeValues-loadAdvancement.patch} (93%) rename patches/{unapplied/server/0892-Add-player-idle-duration-API.patch => server/0885-Add-player-idle-duration-API.patch} (85%) rename patches/{unapplied/server/0893-Don-t-check-if-we-can-see-non-visible-entities.patch => server/0886-Don-t-check-if-we-can-see-non-visible-entities.patch} (85%) rename patches/{unapplied/server/0894-Fix-NPE-in-SculkBloomEvent-world-access.patch => server/0887-Fix-NPE-in-SculkBloomEvent-world-access.patch} (96%) rename patches/{unapplied/server/0895-Allow-null-itemstack-for-Player-sendEquipmentChange.patch => server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch} (84%) rename patches/{unapplied/server/0896-Optimize-VarInts.patch => server/0889-Optimize-VarInts.patch} (100%) rename patches/{unapplied/server/0897-Add-API-to-get-the-collision-shape-of-a-block-before.patch => server/0890-Add-API-to-get-the-collision-shape-of-a-block-before.patch} (90%) rename patches/{unapplied/server/0898-Add-predicate-for-blocks-when-raytracing.patch => server/0891-Add-predicate-for-blocks-when-raytracing.patch} (93%) rename patches/{unapplied/server/0899-Broadcast-take-item-packets-with-collector-as-source.patch => server/0892-Broadcast-take-item-packets-with-collector-as-source.patch} (88%) rename patches/{unapplied/server/0900-Expand-LingeringPotion-API.patch => server/0893-Expand-LingeringPotion-API.patch} (88%) rename patches/{unapplied/server/0901-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch => server/0894-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch} (76%) rename patches/{unapplied/server/0902-Add-hand-to-fish-event-for-all-player-interactions.patch => server/0895-Add-hand-to-fish-event-for-all-player-interactions.patch} (89%) rename patches/{unapplied/server/0903-Fix-several-issues-with-EntityBreedEvent.patch => server/0896-Fix-several-issues-with-EntityBreedEvent.patch} (73%) rename patches/{unapplied/server/0904-Add-UUID-attribute-modifier-API.patch => server/0897-Add-UUID-attribute-modifier-API.patch} (100%) rename patches/{unapplied/server/0905-Fix-missing-event-call-for-entity-teleport-API.patch => server/0898-Fix-missing-event-call-for-entity-teleport-API.patch} (88%) rename patches/{unapplied/server/0906-Lazily-create-LootContext-for-criterions.patch => server/0899-Lazily-create-LootContext-for-criterions.patch} (100%) rename patches/{unapplied/server/0907-Don-t-fire-sync-events-during-worldgen.patch => server/0900-Don-t-fire-sync-events-during-worldgen.patch} (82%) rename patches/{unapplied/server/0908-Add-Structure-check-API.patch => server/0901-Add-Structure-check-API.patch} (85%) rename patches/{unapplied/server/0909-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch => server/0902-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch} (89%) rename patches/{unapplied/server/0910-Restore-vanilla-entity-drops-behavior.patch => server/0903-Restore-vanilla-entity-drops-behavior.patch} (82%) rename patches/{unapplied/server/0911-Dont-resend-blocks-on-interactions.patch => server/0904-Dont-resend-blocks-on-interactions.patch} (85%) rename patches/{unapplied/server/0912-add-more-scoreboard-API.patch => server/0905-add-more-scoreboard-API.patch} (100%) rename patches/{unapplied/server/0913-Improve-Registry.patch => server/0906-Improve-Registry.patch} (94%) rename patches/{unapplied/server/0914-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch => server/0907-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch} (83%) rename patches/{unapplied/server/0915-Add-experience-points-API.patch => server/0908-Add-experience-points-API.patch} (91%) create mode 100644 patches/server/0909-Add-drops-to-shear-events.patch delete mode 100644 patches/unapplied/server/0884-Do-not-read-tile-entities-in-chunks-that-are-positio.patch delete mode 100644 patches/unapplied/server/0916-Add-drops-to-shear-events.patch diff --git a/patches/server/0241-Improve-death-events.patch b/patches/server/0241-Improve-death-events.patch index 26de33a12c1a..d6a188627045 100644 --- a/patches/server/0241-Improve-death-events.patch +++ b/patches/server/0241-Improve-death-events.patch @@ -440,7 +440,7 @@ index 535e0438b02fd7c10aee0d24786a6e38c6e48359..c132b4d4d871eaeadec78921a99ba706 public void injectScaledMaxHealth(Collection collection, boolean force) { diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 474f330f381aa74e9f2fd0accdbaf2617ec1c557..834516cac1f3ac5f078dd4e4dfa449f39462658c 100644 +index 474f330f381aa74e9f2fd0accdbaf2617ec1c557..199abd66d2113e7bc8c478fe8e4f6657d2e12304 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -902,8 +902,15 @@ public class CraftEventFactory { @@ -463,7 +463,7 @@ index 474f330f381aa74e9f2fd0accdbaf2617ec1c557..834516cac1f3ac5f078dd4e4dfa449f3 PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage); event.setKeepInventory(keepInventory); event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel -+populateFields(victim, event); // Paper - make cancellable ++ populateFields(victim, event); // Paper - make cancellable Bukkit.getServer().getPluginManager().callEvent(event); + // Paper start - make cancellable + if (event.isCancelled()) { diff --git a/patches/server/0316-add-hand-to-BlockMultiPlaceEvent.patch b/patches/server/0316-add-hand-to-BlockMultiPlaceEvent.patch index d0fe787da6ad..f5cef45e8c2c 100644 --- a/patches/server/0316-add-hand-to-BlockMultiPlaceEvent.patch +++ b/patches/server/0316-add-hand-to-BlockMultiPlaceEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] add hand to BlockMultiPlaceEvent diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 834516cac1f3ac5f078dd4e4dfa449f39462658c..41f23ce732b6e90828b1bbda7f4b3470cd462c4a 100644 +index 199abd66d2113e7bc8c478fe8e4f6657d2e12304..0627e3be754dbf8201f3212cf823e2f8cb77cdeb 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -411,13 +411,18 @@ public class CraftEventFactory { diff --git a/patches/server/0344-Fix-item-duplication-and-teleport-issues.patch b/patches/server/0344-Fix-item-duplication-and-teleport-issues.patch index 1e7965da69d9..2b42b0e70c22 100644 --- a/patches/server/0344-Fix-item-duplication-and-teleport-issues.patch +++ b/patches/server/0344-Fix-item-duplication-and-teleport-issues.patch @@ -122,7 +122,7 @@ index e20565cf256aacd012a1722c5ebbf9016bc82e42..59fbfe8de2dc5ec020dd61a5e446b0b6 } } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 41f23ce732b6e90828b1bbda7f4b3470cd462c4a..0b9c96105bea9a0d1af17b7ecf4479d3596faa80 100644 +index 0627e3be754dbf8201f3212cf823e2f8cb77cdeb..6b094f8bdf1f25d5c2e108eb88d95aed4a41f6f3 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -903,6 +903,11 @@ public class CraftEventFactory { diff --git a/patches/server/0352-ExperienceOrb-merging-stacking-API-and-fixes.patch b/patches/server/0352-ExperienceOrb-merging-stacking-API-and-fixes.patch index 67ca8599bb15..76581b9350b6 100644 --- a/patches/server/0352-ExperienceOrb-merging-stacking-API-and-fixes.patch +++ b/patches/server/0352-ExperienceOrb-merging-stacking-API-and-fixes.patch @@ -77,7 +77,7 @@ index 5a7d314ec0562e472f5dc45924a7b24841cff126..650e4a01cecc4cc08e7ff9ebcc4c3670 public java.util.UUID getTriggerEntityId() { return getHandle().triggerEntityId; diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 0b9c96105bea9a0d1af17b7ecf4479d3596faa80..b40117e9940ab493ea4a945dbd9754a38b1159b9 100644 +index 6b094f8bdf1f25d5c2e108eb88d95aed4a41f6f3..cb708c5ce9e81005d638f03e398e7f0f2b9f7521 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -712,15 +712,29 @@ public class CraftEventFactory { diff --git a/patches/server/0379-Add-PrepareResultEvent.patch b/patches/server/0379-Add-PrepareResultEvent.patch index 9fb630a728a6..9a7c7568127c 100644 --- a/patches/server/0379-Add-PrepareResultEvent.patch +++ b/patches/server/0379-Add-PrepareResultEvent.patch @@ -94,10 +94,10 @@ index 0fb0ee5b22dc96c48d68e4391fd71b03d4e799f0..97837d1baf6b929a50e5562ef466050e private void setupRecipeList(ItemStack stack) { diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index b40117e9940ab493ea4a945dbd9754a38b1159b9..62f4fd6553ab0310e2c0dde1d917c63679365798 100644 +index cb708c5ce9e81005d638f03e398e7f0f2b9f7521..876644a1b5d119c3420e3042b576e34878797d67 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1679,6 +1679,12 @@ populateFields(victim, event); // Paper - make cancellable +@@ -1679,6 +1679,12 @@ public class CraftEventFactory { } public static PrepareAnvilEvent callPrepareAnvilEvent(AnvilView view, ItemStack item) { @@ -110,7 +110,7 @@ index b40117e9940ab493ea4a945dbd9754a38b1159b9..62f4fd6553ab0310e2c0dde1d917c636 PrepareAnvilEvent event = new PrepareAnvilEvent(view, CraftItemStack.asCraftMirror(item).clone()); event.getView().getPlayer().getServer().getPluginManager().callEvent(event); event.getInventory().setItem(2, event.getResult()); -@@ -1686,6 +1692,12 @@ populateFields(victim, event); // Paper - make cancellable +@@ -1686,6 +1692,12 @@ public class CraftEventFactory { } public static PrepareGrindstoneEvent callPrepareGrindstoneEvent(InventoryView view, ItemStack item) { @@ -123,7 +123,7 @@ index b40117e9940ab493ea4a945dbd9754a38b1159b9..62f4fd6553ab0310e2c0dde1d917c636 PrepareGrindstoneEvent event = new PrepareGrindstoneEvent(view, CraftItemStack.asCraftMirror(item).clone()); event.getView().getPlayer().getServer().getPluginManager().callEvent(event); event.getInventory().setItem(2, event.getResult()); -@@ -1693,12 +1705,39 @@ populateFields(victim, event); // Paper - make cancellable +@@ -1693,12 +1705,39 @@ public class CraftEventFactory { } public static PrepareSmithingEvent callPrepareSmithingEvent(InventoryView view, ItemStack item) { diff --git a/patches/server/0396-Add-BellRingEvent.patch b/patches/server/0396-Add-BellRingEvent.patch index 9c5162d578d0..32c63afd3744 100644 --- a/patches/server/0396-Add-BellRingEvent.patch +++ b/patches/server/0396-Add-BellRingEvent.patch @@ -7,7 +7,7 @@ Add a new event, BellRingEvent, to trigger whenever a player rings a village bell. Passes along the bell block and the player who rang it. diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 62f4fd6553ab0310e2c0dde1d917c63679365798..c7d78f54694b464696c0f1edd0b135d1d5bcde3e 100644 +index 876644a1b5d119c3420e3042b576e34878797d67..629936b6266dadcac9d9a1fd584e7ba6b67a0002 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -377,10 +377,11 @@ public class CraftEventFactory { diff --git a/patches/server/0443-Add-OBSTRUCTED-reason-to-BedEnterResult.patch b/patches/server/0443-Add-OBSTRUCTED-reason-to-BedEnterResult.patch index dde19c16cae0..c118aa890ed1 100644 --- a/patches/server/0443-Add-OBSTRUCTED-reason-to-BedEnterResult.patch +++ b/patches/server/0443-Add-OBSTRUCTED-reason-to-BedEnterResult.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add OBSTRUCTED reason to BedEnterResult diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index c7d78f54694b464696c0f1edd0b135d1d5bcde3e..9e3037ac041da5ec2e15a4cd475ec52fee591aac 100644 +index 629936b6266dadcac9d9a1fd584e7ba6b67a0002..9f97216a4be562acb69281f4a638dad139c6bc7d 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -312,6 +312,10 @@ public class CraftEventFactory { diff --git a/patches/server/0459-Add-BlockFailedDispenseEvent.patch b/patches/server/0459-Add-BlockFailedDispenseEvent.patch index 67fe311615ab..ee65c26c996d 100644 --- a/patches/server/0459-Add-BlockFailedDispenseEvent.patch +++ b/patches/server/0459-Add-BlockFailedDispenseEvent.patch @@ -32,10 +32,10 @@ index a08e8571f3a83afc80c2f1758a9029cd28ed6947..91b514967405115f22edf4255775361a } else { ItemStack itemstack = tileentitydispenser.getItem(i); diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 9e3037ac041da5ec2e15a4cd475ec52fee591aac..4d7ac961b35b747ba5369ec1bdb6a9d78281f5d7 100644 +index 9f97216a4be562acb69281f4a638dad139c6bc7d..1e918ef9296e5127b78a7eb0460225448982772e 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -2125,4 +2125,12 @@ populateFields(victim, event); // Paper - make cancellable +@@ -2125,4 +2125,12 @@ public class CraftEventFactory { return org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getPotion()); } // Paper end - WitchReadyPotionEvent diff --git a/patches/server/0473-Add-BlockPreDispenseEvent.patch b/patches/server/0473-Add-BlockPreDispenseEvent.patch index ae0c60a3b459..d280bd07f124 100644 --- a/patches/server/0473-Add-BlockPreDispenseEvent.patch +++ b/patches/server/0473-Add-BlockPreDispenseEvent.patch @@ -29,10 +29,10 @@ index 91b514967405115f22edf4255775361a672e5c2f..ddecf443df3679e3098eb54edd19585a } else { // CraftBukkit start - Fire event when pushing items into other inventories diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 4d7ac961b35b747ba5369ec1bdb6a9d78281f5d7..12aeb922c8a53eff9ba8e2c765d87df497611362 100644 +index 1e918ef9296e5127b78a7eb0460225448982772e..a25e814978a2f19fa6fe74aaa5c529a524240d71 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -2132,5 +2132,11 @@ populateFields(victim, event); // Paper - make cancellable +@@ -2132,5 +2132,11 @@ public class CraftEventFactory { io.papermc.paper.event.block.BlockFailedDispenseEvent event = new io.papermc.paper.event.block.BlockFailedDispenseEvent(block); return event.callEvent(); } diff --git a/patches/server/0477-Expand-EntityUnleashEvent.patch b/patches/server/0477-Expand-EntityUnleashEvent.patch index fceff6d94abc..88cfdc582eb1 100644 --- a/patches/server/0477-Expand-EntityUnleashEvent.patch +++ b/patches/server/0477-Expand-EntityUnleashEvent.patch @@ -139,10 +139,10 @@ index 4b44830ef5d08887274ebb39e2780606fe3a76b4..d3a7953a3f42a0020342845e9107c699 flag1 = true; } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 12aeb922c8a53eff9ba8e2c765d87df497611362..cee72eb02ebba4f50a117876351b8f516ba12057 100644 +index a25e814978a2f19fa6fe74aaa5c529a524240d71..5064dd8c97f45f0c4e2d1402500e7cf67a263dfa 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1596,8 +1596,10 @@ populateFields(victim, event); // Paper - make cancellable +@@ -1596,8 +1596,10 @@ public class CraftEventFactory { Bukkit.getPluginManager().callEvent(new PlayerRecipeBookSettingsChangeEvent(player.getBukkitEntity(), bukkitType, open, filter)); } diff --git a/patches/server/0483-Allow-adding-items-to-BlockDropItemEvent.patch b/patches/server/0483-Allow-adding-items-to-BlockDropItemEvent.patch index 4f9534949b80..5fe7914ae000 100644 --- a/patches/server/0483-Allow-adding-items-to-BlockDropItemEvent.patch +++ b/patches/server/0483-Allow-adding-items-to-BlockDropItemEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Allow adding items to BlockDropItemEvent diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index cee72eb02ebba4f50a117876351b8f516ba12057..1ce637a2b80dfc5c3da20f7bd95b97f4718a07d4 100644 +index 5064dd8c97f45f0c4e2d1402500e7cf67a263dfa..a5c9ff3a2f06e7207ae4fcaf69be8bd0c874d4e2 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -461,13 +461,30 @@ public class CraftEventFactory { diff --git a/patches/server/0550-Fix-potions-splash-events.patch b/patches/server/0550-Fix-potions-splash-events.patch index d71c03a5dc23..7d09edfbeba4 100644 --- a/patches/server/0550-Fix-potions-splash-events.patch +++ b/patches/server/0550-Fix-potions-splash-events.patch @@ -143,7 +143,7 @@ index 224e768963d6969f25608065d37ad72d82acda68..d6ac07d9d5ee0430a1d91b7084b378aa public boolean isLingering() { diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 1ce637a2b80dfc5c3da20f7bd95b97f4718a07d4..83648509a5b90daa4b072650cbc3215b64659a86 100644 +index a5c9ff3a2f06e7207ae4fcaf69be8bd0c874d4e2..e6b22f24eba945863bb625b40319e6874ff25534 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -884,6 +884,32 @@ public class CraftEventFactory { diff --git a/patches/server/0584-Add-critical-damage-API.patch b/patches/server/0584-Add-critical-damage-API.patch index 66ddf0b45881..3ce4bba7c0f8 100644 --- a/patches/server/0584-Add-critical-damage-API.patch +++ b/patches/server/0584-Add-critical-damage-API.patch @@ -61,10 +61,10 @@ index bc167c21f82ad09952f6cdbf1016523062890f8b..44bcb1117cfa4d66c500011489ae193a int k = entity.getRemainingFireTicks(); diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 83648509a5b90daa4b072650cbc3215b64659a86..376563ea6990aef558a34e4f5889125412b734df 100644 +index e6b22f24eba945863bb625b40319e6874ff25534..a9ba62a9d605234d993b6e5330889795099af391 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1078,7 +1078,7 @@ populateFields(victim, event); // Paper - make cancellable +@@ -1078,7 +1078,7 @@ public class CraftEventFactory { return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled); } DamageCause damageCause = (damager.getBukkitEntity() instanceof org.bukkit.entity.TNTPrimed) ? DamageCause.BLOCK_EXPLOSION : DamageCause.ENTITY_EXPLOSION; @@ -73,7 +73,7 @@ index 83648509a5b90daa4b072650cbc3215b64659a86..376563ea6990aef558a34e4f58891254 } else if (damager != null || source.getDirectEntity() != null) { DamageCause cause = (source.isSweep()) ? DamageCause.ENTITY_SWEEP_ATTACK : DamageCause.ENTITY_ATTACK; -@@ -1104,7 +1104,7 @@ populateFields(victim, event); // Paper - make cancellable +@@ -1104,7 +1104,7 @@ public class CraftEventFactory { cause = DamageCause.MAGIC; } @@ -82,7 +82,7 @@ index 83648509a5b90daa4b072650cbc3215b64659a86..376563ea6990aef558a34e4f58891254 } else if (source.is(DamageTypes.FELL_OUT_OF_WORLD)) { return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.VOID, bukkitDamageSource, modifiers, modifierFunctions, cancelled); } else if (source.is(DamageTypes.LAVA)) { -@@ -1164,13 +1164,13 @@ populateFields(victim, event); // Paper - make cancellable +@@ -1164,13 +1164,13 @@ public class CraftEventFactory { cause = DamageCause.CUSTOM; } diff --git a/patches/server/0670-More-Projectile-API.patch b/patches/server/0670-More-Projectile-API.patch index db5d86dec1ff..b019ac7bd3ee 100644 --- a/patches/server/0670-More-Projectile-API.patch +++ b/patches/server/0670-More-Projectile-API.patch @@ -767,7 +767,7 @@ index e374b9f40eddca13b30855d25a2030f8df98138f..4fc893378fb0568ddcffc7593d66df6b // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 376563ea6990aef558a34e4f5889125412b734df..412f5e414745123535a275d5670b35fff5b1aaec 100644 +index a9ba62a9d605234d993b6e5330889795099af391..e0418c0c36aa99ea43dbf39fa176ddf8855e0568 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -841,19 +841,19 @@ public class CraftEventFactory { diff --git a/patches/server/0679-Fix-new-block-data-for-EntityChangeBlockEvent.patch b/patches/server/0679-Fix-new-block-data-for-EntityChangeBlockEvent.patch index 93f56e515722..0e8243655b45 100644 --- a/patches/server/0679-Fix-new-block-data-for-EntityChangeBlockEvent.patch +++ b/patches/server/0679-Fix-new-block-data-for-EntityChangeBlockEvent.patch @@ -196,10 +196,10 @@ index 674d710ff88db5eced9e017284d1b7ec7a4fe7cd..72320c6099a4b26235bab68570e7b7ef } // CraftBukkit end diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 412f5e414745123535a275d5670b35fff5b1aaec..f7e26e381c2a2fec70cc2df01a12e7dbeeab48cd 100644 +index e0418c0c36aa99ea43dbf39fa176ddf8855e0568..f54a4c263eeb4df40c72c20c3c480ce74718a718 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1378,11 +1378,11 @@ populateFields(victim, event); // Paper - make cancellable +@@ -1378,11 +1378,11 @@ public class CraftEventFactory { return event; } diff --git a/patches/server/0745-Correctly-handle-interactions-with-items-on-cooldown.patch b/patches/server/0745-Correctly-handle-interactions-with-items-on-cooldown.patch index fe489a8bd842..a86affadb8ee 100644 --- a/patches/server/0745-Correctly-handle-interactions-with-items-on-cooldown.patch +++ b/patches/server/0745-Correctly-handle-interactions-with-items-on-cooldown.patch @@ -30,7 +30,7 @@ index a706f0855fdf88cc9aece3ba00ef574b9cd8bd11..2aee9c2fbe38076317a3de7c3fdbd698 this.interactResult = event.useItemInHand() == Event.Result.DENY; this.interactPosition = blockposition.immutable(); diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index f7e26e381c2a2fec70cc2df01a12e7dbeeab48cd..cb05a94f2856a8bfb478bceb7c8712bc5e7ad5c2 100644 +index f54a4c263eeb4df40c72c20c3c480ce74718a718..ea0241de1a7ef64059cddcb43c41f56b91901897 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -555,6 +555,12 @@ public class CraftEventFactory { diff --git a/patches/server/0790-Add-EntityFertilizeEggEvent.patch b/patches/server/0790-Add-EntityFertilizeEggEvent.patch index 7b48ce0ca2f4..24b2e1a1af67 100644 --- a/patches/server/0790-Add-EntityFertilizeEggEvent.patch +++ b/patches/server/0790-Add-EntityFertilizeEggEvent.patch @@ -69,10 +69,10 @@ index 0395b120590552518a85f36a46b68532e936de49..7f70237a274fde0fb97880c1d4724615 this.playSound(SoundEvents.SNIFFER_EGG_PLOP, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 0.5F); } // Paper - Call EntityDropItemEvent diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index cb05a94f2856a8bfb478bceb7c8712bc5e7ad5c2..145a278a1b6d9e79c27136e84d8ccea8834c07bc 100644 +index ea0241de1a7ef64059cddcb43c41f56b91901897..d63b9c666cf6eb1de114c5c89867b8d233267c9e 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -2195,4 +2195,28 @@ populateFields(victim, event); // Paper - make cancellable +@@ -2195,4 +2195,28 @@ public class CraftEventFactory { return event.callEvent(); } // Paper end diff --git a/patches/server/0810-Expand-PlayerItemMendEvent.patch b/patches/server/0810-Expand-PlayerItemMendEvent.patch index 965dcf06033a..12d3c700eaab 100644 --- a/patches/server/0810-Expand-PlayerItemMendEvent.patch +++ b/patches/server/0810-Expand-PlayerItemMendEvent.patch @@ -49,10 +49,10 @@ index 76d8f0d390abf588886b42b6d2e3ed6f79a4d991..cdc53abb5572fa57b4ec98a694c5583a } } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 145a278a1b6d9e79c27136e84d8ccea8834c07bc..ac25a5c933b8748ca44ca02100058992b1aad358 100644 +index d63b9c666cf6eb1de114c5c89867b8d233267c9e..dd0d19faccbc49b5f9718e2df9f004bb17a9ef7e 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1284,10 +1284,10 @@ populateFields(victim, event); // Paper - make cancellable +@@ -1284,10 +1284,10 @@ public class CraftEventFactory { return event; } diff --git a/patches/server/0824-Call-missing-BlockDispenseEvent.patch b/patches/server/0824-Call-missing-BlockDispenseEvent.patch index 3e96187d8ea5..c8d68a1ed8c7 100644 --- a/patches/server/0824-Call-missing-BlockDispenseEvent.patch +++ b/patches/server/0824-Call-missing-BlockDispenseEvent.patch @@ -50,10 +50,10 @@ index 5793569ae8a088f21b0d8d6771a5099b1e88be09..f8f570a97789ab16e57774f233506a28 for (int k = 0; k < 5; ++k) { worldserver.sendParticles(ParticleTypes.SPLASH, (double) blockposition.getX() + worldserver.random.nextDouble(), (double) (blockposition.getY() + 1), (double) blockposition.getZ() + worldserver.random.nextDouble(), 1, 0.0D, 0.0D, 0.0D, 1.0D); diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index ac25a5c933b8748ca44ca02100058992b1aad358..22244f38bfee746f14c969de05bc028c934c6d6b 100644 +index dd0d19faccbc49b5f9718e2df9f004bb17a9ef7e..38c8f69dff0abe62fc405a9fbb29c80d45aa675f 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -2196,6 +2196,32 @@ populateFields(victim, event); // Paper - make cancellable +@@ -2196,6 +2196,32 @@ public class CraftEventFactory { } // Paper end diff --git a/patches/server/0833-ExperienceOrb-should-call-EntitySpawnEvent.patch b/patches/server/0833-ExperienceOrb-should-call-EntitySpawnEvent.patch index 8c098452ae3f..40dec00abbb1 100644 --- a/patches/server/0833-ExperienceOrb-should-call-EntitySpawnEvent.patch +++ b/patches/server/0833-ExperienceOrb-should-call-EntitySpawnEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] ExperienceOrb should call EntitySpawnEvent diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 22244f38bfee746f14c969de05bc028c934c6d6b..03afabc3ab4b264f84698627b79e58f502a8cea9 100644 +index 38c8f69dff0abe62fc405a9fbb29c80d45aa675f..449380c97dc332ecd43e308fcf110c9548930600 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -744,7 +744,8 @@ public class CraftEventFactory { diff --git a/patches/server/0857-Add-BlockFace-to-BlockDamageEvent.patch b/patches/server/0857-Add-BlockFace-to-BlockDamageEvent.patch index 55a882d6f380..2dcf331517fc 100644 --- a/patches/server/0857-Add-BlockFace-to-BlockDamageEvent.patch +++ b/patches/server/0857-Add-BlockFace-to-BlockDamageEvent.patch @@ -18,7 +18,7 @@ index 3bd4ab8161c29bb8df2ba496a4430393b6593476..0da6496c18341c01fc4551ead7e740a6 if (blockEvent.isCancelled()) { // Let the client know the block still exists diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 03afabc3ab4b264f84698627b79e58f502a8cea9..0bf830b51f078d1a642e1bbec6cd8b6e83501135 100644 +index 449380c97dc332ecd43e308fcf110c9548930600..c5f9d9aeeb1fc61edb0e57cef51f5f6371861000 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -660,13 +660,13 @@ public class CraftEventFactory { diff --git a/patches/unapplied/server/0867-More-DragonBattle-API.patch b/patches/server/0860-More-DragonBattle-API.patch similarity index 96% rename from patches/unapplied/server/0867-More-DragonBattle-API.patch rename to patches/server/0860-More-DragonBattle-API.patch index b7b58f6c9920..22ae7f0d40fc 100644 --- a/patches/unapplied/server/0867-More-DragonBattle-API.patch +++ b/patches/server/0860-More-DragonBattle-API.patch @@ -10,10 +10,10 @@ public net.minecraft.world.level.dimension.end.EndDragonFight respawnCrystals public net.minecraft.world.level.dimension.end.EndDragonFight spawnNewGateway(Lnet/minecraft/core/BlockPos;)V diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -index bf39f006efef529db697ed4dccbd1657a2673b79..4a0479fcff94bf6a1f239c1f694202345cdea1d4 100644 +index 3701cdc9f0e71d19a1090cf179bac9d5b8c4759a..7389cecae1a46d652170bf0cfc5e731a230d4e5a 100644 --- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java +++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -@@ -441,6 +441,24 @@ public class EndDragonFight { +@@ -442,6 +442,24 @@ public class EndDragonFight { this.gateways.clear(); } diff --git a/patches/unapplied/server/0868-Add-PlayerPickItemEvent.patch b/patches/server/0861-Add-PlayerPickItemEvent.patch similarity index 73% rename from patches/unapplied/server/0868-Add-PlayerPickItemEvent.patch rename to patches/server/0861-Add-PlayerPickItemEvent.patch index b2bfa9ea75fc..747014f9648b 100644 --- a/patches/unapplied/server/0868-Add-PlayerPickItemEvent.patch +++ b/patches/server/0861-Add-PlayerPickItemEvent.patch @@ -5,33 +5,33 @@ Subject: [PATCH] Add PlayerPickItemEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 7750660defe490bcdc24a3b4ad4f495c8a703fed..be0ce72bb493593a3d2eb7d7c37e3a650b7cc34b 100644 +index f21a5b9de17db9a094b22267b33bbffbf7ef8966..c6f51c3a1c0ff9bc6b6bfe3c7091be324a2129ed 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -935,8 +935,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -939,7 +939,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.disconnect(Component.literal("Invalid hotbar selection (Hacking?)"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause return; } - this.player.getInventory().pickSlot(packet.getSlot()); // Paper - Diff above if changed - // Paper end - validate pick item position + // Paper start - Add PlayerPickItemEvent ++ // this.player.getInventory().pickSlot(packet.getSlot()); // Paper - Diff above if changed - moved down + Player bukkitPlayer = this.player.getBukkitEntity(); + int targetSlot = this.player.getInventory().getSuitableHotbarSlot(); + int sourceSlot = packet.getSlot(); + + io.papermc.paper.event.player.PlayerPickItemEvent event = new io.papermc.paper.event.player.PlayerPickItemEvent(bukkitPlayer, targetSlot, sourceSlot); + if (!event.callEvent()) return; -+ -+ this.player.getInventory().pickSlot(event.getSourceSlot(), event.getTargetSlot()); + // Paper end - Add PlayerPickItemEvent - this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, 0, this.player.getInventory().selected, this.player.getInventory().getItem(this.player.getInventory().selected))); - this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, 0, packet.getSlot(), this.player.getInventory().getItem(packet.getSlot()))); - this.player.connection.send(new ClientboundSetCarriedItemPacket(this.player.getInventory().selected)); ++ ++ this.player.getInventory().pickSlot(event.getSourceSlot(), event.getTargetSlot()); // Paper - Add PlayerPickItemEvent + // Paper end - validate pick item position + int i = this.player.getInventory().selected; + diff --git a/src/main/java/net/minecraft/world/entity/player/Inventory.java b/src/main/java/net/minecraft/world/entity/player/Inventory.java -index 688ed0c32b05b0135b94ec05738cdc6ff8dcb677..a62e7354bf67a66bdf9cd7c8f5d2e8f6bcacc74f 100644 +index 8bdc2dd7e6b6824f4df5dce8bff5e87fa73d3d3a..aaff1592876ac4a967e4fd47e4b6619a17d57867 100644 --- a/src/main/java/net/minecraft/world/entity/player/Inventory.java +++ b/src/main/java/net/minecraft/world/entity/player/Inventory.java -@@ -171,7 +171,13 @@ public class Inventory implements Container, Nameable { +@@ -170,7 +170,13 @@ public class Inventory implements Container, Nameable { } public void pickSlot(int slot) { diff --git a/patches/unapplied/server/0869-Allow-trident-custom-damage.patch b/patches/server/0862-Allow-trident-custom-damage.patch similarity index 93% rename from patches/unapplied/server/0869-Allow-trident-custom-damage.patch rename to patches/server/0862-Allow-trident-custom-damage.patch index 95137bd7d5fe..ee7ac1a043fa 100644 --- a/patches/unapplied/server/0869-Allow-trident-custom-damage.patch +++ b/patches/server/0862-Allow-trident-custom-damage.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Allow trident custom damage diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java -index e45c3a9805d9fac1fabe6d891c817743acd9969e..44c733c5b2c3e9942f28e882ad72306a24459c2c 100644 +index 248410547de380e3195bbdc8b7b39cff908a0c32..322733266fdca8ce43434a8ffea304c51794bcbb 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java @@ -36,16 +36,19 @@ public class ThrownTrident extends AbstractArrow { @@ -28,7 +28,7 @@ index e45c3a9805d9fac1fabe6d891c817743acd9969e..44c733c5b2c3e9942f28e882ad72306a this.entityData.set(ThrownTrident.ID_LOYALTY, this.getLoyaltyFromItem(stack)); this.entityData.set(ThrownTrident.ID_FOIL, stack.hasFoil()); } -@@ -129,7 +132,7 @@ public class ThrownTrident extends AbstractArrow { +@@ -136,7 +139,7 @@ public class ThrownTrident extends AbstractArrow { @Override protected void onHitEntity(EntityHitResult entityHitResult) { Entity entity = entityHitResult.getEntity(); diff --git a/patches/unapplied/server/0870-Expose-hand-in-BlockCanBuildEvent.patch b/patches/server/0863-Expose-hand-in-BlockCanBuildEvent.patch similarity index 91% rename from patches/unapplied/server/0870-Expose-hand-in-BlockCanBuildEvent.patch rename to patches/server/0863-Expose-hand-in-BlockCanBuildEvent.patch index 4abc7e9fc5fc..f3ed54f3f988 100644 --- a/patches/unapplied/server/0870-Expose-hand-in-BlockCanBuildEvent.patch +++ b/patches/server/0863-Expose-hand-in-BlockCanBuildEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Expose hand in BlockCanBuildEvent diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java -index 7180996027f70aef7afe32fb2adfce6431429401..fc7d978f9e57814a933b9cb725c3af1e7d403795 100644 +index d59120f0304823361cc4112f5583323945df4229..986b14a7b7c98641201ece649df09e4b8279a36c 100644 --- a/src/main/java/net/minecraft/world/item/BlockItem.java +++ b/src/main/java/net/minecraft/world/item/BlockItem.java -@@ -191,7 +191,7 @@ public class BlockItem extends Item { +@@ -185,7 +185,7 @@ public class BlockItem extends Item { boolean defaultReturn = (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && world.checkEntityCollision(state, entityhuman, voxelshapecollision, context.getClickedPos(), true); // Paper - Cancel hit for vanished players org.bukkit.entity.Player player = (context.getPlayer() instanceof ServerPlayer) ? (org.bukkit.entity.Player) context.getPlayer().getBukkitEntity() : null; @@ -18,7 +18,7 @@ index 7180996027f70aef7afe32fb2adfce6431429401..fc7d978f9e57814a933b9cb725c3af1e return event.isBuildable(); diff --git a/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java b/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java -index 39b8b3675ac58409e05fac07e07c8016c5280d81..f8f909ebdad5e96379e8bd8c610164ef0697368e 100644 +index 81915cec3ec372d1ff59160b96399b8c6e693eba..1451b25cedb7a8f01c046c8e1f8c6853aca42283 100644 --- a/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java +++ b/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java @@ -59,7 +59,7 @@ public class StandingAndWallBlockItem extends BlockItem { diff --git a/patches/unapplied/server/0871-Optimize-nearest-structure-border-iteration.patch b/patches/server/0864-Optimize-nearest-structure-border-iteration.patch similarity index 95% rename from patches/unapplied/server/0871-Optimize-nearest-structure-border-iteration.patch rename to patches/server/0864-Optimize-nearest-structure-border-iteration.patch index df5f60c52cbd..f16f98ea9bc3 100644 --- a/patches/unapplied/server/0871-Optimize-nearest-structure-border-iteration.patch +++ b/patches/server/0864-Optimize-nearest-structure-border-iteration.patch @@ -14,7 +14,7 @@ ensure that the returned found structure (which may for example be a buried treasure that will be marked on a treasure map) is the same as in vanilla. diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index 102de569415ef011dacdca9a6ea8134d0ef62454..29697fad32dad3377eebc82d280ba48d3c1ad516 100644 +index 906f56d07c26ef3c2dc1a3b62e9349dd91a37742..4cbc68d8e950f8d7c8b00535b82e916964c88ce0 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -265,12 +265,15 @@ public abstract class ChunkGenerator { diff --git a/patches/unapplied/server/0872-Implement-OfflinePlayer-isConnected.patch b/patches/server/0865-Implement-OfflinePlayer-isConnected.patch similarity index 90% rename from patches/unapplied/server/0872-Implement-OfflinePlayer-isConnected.patch rename to patches/server/0865-Implement-OfflinePlayer-isConnected.patch index 199101506f46..67483270a7b5 100644 --- a/patches/unapplied/server/0872-Implement-OfflinePlayer-isConnected.patch +++ b/patches/server/0865-Implement-OfflinePlayer-isConnected.patch @@ -23,10 +23,10 @@ index 2c2c4db31a746b4eb853dc04c6b3e5631bbfa034..4f4e3ee18d586f61706504218cddc06a public String getName() { Player player = this.getPlayer(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index a3912d4de96a6bb2b9b3977705fa3facb891f73d..a1b870fb3d1fd5d209474c47bf523d0d5d58ce39 100644 +index b6093a1bbd8176cde85ef034373ae71f9dd8f1c1..3f55fbf41a85e71a62628db18fde4afb3dd923c3 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -256,6 +256,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -257,6 +257,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.server.getPlayer(this.getUniqueId()) != null; } diff --git a/patches/unapplied/server/0873-Fix-slot-desync.patch b/patches/server/0866-Fix-slot-desync.patch similarity index 84% rename from patches/unapplied/server/0873-Fix-slot-desync.patch rename to patches/server/0866-Fix-slot-desync.patch index aa5a0249855f..449fa59ed08b 100644 --- a/patches/unapplied/server/0873-Fix-slot-desync.patch +++ b/patches/server/0866-Fix-slot-desync.patch @@ -10,10 +10,10 @@ Co-authored-by: Minecrell Co-authored-by: Newwind diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 7270b6fa96bae937663c0fea77887e21fbd0eb57..530728cd4b258444f6efe064903b521f4b23cd04 100644 +index 1a7d2ade0e85dd5e6cd6c9202e3277cc2fa43d4a..37defbc0674e67a26e5a9aebb811310ef12878ee 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -400,6 +400,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -460,6 +460,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { // Use method to resend items in hands in case of client desync, because the item use got cancelled. // For example, when cancelling the leash event @@ -22,10 +22,10 @@ index 7270b6fa96bae937663c0fea77887e21fbd0eb57..530728cd4b258444f6efe064903b521f this.containerMenu.findSlot(this.getInventory(), this.getInventory().selected).ifPresent(s -> { this.containerSynchronizer.sendSlotChange(this.containerMenu, s, this.getMainHandItem()); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index be0ce72bb493593a3d2eb7d7c37e3a650b7cc34b..0ffa95542a0ed49a3f83700841f7c76c0717ae22 100644 +index c6f51c3a1c0ff9bc6b6bfe3c7091be324a2129ed..fe23c77efae996dfa6c3530c11e51202bccca378 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2729,10 +2729,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2741,10 +2741,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Refresh the current entity metadata entity.refreshEntityData(ServerGamePacketListenerImpl.this.player); // SPIGOT-7136 - Allays @@ -40,10 +40,10 @@ index be0ce72bb493593a3d2eb7d7c37e3a650b7cc34b..0ffa95542a0ed49a3f83700841f7c76c if (event.isCancelled()) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 84d283cd637b5c84a8682acec503b0e3831d1684..bd0e205c760414784ae483452fd02292939dcb5c 100644 +index a8a5b28d95f7c3ce944f51993dd0c0eb98e3c550..ba57deb4e10bba180429cca4d8c864ab869065c7 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -2638,8 +2638,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2752,8 +2752,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess if (!this.level().isClientSide()) { // CraftBukkit start - fire PlayerLeashEntityEvent if (CraftEventFactory.callPlayerLeashEntityEvent(this, player, player, hand).isCancelled()) { @@ -55,7 +55,7 @@ index 84d283cd637b5c84a8682acec503b0e3831d1684..bd0e205c760414784ae483452fd02292 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/animal/Cow.java b/src/main/java/net/minecraft/world/entity/animal/Cow.java -index 5a7b1be351834a6b8889b1380cede1be025cb302..e336934f37075a827843e4b1bb2b6b660d2c60c9 100644 +index d99760f943846a1cfe5d0ec97313f453004feb98..3e00bbff266fc71b07014e7e047d77b7f809239f 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Cow.java +++ b/src/main/java/net/minecraft/world/entity/animal/Cow.java @@ -101,6 +101,7 @@ public class Cow extends Animal { @@ -67,10 +67,10 @@ index 5a7b1be351834a6b8889b1380cede1be025cb302..e336934f37075a827843e4b1bb2b6b66 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java -index 02e49c7ae5e120302b6479cf3e3934b9217eebf0..376bcbc189008464f4d518c1e07643431ba96306 100644 +index f745a554b9b84a53d9bd942ca9908153fb0a668c..ec3edd2eefc398dac9058e082c52a98dc48db36d 100644 --- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java +++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java -@@ -234,6 +234,7 @@ public class Goat extends Animal { +@@ -238,6 +238,7 @@ public class Goat extends Animal { PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level(), player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand); if (event.isCancelled()) { @@ -79,7 +79,7 @@ index 02e49c7ae5e120302b6479cf3e3934b9217eebf0..376bcbc189008464f4d518c1e0764343 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/item/ArmorStandItem.java b/src/main/java/net/minecraft/world/item/ArmorStandItem.java -index 1634a7d5ff06583408cf2f02f2b5f90931b1e02a..066a6e5ed2632a55324ec0d10f2f8a6bf3f30a0f 100644 +index 15c7c2417db1661c77c35455b59a77b1d1055858..cb4baebe22eeab17aed67a5ecc506b932fe2230b 100644 --- a/src/main/java/net/minecraft/world/item/ArmorStandItem.java +++ b/src/main/java/net/minecraft/world/item/ArmorStandItem.java @@ -55,6 +55,7 @@ public class ArmorStandItem extends Item { @@ -91,10 +91,10 @@ index 1634a7d5ff06583408cf2f02f2b5f90931b1e02a..066a6e5ed2632a55324ec0d10f2f8a6b } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java -index fc7d978f9e57814a933b9cb725c3af1e7d403795..96fb69ec6db2e7c8c728435f0c537b076259b2fb 100644 +index 986b14a7b7c98641201ece649df09e4b8279a36c..c816c935ecc74a811ffdffbe6ded73c06e92324a 100644 --- a/src/main/java/net/minecraft/world/item/BlockItem.java +++ b/src/main/java/net/minecraft/world/item/BlockItem.java -@@ -114,7 +114,7 @@ public class BlockItem extends Item { +@@ -108,7 +108,7 @@ public class BlockItem extends Item { if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) { blockstate.update(true, false); @@ -104,7 +104,7 @@ index fc7d978f9e57814a933b9cb725c3af1e7d403795..96fb69ec6db2e7c8c728435f0c537b07 } return InteractionResult.FAIL; diff --git a/src/main/java/net/minecraft/world/item/EndCrystalItem.java b/src/main/java/net/minecraft/world/item/EndCrystalItem.java -index f9a940cdff3983d9d4de46bd5ddc1905f9254dcf..273bb38f14b8af08d123e02742d365fb5d91cdf5 100644 +index 5311e653dceb085fcebb8ac5090d84e97e573e62..48317c7436445a7acff9103bac1de558c42f31cc 100644 --- a/src/main/java/net/minecraft/world/item/EndCrystalItem.java +++ b/src/main/java/net/minecraft/world/item/EndCrystalItem.java @@ -49,6 +49,7 @@ public class EndCrystalItem extends Item { @@ -116,14 +116,14 @@ index f9a940cdff3983d9d4de46bd5ddc1905f9254dcf..273bb38f14b8af08d123e02742d365fb } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/item/MinecartItem.java b/src/main/java/net/minecraft/world/item/MinecartItem.java -index 66074445d3908b9bb1c8d70e1e27d057720ec8e5..d524fcc191cb95d6ec7f12ae7fceeb8077bb08fc 100644 +index 04eb25b05681a72968917b0b59c030d6629776fa..7153d9ed12276a0f2d8b8a17c79734aa25ed1fa5 100644 --- a/src/main/java/net/minecraft/world/item/MinecartItem.java +++ b/src/main/java/net/minecraft/world/item/MinecartItem.java -@@ -137,6 +137,7 @@ public class MinecartItem extends Item { +@@ -69,6 +69,7 @@ public class MinecartItem extends Item { - // CraftBukkit start - if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, entityminecartabstract).isCancelled()) { + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, entityminecartabstract).isCancelled()) { + if (context.getPlayer() != null) context.getPlayer().containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync - return InteractionResult.FAIL; - } - // CraftBukkit end + return InteractionResult.FAIL; + } + // CraftBukkit end diff --git a/patches/unapplied/server/0874-Add-titleOverride-to-InventoryOpenEvent.patch b/patches/server/0867-Add-titleOverride-to-InventoryOpenEvent.patch similarity index 94% rename from patches/unapplied/server/0874-Add-titleOverride-to-InventoryOpenEvent.patch rename to patches/server/0867-Add-titleOverride-to-InventoryOpenEvent.patch index ee1767993470..05e37009fdda 100644 --- a/patches/unapplied/server/0874-Add-titleOverride-to-InventoryOpenEvent.patch +++ b/patches/server/0867-Add-titleOverride-to-InventoryOpenEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add titleOverride to InventoryOpenEvent diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 530728cd4b258444f6efe064903b521f4b23cd04..b65d816bb9feb18ecf74e10e9728c302e5657587 100644 +index 37defbc0674e67a26e5a9aebb811310ef12878ee..b0b4bede6f25b8a0de54d954c7010021f87aadc3 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1656,12 +1656,17 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1924,12 +1924,17 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.nextContainerCounter(); AbstractContainerMenu container = factory.createMenu(this.containerCounter, this.getInventory(), this); @@ -27,7 +27,7 @@ index 530728cd4b258444f6efe064903b521f4b23cd04..b65d816bb9feb18ecf74e10e9728c302 if (container == null && !cancelled) { // Let pre-cancelled events fall through // SPIGOT-5263 - close chest if cancelled if (factory instanceof Container) { -@@ -1683,7 +1688,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1951,7 +1956,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } else { // CraftBukkit start this.containerMenu = container; @@ -37,7 +37,7 @@ index 530728cd4b258444f6efe064903b521f4b23cd04..b65d816bb9feb18ecf74e10e9728c302 this.initMenu(container); return OptionalInt.of(this.containerCounter); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index b782cc64426a058881947ed62316c1cb8d332037..7dcfb45c24d7743956be514c7d554e06aac77b3e 100644 +index 7dddf4dd090fcd9e86b147d7e4ddeaa99800713e..4312290ad970f71e1dc25b707ab312c597a481a9 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -366,12 +366,16 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @@ -79,10 +79,10 @@ index b782cc64426a058881947ed62316c1cb8d332037..7dcfb45c24d7743956be514c7d554e06 if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper - Prevent opening inventories when frozen player.containerMenu = container; diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 6b241ec85f360ec79f18b911175d7092861024a4..2690c471b819f8308f6db44150025dfa323d4e0c 100644 +index c5f9d9aeeb1fc61edb0e57cef51f5f6371861000..dbef230ae88ee1bfbc20ba53b534434c3ccac985 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1403,10 +1403,21 @@ public class CraftEventFactory { +@@ -1401,10 +1401,21 @@ public class CraftEventFactory { } public static AbstractContainerMenu callInventoryOpenEvent(ServerPlayer player, AbstractContainerMenu container) { @@ -105,7 +105,7 @@ index 6b241ec85f360ec79f18b911175d7092861024a4..2690c471b819f8308f6db44150025dfa if (player.containerMenu != player.inventoryMenu) { // fire INVENTORY_CLOSE if one already open player.connection.handleContainerClose(new ServerboundContainerClosePacket(player.containerMenu.containerId), InventoryCloseEvent.Reason.OPEN_NEW); // Paper - Inventory close reason } -@@ -1421,10 +1432,10 @@ public class CraftEventFactory { +@@ -1419,10 +1430,10 @@ public class CraftEventFactory { if (event.isCancelled()) { container.transferTo(player.containerMenu, craftPlayer); diff --git a/patches/unapplied/server/0875-Configure-sniffer-egg-hatch-time.patch b/patches/server/0868-Configure-sniffer-egg-hatch-time.patch similarity index 88% rename from patches/unapplied/server/0875-Configure-sniffer-egg-hatch-time.patch rename to patches/server/0868-Configure-sniffer-egg-hatch-time.patch index 7def55b1f7f4..e39971b614a0 100644 --- a/patches/unapplied/server/0875-Configure-sniffer-egg-hatch-time.patch +++ b/patches/server/0868-Configure-sniffer-egg-hatch-time.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Configure sniffer egg hatch time diff --git a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java -index b943384eb6a4612993556036f0d3beec6939a559..ffe5e14cf8190774c8935513ebeb041eda81f912 100644 +index c6b7cfd78bc0c4cb64eada507876c293541890f4..ec04fcc23c86d34a6dc1eaadda7f9d876f3d8ffe 100644 --- a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java -@@ -62,7 +62,7 @@ public class SnifferEggBlock extends Block { +@@ -63,7 +63,7 @@ public class SnifferEggBlock extends Block { // Paper start - Call BlockFadeEvent private void rescheduleTick(ServerLevel world, BlockPos pos) { @@ -17,7 +17,7 @@ index b943384eb6a4612993556036f0d3beec6939a559..ffe5e14cf8190774c8935513ebeb041e world.scheduleTick(pos, this, (baseDelay / 3) + world.random.nextInt(RANDOM_HATCH_OFFSET_TICKS)); // reschedule to avoid being stuck here and behave like the other calls (see #onPlace) } -@@ -104,7 +104,7 @@ public class SnifferEggBlock extends Block { +@@ -105,7 +105,7 @@ public class SnifferEggBlock extends Block { world.levelEvent(3009, pos, 0); } diff --git a/patches/unapplied/server/0876-Do-crystal-portal-proximity-check-before-entity-look.patch b/patches/server/0869-Do-crystal-portal-proximity-check-before-entity-look.patch similarity index 93% rename from patches/unapplied/server/0876-Do-crystal-portal-proximity-check-before-entity-look.patch rename to patches/server/0869-Do-crystal-portal-proximity-check-before-entity-look.patch index ee3855f2b8b4..c2fcf0ba55a2 100644 --- a/patches/unapplied/server/0876-Do-crystal-portal-proximity-check-before-entity-look.patch +++ b/patches/server/0869-Do-crystal-portal-proximity-check-before-entity-look.patch @@ -12,7 +12,7 @@ some servers that have players placing end crystals as a style of combat. The very cheap distance check prevents running the entity lookup every time. diff --git a/src/main/java/net/minecraft/world/item/EndCrystalItem.java b/src/main/java/net/minecraft/world/item/EndCrystalItem.java -index 273bb38f14b8af08d123e02742d365fb5d91cdf5..5f51e64cb0611a4ba6bdcdcacbcba1063a7f3a5c 100644 +index 48317c7436445a7acff9103bac1de558c42f31cc..b62db8c7c8c57e43869ee239ebf4b02f112355d9 100644 --- a/src/main/java/net/minecraft/world/item/EndCrystalItem.java +++ b/src/main/java/net/minecraft/world/item/EndCrystalItem.java @@ -30,7 +30,7 @@ public class EndCrystalItem extends Item { @@ -34,10 +34,10 @@ index 273bb38f14b8af08d123e02742d365fb5d91cdf5..5f51e64cb0611a4ba6bdcdcacbcba106 } diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -index 4a0479fcff94bf6a1f239c1f694202345cdea1d4..84300f2f7b7be4f5281edd8e263646dbcbb3ba07 100644 +index 7389cecae1a46d652170bf0cfc5e731a230d4e5a..c90ad702df2fe5c796d041afc04523a0318d9565 100644 --- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java +++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -@@ -560,6 +560,12 @@ public class EndDragonFight { +@@ -563,6 +563,12 @@ public class EndDragonFight { } public boolean tryRespawn() { // CraftBukkit - return boolean @@ -50,7 +50,7 @@ index 4a0479fcff94bf6a1f239c1f694202345cdea1d4..84300f2f7b7be4f5281edd8e263646db if (this.dragonKilled && this.respawnStage == null) { BlockPos blockposition = this.portalLocation; -@@ -577,6 +583,22 @@ public class EndDragonFight { +@@ -580,6 +586,22 @@ public class EndDragonFight { blockposition = this.portalLocation; } diff --git a/patches/unapplied/server/0877-Skip-POI-finding-if-stuck-in-vehicle.patch b/patches/server/0870-Skip-POI-finding-if-stuck-in-vehicle.patch similarity index 100% rename from patches/unapplied/server/0877-Skip-POI-finding-if-stuck-in-vehicle.patch rename to patches/server/0870-Skip-POI-finding-if-stuck-in-vehicle.patch diff --git a/patches/unapplied/server/0878-Add-slot-sanity-checks-in-container-clicks.patch b/patches/server/0871-Add-slot-sanity-checks-in-container-clicks.patch similarity index 87% rename from patches/unapplied/server/0878-Add-slot-sanity-checks-in-container-clicks.patch rename to patches/server/0871-Add-slot-sanity-checks-in-container-clicks.patch index 3be07bcfa2b4..e09447a233dc 100644 --- a/patches/unapplied/server/0878-Add-slot-sanity-checks-in-container-clicks.patch +++ b/patches/server/0871-Add-slot-sanity-checks-in-container-clicks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add slot sanity checks in container clicks diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 0ffa95542a0ed49a3f83700841f7c76c0717ae22..d377804026f3f5cf80a623228d24e09c56ef0dae 100644 +index fe23c77efae996dfa6c3530c11e51202bccca378..8b5be8870a0077b82e345027b323b8b4f448f231 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2986,6 +2986,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3003,6 +3003,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl break; case SWAP: if ((packet.getButtonNum() >= 0 && packet.getButtonNum() < 9) || packet.getButtonNum() == 40) { @@ -22,10 +22,10 @@ index 0ffa95542a0ed49a3f83700841f7c76c0717ae22..d377804026f3f5cf80a623228d24e09c Slot clickedSlot = this.player.containerMenu.getSlot(packet.getSlotNum()); if (clickedSlot.mayPickup(this.player)) { diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -index 0e380151b038e2133013eb7d73621cf247b5b954..afd8f48bd41d2cac413c292f7988c903da1dc700 100644 +index fc23e2dc42e907d5f8dc134a06102cc3e7fde515..22dc1569aabe69f139d9682ceb81311993706cb8 100644 --- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -@@ -423,6 +423,7 @@ public abstract class AbstractContainerMenu { +@@ -460,6 +460,7 @@ public abstract class AbstractContainerMenu { this.resetQuickCraft(); } } else if (this.quickcraftStatus == 1) { @@ -33,7 +33,7 @@ index 0e380151b038e2133013eb7d73621cf247b5b954..afd8f48bd41d2cac413c292f7988c903 slot = (Slot) this.slots.get(slotIndex); itemstack = this.getCarried(); if (AbstractContainerMenu.canItemQuickReplace(slot, itemstack, true) && slot.mayPlace(itemstack) && (this.quickcraftType == 2 || itemstack.getCount() > this.quickcraftSlots.size()) && this.canDragTo(slot)) { -@@ -597,6 +598,7 @@ public abstract class AbstractContainerMenu { +@@ -634,6 +635,7 @@ public abstract class AbstractContainerMenu { int j2; if (actionType == ClickType.SWAP && (button >= 0 && button < 9 || button == 40)) { diff --git a/patches/unapplied/server/0879-Call-BlockRedstoneEvents-for-lecterns.patch b/patches/server/0872-Call-BlockRedstoneEvents-for-lecterns.patch similarity index 89% rename from patches/unapplied/server/0879-Call-BlockRedstoneEvents-for-lecterns.patch rename to patches/server/0872-Call-BlockRedstoneEvents-for-lecterns.patch index 2c76754071e4..7726626d78f7 100644 --- a/patches/unapplied/server/0879-Call-BlockRedstoneEvents-for-lecterns.patch +++ b/patches/server/0872-Call-BlockRedstoneEvents-for-lecterns.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Call BlockRedstoneEvents for lecterns diff --git a/src/main/java/net/minecraft/world/level/block/LecternBlock.java b/src/main/java/net/minecraft/world/level/block/LecternBlock.java -index 751ff3d51f8ae57f847c3acf7a7cd663a6ae1c68..0c52e1f8bc233bb66e53f4c69e1d8757382bbe81 100644 +index 44d322d26187bd7528799069d0e08dbf571a57f3..3537795720be76483579fc50715914974c97c9c4 100644 --- a/src/main/java/net/minecraft/world/level/block/LecternBlock.java +++ b/src/main/java/net/minecraft/world/level/block/LecternBlock.java -@@ -179,6 +179,16 @@ public class LecternBlock extends BaseEntityBlock { +@@ -180,6 +180,16 @@ public class LecternBlock extends BaseEntityBlock { } private static void changePowered(Level world, BlockPos pos, BlockState state, boolean powered) { diff --git a/patches/unapplied/server/0880-Allow-proper-checking-of-empty-item-stacks.patch b/patches/server/0873-Allow-proper-checking-of-empty-item-stacks.patch similarity index 89% rename from patches/unapplied/server/0880-Allow-proper-checking-of-empty-item-stacks.patch rename to patches/server/0873-Allow-proper-checking-of-empty-item-stacks.patch index c578a2c3c2b5..85819379c183 100644 --- a/patches/unapplied/server/0880-Allow-proper-checking-of-empty-item-stacks.patch +++ b/patches/server/0873-Allow-proper-checking-of-empty-item-stacks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Allow proper checking of empty item stacks diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index 4d29c34e221b749b6972c7ed79ac1f86da999ed7..c5a09f086d35f84c0a30266f78e06e2dfb5603e6 100644 +index 134db8c2dd72d0651fc889cc8931e7c971f62deb..30eba68435387daa3917fa2b3071892c350d9ddc 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -@@ -40,12 +40,19 @@ public final class CraftItemStack extends ItemStack { +@@ -45,12 +45,19 @@ public final class CraftItemStack extends ItemStack { } // Paper end - MC Utils diff --git a/patches/unapplied/server/0881-Fix-silent-equipment-change-for-mobs.patch b/patches/server/0874-Fix-silent-equipment-change-for-mobs.patch similarity index 94% rename from patches/unapplied/server/0881-Fix-silent-equipment-change-for-mobs.patch rename to patches/server/0874-Fix-silent-equipment-change-for-mobs.patch index 882525c86d9e..14b0a2dab0f4 100644 --- a/patches/unapplied/server/0881-Fix-silent-equipment-change-for-mobs.patch +++ b/patches/server/0874-Fix-silent-equipment-change-for-mobs.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix silent equipment change for mobs diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index e87360e21e6eb7b0161c34a3ac6cb83d18bcd1e8..cf1f6a0081f0dbcf43842ec23accf6c3ae9b79d8 100644 +index ac7a52e77fd2fcbe9f95709b95ba54f8c2a6514b..8a0e65ac8318a467996f48b423db1ac621359fbe 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -1106,19 +1106,26 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -1100,19 +1100,26 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab @Override public void setItemSlot(EquipmentSlot slot, ItemStack stack) { @@ -39,10 +39,10 @@ index e87360e21e6eb7b0161c34a3ac6cb83d18bcd1e8..cf1f6a0081f0dbcf43842ec23accf6c3 } diff --git a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java -index 6627126ab02dbd5e9d1de6b186d75d850ef11280..3b5cf6ffb74d11bea5eb21bd66d679734ff5000c 100644 +index 0cb179bc28cc863b09a079b37b957744f26f3e1d..32670a3cb4b54b66d655197e3fde834d2b2b6d34 100644 --- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java +++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java -@@ -254,8 +254,8 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo +@@ -258,8 +258,8 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo // Paper end - shouldBurnInDay API @Override diff --git a/patches/unapplied/server/0882-Fix-spigot-s-Forced-Stats.patch b/patches/server/0875-Fix-spigot-s-Forced-Stats.patch similarity index 100% rename from patches/unapplied/server/0882-Fix-spigot-s-Forced-Stats.patch rename to patches/server/0875-Fix-spigot-s-Forced-Stats.patch diff --git a/patches/unapplied/server/0883-Add-missing-InventoryHolders-to-inventories.patch b/patches/server/0876-Add-missing-InventoryHolders-to-inventories.patch similarity index 88% rename from patches/unapplied/server/0883-Add-missing-InventoryHolders-to-inventories.patch rename to patches/server/0876-Add-missing-InventoryHolders-to-inventories.patch index d05856417401..d6bf23a4f847 100644 --- a/patches/unapplied/server/0883-Add-missing-InventoryHolders-to-inventories.patch +++ b/patches/server/0876-Add-missing-InventoryHolders-to-inventories.patch @@ -18,7 +18,7 @@ index db41ffbd24adccd78edf3368ba1f7a3ab9f6072c..5db5ba026462ca642dcee718af732f80 void setMaxStackSize(int size); diff --git a/src/main/java/net/minecraft/world/SimpleContainer.java b/src/main/java/net/minecraft/world/SimpleContainer.java -index 6632cf24ebe6d147950a1fdb876660937da86b73..d04bf7d06855022c973073fb84c5d3d65f2553e1 100644 +index b0963c534afe5be164701cb283f1849e32ae5a86..7ed52b887c4d766c23220a8809914d5d80f12ea4 100644 --- a/src/main/java/net/minecraft/world/SimpleContainer.java +++ b/src/main/java/net/minecraft/world/SimpleContainer.java @@ -30,7 +30,7 @@ public class SimpleContainer implements Container, StackedContentsCompatible { @@ -57,10 +57,10 @@ index 6632cf24ebe6d147950a1fdb876660937da86b73..d04bf7d06855022c973073fb84c5d3d6 public SimpleContainer(int i, org.bukkit.inventory.InventoryHolder owner) { this.bukkitOwner = owner; diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -index afd8f48bd41d2cac413c292f7988c903da1dc700..8a1035c0aa859f67a6806c183d96a88ddf760baa 100644 +index 22dc1569aabe69f139d9682ceb81311993706cb8..85caec29a705f216eff8a5ae11f250697891a05c 100644 --- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -@@ -991,4 +991,15 @@ public abstract class AbstractContainerMenu { +@@ -1054,4 +1054,15 @@ public abstract class AbstractContainerMenu { this.stateId = this.stateId + 1 & 32767; return this.stateId; } @@ -77,7 +77,7 @@ index afd8f48bd41d2cac413c292f7988c903da1dc700..8a1035c0aa859f67a6806c183d96a88d + // Paper end - Add missing InventoryHolders } diff --git a/src/main/java/net/minecraft/world/inventory/BeaconMenu.java b/src/main/java/net/minecraft/world/inventory/BeaconMenu.java -index a735aeeb59f79154ce797c6e2f5600305f46d217..b93c118d957f0a2f40e2f31fd6400bd69438cf72 100644 +index c0dfa04511110be366ee5b0bd75efc51afcce2e4..e0ee1c10960d24d2369d16f22431a8e02a5570aa 100644 --- a/src/main/java/net/minecraft/world/inventory/BeaconMenu.java +++ b/src/main/java/net/minecraft/world/inventory/BeaconMenu.java @@ -42,7 +42,7 @@ public class BeaconMenu extends AbstractContainerMenu { @@ -90,7 +90,7 @@ index a735aeeb59f79154ce797c6e2f5600305f46d217..b93c118d957f0a2f40e2f31fd6400bd6 public boolean canPlaceItem(int slot, ItemStack stack) { return stack.is(ItemTags.BEACON_PAYMENT_ITEMS); diff --git a/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java -index c52c4c4210bc6ae082443318d9795c48c816aba6..ab98637bf967ac19f0bc06e8cb7f18a8b13ec809 100644 +index 8b72d1fd551dcb113f4137aee441a9531c00288a..b3a16b024e46ee8203b225ee429a5c973eab12c6 100644 --- a/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java +++ b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java @@ -54,7 +54,7 @@ public class CartographyTableMenu extends AbstractContainerMenu { @@ -148,7 +148,7 @@ index 85e336637db8643fc5aca1dba724c9b341cbf46f..12b466ccb7c36021cf807c4f3fd2bcb0 @Override public Optional evaluate(BiFunction getter) { diff --git a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java -index 2fa009b33bccd6aeee30f23f9207ab039740d95d..fff1c39920e7d7051dfe3dd39c77865d3bdf113e 100644 +index 2642d8ddc79ad97675f958c89ef03da39903f359..36496144dd6fa87163b692034570eba70c83678c 100644 --- a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java +++ b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java @@ -63,7 +63,7 @@ public class EnchantmentMenu extends AbstractContainerMenu { @@ -161,7 +161,7 @@ index 2fa009b33bccd6aeee30f23f9207ab039740d95d..fff1c39920e7d7051dfe3dd39c77865d public void setChanged() { super.setChanged(); diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java -index 15ec798e149d80aace186f84b9236ddeaba690c3..1678f6c8b2c7db761783e53043169bf12bc2cb29 100644 +index 8e58dbb4b110338dfe8add26697d0b1c9ec5fa9c..3b303d41b9facfb2892ff8402ee0de4608db7318 100644 --- a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java +++ b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java @@ -60,8 +60,8 @@ public class GrindstoneMenu extends AbstractContainerMenu { @@ -176,37 +176,49 @@ index 15ec798e149d80aace186f84b9236ddeaba690c3..1678f6c8b2c7db761783e53043169bf1 public void setChanged() { super.setChanged(); diff --git a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java -index be840717e180b6b5abd14db6cc9263349737f9a3..7de5e47f9a54263734eeef855a2dc07ef64d30ea 100644 +index 4734dd90f2a66e1ac7a64b35ecd62a630108cf07..a5d53a656513ae81cc3f9fc506caf6adaba62a8e 100644 --- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java -@@ -18,7 +18,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { +@@ -17,12 +17,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { + protected final ContainerLevelAccess access; protected final Player player; protected final Container inputSlots; - private final List inputSlotIndexes; -- protected final ResultContainer resultSlots = new ResultContainer(); +- protected final ResultContainer resultSlots = new ResultContainer() { +- @Override +- public void setChanged() { +- ItemCombinerMenu.this.slotsChanged(this); +- } +- }; + protected final ResultContainer resultSlots; // Paper - Add missing InventoryHolders; delay field init private final int resultSlotIndex; - protected abstract boolean mayPickup(Player player, boolean present); -@@ -30,6 +30,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { - public ItemCombinerMenu(@Nullable MenuType type, int syncId, Inventory playerInventory, ContainerLevelAccess context) { + protected boolean mayPickup(Player player, boolean present) { +@@ -36,6 +31,14 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { + public ItemCombinerMenu(@Nullable MenuType type, int syncId, Inventory playerInventory, ContainerLevelAccess context, ItemCombinerMenuSlotDefinition forgingSlotsManager) { super(type, syncId); this.access = context; -+ this.resultSlots = new ResultContainer(this.createBlockHolder(this.access)); // Paper - Add missing InventoryHolders; delay field init ++ // Paper start - Add missing InventoryHolders; delay field init ++ this.resultSlots = new ResultContainer(this.createBlockHolder(this.access)) { ++ @Override ++ public void setChanged() { ++ ItemCombinerMenu.this.slotsChanged(this); ++ } ++ }; ++ // Paper end - Add missing InventoryHolders; delay field init this.player = playerInventory.player; - ItemCombinerMenuSlotDefinition itemcombinermenuslotdefinition = this.createInputSlotDefinitions(); - -@@ -96,7 +97,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { - protected abstract ItemCombinerMenuSlotDefinition createInputSlotDefinitions(); + this.inputSlots = this.createContainer(forgingSlotsManager.getNumOfInputSlots()); + this.resultSlotIndex = forgingSlotsManager.getResultSlotIndex(); +@@ -82,7 +85,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { + public abstract void createResult(); private SimpleContainer createContainer(int size) { - return new SimpleContainer(size) { -+ return new SimpleContainer(this.createBlockHolder(this.access), size) { // Paper - Add missing InventoryHolders ++ return new SimpleContainer(this.createBlockHolder(this.access), size) { @Override public void setChanged() { super.setChanged(); diff --git a/src/main/java/net/minecraft/world/inventory/LoomMenu.java b/src/main/java/net/minecraft/world/inventory/LoomMenu.java -index dc23b646e55bb66e0aa584d82b75b4b3d233276a..2c0e182f7b03ed0f87c259af4df9c4e52106220d 100644 +index 1b7cf165ab0818792870f43719a6324b282bb57a..98519dd3bccca516acdedc69a59189b1106fb75b 100644 --- a/src/main/java/net/minecraft/world/inventory/LoomMenu.java +++ b/src/main/java/net/minecraft/world/inventory/LoomMenu.java @@ -73,7 +73,7 @@ public class LoomMenu extends AbstractContainerMenu { @@ -261,7 +273,7 @@ index d4592218d761eb38402e3d95c642e80a708cb333..4c4266a85c38e41e6c7e6144a68624f4 public ResultContainer() { this.itemStacks = NonNullList.withSize(1, ItemStack.EMPTY); diff --git a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java -index 37e75c02c374314372630f4bda0b92519809f2a4..5a0015f761f6a25d7bb7b9cfe7a9b4771a6a37ec 100644 +index a93870952e2ef674028b8a20aa52a685c743e7ea..ca65965757e6f12abc972250a04817c7547bb0bd 100644 --- a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java +++ b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java @@ -69,7 +69,7 @@ public class StonecutterMenu extends AbstractContainerMenu { diff --git a/patches/server/0877-Do-not-read-tile-entities-in-chunks-that-are-positio.patch b/patches/server/0877-Do-not-read-tile-entities-in-chunks-that-are-positio.patch new file mode 100644 index 000000000000..c55e56d15738 --- /dev/null +++ b/patches/server/0877-Do-not-read-tile-entities-in-chunks-that-are-positio.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Sun, 18 Jun 2023 23:04:46 -0700 +Subject: [PATCH] Do not read tile entities in chunks that are positioned + outside of the chunk + +The tile entities are not accessible and so should not be loaded. +This can happen as a result of users moving regionfiles around, +which would cause a crash on Folia but would appear to function +fine on Paper. + +diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +index d7a204216332ccbd6bece23bd507be0366ea4d61..b86b3bf713668999a21c4120b1d16c295531b2ad 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java ++++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +@@ -363,6 +363,13 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + + while (iterator2.hasNext()) { + nbttagcompound = (CompoundTag) iterator2.next(); ++ // Paper start - do not read tile entities positioned outside the chunk ++ final BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound); ++ if ((blockposition.getX() >> 4) != chunkPos.x || (blockposition.getZ() >> 4) != chunkPos.z) { ++ LOGGER.warn("Tile entity serialized in chunk {} in world '{}' positioned at {} is located outside of the chunk", chunkPos, world.getWorld().getName(), blockposition); ++ continue; ++ } ++ // Paper end - do not read tile entities positioned outside the chunk + protochunk1.setBlockEntityNbt(nbttagcompound); + } + +@@ -616,6 +623,13 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + chunk.setBlockEntityNbt(nbttagcompound); + } else { + BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound); ++ // Paper start - do not read tile entities positioned outside the chunk ++ ChunkPos chunkPos = chunk.getPos(); ++ if ((blockposition.getX() >> 4) != chunkPos.x || (blockposition.getZ() >> 4) != chunkPos.z) { ++ LOGGER.warn("Tile entity serialized in chunk " + chunkPos + " in world '" + world.getWorld().getName() + "' positioned at " + blockposition + " is located outside of the chunk"); ++ continue; ++ } ++ // Paper end - do not read tile entities positioned outside the chunk + BlockEntity tileentity = BlockEntity.loadStatic(blockposition, chunk.getBlockState(blockposition), nbttagcompound, world.registryAccess()); + + if (tileentity != null) { diff --git a/patches/unapplied/server/0885-Add-missing-logs-for-log-ips-config-option.patch b/patches/server/0878-Add-missing-logs-for-log-ips-config-option.patch similarity index 100% rename from patches/unapplied/server/0885-Add-missing-logs-for-log-ips-config-option.patch rename to patches/server/0878-Add-missing-logs-for-log-ips-config-option.patch diff --git a/patches/unapplied/server/0886-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch b/patches/server/0879-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch similarity index 90% rename from patches/unapplied/server/0886-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch rename to patches/server/0879-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch index e1f2934daaa4..b6ec32df6171 100644 --- a/patches/unapplied/server/0886-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch +++ b/patches/server/0879-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch @@ -14,10 +14,10 @@ field by calling any method on the class, and for convenience we use values(). diff --git a/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java b/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java -index 22b6d0851a51da180cd8fbbe6554c5370f5ac5bd..cd9b65f278a750a0177a3252271015d43172b2e9 100644 +index ce3d79ebc7f933d0b34b3f8f71bbec872076847a..ce84851c0c2bf9a066fd5e07be8635d3dcaea0b9 100644 --- a/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java +++ b/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java -@@ -140,6 +140,7 @@ public class UpgradeData { +@@ -153,6 +153,7 @@ public class UpgradeData { Fluid fluid = tick.type() == Fluids.EMPTY ? level.getFluidState(tick.pos()).getType() : tick.type(); level.scheduleTick(tick.pos(), fluid, tick.delay(), tick.priority()); }); diff --git a/patches/unapplied/server/0887-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch b/patches/server/0880-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch similarity index 100% rename from patches/unapplied/server/0887-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch rename to patches/server/0880-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch diff --git a/patches/unapplied/server/0888-Fix-team-sidebar-objectives-not-being-cleared.patch b/patches/server/0881-Fix-team-sidebar-objectives-not-being-cleared.patch similarity index 100% rename from patches/unapplied/server/0888-Fix-team-sidebar-objectives-not-being-cleared.patch rename to patches/server/0881-Fix-team-sidebar-objectives-not-being-cleared.patch diff --git a/patches/unapplied/server/0889-Fix-missing-map-initialize-event-call.patch b/patches/server/0882-Fix-missing-map-initialize-event-call.patch similarity index 91% rename from patches/unapplied/server/0889-Fix-missing-map-initialize-event-call.patch rename to patches/server/0882-Fix-missing-map-initialize-event-call.patch index 3cb380d89c9f..099784fcc015 100644 --- a/patches/unapplied/server/0889-Fix-missing-map-initialize-event-call.patch +++ b/patches/server/0882-Fix-missing-map-initialize-event-call.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Fix missing map initialize event call public net.minecraft.world.level.storage.DimensionDataStorage readSavedData(Ljava/util/function/Function;Lnet/minecraft/util/datafix/DataFixTypes;Ljava/lang/String;)Lnet/minecraft/world/level/saveddata/SavedData; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 1ed6002501b501e72bfff81ae9abc506133a10d0..c13652fccf08ff9235f22e89941a37b283f92f03 100644 +index 1cb5e107a391ab56942cdb2d1cae7d5646a85ec6..39dba6c2e9de2c1d6716945a49d48d9b76a07c77 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1664,13 +1664,24 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1726,13 +1726,24 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Nullable @Override public MapItemSavedData getMapData(MapId id) { diff --git a/patches/unapplied/server/0890-Update-entity-data-when-attaching-firework-to-entity.patch b/patches/server/0883-Update-entity-data-when-attaching-firework-to-entity.patch similarity index 100% rename from patches/unapplied/server/0890-Update-entity-data-when-attaching-firework-to-entity.patch rename to patches/server/0883-Update-entity-data-when-attaching-firework-to-entity.patch diff --git a/patches/unapplied/server/0891-Fix-UnsafeValues-loadAdvancement.patch b/patches/server/0884-Fix-UnsafeValues-loadAdvancement.patch similarity index 93% rename from patches/unapplied/server/0891-Fix-UnsafeValues-loadAdvancement.patch rename to patches/server/0884-Fix-UnsafeValues-loadAdvancement.patch index 8f824385f852..3bf5c53ea0dd 100644 --- a/patches/unapplied/server/0891-Fix-UnsafeValues-loadAdvancement.patch +++ b/patches/server/0884-Fix-UnsafeValues-loadAdvancement.patch @@ -5,13 +5,13 @@ Subject: [PATCH] Fix UnsafeValues#loadAdvancement diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 23ed0a130525a0b3a1b41330685476463c81f183..b07c8111daa010dee2bb8be52162aafa4c267f1f 100644 +index a4998c2df341a1b9a337afb24284428cd98e59d8..fa3add7cc39997d137b9dbc2178e08e9a6e5f31a 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -308,9 +308,30 @@ public final class CraftMagicNumbers implements UnsafeValues { ResourceLocation minecraftkey = CraftNamespacedKey.toMinecraft(key); - JsonElement jsonelement = ServerAdvancementManager.GSON.fromJson(advancement, JsonElement.class); + JsonElement jsonelement = JsonParser.parseString(advancement); - net.minecraft.advancements.Advancement nms = net.minecraft.advancements.Advancement.CODEC.parse(JsonOps.INSTANCE, jsonelement).getOrThrow(JsonParseException::new); + final net.minecraft.resources.RegistryOps ops = CraftRegistry.getMinecraftRegistry().createSerializationContext(JsonOps.INSTANCE); // Paper - use RegistryOps + final net.minecraft.advancements.Advancement nms = net.minecraft.advancements.Advancement.CODEC.parse(ops, jsonelement).getOrThrow(JsonParseException::new); // Paper - use RegistryOps diff --git a/patches/unapplied/server/0892-Add-player-idle-duration-API.patch b/patches/server/0885-Add-player-idle-duration-API.patch similarity index 85% rename from patches/unapplied/server/0892-Add-player-idle-duration-API.patch rename to patches/server/0885-Add-player-idle-duration-API.patch index 0713bbba0b0f..85d9444c878c 100644 --- a/patches/unapplied/server/0892-Add-player-idle-duration-API.patch +++ b/patches/server/0885-Add-player-idle-duration-API.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add player idle duration API Implements API for getting and resetting a player's idle duration. diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index a1b870fb3d1fd5d209474c47bf523d0d5d58ce39..1d79bacbfb24442573245550263141ad56332971 100644 +index 3f55fbf41a85e71a62628db18fde4afb3dd923c3..6de8cd1961a3d5bb50043cc4f1135a981e398666 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3419,6 +3419,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3432,6 +3432,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end diff --git a/patches/unapplied/server/0893-Don-t-check-if-we-can-see-non-visible-entities.patch b/patches/server/0886-Don-t-check-if-we-can-see-non-visible-entities.patch similarity index 85% rename from patches/unapplied/server/0893-Don-t-check-if-we-can-see-non-visible-entities.patch rename to patches/server/0886-Don-t-check-if-we-can-see-non-visible-entities.patch index 5d9fbe505fe4..e86be5d7849f 100644 --- a/patches/unapplied/server/0893-Don-t-check-if-we-can-see-non-visible-entities.patch +++ b/patches/server/0886-Don-t-check-if-we-can-see-non-visible-entities.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Don't check if we can see non-visible entities diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 57af5d1986021c9a135599c6f55b091aebd3bab7..6c667823c2ef15766f3afc1a9c819cb6c24b0912 100644 +index 49d926313b0d0f2ed2e93ca824009c8d0a988f67..29a28e160f6ca87d263b84fbf0c5429d30e34a21 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1537,7 +1537,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1596,7 +1596,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper end - Configurable entity tracking range by Y // CraftBukkit start - respect vanish API diff --git a/patches/unapplied/server/0894-Fix-NPE-in-SculkBloomEvent-world-access.patch b/patches/server/0887-Fix-NPE-in-SculkBloomEvent-world-access.patch similarity index 96% rename from patches/unapplied/server/0894-Fix-NPE-in-SculkBloomEvent-world-access.patch rename to patches/server/0887-Fix-NPE-in-SculkBloomEvent-world-access.patch index 5abf7cda2cf6..3f44bad4f135 100644 --- a/patches/unapplied/server/0894-Fix-NPE-in-SculkBloomEvent-world-access.patch +++ b/patches/server/0887-Fix-NPE-in-SculkBloomEvent-world-access.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix NPE in SculkBloomEvent world access diff --git a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java -index 8d95d129cae03af9ded699047742324807186994..a74732902c0494c67e6acf2fc04581ff9c46b832 100644 +index da81f76a2ee779ffedf9a02d91b5971004167725..4729befa12732a9fd65cce243b33b3b479026c41 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java @@ -35,9 +35,16 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi diff --git a/patches/unapplied/server/0895-Allow-null-itemstack-for-Player-sendEquipmentChange.patch b/patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch similarity index 84% rename from patches/unapplied/server/0895-Allow-null-itemstack-for-Player-sendEquipmentChange.patch rename to patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch index 6839ae5814ea..102c7e16739b 100644 --- a/patches/unapplied/server/0895-Allow-null-itemstack-for-Player-sendEquipmentChange.patch +++ b/patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Allow null itemstack for Player#sendEquipmentChange diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 1d79bacbfb24442573245550263141ad56332971..b2abaf6b535da13cdeeb99c568b91c585ac2ed20 100644 +index 6de8cd1961a3d5bb50043cc4f1135a981e398666..620977c5afae38b8769cea8ccd5e97b311da6fc3 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1127,7 +1127,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1140,7 +1140,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void sendEquipmentChange(LivingEntity entity, EquipmentSlot slot, ItemStack item) { diff --git a/patches/unapplied/server/0896-Optimize-VarInts.patch b/patches/server/0889-Optimize-VarInts.patch similarity index 100% rename from patches/unapplied/server/0896-Optimize-VarInts.patch rename to patches/server/0889-Optimize-VarInts.patch diff --git a/patches/unapplied/server/0897-Add-API-to-get-the-collision-shape-of-a-block-before.patch b/patches/server/0890-Add-API-to-get-the-collision-shape-of-a-block-before.patch similarity index 90% rename from patches/unapplied/server/0897-Add-API-to-get-the-collision-shape-of-a-block-before.patch rename to patches/server/0890-Add-API-to-get-the-collision-shape-of-a-block-before.patch index f0fcc8b9eb88..50464e50cbf0 100644 --- a/patches/unapplied/server/0897-Add-API-to-get-the-collision-shape-of-a-block-before.patch +++ b/patches/server/0890-Add-API-to-get-the-collision-shape-of-a-block-before.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add API to get the collision shape of a block before it's diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java -index 64ddd6d1c40dc91b6e7fc3118403415bb4533d97..0daa0bf7e56aa7228d89867500cb780b37f06541 100644 +index 3ec64c995dcb59a758741e32b886925983a8be56..50fb7edd25c1b38f5c463b78d21d4583bdc89229 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java +++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java -@@ -679,6 +679,20 @@ public class CraftBlockData implements BlockData { +@@ -683,6 +683,20 @@ public class CraftBlockData implements BlockData { return this.state.isFaceSturdy(EmptyBlockGetter.INSTANCE, BlockPos.ZERO, CraftBlock.blockFaceToNotch(face), CraftBlockSupport.toNMS(support)); } diff --git a/patches/unapplied/server/0898-Add-predicate-for-blocks-when-raytracing.patch b/patches/server/0891-Add-predicate-for-blocks-when-raytracing.patch similarity index 93% rename from patches/unapplied/server/0898-Add-predicate-for-blocks-when-raytracing.patch rename to patches/server/0891-Add-predicate-for-blocks-when-raytracing.patch index d609b7862013..bd4cb684e67e 100644 --- a/patches/unapplied/server/0898-Add-predicate-for-blocks-when-raytracing.patch +++ b/patches/server/0891-Add-predicate-for-blocks-when-raytracing.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add predicate for blocks when raytracing diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java -index c978f3b2d42f512e982f289e76c2422e41b7eec6..bb8e962e63c7a2d931f9bd7f7c002aa35cfa5fd3 100644 +index cc9ae2122b563d7b583c7335d0a8ce227f9b1af4..d00ebcd6fccbf1d1efe83604ed86d317119be5f8 100644 --- a/src/main/java/net/minecraft/world/level/BlockGetter.java +++ b/src/main/java/net/minecraft/world/level/BlockGetter.java -@@ -70,6 +70,12 @@ public interface BlockGetter extends LevelHeightAccessor { +@@ -71,6 +71,12 @@ public interface BlockGetter extends LevelHeightAccessor { // CraftBukkit start - moved block handling into separate method for use by Block#rayTrace default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) { @@ -21,7 +21,7 @@ index c978f3b2d42f512e982f289e76c2422e41b7eec6..bb8e962e63c7a2d931f9bd7f7c002aa3 // Paper start - Prevent raytrace from loading chunks BlockState iblockdata = this.getBlockStateIfLoaded(blockposition); if (iblockdata == null) { -@@ -79,7 +85,7 @@ public interface BlockGetter extends LevelHeightAccessor { +@@ -80,7 +86,7 @@ public interface BlockGetter extends LevelHeightAccessor { return BlockHitResult.miss(raytrace1.getTo(), Direction.getNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(raytrace1.getTo())); } // Paper end - Prevent raytrace from loading chunks @@ -30,7 +30,7 @@ index c978f3b2d42f512e982f289e76c2422e41b7eec6..bb8e962e63c7a2d931f9bd7f7c002aa3 FluidState fluid = iblockdata.getFluidState(); // Paper - Perf: don't need to go to world state again Vec3 vec3d = raytrace1.getFrom(); Vec3 vec3d1 = raytrace1.getTo(); -@@ -95,8 +101,14 @@ public interface BlockGetter extends LevelHeightAccessor { +@@ -96,8 +102,14 @@ public interface BlockGetter extends LevelHeightAccessor { // CraftBukkit end default BlockHitResult clip(ClipContext context) { @@ -47,10 +47,10 @@ index c978f3b2d42f512e982f289e76c2422e41b7eec6..bb8e962e63c7a2d931f9bd7f7c002aa3 Vec3 vec3d = raytrace1.getFrom().subtract(raytrace1.getTo()); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index cb50fca4867688d2572e8ab5b7fef7243c5b8ba9..7ada46aa24e1bc15207a34c15b056e4e76238757 100644 +index 536ad499e893c5b9898fb02582eeca541c917890..a81d9f5920de0bd6e54d199cccad96f7f8cebb05 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -1106,9 +1106,15 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1116,9 +1116,15 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public RayTraceResult rayTraceEntities(Location start, Vector direction, double maxDistance, double raySize, Predicate filter) { @@ -68,7 +68,7 @@ index cb50fca4867688d2572e8ab5b7fef7243c5b8ba9..7ada46aa24e1bc15207a34c15b056e4e Preconditions.checkArgument(direction != null, "Vector direction cannot be null"); direction.checkFinite(); -@@ -1158,9 +1164,16 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1168,9 +1174,16 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public RayTraceResult rayTraceBlocks(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks) { @@ -87,7 +87,7 @@ index cb50fca4867688d2572e8ab5b7fef7243c5b8ba9..7ada46aa24e1bc15207a34c15b056e4e Preconditions.checkArgument(direction != null, "Vector direction cannot be null"); direction.checkFinite(); -@@ -1173,16 +1186,23 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1183,16 +1196,23 @@ public class CraftWorld extends CraftRegionAccessor implements World { } Vector dir = direction.clone().normalize().multiply(maxDistance); diff --git a/patches/unapplied/server/0899-Broadcast-take-item-packets-with-collector-as-source.patch b/patches/server/0892-Broadcast-take-item-packets-with-collector-as-source.patch similarity index 88% rename from patches/unapplied/server/0899-Broadcast-take-item-packets-with-collector-as-source.patch rename to patches/server/0892-Broadcast-take-item-packets-with-collector-as-source.patch index 740ea621a79b..1e33c1acff78 100644 --- a/patches/unapplied/server/0899-Broadcast-take-item-packets-with-collector-as-source.patch +++ b/patches/server/0892-Broadcast-take-item-packets-with-collector-as-source.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Broadcast take item packets with collector as source This fixes players (which can't view the collector) seeing item pickups with themselves as the target. diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 4e96a65396b687d2823f2229744f5d448ba87512..04232f281ebd46954ef2259962c7bfc43b8a8aeb 100644 +index 95bbde31de42e1e12d722de86085e59050f1c3ae..c0646a4c023a34d4ca516390d748d29d7b9c265b 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3749,7 +3749,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3893,7 +3893,7 @@ public abstract class LivingEntity extends Entity implements Attackable { public void take(Entity item, int count) { if (!item.isRemoved() && !this.level().isClientSide && (item instanceof ItemEntity || item instanceof AbstractArrow || item instanceof ExperienceOrb)) { diff --git a/patches/unapplied/server/0900-Expand-LingeringPotion-API.patch b/patches/server/0893-Expand-LingeringPotion-API.patch similarity index 88% rename from patches/unapplied/server/0900-Expand-LingeringPotion-API.patch rename to patches/server/0893-Expand-LingeringPotion-API.patch index fdd0abf66829..3a58f0528a7c 100644 --- a/patches/unapplied/server/0900-Expand-LingeringPotion-API.patch +++ b/patches/server/0893-Expand-LingeringPotion-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Expand LingeringPotion API diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java -index 5c6cb752f61c3f3c2960a337173fb7dfe86cc1d3..86c4b593a97431efd062b8c9d86bf92269c00536 100644 +index e78eef3b6fbcd657f9dd180df4cb2eeb55d0814f..9d79b193fe2a737a20d1709548b2cd6c454ff27b 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java -@@ -274,7 +274,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie +@@ -276,7 +276,7 @@ public class ThrownPotion extends ThrowableItemProjectile { boolean noEffects = potioncontents.hasEffects(); // Paper - Fix potions splash events // CraftBukkit start org.bukkit.event.entity.LingeringPotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callLingeringPotionSplashEvent(this, position, entityareaeffectcloud); diff --git a/patches/unapplied/server/0901-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch b/patches/server/0894-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch similarity index 76% rename from patches/unapplied/server/0901-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch rename to patches/server/0894-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch index da48750747c4..8c456a51f54a 100644 --- a/patches/unapplied/server/0901-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch +++ b/patches/server/0894-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Fix strikeLightningEffect powers lightning rods and clears diff --git a/src/main/java/net/minecraft/world/entity/LightningBolt.java b/src/main/java/net/minecraft/world/entity/LightningBolt.java -index 0471d9c85af02133f99cca4e181b83b58a3f1abc..4f701788bd21b61cad251a3a88f9bc416fb99051 100644 +index 152ecd38814089333b8d61538297ce720756d2c3..12127b14babf646711d3a118416453c4f1ac1460 100644 --- a/src/main/java/net/minecraft/world/entity/LightningBolt.java +++ b/src/main/java/net/minecraft/world/entity/LightningBolt.java -@@ -47,6 +47,7 @@ public class LightningBolt extends Entity { +@@ -48,6 +48,7 @@ public class LightningBolt extends Entity { private ServerPlayer cause; private final Set hitEntities = Sets.newHashSet(); private int blocksSetOnFire; @@ -17,7 +17,7 @@ index 0471d9c85af02133f99cca4e181b83b58a3f1abc..4f701788bd21b61cad251a3a88f9bc41 public LightningBolt(EntityType type, Level world) { super(type, world); -@@ -87,7 +88,7 @@ public class LightningBolt extends Entity { +@@ -86,7 +87,7 @@ public class LightningBolt extends Entity { @Override public void tick() { super.tick(); @@ -26,7 +26,7 @@ index 0471d9c85af02133f99cca4e181b83b58a3f1abc..4f701788bd21b61cad251a3a88f9bc41 if (this.level().isClientSide()) { this.level().playLocalSound(this.getX(), this.getY(), this.getZ(), SoundEvents.LIGHTNING_BOLT_THUNDER, SoundSource.WEATHER, 10000.0F, 0.8F + this.random.nextFloat() * 0.2F, false); this.level().playLocalSound(this.getX(), this.getY(), this.getZ(), SoundEvents.LIGHTNING_BOLT_IMPACT, SoundSource.WEATHER, 2.0F, 0.5F + this.random.nextFloat() * 0.2F, false); -@@ -134,7 +135,7 @@ public class LightningBolt extends Entity { +@@ -133,7 +134,7 @@ public class LightningBolt extends Entity { } } @@ -35,22 +35,22 @@ index 0471d9c85af02133f99cca4e181b83b58a3f1abc..4f701788bd21b61cad251a3a88f9bc41 if (!(this.level() instanceof ServerLevel)) { this.level().setSkyFlashTime(2); } else if (!this.visualOnly) { -@@ -163,7 +164,7 @@ public class LightningBolt extends Entity { +@@ -162,7 +163,7 @@ public class LightningBolt extends Entity { } private void spawnFire(int spreadAttempts) { -- if (!this.visualOnly && !this.level().isClientSide && this.level().getGameRules().getBoolean(GameRules.RULE_DOFIRETICK)) { -+ if (!this.visualOnly && !this.isEffect && !this.level().isClientSide && this.level().getGameRules().getBoolean(GameRules.RULE_DOFIRETICK)) { // Paper - Properly handle lightning effects api - BlockPos blockposition = this.blockPosition(); - BlockState iblockdata = BaseFireBlock.getState(this.level(), blockposition); +- if (!this.visualOnly) { ++ if (!this.visualOnly && !this.isEffect) { // Paper - Properly handle lightning effects api + Level world = this.level(); + if (world instanceof ServerLevel) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 166458785b507208caa7ecf8ee8b60650ca3523a..7200c336de27ffd4d37231768ff5192956ede972 100644 +index a81d9f5920de0bd6e54d199cccad96f7f8cebb05..b8bb6ae33a78b7fb152d0068f54cd7c5b046ebdd 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -736,7 +736,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -742,7 +742,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { - LightningBolt lightning = EntityType.LIGHTNING_BOLT.create(this.world); + LightningBolt lightning = EntityType.LIGHTNING_BOLT.create(this.world, EntitySpawnReason.COMMAND); lightning.moveTo(loc.getX(), loc.getY(), loc.getZ()); - lightning.setVisualOnly(isVisual); + lightning.isEffect = isVisual; // Paper - Properly handle lightning effects api diff --git a/patches/unapplied/server/0902-Add-hand-to-fish-event-for-all-player-interactions.patch b/patches/server/0895-Add-hand-to-fish-event-for-all-player-interactions.patch similarity index 89% rename from patches/unapplied/server/0902-Add-hand-to-fish-event-for-all-player-interactions.patch rename to patches/server/0895-Add-hand-to-fish-event-for-all-player-interactions.patch index dd3e5bba4413..cb3197a1b2e2 100644 --- a/patches/unapplied/server/0902-Add-hand-to-fish-event-for-all-player-interactions.patch +++ b/patches/server/0895-Add-hand-to-fish-event-for-all-player-interactions.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add hand to fish event for all player interactions diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -index e70ca1b2e6fbbc1f20e65429298d01b4ebd2dd29..270f4c94912b16c7d4a2d62670847cbb5e011819 100644 +index 1f95234c0a1457050574aa0f6c4b2a8c91b1f272..5b49b11d2d88b33731df582b119ef7a680d862e9 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java +++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -@@ -482,7 +482,15 @@ public class FishingHook extends Projectile { +@@ -487,7 +487,15 @@ public class FishingHook extends Projectile { @Override public void readAdditionalSaveData(CompoundTag nbt) {} @@ -24,7 +24,7 @@ index e70ca1b2e6fbbc1f20e65429298d01b4ebd2dd29..270f4c94912b16c7d4a2d62670847cbb net.minecraft.world.entity.player.Player entityhuman = this.getPlayerOwner(); if (!this.level().isClientSide && entityhuman != null && !this.shouldStopFishing(entityhuman)) { -@@ -490,7 +498,7 @@ public class FishingHook extends Projectile { +@@ -495,7 +503,7 @@ public class FishingHook extends Projectile { if (this.hookedIn != null) { // CraftBukkit start @@ -33,7 +33,7 @@ index e70ca1b2e6fbbc1f20e65429298d01b4ebd2dd29..270f4c94912b16c7d4a2d62670847cbb this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent); if (playerFishEvent.isCancelled()) { -@@ -519,7 +527,7 @@ public class FishingHook extends Projectile { +@@ -524,7 +532,7 @@ public class FishingHook extends Projectile { } // Paper end // CraftBukkit start @@ -42,7 +42,7 @@ index e70ca1b2e6fbbc1f20e65429298d01b4ebd2dd29..270f4c94912b16c7d4a2d62670847cbb playerFishEvent.setExpToDrop(this.random.nextInt(6) + 1); this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent); -@@ -553,7 +561,7 @@ public class FishingHook extends Projectile { +@@ -558,7 +566,7 @@ public class FishingHook extends Projectile { if (this.onGround()) { // CraftBukkit start @@ -51,7 +51,7 @@ index e70ca1b2e6fbbc1f20e65429298d01b4ebd2dd29..270f4c94912b16c7d4a2d62670847cbb this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent); if (playerFishEvent.isCancelled()) { -@@ -564,7 +572,7 @@ public class FishingHook extends Projectile { +@@ -569,7 +577,7 @@ public class FishingHook extends Projectile { } // CraftBukkit start if (i == 0) { @@ -61,10 +61,10 @@ index e70ca1b2e6fbbc1f20e65429298d01b4ebd2dd29..270f4c94912b16c7d4a2d62670847cbb if (playerFishEvent.isCancelled()) { return 0; diff --git a/src/main/java/net/minecraft/world/item/FishingRodItem.java b/src/main/java/net/minecraft/world/item/FishingRodItem.java -index 364c3090057405f83130089d275baf1a61d8e0ca..efb21967fdd2c3b4cb35db6faf213d55da5fc30e 100644 +index 5a50f3391d73fe881b8219d9da05c1dc45533251..801a513d67637136a15307a98fc6bbec9d202b00 100644 --- a/src/main/java/net/minecraft/world/item/FishingRodItem.java +++ b/src/main/java/net/minecraft/world/item/FishingRodItem.java -@@ -30,7 +30,7 @@ public class FishingRodItem extends Item { +@@ -31,7 +31,7 @@ public class FishingRodItem extends Item { if (user.fishing != null) { if (!world.isClientSide) { diff --git a/patches/unapplied/server/0903-Fix-several-issues-with-EntityBreedEvent.patch b/patches/server/0896-Fix-several-issues-with-EntityBreedEvent.patch similarity index 73% rename from patches/unapplied/server/0903-Fix-several-issues-with-EntityBreedEvent.patch rename to patches/server/0896-Fix-several-issues-with-EntityBreedEvent.patch index 6a97d9fb9e5f..7d7a988fc0c7 100644 --- a/patches/unapplied/server/0903-Fix-several-issues-with-EntityBreedEvent.patch +++ b/patches/server/0896-Fix-several-issues-with-EntityBreedEvent.patch @@ -11,10 +11,10 @@ also changed. Also in several places, the breed item was stored after it was decreased by one to consume the item. diff --git a/src/main/java/net/minecraft/world/entity/animal/Animal.java b/src/main/java/net/minecraft/world/entity/animal/Animal.java -index b46352b328178df2a48d1c9e895bed3fabd2c292..1808e1b01afa3041a54c9c9a7586d4d61960527a 100644 +index 775bfac26aaa6db998c2647ec81247b67d0bf784..5677dc97ed83652f261100cf391883cfac7d16fe 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Animal.java +++ b/src/main/java/net/minecraft/world/entity/animal/Animal.java -@@ -148,8 +148,9 @@ public abstract class Animal extends AgeableMob { +@@ -158,8 +158,9 @@ public abstract class Animal extends AgeableMob { int i = this.getAge(); if (!this.level().isClientSide && i == 0 && this.canFallInLove()) { @@ -22,10 +22,10 @@ index b46352b328178df2a48d1c9e895bed3fabd2c292..1808e1b01afa3041a54c9c9a7586d4d6 this.usePlayerItem(player, hand, itemstack); - this.setInLove(player); + this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying - return InteractionResult.SUCCESS; + this.playEatingSound(); + return InteractionResult.SUCCESS_SERVER; } - -@@ -175,10 +176,18 @@ public abstract class Animal extends AgeableMob { +@@ -201,10 +202,18 @@ public abstract class Animal extends AgeableMob { return this.inLove <= 0; } @@ -44,7 +44,7 @@ index b46352b328178df2a48d1c9e895bed3fabd2c292..1808e1b01afa3041a54c9c9a7586d4d6 return; } this.inLove = entityEnterLoveModeEvent.getTicksInLove(); -@@ -186,7 +195,7 @@ public abstract class Animal extends AgeableMob { +@@ -212,7 +221,7 @@ public abstract class Animal extends AgeableMob { if (player != null) { this.loveCause = player.getUUID(); } @@ -54,10 +54,10 @@ index b46352b328178df2a48d1c9e895bed3fabd2c292..1808e1b01afa3041a54c9c9a7586d4d6 this.level().broadcastEntityEvent(this, (byte) 18); } diff --git a/src/main/java/net/minecraft/world/entity/animal/Panda.java b/src/main/java/net/minecraft/world/entity/animal/Panda.java -index 293d6891948e99ac9bd741008f7dcbc5fc1a2e3d..e108f876d3f129c6287f13d68427aed2a6f0c5b1 100644 +index b654bec0fbe903fac24f3bb99399455bf367c68a..be753557d7ebd6f1e82b1bdb6d60ecc450f72eec 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Panda.java +++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java -@@ -673,8 +673,9 @@ public class Panda extends Animal { +@@ -653,8 +653,9 @@ public class Panda extends Animal { this.usePlayerItem(player, hand, itemstack); this.ageUp((int) ((float) (-this.getAge() / 20) * 0.1F), true); } else if (!this.level().isClientSide && this.getAge() == 0 && this.canFallInLove()) { @@ -66,28 +66,13 @@ index 293d6891948e99ac9bd741008f7dcbc5fc1a2e3d..e108f876d3f129c6287f13d68427aed2 - this.setInLove(player); + this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying } else { - if (this.level().isClientSide || this.isSitting() || this.isInWater()) { - return InteractionResult.PASS; -diff --git a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java -index 4eb305bc77767531efb6f9d299216248d4ee39d2..729fd2d52dd48e25ee7a077a3ffafc80ecef7c9f 100644 ---- a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java -+++ b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java -@@ -352,8 +352,8 @@ public class Armadillo extends Animal { - } - - @Override -- public void setInLove(@Nullable Player player) { -- super.setInLove(player); -+ public void setInLove(@Nullable Player player, @Nullable ItemStack breedItemCopy) { // Paper -+ super.setInLove(player, breedItemCopy); // Paper - this.makeSound(SoundEvents.ARMADILLO_EAT); - } + Level world = this.level(); diff --git a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java -index 0388b09e1c4f03958384680ed487792a54007463..8941752e4600ccd11b3fa1147b2e414785589eed 100644 +index c99d37a40c63726c11980adccc67d09fd5132885..f3c884ab9c09f04dd01cabf2ee9de3b5b620563d 100644 --- a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java +++ b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java -@@ -393,7 +393,7 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Saddl +@@ -395,7 +395,7 @@ public class Camel extends AbstractHorse { boolean flag1 = this.isTamed() && this.getAge() == 0 && this.canFallInLove(); if (flag1) { @@ -97,10 +82,10 @@ index 0388b09e1c4f03958384680ed487792a54007463..8941752e4600ccd11b3fa1147b2e4147 boolean flag2 = this.isBaby(); diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java -index f1e43254936feedfe0ffbf77071505f3a65e5053..1f5ed236fb7c0c1b0181675747d25d233f534284 100644 +index 74151d69380e4adede40c7d7fc20834553706730..8aed30cdbbfdd42c20dcd4c8773c8a0ee21a980d 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java -@@ -572,7 +572,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, +@@ -585,7 +585,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, b0 = 5; if (!this.level().isClientSide && this.isTamed() && this.getAge() == 0 && !this.isInLove()) { flag = true; @@ -109,7 +94,7 @@ index f1e43254936feedfe0ffbf77071505f3a65e5053..1f5ed236fb7c0c1b0181675747d25d23 } } else if (item.is(Items.GOLDEN_APPLE) || item.is(Items.ENCHANTED_GOLDEN_APPLE)) { f = 10.0F; -@@ -580,7 +580,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, +@@ -593,7 +593,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, b0 = 10; if (!this.level().isClientSide && this.isTamed() && this.getAge() == 0 && !this.isInLove()) { flag = true; @@ -119,10 +104,10 @@ index f1e43254936feedfe0ffbf77071505f3a65e5053..1f5ed236fb7c0c1b0181675747d25d23 } diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java -index 82c57124433cc033c99e609e8ad71e03d340bc5e..cf6a3a63b6f2b96943c0f399e8c82d293fee31ba 100644 +index 4da66867109394c8966e27551d20b4bcdf4bc9be..18bd483fe46de3d9dc129bffbccfba9d4cab9550 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java -@@ -179,7 +179,7 @@ public class Llama extends AbstractChestedHorse implements VariantHolder implements FeatureElement, EntityTypeT +@@ -659,9 +659,15 @@ public class EntityType implements FeatureElement, EntityTypeT } - public static Optional create(CompoundTag nbt, Level world) { -+ // Paper start - Don't fire sync event during generation + public static Optional create(CompoundTag nbt, Level world, EntitySpawnReason reason) { ++ // Paper start - Don't fire sync event during generation + return create(nbt, world, false); + } -+ public static Optional create(CompoundTag nbt, Level world, boolean generation) { -+ // Paper end - Don't fire sync event during generation ++ public static Optional create(CompoundTag nbt, Level world, EntitySpawnReason reason, boolean generation) { ++ // Paper end - Don't fire sync event during generation return Util.ifElse(EntityType.by(nbt).map((entitytypes) -> { - return entitytypes.create(world); + return entitytypes.create(world, reason); }), (entity) -> { + if (generation) entity.generation = true; // Paper - Don't fire sync event during generation entity.load(nbt); }, () -> { EntityType.LOGGER.warn("Skipping Entity with id {}", nbt.getString("id")); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 04232f281ebd46954ef2259962c7bfc43b8a8aeb..0c67f04ae7eeaa10a90419031447ad5397c6b9e2 100644 +index c0646a4c023a34d4ca516390d748d29d7b9c265b..d37e6651b7be89b14ed5781e1a72fc1b8f50c103 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1138,6 +1138,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1161,6 +1161,11 @@ public abstract class LivingEntity extends Entity implements Attackable { } public boolean addEffect(MobEffectInstance mobeffect, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause) { @@ -83,7 +83,7 @@ index 04232f281ebd46954ef2259962c7bfc43b8a8aeb..0c67f04ae7eeaa10a90419031447ad53 // org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot // Paper - move to API if (this.isTickingEffects) { this.effectsToProcess.add(new ProcessableEffect(mobeffect, cause)); -@@ -1157,10 +1162,13 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1180,10 +1185,13 @@ public abstract class LivingEntity extends Entity implements Attackable { override = new MobEffectInstance(mobeffect1).update(mobeffect); } @@ -97,7 +97,7 @@ index 04232f281ebd46954ef2259962c7bfc43b8a8aeb..0c67f04ae7eeaa10a90419031447ad53 // CraftBukkit end if (mobeffect1 == null) { -@@ -1169,7 +1177,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1192,7 +1200,7 @@ public abstract class LivingEntity extends Entity implements Attackable { flag = true; mobeffect.onEffectAdded(this); // CraftBukkit start @@ -107,7 +107,7 @@ index 04232f281ebd46954ef2259962c7bfc43b8a8aeb..0c67f04ae7eeaa10a90419031447ad53 this.onEffectUpdated(mobeffect1, true, entity); // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java -index f91ea9ac5a0d0d3bae5d1eb0c409f4f9c4e5a62b..9045f18f49a5c6685597d0a77126d7cb35bc5e88 100644 +index 6c2d4c2163cf299c0943af21d4dc367b5677c089..72e42605c278028480c368762da18f61806d766a 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Spider.java +++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java @@ -172,7 +172,7 @@ public class Spider extends Monster { @@ -120,46 +120,46 @@ index f91ea9ac5a0d0d3bae5d1eb0c409f4f9c4e5a62b..9045f18f49a5c6685597d0a77126d7cb } diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java -index cf8258e8d46ca7286a66c38fa24af369bd9a279f..0555abfda468c343af8244a122ebe769e70a0292 100644 +index 734f511d197bc6bf2b02588069eb02c0224781f5..d35b731751e851bee531aa5e7996557658ba6fae 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java +++ b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java -@@ -525,7 +525,7 @@ public class StructureTemplate { +@@ -549,7 +549,7 @@ public class StructureTemplate { private static Optional createEntityIgnoreException(ServerLevelAccessor world, CompoundTag nbt) { // CraftBukkit start // try { -- return EntityType.create(nbt, world.getLevel()); -+ return EntityType.create(nbt, world.getLevel(), true); // Paper - Don't fire sync event during generation +- return EntityType.create(nbt, world.getLevel(), EntitySpawnReason.STRUCTURE); ++ return EntityType.create(nbt, world.getLevel(), EntitySpawnReason.STRUCTURE, true); // Paper - Don't fire sync event during generation // } catch (Exception exception) { // return Optional.empty(); // } diff --git a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java -index 524b51a0ab808a0629c871ad813115abd4b49dbd..fceed3d08ee6f4c171685986bb19d2be592eedc6 100644 +index e444662ee4d9405eeea7caa41b9cd6b36586d840..54c4434662d057a08800918641b95708cda61207 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java +++ b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java -@@ -92,15 +92,17 @@ public abstract class DelegatedGeneratorAccess implements WorldGenLevel { +@@ -90,15 +90,17 @@ public abstract class DelegatedGeneratorAccess implements WorldGenLevel { return this.handle.getLevel(); } - @Override -- public void addFreshEntityWithPassengers(Entity arg0, CreatureSpawnEvent.SpawnReason arg1) { -- this.handle.addFreshEntityWithPassengers(arg0, arg1); +- public void addFreshEntityWithPassengers(Entity entity) { +- this.handle.addFreshEntityWithPassengers(entity); - } - - @Override -- public void addFreshEntityWithPassengers(Entity entity) { -- this.handle.addFreshEntityWithPassengers(entity); +- public void addFreshEntityWithPassengers(Entity entity, CreatureSpawnEvent.SpawnReason reason) { +- this.handle.addFreshEntityWithPassengers(entity, reason); - } + // Paper start - Don't fire sync event during generation; don't override these methods so all entities are run through addFreshEntity + // @Override -+ // public void addFreshEntityWithPassengers(Entity arg0, CreatureSpawnEvent.SpawnReason arg1) { -+ // this.handle.addFreshEntityWithPassengers(arg0, arg1); ++ // public void addFreshEntityWithPassengers(Entity entity) { ++ // this.handle.addFreshEntityWithPassengers(entity); + // } + // + // @Override -+ // public void addFreshEntityWithPassengers(Entity entity) { -+ // this.handle.addFreshEntityWithPassengers(entity); ++ // public void addFreshEntityWithPassengers(Entity entity, CreatureSpawnEvent.SpawnReason reason) { ++ // this.handle.addFreshEntityWithPassengers(entity, reason); + // } -+ // Paper end - Don't fire sync event during generation; don't override these methods ++ // Paper end - Don't fire sync event during generation; don't override these methods so all entities are run through addFreshEntity @Override public ServerLevel getMinecraftWorld() { diff --git a/patches/unapplied/server/0908-Add-Structure-check-API.patch b/patches/server/0901-Add-Structure-check-API.patch similarity index 85% rename from patches/unapplied/server/0908-Add-Structure-check-API.patch rename to patches/server/0901-Add-Structure-check-API.patch index 6f901b1c7f39..fa4acfd73ee9 100644 --- a/patches/unapplied/server/0908-Add-Structure-check-API.patch +++ b/patches/server/0901-Add-Structure-check-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Structure check API diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 7200c336de27ffd4d37231768ff5192956ede972..cb85180daaa2b40cba2474784548d650bc4d639b 100644 +index b8bb6ae33a78b7fb152d0068f54cd7c5b046ebdd..1675ad5818340f21c7e5b6982af315bcad30240b 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -246,6 +246,15 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -250,6 +250,15 @@ public class CraftWorld extends CraftRegionAccessor implements World { }; } // Paper end diff --git a/patches/unapplied/server/0909-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch b/patches/server/0902-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch similarity index 89% rename from patches/unapplied/server/0909-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch rename to patches/server/0902-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch index 86ed135ebc33..db45e464ac2b 100644 --- a/patches/unapplied/server/0909-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch +++ b/patches/server/0902-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix CraftMetaItem#getAttributeModifier duplication check diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index df34eba383c0d3035c8baed7fdd054ecdd681fa3..f15456b02cabbbe33d701450ef53a0561d91cb8c 100644 +index af78e73755743fb2db7a99b834affc963b44bc10..3bcc807005a677884255f1ee36cbf1653797ba55 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -@@ -1414,7 +1414,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1666,7 +1666,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { Preconditions.checkNotNull(modifier, "AttributeModifier cannot be null"); this.checkAttributeList(); for (Map.Entry entry : this.attributeModifiers.entries()) { diff --git a/patches/unapplied/server/0910-Restore-vanilla-entity-drops-behavior.patch b/patches/server/0903-Restore-vanilla-entity-drops-behavior.patch similarity index 82% rename from patches/unapplied/server/0910-Restore-vanilla-entity-drops-behavior.patch rename to patches/server/0903-Restore-vanilla-entity-drops-behavior.patch index 76363209030c..ae2eeec5524c 100644 --- a/patches/unapplied/server/0910-Restore-vanilla-entity-drops-behavior.patch +++ b/patches/server/0903-Restore-vanilla-entity-drops-behavior.patch @@ -9,16 +9,16 @@ on dropping the item instead of generalizing it for all dropped items like CB does. diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index b65d816bb9feb18ecf74e10e9728c302e5657587..62ec627e80b87a92a2a51ba9fc3626a67636855f 100644 +index b0b4bede6f25b8a0de54d954c7010021f87aadc3..52b18f2c333b7535929bb4e52e65cf5fb0f5692f 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -976,20 +976,20 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1235,20 +1235,20 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { if (this.isRemoved()) { return; } - java.util.List loot = new java.util.ArrayList<>(this.getInventory().getContainerSize()); + List loot = new java.util.ArrayList<>(this.getInventory().getContainerSize()); // Paper - Restore vanilla drops behavior - boolean keepInventory = this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator(); + boolean keepInventory = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator(); if (!keepInventory) { for (ItemStack item : this.getInventory().getContents()) { @@ -30,22 +30,22 @@ index b65d816bb9feb18ecf74e10e9728c302e5657587..62ec627e80b87a92a2a51ba9fc3626a6 } if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - fix player loottables running when mob loot gamerule is false // SPIGOT-5071: manually add player loot tables (SPIGOT-5195 - ignores keepInventory rule) - this.dropFromLootTable(damageSource, this.lastHurtByPlayerTime > 0); + this.dropFromLootTable(this.serverLevel(), damageSource, this.lastHurtByPlayerTime > 0); - this.dropCustomDeathLoot(this.serverLevel(), damageSource, flag); + // Paper - Restore vanilla drops behaviour; custom death loot is a noop on server player, remove. loot.addAll(this.drops); this.drops.clear(); // SPIGOT-5188: make sure to clear diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index f163cb3c75e90b96b3794a7e0c5b803268814c8c..e88c88b6f87dddda8e8e3ed215a8f2c166afa3ef 100644 +index 1fb29f2c5e55d77eb5d04d423cf9f38a6e7d9f4c..0223f2e282a85882645f4ed52891c566a268f37b 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -2562,6 +2562,25 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2678,19 +2678,45 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Nullable - public ItemEntity spawnAtLocation(ItemStack stack, float yOffset) { + public ItemEntity spawnAtLocation(ServerLevel world, ItemStack stack, float yOffset) { + // Paper start - Restore vanilla drops behavior -+ return this.spawnAtLocation(stack, yOffset, null); ++ return this.spawnAtLocation(world, stack, yOffset, null); + } + public record DefaultDrop(Item item, org.bukkit.inventory.ItemStack stack, @Nullable java.util.function.Consumer dropConsumer) { + public DefaultDrop(final ItemStack stack, final java.util.function.Consumer dropConsumer) { @@ -61,12 +61,10 @@ index f163cb3c75e90b96b3794a7e0c5b803268814c8c..e88c88b6f87dddda8e8e3ed215a8f2c1 + } + } + @Nullable -+ public ItemEntity spawnAtLocation(ItemStack stack, float yOffset, @Nullable java.util.function.Consumer delayedAddConsumer) { ++ public ItemEntity spawnAtLocation(ServerLevel world, ItemStack stack, float yOffset, @Nullable java.util.function.Consumer delayedAddConsumer) { + // Paper end - Restore vanilla drops behavior if (stack.isEmpty()) { return null; - } else if (this.level().isClientSide) { -@@ -2569,14 +2588,21 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } else { // CraftBukkit start - Capture drops for death event if (this instanceof net.minecraft.world.entity.LivingEntity && !((net.minecraft.world.entity.LivingEntity) this).forceDrops) { @@ -82,7 +80,7 @@ index f163cb3c75e90b96b3794a7e0c5b803268814c8c..e88c88b6f87dddda8e8e3ed215a8f2c1 return null; } // CraftBukkit end - ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY() + (double) yOffset, this.getZ(), stack.copy()); // Paper - copy so we can destroy original + ItemEntity entityitem = new ItemEntity(world, this.getX(), this.getY() + (double) yOffset, this.getZ(), stack); stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe - entityitem.setDefaultPickUpDelay(); @@ -91,10 +89,10 @@ index f163cb3c75e90b96b3794a7e0c5b803268814c8c..e88c88b6f87dddda8e8e3ed215a8f2c1 return this.spawnAtLocation(entityitem); } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 0c67f04ae7eeaa10a90419031447ad5397c6b9e2..6b2dc430126713e11658f94762035ff10bbe018c 100644 +index d37e6651b7be89b14ed5781e1a72fc1b8f50c103..0fcc5ed28b2371a62be57d7ea62f2e3dfedcf735 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -278,7 +278,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -291,7 +291,7 @@ public abstract class LivingEntity extends Entity implements Attackable { protected float appliedScale; // CraftBukkit start public int expToDrop; @@ -104,16 +102,16 @@ index 0c67f04ae7eeaa10a90419031447ad5397c6b9e2..6b2dc430126713e11658f94762035ff1 public boolean collides = true; public Set collidableExemptions = new HashSet<>(); diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java -index 1b49090a466bc74d9e5f2815314955b6dfbb83dc..62271e74399a827a488159da234465ef18e15e6e 100644 +index e6b18d7f8922cb42acb9e40bef2f71a56aea8646..e1be143959fbaa1d54af2a1a2c27187d70e6a9e9 100644 --- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java +++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java -@@ -538,10 +538,9 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -536,10 +536,10 @@ public class WitherBoss extends Monster implements RangedAttackMob { @Override protected void dropCustomDeathLoot(ServerLevel world, DamageSource source, boolean causedByPlayer) { super.dropCustomDeathLoot(world, source, causedByPlayer); -- ItemEntity entityitem = this.spawnAtLocation((ItemLike) Items.NETHER_STAR); -- -+ ItemEntity entityitem = this.spawnAtLocation(new net.minecraft.world.item.ItemStack(Items.NETHER_STAR), 0, ItemEntity::setExtendedLifetime); // Paper - Restore vanilla drops behavior; spawnAtLocation returns null so modify the item entity with a consumer +- ItemEntity entityitem = this.spawnAtLocation(world, (ItemLike) Items.NETHER_STAR); ++ ItemEntity entityitem = this.spawnAtLocation(world, new net.minecraft.world.item.ItemStack(Items.NETHER_STAR), 0, ItemEntity::setExtendedLifetime); // Paper - Restore vanilla drops behavior; spawnAtLocation returns null so modify the item entity with a consumer + if (entityitem != null) { - entityitem.setExtendedLifetime(); + entityitem.setExtendedLifetime(); // Paper - diff on change @@ -121,10 +119,10 @@ index 1b49090a466bc74d9e5f2815314955b6dfbb83dc..62271e74399a827a488159da234465ef } diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -index 5bcb9a53ebebeef4bd6ec2458df4b63002ebd804..2f398750bfee5758ad8b1367b6fc14364e4de776 100644 +index 2bb2b36f793d25b6e49d1a72bb665cfa9f212730..63f02cdc67d9e88cc6998d0ae9d139c83e85b447 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -621,7 +621,7 @@ public class ArmorStand extends LivingEntity { +@@ -619,7 +619,7 @@ public class ArmorStand extends LivingEntity { ItemStack itemstack = new ItemStack(Items.ARMOR_STAND); itemstack.set(DataComponents.CUSTOM_NAME, this.getCustomName()); @@ -133,7 +131,7 @@ index 5bcb9a53ebebeef4bd6ec2458df4b63002ebd804..2f398750bfee5758ad8b1367b6fc1436 return this.brokenByAnything(world, damageSource); // Paper } -@@ -635,7 +635,7 @@ public class ArmorStand extends LivingEntity { +@@ -633,7 +633,7 @@ public class ArmorStand extends LivingEntity { for (i = 0; i < this.handItems.size(); ++i) { itemstack = (ItemStack) this.handItems.get(i); if (!itemstack.isEmpty()) { @@ -142,7 +140,7 @@ index 5bcb9a53ebebeef4bd6ec2458df4b63002ebd804..2f398750bfee5758ad8b1367b6fc1436 this.handItems.set(i, ItemStack.EMPTY); } } -@@ -643,7 +643,7 @@ public class ArmorStand extends LivingEntity { +@@ -641,7 +641,7 @@ public class ArmorStand extends LivingEntity { for (i = 0; i < this.armorItems.size(); ++i) { itemstack = (ItemStack) this.armorItems.get(i); if (!itemstack.isEmpty()) { @@ -152,10 +150,10 @@ index 5bcb9a53ebebeef4bd6ec2458df4b63002ebd804..2f398750bfee5758ad8b1367b6fc1436 } } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 2690c471b819f8308f6db44150025dfa323d4e0c..f529243852df8e193a604bb6d895333848b14a74 100644 +index dbef230ae88ee1bfbc20ba53b534434c3ccac985..fb75b7f84575c42ab5dcb7e9c5659cecf439da90 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -975,18 +975,24 @@ public class CraftEventFactory { +@@ -973,19 +973,25 @@ public class CraftEventFactory { } public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource) { @@ -175,16 +173,17 @@ index 2690c471b819f8308f6db44150025dfa323d4e0c..f529243852df8e193a604bb6d8953338 + return new Entity.DefaultDrop(CraftItemType.bukkitToMinecraft(stack.getType()), stack, null); + }; + -+ public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List drops, Runnable lootCheck) { // Paper ++ public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List drops, Runnable lootCheck) { // Paper - Restore vanilla drops behavior // Paper end CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity(); CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource); -- EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(damageSource.getEntity())); -+ EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(damageSource.getEntity())); // Paper - Restore vanilla drops behavior - populateFields(victim, event); // Paper - make cancellable CraftWorld world = (CraftWorld) entity.getWorld(); +- EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(world.getHandle(), damageSource.getEntity())); ++ EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(world.getHandle(), damageSource.getEntity())); // Paper - Restore vanilla drops behavior, victim.getExpReward(world.getHandle(), damageSource.getEntity())); + populateFields(victim, event); // Paper - make cancellable Bukkit.getServer().getPluginManager().callEvent(event); -@@ -1000,20 +1006,24 @@ public class CraftEventFactory { + +@@ -998,20 +1004,24 @@ public class CraftEventFactory { victim.expToDrop = event.getDroppedExp(); lootCheck.run(); // Paper - advancement triggers before destroying items @@ -193,7 +192,7 @@ index 2690c471b819f8308f6db44150025dfa323d4e0c..f529243852df8e193a604bb6d8953338 + for (Entity.DefaultDrop drop : drops) { + if (drop == null) continue; + final org.bukkit.inventory.ItemStack stack = drop.stack(); -+ // Paper end - Restore vanilla drops behavior ++ // Paper end - Restore vanilla drops behavior if (stack == null || stack.getType() == Material.AIR || stack.getAmount() == 0) continue; - world.dropItem(entity.getLocation(), stack); // Paper - note: dropItem already clones due to this being bukkit -> NMS @@ -208,12 +207,12 @@ index 2690c471b819f8308f6db44150025dfa323d4e0c..f529243852df8e193a604bb6d8953338 + public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure & Restore vanilla drops behavior CraftPlayer entity = victim.getBukkitEntity(); CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource); -- PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(damageSource.getEntity()), 0, deathMessage); -+ PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(damageSource.getEntity()), 0, deathMessage); // Paper - Restore vanilla drops behavior +- PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage); ++ PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage); // Paper - Restore vanilla drops behavior event.setKeepInventory(keepInventory); event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel populateFields(victim, event); // Paper - make cancellable -@@ -1031,16 +1041,14 @@ public class CraftEventFactory { +@@ -1029,16 +1039,14 @@ public class CraftEventFactory { victim.expToDrop = event.getDroppedExp(); victim.newExp = event.getNewExp(); @@ -222,14 +221,14 @@ index 2690c471b819f8308f6db44150025dfa323d4e0c..f529243852df8e193a604bb6d8953338 + for (Entity.DefaultDrop drop : drops) { + if (drop == null) continue; + final org.bukkit.inventory.ItemStack stack = drop.stack(); -+ // Paper end - Restore vanilla drops behavior ++ // Paper end - Restore vanilla drops behavior if (stack == null || stack.getType() == Material.AIR) continue; - if (stack instanceof CraftItemStack craftItemStack && craftItemStack.isForInventoryDrop()) { - victim.drop(CraftItemStack.asNMSCopy(stack), true, false, false); // SPIGOT-7800, SPIGOT-7801: Vanilla Behaviour for Player Inventory dropped items - } else { - victim.forceDrops = true; -- victim.spawnAtLocation(CraftItemStack.asNMSCopy(stack)); // SPIGOT-7806: Vanilla Behaviour for items not related to Player Inventory dropped items +- victim.spawnAtLocation(victim.serverLevel(), CraftItemStack.asNMSCopy(stack)); // SPIGOT-7806: Vanilla Behaviour for items not related to Player Inventory dropped items - victim.forceDrops = false; - } + drop.runConsumer(s -> victim.drop(CraftItemStack.unwrap(s), true, false, false)); // Paper - Restore vanilla drops behavior @@ -237,10 +236,10 @@ index 2690c471b819f8308f6db44150025dfa323d4e0c..f529243852df8e193a604bb6d8953338 return event; diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index c5a09f086d35f84c0a30266f78e06e2dfb5603e6..f33742ee06e8443a5f5adaaa987d7523dc193b5a 100644 +index 30eba68435387daa3917fa2b3071892c350d9ddc..0b7bc5e83634a26ac6521694377b554c74c6bff0 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -@@ -130,27 +130,6 @@ public final class CraftItemStack extends ItemStack { +@@ -142,27 +142,6 @@ public final class CraftItemStack extends ItemStack { this.setItemMeta(itemMeta); } diff --git a/patches/unapplied/server/0911-Dont-resend-blocks-on-interactions.patch b/patches/server/0904-Dont-resend-blocks-on-interactions.patch similarity index 85% rename from patches/unapplied/server/0911-Dont-resend-blocks-on-interactions.patch rename to patches/server/0904-Dont-resend-blocks-on-interactions.patch index 74650cebfd9d..72f6df6566f3 100644 --- a/patches/unapplied/server/0911-Dont-resend-blocks-on-interactions.patch +++ b/patches/server/0904-Dont-resend-blocks-on-interactions.patch @@ -8,10 +8,10 @@ In general, the client now has an acknowledgment system which will prevent block It should be noted that this system does not yet support block entities, so those still need to resynced when needed. diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index d839f8df658c894f144ba4637d290ffbed77e132..415d9802ae4dd75b44055b8faf19672fa50c585f 100644 +index 0da6496c18341c01fc4551ead7e740a6037dcf31..c4bc1819cba3287c4a67ae5d00f8c4d6ab899732 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -204,7 +204,7 @@ public class ServerPlayerGameMode { +@@ -202,7 +202,7 @@ public class ServerPlayerGameMode { PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, pos, direction, this.player.getInventory().getSelected(), InteractionHand.MAIN_HAND); if (event.isCancelled()) { // Let the client know the block still exists @@ -20,7 +20,7 @@ index d839f8df658c894f144ba4637d290ffbed77e132..415d9802ae4dd75b44055b8faf19672f // Update any tile entity data for this block capturedBlockEntity = true; // Paper - Send block entities after destroy prediction return; -@@ -219,7 +219,7 @@ public class ServerPlayerGameMode { +@@ -217,7 +217,7 @@ public class ServerPlayerGameMode { // Spigot start - handle debug stick left click for non-creative if (this.player.getMainHandItem().is(net.minecraft.world.item.Items.DEBUG_STICK) && ((net.minecraft.world.item.DebugStickItem) net.minecraft.world.item.Items.DEBUG_STICK).handleInteraction(this.player, this.level.getBlockState(pos), this.level, pos, false, this.player.getMainHandItem())) { @@ -29,7 +29,7 @@ index d839f8df658c894f144ba4637d290ffbed77e132..415d9802ae4dd75b44055b8faf19672f return; } // Spigot end -@@ -237,15 +237,17 @@ public class ServerPlayerGameMode { +@@ -235,15 +235,17 @@ public class ServerPlayerGameMode { // CraftBukkit start - Swings at air do *NOT* exist. if (event.useInteractedBlock() == Event.Result.DENY) { // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door. @@ -56,7 +56,7 @@ index d839f8df658c894f144ba4637d290ffbed77e132..415d9802ae4dd75b44055b8faf19672f } else if (!iblockdata.isAir()) { EnchantmentHelper.onHitBlock(this.level, this.player.getMainHandItem(), this.player, this.player, EquipmentSlot.MAINHAND, Vec3.atCenterOf(pos), iblockdata, (item) -> { this.player.onEquippedItemBroken(item, EquipmentSlot.MAINHAND); -@@ -257,7 +259,7 @@ public class ServerPlayerGameMode { +@@ -255,7 +257,7 @@ public class ServerPlayerGameMode { if (event.useItemInHand() == Event.Result.DENY) { // If we 'insta destroyed' then the client needs to be informed. if (f > 1.0f) { @@ -65,7 +65,7 @@ index d839f8df658c894f144ba4637d290ffbed77e132..415d9802ae4dd75b44055b8faf19672f } return; } -@@ -265,7 +267,7 @@ public class ServerPlayerGameMode { +@@ -263,7 +265,7 @@ public class ServerPlayerGameMode { if (blockEvent.isCancelled()) { // Let the client know the block still exists @@ -74,7 +74,7 @@ index d839f8df658c894f144ba4637d290ffbed77e132..415d9802ae4dd75b44055b8faf19672f return; } -@@ -356,7 +358,7 @@ public class ServerPlayerGameMode { +@@ -354,7 +356,7 @@ public class ServerPlayerGameMode { // Tell client the block is gone immediately then process events // Don't tell the client if its a creative sword break because its not broken! @@ -83,7 +83,7 @@ index d839f8df658c894f144ba4637d290ffbed77e132..415d9802ae4dd75b44055b8faf19672f ClientboundBlockUpdatePacket packet = new ClientboundBlockUpdatePacket(pos, Blocks.AIR.defaultBlockState()); this.player.connection.send(packet); } -@@ -382,13 +384,15 @@ public class ServerPlayerGameMode { +@@ -380,13 +382,15 @@ public class ServerPlayerGameMode { if (isSwordNoBreak) { return false; } @@ -103,7 +103,7 @@ index d839f8df658c894f144ba4637d290ffbed77e132..415d9802ae4dd75b44055b8faf19672f // Update any tile entity data for this block if (!captureSentBlockEntities) { // Paper - Send block entities after destroy prediction -@@ -537,16 +541,18 @@ public class ServerPlayerGameMode { +@@ -543,16 +547,18 @@ public class ServerPlayerGameMode { if (event.useInteractedBlock() == Event.Result.DENY) { // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door. if (iblockdata.getBlock() instanceof DoorBlock) { @@ -127,7 +127,7 @@ index d839f8df658c894f144ba4637d290ffbed77e132..415d9802ae4dd75b44055b8faf19672f } else if (iblockdata.is(Blocks.JIGSAW) || iblockdata.is(Blocks.STRUCTURE_BLOCK) || iblockdata.getBlock() instanceof net.minecraft.world.level.block.CommandBlock) { player.connection.send(new net.minecraft.network.protocol.game.ClientboundContainerClosePacket(this.player.containerMenu.containerId)); diff --git a/src/main/java/net/minecraft/world/item/BucketItem.java b/src/main/java/net/minecraft/world/item/BucketItem.java -index 6caed156ed0cfe0017d578f58cb963ee68272d78..321188173918d0d60858a258400dfd682ccdb21c 100644 +index 002e2f8e956b2631529e2189be225385dfb501df..3bddfb6f7412ab86e0c090d0cbc6cf254b3f891c 100644 --- a/src/main/java/net/minecraft/world/item/BucketItem.java +++ b/src/main/java/net/minecraft/world/item/BucketItem.java @@ -79,7 +79,7 @@ public class BucketItem extends Item implements DispensibleContainerItem { @@ -137,7 +137,7 @@ index 6caed156ed0cfe0017d578f58cb963ee68272d78..321188173918d0d60858a258400dfd68 - ((ServerPlayer) user).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-5163 (see PlayerInteractManager) + // ((ServerPlayer) user).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-5163 (see PlayerInteractManager) // Paper - Don't resend blocks ((ServerPlayer) user).getBukkitEntity().updateInventory(); // SPIGOT-4541 - return InteractionResultHolder.fail(itemstack); + return InteractionResult.FAIL; } @@ -187,7 +187,7 @@ public class BucketItem extends Item implements DispensibleContainerItem { if (flag2 && entityhuman != null) { @@ -149,23 +149,23 @@ index 6caed156ed0cfe0017d578f58cb963ee68272d78..321188173918d0d60858a258400dfd68 return false; } diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 87cae96faf33fa0491b13add79e02fc225bd2f70..e9a9c89bd6a4ce7cb30c2fcf79a537fc18204aeb 100644 +index db971851a9e219ead89d71bb97d65ff73d9fd285..bba4fbde31ef25bc086fefaa86f9a479ef6ccf26 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -500,10 +500,12 @@ public final class ItemStack implements DataComponentHolder { - world.preventPoiUpdated = false; +@@ -506,10 +506,12 @@ public final class ItemStack implements DataComponentHolder { + world.preventPoiUpdated = false; - // Brute force all possible updates -- BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition(); -- for (Direction dir : Direction.values()) { -- ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir))); -- } -+ // Paper start - Don't resync blocks -+ // BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition(); -+ // for (Direction dir : Direction.values()) { -+ // ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir))); -+ // } -+ // Paper end - Don't resync blocks - SignItem.openSign = null; // SPIGOT-6758 - Reset on early return - } else { - // Change the stack to its new contents if it hasn't been tampered with. + // Brute force all possible updates +- BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition(); +- for (Direction dir : Direction.values()) { +- ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir))); +- } ++ // Paper start - Don't resync blocks ++ // BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition(); ++ // for (Direction dir : Direction.values()) { ++ // ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir))); ++ // } ++ // Paper end - Don't resync blocks + SignItem.openSign = null; // SPIGOT-6758 - Reset on early return + } else { + // Change the stack to its new contents if it hasn't been tampered with. diff --git a/patches/unapplied/server/0912-add-more-scoreboard-API.patch b/patches/server/0905-add-more-scoreboard-API.patch similarity index 100% rename from patches/unapplied/server/0912-add-more-scoreboard-API.patch rename to patches/server/0905-add-more-scoreboard-API.patch diff --git a/patches/unapplied/server/0913-Improve-Registry.patch b/patches/server/0906-Improve-Registry.patch similarity index 94% rename from patches/unapplied/server/0913-Improve-Registry.patch rename to patches/server/0906-Improve-Registry.patch index 2f04f6238338..d5769f63c038 100644 --- a/patches/unapplied/server/0913-Improve-Registry.patch +++ b/patches/server/0906-Improve-Registry.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Improve Registry diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java -index 3dbdfc2fb973c3c9aecc6582451071e8a939f5f0..c410e2d94562afc6bdd5bb3c9c01995eac0bc3fc 100644 +index 09929f580164abcd1c04061d04c6aa992767e256..aa66fd8dca886c1f064d8cb4a3d15c2086c1719a 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java @@ -155,6 +155,7 @@ public class CraftRegistry implements Registry { @@ -37,7 +37,7 @@ index 3dbdfc2fb973c3c9aecc6582451071e8a939f5f0..c410e2d94562afc6bdd5bb3c9c01995e + // Paper end - improve Registry } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java b/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java -index cd3e35867075e65f46051fb88d8a2460a8bb4b53..76627683f256a034a147765db693a9fd2ab9613f 100644 +index caf7e4312e95e90dd0822355c8832006e69a2700..38578ef887227ecc8e8bba281eae17a849b4fbe6 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java @@ -54,6 +54,7 @@ public class CraftTrimMaterial implements TrimMaterial, Handleable= 0, "Total experience points must not be negative (%s)", exp); this.getHandle().totalExperience = exp; } diff --git a/patches/server/0909-Add-drops-to-shear-events.patch b/patches/server/0909-Add-drops-to-shear-events.patch new file mode 100644 index 000000000000..21efa0e4146e --- /dev/null +++ b/patches/server/0909-Add-drops-to-shear-events.patch @@ -0,0 +1,398 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Tue, 18 May 2021 12:32:02 -0700 +Subject: [PATCH] Add drops to shear events + + +diff --git a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java +index 9b5a1dc958232e4c2c9631f3504edc6383afd92a..f5206e4176f58cff4cfe70c94f014afebc98c589 100644 +--- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java ++++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java +@@ -103,11 +103,14 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior { + if (entityliving instanceof Shearable ishearable) { + if (ishearable.readyForShearing()) { + // CraftBukkit start +- if (CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem).isCancelled()) { ++ // Paper start - Add drops to shear events ++ org.bukkit.event.block.BlockShearEntityEvent event = CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem, ishearable.generateDefaultDrops(worldserver, itemstack)); ++ if (event.isCancelled()) { ++ // Paper end - Add drops to shear events + continue; + } + // CraftBukkit end +- ishearable.shear(worldserver, SoundSource.BLOCKS, itemstack); ++ ishearable.shear(worldserver, SoundSource.BLOCKS, itemstack, CraftItemStack.asNMSCopy(event.getDrops())); // Paper - Add drops to shear events + worldserver.gameEvent((Entity) null, (Holder) GameEvent.SHEAR, blockposition); + return true; + } +diff --git a/src/main/java/net/minecraft/world/entity/Shearable.java b/src/main/java/net/minecraft/world/entity/Shearable.java +index a3095eee48d8b87a35ad35da9c8a2a9ca20c92bc..88dcde6c901753d002a99333eb646bda17122c95 100644 +--- a/src/main/java/net/minecraft/world/entity/Shearable.java ++++ b/src/main/java/net/minecraft/world/entity/Shearable.java +@@ -5,7 +5,13 @@ import net.minecraft.sounds.SoundSource; + import net.minecraft.world.item.ItemStack; + + public interface Shearable { ++ default void shear(ServerLevel world, SoundSource soundCategory, ItemStack shears, java.util.List drops) { this.shear(world, soundCategory, shears); } // Paper - Add drops to shear events + void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears); + + boolean readyForShearing(); ++ // Paper start - custom shear drops; ensure all implementing entities override this ++ default java.util.List generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) { ++ return java.util.Collections.emptyList(); ++ } ++ // Paper end - custom shear drops + } +diff --git a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java +index d4d343e2d75a3e3ea787c3c68c64970f5b239f81..fad312784476d361e548a4d4ea942fa60ec72c66 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java ++++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java +@@ -46,6 +46,7 @@ import net.minecraft.world.level.storage.loot.BuiltInLootTables; + // CraftBukkit start + import org.bukkit.Bukkit; + import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; + import org.bukkit.event.entity.EntityDropItemEvent; + import org.bukkit.event.entity.EntityTransformEvent; + // CraftBukkit end +@@ -128,11 +129,18 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder drops = this.generateDefaultDrops(worldserver, itemstack); ++ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); ++ if (event != null) { ++ if (event.isCancelled()) { ++ return InteractionResult.PASS; ++ } ++ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); ++ // Paper end - custom shear drops + } + // CraftBukkit end +- this.shear(worldserver, SoundSource.PLAYERS, itemstack); ++ this.shear(worldserver, SoundSource.PLAYERS, itemstack, drops); // Paper - custom shear drops + this.gameEvent(GameEvent.SHEAR, player); + itemstack.hurtAndBreak(1, player, getSlotForHand(hand)); + } +@@ -168,22 +176,32 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) { ++ final java.util.List drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); ++ this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.SHEAR_MOOSHROOM, shears, (ignored, stack) -> { ++ for (int i = 0; i < stack.getCount(); ++i) drops.add(stack.copyWithCount(1)); ++ }); ++ return drops; ++ } ++ ++ @Override ++ public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears, java.util.List drops) { ++ // Paper end - custom shear drops + world.playSound((Player) null, (Entity) this, SoundEvents.MOOSHROOM_SHEAR, shearedSoundCategory, 1.0F, 1.0F); + this.convertTo(EntityType.COW, ConversionParams.single(this, false, false), (entitycow) -> { + world.sendParticles(ParticleTypes.EXPLOSION, this.getX(), this.getY(0.5D), this.getZ(), 1, 0.0D, 0.0D, 0.0D, 0.0D); +- this.dropFromShearingLootTable(world, BuiltInLootTables.SHEAR_MOOSHROOM, shears, (worldserver1, itemstack1) -> { +- for (int i = 0; i < itemstack1.getCount(); ++i) { +- // CraftBukkit start +- ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), itemstack1.copyWithCount(1)); +- EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity()); +- Bukkit.getPluginManager().callEvent(event); +- if (event.isCancelled()) { +- continue; +- } +- worldserver1.addFreshEntity(entityitem); +- // CraftBukkit end ++ // Paper start - custom shear drops; moved drop generation to separate method ++ drops.forEach(itemstack1 -> { ++ for (final ItemStack drop : drops) { ++ ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), drop); ++ this.spawnAtLocation(entityitem); + } +- ++ // Paper end - custom shear drops; moved drop generation to separate method + }); + }, EntityTransformEvent.TransformReason.SHEARED, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SHEARED); // CraftBukkit + } +diff --git a/src/main/java/net/minecraft/world/entity/animal/Sheep.java b/src/main/java/net/minecraft/world/entity/animal/Sheep.java +index 1bc638ab505850bffcbd08025de9664dd27e47c6..432ad1c785e133ef18390108fd342be50ec4dddc 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/Sheep.java ++++ b/src/main/java/net/minecraft/world/entity/animal/Sheep.java +@@ -173,11 +173,18 @@ public class Sheep extends Animal implements Shearable { + + if (this.readyForShearing()) { + // CraftBukkit start +- if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) { +- return InteractionResult.PASS; ++ // Paper start - custom shear drops ++ java.util.List drops = this.generateDefaultDrops(worldserver, itemstack); ++ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); ++ if (event != null) { ++ if (event.isCancelled()) { ++ return InteractionResult.PASS; ++ } ++ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); ++ // Paper end - custom shear drops + } + // CraftBukkit end +- this.shear(worldserver, SoundSource.PLAYERS, itemstack); ++ this.shear(worldserver, SoundSource.PLAYERS, itemstack, drops); // Paper - custom shear drops + this.gameEvent(GameEvent.SHEAR, player); + itemstack.hurtAndBreak(1, player, getSlotForHand(hand)); + return InteractionResult.SUCCESS_SERVER; +@@ -192,9 +199,26 @@ public class Sheep extends Animal implements Shearable { + + @Override + public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears) { ++ // Paper start - custom shear drops ++ this.shear(world, shearedSoundCategory, shears, this.generateDefaultDrops(world, shears)); ++ } ++ ++ @Override ++ public java.util.List generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) { ++ final java.util.List drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); ++ this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.SHEAR_SHEEP, shears, (ignored, stack) -> { ++ for (int i = 0; i < stack.getCount(); ++i) drops.add(stack.copyWithCount(1)); ++ }); ++ return drops; ++ } ++ ++ @Override ++ public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears, java.util.List drops) { ++ final ServerLevel worldserver1 = world; // Named for lambda consumption ++ // Paper end - custom shear drops + world.playSound((Player) null, (Entity) this, SoundEvents.SHEEP_SHEAR, shearedSoundCategory, 1.0F, 1.0F); +- this.dropFromShearingLootTable(world, BuiltInLootTables.SHEAR_SHEEP, shears, (worldserver1, itemstack1) -> { +- for (int i = 0; i < itemstack1.getCount(); ++i) { ++ drops.forEach(itemstack1 -> { // Paper - custom drops - loop in generated default drops ++ if (true) { // Paper - custom drops - loop in generated default drops + this.forceDrops = true; // CraftBukkit + ItemEntity entityitem = this.spawnAtLocation(worldserver1, itemstack1.copyWithCount(1), 1.0F); + this.forceDrops = false; // CraftBukkit +diff --git a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java +index 975a9e35303bec29aedfbd554c38e4331cdfb174..fd9f6c17448a4d87f940eb8f544ecb9669068582 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java ++++ b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java +@@ -161,11 +161,18 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM + ServerLevel worldserver = (ServerLevel) world; + + // CraftBukkit start +- if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) { +- return InteractionResult.PASS; ++ // Paper start - custom shear drops ++ java.util.List drops = this.generateDefaultDrops(worldserver, itemstack); ++ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); ++ if (event != null) { ++ if (event.isCancelled()) { ++ return InteractionResult.PASS; ++ } ++ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); ++ // Paper end - custom shear drops + } + // CraftBukkit end +- this.shear(worldserver, SoundSource.PLAYERS, itemstack); ++ this.shear(worldserver, SoundSource.PLAYERS, itemstack, drops); // Paper - custom shear drops + this.gameEvent(GameEvent.SHEAR, player); + itemstack.hurtAndBreak(1, player, getSlotForHand(hand)); + } +@@ -178,9 +185,26 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM + + @Override + public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears) { ++ // Paper start - custom shear drops ++ this.shear(world, shearedSoundCategory, shears, this.generateDefaultDrops(world, shears)); ++ } ++ ++ @Override ++ public java.util.List generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) { ++ final java.util.List drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); ++ this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.SHEAR_SNOW_GOLEM, shears, (ignored, stack) -> { ++ drops.add(stack); ++ }); ++ return drops; ++ } ++ ++ @Override ++ public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears, java.util.List drops) { ++ final ServerLevel worldserver1 = world; // Named for lambda consumption ++ // Paper end - custom shear drops + world.playSound((Player) null, (Entity) this, SoundEvents.SNOW_GOLEM_SHEAR, shearedSoundCategory, 1.0F, 1.0F); + this.setPumpkin(false); +- this.dropFromShearingLootTable(world, BuiltInLootTables.SHEAR_SNOW_GOLEM, shears, (worldserver1, itemstack1) -> { ++ drops.forEach(itemstack1 -> { // Paper - custom shear drops + this.forceDrops = true; // CraftBukkit + this.spawnAtLocation(worldserver1, itemstack1, this.getEyeHeight()); + this.forceDrops = false; // CraftBukkit +diff --git a/src/main/java/net/minecraft/world/entity/monster/Bogged.java b/src/main/java/net/minecraft/world/entity/monster/Bogged.java +index 9d416f775fa19ad1978c7c9c9e0d5bc16728879d..18dae37d65552077aa3825c76f433bbd31152db9 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/Bogged.java ++++ b/src/main/java/net/minecraft/world/entity/monster/Bogged.java +@@ -27,6 +27,7 @@ import net.minecraft.world.item.Items; + import net.minecraft.world.level.Level; + import net.minecraft.world.level.gameevent.GameEvent; + import net.minecraft.world.level.storage.loot.BuiltInLootTables; ++import org.bukkit.craftbukkit.event.CraftEventFactory; + + public class Bogged extends AbstractSkeleton implements Shearable { + +@@ -80,12 +81,19 @@ public class Bogged extends AbstractSkeleton implements Shearable { + ServerLevel worldserver = (ServerLevel) world; + + // CraftBukkit start +- if (!org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) { +- this.getEntityData().markDirty(Bogged.DATA_SHEARED); // CraftBukkit - mark dirty to restore sheared state to clients +- return InteractionResult.PASS; ++ // Paper start - custom shear drops ++ java.util.List drops = this.generateDefaultDrops(worldserver, itemstack); ++ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); ++ if (event != null) { ++ if (event.isCancelled()) { ++ this.getEntityData().markDirty(Bogged.DATA_SHEARED); // CraftBukkit - mark dirty to restore sheared state to clients ++ return InteractionResult.PASS; ++ } ++ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); ++ // Paper end - custom shear drops + } + // CraftBukkit end +- this.shear(worldserver, SoundSource.PLAYERS, itemstack); ++ this.shear(worldserver, SoundSource.PLAYERS, itemstack, drops); // Paper - custom shear drops + this.gameEvent(GameEvent.SHEAR, player); + itemstack.hurtAndBreak(1, player, getSlotForHand(hand)); + } +@@ -139,13 +147,32 @@ public class Bogged extends AbstractSkeleton implements Shearable { + + @Override + public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears) { ++ // Paper start - custom shear drops ++ this.shear(world, shearedSoundCategory, shears, this.generateDefaultDrops(world, shears)); ++ } ++ ++ @Override ++ public java.util.List generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) { ++ final java.util.List drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(); ++ this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.BOGGED_SHEAR, shears, (ignored, stack) -> { ++ drops.add(stack); ++ }); ++ return drops; ++ } ++ ++ @Override ++ public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears, java.util.List drops) { ++ // Paper end - custom shear drops + world.playSound((Player) null, (Entity) this, SoundEvents.BOGGED_SHEAR, shearedSoundCategory, 1.0F, 1.0F); +- this.spawnShearedMushrooms(world, shears); ++ this.spawnShearedMushrooms(world, shears, drops); // Paper - custom shear drops + this.setSheared(true); + } + +- private void spawnShearedMushrooms(ServerLevel world, ItemStack shears) { +- this.dropFromShearingLootTable(world, BuiltInLootTables.BOGGED_SHEAR, shears, (worldserver1, itemstack1) -> { ++ // Paper start - custom shear drops ++ private void spawnShearedMushrooms(ServerLevel world, ItemStack shears, java.util.List drops) { ++ final ServerLevel worldserver1 = world; // Named for lambda consumption ++ drops.forEach(itemstack1 -> { ++ // Paper end - custom shear drops + this.spawnAtLocation(worldserver1, itemstack1, this.getBbHeight()); + }); + } +diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +index fb75b7f84575c42ab5dcb7e9c5659cecf439da90..89109bf9ad85b1859ce6ae0808ac0a1fb2cb6816 100644 +--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java ++++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +@@ -1689,20 +1689,20 @@ public class CraftEventFactory { + player.level().getCraftServer().getPluginManager().callEvent(event); + } + +- public static BlockShearEntityEvent callBlockShearEntityEvent(Entity animal, org.bukkit.block.Block dispenser, CraftItemStack is) { +- BlockShearEntityEvent bse = new BlockShearEntityEvent(dispenser, animal.getBukkitEntity(), is); ++ public static BlockShearEntityEvent callBlockShearEntityEvent(Entity animal, org.bukkit.block.Block dispenser, CraftItemStack is, List drops) { // Paper - custom shear drops ++ BlockShearEntityEvent bse = new BlockShearEntityEvent(dispenser, animal.getBukkitEntity(), is, Lists.transform(drops, CraftItemStack::asCraftMirror)); // Paper - custom shear drops + Bukkit.getPluginManager().callEvent(bse); + return bse; + } + +- public static boolean handlePlayerShearEntityEvent(net.minecraft.world.entity.player.Player player, Entity sheared, ItemStack shears, InteractionHand hand) { ++ public static PlayerShearEntityEvent handlePlayerShearEntityEvent(net.minecraft.world.entity.player.Player player, Entity sheared, ItemStack shears, InteractionHand hand, List drops) { // Paper - custom shear drops + if (!(player instanceof ServerPlayer)) { +- return true; ++ return null; // Paper - custom shear drops + } + +- PlayerShearEntityEvent event = new PlayerShearEntityEvent((Player) player.getBukkitEntity(), sheared.getBukkitEntity(), CraftItemStack.asCraftMirror(shears), (hand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND)); ++ PlayerShearEntityEvent event = new PlayerShearEntityEvent((Player) player.getBukkitEntity(), sheared.getBukkitEntity(), CraftItemStack.asCraftMirror(shears), (hand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND), Lists.transform(drops, CraftItemStack::asCraftMirror)); // Paper - custom shear drops + Bukkit.getPluginManager().callEvent(event); +- return !event.isCancelled(); ++ return event; // Paper - custom shear drops + } + + public static Cancellable handleStatisticsIncrease(net.minecraft.world.entity.player.Player entityHuman, net.minecraft.stats.Stat statistic, int current, int newValue) { +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +index 0b7bc5e83634a26ac6521694377b554c74c6bff0..ffd7ba14be38a117f5a7d7035a8d71a20fb1c4fc 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +@@ -74,6 +74,16 @@ public final class CraftItemStack extends ItemStack { + return stack; + } + ++ // Paper start ++ public static java.util.List asNMSCopy(java.util.List originals) { ++ final java.util.List items = new java.util.ArrayList<>(originals.size()); ++ for (final ItemStack original : originals) { ++ items.add(asNMSCopy(original)); ++ } ++ return items; ++ } ++ // Paper end ++ + public static net.minecraft.world.item.ItemStack copyNMSStack(net.minecraft.world.item.ItemStack original, int amount) { + net.minecraft.world.item.ItemStack stack = original.copy(); + stack.setCount(amount); +diff --git a/src/test/java/io/papermc/paper/entity/ShearableDropsTest.java b/src/test/java/io/papermc/paper/entity/ShearableDropsTest.java +new file mode 100644 +index 0000000000000000000000000000000000000000..5e6dfc93c86ec369b686f15ca066478e1635dbc3 +--- /dev/null ++++ b/src/test/java/io/papermc/paper/entity/ShearableDropsTest.java +@@ -0,0 +1,35 @@ ++package io.papermc.paper.entity; ++ ++import io.github.classgraph.ClassGraph; ++import io.github.classgraph.ClassInfo; ++import io.github.classgraph.MethodInfoList; ++import io.github.classgraph.ScanResult; ++import java.util.ArrayList; ++import net.minecraft.world.entity.Shearable; ++import org.bukkit.support.environment.Normal; ++import org.junit.jupiter.params.ParameterizedTest; ++import org.junit.jupiter.params.provider.MethodSource; ++ ++import static org.junit.jupiter.api.Assertions.assertEquals; ++ ++@Normal ++class ShearableDropsTest { ++ ++ static Iterable parameters() { ++ try (ScanResult scanResult = new ClassGraph() ++ .enableClassInfo() ++ .enableMethodInfo() ++ .whitelistPackages("net.minecraft") ++ .scan() ++ ) { ++ return new ArrayList<>(scanResult.getClassesImplementing(Shearable.class.getName())); ++ } ++ } ++ ++ @ParameterizedTest ++ @MethodSource("parameters") ++ void checkShearableDropOverrides(final ClassInfo classInfo) { ++ final MethodInfoList generateDefaultDrops = classInfo.getDeclaredMethodInfo("generateDefaultDrops"); ++ assertEquals(1, generateDefaultDrops.size(), classInfo.getName() + " doesn't implement Shearable#generateDefaultDrops"); ++ } ++} diff --git a/patches/unapplied/server/0884-Do-not-read-tile-entities-in-chunks-that-are-positio.patch b/patches/unapplied/server/0884-Do-not-read-tile-entities-in-chunks-that-are-positio.patch deleted file mode 100644 index ab4d61b97a7c..000000000000 --- a/patches/unapplied/server/0884-Do-not-read-tile-entities-in-chunks-that-are-positio.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Sun, 18 Jun 2023 23:04:46 -0700 -Subject: [PATCH] Do not read tile entities in chunks that are positioned - outside of the chunk - -The tile entities are not accessible and so should not be loaded. -This can happen as a result of users moving regionfiles around, -which would cause a crash on Folia but would appear to function -fine on Paper. - -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index 5e1a68e3a920aab10a459b9b54f6abd59e7855e0..d42585bccb03f8ee1be5e37cfbe8520af4cc5454 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -@@ -303,6 +303,13 @@ public class ChunkSerializer { - for (int k1 = 0; k1 < nbttaglist3.size(); ++k1) { - CompoundTag nbttagcompound4 = nbttaglist3.getCompound(k1); - -+ // Paper start - do not read tile entities positioned outside the chunk -+ BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound4); -+ if ((blockposition.getX() >> 4) != chunkPos.x || (blockposition.getZ() >> 4) != chunkPos.z) { -+ LOGGER.warn("Tile entity serialized in chunk " + chunkPos + " in world '" + world.getWorld().getName() + "' positioned at " + blockposition + " is located outside of the chunk"); -+ continue; -+ } -+ // Paper end - do not read tile entities positioned outside the chunk - ((ChunkAccess) object1).setBlockEntityNbt(nbttagcompound4); - } - -@@ -507,10 +514,19 @@ public class ChunkSerializer { - CompoundTag nbttagcompound1 = nbttaglist1.getCompound(i); - boolean flag = nbttagcompound1.getBoolean("keepPacked"); - -+ // Paper start - do not read tile entities positioned outside the chunk -+ BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound1); // moved up -+ ChunkPos chunkPos = chunk.getPos(); -+ if ((blockposition.getX() >> 4) != chunkPos.x || (blockposition.getZ() >> 4) != chunkPos.z) { -+ LOGGER.warn("Tile entity serialized in chunk " + chunkPos + " in world '" + world.getWorld().getName() + "' positioned at " + blockposition + " is located outside of the chunk"); -+ continue; -+ } -+ // Paper end - do not read tile entities positioned outside the chunk -+ - if (flag) { - chunk.setBlockEntityNbt(nbttagcompound1); - } else { -- BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound1); -+ // Paper - do not read tile entities positioned outside the chunk; move up - BlockEntity tileentity = BlockEntity.loadStatic(blockposition, chunk.getBlockState(blockposition), nbttagcompound1, world.registryAccess()); - - if (tileentity != null) { diff --git a/patches/unapplied/server/0916-Add-drops-to-shear-events.patch b/patches/unapplied/server/0916-Add-drops-to-shear-events.patch deleted file mode 100644 index 8e1e2cd3f9a7..000000000000 --- a/patches/unapplied/server/0916-Add-drops-to-shear-events.patch +++ /dev/null @@ -1,411 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Tue, 18 May 2021 12:32:02 -0700 -Subject: [PATCH] Add drops to shear events - - -diff --git a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java -index f32f8d5cb22feb885a53d3b56c04ad4219d2bafa..44b79a7c2f8b95a484d1999fa2167ce588f7985b 100644 ---- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java -+++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java -@@ -103,11 +103,14 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior { - if (entityliving instanceof Shearable ishearable) { - if (ishearable.readyForShearing()) { - // CraftBukkit start -- if (CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem).isCancelled()) { -+ // Paper start - Add drops to shear events -+ org.bukkit.event.block.BlockShearEntityEvent event = CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem, ishearable.generateDefaultDrops()); -+ if (event.isCancelled()) { -+ // Paper end - Add drops to shear events - continue; - } - // CraftBukkit end -- ishearable.shear(SoundSource.BLOCKS); -+ ishearable.shear(SoundSource.BLOCKS, CraftItemStack.asNMSCopy(event.getDrops())); // Paper - Add drops to shear events - worldserver.gameEvent((Entity) null, (Holder) GameEvent.SHEAR, blockposition); - return true; - } -diff --git a/src/main/java/net/minecraft/world/entity/Shearable.java b/src/main/java/net/minecraft/world/entity/Shearable.java -index 5e8cc5cfac8888628c6d513148f41be09ca65a2c..2ee48ac3b665db2b02bcb1a30ec972d43a3725b0 100644 ---- a/src/main/java/net/minecraft/world/entity/Shearable.java -+++ b/src/main/java/net/minecraft/world/entity/Shearable.java -@@ -3,7 +3,13 @@ package net.minecraft.world.entity; - import net.minecraft.sounds.SoundSource; - - public interface Shearable { -+ default void shear(SoundSource soundCategory, java.util.List drops) { this.shear(soundCategory); } // Paper - Add drops to shear events - void shear(SoundSource shearedSoundCategory); - - boolean readyForShearing(); -+ // Paper start - custom shear drops; ensure all implementing entities override this -+ default java.util.List generateDefaultDrops() { -+ return java.util.Collections.emptyList(); -+ } -+ // Paper end - custom shear drops - } -diff --git a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java -index aa125e3043b120935aaa015803f065f99eb8d050..0c21959f57ae88fcd0a4d6dc911c1ce347c96528 100644 ---- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java -+++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java -@@ -123,11 +123,18 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder drops = this.generateDefaultDrops(); -+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); -+ if (event != null) { -+ if (event.isCancelled()) { -+ return InteractionResult.PASS; -+ } -+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); - } -+ // Paper end - custom shear drops - // CraftBukkit end -- this.shear(SoundSource.PLAYERS); -+ this.shear(SoundSource.PLAYERS, drops); // Paper - custom shear drops - this.gameEvent(GameEvent.SHEAR, player); - if (!this.level().isClientSide) { - itemstack.hurtAndBreak(1, player, getSlotForHand(hand)); -@@ -164,6 +171,22 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder generateDefaultDrops() { -+ java.util.List dropEntities = new java.util.ArrayList<>(5); -+ for (int i = 0; i < 5; ++i) { -+ dropEntities.add(new ItemStack(this.getVariant().getBlockState().getBlock())); -+ } -+ return dropEntities; -+ } -+ -+ @Override -+ public void shear(SoundSource shearedSoundCategory, java.util.List drops) { // If drops is null, need to generate drops -+ // Paper end - custom shear drops - this.level().playSound((Player) null, (Entity) this, SoundEvents.MOOSHROOM_SHEAR, shearedSoundCategory, 1.0F, 1.0F); - if (!this.level().isClientSide()) { - Cow entitycow = (Cow) EntityType.COW.create(this.level()); -@@ -193,17 +216,12 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder drops = this.generateDefaultDrops(); -+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); -+ if (event != null) { -+ if (event.isCancelled()) { -+ return InteractionResult.PASS; -+ } -+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); - } -+ // Paper end - custom shear drops - // CraftBukkit end -- this.shear(SoundSource.PLAYERS); -+ this.shear(SoundSource.PLAYERS, drops); // Paper - this.gameEvent(GameEvent.SHEAR, player); - itemstack.hurtAndBreak(1, player, getSlotForHand(hand)); - return InteractionResult.SUCCESS; -@@ -274,13 +281,30 @@ public class Sheep extends Animal implements Shearable { - - @Override - public void shear(SoundSource shearedSoundCategory) { -+ // Paper start - custom shear drops -+ this.shear(shearedSoundCategory, this.generateDefaultDrops()); -+ } -+ -+ @Override -+ public java.util.List generateDefaultDrops() { -+ int count = 1 + this.random.nextInt(3); -+ java.util.List dropEntities = new java.util.ArrayList<>(count); -+ for (int j = 0; j < count; ++j) { -+ dropEntities.add(new ItemStack(Sheep.ITEM_BY_DYE.get(this.getColor()))); -+ } -+ return dropEntities; -+ } -+ -+ @Override -+ public void shear(SoundSource shearedSoundCategory, java.util.List drops) { -+ // Paper end - custom shear drops - this.level().playSound((Player) null, (Entity) this, SoundEvents.SHEEP_SHEAR, shearedSoundCategory, 1.0F, 1.0F); - this.setSheared(true); - int i = 1 + this.random.nextInt(3); - -- for (int j = 0; j < i; ++j) { -+ for (final ItemStack drop : drops) { // Paper - custom shear drops (moved drop generation to separate method) - this.forceDrops = true; // CraftBukkit -- ItemEntity entityitem = this.spawnAtLocation((ItemLike) Sheep.ITEM_BY_DYE.get(this.getColor()), 1); -+ ItemEntity entityitem = this.spawnAtLocation(drop, 1); // Paper - custom shear drops - this.forceDrops = false; // CraftBukkit - - if (entityitem != null) { -diff --git a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java -index 2de1a2f666da9db1832907e1651dbff948e37252..5c2ed3c39c8eb850f3be1e2ea5b5a7ea266e16d1 100644 ---- a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java -+++ b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java -@@ -146,11 +146,18 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM - - if (itemstack.is(Items.SHEARS) && this.readyForShearing()) { - // CraftBukkit start -- if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) { -- return InteractionResult.PASS; -+ // Paper start - custom shear drops -+ java.util.List drops = this.generateDefaultDrops(); -+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); -+ if (event != null) { -+ if (event.isCancelled()) { -+ return InteractionResult.PASS; -+ } -+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); - } -+ // Paper end - custom shear drops - // CraftBukkit end -- this.shear(SoundSource.PLAYERS); -+ this.shear(SoundSource.PLAYERS, drops); // Paper - this.gameEvent(GameEvent.SHEAR, player); - if (!this.level().isClientSide) { - itemstack.hurtAndBreak(1, player, getSlotForHand(hand)); -@@ -164,12 +171,28 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM - - @Override - public void shear(SoundSource shearedSoundCategory) { -+ // Paper start - custom shear drops -+ this.shear(shearedSoundCategory, this.generateDefaultDrops()); -+ } -+ -+ @Override -+ public java.util.List generateDefaultDrops() { -+ return java.util.Collections.singletonList(new ItemStack(Items.CARVED_PUMPKIN)); -+ } -+ -+ @Override -+ public void shear(SoundSource shearedSoundCategory, java.util.List drops) { -+ // Paper end - custom shear drops - this.level().playSound((Player) null, (Entity) this, SoundEvents.SNOW_GOLEM_SHEAR, shearedSoundCategory, 1.0F, 1.0F); - if (!this.level().isClientSide()) { - this.setPumpkin(false); -- this.forceDrops = true; // CraftBukkit -- this.spawnAtLocation(new ItemStack(Items.CARVED_PUMPKIN), this.getEyeHeight()); -- this.forceDrops = false; // CraftBukkit -+ // Paper start - custom shear drops (moved drop generation to separate method) -+ for (final ItemStack drop : drops) { -+ this.forceDrops = true; -+ this.spawnAtLocation(drop, this.getEyeHeight()); -+ this.forceDrops = false; -+ } -+ // Paper end - custom shear drops - } - - } -diff --git a/src/main/java/net/minecraft/world/entity/monster/Bogged.java b/src/main/java/net/minecraft/world/entity/monster/Bogged.java -index dc6230458e09f7555eee7f6a567ff60ad454666b..9d50b9ac8084f3db1844cc7ad1ce9153614ff9d9 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/Bogged.java -+++ b/src/main/java/net/minecraft/world/entity/monster/Bogged.java -@@ -80,12 +80,19 @@ public class Bogged extends AbstractSkeleton implements Shearable { - - if (itemstack.is(Items.SHEARS) && this.readyForShearing()) { - // CraftBukkit start -- if (!org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) { -- this.getEntityData().markDirty(Bogged.DATA_SHEARED); // CraftBukkit - mark dirty to restore sheared state to clients -- return InteractionResult.PASS; -+ // Paper start - expose drops in event -+ java.util.List drops = generateDefaultDrops(); -+ final org.bukkit.event.player.PlayerShearEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); -+ if (event != null) { -+ if (event.isCancelled()) { -+ if (player instanceof final net.minecraft.server.level.ServerPlayer serverPlayer) this.resendPossiblyDesyncedDataValues(java.util.List.of(Bogged.DATA_SHEARED), serverPlayer); -+ return InteractionResult.PASS; -+ } -+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); -+ // Paper end - expose drops in event - } - // CraftBukkit end -- this.shear(SoundSource.PLAYERS); -+ this.shear(SoundSource.PLAYERS, drops); // Paper - expose drops in event - this.gameEvent(GameEvent.SHEAR, player); - if (!this.level().isClientSide) { - itemstack.hurtAndBreak(1, player, getSlotForHand(hand)); -@@ -140,12 +147,31 @@ public class Bogged extends AbstractSkeleton implements Shearable { - - @Override - public void shear(SoundSource shearedSoundCategory) { -+ // Paper start - shear drop API -+ this.shear(shearedSoundCategory, generateDefaultDrops()); -+ } -+ -+ @Override -+ public void shear(SoundSource shearedSoundCategory, java.util.List drops) { -+ // Paper end - shear drop API - this.level().playSound((Player) null, (Entity) this, SoundEvents.BOGGED_SHEAR, shearedSoundCategory, 1.0F, 1.0F); -- this.spawnShearedMushrooms(); -+ this.spawnDrops(drops); // Paper - shear drop API - this.setSheared(true); - } - - private void spawnShearedMushrooms() { -+ // Paper start - shear drops API -+ this.spawnDrops(generateDefaultDrops()); // Only here for people calling spawnSheardMushrooms. Not used otherwise. -+ } -+ private void spawnDrops(java.util.List drops) { -+ drops.forEach(stack -> { -+ this.forceDrops = true; -+ this.spawnAtLocation(stack, this.getBbHeight()); -+ this.forceDrops = false; -+ }); -+ } -+ private void generateShearedMushrooms(java.util.function.Consumer stackConsumer) { -+ // Paper end - shear drops API - Level world = this.level(); - - if (world instanceof ServerLevel worldserver) { -@@ -156,12 +182,21 @@ public class Bogged extends AbstractSkeleton implements Shearable { - while (objectlistiterator.hasNext()) { - ItemStack itemstack = (ItemStack) objectlistiterator.next(); - -- this.spawnAtLocation(itemstack, this.getBbHeight()); -+ stackConsumer.accept(itemstack); // Paper - } - } - - } - -+ // Paper start - shear drops API -+ @Override -+ public java.util.List generateDefaultDrops() { -+ final java.util.List drops = new java.util.ArrayList<>(); -+ this.generateShearedMushrooms(drops::add); -+ return drops; -+ } -+ // Paper end - shear drops API -+ - @Override - public boolean readyForShearing() { - return !this.isSheared() && this.isAlive(); -diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index f529243852df8e193a604bb6d895333848b14a74..d407e9e8f1b530f00e632e0249514fb68d48316b 100644 ---- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1691,20 +1691,20 @@ public class CraftEventFactory { - player.level().getCraftServer().getPluginManager().callEvent(event); - } - -- public static BlockShearEntityEvent callBlockShearEntityEvent(Entity animal, org.bukkit.block.Block dispenser, CraftItemStack is) { -- BlockShearEntityEvent bse = new BlockShearEntityEvent(dispenser, animal.getBukkitEntity(), is); -+ public static BlockShearEntityEvent callBlockShearEntityEvent(Entity animal, org.bukkit.block.Block dispenser, CraftItemStack is, List drops) { // Paper - custom shear drops -+ BlockShearEntityEvent bse = new BlockShearEntityEvent(dispenser, animal.getBukkitEntity(), is, Lists.transform(drops, CraftItemStack::asCraftMirror)); // Paper - custom shear drops - Bukkit.getPluginManager().callEvent(bse); - return bse; - } - -- public static boolean handlePlayerShearEntityEvent(net.minecraft.world.entity.player.Player player, Entity sheared, ItemStack shears, InteractionHand hand) { -+ public static PlayerShearEntityEvent handlePlayerShearEntityEvent(net.minecraft.world.entity.player.Player player, Entity sheared, ItemStack shears, InteractionHand hand, List drops) { // Paper - custom shear drops - if (!(player instanceof ServerPlayer)) { -- return true; -+ return null; // Paper - custom shear drops - } - -- PlayerShearEntityEvent event = new PlayerShearEntityEvent((Player) player.getBukkitEntity(), sheared.getBukkitEntity(), CraftItemStack.asCraftMirror(shears), (hand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND)); -+ PlayerShearEntityEvent event = new PlayerShearEntityEvent((Player) player.getBukkitEntity(), sheared.getBukkitEntity(), CraftItemStack.asCraftMirror(shears), (hand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND), Lists.transform(drops, CraftItemStack::asCraftMirror)); // Paper - custom shear drops - Bukkit.getPluginManager().callEvent(event); -- return !event.isCancelled(); -+ return event; // Paper - custom shear drops - } - - public static Cancellable handleStatisticsIncrease(net.minecraft.world.entity.player.Player entityHuman, net.minecraft.stats.Stat statistic, int current, int newValue) { -diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index f33742ee06e8443a5f5adaaa987d7523dc193b5a..a1a32a77bda0560a7b7f30a5d1c1837ee96997d3 100644 ---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -@@ -69,6 +69,16 @@ public final class CraftItemStack extends ItemStack { - return stack; - } - -+ // Paper start -+ public static java.util.List asNMSCopy(java.util.List originals) { -+ final java.util.List items = new java.util.ArrayList<>(originals.size()); -+ for (final ItemStack original : originals) { -+ items.add(asNMSCopy(original)); -+ } -+ return items; -+ } -+ // Paper end -+ - public static net.minecraft.world.item.ItemStack copyNMSStack(net.minecraft.world.item.ItemStack original, int amount) { - net.minecraft.world.item.ItemStack stack = original.copy(); - stack.setCount(amount); -diff --git a/src/test/java/io/papermc/paper/entity/ShearableDropsTest.java b/src/test/java/io/papermc/paper/entity/ShearableDropsTest.java -new file mode 100644 -index 0000000000000000000000000000000000000000..5e6dfc93c86ec369b686f15ca066478e1635dbc3 ---- /dev/null -+++ b/src/test/java/io/papermc/paper/entity/ShearableDropsTest.java -@@ -0,0 +1,35 @@ -+package io.papermc.paper.entity; -+ -+import io.github.classgraph.ClassGraph; -+import io.github.classgraph.ClassInfo; -+import io.github.classgraph.MethodInfoList; -+import io.github.classgraph.ScanResult; -+import java.util.ArrayList; -+import net.minecraft.world.entity.Shearable; -+import org.bukkit.support.environment.Normal; -+import org.junit.jupiter.params.ParameterizedTest; -+import org.junit.jupiter.params.provider.MethodSource; -+ -+import static org.junit.jupiter.api.Assertions.assertEquals; -+ -+@Normal -+class ShearableDropsTest { -+ -+ static Iterable parameters() { -+ try (ScanResult scanResult = new ClassGraph() -+ .enableClassInfo() -+ .enableMethodInfo() -+ .whitelistPackages("net.minecraft") -+ .scan() -+ ) { -+ return new ArrayList<>(scanResult.getClassesImplementing(Shearable.class.getName())); -+ } -+ } -+ -+ @ParameterizedTest -+ @MethodSource("parameters") -+ void checkShearableDropOverrides(final ClassInfo classInfo) { -+ final MethodInfoList generateDefaultDrops = classInfo.getDeclaredMethodInfo("generateDefaultDrops"); -+ assertEquals(1, generateDefaultDrops.size(), classInfo.getName() + " doesn't implement Shearable#generateDefaultDrops"); -+ } -+} From 26f7b4c72efc27c264ec6576a8ef0f1155e20424 Mon Sep 17 00:00:00 2001 From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Date: Thu, 24 Oct 2024 09:25:36 -0400 Subject: [PATCH 037/119] Patch --- .../0910-Add-PlayerShieldDisableEvent.patch} | 28 ++++++------ ...ate-ResourceLocation-in-NBT-reading.patch} | 45 +++++++++---------- ...-experience-dropping-on-block-break.patch} | 14 +++--- .../0913-Fixup-NamespacedKey-handling.patch} | 6 +-- ...14-Expose-LootTable-of-DecoratedPot.patch} | 0 ...location-of-Vec3D-by-entity-tracker.patch} | 36 +++++++-------- ...rTradeEvent-and-PlayerPurchaseEvent.patch} | 20 ++++----- .../0917-Add-ShulkerDuplicateEvent.patch} | 4 +- ...dd-api-for-spawn-egg-texture-colors.patch} | 2 +- 9 files changed, 77 insertions(+), 78 deletions(-) rename patches/{unapplied/server/0917-Add-PlayerShieldDisableEvent.patch => server/0910-Add-PlayerShieldDisableEvent.patch} (67%) rename patches/{unapplied/server/0918-Validate-ResourceLocation-in-NBT-reading.patch => server/0911-Validate-ResourceLocation-in-NBT-reading.patch} (82%) rename patches/{unapplied/server/0919-Properly-handle-experience-dropping-on-block-break.patch => server/0912-Properly-handle-experience-dropping-on-block-break.patch} (91%) rename patches/{unapplied/server/0920-Fixup-NamespacedKey-handling.patch => server/0913-Fixup-NamespacedKey-handling.patch} (97%) rename patches/{unapplied/server/0921-Expose-LootTable-of-DecoratedPot.patch => server/0914-Expose-LootTable-of-DecoratedPot.patch} (100%) rename patches/{unapplied/server/0922-Reduce-allocation-of-Vec3D-by-entity-tracker.patch => server/0915-Reduce-allocation-of-Vec3D-by-entity-tracker.patch} (66%) rename patches/{unapplied/server/0923-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch => server/0916-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch} (94%) rename patches/{unapplied/server/0924-Add-ShulkerDuplicateEvent.patch => server/0917-Add-ShulkerDuplicateEvent.patch} (88%) rename patches/{unapplied/server/0925-Add-api-for-spawn-egg-texture-colors.patch => server/0918-Add-api-for-spawn-egg-texture-colors.patch} (93%) diff --git a/patches/unapplied/server/0917-Add-PlayerShieldDisableEvent.patch b/patches/server/0910-Add-PlayerShieldDisableEvent.patch similarity index 67% rename from patches/unapplied/server/0917-Add-PlayerShieldDisableEvent.patch rename to patches/server/0910-Add-PlayerShieldDisableEvent.patch index 5bbd9b6ff69a..d2d860a0284e 100644 --- a/patches/unapplied/server/0917-Add-PlayerShieldDisableEvent.patch +++ b/patches/server/0910-Add-PlayerShieldDisableEvent.patch @@ -16,36 +16,36 @@ sideeffects, meaning the disable event cannot share a handlerlist with the cooldown event diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index 454b29d8c9e42e328933aa578f49d28f1e77898a..d0b51d96d6795b5fa03bc195b90324680545b752 100644 +index a19a795deaa7f46c92b97912e2ade006bc90c2d5..61d412c4f1ebd55661cc3f0260468e3ac0efe0bb 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -1005,7 +1005,7 @@ public abstract class Player extends LivingEntity { - protected void blockUsingShield(LivingEntity attacker) { - super.blockUsingShield(attacker); - if (attacker.canDisableShield()) { -- this.disableShield(); -+ this.disableShield(attacker); // Paper - Add PlayerShieldDisableEvent +@@ -970,7 +970,7 @@ public abstract class Player extends LivingEntity { + ItemStack itemstack = this.getItemBlockingWith(); + + if (attacker.canDisableShield() && itemstack != null) { +- this.disableShield(itemstack); ++ this.disableShield(itemstack, attacker); // Paper - Add PlayerShieldDisableEvent } } -@@ -1498,8 +1498,21 @@ public abstract class Player extends LivingEntity { +@@ -1463,8 +1463,21 @@ public abstract class Player extends LivingEntity { this.attack(target); } + @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - Add PlayerShieldDisableEvent - public void disableShield() { -- this.getCooldowns().addCooldown(Items.SHIELD, 100); + public void disableShield(ItemStack shield) { +- this.getCooldowns().addCooldown(shield, 100); + // Paper start - Add PlayerShieldDisableEvent -+ this.disableShield(null); ++ this.disableShield(shield, null); + } -+ public void disableShield(@Nullable LivingEntity attacker) { ++ public void disableShield(ItemStack shield, @Nullable LivingEntity attacker) { + final org.bukkit.entity.Entity finalAttacker = attacker != null ? attacker.getBukkitEntity() : null; + if (finalAttacker != null) { + final io.papermc.paper.event.player.PlayerShieldDisableEvent shieldDisableEvent = new io.papermc.paper.event.player.PlayerShieldDisableEvent((org.bukkit.entity.Player) getBukkitEntity(), finalAttacker, 100); + if (!shieldDisableEvent.callEvent()) return; -+ this.getCooldowns().addCooldown(Items.SHIELD, shieldDisableEvent.getCooldown()); ++ this.getCooldowns().addCooldown(shield, shieldDisableEvent.getCooldown()); + } else { -+ this.getCooldowns().addCooldown(Items.SHIELD, 100); ++ this.getCooldowns().addCooldown(shield, 100); + } + // Paper end - Add PlayerShieldDisableEvent this.stopUsingItem(); diff --git a/patches/unapplied/server/0918-Validate-ResourceLocation-in-NBT-reading.patch b/patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch similarity index 82% rename from patches/unapplied/server/0918-Validate-ResourceLocation-in-NBT-reading.patch rename to patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch index 923bdbe37db3..e0dee7a8de7c 100644 --- a/patches/unapplied/server/0918-Validate-ResourceLocation-in-NBT-reading.patch +++ b/patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch @@ -53,10 +53,10 @@ index 084935138b1484f3d96e99f4e5655a6c04931907..9e357abe13f55bd9ce3a1d5348bcf19a if (nbt.contains("LootTableSeed", 4)) { this.setLootTableSeed(nbt.getLong("LootTableSeed")); diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index b98f9246b60daf31460f41ce214dfa7c011f5684..842b0cec0397d7ae5166617627340ffac0e35db1 100644 +index 4eec58353343b414120e189afed04b98ae3e87c8..d77014aadf83088fb53f30a9dbe879f3089e159e 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -623,7 +623,7 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -690,7 +690,7 @@ public class EntityType implements FeatureElement, EntityTypeT } public static Optional> by(CompoundTag nbt) { @@ -66,10 +66,10 @@ index b98f9246b60daf31460f41ce214dfa7c011f5684..842b0cec0397d7ae5166617627340ffa @Nullable diff --git a/src/main/java/net/minecraft/world/entity/Leashable.java b/src/main/java/net/minecraft/world/entity/Leashable.java -index e7535f15be3cc1537aafee53779ccfb4f21d1f38..bd6d587cedfe0e345536d7ebb6b7ca204f073efe 100644 +index 1a6448cccf79a94013f9f44c3067d91da3da1f7e..06af888e4c3d9d01a462b487742b597184a7a8a6 100644 --- a/src/main/java/net/minecraft/world/entity/Leashable.java +++ b/src/main/java/net/minecraft/world/entity/Leashable.java -@@ -54,7 +54,13 @@ public interface Leashable { +@@ -55,7 +55,13 @@ public interface Leashable { @Nullable default Leashable.LeashData readLeashData(CompoundTag nbt) { if (nbt.contains("leash", 10)) { @@ -85,10 +85,10 @@ index e7535f15be3cc1537aafee53779ccfb4f21d1f38..bd6d587cedfe0e345536d7ebb6b7ca20 if (nbt.contains("leash", 11)) { Either either = (Either) NbtUtils.readBlockPos(nbt, "leash").map(Either::right).orElse(null); // CraftBukkit - decompile error diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 13ef1ad250b56dbadba0244186e369d7ba9b5c0e..94169703c5a8111df1ed550d57f59f4a3bb97ae1 100644 +index f42a98324ecfc992cf36c2f44cdb781ad4edbad4..a7f0d49637eb72b4645997a97cc6927b16a59738 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -887,11 +887,13 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -911,11 +911,13 @@ public abstract class LivingEntity extends Entity implements Attackable { if (nbt.contains("SleepingX", 99) && nbt.contains("SleepingY", 99) && nbt.contains("SleepingZ", 99)) { BlockPos blockposition = new BlockPos(nbt.getInt("SleepingX"), nbt.getInt("SleepingY"), nbt.getInt("SleepingZ")); @@ -103,23 +103,23 @@ index 13ef1ad250b56dbadba0244186e369d7ba9b5c0e..94169703c5a8111df1ed550d57f59f4a if (nbt.contains("Brain", 10)) { diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index cf1f6a0081f0dbcf43842ec23accf6c3ae9b79d8..58ff5b4df2124901df757315e42b2490a7da7415 100644 +index 8a0e65ac8318a467996f48b423db1ac621359fbe..aad63549d7c4f501b683b8dead4938eac27895eb 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -603,7 +603,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -601,7 +601,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab this.leashData = this.readLeashData(nbt); this.setLeftHanded(nbt.getBoolean("LeftHanded")); if (nbt.contains("DeathLootTable", 8)) { -- this.lootTable = ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(nbt.getString("DeathLootTable"))); -+ this.lootTable = net.minecraft.Optionull.map(ResourceLocation.tryParse(nbt.getString("DeathLootTable")), rl -> ResourceKey.create(Registries.LOOT_TABLE, rl)); // Paper - Validate ResourceLocation +- this.lootTable = Optional.of(ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(nbt.getString("DeathLootTable")))); ++ this.lootTable = Optional.ofNullable(ResourceLocation.tryParse(nbt.getString("DeathLootTable"))).map((rs) -> ResourceKey.create(Registries.LOOT_TABLE, rs)); // Paper - Validate ResourceLocation this.lootTableSeed = nbt.getLong("DeathLootTableSeed"); } diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -index 10d30304c8c89b1f2a55be8529035311d1424e44..ddf47dab1ab92c45e3eea09239d418a9798ed59e 100644 +index 75cc3db39c974abab8510af4a633fc6812efc647..14e31ae88e90d8ea1a98800cc6c1c3527bb2ed6b 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -@@ -649,7 +649,7 @@ public abstract class AbstractArrow extends Projectile { +@@ -695,7 +695,7 @@ public abstract class AbstractArrow extends Projectile { this.setCritArrow(nbt.getBoolean("crit")); this.setPierceLevel(nbt.getByte("PierceLevel")); if (nbt.contains("SoundEvent", 8)) { @@ -129,41 +129,40 @@ index 10d30304c8c89b1f2a55be8529035311d1424e44..ddf47dab1ab92c45e3eea09239d418a9 if (nbt.contains("item", 10)) { diff --git a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java -index ccc7367ab2740bea0f2b907223a0920b11665092..845eff7401b811c179dc9dee70eca0d724be5c80 100644 +index 5c78e33d4d369700a5fa6eb3cbbe85756465a063..35f90e06dcf30c2e6a2a63e81215283ffbb3ec05 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java @@ -73,7 +73,7 @@ public interface ContainerEntity extends Container, MenuProvider { - default void readChestVehicleSaveData(CompoundTag nbt, HolderLookup.Provider registriesLookup) { + default void readChestVehicleSaveData(CompoundTag nbt, HolderLookup.Provider registries) { this.clearItemStacks(); if (nbt.contains("LootTable", 8)) { -- this.setLootTable(ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(nbt.getString("LootTable")))); -+ this.setLootTable(net.minecraft.Optionull.map(ResourceLocation.tryParse(nbt.getString("LootTable")), rl -> ResourceKey.create(Registries.LOOT_TABLE, rl))); // Paper - Validate ResourceLocation +- this.setContainerLootTable(ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(nbt.getString("LootTable")))); ++ this.setContainerLootTable(net.minecraft.Optionull.map(ResourceLocation.tryParse(nbt.getString("LootTable")), rl -> ResourceKey.create(Registries.LOOT_TABLE, rl))); // Paper - Validate ResourceLocation // Paper start - LootTable API if (this.getLootTable() != null) { this.lootableData().loadNbt(nbt); diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index 65ab9b22f724877b68f4f25aad2831e2cb080b19..730aca233f6e7564d4cb85b5b628d23c4f01d2f4 100644 +index ecb9abc570ef87541184a8033cb33c82a4d1daf2..a1ac34668fcd53cf8adf4ce463e0254b26575fbf 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -@@ -295,7 +295,12 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -180,7 +180,11 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit while (iterator.hasNext()) { String s = (String) iterator.next(); -- this.recipesUsed.put(ResourceLocation.parse(s), nbttagcompound1.getInt(s)); +- this.recipesUsed.put(ResourceKey.create(Registries.RECIPE, ResourceLocation.parse(s)), nbttagcompound1.getInt(s)); + // Paper start - Validate ResourceLocation + final ResourceLocation resourceLocation = ResourceLocation.tryParse(s); + if (resourceLocation != null) { -+ this.recipesUsed.put(resourceLocation, nbttagcompound1.getInt(s)); ++ this.recipesUsed.put(ResourceKey.create(Registries.RECIPE, resourceLocation), nbttagcompound1.getInt(s)); + } -+ // Paper end - Validate ResourceLocation } // Paper start - cook speed multiplier API diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java -index 32de29c385c784ab87e29b2e072f3992386cd775..dc02a3d84b397f634f77f4df9c06e245cc4dcb75 100644 +index 1bfffbf54b1b440c6e19a908ea2bd70387d06b5c..b08867878e56f88569d547765f29cab018a9e791 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java -@@ -202,7 +202,7 @@ public class BrushableBlockEntity extends BlockEntity { +@@ -194,7 +194,7 @@ public class BrushableBlockEntity extends BlockEntity { private boolean tryLoadLootTable(CompoundTag nbt) { if (nbt.contains("LootTable", 8)) { diff --git a/patches/unapplied/server/0919-Properly-handle-experience-dropping-on-block-break.patch b/patches/server/0912-Properly-handle-experience-dropping-on-block-break.patch similarity index 91% rename from patches/unapplied/server/0919-Properly-handle-experience-dropping-on-block-break.patch rename to patches/server/0912-Properly-handle-experience-dropping-on-block-break.patch index c5ffca5d89b5..5b97d88f0fed 100644 --- a/patches/unapplied/server/0919-Properly-handle-experience-dropping-on-block-break.patch +++ b/patches/server/0912-Properly-handle-experience-dropping-on-block-break.patch @@ -7,7 +7,7 @@ This causes spawnAfterBreak to spawn xp by default, removing the need to manuall For classes that use custom xp amounts, they can drop the resources with disabling diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 3f87e60c0d43703a8450b5920dac59a970809397..471fd54edf6aa962d997878ee638974f7f594fa8 100644 +index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..83537aa240ebff8dd19b450956730dc3d4f355a0 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -617,7 +617,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -21,10 +21,10 @@ index 3f87e60c0d43703a8450b5920dac59a970809397..471fd54edf6aa962d997878ee638974f boolean flag1 = this.setBlock(pos, fluid.createLegacyBlock(), 3, maxUpdateDepth); diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index c083dc8b2a69c3747b250d13f1a28ad22b5e6119..bf52c36f31992a01a7403d8c85151327c9e944c4 100644 +index 6fb3f551f432d7e668c606fb7bd3514408e0478a..9917df070d9815b6915e4a0b022dfe4e5b7861e7 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -312,23 +312,31 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -311,23 +311,31 @@ public class Block extends BlockBehaviour implements ItemLike { for (ItemStack drop : Block.getDrops(state, serverLevel, pos, blockEntity)) { items.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(drop)); } @@ -58,7 +58,7 @@ index c083dc8b2a69c3747b250d13f1a28ad22b5e6119..bf52c36f31992a01a7403d8c85151327 } } -@@ -412,7 +420,7 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -415,7 +423,7 @@ public class Block extends BlockBehaviour implements ItemLike { player.awardStat(Stats.BLOCK_MINED.get(this)); player.causeFoodExhaustion(0.005F, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.BLOCK_MINED); // CraftBukkit - EntityExhaustionEvent if (includeDrops) { // Paper - fix drops not preventing stats/food exhaustion @@ -68,10 +68,10 @@ index c083dc8b2a69c3747b250d13f1a28ad22b5e6119..bf52c36f31992a01a7403d8c85151327 } diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -index a8bec3c405732e5863cf717b1fe948d00837bed2..240c250a93289776686d09d7eae17c07d7278da5 100644 +index 0665ca48fe2f8ab1ce1c0306b11be19b06445f74..1b988b92e80faa1ac224caf9f9e955ac43a4c45a 100644 --- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -@@ -1119,6 +1119,7 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -1180,6 +1180,7 @@ public abstract class BlockBehaviour implements FeatureElement { public void spawnAfterBreak(ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) { this.getBlock().spawnAfterBreak(this.asState(), world, pos, tool, dropExperience); @@ -80,7 +80,7 @@ index a8bec3c405732e5863cf717b1fe948d00837bed2..240c250a93289776686d09d7eae17c07 public List getDrops(LootParams.Builder builder) { diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index 461a66c323a74db5a70981fafc5fa20f54f0f40d..ac11f18690434922179b61ffcc3036dea025b0cb 100644 +index a34e888f63ead250c41b6bbe6850a5e5b4254c3d..66ac5d0b6dafd0323b73953cdd633dca624c3bcd 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -509,7 +509,7 @@ public class CraftBlock implements Block { diff --git a/patches/unapplied/server/0920-Fixup-NamespacedKey-handling.patch b/patches/server/0913-Fixup-NamespacedKey-handling.patch similarity index 97% rename from patches/unapplied/server/0920-Fixup-NamespacedKey-handling.patch rename to patches/server/0913-Fixup-NamespacedKey-handling.patch index f5d990944ba5..932cc370d881 100644 --- a/patches/unapplied/server/0920-Fixup-NamespacedKey-handling.patch +++ b/patches/server/0913-Fixup-NamespacedKey-handling.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fixup NamespacedKey handling diff --git a/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java b/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java -index e34deaf398dc6722c3128bdd6b9bc16da2d33bf7..f028daa4f23a1f1868c9922991259739cadc5da2 100644 +index 90b82ad996b2b85628c9a5ddeef9410150b7f70c..5fd22a80e9d05afbea273471cee991732a9485fd 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java @@ -38,7 +38,7 @@ public class CraftLootTable implements org.bukkit.loot.LootTable { @@ -18,7 +18,7 @@ index e34deaf398dc6722c3128bdd6b9bc16da2d33bf7..f028daa4f23a1f1868c9922991259739 public static NamespacedKey minecraftToBukkitKey(ResourceKey minecraft) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java -index 9b78bfd187a1bd5f99af5690f194441904956c7d..bd16933a5341908b21e549f66080c33466ad1079 100644 +index aa66fd8dca886c1f064d8cb4a3d15c2086c1719a..f8450a2abd1e96fac7827d252cc00038b9dee839 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java @@ -122,6 +122,16 @@ public class CraftRegistry implements Registry { @@ -81,7 +81,7 @@ index bcac1359c667ef1ee46384f9c7a5adf4010d2b08..98a4463c9f194f33f4f85d95a0b9fa06 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java -index 2c57fd269484ed79814d974877585f9f7e6393d3..865977ce17fbb8793a1eefd71079729e83f5cfaf 100644 +index 0fdd9dd47594a7e7e785c34c09d9b4a79aad2439..0d3b1692af010bfd7ea83e22e9571dc954906f71 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java @@ -38,8 +38,9 @@ public class CraftMetaArmor extends CraftMetaItem implements ArmorMeta { diff --git a/patches/unapplied/server/0921-Expose-LootTable-of-DecoratedPot.patch b/patches/server/0914-Expose-LootTable-of-DecoratedPot.patch similarity index 100% rename from patches/unapplied/server/0921-Expose-LootTable-of-DecoratedPot.patch rename to patches/server/0914-Expose-LootTable-of-DecoratedPot.patch diff --git a/patches/unapplied/server/0922-Reduce-allocation-of-Vec3D-by-entity-tracker.patch b/patches/server/0915-Reduce-allocation-of-Vec3D-by-entity-tracker.patch similarity index 66% rename from patches/unapplied/server/0922-Reduce-allocation-of-Vec3D-by-entity-tracker.patch rename to patches/server/0915-Reduce-allocation-of-Vec3D-by-entity-tracker.patch index 37c0ef0eefce..a9f20c91ac7b 100644 --- a/patches/unapplied/server/0922-Reduce-allocation-of-Vec3D-by-entity-tracker.patch +++ b/patches/server/0915-Reduce-allocation-of-Vec3D-by-entity-tracker.patch @@ -18,10 +18,10 @@ index a043ac10834562d357ef0b5aded2e916e2a0d056..74276c368016fcc4dbf9579b2ecbadc9 @VisibleForTesting static long encode(double value) { diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 6c667823c2ef15766f3afc1a9c819cb6c24b0912..4c1cf5798209297e1e8a634b63770e917a84a63c 100644 +index 29a28e160f6ca87d263b84fbf0c5429d30e34a21..a43eef8bf05855270601761494b6a67dc55cb1c9 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1519,10 +1519,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1578,10 +1578,14 @@ 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) { @@ -39,21 +39,21 @@ index 6c667823c2ef15766f3afc1a9c819cb6c24b0912..4c1cf5798209297e1e8a634b63770e91 // Paper start - Configurable entity tracking range by Y boolean flag = d1 <= d2; diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index a2fbbbd7a66d4e7b1063638f8467e8887a417282..0e7ace92522fbd4cef7b2c2b8a0f8b86c2cce192 100644 +index 7118e1f806af98159ec292f9340d7e4004e2b486..f3456aeeab7eee5b6d0383a4bf1338dd8cc95bb3 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -163,7 +163,13 @@ public class ServerEntity { - i = Mth.floor(this.entity.getYRot() * 256.0F / 360.0F); - j = Mth.floor(this.entity.getXRot() * 256.0F / 360.0F); - Vec3 vec3d = this.entity.trackingPosition(); -- boolean flag1 = this.positionCodec.delta(vec3d).lengthSqr() >= 7.62939453125E-6D; -+ // Paper start - reduce allocation of Vec3D here -+ Vec3 base = this.positionCodec.base; -+ double vec3d_dx = vec3d.x - base.x; -+ double vec3d_dy = vec3d.y - base.y; -+ double vec3d_dz = vec3d.z - base.z; -+ boolean flag1 = (vec3d_dx * vec3d_dx + vec3d_dy * vec3d_dy + vec3d_dz * vec3d_dz) >= 7.62939453125E-6D; -+ // Paper end - reduce allocation of Vec3D here - Packet packet1 = null; - boolean flag2 = flag1 || this.tickCount % 60 == 0; - boolean flag3 = Math.abs(i - this.lastSentYRot) >= 1 || Math.abs(j - this.lastSentXRot) >= 1; +@@ -178,7 +178,13 @@ public class ServerEntity { + + ++this.teleportDelay; + Vec3 vec3d = this.entity.trackingPosition(); +- boolean flag1 = this.positionCodec.delta(vec3d).lengthSqr() >= 7.62939453125E-6D; ++ // Paper start - reduce allocation of Vec3D here ++ Vec3 base = this.positionCodec.base; ++ double vec3d_dx = vec3d.x - base.x; ++ double vec3d_dy = vec3d.y - base.y; ++ double vec3d_dz = vec3d.z - base.z; ++ boolean flag1 = (vec3d_dx * vec3d_dx + vec3d_dy * vec3d_dy + vec3d_dz * vec3d_dz) >= 7.62939453125E-6D; ++ // Paper end - reduce allocation of Vec3D here + Packet packet1 = null; + boolean flag2 = flag1 || this.tickCount % 60 == 0; + boolean flag3 = false; diff --git a/patches/unapplied/server/0923-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch b/patches/server/0916-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch similarity index 94% rename from patches/unapplied/server/0923-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch rename to patches/server/0916-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch index 95e1104a250d..4ed1121ea18c 100644 --- a/patches/unapplied/server/0923-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch +++ b/patches/server/0916-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add PlayerTradeEvent and PlayerPurchaseEvent Co-authored-by: Alexander diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java -index 2a155d3611ca2370830ca763d40074df6641958f..d28ebcae036168dd65a5f3236d12ee416308c23f 100644 +index 39cb40b077e9c07471437d5bec16ba9a7e6bce52..5f656fc726a1dc5f42657095a2f2b7cf85b92d7c 100644 --- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java +++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java @@ -141,11 +141,24 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa @@ -37,10 +37,10 @@ index 2a155d3611ca2370830ca763d40074df6641958f..d28ebcae036168dd65a5f3236d12ee41 CriteriaTriggers.TRADE.trigger((ServerPlayer) this.tradingPlayer, this, offer.getResult()); } diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -index 8a1035c0aa859f67a6806c183d96a88ddf760baa..46159a127d910028c62ada90ff2d2dccc3b62fc3 100644 +index 85caec29a705f216eff8a5ae11f250697891a05c..78d0ff45c016e900d87010e8b26b0bb10e63f445 100644 --- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -@@ -768,6 +768,14 @@ public abstract class AbstractContainerMenu { +@@ -831,6 +831,14 @@ public abstract class AbstractContainerMenu { public abstract boolean stillValid(Player player); protected boolean moveItemStackTo(ItemStack stack, int startIndex, int endIndex, boolean fromLast) { @@ -55,7 +55,7 @@ index 8a1035c0aa859f67a6806c183d96a88ddf760baa..46159a127d910028c62ada90ff2d2dcc boolean flag1 = false; int k = startIndex; -@@ -791,6 +799,11 @@ public abstract class AbstractContainerMenu { +@@ -854,6 +862,11 @@ public abstract class AbstractContainerMenu { slot = (Slot) this.slots.get(k); itemstack1 = slot.getItem(); @@ -67,7 +67,7 @@ index 8a1035c0aa859f67a6806c183d96a88ddf760baa..46159a127d910028c62ada90ff2d2dcc if (!itemstack1.isEmpty() && ItemStack.isSameItemSameComponents(stack, itemstack1)) { l = itemstack1.getCount() + stack.getCount(); int i1 = slot.getMaxStackSize(itemstack1); -@@ -798,12 +811,16 @@ public abstract class AbstractContainerMenu { +@@ -861,12 +874,16 @@ public abstract class AbstractContainerMenu { if (l <= i1) { stack.setCount(0); itemstack1.setCount(l); @@ -84,7 +84,7 @@ index 8a1035c0aa859f67a6806c183d96a88ddf760baa..46159a127d910028c62ada90ff2d2dcc flag1 = true; } } -@@ -834,10 +851,21 @@ public abstract class AbstractContainerMenu { +@@ -897,10 +914,21 @@ public abstract class AbstractContainerMenu { slot = (Slot) this.slots.get(k); itemstack1 = slot.getItem(); @@ -107,10 +107,10 @@ index 8a1035c0aa859f67a6806c183d96a88ddf760baa..46159a127d910028c62ada90ff2d2dcc break; } diff --git a/src/main/java/net/minecraft/world/inventory/MerchantMenu.java b/src/main/java/net/minecraft/world/inventory/MerchantMenu.java -index e45ab844afdf1a65f23eeff4c4d6cd9e3a8a28e2..5de2030452b96a4df7ce0be82f07e002db595dee 100644 +index 90560dfad263d42432dc034a29930e6bab953b9a..6a529b5e289c416c0ebdc0260086ec039777aa40 100644 --- a/src/main/java/net/minecraft/world/inventory/MerchantMenu.java +++ b/src/main/java/net/minecraft/world/inventory/MerchantMenu.java -@@ -135,12 +135,12 @@ public class MerchantMenu extends AbstractContainerMenu { +@@ -123,12 +123,12 @@ public class MerchantMenu extends AbstractContainerMenu { itemstack = itemstack1.copy(); if (slot == 2) { @@ -126,7 +126,7 @@ index e45ab844afdf1a65f23eeff4c4d6cd9e3a8a28e2..5de2030452b96a4df7ce0be82f07e002 } else if (slot != 0 && slot != 1) { if (slot >= 3 && slot < 30) { if (!this.moveItemStackTo(itemstack1, 30, 39, false)) { -@@ -153,6 +153,7 @@ public class MerchantMenu extends AbstractContainerMenu { +@@ -141,6 +141,7 @@ public class MerchantMenu extends AbstractContainerMenu { return ItemStack.EMPTY; } @@ -134,7 +134,7 @@ index e45ab844afdf1a65f23eeff4c4d6cd9e3a8a28e2..5de2030452b96a4df7ce0be82f07e002 if (itemstack1.isEmpty()) { slot1.setByPlayer(ItemStack.EMPTY); } else { -@@ -164,6 +165,21 @@ public class MerchantMenu extends AbstractContainerMenu { +@@ -152,6 +153,21 @@ public class MerchantMenu extends AbstractContainerMenu { } slot1.onTake(player, itemstack1); diff --git a/patches/unapplied/server/0924-Add-ShulkerDuplicateEvent.patch b/patches/server/0917-Add-ShulkerDuplicateEvent.patch similarity index 88% rename from patches/unapplied/server/0924-Add-ShulkerDuplicateEvent.patch rename to patches/server/0917-Add-ShulkerDuplicateEvent.patch index de864137e235..f06c91ae4814 100644 --- a/patches/unapplied/server/0924-Add-ShulkerDuplicateEvent.patch +++ b/patches/server/0917-Add-ShulkerDuplicateEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add ShulkerDuplicateEvent diff --git a/src/main/java/net/minecraft/world/entity/monster/Shulker.java b/src/main/java/net/minecraft/world/entity/monster/Shulker.java -index bf58956379d0a5dbfdc34e8626847638b4111433..920c7a92643e83598f39bf984cca430d9deed2cd 100644 +index 0fffa9dbcbbb15a2138f9a4e4d8e812c8047a7bb..6e0f2f6573ed6be9b91de960d55c269417ad8907 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Shulker.java +++ b/src/main/java/net/minecraft/world/entity/monster/Shulker.java -@@ -491,6 +491,11 @@ public class Shulker extends AbstractGolem implements VariantHolder Date: Thu, 24 Oct 2024 09:53:28 -0400 Subject: [PATCH 038/119] Patch --- .../0919-Add-Lifecycle-Event-system.patch} | 6 +- .../0920-ItemStack-Tooltip-API.patch} | 2 +- ...Snapshot-includeLightData-parameter.patch} | 8 +- .../0922-Add-FluidState-API.patch} | 6 +- .../0923-add-number-format-api.patch} | 0 .../0924-improve-BanList-types.patch} | 4 +- .../0925-Expanded-Hopper-API.patch} | 0 ...6-Add-BlockBreakProgressUpdateEvent.patch} | 4 +- .../0927-Deprecate-ItemStack-setType.patch} | 4 +- .../0928-Add-CartographyItemEvent.patch} | 6 +- .../0929-More-Raid-API.patch} | 8 +- ...ng-message-for-initial-server-start.patch} | 6 +- ...-Configurable-max-block-fluid-ticks.patch} | 4 +- .../0932-Fix-bees-aging-inside-hives.patch} | 6 +- ...3-Disable-memory-reserve-allocating.patch} | 0 ...ByEntityEvent-for-unowned-wither-sk.patch} | 6 +- .../0935-Fix-DamageSource-API.patch} | 68 +++++----- ...nvalid-block-entity-during-world-ge.patch} | 6 +- ...tackOverflowError-for-some-dispenses.patch | 95 ++++++++++++++ .../0938-Improve-tag-parser-handling.patch} | 31 ++--- .../0939-Item-Mutation-Fixes.patch} | 6 +- ...-Per-world-ticks-per-spawn-settings.patch} | 6 +- ...e-changed-item-from-dispense-events.patch} | 40 +++--- ...nd-End-Portal-Frames-from-being-des.patch} | 52 ++++---- ...-for-mobs-immune-to-default-effects.patch} | 8 +- .../0944-Deep-clone-nbt-tags-in-PDC.patch} | 8 +- ...tackOverflowError-for-some-dispenses.patch | 117 ------------------ ...re-disarming-not-working-as-intended.patch | 22 ---- 28 files changed, 234 insertions(+), 295 deletions(-) rename patches/{unapplied/server/0926-Add-Lifecycle-Event-system.patch => server/0919-Add-Lifecycle-Event-system.patch} (99%) rename patches/{unapplied/server/0927-ItemStack-Tooltip-API.patch => server/0920-ItemStack-Tooltip-API.patch} (95%) rename patches/{unapplied/server/0928-Add-getChunkSnapshot-includeLightData-parameter.patch => server/0921-Add-getChunkSnapshot-includeLightData-parameter.patch} (92%) rename patches/{unapplied/server/0929-Add-FluidState-API.patch => server/0922-Add-FluidState-API.patch} (97%) rename patches/{unapplied/server/0930-add-number-format-api.patch => server/0923-add-number-format-api.patch} (100%) rename patches/{unapplied/server/0931-improve-BanList-types.patch => server/0924-improve-BanList-types.patch} (89%) rename patches/{unapplied/server/0932-Expanded-Hopper-API.patch => server/0925-Expanded-Hopper-API.patch} (100%) rename patches/{unapplied/server/0933-Add-BlockBreakProgressUpdateEvent.patch => server/0926-Add-BlockBreakProgressUpdateEvent.patch} (87%) rename patches/{unapplied/server/0934-Deprecate-ItemStack-setType.patch => server/0927-Deprecate-ItemStack-setType.patch} (89%) rename patches/{unapplied/server/0935-Add-CartographyItemEvent.patch => server/0928-Add-CartographyItemEvent.patch} (91%) rename patches/{unapplied/server/0936-More-Raid-API.patch => server/0929-More-Raid-API.patch} (93%) rename patches/{unapplied/server/0937-Add-onboarding-message-for-initial-server-start.patch => server/0930-Add-onboarding-message-for-initial-server-start.patch} (95%) rename patches/{unapplied/server/0938-Configurable-max-block-fluid-ticks.patch => server/0931-Configurable-max-block-fluid-ticks.patch} (85%) rename patches/{unapplied/server/0939-Fix-bees-aging-inside-hives.patch => server/0932-Fix-bees-aging-inside-hives.patch} (90%) rename patches/{unapplied/server/0940-Disable-memory-reserve-allocating.patch => server/0933-Disable-memory-reserve-allocating.patch} (100%) rename patches/{unapplied/server/0941-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch => server/0934-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch} (67%) rename patches/{unapplied/server/0942-Fix-DamageSource-API.patch => server/0935-Fix-DamageSource-API.patch} (76%) rename patches/{unapplied/server/0943-Fix-creation-of-invalid-block-entity-during-world-ge.patch => server/0936-Fix-creation-of-invalid-block-entity-during-world-ge.patch} (93%) create mode 100644 patches/server/0937-Fix-possible-StackOverflowError-for-some-dispenses.patch rename patches/{unapplied/server/0945-Improve-tag-parser-handling.patch => server/0938-Improve-tag-parser-handling.patch} (92%) rename patches/{unapplied/server/0946-Item-Mutation-Fixes.patch => server/0939-Item-Mutation-Fixes.patch} (90%) rename patches/{unapplied/server/0947-Per-world-ticks-per-spawn-settings.patch => server/0940-Per-world-ticks-per-spawn-settings.patch} (90%) rename patches/{unapplied/server/0948-Properly-track-the-changed-item-from-dispense-events.patch => server/0941-Properly-track-the-changed-item-from-dispense-events.patch} (73%) rename patches/{unapplied/server/0949-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch => server/0942-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch} (86%) rename patches/{unapplied/server/0951-Add-config-for-mobs-immune-to-default-effects.patch => server/0943-Add-config-for-mobs-immune-to-default-effects.patch} (86%) rename patches/{unapplied/server/0952-Deep-clone-nbt-tags-in-PDC.patch => server/0944-Deep-clone-nbt-tags-in-PDC.patch} (89%) delete mode 100644 patches/unapplied/server/0944-Fix-possible-StackOverflowError-for-some-dispenses.patch delete mode 100644 patches/unapplied/server/0950-Fix-tripwire-disarming-not-working-as-intended.patch diff --git a/patches/unapplied/server/0926-Add-Lifecycle-Event-system.patch b/patches/server/0919-Add-Lifecycle-Event-system.patch similarity index 99% rename from patches/unapplied/server/0926-Add-Lifecycle-Event-system.patch rename to patches/server/0919-Add-Lifecycle-Event-system.patch index f6600c437067..2f7888db419f 100644 --- a/patches/unapplied/server/0926-Add-Lifecycle-Event-system.patch +++ b/patches/server/0919-Add-Lifecycle-Event-system.patch @@ -727,10 +727,10 @@ index 2e96308696e131f3f013469a395e5ddda2c5d529..65a66e484c1c39c5f41d97db52f31c67 } catch (Throwable e) { LOGGER.error("Failed to run bootstrapper for %s. This plugin will not be loaded.".formatted(provider.getSource()), e); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 8b871d29d883119cd8ad9ca134f4c1fce9362705..f6b87a5249e1a21b3221f253f891d8978249c50a 100644 +index 2934e232c84603224470fdaba0103d42fc06e8b4..4dc64ab006399d62251f4a238d9c2caebd595301 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1048,6 +1048,11 @@ public final class CraftServer implements Server { +@@ -1051,6 +1051,11 @@ public final class CraftServer implements Server { @Override public void reload() { @@ -743,7 +743,7 @@ index 8b871d29d883119cd8ad9ca134f4c1fce9362705..f6b87a5249e1a21b3221f253f891d897 this.reloadCount++; this.configuration = YamlConfiguration.loadConfiguration(this.getConfigFile()); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 73a3e708f21c1b9c5de1fc180f728d6da7eea0fb..b89db5335aa3984b76513165456ebe43ad9a0cc7 100644 +index b6591836a8d9301b8cf909223426df0e8e675c1f..6396af834c5ca2328896613c5d97e43624eb305d 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -652,6 +652,13 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/unapplied/server/0927-ItemStack-Tooltip-API.patch b/patches/server/0920-ItemStack-Tooltip-API.patch similarity index 95% rename from patches/unapplied/server/0927-ItemStack-Tooltip-API.patch rename to patches/server/0920-ItemStack-Tooltip-API.patch index c487ffd71f25..006236f389ff 100644 --- a/patches/unapplied/server/0927-ItemStack-Tooltip-API.patch +++ b/patches/server/0920-ItemStack-Tooltip-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] ItemStack Tooltip API diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index b89db5335aa3984b76513165456ebe43ad9a0cc7..6e8838245b0792b15fd9788f2ce11f6503d0e070 100644 +index 6396af834c5ca2328896613c5d97e43624eb305d..6e070dada87083656a19b4abf78db63f4b2513e6 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -628,6 +628,21 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/unapplied/server/0928-Add-getChunkSnapshot-includeLightData-parameter.patch b/patches/server/0921-Add-getChunkSnapshot-includeLightData-parameter.patch similarity index 92% rename from patches/unapplied/server/0928-Add-getChunkSnapshot-includeLightData-parameter.patch rename to patches/server/0921-Add-getChunkSnapshot-includeLightData-parameter.patch index 54aa35539f07..ba33560babab 100644 --- a/patches/unapplied/server/0928-Add-getChunkSnapshot-includeLightData-parameter.patch +++ b/patches/server/0921-Add-getChunkSnapshot-includeLightData-parameter.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add getChunkSnapshot includeLightData parameter diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java -index d6eab2a0fdbafc35efa7ed5b404357391565f4f3..69c7fe5bf5b914276a9f7a0e57ce668e569d91f9 100644 +index 887a17a0833064eb5701222e5fb6f5ccf9511588..5fc9e8e969debb3e15ed474b36a1c48b086d0449 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -328,12 +328,21 @@ public class CraftChunk implements Chunk { @@ -49,10 +49,10 @@ index d6eab2a0fdbafc35efa7ed5b404357391565f4f3..69c7fe5bf5b914276a9f7a0e57ce668e if (biome != null) { biome[i] = ((PalettedContainer>) cs[i].getBiomes()).copy(); // Paper - Perf: use copy instead of round tripping with codecs diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java -index 85029f1acfdbb411d9ebdf95838d6db3898f4e58..0756b5adb3039997feadeb94afb10b596abd9424 100644 +index c88e4ba701b2a2325b76478b7f47278157afd2ef..ddcbdbcbfeb6efe0a587b1181505423cc9d2c951 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java -@@ -118,6 +118,7 @@ public class CraftChunkSnapshot implements ChunkSnapshot { +@@ -119,6 +119,7 @@ public class CraftChunkSnapshot implements ChunkSnapshot { @Override public final int getBlockSkyLight(int x, int y, int z) { @@ -60,7 +60,7 @@ index 85029f1acfdbb411d9ebdf95838d6db3898f4e58..0756b5adb3039997feadeb94afb10b59 this.validateChunkCoordinates(x, y, z); int off = ((y & 0xF) << 7) | (z << 3) | (x >> 1); -@@ -126,6 +127,7 @@ public class CraftChunkSnapshot implements ChunkSnapshot { +@@ -127,6 +128,7 @@ public class CraftChunkSnapshot implements ChunkSnapshot { @Override public final int getBlockEmittedLight(int x, int y, int z) { diff --git a/patches/unapplied/server/0929-Add-FluidState-API.patch b/patches/server/0922-Add-FluidState-API.patch similarity index 97% rename from patches/unapplied/server/0929-Add-FluidState-API.patch rename to patches/server/0922-Add-FluidState-API.patch index aac0912819f6..8fa8aecc0225 100644 --- a/patches/unapplied/server/0929-Add-FluidState-API.patch +++ b/patches/server/0922-Add-FluidState-API.patch @@ -173,7 +173,7 @@ index 0000000000000000000000000000000000000000..c0c2805cb045cdd835b402776a6923fe + +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index a14d3e6c43b94c543790571b13808713444a239f..284234fcdd15c4c7a4567c7c887d47bf0b7967f4 100644 +index 29825ea687827c075b87e88c45672e7b0093ed17..9af491e6e9ac96fc766462a1f672f44f8fc50ef1 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java @@ -108,6 +108,13 @@ public abstract class CraftRegionAccessor implements RegionAccessor { @@ -191,10 +191,10 @@ index a14d3e6c43b94c543790571b13808713444a239f..284234fcdd15c4c7a4567c7c887d47bf public BlockData getBlockData(Location location) { return this.getBlockData(location.getBlockX(), location.getBlockY(), location.getBlockZ()); diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java -index eaa9ba70b0b80d86eb376a0641420093a7c9dfdb..25598df0bb0d4347b2c17b6ec0afbfe4ecf808b9 100644 +index a23269e3bdb83f85a1d08d5f7b54742025223ada..a57ac9dc8d08b12ec00ad41d9a1779e5a81e4e8b 100644 --- a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java +++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java -@@ -303,4 +303,11 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe +@@ -304,4 +304,11 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe return centerChunkZ; } // Paper end - Add more LimitedRegion API diff --git a/patches/unapplied/server/0930-add-number-format-api.patch b/patches/server/0923-add-number-format-api.patch similarity index 100% rename from patches/unapplied/server/0930-add-number-format-api.patch rename to patches/server/0923-add-number-format-api.patch diff --git a/patches/unapplied/server/0931-improve-BanList-types.patch b/patches/server/0924-improve-BanList-types.patch similarity index 89% rename from patches/unapplied/server/0931-improve-BanList-types.patch rename to patches/server/0924-improve-BanList-types.patch index a3e327bc830f..24c44ced873d 100644 --- a/patches/unapplied/server/0931-improve-BanList-types.patch +++ b/patches/server/0924-improve-BanList-types.patch @@ -5,10 +5,10 @@ Subject: [PATCH] improve BanList types diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index f6b87a5249e1a21b3221f253f891d8978249c50a..0fc6e659915a4547c2db9205fed205a1d28f21d4 100644 +index 4dc64ab006399d62251f4a238d9c2caebd595301..97850b3111dfa86d15186fa200937b28bec428de 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2256,6 +2256,21 @@ public final class CraftServer implements Server { +@@ -2223,6 +2223,21 @@ public final class CraftServer implements Server { }; } diff --git a/patches/unapplied/server/0932-Expanded-Hopper-API.patch b/patches/server/0925-Expanded-Hopper-API.patch similarity index 100% rename from patches/unapplied/server/0932-Expanded-Hopper-API.patch rename to patches/server/0925-Expanded-Hopper-API.patch diff --git a/patches/unapplied/server/0933-Add-BlockBreakProgressUpdateEvent.patch b/patches/server/0926-Add-BlockBreakProgressUpdateEvent.patch similarity index 87% rename from patches/unapplied/server/0933-Add-BlockBreakProgressUpdateEvent.patch rename to patches/server/0926-Add-BlockBreakProgressUpdateEvent.patch index 3481a288eed1..7d82cc97af77 100644 --- a/patches/unapplied/server/0933-Add-BlockBreakProgressUpdateEvent.patch +++ b/patches/server/0926-Add-BlockBreakProgressUpdateEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add BlockBreakProgressUpdateEvent diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 34ece37aee68e4d8eeaa919e8bd489a672756049..dcd024afef50c90974723632c879258fb1dda073 100644 +index e3df141a2a49f10e83fe132514a9b1d969cc4417..3f0e5bd457e3231d84b9d14396d8d8859989f3f4 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1320,6 +1320,17 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1315,6 +1315,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (entity instanceof Player) entityhuman = (Player) entity; // CraftBukkit end diff --git a/patches/unapplied/server/0934-Deprecate-ItemStack-setType.patch b/patches/server/0927-Deprecate-ItemStack-setType.patch similarity index 89% rename from patches/unapplied/server/0934-Deprecate-ItemStack-setType.patch rename to patches/server/0927-Deprecate-ItemStack-setType.patch index e0a6acc7477f..e58b22013ff7 100644 --- a/patches/unapplied/server/0934-Deprecate-ItemStack-setType.patch +++ b/patches/server/0927-Deprecate-ItemStack-setType.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Deprecate ItemStack#setType diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index a1a32a77bda0560a7b7f30a5d1c1837ee96997d3..9be7859ccb5283b2040ba68d72d6dbdafb4d6835 100644 +index ffd7ba14be38a117f5a7d7035a8d71a20fb1c4fc..7228d43d331de16cbaa0e97c7e3fa45c0bc89558 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -@@ -417,4 +417,24 @@ public final class CraftItemStack extends ItemStack { +@@ -429,4 +429,24 @@ public final class CraftItemStack extends ItemStack { static boolean hasItemMeta(net.minecraft.world.item.ItemStack item) { return !(item == null || item.getComponentsPatch().isEmpty()); } diff --git a/patches/unapplied/server/0935-Add-CartographyItemEvent.patch b/patches/server/0928-Add-CartographyItemEvent.patch similarity index 91% rename from patches/unapplied/server/0935-Add-CartographyItemEvent.patch rename to patches/server/0928-Add-CartographyItemEvent.patch index 9e487673815f..ca08d014f85a 100644 --- a/patches/unapplied/server/0935-Add-CartographyItemEvent.patch +++ b/patches/server/0928-Add-CartographyItemEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add CartographyItemEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index d377804026f3f5cf80a623228d24e09c56ef0dae..fb935b505ec048522f9ab5d689b2c64c64f401a7 100644 +index 8b5be8870a0077b82e345027b323b8b4f448f231..80755a80dfd484af361c208fd4de309ca7ef8553 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3108,6 +3108,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3125,6 +3125,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } @@ -29,7 +29,7 @@ index d377804026f3f5cf80a623228d24e09c56ef0dae..fb935b505ec048522f9ab5d689b2c64c AbstractContainerMenu oldContainer = this.player.containerMenu; // SPIGOT-1224 this.cserver.getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java -index ab98637bf967ac19f0bc06e8cb7f18a8b13ec809..a90e2c56c54797b2fec40eb3865835c5f640a544 100644 +index b3a16b024e46ee8203b225ee429a5c973eab12c6..dc42d42ef91bc3e49f967c0a30a0d1b56e09cf21 100644 --- a/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java +++ b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java @@ -71,7 +71,7 @@ public class CartographyTableMenu extends AbstractContainerMenu { diff --git a/patches/unapplied/server/0936-More-Raid-API.patch b/patches/server/0929-More-Raid-API.patch similarity index 93% rename from patches/unapplied/server/0936-More-Raid-API.patch rename to patches/server/0929-More-Raid-API.patch index 8824526cadf1..6e3632dd09d7 100644 --- a/patches/unapplied/server/0936-More-Raid-API.patch +++ b/patches/server/0929-More-Raid-API.patch @@ -7,7 +7,7 @@ Subject: [PATCH] More Raid API public net.minecraft.world.entity.raid.Raid raidEvent diff --git a/src/main/java/net/minecraft/world/entity/raid/Raid.java b/src/main/java/net/minecraft/world/entity/raid/Raid.java -index fe2a01ae8207c97203d331bbab51699502b977e2..dcbef04bbaab988096bf416163264833e84d1967 100644 +index 28922f2a1cf4762d5d7d09635b9268c6091300c3..11cf2d9def087b0898c828eaa21eb5f7b8811d5f 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raid.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raid.java @@ -107,6 +107,11 @@ public class Raid { @@ -34,7 +34,7 @@ index fe2a01ae8207c97203d331bbab51699502b977e2..dcbef04bbaab988096bf416163264833 } -@@ -867,6 +877,11 @@ public class Raid { +@@ -862,6 +872,11 @@ public class Raid { } nbt.put("HeroesOfTheVillage", nbttaglist); @@ -86,10 +86,10 @@ index b8ce1c1c2447f9cff1717bfcfd6eb911ade0d4b3..51f21af9d75769abdcba713b9aa33392 + // Paper end - more Raid API } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index f27568d26e02b5244a84d0fb6d8c1d9f14b7a519..e8404d5bad60b8fa290f334d3c64ee5503e01e5c 100644 +index 1675ad5818340f21c7e5b6982af315bcad30240b..149377347fc632358a8bb97e644b1c4ab9be413d 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2313,6 +2313,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2326,6 +2326,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { return (raid == null) ? null : new CraftRaid(raid); } diff --git a/patches/unapplied/server/0937-Add-onboarding-message-for-initial-server-start.patch b/patches/server/0930-Add-onboarding-message-for-initial-server-start.patch similarity index 95% rename from patches/unapplied/server/0937-Add-onboarding-message-for-initial-server-start.patch rename to patches/server/0930-Add-onboarding-message-for-initial-server-start.patch index 5bb4e9d2fcb9..f6da9e5a3d0a 100644 --- a/patches/unapplied/server/0937-Add-onboarding-message-for-initial-server-start.patch +++ b/patches/server/0930-Add-onboarding-message-for-initial-server-start.patch @@ -17,7 +17,7 @@ index d9502ba028a96f9cc846f9ed428bd8066b857ca3..87e5f614ba988547a827486740db217e node = loader.load(); this.verifyGlobalConfigVersion(node); diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 917bd0c1dd8f356edc3741ee59d24e4d090af182..f19b4a17a7e22969f7b51d3bea4056b41ab25484 100644 +index 73e8a524925ed6f2580d3bd01616646fabafda78..450a1cc8f1624dce2daf52210d017e0732b1bdf7 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -27,6 +27,7 @@ public class GlobalConfiguration extends ConfigurationPart { @@ -29,10 +29,10 @@ index 917bd0c1dd8f356edc3741ee59d24e4d090af182..f19b4a17a7e22969f7b51d3bea4056b4 return instance; } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 3ee0e2adf576e312c18da90adc46160ad85179fb..42a74f5471da882d63c194b1e212f78a94b103ec 100644 +index f1b1be0caff83720d77454d333abae4613c66e72..f575c0042f67c70df0ddb1d1db68e0138cf0b534 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1135,6 +1135,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop modifiers, Map> modifierFunctions, boolean cancelled) { CraftDamageSource bukkitDamageSource = new CraftDamageSource(source); diff --git a/patches/unapplied/server/0943-Fix-creation-of-invalid-block-entity-during-world-ge.patch b/patches/server/0936-Fix-creation-of-invalid-block-entity-during-world-ge.patch similarity index 93% rename from patches/unapplied/server/0943-Fix-creation-of-invalid-block-entity-during-world-ge.patch rename to patches/server/0936-Fix-creation-of-invalid-block-entity-during-world-ge.patch index 8e09c4fb05bf..f476845b96a8 100644 --- a/patches/unapplied/server/0943-Fix-creation-of-invalid-block-entity-during-world-ge.patch +++ b/patches/server/0936-Fix-creation-of-invalid-block-entity-during-world-ge.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix creation of invalid block entity during world generation diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java -index 682c8cfbd917c086072f1756861a340800ea40da..b26a4a38144ec1b171db911bbf949b53ed35708f 100644 +index 2e72e92762877b28dd908711671e1dfb933de9b0..b7d29389a357f142237cecd75f8ca91cf1eb6b5b 100644 --- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java +++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java @@ -324,7 +324,7 @@ public class WorldGenRegion implements WorldGenLevel { @@ -36,10 +36,10 @@ index 682c8cfbd917c086072f1756861a340800ea40da..b26a4a38144ec1b171db911bbf949b53 nbttagcompound.putInt("x", pos.getX()); 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 59f9ff720e92c69e11afe7f6ccecd81b0e54a74d..86eb9029969f4de3ada7be9e135e9764172b85f5 100644 +index 7181acfafad91aa5f6ab7ce663d9be4a1b65b02a..5dd1df0da1f954778aebe0f40611ae0f3a7866ab 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -961,9 +961,14 @@ public class LevelChunk extends ChunkAccess { +@@ -994,9 +994,14 @@ public class LevelChunk extends ChunkAccess { if (this.blockEntity.getType().isValid(iblockdata)) { this.ticker.tick(LevelChunk.this.level, this.blockEntity.getBlockPos(), iblockdata, this.blockEntity); this.loggedInvalidBlockState = false; diff --git a/patches/server/0937-Fix-possible-StackOverflowError-for-some-dispenses.patch b/patches/server/0937-Fix-possible-StackOverflowError-for-some-dispenses.patch new file mode 100644 index 000000000000..7e0fabb39a2a --- /dev/null +++ b/patches/server/0937-Fix-possible-StackOverflowError-for-some-dispenses.patch @@ -0,0 +1,95 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 29 Oct 2022 17:02:42 -0700 +Subject: [PATCH] Fix possible StackOverflowError for some dispenses + +For saddles, carpets, horse armor, and chests for horse-likes +a BlockDispenseEvent handler that always mutated the item without +changing the type would result in a SO error because when it went +to find the replacement dispense behavior (since the item "changed") +it didn't properly handle if the replacement was the same instance +of dispense behavior. + +Additionally equippable mob heads, wither skulls, and carved pumpkins +are subject to the same possible error. + +diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +index 18304349c9ab24657c4152aff800dba969174665..63b8c806b6ee0ea3cc5e6a7f613b5e57c94bfcf1 100644 +--- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java ++++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +@@ -232,7 +232,7 @@ public interface DispenseItemBehavior { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); +- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE) { ++ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE && idispensebehavior != this) { // Paper - fix possible StackOverflowError + idispensebehavior.dispense(pointer, eventStack); + return stack; + } +@@ -283,7 +283,7 @@ public interface DispenseItemBehavior { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); +- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE) { ++ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE && idispensebehavior != this) { // Paper - fix possible StackOverflowError + idispensebehavior.dispense(pointer, eventStack); + return stack; + } +@@ -645,7 +645,7 @@ public interface DispenseItemBehavior { + stack.shrink(1); + this.setSuccess(true); + } else { +- this.setSuccess(EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack)); ++ this.setSuccess(EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack, this)); // Paper - fix possible StackOverflowError + } + + return stack; +@@ -691,7 +691,7 @@ public interface DispenseItemBehavior { + stack.shrink(1); + this.setSuccess(true); + } else { +- this.setSuccess(EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack)); ++ this.setSuccess(EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack, this)); // Paper - fix possible StackOverflowError + } + + return stack; +@@ -819,7 +819,7 @@ public interface DispenseItemBehavior { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); +- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE) { ++ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE && idispensebehavior != this) { // Paper - fix possible StackOverflowError + idispensebehavior.dispense(pointer, eventStack); + return stack; + } +diff --git a/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java +index a03cc350973fda213251cad273a2db86f438904b..036dd3b15dfee4cd079710eba1255d2bdb4d7220 100644 +--- a/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java ++++ b/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java +@@ -23,10 +23,15 @@ public class EquipmentDispenseItemBehavior extends DefaultDispenseItemBehavior { + + @Override + protected ItemStack execute(BlockSource pointer, ItemStack stack) { +- return EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack) ? stack : super.execute(pointer, stack); ++ return EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack, null) ? stack : super.execute(pointer, stack); // Paper - fix possible StackOverflowError + } + +- public static boolean dispenseEquipment(BlockSource pointer, ItemStack stack) { ++ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper ++ public static boolean dispenseEquipment(BlockSource pointer, ItemStack armor) { ++ // Paper start ++ return dispenseEquipment(pointer, armor, null); ++ } ++ public static boolean dispenseEquipment(BlockSource pointer, ItemStack stack, @javax.annotation.Nullable DispenseItemBehavior currentBehavior) { + BlockPos blockposition = pointer.pos().relative((Direction) pointer.state().getValue(DispenserBlock.FACING)); + List list = pointer.level().getEntitiesOfClass(LivingEntity.class, new AABB(blockposition), (entityliving) -> { + return entityliving.canEquipWithDispenser(stack); +@@ -59,7 +64,7 @@ public class EquipmentDispenseItemBehavior extends DefaultDispenseItemBehavior { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); +- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE) { ++ if (idispensebehavior != DispenseItemBehavior.NOOP && (currentBehavior == null || idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE)) { // Paper - fix possible StackOverflowError + idispensebehavior.dispense(pointer, eventStack); + return true; + } diff --git a/patches/unapplied/server/0945-Improve-tag-parser-handling.patch b/patches/server/0938-Improve-tag-parser-handling.patch similarity index 92% rename from patches/unapplied/server/0945-Improve-tag-parser-handling.patch rename to patches/server/0938-Improve-tag-parser-handling.patch index 9ffa70e38885..91b570e5aabe 100644 --- a/patches/unapplied/server/0945-Improve-tag-parser-handling.patch +++ b/patches/server/0938-Improve-tag-parser-handling.patch @@ -167,27 +167,18 @@ index df26c39a2bb20e2021b50211dce905483a77f4e6..5634122dac8afeecab0cde623e9868d8 text -> stream.map(Component::literal) .reduce((accumulator, current) -> accumulator.append(text).append(current)) diff --git a/src/main/java/net/minecraft/network/chat/contents/SelectorContents.java b/src/main/java/net/minecraft/network/chat/contents/SelectorContents.java -index 1337853badf8e124aa8439ce33a255bc4164125b..933388a60eda2af259d4ef761e31c5abb69c31fd 100644 +index 5e87f5a2bbffe2eba3fc4fb0da51acee99e72fc2..4131067620f723be28a6cdb7508e14d7e2aed48b 100644 --- a/src/main/java/net/minecraft/network/chat/contents/SelectorContents.java +++ b/src/main/java/net/minecraft/network/chat/contents/SelectorContents.java -@@ -50,7 +50,7 @@ public class SelectorContents implements ComponentContents { - EntitySelectorParser entitySelectorParser = new EntitySelectorParser(new StringReader(pattern), true); - entitySelector = entitySelectorParser.parse(); - } catch (CommandSyntaxException var3) { -- LOGGER.warn("Invalid selector component: {}: {}", pattern, var3.getMessage()); -+ return null; // Paper - } - - return entitySelector; -@@ -77,7 +77,7 @@ public class SelectorContents implements ComponentContents { - @Override - public MutableComponent resolve(@Nullable CommandSourceStack source, @Nullable Entity sender, int depth) throws CommandSyntaxException { - if (source != null && this.selector != null) { +@@ -36,7 +36,7 @@ public record SelectorContents(SelectorPattern selector, Optional sep + if (source == null) { + return Component.empty(); + } else { - Optional optional = ComponentUtils.updateForEntity(source, this.separator, sender, depth); + Optional optional = ComponentUtils.updateSeparatorForEntity(source, this.separator, sender, depth); // Paper - validate separator - return ComponentUtils.formatList(this.selector.findEntities(source), optional, Entity::getDisplayName); - } else { - return Component.empty(); + return ComponentUtils.formatList(this.selector.resolved().findEntities(source), optional, Entity::getDisplayName); + } + } diff --git a/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java b/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java index 56e641bc5f6edc657647993ea2efbb7bb9c2f732..4aa6232bf0f72fcde32d257100bd15b1c5192aaa 100644 --- a/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java @@ -248,10 +239,10 @@ index 898b19887ed34c87003fc63cb5905df2ba6234a5..b47eeb23055b135d5567552ba983bfbc private void write(FriendlyByteBuf buf) { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index fb935b505ec048522f9ab5d689b2c64c64f401a7..e0c46e548a34c963750c9411dfd3c0946d67a7c7 100644 +index 80755a80dfd484af361c208fd4de309ca7ef8553..74b70c7a41d03bae57e1b2863b7ce947f951da46 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -766,6 +766,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -770,6 +770,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return; } // Paper end - Don't suggest if tab-complete is disabled @@ -265,7 +256,7 @@ index fb935b505ec048522f9ab5d689b2c64c64f401a7..e0c46e548a34c963750c9411dfd3c094 // Paper start - AsyncTabCompleteEvent TAB_COMPLETE_EXECUTOR.execute(() -> this.handleCustomCommandSuggestions0(packet)); } -@@ -818,6 +825,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -822,6 +829,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private void sendServerSuggestions(final ServerboundCommandSuggestionPacket packet, final StringReader stringreader) { // Paper end - AsyncTabCompleteEvent ParseResults parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack()); diff --git a/patches/unapplied/server/0946-Item-Mutation-Fixes.patch b/patches/server/0939-Item-Mutation-Fixes.patch similarity index 90% rename from patches/unapplied/server/0946-Item-Mutation-Fixes.patch rename to patches/server/0939-Item-Mutation-Fixes.patch index bad3be61f9d6..f7242e591f91 100644 --- a/patches/unapplied/server/0946-Item-Mutation-Fixes.patch +++ b/patches/server/0939-Item-Mutation-Fixes.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Item Mutation Fixes diff --git a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java -index fff1c39920e7d7051dfe3dd39c77865d3bdf113e..1ef014b29645ed09ccffb898f1819428c3dc6259 100644 +index 36496144dd6fa87163b692034570eba70c83678c..b7300052f3c3d496ea41b681a2d5d5b554e67c63 100644 --- a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java +++ b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java -@@ -232,7 +232,7 @@ public class EnchantmentMenu extends AbstractContainerMenu { +@@ -220,7 +220,7 @@ public class EnchantmentMenu extends AbstractContainerMenu { return false; } else if (this.costs[id] > 0 && !itemstack.isEmpty() && (player.experienceLevel >= j && player.experienceLevel >= this.costs[id] || player.getAbilities().instabuild)) { this.access.execute((world, blockposition) -> { @@ -17,7 +17,7 @@ index fff1c39920e7d7051dfe3dd39c77865d3bdf113e..1ef014b29645ed09ccffb898f1819428 List list = this.getEnchantmentList(world.registryAccess(), itemstack, id, this.costs[id]); // CraftBukkit start -@@ -255,10 +255,16 @@ public class EnchantmentMenu extends AbstractContainerMenu { +@@ -243,10 +243,16 @@ public class EnchantmentMenu extends AbstractContainerMenu { return; } // CraftBukkit end diff --git a/patches/unapplied/server/0947-Per-world-ticks-per-spawn-settings.patch b/patches/server/0940-Per-world-ticks-per-spawn-settings.patch similarity index 90% rename from patches/unapplied/server/0947-Per-world-ticks-per-spawn-settings.patch rename to patches/server/0940-Per-world-ticks-per-spawn-settings.patch index 0d7c9ea5b4eb..a028a8c2344e 100644 --- a/patches/unapplied/server/0947-Per-world-ticks-per-spawn-settings.patch +++ b/patches/server/0940-Per-world-ticks-per-spawn-settings.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Per world ticks per spawn settings diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 471fd54edf6aa962d997878ee638974f7f594fa8..b7bf7b3b91046c81467aeb483087e12b6d9191bf 100644 +index 83537aa240ebff8dd19b450956730dc3d4f355a0..ffe894f3034a967f7e3d820c6416acb8adbcfb84 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -186,6 +186,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -22,9 +22,9 @@ index 471fd54edf6aa962d997878ee638974f7f594fa8..b7bf7b3b91046c81467aeb483087e12b + } + // Paper end - public abstract ResourceKey getTypeKey(); -@@ -198,7 +207,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + public abstract ResourceKey getTypeKey(); +@@ -199,7 +208,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // CraftBukkit Ticks things for (SpawnCategory spawnCategory : SpawnCategory.values()) { if (CraftSpawnCategory.isValidForLimits(spawnCategory)) { diff --git a/patches/unapplied/server/0948-Properly-track-the-changed-item-from-dispense-events.patch b/patches/server/0941-Properly-track-the-changed-item-from-dispense-events.patch similarity index 73% rename from patches/unapplied/server/0948-Properly-track-the-changed-item-from-dispense-events.patch rename to patches/server/0941-Properly-track-the-changed-item-from-dispense-events.patch index 2dc797fea793..4b58da1d3318 100644 --- a/patches/unapplied/server/0948-Properly-track-the-changed-item-from-dispense-events.patch +++ b/patches/server/0941-Properly-track-the-changed-item-from-dispense-events.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Properly track the changed item from dispense events diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -index 0c0b8a49b3342cd015381c6a93fab23c32cd32e6..60d3319016beb4f60cbc26dde165f64cf7577602 100644 +index 63b8c806b6ee0ea3cc5e6a7f613b5e57c94bfcf1..cd77e86ff289634d2dd1c56002e569ff70d15f25 100644 --- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -134,10 +134,14 @@ public interface DispenseItemBehavior { +@@ -129,10 +129,14 @@ public interface DispenseItemBehavior { idispensebehavior.dispense(pointer, eventStack); return stack; } @@ -19,12 +19,12 @@ index 0c0b8a49b3342cd015381c6a93fab23c32cd32e6..60d3319016beb4f60cbc26dde165f64c } try { -- entitytypes.spawn(pointer.level(), stack, (Player) null, pointer.pos().relative(enumdirection), MobSpawnType.DISPENSER, enumdirection != Direction.UP, false); -+ entitytypes.spawn(pointer.level(), itemstack1, (Player) null, pointer.pos().relative(enumdirection), MobSpawnType.DISPENSER, enumdirection != Direction.UP, false); // Paper - track changed item in dispense event +- entitytypes.spawn(pointer.level(), stack, (Player) null, pointer.pos().relative(enumdirection), EntitySpawnReason.DISPENSER, enumdirection != Direction.UP, false); ++ entitytypes.spawn(pointer.level(), itemstack1, (Player) null, pointer.pos().relative(enumdirection), EntitySpawnReason.DISPENSER, enumdirection != Direction.UP, false); // Paper - track changed item in dispense event } catch (Exception exception) { DispenseItemBehavior.LOGGER.error("Error while dispensing spawn egg from dispenser at {}", pointer.pos(), exception); // CraftBukkit - decompile error return ItemStack.EMPTY; -@@ -192,9 +196,10 @@ public interface DispenseItemBehavior { +@@ -186,9 +190,10 @@ public interface DispenseItemBehavior { } // CraftBukkit end @@ -33,19 +33,19 @@ index 0c0b8a49b3342cd015381c6a93fab23c32cd32e6..60d3319016beb4f60cbc26dde165f64c entityarmorstand.setYRot(enumdirection.toYRot()); - }, worldserver, stack, (Player) null); + }, worldserver, newStack, (Player) null); // Paper - track changed items in the dispense event - ArmorStand entityarmorstand = (ArmorStand) EntityType.ARMOR_STAND.spawn(worldserver, consumer, blockposition, MobSpawnType.DISPENSER, false, false); + ArmorStand entityarmorstand = (ArmorStand) EntityType.ARMOR_STAND.spawn(worldserver, consumer, blockposition, EntitySpawnReason.DISPENSER, false, false); if (entityarmorstand != null) { -@@ -244,7 +249,7 @@ public interface DispenseItemBehavior { +@@ -237,7 +242,7 @@ public interface DispenseItemBehavior { return stack; } } - ((Saddleable) list.get(0)).equipSaddle(itemstack1, SoundSource.BLOCKS); + ((Saddleable) list.get(0)).equipSaddle(CraftItemStack.asNMSCopy(event.getItem()), SoundSource.BLOCKS); // Paper - track changed items in dispense event // CraftBukkit end - if (shrink) stack.shrink(1); // Paper - actually handle here this.setSuccess(true); -@@ -414,6 +419,7 @@ public interface DispenseItemBehavior { + return stack; +@@ -330,6 +335,7 @@ public interface DispenseItemBehavior { int y = blockposition.getY(); int z = blockposition.getZ(); BlockState iblockdata = worldserver.getBlockState(blockposition); @@ -53,7 +53,7 @@ index 0c0b8a49b3342cd015381c6a93fab23c32cd32e6..60d3319016beb4f60cbc26dde165f64c // Paper start - correctly check if the bucket place will succeed /* Taken from SolidBucketItem#emptyContents */ boolean willEmptyContentsSolidBucketItem = dispensiblecontaineritem instanceof net.minecraft.world.item.SolidBucketItem && worldserver.isInWorldBounds(blockposition) && iblockdata.isAir(); -@@ -443,12 +449,15 @@ public interface DispenseItemBehavior { +@@ -359,12 +365,15 @@ public interface DispenseItemBehavior { } } @@ -72,28 +72,20 @@ index 0c0b8a49b3342cd015381c6a93fab23c32cd32e6..60d3319016beb4f60cbc26dde165f64c } else { return this.defaultDispenseItemBehavior.dispense(pointer, stack); diff --git a/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java b/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java -index 985954030654d521291cccbfc3ca49b67ee4357d..e37d2d29f3ba67cfe28abe4847a3dca07121f0be 100644 +index a9d230d6ff22d5e3a11b2f31e7d751f44888a12c..df495161a5842cf38518adabd359bb35193ee2b3 100644 --- a/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java -@@ -36,7 +36,7 @@ public class ProjectileDispenseBehavior extends DefaultDispenseItemBehavior { - ServerLevel worldserver = pointer.level(); - Direction enumdirection = (Direction) pointer.state().getValue(DispenserBlock.FACING); - Position iposition = this.dispenseConfig.positionFunction().getDispensePosition(pointer, enumdirection); -- Projectile iprojectile = this.projectileItem.asProjectile(worldserver, iposition, stack, enumdirection); -+ // Paper - move down - - // CraftBukkit start - // this.projectileItem.shoot(iprojectile, (double) enumdirection.getStepX(), (double) enumdirection.getStepY(), (double) enumdirection.getStepZ(), this.dispenseConfig.power(), this.dispenseConfig.uncertainty()); -@@ -66,6 +66,7 @@ public class ProjectileDispenseBehavior extends DefaultDispenseItemBehavior { +@@ -64,7 +64,7 @@ public class ProjectileDispenseBehavior extends DefaultDispenseItemBehavior { } } -+ Projectile iprojectile = this.projectileItem.asProjectile(worldserver, iposition, CraftItemStack.unwrap(event.getItem()), enumdirection); // Paper - move from above and track changed items in the dispense event; unwrap is safe here because all uses of the stack make their own copies - this.projectileItem.shoot(iprojectile, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), this.dispenseConfig.power(), this.dispenseConfig.uncertainty()); +- Projectile iprojectile = Projectile.spawnProjectileUsingShoot(this.projectileItem.asProjectile(worldserver, iposition, stack, enumdirection), worldserver, stack, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), this.dispenseConfig.power(), this.dispenseConfig.uncertainty()); ++ Projectile iprojectile = Projectile.spawnProjectileUsingShoot(this.projectileItem.asProjectile(worldserver, iposition, CraftItemStack.unwrap(event.getItem()), enumdirection), worldserver, stack, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), this.dispenseConfig.power(), this.dispenseConfig.uncertainty()); // Paper - mtrack changed items in the dispense event; unwrap is safe here because all uses of the stack make their own copies ((Entity) iprojectile).projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource(pointer.blockEntity()); + // itemstack.shrink(1); // CraftBukkit - Handled during event processing // CraftBukkit end diff --git a/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java -index 6f2adf2334e35e8a617a4ced0c1af2abf32bbd8d..cb308808906a8cdb127df8284e106e00553473ca 100644 +index f84987c36a16df19286d6f1badfb1ffb9cc7e770..8e089f7d5e7fa9ddeccd0691185555f279d55426 100644 --- a/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java @@ -57,7 +57,12 @@ public class ShulkerBoxDispenseBehavior extends OptionalDispenseItemBehavior { diff --git a/patches/unapplied/server/0949-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch b/patches/server/0942-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch similarity index 86% rename from patches/unapplied/server/0949-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch rename to patches/server/0942-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch index 89974873d20c..e76c0c9c8755 100644 --- a/patches/unapplied/server/0949-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch +++ b/patches/server/0942-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch @@ -12,20 +12,8 @@ So protect them from a multitude of methods of destroying them. A config is provided if you rather let players use these exploits, and let them destroy the worlds End Portals and get on top of the nether easy. -diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index edcc9d53ad81e2b2444335ac79abde5a4e2d9d47..2109257fde8606abda4f41427f690da3b96c0175 100644 ---- a/src/main/java/net/minecraft/world/level/Explosion.java -+++ b/src/main/java/net/minecraft/world/level/Explosion.java -@@ -194,6 +194,7 @@ public class Explosion { - for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) { - BlockPos blockposition = BlockPos.containing(d4, d5, d6); - BlockState iblockdata = this.level.getBlockState(blockposition); -+ if (!iblockdata.isDestroyable()) continue; // Paper - Protect Bedrock and End Portal/Frames from being destroyed - FluidState fluid = iblockdata.getFluidState(); // Paper - Perf: Optimize call to getFluid for explosions - - if (!this.level.isInWorldBounds(blockposition)) { diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 9ca71a060f916868e70222e0cdc0f96b96bac450..751da19e147049c4f196d9b200b7baf9bebaed81 100644 +index ffe894f3034a967f7e3d820c6416acb8adbcfb84..35b9a6d382e420844fc21c88b7d8044e3b8b8368 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -447,6 +447,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -39,8 +27,20 @@ index 9ca71a060f916868e70222e0cdc0f96b96bac450..751da19e147049c4f196d9b200b7baf9 CraftBlockState blockstate = this.capturedBlockStates.get(pos); if (blockstate == null) { blockstate = CapturedBlockState.getTreeBlockState(this, pos, flags); +diff --git a/src/main/java/net/minecraft/world/level/ServerExplosion.java b/src/main/java/net/minecraft/world/level/ServerExplosion.java +index 86656de31b1e33381eddd3ef210122118b31e620..fd1ecedfab037e377e4dded61539689bacc90f80 100644 +--- a/src/main/java/net/minecraft/world/level/ServerExplosion.java ++++ b/src/main/java/net/minecraft/world/level/ServerExplosion.java +@@ -150,6 +150,7 @@ public class ServerExplosion implements Explosion { + for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) { + BlockPos blockposition = BlockPos.containing(d4, d5, d6); + BlockState iblockdata = this.level.getBlockState(blockposition); ++ if (!iblockdata.isDestroyable()) continue; // Paper - Protect Bedrock and End Portal/Frames from being destroyed + FluidState fluid = iblockdata.getFluidState(); // Paper - Perf: Optimize call to getFluid for explosions + + if (!this.level.isInWorldBounds(blockposition)) { diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index bf52c36f31992a01a7403d8c85151327c9e944c4..3b06c080afebde1d649f05eca0af938ba32931c1 100644 +index 9917df070d9815b6915e4a0b022dfe4e5b7861e7..729c3d8279b13d21c65ede89ea50869b69d5bfe6 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java @@ -89,6 +89,19 @@ public class Block extends BlockBehaviour implements ItemLike { @@ -64,10 +64,10 @@ index bf52c36f31992a01a7403d8c85151327c9e944c4..3b06c080afebde1d649f05eca0af938b public co.aikar.timings.Timing getTiming() { if (timing == null) { diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java -index e6bfbe2588e0c2a1be14e38d654e889d392ad4db..e0c62227b279a5fe0f3868fbf9ce8c78c515a09c 100644 +index b27cf7d27672ba9ff8ade84b5a8454b19b935607..83bffe2ac011ed0cbd86149e3c803393d30a9e6e 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java +++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java -@@ -213,6 +213,12 @@ public class PistonBaseBlock extends DirectionalBlock { +@@ -216,6 +216,12 @@ public class PistonBaseBlock extends DirectionalBlock { @Override protected boolean triggerEvent(BlockState state, Level world, BlockPos pos, int type, int data) { Direction enumdirection = (Direction) state.getValue(PistonBaseBlock.FACING); @@ -80,7 +80,7 @@ index e6bfbe2588e0c2a1be14e38d654e889d392ad4db..e0c62227b279a5fe0f3868fbf9ce8c78 BlockState iblockdata1 = (BlockState) state.setValue(PistonBaseBlock.EXTENDED, true); if (!world.isClientSide) { -@@ -253,7 +259,7 @@ public class PistonBaseBlock extends DirectionalBlock { +@@ -256,7 +262,7 @@ public class PistonBaseBlock extends DirectionalBlock { } // Paper end - Fix sticky pistons and BlockPistonRetractEvent world.setBlock(pos, iblockdata2, 20); @@ -89,7 +89,7 @@ index e6bfbe2588e0c2a1be14e38d654e889d392ad4db..e0c62227b279a5fe0f3868fbf9ce8c78 world.blockUpdated(pos, iblockdata2.getBlock()); iblockdata2.updateNeighbourShapes(world, pos, 2); if (this.isSticky) { -@@ -289,7 +295,14 @@ public class PistonBaseBlock extends DirectionalBlock { +@@ -292,7 +298,14 @@ public class PistonBaseBlock extends DirectionalBlock { } } } else { @@ -106,19 +106,19 @@ index e6bfbe2588e0c2a1be14e38d654e889d392ad4db..e0c62227b279a5fe0f3868fbf9ce8c78 world.playSound((Player) null, pos, SoundEvents.PISTON_CONTRACT, SoundSource.BLOCKS, 0.5F, world.random.nextFloat() * 0.15F + 0.6F); diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -index 240c250a93289776686d09d7eae17c07d7278da5..f2036917c5ba9f536087d7ee559704055469730e 100644 +index 1b988b92e80faa1ac224caf9f9e955ac43a4c45a..95d30c2db7e291d65c24feb114b0f3598d280912 100644 --- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -@@ -174,7 +174,7 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -178,7 +178,7 @@ public abstract class BlockBehaviour implements FeatureElement { } - protected void onExplosionHit(BlockState state, Level world, BlockPos pos, Explosion explosion, BiConsumer stackMerger) { + protected void onExplosionHit(BlockState state, ServerLevel world, BlockPos pos, Explosion explosion, BiConsumer stackMerger) { - if (!state.isAir() && explosion.getBlockInteraction() != Explosion.BlockInteraction.TRIGGER_BLOCK) { + if (!state.isAir() && explosion.getBlockInteraction() != Explosion.BlockInteraction.TRIGGER_BLOCK && state.isDestroyable()) { // Paper - Protect Bedrock and End Portal/Frames from being destroyed Block block = state.getBlock(); boolean flag = explosion.getIndirectSourceEntity() instanceof Player; -@@ -254,7 +254,7 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -257,7 +257,7 @@ public abstract class BlockBehaviour implements FeatureElement { } protected boolean canBeReplaced(BlockState state, BlockPlaceContext context) { @@ -127,7 +127,7 @@ index 240c250a93289776686d09d7eae17c07d7278da5..f2036917c5ba9f536087d7ee55970405 } protected boolean canBeReplaced(BlockState state, Fluid fluid) { -@@ -883,6 +883,12 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -945,6 +945,12 @@ public abstract class BlockBehaviour implements FeatureElement { return this.legacySolid; } @@ -140,7 +140,7 @@ index 240c250a93289776686d09d7eae17c07d7278da5..f2036917c5ba9f536087d7ee55970405 public boolean isValidSpawn(BlockGetter world, BlockPos pos, EntityType type) { return this.getBlock().properties.isValidSpawn.test(this.asState(), world, pos, type); } -@@ -986,7 +992,7 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -1048,7 +1054,7 @@ public abstract class BlockBehaviour implements FeatureElement { } public PushReaction getPistonPushReaction() { @@ -148,9 +148,9 @@ index 240c250a93289776686d09d7eae17c07d7278da5..f2036917c5ba9f536087d7ee55970405 + return !this.isDestroyable() ? PushReaction.BLOCK : this.pushReaction; // Paper - Protect Bedrock and End Portal/Frames from being destroyed } - public boolean isSolidRender(BlockGetter world, BlockPos pos) { + public boolean isSolidRender() { diff --git a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java -index 5c4b2a33d4007c36aef68604bca40a4eba510b4e..fd04a50183ccb1f21fc6efa70256e1bb4db2d6d4 100644 +index eb409fb5e673d2a343813946cc59cb5da2328eec..83d294f6f48b867d09ea0d339c779011bf4138a5 100644 --- a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java +++ b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java @@ -207,6 +207,13 @@ public class PortalForcer { diff --git a/patches/unapplied/server/0951-Add-config-for-mobs-immune-to-default-effects.patch b/patches/server/0943-Add-config-for-mobs-immune-to-default-effects.patch similarity index 86% rename from patches/unapplied/server/0951-Add-config-for-mobs-immune-to-default-effects.patch rename to patches/server/0943-Add-config-for-mobs-immune-to-default-effects.patch index 74dd1a136012..c3b01a16eda7 100644 --- a/patches/unapplied/server/0951-Add-config-for-mobs-immune-to-default-effects.patch +++ b/patches/server/0943-Add-config-for-mobs-immune-to-default-effects.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add config for mobs immune to default effects diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java -index 62271e74399a827a488159da234465ef18e15e6e..d3b4d492aee380dc17f4232d90eaae4f07bb9f86 100644 +index e1be143959fbaa1d54af2a1a2c27187d70e6a9e9..244e38db508efa3eebebb6392c4ebb0805367baf 100644 --- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java +++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java -@@ -604,7 +604,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob +@@ -602,7 +602,7 @@ public class WitherBoss extends Monster implements RangedAttackMob { @Override public boolean canBeAffected(MobEffectInstance effect) { @@ -18,7 +18,7 @@ index 62271e74399a827a488159da234465ef18e15e6e..d3b4d492aee380dc17f4232d90eaae4f private class WitherDoNothingGoal extends Goal { diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java -index 9045f18f49a5c6685597d0a77126d7cb35bc5e88..a30fb47559eb74b7fe634678e63a85e7e2cad9a4 100644 +index 72e42605c278028480c368762da18f61806d766a..91e521414c3ea5722aac7506b7589fbb399e9636 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Spider.java +++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java @@ -126,7 +126,7 @@ public class Spider extends Monster { @@ -31,7 +31,7 @@ index 9045f18f49a5c6685597d0a77126d7cb35bc5e88..a30fb47559eb74b7fe634678e63a85e7 public boolean isClimbing() { diff --git a/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java -index 56f23d7c7b5838ff8761de8691e685dd59d2eaa2..bb2e7cee612dc1fafa042674a0b0d07d7165b54c 100644 +index c295b604f438c62d589ab05ea44c85dbefcb258b..37d3acda84a984bf4f1c44b3d27e2102839d3e8e 100644 --- a/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java +++ b/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java @@ -114,6 +114,6 @@ public class WitherSkeleton extends AbstractSkeleton { diff --git a/patches/unapplied/server/0952-Deep-clone-nbt-tags-in-PDC.patch b/patches/server/0944-Deep-clone-nbt-tags-in-PDC.patch similarity index 89% rename from patches/unapplied/server/0952-Deep-clone-nbt-tags-in-PDC.patch rename to patches/server/0944-Deep-clone-nbt-tags-in-PDC.patch index 944099f20910..559c6cddea9b 100644 --- a/patches/unapplied/server/0952-Deep-clone-nbt-tags-in-PDC.patch +++ b/patches/server/0944-Deep-clone-nbt-tags-in-PDC.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Deep clone nbt tags in PDC diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index f15456b02cabbbe33d701450ef53a0561d91cb8c..7ad1076de76c81c25b656e52237c2f60a2eca085 100644 +index 3bcc807005a677884255f1ee36cbf1653797ba55..8d13505c36d732f17293c6a6d65cac20919b8b7a 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -@@ -322,7 +322,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -372,7 +372,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { this.maxDamage = meta.maxDamage; this.unhandledTags.copy(meta.unhandledTags.build()); this.removedTags.addAll(meta.removedTags); @@ -17,7 +17,7 @@ index f15456b02cabbbe33d701450ef53a0561d91cb8c..7ad1076de76c81c25b656e52237c2f60 this.customTag = meta.customTag; -@@ -1699,7 +1699,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1966,7 +1966,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { clone.customTag = this.customTag.copy(); } clone.removedTags = Sets.newHashSet(this.removedTags); @@ -25,7 +25,7 @@ index f15456b02cabbbe33d701450ef53a0561d91cb8c..7ad1076de76c81c25b656e52237c2f60 + clone.persistentDataContainer = new CraftPersistentDataContainer(this.persistentDataContainer.getTagsCloned(), CraftMetaItem.DATA_TYPE_REGISTRY); // Paper - deep clone NBT tags clone.hideFlag = this.hideFlag; clone.hideTooltip = this.hideTooltip; - clone.unbreakable = this.unbreakable; + clone.tooltipStyle = this.tooltipStyle; diff --git a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java index 5a4e7e7150b7c137b077e0b393f17ed35b5aec34..f55fdd57ced259ad5a95878840e98ffaa3db2e05 100644 --- a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java diff --git a/patches/unapplied/server/0944-Fix-possible-StackOverflowError-for-some-dispenses.patch b/patches/unapplied/server/0944-Fix-possible-StackOverflowError-for-some-dispenses.patch deleted file mode 100644 index 5351dde83c76..000000000000 --- a/patches/unapplied/server/0944-Fix-possible-StackOverflowError-for-some-dispenses.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sat, 29 Oct 2022 17:02:42 -0700 -Subject: [PATCH] Fix possible StackOverflowError for some dispenses - -For saddles, carpets, horse armor, and chests for horse-likes -a BlockDispenseEvent handler that always mutated the item without -changing the type would result in a SO error because when it went -to find the replacement dispense behavior (since the item "changed") -it didn't properly handle if the replacement was the same instance -of dispense behavior. - -Additionally equippable mob heads, wither skulls, and carved pumpkins -are subject to the same possible error. - -diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -index 7826e2a52da47914aca39fef958b8f398a2ff937..0c0b8a49b3342cd015381c6a93fab23c32cd32e6 100644 ---- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -+++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -239,7 +239,7 @@ public interface DispenseItemBehavior { - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != ArmorItem.DISPENSE_ITEM_BEHAVIOR) { -+ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { // Paper - fix possible StackOverflowError - idispensebehavior.dispense(pointer, eventStack); - return stack; - } -@@ -295,7 +295,7 @@ public interface DispenseItemBehavior { - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != ArmorItem.DISPENSE_ITEM_BEHAVIOR) { -+ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { // Paper - fix possible StackOverflowError - idispensebehavior.dispense(pointer, eventStack); - return stack; - } -@@ -369,7 +369,7 @@ public interface DispenseItemBehavior { - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != ArmorItem.DISPENSE_ITEM_BEHAVIOR) { -+ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { // Paper - fix possible StackOverflowError - idispensebehavior.dispense(pointer, eventStack); - return stack; - } -@@ -690,7 +690,7 @@ public interface DispenseItemBehavior { - OptionalDispenseItemBehavior dispensebehaviormaybe1 = new OptionalDispenseItemBehavior() { - @Override - protected ItemStack execute(BlockSource pointer, ItemStack stack) { -- this.setSuccess(ArmorItem.dispenseArmor(pointer, stack)); -+ this.setSuccess(ArmorItem.dispenseArmor(pointer, stack, this)); // Paper - fix possible StackOverflowError - return stack; - } - }; -@@ -744,7 +744,7 @@ public interface DispenseItemBehavior { - stack.shrink(1); - this.setSuccess(true); - } else { -- this.setSuccess(ArmorItem.dispenseArmor(pointer, stack)); -+ this.setSuccess(ArmorItem.dispenseArmor(pointer, stack, this)); // Paper - fix possible StackOverflowError - } - - return stack; -@@ -790,7 +790,7 @@ public interface DispenseItemBehavior { - stack.shrink(1); - this.setSuccess(true); - } else { -- this.setSuccess(ArmorItem.dispenseArmor(pointer, stack)); -+ this.setSuccess(ArmorItem.dispenseArmor(pointer, stack, this)); // Paper - fix possible StackOverflowError - } - - return stack; -@@ -918,7 +918,7 @@ public interface DispenseItemBehavior { - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != ArmorItem.DISPENSE_ITEM_BEHAVIOR) { -+ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { // Paper - fix possible StackOverflowError - idispensebehavior.dispense(pointer, eventStack); - return stack; - } -diff --git a/src/main/java/net/minecraft/world/item/ArmorItem.java b/src/main/java/net/minecraft/world/item/ArmorItem.java -index fb518f87cc4ccd810fb32cade2fdd7e09ab0abfc..647a4601deace52f8d855f512a73671f82b4762a 100644 ---- a/src/main/java/net/minecraft/world/item/ArmorItem.java -+++ b/src/main/java/net/minecraft/world/item/ArmorItem.java -@@ -39,14 +39,20 @@ public class ArmorItem extends Item implements Equipable { - public static final DispenseItemBehavior DISPENSE_ITEM_BEHAVIOR = new DefaultDispenseItemBehavior() { - @Override - protected ItemStack execute(BlockSource pointer, ItemStack stack) { -- return ArmorItem.dispenseArmor(pointer, stack) ? stack : super.execute(pointer, stack); -+ return ArmorItem.dispenseArmor(pointer, stack, this) ? stack : super.execute(pointer, stack); // Paper - fix possible StackOverflowError - } - }; - protected final ArmorItem.Type type; - protected final Holder material; - private final Supplier defaultModifiers; - -+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - public static boolean dispenseArmor(BlockSource pointer, ItemStack armor) { -+ // Paper start -+ return dispenseArmor(pointer, armor, null); -+ } -+ public static boolean dispenseArmor(BlockSource pointer, ItemStack armor, @javax.annotation.Nullable DispenseItemBehavior currentBehavior) { -+ // Paper end - BlockPos blockposition = pointer.pos().relative((Direction) pointer.state().getValue(DispenserBlock.FACING)); - List list = pointer.level().getEntitiesOfClass(LivingEntity.class, new AABB(blockposition), EntitySelector.NO_SPECTATORS.and(new EntitySelector.MobCanWearArmorEntitySelector(armor))); - -@@ -77,7 +83,7 @@ public class ArmorItem extends Item implements Equipable { - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != ArmorItem.DISPENSE_ITEM_BEHAVIOR) { -+ if (idispensebehavior != DispenseItemBehavior.NOOP && (currentBehavior == null || idispensebehavior != currentBehavior)) { // Paper - fix possible StackOverflowError - idispensebehavior.dispense(pointer, eventStack); - return true; - } diff --git a/patches/unapplied/server/0950-Fix-tripwire-disarming-not-working-as-intended.patch b/patches/unapplied/server/0950-Fix-tripwire-disarming-not-working-as-intended.patch deleted file mode 100644 index fa7f6bde0667..000000000000 --- a/patches/unapplied/server/0950-Fix-tripwire-disarming-not-working-as-intended.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: DungeonDev -Date: Sun, 2 Jul 2023 02:34:54 +0100 -Subject: [PATCH] Fix tripwire disarming not working as intended - -Fixes MC-129055 - -diff --git a/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java b/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java -index 8614fad5b3df7a6030384b108b1689bf6b9f1209..76aca266d3f3222502ff4c196228f08fcd88c5f8 100644 ---- a/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java -@@ -202,9 +202,8 @@ public class TripWireHookBlock extends Block { - BlockState iblockdata4 = aiblockdata[l]; - - if (iblockdata4 != null) { -+ if (world.getBlockState(blockposition2).is(Blocks.TRIPWIRE) || io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowTripwireDisarmingExploits) { // Paper - Fix tripwire disarming not working as intended - world.setBlock(blockposition2, (BlockState) iblockdata4.trySetValue(TripWireHookBlock.ATTACHED, flag4), 3); -- if (!world.getBlockState(blockposition2).isAir()) { -- ; - } - } - } From 7d4cce94ae30af6e091d59af33979eeab3e72175 Mon Sep 17 00:00:00 2001 From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Date: Thu, 24 Oct 2024 10:02:45 -0400 Subject: [PATCH 039/119] Patch --- ...945-Support-old-UUID-format-for-NBT.patch} | 0 ...46-Fix-shield-disable-inconsistency.patch} | 4 +- ...-Large-Packets-disconnecting-client.patch} | 4 +- .../0948-Fix-ItemFlags.patch} | 32 +++++------ ...et-damage-reduction-inconsistencies.patch} | 4 +- ...-handling-of-LivingEntity-actuallyH.patch} | 18 +++--- ...e-checking-handled-tags-in-itemmeta.patch} | 56 ++++++++++++------- ...52-Expose-hasColor-to-leather-armor.patch} | 8 +-- ...-API-to-get-player-ha-proxy-address.patch} | 6 +- 9 files changed, 73 insertions(+), 59 deletions(-) rename patches/{unapplied/server/0953-Support-old-UUID-format-for-NBT.patch => server/0945-Support-old-UUID-format-for-NBT.patch} (100%) rename patches/{unapplied/server/0954-Fix-shield-disable-inconsistency.patch => server/0946-Fix-shield-disable-inconsistency.patch} (87%) rename patches/{unapplied/server/0955-Handle-Large-Packets-disconnecting-client.patch => server/0947-Handle-Large-Packets-disconnecting-client.patch} (97%) rename patches/{unapplied/server/0956-Fix-ItemFlags.patch => server/0948-Fix-ItemFlags.patch} (80%) rename patches/{unapplied/server/0957-Fix-helmet-damage-reduction-inconsistencies.patch => server/0949-Fix-helmet-damage-reduction-inconsistencies.patch} (87%) rename patches/{unapplied/server/0958-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch => server/0950-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch} (77%) rename patches/{unapplied/server/0959-improve-checking-handled-tags-in-itemmeta.patch => server/0951-improve-checking-handled-tags-in-itemmeta.patch} (96%) rename patches/{unapplied/server/0961-Expose-hasColor-to-leather-armor.patch => server/0952-Expose-hasColor-to-leather-armor.patch} (82%) rename patches/{unapplied/server/0962-Added-API-to-get-player-ha-proxy-address.patch => server/0953-Added-API-to-get-player-ha-proxy-address.patch} (93%) diff --git a/patches/unapplied/server/0953-Support-old-UUID-format-for-NBT.patch b/patches/server/0945-Support-old-UUID-format-for-NBT.patch similarity index 100% rename from patches/unapplied/server/0953-Support-old-UUID-format-for-NBT.patch rename to patches/server/0945-Support-old-UUID-format-for-NBT.patch diff --git a/patches/unapplied/server/0954-Fix-shield-disable-inconsistency.patch b/patches/server/0946-Fix-shield-disable-inconsistency.patch similarity index 87% rename from patches/unapplied/server/0954-Fix-shield-disable-inconsistency.patch rename to patches/server/0946-Fix-shield-disable-inconsistency.patch index 61614305d9a7..79d830402022 100644 --- a/patches/unapplied/server/0954-Fix-shield-disable-inconsistency.patch +++ b/patches/server/0946-Fix-shield-disable-inconsistency.patch @@ -8,10 +8,10 @@ it will not disable the shield if the attacker is holding an axe item. diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 94169703c5a8111df1ed550d57f59f4a3bb97ae1..6ff33a6d46daffd15310f21ec00d4861478b360f 100644 +index a7f0d49637eb72b4645997a97cc6927b16a59738..1b9f03dcf63c44c11e79022cb6cce5f6bd1ea30a 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2349,7 +2349,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2426,7 +2426,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.hurtCurrentlyUsedShield((float) -event.getDamage(DamageModifier.BLOCKING)); Entity entity = damagesource.getDirectEntity(); diff --git a/patches/unapplied/server/0955-Handle-Large-Packets-disconnecting-client.patch b/patches/server/0947-Handle-Large-Packets-disconnecting-client.patch similarity index 97% rename from patches/unapplied/server/0955-Handle-Large-Packets-disconnecting-client.patch rename to patches/server/0947-Handle-Large-Packets-disconnecting-client.patch index ea20a101a74d..32e463a24238 100644 --- a/patches/unapplied/server/0955-Handle-Large-Packets-disconnecting-client.patch +++ b/patches/server/0947-Handle-Large-Packets-disconnecting-client.patch @@ -95,7 +95,7 @@ index 4c776c591dd0a7b36945a6487fdfe86d1187b4af..82fc12ffbd1585b4a8d09a025914830a return false; } diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java -index 7e555ece0555b3d2a983ab2c39c5e7ec23fc7e88..8cca2ac616a2c80268c96b9f95e33f834a0fc8fd 100644 +index f53c74fb1863a2d1268a4ddf8cf69d1fda32d73f..8d5939e03a065197af125d95a10134abbccd07ec 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java @@ -36,6 +36,21 @@ public class ClientboundContainerSetContentPacket implements Packet HIDE_ADDITIONAL_TOOLTIP = new ItemMetaKeyType(DataComponents.HIDE_ADDITIONAL_TOOLTIP); @Specific(Specific.To.NBT) static final ItemMetaKeyType CUSTOM_DATA = new ItemMetaKeyType<>(DataComponents.CUSTOM_DATA); @@ -49,7 +49,7 @@ index 7ad1076de76c81c25b656e52237c2f60a2eca085..c2a215544589d903633c5aed51522870 // We store the raw original JSON representation of all text data. See SPIGOT-5063, SPIGOT-5656, SPIGOT-5304 private Component displayName; -@@ -327,6 +333,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -377,6 +383,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { this.customTag = meta.customTag; this.version = meta.version; @@ -60,7 +60,7 @@ index 7ad1076de76c81c25b656e52237c2f60a2eca085..c2a215544589d903633c5aed51522870 } CraftMetaItem(DataComponentPatch tag) { -@@ -425,6 +435,20 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -496,6 +506,20 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { this.customTag = null; } }); @@ -81,7 +81,7 @@ index 7ad1076de76c81c25b656e52237c2f60a2eca085..c2a215544589d903633c5aed51522870 Set, Optional>> keys = tag.entrySet(); for (Map.Entry, Optional> key : keys) { -@@ -627,7 +651,15 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -735,7 +759,15 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { try { CompoundTag unhandledTag = NbtIo.readCompressed(buf, NbtAccounter.unlimitedHeap()); DataComponentPatch unhandledPatch = DataComponentPatch.CODEC.parse(MinecraftServer.getDefaultRegistryAccess().createSerializationContext(NbtOps.INSTANCE), unhandledTag).result().get(); @@ -98,7 +98,7 @@ index 7ad1076de76c81c25b656e52237c2f60a2eca085..c2a215544589d903633c5aed51522870 for (Entry, Optional> entry : unhandledPatch.entrySet()) { // Move removed unhandled tags to dedicated removedTags -@@ -870,6 +902,15 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1006,6 +1038,15 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { itemTag.put(CraftMetaItem.MAX_DAMAGE, this.maxDamage); } @@ -114,16 +114,16 @@ index 7ad1076de76c81c25b656e52237c2f60a2eca085..c2a215544589d903633c5aed51522870 for (Map.Entry, Optional> e : this.unhandledTags.build().entrySet()) { e.getValue().ifPresent((value) -> { itemTag.builder.set((DataComponentType) e.getKey(), value); -@@ -960,7 +1001,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1096,7 +1137,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Overridden boolean isEmpty() { -- return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.removedTags.isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasTool() || this.hasJukeboxPlayable() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null); -+ return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.removedTags.isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasTool() || this.hasJukeboxPlayable() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper +- return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasEnchantable() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.removedTags.isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.hasTooltipStyle() || this.hasItemModel() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isGlider() || this.hasDamageResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasUseRemainder() || this.hasUseCooldown() || this.hasFood() || this.hasTool() || this.hasJukeboxPlayable() || this.hasEquippable() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null); ++ return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasEnchantable() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.removedTags.isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.hasTooltipStyle() || this.hasItemModel() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isGlider() || this.hasDamageResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasUseRemainder() || this.hasUseCooldown() || this.hasFood() || this.hasTool() || this.hasJukeboxPlayable() || this.hasEquippable() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper } // Paper start -@@ -1630,6 +1671,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1889,6 +1930,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { && (this.hasJukeboxPlayable() ? that.hasJukeboxPlayable() && this.jukebox.equals(that.jukebox) : !that.hasJukeboxPlayable()) && (this.hasDamage() ? that.hasDamage() && this.damage == that.damage : !that.hasDamage()) && (this.hasMaxDamage() ? that.hasMaxDamage() && this.maxDamage.equals(that.maxDamage) : !that.hasMaxDamage()) @@ -132,7 +132,7 @@ index 7ad1076de76c81c25b656e52237c2f60a2eca085..c2a215544589d903633c5aed51522870 && (this.version == that.version); } -@@ -1675,6 +1718,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1941,6 +1984,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { hash = 61 * hash + (this.hasDamage() ? this.damage : 0); hash = 61 * hash + (this.hasMaxDamage() ? 1231 : 1237); hash = 61 * hash + (this.hasAttributeModifiers() ? this.attributeModifiers.hashCode() : 0); @@ -141,7 +141,7 @@ index 7ad1076de76c81c25b656e52237c2f60a2eca085..c2a215544589d903633c5aed51522870 hash = 61 * hash + this.version; return hash; } -@@ -1719,6 +1764,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1998,6 +2043,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { clone.damage = this.damage; clone.maxDamage = this.maxDamage; clone.version = this.version; @@ -156,7 +156,7 @@ index 7ad1076de76c81c25b656e52237c2f60a2eca085..c2a215544589d903633c5aed51522870 return clone; } catch (CloneNotSupportedException e) { throw new Error(e); -@@ -1836,6 +1889,16 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2142,6 +2195,16 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { } } @@ -171,9 +171,9 @@ index 7ad1076de76c81c25b656e52237c2f60a2eca085..c2a215544589d903633c5aed51522870 + } + // Paper end if (!this.unhandledTags.isEmpty()) { - Tag unhandled = DataComponentPatch.CODEC.encodeStart(MinecraftServer.getDefaultRegistryAccess().createSerializationContext(NbtOps.INSTANCE), this.unhandledTags.build()).getOrThrow(IllegalStateException::new); + net.minecraft.nbt.Tag unhandled = DataComponentPatch.CODEC.encodeStart(MinecraftServer.getDefaultRegistryAccess().createSerializationContext(NbtOps.INSTANCE), this.unhandledTags.build()).getOrThrow(IllegalStateException::new); try { -@@ -1846,6 +1909,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2152,6 +2215,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex); } } @@ -188,7 +188,7 @@ index 7ad1076de76c81c25b656e52237c2f60a2eca085..c2a215544589d903633c5aed51522870 if (!this.removedTags.isEmpty()) { RegistryAccess registryAccess = CraftRegistry.getMinecraftRegistry(); -@@ -1999,6 +2070,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2312,6 +2383,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { CraftMetaItem.MAX_DAMAGE.TYPE, CraftMetaItem.CUSTOM_DATA.TYPE, CraftMetaItem.ATTRIBUTES.TYPE, diff --git a/patches/unapplied/server/0957-Fix-helmet-damage-reduction-inconsistencies.patch b/patches/server/0949-Fix-helmet-damage-reduction-inconsistencies.patch similarity index 87% rename from patches/unapplied/server/0957-Fix-helmet-damage-reduction-inconsistencies.patch rename to patches/server/0949-Fix-helmet-damage-reduction-inconsistencies.patch index a8b503a8ea7d..186441aa4d43 100644 --- a/patches/unapplied/server/0957-Fix-helmet-damage-reduction-inconsistencies.patch +++ b/patches/server/0949-Fix-helmet-damage-reduction-inconsistencies.patch @@ -7,10 +7,10 @@ Affect the falling stalactite damage type where the reduction is not applied like in Vanilla diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 1b21fdab4269df375d2f445df3bd56f7b1fd2b15..4632eb883e9f5efde520ee543bcad25827c0da2c 100644 +index b0e7d1841d71e377d5ad596a22dfafb90d4f80cc..659d38c90f20f744261190c451235dbca8352e38 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1228,7 +1228,7 @@ public class CraftEventFactory { +@@ -1226,7 +1226,7 @@ public class CraftEventFactory { modifiers.put(DamageModifier.FREEZING, freezingModifier); modifierFunctions.put(DamageModifier.FREEZING, freezing); } diff --git a/patches/unapplied/server/0958-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch b/patches/server/0950-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch similarity index 77% rename from patches/unapplied/server/0958-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch rename to patches/server/0950-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch index 2965a66127b7..b4178f2bef1c 100644 --- a/patches/unapplied/server/0958-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch +++ b/patches/server/0950-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch @@ -5,35 +5,35 @@ Subject: [PATCH] Revert to vanilla handling of LivingEntity#actuallyHurt diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 6ff33a6d46daffd15310f21ec00d4861478b360f..b1e894e9a9cd87f7259302d15d5b5b0e2b32c4ea 100644 +index 1b9f03dcf63c44c11e79022cb6cce5f6bd1ea30a..6f9c4a5a87bdfb8ce32ce40c4a34997695d15ce3 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1425,7 +1425,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1457,7 +1457,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + amount = 0.0F; } - this.noActionTime = 0; - float f1 = amount; + float f1 = amount; final float originalAmount = f1; // Paper - revert to vanilla #hurt - OBFHELPER boolean flag = amount > 0.0F && this.isDamageSourceBlocked(source); // Copied from below float f2 = 0.0F; -@@ -1479,6 +1479,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - if (!this.actuallyHurt(source, (float) event.getFinalDamage() - this.lastHurt, event)) { +@@ -1515,6 +1515,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + if (!this.actuallyHurt(world, source, (float) event.getFinalDamage() - this.lastHurt, event)) { return false; } + if (this instanceof ServerPlayer && event.getDamage() == 0 && originalAmount == 0) return false; // Paper - revert to vanilla damage - players are not affected by damage that is 0 - skip damage if the vanilla damage is 0 and was not modified by plugins in the event. // CraftBukkit end this.lastHurt = amount; flag1 = false; -@@ -1487,6 +1488,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - if (!this.actuallyHurt(source, (float) event.getFinalDamage(), event)) { +@@ -1523,6 +1524,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + if (!this.actuallyHurt(world, source, (float) event.getFinalDamage(), event)) { return false; } + if (this instanceof ServerPlayer && event.getDamage() == 0 && originalAmount == 0) return false; // Paper - revert to vanilla damage - players are not affected by damage that is 0 - skip damage if the vanilla damage is 0 and was not modified by plugins in the event. this.lastHurt = amount; this.invulnerableTime = this.invulnerableDuration; // CraftBukkit - restore use of maxNoDamageTicks - // this.actuallyHurt(damagesource, f); -@@ -2411,12 +2413,12 @@ public abstract class LivingEntity extends Entity implements Attackable { + // this.actuallyHurt(worldserver, damagesource, f); +@@ -2488,12 +2490,12 @@ public abstract class LivingEntity extends Entity implements Attackable { return true; } else { diff --git a/patches/unapplied/server/0959-improve-checking-handled-tags-in-itemmeta.patch b/patches/server/0951-improve-checking-handled-tags-in-itemmeta.patch similarity index 96% rename from patches/unapplied/server/0959-improve-checking-handled-tags-in-itemmeta.patch rename to patches/server/0951-improve-checking-handled-tags-in-itemmeta.patch index 83c83dde6826..41f857627abd 100644 --- a/patches/unapplied/server/0959-improve-checking-handled-tags-in-itemmeta.patch +++ b/patches/server/0951-improve-checking-handled-tags-in-itemmeta.patch @@ -5,10 +5,10 @@ Subject: [PATCH] improve checking handled tags in itemmeta diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java -index a4c4ba0d02f9a072236ce86c1e98e2c60b059cb8..0930d827e96e0b41296d7723238e6735106fd3d5 100644 +index d29f4dd9808e2001c79535d663ca77d6840f6092..1fd6e5a1ada184f9b399b7c41718ffd7db086d91 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java -@@ -39,120 +39,120 @@ import org.bukkit.inventory.meta.TropicalFishBucketMeta; +@@ -40,120 +40,120 @@ import org.bukkit.inventory.meta.TropicalFishBucketMeta; public final class CraftItemMetas { @@ -159,10 +159,10 @@ index a4c4ba0d02f9a072236ce86c1e98e2c60b059cb8..0930d827e96e0b41296d7723238e6735 // We use if instead of a set, since the result gets cached in CraftItemType, diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index 9be7859ccb5283b2040ba68d72d6dbdafb4d6835..6a449bfc765bf427d82df4a90bc60471b5de2fd3 100644 +index 7228d43d331de16cbaa0e97c7e3fa45c0bc89558..dfdabf86433d323966a748baef769cf0462d3f38 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -@@ -161,10 +161,11 @@ public final class CraftItemStack extends ItemStack { +@@ -173,10 +173,11 @@ public final class CraftItemStack extends ItemStack { } else if (this.handle == null) { this.handle = new net.minecraft.world.item.ItemStack(CraftItemType.bukkitToMinecraft(type), 1); } else { @@ -175,7 +175,7 @@ index 9be7859ccb5283b2040ba68d72d6dbdafb4d6835..6a449bfc765bf427d82df4a90bc60471 } } this.setData(null); -@@ -325,6 +326,19 @@ public final class CraftItemStack extends ItemStack { +@@ -337,6 +338,19 @@ public final class CraftItemStack extends ItemStack { public ItemMeta getItemMeta() { return CraftItemStack.getItemMeta(this.handle); } @@ -195,7 +195,7 @@ index 9be7859ccb5283b2040ba68d72d6dbdafb4d6835..6a449bfc765bf427d82df4a90bc60471 // Paper start public static void applyMetaToItem(net.minecraft.world.item.ItemStack itemStack, ItemMeta itemMeta) { final CraftMetaItem.Applicator tag = new CraftMetaItem.Applicator(); -@@ -337,12 +351,17 @@ public final class CraftItemStack extends ItemStack { +@@ -349,12 +363,17 @@ public final class CraftItemStack extends ItemStack { } public static ItemMeta getItemMeta(net.minecraft.world.item.ItemStack item, org.bukkit.inventory.ItemType metaForType) { // Paper end @@ -216,7 +216,7 @@ index 9be7859ccb5283b2040ba68d72d6dbdafb4d6835..6a449bfc765bf427d82df4a90bc60471 static Material getType(net.minecraft.world.item.ItemStack item) { diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java -index a1f2b9d40d374e8cdbaf916b25fa74b6c0970f81..d03f4a767f6c7fe7d6bcef20e6676c39d9657584 100644 +index 6d76cc1db3ac3f1ae74c13511937fb86082a0b3d..f4a6ee6dfcb2d516a9a1a9c81494b50a629110e4 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java @@ -114,8 +114,8 @@ public class CraftItemType implements ItemType.Typed, Han @@ -231,7 +231,7 @@ index a1f2b9d40d374e8cdbaf916b25fa74b6c0970f81..d03f4a767f6c7fe7d6bcef20e6676c39 public M getItemMeta(ItemMeta itemMeta) { diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java -index 865977ce17fbb8793a1eefd71079729e83f5cfaf..889d43acf4cf7a5917f110105ed05838e24c8cf7 100644 +index 0d3b1692af010bfd7ea83e22e9571dc954906f71..e83a662f82b144b11a003a682633cd0ee797fd19 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java @@ -34,8 +34,8 @@ public class CraftMetaArmor extends CraftMetaItem implements ArmorMeta { @@ -456,10 +456,10 @@ index 4941e0afff8df5f10f06c715b54bf58eb86051c5..566d893a413fd04b99e83dc2da8fe958 getOrEmpty(tag, CraftMetaFirework.FIREWORKS).ifPresent((fireworks) -> { this.power = fireworks.flightDuration(); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index c2a215544589d903633c5aed51522870bea556d8..85bc581d0807f07212bf0cd4c85c65f0ec7ef547 100644 +index 6b3eed94c26bc16177f9b9fadd140f9a89163af2..86045b7c4aa6ce9007cdeb1bb1ffdce98de6568b 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -@@ -339,7 +339,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -389,7 +389,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { // Paper end } @@ -468,7 +468,7 @@ index c2a215544589d903633c5aed51522870bea556d8..85bc581d0807f07212bf0cd4c85c65f0 CraftMetaItem.getOrEmpty(tag, CraftMetaItem.NAME).ifPresent((component) -> { this.displayName = component; }); -@@ -450,9 +450,16 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -521,9 +521,16 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { }); // Paper end - fix ItemFlags @@ -486,7 +486,7 @@ index c2a215544589d903633c5aed51522870bea556d8..85bc581d0807f07212bf0cd4c85c65f0 key.getValue().ifPresent((value) -> { this.unhandledTags.set((DataComponentType) key.getKey(), value); }); -@@ -2045,68 +2052,76 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2351,75 +2358,83 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { this.version = version; } @@ -498,18 +498,25 @@ index c2a215544589d903633c5aed51522870bea556d8..85bc581d0807f07212bf0cd4c85c65f0 - CraftMetaItem.ITEM_NAME.TYPE, - CraftMetaItem.LORE.TYPE, - CraftMetaItem.CUSTOM_MODEL_DATA.TYPE, +- CraftMetaItem.ENCHANTABLE.TYPE, - CraftMetaItem.BLOCK_DATA.TYPE, - CraftMetaItem.REPAIR.TYPE, - CraftMetaItem.ENCHANTMENTS.TYPE, - CraftMetaItem.HIDE_ADDITIONAL_TOOLTIP.TYPE, - CraftMetaItem.HIDE_TOOLTIP.TYPE, +- CraftMetaItem.TOOLTIP_STYLE.TYPE, +- CraftMetaItem.ITEM_MODEL.TYPE, - CraftMetaItem.UNBREAKABLE.TYPE, - CraftMetaItem.ENCHANTMENT_GLINT_OVERRIDE.TYPE, -- CraftMetaItem.FIRE_RESISTANT.TYPE, +- CraftMetaItem.GLIDER.TYPE, +- CraftMetaItem.DAMAGE_RESISTANT.TYPE, - CraftMetaItem.MAX_STACK_SIZE.TYPE, - CraftMetaItem.RARITY.TYPE, +- CraftMetaItem.USE_REMAINDER.TYPE, +- CraftMetaItem.USE_COOLDOWN.TYPE, - CraftMetaItem.FOOD.TYPE, - CraftMetaItem.TOOL.TYPE, +- CraftMetaItem.EQUIPPABLE.TYPE, - CraftMetaItem.JUKEBOX_PLAYABLE.TYPE, - CraftMetaItem.DAMAGE.TYPE, - CraftMetaItem.MAX_DAMAGE.TYPE, @@ -558,16 +565,23 @@ index c2a215544589d903633c5aed51522870bea556d8..85bc581d0807f07212bf0cd4c85c65f0 + CraftMetaItem.ITEM_NAME.TYPE, + CraftMetaItem.LORE.TYPE, + CraftMetaItem.CUSTOM_MODEL_DATA.TYPE, ++ CraftMetaItem.CUSTOM_MODEL_DATA.TYPE, + CraftMetaItem.BLOCK_DATA.TYPE, + CraftMetaItem.REPAIR.TYPE, + CraftMetaItem.ENCHANTMENTS.TYPE, + CraftMetaItem.HIDE_ADDITIONAL_TOOLTIP.TYPE, + CraftMetaItem.HIDE_TOOLTIP.TYPE, ++ CraftMetaItem.TOOLTIP_STYLE.TYPE, ++ CraftMetaItem.ITEM_MODEL.TYPE, + CraftMetaItem.UNBREAKABLE.TYPE, + CraftMetaItem.ENCHANTMENT_GLINT_OVERRIDE.TYPE, -+ CraftMetaItem.FIRE_RESISTANT.TYPE, ++ CraftMetaItem.GLIDER.TYPE, ++ CraftMetaItem.DAMAGE_RESISTANT.TYPE, ++ CraftMetaItem.ENCHANTABLE.TYPE, + CraftMetaItem.MAX_STACK_SIZE.TYPE, + CraftMetaItem.RARITY.TYPE, ++ CraftMetaItem.USE_REMAINDER.TYPE, ++ CraftMetaItem.USE_COOLDOWN.TYPE, + CraftMetaItem.FOOD.TYPE, + CraftMetaItem.TOOL.TYPE, + CraftMetaItem.JUKEBOX_PLAYABLE.TYPE, @@ -624,10 +638,10 @@ index c2a215544589d903633c5aed51522870bea556d8..85bc581d0807f07212bf0cd4c85c65f0 protected static Optional getOrEmpty(DataComponentPatch tag, ItemMetaKeyType type) { Optional result = tag.get(type.TYPE); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java -index 573806b9200282f9842ab5289af4e2987905cafc..e47c1b9a52c938b145b721d9c088f4a916a01424 100644 +index 68c0a6d5e06a44ddddddb9cbe093ed6814380444..4dc7adb626ccb74b7e3a60c5a7250d0dc9703997 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java -@@ -30,8 +30,8 @@ public class CraftMetaKnowledgeBook extends CraftMetaItem implements KnowledgeBo +@@ -32,8 +32,8 @@ public class CraftMetaKnowledgeBook extends CraftMetaItem implements KnowledgeBo } } @@ -684,10 +698,10 @@ index 76a3e4893cbdba903a712d6db1d30b9c644795be..a80b9b142ca99c7c0257b1bdeb059dce getOrEmpty(tag, CraftMetaMusicInstrument.GOAT_HORN_INSTRUMENT).ifPresent((instrument) -> { this.instrument = org.bukkit.craftbukkit.CraftRegistry.unwrapAndConvertHolder(org.bukkit.Registry.INSTRUMENT, instrument).orElse(null); // Paper - fix upstream not handling inlined instrument diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java -index 17336c177a969f04c51ff12de4599ef261d79fef..90c554dcbfe2bcca3f742379499f1e8e8665c512 100644 +index ed272c7eb435677de5f6b106a6012c472decbb62..b118d8ecb505d187c02bb158f14df333f487a87f 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java -@@ -23,8 +23,8 @@ public class CraftMetaOminousBottle extends CraftMetaItem implements OminousBott +@@ -24,8 +24,8 @@ public class CraftMetaOminousBottle extends CraftMetaItem implements OminousBott this.ominousBottleAmplifier = bottleMeta.ominousBottleAmplifier; } @@ -696,13 +710,13 @@ index 17336c177a969f04c51ff12de4599ef261d79fef..90c554dcbfe2bcca3f742379499f1e8e + CraftMetaOminousBottle(DataComponentPatch tag, java.util.Set> extraHandledDcts) { // Paper + super(tag, extraHandledDcts); // Paper getOrEmpty(tag, CraftMetaOminousBottle.OMINOUS_BOTTLE_AMPLIFIER).ifPresent((amplifier) -> { - this.ominousBottleAmplifier = amplifier; + this.ominousBottleAmplifier = amplifier.value(); }); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java -index 8404520a3d15464f9dc9fa2292048e9fb1b06930..1a18779f9796704c8690226dbe491b0fa6ba99ea 100644 +index 533c600d632eb733c121f5d8189142726b091713..6f0eebcaffa20337cf5a7f8485f891c690d948ae 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java -@@ -51,8 +51,8 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { +@@ -54,8 +54,8 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { } } diff --git a/patches/unapplied/server/0961-Expose-hasColor-to-leather-armor.patch b/patches/server/0952-Expose-hasColor-to-leather-armor.patch similarity index 82% rename from patches/unapplied/server/0961-Expose-hasColor-to-leather-armor.patch rename to patches/server/0952-Expose-hasColor-to-leather-armor.patch index fb4dc944de05..9166ad6261cb 100644 --- a/patches/unapplied/server/0961-Expose-hasColor-to-leather-armor.patch +++ b/patches/server/0952-Expose-hasColor-to-leather-armor.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Expose #hasColor to leather armor diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java -index 299f2f4f143f753f3cd8a020c8e6ae46298e0f6f..51d7263cdd34359d9cdf72cc01ba654b519f838d 100644 +index 6517ec4933b0eae761fceb117ea1db175755d0b1..dc6398cfbd6e749733c3a681e1eb8ce15c3b2c5e 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java -@@ -118,4 +118,11 @@ public class CraftMetaColorableArmor extends CraftMetaArmor implements Colorable +@@ -100,4 +100,11 @@ public class CraftMetaColorableArmor extends CraftMetaArmor implements Colorable } return original != hash ? CraftMetaColorableArmor.class.hashCode() ^ hash : hash; } @@ -21,10 +21,10 @@ index 299f2f4f143f753f3cd8a020c8e6ae46298e0f6f..51d7263cdd34359d9cdf72cc01ba654b + // Paper end - Expose #hasColor to leather armor } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java -index f1dbfba7ec11b12ead627f098a0b833f49be8000..49889026661fb2a558e14569324016d637de27a0 100644 +index e8c950aa74d31bf7a9128f4acc4bccee26bbcd7f..e76749bffaf5a0bbd3a8d35f882edcc3598351b9 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java -@@ -177,4 +177,11 @@ class CraftMetaLeatherArmor extends CraftMetaItem implements LeatherArmorMeta { +@@ -156,4 +156,11 @@ class CraftMetaLeatherArmor extends CraftMetaItem implements LeatherArmorMeta { builder.put(CraftMetaLeatherArmor.COLOR.BUKKIT, meta.getColor()); } } diff --git a/patches/unapplied/server/0962-Added-API-to-get-player-ha-proxy-address.patch b/patches/server/0953-Added-API-to-get-player-ha-proxy-address.patch similarity index 93% rename from patches/unapplied/server/0962-Added-API-to-get-player-ha-proxy-address.patch rename to patches/server/0953-Added-API-to-get-player-ha-proxy-address.patch index a21e9c27e913..4ff67e86ed55 100644 --- a/patches/unapplied/server/0962-Added-API-to-get-player-ha-proxy-address.patch +++ b/patches/server/0953-Added-API-to-get-player-ha-proxy-address.patch @@ -35,10 +35,10 @@ index c62df32af11636ad408b584fcc590590ce4fb0d0..baed0bb80d44973f9323bbe536551182 } else { super.channelRead(ctx, msg); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 6db4d21ee4dc97820943d3fd2aa55054cac95f50..5f12c91ea598b4b133bf41532a9864645ebf6cea 100644 +index 24b05e9b21ec84a4677f58ed790d308e700741b5..60a5eb5bd23bb267648bc55c1ee6bdfb29f806ce 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -265,7 +265,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -266,7 +266,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public InetSocketAddress getAddress() { @@ -47,7 +47,7 @@ index 6db4d21ee4dc97820943d3fd2aa55054cac95f50..5f12c91ea598b4b133bf41532a986464 SocketAddress addr = this.getHandle().connection.getRemoteAddress(); if (addr instanceof InetSocketAddress) { -@@ -275,6 +275,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -276,6 +276,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } } From b2375286c9615fa5fd01ac876d0d35d6d74959ce Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Thu, 24 Oct 2024 16:31:09 +0200 Subject: [PATCH 040/119] Readd wrongly removed diff --- .../server/0938-Improve-tag-parser-handling.patch | 13 +++++++++++++ ...rack-the-changed-item-from-dispense-events.patch | 4 ++-- ...-improve-checking-handled-tags-in-itemmeta.patch | 6 +++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/patches/server/0938-Improve-tag-parser-handling.patch b/patches/server/0938-Improve-tag-parser-handling.patch index 91b570e5aabe..9435db11ac5c 100644 --- a/patches/server/0938-Improve-tag-parser-handling.patch +++ b/patches/server/0938-Improve-tag-parser-handling.patch @@ -53,6 +53,19 @@ index 0000000000000000000000000000000000000000..a375ad4ba9db990b24a2b9ff366fcba6 + super(EXCEPTION_TYPE, Component.literal(message)); + } +} +diff --git a/src/main/java/net/minecraft/commands/arguments/selector/SelectorPattern.java b/src/main/java/net/minecraft/commands/arguments/selector/SelectorPattern.java +index 82ecd9c034a2ee5040b6a66233070ce1cb4e48d2..50e66b10ec3943b9068e546763087161395f673a 100644 +--- a/src/main/java/net/minecraft/commands/arguments/selector/SelectorPattern.java ++++ b/src/main/java/net/minecraft/commands/arguments/selector/SelectorPattern.java +@@ -13,7 +13,7 @@ public record SelectorPattern(String pattern, EntitySelector resolved) { + EntitySelectorParser entitySelectorParser = new EntitySelectorParser(new StringReader(selector), true); + return DataResult.success(new SelectorPattern(selector, entitySelectorParser.parse())); + } catch (CommandSyntaxException var2) { +- return DataResult.error(() -> "Invalid selector component: " + selector + ": " + var2.getMessage()); ++ return DataResult.error(() -> "Invalid selector component"); // Paper - limit selector error message + } + } + diff --git a/src/main/java/net/minecraft/nbt/TagParser.java b/src/main/java/net/minecraft/nbt/TagParser.java index da101bca71f4710812621b98f0a0d8cab180346a..3cd112584accb8e8f050ac99738eed11c902e60e 100644 --- a/src/main/java/net/minecraft/nbt/TagParser.java diff --git a/patches/server/0941-Properly-track-the-changed-item-from-dispense-events.patch b/patches/server/0941-Properly-track-the-changed-item-from-dispense-events.patch index 4b58da1d3318..3885b9f8a228 100644 --- a/patches/server/0941-Properly-track-the-changed-item-from-dispense-events.patch +++ b/patches/server/0941-Properly-track-the-changed-item-from-dispense-events.patch @@ -72,7 +72,7 @@ index 63b8c806b6ee0ea3cc5e6a7f613b5e57c94bfcf1..cd77e86ff289634d2dd1c56002e569ff } else { return this.defaultDispenseItemBehavior.dispense(pointer, stack); diff --git a/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java b/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java -index a9d230d6ff22d5e3a11b2f31e7d751f44888a12c..df495161a5842cf38518adabd359bb35193ee2b3 100644 +index a9d230d6ff22d5e3a11b2f31e7d751f44888a12c..af222679d0d44d24b2b10455eb52fa8a797ca28a 100644 --- a/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java @@ -64,7 +64,7 @@ public class ProjectileDispenseBehavior extends DefaultDispenseItemBehavior { @@ -80,7 +80,7 @@ index a9d230d6ff22d5e3a11b2f31e7d751f44888a12c..df495161a5842cf38518adabd359bb35 } - Projectile iprojectile = Projectile.spawnProjectileUsingShoot(this.projectileItem.asProjectile(worldserver, iposition, stack, enumdirection), worldserver, stack, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), this.dispenseConfig.power(), this.dispenseConfig.uncertainty()); -+ Projectile iprojectile = Projectile.spawnProjectileUsingShoot(this.projectileItem.asProjectile(worldserver, iposition, CraftItemStack.unwrap(event.getItem()), enumdirection), worldserver, stack, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), this.dispenseConfig.power(), this.dispenseConfig.uncertainty()); // Paper - mtrack changed items in the dispense event; unwrap is safe here because all uses of the stack make their own copies ++ Projectile iprojectile = Projectile.spawnProjectileUsingShoot(this.projectileItem.asProjectile(worldserver, iposition, CraftItemStack.unwrap(event.getItem()), enumdirection), worldserver, stack, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), this.dispenseConfig.power(), this.dispenseConfig.uncertainty()); // Paper - track changed items in the dispense event; unwrap is safe here because all uses of the stack make their own copies ((Entity) iprojectile).projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource(pointer.blockEntity()); // itemstack.shrink(1); // CraftBukkit - Handled during event processing // CraftBukkit end diff --git a/patches/server/0951-improve-checking-handled-tags-in-itemmeta.patch b/patches/server/0951-improve-checking-handled-tags-in-itemmeta.patch index 41f857627abd..8d257c881d29 100644 --- a/patches/server/0951-improve-checking-handled-tags-in-itemmeta.patch +++ b/patches/server/0951-improve-checking-handled-tags-in-itemmeta.patch @@ -456,7 +456,7 @@ index 4941e0afff8df5f10f06c715b54bf58eb86051c5..566d893a413fd04b99e83dc2da8fe958 getOrEmpty(tag, CraftMetaFirework.FIREWORKS).ifPresent((fireworks) -> { this.power = fireworks.flightDuration(); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index 6b3eed94c26bc16177f9b9fadd140f9a89163af2..86045b7c4aa6ce9007cdeb1bb1ffdce98de6568b 100644 +index 6b3eed94c26bc16177f9b9fadd140f9a89163af2..13b19adc21ece31476b2980c5bc01a50f15df634 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -389,7 +389,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @@ -565,7 +565,7 @@ index 6b3eed94c26bc16177f9b9fadd140f9a89163af2..86045b7c4aa6ce9007cdeb1bb1ffdce9 + CraftMetaItem.ITEM_NAME.TYPE, + CraftMetaItem.LORE.TYPE, + CraftMetaItem.CUSTOM_MODEL_DATA.TYPE, -+ CraftMetaItem.CUSTOM_MODEL_DATA.TYPE, ++ CraftMetaItem.ENCHANTABLE.TYPE, + CraftMetaItem.BLOCK_DATA.TYPE, + CraftMetaItem.REPAIR.TYPE, + CraftMetaItem.ENCHANTMENTS.TYPE, @@ -577,13 +577,13 @@ index 6b3eed94c26bc16177f9b9fadd140f9a89163af2..86045b7c4aa6ce9007cdeb1bb1ffdce9 + CraftMetaItem.ENCHANTMENT_GLINT_OVERRIDE.TYPE, + CraftMetaItem.GLIDER.TYPE, + CraftMetaItem.DAMAGE_RESISTANT.TYPE, -+ CraftMetaItem.ENCHANTABLE.TYPE, + CraftMetaItem.MAX_STACK_SIZE.TYPE, + CraftMetaItem.RARITY.TYPE, + CraftMetaItem.USE_REMAINDER.TYPE, + CraftMetaItem.USE_COOLDOWN.TYPE, + CraftMetaItem.FOOD.TYPE, + CraftMetaItem.TOOL.TYPE, ++ CraftMetaItem.EQUIPPABLE.TYPE, + CraftMetaItem.JUKEBOX_PLAYABLE.TYPE, + CraftMetaItem.DAMAGE.TYPE, + CraftMetaItem.MAX_DAMAGE.TYPE, From fc0543071997267d28cf3c7c4c428d6762b78688 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Thu, 24 Oct 2024 17:16:31 +0200 Subject: [PATCH 041/119] 963 --- .../0954-General-ItemMeta-fixes.patch} | 165 +++++++----------- .../0955-More-Chest-Block-API.patch} | 10 +- ...ta-component-type-on-encoding-error.patch} | 2 +- .../0957-Brigadier-based-command-API.patch} | 106 ++++++----- .../0958-Fix-issues-with-Recipe-API.patch | 94 ++++++++++ ...59-Fix-equipment-slot-and-group-API.patch} | 12 +- ...lugin-to-use-Paper-PluginLoader-API.patch} | 0 ...versized-item-data-in-equipment-and.patch} | 24 +-- ...nt-NPE-if-hooked-entity-was-cleared.patch} | 4 +- ...ng-BlockPlaceEvent-calling-onRemove.patch} | 26 +-- ...964-Add-missing-fishing-event-state.patch} | 4 +- ...ate-InvAction-HOTBAR_MOVE_AND_READD.patch} | 4 +- ...nnect-packet-in-phases-where-it-doe.patch} | 0 .../0967-Adopt-MaterialRerouting.patch} | 0 .../0968-Suspicious-Effect-Entry-API.patch} | 4 +- ...eck-if-itemstack-is-stackable-first.patch} | 4 +- ...emoving-recipes-from-RecipeIterator.patch} | 4 +- ...mage-tick-when-blocking-with-shield.patch} | 4 +- ...he-experimental-smithing-inventory-.patch} | 0 .../0966-Fix-issues-with-Recipe-API.patch | 118 ------------- 20 files changed, 260 insertions(+), 325 deletions(-) rename patches/{unapplied/server/0960-General-ItemMeta-fixes.patch => server/0954-General-ItemMeta-fixes.patch} (92%) rename patches/{unapplied/server/0963-More-Chest-Block-API.patch => server/0955-More-Chest-Block-API.patch} (90%) rename patches/{unapplied/server/0964-Print-data-component-type-on-encoding-error.patch => server/0956-Print-data-component-type-on-encoding-error.patch} (92%) rename patches/{unapplied/server/0965-Brigadier-based-command-API.patch => server/0957-Brigadier-based-command-API.patch} (97%) create mode 100644 patches/server/0958-Fix-issues-with-Recipe-API.patch rename patches/{unapplied/server/0967-Fix-equipment-slot-and-group-API.patch => server/0959-Fix-equipment-slot-and-group-API.patch} (93%) rename patches/{unapplied/server/0968-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch => server/0960-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch} (100%) rename patches/{unapplied/server/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch => server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch} (93%) rename patches/{unapplied/server/0970-Prevent-NPE-if-hooked-entity-was-cleared.patch => server/0962-Prevent-NPE-if-hooked-entity-was-cleared.patch} (91%) rename patches/{unapplied/server/0971-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch => server/0963-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch} (75%) rename patches/{unapplied/server/0972-Add-missing-fishing-event-state.patch => server/0964-Add-missing-fishing-event-state.patch} (90%) rename patches/{unapplied/server/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch => server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch} (92%) rename patches/{unapplied/server/0974-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch => server/0966-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch} (100%) rename patches/{unapplied/server/0975-Adopt-MaterialRerouting.patch => server/0967-Adopt-MaterialRerouting.patch} (100%) rename patches/{unapplied/server/0976-Suspicious-Effect-Entry-API.patch => server/0968-Suspicious-Effect-Entry-API.patch} (98%) rename patches/{unapplied/server/0977-check-if-itemstack-is-stackable-first.patch => server/0969-check-if-itemstack-is-stackable-first.patch} (87%) rename patches/{unapplied/server/0978-Fix-removing-recipes-from-RecipeIterator.patch => server/0970-Fix-removing-recipes-from-RecipeIterator.patch} (92%) rename patches/{unapplied/server/0979-Configurable-damage-tick-when-blocking-with-shield.patch => server/0971-Configurable-damage-tick-when-blocking-with-shield.patch} (90%) rename patches/{unapplied/server/0980-Properly-remove-the-experimental-smithing-inventory-.patch => server/0972-Properly-remove-the-experimental-smithing-inventory-.patch} (100%) delete mode 100644 patches/unapplied/server/0966-Fix-issues-with-Recipe-API.patch diff --git a/patches/unapplied/server/0960-General-ItemMeta-fixes.patch b/patches/server/0954-General-ItemMeta-fixes.patch similarity index 92% rename from patches/unapplied/server/0960-General-ItemMeta-fixes.patch rename to patches/server/0954-General-ItemMeta-fixes.patch index d61cc57b5369..70bbb2f9d4b3 100644 --- a/patches/unapplied/server/0960-General-ItemMeta-fixes.patch +++ b/patches/server/0954-General-ItemMeta-fixes.patch @@ -12,10 +12,10 @@ public net/minecraft/world/level/block/entity/BlockEntity saveId(Lnet/minecraft/ Co-authored-by: GhastCraftHD diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 256e5232425985502c0f9cb9258494555118687e..f09ef12023b1bbbf0c9c94487a705abda94db70b 100644 +index bba4fbde31ef25bc086fefaa86f9a479ef6ccf26..62529e61c8751433a8b6abe6cfb2cc414c8c3cf2 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -1275,6 +1275,11 @@ public final class ItemStack implements DataComponentHolder { +@@ -1356,6 +1356,11 @@ public final class ItemStack implements DataComponentHolder { public void setItem(Item item) { this.bukkitStack = null; // Paper this.item = item; @@ -28,13 +28,13 @@ index 256e5232425985502c0f9cb9258494555118687e..f09ef12023b1bbbf0c9c94487a705abd // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index 41f43d7d12a47563360f48a793e63db8cf92ac69..a1d7ae987327382d9566860b991dc361225c7938 100644 +index 63e234fb72952dcede4eeaa5d3d3390d137d88a2..b4aff394694417cff1930cf8fbd6696b9f9c9d01 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java @@ -152,6 +152,11 @@ public abstract class BlockEntity { CompoundTag nbttagcompound = new CompoundTag(); - this.saveAdditional(nbttagcompound, registryLookup); + this.saveAdditional(nbttagcompound, registries); + // Paper start - store PDC here as well + if (this.persistentDataContainer != null && !this.persistentDataContainer.isEmpty()) { + nbttagcompound.put("PublicBukkitValues", this.persistentDataContainer.toTagCompound()); @@ -68,10 +68,10 @@ index fe7e3e0628783d8d1be9635b689da8a9cb46c5d7..04ae258a2f8e98421340d29d5cceedec protected void load(T tileEntity) { if (tileEntity != null && tileEntity != this.snapshot) { diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index 6a449bfc765bf427d82df4a90bc60471b5de2fd3..efb7fb8dbaa7446e394f55b021692c11a25fd29f 100644 +index dfdabf86433d323966a748baef769cf0462d3f38..bb2b4528692aed8e3341428697a60c0abee13779 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -@@ -279,7 +279,9 @@ public final class CraftItemStack extends ItemStack { +@@ -291,7 +291,9 @@ public final class CraftItemStack extends ItemStack { @Override public void removeEnchantments() { @@ -82,7 +82,7 @@ index 6a449bfc765bf427d82df4a90bc60471b5de2fd3..efb7fb8dbaa7446e394f55b021692c11 } @Override -@@ -341,7 +343,14 @@ public final class CraftItemStack extends ItemStack { +@@ -353,7 +355,14 @@ public final class CraftItemStack extends ItemStack { // Paper end - improve handled tags on type change // Paper start public static void applyMetaToItem(net.minecraft.world.item.ItemStack itemStack, ItemMeta itemMeta) { @@ -98,7 +98,7 @@ index 6a449bfc765bf427d82df4a90bc60471b5de2fd3..efb7fb8dbaa7446e394f55b021692c11 ((CraftMetaItem) itemMeta).applyToItem(tag); itemStack.applyComponents(tag.build()); } -@@ -389,15 +398,20 @@ public final class CraftItemStack extends ItemStack { +@@ -401,15 +410,20 @@ public final class CraftItemStack extends ItemStack { if (itemMeta == null) return true; if (!((CraftMetaItem) itemMeta).isEmpty()) { @@ -577,7 +577,7 @@ index 2736a87a6c481da0575e6e29ea08faa539c24378..51da0db4da3549efd69f367e28450408 if (this.items == null) { this.items = new ArrayList<>(); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java -index 6517ec4933b0eae761fceb117ea1db175755d0b1..299f2f4f143f753f3cd8a020c8e6ae46298e0f6f 100644 +index dc6398cfbd6e749733c3a681e1eb8ce15c3b2c5e..51d7263cdd34359d9cdf72cc01ba654b519f838d 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java @@ -11,16 +11,30 @@ import org.bukkit.inventory.meta.ColorableArmorMeta; @@ -1049,10 +1049,10 @@ index 566d893a413fd04b99e83dc2da8fe958a48492a8..a944803771d514572f94b4e98a6d4435 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd2cde76f6 100644 +index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411fcb433c8c 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -@@ -182,9 +182,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -199,9 +199,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { } } @@ -1065,16 +1065,16 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd Applicator put(ItemMetaKeyType key, T value) { this.builder.set(key.TYPE, value); -@@ -271,7 +272,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - private CraftFoodComponent food; +@@ -308,7 +309,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { private CraftToolComponent tool; + private CraftEquippableComponent equippable; private CraftJukeboxComponent jukebox; - private int damage; + private Integer damage; // Paper - may not be set private Integer maxDamage; private static final Set HANDLED_TAGS = Sets.newHashSet(); -@@ -303,7 +304,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -341,7 +342,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { this.enchantments = new EnchantmentMap(meta.enchantments); // Paper } @@ -1083,7 +1083,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd this.attributeModifiers = LinkedHashMultimap.create(meta.attributeModifiers); } -@@ -340,6 +341,11 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -390,6 +391,11 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { } CraftMetaItem(DataComponentPatch tag, Set> extraHandledTags) { // Paper - improve handled tags on type changes @@ -1095,7 +1095,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd CraftMetaItem.getOrEmpty(tag, CraftMetaItem.NAME).ifPresent((component) -> { this.displayName = component; }); -@@ -798,7 +804,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -906,7 +912,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { Map mods = SerializableMeta.getObject(Map.class, map, key.BUKKIT, true); Multimap result = LinkedHashMultimap.create(); if (mods == null) { @@ -1104,7 +1104,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd } for (Object obj : mods.keySet()) { -@@ -901,7 +907,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1037,7 +1043,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { itemTag.put(CraftMetaItem.JUKEBOX_PLAYABLE, this.jukebox.getHandle()); } @@ -1113,7 +1113,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd itemTag.put(CraftMetaItem.DAMAGE, this.damage); } -@@ -951,7 +957,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1087,7 +1093,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { } void applyEnchantments(Map enchantments, CraftMetaItem.Applicator tag, ItemMetaKeyType key, ItemFlag itemFlag) { @@ -1122,7 +1122,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd return; } -@@ -968,10 +974,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1104,10 +1110,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { } void applyModifiers(Multimap modifiers, CraftMetaItem.Applicator tag) { @@ -1135,16 +1135,16 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd return; } -@@ -1008,7 +1012,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1144,7 +1148,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Overridden boolean isEmpty() { -- return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.removedTags.isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasTool() || this.hasJukeboxPlayable() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper -+ return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.removedTags.isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasTool() || this.hasJukeboxPlayable() || this.hasDamageValue() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper +- return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasEnchantable() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.removedTags.isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.hasTooltipStyle() || this.hasItemModel() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isGlider() || this.hasDamageResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasUseRemainder() || this.hasUseCooldown() || this.hasFood() || this.hasTool() || this.hasJukeboxPlayable() || this.hasEquippable() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper ++ return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasEnchantable() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.removedTags.isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.hasTooltipStyle() || this.hasItemModel() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isGlider() || this.hasDamageResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasUseRemainder() || this.hasUseCooldown() || this.hasFood() || this.hasTool() || this.hasJukeboxPlayable() || this.hasEquippable() || this.hasDamageValue() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper } // Paper start -@@ -1104,6 +1108,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1240,6 +1244,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public void lore(final List lore) { @@ -1152,7 +1152,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd this.lore = lore != null ? io.papermc.paper.adventure.PaperAdventure.asVanilla(lore) : null; } // Paper end -@@ -1162,7 +1167,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1298,7 +1303,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public void removeEnchantments() { if (this.hasEnchants()) { @@ -1161,7 +1161,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd } } -@@ -1228,6 +1233,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1364,6 +1369,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { // Paper end @Override public void setLore(List lore) { @@ -1169,7 +1169,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd if (lore == null || lore.isEmpty()) { this.lore = null; } else { -@@ -1243,6 +1249,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1379,6 +1385,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { // Paper start @Override public void setLoreComponents(List lore) { @@ -1177,16 +1177,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd if (lore == null) { this.lore = null; } else { -@@ -1384,7 +1391,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - - @Override - public FoodComponent getFood() { -- return (this.hasFood()) ? new CraftFoodComponent(this.food) : new CraftFoodComponent(new FoodProperties(0, 0, false, 0, Optional.empty(), Collections.emptyList())); -+ return (this.hasFood()) ? new CraftFoodComponent(this.food) : new CraftFoodComponent(new FoodProperties(0, 0, false, FoodProperties.DEFAULT_EAT_SECONDS, Optional.empty(), Collections.emptyList())); // Paper - create a valid food properties - } - - @Override -@@ -1440,7 +1447,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1692,7 +1699,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public Multimap getAttributeModifiers(@Nullable EquipmentSlot slot) { @@ -1195,7 +1186,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd SetMultimap result = LinkedHashMultimap.create(); for (Map.Entry entry : this.attributeModifiers.entries()) { if (entry.getValue().getSlot() == null || entry.getValue().getSlot() == slot) { -@@ -1453,6 +1460,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1705,6 +1712,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public Collection getAttributeModifiers(@Nonnull Attribute attribute) { Preconditions.checkNotNull(attribute, "Attribute cannot be null"); @@ -1203,7 +1194,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd return this.attributeModifiers.containsKey(attribute) ? ImmutableList.copyOf(this.attributeModifiers.get(attribute)) : null; } -@@ -1460,22 +1468,33 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1712,22 +1720,33 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { public boolean addAttributeModifier(@Nonnull Attribute attribute, @Nonnull AttributeModifier modifier) { Preconditions.checkNotNull(attribute, "Attribute cannot be null"); Preconditions.checkNotNull(modifier, "AttributeModifier cannot be null"); @@ -1241,7 +1232,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd Iterator> iterator = attributeModifiers.entries().iterator(); while (iterator.hasNext()) { -@@ -1485,6 +1504,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1737,6 +1756,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { iterator.remove(); continue; } @@ -1249,7 +1240,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd this.attributeModifiers.put(next.getKey(), next.getValue()); } } -@@ -1492,13 +1512,13 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1744,13 +1764,13 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public boolean removeAttributeModifier(@Nonnull Attribute attribute) { Preconditions.checkNotNull(attribute, "Attribute cannot be null"); @@ -1265,7 +1256,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd int removed = 0; Iterator> iter = this.attributeModifiers.entries().iterator(); -@@ -1518,7 +1538,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1770,7 +1790,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { public boolean removeAttributeModifier(@Nonnull Attribute attribute, @Nonnull AttributeModifier modifier) { Preconditions.checkNotNull(attribute, "Attribute cannot be null"); Preconditions.checkNotNull(modifier, "AttributeModifier cannot be null"); @@ -1274,7 +1265,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd int removed = 0; Iterator> iter = this.attributeModifiers.entries().iterator(); -@@ -1540,7 +1560,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1792,7 +1812,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public String getAsString() { @@ -1282,8 +1273,8 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd + CraftMetaItem.Applicator tag = new CraftMetaItem.Applicator() {}; // Paper - support updating profile after resolving it this.applyToItem(tag); DataComponentPatch patch = tag.build(); - Tag nbt = DataComponentPatch.CODEC.encodeStart(MinecraftServer.getDefaultRegistryAccess().createSerializationContext(NbtOps.INSTANCE), patch).getOrThrow(); -@@ -1549,7 +1569,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + net.minecraft.nbt.Tag nbt = DataComponentPatch.CODEC.encodeStart(MinecraftServer.getDefaultRegistryAccess().createSerializationContext(NbtOps.INSTANCE), patch).getOrThrow(); +@@ -1801,7 +1821,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public String getAsComponentString() { @@ -1292,7 +1283,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd this.applyToItem(tag); DataComponentPatch patch = tag.build(); -@@ -1589,6 +1609,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1841,6 +1861,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { if (first == null || second == null) { return false; } @@ -1300,7 +1291,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd for (Map.Entry entry : first.entries()) { if (!second.containsEntry(entry.getKey(), entry.getValue())) { return false; -@@ -1604,19 +1625,33 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1856,19 +1877,33 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public boolean hasDamage() { @@ -1336,7 +1327,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd @Override public boolean hasMaxDamage() { return this.maxDamage != null; -@@ -1630,6 +1665,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1882,6 +1917,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public void setMaxDamage(Integer maxDamage) { @@ -1344,8 +1335,8 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd this.maxDamage = maxDamage; } -@@ -1661,7 +1697,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - && (this.hasCustomModelData() ? that.hasCustomModelData() && this.customModelData.equals(that.customModelData) : !that.hasCustomModelData()) +@@ -1914,7 +1950,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + && (this.hasEnchantable() ? that.hasEnchantable() && this.enchantableValue.equals(that.enchantableValue) : !that.hasEnchantable()) && (this.hasBlockData() ? that.hasBlockData() && this.blockData.equals(that.blockData) : !that.hasBlockData()) && (this.hasRepairCost() ? that.hasRepairCost() && this.repairCost == that.repairCost : !that.hasRepairCost()) - && (this.hasAttributeModifiers() ? that.hasAttributeModifiers() && CraftMetaItem.compareModifiers(this.attributeModifiers, that.attributeModifiers) : !that.hasAttributeModifiers()) @@ -1353,19 +1344,19 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd && (this.unhandledTags.equals(that.unhandledTags)) && (this.removedTags.equals(that.removedTags)) && (Objects.equals(this.customTag, that.customTag)) -@@ -1676,7 +1712,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - && (this.hasFood() ? that.hasFood() && this.food.equals(that.food) : !that.hasFood()) +@@ -1935,7 +1971,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { && (this.hasTool() ? that.hasTool() && this.tool.equals(that.tool) : !that.hasTool()) + && (this.hasEquippable() ? that.hasEquippable() && this.equippable.equals(that.equippable) : !that.hasEquippable()) && (this.hasJukeboxPlayable() ? that.hasJukeboxPlayable() && this.jukebox.equals(that.jukebox) : !that.hasJukeboxPlayable()) - && (this.hasDamage() ? that.hasDamage() && this.damage == that.damage : !that.hasDamage()) + && (Objects.equals(this.damage, that.damage)) // Paper - preserve empty/0 damage && (this.hasMaxDamage() ? that.hasMaxDamage() && this.maxDamage.equals(that.maxDamage) : !that.hasMaxDamage()) && (this.canPlaceOnPredicates != null ? that.canPlaceOnPredicates != null && this.canPlaceOnPredicates.equals(that.canPlaceOnPredicates) : that.canPlaceOnPredicates == null) // Paper && (this.canBreakPredicates != null ? that.canBreakPredicates != null && this.canBreakPredicates.equals(that.canBreakPredicates) : that.canBreakPredicates == null) // Paper -@@ -1722,9 +1758,9 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { - hash = 61 * hash + (this.hasFood() ? this.food.hashCode() : 0); +@@ -1988,9 +2024,9 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { hash = 61 * hash + (this.hasTool() ? this.tool.hashCode() : 0); hash = 61 * hash + (this.hasJukeboxPlayable() ? this.jukebox.hashCode() : 0); + hash = 61 * hash + (this.hasEquippable() ? this.equippable.hashCode() : 0); - hash = 61 * hash + (this.hasDamage() ? this.damage : 0); - hash = 61 * hash + (this.hasMaxDamage() ? 1231 : 1237); - hash = 61 * hash + (this.hasAttributeModifiers() ? this.attributeModifiers.hashCode() : 0); @@ -1375,7 +1366,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd hash = 61 * hash + (this.canPlaceOnPredicates != null ? this.canPlaceOnPredicates.hashCode() : 0); // Paper hash = 61 * hash + (this.canBreakPredicates != null ? this.canBreakPredicates.hashCode() : 0); // Paper hash = 61 * hash + this.version; -@@ -1744,7 +1780,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2011,7 +2047,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { if (this.enchantments != null) { clone.enchantments = new EnchantmentMap(this.enchantments); // Paper } @@ -1384,7 +1375,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd clone.attributeModifiers = LinkedHashMultimap.create(this.attributeModifiers); } if (this.customTag != null) { -@@ -1872,7 +1908,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2178,7 +2214,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { builder.put(CraftMetaItem.JUKEBOX_PLAYABLE.BUKKIT, this.jukebox); } @@ -1393,7 +1384,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd builder.put(CraftMetaItem.DAMAGE.BUKKIT, this.damage); } -@@ -1973,7 +2009,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2279,7 +2315,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { } static void serializeModifiers(Multimap modifiers, ImmutableMap.Builder builder, ItemMetaKey key) { @@ -1402,7 +1393,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd return; } -@@ -2055,7 +2091,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2361,7 +2397,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { // Paper start - improve checking handled tags @org.jetbrains.annotations.VisibleForTesting public static final Map, Set>> HANDLED_DCTS_PER_TYPE = new HashMap<>(); @@ -1411,7 +1402,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd CraftMetaItem.NAME.TYPE, CraftMetaItem.ITEM_NAME.TYPE, CraftMetaItem.LORE.TYPE, -@@ -2124,7 +2160,12 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2437,7 +2473,12 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { // Paper end - improve checking handled data component types protected static Optional getOrEmpty(DataComponentPatch tag, ItemMetaKeyType type) { @@ -1426,7 +1417,7 @@ index 85bc581d0807f07212bf0cd4c85c65f0ec7ef547..ecf3db9b976c0c1ceaf5db04dc0420cd return (result != null) ? result : Optional.empty(); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java -index e8c950aa74d31bf7a9128f4acc4bccee26bbcd7f..f1dbfba7ec11b12ead627f098a0b833f49be8000 100644 +index e76749bffaf5a0bbd3a8d35f882edcc3598351b9..49889026661fb2a558e14569324016d637de27a0 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java @@ -18,16 +18,30 @@ class CraftMetaLeatherArmor extends CraftMetaItem implements LeatherArmorMeta { @@ -1586,10 +1577,10 @@ index 149356981e586e4f67d4543d3df94a2ea99333fc..06c72ed83dab9492b70bfd13f7f9c1a4 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java -index 90c554dcbfe2bcca3f742379499f1e8e8665c512..14acdd2bd02de7e99b7f237151633ed71396db5f 100644 +index b118d8ecb505d187c02bb158f14df333f487a87f..fa1d1a7f37aadf2750f03a0e215fb25fa948f9aa 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java -@@ -69,6 +69,7 @@ public class CraftMetaOminousBottle extends CraftMetaItem implements OminousBott +@@ -70,6 +70,7 @@ public class CraftMetaOminousBottle extends CraftMetaItem implements OminousBott @Override public int getAmplifier() { @@ -1598,19 +1589,19 @@ index 90c554dcbfe2bcca3f742379499f1e8e8665c512..14acdd2bd02de7e99b7f237151633ed7 } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java -index 1a18779f9796704c8690226dbe491b0fa6ba99ea..c2476232b5472f1a0b1862588de2abf879b82ede 100644 +index 6f0eebcaffa20337cf5a7f8485f891c690d948ae..18dc2e83dab0821e5129bd68361de189363823b3 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java -@@ -37,7 +37,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { +@@ -38,7 +38,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { private PotionType type; private List customEffects; - private Color color; + private Integer color; // Paper - keep color component consistent with vanilla (top byte is ignored) + private String customName; CraftMetaPotion(CraftMetaItem meta) { - super(meta); -@@ -60,7 +60,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { +@@ -63,7 +63,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { potionContents.customColor().ifPresent((customColor) -> { try { @@ -1619,16 +1610,16 @@ index 1a18779f9796704c8690226dbe491b0fa6ba99ea..c2476232b5472f1a0b1862588de2abf8 } catch (IllegalArgumentException ex) { // Invalid colour } -@@ -120,7 +120,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { +@@ -132,7 +132,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { } Optional> defaultPotion = (this.hasBasePotionType()) ? Optional.of(CraftPotionType.bukkitToMinecraftHolder(this.type)) : Optional.empty(); - Optional potionColor = (this.hasColor()) ? Optional.of(this.color.asRGB()) : Optional.empty(); + Optional potionColor = (this.hasColor()) ? Optional.of(this.color) : Optional.empty(); // Paper + Optional customName = Optional.ofNullable(this.customName); List effectList = new ArrayList<>(); - if (this.customEffects != null) { -@@ -284,12 +284,12 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { +@@ -297,12 +297,12 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { @Override public Color getColor() { @@ -2036,39 +2027,11 @@ index e00b757d6059715e8697428008fcb3e6e7abbe2e..dcf02bd0f7f4c67f5ab98003cc932b96 + } + // Paper end - General ItemMeta Fixes } -diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftFoodComponent.java b/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftFoodComponent.java -index 92cad73219e11dc5922630769f9dd3a329ea6da1..bde61de7eda72b2e24ddef56ff93a0b46c08670c 100644 ---- a/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftFoodComponent.java -+++ b/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftFoodComponent.java -@@ -114,6 +114,7 @@ public final class CraftFoodComponent implements FoodComponent { - - @Override - public void setEatSeconds(float eatSeconds) { -+ Preconditions.checkArgument(eatSeconds > 0, "Eat seconds must be positive"); // Paper - validate eat_seconds - this.handle = new FoodProperties(this.handle.nutrition(), this.handle.saturation(), this.handle.canAlwaysEat(), eatSeconds, this.handle.usingConvertsTo(), this.handle.effects()); - } - -@@ -124,6 +125,7 @@ public final class CraftFoodComponent implements FoodComponent { - - @Override - public void setUsingConvertsTo(ItemStack item) { -+ Preconditions.checkArgument(item == null || !item.isEmpty(), "Item cannot be empty"); // Paper - validate using_converts_to - this.handle = new FoodProperties(this.handle.nutrition(), this.handle.saturation(), this.handle.canAlwaysEat(), this.handle.eatSeconds(), Optional.ofNullable(item).map(CraftItemStack::asNMSCopy), this.handle.effects()); - } - -@@ -139,6 +141,7 @@ public final class CraftFoodComponent implements FoodComponent { - - @Override - public FoodEffect addEffect(PotionEffect effect, float probability) { -+ Preconditions.checkArgument(0 <= probability && probability <= 1, "Probability cannot be outside range [0,1]"); // Paper - List effects = new ArrayList<>(this.handle.effects()); - - FoodProperties.PossibleEffect newEffect = new net.minecraft.world.food.FoodProperties.PossibleEffect(CraftPotionUtil.fromBukkit(effect), probability); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftToolComponent.java b/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftToolComponent.java -index 6c477913406a0dded8ca00295b8f4928e31404ae..2750c46c535d5b10afcaca109fc89d73d6485fd0 100644 +index 9a4a1d903c22e9d2a0cbda95ceb8b1dcfb29112e..4f7914f96207feda67cd910213bb624df4802a06 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftToolComponent.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftToolComponent.java -@@ -108,6 +108,7 @@ public final class CraftToolComponent implements ToolComponent { +@@ -106,6 +106,7 @@ public final class CraftToolComponent implements ToolComponent { public ToolRule addRule(Material block, Float speed, Boolean correctForDrops) { Preconditions.checkArgument(block != null, "block must not be null"); Preconditions.checkArgument(block.isBlock(), "block must be a block type, given %s", block.getKey()); @@ -2076,7 +2039,7 @@ index 6c477913406a0dded8ca00295b8f4928e31404ae..2750c46c535d5b10afcaca109fc89d73 Holder.Reference nmsBlock = CraftBlockType.bukkitToMinecraft(block).builtInRegistryHolder(); return this.addRule(HolderSet.direct(nmsBlock), speed, correctForDrops); -@@ -115,6 +116,7 @@ public final class CraftToolComponent implements ToolComponent { +@@ -113,6 +114,7 @@ public final class CraftToolComponent implements ToolComponent { @Override public ToolRule addRule(Collection blocks, Float speed, Boolean correctForDrops) { @@ -2084,7 +2047,7 @@ index 6c477913406a0dded8ca00295b8f4928e31404ae..2750c46c535d5b10afcaca109fc89d73 List> nmsBlocks = new ArrayList<>(blocks.size()); for (Material material : blocks) { -@@ -128,6 +130,7 @@ public final class CraftToolComponent implements ToolComponent { +@@ -126,6 +128,7 @@ public final class CraftToolComponent implements ToolComponent { @Override public ToolRule addRule(Tag tag, Float speed, Boolean correctForDrops) { Preconditions.checkArgument(tag instanceof CraftBlockTag, "tag must be a block tag"); @@ -2092,7 +2055,7 @@ index 6c477913406a0dded8ca00295b8f4928e31404ae..2750c46c535d5b10afcaca109fc89d73 return this.addRule(((CraftBlockTag) tag).getHandle(), speed, correctForDrops); } -@@ -290,6 +293,7 @@ public final class CraftToolComponent implements ToolComponent { +@@ -258,6 +261,7 @@ public final class CraftToolComponent implements ToolComponent { @Override public void setSpeed(Float speed) { diff --git a/patches/unapplied/server/0963-More-Chest-Block-API.patch b/patches/server/0955-More-Chest-Block-API.patch similarity index 90% rename from patches/unapplied/server/0963-More-Chest-Block-API.patch rename to patches/server/0955-More-Chest-Block-API.patch index 020d97d086a8..d7c00f61e18a 100644 --- a/patches/unapplied/server/0963-More-Chest-Block-API.patch +++ b/patches/server/0955-More-Chest-Block-API.patch @@ -7,18 +7,18 @@ Subject: [PATCH] More Chest Block API public net.minecraft.world.level.block.ChestBlock isBlockedChestByBlock(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z diff --git a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java -index 5f9858ef8d0ec1a74d469ab4426eb1db068873fd..ca92d49ef2010ba00c623491671dcde8ebe697c1 100644 +index b376f7d3b632d6aaea5c4d93382238074559d56a..ef0d469176ee74b6bb5f9e9cc508735145fda5b8 100644 --- a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java +++ b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java @@ -83,7 +83,7 @@ public class EnderChestBlock extends AbstractChestBlock i - BlockEntity blockEntity = world.getBlockEntity(pos); - if (playerEnderChestContainer != null && blockEntity instanceof EnderChestBlockEntity) { + PlayerEnderChestContainer playerEnderChestContainer = player.getEnderChestInventory(); + if (playerEnderChestContainer != null && world.getBlockEntity(pos) instanceof EnderChestBlockEntity enderChestBlockEntity) { BlockPos blockPos = pos.above(); - if (world.getBlockState(blockPos).isRedstoneConductor(world, blockPos)) { + if (world.getBlockState(blockPos).isRedstoneConductor(world, blockPos)) { // Paper - diff on change; make sure that EnderChest#isBlocked uses the same logic - return InteractionResult.sidedSuccess(world.isClientSide); - } else if (world.isClientSide) { return InteractionResult.SUCCESS; + } else { + if (world instanceof ServerLevel serverLevel) { diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java index 6e98a00d526b734992ce39b15768c5820dce4ca8..cc7bf4d39b834fba472bc163226a01a0cd4b6010 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java diff --git a/patches/unapplied/server/0964-Print-data-component-type-on-encoding-error.patch b/patches/server/0956-Print-data-component-type-on-encoding-error.patch similarity index 92% rename from patches/unapplied/server/0964-Print-data-component-type-on-encoding-error.patch rename to patches/server/0956-Print-data-component-type-on-encoding-error.patch index a60bdfee87b5..f003f33b9254 100644 --- a/patches/unapplied/server/0964-Print-data-component-type-on-encoding-error.patch +++ b/patches/server/0956-Print-data-component-type-on-encoding-error.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Print data component type on encoding error diff --git a/src/main/java/net/minecraft/core/component/DataComponentPatch.java b/src/main/java/net/minecraft/core/component/DataComponentPatch.java -index 87dd1f570fd294daf826ef7e6403776e42ed4f61..cee4a0639b3c73e300a8450f8a831cb4a71958ba 100644 +index 9de958d769a52a8df794988781f8601a4e6a73a4..9dec1c74d10f82636b7176e8f725b8acd1b52e4f 100644 --- a/src/main/java/net/minecraft/core/component/DataComponentPatch.java +++ b/src/main/java/net/minecraft/core/component/DataComponentPatch.java @@ -144,7 +144,13 @@ public final class DataComponentPatch { diff --git a/patches/unapplied/server/0965-Brigadier-based-command-API.patch b/patches/server/0957-Brigadier-based-command-API.patch similarity index 97% rename from patches/unapplied/server/0965-Brigadier-based-command-API.patch rename to patches/server/0957-Brigadier-based-command-API.patch index 6334fcc1c891..6eb0d9779c82 100644 --- a/patches/unapplied/server/0965-Brigadier-based-command-API.patch +++ b/patches/server/0957-Brigadier-based-command-API.patch @@ -2024,10 +2024,10 @@ index 5ba0ef6eda157c4e61d1de99c6b017ceb34430ec..bc5fc57018e347caa5ca453430a45669 // CraftBukkit end }; diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java -index 3c0d2332207ba638faaaa4280bce18c334a01271..4017b82e72fefd6685e9250a936686fd8a0891f1 100644 +index fc0c60b22844ed010aede2fa125b9fa440d3de80..3549ffea451b932602efb113844ba21a7bc72371 100644 --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java +++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java -@@ -45,8 +45,7 @@ import net.minecraft.world.phys.Vec2; +@@ -47,8 +47,7 @@ import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; import com.mojang.brigadier.tree.CommandNode; // CraftBukkit @@ -2037,7 +2037,7 @@ index 3c0d2332207ba638faaaa4280bce18c334a01271..4017b82e72fefd6685e9250a936686fd public static final SimpleCommandExceptionType ERROR_NOT_PLAYER = new SimpleCommandExceptionType(Component.translatable("permissions.requires.player")); public static final SimpleCommandExceptionType ERROR_NOT_ENTITY = new SimpleCommandExceptionType(Component.translatable("permissions.requires.entity")); public final CommandSource source; -@@ -170,26 +169,6 @@ public class CommandSourceStack implements ExecutionCommandSource dispatcher = new com.mojang.brigadier.CommandDispatcher(); public Commands(Commands.CommandSelection environment, CommandBuildContext commandRegistryAccess) { @@ -2090,7 +2090,7 @@ index 7b86e064564d3a285e3971fd08ea6168bac0720e..74fcdc74dc6c5cbf81abb7d46fc70047 AdvancementCommands.register(this.dispatcher); AttributeCommand.register(this.dispatcher, commandRegistryAccess); ExecuteCommand.register(this.dispatcher, commandRegistryAccess); -@@ -263,11 +263,24 @@ public class Commands { +@@ -268,11 +268,24 @@ public class Commands { } } // Paper end - Vanilla command permission fixes @@ -2120,7 +2120,7 @@ index 7b86e064564d3a285e3971fd08ea6168bac0720e..74fcdc74dc6c5cbf81abb7d46fc70047 this.dispatcher.setConsumer(ExecutionCommandSource.resultConsumer()); } -@@ -323,6 +336,11 @@ public class Commands { +@@ -328,6 +341,11 @@ public class Commands { } public void performCommand(ParseResults parseresults, String s, String label) { // CraftBukkit @@ -2131,8 +2131,8 @@ index 7b86e064564d3a285e3971fd08ea6168bac0720e..74fcdc74dc6c5cbf81abb7d46fc70047 + // Paper end CommandSourceStack commandlistenerwrapper = (CommandSourceStack) parseresults.getContext().getSource(); - commandlistenerwrapper.getServer().getProfiler().push(() -> { -@@ -337,10 +355,11 @@ public class Commands { + Profiler.get().push(() -> { +@@ -342,10 +360,11 @@ public class Commands { }); } } catch (Exception exception) { @@ -2145,7 +2145,7 @@ index 7b86e064564d3a285e3971fd08ea6168bac0720e..74fcdc74dc6c5cbf81abb7d46fc70047 StackTraceElement[] astacktraceelement = exception.getStackTrace(); for (int i = 0; i < Math.min(astacktraceelement.length, 3); ++i) { -@@ -473,13 +492,7 @@ public class Commands { +@@ -478,13 +497,7 @@ public class Commands { private void sendAsync(ServerPlayer player) { // Paper end - Perf: Async command map building Map, CommandNode> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues @@ -2160,7 +2160,7 @@ index 7b86e064564d3a285e3971fd08ea6168bac0720e..74fcdc74dc6c5cbf81abb7d46fc70047 RootCommandNode rootcommandnode = new RootCommandNode(); map.put(this.dispatcher.getRoot(), rootcommandnode); -@@ -513,6 +526,7 @@ public class Commands { +@@ -518,6 +531,7 @@ public class Commands { } private void fillUsableCommands(CommandNode tree, CommandNode result, CommandSourceStack source, Map, CommandNode> resultNodes) { @@ -2168,7 +2168,7 @@ index 7b86e064564d3a285e3971fd08ea6168bac0720e..74fcdc74dc6c5cbf81abb7d46fc70047 Iterator iterator = tree.getChildren().iterator(); while (iterator.hasNext()) { -@@ -526,6 +540,42 @@ public class Commands { +@@ -531,6 +545,42 @@ public class Commands { if (commandnode2.canUse(source)) { ArgumentBuilder argumentbuilder = commandnode2.createBuilder(); // CraftBukkit - decompile error @@ -2228,10 +2228,10 @@ index 55484826fc5ddd04ae024e25a0251796d7fa9c28..237e4f7b24908e9ade9a483eb7ae05fa Component component = message.resolveComponent(commandSourceStack); CommandSigningContext commandSigningContext = commandSourceStack.getSigningContext(); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 42a74f5471da882d63c194b1e212f78a94b103ec..a093f29a0b75b5a9e2db2238698d2f3f4ac14ed1 100644 +index f575c0042f67c70df0ddb1d1db68e0138cf0b534..21660e4284cfabb333a3edf9224c892ef80b2403 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -306,7 +306,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; @@ -2240,7 +2240,7 @@ index 42a74f5471da882d63c194b1e212f78a94b103ec..a093f29a0b75b5a9e2db2238698d2f3f private boolean forceTicks; // CraftBukkit end // Spigot start -@@ -392,7 +392,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { @@ -2269,13 +2269,10 @@ index 42a74f5471da882d63c194b1e212f78a94b103ec..a093f29a0b75b5a9e2db2238698d2f3f this.packRepository.setSelected(dataPacks); WorldDataConfiguration worlddataconfiguration = new WorldDataConfiguration(MinecraftServer.getSelectedPacks(this.packRepository, true), this.worldData.enabledFeatures()); -@@ -2192,8 +2194,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop getDispatcher() { @@ -2330,10 +2326,10 @@ index ec29e95d796305b8d44c2075629a8147a05f48c1..9cd4f7c6910727c849ac7f5d675dc610 public void tick() { diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index b4af03c4bdd1ce0861f36c3b75fc7e89d701c46a..0761d5bc5f2813bb4a9f664ac7a05b9744d0a778 100644 +index eb9dab7be7da11ab1c4046a7fc4a29d5bddf31d2..39c9c0dad159744da8322c3dfa3bfae448f73241 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -237,7 +237,6 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -236,7 +236,6 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now @@ -2342,10 +2338,10 @@ index b4af03c4bdd1ce0861f36c3b75fc7e89d701c46a..0761d5bc5f2813bb4a9f664ac7a05b97 this.setPvpAllowed(dedicatedserverproperties.pvp); this.setFlightAllowed(dedicatedserverproperties.allowFlight); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index e0c46e548a34c963750c9411dfd3c0946d67a7c7..5215783353021583e7a726d281e4d1734398f073 100644 +index 74b70c7a41d03bae57e1b2863b7ce947f951da46..7508434475ea93f9153f3976c5fa95c7678807e9 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2407,33 +2407,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2421,33 +2421,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } @@ -2392,10 +2388,10 @@ index e0c46e548a34c963750c9411dfd3c0946d67a7c7..5215783353021583e7a726d281e4d173 // CraftBukkit end diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 0fc6e659915a4547c2db9205fed205a1d28f21d4..35d1dcabb182b0a31727e5ddefe33955c804603b 100644 +index 97850b3111dfa86d15186fa200937b28bec428de..6235d7caede85f4cf21dadde18d8080004672349 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -272,11 +272,11 @@ public final class CraftServer implements Server { +@@ -275,11 +275,11 @@ public final class CraftServer implements Server { private final Logger logger = Logger.getLogger("Minecraft"); private final ServicesManager servicesManager = new SimpleServicesManager(); private final CraftScheduler scheduler = new CraftScheduler(); @@ -2410,7 +2406,7 @@ index 0fc6e659915a4547c2db9205fed205a1d28f21d4..35d1dcabb182b0a31727e5ddefe33955 private final StructureManager structureManager; protected final DedicatedServer console; protected final DedicatedPlayerList playerList; -@@ -404,6 +404,12 @@ public final class CraftServer implements Server { +@@ -407,6 +407,12 @@ public final class CraftServer implements Server { this.serverLinks = new CraftServerLinks(console); Bukkit.setServer(this); @@ -2423,7 +2419,7 @@ index 0fc6e659915a4547c2db9205fed205a1d28f21d4..35d1dcabb182b0a31727e5ddefe33955 CraftRegistry.setMinecraftRegistry(console.registryAccess()); -@@ -603,48 +609,11 @@ public final class CraftServer implements Server { +@@ -606,48 +612,11 @@ public final class CraftServer implements Server { } private void setVanillaCommands(boolean first) { // Spigot @@ -2474,7 +2470,7 @@ index 0fc6e659915a4547c2db9205fed205a1d28f21d4..35d1dcabb182b0a31727e5ddefe33955 // Refresh commands for (ServerPlayer player : this.getHandle().players) { -@@ -1031,17 +1000,31 @@ public final class CraftServer implements Server { +@@ -1034,17 +1003,31 @@ public final class CraftServer implements Server { return true; } @@ -2516,7 +2512,7 @@ index 0fc6e659915a4547c2db9205fed205a1d28f21d4..35d1dcabb182b0a31727e5ddefe33955 return false; } -@@ -1050,7 +1033,7 @@ public final class CraftServer implements Server { +@@ -1053,7 +1036,7 @@ public final class CraftServer implements Server { public void reload() { // Paper start - lifecycle events if (io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner.INSTANCE.blocksPluginReloading()) { @@ -2525,7 +2521,7 @@ index 0fc6e659915a4547c2db9205fed205a1d28f21d4..35d1dcabb182b0a31727e5ddefe33955 } // Paper end - lifecycle events org.spigotmc.WatchdogThread.hasStarted = false; // Paper - Disable watchdog early timeout on reload -@@ -1105,8 +1088,9 @@ public final class CraftServer implements Server { +@@ -1108,8 +1091,9 @@ public final class CraftServer implements Server { } Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper @@ -2536,7 +2532,7 @@ index 0fc6e659915a4547c2db9205fed205a1d28f21d4..35d1dcabb182b0a31727e5ddefe33955 // Paper start for (Plugin plugin : pluginClone) { entityMetadata.removeAll(plugin); -@@ -1146,6 +1130,12 @@ public final class CraftServer implements Server { +@@ -1149,6 +1133,12 @@ public final class CraftServer implements Server { this.enablePlugins(PluginLoadOrder.STARTUP); this.enablePlugins(PluginLoadOrder.POSTWORLD); if (io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper != null) io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper.pluginsEnabled(); // Paper - Remap plugins @@ -2575,11 +2571,11 @@ index 4b1ac1fe7ea07f419ae2818251900e7ba434ee16..90ed57a7fbcd0625b64084347460e986 public Map getKnownCommands() { diff --git a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java -index 2ee33c55890fa659f6d251e486264c85d9e89802..d7a41421784cf9066518310e00031e26d9817171 100644 +index a35e2d2f53e8308d51e5a07b34c56d05a707bc14..945878e989f136ac516eb1c539c0626547c465fb 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java +++ b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java -@@ -23,14 +23,26 @@ import org.bukkit.craftbukkit.entity.CraftMinecartCommand; - import org.bukkit.entity.Entity; +@@ -23,14 +23,26 @@ import org.bukkit.craftbukkit.entity.CraftEntity; + import org.bukkit.craftbukkit.entity.CraftMinecartCommand; import org.bukkit.entity.minecart.CommandMinecart; -public final class VanillaCommandWrapper extends BukkitCommand { @@ -2821,7 +2817,7 @@ index 0000000000000000000000000000000000000000..4b419ce023f61d5af9ff7a34e6879de1 + } +} diff --git a/src/test/java/org/bukkit/support/DummyServerHelper.java b/src/test/java/org/bukkit/support/DummyServerHelper.java -index 5d24b95e3eec351ec1e9444533dd5f9d376ec4c6..fb4b7625b4ea4b4918ade95829e10e98d1bac70f 100644 +index 2fed099bc91a8591a2415493b333f9c18bfe35f6..55c05c16a80c489cdda2fd03c943921d38d978e9 100644 --- a/src/test/java/org/bukkit/support/DummyServerHelper.java +++ b/src/test/java/org/bukkit/support/DummyServerHelper.java @@ -87,7 +87,7 @@ public final class DummyServerHelper { diff --git a/patches/server/0958-Fix-issues-with-Recipe-API.patch b/patches/server/0958-Fix-issues-with-Recipe-API.patch new file mode 100644 index 000000000000..bcc33fc956f8 --- /dev/null +++ b/patches/server/0958-Fix-issues-with-Recipe-API.patch @@ -0,0 +1,94 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sun, 12 May 2024 15:49:36 -0700 +Subject: [PATCH] Fix issues with Recipe API + + +diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java +index dd02af6574dd97404bc9c02c9ead84e1dd537efe..980fea65899ef5f37808506b822fd3de5830d2c7 100644 +--- a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java ++++ b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java +@@ -98,7 +98,7 @@ public class ShapedRecipe implements CraftingRecipe { + char c = 'a'; + for (Optional list : this.pattern.ingredients()) { + RecipeChoice choice = CraftRecipe.toBukkit(list); +- if (choice != null) { ++ if (choice != RecipeChoice.empty()) { // Paper + recipe.setIngredient(c, choice); + } + +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java +index a68e036a12b354c4f04b6596dfb9cd6e7663718b..d8af6522f7516de93e33cb9da8490f5ec14e7553 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java +@@ -38,6 +38,10 @@ public interface CraftRecipe extends Recipe { + stack = Ingredient.of(((RecipeChoice.MaterialChoice) bukkit).getChoices().stream().map((mat) -> CraftItemType.bukkitToMinecraft(mat))); + } else if (bukkit instanceof RecipeChoice.ExactChoice) { + stack = Ingredient.ofStacks(((RecipeChoice.ExactChoice) bukkit).getChoices().stream().map((mat) -> CraftItemStack.asNMSCopy(mat))); ++ // Paper start - support "empty" choices ++ } else if (bukkit == RecipeChoice.empty()) { ++ stack = Ingredient.of(); ++ // Paper end + } else { + throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit); + } +@@ -58,7 +62,7 @@ public interface CraftRecipe extends Recipe { + List> items = list.items(); + + if (items.isEmpty()) { +- return null; ++ return RecipeChoice.empty(); // Paper - null breaks API contracts + } + + if (list.isExact()) { +diff --git a/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java b/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java +new file mode 100644 +index 0000000000000000000000000000000000000000..45ab2b6d32b29cb663df848534e1aa68293dd613 +--- /dev/null ++++ b/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java +@@ -0,0 +1,25 @@ ++package io.papermc.paper.inventory.recipe; ++ ++import java.util.Iterator; ++import org.bukkit.Bukkit; ++import org.bukkit.inventory.Recipe; ++import org.bukkit.support.environment.AllFeatures; ++import org.junit.jupiter.api.Test; ++ ++import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; ++import static org.junit.jupiter.api.Assertions.assertTrue; ++ ++@AllFeatures ++class TestRecipeChoice { ++ ++ @Test ++ void testRecipeChoices() { ++ final Iterator iter = Bukkit.recipeIterator(); ++ boolean foundRecipes = false; ++ while (iter.hasNext()) { ++ foundRecipes = true; ++ assertDoesNotThrow(iter::next, "Failed to convert a recipe to Bukkit recipe!"); ++ } ++ assertTrue(foundRecipes, "No recipes found!"); ++ } ++} +diff --git a/src/test/java/org/bukkit/support/DummyServerHelper.java b/src/test/java/org/bukkit/support/DummyServerHelper.java +index 55c05c16a80c489cdda2fd03c943921d38d978e9..6855816ec5fd232b53622c316e45b3c081297085 100644 +--- a/src/test/java/org/bukkit/support/DummyServerHelper.java ++++ b/src/test/java/org/bukkit/support/DummyServerHelper.java +@@ -92,6 +92,15 @@ public final class DummyServerHelper { + // Paper end - testing additions + + io.papermc.paper.configuration.GlobalConfigTestingBase.setupGlobalConfigForTest(); // Paper - configuration files - setup global configuration test base ++ ++ // Paper start - add test for recipe conversion ++ when(instance.recipeIterator()).thenAnswer(ignored -> ++ com.google.common.collect.Iterators.transform( ++ RegistryHelper.getDataPack().getRecipeManager().byType.entries().iterator(), ++ input -> input.getValue().toBukkitRecipe() ++ ) ++ ); ++ // Paper end - add test for recipe conversion + return instance; + } + } diff --git a/patches/unapplied/server/0967-Fix-equipment-slot-and-group-API.patch b/patches/server/0959-Fix-equipment-slot-and-group-API.patch similarity index 93% rename from patches/unapplied/server/0967-Fix-equipment-slot-and-group-API.patch rename to patches/server/0959-Fix-equipment-slot-and-group-API.patch index e45968e40750..ecc15fdf243f 100644 --- a/patches/unapplied/server/0967-Fix-equipment-slot-and-group-API.patch +++ b/patches/server/0959-Fix-equipment-slot-and-group-API.patch @@ -10,10 +10,10 @@ Adds the following: Co-authored-by: SoSeDiK diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index fb6465bbb2a8bb7597c15d7ac8375f696b897e43..34641a6356876c46d05188a988c02835d0c06dc6 100644 +index a62d17b72c675120b447e625cb3dc437681bdf20..f16067b674118a47735ad22797988d50b4415040 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -1211,4 +1211,11 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -1230,4 +1230,11 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { this.getHandle().setYBodyRot(bodyYaw); } // Paper end - body yaw API @@ -26,7 +26,7 @@ index fb6465bbb2a8bb7597c15d7ac8375f696b897e43..34641a6356876c46d05188a988c02835 + // Paper end - Expose canUseSlot } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java -index 9d74577af071954e1e37201a96368c1360076209..eafa54c870c3e2aef30c3f9f96f516607a7cae24 100644 +index 46d0b324498510c73a8439611f44269edee62313..69982103d8ea31e9b83b18c4c03a7b021bb983b9 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java @@ -135,6 +135,10 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i @@ -52,10 +52,10 @@ index 9d74577af071954e1e37201a96368c1360076209..eafa54c870c3e2aef30c3f9f96f51660 throw new IllegalArgumentException("Not implemented. This is a bug"); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index 88e1156510f3a43dd37e279205e5ed5dd120c1db..7f6f404f5a2be7876ae239355979e8c8a7a198ce 100644 +index 63567251d101b5e50ffd7e2825b1411fcb433c8c..450c5aa14b4195eb7123492c7a111ec6f40ce412 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -@@ -1450,7 +1450,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1702,7 +1702,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { if (this.attributeModifiers == null) return LinkedHashMultimap.create(); // Paper - don't change the components SetMultimap result = LinkedHashMultimap.create(); for (Map.Entry entry : this.attributeModifiers.entries()) { @@ -64,7 +64,7 @@ index 88e1156510f3a43dd37e279205e5ed5dd120c1db..7f6f404f5a2be7876ae239355979e8c8 result.put(entry.getKey(), entry.getValue()); } } -@@ -1524,9 +1524,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1776,9 +1776,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { while (iter.hasNext()) { Map.Entry entry = iter.next(); diff --git a/patches/unapplied/server/0968-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch b/patches/server/0960-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch similarity index 100% rename from patches/unapplied/server/0968-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch rename to patches/server/0960-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch diff --git a/patches/unapplied/server/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch b/patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch similarity index 93% rename from patches/unapplied/server/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch rename to patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch index 121b75eca68b..b2a9a23cfe45 100644 --- a/patches/unapplied/server/0969-Prevent-sending-oversized-item-data-in-equipment-and.patch +++ b/patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch @@ -120,10 +120,10 @@ index 0000000000000000000000000000000000000000..72483dedd3b1864fca3463d3ba3f6fad + } +} diff --git a/src/main/java/net/minecraft/core/component/DataComponents.java b/src/main/java/net/minecraft/core/component/DataComponents.java -index c9aef759c1485da753e820f9b509117ca50a31e4..60757f8df706cba92350d73503b73913cff3bcfc 100644 +index a7f6a53cd1168bfc53b616cb0586a546fb9793e7..5e3bfd4a06b4a547a5f813f3d0c533fb7f4451f3 100644 --- a/src/main/java/net/minecraft/core/component/DataComponents.java +++ b/src/main/java/net/minecraft/core/component/DataComponents.java -@@ -138,10 +138,10 @@ public class DataComponents { +@@ -180,10 +180,10 @@ public class DataComponents { "map_post_processing", builder -> builder.networkSynchronized(MapPostProcessing.STREAM_CODEC) ); public static final DataComponentType CHARGED_PROJECTILES = register( @@ -136,7 +136,7 @@ index c9aef759c1485da753e820f9b509117ca50a31e4..60757f8df706cba92350d73503b73913 ); public static final DataComponentType POTION_CONTENTS = register( "potion_contents", builder -> builder.persistent(PotionContents.CODEC).networkSynchronized(PotionContents.STREAM_CODEC).cacheEncoding() -@@ -208,7 +208,7 @@ public class DataComponents { +@@ -250,7 +250,7 @@ public class DataComponents { "pot_decorations", builder -> builder.persistent(PotDecorations.CODEC).networkSynchronized(PotDecorations.STREAM_CODEC).cacheEncoding() ); public static final DataComponentType CONTAINER = register( @@ -162,7 +162,7 @@ index 59c1c103545f04fd35e6932df64a9910a1d74cd7..56bde49e6b7790155b032d0be40961d5 buf.writeByte(255); } diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java -index 2ea7e90d582866b4e29db80836e250163d811763..d152871142d3def2ac04f50037db53b0527f7894 100644 +index e46030178b3b54168a3532def308a08b10888723..830bd76916e26a3a54954d3cf7b7520af52a2258 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java @@ -19,6 +19,13 @@ public class ClientboundSetEquipmentPacket implements Packet pair = this.slots.get(j); EquipmentSlot equipmentSlot = pair.getFirst(); -@@ -49,6 +57,7 @@ public class ClientboundSetEquipmentPacket implements Packet capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper - Retain block place order when capturing blockstates public List captureDrops; 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 86eb9029969f4de3ada7be9e135e9764172b85f5..21946a93b6a2a3c79d15af1d6e7eabc537ba0125 100644 +index 5dd1df0da1f954778aebe0f40611ae0f3a7866ab..325d1e38a72a4b30f30261267e9adfb8a8726b11 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -345,7 +345,7 @@ public class LevelChunk extends ChunkAccess { +@@ -369,7 +369,7 @@ public class LevelChunk extends ChunkAccess { boolean flag3 = iblockdata1.hasBlockEntity(); diff --git a/patches/unapplied/server/0972-Add-missing-fishing-event-state.patch b/patches/server/0964-Add-missing-fishing-event-state.patch similarity index 90% rename from patches/unapplied/server/0972-Add-missing-fishing-event-state.patch rename to patches/server/0964-Add-missing-fishing-event-state.patch index 6ad1a92dd0c8..5bc1574135b8 100644 --- a/patches/unapplied/server/0972-Add-missing-fishing-event-state.patch +++ b/patches/server/0964-Add-missing-fishing-event-state.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add missing fishing event state diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -index 6ce65e5b336be9b49db84f1c4755c2e2ce7f8378..1223c5d23d0ea6aed068bdf0f5725e2ad49fc82c 100644 +index 762deff3bef8ec478d83139e8193aba35e39807d..4daa69c6be6d48563e30343a7e40e4da9ec7e5ad 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java +++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -@@ -411,6 +411,15 @@ public class FishingHook extends Projectile { +@@ -416,6 +416,15 @@ public class FishingHook extends Projectile { this.fishAngle = Mth.nextFloat(this.random, this.minLureAngle, this.maxLureAngle); this.timeUntilHooked = Mth.nextInt(this.random, this.minLureTime, this.maxLureTime); // CraftBukkit end diff --git a/patches/unapplied/server/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch b/patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch similarity index 92% rename from patches/unapplied/server/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch rename to patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch index 23a507f4bfc7..fedf5ac8051e 100644 --- a/patches/unapplied/server/0973-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch +++ b/patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Deprecate InvAction#HOTBAR_MOVE_AND_READD diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 0fe4c3ff5dd855aea58292c16ba9a2f5d23c00f5..0034483685ba626e5883b857de96ffd36e57e150 100644 +index dc8f2d0bc3adc87088e7289a90c9186483e21cf4..2533c0a54e74666a55a8478c7d4da12d26e31fd4 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2997,14 +2997,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3014,14 +3014,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl Slot clickedSlot = this.player.containerMenu.getSlot(packet.getSlotNum()); if (clickedSlot.mayPickup(this.player)) { ItemStack hotbar = this.player.getInventory().getItem(packet.getButtonNum()); diff --git a/patches/unapplied/server/0974-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch b/patches/server/0966-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch similarity index 100% rename from patches/unapplied/server/0974-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch rename to patches/server/0966-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch diff --git a/patches/unapplied/server/0975-Adopt-MaterialRerouting.patch b/patches/server/0967-Adopt-MaterialRerouting.patch similarity index 100% rename from patches/unapplied/server/0975-Adopt-MaterialRerouting.patch rename to patches/server/0967-Adopt-MaterialRerouting.patch diff --git a/patches/unapplied/server/0976-Suspicious-Effect-Entry-API.patch b/patches/server/0968-Suspicious-Effect-Entry-API.patch similarity index 98% rename from patches/unapplied/server/0976-Suspicious-Effect-Entry-API.patch rename to patches/server/0968-Suspicious-Effect-Entry-API.patch index bc26031199fa..d2599dfa8530 100644 --- a/patches/unapplied/server/0976-Suspicious-Effect-Entry-API.patch +++ b/patches/server/0968-Suspicious-Effect-Entry-API.patch @@ -14,7 +14,7 @@ in which it replaces PotionEffect. Co-authored-by: Yannick Lamprecht diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java -index 9cc81bcccbf1141f66fedada1359b7c0dfa8e22a..5c5b64bd058684520fa175bfd10622ff57856b7c 100644 +index bfe39c7a9d2910bee9b40cf5ab4c154711d5cbb0..596146ad7899c21645df8834ce5f0afd6c1b0604 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java @@ -37,16 +37,24 @@ public class CraftMushroomCow extends CraftCow implements MushroomCow, io.paperm @@ -47,7 +47,7 @@ index 9cc81bcccbf1141f66fedada1359b7c0dfa8e22a..5c5b64bd058684520fa175bfd10622ff return true; } @@ -101,6 +109,43 @@ public class CraftMushroomCow extends CraftCow implements MushroomCow, io.paperm - this.getHandle().setVariant(net.minecraft.world.entity.animal.MushroomCow.MushroomType.values()[variant.ordinal()]); + this.getHandle().setVariant(net.minecraft.world.entity.animal.MushroomCow.Variant.values()[variant.ordinal()]); } + // Paper start diff --git a/patches/unapplied/server/0977-check-if-itemstack-is-stackable-first.patch b/patches/server/0969-check-if-itemstack-is-stackable-first.patch similarity index 87% rename from patches/unapplied/server/0977-check-if-itemstack-is-stackable-first.patch rename to patches/server/0969-check-if-itemstack-is-stackable-first.patch index 8e11960bdd1e..a7ddd8df5bfa 100644 --- a/patches/unapplied/server/0977-check-if-itemstack-is-stackable-first.patch +++ b/patches/server/0969-check-if-itemstack-is-stackable-first.patch @@ -5,10 +5,10 @@ Subject: [PATCH] check if itemstack is stackable first diff --git a/src/main/java/net/minecraft/world/entity/player/Inventory.java b/src/main/java/net/minecraft/world/entity/player/Inventory.java -index a62e7354bf67a66bdf9cd7c8f5d2e8f6bcacc74f..6e66141dca61f777b354854b5d0bac2570b8bf3b 100644 +index aaff1592876ac4a967e4fd47e4b6619a17d57867..ad82e5aeb565b23c3ec565fa60e1f31d1710bd4e 100644 --- a/src/main/java/net/minecraft/world/entity/player/Inventory.java +++ b/src/main/java/net/minecraft/world/entity/player/Inventory.java -@@ -111,7 +111,7 @@ public class Inventory implements Container, Nameable { +@@ -110,7 +110,7 @@ public class Inventory implements Container, Nameable { } private boolean hasRemainingSpaceForItem(ItemStack existingStack, ItemStack stack) { diff --git a/patches/unapplied/server/0978-Fix-removing-recipes-from-RecipeIterator.patch b/patches/server/0970-Fix-removing-recipes-from-RecipeIterator.patch similarity index 92% rename from patches/unapplied/server/0978-Fix-removing-recipes-from-RecipeIterator.patch rename to patches/server/0970-Fix-removing-recipes-from-RecipeIterator.patch index 461c3eb854c1..636f3d2440d1 100644 --- a/patches/unapplied/server/0978-Fix-removing-recipes-from-RecipeIterator.patch +++ b/patches/server/0970-Fix-removing-recipes-from-RecipeIterator.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Fix removing recipes from RecipeIterator public net.minecraft.world.item.crafting.RecipeManager byName diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java b/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java -index 78a2afa981407de793ac940d6eb7315c5cd53b8f..33cd12d55786356dc89ab9d3872b2f7d266c3de2 100644 +index 4e0f7564f04d5d566660a2623fb1b325e3b4e67c..39d2d67bf478beb4c72e41e6f59337893cf47e69 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java @@ -9,6 +9,7 @@ import org.bukkit.inventory.Recipe; @@ -17,7 +17,7 @@ index 78a2afa981407de793ac940d6eb7315c5cd53b8f..33cd12d55786356dc89ab9d3872b2f7d + private Recipe currentRecipe; // Paper - fix removing recipes from RecipeIterator public RecipeIterator() { - this.recipes = MinecraftServer.getServer().getRecipeManager().byType.entries().iterator(); + this.recipes = MinecraftServer.getServer().getRecipeManager().recipes.byType.entries().iterator(); @@ -21,11 +22,19 @@ public class RecipeIterator implements Iterator { @Override diff --git a/patches/unapplied/server/0979-Configurable-damage-tick-when-blocking-with-shield.patch b/patches/server/0971-Configurable-damage-tick-when-blocking-with-shield.patch similarity index 90% rename from patches/unapplied/server/0979-Configurable-damage-tick-when-blocking-with-shield.patch rename to patches/server/0971-Configurable-damage-tick-when-blocking-with-shield.patch index 7f58a8291d4c..0c36cdb62dbf 100644 --- a/patches/unapplied/server/0979-Configurable-damage-tick-when-blocking-with-shield.patch +++ b/patches/server/0971-Configurable-damage-tick-when-blocking-with-shield.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Configurable damage tick when blocking with shield diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 7b6d067eb8b22a8e0a82a2969c92ba243230733a..5f1c585c819d25319a4fefd30abde3de7620cf6d 100644 +index 5a992419f9847480ca6e431b5402d99ac411c15e..6195b207159c638e98a33c3142ed6b0720c8e14d 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2411,7 +2411,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2488,7 +2488,7 @@ public abstract class LivingEntity extends Entity implements Attackable { CriteriaTriggers.PLAYER_HURT_ENTITY.trigger((ServerPlayer) damagesource.getEntity(), this, damagesource, originalDamage, f, true); // Paper - fix taken/dealt param order } diff --git a/patches/unapplied/server/0980-Properly-remove-the-experimental-smithing-inventory-.patch b/patches/server/0972-Properly-remove-the-experimental-smithing-inventory-.patch similarity index 100% rename from patches/unapplied/server/0980-Properly-remove-the-experimental-smithing-inventory-.patch rename to patches/server/0972-Properly-remove-the-experimental-smithing-inventory-.patch diff --git a/patches/unapplied/server/0966-Fix-issues-with-Recipe-API.patch b/patches/unapplied/server/0966-Fix-issues-with-Recipe-API.patch deleted file mode 100644 index 415b2d65ba23..000000000000 --- a/patches/unapplied/server/0966-Fix-issues-with-Recipe-API.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sun, 12 May 2024 15:49:36 -0700 -Subject: [PATCH] Fix issues with Recipe API - - -diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java -index 63cf2b66f51df68aa3f6d98c69368ce454869d64..1bf54b0142fe41b29b21c8b97d3f52bb24a36a92 100644 ---- a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java -+++ b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java -@@ -90,7 +90,7 @@ public class ShapedRecipe extends io.papermc.paper.inventory.recipe.RecipeBookEx - char c = 'a'; - for (Ingredient list : this.pattern.ingredients()) { - RecipeChoice choice = CraftRecipe.toBukkit(list); -- if (choice != null) { -+ if (choice != RecipeChoice.empty()) { // Paper - recipe.setIngredient(c, choice); - } - -diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java -index 6ba29875d78ede4aa7978ff689e588f7fed11528..c76c78bb7757d407102271463e14716a1b012deb 100644 ---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java -+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java -@@ -29,6 +29,10 @@ public interface CraftRecipe extends Recipe { - } else if (bukkit instanceof RecipeChoice.ExactChoice) { - stack = new Ingredient(((RecipeChoice.ExactChoice) bukkit).getChoices().stream().map((mat) -> new net.minecraft.world.item.crafting.Ingredient.ItemValue(CraftItemStack.asNMSCopy(mat)))); - stack.exact = true; -+ // Paper start - support "empty" choices -+ } else if (bukkit == RecipeChoice.empty()) { -+ stack = Ingredient.EMPTY; -+ // Paper end - } else { - throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit); - } -@@ -45,7 +49,7 @@ public interface CraftRecipe extends Recipe { - list.getItems(); - - if (list.itemStacks.length == 0) { -- return null; -+ return RecipeChoice.empty(); // Paper - null breaks API contracts - } - - if (list.exact) { -diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java -index 37b39a2c696a59b0f52324cc222b83c0c9f341e6..3aec771478a6b17353d57e82baac53dd24779e7b 100644 ---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java -+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java -@@ -30,6 +30,6 @@ public class CraftSmithingTransformRecipe extends SmithingTransformRecipe implem - public void addToCraftingManager() { - ItemStack result = this.getResult(); - -- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), CraftItemStack.asNMSCopy(result), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy -+ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), CraftItemStack.asNMSCopy(result), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy & support empty RecipeChoice - } - } -diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java -index 389fa313f811279091cace76faaabf8bdb0fc94c..61af2fe3534ff67f10310c6c7dec39cff0f93ee3 100644 ---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java -+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java -@@ -28,6 +28,6 @@ public class CraftSmithingTrimRecipe extends SmithingTrimRecipe implements Craft - - @Override - public void addToCraftingManager() { -- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy -+ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy & support empty RecipeChoice - } - } -diff --git a/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java b/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java -new file mode 100644 -index 0000000000000000000000000000000000000000..45ab2b6d32b29cb663df848534e1aa68293dd613 ---- /dev/null -+++ b/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java -@@ -0,0 +1,25 @@ -+package io.papermc.paper.inventory.recipe; -+ -+import java.util.Iterator; -+import org.bukkit.Bukkit; -+import org.bukkit.inventory.Recipe; -+import org.bukkit.support.environment.AllFeatures; -+import org.junit.jupiter.api.Test; -+ -+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -+import static org.junit.jupiter.api.Assertions.assertTrue; -+ -+@AllFeatures -+class TestRecipeChoice { -+ -+ @Test -+ void testRecipeChoices() { -+ final Iterator iter = Bukkit.recipeIterator(); -+ boolean foundRecipes = false; -+ while (iter.hasNext()) { -+ foundRecipes = true; -+ assertDoesNotThrow(iter::next, "Failed to convert a recipe to Bukkit recipe!"); -+ } -+ assertTrue(foundRecipes, "No recipes found!"); -+ } -+} -diff --git a/src/test/java/org/bukkit/support/DummyServerHelper.java b/src/test/java/org/bukkit/support/DummyServerHelper.java -index fb4b7625b4ea4b4918ade95829e10e98d1bac70f..cb2b39c562f609375b9e5b20cb5899780995373d 100644 ---- a/src/test/java/org/bukkit/support/DummyServerHelper.java -+++ b/src/test/java/org/bukkit/support/DummyServerHelper.java -@@ -92,6 +92,15 @@ public final class DummyServerHelper { - // Paper end - testing additions - - io.papermc.paper.configuration.GlobalConfigTestingBase.setupGlobalConfigForTest(); // Paper - configuration files - setup global configuration test base -+ -+ // Paper start - add test for recipe conversion -+ when(instance.recipeIterator()).thenAnswer(ignored -> -+ com.google.common.collect.Iterators.transform( -+ RegistryHelper.getDataPack().getRecipeManager().byType.entries().iterator(), -+ input -> input.getValue().toBukkitRecipe() -+ ) -+ ); -+ // Paper end - add test for recipe conversion - return instance; - } - } From 9047541397bdc7dd65114c01de6994870971b851 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Thu, 24 Oct 2024 19:29:35 +0200 Subject: [PATCH 042/119] Upstream update --- README.md | 4 +- build.gradle.kts | 2 +- gradle.properties | 4 +- .../api/0001-Convert-project-to-Gradle.patch | 4 +- patches/api/0006-Adventure.patch | 74 +++++++++---------- patches/api/0011-Timings-v2.patch | 4 +- .../0013-Player-affects-spawning-API.patch | 4 +- patches/api/0017-Add-view-distance-API.patch | 4 +- ...cord-chat-API-from-spigot-subclasses.patch | 4 +- .../0024-Player-Tab-List-and-Title-APIs.patch | 4 +- .../api/0026-Complete-resource-pack-API.patch | 4 +- ...0045-Add-String-based-Action-Bar-API.patch | 6 +- patches/api/0053-Fix-upstream-javadocs.patch | 18 ++--- ...nt-protocol-version-and-virtual-host.patch | 4 +- ...8-Ability-to-apply-mending-to-XP-API.patch | 6 +- .../0089-Player.setPlayerProfile-API.patch | 4 +- ...2-Add-openSign-method-to-HumanEntity.patch | 4 +- ...93-Add-Ban-Methods-to-Player-Objects.patch | 4 +- ...e-attack-cooldown-methods-for-Player.patch | 4 +- .../0166-Fix-Spigot-annotation-mistakes.patch | 4 +- .../0183-Add-Player-Client-Options-API.patch | 4 +- patches/api/0198-Brand-support.patch | 4 +- .../api/0208-Player-elytra-boost-API.patch | 4 +- patches/api/0235-Add-sendOpLevel-API.patch | 4 +- .../api/0280-Add-PlayerKickEvent-causes.patch | 4 +- patches/api/0325-Multi-Block-Change-API.patch | 4 +- patches/api/0353-More-Teleport-API.patch | 4 +- ...stom-Chat-Completion-Suggestions-API.patch | 4 +- .../0364-Elder-Guardian-appearance-API.patch | 4 +- .../0371-Add-Player-Warden-Warning-API.patch | 4 +- .../0381-Add-Sneaking-API-for-Entities.patch | 6 +- patches/api/0383-Flying-Fall-Damage-API.patch | 4 +- patches/api/0385-Win-Screen-API.patch | 4 +- patches/api/0398-Fix-BanList-API.patch | 8 +- .../api/0406-Add-Listing-API-for-Player.patch | 4 +- .../0420-Add-player-idle-duration-API.patch | 4 +- ...0428-Experimental-annotations-change.patch | 2 +- .../api/0431-Add-experience-points-API.patch | 4 +- .../0454-API-for-checking-sent-chunks.patch | 4 +- ...d-API-to-get-player-ha-proxy-address.patch | 4 +- patches/api/0485-Add-FeatureFlag-API.patch | 4 +- .../api/0490-Improve-entity-effect-API.patch | 4 +- .../server/0001-Setup-Gradle-project.patch | 4 +- patches/server/0008-CB-fixes.patch | 2 +- patches/server/0009-MC-Utils.patch | 4 +- patches/server/0010-Adventure.patch | 36 ++++----- patches/server/0019-Paper-Plugins.patch | 2 +- ...ion-calls-in-plugins-using-internals.patch | 2 +- patches/server/0023-Timings-v2.patch | 18 ++--- ...0033-Expose-server-build-information.patch | 2 +- .../0034-Player-affects-spawning-API.patch | 4 +- ...035-Only-refresh-abilities-if-needed.patch | 4 +- .../0048-Use-null-Locale-by-default.patch | 4 +- ...055-Improve-Player-chat-API-handling.patch | 10 +-- .../0059-Player-Tab-List-and-Title-APIs.patch | 4 +- .../0066-Complete-resource-pack-API.patch | 6 +- ...th-absorb-values-and-repair-bad-data.patch | 4 +- ...0083-Add-PlayerUseUnknownEntityEvent.patch | 4 +- ...onfigurable-packet-in-spam-threshold.patch | 4 +- ...07-Configurable-flying-kick-messages.patch | 6 +- .../0119-String-based-Action-Bar-API.patch | 4 +- ...ke-parrots-stay-on-shoulders-despite.patch | 4 +- patches/server/0151-Add-PlayerJumpEvent.patch | 4 +- ...nt-protocol-version-and-virtual-host.patch | 4 +- .../server/0161-AsyncTabCompleteEvent.patch | 4 +- ...3-Ability-to-apply-mending-to-XP-API.patch | 4 +- .../0176-Player.setPlayerProfile-API.patch | 14 ++-- ...81-Flag-to-disable-the-channel-limit.patch | 6 +- .../0207-InventoryCloseEvent-Reason-API.patch | 8 +- ...nd-make-tab-spam-limits-configurable.patch | 8 +- ...e-attack-cooldown-methods-for-Player.patch | 4 +- .../server/0241-Improve-death-events.patch | 4 +- ...event-players-from-moving-into-unloa.patch | 10 +-- ...t-allow-digging-into-unloaded-chunks.patch | 4 +- patches/server/0268-Book-size-limits.patch | 4 +- ...-Replace-OfflinePlayer-getLastPlayed.patch | 10 +-- ...r-remove-if-the-handle-is-a-custom-p.patch | 4 +- .../server/0275-Brigadier-Mojang-API.patch | 4 +- .../0276-Limit-Client-Sign-length-more.patch | 6 +- ...Add-Raw-Byte-ItemStack-Serialization.patch | 2 +- ...-Implement-Player-Client-Options-API.patch | 4 +- ...PickItem-Packet-and-kick-for-invalid.patch | 4 +- ...49-Prevent-teleporting-dead-entities.patch | 4 +- ...t-position-desync-causing-tp-exploit.patch | 4 +- .../0366-Add-PlayerRecipeBookClickEvent.patch | 4 +- ...68-Add-permission-for-command-blocks.patch | 6 +- ...ld-Difficulty-Remembering-Difficulty.patch | 4 +- ...o-not-accept-invalid-client-settings.patch | 4 +- patches/server/0389-Brand-support.patch | 4 +- patches/server/0393-Add-moon-phase-API.patch | 4 +- ...ortation-and-cancel-velocity-if-tele.patch | 4 +- ...y-Counter-to-allow-plugins-to-use-va.patch | 2 +- ...r-large-move-vectors-crashing-server.patch | 12 +-- ...ix-client-lag-on-advancement-loading.patch | 2 +- ...r-spawnParticle-x-y-z-precision-loss.patch | 4 +- .../server/0438-Limit-recipe-packets.patch | 8 +- ...act-event-not-being-called-sometimes.patch | 6 +- patches/server/0466-Add-sendOpLevel-API.patch | 4 +- ...-using-signs-inside-spawn-protection.patch | 4 +- .../server/0496-Expand-world-key-API.patch | 6 +- ...ignore-result-of-PlayerEditBookEvent.patch | 4 +- .../server/0501-Expose-protocol-version.patch | 2 +- ...t-set-drop-chance-to-EntityEquipment.patch | 2 +- ...fix-PlayerItemHeldEvent-firing-twice.patch | 4 +- ...527-Expand-PlayerGameModeChangeEvent.patch | 8 +- .../0528-ItemStack-repair-check-API.patch | 2 +- ...ove-range-check-for-block-placing-up.patch | 4 +- .../0533-Add-Unix-domain-socket-support.patch | 4 +- ...5-Improve-item-default-attribute-API.patch | 2 +- .../0539-Add-PlayerKickEvent-causes.patch | 54 +++++++------- .../server/0548-Line-Of-Sight-Changes.patch | 4 +- .../server/0557-Add-PlayerArmSwingEvent.patch | 4 +- ...k-event-leave-message-not-being-sent.patch | 8 +- ...-AFK-kick-while-watching-end-credits.patch | 4 +- .../server/0566-Add-PlayerSetSpawnEvent.patch | 4 +- .../0580-Get-entity-default-attributes.patch | 2 +- ...89-Add-Raw-Byte-Entity-Serialization.patch | 2 +- ...0593-Improve-and-expand-AsyncCatcher.patch | 4 +- ...-ServerboundCommandSuggestionPacket-.patch | 4 +- ...ulti-Block-Change-API-Implementation.patch | 4 +- patches/server/0665-Custom-Potion-Mixes.patch | 2 +- ...cle-movement-from-players-while-tele.patch | 4 +- .../0673-Implement-getComputedBiome-API.patch | 2 +- .../0674-Make-some-itemstacks-nonnull.patch | 4 +- ...nt-tile-entity-copies-loading-chunks.patch | 4 +- ...g-not-using-commands.spam-exclusions.patch | 4 +- patches/server/0717-More-Teleport-API.patch | 16 ++-- ...ck-entities-after-destroy-prediction.patch | 4 +- ...stom-Chat-Completion-Suggestions-API.patch | 4 +- patches/server/0724-Collision-API.patch | 4 +- ...0728-Add-NamespacedKey-biome-methods.patch | 2 +- .../0741-Fix-a-bunch-of-vanilla-bugs.patch | 4 +- .../0747-Elder-Guardian-appearance-API.patch | 4 +- .../0759-Add-Player-Warden-Warning-API.patch | 4 +- ...async-entity-add-due-to-fungus-trees.patch | 2 +- patches/server/0771-fix-Instruments.patch | 4 +- .../0775-Improve-logging-and-errors.patch | 4 +- ...ssing-SpigotConfig-logCommands-check.patch | 6 +- patches/server/0780-Flying-Fall-Damage.patch | 4 +- ...le-player-info-update-packet-on-join.patch | 4 +- patches/server/0785-Win-Screen-API.patch | 4 +- ...uence-violations-like-they-should-be.patch | 4 +- ...expired-keys-from-impacting-new-join.patch | 8 +- .../0810-Expand-PlayerItemMendEvent.patch | 4 +- patches/server/0829-Fix-BanList-API.patch | 6 +- .../0836-Implement-PlayerFailMoveEvent.patch | 12 +-- ...x-custom-statistic-criteria-creation.patch | 2 +- .../server/0847-Bandaid-fix-for-Effect.patch | 4 +- ...te-namespaced-commands-if-send-names.patch | 4 +- .../0855-Add-Listing-API-for-Player.patch | 8 +- .../server/0861-Add-PlayerPickItemEvent.patch | 4 +- ...-Implement-OfflinePlayer-isConnected.patch | 4 +- patches/server/0866-Fix-slot-desync.patch | 4 +- ...ot-sanity-checks-in-container-clicks.patch | 4 +- ...884-Fix-UnsafeValues-loadAdvancement.patch | 2 +- .../0885-Add-player-idle-duration-API.patch | 4 +- ...stack-for-Player-sendEquipmentChange.patch | 4 +- .../0908-Add-experience-points-API.patch | 4 +- ...Add-api-for-spawn-egg-texture-colors.patch | 2 +- .../0919-Add-Lifecycle-Event-system.patch | 2 +- .../server/0920-ItemStack-Tooltip-API.patch | 2 +- patches/server/0922-Add-FluidState-API.patch | 2 +- .../0928-Add-CartographyItemEvent.patch | 4 +- .../0938-Improve-tag-parser-handling.patch | 6 +- ...d-API-to-get-player-ha-proxy-address.patch | 6 +- .../0957-Brigadier-based-command-API.patch | 4 +- .../0958-Fix-issues-with-Recipe-API.patch | 4 +- ...959-Fix-equipment-slot-and-group-API.patch | 6 +- ...oversized-item-data-in-equipment-and.patch | 4 +- ...cate-InvAction-HOTBAR_MOVE_AND_READD.patch | 4 +- work/BuildData | 2 +- work/Bukkit | 2 +- work/CraftBukkit | 2 +- work/Spigot | 2 +- 174 files changed, 468 insertions(+), 468 deletions(-) diff --git a/README.md b/README.md index de9253cf0b14..9085b3e36b29 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ How To (Plugin Developers) io.papermc.paper paper-api - 1.21.2-R0.1-SNAPSHOT + 1.21.3-R0.1-SNAPSHOT provided ``` @@ -53,7 +53,7 @@ repositories { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.2-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.3-R0.1-SNAPSHOT") } java { diff --git a/build.gradle.kts b/build.gradle.kts index 0182b94ed1e4..9f0522ccbd4d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -67,7 +67,7 @@ repositories { } dependencies { - paramMappings("net.fabricmc:yarn:1.21.2+build.1:mergedv2") + paramMappings("net.fabricmc:yarn:1.21.3+build.1:mergedv2") remapper("net.fabricmc:tiny-remapper:0.10.3:fat") decompiler("org.vineflower:vineflower:1.10.1") spigotDecompiler("io.papermc:patched-spigot-fernflower:0.1+build.13") diff --git a/gradle.properties b/gradle.properties index c61582a178da..37e2da14d9b1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ group=io.papermc.paper -version=1.21.2-R0.1-SNAPSHOT -mcVersion=1.21.2 +version=1.21.3-R0.1-SNAPSHOT +mcVersion=1.21.3 # Set to true while updating Minecraft version updatingMinecraft=true diff --git a/patches/api/0001-Convert-project-to-Gradle.patch b/patches/api/0001-Convert-project-to-Gradle.patch index 42bb94fe5a7f..6cec7f2fe380 100644 --- a/patches/api/0001-Convert-project-to-Gradle.patch +++ b/patches/api/0001-Convert-project-to-Gradle.patch @@ -124,7 +124,7 @@ index 0000000000000000000000000000000000000000..7ac6af074d76b782ef14fe4690bb5b63 +} diff --git a/pom.xml b/pom.xml deleted file mode 100644 -index 9a148bbfa61552dcaa8c0170022fcc463dbcd87b..0000000000000000000000000000000000000000 +index bdde86ea96da233c802e98dc203cb4cb7f8616b0..0000000000000000000000000000000000000000 --- a/pom.xml +++ /dev/null @@ -1,267 +0,0 @@ @@ -135,7 +135,7 @@ index 9a148bbfa61552dcaa8c0170022fcc463dbcd87b..00000000000000000000000000000000 - - org.spigotmc - spigot-api -- 1.21.2-R0.1-SNAPSHOT +- 1.21.3-R0.1-SNAPSHOT - jar - - Spigot-API diff --git a/patches/api/0006-Adventure.patch b/patches/api/0006-Adventure.patch index f96052e8818a..da57b44ba1d6 100644 --- a/patches/api/0006-Adventure.patch +++ b/patches/api/0006-Adventure.patch @@ -2320,10 +2320,10 @@ index 558fe6e23f562ee873fc84112f930c6ea19a09f4..c78fb359bd28b8dc1ba242642ec612e8 + // Paper end } diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306ec156c71b 100644 +index 13bd964951a12a63f4ad243b8a1e1a830ce5abeb..84befa1e5123038b80e0734622a5174634f5a982 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -57,7 +57,41 @@ import org.jetbrains.annotations.Nullable; +@@ -58,7 +58,41 @@ import org.jetbrains.annotations.Nullable; /** * Represents a player, connected or not */ @@ -2366,7 +2366,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e /** * {@inheritDoc} -@@ -74,7 +108,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -75,7 +109,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * places defined by plugins. * * @return the friendly name @@ -2376,7 +2376,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e @NotNull public String getDisplayName(); -@@ -86,15 +122,50 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -87,15 +123,50 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * places defined by plugins. * * @param name The new display name. @@ -2427,7 +2427,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e public String getPlayerListName(); /** -@@ -103,7 +174,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -104,7 +175,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * If the value is null, the name will be identical to {@link #getName()}. * * @param name new player list name @@ -2437,7 +2437,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e public void setPlayerListName(@Nullable String name); /** -@@ -125,7 +198,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -126,7 +199,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * Gets the currently displayed player list header for this player. * * @return player list header or null @@ -2447,7 +2447,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e @Nullable public String getPlayerListHeader(); -@@ -133,7 +208,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -134,7 +209,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * Gets the currently displayed player list footer for this player. * * @return player list header or null @@ -2457,7 +2457,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e @Nullable public String getPlayerListFooter(); -@@ -141,14 +218,18 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -142,14 +219,18 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * Sets the currently displayed player list header for this player. * * @param header player list header, null for empty @@ -2476,7 +2476,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e public void setPlayerListFooter(@Nullable String footer); /** -@@ -157,7 +238,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -158,7 +239,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param header player list header, null for empty * @param footer player list footer, null for empty @@ -2486,7 +2486,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e public void setPlayerListHeaderFooter(@Nullable String header, @Nullable String footer); /** -@@ -234,9 +317,25 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -235,9 +318,25 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * Kicks player with custom kick message. * * @param message kick message @@ -2512,7 +2512,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e /** * Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will * update the entry. -@@ -899,6 +998,106 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -924,6 +1023,106 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public void sendEquipmentChange(@NotNull LivingEntity entity, @NotNull Map items); @@ -2619,7 +2619,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e /** * Send a sign change. This fakes a sign change packet for a user at * a certain location. This will not actually change the world in any way. -@@ -916,7 +1115,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -941,7 +1140,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param lines the new text on the sign or null to clear it * @throws IllegalArgumentException if location is null * @throws IllegalArgumentException if lines is non-null and has a length less than 4 @@ -2631,7 +2631,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e public void sendSignChange(@NotNull Location loc, @Nullable String[] lines) throws IllegalArgumentException; /** -@@ -938,7 +1141,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -963,7 +1166,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException if location is null * @throws IllegalArgumentException if dyeColor is null * @throws IllegalArgumentException if lines is non-null and has a length less than 4 @@ -2643,7 +2643,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e public void sendSignChange(@NotNull Location loc, @Nullable String[] lines, @NotNull DyeColor dyeColor) throws IllegalArgumentException; /** -@@ -961,7 +1168,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -986,7 +1193,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException if location is null * @throws IllegalArgumentException if dyeColor is null * @throws IllegalArgumentException if lines is non-null and has a length less than 4 @@ -2655,7 +2655,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e public void sendSignChange(@NotNull Location loc, @Nullable String[] lines, @NotNull DyeColor dyeColor, boolean hasGlowingText) throws IllegalArgumentException; /** -@@ -1436,7 +1647,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1461,7 +1672,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException Thrown if the URL is null. * @throws IllegalArgumentException Thrown if the URL is too long. * @deprecated Minecraft no longer uses textures packs. Instead you @@ -2664,7 +2664,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e */ @Deprecated public void setTexturePack(@NotNull String url); -@@ -1472,7 +1683,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1497,7 +1708,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException Thrown if the URL is null. * @throws IllegalArgumentException Thrown if the URL is too long. The * length restriction is an implementation specific arbitrary value. @@ -2674,7 +2674,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e public void setResourcePack(@NotNull String url); /** -@@ -1504,6 +1717,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1529,6 +1742,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * pack correctly. * * @@ -2682,7 +2682,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e * @param url The URL from which the client will download the resource * pack. The string must contain only US-ASCII characters and should * be encoded as per RFC 1738. -@@ -1516,6 +1730,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1541,6 +1755,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException Thrown if the hash is not 20 bytes * long. */ @@ -2690,7 +2690,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e public void setResourcePack(@NotNull String url, @Nullable byte[] hash); /** -@@ -1540,12 +1755,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1565,12 +1780,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * {@link PlayerResourcePackStatusEvent} to figure out whether or not * the player loaded the pack! *
  • To remove a resource pack you can use @@ -2705,7 +2705,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e * @param url The URL from which the client will download the resource * pack. The string must contain only US-ASCII characters and should * be encoded as per RFC 1738. -@@ -1559,8 +1775,10 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1584,8 +1800,10 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException Thrown if the hash is not 20 bytes * long. */ @@ -2716,7 +2716,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e /** * Request that the player's client download and switch resource packs. *

    -@@ -1583,7 +1801,54 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1608,7 +1826,54 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * {@link PlayerResourcePackStatusEvent} to figure out whether or not * the player loaded the pack! *

  • To remove a resource pack you can use @@ -2772,7 +2772,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e *
  • The request is sent with empty string as the hash when the hash is * not provided. This might result in newer versions not loading the * pack correctly. -@@ -1602,7 +1867,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1627,7 +1892,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * length restriction is an implementation specific arbitrary value. * @throws IllegalArgumentException Thrown if the hash is not 20 bytes * long. @@ -2782,7 +2782,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e public void setResourcePack(@NotNull String url, @Nullable byte[] hash, boolean force); /** -@@ -1627,7 +1894,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1652,7 +1919,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * {@link PlayerResourcePackStatusEvent} to figure out whether or not * the player loaded the pack! *
  • To remove a resource pack you can use @@ -2791,7 +2791,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e *
  • The request is sent with empty string as the hash when the hash is * not provided. This might result in newer versions not loading the * pack correctly. -@@ -1647,9 +1914,61 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1672,9 +1939,61 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * length restriction is an implementation specific arbitrary value. * @throws IllegalArgumentException Thrown if the hash is not 20 bytes * long. @@ -2853,7 +2853,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e /** * Request that the player's client download and switch resource packs. *

    -@@ -1672,7 +1991,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1697,7 +2016,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * {@link PlayerResourcePackStatusEvent} to figure out whether or not * the player loaded the pack! *

  • To remove a resource pack you can use @@ -2862,7 +2862,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e *
  • The request is sent with empty string as the hash when the hash is * not provided. This might result in newer versions not loading the * pack correctly. -@@ -1693,9 +2012,60 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1718,9 +2037,60 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * length restriction is an implementation specific arbitrary value. * @throws IllegalArgumentException Thrown if the hash is not 20 bytes * long. @@ -2923,7 +2923,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e /** * Request that the player's client download and include another resource pack. *

    -@@ -1748,12 +2118,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1773,12 +2143,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param id the id of the resource pack. * @throws IllegalArgumentException If the ID is null. @@ -2938,7 +2938,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e */ public void removeResourcePacks(); -@@ -1891,7 +2263,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1916,7 +2288,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param title Title text * @param subtitle Subtitle text @@ -2947,7 +2947,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e */ @Deprecated public void sendTitle(@Nullable String title, @Nullable String subtitle); -@@ -1910,7 +2282,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1935,7 +2307,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param fadeIn time in ticks for titles to fade in. Defaults to 10. * @param stay time in ticks for titles to stay. Defaults to 70. * @param fadeOut time in ticks for titles to fade out. Defaults to 20. @@ -2957,7 +2957,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e public void sendTitle(@Nullable String title, @Nullable String subtitle, int fadeIn, int stay, int fadeOut); /** -@@ -2185,6 +2559,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2210,6 +2584,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public int getClientViewDistance(); @@ -2972,7 +2972,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e /** * Gets the player's estimated ping in milliseconds. * -@@ -2210,8 +2592,10 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2235,8 +2617,10 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * they wish. * * @return the player's locale @@ -2983,7 +2983,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e public String getLocale(); /** -@@ -2263,6 +2647,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2288,6 +2672,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public boolean isAllowingServerListings(); @@ -2998,7 +2998,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e // Spigot start public class Spigot extends Entity.Spigot { -@@ -2294,11 +2686,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2319,11 +2711,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM throw new UnsupportedOperationException("Not supported yet."); } @@ -3012,7 +3012,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e @Override public void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent... components) { throw new UnsupportedOperationException("Not supported yet."); -@@ -2309,7 +2703,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2334,7 +2728,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param position the screen position * @param component the components to send @@ -3022,7 +3022,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e public void sendMessage(@NotNull net.md_5.bungee.api.ChatMessageType position, @NotNull net.md_5.bungee.api.chat.BaseComponent component) { throw new UnsupportedOperationException("Not supported yet."); } -@@ -2319,7 +2715,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2344,7 +2740,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param position the screen position * @param components the components to send @@ -3032,7 +3032,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e public void sendMessage(@NotNull net.md_5.bungee.api.ChatMessageType position, @NotNull net.md_5.bungee.api.chat.BaseComponent... components) { throw new UnsupportedOperationException("Not supported yet."); } -@@ -2330,7 +2728,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2355,7 +2753,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param position the screen position * @param sender the sender of the message * @param component the components to send @@ -3042,7 +3042,7 @@ index 6ab82664092c6cedb2ef31b24445ba481fc785d8..0f562dcca9bb0ffc3a3fcb1c2221306e public void sendMessage(@NotNull net.md_5.bungee.api.ChatMessageType position, @Nullable java.util.UUID sender, @NotNull net.md_5.bungee.api.chat.BaseComponent component) { throw new UnsupportedOperationException("Not supported yet."); } -@@ -2341,7 +2741,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2366,7 +2766,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param position the screen position * @param sender the sender of the message * @param components the components to send diff --git a/patches/api/0011-Timings-v2.patch b/patches/api/0011-Timings-v2.patch index 3e430feef495..36aae5482290 100644 --- a/patches/api/0011-Timings-v2.patch +++ b/patches/api/0011-Timings-v2.patch @@ -3484,10 +3484,10 @@ index 516d7fc7812aac343782861d0d567f54aa578c2a..00000000000000000000000000000000 - // Spigot end -} diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 0f562dcca9bb0ffc3a3fcb1c2221306ec156c71b..9e072342eb5af366a4f860db71e15a63b29038aa 100644 +index 84befa1e5123038b80e0734622a5174634f5a982..22de066aef71ad2cf135d5b6f5d6f224de5fcd2d 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -2746,7 +2746,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2771,7 +2771,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM @Deprecated // Paper public void sendMessage(@NotNull net.md_5.bungee.api.ChatMessageType position, @Nullable java.util.UUID sender, @NotNull net.md_5.bungee.api.chat.BaseComponent... components) { throw new UnsupportedOperationException("Not supported yet."); diff --git a/patches/api/0013-Player-affects-spawning-API.patch b/patches/api/0013-Player-affects-spawning-API.patch index cf908129f87e..ebafa9cc7090 100644 --- a/patches/api/0013-Player-affects-spawning-API.patch +++ b/patches/api/0013-Player-affects-spawning-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Player affects spawning API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 9e072342eb5af366a4f860db71e15a63b29038aa..fbcf2a18456b6e700003019965354ce7cbe2fd0d 100644 +index 22de066aef71ad2cf135d5b6f5d6f224de5fcd2d..1c25725a2abb36a81b1821102daee447c7170197 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -2598,6 +2598,22 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2623,6 +2623,22 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM @Deprecated // Paper public String getLocale(); diff --git a/patches/api/0017-Add-view-distance-API.patch b/patches/api/0017-Add-view-distance-API.patch index 493c2f67936f..abf7dbde0afb 100644 --- a/patches/api/0017-Add-view-distance-API.patch +++ b/patches/api/0017-Add-view-distance-API.patch @@ -79,10 +79,10 @@ index 9732929b666b0a5e1a2a41c8e8794cc4f2535e41..0a3a66e04f8785874f10a76603bff464 * Gets all generated structures that intersect the chunk at the given * coordinates.
    diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index fbcf2a18456b6e700003019965354ce7cbe2fd0d..18075f35f62b94c24673211be1d287f57f88c0dc 100644 +index 1c25725a2abb36a81b1821102daee447c7170197..28e821ca1ec8ec3eba160ef2ed06ab1bb7387cae 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -2612,6 +2612,82 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2637,6 +2637,82 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param affects Whether the player can affect mob spawning */ public void setAffectsSpawning(boolean affects); diff --git a/patches/api/0020-Graduate-bungeecord-chat-API-from-spigot-subclasses.patch b/patches/api/0020-Graduate-bungeecord-chat-API-from-spigot-subclasses.patch index 2e693b71afc8..ab7a5818455e 100644 --- a/patches/api/0020-Graduate-bungeecord-chat-API-from-spigot-subclasses.patch +++ b/patches/api/0020-Graduate-bungeecord-chat-API-from-spigot-subclasses.patch @@ -76,10 +76,10 @@ index d78481bf17818415524f14417caf86d5684b2235..067eb3a5f5676f3b1b3f49a65df9c405 * Gets the name of the update folder. The update folder is used to safely * update plugins at the right moment on a plugin load. diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 18075f35f62b94c24673211be1d287f57f88c0dc..9674e920bda2d1c6428081ae7f18cade58b7900d 100644 +index 28e821ca1ec8ec3eba160ef2ed06ab1bb7387cae..fefd6b8a4171c9ec3d2a09d1accb9f37d66aa5b9 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1229,6 +1229,42 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1254,6 +1254,42 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public void sendMap(@NotNull MapView map); diff --git a/patches/api/0024-Player-Tab-List-and-Title-APIs.patch b/patches/api/0024-Player-Tab-List-and-Title-APIs.patch index 197c04e321f4..888137a8b5c6 100644 --- a/patches/api/0024-Player-Tab-List-and-Title-APIs.patch +++ b/patches/api/0024-Player-Tab-List-and-Title-APIs.patch @@ -432,10 +432,10 @@ index 0000000000000000000000000000000000000000..20a028450667edf102b59b6b50ac6e89 + } +} diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 9674e920bda2d1c6428081ae7f18cade58b7900d..ae5ea0513a0688e229a0c49dadf344bfd6704288 100644 +index fefd6b8a4171c9ec3d2a09d1accb9f37d66aa5b9..2685a6fcda7afa23d3f5067af1d5d2fc89bdb0e6 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1263,6 +1263,131 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1288,6 +1288,131 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM public default void sendMessage(net.md_5.bungee.api.ChatMessageType position, net.md_5.bungee.api.chat.BaseComponent... components) { spigot().sendMessage(position, components); } diff --git a/patches/api/0026-Complete-resource-pack-API.patch b/patches/api/0026-Complete-resource-pack-API.patch index 339876b64013..ab4274c827a9 100644 --- a/patches/api/0026-Complete-resource-pack-API.patch +++ b/patches/api/0026-Complete-resource-pack-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Complete resource pack API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index ae5ea0513a0688e229a0c49dadf344bfd6704288..a00afb924b6938e6abb0e1445da0b46415ff0f88 100644 +index 2685a6fcda7afa23d3f5067af1d5d2fc89bdb0e6..47a0d09b433024cd464737eced8a31f995b1ffaf 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -2227,6 +2227,180 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2252,6 +2252,180 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM void setResourcePack(@NotNull UUID uuid, @NotNull String url, byte @Nullable [] hash, net.kyori.adventure.text.@Nullable Component prompt, boolean force); // Paper end diff --git a/patches/api/0045-Add-String-based-Action-Bar-API.patch b/patches/api/0045-Add-String-based-Action-Bar-API.patch index d57aae4afec2..c2b98dd46f46 100644 --- a/patches/api/0045-Add-String-based-Action-Bar-API.patch +++ b/patches/api/0045-Add-String-based-Action-Bar-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add String based Action Bar API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index a00afb924b6938e6abb0e1445da0b46415ff0f88..67e2d3e70c13754371591daf5bb11304aeb9fa87 100644 +index 47a0d09b433024cd464737eced8a31f995b1ffaf..9513ce004101bd1bef90ca4a558f6b7c28d97adb 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1230,6 +1230,39 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1255,6 +1255,39 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM public void sendMap(@NotNull MapView map); // Paper start @@ -48,7 +48,7 @@ index a00afb924b6938e6abb0e1445da0b46415ff0f88..67e2d3e70c13754371591daf5bb11304 /** * Sends the component to the player * -@@ -1257,9 +1290,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1282,9 +1315,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM /** * Sends an array of components as a single message to the specified screen position of this player * diff --git a/patches/api/0053-Fix-upstream-javadocs.patch b/patches/api/0053-Fix-upstream-javadocs.patch index 9f7110425a07..151552e5d6fc 100644 --- a/patches/api/0053-Fix-upstream-javadocs.patch +++ b/patches/api/0053-Fix-upstream-javadocs.patch @@ -500,10 +500,10 @@ index ae9eaaa8e38e1d9dfc459926c7fc51ddb89de84a..b2ec535bb1b0ce0c114ddd7638b90218 @Override public int getConversionTime(); diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 67e2d3e70c13754371591daf5bb11304aeb9fa87..68f36afc6124f07d0e4bd75569252f3ebbb319a0 100644 +index 9513ce004101bd1bef90ca4a558f6b7c28d97adb..c8ba70f787a3460c1f9faaeaab086e9e43ecaf6f 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -491,15 +491,15 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -492,15 +492,15 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM /** * Saves the players current location, health, inventory, motion, and @@ -523,7 +523,7 @@ index 67e2d3e70c13754371591daf5bb11304aeb9fa87..68f36afc6124f07d0e4bd75569252f3e *

    * Note: This will overwrite the players current inventory, health, * motion, etc, with the state from the saved dat file. -@@ -836,7 +836,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -861,7 +861,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM /** * Plays an effect to just this player. * @@ -532,7 +532,7 @@ index 67e2d3e70c13754371591daf5bb11304aeb9fa87..68f36afc6124f07d0e4bd75569252f3e * @param loc the location to play the effect at * @param effect the {@link Effect} * @param data a data bit needed for some effects -@@ -1247,7 +1247,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1272,7 +1272,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * Use supplied alternative character to the section symbol to represent legacy color codes. * @@ -541,7 +541,7 @@ index 67e2d3e70c13754371591daf5bb11304aeb9fa87..68f36afc6124f07d0e4bd75569252f3e * @param message The message to send * @deprecated use {@link #sendActionBar(net.kyori.adventure.text.Component)} */ -@@ -1720,7 +1720,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1745,7 +1745,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM /** * Allows this player to see a player that was previously hidden. If @@ -550,7 +550,7 @@ index 67e2d3e70c13754371591daf5bb11304aeb9fa87..68f36afc6124f07d0e4bd75569252f3e * remain hidden until the other plugin calls this method too. * * @param plugin Plugin that wants to show the player -@@ -1747,7 +1747,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1772,7 +1772,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM /** * Allows this player to see an entity that was previously hidden. If @@ -559,7 +559,7 @@ index 67e2d3e70c13754371591daf5bb11304aeb9fa87..68f36afc6124f07d0e4bd75569252f3e * remain hidden until the other plugin calls this method too. * * @param plugin Plugin that wants to show the entity -@@ -1830,9 +1830,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1855,9 +1855,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * case this method will have no affect on them. Use the * {@link PlayerResourcePackStatusEvent} to figure out whether or not * the player loaded the pack! @@ -569,7 +569,7 @@ index 67e2d3e70c13754371591daf5bb11304aeb9fa87..68f36afc6124f07d0e4bd75569252f3e *

  • The request is send with "null" as the hash. This might result * in newer versions not loading the pack correctly. * -@@ -1866,9 +1863,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1891,9 +1888,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * case this method will have no affect on them. Use the * {@link PlayerResourcePackStatusEvent} to figure out whether or not * the player loaded the pack! @@ -579,7 +579,7 @@ index 67e2d3e70c13754371591daf5bb11304aeb9fa87..68f36afc6124f07d0e4bd75569252f3e *
  • The request is send with empty string as the hash. This might result * in newer versions not loading the pack correctly. * -@@ -1905,9 +1899,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1930,9 +1924,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * case this method will have no affect on them. Use the * {@link PlayerResourcePackStatusEvent} to figure out whether or not * the player loaded the pack! diff --git a/patches/api/0074-Expose-client-protocol-version-and-virtual-host.patch b/patches/api/0074-Expose-client-protocol-version-and-virtual-host.patch index 5f15d77dd217..383d46bfff14 100644 --- a/patches/api/0074-Expose-client-protocol-version-and-virtual-host.patch +++ b/patches/api/0074-Expose-client-protocol-version-and-virtual-host.patch @@ -55,10 +55,10 @@ index 0000000000000000000000000000000000000000..c84ce3fc874eea3d8f0b1cf5273996d9 + +} diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 68f36afc6124f07d0e4bd75569252f3ebbb319a0..a605425b79131f885051d91bb57a30a695e0ce46 100644 +index c8ba70f787a3460c1f9faaeaab086e9e43ecaf6f..1a6ddc4228ed4c26235cfe56b1e0a102c7aa320f 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -57,7 +57,7 @@ import org.jetbrains.annotations.Nullable; +@@ -58,7 +58,7 @@ import org.jetbrains.annotations.Nullable; /** * Represents a player, connected or not */ diff --git a/patches/api/0078-Ability-to-apply-mending-to-XP-API.patch b/patches/api/0078-Ability-to-apply-mending-to-XP-API.patch index 7d05cddb6591..b4e68511a402 100644 --- a/patches/api/0078-Ability-to-apply-mending-to-XP-API.patch +++ b/patches/api/0078-Ability-to-apply-mending-to-XP-API.patch @@ -10,10 +10,10 @@ 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/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index a605425b79131f885051d91bb57a30a695e0ce46..f93ede618b3098faf3ba6e63bfbcea6e36ff3146 100644 +index 1a6ddc4228ed4c26235cfe56b1e0a102c7aa320f..0d92eac00ba883d696d45340feb808988be05c16 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1563,6 +1563,15 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1588,6 +1588,15 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public void resetPlayerWeather(); @@ -29,7 +29,7 @@ index a605425b79131f885051d91bb57a30a695e0ce46..f93ede618b3098faf3ba6e63bfbcea6e /** * Gets the player's cooldown between picking up experience orbs. * -@@ -1588,8 +1597,20 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1613,8 +1622,20 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * Gives the player the amount of experience specified. * * @param amount Exp amount to give diff --git a/patches/api/0089-Player.setPlayerProfile-API.patch b/patches/api/0089-Player.setPlayerProfile-API.patch index 1af7898bdc7a..fb9225d8d543 100644 --- a/patches/api/0089-Player.setPlayerProfile-API.patch +++ b/patches/api/0089-Player.setPlayerProfile-API.patch @@ -93,10 +93,10 @@ index 7a1b80e8d02f23c5d246c3032e5ced909f10bd41..01c052d90bbdad3fc374eb9c8e0a5133 /** diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index f93ede618b3098faf3ba6e63bfbcea6e36ff3146..9f16ea635a27563a8568d10365f1b284cc93b15a 100644 +index 0d92eac00ba883d696d45340feb808988be05c16..357e12c91a710751dc5bf3138362c10e5a26db1e 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3129,6 +3129,26 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3154,6 +3154,26 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM } // Paper end diff --git a/patches/api/0092-Add-openSign-method-to-HumanEntity.patch b/patches/api/0092-Add-openSign-method-to-HumanEntity.patch index bef8b5e42da3..90ee598a25f0 100644 --- a/patches/api/0092-Add-openSign-method-to-HumanEntity.patch +++ b/patches/api/0092-Add-openSign-method-to-HumanEntity.patch @@ -36,10 +36,10 @@ index 08cef0d9fc27d0c09472cfe7091330d95956d9eb..00b803cee96fef8830e5db8722c98ff1 /** * Make the entity drop the item in their hand. diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 9f16ea635a27563a8568d10365f1b284cc93b15a..e1516a8e88aab4bb43a77b773d6682070e8a9b8a 100644 +index 357e12c91a710751dc5bf3138362c10e5a26db1e..ecc0bbf986b065620910f3592115c0f45e863b98 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3090,10 +3090,12 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3115,10 +3115,12 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM /** * Open a Sign for editing by the Player. * diff --git a/patches/api/0093-Add-Ban-Methods-to-Player-Objects.patch b/patches/api/0093-Add-Ban-Methods-to-Player-Objects.patch index b30b80d2f07d..62e9847bb6bd 100644 --- a/patches/api/0093-Add-Ban-Methods-to-Player-Objects.patch +++ b/patches/api/0093-Add-Ban-Methods-to-Player-Objects.patch @@ -86,10 +86,10 @@ index abbf3d6f11350ab2dd47a277771d9f46221036bd..a9d63b1630b05b86a0396355fcfee261 /** * Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index e1516a8e88aab4bb43a77b773d6682070e8a9b8a..4ef6591ce8d85abd15ccefba57ce66091f385e1a 100644 +index ecc0bbf986b065620910f3592115c0f45e863b98..354beb974012fa83fdac0c9d28166016ace93070 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1230,6 +1230,186 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1255,6 +1255,186 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM public void sendMap(@NotNull MapView map); // Paper start diff --git a/patches/api/0141-Expose-attack-cooldown-methods-for-Player.patch b/patches/api/0141-Expose-attack-cooldown-methods-for-Player.patch index baf7c6305e21..d8e3d59112e0 100644 --- a/patches/api/0141-Expose-attack-cooldown-methods-for-Player.patch +++ b/patches/api/0141-Expose-attack-cooldown-methods-for-Player.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Expose attack cooldown methods for Player diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 4ef6591ce8d85abd15ccefba57ce66091f385e1a..4ee5dd69ba1ab743662f1069eabdb7622f53bc9d 100644 +index 354beb974012fa83fdac0c9d28166016ace93070..76ffe308ae2e3bc36c0e7e1a98adc4b307f4211f 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3331,6 +3331,28 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3356,6 +3356,28 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM void setPlayerProfile(com.destroystokyo.paper.profile.@NotNull PlayerProfile profile); // Paper end - Player Profile API diff --git a/patches/api/0166-Fix-Spigot-annotation-mistakes.patch b/patches/api/0166-Fix-Spigot-annotation-mistakes.patch index 9ec07a782b04..69952b703431 100644 --- a/patches/api/0166-Fix-Spigot-annotation-mistakes.patch +++ b/patches/api/0166-Fix-Spigot-annotation-mistakes.patch @@ -970,10 +970,10 @@ index 60522888bc320ba0a55655532e19185fac816bd1..4aa07d4edb2c81d0ae7999b30ad53ff8 /** diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 4ee5dd69ba1ab743662f1069eabdb7622f53bc9d..2435b7d14b52bbd47c4ddb7bdd6849acf42bffef 100644 +index 76ffe308ae2e3bc36c0e7e1a98adc4b307f4211f..80e894e3d625cde14bfe881d2c367b43a4882cfd 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1655,11 +1655,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1680,11 +1680,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM /** * Forces an update of the player's entire inventory. diff --git a/patches/api/0183-Add-Player-Client-Options-API.patch b/patches/api/0183-Add-Player-Client-Options-API.patch index 5e7bc03bd3e7..44f597e1444c 100644 --- a/patches/api/0183-Add-Player-Client-Options-API.patch +++ b/patches/api/0183-Add-Player-Client-Options-API.patch @@ -224,10 +224,10 @@ index 0000000000000000000000000000000000000000..6cf6aa876278d0d3e75148608951fc58 + } +} diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 2435b7d14b52bbd47c4ddb7bdd6849acf42bffef..f4b1ed868a1fc8aa22fd07c3bf3aef886b8c8679 100644 +index 80e894e3d625cde14bfe881d2c367b43a4882cfd..2d3c8febbbab959433101fb9dfc1e0ff9deca192 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3350,6 +3350,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3375,6 +3375,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM void resetCooldown(); // Paper end - attack cooldown API diff --git a/patches/api/0198-Brand-support.patch b/patches/api/0198-Brand-support.patch index 9c23fa64a05e..42971e5ae7d0 100644 --- a/patches/api/0198-Brand-support.patch +++ b/patches/api/0198-Brand-support.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Brand support diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index f4b1ed868a1fc8aa22fd07c3bf3aef886b8c8679..38c61979c20768ad7790c2c7d6463c9d10fb3611 100644 +index 2d3c8febbbab959433101fb9dfc1e0ff9deca192..54d33be1297a6a4646635ca09cae1f0a2d3fb7fa 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3463,6 +3463,16 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3488,6 +3488,16 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM // Paper end } diff --git a/patches/api/0208-Player-elytra-boost-API.patch b/patches/api/0208-Player-elytra-boost-API.patch index 9dcab2869b8e..c5f8ae83d794 100644 --- a/patches/api/0208-Player-elytra-boost-API.patch +++ b/patches/api/0208-Player-elytra-boost-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Player elytra boost API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 38c61979c20768ad7790c2c7d6463c9d10fb3611..756240eef598bdf44507ab003cf1141ac0122292 100644 +index 54d33be1297a6a4646635ca09cae1f0a2d3fb7fa..d2b74718998761a3f1a1a07547eb49661d5431df 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3357,6 +3357,25 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3382,6 +3382,25 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM @NotNull T getClientOption(com.destroystokyo.paper.@NotNull ClientOption option); // Paper end - client option API diff --git a/patches/api/0235-Add-sendOpLevel-API.patch b/patches/api/0235-Add-sendOpLevel-API.patch index f6506212bcac..c64ed185a2b7 100644 --- a/patches/api/0235-Add-sendOpLevel-API.patch +++ b/patches/api/0235-Add-sendOpLevel-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add sendOpLevel API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 756240eef598bdf44507ab003cf1141ac0122292..7e2f2904cc6da994aaf8764399a836c5586cbd70 100644 +index d2b74718998761a3f1a1a07547eb49661d5431df..a03ac5f230521cde2278222de8157f78a152f6a6 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3376,6 +3376,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3401,6 +3401,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM } // Paper end - elytra boost API diff --git a/patches/api/0280-Add-PlayerKickEvent-causes.patch b/patches/api/0280-Add-PlayerKickEvent-causes.patch index 69ccfc773574..5520442f0753 100644 --- a/patches/api/0280-Add-PlayerKickEvent-causes.patch +++ b/patches/api/0280-Add-PlayerKickEvent-causes.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerKickEvent causes diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 7e2f2904cc6da994aaf8764399a836c5586cbd70..b39e8c1cdeee3d554839a055ccbae725aa3d66f5 100644 +index a03ac5f230521cde2278222de8157f78a152f6a6..ff5a0d2b6a070c85545b00cf41c51b8d9cce8d0d 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -334,6 +334,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -335,6 +335,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param message kick message */ void kick(final net.kyori.adventure.text.@Nullable Component message); diff --git a/patches/api/0325-Multi-Block-Change-API.patch b/patches/api/0325-Multi-Block-Change-API.patch index a53a8e108b34..f7cb304e6ec2 100644 --- a/patches/api/0325-Multi-Block-Change-API.patch +++ b/patches/api/0325-Multi-Block-Change-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Multi Block Change API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index b39e8c1cdeee3d554839a055ccbae725aa3d66f5..d61adb687aedb987e33d66978ef4b77ea1b0356f 100644 +index ff5a0d2b6a070c85545b00cf41c51b8d9cce8d0d..99bad852128f499f8f71552399c49f373d51cf9c 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -952,6 +952,29 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -977,6 +977,29 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public void sendBlockDamage(@NotNull Location loc, float progress); diff --git a/patches/api/0353-More-Teleport-API.patch b/patches/api/0353-More-Teleport-API.patch index 48ac16d6f37b..7357803c9787 100644 --- a/patches/api/0353-More-Teleport-API.patch +++ b/patches/api/0353-More-Teleport-API.patch @@ -158,10 +158,10 @@ index f51f3f04ba9efe15f68620c5531b502710078b6e..8bada7f7f0200103edc415ad003132d9 * Teleports this entity to the given location. If this entity is riding a * vehicle, it will be dismounted prior to teleportation. diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index d61adb687aedb987e33d66978ef4b77ea1b0356f..503a2ecd4ffca92ee529e3e15136c368d75692c0 100644 +index 99bad852128f499f8f71552399c49f373d51cf9c..4371ac4683604919782f6268756dff4f05695a40 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3536,6 +3536,45 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3561,6 +3561,45 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM String getClientBrandName(); // Paper end diff --git a/patches/api/0355-Custom-Chat-Completion-Suggestions-API.patch b/patches/api/0355-Custom-Chat-Completion-Suggestions-API.patch index d36522af5422..5c217eaf6bb0 100644 --- a/patches/api/0355-Custom-Chat-Completion-Suggestions-API.patch +++ b/patches/api/0355-Custom-Chat-Completion-Suggestions-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Custom Chat Completion Suggestions API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 503a2ecd4ffca92ee529e3e15136c368d75692c0..675053adf68df2c77ef128f2aec72e22f0f48adf 100644 +index 4371ac4683604919782f6268756dff4f05695a40..761e7982d022eddd1adee6f2536fa93c4a9f67ea 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3420,6 +3420,31 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3445,6 +3445,31 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM void sendOpLevel(byte level); // Paper end - sendOpLevel API diff --git a/patches/api/0364-Elder-Guardian-appearance-API.patch b/patches/api/0364-Elder-Guardian-appearance-API.patch index 8a3655450e14..5adec1def758 100644 --- a/patches/api/0364-Elder-Guardian-appearance-API.patch +++ b/patches/api/0364-Elder-Guardian-appearance-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Elder Guardian appearance API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 675053adf68df2c77ef128f2aec72e22f0f48adf..9c9077c781b8f11d3a41d479ff9415fe83c70e81 100644 +index 761e7982d022eddd1adee6f2536fa93c4a9f67ea..404f448cf1488a9fa5aeebeeba5d51e9a5427bc7 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3600,6 +3600,24 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3625,6 +3625,24 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM void lookAt(@NotNull org.bukkit.entity.Entity entity, @NotNull io.papermc.paper.entity.LookAnchor playerAnchor, @NotNull io.papermc.paper.entity.LookAnchor entityAnchor); // Paper end - Teleport API diff --git a/patches/api/0371-Add-Player-Warden-Warning-API.patch b/patches/api/0371-Add-Player-Warden-Warning-API.patch index e766dc65f7f6..81dbe64546dd 100644 --- a/patches/api/0371-Add-Player-Warden-Warning-API.patch +++ b/patches/api/0371-Add-Player-Warden-Warning-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Player Warden Warning API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 9c9077c781b8f11d3a41d479ff9415fe83c70e81..41a01924b4ffda5e321338ef9831c12ba5ee751a 100644 +index 404f448cf1488a9fa5aeebeeba5d51e9a5427bc7..17d69b6808e581dd69f93d7cb646ca43608b40df 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3616,6 +3616,59 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3641,6 +3641,59 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param silent whether sound should be silenced */ void showElderGuardian(boolean silent); diff --git a/patches/api/0381-Add-Sneaking-API-for-Entities.patch b/patches/api/0381-Add-Sneaking-API-for-Entities.patch index 29e6c9875000..ccee097cf06c 100644 --- a/patches/api/0381-Add-Sneaking-API-for-Entities.patch +++ b/patches/api/0381-Add-Sneaking-API-for-Entities.patch @@ -35,10 +35,10 @@ index 9f4498a955279b8b5c418609801fd09444a1efb5..6dcaf7e9bc9afb708ab569e82f27c878 * Get the category of spawn to which this entity belongs. * diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 41a01924b4ffda5e321338ef9831c12ba5ee751a..fb72464d86de30775e6c324bfd6a9491cc2bee2b 100644 +index 17d69b6808e581dd69f93d7cb646ca43608b40df..9faabe1dcfd69d8dfbefab98f23d8f0b6700e9b2 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -474,6 +474,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -475,6 +475,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @return true if player is in sneak mode */ @@ -46,7 +46,7 @@ index 41a01924b4ffda5e321338ef9831c12ba5ee751a..fb72464d86de30775e6c324bfd6a9491 public boolean isSneaking(); /** -@@ -481,6 +482,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -482,6 +483,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param sneak true if player should appear sneaking */ diff --git a/patches/api/0383-Flying-Fall-Damage-API.patch b/patches/api/0383-Flying-Fall-Damage-API.patch index c3b86a21d23a..f0e6b1e6caff 100644 --- a/patches/api/0383-Flying-Fall-Damage-API.patch +++ b/patches/api/0383-Flying-Fall-Damage-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Flying Fall Damage API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index fb72464d86de30775e6c324bfd6a9491cc2bee2b..d1301c8201c56602fbedcf5475650c5b7e600609 100644 +index 9faabe1dcfd69d8dfbefab98f23d8f0b6700e9b2..1f9e9beb9c36d8885e0c4f19e324f26521634ed3 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1923,6 +1923,23 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1948,6 +1948,23 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public void setAllowFlight(boolean flight); diff --git a/patches/api/0385-Win-Screen-API.patch b/patches/api/0385-Win-Screen-API.patch index c4ac3dae99b6..8911de9fcb5b 100644 --- a/patches/api/0385-Win-Screen-API.patch +++ b/patches/api/0385-Win-Screen-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Win Screen API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index d1301c8201c56602fbedcf5475650c5b7e600609..ee43ecd0bf4d12549323976a0e1c3b023a41333b 100644 +index 1f9e9beb9c36d8885e0c4f19e324f26521634ed3..dd4ce1d68962ec668db7c687c1e4764db52bc04f 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1262,6 +1262,47 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1287,6 +1287,47 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public void sendMap(@NotNull MapView map); diff --git a/patches/api/0398-Fix-BanList-API.patch b/patches/api/0398-Fix-BanList-API.patch index a5c5275a12e3..0d0a781306dd 100644 --- a/patches/api/0398-Fix-BanList-API.patch +++ b/patches/api/0398-Fix-BanList-API.patch @@ -130,10 +130,10 @@ index e805e629cede1c4c0674282c930cb67852718c3e..5248cf08ef83c7304dd76c42a2f646bb + // Paper end } diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index ee43ecd0bf4d12549323976a0e1c3b023a41333b..6103c945b351a9cf6a29b5ab4fa7adb4546097e2 100644 +index dd4ce1d68962ec668db7c687c1e4764db52bc04f..baf7ff3b23be8dd80d2e59299a6ec8f9ce1053df 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -358,7 +358,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -359,7 +359,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * (updated) previous ban */ @Nullable @@ -142,7 +142,7 @@ index ee43ecd0bf4d12549323976a0e1c3b023a41333b..6103c945b351a9cf6a29b5ab4fa7adb4 /** * Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will -@@ -374,7 +374,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -375,7 +375,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * (updated) previous ban */ @Nullable @@ -151,7 +151,7 @@ index ee43ecd0bf4d12549323976a0e1c3b023a41333b..6103c945b351a9cf6a29b5ab4fa7adb4 /** * Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will -@@ -390,7 +390,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -391,7 +391,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * (updated) previous ban */ @Nullable diff --git a/patches/api/0406-Add-Listing-API-for-Player.patch b/patches/api/0406-Add-Listing-API-for-Player.patch index acf4f19c19da..3135969fe0dd 100644 --- a/patches/api/0406-Add-Listing-API-for-Player.patch +++ b/patches/api/0406-Add-Listing-API-for-Player.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Listing API for Player diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 6103c945b351a9cf6a29b5ab4fa7adb4546097e2..38e296eab48b5408255fdb13d6a7b488471395d2 100644 +index baf7ff3b23be8dd80d2e59299a6ec8f9ce1053df..e128750b1175ab8bbe9b23fdd931665262c8d75e 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -2053,6 +2053,32 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2078,6 +2078,32 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public boolean canSee(@NotNull Entity entity); diff --git a/patches/api/0420-Add-player-idle-duration-API.patch b/patches/api/0420-Add-player-idle-duration-API.patch index b11b57b66070..ac250c0760d1 100644 --- a/patches/api/0420-Add-player-idle-duration-API.patch +++ b/patches/api/0420-Add-player-idle-duration-API.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add player idle duration API Implements API for getting and resetting a player's idle duration. diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 38e296eab48b5408255fdb13d6a7b488471395d2..598a1df25f12e2175865bf98dae030b33f78cf7c 100644 +index e128750b1175ab8bbe9b23fdd931665262c8d75e..4297a893799fe39b80029b97f6b5581d543afa8a 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3757,6 +3757,29 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3782,6 +3782,29 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM void increaseWardenWarningLevel(); // Paper end diff --git a/patches/api/0428-Experimental-annotations-change.patch b/patches/api/0428-Experimental-annotations-change.patch index e00991155315..9c079b178f05 100644 --- a/patches/api/0428-Experimental-annotations-change.patch +++ b/patches/api/0428-Experimental-annotations-change.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Experimental annotations change diff --git a/src/main/java/org/bukkit/FeatureFlag.java b/src/main/java/org/bukkit/FeatureFlag.java -index 710f8e6242eab7b638e4f42e4e9790007f4c67b7..82f9ba32256bfc1125ee970a7fed0895fe08f145 100644 +index a96600443a0997c3a696a637422ab66ee1884fb0..20eb27ee041f77f295eb271f878c524ce5592251 100644 --- a/src/main/java/org/bukkit/FeatureFlag.java +++ b/src/main/java/org/bukkit/FeatureFlag.java @@ -29,6 +29,7 @@ public interface FeatureFlag extends Keyed { diff --git a/patches/api/0431-Add-experience-points-API.patch b/patches/api/0431-Add-experience-points-API.patch index 568b3a2494c7..558188330155 100644 --- a/patches/api/0431-Add-experience-points-API.patch +++ b/patches/api/0431-Add-experience-points-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add experience points API diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 598a1df25f12e2175865bf98dae030b33f78cf7c..f7b9cf1f2b90feb954e4d9b03b3a12abe7864a12 100644 +index 4297a893799fe39b80029b97f6b5581d543afa8a..b3b6cdf5491397e0e802ac91f5805d560ed5d88a 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1922,6 +1922,45 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1947,6 +1947,45 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param exp New total experience points */ public void setTotalExperience(int exp); diff --git a/patches/api/0454-API-for-checking-sent-chunks.patch b/patches/api/0454-API-for-checking-sent-chunks.patch index bca113f6abfa..0c353a8070e7 100644 --- a/patches/api/0454-API-for-checking-sent-chunks.patch +++ b/patches/api/0454-API-for-checking-sent-chunks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] API for checking sent chunks diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index f7b9cf1f2b90feb954e4d9b03b3a12abe7864a12..fc16c3df002ca097d9f815c04687e115c911304f 100644 +index b3b6cdf5491397e0e802ac91f5805d560ed5d88a..20db14b3075d70b34eab16ca6332a2e674b34e75 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3819,6 +3819,47 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3844,6 +3844,47 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM void resetIdleDuration(); // Paper end diff --git a/patches/api/0463-Added-API-to-get-player-ha-proxy-address.patch b/patches/api/0463-Added-API-to-get-player-ha-proxy-address.patch index 08d7bec7038a..79b18047969a 100644 --- a/patches/api/0463-Added-API-to-get-player-ha-proxy-address.patch +++ b/patches/api/0463-Added-API-to-get-player-ha-proxy-address.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Added API to get player ha proxy address diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index fc16c3df002ca097d9f815c04687e115c911304f..c8532a25d64217bcfddf075fd09e255aa9a769e7 100644 +index 20db14b3075d70b34eab16ca6332a2e674b34e75..82e92579f899ab3b86c748ba01860262b8ffa17f 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -266,6 +266,16 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -267,6 +267,16 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM @Nullable public InetSocketAddress getAddress(); diff --git a/patches/api/0485-Add-FeatureFlag-API.patch b/patches/api/0485-Add-FeatureFlag-API.patch index ccff2872435a..9afc6440146f 100644 --- a/patches/api/0485-Add-FeatureFlag-API.patch +++ b/patches/api/0485-Add-FeatureFlag-API.patch @@ -104,7 +104,7 @@ index 0000000000000000000000000000000000000000..0955699df65ccbb8711cfa48f0b34d5a + @Unmodifiable Set getFeatureFlags(); +} diff --git a/src/main/java/org/bukkit/FeatureFlag.java b/src/main/java/org/bukkit/FeatureFlag.java -index 82f9ba32256bfc1125ee970a7fed0895fe08f145..163b73204f3c94c1a234eb86cc73bd92858bc5e4 100644 +index 20eb27ee041f77f295eb271f878c524ce5592251..0acea3e8d639c252b44cd5da5e3584aa6e6c9b5c 100644 --- a/src/main/java/org/bukkit/FeatureFlag.java +++ b/src/main/java/org/bukkit/FeatureFlag.java @@ -1,17 +1,24 @@ @@ -137,7 +137,7 @@ index 82f9ba32256bfc1125ee970a7fed0895fe08f145..163b73204f3c94c1a234eb86cc73bd92 + FeatureFlag VANILLA = create("vanilla"); /** - * AVAILABLE BETWEEN VERSIONS: 1.19.3 - 1.21.2 + * AVAILABLE BETWEEN VERSIONS: 1.19.3 - 1.21.1 @@ -19,34 +26,43 @@ public interface FeatureFlag extends Keyed { * @deprecated not available since 1.21.2 */ diff --git a/patches/api/0490-Improve-entity-effect-API.patch b/patches/api/0490-Improve-entity-effect-API.patch index 014c98492877..48043155689c 100644 --- a/patches/api/0490-Improve-entity-effect-API.patch +++ b/patches/api/0490-Improve-entity-effect-API.patch @@ -118,10 +118,10 @@ index 725ef320f929d5e3d141c1ed3246d73a7d741f31..d0ae8a94db20281d3664d74718c65234 + // Paper end - broadcast hurt animation } diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index c8532a25d64217bcfddf075fd09e255aa9a769e7..81e287c8df1c10cf1e268f3bbd262926d60b70c0 100644 +index 82e92579f899ab3b86c748ba01860262b8ffa17f..95f0b3186e313c7fbd5c8531d52b82a69e525f94 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3874,4 +3874,16 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3899,4 +3899,16 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM @Override Spigot spigot(); // Spigot end diff --git a/patches/server/0001-Setup-Gradle-project.patch b/patches/server/0001-Setup-Gradle-project.patch index 7a3394e24690..4319f4cd05d1 100644 --- a/patches/server/0001-Setup-Gradle-project.patch +++ b/patches/server/0001-Setup-Gradle-project.patch @@ -165,7 +165,7 @@ index 0000000000000000000000000000000000000000..6ef457b8ea6ff9b89cb74ecbdca20731 +} diff --git a/pom.xml b/pom.xml deleted file mode 100644 -index da3dad9b745635f2f4b3dd30350070cace3dfc48..0000000000000000000000000000000000000000 +index c2973479d13a5d2898523cf5f246db39c2ea48e6..0000000000000000000000000000000000000000 --- a/pom.xml +++ /dev/null @@ -1,691 +0,0 @@ @@ -175,7 +175,7 @@ index da3dad9b745635f2f4b3dd30350070cace3dfc48..00000000000000000000000000000000 - org.spigotmc - spigot - jar -- 1.21.2-R0.1-SNAPSHOT +- 1.21.3-R0.1-SNAPSHOT - Spigot - https://www.spigotmc.org/ - diff --git a/patches/server/0008-CB-fixes.patch b/patches/server/0008-CB-fixes.patch index ce987eb9e72b..3c0b7b9d42c7 100644 --- a/patches/server/0008-CB-fixes.patch +++ b/patches/server/0008-CB-fixes.patch @@ -115,7 +115,7 @@ index 163d54a8bf4cedbd1471e86b7ab1a1b850ed3f39..6effe47b32a8551aa6f6b11bc0315714 public class CraftScheduler implements BukkitScheduler { diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index fc444b734aad2c23f0808cd66fca23fc350d9e10..2392aa50aec6468f2f498e0a806f65013ce963d1 100644 +index e95c367d1c14dc28b1bf83cc461c80f454af22af..5187d48ba067d0edf55fecfc912ae5ac34452da3 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -246,7 +246,7 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0009-MC-Utils.patch b/patches/server/0009-MC-Utils.patch index 3535d37a4567..4b120d89b8d9 100644 --- a/patches/server/0009-MC-Utils.patch +++ b/patches/server/0009-MC-Utils.patch @@ -5619,10 +5619,10 @@ index 799444e4101283c972a160742a9e2548e604173f..456c58877490feab6be3577d34c89ea7 + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 8ad04c031656d8a676687001b8e9cdc9a1b3bd70..1f013a6eb2088eccb3aea1a5ecd8aac8cc9597d9 100644 +index 031eed24638659f2633bef0ad2e178832ca058e9..a3550d84c273c9720491484382a4bc50dc3246a6 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2433,4 +2433,34 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2447,4 +2447,34 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.spigot; } // Spigot end diff --git a/patches/server/0010-Adventure.patch b/patches/server/0010-Adventure.patch index 1009dbf4c947..589db52a3c19 100644 --- a/patches/server/0010-Adventure.patch +++ b/patches/server/0010-Adventure.patch @@ -2872,7 +2872,7 @@ index e7c407039fef88ef01ba9b6be9ae5bcc3edc026f..5457358bc76889153036818fdfd70a04 @Override diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 2a2197f30db99542cb7d2f99dc1377160ba2dc64..eed5dd58fc37c137c87bf3e55e1e033b74002110 100644 +index 7e276fb310fc9e9217fc12934003611cd616def1..18d56058073b6cc4f9020f0a6137e4ac26eed0b2 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -45,6 +45,7 @@ import net.minecraft.nbt.CompoundTag; @@ -2892,7 +2892,7 @@ index 2a2197f30db99542cb7d2f99dc1377160ba2dc64..eed5dd58fc37c137c87bf3e55e1e033b import com.mojang.datafixers.util.Pair; import java.util.Arrays; import java.util.concurrent.ExecutionException; -@@ -1739,9 +1742,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1747,9 +1750,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl */ this.player.disconnect(); @@ -2907,7 +2907,7 @@ index 2a2197f30db99542cb7d2f99dc1377160ba2dc64..eed5dd58fc37c137c87bf3e55e1e033b } // CraftBukkit end this.player.getTextFilter().leave(); -@@ -1802,10 +1807,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1810,10 +1815,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } CompletableFuture completablefuture = this.filterTextPacket(playerchatmessage.signedContent()).thenApplyAsync(Function.identity(), this.server.chatExecutor); // CraftBukkit - async chat @@ -2921,7 +2921,7 @@ index 2a2197f30db99542cb7d2f99dc1377160ba2dc64..eed5dd58fc37c137c87bf3e55e1e033b this.broadcastChatMessage(playerchatmessage1); }); -@@ -2025,7 +2030,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2033,7 +2038,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.handleCommand(s); } else if (this.player.getChatVisibility() == ChatVisiblity.SYSTEM) { // Do nothing, this is coming from a plugin @@ -2938,7 +2938,7 @@ index 2a2197f30db99542cb7d2f99dc1377160ba2dc64..eed5dd58fc37c137c87bf3e55e1e033b Player player = this.getCraftPlayer(); AsyncPlayerChatEvent event = new AsyncPlayerChatEvent(async, player, s, new LazyPlayerSet(this.server)); String originalFormat = event.getFormat(), originalMessage = event.getMessage(); -@@ -3058,6 +3071,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3066,6 +3079,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void handleClientInformation(ServerboundClientInformationPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); this.player.updateOptions(packet.information()); @@ -4155,10 +4155,10 @@ index 55945b83a5426b352bad9507cc9e94afb1278032..9ea1537408ff2d790747b6e5a681d917 public boolean isOp() { return true; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 1f013a6eb2088eccb3aea1a5ecd8aac8cc9597d9..c02ab554fe6e1b7eb01bbd1824a86ff4de1db2f0 100644 +index a3550d84c273c9720491484382a4bc50dc3246a6..2222fd316ec2463f7e40b2673b29fb338b9d6385 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -391,14 +391,40 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -395,14 +395,40 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public String getDisplayName() { @@ -4199,7 +4199,7 @@ index 1f013a6eb2088eccb3aea1a5ecd8aac8cc9597d9..c02ab554fe6e1b7eb01bbd1824a86ff4 @Override public String getPlayerListName() { return this.getHandle().listName == null ? this.getName() : CraftChatMessage.fromComponent(this.getHandle().listName); -@@ -410,6 +436,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -414,6 +440,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { name = this.getName(); } this.getHandle().listName = name.equals(this.getName()) ? null : CraftChatMessage.fromStringOrNull(name); @@ -4207,7 +4207,7 @@ index 1f013a6eb2088eccb3aea1a5ecd8aac8cc9597d9..c02ab554fe6e1b7eb01bbd1824a86ff4 for (ServerPlayer player : (List) this.server.getHandle().players) { if (player.getBukkitEntity().canSee(this)) { player.connection.send(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME, this.getHandle())); -@@ -429,42 +456,42 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -433,42 +460,42 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().listOrder = order; } @@ -4259,7 +4259,7 @@ index 1f013a6eb2088eccb3aea1a5ecd8aac8cc9597d9..c02ab554fe6e1b7eb01bbd1824a86ff4 this.getHandle().connection.send(packet); } -@@ -494,6 +521,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -498,6 +525,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().transferCookieConnection.kickPlayer(CraftChatMessage.fromStringOrEmpty(message, true)); } @@ -4283,7 +4283,7 @@ index 1f013a6eb2088eccb3aea1a5ecd8aac8cc9597d9..c02ab554fe6e1b7eb01bbd1824a86ff4 @Override public void setCompassTarget(Location loc) { Preconditions.checkArgument(loc != null, "Location cannot be null"); -@@ -790,6 +834,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -794,6 +838,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().connection.send(packet); } @@ -4308,7 +4308,7 @@ index 1f013a6eb2088eccb3aea1a5ecd8aac8cc9597d9..c02ab554fe6e1b7eb01bbd1824a86ff4 @Override public void sendSignChange(Location loc, String[] lines) { this.sendSignChange(loc, lines, DyeColor.BLACK); -@@ -813,6 +875,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -817,6 +879,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { if (this.getHandle().connection == null) return; Component[] components = CraftSign.sanitizeLines(lines); @@ -4321,7 +4321,7 @@ index 1f013a6eb2088eccb3aea1a5ecd8aac8cc9597d9..c02ab554fe6e1b7eb01bbd1824a86ff4 SignBlockEntity sign = new SignBlockEntity(CraftLocation.toBlockPosition(loc), Blocks.OAK_SIGN.defaultBlockState()); SignText text = sign.getFrontText(); text = text.setColor(net.minecraft.world.item.DyeColor.byId(dyeColor.getWoolData())); -@@ -1829,7 +1897,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1843,7 +1911,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setResourcePack(String url) { @@ -4330,7 +4330,7 @@ index 1f013a6eb2088eccb3aea1a5ecd8aac8cc9597d9..c02ab554fe6e1b7eb01bbd1824a86ff4 } @Override -@@ -1844,7 +1912,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1858,7 +1926,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setResourcePack(String url, byte[] hash, boolean force) { @@ -4339,7 +4339,7 @@ index 1f013a6eb2088eccb3aea1a5ecd8aac8cc9597d9..c02ab554fe6e1b7eb01bbd1824a86ff4 } @Override -@@ -1881,6 +1949,59 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1895,6 +1963,59 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.handlePushResourcePack(new ClientboundResourcePackPushPacket(id, url, hashStr, force, CraftChatMessage.fromStringOrOptional(prompt, true)), false); } @@ -4399,7 +4399,7 @@ index 1f013a6eb2088eccb3aea1a5ecd8aac8cc9597d9..c02ab554fe6e1b7eb01bbd1824a86ff4 @Override public void removeResourcePack(UUID id) { Preconditions.checkArgument(id != null, "Resource pack id cannot be null"); -@@ -2301,6 +2422,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2315,6 +2436,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return (this.getHandle().requestedViewDistance() == 0) ? Bukkit.getViewDistance() : this.getHandle().requestedViewDistance(); } @@ -4412,7 +4412,7 @@ index 1f013a6eb2088eccb3aea1a5ecd8aac8cc9597d9..c02ab554fe6e1b7eb01bbd1824a86ff4 @Override public int getPing() { return this.getHandle().connection.latency(); -@@ -2351,6 +2478,248 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2365,6 +2492,248 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.getHandle().allowsListing(); } @@ -5631,7 +5631,7 @@ index ff040613083c015d9c52c0995591b64305fd5018..95444fd9fecc5bda5462ca8dfeca82c5 boolean hadFormat = false; diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 2392aa50aec6468f2f498e0a806f65013ce963d1..e04586249625dc8d77ad5eecd06b8b88fa288503 100644 +index 5187d48ba067d0edf55fecfc912ae5ac34452da3..aa02e932ea19325694b1058d749b0858465530e8 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -79,6 +79,43 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0019-Paper-Plugins.patch b/patches/server/0019-Paper-Plugins.patch index f473973b3c6d..2ca42e58a647 100644 --- a/patches/server/0019-Paper-Plugins.patch +++ b/patches/server/0019-Paper-Plugins.patch @@ -7329,7 +7329,7 @@ index 1b66c5173dd37433d895c0d804257141a3a8c588..e8c1ceed228a1dfb9f3c76b54a91d712 this.enablePlugins(PluginLoadOrder.STARTUP); this.enablePlugins(PluginLoadOrder.POSTWORLD); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index e04586249625dc8d77ad5eecd06b8b88fa288503..1aae364ee6c67b6c89a59ad6cab83bb921645453 100644 +index aa02e932ea19325694b1058d749b0858465530e8..0ff9c62636e8709a6df252e9aaf931c9c17bd9bf 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -401,6 +401,16 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch b/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch index dc4a4d2a0ecc..3610187c209d 100644 --- a/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch +++ b/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch @@ -705,7 +705,7 @@ index 2a29f60c3e82239ab7acd85242fc3390cb9129cd..91c6721201b095eb32c5fd5a1aaf2cbc final Set rerouteMethodData = new HashSet<>(); String className; diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 1aae364ee6c67b6c89a59ad6cab83bb921645453..a45c08c423248a60f9d5822046014427a6dadd12 100644 +index 0ff9c62636e8709a6df252e9aaf931c9c17bd9bf..4b2377a1de608b9142a28c66389d04290f7c0330 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -74,6 +74,7 @@ import org.bukkit.potion.PotionType; diff --git a/patches/server/0023-Timings-v2.patch b/patches/server/0023-Timings-v2.patch index 6cde7981871a..19ddd183bbc6 100644 --- a/patches/server/0023-Timings-v2.patch +++ b/patches/server/0023-Timings-v2.patch @@ -1245,10 +1245,10 @@ index 6fe373de360570b528b8133043ef3bb9ba12529d..d82f4255faac84ce6af47e86707f5c03 this.entityManager.saveAll(); } else { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index eed5dd58fc37c137c87bf3e55e1e033b74002110..7a130da1b50a67331a862f96934739845c7b2d67 100644 +index 18d56058073b6cc4f9020f0a6137e4ac26eed0b2..d8fd2103a40d278c7ee4135c19dea3eb4534dda8 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -337,7 +337,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -339,7 +339,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void tick() { @@ -1256,7 +1256,7 @@ index eed5dd58fc37c137c87bf3e55e1e033b74002110..7a130da1b50a67331a862f9693473984 if (this.ackBlockChangesUpTo > -1) { this.send(new ClientboundBlockChangedAckPacket(this.ackBlockChangesUpTo)); this.ackBlockChangesUpTo = -1; -@@ -393,7 +392,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -395,7 +394,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 this.disconnect((Component) Component.translatable("multiplayer.disconnect.idling")); } @@ -1264,7 +1264,7 @@ index eed5dd58fc37c137c87bf3e55e1e033b74002110..7a130da1b50a67331a862f9693473984 } -@@ -2114,7 +2112,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2122,7 +2120,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } private void handleCommand(String s) { @@ -1273,7 +1273,7 @@ index eed5dd58fc37c137c87bf3e55e1e033b74002110..7a130da1b50a67331a862f9693473984 if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s); -@@ -2124,7 +2122,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2132,7 +2130,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.cserver.getPluginManager().callEvent(event); if (event.isCancelled()) { @@ -1282,7 +1282,7 @@ index eed5dd58fc37c137c87bf3e55e1e033b74002110..7a130da1b50a67331a862f9693473984 return; } -@@ -2137,7 +2135,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2145,7 +2143,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl java.util.logging.Logger.getLogger(ServerGamePacketListenerImpl.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); return; } finally { @@ -1824,10 +1824,10 @@ index b0ffa23faf62629043dfd613315eaf9c5fcc2cfe..00000000000000000000000000000000 - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index c02ab554fe6e1b7eb01bbd1824a86ff4de1db2f0..dafd4105f4ad4729c7637a7b0e5606ff0ec326d1 100644 +index 2222fd316ec2463f7e40b2673b29fb338b9d6385..1e23ea353a552d156cfddb2f620add11c89abbb0 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2795,6 +2795,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2809,6 +2809,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { CraftPlayer.this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundSystemChatPacket(components, position == net.md_5.bungee.api.ChatMessageType.ACTION_BAR)); } @@ -2005,7 +2005,7 @@ index f97eccb6a17c7876e1e002d798eb67bbe80571a0..76effc345d362047e64d064eb64a5222 + } // Paper } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index a45c08c423248a60f9d5822046014427a6dadd12..1e8b13096b0ebed35290c9cbe6b8fb8f4b054b34 100644 +index 4b2377a1de608b9142a28c66389d04290f7c0330..0285349c0e882c1d928240a7ece2f9cc9f4122f2 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -199,6 +199,12 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0033-Expose-server-build-information.patch b/patches/server/0033-Expose-server-build-information.patch index d38434d30412..9cdf2aba91bf 100644 --- a/patches/server/0033-Expose-server-build-information.patch +++ b/patches/server/0033-Expose-server-build-information.patch @@ -692,7 +692,7 @@ index 03790abcc3474999db6d8986e50ebc2caf6eba0c..13f811173c67533ee02f70cc4b6b398c t.printStackTrace(); } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 1e8b13096b0ebed35290c9cbe6b8fb8f4b054b34..d5038fb8720bfe39ffaf3fdea072c01487d315f9 100644 +index 0285349c0e882c1d928240a7ece2f9cc9f4122f2..d22eb174d9c0cc5dd6418c478470c616b75801b2 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -459,6 +459,11 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0034-Player-affects-spawning-API.patch b/patches/server/0034-Player-affects-spawning-API.patch index d5b03dc4aa51..9d430f59c508 100644 --- a/patches/server/0034-Player-affects-spawning-API.patch +++ b/patches/server/0034-Player-affects-spawning-API.patch @@ -135,10 +135,10 @@ index f689b2ca0ebc15c099f36ebfd14e455bda540296..fb043d67eaa6336fc0b5d62774b8f110 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 dafd4105f4ad4729c7637a7b0e5606ff0ec326d1..b5f69a6beaf42abf25463530870c2d7311b18571 100644 +index 1e23ea353a552d156cfddb2f620add11c89abbb0..da568a74260a7068437681bddf102929e6b8f168 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2438,6 +2438,17 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2452,6 +2452,17 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.getHandle().language; } diff --git a/patches/server/0035-Only-refresh-abilities-if-needed.patch b/patches/server/0035-Only-refresh-abilities-if-needed.patch index 2f754caff980..2d9c017bc3ae 100644 --- a/patches/server/0035-Only-refresh-abilities-if-needed.patch +++ b/patches/server/0035-Only-refresh-abilities-if-needed.patch @@ -5,10 +5,10 @@ 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 b5f69a6beaf42abf25463530870c2d7311b18571..2a6db82c926bb5551035f4b040502215d35355fb 100644 +index da568a74260a7068437681bddf102929e6b8f168..29990d84d9e3ee67a4766149c09be6d582999173 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2106,12 +2106,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2120,12 +2120,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setFlying(boolean value) { diff --git a/patches/server/0048-Use-null-Locale-by-default.patch b/patches/server/0048-Use-null-Locale-by-default.patch index 8d9a04746040..7b688c0d3ac3 100644 --- a/patches/server/0048-Use-null-Locale-by-default.patch +++ b/patches/server/0048-Use-null-Locale-by-default.patch @@ -36,10 +36,10 @@ index 4303bde198050cd037f006234d269af406606eff..911ec630c5925b160cc05f99f0d5bb5a this.server.server.getPluginManager().callEvent(event); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 2a6db82c926bb5551035f4b040502215d35355fb..955dda9db5f2142a7cb9634a298a4b30d18dbf3c 100644 +index 29990d84d9e3ee67a4766149c09be6d582999173..9409244db73282816e4f7560dd7d73a961f9e1d3 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2436,7 +2436,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2450,7 +2450,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public String getLocale() { diff --git a/patches/server/0055-Improve-Player-chat-API-handling.patch b/patches/server/0055-Improve-Player-chat-API-handling.patch index 248a889b8cb9..8844c6eaf31b 100644 --- a/patches/server/0055-Improve-Player-chat-API-handling.patch +++ b/patches/server/0055-Improve-Player-chat-API-handling.patch @@ -17,10 +17,10 @@ Co-authored-by: Jake Potrebic Co-authored-by: SoSeDiK diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 7a130da1b50a67331a862f96934739845c7b2d67..6b3023fbbac8ba7d0d0e2968c406b908d81ef7dc 100644 +index d8fd2103a40d278c7ee4135c19dea3eb4534dda8..ab31b31c61d652275a667f34ab018e4c8d0cdc08 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2024,7 +2024,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2032,7 +2032,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } OutgoingChatMessage outgoing = OutgoingChatMessage.create(original); @@ -29,7 +29,7 @@ index 7a130da1b50a67331a862f96934739845c7b2d67..6b3023fbbac8ba7d0d0e2968c406b908 this.handleCommand(s); } else if (this.player.getChatVisibility() == ChatVisiblity.SYSTEM) { // Do nothing, this is coming from a plugin -@@ -2111,7 +2111,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2119,7 +2119,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } @@ -53,10 +53,10 @@ index 9683759c36de3b9d791e56dc1fb993087c1bc37c..3b58cc979c4e2fb5382f0c67ccfaa844 if (this.commandMap.dispatch(sender, commandLine)) { return true; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 955dda9db5f2142a7cb9634a298a4b30d18dbf3c..631ebc76f14482b38374fb2a9cdfe12ea15176e2 100644 +index 9409244db73282816e4f7560dd7d73a961f9e1d3..60bf3f000bbaa8dac201e868ff46963f45251062 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -559,7 +559,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -563,7 +563,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player { if (this.getHandle().connection == null) return; diff --git a/patches/server/0059-Player-Tab-List-and-Title-APIs.patch b/patches/server/0059-Player-Tab-List-and-Title-APIs.patch index 633d3c5d5cc3..d9b0772237ee 100644 --- a/patches/server/0059-Player-Tab-List-and-Title-APIs.patch +++ b/patches/server/0059-Player-Tab-List-and-Title-APIs.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Player Tab List and Title APIs diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 631ebc76f14482b38374fb2a9cdfe12ea15176e2..49befbbd27fb44d564663c140dd594e0f35526f3 100644 +index 60bf3f000bbaa8dac201e868ff46963f45251062..650a9dcb88e9c50fe60e91cfb55f6c440598a356 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -389,6 +389,98 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -393,6 +393,98 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } } diff --git a/patches/server/0066-Complete-resource-pack-API.patch b/patches/server/0066-Complete-resource-pack-API.patch index 745d62228341..1951dc79ca72 100644 --- a/patches/server/0066-Complete-resource-pack-API.patch +++ b/patches/server/0066-Complete-resource-pack-API.patch @@ -22,10 +22,10 @@ index 99f89854e43ed6742dc9ac1624fa7140b4594b3b..d4527831f66bf1c55e6273c7f8923d6e } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 49befbbd27fb44d564663c140dd594e0f35526f3..69459b11c77bd0a6d9584f868773dba92f73aa36 100644 +index 650a9dcb88e9c50fe60e91cfb55f6c440598a356..6e86a515bbea29f3287e968569c177c22c033766 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -209,6 +209,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -213,6 +213,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { private double healthScale = 20; private CraftWorldBorder clientWorldBorder = null; private BorderChangeListener clientWorldBorderListener = this.createWorldBorderListener(); @@ -33,7 +33,7 @@ index 49befbbd27fb44d564663c140dd594e0f35526f3..69459b11c77bd0a6d9584f868773dba9 public CraftPlayer(CraftServer server, ServerPlayer entity) { super(server, entity); -@@ -2107,6 +2108,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2121,6 +2122,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end - adventure diff --git a/patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch b/patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch index a547f5a1766e..6f523d7d27f2 100644 --- a/patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch +++ b/patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch @@ -44,10 +44,10 @@ index 4fa5e7127549e090338b11e6493413a3fab254a0..14d9e62c86309676ddd7eed19cce2f4b protected void internalSetAbsorptionAmount(float absorptionAmount) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 69459b11c77bd0a6d9584f868773dba92f73aa36..ca6194580c10cc864430b859a2c60d0b2e6a9a16 100644 +index 6e86a515bbea29f3287e968569c177c22c033766..cbc8c9bea2a92ecd78ead69e35b9b179819a4c5f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2351,6 +2351,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2365,6 +2365,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } public void setRealHealth(double health) { diff --git a/patches/server/0083-Add-PlayerUseUnknownEntityEvent.patch b/patches/server/0083-Add-PlayerUseUnknownEntityEvent.patch index b5de8e9c2a90..4f7a58fe85d7 100644 --- a/patches/server/0083-Add-PlayerUseUnknownEntityEvent.patch +++ b/patches/server/0083-Add-PlayerUseUnknownEntityEvent.patch @@ -28,10 +28,10 @@ index 1e9c68cd1868d083e6a790d56006dd4aa432010a..8a0ee9564fc36a2badf1357f7e6c47b5 + // Paper end - PlayerUseUnknownEntityEvent } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 6b3023fbbac8ba7d0d0e2968c406b908d81ef7dc..0ddc79be416161d89c9f333ef79a16f079ba6e1d 100644 +index ab31b31c61d652275a667f34ab018e4c8d0cdc08..33caf2d025a5770d2e3ebf044562314df6eb2c15 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2505,7 +2505,26 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2513,7 +2513,26 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl }); } } diff --git a/patches/server/0106-Configurable-packet-in-spam-threshold.patch b/patches/server/0106-Configurable-packet-in-spam-threshold.patch index dea882c5593c..3a0784210e17 100644 --- a/patches/server/0106-Configurable-packet-in-spam-threshold.patch +++ b/patches/server/0106-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 0ddc79be416161d89c9f333ef79a16f079ba6e1d..9646788fc1313467e5a93f923109d412d6c44a77 100644 +index 33caf2d025a5770d2e3ebf044562314df6eb2c15..d5952a0ea86a562cb7ff2e9597260ed9c8ad7192 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1537,13 +1537,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1545,13 +1545,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Spigot start - limit place/interactions private int limitedPackets; private long lastLimitedPacket = -1; diff --git a/patches/server/0107-Configurable-flying-kick-messages.patch b/patches/server/0107-Configurable-flying-kick-messages.patch index e6b2f214c4cf..1c746539c16b 100644 --- a/patches/server/0107-Configurable-flying-kick-messages.patch +++ b/patches/server/0107-Configurable-flying-kick-messages.patch @@ -5,10 +5,10 @@ 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 9646788fc1313467e5a93f923109d412d6c44a77..9289df9663a2dfbc28c2c6dd8c31bf516a6229ae 100644 +index d5952a0ea86a562cb7ff2e9597260ed9c8ad7192..d02c743c8a4fe5d640df53dda881e1d1cba05f5f 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -353,7 +353,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -355,7 +355,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (this.clientIsFloating && !this.player.isSleeping() && !this.player.isPassenger() && !this.player.isDeadOrDying()) { if (++this.aboveGroundTickCount > this.getMaximumFlyingTicks(this.player)) { ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked for floating too long!", this.player.getName().getString()); @@ -17,7 +17,7 @@ index 9646788fc1313467e5a93f923109d412d6c44a77..9289df9663a2dfbc28c2c6dd8c31bf51 return; } } else { -@@ -372,7 +372,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -374,7 +374,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (this.clientVehicleIsFloating && this.lastVehicle.getControllingPassenger() == this.player) { if (++this.aboveGroundVehicleTickCount > this.getMaximumFlyingTicks(this.lastVehicle)) { ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked for floating a vehicle too long!", this.player.getName().getString()); diff --git a/patches/server/0119-String-based-Action-Bar-API.patch b/patches/server/0119-String-based-Action-Bar-API.patch index 69c90a6791be..3dfd3c5e7624 100644 --- a/patches/server/0119-String-based-Action-Bar-API.patch +++ b/patches/server/0119-String-based-Action-Bar-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] String based Action Bar API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index ca6194580c10cc864430b859a2c60d0b2e6a9a16..5085da38a278d8f978e19a5b8df7a8e3d087d753 100644 +index cbc8c9bea2a92ecd78ead69e35b9b179819a4c5f..d3666250037ff4d6594fe859a7b6b0d0ca679d06 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -391,6 +391,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -395,6 +395,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper start diff --git a/patches/server/0129-Add-option-to-make-parrots-stay-on-shoulders-despite.patch b/patches/server/0129-Add-option-to-make-parrots-stay-on-shoulders-despite.patch index 311083326cd1..90926803a24b 100644 --- a/patches/server/0129-Add-option-to-make-parrots-stay-on-shoulders-despite.patch +++ b/patches/server/0129-Add-option-to-make-parrots-stay-on-shoulders-despite.patch @@ -14,10 +14,10 @@ To be converted into a Paper-API event at some point in the future? public net.minecraft.world.entity.player.Player removeEntitiesOnShoulder()V diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 9289df9663a2dfbc28c2c6dd8c31bf516a6229ae..2cc5663878a7c0f4b4d5f4b9a0f69de2326bf415 100644 +index d02c743c8a4fe5d640df53dda881e1d1cba05f5f..74aef01b0b46050f87fd670c435b54e9b98037e1 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2268,6 +2268,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2276,6 +2276,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl switch (packet.getAction()) { case PRESS_SHIFT_KEY: this.player.setShiftKeyDown(true); diff --git a/patches/server/0151-Add-PlayerJumpEvent.patch b/patches/server/0151-Add-PlayerJumpEvent.patch index aed4af669be0..1a5ee572edb5 100644 --- a/patches/server/0151-Add-PlayerJumpEvent.patch +++ b/patches/server/0151-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 2cc5663878a7c0f4b4d5f4b9a0f69de2326bf415..f80bf569089bdc049f861f876ab91183a1860d54 100644 +index 74aef01b0b46050f87fd670c435b54e9b98037e1..1140eac4bb9443508df61e7a50d54add4b206654 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1201,7 +1201,34 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1209,7 +1209,34 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl boolean flag1 = d7 > 0.0D; if (this.player.onGround() && !packet.isOnGround() && flag1) { diff --git a/patches/server/0153-Expose-client-protocol-version-and-virtual-host.patch b/patches/server/0153-Expose-client-protocol-version-and-virtual-host.patch index fba936bcfec4..e88a2bfe3dc9 100644 --- a/patches/server/0153-Expose-client-protocol-version-and-virtual-host.patch +++ b/patches/server/0153-Expose-client-protocol-version-and-virtual-host.patch @@ -90,10 +90,10 @@ index 7ae4279768b70a4fdc8f4438898871a17c8fe402..582bbb376c75ab5bf737f3015ce8ad45 private void beginLogin(ClientIntentionPacket packet, boolean transfer) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 5085da38a278d8f978e19a5b8df7a8e3d087d753..0b18ef707349c086cd670b3c145144eda64df3fd 100644 +index d3666250037ff4d6594fe859a7b6b0d0ca679d06..ce777a7872e34fed0dfdb984127067ffd835477e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -337,6 +337,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -341,6 +341,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().transferCookieConnection.sendPacket(new ClientboundTransferPacket(host, port)); } diff --git a/patches/server/0161-AsyncTabCompleteEvent.patch b/patches/server/0161-AsyncTabCompleteEvent.patch index fba56c021a78..8bf913b966ee 100644 --- a/patches/server/0161-AsyncTabCompleteEvent.patch +++ b/patches/server/0161-AsyncTabCompleteEvent.patch @@ -16,10 +16,10 @@ Also adds isCommand and getLocation to the sync TabCompleteEvent Co-authored-by: Aikar diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index f80bf569089bdc049f861f876ab91183a1860d54..fd5ce79bb1e976dac5109be12aa4b9b550e94f41 100644 +index 1140eac4bb9443508df61e7a50d54add4b206654..752460c4650bebb2860bea82ca186a0f97b1692b 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -714,21 +714,58 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -722,21 +722,58 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } diff --git a/patches/server/0163-Ability-to-apply-mending-to-XP-API.patch b/patches/server/0163-Ability-to-apply-mending-to-XP-API.patch index 501c3bc45cc4..5f8abf9d97b0 100644 --- a/patches/server/0163-Ability-to-apply-mending-to-XP-API.patch +++ b/patches/server/0163-Ability-to-apply-mending-to-XP-API.patch @@ -14,10 +14,10 @@ public net.minecraft.world.entity.ExperienceOrb durabilityToXp(I)I public net.minecraft.world.entity.ExperienceOrb xpToDurability(I)I diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 0b18ef707349c086cd670b3c145144eda64df3fd..18c0f0550cd6b41fa394e36ee5eb9ee48138dc0b 100644 +index ce777a7872e34fed0dfdb984127067ffd835477e..d98c0b9faa4ec97ef251d397456458668c911012 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1651,7 +1651,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1665,7 +1665,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override diff --git a/patches/server/0176-Player.setPlayerProfile-API.patch b/patches/server/0176-Player.setPlayerProfile-API.patch index 8c5b6401bd8a..98bd61340a95 100644 --- a/patches/server/0176-Player.setPlayerProfile-API.patch +++ b/patches/server/0176-Player.setPlayerProfile-API.patch @@ -64,10 +64,10 @@ index 818df09e9245b5d89b4180b1eaa51470b7539341..f6b2ca92fd3510a76cbf56d0ea55aa6c public Server getServer() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 18c0f0550cd6b41fa394e36ee5eb9ee48138dc0b..356681047e34b577f51a4f90ebc8892cb1e6eaa8 100644 +index d98c0b9faa4ec97ef251d397456458668c911012..862001f88b4613cb420bf8b8ca1471f41729ad0f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -250,11 +250,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -254,11 +254,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.server.getPlayer(this.getUniqueId()) != null; } @@ -79,7 +79,7 @@ index 18c0f0550cd6b41fa394e36ee5eb9ee48138dc0b..356681047e34b577f51a4f90ebc8892c @Override public InetSocketAddress getAddress() { if (this.getHandle().connection.protocol() == null) return null; -@@ -1805,8 +1800,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1819,8 +1814,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { private void untrackAndHideEntity(org.bukkit.entity.Entity entity) { // Remove this entity from the hidden player's EntityTrackerEntry @@ -96,7 +96,7 @@ index 18c0f0550cd6b41fa394e36ee5eb9ee48138dc0b..356681047e34b577f51a4f90ebc8892c ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId()); if (entry != null) { entry.removePlayer(this.getHandle()); -@@ -1819,8 +1821,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1833,8 +1835,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().connection.send(new ClientboundPlayerInfoRemovePacket(List.of(otherPlayer.getUUID()))); } } @@ -105,7 +105,7 @@ index 18c0f0550cd6b41fa394e36ee5eb9ee48138dc0b..356681047e34b577f51a4f90ebc8892c } void resetAndHideEntity(org.bukkit.entity.Entity entity) { -@@ -1885,12 +1885,25 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1899,12 +1899,25 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } private void trackAndShowEntity(org.bukkit.entity.Entity entity) { @@ -131,7 +131,7 @@ index 18c0f0550cd6b41fa394e36ee5eb9ee48138dc0b..356681047e34b577f51a4f90ebc8892c } ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId()); -@@ -1900,6 +1913,39 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1914,6 +1927,39 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.server.getPluginManager().callEvent(new PlayerShowEntityEvent(this, entity)); } @@ -171,7 +171,7 @@ index 18c0f0550cd6b41fa394e36ee5eb9ee48138dc0b..356681047e34b577f51a4f90ebc8892c void resetAndShowEntity(org.bukkit.entity.Entity entity) { // SPIGOT-7312: Can't show/hide self -@@ -1911,6 +1957,34 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1925,6 +1971,34 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.trackAndShowEntity(entity); } } diff --git a/patches/server/0181-Flag-to-disable-the-channel-limit.patch b/patches/server/0181-Flag-to-disable-the-channel-limit.patch index 1950fdda934d..415d4913b16a 100644 --- a/patches/server/0181-Flag-to-disable-the-channel-limit.patch +++ b/patches/server/0181-Flag-to-disable-the-channel-limit.patch @@ -9,10 +9,10 @@ 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 356681047e34b577f51a4f90ebc8892cb1e6eaa8..e7477aaad01c26e56e3d5e90bd403311deae8d59 100644 +index 862001f88b4613cb420bf8b8ca1471f41729ad0f..b295c2cb3758f653b28120291b2f6c08ad2e4acf 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -210,6 +210,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -214,6 +214,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { private CraftWorldBorder clientWorldBorder = null; private BorderChangeListener clientWorldBorderListener = this.createWorldBorderListener(); public org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus; // Paper - more resource pack API @@ -20,7 +20,7 @@ index 356681047e34b577f51a4f90ebc8892cb1e6eaa8..e7477aaad01c26e56e3d5e90bd403311 public CraftPlayer(CraftServer server, ServerPlayer entity) { super(server, entity); -@@ -2282,7 +2283,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2296,7 +2297,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } public void addChannel(String channel) { diff --git a/patches/server/0207-InventoryCloseEvent-Reason-API.patch b/patches/server/0207-InventoryCloseEvent-Reason-API.patch index 94f20cfc2c07..1384bfc2db7b 100644 --- a/patches/server/0207-InventoryCloseEvent-Reason-API.patch +++ b/patches/server/0207-InventoryCloseEvent-Reason-API.patch @@ -75,10 +75,10 @@ index 98aeafcc51e23a7534c8d57e4db0eb58abb3f30b..29b836a75b835f0d5233db419fc5ca8d 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 fd5ce79bb1e976dac5109be12aa4b9b550e94f41..9033c0e720a432d9abffdd7aebee2d26e595ee93 100644 +index 752460c4650bebb2860bea82ca186a0f97b1692b..5f514f87b171c5c845d5d7714d2d2179fbb0c1a1 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2633,10 +2633,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2641,10 +2641,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleContainerClose(ServerboundContainerClosePacket packet) { @@ -165,10 +165,10 @@ index 6d4e0a90c70f7a66450cbb18ebec1d7bf9200af2..5ff159be1a6dfb4b1a5b9aa1e435d294 @Override public boolean isBlocking() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index e7477aaad01c26e56e3d5e90bd403311deae8d59..ad75996926b7e054f1053d07fb978ac745f22ce6 100644 +index b295c2cb3758f653b28120291b2f6c08ad2e4acf..dc0a04f68482a5101acd19bfc61a64aea689b773 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1286,7 +1286,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1290,7 +1290,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Close any foreign inventory if (this.getHandle().containerMenu != this.getHandle().inventoryMenu) { diff --git a/patches/server/0221-Break-up-and-make-tab-spam-limits-configurable.patch b/patches/server/0221-Break-up-and-make-tab-spam-limits-configurable.patch index 25b1469681b4..ceaa06bf27ed 100644 --- a/patches/server/0221-Break-up-and-make-tab-spam-limits-configurable.patch +++ b/patches/server/0221-Break-up-and-make-tab-spam-limits-configurable.patch @@ -22,10 +22,10 @@ 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 9033c0e720a432d9abffdd7aebee2d26e595ee93..c20ae23e4ca340cd5ec093578f88d16529c3523a 100644 +index 5f514f87b171c5c845d5d7714d2d2179fbb0c1a1..4f6985d4458cfba8fd8323d06363763871da2fa0 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -272,6 +272,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -274,6 +274,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private int tickCount; private int ackBlockChangesUpTo = -1; private final TickThrottler chatSpamThrottler = new TickThrottler(20, 200); @@ -33,7 +33,7 @@ index 9033c0e720a432d9abffdd7aebee2d26e595ee93..c20ae23e4ca340cd5ec093578f88d165 private final TickThrottler dropSpamThrottler = new TickThrottler(20, 1480); private double firstGoodX; private double firstGoodY; -@@ -387,6 +388,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -389,6 +390,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.keepConnectionAlive(); this.chatSpamThrottler.tick(); @@ -41,7 +41,7 @@ index 9033c0e720a432d9abffdd7aebee2d26e595ee93..c20ae23e4ca340cd5ec093578f88d165 this.dropSpamThrottler.tick(); if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L) { this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 -@@ -722,7 +724,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -730,7 +732,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) { // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async // CraftBukkit start diff --git a/patches/server/0240-Expose-attack-cooldown-methods-for-Player.patch b/patches/server/0240-Expose-attack-cooldown-methods-for-Player.patch index 889ae1c62326..9e8e7726881e 100644 --- a/patches/server/0240-Expose-attack-cooldown-methods-for-Player.patch +++ b/patches/server/0240-Expose-attack-cooldown-methods-for-Player.patch @@ -5,10 +5,10 @@ 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 ad75996926b7e054f1053d07fb978ac745f22ce6..535e0438b02fd7c10aee0d24786a6e38c6e48359 100644 +index dc0a04f68482a5101acd19bfc61a64aea689b773..e3048a5ce7528c056a90a3bc75cea25d832c1d8c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2993,6 +2993,21 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3007,6 +3007,21 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.adventure$pointers; } diff --git a/patches/server/0241-Improve-death-events.patch b/patches/server/0241-Improve-death-events.patch index d6a188627045..c2ce8d6f232a 100644 --- a/patches/server/0241-Improve-death-events.patch +++ b/patches/server/0241-Improve-death-events.patch @@ -420,10 +420,10 @@ index 2caba38a50b7ea535337a3540aa5272d4a9f1878..e20565cf256aacd012a1722c5ebbf901 // CraftBukkit end 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 535e0438b02fd7c10aee0d24786a6e38c6e48359..c132b4d4d871eaeadec78921a99ba7066c59ddda 100644 +index e3048a5ce7528c056a90a3bc75cea25d832c1d8c..d7db67d8bf1f8c9f94547d43e8291e13c9ba34ac 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2530,7 +2530,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2544,7 +2544,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void sendHealthUpdate() { FoodData foodData = this.getHandle().getFoodData(); diff --git a/patches/server/0257-Add-option-to-prevent-players-from-moving-into-unloa.patch b/patches/server/0257-Add-option-to-prevent-players-from-moving-into-unloa.patch index 15dac08b6658..33cebcaddbc4 100644 --- a/patches/server/0257-Add-option-to-prevent-players-from-moving-into-unloa.patch +++ b/patches/server/0257-Add-option-to-prevent-players-from-moving-into-unloa.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add option to prevent players from moving into unloaded diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index c20ae23e4ca340cd5ec093578f88d16529c3523a..ff378b29a2dfec293f7a926d1e8383627795303a 100644 +index 4f6985d4458cfba8fd8323d06363763871da2fa0..b15cd1b5b4e4e20a70099acd351e3ac1025a6f31 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -490,9 +490,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -498,9 +498,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl double d0 = entity.getX(); double d1 = entity.getY(); double d2 = entity.getZ(); @@ -22,7 +22,7 @@ index c20ae23e4ca340cd5ec093578f88d16529c3523a..ff378b29a2dfec293f7a926d1e838362 float f = Mth.wrapDegrees(packet.getYRot()); float f1 = Mth.wrapDegrees(packet.getXRot()); double d6 = d3 - this.vehicleFirstGoodX; -@@ -526,6 +526,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -534,6 +534,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } speed *= 2f; // TODO: Get the speed of the vehicle instead of the player @@ -39,7 +39,7 @@ index c20ae23e4ca340cd5ec093578f88d16529c3523a..ff378b29a2dfec293f7a926d1e838362 if (d10 - d9 > Math.max(100.0D, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { // CraftBukkit end ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", new Object[]{entity.getName().getString(), this.player.getName().getString(), d6, d7, d8}); -@@ -1159,9 +1169,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1167,9 +1177,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } if (!this.updateAwaitingTeleport()) { @@ -52,7 +52,7 @@ index c20ae23e4ca340cd5ec093578f88d16529c3523a..ff378b29a2dfec293f7a926d1e838362 float f = Mth.wrapDegrees(packet.getYRot(this.player.getYRot())); float f1 = Mth.wrapDegrees(packet.getXRot(this.player.getXRot())); -@@ -1219,6 +1229,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1227,6 +1237,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } else { speed = this.player.getAbilities().walkingSpeed * 10f; } diff --git a/patches/server/0264-Don-t-allow-digging-into-unloaded-chunks.patch b/patches/server/0264-Don-t-allow-digging-into-unloaded-chunks.patch index 1ec1ba0901e5..ccd3f8c7b28c 100644 --- a/patches/server/0264-Don-t-allow-digging-into-unloaded-chunks.patch +++ b/patches/server/0264-Don-t-allow-digging-into-unloaded-chunks.patch @@ -59,10 +59,10 @@ index 4c8189a2a7edea824545a24dccb376b8eceac001..4623c8acd125dff4919c4e2045b84831 this.level.destroyBlockProgress(this.player.getId(), pos, -1); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index ff378b29a2dfec293f7a926d1e8383627795303a..3f9025405e90ebcbab5ce4c1edef55fe74e529c6 100644 +index b15cd1b5b4e4e20a70099acd351e3ac1025a6f31..7edc3590c43ba51a4b3ec7e089d32f7dfab411dd 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1598,6 +1598,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1606,6 +1606,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl case START_DESTROY_BLOCK: case ABORT_DESTROY_BLOCK: case STOP_DESTROY_BLOCK: diff --git a/patches/server/0268-Book-size-limits.patch b/patches/server/0268-Book-size-limits.patch index 9f5460577420..92491902e442 100644 --- a/patches/server/0268-Book-size-limits.patch +++ b/patches/server/0268-Book-size-limits.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Book size limits Puts some limits on the size of books. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 3f9025405e90ebcbab5ce4c1edef55fe74e529c6..c234ee2b72249accbaee4f8005fa4c2f1be0fdc8 100644 +index 7edc3590c43ba51a4b3ec7e089d32f7dfab411dd..2c0ebe9f37233877d6507e05bf1db0b5c01f6c35 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1048,6 +1048,44 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1056,6 +1056,44 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleEditBook(ServerboundEditBookPacket packet) { diff --git a/patches/server/0270-Replace-OfflinePlayer-getLastPlayed.patch b/patches/server/0270-Replace-OfflinePlayer-getLastPlayed.patch index 5b71e0546e1f..ac848098b4f6 100644 --- a/patches/server/0270-Replace-OfflinePlayer-getLastPlayed.patch +++ b/patches/server/0270-Replace-OfflinePlayer-getLastPlayed.patch @@ -106,10 +106,10 @@ index f6b2ca92fd3510a76cbf56d0ea55aa6caaf12ba1..e0d342a0ddd140b342f7af138c71596c 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 c132b4d4d871eaeadec78921a99ba7066c59ddda..da5fbeaea4bbb4fd3cac2eb4ff31bd3849754280 100644 +index d7db67d8bf1f8c9f94547d43e8291e13c9ba34ac..5e14d93fe151847969d8c4ca9e1aa960aad39dcc 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -211,6 +211,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -215,6 +215,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { private BorderChangeListener clientWorldBorderListener = this.createWorldBorderListener(); public org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus; // Paper - more resource pack API private static final boolean DISABLE_CHANNEL_LIMIT = System.getProperty("paper.disableChannelLimit") != null; // Paper - add a flag to disable the channel limit @@ -117,7 +117,7 @@ index c132b4d4d871eaeadec78921a99ba7066c59ddda..da5fbeaea4bbb4fd3cac2eb4ff31bd38 public CraftPlayer(CraftServer server, ServerPlayer entity) { super(server, entity); -@@ -2062,6 +2063,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2076,6 +2077,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.firstPlayed = firstPlayed; } @@ -136,7 +136,7 @@ index c132b4d4d871eaeadec78921a99ba7066c59ddda..da5fbeaea4bbb4fd3cac2eb4ff31bd38 public void readExtraData(CompoundTag nbttagcompound) { this.hasPlayedBefore = true; if (nbttagcompound.contains("bukkit")) { -@@ -2084,6 +2097,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2098,6 +2111,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } public void setExtraData(CompoundTag nbttagcompound) { @@ -145,7 +145,7 @@ index c132b4d4d871eaeadec78921a99ba7066c59ddda..da5fbeaea4bbb4fd3cac2eb4ff31bd38 if (!nbttagcompound.contains("bukkit")) { nbttagcompound.put("bukkit", new CompoundTag()); } -@@ -2098,6 +2113,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2112,6 +2127,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { data.putLong("firstPlayed", this.getFirstPlayed()); data.putLong("lastPlayed", System.currentTimeMillis()); data.putString("lastKnownName", handle.getScoreboardName()); diff --git a/patches/server/0272-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch b/patches/server/0272-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch index 2f17f2f3abba..52e9b55fd23f 100644 --- a/patches/server/0272-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch +++ b/patches/server/0272-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch @@ -8,10 +8,10 @@ We just add a check to ensure that the CraftPlayer's handle is a ServerPlayer diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index da5fbeaea4bbb4fd3cac2eb4ff31bd3849754280..df99bc022b25e61dc8827c67fb4eb2909bba097f 100644 +index 5e14d93fe151847969d8c4ca9e1aa960aad39dcc..d4b6a3c2bb63022c00f5d847a1e406ed4efd98c6 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -225,8 +225,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -229,8 +229,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void remove() { diff --git a/patches/server/0275-Brigadier-Mojang-API.patch b/patches/server/0275-Brigadier-Mojang-API.patch index 080f3c0fe575..2c5c3190ef96 100644 --- a/patches/server/0275-Brigadier-Mojang-API.patch +++ b/patches/server/0275-Brigadier-Mojang-API.patch @@ -119,10 +119,10 @@ index e812cc865baaa1ee03872f7969ee98600b82483b..c847fbdb6f52386570eb4c070fcc01d3 if (commandnode2.canUse(source)) { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index c234ee2b72249accbaee4f8005fa4c2f1be0fdc8..77e111973ae33389315af72eb950b6f9d9abee12 100644 +index 2c0ebe9f37233877d6507e05bf1db0b5c01f6c35..4592ac291b6a80785157b7909ad8e249f06e25f5 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -772,19 +772,34 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -780,19 +780,34 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl builder.suggest(completion.suggestion(), PaperAdventure.asVanilla(completion.tooltip())); } } diff --git a/patches/server/0276-Limit-Client-Sign-length-more.patch b/patches/server/0276-Limit-Client-Sign-length-more.patch index 0cbe0df00cdd..c6ce69862eeb 100644 --- a/patches/server/0276-Limit-Client-Sign-length-more.patch +++ b/patches/server/0276-Limit-Client-Sign-length-more.patch @@ -22,10 +22,10 @@ it only impacts data sent from the client. Set -DPaper.maxSignLength=XX to change limit or -1 to disable diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 77e111973ae33389315af72eb950b6f9d9abee12..fd5ad700154a7b75f2ecff6a8d47f6d75ac789e4 100644 +index 4592ac291b6a80785157b7909ad8e249f06e25f5..df2718d7e7dd7969f49b3467347fa2adcf60132a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -306,6 +306,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -308,6 +308,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private final MessageSignatureCache messageSignatureCache = MessageSignatureCache.createDefault(); private final FutureChain chatMessageChain; private boolean waitingForSwitchToConfig; @@ -33,7 +33,7 @@ index 77e111973ae33389315af72eb950b6f9d9abee12..fd5ad700154a7b75f2ecff6a8d47f6d7 public ServerGamePacketListenerImpl(MinecraftServer server, Connection connection, ServerPlayer player, CommonListenerCookie clientData) { super(server, connection, clientData, player); // CraftBukkit -@@ -3196,7 +3197,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3204,7 +3205,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleSignUpdate(ServerboundSignUpdatePacket packet) { diff --git a/patches/server/0324-Add-Raw-Byte-ItemStack-Serialization.patch b/patches/server/0324-Add-Raw-Byte-ItemStack-Serialization.patch index d918d6fca729..62d404577171 100644 --- a/patches/server/0324-Add-Raw-Byte-ItemStack-Serialization.patch +++ b/patches/server/0324-Add-Raw-Byte-ItemStack-Serialization.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add Raw Byte ItemStack Serialization Serializes using NBT which is safer for server data migrations than bukkits format. diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index d5038fb8720bfe39ffaf3fdea072c01487d315f9..180259d1e5401777e121a8c1ec95034afbc0917b 100644 +index d22eb174d9c0cc5dd6418c478470c616b75801b2..f78459e65fd27a5fd9839d2ad1c95758c8d95489 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -464,6 +464,53 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0337-Implement-Player-Client-Options-API.patch b/patches/server/0337-Implement-Player-Client-Options-API.patch index 943a64b447f7..6bd62a888248 100644 --- a/patches/server/0337-Implement-Player-Client-Options-API.patch +++ b/patches/server/0337-Implement-Player-Client-Options-API.patch @@ -136,10 +136,10 @@ index 363175d3325c012f31ba84060bb0bfac694f6ab8..9911e231ad021286f2da90057b06874f this.adventure$locale = java.util.Objects.requireNonNullElse(net.kyori.adventure.translation.Translator.parseLocale(this.language), java.util.Locale.US); // Paper this.requestedViewDistance = clientOptions.viewDistance(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index df99bc022b25e61dc8827c67fb4eb2909bba097f..f836a65db1028b51ebd425251ca37e0c439d4ad6 100644 +index d4b6a3c2bb63022c00f5d847a1e406ed4efd98c6..077d47858ac87f732d8ff0d22191b35bc2a58c42 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -666,6 +666,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -670,6 +670,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { connection.disconnect(message == null ? net.kyori.adventure.text.Component.empty() : message); } } diff --git a/patches/server/0346-Validate-PickItem-Packet-and-kick-for-invalid.patch b/patches/server/0346-Validate-PickItem-Packet-and-kick-for-invalid.patch index 324c88b6988c..cc98d91687ab 100644 --- a/patches/server/0346-Validate-PickItem-Packet-and-kick-for-invalid.patch +++ b/patches/server/0346-Validate-PickItem-Packet-and-kick-for-invalid.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Validate PickItem Packet and kick for invalid diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index fd5ad700154a7b75f2ecff6a8d47f6d75ac789e4..7d3a64ad036470e9cd540131c2c3a58d871bc392 100644 +index df2718d7e7dd7969f49b3467347fa2adcf60132a..1b82e733c107540618cb1f69511ea9e1a4a13fc8 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -898,7 +898,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -906,7 +906,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handlePickItem(ServerboundPickItemPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); diff --git a/patches/server/0349-Prevent-teleporting-dead-entities.patch b/patches/server/0349-Prevent-teleporting-dead-entities.patch index 8016bc245489..ee1f3e1a971b 100644 --- a/patches/server/0349-Prevent-teleporting-dead-entities.patch +++ b/patches/server/0349-Prevent-teleporting-dead-entities.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent teleporting dead entities diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 7d3a64ad036470e9cd540131c2c3a58d871bc392..452fdd64669765d5dc73faa90d94bf474cbe1a07 100644 +index 1b82e733c107540618cb1f69511ea9e1a4a13fc8..9286012c7a07e1a621035b0563cb06a3421ea945 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1563,6 +1563,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1571,6 +1571,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } public void internalTeleport(PositionMoveRotation positionmoverotation, Set set) { diff --git a/patches/server/0364-Prevent-position-desync-causing-tp-exploit.patch b/patches/server/0364-Prevent-position-desync-causing-tp-exploit.patch index 9acb04239e17..ebbd08637af1 100644 --- a/patches/server/0364-Prevent-position-desync-causing-tp-exploit.patch +++ b/patches/server/0364-Prevent-position-desync-causing-tp-exploit.patch @@ -13,10 +13,10 @@ behaviour, we need to move all of this dangerous logic outside of the move call and into an appropriate place in the tick method. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 452fdd64669765d5dc73faa90d94bf474cbe1a07..4ac071f31583cd7fa0d80d8bbaddd3f5de8d648c 100644 +index 9286012c7a07e1a621035b0563cb06a3421ea945..f4f2b6733780312c289af96ec8ffe1fbf732651e 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1351,6 +1351,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1359,6 +1359,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.move(MoverType.PLAYER, new Vec3(d6, d7, d8)); this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move diff --git a/patches/server/0366-Add-PlayerRecipeBookClickEvent.patch b/patches/server/0366-Add-PlayerRecipeBookClickEvent.patch index e6174267bc27..504a8bac86db 100644 --- a/patches/server/0366-Add-PlayerRecipeBookClickEvent.patch +++ b/patches/server/0366-Add-PlayerRecipeBookClickEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerRecipeBookClickEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 4ac071f31583cd7fa0d80d8bbaddd3f5de8d648c..b180bc19f4a8fa413a84429895bcd5d0f6a30a43 100644 +index f4f2b6733780312c289af96ec8ffe1fbf732651e..09b478545ab5eed86dda17c5c74c585c7d3e6df8 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -199,6 +199,7 @@ import net.minecraft.world.phys.Vec3; @@ -16,7 +16,7 @@ index 4ac071f31583cd7fa0d80d8bbaddd3f5de8d648c..b180bc19f4a8fa413a84429895bcd5d0 import org.slf4j.Logger; // CraftBukkit start -@@ -3085,21 +3086,41 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3093,21 +3094,41 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl ServerGamePacketListenerImpl.LOGGER.debug("Player {} tried to place impossible recipe {}", this.player, recipeholder.id().location()); return; } diff --git a/patches/server/0368-Add-permission-for-command-blocks.patch b/patches/server/0368-Add-permission-for-command-blocks.patch index f7d0a92c42cd..f971d5b25aad 100644 --- a/patches/server/0368-Add-permission-for-command-blocks.patch +++ b/patches/server/0368-Add-permission-for-command-blocks.patch @@ -18,10 +18,10 @@ index 4623c8acd125dff4919c4e2045b848310d785da5..86e4559da2344f228ef4d1c4ac3c115f return false; } else if (this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index b180bc19f4a8fa413a84429895bcd5d0f6a30a43..ac073dab2d2552f9bb0394379a237a4dc37c8fb2 100644 +index 09b478545ab5eed86dda17c5c74c585c7d3e6df8..acf13898f316c0ddf3c31c0ac716322c23234318 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -810,7 +810,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -818,7 +818,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (!this.server.isCommandBlockEnabled()) { this.player.sendSystemMessage(Component.translatable("advMode.notEnabled")); @@ -30,7 +30,7 @@ index b180bc19f4a8fa413a84429895bcd5d0f6a30a43..ac073dab2d2552f9bb0394379a237a4d this.player.sendSystemMessage(Component.translatable("advMode.notAllowed")); } else { BaseCommandBlock commandblocklistenerabstract = null; -@@ -877,7 +877,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -885,7 +885,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (!this.server.isCommandBlockEnabled()) { this.player.sendSystemMessage(Component.translatable("advMode.notEnabled")); diff --git a/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch b/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch index b0483140f364..3be0b6418891 100644 --- a/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch +++ b/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch @@ -76,10 +76,10 @@ index 82d5f1235d158326ce6fb1eb6d481c00f57467d3..20a3138c6c2a6c8ada8b6008913abae0 @Override diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index ac073dab2d2552f9bb0394379a237a4dc37c8fb2..7865ff33b0163460a9ffdb7ed4bb3970b5674344 100644 +index acf13898f316c0ddf3c31c0ac716322c23234318..fa25c989433379b3be384f08b7e3cf47a8eac9b7 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3303,7 +3303,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3311,7 +3311,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void handleChangeDifficulty(ServerboundChangeDifficultyPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (this.player.hasPermissions(2) || this.isSingleplayerOwner()) { diff --git a/patches/server/0376-Do-not-accept-invalid-client-settings.patch b/patches/server/0376-Do-not-accept-invalid-client-settings.patch index 590c7811c869..b3c22c0c6598 100644 --- a/patches/server/0376-Do-not-accept-invalid-client-settings.patch +++ b/patches/server/0376-Do-not-accept-invalid-client-settings.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Do not accept invalid client settings diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 7865ff33b0163460a9ffdb7ed4bb3970b5674344..f146787c935287eb5cc545643036eeb2a2d7dc9b 100644 +index fa25c989433379b3be384f08b7e3cf47a8eac9b7..49039d929681891beb76b8c7f6e6d8bb614a7bf0 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3295,6 +3295,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3303,6 +3303,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleClientInformation(ServerboundClientInformationPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); diff --git a/patches/server/0389-Brand-support.patch b/patches/server/0389-Brand-support.patch index 74047404172e..226edc4d049b 100644 --- a/patches/server/0389-Brand-support.patch +++ b/patches/server/0389-Brand-support.patch @@ -57,10 +57,10 @@ index b9fbaddcc8239bf737fdea51790f678306e511eb..9a8b08d4b70b8890961e4af7ce6e870a } catch (Exception ex) { ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t dispatch custom payload", ex); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index f836a65db1028b51ebd425251ca37e0c439d4ad6..eb2954c9b51d4fd76cf5aec17899218f4de7076d 100644 +index 077d47858ac87f732d8ff0d22191b35bc2a58c42..9042bbcfb161d91b1e2c4d6e0461f141fa41872e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3152,6 +3152,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3166,6 +3166,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Paper end }; diff --git a/patches/server/0393-Add-moon-phase-API.patch b/patches/server/0393-Add-moon-phase-API.patch index be42d9302bc9..2fcd34c334fd 100644 --- a/patches/server/0393-Add-moon-phase-API.patch +++ b/patches/server/0393-Add-moon-phase-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add moon phase API diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index 2b5e8d01a31de154faa18c55cdddd3bd7f462891..93dadbf659e41c923268d8ec782fcbdc8aaeff68 100644 +index 92a0c2049fa1df76cedfe7dfbd6e5fe402859f4b..15da29058f80a2d7cf2be26c48421c1746815a10 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -@@ -509,4 +509,11 @@ public abstract class CraftRegionAccessor implements RegionAccessor { +@@ -515,4 +515,11 @@ public abstract class CraftRegionAccessor implements RegionAccessor { throw new IllegalArgumentException("Cannot spawn an entity for " + clazz.getName()); } diff --git a/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch b/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch index 2cb92d0cf82b..a05ecacdceaa 100644 --- a/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch +++ b/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch @@ -9,10 +9,10 @@ as this is how Vanilla teleports entities. Cancel any pending motion when teleported. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index f146787c935287eb5cc545643036eeb2a2d7dc9b..c430434485baa7fc5a213efd9523cee8c2c46b44 100644 +index 49039d929681891beb76b8c7f6e6d8bb614a7bf0..b634a90e87f52c79b74c256c13b659b51556f7fe 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -677,7 +677,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -685,7 +685,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return; } diff --git a/patches/server/0408-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch b/patches/server/0408-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch index a9c355af5979..2b99da73b968 100644 --- a/patches/server/0408-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch +++ b/patches/server/0408-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch @@ -21,7 +21,7 @@ index f8fd729d53248c7598a118d89fedf340f82cdd61..ac1b2b3982e5ceb8fecf20867dd2ac6e + // Paper end - Expose entity id counter } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 180259d1e5401777e121a8c1ec95034afbc0917b..3448ada171a9fb8c8294b0ba93eb2c846788a679 100644 +index f78459e65fd27a5fd9839d2ad1c95758c8d95489..249c0f717a80b9ca8e200ebdbf72a0dc4c3730cc 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -511,6 +511,11 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0414-Fix-for-large-move-vectors-crashing-server.patch b/patches/server/0414-Fix-for-large-move-vectors-crashing-server.patch index 241260a91556..7e52db071fb3 100644 --- a/patches/server/0414-Fix-for-large-move-vectors-crashing-server.patch +++ b/patches/server/0414-Fix-for-large-move-vectors-crashing-server.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Fix for large move vectors crashing server Check movement distance also based on current position. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index c430434485baa7fc5a213efd9523cee8c2c46b44..e3e43c361d8612dbc79fe88730a3794eb44d85e4 100644 +index b634a90e87f52c79b74c256c13b659b51556f7fe..a45078fc6a63742682040518e419fe0e2f704065 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -489,9 +489,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -497,9 +497,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl float prevYaw = this.player.getYRot(); float prevPitch = this.player.getXRot(); // CraftBukkit end @@ -22,7 +22,7 @@ index c430434485baa7fc5a213efd9523cee8c2c46b44..e3e43c361d8612dbc79fe88730a3794e double d3 = ServerGamePacketListenerImpl.clampHorizontal(packet.getX()); final double toX = d3; // Paper - OBFHELPER double d4 = ServerGamePacketListenerImpl.clampVertical(packet.getY()); final double toY = d4; // Paper - OBFHELPER double d5 = ServerGamePacketListenerImpl.clampHorizontal(packet.getZ()); final double toZ = d5; // Paper - OBFHELPER -@@ -501,7 +501,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -509,7 +509,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl double d7 = d4 - this.vehicleFirstGoodY; double d8 = d5 - this.vehicleFirstGoodZ; double d9 = entity.getDeltaMovement().lengthSqr(); @@ -40,7 +40,7 @@ index c430434485baa7fc5a213efd9523cee8c2c46b44..e3e43c361d8612dbc79fe88730a3794e // CraftBukkit start - handle custom speeds and skipped ticks this.allowedPlayerTicks += (System.currentTimeMillis() / 50) - this.lastTick; -@@ -547,9 +556,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -555,9 +564,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl boolean flag = worldserver.noCollision(entity, entity.getBoundingBox().deflate(0.0625D)); @@ -53,7 +53,7 @@ index c430434485baa7fc5a213efd9523cee8c2c46b44..e3e43c361d8612dbc79fe88730a3794e boolean flag1 = entity.verticalCollisionBelow; if (entity instanceof LivingEntity) { -@@ -1256,7 +1265,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1264,7 +1273,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl double d7 = d1 - this.firstGoodY; double d8 = d2 - this.firstGoodZ; double d9 = this.player.getDeltaMovement().lengthSqr(); @@ -71,7 +71,7 @@ index c430434485baa7fc5a213efd9523cee8c2c46b44..e3e43c361d8612dbc79fe88730a3794e if (this.player.isSleeping()) { if (d10 > 1.0D) { -@@ -1312,9 +1330,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1320,9 +1338,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl AABB axisalignedbb = this.player.getBoundingBox(); diff --git a/patches/server/0424-Fix-client-lag-on-advancement-loading.patch b/patches/server/0424-Fix-client-lag-on-advancement-loading.patch index e62e28f8d522..ecae324f162b 100644 --- a/patches/server/0424-Fix-client-lag-on-advancement-loading.patch +++ b/patches/server/0424-Fix-client-lag-on-advancement-loading.patch @@ -15,7 +15,7 @@ manually reload the advancement data for all players, which normally takes place as a part of the datapack reloading. diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 3448ada171a9fb8c8294b0ba93eb2c846788a679..ea9c9ae832c4044a2eccbf901e20ff042df68bf3 100644 +index 249c0f717a80b9ca8e200ebdbf72a0dc4c3730cc..6e8351363af9aea752286311074d53f245196e8d 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -323,7 +323,13 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0430-Fix-Player-spawnParticle-x-y-z-precision-loss.patch b/patches/server/0430-Fix-Player-spawnParticle-x-y-z-precision-loss.patch index 185bc677aca8..535ffd4869a1 100644 --- a/patches/server/0430-Fix-Player-spawnParticle-x-y-z-precision-loss.patch +++ b/patches/server/0430-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 eb2954c9b51d4fd76cf5aec17899218f4de7076d..786b8c10a647d777b951b760e4c51eef057b2edd 100644 +index 9042bbcfb161d91b1e2c4d6e0461f141fa41872e..8d9c2c58f7216e1ae7dc382732bd6920c7c72e5c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2720,7 +2720,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2734,7 +2734,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public 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/0438-Limit-recipe-packets.patch b/patches/server/0438-Limit-recipe-packets.patch index 5ce5387ca5c6..d2270026989f 100644 --- a/patches/server/0438-Limit-recipe-packets.patch +++ b/patches/server/0438-Limit-recipe-packets.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Limit recipe packets diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index e3e43c361d8612dbc79fe88730a3794eb44d85e4..b61cb778196a31df2139deb31dfd924abc6e5d1c 100644 +index a45078fc6a63742682040518e419fe0e2f704065..bca6e44c6a6584be2537d8be1279497b3394c447 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -275,6 +275,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -277,6 +277,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private final TickThrottler chatSpamThrottler = new TickThrottler(20, 200); private final TickThrottler tabSpamThrottler = new TickThrottler(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamIncrement, io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamLimit); // Paper - configurable tab spam limits private final TickThrottler dropSpamThrottler = new TickThrottler(20, 1480); @@ -16,7 +16,7 @@ index e3e43c361d8612dbc79fe88730a3794eb44d85e4..b61cb778196a31df2139deb31dfd924a private double firstGoodX; private double firstGoodY; private double firstGoodZ; -@@ -391,6 +392,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -393,6 +394,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.keepConnectionAlive(); this.chatSpamThrottler.tick(); this.tabSpamThrottler.tick(); // Paper - configurable tab spam limits @@ -24,7 +24,7 @@ index e3e43c361d8612dbc79fe88730a3794eb44d85e4..b61cb778196a31df2139deb31dfd924a this.dropSpamThrottler.tick(); if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L) { this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 -@@ -3083,6 +3085,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3091,6 +3093,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handlePlaceRecipe(ServerboundPlaceRecipePacket packet) { diff --git a/patches/server/0452-Fix-interact-event-not-being-called-sometimes.patch b/patches/server/0452-Fix-interact-event-not-being-called-sometimes.patch index 9aa0d988fa1b..aba682dc6c5d 100644 --- a/patches/server/0452-Fix-interact-event-not-being-called-sometimes.patch +++ b/patches/server/0452-Fix-interact-event-not-being-called-sometimes.patch @@ -11,10 +11,10 @@ Subject: [PATCH] Fix interact event not being called sometimes Co-authored-by: Moulberry diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index b61cb778196a31df2139deb31dfd924abc6e5d1c..0c413f4981038c5c3f12ba17309ce354c3f13ec6 100644 +index bca6e44c6a6584be2537d8be1279497b3394c447..0254ca5ed57de292ecd17900bb4f3d2874e12556 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1777,7 +1777,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1785,7 +1785,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } else if (enuminteractionresult instanceof InteractionResult.Success) { InteractionResult.Success enuminteractionresult_d = (InteractionResult.Success) enuminteractionresult; @@ -23,7 +23,7 @@ index b61cb778196a31df2139deb31dfd924abc6e5d1c..0c413f4981038c5c3f12ba17309ce354 this.player.swing(enumhand, true); } } -@@ -2401,13 +2401,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2409,13 +2409,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl double d3 = Math.max(this.player.blockInteractionRange(), this.player.entityInteractionRange()); // SPIGOT-5607: Only call interact event if no block or entity is being clicked. Use bukkit ray trace method, because it handles blocks and entities at the same time // SPIGOT-7429: Make sure to call PlayerInteractEvent for spectators and non-pickable entities diff --git a/patches/server/0466-Add-sendOpLevel-API.patch b/patches/server/0466-Add-sendOpLevel-API.patch index e37d133769b0..e10d6a9c4faf 100644 --- a/patches/server/0466-Add-sendOpLevel-API.patch +++ b/patches/server/0466-Add-sendOpLevel-API.patch @@ -32,10 +32,10 @@ index 70b7871091ab9b64d2a5503620a71c3d5585c25d..7676dbe55b4bf6e0472dc0190c01e6ec 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 786b8c10a647d777b951b760e4c51eef057b2edd..678099cdcf418b9e3eafed965384e6dcdd9404e3 100644 +index 8d9c2c58f7216e1ae7dc382732bd6920c7c72e5c..680909750f9db56d3cc062b63913e3bd9f69d8a5 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -690,6 +690,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -694,6 +694,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end diff --git a/patches/server/0495-Allow-using-signs-inside-spawn-protection.patch b/patches/server/0495-Allow-using-signs-inside-spawn-protection.patch index 84ca07a4a1fc..09955d8b696c 100644 --- a/patches/server/0495-Allow-using-signs-inside-spawn-protection.patch +++ b/patches/server/0495-Allow-using-signs-inside-spawn-protection.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Allow using signs inside spawn protection diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 0c413f4981038c5c3f12ba17309ce354c3f13ec6..628260aa644539a966e4cc5acf8da34144fcabd0 100644 +index 0254ca5ed57de292ecd17900bb4f3d2874e12556..d93dfaf50c48b1975d59f9aa24b895f151d2e1b1 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1762,7 +1762,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1770,7 +1770,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl int i = this.player.level().getMaxY(); if (blockposition.getY() <= i) { diff --git a/patches/server/0496-Expand-world-key-API.patch b/patches/server/0496-Expand-world-key-API.patch index beef58646723..da317765ced6 100644 --- a/patches/server/0496-Expand-world-key-API.patch +++ b/patches/server/0496-Expand-world-key-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Expand world key API diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index 93dadbf659e41c923268d8ec782fcbdc8aaeff68..21e5dd6624e50dec35859b7d1be4a304e4427883 100644 +index 15da29058f80a2d7cf2be26c48421c1746815a10..a070b2a83edaa702b13bc6d3026914126c211576 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -@@ -515,5 +515,10 @@ public abstract class CraftRegionAccessor implements RegionAccessor { +@@ -521,5 +521,10 @@ public abstract class CraftRegionAccessor implements RegionAccessor { public io.papermc.paper.world.MoonPhase getMoonPhase() { return io.papermc.paper.world.MoonPhase.getPhase(this.getHandle().dayTime() / 24000L); } @@ -67,7 +67,7 @@ index ee231d93d216571a45b11b49663b2ea91c47a1c7..dc20a383950a72aba5d056912d257912 // Check if a World already exists with the UID. if (this.getWorld(world.getUID()) != null) { diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index ea9c9ae832c4044a2eccbf901e20ff042df68bf3..407fa9f1f3d418597eb490e2cf41aee39c715d3a 100644 +index 6e8351363af9aea752286311074d53f245196e8d..e53610ac0ef0c80932e6e50f0c3971938b4bcf9b 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -522,6 +522,11 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0500-Don-t-ignore-result-of-PlayerEditBookEvent.patch b/patches/server/0500-Don-t-ignore-result-of-PlayerEditBookEvent.patch index 1946415e7218..17de34812a40 100644 --- a/patches/server/0500-Don-t-ignore-result-of-PlayerEditBookEvent.patch +++ b/patches/server/0500-Don-t-ignore-result-of-PlayerEditBookEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Don't ignore result of PlayerEditBookEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 628260aa644539a966e4cc5acf8da34144fcabd0..ed6c07cfa69788eb6adcaf8293b2ca2040f057a0 100644 +index d93dfaf50c48b1975d59f9aa24b895f151d2e1b1..c753af9216fae7aa78247f18c064aa2f0f579fcf 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1157,7 +1157,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1165,7 +1165,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl List> list1 = pages.stream().map(this::filterableFromOutgoing).toList(); itemstack.set(DataComponents.WRITABLE_BOOK_CONTENT, new WritableBookContent(list1)); diff --git a/patches/server/0501-Expose-protocol-version.patch b/patches/server/0501-Expose-protocol-version.patch index 1cc14ceba20b..2dcd012c6cfb 100644 --- a/patches/server/0501-Expose-protocol-version.patch +++ b/patches/server/0501-Expose-protocol-version.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Expose protocol version diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 407fa9f1f3d418597eb490e2cf41aee39c715d3a..2f7cb2bd5998204d61c9d758224b3a2e3351de48 100644 +index e53610ac0ef0c80932e6e50f0c3971938b4bcf9b..e546cf93d79b109d50840ebf1fb133ad3c9331d3 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -527,6 +527,11 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0508-add-get-set-drop-chance-to-EntityEquipment.patch b/patches/server/0508-add-get-set-drop-chance-to-EntityEquipment.patch index 0b6de6ac3adf..e7944704100c 100644 --- a/patches/server/0508-add-get-set-drop-chance-to-EntityEquipment.patch +++ b/patches/server/0508-add-get-set-drop-chance-to-EntityEquipment.patch @@ -51,7 +51,7 @@ index cb704cef3845727c465fe3ea7210a11545da56c8..fdcc414f4fa246082ad0732133c870d9 } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java -index b6dbdabcf0fbf9fae8d995fef291ae0aaaa92d2c..5e40faa88c51b0ebd76493fd1731d16ca1051f4a 100644 +index f039c5041e783ef55e19194cb7db7610429b1d96..107fa1d4bd977d17dc062da280dda46eb3c5f81c 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java @@ -353,4 +353,15 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i diff --git a/patches/server/0510-fix-PlayerItemHeldEvent-firing-twice.patch b/patches/server/0510-fix-PlayerItemHeldEvent-firing-twice.patch index d089fabba84d..33e91362d911 100644 --- a/patches/server/0510-fix-PlayerItemHeldEvent-firing-twice.patch +++ b/patches/server/0510-fix-PlayerItemHeldEvent-firing-twice.patch @@ -5,10 +5,10 @@ Subject: [PATCH] fix PlayerItemHeldEvent firing twice diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index ed6c07cfa69788eb6adcaf8293b2ca2040f057a0..04fed7cee8ea816c194dc1d38f82c2c04d2abc23 100644 +index c753af9216fae7aa78247f18c064aa2f0f579fcf..e6a927e991779bad84a02d81010057a4e36b9c95 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1946,6 +1946,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1954,6 +1954,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (this.player.isImmobile()) return; // CraftBukkit if (packet.getSlot() >= 0 && packet.getSlot() < Inventory.getSelectionSize()) { diff --git a/patches/server/0527-Expand-PlayerGameModeChangeEvent.patch b/patches/server/0527-Expand-PlayerGameModeChangeEvent.patch index af1d58d2f529..c9ccc145c007 100644 --- a/patches/server/0527-Expand-PlayerGameModeChangeEvent.patch +++ b/patches/server/0527-Expand-PlayerGameModeChangeEvent.patch @@ -134,10 +134,10 @@ index 546be40a8e4470fb5a6686072cdd342cdaa6fe15..e000a918230187f6841b03b7b0dd7368 } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 04fed7cee8ea816c194dc1d38f82c2c04d2abc23..e07f859a407bdf799bfd79f4bec3c7c4f505c4b8 100644 +index e6a927e991779bad84a02d81010057a4e36b9c95..9007a0f01b823c613c39c974d9e0f5858cd40d15 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2746,7 +2746,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2754,7 +2754,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player = this.server.getPlayerList().respawn(this.player, false, Entity.RemovalReason.KILLED, RespawnReason.DEATH); // CraftBukkit this.resetPosition(); if (this.server.isHardcore()) { @@ -147,10 +147,10 @@ index 04fed7cee8ea816c194dc1d38f82c2c04d2abc23..e07f859a407bdf799bfd79f4bec3c7c4 } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 678099cdcf418b9e3eafed965384e6dcdd9404e3..b54b773a4e1472f94c5c28188f706fbeb2cfb067 100644 +index 680909750f9db56d3cc062b63913e3bd9f69d8a5..3cb6f46492a3441c09a452836d01c15d1837f6ea 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1667,7 +1667,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1681,7 +1681,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { Preconditions.checkArgument(mode != null, "GameMode cannot be null"); if (this.getHandle().connection == null) return; diff --git a/patches/server/0528-ItemStack-repair-check-API.patch b/patches/server/0528-ItemStack-repair-check-API.patch index 14d115481919..cd4d72339316 100644 --- a/patches/server/0528-ItemStack-repair-check-API.patch +++ b/patches/server/0528-ItemStack-repair-check-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] ItemStack repair check API diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 2f7cb2bd5998204d61c9d758224b3a2e3351de48..b791cb8c78b92163cf261a460b39b724e568013c 100644 +index e546cf93d79b109d50840ebf1fb133ad3c9331d3..1ae77ef4bd47a4aea894242cd48dbf042477da33 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -532,6 +532,14 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0530-Move-range-check-for-block-placing-up.patch b/patches/server/0530-Move-range-check-for-block-placing-up.patch index a6de02452f99..4cedf6b84bda 100644 --- a/patches/server/0530-Move-range-check-for-block-placing-up.patch +++ b/patches/server/0530-Move-range-check-for-block-placing-up.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Move range check for block placing up diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index e07f859a407bdf799bfd79f4bec3c7c4f505c4b8..8080ef483a49bfeeaad8d69276684ee08198b1e9 100644 +index 9007a0f01b823c613c39c974d9e0f5858cd40d15..6839d13bc5cfad7c408d55e0cd477085333c7e41 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1749,6 +1749,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1757,6 +1757,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (itemstack.isItemEnabled(worldserver.enabledFeatures())) { BlockHitResult movingobjectpositionblock = packet.getHitResult(); Vec3 vec3d = movingobjectpositionblock.getLocation(); diff --git a/patches/server/0533-Add-Unix-domain-socket-support.patch b/patches/server/0533-Add-Unix-domain-socket-support.patch index de6a5f626d93..a2359131a00a 100644 --- a/patches/server/0533-Add-Unix-domain-socket-support.patch +++ b/patches/server/0533-Add-Unix-domain-socket-support.patch @@ -87,10 +87,10 @@ index d6d7f1c446ba5507f67038ff27775ba75156f4a7..c63c194c44646e6bc1a5942655278701 } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 8080ef483a49bfeeaad8d69276684ee08198b1e9..7990bd0279839558bed18a3dca7739ef74ecb74a 100644 +index 6839d13bc5cfad7c408d55e0cd477085333c7e41..674149f3a392a600a506e55f20db044619328cd2 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2561,6 +2561,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2569,6 +2569,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Spigot Start public SocketAddress getRawAddress() { diff --git a/patches/server/0535-Improve-item-default-attribute-API.patch b/patches/server/0535-Improve-item-default-attribute-API.patch index 3eca60ef25d1..c9eb3843be35 100644 --- a/patches/server/0535-Improve-item-default-attribute-API.patch +++ b/patches/server/0535-Improve-item-default-attribute-API.patch @@ -62,7 +62,7 @@ index 68756419ac6ee292db9569eab380a5c14d748002..6d76cc1db3ac3f1ae74c13511937fb86 return defaultAttributes.build(); } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index b791cb8c78b92163cf261a460b39b724e568013c..821f9a2780dc6fa9926fadbec18b51a915767730 100644 +index 1ae77ef4bd47a4aea894242cd48dbf042477da33..0d9c90a99aa2d8fcf421680aeef4c2fd7ec0fd57 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -391,7 +391,11 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0539-Add-PlayerKickEvent-causes.patch b/patches/server/0539-Add-PlayerKickEvent-causes.patch index 16f523acdd20..80eabf642506 100644 --- a/patches/server/0539-Add-PlayerKickEvent-causes.patch +++ b/patches/server/0539-Add-PlayerKickEvent-causes.patch @@ -229,10 +229,10 @@ index f8ae8c8eff73e4e87eb34d0f2635517f1688a6f1..59d20fd62e850a38380d877cef95ed69 if (this.cserver.getServer().isRunning()) { this.cserver.getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146ed4bd2b52 100644 +index 674149f3a392a600a506e55f20db044619328cd2..0fb16f3193c88c5f58d16aaf85129bbfd01fdfcd 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -357,7 +357,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -359,7 +359,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (this.clientIsFloating && !this.player.isSleeping() && !this.player.isPassenger() && !this.player.isDeadOrDying()) { if (++this.aboveGroundTickCount > this.getMaximumFlyingTicks(this.player)) { ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked for floating too long!", this.player.getName().getString()); @@ -241,7 +241,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e return; } } else { -@@ -376,7 +376,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -378,7 +378,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (this.clientVehicleIsFloating && this.lastVehicle.getControllingPassenger() == this.player) { if (++this.aboveGroundVehicleTickCount > this.getMaximumFlyingTicks(this.lastVehicle)) { ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked for floating a vehicle too long!", this.player.getName().getString()); @@ -250,7 +250,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e return; } } else { -@@ -396,7 +396,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -398,7 +398,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.dropSpamThrottler.tick(); if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L) { this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 @@ -259,7 +259,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e } } -@@ -478,7 +478,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -486,7 +486,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void handleMoveVehicle(ServerboundMoveVehiclePacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (ServerGamePacketListenerImpl.containsInvalidValues(packet.getX(), packet.getY(), packet.getZ(), packet.getYRot(), packet.getXRot())) { @@ -268,7 +268,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e } else if (!this.updateAwaitingTeleport()) { Entity entity = this.player.getRootVehicle(); -@@ -684,7 +684,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -692,7 +692,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (packet.getId() == this.awaitingTeleport) { if (this.awaitingPositionFromClient == null) { @@ -277,7 +277,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e return; } -@@ -748,7 +748,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -756,7 +756,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async // CraftBukkit start if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - configurable tab spam limits @@ -286,7 +286,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e return; } // CraftBukkit end -@@ -913,7 +913,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -921,7 +921,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Paper start - validate pick item position if (!(packet.getSlot() >= 0 && packet.getSlot() < this.player.getInventory().items.size())) { ServerGamePacketListenerImpl.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString()); @@ -295,7 +295,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e return; } this.player.getInventory().pickSlot(packet.getSlot()); // Paper - Diff above if changed -@@ -1116,14 +1116,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1124,14 +1124,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (byteTotal > byteAllowed) { ServerGamePacketListenerImpl.LOGGER.warn("{} tried to send a book too large. Book size: {} - Allowed: {} - Pages: {}", this.player.getScoreboardName(), byteTotal, byteAllowed, pageList.size()); @@ -312,7 +312,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e return; } this.lastBookTick = MinecraftServer.currentTick; -@@ -1232,7 +1232,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1240,7 +1240,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void handleMovePlayer(ServerboundMovePlayerPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (ServerGamePacketListenerImpl.containsInvalidValues(packet.getX(0.0D), packet.getY(0.0D), packet.getZ(0.0D), packet.getYRot(0.0F), packet.getXRot(0.0F))) { @@ -321,7 +321,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e } else { ServerLevel worldserver = this.player.serverLevel(); -@@ -1671,7 +1671,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1679,7 +1679,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.dropCount++; if (this.dropCount >= 20) { ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " dropped their items too quickly!"); @@ -330,7 +330,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e return; } } -@@ -1968,7 +1968,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1976,7 +1976,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.resetLastActionTime(); } else { ServerGamePacketListenerImpl.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString()); @@ -339,7 +339,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e } } -@@ -2166,7 +2166,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2174,7 +2174,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private void tryHandleChat(String s, Runnable runnable, boolean sync) { // CraftBukkit if (ServerGamePacketListenerImpl.isChatMessageIllegal(s)) { @@ -348,7 +348,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e } else if (this.player.isRemoved() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) { // CraftBukkit - dead men tell no tales this.send(new ClientboundSystemChatPacket(Component.translatable("chat.disabled.options").withStyle(ChatFormatting.RED), false)); } else { -@@ -2189,7 +2189,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2197,7 +2197,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (optional.isEmpty()) { ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString()); @@ -357,7 +357,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e } return optional; -@@ -2373,7 +2373,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2381,7 +2381,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // this.chatSpamThrottler.increment(); if (!this.chatSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // CraftBukkit end @@ -366,7 +366,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e } } -@@ -2385,7 +2385,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2393,7 +2393,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl synchronized (this.lastSeenMessages) { if (!this.lastSeenMessages.applyOffset(packet.offset())) { ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString()); @@ -375,7 +375,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e } } -@@ -2533,7 +2533,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2541,7 +2541,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } if (i > 4096) { @@ -384,7 +384,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e } } -@@ -2591,7 +2591,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2599,7 +2599,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Spigot Start if ( entity == this.player && !this.player.isSpectator() ) { @@ -393,7 +393,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e return; } // Spigot End -@@ -2707,7 +2707,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2715,7 +2715,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } @@ -402,7 +402,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e ServerGamePacketListenerImpl.LOGGER.warn("Player {} tried to attack an invalid entity", ServerGamePacketListenerImpl.this.player.getName().getString()); } }); -@@ -3106,7 +3106,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3114,7 +3114,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Paper start - auto recipe limit if (!org.bukkit.Bukkit.isPrimaryThread()) { if (!this.recipeSpamPackets.isIncrementAndUnderThreshold()) { @@ -411,7 +411,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e return; } } -@@ -3377,7 +3377,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3385,7 +3385,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (!Objects.equals(profilepublickey_a, profilepublickey_a1)) { if (profilepublickey_a != null && profilepublickey_a1.expiresAt().isBefore(profilepublickey_a.expiresAt())) { @@ -420,7 +420,7 @@ index 7990bd0279839558bed18a3dca7739ef74ecb74a..f4d92374f7865a39a0442d79eb5f146e } else { try { SignatureValidator signaturevalidator = this.server.getProfileKeySignatureValidator(); -@@ -3390,7 +3390,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3398,7 +3398,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.resetPlayerChatState(remotechatsession_a.validate(this.player.getGameProfile(), signaturevalidator)); } catch (ProfilePublicKey.ValidationException profilepublickey_b) { ServerGamePacketListenerImpl.LOGGER.error("Failed to validate profile key: {}", profilepublickey_b.getMessage()); @@ -495,10 +495,10 @@ index 9e2ad78b12cadbf0e2bda1e12fe844120529c347..6a7d7fad990fc44fdda6849d43dad141 } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index b54b773a4e1472f94c5c28188f706fbeb2cfb067..5347ad30130d598644902cdc8902e0b77ac4dfb1 100644 +index 3cb6f46492a3441c09a452836d01c15d1837f6ea..4b28318dbdeb3fa5935949740343c996d30aa2dd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -276,7 +276,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -280,7 +280,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { void sendPacket(Packet packet); @@ -507,7 +507,7 @@ index b54b773a4e1472f94c5c28188f706fbeb2cfb067..5347ad30130d598644902cdc8902e0b7 } public record CookieFuture(ResourceLocation key, CompletableFuture future) { -@@ -648,7 +648,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -652,7 +652,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void kickPlayer(String message) { org.spigotmc.AsyncCatcher.catchOp("player kick"); // Spigot @@ -516,7 +516,7 @@ index b54b773a4e1472f94c5c28188f706fbeb2cfb067..5347ad30130d598644902cdc8902e0b7 } // Paper start -@@ -660,10 +660,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -664,10 +664,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void kick(final net.kyori.adventure.text.Component message) { @@ -533,7 +533,7 @@ index b54b773a4e1472f94c5c28188f706fbeb2cfb067..5347ad30130d598644902cdc8902e0b7 } } -@@ -722,7 +727,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -726,7 +731,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Paper start - Improve chat handling if (ServerGamePacketListenerImpl.isChatMessageIllegal(msg)) { diff --git a/patches/server/0548-Line-Of-Sight-Changes.patch b/patches/server/0548-Line-Of-Sight-Changes.patch index 08eb10296bd0..2b40552d3f89 100644 --- a/patches/server/0548-Line-Of-Sight-Changes.patch +++ b/patches/server/0548-Line-Of-Sight-Changes.patch @@ -19,10 +19,10 @@ index b7cc3d84c724772e3e1250c5e99bb32e01112220..eeed7d1d4b7fee0e8ab1f43f9b7ec6f7 } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index 21e5dd6624e50dec35859b7d1be4a304e4427883..123824f6b8306900ed5c0b3addb884301dbcab7e 100644 +index a070b2a83edaa702b13bc6d3026914126c211576..ca35e93239eea09b3d0dc6ef18f58743e633996b 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -@@ -520,5 +520,21 @@ public abstract class CraftRegionAccessor implements RegionAccessor { +@@ -526,5 +526,21 @@ public abstract class CraftRegionAccessor implements RegionAccessor { public org.bukkit.NamespacedKey getKey() { return org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(this.getHandle().getLevel().dimension().location()); } diff --git a/patches/server/0557-Add-PlayerArmSwingEvent.patch b/patches/server/0557-Add-PlayerArmSwingEvent.patch index 0b60bfb4b9e5..c334885378ce 100644 --- a/patches/server/0557-Add-PlayerArmSwingEvent.patch +++ b/patches/server/0557-Add-PlayerArmSwingEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerArmSwingEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index f4d92374f7865a39a0442d79eb5f146ed4bd2b52..c8ab002ddfcea910f916ee503e930085f6c5cb5a 100644 +index 0fb16f3193c88c5f58d16aaf85129bbfd01fdfcd..7e11789a8d64b112c5eb354a30ae9618722526b1 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2423,7 +2423,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2431,7 +2431,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // Paper end - Call interact event // Arm swing animation diff --git a/patches/server/0558-Fix-kick-event-leave-message-not-being-sent.patch b/patches/server/0558-Fix-kick-event-leave-message-not-being-sent.patch index 837a22ba70f1..0068fffc6ea8 100644 --- a/patches/server/0558-Fix-kick-event-leave-message-not-being-sent.patch +++ b/patches/server/0558-Fix-kick-event-leave-message-not-being-sent.patch @@ -55,10 +55,10 @@ index 59d20fd62e850a38380d877cef95ed69cb46ecbd..fc242acade3ff06c9213428cde103cf0 MinecraftServer minecraftserver = this.server; Connection networkmanager = this.connection; diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index c8ab002ddfcea910f916ee503e930085f6c5cb5a..e9e5b35cd09fe50ce4f2116ca5c38137408105bf 100644 +index 7e11789a8d64b112c5eb354a30ae9618722526b1..a550f23227770001862e5e837ab2f09e746d76f1 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1907,6 +1907,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1915,6 +1915,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void onDisconnect(DisconnectionDetails info) { @@ -71,7 +71,7 @@ index c8ab002ddfcea910f916ee503e930085f6c5cb5a..e9e5b35cd09fe50ce4f2116ca5c38137 // CraftBukkit start - Rarely it would send a disconnect line twice if (this.processedDisconnect) { return; -@@ -1915,11 +1921,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1923,11 +1929,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // CraftBukkit end ServerGamePacketListenerImpl.LOGGER.info("{} lost connection: {}", this.player.getName().getString(), info.reason().getString()); @@ -91,7 +91,7 @@ index c8ab002ddfcea910f916ee503e930085f6c5cb5a..e9e5b35cd09fe50ce4f2116ca5c38137 this.chatMessageChain.close(); // CraftBukkit start - Replace vanilla quit message handling with our own. /* -@@ -1929,7 +1941,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1937,7 +1949,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.disconnect(); // Paper start - Adventure diff --git a/patches/server/0564-Prevent-AFK-kick-while-watching-end-credits.patch b/patches/server/0564-Prevent-AFK-kick-while-watching-end-credits.patch index a717ad883a1e..3413c09bdaa6 100644 --- a/patches/server/0564-Prevent-AFK-kick-while-watching-end-credits.patch +++ b/patches/server/0564-Prevent-AFK-kick-while-watching-end-credits.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent AFK kick while watching end credits diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index e9e5b35cd09fe50ce4f2116ca5c38137408105bf..74b21852d9346708a62033c78fac04050b98c80b 100644 +index a550f23227770001862e5e837ab2f09e746d76f1..ea793f9ccf3082a7abcb003b9df03901f9b4c0f0 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -394,7 +394,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -396,7 +396,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.tabSpamThrottler.tick(); // Paper - configurable tab spam limits this.recipeSpamPackets.tick(); // Paper - auto recipe limit this.dropSpamThrottler.tick(); diff --git a/patches/server/0566-Add-PlayerSetSpawnEvent.patch b/patches/server/0566-Add-PlayerSetSpawnEvent.patch index 11ac225f5643..ddf33c1b0dd1 100644 --- a/patches/server/0566-Add-PlayerSetSpawnEvent.patch +++ b/patches/server/0566-Add-PlayerSetSpawnEvent.patch @@ -187,10 +187,10 @@ index db26b5a0464bd6087eeacaf6dd61eba37365df92..9117c035d5a6ff114b028fad3380ceb1 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 5347ad30130d598644902cdc8902e0b77ac4dfb1..b3efe7391b7e43327bcca419efe72811574c0664 100644 +index 4b28318dbdeb3fa5935949740343c996d30aa2dd..eacfcaee0f534ff63c723af11517e6c895bc84ed 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1426,9 +1426,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1430,9 +1430,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setRespawnLocation(Location location, boolean override) { if (location == null) { diff --git a/patches/server/0580-Get-entity-default-attributes.patch b/patches/server/0580-Get-entity-default-attributes.patch index 0c9552e4ca6c..d383f32269c9 100644 --- a/patches/server/0580-Get-entity-default-attributes.patch +++ b/patches/server/0580-Get-entity-default-attributes.patch @@ -81,7 +81,7 @@ index 0000000000000000000000000000000000000000..ec9ebd2d539333293c51b7edfa18f18b + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 821f9a2780dc6fa9926fadbec18b51a915767730..d6e9eccd5edce73c9be99e1b9becadf89c593035 100644 +index 0d9c90a99aa2d8fcf421680aeef4c2fd7ec0fd57..5c0a6d93b424db91a5f6474165434f5db3d15a8a 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -544,6 +544,18 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch b/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch index 7519082dc250..34f5031fb4df 100644 --- a/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch +++ b/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch @@ -50,7 +50,7 @@ index 0c1c9033646dedcf1d11dee74d6965683adadf0a..1ed01978611cddb2558e441863dadc46 @Override public boolean isInvisible() { // Paper - moved up from LivingEntity diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index d6e9eccd5edce73c9be99e1b9becadf89c593035..98bbbdbf8fd067df936655334ad5ea25ec07daef 100644 +index 5c0a6d93b424db91a5f6474165434f5db3d15a8a..e2873a1eeb01516b689d0175b091808b2797995f 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -494,7 +494,33 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0593-Improve-and-expand-AsyncCatcher.patch b/patches/server/0593-Improve-and-expand-AsyncCatcher.patch index 136d3b3fdbc1..3a42eb978d43 100644 --- a/patches/server/0593-Improve-and-expand-AsyncCatcher.patch +++ b/patches/server/0593-Improve-and-expand-AsyncCatcher.patch @@ -17,10 +17,10 @@ Async catch modifications to critical entity state Co-authored-by: Jake Potrebic diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 74b21852d9346708a62033c78fac04050b98c80b..020aed78c0eb1fdb9fd0d633bf2fe45bb9eb7532 100644 +index ea793f9ccf3082a7abcb003b9df03901f9b4c0f0..8084bf547a52f3e5c890d2be3757acb364370d34 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1589,6 +1589,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1597,6 +1597,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } public void internalTeleport(PositionMoveRotation positionmoverotation, Set set) { diff --git a/patches/server/0607-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch b/patches/server/0607-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch index e07fa22e0550..60d634041c8e 100644 --- a/patches/server/0607-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch +++ b/patches/server/0607-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Don't respond to ServerboundCommandSuggestionPacket when diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 020aed78c0eb1fdb9fd0d633bf2fe45bb9eb7532..7b858178ce7d0e33fec17311f1710bead5f0837d 100644 +index 8084bf547a52f3e5c890d2be3757acb364370d34..0790d904a408652c593dc8d87b1b2087169e7490 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -752,6 +752,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -760,6 +760,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return; } // CraftBukkit end diff --git a/patches/server/0649-Multi-Block-Change-API-Implementation.patch b/patches/server/0649-Multi-Block-Change-API-Implementation.patch index 75fd9baa246a..7a27fe0df9ae 100644 --- a/patches/server/0649-Multi-Block-Change-API-Implementation.patch +++ b/patches/server/0649-Multi-Block-Change-API-Implementation.patch @@ -24,10 +24,10 @@ index 926ff9be3d9e3f5d620e4c7ccb22b9f64865ff8c..1a37654aff9a9c86c9f7af10a1cf7213 buf.writeLong(this.sectionPos.asLong()); buf.writeVarInt(this.positions.length); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index b3efe7391b7e43327bcca419efe72811574c0664..2347e260780d4703cff01b84a7971861fd924b20 100644 +index eacfcaee0f534ff63c723af11517e6c895bc84ed..0bb2a75b2dd3d6d5d7815d3f4b1d8b11b002db62 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -943,6 +943,32 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -947,6 +947,32 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().connection.send(packet); } diff --git a/patches/server/0665-Custom-Potion-Mixes.patch b/patches/server/0665-Custom-Potion-Mixes.patch index 5ff6d9302329..1e7656e306a6 100644 --- a/patches/server/0665-Custom-Potion-Mixes.patch +++ b/patches/server/0665-Custom-Potion-Mixes.patch @@ -312,7 +312,7 @@ index 29a71a050e49f1131ce9945c4275a33909ea3091..f0eb8284b537014b591e45f034f1498e // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java -index 6f1da5aa8714d64b8454dc79258f941ead986e46..a68e036a12b354c4f04b6596dfb9cd6e7663718b 100644 +index 6d955c0d2ae166fb39fa38c604729c9a66132352..a30950287646524c4906574d193ec7ce94b4eb34 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java @@ -25,6 +25,11 @@ public interface CraftRecipe extends Recipe { diff --git a/patches/server/0672-Don-t-allow-vehicle-movement-from-players-while-tele.patch b/patches/server/0672-Don-t-allow-vehicle-movement-from-players-while-tele.patch index b0a250292cc3..c8f2f8a3b8e1 100644 --- a/patches/server/0672-Don-t-allow-vehicle-movement-from-players-while-tele.patch +++ b/patches/server/0672-Don-t-allow-vehicle-movement-from-players-while-tele.patch @@ -7,10 +7,10 @@ Bring the vehicle move packet behavior in line with the regular player move packet. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 7b858178ce7d0e33fec17311f1710bead5f0837d..33f76a6df7997ecdc789004bf0b230e74ad07f5a 100644 +index 0790d904a408652c593dc8d87b1b2087169e7490..65e0ad4cae47a1912ad12ea1e6eaa3672d4f12e8 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -481,6 +481,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -489,6 +489,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.disconnect((Component) Component.translatable("multiplayer.disconnect.invalid_vehicle_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_VEHICLE_MOVEMENT); // Paper - kick event cause } else if (!this.updateAwaitingTeleport()) { Entity entity = this.player.getRootVehicle(); diff --git a/patches/server/0673-Implement-getComputedBiome-API.patch b/patches/server/0673-Implement-getComputedBiome-API.patch index 3028eee933bf..dab55a6218f9 100644 --- a/patches/server/0673-Implement-getComputedBiome-API.patch +++ b/patches/server/0673-Implement-getComputedBiome-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Implement getComputedBiome API diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index 123824f6b8306900ed5c0b3addb884301dbcab7e..244cff4f84792fd0efe146e6faf47db0b0a0dc87 100644 +index ca35e93239eea09b3d0dc6ef18f58743e633996b..a7748f4b7c5a1630937c702b3fd5fded93793d64 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java @@ -77,6 +77,13 @@ public abstract class CraftRegionAccessor implements RegionAccessor { diff --git a/patches/server/0674-Make-some-itemstacks-nonnull.patch b/patches/server/0674-Make-some-itemstacks-nonnull.patch index 5254271c7e54..20944d908892 100644 --- a/patches/server/0674-Make-some-itemstacks-nonnull.patch +++ b/patches/server/0674-Make-some-itemstacks-nonnull.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Make some itemstacks nonnull diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java -index 5e40faa88c51b0ebd76493fd1731d16ca1051f4a..46d0b324498510c73a8439611f44269edee62313 100644 +index 107fa1d4bd977d17dc062da280dda46eb3c5f81c..e62baea16df017f1e394e3c706157e158066eb93 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java @@ -155,13 +155,13 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i @@ -24,5 +24,5 @@ index 5e40faa88c51b0ebd76493fd1731d16ca1051f4a..46d0b324498510c73a8439611f44269e - return this.getHelmet(); + return java.util.Objects.requireNonNullElseGet(this.getHelmet(), () -> new ItemStack(org.bukkit.Material.AIR)); // Paper - make nonnull default: - throw new IllegalArgumentException("Not implemented. This is a bug"); + throw new IllegalArgumentException("Could not get slot " + slot + " - not a valid slot for PlayerInventory"); } diff --git a/patches/server/0685-Prevent-tile-entity-copies-loading-chunks.patch b/patches/server/0685-Prevent-tile-entity-copies-loading-chunks.patch index cbd52db735ca..e679734f77bb 100644 --- a/patches/server/0685-Prevent-tile-entity-copies-loading-chunks.patch +++ b/patches/server/0685-Prevent-tile-entity-copies-loading-chunks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent tile entity copies loading chunks diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 33f76a6df7997ecdc789004bf0b230e74ad07f5a..ffd8e7a537fd8c6276674f5e0034412bb93ca82c 100644 +index 65e0ad4cae47a1912ad12ea1e6eaa3672d4f12e8..ac2ad33a44ce04d9673adc08ff21a167d606e4db 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3240,7 +3240,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3248,7 +3248,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl BlockPos blockposition = BlockEntity.getPosFromTag(customdata.getUnsafe()); if (this.player.level().isLoaded(blockposition)) { diff --git a/patches/server/0716-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch b/patches/server/0716-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch index 710573f4a20e..d96ba39bb422 100644 --- a/patches/server/0716-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch +++ b/patches/server/0716-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix Spigot Config not using commands.spam-exclusions diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index ffd8e7a537fd8c6276674f5e0034412bb93ca82c..84132f9642f51e1774d6c242330deebc6dfa163a 100644 +index ac2ad33a44ce04d9673adc08ff21a167d606e4db..b34245e82306c4ce607aa984ab8f597dec2ba4b5 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2394,7 +2394,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2402,7 +2402,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // Spigot end // this.chatSpamThrottler.increment(); diff --git a/patches/server/0717-More-Teleport-API.patch b/patches/server/0717-More-Teleport-API.patch index 0454f4acd212..95e3046bb206 100644 --- a/patches/server/0717-More-Teleport-API.patch +++ b/patches/server/0717-More-Teleport-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] More Teleport API diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 84132f9642f51e1774d6c242330deebc6dfa163a..60d3a3497a49c26120650016ffff04123efa1caf 100644 +index b34245e82306c4ce607aa984ab8f597dec2ba4b5..ebe3d51ccc02b46d9bae4ba4f9185eadfec278f2 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1577,11 +1577,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1585,11 +1585,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return true; // CraftBukkit - Return event status } @@ -112,10 +112,10 @@ index 4e6afa243d6108cb946a8a7cf96c4036a3c2ac0c..43786eacc72cdf3bb209d3dfb1808ea9 private final org.bukkit.entity.Entity.Spigot spigot = new org.bukkit.entity.Entity.Spigot() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 2347e260780d4703cff01b84a7971861fd924b20..884b02409968c22b8d0926ffb195ba050f51f9bc 100644 +index 0bb2a75b2dd3d6d5d7815d3f4b1d8b11b002db62..d2029d88a4d9b060e199431ae092ce87ad5a09de 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1299,13 +1299,101 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1303,13 +1303,101 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setRotation(float yaw, float pitch) { @@ -218,7 +218,7 @@ index 2347e260780d4703cff01b84a7971861fd924b20..884b02409968c22b8d0926ffb195ba05 location.checkFinite(); ServerPlayer entity = this.getHandle(); -@@ -1318,7 +1406,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1322,7 +1410,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return false; } @@ -227,7 +227,7 @@ index 2347e260780d4703cff01b84a7971861fd924b20..884b02409968c22b8d0926ffb195ba05 return false; } -@@ -1327,7 +1415,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1331,7 +1419,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // To = Players new Location if Teleport is Successful Location to = location; // Create & Call the Teleport Event. @@ -236,7 +236,7 @@ index 2347e260780d4703cff01b84a7971861fd924b20..884b02409968c22b8d0926ffb195ba05 this.server.getPluginManager().callEvent(event); // Return False to inform the Plugin that the Teleport was unsuccessful/cancelled. -@@ -1336,7 +1424,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1340,7 +1428,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // If this player is riding another entity, we must dismount before teleporting. @@ -245,7 +245,7 @@ index 2347e260780d4703cff01b84a7971861fd924b20..884b02409968c22b8d0926ffb195ba05 // SPIGOT-5509: Wakeup, similar to riding if (this.isSleeping()) { -@@ -1352,13 +1440,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1356,13 +1444,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { ServerLevel toWorld = ((CraftWorld) to.getWorld()).getHandle(); // Close any foreign inventory diff --git a/patches/server/0720-Send-block-entities-after-destroy-prediction.patch b/patches/server/0720-Send-block-entities-after-destroy-prediction.patch index 2636e599bd6c..8cc9f6fcd486 100644 --- a/patches/server/0720-Send-block-entities-after-destroy-prediction.patch +++ b/patches/server/0720-Send-block-entities-after-destroy-prediction.patch @@ -57,10 +57,10 @@ index 5c3e5c348e6fececccd8097355f423b9e7ad982b..064a7a3e1c4d192010e072a5e985a541 } } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 60d3a3497a49c26120650016ffff04123efa1caf..5f567d6a8ac93113c2f57d38736c4891c5f9ae19 100644 +index ebe3d51ccc02b46d9bae4ba4f9185eadfec278f2..19b90fe644da59216e11b35af33e62c0fc66db7b 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1715,8 +1715,28 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1723,8 +1723,28 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return; } // Paper end - Don't allow digging into unloaded chunks diff --git a/patches/server/0722-Custom-Chat-Completion-Suggestions-API.patch b/patches/server/0722-Custom-Chat-Completion-Suggestions-API.patch index d07b1f664e1b..f1b41f3210f9 100644 --- a/patches/server/0722-Custom-Chat-Completion-Suggestions-API.patch +++ b/patches/server/0722-Custom-Chat-Completion-Suggestions-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Custom Chat Completion Suggestions API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 884b02409968c22b8d0926ffb195ba050f51f9bc..025c392f2ca89a87f6301d4af64c4d7daec58409 100644 +index d2029d88a4d9b060e199431ae092ce87ad5a09de..7fd3cb7c69aa212449739f5733de661af662611f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -704,6 +704,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -708,6 +708,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end - Add sendOpLevel API diff --git a/patches/server/0724-Collision-API.patch b/patches/server/0724-Collision-API.patch index 1d22083ef1e3..892f39211ed4 100644 --- a/patches/server/0724-Collision-API.patch +++ b/patches/server/0724-Collision-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Collision API diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index 244cff4f84792fd0efe146e6faf47db0b0a0dc87..6baa06dc0f102fe83b10015dbbe1410066961c82 100644 +index a7748f4b7c5a1630937c702b3fd5fded93793d64..a93a879117ee1eb06842242aa03f757a4a676946 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -@@ -543,5 +543,12 @@ public abstract class CraftRegionAccessor implements RegionAccessor { +@@ -549,5 +549,12 @@ public abstract class CraftRegionAccessor implements RegionAccessor { return this.getHandle().clip(new net.minecraft.world.level.ClipContext(start, end, net.minecraft.world.level.ClipContext.Block.COLLIDER, net.minecraft.world.level.ClipContext.Fluid.NONE, net.minecraft.world.phys.shapes.CollisionContext.empty())).getType() == net.minecraft.world.phys.HitResult.Type.MISS; } diff --git a/patches/server/0728-Add-NamespacedKey-biome-methods.patch b/patches/server/0728-Add-NamespacedKey-biome-methods.patch index 04815e385ef6..0991968c4d81 100644 --- a/patches/server/0728-Add-NamespacedKey-biome-methods.patch +++ b/patches/server/0728-Add-NamespacedKey-biome-methods.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add NamespacedKey biome methods Co-authored-by: Thonk <30448663+ExcessiveAmountsOfZombies@users.noreply.github.com> diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 98bbbdbf8fd067df936655334ad5ea25ec07daef..a5a3a0f0460252415c243dfe3019d103b9589c5b 100644 +index e2873a1eeb01516b689d0175b091808b2797995f..66913ab43bb1e9066487749ff60248c22fc8e824 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -584,6 +584,21 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0741-Fix-a-bunch-of-vanilla-bugs.patch b/patches/server/0741-Fix-a-bunch-of-vanilla-bugs.patch index f21808be3a25..051aef0e0efc 100644 --- a/patches/server/0741-Fix-a-bunch-of-vanilla-bugs.patch +++ b/patches/server/0741-Fix-a-bunch-of-vanilla-bugs.patch @@ -130,10 +130,10 @@ index 064a7a3e1c4d192010e072a5e985a54135748d87..a706f0855fdf88cc9aece3ba00ef574b this.player.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, this.player), this.player); // CraftBukkit this.level.updateSleepingPlayerList(); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 5f567d6a8ac93113c2f57d38736c4891c5f9ae19..6c7c6cd7c071b722faf7ec06e022a6ad8b1ecc42 100644 +index 19b90fe644da59216e11b35af33e62c0fc66db7b..8c615974a738b87116830538646750bb6f7ef7f0 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1823,7 +1823,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1831,7 +1831,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.swing(enumhand, true); } } diff --git a/patches/server/0747-Elder-Guardian-appearance-API.patch b/patches/server/0747-Elder-Guardian-appearance-API.patch index c354816072dd..75a2208ae0c3 100644 --- a/patches/server/0747-Elder-Guardian-appearance-API.patch +++ b/patches/server/0747-Elder-Guardian-appearance-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Elder Guardian appearance API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 025c392f2ca89a87f6301d4af64c4d7daec58409..1dc5f21c337bc3fb67e5919308228d75b03989d1 100644 +index 7fd3cb7c69aa212449739f5733de661af662611f..997a90a7567a90ef357530f9ed5677f0fce4d402 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3311,6 +3311,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3325,6 +3325,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end diff --git a/patches/server/0759-Add-Player-Warden-Warning-API.patch b/patches/server/0759-Add-Player-Warden-Warning-API.patch index 1ac290e09b8a..32eaa6033a74 100644 --- a/patches/server/0759-Add-Player-Warden-Warning-API.patch +++ b/patches/server/0759-Add-Player-Warden-Warning-API.patch @@ -10,10 +10,10 @@ public net.minecraft.world.entity.monster.warden.WardenSpawnTracker cooldownTick public net.minecraft.world.entity.monster.warden.WardenSpawnTracker increaseWarningLevel()V diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 1dc5f21c337bc3fb67e5919308228d75b03989d1..2c38725e6fc0a264df3a0d34c21ab774ad3e2fb5 100644 +index 997a90a7567a90ef357530f9ed5677f0fce4d402..2eafa35e87411ae0b78f445d3d0573ba6e832797 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3316,6 +3316,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3330,6 +3330,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void showElderGuardian(boolean silent) { if (getHandle().connection != null) getHandle().connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.GUARDIAN_ELDER_EFFECT, silent ? 0F : 1F)); } diff --git a/patches/server/0763-Fix-async-entity-add-due-to-fungus-trees.patch b/patches/server/0763-Fix-async-entity-add-due-to-fungus-trees.patch index 44c121394e11..009feeb37af8 100644 --- a/patches/server/0763-Fix-async-entity-add-due-to-fungus-trees.patch +++ b/patches/server/0763-Fix-async-entity-add-due-to-fungus-trees.patch @@ -17,7 +17,7 @@ index 5bf438bb58833c1df3620e82d3d2b90207366372..2e72e92762877b28dd908711671e1dfb BlockEntity tileentity = iblockdata.hasBlockEntity() ? this.getBlockEntity(pos) : null; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index 6baa06dc0f102fe83b10015dbbe1410066961c82..29825ea687827c075b87e88c45672e7b0093ed17 100644 +index a93a879117ee1eb06842242aa03f757a4a676946..4c234e887c42b27754ed8f05f2000d9309274427 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java @@ -261,10 +261,10 @@ public abstract class CraftRegionAccessor implements RegionAccessor { diff --git a/patches/server/0771-fix-Instruments.patch b/patches/server/0771-fix-Instruments.patch index 215623c640a1..194ed300cfe1 100644 --- a/patches/server/0771-fix-Instruments.patch +++ b/patches/server/0771-fix-Instruments.patch @@ -6,10 +6,10 @@ Subject: [PATCH] fix Instruments properly handle Player#playNote diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 2c38725e6fc0a264df3a0d34c21ab774ad3e2fb5..2a0ca017130a76aff3f15064a334cc0be501d782 100644 +index 2eafa35e87411ae0b78f445d3d0573ba6e832797..283e7caa8c564bb0455e29f1ee606b6993f3e57c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -781,7 +781,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -785,7 +785,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { Sound instrumentSound = instrument.getSound(); if (instrumentSound == null) return; diff --git a/patches/server/0775-Improve-logging-and-errors.patch b/patches/server/0775-Improve-logging-and-errors.patch index 4a5cccd9ae78..242eb6cb0e5c 100644 --- a/patches/server/0775-Improve-logging-and-errors.patch +++ b/patches/server/0775-Improve-logging-and-errors.patch @@ -52,10 +52,10 @@ index 4037a1057ebc87e3df6333e0d546fc85b5148d2a..eb9dab7be7da11ab1c4046a7fc4a29d5 } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 6c7c6cd7c071b722faf7ec06e022a6ad8b1ecc42..1a9003f703f6911e37a086f490d4d65ab9d27014 100644 +index 8c615974a738b87116830538646750bb6f7ef7f0..abe5490b54bda4e0767a65244c29b236a40ec8d6 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3443,7 +3443,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3451,7 +3451,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.resetPlayerChatState(remotechatsession_a.validate(this.player.getGameProfile(), signaturevalidator)); } catch (ProfilePublicKey.ValidationException profilepublickey_b) { diff --git a/patches/server/0778-Add-missing-SpigotConfig-logCommands-check.patch b/patches/server/0778-Add-missing-SpigotConfig-logCommands-check.patch index 2e59f69e0560..c4fb5944f4c5 100644 --- a/patches/server/0778-Add-missing-SpigotConfig-logCommands-check.patch +++ b/patches/server/0778-Add-missing-SpigotConfig-logCommands-check.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add missing SpigotConfig logCommands check Co-authored-by: david diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 1a9003f703f6911e37a086f490d4d65ab9d27014..e29cae56ddeb019d2ffd8dad412fd32e4db67091 100644 +index abe5490b54bda4e0767a65244c29b236a40ec8d6..984ee21a6fc59efeabc2e5eeedced548d03f413d 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2070,7 +2070,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2078,7 +2078,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private void performUnsignedChatCommand(String command) { // CraftBukkit start String command1 = "/" + command; @@ -19,7 +19,7 @@ index 1a9003f703f6911e37a086f490d4d65ab9d27014..e29cae56ddeb019d2ffd8dad412fd32e PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(this.getCraftPlayer(), command1, new LazyPlayerSet(this.server)); this.cserver.getPluginManager().callEvent(event); -@@ -2110,7 +2112,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2118,7 +2120,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private void performSignedChatCommand(ServerboundChatCommandSignedPacket packet, LastSeenMessages lastSeenMessages) { // CraftBukkit start String command = "/" + packet.command(); diff --git a/patches/server/0780-Flying-Fall-Damage.patch b/patches/server/0780-Flying-Fall-Damage.patch index d3c19b0590ff..6d32390b0350 100644 --- a/patches/server/0780-Flying-Fall-Damage.patch +++ b/patches/server/0780-Flying-Fall-Damage.patch @@ -26,10 +26,10 @@ index 30e0a5fe3f9bd85d2b702c2c877c5682ed35d461..aca888c2f02b09ac6739bdc81b194c45 } else { if (fallDistance >= 2.0F) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 2a0ca017130a76aff3f15064a334cc0be501d782..83a121331e3922ed8b90e530c2495bf19406c08d 100644 +index 283e7caa8c564bb0455e29f1ee606b6993f3e57c..d9164eda358b56fe5e3b88e9bc7e23ab39034f0f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2594,6 +2594,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2608,6 +2608,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().onUpdateAbilities(); } diff --git a/patches/server/0783-Use-single-player-info-update-packet-on-join.patch b/patches/server/0783-Use-single-player-info-update-packet-on-join.patch index 14893c3080e2..f0e844f29c15 100644 --- a/patches/server/0783-Use-single-player-info-update-packet-on-join.patch +++ b/patches/server/0783-Use-single-player-info-update-packet-on-join.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Use single player info update packet on join diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index e29cae56ddeb019d2ffd8dad412fd32e4db67091..d77ab963802fcd7551058987a534ba54f080027a 100644 +index 984ee21a6fc59efeabc2e5eeedced548d03f413d..f9dffac2a10a6d2aea488197d1302de06980d354 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3481,7 +3481,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3489,7 +3489,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.signedMessageDecoder = session.createMessageDecoder(this.player.getUUID()); this.chatMessageChain.append(() -> { this.player.setChatSession(session); diff --git a/patches/server/0785-Win-Screen-API.patch b/patches/server/0785-Win-Screen-API.patch index 330a77aa214b..f52ebd141586 100644 --- a/patches/server/0785-Win-Screen-API.patch +++ b/patches/server/0785-Win-Screen-API.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Win Screen API public net.minecraft.server.level.ServerPlayer seenCredits diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 83a121331e3922ed8b90e530c2495bf19406c08d..76d8f0d390abf588886b42b6d2e3ed6f79a4d991 100644 +index d9164eda358b56fe5e3b88e9bc7e23ab39034f0f..e6a678dee21b51d5f7005c2cf5038089447d0e7c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1318,6 +1318,25 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1322,6 +1322,25 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().connection.send(packet); } diff --git a/patches/server/0800-Treat-sequence-violations-like-they-should-be.patch b/patches/server/0800-Treat-sequence-violations-like-they-should-be.patch index 3cb7bfe53625..d881aea8c031 100644 --- a/patches/server/0800-Treat-sequence-violations-like-they-should-be.patch +++ b/patches/server/0800-Treat-sequence-violations-like-they-should-be.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Treat sequence violations like they should be diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index d77ab963802fcd7551058987a534ba54f080027a..74054e0acd2ecdc6d7ccdf035c9ec120872f6ef4 100644 +index f9dffac2a10a6d2aea488197d1302de06980d354..90392c7c87feb08711b0af80163a4ea8021448f4 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1989,6 +1989,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1997,6 +1997,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void ackBlockChangesUpTo(int sequence) { if (sequence < 0) { diff --git a/patches/server/0801-Prevent-causing-expired-keys-from-impacting-new-join.patch b/patches/server/0801-Prevent-causing-expired-keys-from-impacting-new-join.patch index 8c461c04b6b1..b1858d977593 100644 --- a/patches/server/0801-Prevent-causing-expired-keys-from-impacting-new-join.patch +++ b/patches/server/0801-Prevent-causing-expired-keys-from-impacting-new-join.patch @@ -26,10 +26,10 @@ index d0b2a8b5ded71a9a41753f4addea1c49826b34a3..29b465fc1dc50e0e84ddb889c5303e80 UPDATE_GAME_MODE((serialized, buf) -> serialized.gameMode = GameType.byId(buf.readVarInt()), (buf, entry) -> buf.writeVarInt(entry.gameMode().getId())), UPDATE_LISTED((serialized, buf) -> serialized.listed = buf.readBoolean(), (buf, entry) -> buf.writeBoolean(entry.listed())), diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 74054e0acd2ecdc6d7ccdf035c9ec120872f6ef4..5d261106b0cd12e9ed737833b1f6d2572d15ab4e 100644 +index 90392c7c87feb08711b0af80163a4ea8021448f4..eb81cd8421aa2fc011e5cb38e8a52b55fc1938b7 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -303,6 +303,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -305,6 +305,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private boolean receivedMovementThisTick; @Nullable private RemoteChatSession chatSession; @@ -37,7 +37,7 @@ index 74054e0acd2ecdc6d7ccdf035c9ec120872f6ef4..5d261106b0cd12e9ed737833b1f6d257 private SignedMessageChain.Decoder signedMessageDecoder; private final LastSeenMessagesValidator lastSeenMessages = new LastSeenMessagesValidator(20); private final MessageSignatureCache messageSignatureCache = MessageSignatureCache.createDefault(); -@@ -399,6 +400,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -401,6 +402,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.disconnect((Component) Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause } @@ -51,7 +51,7 @@ index 74054e0acd2ecdc6d7ccdf035c9ec120872f6ef4..5d261106b0cd12e9ed737833b1f6d257 } private int getMaximumFlyingTicks(Entity vehicle) { -@@ -3479,6 +3487,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3487,6 +3495,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private void resetPlayerChatState(RemoteChatSession session) { this.chatSession = session; diff --git a/patches/server/0810-Expand-PlayerItemMendEvent.patch b/patches/server/0810-Expand-PlayerItemMendEvent.patch index 12d3c700eaab..396bdd4c4535 100644 --- a/patches/server/0810-Expand-PlayerItemMendEvent.patch +++ b/patches/server/0810-Expand-PlayerItemMendEvent.patch @@ -30,10 +30,10 @@ index 3a7af27bb1ce0cbe56bd3760cd400083daf98d4c..bf0838f574fa3fb9654e087d602b8d38 if (l > 0) { // this.value = l; // CraftBukkit - update exp value of orb for PlayerItemMendEvent calls // Paper - the value field should not be mutated here because it doesn't take "count" into account diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 76d8f0d390abf588886b42b6d2e3ed6f79a4d991..cdc53abb5572fa57b4ec98a694c5583ad0982a05 100644 +index e6a678dee21b51d5f7005c2cf5038089447d0e7c..90187f6412a073a3c89da3eb01310e39406bb69c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1866,11 +1866,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1880,11 +1880,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { handle.serverLevel(), itemstack, amount ); int i = Math.min(possibleDurabilityFromXp, itemstack.getDamageValue()); diff --git a/patches/server/0829-Fix-BanList-API.patch b/patches/server/0829-Fix-BanList-API.patch index aa0028893ca3..2621cc9868e8 100644 --- a/patches/server/0829-Fix-BanList-API.patch +++ b/patches/server/0829-Fix-BanList-API.patch @@ -208,10 +208,10 @@ index 172202accf4448a933fcf1ff820316c7910dd7f7..50ee7656580d386db473c054f5c5ec57 return null; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index cdc53abb5572fa57b4ec98a694c5583ad0982a05..79e35265978357eeb27c43205433d6b24335f401 100644 +index 90187f6412a073a3c89da3eb01310e39406bb69c..78a12f857db37ec5305d6c14847bc7653669bcc0 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1760,23 +1760,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1774,23 +1774,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override @@ -240,7 +240,7 @@ index cdc53abb5572fa57b4ec98a694c5583ad0982a05..79e35265978357eeb27c43205433d6b2 if (kickPlayer) { this.kickPlayer(reason); } -@@ -1784,12 +1784,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1798,12 +1798,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override diff --git a/patches/server/0836-Implement-PlayerFailMoveEvent.patch b/patches/server/0836-Implement-PlayerFailMoveEvent.patch index 99859fc1437f..6d31aefbe8c8 100644 --- a/patches/server/0836-Implement-PlayerFailMoveEvent.patch +++ b/patches/server/0836-Implement-PlayerFailMoveEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Implement PlayerFailMoveEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 5d261106b0cd12e9ed737833b1f6d2572d15ab4e..618c620b4bca535c454691f9a87c9b36a36021e2 100644 +index eb81cd8421aa2fc011e5cb38e8a52b55fc1938b7..3b5beeb1599700fcc92f741613f84d6141078626 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1263,8 +1263,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1271,8 +1271,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl double d0 = ServerGamePacketListenerImpl.clampHorizontal(packet.getX(this.player.getX())); final double toX = d0; // Paper - OBFHELPER double d1 = ServerGamePacketListenerImpl.clampVertical(packet.getY(this.player.getY())); final double toY = d1; // Paper - OBFHELPER double d2 = ServerGamePacketListenerImpl.clampHorizontal(packet.getZ(this.player.getZ())); final double toZ = d2; // Paper - OBFHELPER @@ -19,7 +19,7 @@ index 5d261106b0cd12e9ed737833b1f6d2572d15ab4e..618c620b4bca535c454691f9a87c9b36 if (this.player.isPassenger()) { this.player.absMoveTo(this.player.getX(), this.player.getY(), this.player.getZ(), f, f1); -@@ -1331,8 +1331,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1339,8 +1339,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // Paper start - Prevent moving into unloaded chunks if (this.player.level().paperConfig().chunks.preventMovingIntoUnloadedChunks && (this.player.getX() != toX || this.player.getZ() != toZ) && !worldserver.areChunksLoadedForMove(this.player.getBoundingBox().expandTowards(new Vec3(toX, toY, toZ).subtract(this.player.position())))) { @@ -36,7 +36,7 @@ index 5d261106b0cd12e9ed737833b1f6d2572d15ab4e..618c620b4bca535c454691f9a87c9b36 } // Paper end - Prevent moving into unloaded chunks -@@ -1341,9 +1347,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1349,9 +1355,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (d10 - d9 > Math.max(f2, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2))) { // CraftBukkit end @@ -56,7 +56,7 @@ index 5d261106b0cd12e9ed737833b1f6d2572d15ab4e..618c620b4bca535c454691f9a87c9b36 } } } -@@ -1405,14 +1418,31 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1413,14 +1426,31 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl d8 = d2 - this.player.getZ(); d10 = d6 * d6 + d7 * d7 + d8 * d8; @@ -91,7 +91,7 @@ index 5d261106b0cd12e9ed737833b1f6d2572d15ab4e..618c620b4bca535c454691f9a87c9b36 this.internalTeleport(d3, d4, d5, f, f1); // CraftBukkit - SPIGOT-1807: Don't call teleport event, when the client thinks the player is falling, because the chunks are not loaded on the client yet. this.player.doCheckFallDamage(this.player.getX() - d3, this.player.getY() - d4, this.player.getZ() - d5, packet.isOnGround()); } else { -@@ -3529,4 +3559,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3537,4 +3567,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl InteractionResult run(ServerPlayer player, Entity entity, InteractionHand hand); } diff --git a/patches/server/0846-Fix-custom-statistic-criteria-creation.patch b/patches/server/0846-Fix-custom-statistic-criteria-creation.patch index 9301d80ab3f8..6e562a7f2d8d 100644 --- a/patches/server/0846-Fix-custom-statistic-criteria-creation.patch +++ b/patches/server/0846-Fix-custom-statistic-criteria-creation.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix custom statistic criteria creation diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index a5a3a0f0460252415c243dfe3019d103b9589c5b..a4998c2df341a1b9a337afb24284428cd98e59d8 100644 +index 66913ab43bb1e9066487749ff60248c22fc8e824..78b5578ece76c88a4dafcd4220a82081e85cf735 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -599,6 +599,14 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0847-Bandaid-fix-for-Effect.patch b/patches/server/0847-Bandaid-fix-for-Effect.patch index 9aec13d2df4f..c5be523db01b 100644 --- a/patches/server/0847-Bandaid-fix-for-Effect.patch +++ b/patches/server/0847-Bandaid-fix-for-Effect.patch @@ -81,10 +81,10 @@ index 03cef3e33de1cf2a1ad4c7a5ba9a65ee3b69ee52..536ad499e893c5b9898fb02582eeca54 // Special case: the axis is optional for ELECTRIC_SPARK Preconditions.checkArgument(effect.getData() == null || effect == Effect.ELECTRIC_SPARK, "Wrong kind of data for the %s effect", effect); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 79e35265978357eeb27c43205433d6b24335f401..e20e8ba103a0ba094e00ef08ff0fc3b741a9bce5 100644 +index 78a12f857db37ec5305d6c14847bc7653669bcc0..3b0d27c6c07ce4bce0b4ab8877d94a937708d2ae 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -930,7 +930,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -934,7 +934,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { Preconditions.checkArgument(effect != null, "Effect cannot be null"); if (data != null) { Preconditions.checkArgument(effect.getData() != null, "Effect.%s does not have a valid Data", effect); diff --git a/patches/server/0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch b/patches/server/0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch index 0e8de9d68d71..43c52d9c14c8 100644 --- a/patches/server/0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch +++ b/patches/server/0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch @@ -11,10 +11,10 @@ This patch prevents server from sending namespaced commands when player requests tab-complete only commands. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 618c620b4bca535c454691f9a87c9b36a36021e2..f21a5b9de17db9a094b22267b33bbffbf7ef8966 100644 +index 3b5beeb1599700fcc92f741613f84d6141078626..8e877e4cea2a14cc0a8fed41e983712645ba8c48 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -824,6 +824,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -832,6 +832,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl ParseResults parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack()); this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { diff --git a/patches/server/0855-Add-Listing-API-for-Player.patch b/patches/server/0855-Add-Listing-API-for-Player.patch index d6ed7ccd4724..815bcea717e6 100644 --- a/patches/server/0855-Add-Listing-API-for-Player.patch +++ b/patches/server/0855-Add-Listing-API-for-Player.patch @@ -122,10 +122,10 @@ index 7356a027ae3bca3a9f2056ef6849d5fab38a0df3..a4937d11b79cef41f3fbf79282c0c435 // Paper end - Use single player info update packet on join player.sentListPacket = true; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index e20e8ba103a0ba094e00ef08ff0fc3b741a9bce5..b6093a1bbd8176cde85ef034373ae71f9dd8f1c1 100644 +index 3b0d27c6c07ce4bce0b4ab8877d94a937708d2ae..2658c7a0257d7bab26d043626abb9f2310f284e2 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -202,6 +202,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -206,6 +206,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { private final ConversationTracker conversationTracker = new ConversationTracker(); private final Set channels = new HashSet(); private final Map>> invertedVisibilityEntities = new HashMap<>(); @@ -133,7 +133,7 @@ index e20e8ba103a0ba094e00ef08ff0fc3b741a9bce5..b6093a1bbd8176cde85ef034373ae71f private static final WeakHashMap> pluginWeakReferences = new WeakHashMap<>(); private int hash = 0; private double health = 20; -@@ -2105,7 +2106,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2119,7 +2120,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { otherPlayer.setUUID(uuidOverride); } // Paper end @@ -142,7 +142,7 @@ index e20e8ba103a0ba094e00ef08ff0fc3b741a9bce5..b6093a1bbd8176cde85ef034373ae71f if (original != null) otherPlayer.setUUID(original); // Paper - uuid override } -@@ -2209,6 +2210,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2223,6 +2224,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return (entity != null) ? this.canSee(entity) : false; // If we can't find it, we can't see it } diff --git a/patches/server/0861-Add-PlayerPickItemEvent.patch b/patches/server/0861-Add-PlayerPickItemEvent.patch index 747014f9648b..8309e2c11848 100644 --- a/patches/server/0861-Add-PlayerPickItemEvent.patch +++ b/patches/server/0861-Add-PlayerPickItemEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerPickItemEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index f21a5b9de17db9a094b22267b33bbffbf7ef8966..c6f51c3a1c0ff9bc6b6bfe3c7091be324a2129ed 100644 +index 8e877e4cea2a14cc0a8fed41e983712645ba8c48..d4250cc73bc51c51b78a9392a9879d47dc67f159 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -939,7 +939,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -947,7 +947,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.disconnect(Component.literal("Invalid hotbar selection (Hacking?)"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause return; } diff --git a/patches/server/0865-Implement-OfflinePlayer-isConnected.patch b/patches/server/0865-Implement-OfflinePlayer-isConnected.patch index 67483270a7b5..245ae43622e7 100644 --- a/patches/server/0865-Implement-OfflinePlayer-isConnected.patch +++ b/patches/server/0865-Implement-OfflinePlayer-isConnected.patch @@ -23,10 +23,10 @@ index 2c2c4db31a746b4eb853dc04c6b3e5631bbfa034..4f4e3ee18d586f61706504218cddc06a public String getName() { Player player = this.getPlayer(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index b6093a1bbd8176cde85ef034373ae71f9dd8f1c1..3f55fbf41a85e71a62628db18fde4afb3dd923c3 100644 +index 2658c7a0257d7bab26d043626abb9f2310f284e2..060f4cade69dbd41e96d1684b4fba34762f5eaa7 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -257,6 +257,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -261,6 +261,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.server.getPlayer(this.getUniqueId()) != null; } diff --git a/patches/server/0866-Fix-slot-desync.patch b/patches/server/0866-Fix-slot-desync.patch index 449fa59ed08b..b85e196ed610 100644 --- a/patches/server/0866-Fix-slot-desync.patch +++ b/patches/server/0866-Fix-slot-desync.patch @@ -22,10 +22,10 @@ index 1a7d2ade0e85dd5e6cd6c9202e3277cc2fa43d4a..37defbc0674e67a26e5a9aebb811310e this.containerMenu.findSlot(this.getInventory(), this.getInventory().selected).ifPresent(s -> { this.containerSynchronizer.sendSlotChange(this.containerMenu, s, this.getMainHandItem()); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index c6f51c3a1c0ff9bc6b6bfe3c7091be324a2129ed..fe23c77efae996dfa6c3530c11e51202bccca378 100644 +index d4250cc73bc51c51b78a9392a9879d47dc67f159..182897b4ab9415b7aab0b968274993dd43a47903 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2741,10 +2741,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2749,10 +2749,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Refresh the current entity metadata entity.refreshEntityData(ServerGamePacketListenerImpl.this.player); // SPIGOT-7136 - Allays diff --git a/patches/server/0871-Add-slot-sanity-checks-in-container-clicks.patch b/patches/server/0871-Add-slot-sanity-checks-in-container-clicks.patch index e09447a233dc..22ddd65752d7 100644 --- a/patches/server/0871-Add-slot-sanity-checks-in-container-clicks.patch +++ b/patches/server/0871-Add-slot-sanity-checks-in-container-clicks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add slot sanity checks in container clicks diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index fe23c77efae996dfa6c3530c11e51202bccca378..8b5be8870a0077b82e345027b323b8b4f448f231 100644 +index 182897b4ab9415b7aab0b968274993dd43a47903..17402d393df27474b38c8d9b0b7aa424ec34d1a9 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3003,6 +3003,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3011,6 +3011,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl break; case SWAP: if ((packet.getButtonNum() >= 0 && packet.getButtonNum() < 9) || packet.getButtonNum() == 40) { diff --git a/patches/server/0884-Fix-UnsafeValues-loadAdvancement.patch b/patches/server/0884-Fix-UnsafeValues-loadAdvancement.patch index 3bf5c53ea0dd..57e986f1b776 100644 --- a/patches/server/0884-Fix-UnsafeValues-loadAdvancement.patch +++ b/patches/server/0884-Fix-UnsafeValues-loadAdvancement.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix UnsafeValues#loadAdvancement diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index a4998c2df341a1b9a337afb24284428cd98e59d8..fa3add7cc39997d137b9dbc2178e08e9a6e5f31a 100644 +index 78b5578ece76c88a4dafcd4220a82081e85cf735..bd77a942a264a5d9cdaba4cc63099b8ae00c48f6 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -308,9 +308,30 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0885-Add-player-idle-duration-API.patch b/patches/server/0885-Add-player-idle-duration-API.patch index 85d9444c878c..69a1a77c2f69 100644 --- a/patches/server/0885-Add-player-idle-duration-API.patch +++ b/patches/server/0885-Add-player-idle-duration-API.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add player idle duration API Implements API for getting and resetting a player's idle duration. diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 3f55fbf41a85e71a62628db18fde4afb3dd923c3..6de8cd1961a3d5bb50043cc4f1135a981e398666 100644 +index 060f4cade69dbd41e96d1684b4fba34762f5eaa7..1681653f686133b5d2c0c10c368f86134b295d20 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3432,6 +3432,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3446,6 +3446,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end diff --git a/patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch b/patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch index 102c7e16739b..d52f931c35f7 100644 --- a/patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch +++ b/patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Allow null itemstack for Player#sendEquipmentChange diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 6de8cd1961a3d5bb50043cc4f1135a981e398666..620977c5afae38b8769cea8ccd5e97b311da6fc3 100644 +index 1681653f686133b5d2c0c10c368f86134b295d20..bdc9ac5bee552c1de110d6588d3850a6b3cd5723 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1140,7 +1140,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1144,7 +1144,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void sendEquipmentChange(LivingEntity entity, EquipmentSlot slot, ItemStack item) { diff --git a/patches/server/0908-Add-experience-points-API.patch b/patches/server/0908-Add-experience-points-API.patch index c6ac9ee89a0f..0ab86e2d015f 100644 --- a/patches/server/0908-Add-experience-points-API.patch +++ b/patches/server/0908-Add-experience-points-API.patch @@ -18,10 +18,10 @@ index aca888c2f02b09ac6739bdc81b194c4527dd69f5..a19a795deaa7f46c92b97912e2ade006 // Paper start - send while respecting visibility private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 620977c5afae38b8769cea8ccd5e97b311da6fc3..24b05e9b21ec84a4677f58ed790d308e700741b5 100644 +index bdc9ac5bee552c1de110d6588d3850a6b3cd5723..d5d30252241d5051b038cf4f487e956afd554ee0 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1934,6 +1934,49 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1948,6 +1948,49 @@ public class CraftPlayer extends CraftHumanEntity implements Player { Preconditions.checkArgument(exp >= 0, "Total experience points must not be negative (%s)", exp); this.getHandle().totalExperience = exp; } diff --git a/patches/server/0918-Add-api-for-spawn-egg-texture-colors.patch b/patches/server/0918-Add-api-for-spawn-egg-texture-colors.patch index 519fc3ea8151..255e25785b07 100644 --- a/patches/server/0918-Add-api-for-spawn-egg-texture-colors.patch +++ b/patches/server/0918-Add-api-for-spawn-egg-texture-colors.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add api for spawn egg texture colors diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index fa3add7cc39997d137b9dbc2178e08e9a6e5f31a..b6591836a8d9301b8cf909223426df0e8e675c1f 100644 +index bd77a942a264a5d9cdaba4cc63099b8ae00c48f6..db177cb5a99b3529b2eed291bc794234214f8e7c 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -643,6 +643,15 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0919-Add-Lifecycle-Event-system.patch b/patches/server/0919-Add-Lifecycle-Event-system.patch index 2f7888db419f..fe8a2a22de05 100644 --- a/patches/server/0919-Add-Lifecycle-Event-system.patch +++ b/patches/server/0919-Add-Lifecycle-Event-system.patch @@ -743,7 +743,7 @@ index 2934e232c84603224470fdaba0103d42fc06e8b4..4dc64ab006399d62251f4a238d9c2cae this.reloadCount++; this.configuration = YamlConfiguration.loadConfiguration(this.getConfigFile()); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index b6591836a8d9301b8cf909223426df0e8e675c1f..6396af834c5ca2328896613c5d97e43624eb305d 100644 +index db177cb5a99b3529b2eed291bc794234214f8e7c..5a94b9a5c400818818cc427160d696f10470f3a2 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -652,6 +652,13 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0920-ItemStack-Tooltip-API.patch b/patches/server/0920-ItemStack-Tooltip-API.patch index 006236f389ff..c7e83e2f18b4 100644 --- a/patches/server/0920-ItemStack-Tooltip-API.patch +++ b/patches/server/0920-ItemStack-Tooltip-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] ItemStack Tooltip API diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 6396af834c5ca2328896613c5d97e43624eb305d..6e070dada87083656a19b4abf78db63f4b2513e6 100644 +index 5a94b9a5c400818818cc427160d696f10470f3a2..b24ccbff89db873f5bdf62cbebcca0049b94a8d5 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -628,6 +628,21 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0922-Add-FluidState-API.patch b/patches/server/0922-Add-FluidState-API.patch index 8fa8aecc0225..e1e2fe004fe2 100644 --- a/patches/server/0922-Add-FluidState-API.patch +++ b/patches/server/0922-Add-FluidState-API.patch @@ -173,7 +173,7 @@ index 0000000000000000000000000000000000000000..c0c2805cb045cdd835b402776a6923fe + +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index 29825ea687827c075b87e88c45672e7b0093ed17..9af491e6e9ac96fc766462a1f672f44f8fc50ef1 100644 +index 4c234e887c42b27754ed8f05f2000d9309274427..f0bd7d01f56bb792886354ca4f199e46c2cf7503 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java @@ -108,6 +108,13 @@ public abstract class CraftRegionAccessor implements RegionAccessor { diff --git a/patches/server/0928-Add-CartographyItemEvent.patch b/patches/server/0928-Add-CartographyItemEvent.patch index ca08d014f85a..e02b1544dbfe 100644 --- a/patches/server/0928-Add-CartographyItemEvent.patch +++ b/patches/server/0928-Add-CartographyItemEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add CartographyItemEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 8b5be8870a0077b82e345027b323b8b4f448f231..80755a80dfd484af361c208fd4de309ca7ef8553 100644 +index 17402d393df27474b38c8d9b0b7aa424ec34d1a9..605488d9b2b20c82906b5870ffe4e0e37b6d36bf 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3125,6 +3125,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3133,6 +3133,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } diff --git a/patches/server/0938-Improve-tag-parser-handling.patch b/patches/server/0938-Improve-tag-parser-handling.patch index 9435db11ac5c..a3ceebed6803 100644 --- a/patches/server/0938-Improve-tag-parser-handling.patch +++ b/patches/server/0938-Improve-tag-parser-handling.patch @@ -252,10 +252,10 @@ index 898b19887ed34c87003fc63cb5905df2ba6234a5..b47eeb23055b135d5567552ba983bfbc private void write(FriendlyByteBuf buf) { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 80755a80dfd484af361c208fd4de309ca7ef8553..74b70c7a41d03bae57e1b2863b7ce947f951da46 100644 +index 605488d9b2b20c82906b5870ffe4e0e37b6d36bf..ac2a2722e154bdee0c4bbea22f3fb032c3ba39c9 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -770,6 +770,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -778,6 +778,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return; } // Paper end - Don't suggest if tab-complete is disabled @@ -269,7 +269,7 @@ index 80755a80dfd484af361c208fd4de309ca7ef8553..74b70c7a41d03bae57e1b2863b7ce947 // Paper start - AsyncTabCompleteEvent TAB_COMPLETE_EXECUTOR.execute(() -> this.handleCustomCommandSuggestions0(packet)); } -@@ -822,6 +829,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -830,6 +837,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private void sendServerSuggestions(final ServerboundCommandSuggestionPacket packet, final StringReader stringreader) { // Paper end - AsyncTabCompleteEvent ParseResults parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack()); diff --git a/patches/server/0953-Added-API-to-get-player-ha-proxy-address.patch b/patches/server/0953-Added-API-to-get-player-ha-proxy-address.patch index 4ff67e86ed55..e71ca83a36fc 100644 --- a/patches/server/0953-Added-API-to-get-player-ha-proxy-address.patch +++ b/patches/server/0953-Added-API-to-get-player-ha-proxy-address.patch @@ -35,10 +35,10 @@ index c62df32af11636ad408b584fcc590590ce4fb0d0..baed0bb80d44973f9323bbe536551182 } else { super.channelRead(ctx, msg); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 24b05e9b21ec84a4677f58ed790d308e700741b5..60a5eb5bd23bb267648bc55c1ee6bdfb29f806ce 100644 +index d5d30252241d5051b038cf4f487e956afd554ee0..8d16575c74b81ada4e4efe70e8f077f07cd0a3f0 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -266,7 +266,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -270,7 +270,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public InetSocketAddress getAddress() { @@ -47,7 +47,7 @@ index 24b05e9b21ec84a4677f58ed790d308e700741b5..60a5eb5bd23bb267648bc55c1ee6bdfb SocketAddress addr = this.getHandle().connection.getRemoteAddress(); if (addr instanceof InetSocketAddress) { -@@ -276,6 +276,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -280,6 +280,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } } diff --git a/patches/server/0957-Brigadier-based-command-API.patch b/patches/server/0957-Brigadier-based-command-API.patch index 6eb0d9779c82..86df1cfd979d 100644 --- a/patches/server/0957-Brigadier-based-command-API.patch +++ b/patches/server/0957-Brigadier-based-command-API.patch @@ -2338,10 +2338,10 @@ index eb9dab7be7da11ab1c4046a7fc4a29d5bddf31d2..39c9c0dad159744da8322c3dfa3bfae4 this.setPvpAllowed(dedicatedserverproperties.pvp); this.setFlightAllowed(dedicatedserverproperties.allowFlight); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 74b70c7a41d03bae57e1b2863b7ce947f951da46..7508434475ea93f9153f3976c5fa95c7678807e9 100644 +index ac2a2722e154bdee0c4bbea22f3fb032c3ba39c9..4ac4ab815edf34e8037e9f16ec2f8d29b1f2cabd 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2421,33 +2421,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2429,33 +2429,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } diff --git a/patches/server/0958-Fix-issues-with-Recipe-API.patch b/patches/server/0958-Fix-issues-with-Recipe-API.patch index bcc33fc956f8..ab2b6a47eff6 100644 --- a/patches/server/0958-Fix-issues-with-Recipe-API.patch +++ b/patches/server/0958-Fix-issues-with-Recipe-API.patch @@ -18,13 +18,13 @@ index dd02af6574dd97404bc9c02c9ead84e1dd537efe..980fea65899ef5f37808506b822fd3de } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java -index a68e036a12b354c4f04b6596dfb9cd6e7663718b..d8af6522f7516de93e33cb9da8490f5ec14e7553 100644 +index a30950287646524c4906574d193ec7ce94b4eb34..d270e17f10cc8abe3f5209d82991fcb0b2bb1ba7 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java @@ -38,6 +38,10 @@ public interface CraftRecipe extends Recipe { stack = Ingredient.of(((RecipeChoice.MaterialChoice) bukkit).getChoices().stream().map((mat) -> CraftItemType.bukkitToMinecraft(mat))); } else if (bukkit instanceof RecipeChoice.ExactChoice) { - stack = Ingredient.ofStacks(((RecipeChoice.ExactChoice) bukkit).getChoices().stream().map((mat) -> CraftItemStack.asNMSCopy(mat))); + stack = Ingredient.ofStacks(((RecipeChoice.ExactChoice) bukkit).getChoices().stream().map((mat) -> CraftItemStack.asNMSCopy(mat)).toList()); + // Paper start - support "empty" choices + } else if (bukkit == RecipeChoice.empty()) { + stack = Ingredient.of(); diff --git a/patches/server/0959-Fix-equipment-slot-and-group-API.patch b/patches/server/0959-Fix-equipment-slot-and-group-API.patch index ecc15fdf243f..962f6d77b249 100644 --- a/patches/server/0959-Fix-equipment-slot-and-group-API.patch +++ b/patches/server/0959-Fix-equipment-slot-and-group-API.patch @@ -26,7 +26,7 @@ index a62d17b72c675120b447e625cb3dc437681bdf20..f16067b674118a47735ad22797988d50 + // Paper end - Expose canUseSlot } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java -index 46d0b324498510c73a8439611f44269edee62313..69982103d8ea31e9b83b18c4c03a7b021bb983b9 100644 +index e62baea16df017f1e394e3c706157e158066eb93..656c9a6d8cd42891141ee29ec91ab5d166051ed6 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java @@ -135,6 +135,10 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i @@ -38,7 +38,7 @@ index 46d0b324498510c73a8439611f44269edee62313..69982103d8ea31e9b83b18c4c03a7b02 + throw new IllegalArgumentException("BODY is not valid for players!"); + // Paper end default: - throw new IllegalArgumentException("Not implemented. This is a bug"); + throw new IllegalArgumentException("Could not set slot " + slot + " - not a valid slot for PlayerInventory"); } @@ -162,6 +166,10 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i return java.util.Objects.requireNonNullElseGet(this.getChestplate(), () -> new ItemStack(org.bukkit.Material.AIR)); // Paper - make nonnull @@ -49,7 +49,7 @@ index 46d0b324498510c73a8439611f44269edee62313..69982103d8ea31e9b83b18c4c03a7b02 + throw new IllegalArgumentException("BODY is not valid for players!"); + // Paper end default: - throw new IllegalArgumentException("Not implemented. This is a bug"); + throw new IllegalArgumentException("Could not get slot " + slot + " - not a valid slot for PlayerInventory"); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java index 63567251d101b5e50ffd7e2825b1411fcb433c8c..450c5aa14b4195eb7123492c7a111ec6f40ce412 100644 diff --git a/patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch b/patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch index b2a9a23cfe45..b49ee289c2a5 100644 --- a/patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch +++ b/patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch @@ -209,10 +209,10 @@ index f3456aeeab7eee5b6d0383a4bf1338dd8cc95bb3..b2fd3e936559c8fcb8b02ae3ef63c4f3 ((LivingEntity) this.entity).detectEquipmentUpdatesPublic(); // CraftBukkit - SPIGOT-3789: sync again immediately after sending } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 7508434475ea93f9153f3976c5fa95c7678807e9..dc8f2d0bc3adc87088e7289a90c9186483e21cf4 100644 +index 4ac4ab815edf34e8037e9f16ec2f8d29b1f2cabd..93451a4cfc71ba00610c13011b73905e613b0b10 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2743,7 +2743,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2751,7 +2751,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl entity.refreshEntityData(ServerGamePacketListenerImpl.this.player); // SPIGOT-7136 - Allays if (entity instanceof Allay || entity instanceof net.minecraft.world.entity.animal.horse.AbstractHorse) { // Paper - Fix horse armor desync diff --git a/patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch b/patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch index fedf5ac8051e..642be4bf7887 100644 --- a/patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch +++ b/patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Deprecate InvAction#HOTBAR_MOVE_AND_READD diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index dc8f2d0bc3adc87088e7289a90c9186483e21cf4..2533c0a54e74666a55a8478c7d4da12d26e31fd4 100644 +index 93451a4cfc71ba00610c13011b73905e613b0b10..46f4d7a05d4febd1f8fd3cc2cae635a9e3da0e9e 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3014,14 +3014,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3022,14 +3022,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl Slot clickedSlot = this.player.containerMenu.getSlot(packet.getSlotNum()); if (clickedSlot.mayPickup(this.player)) { ItemStack hotbar = this.player.getInventory().getItem(packet.getButtonNum()); diff --git a/work/BuildData b/work/BuildData index 0ea6fcc9bc8a..0c5ebabcb4ce 160000 --- a/work/BuildData +++ b/work/BuildData @@ -1 +1 @@ -Subproject commit 0ea6fcc9bc8ad9e7c729f5031123bcc69ce2b033 +Subproject commit 0c5ebabcb4ce41f69a7d2319b468b6faee434038 diff --git a/work/Bukkit b/work/Bukkit index f6ac70751dbb..553558256cab 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit f6ac70751dbb9d2280a14b3706248987c243e313 +Subproject commit 553558256cab26217919a0809cc26f7aad22995d diff --git a/work/CraftBukkit b/work/CraftBukkit index 459c38af3079..18b8ae183907 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 459c38af307944fbf03a472cba33c71d93287d33 +Subproject commit 18b8ae18390763d48ea292435b75c1eabf5dbff7 diff --git a/work/Spigot b/work/Spigot index a084d85da860..5eb8a94b2f4d 160000 --- a/work/Spigot +++ b/work/Spigot @@ -1 +1 @@ -Subproject commit a084d85da8604d468f81091f56dc81166d912931 +Subproject commit 5eb8a94b2f4dfefed5c71a40f87a84c34d1c8828 From d67e55d367070bd178b9040ee7e25990b48b5362 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Thu, 24 Oct 2024 19:40:24 +0100 Subject: [PATCH 043/119] Checkpoint --- ...cing-for-EntityLiving-hasLineOfSight.patch | 0 .../0991-Optional-per-player-mob-spawns.patch | 0 ...73-disable-forced-empty-world-ticks.patch} | 4 +- ...dBounds-and-getBlockState-for-inlin.patch} | 16 +- ...tem-frames-performance-and-bug-fixe.patch} | 38 ++--- ...Manager-and-add-advanced-packet-sup.patch} | 0 ...77-Allow-Saving-of-Oversized-Chunks.patch} | 10 +- ...978-Flat-bedrock-generator-settings.patch} | 18 +- .../0979-Entity-Activation-Range-2.0.patch} | 160 +++++++++--------- 9 files changed, 120 insertions(+), 126 deletions(-) rename patches/{unapplied/server => later}/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch (100%) rename patches/{unapplied/server => later}/0991-Optional-per-player-mob-spawns.patch (100%) rename patches/{unapplied/server/0983-disable-forced-empty-world-ticks.patch => server/0973-disable-forced-empty-world-ticks.patch} (84%) rename patches/{unapplied/server/0984-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch => server/0974-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch} (84%) rename patches/{unapplied/server/0985-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch => server/0975-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch} (83%) rename patches/{unapplied/server/0987-Optimize-Network-Manager-and-add-advanced-packet-sup.patch => server/0976-Optimize-Network-Manager-and-add-advanced-packet-sup.patch} (100%) rename patches/{unapplied/server/0988-Allow-Saving-of-Oversized-Chunks.patch => server/0977-Allow-Saving-of-Oversized-Chunks.patch} (95%) rename patches/{unapplied/server/0989-Flat-bedrock-generator-settings.patch => server/0978-Flat-bedrock-generator-settings.patch} (96%) rename patches/{unapplied/server/0990-Entity-Activation-Range-2.0.patch => server/0979-Entity-Activation-Range-2.0.patch} (88%) diff --git a/patches/unapplied/server/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch b/patches/later/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch similarity index 100% rename from patches/unapplied/server/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch rename to patches/later/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch diff --git a/patches/unapplied/server/0991-Optional-per-player-mob-spawns.patch b/patches/later/0991-Optional-per-player-mob-spawns.patch similarity index 100% rename from patches/unapplied/server/0991-Optional-per-player-mob-spawns.patch rename to patches/later/0991-Optional-per-player-mob-spawns.patch diff --git a/patches/unapplied/server/0983-disable-forced-empty-world-ticks.patch b/patches/server/0973-disable-forced-empty-world-ticks.patch similarity index 84% rename from patches/unapplied/server/0983-disable-forced-empty-world-ticks.patch rename to patches/server/0973-disable-forced-empty-world-ticks.patch index 4e5fea24f685..ff511523c566 100644 --- a/patches/unapplied/server/0983-disable-forced-empty-world-ticks.patch +++ b/patches/server/0973-disable-forced-empty-world-ticks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] disable forced empty world ticks diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 24d5e741aed1677d0df59c1455fbfc60a29e8e3c..c2189752a422f39428b2c0f1408f359f20c388e5 100644 +index 2aa4437a76d29cdd793680734a36a41c6133ab91..03b07f36b32ad8239f82a9536a4c1b08ed12e9ca 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -686,7 +686,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -519,7 +519,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.handlingTick = false; gameprofilerfiller.pop(); diff --git a/patches/unapplied/server/0984-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch b/patches/server/0974-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch similarity index 84% rename from patches/unapplied/server/0984-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch rename to patches/server/0974-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch index 3046e40be770..f7d697b6899f 100644 --- a/patches/unapplied/server/0984-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch +++ b/patches/server/0974-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch @@ -12,7 +12,7 @@ Replace all calls to the new place to the unnecessary forward. Optimize getType and getBlockData to manually inline and optimize the calls diff --git a/src/main/java/net/minecraft/core/Vec3i.java b/src/main/java/net/minecraft/core/Vec3i.java -index 02367ef1371dde94ff6c4cd40bd32e800d6ccaaf..7b0fc7135bc107103dcaed6dc0707b1829928fae 100644 +index 2f2bcc1b9b32e58bf70ae6c171177ceb333ed6cd..d7afddd1d961495f0b50302a8da0a70fcd3ba1b0 100644 --- a/src/main/java/net/minecraft/core/Vec3i.java +++ b/src/main/java/net/minecraft/core/Vec3i.java @@ -28,6 +28,12 @@ public class Vec3i implements Comparable { @@ -29,10 +29,10 @@ index 02367ef1371dde94ff6c4cd40bd32e800d6ccaaf..7b0fc7135bc107103dcaed6dc0707b18 this.x = x; this.y = y; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 347334130e99dbf938d570bd36440a96f92d475a..c69ed3e899fc8d48afeb731bb3b2d97b5969e6e3 100644 +index 1b899473c6deeaa1aef9007d8b7bcec98580e61c..8adf12491e01830464b07e7a795db995d31f7a31 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -824,7 +824,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -341,7 +341,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Paper end public boolean isInWorldBounds(BlockPos pos) { @@ -42,10 +42,10 @@ index 347334130e99dbf938d570bd36440a96f92d475a..c69ed3e899fc8d48afeb731bb3b2d97b public static boolean isInSpawnableBounds(BlockPos pos) { diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -index fba548c4e6d589323ec3ea5f6b269a6fe9faf6a1..a7fc4b027cee8e1ed2678be7060040494a65682a 100644 +index 37795b9e264c571efe9c718fa9996197dca4ed54..a846dd210ed1de0dc3e8b686663ee346bff33dc8 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -@@ -189,6 +189,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom +@@ -128,6 +128,7 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh return GameEventListenerRegistry.NOOP; } @@ -54,10 +54,10 @@ index fba548c4e6d589323ec3ea5f6b269a6fe9faf6a1..a7fc4b027cee8e1ed2678be706004049 public abstract BlockState setBlockState(BlockPos pos, BlockState state, boolean moved); diff --git a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java -index 4af698930712389881601069a921f054c07935f2..d7d332d8ba3442887e80d2c3d7bddb9de2674c2d 100644 +index 7cce66d4c6efe6fd3cc22a6acf72878c964c61ae..f38700e5fbeeb8a913272d4464b8aa325d511dac 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java -@@ -99,6 +99,12 @@ public class ImposterProtoChunk extends ProtoChunk implements ca.spottedleaf.moo +@@ -56,6 +56,12 @@ public class ImposterProtoChunk extends ProtoChunk { public BlockState getBlockState(BlockPos pos) { return this.wrapped.getBlockState(pos); } @@ -71,7 +71,7 @@ index 4af698930712389881601069a921f054c07935f2..d7d332d8ba3442887e80d2c3d7bddb9d @Override public FluidState getFluidState(BlockPos pos) { diff --git a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java -index 207dc31afcf5ca5a59ab27ee263aa10f94a79559..082eae7032d5a8055a0f67b8a5583bbbf6fa9916 100644 +index 5321109ca638036572df9a7e17eafcef2b4f5112..4d5704df4a7ac6e148774f1a986d46bfb7e95f95 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java @@ -97,14 +97,18 @@ public class ProtoChunk extends ChunkAccess { diff --git a/patches/unapplied/server/0985-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/patches/server/0975-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch similarity index 83% rename from patches/unapplied/server/0985-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch rename to patches/server/0975-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch index a5a550aacabc..cc490d0a6313 100644 --- a/patches/unapplied/server/0985-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch +++ b/patches/server/0975-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 376443dfc846f7511c60125cb7714757d15590ea..81eb2d57045dd9d692109b33fc10804ff3d68d54 100644 +index 03b07f36b32ad8239f82a9536a4c1b08ed12e9ca..e3085b4d106d5985078ab3820dd12bdb58ab5889 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2496,6 +2496,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -2358,6 +2358,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe { if ( iter.next().player == entity ) { @@ -24,30 +24,30 @@ index 376443dfc846f7511c60125cb7714757d15590ea..81eb2d57045dd9d692109b33fc10804f iter.remove(); } } -diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index d0b51d96d6795b5fa03bc195b90324680545b752..09bcbc0ae36e4e69fee87a7e0c49acf496117a39 100644 ---- a/src/main/java/net/minecraft/world/entity/player/Player.java -+++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -808,6 +808,14 @@ public abstract class Player extends LivingEntity { - return null; +diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java +index 52b18f2c333b7535929bb4e52e65cf5fb0f5692f..b0cec2132c21abac64420e0d9a23b5346dfd9ee4 100644 +--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java ++++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +@@ -2811,6 +2811,14 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { + this.awardStat(Stats.DROP); } - // CraftBukkit end + + // Paper start - remove player from map on drop + if (itemstack.getItem() == Items.FILLED_MAP) { + net.minecraft.world.level.saveddata.maps.MapItemSavedData worldmap = net.minecraft.world.item.MapItem.getSavedData(itemstack, this.level()); + if (worldmap != null) { + worldmap.tickCarriedBy(this, itemstack); ++ } + } -+ } + // Paper end - return entityitem; } + } diff --git a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java -index a43544704109f21bab230dd9bf0401e28f878582..6794466051dd4b725d579b2136c37844995a648e 100644 +index 2d5e7380e8a14cbc01ba48cd05deccc0c7f53430..ae321b3b8d98e42ef07fd1f0f738c1a2b428f6db 100644 --- a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java +++ b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java -@@ -79,6 +79,7 @@ public class MapItemSavedData extends SavedData { +@@ -80,6 +80,7 @@ public class MapItemSavedData extends SavedData { public final Map decorations = Maps.newLinkedHashMap(); private final Map frameMarkers = Maps.newHashMap(); private int trackedDecorationCount; @@ -69,9 +69,9 @@ index a43544704109f21bab230dd9bf0401e28f878582..6794466051dd4b725d579b2136c37844 } + worldmap.vanillaRender.buffer = abyte; // Paper - RegistryOps registryops = registryLookup.createSerializationContext(NbtOps.INSTANCE); + RegistryOps registryops = registries.createSerializationContext(NbtOps.INSTANCE); List list = (List) MapBanner.LIST_CODEC.parse(registryops, nbt.get("banners")).resultOrPartial((s) -> { -@@ -348,7 +351,7 @@ public class MapItemSavedData extends SavedData { +@@ -367,7 +370,7 @@ public class MapItemSavedData extends SavedData { --this.trackedDecorationCount; } @@ -80,7 +80,7 @@ index a43544704109f21bab230dd9bf0401e28f878582..6794466051dd4b725d579b2136c37844 } public static void addTargetDecoration(ItemStack stack, BlockPos pos, String id, Holder decorationType) { -@@ -588,6 +591,21 @@ public class MapItemSavedData extends SavedData { +@@ -621,6 +624,21 @@ public class MapItemSavedData extends SavedData { public class HoldingPlayer { @@ -102,10 +102,10 @@ index a43544704109f21bab230dd9bf0401e28f878582..6794466051dd4b725d579b2136c37844 public final Player player; private boolean dirtyData = true; private int minDirtyX; -@@ -621,7 +639,9 @@ public class MapItemSavedData extends SavedData { +@@ -654,7 +672,9 @@ public class MapItemSavedData extends SavedData { @Nullable Packet nextUpdatePacket(MapId mapId) { - MapItemSavedData.MapPatch worldmap_b; + MapItemSavedData.MapPatch worldmap_c; - org.bukkit.craftbukkit.map.RenderData render = MapItemSavedData.this.mapView.render((org.bukkit.craftbukkit.entity.CraftPlayer) this.player.getBukkitEntity()); // CraftBukkit + if (!this.dirtyData && this.tick % 5 != 0) { this.tick++; return null; } // Paper - this won't end up sending, so don't render it! + boolean vanillaMaps = shouldUseVanillaMap(); // Paper @@ -113,7 +113,7 @@ index a43544704109f21bab230dd9bf0401e28f878582..6794466051dd4b725d579b2136c37844 if (this.dirtyData) { this.dirtyData = false; -@@ -637,6 +657,8 @@ public class MapItemSavedData extends SavedData { +@@ -670,6 +690,8 @@ public class MapItemSavedData extends SavedData { // CraftBukkit start java.util.Collection icons = new java.util.ArrayList(); diff --git a/patches/unapplied/server/0987-Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/patches/server/0976-Optimize-Network-Manager-and-add-advanced-packet-sup.patch similarity index 100% rename from patches/unapplied/server/0987-Optimize-Network-Manager-and-add-advanced-packet-sup.patch rename to patches/server/0976-Optimize-Network-Manager-and-add-advanced-packet-sup.patch diff --git a/patches/unapplied/server/0988-Allow-Saving-of-Oversized-Chunks.patch b/patches/server/0977-Allow-Saving-of-Oversized-Chunks.patch similarity index 95% rename from patches/unapplied/server/0988-Allow-Saving-of-Oversized-Chunks.patch rename to patches/server/0977-Allow-Saving-of-Oversized-Chunks.patch index 4eef25929efe..7d1ee992f139 100644 --- a/patches/unapplied/server/0988-Allow-Saving-of-Oversized-Chunks.patch +++ b/patches/server/0977-Allow-Saving-of-Oversized-Chunks.patch @@ -134,11 +134,11 @@ index e858436bcf1b234d4bc6e6a117f5224d5c2d9f90..e761b63eebc1e76b2bb1cb887d83d0b6 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 18054304e08c8a6346c0135a0e6a68e77fe5c37c..0615fd82b71efb9a397de01615050e6d906c2844 100644 +index 4c1212c6ef48594e766fa9e35a6e15916602d587..2a0f7ab0b616fe07baac437372e3933186064dd5 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 -@@ -144,6 +144,43 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise - // Paper end - rewrite chunk system +@@ -55,6 +55,43 @@ public final class RegionFileStorage implements AutoCloseable { + } } + // Paper start @@ -181,7 +181,7 @@ index 18054304e08c8a6346c0135a0e6a68e77fe5c37c..0615fd82b71efb9a397de01615050e6d @Nullable public CompoundTag read(ChunkPos pos) throws IOException { // CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing -@@ -154,6 +191,12 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise +@@ -65,6 +102,12 @@ public final class RegionFileStorage implements AutoCloseable { // CraftBukkit end DataInputStream datainputstream = regionfile.getChunkDataInputStream(pos); @@ -194,7 +194,7 @@ index 18054304e08c8a6346c0135a0e6a68e77fe5c37c..0615fd82b71efb9a397de01615050e6d CompoundTag nbttagcompound; label43: { -@@ -242,6 +285,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise +@@ -147,6 +190,7 @@ public final class RegionFileStorage implements AutoCloseable { try { NbtIo.write(nbt, (DataOutput) dataoutputstream); diff --git a/patches/unapplied/server/0989-Flat-bedrock-generator-settings.patch b/patches/server/0978-Flat-bedrock-generator-settings.patch similarity index 96% rename from patches/unapplied/server/0989-Flat-bedrock-generator-settings.patch rename to patches/server/0978-Flat-bedrock-generator-settings.patch index da68e7d65b5b..1e4bccf2db46 100644 --- a/patches/unapplied/server/0989-Flat-bedrock-generator-settings.patch +++ b/patches/server/0978-Flat-bedrock-generator-settings.patch @@ -105,10 +105,10 @@ index 0000000000000000000000000000000000000000..b5580727eef106fa193e450038d1b20d + } +} diff --git a/src/main/java/net/minecraft/server/Bootstrap.java b/src/main/java/net/minecraft/server/Bootstrap.java -index 061c89b985dafc79c808dd5f0e296b9fbac2fdfc..8c2f9f549b5155b8d8fecbc22164b334805381e2 100644 +index 4840893082cbcd9b00f79149df1a7805af279dcb..ffca3a7df1c5b344dbd77e1db997c76d22a31021 100644 --- a/src/main/java/net/minecraft/server/Bootstrap.java +++ b/src/main/java/net/minecraft/server/Bootstrap.java -@@ -76,6 +76,7 @@ public class Bootstrap { +@@ -77,6 +77,7 @@ public class Bootstrap { CauldronInteraction.bootStrap(); // Paper start BuiltInRegistries.bootStrap(() -> { @@ -117,7 +117,7 @@ index 061c89b985dafc79c808dd5f0e296b9fbac2fdfc..8c2f9f549b5155b8d8fecbc22164b334 // Paper end CreativeModeTabs.validate(); diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -index 996899cb18e6c29665b9de7a1cc97c9a4187924b..68be0d51aa64b5d917fb53dbbbdf8966d4f4abd8 100644 +index 44e64d716eee71492f9a8d813934bb96463ece45..1fcc2b287ed723cf51720f80e68f18f4a15cf429 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java @@ -206,7 +206,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { @@ -127,7 +127,7 @@ index 996899cb18e6c29665b9de7a1cc97c9a4187924b..68be0d51aa64b5d917fb53dbbbdf8966 - WorldGenerationContext worldgenerationcontext = new WorldGenerationContext(this, region); + WorldGenerationContext worldgenerationcontext = new WorldGenerationContext(this, region, region.getMinecraftWorld()); // Paper - Flat bedrock generator settings - this.buildSurface(chunk, worldgenerationcontext, noiseConfig, structures, region.getBiomeManager(), region.registryAccess().registryOrThrow(Registries.BIOME), Blender.of(region)); + this.buildSurface(chunk, worldgenerationcontext, noiseConfig, structures, region.getBiomeManager(), region.registryAccess().lookupOrThrow(Registries.BIOME), Blender.of(region)); } @@ -234,7 +234,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { return this.createNoiseChunk(ichunkaccess1, structureAccessor, Blender.of(chunkRegion), noiseConfig); @@ -135,11 +135,11 @@ index 996899cb18e6c29665b9de7a1cc97c9a4187924b..68be0d51aa64b5d917fb53dbbbdf8966 Aquifer aquifer = noisechunk.aquifer(); - CarvingContext carvingcontext = new CarvingContext(this, chunkRegion.registryAccess(), chunk.getHeightAccessorForGeneration(), noisechunk, noiseConfig, ((NoiseGeneratorSettings) this.settings.value()).surfaceRule()); + CarvingContext carvingcontext = new CarvingContext(this, chunkRegion.registryAccess(), chunk.getHeightAccessorForGeneration(), noisechunk, noiseConfig, ((NoiseGeneratorSettings) this.settings.value()).surfaceRule(), chunkRegion.getMinecraftWorld()); // Paper - Flat bedrock generator settings - CarvingMask carvingmask = ((ProtoChunk) chunk).getOrCreateCarvingMask(carverStep); + CarvingMask carvingmask = ((ProtoChunk) chunk).getOrCreateCarvingMask(); for (int j = -8; j <= 8; ++j) { diff --git a/src/main/java/net/minecraft/world/level/levelgen/WorldGenerationContext.java b/src/main/java/net/minecraft/world/level/levelgen/WorldGenerationContext.java -index b99283c31193e2110f6e3f39c23dbfc2442bab2b..a34e53249668d917c9d77c6837b91360a2349bbc 100644 +index e3360e0a19b610586a6194df1880f15799400fc5..aeee3ea1a3aff45febed1bc7f15ea56570620a6c 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/WorldGenerationContext.java +++ b/src/main/java/net/minecraft/world/level/levelgen/WorldGenerationContext.java @@ -6,10 +6,13 @@ import net.minecraft.world.level.chunk.ChunkGenerator; @@ -151,7 +151,7 @@ index b99283c31193e2110f6e3f39c23dbfc2442bab2b..a34e53249668d917c9d77c6837b91360 - public WorldGenerationContext(ChunkGenerator generator, LevelHeightAccessor world) { + public WorldGenerationContext(ChunkGenerator generator, LevelHeightAccessor world) { this(generator, world, null); } // Paper - Flat bedrock generator settings + public WorldGenerationContext(ChunkGenerator generator, LevelHeightAccessor world, @org.jetbrains.annotations.Nullable net.minecraft.world.level.Level level) { // Paper - Flat bedrock generator settings - this.minY = Math.max(world.getMinBuildHeight(), generator.getMinY()); + this.minY = Math.max(world.getMinY(), generator.getMinY()); this.height = Math.min(world.getHeight(), generator.getGenDepth()); + this.level = level; // Paper - Flat bedrock generator settings } @@ -188,10 +188,10 @@ index 390bcf9c302effd9db42d7a0e65b5433cc2eadd6..b9e919d31e442f49300744395af3cf94 this.noiseChunk = chunkNoiseSampler; this.randomState = noiseConfig; diff --git a/src/main/java/net/minecraft/world/level/levelgen/placement/PlacementContext.java b/src/main/java/net/minecraft/world/level/levelgen/placement/PlacementContext.java -index 640c2683c842655bbaee8f293f1c2613ef44844e..c7dfd844c7846281ceff0d443c0160054fd36c5c 100644 +index 298cedb398cc0dc362e02a2bd9db170a9595407f..4e7aa581c9afc20820b659bb1804f7cf460f0b97 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/placement/PlacementContext.java +++ b/src/main/java/net/minecraft/world/level/levelgen/placement/PlacementContext.java -@@ -18,7 +18,7 @@ public class PlacementContext extends WorldGenerationContext { +@@ -17,7 +17,7 @@ public class PlacementContext extends WorldGenerationContext { private final Optional topFeature; public PlacementContext(WorldGenLevel world, ChunkGenerator generator, Optional placedFeature) { diff --git a/patches/unapplied/server/0990-Entity-Activation-Range-2.0.patch b/patches/server/0979-Entity-Activation-Range-2.0.patch similarity index 88% rename from patches/unapplied/server/0990-Entity-Activation-Range-2.0.patch rename to patches/server/0979-Entity-Activation-Range-2.0.patch index 6430108bbdc7..b84ed217bd5b 100644 --- a/patches/unapplied/server/0990-Entity-Activation-Range-2.0.patch +++ b/patches/server/0979-Entity-Activation-Range-2.0.patch @@ -17,7 +17,7 @@ Adds villagers as separate config public net.minecraft.world.entity.Entity isInsidePortal diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index dec865affbaaa71d09806143d13a854100b98f23..eadbf175c69b6bb2d0df723afac96a517ebf0d83 100644 +index e3085b4d106d5985078ab3820dd12bdb58ab5889..104827e5ca729d7d2f1ad4bda3a5b87fbb939db5 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; @@ -28,7 +28,7 @@ index dec865affbaaa71d09806143d13a854100b98f23..eadbf175c69b6bb2d0df723afac96a51 import com.google.common.collect.Lists; import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.util.Pair; -@@ -1192,17 +1191,17 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -980,17 +979,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe ++TimingHistory.entityTicks; // Paper - timings // Spigot start co.aikar.timings.Timing timer; // Paper @@ -50,41 +50,35 @@ index dec865affbaaa71d09806143d13a854100b98f23..eadbf175c69b6bb2d0df723afac96a51 try { // Paper end - timings entity.setOldPosAndRot(); -@@ -1213,9 +1212,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1001,21 +1000,24 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString(); }); gameprofilerfiller.incrementCounter("tickNonPassenger"); + if (isActive) { // Paper - EAR 2 -+ TimingHistory.activatedEntityTicks++; entity.tick(); entity.postTick(); // CraftBukkit + } else { entity.inactiveTick(); } // Paper - EAR 2 - this.getProfiler().pop(); -+ } finally { timer.stopTiming(); } // Paper - timings + gameprofilerfiller.pop(); ++ } finally { timer.stopTiming(); } // Paper - timings // EAR 2 Iterator iterator = entity.getPassengers().iterator(); while (iterator.hasNext()) { -@@ -1223,13 +1226,18 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. + Entity entity1 = (Entity) iterator.next(); - this.tickPassenger(entity, entity1); +- this.tickPassenger(entity, entity1); ++ this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2 } - } finally { timer.stopTiming(); } // Paper - timings -+ // } finally { timer.stopTiming(); } // Paper - timings - move up ++ // } finally { timer.stopTiming(); } // Paper - timings // EAR 2 } - private void tickPassenger(Entity vehicle, Entity passenger) { +- private void tickPassenger(Entity vehicle, Entity passenger) { ++ private void tickPassenger(Entity vehicle, Entity passenger, boolean isActive) { // Paper - EAR 2 if (!passenger.isRemoved() && passenger.getVehicle() == vehicle) { if (passenger instanceof Player || this.entityTickList.contains(passenger)) { -+ // Paper - EAR 2 -+ final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(passenger); -+ co.aikar.timings.Timing timer = isActive ? passenger.getType().passengerTickTimer.startTiming() : passenger.getType().passengerInactiveTickTimer.startTiming(); // Paper -+ try { -+ // Paper end passenger.setOldPosAndRot(); - ++passenger.tickCount; - ProfilerFiller gameprofilerfiller = this.getProfiler(); -@@ -1238,8 +1246,17 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1026,15 +1028,24 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return BuiltInRegistries.ENTITY_TYPE.getKey(passenger.getType()).toString(); }); gameprofilerfiller.incrementCounter("tickPassenger"); @@ -93,28 +87,28 @@ index dec865affbaaa71d09806143d13a854100b98f23..eadbf175c69b6bb2d0df723afac96a51 passenger.rideTick(); passenger.postTick(); // CraftBukkit + } else { -+ passenger.setDeltaMovement(Vec3.ZERO); -+ passenger.inactiveTick(); -+ // copied from inside of if (isPassenger()) of passengerTick, but that ifPassenger is unnecessary -+ vehicle.positionRider(passenger); ++ passenger.setDeltaMovement(Vec3.ZERO); ++ passenger.inactiveTick(); ++ // copied from inside of if (isPassenger()) of passengerTick, but that ifPassenger is unnecessary ++ vehicle.positionRider(passenger); + } + // Paper end - EAR 2 gameprofilerfiller.pop(); Iterator iterator = passenger.getPassengers().iterator(); -@@ -1249,6 +1266,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - this.tickPassenger(passenger, entity2); + while (iterator.hasNext()) { + Entity entity2 = (Entity) iterator.next(); + +- this.tickPassenger(passenger, entity2); ++ this.tickPassenger(passenger, entity2, isActive); // Paper - EAR 2 } -+ } finally { timer.stopTiming(); }// Paper - EAR2 timings } - } 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 eda8a591033885c5dcb95f5ff651b12529f479ba..242d9213d22cb552e48beee03aa2db141e39d1c4 100644 +index 3d4bb855dec45685d6e336d913903341f0ca4a11..f4b1a773bf809bde8cea919a418700f3d6850389 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -418,6 +418,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -420,6 +420,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // Spigot end protected int numCollisions = 0; // Paper - Cap entity collisions public boolean fromNetherPortal; // Paper - Add option to nerf pigmen from nether portals @@ -123,34 +117,34 @@ index eda8a591033885c5dcb95f5ff651b12529f479ba..242d9213d22cb552e48beee03aa2db14 public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one // Paper start - Entity origin API @javax.annotation.Nullable -@@ -1058,6 +1060,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -992,6 +994,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } else { this.wasOnFire = this.isOnFire(); - if (movementType == MoverType.PISTON) { -+ this.activatedTick = Math.max(this.activatedTick, MinecraftServer.currentTick + 20); // Paper -+ this.activatedImmunityTick = Math.max(this.activatedImmunityTick, MinecraftServer.currentTick + 20); // Paper + if (type == MoverType.PISTON) { ++ this.activatedTick = Math.max(this.activatedTick, MinecraftServer.currentTick + 20); // Paper - EAR 2 ++ this.activatedImmunityTick = Math.max(this.activatedImmunityTick, MinecraftServer.currentTick + 20); // Paper - EAR 2 movement = this.limitPistonMovement(movement); if (movement.equals(Vec3.ZERO)) { return; -@@ -1070,6 +1074,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1006,6 +1010,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.stuckSpeedMultiplier = Vec3.ZERO; this.setDeltaMovement(Vec3.ZERO); } + // Paper start - ignore movement changes while inactive. -+ if (isTemporarilyActive && !(this instanceof ItemEntity) && movement == getDeltaMovement() && movementType == MoverType.SELF) { ++ if (isTemporarilyActive && !(this instanceof ItemEntity) && movement == getDeltaMovement() && type == MoverType.SELF) { + setDeltaMovement(Vec3.ZERO); -+ this.level.getProfiler().pop(); ++ gameprofilerfiller.pop(); + return; + } + // Paper end - movement = this.maybeBackOffFromEdge(movement, movementType); + movement = this.maybeBackOffFromEdge(movement, type); Vec3 vec3d1 = this.collide(movement); diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 58ff5b4df2124901df757315e42b2490a7da7415..763abeea3f14f15c27d600e0bdae44b387687bb4 100644 +index aad63549d7c4f501b683b8dead4938eac27895eb..dbd321f3dc3cc80737830db63aed47a6935e8e89 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -232,6 +232,19 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -235,6 +235,19 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab return this.lookControl; } @@ -171,7 +165,7 @@ index 58ff5b4df2124901df757315e42b2490a7da7415..763abeea3f14f15c27d600e0bdae44b3 Entity entity = this.getControlledVehicle(); diff --git a/src/main/java/net/minecraft/world/entity/PathfinderMob.java b/src/main/java/net/minecraft/world/entity/PathfinderMob.java -index 812aecb88641c09fb5030d145620b95aff19c9cb..ec9e76c548393235dcc6658c29e72e07e5d3510b 100644 +index 7c69c9145eff938ce4615e3058d3d12edfc8bdd2..da1be210a41c3a2fbfa132326a623f1e748f8b77 100644 --- a/src/main/java/net/minecraft/world/entity/PathfinderMob.java +++ b/src/main/java/net/minecraft/world/entity/PathfinderMob.java @@ -22,6 +22,8 @@ public abstract class PathfinderMob extends Mob { @@ -184,22 +178,22 @@ index 812aecb88641c09fb5030d145620b95aff19c9cb..ec9e76c548393235dcc6658c29e72e07 return this.getWalkTargetValue(pos, this.level()); } diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java -index 89b8a304fe9fae4b57640afbab04b6764ce9aab8..074ef807258139f818e30494126585262c2f33c0 100644 +index 8775ce55654e4b99e287acd4a113cd72b9df4ff6..d871975f943a04b49644dc6eb18314d65a7836dc 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java -@@ -26,6 +26,7 @@ public class GoalSelector { +@@ -25,6 +25,7 @@ public class GoalSelector { + private final Map lockedFlags = new EnumMap<>(Goal.Flag.class); private final Set availableGoals = new ObjectLinkedOpenHashSet<>(); - private final Supplier profiler; private final EnumSet disabledFlags = EnumSet.noneOf(Goal.Flag.class); -+ private int curRate; ++ private int curRate; // Paper - EAR 2 - public GoalSelector(Supplier profiler) { - this.profiler = profiler; -@@ -40,6 +41,20 @@ public class GoalSelector { + public void addGoal(int priority, Goal goal) { + this.availableGoals.add(new WrappedGoal(priority, goal)); +@@ -35,6 +36,20 @@ public class GoalSelector { this.availableGoals.removeIf(goal -> predicate.test(goal.getGoal())); } -+ // Paper start ++ // Paper start - EAR 2 + public boolean inactiveTick() { + this.curRate++; + return this.curRate % 3 == 0; // TODO newGoalRate was already unused in 1.20.4, check if this is correct @@ -212,7 +206,7 @@ index 89b8a304fe9fae4b57640afbab04b6764ce9aab8..074ef807258139f818e3049412658526 + } + return false; + } -+ // Paper end ++ // Paper end - EAR 2 public void removeGoal(Goal goal) { for (WrappedGoal wrappedGoal : this.availableGoals) { if (wrappedGoal.getGoal() == goal && wrappedGoal.isRunning()) { @@ -244,69 +238,69 @@ index 6d8ea05e5e86e9f6359b560043bb55a10784e952..aee0147649d458b87d92496eda0c1723 } } diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java -index 393588661c41b490ee6bce2f687962f7ddeff7d4..7e1871401ec5e3e9a85232053490259f132aec0a 100644 +index a573aa4d387ad3a4e1017890f2b50b83a3c27ff4..b7a34f1c4d7b5ef3f7a843d152e33c839dcdedd5 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java -@@ -228,17 +228,34 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -228,19 +228,34 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @Override public void inactiveTick() { // SPIGOT-3874, SPIGOT-3894, SPIGOT-3846, SPIGOT-5286 :( - if (this.level().spigotConfig.tickInactiveVillagers && this.isEffectiveAi()) { -- this.customServerAiStep(); +- this.customServerAiStep((ServerLevel) this.level()); + // Paper start + if (this.getUnhappyCounter() > 0) { + this.setUnhappyCounter(this.getUnhappyCounter() - 1); - } ++ } + if (this.isEffectiveAi()) { + if (this.level().spigotConfig.tickInactiveVillagers) { -+ this.customServerAiStep(); ++ this.customServerAiStep(this.level().getMinecraftWorld()); + } else { -+ this.customServerAiStep(true); ++ this.customServerAiStep(this.level().getMinecraftWorld(), true); + } -+ } + } + maybeDecayGossip(); + // Paper end -+ super.inactiveTick(); } // Spigot End @Override -+ @Deprecated // Paper - protected void customServerAiStep() { -+ // Paper start -+ this.customServerAiStep(false); + protected void customServerAiStep(ServerLevel world) { ++ // Paper start - EAR 2 ++ this.customServerAiStep(world, false); + } -+ protected void customServerAiStep(final boolean inactive) { -+ // Paper end - this.level().getProfiler().push("villagerBrain"); -- this.getBrain().tick((ServerLevel) this.level(), this); -+ if (!inactive) this.getBrain().tick((ServerLevel) this.level(), this); // Paper - this.level().getProfiler().pop(); ++ protected void customServerAiStep(ServerLevel world, final boolean inactive) { ++ // Paper end - EAR 2 + ProfilerFiller gameprofilerfiller = Profiler.get(); + + gameprofilerfiller.push("villagerBrain"); +- this.getBrain().tick(world, this); ++ if (!inactive) this.getBrain().tick(world, this); + gameprofilerfiller.pop(); if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; -@@ -262,7 +279,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -264,7 +279,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler this.lastTradedPlayer = null; } - if (!this.isNoAi() && this.random.nextInt(100) == 0) { -+ if (!inactive && !this.isNoAi() && this.random.nextInt(100) == 0) { // Paper - Raid raid = ((ServerLevel) this.level()).getRaidAt(this.blockPosition()); ++ if (!inactive && !this.isNoAi() && this.random.nextInt(100) == 0) { // Paper - EAR 2 + Raid raid = world.getRaidAt(this.blockPosition()); if (raid != null && raid.isActive() && !raid.isOver()) { -@@ -273,6 +290,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -275,6 +290,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler if (this.getVillagerData().getProfession() == VillagerProfession.NONE && this.isTrading()) { this.stopTrading(); } -+ if (inactive) return; // Paper ++ if (inactive) return; // Paper - EAR 2 - super.customServerAiStep(); + super.customServerAiStep(world); } diff --git a/src/main/java/net/minecraft/world/entity/vehicle/MinecartHopper.java b/src/main/java/net/minecraft/world/entity/vehicle/MinecartHopper.java -index 0b7f52021441d633c37543e8ae485e81c292b747..d7f8464bf3eed0e42a5fc7f14a5b243d171f8b5e 100644 +index f0a005724ab64a3b0cbc44d8f430716f7958461c..d81a6874e8b25f098df619f84c359e146c7f64de 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/MinecartHopper.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/MinecartHopper.java -@@ -52,6 +52,7 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper +@@ -47,6 +47,7 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper if (bl != this.isEnabled()) { this.setEnabled(bl); } @@ -314,7 +308,7 @@ index 0b7f52021441d633c37543e8ae485e81c292b747..d7f8464bf3eed0e42a5fc7f14a5b243d } public boolean isEnabled() { -@@ -92,11 +93,13 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper +@@ -100,11 +101,13 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper public boolean suckInItems() { if (HopperBlockEntity.suckInItems(this.level(), this)) { @@ -328,7 +322,7 @@ index 0b7f52021441d633c37543e8ae485e81c292b747..d7f8464bf3eed0e42a5fc7f14a5b243d return true; } } -@@ -126,4 +129,11 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper +@@ -139,4 +142,11 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper public AbstractContainerMenu createMenu(int syncId, Inventory playerInventory) { return new HopperMenu(syncId, playerInventory, this); } @@ -341,10 +335,10 @@ index 0b7f52021441d633c37543e8ae485e81c292b747..d7f8464bf3eed0e42a5fc7f14a5b243d + } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 574175449af5b767f28e95ff8708ed37fedf4c7d..ce9350ed3c5c5fbbd9b2ade9ae2880e03305c787 100644 +index 8adf12491e01830464b07e7a795db995d31f7a31..cef07ec3dfc8db3f3206fa2f5c2acf64c4b4aa65 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -157,6 +157,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -157,6 +157,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public Map capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper - Retain block place order when capturing blockstates public List captureDrops; public final it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap ticksPerSpawnCategory = new it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<>(); @@ -358,10 +352,10 @@ index 574175449af5b767f28e95ff8708ed37fedf4c7d..ce9350ed3c5c5fbbd9b2ade9ae2880e0 public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot // Paper start - add paper world config diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -index d7b963571c900f0f68005d6954bcd9ef1d9e0b7c..b35f476e26a020cf75e53a5eb488717d996a6935 100644 +index 46afba838cf12eeb1bbccaa260131a76f090364b..e1c9a961064887070b29207efd7af47884f8dc29 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -@@ -148,6 +148,10 @@ public class PistonMovingBlockEntity extends BlockEntity { +@@ -149,6 +149,10 @@ public class PistonMovingBlockEntity extends BlockEntity { } entity.setDeltaMovement(e, g, h); @@ -373,7 +367,7 @@ index d7b963571c900f0f68005d6954bcd9ef1d9e0b7c..b35f476e26a020cf75e53a5eb488717d } } diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 9fb9fa62c32445ac3c3883a6433759c86dcfc428..bf2d18f74b0f0da7c3c30310c74224a1c0853564 100644 +index ad15c7db36bdeadaa8f2ec8f15f41d6f3395bd55..e4252c5a6aec351a4a0a8be372d3b63f7fb771e7 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -1,33 +1,43 @@ @@ -606,7 +600,7 @@ index 9fb9fa62c32445ac3c3883a6433759c86dcfc428..bf2d18f74b0f0da7c3c30310c74224a1 - return true; + return 10; // Paper } - } else if ( !( (AbstractArrow) entity ).inGround ) + } else if ( !( (AbstractArrow) entity ).isInGround() ) { - return true; + return 1; // Paper From fe142cdcd5b9b1206d91be332be817977c030b8a Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Thu, 24 Oct 2024 20:10:38 +0100 Subject: [PATCH 044/119] Anti Xray --- .../0980-Anti-Xray.patch} | 224 +++++++++--------- 1 file changed, 116 insertions(+), 108 deletions(-) rename patches/{unapplied/server/0992-Anti-Xray.patch => server/0980-Anti-Xray.patch} (87%) diff --git a/patches/unapplied/server/0992-Anti-Xray.patch b/patches/server/0980-Anti-Xray.patch similarity index 87% rename from patches/unapplied/server/0992-Anti-Xray.patch rename to patches/server/0980-Anti-Xray.patch index 3081d5cc14e6..ffd46a42f895 100644 --- a/patches/unapplied/server/0992-Anti-Xray.patch +++ b/patches/server/0980-Anti-Xray.patch @@ -1104,23 +1104,23 @@ index 183b2191fa1c1b27adedf39593e1b5a223fb1279..8ead66c134688b11dca15f6509147e72 private ClientboundLevelChunkWithLightPacket(RegistryFriendlyByteBuf buf) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index aee8d882783130ed45a713e6c266114aaf4c0d93..acc11fc7f30b6d4a3a4445b7db25bf99c93b39f2 100644 +index 104827e5ca729d7d2f1ad4bda3a5b87fbb939db5..9a7ac16914bd22a7ca0aaedd2a3ce1576ad2e09c 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -491,7 +491,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - // Holder holder = worlddimension.type(); // CraftBukkit - decompile error +@@ -344,7 +344,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - // Objects.requireNonNull(minecraftserver); // CraftBukkit - decompile error -- super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), minecraftserver::getProfiler, false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules()))); // Paper - create paper world configs -+ super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), minecraftserver::getProfiler, false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules())), executor); // Paper - create paper world configs; Async-Anti-Xray: Pass executor + // Add env and gen to constructor, IWorldDataServer -> WorldDataServer + public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { +- super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules()))); // Paper - create paper world configs ++ super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules())), executor); // Paper - create paper world configs; Async-Anti-Xray: Pass executor this.pvpMode = minecraftserver.isPvpAllowed(); this.convertable = convertable_conversionsession; this.uuid = WorldUUID.getUUID(convertable_conversionsession.levelDirectory.path().toFile()); diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index 415d9802ae4dd75b44055b8faf19672fa50c585f..e9dcdb1e09e84a9b451034ff4bdfa6eae2dd1c04 100644 +index c4bc1819cba3287c4a67ae5d00f8c4d6ab899732..f2dd272a01b4e946a6746865d55ebc9861f8361b 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -50,7 +50,7 @@ import org.bukkit.event.player.PlayerInteractEvent; +@@ -48,7 +48,7 @@ import org.bukkit.event.player.PlayerInteractEvent; public class ServerPlayerGameMode { private static final Logger LOGGER = LogUtils.getLogger(); @@ -1129,7 +1129,7 @@ index 415d9802ae4dd75b44055b8faf19672fa50c585f..e9dcdb1e09e84a9b451034ff4bdfa6ea protected final ServerPlayer player; private GameType gameModeForPlayer; @Nullable -@@ -334,6 +334,8 @@ public class ServerPlayerGameMode { +@@ -332,6 +332,8 @@ public class ServerPlayerGameMode { } } @@ -1139,14 +1139,16 @@ index 415d9802ae4dd75b44055b8faf19672fa50c585f..e9dcdb1e09e84a9b451034ff4bdfa6ea public void destroyAndAck(BlockPos pos, int sequence, String reason) { diff --git a/src/main/java/net/minecraft/server/network/PlayerChunkSender.java b/src/main/java/net/minecraft/server/network/PlayerChunkSender.java -index 32634e45ac8433648e49e47e20081e15ad41ff15..dafa2cf7d3c49fc5bdcd68d2a952812774a1dfe4 100644 +index cdd66e6ce96e2613afe7f06ca8da3cfaa6704b2d..dafa2cf7d3c49fc5bdcd68d2a952812774a1dfe4 100644 --- a/src/main/java/net/minecraft/server/network/PlayerChunkSender.java +++ b/src/main/java/net/minecraft/server/network/PlayerChunkSender.java -@@ -79,7 +79,10 @@ public class PlayerChunkSender { +@@ -78,8 +78,11 @@ public class PlayerChunkSender { + } } - public static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) { // Paper - public +- private static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) { - handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), null, null)); ++ public static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) { // Paper - public + // Paper start - Anti-Xray + final boolean shouldModify = world.chunkPacketBlockController.shouldModify(handler.player, chunk); + handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), null, null, shouldModify)); @@ -1155,23 +1157,23 @@ index 32634e45ac8433648e49e47e20081e15ad41ff15..dafa2cf7d3c49fc5bdcd68d2a9528127 if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) { new io.papermc.paper.event.packet.PlayerChunkLoadEvent(new org.bukkit.craftbukkit.CraftChunk(chunk), handler.getPlayer().getBukkitEntity()).callEvent(); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index f6624d3fab88c4bd7199c8412f1977a6dab388ad..ced2417fdd87ee9624f459065a7abc9df4810850 100644 +index a4937d11b79cef41f3fbf79282c0c435e794dbfe..cde19fddfc9b1c8edbc565bec4f043803651313e 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -414,7 +414,7 @@ public abstract class PlayerList { - .getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS); +@@ -427,7 +427,7 @@ public abstract class PlayerList { + .getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS); player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket( - new net.minecraft.world.level.chunk.EmptyLevelChunk(worldserver1, player.chunkPosition(), plains), -- worldserver1.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null) -+ worldserver1.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null, true) + new net.minecraft.world.level.chunk.EmptyLevelChunk(worldserver1, player.chunkPosition(), plains), +- worldserver1.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null) ++ worldserver1.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null, true) // Paper - Anti-Xray ); } // Paper end - Send empty chunk diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 3272af72ae0609bb9c928d0e4a8ba2ca3d90d63a..c4ec80bbab850fe767a345d96f02103ca43eb3cb 100644 +index cef07ec3dfc8db3f3206fa2f5c2acf64c4b4aa65..ce6c9b82a64a32c4b952d1839260015b1a446365 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -172,6 +172,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -172,6 +172,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } // Paper end - add paper world config @@ -1179,24 +1181,24 @@ index 3272af72ae0609bb9c928d0e4a8ba2ca3d90d63a..c4ec80bbab850fe767a345d96f02103c public final co.aikar.timings.WorldTimingsHandler timings; // Paper public static BlockPos lastPhysicsProblem; // Spigot private org.spigotmc.TickLimiter entityLimiter; -@@ -683,7 +684,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - } - // Paper end - optimise random ticking +@@ -206,7 +207,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + + public abstract ResourceKey getTypeKey(); -- protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator) { // Paper - create paper world config -+ protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - create paper world config & Anti-Xray +- protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator) { // Paper - create paper world config ++ protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - create paper world config & Anti-Xray this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config this.generator = gen; -@@ -770,6 +771,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - this.minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(this); - this.maxSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection(this); - // Paper end - optimise collisions +@@ -287,6 +288,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + this.timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings + this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime); + this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); + this.chunkPacketBlockController = this.paperConfig().anticheat.antiXray.enabled ? new com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray(this, executor) : com.destroystokyo.paper.antixray.ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray } // Paper start - Cancel hit for vanished players -@@ -1047,6 +1049,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -487,6 +489,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // CraftBukkit end BlockState iblockdata1 = chunk.setBlockState(pos, state, (flags & 64) != 0, (flags & 1024) == 0); // CraftBukkit custom NO_PLACE flag @@ -1205,10 +1207,10 @@ index 3272af72ae0609bb9c928d0e4a8ba2ca3d90d63a..c4ec80bbab850fe767a345d96f02103c if (iblockdata1 == null) { // CraftBukkit start - remove blockstate if failed (or the same) diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -index a7fc4b027cee8e1ed2678be7060040494a65682a..75c8125e20b70433fe9d143a3193d821043327c3 100644 +index a846dd210ed1de0dc3e8b686663ee346bff33dc8..63d7d6b93119d96d753230472df30a9dedd889dc 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -@@ -159,7 +159,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom +@@ -108,17 +108,17 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh } } @@ -1216,8 +1218,7 @@ index a7fc4b027cee8e1ed2678be7060040494a65682a..75c8125e20b70433fe9d143a3193d821 + this.replaceMissingSections(biomeRegistry, this.sections); // Paper - Anti-Xray - make it a non-static method // CraftBukkit start this.biomeRegistry = biomeRegistry; - // Paper start - rewrite chunk system -@@ -176,10 +176,10 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom + } public final Registry biomeRegistry; // CraftBukkit end @@ -1231,39 +1232,39 @@ index a7fc4b027cee8e1ed2678be7060040494a65682a..75c8125e20b70433fe9d143a3193d821 } 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 d94e24cfc56c195a47665c212f8fcc901648a4a1..b1a6dc25b04ab6a43e8d62378e14d88d1c60bbbe 100644 +index 325d1e38a72a4b30f30261267e9adfb8a8726b11..71dfd0abb930ecf4f1ba900c80c161fa2a858685 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -91,7 +91,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p +@@ -93,7 +93,7 @@ public class LevelChunk extends ChunkAccess { } public LevelChunk(Level world, ChunkPos pos, UpgradeData upgradeData, LevelChunkTicks blockTickScheduler, LevelChunkTicks fluidTickScheduler, long inhabitedTime, @Nullable LevelChunkSection[] sectionArrayInitializer, @Nullable LevelChunk.PostLoadProcessor entityLoader, @Nullable BlendingData blendingData) { -- super(pos, upgradeData, world, world.registryAccess().registryOrThrow(Registries.BIOME), inhabitedTime, sectionArrayInitializer, blendingData); -+ super(pos, upgradeData, world, net.minecraft.server.MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME), inhabitedTime, sectionArrayInitializer, blendingData); // Paper - Anti-Xray - The world isn't ready yet, use server singleton for registry +- super(pos, upgradeData, world, world.registryAccess().lookupOrThrow(Registries.BIOME), inhabitedTime, sectionArrayInitializer, blendingData); ++ super(pos, upgradeData, world, net.minecraft.server.MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BIOME), inhabitedTime, sectionArrayInitializer, blendingData); // Paper - Anti-Xray - The world isn't ready yet, use server singleton for registry this.tickersInLevel = Maps.newHashMap(); - this.level = (ServerLevel) world; // CraftBukkit - type - this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap(); + this.unsavedListener = (chunkcoordintpair1) -> { + }; diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -index d7b8d984122ba6b6ef5a0be6e012a8828a1af22d..c3b1caa352b988ec44fa2b2eb0536517711f5460 100644 +index 52f44f14bbda60fe771c351e01e6ff470d7371e6..3dab36d00ea48101807ba40c7a7358b7eed12747 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -@@ -55,9 +55,12 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ +@@ -39,9 +39,12 @@ public class LevelChunkSection { this.recalcBlockCounts(); } - public LevelChunkSection(Registry biomeRegistry) { - this.states = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES); -- this.biomes = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES); +- this.biomes = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES); + // Paper start - Anti-Xray - Add parameters + @Deprecated @io.papermc.paper.annotation.DoNotUse public LevelChunkSection(Registry biomeRegistry) { this(biomeRegistry, null, null, 0); } + public LevelChunkSection(Registry biomeRegistry, net.minecraft.world.level.Level level, net.minecraft.world.level.ChunkPos chunkPos, int chunkSectionY) { -+ // Paper end ++ // Paper end + this.states = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, level == null || level.chunkPacketBlockController == null ? null : level.chunkPacketBlockController.getPresetBlockStates(level, chunkPos, chunkSectionY)); // Paper - Anti-Xray - Add preset block states -+ this.biomes = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); // Paper - Anti-Xray - Add preset biomes ++ this.biomes = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); // Paper - Anti-Xray - Add preset biomes } public BlockState getBlockState(int x, int y, int z) { -@@ -236,10 +239,13 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ +@@ -178,10 +181,13 @@ public class LevelChunkSection { this.biomes = datapaletteblock; } @@ -1281,7 +1282,7 @@ index d7b8d984122ba6b6ef5a0be6e012a8828a1af22d..c3b1caa352b988ec44fa2b2eb0536517 public int getSerializedSize() { diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c661e7890f 100644 +index 112d1259dd37743076ff6c67ffd711d084ba8698..69d6f203366df658e1ade55d917f0aa2b8a49be9 100644 --- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java @@ -28,6 +28,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer @@ -1289,7 +1290,7 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6 private final PaletteResize dummyPaletteResize = (newSize, added) -> 0; public final IdMap registry; + private final T @org.jetbrains.annotations.Nullable [] presetValues; // Paper - Anti-Xray - Add preset values - public volatile PalettedContainer.Data data; // Paper - optimise collisions - public + private volatile PalettedContainer.Data data; private final PalettedContainer.Strategy strategy; // private final ThreadingDetector threadingDetector = new ThreadingDetector("PalettedContainer"); // Paper - unused @@ -40,14 +41,19 @@ public class PalettedContainer implements PaletteResize, PalettedContainer @@ -1315,7 +1316,7 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6 ) .map(result -> (PalettedContainerRO)result); return codec(idList, entryCodec, paletteProvider, defaultValue, unpacker); -@@ -71,25 +77,58 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -71,31 +77,65 @@ public class PalettedContainer implements PaletteResize, PalettedContainer ); } @@ -1368,6 +1369,14 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6 this.data = data; } +- private PalettedContainer(PalettedContainer container) { ++ private PalettedContainer(PalettedContainer container, T @org.jetbrains.annotations.Nullable [] presetValues) { // Paper - Anti-Xray - Add preset values ++ this.presetValues = presetValues; // Paper - Anti-Xray - Add preset values + this.registry = container.registry; + this.strategy = container.strategy; + this.data = container.data.copy(this); + } + - public PalettedContainer(IdMap idList, T object, PalettedContainer.Strategy paletteProvider) { + // Paper start - Anti-Xray - Add preset values + @Deprecated @io.papermc.paper.annotation.DoNotUse public PalettedContainer(IdMap idList, T object, PalettedContainer.Strategy paletteProvider) { this(idList, object, paletteProvider, null); } @@ -1377,7 +1386,7 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6 this.strategy = paletteProvider; this.registry = idList; this.data = this.createOrReuseData(null, 0); -@@ -106,11 +145,33 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -112,11 +152,33 @@ public class PalettedContainer implements PaletteResize, PalettedContainer @Override public synchronized int onResize(int newBits, T object) { // Paper - synchronize PalettedContainer.Data data = this.data; @@ -1412,7 +1421,7 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6 public T getAndSet(int x, int y, int z, T value) { this.acquire(); -@@ -177,24 +238,33 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -183,24 +245,33 @@ public class PalettedContainer implements PaletteResize, PalettedContainer data.palette.read(buf); buf.readLongArray(data.storage.getRaw()); this.data = data; @@ -1449,7 +1458,7 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6 ) { List list = serialized.paletteEntries(); int i = paletteProvider.size(); -@@ -227,7 +297,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -233,7 +304,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer } } @@ -1458,12 +1467,12 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6 } @Override -@@ -284,12 +354,12 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - } +@@ -291,12 +362,12 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + @Override public PalettedContainer copy() { -- return new PalettedContainer<>(this.registry, this.strategy, this.data.copy()); -+ return new PalettedContainer<>(this.registry, this.strategy, this.data.copy(), this.presetValues); // Paper - Anti-Xray - Add preset values +- return new PalettedContainer<>(this); ++ return new PalettedContainer<>(this, this.presetValues); // Paper - Anti-Xray - Add preset values } @Override @@ -1473,7 +1482,7 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6 } @Override -@@ -328,9 +398,18 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -335,9 +406,18 @@ public class PalettedContainer implements PaletteResize, PalettedContainer return 1 + this.palette.getSerializedSize() + VarInt.getByteSize(this.storage.getRaw().length) + this.storage.getRaw().length * 8; } @@ -1494,7 +1503,7 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6 } diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainerRO.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainerRO.java -index 9a2bf744abd8916d492e901be889223591bac3fd..1dd415c96d17eff8e7555c33d3c52e57f2559fa5 100644 +index 303e59be721d0e16e8822cf4e407595348ee7abf..51f74dd7b276e858889803d7f341d735ea1d463a 100644 --- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainerRO.java +++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainerRO.java @@ -14,7 +14,10 @@ public interface PalettedContainerRO { @@ -1509,59 +1518,58 @@ index 9a2bf744abd8916d492e901be889223591bac3fd..1dd415c96d17eff8e7555c33d3c52e57 int getSerializedSize(); -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index cb5196f0ff7b9a59927c60b9d24c987a150e69f1..711541a9b12b823c1da779ed6027a53e9078a733 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -@@ -73,7 +73,7 @@ import org.slf4j.Logger; - - public class ChunkSerializer { +diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +index b86b3bf713668999a21c4120b1d16c295531b2ad..57998a47fa39cac141226c75bd68d4b37e8424ae 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java ++++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +@@ -111,6 +111,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun -- public static final Codec> BLOCK_STATE_CODEC = PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState()); -+ public static final Codec> BLOCK_STATE_CODEC = PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), null); // Paper - Anti-Xray - Add preset block states - private static final Logger LOGGER = LogUtils.getLogger(); - private static final String TAG_UPGRADE_DATA = "UpgradeData"; - private static final String BLOCK_TICKS_TAG = "block_ticks"; -@@ -141,13 +141,17 @@ public class ChunkSerializer { + @Nullable + public static SerializableChunkData parse(LevelHeightAccessor world, RegistryAccess registryManager, CompoundTag nbt) { ++ net.minecraft.server.level.ServerLevel serverLevel = (net.minecraft.server.level.ServerLevel) world; // Paper - Anti-Xray This is is seemingly only called from ChunkMap, where, we have a server level. We'll fight this later if needed. + if (!nbt.contains("Status", 8)) { + return null; + } else { +@@ -214,13 +215,17 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun - if (k >= 0 && k < achunksection.length) { - PalettedContainer datapaletteblock; -+ // Paper start - Anti-Xray - Add preset block states -+ BlockState[] presetBlockStates = world.chunkPacketBlockController.getPresetBlockStates(world, chunkPos, b0); + if (b0 >= world.getMinSectionY() && b0 <= world.getMaxSectionY()) { + PalettedContainer datapaletteblock; ++ // Paper start - Anti-Xray - Add preset block states ++ BlockState[] presetBlockStates = serverLevel.chunkPacketBlockController.getPresetBlockStates(serverLevel, chunkcoordintpair, b0); ++ - if (nbttagcompound1.contains("block_states", 10)) { -- datapaletteblock = (PalettedContainer) ChunkSerializer.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, nbttagcompound1.getCompound("block_states")).promotePartial((s) -> { -+ Codec> blockStateCodec = presetBlockStates == null ? ChunkSerializer.BLOCK_STATE_CODEC : PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), presetBlockStates); -+ datapaletteblock = blockStateCodec.parse(NbtOps.INSTANCE, nbttagcompound1.getCompound("block_states")).promotePartial((s) -> { - ChunkSerializer.logErrors(chunkPos, b0, s); - }).getOrThrow(ChunkSerializer.ChunkReadException::new); - } else { -- datapaletteblock = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES); -+ datapaletteblock = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, presetBlockStates); -+ // Paper end - } + if (nbttagcompound3.contains("block_states", 10)) { +- datapaletteblock = (PalettedContainer) SerializableChunkData.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, nbttagcompound3.getCompound("block_states")).promotePartial((s1) -> { ++ Codec> blockStateCodec = presetBlockStates == null ? ChunkSerializer.BLOCK_STATE_CODEC : PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), presetBlockStates); // Paper - Anti-Xray ++ datapaletteblock = blockStateCodec.parse(NbtOps.INSTANCE, nbttagcompound1.getCompound("block_states")).promotePartial((s1) -> { // Paper - Anti-Xray + logErrors(chunkcoordintpair, b0, s1); + }).getOrThrow(SerializableChunkData.ChunkReadException::new); + } else { +- datapaletteblock = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES); ++ datapaletteblock = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, presetBlockStates); // Paper - Anti-Xray + } - PalettedContainer object; // CraftBukkit - read/write -@@ -157,7 +161,7 @@ public class ChunkSerializer { - ChunkSerializer.logErrors(chunkPos, b0, s); - }).getOrThrow(ChunkSerializer.ChunkReadException::new); - } else { -- object = new PalettedContainer<>(iregistry.asHolderIdMap(), iregistry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES); -+ object = new PalettedContainer<>(iregistry.asHolderIdMap(), iregistry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); // Paper - Anti-Xray - Add preset biomes - } + PalettedContainer object; // CraftBukkit - read/write +@@ -230,7 +235,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + logErrors(chunkcoordintpair, b0, s1); + }).getOrThrow(SerializableChunkData.ChunkReadException::new); + } else { +- object = new PalettedContainer<>(iregistry.asHolderIdMap(), iregistry.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES); ++ object = new PalettedContainer<>(iregistry.asHolderIdMap(), iregistry.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); // Paper - Anti-Xray - Add preset biomes + } - LevelChunkSection chunksection = new LevelChunkSection(datapaletteblock, (PalettedContainer) object); // CraftBukkit - read/write -@@ -339,7 +343,7 @@ public class ChunkSerializer { + chunksection = new LevelChunkSection(datapaletteblock, (PalettedContainer) object); // CraftBukkit - read/write +@@ -391,7 +396,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun // CraftBukkit start - read/write private static Codec>> makeBiomeCodecRW(Registry iregistry) { -- return PalettedContainer.codecRW(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getHolderOrThrow(Biomes.PLAINS)); -+ return PalettedContainer.codecRW(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getHolderOrThrow(Biomes.PLAINS), null); // Paper - Anti-Xray - Add preset biomes +- return PalettedContainer.codecRW(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getOrThrow(Biomes.PLAINS)); ++ return PalettedContainer.codecRW(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getOrThrow(Biomes.PLAINS), null); // Paper - Anti-Xray - Add preset biomes } // CraftBukkit end diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java -index 33322b57b4c6922f4daad0f584733f0f24083911..45e262308aebafa377a2353661acdd122933b99e 100644 +index 5fc9e8e969debb3e15ed474b36a1c48b086d0449..f65cc95ab28e8a3b21eac2b16bd9ebe97e56e571 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -56,7 +56,7 @@ public class CraftChunk implements Chunk { @@ -1574,25 +1582,25 @@ index 33322b57b4c6922f4daad0f584733f0f24083911..45e262308aebafa377a2353661acdd12 private static final byte[] EMPTY_LIGHT = new byte[2048]; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 0bad47a4d45e9ca399de98edd0956efb90d21062..27f47383c8065cc3b421001028b6cba528c38865 100644 +index 6235d7caede85f4cf21dadde18d8080004672349..8548c4db6a1932d7de09bf27e583f51627f8c8ec 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2688,7 +2688,7 @@ public final class CraftServer implements Server { +@@ -2655,7 +2655,7 @@ public final class CraftServer implements Server { public ChunkGenerator.ChunkData createChunkData(World world) { Preconditions.checkArgument(world != null, "World cannot be null"); ServerLevel handle = ((CraftWorld) world).getHandle(); -- return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(Registries.BIOME)); -+ return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(Registries.BIOME), world); // Paper - Anti-Xray - Add parameters +- return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().lookupOrThrow(Registries.BIOME)); ++ return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().lookupOrThrow(Registries.BIOME), world); // Paper - Anti-Xray - Add parameters } @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 5ff343759cc0c5046a9d45e8f74d4e6ec63f0f91..359c5771f7e2a0843505787f051bb2a61e0dca57 100644 +index 149377347fc632358a8bb97e644b1c4ab9be413d..8367f0f344d42b6ccdfbe761be1735ac9a64bfab 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -470,11 +470,16 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -472,11 +472,16 @@ public class CraftWorld extends CraftRegionAccessor implements World { List playersInRange = playerChunk.playerProvider.getPlayers(playerChunk.getPos(), false); - if (playersInRange.isEmpty()) return true; // Paper - chunk system + if (playersInRange.isEmpty()) return; - ClientboundLevelChunkWithLightPacket refreshPacket = new ClientboundLevelChunkWithLightPacket(chunk, this.world.getLightEngine(), null, null); + // Paper start - Anti-Xray bypass @@ -1607,8 +1615,8 @@ index 5ff343759cc0c5046a9d45e8f74d4e6ec63f0f91..359c5771f7e2a0843505787f051bb2a6 + })); + // Paper end - Anti-Xray bypass } - // Paper - chunk system - + }); + }); diff --git a/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java b/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java index e7f7a246e9c03e676dadfee59de87b8b2ac55ba3..03eb35d5c67f125c44cf46595c93d124ac7892b8 100644 --- a/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java From 35e01d7a802b25ee85bb096e427496f3daa15dc0 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Thu, 24 Oct 2024 22:29:29 +0200 Subject: [PATCH 045/119] Update work 989 --- ...city-compression-and-cipher-natives.patch} | 8 ++-- ...timize-Collision-to-not-load-chunks.patch} | 41 +++++++++---------- ...alSelector-Goal.Flag-Set-operations.patch} | 28 ++++++------- .../0984-Optimize-Hoppers.patch} | 18 ++++---- .../0985-Optimize-Voxel-Shape-Merging.patch} | 6 +-- ...Optimize-Bit-Operations-by-inlining.patch} | 38 ++++++++--------- .../0987-Remove-streams-from-hot-code.patch} | 8 ++-- ...er-Remove-Streams-Optimized-collect.patch} | 25 +++++------ ...-type-tags-suggestions-in-selectors.patch} | 12 +++--- 9 files changed, 92 insertions(+), 92 deletions(-) rename patches/{unapplied/server/0996-Use-Velocity-compression-and-cipher-natives.patch => server/0981-Use-Velocity-compression-and-cipher-natives.patch} (98%) rename patches/{unapplied/server/0997-Optimize-Collision-to-not-load-chunks.patch => server/0982-Optimize-Collision-to-not-load-chunks.patch} (76%) rename patches/{unapplied/server/0998-Optimize-GoalSelector-Goal.Flag-Set-operations.patch => server/0983-Optimize-GoalSelector-Goal.Flag-Set-operations.patch} (91%) rename patches/{unapplied/server/0999-Optimize-Hoppers.patch => server/0984-Optimize-Hoppers.patch} (97%) rename patches/{unapplied/server/1001-Optimize-Voxel-Shape-Merging.patch => server/0985-Optimize-Voxel-Shape-Merging.patch} (96%) rename patches/{unapplied/server/1002-Optimize-Bit-Operations-by-inlining.patch => server/0986-Optimize-Bit-Operations-by-inlining.patch} (86%) rename patches/{unapplied/server/1003-Remove-streams-from-hot-code.patch => server/0987-Remove-streams-from-hot-code.patch} (97%) rename patches/{unapplied/server/1004-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch => server/0988-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch} (87%) rename patches/{unapplied/server/1006-Fix-entity-type-tags-suggestions-in-selectors.patch => server/0989-Fix-entity-type-tags-suggestions-in-selectors.patch} (96%) diff --git a/patches/unapplied/server/0996-Use-Velocity-compression-and-cipher-natives.patch b/patches/server/0981-Use-Velocity-compression-and-cipher-natives.patch similarity index 98% rename from patches/unapplied/server/0996-Use-Velocity-compression-and-cipher-natives.patch rename to patches/server/0981-Use-Velocity-compression-and-cipher-natives.patch index 5b7853e7ff1c..a57ddf2e8400 100644 --- a/patches/unapplied/server/0996-Use-Velocity-compression-and-cipher-natives.patch +++ b/patches/server/0981-Use-Velocity-compression-and-cipher-natives.patch @@ -5,12 +5,12 @@ Subject: [PATCH] Use Velocity compression and cipher natives diff --git a/build.gradle.kts b/build.gradle.kts -index 9de7a09c5f1b23754a2823978fa3ff218aadcfa7..4f6136ae3ac4890b21a5fb3f69f9c1474a0773d1 100644 +index 25001d6cf4f70bd01ab304625b49ec45f5b1f525..9966576652ed6007d2228237f292c1dc83ede485 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -37,6 +37,11 @@ dependencies { - runtimeOnly("org.xerial:sqlite-jdbc:3.46.0.0") - runtimeOnly("com.mysql:mysql-connector-j:8.4.0") + runtimeOnly("org.xerial:sqlite-jdbc:3.46.1.3") + runtimeOnly("com.mysql:mysql-connector-j:9.1.0") runtimeOnly("com.lmax:disruptor:3.4.4") // Paper + // Paper start - Use Velocity cipher + implementation("com.velocitypowered:velocity-native:3.3.0-SNAPSHOT") { @@ -352,7 +352,7 @@ index 4abe4f75956e4c16f8b4e0b2f77ad64d7914aa65..3a9e25b436f366fffe08c3b0c1fce11e protected void initChannel(Channel channel) { try { diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 35faa10f3b82504ae9d3f923fc04c5a99c1a624a..40638b439966619e9c70a18a32abd95b2178fe9f 100644 +index 4a89b73d972f366e70f4d2bd96c6ee413593baba..033755682c61c889723c3669b5cff4de147f637e 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -287,12 +287,14 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, diff --git a/patches/unapplied/server/0997-Optimize-Collision-to-not-load-chunks.patch b/patches/server/0982-Optimize-Collision-to-not-load-chunks.patch similarity index 76% rename from patches/unapplied/server/0997-Optimize-Collision-to-not-load-chunks.patch rename to patches/server/0982-Optimize-Collision-to-not-load-chunks.patch index 43e8bded4755..507c4c69ee8f 100644 --- a/patches/unapplied/server/0997-Optimize-Collision-to-not-load-chunks.patch +++ b/patches/server/0982-Optimize-Collision-to-not-load-chunks.patch @@ -14,22 +14,22 @@ 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 db0a5c6258fa2b9a5d960f82f6b1f3bc2b386bc9..3a90dd1289d393426151d4457edaf99731cc34db 100644 +index cde19fddfc9b1c8edbc565bec4f043803651313e..4b9761e58f404eedf9db835fc923a88fc1896e96 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -869,6 +869,7 @@ public abstract class PlayerList { - Vec3 vec3d = dimensiontransition.pos(); +@@ -827,6 +827,7 @@ public abstract class PlayerList { + Vec3 vec3d = teleporttransition.position(); - entityplayer1.forceSetPositionRotation(vec3d.x, vec3d.y, vec3d.z, dimensiontransition.yRot(), dimensiontransition.xRot()); + entityplayer1.forceSetPositionRotation(vec3d.x, vec3d.y, vec3d.z, teleporttransition.yRot(), teleporttransition.xRot()); + worldserver.getChunkSource().addRegionTicket(net.minecraft.server.level.TicketType.POST_TELEPORT, new net.minecraft.world.level.ChunkPos(net.minecraft.util.Mth.floor(vec3d.x()) >> 4, net.minecraft.util.Mth.floor(vec3d.z()) >> 4), 1, entityplayer.getId()); // Paper // CraftBukkit end - if (dimensiontransition.missingRespawnBlock()) { + if (teleporttransition.missingRespawnBlock()) { entityplayer1.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0F)); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 242d9213d22cb552e48beee03aa2db141e39d1c4..52f3d0d4ce28cc6566166ae9a5a1b236ff8c027d 100644 +index f4b1a773bf809bde8cea919a418700f3d6850389..ea7100c8ac5da730d55136ac2ab608c2a7ac0ba8 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -250,6 +250,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -258,6 +258,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // Paper end - Share random for entities to make them more random public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason @@ -38,10 +38,10 @@ index 242d9213d22cb552e48beee03aa2db141e39d1c4..52f3d0d4ce28cc6566166ae9a5a1b236 public CraftEntity getBukkitEntity() { diff --git a/src/main/java/net/minecraft/world/level/BlockCollisions.java b/src/main/java/net/minecraft/world/level/BlockCollisions.java -index 1c10835b59aaefa3a65ff64f784620bdc54ddcdc..cd89623a44f02d7db77f0d0f87545cf80841f403 100644 +index 12a14b8fdb079fd8c367e51299486761ebdaeb5b..b360594424118d9d11d00ea140160485048591ca 100644 --- a/src/main/java/net/minecraft/world/level/BlockCollisions.java +++ b/src/main/java/net/minecraft/world/level/BlockCollisions.java -@@ -66,18 +66,37 @@ public class BlockCollisions extends AbstractIterator { +@@ -72,16 +72,37 @@ public class BlockCollisions extends AbstractIterator { @Override protected T computeNext() { while (this.cursor.advance()) { @@ -58,8 +58,6 @@ index 1c10835b59aaefa3a65ff64f784620bdc54ddcdc..cd89623a44f02d7db77f0d0f87545cf8 - this.pos.set(i, j, k); - BlockState blockState = blockGetter.getBlockState(this.pos); - if ((!this.onlySuffocatingBlocks || blockState.isSuffocating(blockGetter, this.pos)) -- && (l != 1 || blockState.hasLargeCollisionShape()) -- && (l != 2 || blockState.is(Blocks.MOVING_PISTON))) { + // Paper start - ensure we don't load chunks + // BlockGetter blockGetter = this.getChunk(i, k); + if (true) { @@ -70,7 +68,7 @@ index 1c10835b59aaefa3a65ff64f784620bdc54ddcdc..cd89623a44f02d7db77f0d0f87545cf8 + if (this.collisionGetter instanceof net.minecraft.server.level.WorldGenRegion) { + BlockGetter blockGetter = this.getChunk(x, z); + if (blockGetter == null) { -+ continue; ++ continue; + } + blockState = blockGetter.getBlockState(this.pos); + } else if ((!far && source instanceof net.minecraft.server.level.ServerPlayer) || (source != null && source.collisionLoadChunks)) { @@ -84,21 +82,22 @@ index 1c10835b59aaefa3a65ff64f784620bdc54ddcdc..cd89623a44f02d7db77f0d0f87545cf8 + } + continue; + } -+ if (/*(!this.onlySuffocatingBlocks || blockState.isSuffocating(blockGetter, this.pos)) &&*/ (l != 1 || blockState.hasLargeCollisionShape()) && (l != 2 || blockState.is(Blocks.MOVING_PISTON))) { // Paper - onlySuffocatingBlocks is only true on the client, so we don't care about it here -+ // Paper end - VoxelShape voxelShape = blockState.getCollisionShape(this.collisionGetter, this.pos, this.context); - if (voxelShape == Shapes.block()) { - if (this.box.intersects((double)i, (double)j, (double)k, (double)i + 1.0, (double)j + 1.0, (double)k + 1.0)) { ++ if (true // onlySuffocatingBlocks is only true on the client, so we don't care about it here ++ // Paper end - ensure we don't load chunks + && (l != 1 || blockState.hasLargeCollisionShape()) + && (l != 2 || blockState.is(Blocks.MOVING_PISTON))) { + VoxelShape voxelShape = this.context.getCollisionShape(blockState, this.collisionGetter, this.pos); diff --git a/src/main/java/net/minecraft/world/level/CollisionGetter.java b/src/main/java/net/minecraft/world/level/CollisionGetter.java -index e57cb7fe53e915d24246e44c7f49971f5b2ab2cf..1ad0c976c6e2d6d31397dff850a9de7c16d16fba 100644 +index 6b63dc10c0a4db8a484588a6d67911ea1023457e..f4c251c2bcfa96ba22e338b97a1de7f0abac5a6f 100644 --- a/src/main/java/net/minecraft/world/level/CollisionGetter.java +++ b/src/main/java/net/minecraft/world/level/CollisionGetter.java -@@ -44,11 +44,13 @@ public interface CollisionGetter extends BlockGetter { +@@ -50,11 +50,13 @@ public interface CollisionGetter extends BlockGetter { } - default boolean noCollision(@Nullable Entity entity, AABB box) { + default boolean noCollision(@Nullable Entity entity, AABB box, boolean checkFluid) { +- for (VoxelShape voxelShape : checkFluid ? this.getBlockAndLiquidCollisions(entity, box) : this.getBlockCollisions(entity, box)) { + try { if (entity != null) entity.collisionLoadChunks = true; // Paper - for (VoxelShape voxelShape : this.getBlockCollisions(entity, box)) { ++ for (VoxelShape voxelShape : checkFluid ? this.getBlockAndLiquidCollisions(entity, box) : this.getBlockCollisions(entity, box)) { if (!voxelShape.isEmpty()) { return false; } diff --git a/patches/unapplied/server/0998-Optimize-GoalSelector-Goal.Flag-Set-operations.patch b/patches/server/0983-Optimize-GoalSelector-Goal.Flag-Set-operations.patch similarity index 91% rename from patches/unapplied/server/0998-Optimize-GoalSelector-Goal.Flag-Set-operations.patch rename to patches/server/0983-Optimize-GoalSelector-Goal.Flag-Set-operations.patch index 65f5e3531eaa..c4c7e7fd3530 100644 --- a/patches/unapplied/server/0998-Optimize-GoalSelector-Goal.Flag-Set-operations.patch +++ b/patches/server/0983-Optimize-GoalSelector-Goal.Flag-Set-operations.patch @@ -7,11 +7,11 @@ Optimise the stream.anyMatch statement to move to a bitset where we can replace the call with a single bitwise operation. diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java -index 16f9a98b8a939e5ca7e2dc04f87134a7ed66736b..47741efa48258c3c30b1d59504bf3121c236cadb 100644 +index acc25b08ed3b9f978229fa017d23f9fa0da519e3..71c952621580fe95730835ed0eab7c9852550030 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java -@@ -4,7 +4,16 @@ import java.util.EnumSet; - import net.minecraft.util.Mth; +@@ -7,7 +7,16 @@ import net.minecraft.world.entity.Entity; + import net.minecraft.world.level.Level; public abstract class Goal { - private final EnumSet flags = EnumSet.noneOf(Goal.Flag.class); @@ -28,7 +28,7 @@ index 16f9a98b8a939e5ca7e2dc04f87134a7ed66736b..47741efa48258c3c30b1d59504bf3121 public abstract boolean canUse(); -@@ -30,8 +39,13 @@ public abstract class Goal { +@@ -33,8 +42,13 @@ public abstract class Goal { } public void setFlags(EnumSet controls) { @@ -44,7 +44,7 @@ index 16f9a98b8a939e5ca7e2dc04f87134a7ed66736b..47741efa48258c3c30b1d59504bf3121 } @Override -@@ -39,8 +53,10 @@ public abstract class Goal { +@@ -42,8 +56,10 @@ public abstract class Goal { return this.getClass().getSimpleName(); } @@ -58,20 +58,20 @@ index 16f9a98b8a939e5ca7e2dc04f87134a7ed66736b..47741efa48258c3c30b1d59504bf3121 protected int adjustedTickDelay(int ticks) { diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java -index 074ef807258139f818e30494126585262c2f33c0..9bdbf3e9453bc3ce96d52d04b8cde0d05f7356d8 100644 +index d871975f943a04b49644dc6eb18314d65a7836dc..29ae74339a4831ccef3d01e8054931715ba192ad 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java -@@ -25,7 +25,8 @@ public class GoalSelector { +@@ -24,7 +24,8 @@ public class GoalSelector { + }; private final Map lockedFlags = new EnumMap<>(Goal.Flag.class); private final Set availableGoals = new ObjectLinkedOpenHashSet<>(); - private final Supplier profiler; - private final EnumSet disabledFlags = EnumSet.noneOf(Goal.Flag.class); + private static final Goal.Flag[] GOAL_FLAG_VALUES = Goal.Flag.values(); // Paper - remove streams from pathfindergoalselector + private final ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet goalTypes = new ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector - private int curRate; + private int curRate; // Paper - EAR 2 - public GoalSelector(Supplier profiler) { -@@ -65,18 +66,18 @@ public class GoalSelector { + public void addGoal(int priority, Goal goal) { +@@ -60,18 +61,18 @@ public class GoalSelector { this.availableGoals.removeIf(wrappedGoalx -> wrappedGoalx.getGoal() == goal); } @@ -99,7 +99,7 @@ index 074ef807258139f818e30494126585262c2f33c0..9bdbf3e9453bc3ce96d52d04b8cde0d0 if (!goalsByControl.getOrDefault(flag, NO_GOAL).canBeReplacedBy(goal)) { return false; } -@@ -90,7 +91,7 @@ public class GoalSelector { +@@ -85,7 +86,7 @@ public class GoalSelector { profilerFiller.push("goalCleanup"); for (WrappedGoal wrappedGoal : this.availableGoals) { @@ -108,7 +108,7 @@ index 074ef807258139f818e30494126585262c2f33c0..9bdbf3e9453bc3ce96d52d04b8cde0d0 wrappedGoal.stop(); } } -@@ -100,11 +101,14 @@ public class GoalSelector { +@@ -95,11 +96,14 @@ public class GoalSelector { profilerFiller.push("goalUpdate"); for (WrappedGoal wrappedGoal2 : this.availableGoals) { @@ -128,7 +128,7 @@ index 074ef807258139f818e30494126585262c2f33c0..9bdbf3e9453bc3ce96d52d04b8cde0d0 WrappedGoal wrappedGoal3 = this.lockedFlags.getOrDefault(flag, NO_GOAL); wrappedGoal3.stop(); this.lockedFlags.put(flag, wrappedGoal2); -@@ -136,11 +140,11 @@ public class GoalSelector { +@@ -131,11 +135,11 @@ public class GoalSelector { } public void disableControlFlag(Goal.Flag control) { diff --git a/patches/unapplied/server/0999-Optimize-Hoppers.patch b/patches/server/0984-Optimize-Hoppers.patch similarity index 97% rename from patches/unapplied/server/0999-Optimize-Hoppers.patch rename to patches/server/0984-Optimize-Hoppers.patch index 46ee4f4df0a2..d3f48217fc2f 100644 --- a/patches/unapplied/server/0999-Optimize-Hoppers.patch +++ b/patches/server/0984-Optimize-Hoppers.patch @@ -50,22 +50,22 @@ index 0000000000000000000000000000000000000000..5c42823726e70ce6c9d0121d07431548 + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 999e9c8f842423e6f1a3e80902e9d076e01f6694..c13b4f39c19dd6a62ae39688bde5a4739b391e59 100644 +index 21660e4284cfabb333a3edf9224c892ef80b2403..dcf046dd1eb8c2b724c971c4adf4462895183f0a 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1719,6 +1719,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent + net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers - this.profiler.push(() -> { + gameprofilerfiller.push(() -> { String s = String.valueOf(worldserver); diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 96b24c1415af531feef7d8ab4724f7fed3ae8388..eec0ec43590be7e8ae5b530a7404c98b5e23cb53 100644 +index 4f20e5bb143e152e19e5fb57f66d0344001ffbd9..888454ff588927e8accc215e7429f72bb286f5aa 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -809,10 +809,16 @@ public final class ItemStack implements DataComponentHolder { +@@ -876,10 +876,16 @@ public final class ItemStack implements DataComponentHolder { } public ItemStack copy() { @@ -85,7 +85,7 @@ index 96b24c1415af531feef7d8ab4724f7fed3ae8388..eec0ec43590be7e8ae5b530a7404c98b itemstack.setPopTime(this.getPopTime()); return itemstack; diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index a1d7ae987327382d9566860b991dc361225c7938..7dfabb11d3c8112f6daef35d204a2e324f4ddb5e 100644 +index b4aff394694417cff1930cf8fbd6696b9f9c9d01..fb00e5a02bb8c64e27d6d009068ba041098951d6 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java @@ -38,6 +38,7 @@ import co.aikar.timings.MinecraftTimings; // Paper @@ -96,7 +96,7 @@ index a1d7ae987327382d9566860b991dc361225c7938..7dfabb11d3c8112f6daef35d204a2e32 public Timing tickTimer = MinecraftTimings.getTileEntityTimings(this); // Paper // CraftBukkit start - data containers -@@ -229,6 +230,7 @@ public abstract class BlockEntity { +@@ -230,6 +231,7 @@ public abstract class BlockEntity { public void setChanged() { if (this.level != null) { @@ -105,7 +105,7 @@ index a1d7ae987327382d9566860b991dc361225c7938..7dfabb11d3c8112f6daef35d204a2e32 } diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index 542a5501ac94f57810d34e0f769a9a7855604f91..cab403efd471bb61835224eea4e99570d34dcaaa 100644 +index b35b44f0776aeb95ef0eda666ba0b652c5e90274..5ebbdb94d9b91c442ff60eb6872f740ebd790fa0 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java @@ -156,6 +156,43 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -650,7 +650,7 @@ index 542a5501ac94f57810d34e0f769a9a7855604f91..cab403efd471bb61835224eea4e99570 @Override diff --git a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java -index 13c9a68b604d4c7c6e09e72b3cea7ab2214b06ab..e2752752417c50b06f7c15b7d00bda0eaad3b0ae 100644 +index fc657b6052d4310ad9c28988042c2cf37cf5d213..a459163bd7148a27c60e030479df4da91e957049 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java @@ -53,7 +53,7 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc diff --git a/patches/unapplied/server/1001-Optimize-Voxel-Shape-Merging.patch b/patches/server/0985-Optimize-Voxel-Shape-Merging.patch similarity index 96% rename from patches/unapplied/server/1001-Optimize-Voxel-Shape-Merging.patch rename to patches/server/0985-Optimize-Voxel-Shape-Merging.patch index 114ee7cb28f2..52246713b3c5 100644 --- a/patches/unapplied/server/1001-Optimize-Voxel-Shape-Merging.patch +++ b/patches/server/0985-Optimize-Voxel-Shape-Merging.patch @@ -68,10 +68,10 @@ index e164c524aef4fa81fe96ac43454eecff1c38b9c1..9cfbbc61fcfc678f0988d6d45c7994d1 this.firstIndices = new int[k]; this.secondIndices = new int[k]; diff --git a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java -index 7ede56f77af1d40e10fde2e660d5794e4b37dc5d..c348171c150bf69d24303d0862e45ab78baddcab 100644 +index 5a0b0b47da3d796c391ac15eb573af25a1dfcd32..76d7435e6fe81a3f1d24b35eae72d06232a1792b 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java +++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java -@@ -343,9 +343,21 @@ public final class Shapes { +@@ -267,9 +267,21 @@ public final class Shapes { } @VisibleForTesting @@ -94,7 +94,7 @@ index 7ede56f77af1d40e10fde2e660d5794e4b37dc5d..c348171c150bf69d24303d0862e45ab7 if (first instanceof CubePointRange && second instanceof CubePointRange) { long l = lcm(i, j); if ((long)size * l <= 256L) { -@@ -353,15 +365,22 @@ public final class Shapes { +@@ -277,15 +289,22 @@ public final class Shapes { } } diff --git a/patches/unapplied/server/1002-Optimize-Bit-Operations-by-inlining.patch b/patches/server/0986-Optimize-Bit-Operations-by-inlining.patch similarity index 86% rename from patches/unapplied/server/1002-Optimize-Bit-Operations-by-inlining.patch rename to patches/server/0986-Optimize-Bit-Operations-by-inlining.patch index b7d93a56b9b5..b9547eb68c7d 100644 --- a/patches/unapplied/server/1002-Optimize-Bit-Operations-by-inlining.patch +++ b/patches/server/0986-Optimize-Bit-Operations-by-inlining.patch @@ -7,36 +7,36 @@ Inline bit operations and reduce instruction count to make these hot operations faster diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java -index 12ff8886bb53ca15db745989c25b9bd2f45335e4..2767d6f97e8b314d23a8e62f22dfd396f5660d31 100644 +index 0d51fb4be8b49e3b57c3c55aff6bcf13d5c78ddd..afbd1651cb29e95b5cc7474f986c52c29676fb8a 100644 --- a/src/main/java/net/minecraft/core/BlockPos.java +++ b/src/main/java/net/minecraft/core/BlockPos.java -@@ -50,15 +50,16 @@ public class BlockPos extends Vec3i { +@@ -50,15 +50,17 @@ public class BlockPos extends Vec3i { }; private static final Logger LOGGER = LogUtils.getLogger(); public static final BlockPos ZERO = new BlockPos(0, 0, 0); -- private static final int PACKED_X_LENGTH = 1 + Mth.log2(Mth.smallestEncompassingPowerOfTwo(30000000)); -- private static final int PACKED_Z_LENGTH = PACKED_X_LENGTH; -- public static final int PACKED_Y_LENGTH = 64 - PACKED_X_LENGTH - PACKED_Z_LENGTH; -- private static final long PACKED_X_MASK = (1L << PACKED_X_LENGTH) - 1L; +- public static final int PACKED_HORIZONTAL_LENGTH = 1 + Mth.log2(Mth.smallestEncompassingPowerOfTwo(30000000)); +- public static final int PACKED_Y_LENGTH = 64 - 2 * PACKED_HORIZONTAL_LENGTH; +- private static final long PACKED_X_MASK = (1L << PACKED_HORIZONTAL_LENGTH) - 1L; - private static final long PACKED_Y_MASK = (1L << PACKED_Y_LENGTH) - 1L; -- private static final long PACKED_Z_MASK = (1L << PACKED_Z_LENGTH) - 1L; -- private static final int Y_OFFSET = 0; -- private static final int Z_OFFSET = PACKED_Y_LENGTH; -- private static final int X_OFFSET = PACKED_Y_LENGTH + PACKED_Z_LENGTH; +- private static final long PACKED_Z_MASK = (1L << PACKED_HORIZONTAL_LENGTH) - 1L; + // Paper start - Optimize Bit Operations by inlining -+ private static final int PACKED_X_LENGTH = 26; -+ private static final int PACKED_Z_LENGTH = 26; ++ private static final int PACKED_HORIZONTAL_LENGTH = 26; + public static final int PACKED_Y_LENGTH = 12; + private static final long PACKED_X_MASK = 67108863; + private static final long PACKED_Y_MASK = 4095; + private static final long PACKED_Z_MASK = 67108863; + private static final int Y_OFFSET = 0; +- private static final int Z_OFFSET = PACKED_Y_LENGTH; +- private static final int X_OFFSET = PACKED_Y_LENGTH + PACKED_HORIZONTAL_LENGTH; +- public static final int MAX_HORIZONTAL_COORDINATE = (1 << PACKED_HORIZONTAL_LENGTH) / 2 - 1; + private static final int Z_OFFSET = 12; + private static final int X_OFFSET = 38; ++ public static final int MAX_HORIZONTAL_COORDINATE = 33554431; + // Paper end - Optimize Bit Operations by inlining public BlockPos(int x, int y, int z) { super(x, y, z); -@@ -68,28 +69,29 @@ public class BlockPos extends Vec3i { +@@ -68,28 +70,29 @@ public class BlockPos extends Vec3i { this(pos.getX(), pos.getY(), pos.getZ()); } @@ -51,7 +51,7 @@ index 12ff8886bb53ca15db745989c25b9bd2f45335e4..2767d6f97e8b314d23a8e62f22dfd396 } public static int getX(long packedPos) { -- return (int)(packedPos << 64 - X_OFFSET - PACKED_X_LENGTH >> 64 - PACKED_X_LENGTH); +- return (int)(packedPos << 64 - X_OFFSET - PACKED_HORIZONTAL_LENGTH >> 64 - PACKED_HORIZONTAL_LENGTH); + return (int) (packedPos >> 38); // Paper - simplify/inline } @@ -61,7 +61,7 @@ index 12ff8886bb53ca15db745989c25b9bd2f45335e4..2767d6f97e8b314d23a8e62f22dfd396 } public static int getZ(long packedPos) { -- return (int)(packedPos << 64 - Z_OFFSET - PACKED_Z_LENGTH >> 64 - PACKED_Z_LENGTH); +- return (int)(packedPos << 64 - Z_OFFSET - PACKED_HORIZONTAL_LENGTH >> 64 - PACKED_HORIZONTAL_LENGTH); + return (int) ((packedPos << 26) >> 38); // Paper - simplify/inline } @@ -71,7 +71,7 @@ index 12ff8886bb53ca15db745989c25b9bd2f45335e4..2767d6f97e8b314d23a8e62f22dfd396 } public static BlockPos containing(double x, double y, double z) { -@@ -113,10 +115,7 @@ public class BlockPos extends Vec3i { +@@ -113,10 +116,7 @@ public class BlockPos extends Vec3i { } public static long asLong(int x, int y, int z) { @@ -84,7 +84,7 @@ index 12ff8886bb53ca15db745989c25b9bd2f45335e4..2767d6f97e8b314d23a8e62f22dfd396 public static long getFlatIndex(long y) { diff --git a/src/main/java/net/minecraft/core/SectionPos.java b/src/main/java/net/minecraft/core/SectionPos.java -index 27e0d53d5893a13a340deddc93a1128968db7e5b..fe3577e533fb829c85fd4881b1bcca3b70aaf1a5 100644 +index 14e852684dcbba43abab0ec7de38f4fc09babd27..137a15e142c6e934804e3f2a072cdac8d40a2ab2 100644 --- a/src/main/java/net/minecraft/core/SectionPos.java +++ b/src/main/java/net/minecraft/core/SectionPos.java @@ -38,7 +38,7 @@ public class SectionPos extends Vec3i { @@ -206,8 +206,8 @@ index 27e0d53d5893a13a340deddc93a1128968db7e5b..fe3577e533fb829c85fd4881b1bcca3b public static Stream aroundChunk(ChunkPos center, int radius, int minY, int maxY) { - int i = center.x; - int j = center.z; -- return betweenClosedStream(i - radius, minY, j - radius, i + radius, maxY - 1, j + radius); -+ return betweenClosedStream(center.x - radius, 0, center.z - radius, center.x + radius, 15, center.z + radius); // Paper - simplify/inline +- return betweenClosedStream(i - radius, minY, j - radius, i + radius, maxY, j + radius); ++ return betweenClosedStream(center.x - radius, minY, center.z - radius, center.x + radius, maxY, center.z + radius); // Paper - simplify/inline } public static Stream betweenClosedStream(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { diff --git a/patches/unapplied/server/1003-Remove-streams-from-hot-code.patch b/patches/server/0987-Remove-streams-from-hot-code.patch similarity index 97% rename from patches/unapplied/server/1003-Remove-streams-from-hot-code.patch rename to patches/server/0987-Remove-streams-from-hot-code.patch index 4c6d94f7bf80..37416513dc5c 100644 --- a/patches/unapplied/server/1003-Remove-streams-from-hot-code.patch +++ b/patches/server/0987-Remove-streams-from-hot-code.patch @@ -157,7 +157,7 @@ index aa32804bc9affe9a615d3ffaa513f6f09aab3f32..c7f012674361a323c1efeca4660cd3f4 public Stream unpack(UUID target) { diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java -index 28fd073ddad358e087e8c78985a97cad21be81b7..a5bd308d1b3ea5db185c06a287167d1d8894a987 100644 +index ba6fd4df02d3097d3ea4273092e27592893de445..de768cf877b899f640b5e13ea9ea9c6410a2e79e 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java @@ -24,13 +24,17 @@ public class NearestItemSensor extends Sensor { @@ -165,11 +165,11 @@ index 28fd073ddad358e087e8c78985a97cad21be81b7..a5bd308d1b3ea5db185c06a287167d1d protected void doTick(ServerLevel world, Mob entity) { Brain brain = entity.getBrain(); - List list = world.getEntitiesOfClass(ItemEntity.class, entity.getBoundingBox().inflate(32.0, 16.0, 32.0), itemEntity -> true); -+ List list = world.getEntitiesOfClass(ItemEntity.class, entity.getBoundingBox().inflate(32.0, 16.0, 32.0), itemEntity -> itemEntity.closerThan(entity, MAX_DISTANCE_TO_WANTED_ITEM) && entity.wantsToPickUp(itemEntity.getItem())); // Paper - Perf: Move predicate into getEntities ++ List list = world.getEntitiesOfClass(ItemEntity.class, entity.getBoundingBox().inflate(32.0, 16.0, 32.0), itemEntity -> itemEntity.closerThan(entity, MAX_DISTANCE_TO_WANTED_ITEM) && entity.wantsToPickUp(world, itemEntity.getItem())); // Paper - Perf: Move predicate into getEntities list.sort(Comparator.comparingDouble(entity::distanceToSqr)); - Optional optional = list.stream() -- .filter(itemEntity -> entity.wantsToPickUp(itemEntity.getItem())) -- .filter(itemEntity -> itemEntity.closerThan(entity, 32.0)) +- .filter(itemEntity -> entity.wantsToPickUp(world, itemEntity.getItem())) +- .filter(itemEntityx -> itemEntityx.closerThan(entity, 32.0)) - .filter(entity::hasLineOfSight) - .findFirst(); - brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, optional); diff --git a/patches/unapplied/server/1004-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch b/patches/server/0988-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch similarity index 87% rename from patches/unapplied/server/1004-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch rename to patches/server/0988-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch index 6fc4445bbf80..b32ebf6b4eab 100644 --- a/patches/unapplied/server/1004-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch +++ b/patches/server/0988-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch @@ -16,10 +16,10 @@ This lets us get faster foreach iteration, as well as avoids map lookups on the values when needed. diff --git a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java -index 8a483c8d2a54617d78af19de32fa0ded71b3223a..18bbb3f8f99849333ff4bc020c8ce758a69312a5 100644 +index 17006cd22152cf942455437ff7b21a8645259578..cc7d94144e39f7dace7b569b4567def98396e8f9 100644 --- a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java +++ b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java -@@ -38,8 +38,12 @@ public class PathFinder { +@@ -43,8 +43,12 @@ public class PathFinder { if (node == null) { return null; } else { @@ -31,18 +31,19 @@ index 8a483c8d2a54617d78af19de32fa0ded71b3223a..18bbb3f8f99849333ff4bc020c8ce758 + map.add(new java.util.AbstractMap.SimpleEntry<>(this.nodeEvaluator.getTarget(pos.getX(), pos.getY(), pos.getZ()), pos)); + } + // Paper end - Perf: remove streams and optimize collection - Path path = this.findPath(world.getProfiler(), node, map, followRange, distance, rangeMultiplier); + Path path = this.findPath(node, map, followRange, distance, rangeMultiplier); this.nodeEvaluator.done(); return path; -@@ -47,18 +51,19 @@ public class PathFinder { +@@ -52,19 +56,20 @@ public class PathFinder { } @Nullable -- private Path findPath(ProfilerFiller profiler, Node startNode, Map positions, float followRange, int distance, float rangeMultiplier) { +- private Path findPath(Node startNode, Map positions, float followRange, int distance, float rangeMultiplier) { + // Paper start - Perf: remove streams and optimize collection -+ private Path findPath(ProfilerFiller profiler, Node startNode, List> positions, float followRange, int distance, float rangeMultiplier) { - profiler.push("find_path"); - profiler.markForCharting(MetricCategory.PATH_FINDING); ++ private Path findPath(Node startNode, List> positions, float followRange, int distance, float rangeMultiplier) { + ProfilerFiller profilerFiller = Profiler.get(); + profilerFiller.push("find_path"); + profilerFiller.markForCharting(MetricCategory.PATH_FINDING); - Set set = positions.keySet(); + // Set set = positions.keySet(); startNode.g = 0.0F; @@ -59,7 +60,7 @@ index 8a483c8d2a54617d78af19de32fa0ded71b3223a..18bbb3f8f99849333ff4bc020c8ce758 int j = (int)((float)this.maxVisitedNodes * rangeMultiplier); while (!this.openSet.isEmpty()) { -@@ -69,14 +74,18 @@ public class PathFinder { +@@ -75,14 +80,18 @@ public class PathFinder { Node node = this.openSet.pop(); node.closed = true; @@ -81,7 +82,7 @@ index 8a483c8d2a54617d78af19de32fa0ded71b3223a..18bbb3f8f99849333ff4bc020c8ce758 break; } -@@ -91,7 +100,7 @@ public class PathFinder { +@@ -97,7 +106,7 @@ public class PathFinder { if (node2.walkedDistance < followRange && (!node2.inOpenSet() || g < node2.g)) { node2.cameFrom = node; node2.g = g; @@ -90,7 +91,7 @@ index 8a483c8d2a54617d78af19de32fa0ded71b3223a..18bbb3f8f99849333ff4bc020c8ce758 if (node2.inOpenSet()) { this.openSet.changeCost(node2, node2.g + node2.h); } else { -@@ -103,23 +112,32 @@ public class PathFinder { +@@ -109,23 +118,32 @@ public class PathFinder { } } @@ -109,7 +110,7 @@ index 8a483c8d2a54617d78af19de32fa0ded71b3223a..18bbb3f8f99849333ff4bc020c8ce758 + if (best == null || comparator.compare(path, best) < 0) + best = path; + } - profiler.pop(); + profilerFiller.pop(); - return optional.isEmpty() ? null : optional.get(); + return best; + // Paper end - Perf: remove streams and optimize collection diff --git a/patches/unapplied/server/1006-Fix-entity-type-tags-suggestions-in-selectors.patch b/patches/server/0989-Fix-entity-type-tags-suggestions-in-selectors.patch similarity index 96% rename from patches/unapplied/server/1006-Fix-entity-type-tags-suggestions-in-selectors.patch rename to patches/server/0989-Fix-entity-type-tags-suggestions-in-selectors.patch index b53d0185a77b..7fdb68ae3b5e 100644 --- a/patches/unapplied/server/1006-Fix-entity-type-tags-suggestions-in-selectors.patch +++ b/patches/server/0989-Fix-entity-type-tags-suggestions-in-selectors.patch @@ -10,10 +10,10 @@ when if this was fixed on the client, that wouldn't be needed. Mojira Issue: https://bugs.mojang.com/browse/MC-235045 diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java -index 4017b82e72fefd6685e9250a936686fd8a0891f1..2d344df35d47b4b1ecddf32ccaa4dae41e5f58cb 100644 +index 3549ffea451b932602efb113844ba21a7bc72371..13bd145b1e8006a53c22f5dc0c78f29b540c7663 100644 --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java +++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java -@@ -447,4 +447,20 @@ public class CommandSourceStack implements ExecutionCommandSource !org.spigotmc.SpigotConfig.sendNamespaced && node.getName().contains( ":" )); // Paper - Remove namedspaced from result nodes to prevent redirect trimming ~ see comment below Iterator iterator = tree.getChildren().iterator(); @@ -46,7 +46,7 @@ index 74fcdc74dc6c5cbf81abb7d46fc700473bd00eff..5ff234c4efdc5347e01ad74737516061 while (iterator.hasNext()) { CommandNode commandnode2 = (CommandNode) iterator.next(); // Paper start - Brigadier API -@@ -591,6 +592,12 @@ public class Commands { +@@ -596,6 +597,12 @@ public class Commands { if (requiredargumentbuilder.getSuggestionsProvider() != null) { requiredargumentbuilder.suggests(SuggestionProviders.safelySwap(requiredargumentbuilder.getSuggestionsProvider())); @@ -114,7 +114,7 @@ index 9d31e29ec62f437e642ed60da69c4b106bd9e770..ce200e673b54c66cfdf34657db28d3ee this.level = MinMaxBounds.Ints.ANY; this.rotX = WrappedMinMaxBounds.ANY; diff --git a/src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java b/src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java -index 44982ff2cdd6e03f0b9ce8c3cc87561ef183ef06..626fe7a45c2edba68eb201974e9f8f5eebf75cc0 100644 +index 5d0c82ba9465bf75640e52bf71924ee5862937f0..e27bd295adcf3289a7c71e044ae392884fe01e0a 100644 --- a/src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java +++ b/src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java @@ -76,6 +76,19 @@ public class EntitySelectorOptions { From 7616ebccd84d934180e27ae952ad11149b7fc1e9 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Thu, 24 Oct 2024 23:03:27 +0200 Subject: [PATCH 046/119] 1000 --- ...-Oversized-block-entities-in-chunks.patch} | 0 ...eck-distance-in-entity-interactions.patch} | 24 ++-- .../0992-Configurable-Sand-Duping.patch} | 6 +- .../0993-Properly-resend-entities.patch} | 51 ++++---- .../0994-Registry-Modification-API.patch} | 119 +++++++++--------- ...995-Add-registry-entry-and-builders.patch} | 0 ...6-Proxy-ItemStack-to-CraftItemStack.patch} | 16 +-- ...-accessible-directly-from-ItemStack.patch} | 4 +- ...aft-commands-in-function-parsing-an.patch} | 4 +- ...99-optimize-dirt-and-snow-spreading.patch} | 2 +- .../1000-Fix-NPE-for-Jukebox-setRecord.patch} | 4 +- 11 files changed, 115 insertions(+), 115 deletions(-) rename patches/{unapplied/server/1007-Handle-Oversized-block-entities-in-chunks.patch => server/0990-Handle-Oversized-block-entities-in-chunks.patch} (100%) rename patches/{unapplied/server/1009-Check-distance-in-entity-interactions.patch => server/0991-Check-distance-in-entity-interactions.patch} (79%) rename patches/{unapplied/server/1010-Configurable-Sand-Duping.patch => server/0992-Configurable-Sand-Duping.patch} (80%) rename patches/{unapplied/server/1013-Properly-resend-entities.patch => server/0993-Properly-resend-entities.patch} (88%) rename patches/{unapplied/server/1014-Registry-Modification-API.patch => server/0994-Registry-Modification-API.patch} (94%) rename patches/{unapplied/server/1015-Add-registry-entry-and-builders.patch => server/0995-Add-registry-entry-and-builders.patch} (100%) rename patches/{unapplied/server/1017-Proxy-ItemStack-to-CraftItemStack.patch => server/0996-Proxy-ItemStack-to-CraftItemStack.patch} (95%) rename patches/{unapplied/server/1018-Make-a-PDC-view-accessible-directly-from-ItemStack.patch => server/0997-Make-a-PDC-view-accessible-directly-from-ItemStack.patch} (98%) rename patches/{unapplied/server/1019-Prioritize-Minecraft-commands-in-function-parsing-an.patch => server/0998-Prioritize-Minecraft-commands-in-function-parsing-an.patch} (98%) rename patches/{unapplied/server/1020-optimize-dirt-and-snow-spreading.patch => server/0999-optimize-dirt-and-snow-spreading.patch} (98%) rename patches/{unapplied/server/1021-Fix-NPE-for-Jukebox-setRecord.patch => server/1000-Fix-NPE-for-Jukebox-setRecord.patch} (87%) diff --git a/patches/unapplied/server/1007-Handle-Oversized-block-entities-in-chunks.patch b/patches/server/0990-Handle-Oversized-block-entities-in-chunks.patch similarity index 100% rename from patches/unapplied/server/1007-Handle-Oversized-block-entities-in-chunks.patch rename to patches/server/0990-Handle-Oversized-block-entities-in-chunks.patch diff --git a/patches/unapplied/server/1009-Check-distance-in-entity-interactions.patch b/patches/server/0991-Check-distance-in-entity-interactions.patch similarity index 79% rename from patches/unapplied/server/1009-Check-distance-in-entity-interactions.patch rename to patches/server/0991-Check-distance-in-entity-interactions.patch index 95e8e99b56e3..d628cdfbc010 100644 --- a/patches/unapplied/server/1009-Check-distance-in-entity-interactions.patch +++ b/patches/server/0991-Check-distance-in-entity-interactions.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Check distance in entity interactions diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java -index 42d7ecfab6f72517904451d9df3f0404b176fdb2..0e38a641d8e537750166b56c57aca4a90d418af1 100644 +index 60e523f4de1cbafc2c58a5d568fe3989b7b07c34..dd2037fe9389765f79330036ec7fa3c5e7c7327a 100644 --- a/src/main/java/net/minecraft/Util.java +++ b/src/main/java/net/minecraft/Util.java -@@ -125,6 +125,7 @@ public class Util { +@@ -128,6 +128,7 @@ public class Util { .filter(fileSystemProvider -> fileSystemProvider.getScheme().equalsIgnoreCase("jar")) .findFirst() .orElseThrow(() -> new IllegalStateException("No jar file system provider found")); @@ -17,10 +17,10 @@ index 42d7ecfab6f72517904451d9df3f0404b176fdb2..0e38a641d8e537750166b56c57aca4a9 }; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 340c4452c09a98bc0220e6fe68dc65afc946986b..05dae689ada8d96009e81aabf95a626bae90ecd3 100644 +index 6195b207159c638e98a33c3142ed6b0720c8e14d..f12c59d3bb15f482969cc9d0d2aff0718972675b 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1437,7 +1437,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1469,7 +1469,7 @@ public abstract class LivingEntity extends Entity implements Attackable { if (!source.is(DamageTypeTags.IS_PROJECTILE)) { Entity entity = source.getDirectEntity(); @@ -29,7 +29,7 @@ index 340c4452c09a98bc0220e6fe68dc65afc946986b..05dae689ada8d96009e81aabf95a626b LivingEntity entityliving = (LivingEntity) entity; this.blockUsingShield(entityliving); -@@ -1557,6 +1557,14 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1593,6 +1593,14 @@ public abstract class LivingEntity extends Entity implements Attackable { d0 = source.getSourcePosition().x() - this.getX(); d1 = source.getSourcePosition().z() - this.getZ(); } @@ -44,7 +44,7 @@ index 340c4452c09a98bc0220e6fe68dc65afc946986b..05dae689ada8d96009e81aabf95a626b this.knockback(0.4000000059604645D, d0, d1, entity1, entity1 == null ? io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE : io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // CraftBukkit // Paper - knockback events if (!flag) { -@@ -2351,7 +2359,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2428,7 +2436,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.hurtCurrentlyUsedShield((float) -event.getDamage(DamageModifier.BLOCKING)); Entity entity = damagesource.getDirectEntity(); @@ -53,16 +53,16 @@ index 340c4452c09a98bc0220e6fe68dc65afc946986b..05dae689ada8d96009e81aabf95a626b this.blockUsingShield((LivingEntity) entity); } } -diff --git a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java -index 907f751c859855484151fb5d607acee2f2a35076..f1955afc8e367f80ead85bd5ad3b8d66c255565a 100644 ---- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java -+++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java -@@ -718,7 +718,7 @@ public class Boat extends VehicleEntity implements Leashable, VariantHolder accessor; diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index e9dcdb1e09e84a9b451034ff4bdfa6eae2dd1c04..24b1715397ba8e6f5e9841a030d0e3d964356f89 100644 +index f2dd272a01b4e946a6746865d55ebc9861f8361b..5d189ba60d40f5c42b2dacc339594ed067418e95 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -561,6 +561,7 @@ public class ServerPlayerGameMode { +@@ -567,6 +567,7 @@ public class ServerPlayerGameMode { } // Paper end - extend Player Interact cancellation player.getBukkitEntity().updateInventory(); // SPIGOT-2867 @@ -68,7 +68,7 @@ index e9dcdb1e09e84a9b451034ff4bdfa6eae2dd1c04..24b1715397ba8e6f5e9841a030d0e3d9 return (event.useItemInHand() != Event.Result.ALLOW) ? InteractionResult.SUCCESS : InteractionResult.PASS; } else if (this.gameModeForPlayer == GameType.SPECTATOR) { MenuProvider itileinventory = iblockdata.getMenuProvider(world, blockposition); -@@ -612,6 +613,11 @@ public class ServerPlayerGameMode { +@@ -618,6 +619,11 @@ public class ServerPlayerGameMode { return enuminteractionresult; } else { @@ -81,10 +81,10 @@ index e9dcdb1e09e84a9b451034ff4bdfa6eae2dd1c04..24b1715397ba8e6f5e9841a030d0e3d9 } } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 0034483685ba626e5883b857de96ffd36e57e150..4c04eb531b6989f7e618d201ecaa84298eab52c4 100644 +index 46f4d7a05d4febd1f8fd3cc2cae635a9e3da0e9e..14a8e05420ae4ca2f1d9028e19379d162a3e6971 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1948,6 +1948,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1966,6 +1966,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } if (cancelled) { @@ -92,7 +92,7 @@ index 0034483685ba626e5883b857de96ffd36e57e150..4c04eb531b6989f7e618d201ecaa8429 this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524 return; } -@@ -2717,7 +2718,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2737,7 +2738,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Entity in bucket - SPIGOT-4048 and SPIGOT-6859a if ((entity instanceof Bucketable && entity instanceof LivingEntity && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null || ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem() != origItem)) { @@ -102,10 +102,10 @@ index 0034483685ba626e5883b857de96ffd36e57e150..4c04eb531b6989f7e618d201ecaa8429 } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 3a90dd1289d393426151d4457edaf99731cc34db..ec058eb6a10500831f173dcb47576c32c7516318 100644 +index 4b9761e58f404eedf9db835fc923a88fc1896e96..682b8926027945066921086b6773b31e626cc941 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -393,7 +393,7 @@ public abstract class PlayerList { +@@ -397,7 +397,7 @@ public abstract class PlayerList { ((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - Fire PlayerJoinEvent when Player is actually ready; track entity now // CraftBukkit end @@ -114,7 +114,7 @@ index 3a90dd1289d393426151d4457edaf99731cc34db..ec058eb6a10500831f173dcb47576c32 this.sendLevelInfo(player, worldserver1); -@@ -948,12 +948,17 @@ public abstract class PlayerList { +@@ -908,12 +908,17 @@ public abstract class PlayerList { } public void sendActiveEffects(LivingEntity entity, ServerGamePacketListenerImpl networkHandler) { @@ -134,10 +134,10 @@ index 3a90dd1289d393426151d4457edaf99731cc34db..ec058eb6a10500831f173dcb47576c32 } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 52f3d0d4ce28cc6566166ae9a5a1b236ff8c027d..74231cb1c89079473d1727aa3ae2a539d4250317 100644 +index ea7100c8ac5da730d55136ac2ab608c2a7ac0ba8..4f0ff0d333d2de1b4f6beac1ce25e214b971e387 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -684,13 +684,45 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -598,13 +598,45 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // CraftBukkit start public void refreshEntityData(ServerPlayer to) { @@ -186,10 +186,10 @@ index 52f3d0d4ce28cc6566166ae9a5a1b236ff8c027d..74231cb1c89079473d1727aa3ae2a539 public boolean equals(Object object) { return object instanceof Entity ? ((Entity) object).id == this.id : false; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 05dae689ada8d96009e81aabf95a626bae90ecd3..3b15995efc65a351da8dac009b9698494771fefb 100644 +index f12c59d3bb15f482969cc9d0d2aff0718972675b..f75b66c9ec786bc6f4d3f5cd5127c815f11166c4 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3879,6 +3879,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4031,6 +4031,11 @@ public abstract class LivingEntity extends Entity implements Attackable { return ((Byte) this.entityData.get(LivingEntity.DATA_LIVING_ENTITY_FLAGS) & 2) > 0 ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND; } @@ -202,7 +202,7 @@ index 05dae689ada8d96009e81aabf95a626bae90ecd3..3b15995efc65a351da8dac009b969849 if (this.isUsingItem()) { if (ItemStack.isSameItem(this.getItemInHand(this.getUsedItemHand()), this.useItem)) { diff --git a/src/main/java/net/minecraft/world/entity/animal/Bucketable.java b/src/main/java/net/minecraft/world/entity/animal/Bucketable.java -index b586116d8cca1585f9c9e618ed4d0cb2ef2747be..acf38ef6d8de8b15cf2b09eb7bda390c4e446e9a 100644 +index 5a12f4c1de2d020e84af933d491397b38d227824..4eca5996a867086be22d22d99db81ab001467516 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Bucketable.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bucketable.java @@ -108,8 +108,7 @@ public interface Bucketable { @@ -215,32 +215,31 @@ index b586116d8cca1585f9c9e618ed4d0cb2ef2747be..acf38ef6d8de8b15cf2b09eb7bda390c return Optional.of(InteractionResult.FAIL); } entity.playSound(((Bucketable) entity).getPickupSound(), 1.0F, 1.0F); -diff --git a/src/main/java/net/minecraft/world/item/SuspiciousStewItem.java b/src/main/java/net/minecraft/world/item/SuspiciousStewItem.java -index 5b448006debecab983167d15fac59fc2a04805df..9523db353df026f33d7e859788612b97542bd001 100644 ---- a/src/main/java/net/minecraft/world/item/SuspiciousStewItem.java -+++ b/src/main/java/net/minecraft/world/item/SuspiciousStewItem.java -@@ -58,10 +58,14 @@ public class SuspiciousStewItem extends Item { +diff --git a/src/main/java/net/minecraft/world/item/component/SuspiciousStewEffects.java b/src/main/java/net/minecraft/world/item/component/SuspiciousStewEffects.java +index 04760d8ba7c560bd9d11191c666715ae8c3e4bff..768f90682cd10045c16337fecc2702f57dfe8a50 100644 +--- a/src/main/java/net/minecraft/world/item/component/SuspiciousStewEffects.java ++++ b/src/main/java/net/minecraft/world/item/component/SuspiciousStewEffects.java +@@ -47,9 +47,14 @@ public record SuspiciousStewEffects(List effects) i + // CraftBukkit start + @Override public void cancelUsingItem(net.minecraft.server.level.ServerPlayer entityplayer, ItemStack itemstack) { - SuspiciousStewEffects suspicioussteweffects = (SuspiciousStewEffects) itemstack.getOrDefault(DataComponents.SUSPICIOUS_STEW_EFFECTS, SuspiciousStewEffects.EMPTY); - + final List> packets = new java.util.ArrayList<>(); // Paper - bundlize packets - for (SuspiciousStewEffects.Entry suspicioussteweffects_a : suspicioussteweffects.effects()) { + for (SuspiciousStewEffects.Entry suspicioussteweffects_a : this.effects) { - entityplayer.connection.send(new net.minecraft.network.protocol.game.ClientboundRemoveMobEffectPacket(entityplayer.getId(), suspicioussteweffects_a.effect())); + packets.add(new net.minecraft.network.protocol.game.ClientboundRemoveMobEffectPacket(entityplayer.getId(), suspicioussteweffects_a.effect())); // Paper - bundlize packets } -- entityplayer.server.getPlayerList().sendActivePlayerEffects(entityplayer); + // Paper start - bundlize packets + entityplayer.server.getPlayerList().sendActiveEffects(entityplayer, packets::add); + entityplayer.connection.send(new net.minecraft.network.protocol.game.ClientboundBundlePacket(packets)); + // Paper end - bundlize packets } // CraftBukkit end - } + diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 9ca1fee03bfa557f1df7388c6043c9ec6d02a79a..cd789c235acf740ec29c30b180e7fbe1a140caa9 100644 +index c1d3dd2bd217efd6914bceb1027fa12b06c22a55..ca95a36b0149d4b8a67c3b42316c5d9d0415f5dd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1012,7 +1012,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1013,7 +1013,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return; } diff --git a/patches/unapplied/server/1014-Registry-Modification-API.patch b/patches/server/0994-Registry-Modification-API.patch similarity index 94% rename from patches/unapplied/server/1014-Registry-Modification-API.patch rename to patches/server/0994-Registry-Modification-API.patch index dba4fa583034..ac28f625c728 100644 --- a/patches/unapplied/server/1014-Registry-Modification-API.patch +++ b/patches/server/0994-Registry-Modification-API.patch @@ -1117,12 +1117,12 @@ index 0000000000000000000000000000000000000000..f09ce9c8547ef05153847245746473dd + } +} diff --git a/src/main/java/net/minecraft/core/MappedRegistry.java b/src/main/java/net/minecraft/core/MappedRegistry.java -index edbbafd1705345282e5e6251eb71bfde5793b7d4..f22d22ebcedcc9c20225677844c86a1ad27c4211 100644 +index 71e04e5c1bc0722abf8ca2e0738bd60b6d7ae21c..063630c1ffcce099139c59d598fc5a210e21f640 100644 --- a/src/main/java/net/minecraft/core/MappedRegistry.java +++ b/src/main/java/net/minecraft/core/MappedRegistry.java -@@ -441,4 +441,12 @@ public class MappedRegistry implements WritableRegistry { - public HolderLookup.RegistryLookup asLookup() { - return this.lookup; +@@ -509,4 +509,12 @@ public class MappedRegistry implements WritableRegistry { + + Stream> getTags(); } + // Paper start + // used to clear intrusive holders from GameEvent, Item, Block, EntityType, and Fluid from unused instances of those types @@ -1134,12 +1134,12 @@ index edbbafd1705345282e5e6251eb71bfde5793b7d4..f22d22ebcedcc9c20225677844c86a1a + // Paper end } diff --git a/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java b/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java -index 44b7927081b476813505cab6b3a2da2ec2942c54..0497318e8f647453f38f3a16a8be6bd9aa19253f 100644 +index 4638ba98dbbdb0f880337347be85a6e0fbed2191..12ba8bc0a946c107b076e2c995aca6a3aeb3811f 100644 --- a/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java +++ b/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java -@@ -288,6 +288,17 @@ public class BuiltInRegistries { - Registries.ENCHANTMENT_PROVIDER_TYPE, EnchantmentProviderTypes::bootstrap - ); +@@ -296,6 +296,17 @@ public class BuiltInRegistries { + public static final Registry> SLOT_DISPLAY = registerSimple(Registries.SLOT_DISPLAY, SlotDisplays::bootstrap); + public static final Registry RECIPE_BOOK_CATEGORY = registerSimple(Registries.RECIPE_BOOK_CATEGORY, RecipeBookCategories::bootstrap); public static final Registry> REGISTRY = WRITABLE_REGISTRY; + // Paper start - add built-in registry conversions + public static final io.papermc.paper.registry.data.util.Conversions BUILT_IN_CONVERSIONS = new io.papermc.paper.registry.data.util.Conversions(new net.minecraft.resources.RegistryOps.RegistryInfoLookup() { @@ -1155,7 +1155,7 @@ index 44b7927081b476813505cab6b3a2da2ec2942c54..0497318e8f647453f38f3a16a8be6bd9 private static Registry registerSimple(ResourceKey> key, BuiltInRegistries.RegistryBootstrap initializer) { return internalRegister(key, new MappedRegistry<>(key, Lifecycle.stable(), false), initializer); -@@ -328,6 +339,7 @@ public class BuiltInRegistries { +@@ -336,6 +347,7 @@ public class BuiltInRegistries { } public static void bootStrap(Runnable runnable) { // Paper end @@ -1163,40 +1163,40 @@ index 44b7927081b476813505cab6b3a2da2ec2942c54..0497318e8f647453f38f3a16a8be6bd9 createContents(); runnable.run(); // Paper freeze(); -@@ -346,6 +358,7 @@ public class BuiltInRegistries { - REGISTRY.freeze(); +@@ -355,6 +367,7 @@ public class BuiltInRegistries { for (Registry registry : REGISTRY) { + bindBootstrappedTagsToEmpty(registry); + io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(registry.key(), BUILT_IN_CONVERSIONS); // Paper registry.freeze(); } } diff --git a/src/main/java/net/minecraft/resources/RegistryDataLoader.java b/src/main/java/net/minecraft/resources/RegistryDataLoader.java -index abadf4abe08dc3bb6612b42cbb3f7df3ffa28ce9..3053243866c655829fe2e980446b4abf1da6d37c 100644 +index 144a6f5b0c53110804d6d099fe857d25f107d938..f2236665eaf3e6d0f9d44605db3cd5afe0cced4e 100644 --- a/src/main/java/net/minecraft/resources/RegistryDataLoader.java +++ b/src/main/java/net/minecraft/resources/RegistryDataLoader.java -@@ -115,7 +115,7 @@ public class RegistryDataLoader { - ); - - public static RegistryAccess.Frozen load(ResourceManager resourceManager, RegistryAccess registryManager, List> entries) { -- return load((loader, infoGetter) -> loader.loadFromResources(resourceManager, infoGetter), registryManager, entries); -+ return load((loader, infoGetter, conversions) -> loader.loadFromResources(resourceManager, infoGetter, conversions), registryManager, entries); // Paper - pass conversions +@@ -130,7 +130,7 @@ public class RegistryDataLoader { + public static RegistryAccess.Frozen load( + ResourceManager resourceManager, List> registries, List> entries + ) { +- return load((loader, infoGetter) -> loader.loadFromResources(resourceManager, infoGetter), registries, entries); ++ return load((loader, infoGetter, conversions) -> loader.loadFromResources(resourceManager, infoGetter, conversions), registries, entries); // Paper - pass conversions } public static RegistryAccess.Frozen load( -@@ -124,7 +124,7 @@ public class RegistryDataLoader { - RegistryAccess registryManager, +@@ -139,7 +139,7 @@ public class RegistryDataLoader { + List> registries, List> entries ) { -- return load((loader, infoGetter) -> loader.loadFromNetwork(data, factory, infoGetter), registryManager, entries); -+ return load((loader, infoGetter, conversions) -> loader.loadFromNetwork(data, factory, infoGetter, conversions), registryManager, entries); // Paper - pass conversions +- return load((loader, infoGetter) -> loader.loadFromNetwork(data, factory, infoGetter), registries, entries); ++ return load((loader, infoGetter, conversions) -> loader.loadFromNetwork(data, factory, infoGetter, conversions), registries, entries); // Paper - pass conversions } private static RegistryAccess.Frozen load( -@@ -133,9 +133,11 @@ public class RegistryDataLoader { +@@ -148,9 +148,11 @@ public class RegistryDataLoader { Map, Exception> map = new HashMap<>(); List> list = entries.stream().map(entry -> entry.create(Lifecycle.stable(), map)).collect(Collectors.toUnmodifiableList()); - RegistryOps.RegistryInfoLookup registryInfoLookup = createContext(baseRegistryManager, list); + RegistryOps.RegistryInfoLookup registryInfoLookup = createContext(registries, list); - list.forEach(loader -> loadable.apply((RegistryDataLoader.Loader)loader, registryInfoLookup)); + final io.papermc.paper.registry.data.util.Conversions conversions = new io.papermc.paper.registry.data.util.Conversions(registryInfoLookup); // Paper - create conversions + list.forEach(loader -> loadable.apply((RegistryDataLoader.Loader)loader, registryInfoLookup, conversions)); @@ -1206,7 +1206,7 @@ index abadf4abe08dc3bb6612b42cbb3f7df3ffa28ce9..3053243866c655829fe2e980446b4abf try { registry.freeze(); -@@ -193,13 +195,13 @@ public class RegistryDataLoader { +@@ -238,13 +240,13 @@ public class RegistryDataLoader { } private static void loadElementFromResource( @@ -1222,7 +1222,7 @@ index abadf4abe08dc3bb6612b42cbb3f7df3ffa28ce9..3053243866c655829fe2e980446b4abf } } -@@ -208,7 +210,8 @@ public class RegistryDataLoader { +@@ -253,7 +255,8 @@ public class RegistryDataLoader { RegistryOps.RegistryInfoLookup infoGetter, WritableRegistry registry, Decoder elementDecoder, @@ -1232,7 +1232,7 @@ index abadf4abe08dc3bb6612b42cbb3f7df3ffa28ce9..3053243866c655829fe2e980446b4abf ) { String string = Registries.elementsDirPath(registry.key()); FileToIdConverter fileToIdConverter = FileToIdConverter.json(string); -@@ -221,7 +224,7 @@ public class RegistryDataLoader { +@@ -266,7 +269,7 @@ public class RegistryDataLoader { RegistrationInfo registrationInfo = REGISTRATION_INFO_CACHE.apply(resource.knownPackInfo()); try { @@ -1241,7 +1241,7 @@ index abadf4abe08dc3bb6612b42cbb3f7df3ffa28ce9..3053243866c655829fe2e980446b4abf } catch (Exception var15) { errors.put( resourceKey, -@@ -237,7 +240,8 @@ public class RegistryDataLoader { +@@ -284,7 +287,8 @@ public class RegistryDataLoader { RegistryOps.RegistryInfoLookup infoGetter, WritableRegistry registry, Decoder decoder, @@ -1249,9 +1249,9 @@ index abadf4abe08dc3bb6612b42cbb3f7df3ffa28ce9..3053243866c655829fe2e980446b4abf + Map, Exception> loadingErrors, + io.papermc.paper.registry.data.util.Conversions conversions // Paper - pass conversions ) { - List list = data.get(registry.key()); - if (list != null) { -@@ -264,7 +268,7 @@ public class RegistryDataLoader { + RegistryDataLoader.NetworkedRegistryData networkedRegistryData = data.get(registry.key()); + if (networkedRegistryData != null) { +@@ -311,7 +315,7 @@ public class RegistryDataLoader { try { Resource resource = factory.getResourceOrThrow(resourceLocation); @@ -1260,7 +1260,7 @@ index abadf4abe08dc3bb6612b42cbb3f7df3ffa28ce9..3053243866c655829fe2e980446b4abf } catch (Exception var18) { loadingErrors.put(resourceKey, new IllegalStateException("Failed to parse local data", var18)); } -@@ -274,22 +278,23 @@ public class RegistryDataLoader { +@@ -323,22 +327,23 @@ public class RegistryDataLoader { } static record Loader(RegistryDataLoader.RegistryData data, WritableRegistry registry, Map, Exception> loadingErrors) { @@ -1271,7 +1271,7 @@ index abadf4abe08dc3bb6612b42cbb3f7df3ffa28ce9..3053243866c655829fe2e980446b4abf } public void loadFromNetwork( - Map>, List> data, + Map>, RegistryDataLoader.NetworkedRegistryData> data, ResourceProvider factory, - RegistryOps.RegistryInfoLookup infoGetter + RegistryOps.RegistryInfoLookup infoGetter, @@ -1288,41 +1288,42 @@ index abadf4abe08dc3bb6612b42cbb3f7df3ffa28ce9..3053243866c655829fe2e980446b4abf + void apply(RegistryDataLoader.Loader loader, RegistryOps.RegistryInfoLookup infoGetter, io.papermc.paper.registry.data.util.Conversions conversions); // Paper - pass conversions } - public static record RegistryData(ResourceKey> key, Codec elementCodec, boolean requiredNonEmpty) { + public static record NetworkedRegistryData(List elements, TagNetworkSerialization.NetworkPayload tags) { diff --git a/src/main/java/net/minecraft/server/ReloadableServerRegistries.java b/src/main/java/net/minecraft/server/ReloadableServerRegistries.java -index 397bdacab9517354875ebc0bc68d35059b3c318b..908431652a0fea79b5a0cee1efd0c7a7d524b614 100644 +index 6fddef967b6314ca0158f5bd4b8898670ea5e9ec..b5ca1a0acb16d0cd8dccc854f309d425a48b070d 100644 --- a/src/main/java/net/minecraft/server/ReloadableServerRegistries.java +++ b/src/main/java/net/minecraft/server/ReloadableServerRegistries.java -@@ -47,15 +47,16 @@ public class ReloadableServerRegistries { - ) { - RegistryAccess.Frozen frozen = dynamicRegistries.getAccessForLoading(RegistryLayer.RELOADABLE); - RegistryOps registryOps = new ReloadableServerRegistries.EmptyTagLookupWrapper(frozen).createSerializationContext(JsonOps.INSTANCE); +@@ -50,8 +50,9 @@ public class ReloadableServerRegistries { + ); + HolderLookup.Provider provider = HolderLookup.Provider.create(list.stream()); + RegistryOps registryOps = provider.createSerializationContext(JsonOps.INSTANCE); + final io.papermc.paper.registry.data.util.Conversions conversions = new io.papermc.paper.registry.data.util.Conversions(registryOps.lookupProvider); // Paper - List>> list = LootDataType.values() -- .map(type -> scheduleElementParse((LootDataType)type, registryOps, resourceManager, prepareExecutor)) -+ .map(type -> scheduleElementParse((LootDataType)type, registryOps, resourceManager, prepareExecutor, conversions)) // Paper + List>> list2 = LootDataType.values() +- .map(type -> scheduleRegistryLoad((LootDataType)type, registryOps, resourceManager, prepareExecutor)) ++ .map(type -> scheduleRegistryLoad((LootDataType)type, registryOps, resourceManager, prepareExecutor, conversions)) // Paper .toList(); - CompletableFuture>> completableFuture = Util.sequence(list); - return completableFuture.thenApplyAsync(registries -> apply(dynamicRegistries, (List>)registries), prepareExecutor); + CompletableFuture>> completableFuture = Util.sequence(list2); + return completableFuture.thenApplyAsync( +@@ -60,7 +61,7 @@ public class ReloadableServerRegistries { } - private static CompletableFuture> scheduleElementParse( + private static CompletableFuture> scheduleRegistryLoad( - LootDataType type, RegistryOps ops, ResourceManager resourceManager, Executor prepareExecutor + LootDataType type, RegistryOps ops, ResourceManager resourceManager, Executor prepareExecutor, io.papermc.paper.registry.data.util.Conversions conversions // Paper ) { - return CompletableFuture.supplyAsync( - () -> { -@@ -66,7 +67,7 @@ public class ReloadableServerRegistries { - SimpleJsonResourceReloadListener.scanDirectory(resourceManager, string, GSON, map); - map.forEach( - (id, json) -> type.deserialize(id, ops, json) -- .ifPresent(value -> writableRegistry.register(ResourceKey.create(type.registryKey(), id), (T)value, DEFAULT_REGISTRATION_INFO)) -+ .ifPresent(value -> io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.registerWithListeners(writableRegistry, ResourceKey.create(type.registryKey(), id), value, DEFAULT_REGISTRATION_INFO, conversions)) // Paper - register with listeners - ); - return writableRegistry; - }, + return CompletableFuture.supplyAsync(() -> { + WritableRegistry writableRegistry = new MappedRegistry<>(type.registryKey(), Lifecycle.experimental()); +@@ -68,7 +69,7 @@ public class ReloadableServerRegistries { + Map map = new HashMap<>(); + String string = Registries.elementsDirPath(type.registryKey()); + SimpleJsonResourceReloadListener.scanDirectory(resourceManager, string, ops, type.codec(), map); +- map.forEach((id, value) -> writableRegistry.register(ResourceKey.create(type.registryKey(), id), (T)value, DEFAULT_REGISTRATION_INFO)); ++ map.forEach((id, value) -> io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.registerWithListeners(writableRegistry, ResourceKey.create(type.registryKey(), id), value, DEFAULT_REGISTRATION_INFO, conversions)); // Paper - register with listeners + TagLoader.loadTagsForRegistry(resourceManager, writableRegistry); + return writableRegistry; + }, prepareExecutor); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java -index 4dff173bbed34a49c22532bbee2b35ebf5920d22..53c70846666b746af6706ed2e363fe388e463e56 100644 +index f8450a2abd1e96fac7827d252cc00038b9dee839..a812a42ea81b1543287e78ea55da6cbf4e0d27f8 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java @@ -167,11 +167,11 @@ public class CraftRegistry implements Registry { @@ -1358,7 +1359,7 @@ index 4dff173bbed34a49c22532bbee2b35ebf5920d22..53c70846666b746af6706ed2e363fe38 + // Paper end - RegistrySet API } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 9f2ddd47dc0658db2f95ef80543fb9a4d2f94f9f..68a6cd43042e87501f5bd48565222638dd58a1cf 100644 +index b24ccbff89db873f5bdf62cbebcca0049b94a8d5..49b898ed5e9de2507a6a6aac61dea4fe902649ca 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -674,6 +674,21 @@ public final class CraftMagicNumbers implements UnsafeValues { @@ -1433,7 +1434,7 @@ index 0000000000000000000000000000000000000000..47b8ebac8496179008b8932c5ca2aadc + } +} diff --git a/src/test/java/org/bukkit/registry/RegistryClassTest.java b/src/test/java/org/bukkit/registry/RegistryClassTest.java -index 575a06125e0b60b5bb8b6f85131f7d6cf86f5083..85f93d8c9b3a48b267e0575ba7fbb3b9f273e70c 100644 +index ea3d37f387bdb0dd5ae3fba9231ace31d0cebd64..c118c911972fe5a9f0c3e306009306f04ae2e821 100644 --- a/src/test/java/org/bukkit/registry/RegistryClassTest.java +++ b/src/test/java/org/bukkit/registry/RegistryClassTest.java @@ -111,7 +111,7 @@ public class RegistryClassTest { diff --git a/patches/unapplied/server/1015-Add-registry-entry-and-builders.patch b/patches/server/0995-Add-registry-entry-and-builders.patch similarity index 100% rename from patches/unapplied/server/1015-Add-registry-entry-and-builders.patch rename to patches/server/0995-Add-registry-entry-and-builders.patch diff --git a/patches/unapplied/server/1017-Proxy-ItemStack-to-CraftItemStack.patch b/patches/server/0996-Proxy-ItemStack-to-CraftItemStack.patch similarity index 95% rename from patches/unapplied/server/1017-Proxy-ItemStack-to-CraftItemStack.patch rename to patches/server/0996-Proxy-ItemStack-to-CraftItemStack.patch index 781b18ae7a7f..684b037d30fd 100644 --- a/patches/unapplied/server/1017-Proxy-ItemStack-to-CraftItemStack.patch +++ b/patches/server/0996-Proxy-ItemStack-to-CraftItemStack.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Proxy ItemStack to CraftItemStack diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index efb7fb8dbaa7446e394f55b021692c11a25fd29f..a3c6d2cbdce60b1cf935d798568b8bb5d97e1229 100644 +index bb2b4528692aed8e3341428697a60c0abee13779..49d2deac8d42a505b75f2196ef895a5564b62cac 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -@@ -26,15 +26,57 @@ import org.jetbrains.annotations.ApiStatus; +@@ -31,15 +31,57 @@ import org.jetbrains.annotations.ApiStatus; @DelegateDeserialization(ItemStack.class) public final class CraftItemStack extends ItemStack { @@ -71,7 +71,7 @@ index efb7fb8dbaa7446e394f55b021692c11a25fd29f..a3c6d2cbdce60b1cf935d798568b8bb5 public static net.minecraft.world.item.ItemStack getOrCloneOnMutation(ItemStack old, ItemStack newInstance) { return old == newInstance ? unwrap(old) : asNMSCopy(newInstance); } -@@ -48,25 +90,13 @@ public final class CraftItemStack extends ItemStack { +@@ -53,25 +95,13 @@ public final class CraftItemStack extends ItemStack { // Paper end - override isEmpty to use vanilla's impl public static net.minecraft.world.item.ItemStack asNMSCopy(ItemStack original) { @@ -102,7 +102,7 @@ index efb7fb8dbaa7446e394f55b021692c11a25fd29f..a3c6d2cbdce60b1cf935d798568b8bb5 } // Paper start -@@ -89,14 +119,10 @@ public final class CraftItemStack extends ItemStack { +@@ -94,14 +124,10 @@ public final class CraftItemStack extends ItemStack { * Copies the NMS stack to return as a strictly-Bukkit stack */ public static ItemStack asBukkitCopy(net.minecraft.world.item.ItemStack original) { @@ -121,7 +121,7 @@ index efb7fb8dbaa7446e394f55b021692c11a25fd29f..a3c6d2cbdce60b1cf935d798568b8bb5 } public static CraftItemStack asCraftMirror(net.minecraft.world.item.ItemStack original) { -@@ -317,11 +343,7 @@ public final class CraftItemStack extends ItemStack { +@@ -329,11 +355,7 @@ public final class CraftItemStack extends ItemStack { @Override public CraftItemStack clone() { @@ -134,7 +134,7 @@ index efb7fb8dbaa7446e394f55b021692c11a25fd29f..a3c6d2cbdce60b1cf935d798568b8bb5 } @Override -@@ -424,22 +446,14 @@ public final class CraftItemStack extends ItemStack { +@@ -436,22 +458,14 @@ public final class CraftItemStack extends ItemStack { if (stack == this) { return true; } @@ -160,7 +160,7 @@ index efb7fb8dbaa7446e394f55b021692c11a25fd29f..a3c6d2cbdce60b1cf935d798568b8bb5 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java -index d03f4a767f6c7fe7d6bcef20e6676c39d9657584..bae3dd5fc67e6b3d98a5e63ffbf639c5042f8843 100644 +index f4a6ee6dfcb2d516a9a1a9c81494b50a629110e4..96dfcfa12c63c682edcdec98647ca6a94d9fb4ed 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java @@ -100,13 +100,14 @@ public class CraftItemType implements ItemType.Typed, Han @@ -205,7 +205,7 @@ index 6cc9d7a9e6d4bfdc27e52fc581b2bb832616f121..6930d0afb230a88aa813b02e4d55c95d + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 68a6cd43042e87501f5bd48565222638dd58a1cf..6adc18c40d5d62e2ebc8deec197cec630a366937 100644 +index 49b898ed5e9de2507a6a6aac61dea4fe902649ca..02745957a08a27af6a032453b8b20a8fed2911b3 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -689,6 +689,13 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/unapplied/server/1018-Make-a-PDC-view-accessible-directly-from-ItemStack.patch b/patches/server/0997-Make-a-PDC-view-accessible-directly-from-ItemStack.patch similarity index 98% rename from patches/unapplied/server/1018-Make-a-PDC-view-accessible-directly-from-ItemStack.patch rename to patches/server/0997-Make-a-PDC-view-accessible-directly-from-ItemStack.patch index f86fe8c7dd53..f0bd1ac5ebe9 100644 --- a/patches/unapplied/server/1018-Make-a-PDC-view-accessible-directly-from-ItemStack.patch +++ b/patches/server/0997-Make-a-PDC-view-accessible-directly-from-ItemStack.patch @@ -131,10 +131,10 @@ index 0000000000000000000000000000000000000000..122c32e82b299cafd7d0c6a9f4818523 + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index a3c6d2cbdce60b1cf935d798568b8bb5d97e1229..6081c588c61406d0d21a15e8e6140d5d5240f0a8 100644 +index 49d2deac8d42a505b75f2196ef895a5564b62cac..756c73a401437566258813946fa10c7caa8f2469 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -@@ -484,4 +484,34 @@ public final class CraftItemStack extends ItemStack { +@@ -496,4 +496,34 @@ public final class CraftItemStack extends ItemStack { return mirrored; } // Paper end diff --git a/patches/unapplied/server/1019-Prioritize-Minecraft-commands-in-function-parsing-an.patch b/patches/server/0998-Prioritize-Minecraft-commands-in-function-parsing-an.patch similarity index 98% rename from patches/unapplied/server/1019-Prioritize-Minecraft-commands-in-function-parsing-an.patch rename to patches/server/0998-Prioritize-Minecraft-commands-in-function-parsing-an.patch index 6e36d9a7b3c7..c22d5f09bed2 100644 --- a/patches/unapplied/server/1019-Prioritize-Minecraft-commands-in-function-parsing-an.patch +++ b/patches/server/0998-Prioritize-Minecraft-commands-in-function-parsing-an.patch @@ -118,10 +118,10 @@ index 85a890403645f0f9d381e85b48efcae126673945..bcc27fec043a57eb5064934c967982de @Override diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index 3e454515360c22a26c9329e4032d525579110d7e..1d1e76de60e40224f5cb81893f9ee50fe987badb 100644 +index 1e7b99a82184f73aa31cb2e0d4e52a806240926f..260350422fc724ba5cd5769cbb387b6007f36a84 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -310,10 +310,7 @@ public class Commands { +@@ -315,10 +315,7 @@ public class Commands { // Paper - Fix permission levels for command blocks diff --git a/patches/unapplied/server/1020-optimize-dirt-and-snow-spreading.patch b/patches/server/0999-optimize-dirt-and-snow-spreading.patch similarity index 98% rename from patches/unapplied/server/1020-optimize-dirt-and-snow-spreading.patch rename to patches/server/0999-optimize-dirt-and-snow-spreading.patch index 49de7fcab946..e89393b028bb 100644 --- a/patches/unapplied/server/1020-optimize-dirt-and-snow-spreading.patch +++ b/patches/server/0999-optimize-dirt-and-snow-spreading.patch @@ -5,7 +5,7 @@ Subject: [PATCH] optimize dirt and snow spreading diff --git a/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java b/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java -index 5a39e8d359dc13383711e49ffb2d1294dad26192..b7165ec19bef1a07f6618fc0429d86cda1b08da4 100644 +index b4b826c53548bcf6952f6d0ee8037975ceb8c6e1..a94c164fbf8fc3bb7669799a53f7e5528d921e7c 100644 --- a/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java @@ -18,8 +18,13 @@ public abstract class SpreadingSnowyDirtBlock extends SnowyDirtBlock { diff --git a/patches/unapplied/server/1021-Fix-NPE-for-Jukebox-setRecord.patch b/patches/server/1000-Fix-NPE-for-Jukebox-setRecord.patch similarity index 87% rename from patches/unapplied/server/1021-Fix-NPE-for-Jukebox-setRecord.patch rename to patches/server/1000-Fix-NPE-for-Jukebox-setRecord.patch index e15a77ee7525..c673e4f8c761 100644 --- a/patches/unapplied/server/1021-Fix-NPE-for-Jukebox-setRecord.patch +++ b/patches/server/1000-Fix-NPE-for-Jukebox-setRecord.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Fix NPE for Jukebox#setRecord Fallback to the global registry if no level exists diff --git a/src/main/java/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java -index 1497e76b548ad76b5aaa297bdd35723e6a8f1f8d..c5069730b25e6f0dfb4e5db3271c91116b485f58 100644 +index 69fb6f5cfc8654995d7c78e8f7e9470b601e8ec7..c3bbe5e9e0cc37f3f22fc1d839fa2652966f1266 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java -@@ -200,7 +200,7 @@ public class JukeboxBlockEntity extends BlockEntity implements Clearable, Contai +@@ -199,7 +199,7 @@ public class JukeboxBlockEntity extends BlockEntity implements ContainerSingleIt public void setSongItemWithoutPlaying(ItemStack itemstack, long ticksSinceSongStarted) { // CraftBukkit - add argument this.item = itemstack; this.jukeboxSongPlayer.song = null; // CraftBukkit - reset From 6a315742d99e51884889364cd119281dd82600c5 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Fri, 25 Oct 2024 00:08:35 +0200 Subject: [PATCH 047/119] 1020 --- .../1001-fix-horse-inventories.patch} | 0 ...ityDamageEvents-before-actuallyHurt.patch} | 14 +- .../1003-Add-ItemType-getItemRarity.patch} | 4 +- .../1004-Add-plugin-info-at-startup.patch} | 0 ...tion-leniency-distance-configurable.patch} | 8 +- ...1006-Fix-PickupStatus-getting-reset.patch} | 14 +- ...ype-in-SculkSensorBlock-canActivate.patch} | 4 +- ...anPlaceOn-and-CanDestroy-NBT-values.patch} | 4 +- ...on-for-horizontal-only-item-merging.patch} | 4 +- ...010-Add-skipping-world-symlink-scan.patch} | 4 +- .../1011-Add-even-more-Enchantment-API.patch} | 0 .../1012-Leashable-API.patch} | 18 +- .../1013-Fix-CraftBukkit-drag-system.patch} | 8 +- ...ent-firing-for-block-entity-loading.patch} | 6 +- ...-lootable-item-function-from-compas.patch} | 0 ...016-Add-enchantment-seed-update-API.patch} | 6 +- ...ending-chat-to-client-with-updating.patch} | 4 +- ...Fix-InventoryOpenEvent-cancellation.patch} | 328 +++++++++--------- ...ire-BlockExpEvent-on-grindstone-use.patch} | 2 +- .../1020-Check-dead-flag-in-isAlive.patch} | 6 +- ...oy-placed-blocks-on-the-end-platform.patch | 26 -- 21 files changed, 209 insertions(+), 251 deletions(-) rename patches/{unapplied/server/1023-fix-horse-inventories.patch => server/1001-fix-horse-inventories.patch} (100%) rename patches/{unapplied/server/1024-Only-call-EntityDamageEvents-before-actuallyHurt.patch => server/1002-Only-call-EntityDamageEvents-before-actuallyHurt.patch} (85%) rename patches/{unapplied/server/1029-Add-ItemType-getItemRarity.patch => server/1003-Add-ItemType-getItemRarity.patch} (86%) rename patches/{unapplied/server/1033-Add-plugin-info-at-startup.patch => server/1004-Add-plugin-info-at-startup.patch} (100%) rename patches/{unapplied/server/1034-Make-interaction-leniency-distance-configurable.patch => server/1005-Make-interaction-leniency-distance-configurable.patch} (87%) rename patches/{unapplied/server/1035-Fix-PickupStatus-getting-reset.patch => server/1006-Fix-PickupStatus-getting-reset.patch} (84%) rename patches/{unapplied/server/1036-Check-for-block-type-in-SculkSensorBlock-canActivate.patch => server/1007-Check-for-block-type-in-SculkSensorBlock-canActivate.patch} (85%) rename patches/{unapplied/server/1037-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch => server/1008-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch} (97%) rename patches/{unapplied/server/1038-Configuration-for-horizontal-only-item-merging.patch => server/1009-Configuration-for-horizontal-only-item-merging.patch} (92%) rename patches/{unapplied/server/1040-Add-skipping-world-symlink-scan.patch => server/1010-Add-skipping-world-symlink-scan.patch} (90%) rename patches/{unapplied/server/1041-Add-even-more-Enchantment-API.patch => server/1011-Add-even-more-Enchantment-API.patch} (100%) rename patches/{unapplied/server/1042-Leashable-API.patch => server/1012-Leashable-API.patch} (87%) rename patches/{unapplied/server/1043-Fix-CraftBukkit-drag-system.patch => server/1013-Fix-CraftBukkit-drag-system.patch} (92%) rename patches/{unapplied/server/1044-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch => server/1014-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch} (91%) rename patches/{unapplied/server/1045-Remove-set-damage-lootable-item-function-from-compas.patch => server/1015-Remove-set-damage-lootable-item-function-from-compas.patch} (100%) rename patches/{unapplied/server/1047-Add-enchantment-seed-update-API.patch => server/1016-Add-enchantment-seed-update-API.patch} (85%) rename patches/{unapplied/server/1048-Fix-synchronise-sending-chat-to-client-with-updating.patch => server/1017-Fix-synchronise-sending-chat-to-client-with-updating.patch} (92%) rename patches/{unapplied/server/1049-Fix-InventoryOpenEvent-cancellation.patch => server/1018-Fix-InventoryOpenEvent-cancellation.patch} (55%) rename patches/{unapplied/server/1050-Fire-BlockExpEvent-on-grindstone-use.patch => server/1019-Fire-BlockExpEvent-on-grindstone-use.patch} (94%) rename patches/{unapplied/server/1051-Check-dead-flag-in-isAlive.patch => server/1020-Check-dead-flag-in-isAlive.patch} (80%) delete mode 100644 patches/unapplied/server/1046-Properly-destroy-placed-blocks-on-the-end-platform.patch diff --git a/patches/unapplied/server/1023-fix-horse-inventories.patch b/patches/server/1001-fix-horse-inventories.patch similarity index 100% rename from patches/unapplied/server/1023-fix-horse-inventories.patch rename to patches/server/1001-fix-horse-inventories.patch diff --git a/patches/unapplied/server/1024-Only-call-EntityDamageEvents-before-actuallyHurt.patch b/patches/server/1002-Only-call-EntityDamageEvents-before-actuallyHurt.patch similarity index 85% rename from patches/unapplied/server/1024-Only-call-EntityDamageEvents-before-actuallyHurt.patch rename to patches/server/1002-Only-call-EntityDamageEvents-before-actuallyHurt.patch index e1393a8173df..8c259f8cbf96 100644 --- a/patches/unapplied/server/1024-Only-call-EntityDamageEvents-before-actuallyHurt.patch +++ b/patches/server/1002-Only-call-EntityDamageEvents-before-actuallyHurt.patch @@ -12,10 +12,10 @@ This patch moves the invocation directly before the #actuallyHurt calls, respective invulnerable timings. diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 3b15995efc65a351da8dac009b9698494771fefb..5079775ce8f86fb061e616190513f56ff086e409 100644 +index f75b66c9ec786bc6f4d3f5cd5127c815f11166c4..b4d1848858fae20f81c27b31bc0c280c6705f082 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1459,12 +1459,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1491,12 +1491,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } // CraftBukkit start @@ -29,7 +29,7 @@ index 3b15995efc65a351da8dac009b9698494771fefb..5079775ce8f86fb061e616190513f56f // CraftBukkit end this.walkAnimation.setSpeed(1.5F); -@@ -1475,6 +1470,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1511,6 +1506,11 @@ public abstract class LivingEntity extends Entity implements Attackable { return false; } @@ -39,9 +39,9 @@ index 3b15995efc65a351da8dac009b9698494771fefb..5079775ce8f86fb061e616190513f56f + // Paper end - only call damage event when actuallyHurt will be called - move call logic down + // CraftBukkit start - if (!this.actuallyHurt(source, (float) event.getFinalDamage() - this.lastHurt, event)) { + if (!this.actuallyHurt(world, source, (float) event.getFinalDamage() - this.lastHurt, event)) { return false; -@@ -1484,6 +1484,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1520,6 +1520,10 @@ public abstract class LivingEntity extends Entity implements Attackable { this.lastHurt = amount; flag1 = false; } else { @@ -50,9 +50,9 @@ index 3b15995efc65a351da8dac009b9698494771fefb..5079775ce8f86fb061e616190513f56f + amount = computeAmountFromEntityDamageEvent(event); + // Paper end - only call damage event when actuallyHurt will be called - move call logic down // CraftBukkit start - if (!this.actuallyHurt(source, (float) event.getFinalDamage(), event)) { + if (!this.actuallyHurt(world, source, (float) event.getFinalDamage(), event)) { return false; -@@ -1615,6 +1619,18 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1655,6 +1659,18 @@ public abstract class LivingEntity extends Entity implements Attackable { } } diff --git a/patches/unapplied/server/1029-Add-ItemType-getItemRarity.patch b/patches/server/1003-Add-ItemType-getItemRarity.patch similarity index 86% rename from patches/unapplied/server/1029-Add-ItemType-getItemRarity.patch rename to patches/server/1003-Add-ItemType-getItemRarity.patch index 35ebf5036bb1..0863f02f5c67 100644 --- a/patches/unapplied/server/1029-Add-ItemType-getItemRarity.patch +++ b/patches/server/1003-Add-ItemType-getItemRarity.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add ItemType#getItemRarity diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java -index bae3dd5fc67e6b3d98a5e63ffbf639c5042f8843..450c63c31d2f5d056d989aa00452231f50c8224d 100644 +index 96dfcfa12c63c682edcdec98647ca6a94d9fb4ed..d3f650d040afae8cb962696381c692cd7884bb4d 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java -@@ -265,4 +265,12 @@ public class CraftItemType implements ItemType.Typed, Han +@@ -262,4 +262,12 @@ public class CraftItemType implements ItemType.Typed, Han return this.item.getDescriptionId(); } // Paper end - add Translatable diff --git a/patches/unapplied/server/1033-Add-plugin-info-at-startup.patch b/patches/server/1004-Add-plugin-info-at-startup.patch similarity index 100% rename from patches/unapplied/server/1033-Add-plugin-info-at-startup.patch rename to patches/server/1004-Add-plugin-info-at-startup.patch diff --git a/patches/unapplied/server/1034-Make-interaction-leniency-distance-configurable.patch b/patches/server/1005-Make-interaction-leniency-distance-configurable.patch similarity index 87% rename from patches/unapplied/server/1034-Make-interaction-leniency-distance-configurable.patch rename to patches/server/1005-Make-interaction-leniency-distance-configurable.patch index c0f7fc9fdc81..98eb372c1ecc 100644 --- a/patches/unapplied/server/1034-Make-interaction-leniency-distance-configurable.patch +++ b/patches/server/1005-Make-interaction-leniency-distance-configurable.patch @@ -12,15 +12,15 @@ This value however may be too low in high latency environments. The patch exposes a new configuration option to configure said value. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 4c04eb531b6989f7e618d201ecaa84298eab52c4..62d5ca25104e10ca16c2005ef9272bf8329ce145 100644 +index 14a8e05420ae4ca2f1d9028e19379d162a3e6971..c9fd2b8cc5a14d4ef4072765d5274d0c470bcfe6 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2702,7 +2702,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2722,7 +2722,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl AABB axisalignedbb = entity.getBoundingBox(); -- if (this.player.canInteractWithEntity(axisalignedbb, 1.0D)) { -+ if (this.player.canInteractWithEntity(axisalignedbb, io.papermc.paper.configuration.GlobalConfiguration.get().misc.clientInteractionLeniencyDistance.or(1.0D))) { // Paper - configurable lenience value for interact range +- if (this.player.canInteractWithEntity(axisalignedbb, 3.0D)) { ++ if (this.player.canInteractWithEntity(axisalignedbb, io.papermc.paper.configuration.GlobalConfiguration.get().misc.clientInteractionLeniencyDistance.or(3.0D))) { // Paper - configurable lenience value for interact range packet.dispatch(new ServerboundInteractPacket.Handler() { private void performInteraction(InteractionHand enumhand, ServerGamePacketListenerImpl.EntityInteraction playerconnection_a, PlayerInteractEntityEvent event) { // CraftBukkit ItemStack itemstack = ServerGamePacketListenerImpl.this.player.getItemInHand(enumhand); diff --git a/patches/unapplied/server/1035-Fix-PickupStatus-getting-reset.patch b/patches/server/1006-Fix-PickupStatus-getting-reset.patch similarity index 84% rename from patches/unapplied/server/1035-Fix-PickupStatus-getting-reset.patch rename to patches/server/1006-Fix-PickupStatus-getting-reset.patch index a952f8a688ac..c731057978b0 100644 --- a/patches/unapplied/server/1035-Fix-PickupStatus-getting-reset.patch +++ b/patches/server/1006-Fix-PickupStatus-getting-reset.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix PickupStatus getting reset diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -index ddf47dab1ab92c45e3eea09239d418a9798ed59e..9ca29b3d4bf8bca5f51f3644e12fcbec2cb5d35e 100644 +index 14e31ae88e90d8ea1a98800cc6c1c3527bb2ed6b..accc246f441c8bf5e1a755cfc0db8f97c0c01c6b 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java +++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java -@@ -668,7 +668,14 @@ public abstract class AbstractArrow extends Projectile { +@@ -714,7 +714,14 @@ public abstract class AbstractArrow extends Projectile { @Override public void setOwner(@Nullable Entity entity) { @@ -24,13 +24,13 @@ index ddf47dab1ab92c45e3eea09239d418a9798ed59e..9ca29b3d4bf8bca5f51f3644e12fcbec byte b0 = 0; diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index f2bdd95a6ae77400742d87bcae35c09fb8b047ba..10ade433c083851d9ea4797c6ec618db122229f9 100644 +index 3982b32cf69250ebd138eff225b65313f75286ea..03c1bffd3125bb7a82ac921b0a23dcab55c33c4f 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -240,7 +240,13 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -353,7 +353,13 @@ public abstract class Projectile extends Entity implements TraceableEntity { public boolean deflect(ProjectileDeflection deflection, @Nullable Entity deflector, @Nullable Entity owner, boolean fromAttack) { + deflection.deflect(this, deflector, this.random); if (!this.level().isClientSide) { - deflection.deflect(this, deflector, this.random); - this.setOwner(owner); + // Paper start - Fix PickupStatus getting reset + if (this instanceof AbstractArrow arrow) { @@ -43,10 +43,10 @@ index f2bdd95a6ae77400742d87bcae35c09fb8b047ba..10ade433c083851d9ea4797c6ec618db } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java -index faa08ad912fa43e7a6c5a2359e23c04c059c5edf..501e2aa3a10dae94c4a8d9dfcdc902e434fcca62 100644 +index 1f30109abd86b76af343eb5eb75ec3db83ef9417..d0c30fd12aa9866900fe72b97d10c257479cf010 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java -@@ -170,4 +170,16 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr +@@ -173,4 +173,16 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr this.getHandle().setSoundEvent(org.bukkit.craftbukkit.CraftSound.bukkitToMinecraft(sound)); } // Paper end diff --git a/patches/unapplied/server/1036-Check-for-block-type-in-SculkSensorBlock-canActivate.patch b/patches/server/1007-Check-for-block-type-in-SculkSensorBlock-canActivate.patch similarity index 85% rename from patches/unapplied/server/1036-Check-for-block-type-in-SculkSensorBlock-canActivate.patch rename to patches/server/1007-Check-for-block-type-in-SculkSensorBlock-canActivate.patch index c56c52b16585..b06a0b6c33b4 100644 --- a/patches/unapplied/server/1036-Check-for-block-type-in-SculkSensorBlock-canActivate.patch +++ b/patches/server/1007-Check-for-block-type-in-SculkSensorBlock-canActivate.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Check for block type in SculkSensorBlock#canActivate diff --git a/src/main/java/net/minecraft/world/level/block/SculkSensorBlock.java b/src/main/java/net/minecraft/world/level/block/SculkSensorBlock.java -index b45bc43b5a59a95c50bd756a981368c7fdadbd41..8d57c68d2f20f7c0d5c1be5d5b12e6926aad8c58 100644 +index 22d299a19f19ad5dd13262792ae448311d1ea3e4..0ed449a188d98f87dbddd2d76009fed02a29ed25 100644 --- a/src/main/java/net/minecraft/world/level/block/SculkSensorBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SculkSensorBlock.java -@@ -218,7 +218,7 @@ public class SculkSensorBlock extends BaseEntityBlock implements SimpleWaterlogg +@@ -219,7 +219,7 @@ public class SculkSensorBlock extends BaseEntityBlock implements SimpleWaterlogg } public static boolean canActivate(BlockState state) { diff --git a/patches/unapplied/server/1037-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch b/patches/server/1008-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch similarity index 97% rename from patches/unapplied/server/1037-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch rename to patches/server/1008-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch index 025db7dddbbc..61b8983112e0 100644 --- a/patches/unapplied/server/1037-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch +++ b/patches/server/1008-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add API for CanPlaceOn and CanDestroy NBT values diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index 7f6f404f5a2be7876ae239355979e8c8a7a198ce..07f31bce96e3c47bea43b5d6443070ae158430ef 100644 +index 450c5aa14b4195eb7123492c7a111ec6f40ce412..7d9f75e680e243ac8c7defdd150e431b47225945 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -@@ -2185,4 +2185,117 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2498,4 +2498,117 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { } // Paper end diff --git a/patches/unapplied/server/1038-Configuration-for-horizontal-only-item-merging.patch b/patches/server/1009-Configuration-for-horizontal-only-item-merging.patch similarity index 92% rename from patches/unapplied/server/1038-Configuration-for-horizontal-only-item-merging.patch rename to patches/server/1009-Configuration-for-horizontal-only-item-merging.patch index 76e790b082ee..4b16b244dd13 100644 --- a/patches/unapplied/server/1038-Configuration-for-horizontal-only-item-merging.patch +++ b/patches/server/1009-Configuration-for-horizontal-only-item-merging.patch @@ -14,10 +14,10 @@ This allows us to have both the reduced number of item entities a high item-merg without most of the visual artifacts caused by items merging vertically. diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index cbfb07bdf8d5e2e5a462835184be2d47e59d506c..03cfa29bdb426a9fb6b1b6be6e897da48d4f2f3e 100644 +index e83a705f54063a17fc69a22683333aacad5a43ce..246b5649883e4f305afa5a887b9df0f3735f7593 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -282,7 +282,7 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -285,7 +285,7 @@ public class ItemEntity extends Entity implements TraceableEntity { if (this.isMergable()) { // Spigot start double radius = this.level().spigotConfig.itemMerge; diff --git a/patches/unapplied/server/1040-Add-skipping-world-symlink-scan.patch b/patches/server/1010-Add-skipping-world-symlink-scan.patch similarity index 90% rename from patches/unapplied/server/1040-Add-skipping-world-symlink-scan.patch rename to patches/server/1010-Add-skipping-world-symlink-scan.patch index edbbf7edf87f..f3221508c695 100644 --- a/patches/unapplied/server/1040-Add-skipping-world-symlink-scan.patch +++ b/patches/server/1010-Add-skipping-world-symlink-scan.patch @@ -7,10 +7,10 @@ In worlds that are extremely large (greater than 1TB), it can take an insanely l This patch adds a system property to disable the symlink scan, which can be used to speed up world loading. diff --git a/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java b/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java -index 427ee4d6f12a7abd8da0c65e0b9081b25824df40..85ba843ce7e1f62971e736fa2cc028c47b274ce4 100644 +index b5abdd1498a3d19559149c30ba959aa2bcf0246c..79397b3c76e4b9d2ee03dfa16c2daf4f71ae8b4d 100644 --- a/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java +++ b/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java -@@ -420,7 +420,7 @@ public class LevelStorageSource { +@@ -411,7 +411,7 @@ public class LevelStorageSource { public LevelStorageSource.LevelStorageAccess validateAndCreateAccess(String s, ResourceKey dimensionType) throws IOException, ContentValidationException { // CraftBukkit Path path = this.getLevelPath(s); diff --git a/patches/unapplied/server/1041-Add-even-more-Enchantment-API.patch b/patches/server/1011-Add-even-more-Enchantment-API.patch similarity index 100% rename from patches/unapplied/server/1041-Add-even-more-Enchantment-API.patch rename to patches/server/1011-Add-even-more-Enchantment-API.patch diff --git a/patches/unapplied/server/1042-Leashable-API.patch b/patches/server/1012-Leashable-API.patch similarity index 87% rename from patches/unapplied/server/1042-Leashable-API.patch rename to patches/server/1012-Leashable-API.patch index 0450da40fd91..20fc6fbdcad9 100644 --- a/patches/unapplied/server/1042-Leashable-API.patch +++ b/patches/server/1012-Leashable-API.patch @@ -61,23 +61,23 @@ index 0000000000000000000000000000000000000000..a9ddf9a4a07cd29833f38d7e5f42b2b1 + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java -index e33b1b6fd50a4eea57500cc00dba20d6edcab75d..01a9660de65688b7c1a4f9dafcb650774ce1853b 100644 +index 412fd9e87ec81cf50cb8bc82fe2dad5dd0029039..9046d6fa36b9f5e5d25835ad8d94c869c0764060 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java -@@ -7,7 +7,7 @@ import org.bukkit.craftbukkit.CraftServer; +@@ -8,7 +8,7 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Boat; import org.bukkit.entity.Entity; --public class CraftBoat extends CraftVehicle implements Boat { -+public class CraftBoat extends CraftVehicle implements Boat, io.papermc.paper.entity.PaperLeashable { // Paper - Leashable API +-public abstract class CraftBoat extends CraftVehicle implements Boat { ++public abstract class CraftBoat extends CraftVehicle implements Boat, io.papermc.paper.entity.PaperLeashable { // Paper - Leashable API - public CraftBoat(CraftServer server, net.minecraft.world.entity.vehicle.Boat entity) { + public CraftBoat(CraftServer server, AbstractBoat entity) { super(server, entity); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -index 7e280955067169f63f15162e9cad1e86e824a8e5..4750df7354ccb5afd0910efe0415f3a2eb19a546 100644 +index f16067b674118a47735ad22797988d50b4415040..d0c409f4efad289e3e325f44b500fc72589d89d4 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java -@@ -777,43 +777,17 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { +@@ -784,43 +784,17 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { @Override public boolean isLeashed() { @@ -125,7 +125,7 @@ index 7e280955067169f63f15162e9cad1e86e824a8e5..4750df7354ccb5afd0910efe0415f3a2 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java -index deb66c04abefb4a88521483db1612e494bd27164..5f9f7e325e3e0276f7a475c4a4725cc0e1b54afd 100644 +index 95d7015a61098d1d22a501124d6bb8fba1516fe3..778a9d3f8bfe5dba59e1e655e4eeb8822678b8cf 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java @@ -11,7 +11,7 @@ import org.bukkit.entity.LivingEntity; @@ -138,7 +138,7 @@ index deb66c04abefb4a88521483db1612e494bd27164..5f9f7e325e3e0276f7a475c4a4725cc0 super(server, entity); paperPathfinder = new com.destroystokyo.paper.entity.PaperPathfinder(entity); // Paper - Mob Pathfinding API @@ -175,4 +175,21 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob { - return getHandle().getExperienceReward((ServerLevel) this.getHandle().level(), null); + return getHandle().getExperienceReward((net.minecraft.server.level.ServerLevel) this.getHandle().level(), null); } // Paper end + diff --git a/patches/unapplied/server/1043-Fix-CraftBukkit-drag-system.patch b/patches/server/1013-Fix-CraftBukkit-drag-system.patch similarity index 92% rename from patches/unapplied/server/1043-Fix-CraftBukkit-drag-system.patch rename to patches/server/1013-Fix-CraftBukkit-drag-system.patch index fe2da46cc5a5..09f889a5eb3d 100644 --- a/patches/unapplied/server/1043-Fix-CraftBukkit-drag-system.patch +++ b/patches/server/1013-Fix-CraftBukkit-drag-system.patch @@ -10,10 +10,10 @@ public net.minecraft.world.inventory.AbstractContainerMenu quickcraftType public net.minecraft.world.inventory.AbstractContainerMenu resetQuickCraft()V diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index f93edc8a6ed7c51ec6e9335f66ab146d6aeb69a0..589214abe82c2acf6bbfda54b25f9385a6b575c4 100644 +index c9fd2b8cc5a14d4ef4072765d5274d0c470bcfe6..1ab3f730301e8ac22702601a04ad8f1521585daa 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3127,6 +3127,25 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3080,6 +3080,25 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } break; case QUICK_CRAFT: @@ -40,10 +40,10 @@ index f93edc8a6ed7c51ec6e9335f66ab146d6aeb69a0..589214abe82c2acf6bbfda54b25f9385 break; case PICKUP_ALL: diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -index 46159a127d910028c62ada90ff2d2dccc3b62fc3..dd4218e108f87f3305b76fbc8d88f488b447c609 100644 +index 78d0ff45c016e900d87010e8b26b0bb10e63f445..4680f77a275d8d2b226018db89a571ac25998dd8 100644 --- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -@@ -431,7 +431,7 @@ public abstract class AbstractContainerMenu { +@@ -468,7 +468,7 @@ public abstract class AbstractContainerMenu { } } else if (this.quickcraftStatus == 2) { if (!this.quickcraftSlots.isEmpty()) { diff --git a/patches/unapplied/server/1044-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch b/patches/server/1014-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch similarity index 91% rename from patches/unapplied/server/1044-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch rename to patches/server/1014-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch index 052376aaeb2b..c2857c22454d 100644 --- a/patches/unapplied/server/1044-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch +++ b/patches/server/1014-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix SculkBloomEvent firing for block entity loading diff --git a/src/main/java/net/minecraft/world/level/block/SculkSpreader.java b/src/main/java/net/minecraft/world/level/block/SculkSpreader.java -index dbdd9cb76f9e2d0962001d9a1e82896c907d7aea..427e9bcb1fa9436543d7ff974eb8642ccce4a6a3 100644 +index b9a1709b79c1f7a21c9d08f986d4ea3b546e4a67..24590d131587c4e1def920333140b1575f9d7471 100644 --- a/src/main/java/net/minecraft/world/level/block/SculkSpreader.java +++ b/src/main/java/net/minecraft/world/level/block/SculkSpreader.java -@@ -125,7 +125,7 @@ public class SculkSpreader { +@@ -126,7 +126,7 @@ public class SculkSpreader { int i = Math.min(list.size(), 32); for (int j = 0; j < i; ++j) { @@ -17,7 +17,7 @@ index dbdd9cb76f9e2d0962001d9a1e82896c907d7aea..427e9bcb1fa9436543d7ff974eb8642c } } -@@ -145,16 +145,16 @@ public class SculkSpreader { +@@ -146,16 +146,16 @@ public class SculkSpreader { while (charge > 0) { int j = Math.min(charge, 1000); diff --git a/patches/unapplied/server/1045-Remove-set-damage-lootable-item-function-from-compas.patch b/patches/server/1015-Remove-set-damage-lootable-item-function-from-compas.patch similarity index 100% rename from patches/unapplied/server/1045-Remove-set-damage-lootable-item-function-from-compas.patch rename to patches/server/1015-Remove-set-damage-lootable-item-function-from-compas.patch diff --git a/patches/unapplied/server/1047-Add-enchantment-seed-update-API.patch b/patches/server/1016-Add-enchantment-seed-update-API.patch similarity index 85% rename from patches/unapplied/server/1047-Add-enchantment-seed-update-API.patch rename to patches/server/1016-Add-enchantment-seed-update-API.patch index 16a2bfd3898d..37251029790f 100644 --- a/patches/unapplied/server/1047-Add-enchantment-seed-update-API.patch +++ b/patches/server/1016-Add-enchantment-seed-update-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add enchantment seed update API diff --git a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java -index 1ef014b29645ed09ccffb898f1819428c3dc6259..9bc9b4218ffd966f43097c9e009b2926af58c810 100644 +index b7300052f3c3d496ea41b681a2d5d5b554e67c63..50a735dd97daab4fb9579f922a4c63de60204f29 100644 --- a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java +++ b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java -@@ -411,4 +411,10 @@ public class EnchantmentMenu extends AbstractContainerMenu { +@@ -399,4 +399,10 @@ public class EnchantmentMenu extends AbstractContainerMenu { return this.bukkitEntity; } // CraftBukkit end @@ -20,7 +20,7 @@ index 1ef014b29645ed09ccffb898f1819428c3dc6259..9bc9b4218ffd966f43097c9e009b2926 + // Paper end - add enchantment seed update API } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftEnchantmentView.java b/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftEnchantmentView.java -index 4d28a2e9a4bfd9adee934c3033f32a8cf66286db..3b3d2d6d23d8f3b75ec52df17b86f6639c8c349b 100644 +index 17f0ce8fcb6d44579d88cfcf01de40485b0037dc..abe709ab9002b30a996e46779843969c984c9be9 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftEnchantmentView.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftEnchantmentView.java @@ -26,6 +26,13 @@ public class CraftEnchantmentView extends CraftInventoryView implements - } else { +@@ -252,8 +252,7 @@ public class ChestBlock extends AbstractChestBlock implements + if (world instanceof ServerLevel worldserver) { MenuProvider itileinventory = this.getMenuProvider(state, world, pos); - if (itileinventory != null) { - player.openMenu(itileinventory); + if (itileinventory != null && player.openMenu(itileinventory).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation player.awardStat(this.getOpenChestStat()); - PiglinAi.angerNearbyPiglins(player, true); + PiglinAi.angerNearbyPiglins(worldserver, player, true); } diff --git a/src/main/java/net/minecraft/world/level/block/CraftingTableBlock.java b/src/main/java/net/minecraft/world/level/block/CraftingTableBlock.java -index 2dedbda759bd5cdc96e1296583cec600bc487464..ace45e3f95940a5770531da0f702dbee51b1032e 100644 +index 673a92d383db463b5c4e2ac3a4ecbd7e97c15c6d..6a2123cd808fa79f3cdb1cb56632d29bfe99058d 100644 --- a/src/main/java/net/minecraft/world/level/block/CraftingTableBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CraftingTableBlock.java -@@ -32,11 +32,10 @@ public class CraftingTableBlock extends Block { +@@ -31,8 +31,9 @@ public class CraftingTableBlock extends Block { + @Override protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { - if (world.isClientSide) { - return InteractionResult.SUCCESS; -- } else { + if (!world.isClientSide) { - player.openMenu(state.getMenuProvider(world, pos)); -+ } else if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation ++ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation player.awardStat(Stats.INTERACT_WITH_CRAFTING_TABLE); -- return InteractionResult.CONSUME; ++ } // Paper - Fix InventoryOpenEvent cancellation } -+ return InteractionResult.CONSUME; // Paper - Fix InventoryOpenEvent cancellation - } - @Override + return InteractionResult.SUCCESS; diff --git a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java -index f6edfea463b3725d3a79aca38825e86dbf82175c..e1021d8be840f378568f28639c259182055c78ac 100644 +index a02f24448b002824b068278fa427003008c0d0f1..0427d590912561cb4f0354715e4ac513e53b3eb3 100644 --- a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java -@@ -78,8 +78,7 @@ public class DispenserBlock extends BaseEntityBlock { - } else { - BlockEntity tileentity = world.getBlockEntity(pos); +@@ -80,8 +80,9 @@ public class DispenserBlock extends BaseEntityBlock { + if (tileentity instanceof DispenserBlockEntity) { + DispenserBlockEntity tileentitydispenser = (DispenserBlockEntity) tileentity; + +- player.openMenu(tileentitydispenser); ++ if (player.openMenu(tileentitydispenser).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + player.awardStat(tileentitydispenser instanceof DropperBlockEntity ? Stats.INSPECT_DROPPER : Stats.INSPECT_DISPENSER); ++ } // Paper - Fix InventoryOpenEvent cancellation + } + } -- if (tileentity instanceof DispenserBlockEntity) { -- player.openMenu((DispenserBlockEntity) tileentity); -+ if (tileentity instanceof DispenserBlockEntity && player.openMenu((DispenserBlockEntity) tileentity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation - if (tileentity instanceof DropperBlockEntity) { - player.awardStat(Stats.INSPECT_DROPPER); - } else { diff --git a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java -index ca92d49ef2010ba00c623491671dcde8ebe697c1..491a59336899179c79820cd61541d49f7337c0f6 100644 +index ef0d469176ee74b6bb5f9e9cc508735145fda5b8..ebb9baca7a65173f7c9fdf9bf47a8db876719625 100644 --- a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java +++ b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java -@@ -90,11 +90,14 @@ public class EnderChestBlock extends AbstractChestBlock i +@@ -86,11 +86,13 @@ public class EnderChestBlock extends AbstractChestBlock i + if (world.getBlockState(blockPos).isRedstoneConductor(world, blockPos)) { // Paper - diff on change; make sure that EnderChest#isBlocked uses the same logic + return InteractionResult.SUCCESS; } else { - EnderChestBlockEntity enderChestBlockEntity = (EnderChestBlockEntity)blockEntity; - playerEnderChestContainer.setActiveChest(enderChestBlockEntity); -- player.openMenu( -+ // Paper start - Fix InventoryOpenEvent cancellation -+ if (player.openMenu( - new SimpleMenuProvider((i, inventory, playerx) -> ChestMenu.threeRows(i, inventory, playerEnderChestContainer), CONTAINER_TITLE) -- ); -- player.awardStat(Stats.OPEN_ENDERCHEST); -- PiglinAi.angerNearbyPiglins(player, true); +- if (world instanceof ServerLevel serverLevel) { ++ // Paper start - Fix InventoryOpenEvent cancellation - moved up; ++ if (world instanceof ServerLevel serverLevel && player.openMenu( ++ new SimpleMenuProvider((i, inventory, playerx) -> ChestMenu.threeRows(i, inventory, playerEnderChestContainer), CONTAINER_TITLE) + ).isPresent()) { -+ player.awardStat(Stats.OPEN_ENDERCHEST); -+ PiglinAi.angerNearbyPiglins(player, true); -+ } -+ // Paper end - Fix InventoryOpenEvent cancellation - return InteractionResult.CONSUME; - } - } else { ++ // Paper end - Fix InventoryOpenEvent cancellation - moved up; + playerEnderChestContainer.setActiveChest(enderChestBlockEntity); +- player.openMenu( +- new SimpleMenuProvider((i, inventory, playerx) -> ChestMenu.threeRows(i, inventory, playerEnderChestContainer), CONTAINER_TITLE) +- ); ++ // Paper - Fix InventoryOpenEvent cancellation - moved up; + player.awardStat(Stats.OPEN_ENDERCHEST); + PiglinAi.angerNearbyPiglins(serverLevel, player, true); + } diff --git a/src/main/java/net/minecraft/world/level/block/FurnaceBlock.java b/src/main/java/net/minecraft/world/level/block/FurnaceBlock.java index 72a3002c291181e7d874a149a22b8004ee2a0b18..618b566f067d53f32351e13b692095ebf6402925 100644 --- a/src/main/java/net/minecraft/world/level/block/FurnaceBlock.java @@ -240,42 +234,39 @@ index 72a3002c291181e7d874a149a22b8004ee2a0b18..618b566f067d53f32351e13b692095eb } } diff --git a/src/main/java/net/minecraft/world/level/block/GrindstoneBlock.java b/src/main/java/net/minecraft/world/level/block/GrindstoneBlock.java -index c62c54fce864f3c28cff955f3030ceb7c3d125d9..ca57d3663afd1ebcbd80682c178344feecda3808 100644 +index 15fb9e8f63d1db1125680aced7f9b477d4ebf43a..59c000612bbf7beb7208af48001d3b1e5111ebd4 100644 --- a/src/main/java/net/minecraft/world/level/block/GrindstoneBlock.java +++ b/src/main/java/net/minecraft/world/level/block/GrindstoneBlock.java -@@ -158,11 +158,10 @@ public class GrindstoneBlock extends FaceAttachedHorizontalDirectionalBlock { +@@ -157,8 +157,9 @@ public class GrindstoneBlock extends FaceAttachedHorizontalDirectionalBlock { + @Override protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { - if (world.isClientSide) { - return InteractionResult.SUCCESS; -- } else { + if (!world.isClientSide) { - player.openMenu(state.getMenuProvider(world, pos)); -+ } else if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation ++ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation player.awardStat(Stats.INTERACT_WITH_GRINDSTONE); -- return InteractionResult.CONSUME; ++ } // Paper - Fix InventoryOpenEvent cancellation } -+ return InteractionResult.CONSUME; // Paper - Fix InventoryOpenEvent cancellation - } - @Override + return InteractionResult.SUCCESS; diff --git a/src/main/java/net/minecraft/world/level/block/HopperBlock.java b/src/main/java/net/minecraft/world/level/block/HopperBlock.java -index 86e5617d445ce762aa374e236a0ccdfe5901fce5..3e1c7d62c24dd48a805260d156135dc4f0c3d1fc 100644 +index b61324fe162f32817b87e4adb80df57b9433259f..005a2a66a6e8a492acfa7ba91117884cda08562d 100644 --- a/src/main/java/net/minecraft/world/level/block/HopperBlock.java +++ b/src/main/java/net/minecraft/world/level/block/HopperBlock.java -@@ -128,8 +128,7 @@ public class HopperBlock extends BaseEntityBlock { - return InteractionResult.SUCCESS; - } else { - BlockEntity blockEntity = world.getBlockEntity(pos); -- if (blockEntity instanceof HopperBlockEntity) { -- player.openMenu((HopperBlockEntity)blockEntity); -+ if (blockEntity instanceof HopperBlockEntity && player.openMenu((HopperBlockEntity)blockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation - player.awardStat(Stats.INSPECT_HOPPER); - } +@@ -125,8 +125,7 @@ public class HopperBlock extends BaseEntityBlock { + + @Override + protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { +- if (!world.isClientSide && world.getBlockEntity(pos) instanceof HopperBlockEntity hopperBlockEntity) { +- player.openMenu(hopperBlockEntity); ++ if (!world.isClientSide && world.getBlockEntity(pos) instanceof HopperBlockEntity hopperBlockEntity && player.openMenu(hopperBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + player.awardStat(Stats.INSPECT_HOPPER); + } diff --git a/src/main/java/net/minecraft/world/level/block/LecternBlock.java b/src/main/java/net/minecraft/world/level/block/LecternBlock.java -index 0c52e1f8bc233bb66e53f4c69e1d8757382bbe81..ebb79907391fe3128d3d16fbe9d8cb0b22bcc9f7 100644 +index 3537795720be76483579fc50715914974c97c9c4..ec6ff0b192ae2f1586095519ad2472e76b2b5589 100644 --- a/src/main/java/net/minecraft/world/level/block/LecternBlock.java +++ b/src/main/java/net/minecraft/world/level/block/LecternBlock.java -@@ -295,8 +295,7 @@ public class LecternBlock extends BaseEntityBlock { +@@ -298,8 +298,7 @@ public class LecternBlock extends BaseEntityBlock { private void openScreen(Level world, BlockPos pos, Player player) { BlockEntity tileentity = world.getBlockEntity(pos); @@ -286,54 +277,50 @@ index 0c52e1f8bc233bb66e53f4c69e1d8757382bbe81..ebb79907391fe3128d3d16fbe9d8cb0b } diff --git a/src/main/java/net/minecraft/world/level/block/LoomBlock.java b/src/main/java/net/minecraft/world/level/block/LoomBlock.java -index 8dd9d92c4730ec9a1cea197817e28e60f70ae3a9..d2f5228e2b0848ca79a7fe6ea79095c230a5f243 100644 +index 2806ca5b0e3c73a3704a514dba2038072947d9ae..1b57f8cf3f4f27f6a76fec82a542ec1c582470c9 100644 --- a/src/main/java/net/minecraft/world/level/block/LoomBlock.java +++ b/src/main/java/net/minecraft/world/level/block/LoomBlock.java -@@ -34,11 +34,10 @@ public class LoomBlock extends HorizontalDirectionalBlock { +@@ -33,8 +33,9 @@ public class LoomBlock extends HorizontalDirectionalBlock { + @Override protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { - if (world.isClientSide) { - return InteractionResult.SUCCESS; -- } else { + if (!world.isClientSide) { - player.openMenu(state.getMenuProvider(world, pos)); -+ } else if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation ++ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation player.awardStat(Stats.INTERACT_WITH_LOOM); -- return InteractionResult.CONSUME; ++ } // Paper - Fix InventoryOpenEvent cancellation } -+ return InteractionResult.CONSUME; // Paper - Fix InventoryOpenEvent cancellation - } - @Override + return InteractionResult.SUCCESS; diff --git a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java -index 6323c96d9b0cd14f89609b38da37d7fcc12d211b..6b2c3afa04a3564e435633b521d918ed795f9f65 100644 +index a0607cb6c6f74285363dfbd49033a8bde5ca6ae3..155c7240b1112729333e6968122568c707d8f66b 100644 --- a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java -@@ -106,8 +106,7 @@ public class ShulkerBoxBlock extends BaseEntityBlock { - } else if (player.isSpectator()) { - return InteractionResult.CONSUME; - } else if (world.getBlockEntity(pos) instanceof ShulkerBoxBlockEntity shulkerBoxBlockEntity) { -- if (canOpen(state, world, pos, shulkerBoxBlockEntity)) { -- player.openMenu(shulkerBoxBlockEntity); -+ if (canOpen(state, world, pos, shulkerBoxBlockEntity) && player.openMenu(shulkerBoxBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation - player.awardStat(Stats.OPEN_SHULKER_BOX); - PiglinAi.angerNearbyPiglins(player, true); - } +@@ -104,8 +104,8 @@ public class ShulkerBoxBlock extends BaseEntityBlock { + protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { + if (world instanceof ServerLevel serverLevel + && world.getBlockEntity(pos) instanceof ShulkerBoxBlockEntity shulkerBoxBlockEntity +- && canOpen(state, world, pos, shulkerBoxBlockEntity)) { +- player.openMenu(shulkerBoxBlockEntity); ++ && canOpen(state, world, pos, shulkerBoxBlockEntity) // Paper - Fix InventoryOpenEvent cancellation - expand if for belows check ++ && player.openMenu(shulkerBoxBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + player.awardStat(Stats.OPEN_SHULKER_BOX); + PiglinAi.angerNearbyPiglins(serverLevel, player, true); + } diff --git a/src/main/java/net/minecraft/world/level/block/SmithingTableBlock.java b/src/main/java/net/minecraft/world/level/block/SmithingTableBlock.java -index cd93d0f5b2ba2d3162e14ded3db2e64b598e318f..dae5a125e90514d9eb920ff405c78eea43504698 100644 +index 6b316b8829f542023c20293d664a2d0716fb6c4c..43dc3d2c419a8b4a76de49a1e625076741a98c73 100644 --- a/src/main/java/net/minecraft/world/level/block/SmithingTableBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SmithingTableBlock.java -@@ -39,10 +39,9 @@ public class SmithingTableBlock extends CraftingTableBlock { +@@ -38,8 +38,9 @@ public class SmithingTableBlock extends CraftingTableBlock { + @Override protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { - if (world.isClientSide) { - return InteractionResult.SUCCESS; -- } else { + if (!world.isClientSide) { - player.openMenu(state.getMenuProvider(world, pos)); -+ } else if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation ++ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation player.awardStat(Stats.INTERACT_WITH_SMITHING_TABLE); -- return InteractionResult.CONSUME; ++ } // Paper - Fix InventoryOpenEvent cancellation } -+ return InteractionResult.CONSUME; // Paper - Fix InventoryOpenEvent cancellation - } - } + + return InteractionResult.SUCCESS; diff --git a/src/main/java/net/minecraft/world/level/block/SmokerBlock.java b/src/main/java/net/minecraft/world/level/block/SmokerBlock.java index b0929942ca06ee14d2ba4f2ec2ee93743ee6233e..83669dfbfec46d319aec82ea2beaa90c9f6b81c3 100644 --- a/src/main/java/net/minecraft/world/level/block/SmokerBlock.java @@ -349,20 +336,17 @@ index b0929942ca06ee14d2ba4f2ec2ee93743ee6233e..83669dfbfec46d319aec82ea2beaa90c } } diff --git a/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java b/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java -index c6ecb378d0cb2ac05b8f22f92fb85df060038f77..59fd521cd1e1101e2adce9830c43784e05abccdd 100644 +index 3a879d1a469a8f597bfba861d41abd75a5743ab8..e61644241f24b42bb4f702d3eef5b590b4d107c8 100644 --- a/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/StonecutterBlock.java -@@ -49,11 +49,10 @@ public class StonecutterBlock extends Block { +@@ -48,8 +48,9 @@ public class StonecutterBlock extends Block { + @Override protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { - if (world.isClientSide) { - return InteractionResult.SUCCESS; -- } else { + if (!world.isClientSide) { - player.openMenu(state.getMenuProvider(world, pos)); -+ } else if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation ++ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation player.awardStat(Stats.INTERACT_WITH_STONECUTTER); -- return InteractionResult.CONSUME; ++ } // Paper - Fix InventoryOpenEvent cancellation } -+ return InteractionResult.CONSUME; // Paper - Fix InventoryOpenEvent cancellation - } - @Nullable + return InteractionResult.SUCCESS; diff --git a/patches/unapplied/server/1050-Fire-BlockExpEvent-on-grindstone-use.patch b/patches/server/1019-Fire-BlockExpEvent-on-grindstone-use.patch similarity index 94% rename from patches/unapplied/server/1050-Fire-BlockExpEvent-on-grindstone-use.patch rename to patches/server/1019-Fire-BlockExpEvent-on-grindstone-use.patch index 58783e8acda7..e5944fabfef3 100644 --- a/patches/unapplied/server/1050-Fire-BlockExpEvent-on-grindstone-use.patch +++ b/patches/server/1019-Fire-BlockExpEvent-on-grindstone-use.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fire BlockExpEvent on grindstone use diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java -index 1678f6c8b2c7db761783e53043169bf12bc2cb29..138f77d13dda574def523d74fa55bc71b5bfa01b 100644 +index 3b303d41b9facfb2892ff8402ee0de4608db7318..5687f492fc76f699e2a388790ca5380d9b8c8d0a 100644 --- a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java +++ b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java @@ -98,7 +98,11 @@ public class GrindstoneMenu extends AbstractContainerMenu { diff --git a/patches/unapplied/server/1051-Check-dead-flag-in-isAlive.patch b/patches/server/1020-Check-dead-flag-in-isAlive.patch similarity index 80% rename from patches/unapplied/server/1051-Check-dead-flag-in-isAlive.patch rename to patches/server/1020-Check-dead-flag-in-isAlive.patch index e00e21c5b9f1..c58a1f41f8ec 100644 --- a/patches/unapplied/server/1051-Check-dead-flag-in-isAlive.patch +++ b/patches/server/1020-Check-dead-flag-in-isAlive.patch @@ -15,10 +15,10 @@ Also, even if the plugin is responsibly checking !isDead() before modifying heal I am currently unable to replicate, these "revived" entities can still appear diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 13c93281f6b81e88f2f54befb8e6a3e4bdabf53d..30f4f1254fc295442d72d50479e8af635f2fe983 100644 +index b4d1848858fae20f81c27b31bc0c280c6705f082..f57c830a7286eb8cab1061c8ddebe6abab1fcced 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2096,7 +2096,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2147,7 +2147,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @Override public boolean isAlive() { @@ -26,4 +26,4 @@ index 13c93281f6b81e88f2f54befb8e6a3e4bdabf53d..30f4f1254fc295442d72d50479e8af63 + return !this.isRemoved() && this.getHealth() > 0.0F && !this.dead; // Paper - Check this.dead } - @Override + public boolean isLookingAtMe(LivingEntity entity, double d0, boolean flag, boolean visualShape, Predicate predicate, DoubleSupplier... entityYChecks) { diff --git a/patches/unapplied/server/1046-Properly-destroy-placed-blocks-on-the-end-platform.patch b/patches/unapplied/server/1046-Properly-destroy-placed-blocks-on-the-end-platform.patch deleted file mode 100644 index c81ee5b7b21b..000000000000 --- a/patches/unapplied/server/1046-Properly-destroy-placed-blocks-on-the-end-platform.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: DerEchtePilz <81232921+DerEchtePilz@users.noreply.github.com> -Date: Sun, 18 Aug 2024 13:05:31 +0200 -Subject: [PATCH] Properly destroy placed blocks on the end platform - -The craftbukkit provided implementation of LevelAccessor, -BlockStateListPopulator, does not support destroyBlock calls, simply -ignoring them. - -This causes the destroyBlock calls during the generation of the end -platform to be lost. The patch moves the destroy calls and executes them -on the actual world access. - -diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/EndPlatformFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/EndPlatformFeature.java -index ff1f151b342a1567605f92a921fc7ab01f1c4807..b92c40352e4f1af05a2f90701b3f74c235ae57cf 100644 ---- a/src/main/java/net/minecraft/world/level/levelgen/feature/EndPlatformFeature.java -+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/EndPlatformFeature.java -@@ -44,7 +44,7 @@ public class EndPlatformFeature extends Feature { - // CraftBukkit start - if (!blockList.getBlockState(blockposition_mutableblockposition1).is(block)) { - if (flag) { -- blockList.destroyBlock(blockposition_mutableblockposition1, true, (Entity) null); -+ // blockList.destroyBlock(blockposition_mutableblockposition1, true, (Entity) null); // Paper - moved down - cb implementation of LevelAccessor does not support destroyBlock - } - - blockList.setBlock(blockposition_mutableblockposition1, block.defaultBlockState(), 3); From 227caac7f0facbf3b0f2d79925be649071eb82ca Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Fri, 25 Oct 2024 12:06:49 +0200 Subject: [PATCH 048/119] Wrong attempt at Tag lifecycle --- .../1021-Add-FeatureFlag-API.patch} | 12 +- .../1022-Tag-Lifecycle-Events.patch} | 178 ++++++++++++------ 2 files changed, 124 insertions(+), 66 deletions(-) rename patches/{unapplied/server/1052-Add-FeatureFlag-API.patch => server/1021-Add-FeatureFlag-API.patch} (97%) rename patches/{unapplied/server/1053-Tag-Lifecycle-Events.patch => server/1022-Tag-Lifecycle-Events.patch} (67%) diff --git a/patches/unapplied/server/1052-Add-FeatureFlag-API.patch b/patches/server/1021-Add-FeatureFlag-API.patch similarity index 97% rename from patches/unapplied/server/1052-Add-FeatureFlag-API.patch rename to patches/server/1021-Add-FeatureFlag-API.patch index aa4354324941..733275936a32 100644 --- a/patches/unapplied/server/1052-Add-FeatureFlag-API.patch +++ b/patches/server/1021-Add-FeatureFlag-API.patch @@ -144,10 +144,10 @@ index da90e5c84a0cc4505a5fff0ed278a905978c6ce2..00000000000000000000000000000000 - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index 284234fcdd15c4c7a4567c7c887d47bf0b7967f4..c9ecec5da937bc5458f69736b68ff6ae50aa5ebc 100644 +index f0bd7d01f56bb792886354ca4f199e46c2cf7503..adc6741e0e017660fbd39a62b69be1e67e0e143f 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -@@ -558,4 +558,11 @@ public abstract class CraftRegionAccessor implements RegionAccessor { +@@ -564,4 +564,11 @@ public abstract class CraftRegionAccessor implements RegionAccessor { return !this.getHandle().noCollision(aabb); } // Paper end @@ -160,10 +160,10 @@ index 284234fcdd15c4c7a4567c7c887d47bf0b7967f4..c9ecec5da937bc5458f69736b68ff6ae + // Paper end - feature flag API } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 74feb45c3199308652448c8448eb87fb8fbf6f11..7fc52f9f4f2e2cd8ea3abdf6c6f5d1f679779c47 100644 +index 8367f0f344d42b6ccdfbe761be1735ac9a64bfab..36c3024c188197a777c8077704e1b64552c02d0a 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2374,10 +2374,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2379,10 +2379,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { return this.persistentDataContainer; } @@ -221,7 +221,7 @@ index c81455a4ee9a3185f125ebf8cec325f4ed2e501d..8d962b055bd6574df7eb5510dd0efd67 + // Paper end - feature flag API } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java -index 450c63c31d2f5d056d989aa00452231f50c8224d..b9d9f1df2720c301915c8b07c0bdc12970128324 100644 +index d3f650d040afae8cb962696381c692cd7884bb4d..1b57649d0d3db24ed32c78cf3d5ce1d9fb1353e0 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java @@ -36,7 +36,7 @@ import org.bukkit.inventory.meta.ItemMeta; @@ -282,7 +282,7 @@ index 6cf790c9fa23ea313423fdaeb7c181bf530828c6..0bcb9df1103050441f8922a688b163dc public static PotionEffectType minecraftHolderToBukkit(Holder minecraft) { return CraftPotionEffectType.minecraftToBukkit(minecraft.value()); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 6adc18c40d5d62e2ebc8deec197cec630a366937..8b2dbdfcdc4e98602f6bfd48d2c53840730f4691 100644 +index 02745957a08a27af6a032453b8b20a8fed2911b3..293757b8e96ae7b0e807d807affa3fdab5181d39 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -47,7 +47,7 @@ import org.bukkit.advancement.Advancement; diff --git a/patches/unapplied/server/1053-Tag-Lifecycle-Events.patch b/patches/server/1022-Tag-Lifecycle-Events.patch similarity index 67% rename from patches/unapplied/server/1053-Tag-Lifecycle-Events.patch rename to patches/server/1022-Tag-Lifecycle-Events.patch index 4b148fce5354..5df52ccc9d65 100644 --- a/patches/unapplied/server/1053-Tag-Lifecycle-Events.patch +++ b/patches/server/1022-Tag-Lifecycle-Events.patch @@ -63,14 +63,15 @@ index 0000000000000000000000000000000000000000..1cf4a3caa8d630e95eb569eef2cd577b +} diff --git a/src/main/java/io/papermc/paper/tag/PaperPostFlattenTagRegistrar.java b/src/main/java/io/papermc/paper/tag/PaperPostFlattenTagRegistrar.java new file mode 100644 -index 0000000000000000000000000000000000000000..cc37618cbbad7f21d65c7753f4dd4416042d2146 +index 0000000000000000000000000000000000000000..2596586fd7e2546cd18cf6ac36a4eb5cf8d00359 --- /dev/null +++ b/src/main/java/io/papermc/paper/tag/PaperPostFlattenTagRegistrar.java -@@ -0,0 +1,118 @@ +@@ -0,0 +1,119 @@ +package io.papermc.paper.tag; + +import com.google.common.collect.Collections2; +import com.google.common.collect.ImmutableMap; ++import com.google.common.collect.Lists; +import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.plugin.bootstrap.BootstrapContext; +import io.papermc.paper.plugin.lifecycle.event.registrar.PaperRegistrar; @@ -95,13 +96,13 @@ index 0000000000000000000000000000000000000000..cc37618cbbad7f21d65c7753f4dd4416 +@DefaultQualifier(NonNull.class) +public class PaperPostFlattenTagRegistrar implements PaperRegistrar, PostFlattenTagRegistrar { + -+ public final Map> tags; ++ public final Map> tags; + private final Function> fromIdConverter; + private final Function toIdConverter; + private final RegistryKey registryKey; + + public PaperPostFlattenTagRegistrar( -+ final Map> tags, ++ final Map> tags, + final TagEventConfig config + ) { + this.tags = tags; @@ -122,16 +123,16 @@ index 0000000000000000000000000000000000000000..cc37618cbbad7f21d65c7753f4dd4416 + @Override + public Map, Collection>> getAllTags() { + final ImmutableMap.Builder, Collection>> tags = ImmutableMap.builderWithExpectedSize(this.tags.size()); -+ for (final Map.Entry> entry : this.tags.entrySet()) { ++ for (final Map.Entry> entry : this.tags.entrySet()) { + final TagKey key = TagKey.create(this.registryKey, CraftNamespacedKey.fromMinecraft(entry.getKey())); + tags.put(key, this.convert(entry.getValue())); + } + return tags.build(); + } + -+ private Collection> convert(final Collection nms) { -+ return Collections.unmodifiableCollection( -+ Collections2.transform(nms, m -> this.convert(this.toIdConverter.apply(m))) ++ private List> convert(final List nms) { ++ return Collections.unmodifiableList( ++ Lists.transform(nms, m -> this.convert(this.toIdConverter.apply(m))) + ); + } + @@ -152,9 +153,9 @@ index 0000000000000000000000000000000000000000..cc37618cbbad7f21d65c7753f4dd4416 + return this.tags.containsKey(PaperAdventure.asVanilla(tagKey.key())); + } + -+ private Collection getNmsTag(final TagKey tagKey, final boolean create) { ++ private List getNmsTag(final TagKey tagKey, final boolean create) { + final ResourceLocation vanillaKey = PaperAdventure.asVanilla(tagKey.key()); -+ Collection tag = this.tags.get(vanillaKey); ++ List tag = this.tags.get(vanillaKey); + if (tag == null) { + if (create) { + tag = this.tags.computeIfAbsent(vanillaKey, k -> new ArrayList<>()); @@ -172,7 +173,7 @@ index 0000000000000000000000000000000000000000..cc37618cbbad7f21d65c7753f4dd4416 + + @Override + public void addToTag(final TagKey tagKey, final Collection> values) { -+ final Collection nmsTag = new ArrayList<>(this.getNmsTag(tagKey, true)); ++ final List nmsTag = new ArrayList<>(this.getNmsTag(tagKey, true)); + for (final TypedKey key : values) { + nmsTag.add(this.convert(key)); + } @@ -321,7 +322,7 @@ index 0000000000000000000000000000000000000000..44111b55eaa6d1cc93e2c556b23bb5c9 +} diff --git a/src/main/java/io/papermc/paper/tag/PaperTagListenerManager.java b/src/main/java/io/papermc/paper/tag/PaperTagListenerManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..f3e4019f9d55d3cce34248a806bf0ccb37c8e7b1 +index 0000000000000000000000000000000000000000..e1ffb7f1df667dd9f92c00ff94b791feb1f14eed --- /dev/null +++ b/src/main/java/io/papermc/paper/tag/PaperTagListenerManager.java @@ -0,0 +1,105 @@ @@ -377,8 +378,8 @@ index 0000000000000000000000000000000000000000..f3e4019f9d55d3cce34248a806bf0ccb + return Map.copyOf(registrar.tags); + } + -+ public Map> firePostFlattenEvent( -+ final Map> initial, ++ public Map> firePostFlattenEvent( ++ final Map> initial, + final @Nullable TagEventConfig config + ) { + if (config == null || config.postFlatten() == null || !config.postFlatten().hasHandlers()) { @@ -412,7 +413,7 @@ index 0000000000000000000000000000000000000000..f3e4019f9d55d3cce34248a806bf0ccb + preFlatten, + postFlatten, + cause, -+ registry::getHolder, ++ registry::get, + h -> ((Holder.Reference) h).key().location(), + PaperRegistries.registryFromNms(registry.key()) + ); @@ -459,11 +460,50 @@ index 0000000000000000000000000000000000000000..d6d4bfc6f45d646afeace422a038c670 + RegistryKey apiRegistryKey +) { +} +diff --git a/src/main/java/net/minecraft/resources/RegistryDataLoader.java b/src/main/java/net/minecraft/resources/RegistryDataLoader.java +index f2236665eaf3e6d0f9d44605db3cd5afe0cced4e..28d809a0e2fccd15a09bc6b55ca024526867ada7 100644 +--- a/src/main/java/net/minecraft/resources/RegistryDataLoader.java ++++ b/src/main/java/net/minecraft/resources/RegistryDataLoader.java +@@ -278,7 +278,7 @@ public class RegistryDataLoader { + } + } + +- TagLoader.loadTagsForRegistry(resourceManager, registry); ++ TagLoader.loadTagsForRegistry(resourceManager, registry, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL); // Paper - tag lifecycle - add cause + } + + static void loadContentsFromNetwork( +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index dcf046dd1eb8c2b724c971c4adf4462895183f0a..448961d7bd80e7e84959866906e6a4e3ac9ab4f7 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -2251,7 +2251,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoopmap(resourcepackrepository::getPack).filter(Objects::nonNull).map(Pack::open).collect(ImmutableList.toImmutableList()); // CraftBukkit - decompile error // Paper - decompile error // todo: is this needed anymore? + }, this).thenCompose((immutablelist) -> { + MultiPackResourceManager resourcemanager = new MultiPackResourceManager(PackType.SERVER_DATA, immutablelist); +- List> list = TagLoader.loadTagsForExistingRegistries(resourcemanager, this.registries.compositeAccess()); ++ List> list = TagLoader.loadTagsForExistingRegistries(resourcemanager, this.registries.compositeAccess(), io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.RELOAD); // Paper - tag lifecycle - add cause + + return ReloadableServerResources.loadResources(resourcemanager, this.registries, list, this.worldData.enabledFeatures(), this.isDedicatedServer() ? Commands.CommandSelection.DEDICATED : Commands.CommandSelection.INTEGRATED, this.getFunctionCompilationLevel(), this.executor, this).whenComplete((datapackresources, throwable) -> { + if (throwable != null) { +diff --git a/src/main/java/net/minecraft/server/ReloadableServerRegistries.java b/src/main/java/net/minecraft/server/ReloadableServerRegistries.java +index b5ca1a0acb16d0cd8dccc854f309d425a48b070d..ea1cbd7a3897ea4a86877a557da264387ef78a38 100644 +--- a/src/main/java/net/minecraft/server/ReloadableServerRegistries.java ++++ b/src/main/java/net/minecraft/server/ReloadableServerRegistries.java +@@ -70,7 +70,7 @@ public class ReloadableServerRegistries { + String string = Registries.elementsDirPath(type.registryKey()); + SimpleJsonResourceReloadListener.scanDirectory(resourceManager, string, ops, type.codec(), map); + map.forEach((id, value) -> io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.registerWithListeners(writableRegistry, ResourceKey.create(type.registryKey(), id), value, DEFAULT_REGISTRATION_INFO, conversions)); // Paper - register with listeners +- TagLoader.loadTagsForRegistry(resourceManager, writableRegistry); ++ TagLoader.loadTagsForRegistry(resourceManager, writableRegistry, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.RELOAD); // Paper - tag life cycle - reload + return writableRegistry; + }, prepareExecutor); + } diff --git a/src/main/java/net/minecraft/server/ServerFunctionLibrary.java b/src/main/java/net/minecraft/server/ServerFunctionLibrary.java -index 8ae2ca2435d84fee930d2931e45ad440245cbe0f..9fff5ca1e9707e4e6be5ecb92be936332d24bb96 100644 +index 7128f01308b60163afa9355b79cb4129b630663d..fa5d4bfd52eb36e48fc811dbbdc1341204cf171d 100644 --- a/src/main/java/net/minecraft/server/ServerFunctionLibrary.java +++ b/src/main/java/net/minecraft/server/ServerFunctionLibrary.java -@@ -118,7 +118,7 @@ public class ServerFunctionLibrary implements PreparableReloadListener { +@@ -113,7 +113,7 @@ public class ServerFunctionLibrary implements PreparableReloadListener { return null; }).join()); this.functions = builder.build(); @@ -472,66 +512,84 @@ index 8ae2ca2435d84fee930d2931e45ad440245cbe0f..9fff5ca1e9707e4e6be5ecb92be93633 }, applyExecutor ); +diff --git a/src/main/java/net/minecraft/server/WorldLoader.java b/src/main/java/net/minecraft/server/WorldLoader.java +index f21ccc50f2d507afe1e0af394321020cb5667e60..fad1cc1be3d1b84acacde8736129b970824f48b8 100644 +--- a/src/main/java/net/minecraft/server/WorldLoader.java ++++ b/src/main/java/net/minecraft/server/WorldLoader.java +@@ -37,7 +37,7 @@ public class WorldLoader { + CloseableResourceManager closeableResourceManager = pair.getSecond(); + LayeredRegistryAccess layeredRegistryAccess = RegistryLayer.createRegistryAccess(); + List> list = TagLoader.loadTagsForExistingRegistries( +- closeableResourceManager, layeredRegistryAccess.getLayer(RegistryLayer.STATIC) ++ closeableResourceManager, layeredRegistryAccess.getLayer(RegistryLayer.STATIC), io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL // Paper - tag lifecycle - add cause + ); + RegistryAccess.Frozen frozen = layeredRegistryAccess.getAccessForLoading(RegistryLayer.WORLDGEN); + List> list2 = TagLoader.buildUpdatedLookups(frozen, list); diff --git a/src/main/java/net/minecraft/tags/TagLoader.java b/src/main/java/net/minecraft/tags/TagLoader.java -index b47afb0ce8d9517ac7ee9c651c160f99d70f8a98..0bde4f7ae7d1897c630513261d1d5fb75a762634 100644 +index 8d742805f7b44b832b532d4ee6d313c0d7659e1d..a81b2b47b909b3858046d2b152d31b2cfc5d5fe4 100644 --- a/src/main/java/net/minecraft/tags/TagLoader.java +++ b/src/main/java/net/minecraft/tags/TagLoader.java -@@ -79,7 +79,10 @@ public class TagLoader { - return list.isEmpty() ? Either.right(builder.build()) : Either.left(list); +@@ -86,7 +86,10 @@ public class TagLoader { + return list.isEmpty() ? Either.right(List.copyOf(sequencedSet)) : Either.left(list); } -- public Map> build(Map> tags) { +- public Map> build(Map> tags) { + // Paper start - fire tag registrar events -+ public Map> build(Map> tags, @Nullable io.papermc.paper.tag.TagEventConfig eventConfig) { ++ public Map> build(Map> tags, @Nullable io.papermc.paper.tag.TagEventConfig eventConfig) { + tags = io.papermc.paper.tag.PaperTagListenerManager.INSTANCE.firePreFlattenEvent(tags, eventConfig); -+ // Paper end - fire tag registrar events - final Map> map = Maps.newHashMap(); ++ // Paper end - fire tag registrar event + final Map> map = new HashMap<>(); TagEntry.Lookup lookup = new TagEntry.Lookup() { @Nullable -@@ -107,11 +110,13 @@ public class TagLoader { +@@ -114,7 +117,7 @@ public class TagLoader { ) - .ifRight(resolvedEntries -> map.put(id, (Collection)resolvedEntries)) + .ifRight(values -> map.put(id, (List)values)) ); - return map; + return io.papermc.paper.tag.PaperTagListenerManager.INSTANCE.firePostFlattenEvent(map, eventConfig); // Paper - fire tag registrar events } -- public Map> loadAndBuild(ResourceManager manager) { -- return this.build(this.load(manager)); -+ // Paper start - fire tag registrar events -+ public Map> loadAndBuild(ResourceManager manager, @Nullable io.papermc.paper.tag.TagEventConfig eventConfig) { -+ return this.build(this.load(manager), eventConfig); -+ // Paper end - fire tag registrar events + public static void loadTagsFromNetwork(TagNetworkSerialization.NetworkPayload tags, WritableRegistry registry) { +@@ -122,28 +125,38 @@ public class TagLoader { + } + + public static List> loadTagsForExistingRegistries(ResourceManager resourceManager, RegistryAccess registryManager) { ++ // Paper start - tag lifecycle - add cause ++ return loadTagsForExistingRegistries(resourceManager, registryManager, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL); ++ } ++ public static List> loadTagsForExistingRegistries(ResourceManager resourceManager, RegistryAccess registryManager, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause cause) { ++ // Paper end - tag lifecycle - add cause + return registryManager.registries() +- .map(registry -> loadPendingTags(resourceManager, registry.value())) ++ .map(registry -> loadPendingTags(resourceManager, registry.value(), cause)) // Paper - tag lifecycle - add cause + .flatMap(Optional::stream) + .collect(Collectors.toUnmodifiableList()); } - public static record EntryWithSource(TagEntry entry, String source) { -diff --git a/src/main/java/net/minecraft/tags/TagManager.java b/src/main/java/net/minecraft/tags/TagManager.java -index 7116362d798d7c28a4880c873a60507afa4673e6..2188274de5d1fe1aa5419be6247da6a3a2414a3b 100644 ---- a/src/main/java/net/minecraft/tags/TagManager.java -+++ b/src/main/java/net/minecraft/tags/TagManager.java -@@ -39,7 +39,7 @@ public class TagManager implements PreparableReloadListener { - ) { - List>> list = this.registryAccess - .registries() -- .map(registry -> this.createLoader(manager, prepareExecutor, (RegistryAccess.RegistryEntry)registry)) -+ .map(registry -> this.createLoader(manager, prepareExecutor, (RegistryAccess.RegistryEntry)registry, applyExecutor instanceof net.minecraft.server.MinecraftServer ? io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL : io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.RELOAD)) // Paper - add registrar event cause - .toList(); - return CompletableFuture.allOf(list.toArray(CompletableFuture[]::new)) - .thenCompose(synchronizer::wait) -@@ -48,11 +48,15 @@ public class TagManager implements PreparableReloadListener { + public static void loadTagsForRegistry(ResourceManager resourceManager, WritableRegistry registry) { ++ // Paper start - tag lifecycle - add registrar event cause ++ loadTagsForRegistry(resourceManager, registry, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL); ++ } ++ public static void loadTagsForRegistry(ResourceManager resourceManager, WritableRegistry registry, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause cause) { ++ // Paper end - tag lifecycle - add registrar event cause + ResourceKey> resourceKey = registry.key(); + TagLoader> tagLoader = new TagLoader<>(TagLoader.ElementLookup.fromWritableRegistry(registry), Registries.tagsDirPath(resourceKey)); +- tagLoader.build(tagLoader.load(resourceManager)).forEach((id, entries) -> registry.bindTag(TagKey.create(resourceKey, id), (List>)entries)); ++ tagLoader.build(tagLoader.load(resourceManager), io.papermc.paper.tag.PaperTagListenerManager.INSTANCE.createEventConfig(registry, cause)).forEach((id, entries) -> registry.bindTag(TagKey.create(resourceKey, id), (List>)entries)); // Paper - tag lifecycle - add registrar event cause + } - private CompletableFuture> createLoader( - ResourceManager resourceManager, Executor prepareExecutor, RegistryAccess.RegistryEntry requirement -+ , io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause cause // Paper - add registrar event cause - ) { - ResourceKey> resourceKey = requirement.key(); - Registry registry = requirement.value(); - TagLoader> tagLoader = new TagLoader<>(registry::getHolder, Registries.tagsDirPath(resourceKey)); -- return CompletableFuture.supplyAsync(() -> new TagManager.LoadResult<>(resourceKey, tagLoader.loadAndBuild(resourceManager)), prepareExecutor); -+ // Paper start - fire tag registrar events -+ final io.papermc.paper.tag.TagEventConfig, ?> config = io.papermc.paper.tag.PaperTagListenerManager.INSTANCE.createEventConfig(registry, cause); -+ return CompletableFuture.supplyAsync(() -> new TagManager.LoadResult<>(resourceKey, tagLoader.loadAndBuild(resourceManager, config)), prepareExecutor); -+ // Paper end - fire tag registrar events + private static Map, List>> wrapTags(ResourceKey> registryRef, Map>> tags) { + return tags.entrySet().stream().collect(Collectors.toUnmodifiableMap(entry -> TagKey.create(registryRef, entry.getKey()), Entry::getValue)); + } + +- private static Optional> loadPendingTags(ResourceManager resourceManager, Registry registry) { ++ private static Optional> loadPendingTags(ResourceManager resourceManager, Registry registry, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause cause) { // Paper - add registrar event cause + ResourceKey> resourceKey = registry.key(); + TagLoader> tagLoader = new TagLoader<>( + (TagLoader.ElementLookup>)TagLoader.ElementLookup.fromFrozenRegistry(registry), Registries.tagsDirPath(resourceKey) + ); +- TagLoader.LoadResult loadResult = new TagLoader.LoadResult<>(resourceKey, wrapTags(registry.key(), tagLoader.build(tagLoader.load(resourceManager)))); ++ TagLoader.LoadResult loadResult = new TagLoader.LoadResult<>(resourceKey, wrapTags(registry.key(), tagLoader.build(tagLoader.load(resourceManager), io.papermc.paper.tag.PaperTagListenerManager.INSTANCE.createEventConfig(registry, cause)))); // Paper - add registrar event cause + return loadResult.tags().isEmpty() ? Optional.empty() : Optional.of(registry.prepareTagReload(loadResult)); } - public static record LoadResult(ResourceKey> key, Map>> tags) { From afbb0d88dd4d9794654e4dc994f5a5891dfba590 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Fri, 25 Oct 2024 12:28:34 +0200 Subject: [PATCH 049/119] 1037 --- .../1023-Item-serialization-as-json.patch} | 4 +- ...ate-slot-in-PlayerInventory-setSlot.patch} | 2 +- ...ll-time-unused-skip-tick-protection.patch} | 22 +-- ...tty-printing-for-advancement-saving.patch} | 2 +- ...dPreprocessEvent-on-signed-commands.patch} | 4 +- ...evels-with-enchantment-registry-set.patch} | 4 +- .../1029-Improve-entity-effect-API.patch} | 16 +- .../1030-Add-recipeBrewTime.patch} | 20 +-- ...31-Call-bucket-events-for-cauldrons.patch} | 149 ++++++++++-------- ...32-Add-PlayerInsertLecternBookEvent.patch} | 4 +- .../1033-Void-damage-configuration-API.patch} | 19 ++- .../1034-Add-Offline-PDC-API.patch} | 0 ...w-bypassEnchantmentLevelRestriction.patch} | 6 +- ...-proper-async-player-disconnections.patch} | 38 ++--- ...-send-Banner-patterns-to-the-client.patch} | 13 +- 15 files changed, 157 insertions(+), 146 deletions(-) rename patches/{unapplied/server/1054-Item-serialization-as-json.patch => server/1023-Item-serialization-as-json.patch} (96%) rename patches/{unapplied/server/1055-Validate-slot-in-PlayerInventory-setSlot.patch => server/1024-Validate-slot-in-PlayerInventory-setSlot.patch} (93%) rename patches/{unapplied/server/1056-Remove-wall-time-unused-skip-tick-protection.patch => server/1025-Remove-wall-time-unused-skip-tick-protection.patch} (91%) rename patches/{unapplied/server/1057-Disable-pretty-printing-for-advancement-saving.patch => server/1026-Disable-pretty-printing-for-advancement-saving.patch} (92%) rename patches/{unapplied/server/1058-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch => server/1027-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch} (93%) rename patches/{unapplied/server/1059-Add-enchantWithLevels-with-enchantment-registry-set.patch => server/1028-Add-enchantWithLevels-with-enchantment-registry-set.patch} (89%) rename patches/{unapplied/server/1060-Improve-entity-effect-API.patch => server/1029-Improve-entity-effect-API.patch} (91%) rename patches/{unapplied/server/1061-Add-recipeBrewTime.patch => server/1030-Add-recipeBrewTime.patch} (92%) rename patches/{unapplied/server/1062-Call-bucket-events-for-cauldrons.patch => server/1031-Call-bucket-events-for-cauldrons.patch} (51%) rename patches/{unapplied/server/1063-Add-PlayerInsertLecternBookEvent.patch => server/1032-Add-PlayerInsertLecternBookEvent.patch} (92%) rename patches/{unapplied/server/1064-Void-damage-configuration-API.patch => server/1033-Void-damage-configuration-API.patch} (79%) rename patches/{unapplied/server/1065-Add-Offline-PDC-API.patch => server/1034-Add-Offline-PDC-API.patch} (100%) rename patches/{unapplied/server/1066-Add-AnvilView-bypassEnchantmentLevelRestriction.patch => server/1035-Add-AnvilView-bypassEnchantmentLevelRestriction.patch} (92%) rename patches/{unapplied/server/1067-Add-proper-async-player-disconnections.patch => server/1036-Add-proper-async-player-disconnections.patch} (85%) rename patches/{unapplied/server/1068-Always-send-Banner-patterns-to-the-client.patch => server/1037-Always-send-Banner-patterns-to-the-client.patch} (83%) diff --git a/patches/unapplied/server/1054-Item-serialization-as-json.patch b/patches/server/1023-Item-serialization-as-json.patch similarity index 96% rename from patches/unapplied/server/1054-Item-serialization-as-json.patch rename to patches/server/1023-Item-serialization-as-json.patch index 20a7aba6f343..51d1f7f8085f 100644 --- a/patches/unapplied/server/1054-Item-serialization-as-json.patch +++ b/patches/server/1023-Item-serialization-as-json.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Item serialization as json diff --git a/src/main/java/net/minecraft/world/item/component/CustomData.java b/src/main/java/net/minecraft/world/item/component/CustomData.java -index 6b7245cf05ea4b6ce05462eb3164bce7f5d76a03..ac1914438307e8a7cc3a3b6352e88a0638f8a33b 100644 +index c80fd4960dfbb0fde37363e7df25b0a5411bdb11..ff7f6916f65466c25a7bde35d64682c15b211697 100644 --- a/src/main/java/net/minecraft/world/item/component/CustomData.java +++ b/src/main/java/net/minecraft/world/item/component/CustomData.java @@ -28,7 +28,17 @@ import org.slf4j.Logger; @@ -28,7 +28,7 @@ index 6b7245cf05ea4b6ce05462eb3164bce7f5d76a03..ac1914438307e8a7cc3a3b6352e88a06 public static final Codec CODEC_WITH_ID = CODEC.validate( component -> component.getUnsafe().contains("id", 8) ? DataResult.success(component) : DataResult.error(() -> "Missing id for entity in: " + component) diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 8b2dbdfcdc4e98602f6bfd48d2c53840730f4691..d06aab9bd5cd901c8367f9680f5d27ddb17b3dc4 100644 +index 293757b8e96ae7b0e807d807affa3fdab5181d39..f880bf91155b017c954e3e321c5a203c05c2162f 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -511,6 +511,39 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/unapplied/server/1055-Validate-slot-in-PlayerInventory-setSlot.patch b/patches/server/1024-Validate-slot-in-PlayerInventory-setSlot.patch similarity index 93% rename from patches/unapplied/server/1055-Validate-slot-in-PlayerInventory-setSlot.patch rename to patches/server/1024-Validate-slot-in-PlayerInventory-setSlot.patch index 51eb36e240c1..3c402b2284bc 100644 --- a/patches/unapplied/server/1055-Validate-slot-in-PlayerInventory-setSlot.patch +++ b/patches/server/1024-Validate-slot-in-PlayerInventory-setSlot.patch @@ -9,7 +9,7 @@ the setSlot method, making a validation necessary over simply silently ignoring invalid slot values. diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java -index eafa54c870c3e2aef30c3f9f96f516607a7cae24..8dea4321e41080829b474ad7b5a12c6a622181fd 100644 +index 656c9a6d8cd42891141ee29ec91ab5d166051ed6..df847c9897f209700a79aa1a8254b708ef7bf260 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java @@ -70,6 +70,11 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i diff --git a/patches/unapplied/server/1056-Remove-wall-time-unused-skip-tick-protection.patch b/patches/server/1025-Remove-wall-time-unused-skip-tick-protection.patch similarity index 91% rename from patches/unapplied/server/1056-Remove-wall-time-unused-skip-tick-protection.patch rename to patches/server/1025-Remove-wall-time-unused-skip-tick-protection.patch index e2d5d9dcabe6..7db8f330bd39 100644 --- a/patches/unapplied/server/1056-Remove-wall-time-unused-skip-tick-protection.patch +++ b/patches/server/1025-Remove-wall-time-unused-skip-tick-protection.patch @@ -30,7 +30,7 @@ completely unnecessary, which also rids paper of the previous described incompatibility with non-ticking chunks. diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index 03cfa29bdb426a9fb6b1b6be6e897da48d4f2f3e..4423973d4d9a2c3879d98d1d4c8b8c117c677ac5 100644 +index 246b5649883e4f305afa5a887b9df0f3735f7593..5d8885bca55503bf7e1a2a4e1bb9b3bd86d55391 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -60,7 +60,7 @@ public class ItemEntity extends Entity implements TraceableEntity { @@ -60,7 +60,7 @@ index 03cfa29bdb426a9fb6b1b6be6e897da48d4f2f3e..4423973d4d9a2c3879d98d1d4c8b8c11 this.xo = this.getX(); this.yo = this.getY(); -@@ -211,7 +210,7 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -212,7 +211,7 @@ public class ItemEntity extends Entity implements TraceableEntity { this.mergeWithNeighbours(); } @@ -69,7 +69,7 @@ index 03cfa29bdb426a9fb6b1b6be6e897da48d4f2f3e..4423973d4d9a2c3879d98d1d4c8b8c11 if (this.age != -32768) { ++this.age; } -@@ -242,12 +241,14 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -243,12 +242,14 @@ public class ItemEntity extends Entity implements TraceableEntity { // Spigot start - copied from above @Override public void inactiveTick() { @@ -91,10 +91,10 @@ index 03cfa29bdb426a9fb6b1b6be6e897da48d4f2f3e..4423973d4d9a2c3879d98d1d4c8b8c11 if (!this.level().isClientSide && this.age >= this.despawnRate) { // Spigot // Paper - Alternative item-despawn-rate // CraftBukkit start - fire ItemDespawnEvent diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index 2280004638fd19ed018cb3e77d53a018b34ec516..2b43337ac63d051718a2074fcc46e128a1d65129 100644 +index 17974f85d3c1db549ea11e8809954cd9d2af063e..5a6e119d29ecdc45dee40d5984e502fb8e4d1543 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -@@ -96,7 +96,7 @@ public class Zombie extends Monster { +@@ -98,7 +98,7 @@ public class Zombie extends Monster { private boolean canBreakDoors; private int inWaterTime; public int conversionTime; @@ -103,7 +103,7 @@ index 2280004638fd19ed018cb3e77d53a018b34ec516..2b43337ac63d051718a2074fcc46e128 private boolean shouldBurnInDay = true; // Paper - Add more Zombie API public Zombie(EntityType type, Level world) { -@@ -219,10 +219,7 @@ public class Zombie extends Monster { +@@ -217,10 +217,7 @@ public class Zombie extends Monster { public void tick() { if (!this.level().isClientSide && this.isAlive() && !this.isNoAi()) { if (this.isUnderWaterConverting()) { @@ -115,7 +115,7 @@ index 2280004638fd19ed018cb3e77d53a018b34ec516..2b43337ac63d051718a2074fcc46e128 if (this.conversionTime < 0) { this.doUnderWaterConversion(); } -@@ -239,7 +236,7 @@ public class Zombie extends Monster { +@@ -237,7 +234,7 @@ public class Zombie extends Monster { } super.tick(); @@ -124,7 +124,7 @@ index 2280004638fd19ed018cb3e77d53a018b34ec516..2b43337ac63d051718a2074fcc46e128 } @Override -@@ -280,7 +277,7 @@ public class Zombie extends Monster { +@@ -278,7 +275,7 @@ public class Zombie extends Monster { } // Paper end - Add more Zombie API public void startUnderWaterConversion(int ticksUntilWaterConversion) { @@ -134,10 +134,10 @@ index 2280004638fd19ed018cb3e77d53a018b34ec516..2b43337ac63d051718a2074fcc46e128 this.getEntityData().set(Zombie.DATA_DROWNED_CONVERSION_ID, true); } diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java -index a2fafef89d5354e2cb02f5672810909950a57777..bf2c303a314205590a2839e0f729af3a9ff40a86 100644 +index 2bafacd7bc56186d9105d2031180f8c4a6940018..4ea29e8f2b39d7b44e0461d6a2cdd3fc257abd44 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java -@@ -54,7 +54,7 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements +@@ -55,7 +55,7 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements public int fuel; protected final ContainerData dataAccess; // CraftBukkit start - add fields and methods @@ -146,7 +146,7 @@ index a2fafef89d5354e2cb02f5672810909950a57777..bf2c303a314205590a2839e0f729af3a public List transaction = new java.util.ArrayList(); private int maxStack = MAX_STACK; -@@ -169,12 +169,10 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements +@@ -170,12 +170,10 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements boolean flag1 = blockEntity.brewTime > 0; ItemStack itemstack1 = (ItemStack) blockEntity.items.get(3); diff --git a/patches/unapplied/server/1057-Disable-pretty-printing-for-advancement-saving.patch b/patches/server/1026-Disable-pretty-printing-for-advancement-saving.patch similarity index 92% rename from patches/unapplied/server/1057-Disable-pretty-printing-for-advancement-saving.patch rename to patches/server/1026-Disable-pretty-printing-for-advancement-saving.patch index 9a966bd65652..c6ad9249f5da 100644 --- a/patches/unapplied/server/1057-Disable-pretty-printing-for-advancement-saving.patch +++ b/patches/server/1026-Disable-pretty-printing-for-advancement-saving.patch @@ -8,7 +8,7 @@ Not sure why advancements even had pretty printing enabled. My best guess was by accident on mojang's part, especially since stats json files don't have pretty printing. diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java -index 9fabf9322acd663c4452b562494e74aa42eb19da..862a4bf003b7f810fb57dbcd150a1417c902b633 100644 +index 1dcb8a287be7df2a59b5b4c1345be80637a7f679..8e2eb7b61421ceb063654826941f1a81f6f50bdf 100644 --- a/src/main/java/net/minecraft/server/PlayerAdvancements.java +++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java @@ -50,7 +50,7 @@ import org.slf4j.Logger; diff --git a/patches/unapplied/server/1058-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch b/patches/server/1027-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch similarity index 93% rename from patches/unapplied/server/1058-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch rename to patches/server/1027-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch index 3f176be06c2e..baad9efd2424 100644 --- a/patches/unapplied/server/1058-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch +++ b/patches/server/1027-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix PlayerCommandPreprocessEvent on signed commands diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index fcccf989c25f0a259b160c4ff7873f7009e64d14..befeaac4786760f6847a5945da2296a3e68dbb17 100644 +index 1722f11ad070715077f5dcaff008b98f7ee104ab..cae9682df8795c5f73e86c27d717b6f72e7e8592 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2245,24 +2245,32 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2195,24 +2195,32 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(this.getCraftPlayer(), command, new LazyPlayerSet(this.server)); this.cserver.getPluginManager().callEvent(event); diff --git a/patches/unapplied/server/1059-Add-enchantWithLevels-with-enchantment-registry-set.patch b/patches/server/1028-Add-enchantWithLevels-with-enchantment-registry-set.patch similarity index 89% rename from patches/unapplied/server/1059-Add-enchantWithLevels-with-enchantment-registry-set.patch rename to patches/server/1028-Add-enchantWithLevels-with-enchantment-registry-set.patch index bdca715a0db9..115ef56bd399 100644 --- a/patches/unapplied/server/1059-Add-enchantWithLevels-with-enchantment-registry-set.patch +++ b/patches/server/1028-Add-enchantWithLevels-with-enchantment-registry-set.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add enchantWithLevels with enchantment registry set diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -index fef91dbede067f1ab99a9c7d463a2c55cc6cae3a..4abd939223a9d5a0c52a64e22c29fe1de85500e9 100644 +index 944dcc1126c947b4c8c3b4fdd174eb57320abbba..260fb93e71812698beb475bab7a05b9b860c6cbd 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -@@ -319,6 +319,22 @@ public final class CraftItemFactory implements ItemFactory { +@@ -322,6 +322,22 @@ public final class CraftItemFactory implements ItemFactory { ); } diff --git a/patches/unapplied/server/1060-Improve-entity-effect-API.patch b/patches/server/1029-Improve-entity-effect-API.patch similarity index 91% rename from patches/unapplied/server/1060-Improve-entity-effect-API.patch rename to patches/server/1029-Improve-entity-effect-API.patch index 1c14f7f686b2..b00b24e762c8 100644 --- a/patches/unapplied/server/1060-Improve-entity-effect-API.patch +++ b/patches/server/1029-Improve-entity-effect-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Improve entity effect API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index cd789c235acf740ec29c30b180e7fbe1a140caa9..89c8713d2c2206d1b0d8c0a392c9d13b3e736f0c 100644 +index ca95a36b0149d4b8a67c3b42316c5d9d0415f5dd..64c6f54cc4d0c22bc972b808cb92925cc7526db2 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1299,4 +1299,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1300,4 +1300,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return this.getHandle().getScoreboardName(); } // Paper end - entity scoreboard name @@ -25,10 +25,10 @@ index cd789c235acf740ec29c30b180e7fbe1a140caa9..89c8713d2c2206d1b0d8c0a392c9d13b + // Paper end - broadcast hurt animation } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index ad740739437be632fc7fedec488a7d0c49534688..42d7660efe5baa6f796f2a7606686c765b6f2478 100644 +index 8d16575c74b81ada4e4efe70e8f077f07cd0a3f0..852cadccfbd22d535f26ac781aea2fe99686947e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1277,6 +1277,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1294,6 +1294,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void sendHurtAnimation(float yaw) { @@ -40,7 +40,7 @@ index ad740739437be632fc7fedec488a7d0c49534688..42d7660efe5baa6f796f2a7606686c76 if (this.getHandle().connection == null) { return; } -@@ -1286,7 +1291,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1303,7 +1308,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { * This makes no sense. We'll add 90 to it so that 0 = front, clockwise from there. */ float actualYaw = yaw + 90; @@ -49,9 +49,9 @@ index ad740739437be632fc7fedec488a7d0c49534688..42d7660efe5baa6f796f2a7606686c76 } @Override -@@ -3553,4 +3558,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { - ((ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer)this.getHandle()) - .moonrise$getViewDistanceHolder().setSendViewDistance(viewDistance); +@@ -3545,4 +3550,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + public void setSendViewDistance(final int viewDistance) { + throw new UnsupportedOperationException("Not implemented yet"); } + + // Paper start - entity effect API diff --git a/patches/unapplied/server/1061-Add-recipeBrewTime.patch b/patches/server/1030-Add-recipeBrewTime.patch similarity index 92% rename from patches/unapplied/server/1061-Add-recipeBrewTime.patch rename to patches/server/1030-Add-recipeBrewTime.patch index cd4192dc8c10..39d714920679 100644 --- a/patches/unapplied/server/1061-Add-recipeBrewTime.patch +++ b/patches/server/1030-Add-recipeBrewTime.patch @@ -24,10 +24,10 @@ index 0000000000000000000000000000000000000000..84dead75191634c3aa6031781a2ff308 + } +} diff --git a/src/main/java/net/minecraft/world/inventory/BrewingStandMenu.java b/src/main/java/net/minecraft/world/inventory/BrewingStandMenu.java -index 68c529cb38d61cd3a0f39bef0f666057fc219c9b..6ec207e91f93b3ab625515dc75367ba399818876 100644 +index 182c87a0b7081f6a777c4c7969961c30438b0d86..3be46ecfa382e15d09a88912c498abb6034c3a90 100644 --- a/src/main/java/net/minecraft/world/inventory/BrewingStandMenu.java +++ b/src/main/java/net/minecraft/world/inventory/BrewingStandMenu.java -@@ -41,14 +41,14 @@ public class BrewingStandMenu extends AbstractContainerMenu { +@@ -42,14 +42,14 @@ public class BrewingStandMenu extends AbstractContainerMenu { // CraftBukkit end public BrewingStandMenu(int syncId, Inventory playerInventory) { @@ -44,7 +44,7 @@ index 68c529cb38d61cd3a0f39bef0f666057fc219c9b..6ec207e91f93b3ab625515dc75367ba3 this.brewingStand = inventory; this.brewingStandData = propertyDelegate; PotionBrewing potionbrewer = playerInventory.player.level().potionBrewing(); -@@ -60,7 +60,20 @@ public class BrewingStandMenu extends AbstractContainerMenu { +@@ -61,7 +61,20 @@ public class BrewingStandMenu extends AbstractContainerMenu { // Paper end - custom potion mixes this.ingredientSlot = this.addSlot(new BrewingStandMenu.IngredientsSlot(potionbrewer, inventory, 3, 79, 17)); this.addSlot(new BrewingStandMenu.FuelSlot(inventory, 4, 17, 17)); @@ -63,14 +63,14 @@ index 68c529cb38d61cd3a0f39bef0f666057fc219c9b..6ec207e91f93b3ab625515dc75367ba3 + } + }); + // Paper end - Add recipeBrewTime - - int j; + this.addStandardInventorySlots(playerInventory, 8, 84); + } diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java -index bf2c303a314205590a2839e0f729af3a9ff40a86..0a93bacd62249bae1800ff306b8a7c765b0e5a8b 100644 +index 4ea29e8f2b39d7b44e0461d6a2cdd3fc257abd44..02fc9ce21c7d367055da350d21be4870d4242f3a 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java -@@ -49,6 +49,7 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements +@@ -50,6 +50,7 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements public static final int NUM_DATA_VALUES = 2; private NonNullList items; public int brewTime; @@ -78,7 +78,7 @@ index bf2c303a314205590a2839e0f729af3a9ff40a86..0a93bacd62249bae1800ff306b8a7c76 private boolean[] lastPotionCount; private Item ingredient; public int fuel; -@@ -99,6 +100,11 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements +@@ -100,6 +101,11 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements case 1: j = BrewingStandBlockEntity.this.fuel; break; @@ -90,7 +90,7 @@ index bf2c303a314205590a2839e0f729af3a9ff40a86..0a93bacd62249bae1800ff306b8a7c76 default: j = 0; } -@@ -114,13 +120,18 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements +@@ -115,13 +121,18 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements break; case 1: BrewingStandBlockEntity.this.fuel = value; @@ -110,7 +110,7 @@ index bf2c303a314205590a2839e0f729af3a9ff40a86..0a93bacd62249bae1800ff306b8a7c76 } }; } -@@ -188,7 +199,8 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements +@@ -189,7 +200,8 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements // CraftBukkit start BrewingStartEvent event = new BrewingStartEvent(CraftBlock.at(world, pos), CraftItemStack.asCraftMirror(itemstack1), 400); world.getCraftServer().getPluginManager().callEvent(event); diff --git a/patches/unapplied/server/1062-Call-bucket-events-for-cauldrons.patch b/patches/server/1031-Call-bucket-events-for-cauldrons.patch similarity index 51% rename from patches/unapplied/server/1062-Call-bucket-events-for-cauldrons.patch rename to patches/server/1031-Call-bucket-events-for-cauldrons.patch index dfb8d7f8e255..ab192b82a43b 100644 --- a/patches/unapplied/server/1062-Call-bucket-events-for-cauldrons.patch +++ b/patches/server/1031-Call-bucket-events-for-cauldrons.patch @@ -5,24 +5,24 @@ Subject: [PATCH] Call bucket events for cauldrons diff --git a/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java b/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java -index f301c20e808b77cb3fcffd9a7c8102928306456e..b584cfe44fbb93d470ca56c091423833c4007d16 100644 +index df76185d42075834a39c79515917e03beb938a06..ee2c4c5265d96afe592c5007b0b6ad7649ce5190 100644 --- a/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java +++ b/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java -@@ -60,7 +60,7 @@ public interface CauldronInteraction { +@@ -53,7 +53,7 @@ public interface CauldronInteraction { static CauldronInteraction.InteractionMap newInteractionMap(String name) { Object2ObjectOpenHashMap object2objectopenhashmap = new Object2ObjectOpenHashMap(); - object2objectopenhashmap.defaultReturnValue((iblockdata, world, blockposition, entityhuman, enumhand, itemstack) -> { + object2objectopenhashmap.defaultReturnValue((iblockdata, world, blockposition, entityhuman, enumhand, itemstack, hitDirection) -> { // Paper - add hitDirection - return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + return InteractionResult.TRY_WITH_EMPTY_HAND; }); CauldronInteraction.InteractionMap cauldroninteraction_a = new CauldronInteraction.InteractionMap(name, object2objectopenhashmap); -@@ -69,13 +69,13 @@ public interface CauldronInteraction { +@@ -62,13 +62,13 @@ public interface CauldronInteraction { return cauldroninteraction_a; } -- ItemInteractionResult interact(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack); -+ ItemInteractionResult interact(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection); // Paper - add hitDirection +- InteractionResult interact(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack); ++ InteractionResult interact(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection); // Paper - add hitDirection static void bootStrap() { Map map = CauldronInteraction.EMPTY.map(); @@ -33,7 +33,7 @@ index f301c20e808b77cb3fcffd9a7c8102928306456e..b584cfe44fbb93d470ca56c091423833 PotionContents potioncontents = (PotionContents) itemstack.get(DataComponents.POTION_CONTENTS); if (potioncontents != null && potioncontents.is(Potions.WATER)) { -@@ -103,12 +103,12 @@ public interface CauldronInteraction { +@@ -96,12 +96,12 @@ public interface CauldronInteraction { Map map1 = CauldronInteraction.WATER.map(); CauldronInteraction.addDefaultInteractions(map1); @@ -49,17 +49,17 @@ index f301c20e808b77cb3fcffd9a7c8102928306456e..b584cfe44fbb93d470ca56c091423833 if (!world.isClientSide) { // CraftBukkit start if (!LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition, entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_FILL)) { -@@ -127,7 +127,7 @@ public interface CauldronInteraction { +@@ -120,7 +120,7 @@ public interface CauldronInteraction { - return ItemInteractionResult.sidedSuccess(world.isClientSide); + return InteractionResult.SUCCESS; }); - map1.put(Items.POTION, (iblockdata, world, blockposition, entityhuman, enumhand, itemstack) -> { + map1.put(Items.POTION, (iblockdata, world, blockposition, entityhuman, enumhand, itemstack, hitDirection) -> { // Paper - add hitDirection if ((Integer) iblockdata.getValue(LayeredCauldronBlock.LEVEL) == 3) { - return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + return InteractionResult.TRY_WITH_EMPTY_HAND; } else { -@@ -194,15 +194,15 @@ public interface CauldronInteraction { - map1.put(Items.YELLOW_SHULKER_BOX, CauldronInteraction.SHULKER_BOX); +@@ -187,18 +187,18 @@ public interface CauldronInteraction { + map1.put(Items.YELLOW_SHULKER_BOX, CauldronInteraction::shulkerBoxInteraction); Map map2 = CauldronInteraction.LAVA.map(); - map2.put(Items.BUCKET, (iblockdata, world, blockposition, entityhuman, enumhand, itemstack) -> { @@ -76,40 +76,44 @@ index f301c20e808b77cb3fcffd9a7c8102928306456e..b584cfe44fbb93d470ca56c091423833 + map3.put(Items.BUCKET, (iblockdata, world, blockposition, entityhuman, enumhand, itemstack, hitDirection) -> { // Paper - add hitDirection return CauldronInteraction.fillBucket(iblockdata, world, blockposition, entityhuman, enumhand, itemstack, new ItemStack(Items.POWDER_SNOW_BUCKET), (iblockdata1) -> { return (Integer) iblockdata1.getValue(LayeredCauldronBlock.LEVEL) == 3; - }, SoundEvents.BUCKET_FILL_POWDER_SNOW); -@@ -217,10 +217,24 @@ public interface CauldronInteraction { +- }, SoundEvents.BUCKET_FILL_POWDER_SNOW); ++ }, SoundEvents.BUCKET_FILL_POWDER_SNOW, hitDirection); // Paper - add hitDirection + }); + CauldronInteraction.addDefaultInteractions(map3); + } +@@ -210,10 +210,24 @@ public interface CauldronInteraction { } - static ItemInteractionResult fillBucket(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, ItemStack output, Predicate fullPredicate, SoundEvent soundEvent) { + static InteractionResult fillBucket(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, ItemStack output, Predicate fullPredicate, SoundEvent soundEvent) { + // Paper start - add hitDirection + return fillBucket(state, world, pos, player, hand, stack, output, fullPredicate, soundEvent, null); // Paper - add hitDirection + } -+ static ItemInteractionResult fillBucket(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, ItemStack output, Predicate fullPredicate, SoundEvent soundEvent, @javax.annotation.Nullable net.minecraft.core.Direction hitDirection) { ++ static InteractionResult fillBucket(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, ItemStack output, Predicate fullPredicate, SoundEvent soundEvent, @javax.annotation.Nullable net.minecraft.core.Direction hitDirection) { + // Paper end - add hitDirection if (!fullPredicate.test(state)) { - return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + return InteractionResult.TRY_WITH_EMPTY_HAND; } else { if (!world.isClientSide) { + // Paper start - fire PlayerBucketFillEvent + if (hitDirection != null) { + org.bukkit.event.player.PlayerBucketEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketFillEvent((net.minecraft.server.level.ServerLevel) world, player, pos, pos, hitDirection, stack, output.getItem(), hand); + if (event.isCancelled()) { -+ return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; ++ return InteractionResult.PASS; + } + output = event.getItemStack() != null ? org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItemStack()) : ItemStack.EMPTY; + } + // Paper end - fire PlayerBucketFillEvent // CraftBukkit start if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.CAULDRON.defaultBlockState(), player, CauldronLevelChangeEvent.ChangeReason.BUCKET_FILL, false)) { // Paper - Call CauldronLevelChangeEvent - return ItemInteractionResult.SUCCESS; -@@ -241,7 +255,22 @@ public interface CauldronInteraction { + return InteractionResult.SUCCESS; +@@ -234,7 +248,22 @@ public interface CauldronInteraction { } - static ItemInteractionResult emptyBucket(Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, BlockState state, SoundEvent soundEvent) { + static InteractionResult emptyBucket(Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, BlockState state, SoundEvent soundEvent) { + // Paper start - add hitDirection + return emptyBucket(world, pos, player, hand, stack, state, soundEvent, null); + } -+ static ItemInteractionResult emptyBucket(Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, BlockState state, SoundEvent soundEvent, @javax.annotation.Nullable net.minecraft.core.Direction hitDirection) { ++ static InteractionResult emptyBucket(Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, BlockState state, SoundEvent soundEvent, @javax.annotation.Nullable net.minecraft.core.Direction hitDirection) { + // Paper end - add hitDirection if (!world.isClientSide) { + // Paper start - fire PlayerBucketEmptyEvent @@ -117,15 +121,15 @@ index f301c20e808b77cb3fcffd9a7c8102928306456e..b584cfe44fbb93d470ca56c091423833 + if (hitDirection != null) { + org.bukkit.event.player.PlayerBucketEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketEmptyEvent((net.minecraft.server.level.ServerLevel) world, player, pos, pos, hitDirection, stack, hand); + if (event.isCancelled()) { -+ return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; ++ return InteractionResult.PASS; + } + output = event.getItemStack() != null ? org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItemStack()) : ItemStack.EMPTY; + } + // Paper end - fire PlayerBucketEmptyEvent // CraftBukkit start if (!LayeredCauldronBlock.changeLevel(state, world, pos, state, player, CauldronLevelChangeEvent.ChangeReason.BUCKET_EMPTY, false)) { // Paper - Call CauldronLevelChangeEvent - return ItemInteractionResult.SUCCESS; -@@ -249,7 +278,7 @@ public interface CauldronInteraction { + return InteractionResult.SUCCESS; +@@ -242,7 +271,7 @@ public interface CauldronInteraction { // CraftBukkit end Item item = stack.getItem(); @@ -134,54 +138,63 @@ index f301c20e808b77cb3fcffd9a7c8102928306456e..b584cfe44fbb93d470ca56c091423833 player.awardStat(Stats.FILL_CAULDRON); player.awardStat(Stats.ITEM_USED.get(item)); // world.setBlockAndUpdate(blockposition, iblockdata); // CraftBukkit -@@ -267,16 +296,16 @@ public interface CauldronInteraction { - CauldronInteraction.InteractionMap WATER = CauldronInteraction.newInteractionMap("water"); - CauldronInteraction.InteractionMap LAVA = CauldronInteraction.newInteractionMap("lava"); - CauldronInteraction.InteractionMap POWDER_SNOW = CauldronInteraction.newInteractionMap("powder_snow"); -- CauldronInteraction FILL_WATER = (iblockdata, world, blockposition, entityhuman, enumhand, itemstack) -> { -- return CauldronInteraction.emptyBucket(world, blockposition, entityhuman, enumhand, itemstack, (BlockState) Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, 3), SoundEvents.BUCKET_EMPTY); -+ CauldronInteraction FILL_WATER = (iblockdata, world, blockposition, entityhuman, enumhand, itemstack, hitDirection) -> { // Paper - add hitDirection -+ return CauldronInteraction.emptyBucket(world, blockposition, entityhuman, enumhand, itemstack, (BlockState) Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, 3), SoundEvents.BUCKET_EMPTY, hitDirection); // Paper - add hitDirection - }; -- CauldronInteraction FILL_LAVA = (iblockdata, world, blockposition, entityhuman, enumhand, itemstack) -> { -- return CauldronInteraction.emptyBucket(world, blockposition, entityhuman, enumhand, itemstack, Blocks.LAVA_CAULDRON.defaultBlockState(), SoundEvents.BUCKET_EMPTY_LAVA); -+ CauldronInteraction FILL_LAVA = (iblockdata, world, blockposition, entityhuman, enumhand, itemstack, hitDirection) -> { // Paper - add hitDirection -+ return CauldronInteraction.emptyBucket(world, blockposition, entityhuman, enumhand, itemstack, Blocks.LAVA_CAULDRON.defaultBlockState(), SoundEvents.BUCKET_EMPTY_LAVA, hitDirection); // Paper - add hitDirection - }; -- CauldronInteraction FILL_POWDER_SNOW = (iblockdata, world, blockposition, entityhuman, enumhand, itemstack) -> { -+ CauldronInteraction FILL_POWDER_SNOW = (iblockdata, world, blockposition, entityhuman, enumhand, itemstack, hitDirection) -> { // Paper - add hitDirection - return CauldronInteraction.emptyBucket(world, blockposition, entityhuman, enumhand, itemstack, (BlockState) Blocks.POWDER_SNOW_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, 3), SoundEvents.BUCKET_EMPTY_POWDER_SNOW); - }; -- CauldronInteraction SHULKER_BOX = (iblockdata, world, blockposition, entityhuman, enumhand, itemstack) -> { -+ CauldronInteraction SHULKER_BOX = (iblockdata, world, blockposition, entityhuman, enumhand, itemstack, hitDirection) -> { // Paper - add hitDirection - // CraftBukkit end - Block block = Block.byItem(itemstack.getItem()); +@@ -253,19 +282,19 @@ public interface CauldronInteraction { + return InteractionResult.SUCCESS; + } -@@ -299,7 +328,7 @@ public interface CauldronInteraction { - return ItemInteractionResult.sidedSuccess(world.isClientSide); - } - }; -- CauldronInteraction BANNER = (iblockdata, world, blockposition, entityhuman, enumhand, itemstack) -> { // CraftBukkit - decompile error -+ CauldronInteraction BANNER = (iblockdata, world, blockposition, entityhuman, enumhand, itemstack, hitDirection) -> { // CraftBukkit - decompile error // Paper - add hitDirection - BannerPatternLayers bannerpatternlayers = (BannerPatternLayers) itemstack.getOrDefault(DataComponents.BANNER_PATTERNS, BannerPatternLayers.EMPTY); - - if (bannerpatternlayers.layers().isEmpty()) { -@@ -322,7 +351,7 @@ public interface CauldronInteraction { - return ItemInteractionResult.sidedSuccess(world.isClientSide); +- private static InteractionResult fillWaterInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack) { +- return CauldronInteraction.emptyBucket(world, pos, player, hand, stack, (BlockState) Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, 3), SoundEvents.BUCKET_EMPTY); ++ private static InteractionResult fillWaterInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection) { // Paper - add hitDirection ++ return CauldronInteraction.emptyBucket(world, pos, player, hand, stack, (BlockState) Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, 3), SoundEvents.BUCKET_EMPTY, hitDirection); // Paper - add hitDirection + } + +- private static InteractionResult fillLavaInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack) { +- return (InteractionResult) (CauldronInteraction.isUnderWater(world, pos) ? InteractionResult.CONSUME : CauldronInteraction.emptyBucket(world, pos, player, hand, stack, Blocks.LAVA_CAULDRON.defaultBlockState(), SoundEvents.BUCKET_EMPTY_LAVA)); ++ private static InteractionResult fillLavaInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection) { // Paper - add hitDirection ++ return (InteractionResult) (CauldronInteraction.isUnderWater(world, pos) ? InteractionResult.CONSUME : CauldronInteraction.emptyBucket(world, pos, player, hand, stack, Blocks.LAVA_CAULDRON.defaultBlockState(), SoundEvents.BUCKET_EMPTY_LAVA, hitDirection)); // Paper - add hitDirection + } + +- private static InteractionResult fillPowderSnowInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack) { +- return (InteractionResult) (CauldronInteraction.isUnderWater(world, pos) ? InteractionResult.CONSUME : CauldronInteraction.emptyBucket(world, pos, player, hand, stack, (BlockState) Blocks.POWDER_SNOW_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, 3), SoundEvents.BUCKET_EMPTY_POWDER_SNOW)); ++ private static InteractionResult fillPowderSnowInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection) { // Paper - add hitDirection ++ return (InteractionResult) (CauldronInteraction.isUnderWater(world, pos) ? InteractionResult.CONSUME : CauldronInteraction.emptyBucket(world, pos, player, hand, stack, (BlockState) Blocks.POWDER_SNOW_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, 3), SoundEvents.BUCKET_EMPTY_POWDER_SNOW, hitDirection)); // Paper - add hitDirection + } + +- private static InteractionResult shulkerBoxInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack) { ++ private static InteractionResult shulkerBoxInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection) { // Paper - add hitDirection + Block block = Block.byItem(stack.getItem()); + + if (!(block instanceof ShulkerBoxBlock)) { +@@ -283,12 +312,11 @@ public interface CauldronInteraction { + player.awardStat(Stats.CLEAN_SHULKER_BOX); + // LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition); // CraftBukkit } - }; -- CauldronInteraction DYED_ITEM = (iblockdata, world, blockposition, entityhuman, enumhand, itemstack) -> { // CraftBukkit - decompile error -+ CauldronInteraction DYED_ITEM = (iblockdata, world, blockposition, entityhuman, enumhand, itemstack, hitDirection) -> { // CraftBukkit - decompile error // Paper - add hitDirection - if (!itemstack.is(ItemTags.DYEABLE)) { - return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; - } else if (!itemstack.has(DataComponents.DYED_COLOR)) { +- + return InteractionResult.SUCCESS; + } + } + +- private static InteractionResult bannerInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack) { ++ private static InteractionResult bannerInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection) { // Paper - add hitDirection + BannerPatternLayers bannerpatternlayers = (BannerPatternLayers) stack.getOrDefault(DataComponents.BANNER_PATTERNS, BannerPatternLayers.EMPTY); + + if (bannerpatternlayers.layers().isEmpty()) { +@@ -312,7 +340,7 @@ public interface CauldronInteraction { + } + } + +- private static InteractionResult dyedItemIteration(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack) { ++ private static InteractionResult dyedItemIteration(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, final net.minecraft.core.Direction hitDirection) { // Paper - add hitDirection + if (!stack.is(ItemTags.DYEABLE)) { + return InteractionResult.TRY_WITH_EMPTY_HAND; + } else if (!stack.has(DataComponents.DYED_COLOR)) { diff --git a/src/main/java/net/minecraft/world/level/block/AbstractCauldronBlock.java b/src/main/java/net/minecraft/world/level/block/AbstractCauldronBlock.java -index 20f2b575c8131621edea0e75fbf38a9fe20a36c4..4fdef6d7bcea0cf6b7d90324398af597660c80e3 100644 +index 173fc110217307e225b4951c92ab22a1bef48dd4..e00ab1ed8088a1970249313ed63e09070fc6192d 100644 --- a/src/main/java/net/minecraft/world/level/block/AbstractCauldronBlock.java +++ b/src/main/java/net/minecraft/world/level/block/AbstractCauldronBlock.java -@@ -58,7 +58,7 @@ public abstract class AbstractCauldronBlock extends Block { - ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit - ) { +@@ -56,7 +56,7 @@ public abstract class AbstractCauldronBlock extends Block { + @Override + protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { CauldronInteraction cauldronInteraction = this.interactions.map().get(stack.getItem()); - return cauldronInteraction.interact(state, world, pos, player, hand, stack); + return cauldronInteraction.interact(state, world, pos, player, hand, stack, hit.getDirection()); // Paper - pass hit direction diff --git a/patches/unapplied/server/1063-Add-PlayerInsertLecternBookEvent.patch b/patches/server/1032-Add-PlayerInsertLecternBookEvent.patch similarity index 92% rename from patches/unapplied/server/1063-Add-PlayerInsertLecternBookEvent.patch rename to patches/server/1032-Add-PlayerInsertLecternBookEvent.patch index c41a641e0189..e410ce7bc22c 100644 --- a/patches/unapplied/server/1063-Add-PlayerInsertLecternBookEvent.patch +++ b/patches/server/1032-Add-PlayerInsertLecternBookEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerInsertLecternBookEvent diff --git a/src/main/java/net/minecraft/world/level/block/LecternBlock.java b/src/main/java/net/minecraft/world/level/block/LecternBlock.java -index ebb79907391fe3128d3d16fbe9d8cb0b22bcc9f7..3a1e2f62b297f384cc0dcfb828e523a37c703d6f 100644 +index ec6ff0b192ae2f1586095519ad2472e76b2b5589..53f388dd0ba6b77fe49a584883e8c9d49d5a5fba 100644 --- a/src/main/java/net/minecraft/world/level/block/LecternBlock.java +++ b/src/main/java/net/minecraft/world/level/block/LecternBlock.java -@@ -157,7 +157,24 @@ public class LecternBlock extends BaseEntityBlock { +@@ -158,7 +158,24 @@ public class LecternBlock extends BaseEntityBlock { BlockEntity tileentity = world.getBlockEntity(pos); if (tileentity instanceof LecternBlockEntity tileentitylectern) { diff --git a/patches/unapplied/server/1064-Void-damage-configuration-API.patch b/patches/server/1033-Void-damage-configuration-API.patch similarity index 79% rename from patches/unapplied/server/1064-Void-damage-configuration-API.patch rename to patches/server/1033-Void-damage-configuration-API.patch index 73205dffa304..7724fc578605 100644 --- a/patches/unapplied/server/1064-Void-damage-configuration-API.patch +++ b/patches/server/1033-Void-damage-configuration-API.patch @@ -5,26 +5,25 @@ Subject: [PATCH] Void damage configuration API diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index bc45c74987974b4828201e06fc8b1f3fbc0af8b4..4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd 100644 +index 4f0ff0d333d2de1b4f6beac1ce25e214b971e387..2cf9490a116d70c00f00d41005b78d5b510f2162 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -931,8 +931,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -853,8 +853,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public void checkBelowWorld() { + if (!this.level.getWorld().isVoidDamageEnabled()) return; // Paper - check if void damage is enabled on the world -+ // Paper start - Configurable nether ceiling damage -- if (this.getY() < (double) (this.level.getMinBuildHeight() - 64) || (this.level.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER -+ if (this.getY() < (double) (this.level.getMinBuildHeight() + this.level.getWorld().getVoidDamageMinBuildHeightOffset()) || (this.level.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER // Paper - use configured min build height offset +- if (this.getY() < (double) (this.level.getMinY() - 64) || (this.level.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER ++ if (this.getY() < (double) (this.level.getMinY() + this.level.getWorld().getVoidDamageMinBuildHeightOffset()) || (this.level.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER // Paper - use configured min build height offset && this.level.paperConfig().environment.netherCeilingVoidDamageHeight.test(v -> this.getY() >= v) && (!(this instanceof Player player) || !player.getAbilities().invulnerable))) { // Paper end - Configurable nether ceiling damage diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 30f4f1254fc295442d72d50479e8af635f2fe983..2aa6374cd4a96efd85899be8cd3172a8257bfe6b 100644 +index f57c830a7286eb8cab1061c8ddebe6abab1fcced..ed624f54bbd7f9fd5a1ddc12a856f41f03571ac9 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2625,7 +2625,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2702,7 +2702,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @Override protected void onBelowWorld() { @@ -34,10 +33,10 @@ index 30f4f1254fc295442d72d50479e8af635f2fe983..2aa6374cd4a96efd85899be8cd3172a8 protected void updateSwingTime() { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 38b046da5acac8633db8618a2957187d291f5e73..33e4818ba5a90d78d69baad9f6b1be1b1382e9f3 100644 +index 36c3024c188197a777c8077704e1b64552c02d0a..38565ee35799bc8cdf3f224e0f92592a4a11300f 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -163,6 +163,41 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -167,6 +167,41 @@ public class CraftWorld extends CraftRegionAccessor implements World { private final Object2IntOpenHashMap spawnCategoryLimit = new Object2IntOpenHashMap<>(); private final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(CraftWorld.DATA_TYPE_REGISTRY); private net.kyori.adventure.pointer.Pointers adventure$pointers; // Paper - implement pointers @@ -79,7 +78,7 @@ index 38b046da5acac8633db8618a2957187d291f5e73..33e4818ba5a90d78d69baad9f6b1be1b // Paper start - Provide fast information methods @Override -@@ -271,6 +306,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -275,6 +310,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { } } // Paper end - per world spawn limits diff --git a/patches/unapplied/server/1065-Add-Offline-PDC-API.patch b/patches/server/1034-Add-Offline-PDC-API.patch similarity index 100% rename from patches/unapplied/server/1065-Add-Offline-PDC-API.patch rename to patches/server/1034-Add-Offline-PDC-API.patch diff --git a/patches/unapplied/server/1066-Add-AnvilView-bypassEnchantmentLevelRestriction.patch b/patches/server/1035-Add-AnvilView-bypassEnchantmentLevelRestriction.patch similarity index 92% rename from patches/unapplied/server/1066-Add-AnvilView-bypassEnchantmentLevelRestriction.patch rename to patches/server/1035-Add-AnvilView-bypassEnchantmentLevelRestriction.patch index 67f7503c242e..f8c089a57c12 100644 --- a/patches/unapplied/server/1066-Add-AnvilView-bypassEnchantmentLevelRestriction.patch +++ b/patches/server/1035-Add-AnvilView-bypassEnchantmentLevelRestriction.patch @@ -8,10 +8,10 @@ maximum level. The added API enables plugins to disable this behaviour, allowing enchantments that are overleveled to be applied via the anvil. diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java -index d685511104ac552dfc9ae2111e1bfb60fa812102..362278407679f245ebcea778f2199b357339e1fe 100644 +index cc5aae32f34305965847ade8b530272b1126b5c9..dc2bc53f6fa84fa09bd86450060ad9878307001c 100644 --- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java -@@ -53,6 +53,7 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -54,6 +54,7 @@ public class AnvilMenu extends ItemCombinerMenu { public int maximumRepairCost = 40; private CraftAnvilView bukkitEntity; // CraftBukkit end @@ -19,7 +19,7 @@ index d685511104ac552dfc9ae2111e1bfb60fa812102..362278407679f245ebcea778f2199b35 public AnvilMenu(int syncId, Inventory inventory) { this(syncId, inventory, ContainerLevelAccess.NULL); -@@ -231,7 +232,7 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -233,7 +234,7 @@ public class AnvilMenu extends ItemCombinerMenu { flag2 = true; } else { flag1 = true; diff --git a/patches/unapplied/server/1067-Add-proper-async-player-disconnections.patch b/patches/server/1036-Add-proper-async-player-disconnections.patch similarity index 85% rename from patches/unapplied/server/1067-Add-proper-async-player-disconnections.patch rename to patches/server/1036-Add-proper-async-player-disconnections.patch index a1280f87988f..9522b5a4cbcd 100644 --- a/patches/unapplied/server/1067-Add-proper-async-player-disconnections.patch +++ b/patches/server/1036-Add-proper-async-player-disconnections.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add proper async player disconnections Blocking can cause performance problems diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java -index 3e550f8e7cd4f4e16f499a8a2a4b95420270f07a..4a8356a714ed50d4a32bcf046a2e16491bef014b 100644 +index 90a2c61c42cba7e38f167eccdd7a951a947963c4..fff8d15d44613a075b9793c2a41520212166eb3b 100644 --- a/src/main/java/net/minecraft/network/Connection.java +++ b/src/main/java/net/minecraft/network/Connection.java -@@ -850,6 +850,14 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -844,6 +844,14 @@ public class Connection extends SimpleChannelInboundHandler> { } @@ -25,10 +25,10 @@ index 3e550f8e7cd4f4e16f499a8a2a4b95420270f07a..4a8356a714ed50d4a32bcf046a2e1649 if (compressionThreshold >= 0) { com.velocitypowered.natives.compression.VelocityCompressor compressor = com.velocitypowered.natives.util.Natives.compress.get().create(io.papermc.paper.configuration.GlobalConfiguration.get().misc.compressionLevel.or(-1)); // Paper - Use Velocity cipher diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 6998f32f8d79dbdb6b31ffaa126602fc4a428616..7174f8c89a7cdcf40ff28f6636ecfb23b13ccdaa 100644 +index fc242acade3ff06c9213428cde103cf078216382..b0bc66dc7248aae691dcab68b925b52a1695e63f 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -136,11 +136,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -143,11 +143,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack this.latency = (this.latency * 3 + i) / 4; this.keepAlivePending = false; } else if (!this.isSingleplayerOwner()) { @@ -41,7 +41,7 @@ index 6998f32f8d79dbdb6b31ffaa126602fc4a428616..7174f8c89a7cdcf40ff28f6636ecfb23 } } -@@ -404,6 +400,31 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -411,6 +407,31 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack minecraftserver.scheduleOnMain(networkmanager::handleDisconnection); // Paper } @@ -74,19 +74,19 @@ index 6998f32f8d79dbdb6b31ffaa126602fc4a428616..7174f8c89a7cdcf40ff28f6636ecfb23 return this.server.isSingleplayerOwner(this.playerProfile()); } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index befeaac4786760f6847a5945da2296a3e68dbb17..064d52d4479727c6a32bf357be8da32d1760e7fc 100644 +index cae9682df8795c5f73e86c27d717b6f72e7e8592..bffbf87a546cf8b5ffc0a58d853bacd5d7759abf 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -791,7 +791,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -769,7 +769,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async // CraftBukkit start - if (this.chatSpamTickCount.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamLimit && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { // Paper - configurable tab spam limits + if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - configurable tab spam limits - this.disconnect(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - Kick event cause + this.disconnectAsync(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - Kick event cause // Paper - add proper async disconnect return; } // CraftBukkit end -@@ -803,7 +803,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -781,7 +781,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Paper start final int index; if (packet.getCommand().length() > 64 && ((index = packet.getCommand().indexOf(' ')) == -1 || index >= 64)) { @@ -95,7 +95,7 @@ index befeaac4786760f6847a5945da2296a3e68dbb17..064d52d4479727c6a32bf357be8da32d return; } // Paper end -@@ -1190,14 +1190,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1171,14 +1171,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (byteTotal > byteAllowed) { ServerGamePacketListenerImpl.LOGGER.warn("{} tried to send a book too large. Book size: {} - Allowed: {} - Pages: {}", this.player.getScoreboardName(), byteTotal, byteAllowed, pageList.size()); @@ -112,7 +112,7 @@ index befeaac4786760f6847a5945da2296a3e68dbb17..064d52d4479727c6a32bf357be8da32d return; } this.lastBookTick = MinecraftServer.currentTick; -@@ -2354,7 +2354,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2304,7 +2304,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private void tryHandleChat(String s, Runnable runnable, boolean sync) { // CraftBukkit if (ServerGamePacketListenerImpl.isChatMessageIllegal(s)) { @@ -121,7 +121,7 @@ index befeaac4786760f6847a5945da2296a3e68dbb17..064d52d4479727c6a32bf357be8da32d } else if (this.player.isRemoved() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) { // CraftBukkit - dead men tell no tales this.send(new ClientboundSystemChatPacket(Component.translatable("chat.disabled.options").withStyle(ChatFormatting.RED), false)); } else { -@@ -2377,7 +2377,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2327,7 +2327,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (optional.isEmpty()) { ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString()); @@ -130,16 +130,16 @@ index befeaac4786760f6847a5945da2296a3e68dbb17..064d52d4479727c6a32bf357be8da32d } return optional; -@@ -2550,7 +2550,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - // this.chatSpamTickCount += 20; - if (counted && this.chatSpamTickCount.addAndGet(20) > 200 && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - exclude from SpigotConfig.spamExclusions +@@ -2498,7 +2498,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + // this.chatSpamThrottler.increment(); + if (counted && !this.chatSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - exclude from SpigotConfig.spamExclusions // CraftBukkit end - this.disconnect((Component) Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause + this.disconnectAsync((Component) Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause // Paper - add proper async disconnect } } -@@ -2562,7 +2562,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2510,7 +2510,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl synchronized (this.lastSeenMessages) { if (!this.lastSeenMessages.applyOffset(packet.offset())) { ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString()); @@ -148,7 +148,7 @@ index befeaac4786760f6847a5945da2296a3e68dbb17..064d52d4479727c6a32bf357be8da32d } } -@@ -2710,7 +2710,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2658,7 +2658,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } if (i > 4096) { @@ -157,10 +157,10 @@ index befeaac4786760f6847a5945da2296a3e68dbb17..064d52d4479727c6a32bf357be8da32d } } -@@ -3314,7 +3314,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3267,7 +3267,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Paper start - auto recipe limit if (!org.bukkit.Bukkit.isPrimaryThread()) { - if (this.recipeSpamPackets.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamLimit) { + if (!this.recipeSpamPackets.isIncrementAndUnderThreshold()) { - this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause + this.disconnectAsync(net.minecraft.network.chat.Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause // Paper - add proper async disconnect return; diff --git a/patches/unapplied/server/1068-Always-send-Banner-patterns-to-the-client.patch b/patches/server/1037-Always-send-Banner-patterns-to-the-client.patch similarity index 83% rename from patches/unapplied/server/1068-Always-send-Banner-patterns-to-the-client.patch rename to patches/server/1037-Always-send-Banner-patterns-to-the-client.patch index 8672bed6d386..a5951afc90da 100644 --- a/patches/unapplied/server/1068-Always-send-Banner-patterns-to-the-client.patch +++ b/patches/server/1037-Always-send-Banner-patterns-to-the-client.patch @@ -9,16 +9,16 @@ flow for them, this is not all too surprising. So, we shall resort to always sending the patterns over the network for update packets. diff --git a/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java -index 60c26076e7acf869fa0e20fdc14eeec341387d99..60a9f3c7f007d268f24a4fe9e87029fdbc8360f9 100644 +index 98bc87fe5d153cc4927f7e1b4a02f61d9dd019a0..9528935a120f7d5a1fdb1a796854478e8a83f833 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java @@ -63,7 +63,7 @@ public class BannerBlockEntity extends BlockEntity implements Nameable { @Override - protected void saveAdditional(CompoundTag nbt, HolderLookup.Provider registryLookup) { - super.saveAdditional(nbt, registryLookup); + protected void saveAdditional(CompoundTag nbt, HolderLookup.Provider registries) { + super.saveAdditional(nbt, registries); - if (!this.patterns.equals(BannerPatternLayers.EMPTY)) { + if (!this.patterns.equals(BannerPatternLayers.EMPTY) || serialisingForNetwork.get()) { // Paper - always send patterns to client - nbt.put("patterns", (Tag) BannerPatternLayers.CODEC.encodeStart(registryLookup.createSerializationContext(NbtOps.INSTANCE), this.patterns).getOrThrow()); + nbt.put("patterns", (Tag) BannerPatternLayers.CODEC.encodeStart(registries.createSerializationContext(NbtOps.INSTANCE), this.patterns).getOrThrow()); } @@ -95,9 +95,18 @@ public class BannerBlockEntity extends BlockEntity implements Nameable { @@ -28,12 +28,11 @@ index 60c26076e7acf869fa0e20fdc14eeec341387d99..60a9f3c7f007d268f24a4fe9e87029fd + // Paper start - always send patterns to client + ThreadLocal serialisingForNetwork = ThreadLocal.withInitial(() -> Boolean.FALSE); @Override - public CompoundTag getUpdateTag(HolderLookup.Provider registryLookup) { -- return this.saveWithoutMetadata(registryLookup); + public CompoundTag getUpdateTag(HolderLookup.Provider registries) { + final Boolean wasSerialisingForNetwork = serialisingForNetwork.get(); + try { + serialisingForNetwork.set(Boolean.TRUE); -+ return this.saveWithoutMetadata(registryLookup); + return this.saveWithoutMetadata(registries); + } finally { + serialisingForNetwork.set(wasSerialisingForNetwork); + } From b06e0b0317fcb28084239d27218fc569e829f12a Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Fri, 25 Oct 2024 12:30:19 +0200 Subject: [PATCH 050/119] Work on compile errors --- patches/server/0002-Remap-fixes.patch | 13 +++++++++ patches/server/0009-MC-Utils.patch | 4 +-- patches/server/0023-Timings-v2.patch | 16 +++------- ...4-PlayerNaturallySpawnCreaturesEvent.patch | 4 +-- ...interactions-from-causing-chunk-load.patch | 4 +-- ...e-getChunkAt-calls-for-loaded-chunks.patch | 2 +- .../0310-Add-debug-for-sync-chunk-loads.patch | 2 +- ...-entity-collision-code-if-not-needed.patch | 4 +-- ...PlayerAttackEntityCooldownResetEvent.patch | 2 +- ...item-duplication-and-teleport-issues.patch | 6 ++-- ...-position-and-AABB-are-never-invalid.patch | 2 +- ...k-for-portal-on-world-gen-entity-add.patch | 2 +- ...ortation-and-cancel-velocity-if-tele.patch | 2 +- ...y-Counter-to-allow-plugins-to-use-va.patch | 2 +- patches/server/0410-Entity-isTicking.patch | 2 +- ...-should-not-bypass-cramming-gamerule.patch | 4 +-- .../0446-MC-4-Fix-item-position-desync.patch | 2 +- ...et-Material-from-Boats-and-Minecarts.patch | 2 +- ...n-for-requiring-a-player-participant.patch | 2 +- .../0477-Expand-EntityUnleashEvent.patch | 2 +- patches/server/0480-Add-EntityMoveEvent.patch | 2 +- ...ItemConsumeEvent-cancelling-properly.patch | 2 +- .../server/0548-Line-Of-Sight-Changes.patch | 2 +- ...ptimize-indirect-passenger-iteration.patch | 2 +- .../0578-Add-back-EntityPortalExitEvent.patch | 2 +- ...89-Add-Raw-Byte-Entity-Serialization.patch | 2 +- ...0593-Improve-and-expand-AsyncCatcher.patch | 2 +- ...id-state-when-raytracing-skip-air-bl.patch | 4 +-- ...date-head-rotation-in-missing-places.patch | 2 +- ...-unintended-light-block-manipulation.patch | 18 +++++++++--- ...-t-attempt-to-teleport-dead-entities.patch | 2 +- ...sive-velocity-through-repeated-crits.patch | 2 +- ...ward-CraftEntity-in-teleport-command.patch | 2 +- .../server/0651-Freeze-Tick-Lock-API.patch | 4 +-- ...efault-CustomSpawners-in-custom-worl.patch | 4 +-- ...o-worldlist-before-initing-the-world.patch | 2 +- patches/server/0665-Custom-Potion-Mixes.patch | 2 +- ...ables-running-when-mob-loot-gamerule.patch | 4 +-- ...assenger-world-matches-ridden-entity.patch | 2 +- .../0694-Add-PlayerStopUsingItemEvent.patch | 2 +- ...entity-loading-causing-async-lookups.patch | 2 +- ...n-on-world-create-while-being-ticked.patch | 2 +- ...-strict-advancement-dimension-checks.patch | 2 +- ...us-missing-EntityDropItemEvent-calls.patch | 6 ++-- patches/server/0717-More-Teleport-API.patch | 29 ++++++++++--------- ...stom-Chat-Completion-Suggestions-API.patch | 2 +- ...ix-plugin-loggers-on-server-shutdown.patch | 2 +- ...ook-changes-from-crashing-the-server.patch | 2 +- ...6-Add-PlayerInventorySlotChangeEvent.patch | 2 +- .../0747-Elder-Guardian-appearance-API.patch | 4 +-- ...tEvent-cancellation-cant-fully-preve.patch | 2 +- .../0759-Add-Player-Warden-Warning-API.patch | 4 +-- ...global-player-list-where-appropriate.patch | 2 +- patches/server/0765-Friction-API.patch | 2 +- ...x-premature-player-kicks-on-shutdown.patch | 2 +- .../0768-Sync-offhand-slot-in-menus.patch | 2 +- .../0769-Player-Entity-Tracking-Events.patch | 2 +- patches/server/0771-fix-Instruments.patch | 2 +- .../server/0776-Improve-PortalEvents.patch | 4 +-- patches/server/0780-Flying-Fall-Damage.patch | 4 +-- ...sion-moving-velocity-to-VehicleBlock.patch | 2 +- ...nk-items-during-EntityResurrectEvent.patch | 2 +- patches/server/0785-Win-Screen-API.patch | 2 +- ...vancement-triggers-for-entity-damage.patch | 2 +- .../0810-Expand-PlayerItemMendEvent.patch | 4 +-- ...esh-ProjectileSource-for-projectiles.patch | 2 +- ...d-chunks-for-supporting-block-checks.patch | 2 +- patches/server/0829-Fix-BanList-API.patch | 6 ++-- ...Folia-scheduler-and-owned-region-API.patch | 4 +-- .../server/0847-Bandaid-fix-for-Effect.patch | 2 +- .../0855-Add-Listing-API-for-Player.patch | 6 ++-- .../0858-Fix-NPE-on-Boat-getStatus.patch | 2 +- patches/server/0859-Expand-Pose-API.patch | 2 +- ...-Implement-OfflinePlayer-isConnected.patch | 2 +- patches/server/0866-Fix-slot-desync.patch | 4 +-- ...-titleOverride-to-InventoryOpenEvent.patch | 2 +- ...ix-missing-map-initialize-event-call.patch | 25 +++++++++------- .../0885-Add-player-idle-duration-API.patch | 4 +-- ...stack-for-Player-sendEquipmentChange.patch | 2 +- ...predicate-for-blocks-when-raytracing.patch | 4 +-- ...tem-packets-with-collector-as-source.patch | 2 +- ...n-t-fire-sync-events-during-worldgen.patch | 6 ++-- ...estore-vanilla-entity-drops-behavior.patch | 10 +++---- ...-on-null-loc-for-EntityTeleportEvent.patch | 2 +- .../0908-Add-experience-points-API.patch | 4 +-- ...date-ResourceLocation-in-NBT-reading.patch | 2 +- ...26-Add-BlockBreakProgressUpdateEvent.patch | 2 +- ...ing-message-for-initial-server-start.patch | 2 +- ...1-Configurable-max-block-fluid-ticks.patch | 2 +- .../server/0935-Fix-DamageSource-API.patch | 2 +- ...946-Fix-shield-disable-inconsistency.patch | 2 +- ...a-handling-of-LivingEntity-actuallyH.patch | 2 +- ...d-API-to-get-player-ha-proxy-address.patch | 2 +- .../0957-Brigadier-based-command-API.patch | 2 +- ...oversized-item-data-in-equipment-and.patch | 2 +- ...amage-tick-when-blocking-with-shield.patch | 2 +- ...973-disable-forced-empty-world-ticks.patch | 2 +- ...item-frames-performance-and-bug-fixe.patch | 8 ++--- .../0979-Entity-Activation-Range-2.0.patch | 4 +-- patches/server/0980-Anti-Xray.patch | 2 +- ...ptimize-Collision-to-not-load-chunks.patch | 2 +- patches/server/0984-Optimize-Hoppers.patch | 2 +- ...heck-distance-in-entity-interactions.patch | 2 +- .../0993-Properly-resend-entities.patch | 4 +-- ...tityDamageEvents-before-actuallyHurt.patch | 2 +- patches/server/1012-Leashable-API.patch | 2 +- ...-Fix-InventoryOpenEvent-cancellation.patch | 2 +- .../1020-Check-dead-flag-in-isAlive.patch | 2 +- .../server/1022-Tag-Lifecycle-Events.patch | 2 +- .../1029-Improve-entity-effect-API.patch | 4 +-- .../1033-Void-damage-configuration-API.patch | 4 +-- 111 files changed, 207 insertions(+), 186 deletions(-) diff --git a/patches/server/0002-Remap-fixes.patch b/patches/server/0002-Remap-fixes.patch index 50ea8b2aa780..d7cff4215bd5 100644 --- a/patches/server/0002-Remap-fixes.patch +++ b/patches/server/0002-Remap-fixes.patch @@ -73,6 +73,19 @@ index f3a2612f0e27c36d5206334307eac1880ce8c4b7..4d4d413b8527e1a109276928611b8c85 private ContextKeySet paramSet; private Optional randomSequence; +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java +index eaa46bf5954ed7c2be6d4b3772b5f2e971505c78..c101d01b55472efc9fc2829b8c17db5377ed57ff 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java +@@ -133,7 +133,7 @@ public abstract class CraftBoat extends CraftVehicle implements Boat { + throw new EnumConstantNotPresentException(Type.class, boatType.toString()); + } + +- public static Status boatStatusFromNms(net.minecraft.world.entity.vehicle.Boat.EnumStatus enumStatus) { ++ public static Status boatStatusFromNms(net.minecraft.world.entity.vehicle.AbstractBoat.Status enumStatus) { // Paper - remap fixes + return switch (enumStatus) { + default -> throw new EnumConstantNotPresentException(Status.class, enumStatus.name()); + case IN_AIR -> Status.IN_AIR; diff --git a/src/test/java/org/bukkit/DyeColorsTest.java b/src/test/java/org/bukkit/DyeColorsTest.java index e96d821da0698dd42651500fb97a0856a9e9ce02..fb7d40181abdaa5b2ce607db47c09d0d0a19c86d 100644 --- a/src/test/java/org/bukkit/DyeColorsTest.java diff --git a/patches/server/0009-MC-Utils.patch b/patches/server/0009-MC-Utils.patch index 4b120d89b8d9..d98cff699198 100644 --- a/patches/server/0009-MC-Utils.patch +++ b/patches/server/0009-MC-Utils.patch @@ -4980,7 +4980,7 @@ index 23a611c9a83d1cea5ab2f64cdbd696c39872477d..bf660a057d135563b47e7b74d927a82a GameProfileCache usercache = this.server.getProfileCache(); // Optional optional; // CraftBukkit - decompile error diff --git a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java -index ae25aec117a7272735c824a00c1ed117fa52a921..f877bc637fef7f446b328381316f1431b3a5dee8 100644 +index ae25aec117a7272735c824a00c1ed117fa52a921..d6e942aca1bcc769c390504a4119d6619872c4d4 100644 --- a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java +++ b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java @@ -82,6 +82,13 @@ public abstract class BlockableEventLoop implements Profiler @@ -4991,7 +4991,7 @@ index ae25aec117a7272735c824a00c1ed117fa52a921..f877bc637fef7f446b328381316f1431 + public void scheduleOnMain(Runnable runnable) { + // postToMainThread does not work the same as older versions of mc + // This method is actually used to create a TickTask, which can then be posted onto main -+ this.tell(this.wrapRunnable(runnable)); ++ this.schedule(this.wrapRunnable(runnable)); + } + // Paper end diff --git a/patches/server/0023-Timings-v2.patch b/patches/server/0023-Timings-v2.patch index 19ddd183bbc6..5cb8445793f6 100644 --- a/patches/server/0023-Timings-v2.patch +++ b/patches/server/0023-Timings-v2.patch @@ -1032,7 +1032,7 @@ index 88e98f49565a098debcea8d58368e53d7623f6b5..84ea1974445fc7be80ed474d8a2133b5 } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index c615510f3f59292715bcff1bd9e4e896c9733436..a29598ae54d5d20740a105f81bcaec2a152fe4ba 100644 +index c615510f3f59292715bcff1bd9e4e896c9733436..93422468474189343cdc1e29f06f6dfb12e4760a 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -207,13 +207,15 @@ public class ServerChunkCache extends ChunkSource { @@ -1076,15 +1076,7 @@ index c615510f3f59292715bcff1bd9e4e896c9733436..a29598ae54d5d20740a105f81bcaec2a } this.level.timings.doChunkUnload.startTiming(); // Spigot -@@ -442,6 +446,7 @@ public class ServerChunkCache extends ChunkSource { - gameprofilerfiller.pop(); - this.clearCache(); - } -+ if (this.level.getServer().tickRateManager().runsNormally()) this.level.timings.chunkTicks.startTiming(); // Paper - - private void tickChunks() { - long i = this.level.getGameTime(); -@@ -481,7 +486,9 @@ public class ServerChunkCache extends ChunkSource { +@@ -481,7 +485,9 @@ public class ServerChunkCache extends ChunkSource { LevelChunk chunk = playerchunk.getTickingChunk(); if (chunk != null) { @@ -1094,7 +1086,7 @@ index c615510f3f59292715bcff1bd9e4e896c9733436..a29598ae54d5d20740a105f81bcaec2a } } -@@ -502,8 +509,10 @@ public class ServerChunkCache extends ChunkSource { +@@ -502,8 +508,10 @@ public class ServerChunkCache extends ChunkSource { private void tickChunks(ProfilerFiller profiler, long timeDelta, List chunks) { profiler.popPush("naturalSpawnCount"); @@ -1105,7 +1097,7 @@ index c615510f3f59292715bcff1bd9e4e896c9733436..a29598ae54d5d20740a105f81bcaec2a this.lastSpawnState = spawnercreature_d; profiler.popPush("spawnAndTick"); -@@ -531,15 +540,17 @@ public class ServerChunkCache extends ChunkSource { +@@ -531,15 +539,17 @@ public class ServerChunkCache extends ChunkSource { } if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { diff --git a/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch b/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch index a6fcccab1af7..1c3173436b98 100644 --- a/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch +++ b/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch @@ -40,10 +40,10 @@ index 84ea1974445fc7be80ed474d8a2133b58ee4c8fe..aa3155bb57c09895d13914b46c77de78 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 a29598ae54d5d20740a105f81bcaec2a152fe4ba..3bbc7aa52a2ee797d6033684e73d6b307c2fadcc 100644 +index 93422468474189343cdc1e29f06f6dfb12e4760a..fef86453d5cf0fe0f11a2a061169cd301b777434 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -521,6 +521,15 @@ public class ServerChunkCache extends ChunkSource { +@@ -520,6 +520,15 @@ public class ServerChunkCache extends ChunkSource { List list1; if (flag && (this.spawnEnemies || this.spawnFriendlies)) { diff --git a/patches/server/0244-Prevent-various-interactions-from-causing-chunk-load.patch b/patches/server/0244-Prevent-various-interactions-from-causing-chunk-load.patch index b7f9185ebb14..a2789a6dfadf 100644 --- a/patches/server/0244-Prevent-various-interactions-from-causing-chunk-load.patch +++ b/patches/server/0244-Prevent-various-interactions-from-causing-chunk-load.patch @@ -77,7 +77,7 @@ index c02a2f9e1b4e727b1deeb73377e1f7193f5ee072..cdd1f6939ce33e62f6609f7eb3a5dff5 : new LodestoneTracker(Optional.empty(), true); } diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java -index 6850ac324ee4d202f112dbd057ea1bde9de17ea9..8e58efd0d8010a3499a1eb1add9fa976aa2b0a3e 100644 +index 6850ac324ee4d202f112dbd057ea1bde9de17ea9..f39ccc0d2a4eea4e1e0b15608780c7c4a749e672 100644 --- a/src/main/java/net/minecraft/world/level/BlockGetter.java +++ b/src/main/java/net/minecraft/world/level/BlockGetter.java @@ -71,7 +71,15 @@ public interface BlockGetter extends LevelHeightAccessor { @@ -91,7 +91,7 @@ index 6850ac324ee4d202f112dbd057ea1bde9de17ea9..8e58efd0d8010a3499a1eb1add9fa976 + // copied the last function parameter (listed below) + Vec3 vec3d = raytrace1.getFrom().subtract(raytrace1.getTo()); + -+ return BlockHitResult.miss(raytrace1.getTo(), Direction.getNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(raytrace1.getTo())); ++ return BlockHitResult.miss(raytrace1.getTo(), Direction.getApproximateNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(raytrace1.getTo())); + } + // Paper end - Prevent raytrace from loading chunks FluidState fluid = this.getFluidState(blockposition); diff --git a/patches/server/0309-Optimise-getChunkAt-calls-for-loaded-chunks.patch b/patches/server/0309-Optimise-getChunkAt-calls-for-loaded-chunks.patch index 8a7a3106660d..32dde0f0e464 100644 --- a/patches/server/0309-Optimise-getChunkAt-calls-for-loaded-chunks.patch +++ b/patches/server/0309-Optimise-getChunkAt-calls-for-loaded-chunks.patch @@ -7,7 +7,7 @@ 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 3bbc7aa52a2ee797d6033684e73d6b307c2fadcc..4302d5119c43eb8de0c026162fc62ddeb5ab87cb 100644 +index fef86453d5cf0fe0f11a2a061169cd301b777434..9ab43b4273975d7599f8eee2f95773f2984b7c37 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -191,6 +191,12 @@ public class ServerChunkCache extends ChunkSource { diff --git a/patches/server/0310-Add-debug-for-sync-chunk-loads.patch b/patches/server/0310-Add-debug-for-sync-chunk-loads.patch index 73dc4103ebbe..a27b5deba212 100644 --- a/patches/server/0310-Add-debug-for-sync-chunk-loads.patch +++ b/patches/server/0310-Add-debug-for-sync-chunk-loads.patch @@ -302,7 +302,7 @@ index 0000000000000000000000000000000000000000..95d6022c9cfb2e36ec5a71be6e343540 + } +} diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 4302d5119c43eb8de0c026162fc62ddeb5ab87cb..7e5714fea4cda68b9ae21031c0e0d39061b07e2f 100644 +index 9ab43b4273975d7599f8eee2f95773f2984b7c37..350bfa9c891130b1aa2ab973e86668de187ee1e0 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -218,6 +218,7 @@ public class ServerChunkCache extends ChunkSource { diff --git a/patches/server/0336-Don-t-run-entity-collision-code-if-not-needed.patch b/patches/server/0336-Don-t-run-entity-collision-code-if-not-needed.patch index 43b1d500a9d4..e0919bb4b1e3 100644 --- a/patches/server/0336-Don-t-run-entity-collision-code-if-not-needed.patch +++ b/patches/server/0336-Don-t-run-entity-collision-code-if-not-needed.patch @@ -12,7 +12,7 @@ The entity's current team collision rule causes them to NEVER collide. Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 304a401fb1f378ff2cbfd888acf56a8516f79310..6ff464fef1f79cff9212135a30adcc6cb8792ed6 100644 +index 304a401fb1f378ff2cbfd888acf56a8516f79310..ecf188d659c8542ca2b52c5e7ec779bfacb5614c 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -3683,10 +3683,24 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -28,7 +28,7 @@ index 304a401fb1f378ff2cbfd888acf56a8516f79310..6ff464fef1f79cff9212135a30adcc6c + return; + } + -+ int i = this.level().getGameRules().getInt(GameRules.RULE_MAX_ENTITY_CRAMMING); ++ int i = worldserver.getGameRules().getInt(GameRules.RULE_MAX_ENTITY_CRAMMING); + if (i <= 0 && this.level().paperConfig().collisions.maxEntityCollisions <= 0) { + return; + } diff --git a/patches/server/0341-Add-PlayerAttackEntityCooldownResetEvent.patch b/patches/server/0341-Add-PlayerAttackEntityCooldownResetEvent.patch index 72ccb53f47da..ce70659c9038 100644 --- a/patches/server/0341-Add-PlayerAttackEntityCooldownResetEvent.patch +++ b/patches/server/0341-Add-PlayerAttackEntityCooldownResetEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerAttackEntityCooldownResetEvent diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 6ff464fef1f79cff9212135a30adcc6cb8792ed6..68e5f6f7013d6a014b9014d945cf3f7dc7a37cb2 100644 +index ecf188d659c8542ca2b52c5e7ec779bfacb5614c..324d654420c3d11f0695fdf029fde0300a865317 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -2354,7 +2354,17 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0344-Fix-item-duplication-and-teleport-issues.patch b/patches/server/0344-Fix-item-duplication-and-teleport-issues.patch index 2b42b0e70c22..128a755a9584 100644 --- a/patches/server/0344-Fix-item-duplication-and-teleport-issues.patch +++ b/patches/server/0344-Fix-item-duplication-and-teleport-issues.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 5b8e264098f1b713de15f714bae59d3efda365cf..4faba83eb73e0d313e9131794962b727f7628a50 100644 +index 5b8e264098f1b713de15f714bae59d3efda365cf..6f1e09087cf2d8dbb61882473b220100e3b0369a 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2630,11 +2630,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -39,7 +39,7 @@ index 5b8e264098f1b713de15f714bae59d3efda365cf..4faba83eb73e0d313e9131794962b727 + // Paper start - Fix item duplication and teleport issues + if (!this.isAlive() || !this.valid) { -+ LOGGER.warn("Illegal Entity Teleport " + this + " to " + teleportTarget.newLevel() + ":" + teleportTarget.pos(), new Throwable()); ++ LOGGER.warn("Illegal Entity Teleport " + this + " to " + teleportTarget.newLevel() + ":" + teleportTarget.position(), new Throwable()); + return null; + } + // Paper end - Fix item duplication and teleport issues @@ -67,7 +67,7 @@ index 5b8e264098f1b713de15f714bae59d3efda365cf..4faba83eb73e0d313e9131794962b727 Iterator iterator = this.getPassengers().iterator(); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 68e5f6f7013d6a014b9014d945cf3f7dc7a37cb2..65909e0a8f8b68f9a4dacefda9069c8263a96ada 100644 +index 324d654420c3d11f0695fdf029fde0300a865317..f7323f54b2ac7236d26da8998a88432f9776e1ea 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -1767,9 +1767,9 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0369-Ensure-Entity-position-and-AABB-are-never-invalid.patch b/patches/server/0369-Ensure-Entity-position-and-AABB-are-never-invalid.patch index 75a8ed8bfea8..acac658b4dff 100644 --- a/patches/server/0369-Ensure-Entity-position-and-AABB-are-never-invalid.patch +++ b/patches/server/0369-Ensure-Entity-position-and-AABB-are-never-invalid.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Ensure Entity position and AABB are never invalid Co-authored-by: Spottedleaf diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 4faba83eb73e0d313e9131794962b727f7628a50..7fdfe1dd09812df1d8d7e5f95bcaf1b48c814e22 100644 +index 6f1e09087cf2d8dbb61882473b220100e3b0369a..a3e096525f89b7b66efa7987f9744618074ca38a 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -677,8 +677,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0380-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch b/patches/server/0380-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch index e97a181c5326..de62fde367cc 100644 --- a/patches/server/0380-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch +++ b/patches/server/0380-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Don't check chunk for portal on world gen entity add diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 65909e0a8f8b68f9a4dacefda9069c8263a96ada..91a5166e69a03d846a1b396ba964003c12a0dcdb 100644 +index f7323f54b2ac7236d26da8998a88432f9776e1ea..e0ccdbcdbc33d378ebe41e3741137b15ff9fd80a 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -3798,7 +3798,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch b/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch index a05ecacdceaa..6b069e9a8cd8 100644 --- a/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch +++ b/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch @@ -22,7 +22,7 @@ index 49039d929681891beb76b8c7f6e6d8bb614a7bf0..b634a90e87f52c79b74c256c13b659b5 this.lastGoodY = this.awaitingPositionFromClient.y; this.lastGoodZ = this.awaitingPositionFromClient.z; diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 7fdfe1dd09812df1d8d7e5f95bcaf1b48c814e22..f8fd729d53248c7598a118d89fedf340f82cdd61 100644 +index a3e096525f89b7b66efa7987f9744618074ca38a..9e4483d31330dfe82fd794c9cfb8d2aa318a39ea 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -179,6 +179,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0408-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch b/patches/server/0408-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch index 2b99da73b968..3dec9f876b2f 100644 --- a/patches/server/0408-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch +++ b/patches/server/0408-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Expose the Entity Counter to allow plugins to use valid and diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index f8fd729d53248c7598a118d89fedf340f82cdd61..ac1b2b3982e5ceb8fecf20867dd2ac6e143463c3 100644 +index 9e4483d31330dfe82fd794c9cfb8d2aa318a39ea..b55ca652e0828bc34848ad4f1ebb9001832550dc 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -4704,4 +4704,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0410-Entity-isTicking.patch b/patches/server/0410-Entity-isTicking.patch index e90c16901da5..d4311d3a19b8 100644 --- a/patches/server/0410-Entity-isTicking.patch +++ b/patches/server/0410-Entity-isTicking.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Entity#isTicking diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index ac1b2b3982e5ceb8fecf20867dd2ac6e143463c3..0bd608894ab596c773570f92b4662aee5a6934cc 100644 +index b55ca652e0828bc34848ad4f1ebb9001832550dc..8cb02a0aeab64e0333c61aa3b30685ad1a169c48 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -4709,5 +4709,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0435-Climbing-should-not-bypass-cramming-gamerule.patch b/patches/server/0435-Climbing-should-not-bypass-cramming-gamerule.patch index e27625ee8ef0..23a3982b7353 100644 --- a/patches/server/0435-Climbing-should-not-bypass-cramming-gamerule.patch +++ b/patches/server/0435-Climbing-should-not-bypass-cramming-gamerule.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Climbing should not bypass cramming gamerule diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 0bd608894ab596c773570f92b4662aee5a6934cc..25f625e28c8c9f63a1b2207d5e8d1a48e2fea039 100644 +index 8cb02a0aeab64e0333c61aa3b30685ad1a169c48..2e9a836f16eace80b010d5a0421901f7a1af8622 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2195,6 +2195,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -44,7 +44,7 @@ index b8d57e25851dd7da905100dfd4022e4b99fd7f02..721321a19ce056f82de2bef44a8791dc } else if (entity1 instanceof Player && entity instanceof Player && !io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions) { // Paper - Configurable player collision return false; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 91a5166e69a03d846a1b396ba964003c12a0dcdb..7ea58478d3cde175a056f41cf945636a04128828 100644 +index e0ccdbcdbc33d378ebe41e3741137b15ff9fd80a..5a551e24be8d4d8157adb0f20f8e7bd3c5c61854 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -3712,7 +3712,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0446-MC-4-Fix-item-position-desync.patch b/patches/server/0446-MC-4-Fix-item-position-desync.patch index 26cf19c2b634..93bbd49bf563 100644 --- a/patches/server/0446-MC-4-Fix-item-position-desync.patch +++ b/patches/server/0446-MC-4-Fix-item-position-desync.patch @@ -28,7 +28,7 @@ index 488ebd443903af812913437f1ade3002093f2470..a043ac10834562d357ef0b5aded2e916 public Vec3 decode(long x, long y, long z) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 25f625e28c8c9f63a1b2207d5e8d1a48e2fea039..ad34a525f54a157140323a26752a420a8e348a55 100644 +index 2e9a836f16eace80b010d5a0421901f7a1af8622..be547b0ef3b91da97fbc270cc00d922ba9c5896e 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -4449,6 +4449,16 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0448-API-to-get-Material-from-Boats-and-Minecarts.patch b/patches/server/0448-API-to-get-Material-from-Boats-and-Minecarts.patch index 8462025bf835..1b80594eba1f 100644 --- a/patches/server/0448-API-to-get-Material-from-Boats-and-Minecarts.patch +++ b/patches/server/0448-API-to-get-Material-from-Boats-and-Minecarts.patch @@ -5,7 +5,7 @@ Subject: [PATCH] API to get Material from Boats and Minecarts diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java -index eaa46bf5954ed7c2be6d4b3772b5f2e971505c78..5de1ada561d11c247a597effab1e0aa363b7c90f 100644 +index c101d01b55472efc9fc2829b8c17db5377ed57ff..5d51a49228eaee94f91cd04843e27c7918ca8796 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java @@ -78,6 +78,13 @@ public abstract class CraftBoat extends CraftVehicle implements Boat { diff --git a/patches/server/0469-Collision-option-for-requiring-a-player-participant.patch b/patches/server/0469-Collision-option-for-requiring-a-player-participant.patch index a1b916f2ada2..251c412a50b9 100644 --- a/patches/server/0469-Collision-option-for-requiring-a-player-participant.patch +++ b/patches/server/0469-Collision-option-for-requiring-a-player-participant.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Collision option for requiring a player participant diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index ad34a525f54a157140323a26752a420a8e348a55..1d2f0f8756addf0db7356b47ea8a1eddd2c4503d 100644 +index be547b0ef3b91da97fbc270cc00d922ba9c5896e..07aff05e2e8cd36ebb6b9fb9d2f19b95c5f9bfc4 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2024,6 +2024,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0477-Expand-EntityUnleashEvent.patch b/patches/server/0477-Expand-EntityUnleashEvent.patch index 88cfdc582eb1..8d23e8ce8587 100644 --- a/patches/server/0477-Expand-EntityUnleashEvent.patch +++ b/patches/server/0477-Expand-EntityUnleashEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Expand EntityUnleashEvent diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 1d2f0f8756addf0db7356b47ea8a1eddd2c4503d..42004784a5421bd27d0a4a2bf1c17d14341fc5a4 100644 +index 07aff05e2e8cd36ebb6b9fb9d2f19b95c5f9bfc4..bb2cfec32b63d3786f9ec255d4beef7065245cae 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2689,12 +2689,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0480-Add-EntityMoveEvent.patch b/patches/server/0480-Add-EntityMoveEvent.patch index 7eb0eacb2e9d..bc7d0f0ad209 100644 --- a/patches/server/0480-Add-EntityMoveEvent.patch +++ b/patches/server/0480-Add-EntityMoveEvent.patch @@ -29,7 +29,7 @@ index d62d6a345837e1b63c1a1393f18e367ac0ef4c30..b91ed08e8d9fbd399834d19ef01ebe56 public LevelChunk getChunkIfLoaded(int x, int z) { return this.chunkSource.getChunk(x, z, false); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 7ea58478d3cde175a056f41cf945636a04128828..293490d124bc06c4a06b9f4a7f77a9c25a8d7d39 100644 +index 5a551e24be8d4d8157adb0f20f8e7bd3c5c61854..8bb10bcc26577ff7b806fbcc48c3d71b241c5963 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -3628,6 +3628,20 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0503-Fix-PlayerItemConsumeEvent-cancelling-properly.patch b/patches/server/0503-Fix-PlayerItemConsumeEvent-cancelling-properly.patch index a1da72f4992e..fc40a810f14d 100644 --- a/patches/server/0503-Fix-PlayerItemConsumeEvent-cancelling-properly.patch +++ b/patches/server/0503-Fix-PlayerItemConsumeEvent-cancelling-properly.patch @@ -9,7 +9,7 @@ till their item is switched. This patch clears the active item when the event is cancelled diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 293490d124bc06c4a06b9f4a7f77a9c25a8d7d39..b7cc3d84c724772e3e1250c5e99bb32e01112220 100644 +index 8bb10bcc26577ff7b806fbcc48c3d71b241c5963..9829419d3531ed6af55e37ac253903975c648a3e 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -4136,6 +4136,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0548-Line-Of-Sight-Changes.patch b/patches/server/0548-Line-Of-Sight-Changes.patch index 2b40552d3f89..d8a956a3092b 100644 --- a/patches/server/0548-Line-Of-Sight-Changes.patch +++ b/patches/server/0548-Line-Of-Sight-Changes.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Line Of Sight Changes diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index b7cc3d84c724772e3e1250c5e99bb32e01112220..eeed7d1d4b7fee0e8ab1f43f9b7ec6f74a01330d 100644 +index 9829419d3531ed6af55e37ac253903975c648a3e..1cb118c12e1b09cb6ae8d3b6949212b46c91b85b 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -3907,7 +3907,8 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0571-Optimize-indirect-passenger-iteration.patch b/patches/server/0571-Optimize-indirect-passenger-iteration.patch index 3d3851641848..ea5798ac84d3 100644 --- a/patches/server/0571-Optimize-indirect-passenger-iteration.patch +++ b/patches/server/0571-Optimize-indirect-passenger-iteration.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Optimize indirect passenger iteration diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 42004784a5421bd27d0a4a2bf1c17d14341fc5a4..ea1492559653063bb14b934f4d40d910b81d8801 100644 +index bb2cfec32b63d3786f9ec255d4beef7065245cae..674df993333ddee13415a4379b81dadc68489af7 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -4087,20 +4087,34 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0578-Add-back-EntityPortalExitEvent.patch b/patches/server/0578-Add-back-EntityPortalExitEvent.patch index 6c0fdf2ce99b..c739f7010ebc 100644 --- a/patches/server/0578-Add-back-EntityPortalExitEvent.patch +++ b/patches/server/0578-Add-back-EntityPortalExitEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add back EntityPortalExitEvent diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index ea1492559653063bb14b934f4d40d910b81d8801..0fd652a60bf9bedda903b734f4fd39153a9c418c 100644 +index 674df993333ddee13415a4379b81dadc68489af7..cb6a167ed778073be9f9e1f2eb27b46547b0a3ce 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -3491,7 +3491,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch b/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch index 34f5031fb4df..75c80fef00f6 100644 --- a/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch +++ b/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Add Raw Byte Entity Serialization public net.minecraft.world.entity.Entity setLevel(Lnet/minecraft/world/level/Level;)V diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 0fd652a60bf9bedda903b734f4fd39153a9c418c..92c743a354e95c8e12fc21673ee172aed07fe1fb 100644 +index cb6a167ed778073be9f9e1f2eb27b46547b0a3ce..3bac521f0be372198c8b83d514f3d14a041b76cd 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2260,6 +2260,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0593-Improve-and-expand-AsyncCatcher.patch b/patches/server/0593-Improve-and-expand-AsyncCatcher.patch index 3a42eb978d43..c51af8278f2a 100644 --- a/patches/server/0593-Improve-and-expand-AsyncCatcher.patch +++ b/patches/server/0593-Improve-and-expand-AsyncCatcher.patch @@ -29,7 +29,7 @@ index ea793f9ccf3082a7abcb003b9df03901f9b4c0f0..8084bf547a52f3e5c890d2be3757acb3 if (player.isRemoved()) { LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName()); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index eeed7d1d4b7fee0e8ab1f43f9b7ec6f74a01330d..f7e14d9668c74e20bc327b05cf84c8203e4e590b 100644 +index 1cb118c12e1b09cb6ae8d3b6949212b46c91b85b..21f9fc5c3111dc126d0197a02bb61541fc422933 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -1145,7 +1145,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0600-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch b/patches/server/0600-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch index 96945dc00175..e01f02928a72 100644 --- a/patches/server/0600-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch +++ b/patches/server/0600-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch @@ -11,11 +11,11 @@ easy win. The remaining problems with this function are mostly with the block getting itself. diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java -index 8e58efd0d8010a3499a1eb1add9fa976aa2b0a3e..cc9ae2122b563d7b583c7335d0a8ce227f9b1af4 100644 +index f39ccc0d2a4eea4e1e0b15608780c7c4a749e672..7e1a332168357b9af14dbe3299549c2c93903fa6 100644 --- a/src/main/java/net/minecraft/world/level/BlockGetter.java +++ b/src/main/java/net/minecraft/world/level/BlockGetter.java @@ -80,7 +80,8 @@ public interface BlockGetter extends LevelHeightAccessor { - return BlockHitResult.miss(raytrace1.getTo(), Direction.getNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(raytrace1.getTo())); + return BlockHitResult.miss(raytrace1.getTo(), Direction.getApproximateNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(raytrace1.getTo())); } // Paper end - Prevent raytrace from loading chunks - FluidState fluid = this.getFluidState(blockposition); diff --git a/patches/server/0616-Update-head-rotation-in-missing-places.patch b/patches/server/0616-Update-head-rotation-in-missing-places.patch index 190dc41a6dab..379a0515459e 100644 --- a/patches/server/0616-Update-head-rotation-in-missing-places.patch +++ b/patches/server/0616-Update-head-rotation-in-missing-places.patch @@ -8,7 +8,7 @@ This is because bukkit uses a separate head rotation field for yaw. This issue only applies to players. diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 92c743a354e95c8e12fc21673ee172aed07fe1fb..b54dcebbd5d2f920efcf91ff2de485493dd2f487 100644 +index 3bac521f0be372198c8b83d514f3d14a041b76cd..366c3165783d3856d9f47f0dd4a594016d9f41ed 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -1914,6 +1914,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0617-prevent-unintended-light-block-manipulation.patch b/patches/server/0617-prevent-unintended-light-block-manipulation.patch index 824f2a8ab9b2..12d564474a9c 100644 --- a/patches/server/0617-prevent-unintended-light-block-manipulation.patch +++ b/patches/server/0617-prevent-unintended-light-block-manipulation.patch @@ -5,17 +5,27 @@ Subject: [PATCH] prevent unintended light block manipulation diff --git a/src/main/java/net/minecraft/world/level/block/LightBlock.java b/src/main/java/net/minecraft/world/level/block/LightBlock.java -index 6c3ca57a29d3c5ad1add1cf2f707b930dfc422ea..71a1a152dca41ba9100bd38efd6758a42bab9f5d 100644 +index 6c3ca57a29d3c5ad1add1cf2f707b930dfc422ea..606c9b03cc69031faed33f437ca254f12224bb62 100644 --- a/src/main/java/net/minecraft/world/level/block/LightBlock.java +++ b/src/main/java/net/minecraft/world/level/block/LightBlock.java -@@ -50,6 +50,14 @@ public class LightBlock extends Block implements SimpleWaterloggedBlock { +@@ -5,7 +5,9 @@ import java.util.function.ToIntFunction; + import net.minecraft.core.BlockPos; + import net.minecraft.core.Direction; + import net.minecraft.core.component.DataComponents; ++import net.minecraft.server.level.ServerLevel; + import net.minecraft.util.RandomSource; ++import net.minecraft.world.InteractionHand; + import net.minecraft.world.InteractionResult; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.item.ItemStack; +@@ -50,6 +52,14 @@ public class LightBlock extends Block implements SimpleWaterloggedBlock { builder.add(LEVEL, WATERLOGGED); } + // Paper start - prevent unintended light block manipulation + @Override -+ protected net.minecraft.world.ItemInteractionResult useItemOn(final ItemStack stack, final BlockState state, final Level world, final BlockPos pos, final Player player, final net.minecraft.world.InteractionHand hand, final BlockHitResult hit) { -+ if (player.getItemInHand(hand).getItem() != Items.LIGHT || !player.mayInteract(world, pos) || !player.mayUseItemAt(pos, hit.getDirection(), player.getItemInHand(hand))) { return net.minecraft.world.ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION; } // Paper - Prevent unintended light block manipulation ++ protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { ++ if (player.getItemInHand(hand).getItem() != Items.LIGHT || (world instanceof final ServerLevel serverLevel && !player.mayInteract(serverLevel, pos)) || !player.mayUseItemAt(pos, hit.getDirection(), player.getItemInHand(hand))) { return net.minecraft.world.InteractionResult.PASS; } // Paper - Prevent unintended light block manipulation + return super.useItemOn(stack, state, world, pos, player, hand, hit); + } + // Paper end - prevent unintended light block manipulation diff --git a/patches/server/0622-don-t-attempt-to-teleport-dead-entities.patch b/patches/server/0622-don-t-attempt-to-teleport-dead-entities.patch index 667b51a9572e..cefb2c7fc0f0 100644 --- a/patches/server/0622-don-t-attempt-to-teleport-dead-entities.patch +++ b/patches/server/0622-don-t-attempt-to-teleport-dead-entities.patch @@ -5,7 +5,7 @@ Subject: [PATCH] don't attempt to teleport dead entities diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index b54dcebbd5d2f920efcf91ff2de485493dd2f487..e311601d8e39e7ea632bc4805260da6d7d6d6776 100644 +index 366c3165783d3856d9f47f0dd4a594016d9f41ed..8b5dc4b3ddb89fcc286c432400e3bc94b8787e4c 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -713,7 +713,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0623-Prevent-excessive-velocity-through-repeated-crits.patch b/patches/server/0623-Prevent-excessive-velocity-through-repeated-crits.patch index 8c7b52d7c5f9..9db70149e677 100644 --- a/patches/server/0623-Prevent-excessive-velocity-through-repeated-crits.patch +++ b/patches/server/0623-Prevent-excessive-velocity-through-repeated-crits.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Prevent excessive velocity through repeated crits diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index f7e14d9668c74e20bc327b05cf84c8203e4e590b..4db8ac288e59c5f14b260686e55a7d48e2f2791d 100644 +index 21f9fc5c3111dc126d0197a02bb61541fc422933..8c7ffa884f64a4263c9399953a7cfca6e35aab61 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -2865,17 +2865,29 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0632-Forward-CraftEntity-in-teleport-command.patch b/patches/server/0632-Forward-CraftEntity-in-teleport-command.patch index b03dbe2831f4..1af3ec979c6b 100644 --- a/patches/server/0632-Forward-CraftEntity-in-teleport-command.patch +++ b/patches/server/0632-Forward-CraftEntity-in-teleport-command.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Forward CraftEntity in teleport command diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index e311601d8e39e7ea632bc4805260da6d7d6d6776..1497c3b79e6dc9ecc270c0fd2003e606f967a56e 100644 +index 8b5dc4b3ddb89fcc286c432400e3bc94b8787e4c..ef923b1cdbe6276d6dc9776bd9e5a508bd021fc0 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -3480,6 +3480,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0651-Freeze-Tick-Lock-API.patch b/patches/server/0651-Freeze-Tick-Lock-API.patch index f97861797746..76a992877a6b 100644 --- a/patches/server/0651-Freeze-Tick-Lock-API.patch +++ b/patches/server/0651-Freeze-Tick-Lock-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Freeze Tick Lock API diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 1497c3b79e6dc9ecc270c0fd2003e606f967a56e..a41bb1d80a84f487a8fb6fdefd7ccc7631902d04 100644 +index ef923b1cdbe6276d6dc9776bd9e5a508bd021fc0..681295efe26a75af61d9ac311e002dfb26ffd8c6 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -414,6 +414,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -46,7 +46,7 @@ index 1497c3b79e6dc9ecc270c0fd2003e606f967a56e..a41bb1d80a84f487a8fb6fdefd7ccc76 } catch (Throwable throwable) { diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 4db8ac288e59c5f14b260686e55a7d48e2f2791d..6598f119edc5d890dcc9d065478e7c52ac5a5183 100644 +index 8c7ffa884f64a4263c9399953a7cfca6e35aab61..0aa7291b3c28c58767fed5f9f01e381b671b5d27 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -3611,7 +3611,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0663-Option-to-have-default-CustomSpawners-in-custom-worl.patch b/patches/server/0663-Option-to-have-default-CustomSpawners-in-custom-worl.patch index 94613610ac6c..45ef22616527 100644 --- a/patches/server/0663-Option-to-have-default-CustomSpawners-in-custom-worl.patch +++ b/patches/server/0663-Option-to-have-default-CustomSpawners-in-custom-worl.patch @@ -10,7 +10,7 @@ just looking at the LevelStem key, look at the DimensionType key which is one level below that. Defaults to off to keep vanilla behavior. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index af392711da61a1921be1f82396c2a04dc897d563..7841421f00a3408e52b8d060674e6a686681210e 100644 +index af392711da61a1921be1f82396c2a04dc897d563..2a92a8a4896a1ce27b3f6e8c5b965c1efb70127e 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -647,7 +647,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop spawners; -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.useDimensionTypeForCustomSpawners && this.registryAccess().registryOrThrow(Registries.DIMENSION_TYPE).getResourceKey(worlddimension.type().value()).orElseThrow() == net.minecraft.world.level.dimension.BuiltinDimensionTypes.OVERWORLD) { ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.useDimensionTypeForCustomSpawners && this.registryAccess().lookupOrThrow(Registries.DIMENSION_TYPE).getResourceKey(worlddimension.type().value()).orElseThrow() == net.minecraft.world.level.dimension.BuiltinDimensionTypes.OVERWORLD) { + spawners = list; + } else { + spawners = Collections.emptyList(); diff --git a/patches/server/0664-Put-world-into-worldlist-before-initing-the-world.patch b/patches/server/0664-Put-world-into-worldlist-before-initing-the-world.patch index b1cada34702a..1dfaf980a23f 100644 --- a/patches/server/0664-Put-world-into-worldlist-before-initing-the-world.patch +++ b/patches/server/0664-Put-world-into-worldlist-before-initing-the-world.patch @@ -7,7 +7,7 @@ Some parts of legacy conversion will need the overworld to get the legacy structure data storage diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 7841421f00a3408e52b8d060674e6a686681210e..cc162b2046c7d39d9a85bcb69fc45e53d15fe5ef 100644 +index 2a92a8a4896a1ce27b3f6e8c5b965c1efb70127e..6567f23cecae8ffc82d14ff34f054182443ce5fb 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -659,9 +659,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0); this.dropCustomDeathLoot(this.serverLevel(), damageSource, flag); diff --git a/patches/server/0681-Ensure-entity-passenger-world-matches-ridden-entity.patch b/patches/server/0681-Ensure-entity-passenger-world-matches-ridden-entity.patch index 941971cf97a6..6a4d8ee24859 100644 --- a/patches/server/0681-Ensure-entity-passenger-world-matches-ridden-entity.patch +++ b/patches/server/0681-Ensure-entity-passenger-world-matches-ridden-entity.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Ensure entity passenger world matches ridden entity Bad plugins doing this would cause some obvious problems... diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index a41bb1d80a84f487a8fb6fdefd7ccc7631902d04..325c8b178dfb39727107190e74663113ebb4ab54 100644 +index 681295efe26a75af61d9ac311e002dfb26ffd8c6..e1da49ec70f03940ce7c0fa23bcbc5cfb2494fc6 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2802,7 +2802,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0694-Add-PlayerStopUsingItemEvent.patch b/patches/server/0694-Add-PlayerStopUsingItemEvent.patch index fb3326f4c0a3..c7cab9712fee 100644 --- a/patches/server/0694-Add-PlayerStopUsingItemEvent.patch +++ b/patches/server/0694-Add-PlayerStopUsingItemEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerStopUsingItemEvent diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 6598f119edc5d890dcc9d065478e7c52ac5a5183..682d0399b9b3729d16978eca258c55c2150afec7 100644 +index 0aa7291b3c28c58767fed5f9f01e381b671b5d27..d41c0f1aa501cbe17c88029bafbe034901f6d562 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -4204,6 +4204,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0702-Prevent-entity-loading-causing-async-lookups.patch b/patches/server/0702-Prevent-entity-loading-causing-async-lookups.patch index 342f805e0345..ee2ca735fdee 100644 --- a/patches/server/0702-Prevent-entity-loading-causing-async-lookups.patch +++ b/patches/server/0702-Prevent-entity-loading-causing-async-lookups.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Prevent entity loading causing async lookups diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 325c8b178dfb39727107190e74663113ebb4ab54..71efd269ea055f13e3ca898bad045448e24f73da 100644 +index e1da49ec70f03940ce7c0fa23bcbc5cfb2494fc6..37111113f6ab6d77c558b10c4162758135db99b0 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -724,6 +724,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0703-Throw-exception-on-world-create-while-being-ticked.patch b/patches/server/0703-Throw-exception-on-world-create-while-being-ticked.patch index 1661a4705fc7..a447e15d32f5 100644 --- a/patches/server/0703-Throw-exception-on-world-create-while-being-ticked.patch +++ b/patches/server/0703-Throw-exception-on-world-create-while-being-ticked.patch @@ -7,7 +7,7 @@ There are no plans to support creating worlds while worlds are being ticked themselvess. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 0b9f4541cc0d0f27e811c1a6798d6758a2687b0c..2101c0a3b000a60733ceada248c202e2c4783af5 100644 +index 9765951d0ed653ca5b4ae4903887ec7ef25cb50a..8030baa8ef189a17502da9c51baace0b7369137b 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -328,6 +328,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop net.minecraft.world.entity.RelativeMovement.X; -+ case Y -> net.minecraft.world.entity.RelativeMovement.Y; -+ case Z -> net.minecraft.world.entity.RelativeMovement.Z; -+ case PITCH -> net.minecraft.world.entity.RelativeMovement.X_ROT; -+ case YAW -> net.minecraft.world.entity.RelativeMovement.Y_ROT; ++ case X -> net.minecraft.world.entity.Relative.X; ++ case Y -> net.minecraft.world.entity.Relative.Y; ++ case Z -> net.minecraft.world.entity.Relative.Z; ++ case PITCH -> net.minecraft.world.entity.Relative.X_ROT; ++ case YAW -> net.minecraft.world.entity.Relative.Y_ROT; + }; + } + -+ public static io.papermc.paper.entity.TeleportFlag.Relative toApiRelativeFlag(net.minecraft.world.entity.RelativeMovement nmsFlag) { ++ public static io.papermc.paper.entity.TeleportFlag.Relative toApiRelativeFlag(net.minecraft.world.entity.Relative nmsFlag) { + return switch (nmsFlag) { + case X -> io.papermc.paper.entity.TeleportFlag.Relative.X; + case Y -> io.papermc.paper.entity.TeleportFlag.Relative.Y; + case Z -> io.papermc.paper.entity.TeleportFlag.Relative.Z; + case X_ROT -> io.papermc.paper.entity.TeleportFlag.Relative.PITCH; + case Y_ROT -> io.papermc.paper.entity.TeleportFlag.Relative.YAW; ++ default -> throw new RuntimeException("not yet"); // TODO figure out what to do with new flags + }; + } + @@ -218,7 +219,7 @@ index 0bb2a75b2dd3d6d5d7815d3f4b1d8b11b002db62..d2029d88a4d9b060e199431ae092ce87 location.checkFinite(); ServerPlayer entity = this.getHandle(); -@@ -1322,7 +1410,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1322,7 +1411,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return false; } @@ -227,7 +228,7 @@ index 0bb2a75b2dd3d6d5d7815d3f4b1d8b11b002db62..d2029d88a4d9b060e199431ae092ce87 return false; } -@@ -1331,7 +1419,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1331,7 +1420,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // To = Players new Location if Teleport is Successful Location to = location; // Create & Call the Teleport Event. @@ -236,7 +237,7 @@ index 0bb2a75b2dd3d6d5d7815d3f4b1d8b11b002db62..d2029d88a4d9b060e199431ae092ce87 this.server.getPluginManager().callEvent(event); // Return False to inform the Plugin that the Teleport was unsuccessful/cancelled. -@@ -1340,7 +1428,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1340,7 +1429,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // If this player is riding another entity, we must dismount before teleporting. @@ -245,7 +246,7 @@ index 0bb2a75b2dd3d6d5d7815d3f4b1d8b11b002db62..d2029d88a4d9b060e199431ae092ce87 // SPIGOT-5509: Wakeup, similar to riding if (this.isSleeping()) { -@@ -1356,13 +1444,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1356,13 +1445,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { ServerLevel toWorld = ((CraftWorld) to.getWorld()).getHandle(); // Close any foreign inventory @@ -258,7 +259,7 @@ index 0bb2a75b2dd3d6d5d7815d3f4b1d8b11b002db62..d2029d88a4d9b060e199431ae092ce87 if (fromWorld == toWorld) { - entity.connection.teleport(to); + // Paper start - Teleport API -+ final Set nms = java.util.EnumSet.noneOf(net.minecraft.world.entity.RelativeMovement.class); ++ final Set nms = java.util.EnumSet.noneOf(net.minecraft.world.entity.Relative.class); + for (final io.papermc.paper.entity.TeleportFlag.Relative bukkit : relativeArguments) { + nms.add(toNmsRelativeFlag(bukkit)); + } diff --git a/patches/server/0722-Custom-Chat-Completion-Suggestions-API.patch b/patches/server/0722-Custom-Chat-Completion-Suggestions-API.patch index f1b41f3210f9..7a419b3d744e 100644 --- a/patches/server/0722-Custom-Chat-Completion-Suggestions-API.patch +++ b/patches/server/0722-Custom-Chat-Completion-Suggestions-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Custom Chat Completion Suggestions API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index d2029d88a4d9b060e199431ae092ce87ad5a09de..7fd3cb7c69aa212449739f5733de661af662611f 100644 +index 2514fbae7c87a96c12e44d21ff7df1d2f3243387..dc360a7a8a8d23be9d8301a5e6fbff5499c9a947 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -708,6 +708,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0729-Fix-plugin-loggers-on-server-shutdown.patch b/patches/server/0729-Fix-plugin-loggers-on-server-shutdown.patch index 6c058f039b4b..2256a7261eec 100644 --- a/patches/server/0729-Fix-plugin-loggers-on-server-shutdown.patch +++ b/patches/server/0729-Fix-plugin-loggers-on-server-shutdown.patch @@ -37,7 +37,7 @@ index 0000000000000000000000000000000000000000..c1d3bac79bb8b4796c013ff4472f75dc + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 2101c0a3b000a60733ceada248c202e2c4783af5..027d94dd08e7789b51c8779c65d4ddad4e62f21a 100644 +index 8030baa8ef189a17502da9c51baace0b7369137b..7d7e1848e7074a0ec94fe924e328f15cb247c291 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1279,6 +1279,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 682d0399b9b3729d16978eca258c55c2150afec7..16f349f8ce621c58f36f445016ea25d8af14910d 100644 +index d41c0f1aa501cbe17c88029bafbe034901f6d562..7705c791bfbb386f0b9f326c4b0ee0057ed0e6f5 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -3272,37 +3272,15 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0746-Add-PlayerInventorySlotChangeEvent.patch b/patches/server/0746-Add-PlayerInventorySlotChangeEvent.patch index 74685096a5a8..cca34b90d083 100644 --- a/patches/server/0746-Add-PlayerInventorySlotChangeEvent.patch +++ b/patches/server/0746-Add-PlayerInventorySlotChangeEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerInventorySlotChangeEvent diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index f87f12666d4708b7fb7ede3eff03570fed8d1f40..bb0aaa16f0de18b15764ba39a781e8b86d690bb9 100644 +index 312225a15261f2e80fbf6133c75c567574ade181..04e3c75c9abfaccb6d2d59d234e5169258b77553 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -381,6 +381,25 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { diff --git a/patches/server/0747-Elder-Guardian-appearance-API.patch b/patches/server/0747-Elder-Guardian-appearance-API.patch index 75a2208ae0c3..4a603b81c083 100644 --- a/patches/server/0747-Elder-Guardian-appearance-API.patch +++ b/patches/server/0747-Elder-Guardian-appearance-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Elder Guardian appearance API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 7fd3cb7c69aa212449739f5733de661af662611f..997a90a7567a90ef357530f9ed5677f0fce4d402 100644 +index dc360a7a8a8d23be9d8301a5e6fbff5499c9a947..74cfa4313c8aba96b792d7855627be68efc41d51 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3325,6 +3325,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3326,6 +3326,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end diff --git a/patches/server/0756-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch b/patches/server/0756-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch index 45c6c70db5ea..ff618c759549 100644 --- a/patches/server/0756-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch +++ b/patches/server/0756-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Fix EntityCombustEvent cancellation cant fully prevent diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 44f585b9dc9e3940193f07a2df1205907b4800ba..24834be9b5596745f9456488076bd89c3c7d2352 100644 +index 911b6391455402922e8bd52cfe9e5694231c81c3..31cb6c4357afc934a5e6e1a7a9222ac54175459d 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -3320,6 +3320,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0759-Add-Player-Warden-Warning-API.patch b/patches/server/0759-Add-Player-Warden-Warning-API.patch index 32eaa6033a74..c44c1b1bc327 100644 --- a/patches/server/0759-Add-Player-Warden-Warning-API.patch +++ b/patches/server/0759-Add-Player-Warden-Warning-API.patch @@ -10,10 +10,10 @@ public net.minecraft.world.entity.monster.warden.WardenSpawnTracker cooldownTick public net.minecraft.world.entity.monster.warden.WardenSpawnTracker increaseWarningLevel()V diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 997a90a7567a90ef357530f9ed5677f0fce4d402..2eafa35e87411ae0b78f445d3d0573ba6e832797 100644 +index 74cfa4313c8aba96b792d7855627be68efc41d51..a000d41fd6b6d9e690ea2a16ac1bd77589b64f14 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3330,6 +3330,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3331,6 +3331,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void showElderGuardian(boolean silent) { if (getHandle().connection != null) getHandle().connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.GUARDIAN_ELDER_EFFECT, silent ? 0F : 1F)); } diff --git a/patches/server/0762-check-global-player-list-where-appropriate.patch b/patches/server/0762-check-global-player-list-where-appropriate.patch index f64210126b58..586cac4e1920 100644 --- a/patches/server/0762-check-global-player-list-where-appropriate.patch +++ b/patches/server/0762-check-global-player-list-where-appropriate.patch @@ -24,7 +24,7 @@ index 4b2309d27867eddc50093e895503e02184e1b825..3eaeeb3ec715d92fe99e14c37e224cb1 + // Paper end - check global player list where appropriate } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 16f349f8ce621c58f36f445016ea25d8af14910d..0a52f925b0ef28ca7cee067a40d5dc4d30c224b0 100644 +index 7705c791bfbb386f0b9f326c4b0ee0057ed0e6f5..2c343617f9467bbef03f4d131ce94b1f1a090a80 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -3867,7 +3867,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0765-Friction-API.patch b/patches/server/0765-Friction-API.patch index ff7124236706..469868818a40 100644 --- a/patches/server/0765-Friction-API.patch +++ b/patches/server/0765-Friction-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Friction API diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 0a52f925b0ef28ca7cee067a40d5dc4d30c224b0..abcb1065100597f66c9f76fdae5f873fa0d8f315 100644 +index 2c343617f9467bbef03f4d131ce94b1f1a090a80..5520d0cdd5af75a6188a68f809aafb6c5880878a 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -298,6 +298,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0767-Fix-premature-player-kicks-on-shutdown.patch b/patches/server/0767-Fix-premature-player-kicks-on-shutdown.patch index 0eec1f89003d..75bc0623ab1f 100644 --- a/patches/server/0767-Fix-premature-player-kicks-on-shutdown.patch +++ b/patches/server/0767-Fix-premature-player-kicks-on-shutdown.patch @@ -47,7 +47,7 @@ index 4d9f1fc884050993287adfa4578a87da710623fb..a8dfe7a4b3d01bf75587be078f471d1e this.disconnect((Component) Component.translatable("multiplayer.disconnect.server_shutdown")); } catch (ClassCastException classcastexception) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 027d94dd08e7789b51c8779c65d4ddad4e62f21a..53c9be615a0f2939cd989e24e304e81e6e27f39d 100644 +index 7d7e1848e7074a0ec94fe924e328f15cb247c291..6cebf229cc5b1eedff45f10db70a4a4f323937b8 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -2170,7 +2170,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop= 2.0F) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 283e7caa8c564bb0455e29f1ee606b6993f3e57c..d9164eda358b56fe5e3b88e9bc7e23ab39034f0f 100644 +index a70db1d658127ed72f82580c1dd743c6c9d5f809..7029f8c76a18b76ab13e43f2d0ec4f910646caee 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2608,6 +2608,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2609,6 +2609,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().onUpdateAbilities(); } diff --git a/patches/server/0781-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch b/patches/server/0781-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch index 7da0a4ef651d..98305f38a5e3 100644 --- a/patches/server/0781-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch +++ b/patches/server/0781-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Expose pre-collision moving velocity to diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 960b3541140bfe36fda5cdb43e3408bbc9db5fde..2c959a99376ed479415354c481801643c5f6b1a1 100644 +index 1d21914ee8193cee8d7a8273f8e6932697b15c3c..6c4171aa43afa679946c8d8a08445bf5741aba8e 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -968,6 +968,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0784-Correctly-shrink-items-during-EntityResurrectEvent.patch b/patches/server/0784-Correctly-shrink-items-during-EntityResurrectEvent.patch index 48eae9b3ecb1..c14b32588290 100644 --- a/patches/server/0784-Correctly-shrink-items-during-EntityResurrectEvent.patch +++ b/patches/server/0784-Correctly-shrink-items-during-EntityResurrectEvent.patch @@ -22,7 +22,7 @@ This patch corrects this behaviour by only shrinking the item if a totem of undying was found and the event was called uncancelled. diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index abcb1065100597f66c9f76fdae5f873fa0d8f315..447fb76a3eb1505b1ef1e1aed8a11239c0124f4f 100644 +index 5520d0cdd5af75a6188a68f809aafb6c5880878a..da42691504177e1e2614db777cbe346f73725eda 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -1674,7 +1674,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0785-Win-Screen-API.patch b/patches/server/0785-Win-Screen-API.patch index f52ebd141586..981c12ddbed2 100644 --- a/patches/server/0785-Win-Screen-API.patch +++ b/patches/server/0785-Win-Screen-API.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Win Screen API public net.minecraft.server.level.ServerPlayer seenCredits diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index d9164eda358b56fe5e3b88e9bc7e23ab39034f0f..e6a678dee21b51d5f7005c2cf5038089447d0e7c 100644 +index 7029f8c76a18b76ab13e43f2d0ec4f910646caee..e90f477207ca0107e23cb29da0cacf6fed3dcfc4 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1322,6 +1322,25 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0794-Fix-advancement-triggers-for-entity-damage.patch b/patches/server/0794-Fix-advancement-triggers-for-entity-damage.patch index fff5e6ce2519..d85577a07808 100644 --- a/patches/server/0794-Fix-advancement-triggers-for-entity-damage.patch +++ b/patches/server/0794-Fix-advancement-triggers-for-entity-damage.patch @@ -23,7 +23,7 @@ index 821bb93e1b055ba38fafe3b7079d79aa062ebe8a..221d73676fe2fd240a47cf312c1179e0 return !this.getResponse(); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 447fb76a3eb1505b1ef1e1aed8a11239c0124f4f..95bbde31de42e1e12d722de86085e59050f1c3ae 100644 +index da42691504177e1e2614db777cbe346f73725eda..a4d24269c1365f32f232116f1530ac75b096c6ab 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -2465,7 +2465,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0810-Expand-PlayerItemMendEvent.patch b/patches/server/0810-Expand-PlayerItemMendEvent.patch index 396bdd4c4535..10de3ba9b2eb 100644 --- a/patches/server/0810-Expand-PlayerItemMendEvent.patch +++ b/patches/server/0810-Expand-PlayerItemMendEvent.patch @@ -30,10 +30,10 @@ index 3a7af27bb1ce0cbe56bd3760cd400083daf98d4c..bf0838f574fa3fb9654e087d602b8d38 if (l > 0) { // this.value = l; // CraftBukkit - update exp value of orb for PlayerItemMendEvent calls // Paper - the value field should not be mutated here because it doesn't take "count" into account diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index e6a678dee21b51d5f7005c2cf5038089447d0e7c..90187f6412a073a3c89da3eb01310e39406bb69c 100644 +index e90f477207ca0107e23cb29da0cacf6fed3dcfc4..de0dc5b37bd0823409974befdd96676b2575cf48 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1880,11 +1880,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1881,11 +1881,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { handle.serverLevel(), itemstack, amount ); int i = Math.min(possibleDurabilityFromXp, itemstack.getDamageValue()); diff --git a/patches/server/0811-Refresh-ProjectileSource-for-projectiles.patch b/patches/server/0811-Refresh-ProjectileSource-for-projectiles.patch index 7bc80ccda253..1cac178f6bdc 100644 --- a/patches/server/0811-Refresh-ProjectileSource-for-projectiles.patch +++ b/patches/server/0811-Refresh-ProjectileSource-for-projectiles.patch @@ -14,7 +14,7 @@ clearing the owner. Co-authored-by: Warrior <50800980+Warriorrrr@users.noreply.github.com> diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 2c959a99376ed479415354c481801643c5f6b1a1..8cdef637f6343119fc77f87e7478ee23e9b8efab 100644 +index 6c4171aa43afa679946c8d8a08445bf5741aba8e..ebd2bf1c16833ea8157bc3e3ef1f5730f646294f 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -393,6 +393,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0825-Don-t-load-chunks-for-supporting-block-checks.patch b/patches/server/0825-Don-t-load-chunks-for-supporting-block-checks.patch index 1feebdd77f80..bcb87c44482a 100644 --- a/patches/server/0825-Don-t-load-chunks-for-supporting-block-checks.patch +++ b/patches/server/0825-Don-t-load-chunks-for-supporting-block-checks.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Don't load chunks for supporting block checks diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 8cdef637f6343119fc77f87e7478ee23e9b8efab..3ef1352030bf1d6f4d2053158caea852552e91a7 100644 +index ebd2bf1c16833ea8157bc3e3ef1f5730f646294f..82d7d0038b269ea310571eb1c109ddd2afac39f7 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -1228,7 +1228,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0829-Fix-BanList-API.patch b/patches/server/0829-Fix-BanList-API.patch index 2621cc9868e8..58b6ec4b043e 100644 --- a/patches/server/0829-Fix-BanList-API.patch +++ b/patches/server/0829-Fix-BanList-API.patch @@ -208,10 +208,10 @@ index 172202accf4448a933fcf1ff820316c7910dd7f7..50ee7656580d386db473c054f5c5ec57 return null; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 90187f6412a073a3c89da3eb01310e39406bb69c..78a12f857db37ec5305d6c14847bc7653669bcc0 100644 +index de0dc5b37bd0823409974befdd96676b2575cf48..642cdf6a205017b9835ad423206617fd3b9a32bf 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1774,23 +1774,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1775,23 +1775,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override @@ -240,7 +240,7 @@ index 90187f6412a073a3c89da3eb01310e39406bb69c..78a12f857db37ec5305d6c14847bc765 if (kickPlayer) { this.kickPlayer(reason); } -@@ -1798,12 +1798,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1799,12 +1799,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override diff --git a/patches/server/0837-Folia-scheduler-and-owned-region-API.patch b/patches/server/0837-Folia-scheduler-and-owned-region-API.patch index e6316ec4c753..b390808ca16f 100644 --- a/patches/server/0837-Folia-scheduler-and-owned-region-API.patch +++ b/patches/server/0837-Folia-scheduler-and-owned-region-API.patch @@ -1148,7 +1148,7 @@ index 0000000000000000000000000000000000000000..d306f911757a4d556c82c0070d4837db + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 53c9be615a0f2939cd989e24e304e81e6e27f39d..f1b1be0caff83720d77454d333abae4613c66e72 100644 +index 6cebf229cc5b1eedff45f10db70a4a4f323937b8..5699863e790bd5f452a37514d1309fbddec0c64a 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1654,6 +1654,20 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> pluginWeakReferences = new WeakHashMap<>(); private int hash = 0; private double health = 20; -@@ -2119,7 +2120,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2120,7 +2121,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { otherPlayer.setUUID(uuidOverride); } // Paper end @@ -142,7 +142,7 @@ index 3b0d27c6c07ce4bce0b4ab8877d94a937708d2ae..2658c7a0257d7bab26d043626abb9f23 if (original != null) otherPlayer.setUUID(original); // Paper - uuid override } -@@ -2223,6 +2224,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2224,6 +2225,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return (entity != null) ? this.canSee(entity) : false; // If we can't find it, we can't see it } diff --git a/patches/server/0858-Fix-NPE-on-Boat-getStatus.patch b/patches/server/0858-Fix-NPE-on-Boat-getStatus.patch index b2413997613a..8ec449ba6c89 100644 --- a/patches/server/0858-Fix-NPE-on-Boat-getStatus.patch +++ b/patches/server/0858-Fix-NPE-on-Boat-getStatus.patch @@ -9,7 +9,7 @@ Boat status is null until the entity is added to the world and the tick() method public net.minecraft.world.entity.vehicle.Boat getStatus()Lnet/minecraft/world/entity/vehicle/Boat$Status; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java -index 5de1ada561d11c247a597effab1e0aa363b7c90f..412fd9e87ec81cf50cb8bc82fe2dad5dd0029039 100644 +index 5d51a49228eaee94f91cd04843e27c7918ca8796..8e9d382693047ed202e9b7cafb934700fd830827 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java @@ -87,6 +87,17 @@ public abstract class CraftBoat extends CraftVehicle implements Boat { diff --git a/patches/server/0859-Expand-Pose-API.patch b/patches/server/0859-Expand-Pose-API.patch index fb6535a3d5cb..891dd712d64f 100644 --- a/patches/server/0859-Expand-Pose-API.patch +++ b/patches/server/0859-Expand-Pose-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Expand Pose API diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index aeeb90481a9ac0a8ec9e3c5af08a32ca3e32bfb6..a8a5b28d95f7c3ce944f51993dd0c0eb98e3c550 100644 +index d8331b2d4ad3ebebb6ecbbf083f3464dad38f623..63e68376d1854f4f7ff1a1d0a11fcec1b8c3b61a 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -427,6 +427,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0865-Implement-OfflinePlayer-isConnected.patch b/patches/server/0865-Implement-OfflinePlayer-isConnected.patch index 245ae43622e7..6c7d4f55ccf5 100644 --- a/patches/server/0865-Implement-OfflinePlayer-isConnected.patch +++ b/patches/server/0865-Implement-OfflinePlayer-isConnected.patch @@ -23,7 +23,7 @@ index 2c2c4db31a746b4eb853dc04c6b3e5631bbfa034..4f4e3ee18d586f61706504218cddc06a public String getName() { Player player = this.getPlayer(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 2658c7a0257d7bab26d043626abb9f2310f284e2..060f4cade69dbd41e96d1684b4fba34762f5eaa7 100644 +index 7104ffd4dd72a053793eb52c8df29eadbd184221..ea5e3973a4021a4584d3b8b33c9d50001f4c0fe6 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -261,6 +261,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0866-Fix-slot-desync.patch b/patches/server/0866-Fix-slot-desync.patch index b85e196ed610..afdb75279e80 100644 --- a/patches/server/0866-Fix-slot-desync.patch +++ b/patches/server/0866-Fix-slot-desync.patch @@ -10,7 +10,7 @@ Co-authored-by: Minecrell Co-authored-by: Newwind diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 1a7d2ade0e85dd5e6cd6c9202e3277cc2fa43d4a..37defbc0674e67a26e5a9aebb811310ef12878ee 100644 +index f05a9fd321a4af28e9771bbf39d73f80dd4160c9..90aa8e401e1d092a31ff21699409b8366629cdcc 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -460,6 +460,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { @@ -40,7 +40,7 @@ index d4250cc73bc51c51b78a9392a9879d47dc67f159..182897b4ab9415b7aab0b968274993dd if (event.isCancelled()) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index a8a5b28d95f7c3ce944f51993dd0c0eb98e3c550..ba57deb4e10bba180429cca4d8c864ab869065c7 100644 +index 63e68376d1854f4f7ff1a1d0a11fcec1b8c3b61a..e9142414c7d247ae2a27c0bc9ea2be3bb8e3db16 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2752,8 +2752,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0867-Add-titleOverride-to-InventoryOpenEvent.patch b/patches/server/0867-Add-titleOverride-to-InventoryOpenEvent.patch index 05e37009fdda..1b98c1b4a0e5 100644 --- a/patches/server/0867-Add-titleOverride-to-InventoryOpenEvent.patch +++ b/patches/server/0867-Add-titleOverride-to-InventoryOpenEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add titleOverride to InventoryOpenEvent diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 37defbc0674e67a26e5a9aebb811310ef12878ee..b0b4bede6f25b8a0de54d954c7010021f87aadc3 100644 +index 90aa8e401e1d092a31ff21699409b8366629cdcc..419fcb4cd97cf10a2601e02024b999a51a0ff952 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -1924,12 +1924,17 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { diff --git a/patches/server/0882-Fix-missing-map-initialize-event-call.patch b/patches/server/0882-Fix-missing-map-initialize-event-call.patch index 099784fcc015..795f551f59dd 100644 --- a/patches/server/0882-Fix-missing-map-initialize-event-call.patch +++ b/patches/server/0882-Fix-missing-map-initialize-event-call.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Fix missing map initialize event call public net.minecraft.world.level.storage.DimensionDataStorage readSavedData(Ljava/util/function/Function;Lnet/minecraft/util/datafix/DataFixTypes;Ljava/lang/String;)Lnet/minecraft/world/level/saveddata/SavedData; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 1cb5e107a391ab56942cdb2d1cae7d5646a85ec6..39dba6c2e9de2c1d6716945a49d48d9b76a07c77 100644 +index 1cb5e107a391ab56942cdb2d1cae7d5646a85ec6..7acb24c2a34fdcbcb1c0e3cc03b01996689667d3 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1726,13 +1726,24 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1726,13 +1726,29 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Nullable @Override public MapItemSavedData getMapData(MapId id) { @@ -21,22 +21,27 @@ index 1cb5e107a391ab56942cdb2d1cae7d5646a85ec6..39dba6c2e9de2c1d6716945a49d48d9b + // Paper start - Call missing map initialize event and set id + final DimensionDataStorage storage = this.getServer().overworld().getDataStorage(); + -+ final net.minecraft.world.level.saveddata.SavedData existing = storage.cache.get(id.key()); -+ if (existing == null && !storage.cache.containsKey(id.key())) { -+ final MapItemSavedData worldmap = (MapItemSavedData) this.getServer().overworld().getDataStorage().get(MapItemSavedData.factory(), id.key()); -+ storage.cache.put(id.key(), worldmap); -+ if (worldmap != null) { ++ final Optional cacheEntry = storage.cache.get(id.key()); ++ if (cacheEntry == null) { // Cache did not contain, try to load and may init ++ final MapItemSavedData worldmap = storage.get(MapItemSavedData.factory(), id.key()); // get populates the cache ++ if (worldmap != null) { // map was read, init it and return + worldmap.id = id; + new MapInitializeEvent(worldmap.mapView).callEvent(); + return worldmap; + } -+ } else if (existing instanceof MapItemSavedData mapItemSavedData) { -+ mapItemSavedData.id = id; ++ ++ return null; // Map does not exist, reading failed. } - return worldmap; - // CraftBukkit end + -+ return existing instanceof MapItemSavedData data ? data : null; ++ // Cache entry exists, update it with the id ref and return. ++ if (cacheEntry.orElse(null) instanceof final MapItemSavedData mapItemSavedData) { ++ mapItemSavedData.id = id; ++ return mapItemSavedData; ++ } ++ ++ return null; + // Paper end - Call missing map initialize event and set id } diff --git a/patches/server/0885-Add-player-idle-duration-API.patch b/patches/server/0885-Add-player-idle-duration-API.patch index 69a1a77c2f69..d715a2ed4a3d 100644 --- a/patches/server/0885-Add-player-idle-duration-API.patch +++ b/patches/server/0885-Add-player-idle-duration-API.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add player idle duration API Implements API for getting and resetting a player's idle duration. diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 060f4cade69dbd41e96d1684b4fba34762f5eaa7..1681653f686133b5d2c0c10c368f86134b295d20 100644 +index ea5e3973a4021a4584d3b8b33c9d50001f4c0fe6..c73089566eccc15aa747e3e3707d089a0f2b8d1d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3446,6 +3446,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3447,6 +3447,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end diff --git a/patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch b/patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch index d52f931c35f7..fe05ccc109e2 100644 --- a/patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch +++ b/patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Allow null itemstack for Player#sendEquipmentChange diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 1681653f686133b5d2c0c10c368f86134b295d20..bdc9ac5bee552c1de110d6588d3850a6b3cd5723 100644 +index c73089566eccc15aa747e3e3707d089a0f2b8d1d..74b90ee971ec799cf19551ac63a9b01f77500967 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1144,7 +1144,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0891-Add-predicate-for-blocks-when-raytracing.patch b/patches/server/0891-Add-predicate-for-blocks-when-raytracing.patch index bd4cb684e67e..438ccfb26779 100644 --- a/patches/server/0891-Add-predicate-for-blocks-when-raytracing.patch +++ b/patches/server/0891-Add-predicate-for-blocks-when-raytracing.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add predicate for blocks when raytracing diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java -index cc9ae2122b563d7b583c7335d0a8ce227f9b1af4..d00ebcd6fccbf1d1efe83604ed86d317119be5f8 100644 +index 7e1a332168357b9af14dbe3299549c2c93903fa6..93738c7dea1ea3d19013a47380391274612a719b 100644 --- a/src/main/java/net/minecraft/world/level/BlockGetter.java +++ b/src/main/java/net/minecraft/world/level/BlockGetter.java @@ -71,6 +71,12 @@ public interface BlockGetter extends LevelHeightAccessor { @@ -22,7 +22,7 @@ index cc9ae2122b563d7b583c7335d0a8ce227f9b1af4..d00ebcd6fccbf1d1efe83604ed86d317 BlockState iblockdata = this.getBlockStateIfLoaded(blockposition); if (iblockdata == null) { @@ -80,7 +86,7 @@ public interface BlockGetter extends LevelHeightAccessor { - return BlockHitResult.miss(raytrace1.getTo(), Direction.getNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(raytrace1.getTo())); + return BlockHitResult.miss(raytrace1.getTo(), Direction.getApproximateNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(raytrace1.getTo())); } // Paper end - Prevent raytrace from loading chunks - if (iblockdata.isAir()) return null; // Paper - Perf: optimise air cases diff --git a/patches/server/0892-Broadcast-take-item-packets-with-collector-as-source.patch b/patches/server/0892-Broadcast-take-item-packets-with-collector-as-source.patch index 1e33c1acff78..03d6650dc143 100644 --- a/patches/server/0892-Broadcast-take-item-packets-with-collector-as-source.patch +++ b/patches/server/0892-Broadcast-take-item-packets-with-collector-as-source.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Broadcast take item packets with collector as source This fixes players (which can't view the collector) seeing item pickups with themselves as the target. diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 95bbde31de42e1e12d722de86085e59050f1c3ae..c0646a4c023a34d4ca516390d748d29d7b9c265b 100644 +index a4d24269c1365f32f232116f1530ac75b096c6ab..30424789ba1c8d25f830145501b4a7399b91f2d1 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -3893,7 +3893,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0900-Don-t-fire-sync-events-during-worldgen.patch b/patches/server/0900-Don-t-fire-sync-events-during-worldgen.patch index 3146ea0138c8..53a3932e6f5a 100644 --- a/patches/server/0900-Don-t-fire-sync-events-during-worldgen.patch +++ b/patches/server/0900-Don-t-fire-sync-events-during-worldgen.patch @@ -19,7 +19,7 @@ where generation happened directly to a ServerLevel and the entity still has the flag set. diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 39dba6c2e9de2c1d6716945a49d48d9b76a07c77..e3df141a2a49f10e83fe132514a9b1d969cc4417 100644 +index 7acb24c2a34fdcbcb1c0e3cc03b01996689667d3..7a713fd31a2155b1c77c54817a67e354b1d4640d 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1219,6 +1219,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -31,7 +31,7 @@ index 39dba6c2e9de2c1d6716945a49d48d9b76a07c77..e3df141a2a49f10e83fe132514a9b1d9 if (entity.valid) { MinecraftServer.LOGGER.error("Attempted Double World add on {}", entity, new Throwable()); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index ba57deb4e10bba180429cca4d8c864ab869065c7..1fb29f2c5e55d77eb5d04d423cf9f38a6e7d9f4c 100644 +index e9142414c7d247ae2a27c0bc9ea2be3bb8e3db16..1d66c35b1092b8101f0a803d8c087e5a958875b1 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -631,7 +631,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -68,7 +68,7 @@ index 6b2f0a4bc911888b72b796099760af38b1e28656..4eec58353343b414120e189afed04b98 }, () -> { EntityType.LOGGER.warn("Skipping Entity with id {}", nbt.getString("id")); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index c0646a4c023a34d4ca516390d748d29d7b9c265b..d37e6651b7be89b14ed5781e1a72fc1b8f50c103 100644 +index 30424789ba1c8d25f830145501b4a7399b91f2d1..9bc6ed9fd8e5154d39fe12ffed1ecd5ec8e70df8 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -1161,6 +1161,11 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0903-Restore-vanilla-entity-drops-behavior.patch b/patches/server/0903-Restore-vanilla-entity-drops-behavior.patch index ae2eeec5524c..0eede4fd44fb 100644 --- a/patches/server/0903-Restore-vanilla-entity-drops-behavior.patch +++ b/patches/server/0903-Restore-vanilla-entity-drops-behavior.patch @@ -9,7 +9,7 @@ on dropping the item instead of generalizing it for all dropped items like CB does. diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index b0b4bede6f25b8a0de54d954c7010021f87aadc3..52b18f2c333b7535929bb4e52e65cf5fb0f5692f 100644 +index 419fcb4cd97cf10a2601e02024b999a51a0ff952..df21cd1bd2a3dda7169edbea18bbfdf043db76f8 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -1235,20 +1235,20 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { @@ -28,7 +28,7 @@ index b0b4bede6f25b8a0de54d954c7010021f87aadc3..52b18f2c333b7535929bb4e52e65cf5f } } } - if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - fix player loottables running when mob loot gamerule is false + if (this.shouldDropLoot() && this.serverLevel().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - fix player loottables running when mob loot gamerule is false // SPIGOT-5071: manually add player loot tables (SPIGOT-5195 - ignores keepInventory rule) this.dropFromLootTable(this.serverLevel(), damageSource, this.lastHurtByPlayerTime > 0); - this.dropCustomDeathLoot(this.serverLevel(), damageSource, flag); @@ -37,7 +37,7 @@ index b0b4bede6f25b8a0de54d954c7010021f87aadc3..52b18f2c333b7535929bb4e52e65cf5f loot.addAll(this.drops); this.drops.clear(); // SPIGOT-5188: make sure to clear diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 1fb29f2c5e55d77eb5d04d423cf9f38a6e7d9f4c..0223f2e282a85882645f4ed52891c566a268f37b 100644 +index 1d66c35b1092b8101f0a803d8c087e5a958875b1..aac1d620bf4cd1f18243f8c53cd32ab16fdeb616 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2678,19 +2678,45 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -86,10 +86,10 @@ index 1fb29f2c5e55d77eb5d04d423cf9f38a6e7d9f4c..0223f2e282a85882645f4ed52891c566 - entityitem.setDefaultPickUpDelay(); + entityitem.setDefaultPickUpDelay(); // Paper - diff on change (in dropConsumer) // Paper start - Call EntityDropItemEvent - return this.spawnAtLocation(entityitem); + return this.spawnAtLocation(world, entityitem); } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index d37e6651b7be89b14ed5781e1a72fc1b8f50c103..0fcc5ed28b2371a62be57d7ea62f2e3dfedcf735 100644 +index 9bc6ed9fd8e5154d39fe12ffed1ecd5ec8e70df8..4b9108e48d052919bca000ddb54f9bf4589c33e6 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -291,7 +291,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0907-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch b/patches/server/0907-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch index 0a3dc9f139c9..8082b201b8dd 100644 --- a/patches/server/0907-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch +++ b/patches/server/0907-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch @@ -26,7 +26,7 @@ index c6dcc37ac5fcf50bcb246f533b99983dfc5c19c2..c13b6f14c3061710c2b27034db240cc9 d3 = to.getX(); d4 = to.getY(); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 0fcc5ed28b2371a62be57d7ea62f2e3dfedcf735..f42a98324ecfc992cf36c2f44cdb781ad4edbad4 100644 +index 4b9108e48d052919bca000ddb54f9bf4589c33e6..1c4ec3857c5c3ecf58f842292c280a4a1f00a04c 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -4365,7 +4365,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0908-Add-experience-points-API.patch b/patches/server/0908-Add-experience-points-API.patch index 0ab86e2d015f..9111f82b8ffd 100644 --- a/patches/server/0908-Add-experience-points-API.patch +++ b/patches/server/0908-Add-experience-points-API.patch @@ -18,10 +18,10 @@ index aca888c2f02b09ac6739bdc81b194c4527dd69f5..a19a795deaa7f46c92b97912e2ade006 // Paper start - send while respecting visibility private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index bdc9ac5bee552c1de110d6588d3850a6b3cd5723..d5d30252241d5051b038cf4f487e956afd554ee0 100644 +index 74b90ee971ec799cf19551ac63a9b01f77500967..a807f37a4b937fc3a1d89cb5d116224c9b3c5f49 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1948,6 +1948,49 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1949,6 +1949,49 @@ public class CraftPlayer extends CraftHumanEntity implements Player { Preconditions.checkArgument(exp >= 0, "Total experience points must not be negative (%s)", exp); this.getHandle().totalExperience = exp; } diff --git a/patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch b/patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch index e0dee7a8de7c..05754abc5d43 100644 --- a/patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch +++ b/patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch @@ -85,7 +85,7 @@ index 1a6448cccf79a94013f9f44c3067d91da3da1f7e..06af888e4c3d9d01a462b487742b5971 if (nbt.contains("leash", 11)) { Either either = (Either) NbtUtils.readBlockPos(nbt, "leash").map(Either::right).orElse(null); // CraftBukkit - decompile error diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index f42a98324ecfc992cf36c2f44cdb781ad4edbad4..a7f0d49637eb72b4645997a97cc6927b16a59738 100644 +index 1c4ec3857c5c3ecf58f842292c280a4a1f00a04c..7196340fefd95845f290329faef489f2b2626ecb 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -911,11 +911,13 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/0926-Add-BlockBreakProgressUpdateEvent.patch b/patches/server/0926-Add-BlockBreakProgressUpdateEvent.patch index 7d82cc97af77..81399fe283d2 100644 --- a/patches/server/0926-Add-BlockBreakProgressUpdateEvent.patch +++ b/patches/server/0926-Add-BlockBreakProgressUpdateEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add BlockBreakProgressUpdateEvent diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index e3df141a2a49f10e83fe132514a9b1d969cc4417..3f0e5bd457e3231d84b9d14396d8d8859989f3f4 100644 +index 7a713fd31a2155b1c77c54817a67e354b1d4640d..942eb8c1ef575de53b1591b39014a39edb054a1f 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1315,6 +1315,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0930-Add-onboarding-message-for-initial-server-start.patch b/patches/server/0930-Add-onboarding-message-for-initial-server-start.patch index f6da9e5a3d0a..dd0167082e32 100644 --- a/patches/server/0930-Add-onboarding-message-for-initial-server-start.patch +++ b/patches/server/0930-Add-onboarding-message-for-initial-server-start.patch @@ -29,7 +29,7 @@ index 73e8a524925ed6f2580d3bd01616646fabafda78..450a1cc8f1624dce2daf52210d017e07 return instance; } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index f1b1be0caff83720d77454d333abae4613c66e72..f575c0042f67c70df0ddb1d1db68e0138cf0b534 100644 +index 5699863e790bd5f452a37514d1309fbddec0c64a..2168b8d29e1a53460ab83189ed457d38990c5c89 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1151,6 +1151,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop void loadContentsFromNetwork( diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index dcf046dd1eb8c2b724c971c4adf4462895183f0a..448961d7bd80e7e84959866906e6a4e3ac9ab4f7 100644 +index 1496bc9fa6fe8b5f3b426f4a70550bb66879dfcc..7dade9a2c0efac0bfb7208f70b16e4e440deebec 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -2251,7 +2251,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Date: Fri, 25 Oct 2024 13:19:23 +0200 Subject: [PATCH 051/119] Compile issues 1 --- ...70-Fix-Per-World-Difficulty-Remembering-Difficulty.patch | 4 ++-- patches/server/0403-Cache-block-data-strings.patch | 2 +- ...x-deop-kicking-non-whitelisted-player-when-white-l.patch | 2 +- patches/server/0457-Add-ServerResourcesReloadedEvent.patch | 2 +- patches/server/0480-Add-EntityMoveEvent.patch | 2 +- ...499-forced-whitelist-use-configurable-kick-message.patch | 2 +- patches/server/0512-More-World-API.patch | 4 ++-- .../0536-Add-cause-to-Weather-ThunderChangeEvents.patch | 2 +- patches/server/0539-Add-PlayerKickEvent-causes.patch | 2 +- patches/server/0549-add-per-world-spawn-limits.patch | 2 +- ...-Add-methods-to-find-targets-for-lightning-strikes.patch | 2 +- patches/server/0593-Improve-and-expand-AsyncCatcher.patch | 2 +- .../0594-Add-paper-mobcaps-and-paper-playermobcaps.patch | 2 +- ...0611-Prevent-softlocked-end-exit-portal-generation.patch | 6 +++--- .../0642-Expose-vanilla-BiomeProvider-from-WorldInfo.patch | 4 ++-- patches/server/0658-Add-GameEvent-tags.patch | 6 +++--- ...ecute-chunk-tasks-fairly-for-worlds-while-waiting-.patch | 2 +- ...tion-to-have-default-CustomSpawners-in-custom-worl.patch | 2 +- ...-Put-world-into-worldlist-before-initing-the-world.patch | 4 ++-- patches/server/0665-Custom-Potion-Mixes.patch | 4 ++-- patches/server/0667-Fix-falling-block-spawn-methods.patch | 2 +- patches/server/0676-Fix-saving-in-unloadWorld.patch | 2 +- patches/server/0688-WorldCreator-keepSpawnLoaded.patch | 2 +- ...Throw-exception-on-world-create-while-being-ticked.patch | 4 ++-- .../0709-Don-t-broadcast-messages-to-command-blocks.patch | 2 +- .../0721-Warn-on-plugins-accessing-faraway-chunks.patch | 2 +- patches/server/0726-Block-Ticking-API.patch | 4 ++-- .../server/0727-Add-Velocity-IP-Forwarding-Support.patch | 2 +- .../server/0729-Fix-plugin-loggers-on-server-shutdown.patch | 2 +- .../0758-ensure-reset-EnderDragon-boss-event-name.patch | 2 +- .../0767-Fix-premature-player-kicks-on-shutdown.patch | 2 +- ...n-t-enforce-icanhasbukkit-default-if-alias-block-e.patch | 2 +- .../server/0837-Folia-scheduler-and-owned-region-API.patch | 4 ++-- patches/server/0840-Only-capture-actual-tree-growth.patch | 2 +- .../server/0843-Use-correct-seed-on-api-world-load.patch | 2 +- patches/server/0847-Bandaid-fix-for-Effect.patch | 2 +- ...precate-and-replace-methods-with-old-StructureType.patch | 2 +- patches/server/0860-More-DragonBattle-API.patch | 2 +- ...-crystal-portal-proximity-check-before-entity-look.patch | 2 +- .../0891-Add-predicate-for-blocks-when-raytracing.patch | 2 +- ...x-strikeLightningEffect-powers-lightning-rods-and-.patch | 2 +- patches/server/0901-Add-Structure-check-API.patch | 2 +- ...Properly-handle-experience-dropping-on-block-break.patch | 2 +- patches/server/0919-Add-Lifecycle-Event-system.patch | 2 +- patches/server/0924-improve-BanList-types.patch | 2 +- patches/server/0929-More-Raid-API.patch | 2 +- ...30-Add-onboarding-message-for-initial-server-start.patch | 2 +- patches/server/0957-Brigadier-based-command-API.patch | 4 ++-- patches/server/0980-Anti-Xray.patch | 4 ++-- patches/server/0984-Optimize-Hoppers.patch | 2 +- patches/server/1021-Add-FeatureFlag-API.patch | 2 +- patches/server/1022-Tag-Lifecycle-Events.patch | 2 +- patches/server/1033-Void-damage-configuration-API.patch | 2 +- 53 files changed, 67 insertions(+), 67 deletions(-) diff --git a/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch b/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch index 3be0b6418891..06d3e294ce60 100644 --- a/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch +++ b/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch @@ -8,7 +8,7 @@ makes it so that the server keeps the last difficulty used instead of restoring the server.properties every single load. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index b4eff440e3d9489f99e10a73611421ef877aa871..9109628a48026ceca9dd53a3e75f79510e56c95c 100644 +index b4eff440e3d9489f99e10a73611421ef877aa871..4af87078b6d7fd733d0e4094af2e7cce029c19d3 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -852,7 +852,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { + Preconditions.checkArgument(clazz == org.bukkit.GameEvent.class, "Game Event namespace must have GameEvent type"); + TagKey gameEventTagKey = TagKey.create(net.minecraft.core.registries.Registries.GAME_EVENT, key); -+ if (net.minecraft.core.registries.BuiltInRegistries.GAME_EVENT.getTag(gameEventTagKey).isPresent()) { ++ if (net.minecraft.core.registries.BuiltInRegistries.GAME_EVENT.get(gameEventTagKey).isPresent()) { + return (org.bukkit.Tag) new io.papermc.paper.CraftGameEventTag(net.minecraft.core.registries.BuiltInRegistries.GAME_EVENT, gameEventTagKey); + } + } @@ -73,7 +73,7 @@ index 8d9816f84e551f1257972f467352e9c9ee09473e..b18ad8abb5e3c53b0e13544a6833198a + case org.bukkit.Tag.REGISTRY_GAME_EVENTS -> { + Preconditions.checkArgument(clazz == org.bukkit.GameEvent.class); + net.minecraft.core.Registry gameEvents = net.minecraft.core.registries.BuiltInRegistries.GAME_EVENT; -+ return gameEvents.getTags().map(pair -> (org.bukkit.Tag) new io.papermc.paper.CraftGameEventTag(gameEvents, pair.getFirst())).collect(ImmutableList.toImmutableList()); ++ return gameEvents.getTags().map(pair -> (org.bukkit.Tag) new io.papermc.paper.CraftGameEventTag(gameEvents, pair.key())).collect(ImmutableList.toImmutableList()); + } + // Paper end default -> throw new IllegalArgumentException(); diff --git a/patches/server/0659-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch b/patches/server/0659-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch index b3d65b12d0e4..02d3260ae341 100644 --- a/patches/server/0659-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch +++ b/patches/server/0659-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch @@ -9,7 +9,7 @@ This might result in chunks loading far slower in the nether, for example. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 15382d7da69967c50007f136e9d17dd2f81166e3..af392711da61a1921be1f82396c2a04dc897d563 100644 +index 7e85d9e00f41abb26fbf0e21e70ab82018f6f2a6..12a3480823722cd907654248ae2a977ca3f7bb0f 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1419,6 +1419,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop(Lnet/minecraft/world/level/Level;DDDLnet/minecraft/world/level/block/state/BlockState;)V diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 7dc167950021371b5cf8a7e1e38f013220e1c8a6..9ea74d52112ab4feea3f4bafd82351a72088cbc5 100644 +index da761980a12dc08ca77dadc8773b4467a48637f9..4bcd91f946dd6157a345ae8e7d049bff051911b3 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1405,7 +1405,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0676-Fix-saving-in-unloadWorld.patch b/patches/server/0676-Fix-saving-in-unloadWorld.patch index d5a0b6e7c712..f2d01904b1c9 100644 --- a/patches/server/0676-Fix-saving-in-unloadWorld.patch +++ b/patches/server/0676-Fix-saving-in-unloadWorld.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Fix saving in unloadWorld Change savingDisabled to false to ensure ServerLevel's saving logic gets called when unloadWorld is called with save = true diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index f0eb8284b537014b591e45f034f1498e7e687e54..cc08b56da8a276202da3e85315fdb2ad530c2545 100644 +index b3e5fc3a417be2af8ed6591f67f8d56c4ca86d74..2860aa8f75ec5901023f88047cb4cb96298a99e0 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1386,7 +1386,7 @@ public final class CraftServer implements Server { diff --git a/patches/server/0688-WorldCreator-keepSpawnLoaded.patch b/patches/server/0688-WorldCreator-keepSpawnLoaded.patch index 0e11daefe3a8..2b6c3f2d6ef6 100644 --- a/patches/server/0688-WorldCreator-keepSpawnLoaded.patch +++ b/patches/server/0688-WorldCreator-keepSpawnLoaded.patch @@ -5,7 +5,7 @@ Subject: [PATCH] WorldCreator#keepSpawnLoaded diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index cc08b56da8a276202da3e85315fdb2ad530c2545..b31f3013ff63bb6ece80a9d10e51641a7e93f3df 100644 +index 2860aa8f75ec5901023f88047cb4cb96298a99e0..d0a72476d36294792550425a8c0646a7c0be75a7 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1329,7 +1329,7 @@ public final class CraftServer implements Server { diff --git a/patches/server/0703-Throw-exception-on-world-create-while-being-ticked.patch b/patches/server/0703-Throw-exception-on-world-create-while-being-ticked.patch index a447e15d32f5..b9e8b476fa1c 100644 --- a/patches/server/0703-Throw-exception-on-world-create-while-being-ticked.patch +++ b/patches/server/0703-Throw-exception-on-world-create-while-being-ticked.patch @@ -7,7 +7,7 @@ There are no plans to support creating worlds while worlds are being ticked themselvess. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 9765951d0ed653ca5b4ae4903887ec7ef25cb50a..8030baa8ef189a17502da9c51baace0b7369137b 100644 +index 46495bf3b04187b4cf945f37f128a06aceb83eb7..fe8c05e51b8e4620a10590aaa24017f205466fca 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -328,6 +328,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop getDrops(LootParams.Builder builder) { diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index a34e888f63ead250c41b6bbe6850a5e5b4254c3d..66ac5d0b6dafd0323b73953cdd633dca624c3bcd 100644 +index 6dceb6082538df6f6147254e861d1cec8af7ec50..5cb69d0b822e11a99a96aef4f59986d083b079f4 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -509,7 +509,7 @@ public class CraftBlock implements Block { diff --git a/patches/server/0919-Add-Lifecycle-Event-system.patch b/patches/server/0919-Add-Lifecycle-Event-system.patch index fe8a2a22de05..e2eaeec2f9bd 100644 --- a/patches/server/0919-Add-Lifecycle-Event-system.patch +++ b/patches/server/0919-Add-Lifecycle-Event-system.patch @@ -727,7 +727,7 @@ index 2e96308696e131f3f013469a395e5ddda2c5d529..65a66e484c1c39c5f41d97db52f31c67 } catch (Throwable e) { LOGGER.error("Failed to run bootstrapper for %s. This plugin will not be loaded.".formatted(provider.getSource()), e); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 2934e232c84603224470fdaba0103d42fc06e8b4..4dc64ab006399d62251f4a238d9c2caebd595301 100644 +index dbdf52a306d7018f0bf01fcf6c24a6d1dc269be5..fb55dced981d16a82e4cc233fbf25695850a1b99 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1051,6 +1051,11 @@ public final class CraftServer implements Server { diff --git a/patches/server/0924-improve-BanList-types.patch b/patches/server/0924-improve-BanList-types.patch index 24c44ced873d..1b56c10b04a0 100644 --- a/patches/server/0924-improve-BanList-types.patch +++ b/patches/server/0924-improve-BanList-types.patch @@ -5,7 +5,7 @@ Subject: [PATCH] improve BanList types diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 4dc64ab006399d62251f4a238d9c2caebd595301..97850b3111dfa86d15186fa200937b28bec428de 100644 +index fb55dced981d16a82e4cc233fbf25695850a1b99..82a85a4e2dd58d22e6aad797e4bd8f7c5b355caf 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -2223,6 +2223,21 @@ public final class CraftServer implements Server { diff --git a/patches/server/0929-More-Raid-API.patch b/patches/server/0929-More-Raid-API.patch index 6e3632dd09d7..daaeb2bdea2e 100644 --- a/patches/server/0929-More-Raid-API.patch +++ b/patches/server/0929-More-Raid-API.patch @@ -86,7 +86,7 @@ index b8ce1c1c2447f9cff1717bfcfd6eb911ade0d4b3..51f21af9d75769abdcba713b9aa33392 + // Paper end - more Raid API } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 1675ad5818340f21c7e5b6982af315bcad30240b..149377347fc632358a8bb97e644b1c4ab9be413d 100644 +index 50b3f5c185b8bb7965226c97a37faf714f5beb0a..51b10d9cceb4dfbea5e1d82d0404948c6cdc5944 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -2326,6 +2326,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0930-Add-onboarding-message-for-initial-server-start.patch b/patches/server/0930-Add-onboarding-message-for-initial-server-start.patch index dd0167082e32..df74ef81615f 100644 --- a/patches/server/0930-Add-onboarding-message-for-initial-server-start.patch +++ b/patches/server/0930-Add-onboarding-message-for-initial-server-start.patch @@ -29,7 +29,7 @@ index 73e8a524925ed6f2580d3bd01616646fabafda78..450a1cc8f1624dce2daf52210d017e07 return instance; } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 5699863e790bd5f452a37514d1309fbddec0c64a..2168b8d29e1a53460ab83189ed457d38990c5c89 100644 +index 96fdbdcbe43c22b62f679837409da08fcaeae55e..675cbdf1cbac219a386c0ea5931b569b3027b203 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1151,6 +1151,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop void loadContentsFromNetwork( diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 1496bc9fa6fe8b5f3b426f4a70550bb66879dfcc..7dade9a2c0efac0bfb7208f70b16e4e440deebec 100644 +index b37e49bd25ed327e03250415799c0777f95bd57b..6d0cfaaf414931d9fd8eee417f4b70ac6679de10 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -2251,7 +2251,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Date: Fri, 25 Oct 2024 13:34:01 +0200 Subject: [PATCH 052/119] Some more compile issues --- patches/server/0002-Remap-fixes.patch | 13 +++++++++++++ patches/server/0023-Timings-v2.patch | 15 +++------------ ...ock-and-tnt-entities-at-the-specified.patch | 6 +++--- .../0034-Player-affects-spawning-API.patch | 4 ++-- ...Table-API-and-replenishable-lootables.patch | 4 ++-- ...k-entity-nbt-data-from-falling-blocks.patch | 2 +- .../server/0166-PreCreatureSpawnEvent.patch | 2 +- patches/server/0267-Add-more-Zombie-API.patch | 2 +- ...and-additions-to-the-spawn-reason-API.patch | 2 +- ...-get-gravity-in-void.-Fixes-MC-167279.patch | 4 ++-- ...e-chance-of-villager-zombie-infection.patch | 2 +- ...ider-respects-game-and-entity-rules-f.patch | 4 ++-- ...-Add-zombie-targets-turtle-egg-config.patch | 2 +- ...rld-settings-for-mobs-picking-up-loot.patch | 2 +- ...Configurable-door-breaking-difficulty.patch | 2 +- patches/server/0553-Missing-Entity-API.patch | 2 +- .../0561-Add-missing-forceDrop-toggles.patch | 2 +- ...t-unintended-light-block-manipulation.patch | 18 ++++-------------- .../0648-Fix-xp-reward-for-baby-zombies.patch | 2 +- ...block-data-for-EntityChangeBlockEvent.patch | 4 ++-- .../server/0696-Expand-FallingBlock-API.patch | 2 +- ...ous-missing-EntityDropItemEvent-calls.patch | 2 +- patches/server/0715-Fix-Bee-flower-NPE.patch | 2 +- .../0741-Fix-a-bunch-of-vanilla-bugs.patch | 6 +++--- .../0744-EntityPickupItemEvent-fixes.patch | 4 ++-- ...-config-for-disabling-entity-tag-tags.patch | 2 +- .../0845-Cache-map-ids-on-item-frames.patch | 2 +- ...on-t-fire-sync-events-during-worldgen.patch | 4 ++-- ...idate-ResourceLocation-in-NBT-reading.patch | 6 +++--- .../server/0992-Configurable-Sand-Duping.patch | 2 +- ...8-Fix-InventoryOpenEvent-cancellation.patch | 2 +- ...wall-time-unused-skip-tick-protection.patch | 2 +- 32 files changed, 62 insertions(+), 68 deletions(-) diff --git a/patches/server/0002-Remap-fixes.patch b/patches/server/0002-Remap-fixes.patch index d7cff4215bd5..2bb4aff8a2d2 100644 --- a/patches/server/0002-Remap-fixes.patch +++ b/patches/server/0002-Remap-fixes.patch @@ -58,6 +58,19 @@ index 7344cff32fa6fe3dedb74ed98126072c55b0abd2..d98b28e9488a5a7736719cf656736bb0 entityliving1 = entityliving2; } else { entityliving1 = null; +diff --git a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java +index 33170f2f1d3f030fbf342e44a1baa109a34c31a7..db8bb6e47b28bac6cf568415af3ffdd6eeac6ac7 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java ++++ b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java +@@ -349,7 +349,7 @@ public class Dolphin extends AgeableWaterCreature { + + @Nullable + @Override +- protected SoundEvent getDeathSound() { ++ public SoundEvent getDeathSound() { // Paper - remap fixes + return SoundEvents.DOLPHIN_DEATH; + } + diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java b/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java index f3a2612f0e27c36d5206334307eac1880ce8c4b7..4d4d413b8527e1a109276928611b8c857ad6f6aa 100644 --- a/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java diff --git a/patches/server/0023-Timings-v2.patch b/patches/server/0023-Timings-v2.patch index 5cb8445793f6..91ba72a47462 100644 --- a/patches/server/0023-Timings-v2.patch +++ b/patches/server/0023-Timings-v2.patch @@ -1344,7 +1344,7 @@ index c010d18061f58a583c69e85fc29305497523f569..c8b8102d84119dfb6093f4b79aa3124c private void applyMovementEmissionAndPlaySound(Entity.MovementEmission moveEffect, Vec3 movement, BlockPos landingPos, BlockState landingState) { diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 17ab230c95901f0533997ac117d5b3d852fcd467..0782b2b58ed30d4ef2598e4b89f338a94a62bbe5 100644 +index 17ab230c95901f0533997ac117d5b3d852fcd467..a9ae3d3210e049b0ce066b47378a3f2024154cfd 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -413,6 +413,16 @@ public class EntityType implements FeatureElement, EntityTypeT @@ -1352,9 +1352,9 @@ index 17ab230c95901f0533997ac117d5b3d852fcd467..0782b2b58ed30d4ef2598e4b89f338a9 public EntityType(EntityType.EntityFactory factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet canSpawnInside, EntityDimensions dimensions, float spawnBoxScale, int maxTrackDistance, int trackTickInterval, String translationKey, Optional> lootTable, FeatureFlagSet requiredFeatures) { + // Paper start -+ this(factory, spawnGroup, saveable, summonable, fireImmune, spawnableFarFromPlayer, canSpawnInside, dimensions, spawnBoxScale, maxTrackDistance, trackTickInterval, requiredFeatures, "custom"); ++ this(factory, spawnGroup, saveable, summonable, fireImmune, spawnableFarFromPlayer, canSpawnInside, dimensions, spawnBoxScale, maxTrackDistance, trackTickInterval, translationKey, lootTable, requiredFeatures, "custom"); + } -+ public EntityType(EntityType.EntityFactory factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet canSpawnInside, EntityDimensions dimensions, float spawnBoxScale, int maxTrackDistance, int trackTickInterval, FeatureFlagSet requiredFeatures, String id) { ++ public EntityType(EntityType.EntityFactory factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet canSpawnInside, EntityDimensions dimensions, float spawnBoxScale, int maxTrackDistance, int trackTickInterval, String translationKey, Optional> lootTable, FeatureFlagSet requiredFeatures, String id) { + this.tickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "tick"); + this.inactiveTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "inactiveTick"); + this.passengerTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "passengerTick"); @@ -1378,15 +1378,6 @@ index 17ab230c95901f0533997ac117d5b3d852fcd467..0782b2b58ed30d4ef2598e4b89f338a9 public boolean trackDeltas() { return this != EntityType.PLAYER && this != EntityType.LLAMA_SPIT && this != EntityType.WITHER && this != EntityType.BAT && this != EntityType.ITEM_FRAME && this != EntityType.GLOW_ITEM_FRAME && this != EntityType.LEASH_KNOT && this != EntityType.PAINTING && this != EntityType.END_CRYSTAL && this != EntityType.EVOKER_FANGS; } -@@ -926,7 +943,7 @@ public class EntityType implements FeatureElement, EntityTypeT - Util.fetchChoiceType(References.ENTITY_TREE, registryKey.location().toString()); - } - -- return new EntityType<>(this.factory, this.category, this.serialize, this.summon, this.fireImmune, this.canSpawnFarFromPlayer, this.immuneTo, this.dimensions.withAttachments(this.attachments), this.spawnDimensionsScale, this.clientTrackingRange, this.updateInterval, (String) this.descriptionId.get(registryKey), (Optional) this.lootTable.get(registryKey), this.requiredFeatures); -+ return new EntityType<>(this.factory, this.category, this.serialize, this.summon, this.fireImmune, this.canSpawnFarFromPlayer, this.immuneTo, this.dimensions.withAttachments(this.attachments), this.spawnDimensionsScale, this.clientTrackingRange, this.updateInterval, (String) this.descriptionId.get(registryKey), (Optional) this.lootTable.get(registryKey), this.requiredFeatures, this.id); // Paper - add id - } - } - diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java index 9aa4e70f1d1c4de2138d31701dceaed25062e69c..6cc86412d45186dff312d9b1246fd1d03dbc15d8 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java diff --git a/patches/server/0032-Drop-falling-block-and-tnt-entities-at-the-specified.patch b/patches/server/0032-Drop-falling-block-and-tnt-entities-at-the-specified.patch index 99a9f78c6b95..1fc91e5693fe 100644 --- a/patches/server/0032-Drop-falling-block-and-tnt-entities-at-the-specified.patch +++ b/patches/server/0032-Drop-falling-block-and-tnt-entities-at-the-specified.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Drop falling block and tnt entities at the specified height Co-authored-by: Jake Potrebic diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java -index e9e8ad33371749f52a88a0ee089540eb26fb0f28..5ed77cc6c8b0459691d8044232d9972e4278964b 100644 +index e9e8ad33371749f52a88a0ee089540eb26fb0f28..a5543a6b4811628ff5178a0ec01933ec4b30dfa4 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -159,6 +159,16 @@ public class FallingBlockEntity extends Entity { @@ -15,8 +15,8 @@ index e9e8ad33371749f52a88a0ee089540eb26fb0f28..5ed77cc6c8b0459691d8044232d9972e this.applyEffectsFromBlocks(); + // Paper start - Configurable falling blocks height nerf + if (this.level().paperConfig().fixes.fallingBlockHeightNerf.test(v -> this.getY() > v)) { -+ if (this.dropItem && this.level().getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { -+ this.spawnAtLocation(block); ++ if (this.dropItem && this.level() instanceof final ServerLevel serverLevel && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { ++ this.spawnAtLocation(serverLevel, block); + } + + this.discard(EntityRemoveEvent.Cause.OUT_OF_WORLD); diff --git a/patches/server/0034-Player-affects-spawning-API.patch b/patches/server/0034-Player-affects-spawning-API.patch index 9d430f59c508..e5e9286e9291 100644 --- a/patches/server/0034-Player-affects-spawning-API.patch +++ b/patches/server/0034-Player-affects-spawning-API.patch @@ -60,7 +60,7 @@ index 0594b6adcb849bba2c810de245a3bdaeeca0be60..52d8ea3e40cdb01eab428f5d3d945c0c } diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index 3836d9255ac326a7220e1decd2e9d98be7884c17..ab7500864e3a77444212bce4eb6ea75976f5ee5a 100644 +index 3836d9255ac326a7220e1decd2e9d98be7884c17..73c4585870b7af409f84474f126a58497ed0495f 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java @@ -349,7 +349,7 @@ public class Zombie extends Monster { @@ -68,7 +68,7 @@ index 3836d9255ac326a7220e1decd2e9d98be7884c17..ab7500864e3a77444212bce4eb6ea759 if (SpawnPlacements.isSpawnPositionOk(entitytypes, world, blockposition) && SpawnPlacements.checkSpawnRules(entitytypes, world, EntitySpawnReason.REINFORCEMENT, blockposition, world.random)) { entityzombie.setPos((double) i1, (double) j1, (double) k1); - if (!world.hasNearbyAlivePlayer((double) i1, (double) j1, (double) k1, 7.0D) && world.isUnobstructed(entityzombie) && world.noCollision((Entity) entityzombie) && (entityzombie.canSpawnInLiquids() || !world.containsAnyLiquid(entityzombie.getBoundingBox()))) { -+ if (!world.hasNearbyAlivePlayerhasNearbyAlivePlayerThatAffectsSpawning((double) i1, (double) j1, (double) k1, 7.0D) && world.isUnobstructed(entityzombie) && world.noCollision((Entity) entityzombie) && (entityzombie.canSpawnInLiquids() || !world.containsAnyLiquid(entityzombie.getBoundingBox()))) { // Paper - affects spawning api ++ if (!world.hasNearbyAlivePlayerThatAffectsSpawning((double) i1, (double) j1, (double) k1, 7.0D) && world.isUnobstructed(entityzombie) && world.noCollision((Entity) entityzombie) && (entityzombie.canSpawnInLiquids() || !world.containsAnyLiquid(entityzombie.getBoundingBox()))) { // Paper - affects spawning api entityzombie.setTarget(entityliving, EntityTargetEvent.TargetReason.REINFORCEMENT_TARGET, true); // CraftBukkit entityzombie.finalizeSpawn(world, world.getCurrentDifficultyAt(entityzombie.blockPosition()), EntitySpawnReason.REINFORCEMENT, (SpawnGroupData) null); world.addFreshEntityWithPassengers(entityzombie, CreatureSpawnEvent.SpawnReason.REINFORCEMENTS); // CraftBukkit diff --git a/patches/server/0095-LootTable-API-and-replenishable-lootables.patch b/patches/server/0095-LootTable-API-and-replenishable-lootables.patch index f5dc7e28d10b..45fb79040d64 100644 --- a/patches/server/0095-LootTable-API-and-replenishable-lootables.patch +++ b/patches/server/0095-LootTable-API-and-replenishable-lootables.patch @@ -656,7 +656,7 @@ index a4be7b19b626957efdf2f2507121f0085ba1da50..d528e8e4aea266c495377365f01e3140 public List transaction = new java.util.ArrayList(); private int maxStack = MAX_STACK; diff --git a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java -index beba927cffdeedcd68d8048708f5bf1a409ff965..5c78e33d4d369700a5fa6eb3cbbe85756465a063 100644 +index beba927cffdeedcd68d8048708f5bf1a409ff965..874a44ab77248665c2db243764e8542bfc0d6514 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java @@ -62,22 +62,26 @@ public interface ContainerEntity extends Container, MenuProvider { @@ -678,7 +678,7 @@ index beba927cffdeedcd68d8048708f5bf1a409ff965..5c78e33d4d369700a5fa6eb3cbbe8575 if (nbt.contains("LootTable", 8)) { this.setContainerLootTable(ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(nbt.getString("LootTable")))); + // Paper start - LootTable API -+ if (this.getLootTable() != null) { ++ if (this.getContainerLootTable() != null) { + this.lootableData().loadNbt(nbt); + } + // Paper end - LootTable API diff --git a/patches/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch b/patches/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch index 55202f63eb4e..bf9d10bb7ea0 100644 --- a/patches/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch +++ b/patches/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Filter bad block entity nbt data from falling blocks diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java -index 5ed77cc6c8b0459691d8044232d9972e4278964b..84d9ae7be1bc9b2c4940cc69de24abf7e4c228b3 100644 +index a5543a6b4811628ff5178a0ec01933ec4b30dfa4..72abeb4f37b70094498ed3b18e8f73346ba0ead0 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -356,7 +356,7 @@ public class FallingBlockEntity extends Entity { diff --git a/patches/server/0166-PreCreatureSpawnEvent.patch b/patches/server/0166-PreCreatureSpawnEvent.patch index e9253fbfd99e..2a845a497c57 100644 --- a/patches/server/0166-PreCreatureSpawnEvent.patch +++ b/patches/server/0166-PreCreatureSpawnEvent.patch @@ -55,7 +55,7 @@ index e139ed6bc6f2dd07fe546588b31309ba30ed9755..34c3bf85473b3ad89355ebc21b68c59b if (t0 != null) { diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 0782b2b58ed30d4ef2598e4b89f338a94a62bbe5..7fb2155b8d320f8871556083aef9ed8e1e91e6e7 100644 +index a9ae3d3210e049b0ce066b47378a3f2024154cfd..47fe53ed2f50f1a7ed9f324adf9fc73a6ecc184a 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -507,6 +507,16 @@ public class EntityType implements FeatureElement, EntityTypeT diff --git a/patches/server/0267-Add-more-Zombie-API.patch b/patches/server/0267-Add-more-Zombie-API.patch index 26bdc7ae87da..f018f7e612bb 100644 --- a/patches/server/0267-Add-more-Zombie-API.patch +++ b/patches/server/0267-Add-more-Zombie-API.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Add more Zombie API public net.minecraft.world.entity.monster.Zombie isSunSensitive()Z diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index ab7500864e3a77444212bce4eb6ea75976f5ee5a..81d27114bd081096612e50a8cb93cae772cf46eb 100644 +index 73c4585870b7af409f84474f126a58497ed0495f..d3d1e170380e7674c9ac13b06186eb563a58cd64 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java @@ -99,6 +99,7 @@ public class Zombie extends Monster { diff --git a/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch b/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch index 6dc2b28b312d..776b020ee88c 100644 --- a/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch +++ b/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch @@ -116,7 +116,7 @@ index 5d551a50e1043e369ebf3ddfe181be1e24cfd068..463d34e7b54efd503c4879d1386b2439 } catch (Throwable throwable) { diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 7fb2155b8d320f8871556083aef9ed8e1e91e6e7..ab02f4ca0bb8cd4939f167b410db208e38f7102b 100644 +index 47fe53ed2f50f1a7ed9f324adf9fc73a6ecc184a..9fe4027aa16d73d806f51a7c195a5cf0468ebba3 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -443,7 +443,7 @@ public class EntityType implements FeatureElement, EntityTypeT diff --git a/patches/server/0307-Bees-get-gravity-in-void.-Fixes-MC-167279.patch b/patches/server/0307-Bees-get-gravity-in-void.-Fixes-MC-167279.patch index f91f8b04220c..cf391a4f9f7f 100644 --- a/patches/server/0307-Bees-get-gravity-in-void.-Fixes-MC-167279.patch +++ b/patches/server/0307-Bees-get-gravity-in-void.-Fixes-MC-167279.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Bees get gravity in void. Fixes MC-167279 diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java -index 310a2aa23365f9a8a8b7b6fa2323aed792f95adb..8c7943fdb56cd75c362e47e6c934bde5a714adaa 100644 +index 310a2aa23365f9a8a8b7b6fa2323aed792f95adb..adff3bec90786b87323653cf4f94a38c7b9ef7ff 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Bee.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java @@ -150,7 +150,22 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @@ -21,7 +21,7 @@ index 310a2aa23365f9a8a8b7b6fa2323aed792f95adb..8c7943fdb56cd75c362e47e6c934bde5 + + @Override + public void tick() { -+ if (this.mob.getY() <= Bee.this.level().getMinBuildHeight()) { ++ if (this.mob.getY() <= Bee.this.level().getMinY()) { + this.mob.setNoGravity(false); + } + super.tick(); diff --git a/patches/server/0319-Configurable-chance-of-villager-zombie-infection.patch b/patches/server/0319-Configurable-chance-of-villager-zombie-infection.patch index d71db6d82415..e26452bb88e3 100644 --- a/patches/server/0319-Configurable-chance-of-villager-zombie-infection.patch +++ b/patches/server/0319-Configurable-chance-of-villager-zombie-infection.patch @@ -8,7 +8,7 @@ This allows you to solve an issue in vanilla behavior where: * On normal difficulty they will have a 50% of getting infected or dying. diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index 81d27114bd081096612e50a8cb93cae772cf46eb..2ed71c9a091bedea276f9043fb0c082dd250cdae 100644 +index d3d1e170380e7674c9ac13b06186eb563a58cd64..5b8ac7113eb8a57fe07bfaacc1b1320383a56d06 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java @@ -484,10 +484,8 @@ public class Zombie extends Monster { diff --git a/patches/server/0356-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch b/patches/server/0356-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch index a854b3123bf9..1a72e117f560 100644 --- a/patches/server/0356-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch +++ b/patches/server/0356-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch @@ -6,14 +6,14 @@ Subject: [PATCH] Ensure EntityRaider respects game and entity rules for diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java -index 96c6a2a6cb015d4ac90f98ce48a4c345ab72fd7a..4b9b961b1b910775788f85b13ee48abcc474daca 100644 +index 96c6a2a6cb015d4ac90f98ce48a4c345ab72fd7a..6ac2351b3476aa04872196836ce00c622adab315 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raider.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java @@ -338,6 +338,7 @@ public abstract class Raider extends PatrollingMonster { } private boolean cannotPickUpBanner() { -+ if (!this.mob.level().getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING) || !this.mob.canPickUpLoot()) return false; // Paper - respect game and entity rules for picking up items ++ if (!getServerLevel(this.mob).getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING) || !this.mob.canPickUpLoot()) return false; // Paper - respect game and entity rules for picking up items if (!this.mob.hasActiveRaid()) { return true; } else if (this.mob.getCurrentRaid().isOver()) { diff --git a/patches/server/0397-Add-zombie-targets-turtle-egg-config.patch b/patches/server/0397-Add-zombie-targets-turtle-egg-config.patch index 2fb3a9a22c9d..73a1b707b4c6 100644 --- a/patches/server/0397-Add-zombie-targets-turtle-egg-config.patch +++ b/patches/server/0397-Add-zombie-targets-turtle-egg-config.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add zombie targets turtle egg config diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index 2ed71c9a091bedea276f9043fb0c082dd250cdae..9adcaa646dff7f5415a467a2bfe5b817e17f5640 100644 +index 5b8ac7113eb8a57fe07bfaacc1b1320383a56d06..c182bdcc5da5652f8b34b4cb8d28651cf79009fe 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java @@ -112,7 +112,7 @@ public class Zombie extends Monster { diff --git a/patches/server/0458-Add-world-settings-for-mobs-picking-up-loot.patch b/patches/server/0458-Add-world-settings-for-mobs-picking-up-loot.patch index 4d332f01e661..9e08c62541b3 100644 --- a/patches/server/0458-Add-world-settings-for-mobs-picking-up-loot.patch +++ b/patches/server/0458-Add-world-settings-for-mobs-picking-up-loot.patch @@ -18,7 +18,7 @@ index 8f63e27d904abb33492daf627d48d33d1193deef..723a098eabcc632caeb096f39c90e4e0 LocalDate localdate = LocalDate.now(); int i = localdate.get(ChronoField.DAY_OF_MONTH); diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index 9adcaa646dff7f5415a467a2bfe5b817e17f5640..4477d1a82a49e391760689eb991d1595995914f5 100644 +index c182bdcc5da5652f8b34b4cb8d28651cf79009fe..34e46a64b3638f749a571d080fd8e7ac1f57edba 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java @@ -518,7 +518,7 @@ public class Zombie extends Monster { diff --git a/patches/server/0462-Configurable-door-breaking-difficulty.patch b/patches/server/0462-Configurable-door-breaking-difficulty.patch index 76df839d0d77..94b37c735f6f 100644 --- a/patches/server/0462-Configurable-door-breaking-difficulty.patch +++ b/patches/server/0462-Configurable-door-breaking-difficulty.patch @@ -23,7 +23,7 @@ index b06eedb1cb13771bbc7d0b812a9df864d1f73142..96b105697c91314148fd1b7835013892 } diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index 4477d1a82a49e391760689eb991d1595995914f5..6dc9fc3451edec01f11f526c05d84138c46a3a8e 100644 +index 34e46a64b3638f749a571d080fd8e7ac1f57edba..a835ec6e063dd247a008da84446f8647f38d89d4 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java @@ -103,7 +103,7 @@ public class Zombie extends Monster { diff --git a/patches/server/0553-Missing-Entity-API.patch b/patches/server/0553-Missing-Entity-API.patch index 564422f36b7e..b583f5319160 100644 --- a/patches/server/0553-Missing-Entity-API.patch +++ b/patches/server/0553-Missing-Entity-API.patch @@ -128,7 +128,7 @@ index 30095df7b64cfda4931dbfa22549ff5abefd53e0..c8ae49f58c254119c0e64a4e1501ebc5 this.leader = null; } diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java -index 8c7943fdb56cd75c362e47e6c934bde5a714adaa..63e068c1a2d98c9c07dbabd1fa574d6b44e1a2fb 100644 +index adff3bec90786b87323653cf4f94a38c7b9ef7ff..048a357546c8f5ad5dbb86e2e1ada2730a52d061 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Bee.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java @@ -561,11 +561,13 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { diff --git a/patches/server/0561-Add-missing-forceDrop-toggles.patch b/patches/server/0561-Add-missing-forceDrop-toggles.patch index b718ecea36d1..acc8574a8135 100644 --- a/patches/server/0561-Add-missing-forceDrop-toggles.patch +++ b/patches/server/0561-Add-missing-forceDrop-toggles.patch @@ -93,7 +93,7 @@ index 42b1bd58c6e2c3bd1170171eabfefe315202f340..55868c82bf8bd61ce3494aa9f363c20c } diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java -index 4b9b961b1b910775788f85b13ee48abcc474daca..69a0a8aa7eec0a68a1460f6d6a4b604963b884c4 100644 +index 6ac2351b3476aa04872196836ce00c622adab315..45375ccdcf730732dd915304dea2f523807eedd6 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raider.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java @@ -233,7 +233,9 @@ public abstract class Raider extends PatrollingMonster { diff --git a/patches/server/0617-prevent-unintended-light-block-manipulation.patch b/patches/server/0617-prevent-unintended-light-block-manipulation.patch index 12d564474a9c..b8ca20506417 100644 --- a/patches/server/0617-prevent-unintended-light-block-manipulation.patch +++ b/patches/server/0617-prevent-unintended-light-block-manipulation.patch @@ -5,27 +5,17 @@ Subject: [PATCH] prevent unintended light block manipulation diff --git a/src/main/java/net/minecraft/world/level/block/LightBlock.java b/src/main/java/net/minecraft/world/level/block/LightBlock.java -index 6c3ca57a29d3c5ad1add1cf2f707b930dfc422ea..606c9b03cc69031faed33f437ca254f12224bb62 100644 +index 6c3ca57a29d3c5ad1add1cf2f707b930dfc422ea..fec6bf38f080039436ba80d5528857ba4787bf4e 100644 --- a/src/main/java/net/minecraft/world/level/block/LightBlock.java +++ b/src/main/java/net/minecraft/world/level/block/LightBlock.java -@@ -5,7 +5,9 @@ import java.util.function.ToIntFunction; - import net.minecraft.core.BlockPos; - import net.minecraft.core.Direction; - import net.minecraft.core.component.DataComponents; -+import net.minecraft.server.level.ServerLevel; - import net.minecraft.util.RandomSource; -+import net.minecraft.world.InteractionHand; - import net.minecraft.world.InteractionResult; - import net.minecraft.world.entity.player.Player; - import net.minecraft.world.item.ItemStack; -@@ -50,6 +52,14 @@ public class LightBlock extends Block implements SimpleWaterloggedBlock { +@@ -50,6 +50,14 @@ public class LightBlock extends Block implements SimpleWaterloggedBlock { builder.add(LEVEL, WATERLOGGED); } + // Paper start - prevent unintended light block manipulation + @Override -+ protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { -+ if (player.getItemInHand(hand).getItem() != Items.LIGHT || (world instanceof final ServerLevel serverLevel && !player.mayInteract(serverLevel, pos)) || !player.mayUseItemAt(pos, hit.getDirection(), player.getItemInHand(hand))) { return net.minecraft.world.InteractionResult.PASS; } // Paper - Prevent unintended light block manipulation ++ protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, net.minecraft.world.InteractionHand hand, BlockHitResult hit) { ++ if (player.getItemInHand(hand).getItem() != Items.LIGHT || (world instanceof final net.minecraft.server.level.ServerLevel serverLevel && !player.mayInteract(serverLevel, pos)) || !player.mayUseItemAt(pos, hit.getDirection(), player.getItemInHand(hand))) { return net.minecraft.world.InteractionResult.PASS; } // Paper - Prevent unintended light block manipulation + return super.useItemOn(stack, state, world, pos, player, hand, hit); + } + // Paper end - prevent unintended light block manipulation diff --git a/patches/server/0648-Fix-xp-reward-for-baby-zombies.patch b/patches/server/0648-Fix-xp-reward-for-baby-zombies.patch index 3c16a1caf672..3ec320760f08 100644 --- a/patches/server/0648-Fix-xp-reward-for-baby-zombies.patch +++ b/patches/server/0648-Fix-xp-reward-for-baby-zombies.patch @@ -9,7 +9,7 @@ so this resets it after each call to Zombie#getExperienceReward diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index 6dc9fc3451edec01f11f526c05d84138c46a3a8e..17974f85d3c1db549ea11e8809954cd9d2af063e 100644 +index a835ec6e063dd247a008da84446f8647f38d89d4..94b3ba2688676e92d9d093b63d92cab39d5d2f02 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java @@ -174,11 +174,16 @@ public class Zombie extends Monster { diff --git a/patches/server/0679-Fix-new-block-data-for-EntityChangeBlockEvent.patch b/patches/server/0679-Fix-new-block-data-for-EntityChangeBlockEvent.patch index 0e8243655b45..fce021dda2b9 100644 --- a/patches/server/0679-Fix-new-block-data-for-EntityChangeBlockEvent.patch +++ b/patches/server/0679-Fix-new-block-data-for-EntityChangeBlockEvent.patch @@ -117,7 +117,7 @@ index c661ae4e5c07494c7de852cc8d01f0f9839c1590..c96fbfe448b3e7b722a8db0e16882767 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/monster/Silverfish.java b/src/main/java/net/minecraft/world/entity/monster/Silverfish.java -index 52d8ea3e40cdb01eab428f5d3d945c0c9f6088ce..1580c8b93a4ea1a9f2d7bf9c589ef64e070e3f53 100644 +index 52d8ea3e40cdb01eab428f5d3d945c0c9f6088ce..ff65cb8ea5233f2dd159f42ad53bc9d300cd604f 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Silverfish.java +++ b/src/main/java/net/minecraft/world/entity/monster/Silverfish.java @@ -165,7 +165,8 @@ public class Silverfish extends Monster { @@ -125,7 +125,7 @@ index 52d8ea3e40cdb01eab428f5d3d945c0c9f6088ce..1580c8b93a4ea1a9f2d7bf9c589ef64e if (block instanceof InfestedBlock) { // CraftBukkit start - if (!CraftEventFactory.callEntityChangeBlockEvent(this.silverfish, blockposition1, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState())) { -+ BlockState afterState = world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? iblockdata.getFluidState().createLegacyBlock() : ((InfestedBlock) block).hostStateByInfested(world.getBlockState(blockposition1)); // Paper - fix wrong block state ++ BlockState afterState = getServerLevel(world).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? iblockdata.getFluidState().createLegacyBlock() : ((InfestedBlock) block).hostStateByInfested(world.getBlockState(blockposition1)); // Paper - fix wrong block state + if (!CraftEventFactory.callEntityChangeBlockEvent(this.silverfish, blockposition1, afterState)) { // Paper - fix wrong block state continue; } diff --git a/patches/server/0696-Expand-FallingBlock-API.patch b/patches/server/0696-Expand-FallingBlock-API.patch index c1e3824d7bc3..7992fef97214 100644 --- a/patches/server/0696-Expand-FallingBlock-API.patch +++ b/patches/server/0696-Expand-FallingBlock-API.patch @@ -13,7 +13,7 @@ public net.minecraft.world.entity.item.FallingBlockEntity blockState Co-authored-by: Lukas Planz diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java -index 84d9ae7be1bc9b2c4940cc69de24abf7e4c228b3..c228ca3ee911d25932932564b73e182840963e7d 100644 +index 72abeb4f37b70094498ed3b18e8f73346ba0ead0..0ecda05a98046938546fe7bc6cf2590c886add41 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -71,6 +71,7 @@ public class FallingBlockEntity extends Entity { diff --git a/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch b/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch index 2aee33da0509..4f072bfdb004 100644 --- a/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch +++ b/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch @@ -24,7 +24,7 @@ index 37111113f6ab6d77c558b10c4162758135db99b0..911b6391455402922e8bd52cfe9e5694 EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity()); Bukkit.getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java -index 33170f2f1d3f030fbf342e44a1baa109a34c31a7..b99e5878b3094ba25084b756c058510bc39f941a 100644 +index db8bb6e47b28bac6cf568415af3ffdd6eeac6ac7..34f35502faf2029525a8e0a8f347456b2868804b 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java +++ b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java @@ -604,7 +604,7 @@ public class Dolphin extends AgeableWaterCreature { diff --git a/patches/server/0715-Fix-Bee-flower-NPE.patch b/patches/server/0715-Fix-Bee-flower-NPE.patch index 6ac238b67a6c..d84bd3a355c0 100644 --- a/patches/server/0715-Fix-Bee-flower-NPE.patch +++ b/patches/server/0715-Fix-Bee-flower-NPE.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix Bee flower NPE diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java -index 63e068c1a2d98c9c07dbabd1fa574d6b44e1a2fb..3f775aeed0afb5c4f19cbb17bf7bd9f7cfdc3adb 100644 +index 048a357546c8f5ad5dbb86e2e1ada2730a52d061..42276acfeadec6e7aa9a91d3f446f4fedb04829d 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Bee.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java @@ -940,7 +940,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { diff --git a/patches/server/0741-Fix-a-bunch-of-vanilla-bugs.patch b/patches/server/0741-Fix-a-bunch-of-vanilla-bugs.patch index 051aef0e0efc..023d12d11ed7 100644 --- a/patches/server/0741-Fix-a-bunch-of-vanilla-bugs.patch +++ b/patches/server/0741-Fix-a-bunch-of-vanilla-bugs.patch @@ -235,7 +235,7 @@ index dbcf14f5af9c9c0655a82529ee99450a8da14525..f745a554b9b84a53d9bd942ca9908153 } diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -index 30af4cbb17148c247a46c0346419d6c838dbc9d2..07c143c3eac263848fc5daf6f958d16a1a163e92 100644 +index 30af4cbb17148c247a46c0346419d6c838dbc9d2..65f7f1f98f415a564aadb440d3a67143699e43db 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java @@ -272,6 +272,14 @@ public class ItemFrame extends HangingEntity { @@ -245,8 +245,8 @@ index 30af4cbb17148c247a46c0346419d6c838dbc9d2..07c143c3eac263848fc5daf6f958d16a + // Paper start - Fix MC-123848 (spawn item frame drops above block) + @Nullable + @Override -+ public net.minecraft.world.entity.item.ItemEntity spawnAtLocation(ItemStack stack) { -+ return this.spawnAtLocation(stack, getDirection().equals(Direction.DOWN) ? -0.6F : 0.0F); ++ public net.minecraft.world.entity.item.ItemEntity spawnAtLocation(ServerLevel serverLevel, ItemStack stack) { ++ return this.spawnAtLocation(serverLevel, stack, getDirection().equals(Direction.DOWN) ? -0.6F : 0.0F); + } + // Paper end + diff --git a/patches/server/0744-EntityPickupItemEvent-fixes.patch b/patches/server/0744-EntityPickupItemEvent-fixes.patch index 6e30e2ebcbe9..9d6076ced99b 100644 --- a/patches/server/0744-EntityPickupItemEvent-fixes.patch +++ b/patches/server/0744-EntityPickupItemEvent-fixes.patch @@ -56,7 +56,7 @@ index 5c26beef2d3f3d4afa51950ddeb7089989218462..e283b1296c1e831376bfe9491cbf02ed if (!flag) { PiglinAi.putInInventory(piglin, itemstack); diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java -index 69a0a8aa7eec0a68a1460f6d6a4b604963b884c4..02f2107285d1bbe2137afd4f94880ad1f9d82fb9 100644 +index 45375ccdcf730732dd915304dea2f523807eedd6..2eb1ad88bd39b3e6539d6c4ac61fb1d58edb5eb2 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raider.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java @@ -228,6 +228,11 @@ public abstract class Raider extends PatrollingMonster { @@ -64,7 +64,7 @@ index 69a0a8aa7eec0a68a1460f6d6a4b604963b884c4..02f2107285d1bbe2137afd4f94880ad1 if (this.hasActiveRaid() && !flag && ItemStack.matches(itemstack, Raid.getOminousBannerInstance(this.registryAccess().lookupOrThrow(Registries.BANNER_PATTERN)))) { + // Paper start - EntityPickupItemEvent fixes -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, item, 0, false).isCancelled()) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, itemstack, 0, false).isCancelled()) { + return; + } + // Paper end - EntityPickupItemEvent fixes diff --git a/patches/server/0782-config-for-disabling-entity-tag-tags.patch b/patches/server/0782-config-for-disabling-entity-tag-tags.patch index c3be8a0eeae4..d0d803196aec 100644 --- a/patches/server/0782-config-for-disabling-entity-tag-tags.patch +++ b/patches/server/0782-config-for-disabling-entity-tag-tags.patch @@ -5,7 +5,7 @@ Subject: [PATCH] config for disabling entity tag tags diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index ab02f4ca0bb8cd4939f167b410db208e38f7102b..6b2f0a4bc911888b72b796099760af38b1e28656 100644 +index 9fe4027aa16d73d806f51a7c195a5cf0468ebba3..9be3f9b218b28fe8dde6321d8377232fbc634ee3 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -579,6 +579,16 @@ public class EntityType implements FeatureElement, EntityTypeT diff --git a/patches/server/0845-Cache-map-ids-on-item-frames.patch b/patches/server/0845-Cache-map-ids-on-item-frames.patch index 7b1ac525686f..38554e1a9c2f 100644 --- a/patches/server/0845-Cache-map-ids-on-item-frames.patch +++ b/patches/server/0845-Cache-map-ids-on-item-frames.patch @@ -18,7 +18,7 @@ index 3cdcc4f44608d24550f2a8c6f3f5ce675d7777c5..7118e1f806af98159ec292f9340d7e40 if (worldmap != null) { diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -index 07c143c3eac263848fc5daf6f958d16a1a163e92..f046a866215fea7df10963af1a235ba9d04d4242 100644 +index 65f7f1f98f415a564aadb440d3a67143699e43db..d6f835320014c07f9d174d05929ed8cc16a10c10 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java @@ -51,6 +51,7 @@ public class ItemFrame extends HangingEntity { diff --git a/patches/server/0900-Don-t-fire-sync-events-during-worldgen.patch b/patches/server/0900-Don-t-fire-sync-events-during-worldgen.patch index 53a3932e6f5a..bc57e531f9ca 100644 --- a/patches/server/0900-Don-t-fire-sync-events-during-worldgen.patch +++ b/patches/server/0900-Don-t-fire-sync-events-during-worldgen.patch @@ -48,7 +48,7 @@ index e9142414c7d247ae2a27c0bc9ea2be3bb8e3db16..1d66c35b1092b8101f0a803d8c087e5a this.entityData.set(Entity.DATA_POSE, pose); } diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 6b2f0a4bc911888b72b796099760af38b1e28656..4eec58353343b414120e189afed04b98ae3e87c8 100644 +index 9be3f9b218b28fe8dde6321d8377232fbc634ee3..d036b02af0a4f63bd1e4e306f1ecd102b3d991fb 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -659,9 +659,15 @@ public class EntityType implements FeatureElement, EntityTypeT @@ -56,7 +56,7 @@ index 6b2f0a4bc911888b72b796099760af38b1e28656..4eec58353343b414120e189afed04b98 public static Optional create(CompoundTag nbt, Level world, EntitySpawnReason reason) { + // Paper start - Don't fire sync event during generation -+ return create(nbt, world, false); ++ return create(nbt, world, reason, false); + } + public static Optional create(CompoundTag nbt, Level world, EntitySpawnReason reason, boolean generation) { + // Paper end - Don't fire sync event during generation diff --git a/patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch b/patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch index 05754abc5d43..75089641a980 100644 --- a/patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch +++ b/patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch @@ -53,7 +53,7 @@ index 084935138b1484f3d96e99f4e5655a6c04931907..9e357abe13f55bd9ce3a1d5348bcf19a if (nbt.contains("LootTableSeed", 4)) { this.setLootTableSeed(nbt.getLong("LootTableSeed")); diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 4eec58353343b414120e189afed04b98ae3e87c8..d77014aadf83088fb53f30a9dbe879f3089e159e 100644 +index d036b02af0a4f63bd1e4e306f1ecd102b3d991fb..97ad6cd38adbe8a7b2ea6e2a5a339bd67b81b5bd 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -690,7 +690,7 @@ public class EntityType implements FeatureElement, EntityTypeT @@ -129,7 +129,7 @@ index 75cc3db39c974abab8510af4a633fc6812efc647..14e31ae88e90d8ea1a98800cc6c1c352 if (nbt.contains("item", 10)) { diff --git a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java -index 5c78e33d4d369700a5fa6eb3cbbe85756465a063..35f90e06dcf30c2e6a2a63e81215283ffbb3ec05 100644 +index 874a44ab77248665c2db243764e8542bfc0d6514..cc7826a10f22e3307231d887db2fee98063b1f46 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java @@ -73,7 +73,7 @@ public interface ContainerEntity extends Container, MenuProvider { @@ -139,7 +139,7 @@ index 5c78e33d4d369700a5fa6eb3cbbe85756465a063..35f90e06dcf30c2e6a2a63e81215283f - this.setContainerLootTable(ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(nbt.getString("LootTable")))); + this.setContainerLootTable(net.minecraft.Optionull.map(ResourceLocation.tryParse(nbt.getString("LootTable")), rl -> ResourceKey.create(Registries.LOOT_TABLE, rl))); // Paper - Validate ResourceLocation // Paper start - LootTable API - if (this.getLootTable() != null) { + if (this.getContainerLootTable() != null) { this.lootableData().loadNbt(nbt); diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java index ecb9abc570ef87541184a8033cb33c82a4d1daf2..a1ac34668fcd53cf8adf4ce463e0254b26575fbf 100644 diff --git a/patches/server/0992-Configurable-Sand-Duping.patch b/patches/server/0992-Configurable-Sand-Duping.patch index 6564a54e0ea9..d209e03e1e80 100644 --- a/patches/server/0992-Configurable-Sand-Duping.patch +++ b/patches/server/0992-Configurable-Sand-Duping.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Configurable Sand Duping diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java -index c228ca3ee911d25932932564b73e182840963e7d..d405ec0a6bb1e813cdf42d8e12db143df2d173b4 100644 +index 0ecda05a98046938546fe7bc6cf2590c886add41..06d9a519e64d4b8b8764b3ad7691ad93b5cee065 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -435,7 +435,7 @@ public class FallingBlockEntity extends Entity { diff --git a/patches/server/1018-Fix-InventoryOpenEvent-cancellation.patch b/patches/server/1018-Fix-InventoryOpenEvent-cancellation.patch index 22702eee548d..6f31e5f36371 100644 --- a/patches/server/1018-Fix-InventoryOpenEvent-cancellation.patch +++ b/patches/server/1018-Fix-InventoryOpenEvent-cancellation.patch @@ -51,7 +51,7 @@ index 8033abfd77bcc20326b992a9d81e2faa9582fb83..1f4cc08e84a23213bb9786ea09ad77ca PiglinAi.angerNearbyPiglins(worldserver, player, true); } diff --git a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java -index 35f90e06dcf30c2e6a2a63e81215283ffbb3ec05..5e7a5248852319471525019b3efcfdb730a9af46 100644 +index cc7826a10f22e3307231d887db2fee98063b1f46..45f6191cc8e2ecdacbc2df0ddb5ea7cc6a546812 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java @@ -95,7 +95,11 @@ public interface ContainerEntity extends Container, MenuProvider { diff --git a/patches/server/1025-Remove-wall-time-unused-skip-tick-protection.patch b/patches/server/1025-Remove-wall-time-unused-skip-tick-protection.patch index 7db8f330bd39..da0d05dd0d5d 100644 --- a/patches/server/1025-Remove-wall-time-unused-skip-tick-protection.patch +++ b/patches/server/1025-Remove-wall-time-unused-skip-tick-protection.patch @@ -91,7 +91,7 @@ index 246b5649883e4f305afa5a887b9df0f3735f7593..5d8885bca55503bf7e1a2a4e1bb9b3bd if (!this.level().isClientSide && this.age >= this.despawnRate) { // Spigot // Paper - Alternative item-despawn-rate // CraftBukkit start - fire ItemDespawnEvent diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index 17974f85d3c1db549ea11e8809954cd9d2af063e..5a6e119d29ecdc45dee40d5984e502fb8e4d1543 100644 +index 94b3ba2688676e92d9d093b63d92cab39d5d2f02..a12461907278cfbfa3b1c0aa74b9f07a31768b8a 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java @@ -98,7 +98,7 @@ public class Zombie extends Monster { From 6fb86bb20a492c5a4f786eb03475940a007199a9 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Fri, 25 Oct 2024 13:52:04 +0200 Subject: [PATCH 053/119] Compiler issues v2 --- .../api/0063-Add-getI18NDisplayName-API.patch | 4 ++-- .../0064-ensureServerConversions-API.patch | 4 ++-- .../0166-Fix-Spigot-annotation-mistakes.patch | 2 +- ...ate-HoverEvent-from-ItemStack-Entity.patch | 2 +- .../api/0340-Add-enchantWithLevels-API.patch | 2 +- ...Levels-with-enchantment-registry-set.patch | 2 +- patches/server/0010-Adventure.patch | 8 ++++---- patches/server/0023-Timings-v2.patch | 2 +- .../0034-Player-affects-spawning-API.patch | 2 +- ...035-Only-refresh-abilities-if-needed.patch | 2 +- .../0048-Use-null-Locale-by-default.patch | 2 +- ...055-Improve-Player-chat-API-handling.patch | 2 +- .../0059-Player-Tab-List-and-Title-APIs.patch | 2 +- .../0066-Complete-resource-pack-API.patch | 2 +- ...th-absorb-values-and-repair-bad-data.patch | 2 +- ...able-API-and-replenishable-lootables.patch | 6 +++--- ...8-Optional-TNT-doesn-t-move-in-water.patch | 4 ++-- .../0119-String-based-Action-Bar-API.patch | 2 +- .../0144-Implement-getI18NDisplayName.patch | 4 ++-- ...nt-protocol-version-and-virtual-host.patch | 2 +- ...3-Ability-to-apply-mending-to-XP-API.patch | 2 +- .../0176-Player.setPlayerProfile-API.patch | 2 +- ...81-Flag-to-disable-the-channel-limit.patch | 2 +- .../0207-InventoryCloseEvent-Reason-API.patch | 2 +- ...e-attack-cooldown-methods-for-Player.patch | 2 +- .../server/0241-Improve-death-events.patch | 2 +- ...-Replace-OfflinePlayer-getLastPlayed.patch | 2 +- ...r-remove-if-the-handle-is-a-custom-p.patch | 2 +- ...-Implement-Player-Client-Options-API.patch | 2 +- patches/server/0389-Brand-support.patch | 2 +- ...ate-HoverEvent-from-ItemStack-Entity.patch | 4 ++-- ...r-spawnParticle-x-y-z-precision-loss.patch | 2 +- patches/server/0466-Add-sendOpLevel-API.patch | 2 +- ...527-Expand-PlayerGameModeChangeEvent.patch | 2 +- .../0539-Add-PlayerKickEvent-causes.patch | 2 +- .../server/0566-Add-PlayerSetSpawnEvent.patch | 2 +- ...0583-Add-ItemFactory-getSpawnEgg-API.patch | 4 ++-- ...ulti-Block-Change-API-Implementation.patch | 2 +- ...666-Force-close-world-loading-screen.patch | 4 ++-- ...0675-Implement-enchantWithLevels-API.patch | 4 ++-- ...tead-of-display-name-in-PlayerList-g.patch | 2 +- ...us-missing-EntityDropItemEvent-calls.patch | 18 +++++++++--------- ...g-not-using-commands.spam-exclusions.patch | 19 ------------------- ...API.patch => 0716-More-Teleport-API.patch} | 6 +++--- ... => 0717-Add-EntityPortalReadyEvent.patch} | 0 ...level-random-in-entity-constructors.patch} | 2 +- ...k-entities-after-destroy-prediction.patch} | 2 +- ...on-plugins-accessing-faraway-chunks.patch} | 0 ...tom-Chat-Completion-Suggestions-API.patch} | 2 +- ...Add-and-fix-missing-BlockFadeEvents.patch} | 0 ...ion-API.patch => 0723-Collision-API.patch} | 0 ...nd-message-for-brigadier-syntax-exc.patch} | 0 ...API.patch => 0725-Block-Ticking-API.patch} | 0 ...-Add-Velocity-IP-Forwarding-Support.patch} | 0 ...727-Add-NamespacedKey-biome-methods.patch} | 0 ...x-plugin-loggers-on-server-shutdown.patch} | 0 ...ok-changes-from-crashing-the-server.patch} | 0 ...tityChangeBlockEvent-in-more-places.patch} | 0 ...> 0731-Missing-eating-regain-reason.patch} | 0 ....patch => 0732-Missing-effect-cause.patch} | 0 ...serialization-deserialization-for-P.patch} | 0 ...4-Call-BlockPhysicsEvent-more-often.patch} | 0 ...0735-Configurable-chat-thread-limit.patch} | 0 ...of-WorldCreator-keepSpawnLoaded-ret.patch} | 0 ... 0737-fix-Jigsaw-block-kicking-user.patch} | 0 ...mEvent-for-mud-converting-into-clay.patch} | 0 ... => 0739-Add-getDrops-to-BlockState.patch} | 0 ...=> 0740-Fix-a-bunch-of-vanilla-bugs.patch} | 6 +++--- ...y-onTrackingStart-during-navigation.patch} | 0 ... 0742-Fix-custom-piglin-loved-items.patch} | 0 ...=> 0743-EntityPickupItemEvent-fixes.patch} | 4 ++-- ...interactions-with-items-on-cooldown.patch} | 0 ...-Add-PlayerInventorySlotChangeEvent.patch} | 0 ... 0746-Elder-Guardian-appearance-API.patch} | 2 +- ...ch => 0747-Add-entity-knockback-API.patch} | 0 ....patch => 0748-Detect-headless-JREs.patch} | 0 ...-vehicle-collision-event-not-called.patch} | 0 ...ch => 0750-Add-EntityToggleSitEvent.patch} | 2 +- ... => 0751-Add-fire-tick-delay-option.patch} | 0 ...patch => 0752-Add-Moving-Piston-API.patch} | 0 ...> 0753-Ignore-impossible-spawn-tick.patch} | 0 ...t-and-EntitySelectorParser-permissi.patch} | 0 ...Event-cancellation-cant-fully-preve.patch} | 0 ...0756-Add-PrePlayerAttackEntityEvent.patch} | 0 ...e-reset-EnderDragon-boss-event-name.patch} | 0 ... 0758-Add-Player-Warden-Warning-API.patch} | 2 +- ...a-friendly-methods-to-update-trades.patch} | 0 ...760-Add-paper-dumplisteners-command.patch} | 0 ...lobal-player-list-where-appropriate.patch} | 0 ...sync-entity-add-due-to-fungus-trees.patch} | 0 ....patch => 0763-ItemStack-damage-API.patch} | 17 ++++++++++------- ...tion-API.patch => 0764-Friction-API.patch} | 0 ...trol-player-s-insomnia-and-phantoms.patch} | 0 ...-premature-player-kicks-on-shutdown.patch} | 0 ... => 0767-Sync-offhand-slot-in-menus.patch} | 0 ... 0768-Player-Entity-Tracking-Events.patch} | 0 ...tch => 0769-Limit-pet-look-distance.patch} | 0 ...ments.patch => 0770-fix-Instruments.patch} | 2 +- ...for-some-hot-BlockBehavior-and-Flui.patch} | 0 ...tch => 0772-Add-BlockLockCheckEvent.patch} | 0 ... 0773-Add-Sneaking-API-for-Entities.patch} | 0 ... => 0774-Improve-logging-and-errors.patch} | 2 +- ....patch => 0775-Improve-PortalEvents.patch} | 0 ...ion-for-spider-worldborder-climbing.patch} | 0 ...sing-SpigotConfig-logCommands-check.patch} | 2 +- ...Allay-stopDancing-while-not-dancing.patch} | 0 ...ge.patch => 0779-Flying-Fall-Damage.patch} | 2 +- ...ion-moving-velocity-to-VehicleBlock.patch} | 0 ...onfig-for-disabling-entity-tag-tags.patch} | 0 ...e-player-info-update-packet-on-join.patch} | 4 ++-- ...k-items-during-EntityResurrectEvent.patch} | 0 ...en-API.patch => 0784-Win-Screen-API.patch} | 2 +- ...ItemStack-setAmount-null-assignment.patch} | 0 ...ix-force-opening-enchantment-tables.patch} | 0 ...tch => 0787-Add-Entity-Body-Yaw-API.patch} | 0 ...vent-sleeping-villagers-moving-towa.patch} | 0 ...=> 0789-Add-EntityFertilizeEggEvent.patch} | 4 ++-- ...ty-drop-not-updating-the-client-inv.patch} | 0 ...temEvent-and-EntityCompostItemEvent.patch} | 0 ...ctly-handle-ArmorStand-invisibility.patch} | 0 ...ancement-triggers-for-entity-damage.patch} | 0 ...794-Fix-text-display-error-on-spawn.patch} | 0 ...nventories-returning-null-Locations.patch} | 0 ...API.patch => 0796-Add-Shearable-API.patch} | 0 ...Fix-SpawnEggMeta-get-setSpawnedType.patch} | 0 ...g-to-bad-recipes-in-furnace-like-ti.patch} | 0 ...ence-violations-like-they-should-be.patch} | 2 +- ...xpired-keys-from-impacting-new-join.patch} | 2 +- ...ts-being-fired-from-unloaded-chunks.patch} | 0 ...0802-Use-array-for-gamerule-storage.patch} | 0 ...Fix-a-couple-of-upstream-bed-issues.patch} | 0 ...ix-demo-flag-not-enabling-demo-mode.patch} | 0 ... 0805-Add-Mob-Experience-reward-API.patch} | 0 ...redstone-on-top-of-trap-doors-early.patch} | 0 ...Lazy-Initialization-for-Enum-Fields.patch} | 0 ...08-More-accurate-isInOpenWater-impl.patch} | 0 ... => 0809-Expand-PlayerItemMendEvent.patch} | 2 +- ...sh-ProjectileSource-for-projectiles.patch} | 0 ... => 0811-Add-transient-modifier-API.patch} | 0 ...patch => 0812-Fix-block-place-logic.patch} | 0 ...nd-playing-for-BlockItem-ItemStacks.patch} | 2 +- ...l-BlockGrowEvent-for-missing-blocks.patch} | 0 ...nhasbukkit-default-if-alias-block-e.patch} | 0 ...pLike-spam-for-missing-key-selector.patch} | 0 ...-Fix-sniffer-removeExploredLocation.patch} | 0 ...to-remove-all-active-potion-effects.patch} | 0 ...9-Add-event-for-player-editing-sign.patch} | 2 +- ...k-item-frames-if-players-can-see-it.patch} | 0 ...ermission-levels-for-command-blocks.patch} | 0 ...Add-option-to-disable-block-updates.patch} | 0 ...823-Call-missing-BlockDispenseEvent.patch} | 0 ...-chunks-for-supporting-block-checks.patch} | 0 ...Optimize-player-lookups-for-beacons.patch} | 0 ...I.patch => 0826-More-Sign-Block-API.patch} | 0 ...7-fix-item-meta-for-tadpole-buckets.patch} | 0 ...t-API.patch => 0828-Fix-BanList-API.patch} | 2 +- ...d-water-fluid-explosion-resistance-.patch} | 0 ...x-possible-NPE-on-painting-creation.patch} | 0 ...imer-for-Wandering-Traders-spawned-.patch} | 0 ...nceOrb-should-call-EntitySpawnEvent.patch} | 0 ...t-throw-both-Spread-and-Grow-Events.patch} | 0 ....patch => 0834-Add-whitelist-events.patch} | 0 ... 0835-Implement-PlayerFailMoveEvent.patch} | 2 +- ...olia-scheduler-and-owned-region-API.patch} | 2 +- ...se-allay-memory-on-non-item-targets.patch} | 0 ...tion-when-spawning-display-entities.patch} | 0 ...839-Only-capture-actual-tree-growth.patch} | 2 +- ...rce-for-mushroom-block-spread-event.patch} | 0 ...Data-on-more-entities-when-spawning.patch} | 0 ...-Use-correct-seed-on-api-world-load.patch} | 0 ...ta-neighbour-ticks-outside-of-range.patch} | 0 ...> 0844-Cache-map-ids-on-item-frames.patch} | 0 ...-custom-statistic-criteria-creation.patch} | 0 ...atch => 0846-Bandaid-fix-for-Effect.patch} | 2 +- ...tch => 0847-SculkCatalyst-bloom-API.patch} | 0 ...API-for-an-entity-s-scoreboard-name.patch} | 0 ...lace-methods-with-old-StructureType.patch} | 0 ...e-namespaced-commands-if-send-names.patch} | 2 +- ...-handle-BlockBreakEvent-isDropItems.patch} | 0 ...entity-death-event-for-ender-dragon.patch} | 0 ...tity-tracking-range-by-Y-coordinate.patch} | 0 ... => 0854-Add-Listing-API-for-Player.patch} | 4 ++-- ...figurable-Region-Compression-Format.patch} | 0 ...6-Add-BlockFace-to-BlockDamageEvent.patch} | 0 ...h => 0857-Fix-NPE-on-Boat-getStatus.patch} | 0 ...e-API.patch => 0858-Expand-Pose-API.patch} | 0 ...patch => 0859-More-DragonBattle-API.patch} | 0 ...tch => 0860-Add-PlayerPickItemEvent.patch} | 2 +- ...=> 0861-Allow-trident-custom-damage.patch} | 0 ...2-Expose-hand-in-BlockCanBuildEvent.patch} | 0 ...-nearest-structure-border-iteration.patch} | 0 ...Implement-OfflinePlayer-isConnected.patch} | 2 +- ...esync.patch => 0865-Fix-slot-desync.patch} | 4 ++-- ...titleOverride-to-InventoryOpenEvent.patch} | 0 ...67-Configure-sniffer-egg-hatch-time.patch} | 0 ...-proximity-check-before-entity-look.patch} | 0 ...kip-POI-finding-if-stuck-in-vehicle.patch} | 0 ...t-sanity-checks-in-container-clicks.patch} | 2 +- ...ll-BlockRedstoneEvents-for-lecterns.patch} | 0 ...roper-checking-of-empty-item-stacks.patch} | 0 ...ix-silent-equipment-change-for-mobs.patch} | 0 ...h => 0874-Fix-spigot-s-Forced-Stats.patch} | 0 ...ing-InventoryHolders-to-inventories.patch} | 0 ...entities-in-chunks-that-are-positio.patch} | 0 ...sing-logs-for-log-ips-config-option.patch} | 0 ...n-on-UpgradeData.BlockFixers-class-.patch} | 0 ...-AdvancementProgress-getDateAwarded.patch} | 0 ...idebar-objectives-not-being-cleared.patch} | 0 ...x-missing-map-initialize-event-call.patch} | 0 ...a-when-attaching-firework-to-entity.patch} | 0 ...83-Fix-UnsafeValues-loadAdvancement.patch} | 0 ...> 0884-Add-player-idle-duration-API.patch} | 2 +- ...-if-we-can-see-non-visible-entities.patch} | 0 ...NPE-in-SculkBloomEvent-world-access.patch} | 0 ...tack-for-Player-sendEquipmentChange.patch} | 2 +- ...Ints.patch => 0888-Optimize-VarInts.patch} | 0 ...e-collision-shape-of-a-block-before.patch} | 0 ...redicate-for-blocks-when-raytracing.patch} | 0 ...em-packets-with-collector-as-source.patch} | 0 ... => 0892-Expand-LingeringPotion-API.patch} | 0 ...ngEffect-powers-lightning-rods-and-.patch} | 0 ...h-event-for-all-player-interactions.patch} | 0 ...everal-issues-with-EntityBreedEvent.patch} | 0 ...896-Add-UUID-attribute-modifier-API.patch} | 0 ...-event-call-for-entity-teleport-API.patch} | 0 ...y-create-LootContext-for-criterions.patch} | 0 ...-t-fire-sync-events-during-worldgen.patch} | 0 ...tch => 0900-Add-Structure-check-API.patch} | 0 ...-getAttributeModifier-duplication-c.patch} | 0 ...store-vanilla-entity-drops-behavior.patch} | 0 ...-Dont-resend-blocks-on-interactions.patch} | 2 +- ...tch => 0904-add-more-scoreboard-API.patch} | 0 ...stry.patch => 0905-Improve-Registry.patch} | 0 ...on-null-loc-for-EntityTeleportEvent.patch} | 0 ...h => 0907-Add-experience-points-API.patch} | 2 +- ...h => 0908-Add-drops-to-shear-events.patch} | 4 ++-- ...> 0909-Add-PlayerShieldDisableEvent.patch} | 0 ...ate-ResourceLocation-in-NBT-reading.patch} | 0 ...-experience-dropping-on-block-break.patch} | 0 ...> 0912-Fixup-NamespacedKey-handling.patch} | 0 ...13-Expose-LootTable-of-DecoratedPot.patch} | 0 ...location-of-Vec3D-by-entity-tracker.patch} | 0 ...rTradeEvent-and-PlayerPurchaseEvent.patch} | 0 ...h => 0916-Add-ShulkerDuplicateEvent.patch} | 0 ...dd-api-for-spawn-egg-texture-colors.patch} | 0 ... => 0918-Add-Lifecycle-Event-system.patch} | 0 ...patch => 0919-ItemStack-Tooltip-API.patch} | 0 ...Snapshot-includeLightData-parameter.patch} | 0 ...PI.patch => 0921-Add-FluidState-API.patch} | 0 ...patch => 0922-add-number-format-api.patch} | 0 ...patch => 0923-improve-BanList-types.patch} | 0 ...I.patch => 0924-Expanded-Hopper-API.patch} | 0 ...5-Add-BlockBreakProgressUpdateEvent.patch} | 0 ...=> 0926-Deprecate-ItemStack-setType.patch} | 0 ...ch => 0927-Add-CartographyItemEvent.patch} | 2 +- ...aid-API.patch => 0928-More-Raid-API.patch} | 0 ...ng-message-for-initial-server-start.patch} | 0 ...-Configurable-max-block-fluid-ticks.patch} | 0 ...=> 0931-Fix-bees-aging-inside-hives.patch} | 0 ...2-Disable-memory-reserve-allocating.patch} | 0 ...ByEntityEvent-for-unowned-wither-sk.patch} | 0 ....patch => 0934-Fix-DamageSource-API.patch} | 0 ...nvalid-block-entity-during-world-ge.patch} | 0 ...ackOverflowError-for-some-dispenses.patch} | 0 ...=> 0937-Improve-tag-parser-handling.patch} | 2 +- ...s.patch => 0938-Item-Mutation-Fixes.patch} | 0 ...-Per-world-ticks-per-spawn-settings.patch} | 0 ...e-changed-item-from-dispense-events.patch} | 0 ...nd-End-Portal-Frames-from-being-des.patch} | 0 ...-for-mobs-immune-to-default-effects.patch} | 0 ... => 0943-Deep-clone-nbt-tags-in-PDC.patch} | 0 ...944-Support-old-UUID-format-for-NBT.patch} | 0 ...45-Fix-shield-disable-inconsistency.patch} | 0 ...-Large-Packets-disconnecting-client.patch} | 0 ...emFlags.patch => 0947-Fix-ItemFlags.patch} | 0 ...et-damage-reduction-inconsistencies.patch} | 0 ...-handling-of-LivingEntity-actuallyH.patch} | 0 ...e-checking-handled-tags-in-itemmeta.patch} | 0 ...51-Expose-hasColor-to-leather-armor.patch} | 0 ...-API-to-get-player-ha-proxy-address.patch} | 2 +- ...atch => 0953-General-ItemMeta-fixes.patch} | 4 ++-- ....patch => 0954-More-Chest-Block-API.patch} | 0 ...ta-component-type-on-encoding-error.patch} | 0 ...=> 0956-Brigadier-based-command-API.patch} | 2 +- ... => 0957-Fix-issues-with-Recipe-API.patch} | 0 ...58-Fix-equipment-slot-and-group-API.patch} | 0 ...lugin-to-use-Paper-PluginLoader-API.patch} | 0 ...versized-item-data-in-equipment-and.patch} | 2 +- ...nt-NPE-if-hooked-entity-was-cleared.patch} | 0 ...ng-BlockPlaceEvent-calling-onRemove.patch} | 2 +- ...963-Add-missing-fishing-event-state.patch} | 0 ...ate-InvAction-HOTBAR_MOVE_AND_READD.patch} | 2 +- ...nnect-packet-in-phases-where-it-doe.patch} | 0 ...tch => 0966-Adopt-MaterialRerouting.patch} | 0 ...=> 0967-Suspicious-Effect-Entry-API.patch} | 0 ...eck-if-itemstack-is-stackable-first.patch} | 0 ...emoving-recipes-from-RecipeIterator.patch} | 0 ...mage-tick-when-blocking-with-shield.patch} | 0 ...he-experimental-smithing-inventory-.patch} | 0 ...72-disable-forced-empty-world-ticks.patch} | 0 ...dBounds-and-getBlockState-for-inlin.patch} | 0 ...tem-frames-performance-and-bug-fixe.patch} | 0 ...Manager-and-add-advanced-packet-sup.patch} | 0 ...76-Allow-Saving-of-Oversized-Chunks.patch} | 0 ...977-Flat-bedrock-generator-settings.patch} | 0 ...=> 0978-Entity-Activation-Range-2.0.patch} | 0 ...0-Anti-Xray.patch => 0979-Anti-Xray.patch} | 4 ++-- ...city-compression-and-cipher-natives.patch} | 0 ...timize-Collision-to-not-load-chunks.patch} | 2 +- ...alSelector-Goal.Flag-Set-operations.patch} | 0 ...pers.patch => 0983-Optimize-Hoppers.patch} | 4 ++-- ...> 0984-Optimize-Voxel-Shape-Merging.patch} | 0 ...Optimize-Bit-Operations-by-inlining.patch} | 0 ...> 0986-Remove-streams-from-hot-code.patch} | 0 ...er-Remove-Streams-Optimized-collect.patch} | 0 ...-type-tags-suggestions-in-selectors.patch} | 0 ...-Oversized-block-entities-in-chunks.patch} | 0 ...eck-distance-in-entity-interactions.patch} | 0 ...ch => 0991-Configurable-Sand-Duping.patch} | 0 ...ch => 0992-Properly-resend-entities.patch} | 4 ++-- ...h => 0993-Registry-Modification-API.patch} | 0 ...994-Add-registry-entry-and-builders.patch} | 0 ...5-Proxy-ItemStack-to-CraftItemStack.patch} | 0 ...-accessible-directly-from-ItemStack.patch} | 0 ...aft-commands-in-function-parsing-an.patch} | 0 ...98-optimize-dirt-and-snow-spreading.patch} | 0 ... 0999-Fix-NPE-for-Jukebox-setRecord.patch} | 0 ...patch => 1000-fix-horse-inventories.patch} | 0 ...ityDamageEvents-before-actuallyHurt.patch} | 0 ... => 1002-Add-ItemType-getItemRarity.patch} | 0 ... => 1003-Add-plugin-info-at-startup.patch} | 0 ...tion-leniency-distance-configurable.patch} | 2 +- ...1005-Fix-PickupStatus-getting-reset.patch} | 0 ...ype-in-SculkSensorBlock-canActivate.patch} | 0 ...anPlaceOn-and-CanDestroy-NBT-values.patch} | 12 +++++++----- ...on-for-horizontal-only-item-merging.patch} | 0 ...009-Add-skipping-world-symlink-scan.patch} | 0 ... 1010-Add-even-more-Enchantment-API.patch} | 0 ...ble-API.patch => 1011-Leashable-API.patch} | 0 ...=> 1012-Fix-CraftBukkit-drag-system.patch} | 2 +- ...ent-firing-for-block-entity-loading.patch} | 0 ...-lootable-item-function-from-compas.patch} | 0 ...015-Add-enchantment-seed-update-API.patch} | 0 ...ending-chat-to-client-with-updating.patch} | 2 +- ...Fix-InventoryOpenEvent-cancellation.patch} | 0 ...ire-BlockExpEvent-on-grindstone-use.patch} | 0 ... => 1019-Check-dead-flag-in-isAlive.patch} | 0 ...I.patch => 1020-Add-FeatureFlag-API.patch} | 0 ....patch => 1021-Tag-Lifecycle-Events.patch} | 0 ... => 1022-Item-serialization-as-json.patch} | 0 ...ate-slot-in-PlayerInventory-setSlot.patch} | 0 ...ll-time-unused-skip-tick-protection.patch} | 0 ...tty-printing-for-advancement-saving.patch} | 0 ...dPreprocessEvent-on-signed-commands.patch} | 2 +- ...evels-with-enchantment-registry-set.patch} | 2 +- ...h => 1028-Improve-entity-effect-API.patch} | 2 +- ...me.patch => 1029-Add-recipeBrewTime.patch} | 0 ...30-Call-bucket-events-for-cauldrons.patch} | 0 ...31-Add-PlayerInsertLecternBookEvent.patch} | 0 ... 1032-Void-damage-configuration-API.patch} | 0 ...I.patch => 1033-Add-Offline-PDC-API.patch} | 0 ...w-bypassEnchantmentLevelRestriction.patch} | 0 ...-proper-async-player-disconnections.patch} | 4 ++-- ...-send-Banner-patterns-to-the-client.patch} | 0 364 files changed, 151 insertions(+), 165 deletions(-) delete mode 100644 patches/server/0716-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch rename patches/server/{0717-More-Teleport-API.patch => 0716-More-Teleport-API.patch} (98%) rename patches/server/{0718-Add-EntityPortalReadyEvent.patch => 0717-Add-EntityPortalReadyEvent.patch} (100%) rename patches/server/{0719-Don-t-use-level-random-in-entity-constructors.patch => 0718-Don-t-use-level-random-in-entity-constructors.patch} (96%) rename patches/server/{0720-Send-block-entities-after-destroy-prediction.patch => 0719-Send-block-entities-after-destroy-prediction.patch} (98%) rename patches/server/{0721-Warn-on-plugins-accessing-faraway-chunks.patch => 0720-Warn-on-plugins-accessing-faraway-chunks.patch} (100%) rename patches/server/{0722-Custom-Chat-Completion-Suggestions-API.patch => 0721-Custom-Chat-Completion-Suggestions-API.patch} (94%) rename patches/server/{0723-Add-and-fix-missing-BlockFadeEvents.patch => 0722-Add-and-fix-missing-BlockFadeEvents.patch} (100%) rename patches/server/{0724-Collision-API.patch => 0723-Collision-API.patch} (100%) rename patches/server/{0725-Fix-suggest-command-message-for-brigadier-syntax-exc.patch => 0724-Fix-suggest-command-message-for-brigadier-syntax-exc.patch} (100%) rename patches/server/{0726-Block-Ticking-API.patch => 0725-Block-Ticking-API.patch} (100%) rename patches/server/{0727-Add-Velocity-IP-Forwarding-Support.patch => 0726-Add-Velocity-IP-Forwarding-Support.patch} (100%) rename patches/server/{0728-Add-NamespacedKey-biome-methods.patch => 0727-Add-NamespacedKey-biome-methods.patch} (100%) rename patches/server/{0729-Fix-plugin-loggers-on-server-shutdown.patch => 0728-Fix-plugin-loggers-on-server-shutdown.patch} (100%) rename patches/server/{0730-Stop-large-look-changes-from-crashing-the-server.patch => 0729-Stop-large-look-changes-from-crashing-the-server.patch} (100%) rename patches/server/{0731-Fire-EntityChangeBlockEvent-in-more-places.patch => 0730-Fire-EntityChangeBlockEvent-in-more-places.patch} (100%) rename patches/server/{0732-Missing-eating-regain-reason.patch => 0731-Missing-eating-regain-reason.patch} (100%) rename patches/server/{0733-Missing-effect-cause.patch => 0732-Missing-effect-cause.patch} (100%) rename patches/server/{0734-Added-byte-array-serialization-deserialization-for-P.patch => 0733-Added-byte-array-serialization-deserialization-for-P.patch} (100%) rename patches/server/{0735-Call-BlockPhysicsEvent-more-often.patch => 0734-Call-BlockPhysicsEvent-more-often.patch} (100%) rename patches/server/{0736-Configurable-chat-thread-limit.patch => 0735-Configurable-chat-thread-limit.patch} (100%) rename patches/server/{0737-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch => 0736-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch} (100%) rename patches/server/{0738-fix-Jigsaw-block-kicking-user.patch => 0737-fix-Jigsaw-block-kicking-user.patch} (100%) rename patches/server/{0739-use-BlockFormEvent-for-mud-converting-into-clay.patch => 0738-use-BlockFormEvent-for-mud-converting-into-clay.patch} (100%) rename patches/server/{0740-Add-getDrops-to-BlockState.patch => 0739-Add-getDrops-to-BlockState.patch} (100%) rename patches/server/{0741-Fix-a-bunch-of-vanilla-bugs.patch => 0740-Fix-a-bunch-of-vanilla-bugs.patch} (98%) rename patches/server/{0742-Remove-unnecessary-onTrackingStart-during-navigation.patch => 0741-Remove-unnecessary-onTrackingStart-during-navigation.patch} (100%) rename patches/server/{0743-Fix-custom-piglin-loved-items.patch => 0742-Fix-custom-piglin-loved-items.patch} (100%) rename patches/server/{0744-EntityPickupItemEvent-fixes.patch => 0743-EntityPickupItemEvent-fixes.patch} (96%) rename patches/server/{0745-Correctly-handle-interactions-with-items-on-cooldown.patch => 0744-Correctly-handle-interactions-with-items-on-cooldown.patch} (100%) rename patches/server/{0746-Add-PlayerInventorySlotChangeEvent.patch => 0745-Add-PlayerInventorySlotChangeEvent.patch} (100%) rename patches/server/{0747-Elder-Guardian-appearance-API.patch => 0746-Elder-Guardian-appearance-API.patch} (90%) rename patches/server/{0748-Add-entity-knockback-API.patch => 0747-Add-entity-knockback-API.patch} (100%) rename patches/server/{0749-Detect-headless-JREs.patch => 0748-Detect-headless-JREs.patch} (100%) rename patches/server/{0750-fix-entity-vehicle-collision-event-not-called.patch => 0749-fix-entity-vehicle-collision-event-not-called.patch} (100%) rename patches/server/{0751-Add-EntityToggleSitEvent.patch => 0750-Add-EntityToggleSitEvent.patch} (98%) rename patches/server/{0752-Add-fire-tick-delay-option.patch => 0751-Add-fire-tick-delay-option.patch} (100%) rename patches/server/{0753-Add-Moving-Piston-API.patch => 0752-Add-Moving-Piston-API.patch} (100%) rename patches/server/{0754-Ignore-impossible-spawn-tick.patch => 0753-Ignore-impossible-spawn-tick.patch} (100%) rename patches/server/{0755-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch => 0754-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch} (100%) rename patches/server/{0756-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch => 0755-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch} (100%) rename patches/server/{0757-Add-PrePlayerAttackEntityEvent.patch => 0756-Add-PrePlayerAttackEntityEvent.patch} (100%) rename patches/server/{0758-ensure-reset-EnderDragon-boss-event-name.patch => 0757-ensure-reset-EnderDragon-boss-event-name.patch} (100%) rename patches/server/{0759-Add-Player-Warden-Warning-API.patch => 0758-Add-Player-Warden-Warning-API.patch} (95%) rename patches/server/{0760-More-vanilla-friendly-methods-to-update-trades.patch => 0759-More-vanilla-friendly-methods-to-update-trades.patch} (100%) rename patches/server/{0761-Add-paper-dumplisteners-command.patch => 0760-Add-paper-dumplisteners-command.patch} (100%) rename patches/server/{0762-check-global-player-list-where-appropriate.patch => 0761-check-global-player-list-where-appropriate.patch} (100%) rename patches/server/{0763-Fix-async-entity-add-due-to-fungus-trees.patch => 0762-Fix-async-entity-add-due-to-fungus-trees.patch} (100%) rename patches/server/{0764-ItemStack-damage-API.patch => 0763-ItemStack-damage-API.patch} (91%) rename patches/server/{0765-Friction-API.patch => 0764-Friction-API.patch} (100%) rename patches/server/{0766-Ability-to-control-player-s-insomnia-and-phantoms.patch => 0765-Ability-to-control-player-s-insomnia-and-phantoms.patch} (100%) rename patches/server/{0767-Fix-premature-player-kicks-on-shutdown.patch => 0766-Fix-premature-player-kicks-on-shutdown.patch} (100%) rename patches/server/{0768-Sync-offhand-slot-in-menus.patch => 0767-Sync-offhand-slot-in-menus.patch} (100%) rename patches/server/{0769-Player-Entity-Tracking-Events.patch => 0768-Player-Entity-Tracking-Events.patch} (100%) rename patches/server/{0770-Limit-pet-look-distance.patch => 0769-Limit-pet-look-distance.patch} (100%) rename patches/server/{0771-fix-Instruments.patch => 0770-fix-Instruments.patch} (96%) rename patches/server/{0772-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch => 0771-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch} (100%) rename patches/server/{0773-Add-BlockLockCheckEvent.patch => 0772-Add-BlockLockCheckEvent.patch} (100%) rename patches/server/{0774-Add-Sneaking-API-for-Entities.patch => 0773-Add-Sneaking-API-for-Entities.patch} (100%) rename patches/server/{0775-Improve-logging-and-errors.patch => 0774-Improve-logging-and-errors.patch} (98%) rename patches/server/{0776-Improve-PortalEvents.patch => 0775-Improve-PortalEvents.patch} (100%) rename patches/server/{0777-Add-config-option-for-spider-worldborder-climbing.patch => 0776-Add-config-option-for-spider-worldborder-climbing.patch} (100%) rename patches/server/{0778-Add-missing-SpigotConfig-logCommands-check.patch => 0777-Add-missing-SpigotConfig-logCommands-check.patch} (95%) rename patches/server/{0779-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch => 0778-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch} (100%) rename patches/server/{0780-Flying-Fall-Damage.patch => 0779-Flying-Fall-Damage.patch} (96%) rename patches/server/{0781-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch => 0780-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch} (100%) rename patches/server/{0782-config-for-disabling-entity-tag-tags.patch => 0781-config-for-disabling-entity-tag-tags.patch} (100%) rename patches/server/{0783-Use-single-player-info-update-packet-on-join.patch => 0782-Use-single-player-info-update-packet-on-join.patch} (94%) rename patches/server/{0784-Correctly-shrink-items-during-EntityResurrectEvent.patch => 0783-Correctly-shrink-items-during-EntityResurrectEvent.patch} (100%) rename patches/server/{0785-Win-Screen-API.patch => 0784-Win-Screen-API.patch} (93%) rename patches/server/{0786-Remove-CraftItemStack-setAmount-null-assignment.patch => 0785-Remove-CraftItemStack-setAmount-null-assignment.patch} (100%) rename patches/server/{0787-Fix-force-opening-enchantment-tables.patch => 0786-Fix-force-opening-enchantment-tables.patch} (100%) rename patches/server/{0788-Add-Entity-Body-Yaw-API.patch => 0787-Add-Entity-Body-Yaw-API.patch} (100%) rename patches/server/{0789-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch => 0788-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch} (100%) rename patches/server/{0790-Add-EntityFertilizeEggEvent.patch => 0789-Add-EntityFertilizeEggEvent.patch} (97%) rename patches/server/{0791-Fix-HumanEntity-drop-not-updating-the-client-inv.patch => 0790-Fix-HumanEntity-drop-not-updating-the-client-inv.patch} (100%) rename patches/server/{0792-Add-CompostItemEvent-and-EntityCompostItemEvent.patch => 0791-Add-CompostItemEvent-and-EntityCompostItemEvent.patch} (100%) rename patches/server/{0793-Correctly-handle-ArmorStand-invisibility.patch => 0792-Correctly-handle-ArmorStand-invisibility.patch} (100%) rename patches/server/{0794-Fix-advancement-triggers-for-entity-damage.patch => 0793-Fix-advancement-triggers-for-entity-damage.patch} (100%) rename patches/server/{0795-Fix-text-display-error-on-spawn.patch => 0794-Fix-text-display-error-on-spawn.patch} (100%) rename patches/server/{0796-Fix-inventories-returning-null-Locations.patch => 0795-Fix-inventories-returning-null-Locations.patch} (100%) rename patches/server/{0797-Add-Shearable-API.patch => 0796-Add-Shearable-API.patch} (100%) rename patches/server/{0798-Fix-SpawnEggMeta-get-setSpawnedType.patch => 0797-Fix-SpawnEggMeta-get-setSpawnedType.patch} (100%) rename patches/server/{0799-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch => 0798-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch} (100%) rename patches/server/{0800-Treat-sequence-violations-like-they-should-be.patch => 0799-Treat-sequence-violations-like-they-should-be.patch} (92%) rename patches/server/{0801-Prevent-causing-expired-keys-from-impacting-new-join.patch => 0800-Prevent-causing-expired-keys-from-impacting-new-join.patch} (97%) rename patches/server/{0802-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch => 0801-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch} (100%) rename patches/server/{0803-Use-array-for-gamerule-storage.patch => 0802-Use-array-for-gamerule-storage.patch} (100%) rename patches/server/{0804-Fix-a-couple-of-upstream-bed-issues.patch => 0803-Fix-a-couple-of-upstream-bed-issues.patch} (100%) rename patches/server/{0805-Fix-demo-flag-not-enabling-demo-mode.patch => 0804-Fix-demo-flag-not-enabling-demo-mode.patch} (100%) rename patches/server/{0806-Add-Mob-Experience-reward-API.patch => 0805-Add-Mob-Experience-reward-API.patch} (100%) rename patches/server/{0807-Break-redstone-on-top-of-trap-doors-early.patch => 0806-Break-redstone-on-top-of-trap-doors-early.patch} (100%) rename patches/server/{0808-Avoid-Lazy-Initialization-for-Enum-Fields.patch => 0807-Avoid-Lazy-Initialization-for-Enum-Fields.patch} (100%) rename patches/server/{0809-More-accurate-isInOpenWater-impl.patch => 0808-More-accurate-isInOpenWater-impl.patch} (100%) rename patches/server/{0810-Expand-PlayerItemMendEvent.patch => 0809-Expand-PlayerItemMendEvent.patch} (98%) rename patches/server/{0811-Refresh-ProjectileSource-for-projectiles.patch => 0810-Refresh-ProjectileSource-for-projectiles.patch} (100%) rename patches/server/{0812-Add-transient-modifier-API.patch => 0811-Add-transient-modifier-API.patch} (100%) rename patches/server/{0813-Fix-block-place-logic.patch => 0812-Fix-block-place-logic.patch} (100%) rename patches/server/{0814-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch => 0813-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch} (94%) rename patches/server/{0815-Call-BlockGrowEvent-for-missing-blocks.patch => 0814-Call-BlockGrowEvent-for-missing-blocks.patch} (100%) rename patches/server/{0816-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch => 0815-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch} (100%) rename patches/server/{0817-fix-MapLike-spam-for-missing-key-selector.patch => 0816-fix-MapLike-spam-for-missing-key-selector.patch} (100%) rename patches/server/{0818-Fix-sniffer-removeExploredLocation.patch => 0817-Fix-sniffer-removeExploredLocation.patch} (100%) rename patches/server/{0819-Add-method-to-remove-all-active-potion-effects.patch => 0818-Add-method-to-remove-all-active-potion-effects.patch} (100%) rename patches/server/{0820-Add-event-for-player-editing-sign.patch => 0819-Add-event-for-player-editing-sign.patch} (98%) rename patches/server/{0821-Only-tick-item-frames-if-players-can-see-it.patch => 0820-Only-tick-item-frames-if-players-can-see-it.patch} (100%) rename patches/server/{0822-Fix-cmd-permission-levels-for-command-blocks.patch => 0821-Fix-cmd-permission-levels-for-command-blocks.patch} (100%) rename patches/server/{0823-Add-option-to-disable-block-updates.patch => 0822-Add-option-to-disable-block-updates.patch} (100%) rename patches/server/{0824-Call-missing-BlockDispenseEvent.patch => 0823-Call-missing-BlockDispenseEvent.patch} (100%) rename patches/server/{0825-Don-t-load-chunks-for-supporting-block-checks.patch => 0824-Don-t-load-chunks-for-supporting-block-checks.patch} (100%) rename patches/server/{0826-Optimize-player-lookups-for-beacons.patch => 0825-Optimize-player-lookups-for-beacons.patch} (100%) rename patches/server/{0827-More-Sign-Block-API.patch => 0826-More-Sign-Block-API.patch} (100%) rename patches/server/{0828-fix-item-meta-for-tadpole-buckets.patch => 0827-fix-item-meta-for-tadpole-buckets.patch} (100%) rename patches/server/{0829-Fix-BanList-API.patch => 0828-Fix-BanList-API.patch} (99%) rename patches/server/{0830-Determine-lava-and-water-fluid-explosion-resistance-.patch => 0829-Determine-lava-and-water-fluid-explosion-resistance-.patch} (100%) rename patches/server/{0831-Fix-possible-NPE-on-painting-creation.patch => 0830-Fix-possible-NPE-on-painting-creation.patch} (100%) rename patches/server/{0832-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch => 0831-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch} (100%) rename patches/server/{0833-ExperienceOrb-should-call-EntitySpawnEvent.patch => 0832-ExperienceOrb-should-call-EntitySpawnEvent.patch} (100%) rename patches/server/{0834-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch => 0833-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch} (100%) rename patches/server/{0835-Add-whitelist-events.patch => 0834-Add-whitelist-events.patch} (100%) rename patches/server/{0836-Implement-PlayerFailMoveEvent.patch => 0835-Implement-PlayerFailMoveEvent.patch} (98%) rename patches/server/{0837-Folia-scheduler-and-owned-region-API.patch => 0836-Folia-scheduler-and-owned-region-API.patch} (99%) rename patches/server/{0838-Only-erase-allay-memory-on-non-item-targets.patch => 0837-Only-erase-allay-memory-on-non-item-targets.patch} (100%) rename patches/server/{0839-Fix-rotation-when-spawning-display-entities.patch => 0838-Fix-rotation-when-spawning-display-entities.patch} (100%) rename patches/server/{0840-Only-capture-actual-tree-growth.patch => 0839-Only-capture-actual-tree-growth.patch} (98%) rename patches/server/{0841-Use-correct-source-for-mushroom-block-spread-event.patch => 0840-Use-correct-source-for-mushroom-block-spread-event.patch} (100%) rename patches/server/{0842-Respect-randomizeData-on-more-entities-when-spawning.patch => 0841-Respect-randomizeData-on-more-entities-when-spawning.patch} (100%) rename patches/server/{0843-Use-correct-seed-on-api-world-load.patch => 0842-Use-correct-seed-on-api-world-load.patch} (100%) rename patches/server/{0844-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch => 0843-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch} (100%) rename patches/server/{0845-Cache-map-ids-on-item-frames.patch => 0844-Cache-map-ids-on-item-frames.patch} (100%) rename patches/server/{0846-Fix-custom-statistic-criteria-creation.patch => 0845-Fix-custom-statistic-criteria-creation.patch} (100%) rename patches/server/{0847-Bandaid-fix-for-Effect.patch => 0846-Bandaid-fix-for-Effect.patch} (98%) rename patches/server/{0848-SculkCatalyst-bloom-API.patch => 0847-SculkCatalyst-bloom-API.patch} (100%) rename patches/server/{0849-API-for-an-entity-s-scoreboard-name.patch => 0848-API-for-an-entity-s-scoreboard-name.patch} (100%) rename patches/server/{0850-Deprecate-and-replace-methods-with-old-StructureType.patch => 0849-Deprecate-and-replace-methods-with-old-StructureType.patch} (100%) rename patches/server/{0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch => 0850-Don-t-tab-complete-namespaced-commands-if-send-names.patch} (95%) rename patches/server/{0852-Properly-handle-BlockBreakEvent-isDropItems.patch => 0851-Properly-handle-BlockBreakEvent-isDropItems.patch} (100%) rename patches/server/{0853-Fire-entity-death-event-for-ender-dragon.patch => 0852-Fire-entity-death-event-for-ender-dragon.patch} (100%) rename patches/server/{0854-Configurable-entity-tracking-range-by-Y-coordinate.patch => 0853-Configurable-entity-tracking-range-by-Y-coordinate.patch} (100%) rename patches/server/{0855-Add-Listing-API-for-Player.patch => 0854-Add-Listing-API-for-Player.patch} (98%) rename patches/server/{0856-Configurable-Region-Compression-Format.patch => 0855-Configurable-Region-Compression-Format.patch} (100%) rename patches/server/{0857-Add-BlockFace-to-BlockDamageEvent.patch => 0856-Add-BlockFace-to-BlockDamageEvent.patch} (100%) rename patches/server/{0858-Fix-NPE-on-Boat-getStatus.patch => 0857-Fix-NPE-on-Boat-getStatus.patch} (100%) rename patches/server/{0859-Expand-Pose-API.patch => 0858-Expand-Pose-API.patch} (100%) rename patches/server/{0860-More-DragonBattle-API.patch => 0859-More-DragonBattle-API.patch} (100%) rename patches/server/{0861-Add-PlayerPickItemEvent.patch => 0860-Add-PlayerPickItemEvent.patch} (96%) rename patches/server/{0862-Allow-trident-custom-damage.patch => 0861-Allow-trident-custom-damage.patch} (100%) rename patches/server/{0863-Expose-hand-in-BlockCanBuildEvent.patch => 0862-Expose-hand-in-BlockCanBuildEvent.patch} (100%) rename patches/server/{0864-Optimize-nearest-structure-border-iteration.patch => 0863-Optimize-nearest-structure-border-iteration.patch} (100%) rename patches/server/{0865-Implement-OfflinePlayer-isConnected.patch => 0864-Implement-OfflinePlayer-isConnected.patch} (94%) rename patches/server/{0866-Fix-slot-desync.patch => 0865-Fix-slot-desync.patch} (98%) rename patches/server/{0867-Add-titleOverride-to-InventoryOpenEvent.patch => 0866-Add-titleOverride-to-InventoryOpenEvent.patch} (100%) rename patches/server/{0868-Configure-sniffer-egg-hatch-time.patch => 0867-Configure-sniffer-egg-hatch-time.patch} (100%) rename patches/server/{0869-Do-crystal-portal-proximity-check-before-entity-look.patch => 0868-Do-crystal-portal-proximity-check-before-entity-look.patch} (100%) rename patches/server/{0870-Skip-POI-finding-if-stuck-in-vehicle.patch => 0869-Skip-POI-finding-if-stuck-in-vehicle.patch} (100%) rename patches/server/{0871-Add-slot-sanity-checks-in-container-clicks.patch => 0870-Add-slot-sanity-checks-in-container-clicks.patch} (96%) rename patches/server/{0872-Call-BlockRedstoneEvents-for-lecterns.patch => 0871-Call-BlockRedstoneEvents-for-lecterns.patch} (100%) rename patches/server/{0873-Allow-proper-checking-of-empty-item-stacks.patch => 0872-Allow-proper-checking-of-empty-item-stacks.patch} (100%) rename patches/server/{0874-Fix-silent-equipment-change-for-mobs.patch => 0873-Fix-silent-equipment-change-for-mobs.patch} (100%) rename patches/server/{0875-Fix-spigot-s-Forced-Stats.patch => 0874-Fix-spigot-s-Forced-Stats.patch} (100%) rename patches/server/{0876-Add-missing-InventoryHolders-to-inventories.patch => 0875-Add-missing-InventoryHolders-to-inventories.patch} (100%) rename patches/server/{0877-Do-not-read-tile-entities-in-chunks-that-are-positio.patch => 0876-Do-not-read-tile-entities-in-chunks-that-are-positio.patch} (100%) rename patches/server/{0878-Add-missing-logs-for-log-ips-config-option.patch => 0877-Add-missing-logs-for-log-ips-config-option.patch} (100%) rename patches/server/{0879-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch => 0878-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch} (100%) rename patches/server/{0880-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch => 0879-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch} (100%) rename patches/server/{0881-Fix-team-sidebar-objectives-not-being-cleared.patch => 0880-Fix-team-sidebar-objectives-not-being-cleared.patch} (100%) rename patches/server/{0882-Fix-missing-map-initialize-event-call.patch => 0881-Fix-missing-map-initialize-event-call.patch} (100%) rename patches/server/{0883-Update-entity-data-when-attaching-firework-to-entity.patch => 0882-Update-entity-data-when-attaching-firework-to-entity.patch} (100%) rename patches/server/{0884-Fix-UnsafeValues-loadAdvancement.patch => 0883-Fix-UnsafeValues-loadAdvancement.patch} (100%) rename patches/server/{0885-Add-player-idle-duration-API.patch => 0884-Add-player-idle-duration-API.patch} (91%) rename patches/server/{0886-Don-t-check-if-we-can-see-non-visible-entities.patch => 0885-Don-t-check-if-we-can-see-non-visible-entities.patch} (100%) rename patches/server/{0887-Fix-NPE-in-SculkBloomEvent-world-access.patch => 0886-Fix-NPE-in-SculkBloomEvent-world-access.patch} (100%) rename patches/server/{0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch => 0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch} (90%) rename patches/server/{0889-Optimize-VarInts.patch => 0888-Optimize-VarInts.patch} (100%) rename patches/server/{0890-Add-API-to-get-the-collision-shape-of-a-block-before.patch => 0889-Add-API-to-get-the-collision-shape-of-a-block-before.patch} (100%) rename patches/server/{0891-Add-predicate-for-blocks-when-raytracing.patch => 0890-Add-predicate-for-blocks-when-raytracing.patch} (100%) rename patches/server/{0892-Broadcast-take-item-packets-with-collector-as-source.patch => 0891-Broadcast-take-item-packets-with-collector-as-source.patch} (100%) rename patches/server/{0893-Expand-LingeringPotion-API.patch => 0892-Expand-LingeringPotion-API.patch} (100%) rename patches/server/{0894-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch => 0893-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch} (100%) rename patches/server/{0895-Add-hand-to-fish-event-for-all-player-interactions.patch => 0894-Add-hand-to-fish-event-for-all-player-interactions.patch} (100%) rename patches/server/{0896-Fix-several-issues-with-EntityBreedEvent.patch => 0895-Fix-several-issues-with-EntityBreedEvent.patch} (100%) rename patches/server/{0897-Add-UUID-attribute-modifier-API.patch => 0896-Add-UUID-attribute-modifier-API.patch} (100%) rename patches/server/{0898-Fix-missing-event-call-for-entity-teleport-API.patch => 0897-Fix-missing-event-call-for-entity-teleport-API.patch} (100%) rename patches/server/{0899-Lazily-create-LootContext-for-criterions.patch => 0898-Lazily-create-LootContext-for-criterions.patch} (100%) rename patches/server/{0900-Don-t-fire-sync-events-during-worldgen.patch => 0899-Don-t-fire-sync-events-during-worldgen.patch} (100%) rename patches/server/{0901-Add-Structure-check-API.patch => 0900-Add-Structure-check-API.patch} (100%) rename patches/server/{0902-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch => 0901-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch} (100%) rename patches/server/{0903-Restore-vanilla-entity-drops-behavior.patch => 0902-Restore-vanilla-entity-drops-behavior.patch} (100%) rename patches/server/{0904-Dont-resend-blocks-on-interactions.patch => 0903-Dont-resend-blocks-on-interactions.patch} (99%) rename patches/server/{0905-add-more-scoreboard-API.patch => 0904-add-more-scoreboard-API.patch} (100%) rename patches/server/{0906-Improve-Registry.patch => 0905-Improve-Registry.patch} (100%) rename patches/server/{0907-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch => 0906-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch} (100%) rename patches/server/{0908-Add-experience-points-API.patch => 0907-Add-experience-points-API.patch} (97%) rename patches/server/{0909-Add-drops-to-shear-events.patch => 0908-Add-drops-to-shear-events.patch} (99%) rename patches/server/{0910-Add-PlayerShieldDisableEvent.patch => 0909-Add-PlayerShieldDisableEvent.patch} (100%) rename patches/server/{0911-Validate-ResourceLocation-in-NBT-reading.patch => 0910-Validate-ResourceLocation-in-NBT-reading.patch} (100%) rename patches/server/{0912-Properly-handle-experience-dropping-on-block-break.patch => 0911-Properly-handle-experience-dropping-on-block-break.patch} (100%) rename patches/server/{0913-Fixup-NamespacedKey-handling.patch => 0912-Fixup-NamespacedKey-handling.patch} (100%) rename patches/server/{0914-Expose-LootTable-of-DecoratedPot.patch => 0913-Expose-LootTable-of-DecoratedPot.patch} (100%) rename patches/server/{0915-Reduce-allocation-of-Vec3D-by-entity-tracker.patch => 0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch} (100%) rename patches/server/{0916-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch => 0915-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch} (100%) rename patches/server/{0917-Add-ShulkerDuplicateEvent.patch => 0916-Add-ShulkerDuplicateEvent.patch} (100%) rename patches/server/{0918-Add-api-for-spawn-egg-texture-colors.patch => 0917-Add-api-for-spawn-egg-texture-colors.patch} (100%) rename patches/server/{0919-Add-Lifecycle-Event-system.patch => 0918-Add-Lifecycle-Event-system.patch} (100%) rename patches/server/{0920-ItemStack-Tooltip-API.patch => 0919-ItemStack-Tooltip-API.patch} (100%) rename patches/server/{0921-Add-getChunkSnapshot-includeLightData-parameter.patch => 0920-Add-getChunkSnapshot-includeLightData-parameter.patch} (100%) rename patches/server/{0922-Add-FluidState-API.patch => 0921-Add-FluidState-API.patch} (100%) rename patches/server/{0923-add-number-format-api.patch => 0922-add-number-format-api.patch} (100%) rename patches/server/{0924-improve-BanList-types.patch => 0923-improve-BanList-types.patch} (100%) rename patches/server/{0925-Expanded-Hopper-API.patch => 0924-Expanded-Hopper-API.patch} (100%) rename patches/server/{0926-Add-BlockBreakProgressUpdateEvent.patch => 0925-Add-BlockBreakProgressUpdateEvent.patch} (100%) rename patches/server/{0927-Deprecate-ItemStack-setType.patch => 0926-Deprecate-ItemStack-setType.patch} (100%) rename patches/server/{0928-Add-CartographyItemEvent.patch => 0927-Add-CartographyItemEvent.patch} (96%) rename patches/server/{0929-More-Raid-API.patch => 0928-More-Raid-API.patch} (100%) rename patches/server/{0930-Add-onboarding-message-for-initial-server-start.patch => 0929-Add-onboarding-message-for-initial-server-start.patch} (100%) rename patches/server/{0931-Configurable-max-block-fluid-ticks.patch => 0930-Configurable-max-block-fluid-ticks.patch} (100%) rename patches/server/{0932-Fix-bees-aging-inside-hives.patch => 0931-Fix-bees-aging-inside-hives.patch} (100%) rename patches/server/{0933-Disable-memory-reserve-allocating.patch => 0932-Disable-memory-reserve-allocating.patch} (100%) rename patches/server/{0934-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch => 0933-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch} (100%) rename patches/server/{0935-Fix-DamageSource-API.patch => 0934-Fix-DamageSource-API.patch} (100%) rename patches/server/{0936-Fix-creation-of-invalid-block-entity-during-world-ge.patch => 0935-Fix-creation-of-invalid-block-entity-during-world-ge.patch} (100%) rename patches/server/{0937-Fix-possible-StackOverflowError-for-some-dispenses.patch => 0936-Fix-possible-StackOverflowError-for-some-dispenses.patch} (100%) rename patches/server/{0938-Improve-tag-parser-handling.patch => 0937-Improve-tag-parser-handling.patch} (99%) rename patches/server/{0939-Item-Mutation-Fixes.patch => 0938-Item-Mutation-Fixes.patch} (100%) rename patches/server/{0940-Per-world-ticks-per-spawn-settings.patch => 0939-Per-world-ticks-per-spawn-settings.patch} (100%) rename patches/server/{0941-Properly-track-the-changed-item-from-dispense-events.patch => 0940-Properly-track-the-changed-item-from-dispense-events.patch} (100%) rename patches/server/{0942-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch => 0941-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch} (100%) rename patches/server/{0943-Add-config-for-mobs-immune-to-default-effects.patch => 0942-Add-config-for-mobs-immune-to-default-effects.patch} (100%) rename patches/server/{0944-Deep-clone-nbt-tags-in-PDC.patch => 0943-Deep-clone-nbt-tags-in-PDC.patch} (100%) rename patches/server/{0945-Support-old-UUID-format-for-NBT.patch => 0944-Support-old-UUID-format-for-NBT.patch} (100%) rename patches/server/{0946-Fix-shield-disable-inconsistency.patch => 0945-Fix-shield-disable-inconsistency.patch} (100%) rename patches/server/{0947-Handle-Large-Packets-disconnecting-client.patch => 0946-Handle-Large-Packets-disconnecting-client.patch} (100%) rename patches/server/{0948-Fix-ItemFlags.patch => 0947-Fix-ItemFlags.patch} (100%) rename patches/server/{0949-Fix-helmet-damage-reduction-inconsistencies.patch => 0948-Fix-helmet-damage-reduction-inconsistencies.patch} (100%) rename patches/server/{0950-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch => 0949-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch} (100%) rename patches/server/{0951-improve-checking-handled-tags-in-itemmeta.patch => 0950-improve-checking-handled-tags-in-itemmeta.patch} (100%) rename patches/server/{0952-Expose-hasColor-to-leather-armor.patch => 0951-Expose-hasColor-to-leather-armor.patch} (100%) rename patches/server/{0953-Added-API-to-get-player-ha-proxy-address.patch => 0952-Added-API-to-get-player-ha-proxy-address.patch} (97%) rename patches/server/{0954-General-ItemMeta-fixes.patch => 0953-General-ItemMeta-fixes.patch} (99%) rename patches/server/{0955-More-Chest-Block-API.patch => 0954-More-Chest-Block-API.patch} (100%) rename patches/server/{0956-Print-data-component-type-on-encoding-error.patch => 0955-Print-data-component-type-on-encoding-error.patch} (100%) rename patches/server/{0957-Brigadier-based-command-API.patch => 0956-Brigadier-based-command-API.patch} (99%) rename patches/server/{0958-Fix-issues-with-Recipe-API.patch => 0957-Fix-issues-with-Recipe-API.patch} (100%) rename patches/server/{0959-Fix-equipment-slot-and-group-API.patch => 0958-Fix-equipment-slot-and-group-API.patch} (100%) rename patches/server/{0960-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch => 0959-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch} (100%) rename patches/server/{0961-Prevent-sending-oversized-item-data-in-equipment-and.patch => 0960-Prevent-sending-oversized-item-data-in-equipment-and.patch} (99%) rename patches/server/{0962-Prevent-NPE-if-hooked-entity-was-cleared.patch => 0961-Prevent-NPE-if-hooked-entity-was-cleared.patch} (100%) rename patches/server/{0963-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch => 0962-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch} (97%) rename patches/server/{0964-Add-missing-fishing-event-state.patch => 0963-Add-missing-fishing-event-state.patch} (100%) rename patches/server/{0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch => 0964-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch} (95%) rename patches/server/{0966-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch => 0965-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch} (100%) rename patches/server/{0967-Adopt-MaterialRerouting.patch => 0966-Adopt-MaterialRerouting.patch} (100%) rename patches/server/{0968-Suspicious-Effect-Entry-API.patch => 0967-Suspicious-Effect-Entry-API.patch} (100%) rename patches/server/{0969-check-if-itemstack-is-stackable-first.patch => 0968-check-if-itemstack-is-stackable-first.patch} (100%) rename patches/server/{0970-Fix-removing-recipes-from-RecipeIterator.patch => 0969-Fix-removing-recipes-from-RecipeIterator.patch} (100%) rename patches/server/{0971-Configurable-damage-tick-when-blocking-with-shield.patch => 0970-Configurable-damage-tick-when-blocking-with-shield.patch} (100%) rename patches/server/{0972-Properly-remove-the-experimental-smithing-inventory-.patch => 0971-Properly-remove-the-experimental-smithing-inventory-.patch} (100%) rename patches/server/{0973-disable-forced-empty-world-ticks.patch => 0972-disable-forced-empty-world-ticks.patch} (100%) rename patches/server/{0974-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch => 0973-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch} (100%) rename patches/server/{0975-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch => 0974-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch} (100%) rename patches/server/{0976-Optimize-Network-Manager-and-add-advanced-packet-sup.patch => 0975-Optimize-Network-Manager-and-add-advanced-packet-sup.patch} (100%) rename patches/server/{0977-Allow-Saving-of-Oversized-Chunks.patch => 0976-Allow-Saving-of-Oversized-Chunks.patch} (100%) rename patches/server/{0978-Flat-bedrock-generator-settings.patch => 0977-Flat-bedrock-generator-settings.patch} (100%) rename patches/server/{0979-Entity-Activation-Range-2.0.patch => 0978-Entity-Activation-Range-2.0.patch} (100%) rename patches/server/{0980-Anti-Xray.patch => 0979-Anti-Xray.patch} (99%) rename patches/server/{0981-Use-Velocity-compression-and-cipher-natives.patch => 0980-Use-Velocity-compression-and-cipher-natives.patch} (100%) rename patches/server/{0982-Optimize-Collision-to-not-load-chunks.patch => 0981-Optimize-Collision-to-not-load-chunks.patch} (98%) rename patches/server/{0983-Optimize-GoalSelector-Goal.Flag-Set-operations.patch => 0982-Optimize-GoalSelector-Goal.Flag-Set-operations.patch} (100%) rename patches/server/{0984-Optimize-Hoppers.patch => 0983-Optimize-Hoppers.patch} (99%) rename patches/server/{0985-Optimize-Voxel-Shape-Merging.patch => 0984-Optimize-Voxel-Shape-Merging.patch} (100%) rename patches/server/{0986-Optimize-Bit-Operations-by-inlining.patch => 0985-Optimize-Bit-Operations-by-inlining.patch} (100%) rename patches/server/{0987-Remove-streams-from-hot-code.patch => 0986-Remove-streams-from-hot-code.patch} (100%) rename patches/server/{0988-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch => 0987-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch} (100%) rename patches/server/{0989-Fix-entity-type-tags-suggestions-in-selectors.patch => 0988-Fix-entity-type-tags-suggestions-in-selectors.patch} (100%) rename patches/server/{0990-Handle-Oversized-block-entities-in-chunks.patch => 0989-Handle-Oversized-block-entities-in-chunks.patch} (100%) rename patches/server/{0991-Check-distance-in-entity-interactions.patch => 0990-Check-distance-in-entity-interactions.patch} (100%) rename patches/server/{0992-Configurable-Sand-Duping.patch => 0991-Configurable-Sand-Duping.patch} (100%) rename patches/server/{0993-Properly-resend-entities.patch => 0992-Properly-resend-entities.patch} (98%) rename patches/server/{0994-Registry-Modification-API.patch => 0993-Registry-Modification-API.patch} (100%) rename patches/server/{0995-Add-registry-entry-and-builders.patch => 0994-Add-registry-entry-and-builders.patch} (100%) rename patches/server/{0996-Proxy-ItemStack-to-CraftItemStack.patch => 0995-Proxy-ItemStack-to-CraftItemStack.patch} (100%) rename patches/server/{0997-Make-a-PDC-view-accessible-directly-from-ItemStack.patch => 0996-Make-a-PDC-view-accessible-directly-from-ItemStack.patch} (100%) rename patches/server/{0998-Prioritize-Minecraft-commands-in-function-parsing-an.patch => 0997-Prioritize-Minecraft-commands-in-function-parsing-an.patch} (100%) rename patches/server/{0999-optimize-dirt-and-snow-spreading.patch => 0998-optimize-dirt-and-snow-spreading.patch} (100%) rename patches/server/{1000-Fix-NPE-for-Jukebox-setRecord.patch => 0999-Fix-NPE-for-Jukebox-setRecord.patch} (100%) rename patches/server/{1001-fix-horse-inventories.patch => 1000-fix-horse-inventories.patch} (100%) rename patches/server/{1002-Only-call-EntityDamageEvents-before-actuallyHurt.patch => 1001-Only-call-EntityDamageEvents-before-actuallyHurt.patch} (100%) rename patches/server/{1003-Add-ItemType-getItemRarity.patch => 1002-Add-ItemType-getItemRarity.patch} (100%) rename patches/server/{1004-Add-plugin-info-at-startup.patch => 1003-Add-plugin-info-at-startup.patch} (100%) rename patches/server/{1005-Make-interaction-leniency-distance-configurable.patch => 1004-Make-interaction-leniency-distance-configurable.patch} (94%) rename patches/server/{1006-Fix-PickupStatus-getting-reset.patch => 1005-Fix-PickupStatus-getting-reset.patch} (100%) rename patches/server/{1007-Check-for-block-type-in-SculkSensorBlock-canActivate.patch => 1006-Check-for-block-type-in-SculkSensorBlock-canActivate.patch} (100%) rename patches/server/{1008-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch => 1007-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch} (87%) rename patches/server/{1009-Configuration-for-horizontal-only-item-merging.patch => 1008-Configuration-for-horizontal-only-item-merging.patch} (100%) rename patches/server/{1010-Add-skipping-world-symlink-scan.patch => 1009-Add-skipping-world-symlink-scan.patch} (100%) rename patches/server/{1011-Add-even-more-Enchantment-API.patch => 1010-Add-even-more-Enchantment-API.patch} (100%) rename patches/server/{1012-Leashable-API.patch => 1011-Leashable-API.patch} (100%) rename patches/server/{1013-Fix-CraftBukkit-drag-system.patch => 1012-Fix-CraftBukkit-drag-system.patch} (97%) rename patches/server/{1014-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch => 1013-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch} (100%) rename patches/server/{1015-Remove-set-damage-lootable-item-function-from-compas.patch => 1014-Remove-set-damage-lootable-item-function-from-compas.patch} (100%) rename patches/server/{1016-Add-enchantment-seed-update-API.patch => 1015-Add-enchantment-seed-update-API.patch} (100%) rename patches/server/{1017-Fix-synchronise-sending-chat-to-client-with-updating.patch => 1016-Fix-synchronise-sending-chat-to-client-with-updating.patch} (95%) rename patches/server/{1018-Fix-InventoryOpenEvent-cancellation.patch => 1017-Fix-InventoryOpenEvent-cancellation.patch} (100%) rename patches/server/{1019-Fire-BlockExpEvent-on-grindstone-use.patch => 1018-Fire-BlockExpEvent-on-grindstone-use.patch} (100%) rename patches/server/{1020-Check-dead-flag-in-isAlive.patch => 1019-Check-dead-flag-in-isAlive.patch} (100%) rename patches/server/{1021-Add-FeatureFlag-API.patch => 1020-Add-FeatureFlag-API.patch} (100%) rename patches/server/{1022-Tag-Lifecycle-Events.patch => 1021-Tag-Lifecycle-Events.patch} (100%) rename patches/server/{1023-Item-serialization-as-json.patch => 1022-Item-serialization-as-json.patch} (100%) rename patches/server/{1024-Validate-slot-in-PlayerInventory-setSlot.patch => 1023-Validate-slot-in-PlayerInventory-setSlot.patch} (100%) rename patches/server/{1025-Remove-wall-time-unused-skip-tick-protection.patch => 1024-Remove-wall-time-unused-skip-tick-protection.patch} (100%) rename patches/server/{1026-Disable-pretty-printing-for-advancement-saving.patch => 1025-Disable-pretty-printing-for-advancement-saving.patch} (100%) rename patches/server/{1027-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch => 1026-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch} (96%) rename patches/server/{1028-Add-enchantWithLevels-with-enchantment-registry-set.patch => 1027-Add-enchantWithLevels-with-enchantment-registry-set.patch} (93%) rename patches/server/{1029-Improve-entity-effect-API.patch => 1028-Improve-entity-effect-API.patch} (98%) rename patches/server/{1030-Add-recipeBrewTime.patch => 1029-Add-recipeBrewTime.patch} (100%) rename patches/server/{1031-Call-bucket-events-for-cauldrons.patch => 1030-Call-bucket-events-for-cauldrons.patch} (100%) rename patches/server/{1032-Add-PlayerInsertLecternBookEvent.patch => 1031-Add-PlayerInsertLecternBookEvent.patch} (100%) rename patches/server/{1033-Void-damage-configuration-API.patch => 1032-Void-damage-configuration-API.patch} (100%) rename patches/server/{1034-Add-Offline-PDC-API.patch => 1033-Add-Offline-PDC-API.patch} (100%) rename patches/server/{1035-Add-AnvilView-bypassEnchantmentLevelRestriction.patch => 1034-Add-AnvilView-bypassEnchantmentLevelRestriction.patch} (100%) rename patches/server/{1036-Add-proper-async-player-disconnections.patch => 1035-Add-proper-async-player-disconnections.patch} (97%) rename patches/server/{1037-Always-send-Banner-patterns-to-the-client.patch => 1036-Always-send-Banner-patterns-to-the-client.patch} (100%) diff --git a/patches/api/0063-Add-getI18NDisplayName-API.patch b/patches/api/0063-Add-getI18NDisplayName-API.patch index dd788d0c271b..ecdf3c006c65 100644 --- a/patches/api/0063-Add-getI18NDisplayName-API.patch +++ b/patches/api/0063-Add-getI18NDisplayName-API.patch @@ -8,7 +8,7 @@ Currently the server only supports the English language. To override this, You must replace the language file embedded in the server jar. diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java -index d5342258086066d3b9ef404916bad8440f0cf0cd..c92843d0adb438d7a64a5d00ce67b67efd65ca14 100644 +index d5342258086066d3b9ef404916bad8440f0cf0cd..333884bc8fe45c66d37a1bbcebc10ea655d2055f 100644 --- a/src/main/java/org/bukkit/inventory/ItemFactory.java +++ b/src/main/java/org/bukkit/inventory/ItemFactory.java @@ -220,4 +220,20 @@ public interface ItemFactory { @@ -28,7 +28,7 @@ index d5342258086066d3b9ef404916bad8440f0cf0cd..c92843d0adb438d7a64a5d00ce67b67e + * {@link net.kyori.adventure.text.Component#translatable(net.kyori.adventure.translation.Translatable)} instead. + */ + @Nullable -+ @Deprecated(since = "1.18.1") ++ @Deprecated(since = "1.18.1", forRemoval = true) + String getI18NDisplayName(@Nullable ItemStack item); + // Paper end - add getI18NDisplayName } diff --git a/patches/api/0064-ensureServerConversions-API.patch b/patches/api/0064-ensureServerConversions-API.patch index 8fa95dd9cbb9..9d1a4cb932f5 100644 --- a/patches/api/0064-ensureServerConversions-API.patch +++ b/patches/api/0064-ensureServerConversions-API.patch @@ -7,11 +7,11 @@ This will take a Bukkit ItemStack and run it through any conversions a server pr to ensure it meets latest minecraft expectations. diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java -index c92843d0adb438d7a64a5d00ce67b67efd65ca14..3d08beee52f2247db6f6e679206ed6a965fbf9a8 100644 +index 333884bc8fe45c66d37a1bbcebc10ea655d2055f..c1ec8efffd5ff2a4dcb1d761be9a431a62284607 100644 --- a/src/main/java/org/bukkit/inventory/ItemFactory.java +++ b/src/main/java/org/bukkit/inventory/ItemFactory.java @@ -236,4 +236,18 @@ public interface ItemFactory { - @Deprecated(since = "1.18.1") + @Deprecated(since = "1.18.1", forRemoval = true) String getI18NDisplayName(@Nullable ItemStack item); // Paper end - add getI18NDisplayName + diff --git a/patches/api/0166-Fix-Spigot-annotation-mistakes.patch b/patches/api/0166-Fix-Spigot-annotation-mistakes.patch index 69952b703431..8107a6a7af36 100644 --- a/patches/api/0166-Fix-Spigot-annotation-mistakes.patch +++ b/patches/api/0166-Fix-Spigot-annotation-mistakes.patch @@ -1579,7 +1579,7 @@ index ebc14022c9ef9b0b3331ee53e96a32667e4762e0..5c258b6077277575daa5d96349837bdf public void setTitle(@NotNull String title); } diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java -index 3d08beee52f2247db6f6e679206ed6a965fbf9a8..1b4f9b93860e58762ac28715adad5a67298b06d7 100644 +index c1ec8efffd5ff2a4dcb1d761be9a431a62284607..a1d8ef8eda3c0256e8c82b7a01c3e7b11454b250 100644 --- a/src/main/java/org/bukkit/inventory/ItemFactory.java +++ b/src/main/java/org/bukkit/inventory/ItemFactory.java @@ -29,7 +29,7 @@ public interface ItemFactory { diff --git a/patches/api/0203-Create-HoverEvent-from-ItemStack-Entity.patch b/patches/api/0203-Create-HoverEvent-from-ItemStack-Entity.patch index 8722000ff7dc..27625797e0fe 100644 --- a/patches/api/0203-Create-HoverEvent-from-ItemStack-Entity.patch +++ b/patches/api/0203-Create-HoverEvent-from-ItemStack-Entity.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Create HoverEvent from ItemStack Entity diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java -index 1b4f9b93860e58762ac28715adad5a67298b06d7..96546712f788e091749a1b4eebc6b1d6c3db7814 100644 +index a1d8ef8eda3c0256e8c82b7a01c3e7b11454b250..579a9037b656bef9fb65c6da03611e981492074a 100644 --- a/src/main/java/org/bukkit/inventory/ItemFactory.java +++ b/src/main/java/org/bukkit/inventory/ItemFactory.java @@ -250,4 +250,65 @@ public interface ItemFactory { diff --git a/patches/api/0340-Add-enchantWithLevels-API.patch b/patches/api/0340-Add-enchantWithLevels-API.patch index 093eaf700c0d..744a7aa96386 100644 --- a/patches/api/0340-Add-enchantWithLevels-API.patch +++ b/patches/api/0340-Add-enchantWithLevels-API.patch @@ -7,7 +7,7 @@ Deprecate upstream's newer and poorly implemented similar API. diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java -index 96546712f788e091749a1b4eebc6b1d6c3db7814..bd0e55562f1cabef3078573182e0cf9fbc844585 100644 +index 579a9037b656bef9fb65c6da03611e981492074a..e1986aea72bb1f1ba2ea76f3ba53f274b6aac899 100644 --- a/src/main/java/org/bukkit/inventory/ItemFactory.java +++ b/src/main/java/org/bukkit/inventory/ItemFactory.java @@ -170,8 +170,11 @@ public interface ItemFactory { diff --git a/patches/api/0489-Add-enchantWithLevels-with-enchantment-registry-set.patch b/patches/api/0489-Add-enchantWithLevels-with-enchantment-registry-set.patch index 41f106e80f40..1978c0b0738f 100644 --- a/patches/api/0489-Add-enchantWithLevels-with-enchantment-registry-set.patch +++ b/patches/api/0489-Add-enchantWithLevels-with-enchantment-registry-set.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add enchantWithLevels with enchantment registry set diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java -index bd0e55562f1cabef3078573182e0cf9fbc844585..2669d783088b9f63f0edd6d0384c3a307ddccac7 100644 +index e1986aea72bb1f1ba2ea76f3ba53f274b6aac899..0a814c1f65afc00034a454e3ff720d26e6c17ecc 100644 --- a/src/main/java/org/bukkit/inventory/ItemFactory.java +++ b/src/main/java/org/bukkit/inventory/ItemFactory.java @@ -338,4 +338,21 @@ public interface ItemFactory { diff --git a/patches/server/0010-Adventure.patch b/patches/server/0010-Adventure.patch index 589db52a3c19..812a9e1167cb 100644 --- a/patches/server/0010-Adventure.patch +++ b/patches/server/0010-Adventure.patch @@ -4155,7 +4155,7 @@ index 55945b83a5426b352bad9507cc9e94afb1278032..9ea1537408ff2d790747b6e5a681d917 public boolean isOp() { return true; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index a3550d84c273c9720491484382a4bc50dc3246a6..2222fd316ec2463f7e40b2673b29fb338b9d6385 100644 +index a3550d84c273c9720491484382a4bc50dc3246a6..24631135f90bb74bf829160ed079e152573666a2 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -395,14 +395,40 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -4437,10 +4437,10 @@ index a3550d84c273c9720491484382a4bc50dc3246a6..2222fd316ec2463f7e40b2673b29fb33 + } + + private net.minecraft.network.chat.ChatType.Bound toHandle(net.kyori.adventure.chat.ChatType.Bound boundChatType) { -+ net.minecraft.core.Registry chatTypeRegistry = this.getHandle().level().registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.CHAT_TYPE); ++ net.minecraft.core.Registry chatTypeRegistry = this.getHandle().level().registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.CHAT_TYPE); + + return new net.minecraft.network.chat.ChatType.Bound( -+ chatTypeRegistry.getHolderOrThrow(net.minecraft.resources.ResourceKey.create(net.minecraft.core.registries.Registries.CHAT_TYPE, io.papermc.paper.adventure.PaperAdventure.asVanilla(boundChatType.type().key()))), ++ chatTypeRegistry.getOrThrow(net.minecraft.resources.ResourceKey.create(net.minecraft.core.registries.Registries.CHAT_TYPE, io.papermc.paper.adventure.PaperAdventure.asVanilla(boundChatType.type().key()))), + io.papermc.paper.adventure.PaperAdventure.asVanilla(boundChatType.name()), + Optional.ofNullable(io.papermc.paper.adventure.PaperAdventure.asVanilla(boundChatType.target())) + ); @@ -4483,7 +4483,7 @@ index a3550d84c273c9720491484382a4bc50dc3246a6..2222fd316ec2463f7e40b2673b29fb33 + @Override + public void sendMessage(final net.kyori.adventure.identity.Identity identity, final net.kyori.adventure.text.Component message, final net.kyori.adventure.audience.MessageType type) { + if (getHandle().connection == null) return; -+ final net.minecraft.core.Registry chatTypeRegistry = this.getHandle().level().registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.CHAT_TYPE); ++ final net.minecraft.core.Registry chatTypeRegistry = this.getHandle().level().registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.CHAT_TYPE); + this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundSystemChatPacket(message, false)); + } + diff --git a/patches/server/0023-Timings-v2.patch b/patches/server/0023-Timings-v2.patch index 91ba72a47462..a8f502b7e6d3 100644 --- a/patches/server/0023-Timings-v2.patch +++ b/patches/server/0023-Timings-v2.patch @@ -1807,7 +1807,7 @@ index b0ffa23faf62629043dfd613315eaf9c5fcc2cfe..00000000000000000000000000000000 - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 2222fd316ec2463f7e40b2673b29fb338b9d6385..1e23ea353a552d156cfddb2f620add11c89abbb0 100644 +index 24631135f90bb74bf829160ed079e152573666a2..f7833cd528797ba46b001db5208c29eb11ae2529 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2809,6 +2809,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0034-Player-affects-spawning-API.patch b/patches/server/0034-Player-affects-spawning-API.patch index e5e9286e9291..8439cb2b0ad4 100644 --- a/patches/server/0034-Player-affects-spawning-API.patch +++ b/patches/server/0034-Player-affects-spawning-API.patch @@ -135,7 +135,7 @@ index f689b2ca0ebc15c099f36ebfd14e455bda540296..fb043d67eaa6336fc0b5d62774b8f110 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 1e23ea353a552d156cfddb2f620add11c89abbb0..da568a74260a7068437681bddf102929e6b8f168 100644 +index f7833cd528797ba46b001db5208c29eb11ae2529..2be8dc983d008cb3da597f3aabd5efc0df51f9e8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2452,6 +2452,17 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0035-Only-refresh-abilities-if-needed.patch b/patches/server/0035-Only-refresh-abilities-if-needed.patch index 2d9c017bc3ae..330dfcd4914d 100644 --- a/patches/server/0035-Only-refresh-abilities-if-needed.patch +++ b/patches/server/0035-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 da568a74260a7068437681bddf102929e6b8f168..29990d84d9e3ee67a4766149c09be6d582999173 100644 +index 2be8dc983d008cb3da597f3aabd5efc0df51f9e8..5600dce95548ffffa1a338f9c9f6d682d30cf02f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2120,12 +2120,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0048-Use-null-Locale-by-default.patch b/patches/server/0048-Use-null-Locale-by-default.patch index 7b688c0d3ac3..0ffa4b3c957e 100644 --- a/patches/server/0048-Use-null-Locale-by-default.patch +++ b/patches/server/0048-Use-null-Locale-by-default.patch @@ -36,7 +36,7 @@ index 4303bde198050cd037f006234d269af406606eff..911ec630c5925b160cc05f99f0d5bb5a this.server.server.getPluginManager().callEvent(event); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 29990d84d9e3ee67a4766149c09be6d582999173..9409244db73282816e4f7560dd7d73a961f9e1d3 100644 +index 5600dce95548ffffa1a338f9c9f6d682d30cf02f..17a5b37a7591274a45a6818144b62b5cd1412a40 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2450,7 +2450,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0055-Improve-Player-chat-API-handling.patch b/patches/server/0055-Improve-Player-chat-API-handling.patch index 8844c6eaf31b..c119f3275003 100644 --- a/patches/server/0055-Improve-Player-chat-API-handling.patch +++ b/patches/server/0055-Improve-Player-chat-API-handling.patch @@ -53,7 +53,7 @@ index 9683759c36de3b9d791e56dc1fb993087c1bc37c..3b58cc979c4e2fb5382f0c67ccfaa844 if (this.commandMap.dispatch(sender, commandLine)) { return true; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 9409244db73282816e4f7560dd7d73a961f9e1d3..60bf3f000bbaa8dac201e868ff46963f45251062 100644 +index 17a5b37a7591274a45a6818144b62b5cd1412a40..51bf9e36ec13af09240c329e40391d79f715a021 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -563,7 +563,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0059-Player-Tab-List-and-Title-APIs.patch b/patches/server/0059-Player-Tab-List-and-Title-APIs.patch index d9b0772237ee..79923e2cfc4e 100644 --- a/patches/server/0059-Player-Tab-List-and-Title-APIs.patch +++ b/patches/server/0059-Player-Tab-List-and-Title-APIs.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Player Tab List and Title APIs diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 60bf3f000bbaa8dac201e868ff46963f45251062..650a9dcb88e9c50fe60e91cfb55f6c440598a356 100644 +index 51bf9e36ec13af09240c329e40391d79f715a021..e3b8cc11a5523614594f1c3a144991fa70227e57 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -393,6 +393,98 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0066-Complete-resource-pack-API.patch b/patches/server/0066-Complete-resource-pack-API.patch index 1951dc79ca72..f330036b9408 100644 --- a/patches/server/0066-Complete-resource-pack-API.patch +++ b/patches/server/0066-Complete-resource-pack-API.patch @@ -22,7 +22,7 @@ index 99f89854e43ed6742dc9ac1624fa7140b4594b3b..d4527831f66bf1c55e6273c7f8923d6e } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 650a9dcb88e9c50fe60e91cfb55f6c440598a356..6e86a515bbea29f3287e968569c177c22c033766 100644 +index e3b8cc11a5523614594f1c3a144991fa70227e57..e904d8558c425d3b2027053f4083999f0deb36fb 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -213,6 +213,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch b/patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch index 6f523d7d27f2..b46ff88f535a 100644 --- a/patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch +++ b/patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch @@ -44,7 +44,7 @@ index 4fa5e7127549e090338b11e6493413a3fab254a0..14d9e62c86309676ddd7eed19cce2f4b protected void internalSetAbsorptionAmount(float absorptionAmount) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 6e86a515bbea29f3287e968569c177c22c033766..cbc8c9bea2a92ecd78ead69e35b9b179819a4c5f 100644 +index e904d8558c425d3b2027053f4083999f0deb36fb..d578d65883f23cc4aaa5b0a7cf1fc88bb337f3a5 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2365,6 +2365,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0095-LootTable-API-and-replenishable-lootables.patch b/patches/server/0095-LootTable-API-and-replenishable-lootables.patch index 45fb79040d64..edb6659a6940 100644 --- a/patches/server/0095-LootTable-API-and-replenishable-lootables.patch +++ b/patches/server/0095-LootTable-API-and-replenishable-lootables.patch @@ -261,7 +261,7 @@ index 0000000000000000000000000000000000000000..9e7c22ef49f1699df298f7121d50d27b +} diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java new file mode 100644 -index 0000000000000000000000000000000000000000..cd61276a45894a02cbefc41a63c27e2cf6361d1e +index 0000000000000000000000000000000000000000..861bff267cb397e13e8e1c79bd0776b130c6e5da --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java @@ -0,0 +1,249 @@ @@ -391,12 +391,12 @@ index 0000000000000000000000000000000000000000..cd61276a45894a02cbefc41a63c27e2c + + @Override + public void setSeed(final ContainerEntity holder, final long seed) { -+ holder.setLootTableSeed(seed); ++ holder.setContainerLootTableSeed(seed); + } + + @Override + public boolean hasLootTable(final ContainerEntity holder) { -+ return holder.getLootTable() != null; ++ return holder.getContainerLootTable() != null; + } + + @Override diff --git a/patches/server/0098-Optional-TNT-doesn-t-move-in-water.patch b/patches/server/0098-Optional-TNT-doesn-t-move-in-water.patch index 6c39d5db19f7..4c44ca39c9a2 100644 --- a/patches/server/0098-Optional-TNT-doesn-t-move-in-water.patch +++ b/patches/server/0098-Optional-TNT-doesn-t-move-in-water.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Optional TNT doesn't move in water diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -index 3d489fdc14b3e29bab63f330d5edbbc1d354382a..f45a466120291103e4501276b3d8f97d79070360 100644 +index 3d489fdc14b3e29bab63f330d5edbbc1d354382a..45c224198135e48f94dc72312c805bf451bf7b0e 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java @@ -135,6 +135,27 @@ public class PrimedTnt extends Entity implements TraceableEntity { @@ -22,7 +22,7 @@ index 3d489fdc14b3e29bab63f330d5edbbc1d354382a..f45a466120291103e4501276b3d8f97d + net.minecraft.server.level.ChunkMap.TrackedEntity ete = ((net.minecraft.server.level.ServerLevel) this.level()).getChunkSource().chunkMap.entityMap.get(this.getId()); + if (ete != null) { + net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket velocityPacket = new net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket(this); -+ net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket positionPacket = new net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket(this); ++ net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket positionPacket = net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket.teleport(this.getId(), net.minecraft.world.entity.PositionMoveRotation.of(this), java.util.Set.of(), this.onGround); + + ete.seenBy.stream() + .filter(viewer -> (viewer.getPlayer().getX() - this.getX()) * (viewer.getPlayer().getY() - this.getY()) * (viewer.getPlayer().getZ() - this.getZ()) < 16 * 16) diff --git a/patches/server/0119-String-based-Action-Bar-API.patch b/patches/server/0119-String-based-Action-Bar-API.patch index 3dfd3c5e7624..028bc2e2c01e 100644 --- a/patches/server/0119-String-based-Action-Bar-API.patch +++ b/patches/server/0119-String-based-Action-Bar-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] String based Action Bar API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index cbc8c9bea2a92ecd78ead69e35b9b179819a4c5f..d3666250037ff4d6594fe859a7b6b0d0ca679d06 100644 +index d578d65883f23cc4aaa5b0a7cf1fc88bb337f3a5..bf8453b2fa3549c827bff784b0d98aa827053634 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -395,6 +395,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0144-Implement-getI18NDisplayName.patch b/patches/server/0144-Implement-getI18NDisplayName.patch index 8ade912d8fd5..32d65af2dc9b 100644 --- a/patches/server/0144-Implement-getI18NDisplayName.patch +++ b/patches/server/0144-Implement-getI18NDisplayName.patch @@ -8,7 +8,7 @@ Currently the server only supports the English language. To override this, You must replace the language file embedded in the server jar. diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -index 91010267b8c4df582415a8f7cd7386723b556cc0..685aa3c35dc593b1d923a31967649b468df8a238 100644 +index 91010267b8c4df582415a8f7cd7386723b556cc0..b407968b111ff9cb9f428319d211e5d9c4c99138 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java @@ -234,4 +234,19 @@ public final class CraftItemFactory implements ItemFactory { @@ -27,7 +27,7 @@ index 91010267b8c4df582415a8f7cd7386723b556cc0..685aa3c35dc593b1d923a31967649b46 + nms = CraftItemStack.asNMSCopy(item); + } + -+ return nms != null ? net.minecraft.locale.Language.getInstance().getOrDefault(nms.getItem().getDescriptionId(nms)) : null; ++ return nms != null ? nms.getItem().getName(nms).getString() : null; + } + // Paper end - add getI18NDisplayName } diff --git a/patches/server/0153-Expose-client-protocol-version-and-virtual-host.patch b/patches/server/0153-Expose-client-protocol-version-and-virtual-host.patch index e88a2bfe3dc9..2c7a6a791154 100644 --- a/patches/server/0153-Expose-client-protocol-version-and-virtual-host.patch +++ b/patches/server/0153-Expose-client-protocol-version-and-virtual-host.patch @@ -90,7 +90,7 @@ index 7ae4279768b70a4fdc8f4438898871a17c8fe402..582bbb376c75ab5bf737f3015ce8ad45 private void beginLogin(ClientIntentionPacket packet, boolean transfer) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index d3666250037ff4d6594fe859a7b6b0d0ca679d06..ce777a7872e34fed0dfdb984127067ffd835477e 100644 +index bf8453b2fa3549c827bff784b0d98aa827053634..63499a4fa349b3fa61040244db8be2d5d2569b96 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -341,6 +341,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0163-Ability-to-apply-mending-to-XP-API.patch b/patches/server/0163-Ability-to-apply-mending-to-XP-API.patch index 5f8abf9d97b0..7a580a6eb764 100644 --- a/patches/server/0163-Ability-to-apply-mending-to-XP-API.patch +++ b/patches/server/0163-Ability-to-apply-mending-to-XP-API.patch @@ -14,7 +14,7 @@ public net.minecraft.world.entity.ExperienceOrb durabilityToXp(I)I public net.minecraft.world.entity.ExperienceOrb xpToDurability(I)I diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index ce777a7872e34fed0dfdb984127067ffd835477e..d98c0b9faa4ec97ef251d397456458668c911012 100644 +index 63499a4fa349b3fa61040244db8be2d5d2569b96..d222de793776b0217c8ec0a4a3151d085efa339f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1665,7 +1665,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0176-Player.setPlayerProfile-API.patch b/patches/server/0176-Player.setPlayerProfile-API.patch index 98bd61340a95..a44003c55f7b 100644 --- a/patches/server/0176-Player.setPlayerProfile-API.patch +++ b/patches/server/0176-Player.setPlayerProfile-API.patch @@ -64,7 +64,7 @@ index 818df09e9245b5d89b4180b1eaa51470b7539341..f6b2ca92fd3510a76cbf56d0ea55aa6c public Server getServer() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index d98c0b9faa4ec97ef251d397456458668c911012..862001f88b4613cb420bf8b8ca1471f41729ad0f 100644 +index d222de793776b0217c8ec0a4a3151d085efa339f..6191c780cfab682464e23c53873d0acb0c642b0d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -254,11 +254,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0181-Flag-to-disable-the-channel-limit.patch b/patches/server/0181-Flag-to-disable-the-channel-limit.patch index 415d4913b16a..bbb4d826854d 100644 --- a/patches/server/0181-Flag-to-disable-the-channel-limit.patch +++ b/patches/server/0181-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 862001f88b4613cb420bf8b8ca1471f41729ad0f..b295c2cb3758f653b28120291b2f6c08ad2e4acf 100644 +index 6191c780cfab682464e23c53873d0acb0c642b0d..afee0dd824cfa229f9ebdbc2b4ca9beee485d6e7 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -214,6 +214,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0207-InventoryCloseEvent-Reason-API.patch b/patches/server/0207-InventoryCloseEvent-Reason-API.patch index 1384bfc2db7b..335dc0d881e0 100644 --- a/patches/server/0207-InventoryCloseEvent-Reason-API.patch +++ b/patches/server/0207-InventoryCloseEvent-Reason-API.patch @@ -165,7 +165,7 @@ index 6d4e0a90c70f7a66450cbb18ebec1d7bf9200af2..5ff159be1a6dfb4b1a5b9aa1e435d294 @Override public boolean isBlocking() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index b295c2cb3758f653b28120291b2f6c08ad2e4acf..dc0a04f68482a5101acd19bfc61a64aea689b773 100644 +index afee0dd824cfa229f9ebdbc2b4ca9beee485d6e7..d1b14e7460bd2974e2c3c49a085968a90e1f410f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1290,7 +1290,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0240-Expose-attack-cooldown-methods-for-Player.patch b/patches/server/0240-Expose-attack-cooldown-methods-for-Player.patch index 9e8e7726881e..2288caab49f0 100644 --- a/patches/server/0240-Expose-attack-cooldown-methods-for-Player.patch +++ b/patches/server/0240-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 dc0a04f68482a5101acd19bfc61a64aea689b773..e3048a5ce7528c056a90a3bc75cea25d832c1d8c 100644 +index d1b14e7460bd2974e2c3c49a085968a90e1f410f..6fb400243e491bb8492342327fe98127b2df331e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -3007,6 +3007,21 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0241-Improve-death-events.patch b/patches/server/0241-Improve-death-events.patch index c2ce8d6f232a..17d781e34a86 100644 --- a/patches/server/0241-Improve-death-events.patch +++ b/patches/server/0241-Improve-death-events.patch @@ -420,7 +420,7 @@ index 2caba38a50b7ea535337a3540aa5272d4a9f1878..e20565cf256aacd012a1722c5ebbf901 // CraftBukkit end 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 e3048a5ce7528c056a90a3bc75cea25d832c1d8c..d7db67d8bf1f8c9f94547d43e8291e13c9ba34ac 100644 +index 6fb400243e491bb8492342327fe98127b2df331e..5dab50309b9441ddb3fe66aec653be0246b049d2 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2544,7 +2544,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0270-Replace-OfflinePlayer-getLastPlayed.patch b/patches/server/0270-Replace-OfflinePlayer-getLastPlayed.patch index ac848098b4f6..51b5df883293 100644 --- a/patches/server/0270-Replace-OfflinePlayer-getLastPlayed.patch +++ b/patches/server/0270-Replace-OfflinePlayer-getLastPlayed.patch @@ -106,7 +106,7 @@ index f6b2ca92fd3510a76cbf56d0ea55aa6caaf12ba1..e0d342a0ddd140b342f7af138c71596c 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 d7db67d8bf1f8c9f94547d43e8291e13c9ba34ac..5e14d93fe151847969d8c4ca9e1aa960aad39dcc 100644 +index 5dab50309b9441ddb3fe66aec653be0246b049d2..38989d2e0702e6edba0e81e292b439b7ef48023c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -215,6 +215,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0272-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch b/patches/server/0272-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch index 52e9b55fd23f..f2bcc599c050 100644 --- a/patches/server/0272-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch +++ b/patches/server/0272-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch @@ -8,7 +8,7 @@ We just add a check to ensure that the CraftPlayer's handle is a ServerPlayer diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 5e14d93fe151847969d8c4ca9e1aa960aad39dcc..d4b6a3c2bb63022c00f5d847a1e406ed4efd98c6 100644 +index 38989d2e0702e6edba0e81e292b439b7ef48023c..92fb4dfce832f5cb98b476365c060acfd8277183 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -229,8 +229,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0337-Implement-Player-Client-Options-API.patch b/patches/server/0337-Implement-Player-Client-Options-API.patch index 6bd62a888248..1ca74a9891e4 100644 --- a/patches/server/0337-Implement-Player-Client-Options-API.patch +++ b/patches/server/0337-Implement-Player-Client-Options-API.patch @@ -136,7 +136,7 @@ index 363175d3325c012f31ba84060bb0bfac694f6ab8..9911e231ad021286f2da90057b06874f this.adventure$locale = java.util.Objects.requireNonNullElse(net.kyori.adventure.translation.Translator.parseLocale(this.language), java.util.Locale.US); // Paper this.requestedViewDistance = clientOptions.viewDistance(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index d4b6a3c2bb63022c00f5d847a1e406ed4efd98c6..077d47858ac87f732d8ff0d22191b35bc2a58c42 100644 +index 92fb4dfce832f5cb98b476365c060acfd8277183..330a64edf72dc598fb5458702cf7cae5dd83ab00 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -670,6 +670,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0389-Brand-support.patch b/patches/server/0389-Brand-support.patch index 226edc4d049b..291a5334d53b 100644 --- a/patches/server/0389-Brand-support.patch +++ b/patches/server/0389-Brand-support.patch @@ -57,7 +57,7 @@ index b9fbaddcc8239bf737fdea51790f678306e511eb..9a8b08d4b70b8890961e4af7ce6e870a } catch (Exception ex) { ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t dispatch custom payload", ex); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 077d47858ac87f732d8ff0d22191b35bc2a58c42..9042bbcfb161d91b1e2c4d6e0461f141fa41872e 100644 +index 330a64edf72dc598fb5458702cf7cae5dd83ab00..3b0e7473b3e0c5d9e9e34ed505eae4823e626aae 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -3166,6 +3166,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0402-Create-HoverEvent-from-ItemStack-Entity.patch b/patches/server/0402-Create-HoverEvent-from-ItemStack-Entity.patch index ff6ef6b1cc9d..66d23bfd33c1 100644 --- a/patches/server/0402-Create-HoverEvent-from-ItemStack-Entity.patch +++ b/patches/server/0402-Create-HoverEvent-from-ItemStack-Entity.patch @@ -5,11 +5,11 @@ Subject: [PATCH] Create HoverEvent from ItemStack Entity diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -index 685aa3c35dc593b1d923a31967649b468df8a238..19c1faecb398f5b91dd04827b66038c352e5b4e4 100644 +index b407968b111ff9cb9f428319d211e5d9c4c99138..cab7a3d21699605cb7fc480830d7529f70e69e88 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java @@ -249,4 +249,44 @@ public final class CraftItemFactory implements ItemFactory { - return nms != null ? net.minecraft.locale.Language.getInstance().getOrDefault(nms.getItem().getDescriptionId(nms)) : null; + return nms != null ? nms.getItem().getName(nms).getString() : null; } // Paper end - add getI18NDisplayName + diff --git a/patches/server/0430-Fix-Player-spawnParticle-x-y-z-precision-loss.patch b/patches/server/0430-Fix-Player-spawnParticle-x-y-z-precision-loss.patch index 535ffd4869a1..b8670990f3b5 100644 --- a/patches/server/0430-Fix-Player-spawnParticle-x-y-z-precision-loss.patch +++ b/patches/server/0430-Fix-Player-spawnParticle-x-y-z-precision-loss.patch @@ -5,7 +5,7 @@ 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 9042bbcfb161d91b1e2c4d6e0461f141fa41872e..8d9c2c58f7216e1ae7dc382732bd6920c7c72e5c 100644 +index 3b0e7473b3e0c5d9e9e34ed505eae4823e626aae..875d96ca1461d254745e53970b401634c07a8dd6 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2734,7 +2734,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0466-Add-sendOpLevel-API.patch b/patches/server/0466-Add-sendOpLevel-API.patch index e10d6a9c4faf..2a4354226e99 100644 --- a/patches/server/0466-Add-sendOpLevel-API.patch +++ b/patches/server/0466-Add-sendOpLevel-API.patch @@ -32,7 +32,7 @@ index 70b7871091ab9b64d2a5503620a71c3d5585c25d..7676dbe55b4bf6e0472dc0190c01e6ec 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 8d9c2c58f7216e1ae7dc382732bd6920c7c72e5c..680909750f9db56d3cc062b63913e3bd9f69d8a5 100644 +index 875d96ca1461d254745e53970b401634c07a8dd6..0ca539a7e037b7f8791ed4c71ce3093a3def2746 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -694,6 +694,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0527-Expand-PlayerGameModeChangeEvent.patch b/patches/server/0527-Expand-PlayerGameModeChangeEvent.patch index c9ccc145c007..050751dcc743 100644 --- a/patches/server/0527-Expand-PlayerGameModeChangeEvent.patch +++ b/patches/server/0527-Expand-PlayerGameModeChangeEvent.patch @@ -147,7 +147,7 @@ index e6a927e991779bad84a02d81010057a4e36b9c95..9007a0f01b823c613c39c974d9e0f585 } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 680909750f9db56d3cc062b63913e3bd9f69d8a5..3cb6f46492a3441c09a452836d01c15d1837f6ea 100644 +index 0ca539a7e037b7f8791ed4c71ce3093a3def2746..8551d626fd4eb38f57414d022f752c0a389a1095 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1681,7 +1681,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0539-Add-PlayerKickEvent-causes.patch b/patches/server/0539-Add-PlayerKickEvent-causes.patch index 15cf2d557402..d11448420fb3 100644 --- a/patches/server/0539-Add-PlayerKickEvent-causes.patch +++ b/patches/server/0539-Add-PlayerKickEvent-causes.patch @@ -495,7 +495,7 @@ index 9e2ad78b12cadbf0e2bda1e12fe844120529c347..6a7d7fad990fc44fdda6849d43dad141 } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 3cb6f46492a3441c09a452836d01c15d1837f6ea..4b28318dbdeb3fa5935949740343c996d30aa2dd 100644 +index 8551d626fd4eb38f57414d022f752c0a389a1095..f0f8238aeb49c45921c7ec48cc49ed628087741f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -280,7 +280,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0566-Add-PlayerSetSpawnEvent.patch b/patches/server/0566-Add-PlayerSetSpawnEvent.patch index ddf33c1b0dd1..e28f1bfdd7ae 100644 --- a/patches/server/0566-Add-PlayerSetSpawnEvent.patch +++ b/patches/server/0566-Add-PlayerSetSpawnEvent.patch @@ -187,7 +187,7 @@ index db26b5a0464bd6087eeacaf6dd61eba37365df92..9117c035d5a6ff114b028fad3380ceb1 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 4b28318dbdeb3fa5935949740343c996d30aa2dd..eacfcaee0f534ff63c723af11517e6c895bc84ed 100644 +index f0f8238aeb49c45921c7ec48cc49ed628087741f..efc9b5f6864b09fcf116bbad82424b82448f5469 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1430,9 +1430,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0583-Add-ItemFactory-getSpawnEgg-API.patch b/patches/server/0583-Add-ItemFactory-getSpawnEgg-API.patch index c0f37d4a0b2d..715b0b753d24 100644 --- a/patches/server/0583-Add-ItemFactory-getSpawnEgg-API.patch +++ b/patches/server/0583-Add-ItemFactory-getSpawnEgg-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add ItemFactory#getSpawnEgg API diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -index 19c1faecb398f5b91dd04827b66038c352e5b4e4..237df8b37ee8cf5b15e8e6d30fa3b51ef394434d 100644 +index cab7a3d21699605cb7fc480830d7529f70e69e88..ad86ee4372e55c82968fd4fc6a65debab0092028 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java @@ -9,6 +9,7 @@ import net.minecraft.core.HolderSet; @@ -30,7 +30,7 @@ index 19c1faecb398f5b91dd04827b66038c352e5b4e4..237df8b37ee8cf5b15e8e6d30fa3b51e + } + String typeId = type.getKey().toString(); + net.minecraft.resources.ResourceLocation typeKey = ResourceLocation.parse(typeId); -+ net.minecraft.world.entity.EntityType nmsType = net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.get(typeKey); ++ net.minecraft.world.entity.EntityType nmsType = net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.getValue(typeKey); + net.minecraft.world.item.SpawnEggItem eggItem = net.minecraft.world.item.SpawnEggItem.byId(nmsType); + return eggItem == null ? null : new net.minecraft.world.item.ItemStack(eggItem).asBukkitMirror(); + } diff --git a/patches/server/0649-Multi-Block-Change-API-Implementation.patch b/patches/server/0649-Multi-Block-Change-API-Implementation.patch index 7a27fe0df9ae..45d3534bd90d 100644 --- a/patches/server/0649-Multi-Block-Change-API-Implementation.patch +++ b/patches/server/0649-Multi-Block-Change-API-Implementation.patch @@ -24,7 +24,7 @@ index 926ff9be3d9e3f5d620e4c7ccb22b9f64865ff8c..1a37654aff9a9c86c9f7af10a1cf7213 buf.writeLong(this.sectionPos.asLong()); buf.writeVarInt(this.positions.length); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index eacfcaee0f534ff63c723af11517e6c895bc84ed..0bb2a75b2dd3d6d5d7815d3f4b1d8b11b002db62 100644 +index efc9b5f6864b09fcf116bbad82424b82448f5469..5274ee417ba3b9ccdab70449c87ce8f3809ea137 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -947,6 +947,32 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0666-Force-close-world-loading-screen.patch b/patches/server/0666-Force-close-world-loading-screen.patch index d29eaabc9055..edae4046079b 100644 --- a/patches/server/0666-Force-close-world-loading-screen.patch +++ b/patches/server/0666-Force-close-world-loading-screen.patch @@ -10,7 +10,7 @@ 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 f34cad30c982f2bb563f0deab030111720858fa8..f64a4693855899409a0ba7ec15ca0b0351febdd3 100644 +index f34cad30c982f2bb563f0deab030111720858fa8..215a3c9839d664f6cfd4c9360338abcf5863799a 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -407,6 +407,16 @@ public abstract class PlayerList { @@ -20,7 +20,7 @@ index f34cad30c982f2bb563f0deab030111720858fa8..f64a4693855899409a0ba7ec15ca0b03 + // Paper start - Send empty chunk, so players aren't stuck in the world loading screen with our chunk system not sending chunks when dead + if (player.isDeadOrDying()) { + net.minecraft.core.Holder plains = worldserver1.registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BIOME) -+ .getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS); ++ .getOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS); + player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket( + new net.minecraft.world.level.chunk.EmptyLevelChunk(worldserver1, player.chunkPosition(), plains), + worldserver1.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null) diff --git a/patches/server/0675-Implement-enchantWithLevels-API.patch b/patches/server/0675-Implement-enchantWithLevels-API.patch index 08f1ffbe3e63..45f1f704cacf 100644 --- a/patches/server/0675-Implement-enchantWithLevels-API.patch +++ b/patches/server/0675-Implement-enchantWithLevels-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Implement enchantWithLevels API diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -index 237df8b37ee8cf5b15e8e6d30fa3b51ef394434d..944dcc1126c947b4c8c3b4fdd174eb57320abbba 100644 +index ad86ee4372e55c82968fd4fc6a65debab0092028..d9eec6cff3c7c6515f4d61bf1063e7d609d4bcb3 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java @@ -305,4 +305,47 @@ public final class CraftItemFactory implements ItemFactory { @@ -24,7 +24,7 @@ index 237df8b37ee8cf5b15e8e6d30fa3b51ef394434d..944dcc1126c947b4c8c3b4fdd174eb57 + // NON_TREASURE, which does contain all enchantments not in the treasure tag. + // Additionally, the allowTreasure boolean is more intended to configure this method to behave like + // an enchanting table. -+ : net.minecraft.server.MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.ENCHANTMENT).getTag(EnchantmentTags.IN_ENCHANTING_TABLE), ++ : net.minecraft.server.MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.ENCHANTMENT).get(EnchantmentTags.IN_ENCHANTING_TABLE), + random + ); + } diff --git a/patches/server/0686-Use-username-instead-of-display-name-in-PlayerList-g.patch b/patches/server/0686-Use-username-instead-of-display-name-in-PlayerList-g.patch index cf9ec6d9665e..b4d6c3390083 100644 --- a/patches/server/0686-Use-username-instead-of-display-name-in-PlayerList-g.patch +++ b/patches/server/0686-Use-username-instead-of-display-name-in-PlayerList-g.patch @@ -6,7 +6,7 @@ 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 f64a4693855899409a0ba7ec15ca0b0351febdd3..f0ce0041497d038c55019e0f5a8e8b8619cec398 100644 +index 215a3c9839d664f6cfd4c9360338abcf5863799a..0646e435e869b5cc067968feb09ff5c6a979a8a7 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -1354,7 +1354,7 @@ public abstract class PlayerList { diff --git a/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch b/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch index 4f072bfdb004..0a9ed2d8c148 100644 --- a/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch +++ b/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch @@ -24,7 +24,7 @@ index 37111113f6ab6d77c558b10c4162758135db99b0..911b6391455402922e8bd52cfe9e5694 EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity()); Bukkit.getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java -index db8bb6e47b28bac6cf568415af3ffdd6eeac6ac7..34f35502faf2029525a8e0a8f347456b2868804b 100644 +index db8bb6e47b28bac6cf568415af3ffdd6eeac6ac7..59b00aa57f62ec9d56c28d18c493e952e66f39c7 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java +++ b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java @@ -604,7 +604,7 @@ public class Dolphin extends AgeableWaterCreature { @@ -32,12 +32,12 @@ index db8bb6e47b28bac6cf568415af3ffdd6eeac6ac7..34f35502faf2029525a8e0a8f347456b entityitem.setDeltaMovement((double) (0.3F * -Mth.sin(Dolphin.this.getYRot() * 0.017453292F) * Mth.cos(Dolphin.this.getXRot() * 0.017453292F) + Mth.cos(f1) * f2), (double) (0.3F * Mth.sin(Dolphin.this.getXRot() * 0.017453292F) * 1.5F), (double) (0.3F * Mth.cos(Dolphin.this.getYRot() * 0.017453292F) * Mth.cos(Dolphin.this.getXRot() * 0.017453292F) + Mth.sin(f1) * f2)); - Dolphin.this.level().addFreshEntity(entityitem); -+ Dolphin.this.spawnAtLocation(entityitem); // Paper - Call EntityDropItemEvent ++ Dolphin.this.spawnAtLocation(getServerLevel(Dolphin.this), entityitem); // Paper - Call EntityDropItemEvent } } } diff --git a/src/main/java/net/minecraft/world/entity/animal/Fox.java b/src/main/java/net/minecraft/world/entity/animal/Fox.java -index 205aefd38a185fa411ff17cfb0155769de8fc2fd..ca45a8ccf7f4593d557d157470603e4d233d948d 100644 +index 205aefd38a185fa411ff17cfb0155769de8fc2fd..67ea374ae3c66af434b4aadbe702a44d230fbe09 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Fox.java +++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java @@ -492,14 +492,14 @@ public class Fox extends Animal implements VariantHolder { @@ -45,7 +45,7 @@ index 205aefd38a185fa411ff17cfb0155769de8fc2fd..ca45a8ccf7f4593d557d157470603e4d entityitem.setThrower(this); this.playSound(SoundEvents.FOX_SPIT, 1.0F, 1.0F); - this.level().addFreshEntity(entityitem); -+ this.spawnAtLocation(entityitem); // Paper - Call EntityDropItemEvent ++ this.spawnAtLocation((net.minecraft.server.level.ServerLevel) this.level(), entityitem); // Paper - Call EntityDropItemEvent } } @@ -53,12 +53,12 @@ index 205aefd38a185fa411ff17cfb0155769de8fc2fd..ca45a8ccf7f4593d557d157470603e4d ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), stack); - this.level().addFreshEntity(entityitem); -+ this.spawnAtLocation(entityitem); // Paper - Call EntityDropItemEvent ++ this.spawnAtLocation((net.minecraft.server.level.ServerLevel) this.level(), entityitem); // Paper - Call EntityDropItemEvent } @Override diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java -index 14e02f9b0169db8388c515a68315ad5cc3f13d22..dbcf14f5af9c9c0655a82529ee99450a8da14525 100644 +index 14e02f9b0169db8388c515a68315ad5cc3f13d22..14b47d6fa189f2a666b12ef7e7708d204c2b0452 100644 --- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java +++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java @@ -365,8 +365,7 @@ public class Goat extends Animal { @@ -67,19 +67,19 @@ index 14e02f9b0169db8388c515a68315ad5cc3f13d22..dbcf14f5af9c9c0655a82529ee99450a - this.level().addFreshEntity(entityitem); - return true; -+ return this.spawnAtLocation(entityitem) != null; // Paper - Call EntityDropItemEvent ++ return this.spawnAtLocation((net.minecraft.server.level.ServerLevel) this.level(), entityitem) != null; // Paper - Call EntityDropItemEvent } } diff --git a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java -index 5e586f174ff4b610a2584f28c9ffdd445ad58bea..0395b120590552518a85f36a46b68532e936de49 100644 +index 5e586f174ff4b610a2584f28c9ffdd445ad58bea..014e1ea1603bc7a7b42ae7ff7d12e5a41f331d2f 100644 --- a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java +++ b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java @@ -345,8 +345,9 @@ public class Sniffer extends Animal { entityitem.setDefaultPickUpDelay(); this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob) null); -+ if (this.spawnAtLocation(entityitem) != null) { // Paper - Call EntityDropItemEvent ++ if (this.spawnAtLocation(world, entityitem) != null) { // Paper - Call EntityDropItemEvent this.playSound(SoundEvents.SNIFFER_EGG_PLOP, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 0.5F); - world.addFreshEntity(entityitem); + } // Paper - Call EntityDropItemEvent diff --git a/patches/server/0716-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch b/patches/server/0716-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch deleted file mode 100644 index d96ba39bb422..000000000000 --- a/patches/server/0716-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Doc -Date: Sun, 17 Jul 2022 11:49:43 -0400 -Subject: [PATCH] Fix Spigot Config not using commands.spam-exclusions - - -diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index ac2ad33a44ce04d9673adc08ff21a167d606e4db..b34245e82306c4ce607aa984ab8f597dec2ba4b5 100644 ---- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2402,7 +2402,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - } - // Spigot end - // this.chatSpamThrottler.increment(); -- if (!this.chatSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { -+ if (counted && !this.chatSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - exclude from SpigotConfig.spamExclusions - // CraftBukkit end - this.disconnect((Component) Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause - } diff --git a/patches/server/0717-More-Teleport-API.patch b/patches/server/0716-More-Teleport-API.patch similarity index 98% rename from patches/server/0717-More-Teleport-API.patch rename to patches/server/0716-More-Teleport-API.patch index 2bbaf5b834e9..70bc44b3da9c 100644 --- a/patches/server/0717-More-Teleport-API.patch +++ b/patches/server/0716-More-Teleport-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] More Teleport API diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index b34245e82306c4ce607aa984ab8f597dec2ba4b5..ebe3d51ccc02b46d9bae4ba4f9185eadfec278f2 100644 +index ac2ad33a44ce04d9673adc08ff21a167d606e4db..349da8b85b7a122977fcad80a399605109b88db2 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1585,11 +1585,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -15,7 +15,7 @@ index b34245e82306c4ce607aa984ab8f597dec2ba4b5..ebe3d51ccc02b46d9bae4ba4f9185ead - PlayerTeleportEvent event = new PlayerTeleportEvent(player, from.clone(), to.clone(), cause); + // Paper start - Teleport API + Set relativeFlags = java.util.EnumSet.noneOf(io.papermc.paper.entity.TeleportFlag.Relative.class); -+ for (RelativeMovement relativeArgument : set) { ++ for (Relative relativeArgument : set) { + relativeFlags.add(org.bukkit.craftbukkit.entity.CraftPlayer.toApiRelativeFlag(relativeArgument)); + } + PlayerTeleportEvent event = new PlayerTeleportEvent(player, from.clone(), to.clone(), cause, java.util.Set.copyOf(relativeFlags)); @@ -112,7 +112,7 @@ index 4e6afa243d6108cb946a8a7cf96c4036a3c2ac0c..43786eacc72cdf3bb209d3dfb1808ea9 private final org.bukkit.entity.Entity.Spigot spigot = new org.bukkit.entity.Entity.Spigot() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 0bb2a75b2dd3d6d5d7815d3f4b1d8b11b002db62..2514fbae7c87a96c12e44d21ff7df1d2f3243387 100644 +index 5274ee417ba3b9ccdab70449c87ce8f3809ea137..c45753f4b65b189ebfdaea4fb0ec51217dd990c3 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1303,13 +1303,102 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0718-Add-EntityPortalReadyEvent.patch b/patches/server/0717-Add-EntityPortalReadyEvent.patch similarity index 100% rename from patches/server/0718-Add-EntityPortalReadyEvent.patch rename to patches/server/0717-Add-EntityPortalReadyEvent.patch diff --git a/patches/server/0719-Don-t-use-level-random-in-entity-constructors.patch b/patches/server/0718-Don-t-use-level-random-in-entity-constructors.patch similarity index 96% rename from patches/server/0719-Don-t-use-level-random-in-entity-constructors.patch rename to patches/server/0718-Don-t-use-level-random-in-entity-constructors.patch index 5fab2f6349df..9ec489bd3e8d 100644 --- a/patches/server/0719-Don-t-use-level-random-in-entity-constructors.patch +++ b/patches/server/0718-Don-t-use-level-random-in-entity-constructors.patch @@ -27,7 +27,7 @@ index 6b19689a19465554b943470fc6f959e48169ac5b..aa41c4cf8d3ae291c4147118c96190ff public ItemEntity(Level world, double x, double y, double z, ItemStack stack, double velocityX, double velocityY, double velocityZ) { diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -index f45a466120291103e4501276b3d8f97d79070360..96453be982623c7eb210a828404122e1d0f78b5d 100644 +index 45c224198135e48f94dc72312c805bf451bf7b0e..de87483600e55d88176fe25db621bbd3e464729f 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java @@ -68,7 +68,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { diff --git a/patches/server/0720-Send-block-entities-after-destroy-prediction.patch b/patches/server/0719-Send-block-entities-after-destroy-prediction.patch similarity index 98% rename from patches/server/0720-Send-block-entities-after-destroy-prediction.patch rename to patches/server/0719-Send-block-entities-after-destroy-prediction.patch index 8cc9f6fcd486..2742769b83a4 100644 --- a/patches/server/0720-Send-block-entities-after-destroy-prediction.patch +++ b/patches/server/0719-Send-block-entities-after-destroy-prediction.patch @@ -57,7 +57,7 @@ index 5c3e5c348e6fececccd8097355f423b9e7ad982b..064a7a3e1c4d192010e072a5e985a541 } } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index ebe3d51ccc02b46d9bae4ba4f9185eadfec278f2..19b90fe644da59216e11b35af33e62c0fc66db7b 100644 +index 349da8b85b7a122977fcad80a399605109b88db2..32ed76fca856b7d121e2215748be4f6d1b18791a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1723,8 +1723,28 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0721-Warn-on-plugins-accessing-faraway-chunks.patch b/patches/server/0720-Warn-on-plugins-accessing-faraway-chunks.patch similarity index 100% rename from patches/server/0721-Warn-on-plugins-accessing-faraway-chunks.patch rename to patches/server/0720-Warn-on-plugins-accessing-faraway-chunks.patch diff --git a/patches/server/0722-Custom-Chat-Completion-Suggestions-API.patch b/patches/server/0721-Custom-Chat-Completion-Suggestions-API.patch similarity index 94% rename from patches/server/0722-Custom-Chat-Completion-Suggestions-API.patch rename to patches/server/0721-Custom-Chat-Completion-Suggestions-API.patch index 7a419b3d744e..d204b1a24fc3 100644 --- a/patches/server/0722-Custom-Chat-Completion-Suggestions-API.patch +++ b/patches/server/0721-Custom-Chat-Completion-Suggestions-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Custom Chat Completion Suggestions API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 2514fbae7c87a96c12e44d21ff7df1d2f3243387..dc360a7a8a8d23be9d8301a5e6fbff5499c9a947 100644 +index c45753f4b65b189ebfdaea4fb0ec51217dd990c3..2b5eb586eda41d465f3f1faae8159f6fbe346312 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -708,6 +708,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0723-Add-and-fix-missing-BlockFadeEvents.patch b/patches/server/0722-Add-and-fix-missing-BlockFadeEvents.patch similarity index 100% rename from patches/server/0723-Add-and-fix-missing-BlockFadeEvents.patch rename to patches/server/0722-Add-and-fix-missing-BlockFadeEvents.patch diff --git a/patches/server/0724-Collision-API.patch b/patches/server/0723-Collision-API.patch similarity index 100% rename from patches/server/0724-Collision-API.patch rename to patches/server/0723-Collision-API.patch diff --git a/patches/server/0725-Fix-suggest-command-message-for-brigadier-syntax-exc.patch b/patches/server/0724-Fix-suggest-command-message-for-brigadier-syntax-exc.patch similarity index 100% rename from patches/server/0725-Fix-suggest-command-message-for-brigadier-syntax-exc.patch rename to patches/server/0724-Fix-suggest-command-message-for-brigadier-syntax-exc.patch diff --git a/patches/server/0726-Block-Ticking-API.patch b/patches/server/0725-Block-Ticking-API.patch similarity index 100% rename from patches/server/0726-Block-Ticking-API.patch rename to patches/server/0725-Block-Ticking-API.patch diff --git a/patches/server/0727-Add-Velocity-IP-Forwarding-Support.patch b/patches/server/0726-Add-Velocity-IP-Forwarding-Support.patch similarity index 100% rename from patches/server/0727-Add-Velocity-IP-Forwarding-Support.patch rename to patches/server/0726-Add-Velocity-IP-Forwarding-Support.patch diff --git a/patches/server/0728-Add-NamespacedKey-biome-methods.patch b/patches/server/0727-Add-NamespacedKey-biome-methods.patch similarity index 100% rename from patches/server/0728-Add-NamespacedKey-biome-methods.patch rename to patches/server/0727-Add-NamespacedKey-biome-methods.patch diff --git a/patches/server/0729-Fix-plugin-loggers-on-server-shutdown.patch b/patches/server/0728-Fix-plugin-loggers-on-server-shutdown.patch similarity index 100% rename from patches/server/0729-Fix-plugin-loggers-on-server-shutdown.patch rename to patches/server/0728-Fix-plugin-loggers-on-server-shutdown.patch diff --git a/patches/server/0730-Stop-large-look-changes-from-crashing-the-server.patch b/patches/server/0729-Stop-large-look-changes-from-crashing-the-server.patch similarity index 100% rename from patches/server/0730-Stop-large-look-changes-from-crashing-the-server.patch rename to patches/server/0729-Stop-large-look-changes-from-crashing-the-server.patch diff --git a/patches/server/0731-Fire-EntityChangeBlockEvent-in-more-places.patch b/patches/server/0730-Fire-EntityChangeBlockEvent-in-more-places.patch similarity index 100% rename from patches/server/0731-Fire-EntityChangeBlockEvent-in-more-places.patch rename to patches/server/0730-Fire-EntityChangeBlockEvent-in-more-places.patch diff --git a/patches/server/0732-Missing-eating-regain-reason.patch b/patches/server/0731-Missing-eating-regain-reason.patch similarity index 100% rename from patches/server/0732-Missing-eating-regain-reason.patch rename to patches/server/0731-Missing-eating-regain-reason.patch diff --git a/patches/server/0733-Missing-effect-cause.patch b/patches/server/0732-Missing-effect-cause.patch similarity index 100% rename from patches/server/0733-Missing-effect-cause.patch rename to patches/server/0732-Missing-effect-cause.patch diff --git a/patches/server/0734-Added-byte-array-serialization-deserialization-for-P.patch b/patches/server/0733-Added-byte-array-serialization-deserialization-for-P.patch similarity index 100% rename from patches/server/0734-Added-byte-array-serialization-deserialization-for-P.patch rename to patches/server/0733-Added-byte-array-serialization-deserialization-for-P.patch diff --git a/patches/server/0735-Call-BlockPhysicsEvent-more-often.patch b/patches/server/0734-Call-BlockPhysicsEvent-more-often.patch similarity index 100% rename from patches/server/0735-Call-BlockPhysicsEvent-more-often.patch rename to patches/server/0734-Call-BlockPhysicsEvent-more-often.patch diff --git a/patches/server/0736-Configurable-chat-thread-limit.patch b/patches/server/0735-Configurable-chat-thread-limit.patch similarity index 100% rename from patches/server/0736-Configurable-chat-thread-limit.patch rename to patches/server/0735-Configurable-chat-thread-limit.patch diff --git a/patches/server/0737-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch b/patches/server/0736-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch similarity index 100% rename from patches/server/0737-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch rename to patches/server/0736-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch diff --git a/patches/server/0738-fix-Jigsaw-block-kicking-user.patch b/patches/server/0737-fix-Jigsaw-block-kicking-user.patch similarity index 100% rename from patches/server/0738-fix-Jigsaw-block-kicking-user.patch rename to patches/server/0737-fix-Jigsaw-block-kicking-user.patch diff --git a/patches/server/0739-use-BlockFormEvent-for-mud-converting-into-clay.patch b/patches/server/0738-use-BlockFormEvent-for-mud-converting-into-clay.patch similarity index 100% rename from patches/server/0739-use-BlockFormEvent-for-mud-converting-into-clay.patch rename to patches/server/0738-use-BlockFormEvent-for-mud-converting-into-clay.patch diff --git a/patches/server/0740-Add-getDrops-to-BlockState.patch b/patches/server/0739-Add-getDrops-to-BlockState.patch similarity index 100% rename from patches/server/0740-Add-getDrops-to-BlockState.patch rename to patches/server/0739-Add-getDrops-to-BlockState.patch diff --git a/patches/server/0741-Fix-a-bunch-of-vanilla-bugs.patch b/patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch similarity index 98% rename from patches/server/0741-Fix-a-bunch-of-vanilla-bugs.patch rename to patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch index 023d12d11ed7..c52bbed900e9 100644 --- a/patches/server/0741-Fix-a-bunch-of-vanilla-bugs.patch +++ b/patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch @@ -130,7 +130,7 @@ index 064a7a3e1c4d192010e072a5e985a54135748d87..a706f0855fdf88cc9aece3ba00ef574b this.player.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, this.player), this.player); // CraftBukkit this.level.updateSleepingPlayerList(); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 19b90fe644da59216e11b35af33e62c0fc66db7b..8c615974a738b87116830538646750bb6f7ef7f0 100644 +index 32ed76fca856b7d121e2215748be4f6d1b18791a..72ac67c6d42a1763fd63bd0d0db18ba709f48314 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1831,7 +1831,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -143,7 +143,7 @@ index 19b90fe644da59216e11b35af33e62c0fc66db7b..8c615974a738b87116830538646750bb MutableComponent ichatmutablecomponent1 = Component.translatable("build.tooHigh", i).withStyle(ChatFormatting.RED); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index f0ce0041497d038c55019e0f5a8e8b8619cec398..8e71eeb5be2df1352447f3662a6d092a7db9e2d0 100644 +index 0646e435e869b5cc067968feb09ff5c6a979a8a7..61c37bf5f75207085f22093e48986dab8231e1c1 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -261,7 +261,7 @@ public abstract class PlayerList { @@ -219,7 +219,7 @@ index ef71b3ef4444c05b4211de87e1c8ec52cbe3e72a..137ec75ee803789deb7b1ca93dd9369c public void start() { this.creeper.getNavigation().stop(); diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java -index dbcf14f5af9c9c0655a82529ee99450a8da14525..f745a554b9b84a53d9bd942ca9908153fb0a668c 100644 +index 14b47d6fa189f2a666b12ef7e7708d204c2b0452..4c6dc427b90012b0945e073dd905dc7e8d1bec82 100644 --- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java +++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java @@ -247,9 +247,10 @@ public class Goat extends Animal { diff --git a/patches/server/0742-Remove-unnecessary-onTrackingStart-during-navigation.patch b/patches/server/0741-Remove-unnecessary-onTrackingStart-during-navigation.patch similarity index 100% rename from patches/server/0742-Remove-unnecessary-onTrackingStart-during-navigation.patch rename to patches/server/0741-Remove-unnecessary-onTrackingStart-during-navigation.patch diff --git a/patches/server/0743-Fix-custom-piglin-loved-items.patch b/patches/server/0742-Fix-custom-piglin-loved-items.patch similarity index 100% rename from patches/server/0743-Fix-custom-piglin-loved-items.patch rename to patches/server/0742-Fix-custom-piglin-loved-items.patch diff --git a/patches/server/0744-EntityPickupItemEvent-fixes.patch b/patches/server/0743-EntityPickupItemEvent-fixes.patch similarity index 96% rename from patches/server/0744-EntityPickupItemEvent-fixes.patch rename to patches/server/0743-EntityPickupItemEvent-fixes.patch index 9d6076ced99b..839a01673d30 100644 --- a/patches/server/0744-EntityPickupItemEvent-fixes.patch +++ b/patches/server/0743-EntityPickupItemEvent-fixes.patch @@ -56,7 +56,7 @@ index 5c26beef2d3f3d4afa51950ddeb7089989218462..e283b1296c1e831376bfe9491cbf02ed if (!flag) { PiglinAi.putInInventory(piglin, itemstack); diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java -index 45375ccdcf730732dd915304dea2f523807eedd6..2eb1ad88bd39b3e6539d6c4ac61fb1d58edb5eb2 100644 +index 45375ccdcf730732dd915304dea2f523807eedd6..ab132041982df2a701e4baea8195873f31b4a5fb 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raider.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java @@ -228,6 +228,11 @@ public abstract class Raider extends PatrollingMonster { @@ -64,7 +64,7 @@ index 45375ccdcf730732dd915304dea2f523807eedd6..2eb1ad88bd39b3e6539d6c4ac61fb1d5 if (this.hasActiveRaid() && !flag && ItemStack.matches(itemstack, Raid.getOminousBannerInstance(this.registryAccess().lookupOrThrow(Registries.BANNER_PATTERN)))) { + // Paper start - EntityPickupItemEvent fixes -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, itemstack, 0, false).isCancelled()) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, itemEntity, 0, false).isCancelled()) { + return; + } + // Paper end - EntityPickupItemEvent fixes diff --git a/patches/server/0745-Correctly-handle-interactions-with-items-on-cooldown.patch b/patches/server/0744-Correctly-handle-interactions-with-items-on-cooldown.patch similarity index 100% rename from patches/server/0745-Correctly-handle-interactions-with-items-on-cooldown.patch rename to patches/server/0744-Correctly-handle-interactions-with-items-on-cooldown.patch diff --git a/patches/server/0746-Add-PlayerInventorySlotChangeEvent.patch b/patches/server/0745-Add-PlayerInventorySlotChangeEvent.patch similarity index 100% rename from patches/server/0746-Add-PlayerInventorySlotChangeEvent.patch rename to patches/server/0745-Add-PlayerInventorySlotChangeEvent.patch diff --git a/patches/server/0747-Elder-Guardian-appearance-API.patch b/patches/server/0746-Elder-Guardian-appearance-API.patch similarity index 90% rename from patches/server/0747-Elder-Guardian-appearance-API.patch rename to patches/server/0746-Elder-Guardian-appearance-API.patch index 4a603b81c083..bf49ebc163a4 100644 --- a/patches/server/0747-Elder-Guardian-appearance-API.patch +++ b/patches/server/0746-Elder-Guardian-appearance-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Elder Guardian appearance API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index dc360a7a8a8d23be9d8301a5e6fbff5499c9a947..74cfa4313c8aba96b792d7855627be68efc41d51 100644 +index 2b5eb586eda41d465f3f1faae8159f6fbe346312..d8d3d256910790fd7fc406d64ab38e1c372ecfa7 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -3326,6 +3326,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0748-Add-entity-knockback-API.patch b/patches/server/0747-Add-entity-knockback-API.patch similarity index 100% rename from patches/server/0748-Add-entity-knockback-API.patch rename to patches/server/0747-Add-entity-knockback-API.patch diff --git a/patches/server/0749-Detect-headless-JREs.patch b/patches/server/0748-Detect-headless-JREs.patch similarity index 100% rename from patches/server/0749-Detect-headless-JREs.patch rename to patches/server/0748-Detect-headless-JREs.patch diff --git a/patches/server/0750-fix-entity-vehicle-collision-event-not-called.patch b/patches/server/0749-fix-entity-vehicle-collision-event-not-called.patch similarity index 100% rename from patches/server/0750-fix-entity-vehicle-collision-event-not-called.patch rename to patches/server/0749-fix-entity-vehicle-collision-event-not-called.patch diff --git a/patches/server/0751-Add-EntityToggleSitEvent.patch b/patches/server/0750-Add-EntityToggleSitEvent.patch similarity index 98% rename from patches/server/0751-Add-EntityToggleSitEvent.patch rename to patches/server/0750-Add-EntityToggleSitEvent.patch index 8b679dd170a2..965b35e0f417 100644 --- a/patches/server/0751-Add-EntityToggleSitEvent.patch +++ b/patches/server/0750-Add-EntityToggleSitEvent.patch @@ -31,7 +31,7 @@ index 550c7f3435cc6c3180769e47f05bf693bdc380e3..e9e4d6fd69f9eec25a75b2610e15a19f if (inSittingPose) { diff --git a/src/main/java/net/minecraft/world/entity/animal/Fox.java b/src/main/java/net/minecraft/world/entity/animal/Fox.java -index ca45a8ccf7f4593d557d157470603e4d233d948d..d98e4882dcba8a903bc86c8d30b290e6e967cc75 100644 +index 67ea374ae3c66af434b4aadbe702a44d230fbe09..a9a8ebb2cebe668628d5bdb33fa1399e0ab1e08b 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Fox.java +++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java @@ -419,7 +419,7 @@ public class Fox extends Animal implements VariantHolder { diff --git a/patches/server/0752-Add-fire-tick-delay-option.patch b/patches/server/0751-Add-fire-tick-delay-option.patch similarity index 100% rename from patches/server/0752-Add-fire-tick-delay-option.patch rename to patches/server/0751-Add-fire-tick-delay-option.patch diff --git a/patches/server/0753-Add-Moving-Piston-API.patch b/patches/server/0752-Add-Moving-Piston-API.patch similarity index 100% rename from patches/server/0753-Add-Moving-Piston-API.patch rename to patches/server/0752-Add-Moving-Piston-API.patch diff --git a/patches/server/0754-Ignore-impossible-spawn-tick.patch b/patches/server/0753-Ignore-impossible-spawn-tick.patch similarity index 100% rename from patches/server/0754-Ignore-impossible-spawn-tick.patch rename to patches/server/0753-Ignore-impossible-spawn-tick.patch diff --git a/patches/server/0755-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch b/patches/server/0754-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch similarity index 100% rename from patches/server/0755-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch rename to patches/server/0754-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch diff --git a/patches/server/0756-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch b/patches/server/0755-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch similarity index 100% rename from patches/server/0756-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch rename to patches/server/0755-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch diff --git a/patches/server/0757-Add-PrePlayerAttackEntityEvent.patch b/patches/server/0756-Add-PrePlayerAttackEntityEvent.patch similarity index 100% rename from patches/server/0757-Add-PrePlayerAttackEntityEvent.patch rename to patches/server/0756-Add-PrePlayerAttackEntityEvent.patch diff --git a/patches/server/0758-ensure-reset-EnderDragon-boss-event-name.patch b/patches/server/0757-ensure-reset-EnderDragon-boss-event-name.patch similarity index 100% rename from patches/server/0758-ensure-reset-EnderDragon-boss-event-name.patch rename to patches/server/0757-ensure-reset-EnderDragon-boss-event-name.patch diff --git a/patches/server/0759-Add-Player-Warden-Warning-API.patch b/patches/server/0758-Add-Player-Warden-Warning-API.patch similarity index 95% rename from patches/server/0759-Add-Player-Warden-Warning-API.patch rename to patches/server/0758-Add-Player-Warden-Warning-API.patch index c44c1b1bc327..9ec70390920d 100644 --- a/patches/server/0759-Add-Player-Warden-Warning-API.patch +++ b/patches/server/0758-Add-Player-Warden-Warning-API.patch @@ -10,7 +10,7 @@ public net.minecraft.world.entity.monster.warden.WardenSpawnTracker cooldownTick public net.minecraft.world.entity.monster.warden.WardenSpawnTracker increaseWarningLevel()V diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 74cfa4313c8aba96b792d7855627be68efc41d51..a000d41fd6b6d9e690ea2a16ac1bd77589b64f14 100644 +index d8d3d256910790fd7fc406d64ab38e1c372ecfa7..bc96e6a4f6833b351da5ac91563fd6f0d057c854 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -3331,6 +3331,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0760-More-vanilla-friendly-methods-to-update-trades.patch b/patches/server/0759-More-vanilla-friendly-methods-to-update-trades.patch similarity index 100% rename from patches/server/0760-More-vanilla-friendly-methods-to-update-trades.patch rename to patches/server/0759-More-vanilla-friendly-methods-to-update-trades.patch diff --git a/patches/server/0761-Add-paper-dumplisteners-command.patch b/patches/server/0760-Add-paper-dumplisteners-command.patch similarity index 100% rename from patches/server/0761-Add-paper-dumplisteners-command.patch rename to patches/server/0760-Add-paper-dumplisteners-command.patch diff --git a/patches/server/0762-check-global-player-list-where-appropriate.patch b/patches/server/0761-check-global-player-list-where-appropriate.patch similarity index 100% rename from patches/server/0762-check-global-player-list-where-appropriate.patch rename to patches/server/0761-check-global-player-list-where-appropriate.patch diff --git a/patches/server/0763-Fix-async-entity-add-due-to-fungus-trees.patch b/patches/server/0762-Fix-async-entity-add-due-to-fungus-trees.patch similarity index 100% rename from patches/server/0763-Fix-async-entity-add-due-to-fungus-trees.patch rename to patches/server/0762-Fix-async-entity-add-due-to-fungus-trees.patch diff --git a/patches/server/0764-ItemStack-damage-API.patch b/patches/server/0763-ItemStack-damage-API.patch similarity index 91% rename from patches/server/0764-ItemStack-damage-API.patch rename to patches/server/0763-ItemStack-damage-API.patch index f6d47719ca45..55e7f06af162 100644 --- a/patches/server/0764-ItemStack-damage-API.patch +++ b/patches/server/0763-ItemStack-damage-API.patch @@ -11,7 +11,7 @@ the logic associated with damaging them public net.minecraft.world.entity.LivingEntity entityEventForEquipmentBreak(Lnet/minecraft/world/entity/EquipmentSlot;)B diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index bcb3a45166e5dd75dd727adf92304b3a75399c8d..d8dc3228f3cd8c9efc8359162edac601a87bf762 100644 +index bcb3a45166e5dd75dd727adf92304b3a75399c8d..90a55f00c36903d52630c51bf69322973a2b5274 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java @@ -693,8 +693,13 @@ public final class ItemStack implements DataComponentHolder { @@ -29,18 +29,21 @@ index bcb3a45166e5dd75dd727adf92304b3a75399c8d..d8dc3228f3cd8c9efc8359162edac601 // CraftBukkit start if (player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), j, originalDamage); // Paper - Add EntityDamageItemEvent -@@ -725,8 +730,8 @@ public final class ItemStack implements DataComponentHolder { - +@@ -726,7 +731,12 @@ public final class ItemStack implements DataComponentHolder { } -- private int processDurabilityChange(int baseDamage, ServerLevel world, @Nullable LivingEntity player) { // Paper - Add EntityDamageItemEvent + private int processDurabilityChange(int baseDamage, ServerLevel world, @Nullable LivingEntity player) { // Paper - Add EntityDamageItemEvent - return !this.isDamageableItem() ? 0 : (player instanceof ServerPlayer && player.hasInfiniteMaterials() ? 0 : (baseDamage > 0 ? EnchantmentHelper.processDurabilityChange(world, this, baseDamage) : baseDamage)); // Paper - Add EntityDamageItemEvent -+ private int processDurabilityChange(int baseDamage, ServerLevel world, @Nullable LivingEntity player, boolean force) { // Paper - Add EntityDamageItemEvent ++ // Paper start - itemstack damage api ++ return processDurabilityChange(baseDamage, world, player, false); ++ } ++ private int processDurabilityChange(int baseDamage, ServerLevel world, @Nullable LivingEntity player, boolean force) { + return !this.isDamageableItem() ? 0 : (player instanceof ServerPlayer && player.hasInfiniteMaterials() && !force ? 0 : (baseDamage > 0 ? EnchantmentHelper.processDurabilityChange(world, this, baseDamage) : baseDamage)); // Paper - Add EntityDamageItemEvent ++ // Paper end - itemstack damage api } private void applyDamage(int damage, @Nullable LivingEntity player, Consumer breakCallback) { // Paper - Add EntityDamageItemEvent -@@ -766,6 +771,11 @@ public final class ItemStack implements DataComponentHolder { +@@ -766,6 +776,11 @@ public final class ItemStack implements DataComponentHolder { } public void hurtAndBreak(int amount, LivingEntity entity, EquipmentSlot slot) { @@ -52,7 +55,7 @@ index bcb3a45166e5dd75dd727adf92304b3a75399c8d..d8dc3228f3cd8c9efc8359162edac601 Level world = entity.level(); if (world instanceof ServerLevel worldserver) { -@@ -778,8 +788,8 @@ public final class ItemStack implements DataComponentHolder { +@@ -778,8 +793,8 @@ public final class ItemStack implements DataComponentHolder { } this.hurtAndBreak(amount, worldserver, entity, (item) -> { // Paper - Add EntityDamageItemEvent diff --git a/patches/server/0765-Friction-API.patch b/patches/server/0764-Friction-API.patch similarity index 100% rename from patches/server/0765-Friction-API.patch rename to patches/server/0764-Friction-API.patch diff --git a/patches/server/0766-Ability-to-control-player-s-insomnia-and-phantoms.patch b/patches/server/0765-Ability-to-control-player-s-insomnia-and-phantoms.patch similarity index 100% rename from patches/server/0766-Ability-to-control-player-s-insomnia-and-phantoms.patch rename to patches/server/0765-Ability-to-control-player-s-insomnia-and-phantoms.patch diff --git a/patches/server/0767-Fix-premature-player-kicks-on-shutdown.patch b/patches/server/0766-Fix-premature-player-kicks-on-shutdown.patch similarity index 100% rename from patches/server/0767-Fix-premature-player-kicks-on-shutdown.patch rename to patches/server/0766-Fix-premature-player-kicks-on-shutdown.patch diff --git a/patches/server/0768-Sync-offhand-slot-in-menus.patch b/patches/server/0767-Sync-offhand-slot-in-menus.patch similarity index 100% rename from patches/server/0768-Sync-offhand-slot-in-menus.patch rename to patches/server/0767-Sync-offhand-slot-in-menus.patch diff --git a/patches/server/0769-Player-Entity-Tracking-Events.patch b/patches/server/0768-Player-Entity-Tracking-Events.patch similarity index 100% rename from patches/server/0769-Player-Entity-Tracking-Events.patch rename to patches/server/0768-Player-Entity-Tracking-Events.patch diff --git a/patches/server/0770-Limit-pet-look-distance.patch b/patches/server/0769-Limit-pet-look-distance.patch similarity index 100% rename from patches/server/0770-Limit-pet-look-distance.patch rename to patches/server/0769-Limit-pet-look-distance.patch diff --git a/patches/server/0771-fix-Instruments.patch b/patches/server/0770-fix-Instruments.patch similarity index 96% rename from patches/server/0771-fix-Instruments.patch rename to patches/server/0770-fix-Instruments.patch index 6ac52bdf2589..fa555c5aa37f 100644 --- a/patches/server/0771-fix-Instruments.patch +++ b/patches/server/0770-fix-Instruments.patch @@ -6,7 +6,7 @@ Subject: [PATCH] fix Instruments properly handle Player#playNote diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index a000d41fd6b6d9e690ea2a16ac1bd77589b64f14..a70db1d658127ed72f82580c1dd743c6c9d5f809 100644 +index bc96e6a4f6833b351da5ac91563fd6f0d057c854..b0818d1fc60ab75770e671d30cdbfd531b3dfa99 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -785,7 +785,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0772-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch b/patches/server/0771-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch similarity index 100% rename from patches/server/0772-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch rename to patches/server/0771-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch diff --git a/patches/server/0773-Add-BlockLockCheckEvent.patch b/patches/server/0772-Add-BlockLockCheckEvent.patch similarity index 100% rename from patches/server/0773-Add-BlockLockCheckEvent.patch rename to patches/server/0772-Add-BlockLockCheckEvent.patch diff --git a/patches/server/0774-Add-Sneaking-API-for-Entities.patch b/patches/server/0773-Add-Sneaking-API-for-Entities.patch similarity index 100% rename from patches/server/0774-Add-Sneaking-API-for-Entities.patch rename to patches/server/0773-Add-Sneaking-API-for-Entities.patch diff --git a/patches/server/0775-Improve-logging-and-errors.patch b/patches/server/0774-Improve-logging-and-errors.patch similarity index 98% rename from patches/server/0775-Improve-logging-and-errors.patch rename to patches/server/0774-Improve-logging-and-errors.patch index 242eb6cb0e5c..d8fff73a33ac 100644 --- a/patches/server/0775-Improve-logging-and-errors.patch +++ b/patches/server/0774-Improve-logging-and-errors.patch @@ -52,7 +52,7 @@ index 4037a1057ebc87e3df6333e0d546fc85b5148d2a..eb9dab7be7da11ab1c4046a7fc4a29d5 } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 8c615974a738b87116830538646750bb6f7ef7f0..abe5490b54bda4e0767a65244c29b236a40ec8d6 100644 +index 72ac67c6d42a1763fd63bd0d0db18ba709f48314..6f3e25d41420b5e54721e88c84fd3194d6170b9a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -3451,7 +3451,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0776-Improve-PortalEvents.patch b/patches/server/0775-Improve-PortalEvents.patch similarity index 100% rename from patches/server/0776-Improve-PortalEvents.patch rename to patches/server/0775-Improve-PortalEvents.patch diff --git a/patches/server/0777-Add-config-option-for-spider-worldborder-climbing.patch b/patches/server/0776-Add-config-option-for-spider-worldborder-climbing.patch similarity index 100% rename from patches/server/0777-Add-config-option-for-spider-worldborder-climbing.patch rename to patches/server/0776-Add-config-option-for-spider-worldborder-climbing.patch diff --git a/patches/server/0778-Add-missing-SpigotConfig-logCommands-check.patch b/patches/server/0777-Add-missing-SpigotConfig-logCommands-check.patch similarity index 95% rename from patches/server/0778-Add-missing-SpigotConfig-logCommands-check.patch rename to patches/server/0777-Add-missing-SpigotConfig-logCommands-check.patch index c4fb5944f4c5..1bd83dc7d88a 100644 --- a/patches/server/0778-Add-missing-SpigotConfig-logCommands-check.patch +++ b/patches/server/0777-Add-missing-SpigotConfig-logCommands-check.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add missing SpigotConfig logCommands check Co-authored-by: david diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index abe5490b54bda4e0767a65244c29b236a40ec8d6..984ee21a6fc59efeabc2e5eeedced548d03f413d 100644 +index 6f3e25d41420b5e54721e88c84fd3194d6170b9a..59b64ea82c84ff7d9b9123473b4466ec01918cd2 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -2078,7 +2078,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0779-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch b/patches/server/0778-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch similarity index 100% rename from patches/server/0779-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch rename to patches/server/0778-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch diff --git a/patches/server/0780-Flying-Fall-Damage.patch b/patches/server/0779-Flying-Fall-Damage.patch similarity index 96% rename from patches/server/0780-Flying-Fall-Damage.patch rename to patches/server/0779-Flying-Fall-Damage.patch index b16a488ee274..a9fc10c351bd 100644 --- a/patches/server/0780-Flying-Fall-Damage.patch +++ b/patches/server/0779-Flying-Fall-Damage.patch @@ -26,7 +26,7 @@ index 30e0a5fe3f9bd85d2b702c2c877c5682ed35d461..aca888c2f02b09ac6739bdc81b194c45 } else { if (fallDistance >= 2.0F) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index a70db1d658127ed72f82580c1dd743c6c9d5f809..7029f8c76a18b76ab13e43f2d0ec4f910646caee 100644 +index b0818d1fc60ab75770e671d30cdbfd531b3dfa99..05d95294a5183612c171fbd0e5181ac02270e784 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2609,6 +2609,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0781-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch b/patches/server/0780-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch similarity index 100% rename from patches/server/0781-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch rename to patches/server/0780-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch diff --git a/patches/server/0782-config-for-disabling-entity-tag-tags.patch b/patches/server/0781-config-for-disabling-entity-tag-tags.patch similarity index 100% rename from patches/server/0782-config-for-disabling-entity-tag-tags.patch rename to patches/server/0781-config-for-disabling-entity-tag-tags.patch diff --git a/patches/server/0783-Use-single-player-info-update-packet-on-join.patch b/patches/server/0782-Use-single-player-info-update-packet-on-join.patch similarity index 94% rename from patches/server/0783-Use-single-player-info-update-packet-on-join.patch rename to patches/server/0782-Use-single-player-info-update-packet-on-join.patch index f0e844f29c15..68e488cbf6ca 100644 --- a/patches/server/0783-Use-single-player-info-update-packet-on-join.patch +++ b/patches/server/0782-Use-single-player-info-update-packet-on-join.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Use single player info update packet on join diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 984ee21a6fc59efeabc2e5eeedced548d03f413d..f9dffac2a10a6d2aea488197d1302de06980d354 100644 +index 59b64ea82c84ff7d9b9123473b4466ec01918cd2..51f4d1e5c02c516b5c57095d35348ba53f5b3193 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -3489,7 +3489,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -18,7 +18,7 @@ index 984ee21a6fc59efeabc2e5eeedced548d03f413d..f9dffac2a10a6d2aea488197d1302de0 } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 8e71eeb5be2df1352447f3662a6d092a7db9e2d0..4fe3024e26b56c2d796acf703a1bc200ff309f09 100644 +index 61c37bf5f75207085f22093e48986dab8231e1c1..f9212fc2db00531da1618780e231e8ad21285907 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -365,6 +365,7 @@ public abstract class PlayerList { diff --git a/patches/server/0784-Correctly-shrink-items-during-EntityResurrectEvent.patch b/patches/server/0783-Correctly-shrink-items-during-EntityResurrectEvent.patch similarity index 100% rename from patches/server/0784-Correctly-shrink-items-during-EntityResurrectEvent.patch rename to patches/server/0783-Correctly-shrink-items-during-EntityResurrectEvent.patch diff --git a/patches/server/0785-Win-Screen-API.patch b/patches/server/0784-Win-Screen-API.patch similarity index 93% rename from patches/server/0785-Win-Screen-API.patch rename to patches/server/0784-Win-Screen-API.patch index 981c12ddbed2..65a47054b53f 100644 --- a/patches/server/0785-Win-Screen-API.patch +++ b/patches/server/0784-Win-Screen-API.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Win Screen API public net.minecraft.server.level.ServerPlayer seenCredits diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 7029f8c76a18b76ab13e43f2d0ec4f910646caee..e90f477207ca0107e23cb29da0cacf6fed3dcfc4 100644 +index 05d95294a5183612c171fbd0e5181ac02270e784..0a700df3e4f4f6e2e902f0c69dd6ae149978be47 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1322,6 +1322,25 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0786-Remove-CraftItemStack-setAmount-null-assignment.patch b/patches/server/0785-Remove-CraftItemStack-setAmount-null-assignment.patch similarity index 100% rename from patches/server/0786-Remove-CraftItemStack-setAmount-null-assignment.patch rename to patches/server/0785-Remove-CraftItemStack-setAmount-null-assignment.patch diff --git a/patches/server/0787-Fix-force-opening-enchantment-tables.patch b/patches/server/0786-Fix-force-opening-enchantment-tables.patch similarity index 100% rename from patches/server/0787-Fix-force-opening-enchantment-tables.patch rename to patches/server/0786-Fix-force-opening-enchantment-tables.patch diff --git a/patches/server/0788-Add-Entity-Body-Yaw-API.patch b/patches/server/0787-Add-Entity-Body-Yaw-API.patch similarity index 100% rename from patches/server/0788-Add-Entity-Body-Yaw-API.patch rename to patches/server/0787-Add-Entity-Body-Yaw-API.patch diff --git a/patches/server/0789-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch b/patches/server/0788-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch similarity index 100% rename from patches/server/0789-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch rename to patches/server/0788-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch diff --git a/patches/server/0790-Add-EntityFertilizeEggEvent.patch b/patches/server/0789-Add-EntityFertilizeEggEvent.patch similarity index 97% rename from patches/server/0790-Add-EntityFertilizeEggEvent.patch rename to patches/server/0789-Add-EntityFertilizeEggEvent.patch index 24b2e1a1af67..5ba280ce9638 100644 --- a/patches/server/0790-Add-EntityFertilizeEggEvent.patch +++ b/patches/server/0789-Add-EntityFertilizeEggEvent.patch @@ -47,7 +47,7 @@ index 100be2ed533450eda32d9c4eb9eb1067846d1516..36846ba6b6c7494c745ebd8b221479a9 } diff --git a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java -index 0395b120590552518a85f36a46b68532e936de49..7f70237a274fde0fb97880c1d47246157e3b3415 100644 +index 014e1ea1603bc7a7b42ae7ff7d12e5a41f331d2f..af2f6e690fc51d319b77d081466c2dc7a1d8fe19 100644 --- a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java +++ b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java @@ -340,11 +340,16 @@ public class Sniffer extends Animal { @@ -65,7 +65,7 @@ index 0395b120590552518a85f36a46b68532e936de49..7f70237a274fde0fb97880c1d4724615 entityitem.setDefaultPickUpDelay(); - this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob) null); + this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob) null, result.getExperience()); // Paper - Add EntityFertilizeEggEvent event - if (this.spawnAtLocation(entityitem) != null) { // Paper - Call EntityDropItemEvent + if (this.spawnAtLocation(world, entityitem) != null) { // Paper - Call EntityDropItemEvent this.playSound(SoundEvents.SNIFFER_EGG_PLOP, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 0.5F); } // Paper - Call EntityDropItemEvent diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java diff --git a/patches/server/0791-Fix-HumanEntity-drop-not-updating-the-client-inv.patch b/patches/server/0790-Fix-HumanEntity-drop-not-updating-the-client-inv.patch similarity index 100% rename from patches/server/0791-Fix-HumanEntity-drop-not-updating-the-client-inv.patch rename to patches/server/0790-Fix-HumanEntity-drop-not-updating-the-client-inv.patch diff --git a/patches/server/0792-Add-CompostItemEvent-and-EntityCompostItemEvent.patch b/patches/server/0791-Add-CompostItemEvent-and-EntityCompostItemEvent.patch similarity index 100% rename from patches/server/0792-Add-CompostItemEvent-and-EntityCompostItemEvent.patch rename to patches/server/0791-Add-CompostItemEvent-and-EntityCompostItemEvent.patch diff --git a/patches/server/0793-Correctly-handle-ArmorStand-invisibility.patch b/patches/server/0792-Correctly-handle-ArmorStand-invisibility.patch similarity index 100% rename from patches/server/0793-Correctly-handle-ArmorStand-invisibility.patch rename to patches/server/0792-Correctly-handle-ArmorStand-invisibility.patch diff --git a/patches/server/0794-Fix-advancement-triggers-for-entity-damage.patch b/patches/server/0793-Fix-advancement-triggers-for-entity-damage.patch similarity index 100% rename from patches/server/0794-Fix-advancement-triggers-for-entity-damage.patch rename to patches/server/0793-Fix-advancement-triggers-for-entity-damage.patch diff --git a/patches/server/0795-Fix-text-display-error-on-spawn.patch b/patches/server/0794-Fix-text-display-error-on-spawn.patch similarity index 100% rename from patches/server/0795-Fix-text-display-error-on-spawn.patch rename to patches/server/0794-Fix-text-display-error-on-spawn.patch diff --git a/patches/server/0796-Fix-inventories-returning-null-Locations.patch b/patches/server/0795-Fix-inventories-returning-null-Locations.patch similarity index 100% rename from patches/server/0796-Fix-inventories-returning-null-Locations.patch rename to patches/server/0795-Fix-inventories-returning-null-Locations.patch diff --git a/patches/server/0797-Add-Shearable-API.patch b/patches/server/0796-Add-Shearable-API.patch similarity index 100% rename from patches/server/0797-Add-Shearable-API.patch rename to patches/server/0796-Add-Shearable-API.patch diff --git a/patches/server/0798-Fix-SpawnEggMeta-get-setSpawnedType.patch b/patches/server/0797-Fix-SpawnEggMeta-get-setSpawnedType.patch similarity index 100% rename from patches/server/0798-Fix-SpawnEggMeta-get-setSpawnedType.patch rename to patches/server/0797-Fix-SpawnEggMeta-get-setSpawnedType.patch diff --git a/patches/server/0799-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch b/patches/server/0798-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch similarity index 100% rename from patches/server/0799-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch rename to patches/server/0798-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch diff --git a/patches/server/0800-Treat-sequence-violations-like-they-should-be.patch b/patches/server/0799-Treat-sequence-violations-like-they-should-be.patch similarity index 92% rename from patches/server/0800-Treat-sequence-violations-like-they-should-be.patch rename to patches/server/0799-Treat-sequence-violations-like-they-should-be.patch index d881aea8c031..387f4dcf4f6f 100644 --- a/patches/server/0800-Treat-sequence-violations-like-they-should-be.patch +++ b/patches/server/0799-Treat-sequence-violations-like-they-should-be.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Treat sequence violations like they should be diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index f9dffac2a10a6d2aea488197d1302de06980d354..90392c7c87feb08711b0af80163a4ea8021448f4 100644 +index 51f4d1e5c02c516b5c57095d35348ba53f5b3193..c2328bc821730dd829440ab17b7c8b1800a1f5ca 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1997,6 +1997,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0801-Prevent-causing-expired-keys-from-impacting-new-join.patch b/patches/server/0800-Prevent-causing-expired-keys-from-impacting-new-join.patch similarity index 97% rename from patches/server/0801-Prevent-causing-expired-keys-from-impacting-new-join.patch rename to patches/server/0800-Prevent-causing-expired-keys-from-impacting-new-join.patch index b1858d977593..2001b0974ca0 100644 --- a/patches/server/0801-Prevent-causing-expired-keys-from-impacting-new-join.patch +++ b/patches/server/0800-Prevent-causing-expired-keys-from-impacting-new-join.patch @@ -26,7 +26,7 @@ index d0b2a8b5ded71a9a41753f4addea1c49826b34a3..29b465fc1dc50e0e84ddb889c5303e80 UPDATE_GAME_MODE((serialized, buf) -> serialized.gameMode = GameType.byId(buf.readVarInt()), (buf, entry) -> buf.writeVarInt(entry.gameMode().getId())), UPDATE_LISTED((serialized, buf) -> serialized.listed = buf.readBoolean(), (buf, entry) -> buf.writeBoolean(entry.listed())), diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 90392c7c87feb08711b0af80163a4ea8021448f4..eb81cd8421aa2fc011e5cb38e8a52b55fc1938b7 100644 +index c2328bc821730dd829440ab17b7c8b1800a1f5ca..60d58622fd568932c019ba6a4e4070a881fdda53 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -305,6 +305,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0802-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch b/patches/server/0801-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch similarity index 100% rename from patches/server/0802-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch rename to patches/server/0801-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch diff --git a/patches/server/0803-Use-array-for-gamerule-storage.patch b/patches/server/0802-Use-array-for-gamerule-storage.patch similarity index 100% rename from patches/server/0803-Use-array-for-gamerule-storage.patch rename to patches/server/0802-Use-array-for-gamerule-storage.patch diff --git a/patches/server/0804-Fix-a-couple-of-upstream-bed-issues.patch b/patches/server/0803-Fix-a-couple-of-upstream-bed-issues.patch similarity index 100% rename from patches/server/0804-Fix-a-couple-of-upstream-bed-issues.patch rename to patches/server/0803-Fix-a-couple-of-upstream-bed-issues.patch diff --git a/patches/server/0805-Fix-demo-flag-not-enabling-demo-mode.patch b/patches/server/0804-Fix-demo-flag-not-enabling-demo-mode.patch similarity index 100% rename from patches/server/0805-Fix-demo-flag-not-enabling-demo-mode.patch rename to patches/server/0804-Fix-demo-flag-not-enabling-demo-mode.patch diff --git a/patches/server/0806-Add-Mob-Experience-reward-API.patch b/patches/server/0805-Add-Mob-Experience-reward-API.patch similarity index 100% rename from patches/server/0806-Add-Mob-Experience-reward-API.patch rename to patches/server/0805-Add-Mob-Experience-reward-API.patch diff --git a/patches/server/0807-Break-redstone-on-top-of-trap-doors-early.patch b/patches/server/0806-Break-redstone-on-top-of-trap-doors-early.patch similarity index 100% rename from patches/server/0807-Break-redstone-on-top-of-trap-doors-early.patch rename to patches/server/0806-Break-redstone-on-top-of-trap-doors-early.patch diff --git a/patches/server/0808-Avoid-Lazy-Initialization-for-Enum-Fields.patch b/patches/server/0807-Avoid-Lazy-Initialization-for-Enum-Fields.patch similarity index 100% rename from patches/server/0808-Avoid-Lazy-Initialization-for-Enum-Fields.patch rename to patches/server/0807-Avoid-Lazy-Initialization-for-Enum-Fields.patch diff --git a/patches/server/0809-More-accurate-isInOpenWater-impl.patch b/patches/server/0808-More-accurate-isInOpenWater-impl.patch similarity index 100% rename from patches/server/0809-More-accurate-isInOpenWater-impl.patch rename to patches/server/0808-More-accurate-isInOpenWater-impl.patch diff --git a/patches/server/0810-Expand-PlayerItemMendEvent.patch b/patches/server/0809-Expand-PlayerItemMendEvent.patch similarity index 98% rename from patches/server/0810-Expand-PlayerItemMendEvent.patch rename to patches/server/0809-Expand-PlayerItemMendEvent.patch index 10de3ba9b2eb..73abf28aa3ee 100644 --- a/patches/server/0810-Expand-PlayerItemMendEvent.patch +++ b/patches/server/0809-Expand-PlayerItemMendEvent.patch @@ -30,7 +30,7 @@ index 3a7af27bb1ce0cbe56bd3760cd400083daf98d4c..bf0838f574fa3fb9654e087d602b8d38 if (l > 0) { // this.value = l; // CraftBukkit - update exp value of orb for PlayerItemMendEvent calls // Paper - the value field should not be mutated here because it doesn't take "count" into account diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index e90f477207ca0107e23cb29da0cacf6fed3dcfc4..de0dc5b37bd0823409974befdd96676b2575cf48 100644 +index 0a700df3e4f4f6e2e902f0c69dd6ae149978be47..3d52de930c4358843c5a8c88a1dce478b61ed616 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1881,11 +1881,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0811-Refresh-ProjectileSource-for-projectiles.patch b/patches/server/0810-Refresh-ProjectileSource-for-projectiles.patch similarity index 100% rename from patches/server/0811-Refresh-ProjectileSource-for-projectiles.patch rename to patches/server/0810-Refresh-ProjectileSource-for-projectiles.patch diff --git a/patches/server/0812-Add-transient-modifier-API.patch b/patches/server/0811-Add-transient-modifier-API.patch similarity index 100% rename from patches/server/0812-Add-transient-modifier-API.patch rename to patches/server/0811-Add-transient-modifier-API.patch diff --git a/patches/server/0813-Fix-block-place-logic.patch b/patches/server/0812-Fix-block-place-logic.patch similarity index 100% rename from patches/server/0813-Fix-block-place-logic.patch rename to patches/server/0812-Fix-block-place-logic.patch diff --git a/patches/server/0814-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch b/patches/server/0813-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch similarity index 94% rename from patches/server/0814-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch rename to patches/server/0813-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch index 45955c4fa8b9..69e6a10e5784 100644 --- a/patches/server/0814-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch +++ b/patches/server/0813-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix spigot sound playing for BlockItem ItemStacks diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index d8dc3228f3cd8c9efc8359162edac601a87bf762..5867a0e3e2ce9be7514771549ad318947e387470 100644 +index 90a55f00c36903d52630c51bf69322973a2b5274..1b7d797dac1ff7ee945cf4ef8c6861475a31903d 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java @@ -577,7 +577,11 @@ public final class ItemStack implements DataComponentHolder { diff --git a/patches/server/0815-Call-BlockGrowEvent-for-missing-blocks.patch b/patches/server/0814-Call-BlockGrowEvent-for-missing-blocks.patch similarity index 100% rename from patches/server/0815-Call-BlockGrowEvent-for-missing-blocks.patch rename to patches/server/0814-Call-BlockGrowEvent-for-missing-blocks.patch diff --git a/patches/server/0816-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch b/patches/server/0815-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch similarity index 100% rename from patches/server/0816-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch rename to patches/server/0815-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch diff --git a/patches/server/0817-fix-MapLike-spam-for-missing-key-selector.patch b/patches/server/0816-fix-MapLike-spam-for-missing-key-selector.patch similarity index 100% rename from patches/server/0817-fix-MapLike-spam-for-missing-key-selector.patch rename to patches/server/0816-fix-MapLike-spam-for-missing-key-selector.patch diff --git a/patches/server/0818-Fix-sniffer-removeExploredLocation.patch b/patches/server/0817-Fix-sniffer-removeExploredLocation.patch similarity index 100% rename from patches/server/0818-Fix-sniffer-removeExploredLocation.patch rename to patches/server/0817-Fix-sniffer-removeExploredLocation.patch diff --git a/patches/server/0819-Add-method-to-remove-all-active-potion-effects.patch b/patches/server/0818-Add-method-to-remove-all-active-potion-effects.patch similarity index 100% rename from patches/server/0819-Add-method-to-remove-all-active-potion-effects.patch rename to patches/server/0818-Add-method-to-remove-all-active-potion-effects.patch diff --git a/patches/server/0820-Add-event-for-player-editing-sign.patch b/patches/server/0819-Add-event-for-player-editing-sign.patch similarity index 98% rename from patches/server/0820-Add-event-for-player-editing-sign.patch rename to patches/server/0819-Add-event-for-player-editing-sign.patch index 9ea10f844872..50295978391f 100644 --- a/patches/server/0820-Add-event-for-player-editing-sign.patch +++ b/patches/server/0819-Add-event-for-player-editing-sign.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add event for player editing sign diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 5867a0e3e2ce9be7514771549ad318947e387470..612eb27b471a9ebfdea29a58e5a32931f869bfb6 100644 +index 1b7d797dac1ff7ee945cf4ef8c6861475a31903d..f81b3e050f21ce10ea86892d9a6bee9a42561514 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java @@ -556,7 +556,7 @@ public final class ItemStack implements DataComponentHolder { diff --git a/patches/server/0821-Only-tick-item-frames-if-players-can-see-it.patch b/patches/server/0820-Only-tick-item-frames-if-players-can-see-it.patch similarity index 100% rename from patches/server/0821-Only-tick-item-frames-if-players-can-see-it.patch rename to patches/server/0820-Only-tick-item-frames-if-players-can-see-it.patch diff --git a/patches/server/0822-Fix-cmd-permission-levels-for-command-blocks.patch b/patches/server/0821-Fix-cmd-permission-levels-for-command-blocks.patch similarity index 100% rename from patches/server/0822-Fix-cmd-permission-levels-for-command-blocks.patch rename to patches/server/0821-Fix-cmd-permission-levels-for-command-blocks.patch diff --git a/patches/server/0823-Add-option-to-disable-block-updates.patch b/patches/server/0822-Add-option-to-disable-block-updates.patch similarity index 100% rename from patches/server/0823-Add-option-to-disable-block-updates.patch rename to patches/server/0822-Add-option-to-disable-block-updates.patch diff --git a/patches/server/0824-Call-missing-BlockDispenseEvent.patch b/patches/server/0823-Call-missing-BlockDispenseEvent.patch similarity index 100% rename from patches/server/0824-Call-missing-BlockDispenseEvent.patch rename to patches/server/0823-Call-missing-BlockDispenseEvent.patch diff --git a/patches/server/0825-Don-t-load-chunks-for-supporting-block-checks.patch b/patches/server/0824-Don-t-load-chunks-for-supporting-block-checks.patch similarity index 100% rename from patches/server/0825-Don-t-load-chunks-for-supporting-block-checks.patch rename to patches/server/0824-Don-t-load-chunks-for-supporting-block-checks.patch diff --git a/patches/server/0826-Optimize-player-lookups-for-beacons.patch b/patches/server/0825-Optimize-player-lookups-for-beacons.patch similarity index 100% rename from patches/server/0826-Optimize-player-lookups-for-beacons.patch rename to patches/server/0825-Optimize-player-lookups-for-beacons.patch diff --git a/patches/server/0827-More-Sign-Block-API.patch b/patches/server/0826-More-Sign-Block-API.patch similarity index 100% rename from patches/server/0827-More-Sign-Block-API.patch rename to patches/server/0826-More-Sign-Block-API.patch diff --git a/patches/server/0828-fix-item-meta-for-tadpole-buckets.patch b/patches/server/0827-fix-item-meta-for-tadpole-buckets.patch similarity index 100% rename from patches/server/0828-fix-item-meta-for-tadpole-buckets.patch rename to patches/server/0827-fix-item-meta-for-tadpole-buckets.patch diff --git a/patches/server/0829-Fix-BanList-API.patch b/patches/server/0828-Fix-BanList-API.patch similarity index 99% rename from patches/server/0829-Fix-BanList-API.patch rename to patches/server/0828-Fix-BanList-API.patch index 58b6ec4b043e..639d56d79e4e 100644 --- a/patches/server/0829-Fix-BanList-API.patch +++ b/patches/server/0828-Fix-BanList-API.patch @@ -208,7 +208,7 @@ index 172202accf4448a933fcf1ff820316c7910dd7f7..50ee7656580d386db473c054f5c5ec57 return null; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index de0dc5b37bd0823409974befdd96676b2575cf48..642cdf6a205017b9835ad423206617fd3b9a32bf 100644 +index 3d52de930c4358843c5a8c88a1dce478b61ed616..de96fdd4b6129f875e710670f6734bf7fa7a4cfb 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1775,23 +1775,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0830-Determine-lava-and-water-fluid-explosion-resistance-.patch b/patches/server/0829-Determine-lava-and-water-fluid-explosion-resistance-.patch similarity index 100% rename from patches/server/0830-Determine-lava-and-water-fluid-explosion-resistance-.patch rename to patches/server/0829-Determine-lava-and-water-fluid-explosion-resistance-.patch diff --git a/patches/server/0831-Fix-possible-NPE-on-painting-creation.patch b/patches/server/0830-Fix-possible-NPE-on-painting-creation.patch similarity index 100% rename from patches/server/0831-Fix-possible-NPE-on-painting-creation.patch rename to patches/server/0830-Fix-possible-NPE-on-painting-creation.patch diff --git a/patches/server/0832-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch b/patches/server/0831-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch similarity index 100% rename from patches/server/0832-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch rename to patches/server/0831-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch diff --git a/patches/server/0833-ExperienceOrb-should-call-EntitySpawnEvent.patch b/patches/server/0832-ExperienceOrb-should-call-EntitySpawnEvent.patch similarity index 100% rename from patches/server/0833-ExperienceOrb-should-call-EntitySpawnEvent.patch rename to patches/server/0832-ExperienceOrb-should-call-EntitySpawnEvent.patch diff --git a/patches/server/0834-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch b/patches/server/0833-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch similarity index 100% rename from patches/server/0834-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch rename to patches/server/0833-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch diff --git a/patches/server/0835-Add-whitelist-events.patch b/patches/server/0834-Add-whitelist-events.patch similarity index 100% rename from patches/server/0835-Add-whitelist-events.patch rename to patches/server/0834-Add-whitelist-events.patch diff --git a/patches/server/0836-Implement-PlayerFailMoveEvent.patch b/patches/server/0835-Implement-PlayerFailMoveEvent.patch similarity index 98% rename from patches/server/0836-Implement-PlayerFailMoveEvent.patch rename to patches/server/0835-Implement-PlayerFailMoveEvent.patch index 6d31aefbe8c8..19858740af64 100644 --- a/patches/server/0836-Implement-PlayerFailMoveEvent.patch +++ b/patches/server/0835-Implement-PlayerFailMoveEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Implement PlayerFailMoveEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index eb81cd8421aa2fc011e5cb38e8a52b55fc1938b7..3b5beeb1599700fcc92f741613f84d6141078626 100644 +index 60d58622fd568932c019ba6a4e4070a881fdda53..368547270a3e6cdbda812fcf0ed2519d71383b81 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1271,8 +1271,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0837-Folia-scheduler-and-owned-region-API.patch b/patches/server/0836-Folia-scheduler-and-owned-region-API.patch similarity index 99% rename from patches/server/0837-Folia-scheduler-and-owned-region-API.patch rename to patches/server/0836-Folia-scheduler-and-owned-region-API.patch index 14d6c5a05c12..ed91fc99abe7 100644 --- a/patches/server/0837-Folia-scheduler-and-owned-region-API.patch +++ b/patches/server/0836-Folia-scheduler-and-owned-region-API.patch @@ -1173,7 +1173,7 @@ index ce35bce647a6f7250b855ad7e542367b5ffd10d1..96fdbdcbe43c22b62f679837409da08f gameprofilerfiller.push("commandFunctions"); MinecraftTimings.commandFunctionsTimer.startTiming(); // Spigot // Paper diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 4fe3024e26b56c2d796acf703a1bc200ff309f09..7356a027ae3bca3a9f2056ef6849d5fab38a0df3 100644 +index f9212fc2db00531da1618780e231e8ad21285907..a9063533ea4b2b349d476127b99c822203d7dfcb 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -598,6 +598,7 @@ public abstract class PlayerList { diff --git a/patches/server/0838-Only-erase-allay-memory-on-non-item-targets.patch b/patches/server/0837-Only-erase-allay-memory-on-non-item-targets.patch similarity index 100% rename from patches/server/0838-Only-erase-allay-memory-on-non-item-targets.patch rename to patches/server/0837-Only-erase-allay-memory-on-non-item-targets.patch diff --git a/patches/server/0839-Fix-rotation-when-spawning-display-entities.patch b/patches/server/0838-Fix-rotation-when-spawning-display-entities.patch similarity index 100% rename from patches/server/0839-Fix-rotation-when-spawning-display-entities.patch rename to patches/server/0838-Fix-rotation-when-spawning-display-entities.patch diff --git a/patches/server/0840-Only-capture-actual-tree-growth.patch b/patches/server/0839-Only-capture-actual-tree-growth.patch similarity index 98% rename from patches/server/0840-Only-capture-actual-tree-growth.patch rename to patches/server/0839-Only-capture-actual-tree-growth.patch index 9ec84e6c2ef5..63a72d6ca21e 100644 --- a/patches/server/0840-Only-capture-actual-tree-growth.patch +++ b/patches/server/0839-Only-capture-actual-tree-growth.patch @@ -38,7 +38,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..1cb5e107a391ab56942cdb2d1cae7d56 @Override public CrashReportCategory fillReportDetails(CrashReport report) { diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 612eb27b471a9ebfdea29a58e5a32931f869bfb6..db971851a9e219ead89d71bb97d65ff73d9fd285 100644 +index f81b3e050f21ce10ea86892d9a6bee9a42561514..cb6bcf8b61793882252827309ffa99526244e445 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java @@ -469,6 +469,7 @@ public final class ItemStack implements DataComponentHolder { diff --git a/patches/server/0841-Use-correct-source-for-mushroom-block-spread-event.patch b/patches/server/0840-Use-correct-source-for-mushroom-block-spread-event.patch similarity index 100% rename from patches/server/0841-Use-correct-source-for-mushroom-block-spread-event.patch rename to patches/server/0840-Use-correct-source-for-mushroom-block-spread-event.patch diff --git a/patches/server/0842-Respect-randomizeData-on-more-entities-when-spawning.patch b/patches/server/0841-Respect-randomizeData-on-more-entities-when-spawning.patch similarity index 100% rename from patches/server/0842-Respect-randomizeData-on-more-entities-when-spawning.patch rename to patches/server/0841-Respect-randomizeData-on-more-entities-when-spawning.patch diff --git a/patches/server/0843-Use-correct-seed-on-api-world-load.patch b/patches/server/0842-Use-correct-seed-on-api-world-load.patch similarity index 100% rename from patches/server/0843-Use-correct-seed-on-api-world-load.patch rename to patches/server/0842-Use-correct-seed-on-api-world-load.patch diff --git a/patches/server/0844-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch b/patches/server/0843-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch similarity index 100% rename from patches/server/0844-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch rename to patches/server/0843-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch diff --git a/patches/server/0845-Cache-map-ids-on-item-frames.patch b/patches/server/0844-Cache-map-ids-on-item-frames.patch similarity index 100% rename from patches/server/0845-Cache-map-ids-on-item-frames.patch rename to patches/server/0844-Cache-map-ids-on-item-frames.patch diff --git a/patches/server/0846-Fix-custom-statistic-criteria-creation.patch b/patches/server/0845-Fix-custom-statistic-criteria-creation.patch similarity index 100% rename from patches/server/0846-Fix-custom-statistic-criteria-creation.patch rename to patches/server/0845-Fix-custom-statistic-criteria-creation.patch diff --git a/patches/server/0847-Bandaid-fix-for-Effect.patch b/patches/server/0846-Bandaid-fix-for-Effect.patch similarity index 98% rename from patches/server/0847-Bandaid-fix-for-Effect.patch rename to patches/server/0846-Bandaid-fix-for-Effect.patch index 2fa9de2aa84b..a4996fb167d5 100644 --- a/patches/server/0847-Bandaid-fix-for-Effect.patch +++ b/patches/server/0846-Bandaid-fix-for-Effect.patch @@ -81,7 +81,7 @@ index 67d6840faea539b41ba3abb6d94b28e417a84511..b646f882de3ab04d54d07e9e944c261c // Special case: the axis is optional for ELECTRIC_SPARK Preconditions.checkArgument(effect.getData() == null || effect == Effect.ELECTRIC_SPARK, "Wrong kind of data for the %s effect", effect); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 642cdf6a205017b9835ad423206617fd3b9a32bf..ebc0c5c2365cca1f7ca28cc3f6a3f7494134a047 100644 +index de96fdd4b6129f875e710670f6734bf7fa7a4cfb..86f74c35a74b3c3a1d04d6be79e0df30642d475a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -934,7 +934,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0848-SculkCatalyst-bloom-API.patch b/patches/server/0847-SculkCatalyst-bloom-API.patch similarity index 100% rename from patches/server/0848-SculkCatalyst-bloom-API.patch rename to patches/server/0847-SculkCatalyst-bloom-API.patch diff --git a/patches/server/0849-API-for-an-entity-s-scoreboard-name.patch b/patches/server/0848-API-for-an-entity-s-scoreboard-name.patch similarity index 100% rename from patches/server/0849-API-for-an-entity-s-scoreboard-name.patch rename to patches/server/0848-API-for-an-entity-s-scoreboard-name.patch diff --git a/patches/server/0850-Deprecate-and-replace-methods-with-old-StructureType.patch b/patches/server/0849-Deprecate-and-replace-methods-with-old-StructureType.patch similarity index 100% rename from patches/server/0850-Deprecate-and-replace-methods-with-old-StructureType.patch rename to patches/server/0849-Deprecate-and-replace-methods-with-old-StructureType.patch diff --git a/patches/server/0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch b/patches/server/0850-Don-t-tab-complete-namespaced-commands-if-send-names.patch similarity index 95% rename from patches/server/0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch rename to patches/server/0850-Don-t-tab-complete-namespaced-commands-if-send-names.patch index 43c52d9c14c8..58454d72670c 100644 --- a/patches/server/0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch +++ b/patches/server/0850-Don-t-tab-complete-namespaced-commands-if-send-names.patch @@ -11,7 +11,7 @@ This patch prevents server from sending namespaced commands when player requests tab-complete only commands. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 3b5beeb1599700fcc92f741613f84d6141078626..8e877e4cea2a14cc0a8fed41e983712645ba8c48 100644 +index 368547270a3e6cdbda812fcf0ed2519d71383b81..293c42dd5e870986a2797840756bd7c4d6a34a5d 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -832,6 +832,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0852-Properly-handle-BlockBreakEvent-isDropItems.patch b/patches/server/0851-Properly-handle-BlockBreakEvent-isDropItems.patch similarity index 100% rename from patches/server/0852-Properly-handle-BlockBreakEvent-isDropItems.patch rename to patches/server/0851-Properly-handle-BlockBreakEvent-isDropItems.patch diff --git a/patches/server/0853-Fire-entity-death-event-for-ender-dragon.patch b/patches/server/0852-Fire-entity-death-event-for-ender-dragon.patch similarity index 100% rename from patches/server/0853-Fire-entity-death-event-for-ender-dragon.patch rename to patches/server/0852-Fire-entity-death-event-for-ender-dragon.patch diff --git a/patches/server/0854-Configurable-entity-tracking-range-by-Y-coordinate.patch b/patches/server/0853-Configurable-entity-tracking-range-by-Y-coordinate.patch similarity index 100% rename from patches/server/0854-Configurable-entity-tracking-range-by-Y-coordinate.patch rename to patches/server/0853-Configurable-entity-tracking-range-by-Y-coordinate.patch diff --git a/patches/server/0855-Add-Listing-API-for-Player.patch b/patches/server/0854-Add-Listing-API-for-Player.patch similarity index 98% rename from patches/server/0855-Add-Listing-API-for-Player.patch rename to patches/server/0854-Add-Listing-API-for-Player.patch index 5090bed69812..34070f7cf34f 100644 --- a/patches/server/0855-Add-Listing-API-for-Player.patch +++ b/patches/server/0854-Add-Listing-API-for-Player.patch @@ -85,7 +85,7 @@ index 29b465fc1dc50e0e84ddb889c5303e80fe662874..4d67d98257b2cb9045d03c999cfd4ba2 static class EntryBuilder { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 7356a027ae3bca3a9f2056ef6849d5fab38a0df3..a4937d11b79cef41f3fbf79282c0c435e794dbfe 100644 +index a9063533ea4b2b349d476127b99c822203d7dfcb..218e18b9c7836bc4c9d3eba78e0717cabb9d6b61 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -363,14 +363,22 @@ public abstract class PlayerList { @@ -122,7 +122,7 @@ index 7356a027ae3bca3a9f2056ef6849d5fab38a0df3..a4937d11b79cef41f3fbf79282c0c435 // Paper end - Use single player info update packet on join player.sentListPacket = true; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index ebc0c5c2365cca1f7ca28cc3f6a3f7494134a047..7104ffd4dd72a053793eb52c8df29eadbd184221 100644 +index 86f74c35a74b3c3a1d04d6be79e0df30642d475a..9b59e7efde0516d55643e8ceb6d94e02ed22aacc 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -206,6 +206,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0856-Configurable-Region-Compression-Format.patch b/patches/server/0855-Configurable-Region-Compression-Format.patch similarity index 100% rename from patches/server/0856-Configurable-Region-Compression-Format.patch rename to patches/server/0855-Configurable-Region-Compression-Format.patch diff --git a/patches/server/0857-Add-BlockFace-to-BlockDamageEvent.patch b/patches/server/0856-Add-BlockFace-to-BlockDamageEvent.patch similarity index 100% rename from patches/server/0857-Add-BlockFace-to-BlockDamageEvent.patch rename to patches/server/0856-Add-BlockFace-to-BlockDamageEvent.patch diff --git a/patches/server/0858-Fix-NPE-on-Boat-getStatus.patch b/patches/server/0857-Fix-NPE-on-Boat-getStatus.patch similarity index 100% rename from patches/server/0858-Fix-NPE-on-Boat-getStatus.patch rename to patches/server/0857-Fix-NPE-on-Boat-getStatus.patch diff --git a/patches/server/0859-Expand-Pose-API.patch b/patches/server/0858-Expand-Pose-API.patch similarity index 100% rename from patches/server/0859-Expand-Pose-API.patch rename to patches/server/0858-Expand-Pose-API.patch diff --git a/patches/server/0860-More-DragonBattle-API.patch b/patches/server/0859-More-DragonBattle-API.patch similarity index 100% rename from patches/server/0860-More-DragonBattle-API.patch rename to patches/server/0859-More-DragonBattle-API.patch diff --git a/patches/server/0861-Add-PlayerPickItemEvent.patch b/patches/server/0860-Add-PlayerPickItemEvent.patch similarity index 96% rename from patches/server/0861-Add-PlayerPickItemEvent.patch rename to patches/server/0860-Add-PlayerPickItemEvent.patch index 8309e2c11848..8a28695a2b67 100644 --- a/patches/server/0861-Add-PlayerPickItemEvent.patch +++ b/patches/server/0860-Add-PlayerPickItemEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerPickItemEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 8e877e4cea2a14cc0a8fed41e983712645ba8c48..d4250cc73bc51c51b78a9392a9879d47dc67f159 100644 +index 293c42dd5e870986a2797840756bd7c4d6a34a5d..c50c3d11700aadd4c0e7114b4b6d5c5d15a33ac4 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -947,7 +947,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0862-Allow-trident-custom-damage.patch b/patches/server/0861-Allow-trident-custom-damage.patch similarity index 100% rename from patches/server/0862-Allow-trident-custom-damage.patch rename to patches/server/0861-Allow-trident-custom-damage.patch diff --git a/patches/server/0863-Expose-hand-in-BlockCanBuildEvent.patch b/patches/server/0862-Expose-hand-in-BlockCanBuildEvent.patch similarity index 100% rename from patches/server/0863-Expose-hand-in-BlockCanBuildEvent.patch rename to patches/server/0862-Expose-hand-in-BlockCanBuildEvent.patch diff --git a/patches/server/0864-Optimize-nearest-structure-border-iteration.patch b/patches/server/0863-Optimize-nearest-structure-border-iteration.patch similarity index 100% rename from patches/server/0864-Optimize-nearest-structure-border-iteration.patch rename to patches/server/0863-Optimize-nearest-structure-border-iteration.patch diff --git a/patches/server/0865-Implement-OfflinePlayer-isConnected.patch b/patches/server/0864-Implement-OfflinePlayer-isConnected.patch similarity index 94% rename from patches/server/0865-Implement-OfflinePlayer-isConnected.patch rename to patches/server/0864-Implement-OfflinePlayer-isConnected.patch index 6c7d4f55ccf5..7c4e1d35362a 100644 --- a/patches/server/0865-Implement-OfflinePlayer-isConnected.patch +++ b/patches/server/0864-Implement-OfflinePlayer-isConnected.patch @@ -23,7 +23,7 @@ index 2c2c4db31a746b4eb853dc04c6b3e5631bbfa034..4f4e3ee18d586f61706504218cddc06a public String getName() { Player player = this.getPlayer(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 7104ffd4dd72a053793eb52c8df29eadbd184221..ea5e3973a4021a4584d3b8b33c9d50001f4c0fe6 100644 +index 9b59e7efde0516d55643e8ceb6d94e02ed22aacc..4de2a6a04a5bcf635f2bb5da640eb5941183e87c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -261,6 +261,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0866-Fix-slot-desync.patch b/patches/server/0865-Fix-slot-desync.patch similarity index 98% rename from patches/server/0866-Fix-slot-desync.patch rename to patches/server/0865-Fix-slot-desync.patch index afdb75279e80..5b0a3d572157 100644 --- a/patches/server/0866-Fix-slot-desync.patch +++ b/patches/server/0865-Fix-slot-desync.patch @@ -22,7 +22,7 @@ index f05a9fd321a4af28e9771bbf39d73f80dd4160c9..90aa8e401e1d092a31ff21699409b836 this.containerMenu.findSlot(this.getInventory(), this.getInventory().selected).ifPresent(s -> { this.containerSynchronizer.sendSlotChange(this.containerMenu, s, this.getMainHandItem()); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index d4250cc73bc51c51b78a9392a9879d47dc67f159..182897b4ab9415b7aab0b968274993dd43a47903 100644 +index c50c3d11700aadd4c0e7114b4b6d5c5d15a33ac4..af7696900171ea6b7941251046bfc10c1f4eb469 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -2749,10 +2749,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -67,7 +67,7 @@ index d99760f943846a1cfe5d0ec97313f453004feb98..3e00bbff266fc71b07014e7e047d77b7 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java -index f745a554b9b84a53d9bd942ca9908153fb0a668c..ec3edd2eefc398dac9058e082c52a98dc48db36d 100644 +index 4c6dc427b90012b0945e073dd905dc7e8d1bec82..76aca47d8638d5c37c57d3a59fa7f8ceaa5a53b4 100644 --- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java +++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java @@ -238,6 +238,7 @@ public class Goat extends Animal { diff --git a/patches/server/0867-Add-titleOverride-to-InventoryOpenEvent.patch b/patches/server/0866-Add-titleOverride-to-InventoryOpenEvent.patch similarity index 100% rename from patches/server/0867-Add-titleOverride-to-InventoryOpenEvent.patch rename to patches/server/0866-Add-titleOverride-to-InventoryOpenEvent.patch diff --git a/patches/server/0868-Configure-sniffer-egg-hatch-time.patch b/patches/server/0867-Configure-sniffer-egg-hatch-time.patch similarity index 100% rename from patches/server/0868-Configure-sniffer-egg-hatch-time.patch rename to patches/server/0867-Configure-sniffer-egg-hatch-time.patch diff --git a/patches/server/0869-Do-crystal-portal-proximity-check-before-entity-look.patch b/patches/server/0868-Do-crystal-portal-proximity-check-before-entity-look.patch similarity index 100% rename from patches/server/0869-Do-crystal-portal-proximity-check-before-entity-look.patch rename to patches/server/0868-Do-crystal-portal-proximity-check-before-entity-look.patch diff --git a/patches/server/0870-Skip-POI-finding-if-stuck-in-vehicle.patch b/patches/server/0869-Skip-POI-finding-if-stuck-in-vehicle.patch similarity index 100% rename from patches/server/0870-Skip-POI-finding-if-stuck-in-vehicle.patch rename to patches/server/0869-Skip-POI-finding-if-stuck-in-vehicle.patch diff --git a/patches/server/0871-Add-slot-sanity-checks-in-container-clicks.patch b/patches/server/0870-Add-slot-sanity-checks-in-container-clicks.patch similarity index 96% rename from patches/server/0871-Add-slot-sanity-checks-in-container-clicks.patch rename to patches/server/0870-Add-slot-sanity-checks-in-container-clicks.patch index 22ddd65752d7..08f85bdb3bff 100644 --- a/patches/server/0871-Add-slot-sanity-checks-in-container-clicks.patch +++ b/patches/server/0870-Add-slot-sanity-checks-in-container-clicks.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add slot sanity checks in container clicks diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 182897b4ab9415b7aab0b968274993dd43a47903..17402d393df27474b38c8d9b0b7aa424ec34d1a9 100644 +index af7696900171ea6b7941251046bfc10c1f4eb469..836e6b705b201253f2b81d1ca0228b8a0266a1dd 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -3011,6 +3011,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0872-Call-BlockRedstoneEvents-for-lecterns.patch b/patches/server/0871-Call-BlockRedstoneEvents-for-lecterns.patch similarity index 100% rename from patches/server/0872-Call-BlockRedstoneEvents-for-lecterns.patch rename to patches/server/0871-Call-BlockRedstoneEvents-for-lecterns.patch diff --git a/patches/server/0873-Allow-proper-checking-of-empty-item-stacks.patch b/patches/server/0872-Allow-proper-checking-of-empty-item-stacks.patch similarity index 100% rename from patches/server/0873-Allow-proper-checking-of-empty-item-stacks.patch rename to patches/server/0872-Allow-proper-checking-of-empty-item-stacks.patch diff --git a/patches/server/0874-Fix-silent-equipment-change-for-mobs.patch b/patches/server/0873-Fix-silent-equipment-change-for-mobs.patch similarity index 100% rename from patches/server/0874-Fix-silent-equipment-change-for-mobs.patch rename to patches/server/0873-Fix-silent-equipment-change-for-mobs.patch diff --git a/patches/server/0875-Fix-spigot-s-Forced-Stats.patch b/patches/server/0874-Fix-spigot-s-Forced-Stats.patch similarity index 100% rename from patches/server/0875-Fix-spigot-s-Forced-Stats.patch rename to patches/server/0874-Fix-spigot-s-Forced-Stats.patch diff --git a/patches/server/0876-Add-missing-InventoryHolders-to-inventories.patch b/patches/server/0875-Add-missing-InventoryHolders-to-inventories.patch similarity index 100% rename from patches/server/0876-Add-missing-InventoryHolders-to-inventories.patch rename to patches/server/0875-Add-missing-InventoryHolders-to-inventories.patch diff --git a/patches/server/0877-Do-not-read-tile-entities-in-chunks-that-are-positio.patch b/patches/server/0876-Do-not-read-tile-entities-in-chunks-that-are-positio.patch similarity index 100% rename from patches/server/0877-Do-not-read-tile-entities-in-chunks-that-are-positio.patch rename to patches/server/0876-Do-not-read-tile-entities-in-chunks-that-are-positio.patch diff --git a/patches/server/0878-Add-missing-logs-for-log-ips-config-option.patch b/patches/server/0877-Add-missing-logs-for-log-ips-config-option.patch similarity index 100% rename from patches/server/0878-Add-missing-logs-for-log-ips-config-option.patch rename to patches/server/0877-Add-missing-logs-for-log-ips-config-option.patch diff --git a/patches/server/0879-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch b/patches/server/0878-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch similarity index 100% rename from patches/server/0879-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch rename to patches/server/0878-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch diff --git a/patches/server/0880-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch b/patches/server/0879-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch similarity index 100% rename from patches/server/0880-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch rename to patches/server/0879-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch diff --git a/patches/server/0881-Fix-team-sidebar-objectives-not-being-cleared.patch b/patches/server/0880-Fix-team-sidebar-objectives-not-being-cleared.patch similarity index 100% rename from patches/server/0881-Fix-team-sidebar-objectives-not-being-cleared.patch rename to patches/server/0880-Fix-team-sidebar-objectives-not-being-cleared.patch diff --git a/patches/server/0882-Fix-missing-map-initialize-event-call.patch b/patches/server/0881-Fix-missing-map-initialize-event-call.patch similarity index 100% rename from patches/server/0882-Fix-missing-map-initialize-event-call.patch rename to patches/server/0881-Fix-missing-map-initialize-event-call.patch diff --git a/patches/server/0883-Update-entity-data-when-attaching-firework-to-entity.patch b/patches/server/0882-Update-entity-data-when-attaching-firework-to-entity.patch similarity index 100% rename from patches/server/0883-Update-entity-data-when-attaching-firework-to-entity.patch rename to patches/server/0882-Update-entity-data-when-attaching-firework-to-entity.patch diff --git a/patches/server/0884-Fix-UnsafeValues-loadAdvancement.patch b/patches/server/0883-Fix-UnsafeValues-loadAdvancement.patch similarity index 100% rename from patches/server/0884-Fix-UnsafeValues-loadAdvancement.patch rename to patches/server/0883-Fix-UnsafeValues-loadAdvancement.patch diff --git a/patches/server/0885-Add-player-idle-duration-API.patch b/patches/server/0884-Add-player-idle-duration-API.patch similarity index 91% rename from patches/server/0885-Add-player-idle-duration-API.patch rename to patches/server/0884-Add-player-idle-duration-API.patch index d715a2ed4a3d..3f3f534dbcf6 100644 --- a/patches/server/0885-Add-player-idle-duration-API.patch +++ b/patches/server/0884-Add-player-idle-duration-API.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add player idle duration API Implements API for getting and resetting a player's idle duration. diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index ea5e3973a4021a4584d3b8b33c9d50001f4c0fe6..c73089566eccc15aa747e3e3707d089a0f2b8d1d 100644 +index 4de2a6a04a5bcf635f2bb5da640eb5941183e87c..4060a25f414631f702f04a53169b14e2ae6f9e31 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -3447,6 +3447,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0886-Don-t-check-if-we-can-see-non-visible-entities.patch b/patches/server/0885-Don-t-check-if-we-can-see-non-visible-entities.patch similarity index 100% rename from patches/server/0886-Don-t-check-if-we-can-see-non-visible-entities.patch rename to patches/server/0885-Don-t-check-if-we-can-see-non-visible-entities.patch diff --git a/patches/server/0887-Fix-NPE-in-SculkBloomEvent-world-access.patch b/patches/server/0886-Fix-NPE-in-SculkBloomEvent-world-access.patch similarity index 100% rename from patches/server/0887-Fix-NPE-in-SculkBloomEvent-world-access.patch rename to patches/server/0886-Fix-NPE-in-SculkBloomEvent-world-access.patch diff --git a/patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch b/patches/server/0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch similarity index 90% rename from patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch rename to patches/server/0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch index fe05ccc109e2..272dd0236ddb 100644 --- a/patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch +++ b/patches/server/0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Allow null itemstack for Player#sendEquipmentChange diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index c73089566eccc15aa747e3e3707d089a0f2b8d1d..74b90ee971ec799cf19551ac63a9b01f77500967 100644 +index 4060a25f414631f702f04a53169b14e2ae6f9e31..a343684b52594c295d5a75b9005da3434b72f329 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1144,7 +1144,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0889-Optimize-VarInts.patch b/patches/server/0888-Optimize-VarInts.patch similarity index 100% rename from patches/server/0889-Optimize-VarInts.patch rename to patches/server/0888-Optimize-VarInts.patch diff --git a/patches/server/0890-Add-API-to-get-the-collision-shape-of-a-block-before.patch b/patches/server/0889-Add-API-to-get-the-collision-shape-of-a-block-before.patch similarity index 100% rename from patches/server/0890-Add-API-to-get-the-collision-shape-of-a-block-before.patch rename to patches/server/0889-Add-API-to-get-the-collision-shape-of-a-block-before.patch diff --git a/patches/server/0891-Add-predicate-for-blocks-when-raytracing.patch b/patches/server/0890-Add-predicate-for-blocks-when-raytracing.patch similarity index 100% rename from patches/server/0891-Add-predicate-for-blocks-when-raytracing.patch rename to patches/server/0890-Add-predicate-for-blocks-when-raytracing.patch diff --git a/patches/server/0892-Broadcast-take-item-packets-with-collector-as-source.patch b/patches/server/0891-Broadcast-take-item-packets-with-collector-as-source.patch similarity index 100% rename from patches/server/0892-Broadcast-take-item-packets-with-collector-as-source.patch rename to patches/server/0891-Broadcast-take-item-packets-with-collector-as-source.patch diff --git a/patches/server/0893-Expand-LingeringPotion-API.patch b/patches/server/0892-Expand-LingeringPotion-API.patch similarity index 100% rename from patches/server/0893-Expand-LingeringPotion-API.patch rename to patches/server/0892-Expand-LingeringPotion-API.patch diff --git a/patches/server/0894-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch b/patches/server/0893-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch similarity index 100% rename from patches/server/0894-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch rename to patches/server/0893-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch diff --git a/patches/server/0895-Add-hand-to-fish-event-for-all-player-interactions.patch b/patches/server/0894-Add-hand-to-fish-event-for-all-player-interactions.patch similarity index 100% rename from patches/server/0895-Add-hand-to-fish-event-for-all-player-interactions.patch rename to patches/server/0894-Add-hand-to-fish-event-for-all-player-interactions.patch diff --git a/patches/server/0896-Fix-several-issues-with-EntityBreedEvent.patch b/patches/server/0895-Fix-several-issues-with-EntityBreedEvent.patch similarity index 100% rename from patches/server/0896-Fix-several-issues-with-EntityBreedEvent.patch rename to patches/server/0895-Fix-several-issues-with-EntityBreedEvent.patch diff --git a/patches/server/0897-Add-UUID-attribute-modifier-API.patch b/patches/server/0896-Add-UUID-attribute-modifier-API.patch similarity index 100% rename from patches/server/0897-Add-UUID-attribute-modifier-API.patch rename to patches/server/0896-Add-UUID-attribute-modifier-API.patch diff --git a/patches/server/0898-Fix-missing-event-call-for-entity-teleport-API.patch b/patches/server/0897-Fix-missing-event-call-for-entity-teleport-API.patch similarity index 100% rename from patches/server/0898-Fix-missing-event-call-for-entity-teleport-API.patch rename to patches/server/0897-Fix-missing-event-call-for-entity-teleport-API.patch diff --git a/patches/server/0899-Lazily-create-LootContext-for-criterions.patch b/patches/server/0898-Lazily-create-LootContext-for-criterions.patch similarity index 100% rename from patches/server/0899-Lazily-create-LootContext-for-criterions.patch rename to patches/server/0898-Lazily-create-LootContext-for-criterions.patch diff --git a/patches/server/0900-Don-t-fire-sync-events-during-worldgen.patch b/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch similarity index 100% rename from patches/server/0900-Don-t-fire-sync-events-during-worldgen.patch rename to patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch diff --git a/patches/server/0901-Add-Structure-check-API.patch b/patches/server/0900-Add-Structure-check-API.patch similarity index 100% rename from patches/server/0901-Add-Structure-check-API.patch rename to patches/server/0900-Add-Structure-check-API.patch diff --git a/patches/server/0902-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch b/patches/server/0901-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch similarity index 100% rename from patches/server/0902-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch rename to patches/server/0901-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch diff --git a/patches/server/0903-Restore-vanilla-entity-drops-behavior.patch b/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch similarity index 100% rename from patches/server/0903-Restore-vanilla-entity-drops-behavior.patch rename to patches/server/0902-Restore-vanilla-entity-drops-behavior.patch diff --git a/patches/server/0904-Dont-resend-blocks-on-interactions.patch b/patches/server/0903-Dont-resend-blocks-on-interactions.patch similarity index 99% rename from patches/server/0904-Dont-resend-blocks-on-interactions.patch rename to patches/server/0903-Dont-resend-blocks-on-interactions.patch index 72f6df6566f3..04f0061970ea 100644 --- a/patches/server/0904-Dont-resend-blocks-on-interactions.patch +++ b/patches/server/0903-Dont-resend-blocks-on-interactions.patch @@ -149,7 +149,7 @@ index 002e2f8e956b2631529e2189be225385dfb501df..3bddfb6f7412ab86e0c090d0cbc6cf25 return false; } diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index db971851a9e219ead89d71bb97d65ff73d9fd285..bba4fbde31ef25bc086fefaa86f9a479ef6ccf26 100644 +index cb6bcf8b61793882252827309ffa99526244e445..98b5208baeaa12a5ff2788e457c542000d6ea48b 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java @@ -506,10 +506,12 @@ public final class ItemStack implements DataComponentHolder { diff --git a/patches/server/0905-add-more-scoreboard-API.patch b/patches/server/0904-add-more-scoreboard-API.patch similarity index 100% rename from patches/server/0905-add-more-scoreboard-API.patch rename to patches/server/0904-add-more-scoreboard-API.patch diff --git a/patches/server/0906-Improve-Registry.patch b/patches/server/0905-Improve-Registry.patch similarity index 100% rename from patches/server/0906-Improve-Registry.patch rename to patches/server/0905-Improve-Registry.patch diff --git a/patches/server/0907-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch b/patches/server/0906-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch similarity index 100% rename from patches/server/0907-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch rename to patches/server/0906-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch diff --git a/patches/server/0908-Add-experience-points-API.patch b/patches/server/0907-Add-experience-points-API.patch similarity index 97% rename from patches/server/0908-Add-experience-points-API.patch rename to patches/server/0907-Add-experience-points-API.patch index 9111f82b8ffd..14c94b5af4c2 100644 --- a/patches/server/0908-Add-experience-points-API.patch +++ b/patches/server/0907-Add-experience-points-API.patch @@ -18,7 +18,7 @@ index aca888c2f02b09ac6739bdc81b194c4527dd69f5..a19a795deaa7f46c92b97912e2ade006 // Paper start - send while respecting visibility private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 74b90ee971ec799cf19551ac63a9b01f77500967..a807f37a4b937fc3a1d89cb5d116224c9b3c5f49 100644 +index a343684b52594c295d5a75b9005da3434b72f329..a6b26d33de210e8c5351f3246b9ac391eb688689 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1949,6 +1949,49 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0909-Add-drops-to-shear-events.patch b/patches/server/0908-Add-drops-to-shear-events.patch similarity index 99% rename from patches/server/0909-Add-drops-to-shear-events.patch rename to patches/server/0908-Add-drops-to-shear-events.patch index 21efa0e4146e..d09a2508e859 100644 --- a/patches/server/0909-Add-drops-to-shear-events.patch +++ b/patches/server/0908-Add-drops-to-shear-events.patch @@ -44,7 +44,7 @@ index a3095eee48d8b87a35ad35da9c8a2a9ca20c92bc..88dcde6c901753d002a99333eb646bda + // Paper end - custom shear drops } diff --git a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java -index d4d343e2d75a3e3ea787c3c68c64970f5b239f81..fad312784476d361e548a4d4ea942fa60ec72c66 100644 +index d4d343e2d75a3e3ea787c3c68c64970f5b239f81..feeb7bc34ae02e44d7f13f0bae5d175ef924c53a 100644 --- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java +++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java @@ -46,6 +46,7 @@ import net.minecraft.world.level.storage.loot.BuiltInLootTables; @@ -115,7 +115,7 @@ index d4d343e2d75a3e3ea787c3c68c64970f5b239f81..fad312784476d361e548a4d4ea942fa6 + drops.forEach(itemstack1 -> { + for (final ItemStack drop : drops) { + ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), drop); -+ this.spawnAtLocation(entityitem); ++ this.spawnAtLocation(world, entityitem); } - + // Paper end - custom shear drops; moved drop generation to separate method diff --git a/patches/server/0910-Add-PlayerShieldDisableEvent.patch b/patches/server/0909-Add-PlayerShieldDisableEvent.patch similarity index 100% rename from patches/server/0910-Add-PlayerShieldDisableEvent.patch rename to patches/server/0909-Add-PlayerShieldDisableEvent.patch diff --git a/patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch b/patches/server/0910-Validate-ResourceLocation-in-NBT-reading.patch similarity index 100% rename from patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch rename to patches/server/0910-Validate-ResourceLocation-in-NBT-reading.patch diff --git a/patches/server/0912-Properly-handle-experience-dropping-on-block-break.patch b/patches/server/0911-Properly-handle-experience-dropping-on-block-break.patch similarity index 100% rename from patches/server/0912-Properly-handle-experience-dropping-on-block-break.patch rename to patches/server/0911-Properly-handle-experience-dropping-on-block-break.patch diff --git a/patches/server/0913-Fixup-NamespacedKey-handling.patch b/patches/server/0912-Fixup-NamespacedKey-handling.patch similarity index 100% rename from patches/server/0913-Fixup-NamespacedKey-handling.patch rename to patches/server/0912-Fixup-NamespacedKey-handling.patch diff --git a/patches/server/0914-Expose-LootTable-of-DecoratedPot.patch b/patches/server/0913-Expose-LootTable-of-DecoratedPot.patch similarity index 100% rename from patches/server/0914-Expose-LootTable-of-DecoratedPot.patch rename to patches/server/0913-Expose-LootTable-of-DecoratedPot.patch diff --git a/patches/server/0915-Reduce-allocation-of-Vec3D-by-entity-tracker.patch b/patches/server/0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch similarity index 100% rename from patches/server/0915-Reduce-allocation-of-Vec3D-by-entity-tracker.patch rename to patches/server/0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch diff --git a/patches/server/0916-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch b/patches/server/0915-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch similarity index 100% rename from patches/server/0916-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch rename to patches/server/0915-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch diff --git a/patches/server/0917-Add-ShulkerDuplicateEvent.patch b/patches/server/0916-Add-ShulkerDuplicateEvent.patch similarity index 100% rename from patches/server/0917-Add-ShulkerDuplicateEvent.patch rename to patches/server/0916-Add-ShulkerDuplicateEvent.patch diff --git a/patches/server/0918-Add-api-for-spawn-egg-texture-colors.patch b/patches/server/0917-Add-api-for-spawn-egg-texture-colors.patch similarity index 100% rename from patches/server/0918-Add-api-for-spawn-egg-texture-colors.patch rename to patches/server/0917-Add-api-for-spawn-egg-texture-colors.patch diff --git a/patches/server/0919-Add-Lifecycle-Event-system.patch b/patches/server/0918-Add-Lifecycle-Event-system.patch similarity index 100% rename from patches/server/0919-Add-Lifecycle-Event-system.patch rename to patches/server/0918-Add-Lifecycle-Event-system.patch diff --git a/patches/server/0920-ItemStack-Tooltip-API.patch b/patches/server/0919-ItemStack-Tooltip-API.patch similarity index 100% rename from patches/server/0920-ItemStack-Tooltip-API.patch rename to patches/server/0919-ItemStack-Tooltip-API.patch diff --git a/patches/server/0921-Add-getChunkSnapshot-includeLightData-parameter.patch b/patches/server/0920-Add-getChunkSnapshot-includeLightData-parameter.patch similarity index 100% rename from patches/server/0921-Add-getChunkSnapshot-includeLightData-parameter.patch rename to patches/server/0920-Add-getChunkSnapshot-includeLightData-parameter.patch diff --git a/patches/server/0922-Add-FluidState-API.patch b/patches/server/0921-Add-FluidState-API.patch similarity index 100% rename from patches/server/0922-Add-FluidState-API.patch rename to patches/server/0921-Add-FluidState-API.patch diff --git a/patches/server/0923-add-number-format-api.patch b/patches/server/0922-add-number-format-api.patch similarity index 100% rename from patches/server/0923-add-number-format-api.patch rename to patches/server/0922-add-number-format-api.patch diff --git a/patches/server/0924-improve-BanList-types.patch b/patches/server/0923-improve-BanList-types.patch similarity index 100% rename from patches/server/0924-improve-BanList-types.patch rename to patches/server/0923-improve-BanList-types.patch diff --git a/patches/server/0925-Expanded-Hopper-API.patch b/patches/server/0924-Expanded-Hopper-API.patch similarity index 100% rename from patches/server/0925-Expanded-Hopper-API.patch rename to patches/server/0924-Expanded-Hopper-API.patch diff --git a/patches/server/0926-Add-BlockBreakProgressUpdateEvent.patch b/patches/server/0925-Add-BlockBreakProgressUpdateEvent.patch similarity index 100% rename from patches/server/0926-Add-BlockBreakProgressUpdateEvent.patch rename to patches/server/0925-Add-BlockBreakProgressUpdateEvent.patch diff --git a/patches/server/0927-Deprecate-ItemStack-setType.patch b/patches/server/0926-Deprecate-ItemStack-setType.patch similarity index 100% rename from patches/server/0927-Deprecate-ItemStack-setType.patch rename to patches/server/0926-Deprecate-ItemStack-setType.patch diff --git a/patches/server/0928-Add-CartographyItemEvent.patch b/patches/server/0927-Add-CartographyItemEvent.patch similarity index 96% rename from patches/server/0928-Add-CartographyItemEvent.patch rename to patches/server/0927-Add-CartographyItemEvent.patch index e02b1544dbfe..b8a1377ce941 100644 --- a/patches/server/0928-Add-CartographyItemEvent.patch +++ b/patches/server/0927-Add-CartographyItemEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add CartographyItemEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 17402d393df27474b38c8d9b0b7aa424ec34d1a9..605488d9b2b20c82906b5870ffe4e0e37b6d36bf 100644 +index 836e6b705b201253f2b81d1ca0228b8a0266a1dd..d3975496dcf94d3474e891bcd3105120559b6a61 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -3133,6 +3133,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0929-More-Raid-API.patch b/patches/server/0928-More-Raid-API.patch similarity index 100% rename from patches/server/0929-More-Raid-API.patch rename to patches/server/0928-More-Raid-API.patch diff --git a/patches/server/0930-Add-onboarding-message-for-initial-server-start.patch b/patches/server/0929-Add-onboarding-message-for-initial-server-start.patch similarity index 100% rename from patches/server/0930-Add-onboarding-message-for-initial-server-start.patch rename to patches/server/0929-Add-onboarding-message-for-initial-server-start.patch diff --git a/patches/server/0931-Configurable-max-block-fluid-ticks.patch b/patches/server/0930-Configurable-max-block-fluid-ticks.patch similarity index 100% rename from patches/server/0931-Configurable-max-block-fluid-ticks.patch rename to patches/server/0930-Configurable-max-block-fluid-ticks.patch diff --git a/patches/server/0932-Fix-bees-aging-inside-hives.patch b/patches/server/0931-Fix-bees-aging-inside-hives.patch similarity index 100% rename from patches/server/0932-Fix-bees-aging-inside-hives.patch rename to patches/server/0931-Fix-bees-aging-inside-hives.patch diff --git a/patches/server/0933-Disable-memory-reserve-allocating.patch b/patches/server/0932-Disable-memory-reserve-allocating.patch similarity index 100% rename from patches/server/0933-Disable-memory-reserve-allocating.patch rename to patches/server/0932-Disable-memory-reserve-allocating.patch diff --git a/patches/server/0934-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch b/patches/server/0933-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch similarity index 100% rename from patches/server/0934-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch rename to patches/server/0933-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch diff --git a/patches/server/0935-Fix-DamageSource-API.patch b/patches/server/0934-Fix-DamageSource-API.patch similarity index 100% rename from patches/server/0935-Fix-DamageSource-API.patch rename to patches/server/0934-Fix-DamageSource-API.patch diff --git a/patches/server/0936-Fix-creation-of-invalid-block-entity-during-world-ge.patch b/patches/server/0935-Fix-creation-of-invalid-block-entity-during-world-ge.patch similarity index 100% rename from patches/server/0936-Fix-creation-of-invalid-block-entity-during-world-ge.patch rename to patches/server/0935-Fix-creation-of-invalid-block-entity-during-world-ge.patch diff --git a/patches/server/0937-Fix-possible-StackOverflowError-for-some-dispenses.patch b/patches/server/0936-Fix-possible-StackOverflowError-for-some-dispenses.patch similarity index 100% rename from patches/server/0937-Fix-possible-StackOverflowError-for-some-dispenses.patch rename to patches/server/0936-Fix-possible-StackOverflowError-for-some-dispenses.patch diff --git a/patches/server/0938-Improve-tag-parser-handling.patch b/patches/server/0937-Improve-tag-parser-handling.patch similarity index 99% rename from patches/server/0938-Improve-tag-parser-handling.patch rename to patches/server/0937-Improve-tag-parser-handling.patch index a3ceebed6803..c7b698366d20 100644 --- a/patches/server/0938-Improve-tag-parser-handling.patch +++ b/patches/server/0937-Improve-tag-parser-handling.patch @@ -252,7 +252,7 @@ index 898b19887ed34c87003fc63cb5905df2ba6234a5..b47eeb23055b135d5567552ba983bfbc private void write(FriendlyByteBuf buf) { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 605488d9b2b20c82906b5870ffe4e0e37b6d36bf..ac2a2722e154bdee0c4bbea22f3fb032c3ba39c9 100644 +index d3975496dcf94d3474e891bcd3105120559b6a61..2cef6390ce8cdc43ae7566683afc157cb3a6fd78 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -778,6 +778,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0939-Item-Mutation-Fixes.patch b/patches/server/0938-Item-Mutation-Fixes.patch similarity index 100% rename from patches/server/0939-Item-Mutation-Fixes.patch rename to patches/server/0938-Item-Mutation-Fixes.patch diff --git a/patches/server/0940-Per-world-ticks-per-spawn-settings.patch b/patches/server/0939-Per-world-ticks-per-spawn-settings.patch similarity index 100% rename from patches/server/0940-Per-world-ticks-per-spawn-settings.patch rename to patches/server/0939-Per-world-ticks-per-spawn-settings.patch diff --git a/patches/server/0941-Properly-track-the-changed-item-from-dispense-events.patch b/patches/server/0940-Properly-track-the-changed-item-from-dispense-events.patch similarity index 100% rename from patches/server/0941-Properly-track-the-changed-item-from-dispense-events.patch rename to patches/server/0940-Properly-track-the-changed-item-from-dispense-events.patch diff --git a/patches/server/0942-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch b/patches/server/0941-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch similarity index 100% rename from patches/server/0942-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch rename to patches/server/0941-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch diff --git a/patches/server/0943-Add-config-for-mobs-immune-to-default-effects.patch b/patches/server/0942-Add-config-for-mobs-immune-to-default-effects.patch similarity index 100% rename from patches/server/0943-Add-config-for-mobs-immune-to-default-effects.patch rename to patches/server/0942-Add-config-for-mobs-immune-to-default-effects.patch diff --git a/patches/server/0944-Deep-clone-nbt-tags-in-PDC.patch b/patches/server/0943-Deep-clone-nbt-tags-in-PDC.patch similarity index 100% rename from patches/server/0944-Deep-clone-nbt-tags-in-PDC.patch rename to patches/server/0943-Deep-clone-nbt-tags-in-PDC.patch diff --git a/patches/server/0945-Support-old-UUID-format-for-NBT.patch b/patches/server/0944-Support-old-UUID-format-for-NBT.patch similarity index 100% rename from patches/server/0945-Support-old-UUID-format-for-NBT.patch rename to patches/server/0944-Support-old-UUID-format-for-NBT.patch diff --git a/patches/server/0946-Fix-shield-disable-inconsistency.patch b/patches/server/0945-Fix-shield-disable-inconsistency.patch similarity index 100% rename from patches/server/0946-Fix-shield-disable-inconsistency.patch rename to patches/server/0945-Fix-shield-disable-inconsistency.patch diff --git a/patches/server/0947-Handle-Large-Packets-disconnecting-client.patch b/patches/server/0946-Handle-Large-Packets-disconnecting-client.patch similarity index 100% rename from patches/server/0947-Handle-Large-Packets-disconnecting-client.patch rename to patches/server/0946-Handle-Large-Packets-disconnecting-client.patch diff --git a/patches/server/0948-Fix-ItemFlags.patch b/patches/server/0947-Fix-ItemFlags.patch similarity index 100% rename from patches/server/0948-Fix-ItemFlags.patch rename to patches/server/0947-Fix-ItemFlags.patch diff --git a/patches/server/0949-Fix-helmet-damage-reduction-inconsistencies.patch b/patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch similarity index 100% rename from patches/server/0949-Fix-helmet-damage-reduction-inconsistencies.patch rename to patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch diff --git a/patches/server/0950-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch b/patches/server/0949-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch similarity index 100% rename from patches/server/0950-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch rename to patches/server/0949-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch diff --git a/patches/server/0951-improve-checking-handled-tags-in-itemmeta.patch b/patches/server/0950-improve-checking-handled-tags-in-itemmeta.patch similarity index 100% rename from patches/server/0951-improve-checking-handled-tags-in-itemmeta.patch rename to patches/server/0950-improve-checking-handled-tags-in-itemmeta.patch diff --git a/patches/server/0952-Expose-hasColor-to-leather-armor.patch b/patches/server/0951-Expose-hasColor-to-leather-armor.patch similarity index 100% rename from patches/server/0952-Expose-hasColor-to-leather-armor.patch rename to patches/server/0951-Expose-hasColor-to-leather-armor.patch diff --git a/patches/server/0953-Added-API-to-get-player-ha-proxy-address.patch b/patches/server/0952-Added-API-to-get-player-ha-proxy-address.patch similarity index 97% rename from patches/server/0953-Added-API-to-get-player-ha-proxy-address.patch rename to patches/server/0952-Added-API-to-get-player-ha-proxy-address.patch index c194f40ac803..5fa97c5b54c6 100644 --- a/patches/server/0953-Added-API-to-get-player-ha-proxy-address.patch +++ b/patches/server/0952-Added-API-to-get-player-ha-proxy-address.patch @@ -35,7 +35,7 @@ index c62df32af11636ad408b584fcc590590ce4fb0d0..baed0bb80d44973f9323bbe536551182 } else { super.channelRead(ctx, msg); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index a807f37a4b937fc3a1d89cb5d116224c9b3c5f49..cd8c2a9bff2d207c385b7d4ffb889c1f560a5227 100644 +index a6b26d33de210e8c5351f3246b9ac391eb688689..7d8465ec67d4b2551c8fbe01964dd0cb2c94cbe8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -270,7 +270,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0954-General-ItemMeta-fixes.patch b/patches/server/0953-General-ItemMeta-fixes.patch similarity index 99% rename from patches/server/0954-General-ItemMeta-fixes.patch rename to patches/server/0953-General-ItemMeta-fixes.patch index 70bbb2f9d4b3..9b0956d39b1c 100644 --- a/patches/server/0954-General-ItemMeta-fixes.patch +++ b/patches/server/0953-General-ItemMeta-fixes.patch @@ -12,10 +12,10 @@ public net/minecraft/world/level/block/entity/BlockEntity saveId(Lnet/minecraft/ Co-authored-by: GhastCraftHD diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index bba4fbde31ef25bc086fefaa86f9a479ef6ccf26..62529e61c8751433a8b6abe6cfb2cc414c8c3cf2 100644 +index 98b5208baeaa12a5ff2788e457c542000d6ea48b..babd89f39c43b0c64709d99bf8aca6cdc6ca1b24 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -1356,6 +1356,11 @@ public final class ItemStack implements DataComponentHolder { +@@ -1361,6 +1361,11 @@ public final class ItemStack implements DataComponentHolder { public void setItem(Item item) { this.bukkitStack = null; // Paper this.item = item; diff --git a/patches/server/0955-More-Chest-Block-API.patch b/patches/server/0954-More-Chest-Block-API.patch similarity index 100% rename from patches/server/0955-More-Chest-Block-API.patch rename to patches/server/0954-More-Chest-Block-API.patch diff --git a/patches/server/0956-Print-data-component-type-on-encoding-error.patch b/patches/server/0955-Print-data-component-type-on-encoding-error.patch similarity index 100% rename from patches/server/0956-Print-data-component-type-on-encoding-error.patch rename to patches/server/0955-Print-data-component-type-on-encoding-error.patch diff --git a/patches/server/0957-Brigadier-based-command-API.patch b/patches/server/0956-Brigadier-based-command-API.patch similarity index 99% rename from patches/server/0957-Brigadier-based-command-API.patch rename to patches/server/0956-Brigadier-based-command-API.patch index 8d3628ec6d45..6e0484371e30 100644 --- a/patches/server/0957-Brigadier-based-command-API.patch +++ b/patches/server/0956-Brigadier-based-command-API.patch @@ -2338,7 +2338,7 @@ index eb9dab7be7da11ab1c4046a7fc4a29d5bddf31d2..39c9c0dad159744da8322c3dfa3bfae4 this.setPvpAllowed(dedicatedserverproperties.pvp); this.setFlightAllowed(dedicatedserverproperties.allowFlight); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index ac2a2722e154bdee0c4bbea22f3fb032c3ba39c9..4ac4ab815edf34e8037e9f16ec2f8d29b1f2cabd 100644 +index 2cef6390ce8cdc43ae7566683afc157cb3a6fd78..af3e0049beb5590520ed84b52d6df85ad22a8f23 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -2429,33 +2429,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0958-Fix-issues-with-Recipe-API.patch b/patches/server/0957-Fix-issues-with-Recipe-API.patch similarity index 100% rename from patches/server/0958-Fix-issues-with-Recipe-API.patch rename to patches/server/0957-Fix-issues-with-Recipe-API.patch diff --git a/patches/server/0959-Fix-equipment-slot-and-group-API.patch b/patches/server/0958-Fix-equipment-slot-and-group-API.patch similarity index 100% rename from patches/server/0959-Fix-equipment-slot-and-group-API.patch rename to patches/server/0958-Fix-equipment-slot-and-group-API.patch diff --git a/patches/server/0960-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch b/patches/server/0959-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch similarity index 100% rename from patches/server/0960-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch rename to patches/server/0959-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch diff --git a/patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch b/patches/server/0960-Prevent-sending-oversized-item-data-in-equipment-and.patch similarity index 99% rename from patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch rename to patches/server/0960-Prevent-sending-oversized-item-data-in-equipment-and.patch index 2453902d3008..6f1042e76767 100644 --- a/patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch +++ b/patches/server/0960-Prevent-sending-oversized-item-data-in-equipment-and.patch @@ -209,7 +209,7 @@ index f3456aeeab7eee5b6d0383a4bf1338dd8cc95bb3..b2fd3e936559c8fcb8b02ae3ef63c4f3 ((LivingEntity) this.entity).detectEquipmentUpdatesPublic(); // CraftBukkit - SPIGOT-3789: sync again immediately after sending } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 4ac4ab815edf34e8037e9f16ec2f8d29b1f2cabd..93451a4cfc71ba00610c13011b73905e613b0b10 100644 +index af3e0049beb5590520ed84b52d6df85ad22a8f23..b7ff8607cd33d8e6bdab9533792cf43a434210bd 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -2751,7 +2751,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0962-Prevent-NPE-if-hooked-entity-was-cleared.patch b/patches/server/0961-Prevent-NPE-if-hooked-entity-was-cleared.patch similarity index 100% rename from patches/server/0962-Prevent-NPE-if-hooked-entity-was-cleared.patch rename to patches/server/0961-Prevent-NPE-if-hooked-entity-was-cleared.patch diff --git a/patches/server/0963-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch b/patches/server/0962-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch similarity index 97% rename from patches/server/0963-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch rename to patches/server/0962-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch index a7fee3a0b4b3..6043bb02b6db 100644 --- a/patches/server/0963-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch +++ b/patches/server/0962-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix cancelling BlockPlaceEvent calling onRemove diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 62529e61c8751433a8b6abe6cfb2cc414c8c3cf2..4f20e5bb143e152e19e5fb57f66d0344001ffbd9 100644 +index babd89f39c43b0c64709d99bf8aca6cdc6ca1b24..947e2a3620d73569552c5185664b7564e908007e 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java @@ -500,9 +500,11 @@ public final class ItemStack implements DataComponentHolder { diff --git a/patches/server/0964-Add-missing-fishing-event-state.patch b/patches/server/0963-Add-missing-fishing-event-state.patch similarity index 100% rename from patches/server/0964-Add-missing-fishing-event-state.patch rename to patches/server/0963-Add-missing-fishing-event-state.patch diff --git a/patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch b/patches/server/0964-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch similarity index 95% rename from patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch rename to patches/server/0964-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch index 642be4bf7887..3fc9866acfa9 100644 --- a/patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch +++ b/patches/server/0964-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Deprecate InvAction#HOTBAR_MOVE_AND_READD diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 93451a4cfc71ba00610c13011b73905e613b0b10..46f4d7a05d4febd1f8fd3cc2cae635a9e3da0e9e 100644 +index b7ff8607cd33d8e6bdab9533792cf43a434210bd..52eafd99ed63f5fc9596225cf45175b1287f20a1 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -3022,14 +3022,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0966-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch b/patches/server/0965-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch similarity index 100% rename from patches/server/0966-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch rename to patches/server/0965-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch diff --git a/patches/server/0967-Adopt-MaterialRerouting.patch b/patches/server/0966-Adopt-MaterialRerouting.patch similarity index 100% rename from patches/server/0967-Adopt-MaterialRerouting.patch rename to patches/server/0966-Adopt-MaterialRerouting.patch diff --git a/patches/server/0968-Suspicious-Effect-Entry-API.patch b/patches/server/0967-Suspicious-Effect-Entry-API.patch similarity index 100% rename from patches/server/0968-Suspicious-Effect-Entry-API.patch rename to patches/server/0967-Suspicious-Effect-Entry-API.patch diff --git a/patches/server/0969-check-if-itemstack-is-stackable-first.patch b/patches/server/0968-check-if-itemstack-is-stackable-first.patch similarity index 100% rename from patches/server/0969-check-if-itemstack-is-stackable-first.patch rename to patches/server/0968-check-if-itemstack-is-stackable-first.patch diff --git a/patches/server/0970-Fix-removing-recipes-from-RecipeIterator.patch b/patches/server/0969-Fix-removing-recipes-from-RecipeIterator.patch similarity index 100% rename from patches/server/0970-Fix-removing-recipes-from-RecipeIterator.patch rename to patches/server/0969-Fix-removing-recipes-from-RecipeIterator.patch diff --git a/patches/server/0971-Configurable-damage-tick-when-blocking-with-shield.patch b/patches/server/0970-Configurable-damage-tick-when-blocking-with-shield.patch similarity index 100% rename from patches/server/0971-Configurable-damage-tick-when-blocking-with-shield.patch rename to patches/server/0970-Configurable-damage-tick-when-blocking-with-shield.patch diff --git a/patches/server/0972-Properly-remove-the-experimental-smithing-inventory-.patch b/patches/server/0971-Properly-remove-the-experimental-smithing-inventory-.patch similarity index 100% rename from patches/server/0972-Properly-remove-the-experimental-smithing-inventory-.patch rename to patches/server/0971-Properly-remove-the-experimental-smithing-inventory-.patch diff --git a/patches/server/0973-disable-forced-empty-world-ticks.patch b/patches/server/0972-disable-forced-empty-world-ticks.patch similarity index 100% rename from patches/server/0973-disable-forced-empty-world-ticks.patch rename to patches/server/0972-disable-forced-empty-world-ticks.patch diff --git a/patches/server/0974-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch b/patches/server/0973-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch similarity index 100% rename from patches/server/0974-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch rename to patches/server/0973-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch diff --git a/patches/server/0975-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/patches/server/0974-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch similarity index 100% rename from patches/server/0975-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch rename to patches/server/0974-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch diff --git a/patches/server/0976-Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/patches/server/0975-Optimize-Network-Manager-and-add-advanced-packet-sup.patch similarity index 100% rename from patches/server/0976-Optimize-Network-Manager-and-add-advanced-packet-sup.patch rename to patches/server/0975-Optimize-Network-Manager-and-add-advanced-packet-sup.patch diff --git a/patches/server/0977-Allow-Saving-of-Oversized-Chunks.patch b/patches/server/0976-Allow-Saving-of-Oversized-Chunks.patch similarity index 100% rename from patches/server/0977-Allow-Saving-of-Oversized-Chunks.patch rename to patches/server/0976-Allow-Saving-of-Oversized-Chunks.patch diff --git a/patches/server/0978-Flat-bedrock-generator-settings.patch b/patches/server/0977-Flat-bedrock-generator-settings.patch similarity index 100% rename from patches/server/0978-Flat-bedrock-generator-settings.patch rename to patches/server/0977-Flat-bedrock-generator-settings.patch diff --git a/patches/server/0979-Entity-Activation-Range-2.0.patch b/patches/server/0978-Entity-Activation-Range-2.0.patch similarity index 100% rename from patches/server/0979-Entity-Activation-Range-2.0.patch rename to patches/server/0978-Entity-Activation-Range-2.0.patch diff --git a/patches/server/0980-Anti-Xray.patch b/patches/server/0979-Anti-Xray.patch similarity index 99% rename from patches/server/0980-Anti-Xray.patch rename to patches/server/0979-Anti-Xray.patch index 44c50f46320b..f19373b3edb0 100644 --- a/patches/server/0980-Anti-Xray.patch +++ b/patches/server/0979-Anti-Xray.patch @@ -1157,11 +1157,11 @@ index cdd66e6ce96e2613afe7f06ca8da3cfaa6704b2d..dafa2cf7d3c49fc5bdcd68d2a9528127 if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) { new io.papermc.paper.event.packet.PlayerChunkLoadEvent(new org.bukkit.craftbukkit.CraftChunk(chunk), handler.getPlayer().getBukkitEntity()).callEvent(); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index a4937d11b79cef41f3fbf79282c0c435e794dbfe..cde19fddfc9b1c8edbc565bec4f043803651313e 100644 +index 218e18b9c7836bc4c9d3eba78e0717cabb9d6b61..d12ac1b045c6721255780c5afbbad6e7103629eb 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -427,7 +427,7 @@ public abstract class PlayerList { - .getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS); + .getOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS); player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket( new net.minecraft.world.level.chunk.EmptyLevelChunk(worldserver1, player.chunkPosition(), plains), - worldserver1.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null) diff --git a/patches/server/0981-Use-Velocity-compression-and-cipher-natives.patch b/patches/server/0980-Use-Velocity-compression-and-cipher-natives.patch similarity index 100% rename from patches/server/0981-Use-Velocity-compression-and-cipher-natives.patch rename to patches/server/0980-Use-Velocity-compression-and-cipher-natives.patch diff --git a/patches/server/0982-Optimize-Collision-to-not-load-chunks.patch b/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch similarity index 98% rename from patches/server/0982-Optimize-Collision-to-not-load-chunks.patch rename to patches/server/0981-Optimize-Collision-to-not-load-chunks.patch index 0b3dc789347e..0f89ea94cae8 100644 --- a/patches/server/0982-Optimize-Collision-to-not-load-chunks.patch +++ b/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch @@ -14,7 +14,7 @@ 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 cde19fddfc9b1c8edbc565bec4f043803651313e..4b9761e58f404eedf9db835fc923a88fc1896e96 100644 +index d12ac1b045c6721255780c5afbbad6e7103629eb..59cc1702079f1d182bdbe8068aa37b5b979aa64d 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -827,6 +827,7 @@ public abstract class PlayerList { diff --git a/patches/server/0983-Optimize-GoalSelector-Goal.Flag-Set-operations.patch b/patches/server/0982-Optimize-GoalSelector-Goal.Flag-Set-operations.patch similarity index 100% rename from patches/server/0983-Optimize-GoalSelector-Goal.Flag-Set-operations.patch rename to patches/server/0982-Optimize-GoalSelector-Goal.Flag-Set-operations.patch diff --git a/patches/server/0984-Optimize-Hoppers.patch b/patches/server/0983-Optimize-Hoppers.patch similarity index 99% rename from patches/server/0984-Optimize-Hoppers.patch rename to patches/server/0983-Optimize-Hoppers.patch index 7567e0fc0959..0d9bca0049a3 100644 --- a/patches/server/0984-Optimize-Hoppers.patch +++ b/patches/server/0983-Optimize-Hoppers.patch @@ -62,10 +62,10 @@ index 510087723ce7497dbd9ecd42385acb31e36cf458..b37e49bd25ed327e03250415799c0777 gameprofilerfiller.push(() -> { String s = String.valueOf(worldserver); diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 4f20e5bb143e152e19e5fb57f66d0344001ffbd9..888454ff588927e8accc215e7429f72bb286f5aa 100644 +index 947e2a3620d73569552c5185664b7564e908007e..33e7d2884195677c4d6340d8b84c1dd85c636ec1 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -876,10 +876,16 @@ public final class ItemStack implements DataComponentHolder { +@@ -881,10 +881,16 @@ public final class ItemStack implements DataComponentHolder { } public ItemStack copy() { diff --git a/patches/server/0985-Optimize-Voxel-Shape-Merging.patch b/patches/server/0984-Optimize-Voxel-Shape-Merging.patch similarity index 100% rename from patches/server/0985-Optimize-Voxel-Shape-Merging.patch rename to patches/server/0984-Optimize-Voxel-Shape-Merging.patch diff --git a/patches/server/0986-Optimize-Bit-Operations-by-inlining.patch b/patches/server/0985-Optimize-Bit-Operations-by-inlining.patch similarity index 100% rename from patches/server/0986-Optimize-Bit-Operations-by-inlining.patch rename to patches/server/0985-Optimize-Bit-Operations-by-inlining.patch diff --git a/patches/server/0987-Remove-streams-from-hot-code.patch b/patches/server/0986-Remove-streams-from-hot-code.patch similarity index 100% rename from patches/server/0987-Remove-streams-from-hot-code.patch rename to patches/server/0986-Remove-streams-from-hot-code.patch diff --git a/patches/server/0988-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch b/patches/server/0987-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch similarity index 100% rename from patches/server/0988-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch rename to patches/server/0987-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch diff --git a/patches/server/0989-Fix-entity-type-tags-suggestions-in-selectors.patch b/patches/server/0988-Fix-entity-type-tags-suggestions-in-selectors.patch similarity index 100% rename from patches/server/0989-Fix-entity-type-tags-suggestions-in-selectors.patch rename to patches/server/0988-Fix-entity-type-tags-suggestions-in-selectors.patch diff --git a/patches/server/0990-Handle-Oversized-block-entities-in-chunks.patch b/patches/server/0989-Handle-Oversized-block-entities-in-chunks.patch similarity index 100% rename from patches/server/0990-Handle-Oversized-block-entities-in-chunks.patch rename to patches/server/0989-Handle-Oversized-block-entities-in-chunks.patch diff --git a/patches/server/0991-Check-distance-in-entity-interactions.patch b/patches/server/0990-Check-distance-in-entity-interactions.patch similarity index 100% rename from patches/server/0991-Check-distance-in-entity-interactions.patch rename to patches/server/0990-Check-distance-in-entity-interactions.patch diff --git a/patches/server/0992-Configurable-Sand-Duping.patch b/patches/server/0991-Configurable-Sand-Duping.patch similarity index 100% rename from patches/server/0992-Configurable-Sand-Duping.patch rename to patches/server/0991-Configurable-Sand-Duping.patch diff --git a/patches/server/0993-Properly-resend-entities.patch b/patches/server/0992-Properly-resend-entities.patch similarity index 98% rename from patches/server/0993-Properly-resend-entities.patch rename to patches/server/0992-Properly-resend-entities.patch index 82b6444c6598..6acf6d708b63 100644 --- a/patches/server/0993-Properly-resend-entities.patch +++ b/patches/server/0992-Properly-resend-entities.patch @@ -81,7 +81,7 @@ index f2dd272a01b4e946a6746865d55ebc9861f8361b..5d189ba60d40f5c42b2dacc339594ed0 } } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 46f4d7a05d4febd1f8fd3cc2cae635a9e3da0e9e..14a8e05420ae4ca2f1d9028e19379d162a3e6971 100644 +index 52eafd99ed63f5fc9596225cf45175b1287f20a1..e5db85f858ab376b225172e22b92b841f1f9546a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1966,6 +1966,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -102,7 +102,7 @@ index 46f4d7a05d4febd1f8fd3cc2cae635a9e3da0e9e..14a8e05420ae4ca2f1d9028e19379d16 } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 4b9761e58f404eedf9db835fc923a88fc1896e96..682b8926027945066921086b6773b31e626cc941 100644 +index 59cc1702079f1d182bdbe8068aa37b5b979aa64d..90c469193ecf9d04dd9e3f1a38157d47c5094985 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -397,7 +397,7 @@ public abstract class PlayerList { diff --git a/patches/server/0994-Registry-Modification-API.patch b/patches/server/0993-Registry-Modification-API.patch similarity index 100% rename from patches/server/0994-Registry-Modification-API.patch rename to patches/server/0993-Registry-Modification-API.patch diff --git a/patches/server/0995-Add-registry-entry-and-builders.patch b/patches/server/0994-Add-registry-entry-and-builders.patch similarity index 100% rename from patches/server/0995-Add-registry-entry-and-builders.patch rename to patches/server/0994-Add-registry-entry-and-builders.patch diff --git a/patches/server/0996-Proxy-ItemStack-to-CraftItemStack.patch b/patches/server/0995-Proxy-ItemStack-to-CraftItemStack.patch similarity index 100% rename from patches/server/0996-Proxy-ItemStack-to-CraftItemStack.patch rename to patches/server/0995-Proxy-ItemStack-to-CraftItemStack.patch diff --git a/patches/server/0997-Make-a-PDC-view-accessible-directly-from-ItemStack.patch b/patches/server/0996-Make-a-PDC-view-accessible-directly-from-ItemStack.patch similarity index 100% rename from patches/server/0997-Make-a-PDC-view-accessible-directly-from-ItemStack.patch rename to patches/server/0996-Make-a-PDC-view-accessible-directly-from-ItemStack.patch diff --git a/patches/server/0998-Prioritize-Minecraft-commands-in-function-parsing-an.patch b/patches/server/0997-Prioritize-Minecraft-commands-in-function-parsing-an.patch similarity index 100% rename from patches/server/0998-Prioritize-Minecraft-commands-in-function-parsing-an.patch rename to patches/server/0997-Prioritize-Minecraft-commands-in-function-parsing-an.patch diff --git a/patches/server/0999-optimize-dirt-and-snow-spreading.patch b/patches/server/0998-optimize-dirt-and-snow-spreading.patch similarity index 100% rename from patches/server/0999-optimize-dirt-and-snow-spreading.patch rename to patches/server/0998-optimize-dirt-and-snow-spreading.patch diff --git a/patches/server/1000-Fix-NPE-for-Jukebox-setRecord.patch b/patches/server/0999-Fix-NPE-for-Jukebox-setRecord.patch similarity index 100% rename from patches/server/1000-Fix-NPE-for-Jukebox-setRecord.patch rename to patches/server/0999-Fix-NPE-for-Jukebox-setRecord.patch diff --git a/patches/server/1001-fix-horse-inventories.patch b/patches/server/1000-fix-horse-inventories.patch similarity index 100% rename from patches/server/1001-fix-horse-inventories.patch rename to patches/server/1000-fix-horse-inventories.patch diff --git a/patches/server/1002-Only-call-EntityDamageEvents-before-actuallyHurt.patch b/patches/server/1001-Only-call-EntityDamageEvents-before-actuallyHurt.patch similarity index 100% rename from patches/server/1002-Only-call-EntityDamageEvents-before-actuallyHurt.patch rename to patches/server/1001-Only-call-EntityDamageEvents-before-actuallyHurt.patch diff --git a/patches/server/1003-Add-ItemType-getItemRarity.patch b/patches/server/1002-Add-ItemType-getItemRarity.patch similarity index 100% rename from patches/server/1003-Add-ItemType-getItemRarity.patch rename to patches/server/1002-Add-ItemType-getItemRarity.patch diff --git a/patches/server/1004-Add-plugin-info-at-startup.patch b/patches/server/1003-Add-plugin-info-at-startup.patch similarity index 100% rename from patches/server/1004-Add-plugin-info-at-startup.patch rename to patches/server/1003-Add-plugin-info-at-startup.patch diff --git a/patches/server/1005-Make-interaction-leniency-distance-configurable.patch b/patches/server/1004-Make-interaction-leniency-distance-configurable.patch similarity index 94% rename from patches/server/1005-Make-interaction-leniency-distance-configurable.patch rename to patches/server/1004-Make-interaction-leniency-distance-configurable.patch index 98eb372c1ecc..ae6223c7834a 100644 --- a/patches/server/1005-Make-interaction-leniency-distance-configurable.patch +++ b/patches/server/1004-Make-interaction-leniency-distance-configurable.patch @@ -12,7 +12,7 @@ This value however may be too low in high latency environments. The patch exposes a new configuration option to configure said value. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 14a8e05420ae4ca2f1d9028e19379d162a3e6971..c9fd2b8cc5a14d4ef4072765d5274d0c470bcfe6 100644 +index e5db85f858ab376b225172e22b92b841f1f9546a..293f83f5513d3ab6492f93834229903570009fdb 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -2722,7 +2722,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/1006-Fix-PickupStatus-getting-reset.patch b/patches/server/1005-Fix-PickupStatus-getting-reset.patch similarity index 100% rename from patches/server/1006-Fix-PickupStatus-getting-reset.patch rename to patches/server/1005-Fix-PickupStatus-getting-reset.patch diff --git a/patches/server/1007-Check-for-block-type-in-SculkSensorBlock-canActivate.patch b/patches/server/1006-Check-for-block-type-in-SculkSensorBlock-canActivate.patch similarity index 100% rename from patches/server/1007-Check-for-block-type-in-SculkSensorBlock-canActivate.patch rename to patches/server/1006-Check-for-block-type-in-SculkSensorBlock-canActivate.patch diff --git a/patches/server/1008-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch b/patches/server/1007-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch similarity index 87% rename from patches/server/1008-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch rename to patches/server/1007-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch index 61b8983112e0..e1242464ddbb 100644 --- a/patches/server/1008-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch +++ b/patches/server/1007-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add API for CanPlaceOn and CanDestroy NBT values diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index 450c5aa14b4195eb7123492c7a111ec6f40ce412..7d9f75e680e243ac8c7defdd150e431b47225945 100644 +index 450c5aa14b4195eb7123492c7a111ec6f40ce412..3b3c15c8bd8591aa173343251d7a504c6004e9d2 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -@@ -2498,4 +2498,117 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2498,4 +2498,119 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { } // Paper end @@ -36,8 +36,9 @@ index 450c5aa14b4195eb7123492c7a111ec6f40ce412..7d9f75e680e243ac8c7defdd150e431b + } + + private static List convertFromLegacyMaterial(final Collection materials) { ++ final net.minecraft.core.Registry blockRegistry = net.minecraft.server.MinecraftServer.getServer().registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BLOCK); + return materials.stream().map(m -> { -+ return net.minecraft.advancements.critereon.BlockPredicate.Builder.block().of(CraftBlockType.bukkitToMinecraft(m)).build(); ++ return net.minecraft.advancements.critereon.BlockPredicate.Builder.block().of(blockRegistry, CraftBlockType.bukkitToMinecraft(m)).build(); + }).toList(); + } + @@ -74,11 +75,12 @@ index 450c5aa14b4195eb7123492c7a111ec6f40ce412..7d9f75e680e243ac8c7defdd150e431b + + private static List convertFromLegacyNamespaced(final Collection namespaceds) { + final List predicates = new ArrayList<>(); ++ final net.minecraft.core.Registry blockRegistry = net.minecraft.server.MinecraftServer.getServer().registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BLOCK); + for (final com.destroystokyo.paper.Namespaced namespaced : namespaceds) { + if (namespaced instanceof final org.bukkit.NamespacedKey key) { -+ predicates.add(net.minecraft.advancements.critereon.BlockPredicate.Builder.block().of(CraftBlockType.bukkitToMinecraft(Objects.requireNonNull(org.bukkit.Registry.MATERIAL.get(key)))).build()); ++ predicates.add(net.minecraft.advancements.critereon.BlockPredicate.Builder.block().of(blockRegistry, CraftBlockType.bukkitToMinecraft(Objects.requireNonNull(org.bukkit.Registry.MATERIAL.get(key)))).build()); + } else if (namespaced instanceof final com.destroystokyo.paper.NamespacedTag tag) { -+ predicates.add(net.minecraft.advancements.critereon.BlockPredicate.Builder.block().of(net.minecraft.tags.TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath(tag.getNamespace(), tag.getKey()))).build()); ++ predicates.add(net.minecraft.advancements.critereon.BlockPredicate.Builder.block().of(blockRegistry, net.minecraft.tags.TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath(tag.getNamespace(), tag.getKey()))).build()); + } + } + return predicates; diff --git a/patches/server/1009-Configuration-for-horizontal-only-item-merging.patch b/patches/server/1008-Configuration-for-horizontal-only-item-merging.patch similarity index 100% rename from patches/server/1009-Configuration-for-horizontal-only-item-merging.patch rename to patches/server/1008-Configuration-for-horizontal-only-item-merging.patch diff --git a/patches/server/1010-Add-skipping-world-symlink-scan.patch b/patches/server/1009-Add-skipping-world-symlink-scan.patch similarity index 100% rename from patches/server/1010-Add-skipping-world-symlink-scan.patch rename to patches/server/1009-Add-skipping-world-symlink-scan.patch diff --git a/patches/server/1011-Add-even-more-Enchantment-API.patch b/patches/server/1010-Add-even-more-Enchantment-API.patch similarity index 100% rename from patches/server/1011-Add-even-more-Enchantment-API.patch rename to patches/server/1010-Add-even-more-Enchantment-API.patch diff --git a/patches/server/1012-Leashable-API.patch b/patches/server/1011-Leashable-API.patch similarity index 100% rename from patches/server/1012-Leashable-API.patch rename to patches/server/1011-Leashable-API.patch diff --git a/patches/server/1013-Fix-CraftBukkit-drag-system.patch b/patches/server/1012-Fix-CraftBukkit-drag-system.patch similarity index 97% rename from patches/server/1013-Fix-CraftBukkit-drag-system.patch rename to patches/server/1012-Fix-CraftBukkit-drag-system.patch index 09f889a5eb3d..afd7345911e6 100644 --- a/patches/server/1013-Fix-CraftBukkit-drag-system.patch +++ b/patches/server/1012-Fix-CraftBukkit-drag-system.patch @@ -10,7 +10,7 @@ public net.minecraft.world.inventory.AbstractContainerMenu quickcraftType public net.minecraft.world.inventory.AbstractContainerMenu resetQuickCraft()V diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index c9fd2b8cc5a14d4ef4072765d5274d0c470bcfe6..1ab3f730301e8ac22702601a04ad8f1521585daa 100644 +index 293f83f5513d3ab6492f93834229903570009fdb..654531ada32d3adacca71546480abeebfdad40d3 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -3080,6 +3080,25 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/1014-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch b/patches/server/1013-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch similarity index 100% rename from patches/server/1014-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch rename to patches/server/1013-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch diff --git a/patches/server/1015-Remove-set-damage-lootable-item-function-from-compas.patch b/patches/server/1014-Remove-set-damage-lootable-item-function-from-compas.patch similarity index 100% rename from patches/server/1015-Remove-set-damage-lootable-item-function-from-compas.patch rename to patches/server/1014-Remove-set-damage-lootable-item-function-from-compas.patch diff --git a/patches/server/1016-Add-enchantment-seed-update-API.patch b/patches/server/1015-Add-enchantment-seed-update-API.patch similarity index 100% rename from patches/server/1016-Add-enchantment-seed-update-API.patch rename to patches/server/1015-Add-enchantment-seed-update-API.patch diff --git a/patches/server/1017-Fix-synchronise-sending-chat-to-client-with-updating.patch b/patches/server/1016-Fix-synchronise-sending-chat-to-client-with-updating.patch similarity index 95% rename from patches/server/1017-Fix-synchronise-sending-chat-to-client-with-updating.patch rename to patches/server/1016-Fix-synchronise-sending-chat-to-client-with-updating.patch index e7bfb5065813..63f9be4942f5 100644 --- a/patches/server/1017-Fix-synchronise-sending-chat-to-client-with-updating.patch +++ b/patches/server/1016-Fix-synchronise-sending-chat-to-client-with-updating.patch @@ -9,7 +9,7 @@ In the case where multiple messages from different players are being processed i This also applies to the last seen state of the server, which becomes inconsistent in the same way as the message signature cache and would cause any messages sent to be rejected by the server too. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 1ab3f730301e8ac22702601a04ad8f1521585daa..1722f11ad070715077f5dcaff008b98f7ee104ab 100644 +index 654531ada32d3adacca71546480abeebfdad40d3..b57f9e048581f67ab031731553e82829d7eb7c1d 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -2663,8 +2663,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/1018-Fix-InventoryOpenEvent-cancellation.patch b/patches/server/1017-Fix-InventoryOpenEvent-cancellation.patch similarity index 100% rename from patches/server/1018-Fix-InventoryOpenEvent-cancellation.patch rename to patches/server/1017-Fix-InventoryOpenEvent-cancellation.patch diff --git a/patches/server/1019-Fire-BlockExpEvent-on-grindstone-use.patch b/patches/server/1018-Fire-BlockExpEvent-on-grindstone-use.patch similarity index 100% rename from patches/server/1019-Fire-BlockExpEvent-on-grindstone-use.patch rename to patches/server/1018-Fire-BlockExpEvent-on-grindstone-use.patch diff --git a/patches/server/1020-Check-dead-flag-in-isAlive.patch b/patches/server/1019-Check-dead-flag-in-isAlive.patch similarity index 100% rename from patches/server/1020-Check-dead-flag-in-isAlive.patch rename to patches/server/1019-Check-dead-flag-in-isAlive.patch diff --git a/patches/server/1021-Add-FeatureFlag-API.patch b/patches/server/1020-Add-FeatureFlag-API.patch similarity index 100% rename from patches/server/1021-Add-FeatureFlag-API.patch rename to patches/server/1020-Add-FeatureFlag-API.patch diff --git a/patches/server/1022-Tag-Lifecycle-Events.patch b/patches/server/1021-Tag-Lifecycle-Events.patch similarity index 100% rename from patches/server/1022-Tag-Lifecycle-Events.patch rename to patches/server/1021-Tag-Lifecycle-Events.patch diff --git a/patches/server/1023-Item-serialization-as-json.patch b/patches/server/1022-Item-serialization-as-json.patch similarity index 100% rename from patches/server/1023-Item-serialization-as-json.patch rename to patches/server/1022-Item-serialization-as-json.patch diff --git a/patches/server/1024-Validate-slot-in-PlayerInventory-setSlot.patch b/patches/server/1023-Validate-slot-in-PlayerInventory-setSlot.patch similarity index 100% rename from patches/server/1024-Validate-slot-in-PlayerInventory-setSlot.patch rename to patches/server/1023-Validate-slot-in-PlayerInventory-setSlot.patch diff --git a/patches/server/1025-Remove-wall-time-unused-skip-tick-protection.patch b/patches/server/1024-Remove-wall-time-unused-skip-tick-protection.patch similarity index 100% rename from patches/server/1025-Remove-wall-time-unused-skip-tick-protection.patch rename to patches/server/1024-Remove-wall-time-unused-skip-tick-protection.patch diff --git a/patches/server/1026-Disable-pretty-printing-for-advancement-saving.patch b/patches/server/1025-Disable-pretty-printing-for-advancement-saving.patch similarity index 100% rename from patches/server/1026-Disable-pretty-printing-for-advancement-saving.patch rename to patches/server/1025-Disable-pretty-printing-for-advancement-saving.patch diff --git a/patches/server/1027-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch b/patches/server/1026-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch similarity index 96% rename from patches/server/1027-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch rename to patches/server/1026-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch index baad9efd2424..88334f270985 100644 --- a/patches/server/1027-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch +++ b/patches/server/1026-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix PlayerCommandPreprocessEvent on signed commands diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 1722f11ad070715077f5dcaff008b98f7ee104ab..cae9682df8795c5f73e86c27d717b6f72e7e8592 100644 +index b57f9e048581f67ab031731553e82829d7eb7c1d..bcf6c5ec1cb4be806d49f30f3404498018760f91 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -2195,24 +2195,32 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/1028-Add-enchantWithLevels-with-enchantment-registry-set.patch b/patches/server/1027-Add-enchantWithLevels-with-enchantment-registry-set.patch similarity index 93% rename from patches/server/1028-Add-enchantWithLevels-with-enchantment-registry-set.patch rename to patches/server/1027-Add-enchantWithLevels-with-enchantment-registry-set.patch index 115ef56bd399..61f5aced36db 100644 --- a/patches/server/1028-Add-enchantWithLevels-with-enchantment-registry-set.patch +++ b/patches/server/1027-Add-enchantWithLevels-with-enchantment-registry-set.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add enchantWithLevels with enchantment registry set diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java -index 944dcc1126c947b4c8c3b4fdd174eb57320abbba..260fb93e71812698beb475bab7a05b9b860c6cbd 100644 +index d9eec6cff3c7c6515f4d61bf1063e7d609d4bcb3..2f11d324ee5e8df66b65c1426e7d1a6d82990ea7 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java @@ -322,6 +322,22 @@ public final class CraftItemFactory implements ItemFactory { diff --git a/patches/server/1029-Improve-entity-effect-API.patch b/patches/server/1028-Improve-entity-effect-API.patch similarity index 98% rename from patches/server/1029-Improve-entity-effect-API.patch rename to patches/server/1028-Improve-entity-effect-API.patch index 3accb2cf6d8b..2b11b7ac1cd6 100644 --- a/patches/server/1029-Improve-entity-effect-API.patch +++ b/patches/server/1028-Improve-entity-effect-API.patch @@ -25,7 +25,7 @@ index ca95a36b0149d4b8a67c3b42316c5d9d0415f5dd..64c6f54cc4d0c22bc972b808cb92925c + // Paper end - broadcast hurt animation } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index cd8c2a9bff2d207c385b7d4ffb889c1f560a5227..d6c3c497a43694988c5e05c0ef04efa5a3c1630c 100644 +index 7d8465ec67d4b2551c8fbe01964dd0cb2c94cbe8..40a9f02091e9ae06fae28508c967fe1298419eda 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1294,6 +1294,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/1030-Add-recipeBrewTime.patch b/patches/server/1029-Add-recipeBrewTime.patch similarity index 100% rename from patches/server/1030-Add-recipeBrewTime.patch rename to patches/server/1029-Add-recipeBrewTime.patch diff --git a/patches/server/1031-Call-bucket-events-for-cauldrons.patch b/patches/server/1030-Call-bucket-events-for-cauldrons.patch similarity index 100% rename from patches/server/1031-Call-bucket-events-for-cauldrons.patch rename to patches/server/1030-Call-bucket-events-for-cauldrons.patch diff --git a/patches/server/1032-Add-PlayerInsertLecternBookEvent.patch b/patches/server/1031-Add-PlayerInsertLecternBookEvent.patch similarity index 100% rename from patches/server/1032-Add-PlayerInsertLecternBookEvent.patch rename to patches/server/1031-Add-PlayerInsertLecternBookEvent.patch diff --git a/patches/server/1033-Void-damage-configuration-API.patch b/patches/server/1032-Void-damage-configuration-API.patch similarity index 100% rename from patches/server/1033-Void-damage-configuration-API.patch rename to patches/server/1032-Void-damage-configuration-API.patch diff --git a/patches/server/1034-Add-Offline-PDC-API.patch b/patches/server/1033-Add-Offline-PDC-API.patch similarity index 100% rename from patches/server/1034-Add-Offline-PDC-API.patch rename to patches/server/1033-Add-Offline-PDC-API.patch diff --git a/patches/server/1035-Add-AnvilView-bypassEnchantmentLevelRestriction.patch b/patches/server/1034-Add-AnvilView-bypassEnchantmentLevelRestriction.patch similarity index 100% rename from patches/server/1035-Add-AnvilView-bypassEnchantmentLevelRestriction.patch rename to patches/server/1034-Add-AnvilView-bypassEnchantmentLevelRestriction.patch diff --git a/patches/server/1036-Add-proper-async-player-disconnections.patch b/patches/server/1035-Add-proper-async-player-disconnections.patch similarity index 97% rename from patches/server/1036-Add-proper-async-player-disconnections.patch rename to patches/server/1035-Add-proper-async-player-disconnections.patch index 9522b5a4cbcd..6369e9271b15 100644 --- a/patches/server/1036-Add-proper-async-player-disconnections.patch +++ b/patches/server/1035-Add-proper-async-player-disconnections.patch @@ -74,7 +74,7 @@ index fc242acade3ff06c9213428cde103cf078216382..b0bc66dc7248aae691dcab68b925b52a return this.server.isSingleplayerOwner(this.playerProfile()); } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index cae9682df8795c5f73e86c27d717b6f72e7e8592..bffbf87a546cf8b5ffc0a58d853bacd5d7759abf 100644 +index bcf6c5ec1cb4be806d49f30f3404498018760f91..eef96e946b80064fe211039a65db4192ea7a52d3 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -769,7 +769,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -132,7 +132,7 @@ index cae9682df8795c5f73e86c27d717b6f72e7e8592..bffbf87a546cf8b5ffc0a58d853bacd5 return optional; @@ -2498,7 +2498,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // this.chatSpamThrottler.increment(); - if (counted && !this.chatSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - exclude from SpigotConfig.spamExclusions + if (!this.chatSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // CraftBukkit end - this.disconnect((Component) Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause + this.disconnectAsync((Component) Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause // Paper - add proper async disconnect diff --git a/patches/server/1037-Always-send-Banner-patterns-to-the-client.patch b/patches/server/1036-Always-send-Banner-patterns-to-the-client.patch similarity index 100% rename from patches/server/1037-Always-send-Banner-patterns-to-the-client.patch rename to patches/server/1036-Always-send-Banner-patterns-to-the-client.patch From 918ca965d919fc3ed4d11e09317b1dd91be774ff Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Fri, 25 Oct 2024 14:55:49 +0200 Subject: [PATCH 054/119] Compiler issues v3 --- patches/server/0002-Remap-fixes.patch | 13 ------- patches/server/0006-MC-Dev-fixes.patch | 39 +++++++++++++++++++ patches/server/0009-MC-Utils.patch | 18 ++++----- patches/server/0023-Timings-v2.patch | 2 +- ...able-API-and-replenishable-lootables.patch | 10 ++--- .../0101-Fix-global-sound-handling.patch | 11 +++--- ...-profile-lookups-to-worldgen-threads.patch | 2 +- ...4-PlayerNaturallySpawnCreaturesEvent.patch | 2 +- .../0212-PlayerLaunchProjectileEvent.patch | 4 +- ...er-Thread-Pool-and-Thread-Priorities.patch | 2 +- .../0306-Tracking-Range-Improvements.patch | 2 +- ...-PlayerChunkMap-adds-crashing-server.patch | 2 +- ...nEvent-when-Player-is-actually-ready.patch | 2 +- .../0432-Add-PlayerItemCooldownEvent.patch | 6 +-- .../0437-Add-PlayerShearBlockEvent.patch | 8 ++-- ...1-Add-PlayerFlowerPotManipulateEvent.patch | 4 +- ...gistryAccess-for-managing-Registries.patch | 2 +- .../0468-Add-StructuresLocateEvent.patch | 6 +-- .../0528-ItemStack-repair-check-API.patch | 4 +- ...5-Improve-item-default-attribute-API.patch | 2 +- .../0580-Get-entity-default-attributes.patch | 8 ++-- ...89-Add-Raw-Byte-Entity-Serialization.patch | 4 +- ...primise-map-impl-for-tracked-players.patch | 2 +- .../0620-Configurable-feature-seeds.patch | 2 +- ...de-code-using-deprecated-for-removal.patch | 2 +- ...d-missing-structure-set-seed-configs.patch | 2 +- ..._destroyed-trigger-in-the-correct-pl.patch | 2 +- ...us-missing-EntityDropItemEvent-calls.patch | 2 +- ...0727-Add-NamespacedKey-biome-methods.patch | 6 +-- ...ntityChangeBlockEvent-in-more-places.patch | 27 +++++++------ .../0737-fix-Jigsaw-block-kicking-user.patch | 4 +- .../0740-Fix-a-bunch-of-vanilla-bugs.patch | 2 +- .../0768-Player-Entity-Tracking-Events.patch | 2 +- ...ItemEvent-and-EntityCompostItemEvent.patch | 2 +- ...x-custom-statistic-criteria-creation.patch | 2 +- ...y-handle-BlockBreakEvent-isDropItems.patch | 2 +- ...ntity-tracking-range-by-Y-coordinate.patch | 2 +- ...e-nearest-structure-border-iteration.patch | 2 +- .../0874-Fix-spigot-s-Forced-Stats.patch | 4 +- ...883-Fix-UnsafeValues-loadAdvancement.patch | 2 +- ...k-if-we-can-see-non-visible-entities.patch | 2 +- ...llocation-of-Vec3D-by-entity-tracker.patch | 2 +- ...Add-api-for-spawn-egg-texture-colors.patch | 2 +- .../0918-Add-Lifecycle-Event-system.patch | 2 +- .../server/0919-ItemStack-Tooltip-API.patch | 2 +- patches/server/0979-Anti-Xray.patch | 12 +++--- ...y-type-tags-suggestions-in-selectors.patch | 4 +- ...heck-distance-in-entity-interactions.patch | 2 +- .../0993-Registry-Modification-API.patch | 20 +++++----- ...95-Proxy-ItemStack-to-CraftItemStack.patch | 2 +- patches/server/1020-Add-FeatureFlag-API.patch | 2 +- .../server/1021-Tag-Lifecycle-Events.patch | 2 +- .../1022-Item-serialization-as-json.patch | 2 +- 53 files changed, 154 insertions(+), 124 deletions(-) diff --git a/patches/server/0002-Remap-fixes.patch b/patches/server/0002-Remap-fixes.patch index 2bb4aff8a2d2..d7cff4215bd5 100644 --- a/patches/server/0002-Remap-fixes.patch +++ b/patches/server/0002-Remap-fixes.patch @@ -58,19 +58,6 @@ index 7344cff32fa6fe3dedb74ed98126072c55b0abd2..d98b28e9488a5a7736719cf656736bb0 entityliving1 = entityliving2; } else { entityliving1 = null; -diff --git a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java -index 33170f2f1d3f030fbf342e44a1baa109a34c31a7..db8bb6e47b28bac6cf568415af3ffdd6eeac6ac7 100644 ---- a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java -+++ b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java -@@ -349,7 +349,7 @@ public class Dolphin extends AgeableWaterCreature { - - @Nullable - @Override -- protected SoundEvent getDeathSound() { -+ public SoundEvent getDeathSound() { // Paper - remap fixes - return SoundEvents.DOLPHIN_DEATH; - } - diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java b/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java index f3a2612f0e27c36d5206334307eac1880ce8c4b7..4d4d413b8527e1a109276928611b8c857ad6f6aa 100644 --- a/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java diff --git a/patches/server/0006-MC-Dev-fixes.patch b/patches/server/0006-MC-Dev-fixes.patch index 2f90f68dd262..6c9bb2f227c5 100644 --- a/patches/server/0006-MC-Dev-fixes.patch +++ b/patches/server/0006-MC-Dev-fixes.patch @@ -4,6 +4,19 @@ Date: Wed, 30 Mar 2016 19:36:20 -0400 Subject: [PATCH] MC Dev fixes +diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java +index 5b9ca3d968fd4884b1b7f2c06477ae00c09f202e..0842080f1840a83b34c2cc829dfddba78ba12157 100644 +--- a/src/main/java/net/minecraft/Util.java ++++ b/src/main/java/net/minecraft/Util.java +@@ -533,7 +533,7 @@ public class Util { + public static , V> EnumMap makeEnumMap(Class enumClass, Function mapper) { + EnumMap enumMap = new EnumMap<>(enumClass); + +- for (K enum_ : (Enum[])enumClass.getEnumConstants()) { ++ for (K enum_ : enumClass.getEnumConstants()) { // Paper - decompile error + enumMap.put(enum_, mapper.apply(enum_)); + } + diff --git a/src/main/java/net/minecraft/commands/arguments/item/ItemInput.java b/src/main/java/net/minecraft/commands/arguments/item/ItemInput.java index 643bb8860962ad691b11073f6dbf406bf7ec5fb1..9b8ec1fd158f6e51779be263fd56b9119d0d9bbb 100644 --- a/src/main/java/net/minecraft/commands/arguments/item/ItemInput.java @@ -70,6 +83,19 @@ index a614e960fcd5958ad17b679eee8a8e6926f58e62..da101bca71f4710812621b98f0a0d8ca } if (!this.hasElementSeparator()) { +diff --git a/src/main/java/net/minecraft/resources/RegistryDataLoader.java b/src/main/java/net/minecraft/resources/RegistryDataLoader.java +index f4f1a99d53ffb953beb2a944f54d28fa6349fa29..a75f6fefdd72188fa8d16df2b5cbb34c4129f52d 100644 +--- a/src/main/java/net/minecraft/resources/RegistryDataLoader.java ++++ b/src/main/java/net/minecraft/resources/RegistryDataLoader.java +@@ -74,7 +74,7 @@ import org.slf4j.Logger; + + public class RegistryDataLoader { + private static final Logger LOGGER = LogUtils.getLogger(); +- private static final Comparator> ERROR_KEY_COMPARATOR = Comparator.comparing(ResourceKey::registry).thenComparing(ResourceKey::location); ++ private static final Comparator> ERROR_KEY_COMPARATOR = Comparator., ResourceLocation>comparing(ResourceKey::registry).thenComparing(ResourceKey::location); // Paper - decompile fix + private static final RegistrationInfo NETWORK_REGISTRATION_INFO = new RegistrationInfo(Optional.empty(), Lifecycle.experimental()); + private static final Function, RegistrationInfo> REGISTRATION_INFO_CACHE = Util.memoize(knownPacks -> { + Lifecycle lifecycle = knownPacks.map(KnownPack::isVanilla).map(vanilla -> Lifecycle.stable()).orElse(Lifecycle.experimental()); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 3fc0abef2c4e2c8ceb3b8c4f02c59700aa3d0803..8e16bc7da15824723f1d7d4bff87fac181978500 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java @@ -96,6 +122,19 @@ index 661a6274a800ca9b91bdb809d026972d23c3b263..ea72dcb064a35bc6245bc5c94d592efe } public static SortedArraySet create(Comparator comparator) { +diff --git a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java +index 33170f2f1d3f030fbf342e44a1baa109a34c31a7..dde1ccca98f58200910334160f0f79eb00dd2388 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java ++++ b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java +@@ -349,7 +349,7 @@ public class Dolphin extends AgeableWaterCreature { + + @Nullable + @Override +- protected SoundEvent getDeathSound() { ++ public SoundEvent getDeathSound() { // Paper - decompile error + return SoundEvents.DOLPHIN_DEATH; + } + diff --git a/src/main/java/net/minecraft/world/entity/monster/Pillager.java b/src/main/java/net/minecraft/world/entity/monster/Pillager.java index cf025d7a4392213db3cf04e7ace3e2b166e710eb..3e8631c7bd1e7591051ca21c6ae7acd87d3c7529 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Pillager.java diff --git a/patches/server/0009-MC-Utils.patch b/patches/server/0009-MC-Utils.patch index d98cff699198..1adc5ed577f6 100644 --- a/patches/server/0009-MC-Utils.patch +++ b/patches/server/0009-MC-Utils.patch @@ -3868,7 +3868,7 @@ index 0000000000000000000000000000000000000000..11b7f15755dde766140c29bedca456c8 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java new file mode 100644 -index 0000000000000000000000000000000000000000..af9623240ff2d389aa7090623f507720e7dbab7d +index 0000000000000000000000000000000000000000..561a1a3ff418393d0a0db58de91b336f4c33aa4e --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java @@ -0,0 +1,54 @@ @@ -3882,11 +3882,11 @@ index 0000000000000000000000000000000000000000..af9623240ff2d389aa7090623f507720 + // min, max are inclusive + + public static int getMaxSection(final LevelHeightAccessor world) { -+ return world.getMaxSection() - 1; // getMaxSection() is exclusive ++ return world.getMaxSectionY() - 1; // getMaxSection() is exclusive + } + + public static int getMinSection(final LevelHeightAccessor world) { -+ return world.getMinSection(); ++ return world.getMinSectionY(); + } + + public static int getMaxLightSection(final LevelHeightAccessor world) { @@ -4288,7 +4288,7 @@ index 0000000000000000000000000000000000000000..f7114d5b8f2f93f62883e24da29afaf9 + } +} diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java -index 5b9ca3d968fd4884b1b7f2c06477ae00c09f202e..5d0ef11671beb2381e0e1959f5e5f845789a2982 100644 +index 0842080f1840a83b34c2cc829dfddba78ba12157..2ff5a6517d717bbd4c944572040bd30866347341 100644 --- a/src/main/java/net/minecraft/Util.java +++ b/src/main/java/net/minecraft/Util.java @@ -136,7 +136,7 @@ public class Util { @@ -4538,7 +4538,7 @@ index 59bc334ade71c106e01e54db8d21fb65563dd3f1..b9ab241b930edc63a39dbbcf14cd0b5e } diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 952936754cbe5a6fae543d19432599e30eb495b0..88e98f49565a098debcea8d58368e53d7623f6b5 100644 +index 952936754cbe5a6fae543d19432599e30eb495b0..3bb6eaabe8f62b556a52b83227b48f8324a9d0f0 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -174,6 +174,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -4616,29 +4616,27 @@ index 952936754cbe5a6fae543d19432599e30eb495b0..88e98f49565a098debcea8d58368e53d } private void processUnloads(BooleanSupplier shouldKeepTicking) { -@@ -568,9 +583,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -568,8 +583,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.scheduleUnload(pos, chunk); } else { ChunkAccess ichunkaccess = chunk.getLatestChunk(); - - if (this.pendingUnloads.remove(pos, chunk) && ichunkaccess != null) { -- LevelChunk chunk1; + // Paper start + boolean removed; + if ((removed = this.pendingUnloads.remove(pos, chunk)) && ichunkaccess != null) { + ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, chunk); + // Paper end -+ LevelChunk chunk; + LevelChunk chunk1; if (ichunkaccess instanceof LevelChunk) { - chunk1 = (LevelChunk) ichunkaccess; @@ -587,7 +605,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.lightEngine.tryScheduleUpdate(); this.progressListener.onStatusChange(ichunkaccess.getPos(), (ChunkStatus) null); this.nextChunkSaveTime.remove(ichunkaccess.getPos().toLong()); - } + } else if (removed) { // Paper start -+ ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, holder); ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, chunk); + } // Paper end } diff --git a/patches/server/0023-Timings-v2.patch b/patches/server/0023-Timings-v2.patch index a8f502b7e6d3..0fd756a82d83 100644 --- a/patches/server/0023-Timings-v2.patch +++ b/patches/server/0023-Timings-v2.patch @@ -991,7 +991,7 @@ index 9d6be455c3bbcdbcb9d3d24b0bad79f46ba6a8cb..de6cceeec4fc4a64d325b506ae9d9b0e // CraftBukkit end } diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 88e98f49565a098debcea8d58368e53d7623f6b5..84ea1974445fc7be80ed474d8a2133b58ee4c8fe 100644 +index 3bb6eaabe8f62b556a52b83227b48f8324a9d0f0..30b28d9523820ed138c837ab9ee9bbb23c0dd285 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 @@ diff --git a/patches/server/0095-LootTable-API-and-replenishable-lootables.patch b/patches/server/0095-LootTable-API-and-replenishable-lootables.patch index edb6659a6940..373db66b1f4a 100644 --- a/patches/server/0095-LootTable-API-and-replenishable-lootables.patch +++ b/patches/server/0095-LootTable-API-and-replenishable-lootables.patch @@ -109,7 +109,7 @@ index 0000000000000000000000000000000000000000..0699c60920333ea1fec04e3c94d95224 +} diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperLootableEntity.java b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableEntity.java new file mode 100644 -index 0000000000000000000000000000000000000000..de528b8bafd75b6f14b1384157f3a8a27e06b4a2 +index 0000000000000000000000000000000000000000..d933054535c83f877888cd36cd8bd8bf9d93a9df --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableEntity.java @@ -0,0 +1,29 @@ @@ -128,18 +128,18 @@ index 0000000000000000000000000000000000000000..de528b8bafd75b6f14b1384157f3a8a2 + /* Lootable */ + @Override + default @Nullable LootTable getLootTable() { -+ return CraftLootTable.minecraftToBukkit(this.getHandle().getLootTable()); ++ return CraftLootTable.minecraftToBukkit(this.getHandle().getContainerLootTable()); + } + + @Override + default void setLootTable(final @Nullable LootTable table, final long seed) { -+ this.getHandle().setLootTable(CraftLootTable.bukkitToMinecraft(table)); -+ this.getHandle().setLootTableSeed(seed); ++ this.getHandle().setContainerLootTable(CraftLootTable.bukkitToMinecraft(table)); ++ this.getHandle().setContainerLootTableSeed(seed); + } + + @Override + default long getSeed() { -+ return this.getHandle().getLootTableSeed(); ++ return this.getHandle().getContainerLootTableSeed(); + } +} diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperLootableEntityInventory.java b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableEntityInventory.java diff --git a/patches/server/0101-Fix-global-sound-handling.patch b/patches/server/0101-Fix-global-sound-handling.patch index 68b8b9a1b89f..e96dd9f673ff 100644 --- a/patches/server/0101-Fix-global-sound-handling.patch +++ b/patches/server/0101-Fix-global-sound-handling.patch @@ -80,21 +80,22 @@ index 4c284ccd5b2eb05f487aba18e1daa0b59c3e8129..10c79cbc25383c0b65fb22a734751313 double deltaLength = Math.sqrt(distanceSquared); double relativeX = player.getX() + (deltaX / deltaLength) * viewDistance; diff --git a/src/main/java/net/minecraft/world/item/EnderEyeItem.java b/src/main/java/net/minecraft/world/item/EnderEyeItem.java -index 04fce5cc4350df81c7ea103b74b845313dd6cc37..770467bd319f8e2fdf3d713591368aa825cfa5ae 100644 +index 04fce5cc4350df81c7ea103b74b845313dd6cc37..08cbf02bba3633a84cce90c202d13f2beb5b88a2 100644 --- a/src/main/java/net/minecraft/world/item/EnderEyeItem.java +++ b/src/main/java/net/minecraft/world/item/EnderEyeItem.java -@@ -66,11 +66,12 @@ public class EnderEyeItem extends Item { +@@ -66,11 +66,13 @@ public class EnderEyeItem extends Item { // world.globalLevelEvent(1038, blockposition1.offset(1, 0, 1), 0); int viewDistance = world.getCraftServer().getViewDistance() * 16; BlockPos soundPos = blockposition1.offset(1, 0, 1); - for (ServerPlayer player : world.getServer().getPlayerList().players) { -+ for (ServerPlayer player : world.getPlayersForGlobalSoundGamerule()) { // Paper - respect global sound events gamerule ++ final net.minecraft.server.level.ServerLevel serverLevel = (net.minecraft.server.level.ServerLevel) world; // Paper - respect global sound events gamerule - ensured by isClientSide check above ++ for (ServerPlayer player : serverLevel.getPlayersForGlobalSoundGamerule()) { // Paper - respect global sound events gamerule double deltaX = soundPos.getX() - player.getX(); double deltaZ = soundPos.getZ() - player.getZ(); double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; - if (world.spigotConfig.endPortalSoundRadius > 0 && distanceSquared > world.spigotConfig.endPortalSoundRadius * world.spigotConfig.endPortalSoundRadius) continue; // Spigot -+ final double soundRadiusSquared = world.getGlobalSoundRangeSquared(config -> config.endPortalSoundRadius); // Paper - respect global sound events gamerule -+ if (!world.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_GLOBAL_SOUND_EVENTS) && distanceSquared > soundRadiusSquared) continue; // Spigot // Paper - respect global sound events gamerule ++ final double soundRadiusSquared = serverLevel.getGlobalSoundRangeSquared(config -> config.endPortalSoundRadius); // Paper - respect global sound events gamerule ++ if (!serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_GLOBAL_SOUND_EVENTS) && distanceSquared > soundRadiusSquared) continue; // Spigot // Paper - respect global sound events gamerule if (distanceSquared > viewDistance * viewDistance) { double deltaLength = Math.sqrt(distanceSquared); double relativeX = player.getX() + (deltaX / deltaLength) * viewDistance; diff --git a/patches/server/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch b/patches/server/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch index 572b69e96e22..11222ddf7db3 100644 --- a/patches/server/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch +++ b/patches/server/0135-Do-not-submit-profile-lookups-to-worldgen-threads.patch @@ -10,7 +10,7 @@ out due to a sync load, as the worldgen threads will be stalling on profile lookups. diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java -index 5d0ef11671beb2381e0e1959f5e5f845789a2982..b87d3ac2700eedb492bd55a631c60630c2f9c96c 100644 +index 2ff5a6517d717bbd4c944572040bd30866347341..8cac2075077b1d9c2b01e09c99780ff9e204abb2 100644 --- a/src/main/java/net/minecraft/Util.java +++ b/src/main/java/net/minecraft/Util.java @@ -95,6 +95,22 @@ public class Util { diff --git a/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch b/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch index 1c3173436b98..176e32776450 100644 --- a/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch +++ b/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch @@ -9,7 +9,7 @@ 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 84ea1974445fc7be80ed474d8a2133b58ee4c8fe..aa3155bb57c09895d13914b46c77de78a90f250a 100644 +index 30b28d9523820ed138c837ab9ee9bbb23c0dd285..01c32ed14b1047671883911f8606ef2924ebee73 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1100,7 +1100,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0212-PlayerLaunchProjectileEvent.patch b/patches/server/0212-PlayerLaunchProjectileEvent.patch index 14e01c4e3f84..1905955997d1 100644 --- a/patches/server/0212-PlayerLaunchProjectileEvent.patch +++ b/patches/server/0212-PlayerLaunchProjectileEvent.patch @@ -201,7 +201,7 @@ index 7a5045469bc2d383ed087dcc094b6f97df4ec7ab..fa92a1346825f00a585503d0a0825711 } } diff --git a/src/main/java/net/minecraft/world/item/SnowballItem.java b/src/main/java/net/minecraft/world/item/SnowballItem.java -index ada9bc42a788b5f472324a0765edf5766d729784..1e996276a80b34e353c6a7c7fee765c9db7123ea 100644 +index ada9bc42a788b5f472324a0765edf5766d729784..57872ebef6beb8cdc03c9f8f19de94652ee19062 100644 --- a/src/main/java/net/minecraft/world/item/SnowballItem.java +++ b/src/main/java/net/minecraft/world/item/SnowballItem.java @@ -26,17 +26,26 @@ public class SnowballItem extends Item implements ProjectileItem { @@ -212,7 +212,7 @@ index ada9bc42a788b5f472324a0765edf5766d729784..1e996276a80b34e353c6a7c7fee765c9 - itemstack.consume(1, user); + // Paper start - PlayerLaunchProjectileEvent + final Projectile.Delayed snowball = Projectile.spawnProjectileFromRotationDelayed(Snowball::new, worldserver, itemstack, user, 0.0F, 1.5F, 1.0F); -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitysnowball.getBukkitEntity()); ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) snowball.projectile().getBukkitEntity()); + if (event.callEvent() && snowball.attemptSpawn()) { + user.awardStat(Stats.ITEM_USED.get(this)); + if (event.shouldConsume()) { diff --git a/patches/server/0260-Improve-Server-Thread-Pool-and-Thread-Priorities.patch b/patches/server/0260-Improve-Server-Thread-Pool-and-Thread-Priorities.patch index 7ea32f4967db..3d0645bfc41c 100644 --- a/patches/server/0260-Improve-Server-Thread-Pool-and-Thread-Priorities.patch +++ b/patches/server/0260-Improve-Server-Thread-Pool-and-Thread-Priorities.patch @@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..b60f59cf5cc8eb84a6055b7861857dec + } +} diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java -index b87d3ac2700eedb492bd55a631c60630c2f9c96c..0fbe4ea495a8101f6bc1b9830ce3f47af2aa5be4 100644 +index 8cac2075077b1d9c2b01e09c99780ff9e204abb2..bf2833c92eca6491699b4a89410e4e46b5bbe4d1 100644 --- a/src/main/java/net/minecraft/Util.java +++ b/src/main/java/net/minecraft/Util.java @@ -92,7 +92,7 @@ public class Util { diff --git a/patches/server/0306-Tracking-Range-Improvements.patch b/patches/server/0306-Tracking-Range-Improvements.patch index 45bbbb2ad5b5..a7cfc3f988eb 100644 --- a/patches/server/0306-Tracking-Range-Improvements.patch +++ b/patches/server/0306-Tracking-Range-Improvements.patch @@ -8,7 +8,7 @@ Sets tracking range of watermobs to animals instead of misc and simplifies code Also ignores Enderdragon, defaulting it to Mojang's setting diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index aa3155bb57c09895d13914b46c77de78a90f250a..b849d24144dc9f7d24484398cec3b2b90befb507 100644 +index 01c32ed14b1047671883911f8606ef2924ebee73..f8decd2f1841da947a3cff5b275efff63ba37def 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1604,6 +1604,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0328-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch b/patches/server/0328-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch index 538add849398..3a9e4f516e8c 100644 --- a/patches/server/0328-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch +++ b/patches/server/0328-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch @@ -7,7 +7,7 @@ Suspected case would be around the technique used in .stopRiding Stack will identify any causer of this and warn instead of crashing. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index b849d24144dc9f7d24484398cec3b2b90befb507..f3b99cd96672363e0d60e56b744f0bea8fa00c3f 100644 +index f8decd2f1841da947a3cff5b275efff63ba37def..926e1ebfe3a011a28fb82b855511aaabca0c4072 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1300,6 +1300,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0339-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch b/patches/server/0339-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch index 7d3cdd3d1cad..0863194ba30a 100644 --- a/patches/server/0339-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch +++ b/patches/server/0339-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch @@ -31,7 +31,7 @@ delays anymore. public net.minecraft.server.level.ChunkMap addEntity(Lnet/minecraft/world/entity/Entity;)V diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index f3b99cd96672363e0d60e56b744f0bea8fa00c3f..8121f7f5fb4dadb1c929b3d81121e3649981bfac 100644 +index 926e1ebfe3a011a28fb82b855511aaabca0c4072..4d8dcc47b39d28ab715110e55110869fe3c9b456 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1307,6 +1307,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0432-Add-PlayerItemCooldownEvent.patch b/patches/server/0432-Add-PlayerItemCooldownEvent.patch index 70845dd2e6fe..954ff181f9fe 100644 --- a/patches/server/0432-Add-PlayerItemCooldownEvent.patch +++ b/patches/server/0432-Add-PlayerItemCooldownEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerItemCooldownEvent diff --git a/src/main/java/net/minecraft/world/item/ServerItemCooldowns.java b/src/main/java/net/minecraft/world/item/ServerItemCooldowns.java -index 3a45a149ec4a28f25ea9e45803ecbb7392b63f86..872813ef19fc08cad93786367e15f59400825c33 100644 +index 3a45a149ec4a28f25ea9e45803ecbb7392b63f86..2a80b8e962bf9d01e720b5967f0feac7d5dcaa28 100644 --- a/src/main/java/net/minecraft/world/item/ServerItemCooldowns.java +++ b/src/main/java/net/minecraft/world/item/ServerItemCooldowns.java @@ -11,6 +11,16 @@ public class ServerItemCooldowns extends ItemCooldowns { @@ -14,8 +14,8 @@ index 3a45a149ec4a28f25ea9e45803ecbb7392b63f86..872813ef19fc08cad93786367e15f594 + // Paper start - Add PlayerItemCooldownEvent + @Override -+ public void addCooldown(Item item, int duration) { -+ io.papermc.paper.event.player.PlayerItemCooldownEvent event = new io.papermc.paper.event.player.PlayerItemCooldownEvent(this.player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemType.minecraftToBukkit(item), duration); ++ public void addCooldown(ItemStack item, int duration) { ++ io.papermc.paper.event.player.PlayerItemCooldownEvent event = new io.papermc.paper.event.player.PlayerItemCooldownEvent(this.player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemType.minecraftToBukkit(item.getItem()), duration); + if (event.callEvent()) { + super.addCooldown(item, event.getCooldown()); + } diff --git a/patches/server/0437-Add-PlayerShearBlockEvent.patch b/patches/server/0437-Add-PlayerShearBlockEvent.patch index ea5d3db95175..db7c1ccc7155 100644 --- a/patches/server/0437-Add-PlayerShearBlockEvent.patch +++ b/patches/server/0437-Add-PlayerShearBlockEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerShearBlockEvent diff --git a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java -index 7e2a39a1ee092b46ab46caec0214255d9c333536..a5b84e6844e16cf1fdfb6f45efb8a7a165757d1c 100644 +index 7e2a39a1ee092b46ab46caec0214255d9c333536..20f705c90a0a96321cfe29c0cf564013dcccd18f 100644 --- a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java @@ -141,7 +141,7 @@ public class BeehiveBlock extends BaseEntityBlock { @@ -25,7 +25,7 @@ index 7e2a39a1ee092b46ab46caec0214255d9c333536..a5b84e6844e16cf1fdfb6f45efb8a7a1 + io.papermc.paper.event.block.PlayerShearBlockEvent event = new io.papermc.paper.event.block.PlayerShearBlockEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), new java.util.ArrayList<>()); + event.getDrops().add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(new ItemStack(Items.HONEYCOMB, 3))); + if (!event.callEvent()) { -+ return ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION; ++ return InteractionResult.PASS; + } + // Paper end world.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BEEHIVE_SHEAR, SoundSource.BLOCKS, 1.0F, 1.0F); @@ -39,7 +39,7 @@ index 7e2a39a1ee092b46ab46caec0214255d9c333536..a5b84e6844e16cf1fdfb6f45efb8a7a1 flag = true; world.gameEvent((Entity) player, (Holder) GameEvent.SHEAR, pos); diff --git a/src/main/java/net/minecraft/world/level/block/PumpkinBlock.java b/src/main/java/net/minecraft/world/level/block/PumpkinBlock.java -index dad7a610286b0ab6b916a6169fa8f6f641deb39a..42413723b3c826debb310ef1d5d2c9f80a616e86 100644 +index dad7a610286b0ab6b916a6169fa8f6f641deb39a..2b43c77d5aa609d4716df827cefcf008dfd13a06 100644 --- a/src/main/java/net/minecraft/world/level/block/PumpkinBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PumpkinBlock.java @@ -38,16 +38,24 @@ public class PumpkinBlock extends Block { @@ -50,7 +50,7 @@ index dad7a610286b0ab6b916a6169fa8f6f641deb39a..42413723b3c826debb310ef1d5d2c9f8 + io.papermc.paper.event.block.PlayerShearBlockEvent event = new io.papermc.paper.event.block.PlayerShearBlockEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), new java.util.ArrayList<>()); + event.getDrops().add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(new ItemStack(Items.PUMPKIN_SEEDS, 4))); + if (!event.callEvent()) { -+ return ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION; ++ return InteractionResult.PASS; + } + // Paper end - Add PlayerShearBlockEvent Direction direction = hit.getDirection(); diff --git a/patches/server/0451-Add-PlayerFlowerPotManipulateEvent.patch b/patches/server/0451-Add-PlayerFlowerPotManipulateEvent.patch index aa78c43c602b..5b13a05793ce 100644 --- a/patches/server/0451-Add-PlayerFlowerPotManipulateEvent.patch +++ b/patches/server/0451-Add-PlayerFlowerPotManipulateEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerFlowerPotManipulateEvent diff --git a/src/main/java/net/minecraft/world/level/block/FlowerPotBlock.java b/src/main/java/net/minecraft/world/level/block/FlowerPotBlock.java -index c6de1b6587b300404c38c27f566c80de11bc0814..863eec736b4941930c62ca357703a56d4d21c950 100644 +index c6de1b6587b300404c38c27f566c80de11bc0814..bee71ed48365694c488af88317a738fc6a4e5893 100644 --- a/src/main/java/net/minecraft/world/level/block/FlowerPotBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FlowerPotBlock.java @@ -61,6 +61,18 @@ public class FlowerPotBlock extends Block { @@ -21,7 +21,7 @@ index c6de1b6587b300404c38c27f566c80de11bc0814..863eec736b4941930c62ca357703a56d + // Update client + player.containerMenu.sendAllDataToRemote(); + -+ return ItemInteractionResult.CONSUME; ++ return InteractionResult.CONSUME; + } + // Paper end - Add PlayerFlowerPotManipulateEvent world.setBlock(pos, blockState, 3); diff --git a/patches/server/0467-Add-RegistryAccess-for-managing-Registries.patch b/patches/server/0467-Add-RegistryAccess-for-managing-Registries.patch index 2dfbc6b5603a..5c3821894826 100644 --- a/patches/server/0467-Add-RegistryAccess-for-managing-Registries.patch +++ b/patches/server/0467-Add-RegistryAccess-for-managing-Registries.patch @@ -719,7 +719,7 @@ index 3f72e30b57fb2a4231e22a2234729408c1240af4..4638ba98dbbdb0f880337347be85a6e0 LOADERS.put(resourceLocation, () -> initializer.run(registry)); WRITABLE_REGISTRY.register((ResourceKey)key, registry, RegistrationInfo.BUILT_IN); // Paper - decompile fix diff --git a/src/main/java/net/minecraft/resources/RegistryDataLoader.java b/src/main/java/net/minecraft/resources/RegistryDataLoader.java -index f4f1a99d53ffb953beb2a944f54d28fa6349fa29..144a6f5b0c53110804d6d099fe857d25f107d938 100644 +index a75f6fefdd72188fa8d16df2b5cbb34c4129f52d..61774165a25209ee6d26cf8d80149b220c3874e6 100644 --- a/src/main/java/net/minecraft/resources/RegistryDataLoader.java +++ b/src/main/java/net/minecraft/resources/RegistryDataLoader.java @@ -351,6 +351,7 @@ public class RegistryDataLoader { diff --git a/patches/server/0468-Add-StructuresLocateEvent.patch b/patches/server/0468-Add-StructuresLocateEvent.patch index 5312adefad7b..5556e96212ef 100644 --- a/patches/server/0468-Add-StructuresLocateEvent.patch +++ b/patches/server/0468-Add-StructuresLocateEvent.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add StructuresLocateEvent Co-authored-by: Jake Potrebic diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index 115deba41ec48143570489e8494785a3a48cd789..fd2dd6d25b8d6f3066c60a7f30a58a72cb418b85 100644 +index 115deba41ec48143570489e8494785a3a48cd789..e3c5a49611d584fbd19a44da5aa78ff6d7c43881 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -126,6 +126,24 @@ public abstract class ChunkGenerator { @@ -23,12 +23,12 @@ index 115deba41ec48143570489e8494785a3a48cd789..fd2dd6d25b8d6f3066c60a7f30a58a72 + return null; + } + if (event.getResult() != null) { -+ return Pair.of(io.papermc.paper.util.MCUtil.toBlockPos(event.getResult().pos()), world.registryAccess().registryOrThrow(Registries.STRUCTURE).wrapAsHolder(org.bukkit.craftbukkit.generator.structure.CraftStructure.bukkitToMinecraft(event.getResult().structure()))); ++ return Pair.of(io.papermc.paper.util.MCUtil.toBlockPos(event.getResult().pos()), world.registryAccess().lookupOrThrow(Registries.STRUCTURE).wrapAsHolder(org.bukkit.craftbukkit.generator.structure.CraftStructure.bukkitToMinecraft(event.getResult().structure()))); + } + center = io.papermc.paper.util.MCUtil.toBlockPosition(event.getOrigin()); + radius = event.getRadius(); + skipReferencedStructures = event.shouldFindUnexplored(); -+ structures = HolderSet.direct(api -> world.registryAccess().registryOrThrow(Registries.STRUCTURE).wrapAsHolder(org.bukkit.craftbukkit.generator.structure.CraftStructure.bukkitToMinecraft(api)), event.getStructures()); ++ structures = HolderSet.direct(api -> world.registryAccess().lookupOrThrow(Registries.STRUCTURE).wrapAsHolder(org.bukkit.craftbukkit.generator.structure.CraftStructure.bukkitToMinecraft(api)), event.getStructures()); + } + // Paper end ChunkGeneratorStructureState chunkgeneratorstructurestate = world.getChunkSource().getGeneratorState(); diff --git a/patches/server/0528-ItemStack-repair-check-API.patch b/patches/server/0528-ItemStack-repair-check-API.patch index cd4d72339316..46a3c4192142 100644 --- a/patches/server/0528-ItemStack-repair-check-API.patch +++ b/patches/server/0528-ItemStack-repair-check-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] ItemStack repair check API diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index e546cf93d79b109d50840ebf1fb133ad3c9331d3..1ae77ef4bd47a4aea894242cd48dbf042477da33 100644 +index e546cf93d79b109d50840ebf1fb133ad3c9331d3..844dbd996858aa02e81a4256383df6992b87bde2 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -532,6 +532,14 @@ public final class CraftMagicNumbers implements UnsafeValues { @@ -18,7 +18,7 @@ index e546cf93d79b109d50840ebf1fb133ad3c9331d3..1ae77ef4bd47a4aea894242cd48dbf04 + if (!itemToBeRepaired.getType().isItem() || !repairMaterial.getType().isItem()) { + return false; + } -+ return CraftMagicNumbers.getItem(itemToBeRepaired.getType()).isValidRepairItem(CraftItemStack.asNMSCopy(itemToBeRepaired), CraftItemStack.asNMSCopy(repairMaterial)); ++ return CraftItemStack.unwrap(itemToBeRepaired).isValidRepairItem(CraftItemStack.unwrap(repairMaterial)); + } // Paper end diff --git a/patches/server/0535-Improve-item-default-attribute-API.patch b/patches/server/0535-Improve-item-default-attribute-API.patch index c9eb3843be35..b970088c751d 100644 --- a/patches/server/0535-Improve-item-default-attribute-API.patch +++ b/patches/server/0535-Improve-item-default-attribute-API.patch @@ -62,7 +62,7 @@ index 68756419ac6ee292db9569eab380a5c14d748002..6d76cc1db3ac3f1ae74c13511937fb86 return defaultAttributes.build(); } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 1ae77ef4bd47a4aea894242cd48dbf042477da33..0d9c90a99aa2d8fcf421680aeef4c2fd7ec0fd57 100644 +index 844dbd996858aa02e81a4256383df6992b87bde2..7e33f55e4a269fd8e96080776c97f49d65e895c4 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -391,7 +391,11 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0580-Get-entity-default-attributes.patch b/patches/server/0580-Get-entity-default-attributes.patch index d383f32269c9..ef862f64a60e 100644 --- a/patches/server/0580-Get-entity-default-attributes.patch +++ b/patches/server/0580-Get-entity-default-attributes.patch @@ -81,23 +81,23 @@ index 0000000000000000000000000000000000000000..ec9ebd2d539333293c51b7edfa18f18b + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 0d9c90a99aa2d8fcf421680aeef4c2fd7ec0fd57..5c0a6d93b424db91a5f6474165434f5db3d15a8a 100644 +index 7e33f55e4a269fd8e96080776c97f49d65e895c4..c9e0a2a4c7c8ab50f6dbb6079f2cba06652a92a3 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -544,6 +544,18 @@ public final class CraftMagicNumbers implements UnsafeValues { } - return CraftMagicNumbers.getItem(itemToBeRepaired.getType()).isValidRepairItem(CraftItemStack.asNMSCopy(itemToBeRepaired), CraftItemStack.asNMSCopy(repairMaterial)); + return CraftItemStack.unwrap(itemToBeRepaired).isValidRepairItem(CraftItemStack.unwrap(repairMaterial)); } + + @Override + public boolean hasDefaultEntityAttributes(NamespacedKey bukkitEntityKey) { -+ return net.minecraft.world.entity.ai.attributes.DefaultAttributes.hasSupplier(net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.get(CraftNamespacedKey.toMinecraft(bukkitEntityKey))); ++ return net.minecraft.world.entity.ai.attributes.DefaultAttributes.hasSupplier(net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.getValue(CraftNamespacedKey.toMinecraft(bukkitEntityKey))); + } + + @Override + public org.bukkit.attribute.Attributable getDefaultEntityAttributes(NamespacedKey bukkitEntityKey) { + Preconditions.checkArgument(hasDefaultEntityAttributes(bukkitEntityKey), bukkitEntityKey + " doesn't have default attributes"); -+ var supplier = net.minecraft.world.entity.ai.attributes.DefaultAttributes.getSupplier((net.minecraft.world.entity.EntityType) net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.get(CraftNamespacedKey.toMinecraft(bukkitEntityKey))); ++ var supplier = net.minecraft.world.entity.ai.attributes.DefaultAttributes.getSupplier((net.minecraft.world.entity.EntityType) net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.getValue(CraftNamespacedKey.toMinecraft(bukkitEntityKey))); + return new io.papermc.paper.attribute.UnmodifiableAttributeMap(supplier); + } // Paper end diff --git a/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch b/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch index 75c80fef00f6..3464fbf215c8 100644 --- a/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch +++ b/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch @@ -50,7 +50,7 @@ index 0c1c9033646dedcf1d11dee74d6965683adadf0a..1ed01978611cddb2558e441863dadc46 @Override public boolean isInvisible() { // Paper - moved up from LivingEntity diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 5c0a6d93b424db91a5f6474165434f5db3d15a8a..e2873a1eeb01516b689d0175b091808b2797995f 100644 +index c9e0a2a4c7c8ab50f6dbb6079f2cba06652a92a3..8d51786837448db1a96d0071293025d07e14c225 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -494,7 +494,33 @@ public final class CraftMagicNumbers implements UnsafeValues { @@ -80,7 +80,7 @@ index 5c0a6d93b424db91a5f6474165434f5db3d15a8a..e2873a1eeb01516b689d0175b091808b + // Generate a new UUID so we don't have to worry about deserializing the same entity twice + compound.remove("UUID"); + } -+ return net.minecraft.world.entity.EntityType.create(compound, ((org.bukkit.craftbukkit.CraftWorld) world).getHandle()) ++ return net.minecraft.world.entity.EntityType.create(compound, ((org.bukkit.craftbukkit.CraftWorld) world).getHandle(), net.minecraft.world.entity.EntitySpawnReason.LOAD) + .orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?")).getBukkitEntity(); + } + diff --git a/patches/server/0602-Oprimise-map-impl-for-tracked-players.patch b/patches/server/0602-Oprimise-map-impl-for-tracked-players.patch index fb3f23985694..c0bbabf27c02 100644 --- a/patches/server/0602-Oprimise-map-impl-for-tracked-players.patch +++ b/patches/server/0602-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 8121f7f5fb4dadb1c929b3d81121e3649981bfac..7f18146c0dea654c62b3e01e6848fd1c05f87946 100644 +index 4d8dcc47b39d28ab715110e55110869fe3c9b456..75854574aa8d4aef35d84ba4c0fc7df9a67ae48c 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1520,7 +1520,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0620-Configurable-feature-seeds.patch b/patches/server/0620-Configurable-feature-seeds.patch index 9085e326c316..ffca9db1e262 100644 --- a/patches/server/0620-Configurable-feature-seeds.patch +++ b/patches/server/0620-Configurable-feature-seeds.patch @@ -19,7 +19,7 @@ index 49028463ba47e760281545c2f7597e3db8d6c453..7620c72a4c243cbeea245203ce03a97c } final Object val = config.get(key); diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index fd2dd6d25b8d6f3066c60a7f30a58a72cb418b85..575fa665ff9c8f52056a0e7305540ec5c3da4785 100644 +index e3c5a49611d584fbd19a44da5aa78ff6d7c43881..fc8e3edd9734fa7b69f0fc6b4eefd8a704e451cf 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -436,7 +436,14 @@ public abstract class ChunkGenerator { diff --git a/patches/server/0624-Remove-client-side-code-using-deprecated-for-removal.patch b/patches/server/0624-Remove-client-side-code-using-deprecated-for-removal.patch index 3640523f9a31..1a9d2657f14f 100644 --- a/patches/server/0624-Remove-client-side-code-using-deprecated-for-removal.patch +++ b/patches/server/0624-Remove-client-side-code-using-deprecated-for-removal.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Remove client-side code using deprecated for removal Fixes warnings on build diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java -index 0fbe4ea495a8101f6bc1b9830ce3f47af2aa5be4..60e523f4de1cbafc2c58a5d568fe3989b7b07c34 100644 +index bf2833c92eca6491699b4a89410e4e46b5bbe4d1..57223285860f61119b6cf348aa78e59384a04e22 100644 --- a/src/main/java/net/minecraft/Util.java +++ b/src/main/java/net/minecraft/Util.java @@ -1082,16 +1082,7 @@ public class Util { diff --git a/patches/server/0655-Add-missing-structure-set-seed-configs.patch b/patches/server/0655-Add-missing-structure-set-seed-configs.patch index 2862998d8470..42bd7f0c4b78 100644 --- a/patches/server/0655-Add-missing-structure-set-seed-configs.patch +++ b/patches/server/0655-Add-missing-structure-set-seed-configs.patch @@ -20,7 +20,7 @@ seeds/salts to the frequency reducer which has a similar effect. Co-authored-by: William Blake Galbreath diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index 575fa665ff9c8f52056a0e7305540ec5c3da4785..906f56d07c26ef3c2dc1a3b62e9349dd91a37742 100644 +index fc8e3edd9734fa7b69f0fc6b4eefd8a704e451cf..31c5f54c90d6e35875f762747f8618e58e2eed91 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -573,7 +573,7 @@ public abstract class ChunkGenerator { diff --git a/patches/server/0690-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch b/patches/server/0690-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch index 3ba905932f5e..3ecc56a3325f 100644 --- a/patches/server/0690-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch +++ b/patches/server/0690-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch @@ -40,7 +40,7 @@ index e000a918230187f6841b03b7b0dd73687f3cc15e..5c3e5c348e6fececccd8097355f423b9 return true; // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java -index a5b84e6844e16cf1fdfb6f45efb8a7a165757d1c..90f69a0c4d0707fd2319db71aea7dfdc14636d82 100644 +index 20f705c90a0a96321cfe29c0cf564013dcccd18f..d5ed53c37bba79f84b60d616887cd5176e124f10 100644 --- a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java @@ -103,7 +103,7 @@ public class BeehiveBlock extends BaseEntityBlock { diff --git a/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch b/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch index 0a9ed2d8c148..410a98a9238c 100644 --- a/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch +++ b/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch @@ -24,7 +24,7 @@ index 37111113f6ab6d77c558b10c4162758135db99b0..911b6391455402922e8bd52cfe9e5694 EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity()); Bukkit.getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java -index db8bb6e47b28bac6cf568415af3ffdd6eeac6ac7..59b00aa57f62ec9d56c28d18c493e952e66f39c7 100644 +index dde1ccca98f58200910334160f0f79eb00dd2388..5af4d590a9b0f17ba53c6959d9c18bd1269878a4 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java +++ b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java @@ -604,7 +604,7 @@ public class Dolphin extends AgeableWaterCreature { diff --git a/patches/server/0727-Add-NamespacedKey-biome-methods.patch b/patches/server/0727-Add-NamespacedKey-biome-methods.patch index 0991968c4d81..547d0fb0b746 100644 --- a/patches/server/0727-Add-NamespacedKey-biome-methods.patch +++ b/patches/server/0727-Add-NamespacedKey-biome-methods.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add NamespacedKey biome methods Co-authored-by: Thonk <30448663+ExcessiveAmountsOfZombies@users.noreply.github.com> diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index e2873a1eeb01516b689d0175b091808b2797995f..66913ab43bb1e9066487749ff60248c22fc8e824 100644 +index 8d51786837448db1a96d0071293025d07e14c225..9e0af05e066132b66fafff84ff0a0957c1a44f9f 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -584,6 +584,21 @@ public final class CraftMagicNumbers implements UnsafeValues { @@ -17,13 +17,13 @@ index e2873a1eeb01516b689d0175b091808b2797995f..66913ab43bb1e9066487749ff60248c2 + @Override + public org.bukkit.NamespacedKey getBiomeKey(org.bukkit.RegionAccessor accessor, int x, int y, int z) { + org.bukkit.craftbukkit.CraftRegionAccessor cra = (org.bukkit.craftbukkit.CraftRegionAccessor) accessor; -+ return org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(cra.getHandle().registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.BIOME).getKey(cra.getHandle().getBiome(new net.minecraft.core.BlockPos(x, y, z)).value())); ++ return org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(cra.getHandle().registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BIOME).getKey(cra.getHandle().getBiome(new net.minecraft.core.BlockPos(x, y, z)).value())); + } + + @Override + public void setBiomeKey(org.bukkit.RegionAccessor accessor, int x, int y, int z, org.bukkit.NamespacedKey biomeKey) { + org.bukkit.craftbukkit.CraftRegionAccessor cra = (org.bukkit.craftbukkit.CraftRegionAccessor) accessor; -+ net.minecraft.core.Holder biomeBase = cra.getHandle().registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.BIOME).getHolderOrThrow(net.minecraft.resources.ResourceKey.create(net.minecraft.core.registries.Registries.BIOME, org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(biomeKey))); ++ net.minecraft.core.Holder biomeBase = cra.getHandle().registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BIOME).getOrThrow(net.minecraft.resources.ResourceKey.create(net.minecraft.core.registries.Registries.BIOME, org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(biomeKey))); + cra.setBiome(x, y, z, biomeBase); + } + // Paper end - namespaced key biome methods diff --git a/patches/server/0730-Fire-EntityChangeBlockEvent-in-more-places.patch b/patches/server/0730-Fire-EntityChangeBlockEvent-in-more-places.patch index 3fab5db6280f..1d46619357f1 100644 --- a/patches/server/0730-Fire-EntityChangeBlockEvent-in-more-places.patch +++ b/patches/server/0730-Fire-EntityChangeBlockEvent-in-more-places.patch @@ -7,18 +7,23 @@ Co-authored-by: ChristopheG <61288881+chrisgdt@users.noreply.github.com> Co-authored-by: maxcom1 <46265094+maxcom1@users.noreply.github.com> diff --git a/src/main/java/net/minecraft/world/effect/WeavingMobEffect.java b/src/main/java/net/minecraft/world/effect/WeavingMobEffect.java -index e311f94918fb03e9d202cbae71b0909ea3219180..d090126dbe6b69489490e6b1e2d443fa171ddde6 100644 +index e311f94918fb03e9d202cbae71b0909ea3219180..b751748196b458c8a89d512fdd9f9632d25e8be8 100644 --- a/src/main/java/net/minecraft/world/effect/WeavingMobEffect.java +++ b/src/main/java/net/minecraft/world/effect/WeavingMobEffect.java -@@ -25,7 +25,7 @@ class WeavingMobEffect extends MobEffect { +@@ -25,11 +25,11 @@ class WeavingMobEffect extends MobEffect { @Override public void onMobRemoved(ServerLevel world, LivingEntity entity, int amplifier, Entity.RemovalReason reason) { if (reason == Entity.RemovalReason.KILLED && (entity instanceof Player || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { - this.spawnCobwebsRandomlyAround(world, entity.getRandom(), entity.blockPosition()); -+ this.spawnCobwebsRandomlyAround(entity, world, entity.getRandom(), entity.blockPosition()); // Paper - Fire EntityChangeBlockEvent in more places ++ this.spawnCobwebsRandomlyAround(world, entity.getRandom(), entity.blockPosition(), entity); // Paper - Fire EntityChangeBlockEvent in more places } } +- private void spawnCobwebsRandomlyAround(ServerLevel world, RandomSource random, BlockPos pos) { ++ private void spawnCobwebsRandomlyAround(ServerLevel world, RandomSource random, BlockPos pos, LivingEntity entity) { // Paper - Fire EntityChangeBlockEvent in more places + Set set = Sets.newHashSet(); + int i = this.maxCobwebs.applyAsInt(random); + @@ -46,6 +46,7 @@ class WeavingMobEffect extends MobEffect { } @@ -117,7 +122,7 @@ index 74c9966093377b67e31b50483c2f24b70734faf6..abff08f2d61014944235ffe2f5494a71 CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, blockPos, itemStack); } diff --git a/src/main/java/net/minecraft/world/item/EnderEyeItem.java b/src/main/java/net/minecraft/world/item/EnderEyeItem.java -index 770467bd319f8e2fdf3d713591368aa825cfa5ae..b00a2fe4cefff26b65789829777b25bbc8e024fa 100644 +index 08cbf02bba3633a84cce90c202d13f2beb5b88a2..c71a426c47e0ebc57ecb8c9c1d171737a084ccab 100644 --- a/src/main/java/net/minecraft/world/item/EnderEyeItem.java +++ b/src/main/java/net/minecraft/world/item/EnderEyeItem.java @@ -45,6 +45,11 @@ public class EnderEyeItem extends Item { @@ -152,7 +157,7 @@ index 6c0fe41692c9d1fa50a4f421eb4735860a9ae0e9..d7924825823b2bf79ca3a26272de11ff CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(serverPlayer, blockPos, itemStack); } diff --git a/src/main/java/net/minecraft/world/item/PotionItem.java b/src/main/java/net/minecraft/world/item/PotionItem.java -index 1c8fd643c32226d72d51abc869a49e256dd2432b..627439c3aa8171e9a54dbcb8842af50cc58f7f23 100644 +index 1c8fd643c32226d72d51abc869a49e256dd2432b..f19bd2c25d3c84d9f16cad38ac5c32736f0f3a8d 100644 --- a/src/main/java/net/minecraft/world/item/PotionItem.java +++ b/src/main/java/net/minecraft/world/item/PotionItem.java @@ -42,6 +42,12 @@ public class PotionItem extends Item { @@ -160,8 +165,8 @@ index 1c8fd643c32226d72d51abc869a49e256dd2432b..627439c3aa8171e9a54dbcb8842af50c BlockState blockState = level.getBlockState(blockPos); if (context.getClickedFace() != Direction.DOWN && blockState.is(BlockTags.CONVERTABLE_TO_MUD) && potionContents.is(Potions.WATER)) { + // Paper start -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entityhuman, blockposition, Blocks.MUD.defaultBlockState())) { -+ entityhuman.containerMenu.sendAllDataToRemote(); ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, Blocks.MUD.defaultBlockState())) { ++ player.containerMenu.sendAllDataToRemote(); + return InteractionResult.PASS; + } + // Paper end @@ -204,7 +209,7 @@ index c0377341227e8f4f1f7b1448580b3c7bc1b65f48..55c18f182166f4905d623d6f5e909eef level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(player, blockState3)); if (player != null) { diff --git a/src/main/java/net/minecraft/world/level/block/CakeBlock.java b/src/main/java/net/minecraft/world/level/block/CakeBlock.java -index 7629b9212ded7155e94f67ca429f62271e5f5aa0..1104f620a050555f71d058711cc34fadb964222f 100644 +index 7629b9212ded7155e94f67ca429f62271e5f5aa0..648c2510beb162e73aed236a3169d0bbb8fc5050 100644 --- a/src/main/java/net/minecraft/world/level/block/CakeBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CakeBlock.java @@ -66,6 +66,12 @@ public class CakeBlock extends Block { @@ -214,7 +219,7 @@ index 7629b9212ded7155e94f67ca429f62271e5f5aa0..1104f620a050555f71d058711cc34fad + // Paper start - call change block event + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, pos, CandleCakeBlock.byCandle(candleblock))) { + player.containerMenu.sendAllDataToRemote(); // update inv because candle could decrease -+ return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; ++ return InteractionResult.TRY_WITH_EMPTY_HAND; + } + // Paper end - call change block event stack.consume(1, player); @@ -245,7 +250,7 @@ index 7629b9212ded7155e94f67ca429f62271e5f5aa0..1104f620a050555f71d058711cc34fad world.gameEvent((Entity) player, (Holder) GameEvent.EAT, pos); if (i < 6) { diff --git a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java -index 2bcd246a26dad560cf69682b29983d320ebf1884..60bf63c2cff3ce8a1892ba5c2303738c35b83d79 100644 +index 2bcd246a26dad560cf69682b29983d320ebf1884..05b2eab26e2dc8e143e9fff2dcec40cfe927a197 100644 --- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java @@ -243,6 +243,11 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { @@ -254,7 +259,7 @@ index 2bcd246a26dad560cf69682b29983d320ebf1884..60bf63c2cff3ce8a1892ba5c2303738c BlockState iblockdata1 = ComposterBlock.addItem(player, state, world, pos, stack); + // Paper start - handle cancelled events + if (iblockdata1 == null) { -+ return ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION; ++ return InteractionResult.PASS; + } + // Paper end diff --git a/patches/server/0737-fix-Jigsaw-block-kicking-user.patch b/patches/server/0737-fix-Jigsaw-block-kicking-user.patch index a7960e5bc324..749d498f5799 100644 --- a/patches/server/0737-fix-Jigsaw-block-kicking-user.patch +++ b/patches/server/0737-fix-Jigsaw-block-kicking-user.patch @@ -5,7 +5,7 @@ Subject: [PATCH] fix Jigsaw block kicking user diff --git a/src/main/java/net/minecraft/world/level/block/entity/JigsawBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/JigsawBlockEntity.java -index 42300114e3baf31fd26090fca3b497c8157d4bb9..8fda7f812ba266cf8051f6796d2c35cba197e904 100644 +index 42300114e3baf31fd26090fca3b497c8157d4bb9..6410cd7a7324bb04e9285a5b090b1675a5ffa16f 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/JigsawBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/JigsawBlockEntity.java @@ -131,7 +131,12 @@ public class JigsawBlockEntity extends BlockEntity { @@ -14,7 +14,7 @@ index 42300114e3baf31fd26090fca3b497c8157d4bb9..8fda7f812ba266cf8051f6796d2c35cb Registry registry = world.registryAccess().lookupOrThrow(Registries.TEMPLATE_POOL); - Holder holder = registry.getOrThrow(this.pool); + // Paper start - Replace getHolderOrThrow with a null check -+ Holder holder = registry.getHolder(this.pool).orElse(null); ++ Holder holder = registry.get(this.pool).orElse(null); + if (holder == null) { + return; + } diff --git a/patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch b/patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch index c52bbed900e9..0de43bc77c23 100644 --- a/patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch +++ b/patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch @@ -91,7 +91,7 @@ index 6854ca4d4fec2b4fa541c3fabf63787665572609..e7b444a10b244828827b3c66c5346520 } diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 7f18146c0dea654c62b3e01e6848fd1c05f87946..1a724f9bb6ef82a0b5fdd9ade036d7365167f14b 100644 +index 75854574aa8d4aef35d84ba4c0fc7df9a67ae48c..3f3124bbb5077a18c3d3afac7748a47e84b8fe35 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1080,7 +1080,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0768-Player-Entity-Tracking-Events.patch b/patches/server/0768-Player-Entity-Tracking-Events.patch index c3458e621d9a..3cf77bc532c2 100644 --- a/patches/server/0768-Player-Entity-Tracking-Events.patch +++ b/patches/server/0768-Player-Entity-Tracking-Events.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Player Entity Tracking Events diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 1a724f9bb6ef82a0b5fdd9ade036d7365167f14b..ec19eb88705a07db45f1a3541571fb7f43efb5a9 100644 +index 3f3124bbb5077a18c3d3afac7748a47e84b8fe35..7810df9c5045a78c2731ee416366da4f973e5d29 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1592,7 +1592,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0791-Add-CompostItemEvent-and-EntityCompostItemEvent.patch b/patches/server/0791-Add-CompostItemEvent-and-EntityCompostItemEvent.patch index eba5cdc5c9da..2e105236eec0 100644 --- a/patches/server/0791-Add-CompostItemEvent-and-EntityCompostItemEvent.patch +++ b/patches/server/0791-Add-CompostItemEvent-and-EntityCompostItemEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add CompostItemEvent and EntityCompostItemEvent diff --git a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java -index 60bf63c2cff3ce8a1892ba5c2303738c35b83d79..2d7712fae0801b6ae48d23cabd46a7700c0c0bec 100644 +index 05b2eab26e2dc8e143e9fff2dcec40cfe927a197..db837b250fc35af5b528bf973b3b07f63e79bc46 100644 --- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java @@ -340,7 +340,21 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { diff --git a/patches/server/0845-Fix-custom-statistic-criteria-creation.patch b/patches/server/0845-Fix-custom-statistic-criteria-creation.patch index 6e562a7f2d8d..420f7179e993 100644 --- a/patches/server/0845-Fix-custom-statistic-criteria-creation.patch +++ b/patches/server/0845-Fix-custom-statistic-criteria-creation.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix custom statistic criteria creation diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 66913ab43bb1e9066487749ff60248c22fc8e824..78b5578ece76c88a4dafcd4220a82081e85cf735 100644 +index 9e0af05e066132b66fafff84ff0a0957c1a44f9f..766ef49d72eef0ff80247a807db5379f7fc60302 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -599,6 +599,14 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0851-Properly-handle-BlockBreakEvent-isDropItems.patch b/patches/server/0851-Properly-handle-BlockBreakEvent-isDropItems.patch index 047d717ba6e0..6c61a65a1c40 100644 --- a/patches/server/0851-Properly-handle-BlockBreakEvent-isDropItems.patch +++ b/patches/server/0851-Properly-handle-BlockBreakEvent-isDropItems.patch @@ -24,7 +24,7 @@ index 2aee9c2fbe38076317a3de7c3fdbd6988b64b389..3bd4ab8161c29bb8df2ba496a4430393 // return true; // CraftBukkit diff --git a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java -index 90f69a0c4d0707fd2319db71aea7dfdc14636d82..9591870420390fe1a69d44855a8f4de779332b7d 100644 +index d5ed53c37bba79f84b60d616887cd5176e124f10..6c0ea0bde1c36edda92807e317ed37f8b1bdac6a 100644 --- a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java @@ -94,8 +94,8 @@ public class BeehiveBlock extends BaseEntityBlock { diff --git a/patches/server/0853-Configurable-entity-tracking-range-by-Y-coordinate.patch b/patches/server/0853-Configurable-entity-tracking-range-by-Y-coordinate.patch index 6c2edf83e23d..75dd71166a36 100644 --- a/patches/server/0853-Configurable-entity-tracking-range-by-Y-coordinate.patch +++ b/patches/server/0853-Configurable-entity-tracking-range-by-Y-coordinate.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Configurable entity tracking range by Y coordinate Options to configure entity tracking by Y coordinate, also for each entity category. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index ec19eb88705a07db45f1a3541571fb7f43efb5a9..49d926313b0d0f2ed2e93ca824009c8d0a988f67 100644 +index 7810df9c5045a78c2731ee416366da4f973e5d29..502d73830ed87e06529f194090a4ffb895b2623c 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1583,7 +1583,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0863-Optimize-nearest-structure-border-iteration.patch b/patches/server/0863-Optimize-nearest-structure-border-iteration.patch index f16f98ea9bc3..edd50774ccac 100644 --- a/patches/server/0863-Optimize-nearest-structure-border-iteration.patch +++ b/patches/server/0863-Optimize-nearest-structure-border-iteration.patch @@ -14,7 +14,7 @@ ensure that the returned found structure (which may for example be a buried treasure that will be marked on a treasure map) is the same as in vanilla. diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index 906f56d07c26ef3c2dc1a3b62e9349dd91a37742..4cbc68d8e950f8d7c8b00535b82e916964c88ce0 100644 +index 31c5f54c90d6e35875f762747f8618e58e2eed91..582065b2d4e818c0edec36b2e9847f8ed3266b10 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -265,12 +265,15 @@ public abstract class ChunkGenerator { diff --git a/patches/server/0874-Fix-spigot-s-Forced-Stats.patch b/patches/server/0874-Fix-spigot-s-Forced-Stats.patch index 554f1f884493..8e920d0d8974 100644 --- a/patches/server/0874-Fix-spigot-s-Forced-Stats.patch +++ b/patches/server/0874-Fix-spigot-s-Forced-Stats.patch @@ -8,7 +8,7 @@ disables saving any forced stats, so it stays at the same value (without enablin fixes stat initialization to not cause a NullPointerException diff --git a/src/main/java/net/minecraft/stats/ServerStatsCounter.java b/src/main/java/net/minecraft/stats/ServerStatsCounter.java -index ec437644adff6a6ec1e3fe2dd3a6354edafde1db..fb7342f7a5008a283c3400c6313c637de8210dfa 100644 +index ec437644adff6a6ec1e3fe2dd3a6354edafde1db..da7e1a69ecb4e6b3be2d8544ac406aa519bd196e 100644 --- a/src/main/java/net/minecraft/stats/ServerStatsCounter.java +++ b/src/main/java/net/minecraft/stats/ServerStatsCounter.java @@ -48,13 +48,6 @@ public class ServerStatsCounter extends StatsCounter { @@ -36,7 +36,7 @@ index ec437644adff6a6ec1e3fe2dd3a6354edafde1db..fb7342f7a5008a283c3400c6313c637d + // Spigot start + for ( Map.Entry entry : org.spigotmc.SpigotConfig.forcedStats.entrySet() ) + { -+ Stat wrapper = Stats.CUSTOM.get(java.util.Objects.requireNonNull(BuiltInRegistries.CUSTOM_STAT.get(entry.getKey()))); // Paper - ensured by SpigotConfig#stats ++ Stat wrapper = Stats.CUSTOM.get(java.util.Objects.requireNonNull(BuiltInRegistries.CUSTOM_STAT.getValue(entry.getKey()))); // Paper - ensured by SpigotConfig#stats + this.stats.put( wrapper, entry.getValue().intValue() ); + } + // Spigot end diff --git a/patches/server/0883-Fix-UnsafeValues-loadAdvancement.patch b/patches/server/0883-Fix-UnsafeValues-loadAdvancement.patch index 57e986f1b776..fa08d471abd2 100644 --- a/patches/server/0883-Fix-UnsafeValues-loadAdvancement.patch +++ b/patches/server/0883-Fix-UnsafeValues-loadAdvancement.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix UnsafeValues#loadAdvancement diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 78b5578ece76c88a4dafcd4220a82081e85cf735..bd77a942a264a5d9cdaba4cc63099b8ae00c48f6 100644 +index 766ef49d72eef0ff80247a807db5379f7fc60302..3900f95f3ea41b010b8ea79c043fe322fa233461 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -308,9 +308,30 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0885-Don-t-check-if-we-can-see-non-visible-entities.patch b/patches/server/0885-Don-t-check-if-we-can-see-non-visible-entities.patch index e86be5d7849f..5078fe7f0179 100644 --- a/patches/server/0885-Don-t-check-if-we-can-see-non-visible-entities.patch +++ b/patches/server/0885-Don-t-check-if-we-can-see-non-visible-entities.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Don't check if we can see non-visible entities diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 49d926313b0d0f2ed2e93ca824009c8d0a988f67..29a28e160f6ca87d263b84fbf0c5429d30e34a21 100644 +index 502d73830ed87e06529f194090a4ffb895b2623c..95c70de2c9f0e26742c0d66ad6c3bcc310a923f6 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1596,7 +1596,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch b/patches/server/0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch index a9f20c91ac7b..2fd7060c00b0 100644 --- a/patches/server/0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch +++ b/patches/server/0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch @@ -18,7 +18,7 @@ index a043ac10834562d357ef0b5aded2e916e2a0d056..74276c368016fcc4dbf9579b2ecbadc9 @VisibleForTesting static long encode(double value) { diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 29a28e160f6ca87d263b84fbf0c5429d30e34a21..a43eef8bf05855270601761494b6a67dc55cb1c9 100644 +index 95c70de2c9f0e26742c0d66ad6c3bcc310a923f6..182513bb175feb5f30f0fb1cd5db501b6d483afd 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1578,10 +1578,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0917-Add-api-for-spawn-egg-texture-colors.patch b/patches/server/0917-Add-api-for-spawn-egg-texture-colors.patch index 255e25785b07..ee55eb2e4a4d 100644 --- a/patches/server/0917-Add-api-for-spawn-egg-texture-colors.patch +++ b/patches/server/0917-Add-api-for-spawn-egg-texture-colors.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add api for spawn egg texture colors diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index bd77a942a264a5d9cdaba4cc63099b8ae00c48f6..db177cb5a99b3529b2eed291bc794234214f8e7c 100644 +index 3900f95f3ea41b010b8ea79c043fe322fa233461..7ae4567bc6f2f0374d1a4a3859f6329eaace7415 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -643,6 +643,15 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0918-Add-Lifecycle-Event-system.patch b/patches/server/0918-Add-Lifecycle-Event-system.patch index e2eaeec2f9bd..d93b26d6b3df 100644 --- a/patches/server/0918-Add-Lifecycle-Event-system.patch +++ b/patches/server/0918-Add-Lifecycle-Event-system.patch @@ -743,7 +743,7 @@ index dbdf52a306d7018f0bf01fcf6c24a6d1dc269be5..fb55dced981d16a82e4cc233fbf25695 this.reloadCount++; this.configuration = YamlConfiguration.loadConfiguration(this.getConfigFile()); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index db177cb5a99b3529b2eed291bc794234214f8e7c..5a94b9a5c400818818cc427160d696f10470f3a2 100644 +index 7ae4567bc6f2f0374d1a4a3859f6329eaace7415..ca201861b383bac4ea93284ac017e85ae0b3b17c 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -652,6 +652,13 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0919-ItemStack-Tooltip-API.patch b/patches/server/0919-ItemStack-Tooltip-API.patch index c7e83e2f18b4..7279f3026121 100644 --- a/patches/server/0919-ItemStack-Tooltip-API.patch +++ b/patches/server/0919-ItemStack-Tooltip-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] ItemStack Tooltip API diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 5a94b9a5c400818818cc427160d696f10470f3a2..b24ccbff89db873f5bdf62cbebcca0049b94a8d5 100644 +index ca201861b383bac4ea93284ac017e85ae0b3b17c..8feba2bd411abe36e64a39a0c599c73d07c19e20 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -628,6 +628,21 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/0979-Anti-Xray.patch b/patches/server/0979-Anti-Xray.patch index f19373b3edb0..88fd107647ed 100644 --- a/patches/server/0979-Anti-Xray.patch +++ b/patches/server/0979-Anti-Xray.patch @@ -199,7 +199,7 @@ index 0000000000000000000000000000000000000000..52d2e2b744f91914802506e52a071617 +} diff --git a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java new file mode 100644 -index 0000000000000000000000000000000000000000..e7fe98ea30ae6d0baea3ec1f9f98a89502a49a12 +index 0000000000000000000000000000000000000000..4b44053cf7704e3889440361bb4971d7aa03e3ba --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java @@ -0,0 +1,676 @@ @@ -331,7 +331,7 @@ index 0000000000000000000000000000000000000000..e7fe98ea30ae6d0baea3ec1f9f98a895 + } + } + -+ EmptyLevelChunk emptyChunk = new EmptyLevelChunk(level, new ChunkPos(0, 0), MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME).getHolderOrThrow(Biomes.PLAINS)); ++ EmptyLevelChunk emptyChunk = new EmptyLevelChunk(level, new ChunkPos(0, 0), MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BIOME).getOrThrow(Biomes.PLAINS)); + BlockPos zeroPos = new BlockPos(0, 0, 0); + + for (int i = 0; i < solidGlobal.length; i++) { @@ -427,7 +427,7 @@ index 0000000000000000000000000000000000000000..e7fe98ea30ae6d0baea3ec1f9f98a895 + LevelChunkSection[] nearbyChunkSections = new LevelChunkSection[4]; + LevelChunk chunk = chunkPacketInfoAntiXray.getChunk(); + Level level = chunk.getLevel(); -+ int maxChunkSectionIndex = Math.min((maxBlockHeight >> 4) - chunk.getMinSection(), chunk.getSectionsCount()) - 1; ++ int maxChunkSectionIndex = Math.min((maxBlockHeight >> 4) - chunk.getMinSectionY(), chunk.getSectionsCount()) - 1; + boolean[] solidTemp = null; + boolean[] obfuscateTemp = null; + bitStorageReader.setBuffer(chunkPacketInfoAntiXray.getBuffer()); @@ -485,7 +485,7 @@ index 0000000000000000000000000000000000000000..e7fe98ea30ae6d0baea3ec1f9f98a895 + presetBlockStateBitsTemp = switch (level.getWorld().getEnvironment()) { + case NETHER -> presetBlockStateBitsNetherrackGlobal; + case THE_END -> presetBlockStateBitsEndStoneGlobal; -+ default -> chunkSectionIndex + chunk.getMinSection() < 0 ? presetBlockStateBitsDeepslateGlobal : presetBlockStateBitsStoneGlobal; ++ default -> chunkSectionIndex + chunk.getMinSectionY() < 0 ? presetBlockStateBitsDeepslateGlobal : presetBlockStateBitsStoneGlobal; + }; + } else { + presetBlockStateBitsTemp = presetBlockStateBitsGlobal; @@ -1519,7 +1519,7 @@ index 303e59be721d0e16e8822cf4e407595348ee7abf..51f74dd7b276e858889803d7f341d735 int getSerializedSize(); diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index b86b3bf713668999a21c4120b1d16c295531b2ad..57998a47fa39cac141226c75bd68d4b37e8424ae 100644 +index b86b3bf713668999a21c4120b1d16c295531b2ad..f6c42532d4921628072d44313404696890087b9f 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java @@ -111,6 +111,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun @@ -1540,7 +1540,7 @@ index b86b3bf713668999a21c4120b1d16c295531b2ad..57998a47fa39cac141226c75bd68d4b3 if (nbttagcompound3.contains("block_states", 10)) { - datapaletteblock = (PalettedContainer) SerializableChunkData.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, nbttagcompound3.getCompound("block_states")).promotePartial((s1) -> { -+ Codec> blockStateCodec = presetBlockStates == null ? ChunkSerializer.BLOCK_STATE_CODEC : PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), presetBlockStates); // Paper - Anti-Xray ++ Codec> blockStateCodec = presetBlockStates == null ? BLOCK_STATE_CODEC : PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), presetBlockStates); // Paper - Anti-Xray + datapaletteblock = blockStateCodec.parse(NbtOps.INSTANCE, nbttagcompound1.getCompound("block_states")).promotePartial((s1) -> { // Paper - Anti-Xray logErrors(chunkcoordintpair, b0, s1); }).getOrThrow(SerializableChunkData.ChunkReadException::new); diff --git a/patches/server/0988-Fix-entity-type-tags-suggestions-in-selectors.patch b/patches/server/0988-Fix-entity-type-tags-suggestions-in-selectors.patch index 7fdb68ae3b5e..1b14145b717b 100644 --- a/patches/server/0988-Fix-entity-type-tags-suggestions-in-selectors.patch +++ b/patches/server/0988-Fix-entity-type-tags-suggestions-in-selectors.patch @@ -114,7 +114,7 @@ index 9d31e29ec62f437e642ed60da69c4b106bd9e770..ce200e673b54c66cfdf34657db28d3ee this.level = MinMaxBounds.Ints.ANY; this.rotX = WrappedMinMaxBounds.ANY; diff --git a/src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java b/src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java -index 5d0c82ba9465bf75640e52bf71924ee5862937f0..e27bd295adcf3289a7c71e044ae392884fe01e0a 100644 +index 5d0c82ba9465bf75640e52bf71924ee5862937f0..9d5c766416cf34ddf0d7e250f13c0985195cb135 100644 --- a/src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java +++ b/src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java @@ -76,6 +76,19 @@ public class EntitySelectorOptions { @@ -142,7 +142,7 @@ index 5d0c82ba9465bf75640e52bf71924ee5862937f0..e27bd295adcf3289a7c71e044ae39288 if (reader.isTag()) { TagKey> tagKey = TagKey.create(Registries.ENTITY_TYPE, ResourceLocation.read(reader.getReader())); + // Paper start - tell clients to ask server for suggestions for EntityArguments; throw error if invalid entity tag (only on suggestions to keep cmd success behavior) -+ if (reader.parsingEntityArgumentSuggestions && io.papermc.paper.configuration.GlobalConfiguration.get().commands.fixTargetSelectorTagCompletion && net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.getTag(tagKey).isEmpty()) { ++ if (reader.parsingEntityArgumentSuggestions && io.papermc.paper.configuration.GlobalConfiguration.get().commands.fixTargetSelectorTagCompletion && net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.get(tagKey).isEmpty()) { + reader.getReader().setCursor(i); + throw ERROR_ENTITY_TAG_INVALID.createWithContext(reader.getReader(), tagKey); + } diff --git a/patches/server/0990-Check-distance-in-entity-interactions.patch b/patches/server/0990-Check-distance-in-entity-interactions.patch index d142b760dd9d..8fe3898ba0cb 100644 --- a/patches/server/0990-Check-distance-in-entity-interactions.patch +++ b/patches/server/0990-Check-distance-in-entity-interactions.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Check distance in entity interactions diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java -index 60e523f4de1cbafc2c58a5d568fe3989b7b07c34..dd2037fe9389765f79330036ec7fa3c5e7c7327a 100644 +index 57223285860f61119b6cf348aa78e59384a04e22..ccfe9ef24dce9f34613692adb13738d3ad0e7aac 100644 --- a/src/main/java/net/minecraft/Util.java +++ b/src/main/java/net/minecraft/Util.java @@ -128,6 +128,7 @@ public class Util { diff --git a/patches/server/0993-Registry-Modification-API.patch b/patches/server/0993-Registry-Modification-API.patch index ac28f625c728..d61a98a7a446 100644 --- a/patches/server/0993-Registry-Modification-API.patch +++ b/patches/server/0993-Registry-Modification-API.patch @@ -1134,7 +1134,7 @@ index 71e04e5c1bc0722abf8ca2e0738bd60b6d7ae21c..063630c1ffcce099139c59d598fc5a21 + // Paper end } diff --git a/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java b/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java -index 4638ba98dbbdb0f880337347be85a6e0fbed2191..12ba8bc0a946c107b076e2c995aca6a3aeb3811f 100644 +index 4638ba98dbbdb0f880337347be85a6e0fbed2191..bc448f8511c629d1f13d4baf717a11e6a6ad24f9 100644 --- a/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java +++ b/src/main/java/net/minecraft/core/registries/BuiltInRegistries.java @@ -296,6 +296,17 @@ public class BuiltInRegistries { @@ -1145,9 +1145,9 @@ index 4638ba98dbbdb0f880337347be85a6e0fbed2191..12ba8bc0a946c107b076e2c995aca6a3 + public static final io.papermc.paper.registry.data.util.Conversions BUILT_IN_CONVERSIONS = new io.papermc.paper.registry.data.util.Conversions(new net.minecraft.resources.RegistryOps.RegistryInfoLookup() { + @Override + public java.util.Optional> lookup(final ResourceKey> registryRef) { -+ final Registry registry = net.minecraft.server.RegistryLayer.STATIC_ACCESS.registryOrThrow(registryRef); ++ final Registry registry = net.minecraft.server.RegistryLayer.STATIC_ACCESS.lookupOrThrow(registryRef); + return java.util.Optional.of( -+ new net.minecraft.resources.RegistryOps.RegistryInfo<>(registry.asLookup(), registry.asTagAddingLookup(), Lifecycle.experimental()) ++ new net.minecraft.resources.RegistryOps.RegistryInfo<>(registry, registry, Lifecycle.experimental()) + ); + } + }); @@ -1172,7 +1172,7 @@ index 4638ba98dbbdb0f880337347be85a6e0fbed2191..12ba8bc0a946c107b076e2c995aca6a3 } } diff --git a/src/main/java/net/minecraft/resources/RegistryDataLoader.java b/src/main/java/net/minecraft/resources/RegistryDataLoader.java -index 144a6f5b0c53110804d6d099fe857d25f107d938..f2236665eaf3e6d0f9d44605db3cd5afe0cced4e 100644 +index 61774165a25209ee6d26cf8d80149b220c3874e6..fdc88e52235a152dbe3cca273990b4b68f8daaf8 100644 --- a/src/main/java/net/minecraft/resources/RegistryDataLoader.java +++ b/src/main/java/net/minecraft/resources/RegistryDataLoader.java @@ -130,7 +130,7 @@ public class RegistryDataLoader { @@ -1323,7 +1323,7 @@ index 6fddef967b6314ca0158f5bd4b8898670ea5e9ec..b5ca1a0acb16d0cd8dccc854f309d425 return writableRegistry; }, prepareExecutor); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java -index f8450a2abd1e96fac7827d252cc00038b9dee839..a812a42ea81b1543287e78ea55da6cbf4e0d27f8 100644 +index f8450a2abd1e96fac7827d252cc00038b9dee839..891ccc39d52331648a11b4e7cce78d4c848cdea0 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java @@ -167,11 +167,11 @@ public class CraftRegistry implements Registry { @@ -1348,18 +1348,18 @@ index f8450a2abd1e96fac7827d252cc00038b9dee839..a812a42ea81b1543287e78ea55da6cbf + // Paper start - RegistrySet API + @Override + public boolean hasTag(final io.papermc.paper.registry.tag.TagKey key) { -+ return this.minecraftRegistry.getTag(net.minecraft.tags.TagKey.create(this.minecraftRegistry.key(), io.papermc.paper.adventure.PaperAdventure.asVanilla(key.key()))).isPresent(); ++ return this.minecraftRegistry.get(net.minecraft.tags.TagKey.create(this.minecraftRegistry.key(), io.papermc.paper.adventure.PaperAdventure.asVanilla(key.key()))).isPresent(); + } + + @Override + public io.papermc.paper.registry.tag.Tag getTag(final io.papermc.paper.registry.tag.TagKey key) { -+ final net.minecraft.core.HolderSet.Named namedHolderSet = this.minecraftRegistry.getTag(io.papermc.paper.registry.PaperRegistries.toNms(key)).orElseThrow(); ++ final net.minecraft.core.HolderSet.Named namedHolderSet = this.minecraftRegistry.get(io.papermc.paper.registry.PaperRegistries.toNms(key)).orElseThrow(); + return new io.papermc.paper.registry.set.NamedRegistryKeySetImpl<>(key, namedHolderSet); + } + // Paper end - RegistrySet API } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index b24ccbff89db873f5bdf62cbebcca0049b94a8d5..49b898ed5e9de2507a6a6aac61dea4fe902649ca 100644 +index 8feba2bd411abe36e64a39a0c599c73d07c19e20..75b5ec1023e2cf974696ee077195b195025ddc74 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -674,6 +674,21 @@ public final class CraftMagicNumbers implements UnsafeValues { @@ -1373,9 +1373,9 @@ index b24ccbff89db873f5bdf62cbebcca0049b94a8d5..49b898ed5e9de2507a6a6aac61dea4fe + throw new UnsupportedOperationException(tagKey.registryKey() + " doesn't have tags"); + } + final net.minecraft.resources.ResourceKey> nmsKey = io.papermc.paper.registry.PaperRegistries.registryToNms(tagKey.registryKey()); -+ final net.minecraft.core.Registry nmsRegistry = org.bukkit.craftbukkit.CraftRegistry.getMinecraftRegistry().registryOrThrow(nmsKey); ++ final net.minecraft.core.Registry nmsRegistry = org.bukkit.craftbukkit.CraftRegistry.getMinecraftRegistry().lookupOrThrow(nmsKey); + return nmsRegistry -+ .getTag(io.papermc.paper.registry.PaperRegistries.toNms(tagKey)) ++ .get(io.papermc.paper.registry.PaperRegistries.toNms(tagKey)) + .map(named -> new io.papermc.paper.registry.set.NamedRegistryKeySetImpl<>(tagKey, named)) + .orElse(null); + } diff --git a/patches/server/0995-Proxy-ItemStack-to-CraftItemStack.patch b/patches/server/0995-Proxy-ItemStack-to-CraftItemStack.patch index 684b037d30fd..f37751ee6f15 100644 --- a/patches/server/0995-Proxy-ItemStack-to-CraftItemStack.patch +++ b/patches/server/0995-Proxy-ItemStack-to-CraftItemStack.patch @@ -205,7 +205,7 @@ index 6cc9d7a9e6d4bfdc27e52fc581b2bb832616f121..6930d0afb230a88aa813b02e4d55c95d + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 49b898ed5e9de2507a6a6aac61dea4fe902649ca..02745957a08a27af6a032453b8b20a8fed2911b3 100644 +index 75b5ec1023e2cf974696ee077195b195025ddc74..f1178a6c8ccd1ad099d67b906f755eea1dfc0e53 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -689,6 +689,13 @@ public final class CraftMagicNumbers implements UnsafeValues { diff --git a/patches/server/1020-Add-FeatureFlag-API.patch b/patches/server/1020-Add-FeatureFlag-API.patch index c8da36ae78b0..deea8b504e67 100644 --- a/patches/server/1020-Add-FeatureFlag-API.patch +++ b/patches/server/1020-Add-FeatureFlag-API.patch @@ -282,7 +282,7 @@ index 6cf790c9fa23ea313423fdaeb7c181bf530828c6..0bcb9df1103050441f8922a688b163dc public static PotionEffectType minecraftHolderToBukkit(Holder minecraft) { return CraftPotionEffectType.minecraftToBukkit(minecraft.value()); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 02745957a08a27af6a032453b8b20a8fed2911b3..293757b8e96ae7b0e807d807affa3fdab5181d39 100644 +index f1178a6c8ccd1ad099d67b906f755eea1dfc0e53..e1186f840670aabb73668e03d66789f9e306e234 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -47,7 +47,7 @@ import org.bukkit.advancement.Advancement; diff --git a/patches/server/1021-Tag-Lifecycle-Events.patch b/patches/server/1021-Tag-Lifecycle-Events.patch index dcd0a5334a2a..fb7d66db7d3e 100644 --- a/patches/server/1021-Tag-Lifecycle-Events.patch +++ b/patches/server/1021-Tag-Lifecycle-Events.patch @@ -461,7 +461,7 @@ index 0000000000000000000000000000000000000000..d6d4bfc6f45d646afeace422a038c670 +) { +} diff --git a/src/main/java/net/minecraft/resources/RegistryDataLoader.java b/src/main/java/net/minecraft/resources/RegistryDataLoader.java -index f2236665eaf3e6d0f9d44605db3cd5afe0cced4e..28d809a0e2fccd15a09bc6b55ca024526867ada7 100644 +index fdc88e52235a152dbe3cca273990b4b68f8daaf8..13797035494a1e010e1da529fb46040f8a6e859f 100644 --- a/src/main/java/net/minecraft/resources/RegistryDataLoader.java +++ b/src/main/java/net/minecraft/resources/RegistryDataLoader.java @@ -278,7 +278,7 @@ public class RegistryDataLoader { diff --git a/patches/server/1022-Item-serialization-as-json.patch b/patches/server/1022-Item-serialization-as-json.patch index 51d1f7f8085f..9e7e7399ca2b 100644 --- a/patches/server/1022-Item-serialization-as-json.patch +++ b/patches/server/1022-Item-serialization-as-json.patch @@ -28,7 +28,7 @@ index c80fd4960dfbb0fde37363e7df25b0a5411bdb11..ff7f6916f65466c25a7bde35d64682c1 public static final Codec CODEC_WITH_ID = CODEC.validate( component -> component.getUnsafe().contains("id", 8) ? DataResult.success(component) : DataResult.error(() -> "Missing id for entity in: " + component) diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 293757b8e96ae7b0e807d807affa3fdab5181d39..f880bf91155b017c954e3e321c5a203c05c2162f 100644 +index e1186f840670aabb73668e03d66789f9e306e234..2a5c5e9e04d90c4e218b200bb55ff6bf2877ad73 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -511,6 +511,39 @@ public final class CraftMagicNumbers implements UnsafeValues { From bb124f40217e336a6a1575a9b4334762cd796553 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Fri, 25 Oct 2024 17:08:48 +0200 Subject: [PATCH 055/119] Compiler issues v4 --- .../api/0227-Zombie-API-breaking-doors.patch | 6 ++-- patches/server/0009-MC-Utils.patch | 18 +++++++++-- ...PI-for-Reason-Source-Triggering-play.patch | 2 +- .../server/0211-PlayerElytraBoostEvent.patch | 2 +- .../0212-PlayerLaunchProjectileEvent.patch | 2 +- ...5-Vanished-players-don-t-have-rights.patch | 2 +- ...nt-furnace-cook-speed-multiplier-API.patch | 13 +++++--- ...nd-additions-to-the-spawn-reason-API.patch | 2 +- ...gurable-projectile-relative-velocity.patch | 2 +- ...-should-not-bypass-cramming-gamerule.patch | 2 +- ...et-Material-from-Boats-and-Minecarts.patch | 31 ++++++++++--------- .../0453-Zombie-API-breaking-doors.patch | 4 +-- ...n-for-requiring-a-player-participant.patch | 2 +- .../0493-Add-recipe-to-cook-events.patch | 2 +- ...-add-consumeFuel-to-FurnaceBurnEvent.patch | 2 +- ...d-canSmelt-methods-to-FurnaceInvento.patch | 9 +++--- .../server/0660-Furnace-RecipesUsed-API.patch | 18 +++++------ patches/server/0670-More-Projectile-API.patch | 3 +- ...ook-changes-from-crashing-the-server.patch | 2 +- .../0740-Fix-a-bunch-of-vanilla-bugs.patch | 2 +- patches/server/0796-Add-Shearable-API.patch | 20 ++++++++++-- ...ng-to-bad-recipes-in-furnace-like-ti.patch | 2 +- ...esh-ProjectileSource-for-projectiles.patch | 2 +- .../0857-Fix-NPE-on-Boat-getStatus.patch | 6 ++-- .../0908-Add-drops-to-shear-events.patch | 6 ++-- ...date-ResourceLocation-in-NBT-reading.patch | 2 +- ...heck-distance-in-entity-interactions.patch | 2 +- .../1005-Fix-PickupStatus-getting-reset.patch | 2 +- patches/server/1011-Leashable-API.patch | 2 +- 29 files changed, 104 insertions(+), 66 deletions(-) diff --git a/patches/api/0227-Zombie-API-breaking-doors.patch b/patches/api/0227-Zombie-API-breaking-doors.patch index 24118c13ee22..05fc193f7214 100644 --- a/patches/api/0227-Zombie-API-breaking-doors.patch +++ b/patches/api/0227-Zombie-API-breaking-doors.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Zombie API - breaking doors diff --git a/src/main/java/org/bukkit/entity/Zombie.java b/src/main/java/org/bukkit/entity/Zombie.java -index c1a5b625ea602d751a8026d989882c60e80756c9..93de95f68af45dba6a1da350a46adc1d1d058899 100644 +index c1a5b625ea602d751a8026d989882c60e80756c9..0a7d4d3f776a72b345d746c583e4c32267929b54 100644 --- a/src/main/java/org/bukkit/entity/Zombie.java +++ b/src/main/java/org/bukkit/entity/Zombie.java @@ -100,8 +100,10 @@ public interface Zombie extends Monster, Ageable { @@ -21,7 +21,7 @@ index c1a5b625ea602d751a8026d989882c60e80756c9..93de95f68af45dba6a1da350a46adc1d * the entity is currently breaking a door. * * @param flag Whether this zombie can break doors -@@ -162,5 +164,15 @@ public interface Zombie extends Monster, Ageable { +@@ -162,5 +164,17 @@ public interface Zombie extends Monster, Ageable { * @param shouldBurnInDay True to burn in sunlight */ void setShouldBurnInDay(boolean shouldBurnInDay); @@ -33,7 +33,9 @@ index c1a5b625ea602d751a8026d989882c60e80756c9..93de95f68af45dba6a1da350a46adc1d + * no effect. + * + * @return true if entity supports breaking doors ++ * @deprecated Since 1.21.2 all zombie types can break doors if instructed as MC-137053 was fixed. + */ ++ @Deprecated(since = "1.21.2", forRemoval = true) + boolean supportsBreakingDoors(); // Paper end } diff --git a/patches/server/0009-MC-Utils.patch b/patches/server/0009-MC-Utils.patch index 1adc5ed577f6..310d5c2f29f1 100644 --- a/patches/server/0009-MC-Utils.patch +++ b/patches/server/0009-MC-Utils.patch @@ -4077,10 +4077,10 @@ index 0000000000000000000000000000000000000000..197224e31175252d8438a8df585bbb65 +} diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java new file mode 100644 -index 0000000000000000000000000000000000000000..0449d4619e3a0752dea0981fb149542e23076c52 +index 0000000000000000000000000000000000000000..422bc104e5bdd4ae786b14d97eb779dc76bfad69 --- /dev/null +++ b/src/main/java/io/papermc/paper/util/MCUtil.java -@@ -0,0 +1,176 @@ +@@ -0,0 +1,190 @@ +package io.papermc.paper.util; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; @@ -4098,11 +4098,14 @@ index 0000000000000000000000000000000000000000..0449d4619e3a0752dea0981fb149542e +import java.util.function.Supplier; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Vec3i; ++import net.minecraft.resources.ResourceKey; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; +import org.bukkit.Location; ++import org.bukkit.NamespacedKey; ++import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.craftbukkit.util.Waitable; + +public final class MCUtil { @@ -4256,6 +4259,17 @@ index 0000000000000000000000000000000000000000..0449d4619e3a0752dea0981fb149542e + public static void scheduleAsyncTask(Runnable run) { + asyncExecutor.execute(run); + } ++ ++ public static ResourceKey toResourceKey( ++ final ResourceKey> registry, ++ final NamespacedKey namespacedKey ++ ) { ++ return ResourceKey.create(registry, CraftNamespacedKey.toMinecraft(namespacedKey)); ++ } ++ ++ public static NamespacedKey fromResourceKey(final ResourceKey key) { ++ return CraftNamespacedKey.fromMinecraft(key.location()); ++ } +} diff --git a/src/main/java/io/papermc/paper/util/StackWalkerUtil.java b/src/main/java/io/papermc/paper/util/StackWalkerUtil.java new file mode 100644 diff --git a/patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch b/patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch index 54243150fc94..6f2899e0dbad 100644 --- a/patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch +++ b/patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch @@ -304,7 +304,7 @@ index 3cefda12d4c2ca2c4e9ef97eff961a55af164d6b..43c2b411115d3a8a0e47d3e2277789b2 } diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index bddbb351ef676a86edb5da74a2a656c7da2ecb5d..62c49afd4da165d0cb4156f106e6e5480d267d4e 100644 +index 7341e14645eac007312889776a29d16fc390c5bf..119ea31f6e15185b6d6171053f790e39c24f6823 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java @@ -517,7 +517,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit diff --git a/patches/server/0211-PlayerElytraBoostEvent.patch b/patches/server/0211-PlayerElytraBoostEvent.patch index 53897d0ae43e..907b6b84e09f 100644 --- a/patches/server/0211-PlayerElytraBoostEvent.patch +++ b/patches/server/0211-PlayerElytraBoostEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] PlayerElytraBoostEvent diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 3b0b543a1bf8b190620fd4385751f05db74a47f1..9a6701f4ceed680ee12224802f01ce399798b6e1 100644 +index 46eff02aa250890485d58a10e76d571052086aa8..fd8afa4b12d66d1e0a789cef41ca77c45c64e2e8 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -219,11 +219,34 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/0212-PlayerLaunchProjectileEvent.patch b/patches/server/0212-PlayerLaunchProjectileEvent.patch index 1905955997d1..73ad83abbd81 100644 --- a/patches/server/0212-PlayerLaunchProjectileEvent.patch +++ b/patches/server/0212-PlayerLaunchProjectileEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] PlayerLaunchProjectileEvent diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 9a6701f4ceed680ee12224802f01ce399798b6e1..55c0d23ea68cd328881bd40d6bfd12d58477d15b 100644 +index fd8afa4b12d66d1e0a789cef41ca77c45c64e2e8..d29d58fd9879d69a7d3fd7cbcad8cc31c89fa679 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -197,7 +197,12 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/0215-Vanished-players-don-t-have-rights.patch b/patches/server/0215-Vanished-players-don-t-have-rights.patch index 59109ecdaa09..3bdc5087c3d1 100644 --- a/patches/server/0215-Vanished-players-don-t-have-rights.patch +++ b/patches/server/0215-Vanished-players-don-t-have-rights.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Vanished players don't have rights diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 55c0d23ea68cd328881bd40d6bfd12d58477d15b..e7fe338572a8bb740d6023c688d8c84ea04a2169 100644 +index d29d58fd9879d69a7d3fd7cbcad8cc31c89fa679..07b7187382fefc8b03a8822a097fb04e647f7732 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -387,6 +387,15 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/0246-Implement-furnace-cook-speed-multiplier-API.patch b/patches/server/0246-Implement-furnace-cook-speed-multiplier-API.patch index 1f16e2891306..3a04c8b1ea0e 100644 --- a/patches/server/0246-Implement-furnace-cook-speed-multiplier-API.patch +++ b/patches/server/0246-Implement-furnace-cook-speed-multiplier-API.patch @@ -6,10 +6,13 @@ Subject: [PATCH] Implement furnace cook speed multiplier API Fixed an issue where a furnace's cook-speed multiplier rounds down to the nearest Integer when updating its current cook time. +== AT == +public net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity getTotalCookTime(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;)I + Co-authored-by: Eric Su diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index 62c49afd4da165d0cb4156f106e6e5480d267d4e..b9dd5f710533b156311cac2c020fd0d5f64b6265 100644 +index 119ea31f6e15185b6d6171053f790e39c24f6823..187f380eae3948eb5e37e8703db6ea785aaf833d 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java @@ -74,11 +74,13 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit @@ -79,9 +82,9 @@ index 62c49afd4da165d0cb4156f106e6e5480d267d4e..b9dd5f710533b156311cac2c020fd0d5 return fuelRegistry.burnDuration(stack); } -- private static int getTotalCookTime(ServerLevel world, AbstractFurnaceBlockEntity furnace) { +- public static int getTotalCookTime(ServerLevel world, AbstractFurnaceBlockEntity furnace) { - if (world == null) return 200; // CraftBukkit - SPIGOT-4302 -+ private static int getTotalCookTime(@Nullable ServerLevel world, AbstractFurnaceBlockEntity furnace, RecipeType recipeType, double cookSpeedMultiplier) { // Paper - cook speed multiplier API ++ public static int getTotalCookTime(@Nullable ServerLevel world, AbstractFurnaceBlockEntity furnace, RecipeType recipeType, double cookSpeedMultiplier) { // Paper - cook speed multiplier API SingleRecipeInput singlerecipeinput = new SingleRecipeInput(furnace.getItem(0)); - return (Integer) furnace.quickCheck.getRecipeFor(singlerecipeinput, world).map((recipeholder) -> { @@ -110,7 +113,7 @@ index 62c49afd4da165d0cb4156f106e6e5480d267d4e..b9dd5f710533b156311cac2c020fd0d5 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java -index 7ed43bc29a4bc0f6db2cabd3cd4c8489ed81ee81..0ec30feb68efc1747e489ee4bb60e6a503cb31c4 100644 +index 7ed43bc29a4bc0f6db2cabd3cd4c8489ed81ee81..7b5f35779ac63b5f9b3a88cc4dcde38147fea2b7 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java @@ -88,4 +88,20 @@ public abstract class CraftFurnace extends @@ -130,7 +133,7 @@ index 7ed43bc29a4bc0f6db2cabd3cd4c8489ed81ee81..0ec30feb68efc1747e489ee4bb60e6a5 + com.google.common.base.Preconditions.checkArgument(multiplier <= 200, "Furnace speed multiplier cannot more than 200"); + T snapshot = this.getSnapshot(); + snapshot.cookSpeedMultiplier = multiplier; -+ snapshot.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.isPlaced() ? this.world.getHandle() : null, snapshot.recipeType, snapshot, snapshot.cookSpeedMultiplier); // Update the snapshot's current total cook time to scale with the newly set multiplier ++ snapshot.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.isPlaced() ? this.world.getHandle() : null, snapshot, snapshot.recipeType, snapshot.cookSpeedMultiplier); // Update the snapshot's current total cook time to scale with the newly set multiplier + } + // Paper end } diff --git a/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch b/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch index 776b020ee88c..90c812385400 100644 --- a/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch +++ b/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch @@ -173,7 +173,7 @@ index 2eecdcbea3d51b1fb6e0c3db0667464a699ca0df..c68ddccd5fbe27f6a62cedbdc2337f1b this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause } diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index e7fe338572a8bb740d6023c688d8c84ea04a2169..7c8f92b7e5eb66d26e6c46dc2ed86c68dbe97ae9 100644 +index 07b7187382fefc8b03a8822a097fb04e647f7732..e21b9a34d07fcd75f9c470074c545862d0aa9363 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -214,7 +214,12 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/0291-Configurable-projectile-relative-velocity.patch b/patches/server/0291-Configurable-projectile-relative-velocity.patch index 3ca413377fd6..c2d2345882ac 100644 --- a/patches/server/0291-Configurable-projectile-relative-velocity.patch +++ b/patches/server/0291-Configurable-projectile-relative-velocity.patch @@ -25,7 +25,7 @@ P3) Solutions for 1) and especially 2) might not be future-proof, while this server-internal fix makes this change future-proof. diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 7c8f92b7e5eb66d26e6c46dc2ed86c68dbe97ae9..2cb77d0b6e6ba880a2a76488a870a20ed883b15a 100644 +index e21b9a34d07fcd75f9c470074c545862d0aa9363..09d1131c7f2b32b6c032341a60521608b098c109 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -192,8 +192,11 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/0435-Climbing-should-not-bypass-cramming-gamerule.patch b/patches/server/0435-Climbing-should-not-bypass-cramming-gamerule.patch index 23a3982b7353..fec776eb5759 100644 --- a/patches/server/0435-Climbing-should-not-bypass-cramming-gamerule.patch +++ b/patches/server/0435-Climbing-should-not-bypass-cramming-gamerule.patch @@ -129,7 +129,7 @@ index 59fbfe8de2dc5ec020dd61a5e446b0b6f67d76e4..2bb2b36f793d25b6e49d1a72bb665cfa } diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java -index 4f3f149b79fc2f5cd97e7337b2ae39193b7177cd..a4eab65c280e493889621e62d8fc94158b930c96 100644 +index b0373df16a3e6910fb5f4a2ab7ca2523ced84a22..a9661ab34bc98c19d525eb4b60b1f0d05d73241e 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java @@ -144,7 +144,7 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable { diff --git a/patches/server/0448-API-to-get-Material-from-Boats-and-Minecarts.patch b/patches/server/0448-API-to-get-Material-from-Boats-and-Minecarts.patch index 1b80594eba1f..4194a22c1987 100644 --- a/patches/server/0448-API-to-get-Material-from-Boats-and-Minecarts.patch +++ b/patches/server/0448-API-to-get-Material-from-Boats-and-Minecarts.patch @@ -3,6 +3,8 @@ From: Madeline Miller Date: Thu, 31 Dec 2020 12:48:19 +1000 Subject: [PATCH] API to get Material from Boats and Minecarts +== AT == +public net.minecraft.world.entity.vehicle.AbstractBoat getDropItem()Lnet/minecraft/world/item/Item; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java index c101d01b55472efc9fc2829b8c17db5377ed57ff..5d51a49228eaee94f91cd04843e27c7918ca8796 100644 @@ -23,37 +25,36 @@ index c101d01b55472efc9fc2829b8c17db5377ed57ff..5d51a49228eaee94f91cd04843e27c79 public Status getStatus() { return CraftBoat.boatStatusFromNms(this.getHandle().status); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java -index ee010d53f8c671d17d68f3f43dca9978e23ac8ab..8920af5a0dfe737c1f38d906b53e6a278456d2aa 100644 +index ee010d53f8c671d17d68f3f43dca9978e23ac8ab..d35c1a10e58932b19c8053c5dacdc25fd7f22e8c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java -@@ -1,8 +1,10 @@ - package org.bukkit.craftbukkit.entity; - +@@ -3,6 +3,7 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.world.entity.vehicle.AbstractMinecart; -+import net.minecraft.world.item.Items; // Paper import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.Material; // Paper import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@@ -68,6 +70,22 @@ public abstract class CraftMinecart extends CraftVehicle implements Minecart { +@@ -68,6 +69,24 @@ public abstract class CraftMinecart extends CraftVehicle implements Minecart { this.getHandle().setDerailedVelocityMod(derailed); } + // Paper start + @Override + public Material getMinecartMaterial() { -+ net.minecraft.world.item.Item minecartItem = switch (getHandle().getMinecartType()) { -+ case CHEST -> Items.CHEST_MINECART; -+ case FURNACE -> Items.FURNACE_MINECART; -+ case TNT -> Items.TNT_MINECART; -+ case HOPPER -> Items.HOPPER_MINECART; -+ case COMMAND_BLOCK -> Items.COMMAND_BLOCK_MINECART; -+ case RIDEABLE, SPAWNER -> Items.MINECART; -+ }; ++ return CraftMagicNumbers.getMaterial(minecartEntityTypeToMaterial(this.getHandle().getType())); ++ } + -+ return CraftMagicNumbers.getMaterial(minecartItem); ++ static net.minecraft.world.item.Item minecartEntityTypeToMaterial(final net.minecraft.world.entity.EntityType type) { ++ if (type == net.minecraft.world.entity.EntityType.MINECART) return net.minecraft.world.item.Items.MINECART; ++ else if (type == net.minecraft.world.entity.EntityType.CHEST_MINECART) return net.minecraft.world.item.Items.CHEST_MINECART; ++ else if (type == net.minecraft.world.entity.EntityType.FURNACE_MINECART) return net.minecraft.world.item.Items.FURNACE_MINECART; ++ else if (type == net.minecraft.world.entity.EntityType.SPAWNER_MINECART) return net.minecraft.world.item.Items.MINECART; ++ else if (type == net.minecraft.world.entity.EntityType.COMMAND_BLOCK_MINECART) return net.minecraft.world.item.Items.COMMAND_BLOCK_MINECART; ++ else if (type == net.minecraft.world.entity.EntityType.HOPPER_MINECART) return net.minecraft.world.item.Items.HOPPER_MINECART; ++ else if (type == net.minecraft.world.entity.EntityType.TNT_MINECART) return net.minecraft.world.item.Items.TNT_MINECART; ++ else throw new UnsupportedOperationException("Server implementation is missing minecart material binding for entity type " + type.toShortString()); + } + // Paper end + diff --git a/patches/server/0453-Zombie-API-breaking-doors.patch b/patches/server/0453-Zombie-API-breaking-doors.patch index 50bb6965cf53..b0741f110fdc 100644 --- a/patches/server/0453-Zombie-API-breaking-doors.patch +++ b/patches/server/0453-Zombie-API-breaking-doors.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Zombie API - breaking doors public net.minecraft.world.entity.monster.Zombie supportsBreakDoorGoal()Z diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java -index 4412c913123f7521f449c98b60378e8d3b1671ce..46336111dcf62a29390e724b1879c84c697076e9 100644 +index 4412c913123f7521f449c98b60378e8d3b1671ce..dfc2b40e20069705f92d86a6898e3e8348bf4dcd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java @@ -122,6 +122,11 @@ public class CraftZombie extends CraftMonster implements Zombie { @@ -17,7 +17,7 @@ index 4412c913123f7521f449c98b60378e8d3b1671ce..46336111dcf62a29390e724b1879c84c + + @Override + public boolean supportsBreakingDoors() { -+ return getHandle().supportsBreakDoorGoal(); ++ return true; // All zombies are now capable of breaking doors, see https://bugs.mojang.com/browse/MC-137053 + } // Paper end diff --git a/patches/server/0469-Collision-option-for-requiring-a-player-participant.patch b/patches/server/0469-Collision-option-for-requiring-a-player-participant.patch index 251c412a50b9..a3eef4b0344f 100644 --- a/patches/server/0469-Collision-option-for-requiring-a-player-participant.patch +++ b/patches/server/0469-Collision-option-for-requiring-a-player-participant.patch @@ -17,7 +17,7 @@ index be547b0ef3b91da97fbc270cc00d922ba9c5896e..07aff05e2e8cd36ebb6b9fb9d2f19b95 double d1 = entity.getZ() - this.getZ(); double d2 = Mth.absMax(d0, d1); diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java -index a4eab65c280e493889621e62d8fc94158b930c96..57ea01469ddd180a0c2121cce2807bcccf93bf48 100644 +index a9661ab34bc98c19d525eb4b60b1f0d05d73241e..3590f4bc1af829cdb6e0cfdc8fa6857197b9219e 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java @@ -196,6 +196,7 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable { diff --git a/patches/server/0493-Add-recipe-to-cook-events.patch b/patches/server/0493-Add-recipe-to-cook-events.patch index 737ce3caf898..db11d30abcbc 100644 --- a/patches/server/0493-Add-recipe-to-cook-events.patch +++ b/patches/server/0493-Add-recipe-to-cook-events.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add recipe to cook events diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index b9dd5f710533b156311cac2c020fd0d5f64b6265..2ec1c00eb77051c622fedec1ebeba2953886ace4 100644 +index 187f380eae3948eb5e37e8703db6ea785aaf833d..08b94e5e31ca835c1f9eaefbab07076c91deadeb 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java @@ -332,7 +332,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit diff --git a/patches/server/0507-add-consumeFuel-to-FurnaceBurnEvent.patch b/patches/server/0507-add-consumeFuel-to-FurnaceBurnEvent.patch index 7beadf8d5ca8..5b664856f408 100644 --- a/patches/server/0507-add-consumeFuel-to-FurnaceBurnEvent.patch +++ b/patches/server/0507-add-consumeFuel-to-FurnaceBurnEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] add consumeFuel to FurnaceBurnEvent diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index 2ec1c00eb77051c622fedec1ebeba2953886ace4..a23a87da259ab8d28dd8d8513098cd0730e72e0c 100644 +index 08b94e5e31ca835c1f9eaefbab07076c91deadeb..9c1267df7057caa3500c7a9e6c705ea58c2b5e11 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java @@ -255,7 +255,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit diff --git a/patches/server/0638-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch b/patches/server/0638-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch index 026f79354172..cfaa29570688 100644 --- a/patches/server/0638-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch +++ b/patches/server/0638-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch @@ -5,24 +5,25 @@ Subject: [PATCH] Expose isFuel and canSmelt methods to FurnaceInventory diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java -index 29a8cd7667860c4598a556e6ef3af39c731683db..bd370f5c856d75b7210ef26036aedaa859c570be 100644 +index 29a8cd7667860c4598a556e6ef3af39c731683db..33c970b467675429ad952925830ed334632fd3b6 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java -@@ -40,6 +40,20 @@ public class CraftInventoryFurnace extends CraftInventory implements FurnaceInve +@@ -40,6 +40,21 @@ public class CraftInventoryFurnace extends CraftInventory implements FurnaceInve this.setItem(0, stack); } + // Paper start + @Override + public boolean isFuel(ItemStack stack) { -+ return stack != null && !stack.getType().isEmpty() && AbstractFurnaceBlockEntity.isFuel(CraftItemStack.asNMSCopy(stack)); ++ net.minecraft.server.level.ServerLevel world = ((org.bukkit.craftbukkit.CraftWorld) org.bukkit.Bukkit.getWorlds().get(0)).getHandle(); ++ return stack != null && !stack.getType().isEmpty() && world.fuelValues().isFuel(CraftItemStack.asNMSCopy(stack)); + } + + @Override + public boolean canSmelt(ItemStack stack) { + // data packs are always loaded in the main world + net.minecraft.server.level.ServerLevel world = ((org.bukkit.craftbukkit.CraftWorld) org.bukkit.Bukkit.getWorlds().get(0)).getHandle(); -+ return stack != null && !stack.getType().isEmpty() && world.getRecipeManager().getRecipeFor(((AbstractFurnaceBlockEntity) this.inventory).recipeType, new net.minecraft.world.item.crafting.SingleRecipeInput(CraftItemStack.asNMSCopy(stack)), world).isPresent(); ++ return stack != null && !stack.getType().isEmpty() && world.recipeAccess().getRecipeFor(((AbstractFurnaceBlockEntity) this.inventory).recipeType, new net.minecraft.world.item.crafting.SingleRecipeInput(CraftItemStack.asNMSCopy(stack)), world).isPresent(); + } + // Paper end + diff --git a/patches/server/0660-Furnace-RecipesUsed-API.patch b/patches/server/0660-Furnace-RecipesUsed-API.patch index 53a44cadbfa6..5b19cd68c049 100644 --- a/patches/server/0660-Furnace-RecipesUsed-API.patch +++ b/patches/server/0660-Furnace-RecipesUsed-API.patch @@ -5,39 +5,39 @@ Subject: [PATCH] Furnace RecipesUsed API diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java -index 0ec30feb68efc1747e489ee4bb60e6a503cb31c4..e39fe3c848657bb75ffa510926c5d9109e523db9 100644 +index 7b5f35779ac63b5f9b3a88cc4dcde38147fea2b7..e8d57a9497d545a84955eb3d0240844ae8276c08 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java @@ -103,5 +103,37 @@ public abstract class CraftFurnace extends snapshot.cookSpeedMultiplier = multiplier; - snapshot.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.isPlaced() ? this.world.getHandle() : null, snapshot.recipeType, snapshot, snapshot.cookSpeedMultiplier); // Update the snapshot's current total cook time to scale with the newly set multiplier + snapshot.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.isPlaced() ? this.world.getHandle() : null, snapshot, snapshot.recipeType, snapshot.cookSpeedMultiplier); // Update the snapshot's current total cook time to scale with the newly set multiplier } + + @Override + public int getRecipeUsedCount(org.bukkit.NamespacedKey furnaceRecipe) { -+ return this.getSnapshot().getRecipesUsed().getInt(org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(furnaceRecipe)); ++ return this.getSnapshot().recipesUsed.getInt(io.papermc.paper.util.MCUtil.toResourceKey(net.minecraft.core.registries.Registries.RECIPE, furnaceRecipe)); + } + + @Override + public boolean hasRecipeUsedCount(org.bukkit.NamespacedKey furnaceRecipe) { -+ return this.getSnapshot().getRecipesUsed().containsKey(org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(furnaceRecipe)); ++ return this.getSnapshot().recipesUsed.containsKey(io.papermc.paper.util.MCUtil.toResourceKey(net.minecraft.core.registries.Registries.RECIPE, furnaceRecipe)); + } + + @Override + public void setRecipeUsedCount(org.bukkit.inventory.CookingRecipe furnaceRecipe, int count) { -+ final net.minecraft.resources.ResourceLocation location = org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(furnaceRecipe.getKey()); -+ java.util.Optional> nmsRecipe = (this.isPlaced() ? this.world.getHandle().getRecipeManager() : net.minecraft.server.MinecraftServer.getServer().getRecipeManager()).byKey(location); ++ final var location = io.papermc.paper.util.MCUtil.toResourceKey(net.minecraft.core.registries.Registries.RECIPE, furnaceRecipe.getKey()); ++ java.util.Optional> nmsRecipe = (this.isPlaced() ? this.world.getHandle().recipeAccess() : net.minecraft.server.MinecraftServer.getServer().getRecipeManager()).byKey(location); + com.google.common.base.Preconditions.checkArgument(nmsRecipe.isPresent() && nmsRecipe.get().value() instanceof net.minecraft.world.item.crafting.AbstractCookingRecipe, furnaceRecipe.getKey() + " is not recognized as a valid and registered furnace recipe"); + if (count > 0) { -+ this.getSnapshot().getRecipesUsed().put(location, count); ++ this.getSnapshot().recipesUsed.put(location, count); + } else { -+ this.getSnapshot().getRecipesUsed().removeInt(location); ++ this.getSnapshot().recipesUsed.removeInt(location); + } + } + + @Override + public void setRecipesUsed(java.util.Map, Integer> recipesUsed) { -+ this.getSnapshot().getRecipesUsed().clear(); ++ this.getSnapshot().recipesUsed.clear(); + recipesUsed.forEach((recipe, integer) -> { + if (integer != null) { + this.setRecipeUsedCount(recipe, integer); diff --git a/patches/server/0670-More-Projectile-API.patch b/patches/server/0670-More-Projectile-API.patch index b019ac7bd3ee..9f9c1e0dd46d 100644 --- a/patches/server/0670-More-Projectile-API.patch +++ b/patches/server/0670-More-Projectile-API.patch @@ -17,6 +17,7 @@ public net.minecraft.world.entity.projectile.ThrownTrident dealtDamage public net.minecraft.world.entity.projectile.Arrow NO_EFFECT_COLOR public net.minecraft.world.entity.projectile.Projectile hasBeenShot public net.minecraft.world.entity.projectile.Projectile leftOwner +public net.minecraft.world.entity.projectile.Projectile ownerUUID public net.minecraft.world.entity.projectile.Projectile preOnHit(Lnet/minecraft/world/phys/HitResult;)V public net.minecraft.world.entity.projectile.Projectile canHitEntity(Lnet/minecraft/world/entity/Entity;)Z public net.minecraft.world.entity.projectile.FireworkRocketEntity getDefaultItem()Lnet/minecraft/world/item/ItemStack; @@ -53,7 +54,7 @@ index 536196a740f607adda2a5ae7f644981ac26bef98..1f95234c0a1457050574aa0f6c4b2a8c public boolean calculateOpenWater(BlockPos pos) { FishingHook.OpenWaterType entityfishinghook_waterposition = FishingHook.OpenWaterType.INVALID; diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 2cb77d0b6e6ba880a2a76488a870a20ed883b15a..846a108af8bacdcaf3a17db9fb808965ce2581bb 100644 +index 09d1131c7f2b32b6c032341a60521608b098c109..824090367e833c57a22c1017981f0508b28a35d2 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -288,7 +288,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/0729-Stop-large-look-changes-from-crashing-the-server.patch b/patches/server/0729-Stop-large-look-changes-from-crashing-the-server.patch index 7c262a4f87d8..712c23490359 100644 --- a/patches/server/0729-Stop-large-look-changes-from-crashing-the-server.patch +++ b/patches/server/0729-Stop-large-look-changes-from-crashing-the-server.patch @@ -54,7 +54,7 @@ index d41c0f1aa501cbe17c88029bafbe034901f6d562..7705c791bfbb386f0b9f326c4b0ee005 gameprofilerfiller.pop(); this.animStep += f2; diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 846a108af8bacdcaf3a17db9fb808965ce2581bb..4d487090a622d280bdfacc18978929c61f74f147 100644 +index 824090367e833c57a22c1017981f0508b28a35d2..df0417f27bbf0f18f007746afe24fab48e2a0a08 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -428,13 +428,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch b/patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch index 0de43bc77c23..52154e4e5a35 100644 --- a/patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch +++ b/patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch @@ -297,7 +297,7 @@ index 7dd6b7c0ea472cfbc7ece55bc64bc5d85be4a6c0..6dcb571e9f35fbae724be69dc113b0c3 entity.clearFire(); } diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index a23a87da259ab8d28dd8d8513098cd0730e72e0c..18f8b2c469feef659437684ce156a79ec3a3ce83 100644 +index 9c1267df7057caa3500c7a9e6c705ea58c2b5e11..4d36aa195332c2ff6fa7bc5fff61ff7dc80a3fd5 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java @@ -531,13 +531,10 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit diff --git a/patches/server/0796-Add-Shearable-API.patch b/patches/server/0796-Add-Shearable-API.patch index 5d99e92e0b75..302cec90c208 100644 --- a/patches/server/0796-Add-Shearable-API.patch +++ b/patches/server/0796-Add-Shearable-API.patch @@ -6,15 +6,18 @@ Subject: [PATCH] Add Shearable API diff --git a/src/main/java/io/papermc/paper/entity/PaperShearable.java b/src/main/java/io/papermc/paper/entity/PaperShearable.java new file mode 100644 -index 0000000000000000000000000000000000000000..bcf254e3c81cf1e401bddc850fb24ad29dcc127c +index 0000000000000000000000000000000000000000..b02e2f2ea4f83615897cb4c66be8b29948097815 --- /dev/null +++ b/src/main/java/io/papermc/paper/entity/PaperShearable.java -@@ -0,0 +1,21 @@ +@@ -0,0 +1,25 @@ +package io.papermc.paper.entity; + +import io.papermc.paper.adventure.PaperAdventure; +import net.kyori.adventure.sound.Sound; ++import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Shearable; ++import net.minecraft.world.item.ItemStack; ++import net.minecraft.world.item.Items; +import org.jetbrains.annotations.NotNull; + +public interface PaperShearable extends io.papermc.paper.entity.Shearable { @@ -28,9 +31,20 @@ index 0000000000000000000000000000000000000000..bcf254e3c81cf1e401bddc850fb24ad2 + + @Override + default void shear(@NotNull Sound.Source source) { -+ this.getHandle().shear(PaperAdventure.asVanilla(source)); ++ if (!(this.getHandle().level() instanceof final ServerLevel serverLevel)) return; ++ this.getHandle().shear(serverLevel, PaperAdventure.asVanilla(source), new ItemStack(Items.SHEARS)); + } +} +diff --git a/src/main/java/net/minecraft/world/entity/Shearable.java b/src/main/java/net/minecraft/world/entity/Shearable.java +index a3095eee48d8b87a35ad35da9c8a2a9ca20c92bc..35076593f3ccd651295ae1fc9bcf8256c19672dd 100644 +--- a/src/main/java/net/minecraft/world/entity/Shearable.java ++++ b/src/main/java/net/minecraft/world/entity/Shearable.java +@@ -8,4 +8,5 @@ public interface Shearable { + void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears); + + boolean readyForShearing(); ++ net.minecraft.world.level.Level level(); // Shearable API - expose default level needed for shearing. + } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBogged.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBogged.java index 0139e85c0751564bb4d2847b7b2e48f75fee9e53..e8e4704304504e69c7964dcd4df8ce5db9e92bf6 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBogged.java diff --git a/patches/server/0798-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch b/patches/server/0798-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch index 05a14ce9774b..72035f8c0e63 100644 --- a/patches/server/0798-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch +++ b/patches/server/0798-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Fix crash relating to bad recipes in furnace-like tile diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index 18f8b2c469feef659437684ce156a79ec3a3ce83..ecb9abc570ef87541184a8033cb33c82a4d1daf2 100644 +index 4d36aa195332c2ff6fa7bc5fff61ff7dc80a3fd5..b1067a3add5dc0cfa853b02b5b556d6d67e2932a 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java @@ -499,6 +499,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit diff --git a/patches/server/0810-Refresh-ProjectileSource-for-projectiles.patch b/patches/server/0810-Refresh-ProjectileSource-for-projectiles.patch index 1cac178f6bdc..b44397440aec 100644 --- a/patches/server/0810-Refresh-ProjectileSource-for-projectiles.patch +++ b/patches/server/0810-Refresh-ProjectileSource-for-projectiles.patch @@ -26,7 +26,7 @@ index 6c4171aa43afa679946c8d8a08445bf5741aba8e..ebd2bf1c16833ea8157bc3e3ef1f5730 public boolean lastDamageCancelled; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled public boolean persistentInvisibility = false; diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 4d487090a622d280bdfacc18978929c61f74f147..3982b32cf69250ebd138eff225b65313f75286ea 100644 +index df0417f27bbf0f18f007746afe24fab48e2a0a08..1a45fca020f5ecee7af837af01b60ed4590b845a 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -63,17 +63,35 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/0857-Fix-NPE-on-Boat-getStatus.patch b/patches/server/0857-Fix-NPE-on-Boat-getStatus.patch index 8ec449ba6c89..19f832054de0 100644 --- a/patches/server/0857-Fix-NPE-on-Boat-getStatus.patch +++ b/patches/server/0857-Fix-NPE-on-Boat-getStatus.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Fix NPE on Boat getStatus Boat status is null until the entity is added to the world and the tick() method is called. == AT == -public net.minecraft.world.entity.vehicle.Boat getStatus()Lnet/minecraft/world/entity/vehicle/Boat$Status; +public net.minecraft.world.entity.vehicle.AbstractBoat getStatus()Lnet/minecraft/world/entity/vehicle/AbstractBoat$Status; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java -index 5d51a49228eaee94f91cd04843e27c7918ca8796..8e9d382693047ed202e9b7cafb934700fd830827 100644 +index 5d51a49228eaee94f91cd04843e27c7918ca8796..ff82dc98478a8ac564bdbf4ec58da612e5f6c2ce 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java @@ -87,6 +87,17 @@ public abstract class CraftBoat extends CraftVehicle implements Boat { @@ -17,7 +17,7 @@ index 5d51a49228eaee94f91cd04843e27c7918ca8796..8e9d382693047ed202e9b7cafb934700 @Override public Status getStatus() { + // Paper start - Fix NPE on Boat getStatus -+ final net.minecraft.world.entity.vehicle.Boat handle = this.getHandle(); ++ final net.minecraft.world.entity.vehicle.AbstractBoat handle = this.getHandle(); + if (handle.status == null) { + if (handle.valid) { + // Don't actually set the status because it would skew the old status check in the next tick diff --git a/patches/server/0908-Add-drops-to-shear-events.patch b/patches/server/0908-Add-drops-to-shear-events.patch index d09a2508e859..899419ccb631 100644 --- a/patches/server/0908-Add-drops-to-shear-events.patch +++ b/patches/server/0908-Add-drops-to-shear-events.patch @@ -26,10 +26,10 @@ index 9b5a1dc958232e4c2c9631f3504edc6383afd92a..f5206e4176f58cff4cfe70c94f014afe return true; } diff --git a/src/main/java/net/minecraft/world/entity/Shearable.java b/src/main/java/net/minecraft/world/entity/Shearable.java -index a3095eee48d8b87a35ad35da9c8a2a9ca20c92bc..88dcde6c901753d002a99333eb646bda17122c95 100644 +index 35076593f3ccd651295ae1fc9bcf8256c19672dd..8fda407c9fbfdde623564a7d9607275c4894b744 100644 --- a/src/main/java/net/minecraft/world/entity/Shearable.java +++ b/src/main/java/net/minecraft/world/entity/Shearable.java -@@ -5,7 +5,13 @@ import net.minecraft.sounds.SoundSource; +@@ -5,8 +5,15 @@ import net.minecraft.sounds.SoundSource; import net.minecraft.world.item.ItemStack; public interface Shearable { @@ -37,6 +37,8 @@ index a3095eee48d8b87a35ad35da9c8a2a9ca20c92bc..88dcde6c901753d002a99333eb646bda void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears); boolean readyForShearing(); + net.minecraft.world.level.Level level(); // Shearable API - expose default level needed for shearing. ++ + // Paper start - custom shear drops; ensure all implementing entities override this + default java.util.List generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) { + return java.util.Collections.emptyList(); diff --git a/patches/server/0910-Validate-ResourceLocation-in-NBT-reading.patch b/patches/server/0910-Validate-ResourceLocation-in-NBT-reading.patch index 75089641a980..ae571f6c51f0 100644 --- a/patches/server/0910-Validate-ResourceLocation-in-NBT-reading.patch +++ b/patches/server/0910-Validate-ResourceLocation-in-NBT-reading.patch @@ -142,7 +142,7 @@ index 874a44ab77248665c2db243764e8542bfc0d6514..cc7826a10f22e3307231d887db2fee98 if (this.getContainerLootTable() != null) { this.lootableData().loadNbt(nbt); diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index ecb9abc570ef87541184a8033cb33c82a4d1daf2..a1ac34668fcd53cf8adf4ce463e0254b26575fbf 100644 +index b1067a3add5dc0cfa853b02b5b556d6d67e2932a..15e0861486a2bda3e2f4049b1b5a299c870acd31 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java @@ -180,7 +180,11 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit diff --git a/patches/server/0990-Check-distance-in-entity-interactions.patch b/patches/server/0990-Check-distance-in-entity-interactions.patch index 8fe3898ba0cb..f8d61a567e41 100644 --- a/patches/server/0990-Check-distance-in-entity-interactions.patch +++ b/patches/server/0990-Check-distance-in-entity-interactions.patch @@ -54,7 +54,7 @@ index 4f6a9c9a1a9fa0f98ee2c3bfdc4c5b3202c5cdd0..52ca53b4795981080476fa9425e01f2c } } diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java -index 57ea01469ddd180a0c2121cce2807bcccf93bf48..b8d231225a9f5c2e6af1727d15c8819adbc13cba 100644 +index 3590f4bc1af829cdb6e0cfdc8fa6857197b9219e..1fdbef16cd29c8fc74578ac3328f985eca61088d 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java @@ -674,7 +674,7 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable { diff --git a/patches/server/1005-Fix-PickupStatus-getting-reset.patch b/patches/server/1005-Fix-PickupStatus-getting-reset.patch index c731057978b0..4f8f62e8bc2e 100644 --- a/patches/server/1005-Fix-PickupStatus-getting-reset.patch +++ b/patches/server/1005-Fix-PickupStatus-getting-reset.patch @@ -24,7 +24,7 @@ index 14e31ae88e90d8ea1a98800cc6c1c3527bb2ed6b..accc246f441c8bf5e1a755cfc0db8f97 byte b0 = 0; diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 3982b32cf69250ebd138eff225b65313f75286ea..03c1bffd3125bb7a82ac921b0a23dcab55c33c4f 100644 +index 1a45fca020f5ecee7af837af01b60ed4590b845a..49c0f09f91f9ea2428fd3b13b00c99073074beba 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -353,7 +353,13 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/1011-Leashable-API.patch b/patches/server/1011-Leashable-API.patch index d54784d18cdd..f3cf7dc395ed 100644 --- a/patches/server/1011-Leashable-API.patch +++ b/patches/server/1011-Leashable-API.patch @@ -61,7 +61,7 @@ index 0000000000000000000000000000000000000000..a9ddf9a4a07cd29833f38d7e5f42b2b1 + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java -index 8e9d382693047ed202e9b7cafb934700fd830827..2173963bbbb4c76b89996c857a36d81d8b2d79ea 100644 +index ff82dc98478a8ac564bdbf4ec58da612e5f6c2ce..2a2839c31989d127739d829159a8b6e5b9a5210b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java @@ -8,7 +8,7 @@ import org.bukkit.craftbukkit.CraftServer; From 0a8fd78e37d7204c81a62252a412c9c7054092ea Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Fri, 25 Oct 2024 18:08:28 +0200 Subject: [PATCH 056/119] Compiler issue v5 --- patches/server/0005-Paper-config-files.patch | 22 +++++++++---------- patches/server/0010-Adventure.patch | 22 +++++++++++-------- ...oleAppender-for-console-improvements.patch | 2 +- ...3-Ability-to-apply-mending-to-XP-API.patch | 8 +++---- .../0176-Player.setPlayerProfile-API.patch | 2 +- ...81-Flag-to-disable-the-channel-limit.patch | 2 +- .../0207-InventoryCloseEvent-Reason-API.patch | 2 +- .../server/0218-Expand-ArmorStand-API.patch | 4 ++-- ...e-attack-cooldown-methods-for-Player.patch | 2 +- .../server/0241-Improve-death-events.patch | 2 +- ...-Replace-OfflinePlayer-getLastPlayed.patch | 2 +- ...r-remove-if-the-handle-is-a-custom-p.patch | 2 +- ...-Implement-Player-Client-Options-API.patch | 2 +- .../server/0371-Paper-dumpitem-command.patch | 4 ++-- patches/server/0389-Brand-support.patch | 2 +- ...r-spawnParticle-x-y-z-precision-loss.patch | 2 +- patches/server/0466-Add-sendOpLevel-API.patch | 2 +- ...527-Expand-PlayerGameModeChangeEvent.patch | 2 +- .../0539-Add-PlayerKickEvent-causes.patch | 2 +- .../server/0566-Add-PlayerSetSpawnEvent.patch | 2 +- ...ulti-Block-Change-API-Implementation.patch | 2 +- patches/server/0658-Add-GameEvent-tags.patch | 4 ++-- ...-Expose-furnace-minecart-push-values.patch | 14 +++++++----- patches/server/0716-More-Teleport-API.patch | 8 ++++--- ...stom-Chat-Completion-Suggestions-API.patch | 2 +- .../0746-Elder-Guardian-appearance-API.patch | 4 ++-- .../0758-Add-Player-Warden-Warning-API.patch | 4 ++-- patches/server/0770-fix-Instruments.patch | 2 +- patches/server/0779-Flying-Fall-Damage.patch | 4 ++-- patches/server/0784-Win-Screen-API.patch | 2 +- ...ectly-handle-ArmorStand-invisibility.patch | 2 +- .../0809-Expand-PlayerItemMendEvent.patch | 4 ++-- patches/server/0828-Fix-BanList-API.patch | 6 ++--- .../server/0846-Bandaid-fix-for-Effect.patch | 2 +- .../0854-Add-Listing-API-for-Player.patch | 6 ++--- ...-Implement-OfflinePlayer-isConnected.patch | 2 +- .../0884-Add-player-idle-duration-API.patch | 4 ++-- ...stack-for-Player-sendEquipmentChange.patch | 2 +- .../0907-Add-experience-points-API.patch | 4 ++-- ...d-API-to-get-player-ha-proxy-address.patch | 2 +- patches/server/1020-Add-FeatureFlag-API.patch | 10 +++++---- .../1028-Improve-entity-effect-API.patch | 4 ++-- 42 files changed, 97 insertions(+), 87 deletions(-) diff --git a/patches/server/0005-Paper-config-files.patch b/patches/server/0005-Paper-config-files.patch index eb69aa8d12b0..553c9188755f 100644 --- a/patches/server/0005-Paper-config-files.patch +++ b/patches/server/0005-Paper-config-files.patch @@ -3140,7 +3140,7 @@ index 0000000000000000000000000000000000000000..36ca88b677e1b55b41c52750948d5b6d +} diff --git a/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryEntrySerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryEntrySerializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..9073c619f14feb7a14bf32a504eb935f6d4cfe2e +index 0000000000000000000000000000000000000000..cb0de1a639578320fd38177a915bfa5d1e9a73bd --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryEntrySerializer.java @@ -0,0 +1,64 @@ @@ -3178,7 +3178,7 @@ index 0000000000000000000000000000000000000000..9073c619f14feb7a14bf32a504eb935f + } + + protected final Registry registry() { -+ return this.registryAccess.registryOrThrow(this.registryKey); ++ return this.registryAccess.lookupOrThrow(this.registryKey); + } + + protected abstract T convertFromResourceKey(ResourceKey key) throws SerializationException; @@ -3210,7 +3210,7 @@ index 0000000000000000000000000000000000000000..9073c619f14feb7a14bf32a504eb935f +} diff --git a/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryHolderSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryHolderSerializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..eeae35ede747e473ddba4ca1688f2f6cbc35ce7d +index 0000000000000000000000000000000000000000..76f6219eac049afef7ce03cd30d7c3232b5b9b7c --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryHolderSerializer.java @@ -0,0 +1,34 @@ @@ -3240,7 +3240,7 @@ index 0000000000000000000000000000000000000000..eeae35ede747e473ddba4ca1688f2f6c + + @Override + protected Holder convertFromResourceKey(ResourceKey key) throws SerializationException { -+ return this.registry().getHolder(key).orElseThrow(() -> new SerializationException("Missing holder in " + this.registry().key() + " with key " + key)); ++ return this.registry().get(key).orElseThrow(() -> new SerializationException("Missing holder in " + this.registry().key() + " with key " + key)); + } + + @Override @@ -3250,7 +3250,7 @@ index 0000000000000000000000000000000000000000..eeae35ede747e473ddba4ca1688f2f6c +} diff --git a/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryValueSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryValueSerializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..718377ce91a010a48b2b4a5e59e02ee8a42107a7 +index 0000000000000000000000000000000000000000..6831b7b72c5e1f79eff36019ca2ff56531c26df8 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryValueSerializer.java @@ -0,0 +1,35 @@ @@ -3277,7 +3277,7 @@ index 0000000000000000000000000000000000000000..718377ce91a010a48b2b4a5e59e02ee8 + + @Override + protected T convertFromResourceKey(ResourceKey key) throws SerializationException { -+ final T value = this.registry().get(key); ++ final T value = this.registry().getValue(key); + if (value == null) { + throw new SerializationException("Missing value in " + this.registry() + " with key " + key.location()); + } @@ -3617,7 +3617,7 @@ index 0000000000000000000000000000000000000000..66073f7a6a96405348cc4044ad1e6922 +} diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/FeatureSeedsGeneration.java b/src/main/java/io/papermc/paper/configuration/transformation/world/FeatureSeedsGeneration.java new file mode 100644 -index 0000000000000000000000000000000000000000..6cdc40cb4a5f94654c874f9dbdb106fa0e4d41f3 +index 0000000000000000000000000000000000000000..cb1f5f65c098470dc8553b015d0f0f29f28ed956 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/transformation/world/FeatureSeedsGeneration.java @@ -0,0 +1,71 @@ @@ -3668,7 +3668,7 @@ index 0000000000000000000000000000000000000000..6cdc40cb4a5f94654c874f9dbdb106fa + final Reference2LongMap>> features = Objects.requireNonNullElseGet(featureNode.get(new TypeToken>>>() {}), Reference2LongOpenHashMap::new); + final Random random = new SecureRandom(); + AtomicInteger counter = new AtomicInteger(0); -+ MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).holders().forEach(holder -> { ++ MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.CONFIGURED_FEATURE).listElements().forEach(holder -> { + if (features.containsKey(holder)) { + return; + } @@ -3694,7 +3694,7 @@ index 0000000000000000000000000000000000000000..6cdc40cb4a5f94654c874f9dbdb106fa +} diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/LegacyPaperWorldConfig.java b/src/main/java/io/papermc/paper/configuration/transformation/world/LegacyPaperWorldConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..3332531d902899a156179ef2e9ec85b2f42c1fd1 +index 0000000000000000000000000000000000000000..77e530830dc8ebc861b2e70f787f9b71524a54d2 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/transformation/world/LegacyPaperWorldConfig.java @@ -0,0 +1,322 @@ @@ -3805,7 +3805,7 @@ index 0000000000000000000000000000000000000000..3332531d902899a156179ef2e9ec85b2 + ) + .addVersion(26, ConfigurationTransformation.builder().addAction(path("alt-item-despawn-rate", "items", ConfigurationTransformation.WILDCARD_OBJECT), (path, value) -> { + String itemName = path.get(path.size() - 1).toString(); -+ final Optional> item = BuiltInRegistries.ITEM.getHolder(ResourceKey.create(Registries.ITEM, ResourceLocation.parse(itemName.toLowerCase(Locale.ROOT)))); ++ final Optional> item = BuiltInRegistries.ITEM.get(ResourceKey.create(Registries.ITEM, ResourceLocation.parse(itemName.toLowerCase(Locale.ROOT)))); + if (item.isEmpty()) { + itemName = Material.valueOf(itemName).getKey().getKey(); + } @@ -3837,7 +3837,7 @@ index 0000000000000000000000000000000000000000..3332531d902899a156179ef2e9ec85b2 + Map rebuild = new HashMap<>(); + value.childrenMap().forEach((key, node) -> { + String itemName = key.toString(); -+ final Optional> itemHolder = BuiltInRegistries.ITEM.getHolder(ResourceKey.create(Registries.ITEM, ResourceLocation.parse(itemName.toLowerCase(Locale.ROOT)))); ++ final Optional> itemHolder = BuiltInRegistries.ITEM.get(ResourceKey.create(Registries.ITEM, ResourceLocation.parse(itemName.toLowerCase(Locale.ROOT)))); + final @Nullable String item; + if (itemHolder.isEmpty()) { + final @Nullable Material bukkitMat = Material.matchMaterial(itemName); diff --git a/patches/server/0010-Adventure.patch b/patches/server/0010-Adventure.patch index 812a9e1167cb..a8d9cacd7474 100644 --- a/patches/server/0010-Adventure.patch +++ b/patches/server/0010-Adventure.patch @@ -14,10 +14,10 @@ Co-authored-by: Jake Potrebic diff --git a/src/main/java/io/papermc/paper/adventure/AdventureCodecs.java b/src/main/java/io/papermc/paper/adventure/AdventureCodecs.java new file mode 100644 -index 0000000000000000000000000000000000000000..8dcedc5f4d4453fd942787dbcb9c757274ec7715 +index 0000000000000000000000000000000000000000..2c5702a42c4a3d8b37deeb26e1bd7fbdcca3554e --- /dev/null +++ b/src/main/java/io/papermc/paper/adventure/AdventureCodecs.java -@@ -0,0 +1,446 @@ +@@ -0,0 +1,450 @@ +package io.papermc.paper.adventure; + +import com.google.gson.JsonElement; @@ -61,6 +61,7 @@ index 0000000000000000000000000000000000000000..8dcedc5f4d4453fd942787dbcb9c7572 +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; ++import net.minecraft.commands.arguments.selector.SelectorPattern; +import net.minecraft.core.UUIDUtil; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.nbt.CompoundTag; @@ -146,7 +147,7 @@ index 0000000000000000000000000000000000000000..8dcedc5f4d4453fd942787dbcb9c7572 + @Subst("key") final String typeKey = isi.item.unwrapKey().orElseThrow().location().toString(); + return HoverEvent.ShowItem.showItem(Key.key(typeKey), isi.count, PaperAdventure.asAdventure(isi.getItemStack().getComponentsPatch())); + }, si -> { -+ final Item itemType = BuiltInRegistries.ITEM.get(PaperAdventure.asVanilla(si.item())); ++ final Item itemType = BuiltInRegistries.ITEM.getValue(PaperAdventure.asVanilla(si.item())); + final Map dataComponentsMap = si.dataComponents(); + final ItemStack stack = new ItemStack(BuiltInRegistries.ITEM.wrapAsHolder(itemType), si.count(), PaperAdventure.asVanilla(dataComponentsMap)); + return new net.minecraft.network.chat.HoverEvent.ItemStackInfo(stack); @@ -315,7 +316,10 @@ index 0000000000000000000000000000000000000000..8dcedc5f4d4453fd942787dbcb9c7572 + }); + + static final MapCodec KEYBIND_COMPONENT_MAP_CODEC = KeybindContents.CODEC.xmap(k -> Component.keybind(k.getName()), k -> new KeybindContents(k.keybind())); -+ static final MapCodec SCORE_COMPONENT_INNER_MAP_CODEC = ScoreContents.INNER_CODEC.xmap(s -> Component.score(s.getName(), s.getObjective()), s -> new ScoreContents(s.name(), s.objective())); ++ static final MapCodec SCORE_COMPONENT_INNER_MAP_CODEC = ScoreContents.INNER_CODEC.xmap( ++ s -> Component.score(s.name().map(SelectorPattern::pattern, Function.identity()), s.objective()), ++ s -> new ScoreContents(SelectorPattern.parse(s.name()).>map(Either::left).result().orElse(Either.right(s.name())), s.objective()) ++ ); // TODO we might want to ask adventure for a nice way we can avoid parsing and flattening the SelectorPattern on every conversion. + static final MapCodec SCORE_COMPONENT_MAP_CODEC = SCORE_COMPONENT_INNER_MAP_CODEC.fieldOf("score"); + static final MapCodec SELECTOR_COMPONENT_MAP_CODEC = mapCodec((instance) -> { + return instance.group( @@ -1157,7 +1161,7 @@ index 0000000000000000000000000000000000000000..2fd6c3e65354071af71c7d8ebb97b559 +} diff --git a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java new file mode 100644 -index 0000000000000000000000000000000000000000..dc4837c577676115f0653acc35f55962a432e425 +index 0000000000000000000000000000000000000000..161bc8c577643094d824ea96fb6974c76e5e77f0 --- /dev/null +++ b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java @@ -0,0 +1,479 @@ @@ -1580,7 +1584,7 @@ index 0000000000000000000000000000000000000000..dc4837c577676115f0653acc35f55962 + } + final DataComponentPatch.Builder builder = DataComponentPatch.builder(); + map.forEach((key, dataComponentValue) -> { -+ final DataComponentType type = requireNonNull(BuiltInRegistries.DATA_COMPONENT_TYPE.get(asVanilla(key))); ++ final DataComponentType type = requireNonNull(BuiltInRegistries.DATA_COMPONENT_TYPE.getValue(asVanilla(key))); + if (dataComponentValue instanceof DataComponentValue.Removed) { + builder.remove(type); + return; @@ -1839,7 +1843,7 @@ index 0000000000000000000000000000000000000000..8323f135d6bf2e1f12525e05094ffa3f +} diff --git a/src/main/java/io/papermc/paper/adventure/providers/DataComponentValueConverterProviderImpl.java b/src/main/java/io/papermc/paper/adventure/providers/DataComponentValueConverterProviderImpl.java new file mode 100644 -index 0000000000000000000000000000000000000000..6b37c0ebda4a0cfcf9c3b2c3483ffababe622555 +index 0000000000000000000000000000000000000000..ee2076fd098ae2164596f39b88f56b3700ed3687 --- /dev/null +++ b/src/main/java/io/papermc/paper/adventure/providers/DataComponentValueConverterProviderImpl.java @@ -0,0 +1,82 @@ @@ -1895,7 +1899,7 @@ index 0000000000000000000000000000000000000000..6b37c0ebda4a0cfcf9c3b2c3483ffaba + GsonDataComponentValue.class, + PaperAdventure.DataComponentValueImpl.class, + (key, dataComponentValue) -> { -+ final @Nullable DataComponentType type = BuiltInRegistries.DATA_COMPONENT_TYPE.get(PaperAdventure.asVanilla(key)); ++ final @Nullable DataComponentType type = BuiltInRegistries.DATA_COMPONENT_TYPE.getValue(PaperAdventure.asVanilla(key)); + if (type == null) { + throw new IllegalArgumentException("Unknown data component type: " + key); + } @@ -1911,7 +1915,7 @@ index 0000000000000000000000000000000000000000..6b37c0ebda4a0cfcf9c3b2c3483ffaba + DataComponentValue.TagSerializable.class, + PaperAdventure.DataComponentValueImpl.class, + (key, tagSerializable) -> { -+ final @Nullable DataComponentType type = BuiltInRegistries.DATA_COMPONENT_TYPE.get(PaperAdventure.asVanilla(key)); ++ final @Nullable DataComponentType type = BuiltInRegistries.DATA_COMPONENT_TYPE.getValue(PaperAdventure.asVanilla(key)); + if (type == null) { + throw new IllegalArgumentException("Unknown data component type: " + key); + } diff --git a/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch b/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch index 0f0dfcc8f8e0..2e40e9d13877 100644 --- a/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch +++ b/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch @@ -216,7 +216,7 @@ index 0000000000000000000000000000000000000000..8f07539a82f449ad217e316a7513a170 + +} diff --git a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java -index dc4837c577676115f0653acc35f55962a432e425..22fe529890f34f66534c01248f654dc911b44c3b 100644 +index 161bc8c577643094d824ea96fb6974c76e5e77f0..cfcaf215c4a901dd2938c7ce41db502c57b42bbf 100644 --- a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java +++ b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java @@ -32,6 +32,7 @@ import net.kyori.adventure.text.flattener.ComponentFlattener; diff --git a/patches/server/0163-Ability-to-apply-mending-to-XP-API.patch b/patches/server/0163-Ability-to-apply-mending-to-XP-API.patch index 7a580a6eb764..590dfbe62799 100644 --- a/patches/server/0163-Ability-to-apply-mending-to-XP-API.patch +++ b/patches/server/0163-Ability-to-apply-mending-to-XP-API.patch @@ -14,7 +14,7 @@ public net.minecraft.world.entity.ExperienceOrb durabilityToXp(I)I public net.minecraft.world.entity.ExperienceOrb xpToDurability(I)I diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 63499a4fa349b3fa61040244db8be2d5d2569b96..d222de793776b0217c8ec0a4a3151d085efa339f 100644 +index 63499a4fa349b3fa61040244db8be2d5d2569b96..128fcd537783986d816dae6d1ce2afb7af07d45a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1665,7 +1665,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -22,7 +22,7 @@ index 63499a4fa349b3fa61040244db8be2d5d2569b96..d222de793776b0217c8ec0a4a3151d08 @Override - public void giveExp(int exp) { -+ // Paper start ++ // Paper start - ability to apply mending + public int applyMending(int amount) { + ServerPlayer handle = this.getHandle(); + // Logic copied from EntityExperienceOrb and remapped to unobfuscated methods/properties @@ -31,7 +31,7 @@ index 63499a4fa349b3fa61040244db8be2d5d2569b96..d222de793776b0217c8ec0a4a3151d08 + .getRandomItemWith(net.minecraft.world.item.enchantment.EnchantmentEffectComponents.REPAIR_WITH_XP, handle, net.minecraft.world.item.ItemStack::isDamaged); + final net.minecraft.world.item.ItemStack itemstack = stackEntry.map(net.minecraft.world.item.enchantment.EnchantedItemInUse::itemStack).orElse(net.minecraft.world.item.ItemStack.EMPTY); + if (!itemstack.isEmpty() && itemstack.getItem().components().has(net.minecraft.core.component.DataComponents.MAX_DAMAGE)) { -+ net.minecraft.world.entity.ExperienceOrb orb = net.minecraft.world.entity.EntityType.EXPERIENCE_ORB.create(handle.level()); ++ net.minecraft.world.entity.ExperienceOrb orb = net.minecraft.world.entity.EntityType.EXPERIENCE_ORB.create(handle.level(), net.minecraft.world.entity.EntitySpawnReason.COMMAND); + orb.value = amount; + orb.spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.CUSTOM; + orb.setPosRaw(handle.getX(), handle.getY(), handle.getZ()); @@ -56,7 +56,7 @@ index 63499a4fa349b3fa61040244db8be2d5d2569b96..d222de793776b0217c8ec0a4a3151d08 + if (applyMending) { + exp = this.applyMending(exp); + } -+ // Paper end ++ // Paper end - ability to apply mending this.getHandle().giveExperiencePoints(exp); } diff --git a/patches/server/0176-Player.setPlayerProfile-API.patch b/patches/server/0176-Player.setPlayerProfile-API.patch index a44003c55f7b..4f18504a3fd0 100644 --- a/patches/server/0176-Player.setPlayerProfile-API.patch +++ b/patches/server/0176-Player.setPlayerProfile-API.patch @@ -64,7 +64,7 @@ index 818df09e9245b5d89b4180b1eaa51470b7539341..f6b2ca92fd3510a76cbf56d0ea55aa6c public Server getServer() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index d222de793776b0217c8ec0a4a3151d085efa339f..6191c780cfab682464e23c53873d0acb0c642b0d 100644 +index 128fcd537783986d816dae6d1ce2afb7af07d45a..32eeca2467189c6c97f7da5529d4fe9375e8a848 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -254,11 +254,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0181-Flag-to-disable-the-channel-limit.patch b/patches/server/0181-Flag-to-disable-the-channel-limit.patch index bbb4d826854d..867f7c6540e4 100644 --- a/patches/server/0181-Flag-to-disable-the-channel-limit.patch +++ b/patches/server/0181-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 6191c780cfab682464e23c53873d0acb0c642b0d..afee0dd824cfa229f9ebdbc2b4ca9beee485d6e7 100644 +index 32eeca2467189c6c97f7da5529d4fe9375e8a848..a4333eae8aa2ae3fefdc8a765a4434c36e123b12 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -214,6 +214,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0207-InventoryCloseEvent-Reason-API.patch b/patches/server/0207-InventoryCloseEvent-Reason-API.patch index 335dc0d881e0..d0f2f2b3fcc6 100644 --- a/patches/server/0207-InventoryCloseEvent-Reason-API.patch +++ b/patches/server/0207-InventoryCloseEvent-Reason-API.patch @@ -165,7 +165,7 @@ index 6d4e0a90c70f7a66450cbb18ebec1d7bf9200af2..5ff159be1a6dfb4b1a5b9aa1e435d294 @Override public boolean isBlocking() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index afee0dd824cfa229f9ebdbc2b4ca9beee485d6e7..d1b14e7460bd2974e2c3c49a085968a90e1f410f 100644 +index a4333eae8aa2ae3fefdc8a765a4434c36e123b12..462877cf6f0dce4f86b6a47564affe9beb2559a8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1290,7 +1290,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0218-Expand-ArmorStand-API.patch b/patches/server/0218-Expand-ArmorStand-API.patch index c5c95632422d..8e53f0be90d2 100644 --- a/patches/server/0218-Expand-ArmorStand-API.patch +++ b/patches/server/0218-Expand-ArmorStand-API.patch @@ -14,7 +14,7 @@ public net.minecraft.world.entity.decoration.ArmorStand isDisabled(Lnet/minecraf Co-authored-by: SoSeDiK diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java -index 1bb080a8af45411b68a0f2a3c40718d60fdc9d97..e1cedcb95e9b2e2e9587b623256b5cffa7b08ce4 100644 +index 1bb080a8af45411b68a0f2a3c40718d60fdc9d97..c8713200d946b0fdd74b60d0c2c136c8226389e0 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java @@ -233,6 +233,149 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @@ -72,7 +72,7 @@ index 1bb080a8af45411b68a0f2a3c40718d60fdc9d97..e1cedcb95e9b2e2e9587b623256b5cff + for (org.bukkit.inventory.EquipmentSlot slot : slots) { + if (slot == org.bukkit.inventory.EquipmentSlot.OFF_HAND) continue; + net.minecraft.world.entity.EquipmentSlot nmsSlot = org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot); -+ disabled += (1 << nmsSlot.getFilterFlag()) + (1 << (nmsSlot.getFilterFlag() + 8)) + (1 << (nmsSlot.getFilterFlag() + 16)); ++ disabled += (1 << nmsSlot.getFilterBit(0)) + (1 << nmsSlot.getFilterBit(8)) + (1 << nmsSlot.getFilterBit(16)); + } + getHandle().disabledSlots = disabled; + } diff --git a/patches/server/0240-Expose-attack-cooldown-methods-for-Player.patch b/patches/server/0240-Expose-attack-cooldown-methods-for-Player.patch index 2288caab49f0..348ac73d0c42 100644 --- a/patches/server/0240-Expose-attack-cooldown-methods-for-Player.patch +++ b/patches/server/0240-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 d1b14e7460bd2974e2c3c49a085968a90e1f410f..6fb400243e491bb8492342327fe98127b2df331e 100644 +index 462877cf6f0dce4f86b6a47564affe9beb2559a8..e4d840d6335007a6a542240746504bf1f2af332d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -3007,6 +3007,21 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0241-Improve-death-events.patch b/patches/server/0241-Improve-death-events.patch index 17d781e34a86..642cd86423f1 100644 --- a/patches/server/0241-Improve-death-events.patch +++ b/patches/server/0241-Improve-death-events.patch @@ -420,7 +420,7 @@ index 2caba38a50b7ea535337a3540aa5272d4a9f1878..e20565cf256aacd012a1722c5ebbf901 // CraftBukkit end 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 6fb400243e491bb8492342327fe98127b2df331e..5dab50309b9441ddb3fe66aec653be0246b049d2 100644 +index e4d840d6335007a6a542240746504bf1f2af332d..159bba49095aec77cce5f53d4388a5dff0afcc60 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2544,7 +2544,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0270-Replace-OfflinePlayer-getLastPlayed.patch b/patches/server/0270-Replace-OfflinePlayer-getLastPlayed.patch index 51b5df883293..cc333123381b 100644 --- a/patches/server/0270-Replace-OfflinePlayer-getLastPlayed.patch +++ b/patches/server/0270-Replace-OfflinePlayer-getLastPlayed.patch @@ -106,7 +106,7 @@ index f6b2ca92fd3510a76cbf56d0ea55aa6caaf12ba1..e0d342a0ddd140b342f7af138c71596c 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 5dab50309b9441ddb3fe66aec653be0246b049d2..38989d2e0702e6edba0e81e292b439b7ef48023c 100644 +index 159bba49095aec77cce5f53d4388a5dff0afcc60..f351250b8e8b66bcf72230bbc76835fcb45817e1 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -215,6 +215,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0272-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch b/patches/server/0272-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch index f2bcc599c050..12aeb87aa360 100644 --- a/patches/server/0272-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch +++ b/patches/server/0272-Dont-block-Player-remove-if-the-handle-is-a-custom-p.patch @@ -8,7 +8,7 @@ We just add a check to ensure that the CraftPlayer's handle is a ServerPlayer diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 38989d2e0702e6edba0e81e292b439b7ef48023c..92fb4dfce832f5cb98b476365c060acfd8277183 100644 +index f351250b8e8b66bcf72230bbc76835fcb45817e1..faab55435a0c4fc6ff9d117f29a2401677b9f828 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -229,8 +229,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0337-Implement-Player-Client-Options-API.patch b/patches/server/0337-Implement-Player-Client-Options-API.patch index 1ca74a9891e4..da2d0fcb26f3 100644 --- a/patches/server/0337-Implement-Player-Client-Options-API.patch +++ b/patches/server/0337-Implement-Player-Client-Options-API.patch @@ -136,7 +136,7 @@ index 363175d3325c012f31ba84060bb0bfac694f6ab8..9911e231ad021286f2da90057b06874f this.adventure$locale = java.util.Objects.requireNonNullElse(net.kyori.adventure.translation.Translator.parseLocale(this.language), java.util.Locale.US); // Paper this.requestedViewDistance = clientOptions.viewDistance(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 92fb4dfce832f5cb98b476365c060acfd8277183..330a64edf72dc598fb5458702cf7cae5dd83ab00 100644 +index faab55435a0c4fc6ff9d117f29a2401677b9f828..69108fd869c7c929fd7971abea520d5ab9063f69 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -670,6 +670,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0371-Paper-dumpitem-command.patch b/patches/server/0371-Paper-dumpitem-command.patch index 088efe087c0e..3c8440021538 100644 --- a/patches/server/0371-Paper-dumpitem-command.patch +++ b/patches/server/0371-Paper-dumpitem-command.patch @@ -19,7 +19,7 @@ index 3010d57efcc97fb409bfe43b1fc9af198c099a67..cdad0fd5257ae842f83b9c1c98b4565b .flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue()))) diff --git a/src/main/java/io/papermc/paper/command/subcommands/DumpItemCommand.java b/src/main/java/io/papermc/paper/command/subcommands/DumpItemCommand.java new file mode 100644 -index 0000000000000000000000000000000000000000..e993177b052c76cb3f9c44edb598ebb4be858393 +index 0000000000000000000000000000000000000000..b4b90c1bda72f845756b46e2316d952361989697 --- /dev/null +++ b/src/main/java/io/papermc/paper/command/subcommands/DumpItemCommand.java @@ -0,0 +1,133 @@ @@ -103,7 +103,7 @@ index 0000000000000000000000000000000000000000..e993177b052c76cb3f9c44edb598ebb4 + + final RegistryAccess.Frozen access = ((CraftServer) sender.getServer()).getServer().registryAccess(); + final RegistryOps ops = access.createSerializationContext(NbtOps.INSTANCE); -+ final Registry> registry = access.registryOrThrow(Registries.DATA_COMPONENT_TYPE); ++ final Registry> registry = access.lookupOrThrow(Registries.DATA_COMPONENT_TYPE); + final List componentComponents = new ArrayList<>(); + final List commandComponents = new ArrayList<>(); + for (final DataComponentType type : referencedComponentTypes) { diff --git a/patches/server/0389-Brand-support.patch b/patches/server/0389-Brand-support.patch index 291a5334d53b..917f8102d4c8 100644 --- a/patches/server/0389-Brand-support.patch +++ b/patches/server/0389-Brand-support.patch @@ -57,7 +57,7 @@ index b9fbaddcc8239bf737fdea51790f678306e511eb..9a8b08d4b70b8890961e4af7ce6e870a } catch (Exception ex) { ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t dispatch custom payload", ex); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 330a64edf72dc598fb5458702cf7cae5dd83ab00..3b0e7473b3e0c5d9e9e34ed505eae4823e626aae 100644 +index 69108fd869c7c929fd7971abea520d5ab9063f69..3191c66c9e5b9c5fcfd07716733aaa51612d507f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -3166,6 +3166,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0430-Fix-Player-spawnParticle-x-y-z-precision-loss.patch b/patches/server/0430-Fix-Player-spawnParticle-x-y-z-precision-loss.patch index b8670990f3b5..066a872e128d 100644 --- a/patches/server/0430-Fix-Player-spawnParticle-x-y-z-precision-loss.patch +++ b/patches/server/0430-Fix-Player-spawnParticle-x-y-z-precision-loss.patch @@ -5,7 +5,7 @@ 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 3b0e7473b3e0c5d9e9e34ed505eae4823e626aae..875d96ca1461d254745e53970b401634c07a8dd6 100644 +index 3191c66c9e5b9c5fcfd07716733aaa51612d507f..e7f2d02de2ac58ffa484d8eca5f8b5688e7e02d8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2734,7 +2734,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0466-Add-sendOpLevel-API.patch b/patches/server/0466-Add-sendOpLevel-API.patch index 2a4354226e99..fde6ae317a57 100644 --- a/patches/server/0466-Add-sendOpLevel-API.patch +++ b/patches/server/0466-Add-sendOpLevel-API.patch @@ -32,7 +32,7 @@ index 70b7871091ab9b64d2a5503620a71c3d5585c25d..7676dbe55b4bf6e0472dc0190c01e6ec 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 875d96ca1461d254745e53970b401634c07a8dd6..0ca539a7e037b7f8791ed4c71ce3093a3def2746 100644 +index e7f2d02de2ac58ffa484d8eca5f8b5688e7e02d8..711697d039da58c1b93392f70a70e1ad827b1646 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -694,6 +694,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0527-Expand-PlayerGameModeChangeEvent.patch b/patches/server/0527-Expand-PlayerGameModeChangeEvent.patch index 050751dcc743..aac8a279c58a 100644 --- a/patches/server/0527-Expand-PlayerGameModeChangeEvent.patch +++ b/patches/server/0527-Expand-PlayerGameModeChangeEvent.patch @@ -147,7 +147,7 @@ index e6a927e991779bad84a02d81010057a4e36b9c95..9007a0f01b823c613c39c974d9e0f585 } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 0ca539a7e037b7f8791ed4c71ce3093a3def2746..8551d626fd4eb38f57414d022f752c0a389a1095 100644 +index 711697d039da58c1b93392f70a70e1ad827b1646..fc246d30808ad6242f4adfe201adc169a2ddeb90 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1681,7 +1681,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0539-Add-PlayerKickEvent-causes.patch b/patches/server/0539-Add-PlayerKickEvent-causes.patch index d11448420fb3..04617f2c411b 100644 --- a/patches/server/0539-Add-PlayerKickEvent-causes.patch +++ b/patches/server/0539-Add-PlayerKickEvent-causes.patch @@ -495,7 +495,7 @@ index 9e2ad78b12cadbf0e2bda1e12fe844120529c347..6a7d7fad990fc44fdda6849d43dad141 } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 8551d626fd4eb38f57414d022f752c0a389a1095..f0f8238aeb49c45921c7ec48cc49ed628087741f 100644 +index fc246d30808ad6242f4adfe201adc169a2ddeb90..e24d5992cfb89ccc4e727c91918ab1f94131987e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -280,7 +280,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0566-Add-PlayerSetSpawnEvent.patch b/patches/server/0566-Add-PlayerSetSpawnEvent.patch index e28f1bfdd7ae..6c4f8f48bc94 100644 --- a/patches/server/0566-Add-PlayerSetSpawnEvent.patch +++ b/patches/server/0566-Add-PlayerSetSpawnEvent.patch @@ -187,7 +187,7 @@ index db26b5a0464bd6087eeacaf6dd61eba37365df92..9117c035d5a6ff114b028fad3380ceb1 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index f0f8238aeb49c45921c7ec48cc49ed628087741f..efc9b5f6864b09fcf116bbad82424b82448f5469 100644 +index e24d5992cfb89ccc4e727c91918ab1f94131987e..ca13d317a5e1c7b7ccda3fdec63e2146562649f6 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1430,9 +1430,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0649-Multi-Block-Change-API-Implementation.patch b/patches/server/0649-Multi-Block-Change-API-Implementation.patch index 45d3534bd90d..9edd052d01b2 100644 --- a/patches/server/0649-Multi-Block-Change-API-Implementation.patch +++ b/patches/server/0649-Multi-Block-Change-API-Implementation.patch @@ -24,7 +24,7 @@ index 926ff9be3d9e3f5d620e4c7ccb22b9f64865ff8c..1a37654aff9a9c86c9f7af10a1cf7213 buf.writeLong(this.sectionPos.asLong()); buf.writeVarInt(this.positions.length); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index efc9b5f6864b09fcf116bbad82424b82448f5469..5274ee417ba3b9ccdab70449c87ce8f3809ea137 100644 +index ca13d317a5e1c7b7ccda3fdec63e2146562649f6..fe0c355f8203c9bfa30d2ec48392a5a1a3d616ae 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -947,6 +947,32 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0658-Add-GameEvent-tags.patch b/patches/server/0658-Add-GameEvent-tags.patch index f36a025eb7ba..34a9b8a43edd 100644 --- a/patches/server/0658-Add-GameEvent-tags.patch +++ b/patches/server/0658-Add-GameEvent-tags.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add GameEvent tags diff --git a/src/main/java/io/papermc/paper/CraftGameEventTag.java b/src/main/java/io/papermc/paper/CraftGameEventTag.java new file mode 100644 -index 0000000000000000000000000000000000000000..e7d9fd2702a1ce96596580fff8f5ee4fd3d22b5b +index 0000000000000000000000000000000000000000..874c420e60b6be09c806d64f40cf63663ffddc07 --- /dev/null +++ b/src/main/java/io/papermc/paper/CraftGameEventTag.java @@ -0,0 +1,35 @@ @@ -37,7 +37,7 @@ index 0000000000000000000000000000000000000000..e7d9fd2702a1ce96596580fff8f5ee4f + private static final Map> KEY_CACHE = Collections.synchronizedMap(new IdentityHashMap<>()); + @Override + public boolean isTagged(@NotNull GameEvent gameEvent) { -+ return registry.getHolderOrThrow(KEY_CACHE.computeIfAbsent(gameEvent, event -> ResourceKey.create(Registries.GAME_EVENT, CraftNamespacedKey.toMinecraft(event.getKey())))).is(tag); ++ return registry.getOrThrow(KEY_CACHE.computeIfAbsent(gameEvent, event -> ResourceKey.create(Registries.GAME_EVENT, CraftNamespacedKey.toMinecraft(event.getKey())))).is(tag); + } + + @Override diff --git a/patches/server/0668-Expose-furnace-minecart-push-values.patch b/patches/server/0668-Expose-furnace-minecart-push-values.patch index 6245e14b4e0c..fb48aabb5f80 100644 --- a/patches/server/0668-Expose-furnace-minecart-push-values.patch +++ b/patches/server/0668-Expose-furnace-minecart-push-values.patch @@ -6,32 +6,34 @@ Subject: [PATCH] Expose furnace minecart push values Adds methods for getting and setting a furnace minecart's push values diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java -index 53042b75b45093535d6572239b34c3ff9a72f648..1b41026ab638bb2764b19429706eb0aded5aad12 100644 +index 53042b75b45093535d6572239b34c3ff9a72f648..1be1f6d23f2224d4d8720d40f2e530736b1bae81 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java -@@ -27,6 +27,28 @@ public class CraftMinecartFurnace extends CraftMinecart implements PoweredMineca +@@ -27,6 +27,30 @@ public class CraftMinecartFurnace extends CraftMinecart implements PoweredMineca this.getHandle().fuel = fuel; } + // Paper start + @Override + public double getPushX() { -+ return getHandle().xPush; ++ return getHandle().push.x; + } + + @Override + public double getPushZ() { -+ return getHandle().zPush; ++ return getHandle().push.z; + } + + @Override + public void setPushX(double xPush) { -+ getHandle().xPush = xPush; ++ final net.minecraft.world.phys.Vec3 push = getHandle().push; ++ getHandle().push = new net.minecraft.world.phys.Vec3(xPush, push.y, push.z); + } + + @Override + public void setPushZ(double zPush) { -+ getHandle().zPush = zPush; ++ final net.minecraft.world.phys.Vec3 push = getHandle().push; ++ getHandle().push = new net.minecraft.world.phys.Vec3(push.x, push.y, zPush); + } + // Paper end + diff --git a/patches/server/0716-More-Teleport-API.patch b/patches/server/0716-More-Teleport-API.patch index 70bc44b3da9c..850f742352b2 100644 --- a/patches/server/0716-More-Teleport-API.patch +++ b/patches/server/0716-More-Teleport-API.patch @@ -112,7 +112,7 @@ index 4e6afa243d6108cb946a8a7cf96c4036a3c2ac0c..43786eacc72cdf3bb209d3dfb1808ea9 private final org.bukkit.entity.Entity.Spigot spigot = new org.bukkit.entity.Entity.Spigot() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 5274ee417ba3b9ccdab70449c87ce8f3809ea137..c45753f4b65b189ebfdaea4fb0ec51217dd990c3 100644 +index fe0c355f8203c9bfa30d2ec48392a5a1a3d616ae..baae7a129853a296273b7f295f58cbb99187da22 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1303,13 +1303,102 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -246,7 +246,7 @@ index 5274ee417ba3b9ccdab70449c87ce8f3809ea137..c45753f4b65b189ebfdaea4fb0ec5121 // SPIGOT-5509: Wakeup, similar to riding if (this.isSleeping()) { -@@ -1356,13 +1445,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1356,13 +1445,21 @@ public class CraftPlayer extends CraftHumanEntity implements Player { ServerLevel toWorld = ((CraftWorld) to.getWorld()).getHandle(); // Close any foreign inventory @@ -263,7 +263,9 @@ index 5274ee417ba3b9ccdab70449c87ce8f3809ea137..c45753f4b65b189ebfdaea4fb0ec5121 + for (final io.papermc.paper.entity.TeleportFlag.Relative bukkit : relativeArguments) { + nms.add(toNmsRelativeFlag(bukkit)); + } -+ entity.connection.internalTeleport(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch(), nms); ++ entity.connection.internalTeleport(new net.minecraft.world.entity.PositionMoveRotation( ++ io.papermc.paper.util.MCUtil.toVec3(to), net.minecraft.world.phys.Vec3.ZERO, to.getYaw(), to.getPitch() ++ ), nms); + // Paper end - Teleport API } else { entity.portalProcess = null; // SPIGOT-7785: there is no need to carry this over as it contains the old world/location and we might run into trouble if there is a portal in the same spot in both worlds diff --git a/patches/server/0721-Custom-Chat-Completion-Suggestions-API.patch b/patches/server/0721-Custom-Chat-Completion-Suggestions-API.patch index d204b1a24fc3..9908dc279cca 100644 --- a/patches/server/0721-Custom-Chat-Completion-Suggestions-API.patch +++ b/patches/server/0721-Custom-Chat-Completion-Suggestions-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Custom Chat Completion Suggestions API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index c45753f4b65b189ebfdaea4fb0ec51217dd990c3..2b5eb586eda41d465f3f1faae8159f6fbe346312 100644 +index baae7a129853a296273b7f295f58cbb99187da22..58f3ca95b1d79269bed3b6473cd69d8988ede162 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -708,6 +708,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0746-Elder-Guardian-appearance-API.patch b/patches/server/0746-Elder-Guardian-appearance-API.patch index bf49ebc163a4..772a3c2cd3e9 100644 --- a/patches/server/0746-Elder-Guardian-appearance-API.patch +++ b/patches/server/0746-Elder-Guardian-appearance-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Elder Guardian appearance API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 2b5eb586eda41d465f3f1faae8159f6fbe346312..d8d3d256910790fd7fc406d64ab38e1c372ecfa7 100644 +index 58f3ca95b1d79269bed3b6473cd69d8988ede162..667796909ea6b56b93ec591aae1c393ec2f8940a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3326,6 +3326,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3328,6 +3328,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end diff --git a/patches/server/0758-Add-Player-Warden-Warning-API.patch b/patches/server/0758-Add-Player-Warden-Warning-API.patch index 9ec70390920d..2ce951d03613 100644 --- a/patches/server/0758-Add-Player-Warden-Warning-API.patch +++ b/patches/server/0758-Add-Player-Warden-Warning-API.patch @@ -10,10 +10,10 @@ public net.minecraft.world.entity.monster.warden.WardenSpawnTracker cooldownTick public net.minecraft.world.entity.monster.warden.WardenSpawnTracker increaseWarningLevel()V diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index d8d3d256910790fd7fc406d64ab38e1c372ecfa7..bc96e6a4f6833b351da5ac91563fd6f0d057c854 100644 +index 667796909ea6b56b93ec591aae1c393ec2f8940a..7ef67f0b5da392fa09a99d1213eefa373aad96b6 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3331,6 +3331,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3333,6 +3333,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void showElderGuardian(boolean silent) { if (getHandle().connection != null) getHandle().connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.GUARDIAN_ELDER_EFFECT, silent ? 0F : 1F)); } diff --git a/patches/server/0770-fix-Instruments.patch b/patches/server/0770-fix-Instruments.patch index fa555c5aa37f..ff46175c0f40 100644 --- a/patches/server/0770-fix-Instruments.patch +++ b/patches/server/0770-fix-Instruments.patch @@ -6,7 +6,7 @@ Subject: [PATCH] fix Instruments properly handle Player#playNote diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index bc96e6a4f6833b351da5ac91563fd6f0d057c854..b0818d1fc60ab75770e671d30cdbfd531b3dfa99 100644 +index 7ef67f0b5da392fa09a99d1213eefa373aad96b6..f710776d2a81c426cbe75532b06da4f8b1ef4787 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -785,7 +785,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0779-Flying-Fall-Damage.patch b/patches/server/0779-Flying-Fall-Damage.patch index a9fc10c351bd..a09b209fd2c6 100644 --- a/patches/server/0779-Flying-Fall-Damage.patch +++ b/patches/server/0779-Flying-Fall-Damage.patch @@ -26,10 +26,10 @@ index 30e0a5fe3f9bd85d2b702c2c877c5682ed35d461..aca888c2f02b09ac6739bdc81b194c45 } else { if (fallDistance >= 2.0F) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index b0818d1fc60ab75770e671d30cdbfd531b3dfa99..05d95294a5183612c171fbd0e5181ac02270e784 100644 +index f710776d2a81c426cbe75532b06da4f8b1ef4787..35722608d2c2d702429f5724732e8af39bb37488 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2609,6 +2609,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2611,6 +2611,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().onUpdateAbilities(); } diff --git a/patches/server/0784-Win-Screen-API.patch b/patches/server/0784-Win-Screen-API.patch index 65a47054b53f..8412d997bc15 100644 --- a/patches/server/0784-Win-Screen-API.patch +++ b/patches/server/0784-Win-Screen-API.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Win Screen API public net.minecraft.server.level.ServerPlayer seenCredits diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 05d95294a5183612c171fbd0e5181ac02270e784..0a700df3e4f4f6e2e902f0c69dd6ae149978be47 100644 +index 35722608d2c2d702429f5724732e8af39bb37488..83e29f518a57bd2eb4113d5b93cdf47af119c715 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1322,6 +1322,25 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0792-Correctly-handle-ArmorStand-invisibility.patch b/patches/server/0792-Correctly-handle-ArmorStand-invisibility.patch index c3b0b191aaa7..4c4c5048be7c 100644 --- a/patches/server/0792-Correctly-handle-ArmorStand-invisibility.patch +++ b/patches/server/0792-Correctly-handle-ArmorStand-invisibility.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Correctly handle ArmorStand invisibility diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java -index e1cedcb95e9b2e2e9587b623256b5cffa7b08ce4..a2a0064ed86628494e80cb6f6357b4cd9f91f04b 100644 +index c8713200d946b0fdd74b60d0c2c136c8226389e0..184fe8257e5ffb0ef090ffa2833786a4db8b59ea 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java @@ -152,6 +152,14 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { diff --git a/patches/server/0809-Expand-PlayerItemMendEvent.patch b/patches/server/0809-Expand-PlayerItemMendEvent.patch index 73abf28aa3ee..7c61c0095c8d 100644 --- a/patches/server/0809-Expand-PlayerItemMendEvent.patch +++ b/patches/server/0809-Expand-PlayerItemMendEvent.patch @@ -30,10 +30,10 @@ index 3a7af27bb1ce0cbe56bd3760cd400083daf98d4c..bf0838f574fa3fb9654e087d602b8d38 if (l > 0) { // this.value = l; // CraftBukkit - update exp value of orb for PlayerItemMendEvent calls // Paper - the value field should not be mutated here because it doesn't take "count" into account diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 0a700df3e4f4f6e2e902f0c69dd6ae149978be47..3d52de930c4358843c5a8c88a1dce478b61ed616 100644 +index 83e29f518a57bd2eb4113d5b93cdf47af119c715..0d2fd570463d7ad1b6457a8b14303273b97716dd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1881,11 +1881,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1883,11 +1883,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { handle.serverLevel(), itemstack, amount ); int i = Math.min(possibleDurabilityFromXp, itemstack.getDamageValue()); diff --git a/patches/server/0828-Fix-BanList-API.patch b/patches/server/0828-Fix-BanList-API.patch index 639d56d79e4e..1164a2d94969 100644 --- a/patches/server/0828-Fix-BanList-API.patch +++ b/patches/server/0828-Fix-BanList-API.patch @@ -208,10 +208,10 @@ index 172202accf4448a933fcf1ff820316c7910dd7f7..50ee7656580d386db473c054f5c5ec57 return null; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 3d52de930c4358843c5a8c88a1dce478b61ed616..de96fdd4b6129f875e710670f6734bf7fa7a4cfb 100644 +index 0d2fd570463d7ad1b6457a8b14303273b97716dd..ccf2c23ecf6f406ae07a2d7614d52e65da8ca586 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1775,23 +1775,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1777,23 +1777,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override @@ -240,7 +240,7 @@ index 3d52de930c4358843c5a8c88a1dce478b61ed616..de96fdd4b6129f875e710670f6734bf7 if (kickPlayer) { this.kickPlayer(reason); } -@@ -1799,12 +1799,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1801,12 +1801,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override diff --git a/patches/server/0846-Bandaid-fix-for-Effect.patch b/patches/server/0846-Bandaid-fix-for-Effect.patch index a4996fb167d5..26b1a9f2368d 100644 --- a/patches/server/0846-Bandaid-fix-for-Effect.patch +++ b/patches/server/0846-Bandaid-fix-for-Effect.patch @@ -81,7 +81,7 @@ index 67d6840faea539b41ba3abb6d94b28e417a84511..b646f882de3ab04d54d07e9e944c261c // Special case: the axis is optional for ELECTRIC_SPARK Preconditions.checkArgument(effect.getData() == null || effect == Effect.ELECTRIC_SPARK, "Wrong kind of data for the %s effect", effect); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index de96fdd4b6129f875e710670f6734bf7fa7a4cfb..86f74c35a74b3c3a1d04d6be79e0df30642d475a 100644 +index ccf2c23ecf6f406ae07a2d7614d52e65da8ca586..80877e62d0743891f38abeee5b5b04b4f3bc4010 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -934,7 +934,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0854-Add-Listing-API-for-Player.patch b/patches/server/0854-Add-Listing-API-for-Player.patch index 34070f7cf34f..e99f679a7084 100644 --- a/patches/server/0854-Add-Listing-API-for-Player.patch +++ b/patches/server/0854-Add-Listing-API-for-Player.patch @@ -122,7 +122,7 @@ index a9063533ea4b2b349d476127b99c822203d7dfcb..218e18b9c7836bc4c9d3eba78e0717ca // Paper end - Use single player info update packet on join player.sentListPacket = true; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 86f74c35a74b3c3a1d04d6be79e0df30642d475a..9b59e7efde0516d55643e8ceb6d94e02ed22aacc 100644 +index 80877e62d0743891f38abeee5b5b04b4f3bc4010..1943cb7b691573d3f9755d21d4b5a4210c1cc329 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -206,6 +206,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -133,7 +133,7 @@ index 86f74c35a74b3c3a1d04d6be79e0df30642d475a..9b59e7efde0516d55643e8ceb6d94e02 private static final WeakHashMap> pluginWeakReferences = new WeakHashMap<>(); private int hash = 0; private double health = 20; -@@ -2120,7 +2121,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2122,7 +2123,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { otherPlayer.setUUID(uuidOverride); } // Paper end @@ -142,7 +142,7 @@ index 86f74c35a74b3c3a1d04d6be79e0df30642d475a..9b59e7efde0516d55643e8ceb6d94e02 if (original != null) otherPlayer.setUUID(original); // Paper - uuid override } -@@ -2224,6 +2225,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2226,6 +2227,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return (entity != null) ? this.canSee(entity) : false; // If we can't find it, we can't see it } diff --git a/patches/server/0864-Implement-OfflinePlayer-isConnected.patch b/patches/server/0864-Implement-OfflinePlayer-isConnected.patch index 7c4e1d35362a..ebef6c5101cb 100644 --- a/patches/server/0864-Implement-OfflinePlayer-isConnected.patch +++ b/patches/server/0864-Implement-OfflinePlayer-isConnected.patch @@ -23,7 +23,7 @@ index 2c2c4db31a746b4eb853dc04c6b3e5631bbfa034..4f4e3ee18d586f61706504218cddc06a public String getName() { Player player = this.getPlayer(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 9b59e7efde0516d55643e8ceb6d94e02ed22aacc..4de2a6a04a5bcf635f2bb5da640eb5941183e87c 100644 +index 1943cb7b691573d3f9755d21d4b5a4210c1cc329..3b2d7837486424a2d1759c4ba5d1b1d492e9ec48 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -261,6 +261,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0884-Add-player-idle-duration-API.patch b/patches/server/0884-Add-player-idle-duration-API.patch index 3f3f534dbcf6..3bf9d659b766 100644 --- a/patches/server/0884-Add-player-idle-duration-API.patch +++ b/patches/server/0884-Add-player-idle-duration-API.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add player idle duration API Implements API for getting and resetting a player's idle duration. diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 4de2a6a04a5bcf635f2bb5da640eb5941183e87c..4060a25f414631f702f04a53169b14e2ae6f9e31 100644 +index 3b2d7837486424a2d1759c4ba5d1b1d492e9ec48..b72d6395768a762cd72f2b98bc8cb2598dc286b9 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3447,6 +3447,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3449,6 +3449,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end diff --git a/patches/server/0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch b/patches/server/0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch index 272dd0236ddb..c5594fd831dd 100644 --- a/patches/server/0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch +++ b/patches/server/0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Allow null itemstack for Player#sendEquipmentChange diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 4060a25f414631f702f04a53169b14e2ae6f9e31..a343684b52594c295d5a75b9005da3434b72f329 100644 +index b72d6395768a762cd72f2b98bc8cb2598dc286b9..542c2d85da9695da0f8cc5c34f2e3c0b925dfb7c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1144,7 +1144,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0907-Add-experience-points-API.patch b/patches/server/0907-Add-experience-points-API.patch index 14c94b5af4c2..1b8c5e9d3f3c 100644 --- a/patches/server/0907-Add-experience-points-API.patch +++ b/patches/server/0907-Add-experience-points-API.patch @@ -18,10 +18,10 @@ index aca888c2f02b09ac6739bdc81b194c4527dd69f5..a19a795deaa7f46c92b97912e2ade006 // Paper start - send while respecting visibility private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index a343684b52594c295d5a75b9005da3434b72f329..a6b26d33de210e8c5351f3246b9ac391eb688689 100644 +index 542c2d85da9695da0f8cc5c34f2e3c0b925dfb7c..0a3d44ac5bfe252854377011ac363d52991c15ed 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1949,6 +1949,49 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1951,6 +1951,49 @@ public class CraftPlayer extends CraftHumanEntity implements Player { Preconditions.checkArgument(exp >= 0, "Total experience points must not be negative (%s)", exp); this.getHandle().totalExperience = exp; } diff --git a/patches/server/0952-Added-API-to-get-player-ha-proxy-address.patch b/patches/server/0952-Added-API-to-get-player-ha-proxy-address.patch index 5fa97c5b54c6..1871d148106a 100644 --- a/patches/server/0952-Added-API-to-get-player-ha-proxy-address.patch +++ b/patches/server/0952-Added-API-to-get-player-ha-proxy-address.patch @@ -35,7 +35,7 @@ index c62df32af11636ad408b584fcc590590ce4fb0d0..baed0bb80d44973f9323bbe536551182 } else { super.channelRead(ctx, msg); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index a6b26d33de210e8c5351f3246b9ac391eb688689..7d8465ec67d4b2551c8fbe01964dd0cb2c94cbe8 100644 +index 0a3d44ac5bfe252854377011ac363d52991c15ed..72b9bffb12ef94d029c9502be90fb8c1bd37a4d1 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -270,7 +270,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/1020-Add-FeatureFlag-API.patch b/patches/server/1020-Add-FeatureFlag-API.patch index deea8b504e67..dc614e582a10 100644 --- a/patches/server/1020-Add-FeatureFlag-API.patch +++ b/patches/server/1020-Add-FeatureFlag-API.patch @@ -29,10 +29,10 @@ index 0000000000000000000000000000000000000000..c6fd2e8a570ac474dd1751929137280c +} diff --git a/src/main/java/io/papermc/paper/world/flag/PaperFeatureFlagProviderImpl.java b/src/main/java/io/papermc/paper/world/flag/PaperFeatureFlagProviderImpl.java new file mode 100644 -index 0000000000000000000000000000000000000000..d58b650fcafd04d00a92005ca8576d314535ce32 +index 0000000000000000000000000000000000000000..8a2fb217501bb6293adf54686420ef7d1ce2ec11 --- /dev/null +++ b/src/main/java/io/papermc/paper/world/flag/PaperFeatureFlagProviderImpl.java -@@ -0,0 +1,53 @@ +@@ -0,0 +1,55 @@ +package io.papermc.paper.world.flag; + +import com.google.common.collect.BiMap; @@ -55,8 +55,10 @@ index 0000000000000000000000000000000000000000..d58b650fcafd04d00a92005ca8576d31 + + public static final BiMap FLAGS = ImmutableBiMap.of( + FeatureFlag.VANILLA, FeatureFlags.VANILLA, -+ FeatureFlag.BUNDLE, FeatureFlags.BUNDLE, -+ FeatureFlag.TRADE_REBALANCE, FeatureFlags.TRADE_REBALANCE ++ FeatureFlag.TRADE_REBALANCE, FeatureFlags.TRADE_REBALANCE, ++ FeatureFlag.MINECART_IMPROVEMENTS, FeatureFlags.MINECART_IMPROVEMENTS, ++ FeatureFlag.REDSTONE_EXPERIMENTS, FeatureFlags.REDSTONE_EXPERIMENTS, ++ FeatureFlag.WINTER_DROP, FeatureFlags.WINTER_DROP + ); + + @Override diff --git a/patches/server/1028-Improve-entity-effect-API.patch b/patches/server/1028-Improve-entity-effect-API.patch index 2b11b7ac1cd6..cc5195f74b51 100644 --- a/patches/server/1028-Improve-entity-effect-API.patch +++ b/patches/server/1028-Improve-entity-effect-API.patch @@ -25,7 +25,7 @@ index ca95a36b0149d4b8a67c3b42316c5d9d0415f5dd..64c6f54cc4d0c22bc972b808cb92925c + // Paper end - broadcast hurt animation } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 7d8465ec67d4b2551c8fbe01964dd0cb2c94cbe8..40a9f02091e9ae06fae28508c967fe1298419eda 100644 +index 72b9bffb12ef94d029c9502be90fb8c1bd37a4d1..d5dc7ecb9c4dddfd2c92d89b27c15512a0822b08 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1294,6 +1294,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -49,7 +49,7 @@ index 7d8465ec67d4b2551c8fbe01964dd0cb2c94cbe8..40a9f02091e9ae06fae28508c967fe12 } @Override -@@ -3546,4 +3551,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3548,4 +3553,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void setSendViewDistance(final int viewDistance) { throw new UnsupportedOperationException("Not implemented yet"); } From e19f48475db512e0b6f699c7a930434ea36cb753 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Fri, 25 Oct 2024 19:15:40 +0200 Subject: [PATCH 057/119] Test compile fixes --- .../0457-Fix-SpawnerEntry-Equipment-API.patch | 4 ++-- patches/server/0004-Test-changes.patch | 4 ++-- .../0156-Add-PlayerArmorChangeEvent.patch | 22 +++++++++---------- ...-Add-methods-to-get-translation-keys.patch | 16 +++++++++----- ...gistryAccess-for-managing-Registries.patch | 4 ++-- ...d-missing-structure-set-seed-configs.patch | 6 ++--- .../0957-Fix-issues-with-Recipe-API.patch | 4 ++-- patches/server/0979-Anti-Xray.patch | 11 +++++++++- .../0993-Registry-Modification-API.patch | 4 ++-- ...0994-Add-registry-entry-and-builders.patch | 2 +- 10 files changed, 45 insertions(+), 32 deletions(-) diff --git a/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch b/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch index 201dc87c4239..e170eabd170e 100644 --- a/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch +++ b/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix SpawnerEntry$Equipment API diff --git a/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java b/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java -index fc1c0435dfea121923eb1fe0182880752f321143..e167003cdf014e1ef4c475d1138c4462153fbc85 100644 +index fc1c0435dfea121923eb1fe0182880752f321143..bc8ccd139df6072f9744cfb85ad0070369600aa1 100644 --- a/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java +++ b/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java @@ -120,27 +120,29 @@ public class SpawnerEntry { @@ -22,7 +22,7 @@ index fc1c0435dfea121923eb1fe0182880752f321143..e167003cdf014e1ef4c475d1138c4462 + * Set the loot table for the spawned entity's equipment slots. *
    - * To remove a loot table use null. -+ * To remove a loot table use {@link org.bukkit.loot.LootTables#EMPTY}. ++ * To remove a loot table use the empty loot table. * * @param table this {@link org.bukkit.entity.Mob} will have. */ diff --git a/patches/server/0004-Test-changes.patch b/patches/server/0004-Test-changes.patch index adf6660553f9..2bf3cdb56617 100644 --- a/patches/server/0004-Test-changes.patch +++ b/patches/server/0004-Test-changes.patch @@ -32,7 +32,7 @@ index d4a5229b4df544ff60cdaee80c8ae301faf2a235..41b000aaa71dca3fb392ae657be16e05 } diff --git a/src/test/java/io/papermc/paper/registry/RegistryKeyTest.java b/src/test/java/io/papermc/paper/registry/RegistryKeyTest.java new file mode 100644 -index 0000000000000000000000000000000000000000..fe52d229c31526cc32f6422328efe92edf75a7ff +index 0000000000000000000000000000000000000000..d8857a05858585113bc7efde3416748effb53d01 --- /dev/null +++ b/src/test/java/io/papermc/paper/registry/RegistryKeyTest.java @@ -0,0 +1,34 @@ @@ -65,7 +65,7 @@ index 0000000000000000000000000000000000000000..fe52d229c31526cc32f6422328efe92e + @ParameterizedTest + @MethodSource("data") + void testApiRegistryKeysExist(final RegistryKey key) { -+ final Optional> registry = RegistryHelper.getRegistry().registry(ResourceKey.createRegistryKey(ResourceLocation.parse(key.key().asString()))); ++ final Optional> registry = RegistryHelper.getRegistry().lookup(ResourceKey.createRegistryKey(ResourceLocation.parse(key.key().asString()))); + assertTrue(registry.isPresent(), "Missing vanilla registry for " + key.key().asString()); + + } diff --git a/patches/server/0156-Add-PlayerArmorChangeEvent.patch b/patches/server/0156-Add-PlayerArmorChangeEvent.patch index cd684e2357ca..3655d4701af9 100644 --- a/patches/server/0156-Add-PlayerArmorChangeEvent.patch +++ b/patches/server/0156-Add-PlayerArmorChangeEvent.patch @@ -24,7 +24,7 @@ index f2f8fbc8a8cf32bcba0ad7ac9b6cdd75468e062a..76b71af07a311bc415b36f517afab315 } diff --git a/src/test/java/io/papermc/paper/inventory/item/ArmorSlotTypeMaterialTest.java b/src/test/java/io/papermc/paper/inventory/item/ArmorSlotTypeMaterialTest.java new file mode 100644 -index 0000000000000000000000000000000000000000..8943cef5cdb8269080b9f0e2edbad5d5ea8b421d +index 0000000000000000000000000000000000000000..1431b3faf081dc3ee5b33639bdc90c5057ae7027 --- /dev/null +++ b/src/test/java/io/papermc/paper/inventory/item/ArmorSlotTypeMaterialTest.java @@ -0,0 +1,75 @@ @@ -34,10 +34,10 @@ index 0000000000000000000000000000000000000000..8943cef5cdb8269080b9f0e2edbad5d5 +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; ++import net.minecraft.core.component.DataComponents; +import net.minecraft.world.entity.EquipmentSlot; -+import net.minecraft.world.item.Equipable; +import net.minecraft.world.item.Item; -+import net.minecraft.world.item.ItemStack; ++import net.minecraft.world.item.equipment.Equippable; +import org.bukkit.Material; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.support.environment.AllFeatures; @@ -65,23 +65,23 @@ index 0000000000000000000000000000000000000000..8943cef5cdb8269080b9f0e2edbad5d5 + @MethodSource("slotTypeParams") + public void testSlotType(PlayerArmorChangeEvent.SlotType slotType, Material item) { + final Item nmsItem = CraftMagicNumbers.getItem(item); -+ final Equipable equipable = Equipable.get(new ItemStack(nmsItem)); -+ assertNotNull(equipable, item + " isn't equipable"); ++ final Equippable equippable = nmsItem.components().get(DataComponents.EQUIPPABLE); ++ assertNotNull(equippable, item + " isn't equipable"); + final EquipmentSlot slot = switch (slotType) { + case HEAD -> EquipmentSlot.HEAD; + case CHEST -> EquipmentSlot.CHEST; + case LEGS -> EquipmentSlot.LEGS; + case FEET -> EquipmentSlot.FEET; + }; -+ assertEquals(equipable.getEquipmentSlot(), slot, item + " isn't set to the right slot"); ++ assertEquals(equippable.slot(), slot, item + " isn't set to the right slot"); + } + + public static Stream equipableParams() { + final List parameters = new ArrayList<>(); + for (final Item item : net.minecraft.core.registries.BuiltInRegistries.ITEM) { -+ final Equipable equipable = Equipable.get(new ItemStack(item)); -+ if (equipable != null) { -+ parameters.add(new Object[]{equipable, item}); ++ final Equippable equippable = item.components().get(DataComponents.EQUIPPABLE); ++ if (equippable != null) { ++ parameters.add(new Object[]{equippable, item}); + } + } + return parameters.stream(); @@ -89,8 +89,8 @@ index 0000000000000000000000000000000000000000..8943cef5cdb8269080b9f0e2edbad5d5 + + @ParameterizedTest(name = "{argumentsWithNames}") + @MethodSource("equipableParams") -+ public void testEquipable(Equipable equipable, Item item) { -+ final EquipmentSlot equipmentSlot = equipable.getEquipmentSlot(); ++ public void testEquipable(Equippable equipable, Item item) { ++ final EquipmentSlot equipmentSlot = equipable.slot(); + PlayerArmorChangeEvent.SlotType slotType = switch (equipmentSlot) { + case HEAD -> PlayerArmorChangeEvent.SlotType.HEAD; + case CHEST -> PlayerArmorChangeEvent.SlotType.CHEST; diff --git a/patches/server/0401-Add-methods-to-get-translation-keys.patch b/patches/server/0401-Add-methods-to-get-translation-keys.patch index bc50b97d021a..8ff2f02eb993 100644 --- a/patches/server/0401-Add-methods-to-get-translation-keys.patch +++ b/patches/server/0401-Add-methods-to-get-translation-keys.patch @@ -93,20 +93,22 @@ index 4921fc085c9d60c74028ef390325e26c598e8df1..4941e0afff8df5f10f06c715b54bf58e case BALL: return FireworkExplosion.Shape.SMALL_BALL; diff --git a/src/test/java/io/papermc/paper/world/TranslationKeyTest.java b/src/test/java/io/papermc/paper/world/TranslationKeyTest.java -index 7f8b6462d2a1bbd39a870d2543bebc135f7eb45b..4001c73e833ebf17baa22463dd197cee8ad67266 100644 +index 7f8b6462d2a1bbd39a870d2543bebc135f7eb45b..e8d5c3eb8ad98b2082bdd33d96bfb1d7124ea186 100644 --- a/src/test/java/io/papermc/paper/world/TranslationKeyTest.java +++ b/src/test/java/io/papermc/paper/world/TranslationKeyTest.java -@@ -1,11 +1,29 @@ +@@ -1,11 +1,32 @@ package io.papermc.paper.world; import com.destroystokyo.paper.ClientOption; +import java.util.Locale; +import java.util.Map; -+import net.minecraft.core.registries.BuiltInRegistries; ++import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.contents.TranslatableContents; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.ChatVisiblity; ++import net.minecraft.world.flag.FeatureFlags; ++import net.minecraft.world.level.GameRules; +import net.minecraft.world.level.GameType; +import net.minecraft.world.level.biome.Biome; import org.bukkit.Difficulty; @@ -115,6 +117,7 @@ index 7f8b6462d2a1bbd39a870d2543bebc135f7eb45b..4001c73e833ebf17baa22463dd197cee +import org.bukkit.GameRule; +import org.bukkit.MusicInstrument; +import org.bukkit.attribute.Attribute; ++import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.support.RegistryHelper; +import org.bukkit.support.environment.AllFeatures; @@ -126,7 +129,7 @@ index 7f8b6462d2a1bbd39a870d2543bebc135f7eb45b..4001c73e833ebf17baa22463dd197cee public class TranslationKeyTest { @Test -@@ -15,4 +33,69 @@ public class TranslationKeyTest { +@@ -15,4 +36,70 @@ public class TranslationKeyTest { Assertions.assertEquals(ChatVisiblity.valueOf(chatVisibility.name()).getKey(), chatVisibility.translationKey(), chatVisibility + "'s translation key doesn't match"); } } @@ -140,8 +143,9 @@ index 7f8b6462d2a1bbd39a870d2543bebc135f7eb45b..4001c73e833ebf17baa22463dd197cee + + @Test + public void testGameruleKeys() { ++ final Map> gameRules = CraftWorld.getGameRulesNMS(new GameRules(FeatureFlags.REGISTRY.allFlags())); + for (GameRule rule : GameRule.values()) { -+ Assertions.assertEquals(org.bukkit.craftbukkit.CraftWorld.getGameRulesNMS().get(rule.getName()).getDescriptionId(), rule.translationKey(), rule.getName() + "'s translation doesn't match"); ++ Assertions.assertEquals(gameRules.get(rule.getName()).getDescriptionId(), rule.translationKey(), rule.getName() + "'s translation doesn't match"); + } + } + @@ -189,7 +193,7 @@ index 7f8b6462d2a1bbd39a870d2543bebc135f7eb45b..4001c73e833ebf17baa22463dd197cee + + @Test + public void testMusicInstrument() { -+ for (final ResourceLocation nms : BuiltInRegistries.INSTRUMENT.keySet()) { ++ for (final ResourceLocation nms : RegistryHelper.getRegistry().lookupOrThrow(Registries.INSTRUMENT).keySet()) { + final MusicInstrument bukkit = MusicInstrument.getByKey(CraftNamespacedKey.fromMinecraft(nms)); + Assertions.assertNotNull(bukkit, "Missing bukkit instrument for " + nms); + Assertions.assertEquals(nms.toLanguageKey("instrument"), bukkit.translationKey(), "translation key mismatch for " + bukkit); diff --git a/patches/server/0467-Add-RegistryAccess-for-managing-Registries.patch b/patches/server/0467-Add-RegistryAccess-for-managing-Registries.patch index 5c3821894826..2f3085960e10 100644 --- a/patches/server/0467-Add-RegistryAccess-for-managing-Registries.patch +++ b/patches/server/0467-Add-RegistryAccess-for-managing-Registries.patch @@ -1004,7 +1004,7 @@ index 0000000000000000000000000000000000000000..a80b0ded74c0be657e734de61cbf5e32 + } +} diff --git a/src/test/java/io/papermc/paper/registry/RegistryKeyTest.java b/src/test/java/io/papermc/paper/registry/RegistryKeyTest.java -index fe52d229c31526cc32f6422328efe92edf75a7ff..67dadb1765a5ef9a391a459224e233f38201f5d5 100644 +index d8857a05858585113bc7efde3416748effb53d01..41c38b1b6d25c7a7ed08d70b19f5f4a70fc2df94 100644 --- a/src/test/java/io/papermc/paper/registry/RegistryKeyTest.java +++ b/src/test/java/io/papermc/paper/registry/RegistryKeyTest.java @@ -1,15 +1,19 @@ @@ -1030,7 +1030,7 @@ index fe52d229c31526cc32f6422328efe92edf75a7ff..67dadb1765a5ef9a391a459224e233f3 @AllFeatures @@ -29,6 +33,12 @@ class RegistryKeyTest { void testApiRegistryKeysExist(final RegistryKey key) { - final Optional> registry = RegistryHelper.getRegistry().registry(ResourceKey.createRegistryKey(ResourceLocation.parse(key.key().asString()))); + final Optional> registry = RegistryHelper.getRegistry().lookup(ResourceKey.createRegistryKey(ResourceLocation.parse(key.key().asString()))); assertTrue(registry.isPresent(), "Missing vanilla registry for " + key.key().asString()); + } diff --git a/patches/server/0655-Add-missing-structure-set-seed-configs.patch b/patches/server/0655-Add-missing-structure-set-seed-configs.patch index 42bd7f0c4b78..8677197bdc76 100644 --- a/patches/server/0655-Add-missing-structure-set-seed-configs.patch +++ b/patches/server/0655-Add-missing-structure-set-seed-configs.patch @@ -316,7 +316,7 @@ index e76f96a5c48d1eda2f9bbb3e11dd79f23f9ab75c..2b263246135c85aa225120519e9702a6 } diff --git a/src/test/java/io/papermc/paper/world/structure/StructureSeedConfigTest.java b/src/test/java/io/papermc/paper/world/structure/StructureSeedConfigTest.java new file mode 100644 -index 0000000000000000000000000000000000000000..c77345f7e0c9bf179b8b35a8b300085f31fd45af +index 0000000000000000000000000000000000000000..cc1fb5ae9e0898735771c6163c9b90658fb61eed --- /dev/null +++ b/src/test/java/io/papermc/paper/world/structure/StructureSeedConfigTest.java @@ -0,0 +1,77 @@ @@ -356,10 +356,10 @@ index 0000000000000000000000000000000000000000..c77345f7e0c9bf179b8b35a8b300085f + final SpigotWorldConfig config = PaperConfigurations.SPIGOT_WORLD_DEFAULTS.get(); + + -+ final Registry structureSets = RegistryHelper.getRegistry().registryOrThrow(Registries.STRUCTURE_SET); ++ final Registry structureSets = RegistryHelper.getRegistry().lookupOrThrow(Registries.STRUCTURE_SET); + for (final ResourceKey setKey : structureSets.registryKeySet()) { + assertEquals(ResourceLocation.DEFAULT_NAMESPACE, setKey.location().getNamespace()); -+ final StructureSet set = structureSets.getOrThrow(setKey); ++ final StructureSet set = structureSets.getValueOrThrow(setKey); + if (setKey == BuiltinStructureSets.STRONGHOLDS) { // special case due to seed matching world seed + assertEquals(0, set.placement().salt); + continue; diff --git a/patches/server/0957-Fix-issues-with-Recipe-API.patch b/patches/server/0957-Fix-issues-with-Recipe-API.patch index ab2b6a47eff6..17a8c00f6436 100644 --- a/patches/server/0957-Fix-issues-with-Recipe-API.patch +++ b/patches/server/0957-Fix-issues-with-Recipe-API.patch @@ -73,7 +73,7 @@ index 0000000000000000000000000000000000000000..45ab2b6d32b29cb663df848534e1aa68 + } +} diff --git a/src/test/java/org/bukkit/support/DummyServerHelper.java b/src/test/java/org/bukkit/support/DummyServerHelper.java -index 55c05c16a80c489cdda2fd03c943921d38d978e9..6855816ec5fd232b53622c316e45b3c081297085 100644 +index 55c05c16a80c489cdda2fd03c943921d38d978e9..309d371247adcddf0a1b370cc5faff3e6e01cb0f 100644 --- a/src/test/java/org/bukkit/support/DummyServerHelper.java +++ b/src/test/java/org/bukkit/support/DummyServerHelper.java @@ -92,6 +92,15 @@ public final class DummyServerHelper { @@ -84,7 +84,7 @@ index 55c05c16a80c489cdda2fd03c943921d38d978e9..6855816ec5fd232b53622c316e45b3c0 + // Paper start - add test for recipe conversion + when(instance.recipeIterator()).thenAnswer(ignored -> + com.google.common.collect.Iterators.transform( -+ RegistryHelper.getDataPack().getRecipeManager().byType.entries().iterator(), ++ RegistryHelper.getDataPack().getRecipeManager().recipes.byType.entries().iterator(), + input -> input.getValue().toBukkitRecipe() + ) + ); diff --git a/patches/server/0979-Anti-Xray.patch b/patches/server/0979-Anti-Xray.patch index 88fd107647ed..3a140d851c3a 100644 --- a/patches/server/0979-Anti-Xray.patch +++ b/patches/server/0979-Anti-Xray.patch @@ -1519,9 +1519,18 @@ index 303e59be721d0e16e8822cf4e407595348ee7abf..51f74dd7b276e858889803d7f341d735 int getSerializedSize(); diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index b86b3bf713668999a21c4120b1d16c295531b2ad..f6c42532d4921628072d44313404696890087b9f 100644 +index b86b3bf713668999a21c4120b1d16c295531b2ad..eba3e34e5b129050bf6eaed6ce4e690357a3de20 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +@@ -79,7 +79,7 @@ import org.slf4j.Logger; + // CraftBukkit - persistentDataContainer + public record SerializableChunkData(Registry biomeRegistry, ChunkPos chunkPos, int minSectionY, long lastUpdateTime, long inhabitedTime, ChunkStatus chunkStatus, @Nullable BlendingData.Packed blendingData, @Nullable BelowZeroRetrogen belowZeroRetrogen, UpgradeData upgradeData, @Nullable long[] carvingMask, Map heightmaps, ChunkAccess.PackedTicks packedTicks, ShortList[] postProcessingSections, boolean lightCorrect, List sectionData, List entities, List blockEntities, CompoundTag structureData, @Nullable Tag persistentDataContainer) { + +- public static final Codec> BLOCK_STATE_CODEC = PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState()); ++ public static final Codec> BLOCK_STATE_CODEC = PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), null); // Paper start - Anti-Xray + private static final Logger LOGGER = LogUtils.getLogger(); + private static final String TAG_UPGRADE_DATA = "UpgradeData"; + private static final String BLOCK_TICKS_TAG = "block_ticks"; @@ -111,6 +111,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun @Nullable diff --git a/patches/server/0993-Registry-Modification-API.patch b/patches/server/0993-Registry-Modification-API.patch index d61a98a7a446..9568730b7f11 100644 --- a/patches/server/0993-Registry-Modification-API.patch +++ b/patches/server/0993-Registry-Modification-API.patch @@ -1393,7 +1393,7 @@ index 0000000000000000000000000000000000000000..8bee1a5ed877a04e4d027593df1f42ce +io.papermc.paper.registry.event.RegistryEventTypeProviderImpl diff --git a/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java b/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java new file mode 100644 -index 0000000000000000000000000000000000000000..47b8ebac8496179008b8932c5ca2aadc274e24e0 +index 0000000000000000000000000000000000000000..ceef7b5864deb1d7c6aa5630febe86ba9427bdc4 --- /dev/null +++ b/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java @@ -0,0 +1,36 @@ @@ -1426,7 +1426,7 @@ index 0000000000000000000000000000000000000000..47b8ebac8496179008b8932c5ca2aadc + @ParameterizedTest + @MethodSource("registries") + void testEquality(final ResourceKey> resourceKey, final PaperRegistryBuilder.Filler filler) { -+ final Registry registry = RegistryHelper.getRegistry().registryOrThrow(resourceKey); ++ final Registry registry = RegistryHelper.getRegistry().lookupOrThrow(resourceKey); + for (final Map.Entry, M> entry : registry.entrySet()) { + final M built = filler.fill(new Conversions(new RegistryOps.HolderLookupAdapter(RegistryHelper.getRegistry())), PaperRegistries.fromNms(entry.getKey()), entry.getValue()).build(); + assertEquals(entry.getValue(), built); diff --git a/patches/server/0994-Add-registry-entry-and-builders.patch b/patches/server/0994-Add-registry-entry-and-builders.patch index 8f2663ac94de..0355a6b2992e 100644 --- a/patches/server/0994-Add-registry-entry-and-builders.patch +++ b/patches/server/0994-Add-registry-entry-and-builders.patch @@ -442,7 +442,7 @@ index ac9b4328cd55a68664a3f71186bc9a7be7cd9658..ea9fe1f8b1a1685ea975eba0ca418a83 @Override public NamespacedKey getKey() { diff --git a/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java b/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java -index 47b8ebac8496179008b8932c5ca2aadc274e24e0..814675bf67fd02e8cd2311dce60eeef651ef16f1 100644 +index ceef7b5864deb1d7c6aa5630febe86ba9427bdc4..4d4632da6bf1bde85115dde2e2f7e353bd392176 100644 --- a/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java +++ b/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java @@ -1,11 +1,16 @@ From 35189742708c510869dd398b8de18405f6f13114 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Fri, 25 Oct 2024 20:09:45 +0200 Subject: [PATCH 058/119] fix some issues --- patches/server/0023-Timings-v2.patch | 8 +++----- patches/server/0166-PreCreatureSpawnEvent.patch | 4 ++-- ...0278-Fixes-and-additions-to-the-spawn-reason-API.patch | 4 ++-- .../0362-Fix-piston-physics-inconsistency-MC-188840.patch | 5 +++-- patches/server/0477-Expand-EntityUnleashEvent.patch | 5 +++-- patches/server/0574-Add-BlockBreakBlockEvent.patch | 2 +- ...7-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch | 2 +- patches/server/0678-Add-TameableDeathMessageEvent.patch | 4 ++-- .../0683-Allow-changing-the-EnderDragon-podium.patch | 4 ++-- patches/server/0750-Add-EntityToggleSitEvent.patch | 2 +- .../0781-config-for-disabling-entity-tag-tags.patch | 4 ++-- patches/server/0789-Add-EntityFertilizeEggEvent.patch | 4 ++-- ...-set-despawnTimer-for-Wandering-Traders-spawned-.patch | 4 ++-- .../0899-Don-t-fire-sync-events-during-worldgen.patch | 4 ++-- .../0902-Restore-vanilla-entity-drops-behavior.patch | 4 ++-- ...0906-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch | 2 +- patches/server/0908-Add-drops-to-shear-events.patch | 2 +- .../0910-Validate-ResourceLocation-in-NBT-reading.patch | 6 +++--- patches/server/0934-Fix-DamageSource-API.patch | 4 ++-- ...ect-Bedrock-and-End-Portal-Frames-from-being-des.patch | 2 +- ...0948-Fix-helmet-damage-reduction-inconsistencies.patch | 2 +- .../server/0985-Optimize-Bit-Operations-by-inlining.patch | 4 ++-- 22 files changed, 41 insertions(+), 41 deletions(-) diff --git a/patches/server/0023-Timings-v2.patch b/patches/server/0023-Timings-v2.patch index 0fd756a82d83..4e5f30f3df77 100644 --- a/patches/server/0023-Timings-v2.patch +++ b/patches/server/0023-Timings-v2.patch @@ -1344,10 +1344,10 @@ index c010d18061f58a583c69e85fc29305497523f569..c8b8102d84119dfb6093f4b79aa3124c private void applyMovementEmissionAndPlaySound(Entity.MovementEmission moveEffect, Vec3 movement, BlockPos landingPos, BlockState landingState) { diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 17ab230c95901f0533997ac117d5b3d852fcd467..a9ae3d3210e049b0ce066b47378a3f2024154cfd 100644 +index 17ab230c95901f0533997ac117d5b3d852fcd467..970161efa46b3a71ddae665f9df5966c70fd3471 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -413,6 +413,16 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -413,6 +413,15 @@ public class EntityType implements FeatureElement, EntityTypeT } public EntityType(EntityType.EntityFactory factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet canSpawnInside, EntityDimensions dimensions, float spawnBoxScale, int maxTrackDistance, int trackTickInterval, String translationKey, Optional> lootTable, FeatureFlagSet requiredFeatures) { @@ -1359,12 +1359,11 @@ index 17ab230c95901f0533997ac117d5b3d852fcd467..a9ae3d3210e049b0ce066b47378a3f20 + this.inactiveTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "inactiveTick"); + this.passengerTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "passengerTick"); + this.passengerInactiveTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "passengerInactiveTick"); -+ this.id = id; + // Paper end this.builtInRegistryHolder = BuiltInRegistries.ENTITY_TYPE.createIntrusiveHolder(this); this.factory = factory; this.category = spawnGroup; -@@ -720,6 +730,13 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -720,6 +729,12 @@ public class EntityType implements FeatureElement, EntityTypeT return this.updateInterval; } @@ -1373,7 +1372,6 @@ index 17ab230c95901f0533997ac117d5b3d852fcd467..a9ae3d3210e049b0ce066b47378a3f20 + public final co.aikar.timings.Timing inactiveTickTimer; + public final co.aikar.timings.Timing passengerTickTimer; + public final co.aikar.timings.Timing passengerInactiveTickTimer; -+ private final String id; + // Paper end public boolean trackDeltas() { return this != EntityType.PLAYER && this != EntityType.LLAMA_SPIT && this != EntityType.WITHER && this != EntityType.BAT && this != EntityType.ITEM_FRAME && this != EntityType.GLOW_ITEM_FRAME && this != EntityType.LEASH_KNOT && this != EntityType.PAINTING && this != EntityType.END_CRYSTAL && this != EntityType.EVOKER_FANGS; diff --git a/patches/server/0166-PreCreatureSpawnEvent.patch b/patches/server/0166-PreCreatureSpawnEvent.patch index 2a845a497c57..8c22573ffb05 100644 --- a/patches/server/0166-PreCreatureSpawnEvent.patch +++ b/patches/server/0166-PreCreatureSpawnEvent.patch @@ -55,10 +55,10 @@ index e139ed6bc6f2dd07fe546588b31309ba30ed9755..34c3bf85473b3ad89355ebc21b68c59b if (t0 != null) { diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index a9ae3d3210e049b0ce066b47378a3f2024154cfd..47fe53ed2f50f1a7ed9f324adf9fc73a6ecc184a 100644 +index 970161efa46b3a71ddae665f9df5966c70fd3471..5fe268b5c3297de7650f5d1f310cdf8ac231de75 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -507,6 +507,16 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -506,6 +506,16 @@ public class EntityType implements FeatureElement, EntityTypeT @Nullable public T spawn(ServerLevel worldserver, @Nullable Consumer consumer, BlockPos blockposition, EntitySpawnReason entityspawnreason, boolean flag, boolean flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { // CraftBukkit end diff --git a/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch b/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch index 90c812385400..2e0766fbd74b 100644 --- a/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch +++ b/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch @@ -116,10 +116,10 @@ index 5d551a50e1043e369ebf3ddfe181be1e24cfd068..463d34e7b54efd503c4879d1386b2439 } catch (Throwable throwable) { diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 47fe53ed2f50f1a7ed9f324adf9fc73a6ecc184a..9fe4027aa16d73d806f51a7c195a5cf0468ebba3 100644 +index 5fe268b5c3297de7650f5d1f310cdf8ac231de75..e5dc6f868f090d1957306a6389d85cf9dbbc444d 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -443,7 +443,7 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -442,7 +442,7 @@ public class EntityType implements FeatureElement, EntityTypeT @Nullable public T spawn(ServerLevel world, @Nullable ItemStack stack, @Nullable Player player, BlockPos pos, EntitySpawnReason spawnReason, boolean alignPosition, boolean invertY) { // CraftBukkit start diff --git a/patches/server/0362-Fix-piston-physics-inconsistency-MC-188840.patch b/patches/server/0362-Fix-piston-physics-inconsistency-MC-188840.patch index 60773947a868..aca7ba66dff4 100644 --- a/patches/server/0362-Fix-piston-physics-inconsistency-MC-188840.patch +++ b/patches/server/0362-Fix-piston-physics-inconsistency-MC-188840.patch @@ -32,7 +32,7 @@ This patch fixes https://bugs.mojang.com/browse/MC-188840 This patch also fixes rail duping and carpet duping. diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java -index 0b80940ed23a35e0412957a50d04907b676b0aca..e84501fdce7b94300b1f5d6d20e2db90b175454d 100644 +index 0b80940ed23a35e0412957a50d04907b676b0aca..0c6b517196d48ba4384eac240b7e580adfdbc4d4 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java +++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java @@ -419,13 +419,25 @@ public class PistonBaseBlock extends DirectionalBlock { @@ -50,12 +50,13 @@ index 0b80940ed23a35e0412957a50d04907b676b0aca..e84501fdce7b94300b1f5d6d20e2db90 map.remove(blockposition3); iblockdata2 = (BlockState) Blocks.MOVING_PISTON.defaultBlockState().setValue(PistonBaseBlock.FACING, dir); world.setBlock(blockposition3, iblockdata2, 68); +- world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(blockposition3, iblockdata2, (BlockState) list1.get(j), dir, extend, false)); + // Paper start - fix a variety of piston desync dupes + if (!allowDesync) { + iblockdata1 = world.getBlockState(oldPos); + map.replace(oldPos, iblockdata1); + } - world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(blockposition3, iblockdata2, (BlockState) list1.get(j), dir, extend, false)); ++ world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(blockposition3, iblockdata2, allowDesync ? (BlockState) list1.get(j) : iblockdata1, dir, extend, false)); + if (!allowDesync) { + world.setBlock(oldPos, Blocks.AIR.defaultBlockState(), Block.UPDATE_CLIENTS | Block.UPDATE_KNOWN_SHAPE | Block.UPDATE_MOVE_BY_PISTON | 1024); // set air to prevent later physics updates from seeing this block + } diff --git a/patches/server/0477-Expand-EntityUnleashEvent.patch b/patches/server/0477-Expand-EntityUnleashEvent.patch index 8d23e8ce8587..09c4e7f7eb73 100644 --- a/patches/server/0477-Expand-EntityUnleashEvent.patch +++ b/patches/server/0477-Expand-EntityUnleashEvent.patch @@ -43,7 +43,7 @@ index 07aff05e2e8cd36ebb6b9fb9d2f19b95c5f9bfc4..bb2cfec32b63d3786f9ec255d4beef70 } diff --git a/src/main/java/net/minecraft/world/entity/Leashable.java b/src/main/java/net/minecraft/world/entity/Leashable.java -index dc39ecc3e1aada638337d31bfe68b400c6454af7..1a6448cccf79a94013f9f44c3067d91da3da1f7e 100644 +index dc39ecc3e1aada638337d31bfe68b400c6454af7..b7721ed97305d1cd6725935f965c2effc1bef5a1 100644 --- a/src/main/java/net/minecraft/world/entity/Leashable.java +++ b/src/main/java/net/minecraft/world/entity/Leashable.java @@ -167,8 +167,11 @@ public interface Leashable { @@ -51,10 +51,11 @@ index dc39ecc3e1aada638337d31bfe68b400c6454af7..1a6448cccf79a94013f9f44c3067d91d if (leashable_a != null && leashable_a.leashHolder != null) { if (!entity.isAlive() || !leashable_a.leashHolder.isAlive()) { - world.getCraftServer().getPluginManager().callEvent(new EntityUnleashEvent(entity.getBukkitEntity(), (!entity.isAlive()) ? UnleashReason.PLAYER_UNLEASH : UnleashReason.HOLDER_GONE)); // CraftBukkit +- Leashable.dropLeash(entity, true, world.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS) && !entity.pluginRemoved); // CraftBukkit - SPIGOT-7487: Don't drop leash, when the holder was removed by a plugin + // Paper start - Expand EntityUnleashEvent + final EntityUnleashEvent event = new EntityUnleashEvent(entity.getBukkitEntity(), (!entity.isAlive()) ? UnleashReason.PLAYER_UNLEASH : UnleashReason.HOLDER_GONE, world.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS) && !entity.pluginRemoved); + event.callEvent(); - Leashable.dropLeash(entity, true, world.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS) && !entity.pluginRemoved); // CraftBukkit - SPIGOT-7487: Don't drop leash, when the holder was removed by a plugin ++ Leashable.dropLeash(entity, true, event.isDropLeash()); // CraftBukkit - SPIGOT-7487: Don't drop leash, when the holder was removed by a plugin + // Paper end - Expand EntityUnleashEvent } diff --git a/patches/server/0574-Add-BlockBreakBlockEvent.patch b/patches/server/0574-Add-BlockBreakBlockEvent.patch index a5e51ea2aa64..4a3af0251e1a 100644 --- a/patches/server/0574-Add-BlockBreakBlockEvent.patch +++ b/patches/server/0574-Add-BlockBreakBlockEvent.patch @@ -34,7 +34,7 @@ index 43c2b411115d3a8a0e47d3e2277789b2667897af..4d140bd83ca0e1554afad80ec4fc6186 if (world instanceof ServerLevel) { Block.getDrops(state, (ServerLevel) world, pos, blockEntity, entity, tool).forEach((itemstack1) -> { diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java -index e84501fdce7b94300b1f5d6d20e2db90b175454d..560797552799f7874133fd4aaf6e421609a54dbf 100644 +index 0c6b517196d48ba4384eac240b7e580adfdbc4d4..4973d75b26880e39d42b5ef533896f43a1f07cba 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java +++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java @@ -406,7 +406,7 @@ public class PistonBaseBlock extends DirectionalBlock { diff --git a/patches/server/0637-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch b/patches/server/0637-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch index 179f6e156598..b239d74e25a7 100644 --- a/patches/server/0637-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch +++ b/patches/server/0637-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch @@ -27,7 +27,7 @@ Co-authored-by: Zach Brown Co-authored-by: Madeline Miller diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java -index 560797552799f7874133fd4aaf6e421609a54dbf..b27cf7d27672ba9ff8ade84b5a8454b19b935607 100644 +index 4973d75b26880e39d42b5ef533896f43a1f07cba..e841fccb8f298ef692677583b468869f56dc722c 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java +++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java @@ -163,15 +163,15 @@ public class PistonBaseBlock extends DirectionalBlock { diff --git a/patches/server/0678-Add-TameableDeathMessageEvent.patch b/patches/server/0678-Add-TameableDeathMessageEvent.patch index 79f0ebc540e9..641b0b0e3757 100644 --- a/patches/server/0678-Add-TameableDeathMessageEvent.patch +++ b/patches/server/0678-Add-TameableDeathMessageEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add TameableDeathMessageEvent diff --git a/src/main/java/net/minecraft/world/entity/TamableAnimal.java b/src/main/java/net/minecraft/world/entity/TamableAnimal.java -index cd565d1a8dab8d45196e4d29cab3d93a3ca619eb..550c7f3435cc6c3180769e47f05bf693bdc380e3 100644 +index cd565d1a8dab8d45196e4d29cab3d93a3ca619eb..749ae54ee42229cb32ec5280bc59a88f74fde197 100644 --- a/src/main/java/net/minecraft/world/entity/TamableAnimal.java +++ b/src/main/java/net/minecraft/world/entity/TamableAnimal.java @@ -250,7 +250,12 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity { @@ -16,7 +16,7 @@ index cd565d1a8dab8d45196e4d29cab3d93a3ca619eb..550c7f3435cc6c3180769e47f05bf693 + // Paper start - Add TameableDeathMessageEvent + io.papermc.paper.event.entity.TameableDeathMessageEvent event = new io.papermc.paper.event.entity.TameableDeathMessageEvent((org.bukkit.entity.Tameable) getBukkitEntity(), io.papermc.paper.adventure.PaperAdventure.asAdventure(this.getCombatTracker().getDeathMessage())); + if (event.callEvent()) { -+ entityplayer.sendSystemMessage(this.getCombatTracker().getDeathMessage()); ++ entityplayer.sendSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.deathMessage())); + } + // Paper end - Add TameableDeathMessageEvent } diff --git a/patches/server/0683-Allow-changing-the-EnderDragon-podium.patch b/patches/server/0683-Allow-changing-the-EnderDragon-podium.patch index 0102f9445352..5cbce2b4ecc6 100644 --- a/patches/server/0683-Allow-changing-the-EnderDragon-podium.patch +++ b/patches/server/0683-Allow-changing-the-EnderDragon-podium.patch @@ -62,7 +62,7 @@ index a897c994423d7d624df6ff3a67789cc2436f0417..29f4acc2943ce009088c61bb32aed330 } diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java -index 2db996f3528c65f5d719cbcfb8ae587ff59c14c1..b8730a0fc759dbacc9b2e737c3e48d3ff9c5d824 100644 +index 2db996f3528c65f5d719cbcfb8ae587ff59c14c1..8e39cf181993ff284a2b0429577de0c307f3ef16 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java @@ -53,7 +53,7 @@ public class DragonHoldingPatternPhase extends AbstractDragonPhaseInstance { @@ -70,7 +70,7 @@ index 2db996f3528c65f5d719cbcfb8ae587ff59c14c1..b8730a0fc759dbacc9b2e737c3e48d3f private void findNewTarget(ServerLevel world) { if (this.currentPath != null && this.currentPath.isDone()) { - BlockPos blockPos = world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(this.dragon.getFightOrigin())); -+ BlockPos blockPos = world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, new BlockPos(this.dragon.getPodium())); // Paper - Allow changing the EnderDragon podium ++ BlockPos blockPos = world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()); // Paper - Allow changing the EnderDragon podium int i = this.dragon.getDragonFight() == null ? 0 : this.dragon.getDragonFight().getCrystalsAlive(); if (this.dragon.getRandom().nextInt(i + 3) == 0) { this.dragon.getPhaseManager().setPhase(EnderDragonPhase.LANDING_APPROACH); diff --git a/patches/server/0750-Add-EntityToggleSitEvent.patch b/patches/server/0750-Add-EntityToggleSitEvent.patch index 965b35e0f417..7bab6af93d78 100644 --- a/patches/server/0750-Add-EntityToggleSitEvent.patch +++ b/patches/server/0750-Add-EntityToggleSitEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add EntityToggleSitEvent diff --git a/src/main/java/net/minecraft/world/entity/TamableAnimal.java b/src/main/java/net/minecraft/world/entity/TamableAnimal.java -index 550c7f3435cc6c3180769e47f05bf693bdc380e3..e9e4d6fd69f9eec25a75b2610e15a19f8326f87b 100644 +index 749ae54ee42229cb32ec5280bc59a88f74fde197..f6a253e063f4a2cf78a036e44431806a0ba270d9 100644 --- a/src/main/java/net/minecraft/world/entity/TamableAnimal.java +++ b/src/main/java/net/minecraft/world/entity/TamableAnimal.java @@ -87,7 +87,7 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity { diff --git a/patches/server/0781-config-for-disabling-entity-tag-tags.patch b/patches/server/0781-config-for-disabling-entity-tag-tags.patch index d0d803196aec..f1526d5e31b9 100644 --- a/patches/server/0781-config-for-disabling-entity-tag-tags.patch +++ b/patches/server/0781-config-for-disabling-entity-tag-tags.patch @@ -5,10 +5,10 @@ Subject: [PATCH] config for disabling entity tag tags diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 9fe4027aa16d73d806f51a7c195a5cf0468ebba3..9be3f9b218b28fe8dde6321d8377232fbc634ee3 100644 +index e5dc6f868f090d1957306a6389d85cf9dbbc444d..ca9e63942f3cb8986456410b2a77aafc6541aad2 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -579,6 +579,16 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -578,6 +578,16 @@ public class EntityType implements FeatureElement, EntityTypeT if (minecraftserver != null && entity != null) { if (world.isClientSide || !entity.onlyOpCanSetNbt() || player != null && minecraftserver.getPlayerList().isOp(player.getGameProfile())) { diff --git a/patches/server/0789-Add-EntityFertilizeEggEvent.patch b/patches/server/0789-Add-EntityFertilizeEggEvent.patch index 5ba280ce9638..ea7e33d8b0e8 100644 --- a/patches/server/0789-Add-EntityFertilizeEggEvent.patch +++ b/patches/server/0789-Add-EntityFertilizeEggEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add EntityFertilizeEggEvent diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java -index ed7f5eb9b3b700c2f817d61ee0bf8a6952731510..8e91f930e19a91db44274e4ecd98841362867609 100644 +index ed7f5eb9b3b700c2f817d61ee0bf8a6952731510..9a9ecc3e2c176c6d9700c4c585250b9780b7629b 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java +++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java @@ -448,6 +448,10 @@ public class Turtle extends Animal { @@ -24,7 +24,7 @@ index ed7f5eb9b3b700c2f817d61ee0bf8a6952731510..8e91f930e19a91db44274e4ecd988413 if (getServerLevel((Level) this.level).getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { - this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), randomsource.nextInt(7) + 1, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer)); // Paper; -+ if (event.getExperience() > 0) this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), randomsource.nextInt(7) + 1, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer)); // Paper - Add EntityFertilizeEggEvent event ++ if (event.getExperience() > 0) this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), event.getExperience(), org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer)); // Paper - Add EntityFertilizeEggEvent event } } diff --git a/patches/server/0831-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch b/patches/server/0831-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch index 28dc555f0838..c481798890f8 100644 --- a/patches/server/0831-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch +++ b/patches/server/0831-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch @@ -19,7 +19,7 @@ index a65fba5621c067c453858efb7fee64cbee1e7916..1e77cce428d9e53142aaa2cf780b7f86 @Override diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java -index 08a3c7140867f339dd99a95094ed0fd8ff344fca..9d206bed5b982603f39bc1f70ae23ea38e4d9bc9 100644 +index 08a3c7140867f339dd99a95094ed0fd8ff344fca..a728dcbf956f108f01c966c7531449a506a14a87 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java @@ -120,7 +120,7 @@ public class WanderingTraderSpawner implements CustomSpawner { @@ -27,7 +27,7 @@ index 08a3c7140867f339dd99a95094ed0fd8ff344fca..9d206bed5b982603f39bc1f70ae23ea3 } - WanderingTrader entityvillagertrader = (WanderingTrader) EntityType.WANDERING_TRADER.spawn(world, blockposition2, EntitySpawnReason.EVENT, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit -+ WanderingTrader entityvillagertrader = (WanderingTrader) EntityType.WANDERING_TRADER.spawn(world, trader -> trader.setDespawnDelay(48000), blockposition2, EntitySpawnReason.EVENT, false, false, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBu // Paper - set despawnTimer before spawn events calledkkit ++ WanderingTrader entityvillagertrader = (WanderingTrader) EntityType.WANDERING_TRADER.spawn(world, trader -> trader.setDespawnDelay(48000), blockposition2, EntitySpawnReason.EVENT, false, false, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit // Paper - set despawnTimer before spawn events called if (entityvillagertrader != null) { for (int i = 0; i < 2; ++i) { diff --git a/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch b/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch index bc57e531f9ca..d3a68412bc69 100644 --- a/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch +++ b/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch @@ -48,10 +48,10 @@ index e9142414c7d247ae2a27c0bc9ea2be3bb8e3db16..1d66c35b1092b8101f0a803d8c087e5a this.entityData.set(Entity.DATA_POSE, pose); } diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 9be3f9b218b28fe8dde6321d8377232fbc634ee3..d036b02af0a4f63bd1e4e306f1ecd102b3d991fb 100644 +index ca9e63942f3cb8986456410b2a77aafc6541aad2..ccee69813597f45d382268bd1792a49722afebe9 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -659,9 +659,15 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -658,9 +658,15 @@ public class EntityType implements FeatureElement, EntityTypeT } public static Optional create(CompoundTag nbt, Level world, EntitySpawnReason reason) { diff --git a/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch b/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch index 0eede4fd44fb..74f4887dcee1 100644 --- a/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch +++ b/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch @@ -150,7 +150,7 @@ index 2bb2b36f793d25b6e49d1a72bb665cfa9f212730..63f02cdc67d9e88cc6998d0ae9d139c8 } } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index dbef230ae88ee1bfbc20ba53b534434c3ccac985..fb75b7f84575c42ab5dcb7e9c5659cecf439da90 100644 +index dbef230ae88ee1bfbc20ba53b534434c3ccac985..a0455f590d549343d6d8fd7991ba1b87a87acdb8 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -973,19 +973,25 @@ public class CraftEventFactory { @@ -179,7 +179,7 @@ index dbef230ae88ee1bfbc20ba53b534434c3ccac985..fb75b7f84575c42ab5dcb7e9c5659cec CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource); CraftWorld world = (CraftWorld) entity.getWorld(); - EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(world.getHandle(), damageSource.getEntity())); -+ EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(world.getHandle(), damageSource.getEntity())); // Paper - Restore vanilla drops behavior, victim.getExpReward(world.getHandle(), damageSource.getEntity())); ++ EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(world.getHandle(), damageSource.getEntity())); // Paper - Restore vanilla drops behavior populateFields(victim, event); // Paper - make cancellable Bukkit.getServer().getPluginManager().callEvent(event); diff --git a/patches/server/0906-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch b/patches/server/0906-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch index 8082b201b8dd..394a12efc224 100644 --- a/patches/server/0906-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch +++ b/patches/server/0906-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch @@ -39,7 +39,7 @@ index 4b9108e48d052919bca000ddb54f9bf4589c33e6..1c4ec3857c5c3ecf58f842292c280a4a this.teleportTo(to.getX(), to.getY(), to.getZ()); } else { diff --git a/src/main/java/net/minecraft/world/entity/TamableAnimal.java b/src/main/java/net/minecraft/world/entity/TamableAnimal.java -index e9e4d6fd69f9eec25a75b2610e15a19f8326f87b..7a4cb1d27bfe42f93525232892a59068560cd735 100644 +index f6a253e063f4a2cf78a036e44431806a0ba270d9..332ae836826270507110f1e0438aaa36d6e9deb5 100644 --- a/src/main/java/net/minecraft/world/entity/TamableAnimal.java +++ b/src/main/java/net/minecraft/world/entity/TamableAnimal.java @@ -314,7 +314,7 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity { diff --git a/patches/server/0908-Add-drops-to-shear-events.patch b/patches/server/0908-Add-drops-to-shear-events.patch index 899419ccb631..0ae1794dca13 100644 --- a/patches/server/0908-Add-drops-to-shear-events.patch +++ b/patches/server/0908-Add-drops-to-shear-events.patch @@ -306,7 +306,7 @@ index 9d416f775fa19ad1978c7c9c9e0d5bc16728879d..18dae37d65552077aa3825c76f433bbd }); } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index fb75b7f84575c42ab5dcb7e9c5659cecf439da90..89109bf9ad85b1859ce6ae0808ac0a1fb2cb6816 100644 +index a0455f590d549343d6d8fd7991ba1b87a87acdb8..e7749a3ef6289d73379649f2f76f4e4fdfac7a8b 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -1689,20 +1689,20 @@ public class CraftEventFactory { diff --git a/patches/server/0910-Validate-ResourceLocation-in-NBT-reading.patch b/patches/server/0910-Validate-ResourceLocation-in-NBT-reading.patch index ae571f6c51f0..5a6790a25df3 100644 --- a/patches/server/0910-Validate-ResourceLocation-in-NBT-reading.patch +++ b/patches/server/0910-Validate-ResourceLocation-in-NBT-reading.patch @@ -53,10 +53,10 @@ index 084935138b1484f3d96e99f4e5655a6c04931907..9e357abe13f55bd9ce3a1d5348bcf19a if (nbt.contains("LootTableSeed", 4)) { this.setLootTableSeed(nbt.getLong("LootTableSeed")); diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index d036b02af0a4f63bd1e4e306f1ecd102b3d991fb..97ad6cd38adbe8a7b2ea6e2a5a339bd67b81b5bd 100644 +index ccee69813597f45d382268bd1792a49722afebe9..e56050bef4a5aaa0fca17192dab4cf5e6a55fbae 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -690,7 +690,7 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -689,7 +689,7 @@ public class EntityType implements FeatureElement, EntityTypeT } public static Optional> by(CompoundTag nbt) { @@ -66,7 +66,7 @@ index d036b02af0a4f63bd1e4e306f1ecd102b3d991fb..97ad6cd38adbe8a7b2ea6e2a5a339bd6 @Nullable diff --git a/src/main/java/net/minecraft/world/entity/Leashable.java b/src/main/java/net/minecraft/world/entity/Leashable.java -index 1a6448cccf79a94013f9f44c3067d91da3da1f7e..06af888e4c3d9d01a462b487742b597184a7a8a6 100644 +index b7721ed97305d1cd6725935f965c2effc1bef5a1..5f880a8809f9c20bc8e8c0b2d48590bab02cf077 100644 --- a/src/main/java/net/minecraft/world/entity/Leashable.java +++ b/src/main/java/net/minecraft/world/entity/Leashable.java @@ -55,7 +55,13 @@ public interface Leashable { diff --git a/patches/server/0934-Fix-DamageSource-API.patch b/patches/server/0934-Fix-DamageSource-API.patch index 306d0de49204..f42e69a0af12 100644 --- a/patches/server/0934-Fix-DamageSource-API.patch +++ b/patches/server/0934-Fix-DamageSource-API.patch @@ -97,7 +97,7 @@ index aac1d620bf4cd1f18243f8c53cd32ab16fdeb616..5c0d64c70a94d20ff0e72aed490ef297 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java -index 8e91f930e19a91db44274e4ecd98841362867609..79e1e911333d4a009c0b4e2462b41a0c146b9a06 100644 +index 9a9ecc3e2c176c6d9700c4c585250b9780b7629b..d6605c15111dbdb6ee61a24822bc0a9aed7198d6 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java +++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java @@ -341,7 +341,7 @@ public class Turtle extends Animal { @@ -220,7 +220,7 @@ index 4c6e15535fa40aad8cf1920f392589404f9ba79c..35eb95ef6fb6a0f7ea63351e90741c48 } } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 89109bf9ad85b1859ce6ae0808ac0a1fb2cb6816..b0e7d1841d71e377d5ad596a22dfafb90d4f80cc 100644 +index e7749a3ef6289d73379649f2f76f4e4fdfac7a8b..96b901d07718d8926a2175925e867b4417c3947c 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -1092,7 +1092,7 @@ public class CraftEventFactory { diff --git a/patches/server/0941-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch b/patches/server/0941-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch index e76c0c9c8755..40895c886c0e 100644 --- a/patches/server/0941-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch +++ b/patches/server/0941-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch @@ -64,7 +64,7 @@ index 9917df070d9815b6915e4a0b022dfe4e5b7861e7..729c3d8279b13d21c65ede89ea50869b public co.aikar.timings.Timing getTiming() { if (timing == null) { diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java -index b27cf7d27672ba9ff8ade84b5a8454b19b935607..83bffe2ac011ed0cbd86149e3c803393d30a9e6e 100644 +index e841fccb8f298ef692677583b468869f56dc722c..4b51472502d08ea357da437afeb4b581979e9cff 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java +++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java @@ -216,6 +216,12 @@ public class PistonBaseBlock extends DirectionalBlock { diff --git a/patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch b/patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch index 186441aa4d43..ef4efc0ef7b6 100644 --- a/patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch +++ b/patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch @@ -7,7 +7,7 @@ Affect the falling stalactite damage type where the reduction is not applied like in Vanilla diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index b0e7d1841d71e377d5ad596a22dfafb90d4f80cc..659d38c90f20f744261190c451235dbca8352e38 100644 +index 96b901d07718d8926a2175925e867b4417c3947c..6c60bb4f4d1133844a4232df518c062216847fdc 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -1226,7 +1226,7 @@ public class CraftEventFactory { diff --git a/patches/server/0985-Optimize-Bit-Operations-by-inlining.patch b/patches/server/0985-Optimize-Bit-Operations-by-inlining.patch index b9547eb68c7d..02b75062fb66 100644 --- a/patches/server/0985-Optimize-Bit-Operations-by-inlining.patch +++ b/patches/server/0985-Optimize-Bit-Operations-by-inlining.patch @@ -7,7 +7,7 @@ Inline bit operations and reduce instruction count to make these hot operations faster diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java -index 0d51fb4be8b49e3b57c3c55aff6bcf13d5c78ddd..afbd1651cb29e95b5cc7474f986c52c29676fb8a 100644 +index 0d51fb4be8b49e3b57c3c55aff6bcf13d5c78ddd..a5dab9b1652ac76372d88316e2c165eed6317891 100644 --- a/src/main/java/net/minecraft/core/BlockPos.java +++ b/src/main/java/net/minecraft/core/BlockPos.java @@ -50,15 +50,17 @@ public class BlockPos extends Vec3i { @@ -20,7 +20,7 @@ index 0d51fb4be8b49e3b57c3c55aff6bcf13d5c78ddd..afbd1651cb29e95b5cc7474f986c52c2 - private static final long PACKED_Y_MASK = (1L << PACKED_Y_LENGTH) - 1L; - private static final long PACKED_Z_MASK = (1L << PACKED_HORIZONTAL_LENGTH) - 1L; + // Paper start - Optimize Bit Operations by inlining -+ private static final int PACKED_HORIZONTAL_LENGTH = 26; ++ public static final int PACKED_HORIZONTAL_LENGTH = 26; + public static final int PACKED_Y_LENGTH = 12; + private static final long PACKED_X_MASK = 67108863; + private static final long PACKED_Y_MASK = 4095; From 6df21e61afabedae7d4888ba5b4a2bb16fe1c264 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Mon, 21 Oct 2024 21:01:00 -0700 Subject: [PATCH 059/119] Start Moonrise update This is based on Moonrise's 1.21.2 branch, but this on 1.21.1 so some diffs cannot be applied (and this doesn't compile). See moonrise_update_1_21_2.txt for progress --- moonrise_update_1_21_2.txt | 43 + patches/server/0489-Improve-ServerGUI.patch | 647 +- .../server/1069-fixup-ConcurrentUtil.patch | 6177 +++++++ patches/server/1070-fixup-MC-Utils.patch | 87 + ...ble-implementation-for-blockstate-st.patch | 345 + ...ptimize-BlockPosition-helper-methods.patch | 64 + ...-fixup-Moonrise-optimisation-patches.patch | 14304 ++++++++++++++++ 7 files changed, 21344 insertions(+), 323 deletions(-) create mode 100644 moonrise_update_1_21_2.txt create mode 100644 patches/server/1069-fixup-ConcurrentUtil.patch create mode 100644 patches/server/1070-fixup-MC-Utils.patch create mode 100644 patches/server/1071-Revert-Custom-table-implementation-for-blockstate-st.patch create mode 100644 patches/server/1072-fixup-Optimize-BlockPosition-helper-methods.patch create mode 100644 patches/server/1073-fixup-Moonrise-optimisation-patches.patch diff --git a/moonrise_update_1_21_2.txt b/moonrise_update_1_21_2.txt new file mode 100644 index 000000000000..87e5b1546a64 --- /dev/null +++ b/moonrise_update_1_21_2.txt @@ -0,0 +1,43 @@ +reference comparison: +https://github.com/Tuinity/Moonrise/compare/6a2c6d27df11d417c1fefa749109d8e87599e8c2...03784b8c69c299db4af4f9984565e5752617d9dc +need to compare the diffs + + +add notes to moonrise patch: + - implemented fast palette patch + - implemented better bitstorage magic patch + - implemented blockstate property patch (replaced old paper one) + - implemented fluid patch + + +todo: +- double check that the misc changes commit on dev/1.21.2 moonrise is applied +- implement platformhooks +- move common diff from moonrise patch to mcutil patch +- delete old block state table patch +- in StateHolder, implement getNullableValue from blockstate_propertyaccess +- ChunkEntitySlices getChunkEntities(), callEntitiesLoadEvent(), callEntitiesUnloadEvent() +- in ChunkEntitySlices, implement modifySavedEntities() by copying from old +- in ChunkEntitySlices, implement unload() Entity.setRemoved() +- change PersistentEntitySectionManager addEntity chunk system call to have event=true +- implement PlayerChunkUnloadEvent in PlatformHooks#onChunkUnWatch +- make sure chunk pos is passed in PlatformHooks#postLoadProtoChunk +- implement chunk_system.ChunkMapMixin diff from reference +- implement chunk_system.ChunkStorageMixin diff from reference +- implement chunk_system.DistanceManagerMixin diff from reference +- implement chunk_system.GenerationChunkHolderMixin diff from reference +- implement chunk_system.LevelChunkMixin diff from reference +- implement chunk_system.LevelMixin diff from reference +- implement chunk_system.SectionStorageMixin diff from reference +- implement chunk_system.SerializableChunkDataMixin diff from reference +- implement chunk_system.ServerLevelMixin diff from reference +- implement chunk_tick_iteration +- implement collisions.ServerExplosionMixin diff from reference +- implement modifyEntityTrackingRange with org.spigotmc.TrackingRange.getEntityTrackingRange +- implement random_ticking.BiomeMixin diff from reference +- implement starlight.LevelLightEngineMixin diff from reference +- implement starlight.ThreadedLevelLightEngineMixin diff from reference +- implement starlight.ChunkSerializerMixin diff from reference +- implement starlight.SerializableChunkData$SectionData diff from reference +- implement starlight.SerializableChunkDataMixin diff from reference + diff --git a/patches/server/0489-Improve-ServerGUI.patch b/patches/server/0489-Improve-ServerGUI.patch index 8dde1d1a9bc4..48a151cd82f1 100644 --- a/patches/server/0489-Improve-ServerGUI.patch +++ b/patches/server/0489-Improve-ServerGUI.patch @@ -102,329 +102,330 @@ new file mode 100644 index 0000000000000000000000000000000000000000..8b924977b7886df9ab8790b1e4ff9b1c04a2af45 GIT binary patch literal 16900 -zcmaicV|1Ng^k&Q(Hn!T>_Kj`Zc4OO48rwD-Gw*(Xv_UIGaL4*?7e3`t5-R2lSh^xqd84Cs4}W^FDQn9zijsF13M{zVR~<`0dB -z;hww3Rk_uLO*yyZ^N(arMN#SjFcHEi60E_fZug`IjtJ^LVtno=lKj+Jze{_WszRIN1X*HUTCH>C_wc;+D)6YYT -z*RWmTUi`Puu_Uwkj6-qwu_Ue*kO&$%=o%J?6*rej_Ock3znkGIb6 -zWm&yS2Z9LS7slFgUx+?ilDgQBdj7`ruw|IVzJ@wV{&tD)G@SPTMW@9Wl5lcsuU~6` -z7raw|%Or|@Pnlh`7!!rA1H$`p;zz}+92Tp2bFmKDAL`nrC>)<{qBHso -zvJ6|o^vMxL?frh4XZ`3WdH7s_NI0p@{EElbnX*!yp;Vtx&K&w$&to`sW -z79>enm;xWhu;ZKKIN}-h!eBKZM6j$9~*Q(SlE*i_bHS0o#tPY -z5-j+ww|x>h9%`RLUixM!e%f0qVAe5GH83X6?!#^_j-M@lO@*-aD%NMF2;Hg^Wgh@}elrPA3o_&(- -zeNyws4es~%;K1o+pfG(Z!G-nFWzl7)ejRNxY?M~uI=I&MYuz@4>GLH*ptjlQJ`LYr -z*KIIVzBhKHIDwe`X2hc@gsdjzXxX%b<_#kc$vIHFi2)-XM1=fs(`g?0)M{lcJXwp< -zBgIdDXM&n-=+_%;1a?sE$oeN{r%w=8tFfAlQopAk -z%wrVN=r>)oZ0w7^M~Xi~qp6lEaABgF(ck7V3Un;@cg|ODuD7@fw~OZ;^TQV -z$&4AiUj}-4;o`6JV$Y4C2G -z8hVweUdzl78hWzD|&J_)oRr2JdJP -zA&lca);^P(q@hQb9-kqNXVo9An7Q3NoAtyRQw-@JUDD$oluryjE -z3{zzbZhStP-K;xw@Yxf-B=4h(p=4f`k8p2DH$>qQLPR!szD!2|vJ}J`C6=EoRwG^+ -z;`ZDv1SGVO+?IqSxpxSM^_V~@2E+~dZQdl+oz;TP1MX+XXwugMy?Z5AoZ7#R33Y@T -zM)w4;9L0szO3>6i#4fV3q49@wu&`zcvQ!d8!m*dpn&7pp0Y=;QbiyOzhC7)Ki7tDt -zXaIqysWqx53ZgHlO)|YRDG**$7&F{0a8VEECY`3;yx)F>2;4Xr&gC;Iqiqx;orWkF -z8xk0Ty-mK&z`^~Fbs#S;;Qd@1ZFJh4R`+H>Wx$xgn>^oka;w9~QfR>rS7lYHG?D#o -z6Jo`Qg_-DP -zX@kdURs~L5?afF*73QF!=HQ?vIysP;FNCMBfA*}*&%$eDHh5L|y~D=C^v8(wdtcYZ -z)8Q|56BuZ~3~KpF-oKg|5Uf@Ac15Z>sP<9hpm(E>^cgr8dMxGhn7mnWA+JPK+EGR; -zCfK+V1&Xi1M6CUFIA+oJqr(aF3W_=ph7h;IVlqq&xJ=d(CqczQwL>f*A$gJW_|iZw -z&>!^cGyI)UH(_%jFMta0ci8K;?^D#C4_`@%@wP6R4qvs8y@ecdj|*ia7Exg3*BpG4 -z%Dqav(-_hWolzv04-3Ygs)Z~U$`R?hQq2Is2`RWS%z4?!GF2CryzMjCEFg_Y%K+yz -zG8tm;0X{;XG5?BBT|pMZ296(fGUtoF_$Ryrso&s;Cc!g3a;pYOn-tjPvW+1)iAQ)I -zaPyG(wl0MZUqz_Z!4+oEh$t>QIaiZ+J1|fQdfugliOCAg+6D!~3<-k#gA8N#Rk3@5 -z&u3Yevetsi3m`sm2Ntt>FV(PfME~wR=LFu+2@Noy&wr###hgP3mjy&H03re#97OQ% -zsZ;NtktNoC?s@G44Num-@G1zw*?jMf)dA`SWJHyI-Lp=m -zyv8V97L8$~?>Sf(&Ee27TQvEf=-_%~EL56_n`*ZRVS`=4Ka4&HGjr9P8e3rf;8BK& -z&0s~H!Z|V-mPt9vUj?5&%Sa@;XK~`TS$ylgW4|1h&I!<9c6_zoDdR2)FLErHw%Sow -zwc_2ZKizcAMchMvZ^6OY8)uiUt&RwA(`3@dzgihQ1MSrNi;ruq-C+?oVa@U0x -z(>^4ei3Bedg+!LX52G(u@W4P&3sdv45%OawU(*aQat~OuEf?Hi6Zi>__qCd)nw0_j -zvUwA_6WQ5tnFsl_AZNz8L8L*=L4?0A>inj9l&C`AC71u=H -z?bu{Q_=al@1+|F&El|te2eQB@?#+g(D(LjFx>w=0X;CJ|CQc@tuin_)Rd$KH$Y9P9 -z${MAq+Ns2`>_SLAfKm9~%?U2bK6>hiDEbdUD#NMd$hR*wFx8TxWVY3Za -zM&tRPhR$htT-*KlZT-SGBy4YD;6aZfAz^Jt1`=ABifztn#D_;u)2WTa-Bo^EKL;=o -zDc6Ov2x3ybU1B6gkFjv-UvyFl^(EFkIb4ht2Z(*io4 -zW(6^Rp7OMxVh73mYH?bkbxgXB=+TL>U^8OY>=P$oXPkGAmF?6#80T -z+e?24uzuJC8?nCu`7)ef&Nu8x+`0%wOB9wmZ^(+|&$!T80~3uj?NRH)aNhf~#vN9e -zem1VW#bKd$SZ4ufS0-pzoJ%P7UWdT@8yg`1+kpYLV153t;UJy~P8@7sO+#{ePIXcSgw}v2XayA<>Jxh}D)tMOGRgJY0QEJs` -z{>aB;ssVeqKi-6L#(PnBpPuOu<4Rf*GWVk8BdMCd} -zc^_!LU3n2YWBEk1?0<%f@MkB;t#h0%&cixNCZn@Lft$eDVl6z=l@Ga}k<7cF5n!!o -zXet^Q3;AyG!j)+$=3U>7D5cEf)=YMZ)jSZ?)!6EoSa3kU!3W2Xn`K`PqR|ML`Ju!A)|K2`l1>ErJG>o*qIC72B&jHYe36od@P! -zi)qQ9Y7g*>N;Y4;sSLlPxvM;q-Tzw2m;Zx=x>{mk0;Ed5zA?Hb1FrDGc6-;m+iSFU -zc22aC&R^-iyw5vE$D?GWWo7A5o@@>d3_uD92sGM_-tlsdQ?ZbAnF4LsSxDj&0TFgO -zFbB*@;0<;Y0es>tB&~M12_up)gRS(Ce{seFR$9$~MC8~S%gCTV+2AIiH`gndEW2~H -z`z|RK5KuxIccy|!;Bkm8puw0EcWFE{ij71G*o4( -z0~y!3%z_nq1kdh3x<;XVQS{_v?Q3|H1so1Z#CL|Zm2Z&7-mTO?&1?U-oogOAE4Cm{ -z`d4o(XCnWH-J^hx&?7X^xHns&B`u2*skUy`s~w=0252bVaZy(}U?e5?u>fG!UbYaS -z4Gz$YBX|~|U$??YUR+zxw2g5F_OJB7viI^}qx|ouEswnc0o{D4T~~|912EVr9)4P& -zS=*@uBmgy>GC)sz_8A$Iga2y-R#LKP$zyVe7P=4Vrn@Q)Fp6mG;Nall=^07<{OPT~ -zPDD~5M}Py>^H&ikOMCrXaXjFMyNuyNg$gXaPOE4z3=$o3Jt(guFuvAQbA?*MR;Dx}r~+zsgJ -zzCtQ*$r?UAKNl$E39K|(pdcV17*;zU{VtG7{)QDicnC&XAit07AxkJs2xbNxkEh-l -ztI=-hZ#0{5e0{huHk5pMKFXUdk-_HT=8j~#**>ze%L-Vq--ELbc7OqlEqqgfDL$7| -z^zia3^m~7il#>&4bK{s6W!C%o9eQ_nw_LRXoq&)qk2e`~Carh!_+@C+^?4E@nB?8v -zrP(B~aF_-3_5wx4#3EgX2f|T2iDX6dBot9e+}zxz-+7y;fop?^#LWumnJ%(ER<|F> -z44(0)x_-m7iZI17bV#w5<;|{V>IZ-R+z|XI2d!L0M$z{_~PzI|b} -z_>I9TkwT-USfkDEyuoB7YJe7^SUeW*JCd>d31w)Viag>w -zE)Hcnu_U(A@CEh^w;UM0IVsDf+yNUB)lCpiM=a>2dMSVx95URpuHBLGh>h8fgM&77%eeba~6*@>lA8=;7iEw2QP4d^IvP -z8fpiWc?lq5kxp*C)nS|HY^i2ov(x?A!{1u(mk%xyJ_nmAsx{Zt=LV=Ta0-O}2|y4O -z5yIAhMw5|xp3lvw|Ps$0W*KZd^Wlj=W@{AaG=^es3_){Y~Jis`IYYiWN~ho|DLil1qRD5 -zN6xAlvXG=U-8`VKVHr!k-;5Bi)EfnJRTtvY$;jR$#e%~lxMV?xboY;JA{IT_^y}D0 -zw1mJ8tVoSO-(}absB6M8b$Zqe)Ok0$OkaA#I -z48@e8TAlv;PmB6dbP|{7<%qt@Ea>I;PRL4)=M`_G!A40Y$Xy1Mum)I0#!3<77H4)u -zI6c{)TUsy&o^*@2H9Bp>QJA#S8$`zN?+@z^IIQL|VxYEQfVw~Oc}Wq!FS`G2T=aDu -z-DMYe(1$x=331oN(i#yV%?Q)lcY`}FpGRp*74@@$fX%pE+dAGOh5QRhJ&mcaXOhk4 -zLi_pirw^Zws;d9n^#IE8T1ypZDX|crNABquU?iL2;Ql%4Vg5cNBt}OJdbLKnEi|`g2q%v70%eM&7 -z5gdFefu8Ix3n54MC -zW40SGT11ajrrm5AI24T?-2$|VMsU%VX}AMmt>Pr~B}#An{>%QG>_1FQYV^)CExzx2 -z&7E_9c!fpiCLci|F3H*eM2DQQRtQp4>V2RP=KX3ZVw#OXuFxj$VDmM&HQD{*dc7301976VQyI69%EFvxxn>qC&Lo-`%ImvM -zCv>AXKPcD26Z_;m`1pw)uF6Mp=RnShU^yM81!?jbl!v#-kSa#RLhSOG0?yp1YB6Jr -zW=GrO|0zIRSHiH?DYiO+$EpdMkwz#4I6V(J12-W0+dAo4J*?nDQrFI<*}a92Y%1bU -z`RC_4tyg7>R(8{ -zA8*g?PWv##WoF+p0bJe>whg#+(1_+A+)9HS$|n?k;(r=Le*vR;57rn)2& -zEkD8KBSZm#3Drt?t!*#s#>0+yUNysIKRg=t`KSOcSHieiUP0z8F_$tZ(ciPnq_o~@ -z%-{zhbs{i7 -zt~8q8%WO|MF(FE_ye*bl_-@NcA!S9$IMb6x0`e_oNF!hy5a)H^H)5)t(}ek4a1Nc~FF4@f;5aO%aB&3O%B8NuMWWCzYb`d> -zQ-&3)G|5M|pzcLy>pA(p=?3&XKn+v0^`HNsS?M0eb+60BxF|&Y{?>MI^x``)Vp}1V -z;<0N$BUc(0=p=y>zD3k_I~ -zMC>T|rn!T!wN%lqT@ -z&Afsj|04$m&CH2M?F|6yeqb+e`&JWTP^~~z(;c>5;z6RuFKe)%3j|YzeZB9c)5E08 -zvX9?L9%?PT7Vu(RAIXR}s*=I*@Qp<*vA{&7B2uwdBH$_I`33U5di9weG|3 -zx-Iy`1L`R>G-q<+w-{f5qc<7ls}^cT4Y^Qi+meHXFIDgqkt0wpdBZGY?LB+q9&o`T -zd18L5%R+44Ml^UNbEw58BXP#{+I#J1$;VGO`#6Grd<=RWgP+T+ktE6H^>C;%(}szj -zK;wt^oW!yG4Fz=zm4zKw@$Wdo`VJm=879kp$F&$uMP_qiKSB4L@SV)g55F9Rb=3ocrK>iqIRR9n!X0Do*Ldi{9M&^sg&T_TZz~>`tbXc$p%%BI% -z#MahUA?U0t#2ZA4_41*w&52#TXU^_G4)$#uGOnpIb{Gs?Bge_xP|beH;cUSBec^gk -zu;a`And#3j5LZ)LALL9lQ0{$A?tzx&K6M(;#M))7n&`7KTkT>KvjI7O4?mTa;X`81yn7WAir6 -z^Dv#2{~#3{X=5gyP*2v`3yoLJl)--n2rC2}*3n8(L~4ohHzT6QbyEu{!K3q#&p9Lp -z?3#RrZR0JWoh5V%Au%m2?uSB&RO!i99khjDd#7P;NaxJ<_f>mYXQOtXqBZifoWn1d5WC&hmG;&Gv(>!l)|)selJ-m-pz9Og@*rA -z%Xl~n+gHI_Rjy513U_dEaq-~ZLm%H7RpVbREoW=Zu*D?n%JFyy6(v}{RCOy -z>_wu--o5bv-4rRuWG0oN3a2+(f)C6nR0%>9HdI1mB`d{jE6Q4vSf>>{@~N-bGMc6~ -zn=1MB2?XIjZuOC!s@-pN5{60UUw-L4f1L-3Ohud?4)I$4Y&#w^A*ij(1$$3|Vskv} -z#YKCOBnHKh5QN8fd|k)wI{^HZj_1!`{L&>R(m@P^tYk*J)5>eCrio9{j>kWLDCGrM -z*O<)utCbjQiH>aHzD!~>SNyzV|B?uyizaR*!v`(g6N5ks=aSqWHk#wzbQOx2Ehc(>s -zfl`oSK+EzLOKDeK?n#pu;5qF1g-8bXyN##%K`x2R14CxOh8w&P-kz4U}>3Q=A& -zwAa>sCXe?|fR^Y+S9_jW;=!_GK`1Bc2HY6Y)*s}A##+#}239~LV&Q~wL&4n_6^@vW -z;nGUYJ$5-C#kJr2EtD&Ty$t-H)#GyT->}39LWB1gdo%LwqR8{YbRBL*-FCEc5iY{; -z#TpZ~y8yolNKuWi&enqz%<*)Y)j#ff)9q1ezkI|N7|zr3b=T|b>+m?)d% -zKJ;1@L~w8ZQn0MxZS*{ew-;Ohn^Jl!+U{m|QvgB~tai**t#d>0E=CMjN*SZ+36QnO -z4NrSN!Cd>9SLf?=!Hjh+ek}c}ND_U`vvi9(MS>7nGZ*lPm%4(7(bhfuTHod8y%;N{YO_KMV}N<7D)x5snD;XG -zzCOH#WK2$4mAvQWFCCZW#F8TRInJ+=$6eR`V~dES6+!6-=6lkVCHyCW^Bb-$@=b%3 -zi%hxQwAp^EOp|zR61~UikJsM89qE@P3@X5J>+K)hO6K`Z$80UqhLV&|mVt3wQ#G4H -zi4>T}s*jr9pkN+B@=LbuMW8^kzEFQde*yOdnXiUws9u#OD8dYzm?0F`qCm7pBCNNz -zOJB@PR!5?2&9Zw_Jg~i=TwmStKiYq1_@$ -zZKB*^u}y2o({7rV#Nl+8$2T5 -zthMF3X`+*;4Q-~&-*4NzrU=7>#}h=jB}<^tsAch7Ac~Vq;V7 -ziknpCHOP}_P8F&VE%6e`WG~EVa?$ra`knKZrYWbIZ_w@4vO+{B!(Pb&!YhY8pCfe= -zjxF8x>Zh3;#gw`fu})grVJcf=Ohg_Xc9m?(57$!NXQ#N%;Q{V}EjtmA$m<@Ie2(h2j9T2Xq=0<2R#daW&$ -z85=lCIqjn+?h$SF4u|?#DOOKg9>2c{9GSdlh{<(WR;Mb+bxH>u95roevUiqSmcdG* -zEL`{Qv+mA#hjLxuC*l?ROBgDsPYkDNU%;m09$2^ni=SVA=kS_) -z_h->URCbhQr89T-a-Gg9Dk?P`CT8-=f%@A28AYMmma&Ks#DNDsr^|eI%nHBQ0Nps* -z<{@u^G-9krSD|^{Vm?_nRkW_T!;E*n95To#4sxn;9FH2W%&T043S^Vg_Bk^^&J9*H -z=-^Zd6GYUG(CMkA?hy<&4Tc5fn4$3ys+ZiGw!07qHH1zPDzAJY;{8Oj#B1-LTAZ>D -zKqX)c%j0#o|H%z2zdkxYKaV6<&nEMgP`q%2&v+2dsa++rFeWoOnf$VkCAY6|8|kw{ -zdwe(maC?oeGlx#HVClH?)W&QZ`+=l3PIeQ%9cb~nWxJ9)YD|MPt`v?0-3bMcbZ<2Z -zG7xSnH{QoOr#C@?R{C$168|JMfCxcPAVuEhewgQpYO@AfbP3Fw+|Vi7h~L@$6ydj5 -zyf7_h9Rp$0Gii0mkT9xddqw>hIVCXV203~$D~swIj_)TV=zX)@-tK6Hb66mM;EywH -zsMV;{!i^8fvae3b)iz7_f6$4yU2i-b%Bh|o@eU2$RD^G(AtWlyl0^8dxd<9 -zCi_xU0%&wFugtmc%-uOk=xMY?lR%{7BQRZ~b8}1<=DQI)v2*#3|70VNVV*?SK4O}0 -z-HEICfCoyTwy@{F=Ac>4KISQEgQLDcj|>j}hzn(*RSn -zZw&u6!^Z2~7ae&u`+{IHYm_vxJJ@RRZ!LoCjQ2ecK6E;AqeyJZxfuAC -zaFBgBIQO4DawgA~vN)BCS%`;S38kn@9kWOTMq)$V$+z&4nDQvH*{(1#N58$C)v2#; -zJW|ch#FaXRBNNj6mX)HNV{_ScADWB7#Jn(Th}B15lvrI|-2fj-=SL1AY -zQrI&y#`tyxRIyenc$G7)m}|d;5&h;8q8?ap1~7v{vEXIAhojO|^XI$6=K!f+>;5yx -zJJXiq*Z?mW;Ak{?4<=)9$$a@6Q*=1_%}Nx&bGA3oqS%{I)k3y{#DALAzrPw)h(FU -zj}8a8Xte($dBpT -z_ZLeg50aO#zhmy?M*+dS#c4NyP>CZSyS+OOi>@2;)lr;&A$)(OEO;kV+bz6O57by -zyW>9>Ij2^Du|A83(r~$46%S7?Ancv(6R -zJK?TL+k$9p$KMJgY}hdrTzyS}0it==hvU?8YM**7M}l@-W{&s26~NM6 -z#U8(RCX-=6Lw%{$D&=aKSfE%aJ<__RASP1DaZcJPva<-yi3NH#t$OuNk6wlp&CD~1 -zanJ|7AhF;l{a^)Qhr_9Bo;2ZG8=}0whx#r7zZ6W`Fs5 -zJEbvhZVJVsORu$w4Y1HyT1E4?Vka&kS*mSpBuKM>OAT~3W;g7KLGzfQWF~QJ1)H6S -zFCOXwP_auqzKSygLBPB}EH;Q1gXb@Wm*lZWfM<8NWGZM_*$8Ze)0+^IpqCyco5T+P -z>!edzc-RMsx%H6~4%a*u{&6!V2Xf)f8oOKEEtBAhvI#TkSv+Ago-TMSQ(2q}=S0FP -zL(1v}1vp6Ya1@zfO!}Dq3ke|~@mmFXu2dHEQWpO$6X$;c8V@V*w>NACSkmSKF-THX -zXc85Wu2(uhx0b@}vaeA-YhO(oJ!8ZlugSxzOn{tnI7h@dCB`UVE~EEY_ww_|qDlb| -zQh0>qvDy{uar91x0J$!N&ch{3*B*?y730`NAZJT0IXU?T1Oo1Zc+QnB&!+ZYLh%_v -zV;)6DQs1sEzvoxu0r{lou-yG%CgwotYzFK>vqr!e>KRehvaz@y)fTge`_wgV2*|2H -zVl|vbxEx$3ymn~uGqN65%FYqJ<_)*Uqs49;KY2h*(Xa?Tk7AFfl-xf>irJoUyL*;0 -z19&1GQV*5Ni~#kTnaq0ymCiLjk_=0q&=&|cG{r57n*6NwV6zJl5K*ED&DsZy8iEL_rr -zgsLXr6cN9-S7dCo0TeKI3ByoGNNBIG{4b4m4=LB^FstU0B?!6TBZ1v~zn%e*Xk=B) -z@_rySE6iHcIxSfbe^sRAkjZKFfR!7A5uNa|Q%HSV{);)`X_I$=Rz#g9)RV -zjIuDE+A6IDHt@Noy^%sCnU|?kL3tCMU12QN7688MFeYr;%^{CT)BqX<4rY8gFNo(^2<+x6~@> -z0Y;8%xJK3sk3si!JoTyNPRqf>i>%mkw_b{g-~}-aAljQww_S1L53kdn=uMDZM5$#ndk -z&22o*u=b&^trc3UMGkzzrL*~$;t?gd{w8WCC+z$)6{fY`v4CL%;?|JZtR3}&oLz8* -zT?G#HsX)xAYvWho@h=pJpzsjcWp0%LD4s08onG)Nb4)MY=8K^XfVvcKVvP||0{idF -zr>Wx=dX&);ID@-|u5Y#BAa0c8rW_t)Xfo4c@By|jKCCPsr7DjJ6t;eTIrmF;CpM`~(ysWB=S@seY-cC;IYp7eGp3%$l} -z)oc?3jDrN<0qs>+yfj#>o^%eHp8`K^wUK{qUM_Xl#K;;VHK+>&$DqLQV1~BoxLuBrt&0}DAhEKn_^ER` -zz-29QNvC|8F%an87xNYKcn*LCu89T8nVkc&?~&O83)5GbY)slt*#=)i7s;A_C=2r7N7+fk`X1KngTDCyUEafq@X5m_z1=DeiD@Q38P{+Ou8AdwgrjC5 -zajlbj!7Ae^jZ~9GGnmvF%|dV*Siz7~1$lG}zFHP5%BV8TD09lQN!w79WRZ;`=PM(z -z0;YT`0PcRb5SM~SQ_OKjwTc~?W_G_IPe||U$;Um2U%fe+7X>%Nvy!xcXUbbT1miw0 -z=$X7_W&m0ay!h~`ae>C68mu@al*ia7R0saqO=sn$tE@ww372nWLhU^>%{WE>Eoln8 -zaeH(5Zly+xlW1Z@B{Z2HqS52V*oh`BC}k&quf19RS}N6$l#0qGWzl9DQkZ@85(#UMH4E) -z!&hPrOmR$HRF*}2C{e3A#U3h9d)gN68^|>O9=TO4Ga~u#5kl0}_*QP9IxEl~Ce;Vj -zS3zvyQ+p-TKYiV8z>J$akDBH=i$W7}&)8|aN%_17$7$H|;eKWRKgAtrMwoyE;#kJp -z>iJ{R+d4p$2q2;Y5EBQ7>@E&mk*MzVW>!EDsQ9Pd1Icl|=0d^U2HU!hP6MLe0bwp2 -zA=U!|OQM?{{^8dU?o^&w|I~Y5fw~zw)IT&*mzBRUy1Ljo^-=Z`fvN|N_JgxG~k*Hc%03VftQZkoi*AD{-11-bt2%}_=-R;7ZY`jOzsFyAEWb! -zVJNLPL#@4|8iv-c@m4Lu!^Uc7?VOsDWty>@T6^QN67|~9P?w&boWVpR2)d)gI@s*$ -zT0uPct)H#x^_Y(_q2El&g2<(pF8niAzCde(;c)XAp3awn@Z)3{qMO$l1?#O_cXL+a -zB+yS96Q;w{xIBw9%-h2xp$%a(D0`Noi$$31BbukCM_lu$4sG_+rWsH9U`eD0eY3t3 -z@`vkyB5OW$_NhyNPE(&_JPvYO1XVd%SiaJPVza|ZguGogD*p`OzJ!Odk4wR7o=G7; -zQFEN*_9WQcO`Vliy5G@VCnZ;Qb~fJ44e1$o^Tw=L_lA;Z-8Dw0CC}X_m5Q_J*xP61 -z2tVQGAnU9PA@k;{9QL{c=-~c_joC`W*8qxTI)7}foE-)SU;g6SD;S1P5oGCta0DrC -zGXz?khB$Fn{Ycwuk%t&RTyJ!Mz8mnC0U+AYu}PkaA-t-gE*25%;RVKNKyWz!scpu6 -zZDKFBX5S4#lCQK!Ip%UxMsP%cC4T!8d`;mo#M{(B)h;Ilk3UVA`-O^+JuQDuUnt-K -z=jEH2NuzvVs7mGT0rJ;Nz54;;pVk-{O`o<8h5~yAG9cx)%sJ+#d0-B8j!9{+{>1@9 -zYiz-m^g@6wE8^*umZD0JhIN!|&Ok-?2XhJ@B|oI&FfS^$rs90JhlZBoJW`e5b9j^- -zWO>uD9oB-o4QKEBn$akVeT1MeUX-s%#m~lPXZR!_h7SU~%Y_rx{QlrO`$o+{oUb!PIS+x5N -z+{O+YLa6?IE1#&A?RMZ&J}!O!vj>Os^y>J_BMi^Cu8;>FP)!5eagStg`4k8`f<9)s -zLv>uniXJHc5tD}2a*xO+UycHT8lGykAS#tq7H&?$Q|yXO#aH{77;M;}%#Rn*u_i#Q#=kFoCjB -zxM)O)sW@_wx=K{lJ|iyESH0iv9Nr111eP3eEA!SenTb%U12{RS*7qj0=;%^Kd#QiJ -ziYTEU=jFY{zWsSqmqmw<7L@5T1o7NxWhht`9gu$(b|QZnjVAE)D;lyC=>~hv=8piE3T9#-QVKCSaq-q&xr*zuRbfKtru+;Kkp5Si5+<6{tz}rp -zigZWmiiYYR#xdxCbhhJz=wN$k9zPcR8H;AJErv2><3*Bm51h&CEJlpT9yo5`1`w{pnaAJ%0k=ISmg0E -zo$J6^H1-w0!^WV5w|yx36dtal`WN}DGpD-gqYjDTfjIaLtR}xxCDSo6v=}KHRM^9@ -z&T;nw5x5ee(K3%Z3QQF%sMId_cIRpr&3g$f><9ZoX7X_c7g4f{y)mf(?;`TLI@jLv -z?N)ryzDJ)LsBZU+VnRH0X1E}KJ!}%#n_-hEY9w -z`8(=7Fd9^wGY;{_ggJK@ZR?yW!1!^^d;F^x%}=DG(7K8XMm$L~K*Np|t>vZmA5%Y| -zINrWxnZFq_J7&ksTGEluekfNRCX$8u^xk+?w8Q1iII^7LA8Wc=uh=>E34C14fN(+~ -zjb&LKSzG|ur8^cG=n*d|U)DK;5`-D7c>o{;1qb8{cYdL5^ll*Y29ag^ZWs(}{Dq?& -z7Vt6fu%BVSoqvD;RYW!I!KS^e-kCz_2@FvAByt<`2mpvxlE{aWp)% -z7->KZs4&!M+Z9|_;(QrbPRGNC2zLU&;bq*v@zaDlNR7 -zR!OB(0w7?XvMI3w1tc_A&fY$=RO&K>9q)K{?KeL9#X2nl`k!ouFF)XFC@Tui*%L4~ -zwNvTu3}=K5TH;uDS!^k3d+!l_hx$f?(hkYU(6NBYx@mz*Y6dZ7D@JF^5^p{aiT5zv -z;Xjc--#|sw407DGZz<4^FBXBq5F)zwTQ|65$~FTfyft2wOiY&QG(ydKoz#wa?YKny -z)9C@EX0c#XN}}K5dNFdMNo^+Os>0sS^c;E5Ky4zm)q;>J{J+z3sdUj)7tN@@gZSf7 -zJ|wiD$oI`e{Xe-gDV9P_(x}i7AaPVJn&m~NMi(84-RGbXy6@{lY?h66ze7!6Ee=i! -zInre-6PCHrI9+8v4+)Zge*esLVEy0*)t)o|)801Zf98hgQ=EZH2bpZ=)5NN_2yjw# -zP8Ewr(5WN{8DJpt*e!|G(gvZ5Pxywag$Agdns%%4+IH>|FMw9b -zKb<-v)*Cb*Ao~hb;B*`Ee&trZYBi`{$ru%gmKbuXcPNb3lD3H3Jimki7;BEFp{bxX -zFJ7Rk<~$d5(AGs1%w=$DDrj&3=?C4wX`U{m8^^=Z8R3YTB_A>ZAOkmldWl -zwo0ZyTNCB`dfUZA+chm*()HWtA2!JQ3>g${8%Vr% -zasf==&095e)fG}M%iIsk{PaQ>2|D59ppz^2pExvb9Ou9EI^`kN!0aXr*u3p0ex0b4 -z=AnHH#@v>`#o*LjN-yB0^^l)H2Nm=yD3|>1aNigv$f`s680kxF8B%d>SUG)YF0R~W -z$TI5rvll2~&q4RSwu3})*@1!~z4l}@NsY#MwV(2Y=hbLZh-ce*Eq3<#rZ -zxra}au9h@`-JaCDeW|)St?N40z`g~4rjZ?xu=?#W;cJyHNPXCV2DuxD%N1A2hAlFH -zwTJm(6XPn#dA&{dq>&yd{5Lp=pa<%$*em=~TdQ%rn_v#5`>I!IS>M^uNpl#N|wC@HMBcRTMT#SL;d7 -z<(&BuA6dLkkx|8fWw@PXzCeCBgDx@HJs@)L+j8y~gZ)7)${p-|O7{G? -z&|M6FI|A*^d_U+Of-3`+w(c~-YsQby|NH)g|G7xv|Nek^|Jex)g~z+)I0xPC0460S -LFIp>X81%mY^Bg|U +zcmaf)RZtymu&!}kXmDLfg1h^|-QC?ixG&s2I0Sch5AG1$U4m2?7EFMOsQs1p)$M^xuU52LS<5tyS|A0z!B~T1;5Y)8HZp +zUh9YE!*I`C!>au1!lt}?^7%)ymXa9F0E8%U6cA@Hs@r2|t2YjT?MMEK&sF!xR;P(1 +zJxFf8OgT_&`%_^18f74-j~9B>_v*F_4QG7P$=~I&{g0k-!dKZ;dhG_Yv84aKQ7`JU +zJ^ehid=1+b=_P#o97{5v??~H!^zyIS&U_=f-+Z&XS28Q#IuJUNE}ApzE+z8$!_(s%I3_!)=jTdGmXzz2p&3&czvSwVkj_PR|SM`xDjT-m<)@wFKtJ!fY +z+A9f&c$RQF&Z%Ui9@S9nRjlxMs@)Z5_OxNu^|5JS^tNFPeEv!Mp+fj^Yc}Scf482J +z_jv2_UYgabd?1AMePOH(|ApkUIjM`|sON7?4||4r>}#l#)Nj}LPNV67U-a5cAqgk9 +z4hA)b1i?G`_{?Is2NgH3=G*Y_oV4G*#y>w?4I7fSpx2h|vD&hsqdFVmofnVkNpM8o +zEDOkF7WVse0CrXXeH^X&Y+X5Ugeg(@8XVq_7ngH%kQ4q8to@(w`VD%+t{VjBlZzMA{89 +z;%$e2aiD==VT$}%!%lBbY3xicyog$jB!Djxd7vpR6bXArR{Oqv(5MfWsJg3Yy +zcUpf*M1f-z9ik)^?H|-}` +zxbJl0Xc<(adaW`;Xc^eA&$kJ4EZWH)dOO+mFzw;MBfNjA5<1ZP>E3RWzD|&L1WdK! +z2k&T-AdM3|);yD$reQ{x9G{_#6R5f}9%tdjf-W#_wS$qa(*X;ot*Gkja`g1Q_eN^= +z`0%;Ho3r-6zU-m(+)f%v8KxzXfn20UBXua$j&hd^L+a{0lv^F@IS92IL#!_sffCl2&zHVp_~j(J1np!W5n69+~xPAJ6}_zBa%4jtFt9W +z{@f*=wRJ|ZitBopGm@A{J`xa&M +z)PY`TF0^X2?f!}827nOWNuI-}Ne-gU_A_rT89Qjihq3d_{Ugx}ge|kRq}v@?<-}sM1htR5<=} +zI1L1)$lG(bP|&c#@>`Np6h0xGHe-S%SWq_O*_rH`M&)M5xj9Un#*HS!PqE5 +zISo-XF(NX8c$<8iK|uH&>qt?Q&-b}D+Tgr7t>MFp&WJTZFnPZ1>|RTVqu7iauEwTX +zVJi3CHpH3>2eq__Ox+k#@Bzl=K|7STdhX7MT{c8Ce71~q9Y&PXH}*iaRuCUgMZj4H +z)QyHub +z_qnc(rzc$MCNk878`Sofx_>n{BwDNL?TS=$RO_S6!R*Ey=`(aG@LbB{HGQ+@MqP=h +zu&0VvO0ab!36xlai&*>Xc+6_xPmdSo9TasQ3?*TY!)%lYzD(AZ0HWie+au=#fiLo& +zU+O6Y`-6UchQAZ*C2TI_f~f(2hrMt6KE)jP36+(ZZfle23Dx>Inkk_7xY0&pkp)+N +z%^^0b-mA7bkD<)a8%J{cvSRJ2S;}#v9g(doR}TQ3QGy%7T$YWkQuW{|T0eu$!D%Gg +zhIpru$xwR_h!F-%c~|@zigH-C2m=8{D8VNnCdFPc6Rfz(8f#dDmuUW@`u=TQn?l6ex-ha;(`` +zrS1uS-(@|j8cS+#fW*WdM9k{Fbp6f|!@JL%Gh}@yEWnTjE-DYfVpx0s5?hF9Qzi@Lf>~6Pm?DX{;HP^Q242(r1D1_=jrbppWF;PQk_!Ls +zS?3Zy6SOYNhA^`C9Gr`$aM+kF+PqIpNc~b)YOTag^;@K{!LHyR#-D?kKh>QZn&JHs +z(S}LQ;l-T8IWrlT$vDeig`Pf3fs);`cyZgTesw;vUk*#=1ZlB5zS``R@)U;`I^|DW +z?`Wu5^KI6hZo2(M-a~zF#>3kiX?zjyY=f@)xk3s24jF8WN!RqnV5qMC{5IS-?p~l` +z*Od<2Atam`NRWyKlq2%T>WdXRFci|p)_QD!{us*BG6#&@1J>-ygf`d(+Yt%AR?$|m +zG2&h}ZNhe;3iL&t-&Bo~bSQvwc_uqFF*q*u<%r&3Io&Jc +z8X3Bs8jXqH@NHmV7BRmCYCHHs=Nrep*-}>qojz9eD&96O%Es8n$%gaSnOL~VE%6i@ +z&N;!@pfy%G7dw?+2y1|uMDE?45uzNTNB_7>aX);UvtG>N2^CK4jXJOIypMJdF8LKU +zTYqIdp7&|wl19M2-A~xsFLDE9e-nocdK3)_YdtcQ)W%k7bx|ihJbIc=Z5ZyZ^yh9L +zz(%H87tSJzNkw!4yq5hajBkYU#kO&cksLk7!K-`GO(iyvT=U{|HBlNQU1VB|)w$-~ +z!`vE~Br`P8J<1%ly9{1OIZc%XlCTOPAdcit!jhpR;%=Zn+J^5sT)?#vtC4a+pY5iB +zJDz5Ru-Z>~+fH$VWPdd~FVQ(AT}O25HPC_wANYArttZij2ISLx>m75xSQO6+R*;0g +zmeuq!90F_}HX%kFZpuj4@q)SDa3k?+Bb2PrSZjTt%acFjLT3$4HPduPZ4Sfv?#~)_ +z*x>rvxpNnXh2P;_1YzBnVcqa9VK{mn1MhEaK>}|FhPXm?dB28(cqh2Ag&XIAnbGh%w38mufD688Vg0{`stk3i+PA1e~X7W%o(N09G +z(V+dK5Ra`6>fQc$6V4g$Mc;jTrbmt|ZcfPDi&luFxnBGk{2GGnMACo~C5VWy9A^BK +z%9O|VK>O{=o7e@%H==p}Gh9?4J3)S(^K@|@-bpGMlMM#a6u}N>;hDZ{$m0w+?{P+i +zv!bb`WN0Gnx5bB0s;!iJeK(?O@&xo_Yr==8dbs9N^gw0u(XKa5#%g4gLt%5d9^x&bUp+ +zI*CuQXb^F)LGcsTq00ke&-aZbA7b?Ow}kNZFJJuWYsoo#JJ +zd^|iHd;0^2Lk8)L=de&2-C9OWIvMMW>WH|w6peAk$qJ4MH%Wu;|h=~A6+4h{@J3knK0*pJ@vag9^60=vvWcI&Lb_(VX2 +zy)N7VOA=(g{REg_f)&_ekDo9i1vl8j0R0zl47}1}4kDqz)m%np1-97YCtxX^_8Eb1U&2>fjdHvFw8)9n=PT=mS{*wNJdpIN5Au>lfU5v4<160teocH-d>QHxOk-7@IW}47m1u$uA~w=(B0jA`kk+l2DCPaOxmP~ndvI$ +zYkm8H%IFn;s^>pUrvz6NLyr<`Ro3Korg8A+&kfO!G6vn2h>XJTf5yvnnk!b`Vn06= +zO|u}x(#U)>eRZq|c{Ep6$&^P+2{n)IUvm+$hJWpRp@dc$Pc5;};;;?#x;>0!Q&lV! +z`h5GsX89Y7O)`a6U8!1!!`XBAGrQC|6pr$y?Yi~{n@H;dTYvsSV}Guzrbl=`^4UoI +z8~S7M#L3iCl4D&LZY7p{pxhZgK`flMwzluNP~zogXL!BoNYnrwRFOn1!FLoBg%hgK +zT2%$)cYHjmbW$l?<>3q586J5ELJKn1OZfwK6zZEGypC8YxWSi_nBA+Z_&{j*y_tMb +z6C6(s<>8a1YQkTymwXrrI?Xm2Z(XHsp-_~6s;*Hc@MZxKw?mh=jIMvB--jM9zQDT5 +z_##%J(qN!>z*rOmA{Oc8*IOL7NzRt42R1uBo;?F>^ndx{qY!eko1xoqPknBbx`jeg +zBK1!If?!CHwgxmCjWr7V)0^wAxV{-lm1HGp@U)MCwN_MeX3LZ*jEL+Um3h1ahneA%41;uV#JudJYWnF4<o}yV;v9^YzeZ9DJPbxV +zCaJz8JMuzS|;y@^GISocc73^ZoFw_q)lcpJX%zS +z?3#&5BtAW>(BMlU0{VA<|F{5pf0gcm5ueT^9u0&(YN^<63?O&=!S{pn(` +zLg_%W?ebF_1IK2E8}fXKJRN7Sd1NEd3=zE}{Ff-55EeRtg*n1;E66aMQp_*vt;2W-BHy(2b;Flg4sLL8j`MDJ +zAbfu?@{0+Il12eRII46kiNKmt05>iU=h +z$)Irsw!hHw5wf7*gjxln_O`c8!(m4}pSsbqKLIVrd=!}5jW}+WPlzQ;+_e-& +z?Dy<48J&+h3*@LUmFxqzh_g>rb^`iEl)hiDf5($dZZJpaL!%i&d@Buf3+M~(|w0IKfQ +za3X0Srk%nLvE~Ab9|gBtt2_H<(fw_Zha@}t^K>=dbE+8{uYX2|#N=bmI)Wc;T*rwV +zwd5A@i2kamPB6hHF1AG?W!pUo_~vz+3wdlN<%QSGe!5}^qJ59h?#udS@qUf7 +zv-9ZWcl%ZgYEV62Ov?klP4Ypq+COVB +zzbpQbKJ4p#FTFlCeU?M~M)FWg!L^__)A~q8ym6&0c0f4_^d1Qsf;q;YQPHwFTKQaY +z@}^_vfdLrw7oSN5$O~22BEUPFgd#kF2FBsIH_Toz2Nw=v^=tZBu!NT|Lp7qp(fZ&&7q@7C0rFJD6; +z(%|4PztN>6GF#&@{I1tbNIIaALQ8ulFL8_Y1vGk-QMPKSZe0HpMtxgqkoct%kuq`w +z#x-}Cb*!ytPr?%+STtAMUu{{K-N%@g062$UWI7UOQm3=mc9wknbhD2qEj-!b^P +z%oYhuwx~lumz_3B^a7bYyyq-71@Fw*7ULPhNJocwr5CvLRsE<~sh>maF=R1p!hO** +zh+7MfH?17kb@`xEls`270@5OICG>$(UstdYt%lJ^wwiJK8I1@$5SE2?UF-^CtL8@; +zs4{#zGZBM@8f^QW&S9I{2Bl9>kdJkdQs6??R6c{5q%l*?6D-aNSM(>Zc4);q<1&7n +zVSb1AZyvYG&77Xtb`dpP1hGZw+U_-uc%-;be&gSUcbi*hJ9V!?LnI5O4d&1TOrlrE +z11&b|=uC!5&O5GB^zm!T#ncJ-bmy8|`YuXV_zy3)jPFmR0m +zFLy&N`z42~p5XU|+fn|GAIE2AfPi3JbxB>QXQ+7$3m_ug7v}~qfMAh#5*_)0mSKO^ +z)R>_thix1PNC=^T>X5@o5Ik^s!>_0nb%0+Qu?l@fMu||fRMI8(eq@a06~$a6goXp4 +zTc(!CW&GU`Z?7*~C%0!|`Po;Y-B>bq8(=^Pt0w>CW3cOKf|^OmN3o|I)zb~mlpR!VZRWgf3r$DjB6U@% +zJ!v9xOZ<+LBarT*ahaknq^miC#W^ANPQ%<$&RHDpEBCU_M(sbvsugC-mYh-fO{Sw9 +z2eEARzci;On#5;xRA{kHL-zc9^rxh(B6&XXZ*i0bo|+5(tR}B*i$>CjH@i(J`<5N< +zm*!QawcKB`2qVVWN|!2bmCj+qMz_>lyQe41Uc6GYo8|ZmgRouOWH<`fPtitAzEwsVe{gYe@!;OmfY1hA^J^GP2Zh7jc0#tW +zV;K{f-a2?ll{FjAo&kmu**_ByBXvrN+H7%pUgwrk*v>}T<%nfg$(O1#f`vAf;$Wwj +zK4OU>ekZ7*cXG`zK^{1Jk?6U1Z!$nXMaDUqNo}Oc<%5yn3pWZ=j1+|nlh9DXMmgJp +zw$>=#X^n__>Lz7RpGg`FbOM{jMF-I&Mx~Gtq{nwcJ*VwE0OFOdSNksknPO9!AjUy9a^u}; +zl{GfA#HVPd@8C*|vf;gcdLXrJL?MukrGr%c^ +z`dR^O=T^5*G@CU0fpX=d2?dv}l#Z}rvrURI+yrK9#ndWZg69>4-LW#tEa5!`s{Zgq +z8R@zhQOojaXAAXjJW6}a5>uV1LhgG$u5JQ_EBF0C=A-S5S2BuoH^CBy68!ST^VMKp +z5t!x0xnCI*Lk$t%?=aM?bAC5Sk&8&Qiu@hZj7DiJ;6#WZd1Z764c#+#;>O(U9%lfW +z>suxqZ)SVz&lYoFmEAcgM7u2vPU$2e-Hjzv>AJy1PeOk$DMk`K`~^i^seLl#HX2s@ +z&vS?_kECyji(-+eKdk1750r)$2U(RhTgkZT@l<$kC`GSck-TzG(h{pKG1aJhxkqgZ +zItykNw;mTU?xiP8Q;PAKW4yNPGkd;&0<^_8y4rHh6AzZ1@@Og1z$t3+RoVK`LOEWpvj)dqZ+bn-ZI_R@g2TDm +zUOXS$8{AioF8c*Kd%YqEKoqkyqA= +z;h>9H=F|lLAffO3sj^3_YLHV~t7o60Afgf+&g?fx9El~tAP}$YS=MFe#gI{HMPF+3A4XgD2y6V7pZ8*{ +zm8;APEKL9wC2F|aO=CXGJo^TSmQpb}X_X3Im%nsfn-Yr)Ip(;&N*#Ay_m3?ila&Xh +zA6V?kP!$WD1kP``H7hg@QY|w7?54~1UuB*oXqD_ePJg`i3GPV0EM`;%joWPh;8C{7 +zYdmIemNAl|da??P+nTE06i%eXK303w@_~!CLz4QEZFdnUm~0^2U*Dh4GePdBsTQhV +zsihVr6*e(LETK(_Y=c5vXJenfn3=4BLe-LG|E6?ccR#tlx)pG=|6cC;SaBt^!li5R +zcPgX&c2MsDL}~N-O+3=a0$|oiwZm$c)<&SyI4_0A@|JEcP=7FY3^?#Of0zNSfD^&A$%$p{mSW|9&i*6 +zj(_qDpxvBQ=^ptttH-vj$9~Va*80<33lpe5w3*6)d5BABGb>2&T7!J8KM%t$O}n*W +zJo+7yk8gR<_bN{XJ|u{lon5UfZc>HMFjulERk&KL*jqG{qadfz)xhuQcg|aymb_Y? +zVYhel3JJX|M+K*)DQMX1IZ`*_*vfscZkpLiT)9gL=cKs}uA(KzRP<4d8#RxOLcE#D +zJP9@OB>kt#JaeOXaqm4Kc^GYiehxcy4(-(f*^`-a9<3OAl0lXjMU1hK=(Co4O{$8%UM|E#&*;l(B?QsiT24bqlr*B{Z7V`VuFjMMHlGAysOT^==1z=5qZQ_2R +z-1qLb)#p6A6j}B#jg`CWg~=F5uJg4=mk4 +zMbEFlbNEc>OXUCT5piF*6@<3E+@D1YQ`=LOmdxBa$alJ^s;X9Vnwl%91RCi4CyD~~ +zEfY~;r~^+zF4y_)m=yu>0s3+B%|pI?8RS^ct^$kP#XRzE>S#R+#~GhIc~p)Cii4cW +z9H*m(D~n23;e5HIw0*7&$Qv-cSkS?#GB%E4^9a4Zdg>n0VB=s|P>wkUFR@1Py;++p +zX;6LW6tT+67ZSct6f1(Z{;9<&8!$Q%dsr@?heJCLyu$kE{QNwMcpba!S7M2R5q^_F +z1m`x@%z~KAD3f^-kF`7BW3BU>kYEeLw+hLBNDUxD$O}Z7ySX3c +zb)wd!i4k24wW1_C2@tbyw%f-8qhJmP`&caiZ`w$^LAjZS5Sn#m^9yX>OCkC~g$Cc7>RooBAs^cU +zIlTk#)OXQ82-Til1rliQ85sNCA>X3OzZ4b&8XPSua_&2S?i?lbG}vKCBGdB|nXS>g +zJ0*+o--w^syM8BpvQ@ycNTP2WG0U^*#8-MC0N=cB;m&`}!LXiv%vI8XM1O%D865l( +z{g6XRuw=jeOMjz9WK|@yzj!yA9i}KA0|SHG1bi12L)S{x7e=_kAN~FN)m7xbSP^arS9Rd{|t-bdQUEl`8{54zNMvQ +zmVu~1GPeH>P7JxwZV*CX5cIQzmo3E{siDMziZ%E7Tl9Q4KN4`#}D9_*vX?k}pO!=)gn7_4Bb4bJT +zqDaOnV(7U1_j;to@cwADU9mBc-@BdBUmAHSzyI{7YGVPi_y~b*r-e;$%CQnDe?9;8 +zfw~{4mSb>(|FgeRQE<@@i1>JZxfuACaFBgBIQO3(xsqo~Se?tnEhWOPgi|!6k69%H +zBXMEw6q@;gX1q%5b}P&*(QhwjwHm7%kJPg>aV1XSsKm6t<)rE6*j;x$hUQ|hu`kT) +zV+}ADC0AEh_W-HRr1Y}-%^FExK~@Y^t(ANZuuEJ`p#^k<`-MWnN77L2@X=9jV+>R; +zXOQ`#-WMm65hugihkOgXY4OID(WpNU{=B$ZDs8X^hCKKCdranviTkKK>$2J_;-Ga6 +z>WBEX7GD$0K(CoP7J96eYCwj_U5&HrOXJSWm=N0MQ^#7X5>(8zV6XiWLH3_ZhnV9@qF1Eb95#jw+CTK +zcnC_X6?w!ouwb8!t?ZeXbU*`_*tn=L1`tKaPq~o#XH-LT(pdaeEr(+5o7_BF^YP^9 +z=s=xqrRelm)Z^rj$VCV;RnXkG!NaMn=)gAL=kN77LMYwzIqFtY;-;Q!9U{UKkl*Z; +zxmwdAck=k)YYlsT2UM!0spVa*x7IFL)Qt{!?hIJJcZxQPc`eiw~~Oj@Tz_oM0xtx3Lb{5kxu +zyBD?uz>WN#g_E*U&crG80;MCX-DnFuJuz_nIeOw6$6c?&s+F|L2zU?5G!ekeS!llo +zFPgW-3Pcj`}O?5W?ab_h%Gy97f=v~(o +zy&qFFhNcAIGR5-l!~O!ti+&6tBv?y$VCZ!G*COZC^Rd=v3DD{VK&YZV`0rM0q-=5@nOTtcx@ +z-`GfyVTF_)=xoTY-xG)BHAl-#;@k>0Kap5G)B~X77JGh`U;(W#+Xleny2|+?3X~v9 +z@j4(Oa(GxV=hv@n1U4Y(PY6pg$c&Ot;)efq)~zTw>;uHy`pS!hYaNUHxEYhbgRg4R +z+}+}7o`g)4OPEQ|;tiYeawTA$%HmQyClOH{QqjoI$3uxnpv;6|Hoy*8NC^3e-^$N* +zqqby_w*0S5T>t%`@v?z_`@m;FByBE`COSJ7m_~uq^-Bim*HTzq_chCA9jeHpXN(2n +zwRqW7h)`1w=SY~Q#F+#wWc43wU)ql>D-{W#MMi*+Rc<(sqj$1IsI?*Vo~~JX4iGFY +zSjVn{Ia}(<$;mhGkK6li&$laGUX5+PgyS=U#yks+rN3QUeb1{R0P)Mr;duDNP0Yns +zOl80yG--mz(9cLJmrW%6skc}}J*KYlL*%B2MMfm>8W3{uoeA1tCC=;U0l+}4z>%rz1`1Gu3qlk(DUqGWSub-M#qTbUB+d9M069OLgJ6ct8Id?;aM)g-r9s^V6BrQ}Q;SCiP`udh7DC +zQX$nG;n1i3pom{#4@R?{E?z&>^3sL?I2rH<%HigVl9la73e4N^TR>PE}F +zsi3VDlCxI}2NOm!ndIQSbW~gNZ4rN(jki^a>Fbq! +zqTN5 +zzb`nx8&_h%Jrt7lQxR^o;6yE0jUGfj6BHagGKnEIbC?*Yeh-mN_p6 +zlPomN>R(3=k&0Ki-xElR=54S +ziifTvyozV0-H|T?}miG^F_wtBpw#IDTI~O&zZ=pp6zI7~U;(eX9v~ +z%_Rrklp$gbO-9{o@iq>QY$8+WLWjtqUprlw=!9l&&i<-B;;B?gDuUYF04x={Q|PYo +z11qyPuIW6^msVN_PE8KdAMXa}bHL6LC^fQ9sh369#H1cfF?JZ}v`b#V$&6F1HA?9- +z8rMp!9QAw;KUupJE(75s%Q_j;=twh?gcLwR?pti!=J%3LhEmj*cmxEL#xOjNHpVeK +zJkF%}PF#r=gweO>TUjCt`~eJ7()chG!YE-`x^-8vG;ltjSQ*{>Exm{gthe@Wqr_;) +z0wt5sLc;HhZgRcM=_rjYuGPk6qTcdMHcs}#u#-NnrJ>ijEn2POpi%bVAyH$%NC@JW +z!9x#~LZ0#)=w{X8oW39GR&eJl^`<7%yQQ1IMRYe1(f#2jGXHCzX6=QT%WeN8>DptC +zHdSdtJVzrAI(JAmUV3k0>(|f-Xp$15@*N%7K>n%=8xkhRkB3QAUtf=ah{(e3zoSSq +z_gFfN{zLz`jCqlr&;1O+r(+F_Z0oUu;MXftO1`Y +z9;O;>OCXbj;jbt_S7jVfllzmVYhq*#nMM~j1j#8VFg%#?vdErxSYKI2XR#z#^jrF| +z60VzCe$K!`P7W(fGZ`zDbu=Gj|Fluc!xb3b3?KS{Jm5T)ZILV)F5q8zrZN3x1!?Fl +zj24#65txQAH>pypq52gcF^Lw8LkW1LoMwVHld&c-soCEOJ`7#g5|?z#rkMgkK7BD? +zv5)5fIFMR6Y+7b6;Ou);_P~PlRc2e$)>HPum(WG>M&1%61LbYx=>T1OuOHP=A_2Ml +zUJa0_6*NB&eSM@;e}$dm67YWg_RVCo!)>o6Rkzh4GG20Rk8#RK+5)kj +zy-EvI3s#yE&SmNou7&*UrnmOiQ_-c!M98x?rSX}WW}0I7mNW&~u)Vo_w^FUmMKUp> +z8k)=i)!=z!;!K+sl(Lhz*Vd$PEuCsaMon#-vS>REEy6K+i5a(<$=x(75fa)xG@=%o +zR1GQOG=s!5g(EG{JieFH*|kCh7=CEGG~xLSIY@MDuIiAnc`G2Ge{P@B(m6G +z!ibqfOA9p9!7d%@C@Z6Oj!J3yF%OjokW8F{Y}gut?pbEsRm(4LL??RqN~(!1fsK#O +zx=08kW?ie)L(K_4s$=P~flB)?RT~0m>*m4)K}Eg&^ysOF8lN +zUHK0Q90oI&{$mRN4;~O7eZ2)RYWiOSNUxax118K@axIASH?!$hWNTeE-m< +z9|d2NgO0N~GYHc0yR$}HApgS_*(Si(CRarIKe5r*$mNd^46r(X7=_aLFxEIYsbgvH +znrzh|J#4IY*379ZTcw$}tG6{QE7PnE4Rz`3%NtHKG_U~aaSk@Sx>k@6ej8+~c|Yc1 +zO&By$u_ANpr;D`5D&%W#Fdl9`BhvdZ5`UZwLv{1Hpy9lA>ut_To&@^KV8eBInUrO5 +zh52}zCbS}L24&AucCm_(e?;?E_ef|R)nd$k+BOlW94v|UU~blRLjQ0ZP-4r2%|3Mn +z>o)c|#p9v2Mo^cLhvg|xC^b2rL@3y2qYKOs?@M}`_`2q==9(4=kTk_PZBIhX-PBrZ +zr~4n>by9I>XJ-@K+>o8|G;Pd^cW)?r)m~#|TJhd}QmeX{jlF$FjtCHM4zkU<60>Zs +z%Hys(I^Fbs!^Li)<*(mdMDF~twQ_bC9DMnUdoO<&F-3^A3(9GW4BH?t7v#5rXa(*RMsaFXpk@rOtgnql#(8*wa~=>H&U=;wN0Q<% +z=~0Qf+>{j>5oC?u{)Ajpd<^k1GgPzB2_X=HLz81#(ra*Wz}OO-za_H(wqrv+ +zz0y`v?a{P}lFJz=@BUy(A)pd~b{ghG$JJ7r@AlNxR+>kt6nYMil7}v99Ja?<@UZ3T +zeP1&kMRSM{5+R84Gc9j#ct$;ly+^es_n)lXhG>_EcB%`8iYCWLpCv8)3~8MaxHrGc +zWH36`!Flt6p(JJsBEPqrE&gHZ?iZtxyx?@fgPx*GS)go(Nf7>mW01|;SB);nF)3s-o4wF7D!)tc}@L$K1~NQb +z#Yr2Tunx+&wm$nlh2CtbCg8*b5`pf^Y+pukoQ>UqK#>9GQek~Po6Bh899xq^a4oaN +z9sDuzXNM=T^ExFYu?oyxI-}8y%D;slDQ*$`e5+$KKq!pF-*Qc6*L_WdXk^K$IEown +zc`-GIjJQlcjeh%cL}$EWcnajL%v-BuW@70M(BzzY-<$NJlWQg2rNIpwvZO(rx6c;G +z_UBD)7Cj+GP^Rw?)N_Nikx*qcIPWa%MBy?TL-6TWG;|5d3z|f%7il*;Ac9f={o-sOWXfH2ow& +z+F%t%kw65bbTBi=kaCFWiK~y^%2iyKohma@H`Ql2SmxhqN|;zqx3*C&8_FG(8wPqn +z80VlP%Gr)DvZLLlMf_OsXDo*4wm909tv4{~9yF8NS%e&sJ#dPsVWzk;(a?)XK|KjU +zmKml2h#A~>%-bFxM<7`wSX>`I?z8$Ca++fy%HqqV=8QYYD~bl^Hz_tBVxFF`f!?T6 +z!OC4>a={OOkbTFV#ew8k2GrG${kNo(rcXXA_NWUqI*@?8f!7jnu3$bUg%u}bhY5Q));;cCAc0gS +zHeTk{K!dAfJ6}@_zTLUn#qe2z2>ZdYkePg(!A+9v>R>`9$hU~PuED*xe7hANwC~xc +zzMc7YMmZr7Iy0P~w;nbL>dml8nV{FL;+xs}qjWkGV5~K1I6DPEC&#K9z5E?@9vBT9 +zvo#L&#*9687;Wd0D#-M4&3F8(7sFq)qrj$;8%`og3#@6+hSB^|^UtXtP#SOBvdY^G +znH{rdVJq%P=QxzF3KPx3etK`XD%|1rVH#OZ35YdYtyAh8`vg5MWd_yI4)jPAmo4j_!3e<(RzCocf`Y+$BAs988hq->eMY}S?z>|#t_c*3a#|wBAi{r! +z{dW0rO)!J3t~1!Um(@E{ATxo*eW!!k$}$1~;aQ@PPH8`A%_SDxVmA)U!Hw)$KXA7$ +zqdYbaY15D(b-OI$URl0+-TYf+!wm}Fwiu|ApRr6t288`7`y!ZbjuZgH`OF0cwYAez +zqSFt2_caUMO6L4Xk>1Be-C +zNHX4bgVd8eU&h^$7@$FnL%%Qp$e+fZ(4dAotr#y7!RrZ>u)-F!F&*jOE8kA5rqU|| +zkg!kLmDxaol3FWgZ=YGJwHYE#cf7j}8z24RotEJKC)?r64}@x}^89m-1nf0~ +z*_bz@JP+Ml3hd*HWuOR@sNVh74L-Sw?LaYKwKo+rvy}#|aFc!~jT1o|KFR)cI+)Bn +z7Gg?S>|0zfR!%gT?WBBV*!!8j6W>|lJse7F&5>m#;ooWbRQhP@izf8nK?3n;AClTI +z6#M340iQgXluMzeY19}<(0FQ=O$wq@ql-?Y9&<2A-S>4Nw#z1Z-(eOaL`iCMI&1sAHP4i1wfU%}{TH10ti=qYU +zDz0-eM;$$6p`VP-jrsMCM}MB&A!(m3WE#f9F_{oZS)?8^0-?^g11w23S(X*2v9^k* +zKU)$N`g+?WLff<~UDFNP<{vgF`ivNrY!#|!D3|%nvN;axyiKQdEH}n|UAvW!JH2@P +z6TzqIA6}zL<{b4pMQp)4ffz(REKD*y3@}3^xF7ui{>6upo0Tm&dOIrt&>JXx_VQrn +z?-nhZdK!u;m!%$urT+S%i$tA>aj?l1`%j#jH%{|kdYyAos^NAM25jH<6TePW$nes= +z1!HeZ;$v}XEv4u4(RnINU~U}A*?wwCqU9m|k--nxsx^vf5AeRn$pVh?0Mnuc`C!uLu2;Vg{7)wfw`U +zX;*Wa;BHUq-TwcZ=lb=LAJ!W;9=uX-aQwln)6svvPf%SQ<1JdhQIPpzpQJ_KDid+% +z!(xv_|7G`-+M9p4uk#~(Mx)cG<|di_EPs|%wf~Qb+;nQM%q9N4&z7FNB6Z+G+^+MR +zj)|=QD8BER{dSeRdtd$LH*1N?VC!qI+*y}-;)|d!tvt|0N +zm5Vlct%>!zH1~C#{PXnRXO%R17-p8ep7o3QUvcWms)tYH$`9TvKIF>&@BVzZ?VI=h +zpErH+ydwvGOs@R*Hs)&kpXVngrCvTXb;0-d@xj~oPM7_l|L;HY`3dlY6p$IBU;poR +XXyugpZ1#qMfq}u()z4*}Q$iB}^Bg|U literal 0 HcmV?d00001 diff --git a/patches/server/1069-fixup-ConcurrentUtil.patch b/patches/server/1069-fixup-ConcurrentUtil.patch new file mode 100644 index 000000000000..60d57a16567c --- /dev/null +++ b/patches/server/1069-fixup-ConcurrentUtil.patch @@ -0,0 +1,6177 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Mon, 21 Oct 2024 11:47:34 -0700 +Subject: [PATCH] fixup! ConcurrentUtil + + +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/collection/SRSWLinkedQueue.java b/src/main/java/ca/spottedleaf/concurrentutil/collection/SRSWLinkedQueue.java +deleted file mode 100644 +index 094eff418b4e3bffce020d650931b4d9e58fa9ed..0000000000000000000000000000000000000000 +--- a/src/main/java/ca/spottedleaf/concurrentutil/collection/SRSWLinkedQueue.java ++++ /dev/null +@@ -1,149 +0,0 @@ +-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.ConcurrentModificationException; +- +-/** +- * Single reader thread single writer thread queue. The reader side of the queue is ordered by acquire semantics, +- * and the writer side of the queue is ordered by release semantics. +- */ +-// TODO test +-public class SRSWLinkedQueue { +- +- // always non-null +- protected LinkedNode head; +- +- // always non-null +- protected LinkedNode tail; +- +- /* IMPL NOTE: Leave hashCode and equals to their defaults */ +- +- public SRSWLinkedQueue() { +- final LinkedNode dummy = new LinkedNode<>(null, null); +- this.head = this.tail = dummy; +- } +- +- /** +- * Must be the reader thread. +- * +- *

    +- * Returns, without removing, the first element of this queue. +- *

    +- * @return Returns, without removing, the first element of this queue. +- */ +- public E peekFirst() { +- LinkedNode head = this.head; +- E ret = head.getElementPlain(); +- if (ret == null) { +- head = head.getNextAcquire(); +- if (head == null) { +- // empty +- return null; +- } +- // update head reference for next poll() call +- this.head = head; +- // guaranteed to be non-null +- ret = head.getElementPlain(); +- if (ret == null) { +- throw new ConcurrentModificationException("Multiple reader threads"); +- } +- } +- +- return ret; +- } +- +- /** +- * Must be the reader thread. +- * +- *

    +- * Returns and removes the first element of this queue. +- *

    +- * @return Returns and removes the first element of this queue. +- */ +- public E poll() { +- LinkedNode head = this.head; +- E ret = head.getElementPlain(); +- if (ret == null) { +- head = head.getNextAcquire(); +- if (head == null) { +- // empty +- return null; +- } +- // guaranteed to be non-null +- ret = head.getElementPlain(); +- if (ret == null) { +- throw new ConcurrentModificationException("Multiple reader threads"); +- } +- } +- +- head.setElementPlain(null); +- LinkedNode next = head.getNextAcquire(); +- this.head = next == null ? head : next; +- +- return ret; +- } +- +- /** +- * Must be the writer thread. +- * +- *

    +- * Adds the element to the end of the queue. +- *

    +- * +- * @throws NullPointerException If the provided element is null +- */ +- public void addLast(final E element) { +- Validate.notNull(element, "Provided element cannot be null"); +- final LinkedNode append = new LinkedNode<>(element, null); +- +- this.tail.setNextRelease(append); +- this.tail = append; +- } +- +- protected static final class LinkedNode { +- +- protected volatile Object element; +- protected volatile LinkedNode 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 next) { +- ELEMENT_HANDLE.set(this, element); +- NEXT_HANDLE.set(this, next); +- } +- +- /* element */ +- +- @SuppressWarnings("unchecked") +- protected final E getElementPlain() { +- return (E)ELEMENT_HANDLE.get(this); +- } +- +- protected final void setElementPlain(final E update) { +- ELEMENT_HANDLE.set(this, (Object)update); +- } +- /* next */ +- +- @SuppressWarnings("unchecked") +- protected final LinkedNode getNextPlain() { +- return (LinkedNode)NEXT_HANDLE.get(this); +- } +- +- @SuppressWarnings("unchecked") +- protected final LinkedNode getNextAcquire() { +- return (LinkedNode)NEXT_HANDLE.getAcquire(this); +- } +- +- protected final void setNextPlain(final LinkedNode next) { +- NEXT_HANDLE.set(this, next); +- } +- +- protected final void setNextRelease(final LinkedNode next) { +- NEXT_HANDLE.setRelease(this, next); +- } +- } +-} +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/completable/CallbackCompletable.java b/src/main/java/ca/spottedleaf/concurrentutil/completable/CallbackCompletable.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6bad6f8ecc0944d2f406924c7de7e227ff1e70fa +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/completable/CallbackCompletable.java +@@ -0,0 +1,110 @@ ++package ca.spottedleaf.concurrentutil.completable; ++ ++import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; ++import ca.spottedleaf.concurrentutil.executor.Cancellable; ++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; ++import java.util.function.BiConsumer; ++ ++public final class CallbackCompletable { ++ ++ private static final Logger LOGGER = LoggerFactory.getLogger(CallbackCompletable.class); ++ ++ private final MultiThreadedQueue> 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; ++ } ++ ++ /** ++ * Adds a waiter that should only be completed asynchronously by the complete() calls. If complete() ++ * has already been called, returns {@code null} and does not invoke the specified consumer. ++ * @param consumer Consumer to be executed on completion ++ * @throws NullPointerException If consumer is null ++ * @return A cancellable which will control the execution of the specified consumer ++ */ ++ public Cancellable addAsynchronousWaiter(final BiConsumer 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 waiter; ++ while ((waiter = this.waiters.pollOrBlockAdds()) != null) { ++ this.completeWaiter(waiter, result, throwable); ++ } ++ } ++ ++ private void completeWaiter(final BiConsumer consumer, final T result, final Throwable throwable) { ++ try { ++ consumer.accept(result, throwable); ++ } catch (final Throwable throwable2) { ++ LOGGER.error("Failed to complete callback " + ConcurrentUtil.genericToString(consumer), throwable2); ++ } ++ } ++ ++ /** ++ * Adds a waiter that will be completed asynchronously by the complete() calls. If complete() ++ * has already been called, then invokes the consumer synchronously with the completed result. ++ * @param consumer Consumer to be executed on completion ++ * @throws NullPointerException If consumer is null ++ * @return A cancellable which will control the execution of the specified consumer ++ */ ++ public Cancellable addWaiter(final BiConsumer 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 waiter; ++ ++ private CancellableImpl(final BiConsumer waiter) { ++ this.waiter = waiter; ++ } ++ ++ @Override ++ public boolean cancel() { ++ return CallbackCompletable.this.waiters.remove(this.waiter); ++ } ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/completable/Completable.java b/src/main/java/ca/spottedleaf/concurrentutil/completable/Completable.java +index 46d1bd01542ebeeffc0006a5c585a50dbbbff907..365616439fa079017d648ed7f6ddf6950a691adf 100644 +--- a/src/main/java/ca/spottedleaf/concurrentutil/completable/Completable.java ++++ b/src/main/java/ca/spottedleaf/concurrentutil/completable/Completable.java +@@ -1,112 +1,737 @@ + package ca.spottedleaf.concurrentutil.completable; + +-import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; +-import ca.spottedleaf.concurrentutil.executor.Cancellable; + import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Validate; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; ++import java.lang.invoke.VarHandle; ++import java.util.concurrent.CompletableFuture; ++import java.util.concurrent.CompletionException; ++import java.util.concurrent.CompletionStage; ++import java.util.concurrent.Executor; ++import java.util.concurrent.ForkJoinPool; ++import java.util.concurrent.locks.LockSupport; + import java.util.function.BiConsumer; ++import java.util.function.BiFunction; ++import java.util.function.Consumer; ++import java.util.function.Function; ++import java.util.function.Supplier; + + public final class Completable { + + private static final Logger LOGGER = LoggerFactory.getLogger(Completable.class); ++ private static final Function DEFAULT_EXCEPTION_HANDLER = (final Throwable thr) -> { ++ LOGGER.error("Unhandled exception during Completable operation", thr); ++ return thr; ++ }; + +- private final MultiThreadedQueue> waiters = new MultiThreadedQueue<>(); +- private T result; +- private Throwable throwable; +- private volatile boolean completed; ++ public static Executor getDefaultExecutor() { ++ return ForkJoinPool.commonPool(); ++ } ++ ++ private static final Transform COMPLETED_STACK = new Transform<>(null, null, null, null) { ++ @Override ++ public void run() {} ++ }; ++ private volatile Transform completeStack; ++ private static final VarHandle COMPLETE_STACK_HANDLE = ConcurrentUtil.getVarHandle(Completable.class, "completeStack", Transform.class); ++ ++ private static final Object NULL_MASK = new Object(); ++ private volatile Object result; ++ private static final VarHandle RESULT_HANDLE = ConcurrentUtil.getVarHandle(Completable.class, "result", Object.class); + +- public boolean isCompleted() { +- return this.completed; ++ private Object getResultPlain() { ++ return (Object)RESULT_HANDLE.get(this); + } + +- /** +- * Note: Can only use after calling {@link #addAsynchronousWaiter(BiConsumer)}, as this function performs zero +- * synchronisation +- */ +- public T getResult() { +- return this.result; ++ private Object getResultVolatile() { ++ return (Object)RESULT_HANDLE.getVolatile(this); + } + +- /** +- * Note: Can only use after calling {@link #addAsynchronousWaiter(BiConsumer)}, as this function performs zero +- * synchronisation +- */ +- public Throwable getThrowable() { +- return this.throwable; ++ private void pushStackOrRun(final Transform push) { ++ int failures = 0; ++ for (Transform curr = (Transform)COMPLETE_STACK_HANDLE.getVolatile(this);;) { ++ if (curr == COMPLETED_STACK) { ++ push.execute(); ++ return; ++ } ++ ++ push.next = curr; ++ ++ for (int i = 0; i < failures; ++i) { ++ ConcurrentUtil.backoff(); ++ } ++ ++ if (curr == (curr = (Transform)COMPLETE_STACK_HANDLE.compareAndExchange(this, curr, push))) { ++ return; ++ } ++ push.next = null; ++ ++failures; ++ } + } + +- /** +- * Adds a waiter that should only be completed asynchronously by the complete() calls. If complete() +- * has already been called, returns {@code null} and does not invoke the specified consumer. +- * @param consumer Consumer to be executed on completion +- * @throws NullPointerException If consumer is null +- * @return A cancellable which will control the execution of the specified consumer +- */ +- public Cancellable addAsynchronousWaiter(final BiConsumer consumer) { +- if (this.waiters.add(consumer)) { +- return new CancellableImpl(consumer); ++ private void propagateStack() { ++ Transform topStack = (Transform)COMPLETE_STACK_HANDLE.getAndSet(this, COMPLETED_STACK); ++ while (topStack != null) { ++ topStack.execute(); ++ topStack = topStack.next; + } +- return null; + } + +- private void completeAllWaiters(final T result, final Throwable throwable) { +- this.completed = true; +- BiConsumer waiter; +- while ((waiter = this.waiters.pollOrBlockAdds()) != null) { +- this.completeWaiter(waiter, result, throwable); ++ private static Object maskNull(final Object res) { ++ return res == null ? NULL_MASK : res; ++ } ++ ++ private static Object unmaskNull(final Object res) { ++ return res == NULL_MASK ? null : res; ++ } ++ ++ private static Executor checkExecutor(final Executor executor) { ++ return Validate.notNull(executor, "Executor may not be null"); ++ } ++ ++ public Completable() {} ++ ++ private Completable(final Object complete) { ++ COMPLETE_STACK_HANDLE.set(this, COMPLETED_STACK); ++ RESULT_HANDLE.setRelease(this, complete); ++ } ++ ++ public static Completable completed(final T value) { ++ return new Completable<>(maskNull(value)); ++ } ++ ++ public static Completable failed(final Throwable ex) { ++ Validate.notNull(ex, "Exception may not be null"); ++ ++ return new Completable<>(new ExceptionResult(ex)); ++ } ++ ++ public static Completable supplied(final Supplier supplier) { ++ return supplied(supplier, DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public static Completable supplied(final Supplier supplier, final Function exceptionHandler) { ++ try { ++ return completed(supplier.get()); ++ } catch (final Throwable throwable) { ++ Throwable complete; ++ try { ++ complete = exceptionHandler.apply(throwable); ++ } catch (final Throwable thr2) { ++ throwable.addSuppressed(thr2); ++ complete = throwable; ++ } ++ return failed(complete); + } + } + +- private void completeWaiter(final BiConsumer consumer, final T result, final Throwable throwable) { ++ public static Completable suppliedAsync(final Supplier supplier, final Executor executor) { ++ return suppliedAsync(supplier, executor, DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public static Completable suppliedAsync(final Supplier supplier, final Executor executor, final Function exceptionHandler) { ++ final Completable ret = new Completable<>(); ++ ++ class AsyncSuppliedCompletable implements Runnable, CompletableFuture.AsynchronousCompletionTask { ++ @Override ++ public void run() { ++ try { ++ ret.complete(supplier.get()); ++ } catch (final Throwable throwable) { ++ Throwable complete; ++ try { ++ complete = exceptionHandler.apply(throwable); ++ } catch (final Throwable thr2) { ++ throwable.addSuppressed(thr2); ++ complete = throwable; ++ } ++ ret.completeExceptionally(complete); ++ } ++ } ++ } ++ + 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); ++ executor.execute(new AsyncSuppliedCompletable()); ++ } catch (final Throwable throwable) { ++ Throwable complete; ++ try { ++ complete = exceptionHandler.apply(throwable); ++ } catch (final Throwable thr2) { ++ throwable.addSuppressed(thr2); ++ complete = throwable; ++ } ++ ret.completeExceptionally(complete); ++ } ++ ++ return ret; ++ } ++ ++ private boolean completeRaw(final Object value) { ++ if ((Object)RESULT_HANDLE.getVolatile(this) != null || !(boolean)RESULT_HANDLE.compareAndSet(this, (Object)null, value)) { ++ return false; ++ } ++ ++ this.propagateStack(); ++ return true; ++ } ++ ++ public boolean complete(final T result) { ++ return this.completeRaw(maskNull(result)); ++ } ++ ++ public boolean completeExceptionally(final Throwable exception) { ++ Validate.notNull(exception, "Exception may not be null"); ++ ++ return this.completeRaw(new ExceptionResult(exception)); ++ } ++ ++ public boolean isDone() { ++ return this.getResultVolatile() != null; ++ } ++ ++ public boolean isNormallyComplete() { ++ return this.getResultVolatile() != null && !(this.getResultVolatile() instanceof ExceptionResult); ++ } ++ ++ public boolean isExceptionallyComplete() { ++ return this.getResultVolatile() instanceof ExceptionResult; ++ } ++ ++ public Throwable getException() { ++ final Object res = this.getResultVolatile(); ++ if (res == null) { ++ return null; ++ } ++ ++ if (!(res instanceof ExceptionResult exRes)) { ++ throw new IllegalStateException("Not completed exceptionally"); ++ } ++ ++ return exRes.ex; ++ } ++ ++ public T getNow(final T dfl) throws CompletionException { ++ final Object res = this.getResultVolatile(); ++ if (res == null) { ++ return dfl; ++ } ++ ++ if (res instanceof ExceptionResult exRes) { ++ throw new CompletionException(exRes.ex); ++ } ++ ++ return (T)unmaskNull(res); ++ } ++ ++ public T join() throws CompletionException { ++ if (this.isDone()) { ++ return this.getNow(null); ++ } ++ ++ final UnparkTransform unparkTransform = new UnparkTransform<>(this, Thread.currentThread()); ++ ++ this.pushStackOrRun(unparkTransform); ++ ++ boolean interuptted = false; ++ while (!unparkTransform.isReleasable()) { ++ try { ++ ForkJoinPool.managedBlock(unparkTransform); ++ } catch (final InterruptedException ex) { ++ interuptted = true; ++ } ++ } ++ ++ if (interuptted) { ++ Thread.currentThread().interrupt(); ++ } ++ ++ return this.getNow(null); ++ } ++ ++ public CompletableFuture toFuture() { ++ final Object rawResult = this.getResultVolatile(); ++ if (rawResult != null) { ++ if (rawResult instanceof ExceptionResult exRes) { ++ return CompletableFuture.failedFuture(exRes.ex); ++ } else { ++ return CompletableFuture.completedFuture((T)unmaskNull(rawResult)); ++ } ++ } ++ ++ final CompletableFuture ret = new CompletableFuture<>(); ++ ++ class ToFuture implements BiConsumer { ++ ++ @Override ++ public void accept(final T res, final Throwable ex) { ++ if (ex != null) { ++ ret.completeExceptionally(ex); ++ } else { ++ ret.complete(res); ++ } ++ } ++ } ++ ++ this.whenComplete(new ToFuture()); ++ ++ return ret; ++ } ++ ++ public static Completable fromFuture(final CompletionStage stage) { ++ final Completable ret = new Completable<>(); ++ ++ class FromFuture implements BiConsumer { ++ @Override ++ public void accept(final T res, final Throwable ex) { ++ if (ex != null) { ++ ret.completeExceptionally(ex); ++ } else { ++ ret.complete(res); ++ } ++ } ++ } ++ ++ stage.whenComplete(new FromFuture()); ++ ++ return ret; ++ } ++ ++ ++ public Completable thenApply(final Function function) { ++ return this.thenApply(function, DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable thenApply(final Function function, final Function exceptionHandler) { ++ Validate.notNull(function, "Function may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); ++ ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new ApplyTransform<>(null, this, ret, exceptionHandler, function)); ++ return ret; ++ } ++ ++ public Completable thenApplyAsync(final Function function) { ++ return this.thenApplyAsync(function, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable thenApplyAsync(final Function function, final Executor executor) { ++ return this.thenApplyAsync(function, executor, DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable thenApplyAsync(final Function function, final Executor executor, final Function exceptionHandler) { ++ Validate.notNull(function, "Function may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); ++ ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new ApplyTransform<>(checkExecutor(executor), this, ret, exceptionHandler, function)); ++ return ret; ++ } ++ ++ ++ public Completable thenAccept(final Consumer consumer) { ++ return this.thenAccept(consumer, DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable thenAccept(final Consumer consumer, final Function exceptionHandler) { ++ Validate.notNull(consumer, "Consumer may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); ++ ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new AcceptTransform<>(null, this, ret, exceptionHandler, consumer)); ++ return ret; ++ } ++ ++ public Completable thenAcceptAsync(final Consumer consumer) { ++ return this.thenAcceptAsync(consumer, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable thenAcceptAsync(final Consumer consumer, final Executor executor) { ++ return this.thenAcceptAsync(consumer, executor, DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable thenAcceptAsync(final Consumer consumer, final Executor executor, final Function exceptionHandler) { ++ Validate.notNull(consumer, "Consumer may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); ++ ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new AcceptTransform<>(checkExecutor(executor), this, ret, exceptionHandler, consumer)); ++ return ret; ++ } ++ ++ ++ public Completable thenRun(final Runnable run) { ++ return this.thenRun(run, DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable thenRun(final Runnable run, final Function exceptionHandler) { ++ Validate.notNull(run, "Run may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); ++ ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new RunTransform<>(null, this, ret, exceptionHandler, run)); ++ return ret; ++ } ++ ++ public Completable thenRunAsync(final Runnable run) { ++ return this.thenRunAsync(run, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable thenRunAsync(final Runnable run, final Executor executor) { ++ return this.thenRunAsync(run, executor, DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable thenRunAsync(final Runnable run, final Executor executor, final Function exceptionHandler) { ++ Validate.notNull(run, "Run may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); ++ ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new RunTransform<>(checkExecutor(executor), this, ret, exceptionHandler, run)); ++ return ret; ++ } ++ ++ ++ public Completable handle(final BiFunction function) { ++ return this.handle(function, DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable handle(final BiFunction function, ++ final Function exceptionHandler) { ++ Validate.notNull(function, "Function may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); ++ ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new HandleTransform<>(null, this, ret, exceptionHandler, function)); ++ return ret; ++ } ++ ++ public Completable handleAsync(final BiFunction function) { ++ return this.handleAsync(function, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable handleAsync(final BiFunction function, ++ final Executor executor) { ++ return this.handleAsync(function, executor, DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable handleAsync(final BiFunction function, ++ final Executor executor, ++ final Function exceptionHandler) { ++ Validate.notNull(function, "Function may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); ++ ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new HandleTransform<>(checkExecutor(executor), this, ret, exceptionHandler, function)); ++ return ret; ++ } ++ ++ ++ public Completable whenComplete(final BiConsumer consumer) { ++ return this.whenComplete(consumer, DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable whenComplete(final BiConsumer consumer, final Function exceptionHandler) { ++ Validate.notNull(consumer, "Consumer may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); ++ ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new WhenTransform<>(null, this, ret, exceptionHandler, consumer)); ++ return ret; ++ } ++ ++ public Completable whenCompleteAsync(final BiConsumer consumer) { ++ return this.whenCompleteAsync(consumer, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable whenCompleteAsync(final BiConsumer consumer, final Executor executor) { ++ return this.whenCompleteAsync(consumer, executor, DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable whenCompleteAsync(final BiConsumer consumer, final Executor executor, ++ final Function exceptionHandler) { ++ Validate.notNull(consumer, "Consumer may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); ++ ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new WhenTransform<>(checkExecutor(executor), this, ret, exceptionHandler, consumer)); ++ return ret; ++ } ++ ++ ++ public Completable exceptionally(final Function function) { ++ return this.exceptionally(function, DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable exceptionally(final Function function, final Function exceptionHandler) { ++ Validate.notNull(function, "Function may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); ++ ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new ExceptionallyTransform<>(null, this, ret, exceptionHandler, function)); ++ return ret; ++ } ++ ++ public Completable exceptionallyAsync(final Function function) { ++ return this.exceptionallyAsync(function, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable exceptionallyAsync(final Function function, final Executor executor) { ++ return this.exceptionallyAsync(function, executor, DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public Completable exceptionallyAsync(final Function function, final Executor executor, ++ final Function exceptionHandler) { ++ Validate.notNull(function, "Function may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); ++ ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new ExceptionallyTransform<>(checkExecutor(executor), this, ret, exceptionHandler, function)); ++ return ret; ++ } ++ ++ private static final class ExceptionResult { ++ public final Throwable ex; ++ ++ public ExceptionResult(final Throwable ex) { ++ this.ex = ex; + } + } + +- /** +- * Adds a waiter that will be completed asynchronously by the complete() calls. If complete() +- * has already been called, then invokes the consumer synchronously with the completed result. +- * @param consumer Consumer to be executed on completion +- * @throws NullPointerException If consumer is null +- * @return A cancellable which will control the execution of the specified consumer +- */ +- public Cancellable addWaiter(final BiConsumer consumer) { +- if (this.waiters.add(consumer)) { +- return new CancellableImpl(consumer); ++ private static abstract class Transform implements Runnable, CompletableFuture.AsynchronousCompletionTask { ++ ++ private Transform next; ++ ++ private final Executor executor; ++ protected final Completable from; ++ protected final Completable to; ++ protected final Function exceptionHandler; ++ ++ protected Transform(final Executor executor, final Completable from, final Completable to, ++ final Function exceptionHandler) { ++ this.executor = executor; ++ this.from = from; ++ this.to = to; ++ this.exceptionHandler = exceptionHandler; ++ } ++ ++ // force interface call to become virtual call ++ @Override ++ public abstract void run(); ++ ++ protected void failed(final Throwable throwable) { ++ Throwable complete; ++ try { ++ complete = this.exceptionHandler.apply(throwable); ++ } catch (final Throwable thr2) { ++ throwable.addSuppressed(thr2); ++ complete = throwable; ++ } ++ this.to.completeExceptionally(complete); ++ } ++ ++ public void execute() { ++ if (this.executor == null) { ++ this.run(); ++ return; ++ } ++ ++ try { ++ this.executor.execute(this); ++ } catch (final Throwable throwable) { ++ this.failed(throwable); ++ } ++ } ++ } ++ ++ private static final class ApplyTransform extends Transform { ++ ++ private final Function function; ++ ++ public ApplyTransform(final Executor executor, final Completable from, final Completable to, ++ final Function exceptionHandler, ++ final Function function) { ++ super(executor, from, to, exceptionHandler); ++ this.function = function; ++ } ++ ++ @Override ++ public void run() { ++ final Object result = this.from.getResultPlain(); ++ try { ++ if (result instanceof ExceptionResult exRes) { ++ this.to.completeExceptionally(exRes.ex); ++ } else { ++ this.to.complete(this.function.apply((T)unmaskNull(result))); ++ } ++ } catch (final Throwable throwable) { ++ this.failed(throwable); ++ } + } +- this.completeWaiter(consumer, this.result, this.throwable); +- return new CancellableImpl(consumer); + } + +- public void complete(final T result) { +- this.result = result; +- this.completeAllWaiters(result, null); ++ private static final class AcceptTransform extends Transform { ++ private final Consumer consumer; ++ ++ public AcceptTransform(final Executor executor, final Completable from, final Completable to, ++ final Function exceptionHandler, ++ final Consumer consumer) { ++ super(executor, from, to, exceptionHandler); ++ this.consumer = consumer; ++ } ++ ++ @Override ++ public void run() { ++ final Object result = this.from.getResultPlain(); ++ try { ++ if (result instanceof ExceptionResult exRes) { ++ this.to.completeExceptionally(exRes.ex); ++ } else { ++ this.consumer.accept((T)unmaskNull(result)); ++ this.to.complete(null); ++ } ++ } catch (final Throwable throwable) { ++ this.failed(throwable); ++ } ++ } + } + +- public void completeWithThrowable(final Throwable throwable) { +- if (throwable == null) { +- throw new NullPointerException("Throwable cannot be null"); ++ private static final class RunTransform extends Transform { ++ private final Runnable run; ++ ++ public RunTransform(final Executor executor, final Completable from, final Completable to, ++ final Function exceptionHandler, ++ final Runnable run) { ++ super(executor, from, to, exceptionHandler); ++ this.run = run; ++ } ++ ++ @Override ++ public void run() { ++ final Object result = this.from.getResultPlain(); ++ try { ++ if (result instanceof ExceptionResult exRes) { ++ this.to.completeExceptionally(exRes.ex); ++ } else { ++ this.run.run(); ++ this.to.complete(null); ++ } ++ } catch (final Throwable throwable) { ++ this.failed(throwable); ++ } + } +- this.throwable = throwable; +- this.completeAllWaiters(null, throwable); + } + +- private final class CancellableImpl implements Cancellable { ++ private static final class HandleTransform extends Transform { ++ ++ private final BiFunction function; ++ ++ public HandleTransform(final Executor executor, final Completable from, final Completable to, ++ final Function exceptionHandler, ++ final BiFunction function) { ++ super(executor, from, to, exceptionHandler); ++ this.function = function; ++ } + +- private final BiConsumer waiter; ++ @Override ++ public void run() { ++ final Object result = this.from.getResultPlain(); ++ try { ++ if (result instanceof ExceptionResult exRes) { ++ this.to.complete(this.function.apply(null, exRes.ex)); ++ } else { ++ this.to.complete(this.function.apply((T)unmaskNull(result), null)); ++ } ++ } catch (final Throwable throwable) { ++ this.failed(throwable); ++ } ++ } ++ } ++ ++ private static final class WhenTransform extends Transform { ++ ++ private final BiConsumer consumer; ++ ++ public WhenTransform(final Executor executor, final Completable from, final Completable to, ++ final Function exceptionHandler, ++ final BiConsumer consumer) { ++ super(executor, from, to, exceptionHandler); ++ this.consumer = consumer; ++ } ++ ++ @Override ++ public void run() { ++ final Object result = this.from.getResultPlain(); ++ try { ++ if (result instanceof ExceptionResult exRes) { ++ this.consumer.accept(null, exRes.ex); ++ this.to.completeExceptionally(exRes.ex); ++ } else { ++ final T unmasked = (T)unmaskNull(result); ++ this.consumer.accept(unmasked, null); ++ this.to.complete(unmasked); ++ } ++ } catch (final Throwable throwable) { ++ this.failed(throwable); ++ } ++ } ++ } ++ ++ private static final class ExceptionallyTransform extends Transform { ++ private final Function function; ++ ++ public ExceptionallyTransform(final Executor executor, final Completable from, final Completable to, ++ final Function exceptionHandler, ++ final Function function) { ++ super(executor, from, to, exceptionHandler); ++ this.function = function; ++ } ++ ++ @Override ++ public void run() { ++ final Object result = this.from.getResultPlain(); ++ try { ++ if (result instanceof ExceptionResult exRes) { ++ this.to.complete(this.function.apply(exRes.ex)); ++ } else { ++ this.to.complete((T)unmaskNull(result)); ++ } ++ } catch (final Throwable throwable) { ++ this.failed(throwable); ++ } ++ } ++ } ++ ++ private static final class UnparkTransform extends Transform implements ForkJoinPool.ManagedBlocker { ++ ++ private volatile Thread thread; ++ ++ public UnparkTransform(final Completable from, final Thread target) { ++ super(null, from, null, null); ++ this.thread = target; ++ } ++ ++ @Override ++ public void run() { ++ final Thread t = this.thread; ++ this.thread = null; ++ LockSupport.unpark(t); ++ } ++ ++ @Override ++ public boolean block() throws InterruptedException { ++ while (!this.isReleasable()) { ++ if (Thread.interrupted()) { ++ throw new InterruptedException(); ++ } ++ LockSupport.park(this); ++ } + +- private CancellableImpl(final BiConsumer waiter) { +- this.waiter = waiter; ++ return true; + } + + @Override +- public boolean cancel() { +- return Completable.this.waiters.remove(this.waiter); ++ public boolean isReleasable() { ++ return this.thread == null; + } + } + } +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/BaseExecutor.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/BaseExecutor.java +deleted file mode 100644 +index 18d646676fd022afd64afaac30ec1bd283a73b0e..0000000000000000000000000000000000000000 +--- a/src/main/java/ca/spottedleaf/concurrentutil/executor/BaseExecutor.java ++++ /dev/null +@@ -1,208 +0,0 @@ +-package ca.spottedleaf.concurrentutil.executor; +- +-import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; +-import java.util.function.BooleanSupplier; +- +-/** +- * Base implementation for an abstract queue of tasks which are executed either synchronously or asynchronously. +- * +- *

    +- * The implementation supports tracking task executions using {@link #getTotalTasksScheduled()} and +- * {@link #getTotalTasksExecuted()}, and optionally shutting down the executor using {@link #shutdown()} +- *

    +- * +- *

    +- * The base implementation does not provide a method to queue a task for execution, rather that is specified in +- * the specific implementation. However, it is required that a specific implementation provides a method to +- * queue a task or create a task. A queued task is one which will eventually be executed, +- * and a created task must be queued to execute via {@link BaseTask#queue()} or be executed manually via +- * {@link BaseTask#execute()}. This choice of delaying the queueing of a task may be useful to provide a task handle +- * which may be cancelled or adjusted before the actual real task logic is ready to be executed. +- *

    +- */ +-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()} +- *

    +- * 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. +- *

    +- *

    +- * 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. +- *

    +- *

    +- * Note: Interruptions to the the current thread have no effect. Interrupt status is also not affected by this call. +- *

    +- * +- * @throws IllegalStateException If the current thread is not allowed to wait +- */ +- public default void waitUntilAllExecuted() throws IllegalStateException { +- long failures = 1L; // start at 0.25ms +- +- while (!this.haveAllTasksExecuted()) { +- Thread.yield(); +- failures = ConcurrentUtil.linearLongBackoff(failures, 250_000L, 5_000_000L); // 500us, 5ms +- } +- } +- +- /** +- * Executes the next available task. +- * +- * @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}. +- *

    +- * WARNING: This function is not suitable for waiting until a deadline! +- * Use {@link #executeUntil(long)} or {@link #executeConditionally(BooleanSupplier, long)} instead. +- *

    +- */ +- 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 >= 0}. +- */ +- 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 < 0L) && !condition.getAsBoolean() && (System.nanoTime() - deadline < 0L)) { +- 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 >= 0}. +- */ +- public default void executeUntil(final long deadline) { +- long failures = 0; +- while (System.nanoTime() - deadline < 0L) { +- 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. +- *

    +- * This operation is atomic with respect to other shutdown calls +- *

    +- *

    +- * After this call has completed, regardless of return value, this queue will be shutdown. +- *

    +- * +- * @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 +- * @see #isShutdown() +- */ +- 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 the tasks scheduled have been executed. +- * @return Returns whether this queue has shut down. +- * @see #waitUntilAllExecuted() +- */ +- public default boolean isShutdown() { +- return false; +- } +- +- /** +- * Task object returned for any {@link BaseExecutor} scheduled task. +- * @see BaseExecutor +- */ +- 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. +- *

    +- * Exceptions thrown from the runnable will be rethrown. +- *

    +- * +- * @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/PrioritisedExecutor.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/PrioritisedExecutor.java +new file mode 100644 +index 0000000000000000000000000000000000000000..17cbaee1e89bd3f6d905e640d20d0119ab0570a0 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/PrioritisedExecutor.java +@@ -0,0 +1,271 @@ ++package ca.spottedleaf.concurrentutil.executor; ++ ++import ca.spottedleaf.concurrentutil.util.Priority; ++ ++public interface PrioritisedExecutor { ++ ++ /** ++ * Returns the number of tasks that have been scheduled are pending to be scheduled. ++ */ ++ public long getTotalTasksScheduled(); ++ ++ /** ++ * Returns the number of tasks that have been executed. ++ */ ++ public long getTotalTasksExecuted(); ++ ++ /** ++ * Generates the next suborder id. ++ * @return The next suborder id. ++ */ ++ public long generateNextSubOrder(); ++ ++ /** ++ * Executes the next available task. ++ *

    ++ * If there is a task with priority {@link Priority#BLOCKING} available, then that such task is executed. ++ *

    ++ *

    ++ * If there is a task with priority {@link Priority#IDLE} available then that task is only executed ++ * when there are no other tasks available with a higher priority. ++ *

    ++ *

    ++ * If there are no tasks that have priority {@link Priority#BLOCKING} or {@link Priority#IDLE}, then ++ * this function will be biased to execute tasks that have higher priorities. ++ *

    ++ * ++ * @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; ++ ++ /** ++ * Prevent further additions to this executor. Attempts to add after this call has completed (potentially during) will ++ * result in {@link IllegalStateException} being thrown. ++ *

    ++ * This operation is atomic with respect to other shutdown calls ++ *

    ++ *

    ++ * After this call has completed, regardless of return value, this executor will be shutdown. ++ *

    ++ * ++ * @return {@code true} if the executor was shutdown, {@code false} if it has shut down already ++ * @see #isShutdown() ++ */ ++ public boolean shutdown(); ++ ++ /** ++ * Returns whether this executor has shut down. Effectively, returns whether new tasks will be rejected. ++ * This method does not indicate whether all the tasks scheduled have been executed. ++ * @return Returns whether this executor has shut down. ++ */ ++ public boolean isShutdown(); ++ ++ /** ++ * Queues or executes a task at {@link Priority#NORMAL} priority. ++ * @param task The task to run. ++ * ++ * @throws IllegalStateException If this executor 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 PrioritisedTask queueTask(final Runnable task); ++ ++ /** ++ * Queues or executes a task. ++ * ++ * @param task The task to run. ++ * @param priority The priority for the task. ++ * ++ * @throws IllegalStateException If this executor 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 queueTask(final Runnable task, final Priority priority); ++ ++ /** ++ * Queues or executes a task. ++ * ++ * @param task The task to run. ++ * @param priority The priority for the task. ++ * @param subOrder The task's suborder. ++ * ++ * @throws IllegalStateException If this executor 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 queueTask(final Runnable task, final Priority priority, final long subOrder); ++ ++ /** ++ * Creates, but does not queue or execute, a task at {@link Priority#NORMAL} priority. ++ * @param task The task to run. ++ * ++ * @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 PrioritisedTask createTask(final Runnable task); ++ ++ /** ++ * Creates, but does not queue or execute, a task at {@link Priority#NORMAL} priority. ++ * ++ * @param task The task to run. ++ * @param priority The priority for the task. ++ * ++ * @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 createTask(final Runnable task, final Priority priority); ++ ++ /** ++ * Creates, but does not queue or execute, a task at {@link Priority#NORMAL} priority. ++ * ++ * @param task The task to run. ++ * @param priority The priority for the task. ++ * @param subOrder The task's suborder. ++ * ++ * @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 createTask(final Runnable task, final Priority priority, final long subOrder); ++ ++ public static interface PrioritisedTask extends Cancellable { ++ ++ /** ++ * Returns the executor associated with this task. ++ * @return The executor associated with this task. ++ */ ++ public PrioritisedExecutor getExecutor(); ++ ++ /** ++ * Causes a lazily queued task to become queued or executed ++ * ++ * @throws IllegalStateException If the backing executor has shutdown ++ * @return {@code true} If the task was queued, {@code false} if the task was already queued/cancelled/executed ++ */ ++ public boolean queue(); ++ ++ /** ++ * Returns whether this task has been queued and is not completing. ++ * @return {@code true} If the task has been queued, {@code false} if the task has not been queued or is marked ++ * as completing. ++ */ ++ public boolean isQueued(); ++ ++ /** ++ * 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. ++ *

    ++ * Exceptions thrown from the runnable will be rethrown. ++ *

    ++ * ++ * @return {@code true} if this task was executed, {@code false} if it was already marked as completed. ++ */ ++ public boolean execute(); ++ ++ /** ++ * Returns the current priority. Note that {@link Priority#COMPLETING} will be returned ++ * if this task is completing or has completed. ++ */ ++ public 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 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 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 Priority priority); ++ ++ /** ++ * Returns the suborder id associated with this task. ++ * @return The suborder id associated with this task. ++ */ ++ public long getSubOrder(); ++ ++ /** ++ * Sets the suborder id associated with this task. Ths function has no effect when this task ++ * is completing or is completed. ++ * ++ * @param subOrder Specified new sub order. ++ * ++ * @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 current suborder is the same as the new sub order. ++ */ ++ public boolean setSubOrder(final long subOrder); ++ ++ /** ++ * Attempts to raise the suborder to the suborder specified. ++ * ++ * @param subOrder Specified new sub order. ++ * ++ * @return {@code false} if the current task is completing, {@code true} if the suborder was raised to the ++ * specified suborder or was already at the specified suborder or higher. ++ */ ++ public boolean raiseSubOrder(final long subOrder); ++ ++ /** ++ * Attempts to lower the suborder to the suborder specified. ++ * ++ * @param subOrder Specified new sub order. ++ * ++ * @return {@code false} if the current task is completing, {@code true} if the suborder was lowered to the ++ * specified suborder or was already at the specified suborder or lower. ++ */ ++ public boolean lowerSubOrder(final long subOrder); ++ ++ /** ++ * Sets the priority and suborder id associated with this task. Ths function has no effect when this task ++ * is completing or is completed. ++ * ++ * @param priority Priority specified ++ * @param subOrder Specified new sub order. ++ * @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 current priority and suborder are the same as ++ * the parameters. ++ */ ++ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder); ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/queue/PrioritisedTaskQueue.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/queue/PrioritisedTaskQueue.java +new file mode 100644 +index 0000000000000000000000000000000000000000..edb8c6611bdc9aced2714b963e00bbb7829603d2 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/queue/PrioritisedTaskQueue.java +@@ -0,0 +1,454 @@ ++package ca.spottedleaf.concurrentutil.executor.queue; ++ ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import java.lang.invoke.VarHandle; ++import java.util.Comparator; ++import java.util.Map; ++import java.util.concurrent.ConcurrentSkipListMap; ++import java.util.concurrent.atomic.AtomicBoolean; ++import java.util.concurrent.atomic.AtomicLong; ++ ++public final class PrioritisedTaskQueue implements PrioritisedExecutor { ++ ++ /** ++ * Required for tie-breaking in the queue ++ */ ++ private final AtomicLong taskIdGenerator = new AtomicLong(); ++ private final AtomicLong scheduledTasks = new AtomicLong(); ++ private final AtomicLong executedTasks = new AtomicLong(); ++ private final AtomicLong subOrderGenerator = new AtomicLong(); ++ private final AtomicBoolean shutdown = new AtomicBoolean(); ++ private final ConcurrentSkipListMap tasks = new ConcurrentSkipListMap<>(PrioritisedQueuedTask.COMPARATOR); ++ ++ @Override ++ public long getTotalTasksScheduled() { ++ return this.scheduledTasks.get(); ++ } ++ ++ @Override ++ public long getTotalTasksExecuted() { ++ return this.executedTasks.get(); ++ } ++ ++ @Override ++ public long generateNextSubOrder() { ++ return this.subOrderGenerator.getAndIncrement(); ++ } ++ ++ @Override ++ public boolean shutdown() { ++ return !this.shutdown.getAndSet(true); ++ } ++ ++ @Override ++ public boolean isShutdown() { ++ return this.shutdown.get(); ++ } ++ ++ public PrioritisedTask peekFirst() { ++ final Map.Entry firstEntry = this.tasks.firstEntry(); ++ return firstEntry == null ? null : firstEntry.getKey().task; ++ } ++ ++ public Priority getHighestPriority() { ++ final Map.Entry firstEntry = this.tasks.firstEntry(); ++ return firstEntry == null ? null : Priority.getPriority(firstEntry.getKey().priority); ++ } ++ ++ public boolean hasNoScheduledTasks() { ++ final long executedTasks = this.executedTasks.get(); ++ final long scheduledTasks = this.scheduledTasks.get(); ++ ++ return executedTasks == scheduledTasks; ++ } ++ ++ public PrioritySubOrderPair getHighestPrioritySubOrder() { ++ final Map.Entry firstEntry = this.tasks.firstEntry(); ++ if (firstEntry == null) { ++ return null; ++ } ++ ++ final PrioritisedQueuedTask.Holder holder = firstEntry.getKey(); ++ ++ return new PrioritySubOrderPair(Priority.getPriority(holder.priority), holder.subOrder); ++ } ++ ++ public Runnable pollTask() { ++ for (;;) { ++ final Map.Entry firstEntry = this.tasks.pollFirstEntry(); ++ if (firstEntry != null) { ++ final PrioritisedQueuedTask.Holder task = firstEntry.getKey(); ++ task.markRemoved(); ++ if (!task.task.cancel()) { ++ continue; ++ } ++ return task.task.execute; ++ } ++ ++ return null; ++ } ++ } ++ ++ @Override ++ public boolean executeTask() { ++ for (;;) { ++ final Map.Entry firstEntry = this.tasks.pollFirstEntry(); ++ if (firstEntry != null) { ++ final PrioritisedQueuedTask.Holder task = firstEntry.getKey(); ++ task.markRemoved(); ++ if (!task.task.execute()) { ++ continue; ++ } ++ return true; ++ } ++ ++ return false; ++ } ++ } ++ ++ @Override ++ public PrioritisedTask createTask(final Runnable task) { ++ return this.createTask(task, Priority.NORMAL, this.generateNextSubOrder()); ++ } ++ ++ @Override ++ public PrioritisedTask createTask(final Runnable task, final Priority priority) { ++ return this.createTask(task, priority, this.generateNextSubOrder()); ++ } ++ ++ @Override ++ public PrioritisedTask createTask(final Runnable task, final Priority priority, final long subOrder) { ++ return new PrioritisedQueuedTask(task, priority, subOrder); ++ } ++ ++ @Override ++ public PrioritisedTask queueTask(final Runnable task) { ++ return this.queueTask(task, Priority.NORMAL, this.generateNextSubOrder()); ++ } ++ ++ @Override ++ public PrioritisedTask queueTask(final Runnable task, final Priority priority) { ++ return this.queueTask(task, priority, this.generateNextSubOrder()); ++ } ++ ++ @Override ++ public PrioritisedTask queueTask(final Runnable task, final Priority priority, final long subOrder) { ++ final PrioritisedQueuedTask ret = new PrioritisedQueuedTask(task, priority, subOrder); ++ ++ ret.queue(); ++ ++ return ret; ++ } ++ ++ private final class PrioritisedQueuedTask implements PrioritisedExecutor.PrioritisedTask { ++ public static final Comparator COMPARATOR = (final PrioritisedQueuedTask.Holder t1, final PrioritisedQueuedTask.Holder t2) -> { ++ final int priorityCompare = t1.priority - t2.priority; ++ if (priorityCompare != 0) { ++ return priorityCompare; ++ } ++ ++ final int subOrderCompare = Long.compare(t1.subOrder, t2.subOrder); ++ if (subOrderCompare != 0) { ++ return subOrderCompare; ++ } ++ ++ return Long.compare(t1.id, t2.id); ++ }; ++ ++ private static final class Holder { ++ private final PrioritisedQueuedTask task; ++ private final int priority; ++ private final long subOrder; ++ private final long id; ++ ++ private volatile boolean removed; ++ private static final VarHandle REMOVED_HANDLE = ConcurrentUtil.getVarHandle(Holder.class, "removed", boolean.class); ++ ++ private Holder(final PrioritisedQueuedTask task, final int priority, final long subOrder, ++ final long id) { ++ this.task = task; ++ this.priority = priority; ++ this.subOrder = subOrder; ++ this.id = id; ++ } ++ ++ /** ++ * Returns true if marked as removed ++ */ ++ public boolean markRemoved() { ++ return !(boolean)REMOVED_HANDLE.getAndSet((Holder)this, (boolean)true); ++ } ++ } ++ ++ private final long id; ++ private final Runnable execute; ++ ++ private Priority priority; ++ private long subOrder; ++ private Holder holder; ++ ++ public PrioritisedQueuedTask(final Runnable execute, final Priority priority, final long subOrder) { ++ if (!Priority.isValidPriority(priority)) { ++ throw new IllegalArgumentException("Invalid priority " + priority); ++ } ++ ++ this.execute = execute; ++ this.priority = priority; ++ this.subOrder = subOrder; ++ this.id = PrioritisedTaskQueue.this.taskIdGenerator.getAndIncrement(); ++ } ++ ++ @Override ++ public PrioritisedExecutor getExecutor() { ++ return PrioritisedTaskQueue.this; ++ } ++ ++ @Override ++ public boolean queue() { ++ synchronized (this) { ++ if (this.holder != null || this.priority == Priority.COMPLETING) { ++ return false; ++ } ++ ++ if (PrioritisedTaskQueue.this.isShutdown()) { ++ throw new IllegalStateException("Queue is shutdown"); ++ } ++ ++ final Holder holder = new Holder(this, this.priority.priority, this.subOrder, this.id); ++ this.holder = holder; ++ ++ PrioritisedTaskQueue.this.scheduledTasks.getAndIncrement(); ++ PrioritisedTaskQueue.this.tasks.put(holder, Boolean.TRUE); ++ } ++ ++ if (PrioritisedTaskQueue.this.isShutdown()) { ++ this.cancel(); ++ throw new IllegalStateException("Queue is shutdown"); ++ } ++ ++ ++ return true; ++ } ++ ++ @Override ++ public boolean isQueued() { ++ synchronized (this) { ++ return this.holder != null && this.priority != Priority.COMPLETING; ++ } ++ } ++ ++ @Override ++ public boolean cancel() { ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING) { ++ return false; ++ } ++ ++ this.priority = Priority.COMPLETING; ++ ++ if (this.holder != null) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ PrioritisedTaskQueue.this.executedTasks.getAndIncrement(); ++ } ++ ++ return true; ++ } ++ } ++ ++ @Override ++ public boolean execute() { ++ final boolean increaseExecuted; ++ ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING) { ++ return false; ++ } ++ ++ this.priority = Priority.COMPLETING; ++ ++ if (increaseExecuted = (this.holder != null)) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ } ++ } ++ ++ try { ++ this.execute.run(); ++ return true; ++ } finally { ++ if (increaseExecuted) { ++ PrioritisedTaskQueue.this.executedTasks.getAndIncrement(); ++ } ++ } ++ } ++ ++ @Override ++ public Priority getPriority() { ++ synchronized (this) { ++ return this.priority; ++ } ++ } ++ ++ @Override ++ public boolean setPriority(final Priority priority) { ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING || this.priority == priority) { ++ return false; ++ } ++ ++ this.priority = priority; ++ ++ if (this.holder != null) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); ++ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); ++ } ++ ++ return true; ++ } ++ } ++ ++ @Override ++ public boolean raisePriority(final Priority priority) { ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING || this.priority.isHigherOrEqualPriority(priority)) { ++ return false; ++ } ++ ++ this.priority = priority; ++ ++ if (this.holder != null) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); ++ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); ++ } ++ ++ return true; ++ } ++ } ++ ++ @Override ++ public boolean lowerPriority(Priority priority) { ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING || this.priority.isLowerOrEqualPriority(priority)) { ++ return false; ++ } ++ ++ this.priority = priority; ++ ++ if (this.holder != null) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); ++ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); ++ } ++ ++ return true; ++ } ++ } ++ ++ @Override ++ public long getSubOrder() { ++ synchronized (this) { ++ return this.subOrder; ++ } ++ } ++ ++ @Override ++ public boolean setSubOrder(final long subOrder) { ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING || this.subOrder == subOrder) { ++ return false; ++ } ++ ++ this.subOrder = subOrder; ++ ++ if (this.holder != null) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); ++ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); ++ } ++ ++ return true; ++ } ++ } ++ ++ @Override ++ public boolean raiseSubOrder(long subOrder) { ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING || this.subOrder >= subOrder) { ++ return false; ++ } ++ ++ this.subOrder = subOrder; ++ ++ if (this.holder != null) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); ++ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); ++ } ++ ++ return true; ++ } ++ } ++ ++ @Override ++ public boolean lowerSubOrder(final long subOrder) { ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING || this.subOrder <= subOrder) { ++ return false; ++ } ++ ++ this.subOrder = subOrder; ++ ++ if (this.holder != null) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); ++ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); ++ } ++ ++ return true; ++ } ++ } ++ ++ @Override ++ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder) { ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING || (this.priority == priority && this.subOrder == subOrder)) { ++ return false; ++ } ++ ++ this.priority = priority; ++ this.subOrder = subOrder; ++ ++ if (this.holder != null) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); ++ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); ++ } ++ ++ return true; ++ } ++ } ++ } ++ ++ public static record PrioritySubOrderPair(Priority priority, long subOrder) {} ++} +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/DelayedPrioritisedTask.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/DelayedPrioritisedTask.java +deleted file mode 100644 +index 3ce10053d4ec51855ad7012abb5d97df1c0e557a..0000000000000000000000000000000000000000 +--- a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/DelayedPrioritisedTask.java ++++ /dev/null +@@ -1,170 +0,0 @@ +-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 +deleted file mode 100644 +index 91beb6f23f257cf265fe3150f760892e605f217a..0000000000000000000000000000000000000000 +--- a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedExecutor.java ++++ /dev/null +@@ -1,276 +0,0 @@ +-package ca.spottedleaf.concurrentutil.executor.standard; +- +-import ca.spottedleaf.concurrentutil.executor.BaseExecutor; +- +-/** +- * Implementation of {@link BaseExecutor} which schedules tasks to be executed by a given priority. +- * @see 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 Priority max(final Priority p1, final Priority p2) { +- return p1.isHigherOrEqualPriority(p2) ? p1 : p2; +- } +- +- // returns the lower priroity of the two +- public static 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 Priority[] PRIORITIES = 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 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; +- } +- } +- +- /** +- * Executes the next available task. +- *

    +- * If there is a task with priority {@link PrioritisedExecutor.Priority#BLOCKING} available, then that such task is executed. +- *

    +- *

    +- * 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. +- *

    +- *

    +- * 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. +- *

    +- * +- * @return {@code true} if a task was executed, {@code false} otherwise +- * @throws IllegalStateException If the current thread is not allowed to execute a task +- */ +- @Override +- public boolean executeTask() throws IllegalStateException; +- +- /** +- * 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, 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 Priority priority); +- +- /** +- * Creates, but does not execute or queue the task. The task must later be queued via {@link 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 PrioritisedTask createTask(final Runnable task) { +- return this.createTask(task, Priority.NORMAL); +- } +- +- /** +- * Creates, but does not execute or queue the task. The task must later be queued via {@link 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 PrioritisedTask createTask(final Runnable task, final Priority priority); +- +- /** +- * Extension of {@link ca.spottedleaf.concurrentutil.executor.BaseExecutor.BaseTask} which adds functions +- * to retrieve and modify the task's associated priority. +- * +- * @see ca.spottedleaf.concurrentutil.executor.BaseExecutor.BaseTask +- */ +- public static interface PrioritisedTask extends BaseTask { +- +- /** +- * Returns the current priority. Note that {@link Priority#COMPLETING} will be returned +- * if this task is completing or has completed. +- */ +- public 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 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 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 Priority priority); +- } +-} +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedThreadPool.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedThreadPool.java +deleted file mode 100644 +index 2ba36e29d0d8693f2f5e6c6d195ca27f2a5099aa..0000000000000000000000000000000000000000 +--- a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedThreadPool.java ++++ /dev/null +@@ -1,632 +0,0 @@ +-package ca.spottedleaf.concurrentutil.executor.standard; +- +-import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; +-import org.slf4j.Logger; +-import org.slf4j.LoggerFactory; +-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 = LoggerFactory.getLogger(PrioritisedThreadPool.class); +- +- private final PrioritisedThread[] threads; +- private final TreeSet queues = new TreeSet<>(PrioritisedPoolExecutorImpl.comparator()); +- private final String name; +- private final long queueMaxHoldTime; +- +- private final ReferenceOpenHashSet nonShutdownQueues = new ReferenceOpenHashSet<>(); +- private final ReferenceOpenHashSet activeQueues = new ReferenceOpenHashSet<>(); +- +- private boolean shutdown; +- +- private long schedulingIdGenerator; +- +- private static final long DEFAULT_QUEUE_HOLD_TIME = (long)(5.0e6); +- +- /** +- * @param name Specified debug name of this thread pool +- * @param threads The number of threads to use +- */ +- public PrioritisedThreadPool(final String name, final int threads) { +- this(name, threads, null); +- } +- +- /** +- * @param name Specified debug name of this thread pool +- * @param threads The number of threads to use +- * @param threadModifier Invoked for each created thread with its incremental id before starting them +- */ +- public PrioritisedThreadPool(final String name, final int threads, final BiConsumer threadModifier) { +- this(name, threads, threadModifier, DEFAULT_QUEUE_HOLD_TIME); // 5ms +- } +- +- /** +- * @param name Specified debug name of this thread pool +- * @param threads The number of threads to use +- * @param threadModifier Invoked for each created thread with its incremental id before starting them +- * @param queueHoldTime The maximum amount of time to spend executing tasks in a specific queue before attempting +- * to switch to another queue, per thread +- */ +- public PrioritisedThreadPool(final String name, final int threads, final BiConsumer 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(); +- } +- } +- +- /** +- * Returns an array representing the threads backing this thread pool. +- */ +- public Thread[] getThreads() { +- return Arrays.copyOf(this.threads, this.threads.length, Thread[].class); +- } +- +- /** +- * Creates and returns a {@link PrioritisedPoolExecutor} to schedule tasks onto. The returned executor will execute +- * tasks on this thread pool only. +- * @param name The debug name of the executor. +- * @param minParallelism The minimum number of threads to be executing tasks from the returned executor +- * before threads may be allocated to other queues in this thread pool. +- * @param parallelism The maximum number of threads which may be executing tasks from the returned executor. +- * @throws IllegalStateException If this thread pool is shut down +- */ +- public PrioritisedPoolExecutor createExecutor(final String name, final int minParallelism, 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), +- Math.min(Math.max(0, minParallelism), 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 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(); +- } +- } +- } +- +- /** +- * Shuts down this thread pool, optionally waiting for all tasks to be executed. +- * This function will invoke {@link PrioritisedPoolExecutor#shutdown()} on all created executors on this +- * thread pool. +- * @param wait Whether to wait for tasks to be executed +- */ +- public void shutdown(final boolean wait) { +- final ArrayList 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 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 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 final int minimumExecutors; +- protected boolean isQueued; +- +- public PrioritisedPoolExecutorImpl(final PrioritisedThreadPool pool, final String name, final int maximumExecutors, final int minimumExecutors) { +- this.pool = pool; +- this.name = name; +- this.maximumExecutors = maximumExecutors; +- this.minimumExecutors = minimumExecutors; +- } +- +- public static Comparator comparator() { +- return (final PrioritisedPoolExecutorImpl p1, final PrioritisedPoolExecutorImpl p2) -> { +- if (p1 == p2) { +- return 0; +- } +- +- final int belowMin1 = p1.minimumExecutors - p1.concurrentExecutors; +- final int belowMin2 = p2.minimumExecutors - p2.concurrentExecutors; +- +- // test minimum executors +- if (belowMin1 > 0 || belowMin2 > 0) { +- // want the largest belowMin to be first +- final int minCompare = Integer.compare(belowMin2, belowMin1); +- +- if (minCompare != 0) { +- return minCompare; +- } +- } +- +- // 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 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 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 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 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 +deleted file mode 100644 +index 3e8401b1b1f833c4f01bc87059a2f48d761d989f..0000000000000000000000000000000000000000 +--- a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedThreadedTaskQueue.java ++++ /dev/null +@@ -1,378 +0,0 @@ +-package ca.spottedleaf.concurrentutil.executor.standard; +- +-import java.util.ArrayDeque; +-import java.util.concurrent.atomic.AtomicLong; +- +-public class PrioritisedThreadedTaskQueue implements PrioritisedExecutor { +- +- protected final ArrayDeque[] 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 Priority priority) throws IllegalStateException, IllegalArgumentException { +- if (!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 (!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 Priority minPriority) { +- final ArrayDeque[] queues = this.queues; +- synchronized (queues) { +- final int max = minPriority.priority; +- for (int i = 0; i <= max; ++i) { +- final ArrayDeque 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 Priority priority; +- +- protected PrioritisedTask(final long id, final Runnable runnable, final Priority priority, final PrioritisedThreadedTaskQueue queue) { +- if (!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 Priority priority, final PrioritisedThreadedTaskQueue queue) { +- if (!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 Priority priority = this.priority; +- if (priority == 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 Priority oldPriority = this.priority; +- if (oldPriority != Priority.COMPLETING && oldPriority.isHigherOrEqualPriority(minPriority)) { +- this.priority = Priority.COMPLETING; +- if (this.id != NOT_SCHEDULED_ID) { +- this.queue.priorityChange(this, oldPriority, Priority.COMPLETING); +- } +- return true; +- } +- +- return false; +- } +- +- @Override +- public Priority getPriority() { +- return this.priority; +- } +- +- @Override +- public boolean setPriority(final Priority priority) { +- if (!Priority.isValidPriority(priority)) { +- throw new IllegalArgumentException("Invalid priority " + priority); +- } +- synchronized (this.queue.queues) { +- final Priority curr = this.priority; +- +- if (curr == 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 Priority priority) { +- if (!Priority.isValidPriority(priority)) { +- throw new IllegalArgumentException("Invalid priority " + priority); +- } +- +- synchronized (this.queue.queues) { +- final Priority curr = this.priority; +- +- if (curr == 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 Priority priority) { +- if (!Priority.isValidPriority(priority)) { +- throw new IllegalArgumentException("Invalid priority " + priority); +- } +- +- synchronized (this.queue.queues) { +- final Priority curr = this.priority; +- +- if (curr == 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 == Priority.COMPLETING) { +- return false; +- } +- +- this.priority = Priority.COMPLETING; +- // call priority change callback +- if ((id = this.id) != NOT_SCHEDULED_ID) { +- this.queue.priorityChange(this, oldPriority, 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 == Priority.COMPLETING) { +- return false; +- } +- +- this.priority = Priority.COMPLETING; +- // call priority change callback +- if (this.id != NOT_SCHEDULED_ID) { +- this.queue.priorityChange(this, oldPriority, Priority.COMPLETING); +- } +- } +- +- this.executeInternal(); +- return true; +- } +- } +-} +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedQueueExecutorThread.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedQueueExecutorThread.java +similarity index 60% +rename from src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedQueueExecutorThread.java +rename to src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedQueueExecutorThread.java +index d1683ba6350e530373944f98192c0f2baf241e70..f5367a13aaa02f0f929813c00a67e6ac7c8652cb 100644 +--- a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedQueueExecutorThread.java ++++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedQueueExecutorThread.java +@@ -1,6 +1,8 @@ +-package ca.spottedleaf.concurrentutil.executor.standard; ++package ca.spottedleaf.concurrentutil.executor.thread; + ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; + import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + import java.lang.invoke.VarHandle; +@@ -11,8 +13,7 @@ import java.util.concurrent.locks.LockSupport; + *

    + * 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. ++ * of task scheduling, use the methods provided on this class to schedule tasks. + *

    + */ + public class PrioritisedQueueExecutorThread extends Thread implements PrioritisedExecutor { +@@ -30,7 +31,7 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise + + protected final long spinWaitTime; + +- static final long DEFAULT_SPINWAIT_TIME = (long)(0.1e6);// 0.1ms ++ protected static final long DEFAULT_SPINWAIT_TIME = (long)(0.1e6);// 0.1ms + + public PrioritisedQueueExecutorThread(final PrioritisedExecutor queue) { + this(queue, DEFAULT_SPINWAIT_TIME); // 0.1ms +@@ -42,7 +43,16 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise + } + + @Override +- public void run() { ++ public final void run() { ++ try { ++ this.begin(); ++ this.doRun(); ++ } finally { ++ this.die(); ++ } ++ } ++ ++ public final void doRun() { + final long spinWaitTime = this.spinWaitTime; + + main_loop: +@@ -80,7 +90,7 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise + 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) ++ // (i.e. it will not notify us) + if (this.pollTasks()) { + this.setThreadParkedVolatile(false); + continue; +@@ -99,6 +109,10 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise + } + } + ++ protected void begin() {} ++ ++ protected void die() {} ++ + /** + * Attempts to poll as many tasks as possible, returning when finished. + * @return Whether any tasks were executed. +@@ -115,8 +129,6 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise + 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); + } +@@ -146,95 +158,86 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise + } + + @Override +- public PrioritisedTask createTask(final Runnable task, final Priority priority) { +- final 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); +- } ++ public long getTotalTasksExecuted() { ++ return this.queue.getTotalTasksExecuted(); ++ } + +- @Override +- public boolean raisePriority(final Priority priority) { +- return queueTask.raisePriority(priority); +- } ++ @Override ++ public long getTotalTasksScheduled() { ++ return this.queue.getTotalTasksScheduled(); ++ } + +- @Override +- public boolean lowerPriority(final Priority priority) { +- return queueTask.lowerPriority(priority); +- } ++ @Override ++ public long generateNextSubOrder() { ++ return this.queue.generateNextSubOrder(); ++ } + +- @Override +- public boolean queue() { +- final boolean ret = queueTask.queue(); +- if (ret) { +- PrioritisedQueueExecutorThread.this.notifyTasks(); +- } +- return ret; +- } ++ @Override ++ public boolean shutdown() { ++ throw new UnsupportedOperationException(); ++ } + +- @Override +- public boolean cancel() { +- return queueTask.cancel(); +- } ++ @Override ++ public boolean isShutdown() { ++ return false; ++ } + +- @Override +- public boolean execute() { +- return queueTask.execute(); +- } +- }; ++ /** ++ * {@inheritDoc} ++ * @throws IllegalStateException Always ++ */ ++ @Override ++ public boolean executeTask() throws IllegalStateException { ++ throw new IllegalStateException(); + } + + @Override +- public PrioritisedTask queueRunnable(final Runnable task, final Priority priority) { +- final PrioritisedTask ret = this.queue.queueRunnable(task, priority); ++ public PrioritisedTask queueTask(final Runnable task) { ++ final PrioritisedTask ret = this.createTask(task); + +- this.notifyTasks(); ++ ret.queue(); + + return ret; + } + + @Override +- public boolean haveAllTasksExecuted() { +- return this.queue.haveAllTasksExecuted(); ++ public PrioritisedTask queueTask(final Runnable task, final Priority priority) { ++ final PrioritisedTask ret = this.createTask(task, priority); ++ ++ ret.queue(); ++ ++ return ret; + } + + @Override +- public long getTotalTasksExecuted() { +- return this.queue.getTotalTasksExecuted(); ++ public PrioritisedTask queueTask(final Runnable task, final Priority priority, final long subOrder) { ++ final PrioritisedTask ret = this.createTask(task, priority, subOrder); ++ ++ ret.queue(); ++ ++ return ret; + } + ++ + @Override +- public long getTotalTasksScheduled() { +- return this.queue.getTotalTasksScheduled(); ++ public PrioritisedTask createTask(Runnable task) { ++ final PrioritisedTask queueTask = this.queue.createTask(task); ++ ++ return new WrappedTask(queueTask); + } + +- /** +- * {@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(); ++ public PrioritisedTask createTask(final Runnable task, final Priority priority) { ++ final PrioritisedTask queueTask = this.queue.createTask(task, priority); ++ ++ return new WrappedTask(queueTask); + } + +- /** +- * {@inheritDoc} +- * @throws IllegalStateException Always +- */ + @Override +- public boolean executeTask() throws IllegalStateException { +- throw new IllegalStateException(); ++ public PrioritisedTask createTask(final Runnable task, final Priority priority, final long subOrder) { ++ final PrioritisedTask queueTask = this.queue.createTask(task, priority, subOrder); ++ ++ return new WrappedTask(queueTask); + } + + /** +@@ -242,7 +245,7 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise + *

    + * This function is MT-Safe. + *

    +- * @param wait If this call is to wait until the queue is empty and there are no tasks executing in the queue. ++ * @param wait If this call is to wait until this thread shuts down. + * @param killQueue Whether to shutdown this thread's queue + * @return whether this thread shut down the queue + * @see #halt(boolean) +@@ -256,7 +259,20 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise + LockSupport.unpark(this); + + if (wait) { +- this.waitUntilAllExecuted(); ++ boolean interrupted = false; ++ for (;;) { ++ if (this.isAlive()) { ++ if (interrupted) { ++ Thread.currentThread().interrupt(); ++ } ++ break; ++ } ++ try { ++ this.join(); ++ } catch (final InterruptedException ex) { ++ interrupted = true; ++ } ++ } + } + + return ret; +@@ -298,4 +314,89 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise + protected final void setThreadParkedVolatile(final boolean value) { + THREAD_PARKED_HANDLE.setVolatile(this, value); + } ++ ++ /** ++ * Required so that queue() can notify (unpark) this thread ++ */ ++ private final class WrappedTask implements PrioritisedTask { ++ private final PrioritisedTask queueTask; ++ ++ public WrappedTask(final PrioritisedTask queueTask) { ++ this.queueTask = queueTask; ++ } ++ ++ @Override ++ public PrioritisedExecutor getExecutor() { ++ return PrioritisedQueueExecutorThread.this; ++ } ++ ++ @Override ++ public boolean queue() { ++ final boolean ret = this.queueTask.queue(); ++ if (ret) { ++ PrioritisedQueueExecutorThread.this.notifyTasks(); ++ } ++ return ret; ++ } ++ ++ @Override ++ public boolean isQueued() { ++ return this.queueTask.isQueued(); ++ } ++ ++ @Override ++ public boolean cancel() { ++ return this.queueTask.cancel(); ++ } ++ ++ @Override ++ public boolean execute() { ++ return this.queueTask.execute(); ++ } ++ ++ @Override ++ public Priority getPriority() { ++ return this.queueTask.getPriority(); ++ } ++ ++ @Override ++ public boolean setPriority(final Priority priority) { ++ return this.queueTask.setPriority(priority); ++ } ++ ++ @Override ++ public boolean raisePriority(final Priority priority) { ++ return this.queueTask.raisePriority(priority); ++ } ++ ++ @Override ++ public boolean lowerPriority(final Priority priority) { ++ return this.queueTask.lowerPriority(priority); ++ } ++ ++ @Override ++ public long getSubOrder() { ++ return this.queueTask.getSubOrder(); ++ } ++ ++ @Override ++ public boolean setSubOrder(final long subOrder) { ++ return this.queueTask.setSubOrder(subOrder); ++ } ++ ++ @Override ++ public boolean raiseSubOrder(final long subOrder) { ++ return this.queueTask.raiseSubOrder(subOrder); ++ } ++ ++ @Override ++ public boolean lowerSubOrder(final long subOrder) { ++ return this.queueTask.lowerSubOrder(subOrder); ++ } ++ ++ @Override ++ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder) { ++ return this.queueTask.setPriorityAndSubOrder(priority, subOrder); ++ } ++ } + } +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedThreadPool.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedThreadPool.java +new file mode 100644 +index 0000000000000000000000000000000000000000..cb9df914a9a6d0d3f58fa58d8c93f4f583416cd1 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedThreadPool.java +@@ -0,0 +1,741 @@ ++package ca.spottedleaf.concurrentutil.executor.thread; ++ ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.queue.PrioritisedTaskQueue; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.concurrentutil.util.TimeUtil; ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; ++import java.lang.reflect.Array; ++import java.util.Arrays; ++import java.util.concurrent.atomic.AtomicBoolean; ++import java.util.concurrent.atomic.AtomicLong; ++import java.util.function.Consumer; ++ ++public final class PrioritisedThreadPool { ++ ++ private static final Logger LOGGER = LoggerFactory.getLogger(PrioritisedThreadPool.class); ++ ++ private final Consumer threadModifier; ++ private final COWArrayList executors = new COWArrayList<>(ExecutorGroup.class); ++ private final COWArrayList threads = new COWArrayList<>(PrioritisedThread.class); ++ private final COWArrayList aliveThreads = new COWArrayList<>(PrioritisedThread.class); ++ ++ private static final Priority HIGH_PRIORITY_NOTIFY_THRESHOLD = Priority.HIGH; ++ private static final Priority QUEUE_SHUTDOWN_PRIORITY = Priority.HIGH; ++ ++ private boolean shutdown; ++ ++ public PrioritisedThreadPool(final Consumer threadModifier) { ++ this.threadModifier = threadModifier; ++ ++ if (threadModifier == null) { ++ throw new NullPointerException("Thread factory may not be null"); ++ } ++ } ++ ++ public Thread[] getAliveThreads() { ++ final PrioritisedThread[] threads = this.aliveThreads.getArray(); ++ ++ return Arrays.copyOf(threads, threads.length, Thread[].class); ++ } ++ ++ public Thread[] getCoreThreads() { ++ final PrioritisedThread[] threads = this.threads.getArray(); ++ ++ return Arrays.copyOf(threads, threads.length, Thread[].class); ++ } ++ ++ /** ++ * Prevents creation of new queues, shutdowns all non-shutdown queues if specified ++ */ ++ public void halt(final boolean shutdownQueues) { ++ synchronized (this) { ++ this.shutdown = true; ++ } ++ ++ if (shutdownQueues) { ++ for (final ExecutorGroup group : this.executors.getArray()) { ++ for (final ExecutorGroup.ThreadPoolExecutor executor : group.executors.getArray()) { ++ executor.shutdown(); ++ } ++ } ++ } ++ ++ for (final PrioritisedThread thread : this.threads.getArray()) { ++ 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.aliveThreads.getArray()) { ++ for (;;) { ++ if (!thread.isAlive()) { ++ break; ++ } ++ final long current = System.nanoTime(); ++ if (current >= deadline && msToWait > 0L) { ++ return false; ++ } ++ ++ try { ++ thread.join(msToWait <= 0L ? 0L : 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(); ++ } ++ } ++ } ++ ++ /** ++ * Shuts down this thread pool, optionally waiting for all tasks to be executed. ++ * This function will invoke {@link PrioritisedExecutor#shutdown()} on all created executors on this ++ * thread pool. ++ * @param wait Whether to wait for tasks to be executed ++ */ ++ public void shutdown(final boolean wait) { ++ synchronized (this) { ++ this.shutdown = true; ++ } ++ ++ for (final ExecutorGroup group : this.executors.getArray()) { ++ for (final ExecutorGroup.ThreadPoolExecutor executor : group.executors.getArray()) { ++ executor.shutdown(); ++ } ++ } ++ ++ ++ for (final PrioritisedThread thread : this.threads.getArray()) { ++ // none of these can be true or else NPE ++ thread.close(false, false); ++ } ++ ++ if (wait) { ++ this.join(0L); ++ } ++ } ++ ++ private void die(final PrioritisedThread thread) { ++ this.aliveThreads.remove(thread); ++ } ++ ++ public void adjustThreadCount(final int threads) { ++ synchronized (this) { ++ if (this.shutdown) { ++ return; ++ } ++ ++ final PrioritisedThread[] currentThreads = this.threads.getArray(); ++ if (threads == currentThreads.length) { ++ // no adjustment needed ++ return; ++ } ++ ++ if (threads < currentThreads.length) { ++ // we need to trim threads ++ for (int i = 0, difference = currentThreads.length - threads; i < difference; ++i) { ++ final PrioritisedThread remove = currentThreads[currentThreads.length - i - 1]; ++ ++ remove.halt(false); ++ this.threads.remove(remove); ++ } ++ } else { ++ // we need to add threads ++ for (int i = 0, difference = threads - currentThreads.length; i < difference; ++i) { ++ final PrioritisedThread thread = new PrioritisedThread(); ++ ++ this.threadModifier.accept(thread); ++ this.aliveThreads.add(thread); ++ this.threads.add(thread); ++ ++ thread.start(); ++ } ++ } ++ } ++ } ++ ++ private static int compareInsideGroup(final ExecutorGroup.ThreadPoolExecutor src, final Priority srcPriority, ++ final ExecutorGroup.ThreadPoolExecutor dst, final Priority dstPriority) { ++ final int priorityCompare = srcPriority.ordinal() - dstPriority.ordinal(); ++ if (priorityCompare != 0) { ++ return priorityCompare; ++ } ++ ++ final int parallelismCompare = src.currentParallelism - dst.currentParallelism; ++ if (parallelismCompare != 0) { ++ return parallelismCompare; ++ } ++ ++ return TimeUtil.compareTimes(src.lastRetrieved, dst.lastRetrieved); ++ } ++ ++ private static int compareOutsideGroup(final ExecutorGroup.ThreadPoolExecutor src, final Priority srcPriority, ++ final ExecutorGroup.ThreadPoolExecutor dst, final Priority dstPriority) { ++ if (src.getGroup().division == dst.getGroup().division) { ++ // can only compare priorities inside the same division ++ final int priorityCompare = srcPriority.ordinal() - dstPriority.ordinal(); ++ if (priorityCompare != 0) { ++ return priorityCompare; ++ } ++ } ++ ++ final int parallelismCompare = src.getGroup().currentParallelism - dst.getGroup().currentParallelism; ++ if (parallelismCompare != 0) { ++ return parallelismCompare; ++ } ++ ++ return TimeUtil.compareTimes(src.lastRetrieved, dst.lastRetrieved); ++ } ++ ++ private ExecutorGroup.ThreadPoolExecutor obtainQueue() { ++ final long time = System.nanoTime(); ++ synchronized (this) { ++ ExecutorGroup.ThreadPoolExecutor ret = null; ++ Priority retPriority = null; ++ ++ for (final ExecutorGroup executorGroup : this.executors.getArray()) { ++ ExecutorGroup.ThreadPoolExecutor highest = null; ++ Priority highestPriority = null; ++ for (final ExecutorGroup.ThreadPoolExecutor executor : executorGroup.executors.getArray()) { ++ final int maxParallelism = executor.maxParallelism; ++ if (maxParallelism > 0 && executor.currentParallelism >= maxParallelism) { ++ continue; ++ } ++ ++ final Priority priority = executor.getTargetPriority(); ++ ++ if (priority == null) { ++ continue; ++ } ++ ++ if (highestPriority == null || compareInsideGroup(highest, highestPriority, executor, priority) > 0) { ++ highest = executor; ++ highestPriority = priority; ++ } ++ } ++ ++ if (highest == null) { ++ continue; ++ } ++ ++ if (ret == null || compareOutsideGroup(ret, retPriority, highest, highestPriority) > 0) { ++ ret = highest; ++ retPriority = highestPriority; ++ } ++ } ++ ++ if (ret != null) { ++ ret.lastRetrieved = time; ++ ++ret.currentParallelism; ++ ++ret.getGroup().currentParallelism; ++ return ret; ++ } ++ ++ return ret; ++ } ++ } ++ ++ private void returnQueue(final ExecutorGroup.ThreadPoolExecutor executor) { ++ synchronized (this) { ++ --executor.currentParallelism; ++ --executor.getGroup().currentParallelism; ++ } ++ ++ if (executor.isShutdown() && executor.queue.hasNoScheduledTasks()) { ++ executor.getGroup().executors.remove(executor); ++ } ++ } ++ ++ private void notifyAllThreads() { ++ for (final PrioritisedThread thread : this.threads.getArray()) { ++ thread.notifyTasks(); ++ } ++ } ++ ++ public ExecutorGroup createExecutorGroup(final int division, final int flags) { ++ synchronized (this) { ++ if (this.shutdown) { ++ throw new IllegalStateException("Queue is shutdown: " + this.toString()); ++ } ++ ++ final ExecutorGroup ret = new ExecutorGroup(division, flags); ++ ++ this.executors.add(ret); ++ ++ return ret; ++ } ++ } ++ ++ private final class PrioritisedThread extends PrioritisedQueueExecutorThread { ++ ++ private final AtomicBoolean alertedHighPriority = new AtomicBoolean(); ++ ++ public PrioritisedThread() { ++ super(null); ++ } ++ ++ 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 void die() { ++ PrioritisedThreadPool.this.die(this); ++ } ++ ++ @Override ++ protected boolean pollTasks() { ++ boolean ret = false; ++ ++ for (;;) { ++ if (this.halted) { ++ break; ++ } ++ ++ final ExecutorGroup.ThreadPoolExecutor executor = PrioritisedThreadPool.this.obtainQueue(); ++ if (executor == null) { ++ break; ++ } ++ final long deadline = System.nanoTime() + executor.queueMaxHoldTime; ++ do { ++ try { ++ if (this.halted || executor.halt) { ++ break; ++ } ++ if (!executor.executeTask()) { ++ // no more tasks, try next queue ++ break; ++ } ++ ret = true; ++ } catch (final Throwable throwable) { ++ LOGGER.error("Exception thrown from thread '" + this.getName() + "' in queue '" + executor.toString() + "'", throwable); ++ } ++ } while (!this.isAlertedHighPriority() && System.nanoTime() <= deadline); ++ ++ PrioritisedThreadPool.this.returnQueue(executor); ++ } ++ ++ ++ return ret; ++ } ++ } ++ ++ public final class ExecutorGroup { ++ ++ private final AtomicLong subOrderGenerator = new AtomicLong(); ++ private final COWArrayList executors = new COWArrayList<>(ThreadPoolExecutor.class); ++ ++ private final int division; ++ private int currentParallelism; ++ ++ private ExecutorGroup(final int division, final int flags) { ++ this.division = division; ++ } ++ ++ public ThreadPoolExecutor[] getAllExecutors() { ++ return this.executors.getArray().clone(); ++ } ++ ++ private PrioritisedThreadPool getThreadPool() { ++ return PrioritisedThreadPool.this; ++ } ++ ++ public ThreadPoolExecutor createExecutor(final int maxParallelism, final long queueMaxHoldTime, final int flags) { ++ synchronized (PrioritisedThreadPool.this) { ++ if (PrioritisedThreadPool.this.shutdown) { ++ throw new IllegalStateException("Queue is shutdown: " + PrioritisedThreadPool.this.toString()); ++ } ++ ++ final ThreadPoolExecutor ret = new ThreadPoolExecutor(maxParallelism, queueMaxHoldTime, flags); ++ ++ this.executors.add(ret); ++ ++ return ret; ++ } ++ } ++ ++ public final class ThreadPoolExecutor implements PrioritisedExecutor { ++ ++ private final PrioritisedTaskQueue queue = new PrioritisedTaskQueue(); ++ ++ private volatile int maxParallelism; ++ private final long queueMaxHoldTime; ++ private volatile int currentParallelism; ++ private volatile boolean halt; ++ private long lastRetrieved = System.nanoTime(); ++ ++ private ThreadPoolExecutor(final int maxParallelism, final long queueMaxHoldTime, final int flags) { ++ this.maxParallelism = maxParallelism; ++ this.queueMaxHoldTime = queueMaxHoldTime; ++ } ++ ++ private ExecutorGroup getGroup() { ++ return ExecutorGroup.this; ++ } ++ ++ private boolean canNotify() { ++ if (this.halt) { ++ return false; ++ } ++ ++ final int max = this.maxParallelism; ++ return max < 0 || this.currentParallelism < max; ++ } ++ ++ private void notifyHighPriority() { ++ if (!this.canNotify()) { ++ return; ++ } ++ for (final PrioritisedThread thread : this.getGroup().getThreadPool().threads.getArray()) { ++ if (thread.alertHighPriorityExecutor()) { ++ return; ++ } ++ } ++ } ++ ++ private void notifyScheduled() { ++ if (!this.canNotify()) { ++ return; ++ } ++ for (final PrioritisedThread thread : this.getGroup().getThreadPool().threads.getArray()) { ++ if (thread.notifyTasks()) { ++ return; ++ } ++ } ++ } ++ ++ /** ++ * Removes this queue from the thread pool without shutting the queue down or waiting for queued tasks to be executed ++ */ ++ public void halt() { ++ this.halt = true; ++ ++ ExecutorGroup.this.executors.remove(this); ++ } ++ ++ /** ++ * 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() { ++ if (this.halt) { ++ return this.currentParallelism > 0; ++ } else { ++ if (!this.isShutdown()) { ++ return true; ++ } ++ ++ return !this.queue.hasNoScheduledTasks(); ++ } ++ } ++ ++ @Override ++ public boolean shutdown() { ++ if (!this.queue.shutdown()) { ++ return false; ++ } ++ ++ if (this.queue.hasNoScheduledTasks()) { ++ ExecutorGroup.this.executors.remove(this); ++ } ++ ++ return true; ++ } ++ ++ @Override ++ public boolean isShutdown() { ++ return this.queue.isShutdown(); ++ } ++ ++ public void setMaxParallelism(final int maxParallelism) { ++ this.maxParallelism = maxParallelism; ++ // assume that we could have increased the parallelism ++ if (this.getTargetPriority() != null) { ++ ExecutorGroup.this.getThreadPool().notifyAllThreads(); ++ } ++ } ++ ++ Priority getTargetPriority() { ++ final Priority ret = this.queue.getHighestPriority(); ++ if (!this.isShutdown()) { ++ return ret; ++ } ++ ++ return ret == null ? QUEUE_SHUTDOWN_PRIORITY : Priority.max(ret, QUEUE_SHUTDOWN_PRIORITY); ++ } ++ ++ @Override ++ public long getTotalTasksScheduled() { ++ return this.queue.getTotalTasksScheduled(); ++ } ++ ++ @Override ++ public long getTotalTasksExecuted() { ++ return this.queue.getTotalTasksExecuted(); ++ } ++ ++ @Override ++ public long generateNextSubOrder() { ++ return ExecutorGroup.this.subOrderGenerator.getAndIncrement(); ++ } ++ ++ @Override ++ public boolean executeTask() { ++ return this.queue.executeTask(); ++ } ++ ++ @Override ++ public PrioritisedTask queueTask(final Runnable task) { ++ final PrioritisedTask ret = this.createTask(task); ++ ++ ret.queue(); ++ ++ return ret; ++ } ++ ++ @Override ++ public PrioritisedTask queueTask(final Runnable task, final Priority priority) { ++ final PrioritisedTask ret = this.createTask(task, priority); ++ ++ ret.queue(); ++ ++ return ret; ++ } ++ ++ @Override ++ public PrioritisedTask queueTask(final Runnable task, final Priority priority, final long subOrder) { ++ final PrioritisedTask ret = this.createTask(task, priority, subOrder); ++ ++ ret.queue(); ++ ++ return ret; ++ } ++ ++ @Override ++ public PrioritisedTask createTask(final Runnable task) { ++ return this.createTask(task, Priority.NORMAL); ++ } ++ ++ @Override ++ public PrioritisedTask createTask(final Runnable task, final Priority priority) { ++ return this.createTask(task, priority, this.generateNextSubOrder()); ++ } ++ ++ @Override ++ public PrioritisedTask createTask(final Runnable task, final Priority priority, final long subOrder) { ++ return new WrappedTask(this.queue.createTask(task, priority, subOrder)); ++ } ++ ++ private final class WrappedTask implements PrioritisedTask { ++ ++ private final PrioritisedTask wrapped; ++ ++ private WrappedTask(final PrioritisedTask wrapped) { ++ this.wrapped = wrapped; ++ } ++ ++ @Override ++ public PrioritisedExecutor getExecutor() { ++ return ThreadPoolExecutor.this; ++ } ++ ++ @Override ++ public boolean queue() { ++ if (this.wrapped.queue()) { ++ final Priority priority = this.getPriority(); ++ if (priority != Priority.COMPLETING) { ++ if (priority.isHigherOrEqualPriority(HIGH_PRIORITY_NOTIFY_THRESHOLD)) { ++ ThreadPoolExecutor.this.notifyHighPriority(); ++ } else { ++ ThreadPoolExecutor.this.notifyScheduled(); ++ } ++ } ++ return true; ++ } ++ ++ return false; ++ } ++ ++ @Override ++ public boolean isQueued() { ++ return this.wrapped.isQueued(); ++ } ++ ++ @Override ++ public boolean cancel() { ++ return this.wrapped.cancel(); ++ } ++ ++ @Override ++ public boolean execute() { ++ return this.wrapped.execute(); ++ } ++ ++ @Override ++ public Priority getPriority() { ++ return this.wrapped.getPriority(); ++ } ++ ++ @Override ++ public boolean setPriority(final Priority priority) { ++ if (this.wrapped.setPriority(priority)) { ++ if (priority.isHigherOrEqualPriority(HIGH_PRIORITY_NOTIFY_THRESHOLD)) { ++ ThreadPoolExecutor.this.notifyHighPriority(); ++ } ++ return true; ++ } ++ ++ return false; ++ } ++ ++ @Override ++ public boolean raisePriority(final Priority priority) { ++ if (this.wrapped.raisePriority(priority)) { ++ if (priority.isHigherOrEqualPriority(HIGH_PRIORITY_NOTIFY_THRESHOLD)) { ++ ThreadPoolExecutor.this.notifyHighPriority(); ++ } ++ return true; ++ } ++ ++ return false; ++ } ++ ++ @Override ++ public boolean lowerPriority(final Priority priority) { ++ return this.wrapped.lowerPriority(priority); ++ } ++ ++ @Override ++ public long getSubOrder() { ++ return this.wrapped.getSubOrder(); ++ } ++ ++ @Override ++ public boolean setSubOrder(final long subOrder) { ++ return this.wrapped.setSubOrder(subOrder); ++ } ++ ++ @Override ++ public boolean raiseSubOrder(final long subOrder) { ++ return this.wrapped.raiseSubOrder(subOrder); ++ } ++ ++ @Override ++ public boolean lowerSubOrder(final long subOrder) { ++ return this.wrapped.lowerSubOrder(subOrder); ++ } ++ ++ @Override ++ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder) { ++ if (this.wrapped.setPriorityAndSubOrder(priority, subOrder)) { ++ if (priority.isHigherOrEqualPriority(HIGH_PRIORITY_NOTIFY_THRESHOLD)) { ++ ThreadPoolExecutor.this.notifyHighPriority(); ++ } ++ return true; ++ } ++ ++ return false; ++ } ++ } ++ } ++ } ++ ++ private static final class COWArrayList { ++ ++ private volatile E[] array; ++ ++ public COWArrayList(final Class clazz) { ++ this.array = (E[])Array.newInstance(clazz, 0); ++ } ++ ++ public E[] getArray() { ++ return this.array; ++ } ++ ++ public void add(final E element) { ++ synchronized (this) { ++ final E[] array = this.array; ++ ++ final E[] copy = Arrays.copyOf(array, array.length + 1); ++ copy[array.length] = element; ++ ++ this.array = copy; ++ } ++ } ++ ++ public boolean remove(final E element) { ++ synchronized (this) { ++ final E[] array = this.array; ++ int index = -1; ++ for (int i = 0, len = array.length; i < len; ++i) { ++ if (array[i] == element) { ++ index = i; ++ break; ++ } ++ } ++ ++ if (index == -1) { ++ return false; ++ } ++ ++ final E[] copy = (E[])Array.newInstance(array.getClass().getComponentType(), array.length - 1); ++ ++ System.arraycopy(array, 0, copy, 0, index); ++ System.arraycopy(array, index + 1, copy, index, (array.length - 1) - index); ++ ++ this.array = copy; ++ } ++ ++ return true; ++ } ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/map/ConcurrentLong2ReferenceChainedHashTable.java b/src/main/java/ca/spottedleaf/concurrentutil/map/ConcurrentLong2ReferenceChainedHashTable.java +index d701998b376579ec652fb94823befa3cc0bc4090..6918f130099e6c19e20a47bfdb54915cdd13732a 100644 +--- a/src/main/java/ca/spottedleaf/concurrentutil/map/ConcurrentLong2ReferenceChainedHashTable.java ++++ b/src/main/java/ca/spottedleaf/concurrentutil/map/ConcurrentLong2ReferenceChainedHashTable.java +@@ -43,7 +43,7 @@ import java.util.function.Predicate; + * @param + * @see java.util.concurrent.ConcurrentMap + */ +-public class ConcurrentLong2ReferenceChainedHashTable { ++public class ConcurrentLong2ReferenceChainedHashTable implements Iterable> { + + protected static final int DEFAULT_CAPACITY = 16; + protected static final float DEFAULT_LOAD_FACTOR = 0.75f; +@@ -192,6 +192,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + } + + if (node.resize) { ++ // noinspection unchecked + table = (TableEntry[])node.getValuePlain(); + continue; + } +@@ -274,10 +275,10 @@ public class ConcurrentLong2ReferenceChainedHashTable { + public int size() { + final long ret = this.size.sum(); + +- if (ret <= 0L) { ++ if (ret < 0L) { + return 0; + } +- if (ret >= (long)Integer.MAX_VALUE) { ++ if (ret > (long)Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } + +@@ -341,6 +342,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + + // create new table data + ++ // noinspection unchecked + final TableEntry[] newTable = new TableEntry[capacity]; + // noinspection unchecked + final TableEntry resizeNode = new TableEntry<>(0L, (V)newTable, true); +@@ -365,6 +367,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + throw new IllegalStateException("Resizing to same size"); + } + ++ // noinspection unchecked + final TableEntry[] work = new TableEntry[1 << capDiffShift]; // typically, capDiffShift = 1 + + for (int i = 0, len = oldTable.length; i < len; ++i) { +@@ -538,6 +541,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + } + + if (node.resize) { ++ // noinspection unchecked + table = (TableEntry[])node.getValuePlain(); + continue table_loop; + } +@@ -599,6 +603,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + } + + if (node.resize) { ++ // noinspection unchecked + table = (TableEntry[])node.getValuePlain(); + continue table_loop; + } +@@ -653,6 +658,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + } + + if (node.resize) { ++ // noinspection unchecked + table = (TableEntry[])node.getValuePlain(); + continue table_loop; + } +@@ -704,6 +710,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + } + + if (node.resize) { ++ // noinspection unchecked + table = (TableEntry[])node.getValuePlain(); + continue table_loop; + } +@@ -772,6 +779,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + } + + if (node.resize) { ++ // noinspection unchecked + table = (TableEntry[])node.getValuePlain(); + continue table_loop; + } +@@ -848,6 +856,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + } + + if (node.resize) { ++ // noinspection unchecked + table = (TableEntry[])node.getValuePlain(); + continue table_loop; + } +@@ -944,6 +953,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + } + + if (node.resize) { ++ // noinspection unchecked + table = (TableEntry[])node.getValuePlain(); + continue table_loop; + } +@@ -1058,6 +1068,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + } + + if (node.resize) { ++ // noinspection unchecked + table = (TableEntry[])node.getValuePlain(); + continue table_loop; + } +@@ -1126,6 +1137,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + } + + if (node.resize) { ++ // noinspection unchecked + table = (TableEntry[])node.getValuePlain(); + continue table_loop; + } +@@ -1200,6 +1212,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + } + + if (node.resize) { ++ // noinspection unchecked + table = (TableEntry[])node.getValuePlain(); + continue table_loop; + } +@@ -1288,6 +1301,11 @@ public class ConcurrentLong2ReferenceChainedHashTable { + return new EntryIterator<>(this); + } + ++ @Override ++ public final Iterator> iterator() { ++ return this.entryIterator(); ++ } ++ + /** + * Returns an iterator over the keys in this map. The iterator is only guaranteed to see keys that were + * added before the beginning of this call, but it may see keys added during. +@@ -1306,7 +1324,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + + protected static final class EntryIterator extends BaseIteratorImpl> { + +- protected EntryIterator(final ConcurrentLong2ReferenceChainedHashTable map) { ++ public EntryIterator(final ConcurrentLong2ReferenceChainedHashTable map) { + super(map); + } + +@@ -1326,7 +1344,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + + protected static final class KeyIterator extends BaseIteratorImpl implements PrimitiveIterator.OfLong { + +- protected KeyIterator(final ConcurrentLong2ReferenceChainedHashTable map) { ++ public KeyIterator(final ConcurrentLong2ReferenceChainedHashTable map) { + super(map); + } + +@@ -1365,7 +1383,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + + protected static final class ValueIterator extends BaseIteratorImpl { + +- protected ValueIterator(final ConcurrentLong2ReferenceChainedHashTable map) { ++ public ValueIterator(final ConcurrentLong2ReferenceChainedHashTable map) { + super(map); + } + +@@ -1420,7 +1438,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + + @Override + public final void remove() { +- final TableEntry lastReturned = this.nextToReturn; ++ final TableEntry lastReturned = this.lastReturned; + if (lastReturned == null) { + throw new NoSuchElementException(); + } +@@ -1492,6 +1510,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + final ResizeChain chain = this.resizeChain; + + if (chain == null) { ++ // noinspection unchecked + final TableEntry[] nextTable = (TableEntry[])entry.getValuePlain(); + + final ResizeChain oldChain = new ResizeChain<>(table, null, null); +@@ -1506,6 +1525,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { + } else { + ResizeChain currChain = chain.next; + if (currChain == null) { ++ // noinspection unchecked + final TableEntry[] ret = (TableEntry[])entry.getValuePlain(); + currChain = new ResizeChain<>(ret, chain, null); + chain.next = currChain; +@@ -1586,11 +1606,11 @@ public class ConcurrentLong2ReferenceChainedHashTable { + + protected static final class ResizeChain { + +- protected final TableEntry[] table; +- protected final ResizeChain prev; +- protected ResizeChain next; ++ public final TableEntry[] table; ++ public final ResizeChain prev; ++ public ResizeChain next; + +- protected ResizeChain(final TableEntry[] table, final ResizeChain prev, final ResizeChain next) { ++ public ResizeChain(final TableEntry[] table, final ResizeChain prev, final ResizeChain next) { + this.table = table; + this.prev = prev; + this.next = next; +@@ -1600,64 +1620,64 @@ public class ConcurrentLong2ReferenceChainedHashTable { + + public static final class TableEntry { + +- protected static final VarHandle TABLE_ENTRY_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(TableEntry[].class); ++ private static final VarHandle TABLE_ENTRY_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(TableEntry[].class); + +- protected final boolean resize; ++ private final boolean resize; + +- protected final long key; ++ private final long key; + +- protected volatile V value; +- protected static final VarHandle VALUE_HANDLE = ConcurrentUtil.getVarHandle(TableEntry.class, "value", Object.class); ++ private volatile V value; ++ private static final VarHandle VALUE_HANDLE = ConcurrentUtil.getVarHandle(TableEntry.class, "value", Object.class); + +- protected final V getValuePlain() { ++ private V getValuePlain() { + //noinspection unchecked + return (V)VALUE_HANDLE.get(this); + } + +- protected final V getValueAcquire() { ++ private V getValueAcquire() { + //noinspection unchecked + return (V)VALUE_HANDLE.getAcquire(this); + } + +- protected final V getValueVolatile() { ++ private V getValueVolatile() { + //noinspection unchecked + return (V)VALUE_HANDLE.getVolatile(this); + } + +- protected final void setValuePlain(final V value) { ++ private void setValuePlain(final V value) { + VALUE_HANDLE.set(this, (Object)value); + } + +- protected final void setValueRelease(final V value) { ++ private void setValueRelease(final V value) { + VALUE_HANDLE.setRelease(this, (Object)value); + } + +- protected final void setValueVolatile(final V value) { ++ private void setValueVolatile(final V value) { + VALUE_HANDLE.setVolatile(this, (Object)value); + } + +- protected volatile TableEntry next; +- protected static final VarHandle NEXT_HANDLE = ConcurrentUtil.getVarHandle(TableEntry.class, "next", TableEntry.class); ++ private volatile TableEntry next; ++ private static final VarHandle NEXT_HANDLE = ConcurrentUtil.getVarHandle(TableEntry.class, "next", TableEntry.class); + +- protected final TableEntry getNextPlain() { ++ private TableEntry getNextPlain() { + //noinspection unchecked + return (TableEntry)NEXT_HANDLE.get(this); + } + +- protected final TableEntry getNextVolatile() { ++ private TableEntry getNextVolatile() { + //noinspection unchecked + return (TableEntry)NEXT_HANDLE.getVolatile(this); + } + +- protected final void setNextPlain(final TableEntry next) { ++ private void setNextPlain(final TableEntry next) { + NEXT_HANDLE.set(this, next); + } + +- protected final void setNextRelease(final TableEntry next) { ++ private void setNextRelease(final TableEntry next) { + NEXT_HANDLE.setRelease(this, next); + } + +- protected final void setNextVolatile(final TableEntry next) { ++ private void setNextVolatile(final TableEntry next) { + NEXT_HANDLE.setVolatile(this, next); + } + +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/scheduler/SchedulerThreadPool.java b/src/main/java/ca/spottedleaf/concurrentutil/scheduler/SchedulerThreadPool.java +index 8197ccb1c4e5878dbd8007b5fb514640765ec8e4..85e6ef636d435a0ee4bf3e0760b0c87422c520a1 100644 +--- a/src/main/java/ca/spottedleaf/concurrentutil/scheduler/SchedulerThreadPool.java ++++ b/src/main/java/ca/spottedleaf/concurrentutil/scheduler/SchedulerThreadPool.java +@@ -13,6 +13,10 @@ import java.util.concurrent.atomic.AtomicLong; + import java.util.concurrent.locks.LockSupport; + import java.util.function.BooleanSupplier; + ++/** ++ * @deprecated To be replaced ++ */ ++@Deprecated + public class SchedulerThreadPool { + + public static final long DEADLINE_NOT_SET = Long.MIN_VALUE; +@@ -297,7 +301,9 @@ public class SchedulerThreadPool { + * is invoked for any scheduled task - otherwise, {@link #runTasks(BooleanSupplier)} may not be invoked to + * parse intermediate tasks. + *

    ++ * @deprecated To be replaced + */ ++ @Deprecated + public static abstract class SchedulableTick { + private static final AtomicLong ID_GENERATOR = new AtomicLong(); + public final long id = ID_GENERATOR.getAndIncrement(); +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedSortedSet.java b/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedSortedSet.java +index 212bc9ae2fc7d37d4a089a2921b00de1e97f7cc1..82c4c11b0b564c97ac92bd5f54e3754a7ba95184 100644 +--- a/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedSortedSet.java ++++ b/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedSortedSet.java +@@ -8,8 +8,8 @@ public final class LinkedSortedSet implements Iterable { + + public final Comparator comparator; + +- protected Link head; +- protected Link tail; ++ private Link head; ++ private Link tail; + + public LinkedSortedSet() { + this((Comparator)Comparator.naturalOrder()); +@@ -257,8 +257,6 @@ public final class LinkedSortedSet implements Iterable { + private Link prev; + private Link next; + +- private Link() {} +- + private Link(final E element) { + this.element = element; + } +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedUnsortedList.java b/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedUnsortedList.java +new file mode 100644 +index 0000000000000000000000000000000000000000..bd8eb4f25d1dee00fbf9c05c14b0d94c5c641a55 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedUnsortedList.java +@@ -0,0 +1,204 @@ ++package ca.spottedleaf.concurrentutil.set; ++ ++import java.util.Iterator; ++import java.util.NoSuchElementException; ++import java.util.Objects; ++ ++public final class LinkedUnsortedList implements Iterable { ++ ++ private Link head; ++ private Link tail; ++ ++ public LinkedUnsortedList() {} ++ ++ public void clear() { ++ this.head = this.tail = null; ++ } ++ ++ public boolean isEmpty() { ++ return this.head == null; ++ } ++ ++ public E first() { ++ final Link head = this.head; ++ return head == null ? null : head.element; ++ } ++ ++ public E last() { ++ final Link tail = this.tail; ++ return tail == null ? null : tail.element; ++ } ++ ++ public boolean containsFirst(final E element) { ++ for (Link curr = this.head; curr != null; curr = curr.next) { ++ if (Objects.equals(element, curr.element)) { ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ public boolean containsLast(final E element) { ++ for (Link curr = this.tail; curr != null; curr = curr.prev) { ++ if (Objects.equals(element, curr.element)) { ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ private void removeNode(final Link node) { ++ final Link prev = node.prev; ++ final Link next = node.next; ++ ++ // help GC ++ node.element = null; ++ node.prev = null; ++ node.next = null; ++ ++ if (prev == null) { ++ this.head = next; ++ } else { ++ prev.next = next; ++ } ++ ++ if (next == null) { ++ this.tail = prev; ++ } else { ++ next.prev = prev; ++ } ++ } ++ ++ public boolean remove(final Link link) { ++ if (link.element == null) { ++ return false; ++ } ++ ++ this.removeNode(link); ++ return true; ++ } ++ ++ public boolean removeFirst(final E element) { ++ for (Link curr = this.head; curr != null; curr = curr.next) { ++ if (Objects.equals(element, curr.element)) { ++ this.removeNode(curr); ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ public boolean removeLast(final E element) { ++ for (Link curr = this.tail; curr != null; curr = curr.prev) { ++ if (Objects.equals(element, curr.element)) { ++ this.removeNode(curr); ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ @Override ++ public Iterator iterator() { ++ return new Iterator<>() { ++ private Link next = LinkedUnsortedList.this.head; ++ ++ @Override ++ public boolean hasNext() { ++ return this.next != null; ++ } ++ ++ @Override ++ public E next() { ++ final Link next = this.next; ++ if (next == null) { ++ throw new NoSuchElementException(); ++ } ++ this.next = next.next; ++ return next.element; ++ } ++ }; ++ } ++ ++ public E pollFirst() { ++ final Link head = this.head; ++ if (head == null) { ++ return null; ++ } ++ ++ final E ret = head.element; ++ final Link next = head.next; ++ ++ // unlink head ++ this.head = next; ++ if (next == null) { ++ this.tail = null; ++ } else { ++ next.prev = null; ++ } ++ ++ // help GC ++ head.element = null; ++ head.next = null; ++ ++ return ret; ++ } ++ ++ public E pollLast() { ++ final Link tail = this.tail; ++ if (tail == null) { ++ return null; ++ } ++ ++ final E ret = tail.element; ++ final Link prev = tail.prev; ++ ++ // unlink tail ++ this.tail = prev; ++ if (prev == null) { ++ this.head = null; ++ } else { ++ prev.next = null; ++ } ++ ++ // help GC ++ tail.element = null; ++ tail.prev = null; ++ ++ return ret; ++ } ++ ++ public Link addLast(final E element) { ++ final Link curr = this.tail; ++ if (curr != null) { ++ return this.tail = new Link<>(element, curr, null); ++ } else { ++ return this.head = this.tail = new Link<>(element); ++ } ++ } ++ ++ public Link addFirst(final E element) { ++ final Link curr = this.head; ++ if (curr != null) { ++ return this.head = new Link<>(element, null, curr); ++ } else { ++ return this.head = this.tail = new Link<>(element); ++ } ++ } ++ ++ public static final class Link { ++ private E element; ++ private Link prev; ++ private Link next; ++ ++ private Link(final E element) { ++ this.element = element; ++ } ++ ++ private Link(final E element, final Link prev, final Link next) { ++ this.element = element; ++ this.prev = prev; ++ this.next = next; ++ } ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/util/ArrayUtil.java b/src/main/java/ca/spottedleaf/concurrentutil/util/ArrayUtil.java +deleted file mode 100644 +index ebb1ab06165addb173fea4d295001fe37f4e79d3..0000000000000000000000000000000000000000 +--- a/src/main/java/ca/spottedleaf/concurrentutil/util/ArrayUtil.java ++++ /dev/null +@@ -1,816 +0,0 @@ +-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 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 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 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 getVolatile(final T[] array, final int index) { +- final Object ret = OBJECT_ARRAY_HANDLE.getVolatile((Object[])array, index); +- return (T)ret; +- } +- +- public static void setPlain(final T[] array, final int index, final T value) { +- OBJECT_ARRAY_HANDLE.set((Object[])array, index, (Object)value); +- } +- +- public static void setOpaque(final T[] array, final int index, final T value) { +- OBJECT_ARRAY_HANDLE.setOpaque((Object[])array, index, (Object)value); +- } +- +- public static void setRelease(final T[] array, final int index, final T value) { +- OBJECT_ARRAY_HANDLE.setRelease((Object[])array, index, (Object)value); +- } +- +- public static void setVolatile(final T[] array, final int index, final T value) { +- OBJECT_ARRAY_HANDLE.setVolatile((Object[])array, index, (Object)value); +- } +- +- public static 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 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 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 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 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/IntegerUtil.java b/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java +index 77699c5fa9681f9ec7aa05cbb50eb60828e193ab..9d7b9b8158cd01d12adbd7896ff77bee9828e101 100644 +--- a/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java ++++ b/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java +@@ -170,6 +170,26 @@ public final class IntegerUtil { + return (mask ^ val) - mask; // if val < 0, then (0 ^ val) - 0 else (-1 ^ val) + 1 + } + ++ // https://lemire.me/blog/2019/02/08/faster-remainders-when-the-divisor-is-a-constant-beating-compilers-and-libdivide ++ /** ++ * ++ * Usage: ++ *
    ++     * {@code
    ++     *     static final long mult = getSimpleMultiplier(divisor, bits);
    ++     *     long x = ...;
    ++     *     long magic = x * mult;
    ++     *     long divQ = magic >>> bits;
    ++     *     long divR = ((magic & ((1 << bits) - 1)) * divisor) >>> bits;
    ++     * }
    ++     * 
    ++ * ++ * @param bits The number of bits of precision for the returned result ++ */ ++ public static long getUnsignedDivisorMagic(final long divisor, final int bits) { ++ return (((1L << bits) - 1L) / divisor) + 1; ++ } ++ + private IntegerUtil() { + throw new RuntimeException(); + } +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/util/Priority.java b/src/main/java/ca/spottedleaf/concurrentutil/util/Priority.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2919bbaa07b70f182438c3be8f9ebbe0649809b6 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/util/Priority.java +@@ -0,0 +1,145 @@ ++package ca.spottedleaf.concurrentutil.util; ++ ++public 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 Priority max(final Priority p1, final Priority p2) { ++ return p1.isHigherOrEqualPriority(p2) ? p1 : p2; ++ } ++ ++ // returns the lower priroity of the two ++ public static 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 Priority[] PRIORITIES = 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 Priority getPriority(final int priority) { ++ return PRIORITIES[priority + 1]; ++ } ++ ++ private static int priorityCounter; ++ ++ private static int nextCounter() { ++ return priorityCounter++; ++ } ++ ++ public final int priority; ++ ++ private Priority() { ++ this(nextCounter()); ++ } ++ ++ private Priority(final int priority) { ++ this.priority = priority; ++ } ++} +\ No newline at end of file diff --git a/patches/server/1070-fixup-MC-Utils.patch b/patches/server/1070-fixup-MC-Utils.patch new file mode 100644 index 000000000000..6bca72238a78 --- /dev/null +++ b/patches/server/1070-fixup-MC-Utils.patch @@ -0,0 +1,87 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Mon, 21 Oct 2024 12:21:54 -0700 +Subject: [PATCH] fixup! MC Utils + + +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java +index 0abba00741b39b69a7f167e5d2670f2565c9a752..96bbab283eb6c7e7863383fea0ddc62510391091 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java +@@ -1,6 +1,6 @@ + package ca.spottedleaf.moonrise.common.util; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.util.Priority; + import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; + import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk; + import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader; +@@ -23,27 +23,27 @@ 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); ++ scheduleChunkTask(level, chunkX, chunkZ, run, Priority.NORMAL); + } + +- public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) { ++ public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final Priority priority) { + ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkTask(chunkX, chunkZ, run, priority); + } + + 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 ChunkStatus toStatus, final boolean addTicket, final Priority priority, + final Consumer onComplete) { + ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, gen, toStatus, addTicket, priority, onComplete); + } + + 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 onComplete) { ++ final boolean addTicket, final Priority priority, final Consumer onComplete) { + ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); + } + + public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ, + final FullChunkStatus toStatus, final boolean addTicket, +- final PrioritisedExecutor.Priority priority, final Consumer onComplete) { ++ final Priority priority, final Consumer onComplete) { + ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); + } + +@@ -67,7 +67,7 @@ public final class ChunkSystem { + return getUpdatingChunkHolderCount(level) != 0; + } + +- public static boolean screenEntity(final ServerLevel level, final Entity entity) { ++ public static boolean screenEntity(final ServerLevel level, final Entity entity, final boolean fromDisk, final boolean event) { + return true; + } + +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 6baa313b8201ed23193d7885c85606b0899ade3c..3eb38271b6ca26099b2da04c2d969e32fd72b2af 100644 +--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java ++++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java +@@ -94,15 +94,13 @@ public class PersistentEntitySectionManager implements A + private boolean addEntity(T entity, boolean existing) { + org.spigotmc.AsyncCatcher.catchOp("Entity add"); // Paper + // 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(); +- boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted); +- if ((!wasRemoved && entityCasted.isRemoved()) || !screened) { +- // removed by callback +- return false; +- } ++ // I don't want to know why this is a generic type. ++ Entity entityCasted = (Entity)entity; ++ boolean wasRemoved = entityCasted.isRemoved(); ++ boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted, existing, false); ++ if ((!wasRemoved && entityCasted.isRemoved()) || !screened) { ++ // removed by callback ++ return false; + } + // Paper end - chunk system hooks + if (!this.addEntityUuid(entity)) { diff --git a/patches/server/1071-Revert-Custom-table-implementation-for-blockstate-st.patch b/patches/server/1071-Revert-Custom-table-implementation-for-blockstate-st.patch new file mode 100644 index 000000000000..fa362b310f73 --- /dev/null +++ b/patches/server/1071-Revert-Custom-table-implementation-for-blockstate-st.patch @@ -0,0 +1,345 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Mon, 21 Oct 2024 12:52:44 -0700 +Subject: [PATCH] Revert "Custom table implementation for blockstate state + lookups" + +This reverts commit 14a7e6521ba0ce6dc8ebf98a1ccce59a5ec6a194. + +TODO Replace via deleting the patch + +diff --git a/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java b/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java +deleted file mode 100644 +index 57d0cd3ad6f972e986c72a57f1a6e36003f190c2..0000000000000000000000000000000000000000 +--- a/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java ++++ /dev/null +@@ -1,160 +0,0 @@ +-package io.papermc.paper.util.table; +- +-import com.google.common.collect.Table; +-import net.minecraft.world.level.block.state.StateHolder; +-import net.minecraft.world.level.block.state.properties.Property; +-import java.util.Collection; +-import java.util.HashSet; +-import java.util.Map; +-import java.util.Set; +- +-public final class ZeroCollidingReferenceStateTable { +- +- // upper 32 bits: starting index +- // lower 32 bits: bitset for contained ids +- protected final long[] this_index_table; +- protected final Comparable[] this_table; +- protected final StateHolder this_state; +- +- protected long[] index_table; +- protected StateHolder[][] value_table; +- +- public ZeroCollidingReferenceStateTable(final StateHolder state, final Map, Comparable> this_map) { +- this.this_state = state; +- this.this_index_table = this.create_table(this_map.keySet()); +- +- int max_id = -1; +- for (final Property property : this_map.keySet()) { +- final int id = lookup_vindex(property, this.this_index_table); +- if (id > max_id) { +- max_id = id; +- } +- } +- +- this.this_table = new Comparable[max_id + 1]; +- for (final Map.Entry, Comparable> entry : this_map.entrySet()) { +- this.this_table[lookup_vindex(entry.getKey(), this.this_index_table)] = entry.getValue(); +- } +- } +- +- public void loadInTable(final Table, Comparable, StateHolder> table, +- final Map, Comparable> this_map) { +- final Set> combined = new HashSet<>(table.rowKeySet()); +- combined.addAll(this_map.keySet()); +- +- this.index_table = this.create_table(combined); +- +- int max_id = -1; +- for (final Property property : combined) { +- final int id = lookup_vindex(property, this.index_table); +- if (id > max_id) { +- max_id = id; +- } +- } +- +- this.value_table = new StateHolder[max_id + 1][]; +- +- final Map, Map, StateHolder>> map = table.rowMap(); +- for (final Property property : map.keySet()) { +- final Map, StateHolder> propertyMap = map.get(property); +- +- final int id = lookup_vindex(property, this.index_table); +- final StateHolder[] states = this.value_table[id] = new StateHolder[property.getPossibleValues().size()]; +- +- for (final Map.Entry, StateHolder> entry : propertyMap.entrySet()) { +- if (entry.getValue() == null) { +- // TODO what +- continue; +- } +- +- states[((Property)property).getIdFor(entry.getKey())] = entry.getValue(); +- } +- } +- +- +- for (final Map.Entry, Comparable> entry : this_map.entrySet()) { +- final Property property = entry.getKey(); +- final int index = lookup_vindex(property, this.index_table); +- +- if (this.value_table[index] == null) { +- this.value_table[index] = new StateHolder[property.getPossibleValues().size()]; +- } +- +- this.value_table[index][((Property)property).getIdFor(entry.getValue())] = this.this_state; +- } +- } +- +- +- protected long[] create_table(final Collection> collection) { +- int max_id = -1; +- for (final Property property : collection) { +- final int id = property.getId(); +- if (id > max_id) { +- max_id = id; +- } +- } +- +- final long[] ret = new long[((max_id + 1) + 31) >>> 5]; // ceil((max_id + 1) / 32) +- +- for (final Property property : collection) { +- final int id = property.getId(); +- +- ret[id >>> 5] |= (1L << (id & 31)); +- } +- +- int total = 0; +- for (int i = 1, len = ret.length; i < len; ++i) { +- ret[i] |= (long)(total += Long.bitCount(ret[i - 1] & 0xFFFFFFFFL)) << 32; +- } +- +- return ret; +- } +- +- public Comparable get(final Property state) { +- final Comparable[] table = this.this_table; +- final int index = lookup_vindex(state, this.this_index_table); +- +- if (index < 0 || index >= table.length) { +- return null; +- } +- return table[index]; +- } +- +- public StateHolder get(final Property property, final Comparable with) { +- final int withId = ((Property)property).getIdFor(with); +- if (withId < 0) { +- return null; +- } +- +- final int index = lookup_vindex(property, this.index_table); +- final StateHolder[][] table = this.value_table; +- if (index < 0 || index >= table.length) { +- return null; +- } +- +- final StateHolder[] values = table[index]; +- +- if (withId >= values.length) { +- return null; +- } +- +- return values[withId]; +- } +- +- protected static int lookup_vindex(final Property property, final long[] index_table) { +- final int id = property.getId(); +- final long bitset_mask = (1L << (id & 31)); +- final long lower_mask = bitset_mask - 1; +- final int index = id >>> 5; +- if (index >= index_table.length) { +- return -1; +- } +- final long index_value = index_table[index]; +- final long contains_check = ((index_value & bitset_mask) - 1) >> (Long.SIZE - 1); // -1L if doesn't contain +- +- // index = total bits set in lower table values (upper 32 bits of index_value) plus total bits set in lower indices below id +- // contains_check is 0 if the bitset had id set, else it's -1: so index is unaffected if contains_check == 0, +- // otherwise it comes out as -1. +- return (int)(((index_value >>> 32) + Long.bitCount(index_value & lower_mask)) | contains_check); +- } +-} +diff --git a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java +index 45744d86e9582a93a0cec26009deea091080fbbe..daedcfd867ed6171fb61bdcbded417a11c8a5b0f 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java ++++ b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java +@@ -39,13 +39,11 @@ public abstract class StateHolder { + private final Reference2ObjectArrayMap, Comparable> values; + private Table, Comparable, S> neighbours; + protected final MapCodec propertiesCodec; +- protected final io.papermc.paper.util.table.ZeroCollidingReferenceStateTable optimisedTable; // Paper - optimise state lookup + + protected StateHolder(O owner, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { + this.owner = owner; + this.values = propertyMap; + this.propertiesCodec = codec; +- this.optimisedTable = new io.papermc.paper.util.table.ZeroCollidingReferenceStateTable(this, propertyMap); // Paper - optimise state lookup + } + + public > S cycle(Property property) { +@@ -86,11 +84,11 @@ public abstract class StateHolder { + } + + public > boolean hasProperty(Property property) { +- return this.optimisedTable.get(property) != null; // Paper - optimise state lookup ++ return this.values.containsKey(property); + } + + public > T getValue(Property property) { +- Comparable comparable = this.optimisedTable.get(property); // Paper - optimise state lookup ++ Comparable comparable = this.values.get(property); + if (comparable == null) { + throw new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.owner); + } else { +@@ -99,18 +97,24 @@ public abstract class StateHolder { + } + + public > Optional getOptionalValue(Property property) { +- Comparable comparable = this.optimisedTable.get(property); // Paper - optimise state lookup ++ Comparable comparable = this.values.get(property); + return comparable == null ? Optional.empty() : Optional.of(property.getValueClass().cast(comparable)); + } + + public , V extends T> S setValue(Property property, V value) { +- // Paper start - optimise state lookup +- final S ret = (S)this.optimisedTable.get(property, value); +- if (ret == null) { +- throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value"); ++ Comparable comparable = this.values.get(property); ++ if (comparable == null) { ++ throw new IllegalArgumentException("Cannot set property " + property + " as it does not exist in " + this.owner); ++ } else if (comparable.equals(value)) { ++ return (S)this; ++ } else { ++ S object = this.neighbours.get(property, value); ++ if (object == null) { ++ throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value"); ++ } else { ++ return object; ++ } + } +- return ret; +- // Paper end - optimise state lookup + } + + public , V extends T> S trySetValue(Property property, V value) { +@@ -143,7 +147,7 @@ public abstract class StateHolder { + } + } + +- this.neighbours = (Table, Comparable, S>)(table.isEmpty() ? table : ArrayTable.create(table)); this.optimisedTable.loadInTable((Table)this.neighbours, this.values); // Paper - optimise state lookup ++ this.neighbours = (Table, Comparable, S>)(table.isEmpty() ? table : ArrayTable.create(table)); + } + } + +diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java +index ff5fd91257c4554c523682009efe1db83f53fd5b..b63116b333b6e06494091a82588acfb639bddb71 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java ++++ b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java +@@ -7,13 +7,6 @@ import java.util.Optional; + public class BooleanProperty extends Property { + private final ImmutableSet values = ImmutableSet.of(true, false); + +- // Paper start - optimise iblockdata state lookup +- @Override +- public final int getIdFor(final Boolean value) { +- return value.booleanValue() ? 1 : 0; +- } +- // Paper end - optimise iblockdata state lookup +- + protected BooleanProperty(String name) { + super(name, Boolean.class); + } +diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java +index 498c5abe0a9d024d77029719c621c1c8485791f3..3097298fe356df98967cf4bdeaaede69dfe8a441 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java ++++ b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java +@@ -15,15 +15,6 @@ public class EnumProperty & StringRepresentable> extends Prope + private final ImmutableSet values; + private final Map names = Maps.newHashMap(); + +- // Paper start - optimise iblockdata state lookup +- private int[] idLookupTable; +- +- @Override +- public final int getIdFor(final T value) { +- return this.idLookupTable[value.ordinal()]; +- } +- // Paper end - optimise iblockdata state lookup +- + protected EnumProperty(String name, Class type, Collection values) { + super(name, type); + this.values = ImmutableSet.copyOf(values); +@@ -36,14 +27,6 @@ public class EnumProperty & StringRepresentable> extends Prope + + this.names.put(string, enum_); + } +- // Paper start - optimise BlockState lookup +- int id = 0; +- this.idLookupTable = new int[type.getEnumConstants().length]; +- java.util.Arrays.fill(this.idLookupTable, -1); +- for (final T value : this.getPossibleValues()) { +- this.idLookupTable[value.ordinal()] = id++; +- } +- // Paper end - optimise BlockState lookup + } + + @Override +diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java +index 977504f2641d0133a572b0d5de85d058609343bb..3a850321a4bcc68058483b5fd53e829c425a68af 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java ++++ b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java +@@ -11,16 +11,6 @@ public class IntegerProperty extends Property { + public final int min; + public final int max; + +- // Paper start - optimise iblockdata state lookup +- @Override +- public final int getIdFor(final Integer value) { +- final int val = value.intValue(); +- final int ret = val - this.min; +- +- return ret | ((this.max - ret) >> 31); +- } +- // Paper end - optimise iblockdata state lookup +- + protected IntegerProperty(String name, int min, int max) { + super(name, Integer.class); + if (min < 0) { +diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java +index b9493e3762410aca8e683c32b5aef187c0bee082..9055f15af0cae55effa6942913a9d7edf3857e07 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java ++++ b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java +@@ -24,17 +24,6 @@ public abstract class Property> { + ); + private final Codec> valueCodec = this.codec.xmap(this::value, Property.Value::value); + +- // Paper start - optimise iblockdata state lookup +- private static final java.util.concurrent.atomic.AtomicInteger ID_GENERATOR = new java.util.concurrent.atomic.AtomicInteger(); +- private final int id = ID_GENERATOR.getAndIncrement(); +- +- public final int getId() { +- return this.id; +- } +- +- public abstract int getIdFor(final T value); +- // Paper end - optimise state lookup +- + protected Property(String name, Class type) { + this.clazz = type; + this.name = name; diff --git a/patches/server/1072-fixup-Optimize-BlockPosition-helper-methods.patch b/patches/server/1072-fixup-Optimize-BlockPosition-helper-methods.patch new file mode 100644 index 000000000000..f68e9eae926d --- /dev/null +++ b/patches/server/1072-fixup-Optimize-BlockPosition-helper-methods.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Mon, 21 Oct 2024 19:13:43 -0700 +Subject: [PATCH] fixup! Optimize BlockPosition helper methods + + +diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java +index 2767d6f97e8b314d23a8e62f22dfd396f5660d31..7362d471f9c1858e0dd7832e1ff59e3e51d7f249 100644 +--- a/src/main/java/net/minecraft/core/BlockPos.java ++++ b/src/main/java/net/minecraft/core/BlockPos.java +@@ -161,7 +161,7 @@ public class BlockPos extends Vec3i { + + @Override + public BlockPos above(int distance) { +- return distance == 0 ? this : new BlockPos(this.getX(), this.getY() + distance, this.getZ()); // Paper - Perf: Optimize BlockPosition ++ return distance == 0 ? this.immutable() : new BlockPos(this.getX(), this.getY() + distance, this.getZ()); // Paper - Perf: Optimize BlockPosition + } + + @Override +@@ -171,7 +171,7 @@ public class BlockPos extends Vec3i { + + @Override + public BlockPos below(int i) { +- return i == 0 ? this : new BlockPos(this.getX(), this.getY() - i, this.getZ()); // Paper - Perf: Optimize BlockPosition ++ return i == 0 ? this.immutable() : new BlockPos(this.getX(), this.getY() - i, this.getZ()); // Paper - Perf: Optimize BlockPosition + } + + @Override +@@ -181,7 +181,7 @@ public class BlockPos extends Vec3i { + + @Override + public BlockPos north(int distance) { +- return distance == 0 ? this : new BlockPos(this.getX(), this.getY(), this.getZ() - distance); // Paper - Perf: Optimize BlockPosition ++ return distance == 0 ? this.immutable() : new BlockPos(this.getX(), this.getY(), this.getZ() - distance); // Paper - Perf: Optimize BlockPosition + } + + @Override +@@ -191,7 +191,7 @@ public class BlockPos extends Vec3i { + + @Override + public BlockPos south(int distance) { +- return distance == 0 ? this : new BlockPos(this.getX(), this.getY(), this.getZ() + distance); // Paper - Perf: Optimize BlockPosition ++ return distance == 0 ? this.immutable() : new BlockPos(this.getX(), this.getY(), this.getZ() + distance); // Paper - Perf: Optimize BlockPosition + } + + @Override +@@ -201,7 +201,7 @@ public class BlockPos extends Vec3i { + + @Override + public BlockPos west(int distance) { +- return distance == 0 ? this : new BlockPos(this.getX() - distance, this.getY(), this.getZ()); // Paper - Perf: Optimize BlockPosition ++ return distance == 0 ? this.immutable() : new BlockPos(this.getX() - distance, this.getY(), this.getZ()); // Paper - Perf: Optimize BlockPosition + } + + @Override +@@ -211,7 +211,7 @@ public class BlockPos extends Vec3i { + + @Override + public BlockPos east(int distance) { +- return distance == 0 ? this : new BlockPos(this.getX() + distance, this.getY(), this.getZ()); // Paper - Perf: Optimize BlockPosition ++ return distance == 0 ? this.immutable() : new BlockPos(this.getX() + distance, this.getY(), this.getZ()); // Paper - Perf: Optimize BlockPosition + } + + @Override diff --git a/patches/server/1073-fixup-Moonrise-optimisation-patches.patch b/patches/server/1073-fixup-Moonrise-optimisation-patches.patch new file mode 100644 index 000000000000..42a3be51224c --- /dev/null +++ b/patches/server/1073-fixup-Moonrise-optimisation-patches.patch @@ -0,0 +1,14304 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Mon, 21 Oct 2024 11:06:24 -0700 +Subject: [PATCH] fixup! Moonrise optimisation patches + + +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java +new file mode 100644 +index 0000000000000000000000000000000000000000..69a20e9d72b02f28b349f24fd0ea08736888e642 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java +@@ -0,0 +1,115 @@ ++package ca.spottedleaf.moonrise.common; ++ ++import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder; ++import com.mojang.datafixers.DataFixer; ++import net.minecraft.core.BlockPos; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.server.level.GenerationChunkHolder; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.util.datafix.DataFixTypes; ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.level.BlockGetter; ++import net.minecraft.world.level.ChunkPos; ++import net.minecraft.world.level.Level; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.chunk.ChunkAccess; ++import net.minecraft.world.level.chunk.LevelChunk; ++import net.minecraft.world.level.chunk.ProtoChunk; ++import net.minecraft.world.level.chunk.storage.SerializableChunkData; ++import net.minecraft.world.level.entity.EntityTypeTest; ++import net.minecraft.world.phys.AABB; ++import java.util.List; ++import java.util.ServiceLoader; ++import java.util.function.Predicate; ++ ++public interface PlatformHooks { ++ public static PlatformHooks get() { ++ return Holder.INSTANCE; ++ } ++ ++ public String getBrand(); ++ ++ public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos); ++ ++ public Predicate maybeHasLightEmission(); ++ ++ public boolean hasCurrentlyLoadingChunk(); ++ ++ public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder); ++ ++ public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk); ++ ++ public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original); ++ ++ public boolean allowAsyncTicketUpdates(); ++ ++ public void onChunkHolderTicketChange(final ServerLevel world, final NewChunkHolder holder, final int oldLevel, final int newLevel); ++ ++ public void chunkUnloadFromWorld(final LevelChunk chunk); ++ ++ public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data); ++ ++ public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player); ++ ++ public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player); ++ ++ public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate predicate, ++ final List into); ++ ++ public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, ++ final AABB boundingBox, final Predicate predicate, ++ final List into, final int maxCount); ++ ++ public void entityMove(final Entity entity, final long oldSection, final long newSection); ++ ++ public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event); ++ ++ public boolean configFixMC224294(); ++ ++ public boolean configAutoConfigSendDistance(); ++ ++ public double configPlayerMaxLoadRate(); ++ ++ public double configPlayerMaxGenRate(); ++ ++ public double configPlayerMaxSendRate(); ++ ++ public int configPlayerMaxConcurrentLoads(); ++ ++ public int configPlayerMaxConcurrentGens(); ++ ++ public long configAutoSaveInterval(); ++ ++ public int configMaxAutoSavePerTick(); ++ ++ public boolean configFixMC159283(); ++ ++ // support for CB chunk mustNotSave ++ public boolean forceNoSave(final ChunkAccess chunk); ++ ++ public CompoundTag convertNBT(final DataFixTypes type, final DataFixer dataFixer, final CompoundTag nbt, ++ final int fromVersion, final int toVersion); ++ ++ public boolean hasMainChunkLoadHook(); ++ ++ public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData); ++ ++ public List modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List entities); ++ ++ public void unloadEntity(final Entity entity); ++ ++ public int modifyEntityTrackingRange(final Entity entity, final int currentRange); ++ ++ public static final class Holder { ++ private Holder() { ++ } ++ ++ private static final PlatformHooks INSTANCE; ++ ++ static { ++ INSTANCE = ServiceLoader.load(PlatformHooks.class, PlatformHooks.class.getClassLoader()).findFirst() ++ .orElseThrow(() -> new RuntimeException("Failed to locate PlatformHooks")); ++ } ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java +index ba68998f6ef57b24c72fd833bd7de440de9501cc..7fed43a1e7bcf35c4d7fd3224837a47fedd59860 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java +@@ -13,15 +13,15 @@ import java.util.NoSuchElementException; + */ + public final class EntityList implements Iterable { + +- protected final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); ++ private final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); + { + this.entityToIndex.defaultReturnValue(Integer.MIN_VALUE); + } + +- protected static final Entity[] EMPTY_LIST = new Entity[0]; ++ private static final Entity[] EMPTY_LIST = new Entity[0]; + +- protected Entity[] entities = EMPTY_LIST; +- protected int count; ++ private Entity[] entities = EMPTY_LIST; ++ private int count; + + public int size() { + return this.count; +@@ -94,10 +94,9 @@ public final class EntityList implements Iterable { + + @Override + public Iterator iterator() { +- return new Iterator() { +- +- Entity lastRet; +- int current; ++ return new Iterator<>() { ++ private Entity lastRet; ++ private int current; + + @Override + public boolean hasNext() { +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java +deleted file mode 100644 +index fcfbca333234c09f7c056bbfcd9ac8860b20a8db..0000000000000000000000000000000000000000 +--- a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java ++++ /dev/null +@@ -1,125 +0,0 @@ +-package ca.spottedleaf.moonrise.common.list; +- +-import it.unimi.dsi.fastutil.longs.LongIterator; +-import it.unimi.dsi.fastutil.shorts.Short2LongOpenHashMap; +-import java.util.Arrays; +-import net.minecraft.world.level.block.Block; +-import net.minecraft.world.level.block.state.BlockState; +-import net.minecraft.world.level.chunk.GlobalPalette; +- +-public final class IBlockDataList { +- +- private static final GlobalPalette GLOBAL_PALETTE = new GlobalPalette<>(Block.BLOCK_STATE_REGISTRY); +- +- // map of location -> (index | (location << 16) | (palette id << 32)) +- private final Short2LongOpenHashMap map = new Short2LongOpenHashMap(2, 0.8f); +- { +- this.map.defaultReturnValue(Long.MAX_VALUE); +- } +- +- private static final long[] EMPTY_LIST = new long[0]; +- +- private long[] byIndex = EMPTY_LIST; +- private int size; +- +- public static int getLocationKey(final int x, final int y, final int z) { +- return (x & 15) | (((z & 15) << 4)) | ((y & 255) << (4 + 4)); +- } +- +- public static BlockState getBlockDataFromRaw(final long raw) { +- return GLOBAL_PALETTE.valueFor((int)(raw >>> 32)); +- } +- +- public static int getIndexFromRaw(final long raw) { +- return (int)(raw & 0xFFFF); +- } +- +- public static int getLocationFromRaw(final long raw) { +- return (int)((raw >>> 16) & 0xFFFF); +- } +- +- public static long getRawFromValues(final int index, final int location, final BlockState data) { +- return (long)index | ((long)location << 16) | (((long)GLOBAL_PALETTE.idFor(data)) << 32); +- } +- +- public static long setIndexRawValues(final long value, final int index) { +- return value & ~(0xFFFF) | (index); +- } +- +- public long add(final int x, final int y, final int z, final BlockState data) { +- return this.add(getLocationKey(x, y, z), data); +- } +- +- public long add(final int location, final BlockState data) { +- final long curr = this.map.get((short)location); +- +- if (curr == Long.MAX_VALUE) { +- final int index = this.size++; +- final long raw = getRawFromValues(index, location, data); +- this.map.put((short)location, raw); +- +- if (index >= this.byIndex.length) { +- this.byIndex = Arrays.copyOf(this.byIndex, (int)Math.max(4L, this.byIndex.length * 2L)); +- } +- +- this.byIndex[index] = raw; +- return raw; +- } else { +- final int index = getIndexFromRaw(curr); +- final long raw = this.byIndex[index] = getRawFromValues(index, location, data); +- +- this.map.put((short)location, raw); +- +- return raw; +- } +- } +- +- public long remove(final int x, final int y, final int z) { +- return this.remove(getLocationKey(x, y, z)); +- } +- +- public long remove(final int location) { +- final long ret = this.map.remove((short)location); +- final int index = getIndexFromRaw(ret); +- if (ret == Long.MAX_VALUE) { +- return ret; +- } +- +- // move the entry at the end to this index +- final int endIndex = --this.size; +- final long end = this.byIndex[endIndex]; +- if (index != endIndex) { +- // not empty after this call +- this.map.put((short)getLocationFromRaw(end), setIndexRawValues(end, index)); +- } +- this.byIndex[index] = end; +- this.byIndex[endIndex] = 0L; +- +- return ret; +- } +- +- public int size() { +- return this.size; +- } +- +- public long getRaw(final int index) { +- return this.byIndex[index]; +- } +- +- public int getLocation(final int index) { +- return getLocationFromRaw(this.getRaw(index)); +- } +- +- public BlockState getData(final int index) { +- return getBlockDataFromRaw(this.getRaw(index)); +- } +- +- public void clear() { +- this.size = 0; +- this.map.clear(); +- } +- +- public LongIterator getRawIterator() { +- return this.map.values().iterator(); +- } +-} +\ No newline at end of file +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9f3b25bb2439f283f878db93973a02fcdcd14eed +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java +@@ -0,0 +1,77 @@ ++package ca.spottedleaf.moonrise.common.list; ++ ++import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; ++import java.util.Arrays; ++ ++public final class IntList { ++ ++ private final Int2IntOpenHashMap map = new Int2IntOpenHashMap(); ++ { ++ this.map.defaultReturnValue(Integer.MIN_VALUE); ++ } ++ ++ private static final int[] EMPTY_LIST = new int[0]; ++ ++ private int[] byIndex = EMPTY_LIST; ++ private int count; ++ ++ public int size() { ++ return this.count; ++ } ++ ++ public void setMinCapacity(final int len) { ++ final int[] byIndex = this.byIndex; ++ if (byIndex.length < len) { ++ this.byIndex = Arrays.copyOf(byIndex, len); ++ } ++ } ++ ++ public int getRaw(final int index) { ++ return this.byIndex[index]; ++ } ++ ++ public boolean add(final int value) { ++ final int count = this.count; ++ final int currIndex = this.map.putIfAbsent(value, count); ++ ++ if (currIndex != Integer.MIN_VALUE) { ++ return false; // already in this list ++ } ++ ++ int[] list = this.byIndex; ++ ++ if (list.length == count) { ++ // resize required ++ list = this.byIndex = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative ++ } ++ ++ list[count] = value; ++ this.count = count + 1; ++ ++ return true; ++ } ++ ++ public boolean remove(final int value) { ++ final int index = this.map.remove(value); ++ if (index == Integer.MIN_VALUE) { ++ return false; ++ } ++ ++ // move the entry at the end to this index ++ final int endIndex = --this.count; ++ final int end = this.byIndex[endIndex]; ++ if (index != endIndex) { ++ // not empty after this call ++ this.map.put(end, index); ++ } ++ this.byIndex[index] = end; ++ this.byIndex[endIndex] = 0; ++ ++ return true; ++ } ++ ++ public void clear() { ++ this.count = 0; ++ this.map.clear(); ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2bae9949ef325d0001aa638150fbbdf968367e75 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java +@@ -0,0 +1,77 @@ ++package ca.spottedleaf.moonrise.common.list; ++ ++import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap; ++import java.util.Arrays; ++ ++public final class ShortList { ++ ++ private final Short2ShortOpenHashMap map = new Short2ShortOpenHashMap(); ++ { ++ this.map.defaultReturnValue(Short.MIN_VALUE); ++ } ++ ++ private static final short[] EMPTY_LIST = new short[0]; ++ ++ private short[] byIndex = EMPTY_LIST; ++ private short count; ++ ++ public int size() { ++ return (int)this.count; ++ } ++ ++ public short getRaw(final int index) { ++ return this.byIndex[index]; ++ } ++ ++ public void setMinCapacity(final int len) { ++ final short[] byIndex = this.byIndex; ++ if (byIndex.length < len) { ++ this.byIndex = Arrays.copyOf(byIndex, len); ++ } ++ } ++ ++ public boolean add(final short value) { ++ final int count = (int)this.count; ++ final short currIndex = this.map.putIfAbsent(value, (short)count); ++ ++ if (currIndex != Short.MIN_VALUE) { ++ return false; // already in this list ++ } ++ ++ short[] list = this.byIndex; ++ ++ if (list.length == count) { ++ // resize required ++ list = this.byIndex = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative ++ } ++ ++ list[count] = value; ++ this.count = (short)(count + 1); ++ ++ return true; ++ } ++ ++ public boolean remove(final short value) { ++ final short index = this.map.remove(value); ++ if (index == Short.MIN_VALUE) { ++ return false; ++ } ++ ++ // move the entry at the end to this index ++ final short endIndex = --this.count; ++ final short end = this.byIndex[endIndex]; ++ if (index != endIndex) { ++ // not empty after this call ++ this.map.put(end, index); ++ } ++ this.byIndex[(int)index] = end; ++ this.byIndex[(int)endIndex] = (short)0; ++ ++ return true; ++ } ++ ++ public void clear() { ++ this.count = (short)0; ++ this.map.clear(); ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c2d917c2eac55b8a4411a6e159f177f9428b1150 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java +@@ -0,0 +1,22 @@ ++package ca.spottedleaf.moonrise.common.misc; ++ ++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import java.lang.invoke.VarHandle; ++ ++public final class LazyRunnable implements Runnable { ++ ++ private volatile Runnable toRun; ++ private static final VarHandle TO_RUN_HANDLE = ConcurrentUtil.getVarHandle(LazyRunnable.class, "toRun", Runnable.class); ++ ++ public void setRunnable(final Runnable run) { ++ final Runnable prev = (Runnable)TO_RUN_HANDLE.compareAndExchange(this, (Runnable)null, run); ++ if (prev != null) { ++ throw new IllegalStateException("Runnable already set"); ++ } ++ } ++ ++ @Override ++ public void run() { ++ ((Runnable)TO_RUN_HANDLE.getVolatile(this)).run(); ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java +index ab093b0e8ac6f762921eb1d15f5217345c4eba05..bb44de17a37082e57f2292a4f470740be1d09b11 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java +@@ -4,13 +4,17 @@ import ca.spottedleaf.moonrise.common.list.ReferenceList; + import ca.spottedleaf.moonrise.common.util.CoordinateUtils; + import ca.spottedleaf.moonrise.common.util.MoonriseConstants; + import ca.spottedleaf.moonrise.common.util.ChunkSystem; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; + import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants; ++import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel; + import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; + import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; + import net.minecraft.core.BlockPos; + import net.minecraft.server.level.ServerLevel; + import net.minecraft.server.level.ServerPlayer; + import net.minecraft.world.level.ChunkPos; ++import java.util.ArrayList; + + public final class NearbyPlayers { + +@@ -20,7 +24,27 @@ public final class NearbyPlayers { + GENERAL_REALLY_SMALL, + TICK_VIEW_DISTANCE, + VIEW_DISTANCE, +- SPAWN_RANGE, // Moonrise - chunk tick iteration ++ // Moonrise start - chunk tick iteration ++ SPAWN_RANGE { ++ @Override ++ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ((ChunkTickServerLevel)world).moonrise$addPlayerTickingRequest(chunkX, chunkZ); ++ } ++ ++ @Override ++ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ((ChunkTickServerLevel)world).moonrise$removePlayerTickingRequest(chunkX, chunkZ); ++ } ++ }; ++ // Moonrise end - chunk tick iteration ++ ++ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ++ } ++ ++ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ++ } + } + + private static final NearbyMapType[] MAP_TYPES = NearbyMapType.values(); +@@ -37,6 +61,12 @@ public final class NearbyPlayers { + private final ServerLevel world; + private final Reference2ReferenceOpenHashMap players = new Reference2ReferenceOpenHashMap<>(); + private final Long2ReferenceOpenHashMap byChunk = new Long2ReferenceOpenHashMap<>(); ++ private final Long2ReferenceOpenHashMap>[] directByChunk = new Long2ReferenceOpenHashMap[TOTAL_MAP_TYPES]; ++ { ++ for (int i = 0; i < this.directByChunk.length; ++i) { ++ this.directByChunk[i] = new Long2ReferenceOpenHashMap<>(); ++ } ++ } + + public NearbyPlayers(final ServerLevel world) { + this.world = world; +@@ -70,6 +100,16 @@ public final class NearbyPlayers { + } + } + ++ public void clear() { ++ if (this.players.isEmpty()) { ++ return; ++ } ++ ++ for (final ServerPlayer player : new ArrayList<>(this.players.keySet())) { ++ this.removePlayer(player); ++ } ++ } ++ + public void tickPlayer(final ServerPlayer player) { + final TrackedPlayer[] players = this.players.get(player); + if (players == null) { +@@ -94,38 +134,41 @@ public final class NearbyPlayers { + return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); + } + +- public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { +- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); ++ public TrackedChunk getChunk(final int chunkX, final int chunkZ) { ++ return this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ } + +- return chunk == null ? null : chunk.players[type.ordinal()]; ++ public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); + } + + public ReferenceList getPlayers(final ChunkPos pos, final NearbyMapType type) { +- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); +- +- return chunk == null ? null : chunk.players[type.ordinal()]; ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); + } + + public ReferenceList getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) { +- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); +- +- return chunk == null ? null : chunk.players[type.ordinal()]; ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + } + + public ReferenceList getPlayersByBlock(final int blockX, final int blockZ, final NearbyMapType type) { +- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); +- +- return chunk == null ? null : chunk.players[type.ordinal()]; ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); + } + + public static final class TrackedChunk { + + private static final ServerPlayer[] EMPTY_PLAYERS_ARRAY = new ServerPlayer[0]; + ++ private final long chunkKey; ++ private final NearbyPlayers nearbyPlayers; + private final ReferenceList[] players = new ReferenceList[TOTAL_MAP_TYPES]; + private int nonEmptyLists; + private long updateCount; + ++ public TrackedChunk(final long chunkKey, final NearbyPlayers nearbyPlayers) { ++ this.chunkKey = chunkKey; ++ this.nearbyPlayers = nearbyPlayers; ++ } ++ + public boolean isEmpty() { + return this.nonEmptyLists == 0; + } +@@ -145,7 +188,9 @@ public final class NearbyPlayers { + final ReferenceList list = this.players[idx]; + if (list == null) { + ++this.nonEmptyLists; +- (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)).add(player); ++ final ReferenceList players = (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)); ++ this.nearbyPlayers.directByChunk[idx].put(this.chunkKey, players); ++ players.add(player); + return; + } + +@@ -169,6 +214,7 @@ public final class NearbyPlayers { + + if (list.size() == 0) { + this.players[idx] = null; ++ this.nearbyPlayers.directByChunk[idx].remove(this.chunkKey); + --this.nonEmptyLists; + } + } +@@ -187,9 +233,19 @@ public final class NearbyPlayers { + protected void addCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { + final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); + +- NearbyPlayers.this.byChunk.computeIfAbsent(chunkKey, (final long keyInMap) -> { +- return new TrackedChunk(); +- }).addPlayer(parameter, this.type); ++ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey); ++ final NearbyMapType type = this.type; ++ if (chunk != null) { ++ chunk.addPlayer(parameter, type); ++ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); ++ } else { ++ final TrackedChunk created = new TrackedChunk(chunkKey, NearbyPlayers.this); ++ NearbyPlayers.this.byChunk.put(chunkKey, created); ++ created.addPlayer(parameter, type); ++ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); ++ ++ ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$requestChunkData(chunkKey).nearbyPlayers = created; ++ } + } + + @Override +@@ -201,10 +257,16 @@ public final class NearbyPlayers { + throw new IllegalStateException("Chunk should exist at " + new ChunkPos(chunkKey)); + } + +- chunk.removePlayer(parameter, this.type); ++ final NearbyMapType type = this.type; ++ chunk.removePlayer(parameter, type); ++ type.removeFrom(parameter, NearbyPlayers.this.world, chunkX, chunkZ); + + if (chunk.isEmpty()) { + NearbyPlayers.this.byChunk.remove(chunkKey); ++ final ChunkData chunkData = ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$releaseChunkData(chunkKey); ++ if (chunkData != null) { ++ chunkData.nearbyPlayers = null; ++ } + } + } + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java +index 96bbab283eb6c7e7863383fea0ddc62510391091..fc029c8fb22a7c8eeb23bfc171812f6da91c60fa 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java +@@ -1,15 +1,18 @@ + package ca.spottedleaf.moonrise.common.util; + + import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.PlatformHooks; + import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; + import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk; + import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader; + import ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemServerChunkCache; ++import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel; + import com.mojang.logging.LogUtils; + import net.minecraft.server.level.ChunkHolder; + import net.minecraft.server.level.FullChunkStatus; + import net.minecraft.server.level.ServerLevel; + import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.server.level.progress.ChunkProgressListener; + import net.minecraft.world.entity.Entity; + import net.minecraft.world.level.chunk.ChunkAccess; + import net.minecraft.world.level.chunk.LevelChunk; +@@ -68,6 +71,9 @@ public final class ChunkSystem { + } + + public static boolean screenEntity(final ServerLevel level, final Entity entity, final boolean fromDisk, final boolean event) { ++ if (!PlatformHooks.get().screenEntity(level, entity, fromDisk, event)) { ++ return false; ++ } + return true; + } + +@@ -76,7 +82,13 @@ public final class ChunkSystem { + } + + public static void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder) { +- ++ // Update progress listener for LevelLoadingScreen ++ final ChunkProgressListener progressListener = level.getChunkSource().chunkMap.progressListener; ++ if (progressListener != null) { ++ ChunkSystem.scheduleChunkTask(level, holder.getPos().x, holder.getPos().z, () -> { ++ progressListener.onStatusChange(holder.getPos(), null); ++ }); ++ } + } + + public static void onChunkPreBorder(final LevelChunk chunk, final ChunkHolder holder) { +@@ -108,16 +120,18 @@ public final class ChunkSystem { + ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder() + ); + if (!((ChunkSystemLevelChunk)chunk).moonrise$isPostProcessingDone()) { +- chunk.postProcessGeneration(); ++ chunk.postProcessGeneration((ServerLevel)chunk.getLevel()); + } + ((ServerLevel)chunk.getLevel()).startTickingChunk(chunk); + ((ServerLevel)chunk.getLevel()).getChunkSource().chunkMap.tickingGenerated.incrementAndGet(); ++ ((ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$markChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration + } + + public static void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) { + ((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getTickingChunks().remove( + ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder() + ); ++ ((ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$removeChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration + } + + public static void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java +index ac6f284ee4469d16c5655328b2488d7612832353..97848869df61648fc415e4d39f409f433202c274 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java +@@ -3,8 +3,12 @@ package ca.spottedleaf.moonrise.common.util; + public final class MixinWorkarounds { + + // mixins tries to find the owner of the clone() method, which doesn't exist and NPEs ++ // https://github.com/FabricMC/Mixin/pull/147 + public static long[] clone(final long[] values) { + return values.clone(); + } + ++ public static byte[] clone(final byte[] values) { ++ return values.clone(); ++ } + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java +index 3abe0bd2a820352b85306d554bf14a4cf6123091..c125c70a68130be373acc989053a6c0e487be924 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java +@@ -1,45 +1,100 @@ + package ca.spottedleaf.moonrise.common.util; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool; ++import ca.spottedleaf.concurrentutil.executor.thread.PrioritisedThreadPool; ++import ca.spottedleaf.moonrise.common.PlatformHooks; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; +-import java.io.File; ++import java.util.concurrent.TimeUnit; ++import java.util.concurrent.atomic.AtomicInteger; ++import java.util.function.Consumer; + + public final class MoonriseCommon { + + private static final Logger LOGGER = LoggerFactory.getLogger(MoonriseCommon.class); + +- // Paper start +- public static PrioritisedThreadPool WORKER_POOL; +- public static int WORKER_THREADS; +- public static void init(io.papermc.paper.configuration.GlobalConfiguration.ChunkSystem chunkSystem) { +- // Paper end ++ public static final PrioritisedThreadPool WORKER_POOL = new PrioritisedThreadPool( ++ new Consumer<>() { ++ private final AtomicInteger idGenerator = new AtomicInteger(); ++ ++ @Override ++ public void accept(Thread thread) { ++ thread.setDaemon(true); ++ thread.setName(PlatformHooks.get().getBrand() + " Common Worker #" + this.idGenerator.getAndIncrement()); ++ thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { ++ @Override ++ public void uncaughtException(final Thread thread, final Throwable throwable) { ++ LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); ++ } ++ }); ++ } ++ } ++ ); ++ public static final long WORKER_QUEUE_HOLD_TIME = (long)(20.0e6); // 20ms ++ public static final int CLIENT_DIVISION = 0; ++ public static final PrioritisedThreadPool.ExecutorGroup RENDER_EXECUTOR_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(CLIENT_DIVISION, 0); ++ public static final int SERVER_DIVISION = 1; ++ public static final PrioritisedThreadPool.ExecutorGroup PARALLEL_GEN_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); ++ public static final PrioritisedThreadPool.ExecutorGroup RADIUS_AWARE_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); ++ public static final PrioritisedThreadPool.ExecutorGroup LOAD_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); ++ ++ public static void adjustWorkerThreads(final int configWorkerThreads, final int configIoThreads) { + int defaultWorkerThreads = Runtime.getRuntime().availableProcessors() / 2; + if (defaultWorkerThreads <= 4) { + defaultWorkerThreads = defaultWorkerThreads <= 3 ? 1 : 2; + } else { + defaultWorkerThreads = defaultWorkerThreads / 2; + } +- defaultWorkerThreads = Integer.getInteger("Paper.WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); // Paper ++ defaultWorkerThreads = Integer.getInteger(PlatformHooks.get().getBrand() + ".WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); + +- int workerThreads = chunkSystem.workerThreads; // Paper ++ int workerThreads = configWorkerThreads; + + if (workerThreads <= 0) { + workerThreads = defaultWorkerThreads; + } + +- WORKER_POOL = new PrioritisedThreadPool( +- "Paper Worker Pool", workerThreads, // Paper +- (final Thread thread, final Integer id) -> { +- thread.setName("Paper Common Worker #" + id.intValue()); // Paper ++ final int ioThreads = Math.max(1, configIoThreads); ++ ++ WORKER_POOL.adjustThreadCount(workerThreads); ++ IO_POOL.adjustThreadCount(ioThreads); ++ ++ LOGGER.info(PlatformHooks.get().getBrand() + " is using " + workerThreads + " worker threads, " + ioThreads + " I/O threads"); ++ } ++ ++ public static final PrioritisedThreadPool IO_POOL = new PrioritisedThreadPool( ++ new Consumer<>() { ++ private final AtomicInteger idGenerator = new AtomicInteger(); ++ ++ @Override ++ public void accept(final Thread thread) { ++ thread.setDaemon(true); ++ thread.setName(PlatformHooks.get().getBrand() + " I/O Worker #" + this.idGenerator.getAndIncrement()); + thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(final Thread thread, final Throwable throwable) { + LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); + } + }); +- }, (long)(20.0e6)); // 20ms +- WORKER_THREADS = workerThreads; ++ } ++ } ++ ); ++ public static final long IO_QUEUE_HOLD_TIME = (long)(100.0e6); // 100ms ++ public static final PrioritisedThreadPool.ExecutorGroup CLIENT_PROFILER_IO_GROUP = IO_POOL.createExecutorGroup(CLIENT_DIVISION, 0); ++ public static final PrioritisedThreadPool.ExecutorGroup SERVER_REGION_IO_GROUP = IO_POOL.createExecutorGroup(SERVER_DIVISION, 0); ++ ++ public static void haltExecutors() { ++ MoonriseCommon.WORKER_POOL.shutdown(false); ++ LOGGER.info("Awaiting termination of worker pool for up to 60s..."); ++ if (!MoonriseCommon.WORKER_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { ++ LOGGER.error("Worker pool did not shut down in time!"); ++ MoonriseCommon.WORKER_POOL.halt(false); ++ } ++ ++ MoonriseCommon.IO_POOL.shutdown(false); ++ LOGGER.info("Awaiting termination of I/O pool for up to 60s..."); ++ if (!MoonriseCommon.IO_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { ++ LOGGER.error("I/O pool did not shut down in time!"); ++ MoonriseCommon.IO_POOL.halt(false); ++ } + } + + private MoonriseCommon() {} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java +index 1cf32d7d1bbc8a0a3f7cb9024c793f6744199f64..559c959aff3c9deef867b9e425fba3e2e669cac6 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java +@@ -1,8 +1,10 @@ + package ca.spottedleaf.moonrise.common.util; + ++import ca.spottedleaf.moonrise.common.PlatformHooks; ++ + public final class MoonriseConstants { + +- public static final int MAX_VIEW_DISTANCE = 32; ++ public static final int MAX_VIEW_DISTANCE = Integer.getInteger(PlatformHooks.get().getBrand() + ".MaxViewDistance", 32); + + private MoonriseConstants() {} + +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java b/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a9ff1c1a70faf4b7a64b265932f07a8b8f00c1ff +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java +@@ -0,0 +1,52 @@ ++package ca.spottedleaf.moonrise.common.util; ++ ++import net.minecraft.world.level.levelgen.LegacyRandomSource; ++ ++/** ++ * Avoid costly CAS of superclass ++ */ ++public final class SimpleRandom extends LegacyRandomSource { ++ ++ private static final long MULTIPLIER = 25214903917L; ++ private static final long ADDEND = 11L; ++ private static final int BITS = 48; ++ private static final long MASK = (1L << BITS) - 1; ++ ++ private long value; ++ ++ public SimpleRandom(final long seed) { ++ super(0L); ++ this.value = seed; ++ } ++ ++ @Override ++ public void setSeed(final long seed) { ++ this.value = (seed ^ MULTIPLIER) & MASK; ++ } ++ ++ private long advanceSeed() { ++ return this.value = ((this.value * MULTIPLIER) + ADDEND) & MASK; ++ } ++ ++ @Override ++ public int next(final int bits) { ++ return (int)(this.advanceSeed() >>> (BITS - bits)); ++ } ++ ++ @Override ++ public int nextInt() { ++ final long seed = this.advanceSeed(); ++ return (int)(seed >>> (BITS - Integer.SIZE)); ++ } ++ ++ @Override ++ public int nextInt(final int bound) { ++ if (bound <= 0) { ++ throw new IllegalArgumentException(); ++ } ++ ++ // https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ ++ final long value = this.advanceSeed() >>> (BITS - Integer.SIZE); ++ return (int)((value * (long)bound) >>> Integer.SIZE); ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java +index 11b7f15755dde766140c29bedca456c80d53293f..217d1f908a36a5177ba3cbb80a33f73d4dab0fa0 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java +@@ -77,11 +77,15 @@ public class TickThread extends Thread { + } + + public TickThread(final Runnable run, final String name) { +- this(run, name, ID_GENERATOR.incrementAndGet()); ++ this(null, run, name); + } + +- private TickThread(final Runnable run, final String name, final int id) { +- super(run, name); ++ public TickThread(final ThreadGroup group, final Runnable run, final String name) { ++ this(group, run, name, ID_GENERATOR.incrementAndGet()); ++ } ++ ++ private TickThread(final ThreadGroup group, final Runnable run, final String name, final int id) { ++ super(group, run, name); + this.id = id; + } + +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java +index af9623240ff2d389aa7090623f507720e7dbab7d..efda2688ae1254a82ba7f6bf8bf597ef224cbb86 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java +@@ -8,11 +8,19 @@ public final class WorldUtil { + // min, max are inclusive + + public static int getMaxSection(final LevelHeightAccessor world) { +- return world.getMaxSection() - 1; // getMaxSection() is exclusive ++ return world.getMaxSectionY(); ++ } ++ ++ public static int getMaxSection(final Level world) { ++ return world.getMaxSectionY(); + } + + public static int getMinSection(final LevelHeightAccessor world) { +- return world.getMinSection(); ++ return world.getMinSectionY(); ++ } ++ ++ public static int getMinSection(final Level world) { ++ return world.getMinSectionY(); + } + + public static int getMaxLightSection(final LevelHeightAccessor world) { +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java +index aef4fc0d3c272febe675d1ac846b88e58b4e7533..93bc56daec4526f373c84763b8c7ccb4a30e800b 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java +@@ -1,10 +1,10 @@ + package ca.spottedleaf.moonrise.patches.block_counting; + + import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +-import it.unimi.dsi.fastutil.ints.IntArrayList; ++import it.unimi.dsi.fastutil.shorts.ShortArrayList; + + public interface BlockCountingBitStorage { + +- public Int2ObjectOpenHashMap moonrise$countEntries(); ++ public Int2ObjectOpenHashMap moonrise$countEntries(); + + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java +index a08ddb0598d44368af5b6bace971ee31edf9919e..0d1443a113c07d7655e7b927a899447f70db8fa9 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java +@@ -1,11 +1,11 @@ + package ca.spottedleaf.moonrise.patches.block_counting; + +-import ca.spottedleaf.moonrise.common.list.IBlockDataList; ++import ca.spottedleaf.moonrise.common.list.ShortList; + + public interface BlockCountingChunkSection { + +- public int moonrise$getSpecialCollidingBlocks(); ++ public boolean moonrise$hasSpecialCollidingBlocks(); + +- public IBlockDataList moonrise$getTickingBlockList(); ++ public ShortList moonrise$getTickingBlockList(); + + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccess.java b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccess.java +new file mode 100644 +index 0000000000000000000000000000000000000000..89e75b454695e174c5619104eeb15eb923a2d9a7 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccess.java +@@ -0,0 +1,12 @@ ++package ca.spottedleaf.moonrise.patches.blockstate_propertyaccess; ++ ++public interface PropertyAccess { ++ ++ public int moonrise$getId(); ++ ++ public int moonrise$getIdFor(final T value); ++ ++ public T moonrise$getById(final int id); ++ ++ public void moonrise$setById(final T[] values); ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccessStateHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccessStateHolder.java +new file mode 100644 +index 0000000000000000000000000000000000000000..01da52b9e8a786824f199a057b62ce0431ecbc43 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccessStateHolder.java +@@ -0,0 +1,7 @@ ++package ca.spottedleaf.moonrise.patches.blockstate_propertyaccess; ++ ++public interface PropertyAccessStateHolder { ++ ++ public long moonrise$getTableIndex(); ++ ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b5335a2a8cb5dc7637c7112c8f7193389d726489 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java +@@ -0,0 +1,230 @@ ++package ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.util; ++ ++import ca.spottedleaf.concurrentutil.util.IntegerUtil; ++import ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess; ++import ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccessStateHolder; ++import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; ++import it.unimi.dsi.fastutil.objects.AbstractObjectSet; ++import it.unimi.dsi.fastutil.objects.AbstractReference2ObjectMap; ++import it.unimi.dsi.fastutil.objects.ObjectIterator; ++import it.unimi.dsi.fastutil.objects.ObjectSet; ++import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; ++import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; ++import java.util.ArrayList; ++import java.util.Collection; ++import java.util.Collections; ++import java.util.Iterator; ++import java.util.List; ++import java.util.Map; ++import net.minecraft.world.level.block.state.StateHolder; ++import net.minecraft.world.level.block.state.properties.Property; ++ ++public final class ZeroCollidingReferenceStateTable { ++ ++ private final Int2ObjectOpenHashMap propertyToIndexer; ++ private S[] lookup; ++ private final Collection> properties; ++ ++ public ZeroCollidingReferenceStateTable(final Collection> properties) { ++ this.propertyToIndexer = new Int2ObjectOpenHashMap<>(properties.size()); ++ this.properties = new ReferenceOpenHashSet<>(properties); ++ ++ final List> sortedProperties = new ArrayList<>(properties); ++ ++ // important that each table sees the same property order given the same _set_ of properties, ++ // as each table will calculate the index for the block state ++ sortedProperties.sort((final Property p1, final Property p2) -> { ++ return Integer.compare( ++ ((PropertyAccess)p1).moonrise$getId(), ++ ((PropertyAccess)p2).moonrise$getId() ++ ); ++ }); ++ ++ int currentMultiple = 1; ++ for (final Property property : sortedProperties) { ++ final int totalValues = property.getPossibleValues().size(); ++ ++ this.propertyToIndexer.put( ++ ((PropertyAccess)property).moonrise$getId(), ++ new Indexer( ++ totalValues, ++ currentMultiple, ++ IntegerUtil.getUnsignedDivisorMagic((long)currentMultiple, 32), ++ IntegerUtil.getUnsignedDivisorMagic((long)totalValues, 32) ++ ) ++ ); ++ ++ currentMultiple *= totalValues; ++ } ++ } ++ ++ public > boolean hasProperty(final Property property) { ++ return this.propertyToIndexer.containsKey(((PropertyAccess)property).moonrise$getId()); ++ } ++ ++ public long getIndex(final StateHolder stateHolder) { ++ long ret = 0L; ++ ++ for (final Map.Entry, Comparable> entry : stateHolder.getValues().entrySet()) { ++ final Property property = entry.getKey(); ++ final Comparable value = entry.getValue(); ++ ++ final Indexer indexer = this.propertyToIndexer.get(((PropertyAccess)property).moonrise$getId()); ++ ++ ret += (((PropertyAccess)property).moonrise$getIdFor(value)) * indexer.multiple; ++ } ++ ++ return ret; ++ } ++ ++ public boolean isLoaded() { ++ return this.lookup != null; ++ } ++ ++ public void loadInTable(final Map, Comparable>, S> universe) { ++ if (this.lookup != null) { ++ throw new IllegalStateException(); ++ } ++ ++ this.lookup = (S[])new StateHolder[universe.size()]; ++ ++ for (final Map.Entry, Comparable>, S> entry : universe.entrySet()) { ++ final S value = entry.getValue(); ++ if (value == null) { ++ continue; ++ } ++ this.lookup[(int)((PropertyAccessStateHolder)(StateHolder)value).moonrise$getTableIndex()] = value; ++ } ++ ++ for (final S value : this.lookup) { ++ if (value == null) { ++ throw new IllegalStateException(); ++ } ++ } ++ } ++ ++ public > T get(final long index, final Property property) { ++ final Indexer indexer = this.propertyToIndexer.get(((PropertyAccess)property).moonrise$getId()); ++ if (indexer == null) { ++ return null; ++ } ++ ++ final long divided = (index * indexer.multipleDivMagic) >>> 32; ++ final long modded = (((divided * indexer.modMagic) & 0xFFFFFFFFL) * indexer.totalValues) >>> 32; ++ // equiv to: divided = index / multiple ++ // modded = divided % totalValues ++ ++ return ((PropertyAccess)property).moonrise$getById((int)modded); ++ } ++ ++ public > S set(final long index, final Property property, final T with) { ++ final int newValueId = ((PropertyAccess)property).moonrise$getIdFor(with); ++ if (newValueId < 0) { ++ return null; ++ } ++ ++ final Indexer indexer = this.propertyToIndexer.get(((PropertyAccess)property).moonrise$getId()); ++ if (indexer == null) { ++ return null; ++ } ++ ++ final long divided = (index * indexer.multipleDivMagic) >>> 32; ++ final long modded = (((divided * indexer.modMagic) & 0xFFFFFFFFL) * indexer.totalValues) >>> 32; ++ // equiv to: divided = index / multiple ++ // modded = divided % totalValues ++ ++ // subtract out the old value, add in the new ++ final long newIndex = (((long)newValueId - modded) * indexer.multiple) + index; ++ ++ return this.lookup[(int)newIndex]; ++ } ++ ++ public > S trySet(final long index, final Property property, final T with, final S dfl) { ++ final Indexer indexer = this.propertyToIndexer.get(((PropertyAccess)property).moonrise$getId()); ++ if (indexer == null) { ++ return dfl; ++ } ++ ++ final int newValueId = ((PropertyAccess)property).moonrise$getIdFor(with); ++ if (newValueId < 0) { ++ return null; ++ } ++ ++ final long divided = (index * indexer.multipleDivMagic) >>> 32; ++ final long modded = (((divided * indexer.modMagic) & 0xFFFFFFFFL) * indexer.totalValues) >>> 32; ++ // equiv to: divided = index / multiple ++ // modded = divided % totalValues ++ ++ // subtract out the old value, add in the new ++ final long newIndex = (((long)newValueId - modded) * indexer.multiple) + index; ++ ++ return this.lookup[(int)newIndex]; ++ } ++ ++ public Collection> getProperties() { ++ return Collections.unmodifiableCollection(this.properties); ++ } ++ ++ public Map, Comparable> getMapView(final long stateIndex) { ++ return new MapView(stateIndex); ++ } ++ ++ private static final record Indexer( ++ int totalValues, int multiple, long multipleDivMagic, long modMagic ++ ) {} ++ ++ private class MapView extends AbstractReference2ObjectMap, Comparable> { ++ private final long stateIndex; ++ private EntrySet entrySet; ++ ++ MapView(final long stateIndex) { ++ this.stateIndex = stateIndex; ++ } ++ ++ @Override ++ public boolean containsKey(final Object key) { ++ return key instanceof Property prop && ZeroCollidingReferenceStateTable.this.hasProperty(prop); ++ } ++ ++ @Override ++ public int size() { ++ return ZeroCollidingReferenceStateTable.this.properties.size(); ++ } ++ ++ @Override ++ public ObjectSet, Comparable>> reference2ObjectEntrySet() { ++ if (this.entrySet == null) ++ this.entrySet = new EntrySet(); ++ return this.entrySet; ++ } ++ ++ @Override ++ public Comparable get(final Object key) { ++ return key instanceof Property prop ? ZeroCollidingReferenceStateTable.this.get(this.stateIndex, prop) : null; ++ } ++ ++ class EntrySet extends AbstractObjectSet, Comparable>> { ++ @Override ++ public ObjectIterator, Comparable>> iterator() { ++ final Iterator> propIterator = ZeroCollidingReferenceStateTable.this.properties.iterator(); ++ return new ObjectIterator<>() { ++ @Override ++ public boolean hasNext() { ++ return propIterator.hasNext(); ++ } ++ ++ @Override ++ public Entry, Comparable> next() { ++ Property prop = propIterator.next(); ++ return new AbstractReference2ObjectMap.BasicEntry<>(prop, ZeroCollidingReferenceStateTable.this.get(MapView.this.stateIndex, prop)); ++ } ++ }; ++ } ++ ++ @Override ++ public int size() { ++ return ZeroCollidingReferenceStateTable.this.properties.size(); ++ } ++ } ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java +index 5fca5dc7cdfa976bcc58dfcf0d14abb78a931475..cee2c8efbe280e20c63e2d66464dc835cd328e4a 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java +@@ -1,5 +1,6 @@ + package ca.spottedleaf.moonrise.patches.chunk_system; + ++import ca.spottedleaf.moonrise.common.PlatformHooks; + import net.minecraft.SharedConstants; + import net.minecraft.nbt.CompoundTag; + import net.minecraft.nbt.Tag; +@@ -25,21 +26,13 @@ public final class ChunkSystemConverters { + public static CompoundTag convertPoiCompoundTag(final CompoundTag data, final ServerLevel world) { + final int dataVersion = getDataVersion(data, DEFAULT_POI_DATA_VERSION); + +- // Paper start - dataconverter +- return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( +- ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.POI_CHUNK, data, dataVersion, getCurrentVersion() +- ); +- // Paper end - dataconverter ++ return PlatformHooks.get().convertNBT(DataFixTypes.POI_CHUNK, world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); + } + + public static CompoundTag convertEntityChunkCompoundTag(final CompoundTag data, final ServerLevel world) { + final int dataVersion = getDataVersion(data, DEFAULT_ENTITY_CHUNK_DATA_VERSION); + +- // Paper start - dataconverter +- return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( +- ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ENTITY_CHUNK, data, dataVersion, getCurrentVersion() +- ); +- // Paper end - dataconverter ++ return PlatformHooks.get().convertNBT(DataFixTypes.ENTITY_CHUNK, world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); + } + + private ChunkSystemConverters() {} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemFeatures.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemFeatures.java +deleted file mode 100644 +index 67f6dd9a4855611cfe242c2e37e90f6d27d4c823..0000000000000000000000000000000000000000 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemFeatures.java ++++ /dev/null +@@ -1,36 +0,0 @@ +-package ca.spottedleaf.moonrise.patches.chunk_system; +- +-import ca.spottedleaf.moonrise.patches.chunk_system.async_save.AsyncChunkSaveData; +-import net.minecraft.nbt.CompoundTag; +-import net.minecraft.server.level.ServerLevel; +-import net.minecraft.world.level.chunk.ChunkAccess; +- +-public final class ChunkSystemFeatures { +- +- public static boolean supportsAsyncChunkSave() { +- // uncertain how to properly pass AsyncSaveData to ChunkSerializer#write +- // additionally, there may be mods hooking into the write() call which may not be thread-safe to call +- return true; +- } +- +- public static AsyncChunkSaveData getAsyncSaveData(final ServerLevel world, final ChunkAccess chunk) { +- return net.minecraft.world.level.chunk.storage.ChunkSerializer.getAsyncSaveData(world, chunk); +- } +- +- public static CompoundTag saveChunkAsync(final ServerLevel world, final ChunkAccess chunk, final AsyncChunkSaveData asyncSaveData) { +- return net.minecraft.world.level.chunk.storage.ChunkSerializer.saveChunk(world, chunk, asyncSaveData); +- } +- +- public static boolean forceNoSave(final ChunkAccess chunk) { +- // support for CB chunk mustNotSave +- return chunk instanceof net.minecraft.world.level.chunk.LevelChunk levelChunk && levelChunk.mustNotSave; +- } +- +- public static boolean supportsAsyncChunkDeserialization() { +- // as it stands, the current problem with supporting this in Moonrise is that we are unsure that any mods +- // hooking into ChunkSerializer#read() are thread-safe to call +- return true; +- } +- +- private ChunkSystemFeatures() {} +-} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/async_save/AsyncChunkSaveData.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/async_save/AsyncChunkSaveData.java +deleted file mode 100644 +index becd1c6d54ed6c912aee3a9178a970e2751d3694..0000000000000000000000000000000000000000 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/async_save/AsyncChunkSaveData.java ++++ /dev/null +@@ -1,11 +0,0 @@ +-package ca.spottedleaf.moonrise.patches.chunk_system.async_save; +- +-import net.minecraft.nbt.ListTag; +-import net.minecraft.nbt.Tag; +- +-public record AsyncChunkSaveData( +- Tag blockTickList, // non-null if we had to go to the server's tick list +- Tag fluidTickList, // non-null if we had to go to the server's tick list +- ListTag blockEntities, +- long worldTime +-) {} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java +index 2c279854bdf214538380fa354e4298ec4bd9ac4e..c7da23900228aab3a5673eb5adfada5091140319 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java +@@ -1,5 +1,6 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.entity; + ++import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; + import net.minecraft.server.level.FullChunkStatus; + import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.monster.Shulker; +@@ -19,6 +20,10 @@ public interface ChunkSystemEntity { + + public void moonrise$setChunkStatus(final FullChunkStatus status); + ++ public ChunkData moonrise$getChunkData(); ++ ++ public void moonrise$setChunkData(final ChunkData chunkData); ++ + public int moonrise$getSectionX(); + + public void moonrise$setSectionX(final int x); +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java +index 73df26b27146bbad2106d57b22dd3c792ed3dd1d..a814512fcfb85312474ae2c2c21443843bf57831 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java +@@ -1,5 +1,6 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.io; + ++import net.minecraft.nbt.CompoundTag; + import net.minecraft.world.level.chunk.storage.RegionFile; + import java.io.IOException; + +@@ -11,4 +12,20 @@ public interface ChunkSystemRegionFileStorage { + + public RegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException; + ++ public MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite( ++ final int chunkX, final int chunkZ, final CompoundTag compound ++ ) throws IOException; ++ ++ public void moonrise$finishWrite( ++ final int chunkX, final int chunkZ, final MoonriseRegionFileIO.RegionDataController.WriteData writeData ++ ) throws IOException; ++ ++ public MoonriseRegionFileIO.RegionDataController.ReadData moonrise$readData( ++ final int chunkX, final int chunkZ ++ ) throws IOException; ++ ++ // if the return value is null, then the caller needs to re-try with a new call to readData() ++ public CompoundTag moonrise$finishRead( ++ final int chunkX, final int chunkZ, final MoonriseRegionFileIO.RegionDataController.ReadData readData ++ ) throws IOException; + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java +new file mode 100644 +index 0000000000000000000000000000000000000000..99f6f3e58b11b8967e6f1c3391c190d9a860ab7f +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java +@@ -0,0 +1,1707 @@ ++package ca.spottedleaf.moonrise.patches.chunk_system.io; ++ ++import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; ++import ca.spottedleaf.concurrentutil.completable.CallbackCompletable; ++import ca.spottedleaf.concurrentutil.completable.Completable; ++import ca.spottedleaf.concurrentutil.executor.Cancellable; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.queue.PrioritisedTaskQueue; ++import ca.spottedleaf.concurrentutil.function.BiLong1Function; ++import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; ++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.util.CoordinateUtils; ++import ca.spottedleaf.moonrise.common.util.TickThread; ++import ca.spottedleaf.moonrise.common.util.WorldUtil; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; ++import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.server.MinecraftServer; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.world.level.chunk.storage.RegionFile; ++import net.minecraft.world.level.chunk.storage.RegionFileStorage; ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; ++import java.io.DataInputStream; ++import java.io.DataOutputStream; ++import java.io.IOException; ++import java.lang.invoke.VarHandle; ++import java.util.concurrent.CompletableFuture; ++import java.util.concurrent.CompletionException; ++import java.util.concurrent.atomic.AtomicInteger; ++import java.util.concurrent.atomic.AtomicLong; ++import java.util.function.BiConsumer; ++import java.util.function.Consumer; ++ ++public final class MoonriseRegionFileIO { ++ ++ private static final int REGION_FILE_SHIFT = 5; ++ private static final Logger LOGGER = LoggerFactory.getLogger(MoonriseRegionFileIO.class); ++ ++ /** ++ * The types of RegionFiles controlled by the I/O thread(s). ++ */ ++ public static enum RegionFileType { ++ CHUNK_DATA, ++ POI_DATA, ++ ENTITY_DATA; ++ } ++ ++ public static RegionDataController getControllerFor(final ServerLevel world, final RegionFileType type) { ++ switch (type) { ++ case CHUNK_DATA: ++ return ((ChunkSystemServerLevel)world).moonrise$getChunkDataController(); ++ case POI_DATA: ++ return ((ChunkSystemServerLevel)world).moonrise$getPoiChunkDataController(); ++ case ENTITY_DATA: ++ return ((ChunkSystemServerLevel)world).moonrise$getEntityChunkDataController(); ++ default: ++ throw new IllegalStateException("Unknown controller type " + type); ++ } ++ } ++ ++ private static final RegionFileType[] CACHED_REGIONFILE_TYPES = RegionFileType.values(); ++ ++ /** ++ * Collects RegionFile data for a certain chunk. ++ */ ++ public static final class RegionFileData { ++ ++ private final boolean[] hasResult = new boolean[CACHED_REGIONFILE_TYPES.length]; ++ private final CompoundTag[] data = new CompoundTag[CACHED_REGIONFILE_TYPES.length]; ++ private final Throwable[] throwables = new Throwable[CACHED_REGIONFILE_TYPES.length]; ++ ++ /** ++ * Sets the result associated with the specified RegionFile type. Note that ++ * results can only be set once per RegionFile type. ++ * ++ * @param type The RegionFile type. ++ * @param data The result to set. ++ */ ++ public void setData(final MoonriseRegionFileIO.RegionFileType type, final CompoundTag data) { ++ final int index = type.ordinal(); ++ ++ if (this.hasResult[index]) { ++ throw new IllegalArgumentException("Result already exists for type " + type); ++ } ++ this.hasResult[index] = true; ++ this.data[index] = data; ++ } ++ ++ /** ++ * Sets the result associated with the specified RegionFile type. Note that ++ * results can only be set once per RegionFile type. ++ * ++ * @param type The RegionFile type. ++ * @param throwable The result to set. ++ */ ++ public void setThrowable(final MoonriseRegionFileIO.RegionFileType type, final Throwable throwable) { ++ final int index = type.ordinal(); ++ ++ if (this.hasResult[index]) { ++ throw new IllegalArgumentException("Result already exists for type " + type); ++ } ++ this.hasResult[index] = true; ++ this.throwables[index] = throwable; ++ } ++ ++ /** ++ * Returns whether there is a result for the specified RegionFile type. ++ * ++ * @param type Specified RegionFile type. ++ * ++ * @return Whether a result exists for {@code type}. ++ */ ++ public boolean hasResult(final MoonriseRegionFileIO.RegionFileType type) { ++ return this.hasResult[type.ordinal()]; ++ } ++ ++ /** ++ * Returns the data result for the RegionFile type. ++ * ++ * @param type Specified RegionFile type. ++ * ++ * @throws IllegalArgumentException If the result has not been set for {@code type}. ++ * @return The data result for the specified type. If the result is a {@code Throwable}, ++ * then returns {@code null}. ++ */ ++ public CompoundTag getData(final MoonriseRegionFileIO.RegionFileType type) { ++ final int index = type.ordinal(); ++ ++ if (!this.hasResult[index]) { ++ throw new IllegalArgumentException("Result does not exist for type " + type); ++ } ++ ++ return this.data[index]; ++ } ++ ++ /** ++ * Returns the throwable result for the RegionFile type. ++ * ++ * @param type Specified RegionFile type. ++ * ++ * @throws IllegalArgumentException If the result has not been set for {@code type}. ++ * @return The throwable result for the specified type. If the result is an {@code CompoundTag}, ++ * then returns {@code null}. ++ */ ++ public Throwable getThrowable(final MoonriseRegionFileIO.RegionFileType type) { ++ final int index = type.ordinal(); ++ ++ if (!this.hasResult[index]) { ++ throw new IllegalArgumentException("Result does not exist for type " + type); ++ } ++ ++ return this.throwables[index]; ++ } ++ } ++ ++ public static void flushRegionStorages(final ServerLevel world) throws IOException { ++ for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { ++ flushRegionStorages(world, type); ++ } ++ } ++ ++ public static void flushRegionStorages(final ServerLevel world, final RegionFileType type) throws IOException { ++ getControllerFor(world, type).getCache().flush(); ++ } ++ ++ public static void flush(final MinecraftServer server) { ++ for (final ServerLevel world : server.getAllLevels()) { ++ flush(world); ++ } ++ } ++ ++ public static void flush(final ServerLevel world) { ++ for (final RegionFileType regionFileType : CACHED_REGIONFILE_TYPES) { ++ flush(world, regionFileType); ++ } ++ } ++ ++ public static void flush(final ServerLevel world, final RegionFileType type) { ++ final RegionDataController taskController = getControllerFor(world, type); ++ ++ long failures = 1L; // start at 0.13ms ++ ++ while (taskController.hasTasks()) { ++ Thread.yield(); ++ failures = ConcurrentUtil.linearLongBackoff(failures, 125_000L, 5_000_000L); // 125us, 5ms ++ } ++ } ++ ++ public static void partialFlush(final ServerLevel world, final int tasksRemaining) { ++ for (long failures = 1L;;) { // start at 0.13ms ++ long totalTasks = 0L; ++ for (final RegionFileType regionFileType : CACHED_REGIONFILE_TYPES) { ++ totalTasks += getControllerFor(world, regionFileType).getTotalWorkingTasks(); ++ } ++ ++ if (totalTasks > (long)tasksRemaining) { ++ Thread.yield(); ++ failures = ConcurrentUtil.linearLongBackoff(failures, 125_000L, 5_000_000L); // 125us, 5ms ++ } else { ++ return; ++ } ++ } ++ } ++ ++ /** ++ * Returns the priority associated with blocking I/O based on the current thread. The goal is to avoid ++ * dumb plugins from taking away priority from threads we consider crucial. ++ * @return The priroity to use with blocking I/O on the current thread. ++ */ ++ public static Priority getIOBlockingPriorityForCurrentThread() { ++ if (TickThread.isTickThread()) { ++ return Priority.BLOCKING; ++ } ++ return Priority.HIGHEST; ++ } ++ ++ /** ++ * Returns the priority for the specified regionfile type for the specified chunk. ++ * @param world Specified world. ++ * @param chunkX Specified chunk x. ++ * @param chunkZ Specified chunk z. ++ * @param type Specified regionfile type. ++ * @return The priority for the chunk ++ */ ++ public static Priority getPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { ++ final RegionDataController taskController = getControllerFor(world, type); ++ final ChunkIOTask task = taskController.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ ++ if (task == null) { ++ return Priority.COMPLETING; ++ } ++ ++ return task.getPriority(); ++ } ++ ++ /** ++ * Sets the priority for all regionfile types for the specified chunk. Note that great care should ++ * be taken using this method, as there can be multiple tasks tied to the same chunk that want different ++ * priorities. ++ * ++ * @param world Specified world. ++ * @param chunkX Specified chunk x. ++ * @param chunkZ Specified chunk z. ++ * @param priority New priority. ++ * ++ * @see #raisePriority(ServerLevel, int, int, Priority) ++ * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) ++ * @see #lowerPriority(ServerLevel, int, int, Priority) ++ * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) ++ */ ++ public static void setPriority(final ServerLevel world, final int chunkX, final int chunkZ, ++ final Priority priority) { ++ for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { ++ MoonriseRegionFileIO.setPriority(world, chunkX, chunkZ, type, priority); ++ } ++ } ++ ++ /** ++ * Sets the priority for the specified regionfile type for the specified chunk. Note that great care should ++ * be taken using this method, as there can be multiple tasks tied to the same chunk that want different ++ * priorities. ++ * ++ * @param world Specified world. ++ * @param chunkX Specified chunk x. ++ * @param chunkZ Specified chunk z. ++ * @param type Specified regionfile type. ++ * @param priority New priority. ++ * ++ * @see #raisePriority(ServerLevel, int, int, Priority) ++ * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) ++ * @see #lowerPriority(ServerLevel, int, int, Priority) ++ * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) ++ */ ++ public static void setPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, ++ final Priority priority) { ++ final RegionDataController taskController = getControllerFor(world, type); ++ final ChunkIOTask task = taskController.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ ++ if (task != null) { ++ task.setPriority(priority); ++ } ++ } ++ ++ /** ++ * Raises the priority for all regionfile types for the specified chunk. ++ * ++ * @param world Specified world. ++ * @param chunkX Specified chunk x. ++ * @param chunkZ Specified chunk z. ++ * @param priority New priority. ++ * ++ * @see #setPriority(ServerLevel, int, int, Priority) ++ * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) ++ * @see #lowerPriority(ServerLevel, int, int, Priority) ++ * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) ++ */ ++ public static void raisePriority(final ServerLevel world, final int chunkX, final int chunkZ, ++ final Priority priority) { ++ for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { ++ MoonriseRegionFileIO.raisePriority(world, chunkX, chunkZ, type, priority); ++ } ++ } ++ ++ /** ++ * Raises the priority for the specified regionfile type for the specified chunk. ++ * ++ * @param world Specified world. ++ * @param chunkX Specified chunk x. ++ * @param chunkZ Specified chunk z. ++ * @param type Specified regionfile type. ++ * @param priority New priority. ++ * ++ * @see #setPriority(ServerLevel, int, int, Priority) ++ * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) ++ * @see #lowerPriority(ServerLevel, int, int, Priority) ++ * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) ++ */ ++ public static void raisePriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, ++ final Priority priority) { ++ final RegionDataController taskController = getControllerFor(world, type); ++ final ChunkIOTask task = taskController.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ ++ if (task != null) { ++ task.raisePriority(priority); ++ } ++ } ++ ++ /** ++ * Lowers the priority for all regionfile types for the specified chunk. ++ * ++ * @param world Specified world. ++ * @param chunkX Specified chunk x. ++ * @param chunkZ Specified chunk z. ++ * @param priority New priority. ++ * ++ * @see #raisePriority(ServerLevel, int, int, Priority) ++ * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) ++ * @see #setPriority(ServerLevel, int, int, Priority) ++ * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) ++ */ ++ public static void lowerPriority(final ServerLevel world, final int chunkX, final int chunkZ, ++ final Priority priority) { ++ for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { ++ MoonriseRegionFileIO.lowerPriority(world, chunkX, chunkZ, type, priority); ++ } ++ } ++ ++ /** ++ * Lowers the priority for the specified regionfile type for the specified chunk. ++ * ++ * @param world Specified world. ++ * @param chunkX Specified chunk x. ++ * @param chunkZ Specified chunk z. ++ * @param type Specified regionfile type. ++ * @param priority New priority. ++ * ++ * @see #raisePriority(ServerLevel, int, int, Priority) ++ * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) ++ * @see #setPriority(ServerLevel, int, int, Priority) ++ * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) ++ */ ++ public static void lowerPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, ++ final Priority priority) { ++ final RegionDataController taskController = getControllerFor(world, type); ++ final ChunkIOTask task = taskController.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ ++ if (task != null) { ++ task.lowerPriority(priority); ++ } ++ } ++ ++ /** ++ * Schedules the chunk data to be written asynchronously. ++ *

    ++ * Impl notes: ++ *

    ++ *
  • ++ * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means ++ * saves must be scheduled before a chunk is unloaded. ++ *
  • ++ *
  • ++ * Writes may be called concurrently, although only the "later" write will go through. ++ *
  • ++ * ++ * @param world Chunk's world ++ * @param chunkX Chunk's x coordinate ++ * @param chunkZ Chunk's z coordinate ++ * @param data Chunk's data ++ * @param type The regionfile type to write to. ++ * ++ * @throws IllegalStateException If the file io thread has shutdown. ++ */ ++ public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data, ++ final RegionFileType type) { ++ MoonriseRegionFileIO.scheduleSave(world, chunkX, chunkZ, data, type, Priority.NORMAL); ++ } ++ ++ /** ++ * Schedules the chunk data to be written asynchronously. ++ *

    ++ * Impl notes: ++ *

    ++ *
  • ++ * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means ++ * saves must be scheduled before a chunk is unloaded. ++ *
  • ++ *
  • ++ * Writes may be called concurrently, although only the "later" write will go through. ++ *
  • ++ * ++ * @param world Chunk's world ++ * @param chunkX Chunk's x coordinate ++ * @param chunkZ Chunk's z coordinate ++ * @param data Chunk's data ++ * @param type The regionfile type to write to. ++ * @param priority The minimum priority to schedule at. ++ * ++ * @throws IllegalStateException If the file io thread has shutdown. ++ */ ++ public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data, ++ final RegionFileType type, final Priority priority) { ++ scheduleSave( ++ world, chunkX, chunkZ, ++ (final BiConsumer consumer) -> { ++ consumer.accept(data, null); ++ }, null, type, priority ++ ); ++ } ++ ++ /** ++ * Schedules the chunk data to be written asynchronously. ++ *

    ++ * Impl notes: ++ *

    ++ *
  • ++ * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means ++ * saves must be scheduled before a chunk is unloaded. ++ *
  • ++ *
  • ++ * Writes may be called concurrently, although only the "later" write will go through. ++ *
  • ++ *
  • ++ * The specified write task, if not null, will have its priority controlled by the scheduler. ++ *
  • ++ * ++ * @param world Chunk's world ++ * @param chunkX Chunk's x coordinate ++ * @param chunkZ Chunk's z coordinate ++ * @param completable Chunk's pending data ++ * @param writeTask The task responsible for completing the pending chunk data ++ * @param type The regionfile type to write to. ++ * @param priority The minimum priority to schedule at. ++ * ++ * @throws IllegalStateException If the file io thread has shutdown. ++ */ ++ public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final CallbackCompletable completable, ++ final PrioritisedExecutor.PrioritisedTask writeTask, final RegionFileType type, final Priority priority) { ++ scheduleSave(world, chunkX, chunkZ, completable::addWaiter, writeTask, type, priority); ++ } ++ ++ /** ++ * Schedules the chunk data to be written asynchronously. ++ *

    ++ * Impl notes: ++ *

    ++ *
  • ++ * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means ++ * saves must be scheduled before a chunk is unloaded. ++ *
  • ++ *
  • ++ * Writes may be called concurrently, although only the "later" write will go through. ++ *
  • ++ *
  • ++ * The specified write task, if not null, will have its priority controlled by the scheduler. ++ *
  • ++ * ++ * @param world Chunk's world ++ * @param chunkX Chunk's x coordinate ++ * @param chunkZ Chunk's z coordinate ++ * @param completable Chunk's pending data ++ * @param writeTask The task responsible for completing the pending chunk data ++ * @param type The regionfile type to write to. ++ * @param priority The minimum priority to schedule at. ++ * ++ * @throws IllegalStateException If the file io thread has shutdown. ++ */ ++ public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final Completable completable, ++ final PrioritisedExecutor.PrioritisedTask writeTask, final RegionFileType type, final Priority priority) { ++ scheduleSave(world, chunkX, chunkZ, completable::whenComplete, writeTask, type, priority); ++ } ++ ++ private static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final Consumer> scheduler, ++ final PrioritisedExecutor.PrioritisedTask writeTask, final RegionFileType type, final Priority priority) { ++ final RegionDataController taskController = getControllerFor(world, type); ++ ++ final boolean[] created = new boolean[1]; ++ final ChunkIOTask.InProgressWrite write = new ChunkIOTask.InProgressWrite(writeTask); ++ final ChunkIOTask task = taskController.chunkTasks.compute(CoordinateUtils.getChunkKey(chunkX, chunkZ), ++ (final long keyInMap, final ChunkIOTask taskRunning) -> { ++ if (taskRunning == null || taskRunning.failedWrite) { ++ // no task is scheduled or the previous write failed - meaning we need to overwrite it ++ ++ // create task ++ final ChunkIOTask newTask = new ChunkIOTask( ++ world, taskController, chunkX, chunkZ, priority, new ChunkIOTask.InProgressRead() ++ ); ++ ++ newTask.pushPendingWrite(write); ++ ++ created[0] = true; ++ ++ return newTask; ++ } ++ ++ taskRunning.pushPendingWrite(write); ++ ++ return taskRunning; ++ } ++ ); ++ ++ write.schedule(task, scheduler); ++ ++ if (created[0]) { ++ taskController.startTask(task); ++ task.scheduleWriteCompress(); ++ } else { ++ task.raisePriority(priority); ++ } ++ } ++ ++ /** ++ * Schedules a load to be executed asynchronously. This task will load all regionfile types, and then call ++ * {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean)} ++ * for single load. ++ *

    ++ * Impl notes: ++ *

    ++ *
  • ++ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may ++ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of ++ * data is undefined behaviour, and can cause deadlock. ++ *
  • ++ * ++ * @param world Chunk's world ++ * @param chunkX Chunk's x coordinate ++ * @param chunkZ Chunk's z coordinate ++ * @param onComplete Consumer to execute once this task has completed ++ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost ++ * of this call. ++ * ++ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. ++ * ++ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) ++ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) ++ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) ++ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) ++ */ ++ public static Cancellable loadAllChunkData(final ServerLevel world, final int chunkX, final int chunkZ, ++ final Consumer onComplete, final boolean intendingToBlock) { ++ return MoonriseRegionFileIO.loadAllChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, Priority.NORMAL); ++ } ++ ++ /** ++ * Schedules a load to be executed asynchronously. This task will load all regionfile types, and then call ++ * {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority)} ++ * for single load. ++ *

    ++ * Impl notes: ++ *

    ++ *
  • ++ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may ++ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of ++ * data is undefined behaviour, and can cause deadlock. ++ *
  • ++ * ++ * @param world Chunk's world ++ * @param chunkX Chunk's x coordinate ++ * @param chunkZ Chunk's z coordinate ++ * @param onComplete Consumer to execute once this task has completed ++ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost ++ * of this call. ++ * @param priority The minimum priority to load the data at. ++ * ++ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. ++ * ++ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) ++ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) ++ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) ++ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) ++ */ ++ public static Cancellable loadAllChunkData(final ServerLevel world, final int chunkX, final int chunkZ, ++ final Consumer onComplete, final boolean intendingToBlock, ++ final Priority priority) { ++ return MoonriseRegionFileIO.loadChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, priority, CACHED_REGIONFILE_TYPES); ++ } ++ ++ /** ++ * Schedules a load to be executed asynchronously. This task will load data for the specified regionfile type(s), and ++ * then call {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean)} ++ * for single load. ++ *

    ++ * Impl notes: ++ *

    ++ *
  • ++ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may ++ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of ++ * data is undefined behaviour, and can cause deadlock. ++ *
  • ++ * ++ * @param world Chunk's world ++ * @param chunkX Chunk's x coordinate ++ * @param chunkZ Chunk's z coordinate ++ * @param onComplete Consumer to execute once this task has completed ++ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost ++ * of this call. ++ * @param types The regionfile type(s) to load. ++ * ++ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. ++ * ++ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) ++ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) ++ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) ++ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) ++ */ ++ public static Cancellable loadChunkData(final ServerLevel world, final int chunkX, final int chunkZ, ++ final Consumer onComplete, final boolean intendingToBlock, ++ final RegionFileType... types) { ++ return MoonriseRegionFileIO.loadChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, Priority.NORMAL, types); ++ } ++ ++ /** ++ * Schedules a load to be executed asynchronously. This task will load data for the specified regionfile type(s), and ++ * then call {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority)} ++ * for single load. ++ *

    ++ * Impl notes: ++ *

    ++ *
  • ++ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may ++ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of ++ * data is undefined behaviour, and can cause deadlock. ++ *
  • ++ * ++ * @param world Chunk's world ++ * @param chunkX Chunk's x coordinate ++ * @param chunkZ Chunk's z coordinate ++ * @param onComplete Consumer to execute once this task has completed ++ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost ++ * of this call. ++ * @param types The regionfile type(s) to load. ++ * @param priority The minimum priority to load the data at. ++ * ++ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. ++ * ++ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) ++ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) ++ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) ++ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) ++ */ ++ public static Cancellable loadChunkData(final ServerLevel world, final int chunkX, final int chunkZ, ++ final Consumer onComplete, final boolean intendingToBlock, ++ final Priority priority, final RegionFileType... types) { ++ if (types == null) { ++ throw new NullPointerException("Types cannot be null"); ++ } ++ if (types.length == 0) { ++ throw new IllegalArgumentException("Types cannot be empty"); ++ } ++ ++ final RegionFileData ret = new RegionFileData(); ++ ++ final Cancellable[] reads = new CancellableRead[types.length]; ++ final AtomicInteger completions = new AtomicInteger(); ++ final int expectedCompletions = types.length; ++ ++ for (int i = 0; i < expectedCompletions; ++i) { ++ final RegionFileType type = types[i]; ++ reads[i] = MoonriseRegionFileIO.loadDataAsync(world, chunkX, chunkZ, type, ++ (final CompoundTag data, final Throwable throwable) -> { ++ if (throwable != null) { ++ ret.setThrowable(type, throwable); ++ } else { ++ ret.setData(type, data); ++ } ++ ++ if (completions.incrementAndGet() == expectedCompletions) { ++ onComplete.accept(ret); ++ } ++ }, intendingToBlock, priority); ++ } ++ ++ return new CancellableReads(reads); ++ } ++ ++ /** ++ * Schedules a load to be executed asynchronously. This task will load the specified regionfile type, and then call ++ * {@code onComplete}. ++ *

    ++ * Impl notes: ++ *

    ++ *
  • ++ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may ++ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of ++ * data is undefined behaviour, and can cause deadlock. ++ *
  • ++ * ++ * @param world Chunk's world ++ * @param chunkX Chunk's x coordinate ++ * @param chunkZ Chunk's z coordinate ++ * @param onComplete Consumer to execute once this task has completed ++ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost ++ * of this call. ++ * ++ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. ++ * ++ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) ++ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) ++ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) ++ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) ++ */ ++ public static Cancellable loadDataAsync(final ServerLevel world, final int chunkX, final int chunkZ, ++ final RegionFileType type, final BiConsumer onComplete, ++ final boolean intendingToBlock) { ++ return MoonriseRegionFileIO.loadDataAsync(world, chunkX, chunkZ, type, onComplete, intendingToBlock, Priority.NORMAL); ++ } ++ ++ /** ++ * Schedules a load to be executed asynchronously. This task will load the specified regionfile type, and then call ++ * {@code onComplete}. ++ *

    ++ * Impl notes: ++ *

    ++ *
  • ++ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may ++ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of ++ * data is undefined behaviour, and can cause deadlock. ++ *
  • ++ * ++ * @param world Chunk's world ++ * @param chunkX Chunk's x coordinate ++ * @param chunkZ Chunk's z coordinate ++ * @param onComplete Consumer to execute once this task has completed ++ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost ++ * of this call. ++ * @param priority Minimum priority to load the data at. ++ * ++ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. ++ * ++ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) ++ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) ++ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) ++ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) ++ */ ++ public static Cancellable loadDataAsync(final ServerLevel world, final int chunkX, final int chunkZ, ++ final RegionFileType type, final BiConsumer onComplete, ++ final boolean intendingToBlock, final Priority priority) { ++ final RegionDataController taskController = getControllerFor(world, type); ++ ++ final ImmediateCallbackCompletion callbackInfo = new ImmediateCallbackCompletion(); ++ ++ final long key = CoordinateUtils.getChunkKey(chunkX, chunkZ); ++ final BiLong1Function compute = (final long keyInMap, final ChunkIOTask running) -> { ++ if (running == null) { ++ // not scheduled ++ ++ // set up task ++ final ChunkIOTask newTask = new ChunkIOTask( ++ world, taskController, chunkX, chunkZ, priority, new ChunkIOTask.InProgressRead() ++ ); ++ newTask.inProgressRead.addToAsyncWaiters(onComplete); ++ ++ callbackInfo.tasksNeedReadScheduling = true; ++ return newTask; ++ } ++ ++ final ChunkIOTask.InProgressWrite pendingWrite = running.inProgressWrite; ++ ++ if (pendingWrite == null) { ++ // need to add to waiters here, because the regionfile thread will use compute() to lock and check for cancellations ++ if (!running.inProgressRead.addToAsyncWaiters(onComplete)) { ++ callbackInfo.data = running.inProgressRead.value; ++ callbackInfo.throwable = running.inProgressRead.throwable; ++ callbackInfo.completeNow = true; ++ return running; ++ } ++ ++ callbackInfo.read = running.inProgressRead; ++ ++ return running; ++ } ++ ++ // at this stage we have to use the in progress write's data to avoid an order issue ++ ++ if (!pendingWrite.addToAsyncWaiters(onComplete)) { ++ // data is ready now ++ callbackInfo.data = pendingWrite.value; ++ callbackInfo.throwable = pendingWrite.throwable; ++ callbackInfo.completeNow = true; ++ return running; ++ } ++ ++ callbackInfo.write = pendingWrite; ++ ++ return running; ++ }; ++ ++ final ChunkIOTask ret = taskController.chunkTasks.compute(key, compute); ++ ++ // needs to be scheduled ++ if (callbackInfo.tasksNeedReadScheduling) { ++ taskController.startTask(ret); ++ ret.scheduleReadIO(); ++ } else if (callbackInfo.completeNow) { ++ try { ++ onComplete.accept(callbackInfo.data == null ? null : callbackInfo.data.copy(), callbackInfo.throwable); ++ } catch (final Throwable thr) { ++ LOGGER.error("Callback " + ConcurrentUtil.genericToString(onComplete) + " synchronously failed to handle chunk data for task " + ret.toString(), thr); ++ } ++ } else { ++ // we're waiting on a task we didn't schedule, so raise its priority to what we want ++ ret.raisePriority(priority); ++ } ++ ++ return new CancellableRead(onComplete, callbackInfo.read, callbackInfo.write); ++ } ++ ++ private static final class ImmediateCallbackCompletion { ++ ++ private CompoundTag data; ++ private Throwable throwable; ++ private boolean completeNow; ++ private boolean tasksNeedReadScheduling; ++ private ChunkIOTask.InProgressRead read; ++ private ChunkIOTask.InProgressWrite write; ++ ++ } ++ ++ /** ++ * Schedules a load task to be executed asynchronously, and blocks on that task. ++ * ++ * @param world Chunk's world ++ * @param chunkX Chunk's x coordinate ++ * @param chunkZ Chunk's z coordinate ++ * @param type Regionfile type ++ * @param priority Minimum priority to load the data at. ++ * ++ * @return The chunk data for the chunk. Note that a {@code null} result means the chunk or regionfile does not exist on disk. ++ * ++ * @throws IOException If the load fails for any reason ++ */ ++ public static CompoundTag loadData(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, ++ final Priority priority) throws IOException { ++ final CompletableFuture ret = new CompletableFuture<>(); ++ ++ MoonriseRegionFileIO.loadDataAsync(world, chunkX, chunkZ, type, (final CompoundTag compound, final Throwable thr) -> { ++ if (thr != null) { ++ ret.completeExceptionally(thr); ++ } else { ++ ret.complete(compound); ++ } ++ }, true, priority); ++ ++ try { ++ return ret.join(); ++ } catch (final CompletionException ex) { ++ throw new IOException(ex); ++ } ++ } ++ ++ private static final class CancellableRead implements Cancellable { ++ ++ private BiConsumer callback; ++ private ChunkIOTask.InProgressRead read; ++ private ChunkIOTask.InProgressWrite write; ++ ++ private CancellableRead(final BiConsumer callback, ++ final ChunkIOTask.InProgressRead read, ++ final ChunkIOTask.InProgressWrite write) { ++ this.callback = callback; ++ this.read = read; ++ this.write = write; ++ } ++ ++ @Override ++ public boolean cancel() { ++ final BiConsumer callback = this.callback; ++ final ChunkIOTask.InProgressRead read = this.read; ++ final ChunkIOTask.InProgressWrite write = this.write; ++ ++ if (callback == null || (read == null && write == null)) { ++ return false; ++ } ++ ++ this.callback = null; ++ this.read = null; ++ this.write = null; ++ ++ if (read != null) { ++ return read.cancel(callback); ++ } ++ if (write != null) { ++ return write.cancel(callback); ++ } ++ ++ // unreachable ++ throw new InternalError(); ++ } ++ } ++ ++ private static final class CancellableReads implements Cancellable { ++ ++ private Cancellable[] reads; ++ private static final VarHandle READS_HANDLE = ConcurrentUtil.getVarHandle(CancellableReads.class, "reads", Cancellable[].class); ++ ++ private CancellableReads(final Cancellable[] reads) { ++ this.reads = reads; ++ } ++ ++ @Override ++ public boolean cancel() { ++ final Cancellable[] reads = (Cancellable[])READS_HANDLE.getAndSet((CancellableReads)this, (Cancellable[])null); ++ ++ if (reads == null) { ++ return false; ++ } ++ ++ boolean ret = false; ++ ++ for (final Cancellable read : reads) { ++ ret |= read.cancel(); ++ } ++ ++ return ret; ++ } ++ } ++ ++ private static final class ChunkIOTask { ++ ++ private final ServerLevel world; ++ private final RegionDataController regionDataController; ++ private final int chunkX; ++ private final int chunkZ; ++ private Priority priority; ++ private PrioritisedExecutor.PrioritisedTask currentTask; ++ ++ private final InProgressRead inProgressRead; ++ private volatile InProgressWrite inProgressWrite; ++ private final ReferenceOpenHashSet allPendingWrites = new ReferenceOpenHashSet<>(); ++ ++ private RegionDataController.ReadData readData; ++ private RegionDataController.WriteData writeData; ++ private boolean failedWrite; ++ ++ public ChunkIOTask(final ServerLevel world, final RegionDataController regionDataController, ++ final int chunkX, final int chunkZ, final Priority priority, final InProgressRead inProgressRead) { ++ this.world = world; ++ this.regionDataController = regionDataController; ++ this.chunkX = chunkX; ++ this.chunkZ = chunkZ; ++ this.priority = priority; ++ this.inProgressRead = inProgressRead; ++ } ++ ++ public Priority getPriority() { ++ synchronized (this) { ++ return this.priority; ++ } ++ } ++ ++ // must hold lock on this object ++ private void updatePriority(final Priority priority) { ++ this.priority = priority; ++ if (this.currentTask != null) { ++ this.currentTask.setPriority(priority); ++ } ++ for (final InProgressWrite write : this.allPendingWrites) { ++ if (write.writeTask != null) { ++ write.writeTask.setPriority(priority); ++ } ++ } ++ } ++ ++ public boolean setPriority(final Priority priority) { ++ synchronized (this) { ++ if (this.priority == priority) { ++ return false; ++ } ++ ++ this.updatePriority(priority); ++ ++ return true; ++ } ++ } ++ ++ public boolean raisePriority(final Priority priority) { ++ synchronized (this) { ++ if (this.priority.isHigherOrEqualPriority(priority)) { ++ return false; ++ } ++ ++ this.updatePriority(priority); ++ ++ return true; ++ } ++ } ++ ++ public boolean lowerPriority(final Priority priority) { ++ synchronized (this) { ++ if (this.priority.isLowerOrEqualPriority(priority)) { ++ return false; ++ } ++ ++ this.updatePriority(priority); ++ ++ return true; ++ } ++ } ++ ++ private void pushPendingWrite(final InProgressWrite write) { ++ this.inProgressWrite = write; ++ synchronized (this) { ++ this.allPendingWrites.add(write); ++ if (write.writeTask != null) { ++ write.writeTask.setPriority(this.priority); ++ } ++ } ++ } ++ ++ private void pendingWriteComplete(final InProgressWrite write) { ++ synchronized (this) { ++ this.allPendingWrites.remove(write); ++ } ++ } ++ ++ public void scheduleReadIO() { ++ final PrioritisedExecutor.PrioritisedTask task; ++ synchronized (this) { ++ task = this.regionDataController.ioScheduler.createTask(this.chunkX, this.chunkZ, this::performReadIO, this.priority); ++ this.currentTask = task; ++ } ++ task.queue(); ++ } ++ ++ private void performReadIO() { ++ final InProgressRead read = this.inProgressRead; ++ final long chunkKey = CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ); ++ ++ final boolean[] canRead = new boolean[] { true }; ++ ++ if (read.hasNoWaiters()) { ++ // cancelled read? go to task controller to confirm ++ final ChunkIOTask inMap = this.regionDataController.chunkTasks.compute(chunkKey, (final long keyInMap, final ChunkIOTask valueInMap) -> { ++ if (valueInMap == null) { ++ throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkIOTask.this.toString() + ", report this!"); ++ } ++ if (valueInMap != ChunkIOTask.this) { ++ throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkIOTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); ++ } ++ ++ if (!read.hasNoWaiters()) { ++ return valueInMap; ++ } else { ++ canRead[0] = false; ++ } ++ ++ if (valueInMap.inProgressWrite != null) { ++ return valueInMap; ++ } ++ ++ return null; ++ }); ++ ++ if (inMap == null) { ++ this.regionDataController.endTask(this); ++ // read is cancelled - and no write pending, so we're done ++ return; ++ } ++ // if there is a write in progress, we don't actually have to worry about waiters gaining new entries - ++ // the readers will just use the in progress write, so the value in canRead is good to use without ++ // further synchronisation. ++ } ++ ++ if (canRead[0]) { ++ RegionDataController.ReadData readData = null; ++ Throwable throwable = null; ++ ++ try { ++ readData = this.regionDataController.readData(this.chunkX, this.chunkZ); ++ } catch (final Throwable thr) { ++ throwable = thr; ++ LOGGER.error("Failed to read chunk data for task: " + this.toString(), thr); ++ } ++ ++ if (throwable != null) { ++ this.finishRead(null, throwable); ++ } else { ++ switch (readData.result()) { ++ case NO_DATA: ++ case SYNC_READ: { ++ this.finishRead(readData.syncRead(), null); ++ break; ++ } ++ case HAS_DATA: { ++ this.readData = readData; ++ this.scheduleReadDecompress(); ++ // read will handle write scheduling ++ return; ++ } ++ default: { ++ throw new IllegalStateException("Unknown state: " + readData.result()); ++ } ++ } ++ } ++ } ++ ++ if (!this.tryAbortWrite()) { ++ this.scheduleWriteCompress(); ++ } ++ } ++ ++ private void scheduleReadDecompress() { ++ final PrioritisedExecutor.PrioritisedTask task; ++ synchronized (this) { ++ task = this.regionDataController.compressionExecutor.createTask(this::performReadDecompress, this.priority); ++ this.currentTask = task; ++ } ++ task.queue(); ++ } ++ ++ private void performReadDecompress() { ++ final RegionDataController.ReadData readData = this.readData; ++ this.readData = null; ++ ++ CompoundTag compoundTag = null; ++ Throwable throwable = null; ++ ++ try { ++ compoundTag = this.regionDataController.finishRead(this.chunkX, this.chunkZ, readData); ++ } catch (final Throwable thr) { ++ throwable = thr; ++ LOGGER.error("Failed to decompress chunk data for task: " + this.toString(), thr); ++ } ++ ++ if (compoundTag == null) { ++ // need to re-try from the start ++ this.scheduleReadIO(); ++ return; ++ } ++ ++ this.finishRead(compoundTag, throwable); ++ if (!this.tryAbortWrite()) { ++ this.scheduleWriteCompress(); ++ } ++ } ++ ++ private void finishRead(final CompoundTag compoundTag, final Throwable throwable) { ++ this.inProgressRead.complete(this, compoundTag, throwable); ++ } ++ ++ public void scheduleWriteCompress() { ++ final InProgressWrite inProgressWrite = this.inProgressWrite; ++ ++ final PrioritisedExecutor.PrioritisedTask task; ++ synchronized (this) { ++ task = this.regionDataController.compressionExecutor.createTask(() -> { ++ ChunkIOTask.this.performWriteCompress(inProgressWrite); ++ }, this.priority); ++ this.currentTask = task; ++ } ++ ++ inProgressWrite.addToWaiters(this, (final CompoundTag data, final Throwable throwable) -> { ++ task.queue(); ++ }); ++ } ++ ++ private boolean tryAbortWrite() { ++ final long chunkKey = CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ); ++ if (this.inProgressWrite == null) { ++ final ChunkIOTask inMap = this.regionDataController.chunkTasks.compute(chunkKey, (final long keyInMap, final ChunkIOTask valueInMap) -> { ++ if (valueInMap == null) { ++ throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkIOTask.this.toString() + ", report this!"); ++ } ++ if (valueInMap != ChunkIOTask.this) { ++ throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkIOTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); ++ } ++ ++ if (valueInMap.inProgressWrite != null) { ++ return valueInMap; ++ } ++ ++ return null; ++ }); ++ ++ if (inMap == null) { ++ this.regionDataController.endTask(this); ++ return true; // set the task value to null, indicating we're done ++ } // else: inProgressWrite changed, so now we have something to write ++ } ++ ++ return false; ++ } ++ ++ private void performWriteCompress(final InProgressWrite inProgressWrite) { ++ final CompoundTag write = inProgressWrite.value; ++ if (!inProgressWrite.isComplete()) { ++ throw new IllegalStateException("Should be writable"); ++ } ++ ++ RegionDataController.WriteData writeData = null; ++ boolean failedWrite = false; ++ ++ try { ++ writeData = this.regionDataController.startWrite(this.chunkX, this.chunkZ, write); ++ } catch (final Throwable thr) { ++ // TODO implement this? ++ /*if (thr instanceof RegionFileStorage.RegionFileSizeException) { ++ final int maxSize = RegionFile.MAX_CHUNK_SIZE / (1024 * 1024); ++ LOGGER.error("Chunk at (" + this.chunkX + "," + this.chunkZ + ") in '" + WorldUtil.getWorldName(this.world) + "' exceeds max size of " + maxSize + "MiB, it has been deleted from disk."); ++ } else */ ++ { ++ failedWrite = thr instanceof IOException; ++ LOGGER.error("Failed to write chunk data for task: " + this.toString(), thr); ++ } ++ } ++ ++ if (writeData == null) { ++ // null if a throwable was encountered ++ ++ // we cannot continue to the I/O stage here, so try to complete ++ ++ if (this.tryCompleteWrite(inProgressWrite, failedWrite)) { ++ return; ++ } else { ++ // fetch new data and try again ++ this.scheduleWriteCompress(); ++ return; ++ } ++ } else { ++ // writeData != null && !failedWrite ++ // we can continue to I/O stage ++ this.writeData = writeData; ++ this.scheduleWriteIO(inProgressWrite); ++ return; ++ } ++ } ++ ++ private void scheduleWriteIO(final InProgressWrite inProgressWrite) { ++ final PrioritisedExecutor.PrioritisedTask task; ++ synchronized (this) { ++ task = this.regionDataController.ioScheduler.createTask(this.chunkX, this.chunkZ, () -> { ++ ChunkIOTask.this.runWriteIO(inProgressWrite); ++ }, this.priority); ++ this.currentTask = task; ++ } ++ task.queue(); ++ } ++ ++ private void runWriteIO(final InProgressWrite inProgressWrite) { ++ RegionDataController.WriteData writeData = this.writeData; ++ this.writeData = null; ++ ++ boolean failedWrite = false; ++ ++ try { ++ this.regionDataController.finishWrite(this.chunkX, this.chunkZ, writeData); ++ } catch (final Throwable thr) { ++ failedWrite = thr instanceof IOException; ++ LOGGER.error("Failed to write chunk data for task: " + this.toString(), thr); ++ } ++ ++ if (!this.tryCompleteWrite(inProgressWrite, failedWrite)) { ++ // fetch new data and try again ++ this.scheduleWriteCompress(); ++ } ++ return; ++ } ++ ++ private boolean tryCompleteWrite(final InProgressWrite written, final boolean failedWrite) { ++ final long chunkKey = CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ); ++ ++ final boolean[] done = new boolean[] { false }; ++ ++ this.regionDataController.chunkTasks.compute(chunkKey, (final long keyInMap, final ChunkIOTask valueInMap) -> { ++ if (valueInMap == null) { ++ throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkIOTask.this.toString() + ", report this!"); ++ } ++ if (valueInMap != ChunkIOTask.this) { ++ throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkIOTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); ++ } ++ if (valueInMap.inProgressWrite == written) { ++ valueInMap.failedWrite = failedWrite; ++ done[0] = true; ++ // keep the data in map if we failed the write so we can try to prevent data loss ++ return failedWrite ? valueInMap : null; ++ } ++ // different data than expected, means we need to retry write ++ return valueInMap; ++ }); ++ ++ if (done[0]) { ++ this.regionDataController.endTask(this); ++ return true; ++ } ++ return false; ++ } ++ ++ @Override ++ public String toString() { ++ return "Task for world: '" + WorldUtil.getWorldName(this.world) + "' at (" + this.chunkX + "," ++ + this.chunkZ + ") type: " + this.regionDataController.type.name() + ", hash: " + this.hashCode(); ++ } ++ ++ private static final class InProgressRead { ++ ++ private static final Logger LOGGER = LoggerFactory.getLogger(InProgressRead.class); ++ ++ private CompoundTag value; ++ private Throwable throwable; ++ private final MultiThreadedQueue> callbacks = new MultiThreadedQueue<>(); ++ ++ public boolean hasNoWaiters() { ++ return this.callbacks.isEmpty(); ++ } ++ ++ public boolean addToAsyncWaiters(final BiConsumer callback) { ++ return this.callbacks.add(callback); ++ } ++ ++ public boolean cancel(final BiConsumer callback) { ++ return this.callbacks.remove(callback); ++ } ++ ++ public void complete(final ChunkIOTask task, final CompoundTag value, final Throwable throwable) { ++ this.value = value; ++ this.throwable = throwable; ++ ++ BiConsumer consumer; ++ while ((consumer = this.callbacks.pollOrBlockAdds()) != null) { ++ try { ++ consumer.accept(value == null ? null : value.copy(), throwable); ++ } catch (final Throwable thr) { ++ LOGGER.error("Callback " + ConcurrentUtil.genericToString(consumer) + " failed to handle chunk data (read) for task " + task.toString(), thr); ++ } ++ } ++ } ++ } ++ ++ private static final class InProgressWrite { ++ ++ private static final Logger LOGGER = LoggerFactory.getLogger(InProgressWrite.class); ++ ++ private CompoundTag value; ++ private Throwable throwable; ++ private volatile boolean complete; ++ private final MultiThreadedQueue> callbacks = new MultiThreadedQueue<>(); ++ ++ private final PrioritisedExecutor.PrioritisedTask writeTask; ++ ++ public InProgressWrite(final PrioritisedExecutor.PrioritisedTask writeTask) { ++ this.writeTask = writeTask; ++ } ++ ++ public boolean isComplete() { ++ return this.complete; ++ } ++ ++ public void schedule(final ChunkIOTask task, final Consumer> scheduler) { ++ scheduler.accept((final CompoundTag data, final Throwable throwable) -> { ++ InProgressWrite.this.complete(task, data, throwable); ++ }); ++ } ++ ++ public boolean addToAsyncWaiters(final BiConsumer callback) { ++ return this.callbacks.add(callback); ++ } ++ ++ public void addToWaiters(final ChunkIOTask task, final BiConsumer consumer) { ++ if (!this.callbacks.add(consumer)) { ++ this.syncAccept(task, consumer, this.value, this.throwable); ++ } ++ } ++ ++ private void syncAccept(final ChunkIOTask task, final BiConsumer consumer, final CompoundTag value, final Throwable throwable) { ++ try { ++ consumer.accept(value == null ? null : value.copy(), throwable); ++ } catch (final Throwable thr) { ++ LOGGER.error("Callback " + ConcurrentUtil.genericToString(consumer) + " failed to handle chunk data (write) for task " + task.toString(), thr); ++ } ++ } ++ ++ public void complete(final ChunkIOTask task, final CompoundTag value, final Throwable throwable) { ++ this.value = value; ++ this.throwable = throwable; ++ this.complete = true; ++ ++ task.pendingWriteComplete(this); ++ ++ BiConsumer consumer; ++ while ((consumer = this.callbacks.pollOrBlockAdds()) != null) { ++ this.syncAccept(task, consumer, value, throwable); ++ } ++ } ++ ++ public boolean cancel(final BiConsumer callback) { ++ return this.callbacks.remove(callback); ++ } ++ } ++ } ++ ++ public static abstract class RegionDataController { ++ ++ public final RegionFileType type; ++ private final PrioritisedExecutor compressionExecutor; ++ private final IOScheduler ioScheduler; ++ private final ConcurrentLong2ReferenceChainedHashTable chunkTasks = new ConcurrentLong2ReferenceChainedHashTable<>(); ++ ++ private final AtomicLong inProgressTasks = new AtomicLong(); ++ ++ public RegionDataController(final RegionFileType type, final PrioritisedExecutor ioExecutor, ++ final PrioritisedExecutor compressionExecutor) { ++ this.type = type; ++ this.compressionExecutor = compressionExecutor; ++ this.ioScheduler = new IOScheduler(ioExecutor); ++ } ++ ++ final void startTask(final ChunkIOTask task) { ++ this.inProgressTasks.getAndIncrement(); ++ } ++ ++ final void endTask(final ChunkIOTask task) { ++ this.inProgressTasks.getAndDecrement(); ++ } ++ ++ public boolean hasTasks() { ++ return this.inProgressTasks.get() != 0L; ++ } ++ ++ public long getTotalWorkingTasks() { ++ return this.inProgressTasks.get(); ++ } ++ ++ public abstract RegionFileStorage getCache(); ++ ++ public static record WriteData(CompoundTag input, WriteResult result, DataOutputStream output, IORunnable write) { ++ public static enum WriteResult { ++ WRITE, ++ DELETE; ++ } ++ } ++ ++ public abstract WriteData startWrite(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException; ++ ++ public abstract void finishWrite(final int chunkX, final int chunkZ, final WriteData writeData) throws IOException; ++ ++ public static record ReadData(ReadResult result, DataInputStream input, CompoundTag syncRead) { ++ public static enum ReadResult { ++ NO_DATA, ++ HAS_DATA, ++ SYNC_READ; ++ } ++ } ++ ++ public abstract ReadData readData(final int chunkX, final int chunkZ) throws IOException; ++ ++ // if the return value is null, then the caller needs to re-try with a new call to readData() ++ public abstract CompoundTag finishRead(final int chunkX, final int chunkZ, final ReadData readData) throws IOException; ++ ++ public static interface IORunnable { ++ ++ public void run(final RegionFile regionFile) throws IOException; ++ ++ } ++ } ++ ++ private static final class IOScheduler { ++ ++ private final ConcurrentLong2ReferenceChainedHashTable regionTasks = new ConcurrentLong2ReferenceChainedHashTable<>(); ++ private final PrioritisedExecutor executor; ++ ++ public IOScheduler(final PrioritisedExecutor executor) { ++ this.executor = executor; ++ } ++ ++ public PrioritisedExecutor.PrioritisedTask createTask(final int chunkX, final int chunkZ, ++ final Runnable run, final Priority priority) { ++ final PrioritisedExecutor.PrioritisedTask[] ret = new PrioritisedExecutor.PrioritisedTask[1]; ++ final long subOrder = this.executor.generateNextSubOrder(); ++ this.regionTasks.compute(CoordinateUtils.getChunkKey(chunkX >> REGION_FILE_SHIFT, chunkZ >> REGION_FILE_SHIFT), ++ (final long regionKey, final RegionIOTasks existing) -> { ++ final RegionIOTasks res; ++ if (existing != null) { ++ res = existing; ++ } else { ++ res = new RegionIOTasks(regionKey, IOScheduler.this); ++ } ++ ++ ret[0] = res.createTask(run, priority, subOrder); ++ ++ return res; ++ }); ++ ++ return ret[0]; ++ } ++ } ++ ++ private static final class RegionIOTasks implements Runnable { ++ ++ private static final Logger LOGGER = LoggerFactory.getLogger(RegionIOTasks.class); ++ ++ private final PrioritisedTaskQueue queue = new PrioritisedTaskQueue(); ++ private final long regionKey; ++ private final IOScheduler ioScheduler; ++ private long createdTasks; ++ private long executedTasks; ++ ++ private PrioritisedExecutor.PrioritisedTask task; ++ ++ public RegionIOTasks(final long regionKey, final IOScheduler ioScheduler) { ++ this.regionKey = regionKey; ++ this.ioScheduler = ioScheduler; ++ } ++ ++ public PrioritisedExecutor.PrioritisedTask createTask(final Runnable run, final Priority priority, ++ final long subOrder) { ++ ++this.createdTasks; ++ return new WrappedTask(this.queue.createTask(run, priority, subOrder)); ++ } ++ ++ private void adjustTaskPriority() { ++ final PrioritisedTaskQueue.PrioritySubOrderPair priority = this.queue.getHighestPrioritySubOrder(); ++ if (this.task == null) { ++ if (priority == null) { ++ return; ++ } ++ this.task = this.ioScheduler.executor.createTask(this, priority.priority(), priority.subOrder()); ++ this.task.queue(); ++ } else { ++ if (priority == null) { ++ throw new IllegalStateException(); ++ } else { ++ this.task.setPriorityAndSubOrder(priority.priority(), priority.subOrder()); ++ } ++ } ++ } ++ ++ @Override ++ public void run() { ++ final Runnable run; ++ synchronized (this) { ++ run = this.queue.pollTask(); ++ } ++ ++ try { ++ run.run(); ++ } finally { ++ synchronized (this) { ++ this.task = null; ++ this.adjustTaskPriority(); ++ } ++ this.ioScheduler.regionTasks.compute(this.regionKey, (final long keyInMap, final RegionIOTasks tasks) -> { ++ if (tasks != RegionIOTasks.this) { ++ throw new IllegalStateException("Region task mismatch"); ++ } ++ ++tasks.executedTasks; ++ if (tasks.createdTasks != tasks.executedTasks) { ++ return tasks; ++ } ++ ++ if (tasks.task != null) { ++ throw new IllegalStateException("Task may not be null when created==executed"); ++ } ++ ++ return null; ++ }); ++ } ++ } ++ ++ private final class WrappedTask implements PrioritisedExecutor.PrioritisedTask { ++ ++ private final PrioritisedExecutor.PrioritisedTask wrapped; ++ ++ public WrappedTask(final PrioritisedExecutor.PrioritisedTask wrap) { ++ this.wrapped = wrap; ++ } ++ ++ @Override ++ public PrioritisedExecutor getExecutor() { ++ return RegionIOTasks.this.ioScheduler.executor; ++ } ++ ++ @Override ++ public boolean queue() { ++ synchronized (RegionIOTasks.this) { ++ if (this.wrapped.queue()) { ++ RegionIOTasks.this.adjustTaskPriority(); ++ return true; ++ } ++ return false; ++ } ++ } ++ ++ @Override ++ public boolean isQueued() { ++ return this.wrapped.isQueued(); ++ } ++ ++ @Override ++ public boolean cancel() { ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public boolean execute() { ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public Priority getPriority() { ++ return this.wrapped.getPriority(); ++ } ++ ++ @Override ++ public boolean setPriority(final Priority priority) { ++ synchronized (RegionIOTasks.this) { ++ if (this.wrapped.setPriority(priority) && this.wrapped.isQueued()) { ++ RegionIOTasks.this.adjustTaskPriority(); ++ return true; ++ } ++ return false; ++ } ++ } ++ ++ @Override ++ public boolean raisePriority(final Priority priority) { ++ synchronized (RegionIOTasks.this) { ++ if (this.wrapped.raisePriority(priority) && this.wrapped.isQueued()) { ++ RegionIOTasks.this.adjustTaskPriority(); ++ return true; ++ } ++ return false; ++ } ++ } ++ ++ @Override ++ public boolean lowerPriority(final Priority priority) { ++ synchronized (RegionIOTasks.this) { ++ if (this.wrapped.lowerPriority(priority) && this.wrapped.isQueued()) { ++ RegionIOTasks.this.adjustTaskPriority(); ++ return true; ++ } ++ return false; ++ } ++ } ++ ++ @Override ++ public long getSubOrder() { ++ return this.wrapped.getSubOrder(); ++ } ++ ++ @Override ++ public boolean setSubOrder(final long subOrder) { ++ synchronized (RegionIOTasks.this) { ++ if (this.wrapped.setSubOrder(subOrder) && this.wrapped.isQueued()) { ++ RegionIOTasks.this.adjustTaskPriority(); ++ return true; ++ } ++ return false; ++ } ++ } ++ ++ @Override ++ public boolean raiseSubOrder(final long subOrder) { ++ synchronized (RegionIOTasks.this) { ++ if (this.wrapped.raiseSubOrder(subOrder) && this.wrapped.isQueued()) { ++ RegionIOTasks.this.adjustTaskPriority(); ++ return true; ++ } ++ return false; ++ } ++ } ++ ++ @Override ++ public boolean lowerSubOrder(final long subOrder) { ++ synchronized (RegionIOTasks.this) { ++ if (this.wrapped.lowerSubOrder(subOrder) && this.wrapped.isQueued()) { ++ RegionIOTasks.this.adjustTaskPriority(); ++ return true; ++ } ++ return false; ++ } ++ } ++ ++ @Override ++ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder) { ++ synchronized (RegionIOTasks.this) { ++ if (this.wrapped.setPriorityAndSubOrder(priority, subOrder) && this.wrapped.isQueued()) { ++ RegionIOTasks.this.adjustTaskPriority(); ++ return true; ++ } ++ return false; ++ } ++ } ++ } ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java +deleted file mode 100644 +index 3218cbf84f54daf06e84442d5eb1a36d8da6b215..0000000000000000000000000000000000000000 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java ++++ /dev/null +@@ -1,1240 +0,0 @@ +-package ca.spottedleaf.moonrise.patches.chunk_system.io; +- +-import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; +-import ca.spottedleaf.concurrentutil.executor.Cancellable; +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedQueueExecutorThread; +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadedTaskQueue; +-import ca.spottedleaf.concurrentutil.function.BiLong1Function; +-import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; +-import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; +-import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +-import ca.spottedleaf.moonrise.common.util.TickThread; +-import ca.spottedleaf.moonrise.common.util.WorldUtil; +-import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; +-import net.minecraft.nbt.CompoundTag; +-import net.minecraft.server.level.ServerLevel; +-import net.minecraft.world.level.ChunkPos; +-import net.minecraft.world.level.chunk.storage.RegionFile; +-import net.minecraft.world.level.chunk.storage.RegionFileStorage; +-import org.slf4j.Logger; +-import org.slf4j.LoggerFactory; +-import java.io.IOException; +-import java.lang.invoke.VarHandle; +-import java.util.concurrent.CompletableFuture; +-import java.util.concurrent.CompletionException; +-import java.util.concurrent.atomic.AtomicInteger; +-import java.util.function.BiConsumer; +-import java.util.function.Consumer; +-import java.util.function.Function; +- +-/** +- * Prioritised RegionFile I/O executor, responsible for all RegionFile access. +- *

    +- * All functions provided are MT-Safe, however certain ordering constraints are recommended: +- *

  • +- * Chunk saves may not occur for unloaded chunks. +- *
  • +- *
  • +- * Tasks must be scheduled on the chunk scheduler thread. +- *
  • +- * By following these constraints, no chunk data loss should occur with the exception of underlying I/O problems. +- *

    +- */ +-public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { +- +- private static final Logger LOGGER = LoggerFactory.getLogger(RegionFileIOThread.class); +- +- /** +- * The kinds of region files controlled by the region file thread. Add more when needed, and ensure +- * getControllerFor is updated. +- */ +- public static enum RegionFileType { +- CHUNK_DATA, +- POI_DATA, +- ENTITY_DATA; +- } +- +- private static final RegionFileType[] CACHED_REGIONFILE_TYPES = RegionFileType.values(); +- +- public static ChunkDataController getControllerFor(final ServerLevel world, final RegionFileType type) { +- switch (type) { +- case CHUNK_DATA: +- return ((ChunkSystemServerLevel)world).moonrise$getChunkDataController(); +- case POI_DATA: +- return ((ChunkSystemServerLevel)world).moonrise$getPoiChunkDataController(); +- case ENTITY_DATA: +- return ((ChunkSystemServerLevel)world).moonrise$getEntityChunkDataController(); +- default: +- throw new IllegalStateException("Unknown controller type " + type); +- } +- } +- +- /** +- * Collects regionfile data for a certain chunk. +- */ +- public static final class RegionFileData { +- +- private final boolean[] hasResult = new boolean[CACHED_REGIONFILE_TYPES.length]; +- private final CompoundTag[] data = new CompoundTag[CACHED_REGIONFILE_TYPES.length]; +- private final Throwable[] throwables = new Throwable[CACHED_REGIONFILE_TYPES.length]; +- +- /** +- * Sets the result associated with the specified regionfile type. Note that +- * results can only be set once per regionfile type. +- * +- * @param type The regionfile type. +- * @param data The result to set. +- */ +- public void setData(final RegionFileType type, final CompoundTag data) { +- final int index = type.ordinal(); +- +- if (this.hasResult[index]) { +- throw new IllegalArgumentException("Result already exists for type " + type); +- } +- this.hasResult[index] = true; +- this.data[index] = data; +- } +- +- /** +- * Sets the result associated with the specified regionfile type. Note that +- * results can only be set once per regionfile type. +- * +- * @param type The regionfile type. +- * @param throwable The result to set. +- */ +- public void setThrowable(final RegionFileType type, final Throwable throwable) { +- final int index = type.ordinal(); +- +- if (this.hasResult[index]) { +- throw new IllegalArgumentException("Result already exists for type " + type); +- } +- this.hasResult[index] = true; +- this.throwables[index] = throwable; +- } +- +- /** +- * Returns whether there is a result for the specified regionfile type. +- * +- * @param type Specified regionfile type. +- * +- * @return Whether a result exists for {@code type}. +- */ +- public boolean hasResult(final RegionFileType type) { +- return this.hasResult[type.ordinal()]; +- } +- +- /** +- * Returns the data result for the regionfile type. +- * +- * @param type Specified regionfile type. +- * +- * @throws IllegalArgumentException If the result has not been set for {@code type}. +- * @return The data result for the specified type. If the result is a {@code Throwable}, +- * then returns {@code null}. +- */ +- public CompoundTag getData(final RegionFileType type) { +- final int index = type.ordinal(); +- +- if (!this.hasResult[index]) { +- throw new IllegalArgumentException("Result does not exist for type " + type); +- } +- +- return this.data[index]; +- } +- +- /** +- * Returns the throwable result for the regionfile type. +- * +- * @param type Specified regionfile type. +- * +- * @throws IllegalArgumentException If the result has not been set for {@code type}. +- * @return The throwable result for the specified type. If the result is an {@code CompoundTag}, +- * then returns {@code null}. +- */ +- public Throwable getThrowable(final RegionFileType type) { +- final int index = type.ordinal(); +- +- if (!this.hasResult[index]) { +- throw new IllegalArgumentException("Result does not exist for type " + type); +- } +- +- return this.throwables[index]; +- } +- } +- +- private static final Object INIT_LOCK = new Object(); +- +- static RegionFileIOThread[] threads; +- +- /* needs to be consistent given a set of parameters */ +- static RegionFileIOThread selectThread(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { +- if (threads == null) { +- throw new IllegalStateException("Threads not initialised"); +- } +- +- final int regionX = chunkX >> 5; +- final int regionZ = chunkZ >> 5; +- final int typeOffset = type.ordinal(); +- +- return threads[(System.identityHashCode(world) + regionX + regionZ + typeOffset) % threads.length]; +- } +- +- /** +- * Shuts down the I/O executor(s). Watis for all tasks to complete if specified. +- * Tasks queued during this call might not be accepted, and tasks queued after will not be accepted. +- * +- * @param wait Whether to wait until all tasks have completed. +- */ +- public static void close(final boolean wait) { +- for (int i = 0, len = threads.length; i < len; ++i) { +- threads[i].close(false, true); +- } +- if (wait) { +- RegionFileIOThread.flush(); +- } +- } +- +- public static long[] getExecutedTasks() { +- final long[] ret = new long[threads.length]; +- for (int i = 0, len = threads.length; i < len; ++i) { +- ret[i] = threads[i].getTotalTasksExecuted(); +- } +- +- return ret; +- } +- +- public static long[] getTasksScheduled() { +- final long[] ret = new long[threads.length]; +- for (int i = 0, len = threads.length; i < len; ++i) { +- ret[i] = threads[i].getTotalTasksScheduled(); +- } +- return ret; +- } +- +- public static void flush() { +- for (int i = 0, len = threads.length; i < len; ++i) { +- threads[i].waitUntilAllExecuted(); +- } +- } +- +- public static void flushRegionStorages(final ServerLevel world) throws IOException { +- for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { +- getControllerFor(world, type).getCache().flush(); +- } +- } +- +- public static void partialFlush(final int totalTasksRemaining) { +- long failures = 1L; // start out at 0.25ms +- +- for (;;) { +- final long[] executed = getExecutedTasks(); +- final long[] scheduled = getTasksScheduled(); +- +- long sum = 0; +- for (int i = 0; i < executed.length; ++i) { +- sum += scheduled[i] - executed[i]; +- } +- +- if (sum <= totalTasksRemaining) { +- break; +- } +- +- failures = ConcurrentUtil.linearLongBackoff(failures, 250_000L, 5_000_000L); // 500us, 5ms +- } +- } +- +- /** +- * Inits the executor with the specified number of threads. +- * +- * @param threads Specified number of threads. +- */ +- public static void init(final int threads) { +- synchronized (INIT_LOCK) { +- if (RegionFileIOThread.threads != null) { +- throw new IllegalStateException("Already initialised threads"); +- } +- +- RegionFileIOThread.threads = new RegionFileIOThread[threads]; +- +- for (int i = 0; i < threads; ++i) { +- RegionFileIOThread.threads[i] = new RegionFileIOThread(i); +- RegionFileIOThread.threads[i].start(); +- } +- } +- } +- +- public static void deinit() { +- if (true) { // Paper +- // TODO does this cause issues with mods? how to implement +- close(true); +- synchronized (INIT_LOCK) { +- RegionFileIOThread.threads = null; +- } +- } else { RegionFileIOThread.flush(); } +- } +- +- private RegionFileIOThread(final int threadNumber) { +- super(new PrioritisedThreadedTaskQueue(), (int)(1.0e6)); // 1.0ms spinwait time +- this.setName("RegionFile I/O Thread #" + threadNumber); +- this.setPriority(Thread.NORM_PRIORITY - 2); // we keep priority close to normal because threads can wait on us +- this.setUncaughtExceptionHandler((final Thread thread, final Throwable thr) -> { +- LOGGER.error("Uncaught exception thrown from I/O thread, report this! Thread: " + thread.getName(), thr); +- }); +- } +- +- /** +- * Returns whether the current thread is a regionfile I/O executor. +- * @return Whether the current thread is a regionfile I/O executor. +- */ +- public static boolean isRegionFileThread() { +- return Thread.currentThread() instanceof RegionFileIOThread; +- } +- +- /** +- * Returns the priority associated with blocking I/O based on the current thread. The goal is to avoid +- * dumb plugins from taking away priority from threads we consider crucial. +- * @return The priroity to use with blocking I/O on the current thread. +- */ +- public static Priority getIOBlockingPriorityForCurrentThread() { +- if (TickThread.isTickThread()) { +- return Priority.BLOCKING; +- } +- return Priority.HIGHEST; +- } +- +- /** +- * Returns the current {@code CompoundTag} pending for write for the specified chunk & regionfile type. +- * Note that this does not copy the result, so do not modify the result returned. +- * +- * @param world Specified world. +- * @param chunkX Specified chunk x. +- * @param chunkZ Specified chunk z. +- * @param type Specified regionfile type. +- * +- * @return The compound tag associated for the specified chunk. {@code null} if no write was pending, or if {@code null} is the write pending. +- */ +- public static CompoundTag getPendingWrite(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { +- final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); +- return thread.getPendingWriteInternal(world, chunkX, chunkZ, type); +- } +- +- CompoundTag getPendingWriteInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { +- final ChunkDataController taskController = getControllerFor(world, type); +- final ChunkDataTask task = taskController.tasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); +- +- if (task == null) { +- return null; +- } +- +- final CompoundTag ret = task.inProgressWrite; +- +- return ret == ChunkDataTask.NOTHING_TO_WRITE ? null : ret; +- } +- +- /** +- * Returns the priority for the specified regionfile type for the specified chunk. +- * @param world Specified world. +- * @param chunkX Specified chunk x. +- * @param chunkZ Specified chunk z. +- * @param type Specified regionfile type. +- * @return The priority for the chunk +- */ +- public static Priority getPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { +- final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); +- return thread.getPriorityInternal(world, chunkX, chunkZ, type); +- } +- +- Priority getPriorityInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { +- final ChunkDataController taskController = getControllerFor(world, type); +- final ChunkDataTask task = taskController.tasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); +- +- if (task == null) { +- return Priority.COMPLETING; +- } +- +- return task.prioritisedTask.getPriority(); +- } +- +- /** +- * Sets the priority for all regionfile types for the specified chunk. Note that great care should +- * be taken using this method, as there can be multiple tasks tied to the same chunk that want different +- * priorities. +- * +- * @param world Specified world. +- * @param chunkX Specified chunk x. +- * @param chunkZ Specified chunk z. +- * @param priority New priority. +- * +- * @see #raisePriority(ServerLevel, int, int, Priority) +- * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) +- * @see #lowerPriority(ServerLevel, int, int, Priority) +- * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) +- */ +- public static void setPriority(final ServerLevel world, final int chunkX, final int chunkZ, +- final Priority priority) { +- for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { +- RegionFileIOThread.setPriority(world, chunkX, chunkZ, type, priority); +- } +- } +- +- /** +- * Sets the priority for the specified regionfile type for the specified chunk. Note that great care should +- * be taken using this method, as there can be multiple tasks tied to the same chunk that want different +- * priorities. +- * +- * @param world Specified world. +- * @param chunkX Specified chunk x. +- * @param chunkZ Specified chunk z. +- * @param type Specified regionfile type. +- * @param priority New priority. +- * +- * @see #raisePriority(ServerLevel, int, int, Priority) +- * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) +- * @see #lowerPriority(ServerLevel, int, int, Priority) +- * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) +- */ +- public static void setPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, +- final Priority priority) { +- final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); +- thread.setPriorityInternal(world, chunkX, chunkZ, type, priority); +- } +- +- void setPriorityInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, +- final Priority priority) { +- final ChunkDataController taskController = getControllerFor(world, type); +- final ChunkDataTask task = taskController.tasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); +- +- if (task != null) { +- task.prioritisedTask.setPriority(priority); +- } +- } +- +- /** +- * Raises the priority for all regionfile types for the specified chunk. +- * +- * @param world Specified world. +- * @param chunkX Specified chunk x. +- * @param chunkZ Specified chunk z. +- * @param priority New priority. +- * +- * @see #setPriority(ServerLevel, int, int, Priority) +- * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) +- * @see #lowerPriority(ServerLevel, int, int, Priority) +- * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) +- */ +- public static void raisePriority(final ServerLevel world, final int chunkX, final int chunkZ, +- final Priority priority) { +- for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { +- RegionFileIOThread.raisePriority(world, chunkX, chunkZ, type, priority); +- } +- } +- +- /** +- * Raises the priority for the specified regionfile type for the specified chunk. +- * +- * @param world Specified world. +- * @param chunkX Specified chunk x. +- * @param chunkZ Specified chunk z. +- * @param type Specified regionfile type. +- * @param priority New priority. +- * +- * @see #setPriority(ServerLevel, int, int, Priority) +- * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) +- * @see #lowerPriority(ServerLevel, int, int, Priority) +- * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) +- */ +- public static void raisePriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, +- final Priority priority) { +- final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); +- thread.raisePriorityInternal(world, chunkX, chunkZ, type, priority); +- } +- +- void raisePriorityInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, +- final Priority priority) { +- final ChunkDataController taskController = getControllerFor(world, type); +- final ChunkDataTask task = taskController.tasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); +- +- if (task != null) { +- task.prioritisedTask.raisePriority(priority); +- } +- } +- +- /** +- * Lowers the priority for all regionfile types for the specified chunk. +- * +- * @param world Specified world. +- * @param chunkX Specified chunk x. +- * @param chunkZ Specified chunk z. +- * @param priority New priority. +- * +- * @see #raisePriority(ServerLevel, int, int, Priority) +- * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) +- * @see #setPriority(ServerLevel, int, int, Priority) +- * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) +- */ +- public static void lowerPriority(final ServerLevel world, final int chunkX, final int chunkZ, +- final Priority priority) { +- for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { +- RegionFileIOThread.lowerPriority(world, chunkX, chunkZ, type, priority); +- } +- } +- +- /** +- * Lowers the priority for the specified regionfile type for the specified chunk. +- * +- * @param world Specified world. +- * @param chunkX Specified chunk x. +- * @param chunkZ Specified chunk z. +- * @param type Specified regionfile type. +- * @param priority New priority. +- * +- * @see #raisePriority(ServerLevel, int, int, Priority) +- * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) +- * @see #setPriority(ServerLevel, int, int, Priority) +- * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) +- */ +- public static void lowerPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, +- final Priority priority) { +- final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); +- thread.lowerPriorityInternal(world, chunkX, chunkZ, type, priority); +- } +- +- void lowerPriorityInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, +- final Priority priority) { +- final ChunkDataController taskController = getControllerFor(world, type); +- final ChunkDataTask task = taskController.tasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); +- +- if (task != null) { +- task.prioritisedTask.lowerPriority(priority); +- } +- } +- +- /** +- * Schedules the chunk data to be written asynchronously. +- *

    +- * Impl notes: +- *

    +- *
  • +- * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means +- * saves must be scheduled before a chunk is unloaded. +- *
  • +- *
  • +- * Writes may be called concurrently, although only the "later" write will go through. +- *
  • +- * +- * @param world Chunk's world +- * @param chunkX Chunk's x coordinate +- * @param chunkZ Chunk's z coordinate +- * @param data Chunk's data +- * @param type The regionfile type to write to. +- * +- * @throws IllegalStateException If the file io thread has shutdown. +- */ +- public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data, +- final RegionFileType type) { +- RegionFileIOThread.scheduleSave(world, chunkX, chunkZ, data, type, Priority.NORMAL); +- } +- +- /** +- * Schedules the chunk data to be written asynchronously. +- *

    +- * Impl notes: +- *

    +- *
  • +- * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means +- * saves must be scheduled before a chunk is unloaded. +- *
  • +- *
  • +- * Writes may be called concurrently, although only the "later" write will go through. +- *
  • +- * +- * @param world Chunk's world +- * @param chunkX Chunk's x coordinate +- * @param chunkZ Chunk's z coordinate +- * @param data Chunk's data +- * @param type The regionfile type to write to. +- * @param priority The minimum priority to schedule at. +- * +- * @throws IllegalStateException If the file io thread has shutdown. +- */ +- public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data, +- final RegionFileType type, final Priority priority) { +- final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); +- thread.scheduleSaveInternal(world, chunkX, chunkZ, data, type, priority); +- } +- +- void scheduleSaveInternal(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data, +- final RegionFileType type, final Priority priority) { +- final ChunkDataController taskController = getControllerFor(world, type); +- +- final boolean[] created = new boolean[1]; +- final long key = CoordinateUtils.getChunkKey(chunkX, chunkZ); +- final ChunkDataTask task = taskController.tasks.compute(key, (final long keyInMap, final ChunkDataTask taskRunning) -> { +- if (taskRunning == null || taskRunning.failedWrite) { +- // no task is scheduled or the previous write failed - meaning we need to overwrite it +- +- // create task +- final ChunkDataTask newTask = new ChunkDataTask(world, chunkX, chunkZ, taskController, RegionFileIOThread.this, priority); +- newTask.inProgressWrite = data; +- created[0] = true; +- +- return newTask; +- } +- +- taskRunning.inProgressWrite = data; +- +- return taskRunning; +- }); +- +- if (created[0]) { +- task.prioritisedTask.queue(); +- } else { +- task.prioritisedTask.raisePriority(priority); +- } +- } +- +- /** +- * Schedules a load to be executed asynchronously. This task will load all regionfile types, and then call +- * {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean)} +- * for single load. +- *

    +- * Impl notes: +- *

    +- *
  • +- * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may +- * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of +- * data is undefined behaviour, and can cause deadlock. +- *
  • +- * +- * @param world Chunk's world +- * @param chunkX Chunk's x coordinate +- * @param chunkZ Chunk's z coordinate +- * @param onComplete Consumer to execute once this task has completed +- * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost +- * of this call. +- * +- * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. +- * +- * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) +- * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) +- * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) +- * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) +- */ +- public static Cancellable loadAllChunkData(final ServerLevel world, final int chunkX, final int chunkZ, +- final Consumer onComplete, final boolean intendingToBlock) { +- return RegionFileIOThread.loadAllChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, Priority.NORMAL); +- } +- +- /** +- * Schedules a load to be executed asynchronously. This task will load all regionfile types, and then call +- * {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority)} +- * for single load. +- *

    +- * Impl notes: +- *

    +- *
  • +- * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may +- * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of +- * data is undefined behaviour, and can cause deadlock. +- *
  • +- * +- * @param world Chunk's world +- * @param chunkX Chunk's x coordinate +- * @param chunkZ Chunk's z coordinate +- * @param onComplete Consumer to execute once this task has completed +- * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost +- * of this call. +- * @param priority The minimum priority to load the data at. +- * +- * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. +- * +- * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) +- * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) +- * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) +- * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) +- */ +- public static Cancellable loadAllChunkData(final ServerLevel world, final int chunkX, final int chunkZ, +- final Consumer onComplete, final boolean intendingToBlock, +- final Priority priority) { +- return RegionFileIOThread.loadChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, priority, CACHED_REGIONFILE_TYPES); +- } +- +- /** +- * Schedules a load to be executed asynchronously. This task will load data for the specified regionfile type(s), and +- * then call {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean)} +- * for single load. +- *

    +- * Impl notes: +- *

    +- *
  • +- * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may +- * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of +- * data is undefined behaviour, and can cause deadlock. +- *
  • +- * +- * @param world Chunk's world +- * @param chunkX Chunk's x coordinate +- * @param chunkZ Chunk's z coordinate +- * @param onComplete Consumer to execute once this task has completed +- * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost +- * of this call. +- * @param types The regionfile type(s) to load. +- * +- * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. +- * +- * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) +- * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) +- * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) +- * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) +- */ +- public static Cancellable loadChunkData(final ServerLevel world, final int chunkX, final int chunkZ, +- final Consumer onComplete, final boolean intendingToBlock, +- final RegionFileType... types) { +- return RegionFileIOThread.loadChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, Priority.NORMAL, types); +- } +- +- /** +- * Schedules a load to be executed asynchronously. This task will load data for the specified regionfile type(s), and +- * then call {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority)} +- * for single load. +- *

    +- * Impl notes: +- *

    +- *
  • +- * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may +- * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of +- * data is undefined behaviour, and can cause deadlock. +- *
  • +- * +- * @param world Chunk's world +- * @param chunkX Chunk's x coordinate +- * @param chunkZ Chunk's z coordinate +- * @param onComplete Consumer to execute once this task has completed +- * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost +- * of this call. +- * @param types The regionfile type(s) to load. +- * @param priority The minimum priority to load the data at. +- * +- * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. +- * +- * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) +- * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) +- * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) +- * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) +- */ +- public static Cancellable loadChunkData(final ServerLevel world, final int chunkX, final int chunkZ, +- final Consumer onComplete, final boolean intendingToBlock, +- final Priority priority, final RegionFileType... types) { +- if (types == null) { +- throw new NullPointerException("Types cannot be null"); +- } +- if (types.length == 0) { +- throw new IllegalArgumentException("Types cannot be empty"); +- } +- +- final RegionFileData ret = new RegionFileData(); +- +- final Cancellable[] reads = new CancellableRead[types.length]; +- final AtomicInteger completions = new AtomicInteger(); +- final int expectedCompletions = types.length; +- +- for (int i = 0; i < expectedCompletions; ++i) { +- final RegionFileType type = types[i]; +- reads[i] = RegionFileIOThread.loadDataAsync(world, chunkX, chunkZ, type, +- (final CompoundTag data, final Throwable throwable) -> { +- if (throwable != null) { +- ret.setThrowable(type, throwable); +- } else { +- ret.setData(type, data); +- } +- +- if (completions.incrementAndGet() == expectedCompletions) { +- onComplete.accept(ret); +- } +- }, intendingToBlock, priority); +- } +- +- return new CancellableReads(reads); +- } +- +- /** +- * Schedules a load to be executed asynchronously. This task will load the specified regionfile type, and then call +- * {@code onComplete}. +- *

    +- * Impl notes: +- *

    +- *
  • +- * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may +- * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of +- * data is undefined behaviour, and can cause deadlock. +- *
  • +- * +- * @param world Chunk's world +- * @param chunkX Chunk's x coordinate +- * @param chunkZ Chunk's z coordinate +- * @param onComplete Consumer to execute once this task has completed +- * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost +- * of this call. +- * +- * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. +- * +- * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) +- * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) +- * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) +- * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) +- */ +- public static Cancellable loadDataAsync(final ServerLevel world, final int chunkX, final int chunkZ, +- final RegionFileType type, final BiConsumer onComplete, +- final boolean intendingToBlock) { +- return RegionFileIOThread.loadDataAsync(world, chunkX, chunkZ, type, onComplete, intendingToBlock, Priority.NORMAL); +- } +- +- /** +- * Schedules a load to be executed asynchronously. This task will load the specified regionfile type, and then call +- * {@code onComplete}. +- *

    +- * Impl notes: +- *

    +- *
  • +- * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may +- * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of +- * data is undefined behaviour, and can cause deadlock. +- *
  • +- * +- * @param world Chunk's world +- * @param chunkX Chunk's x coordinate +- * @param chunkZ Chunk's z coordinate +- * @param onComplete Consumer to execute once this task has completed +- * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost +- * of this call. +- * @param priority Minimum priority to load the data at. +- * +- * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. +- * +- * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) +- * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) +- * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) +- * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) +- */ +- public static Cancellable loadDataAsync(final ServerLevel world, final int chunkX, final int chunkZ, +- final RegionFileType type, final BiConsumer onComplete, +- final boolean intendingToBlock, final Priority priority) { +- final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); +- return thread.loadDataAsyncInternal(world, chunkX, chunkZ, type, onComplete, intendingToBlock, priority); +- } +- +- Cancellable loadDataAsyncInternal(final ServerLevel world, final int chunkX, final int chunkZ, +- final RegionFileType type, final BiConsumer onComplete, +- final boolean intendingToBlock, final Priority priority) { +- final ChunkDataController taskController = getControllerFor(world, type); +- +- final ImmediateCallbackCompletion callbackInfo = new ImmediateCallbackCompletion(); +- +- final long key = CoordinateUtils.getChunkKey(chunkX, chunkZ); +- final BiLong1Function compute = (final long keyInMap, final ChunkDataTask running) -> { +- if (running == null) { +- // not scheduled +- +- // set up task +- final ChunkDataTask newTask = new ChunkDataTask( +- world, chunkX, chunkZ, taskController, RegionFileIOThread.this, priority +- ); +- newTask.inProgressRead = new InProgressRead(); +- newTask.inProgressRead.addToAsyncWaiters(onComplete); +- +- callbackInfo.tasksNeedsScheduling = true; +- return newTask; +- } +- +- final CompoundTag pendingWrite = running.inProgressWrite; +- +- if (pendingWrite == ChunkDataTask.NOTHING_TO_WRITE) { +- // need to add to waiters here, because the regionfile thread will use compute() to lock and check for cancellations +- if (!running.inProgressRead.addToAsyncWaiters(onComplete)) { +- callbackInfo.data = running.inProgressRead.value; +- callbackInfo.throwable = running.inProgressRead.throwable; +- callbackInfo.completeNow = true; +- } +- return running; +- } +- +- // at this stage we have to use the in progress write's data to avoid an order issue +- callbackInfo.data = pendingWrite; +- callbackInfo.throwable = null; +- callbackInfo.completeNow = true; +- return running; +- }; +- +- final ChunkDataTask ret = taskController.tasks.compute(key, compute); +- +- // needs to be scheduled +- if (callbackInfo.tasksNeedsScheduling) { +- ret.prioritisedTask.queue(); +- } else if (callbackInfo.completeNow) { +- try { +- onComplete.accept(callbackInfo.data == null ? null : callbackInfo.data.copy(), callbackInfo.throwable); +- } catch (final Throwable thr) { +- LOGGER.error("Callback " + ConcurrentUtil.genericToString(onComplete) + " synchronously failed to handle chunk data for task " + ret.toString(), thr); +- } +- } else { +- // we're waiting on a task we didn't schedule, so raise its priority to what we want +- ret.prioritisedTask.raisePriority(priority); +- } +- +- return new CancellableRead(onComplete, ret); +- } +- +- /** +- * Schedules a load task to be executed asynchronously, and blocks on that task. +- * +- * @param world Chunk's world +- * @param chunkX Chunk's x coordinate +- * @param chunkZ Chunk's z coordinate +- * @param type Regionfile type +- * @param priority Minimum priority to load the data at. +- * +- * @return The chunk data for the chunk. Note that a {@code null} result means the chunk or regionfile does not exist on disk. +- * +- * @throws IOException If the load fails for any reason +- */ +- public static CompoundTag loadData(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, +- final Priority priority) throws IOException { +- final CompletableFuture ret = new CompletableFuture<>(); +- +- RegionFileIOThread.loadDataAsync(world, chunkX, chunkZ, type, (final CompoundTag compound, final Throwable thr) -> { +- if (thr != null) { +- ret.completeExceptionally(thr); +- } else { +- ret.complete(compound); +- } +- }, true, priority); +- +- try { +- return ret.join(); +- } catch (final CompletionException ex) { +- throw new IOException(ex); +- } +- } +- +- private static final class ImmediateCallbackCompletion { +- +- public CompoundTag data; +- public Throwable throwable; +- public boolean completeNow; +- public boolean tasksNeedsScheduling; +- +- } +- +- private static final class CancellableRead implements Cancellable { +- +- private BiConsumer callback; +- private ChunkDataTask task; +- +- CancellableRead(final BiConsumer callback, final ChunkDataTask task) { +- this.callback = callback; +- this.task = task; +- } +- +- @Override +- public boolean cancel() { +- final BiConsumer callback = this.callback; +- final ChunkDataTask task = this.task; +- +- if (callback == null || task == null) { +- return false; +- } +- +- this.callback = null; +- this.task = null; +- +- final InProgressRead read = task.inProgressRead; +- +- // read can be null if no read was scheduled (i.e no regionfile existed or chunk in regionfile didn't) +- return read != null && read.cancel(callback); +- } +- } +- +- private static final class CancellableReads implements Cancellable { +- +- private Cancellable[] reads; +- +- private static final VarHandle READS_HANDLE = ConcurrentUtil.getVarHandle(CancellableReads.class, "reads", Cancellable[].class); +- +- CancellableReads(final Cancellable[] reads) { +- this.reads = reads; +- } +- +- @Override +- public boolean cancel() { +- final Cancellable[] reads = (Cancellable[])READS_HANDLE.getAndSet((CancellableReads)this, (Cancellable[])null); +- +- if (reads == null) { +- return false; +- } +- +- boolean ret = false; +- +- for (final Cancellable read : reads) { +- ret |= read.cancel(); +- } +- +- return ret; +- } +- } +- +- private static final class InProgressRead { +- +- private static final Logger LOGGER = LoggerFactory.getLogger(InProgressRead.class); +- +- private CompoundTag value; +- private Throwable throwable; +- private final MultiThreadedQueue> callbacks = new MultiThreadedQueue<>(); +- +- public boolean hasNoWaiters() { +- return this.callbacks.isEmpty(); +- } +- +- public boolean addToAsyncWaiters(final BiConsumer callback) { +- return this.callbacks.add(callback); +- } +- +- public boolean cancel(final BiConsumer callback) { +- return this.callbacks.remove(callback); +- } +- +- public void complete(final ChunkDataTask task, final CompoundTag value, final Throwable throwable) { +- this.value = value; +- this.throwable = throwable; +- +- BiConsumer consumer; +- while ((consumer = this.callbacks.pollOrBlockAdds()) != null) { +- try { +- consumer.accept(value == null ? null : value.copy(), throwable); +- } catch (final Throwable thr) { +- LOGGER.error("Callback " + ConcurrentUtil.genericToString(consumer) + " failed to handle chunk data for task " + task.toString(), thr); +- } +- } +- } +- } +- +- public static abstract class ChunkDataController { +- +- // ConcurrentHashMap synchronizes per chain, so reduce the chance of task's hashes colliding. +- private final ConcurrentLong2ReferenceChainedHashTable tasks = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(8192, 0.5f); +- +- public final RegionFileType type; +- +- public ChunkDataController(final RegionFileType type) { +- this.type = type; +- } +- +- public abstract RegionFileStorage getCache(); +- +- public abstract void writeData(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException; +- +- public abstract CompoundTag readData(final int chunkX, final int chunkZ) throws IOException; +- +- public boolean hasTasks() { +- return !this.tasks.isEmpty(); +- } +- +- public boolean doesRegionFileNotExist(final int chunkX, final int chunkZ) { +- return ((ChunkSystemRegionFileStorage)(Object)this.getCache()).moonrise$doesRegionFileNotExistNoIO(chunkX, chunkZ); +- } +- +- public T computeForRegionFile(final int chunkX, final int chunkZ, final boolean existingOnly, final Function function) { +- final RegionFileStorage cache = this.getCache(); +- final RegionFile regionFile; +- synchronized (cache) { +- try { +- if (existingOnly) { +- regionFile = ((ChunkSystemRegionFileStorage)(Object)cache).moonrise$getRegionFileIfExists(chunkX, chunkZ); +- } else { +- regionFile = cache.getRegionFile(new ChunkPos(chunkX, chunkZ), existingOnly); +- } +- } catch (final IOException ex) { +- throw new RuntimeException(ex); +- } +- +- return function.apply(regionFile); +- } +- } +- +- public T computeForRegionFileIfLoaded(final int chunkX, final int chunkZ, final Function function) { +- final RegionFileStorage cache = this.getCache(); +- final RegionFile regionFile; +- +- synchronized (cache) { +- regionFile = ((ChunkSystemRegionFileStorage)(Object)cache).moonrise$getRegionFileIfLoaded(chunkX, chunkZ); +- +- return function.apply(regionFile); +- } +- } +- } +- +- private static final class ChunkDataTask implements Runnable { +- +- private static final CompoundTag NOTHING_TO_WRITE = new CompoundTag(); +- +- private static final Logger LOGGER = LoggerFactory.getLogger(ChunkDataTask.class); +- +- private InProgressRead inProgressRead; +- private volatile CompoundTag inProgressWrite = NOTHING_TO_WRITE; // only needs to be acquire/release +- +- private boolean failedWrite; +- +- private final ServerLevel world; +- private final int chunkX; +- private final int chunkZ; +- private final ChunkDataController taskController; +- +- private final PrioritisedTask prioritisedTask; +- +- /* +- * IO thread will perform reads before writes for a given chunk x and z +- * +- * How reads/writes are scheduled: +- * +- * If read is scheduled while scheduling write, take no special action and just schedule write +- * If read is scheduled while scheduling read and no write is scheduled, chain the read task +- * +- * +- * If write is scheduled while scheduling read, use the pending write data and ret immediately (so no read is scheduled) +- * If write is scheduled while scheduling write (ignore read in progress), overwrite the write in progress data +- * +- * This allows the reads and writes to act as if they occur synchronously to the thread scheduling them, however +- * it fails to properly propagate write failures thanks to writes overwriting each other +- */ +- +- public ChunkDataTask(final ServerLevel world, final int chunkX, final int chunkZ, final ChunkDataController taskController, +- final PrioritisedExecutor executor, final Priority priority) { +- this.world = world; +- this.chunkX = chunkX; +- this.chunkZ = chunkZ; +- this.taskController = taskController; +- this.prioritisedTask = executor.createTask(this, priority); +- } +- +- @Override +- public String toString() { +- return "Task for world: '" + WorldUtil.getWorldName(this.world) + "' at (" + this.chunkX + "," + this.chunkZ + +- ") type: " + this.taskController.type.name() + ", hash: " + this.hashCode(); +- } +- +- @Override +- public void run() { +- final InProgressRead read = this.inProgressRead; +- final long chunkKey = CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ); +- +- if (read != null) { +- final boolean[] canRead = new boolean[] { true }; +- +- if (read.hasNoWaiters()) { +- // cancelled read? go to task controller to confirm +- final ChunkDataTask inMap = this.taskController.tasks.compute(chunkKey, (final long keyInMap, final ChunkDataTask valueInMap) -> { +- if (valueInMap == null) { +- throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkDataTask.this.toString() + ", report this!"); +- } +- if (valueInMap != ChunkDataTask.this) { +- throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkDataTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); +- } +- +- if (!read.hasNoWaiters()) { +- return valueInMap; +- } else { +- canRead[0] = false; +- } +- +- return valueInMap.inProgressWrite == NOTHING_TO_WRITE ? null : valueInMap; +- }); +- +- if (inMap == null) { +- // read is cancelled - and no write pending, so we're done +- return; +- } +- // if there is a write in progress, we don't actually have to worry about waiters gaining new entries - +- // the readers will just use the in progress write, so the value in canRead is good to use without +- // further synchronisation. +- } +- +- if (canRead[0]) { +- CompoundTag compound = null; +- Throwable throwable = null; +- +- try { +- compound = this.taskController.readData(this.chunkX, this.chunkZ); +- } catch (final Throwable thr) { +- throwable = thr; +- LOGGER.error("Failed to read chunk data for task: " + this.toString(), thr); +- } +- read.complete(this, compound, throwable); +- } +- } +- +- CompoundTag write = this.inProgressWrite; +- +- if (write == NOTHING_TO_WRITE) { +- final ChunkDataTask inMap = this.taskController.tasks.compute(chunkKey, (final long keyInMap, final ChunkDataTask valueInMap) -> { +- if (valueInMap == null) { +- throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkDataTask.this.toString() + ", report this!"); +- } +- if (valueInMap != ChunkDataTask.this) { +- throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkDataTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); +- } +- return valueInMap.inProgressWrite == NOTHING_TO_WRITE ? null : valueInMap; +- }); +- +- if (inMap == null) { +- return; // set the task value to null, indicating we're done +- } // else: inProgressWrite changed, so now we have something to write +- } +- +- for (;;) { +- write = this.inProgressWrite; +- final CompoundTag dataWritten = write; +- +- boolean failedWrite = false; +- +- try { +- this.taskController.writeData(this.chunkX, this.chunkZ, write); +- } catch (final Throwable thr) { +- if (thr instanceof RegionFileStorage.RegionFileSizeException) { +- final int maxSize = RegionFile.MAX_CHUNK_SIZE / (1024 * 1024); +- LOGGER.error("Chunk at (" + this.chunkX + "," + this.chunkZ + ") in '" + WorldUtil.getWorldName(this.world) + "' exceeds max size of " + maxSize + "MiB, it has been deleted from disk."); +- } else { +- failedWrite = thr instanceof IOException; +- LOGGER.error("Failed to write chunk data for task: " + this.toString(), thr); +- } +- } +- +- final boolean finalFailWrite = failedWrite; +- final boolean[] done = new boolean[] { false }; +- +- this.taskController.tasks.compute(chunkKey, (final long keyInMap, final ChunkDataTask valueInMap) -> { +- if (valueInMap == null) { +- throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkDataTask.this.toString() + ", report this!"); +- } +- if (valueInMap != ChunkDataTask.this) { +- throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkDataTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); +- } +- if (valueInMap.inProgressWrite == dataWritten) { +- valueInMap.failedWrite = finalFailWrite; +- done[0] = true; +- // keep the data in map if we failed the write so we can try to prevent data loss +- return finalFailWrite ? valueInMap : null; +- } +- // different data than expected, means we need to retry write +- return valueInMap; +- }); +- +- if (done[0]) { +- return; +- } +- +- // fetch & write new data +- continue; +- } +- } +- } +-} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/ChunkDataController.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/ChunkDataController.java +index c35e0c29700be48dda3e53e7d2db224766ef17b7..a36ab89f5c37f5f9ab0152f087bb4cf3560f8581 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/ChunkDataController.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/ChunkDataController.java +@@ -1,22 +1,24 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller; + +-import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.ChunkSystemRegionFileStorage; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemChunkMap; ++import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; + import ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkStorage; + import net.minecraft.nbt.CompoundTag; + import net.minecraft.server.level.ServerLevel; + import net.minecraft.world.level.ChunkPos; + import net.minecraft.world.level.chunk.storage.RegionFileStorage; + import java.io.IOException; +-import java.util.Optional; + import java.util.concurrent.CompletableFuture; + import java.util.concurrent.CompletionException; + +-public final class ChunkDataController extends RegionFileIOThread.ChunkDataController { ++public final class ChunkDataController extends MoonriseRegionFileIO.RegionDataController { + + private final ServerLevel world; + +- public ChunkDataController(final ServerLevel world) { +- super(RegionFileIOThread.RegionFileType.CHUNK_DATA); ++ public ChunkDataController(final ServerLevel world, final ChunkTaskScheduler taskScheduler) { ++ super(MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, taskScheduler.ioExecutor, taskScheduler.compressionExecutor); + this.world = world; + } + +@@ -26,31 +28,23 @@ public final class ChunkDataController extends RegionFileIOThread.ChunkDataContr + } + + @Override +- public void writeData(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { +- final CompletableFuture future = this.world.getChunkSource().chunkMap.write(new ChunkPos(chunkX, chunkZ), compound); +- +- try { +- if (future != null) { +- // rets non-null when sync writing (i.e. future should be completed here) +- future.join(); +- } +- } catch (final CompletionException ex) { +- if (ex.getCause() instanceof IOException ioException) { +- throw ioException; +- } +- throw ex; +- } ++ public WriteData startWrite(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$startWrite(chunkX, chunkZ, compound); + } + + @Override +- public CompoundTag readData(final int chunkX, final int chunkZ) throws IOException { +- try { +- return this.world.getChunkSource().chunkMap.read(new ChunkPos(chunkX, chunkZ)).join().orElse(null); +- } catch (final CompletionException ex) { +- if (ex.getCause() instanceof IOException ioException) { +- throw ioException; +- } +- throw ex; +- } ++ public void finishWrite(final int chunkX, final int chunkZ, final WriteData writeData) throws IOException { ++ ((ChunkSystemChunkMap)this.world.getChunkSource().chunkMap).moonrise$writeFinishCallback(new ChunkPos(chunkX, chunkZ)); ++ ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishWrite(chunkX, chunkZ, writeData); ++ } ++ ++ @Override ++ public ReadData readData(final int chunkX, final int chunkZ) throws IOException { ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$readData(chunkX, chunkZ); ++ } ++ ++ @Override ++ public CompoundTag finishRead(final int chunkX, final int chunkZ, final ReadData readData) throws IOException { ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishRead(chunkX, chunkZ, readData); + } + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/EntityDataController.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/EntityDataController.java +index fdd189ef056187941d43809c5d61cab717aecf60..828c868f68c2a20bf90d0f7ec253fdeb591f15f6 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/EntityDataController.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/EntityDataController.java +@@ -1,6 +1,8 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller; + +-import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.ChunkSystemRegionFileStorage; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; ++import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; + import net.minecraft.nbt.CompoundTag; + import net.minecraft.world.level.ChunkPos; + import net.minecraft.world.level.chunk.storage.EntityStorage; +@@ -9,12 +11,12 @@ import net.minecraft.world.level.chunk.storage.RegionStorageInfo; + import java.io.IOException; + import java.nio.file.Path; + +-public final class EntityDataController extends RegionFileIOThread.ChunkDataController { ++public final class EntityDataController extends MoonriseRegionFileIO.RegionDataController { + + private final EntityRegionFileStorage storage; + +- public EntityDataController(final EntityRegionFileStorage storage) { +- super(RegionFileIOThread.RegionFileType.ENTITY_DATA); ++ public EntityDataController(final EntityRegionFileStorage storage, final ChunkTaskScheduler taskScheduler) { ++ super(MoonriseRegionFileIO.RegionFileType.ENTITY_DATA, taskScheduler.ioExecutor, taskScheduler.compressionExecutor); + this.storage = storage; + } + +@@ -24,13 +26,35 @@ public final class EntityDataController extends RegionFileIOThread.ChunkDataCont + } + + @Override +- public void writeData(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { +- this.storage.write(new ChunkPos(chunkX, chunkZ), compound); ++ public WriteData startWrite(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { ++ checkPosition(new ChunkPos(chunkX, chunkZ), compound); ++ ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$startWrite(chunkX, chunkZ, compound); ++ } ++ ++ @Override ++ public void finishWrite(final int chunkX, final int chunkZ, final WriteData writeData) throws IOException { ++ ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishWrite(chunkX, chunkZ, writeData); ++ } ++ ++ @Override ++ public ReadData readData(final int chunkX, final int chunkZ) throws IOException { ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$readData(chunkX, chunkZ); + } + + @Override +- public CompoundTag readData(final int chunkX, final int chunkZ) throws IOException { +- return this.storage.read(new ChunkPos(chunkX, chunkZ)); ++ public CompoundTag finishRead(final int chunkX, final int chunkZ, final ReadData readData) throws IOException { ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishRead(chunkX, chunkZ, readData); ++ } ++ ++ private static void checkPosition(final ChunkPos pos, final CompoundTag nbt) { ++ final ChunkPos nbtPos = nbt == null ? null : EntityStorage.readChunkPos(nbt); ++ if (nbtPos != null && !pos.equals(nbtPos)) { ++ throw new IllegalArgumentException( ++ "Entity chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + pos.toString() ++ + " but compound says coordinate is " + nbtPos ++ ); ++ } + } + + public static final class EntityRegionFileStorage extends RegionFileStorage { +@@ -42,13 +66,7 @@ public final class EntityDataController extends RegionFileIOThread.ChunkDataCont + + @Override + public void write(final ChunkPos pos, final CompoundTag nbt) throws IOException { +- final ChunkPos nbtPos = nbt == null ? null : EntityStorage.readChunkPos(nbt); +- if (nbtPos != null && !pos.equals(nbtPos)) { +- throw new IllegalArgumentException( +- "Entity chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + pos.toString() +- + " but compound says coordinate is " + nbtPos + " for world: " + this +- ); +- } ++ checkPosition(pos, nbt); + super.write(pos, nbt); + } + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/PoiDataController.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/PoiDataController.java +index af867f8fedd0bb8f675e94243aa1a3f17363483b..bd0d782852f9cfe5bc0b5339ecf4d82c10332ec9 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/PoiDataController.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/PoiDataController.java +@@ -1,18 +1,20 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller; + +-import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.ChunkSystemRegionFileStorage; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; + import ca.spottedleaf.moonrise.patches.chunk_system.level.storage.ChunkSystemSectionStorage; ++import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; + import net.minecraft.nbt.CompoundTag; + import net.minecraft.server.level.ServerLevel; + import net.minecraft.world.level.chunk.storage.RegionFileStorage; + import java.io.IOException; + +-public final class PoiDataController extends RegionFileIOThread.ChunkDataController { ++public final class PoiDataController extends MoonriseRegionFileIO.RegionDataController { + + private final ServerLevel world; + +- public PoiDataController(final ServerLevel world) { +- super(RegionFileIOThread.RegionFileType.POI_DATA); ++ public PoiDataController(final ServerLevel world, final ChunkTaskScheduler taskScheduler) { ++ super(MoonriseRegionFileIO.RegionFileType.POI_DATA, taskScheduler.ioExecutor, taskScheduler.compressionExecutor); + this.world = world; + } + +@@ -22,12 +24,22 @@ public final class PoiDataController extends RegionFileIOThread.ChunkDataControl + } + + @Override +- public void writeData(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { +- ((ChunkSystemSectionStorage)this.world.getPoiManager()).moonrise$write(chunkX, chunkZ, compound); ++ public WriteData startWrite(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$startWrite(chunkX, chunkZ, compound); + } + + @Override +- public CompoundTag readData(final int chunkX, final int chunkZ) throws IOException { +- return ((ChunkSystemSectionStorage)this.world.getPoiManager()).moonrise$read(chunkX, chunkZ); ++ public void finishWrite(final int chunkX, final int chunkZ, final WriteData writeData) throws IOException { ++ ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishWrite(chunkX, chunkZ, writeData); ++ } ++ ++ @Override ++ public ReadData readData(final int chunkX, final int chunkZ) throws IOException { ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$readData(chunkX, chunkZ); ++ } ++ ++ @Override ++ public CompoundTag finishRead(final int chunkX, final int chunkZ, final ReadData readData) throws IOException { ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishRead(chunkX, chunkZ, readData); + } + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemChunkMap.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemChunkMap.java +new file mode 100644 +index 0000000000000000000000000000000000000000..47a4d3376d08dde94a39254bec21473ff27f53e6 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemChunkMap.java +@@ -0,0 +1,10 @@ ++package ca.spottedleaf.moonrise.patches.chunk_system.level; ++ ++import net.minecraft.world.level.ChunkPos; ++import java.io.IOException; ++ ++public interface ChunkSystemChunkMap { ++ ++ public void moonrise$writeFinishCallback(final ChunkPos pos) throws IOException; ++ ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemLevel.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemLevel.java +index efcd9057f008f0b9cf0d22b2b21d1851205841e5..5d4d650186b18eb00782429d53d861564d8e4ba9 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemLevel.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemLevel.java +@@ -1,5 +1,6 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.level; + ++import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; + import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup; + import net.minecraft.world.level.chunk.ChunkAccess; + import net.minecraft.world.level.chunk.LevelChunk; +@@ -19,4 +20,14 @@ public interface ChunkSystemLevel { + + public void moonrise$midTickTasks(); + ++ public ChunkData moonrise$getChunkData(final long chunkKey); ++ ++ public ChunkData moonrise$getChunkData(final int chunkX, final int chunkZ); ++ ++ public ChunkData moonrise$requestChunkData(final long chunkKey); ++ ++ public ChunkData moonrise$releaseChunkData(final long chunkKey); ++ ++ public boolean moonrise$areChunksLoaded(final int fromX, final int fromZ, final int toX, final int toZ); ++ + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java +index b8a87b7e6505feb76ce1bd58c84615256cf6faa6..9d46482476f9ed9032a2b0f89afc20e03ed42dbb 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java +@@ -1,12 +1,13 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.level; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.util.Priority; + import ca.spottedleaf.moonrise.common.list.ReferenceList; + import ca.spottedleaf.moonrise.common.misc.NearbyPlayers; +-import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; + import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader; + import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; + import net.minecraft.core.BlockPos; ++import net.minecraft.server.level.ChunkHolder; + import net.minecraft.server.level.ServerChunkCache; + import net.minecraft.world.level.chunk.ChunkAccess; + import net.minecraft.world.level.chunk.status.ChunkStatus; +@@ -17,32 +18,34 @@ public interface ChunkSystemServerLevel extends ChunkSystemLevel { + + public ChunkTaskScheduler moonrise$getChunkTaskScheduler(); + +- public RegionFileIOThread.ChunkDataController moonrise$getChunkDataController(); ++ public MoonriseRegionFileIO.RegionDataController moonrise$getChunkDataController(); + +- public RegionFileIOThread.ChunkDataController moonrise$getPoiChunkDataController(); ++ public MoonriseRegionFileIO.RegionDataController moonrise$getPoiChunkDataController(); + +- public RegionFileIOThread.ChunkDataController moonrise$getEntityChunkDataController(); ++ public MoonriseRegionFileIO.RegionDataController moonrise$getEntityChunkDataController(); + + public int moonrise$getRegionChunkShift(); + +- // Paper - marked closing not needed on CB ++ public boolean moonrise$isMarkedClosing(); ++ ++ public void moonrise$setMarkedClosing(final boolean value); + + public RegionizedPlayerChunkLoader moonrise$getPlayerChunkLoader(); + + public void moonrise$loadChunksAsync(final BlockPos pos, final int radiusBlocks, +- final PrioritisedExecutor.Priority priority, ++ final Priority priority, + final Consumer> onLoad); + + public void moonrise$loadChunksAsync(final BlockPos pos, final int radiusBlocks, +- final ChunkStatus chunkStatus, final PrioritisedExecutor.Priority priority, ++ final ChunkStatus chunkStatus, final Priority priority, + final Consumer> onLoad); + + public void moonrise$loadChunksAsync(final int minChunkX, final int maxChunkX, final int minChunkZ, final int maxChunkZ, +- final PrioritisedExecutor.Priority priority, ++ final Priority priority, + final Consumer> onLoad); + + public void moonrise$loadChunksAsync(final int minChunkX, final int maxChunkX, final int minChunkZ, final int maxChunkZ, +- final ChunkStatus chunkStatus, final PrioritisedExecutor.Priority priority, ++ final ChunkStatus chunkStatus, final Priority priority, + final Consumer> onLoad); + + public RegionizedPlayerChunkLoader.ViewDistanceHolder moonrise$getViewDistanceHolder(); +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkData.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkData.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8b9dc582627b46843f4b5ea6f8c3df2d8cac46fa +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkData.java +@@ -0,0 +1,21 @@ ++package ca.spottedleaf.moonrise.patches.chunk_system.level.chunk; ++ ++import ca.spottedleaf.moonrise.common.misc.NearbyPlayers; ++ ++public final class ChunkData { ++ ++ private int referenceCount = 0; ++ public NearbyPlayers.TrackedChunk nearbyPlayers; // Moonrise - nearby players ++ ++ public ChunkData() { ++ ++ } ++ ++ public int increaseRef() { ++ return ++this.referenceCount; ++ } ++ ++ public int decreaseRef() { ++ return --this.referenceCount; ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemDistanceManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemDistanceManager.java +index 883fe6401f1b9711fa544d18a815b4d638f580df..aacd543f03b35908011d0c2891e978cc093ebcf5 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemDistanceManager.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemDistanceManager.java +@@ -1,9 +1,12 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.level.chunk; + ++import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager; + import net.minecraft.server.level.ChunkMap; + + public interface ChunkSystemDistanceManager { + + public ChunkMap moonrise$getChunkMap(); + ++ public ChunkHolderManager moonrise$getChunkHolderManager(); ++ + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java +index 5c7f2471a0b15ac2e714527296ad2aa7291999eb..40dc7569c32b100d4eebbde9024ded2acbb2fb20 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java +@@ -1,6 +1,8 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.level.entity; + ++import ca.spottedleaf.moonrise.common.PlatformHooks; + import ca.spottedleaf.moonrise.common.list.EntityList; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; + import ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity; + import com.google.common.collect.ImmutableList; + import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; +@@ -13,6 +15,7 @@ import net.minecraft.server.level.FullChunkStatus; + import net.minecraft.server.level.ServerLevel; + import net.minecraft.util.Mth; + import net.minecraft.world.entity.Entity; ++import net.minecraft.world.entity.EntitySpawnReason; + import net.minecraft.world.entity.EntityType; + import net.minecraft.world.entity.boss.EnderDragonPart; + import net.minecraft.world.entity.boss.enderdragon.EnderDragon; +@@ -26,7 +29,6 @@ import java.util.Arrays; + import java.util.Iterator; + import java.util.List; + import java.util.function.Predicate; +-import org.bukkit.event.entity.EntityRemoveEvent; + + public final class ChunkEntitySlices { + +@@ -43,6 +45,7 @@ public final class ChunkEntitySlices { + private final EntityList entities = new EntityList(); + + public FullChunkStatus status; ++ public final ChunkData chunkData; + + private boolean isTransient; + +@@ -55,7 +58,7 @@ public final class ChunkEntitySlices { + } + + public ChunkEntitySlices(final Level world, final int chunkX, final int chunkZ, final FullChunkStatus status, +- final int minSection, final int maxSection) { // inclusive, inclusive ++ final ChunkData chunkData, final int minSection, final int maxSection) { // inclusive, inclusive + this.minSection = minSection; + this.maxSection = maxSection; + this.chunkX = chunkX; +@@ -68,11 +71,12 @@ public final class ChunkEntitySlices { + this.entitiesByType = new Reference2ObjectOpenHashMap<>(); + + this.status = status; ++ this.chunkData = chunkData; + } + + public static List readEntities(final ServerLevel world, final CompoundTag compoundTag) { + // TODO check this and below on update for format changes +- return EntityType.loadEntitiesRecursive(compoundTag.getList("Entities", 10), world).collect(ImmutableList.toImmutableList()); ++ return EntityType.loadEntitiesRecursive(compoundTag.getList("Entities", 10), world, EntitySpawnReason.LOAD).collect(ImmutableList.toImmutableList()); + } + + // Paper start - rewrite chunk system +@@ -100,18 +104,7 @@ public final class ChunkEntitySlices { + } + + final ListTag entitiesTag = new ListTag(); +- final java.util.Map, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk +- for (final Entity entity : entities) { +- // Paper start - Entity load/save limit per chunk +- final EntityType entityType = entity.getType(); +- final int saveLimit = world.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1); +- if (saveLimit > -1) { +- if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) { +- continue; +- } +- savedEntityCounts.merge(entityType, 1, Integer::sum); +- } +- // Paper end - Entity load/save limit per chunk ++ for (final Entity entity : PlatformHooks.get().modifySavedEntities(world, chunkPos.x, chunkPos.z, entities)) { + CompoundTag compoundTag = new CompoundTag(); + if (entity.save(compoundTag)) { + entitiesTag.add(compoundTag); +@@ -158,12 +151,12 @@ public final class ChunkEntitySlices { + continue; + } + if (entity.shouldBeSaved()) { +- entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, EntityRemoveEvent.Cause.UNLOAD); ++ PlatformHooks.get().unloadEntity(entity); + if (entity.isVehicle()) { + // we cannot assume that these entities are contained within this chunk, because entities can + // desync - so we need to remove them all + for (final Entity passenger : entity.getIndirectPassengers()) { +- passenger.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, EntityRemoveEvent.Cause.UNLOAD); ++ PlatformHooks.get().unloadEntity(passenger); + } + } + } +@@ -172,33 +165,6 @@ public final class ChunkEntitySlices { + return this.entities.size() != 0; + } + +- // Paper start +- public org.bukkit.entity.Entity[] getChunkEntities() { +- List ret = new java.util.ArrayList<>(); +- final Entity[] entities = this.entities.getRawData(); +- for (int i = 0, size = Math.min(entities.length, this.entities.size()); i < size; ++i) { +- final Entity entity = entities[i]; +- if (entity == null) { +- continue; +- } +- final org.bukkit.entity.Entity bukkit = entity.getBukkitEntity(); +- if (bukkit != null && bukkit.isValid()) { +- ret.add(bukkit); +- } +- } +- +- return ret.toArray(new org.bukkit.entity.Entity[0]); +- } +- +- public void callEntitiesLoadEvent() { +- org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesLoadEvent(this.world, new ChunkPos(this.chunkX, this.chunkZ), this.getAllEntities()); +- } +- +- public void callEntitiesUnloadEvent() { +- org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesUnloadEvent(this.world, new ChunkPos(this.chunkX, this.chunkZ), this.getAllEntities()); +- } +- // Paper end +- + private List getAllEntities() { + final int len = this.entities.size(); + if (len == 0) { +@@ -262,6 +228,7 @@ public final class ChunkEntitySlices { + return false; + } + ((ChunkSystemEntity)entity).moonrise$setChunkStatus(this.status); ++ ((ChunkSystemEntity)entity).moonrise$setChunkData(this.chunkData); + final int sectionIndex = chunkSection - this.minSection; + + this.allEntities.addEntity(entity, sectionIndex); +@@ -295,6 +262,7 @@ public final class ChunkEntitySlices { + return false; + } + ((ChunkSystemEntity)entity).moonrise$setChunkStatus(null); ++ ((ChunkSystemEntity)entity).moonrise$setChunkData(null); + final int sectionIndex = chunkSection - this.minSection; + + this.allEntities.removeEntity(entity, sectionIndex); +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java +index efc0c1acc8239dd7b00211a1d3bfd3fc3b2c810c..93335de8cf514dc8417e4b9b2d495663deda2904 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java +@@ -46,8 +46,6 @@ public abstract class EntityLookup implements LevelEntityGetter { + + protected final SWMRLong2ObjectHashTable regions = new SWMRLong2ObjectHashTable<>(128, 0.5f); + +- protected final int minSection; // inclusive +- protected final int maxSection; // inclusive + protected final LevelCallback worldCallback; + + protected final ConcurrentLong2ReferenceChainedHashTable entityById = new ConcurrentLong2ReferenceChainedHashTable<>(); +@@ -56,8 +54,6 @@ public abstract class EntityLookup implements LevelEntityGetter { + + public EntityLookup(final Level world, final LevelCallback worldCallback) { + this.world = world; +- this.minSection = WorldUtil.getMinSection(world); +- this.maxSection = WorldUtil.getMaxSection(world); + this.worldCallback = worldCallback; + } + +@@ -91,7 +87,7 @@ public abstract class EntityLookup implements LevelEntityGetter { + + protected abstract void entityEndTicking(final Entity entity); + +- protected abstract boolean screenEntity(final Entity entity); ++ protected abstract boolean screenEntity(final Entity entity, final boolean fromDisk, final boolean event); + + private static Entity maskNonAccessible(final Entity entity) { + if (entity == null) { +@@ -347,7 +343,7 @@ public abstract class EntityLookup implements LevelEntityGetter { + } + + protected void addRecursivelySafe(final Entity root, final boolean fromDisk) { +- if (!this.addEntity(root, fromDisk)) { ++ if (!this.addEntity(root, fromDisk, true)) { + // possible we are a passenger, and so should dismount from any valid entity in the world + root.stopRiding(); + return; +@@ -386,7 +382,11 @@ public abstract class EntityLookup implements LevelEntityGetter { + } + + public boolean addNewEntity(final Entity entity) { +- return this.addEntity(entity, false); ++ return this.addNewEntity(entity, true); ++ } ++ ++ public boolean addNewEntity(final Entity entity, final boolean event) { ++ return this.addEntity(entity, false, event); + } + + public static Visibility getEntityStatus(final Entity entity) { +@@ -397,10 +397,10 @@ public abstract class EntityLookup implements LevelEntityGetter { + return Visibility.fromFullChunkStatus(entityStatus == null ? FullChunkStatus.INACCESSIBLE : entityStatus); + } + +- protected boolean addEntity(final Entity entity, final boolean fromDisk) { ++ protected boolean addEntity(final Entity entity, final boolean fromDisk, final boolean event) { + final BlockPos pos = entity.blockPosition(); + final int sectionX = pos.getX() >> 4; +- final int sectionY = Mth.clamp(pos.getY() >> 4, this.minSection, this.maxSection); ++ final int sectionY = Mth.clamp(pos.getY() >> 4, WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world)); + final int sectionZ = pos.getZ() >> 4; + this.checkThread(sectionX, sectionZ, "Cannot add entity off-main thread"); + +@@ -414,7 +414,7 @@ public abstract class EntityLookup implements LevelEntityGetter { + return false; + } + +- if (!this.screenEntity(entity)) { ++ if (!this.screenEntity(entity, fromDisk, event)) { + return false; + } + +@@ -519,7 +519,7 @@ public abstract class EntityLookup implements LevelEntityGetter { + final int sectionZ = ((ChunkSystemEntity)entity).moonrise$getSectionZ(); + final BlockPos newPos = entity.blockPosition(); + final int newSectionX = newPos.getX() >> 4; +- final int newSectionY = Mth.clamp(newPos.getY() >> 4, this.minSection, this.maxSection); ++ final int newSectionY = Mth.clamp(newPos.getY() >> 4, WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world)); + final int newSectionZ = newPos.getZ() >> 4; + + if (newSectionX == sectionX && newSectionY == sectionY && newSectionZ == sectionZ) { +@@ -959,7 +959,7 @@ public abstract class EntityLookup implements LevelEntityGetter { + + public ChunkEntitySlices getOrCreateChunk(final int chunkX, final int chunkZ) { + final ChunkSlicesRegion region = this.getRegion(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT); +- ChunkEntitySlices ret; ++ final ChunkEntitySlices ret; + if (region == null || (ret = region.get((chunkX & REGION_MASK) | ((chunkZ & REGION_MASK) << REGION_SHIFT))) == null) { + return this.createEntityChunk(chunkX, chunkZ, true); + } +@@ -1057,7 +1057,7 @@ public abstract class EntityLookup implements LevelEntityGetter { + @Override + public void onRemove(final Entity.RemovalReason reason) { + final Entity entity = this.entity; +- EntityLookup.this.checkThread(entity, "Cannot remove entity off-main"); // Paper - rewrite chunk system ++ EntityLookup.this.checkThread(entity, "Cannot remove entity off-main"); + final Visibility tickingState = EntityLookup.getEntityStatus(entity); + + EntityLookup.this.removeEntity(entity); +@@ -1080,4 +1080,4 @@ public abstract class EntityLookup implements LevelEntityGetter { + @Override + public void onRemove(final Entity.RemovalReason reason) {} + } +-} +\ No newline at end of file ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java +index edcde00206d068bd79175fea33efa05b0e8c1562..a038215156a163b0b1cbc870ada5b4ac85ed1335 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java +@@ -1,5 +1,6 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.level.entity.client; + ++import ca.spottedleaf.moonrise.common.PlatformHooks; + import ca.spottedleaf.moonrise.common.util.CoordinateUtils; + import ca.spottedleaf.moonrise.common.util.WorldUtil; + import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; +@@ -45,7 +46,8 @@ public final class ClientEntityLookup extends EntityLookup { + + final ChunkEntitySlices ret = new ChunkEntitySlices( + this.world, chunkX, chunkZ, +- ticking ? FullChunkStatus.ENTITY_TICKING : FullChunkStatus.FULL, WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) ++ ticking ? FullChunkStatus.ENTITY_TICKING : FullChunkStatus.FULL, null, ++ WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) + ); + + // note: not handled by superclass +@@ -63,7 +65,11 @@ public final class ClientEntityLookup extends EntityLookup { + protected void entitySectionChangeCallback(final Entity entity, + final int oldSectionX, final int oldSectionY, final int oldSectionZ, + final int newSectionX, final int newSectionY, final int newSectionZ) { +- ++ PlatformHooks.get().entityMove( ++ entity, ++ CoordinateUtils.getChunkSectionKey(oldSectionX, oldSectionY, oldSectionZ), ++ CoordinateUtils.getChunkSectionKey(newSectionX, newSectionY, newSectionZ) ++ ); + } + + @Override +@@ -97,7 +103,7 @@ public final class ClientEntityLookup extends EntityLookup { + } + + @Override +- protected boolean screenEntity(final Entity entity) { ++ protected boolean screenEntity(final Entity entity, final boolean fromDisk, final boolean event) { + return true; + } + +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java +index 465469e44346c50f30f3abd6b44f4173ccfcf248..2ff58cf753c60913ee73aae015182e9c5560d529 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java +@@ -32,7 +32,7 @@ public final class DefaultEntityLookup extends EntityLookup { + protected ChunkEntitySlices createEntityChunk(final int chunkX, final int chunkZ, final boolean transientChunk) { + final ChunkEntitySlices ret = new ChunkEntitySlices( + this.world, chunkX, chunkZ, FullChunkStatus.FULL, +- WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) ++ null, WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) + ); + + // note: not handled by superclass +@@ -84,7 +84,7 @@ public final class DefaultEntityLookup extends EntityLookup { + } + + @Override +- protected boolean screenEntity(final Entity entity) { ++ protected boolean screenEntity(final Entity entity, final boolean fromDisk, final boolean event) { + return true; + } + +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java +index dacf2b2988ce603879fe525a3418ac77f8a663f7..58d9187adc188b693b6becc400f766e069bf1bf5 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java +@@ -1,6 +1,8 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server; + ++import ca.spottedleaf.moonrise.common.PlatformHooks; + import ca.spottedleaf.moonrise.common.list.ReferenceList; ++import ca.spottedleaf.moonrise.common.util.CoordinateUtils; + import ca.spottedleaf.moonrise.common.util.TickThread; + import ca.spottedleaf.moonrise.common.util.ChunkSystem; + import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; +@@ -17,7 +19,6 @@ public final class ServerEntityLookup extends EntityLookup { + + private final ServerLevel serverWorld; + public final ReferenceList trackerEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY); // Moonrise - entity tracker +- public final ReferenceList trackerUnloadedEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY); // Moonrise - entity tracker + + public ServerEntityLookup(final ServerLevel world, final LevelCallback worldCallback) { + super(world, worldCallback); +@@ -63,6 +64,11 @@ public final class ServerEntityLookup extends EntityLookup { + if (entity instanceof ServerPlayer player) { + ((ChunkSystemServerLevel)this.serverWorld).moonrise$getNearbyPlayers().tickPlayer(player); + } ++ PlatformHooks.get().entityMove( ++ entity, ++ CoordinateUtils.getChunkSectionKey(oldSectionX, oldSectionY, oldSectionZ), ++ CoordinateUtils.getChunkSectionKey(newSectionX, newSectionY, newSectionZ) ++ ); + } + + @Override +@@ -77,14 +83,12 @@ public final class ServerEntityLookup extends EntityLookup { + if (entity instanceof ServerPlayer player) { + ((ChunkSystemServerLevel)this.serverWorld).moonrise$getNearbyPlayers().removePlayer(player); + } +- this.trackerUnloadedEntities.remove(entity); // Moonrise - entity tracker + } + + @Override + protected void entityStartLoaded(final Entity entity) { + // Moonrise start - entity tracker + this.trackerEntities.add(entity); +- this.trackerUnloadedEntities.remove(entity); + // Moonrise end - entity tracker + } + +@@ -92,7 +96,6 @@ public final class ServerEntityLookup extends EntityLookup { + protected void entityEndLoaded(final Entity entity) { + // Moonrise start - entity tracker + this.trackerEntities.remove(entity); +- this.trackerUnloadedEntities.add(entity); + // Moonrise end - entity tracker + } + +@@ -107,7 +110,7 @@ public final class ServerEntityLookup extends EntityLookup { + } + + @Override +- protected boolean screenEntity(final Entity entity) { +- return ChunkSystem.screenEntity(this.serverWorld, entity); ++ protected boolean screenEntity(final Entity entity, final boolean fromDisk, final boolean event) { ++ return ChunkSystem.screenEntity(this.serverWorld, entity, fromDisk, event); + } + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java +index fd35e4db0c8fec8f86b8743bcc2b15ed2e7433f1..bbf9d6c1c9525d97160806819a57be03eca290f1 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java +@@ -3,7 +3,6 @@ package ca.spottedleaf.moonrise.patches.chunk_system.level.poi; + import ca.spottedleaf.moonrise.common.util.CoordinateUtils; + import ca.spottedleaf.moonrise.common.util.TickThread; + import ca.spottedleaf.moonrise.common.util.WorldUtil; +-import com.mojang.serialization.Codec; + import com.mojang.serialization.DataResult; + import net.minecraft.SharedConstants; + import net.minecraft.nbt.CompoundTag; +@@ -123,7 +122,6 @@ public final class PoiChunk { + ret.putInt("DataVersion", SharedConstants.getCurrentVersion().getDataVersion().getVersion()); + + final ServerLevel world = this.world; +- final PoiManager poiManager = world.getPoiManager(); + final int chunkX = this.chunkX; + final int chunkZ = this.chunkZ; + +@@ -133,13 +131,8 @@ public final class PoiChunk { + continue; + } + +- final long key = CoordinateUtils.getChunkSectionKey(chunkX, sectionY, chunkZ); +- // codecs are honestly such a fucking disaster. What the fuck is this trash? +- final Codec codec = PoiSection.codec(() -> { +- poiManager.setDirty(key); +- }); +- +- final DataResult serializedResult = codec.encodeStart(registryOps, section); ++ // I do not believe asynchronously converting to CompoundTag is worth the scheduling. ++ final DataResult serializedResult = PoiSection.Packed.CODEC.encodeStart(registryOps, section.pack()); + final int finalSectionY = sectionY; + final Tag serialized = serializedResult.resultOrPartial((final String description) -> { + LOGGER.error("Failed to serialize poi chunk for world: " + WorldUtil.getWorldName(world) + ", chunk: (" + chunkX + "," + finalSectionY + "," + chunkZ + "); description: " + description); +@@ -183,19 +176,18 @@ public final class PoiChunk { + continue; + } + +- final long coordinateKey = CoordinateUtils.getChunkSectionKey(chunkX, sectionY, chunkZ); +- // codecs are honestly such a fucking disaster. What the fuck is this trash? +- final Codec codec = PoiSection.codec(() -> { +- poiManager.setDirty(coordinateKey); +- }); +- + final CompoundTag section = sections.getCompound(key); +- final DataResult deserializeResult = codec.parse(registryOps, section); ++ final DataResult deserializeResult = PoiSection.Packed.CODEC.parse(registryOps, section); + final int finalSectionY = sectionY; +- final PoiSection deserialized = deserializeResult.resultOrPartial((final String description) -> { ++ final PoiSection.Packed packed = deserializeResult.resultOrPartial((final String description) -> { + LOGGER.error("Failed to deserialize poi chunk for world: " + WorldUtil.getWorldName(world) + ", chunk: (" + chunkX + "," + finalSectionY + "," + chunkZ + "); description: " + description); + }).orElse(null); + ++ final long coordinateKey = CoordinateUtils.getChunkSectionKey(chunkX, sectionY, chunkZ); ++ final PoiSection deserialized = packed == null ? null : packed.unpack(() -> { ++ poiManager.setDirty(coordinateKey); ++ }); ++ + if (deserialized == null || ((ChunkSystemPoiSection)deserialized).moonrise$isEmpty()) { + // completely empty, no point in storing this + continue; +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java +index 3f5edb756beb9c31b6f591a24b778d6ac2b0bf51..23bd741dc0bfd48b8064a2b498d71cfa8f8145b2 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java +@@ -1,12 +1,8 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.level.storage; + +-import com.mojang.serialization.Dynamic; + import net.minecraft.nbt.CompoundTag; +-import net.minecraft.nbt.Tag; + import net.minecraft.world.level.chunk.storage.RegionFileStorage; + import java.io.IOException; +-import java.util.Optional; +-import java.util.concurrent.CompletableFuture; + + public interface ChunkSystemSectionStorage { + +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java +index a608f57ebca98eda88ad749d0aad021678be54f9..b2fa9883aefb07f64bb5db7e0052218d2ad09aba 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java +@@ -1,7 +1,8 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.player; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; + import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.PlatformHooks; + import ca.spottedleaf.moonrise.common.misc.AllocatingRateLimiter; + import ca.spottedleaf.moonrise.common.misc.SingleUserAreaMap; + import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +@@ -412,7 +413,11 @@ public final class RegionizedPlayerChunkLoader { + if (this.sentChunks.add(CoordinateUtils.getChunkKey(chunkX, chunkZ))) { + ((ChunkSystemChunkHolder)((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager + .getChunkHolder(chunkX, chunkZ).vanillaChunkHolder).moonrise$addReceivedChunk(this.player); +- PlayerChunkSender.sendChunk(this.player.connection, this.world, ((ChunkSystemLevel)this.world).moonrise$getFullChunkIfLoaded(chunkX, chunkZ)); ++ ++ final LevelChunk chunk = ((ChunkSystemLevel)this.world).moonrise$getFullChunkIfLoaded(chunkX, chunkZ); ++ ++ PlatformHooks.get().onChunkWatch(this.world, chunk, this.player); ++ PlayerChunkSender.sendChunk(this.player.connection, this.world, chunk); + return; + } + throw new IllegalStateException(); +@@ -426,17 +431,12 @@ public final class RegionizedPlayerChunkLoader { + } + + private void sendUnloadChunkRaw(final int chunkX, final int chunkZ) { ++ PlatformHooks.get().onChunkUnWatch(this.world, new ChunkPos(chunkX, chunkZ), this.player); + // Note: Check PlayerChunkSender#dropChunk for other logic + // Note: drop isAlive() check so that chunks properly unload client-side when the player dies + ((ChunkSystemChunkHolder)((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager + .getChunkHolder(chunkX, chunkZ).vanillaChunkHolder).moonrise$removeReceivedChunk(this.player); +- final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); +- this.player.connection.send(new ClientboundForgetLevelChunkPacket(chunkPos)); +- // Paper start - PlayerChunkUnloadEvent +- if (io.papermc.paper.event.packet.PlayerChunkUnloadEvent.getHandlerList().getRegisteredListeners().length > 0) { +- new io.papermc.paper.event.packet.PlayerChunkUnloadEvent(this.world.getWorld().getChunkAt(chunkPos.longKey), this.player.getBukkitEntity()).callEvent(); +- } +- // Paper end - PlayerChunkUnloadEvent ++ this.player.connection.send(new ClientboundForgetLevelChunkPacket(new ChunkPos(chunkX, chunkZ))); + } + + private final SingleUserAreaMap broadcastMap = new SingleUserAreaMap<>(this) { +@@ -529,7 +529,7 @@ public final class RegionizedPlayerChunkLoader { + final int playerSendViewDistance, final int worldSendViewDistance) { + return Math.min( + loadViewDistance - 1, +- playerSendViewDistance < 0 ? (!io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.autoConfigSendDistance || clientViewDistance < 0 ? (worldSendViewDistance < 0 ? (loadViewDistance - 1) : worldSendViewDistance) : clientViewDistance + 1) : playerSendViewDistance ++ playerSendViewDistance < 0 ? (!PlatformHooks.get().configAutoConfigSendDistance() || clientViewDistance < 0 ? (worldSendViewDistance < 0 ? (loadViewDistance - 1) : worldSendViewDistance) : clientViewDistance + 1) : playerSendViewDistance + ); + } + +@@ -554,26 +554,26 @@ public final class RegionizedPlayerChunkLoader { + } + + private double getMaxChunkLoadRate() { +- final double configRate = io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkLoadRate; ++ final double configRate = PlatformHooks.get().configPlayerMaxLoadRate(); + + return configRate <= 0.0 || configRate > (double)MAX_RATE ? (double)MAX_RATE : Math.max(1.0, configRate); + } + + private double getMaxChunkGenRate() { +- final double configRate = io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkGenerateRate; ++ final double configRate = PlatformHooks.get().configPlayerMaxGenRate(); + + return configRate <= 0.0 || configRate > (double)MAX_RATE ? (double)MAX_RATE : Math.max(1.0, configRate); + } + + private double getMaxChunkSendRate() { +- final double configRate = io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkSendRate; ++ final double configRate = PlatformHooks.get().configPlayerMaxSendRate(); + + return configRate <= 0.0 || configRate > (double)MAX_RATE ? (double)MAX_RATE : Math.max(1.0, configRate); + } + + private long getMaxChunkLoads() { + final long radiusChunks = (2L * this.lastLoadDistance + 1L) * (2L * this.lastLoadDistance + 1L); +- long configLimit = io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkLoads; ++ long configLimit = (long)PlatformHooks.get().configPlayerMaxConcurrentLoads(); + if (configLimit == 0L) { + // by default, only allow 1/5th of the chunks in the view distance to be concurrently active + configLimit = Math.max(5L, radiusChunks / 5L); +@@ -587,7 +587,7 @@ public final class RegionizedPlayerChunkLoader { + + private long getMaxChunkGenerates() { + final long radiusChunks = (2L * this.lastLoadDistance + 1L) * (2L * this.lastLoadDistance + 1L); +- long configLimit = io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkGenerates; ++ long configLimit = (long)PlatformHooks.get().configPlayerMaxConcurrentGens(); + if (configLimit == 0L) { + // by default, only allow 1/5th of the chunks in the view distance to be concurrently active + configLimit = Math.max(5L, radiusChunks / 5L); +@@ -709,7 +709,7 @@ public final class RegionizedPlayerChunkLoader { + final int queuedChunkX = CoordinateUtils.getChunkX(queuedLoadChunk); + final int queuedChunkZ = CoordinateUtils.getChunkZ(queuedLoadChunk); + ((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().scheduleChunkLoad( +- queuedChunkX, queuedChunkZ, ChunkStatus.EMPTY, false, PrioritisedExecutor.Priority.NORMAL, null ++ queuedChunkX, queuedChunkZ, ChunkStatus.EMPTY, false, Priority.NORMAL, null + ); + if (this.removed) { + return; +@@ -825,7 +825,7 @@ public final class RegionizedPlayerChunkLoader { + } + if (!((ChunkSystemLevelChunk)chunk).moonrise$isPostProcessingDone()) { + // not yet post-processed, need to do this so that tile entities can properly be sent to clients +- chunk.postProcessGeneration(); ++ chunk.postProcessGeneration(this.world); + // check if there was any recursive action + if (this.removed || this.sendQueue.isEmpty() || this.sendQueue.firstLong() != pendingSend) { + return; +@@ -864,7 +864,6 @@ public final class RegionizedPlayerChunkLoader { + final int clientViewDistance = getClientViewDistance(this.player); + final int sendViewDistance = getSendViewDistance(loadViewDistance, clientViewDistance, playerDistances.sendViewDistance, worldDistances.sendViewDistance); + +- // TODO check PlayerList diff in paper chunk system patch + // send view distances + this.player.connection.send(this.updateClientChunkRadius(sendViewDistance)); + this.player.connection.send(this.updateClientSimulationDistance(tickViewDistance)); +@@ -1079,8 +1078,7 @@ public final class RegionizedPlayerChunkLoader { + // now all tickets should be removed, which is all of our external state + } + +- // For external checks +- public it.unimi.dsi.fastutil.longs.LongOpenHashSet getSentChunksRaw() { ++ public LongOpenHashSet getSentChunksRaw() { + return this.sentChunks; + } + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java +index 58d3d1a47e9f2423c467bb329c2d5f4b58a8b5ef..f98df65eaed2abedc66f3a49790e0cfb65354ed9 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java +@@ -1,14 +1,14 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; + import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; + import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.PlatformHooks; + import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +-import ca.spottedleaf.moonrise.common.util.MoonriseCommon; + import ca.spottedleaf.moonrise.common.util.TickThread; + import ca.spottedleaf.moonrise.common.util.WorldUtil; + import ca.spottedleaf.moonrise.common.util.ChunkSystem; +-import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; + import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; + import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; + import ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk; +@@ -20,7 +20,6 @@ import ca.spottedleaf.moonrise.patches.chunk_system.ticket.ChunkSystemTicket; + import ca.spottedleaf.moonrise.patches.chunk_system.util.ChunkSystemSortedArraySet; + import com.google.gson.JsonArray; + import com.google.gson.JsonObject; +-import com.mojang.logging.LogUtils; + import it.unimi.dsi.fastutil.longs.Long2ByteLinkedOpenHashMap; + import it.unimi.dsi.fastutil.longs.Long2ByteMap; + import it.unimi.dsi.fastutil.longs.Long2IntMap; +@@ -40,7 +39,9 @@ import net.minecraft.server.level.TicketType; + import net.minecraft.util.SortedArraySet; + import net.minecraft.util.Unit; + import net.minecraft.world.level.ChunkPos; ++import net.minecraft.world.level.chunk.LevelChunk; + import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; + import java.io.IOException; + import java.text.DecimalFormat; + import java.util.ArrayDeque; +@@ -58,7 +59,7 @@ import java.util.function.Predicate; + + public final class ChunkHolderManager { + +- private static final Logger LOGGER = LogUtils.getClassLogger(); ++ private static final Logger LOGGER = LoggerFactory.getLogger(ChunkHolderManager.class); + + public static final int FULL_LOADED_TICKET_LEVEL = ChunkLevel.FULL_CHUNK_LEVEL; + public static final int BLOCK_TICKING_TICKET_LEVEL = ChunkLevel.BLOCK_TICKING_LEVEL; +@@ -189,7 +190,7 @@ public final class ChunkHolderManager { + if (halt) { + LOGGER.info("Waiting 60s for chunk system to halt for world '" + WorldUtil.getWorldName(this.world) + "'"); + if (!this.taskScheduler.halt(true, TimeUnit.SECONDS.toNanos(60L))) { +- LOGGER.warn("Failed to halt world generation/loading tasks for world '" + WorldUtil.getWorldName(this.world) + "'"); ++ LOGGER.warn("Failed to halt generation/loading tasks for world '" + WorldUtil.getWorldName(this.world) + "'"); + } else { + LOGGER.info("Halted chunk system for world '" + WorldUtil.getWorldName(this.world) + "'"); + } +@@ -199,21 +200,21 @@ public final class ChunkHolderManager { + this.saveAllChunks(true, true, true); + } + +- boolean hasTasks = false; +- for (final RegionFileIOThread.RegionFileType type : RegionFileIOThread.RegionFileType.values()) { +- if (RegionFileIOThread.getControllerFor(this.world, type).hasTasks()) { +- hasTasks = true; +- break; ++ MoonriseRegionFileIO.flush(this.world); ++ ++ if (halt) { ++ LOGGER.info("Waiting 60s for chunk I/O to halt for world '" + WorldUtil.getWorldName(this.world) + "'"); ++ if (!this.taskScheduler.haltIO(true, TimeUnit.SECONDS.toNanos(60L))) { ++ LOGGER.warn("Failed to halt I/O tasks for world '" + WorldUtil.getWorldName(this.world) + "'"); ++ } else { ++ LOGGER.info("Halted I/O scheduler for world '" + WorldUtil.getWorldName(this.world) + "'"); + } + } +- if (hasTasks) { +- RegionFileIOThread.flush(); +- } + + // kill regionfile cache +- for (final RegionFileIOThread.RegionFileType type : RegionFileIOThread.RegionFileType.values()) { ++ for (final MoonriseRegionFileIO.RegionFileType type : MoonriseRegionFileIO.RegionFileType.values()) { + try { +- RegionFileIOThread.getControllerFor(this.world, type).getCache().close(); ++ MoonriseRegionFileIO.getControllerFor(this.world, type).getCache().close(); + } catch (final IOException ex) { + LOGGER.error("Failed to close '" + type.name() + "' regionfile cache for world '" + WorldUtil.getWorldName(this.world) + "'", ex); + } +@@ -230,8 +231,8 @@ public final class ChunkHolderManager { + public void autoSave() { + final List reschedule = new ArrayList<>(); + final long currentTick = this.currentTick; +- final long maxSaveTime = currentTick - Math.max(1L, this.world.paperConfig().chunks.autoSaveInterval.value()); +- final int maxToSave = this.world.paperConfig().chunks.maxAutoSaveChunksPerTick; ++ final long maxSaveTime = currentTick - Math.max(1L, PlatformHooks.get().configAutoSaveInterval()); ++ final int maxToSave = PlatformHooks.get().configMaxAutoSavePerTick(); + for (int autoSaved = 0; autoSaved < maxToSave && !this.autoSaveQueue.isEmpty();) { + final NewChunkHolder holder = this.autoSaveQueue.first(); + +@@ -271,55 +272,74 @@ public final class ChunkHolderManager { + + long start = System.nanoTime(); + long lastLog = start; +- boolean needsFlush = false; +- final int flushInterval = 50; ++ final int flushInterval = 200; ++ int lastFlush = 0; + + int savedChunk = 0; + int savedEntity = 0; + int savedPoi = 0; + ++ if (shutdown) { ++ // Normal unload process does not occur during shutdown: fire event manually ++ // for mods that expect ChunkEvent.Unload to fire on shutdown (before LevelEvent.Unload) ++ for (int i = 0, len = holders.size(); i < len; ++i) { ++ final NewChunkHolder holder = holders.get(i); ++ if (holder.getCurrentChunk() instanceof LevelChunk levelChunk) { ++ PlatformHooks.get().chunkUnloadFromWorld(levelChunk); ++ } ++ } ++ } + for (int i = 0, len = holders.size(); i < len; ++i) { + final NewChunkHolder holder = holders.get(i); + try { + final NewChunkHolder.SaveStat saveStat = holder.save(shutdown); + if (saveStat != null) { +- ++saved; +- needsFlush = flush; + if (saveStat.savedChunk()) { + ++savedChunk; ++ ++saved; + } + if (saveStat.savedEntityChunk()) { + ++savedEntity; ++ ++saved; + } + if (saveStat.savedPoiChunk()) { + ++savedPoi; ++ ++saved; + } + } + } catch (final Throwable thr) { + LOGGER.error("Failed to save chunk (" + holder.chunkX + "," + holder.chunkZ + ") in world '" + WorldUtil.getWorldName(this.world) + "'", thr); + } +- if (needsFlush && (saved % flushInterval) == 0) { +- needsFlush = false; +- RegionFileIOThread.partialFlush(flushInterval / 2); ++ if (flush && (saved - lastFlush) > (flushInterval / 2)) { ++ lastFlush = saved; ++ MoonriseRegionFileIO.partialFlush(this.world, flushInterval / 2); + } + if (logProgress) { + final long currTime = System.nanoTime(); + if ((currTime - lastLog) > TimeUnit.SECONDS.toNanos(10L)) { + lastLog = currTime; +- LOGGER.info("Saved " + saved + " chunks (" + format.format((double)(i+1)/(double)len * 100.0) + "%) in world '" + WorldUtil.getWorldName(this.world) + "'"); ++ LOGGER.info( ++ "Saved " + savedChunk + " block chunks, " + savedEntity + " entity chunks, " + savedPoi ++ + " poi chunks in world '" + WorldUtil.getWorldName(this.world) + "', progress: " ++ + format.format((double)(i+1)/(double)len * 100.0) ++ ); + } + } + } + if (flush) { +- RegionFileIOThread.flush(); ++ MoonriseRegionFileIO.flush(this.world); + try { +- RegionFileIOThread.flushRegionStorages(this.world); ++ MoonriseRegionFileIO.flushRegionStorages(this.world); + } catch (final IOException ex) { + LOGGER.error("Exception when flushing regions in world '" + WorldUtil.getWorldName(this.world) + "'", ex); + } + } + if (logProgress) { +- LOGGER.info("Saved " + savedChunk + " block chunks, " + savedEntity + " entity chunks, " + savedPoi + " poi chunks in world '" + WorldUtil.getWorldName(this.world) + "' in " + format.format(1.0E-9 * (System.nanoTime() - start)) + "s"); ++ LOGGER.info( ++ "Saved " + savedChunk + " block chunks, " + savedEntity + " entity chunks, " + savedPoi ++ + " poi chunks in world '" + WorldUtil.getWorldName(this.world) + "' in " ++ + format.format(1.0E-9 * (System.nanoTime() - start)) + "s" ++ ); + } + } + +@@ -798,21 +818,21 @@ public final class ChunkHolderManager { + return this.chunkHolders.get(position); + } + +- public void raisePriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { ++ public void raisePriority(final int x, final int z, final Priority priority) { + final NewChunkHolder chunkHolder = this.getChunkHolder(x, z); + if (chunkHolder != null) { + chunkHolder.raisePriority(priority); + } + } + +- public void setPriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { ++ public void setPriority(final int x, final int z, final Priority priority) { + final NewChunkHolder chunkHolder = this.getChunkHolder(x, z); + if (chunkHolder != null) { + chunkHolder.setPriority(priority); + } + } + +- public void lowerPriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(final int x, final int z, final Priority priority) { + final NewChunkHolder chunkHolder = this.getChunkHolder(x, z); + if (chunkHolder != null) { + chunkHolder.lowerPriority(priority); +@@ -895,7 +915,7 @@ public final class ChunkHolderManager { + final ChunkLoadTask.EntityDataLoadTask entityLoad = current.getEntityDataLoadTask(); + + if (entityLoad != null) { +- entityLoad.raisePriority(PrioritisedExecutor.Priority.BLOCKING); ++ entityLoad.raisePriority(Priority.BLOCKING); + } + } + } +@@ -971,7 +991,7 @@ public final class ChunkHolderManager { + final ChunkLoadTask.PoiDataLoadTask poiLoad = current.getPoiDataLoadTask(); + + if (poiLoad != null) { +- poiLoad.raisePriority(PrioritisedExecutor.Priority.BLOCKING); ++ poiLoad.raisePriority(Priority.BLOCKING); + } + } + } finally { +@@ -1018,7 +1038,7 @@ public final class ChunkHolderManager { + } + + ChunkHolderManager.this.processPendingFullUpdate(); +- }, PrioritisedExecutor.Priority.HIGHEST); ++ }, Priority.HIGHEST); + } else { + final ArrayDeque pendingFullLoadUpdate = this.pendingFullLoadUpdate; + for (int i = 0, len = changedFullStatus.size(); i < len; ++i) { +@@ -1028,11 +1048,10 @@ public final class ChunkHolderManager { + } + + private void removeChunkHolder(final NewChunkHolder holder) { +- holder.markUnloaded(); ++ holder.onUnload(); + this.autoSaveQueue.remove(holder); + ChunkSystem.onChunkHolderDelete(this.world, holder.vanillaChunkHolder); + this.chunkHolders.remove(CoordinateUtils.getChunkKey(holder.chunkX, holder.chunkZ)); +- + } + + // note: never call while inside the chunk system, this will absolutely break everything +@@ -1313,6 +1332,9 @@ public final class ChunkHolderManager { + if (BLOCK_TICKET_UPDATES.get() == Boolean.TRUE) { + throw new IllegalStateException("Cannot update ticket level while unloading chunks or updating entity manager"); + } ++ if (!PlatformHooks.get().allowAsyncTicketUpdates() && !TickThread.isTickThread()) { ++ TickThread.ensureTickThread("Cannot asynchronously process ticket updates"); ++ } + + List changedFullStatus = null; + +@@ -1328,10 +1350,15 @@ public final class ChunkHolderManager { + } + changedFullStatus = new ArrayList<>(); + +- ret |= this.ticketLevelPropagator.performUpdates( +- this.ticketLockArea, this.taskScheduler.schedulingLockArea, +- scheduledTasks, changedFullStatus +- ); ++ this.blockTicketUpdates(); ++ try { ++ ret |= this.ticketLevelPropagator.performUpdates( ++ this.ticketLockArea, this.taskScheduler.schedulingLockArea, ++ scheduledTasks, changedFullStatus ++ ); ++ } finally { ++ this.unblockTicketUpdates(Boolean.FALSE); ++ } + } + + if (changedFullStatus != null) { +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java +index 8671a90e969d16c7a57ddc38fedb7cf01815f64c..120ce31729dc8d4bba0901ca06d3212f3158d089 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java +@@ -1,16 +1,17 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool; +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadedTaskQueue; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.queue.PrioritisedTaskQueue; ++import ca.spottedleaf.concurrentutil.executor.thread.PrioritisedThreadPool; + import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; + import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.config.moonrise.MoonriseConfig; + import ca.spottedleaf.moonrise.common.util.CoordinateUtils; + import ca.spottedleaf.moonrise.common.util.JsonUtil; + import ca.spottedleaf.moonrise.common.util.MoonriseCommon; + import ca.spottedleaf.moonrise.common.util.TickThread; + import ca.spottedleaf.moonrise.common.util.WorldUtil; +-import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; + import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; + import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkStatus; + import ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer; +@@ -23,7 +24,6 @@ import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkUpgrade + import ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer; + import ca.spottedleaf.moonrise.patches.chunk_system.status.ChunkSystemChunkStep; + import ca.spottedleaf.moonrise.patches.chunk_system.util.ParallelSearchRadiusIteration; +-import com.mojang.logging.LogUtils; + import com.google.gson.JsonArray; + import com.google.gson.JsonObject; + import net.minecraft.CrashReport; +@@ -48,6 +48,7 @@ import net.minecraft.world.level.chunk.status.ChunkStatus; + import net.minecraft.world.level.chunk.status.ChunkStep; + import net.minecraft.world.phys.Vec3; + import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; + import java.io.File; + import java.time.LocalDateTime; + import java.time.format.DateTimeFormatter; +@@ -63,51 +64,14 @@ import java.util.function.Consumer; + + public final class ChunkTaskScheduler { + +- private static final Logger LOGGER = LogUtils.getClassLogger(); ++ private static final Logger LOGGER = LoggerFactory.getLogger(ChunkTaskScheduler.class); + +- static int newChunkSystemIOThreads; +- static int newChunkSystemGenParallelism; +- static int newChunkSystemGenPopulationParallelism; +- static int newChunkSystemLoadParallelism; +- +- private static boolean initialised = false; +- +- public static void init(io.papermc.paper.configuration.GlobalConfiguration.ChunkSystem chunkSystem) { +- if (initialised) { +- return; +- } +- initialised = true; +- MoonriseCommon.init(chunkSystem); // Paper +- newChunkSystemIOThreads = chunkSystem.ioThreads; +- if (newChunkSystemIOThreads <= 0) { +- newChunkSystemIOThreads = 1; +- } else { +- newChunkSystemIOThreads = Math.max(1, newChunkSystemIOThreads); +- } +- +- String newChunkSystemGenParallelism = chunkSystem.genParallelism; +- if (newChunkSystemGenParallelism.equalsIgnoreCase("default")) { +- newChunkSystemGenParallelism = "true"; +- } +- +- boolean useParallelGen; +- if (newChunkSystemGenParallelism.equalsIgnoreCase("on") || newChunkSystemGenParallelism.equalsIgnoreCase("enabled") +- || newChunkSystemGenParallelism.equalsIgnoreCase("true")) { +- useParallelGen = true; +- } else if (newChunkSystemGenParallelism.equalsIgnoreCase("off") || newChunkSystemGenParallelism.equalsIgnoreCase("disabled") +- || newChunkSystemGenParallelism.equalsIgnoreCase("false")) { +- useParallelGen = false; +- } else { +- throw new IllegalStateException("Invalid option for gen-parallelism: must be one of [on, off, enabled, disabled, true, false, default]"); ++ public static void init(final boolean useParallelGen) { ++ for (final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor executor : MoonriseCommon.RADIUS_AWARE_GROUP.getAllExecutors()) { ++ executor.setMaxParallelism(useParallelGen ? -1 : 1); + } + +- ChunkTaskScheduler.newChunkSystemGenParallelism = MoonriseCommon.WORKER_THREADS; +- ChunkTaskScheduler.newChunkSystemGenPopulationParallelism = useParallelGen ? MoonriseCommon.WORKER_THREADS : 1; +- ChunkTaskScheduler.newChunkSystemLoadParallelism = MoonriseCommon.WORKER_THREADS; +- +- RegionFileIOThread.init(newChunkSystemIOThreads); +- +- LOGGER.info("Chunk system is using " + newChunkSystemIOThreads + " I/O threads, " + MoonriseCommon.WORKER_THREADS + " worker threads, and population gen parallelism of " + ChunkTaskScheduler.newChunkSystemGenPopulationParallelism + " threads"); ++ LOGGER.info("Chunk system is using population gen parallelism: " + useParallelGen); + } + + public static final TicketType CHUNK_LOAD = TicketType.create("chunk_system:chunk_load", Long::compareTo); +@@ -151,13 +115,15 @@ public final class ChunkTaskScheduler { + } + + public final ServerLevel world; +- public final PrioritisedThreadPool workers; + public final RadiusAwarePrioritisedExecutor radiusAwareScheduler; +- public final PrioritisedThreadPool.PrioritisedPoolExecutor parallelGenExecutor; +- private final PrioritisedThreadPool.PrioritisedPoolExecutor radiusAwareGenExecutor; +- public final PrioritisedThreadPool.PrioritisedPoolExecutor loadExecutor; ++ public final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor parallelGenExecutor; ++ private final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor radiusAwareGenExecutor; ++ public final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor loadExecutor; ++ public final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor ioExecutor; ++ public final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor compressionExecutor; ++ public final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor saveExecutor; + +- private final PrioritisedThreadedTaskQueue mainThreadExecutor = new PrioritisedThreadedTaskQueue(); ++ private final PrioritisedTaskQueue mainThreadExecutor = new PrioritisedTaskQueue(); + + public final ChunkHolderManager chunkHolderManager; + +@@ -306,9 +272,8 @@ public final class ChunkTaskScheduler { + return this.lockShift; + } + +- public ChunkTaskScheduler(final ServerLevel world, final PrioritisedThreadPool workers) { ++ public ChunkTaskScheduler(final ServerLevel world) { + this.world = world; +- this.workers = workers; + // must be >= region shift (in paper, doesn't exist) and must be >= ticket propagator section shift + // it must be >= region shift since the regioniser assumes ticket updates do not occur in parallel for the region sections + // it must be >= ticket propagator section shift so that the ticket propagator can assume that owning a position implies owning +@@ -317,11 +282,14 @@ public final class ChunkTaskScheduler { + this.lockShift = Math.max(((ChunkSystemServerLevel)world).moonrise$getRegionChunkShift(), ThreadedTicketLevelPropagator.SECTION_SHIFT); + this.schedulingLockArea = new ReentrantAreaLock(this.getChunkSystemLockShift()); + +- final String worldName = WorldUtil.getWorldName(world); +- this.parallelGenExecutor = workers.createExecutor("Chunk parallel generation executor for world '" + worldName + "'", 1, Math.max(1, newChunkSystemGenParallelism)); +- this.radiusAwareGenExecutor = workers.createExecutor("Chunk radius aware generator for world '" + worldName + "'", 1, Math.max(1, newChunkSystemGenPopulationParallelism)); +- this.loadExecutor = workers.createExecutor("Chunk load executor for world '" + worldName + "'", 1, newChunkSystemLoadParallelism); +- this.radiusAwareScheduler = new RadiusAwarePrioritisedExecutor(this.radiusAwareGenExecutor, Math.max(2, 1 + newChunkSystemGenPopulationParallelism)); ++ this.parallelGenExecutor = MoonriseCommon.PARALLEL_GEN_GROUP.createExecutor(-1, MoonriseCommon.WORKER_QUEUE_HOLD_TIME, 0); ++ this.radiusAwareGenExecutor = MoonriseCommon.RADIUS_AWARE_GROUP.createExecutor(1, MoonriseCommon.WORKER_QUEUE_HOLD_TIME, 0); ++ this.loadExecutor = MoonriseCommon.LOAD_GROUP.createExecutor(-1, MoonriseCommon.WORKER_QUEUE_HOLD_TIME, 0); ++ this.radiusAwareScheduler = new RadiusAwarePrioritisedExecutor(this.radiusAwareGenExecutor, 16); ++ this.ioExecutor = MoonriseCommon.SERVER_REGION_IO_GROUP.createExecutor(-1, MoonriseCommon.IO_QUEUE_HOLD_TIME, 0); ++ // we need a separate executor here so that on shutdown we can continue to process I/O tasks ++ this.compressionExecutor = MoonriseCommon.LOAD_GROUP.createExecutor(-1, MoonriseCommon.WORKER_QUEUE_HOLD_TIME, 0); ++ this.saveExecutor = MoonriseCommon.LOAD_GROUP.createExecutor(-1, MoonriseCommon.WORKER_QUEUE_HOLD_TIME, 0); + this.chunkHolderManager = new ChunkHolderManager(world, this); + } + +@@ -360,7 +328,7 @@ public final class ChunkTaskScheduler { + }; + + // this may not be good enough, specifically thanks to stupid ass plugins swallowing exceptions +- this.scheduleChunkTask(chunkX, chunkZ, crash, PrioritisedExecutor.Priority.BLOCKING); ++ this.scheduleChunkTask(chunkX, chunkZ, crash, Priority.BLOCKING); + // so, make the main thread pick it up + ((ChunkSystemMinecraftServer)this.world.getServer()).moonrise$setChunkSystemCrash(new RuntimeException("Chunk system crash propagated from unrecoverableChunkSystemFailure", reportedException)); + } +@@ -370,20 +338,20 @@ public final class ChunkTaskScheduler { + return this.mainThreadExecutor.executeTask(); + } + +- public void raisePriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { ++ public void raisePriority(final int x, final int z, final Priority priority) { + this.chunkHolderManager.raisePriority(x, z, priority); + } + +- public void setPriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { ++ public void setPriority(final int x, final int z, final Priority priority) { + this.chunkHolderManager.setPriority(x, z, priority); + } + +- public void lowerPriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(final int x, final int z, final Priority priority) { + this.chunkHolderManager.lowerPriority(x, z, priority); + } + + public void scheduleTickingState(final int chunkX, final int chunkZ, final FullChunkStatus toStatus, +- final boolean addTicket, final PrioritisedExecutor.Priority priority, ++ final boolean addTicket, final Priority priority, + final Consumer onComplete) { + final int radius = toStatus.ordinal() - 1; // 0 -> BORDER, 1 -> TICKING, 2 -> ENTITY_TICKING + +@@ -479,7 +447,7 @@ public final class ChunkTaskScheduler { + } + + public void scheduleChunkLoad(final int chunkX, final int chunkZ, final boolean gen, final ChunkStatus toStatus, final boolean addTicket, +- final PrioritisedExecutor.Priority priority, final Consumer onComplete) { ++ final Priority priority, final Consumer onComplete) { + if (gen) { + this.scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); + return; +@@ -503,7 +471,7 @@ public final class ChunkTaskScheduler { + + // only appropriate to use with syncLoadNonFull + public boolean beginChunkLoadForNonFullSync(final int chunkX, final int chunkZ, final ChunkStatus toStatus, +- final PrioritisedExecutor.Priority priority) { ++ final Priority priority) { + final int accessRadius = getAccessRadius(toStatus); + final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); + final int minLevel = ChunkTaskScheduler.getTicketLevel(toStatus); +@@ -548,6 +516,11 @@ public final class ChunkTaskScheduler { + if (status == null || status.isOrAfter(ChunkStatus.FULL)) { + throw new IllegalArgumentException("Status: " + status); + } ++ ++ if (!TickThread.isTickThread()) { ++ return this.world.getChunkSource().getChunk(chunkX, chunkZ, status, true); ++ } ++ + ChunkAccess loaded = ((ChunkSystemServerLevel)this.world).moonrise$getSpecificChunkIfLoaded(chunkX, chunkZ, status); + if (loaded != null) { + return loaded; +@@ -558,7 +531,7 @@ public final class ChunkTaskScheduler { + this.chunkHolderManager.addTicketAtLevel(NON_FULL_CHUNK_LOAD, chunkX, chunkZ, ticketLevel, ticketId); + this.chunkHolderManager.processTicketUpdates(); + +- this.beginChunkLoadForNonFullSync(chunkX, chunkZ, status, PrioritisedExecutor.Priority.BLOCKING); ++ this.beginChunkLoadForNonFullSync(chunkX, chunkZ, status, Priority.BLOCKING); + + // we could do a simple spinwait here, since we do not need to process tasks while performing this load + // but we process tasks only because it's a better use of the time spent +@@ -578,7 +551,7 @@ public final class ChunkTaskScheduler { + } + + public void scheduleChunkLoad(final int chunkX, final int chunkZ, final ChunkStatus toStatus, final boolean addTicket, +- final PrioritisedExecutor.Priority priority, final Consumer onComplete) { ++ final Priority priority, final Consumer onComplete) { + if (!TickThread.isTickThreadFor(this.world, chunkX, chunkZ)) { + this.scheduleChunkTask(chunkX, chunkZ, () -> { + ChunkTaskScheduler.this.scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); +@@ -670,7 +643,7 @@ public final class ChunkTaskScheduler { + + private ChunkProgressionTask createTask(final int chunkX, final int chunkZ, final ChunkAccess chunk, + final NewChunkHolder chunkHolder, final StaticCache2D neighbours, +- final ChunkStatus toStatus, final PrioritisedExecutor.Priority initialPriority) { ++ final ChunkStatus toStatus, final Priority initialPriority) { + if (toStatus == ChunkStatus.EMPTY) { + return new ChunkLoadTask(this, this.world, chunkX, chunkZ, chunkHolder, initialPriority); + } +@@ -686,7 +659,7 @@ public final class ChunkTaskScheduler { + + ChunkProgressionTask schedule(final int chunkX, final int chunkZ, final ChunkStatus targetStatus, final NewChunkHolder chunkHolder, + final List allTasks) { +- return this.schedule(chunkX, chunkZ, targetStatus, chunkHolder, allTasks, chunkHolder.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL)); ++ return this.schedule(chunkX, chunkZ, targetStatus, chunkHolder, allTasks, chunkHolder.getEffectivePriority(Priority.NORMAL)); + } + + // rets new task scheduled for the _specified_ chunk +@@ -695,7 +668,7 @@ public final class ChunkTaskScheduler { + // schedule will ignore the generation target, so it should be checked by the caller to ensure the target is not regressed! + private ChunkProgressionTask schedule(final int chunkX, final int chunkZ, final ChunkStatus targetStatus, + final NewChunkHolder chunkHolder, final List allTasks, +- final PrioritisedExecutor.Priority minPriority) { ++ final Priority minPriority) { + if (!this.schedulingLockArea.isHeldByCurrentThread(chunkX, chunkZ, getAccessRadius(targetStatus))) { + throw new IllegalStateException("Not holding scheduling lock"); + } +@@ -705,8 +678,8 @@ public final class ChunkTaskScheduler { + return null; + } + +- final PrioritisedExecutor.Priority requestedPriority = PrioritisedExecutor.Priority.max( +- minPriority, chunkHolder.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) ++ final Priority requestedPriority = Priority.max( ++ minPriority, chunkHolder.getEffectivePriority(Priority.NORMAL) + ); + final ChunkStatus currentGenStatus = chunkHolder.getCurrentGenStatus(); + final ChunkAccess chunk = chunkHolder.getCurrentChunk(); +@@ -743,7 +716,7 @@ public final class ChunkTaskScheduler { + + final int neighbourReadRadius = Math.max( + 0, +- chunkPyramid.getStepTo(toStatus).getAccumulatedRadiusOf(ChunkStatus.EMPTY) ++ chunkStep.getAccumulatedRadiusOf(ChunkStatus.EMPTY) + ); + + boolean unGeneratedNeighbours = false; +@@ -783,7 +756,7 @@ public final class ChunkTaskScheduler { + + final ChunkProgressionTask task = this.createTask( + chunkX, chunkZ, chunk, chunkHolder, neighbours, toStatus, +- chunkHolder.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) ++ chunkHolder.getEffectivePriority(Priority.NORMAL) + ); + allTasks.add(task); + +@@ -794,7 +767,7 @@ public final class ChunkTaskScheduler { + + // rets true if the neighbour is not at the required status, false otherwise + private boolean checkNeighbour(final int chunkX, final int chunkZ, final ChunkStatus requiredStatus, final NewChunkHolder center, +- final List tasks, final PrioritisedExecutor.Priority minPriority) { ++ final List tasks, final Priority minPriority) { + final NewChunkHolder chunkHolder = this.chunkHolderManager.getChunkHolder(chunkX, chunkZ); + + if (chunkHolder == null) { +@@ -830,41 +803,41 @@ public final class ChunkTaskScheduler { + */ + @Deprecated + public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final Runnable run) { +- return this.scheduleChunkTask(run, PrioritisedExecutor.Priority.NORMAL); ++ return this.scheduleChunkTask(run, Priority.NORMAL); + } + + /** + * @deprecated Chunk tasks must be tied to coordinates in the future + */ + @Deprecated +- public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final Runnable run, final PrioritisedExecutor.Priority priority) { +- return this.mainThreadExecutor.queueRunnable(run, priority); ++ public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final Runnable run, final Priority priority) { ++ return this.mainThreadExecutor.queueTask(run, priority); + } + + public PrioritisedExecutor.PrioritisedTask createChunkTask(final int chunkX, final int chunkZ, final Runnable run) { +- return this.createChunkTask(chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); ++ return this.createChunkTask(chunkX, chunkZ, run, Priority.NORMAL); + } + + public PrioritisedExecutor.PrioritisedTask createChunkTask(final int chunkX, final int chunkZ, final Runnable run, +- final PrioritisedExecutor.Priority priority) { ++ final Priority priority) { + return this.mainThreadExecutor.createTask(run, priority); + } + + public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final int chunkX, final int chunkZ, final Runnable run) { +- return this.scheduleChunkTask(chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); ++ return this.scheduleChunkTask(chunkX, chunkZ, run, Priority.NORMAL); + } + + public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final int chunkX, final int chunkZ, final Runnable run, +- final PrioritisedExecutor.Priority priority) { +- return this.mainThreadExecutor.queueRunnable(run, priority); ++ final Priority priority) { ++ return this.mainThreadExecutor.queueTask(run, priority); + } + + public boolean halt(final boolean sync, final long maxWaitNS) { + this.radiusAwareGenExecutor.halt(); + this.parallelGenExecutor.halt(); + this.loadExecutor.halt(); +- final long time = System.nanoTime(); + if (sync) { ++ final long time = System.nanoTime(); + for (long failures = 9L;; failures = ConcurrentUtil.linearLongBackoff(failures, 500_000L, 50_000_000L)) { + if ( + !this.radiusAwareGenExecutor.isActive() && +@@ -882,6 +855,29 @@ public final class ChunkTaskScheduler { + return true; + } + ++ public boolean haltIO(final boolean sync, final long maxWaitNS) { ++ this.ioExecutor.halt(); ++ this.saveExecutor.halt(); ++ this.compressionExecutor.halt(); ++ if (sync) { ++ final long time = System.nanoTime(); ++ for (long failures = 9L;; failures = ConcurrentUtil.linearLongBackoff(failures, 500_000L, 50_000_000L)) { ++ if ( ++ !this.ioExecutor.isActive() && ++ !this.saveExecutor.isActive() && ++ !this.compressionExecutor.isActive() ++ ) { ++ return true; ++ } ++ if ((System.nanoTime() - time) >= maxWaitNS) { ++ return false; ++ } ++ } ++ } ++ ++ return true; ++ } ++ + public static final ArrayDeque WAITING_CHUNKS = new ArrayDeque<>(); // stack + + public static final class ChunkInfo { +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java +index 45eda96fd8a1acb87dbb69ce5495fec7e451416f..381631e405895ba3eede1cd2e1011c64aadbd662 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java +@@ -1,18 +1,20 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; + +-import ca.spottedleaf.concurrentutil.completable.Completable; ++import ca.spottedleaf.concurrentutil.completable.CallbackCompletable; + import ca.spottedleaf.concurrentutil.executor.Cancellable; +-import ca.spottedleaf.concurrentutil.executor.standard.DelayedPrioritisedTask; +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; + import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; + import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.PlatformHooks; ++import ca.spottedleaf.moonrise.common.misc.LazyRunnable; + import ca.spottedleaf.moonrise.common.util.CoordinateUtils; + import ca.spottedleaf.moonrise.common.util.TickThread; + import ca.spottedleaf.moonrise.common.util.WorldUtil; + import ca.spottedleaf.moonrise.common.util.ChunkSystem; +-import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystemFeatures; +-import ca.spottedleaf.moonrise.patches.chunk_system.async_save.AsyncChunkSaveData; +-import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel; + import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; + import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkHolder; + import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkStatus; +@@ -36,13 +38,14 @@ import net.minecraft.server.level.ChunkHolder; + import net.minecraft.server.level.ChunkLevel; + import net.minecraft.server.level.FullChunkStatus; + import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.progress.ChunkProgressListener; + 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.ImposterProtoChunk; + import net.minecraft.world.level.chunk.LevelChunk; + import net.minecraft.world.level.chunk.status.ChunkStatus; +-import net.minecraft.world.level.chunk.storage.ChunkSerializer; ++import net.minecraft.world.level.chunk.storage.SerializableChunkData; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + import java.lang.invoke.VarHandle; +@@ -58,6 +61,8 @@ public final class NewChunkHolder { + + private static final Logger LOGGER = LoggerFactory.getLogger(NewChunkHolder.class); + ++ public final ChunkData holderData; ++ + public final ServerLevel world; + public final int chunkX; + public final int chunkZ; +@@ -89,7 +94,7 @@ public final class NewChunkHolder { + if (this.entityChunk == null) { + ret = this.entityChunk = new ChunkEntitySlices( + this.world, this.chunkX, this.chunkZ, this.getChunkStatus(), +- WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) ++ this.holderData, WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) + ); + + ret.setTransient(transientChunk); +@@ -173,7 +178,7 @@ public final class NewChunkHolder { + // no tasks to schedule _for_ + } else { + entityDataLoadTask = this.entityDataLoadTask = new ChunkLoadTask.EntityDataLoadTask( +- this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) ++ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(Priority.NORMAL) + ); + entityDataLoadTask.addCallback(this::completeEntityLoad); + // need one schedule() per waiter +@@ -220,7 +225,7 @@ public final class NewChunkHolder { + + if (this.entityDataLoadTask == null) { + this.entityDataLoadTask = new ChunkLoadTask.EntityDataLoadTask( +- this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) ++ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(Priority.NORMAL) + ); + this.entityDataLoadTask.addCallback(this::completeEntityLoad); + this.entityDataLoadTaskWaiters = new ArrayList<>(); +@@ -294,7 +299,7 @@ public final class NewChunkHolder { + // no tasks to schedule _for_ + } else { + poiDataLoadTask = this.poiDataLoadTask = new ChunkLoadTask.PoiDataLoadTask( +- this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) ++ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(Priority.NORMAL) + ); + poiDataLoadTask.addCallback(this::completePoiLoad); + // need one schedule() per waiter +@@ -340,7 +345,7 @@ public final class NewChunkHolder { + + if (this.poiDataLoadTask == null) { + this.poiDataLoadTask = new ChunkLoadTask.PoiDataLoadTask( +- this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) ++ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(Priority.NORMAL) + ); + this.poiDataLoadTask.addCallback(this::completePoiLoad); + this.poiDataLoadTaskWaiters = new ArrayList<>(); +@@ -519,15 +524,15 @@ public final class NewChunkHolder { + // priority state + + // the target priority for this chunk to generate at +- private PrioritisedExecutor.Priority priority = null; ++ private Priority priority = null; + private boolean priorityLocked; + + // the priority neighbouring chunks have requested this chunk generate at +- private PrioritisedExecutor.Priority neighbourRequestedPriority = null; ++ private Priority neighbourRequestedPriority = null; + +- public PrioritisedExecutor.Priority getEffectivePriority(final PrioritisedExecutor.Priority dfl) { +- final PrioritisedExecutor.Priority neighbour = this.neighbourRequestedPriority; +- final PrioritisedExecutor.Priority us = this.priority; ++ public Priority getEffectivePriority(final Priority dfl) { ++ final Priority neighbour = this.neighbourRequestedPriority; ++ final Priority us = this.priority; + + if (neighbour == null) { + return us == null ? dfl : us; +@@ -536,7 +541,7 @@ public final class NewChunkHolder { + return neighbour; + } + +- return PrioritisedExecutor.Priority.max(us, neighbour); ++ return Priority.max(us, neighbour); + } + + private void recalculateNeighbourRequestedPriority() { +@@ -545,18 +550,18 @@ public final class NewChunkHolder { + return; + } + +- PrioritisedExecutor.Priority max = null; ++ Priority max = null; + + for (final NewChunkHolder holder : this.neighboursWaitingForUs.keySet()) { +- final PrioritisedExecutor.Priority neighbourPriority = holder.getEffectivePriority(null); ++ final Priority neighbourPriority = holder.getEffectivePriority(null); + if (neighbourPriority != null && (max == null || neighbourPriority.isHigherPriority(max))) { + max = neighbourPriority; + } + } + +- final PrioritisedExecutor.Priority current = this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL); ++ final Priority current = this.getEffectivePriority(Priority.NORMAL); + this.neighbourRequestedPriority = max; +- final PrioritisedExecutor.Priority next = this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL); ++ final Priority next = this.getEffectivePriority(Priority.NORMAL); + + if (current == next) { + return; +@@ -578,7 +583,7 @@ public final class NewChunkHolder { + } + + // must hold scheduling lock +- public void raisePriority(final PrioritisedExecutor.Priority priority) { ++ public void raisePriority(final Priority priority) { + if (this.priority != null && this.priority.isHigherOrEqualPriority(priority)) { + return; + } +@@ -591,13 +596,13 @@ public final class NewChunkHolder { + } + + // must hold scheduling lock +- public void setPriority(final PrioritisedExecutor.Priority priority) { ++ public void setPriority(final Priority priority) { + if (this.priorityLocked) { + return; + } +- final PrioritisedExecutor.Priority old = this.getEffectivePriority(null); ++ final Priority old = this.getEffectivePriority(null); + this.priority = priority; +- final PrioritisedExecutor.Priority newPriority = this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL); ++ final Priority newPriority = this.getEffectivePriority(Priority.NORMAL); + + if (old != newPriority) { + if (this.generationTask != null) { +@@ -609,7 +614,7 @@ public final class NewChunkHolder { + } + + // must hold scheduling lock +- public void lowerPriority(final PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(final Priority priority) { + if (this.priority != null && this.priority.isLowerOrEqualPriority(priority)) { + return; + } +@@ -632,7 +637,7 @@ public final class NewChunkHolder { + } + + // ticket level state +- public int oldTicketLevel = ChunkHolderManager.MAX_TICKET_LEVEL + 1; ++ private int oldTicketLevel = ChunkHolderManager.MAX_TICKET_LEVEL + 1; + private int currentTicketLevel = ChunkHolderManager.MAX_TICKET_LEVEL + 1; + + public int getTicketLevel() { +@@ -651,6 +656,7 @@ public final class NewChunkHolder { + world.getLightEngine(), null, world.getChunkSource().chunkMap + ); + ((ChunkSystemChunkHolder)this.vanillaChunkHolder).moonrise$setRealChunkHolder(this); ++ this.holderData = ((ChunkSystemLevel)this.world).moonrise$requestChunkData(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + } + + public ChunkAccess getCurrentChunk() { +@@ -750,8 +756,9 @@ public final class NewChunkHolder { + /** Unloaded from chunk map */ + private boolean unloaded; + +- void markUnloaded() { ++ void onUnload() { + this.unloaded = true; ++ ((ChunkSystemLevel)this.world).moonrise$releaseChunkData(CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ)); + } + + private boolean inUnloadQueue = false; +@@ -788,9 +795,10 @@ public final class NewChunkHolder { + private UnloadTask entityDataUnload; + private UnloadTask poiDataUnload; + +- public static final record UnloadTask(Completable completable, DelayedPrioritisedTask task) {} ++ public static final record UnloadTask(CallbackCompletable completable, PrioritisedExecutor.PrioritisedTask task, ++ LazyRunnable toRun) {} + +- public UnloadTask getUnloadTask(final RegionFileIOThread.RegionFileType type) { ++ public UnloadTask getUnloadTask(final MoonriseRegionFileIO.RegionFileType type) { + switch (type) { + case CHUNK_DATA: + return this.chunkDataUnload; +@@ -803,7 +811,7 @@ public final class NewChunkHolder { + } + } + +- private void removeUnloadTask(final RegionFileIOThread.RegionFileType type) { ++ private void removeUnloadTask(final MoonriseRegionFileIO.RegionFileType type) { + switch (type) { + case CHUNK_DATA: { + this.chunkDataUnload = null; +@@ -836,10 +844,10 @@ public final class NewChunkHolder { + // chunk state + this.currentChunk = null; + this.currentGenStatus = null; +- this.lastChunkCompletion = null; + for (int i = 0; i < this.chunkCompletions.length; ++i) { +- CHUNK_COMPLETION_ARRAY_HANDLE.setVolatile(this.chunkCompletions, i, (ChunkCompletion)null); ++ CHUNK_COMPLETION_ARRAY_HANDLE.setRelease(this.chunkCompletions, i, (ChunkCompletion)null); + } ++ this.lastChunkCompletion = null; + // entity chunk state + this.entityChunk = null; + this.pendingEntityChunk = null; +@@ -851,22 +859,23 @@ public final class NewChunkHolder { + this.priorityLocked = false; + + if (chunk != null) { +- this.chunkDataUnload = new UnloadTask(new Completable<>(), new DelayedPrioritisedTask(PrioritisedExecutor.Priority.NORMAL)); ++ final LazyRunnable toRun = new LazyRunnable(); ++ this.chunkDataUnload = new UnloadTask(new CallbackCompletable<>(), this.scheduler.saveExecutor.createTask(toRun), toRun); + } + if (poiChunk != null) { +- this.poiDataUnload = new UnloadTask(new Completable<>(), null); ++ this.poiDataUnload = new UnloadTask(new CallbackCompletable<>(), null, null); + } + if (entityChunk != null) { +- this.entityDataUnload = new UnloadTask(new Completable<>(), null); ++ this.entityDataUnload = new UnloadTask(new CallbackCompletable<>(), null, null); + } + + return this.unloadState = (chunk != null || entityChunk != null || poiChunk != null) ? new UnloadState(this, chunk, entityChunk, poiChunk) : null; + } + + // data is null if failed or does not need to be saved +- void completeAsyncUnloadDataSave(final RegionFileIOThread.RegionFileType type, final CompoundTag data) { ++ void completeAsyncUnloadDataSave(final MoonriseRegionFileIO.RegionFileType type, final CompoundTag data) { + if (data != null) { +- RegionFileIOThread.scheduleSave(this.world, this.chunkX, this.chunkZ, data, type); ++ MoonriseRegionFileIO.scheduleSave(this.world, this.chunkX, this.chunkZ, data, type); + } + + this.getUnloadTask(type).completable().complete(data); +@@ -886,18 +895,19 @@ public final class NewChunkHolder { + final ChunkEntitySlices entityChunk = state.entityChunk(); + final PoiChunk poiChunk = state.poiChunk(); + +- final boolean shouldLevelChunkNotSave = ChunkSystemFeatures.forceNoSave(chunk); ++ final boolean shouldLevelChunkNotSave = PlatformHooks.get().forceNoSave(chunk); + + // unload chunk data + if (chunk != null) { + if (chunk instanceof LevelChunk levelChunk) { + levelChunk.setLoaded(false); ++ PlatformHooks.get().chunkUnloadFromWorld(levelChunk); + } + + if (!shouldLevelChunkNotSave) { + this.saveChunk(chunk, true); + } else { +- this.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, null); ++ this.completeAsyncUnloadDataSave(MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, null); + } + + if (chunk instanceof LevelChunk levelChunk) { +@@ -1066,6 +1076,9 @@ public final class NewChunkHolder { + if (oldUnloaded != newUnloaded) { + this.checkUnload(); + } ++ ++ // Don't really have a choice but to place this hook here ++ PlatformHooks.get().onChunkHolderTicketChange(this.world, this, oldLevel, newLevel); + } + + static final int NEIGHBOUR_RADIUS = 2; +@@ -1111,24 +1124,6 @@ public final class NewChunkHolder { + private static final long CHUNK_LOADED_MASK_RAD1 = getLoadedMask(1); + private static final long CHUNK_LOADED_MASK_RAD2 = getLoadedMask(2); + +- public static boolean areNeighboursFullLoaded(final long bitset, final int radius) { +- switch (radius) { +- case 0: { +- return (bitset & CHUNK_LOADED_MASK_RAD0) == CHUNK_LOADED_MASK_RAD0; +- } +- case 1: { +- return (bitset & CHUNK_LOADED_MASK_RAD1) == CHUNK_LOADED_MASK_RAD1; +- } +- case 2: { +- return (bitset & CHUNK_LOADED_MASK_RAD2) == CHUNK_LOADED_MASK_RAD2; +- } +- +- default: { +- throw new IllegalArgumentException("Radius not recognized: " + radius); +- } +- } +- } +- + // only updated while holding scheduling lock + private FullChunkStatus pendingFullChunkStatus = FullChunkStatus.INACCESSIBLE; + // updated while holding no locks, but adds a ticket before to prevent pending status from dropping +@@ -1363,6 +1358,17 @@ public final class NewChunkHolder { + } + + private void completeStatusConsumers(ChunkStatus status, final ChunkAccess chunk) { ++ // Update progress listener for LevelLoadingScreen ++ if (chunk != null) { ++ final ChunkProgressListener progressListener = this.world.getChunkSource().chunkMap.progressListener; ++ if (progressListener != null) { ++ final ChunkStatus finalStatus = status; ++ this.scheduler.scheduleChunkTask(this.chunkX, this.chunkZ, () -> { ++ progressListener.onStatusChange(this.vanillaChunkHolder.getPos(), finalStatus); ++ }); ++ } ++ } ++ + // need to tell future statuses to complete if cancelled + do { + this.completeStatusConsumers0(status, chunk); +@@ -1386,7 +1392,7 @@ public final class NewChunkHolder { + LOGGER.error("Failed to process chunk status callback", thr); + } + } +- }, PrioritisedExecutor.Priority.HIGHEST); ++ }, Priority.HIGHEST); + } + + private final Reference2ObjectOpenHashMap>> fullStatusWaiters = new Reference2ObjectOpenHashMap<>(); +@@ -1414,7 +1420,7 @@ public final class NewChunkHolder { + LOGGER.error("Failed to process chunk status callback", thr); + } + } +- }, PrioritisedExecutor.Priority.HIGHEST); ++ }, Priority.HIGHEST); + } + + // note: must hold scheduling lock +@@ -1670,6 +1676,8 @@ public final class NewChunkHolder { + + public static final record SaveStat(boolean savedChunk, boolean savedEntityChunk, boolean savedPoiChunk) {} + ++ private static final MoonriseRegionFileIO.RegionFileType[] REGION_FILE_TYPES = MoonriseRegionFileIO.RegionFileType.values(); ++ + public SaveStat save(final boolean shutdown) { + TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Cannot save data off-main"); + +@@ -1677,6 +1685,7 @@ public final class NewChunkHolder { + PoiChunk poi = this.getPoiChunk(); + ChunkEntitySlices entities = this.getEntityChunk(); + boolean executedUnloadTask = false; ++ final boolean[] executedUnloadTasks = new boolean[REGION_FILE_TYPES.length]; + + if (shutdown) { + // make sure that the async unloads complete +@@ -1686,17 +1695,22 @@ public final class NewChunkHolder { + poi = this.unloadState.poiChunk(); + entities = this.unloadState.entityChunk(); + } +- final UnloadTask chunkUnloadTask = this.chunkDataUnload; +- final DelayedPrioritisedTask chunkDataUnloadTask = chunkUnloadTask == null ? null : chunkUnloadTask.task(); +- if (chunkDataUnloadTask != null) { +- final PrioritisedExecutor.PrioritisedTask unloadTask = chunkDataUnloadTask.getTask(); +- if (unloadTask != null) { +- executedUnloadTask = unloadTask.execute(); ++ for (final MoonriseRegionFileIO.RegionFileType regionFileType : REGION_FILE_TYPES) { ++ final UnloadTask unloadTask = this.getUnloadTask(regionFileType); ++ if (unloadTask == null) { ++ continue; ++ } ++ ++ final PrioritisedExecutor.PrioritisedTask task = unloadTask.task(); ++ if (task != null && task.isQueued()) { ++ final boolean executed = task.execute(); ++ executedUnloadTask |= executed; ++ executedUnloadTasks[regionFileType.ordinal()] = executed; + } + } + } + +- final boolean forceNoSaveChunk = ChunkSystemFeatures.forceNoSave(chunk); ++ final boolean forceNoSaveChunk = PlatformHooks.get().forceNoSave(chunk); + + // can only synchronously save worldgen chunks during shutdown + boolean canSaveChunk = !forceNoSaveChunk && (chunk != null && ((shutdown || chunk instanceof LevelChunk) && chunk.isUnsaved())); +@@ -1717,106 +1731,55 @@ public final class NewChunkHolder { + } + } + +- return executedUnloadTask | canSaveChunk | canSaveEntities | canSavePOI ? new SaveStat(executedUnloadTask || canSaveChunk, canSaveEntities, canSavePOI): null; +- } +- +- static final class AsyncChunkSerializeTask implements Runnable { +- +- private final ServerLevel world; +- private final ChunkAccess chunk; +- private final AsyncChunkSaveData asyncSaveData; +- private final NewChunkHolder toComplete; +- +- public AsyncChunkSerializeTask(final ServerLevel world, final ChunkAccess chunk, final AsyncChunkSaveData asyncSaveData, +- final NewChunkHolder toComplete) { +- this.world = world; +- this.chunk = chunk; +- this.asyncSaveData = asyncSaveData; +- this.toComplete = toComplete; +- } +- +- @Override +- public void run() { +- final CompoundTag toSerialize; +- try { +- toSerialize = ChunkSystemFeatures.saveChunkAsync(this.world, this.chunk, this.asyncSaveData); +- } catch (final Throwable throwable) { +- LOGGER.error("Failed to asynchronously save chunk " + this.chunk.getPos() + " for world '" + WorldUtil.getWorldName(this.world) + "', falling back to synchronous save", throwable); +- final ChunkPos pos = this.chunk.getPos(); +- ((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().scheduleChunkTask(pos.x, pos.z, () -> { +- final CompoundTag synchronousSave; +- try { +- synchronousSave = ChunkSystemFeatures.saveChunkAsync(AsyncChunkSerializeTask.this.world, AsyncChunkSerializeTask.this.chunk, AsyncChunkSerializeTask.this.asyncSaveData); +- } catch (final Throwable throwable2) { +- LOGGER.error("Failed to synchronously save chunk " + AsyncChunkSerializeTask.this.chunk.getPos() + " for world '" + WorldUtil.getWorldName(AsyncChunkSerializeTask.this.world) + "', chunk data will be lost", throwable2); +- AsyncChunkSerializeTask.this.toComplete.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, null); +- return; +- } +- +- AsyncChunkSerializeTask.this.toComplete.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, synchronousSave); +- LOGGER.info("Successfully serialized chunk " + AsyncChunkSerializeTask.this.chunk.getPos() + " for world '" + WorldUtil.getWorldName(AsyncChunkSerializeTask.this.world) + "' synchronously"); +- +- }, PrioritisedExecutor.Priority.HIGHEST); +- return; +- } +- this.toComplete.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, toSerialize); +- } +- +- @Override +- public String toString() { +- return "AsyncChunkSerializeTask{" + +- "chunk={pos=" + this.chunk.getPos() + ",world=\"" + WorldUtil.getWorldName(this.world) + "\"}" + +- "}"; +- } ++ return executedUnloadTask | canSaveChunk | canSaveEntities | canSavePOI ? ++ new SaveStat( ++ canSaveChunk | executedUnloadTasks[MoonriseRegionFileIO.RegionFileType.CHUNK_DATA.ordinal()], ++ canSaveEntities | executedUnloadTasks[MoonriseRegionFileIO.RegionFileType.ENTITY_DATA.ordinal()], ++ canSavePOI | executedUnloadTasks[MoonriseRegionFileIO.RegionFileType.POI_DATA.ordinal()] ++ ) ++ : null; + } + + private boolean saveChunk(final ChunkAccess chunk, final boolean unloading) { + if (!chunk.isUnsaved()) { + if (unloading) { +- this.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, null); ++ this.completeAsyncUnloadDataSave(MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, null); + } + return false; + } +- boolean completing = false; +- boolean failedAsyncPrepare = false; + try { +- if (unloading && ChunkSystemFeatures.supportsAsyncChunkSave()) { +- try { +- final AsyncChunkSaveData asyncSaveData = ChunkSystemFeatures.getAsyncSaveData(this.world, chunk); ++ final SerializableChunkData chunkData = SerializableChunkData.copyOf(this.world, chunk); ++ PlatformHooks.get().chunkSyncSave(this.world, chunk, chunkData); + +- final PrioritisedExecutor.PrioritisedTask task = this.scheduler.loadExecutor.createTask(new AsyncChunkSerializeTask(this.world, chunk, asyncSaveData, this)); ++ chunk.tryMarkSaved(); + +- this.chunkDataUnload.task().setTask(task); ++ final CallbackCompletable completable = new CallbackCompletable<>(); + +- chunk.setUnsaved(false); ++ final Runnable run = () -> { ++ final CompoundTag data = chunkData.write(); + +- task.queue(); ++ completable.complete(data); + +- return true; +- } catch (final Throwable thr) { +- LOGGER.error("Failed to prepare async chunk data (" + this.chunkX + "," + this.chunkZ + ") in world '" + WorldUtil.getWorldName(this.world) + "', falling back to synchronous save", thr); +- failedAsyncPrepare = true; +- // fall through to synchronous save ++ if (unloading) { ++ NewChunkHolder.this.completeAsyncUnloadDataSave(MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, data); + } +- } +- +- final CompoundTag save = ChunkSerializer.write(this.world, chunk); ++ }; + ++ final PrioritisedExecutor.PrioritisedTask task; + if (unloading) { +- completing = true; +- this.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, save); +- if (failedAsyncPrepare) { +- LOGGER.info("Successfully serialized chunk data (" + this.chunkX + "," + this.chunkZ + ") in world '" + WorldUtil.getWorldName(this.world) + "' synchronously"); +- } ++ this.chunkDataUnload.toRun().setRunnable(run); ++ task = this.chunkDataUnload.task(); + } else { +- RegionFileIOThread.scheduleSave(this.world, this.chunkX, this.chunkZ, save, RegionFileIOThread.RegionFileType.CHUNK_DATA); ++ task = this.scheduler.saveExecutor.createTask(run); + } +- chunk.setUnsaved(false); ++ ++ task.queue(); ++ ++ MoonriseRegionFileIO.scheduleSave( ++ this.world, this.chunkX, this.chunkZ, completable, task, MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, Priority.NORMAL ++ ); + } catch (final Throwable thr) { + LOGGER.error("Failed to save chunk data (" + this.chunkX + "," + this.chunkZ + ") in world '" + WorldUtil.getWorldName(this.world) + "'", thr); +- if (unloading && !completing) { +- this.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, null); +- } + } + + return true; +@@ -1834,7 +1797,7 @@ public final class NewChunkHolder { + return false; + } + try { +- mergeFrom = RegionFileIOThread.loadData(this.world, this.chunkX, this.chunkZ, RegionFileIOThread.RegionFileType.ENTITY_DATA, PrioritisedExecutor.Priority.BLOCKING); ++ mergeFrom = MoonriseRegionFileIO.loadData(this.world, this.chunkX, this.chunkZ, MoonriseRegionFileIO.RegionFileType.ENTITY_DATA, Priority.BLOCKING); + } catch (final Exception ex) { + LOGGER.error("Cannot merge transient entities for chunk (" + this.chunkX + "," + this.chunkZ + ") in world '" + WorldUtil.getWorldName(this.world) + "', data on disk will be replaced", ex); + } +@@ -1853,7 +1816,7 @@ public final class NewChunkHolder { + return false; + } + +- RegionFileIOThread.scheduleSave(this.world, this.chunkX, this.chunkZ, save, RegionFileIOThread.RegionFileType.ENTITY_DATA); ++ MoonriseRegionFileIO.scheduleSave(this.world, this.chunkX, this.chunkZ, save, MoonriseRegionFileIO.RegionFileType.ENTITY_DATA); + this.lastEntitySaveNull = save == null; + if (unloading) { + this.lastEntityUnload = save; +@@ -1877,7 +1840,7 @@ public final class NewChunkHolder { + return false; + } + +- RegionFileIOThread.scheduleSave(this.world, this.chunkX, this.chunkZ, save, RegionFileIOThread.RegionFileType.POI_DATA); ++ MoonriseRegionFileIO.scheduleSave(this.world, this.chunkX, this.chunkZ, save, MoonriseRegionFileIO.RegionFileType.POI_DATA); + this.lastPoiSaveNull = save == null; + if (unloading) { + this.poiDataUnload.completable().complete(save); +@@ -1924,7 +1887,7 @@ public final class NewChunkHolder { + return element == null ? JsonNull.INSTANCE : new JsonPrimitive(element.toString()); + } + +- private static JsonObject serializeCompletable(final Completable completable) { ++ private static JsonObject serializeCompletable(final CallbackCompletable completable) { + final JsonObject ret = new JsonObject(); + + if (completable == null) { +@@ -2019,13 +1982,13 @@ public final class NewChunkHolder { + ret.add("poi_unload_completable", serializeCompletable(poiDataUnload == null ? null : poiDataUnload.completable())); + ret.add("chunk_unload_completable", serializeCompletable(chunkDataUnload == null ? null : chunkDataUnload.completable())); + +- final DelayedPrioritisedTask unloadTask = chunkDataUnload == null ? null : chunkDataUnload.task(); ++ final PrioritisedExecutor.PrioritisedTask unloadTask = chunkDataUnload == null ? null : chunkDataUnload.task(); + if (unloadTask == null) { + ret.addProperty("unload_task_priority", "null"); +- ret.addProperty("unload_task_priority_raw", "null"); ++ ret.addProperty("unload_task_suborder", Long.valueOf(0L)); + } else { + ret.addProperty("unload_task_priority", Objects.toString(unloadTask.getPriority())); +- ret.addProperty("unload_task_priority_raw", Integer.valueOf(unloadTask.getPriorityInternal())); ++ ret.addProperty("unload_task_suborder", Long.valueOf(unloadTask.getSubOrder())); + } + + ret.addProperty("killed", Boolean.valueOf(this.unloaded)); +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/PriorityHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/PriorityHolder.java +index 261e09454f49d04eb159c984ec695d7c7aa6a3a8..6b468c621b74449a6218391f6477cf63cfc98c7c 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/PriorityHolder.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/PriorityHolder.java +@@ -1,7 +1,7 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; + import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; + import java.lang.invoke.VarHandle; + + public abstract class PriorityHolder { +@@ -28,8 +28,8 @@ public abstract class PriorityHolder { + PRIORITY_HANDLE.set((PriorityHolder)this, (int)val); + } + +- protected PriorityHolder(final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ protected PriorityHolder(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.setPriorityPlain(priority.priority); +@@ -69,7 +69,7 @@ public abstract class PriorityHolder { + return; + } + +- this.scheduleTask(PrioritisedExecutor.Priority.getPriority(priority)); ++ this.scheduleTask(Priority.getPriority(priority)); + + int failures = 0; + for (;;) { +@@ -86,7 +86,7 @@ public abstract class PriorityHolder { + return; + } + +- this.setPriorityScheduled(PrioritisedExecutor.Priority.getPriority(priority)); ++ this.setPriorityScheduled(Priority.getPriority(priority)); + + ++failures; + for (int i = 0; i < failures; ++i) { +@@ -95,19 +95,19 @@ public abstract class PriorityHolder { + } + } + +- public final PrioritisedExecutor.Priority getPriority() { ++ public final Priority getPriority() { + final int ret = this.getPriorityVolatile(); + if ((ret & PRIORITY_EXECUTED) != 0) { +- return PrioritisedExecutor.Priority.COMPLETING; ++ return Priority.COMPLETING; + } + if ((ret & PRIORITY_SCHEDULED) != 0) { + return this.getScheduledPriority(); + } +- return PrioritisedExecutor.Priority.getPriority(ret); ++ return Priority.getPriority(ret); + } + +- public final void lowerPriority(final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public final void lowerPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + +@@ -139,8 +139,8 @@ public abstract class PriorityHolder { + } + } + +- public final void setPriority(final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public final void setPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + +@@ -168,8 +168,8 @@ public abstract class PriorityHolder { + } + } + +- public final void raisePriority(final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public final void raisePriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + +@@ -203,13 +203,13 @@ public abstract class PriorityHolder { + + protected abstract void cancelScheduled(); + +- protected abstract PrioritisedExecutor.Priority getScheduledPriority(); ++ protected abstract Priority getScheduledPriority(); + +- protected abstract void scheduleTask(final PrioritisedExecutor.Priority priority); ++ protected abstract void scheduleTask(final Priority priority); + +- protected abstract void lowerPriorityScheduled(final PrioritisedExecutor.Priority priority); ++ protected abstract void lowerPriorityScheduled(final Priority priority); + +- protected abstract void setPriorityScheduled(final PrioritisedExecutor.Priority priority); ++ protected abstract void setPriorityScheduled(final Priority priority); + +- protected abstract void raisePriorityScheduled(final PrioritisedExecutor.Priority priority); ++ protected abstract void raisePriorityScheduled(final Priority priority); + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/executor/RadiusAwarePrioritisedExecutor.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/executor/RadiusAwarePrioritisedExecutor.java +index e0b26ccb63596748b80fc6a5e47e373ba811ba8b..5f4b99d8c5453f8ad2e600a57ea4e7dafa2d45f8 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/executor/RadiusAwarePrioritisedExecutor.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/executor/RadiusAwarePrioritisedExecutor.java +@@ -1,10 +1,10 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.executor; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.util.Priority; + import ca.spottedleaf.moonrise.common.util.CoordinateUtils; + import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; + import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; +- + import java.util.ArrayList; + import java.util.Comparator; + import java.util.List; +@@ -16,15 +16,36 @@ public class RadiusAwarePrioritisedExecutor { + return Long.compare(t1.id, t2.id); + }; + +- private final DependencyTree[] queues = new DependencyTree[PrioritisedExecutor.Priority.TOTAL_SCHEDULABLE_PRIORITIES]; ++ private final PrioritisedExecutor executor; ++ private final DependencyTree[] queues = new DependencyTree[Priority.TOTAL_SCHEDULABLE_PRIORITIES]; + private static final int NO_TASKS_QUEUED = -1; + private int selectedQueue = NO_TASKS_QUEUED; + private boolean canQueueTasks = true; + + public RadiusAwarePrioritisedExecutor(final PrioritisedExecutor executor, final int maxToSchedule) { ++ this.executor = executor; ++ + for (int i = 0; i < this.queues.length; ++i) { +- this.queues[i] = new DependencyTree(this, executor, maxToSchedule, i); ++ this.queues[i] = new DependencyTree(this, executor, maxToSchedule); ++ } ++ } ++ ++ public void setMaxToSchedule(final int maxToSchedule) { ++ final List tasks; ++ ++ synchronized (this) { ++ for (final DependencyTree dependencyTree : this.queues) { ++ dependencyTree.maxToSchedule = maxToSchedule; ++ } ++ ++ if (this.selectedQueue == NO_TASKS_QUEUED || !this.canQueueTasks) { ++ return; ++ } ++ ++ tasks = this.queues[this.selectedQueue].tryPushTasks(); + } ++ ++ scheduleTasks(tasks); + } + + private boolean canQueueTasks() { +@@ -56,7 +77,7 @@ public class RadiusAwarePrioritisedExecutor { + return null; + } + +- private List queue(final Task task, final PrioritisedExecutor.Priority priority) { ++ private List queue(final Task task, final Priority priority) { + final int priorityId = priority.priority; + final DependencyTree queue = this.queues[priorityId]; + +@@ -79,7 +100,7 @@ public class RadiusAwarePrioritisedExecutor { + return null; + } + +- if (PrioritisedExecutor.Priority.isHigherPriority(priorityId, this.selectedQueue)) { ++ if (Priority.isHigherPriority(priorityId, this.selectedQueue)) { + // prevent the lower priority tree from queueing more tasks + this.canQueueTasks = false; + return null; +@@ -90,7 +111,7 @@ public class RadiusAwarePrioritisedExecutor { + } + + public PrioritisedExecutor.PrioritisedTask createTask(final int chunkX, final int chunkZ, final int radius, +- final Runnable run, final PrioritisedExecutor.Priority priority) { ++ final Runnable run, final Priority priority) { + if (radius < 0) { + throw new IllegalArgumentException("Radius must be > 0: " + radius); + } +@@ -99,11 +120,11 @@ public class RadiusAwarePrioritisedExecutor { + + public PrioritisedExecutor.PrioritisedTask createTask(final int chunkX, final int chunkZ, final int radius, + final Runnable run) { +- return this.createTask(chunkX, chunkZ, radius, run, PrioritisedExecutor.Priority.NORMAL); ++ return this.createTask(chunkX, chunkZ, radius, run, Priority.NORMAL); + } + + public PrioritisedExecutor.PrioritisedTask queueTask(final int chunkX, final int chunkZ, final int radius, +- final Runnable run, final PrioritisedExecutor.Priority priority) { ++ final Runnable run, final Priority priority) { + final PrioritisedExecutor.PrioritisedTask ret = this.createTask(chunkX, chunkZ, radius, run, priority); + + ret.queue(); +@@ -120,15 +141,15 @@ public class RadiusAwarePrioritisedExecutor { + return ret; + } + +- public PrioritisedExecutor.PrioritisedTask createInfiniteRadiusTask(final Runnable run, final PrioritisedExecutor.Priority priority) { ++ public PrioritisedExecutor.PrioritisedTask createInfiniteRadiusTask(final Runnable run, final Priority priority) { + return new Task(this, 0, 0, -1, run, priority); + } + + public PrioritisedExecutor.PrioritisedTask createInfiniteRadiusTask(final Runnable run) { +- return this.createInfiniteRadiusTask(run, PrioritisedExecutor.Priority.NORMAL); ++ return this.createInfiniteRadiusTask(run, Priority.NORMAL); + } + +- public PrioritisedExecutor.PrioritisedTask queueInfiniteRadiusTask(final Runnable run, final PrioritisedExecutor.Priority priority) { ++ public PrioritisedExecutor.PrioritisedTask queueInfiniteRadiusTask(final Runnable run, final Priority priority) { + final PrioritisedExecutor.PrioritisedTask ret = this.createInfiniteRadiusTask(run, priority); + + ret.queue(); +@@ -137,20 +158,27 @@ public class RadiusAwarePrioritisedExecutor { + } + + public PrioritisedExecutor.PrioritisedTask queueInfiniteRadiusTask(final Runnable run) { +- final PrioritisedExecutor.PrioritisedTask ret = this.createInfiniteRadiusTask(run, PrioritisedExecutor.Priority.NORMAL); ++ final PrioritisedExecutor.PrioritisedTask ret = this.createInfiniteRadiusTask(run, Priority.NORMAL); + + ret.queue(); + + return ret; + } + ++ private static void scheduleTasks(final List toSchedule) { ++ if (toSchedule != null) { ++ for (int i = 0, len = toSchedule.size(); i < len; ++i) { ++ toSchedule.get(i).queue(); ++ } ++ } ++ } ++ + // all accesses must be synchronised by the radius aware object + private static final class DependencyTree { + + private final RadiusAwarePrioritisedExecutor scheduler; + private final PrioritisedExecutor executor; +- private final int maxToSchedule; +- private final int treeIndex; ++ private int maxToSchedule; + + private int currentlyExecuting; + private long idGenerator; +@@ -163,11 +191,10 @@ public class RadiusAwarePrioritisedExecutor { + private final Long2ReferenceOpenHashMap nodeByPosition = new Long2ReferenceOpenHashMap<>(); + + public DependencyTree(final RadiusAwarePrioritisedExecutor scheduler, final PrioritisedExecutor executor, +- final int maxToSchedule, final int treeIndex) { ++ final int maxToSchedule) { + this.scheduler = scheduler; + this.executor = executor; + this.maxToSchedule = maxToSchedule; +- this.treeIndex = treeIndex; + } + + public boolean hasWaitingTasks() { +@@ -412,13 +439,13 @@ public class RadiusAwarePrioritisedExecutor { + private final int chunkZ; + private final int radius; + private Runnable run; +- private PrioritisedExecutor.Priority priority; ++ private Priority priority; + + private DependencyNode dependencyNode; + private PrioritisedExecutor.PrioritisedTask queuedTask; + + private Task(final RadiusAwarePrioritisedExecutor scheduler, final int chunkX, final int chunkZ, final int radius, +- final Runnable run, final PrioritisedExecutor.Priority priority) { ++ final Runnable run, final Priority priority) { + this.scheduler = scheduler; + this.chunkX = chunkX; + this.chunkZ = chunkZ; +@@ -441,14 +468,6 @@ public class RadiusAwarePrioritisedExecutor { + run.run(); + } + +- private static void scheduleTasks(final List toSchedule) { +- if (toSchedule != null) { +- for (int i = 0, len = toSchedule.size(); i < len; ++i) { +- toSchedule.get(i).queue(); +- } +- } +- } +- + private void returnNode() { + final List toSchedule; + synchronized (this.scheduler) { +@@ -460,6 +479,11 @@ public class RadiusAwarePrioritisedExecutor { + scheduleTasks(toSchedule); + } + ++ @Override ++ public PrioritisedExecutor getExecutor() { ++ return this.scheduler.executor; ++ } ++ + @Override + public void run() { + final Runnable run = this.run; +@@ -475,7 +499,7 @@ public class RadiusAwarePrioritisedExecutor { + public boolean queue() { + final List toSchedule; + synchronized (this.scheduler) { +- if (this.queuedTask != null || this.dependencyNode != null || this.priority == PrioritisedExecutor.Priority.COMPLETING) { ++ if (this.queuedTask != null || this.dependencyNode != null || this.priority == Priority.COMPLETING) { + return false; + } + +@@ -486,16 +510,23 @@ public class RadiusAwarePrioritisedExecutor { + return true; + } + ++ @Override ++ public boolean isQueued() { ++ synchronized (this.scheduler) { ++ return (this.queuedTask != null || this.dependencyNode != null) && this.priority != Priority.COMPLETING; ++ } ++ } ++ + @Override + public boolean cancel() { + final PrioritisedExecutor.PrioritisedTask task; + synchronized (this.scheduler) { + if ((task = this.queuedTask) == null) { +- if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { ++ if (this.priority == Priority.COMPLETING) { + return false; + } + +- this.priority = PrioritisedExecutor.Priority.COMPLETING; ++ this.priority = Priority.COMPLETING; + if (this.dependencyNode != null) { + this.dependencyNode.purged = true; + this.dependencyNode = null; +@@ -519,11 +550,11 @@ public class RadiusAwarePrioritisedExecutor { + final PrioritisedExecutor.PrioritisedTask task; + synchronized (this.scheduler) { + if ((task = this.queuedTask) == null) { +- if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { ++ if (this.priority == Priority.COMPLETING) { + return false; + } + +- this.priority = PrioritisedExecutor.Priority.COMPLETING; ++ this.priority = Priority.COMPLETING; + if (this.dependencyNode != null) { + this.dependencyNode.purged = true; + this.dependencyNode = null; +@@ -543,7 +574,7 @@ public class RadiusAwarePrioritisedExecutor { + } + + @Override +- public PrioritisedExecutor.Priority getPriority() { ++ public Priority getPriority() { + final PrioritisedExecutor.PrioritisedTask task; + synchronized (this.scheduler) { + if ((task = this.queuedTask) == null) { +@@ -555,8 +586,8 @@ public class RadiusAwarePrioritisedExecutor { + } + + @Override +- public boolean setPriority(final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public boolean setPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + +@@ -564,7 +595,7 @@ public class RadiusAwarePrioritisedExecutor { + List toSchedule = null; + synchronized (this.scheduler) { + if ((task = this.queuedTask) == null) { +- if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { ++ if (this.priority == Priority.COMPLETING) { + return false; + } + +@@ -592,8 +623,8 @@ public class RadiusAwarePrioritisedExecutor { + } + + @Override +- public boolean raisePriority(final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public boolean raisePriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + +@@ -601,7 +632,7 @@ public class RadiusAwarePrioritisedExecutor { + List toSchedule = null; + synchronized (this.scheduler) { + if ((task = this.queuedTask) == null) { +- if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { ++ if (this.priority == Priority.COMPLETING) { + return false; + } + +@@ -629,8 +660,8 @@ public class RadiusAwarePrioritisedExecutor { + } + + @Override +- public boolean lowerPriority(final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public boolean lowerPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + +@@ -638,7 +669,7 @@ public class RadiusAwarePrioritisedExecutor { + List toSchedule = null; + synchronized (this.scheduler) { + if ((task = this.queuedTask) == null) { +- if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { ++ if (this.priority == Priority.COMPLETING) { + return false; + } + +@@ -664,5 +695,35 @@ public class RadiusAwarePrioritisedExecutor { + + return true; + } ++ ++ @Override ++ public long getSubOrder() { ++ // TODO implement ++ return 0; ++ } ++ ++ @Override ++ public boolean setSubOrder(final long subOrder) { ++ // TODO implement ++ return false; ++ } ++ ++ @Override ++ public boolean raiseSubOrder(final long subOrder) { ++ // TODO implement ++ return false; ++ } ++ ++ @Override ++ public boolean lowerSubOrder(final long subOrder) { ++ // TODO implement ++ return false; ++ } ++ ++ @Override ++ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder) { ++ // TODO implement ++ return this.setPriority(priority); ++ } + } +-} +\ No newline at end of file ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java +index fbdf721e8b4cfe6cef4ee60c53c680cbfc858d88..98382575eb6cd48aa163264e4935c812db1f1aff 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java +@@ -1,7 +1,9 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; + import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.PlatformHooks; + import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; + import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk; + import ca.spottedleaf.moonrise.patches.chunk_system.level.poi.ChunkSystemPoiManager; +@@ -29,7 +31,7 @@ public final class ChunkFullTask extends ChunkProgressionTask implements Runnabl + private final PrioritisedExecutor.PrioritisedTask convertToFullTask; + + public ChunkFullTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, final int chunkZ, +- final NewChunkHolder chunkHolder, final ChunkAccess fromChunk, final PrioritisedExecutor.Priority priority) { ++ final NewChunkHolder chunkHolder, final ChunkAccess fromChunk, final Priority priority) { + super(scheduler, world, chunkX, chunkZ); + this.chunkHolder = chunkHolder; + this.fromChunk = fromChunk; +@@ -43,6 +45,8 @@ public final class ChunkFullTask extends ChunkProgressionTask implements Runnabl + + @Override + public void run() { ++ final PlatformHooks platformHooks = PlatformHooks.get(); ++ + // See Vanilla ChunkPyramid#LOADING_PYRAMID.FULL for what this function should be doing + final LevelChunk chunk; + try { +@@ -61,7 +65,7 @@ public final class ChunkFullTask extends ChunkProgressionTask implements Runnabl + final ServerLevel world = this.world; + final ProtoChunk protoChunk = (ProtoChunk)this.fromChunk; + chunk = new LevelChunk(this.world, protoChunk, (final LevelChunk unused) -> { +- ChunkStatusTasks.postLoadProtoChunk(world, protoChunk.getEntities(), protoChunk.getPos()); // Paper - pass chunk pos ++ ChunkStatusTasks.postLoadProtoChunk(world, protoChunk.getEntities()); + }); + this.chunkHolder.replaceProtoChunk(new ImposterProtoChunk(chunk, false)); + } +@@ -71,16 +75,21 @@ public final class ChunkFullTask extends ChunkProgressionTask implements Runnabl + final NewChunkHolder chunkHolder = this.chunkHolder; + + chunk.setFullStatus(chunkHolder::getChunkStatus); +- chunk.runPostLoad(); +- // Unlike Vanilla, we load the entity chunk here, as we load the NBT in empty status (unlike Vanilla) +- // This brings entity addition back in line with older versions of the game +- // Since we load the NBT in the empty status, this will never block for I/O +- ((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager.getOrCreateEntityChunk(this.chunkX, this.chunkZ, false); +- +- // we don't need the entitiesInLevel, not sure why it's there +- chunk.setLoaded(true); +- chunk.registerAllBlockEntitiesAfterLevelLoad(); +- chunk.registerTickContainerInLevel(this.world); ++ try { ++ platformHooks.setCurrentlyLoading(this.chunkHolder.vanillaChunkHolder, chunk); ++ chunk.runPostLoad(); ++ // Unlike Vanilla, we load the entity chunk here, as we load the NBT in empty status (unlike Vanilla) ++ // This brings entity addition back in line with older versions of the game ++ // Since we load the NBT in the empty status, this will never block for I/O ++ ((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager.getOrCreateEntityChunk(this.chunkX, this.chunkZ, false); ++ chunk.setLoaded(true); ++ chunk.registerAllBlockEntitiesAfterLevelLoad(); ++ chunk.registerTickContainerInLevel(this.world); ++ chunk.setUnsavedListener(this.world.getChunkSource().chunkMap.worldGenContext.unsavedListener()); ++ platformHooks.chunkFullStatusComplete(chunk, (ProtoChunk)this.fromChunk); ++ } finally { ++ platformHooks.setCurrentlyLoading(this.chunkHolder.vanillaChunkHolder, null); ++ } + } catch (final Throwable throwable) { + this.complete(null, throwable); + return; +@@ -112,29 +121,29 @@ public final class ChunkFullTask extends ChunkProgressionTask implements Runnabl + } + + @Override +- public PrioritisedExecutor.Priority getPriority() { ++ public Priority getPriority() { + return this.convertToFullTask.getPriority(); + } + + @Override +- public void lowerPriority(final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void lowerPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.convertToFullTask.lowerPriority(priority); + } + + @Override +- public void setPriority(final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void setPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.convertToFullTask.setPriority(priority); + } + + @Override +- public void raisePriority(final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void raisePriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.convertToFullTask.raisePriority(priority); +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLightTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLightTask.java +index 7c2e6752228fac175c4aa97fa3d817b8a938922f..4538ccfaea83d217ed85eaf16e82393c7f286489 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLightTask.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLightTask.java +@@ -1,6 +1,6 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.util.Priority; + import ca.spottedleaf.moonrise.common.util.WorldUtil; + import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; + import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.PriorityHolder; +@@ -25,9 +25,9 @@ public final class ChunkLightTask extends ChunkProgressionTask { + private final LightTaskPriorityHolder priorityHolder; + + public ChunkLightTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, final int chunkZ, +- final ChunkAccess chunk, final PrioritisedExecutor.Priority priority) { ++ final ChunkAccess chunk, final Priority priority) { + super(scheduler, world, chunkX, chunkZ); +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.priorityHolder = new LightTaskPriorityHolder(priority, this); +@@ -55,22 +55,22 @@ public final class ChunkLightTask extends ChunkProgressionTask { + } + + @Override +- public PrioritisedExecutor.Priority getPriority() { ++ public Priority getPriority() { + return this.priorityHolder.getPriority(); + } + + @Override +- public void lowerPriority(final PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(final Priority priority) { + this.priorityHolder.raisePriority(priority); + } + + @Override +- public void setPriority(final PrioritisedExecutor.Priority priority) { ++ public void setPriority(final Priority priority) { + this.priorityHolder.setPriority(priority); + } + + @Override +- public void raisePriority(final PrioritisedExecutor.Priority priority) { ++ public void raisePriority(final Priority priority) { + this.priorityHolder.raisePriority(priority); + } + +@@ -78,7 +78,7 @@ public final class ChunkLightTask extends ChunkProgressionTask { + + private final ChunkLightTask task; + +- private LightTaskPriorityHolder(final PrioritisedExecutor.Priority priority, final ChunkLightTask task) { ++ private LightTaskPriorityHolder(final Priority priority, final ChunkLightTask task) { + super(priority); + this.task = task; + } +@@ -90,13 +90,13 @@ public final class ChunkLightTask extends ChunkProgressionTask { + } + + @Override +- protected PrioritisedExecutor.Priority getScheduledPriority() { ++ protected Priority getScheduledPriority() { + final ChunkLightTask task = this.task; + return ((StarLightLightingProvider)task.world.getChunkSource().getLightEngine()).starlight$getLightEngine().getServerLightQueue().getPriority(task.chunkX, task.chunkZ); + } + + @Override +- protected void scheduleTask(final PrioritisedExecutor.Priority priority) { ++ protected void scheduleTask(final Priority priority) { + final ChunkLightTask task = this.task; + final StarLightInterface starLightInterface = ((StarLightLightingProvider)task.world.getChunkSource().getLightEngine()).starlight$getLightEngine(); + final StarLightInterface.ServerLightQueue lightQueue = starLightInterface.getServerLightQueue(); +@@ -105,7 +105,7 @@ public final class ChunkLightTask extends ChunkProgressionTask { + } + + @Override +- protected void lowerPriorityScheduled(final PrioritisedExecutor.Priority priority) { ++ protected void lowerPriorityScheduled(final Priority priority) { + final ChunkLightTask task = this.task; + final StarLightInterface starLightInterface = ((StarLightLightingProvider)task.world.getChunkSource().getLightEngine()).starlight$getLightEngine(); + final StarLightInterface.ServerLightQueue lightQueue = starLightInterface.getServerLightQueue(); +@@ -113,7 +113,7 @@ public final class ChunkLightTask extends ChunkProgressionTask { + } + + @Override +- protected void setPriorityScheduled(final PrioritisedExecutor.Priority priority) { ++ protected void setPriorityScheduled(final Priority priority) { + final ChunkLightTask task = this.task; + final StarLightInterface starLightInterface = ((StarLightLightingProvider)task.world.getChunkSource().getLightEngine()).starlight$getLightEngine(); + final StarLightInterface.ServerLightQueue lightQueue = starLightInterface.getServerLightQueue(); +@@ -121,7 +121,7 @@ public final class ChunkLightTask extends ChunkProgressionTask { + } + + @Override +- protected void raisePriorityScheduled(final PrioritisedExecutor.Priority priority) { ++ protected void raisePriorityScheduled(final Priority priority) { + final ChunkLightTask task = this.task; + final StarLightInterface starLightInterface = ((StarLightLightingProvider)task.world.getChunkSource().getLightEngine()).starlight$getLightEngine(); + final StarLightInterface.ServerLightQueue lightQueue = starLightInterface.getServerLightQueue(); +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java +index 1ab93f219246d0b4dcdfd0f685f47c13091425f8..e0a88615a8b6d58191f29b1ff1a26427f0a4c1a6 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java +@@ -1,12 +1,13 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; + + import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; + import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; + import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.PlatformHooks; + import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystemConverters; +-import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystemFeatures; +-import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; + import ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk; + import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; + import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder; +@@ -18,7 +19,7 @@ import net.minecraft.world.level.chunk.ChunkAccess; + import net.minecraft.world.level.chunk.ProtoChunk; + import net.minecraft.world.level.chunk.UpgradeData; + import net.minecraft.world.level.chunk.status.ChunkStatus; +-import net.minecraft.world.level.chunk.storage.ChunkSerializer; ++import net.minecraft.world.level.chunk.storage.SerializableChunkData; + import net.minecraft.world.level.levelgen.blending.BlendingData; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; +@@ -41,7 +42,7 @@ public final class ChunkLoadTask extends ChunkProgressionTask { + private final AtomicInteger taskCountToComplete = new AtomicInteger(3); // one for poi, one for entity, and one for chunk data + + public ChunkLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, final int chunkZ, +- final NewChunkHolder chunkHolder, final PrioritisedExecutor.Priority priority) { ++ final NewChunkHolder chunkHolder, final Priority priority) { + super(scheduler, world, chunkX, chunkZ); + this.chunkHolder = chunkHolder; + this.loadTask = new ChunkDataLoadTask(scheduler, world, chunkX, chunkZ, priority); +@@ -170,12 +171,12 @@ public final class ChunkLoadTask extends ChunkProgressionTask { + } + + @Override +- public PrioritisedExecutor.Priority getPriority() { ++ public Priority getPriority() { + return this.loadTask.getPriority(); + } + + @Override +- public void lowerPriority(final PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(final Priority priority) { + final EntityDataLoadTask entityLoad = this.chunkHolder.getEntityDataLoadTask(); + if (entityLoad != null) { + entityLoad.lowerPriority(priority); +@@ -191,7 +192,7 @@ public final class ChunkLoadTask extends ChunkProgressionTask { + } + + @Override +- public void setPriority(final PrioritisedExecutor.Priority priority) { ++ public void setPriority(final Priority priority) { + final EntityDataLoadTask entityLoad = this.chunkHolder.getEntityDataLoadTask(); + if (entityLoad != null) { + entityLoad.setPriority(priority); +@@ -207,7 +208,7 @@ public final class ChunkLoadTask extends ChunkProgressionTask { + } + + @Override +- public void raisePriority(final PrioritisedExecutor.Priority priority) { ++ public void raisePriority(final Priority priority) { + final EntityDataLoadTask entityLoad = this.chunkHolder.getEntityDataLoadTask(); + if (entityLoad != null) { + entityLoad.raisePriority(priority); +@@ -231,8 +232,8 @@ public final class ChunkLoadTask extends ChunkProgressionTask { + protected static final VarHandle COMPLETED_HANDLE = ConcurrentUtil.getVarHandle(CallbackDataLoadTask.class, "completed", boolean.class); + + protected CallbackDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, +- final int chunkZ, final RegionFileIOThread.RegionFileType type, +- final PrioritisedExecutor.Priority priority) { ++ final int chunkZ, final MoonriseRegionFileIO.RegionFileType type, ++ final Priority priority) { + super(scheduler, world, chunkX, chunkZ, type, priority); + } + +@@ -272,10 +273,13 @@ public final class ChunkLoadTask extends ChunkProgressionTask { + } + } + +- private static final class ChunkDataLoadTask extends CallbackDataLoadTask { ++ ++ private static record ReadChunk(ProtoChunk protoChunk, SerializableChunkData chunkData) {} ++ ++ private static final class ChunkDataLoadTask extends CallbackDataLoadTask { + private ChunkDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, +- final int chunkZ, final PrioritisedExecutor.Priority priority) { +- super(scheduler, world, chunkX, chunkZ, RegionFileIOThread.RegionFileType.CHUNK_DATA, priority); ++ final int chunkZ, final Priority priority) { ++ super(scheduler, world, chunkX, chunkZ, MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, priority); + } + + @Override +@@ -289,40 +293,42 @@ public final class ChunkLoadTask extends ChunkProgressionTask { + } + + @Override +- protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final PrioritisedExecutor.Priority priority) { ++ protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final Priority priority) { + return this.scheduler.loadExecutor.createTask(run, priority); + } + + @Override +- protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final PrioritisedExecutor.Priority priority) { ++ protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final Priority priority) { + return this.scheduler.createChunkTask(this.chunkX, this.chunkZ, run, priority); + } + + @Override +- protected TaskResult completeOnMainOffMain(final CompoundTag data, final Throwable throwable) { ++ protected TaskResult completeOnMainOffMain(final ReadChunk data, final Throwable throwable) { + if (throwable != null) { + return new TaskResult<>(null, throwable); + } +- if (data == null) { ++ ++ if (data == null || data.protoChunk() == null) { + return new TaskResult<>(this.getEmptyChunk(), null); + } + +- if (ChunkSystemFeatures.supportsAsyncChunkDeserialization()) { +- return this.deserialize(data); ++ if (!PlatformHooks.get().hasMainChunkLoadHook()) { ++ return new TaskResult<>(data.protoChunk(), null); + } +- // need to deserialize on main thread ++ ++ // need to invoke the callback for loading on the main thread + return null; + } + + private ProtoChunk getEmptyChunk() { + return new ProtoChunk( + new ChunkPos(this.chunkX, this.chunkZ), UpgradeData.EMPTY, this.world, +- this.world.registryAccess().registryOrThrow(Registries.BIOME), (BlendingData)null ++ this.world.registryAccess().lookupOrThrow(Registries.BIOME), (BlendingData)null + ); + } + + @Override +- protected TaskResult runOffMain(final CompoundTag data, final Throwable throwable) { ++ protected TaskResult runOffMain(final CompoundTag data, final Throwable throwable) { + if (throwable != null) { + LOGGER.error("Failed to load chunk data for task: " + this.toString() + ", chunk data will be lost", throwable); + return new TaskResult<>(null, null); +@@ -334,42 +340,43 @@ public final class ChunkLoadTask extends ChunkProgressionTask { + + try { + // run converters +- final CompoundTag converted = this.world.getChunkSource().chunkMap.upgradeChunkTag(data, new net.minecraft.world.level.ChunkPos(this.chunkX, this.chunkZ)); ++ final CompoundTag converted = this.world.getChunkSource().chunkMap.upgradeChunkTag(data); + +- return new TaskResult<>(converted, null); +- } catch (final Throwable thr2) { +- LOGGER.error("Failed to parse chunk data for task: " + this.toString() + ", chunk data will be lost", thr2); +- return new TaskResult<>(null, null); +- } +- } ++ // unpack the data ++ final SerializableChunkData chunkData = SerializableChunkData.parse( ++ this.world, this.world.registryAccess(), converted ++ ); + +- private TaskResult deserialize(final CompoundTag data) { +- try { +- final ChunkAccess deserialized = ChunkSerializer.read( +- this.world, this.world.getPoiManager(), this.world.getChunkSource().chunkMap.storageInfo(), new ChunkPos(this.chunkX, this.chunkZ), data ++ if (chunkData == null) { ++ LOGGER.error("Deserialized chunk for task: " + this.toString() + " produced null, chunk data will be lost?"); ++ } ++ ++ // read into ProtoChunk ++ final ProtoChunk chunk = chunkData == null ? null : chunkData.read( ++ this.world, this.world.getPoiManager(), this.world.getChunkSource().chunkMap.storageInfo(), ++ new ChunkPos(this.chunkX, this.chunkZ) + ); +- return new TaskResult<>(deserialized, null); ++ ++ return new TaskResult<>(new ReadChunk(chunk, chunkData), null); + } catch (final Throwable thr2) { + LOGGER.error("Failed to parse chunk data for task: " + this.toString() + ", chunk data will be lost", thr2); +- return new TaskResult<>(this.getEmptyChunk(), null); ++ return new TaskResult<>(null, null); + } + } + + @Override +- protected TaskResult runOnMain(final CompoundTag data, final Throwable throwable) { +- // data != null && throwable == null +- if (ChunkSystemFeatures.supportsAsyncChunkDeserialization()) { +- throw new UnsupportedOperationException(); +- } +- return this.deserialize(data); ++ protected TaskResult runOnMain(final ReadChunk data, final Throwable throwable) { ++ PlatformHooks.get().mainChunkLoad(data.protoChunk(), data.chunkData()); ++ ++ return new TaskResult<>(data.protoChunk(), null); + } + } + + public static final class PoiDataLoadTask extends CallbackDataLoadTask { + + public PoiDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, +- final int chunkZ, final PrioritisedExecutor.Priority priority) { +- super(scheduler, world, chunkX, chunkZ, RegionFileIOThread.RegionFileType.POI_DATA, priority); ++ final int chunkZ, final Priority priority) { ++ super(scheduler, world, chunkX, chunkZ, MoonriseRegionFileIO.RegionFileType.POI_DATA, priority); + } + + @Override +@@ -383,12 +390,12 @@ public final class ChunkLoadTask extends ChunkProgressionTask { + } + + @Override +- protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final PrioritisedExecutor.Priority priority) { ++ protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final Priority priority) { + return this.scheduler.loadExecutor.createTask(run, priority); + } + + @Override +- protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final PrioritisedExecutor.Priority priority) { ++ protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final Priority priority) { + throw new UnsupportedOperationException(); + } + +@@ -430,8 +437,8 @@ public final class ChunkLoadTask extends ChunkProgressionTask { + public static final class EntityDataLoadTask extends CallbackDataLoadTask { + + public EntityDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, +- final int chunkZ, final PrioritisedExecutor.Priority priority) { +- super(scheduler, world, chunkX, chunkZ, RegionFileIOThread.RegionFileType.ENTITY_DATA, priority); ++ final int chunkZ, final Priority priority) { ++ super(scheduler, world, chunkX, chunkZ, MoonriseRegionFileIO.RegionFileType.ENTITY_DATA, priority); + } + + @Override +@@ -445,12 +452,12 @@ public final class ChunkLoadTask extends ChunkProgressionTask { + } + + @Override +- protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final PrioritisedExecutor.Priority priority) { ++ protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final Priority priority) { + return this.scheduler.loadExecutor.createTask(run, priority); + } + + @Override +- protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final PrioritisedExecutor.Priority priority) { ++ protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final Priority priority) { + throw new UnsupportedOperationException(); + } + +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkProgressionTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkProgressionTask.java +index 70e900b0f9c131900bf8b3f3ecbfbd5df5361205..002ee365aa70d8e6a6e6bd5c95988bd17db4395a 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkProgressionTask.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkProgressionTask.java +@@ -1,8 +1,8 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; + + import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; + import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; + import ca.spottedleaf.moonrise.common.util.WorldUtil; + import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; + import net.minecraft.server.level.ServerLevel; +@@ -46,15 +46,15 @@ public abstract class ChunkProgressionTask { + /* May be called multiple times */ + public abstract void cancel(); + +- public abstract PrioritisedExecutor.Priority getPriority(); ++ public abstract Priority getPriority(); + + /* Schedule lock is always held for the priority update calls */ + +- public abstract void lowerPriority(final PrioritisedExecutor.Priority priority); ++ public abstract void lowerPriority(final Priority priority); + +- public abstract void setPriority(final PrioritisedExecutor.Priority priority); ++ public abstract void setPriority(final Priority priority); + +- public abstract void raisePriority(final PrioritisedExecutor.Priority priority); ++ public abstract void raisePriority(final Priority priority); + + public final void onComplete(final BiConsumer onComplete) { + if (!this.waiters.add(onComplete)) { +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkUpgradeGenericStatusTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkUpgradeGenericStatusTask.java +index 2c17d5589f15f1155be08be670d29acbe954a8fa..25d8da4773dcee5096053e7e3788bfc224d705a7 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkUpgradeGenericStatusTask.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkUpgradeGenericStatusTask.java +@@ -1,7 +1,8 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; + import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; + import ca.spottedleaf.moonrise.common.util.WorldUtil; + import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkStatus; + import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; +@@ -36,9 +37,9 @@ public final class ChunkUpgradeGenericStatusTask extends ChunkProgressionTask im + + public ChunkUpgradeGenericStatusTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, + final int chunkZ, final ChunkAccess chunk, final StaticCache2D neighbours, +- final ChunkStatus toStatus, final PrioritisedExecutor.Priority priority) { ++ final ChunkStatus toStatus, final Priority priority) { + super(scheduler, world, chunkX, chunkZ); +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.fromChunk = chunk; +@@ -187,29 +188,29 @@ public final class ChunkUpgradeGenericStatusTask extends ChunkProgressionTask im + } + + @Override +- public PrioritisedExecutor.Priority getPriority() { ++ public Priority getPriority() { + return this.generateTask.getPriority(); + } + + @Override +- public void lowerPriority(final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void lowerPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.generateTask.lowerPriority(priority); + } + + @Override +- public void setPriority(final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void setPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.generateTask.setPriority(priority); + } + + @Override +- public void raisePriority(final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void raisePriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.generateTask.raisePriority(priority); +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/GenericDataLoadTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/GenericDataLoadTask.java +index 7a65d351b448873c6f2c145c975c92be314b876c..bdcd1879457bafcca4e76523aac0555968f37c0b 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/GenericDataLoadTask.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/GenericDataLoadTask.java +@@ -1,12 +1,13 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; + ++import ca.spottedleaf.concurrentutil.completable.CallbackCompletable; + import ca.spottedleaf.concurrentutil.completable.Completable; + import ca.spottedleaf.concurrentutil.executor.Cancellable; +-import ca.spottedleaf.concurrentutil.executor.standard.DelayedPrioritisedTask; +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; + import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; + import ca.spottedleaf.moonrise.common.util.WorldUtil; +-import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; + import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; + import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; + import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder; +@@ -47,11 +48,11 @@ public abstract class GenericDataLoadTask { + protected final ServerLevel world; + protected final int chunkX; + protected final int chunkZ; +- protected final RegionFileIOThread.RegionFileType type; ++ protected final MoonriseRegionFileIO.RegionFileType type; + + public GenericDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, +- final int chunkZ, final RegionFileIOThread.RegionFileType type, +- final PrioritisedExecutor.Priority priority) { ++ final int chunkZ, final MoonriseRegionFileIO.RegionFileType type, ++ final Priority priority) { + this.scheduler = scheduler; + this.world = world; + this.chunkX = chunkX; +@@ -89,9 +90,9 @@ public abstract class GenericDataLoadTask { + + protected abstract boolean hasOnMain(); + +- protected abstract PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final PrioritisedExecutor.Priority priority); ++ protected abstract PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final Priority priority); + +- protected abstract PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final PrioritisedExecutor.Priority priority); ++ protected abstract PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final Priority priority); + + protected abstract TaskResult runOffMain(final CompoundTag data, final Throwable throwable); + +@@ -108,7 +109,7 @@ public abstract class GenericDataLoadTask { + ", type: " + this.type.toString() + "}"; + } + +- public PrioritisedExecutor.Priority getPriority() { ++ public Priority getPriority() { + if (this.processOnMain != null) { + return this.processOnMain.getPriority(); + } else { +@@ -116,7 +117,7 @@ public abstract class GenericDataLoadTask { + } + } + +- public void lowerPriority(final PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(final Priority priority) { + // can't lower I/O tasks, we don't know what they affect + if (this.processOffMain != null) { + this.processOffMain.lowerPriority(priority); +@@ -126,7 +127,7 @@ public abstract class GenericDataLoadTask { + } + } + +- public void setPriority(final PrioritisedExecutor.Priority priority) { ++ public void setPriority(final Priority priority) { + // can't lower I/O tasks, we don't know what they affect + this.loadDataFromDiskTask.raisePriority(priority); + if (this.processOffMain != null) { +@@ -137,7 +138,7 @@ public abstract class GenericDataLoadTask { + } + } + +- public void raisePriority(final PrioritisedExecutor.Priority priority) { ++ public void raisePriority(final Priority priority) { + // can't lower I/O tasks, we don't know what they affect + this.loadDataFromDiskTask.raisePriority(priority); + if (this.processOffMain != null) { +@@ -382,10 +383,10 @@ public abstract class GenericDataLoadTask { + private final int chunkX; + private final int chunkZ; + +- private final RegionFileIOThread.RegionFileType type; ++ private final MoonriseRegionFileIO.RegionFileType type; + private Cancellable dataLoadTask; + private Cancellable dataUnloadCancellable; +- private DelayedPrioritisedTask dataUnloadTask; ++ private PrioritisedExecutor.PrioritisedTask dataUnloadTask; + + private final BiConsumer onComplete; + private final AtomicBoolean scheduled = new AtomicBoolean(); +@@ -393,10 +394,10 @@ public abstract class GenericDataLoadTask { + // onComplete should be caller sensitive, it may complete synchronously with schedule() - which does + // hold a priority lock. + public LoadDataFromDiskTask(final ServerLevel world, final int chunkX, final int chunkZ, +- final RegionFileIOThread.RegionFileType type, ++ final MoonriseRegionFileIO.RegionFileType type, + final BiConsumer onComplete, +- final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.world = world; +@@ -426,8 +427,8 @@ public abstract class GenericDataLoadTask { + return (this.getPriorityVolatile() & PRIORITY_EXECUTED) != 0; + } + +- public void lowerPriority(final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void lowerPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + +@@ -439,7 +440,7 @@ public abstract class GenericDataLoadTask { + } + + if ((curr & PRIORITY_LOAD_SCHEDULED) != 0) { +- RegionFileIOThread.lowerPriority(this.world, this.chunkX, this.chunkZ, this.type, priority); ++ MoonriseRegionFileIO.lowerPriority(this.world, this.chunkX, this.chunkZ, this.type, priority); + return; + } + +@@ -467,8 +468,8 @@ public abstract class GenericDataLoadTask { + } + } + +- public void setPriority(final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void setPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + +@@ -480,7 +481,7 @@ public abstract class GenericDataLoadTask { + } + + if ((curr & PRIORITY_LOAD_SCHEDULED) != 0) { +- RegionFileIOThread.setPriority(this.world, this.chunkX, this.chunkZ, this.type, priority); ++ MoonriseRegionFileIO.setPriority(this.world, this.chunkX, this.chunkZ, this.type, priority); + return; + } + +@@ -504,8 +505,8 @@ public abstract class GenericDataLoadTask { + } + } + +- public void raisePriority(final PrioritisedExecutor.Priority priority) { +- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void raisePriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + +@@ -517,7 +518,7 @@ public abstract class GenericDataLoadTask { + } + + if ((curr & PRIORITY_LOAD_SCHEDULED) != 0) { +- RegionFileIOThread.raisePriority(this.world, this.chunkX, this.chunkZ, this.type, priority); ++ MoonriseRegionFileIO.raisePriority(this.world, this.chunkX, this.chunkZ, this.type, priority); + return; + } + +@@ -583,7 +584,7 @@ public abstract class GenericDataLoadTask { + } // else: cancelled + }; + +- final PrioritisedExecutor.Priority initialPriority = PrioritisedExecutor.Priority.getPriority(priority); ++ final Priority initialPriority = Priority.getPriority(priority); + boolean scheduledUnload = false; + + final NewChunkHolder holder = ((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.chunkX, this.chunkZ); +@@ -593,13 +594,13 @@ public abstract class GenericDataLoadTask { + consumer.accept(data, null); + } else { + // need to schedule task +- LoadDataFromDiskTask.this.schedule(false, consumer, PrioritisedExecutor.Priority.getPriority(LoadDataFromDiskTask.this.getPriorityVolatile() & ~PRIORITY_FLAGS)); ++ LoadDataFromDiskTask.this.schedule(false, consumer, Priority.getPriority(LoadDataFromDiskTask.this.getPriorityVolatile() & ~PRIORITY_FLAGS)); + } + }; + Cancellable unloadCancellable = null; + CompoundTag syncComplete = null; + final NewChunkHolder.UnloadTask unloadTask = holder.getUnloadTask(this.type); // can be null if no task exists +- final Completable unloadCompletable = unloadTask == null ? null : unloadTask.completable(); ++ final CallbackCompletable unloadCompletable = unloadTask == null ? null : unloadTask.completable(); + if (unloadCompletable != null) { + unloadCancellable = unloadCompletable.addAsynchronousWaiter(unloadConsumer); + if (unloadCancellable == null) { +@@ -622,7 +623,7 @@ public abstract class GenericDataLoadTask { + this.schedule(scheduledUnload, consumer, initialPriority); + } + +- private void schedule(final boolean scheduledUnload, final BiConsumer consumer, final PrioritisedExecutor.Priority initialPriority) { ++ private void schedule(final boolean scheduledUnload, final BiConsumer consumer, final Priority initialPriority) { + int priority = this.getPriorityVolatile(); + + if ((priority & PRIORITY_EXECUTED) != 0) { +@@ -631,9 +632,9 @@ public abstract class GenericDataLoadTask { + } + + if (!scheduledUnload) { +- this.dataLoadTask = RegionFileIOThread.loadDataAsync( ++ this.dataLoadTask = MoonriseRegionFileIO.loadDataAsync( + this.world, this.chunkX, this.chunkZ, this.type, consumer, +- initialPriority.isHigherPriority(PrioritisedExecutor.Priority.NORMAL), initialPriority ++ initialPriority.isHigherPriority(Priority.NORMAL), initialPriority + ); + } + +@@ -657,10 +658,10 @@ public abstract class GenericDataLoadTask { + + if (scheduledUnload) { + if (this.dataUnloadTask != null) { +- this.dataUnloadTask.setPriority(PrioritisedExecutor.Priority.getPriority(priority & ~PRIORITY_FLAGS)); ++ this.dataUnloadTask.setPriority(Priority.getPriority(priority & ~PRIORITY_FLAGS)); + } + } else { +- RegionFileIOThread.setPriority(this.world, this.chunkX, this.chunkZ, this.type, PrioritisedExecutor.Priority.getPriority(priority & ~PRIORITY_FLAGS)); ++ MoonriseRegionFileIO.setPriority(this.world, this.chunkX, this.chunkZ, this.type, Priority.getPriority(priority & ~PRIORITY_FLAGS)); + } + + ++failures; +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java +new file mode 100644 +index 0000000000000000000000000000000000000000..51c126735ace8fdde89ad97b5cab62f244212db0 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java +@@ -0,0 +1,12 @@ ++package ca.spottedleaf.moonrise.patches.chunk_system.storage; ++ ++import net.minecraft.world.level.chunk.storage.RegionFile; ++import java.io.IOException; ++ ++public interface ChunkSystemChunkBuffer { ++ public boolean moonrise$getWriteOnClose(); ++ ++ public void moonrise$setWriteOnClose(final boolean value); ++ ++ public void moonrise$write(final RegionFile regionFile) throws IOException; ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemRegionFile.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemRegionFile.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3bd1b59250dbab15097a64d515999b278636795a +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemRegionFile.java +@@ -0,0 +1,12 @@ ++package ca.spottedleaf.moonrise.patches.chunk_system.storage; ++ ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.world.level.ChunkPos; ++import java.io.IOException; ++ ++public interface ChunkSystemRegionFile { ++ ++ public MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite(final CompoundTag data, final ChunkPos pos) throws IOException; ++ ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/ParallelSearchRadiusIteration.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/ParallelSearchRadiusIteration.java +index 3a9a564edfdb99e006e4816cb8821bd1e9ecff43..93fd23027c00cef76562098306737272fda1350a 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/ParallelSearchRadiusIteration.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/ParallelSearchRadiusIteration.java +@@ -1,6 +1,7 @@ + package ca.spottedleaf.moonrise.patches.chunk_system.util; + + import ca.spottedleaf.moonrise.common.util.CoordinateUtils; ++import ca.spottedleaf.moonrise.common.util.MoonriseConstants; + import it.unimi.dsi.fastutil.HashCommon; + import it.unimi.dsi.fastutil.longs.LongArrayList; + import it.unimi.dsi.fastutil.longs.LongIterator; +@@ -13,7 +14,7 @@ public final class ParallelSearchRadiusIteration { + + // expected that this list returns for a given radius, the set of chunks ordered + // by manhattan distance +- private static final long[][] SEARCH_RADIUS_ITERATION_LIST = new long[64+2+1][]; ++ private static final long[][] SEARCH_RADIUS_ITERATION_LIST = new long[MoonriseConstants.MAX_VIEW_DISTANCE+2+1][]; + static { + for (int i = 0; i < SEARCH_RADIUS_ITERATION_LIST.length; ++i) { + // a BFS around -x, -z, +x, +z will give increasing manhatten distance +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/stream/ExternalChunkStreamMarker.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/stream/ExternalChunkStreamMarker.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7ef3dcca89ed7578c6c0f5565131889110063056 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/stream/ExternalChunkStreamMarker.java +@@ -0,0 +1,37 @@ ++package ca.spottedleaf.moonrise.patches.chunk_system.util.stream; ++ ++import java.io.DataInputStream; ++import java.io.FilterInputStream; ++import java.io.InputStream; ++import java.lang.reflect.Field; ++ ++/** ++ * Used to mark chunk data streams that are on external files ++ */ ++public class ExternalChunkStreamMarker extends DataInputStream { ++ ++ private static final Field IN_FIELD; ++ static { ++ Field field; ++ try { ++ field = FilterInputStream.class.getDeclaredField("in"); ++ field.setAccessible(true); ++ } catch (final Throwable throwable) { ++ field = null; ++ } ++ ++ IN_FIELD = field; ++ } ++ ++ private static InputStream getWrapped(final FilterInputStream in) { ++ try { ++ return (InputStream)IN_FIELD.get(in); ++ } catch (final Throwable throwable) { ++ return in; ++ } ++ } ++ ++ public ExternalChunkStreamMarker(final DataInputStream in) { ++ super(getWrapped(in)); ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java +index 748ab4d637ce463272bae4fdbab6842a27385126..3abd4ad6379c383c3a31931255292b42d9435694 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java +@@ -1,15 +1,58 @@ + package ca.spottedleaf.moonrise.patches.collisions; + ++import ca.spottedleaf.moonrise.common.util.WorldUtil; ++import ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemEntityGetter; ++import ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState; ++import ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity; ++import ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData; ++import ca.spottedleaf.moonrise.patches.collisions.shape.CollisionDiscreteVoxelShape; ++import ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape; ++import ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection; ++import it.unimi.dsi.fastutil.doubles.DoubleArrayList; ++import it.unimi.dsi.fastutil.doubles.DoubleList; ++import net.minecraft.core.BlockPos; ++import net.minecraft.core.Direction; ++import net.minecraft.util.Mth; ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.item.Item; ++import net.minecraft.world.level.Level; ++import net.minecraft.world.level.block.Blocks; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.border.WorldBorder; ++import net.minecraft.world.level.chunk.ChunkAccess; ++import net.minecraft.world.level.chunk.ChunkSource; ++import net.minecraft.world.level.chunk.LevelChunkSection; ++import net.minecraft.world.level.chunk.PalettedContainer; ++import net.minecraft.world.level.chunk.status.ChunkStatus; ++import net.minecraft.world.level.material.FluidState; ++import net.minecraft.world.phys.AABB; ++import net.minecraft.world.phys.Vec3; ++import net.minecraft.world.phys.shapes.ArrayVoxelShape; ++import net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape; ++import net.minecraft.world.phys.shapes.BooleanOp; ++import net.minecraft.world.phys.shapes.CollisionContext; ++import net.minecraft.world.phys.shapes.DiscreteVoxelShape; ++import net.minecraft.world.phys.shapes.EntityCollisionContext; ++import net.minecraft.world.phys.shapes.OffsetDoubleList; ++import net.minecraft.world.phys.shapes.Shapes; ++import net.minecraft.world.phys.shapes.SliceShape; ++import net.minecraft.world.phys.shapes.VoxelShape; ++import java.util.Arrays; ++import java.util.List; ++import java.util.Objects; ++import java.util.function.BiPredicate; ++import java.util.function.Predicate; ++ + public final class CollisionUtil { + + public static final double COLLISION_EPSILON = 1.0E-7; +- public static final it.unimi.dsi.fastutil.doubles.DoubleArrayList ZERO_ONE = it.unimi.dsi.fastutil.doubles.DoubleArrayList.wrap(new double[] { 0.0, 1.0 }); ++ public static final DoubleArrayList ZERO_ONE = DoubleArrayList.wrap(new double[] { 0.0, 1.0 }); + + public static boolean isSpecialCollidingBlock(final net.minecraft.world.level.block.state.BlockBehaviour.BlockStateBase block) { +- return block.hasLargeCollisionShape() || block.getBlock() == net.minecraft.world.level.block.Blocks.MOVING_PISTON; ++ return block.hasLargeCollisionShape() || block.getBlock() == Blocks.MOVING_PISTON; + } + +- public static boolean isEmpty(final net.minecraft.world.phys.AABB aabb) { ++ public static boolean isEmpty(final AABB aabb) { + return (aabb.maxX - aabb.minX) < COLLISION_EPSILON || (aabb.maxY - aabb.minY) < COLLISION_EPSILON || (aabb.maxZ - aabb.minZ) < COLLISION_EPSILON; + } + +@@ -18,11 +61,11 @@ public final class CollisionUtil { + return (maxX - minX) < COLLISION_EPSILON || (maxY - minY) < COLLISION_EPSILON || (maxZ - minZ) < COLLISION_EPSILON; + } + +- public static net.minecraft.world.phys.AABB getBoxForChunk(final int chunkX, final int chunkZ) { ++ public static AABB getBoxForChunk(final int chunkX, final int chunkZ) { + double x = (double)(chunkX << 4); + double z = (double)(chunkZ << 4); + // use a bounding box bigger than the chunk to prevent entities from entering it on move +- return new net.minecraft.world.phys.AABB(x - 3*COLLISION_EPSILON, Double.NEGATIVE_INFINITY, z - 3*COLLISION_EPSILON, ++ return new AABB(x - 3*COLLISION_EPSILON, Double.NEGATIVE_INFINITY, z - 3*COLLISION_EPSILON, + x + (16.0 + 3*COLLISION_EPSILON), Double.POSITIVE_INFINITY, z + (16.0 + 3*COLLISION_EPSILON)); + } + +@@ -43,21 +86,21 @@ public final class CollisionUtil { + (minZ1 - maxZ2) < -COLLISION_EPSILON && (maxZ1 - minZ2) > COLLISION_EPSILON; + } + +- public static boolean voxelShapeIntersect(final net.minecraft.world.phys.AABB box, final double minX, final double minY, final double minZ, ++ public static boolean voxelShapeIntersect(final AABB box, final double minX, final double minY, final double minZ, + final double maxX, final double maxY, final double maxZ) { + return (box.minX - maxX) < -COLLISION_EPSILON && (box.maxX - minX) > COLLISION_EPSILON && + (box.minY - maxY) < -COLLISION_EPSILON && (box.maxY - minY) > COLLISION_EPSILON && + (box.minZ - maxZ) < -COLLISION_EPSILON && (box.maxZ - minZ) > COLLISION_EPSILON; + } + +- public static boolean voxelShapeIntersect(final net.minecraft.world.phys.AABB box1, final net.minecraft.world.phys.AABB box2) { ++ public static boolean voxelShapeIntersect(final AABB box1, final AABB box2) { + return (box1.minX - box2.maxX) < -COLLISION_EPSILON && (box1.maxX - box2.minX) > COLLISION_EPSILON && + (box1.minY - box2.maxY) < -COLLISION_EPSILON && (box1.maxY - box2.minY) > COLLISION_EPSILON && + (box1.minZ - box2.maxZ) < -COLLISION_EPSILON && (box1.maxZ - box2.minZ) > COLLISION_EPSILON; + } + + // assume !isEmpty(target) && abs(source_move) >= COLLISION_EPSILON +- public static double collideX(final net.minecraft.world.phys.AABB target, final net.minecraft.world.phys.AABB source, final double source_move) { ++ public static double collideX(final AABB target, final AABB source, final double source_move) { + if ((source.minY - target.maxY) < -COLLISION_EPSILON && (source.maxY - target.minY) > COLLISION_EPSILON && + (source.minZ - target.maxZ) < -COLLISION_EPSILON && (source.maxZ - target.minZ) > COLLISION_EPSILON) { + if (source_move >= 0.0) { +@@ -78,7 +121,7 @@ public final class CollisionUtil { + } + + // assume !isEmpty(target) && abs(source_move) >= COLLISION_EPSILON +- public static double collideY(final net.minecraft.world.phys.AABB target, final net.minecraft.world.phys.AABB source, final double source_move) { ++ public static double collideY(final AABB target, final AABB source, final double source_move) { + if ((source.minX - target.maxX) < -COLLISION_EPSILON && (source.maxX - target.minX) > COLLISION_EPSILON && + (source.minZ - target.maxZ) < -COLLISION_EPSILON && (source.maxZ - target.minZ) > COLLISION_EPSILON) { + if (source_move >= 0.0) { +@@ -99,7 +142,7 @@ public final class CollisionUtil { + } + + // assume !isEmpty(target) && abs(source_move) >= COLLISION_EPSILON +- public static double collideZ(final net.minecraft.world.phys.AABB target, final net.minecraft.world.phys.AABB source, final double source_move) { ++ public static double collideZ(final AABB target, final AABB source, final double source_move) { + if ((source.minX - target.maxX) < -COLLISION_EPSILON && (source.maxX - target.minX) > COLLISION_EPSILON && + (source.minY - target.maxY) < -COLLISION_EPSILON && (source.maxY - target.minY) > COLLISION_EPSILON) { + if (source_move >= 0.0) { +@@ -121,7 +164,8 @@ public final class CollisionUtil { + + // startIndex and endIndex inclusive + // assumes indices are in range of array +- private static int findFloor(final double[] values, final double value, int startIndex, int endIndex) { ++ public static int findFloor(final double[] values, final double value, int startIndex, int endIndex) { ++ Objects.checkFromToIndex(startIndex, endIndex + 1, values.length); + do { + final int middle = (startIndex + endIndex) >>> 1; + final double middleVal = values[middle]; +@@ -136,7 +180,217 @@ public final class CollisionUtil { + return startIndex - 1; + } + +- public static boolean voxelShapeIntersectNoEmpty(final net.minecraft.world.phys.shapes.VoxelShape voxel, final net.minecraft.world.phys.AABB aabb) { ++ private static VoxelShape sliceShapeVanilla(final VoxelShape src, final Direction.Axis axis, ++ final int index) { ++ return new SliceShape(src, axis, index); ++ } ++ ++ private static DoubleList offsetList(final double[] src, final double by) { ++ final DoubleArrayList wrap = DoubleArrayList.wrap(src); ++ if (by == 0.0) { ++ return wrap; ++ } ++ return new OffsetDoubleList(wrap, by); ++ } ++ ++ private static VoxelShape sliceShapeOptimised(final VoxelShape src, final Direction.Axis axis, ++ final int index) { ++ // assume index in range ++ final double off_x = ((CollisionVoxelShape)src).moonrise$offsetX(); ++ final double off_y = ((CollisionVoxelShape)src).moonrise$offsetY(); ++ final double off_z = ((CollisionVoxelShape)src).moonrise$offsetZ(); ++ ++ final double[] coords_x = ((CollisionVoxelShape)src).moonrise$rootCoordinatesX(); ++ final double[] coords_y = ((CollisionVoxelShape)src).moonrise$rootCoordinatesY(); ++ final double[] coords_z = ((CollisionVoxelShape)src).moonrise$rootCoordinatesZ(); ++ ++ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)src).moonrise$getCachedVoxelData(); ++ ++ // note: size = coords.length - 1 ++ final int size_x = cached_shape_data.sizeX(); ++ final int size_y = cached_shape_data.sizeY(); ++ final int size_z = cached_shape_data.sizeZ(); ++ ++ final long[] bitset = cached_shape_data.voxelSet(); ++ ++ final DoubleList list_x; ++ final DoubleList list_y; ++ final DoubleList list_z; ++ final int shape_sx; ++ final int shape_ex; ++ final int shape_sy; ++ final int shape_ey; ++ final int shape_sz; ++ final int shape_ez; ++ ++ switch (axis) { ++ case X: { ++ // validate index ++ if (index < 0 || index >= size_x) { ++ return Shapes.empty(); ++ } ++ ++ // test if input is already "sliced" ++ if (coords_x.length == 2 && (coords_x[0] + off_x) == 0.0 && (coords_x[1] + off_x) == 1.0) { ++ return src; ++ } ++ ++ // test if result would be full box ++ if (coords_y.length == 2 && coords_z.length == 2 && ++ (coords_y[0] + off_y) == 0.0 && (coords_y[1] + off_y) == 1.0 && ++ (coords_z[0] + off_z) == 0.0 && (coords_z[1] + off_z) == 1.0) { ++ // note: size_y == size_z == 1 ++ final int bitIdx = 0 + 0*size_z + index*(size_z*size_y); ++ return (bitset[bitIdx >>> 6] & (1L << bitIdx)) == 0L ? Shapes.empty() : Shapes.block(); ++ } ++ ++ list_x = ZERO_ONE; ++ list_y = offsetList(coords_y, off_y); ++ list_z = offsetList(coords_z, off_z); ++ shape_sx = index; ++ shape_ex = index + 1; ++ shape_sy = 0; ++ shape_ey = size_y; ++ shape_sz = 0; ++ shape_ez = size_z; ++ ++ break; ++ } ++ case Y: { ++ // validate index ++ if (index < 0 || index >= size_y) { ++ return Shapes.empty(); ++ } ++ ++ // test if input is already "sliced" ++ if (coords_y.length == 2 && (coords_y[0] + off_y) == 0.0 && (coords_y[1] + off_y) == 1.0) { ++ return src; ++ } ++ ++ // test if result would be full box ++ if (coords_x.length == 2 && coords_z.length == 2 && ++ (coords_x[0] + off_x) == 0.0 && (coords_x[1] + off_x) == 1.0 && ++ (coords_z[0] + off_z) == 0.0 && (coords_z[1] + off_z) == 1.0) { ++ // note: size_x == size_z == 1 ++ final int bitIdx = 0 + index*size_z + 0*(size_z*size_y); ++ return (bitset[bitIdx >>> 6] & (1L << bitIdx)) == 0L ? Shapes.empty() : Shapes.block(); ++ } ++ ++ list_x = offsetList(coords_x, off_x); ++ list_y = ZERO_ONE; ++ list_z = offsetList(coords_z, off_z); ++ shape_sx = 0; ++ shape_ex = size_x; ++ shape_sy = index; ++ shape_ey = index + 1; ++ shape_sz = 0; ++ shape_ez = size_z; ++ ++ break; ++ } ++ case Z: { ++ // validate index ++ if (index < 0 || index >= size_z) { ++ return Shapes.empty(); ++ } ++ ++ // test if input is already "sliced" ++ if (coords_z.length == 2 && (coords_z[0] + off_z) == 0.0 && (coords_z[1] + off_z) == 1.0) { ++ return src; ++ } ++ ++ // test if result would be full box ++ if (coords_x.length == 2 && coords_y.length == 2 && ++ (coords_x[0] + off_x) == 0.0 && (coords_x[1] + off_x) == 1.0 && ++ (coords_y[0] + off_y) == 0.0 && (coords_y[1] + off_y) == 1.0) { ++ // note: size_x == size_y == 1 ++ final int bitIdx = index + 0*size_z + 0*(size_z*size_y); ++ return (bitset[bitIdx >>> 6] & (1L << bitIdx)) == 0L ? Shapes.empty() : Shapes.block(); ++ } ++ ++ list_x = offsetList(coords_x, off_x); ++ list_y = offsetList(coords_y, off_y); ++ list_z = ZERO_ONE; ++ shape_sx = 0; ++ shape_ex = size_x; ++ shape_sy = 0; ++ shape_ey = size_y; ++ shape_sz = index; ++ shape_ez = index + 1; ++ ++ break; ++ } ++ default: { ++ throw new IllegalStateException("Unknown axis: " + axis); ++ } ++ } ++ ++ final int local_len_x = shape_ex - shape_sx; ++ final int local_len_y = shape_ey - shape_sy; ++ final int local_len_z = shape_ez - shape_sz; ++ ++ final BitSetDiscreteVoxelShape shape = new BitSetDiscreteVoxelShape(local_len_x, local_len_y, local_len_z); ++ ++ final int bitset_mul_x = size_z*size_y; ++ final int idx_off = shape_sz + shape_sy*size_z + shape_sx*bitset_mul_x; ++ final int shape_mul_x = local_len_y*local_len_z; ++ for (int x = 0; x < local_len_x; ++x) { ++ boolean setX = false; ++ for (int y = 0; y < local_len_y; ++y) { ++ boolean setY = false; ++ for (int z = 0; z < local_len_z; ++z) { ++ final int unslicedIdx = idx_off + z + y*size_z + x*bitset_mul_x; ++ if ((bitset[unslicedIdx >>> 6] & (1L << unslicedIdx)) == 0L) { ++ continue; ++ } ++ ++ setY = true; ++ setX = true; ++ shape.zMin = Math.min(shape.zMin, z); ++ shape.zMax = Math.max(shape.zMax, z + 1); ++ ++ shape.storage.set( ++ z + y*local_len_z + x*shape_mul_x ++ ); ++ } ++ ++ if (setY) { ++ shape.yMin = Math.min(shape.yMin, y); ++ shape.yMax = Math.max(shape.yMax, y + 1); ++ } ++ } ++ if (setX) { ++ shape.xMin = Math.min(shape.xMin, x); ++ shape.xMax = Math.max(shape.xMax, x + 1); ++ } ++ } ++ ++ return shape.isEmpty() ? Shapes.empty() : new ArrayVoxelShape( ++ shape, list_x, list_y, list_z ++ ); ++ } ++ ++ private static final boolean DEBUG_SLICE_SHAPE = false; ++ ++ public static VoxelShape sliceShape(final VoxelShape src, final Direction.Axis axis, ++ final int index) { ++ final VoxelShape ret = sliceShapeOptimised(src, axis, index); ++ if (DEBUG_SLICE_SHAPE) { ++ final VoxelShape vanilla = sliceShapeVanilla(src, axis, index); ++ if (!equals(ret, vanilla)) { ++ // special case: SliceShape is not empty when it should be! ++ if (areAnyFull(ret.shape) || areAnyFull(vanilla.shape)) { ++ equals(ret, vanilla); ++ sliceShapeOptimised(src, axis, index); ++ throw new IllegalStateException("Slice shape mismatch"); ++ } ++ } ++ } ++ ++ return ret; ++ } ++ ++ public static boolean voxelShapeIntersectNoEmpty(final VoxelShape voxel, final AABB aabb) { + if (voxel.isEmpty()) { + return false; + } +@@ -144,15 +398,15 @@ public final class CollisionUtil { + // note: this function assumes that for any i in coords that coord[i + 1] - coord[i] > COLLISION_EPSILON is true + + // offsets that should be applied to coords +- final double off_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetX(); +- final double off_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetY(); +- final double off_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetZ(); ++ final double off_x = ((CollisionVoxelShape)voxel).moonrise$offsetX(); ++ final double off_y = ((CollisionVoxelShape)voxel).moonrise$offsetY(); ++ final double off_z = ((CollisionVoxelShape)voxel).moonrise$offsetZ(); + +- final double[] coords_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesX(); +- final double[] coords_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesY(); +- final double[] coords_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesZ(); ++ final double[] coords_x = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesX(); ++ final double[] coords_y = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesY(); ++ final double[] coords_z = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesZ(); + +- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cached_shape_data = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$getCachedVoxelData(); ++ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)voxel).moonrise$getCachedVoxelData(); + + // note: size = coords.length - 1 + final int size_x = cached_shape_data.sizeX(); +@@ -246,23 +500,23 @@ public final class CollisionUtil { + } + + // assume !target.isEmpty() && abs(source_move) >= COLLISION_EPSILON +- public static double collideX(final net.minecraft.world.phys.shapes.VoxelShape target, final net.minecraft.world.phys.AABB source, final double source_move) { +- final net.minecraft.world.phys.AABB single_aabb = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); ++ public static double collideX(final VoxelShape target, final AABB source, final double source_move) { ++ final AABB single_aabb = ((CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); + if (single_aabb != null) { + return collideX(single_aabb, source, source_move); + } + // note: this function assumes that for any i in coords that coord[i + 1] - coord[i] > COLLISION_EPSILON is true + + // offsets that should be applied to coords +- final double off_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetX(); +- final double off_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetY(); +- final double off_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetZ(); ++ final double off_x = ((CollisionVoxelShape)target).moonrise$offsetX(); ++ final double off_y = ((CollisionVoxelShape)target).moonrise$offsetY(); ++ final double off_z = ((CollisionVoxelShape)target).moonrise$offsetZ(); + +- final double[] coords_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesX(); +- final double[] coords_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesY(); +- final double[] coords_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); ++ final double[] coords_x = ((CollisionVoxelShape)target).moonrise$rootCoordinatesX(); ++ final double[] coords_y = ((CollisionVoxelShape)target).moonrise$rootCoordinatesY(); ++ final double[] coords_z = ((CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); + +- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cached_shape_data = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getCachedVoxelData(); ++ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)target).moonrise$getCachedVoxelData(); + + // note: size = coords.length - 1 + final int size_x = cached_shape_data.sizeX(); +@@ -404,23 +658,23 @@ public final class CollisionUtil { + } + } + +- public static double collideY(final net.minecraft.world.phys.shapes.VoxelShape target, final net.minecraft.world.phys.AABB source, final double source_move) { +- final net.minecraft.world.phys.AABB single_aabb = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); ++ public static double collideY(final VoxelShape target, final AABB source, final double source_move) { ++ final AABB single_aabb = ((CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); + if (single_aabb != null) { + return collideY(single_aabb, source, source_move); + } + // note: this function assumes that for any i in coords that coord[i + 1] - coord[i] > COLLISION_EPSILON is true + + // offsets that should be applied to coords +- final double off_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetX(); +- final double off_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetY(); +- final double off_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetZ(); ++ final double off_x = ((CollisionVoxelShape)target).moonrise$offsetX(); ++ final double off_y = ((CollisionVoxelShape)target).moonrise$offsetY(); ++ final double off_z = ((CollisionVoxelShape)target).moonrise$offsetZ(); + +- final double[] coords_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesX(); +- final double[] coords_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesY(); +- final double[] coords_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); ++ final double[] coords_x = ((CollisionVoxelShape)target).moonrise$rootCoordinatesX(); ++ final double[] coords_y = ((CollisionVoxelShape)target).moonrise$rootCoordinatesY(); ++ final double[] coords_z = ((CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); + +- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cached_shape_data = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getCachedVoxelData(); ++ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)target).moonrise$getCachedVoxelData(); + + // note: size = coords.length - 1 + final int size_x = cached_shape_data.sizeX(); +@@ -562,23 +816,23 @@ public final class CollisionUtil { + } + } + +- public static double collideZ(final net.minecraft.world.phys.shapes.VoxelShape target, final net.minecraft.world.phys.AABB source, final double source_move) { +- final net.minecraft.world.phys.AABB single_aabb = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); ++ public static double collideZ(final VoxelShape target, final AABB source, final double source_move) { ++ final AABB single_aabb = ((CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); + if (single_aabb != null) { + return collideZ(single_aabb, source, source_move); + } + // note: this function assumes that for any i in coords that coord[i + 1] - coord[i] > COLLISION_EPSILON is true + + // offsets that should be applied to coords +- final double off_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetX(); +- final double off_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetY(); +- final double off_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetZ(); ++ final double off_x = ((CollisionVoxelShape)target).moonrise$offsetX(); ++ final double off_y = ((CollisionVoxelShape)target).moonrise$offsetY(); ++ final double off_z = ((CollisionVoxelShape)target).moonrise$offsetZ(); + +- final double[] coords_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesX(); +- final double[] coords_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesY(); +- final double[] coords_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); ++ final double[] coords_x = ((CollisionVoxelShape)target).moonrise$rootCoordinatesX(); ++ final double[] coords_y = ((CollisionVoxelShape)target).moonrise$rootCoordinatesY(); ++ final double[] coords_z = ((CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); + +- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cached_shape_data = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getCachedVoxelData(); ++ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)target).moonrise$getCachedVoxelData(); + + // note: size = coords.length - 1 + final int size_x = cached_shape_data.sizeX(); +@@ -721,13 +975,13 @@ public final class CollisionUtil { + } + + // does not use epsilon +- public static boolean strictlyContains(final net.minecraft.world.phys.shapes.VoxelShape voxel, final net.minecraft.world.phys.Vec3 point) { ++ public static boolean strictlyContains(final VoxelShape voxel, final Vec3 point) { + return strictlyContains(voxel, point.x, point.y, point.z); + } + + // does not use epsilon +- public static boolean strictlyContains(final net.minecraft.world.phys.shapes.VoxelShape voxel, double x, double y, double z) { +- final net.minecraft.world.phys.AABB single_aabb = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$getSingleAABBRepresentation(); ++ public static boolean strictlyContains(final VoxelShape voxel, double x, double y, double z) { ++ final AABB single_aabb = ((CollisionVoxelShape)voxel).moonrise$getSingleAABBRepresentation(); + if (single_aabb != null) { + return single_aabb.contains(x, y, z); + } +@@ -738,15 +992,15 @@ public final class CollisionUtil { + } + + // offset input +- x -= ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetX(); +- y -= ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetY(); +- z -= ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetZ(); ++ x -= ((CollisionVoxelShape)voxel).moonrise$offsetX(); ++ y -= ((CollisionVoxelShape)voxel).moonrise$offsetY(); ++ z -= ((CollisionVoxelShape)voxel).moonrise$offsetZ(); + +- final double[] coords_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesX(); +- final double[] coords_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesY(); +- final double[] coords_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesZ(); ++ final double[] coords_x = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesX(); ++ final double[] coords_y = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesY(); ++ final double[] coords_z = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesZ(); + +- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cached_shape_data = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$getCachedVoxelData(); ++ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)voxel).moonrise$getCachedVoxelData(); + + // note: size = coords.length - 1 + final int size_x = cached_shape_data.sizeX(); +@@ -788,10 +1042,10 @@ public final class CollisionUtil { + return ((ft ? 1 : 0) << 1) | ((tf ? 1 : 0) << 2) | ((tt ? 1 : 0) << 3); + } + +- private static net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape merge(final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataFirst, final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataSecond, +- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedX, final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedY, +- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedZ, +- final int booleanOp) { ++ private static BitSetDiscreteVoxelShape merge(final CachedShapeData shapeDataFirst, final CachedShapeData shapeDataSecond, ++ final MergedVoxelCoordinateList mergedX, final MergedVoxelCoordinateList mergedY, ++ final MergedVoxelCoordinateList mergedZ, ++ final int booleanOp) { + final int sizeX = mergedX.voxels; + final int sizeY = mergedY.voxels; + final int sizeZ = mergedZ.voxels; +@@ -806,7 +1060,7 @@ public final class CollisionUtil { + final int s2Mul2 = s2Mul1 * shapeDataSecond.sizeY(); + + // note: indices may contain -1, but nothing > size +- final net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape ret = new net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape(sizeX, sizeY, sizeZ); ++ final BitSetDiscreteVoxelShape ret = new BitSetDiscreteVoxelShape(sizeX, sizeY, sizeZ); + + boolean empty = true; + +@@ -823,10 +1077,11 @@ public final class CollisionUtil { + final int s1z = mergedZ.firstIndices[idxZ]; + final int s2z = mergedZ.secondIndices[idxZ]; + +- int idx; ++ int idx1; ++ int idx2; + +- final int isS1Full = (s1x | s1y | s1z) < 0 ? 0 : (int)((s1Voxels[(idx = s1z + s1y*s1Mul1 + s1x*s1Mul2) >>> 6] >>> idx) & 1L); +- final int isS2Full = (s2x | s2y | s2z) < 0 ? 0 : (int)((s2Voxels[(idx = s2z + s2y*s2Mul1 + s2x*s2Mul2) >>> 6] >>> idx) & 1L); ++ final int isS1Full = (s1x | s1y | s1z) < 0 ? 0 : (int)((s1Voxels[(idx1 = s1z + s1y*s1Mul1 + s1x*s1Mul2) >>> 6] >>> idx1) & 1L); ++ final int isS2Full = (s2x | s2y | s2z) < 0 ? 0 : (int)((s2Voxels[(idx2 = s2z + s2y*s2Mul1 + s2x*s2Mul2) >>> 6] >>> idx2) & 1L); + + // idx ff -> 0 + // idx ft -> 1 +@@ -861,9 +1116,9 @@ public final class CollisionUtil { + return empty ? null : ret; + } + +- private static boolean isMergeEmpty(final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataFirst, final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataSecond, +- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedX, final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedY, +- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedZ, ++ private static boolean isMergeEmpty(final CachedShapeData shapeDataFirst, final CachedShapeData shapeDataSecond, ++ final MergedVoxelCoordinateList mergedX, final MergedVoxelCoordinateList mergedY, ++ final MergedVoxelCoordinateList mergedZ, + final int booleanOp) { + final int sizeX = mergedX.voxels; + final int sizeY = mergedY.voxels; +@@ -889,10 +1144,11 @@ public final class CollisionUtil { + final int s1z = mergedZ.firstIndices[idxZ]; + final int s2z = mergedZ.secondIndices[idxZ]; + +- int idx; ++ int idx1; ++ int idx2; + +- final int isS1Full = (s1x | s1y | s1z) < 0 ? 0 : (int)((s1Voxels[(idx = s1z + s1y*s1Mul1 + s1x*s1Mul2) >>> 6] >>> idx) & 1L); +- final int isS2Full = (s2x | s2y | s2z) < 0 ? 0 : (int)((s2Voxels[(idx = s2z + s2y*s2Mul1 + s2x*s2Mul2) >>> 6] >>> idx) & 1L); ++ final int isS1Full = (s1x | s1y | s1z) < 0 ? 0 : (int)((s1Voxels[(idx1 = s1z + s1y*s1Mul1 + s1x*s1Mul2) >>> 6] >>> idx1) & 1L); ++ final int isS2Full = (s2x | s2y | s2z) < 0 ? 0 : (int)((s2Voxels[(idx2 = s2z + s2y*s2Mul1 + s2x*s2Mul2) >>> 6] >>> idx2) & 1L); + + // idx ff -> 0 + // idx ft -> 1 +@@ -911,11 +1167,11 @@ public final class CollisionUtil { + return true; + } + +- public static net.minecraft.world.phys.shapes.VoxelShape joinOptimized(final net.minecraft.world.phys.shapes.VoxelShape first, final net.minecraft.world.phys.shapes.VoxelShape second, final net.minecraft.world.phys.shapes.BooleanOp operator) { ++ public static VoxelShape joinOptimized(final VoxelShape first, final VoxelShape second, final BooleanOp operator) { + return joinUnoptimized(first, second, operator).optimize(); + } + +- public static net.minecraft.world.phys.shapes.VoxelShape joinUnoptimized(final net.minecraft.world.phys.shapes.VoxelShape first, final net.minecraft.world.phys.shapes.VoxelShape second, final net.minecraft.world.phys.shapes.BooleanOp operator) { ++ public static VoxelShape joinUnoptimized(final VoxelShape first, final VoxelShape second, final BooleanOp operator) { + final boolean ff = operator.apply(false, false); + if (ff) { + // technically, should be an infinite box but that's clearly an error +@@ -925,23 +1181,23 @@ public final class CollisionUtil { + final boolean tt = operator.apply(true, true); + + if (first == second) { +- return tt ? first : net.minecraft.world.phys.shapes.Shapes.empty(); ++ return tt ? first : Shapes.empty(); + } + + final boolean ft = operator.apply(false, true); + final boolean tf = operator.apply(true, false); + + if (first.isEmpty()) { +- return ft ? second : net.minecraft.world.phys.shapes.Shapes.empty(); ++ return ft ? second : Shapes.empty(); + } + if (second.isEmpty()) { +- return tf ? first : net.minecraft.world.phys.shapes.Shapes.empty(); ++ return tf ? first : Shapes.empty(); + } + + if (!tt) { + // try to check for no intersection, since tt = false +- final net.minecraft.world.phys.AABB aabbF = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$getSingleAABBRepresentation(); +- final net.minecraft.world.phys.AABB aabbS = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$getSingleAABBRepresentation(); ++ final AABB aabbF = ((CollisionVoxelShape)first).moonrise$getSingleAABBRepresentation(); ++ final AABB aabbS = ((CollisionVoxelShape)second).moonrise$getSingleAABBRepresentation(); + + final boolean intersect; + +@@ -962,7 +1218,7 @@ public final class CollisionUtil { + + if (!intersect) { + if (!tf & !ft) { +- return net.minecraft.world.phys.shapes.Shapes.empty(); ++ return Shapes.empty(); + } + if (!tf | !ft) { + return tf ? first : second; +@@ -970,50 +1226,50 @@ public final class CollisionUtil { + } + } + +- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedX = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( +- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesX(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetX(), +- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesX(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetX(), ++ final MergedVoxelCoordinateList mergedX = MergedVoxelCoordinateList.merge( ++ ((CollisionVoxelShape)first).moonrise$rootCoordinatesX(), ((CollisionVoxelShape)first).moonrise$offsetX(), ++ ((CollisionVoxelShape)second).moonrise$rootCoordinatesX(), ((CollisionVoxelShape)second).moonrise$offsetX(), + ft, tf + ); +- if (mergedX == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { +- return net.minecraft.world.phys.shapes.Shapes.empty(); ++ if (mergedX == null) { ++ return Shapes.empty(); + } +- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedY = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( +- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesY(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetY(), +- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesY(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetY(), ++ final MergedVoxelCoordinateList mergedY = MergedVoxelCoordinateList.merge( ++ ((CollisionVoxelShape)first).moonrise$rootCoordinatesY(), ((CollisionVoxelShape)first).moonrise$offsetY(), ++ ((CollisionVoxelShape)second).moonrise$rootCoordinatesY(), ((CollisionVoxelShape)second).moonrise$offsetY(), + ft, tf + ); +- if (mergedY == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { +- return net.minecraft.world.phys.shapes.Shapes.empty(); ++ if (mergedY == null) { ++ return Shapes.empty(); + } +- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedZ = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( +- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesZ(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetZ(), +- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesZ(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetZ(), ++ final MergedVoxelCoordinateList mergedZ = MergedVoxelCoordinateList.merge( ++ ((CollisionVoxelShape)first).moonrise$rootCoordinatesZ(), ((CollisionVoxelShape)first).moonrise$offsetZ(), ++ ((CollisionVoxelShape)second).moonrise$rootCoordinatesZ(), ((CollisionVoxelShape)second).moonrise$offsetZ(), + ft, tf + ); +- if (mergedZ == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { +- return net.minecraft.world.phys.shapes.Shapes.empty(); ++ if (mergedZ == null) { ++ return Shapes.empty(); + } + +- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataFirst = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$getCachedVoxelData(); +- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataSecond = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$getCachedVoxelData(); ++ final CachedShapeData shapeDataFirst = ((CollisionVoxelShape)first).moonrise$getCachedVoxelData(); ++ final CachedShapeData shapeDataSecond = ((CollisionVoxelShape)second).moonrise$getCachedVoxelData(); + +- final net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape mergedShape = merge( ++ final BitSetDiscreteVoxelShape mergedShape = merge( + shapeDataFirst, shapeDataSecond, + mergedX, mergedY, mergedZ, + makeBitset(ft, tf, tt) + ); + + if (mergedShape == null) { +- return net.minecraft.world.phys.shapes.Shapes.empty(); ++ return Shapes.empty(); + } + +- return new net.minecraft.world.phys.shapes.ArrayVoxelShape( ++ return new ArrayVoxelShape( + mergedShape, mergedX.wrapCoords(), mergedY.wrapCoords(), mergedZ.wrapCoords() + ); + } + +- public static boolean isJoinNonEmpty(final net.minecraft.world.phys.shapes.VoxelShape first, final net.minecraft.world.phys.shapes.VoxelShape second, final net.minecraft.world.phys.shapes.BooleanOp operator) { ++ public static boolean isJoinNonEmpty(final VoxelShape first, final VoxelShape second, final BooleanOp operator) { + final boolean ff = operator.apply(false, false); + if (ff) { + // technically, should be an infinite box but that's clearly an error +@@ -1035,8 +1291,8 @@ public final class CollisionUtil { + final boolean tf = operator.apply(true, false); + + // try to check intersection +- final net.minecraft.world.phys.AABB aabbF = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$getSingleAABBRepresentation(); +- final net.minecraft.world.phys.AABB aabbS = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$getSingleAABBRepresentation(); ++ final AABB aabbF = ((CollisionVoxelShape)first).moonrise$getSingleAABBRepresentation(); ++ final AABB aabbS = ((CollisionVoxelShape)second).moonrise$getSingleAABBRepresentation(); + + final boolean intersect; + +@@ -1068,33 +1324,33 @@ public final class CollisionUtil { + } + } + +- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedX = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( +- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesX(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetX(), +- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesX(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetX(), ++ final MergedVoxelCoordinateList mergedX = MergedVoxelCoordinateList.merge( ++ ((CollisionVoxelShape)first).moonrise$rootCoordinatesX(), ((CollisionVoxelShape)first).moonrise$offsetX(), ++ ((CollisionVoxelShape)second).moonrise$rootCoordinatesX(), ((CollisionVoxelShape)second).moonrise$offsetX(), + ft, tf + ); +- if (mergedX == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { ++ if (mergedX == null) { + return false; + } +- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedY = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( +- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesY(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetY(), +- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesY(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetY(), ++ final MergedVoxelCoordinateList mergedY = MergedVoxelCoordinateList.merge( ++ ((CollisionVoxelShape)first).moonrise$rootCoordinatesY(), ((CollisionVoxelShape)first).moonrise$offsetY(), ++ ((CollisionVoxelShape)second).moonrise$rootCoordinatesY(), ((CollisionVoxelShape)second).moonrise$offsetY(), + ft, tf + ); +- if (mergedY == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { ++ if (mergedY == null) { + return false; + } +- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedZ = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( +- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesZ(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetZ(), +- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesZ(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetZ(), ++ final MergedVoxelCoordinateList mergedZ = MergedVoxelCoordinateList.merge( ++ ((CollisionVoxelShape)first).moonrise$rootCoordinatesZ(), ((CollisionVoxelShape)first).moonrise$offsetZ(), ++ ((CollisionVoxelShape)second).moonrise$rootCoordinatesZ(), ((CollisionVoxelShape)second).moonrise$offsetZ(), + ft, tf + ); +- if (mergedZ == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { ++ if (mergedZ == null) { + return false; + } + +- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataFirst = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$getCachedVoxelData(); +- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataSecond = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$getCachedVoxelData(); ++ final CachedShapeData shapeDataFirst = ((CollisionVoxelShape)first).moonrise$getCachedVoxelData(); ++ final CachedShapeData shapeDataSecond = ((CollisionVoxelShape)second).moonrise$getCachedVoxelData(); + + return !isMergeEmpty( + shapeDataFirst, shapeDataSecond, +@@ -1112,10 +1368,6 @@ public final class CollisionUtil { + } + } + +- private static final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList EMPTY = new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList( +- new double[] { 0.0 }, 0.0, new int[0], new int[0], 0 +- ); +- + private static int[] getIndices(final int length) { + final int[] ret = new int[length]; + +@@ -1142,25 +1394,25 @@ public final class CollisionUtil { + this.voxels = voxels; + } + +- public it.unimi.dsi.fastutil.doubles.DoubleList wrapCoords() { ++ public DoubleList wrapCoords() { + if (this.coordinateOffset == 0.0) { +- return it.unimi.dsi.fastutil.doubles.DoubleArrayList.wrap(this.coordinates, this.voxels + 1); ++ return DoubleArrayList.wrap(this.coordinates, this.voxels + 1); + } +- return new net.minecraft.world.phys.shapes.OffsetDoubleList(it.unimi.dsi.fastutil.doubles.DoubleArrayList.wrap(this.coordinates, this.voxels + 1), this.coordinateOffset); ++ return new OffsetDoubleList(DoubleArrayList.wrap(this.coordinates, this.voxels + 1), this.coordinateOffset); + } + + // assume coordinates.length > 1 +- public static ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList getForSingle(final double[] coordinates, final double offset) { ++ public static MergedVoxelCoordinateList getForSingle(final double[] coordinates, final double offset) { + final int voxels = coordinates.length - 1; + final int[] indices = voxels < SIMPLE_INDICES_CACHE.length ? SIMPLE_INDICES_CACHE[voxels] : getIndices(voxels); + +- return new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList(coordinates, offset, indices, indices, voxels); ++ return new MergedVoxelCoordinateList(coordinates, offset, indices, indices, voxels); + } + + // assume coordinates.length > 1 +- public static ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList merge(final double[] firstCoordinates, final double firstOffset, +- final double[] secondCoordinates, final double secondOffset, +- final boolean ft, final boolean tf) { ++ public static MergedVoxelCoordinateList merge(final double[] firstCoordinates, final double firstOffset, ++ final double[] secondCoordinates, final double secondOffset, ++ final boolean ft, final boolean tf) { + if (firstCoordinates == secondCoordinates && firstOffset == secondOffset) { + return getForSingle(firstCoordinates, firstOffset); + } +@@ -1250,13 +1502,13 @@ public final class CollisionUtil { + } + } + +- return resultSize <= 1 ? EMPTY : new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList(coordinates, 0.0, firstIndices, secondIndices, resultSize - 1); ++ return resultSize <= 1 ? null : new MergedVoxelCoordinateList(coordinates, 0.0, firstIndices, secondIndices, resultSize - 1); + } + } + +- public static boolean equals(final net.minecraft.world.phys.shapes.DiscreteVoxelShape shape1, final net.minecraft.world.phys.shapes.DiscreteVoxelShape shape2) { +- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cachedShapeData1 = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionDiscreteVoxelShape)shape1).moonrise$getOrCreateCachedShapeData(); +- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cachedShapeData2 = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionDiscreteVoxelShape)shape2).moonrise$getOrCreateCachedShapeData(); ++ public static boolean equals(final DiscreteVoxelShape shape1, final DiscreteVoxelShape shape2) { ++ final CachedShapeData cachedShapeData1 = ((CollisionDiscreteVoxelShape)shape1).moonrise$getOrCreateCachedShapeData(); ++ final CachedShapeData cachedShapeData2 = ((CollisionDiscreteVoxelShape)shape2).moonrise$getOrCreateCachedShapeData(); + + final boolean isEmpty1 = cachedShapeData1.isEmpty(); + final boolean isEmpty2 = cachedShapeData2.isEmpty(); +@@ -1265,7 +1517,7 @@ public final class CollisionUtil { + return true; + } else if (isEmpty1 ^ isEmpty2) { + return false; +- } ++ } // else: isEmpty1 = isEmpty2 = false + + if (cachedShapeData1.hasSingleAABB() != cachedShapeData2.hasSingleAABB()) { + return false; +@@ -1281,153 +1533,237 @@ public final class CollisionUtil { + return false; + } + +- return java.util.Arrays.equals(cachedShapeData1.voxelSet(), cachedShapeData2.voxelSet()); ++ return Arrays.equals(cachedShapeData1.voxelSet(), cachedShapeData2.voxelSet()); + } + + // useful only for testing +- public static boolean equals(final net.minecraft.world.phys.shapes.VoxelShape shape1, final net.minecraft.world.phys.shapes.VoxelShape shape2) { ++ public static boolean equals(final VoxelShape shape1, final VoxelShape shape2) { ++ if (shape1.isEmpty() & shape2.isEmpty()) { ++ return true; ++ } else if (shape1.isEmpty() ^ shape2.isEmpty()) { ++ return false; ++ } ++ + if (!equals(shape1.shape, shape2.shape)) { + return false; + } + +- return shape1.getCoords(net.minecraft.core.Direction.Axis.X).equals(shape2.getCoords(net.minecraft.core.Direction.Axis.X)) && +- shape1.getCoords(net.minecraft.core.Direction.Axis.Y).equals(shape2.getCoords(net.minecraft.core.Direction.Axis.Y)) && +- shape1.getCoords(net.minecraft.core.Direction.Axis.Z).equals(shape2.getCoords(net.minecraft.core.Direction.Axis.Z)); ++ return shape1.getCoords(Direction.Axis.X).equals(shape2.getCoords(Direction.Axis.X)) && ++ shape1.getCoords(Direction.Axis.Y).equals(shape2.getCoords(Direction.Axis.Y)) && ++ shape1.getCoords(Direction.Axis.Z).equals(shape2.getCoords(Direction.Axis.Z)); ++ } ++ ++ public static boolean areAnyFull(final DiscreteVoxelShape shape) { ++ if (shape.isEmpty()) { ++ return false; ++ } ++ ++ final int sizeX = shape.getXSize(); ++ final int sizeY = shape.getYSize(); ++ final int sizeZ = shape.getZSize(); ++ ++ for (int x = 0; x < sizeX; ++x) { ++ for (int y = 0; y < sizeY; ++y) { ++ for (int z = 0; z < sizeZ; ++z) { ++ if (shape.isFull(x, y, z)) { ++ return true; ++ } ++ } ++ } ++ } ++ ++ return false; ++ } ++ ++ public static String shapeMismatch(final DiscreteVoxelShape shape1, final DiscreteVoxelShape shape2) { ++ final CachedShapeData cachedShapeData1 = ((CollisionDiscreteVoxelShape)shape1).moonrise$getOrCreateCachedShapeData(); ++ final CachedShapeData cachedShapeData2 = ((CollisionDiscreteVoxelShape)shape2).moonrise$getOrCreateCachedShapeData(); ++ ++ final boolean isEmpty1 = cachedShapeData1.isEmpty(); ++ final boolean isEmpty2 = cachedShapeData2.isEmpty(); ++ ++ if (isEmpty1 & isEmpty2) { ++ return null; ++ } else if (isEmpty1 ^ isEmpty2) { ++ return null; ++ } // else: isEmpty1 = isEmpty2 = false ++ ++ if (cachedShapeData1.sizeX() != cachedShapeData2.sizeX()) { ++ return "size x: " + cachedShapeData1.sizeX() + " != " + cachedShapeData2.sizeX(); ++ } ++ if (cachedShapeData1.sizeY() != cachedShapeData2.sizeY()) { ++ return "size y: " + cachedShapeData1.sizeY() + " != " + cachedShapeData2.sizeY(); ++ } ++ if (cachedShapeData1.sizeZ() != cachedShapeData2.sizeZ()) { ++ return "size z: " + cachedShapeData1.sizeZ() + " != " + cachedShapeData2.sizeZ(); ++ } ++ ++ final StringBuilder ret = new StringBuilder(); ++ ++ final int sizeX = cachedShapeData1.sizeX();; ++ final int sizeY = cachedShapeData1.sizeY(); ++ final int sizeZ = cachedShapeData1.sizeZ(); ++ ++ boolean first = true; ++ ++ for (int x = 0; x < sizeX; ++x) { ++ for (int y = 0; y < sizeY; ++y) { ++ for (int z = 0; z < sizeZ; ++z) { ++ final boolean isFull1 = shape1.isFull(x, y, z); ++ final boolean isFull2 = shape2.isFull(x, y, z); ++ ++ if (isFull1 == isFull2) { ++ continue; ++ } ++ ++ if (first) { ++ first = false; ++ } else { ++ ret.append(", "); ++ } ++ ++ ret.append("(").append(x).append(",").append(y).append(",").append(z) ++ .append("): shape1: ").append(isFull1).append(", shape2: ").append(isFull2); ++ } ++ } ++ } ++ ++ return ret.isEmpty() ? null : ret.toString(); + } + +- public static net.minecraft.world.phys.AABB offsetX(final net.minecraft.world.phys.AABB box, final double dx) { +- return new net.minecraft.world.phys.AABB(box.minX + dx, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); ++ public static AABB offsetX(final AABB box, final double dx) { ++ return new AABB(box.minX + dx, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); + } + +- public static net.minecraft.world.phys.AABB offsetY(final net.minecraft.world.phys.AABB box, final double dy) { +- return new net.minecraft.world.phys.AABB(box.minX, box.minY + dy, box.minZ, box.maxX, box.maxY + dy, box.maxZ); ++ public static AABB offsetY(final AABB box, final double dy) { ++ return new AABB(box.minX, box.minY + dy, box.minZ, box.maxX, box.maxY + dy, box.maxZ); + } + +- public static net.minecraft.world.phys.AABB offsetZ(final net.minecraft.world.phys.AABB box, final double dz) { +- return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ + dz, box.maxX, box.maxY, box.maxZ + dz); ++ public static AABB offsetZ(final AABB box, final double dz) { ++ return new AABB(box.minX, box.minY, box.minZ + dz, box.maxX, box.maxY, box.maxZ + dz); + } + +- public static net.minecraft.world.phys.AABB expandRight(final net.minecraft.world.phys.AABB box, final double dx) { // dx > 0.0 +- return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); ++ public static AABB expandRight(final AABB box, final double dx) { // dx > 0.0 ++ return new AABB(box.minX, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); + } + +- public static net.minecraft.world.phys.AABB expandLeft(final net.minecraft.world.phys.AABB box, final double dx) { // dx < 0.0 +- return new net.minecraft.world.phys.AABB(box.minX - dx, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ); ++ public static AABB expandLeft(final AABB box, final double dx) { // dx < 0.0 ++ return new AABB(box.minX - dx, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ); + } + +- public static net.minecraft.world.phys.AABB expandUpwards(final net.minecraft.world.phys.AABB box, final double dy) { // dy > 0.0 +- return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ, box.maxX, box.maxY + dy, box.maxZ); ++ public static AABB expandUpwards(final AABB box, final double dy) { // dy > 0.0 ++ return new AABB(box.minX, box.minY, box.minZ, box.maxX, box.maxY + dy, box.maxZ); + } + +- public static net.minecraft.world.phys.AABB expandDownwards(final net.minecraft.world.phys.AABB box, final double dy) { // dy < 0.0 +- return new net.minecraft.world.phys.AABB(box.minX, box.minY - dy, box.minZ, box.maxX, box.maxY, box.maxZ); ++ public static AABB expandDownwards(final AABB box, final double dy) { // dy < 0.0 ++ return new AABB(box.minX, box.minY - dy, box.minZ, box.maxX, box.maxY, box.maxZ); + } + +- public static net.minecraft.world.phys.AABB expandForwards(final net.minecraft.world.phys.AABB box, final double dz) { // dz > 0.0 +- return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ + dz); ++ public static AABB expandForwards(final AABB box, final double dz) { // dz > 0.0 ++ return new AABB(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ + dz); + } + +- public static net.minecraft.world.phys.AABB expandBackwards(final net.minecraft.world.phys.AABB box, final double dz) { // dz < 0.0 +- return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ - dz, box.maxX, box.maxY, box.maxZ); ++ public static AABB expandBackwards(final AABB box, final double dz) { // dz < 0.0 ++ return new AABB(box.minX, box.minY, box.minZ - dz, box.maxX, box.maxY, box.maxZ); + } + +- public static net.minecraft.world.phys.AABB cutRight(final net.minecraft.world.phys.AABB box, final double dx) { // dx > 0.0 +- return new net.minecraft.world.phys.AABB(box.maxX, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); ++ public static AABB cutRight(final AABB box, final double dx) { // dx > 0.0 ++ return new AABB(box.maxX, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); + } + +- public static net.minecraft.world.phys.AABB cutLeft(final net.minecraft.world.phys.AABB box, final double dx) { // dx < 0.0 +- return new net.minecraft.world.phys.AABB(box.minX + dx, box.minY, box.minZ, box.minX, box.maxY, box.maxZ); ++ public static AABB cutLeft(final AABB box, final double dx) { // dx < 0.0 ++ return new AABB(box.minX + dx, box.minY, box.minZ, box.minX, box.maxY, box.maxZ); + } + +- public static net.minecraft.world.phys.AABB cutUpwards(final net.minecraft.world.phys.AABB box, final double dy) { // dy > 0.0 +- return new net.minecraft.world.phys.AABB(box.minX, box.maxY, box.minZ, box.maxX, box.maxY + dy, box.maxZ); ++ public static AABB cutUpwards(final AABB box, final double dy) { // dy > 0.0 ++ return new AABB(box.minX, box.maxY, box.minZ, box.maxX, box.maxY + dy, box.maxZ); + } + +- public static net.minecraft.world.phys.AABB cutDownwards(final net.minecraft.world.phys.AABB box, final double dy) { // dy < 0.0 +- return new net.minecraft.world.phys.AABB(box.minX, box.minY + dy, box.minZ, box.maxX, box.minY, box.maxZ); ++ public static AABB cutDownwards(final AABB box, final double dy) { // dy < 0.0 ++ return new AABB(box.minX, box.minY + dy, box.minZ, box.maxX, box.minY, box.maxZ); + } + +- public static net.minecraft.world.phys.AABB cutForwards(final net.minecraft.world.phys.AABB box, final double dz) { // dz > 0.0 +- return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.maxZ, box.maxX, box.maxY, box.maxZ + dz); ++ public static AABB cutForwards(final AABB box, final double dz) { // dz > 0.0 ++ return new AABB(box.minX, box.minY, box.maxZ, box.maxX, box.maxY, box.maxZ + dz); + } + +- public static net.minecraft.world.phys.AABB cutBackwards(final net.minecraft.world.phys.AABB box, final double dz) { // dz < 0.0 +- return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ + dz, box.maxX, box.maxY, box.minZ); ++ public static AABB cutBackwards(final AABB box, final double dz) { // dz < 0.0 ++ return new AABB(box.minX, box.minY, box.minZ + dz, box.maxX, box.maxY, box.minZ); + } + +- public static double performAABBCollisionsX(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { ++ public static double performAABBCollisionsX(final AABB currentBoundingBox, double value, final List potentialCollisions) { + for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { + if (Math.abs(value) < COLLISION_EPSILON) { + return 0.0; + } +- final net.minecraft.world.phys.AABB target = potentialCollisions.get(i); ++ final AABB target = potentialCollisions.get(i); + value = collideX(target, currentBoundingBox, value); + } + +- return value; ++ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; + } + +- public static double performAABBCollisionsY(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { ++ public static double performAABBCollisionsY(final AABB currentBoundingBox, double value, final List potentialCollisions) { + for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { + if (Math.abs(value) < COLLISION_EPSILON) { + return 0.0; + } +- final net.minecraft.world.phys.AABB target = potentialCollisions.get(i); ++ final AABB target = potentialCollisions.get(i); + value = collideY(target, currentBoundingBox, value); + } + +- return value; ++ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; + } + +- public static double performAABBCollisionsZ(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { ++ public static double performAABBCollisionsZ(final AABB currentBoundingBox, double value, final List potentialCollisions) { + for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { + if (Math.abs(value) < COLLISION_EPSILON) { + return 0.0; + } +- final net.minecraft.world.phys.AABB target = potentialCollisions.get(i); ++ final AABB target = potentialCollisions.get(i); + value = collideZ(target, currentBoundingBox, value); + } + +- return value; ++ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; + } + +- public static double performVoxelCollisionsX(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { ++ public static double performVoxelCollisionsX(final AABB currentBoundingBox, double value, final List potentialCollisions) { + for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { + if (Math.abs(value) < COLLISION_EPSILON) { + return 0.0; + } +- final net.minecraft.world.phys.shapes.VoxelShape target = potentialCollisions.get(i); ++ final VoxelShape target = potentialCollisions.get(i); + value = collideX(target, currentBoundingBox, value); + } + +- return value; ++ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; + } + +- public static double performVoxelCollisionsY(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { ++ public static double performVoxelCollisionsY(final AABB currentBoundingBox, double value, final List potentialCollisions) { + for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { + if (Math.abs(value) < COLLISION_EPSILON) { + return 0.0; + } +- final net.minecraft.world.phys.shapes.VoxelShape target = potentialCollisions.get(i); ++ final VoxelShape target = potentialCollisions.get(i); + value = collideY(target, currentBoundingBox, value); + } + +- return value; ++ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; + } + +- public static double performVoxelCollisionsZ(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { ++ public static double performVoxelCollisionsZ(final AABB currentBoundingBox, double value, final List potentialCollisions) { + for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { + if (Math.abs(value) < COLLISION_EPSILON) { + return 0.0; + } +- final net.minecraft.world.phys.shapes.VoxelShape target = potentialCollisions.get(i); ++ final VoxelShape target = potentialCollisions.get(i); + value = collideZ(target, currentBoundingBox, value); + } + +- return value; ++ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; + } + +- public static net.minecraft.world.phys.Vec3 performVoxelCollisions(final net.minecraft.world.phys.Vec3 moveVector, net.minecraft.world.phys.AABB axisalignedbb, final java.util.List potentialCollisions) { ++ public static Vec3 performVoxelCollisions(final Vec3 moveVector, AABB axisalignedbb, final List potentialCollisions) { + double x = moveVector.x; + double y = moveVector.y; + double z = moveVector.z; +@@ -1459,10 +1795,10 @@ public final class CollisionUtil { + z = performVoxelCollisionsZ(axisalignedbb, z, potentialCollisions); + } + +- return new net.minecraft.world.phys.Vec3(x, y, z); ++ return new Vec3(x, y, z); + } + +- public static net.minecraft.world.phys.Vec3 performAABBCollisions(final net.minecraft.world.phys.Vec3 moveVector, net.minecraft.world.phys.AABB axisalignedbb, final java.util.List potentialCollisions) { ++ public static Vec3 performAABBCollisions(final Vec3 moveVector, AABB axisalignedbb, final List potentialCollisions) { + double x = moveVector.x; + double y = moveVector.y; + double z = moveVector.z; +@@ -1494,12 +1830,12 @@ public final class CollisionUtil { + z = performAABBCollisionsZ(axisalignedbb, z, potentialCollisions); + } + +- return new net.minecraft.world.phys.Vec3(x, y, z); ++ return new Vec3(x, y, z); + } + +- public static net.minecraft.world.phys.Vec3 performCollisions(final net.minecraft.world.phys.Vec3 moveVector, net.minecraft.world.phys.AABB axisalignedbb, +- final java.util.List voxels, +- final java.util.List aabbs) { ++ public static Vec3 performCollisions(final Vec3 moveVector, AABB axisalignedbb, ++ final List voxels, ++ final List aabbs) { + if (voxels.isEmpty()) { + // fast track only AABBs + return performAABBCollisions(moveVector, axisalignedbb, aabbs); +@@ -1540,14 +1876,14 @@ public final class CollisionUtil { + z = performVoxelCollisionsZ(axisalignedbb, z, voxels); + } + +- return new net.minecraft.world.phys.Vec3(x, y, z); ++ return new Vec3(x, y, z); + } + +- public static boolean isCollidingWithBorder(final net.minecraft.world.level.border.WorldBorder worldborder, final net.minecraft.world.phys.AABB boundingBox) { ++ public static boolean isCollidingWithBorder(final WorldBorder worldborder, final AABB boundingBox) { + return isCollidingWithBorder(worldborder, boundingBox.minX, boundingBox.maxX, boundingBox.minZ, boundingBox.maxZ); + } + +- public static boolean isCollidingWithBorder(final net.minecraft.world.level.border.WorldBorder worldborder, ++ public static boolean isCollidingWithBorder(final WorldBorder worldborder, + final double boxMinX, final double boxMaxX, + final double boxMinZ, final double boxMaxZ) { + final double borderMinX = Math.floor(worldborder.getMinX()); // -X +@@ -1557,8 +1893,8 @@ public final class CollisionUtil { + final double borderMaxZ = Math.ceil(worldborder.getMaxZ()); // +Z + + // inverted check for world border enclosing the specified box expanded by -EPSILON +- return (borderMinX - boxMinX) > ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON || (borderMaxX - boxMaxX) < -ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON || +- (borderMinZ - boxMinZ) > ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON || (borderMaxZ - boxMaxZ) < -ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON; ++ return (borderMinX - boxMinX) > CollisionUtil.COLLISION_EPSILON || (borderMaxX - boxMaxX) < -CollisionUtil.COLLISION_EPSILON || ++ (borderMinZ - boxMinZ) > CollisionUtil.COLLISION_EPSILON || (borderMaxZ - boxMaxZ) < -CollisionUtil.COLLISION_EPSILON; + } + + /* Math.max/min specify that any NaN argument results in a NaN return, unlike these functions */ +@@ -1575,38 +1911,38 @@ public final class CollisionUtil { + public static final int COLLISION_FLAG_CHECK_BORDER = 1 << 2; + public static final int COLLISION_FLAG_CHECK_ONLY = 1 << 3; + +- public static boolean getCollisionsForBlocksOrWorldBorder(final net.minecraft.world.level.Level world, final net.minecraft.world.entity.Entity entity, final net.minecraft.world.phys.AABB aabb, +- final java.util.List intoVoxel, final java.util.List intoAABB, +- final int collisionFlags, final java.util.function.BiPredicate predicate) { ++ public static boolean getCollisionsForBlocksOrWorldBorder(final Level world, final Entity entity, final AABB aabb, ++ final List intoVoxel, final List intoAABB, ++ final int collisionFlags, final BiPredicate predicate) { + final boolean checkOnly = (collisionFlags & COLLISION_FLAG_CHECK_ONLY) != 0; + boolean ret = false; + + if ((collisionFlags & COLLISION_FLAG_CHECK_BORDER) != 0) { +- final net.minecraft.world.level.border.WorldBorder worldBorder = world.getWorldBorder(); +- if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isCollidingWithBorder(worldBorder, aabb) && entity != null && worldBorder.isInsideCloseToBorder(entity, aabb)) { ++ final WorldBorder worldBorder = world.getWorldBorder(); ++ if (CollisionUtil.isCollidingWithBorder(worldBorder, aabb) && entity != null && worldBorder.isInsideCloseToBorder(entity, aabb)) { + if (checkOnly) { + return true; + } else { +- final net.minecraft.world.phys.shapes.VoxelShape borderShape = worldBorder.getCollisionShape(); ++ final VoxelShape borderShape = worldBorder.getCollisionShape(); + intoVoxel.add(borderShape); + ret = true; + } + } + } + +- final int minSection = ((ca.spottedleaf.moonrise.patches.collisions.world.CollisionLevel)world).moonrise$getMinSection(); ++ final int minSection = WorldUtil.getMinSection(world); + +- final int minBlockX = net.minecraft.util.Mth.floor(aabb.minX - COLLISION_EPSILON) - 1; +- final int maxBlockX = net.minecraft.util.Mth.floor(aabb.maxX + COLLISION_EPSILON) + 1; ++ final int minBlockX = Mth.floor(aabb.minX - COLLISION_EPSILON) - 1; ++ final int maxBlockX = Mth.floor(aabb.maxX + COLLISION_EPSILON) + 1; + +- final int minBlockY = Math.max((minSection << 4) - 1, net.minecraft.util.Mth.floor(aabb.minY - COLLISION_EPSILON) - 1); +- final int maxBlockY = Math.min((((ca.spottedleaf.moonrise.patches.collisions.world.CollisionLevel)world).moonrise$getMaxSection() << 4) + 16, net.minecraft.util.Mth.floor(aabb.maxY + COLLISION_EPSILON) + 1); ++ final int minBlockY = Math.max((minSection << 4) - 1, Mth.floor(aabb.minY - COLLISION_EPSILON) - 1); ++ final int maxBlockY = Math.min((WorldUtil.getMaxSection(world) << 4) + 16, Mth.floor(aabb.maxY + COLLISION_EPSILON) + 1); + +- final int minBlockZ = net.minecraft.util.Mth.floor(aabb.minZ - COLLISION_EPSILON) - 1; +- final int maxBlockZ = net.minecraft.util.Mth.floor(aabb.maxZ + COLLISION_EPSILON) + 1; ++ final int minBlockZ = Mth.floor(aabb.minZ - COLLISION_EPSILON) - 1; ++ final int maxBlockZ = Mth.floor(aabb.maxZ + COLLISION_EPSILON) + 1; + +- final net.minecraft.core.BlockPos.MutableBlockPos mutablePos = new net.minecraft.core.BlockPos.MutableBlockPos(); +- final net.minecraft.world.phys.shapes.CollisionContext collisionShape = new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext(entity); ++ final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); ++ final CollisionContext collisionShape = new LazyEntityCollisionContext(entity); + + // special cases: + if (minBlockY > maxBlockY) { +@@ -1624,11 +1960,11 @@ public final class CollisionUtil { + final int maxChunkZ = maxBlockZ >> 4; + + final boolean loadChunks = (collisionFlags & COLLISION_FLAG_LOAD_CHUNKS) != 0; +- final net.minecraft.world.level.chunk.ChunkSource chunkSource = world.getChunkSource(); ++ final ChunkSource chunkSource = world.getChunkSource(); + + for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { + for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { +- final net.minecraft.world.level.chunk.ChunkAccess chunk = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, loadChunks); ++ final ChunkAccess chunk = chunkSource.getChunk(currChunkX, currChunkZ, ChunkStatus.FULL, loadChunks); + + if (chunk == null) { + if ((collisionFlags & COLLISION_FLAG_COLLIDE_WITH_UNLOADED_CHUNKS) != 0) { +@@ -1642,7 +1978,7 @@ public final class CollisionUtil { + continue; + } + +- final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections(); ++ final LevelChunkSection[] sections = chunk.getSections(); + + // bound y + for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) { +@@ -1650,16 +1986,16 @@ public final class CollisionUtil { + if (sectionIdx < 0 || sectionIdx >= sections.length) { + continue; + } +- final net.minecraft.world.level.chunk.LevelChunkSection section = sections[sectionIdx]; +- if (section == null || section.hasOnlyAir()) { ++ final LevelChunkSection section = sections[sectionIdx]; ++ if (section.hasOnlyAir()) { + // empty + continue; + } + +- final boolean hasSpecial = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$getSpecialCollidingBlocks() != 0; ++ final boolean hasSpecial = ((BlockCountingChunkSection)section).moonrise$hasSpecialCollidingBlocks(); + final int sectionAdjust = !hasSpecial ? 1 : 0; + +- final net.minecraft.world.level.chunk.PalettedContainer blocks = section.states; ++ final PalettedContainer blocks = section.states; + + final int minXIterate = currChunkX == minChunkX ? (minBlockX & 15) + sectionAdjust : 0; + final int maxXIterate = currChunkX == maxChunkX ? (maxBlockX & 15) - sectionAdjust : 15; +@@ -1683,21 +2019,21 @@ public final class CollisionUtil { + continue; + } + +- final net.minecraft.world.level.block.state.BlockState blockData = blocks.get(localBlockIndex); ++ final BlockState blockData = blocks.get(localBlockIndex); + +- if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockData).moonrise$emptyCollisionShape()) { ++ if (((CollisionBlockState)blockData).moonrise$emptyContextCollisionShape()) { + continue; + } + +- net.minecraft.world.phys.shapes.VoxelShape blockCollision = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockData).moonrise$getConstantCollisionShape(); ++ VoxelShape blockCollision = ((CollisionBlockState)blockData).moonrise$getConstantContextCollisionShape(); + +- if (edgeCount == 0 || ((edgeCount != 1 || blockData.hasLargeCollisionShape()) && (edgeCount != 2 || blockData.getBlock() == net.minecraft.world.level.block.Blocks.MOVING_PISTON))) { ++ if (edgeCount == 0 || ((edgeCount != 1 || blockData.hasLargeCollisionShape()) && (edgeCount != 2 || blockData.getBlock() == Blocks.MOVING_PISTON))) { + if (blockCollision == null) { + mutablePos.set(blockX, blockY, blockZ); + blockCollision = blockData.getCollisionShape(world, mutablePos, collisionShape); + } + +- net.minecraft.world.phys.AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation(); ++ AABB singleAABB = ((CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation(); + if (singleAABB != null) { + singleAABB = singleAABB.move((double)blockX, (double)blockY, (double)blockZ); + if (!voxelShapeIntersect(aabb, singleAABB)) { +@@ -1724,7 +2060,7 @@ public final class CollisionUtil { + continue; + } + +- final net.minecraft.world.phys.shapes.VoxelShape blockCollisionOffset = blockCollision.move((double)blockX, (double)blockY, (double)blockZ); ++ final VoxelShape blockCollisionOffset = blockCollision.move((double)blockX, (double)blockY, (double)blockZ); + + if (!voxelShapeIntersectNoEmpty(blockCollisionOffset, aabb)) { + continue; +@@ -1755,8 +2091,8 @@ public final class CollisionUtil { + return ret; + } + +- public static boolean getEntityHardCollisions(final net.minecraft.world.level.Level world, final net.minecraft.world.entity.Entity entity, net.minecraft.world.phys.AABB aabb, +- final java.util.List into, final int collisionFlags, final java.util.function.Predicate predicate) { ++ public static boolean getEntityHardCollisions(final Level world, final Entity entity, AABB aabb, ++ final List into, final int collisionFlags, final Predicate predicate) { + final boolean checkOnly = (collisionFlags & COLLISION_FLAG_CHECK_ONLY) != 0; + + boolean ret = false; +@@ -1765,15 +2101,15 @@ public final class CollisionUtil { + // Vanilla for hard collisions has this backwards, and they expand by +epsilon but this causes terrible problems + // specifically with boat collisions. + aabb = aabb.inflate(-COLLISION_EPSILON, -COLLISION_EPSILON, -COLLISION_EPSILON); +- final java.util.List entities; +- if (entity != null && ((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)entity).moonrise$isHardColliding()) { ++ final List entities; ++ if (entity != null && ((ChunkSystemEntity)entity).moonrise$isHardColliding()) { + entities = world.getEntities(entity, aabb, predicate); + } else { +- entities = ((ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemEntityGetter)world).moonrise$getHardCollidingEntities(entity, aabb, predicate); ++ entities = ((ChunkSystemEntityGetter)world).moonrise$getHardCollidingEntities(entity, aabb, predicate); + } + + for (int i = 0, len = entities.size(); i < len; ++i) { +- final net.minecraft.world.entity.Entity otherEntity = entities.get(i); ++ final Entity otherEntity = entities.get(i); + + if (otherEntity.isSpectator()) { + continue; +@@ -1792,10 +2128,10 @@ public final class CollisionUtil { + return ret; + } + +- public static boolean getCollisions(final net.minecraft.world.level.Level world, final net.minecraft.world.entity.Entity entity, final net.minecraft.world.phys.AABB aabb, +- final java.util.List intoVoxel, final java.util.List intoAABB, final int collisionFlags, +- final java.util.function.BiPredicate blockPredicate, +- final java.util.function.Predicate entityPredicate) { ++ public static boolean getCollisions(final Level world, final Entity entity, final AABB aabb, ++ final List intoVoxel, final List intoAABB, final int collisionFlags, ++ final BiPredicate blockPredicate, ++ final Predicate entityPredicate) { + if ((collisionFlags & COLLISION_FLAG_CHECK_ONLY) != 0) { + return getCollisionsForBlocksOrWorldBorder(world, entity, aabb, intoVoxel, intoAABB, collisionFlags, blockPredicate) + || getEntityHardCollisions(world, entity, aabb, intoAABB, collisionFlags, entityPredicate); +@@ -1805,12 +2141,12 @@ public final class CollisionUtil { + } + } + +- public static final class LazyEntityCollisionContext extends net.minecraft.world.phys.shapes.EntityCollisionContext { ++ public static final class LazyEntityCollisionContext extends EntityCollisionContext { + +- private net.minecraft.world.phys.shapes.CollisionContext delegate; ++ private CollisionContext delegate; + private boolean delegated; + +- public LazyEntityCollisionContext(final net.minecraft.world.entity.Entity entity) { ++ public LazyEntityCollisionContext(final Entity entity) { + super(false, 0.0, null, null, entity); + } + +@@ -1820,10 +2156,10 @@ public final class CollisionUtil { + return delegated; + } + +- public net.minecraft.world.phys.shapes.CollisionContext getDelegate() { ++ public CollisionContext getDelegate() { + this.delegated = true; +- final net.minecraft.world.entity.Entity entity = this.getEntity(); +- return this.delegate == null ? this.delegate = (entity == null ? net.minecraft.world.phys.shapes.CollisionContext.empty() : net.minecraft.world.phys.shapes.CollisionContext.of(entity)) : this.delegate; ++ final Entity entity = this.getEntity(); ++ return this.delegate == null ? this.delegate = (entity == null ? CollisionContext.empty() : CollisionContext.of(entity)) : this.delegate; + } + + @Override +@@ -1832,17 +2168,17 @@ public final class CollisionUtil { + } + + @Override +- public boolean isAbove(final net.minecraft.world.phys.shapes.VoxelShape shape, final net.minecraft.core.BlockPos pos, final boolean defaultValue) { ++ public boolean isAbove(final VoxelShape shape, final BlockPos pos, final boolean defaultValue) { + return this.getDelegate().isAbove(shape, pos, defaultValue); + } + + @Override +- public boolean isHoldingItem(final net.minecraft.world.item.Item item) { ++ public boolean isHoldingItem(final Item item) { + return this.getDelegate().isHoldingItem(item); + } + + @Override +- public boolean canStandOnFluid(final net.minecraft.world.level.material.FluidState state, final net.minecraft.world.level.material.FluidState fluidState) { ++ public boolean canStandOnFluid(final FluidState state, final FluidState fluidState) { + return this.getDelegate().canStandOnFluid(state, fluidState); + } + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/ExplosionBlockCache.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/ExplosionBlockCache.java +index eb7200657d5c7ac37ee93868ba43be0aefecac6d..35c8aaf0bfa42717f45eed1d1072e1614874de91 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/ExplosionBlockCache.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/ExplosionBlockCache.java +@@ -1,18 +1,23 @@ + package ca.spottedleaf.moonrise.patches.collisions; + ++import net.minecraft.core.BlockPos; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.material.FluidState; ++import net.minecraft.world.phys.shapes.VoxelShape; ++ + public final class ExplosionBlockCache { + + public final long key; +- public final net.minecraft.core.BlockPos immutablePos; +- public final net.minecraft.world.level.block.state.BlockState blockState; +- public final net.minecraft.world.level.material.FluidState fluidState; ++ public final BlockPos immutablePos; ++ public final BlockState blockState; ++ public final FluidState fluidState; + public final float resistance; + public final boolean outOfWorld; + public Boolean shouldExplode; // null -> not called yet +- public net.minecraft.world.phys.shapes.VoxelShape cachedCollisionShape; ++ public VoxelShape cachedCollisionShape; + +- public ExplosionBlockCache(final long key, final net.minecraft.core.BlockPos immutablePos, final net.minecraft.world.level.block.state.BlockState blockState, +- final net.minecraft.world.level.material.FluidState fluidState, final float resistance, final boolean outOfWorld) { ++ public ExplosionBlockCache(final long key, final BlockPos immutablePos, final BlockState blockState, ++ final FluidState fluidState, final float resistance, final boolean outOfWorld) { + this.key = key; + this.immutablePos = immutablePos; + this.blockState = blockState; +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/block/CollisionBlockState.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/block/CollisionBlockState.java +index 02b29c563a298e06186de010de68a716bccba494..a38ab583200ebf68ca68fdddf2d12077720b72b7 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/block/CollisionBlockState.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/block/CollisionBlockState.java +@@ -1,5 +1,7 @@ + package ca.spottedleaf.moonrise.patches.collisions.block; + ++import net.minecraft.world.phys.shapes.VoxelShape; ++ + public interface CollisionBlockState { + + // note: this does not consider canOcclude, it is only based on the cached collision shape (i.e hasCache()) +@@ -9,6 +11,9 @@ public interface CollisionBlockState { + // whether the cached collision shape exists and is empty + public boolean moonrise$emptyCollisionShape(); + ++ // whether the context-sensitive shape is constant and is empty ++ public boolean moonrise$emptyContextCollisionShape(); ++ + // indicates that occludesFullBlock is cached for the collision shape + public boolean moonrise$hasCache(); + +@@ -20,7 +25,5 @@ public interface CollisionBlockState { + // value is still unique + public int moonrise$uniqueId2(); + +- public net.minecraft.world.phys.shapes.VoxelShape moonrise$getConstantCollisionShape(); +- +- public net.minecraft.world.phys.AABB moonrise$getConstantCollisionAABB(); ++ public VoxelShape moonrise$getConstantContextCollisionShape(); + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CachedToAABBs.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CachedToAABBs.java +index 5fe1dad9dad368911aedbe6ba7fcd8f9b0189d32..9d33ead3a97d86b371e4d9ad9fed80d789bed844 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CachedToAABBs.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CachedToAABBs.java +@@ -1,27 +1,31 @@ + package ca.spottedleaf.moonrise.patches.collisions.shape; + ++import net.minecraft.world.phys.AABB; ++import java.util.ArrayList; ++import java.util.List; ++ + public record CachedToAABBs( +- java.util.List aabbs, ++ List aabbs, + boolean isOffset, + double offX, double offY, double offZ + ) { + +- public ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs removeOffset() { +- final java.util.List toOffset = this.aabbs; ++ public CachedToAABBs removeOffset() { ++ final List toOffset = this.aabbs; + final double offX = this.offX; + final double offY = this.offY; + final double offZ = this.offZ; + +- final java.util.List ret = new java.util.ArrayList<>(toOffset.size()); ++ final List ret = new ArrayList<>(toOffset.size()); + + for (int i = 0, len = toOffset.size(); i < len; ++i) { + ret.add(toOffset.get(i).move(offX, offY, offZ)); + } + +- return new ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs(ret, false, 0.0, 0.0, 0.0); ++ return new CachedToAABBs(ret, false, 0.0, 0.0, 0.0); + } + +- public static ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs offset(final ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs cache, final double offX, final double offY, final double offZ) { ++ public static CachedToAABBs offset(final CachedToAABBs cache, final double offX, final double offY, final double offZ) { + if (offX == 0.0 && offY == 0.0 && offZ == 0.0) { + return cache; + } +@@ -30,6 +34,6 @@ public record CachedToAABBs( + final double resY = cache.offY + offY; + final double resZ = cache.offZ + offZ; + +- return new ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs(cache.aabbs, true, resX, resY, resZ); ++ return new CachedToAABBs(cache.aabbs, true, resX, resY, resZ); + } + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionDiscreteVoxelShape.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionDiscreteVoxelShape.java +index a09efadea9b733840bbe69830dd8f2a303fe656f..07fe5e02c2d0a27d2fe37bb45761654dc2d02e5d 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionDiscreteVoxelShape.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionDiscreteVoxelShape.java +@@ -2,6 +2,6 @@ package ca.spottedleaf.moonrise.patches.collisions.shape; + + public interface CollisionDiscreteVoxelShape { + +- public ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData moonrise$getOrCreateCachedShapeData(); ++ public CachedShapeData moonrise$getOrCreateCachedShapeData(); + + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionVoxelShape.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionVoxelShape.java +index 70371eb87c11a106e8513cdbc8d938dda088f745..05d7b3f9d8659c259f3ed0537c57e6e43eb6e288 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionVoxelShape.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionVoxelShape.java +@@ -1,5 +1,9 @@ + package ca.spottedleaf.moonrise.patches.collisions.shape; + ++import net.minecraft.core.Direction; ++import net.minecraft.world.phys.AABB; ++import net.minecraft.world.phys.shapes.VoxelShape; ++ + public interface CollisionVoxelShape { + + public double moonrise$offsetX(); +@@ -14,16 +18,16 @@ public interface CollisionVoxelShape { + + public double[] moonrise$rootCoordinatesZ(); + +- public ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData moonrise$getCachedVoxelData(); ++ public CachedShapeData moonrise$getCachedVoxelData(); + + // rets null if not possible to represent this shape as one AABB +- public net.minecraft.world.phys.AABB moonrise$getSingleAABBRepresentation(); ++ public AABB moonrise$getSingleAABBRepresentation(); + + // ONLY USE INTERNALLY, ONLY FOR INITIALISING IN CONSTRUCTOR: VOXELSHAPES ARE STATIC + public void moonrise$initCache(); + + // this returns empty if not clamped to 1.0 or 0.0 depending on direction +- public net.minecraft.world.phys.shapes.VoxelShape moonrise$getFaceShapeClamped(final net.minecraft.core.Direction direction); ++ public VoxelShape moonrise$getFaceShapeClamped(final Direction direction); + + public boolean moonrise$isFullBlock(); + +@@ -32,5 +36,5 @@ public interface CollisionVoxelShape { + public boolean moonrise$occludesFullBlockIfCached(); + + // uses a cache internally +- public net.minecraft.world.phys.shapes.VoxelShape moonrise$orUnoptimized(final net.minecraft.world.phys.shapes.VoxelShape other); ++ public VoxelShape moonrise$orUnoptimized(final VoxelShape other); + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/MergedORCache.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/MergedORCache.java +index 4217426d3eca5e5cd2bc37e509f84da1d6fed0b2..44831fc18efb7534dc6e4822f3c9b5cdc4dcc33e 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/MergedORCache.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/MergedORCache.java +@@ -1,8 +1,10 @@ + package ca.spottedleaf.moonrise.patches.collisions.shape; + ++import net.minecraft.world.phys.shapes.VoxelShape; ++ + public record MergedORCache( +- net.minecraft.world.phys.shapes.VoxelShape key, +- net.minecraft.world.phys.shapes.VoxelShape result ++ VoxelShape key, ++ VoxelShape result + ) { + + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/EmptyStreamForMoveCall.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/EmptyStreamForMoveCall.java +deleted file mode 100644 +index 673103f160cbe577c6e05f998706af4e6850011b..0000000000000000000000000000000000000000 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/EmptyStreamForMoveCall.java ++++ /dev/null +@@ -1,225 +0,0 @@ +-package ca.spottedleaf.moonrise.patches.collisions.util; +- +-import java.util.Iterator; +-import java.util.Optional; +-import java.util.Spliterator; +-import java.util.stream.Stream; +- +-public final class EmptyStreamForMoveCall implements java.util.stream.Stream { +- +- public static final ca.spottedleaf.moonrise.patches.collisions.util.EmptyStreamForMoveCall INSTANCE = new ca.spottedleaf.moonrise.patches.collisions.util.EmptyStreamForMoveCall(); +- +- @Override +- public boolean noneMatch(java.util.function.Predicate predicate) { +- return false; // important: ret false so the branch is never taken by mojang code +- } +- +- @Override +- public java.util.stream.Stream filter(java.util.function.Predicate predicate) { +- return null; +- } +- +- @Override +- public java.util.stream.Stream map(java.util.function.Function mapper) { +- return null; +- } +- +- @Override +- public java.util.stream.IntStream mapToInt(java.util.function.ToIntFunction mapper) { +- return null; +- } +- +- @Override +- public java.util.stream.LongStream mapToLong(java.util.function.ToLongFunction mapper) { +- return null; +- } +- +- @Override +- public java.util.stream.DoubleStream mapToDouble(java.util.function.ToDoubleFunction mapper) { +- return null; +- } +- +- @Override +- public java.util.stream.Stream flatMap(java.util.function.Function> mapper) { +- return null; +- } +- +- @Override +- public java.util.stream.IntStream flatMapToInt(java.util.function.Function mapper) { +- return null; +- } +- +- @Override +- public java.util.stream.LongStream flatMapToLong(java.util.function.Function mapper) { +- return null; +- } +- +- @Override +- public java.util.stream.DoubleStream flatMapToDouble(java.util.function.Function mapper) { +- return null; +- } +- +- @Override +- public java.util.stream.Stream distinct() { +- return null; +- } +- +- @Override +- public java.util.stream.Stream sorted() { +- return null; +- } +- +- @Override +- public java.util.stream.Stream sorted(java.util.Comparator comparator) { +- return null; +- } +- +- @Override +- public java.util.stream.Stream peek(java.util.function.Consumer action) { +- return null; +- } +- +- @Override +- public java.util.stream.Stream limit(long maxSize) { +- return null; +- } +- +- @Override +- public java.util.stream.Stream skip(long n) { +- return null; +- } +- +- @Override +- public void forEach(java.util.function.Consumer action) { +- +- } +- +- @Override +- public void forEachOrdered(java.util.function.Consumer action) { +- +- } +- +- @org.jetbrains.annotations.NotNull +- @Override +- public Object[] toArray() { +- return new Object[0]; +- } +- +- @org.jetbrains.annotations.NotNull +- @Override +- public
    A[] toArray(java.util.function.IntFunction generator) { +- return null; +- } +- +- @Override +- public T reduce(T identity, java.util.function.BinaryOperator accumulator) { +- return null; +- } +- +- @org.jetbrains.annotations.NotNull +- @Override +- public Optional reduce(java.util.function.BinaryOperator accumulator) { +- return java.util.Optional.empty(); +- } +- +- @Override +- public U reduce(U identity, java.util.function.BiFunction accumulator, java.util.function.BinaryOperator combiner) { +- return null; +- } +- +- @Override +- public R collect(java.util.function.Supplier supplier, java.util.function.BiConsumer accumulator, java.util.function.BiConsumer combiner) { +- return null; +- } +- +- @Override +- public R collect(java.util.stream.Collector collector) { +- return null; +- } +- +- @org.jetbrains.annotations.NotNull +- @Override +- public Optional min(java.util.Comparator comparator) { +- return java.util.Optional.empty(); +- } +- +- @org.jetbrains.annotations.NotNull +- @Override +- public Optional max(java.util.Comparator comparator) { +- return java.util.Optional.empty(); +- } +- +- @Override +- public long count() { +- return 0; +- } +- +- @Override +- public boolean anyMatch(java.util.function.Predicate predicate) { +- return false; +- } +- +- @Override +- public boolean allMatch(java.util.function.Predicate predicate) { +- return false; +- } +- +- @org.jetbrains.annotations.NotNull +- @Override +- public Optional findFirst() { +- return java.util.Optional.empty(); +- } +- +- @org.jetbrains.annotations.NotNull +- @Override +- public Optional findAny() { +- return java.util.Optional.empty(); +- } +- +- +- @org.jetbrains.annotations.NotNull +- @Override +- public Iterator iterator() { +- return null; +- } +- +- @org.jetbrains.annotations.NotNull +- @Override +- public Spliterator spliterator() { +- return null; +- } +- +- @Override +- public boolean isParallel() { +- return false; +- } +- +- @org.jetbrains.annotations.NotNull +- @Override +- public Stream sequential() { +- return null; +- } +- +- @org.jetbrains.annotations.NotNull +- @Override +- public Stream parallel() { +- return null; +- } +- +- @org.jetbrains.annotations.NotNull +- @Override +- public Stream unordered() { +- return null; +- } +- +- @org.jetbrains.annotations.NotNull +- @Override +- public Stream onClose(Runnable closeHandler) { +- return null; +- } +- +- @Override +- public void close() { +- +- } +-} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java +index 128267ff40b38c7b3ea0feb5133825cc6aae075b..cf9ffdeff6bf0b62a45f7a44dbfe0dd7d17dc4f4 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java +@@ -1,4 +1,7 @@ + package ca.spottedleaf.moonrise.patches.collisions.util; + +-public record FluidOcclusionCacheKey(net.minecraft.world.level.block.state.BlockState first, net.minecraft.world.level.block.state.BlockState second, net.minecraft.core.Direction direction, boolean result) { ++import net.minecraft.core.Direction; ++import net.minecraft.world.level.block.state.BlockState; ++ ++public record FluidOcclusionCacheKey(BlockState first, BlockState second, Direction direction, boolean result) { + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/world/CollisionLevel.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/world/CollisionLevel.java +deleted file mode 100644 +index e851e81e13edbad6316df63fcb7095d48f85c5b0..0000000000000000000000000000000000000000 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/world/CollisionLevel.java ++++ /dev/null +@@ -1,9 +0,0 @@ +-package ca.spottedleaf.moonrise.patches.collisions.world; +- +-public interface CollisionLevel { +- +- public int moonrise$getMinSection(); +- +- public int moonrise$getMaxSection(); +- +-} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerTrackedEntity.java b/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerTrackedEntity.java +index 1fa07bef57d82c6d5242aaaf66011f0913515231..8e7472157a98de607c03769a91f64c8369fd3ea6 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerTrackedEntity.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerTrackedEntity.java +@@ -10,4 +10,6 @@ public interface EntityTrackerTrackedEntity { + + public void moonrise$clearPlayers(); + ++ public boolean moonrise$hasPlayers(); ++ + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPalette.java b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPalette.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4a7abd239a9c59aa98947e7993962d75e9051902 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPalette.java +@@ -0,0 +1,9 @@ ++package ca.spottedleaf.moonrise.patches.fast_palette; ++ ++public interface FastPalette { ++ ++ public default T[] moonrise$getRawPalette(final FastPaletteData src) { ++ return null; ++ } ++ ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPaletteData.java b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPaletteData.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4503f3495846a7d7ed082b9e24636044e4fbccd1 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPaletteData.java +@@ -0,0 +1,9 @@ ++package ca.spottedleaf.moonrise.patches.fast_palette; ++ ++public interface FastPaletteData { ++ ++ public T[] moonrise$getPalette(); ++ ++ public void moonrise$setPalette(final T[] palette); ++ ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/fluid/FluidFluidState.java b/src/main/java/ca/spottedleaf/moonrise/patches/fluid/FluidFluidState.java +new file mode 100644 +index 0000000000000000000000000000000000000000..107c97089354edd35f330582f5e0c8a18e792a6e +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/fluid/FluidFluidState.java +@@ -0,0 +1,5 @@ ++package ca.spottedleaf.moonrise.patches.fluid; ++ ++public interface FluidFluidState { ++ public void moonrise$initCaches(); ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_getblock/GetBlockChunk.java b/src/main/java/ca/spottedleaf/moonrise/patches/getblock/GetBlockChunk.java +similarity index 75% +rename from src/main/java/ca/spottedleaf/moonrise/patches/chunk_getblock/GetBlockChunk.java +rename to src/main/java/ca/spottedleaf/moonrise/patches/getblock/GetBlockChunk.java +index 08338917dc61c856eaba0b76e05c1497c458399d..540c14a6d2c216cd3ef2a9c4056e15712bf8cb8c 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_getblock/GetBlockChunk.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/getblock/GetBlockChunk.java +@@ -1,4 +1,4 @@ +-package ca.spottedleaf.moonrise.patches.chunk_getblock; ++package ca.spottedleaf.moonrise.patches.getblock; + + import net.minecraft.world.level.block.state.BlockState; + +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/blockstate/StarlightAbstractBlockState.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/blockstate/StarlightAbstractBlockState.java +index 2bfdf3721db9a45e36538d71cbefcb1d339e6c58..8e6d79b7c10ef25f5478b72c53c555423d615a2f 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/blockstate/StarlightAbstractBlockState.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/blockstate/StarlightAbstractBlockState.java +@@ -4,6 +4,4 @@ public interface StarlightAbstractBlockState { + + public boolean starlight$isConditionallyFullOpaque(); + +- public int starlight$getOpacityIfCached(); +- + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/BlockStarLightEngine.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/BlockStarLightEngine.java +index 154443ac1ee1d6d18b8ff0f40a307d638b213aeb..fa7b784a89626e8528c249d7889a598bd7ee3d49 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/BlockStarLightEngine.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/BlockStarLightEngine.java +@@ -1,8 +1,10 @@ + package ca.spottedleaf.moonrise.patches.starlight.light; + ++import ca.spottedleaf.moonrise.common.PlatformHooks; + import ca.spottedleaf.moonrise.patches.starlight.blockstate.StarlightAbstractBlockState; + import ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk; + import net.minecraft.core.BlockPos; ++import net.minecraft.world.level.BlockGetter; + import net.minecraft.world.level.Level; + import net.minecraft.world.level.block.state.BlockState; + import net.minecraft.world.level.chunk.ChunkAccess; +@@ -91,7 +93,7 @@ public final class BlockStarLightEngine extends StarLightEngine { + + final int currentLevel = this.getLightLevel(worldX, worldY, worldZ); + final BlockState blockState = this.getBlockState(worldX, worldY, worldZ); +- final int emittedLevel = blockState.getLightEmission() & emittedMask; ++ final int emittedLevel = (PlatformHooks.get().getLightEmission(blockState, lightAccess.getLevel(), this.lightEmissionPos.set(worldX, worldY, worldZ))) & emittedMask; + + this.setLightLevel(worldX, worldY, worldZ, emittedLevel); + // this accounts for change in emitted light that would cause an increase +@@ -119,37 +121,32 @@ public final class BlockStarLightEngine extends StarLightEngine { + } + + protected final BlockPos.MutableBlockPos recalcCenterPos = new BlockPos.MutableBlockPos(); +- protected final BlockPos.MutableBlockPos recalcNeighbourPos = new BlockPos.MutableBlockPos(); + + @Override + protected int calculateLightValue(final LightChunkGetter lightAccess, final int worldX, final int worldY, final int worldZ, + final int expect) { ++ this.recalcCenterPos.set(worldX, worldY, worldZ); ++ + final BlockState centerState = this.getBlockState(worldX, worldY, worldZ); +- int level = centerState.getLightEmission() & 0xF; ++ final BlockGetter world = lightAccess.getLevel(); ++ int level = (PlatformHooks.get().getLightEmission(centerState, world, this.recalcCenterPos)) & this.emittedLightMask; + + if (level >= (15 - 1) || level > expect) { + return level; + } + +- final int sectionOffset = this.chunkSectionIndexOffset; +- final BlockState conditionallyOpaqueState; +- int opacity = ((StarlightAbstractBlockState)centerState).starlight$getOpacityIfCached(); +- +- if (opacity == -1) { +- this.recalcCenterPos.set(worldX, worldY, worldZ); +- opacity = centerState.getLightBlock(lightAccess.getLevel(), this.recalcCenterPos); +- if (((StarlightAbstractBlockState)centerState).starlight$isConditionallyFullOpaque()) { +- conditionallyOpaqueState = centerState; +- } else { +- conditionallyOpaqueState = null; +- } +- } else if (opacity >= 15) { ++ final int opacity = Math.max(1, centerState.getLightBlock()); ++ if (opacity >= 15) { + return level; ++ } ++ final BlockState conditionallyOpaqueState; ++ if (((StarlightAbstractBlockState)centerState).starlight$isConditionallyFullOpaque()) { ++ conditionallyOpaqueState = centerState; + } else { + conditionallyOpaqueState = null; + } +- opacity = Math.max(1, opacity); + ++ final int sectionOffset = this.chunkSectionIndexOffset; + for (final AxisDirection direction : AXIS_DIRECTIONS) { + final int offX = worldX + direction.x; + final int offY = worldY + direction.y; +@@ -169,9 +166,8 @@ public final class BlockStarLightEngine extends StarLightEngine { + // here the block can be conditionally opaque (i.e light cannot propagate from it), so we need to test that + // we don't read the blockstate because most of the time this is false, so using the faster + // known transparency lookup results in a net win +- this.recalcNeighbourPos.set(offX, offY, offZ); +- final VoxelShape neighbourFace = neighbourState.getFaceOcclusionShape(lightAccess.getLevel(), this.recalcNeighbourPos, direction.opposite.nms); +- final VoxelShape thisFace = conditionallyOpaqueState == null ? Shapes.empty() : conditionallyOpaqueState.getFaceOcclusionShape(lightAccess.getLevel(), this.recalcCenterPos, direction.nms); ++ final VoxelShape neighbourFace = neighbourState.getFaceOcclusionShape(direction.opposite.nms); ++ final VoxelShape thisFace = conditionallyOpaqueState == null ? Shapes.empty() : conditionallyOpaqueState.getFaceOcclusionShape(direction.nms); + if (Shapes.faceShapeOccludes(thisFace, neighbourFace)) { + // not allowed to propagate + continue; +@@ -205,30 +201,34 @@ public final class BlockStarLightEngine extends StarLightEngine { + final int offX = chunk.getPos().x << 4; + final int offZ = chunk.getPos().z << 4; + ++ final PlatformHooks platformHooks = PlatformHooks.get(); ++ ++ final BlockGetter world = lightAccess.getLevel(); + final LevelChunkSection[] sections = chunk.getSections(); + for (int sectionY = this.minSection; sectionY <= this.maxSection; ++sectionY) { + final LevelChunkSection section = sections[sectionY - this.minSection]; +- if (section == null || section.hasOnlyAir()) { ++ if (section.hasOnlyAir()) { + // no sources in empty sections + continue; + } +- if (!section.maybeHas((final BlockState state) -> { +- return state.getLightEmission() > 0; +- })) { ++ if (!section.maybeHas(platformHooks.maybeHasLightEmission())) { + // no light sources in palette + continue; + } + final PalettedContainer states = section.states; + final int offY = sectionY << 4; + ++ final BlockPos.MutableBlockPos mutablePos = this.lightEmissionPos; + for (int index = 0; index < (16 * 16 * 16); ++index) { + final BlockState state = states.get(index); +- if (state.getLightEmission() <= 0) { ++ mutablePos.set(offX | (index & 15), offY | (index >>> 8), offZ | ((index >>> 4) & 15)); ++ ++ if ((platformHooks.getLightEmission(state, world, mutablePos)) == 0) { + continue; + } + + // index = x | (z << 4) | (y << 8) +- sources.add(new BlockPos(offX | (index & 15), offY | (index >>> 8), offZ | ((index >>> 4) & 15))); ++ sources.add(mutablePos.immutable()); + } + } + +@@ -238,12 +238,15 @@ public final class BlockStarLightEngine extends StarLightEngine { + @Override + public void lightChunk(final LightChunkGetter lightAccess, final ChunkAccess chunk, final boolean needsEdgeChecks) { + // setup sources ++ final BlockGetter world = lightAccess.getLevel(); ++ final PlatformHooks platformHooks = PlatformHooks.get(); ++ + final int emittedMask = this.emittedLightMask; + final List positions = this.getSources(lightAccess, chunk); + for (int i = 0, len = positions.size(); i < len; ++i) { + final BlockPos pos = positions.get(i); + final BlockState blockState = this.getBlockState(pos.getX(), pos.getY(), pos.getZ()); +- final int emittedLight = blockState.getLightEmission() & emittedMask; ++ final int emittedLight = platformHooks.getLightEmission(blockState, world, pos) & emittedMask; + + if (emittedLight <= this.getLightLevel(pos.getX(), pos.getY(), pos.getZ())) { + // some other source is brighter +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/SkyStarLightEngine.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/SkyStarLightEngine.java +index fdbc015f498164c9d2c578cd84a73def568142a4..f9aef289e9a2d6f63c98c72c56ef32b8793f57f4 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/SkyStarLightEngine.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/SkyStarLightEngine.java +@@ -290,9 +290,6 @@ public final class SkyStarLightEngine extends StarLightEngine { + ); + } + +- protected final BlockPos.MutableBlockPos recalcCenterPos = new BlockPos.MutableBlockPos(); +- protected final BlockPos.MutableBlockPos recalcNeighbourPos = new BlockPos.MutableBlockPos(); +- + @Override + protected int calculateLightValue(final LightChunkGetter lightAccess, final int worldX, final int worldY, final int worldZ, + final int expect) { +@@ -302,20 +299,13 @@ public final class SkyStarLightEngine extends StarLightEngine { + + final int sectionOffset = this.chunkSectionIndexOffset; + final BlockState centerState = this.getBlockState(worldX, worldY, worldZ); +- int opacity = ((StarlightAbstractBlockState)centerState).starlight$getOpacityIfCached(); + + final BlockState conditionallyOpaqueState; +- if (opacity < 0) { +- this.recalcCenterPos.set(worldX, worldY, worldZ); +- opacity = Math.max(1, centerState.getLightBlock(lightAccess.getLevel(), this.recalcCenterPos)); +- if (((StarlightAbstractBlockState)centerState).starlight$isConditionallyFullOpaque()) { +- conditionallyOpaqueState = centerState; +- } else { +- conditionallyOpaqueState = null; +- } ++ final int opacity = Math.max(1, centerState.getLightBlock()); ++ if (((StarlightAbstractBlockState)centerState).starlight$isConditionallyFullOpaque()) { ++ conditionallyOpaqueState = centerState; + } else { + conditionallyOpaqueState = null; +- opacity = Math.max(1, opacity); + } + + int level = 0; +@@ -340,9 +330,8 @@ public final class SkyStarLightEngine extends StarLightEngine { + // here the block can be conditionally opaque (i.e light cannot propagate from it), so we need to test that + // we don't read the blockstate because most of the time this is false, so using the faster + // known transparency lookup results in a net win +- this.recalcNeighbourPos.set(offX, offY, offZ); +- final VoxelShape neighbourFace = neighbourState.getFaceOcclusionShape(lightAccess.getLevel(), this.recalcNeighbourPos, direction.opposite.nms); +- final VoxelShape thisFace = conditionallyOpaqueState == null ? Shapes.empty() : conditionallyOpaqueState.getFaceOcclusionShape(lightAccess.getLevel(), this.recalcCenterPos, direction.nms); ++ final VoxelShape neighbourFace = neighbourState.getFaceOcclusionShape(direction.opposite.nms); ++ final VoxelShape thisFace = conditionallyOpaqueState == null ? Shapes.empty() : conditionallyOpaqueState.getFaceOcclusionShape(direction.nms); + if (Shapes.faceShapeOccludes(thisFace, neighbourFace)) { + // not allowed to propagate + continue; +@@ -610,7 +599,6 @@ public final class SkyStarLightEngine extends StarLightEngine { + // clobbering the light values will result in broken propagation) + protected final int tryPropagateSkylight(final BlockGetter world, final int worldX, int startY, final int worldZ, + final boolean extrudeInitialised, final boolean delayLightSet) { +- final BlockPos.MutableBlockPos mutablePos = this.mutablePos3; + final int encodeOffset = this.coordinateOffset; + final long propagateDirection = AxisDirection.POSITIVE_Y.everythingButThisDirection; // just don't check upwards. + +@@ -632,8 +620,7 @@ public final class SkyStarLightEngine extends StarLightEngine { + + final VoxelShape fromShape; + if (((StarlightAbstractBlockState)above).starlight$isConditionallyFullOpaque()) { +- this.mutablePos2.set(worldX, startY + 1, worldZ); +- fromShape = above.getFaceOcclusionShape(world, this.mutablePos2, AxisDirection.NEGATIVE_Y.nms); ++ fromShape = above.getFaceOcclusionShape(AxisDirection.NEGATIVE_Y.nms); + if (Shapes.faceShapeOccludes(Shapes.empty(), fromShape)) { + // above wont let us propagate + break; +@@ -642,49 +629,32 @@ public final class SkyStarLightEngine extends StarLightEngine { + fromShape = Shapes.empty(); + } + +- final int opacityIfCached = ((StarlightAbstractBlockState)current).starlight$getOpacityIfCached(); + // does light propagate from the top down? +- if (opacityIfCached != -1) { +- if (opacityIfCached != 0) { +- // we cannot propagate 15 through this +- break; +- } +- // most of the time it falls here. +- // add to propagate +- // light set delayed until we determine if this nibble section is null +- this.appendToIncreaseQueue( +- ((worldX + (worldZ << 6) + (startY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | (15L << (6 + 6 + 16)) // we know we're at full lit here +- | (propagateDirection << (6 + 6 + 16 + 4)) +- ); +- } else { +- mutablePos.set(worldX, startY, worldZ); +- long flags = 0L; +- if (((StarlightAbstractBlockState)current).starlight$isConditionallyFullOpaque()) { +- final VoxelShape cullingFace = current.getFaceOcclusionShape(world, mutablePos, AxisDirection.POSITIVE_Y.nms); ++ long flags = 0L; ++ if (((StarlightAbstractBlockState)current).starlight$isConditionallyFullOpaque()) { ++ final VoxelShape cullingFace = current.getFaceOcclusionShape(AxisDirection.POSITIVE_Y.nms); + +- if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { +- // can't propagate here, we're done on this column. +- break; +- } +- flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; +- } +- +- final int opacity = current.getLightBlock(world, mutablePos); +- if (opacity > 0) { +- // let the queued value (if any) handle it from here. ++ if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { ++ // can't propagate here, we're done on this column. + break; + } ++ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; ++ } + +- // light set delayed until we determine if this nibble section is null +- this.appendToIncreaseQueue( +- ((worldX + (worldZ << 6) + (startY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | (15L << (6 + 6 + 16)) // we know we're at full lit here +- | (propagateDirection << (6 + 6 + 16 + 4)) +- | flags +- ); ++ final int opacity = current.getLightBlock(); ++ if (opacity > 0) { ++ // let the queued value (if any) handle it from here. ++ break; + } + ++ // light set delayed until we determine if this nibble section is null ++ this.appendToIncreaseQueue( ++ ((worldX + (worldZ << 6) + (startY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | (15L << (6 + 6 + 16)) // we know we're at full lit here ++ | (propagateDirection << (6 + 6 + 16 + 4)) ++ | flags ++ ); ++ + above = current; + + if (this.getNibbleFromCache(worldX >> 4, startY >> 4, worldZ >> 4) == null) { +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightEngine.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightEngine.java +index 382c9e445af0d6ad2428fc22d0f63017c58191e2..8aeb5fb87f94a35659347a09a638420699b52a6f 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightEngine.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightEngine.java +@@ -1,6 +1,7 @@ + package ca.spottedleaf.moonrise.patches.starlight.light; + + import ca.spottedleaf.concurrentutil.util.IntegerUtil; ++import ca.spottedleaf.moonrise.common.PlatformHooks; + import ca.spottedleaf.moonrise.common.util.CoordinateUtils; + import ca.spottedleaf.moonrise.common.util.WorldUtil; + import ca.spottedleaf.moonrise.patches.starlight.blockstate.StarlightAbstractBlockState; +@@ -43,9 +44,9 @@ public abstract class StarLightEngine { + protected static enum AxisDirection { + + // Declaration order is important and relied upon. Do not change without modifying propagation code. +- POSITIVE_X(1, 0, 0), NEGATIVE_X(-1, 0, 0), +- POSITIVE_Z(0, 0, 1), NEGATIVE_Z(0, 0, -1), +- POSITIVE_Y(0, 1, 0), NEGATIVE_Y(0, -1, 0); ++ POSITIVE_X(1, 0, 0, Direction.EAST) , NEGATIVE_X(-1, 0, 0, Direction.WEST), ++ POSITIVE_Z(0, 0, 1, Direction.SOUTH), NEGATIVE_Z(0, 0, -1, Direction.NORTH), ++ POSITIVE_Y(0, 1, 0, Direction.UP) , NEGATIVE_Y(0, -1, 0, Direction.DOWN); + + static { + POSITIVE_X.opposite = NEGATIVE_X; NEGATIVE_X.opposite = POSITIVE_X; +@@ -62,11 +63,11 @@ public abstract class StarLightEngine { + public final long everythingButThisDirection; + public final long everythingButTheOppositeDirection; + +- AxisDirection(final int x, final int y, final int z) { ++ AxisDirection(final int x, final int y, final int z, final Direction nms) { + this.x = x; + this.y = y; + this.z = z; +- this.nms = Direction.fromDelta(x, y, z); ++ this.nms = nms; + this.everythingButThisDirection = (long)(ALL_DIRECTIONS_BITSET ^ (1 << this.ordinal())); + // positive is always even, negative is always odd. Flip the 1 bit to get the negative direction. + this.everythingButTheOppositeDirection = (long)(ALL_DIRECTIONS_BITSET ^ (1 << (this.ordinal() ^ 1))); +@@ -106,9 +107,7 @@ public abstract class StarLightEngine { + // index = x + (z * 5) + protected final boolean[][] emptinessMapCache = new boolean[5 * 5][]; + +- protected final BlockPos.MutableBlockPos mutablePos1 = new BlockPos.MutableBlockPos(); +- protected final BlockPos.MutableBlockPos mutablePos2 = new BlockPos.MutableBlockPos(); +- protected final BlockPos.MutableBlockPos mutablePos3 = new BlockPos.MutableBlockPos(); ++ protected final BlockPos.MutableBlockPos lightEmissionPos = new BlockPos.MutableBlockPos(); + + protected int encodeOffsetX; + protected int encodeOffsetY; +@@ -1150,69 +1149,46 @@ public abstract class StarLightEngine { + if (blockState == null) { + continue; + } +- final int opacityCached = ((StarlightAbstractBlockState)blockState).starlight$getOpacityIfCached(); +- if (opacityCached != -1) { +- final int targetLevel = propagatedLightLevel - Math.max(1, opacityCached); +- if (targetLevel > currentLevel) { +- currentNibble.set(localIndex, targetLevel); +- this.postLightUpdate(offX, offY, offZ); +- +- if (targetLevel > 1) { +- if (queueLength >= queue.length) { +- queue = this.resizeIncreaseQueue(); +- } +- queue[queueLength++] = +- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | ((targetLevel & 0xFL) << (6 + 6 + 16)) +- | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)); +- continue; +- } +- } +- continue; +- } else { +- this.mutablePos1.set(offX, offY, offZ); +- long flags = 0; +- if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { +- final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms); ++ long flags = 0; ++ if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { ++ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(propagate.getOpposite().nms); + +- if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) { +- continue; +- } +- flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; +- } +- +- final int opacity = blockState.getLightBlock(world, this.mutablePos1); +- final int targetLevel = propagatedLightLevel - Math.max(1, opacity); +- if (targetLevel <= currentLevel) { ++ if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) { + continue; + } ++ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; ++ } + +- currentNibble.set(localIndex, targetLevel); +- this.postLightUpdate(offX, offY, offZ); ++ final int opacity = blockState.getLightBlock(); ++ final int targetLevel = propagatedLightLevel - Math.max(1, opacity); ++ if (targetLevel <= currentLevel) { ++ continue; ++ } + +- if (targetLevel > 1) { +- if (queueLength >= queue.length) { +- queue = this.resizeIncreaseQueue(); +- } +- queue[queueLength++] = +- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | ((targetLevel & 0xFL) << (6 + 6 + 16)) +- | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)) +- | (flags); ++ currentNibble.set(localIndex, targetLevel); ++ this.postLightUpdate(offX, offY, offZ); ++ ++ if (targetLevel > 1) { ++ if (queueLength >= queue.length) { ++ queue = this.resizeIncreaseQueue(); + } +- continue; ++ queue[queueLength++] = ++ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | ((targetLevel & 0xFL) << (6 + 6 + 16)) ++ | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)) ++ | (flags); + } ++ continue; + } + } else { + // we actually need to worry about our state here + final BlockState fromBlock = this.getBlockState(posX, posY, posZ); +- this.mutablePos2.set(posX, posY, posZ); + for (final AxisDirection propagate : checkDirections) { + final int offX = posX + propagate.x; + final int offY = posY + propagate.y; + final int offZ = posZ + propagate.z; + +- final VoxelShape fromShape = (((StarlightAbstractBlockState)fromBlock).starlight$isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(world, this.mutablePos2, propagate.nms) : Shapes.empty(); ++ final VoxelShape fromShape = (((StarlightAbstractBlockState)fromBlock).starlight$isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(propagate.nms) : Shapes.empty(); + + if (fromShape != Shapes.empty() && Shapes.faceShapeOccludes(Shapes.empty(), fromShape)) { + continue; +@@ -1232,58 +1208,36 @@ public abstract class StarLightEngine { + if (blockState == null) { + continue; + } +- final int opacityCached = ((StarlightAbstractBlockState)blockState).starlight$getOpacityIfCached(); +- if (opacityCached != -1) { +- final int targetLevel = propagatedLightLevel - Math.max(1, opacityCached); +- if (targetLevel > currentLevel) { +- currentNibble.set(localIndex, targetLevel); +- this.postLightUpdate(offX, offY, offZ); +- +- if (targetLevel > 1) { +- if (queueLength >= queue.length) { +- queue = this.resizeIncreaseQueue(); +- } +- queue[queueLength++] = +- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | ((targetLevel & 0xFL) << (6 + 6 + 16)) +- | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)); +- continue; +- } +- } +- continue; +- } else { +- this.mutablePos1.set(offX, offY, offZ); +- long flags = 0; +- if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { +- final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms); +- +- if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { +- continue; +- } +- flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; +- } ++ long flags = 0; ++ if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { ++ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(propagate.getOpposite().nms); + +- final int opacity = blockState.getLightBlock(world, this.mutablePos1); +- final int targetLevel = propagatedLightLevel - Math.max(1, opacity); +- if (targetLevel <= currentLevel) { ++ if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { + continue; + } ++ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; ++ } + +- currentNibble.set(localIndex, targetLevel); +- this.postLightUpdate(offX, offY, offZ); ++ final int opacity = blockState.getLightBlock(); ++ final int targetLevel = propagatedLightLevel - Math.max(1, opacity); ++ if (targetLevel <= currentLevel) { ++ continue; ++ } + +- if (targetLevel > 1) { +- if (queueLength >= queue.length) { +- queue = this.resizeIncreaseQueue(); +- } +- queue[queueLength++] = +- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | ((targetLevel & 0xFL) << (6 + 6 + 16)) +- | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)) +- | (flags); ++ currentNibble.set(localIndex, targetLevel); ++ this.postLightUpdate(offX, offY, offZ); ++ ++ if (targetLevel > 1) { ++ if (queueLength >= queue.length) { ++ queue = this.resizeIncreaseQueue(); + } +- continue; ++ queue[queueLength++] = ++ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | ((targetLevel & 0xFL) << (6 + 6 + 16)) ++ | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)) ++ | (flags); + } ++ continue; + } + } + } +@@ -1304,6 +1258,8 @@ public abstract class StarLightEngine { + final int sectionOffset = this.chunkSectionIndexOffset; + final int emittedMask = this.emittedLightMask; + ++ final PlatformHooks platformHooks = PlatformHooks.get(); ++ + while (queueReadIndex < queueLength) { + final long queueValue = queue[queueReadIndex++]; + +@@ -1335,109 +1291,63 @@ public abstract class StarLightEngine { + if (blockState == null) { + continue; + } +- final int opacityCached = ((StarlightAbstractBlockState)blockState).starlight$getOpacityIfCached(); +- if (opacityCached != -1) { +- final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacityCached)); +- if (lightLevel > targetLevel) { +- // it looks like another source propagated here, so re-propagate it +- if (increaseQueueLength >= increaseQueue.length) { +- increaseQueue = this.resizeIncreaseQueue(); +- } +- increaseQueue[increaseQueueLength++] = +- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | ((lightLevel & 0xFL) << (6 + 6 + 16)) +- | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) +- | FLAG_RECHECK_LEVEL; +- continue; +- } +- final int emittedLight = blockState.getLightEmission() & emittedMask; +- if (emittedLight != 0) { +- // re-propagate source +- // note: do not set recheck level, or else the propagation will fail +- if (increaseQueueLength >= increaseQueue.length) { +- increaseQueue = this.resizeIncreaseQueue(); +- } +- increaseQueue[increaseQueueLength++] = +- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | ((emittedLight & 0xFL) << (6 + 6 + 16)) +- | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) +- | (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque() ? (FLAG_WRITE_LEVEL | FLAG_HAS_SIDED_TRANSPARENT_BLOCKS) : FLAG_WRITE_LEVEL); +- } +- +- currentNibble.set(localIndex, 0); +- this.postLightUpdate(offX, offY, offZ); ++ this.lightEmissionPos.set(offX, offY, offZ); ++ long flags = 0; ++ if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { ++ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(propagate.getOpposite().nms); + +- if (targetLevel > 0) { // we actually need to propagate 0 just in case we find a neighbour... +- if (queueLength >= queue.length) { +- queue = this.resizeDecreaseQueue(); +- } +- queue[queueLength++] = +- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | ((targetLevel & 0xFL) << (6 + 6 + 16)) +- | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)); ++ if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) { + continue; + } +- continue; +- } else { +- this.mutablePos1.set(offX, offY, offZ); +- long flags = 0; +- if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { +- final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms); +- +- if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) { +- continue; +- } +- flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; +- } ++ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; ++ } + +- final int opacity = blockState.getLightBlock(world, this.mutablePos1); +- final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacity)); +- if (lightLevel > targetLevel) { +- // it looks like another source propagated here, so re-propagate it +- if (increaseQueueLength >= increaseQueue.length) { +- increaseQueue = this.resizeIncreaseQueue(); +- } +- increaseQueue[increaseQueueLength++] = +- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | ((lightLevel & 0xFL) << (6 + 6 + 16)) +- | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) +- | (FLAG_RECHECK_LEVEL | flags); +- continue; ++ final int opacity = blockState.getLightBlock(); ++ final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacity)); ++ if (lightLevel > targetLevel) { ++ // it looks like another source propagated here, so re-propagate it ++ if (increaseQueueLength >= increaseQueue.length) { ++ increaseQueue = this.resizeIncreaseQueue(); + } +- final int emittedLight = blockState.getLightEmission() & emittedMask; +- if (emittedLight != 0) { +- // re-propagate source +- // note: do not set recheck level, or else the propagation will fail +- if (increaseQueueLength >= increaseQueue.length) { +- increaseQueue = this.resizeIncreaseQueue(); +- } +- increaseQueue[increaseQueueLength++] = +- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | ((emittedLight & 0xFL) << (6 + 6 + 16)) +- | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) +- | (flags | FLAG_WRITE_LEVEL); ++ increaseQueue[increaseQueueLength++] = ++ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | ((lightLevel & 0xFL) << (6 + 6 + 16)) ++ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) ++ | (FLAG_RECHECK_LEVEL | flags); ++ continue; ++ } ++ final int emittedLight = (platformHooks.getLightEmission(blockState, world, this.lightEmissionPos)) & emittedMask; ++ if (emittedLight != 0) { ++ // re-propagate source ++ // note: do not set recheck level, or else the propagation will fail ++ if (increaseQueueLength >= increaseQueue.length) { ++ increaseQueue = this.resizeIncreaseQueue(); + } ++ increaseQueue[increaseQueueLength++] = ++ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | ((emittedLight & 0xFL) << (6 + 6 + 16)) ++ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) ++ | (flags | FLAG_WRITE_LEVEL); ++ } + +- currentNibble.set(localIndex, 0); +- this.postLightUpdate(offX, offY, offZ); ++ currentNibble.set(localIndex, 0); ++ this.postLightUpdate(offX, offY, offZ); + +- if (targetLevel > 0) { +- if (queueLength >= queue.length) { +- queue = this.resizeDecreaseQueue(); +- } +- queue[queueLength++] = +- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | ((targetLevel & 0xFL) << (6 + 6 + 16)) +- | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)) +- | flags; ++ if (targetLevel > 0) { ++ if (queueLength >= queue.length) { ++ queue = this.resizeDecreaseQueue(); + } +- continue; ++ queue[queueLength++] = ++ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | ((targetLevel & 0xFL) << (6 + 6 + 16)) ++ | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)) ++ | flags; + } ++ continue; + } + } else { + // we actually need to worry about our state here + final BlockState fromBlock = this.getBlockState(posX, posY, posZ); +- this.mutablePos2.set(posX, posY, posZ); + for (final AxisDirection propagate : checkDirections) { + final int offX = posX + propagate.x; + final int offY = posY + propagate.y; +@@ -1446,7 +1356,7 @@ public abstract class StarLightEngine { + final int sectionIndex = (offX >> 4) + 5 * (offZ >> 4) + (5 * 5) * (offY >> 4) + sectionOffset; + final int localIndex = (offX & 15) | ((offZ & 15) << 4) | ((offY & 15) << 8); + +- final VoxelShape fromShape = (((StarlightAbstractBlockState)fromBlock).starlight$isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(world, this.mutablePos2, propagate.nms) : Shapes.empty(); ++ final VoxelShape fromShape = (((StarlightAbstractBlockState)fromBlock).starlight$isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(propagate.nms) : Shapes.empty(); + + if (fromShape != Shapes.empty() && Shapes.faceShapeOccludes(Shapes.empty(), fromShape)) { + continue; +@@ -1464,104 +1374,59 @@ public abstract class StarLightEngine { + if (blockState == null) { + continue; + } +- final int opacityCached = ((StarlightAbstractBlockState)blockState).starlight$getOpacityIfCached(); +- if (opacityCached != -1) { +- final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacityCached)); +- if (lightLevel > targetLevel) { +- // it looks like another source propagated here, so re-propagate it +- if (increaseQueueLength >= increaseQueue.length) { +- increaseQueue = this.resizeIncreaseQueue(); +- } +- increaseQueue[increaseQueueLength++] = +- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | ((lightLevel & 0xFL) << (6 + 6 + 16)) +- | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) +- | FLAG_RECHECK_LEVEL; +- continue; +- } +- final int emittedLight = blockState.getLightEmission() & emittedMask; +- if (emittedLight != 0) { +- // re-propagate source +- // note: do not set recheck level, or else the propagation will fail +- if (increaseQueueLength >= increaseQueue.length) { +- increaseQueue = this.resizeIncreaseQueue(); +- } +- increaseQueue[increaseQueueLength++] = +- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | ((emittedLight & 0xFL) << (6 + 6 + 16)) +- | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) +- | (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque() ? (FLAG_WRITE_LEVEL | FLAG_HAS_SIDED_TRANSPARENT_BLOCKS) : FLAG_WRITE_LEVEL); +- } +- +- currentNibble.set(localIndex, 0); +- this.postLightUpdate(offX, offY, offZ); ++ this.lightEmissionPos.set(offX, offY, offZ); ++ long flags = 0; ++ if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { ++ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(propagate.getOpposite().nms); + +- if (targetLevel > 0) { // we actually need to propagate 0 just in case we find a neighbour... +- if (queueLength >= queue.length) { +- queue = this.resizeDecreaseQueue(); +- } +- queue[queueLength++] = +- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | ((targetLevel & 0xFL) << (6 + 6 + 16)) +- | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)); ++ if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { + continue; + } +- continue; +- } else { +- this.mutablePos1.set(offX, offY, offZ); +- long flags = 0; +- if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { +- final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms); +- +- if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { +- continue; +- } +- flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; +- } ++ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; ++ } + +- final int opacity = blockState.getLightBlock(world, this.mutablePos1); +- final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacity)); +- if (lightLevel > targetLevel) { +- // it looks like another source propagated here, so re-propagate it +- if (increaseQueueLength >= increaseQueue.length) { +- increaseQueue = this.resizeIncreaseQueue(); +- } +- increaseQueue[increaseQueueLength++] = +- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | ((lightLevel & 0xFL) << (6 + 6 + 16)) +- | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) +- | (FLAG_RECHECK_LEVEL | flags); +- continue; ++ final int opacity = blockState.getLightBlock(); ++ final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacity)); ++ if (lightLevel > targetLevel) { ++ // it looks like another source propagated here, so re-propagate it ++ if (increaseQueueLength >= increaseQueue.length) { ++ increaseQueue = this.resizeIncreaseQueue(); + } +- final int emittedLight = blockState.getLightEmission() & emittedMask; +- if (emittedLight != 0) { +- // re-propagate source +- // note: do not set recheck level, or else the propagation will fail +- if (increaseQueueLength >= increaseQueue.length) { +- increaseQueue = this.resizeIncreaseQueue(); +- } +- increaseQueue[increaseQueueLength++] = +- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | ((emittedLight & 0xFL) << (6 + 6 + 16)) +- | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) +- | (flags | FLAG_WRITE_LEVEL); ++ increaseQueue[increaseQueueLength++] = ++ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | ((lightLevel & 0xFL) << (6 + 6 + 16)) ++ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) ++ | (FLAG_RECHECK_LEVEL | flags); ++ continue; ++ } ++ final int emittedLight = (platformHooks.getLightEmission(blockState, world, this.lightEmissionPos)) & emittedMask; ++ if (emittedLight != 0) { ++ // re-propagate source ++ // note: do not set recheck level, or else the propagation will fail ++ if (increaseQueueLength >= increaseQueue.length) { ++ increaseQueue = this.resizeIncreaseQueue(); + } ++ increaseQueue[increaseQueueLength++] = ++ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | ((emittedLight & 0xFL) << (6 + 6 + 16)) ++ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) ++ | (flags | FLAG_WRITE_LEVEL); ++ } + +- currentNibble.set(localIndex, 0); +- this.postLightUpdate(offX, offY, offZ); ++ currentNibble.set(localIndex, 0); ++ this.postLightUpdate(offX, offY, offZ); + +- if (targetLevel > 0) { // we actually need to propagate 0 just in case we find a neighbour... +- if (queueLength >= queue.length) { +- queue = this.resizeDecreaseQueue(); +- } +- queue[queueLength++] = +- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) +- | ((targetLevel & 0xFL) << (6 + 6 + 16)) +- | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)) +- | flags; ++ if (targetLevel > 0) { // we actually need to propagate 0 just in case we find a neighbour... ++ if (queueLength >= queue.length) { ++ queue = this.resizeDecreaseQueue(); + } +- continue; ++ queue[queueLength++] = ++ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | ((targetLevel & 0xFL) << (6 + 6 + 16)) ++ | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)) ++ | flags; + } ++ continue; + } + } + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java +index c64ab41198a5e0c7cbcbe6452af11f82f5938862..571db5f9bf94745a8afe2cd313e593fb15db5e37 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java +@@ -1,8 +1,9 @@ + package ca.spottedleaf.moonrise.patches.starlight.light; + + import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; + import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; ++import ca.spottedleaf.concurrentutil.util.Priority; + import ca.spottedleaf.moonrise.common.util.CoordinateUtils; + import ca.spottedleaf.moonrise.common.util.WorldUtil; + import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel; +@@ -745,34 +746,34 @@ public final class StarLightInterface { + super(lightInterface); + } + +- public void lowerPriority(final int chunkX, final int chunkZ, final PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(final int chunkX, final int chunkZ, final Priority priority) { + final ServerChunkTasks task = this.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + if (task != null) { + task.lowerPriority(priority); + } + } + +- public void setPriority(final int chunkX, final int chunkZ, final PrioritisedExecutor.Priority priority) { ++ public void setPriority(final int chunkX, final int chunkZ, final Priority priority) { + final ServerChunkTasks task = this.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + if (task != null) { + task.setPriority(priority); + } + } + +- public void raisePriority(final int chunkX, final int chunkZ, final PrioritisedExecutor.Priority priority) { ++ public void raisePriority(final int chunkX, final int chunkZ, final Priority priority) { + final ServerChunkTasks task = this.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + if (task != null) { + task.raisePriority(priority); + } + } + +- public PrioritisedExecutor.Priority getPriority(final int chunkX, final int chunkZ) { ++ public Priority getPriority(final int chunkX, final int chunkZ) { + final ServerChunkTasks task = this.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + if (task != null) { + return task.getPriority(); + } + +- return PrioritisedExecutor.Priority.COMPLETING; ++ return Priority.COMPLETING; + } + + @Override +@@ -816,7 +817,7 @@ public final class StarLightInterface { + return ret; + } + +- public ServerChunkTasks queueChunkLightTask(final ChunkPos pos, final BooleanSupplier lightTask, final PrioritisedExecutor.Priority priority) { ++ public ServerChunkTasks queueChunkLightTask(final ChunkPos pos, final BooleanSupplier lightTask, final Priority priority) { + final ServerChunkTasks ret = this.chunkTasks.compute(CoordinateUtils.getChunkKey(pos), (final long keyInMap, ServerChunkTasks valueInMap) -> { + if (valueInMap == null) { + valueInMap = new ServerChunkTasks( +@@ -879,11 +880,11 @@ public final class StarLightInterface { + + public ServerChunkTasks(final long chunkCoordinate, final StarLightInterface lightEngine, + final ServerLightQueue queue) { +- this(chunkCoordinate, lightEngine, queue, PrioritisedExecutor.Priority.NORMAL); ++ this(chunkCoordinate, lightEngine, queue, Priority.NORMAL); + } + + public ServerChunkTasks(final long chunkCoordinate, final StarLightInterface lightEngine, +- final ServerLightQueue queue, final PrioritisedExecutor.Priority priority) { ++ final ServerLightQueue queue, final Priority priority) { + super(chunkCoordinate, lightEngine, queue); + this.task = ((ChunkSystemServerLevel)(ServerLevel)lightEngine.getWorld()).moonrise$getChunkTaskScheduler().radiusAwareScheduler.createTask( + CoordinateUtils.getChunkX(chunkCoordinate), CoordinateUtils.getChunkZ(chunkCoordinate), +@@ -903,19 +904,19 @@ public final class StarLightInterface { + return this.task.cancel(); + } + +- public PrioritisedExecutor.Priority getPriority() { ++ public Priority getPriority() { + return this.task.getPriority(); + } + +- public void lowerPriority(final PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(final Priority priority) { + this.task.lowerPriority(priority); + } + +- public void setPriority(final PrioritisedExecutor.Priority priority) { ++ public void setPriority(final Priority priority) { + this.task.setPriority(priority); + } + +- public void raisePriority(final PrioritisedExecutor.Priority priority) { ++ public void raisePriority(final Priority priority) { + this.task.raisePriority(priority); + } + +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/storage/StarlightSectionData.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/storage/StarlightSectionData.java +new file mode 100644 +index 0000000000000000000000000000000000000000..40d004afdc6449530f5bb2d7c7638b8ee3e3a577 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/storage/StarlightSectionData.java +@@ -0,0 +1,13 @@ ++package ca.spottedleaf.moonrise.patches.starlight.storage; ++ ++public interface StarlightSectionData { ++ ++ public int starlight$getBlockLightState(); ++ ++ public void starlight$setBlockLightState(final int state); ++ ++ public int starlight$getSkyLightState(); ++ ++ public void starlight$setSkyLightState(final int state); ++ ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/util/SaveUtil.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/util/SaveUtil.java +index 57692a503e147a00ac4e1586cd78e12b71a80d3f..689ce367164e79e0426eeecb81dbbc521d4bc742 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/util/SaveUtil.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/util/SaveUtil.java +@@ -14,19 +14,20 @@ import net.minecraft.world.level.chunk.ChunkAccess; + import net.minecraft.world.level.chunk.status.ChunkStatus; + import org.slf4j.Logger; + ++// note: keep in-sync with SerializableChunkDataMixin + public final class SaveUtil { + + private static final Logger LOGGER = LogUtils.getLogger(); + +- private static final int STARLIGHT_LIGHT_VERSION = 9; ++ public static final int STARLIGHT_LIGHT_VERSION = 9; + + public static int getLightVersion() { + return STARLIGHT_LIGHT_VERSION; + } + +- private static final String BLOCKLIGHT_STATE_TAG = "starlight.blocklight_state"; +- private static final String SKYLIGHT_STATE_TAG = "starlight.skylight_state"; +- private static final String STARLIGHT_VERSION_TAG = "starlight.light_version"; ++ public static final String BLOCKLIGHT_STATE_TAG = "starlight.blocklight_state"; ++ public static final String SKYLIGHT_STATE_TAG = "starlight.skylight_state"; ++ public static final String STARLIGHT_VERSION_TAG = "starlight.light_version"; + + public static void saveLightHook(final Level world, final ChunkAccess chunk, final CompoundTag nbt) { + try { +diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +index a9dd0e5216e95afd98fd2200d110e2cc0b1b0dca..8371ce4e3df5ef8e39acd6e005209337cc76b451 100644 +--- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java ++++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +@@ -243,6 +243,7 @@ public class GlobalConfiguration extends ConfigurationPart { + + @PostProcess + private void postProcess() { ++ ca.spottedleaf.moonrise.common.util.MoonriseCommon.adjustWorkerThreads(this.workerThreads, this.ioThreads); + ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.init(this); + } + } +diff --git a/src/main/java/net/minecraft/core/MappedRegistry.java b/src/main/java/net/minecraft/core/MappedRegistry.java +index f22d22ebcedcc9c20225677844c86a1ad27c4211..ee1d39b6196c0f87ba473a15d3377e858922696c 100644 +--- a/src/main/java/net/minecraft/core/MappedRegistry.java ++++ b/src/main/java/net/minecraft/core/MappedRegistry.java +@@ -78,6 +78,19 @@ public class MappedRegistry implements WritableRegistry { + }; + private final Object tagAdditionLock = new Object(); + ++ // Paper start - fluid method optimisations ++ private void injectFluidRegister( ++ final ResourceKey resourceKey, ++ final T object ++ ) { ++ if (resourceKey.registryKey() == (Object)net.minecraft.core.registries.Registries.FLUID) { ++ for (final net.minecraft.world.level.material.FluidState possibleState : ((net.minecraft.world.level.material.Fluid)object).getStateDefinition().getPossibleStates()) { ++ ((ca.spottedleaf.moonrise.patches.fluid.FluidFluidState)(Object)possibleState).moonrise$initCaches(); ++ } ++ } ++ } ++ // Paper end - fluid method optimisations ++ + public MappedRegistry(ResourceKey> key, Lifecycle lifecycle) { + this(key, lifecycle, false); + } +@@ -145,6 +158,7 @@ public class MappedRegistry implements WritableRegistry { + this.toId.put(value, i); + this.registrationInfos.put(key, info); + this.registryLifecycle = this.registryLifecycle.add(info.lifecycle()); ++ this.injectFluidRegister(key, value); // Paper - fluid method optimisations + return reference; + } + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 696d075ca2883f3c37e35f983c4d020e5db89d16..25047b8536bc7e7a91ac0dfb82ad77099af6f125 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -1106,7 +1106,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop trackerEntities = entityLookup.trackerEntities; +@@ -927,21 +926,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + if (tracker == null) { + continue; + } +- ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity)tracker).moonrise$tick(nearbyPlayers.getChunk(entity.chunkPosition())); +- tracker.serverEntity.sendChanges(); +- } +- +- // process unloads +- final ca.spottedleaf.moonrise.common.list.ReferenceList unloadedEntities = entityLookup.trackerUnloadedEntities; +- final Entity[] unloadedEntitiesRaw = java.util.Arrays.copyOf(unloadedEntities.getRawDataUnchecked(), unloadedEntities.size()); +- unloadedEntities.clear(); +- +- for (final Entity entity : unloadedEntitiesRaw) { +- final ChunkMap.TrackedEntity tracker = ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$getTrackedEntity(); +- if (tracker == null) { +- continue; ++ ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity)tracker).moonrise$tick(((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)entity).moonrise$getChunkData().nearbyPlayers); ++ if (((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity)tracker).moonrise$hasPlayers() ++ || ((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)entity).moonrise$getChunkStatus().isOrAfter(FullChunkStatus.ENTITY_TICKING)) { ++ tracker.serverEntity.sendChanges(); + } +- ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity)tracker).moonrise$clearPlayers(); + } + } + // Paper end - optimise entity tracker +@@ -1178,6 +1167,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + this.removePlayer(player); + } + } ++ ++ @Override ++ public final boolean moonrise$hasPlayers() { ++ return !this.seenBy.isEmpty(); ++ } + // Paper end - optimise entity tracker + + public TrackedEntity(final Entity entity, final int i, final int j, final boolean flag) { +@@ -1283,20 +1277,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + } + + private int getEffectiveRange() { +- int i = this.range; +- Iterator iterator = this.entity.getIndirectPassengers().iterator(); ++ // Paper start - optimise entity tracker ++ final Entity entity = this.entity; ++ int range = ca.spottedleaf.moonrise.common.PlatformHooks.get().modifyEntityTrackingRange(entity, this.range); + +- while (iterator.hasNext()) { +- Entity entity = (Entity) iterator.next(); +- int j = entity.getType().clientTrackingRange() * 16; +- j = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, j); // Paper ++ if (entity.getPassengers() == ImmutableList.of()) { ++ return this.scaledRange(range); ++ } + +- if (j > i) { +- i = j; +- } ++ // note: we change to List ++ final List passengers = (List)entity.getIndirectPassengers(); ++ for (int i = 0, len = passengers.size(); i < len; ++i) { ++ final Entity passenger = passengers.get(i); ++ // note: max should be branchless ++ range = Math.max(range, ca.spottedleaf.moonrise.common.PlatformHooks.get().modifyEntityTrackingRange(passenger, passenger.getType().clientTrackingRange() << 4)); + } + +- return this.scaledRange(i); ++ return this.scaledRange(range); ++ // Paper end - optimise entity tracker + } + + public void updatePlayers(List players) { +diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +index dcb5651d1d9b10b40430fb2f713beedf68336704..b380509cc942a054ea176216210ba69f5b517ae9 100644 +--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java ++++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +@@ -92,7 +92,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler chunkTaskScheduler = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler(); + final CompletableFuture completable = new CompletableFuture<>(); + chunkTaskScheduler.scheduleChunkLoad( +- chunkX, chunkZ, toStatus, true, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.BLOCKING, ++ chunkX, chunkZ, toStatus, true, ca.spottedleaf.concurrentutil.util.Priority.BLOCKING, + completable::complete + ); + +@@ -123,6 +123,15 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + return ifPresent; + } + ++ final ca.spottedleaf.moonrise.common.PlatformHooks platformHooks = ca.spottedleaf.moonrise.common.PlatformHooks.get(); ++ ++ if (platformHooks.hasCurrentlyLoadingChunk() && currentChunk != null) { ++ final ChunkAccess loading = platformHooks.getCurrentlyLoadingChunk(currentChunk.vanillaChunkHolder); ++ if (loading != null && ca.spottedleaf.moonrise.common.util.TickThread.isTickThread()) { ++ return loading; ++ } ++ } ++ + return load ? this.syncLoad(chunkX, chunkZ, toStatus) : null; + } + // Paper end - rewrite chunk system +@@ -242,7 +251,24 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + @Nullable + @Override + public LevelChunk getChunkNow(int chunkX, int chunkZ) { +- return this.fullChunks.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); // Paper - rewrite chunk system ++ // Paper start - rewrite chunk system ++ final LevelChunk ret = this.fullChunks.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ if (!ca.spottedleaf.moonrise.common.PlatformHooks.get().hasCurrentlyLoadingChunk()) { ++ return ret; ++ } ++ ++ if (ret != null || !ca.spottedleaf.moonrise.common.util.TickThread.isTickThread()) { ++ return ret; ++ } ++ ++ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder holder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler() ++ .chunkHolderManager.getChunkHolder(chunkX, chunkZ); ++ if (holder == null) { ++ return ret; ++ } ++ ++ return ca.spottedleaf.moonrise.common.PlatformHooks.get().getCurrentlyLoadingChunk(holder.vanillaChunkHolder); ++ // Paper end - rewrite chunk system + } + + private void clearCache() { +@@ -299,7 +325,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().scheduleChunkLoad( + chunkX, chunkZ, leastStatus, true, +- ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER, ++ ca.spottedleaf.concurrentutil.util.Priority.HIGHER, + complete + ); + +@@ -556,7 +582,8 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + + private void getFullChunk(long pos, Consumer chunkConsumer) { + // Paper start - rewrite chunk system +- final LevelChunk fullChunk = this.getChunkNow(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkX(pos), ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkZ(pos)); ++ // note: bypass currentlyLoaded from getChunkNow ++ final LevelChunk fullChunk = this.fullChunks.get(pos); + if (fullChunk != null) { + chunkConsumer.accept(fullChunk); + } +diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java +index f9abf63e12ea930275121b470e4e4906cff0fc12..55e81892b928a02e240aaa31dd501b0aacef8dbe 100644 +--- a/src/main/java/net/minecraft/server/level/ServerLevel.java ++++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +@@ -799,11 +799,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. + } + + // Paper start - optimise random ticking ++ private final ca.spottedleaf.moonrise.common.util.SimpleRandom simpleRandom = new ca.spottedleaf.moonrise.common.util.SimpleRandom(0L); ++ + private void optimiseRandomTick(final LevelChunk chunk, final int tickSpeed) { + final LevelChunkSection[] sections = chunk.getSections(); + final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection((ServerLevel)(Object)this); +- final RandomSource random = this.random; +- final boolean tickFluids = false; // Paper - not configurable - MC-224294 ++ final ca.spottedleaf.moonrise.common.util.SimpleRandom simpleRandom = this.simpleRandom; ++ final boolean doubleTickFluids = !ca.spottedleaf.moonrise.common.PlatformHooks.get().configFixMC224294(); + + final ChunkPos cpos = chunk.getPos(); + final int offsetX = cpos.x << 4; +@@ -813,39 +815,32 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. + final int offsetY = (sectionIndex + minSection) << 4; + final LevelChunkSection section = sections[sectionIndex]; + final net.minecraft.world.level.chunk.PalettedContainer states = section.states; +- if (section == null || !section.isRandomlyTickingBlocks()) { ++ if (!section.isRandomlyTickingBlocks()) { + continue; + } + +- final ca.spottedleaf.moonrise.common.list.IBlockDataList tickList = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$getTickingBlockList(); +- if (tickList.size() == 0) { +- continue; +- } ++ final ca.spottedleaf.moonrise.common.list.ShortList tickList = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$getTickingBlockList(); + + for (int i = 0; i < tickSpeed; ++i) { + final int tickingBlocks = tickList.size(); +- final int index = random.nextInt() & ((16 * 16 * 16) - 1); ++ final int index = simpleRandom.nextInt() & ((16 * 16 * 16) - 1); + + if (index >= tickingBlocks) { + // most of the time we fall here + continue; + } + +- final long raw = tickList.getRaw(index); +- final int location = ca.spottedleaf.moonrise.common.list.IBlockDataList.getLocationFromRaw(raw); +- final int randomX = (location & 15); +- final int randomY = ((location >>> (4 + 4)) & 255); +- final int randomZ = ((location >>> 4) & 15); +- final BlockState state = states.get(randomX | (randomZ << 4) | (randomY << 8)); ++ final int location = (int)tickList.getRaw(index) & 0xFFFF; ++ final BlockState state = states.get(location); + + // do not use a mutable pos, as some random tick implementations store the input without calling immutable()! +- final BlockPos pos = new BlockPos(randomX | offsetX, randomY | offsetY, randomZ | offsetZ); ++ final BlockPos pos = new BlockPos((location & 15) | offsetX, ((location >>> (4 + 4)) & 15) | offsetY, ((location >>> 4) & 15) | offsetZ); + +- state.randomTick((ServerLevel)(Object)this, pos, random); +- if (tickFluids) { ++ state.randomTick((ServerLevel)(Object)this, pos, simpleRandom); ++ if (doubleTickFluids) { + final FluidState fluidState = state.getFluidState(); + if (fluidState.isRandomlyTicking()) { +- fluidState.randomTick((ServerLevel)(Object)this, pos, random); ++ fluidState.randomTick((ServerLevel)(Object)this, pos, simpleRandom); + } + } + } +@@ -856,6 +851,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. + // Paper end - optimise random ticking + + public void tickChunk(LevelChunk chunk, int randomTickSpeed) { ++ final ca.spottedleaf.moonrise.common.util.SimpleRandom simpleRandom = this.simpleRandom; // Paper - optimise random ticking + ChunkPos chunkcoordintpair = chunk.getPos(); + boolean flag = this.isRaining(); + int j = chunkcoordintpair.getMinBlockX(); +@@ -863,7 +859,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. + ProfilerFiller gameprofilerfiller = this.getProfiler(); + + gameprofilerfiller.push("thunder"); +- if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - Option to disable thunder ++ if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && simpleRandom.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - Option to disable thunder // Paper - optimise random ticking + BlockPos blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15)); + + if (this.isRainingAt(blockposition)) { +@@ -895,7 +891,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. + + if (!this.paperConfig().environment.disableIceAndSnow) { // Paper - Option to disable ice and snow + for (int l = 0; l < randomTickSpeed; ++l) { +- if (this.random.nextInt(48) == 0) { ++ if (simpleRandom.nextInt(48) == 0) { // Paper - optimise random ticking + this.tickPrecipitation(this.getBlockRandomPos(j, 0, k, 15)); + } + } +diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java +index 5e2c4969e77c669acbb4a13c07033cb267c3d586..f1371f3b9ea0cda0cf146d876828a6823632463c 100644 +--- a/src/main/java/net/minecraft/server/players/PlayerList.java ++++ b/src/main/java/net/minecraft/server/players/PlayerList.java +@@ -1475,7 +1475,7 @@ public abstract class PlayerList { + + public void setViewDistance(int viewDistance) { + this.viewDistance = viewDistance; +- this.broadcastAll(new ClientboundSetChunkCacheRadiusPacket(viewDistance)); ++ //this.broadcastAll(new ClientboundSetChunkCacheRadiusPacket(viewDistance)); // Paper - rewrite chunk system + Iterator iterator = this.server.getAllLevels().iterator(); + + while (iterator.hasNext()) { +diff --git a/src/main/java/net/minecraft/util/BitStorage.java b/src/main/java/net/minecraft/util/BitStorage.java +index 19661e106612b8e4e152085fb398db7bd06acc23..e4e153cb8899e70273aa150b8ea26907cf68b15c 100644 +--- a/src/main/java/net/minecraft/util/BitStorage.java ++++ b/src/main/java/net/minecraft/util/BitStorage.java +@@ -24,15 +24,15 @@ public interface BitStorage extends ca.spottedleaf.moonrise.patches.block_counti + // Paper start - block counting + // provide default impl in case mods implement this... + @Override +- public default it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { +- final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(); ++ public default it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { ++ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(); + + final int size = this.getSize(); + for (int index = 0; index < size; ++index) { + final int paletteIdx = this.get(index); + ret.computeIfAbsent(paletteIdx, (final int key) -> { +- return new it.unimi.dsi.fastutil.ints.IntArrayList(); +- }).add(index); ++ return new it.unimi.dsi.fastutil.shorts.ShortArrayList(); ++ }).add((short)index); + } + + return ret; +diff --git a/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java b/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java +index 61dee55417bc802e25b9ba2f271d32d8c12844a9..a8a260a3caaa8e5004069b833ecc8b17b2fc8db5 100644 +--- a/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java ++++ b/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java +@@ -7,7 +7,7 @@ import java.util.Iterator; + import javax.annotation.Nullable; + import net.minecraft.core.IdMap; + +-public class CrudeIncrementalIntIdentityHashBiMap implements IdMap { ++public class CrudeIncrementalIntIdentityHashBiMap implements IdMap, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Paper - optimise palette reads + private static final int NOT_FOUND = -1; + private static final Object EMPTY_SLOT = null; + private static final float LOADFACTOR = 0.8F; +@@ -17,6 +17,16 @@ public class CrudeIncrementalIntIdentityHashBiMap implements IdMap { + private int nextId; + private int size; + ++ // Paper start - optimise palette reads ++ private ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData reference; ++ ++ @Override ++ public final K[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData src) { ++ this.reference = src; ++ return this.byId; ++ } ++ // Paper end - optimise palette reads ++ + private CrudeIncrementalIntIdentityHashBiMap(int size) { + this.keys = (K[])(new Object[size]); + this.values = new int[size]; +@@ -88,6 +98,12 @@ public class CrudeIncrementalIntIdentityHashBiMap implements IdMap { + this.byId = crudeIncrementalIntIdentityHashBiMap.byId; + this.nextId = crudeIncrementalIntIdentityHashBiMap.nextId; + this.size = crudeIncrementalIntIdentityHashBiMap.size; ++ // Paper start - optimise palette reads ++ final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData ref = this.reference; ++ if (ref != null) { ++ ref.moonrise$setPalette(this.byId); ++ } ++ // Paper end - optimise palette reads + } + + public void addMapping(K value, int id) { +diff --git a/src/main/java/net/minecraft/util/SimpleBitStorage.java b/src/main/java/net/minecraft/util/SimpleBitStorage.java +index 8acf2f2491a8d9d13392c5e89b2bd5c9918285e1..d99ec470b4653beab630999a5b2c1a6428b20c38 100644 +--- a/src/main/java/net/minecraft/util/SimpleBitStorage.java ++++ b/src/main/java/net/minecraft/util/SimpleBitStorage.java +@@ -208,6 +208,20 @@ public class SimpleBitStorage implements BitStorage { + private final int divideAdd; private final long divideAddUnsigned; // Paper - Perf: Optimize SimpleBitStorage + private final int divideShift; + ++ // Paper start - optimise bitstorage read/write operations ++ private static final int[] BETTER_MAGIC = new int[33]; ++ static { ++ // 20 bits of precision ++ // since index is always [0, 4095] (i.e 12 bits), multiplication by a magic value here (20 bits) ++ // fits exactly in an int and allows us to use integer arithmetic ++ for (int bits = 1; bits < BETTER_MAGIC.length; ++bits) { ++ BETTER_MAGIC[bits] = (int)ca.spottedleaf.concurrentutil.util.IntegerUtil.getUnsignedDivisorMagic(64L / bits, 20); ++ } ++ } ++ private final int magic; ++ private final int mulBits; ++ // Paper end - optimise bitstorage read/write operations ++ + public SimpleBitStorage(int elementBits, int size, int[] data) { + this(elementBits, size); + int i = 0; +@@ -261,6 +275,13 @@ public class SimpleBitStorage implements BitStorage { + } else { + this.data = new long[j]; + } ++ // Paper start - optimise bitstorage read/write operations ++ this.magic = BETTER_MAGIC[this.bits]; ++ this.mulBits = (64 / this.bits) * this.bits; ++ if (this.size > 4096) { ++ throw new IllegalStateException("Size > 4096 not supported"); ++ } ++ // Paper end - optimise bitstorage read/write operations + } + + private int cellIndex(int index) { +@@ -273,31 +294,54 @@ public class SimpleBitStorage implements BitStorage { + public final int getAndSet(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage + //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage + //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper - Perf: Optimize SimpleBitStorage +- int i = this.cellIndex(index); +- long l = this.data[i]; +- int j = (index - i * this.valuesPerLong) * this.bits; +- int k = (int)(l >> j & this.mask); +- this.data[i] = l & ~(this.mask << j) | ((long)value & this.mask) << j; +- return k; ++ // Paper start - optimise bitstorage read/write operations ++ final int full = this.magic * index; // 20 bits of magic + 12 bits of index = barely int ++ final int divQ = full >>> 20; ++ final int divR = (full & 0xFFFFF) * this.mulBits >>> 20; ++ ++ final long[] dataArray = this.data; ++ ++ final long data = dataArray[divQ]; ++ final long mask = this.mask; ++ ++ final long write = data & ~(mask << divR) | ((long)value & mask) << divR; ++ ++ dataArray[divQ] = write; ++ ++ return (int)(data >>> divR & mask); ++ // Paper end - optimise bitstorage read/write operations + } + + @Override + public final void set(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage + //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage + //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper - Perf: Optimize SimpleBitStorage +- int i = this.cellIndex(index); +- long l = this.data[i]; +- int j = (index - i * this.valuesPerLong) * this.bits; +- this.data[i] = l & ~(this.mask << j) | ((long)value & this.mask) << j; ++ // Paper start - optimise bitstorage read/write operations ++ final int full = this.magic * index; // 20 bits of magic + 12 bits of index = barely int ++ final int divQ = full >>> 20; ++ final int divR = (full & 0xFFFFF) * this.mulBits >>> 20; ++ ++ final long[] dataArray = this.data; ++ ++ final long data = dataArray[divQ]; ++ final long mask = this.mask; ++ ++ final long write = data & ~(mask << divR) | ((long)value & mask) << divR; ++ ++ dataArray[divQ] = write; ++ // Paper end - optimise bitstorage read/write operations + } + + @Override + public final int get(int index) { // Paper - Perf: Optimize SimpleBitStorage + //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage +- int i = this.cellIndex(index); +- long l = this.data[i]; +- int j = (index - i * this.valuesPerLong) * this.bits; +- return (int)(l >> j & this.mask); ++ // Paper start - optimise bitstorage read/write operations ++ final int full = this.magic * index; // 20 bits of magic + 12 bits of index = barely int ++ final int divQ = full >>> 20; ++ final int divR = (full & 0xFFFFF) * this.mulBits >>> 20; ++ ++ return (int)(this.data[divQ] >>> divR & this.mask); ++ // Paper end - optimise bitstorage read/write operations + } + + @Override +@@ -364,35 +408,62 @@ public class SimpleBitStorage implements BitStorage { + + // Paper start - block counting + @Override +- public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { ++ public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { + final int valuesPerLong = this.valuesPerLong; + final int bits = this.bits; +- final long mask = this.mask; ++ final long mask = (1L << bits) - 1L; + final int size = this.size; + +- // we may be backed by global palette, so limit bits for init capacity +- final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>( +- 1 << Math.min(6, bits) +- ); +- +- int index = 0; +- +- for (long value : this.data) { +- int li = 0; +- do { +- final int paletteIdx = (int)(value & mask); +- value >>= bits; ++ if (bits <= 6) { ++ final it.unimi.dsi.fastutil.shorts.ShortArrayList[] byId = new it.unimi.dsi.fastutil.shorts.ShortArrayList[1 << bits]; ++ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1 << bits); ++ ++ int index = 0; ++ ++ for (long value : this.data) { ++ int li = 0; ++ do { ++ final int paletteIdx = (int)(value & mask); ++ value >>= bits; ++ ++li; ++ ++ final it.unimi.dsi.fastutil.shorts.ShortArrayList coords = byId[paletteIdx]; ++ if (coords != null) { ++ coords.add((short)index++); ++ continue; ++ } else { ++ final it.unimi.dsi.fastutil.shorts.ShortArrayList newCoords = new it.unimi.dsi.fastutil.shorts.ShortArrayList(64); ++ byId[paletteIdx] = newCoords; ++ newCoords.add((short)index++); ++ ret.put(paletteIdx, newCoords); ++ continue; ++ } ++ } while (li < valuesPerLong && index < size); ++ } + +- ret.computeIfAbsent(paletteIdx, (final int key) -> { +- return new it.unimi.dsi.fastutil.ints.IntArrayList(); +- }).add(index); ++ return ret; ++ } else { ++ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>( ++ 1 << 6 ++ ); ++ ++ int index = 0; ++ ++ for (long value : this.data) { ++ int li = 0; ++ do { ++ final int paletteIdx = (int)(value & mask); ++ value >>= bits; ++ ++li; ++ ++ ret.computeIfAbsent(paletteIdx, (final int key) -> { ++ return new it.unimi.dsi.fastutil.shorts.ShortArrayList(64); ++ }).add((short)index++); ++ } while (li < valuesPerLong && index < size); ++ } + +- ++li; +- ++index; +- } while (li < valuesPerLong && index < size); ++ return ret; + } +- +- return ret; + } + // Paper end - block counting + +diff --git a/src/main/java/net/minecraft/util/ZeroBitStorage.java b/src/main/java/net/minecraft/util/ZeroBitStorage.java +index 15c5164d0ef41a978c16ee317fa73e97f2480207..1f9c436a632e4f110be61cf76fcfc3b7eb80334e 100644 +--- a/src/main/java/net/minecraft/util/ZeroBitStorage.java ++++ b/src/main/java/net/minecraft/util/ZeroBitStorage.java +@@ -65,17 +65,17 @@ public class ZeroBitStorage implements BitStorage { + + // Paper start - block counting + @Override +- public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { ++ public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { + final int size = this.size; + +- final int[] raw = new int[size]; ++ final short[] raw = new short[size]; + for (int i = 0; i < size; ++i) { +- raw[i] = i; ++ raw[i] = (short)i; + } + +- final it.unimi.dsi.fastutil.ints.IntArrayList coordinates = it.unimi.dsi.fastutil.ints.IntArrayList.wrap(raw, size); ++ final it.unimi.dsi.fastutil.shorts.ShortArrayList coordinates = it.unimi.dsi.fastutil.shorts.ShortArrayList.wrap(raw, size); + +- final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1); ++ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1); + ret.put(0, coordinates); + return ret; + } +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..379456dd5c18ca627b9cf6a473fd0355e8d839ef 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -461,6 +461,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + // Paper start - rewrite chunk system + private final boolean isHardColliding = this.moonrise$isHardCollidingUncached(); + private net.minecraft.server.level.FullChunkStatus chunkStatus; ++ private ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData chunkData; + private int sectionX = Integer.MIN_VALUE; + private int sectionY = Integer.MIN_VALUE; + private int sectionZ = Integer.MIN_VALUE; +@@ -481,6 +482,16 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + this.chunkStatus = status; + } + ++ @Override ++ public final ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData moonrise$getChunkData() { ++ return this.chunkData; ++ } ++ ++ @Override ++ public final void moonrise$setChunkData(final ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData chunkData) { ++ this.chunkData = chunkData; ++ } ++ + @Override + public final int moonrise$getSectionX() { + return this.sectionX; +@@ -529,6 +540,54 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + return this.getIndirectPassengersStream().anyMatch((entity) -> entity instanceof Player); + } + // Paper end - rewrite chunk system ++ // Paper start - optimise collisions ++ private static float[] calculateStepHeights(final AABB box, final List voxels, final List aabbs, final float stepHeight, ++ final float collidedY) { ++ final FloatArraySet ret = new FloatArraySet(); ++ ++ for (int i = 0, len = voxels.size(); i < len; ++i) { ++ final VoxelShape shape = voxels.get(i); ++ ++ final double[] yCoords = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$rootCoordinatesY(); ++ final double yOffset = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$offsetY(); ++ ++ for (final double yUnoffset : yCoords) { ++ final double y = yUnoffset + yOffset; ++ ++ final float step = (float)(y - box.minY); ++ ++ if (step > stepHeight) { ++ break; ++ } ++ ++ if (step < 0.0f || !(step != collidedY)) { ++ continue; ++ } ++ ++ ret.add(step); ++ } ++ } ++ ++ for (int i = 0, len = aabbs.size(); i < len; ++i) { ++ final AABB shape = aabbs.get(i); ++ ++ final float step1 = (float)(shape.minY - box.minY); ++ final float step2 = (float)(shape.maxY - box.minY); ++ ++ if (!(step1 < 0.0f) && step1 != collidedY && !(step1 > stepHeight)) { ++ ret.add(step1); ++ } ++ ++ if (!(step2 < 0.0f) && step2 != collidedY && !(step2 > stepHeight)) { ++ ret.add(step2); ++ } ++ } ++ ++ final float[] steps = ret.toFloatArray(); ++ FloatArrays.unstableSort(steps); ++ return steps; ++ } ++ // Paper end - optimise collisions + // Paper start - optimise entity tracker + private net.minecraft.server.level.ChunkMap.TrackedEntity trackedEntity; + +@@ -1465,73 +1524,67 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + return movement; + } + +- final Level world = this.level; +- final AABB currBoundingBox = this.getBoundingBox(); +- +- if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(currBoundingBox)) { +- return movement; +- } ++ final AABB currentBox = this.getBoundingBox(); + +- final List potentialCollisionsBB = new ArrayList<>(); + final List potentialCollisionsVoxel = new ArrayList<>(); +- final double stepHeight = (double)this.maxUpStep(); +- final AABB collisionBox; +- final boolean onGround = this.onGround; ++ final List potentialCollisionsBB = new ArrayList<>(); + ++ final AABB initialCollisionBox; + if (xZero & zZero) { +- if (movement.y > 0.0) { +- collisionBox = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutUpwards(currBoundingBox, movement.y); +- } else { +- collisionBox = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutDownwards(currBoundingBox, movement.y); +- } ++ // note: xZero & zZero -> collision on x/z == 0 -> no step height calculation ++ // this specifically optimises entities standing still ++ initialCollisionBox = movement.y < 0.0 ? ++ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutDownwards(currentBox, movement.y) : ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutUpwards(currentBox, movement.y); + } else { +- // note: xZero == false or zZero == false +- if (stepHeight > 0.0 && (onGround || (movement.y < 0.0))) { +- // don't bother getting the collisions if we don't need them. +- if (movement.y <= 0.0) { +- collisionBox = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.expandUpwards(currBoundingBox.expandTowards(movement.x, movement.y, movement.z), stepHeight); +- } else { +- collisionBox = currBoundingBox.expandTowards(movement.x, Math.max(stepHeight, movement.y), movement.z); +- } +- } else { +- collisionBox = currBoundingBox.expandTowards(movement.x, movement.y, movement.z); +- } ++ initialCollisionBox = currentBox.expandTowards(movement); + } + +- ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisions( +- world, (Entity)(Object)this, collisionBox, potentialCollisionsVoxel, potentialCollisionsBB, +- ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_BORDER, +- null, null ++ final List entityAABBs = new ArrayList<>(); ++ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getEntityHardCollisions( ++ this.level, (Entity)(Object)this, initialCollisionBox, entityAABBs, 0, null + ); + +- if (potentialCollisionsVoxel.isEmpty() && potentialCollisionsBB.isEmpty()) { +- return movement; +- } ++ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisionsForBlocksOrWorldBorder( ++ this.level, (Entity)(Object)this, initialCollisionBox, potentialCollisionsVoxel, potentialCollisionsBB, ++ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_BORDER, null ++ ); ++ potentialCollisionsBB.addAll(entityAABBs); ++ final Vec3 collided = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(movement, currentBox, potentialCollisionsVoxel, potentialCollisionsBB); + +- final Vec3 limitedMoveVector = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(movement, currBoundingBox, potentialCollisionsVoxel, potentialCollisionsBB); ++ final boolean collidedX = collided.x != movement.x; ++ final boolean collidedY = collided.y != movement.y; ++ final boolean collidedZ = collided.z != movement.z; + +- if (stepHeight > 0.0 +- && (onGround || (limitedMoveVector.y != movement.y && movement.y < 0.0)) +- && (limitedMoveVector.x != movement.x || limitedMoveVector.z != movement.z)) { +- Vec3 vec3d2 = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(new Vec3(movement.x, stepHeight, movement.z), currBoundingBox, potentialCollisionsVoxel, potentialCollisionsBB); +- final Vec3 vec3d3 = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(new Vec3(0.0, stepHeight, 0.0), currBoundingBox.expandTowards(movement.x, 0.0, movement.z), potentialCollisionsVoxel, potentialCollisionsBB); ++ final boolean collidedDownwards = collidedY && movement.y < 0.0; + +- if (vec3d3.y < stepHeight) { +- final Vec3 vec3d4 = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(new Vec3(movement.x, 0.0D, movement.z), currBoundingBox.move(vec3d3), potentialCollisionsVoxel, potentialCollisionsBB).add(vec3d3); ++ final double stepHeight; + +- if (vec3d4.horizontalDistanceSqr() > vec3d2.horizontalDistanceSqr()) { +- vec3d2 = vec3d4; +- } +- } ++ if ((!collidedDownwards && !this.onGround) || (!collidedX && !collidedZ) || (stepHeight = (double)this.maxUpStep()) <= 0.0) { ++ return collided; ++ } + +- if (vec3d2.horizontalDistanceSqr() > limitedMoveVector.horizontalDistanceSqr()) { +- return vec3d2.add(ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(new Vec3(0.0D, -vec3d2.y + movement.y, 0.0D), currBoundingBox.move(vec3d2), potentialCollisionsVoxel, potentialCollisionsBB)); +- } ++ final AABB collidedYBox = collidedDownwards ? currentBox.move(0.0, collided.y, 0.0) : currentBox; ++ AABB stepRetrievalBox = collidedYBox.expandTowards(movement.x, stepHeight, movement.z); ++ if (!collidedDownwards) { ++ stepRetrievalBox = stepRetrievalBox.expandTowards(0.0, (double)-1.0E-5F, 0.0); ++ } + +- return limitedMoveVector; +- } else { +- return limitedMoveVector; ++ final List stepVoxels = new ArrayList<>(); ++ final List stepAABBs = entityAABBs; ++ ++ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisionsForBlocksOrWorldBorder( ++ this.level, (Entity)(Object)this, stepRetrievalBox, stepVoxels, stepAABBs, ++ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_BORDER, null ++ ); ++ ++ for (final float step : calculateStepHeights(collidedYBox, stepVoxels, stepAABBs, (float)stepHeight, (float)collided.y)) { ++ final Vec3 stepResult = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(new Vec3(movement.x, (double)step, movement.z), collidedYBox, stepVoxels, stepAABBs); ++ if (stepResult.horizontalDistanceSqr() > collided.horizontalDistanceSqr()) { ++ return stepResult.add(0.0, collidedYBox.minY - currentBox.minY, 0.0); ++ } + } ++ ++ return collided; + // Paper end - optimise collisions + } + +@@ -2853,64 +2906,99 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + return false; + } + +- final float reducedWith = this.dimensions.width() * 0.8F; +- final AABB box = AABB.ofSize(this.getEyePosition(), reducedWith, 1.0E-6D, reducedWith); ++ final double reducedWith = (double)(this.dimensions.width() * 0.8F); ++ final AABB boundingBox = AABB.ofSize(this.getEyePosition(), reducedWith, 1.0E-6D, reducedWith); ++ final Level world = this.level; + +- if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(box)) { ++ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(boundingBox)) { + return false; + } + +- final BlockPos.MutableBlockPos tempPos = new BlockPos.MutableBlockPos(); ++ final int minBlockX = Mth.floor(boundingBox.minX); ++ final int minBlockY = Mth.floor(boundingBox.minY); ++ final int minBlockZ = Mth.floor(boundingBox.minZ); ++ ++ final int maxBlockX = Mth.floor(boundingBox.maxX); ++ final int maxBlockY = Mth.floor(boundingBox.maxY); ++ final int maxBlockZ = Mth.floor(boundingBox.maxZ); + +- final int minX = Mth.floor(box.minX); +- final int minY = Mth.floor(box.minY); +- final int minZ = Mth.floor(box.minZ); +- final int maxX = Mth.floor(box.maxX); +- final int maxY = Mth.floor(box.maxY); +- final int maxZ = Mth.floor(box.maxZ); ++ final int minChunkX = minBlockX >> 4; ++ final int minChunkY = minBlockY >> 4; ++ final int minChunkZ = minBlockZ >> 4; + +- final net.minecraft.world.level.chunk.ChunkSource chunkProvider = this.level.getChunkSource(); ++ final int maxChunkX = maxBlockX >> 4; ++ final int maxChunkY = maxBlockY >> 4; ++ final int maxChunkZ = maxBlockZ >> 4; + +- long lastChunkKey = ChunkPos.INVALID_CHUNK_POS; +- net.minecraft.world.level.chunk.LevelChunk lastChunk = null; +- for (int fz = minZ; fz <= maxZ; ++fz) { +- tempPos.setZ(fz); +- for (int fx = minX; fx <= maxX; ++fx) { +- final int newChunkX = fx >> 4; +- final int newChunkZ = fz >> 4; +- final net.minecraft.world.level.chunk.LevelChunk chunk = lastChunkKey == (lastChunkKey = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(newChunkX, newChunkZ)) ? +- lastChunk : (lastChunk = (net.minecraft.world.level.chunk.LevelChunk)chunkProvider.getChunk(newChunkX, newChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, true)); +- tempPos.setX(fx); +- for (int fy = minY; fy <= maxY; ++fy) { +- tempPos.setY(fy); ++ final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(world); ++ final net.minecraft.world.level.chunk.ChunkSource chunkSource = world.getChunkSource(); ++ final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); + +- final BlockState state = chunk.getBlockState(tempPos); ++ for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { ++ for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { ++ final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, true).getSections(); + +- if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)state).moonrise$emptyCollisionShape() || !state.isSuffocating(this.level, tempPos)) { ++ for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) { ++ final int sectionIdx = currChunkY - minSection; ++ if (sectionIdx < 0 || sectionIdx >= sections.length) { + continue; + } +- +- // Yes, it does not use the Entity context stuff. +- final VoxelShape collisionShape = state.getCollisionShape(this.level, tempPos); +- +- if (collisionShape.isEmpty()) { ++ final net.minecraft.world.level.chunk.LevelChunkSection section = sections[sectionIdx]; ++ if (section.hasOnlyAir()) { ++ // empty + continue; + } + +- final AABB toCollide = box.move(-(double)fx, -(double)fy, -(double)fz); ++ final net.minecraft.world.level.chunk.PalettedContainer blocks = section.states; ++ ++ final int minXIterate = currChunkX == minChunkX ? (minBlockX & 15) : 0; ++ final int maxXIterate = currChunkX == maxChunkX ? (maxBlockX & 15) : 15; ++ final int minZIterate = currChunkZ == minChunkZ ? (minBlockZ & 15) : 0; ++ final int maxZIterate = currChunkZ == maxChunkZ ? (maxBlockZ & 15) : 15; ++ final int minYIterate = currChunkY == minChunkY ? (minBlockY & 15) : 0; ++ final int maxYIterate = currChunkY == maxChunkY ? (maxBlockY & 15) : 15; ++ ++ for (int currY = minYIterate; currY <= maxYIterate; ++currY) { ++ final int blockY = currY | (currChunkY << 4); ++ mutablePos.setY(blockY); ++ for (int currZ = minZIterate; currZ <= maxZIterate; ++currZ) { ++ final int blockZ = currZ | (currChunkZ << 4); ++ mutablePos.setZ(blockZ); ++ for (int currX = minXIterate; currX <= maxXIterate; ++currX) { ++ final int blockX = currX | (currChunkX << 4); ++ mutablePos.setX(blockX); ++ ++ final BlockState blockState = blocks.get((currX) | (currZ << 4) | ((currY) << 8)); ++ ++ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockState).moonrise$emptyCollisionShape() ++ || !blockState.isSuffocating(world, mutablePos)) { ++ continue; ++ } + +- final AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)collisionShape).moonrise$getSingleAABBRepresentation(); +- if (singleAABB != null) { +- if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersect(singleAABB, toCollide)) { +- return true; +- } +- continue; +- } ++ // Yes, it does not use the Entity context stuff. ++ final VoxelShape collisionShape = blockState.getCollisionShape(world, mutablePos); ++ ++ if (collisionShape.isEmpty()) { ++ continue; ++ } + +- if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersectNoEmpty(collisionShape, toCollide)) { +- return true; ++ final AABB toCollide = boundingBox.move(-(double)blockX, -(double)blockY, -(double)blockZ); ++ ++ final AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)collisionShape).moonrise$getSingleAABBRepresentation(); ++ if (singleAABB != null) { ++ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersect(singleAABB, toCollide)) { ++ return true; ++ } ++ continue; ++ } ++ ++ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersectNoEmpty(collisionShape, toCollide)) { ++ return true; ++ } ++ continue; ++ } ++ } + } +- continue; + } + } + } +@@ -4451,82 +4539,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + return Mth.lerp(delta, this.yRotO, this.yRot); + } + +- public boolean updateFluidHeightAndDoFluidPushing(TagKey tag, double speed) { ++ // Paper start - optimise collisions ++ public boolean updateFluidHeightAndDoFluidPushing(final TagKey fluid, final double flowScale) { + if (this.touchingUnloadedChunk()) { + return false; +- } else { +- AABB axisalignedbb = this.getBoundingBox().deflate(0.001D); +- int i = Mth.floor(axisalignedbb.minX); +- int j = Mth.ceil(axisalignedbb.maxX); +- int k = Mth.floor(axisalignedbb.minY); +- int l = Mth.ceil(axisalignedbb.maxY); +- int i1 = Mth.floor(axisalignedbb.minZ); +- int j1 = Mth.ceil(axisalignedbb.maxZ); +- double d1 = 0.0D; +- boolean flag = this.isPushedByFluid(); +- boolean flag1 = false; +- Vec3 vec3d = Vec3.ZERO; +- int k1 = 0; +- BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); ++ } + +- for (int l1 = i; l1 < j; ++l1) { +- for (int i2 = k; i2 < l; ++i2) { +- for (int j2 = i1; j2 < j1; ++j2) { +- blockposition_mutableblockposition.set(l1, i2, j2); +- FluidState fluid = this.level().getFluidState(blockposition_mutableblockposition); ++ final AABB boundingBox = this.getBoundingBox().deflate(1.0E-3); + +- if (fluid.is(tag)) { +- double d2 = (double) ((float) i2 + fluid.getHeight(this.level(), blockposition_mutableblockposition)); ++ final Level world = this.level; ++ final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(world); + +- if (d2 >= axisalignedbb.minY) { +- flag1 = true; +- d1 = Math.max(d2 - axisalignedbb.minY, d1); +- if (flag) { +- Vec3 vec3d1 = fluid.getFlow(this.level(), blockposition_mutableblockposition); ++ final int minBlockX = Mth.floor(boundingBox.minX); ++ final int minBlockY = Math.max((minSection << 4), Mth.floor(boundingBox.minY)); ++ final int minBlockZ = Mth.floor(boundingBox.minZ); + +- if (d1 < 0.4D) { +- vec3d1 = vec3d1.scale(d1); +- } ++ // note: bounds are exclusive in Vanilla, so we subtract 1 - our loop expects bounds to be inclusive ++ final int maxBlockX = Mth.ceil(boundingBox.maxX) - 1; ++ final int maxBlockY = Math.min((ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection(world) << 4) | 15, Mth.ceil(boundingBox.maxY) - 1); ++ final int maxBlockZ = Mth.ceil(boundingBox.maxZ) - 1; ++ ++ final boolean isPushable = this.isPushedByFluid(); ++ final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); + +- vec3d = vec3d.add(vec3d1); +- ++k1; ++ Vec3 pushVector = Vec3.ZERO; ++ double totalPushes = 0.0; ++ double maxHeightDiff = 0.0; ++ boolean inFluid = false; ++ ++ final int minChunkX = minBlockX >> 4; ++ final int maxChunkX = maxBlockX >> 4; ++ ++ final int minChunkY = minBlockY >> 4; ++ final int maxChunkY = maxBlockY >> 4; ++ ++ final int minChunkZ = minBlockZ >> 4; ++ final int maxChunkZ = maxBlockZ >> 4; ++ ++ final net.minecraft.world.level.chunk.ChunkSource chunkSource = world.getChunkSource(); ++ ++ for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { ++ for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { ++ final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, false).getSections(); ++ ++ // bound y ++ for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) { ++ final int sectionIdx = currChunkY - minSection; ++ if (sectionIdx < 0 || sectionIdx >= sections.length) { ++ continue; ++ } ++ final net.minecraft.world.level.chunk.LevelChunkSection section = sections[sectionIdx]; ++ if (section.hasOnlyAir()) { ++ // empty ++ continue; ++ } ++ ++ final net.minecraft.world.level.chunk.PalettedContainer blocks = section.states; ++ ++ final int minXIterate = currChunkX == minChunkX ? (minBlockX & 15) : 0; ++ final int maxXIterate = currChunkX == maxChunkX ? (maxBlockX & 15) : 15; ++ final int minZIterate = currChunkZ == minChunkZ ? (minBlockZ & 15) : 0; ++ final int maxZIterate = currChunkZ == maxChunkZ ? (maxBlockZ & 15) : 15; ++ final int minYIterate = currChunkY == minChunkY ? (minBlockY & 15) : 0; ++ final int maxYIterate = currChunkY == maxChunkY ? (maxBlockY & 15) : 15; ++ ++ for (int currY = minYIterate; currY <= maxYIterate; ++currY) { ++ for (int currZ = minZIterate; currZ <= maxZIterate; ++currZ) { ++ for (int currX = minXIterate; currX <= maxXIterate; ++currX) { ++ final FluidState fluidState = blocks.get((currX) | (currZ << 4) | ((currY) << 8)).getFluidState(); ++ ++ if (fluidState.isEmpty() || !fluidState.is(fluid)) { ++ continue; + } +- // CraftBukkit start - store last lava contact location +- if (tag == FluidTags.LAVA) { +- this.lastLavaContact = blockposition_mutableblockposition.immutable(); ++ ++ mutablePos.set(currX | (currChunkX << 4), currY | (currChunkY << 4), currZ | (currChunkZ << 4)); ++ ++ final double height = (double)((float)mutablePos.getY() + fluidState.getHeight(world, mutablePos)); ++ final double diff = height - boundingBox.minY; ++ ++ if (diff < 0.0) { ++ continue; ++ } ++ ++ inFluid = true; ++ maxHeightDiff = Math.max(maxHeightDiff, diff); ++ ++ if (!isPushable) { ++ continue; ++ } ++ ++ ++totalPushes; ++ ++ final Vec3 flow = fluidState.getFlow(world, mutablePos); ++ ++ if (diff < 0.4) { ++ pushVector = pushVector.add(flow.scale(diff)); ++ } else { ++ pushVector = pushVector.add(flow); + } +- // CraftBukkit end + } + } + } + } + } ++ } + +- if (vec3d.length() > 0.0D) { +- if (k1 > 0) { +- vec3d = vec3d.scale(1.0D / (double) k1); +- } ++ this.fluidHeight.put(fluid, maxHeightDiff); + +- if (!(this instanceof Player)) { +- vec3d = vec3d.normalize(); +- } ++ if (pushVector.lengthSqr() == 0.0) { ++ return inFluid; ++ } + +- Vec3 vec3d2 = this.getDeltaMovement(); ++ // note: totalPushes != 0 as pushVector != 0 ++ pushVector = pushVector.scale(1.0 / totalPushes); ++ final Vec3 currMovement = this.getDeltaMovement(); + +- vec3d = vec3d.scale(speed); +- double d3 = 0.003D; ++ if (!((Entity)(Object)this instanceof Player)) { ++ pushVector = pushVector.normalize(); ++ } + +- if (Math.abs(vec3d2.x) < 0.003D && Math.abs(vec3d2.z) < 0.003D && vec3d.length() < 0.0045000000000000005D) { +- vec3d = vec3d.normalize().scale(0.0045000000000000005D); +- } ++ pushVector = pushVector.scale(flowScale); ++ if (Math.abs(currMovement.x) < 0.003 && Math.abs(currMovement.z) < 0.003 && pushVector.length() < 0.0045000000000000005) { ++ pushVector = pushVector.normalize().scale(0.0045000000000000005); ++ } + +- this.setDeltaMovement(this.getDeltaMovement().add(vec3d)); +- } ++ this.setDeltaMovement(currMovement.add(pushVector)); + +- this.fluidHeight.put(tag, d1); +- return flag1; +- } ++ // note: inFluid = true here as pushVector != 0 ++ return true; + } ++ // Paper end - optimise collisions + + public boolean touchingUnloadedChunk() { + AABB axisalignedbb = this.getBoundingBox().inflate(1.0D); +diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java +index a908bf1dc5e821dcf6981a8c21076fb0bdc6516d..42642b49a4ed6d06f52e4076dfb745b32a964a34 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java ++++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java +@@ -73,8 +73,7 @@ public class PoiManager extends SectionStorage implements ca.spotted + + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Accessing poi chunk off-main"); + +- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager manager = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager; +- final ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk ret = manager.getPoiChunkIfLoaded(chunkX, chunkZ, true); ++ final ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk ret = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager.getPoiChunkIfLoaded(chunkX, chunkZ, true); + + return ret == null ? Optional.empty() : ret.getSectionForVanilla(chunkY); + } +@@ -128,9 +127,13 @@ public class PoiManager extends SectionStorage implements ca.spotted + public final void moonrise$onUnload(final long coordinate) { // Paper - rewrite chunk system + final int chunkX = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkX(coordinate); + final int chunkZ = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkZ(coordinate); ++ ++ final int minY = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(this.world); ++ final int maxY = ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection(this.world); ++ + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Unloading poi chunk off-main"); +- for (int section = this.levelHeightAccessor.getMinSection(); section < this.levelHeightAccessor.getMaxSection(); ++section) { +- final long sectionPos = SectionPos.asLong(chunkX, section, chunkZ); ++ for (int sectionY = minY; sectionY <= maxY; ++sectionY) { ++ final long sectionPos = SectionPos.asLong(chunkX, sectionY, chunkZ); + this.updateDistanceTracking(sectionPos); + } + } +@@ -139,8 +142,12 @@ public class PoiManager extends SectionStorage implements ca.spotted + public final void moonrise$loadInPoiChunk(final ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk poiChunk) { + final int chunkX = poiChunk.chunkX; + final int chunkZ = poiChunk.chunkZ; ++ ++ final int minY = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(this.world); ++ final int maxY = ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection(this.world); ++ + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Loading poi chunk off-main"); +- for (int sectionY = this.levelHeightAccessor.getMinSection(); sectionY < this.levelHeightAccessor.getMaxSection(); ++sectionY) { ++ for (int sectionY = minY; sectionY <= maxY; ++sectionY) { + final PoiSection section = poiChunk.getSection(sectionY); + if (section != null && !((ca.spottedleaf.moonrise.patches.chunk_system.level.poi.ChunkSystemPoiSection)section).moonrise$isEmpty()) { + this.onSectionLoad(SectionPos.asLong(chunkX, sectionY, chunkZ)); +@@ -166,22 +173,15 @@ public class PoiManager extends SectionStorage implements ca.spotted + + @Override + public final net.minecraft.nbt.CompoundTag moonrise$read(final int chunkX, final int chunkZ) throws java.io.IOException { +- if (!ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.isRegionFileThread()) { +- return ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.loadData( +- this.world, chunkX, chunkZ, ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.RegionFileType.POI_DATA, +- ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.getIOBlockingPriorityForCurrentThread() +- ); +- } +- return this.moonrise$getRegionStorage().read(new ChunkPos(chunkX, chunkZ)); ++ return ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.loadData( ++ this.world, chunkX, chunkZ, ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionFileType.POI_DATA, ++ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.getIOBlockingPriorityForCurrentThread() ++ ); + } + + @Override + public final void moonrise$write(final int chunkX, final int chunkZ, final net.minecraft.nbt.CompoundTag data) throws java.io.IOException { +- if (!ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.isRegionFileThread()) { +- ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.scheduleSave(this.world, chunkX, chunkZ, data, ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.RegionFileType.POI_DATA); +- return; +- } +- this.moonrise$getRegionStorage().write(new ChunkPos(chunkX, chunkZ), data); ++ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.scheduleSave(this.world, chunkX, chunkZ, data, ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionFileType.POI_DATA); + } + // Paper end - rewrite chunk system + +@@ -359,8 +359,10 @@ public class PoiManager extends SectionStorage implements ca.spotted + } + + public int sectionsToVillage(SectionPos pos) { +- this.villageDistanceTracker.propagateUpdates(); // Paper - rewrite chunk system +- return convertBetweenLevels(this.villageDistanceTracker.getLevel(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkSectionKey(pos))); // Paper - rewrite chunk system ++ // Paper start - rewrite chunk system ++ this.villageDistanceTracker.propagateUpdates(); ++ return convertBetweenLevels(this.villageDistanceTracker.getLevel(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkSectionKey(pos))); ++ // Paper end - rewrite chunk system + } + + boolean isVillageCenter(long pos) { +diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java +index 11e895d837794d79a76303b912092096bd7d07a8..f1458b0153f6a93875f2e439759324985fa13556 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java ++++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java +@@ -43,7 +43,7 @@ public class PoiSection implements ca.spottedleaf.moonrise.patches.chunk_system. + } + + // Paper start - rewrite chunk system +- private final Optional noAllocOptional = Optional.of((PoiSection)(Object)this);; ++ private final Optional noAllocOptional = Optional.of((PoiSection)(Object)this); + + @Override + public final boolean moonrise$isEmpty() { +diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java +index 507671476c3d2d92a2fdb05be24443af27d26dcf..41ecc30c1e38bf84655464d539ced43549b35d20 100644 +--- a/src/main/java/net/minecraft/world/level/Level.java ++++ b/src/main/java/net/minecraft/world/level/Level.java +@@ -280,26 +280,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + } + // Paper end - rewrite chunk system + // Paper start - optimise collisions +- private final int minSection; +- private final int maxSection; +- +- @Override +- public final int moonrise$getMinSection() { +- return this.minSection; +- } +- +- @Override +- public final int moonrise$getMaxSection() { +- return this.maxSection; +- } +- + /** + * Route to faster lookup. + * See {@link EntityGetter#isUnobstructed(Entity, VoxelShape)} for expected behavior + * @author Spottedleaf + */ + @Override +- public final boolean isUnobstructed(final Entity entity) { ++ public boolean isUnobstructed(final Entity entity) { + final AABB boundingBox = entity.getBoundingBox(); + if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(boundingBox)) { + return false; +@@ -329,7 +316,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + final Vec3 to = clipContext.getTo(); + final Vec3 from = clipContext.getFrom(); + +- return net.minecraft.world.phys.BlockHitResult.miss(to, Direction.getNearest(from.x - to.x, from.y - to.y, from.z - to.z), BlockPos.containing(to.x, to.y, to.z)); ++ return net.minecraft.world.phys.BlockHitResult.miss(to, Direction.getApproximateNearest(from.x - to.x, from.y - to.y, from.z - to.z), BlockPos.containing(to.x, to.y, to.z)); + } + + private static final FluidState AIR_FLUIDSTATE = Fluids.EMPTY.defaultFluidState(); +@@ -383,7 +370,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + int lastChunkY = Integer.MIN_VALUE; + int lastChunkZ = Integer.MIN_VALUE; + +- final int minSection = ((ca.spottedleaf.moonrise.patches.collisions.world.CollisionLevel)level).moonrise$getMinSection(); ++ final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(level); + + for (;;) { + currPos.set(currX, currY, currZ); +@@ -466,7 +453,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + * @author Spottedleaf + */ + @Override +- public final net.minecraft.world.phys.BlockHitResult clip(final ClipContext clipContext) { ++ public net.minecraft.world.phys.BlockHitResult clip(final ClipContext clipContext) { + // can only do this in this class, as not everything that implements BlockGetter can retrieve chunks + return fastClip(clipContext.getFrom(), clipContext.getTo(), (Level)(Object)this, clipContext); + } +@@ -476,7 +463,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + * @author Spottedleaf + */ + @Override +- public final boolean collidesWithSuffocatingBlock(final Entity entity, final AABB box) { ++ public boolean collidesWithSuffocatingBlock(final Entity entity, final AABB box) { + return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisionsForBlocksOrWorldBorder((Level)(Object)this, entity, box, null, null, + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_ONLY, + (final BlockState state, final BlockPos pos) -> { +@@ -502,8 +489,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + * @author Spottedleaf + */ + @Override +- public final java.util.Optional findFreePosition(final Entity entity, final VoxelShape boundsShape, final Vec3 fromPosition, +- final double rangeX, final double rangeY, final double rangeZ) { ++ public java.util.Optional findFreePosition(final Entity entity, final VoxelShape boundsShape, final Vec3 fromPosition, ++ final double rangeX, final double rangeY, final double rangeZ) { + if (boundsShape.isEmpty()) { + return java.util.Optional.empty(); + } +@@ -562,103 +549,139 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + * @author Spottedleaf + */ + @Override +- public final java.util.Optional findSupportingBlock(final Entity entity, final AABB aabb) { ++ public java.util.Optional findSupportingBlock(final Entity entity, final AABB aabb) { ++ final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection((Level)(Object)this); ++ + final int minBlockX = Mth.floor(aabb.minX - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) - 1; + final int maxBlockX = Mth.floor(aabb.maxX + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) + 1; + +- final int minBlockY = Mth.floor(aabb.minY - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) - 1; +- final int maxBlockY = Mth.floor(aabb.maxY + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) + 1; ++ final int minBlockY = Math.max((minSection << 4) - 1, Mth.floor(aabb.minY - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) - 1); ++ final int maxBlockY = Math.min((ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection((Level)(Object)this) << 4) + 16, Mth.floor(aabb.maxY + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) + 1); + + final int minBlockZ = Mth.floor(aabb.minZ - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) - 1; + final int maxBlockZ = Mth.floor(aabb.maxZ + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) + 1; + +- ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext collisionContext = null; +- +- final BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); ++ final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); ++ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext collisionShape = new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext(entity); + BlockPos selected = null; + double selectedDistance = Double.MAX_VALUE; +- + final Vec3 entityPos = entity.position(); + +- LevelChunk lastChunk = null; +- int lastChunkX = Integer.MIN_VALUE; +- int lastChunkZ = Integer.MIN_VALUE; ++ // special cases: ++ if (minBlockY > maxBlockY) { ++ // no point in checking ++ return java.util.Optional.empty(); ++ } + +- final ChunkSource chunkSource = this.getChunkSource(); ++ final int minChunkX = minBlockX >> 4; ++ final int maxChunkX = maxBlockX >> 4; + +- for (int currZ = minBlockZ; currZ <= maxBlockZ; ++currZ) { +- pos.setZ(currZ); +- for (int currX = minBlockX; currX <= maxBlockX; ++currX) { +- pos.setX(currX); ++ final int minChunkY = minBlockY >> 4; ++ final int maxChunkY = maxBlockY >> 4; + +- final int newChunkX = currX >> 4; +- final int newChunkZ = currZ >> 4; ++ final int minChunkZ = minBlockZ >> 4; ++ final int maxChunkZ = maxBlockZ >> 4; + +- if (((newChunkX ^ lastChunkX) | (newChunkZ ^ lastChunkZ)) != 0) { +- lastChunkX = newChunkX; +- lastChunkZ = newChunkZ; +- lastChunk = (LevelChunk)chunkSource.getChunk(newChunkX, newChunkZ, ChunkStatus.FULL, false); +- } ++ final ChunkSource chunkSource = this.getChunkSource(); ++ ++ for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { ++ for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { ++ final ChunkAccess chunk = chunkSource.getChunk(currChunkX, currChunkZ, ChunkStatus.FULL, false); + +- if (lastChunk == null) { ++ if (chunk == null) { + continue; + } +- for (int currY = minBlockY; currY <= maxBlockY; ++currY) { +- int edgeCount = ((currX == minBlockX || currX == maxBlockX) ? 1 : 0) + +- ((currY == minBlockY || currY == maxBlockY) ? 1 : 0) + +- ((currZ == minBlockZ || currZ == maxBlockZ) ? 1 : 0); +- if (edgeCount == 3) { +- continue; +- } + +- pos.setY(currY); ++ final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections(); + +- final double distance = pos.distToCenterSqr(entityPos); +- if (distance > selectedDistance || (distance == selectedDistance && selected.compareTo(pos) >= 0)) { ++ // bound y ++ for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) { ++ final int sectionIdx = currChunkY - minSection; ++ if (sectionIdx < 0 || sectionIdx >= sections.length) { + continue; + } +- +- final BlockState state = ((ca.spottedleaf.moonrise.patches.chunk_getblock.GetBlockChunk)lastChunk).moonrise$getBlock(currX, currY, currZ); +- if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)state).moonrise$emptyCollisionShape()) { ++ final net.minecraft.world.level.chunk.LevelChunkSection section = sections[sectionIdx]; ++ if (section.hasOnlyAir()) { ++ // empty + continue; + } + +- VoxelShape blockCollision = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)state).moonrise$getConstantCollisionShape(); +- +- if ((edgeCount != 1 || state.hasLargeCollisionShape()) && (edgeCount != 2 || state.getBlock() == Blocks.MOVING_PISTON)) { +- if (collisionContext == null) { +- collisionContext = new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext(entity); +- } +- +- if (blockCollision == null) { +- blockCollision = state.getCollisionShape((Level)(Object)this, pos, collisionContext); +- } +- +- if (blockCollision.isEmpty()) { +- continue; +- } +- +- // avoid VoxelShape#move by shifting the entity collision shape instead +- final AABB shiftedAABB = aabb.move(-(double)currX, -(double)currY, -(double)currZ); +- +- final AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation(); +- if (singleAABB != null) { +- if (!ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersect(singleAABB, shiftedAABB)) { +- continue; ++ final boolean hasSpecial = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$hasSpecialCollidingBlocks(); ++ final int sectionAdjust = !hasSpecial ? 1 : 0; ++ ++ final net.minecraft.world.level.chunk.PalettedContainer blocks = section.states; ++ ++ final int minXIterate = currChunkX == minChunkX ? (minBlockX & 15) + sectionAdjust : 0; ++ final int maxXIterate = currChunkX == maxChunkX ? (maxBlockX & 15) - sectionAdjust : 15; ++ final int minZIterate = currChunkZ == minChunkZ ? (minBlockZ & 15) + sectionAdjust : 0; ++ final int maxZIterate = currChunkZ == maxChunkZ ? (maxBlockZ & 15) - sectionAdjust : 15; ++ final int minYIterate = currChunkY == minChunkY ? (minBlockY & 15) + sectionAdjust : 0; ++ final int maxYIterate = currChunkY == maxChunkY ? (maxBlockY & 15) - sectionAdjust : 15; ++ ++ for (int currY = minYIterate; currY <= maxYIterate; ++currY) { ++ final int blockY = currY | (currChunkY << 4); ++ mutablePos.setY(blockY); ++ for (int currZ = minZIterate; currZ <= maxZIterate; ++currZ) { ++ final int blockZ = currZ | (currChunkZ << 4); ++ mutablePos.setZ(blockZ); ++ for (int currX = minXIterate; currX <= maxXIterate; ++currX) { ++ final int localBlockIndex = (currX) | (currZ << 4) | ((currY) << 8); ++ final int blockX = currX | (currChunkX << 4); ++ mutablePos.setX(blockX); ++ ++ final int edgeCount = hasSpecial ? ((blockX == minBlockX || blockX == maxBlockX) ? 1 : 0) + ++ ((blockY == minBlockY || blockY == maxBlockY) ? 1 : 0) + ++ ((blockZ == minBlockZ || blockZ == maxBlockZ) ? 1 : 0) : 0; ++ if (edgeCount == 3) { ++ continue; ++ } ++ ++ final double distance = mutablePos.distToCenterSqr(entityPos); ++ if (distance > selectedDistance || (distance == selectedDistance && selected.compareTo(mutablePos) >= 0)) { ++ continue; ++ } ++ ++ final BlockState blockData = blocks.get(localBlockIndex); ++ ++ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockData).moonrise$emptyContextCollisionShape()) { ++ continue; ++ } ++ ++ VoxelShape blockCollision = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockData).moonrise$getConstantContextCollisionShape(); ++ ++ if (edgeCount == 0 || ((edgeCount != 1 || blockData.hasLargeCollisionShape()) && (edgeCount != 2 || blockData.getBlock() == Blocks.MOVING_PISTON))) { ++ if (blockCollision == null) { ++ blockCollision = blockData.getCollisionShape((Level)(Object)this, mutablePos, collisionShape); ++ ++ if (blockCollision.isEmpty()) { ++ continue; ++ } ++ } ++ ++ // avoid VoxelShape#move by shifting the entity collision shape instead ++ final AABB shiftedAABB = aabb.move(-(double)blockX, -(double)blockY, -(double)blockZ); ++ ++ final AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation(); ++ if (singleAABB != null) { ++ if (!ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersect(singleAABB, shiftedAABB)) { ++ continue; ++ } ++ ++ selected = mutablePos.immutable(); ++ selectedDistance = distance; ++ continue; ++ } ++ ++ if (!ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersectNoEmpty(blockCollision, shiftedAABB)) { ++ continue; ++ } ++ ++ selected = mutablePos.immutable(); ++ selectedDistance = distance; ++ continue; ++ } + } +- +- selected = pos.immutable(); +- selectedDistance = distance; +- continue; + } +- +- if (!ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersectNoEmpty(blockCollision, shiftedAABB)) { +- continue; +- } +- +- selected = pos.immutable(); +- selectedDistance = distance; +- continue; + } + } + } +@@ -667,6 +690,74 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + return java.util.Optional.ofNullable(selected); + } + // Paper end - optimise collisions ++ // Paper start - getblock optimisations - cache world height/sections ++ private final int minY; ++ private final int height; ++ private final int maxY; ++ private final int minSectionY; ++ private final int maxSectionY; ++ private final int sectionsCount; ++ ++ @Override ++ public int getMinY() { ++ return this.minY; ++ } ++ ++ @Override ++ public int getHeight() { ++ return this.height; ++ } ++ ++ @Override ++ public int getMaxY() { ++ return this.maxY; ++ } ++ ++ @Override ++ public int getSectionsCount() { ++ return this.sectionsCount; ++ } ++ ++ @Override ++ public int getMinSectionY() { ++ return this.minSectionY; ++ } ++ ++ @Override ++ public int getMaxSectionY() { ++ return this.maxSectionY; ++ } ++ ++ @Override ++ public boolean isInsideBuildHeight(final int blockY) { ++ return blockY >= this.minY && blockY <= this.maxY; ++ } ++ ++ @Override ++ public boolean isOutsideBuildHeight(final BlockPos pos) { ++ return this.isOutsideBuildHeight(pos.getY()); ++ } ++ ++ @Override ++ public boolean isOutsideBuildHeight(final int blockY) { ++ return blockY < this.minY || blockY > this.maxY; ++ } ++ ++ @Override ++ public int getSectionIndex(final int blockY) { ++ return (blockY >> 4) - this.minSectionY; ++ } ++ ++ @Override ++ public int getSectionIndexFromSectionY(final int sectionY) { ++ return sectionY - this.minSectionY; ++ } ++ ++ @Override ++ public int getSectionYFromSectionIndex(final int sectionIdx) { ++ return sectionIdx + this.minSectionY; ++ } ++ // Paper end - getblock optimisations - cache world height/sections + // Paper start - optimise random ticking + @Override + public abstract Holder getUncachedNoiseBiome(final int x, final int y, final int z); +@@ -685,6 +776,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + // Paper end - optimise random ticking + + protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - create paper world config & Anti-Xray ++ // Paper start - getblock optimisations - cache world height/sections ++ final DimensionType dimType = holder.value(); ++ this.minY = dimType.minY(); ++ this.height = dimType.height(); ++ this.maxY = this.minY + this.height - 1; ++ this.minSectionY = this.minY >> 4; ++ this.maxSectionY = this.maxY >> 4; ++ this.sectionsCount = this.maxSectionY - this.minSectionY + 1; ++ // Paper end - getblock optimisations - cache world height/sections + this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot + this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config + this.generator = gen; +diff --git a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java +index 01352cc83b25eb0e30b7e0ff521fc7c1b3d5155b..90f8360f547ce709fd13ee34f8e67d8bfa94b498 100644 +--- a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java ++++ b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java +@@ -98,8 +98,7 @@ public class BiomeManager { + } + + private static double getFiddle(long l) { +- double d = (double)Math.floorMod(l >> 24, 1024) / 1024.0; +- return (d - 0.5) * 0.9; ++ return (double)(((l >> 24) & (1024 - 1)) - (1024/2)) * (0.9 / 1024.0); // Paper - avoid floorMod, fp division, and fp subtraction + } + + public interface NoiseBiomeSource { +diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +index d0109633e8bdf109cfc9178963d7b6cf92f8b189..ad9c85c19146970371106050ec009a96075769c1 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java ++++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +@@ -796,18 +796,12 @@ public abstract class BlockBehaviour implements FeatureElement { + private boolean isRandomlyTicking; + + // Paper start - rewrite chunk system +- private int opacityIfCached; + private boolean isConditionallyFullOpaque; + + @Override + public final boolean starlight$isConditionallyFullOpaque() { + return this.isConditionallyFullOpaque; + } +- +- @Override +- public final int starlight$getOpacityIfCached() { +- return this.opacityIfCached; +- } + // Paper end - rewrite chunk system + // Paper start - optimise collisions + private static final int RANDOM_OFFSET = 704237939; +@@ -817,16 +811,22 @@ public abstract class BlockBehaviour implements FeatureElement { + private final int id2 = it.unimi.dsi.fastutil.HashCommon.murmurHash3(it.unimi.dsi.fastutil.HashCommon.murmurHash3(ID_GENERATOR.getAndIncrement() + RANDOM_OFFSET) + RANDOM_OFFSET); + private boolean occludesFullBlock; + private boolean emptyCollisionShape; ++ private boolean emptyConstantCollisionShape; + private VoxelShape constantCollisionShape; +- private AABB constantAABBCollision; + +- private static void initCaches(final VoxelShape shape) { ++ private static void initCaches(final VoxelShape shape, final boolean neighbours) { + ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$isFullBlock(); + ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$occludesFullBlock(); + shape.toAabbs(); + if (!shape.isEmpty()) { + shape.bounds(); + } ++ if (neighbours) { ++ for (final Direction direction : DIRECTIONS_CACHED) { ++ initCaches(((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$getFaceShapeClamped(direction), false); ++ initCaches(shape.getFaceShape(direction), false); ++ } ++ } + } + + @Override +@@ -844,6 +844,11 @@ public abstract class BlockBehaviour implements FeatureElement { + return this.emptyCollisionShape; + } + ++ @Override ++ public final boolean moonrise$emptyContextCollisionShape() { ++ return this.emptyConstantCollisionShape; ++ } ++ + @Override + public final int moonrise$uniqueId1() { + return this.id1; +@@ -855,14 +860,9 @@ public abstract class BlockBehaviour implements FeatureElement { + } + + @Override +- public final VoxelShape moonrise$getConstantCollisionShape() { ++ public final VoxelShape moonrise$getConstantContextCollisionShape() { + return this.constantCollisionShape; + } +- +- @Override +- public final AABB moonrise$getConstantCollisionAABB() { +- return this.constantAABBCollision; +- } + // Paper end - optimise collisions + + protected BlockStateBase(Block block, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { +@@ -931,39 +931,37 @@ public abstract class BlockBehaviour implements FeatureElement { + this.legacySolid = this.calculateSolid(); + // Paper start - rewrite chunk system + this.isConditionallyFullOpaque = this.canOcclude & this.useShapeForLightOcclusion; +- this.opacityIfCached = this.cache == null || this.isConditionallyFullOpaque ? -1 : this.cache.lightBlock; + // Paper end - rewrite chunk system + // Paper start - optimise collisions + if (this.cache != null) { + final VoxelShape collisionShape = this.cache.collisionShape; + try { + this.constantCollisionShape = this.getCollisionShape(null, null, null); +- this.constantAABBCollision = this.constantCollisionShape == null ? null : ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)this.constantCollisionShape).moonrise$getSingleAABBRepresentation(); + } catch (final Throwable throwable) { + this.constantCollisionShape = null; +- this.constantAABBCollision = null; + } + this.occludesFullBlock = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)collisionShape).moonrise$occludesFullBlock(); + this.emptyCollisionShape = collisionShape.isEmpty(); ++ this.emptyConstantCollisionShape = this.constantCollisionShape != null && this.constantCollisionShape.isEmpty(); + // init caches +- initCaches(collisionShape); +- if (collisionShape != Shapes.empty() && collisionShape != Shapes.block()) { +- for (final Direction direction : DIRECTIONS_CACHED) { +- // initialise the directional face shape cache as well +- final VoxelShape shape = Shapes.getFaceShape(collisionShape, direction); +- initCaches(shape); +- } +- } +- if (this.cache.occlusionShapes != null) { +- for (final VoxelShape shape : this.cache.occlusionShapes) { +- initCaches(shape); +- } ++ initCaches(collisionShape, true); ++ if (this.constantCollisionShape != null) { ++ initCaches(this.constantCollisionShape, true); + } + } else { + this.occludesFullBlock = false; + this.emptyCollisionShape = false; ++ this.emptyConstantCollisionShape = false; + this.constantCollisionShape = null; +- this.constantAABBCollision = null; ++ } ++ ++ if (this.occlusionShape != null) { ++ initCaches(this.occlusionShape, true); ++ } ++ if (this.occlusionShapesByFace != null) { ++ for (final VoxelShape shape : this.occlusionShapesByFace) { ++ initCaches(shape, true); ++ } + } + // Paper end - optimise collisions + } +diff --git a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java +index daedcfd867ed6171fb61bdcbded417a11c8a5b0f..97a7860b66be418399912307f8e68db9b4edf121 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java ++++ b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java +@@ -17,7 +17,7 @@ import java.util.stream.Collectors; + import javax.annotation.Nullable; + import net.minecraft.world.level.block.state.properties.Property; + +-public abstract class StateHolder { ++public abstract class StateHolder implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccessStateHolder { // Paper - optimise blockstate property access + public static final String NAME_TAG = "Name"; + public static final String PROPERTIES_TAG = "Properties"; + public static final Function, Comparable>, String> PROPERTY_ENTRY_TO_STRING_FUNCTION = new Function, Comparable>, String>() { +@@ -36,14 +36,28 @@ public abstract class StateHolder { + } + }; + protected final O owner; +- private final Reference2ObjectArrayMap, Comparable> values; ++ private Reference2ObjectArrayMap, Comparable> values; // Paper - optimise blockstate property access - remove final + private Table, Comparable, S> neighbours; + protected final MapCodec propertiesCodec; + ++ // Paper start - optimise blockstate property access ++ protected ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.util.ZeroCollidingReferenceStateTable optimisedTable; ++ protected final long tableIndex; ++ ++ @Override ++ public final long moonrise$getTableIndex() { ++ return this.tableIndex; ++ } ++ // Paper end - optimise blockstate property access ++ + protected StateHolder(O owner, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { + this.owner = owner; + this.values = propertyMap; + this.propertiesCodec = codec; ++ // Paper start - optimise blockstate property access ++ this.optimisedTable = new ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.util.ZeroCollidingReferenceStateTable<>(this.values.keySet()); ++ this.tableIndex = this.optimisedTable.getIndex((StateHolder)(Object)this); ++ // Paper end - optimise blockstate property access + } + + public > S cycle(Property property) { +@@ -80,20 +94,21 @@ public abstract class StateHolder { + } + + public Collection> getProperties() { +- return Collections.unmodifiableCollection(this.values.keySet()); ++ return this.optimisedTable.getProperties(); // Paper - optimise blockstate property access + } + + public > boolean hasProperty(Property property) { +- return this.values.containsKey(property); ++ return property != null && this.optimisedTable.hasProperty(property); // Paper - optimise blockstate property access + } + + public > T getValue(Property property) { +- Comparable comparable = this.values.get(property); +- if (comparable == null) { +- throw new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.owner); +- } else { +- return property.getValueClass().cast(comparable); ++ // Paper start - optimise blockstate property access ++ final T ret = this.optimisedTable.get(this.tableIndex, property); ++ if (ret != null) { ++ return ret; + } ++ throw new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.owner); ++ // Paper end - optimise blockstate property access + } + + public > Optional getOptionalValue(Property property) { +@@ -102,36 +117,52 @@ public abstract class StateHolder { + } + + public , V extends T> S setValue(Property property, V value) { +- Comparable comparable = this.values.get(property); +- if (comparable == null) { +- throw new IllegalArgumentException("Cannot set property " + property + " as it does not exist in " + this.owner); +- } else if (comparable.equals(value)) { +- return (S)this; +- } else { +- S object = this.neighbours.get(property, value); +- if (object == null) { +- throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value"); +- } else { +- return object; +- } ++ // Paper start - optimise blockstate property access ++ final S ret = this.optimisedTable.set(this.tableIndex, property, value); ++ if (ret != null) { ++ return ret; + } ++ throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner); ++ // Paper end - optimise blockstate property access + } + + public , V extends T> S trySetValue(Property property, V value) { +- Comparable comparable = this.values.get(property); +- if (comparable != null && !comparable.equals(value)) { +- S object = this.neighbours.get(property, value); +- if (object == null) { +- throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value"); +- } else { +- return object; +- } +- } else { +- return (S)this; ++ // Paper start - optimise blockstate property access ++ if (property == null) { ++ return (S)(StateHolder)(Object)this; + } ++ final S ret = this.optimisedTable.trySet(this.tableIndex, property, value, (S)(StateHolder)(Object)this); ++ if (ret != null) { ++ return ret; ++ } ++ throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner); ++ // Paper end - optimise blockstate property access + } + + public void populateNeighbours(Map, Comparable>, S> states) { ++ // Paper start - optimise blockstate property access ++ final Map, Comparable>, S> map = states; ++ if (true) { ++ if (this.optimisedTable.isLoaded()) { ++ return; ++ } ++ this.optimisedTable.loadInTable(map); ++ ++ // de-duplicate the tables ++ for (final Map.Entry, Comparable>, S> entry : map.entrySet()) { ++ final S value = entry.getValue(); ++ ((StateHolder)value).optimisedTable = this.optimisedTable; ++ } ++ ++ // remove values arrays ++ for (final Map.Entry, Comparable>, S> entry : map.entrySet()) { ++ final S value = entry.getValue(); ++ ((StateHolder)value).values = null; ++ } ++ ++ return; ++ } ++ // Paper end - optimise blockstate property access + if (this.neighbours != null) { + throw new IllegalStateException(); + } else { +@@ -158,7 +189,11 @@ public abstract class StateHolder { + } + + public Map, Comparable> getValues() { +- return this.values; ++ // Paper start - optimise blockstate property access ++ ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.util.ZeroCollidingReferenceStateTable table = this.optimisedTable; ++ // We have to use this.values until the table is loaded ++ return table.isLoaded() ? table.getMapView(this.tableIndex) : this.values; ++ // Paper end - optimise blockstate property access + } + + protected static > Codec codec(Codec codec, Function ownerToStateFunction) { +diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java +index b63116b333b6e06494091a82588acfb639bddb71..054a2569b5b103835facef1e34867c60884e5c29 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java ++++ b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java +@@ -4,11 +4,21 @@ import com.google.common.collect.ImmutableSet; + import java.util.Collection; + import java.util.Optional; + +-public class BooleanProperty extends Property { ++public class BooleanProperty extends Property implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access + private final ImmutableSet values = ImmutableSet.of(true, false); + ++ // Paper start - optimise blockstate property access ++ private static final Boolean[] BY_ID = new Boolean[]{ Boolean.FALSE, Boolean.TRUE }; ++ ++ @Override ++ public final int moonrise$getIdFor(final Boolean value) { ++ return value.booleanValue() ? 1 : 0; ++ } ++ // Paper end - optimise blockstate property access ++ + protected BooleanProperty(String name) { + super(name, Boolean.class); ++ this.moonrise$setById(BY_ID); // Paper - optimise blockstate property access + } + + @Override +diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java +index 3097298fe356df98967cf4bdeaaede69dfe8a441..c23cb4ac167799e61ab9a4e1f43a5722d596332e 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java ++++ b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java +@@ -11,10 +11,38 @@ import java.util.function.Predicate; + import java.util.stream.Collectors; + import net.minecraft.util.StringRepresentable; + +-public class EnumProperty & StringRepresentable> extends Property { ++public class EnumProperty & StringRepresentable> extends Property implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access + private final ImmutableSet values; + private final Map names = Maps.newHashMap(); + ++ // Paper start - optimise blockstate property access ++ private int[] idLookupTable; ++ ++ @Override ++ public final int moonrise$getIdFor(final T value) { ++ final Class target = this.getValueClass(); ++ return ((value.getClass() != target && value.getDeclaringClass() != target)) ? -1 : this.idLookupTable[value.ordinal()]; ++ } ++ ++ private void init() { ++ final Collection values = this.getPossibleValues(); ++ final Class clazz = this.getValueClass(); ++ ++ int id = 0; ++ this.idLookupTable = new int[clazz.getEnumConstants().length]; ++ Arrays.fill(this.idLookupTable, -1); ++ final T[] byId = (T[])java.lang.reflect.Array.newInstance(clazz, values.size()); ++ ++ for (final T value : values) { ++ final int valueId = id++; ++ this.idLookupTable[value.ordinal()] = valueId; ++ byId[valueId] = value; ++ } ++ ++ this.moonrise$setById(byId); ++ } ++ // Paper end - optimise blockstate property access ++ + protected EnumProperty(String name, Class type, Collection values) { + super(name, type); + this.values = ImmutableSet.copyOf(values); +@@ -27,6 +55,7 @@ public class EnumProperty & StringRepresentable> extends Prope + + this.names.put(string, enum_); + } ++ this.init(); // Paper - optimise blockstate property access + } + + @Override +diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java +index 3a850321a4bcc68058483b5fd53e829c425a68af..4a21ec538d7410159bb26b9bf3701605b5ef317f 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java ++++ b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java +@@ -6,11 +6,33 @@ import java.util.Collection; + import java.util.Optional; + import java.util.Set; + +-public class IntegerProperty extends Property { ++public class IntegerProperty extends Property implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access + private final ImmutableSet values; + public final int min; + public final int max; + ++ // Paper start - optimise blockstate property access ++ @Override ++ public final int moonrise$getIdFor(final Integer value) { ++ final int val = value.intValue(); ++ final int ret = val - this.min; ++ ++ return ret | ((this.max - ret) >> 31); ++ } ++ ++ private void init() { ++ final int min = this.min; ++ final int max = this.max; ++ ++ final Integer[] byId = new Integer[max - min + 1]; ++ for (int i = min; i <= max; ++i) { ++ byId[i - min] = Integer.valueOf(i); ++ } ++ ++ this.moonrise$setById(byId); ++ } ++ // Paper end - optimise blockstate property access ++ + protected IntegerProperty(String name, int min, int max) { + super(name, Integer.class); + if (min < 0) { +@@ -28,6 +50,7 @@ public class IntegerProperty extends Property { + + this.values = ImmutableSet.copyOf(set); + } ++ this.init(); // Paper - optimise blockstate property access + } + + @Override +diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java +index 9055f15af0cae55effa6942913a9d7edf3857e07..e63a7541f43e5c8f92f348c4e49756b33698c668 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java ++++ b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java +@@ -10,7 +10,7 @@ import java.util.stream.Stream; + import javax.annotation.Nullable; + import net.minecraft.world.level.block.state.StateHolder; + +-public abstract class Property> { ++public abstract class Property> implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access + private final Class clazz; + private final String name; + @Nullable +@@ -24,9 +24,38 @@ public abstract class Property> { + ); + private final Codec> valueCodec = this.codec.xmap(this::value, Property.Value::value); + ++ // Paper start - optimise blockstate property access ++ private static final java.util.concurrent.atomic.AtomicInteger ID_GENERATOR = new java.util.concurrent.atomic.AtomicInteger(); ++ private final int id; ++ private T[] byId; ++ ++ @Override ++ public final int moonrise$getId() { ++ return this.id; ++ } ++ ++ @Override ++ public final T moonrise$getById(final int id) { ++ final T[] byId = this.byId; ++ return id < 0 || id >= byId.length ? null : this.byId[id]; ++ } ++ ++ @Override ++ public final void moonrise$setById(final T[] byId) { ++ if (this.byId != null) { ++ throw new IllegalStateException(); ++ } ++ this.byId = byId; ++ } ++ ++ @Override ++ public abstract int moonrise$getIdFor(final T value); ++ // Paper end - optimise blockstate property access ++ + protected Property(String name, Class type) { + this.clazz = type; + this.name = name; ++ this.id = ID_GENERATOR.getAndIncrement(); // Paper - optimise blockstate property access + } + + public Property.Value value(T value) { +diff --git a/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java b/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java +index c5e1040c239874dcf20b79472bf690ee7f0a9e5f..0f403e0c257b1304be2ede89b8529676dbe8c32b 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java ++++ b/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java +@@ -8,12 +8,19 @@ import net.minecraft.network.FriendlyByteBuf; + import net.minecraft.network.VarInt; + import net.minecraft.util.CrudeIncrementalIntIdentityHashBiMap; + +-public class HashMapPalette implements Palette { ++public class HashMapPalette implements Palette, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Paper - optimise palette reads + private final IdMap registry; + private final CrudeIncrementalIntIdentityHashBiMap values; + private final PaletteResize resizeHandler; + private final int bits; + ++ // Paper start - optimise palette reads ++ @Override ++ public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData container) { ++ return ((ca.spottedleaf.moonrise.patches.fast_palette.FastPalette)this.values).moonrise$getRawPalette(container); ++ } ++ // Paper end - optimise palette reads ++ + public HashMapPalette(IdMap idList, int bits, PaletteResize listener, List entries) { + this(idList, bits, listener); + entries.forEach(this.values::add); +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 7c11853c5090fbc4fa5b3e73a69acf166158fdec..170df85f42410f4766b04e73fc3a95e6dc4a3b8a 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java ++++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +@@ -53,7 +53,7 @@ import net.minecraft.world.ticks.LevelChunkTicks; + import net.minecraft.world.ticks.TickContainerAccess; + import org.slf4j.Logger; + +-public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk, ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk, ca.spottedleaf.moonrise.patches.chunk_getblock.GetBlockChunk { // Paper - rewrite chunk system // Paper - get block chunk optimisation ++public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk, ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk, ca.spottedleaf.moonrise.patches.getblock.GetBlockChunk { // Paper - rewrite chunk system // Paper - get block chunk optimisation + + static final Logger LOGGER = LogUtils.getLogger(); + private static final TickingBlockEntity NULL_TICKER = new TickingBlockEntity() { +diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java +index c3b1caa352b988ec44fa2b2eb0536517711f5460..df1b3f3ae48f66137484e0eb3f4c7323269e1a74 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java ++++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java +@@ -27,15 +27,17 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + private PalettedContainer> biomes; + + // Paper start - block counting +- private static final it.unimi.dsi.fastutil.ints.IntArrayList FULL_LIST = new it.unimi.dsi.fastutil.ints.IntArrayList(16*16*16); ++ private static final it.unimi.dsi.fastutil.shorts.ShortArrayList FULL_LIST = new it.unimi.dsi.fastutil.shorts.ShortArrayList(16*16*16); + static { +- for (int i = 0; i < (16*16*16); ++i) { ++ for (short i = 0; i < (16*16*16); ++i) { + FULL_LIST.add(i); + } + } + +- private int specialCollidingBlocks; +- private final ca.spottedleaf.moonrise.common.list.IBlockDataList tickingBlocks = new ca.spottedleaf.moonrise.common.list.IBlockDataList(); ++ private boolean isClient; ++ private static final short CLIENT_FORCED_SPECIAL_COLLIDING_BLOCKS = (short)9999; ++ private short specialCollidingBlocks; ++ private final ca.spottedleaf.moonrise.common.list.ShortList tickingBlocks = new ca.spottedleaf.moonrise.common.list.ShortList(); + + @Override + public final int moonrise$getSpecialCollidingBlocks() { +@@ -43,7 +45,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + } + + @Override +- public final ca.spottedleaf.moonrise.common.list.IBlockDataList moonrise$getTickingBlockList() { ++ public final ca.spottedleaf.moonrise.common.list.ShortList moonrise$getTickingBlockList() { + return this.tickingBlocks; + } + // Paper end - block counting +@@ -83,6 +85,45 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + return this.setBlockState(x, y, z, state, true); + } + ++ // Paper start - block counting ++ private void updateBlockCallback(final int x, final int y, final int z, final BlockState newState, ++ final BlockState oldState) { ++ if (oldState == newState) { ++ return; ++ } ++ ++ if (this.isClient) { ++ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(newState)) { ++ this.specialCollidingBlocks = CLIENT_FORCED_SPECIAL_COLLIDING_BLOCKS; ++ } ++ return; ++ } ++ ++ final boolean isSpecialOld = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(oldState); ++ final boolean isSpecialNew = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(newState); ++ if (isSpecialOld != isSpecialNew) { ++ if (isSpecialOld) { ++ --this.specialCollidingBlocks; ++ } else { ++ ++this.specialCollidingBlocks; ++ } ++ } ++ ++ final boolean oldTicking = oldState.isRandomlyTicking(); ++ final boolean newTicking = newState.isRandomlyTicking(); ++ if (oldTicking != newTicking) { ++ final ca.spottedleaf.moonrise.common.list.ShortList tickingBlocks = this.tickingBlocks; ++ final short position = (short)(x | (z << 4) | (y << (4+4))); ++ ++ if (oldTicking) { ++ tickingBlocks.remove(position); ++ } else { ++ tickingBlocks.add(position); ++ } ++ } ++ } ++ // Paper end - block counting ++ + public BlockState setBlockState(int x, int y, int z, BlockState state, boolean lock) { + BlockState iblockdata1; + +@@ -102,7 +143,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + } + } + +- if (!fluid.isEmpty()) { ++ if (!!fluid.isRandomlyTicking()) { // Paper - block counting + --this.tickingFluidCount; + } + +@@ -113,25 +154,11 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + } + } + +- if (!fluid1.isEmpty()) { ++ if (!!fluid1.isRandomlyTicking()) { // Paper - block counting + ++this.tickingFluidCount; + } + +- // Paper start - block counting +- if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(iblockdata1)) { +- --this.specialCollidingBlocks; +- } +- if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(state)) { +- ++this.specialCollidingBlocks; +- } +- +- if (iblockdata1.isRandomlyTicking()) { +- this.tickingBlocks.remove(x, y, z); +- } +- if (state.isRandomlyTicking()) { +- this.tickingBlocks.add(x, y, z, state); +- } +- // Paper end - block counting ++ this.updateBlockCallback(x, y, z, state, iblockdata1); // Paper - block counting + + return iblockdata1; + } +@@ -167,7 +194,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + final int paletteSize = palette.getSize(); + final net.minecraft.util.BitStorage storage = data.storage(); + +- final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap counts; ++ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap counts; + if (paletteSize == 1) { + counts = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1); + counts.put(0, FULL_LIST); +@@ -175,10 +202,10 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + counts = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingBitStorage)storage).moonrise$countEntries(); + } + +- for (final java.util.Iterator> iterator = counts.int2ObjectEntrySet().fastIterator(); iterator.hasNext();) { +- final it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry entry = iterator.next(); ++ for (final java.util.Iterator> iterator = counts.int2ObjectEntrySet().fastIterator(); iterator.hasNext();) { ++ final it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry entry = iterator.next(); + final int paletteIdx = entry.getIntKey(); +- final it.unimi.dsi.fastutil.ints.IntArrayList coordinates = entry.getValue(); ++ final it.unimi.dsi.fastutil.shorts.ShortArrayList coordinates = entry.getValue(); + final int paletteCount = coordinates.size(); + + final BlockState state = palette.valueFor(paletteIdx); +@@ -188,25 +215,30 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + } + + if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(state)) { +- this.specialCollidingBlocks += paletteCount; ++ this.specialCollidingBlocks += (short)paletteCount; + } +- this.nonEmptyBlockCount += paletteCount; ++ this.nonEmptyBlockCount += (short)paletteCount; + if (state.isRandomlyTicking()) { +- this.tickingBlockCount += paletteCount; +- final int[] raw = coordinates.elements(); ++ this.tickingBlockCount += (short)paletteCount; ++ final short[] raw = coordinates.elements(); ++ final int rawLen = raw.length; ++ ++ final ca.spottedleaf.moonrise.common.list.ShortList tickingBlocks = this.tickingBlocks; ++ ++ tickingBlocks.setMinCapacity(Math.min((rawLen + tickingBlocks.size()) * 3 / 2, 16*16*16)); + + java.util.Objects.checkFromToIndex(0, paletteCount, raw.length); + for (int i = 0; i < paletteCount; ++i) { +- this.tickingBlocks.add(raw[i], state); ++ tickingBlocks.add(raw[i]); + } + } + + final FluidState fluid = state.getFluidState(); + + if (!fluid.isEmpty()) { +- //this.nonEmptyBlockCount += count; // fix vanilla bug: make non empty block count correct ++ //this.nonEmptyBlockCount += count; // fix vanilla bug: make non-empty block count correct + if (fluid.isRandomlyTicking()) { +- this.tickingFluidCount += paletteCount; ++ this.tickingFluidCount += (short)paletteCount; + } + } + } +@@ -229,7 +261,11 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + + datapaletteblock.read(buf); + this.biomes = datapaletteblock; +- this.recalcBlockCounts(); // Paper - block counting ++ // Paper start - block counting ++ this.isClient = true; ++ // force has special colliding blocks to be true ++ this.specialCollidingBlocks = this.nonEmptyBlockCount != (short)0 && this.maybeHas(ca.spottedleaf.moonrise.patches.collisions.CollisionUtil::isSpecialCollidingBlock) ? CLIENT_FORCED_SPECIAL_COLLIDING_BLOCKS : (short)0; ++ // Paper end - block counting + } + + public void readBiomes(FriendlyByteBuf buf) { +diff --git a/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java b/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java +index f4c3f2a49b8d023b8ef67529eba30cf31467d8bf..716eb6f406db4b81b8854de0ea693a72f9ca9d13 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java ++++ b/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java +@@ -7,13 +7,20 @@ import net.minecraft.network.FriendlyByteBuf; + import net.minecraft.network.VarInt; + import org.apache.commons.lang3.Validate; + +-public class LinearPalette implements Palette { ++public class LinearPalette implements Palette, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Paper - optimise palette reads + private final IdMap registry; + private final T[] values; + private final PaletteResize resizeHandler; + private final int bits; + private int size; + ++ // Paper start - optimise palette reads ++ @Override ++ public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData container) { ++ return this.values; ++ } ++ // Paper end - optimise palette reads ++ + private LinearPalette(IdMap idList, int bits, PaletteResize listener, List list) { + this.registry = idList; + this.values = (T[])(new Object[1 << bits]); +diff --git a/src/main/java/net/minecraft/world/level/chunk/Palette.java b/src/main/java/net/minecraft/world/level/chunk/Palette.java +index e379f39cc6e03723a5323d8392b4c10bfde65115..882284fe7beeb56a8b35ac6153ff41e84ebad27e 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/Palette.java ++++ b/src/main/java/net/minecraft/world/level/chunk/Palette.java +@@ -5,7 +5,7 @@ import java.util.function.Predicate; + import net.minecraft.core.IdMap; + import net.minecraft.network.FriendlyByteBuf; + +-public interface Palette { ++public interface Palette extends ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Paper - optimise palette reads + int idFor(T object); + + boolean maybeHas(Predicate predicate); +diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +index 13d3c877b006a4975e7370713e3919c661e7890f..955862559b8c751b82082a5c0e02031324bf4805 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java ++++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +@@ -41,6 +41,33 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + // this.threadingDetector.checkAndUnlock(); // Paper - disable this + } + ++ // Paper start - optimise palette reads ++ private void updateData(final PalettedContainer.Data data) { ++ if (data != null) { ++ ((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData)(Object)data).moonrise$setPalette( ++ ((ca.spottedleaf.moonrise.patches.fast_palette.FastPalette)data.palette).moonrise$getRawPalette((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData)(Object)data) ++ ); ++ } ++ } ++ ++ private T readPaletteSlow(final PalettedContainer.Data data, final int paletteIdx) { ++ return data.palette.valueFor(paletteIdx); ++ } ++ ++ private T readPalette(final PalettedContainer.Data data, final int paletteIdx) { ++ final T[] palette = ((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData)(Object)data).moonrise$getPalette(); ++ if (palette == null) { ++ return this.readPaletteSlow(data, paletteIdx); ++ } ++ ++ final T ret = palette[paletteIdx]; ++ if (ret == null) { ++ throw new IllegalArgumentException("Palette index out of bounds"); ++ } ++ return ret; ++ } ++ // Paper end - optimise palette reads ++ + // Paper start - Anti-Xray - Add preset values + @Deprecated @io.papermc.paper.annotation.DoNotUse public static Codec> codecRW(IdMap idList, Codec entryCodec, PalettedContainer.Strategy paletteProvider, T defaultValue) { return PalettedContainer.codecRW(idList, entryCodec, paletteProvider, defaultValue, null); } + public static Codec> codecRW(IdMap idList, Codec entryCodec, PalettedContainer.Strategy paletteProvider, T defaultValue, T @org.jetbrains.annotations.Nullable [] presetValues) { +@@ -113,6 +140,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + } + } + // Paper end ++ this.updateData(this.data); // Paper - optimise palette reads + } + + // Paper start - Anti-Xray - Add preset values +@@ -122,6 +150,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + this.registry = idList; + this.strategy = paletteProvider; + this.data = data; ++ this.updateData(this.data); // Paper - optimise palette reads + } + + // Paper start - Anti-Xray - Add preset values +@@ -133,6 +162,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + this.registry = idList; + this.data = this.createOrReuseData(null, 0); + this.data.palette.idFor(object); ++ this.updateData(this.data); // Paper - optimise palette reads + } + + private PalettedContainer.Data createOrReuseData(@Nullable PalettedContainer.Data previousData, int bits) { +@@ -158,6 +188,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + PalettedContainer.Data data2 = this.createOrReuseData(data, newBits); + data2.copyFrom(data.palette, data.storage); + this.data = data2; ++ this.updateData(this.data); // Paper - optimise palette reads + this.addPresetValues(); + return object == null ? -1 : data2.palette.idFor(object); + // Paper end +@@ -191,9 +222,12 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + } + + private synchronized T getAndSet(int index, T value) { // Paper - synchronize +- int i = this.data.palette.idFor(value); +- int j = this.data.storage.getAndSet(index, i); +- return this.data.palette.valueFor(j); ++ // Paper start - optimise palette reads ++ final int paletteIdx = this.data.palette.idFor(value); ++ final PalettedContainer.Data data = this.data; ++ final int prev = data.storage.getAndSet(index, paletteIdx); ++ return this.readPalette(data, prev); ++ // Paper end - optimise palette reads + } + + public void set(int x, int y, int z, T value) { +@@ -217,8 +251,10 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + } + + public T get(int index) { // Paper - public +- PalettedContainer.Data data = this.data; +- return data.palette.valueFor(data.storage.get(index)); ++ // Paper start - optimise palette reads ++ final PalettedContainer.Data data = this.data; ++ return this.readPalette(data, data.storage.get(index)); ++ // Paper end - optimise palette reads + } + + @Override +@@ -238,6 +274,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + data.palette.read(buf); + buf.readLongArray(data.storage.getRaw()); + this.data = data; ++ this.updateData(this.data); // Paper - optimise palette reads + this.addPresetValues(); // Paper - Anti-Xray - Add preset values (inefficient, but this isn't used by the server) + } finally { + this.release(); +@@ -386,7 +423,44 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + void accept(T object, int count); + } + +- static record Data(PalettedContainer.Configuration configuration, BitStorage storage, Palette palette) { ++ // Paper start - optimise palette reads ++ public static final class Data implements ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData { ++ ++ private final PalettedContainer.Configuration configuration; ++ private final BitStorage storage; ++ private final Palette palette; ++ ++ private T[] moonrise$palette; ++ ++ public Data(final PalettedContainer.Configuration configuration, final BitStorage storage, final Palette palette) { ++ this.configuration = configuration; ++ this.storage = storage; ++ this.palette = palette; ++ } ++ ++ public PalettedContainer.Configuration configuration() { ++ return this.configuration; ++ } ++ ++ public BitStorage storage() { ++ return this.storage; ++ } ++ ++ public Palette palette() { ++ return this.palette; ++ } ++ ++ @Override ++ public final T[] moonrise$getPalette() { ++ return this.moonrise$palette; ++ } ++ ++ @Override ++ public final void moonrise$setPalette(final T[] palette) { ++ this.moonrise$palette = palette; ++ } ++ // Paper end - optimise palette reads ++ + public void copyFrom(Palette palette, BitStorage storage) { + for (int i = 0; i < storage.getSize(); i++) { + T object = palette.valueFor(storage.get(i)); +diff --git a/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java b/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java +index 24b608cfcd6f39db02e682e5d8162dc4ad9fd6d6..3a06392a327f26d78c28fdcce39f74b130c4d906 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java ++++ b/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java +@@ -8,12 +8,24 @@ import net.minecraft.network.FriendlyByteBuf; + import net.minecraft.network.VarInt; + import org.apache.commons.lang3.Validate; + +-public class SingleValuePalette implements Palette { ++public class SingleValuePalette implements Palette, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Paper - optimise palette reads + private final IdMap registry; + @Nullable + private T value; + private final PaletteResize resizeHandler; + ++ // Paper start - optimise palette reads ++ private T[] rawPalette; ++ ++ @Override ++ public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData container) { ++ if (this.rawPalette != null) { ++ return this.rawPalette; ++ } ++ return this.rawPalette = (T[])new Object[] { this.value }; ++ } ++ // Paper end - optimise palette reads ++ + public SingleValuePalette(IdMap idList, PaletteResize listener, List entries) { + this.registry = idList; + this.resizeHandler = listener; +@@ -33,6 +45,11 @@ public class SingleValuePalette implements Palette { + return this.resizeHandler.onResize(1, object); + } else { + this.value = object; ++ // Paper start - optimise palette reads ++ if (this.rawPalette != null) { ++ this.rawPalette[0] = object; ++ } ++ // Paper end - optimise palette reads + return 0; + } + } +@@ -58,6 +75,11 @@ public class SingleValuePalette implements Palette { + @Override + public void read(FriendlyByteBuf buf) { + this.value = this.registry.byIdOrThrow(buf.readVarInt()); ++ // Paper start - optimise palette reads ++ if (this.rawPalette != null) { ++ this.rawPalette[0] = this.value; ++ } ++ // Paper end - optimise palette reads + } + + @Override +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 1e0439cf3f4008fa430acb90b45f5bc4cdd6d7f2..e46bdcbf3514eaa6f4990a797a63c5041a142807 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 +@@ -28,7 +28,7 @@ import net.minecraft.nbt.NbtIo; // Paper + import net.minecraft.world.level.ChunkPos; + import org.slf4j.Logger; + +-public class RegionFile implements AutoCloseable { ++public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile { // Paper - rewrite chunk system + + private static final Logger LOGGER = LogUtils.getLogger(); + private static final int SECTOR_BYTES = 4096; +@@ -51,6 +51,20 @@ public class RegionFile implements AutoCloseable { + private final IntBuffer timestamps; + @VisibleForTesting + protected final RegionBitmap usedSectors; ++ // Paper start - rewrite chunk system ++ @Override ++ public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite(final CompoundTag data, final ChunkPos pos) throws IOException { ++ final RegionFile.ChunkBuffer buffer = ((RegionFile)(Object)this).new ChunkBuffer(pos); ++ ((ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkBuffer)buffer).moonrise$setWriteOnClose(false); ++ ++ final DataOutputStream out = new DataOutputStream(this.version.wrap(buffer)); ++ ++ return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData( ++ data, ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData.WriteResult.WRITE, ++ out, ((ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkBuffer)buffer)::moonrise$write ++ ); ++ } ++ // Paper end - rewrite chunk system + // Paper start - Attempt to recalculate regionfile header if it is corrupt + private static long roundToSectors(long bytes) { + long sectors = bytes >>> 12; // 4096 = 2^12 +@@ -682,6 +696,16 @@ public class RegionFile implements AutoCloseable { + + @Nullable + private DataInputStream createExternalChunkInputStream(ChunkPos pos, byte flags) throws IOException { ++ // Paper start - rewrite chunk system ++ final DataInputStream is = this.createExternalChunkInputStream0(pos, flags); ++ if (is == null) { ++ return is; ++ } ++ return new ca.spottedleaf.moonrise.patches.chunk_system.util.stream.ExternalChunkStreamMarker(is); ++ } ++ @Nullable ++ private DataInputStream createExternalChunkInputStream0(ChunkPos pos, byte flags) throws IOException { ++ // Paper end - rewrite chunk system + Path path = this.getExternalChunkPath(pos); + + if (!Files.isRegularFile(path, new LinkOption[0])) { +@@ -978,10 +1002,29 @@ public class RegionFile implements AutoCloseable { + + } + // Paper end +- private class ChunkBuffer extends ByteArrayOutputStream { ++ private class ChunkBuffer extends ByteArrayOutputStream implements ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkBuffer { // Paper - rewrite chunk system + + private final ChunkPos pos; + ++ // Paper start - rewrite chunk system ++ private boolean writeOnClose = true; ++ ++ @Override ++ public final boolean moonrise$getWriteOnClose() { ++ return this.writeOnClose; ++ } ++ ++ @Override ++ public final void moonrise$setWriteOnClose(final boolean value) { ++ this.writeOnClose = value; ++ } ++ ++ @Override ++ public final void moonrise$write(final RegionFile regionFile) throws IOException { ++ regionFile.write(this.pos, ByteBuffer.wrap(this.buf, 0, this.count)); ++ } ++ // Paper end - rewrite chunk system ++ + public ChunkBuffer(final ChunkPos chunkcoordintpair) { + super(8096); + super.write(0); +@@ -1015,7 +1058,7 @@ public class RegionFile implements AutoCloseable { + + JvmProfiler.INSTANCE.onRegionFileWrite(RegionFile.this.info, this.pos, RegionFile.this.version, i); + bytebuffer.putInt(0, i); +- RegionFile.this.write(this.pos, bytebuffer); ++ if (this.writeOnClose) { RegionFile.this.write(this.pos, bytebuffer); } // Paper - rewrite chunk system + } + } + +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 40689256711cc94a806ca1da346f4f62eda31526..b0ace4c7f25425a58c0707e7a7992446164bef88 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 +@@ -28,8 +28,8 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise + + // Paper start - rewrite chunk system + private static final int REGION_SHIFT = 5; +- private static final int MAX_NON_EXISTING_CACHE = 1024 * 64; +- private final it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet nonExistingRegionFiles = new it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet(MAX_NON_EXISTING_CACHE+1); ++ private static final int MAX_NON_EXISTING_CACHE = 1024 * 4; ++ private final it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet nonExistingRegionFiles = new it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet(); + private static String getRegionFileName(final int chunkX, final int chunkZ) { + return "r." + (chunkX >> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + ".mca"; + } +@@ -104,6 +104,97 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise + + return ret; + } ++ ++ @Override ++ public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite( ++ final int chunkX, final int chunkZ, final CompoundTag compound ++ ) throws IOException { ++ if (compound == null) { ++ return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData( ++ compound, ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData.WriteResult.DELETE, ++ null, null ++ ); ++ } ++ ++ final ChunkPos pos = new ChunkPos(chunkX, chunkZ); ++ final RegionFile regionFile = this.getRegionFile(pos); ++ ++ // note: not required to keep regionfile loaded after this call, as the write param takes a regionfile as input ++ // (and, the regionfile parameter is unused for writing until the write call) ++ final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData writeData = ((ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile)regionFile).moonrise$startWrite(compound, pos); ++ ++ try { ++ NbtIo.write(compound, writeData.output()); ++ } finally { ++ writeData.output().close(); ++ } ++ ++ return writeData; ++ } ++ ++ @Override ++ public final void moonrise$finishWrite( ++ final int chunkX, final int chunkZ, final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData writeData ++ ) throws IOException { ++ final ChunkPos pos = new ChunkPos(chunkX, chunkZ); ++ if (writeData.result() == ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData.WriteResult.DELETE) { ++ final RegionFile regionFile = this.moonrise$getRegionFileIfExists(chunkX, chunkZ); ++ if (regionFile != null) { ++ regionFile.clear(pos); ++ } // else: didn't exist ++ ++ return; ++ } ++ ++ writeData.write().run(this.getRegionFile(pos)); ++ } ++ ++ @Override ++ public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData moonrise$readData( ++ final int chunkX, final int chunkZ ++ ) throws IOException { ++ final RegionFile regionFile = this.moonrise$getRegionFileIfExists(chunkX, chunkZ); ++ ++ final DataInputStream input = regionFile == null ? null : regionFile.getChunkDataInputStream(new ChunkPos(chunkX, chunkZ)); ++ ++ if (input == null) { ++ return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData( ++ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.NO_DATA, null, null ++ ); ++ } ++ ++ final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData ret = new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData( ++ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.HAS_DATA, input, null ++ ); ++ ++ if (!(input instanceof ca.spottedleaf.moonrise.patches.chunk_system.util.stream.ExternalChunkStreamMarker)) { ++ // internal stream, which is fully read ++ return ret; ++ } ++ ++ final CompoundTag syncRead = this.moonrise$finishRead(chunkX, chunkZ, ret); ++ ++ if (syncRead == null) { ++ // need to try again ++ return this.moonrise$readData(chunkX, chunkZ); ++ } ++ ++ return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData( ++ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.SYNC_READ, null, syncRead ++ ); ++ } ++ ++ // if the return value is null, then the caller needs to re-try with a new call to readData() ++ @Override ++ public final CompoundTag moonrise$finishRead( ++ final int chunkX, final int chunkZ, final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData readData ++ ) throws IOException { ++ try { ++ return NbtIo.read(readData.input()); ++ } finally { ++ readData.input().close(); ++ } ++ } + // Paper end - rewrite chunk system + // Paper start - recalculate region file headers + private final boolean isChunkData; +@@ -143,6 +234,12 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise + this.isChunkData = isChunkDataFolder(this.folder); // Paper - recalculate region file headers + } + ++ // Paper start - rewrite chunk system ++ public RegionFile getRegionFile(ChunkPos chunkcoordintpair) throws IOException { ++ return this.getRegionFile(chunkcoordintpair, false); ++ } ++ // Paper end - rewrite chunk system ++ + public RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit // Paper - public + // Paper start - rewrite chunk system + if (existingOnly) { +diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +index 1c0712295695727ee9c4d430d4157b8e17cbd71f..7b8e5be1648ef8741aadabd6cbdcf991012c3ce2 100644 +--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java ++++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +@@ -55,6 +55,48 @@ public abstract class FlowingFluid extends Fluid { + }); + private final Map shapes = Maps.newIdentityHashMap(); + ++ // Paper start - fluid method optimisations ++ private FluidState sourceFalling; ++ private FluidState sourceNotFalling; ++ ++ private static final int TOTAL_FLOWING_STATES = FALLING.getPossibleValues().size() * LEVEL.getPossibleValues().size(); ++ private static final int MIN_LEVEL = LEVEL.getPossibleValues().stream().sorted().findFirst().get().intValue(); ++ ++ // index = (falling ? 1 : 0) + level*2 ++ private FluidState[] flowingLookUp; ++ private volatile boolean init; ++ ++ private static final int COLLISION_OCCLUSION_CACHE_SIZE = 2048; ++ private static final ThreadLocal COLLISION_OCCLUSION_CACHE = ThreadLocal.withInitial(() -> new ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey[COLLISION_OCCLUSION_CACHE_SIZE]); ++ ++ ++ /** ++ * Due to init order, we need to use callbacks to initialise our state ++ */ ++ private void init() { ++ synchronized (this) { ++ if (this.init) { ++ return; ++ } ++ this.flowingLookUp = new FluidState[TOTAL_FLOWING_STATES]; ++ final FluidState defaultFlowState = this.getFlowing().defaultFluidState(); ++ for (int i = 0; i < TOTAL_FLOWING_STATES; ++i) { ++ final int falling = i & 1; ++ final int level = (i >>> 1) + MIN_LEVEL; ++ ++ this.flowingLookUp[i] = defaultFlowState.setValue(FALLING, falling == 1 ? Boolean.TRUE : Boolean.FALSE) ++ .setValue(LEVEL, Integer.valueOf(level)); ++ } ++ ++ final FluidState defaultFallState = this.getSource().defaultFluidState(); ++ this.sourceFalling = defaultFallState.setValue(FALLING, Boolean.TRUE); ++ this.sourceNotFalling = defaultFallState.setValue(FALLING, Boolean.FALSE); ++ ++ this.init = true; ++ } ++ } ++ // Paper end - fluid method optimisations ++ + public FlowingFluid() {} + + @Override +@@ -239,53 +281,70 @@ public abstract class FlowingFluid extends Fluid { + } + } + +- private boolean canPassThroughWall(Direction face, BlockGetter world, BlockPos pos, BlockState state, BlockPos fromPos, BlockState fromState) { +- Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap; ++ // Paper start - fluid method optimisations ++ private static boolean canPassThroughWall(final Direction direction, final BlockGetter level, ++ final BlockPos fromPos, final BlockState fromState, ++ final BlockPos toPos, final BlockState toState) { ++ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$emptyCollisionShape() & ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$emptyCollisionShape()) { ++ // don't even try to cache simple cases ++ return true; ++ } + +- if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) { +- object2bytelinkedopenhashmap = (Object2ByteLinkedOpenHashMap) FlowingFluid.OCCLUSION_CACHE.get(); +- } else { +- object2bytelinkedopenhashmap = null; ++ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$occludesFullBlock() | ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$occludesFullBlock()) { ++ // don't even try to cache simple cases ++ return false; + } + +- Block.BlockStatePairKey block_a; ++ final ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey[] cache = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$hasCache() & ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$hasCache() ? ++ COLLISION_OCCLUSION_CACHE.get() : null; + +- if (object2bytelinkedopenhashmap != null) { +- block_a = new Block.BlockStatePairKey(state, fromState, face); +- byte b0 = object2bytelinkedopenhashmap.getAndMoveToFirst(block_a); ++ final int keyIndex ++ = (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$uniqueId1() ^ ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$uniqueId2() ^ ((ca.spottedleaf.moonrise.patches.collisions.util.CollisionDirection)(Object)direction).moonrise$uniqueId()) ++ & (COLLISION_OCCLUSION_CACHE_SIZE - 1); + +- if (b0 != 127) { +- return b0 != 0; ++ if (cache != null) { ++ final ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey cached = cache[keyIndex]; ++ if (cached != null && cached.first() == fromState && cached.second() == toState && cached.direction() == direction) { ++ return cached.result(); + } +- } else { +- block_a = null; + } + +- VoxelShape voxelshape = state.getCollisionShape(world, pos); +- VoxelShape voxelshape1 = fromState.getCollisionShape(world, fromPos); +- boolean flag = !Shapes.mergedFaceOccludes(voxelshape, voxelshape1, face); ++ final VoxelShape shape1 = fromState.getCollisionShape(level, fromPos); ++ final VoxelShape shape2 = toState.getCollisionShape(level, toPos); + +- if (object2bytelinkedopenhashmap != null) { +- if (object2bytelinkedopenhashmap.size() == 200) { +- object2bytelinkedopenhashmap.removeLastByte(); +- } ++ final boolean result = !Shapes.mergedFaceOccludes(shape1, shape2, direction); + +- object2bytelinkedopenhashmap.putAndMoveToFirst(block_a, (byte) (flag ? 1 : 0)); ++ if (cache != null) { ++ // we can afford to replace in-use keys more often due to the excessive caching the collision patch does in mergedFaceOccludes ++ cache[keyIndex] = new ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey(fromState, toState, direction, result); + } + +- return flag; ++ return result; + } ++ // Paper end - fluid method optimisations + + public abstract Fluid getFlowing(); + + public FluidState getFlowing(int level, boolean falling) { +- return (FluidState) ((FluidState) this.getFlowing().defaultFluidState().setValue(FlowingFluid.LEVEL, level)).setValue(FlowingFluid.FALLING, falling); ++ // Paper start - fluid method optimisations ++ final int amount = level; ++ if (!this.init) { ++ this.init(); ++ } ++ final int index = (falling ? 1 : 0) | ((amount - MIN_LEVEL) << 1); ++ return this.flowingLookUp[index]; ++ // Paper end - fluid method optimisations + } + + public abstract Fluid getSource(); + + public FluidState getSource(boolean falling) { +- return (FluidState) this.getSource().defaultFluidState().setValue(FlowingFluid.FALLING, falling); ++ // Paper start - fluid method optimisations ++ if (!this.init) { ++ this.init(); ++ } ++ return falling ? this.sourceFalling : this.sourceNotFalling; ++ // Paper end - fluid method optimisations + } + + protected abstract boolean canConvertToSource(Level world); +diff --git a/src/main/java/net/minecraft/world/level/material/FluidState.java b/src/main/java/net/minecraft/world/level/material/FluidState.java +index 14bb12d2a0066e8b020f2e0e670a7a5c74633623..8ceeb053a391d1a53083eb0680cf34c453afcba2 100644 +--- a/src/main/java/net/minecraft/world/level/material/FluidState.java ++++ b/src/main/java/net/minecraft/world/level/material/FluidState.java +@@ -21,12 +21,30 @@ import net.minecraft.world.level.block.state.properties.Property; + import net.minecraft.world.phys.Vec3; + import net.minecraft.world.phys.shapes.VoxelShape; + +-public final class FluidState extends StateHolder { ++public final class FluidState extends StateHolder implements ca.spottedleaf.moonrise.patches.fluid.FluidFluidState { // Paper - fluid method optimisations + public static final Codec CODEC = codec(BuiltInRegistries.FLUID.byNameCodec(), Fluid::defaultFluidState).stable(); + public static final int AMOUNT_MAX = 9; + public static final int AMOUNT_FULL = 8; + protected final boolean isEmpty; // Paper - Perf: moved from isEmpty() + ++ // Paper start - fluid method optimisations ++ private int amount; ++ //private boolean isEmpty; ++ private boolean isSource; ++ private float ownHeight; ++ private boolean isRandomlyTicking; ++ private BlockState legacyBlock; ++ ++ @Override ++ public final void moonrise$initCaches() { ++ this.amount = this.getType().getAmount((FluidState)(Object)this); ++ //this.isEmpty = this.getType().isEmpty(); ++ this.isSource = this.getType().isSource((FluidState)(Object)this); ++ this.ownHeight = this.getType().getOwnHeight((FluidState)(Object)this); ++ this.isRandomlyTicking = this.getType().isRandomlyTicking(); ++ } ++ // Paper end - fluid method optimisations ++ + public FluidState(Fluid fluid, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { + super(fluid, propertyMap, codec); + this.isEmpty = fluid.isEmpty(); // Paper - Perf: moved from isEmpty() +@@ -37,11 +55,11 @@ public final class FluidState extends StateHolder { + } + + public boolean isSource() { +- return this.getType().isSource(this); ++ return this.isSource; // Paper - fluid method optimisations + } + + public boolean isSourceOfType(Fluid fluid) { +- return this.owner == fluid && this.owner.isSource(this); ++ return this.isSource && this.owner == fluid; // Paper - fluid method optimisations + } + + public boolean isEmpty() { +@@ -53,11 +71,11 @@ public final class FluidState extends StateHolder { + } + + public float getOwnHeight() { +- return this.getType().getOwnHeight(this); ++ return this.ownHeight; // Paper - fluid method optimisations + } + + public int getAmount() { +- return this.getType().getAmount(this); ++ return this.amount; // Paper - fluid method optimisations + } + + public boolean shouldRenderBackwardUpFace(BlockGetter world, BlockPos pos) { +@@ -83,7 +101,7 @@ public final class FluidState extends StateHolder { + } + + public boolean isRandomlyTicking() { +- return this.getType().isRandomlyTicking(); ++ return this.isRandomlyTicking; // Paper - fluid method optimisations + } + + public void randomTick(Level world, BlockPos pos, RandomSource random) { +@@ -95,7 +113,12 @@ public final class FluidState extends StateHolder { + } + + public BlockState createLegacyBlock() { +- return this.getType().createLegacyBlock(this); ++ // Paper start - fluid method optimisations ++ if (this.legacyBlock != null) { ++ return this.legacyBlock; ++ } ++ return this.legacyBlock = this.getType().createLegacyBlock((FluidState)(Object)this); ++ // Paper end - fluid method optimisations + } + + @Nullable +diff --git a/src/main/java/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java +index 1d36f8dcffd22cf844448d3d8351fb8718cf5227..fbe0c4b0fdbb992b7002f6afe1e74d63cbb420f2 100644 +--- a/src/main/java/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java ++++ b/src/main/java/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java +@@ -57,7 +57,7 @@ public abstract class DiscreteVoxelShape implements ca.spottedleaf.moonrise.patc + } + } + +- final boolean hasSingleAABB = sizeX == 1 && sizeY == 1 && sizeZ == 1 && !isEmpty && discreteVoxelShape.isFull(0, 0, 0); ++ final boolean hasSingleAABB = sizeX == 1 && sizeY == 1 && sizeZ == 1 && !isEmpty && (voxelSet[0] & 1L) != 0L; + + final int minFullX = discreteVoxelShape.firstFull(Direction.Axis.X); + final int minFullY = discreteVoxelShape.firstFull(Direction.Axis.Y); +diff --git a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java +index c348171c150bf69d24303d0862e45ab78baddcab..4c8185fbc560a5c5304729e5827ae7762933ec36 100644 +--- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java ++++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java +@@ -180,13 +180,13 @@ public final class Shapes { + final VoxelShape first = tmp[i]; + final VoxelShape second = tmp[next]; + +- tmp[newSize++] = Shapes.or(first, second); ++ tmp[newSize++] = Shapes.joinUnoptimized(first, second, BooleanOp.OR); + } + } + size = newSize; + } + +- return tmp[0]; ++ return tmp[0].optimize(); + // Paper end - optimise collisions + } + +@@ -255,7 +255,22 @@ public final class Shapes { + } + + public static VoxelShape getFaceShape(VoxelShape shape, Direction direction) { +- return ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$getFaceShapeClamped(direction); // Paper - optimise collisions ++ if (shape == block()) { ++ return block(); ++ } else { ++ Direction.Axis axis = direction.getAxis(); ++ boolean bl; ++ int i; ++ if (direction.getAxisDirection() == Direction.AxisDirection.POSITIVE) { ++ bl = DoubleMath.fuzzyEquals(shape.max(axis), 1.0, 1.0E-7); ++ i = shape.shape.getSize(axis) - 1; ++ } else { ++ bl = DoubleMath.fuzzyEquals(shape.min(axis), 0.0, 1.0E-7); ++ i = 0; ++ } ++ ++ return (VoxelShape)(!bl ? empty() : new SliceShape(shape, axis, i)); ++ } + } + + // Paper start - optimise collisions +diff --git a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java +index 11824d39e72fa003b3a56aa9b8d679fe8e23a1a4..c207e54dc52e67ba91dac5c6ce1391a77f597bcd 100644 +--- a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java ++++ b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java +@@ -162,13 +162,13 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll + + if (direction.getAxisDirection() == Direction.AxisDirection.POSITIVE) { + if (DoubleMath.fuzzyEquals(this.max(axis), 1.0, ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)) { +- ret = tryForceBlock(new SliceShape((VoxelShape)(Object)this, axis, this.shape.getSize(axis) - 1)); ++ ret = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.sliceShape((VoxelShape)(Object)this, axis, this.shape.getSize(axis) - 1); + } else { + ret = Shapes.empty(); + } + } else { + if (DoubleMath.fuzzyEquals(this.min(axis), 0.0, ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)) { +- ret = tryForceBlock(new SliceShape((VoxelShape)(Object)this, axis, 0)); ++ ret = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.sliceShape((VoxelShape)(Object)this, axis, 0); + } else { + ret = Shapes.empty(); + } +@@ -179,23 +179,6 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll + return ret; + } + +- private static VoxelShape tryForceBlock(final VoxelShape other) { +- if (other == Shapes.block()) { +- return other; +- } +- +- final AABB otherAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)other).moonrise$getSingleAABBRepresentation(); +- if (otherAABB == null) { +- return other; +- } +- +- if (((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)Shapes.block()).moonrise$getSingleAABBRepresentation().equals(otherAABB)) { +- return Shapes.block(); +- } +- +- return other; +- } +- + private boolean computeOccludesFullBlock() { + if (this.isEmpty) { + this.occludesFullBlock = Boolean.FALSE; +@@ -293,18 +276,21 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll + return result; + } + +- private static DoubleList offsetList(final DoubleList src, final double by) { +- if (src instanceof OffsetDoubleList offsetDoubleList) { +- return new OffsetDoubleList(offsetDoubleList.delegate, by + offsetDoubleList.offset); ++ private static DoubleList offsetList(final double[] src, final double by) { ++ final it.unimi.dsi.fastutil.doubles.DoubleArrayList wrap = it.unimi.dsi.fastutil.doubles.DoubleArrayList.wrap(src); ++ if (by == 0.0) { ++ return wrap; + } +- return new OffsetDoubleList(src, by); ++ return new OffsetDoubleList(wrap, by); + } + + private List toAabbsUncached() { +- final List ret = new java.util.ArrayList<>(); ++ final List ret; + if (this.singleAABBRepresentation != null) { ++ ret = new java.util.ArrayList<>(1); + ret.add(this.singleAABBRepresentation); + } else { ++ ret = new java.util.ArrayList<>(); + final double[] coordsX = this.rootCoordinatesX; + final double[] coordsY = this.rootCoordinatesY; + final double[] coordsZ = this.rootCoordinatesZ; +@@ -426,6 +412,26 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll + final double minDistance = minDistanceArr[0]; + return new BlockHitResult(from.add(minDistance * diffX, minDistance * diffY, minDistance * diffZ), direction, offset, false); + } ++ ++ private VoxelShape calculateFaceDirect(final Direction direction, final Direction.Axis axis, final double[] coords, final double offset) { ++ if (coords.length == 2 && ++ DoubleMath.fuzzyEquals(coords[0] + offset, 0.0, ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) && ++ DoubleMath.fuzzyEquals(coords[1] + offset, 1.0, ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)) { ++ return (VoxelShape)(Object)this; ++ } ++ ++ final boolean positiveDir = direction.getAxisDirection() == Direction.AxisDirection.POSITIVE; ++ ++ // see findIndex ++ final int index = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.findFloor( ++ coords, (positiveDir ? (1.0 - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) : (0.0 + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)) - offset, ++ 0, coords.length - 1 ++ ); ++ ++ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.sliceShape( ++ (VoxelShape)(Object)this, axis, index ++ ); ++ } + // Paper end - optimise collisions + + protected VoxelShape(DiscreteVoxelShape voxels) { +@@ -517,20 +523,32 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll + } + + public VoxelShape singleEncompassing() { +- return this.isEmpty() +- ? Shapes.empty() +- : Shapes.box( +- this.min(Direction.Axis.X), +- this.min(Direction.Axis.Y), +- this.min(Direction.Axis.Z), +- this.max(Direction.Axis.X), +- this.max(Direction.Axis.Y), +- this.max(Direction.Axis.Z) +- ); ++ // Paper start - optimise collisions ++ if (this.isEmpty) { ++ return Shapes.empty(); ++ } ++ return Shapes.create(this.bounds()); ++ // Paper end - optimise collisions + } + + protected double get(Direction.Axis axis, int index) { +- return this.getCoords(axis).getDouble(index); ++ // Paper start - optimise collisions ++ final int idx = index; ++ switch (axis) { ++ case X: { ++ return this.rootCoordinatesX[idx] + this.offsetX; ++ } ++ case Y: { ++ return this.rootCoordinatesY[idx] + this.offsetY; ++ } ++ case Z: { ++ return this.rootCoordinatesZ[idx] + this.offsetZ; ++ } ++ default: { ++ throw new IllegalStateException("Unknown axis: " + axis); ++ } ++ } ++ // Paper end - optimise collisions + } + + public abstract DoubleList getCoords(Direction.Axis axis); +@@ -547,9 +565,9 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll + + final ArrayVoxelShape ret = new ArrayVoxelShape( + this.shape, +- offsetList(this.getCoords(Direction.Axis.X), x), +- offsetList(this.getCoords(Direction.Axis.Y), y), +- offsetList(this.getCoords(Direction.Axis.Z), z) ++ offsetList(this.rootCoordinatesX, this.offsetX + x), ++ offsetList(this.rootCoordinatesY, this.offsetY + y), ++ offsetList(this.rootCoordinatesZ, this.offsetZ + z) + ); + + final ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs cachedToAABBs = this.cachedToAABBs; +@@ -574,6 +592,11 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll + + final List aabbs = this.toAabbs(); + ++ if (aabbs.isEmpty()) { ++ // We are a SliceShape, which does not properly fill isEmpty for every case ++ return Shapes.empty(); ++ } ++ + if (aabbs.size() == 1) { + final AABB singleAABB = aabbs.get(0); + final VoxelShape ret = Shapes.create(singleAABB); +@@ -700,7 +723,32 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll + } + + protected int findIndex(Direction.Axis axis, double coord) { +- return Mth.binarySearch(0, this.shape.getSize(axis) + 1, i -> coord < this.get(axis, i)) - 1; ++ // Paper start - optimise collisions ++ final double value = coord; ++ switch (axis) { ++ case X: { ++ final double[] values = this.rootCoordinatesX; ++ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.findFloor( ++ values, value - this.offsetX, 0, values.length - 1 ++ ); ++ } ++ case Y: { ++ final double[] values = this.rootCoordinatesY; ++ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.findFloor( ++ values, value - this.offsetY, 0, values.length - 1 ++ ); ++ } ++ case Z: { ++ final double[] values = this.rootCoordinatesZ; ++ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.findFloor( ++ values, value - this.offsetZ, 0, values.length - 1 ++ ); ++ } ++ default: { ++ throw new IllegalStateException("Unknown axis: " + axis); ++ } ++ } ++ // Paper end - optimise collisions + } + + @Nullable +@@ -723,13 +771,13 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll + final AABB singleAABB = this.singleAABBRepresentation; + if (singleAABB != null) { + if (singleAABB.contains(fromBehindOffsetX, fromBehindOffsetY, fromBehindOffsetZ)) { +- return new BlockHitResult(fromBehind, Direction.getNearest(directionOpposite.x, directionOpposite.y, directionOpposite.z).getOpposite(), offset, true); ++ return new BlockHitResult(fromBehind, Direction.getApproximateNearest(directionOpposite.x, directionOpposite.y, directionOpposite.z).getOpposite(), offset, true); + } + return clip(singleAABB, from, to, offset); + } + + if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.strictlyContains((VoxelShape)(Object)this, fromBehindOffsetX, fromBehindOffsetY, fromBehindOffsetZ)) { +- return new BlockHitResult(fromBehind, Direction.getNearest(directionOpposite.x, directionOpposite.y, directionOpposite.z).getOpposite(), offset, true); ++ return new BlockHitResult(fromBehind, Direction.getApproximateNearest(directionOpposite.x, directionOpposite.y, directionOpposite.z).getOpposite(), offset, true); + } + + return AABB.clip(((VoxelShape)(Object)this).toAabbs(), from, to, offset); +@@ -783,17 +831,23 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll + } + + private VoxelShape calculateFace(Direction direction) { +- Direction.Axis axis = direction.getAxis(); +- DoubleList doubleList = this.getCoords(axis); +- if (doubleList.size() == 2 +- && DoubleMath.fuzzyEquals(doubleList.getDouble(0), 0.0, 1.0E-7) +- && DoubleMath.fuzzyEquals(doubleList.getDouble(1), 1.0, 1.0E-7)) { +- return this; +- } else { +- Direction.AxisDirection axisDirection = direction.getAxisDirection(); +- int i = this.findIndex(axis, axisDirection == Direction.AxisDirection.POSITIVE ? 0.9999999 : 1.0E-7); +- return new SliceShape(this, axis, i); ++ // Paper start - optimise collisions ++ final Direction.Axis axis = direction.getAxis(); ++ switch (axis) { ++ case X: { ++ return this.calculateFaceDirect(direction, axis, this.rootCoordinatesX, this.offsetX); ++ } ++ case Y: { ++ return this.calculateFaceDirect(direction, axis, this.rootCoordinatesY, this.offsetY); ++ } ++ case Z: { ++ return this.calculateFaceDirect(direction, axis, this.rootCoordinatesZ, this.offsetZ); ++ } ++ default: { ++ throw new IllegalStateException("Unknown axis: " + axis); ++ } + } ++ // Paper end - optimise collisions + } + + // Paper start - optimise collisions From 47258a71184e0b3c919e2f224cf2aca985722ddf Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Wed, 23 Oct 2024 20:45:35 -0700 Subject: [PATCH 060/119] Move common diffs to MCUtils --- moonrise_update_1_21_2.txt | 1 - patches/server/1070-fixup-MC-Utils.patch | 952 ++++++++++++++++- ...-fixup-Moonrise-optimisation-patches.patch | 963 +----------------- 3 files changed, 952 insertions(+), 964 deletions(-) diff --git a/moonrise_update_1_21_2.txt b/moonrise_update_1_21_2.txt index 87e5b1546a64..f7067cc55624 100644 --- a/moonrise_update_1_21_2.txt +++ b/moonrise_update_1_21_2.txt @@ -13,7 +13,6 @@ add notes to moonrise patch: todo: - double check that the misc changes commit on dev/1.21.2 moonrise is applied - implement platformhooks -- move common diff from moonrise patch to mcutil patch - delete old block state table patch - in StateHolder, implement getNullableValue from blockstate_propertyaccess - ChunkEntitySlices getChunkEntities(), callEntitiesLoadEvent(), callEntitiesUnloadEvent() diff --git a/patches/server/1070-fixup-MC-Utils.patch b/patches/server/1070-fixup-MC-Utils.patch index 6bca72238a78..b68d600395c4 100644 --- a/patches/server/1070-fixup-MC-Utils.patch +++ b/patches/server/1070-fixup-MC-Utils.patch @@ -4,19 +4,700 @@ Date: Mon, 21 Oct 2024 12:21:54 -0700 Subject: [PATCH] fixup! MC Utils +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java +new file mode 100644 +index 0000000000000000000000000000000000000000..69a20e9d72b02f28b349f24fd0ea08736888e642 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java +@@ -0,0 +1,115 @@ ++package ca.spottedleaf.moonrise.common; ++ ++import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder; ++import com.mojang.datafixers.DataFixer; ++import net.minecraft.core.BlockPos; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.server.level.GenerationChunkHolder; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.util.datafix.DataFixTypes; ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.level.BlockGetter; ++import net.minecraft.world.level.ChunkPos; ++import net.minecraft.world.level.Level; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.chunk.ChunkAccess; ++import net.minecraft.world.level.chunk.LevelChunk; ++import net.minecraft.world.level.chunk.ProtoChunk; ++import net.minecraft.world.level.chunk.storage.SerializableChunkData; ++import net.minecraft.world.level.entity.EntityTypeTest; ++import net.minecraft.world.phys.AABB; ++import java.util.List; ++import java.util.ServiceLoader; ++import java.util.function.Predicate; ++ ++public interface PlatformHooks { ++ public static PlatformHooks get() { ++ return Holder.INSTANCE; ++ } ++ ++ public String getBrand(); ++ ++ public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos); ++ ++ public Predicate maybeHasLightEmission(); ++ ++ public boolean hasCurrentlyLoadingChunk(); ++ ++ public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder); ++ ++ public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk); ++ ++ public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original); ++ ++ public boolean allowAsyncTicketUpdates(); ++ ++ public void onChunkHolderTicketChange(final ServerLevel world, final NewChunkHolder holder, final int oldLevel, final int newLevel); ++ ++ public void chunkUnloadFromWorld(final LevelChunk chunk); ++ ++ public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data); ++ ++ public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player); ++ ++ public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player); ++ ++ public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate predicate, ++ final List into); ++ ++ public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, ++ final AABB boundingBox, final Predicate predicate, ++ final List into, final int maxCount); ++ ++ public void entityMove(final Entity entity, final long oldSection, final long newSection); ++ ++ public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event); ++ ++ public boolean configFixMC224294(); ++ ++ public boolean configAutoConfigSendDistance(); ++ ++ public double configPlayerMaxLoadRate(); ++ ++ public double configPlayerMaxGenRate(); ++ ++ public double configPlayerMaxSendRate(); ++ ++ public int configPlayerMaxConcurrentLoads(); ++ ++ public int configPlayerMaxConcurrentGens(); ++ ++ public long configAutoSaveInterval(); ++ ++ public int configMaxAutoSavePerTick(); ++ ++ public boolean configFixMC159283(); ++ ++ // support for CB chunk mustNotSave ++ public boolean forceNoSave(final ChunkAccess chunk); ++ ++ public CompoundTag convertNBT(final DataFixTypes type, final DataFixer dataFixer, final CompoundTag nbt, ++ final int fromVersion, final int toVersion); ++ ++ public boolean hasMainChunkLoadHook(); ++ ++ public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData); ++ ++ public List modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List entities); ++ ++ public void unloadEntity(final Entity entity); ++ ++ public int modifyEntityTrackingRange(final Entity entity, final int currentRange); ++ ++ public static final class Holder { ++ private Holder() { ++ } ++ ++ private static final PlatformHooks INSTANCE; ++ ++ static { ++ INSTANCE = ServiceLoader.load(PlatformHooks.class, PlatformHooks.class.getClassLoader()).findFirst() ++ .orElseThrow(() -> new RuntimeException("Failed to locate PlatformHooks")); ++ } ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java +index ba68998f6ef57b24c72fd833bd7de440de9501cc..7fed43a1e7bcf35c4d7fd3224837a47fedd59860 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java +@@ -13,15 +13,15 @@ import java.util.NoSuchElementException; + */ + public final class EntityList implements Iterable { + +- protected final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); ++ private final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); + { + this.entityToIndex.defaultReturnValue(Integer.MIN_VALUE); + } + +- protected static final Entity[] EMPTY_LIST = new Entity[0]; ++ private static final Entity[] EMPTY_LIST = new Entity[0]; + +- protected Entity[] entities = EMPTY_LIST; +- protected int count; ++ private Entity[] entities = EMPTY_LIST; ++ private int count; + + public int size() { + return this.count; +@@ -94,10 +94,9 @@ public final class EntityList implements Iterable { + + @Override + public Iterator iterator() { +- return new Iterator() { +- +- Entity lastRet; +- int current; ++ return new Iterator<>() { ++ private Entity lastRet; ++ private int current; + + @Override + public boolean hasNext() { +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java +deleted file mode 100644 +index fcfbca333234c09f7c056bbfcd9ac8860b20a8db..0000000000000000000000000000000000000000 +--- a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java ++++ /dev/null +@@ -1,125 +0,0 @@ +-package ca.spottedleaf.moonrise.common.list; +- +-import it.unimi.dsi.fastutil.longs.LongIterator; +-import it.unimi.dsi.fastutil.shorts.Short2LongOpenHashMap; +-import java.util.Arrays; +-import net.minecraft.world.level.block.Block; +-import net.minecraft.world.level.block.state.BlockState; +-import net.minecraft.world.level.chunk.GlobalPalette; +- +-public final class IBlockDataList { +- +- private static final GlobalPalette GLOBAL_PALETTE = new GlobalPalette<>(Block.BLOCK_STATE_REGISTRY); +- +- // map of location -> (index | (location << 16) | (palette id << 32)) +- private final Short2LongOpenHashMap map = new Short2LongOpenHashMap(2, 0.8f); +- { +- this.map.defaultReturnValue(Long.MAX_VALUE); +- } +- +- private static final long[] EMPTY_LIST = new long[0]; +- +- private long[] byIndex = EMPTY_LIST; +- private int size; +- +- public static int getLocationKey(final int x, final int y, final int z) { +- return (x & 15) | (((z & 15) << 4)) | ((y & 255) << (4 + 4)); +- } +- +- public static BlockState getBlockDataFromRaw(final long raw) { +- return GLOBAL_PALETTE.valueFor((int)(raw >>> 32)); +- } +- +- public static int getIndexFromRaw(final long raw) { +- return (int)(raw & 0xFFFF); +- } +- +- public static int getLocationFromRaw(final long raw) { +- return (int)((raw >>> 16) & 0xFFFF); +- } +- +- public static long getRawFromValues(final int index, final int location, final BlockState data) { +- return (long)index | ((long)location << 16) | (((long)GLOBAL_PALETTE.idFor(data)) << 32); +- } +- +- public static long setIndexRawValues(final long value, final int index) { +- return value & ~(0xFFFF) | (index); +- } +- +- public long add(final int x, final int y, final int z, final BlockState data) { +- return this.add(getLocationKey(x, y, z), data); +- } +- +- public long add(final int location, final BlockState data) { +- final long curr = this.map.get((short)location); +- +- if (curr == Long.MAX_VALUE) { +- final int index = this.size++; +- final long raw = getRawFromValues(index, location, data); +- this.map.put((short)location, raw); +- +- if (index >= this.byIndex.length) { +- this.byIndex = Arrays.copyOf(this.byIndex, (int)Math.max(4L, this.byIndex.length * 2L)); +- } +- +- this.byIndex[index] = raw; +- return raw; +- } else { +- final int index = getIndexFromRaw(curr); +- final long raw = this.byIndex[index] = getRawFromValues(index, location, data); +- +- this.map.put((short)location, raw); +- +- return raw; +- } +- } +- +- public long remove(final int x, final int y, final int z) { +- return this.remove(getLocationKey(x, y, z)); +- } +- +- public long remove(final int location) { +- final long ret = this.map.remove((short)location); +- final int index = getIndexFromRaw(ret); +- if (ret == Long.MAX_VALUE) { +- return ret; +- } +- +- // move the entry at the end to this index +- final int endIndex = --this.size; +- final long end = this.byIndex[endIndex]; +- if (index != endIndex) { +- // not empty after this call +- this.map.put((short)getLocationFromRaw(end), setIndexRawValues(end, index)); +- } +- this.byIndex[index] = end; +- this.byIndex[endIndex] = 0L; +- +- return ret; +- } +- +- public int size() { +- return this.size; +- } +- +- public long getRaw(final int index) { +- return this.byIndex[index]; +- } +- +- public int getLocation(final int index) { +- return getLocationFromRaw(this.getRaw(index)); +- } +- +- public BlockState getData(final int index) { +- return getBlockDataFromRaw(this.getRaw(index)); +- } +- +- public void clear() { +- this.size = 0; +- this.map.clear(); +- } +- +- public LongIterator getRawIterator() { +- return this.map.values().iterator(); +- } +-} +\ No newline at end of file +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9f3b25bb2439f283f878db93973a02fcdcd14eed +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java +@@ -0,0 +1,77 @@ ++package ca.spottedleaf.moonrise.common.list; ++ ++import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; ++import java.util.Arrays; ++ ++public final class IntList { ++ ++ private final Int2IntOpenHashMap map = new Int2IntOpenHashMap(); ++ { ++ this.map.defaultReturnValue(Integer.MIN_VALUE); ++ } ++ ++ private static final int[] EMPTY_LIST = new int[0]; ++ ++ private int[] byIndex = EMPTY_LIST; ++ private int count; ++ ++ public int size() { ++ return this.count; ++ } ++ ++ public void setMinCapacity(final int len) { ++ final int[] byIndex = this.byIndex; ++ if (byIndex.length < len) { ++ this.byIndex = Arrays.copyOf(byIndex, len); ++ } ++ } ++ ++ public int getRaw(final int index) { ++ return this.byIndex[index]; ++ } ++ ++ public boolean add(final int value) { ++ final int count = this.count; ++ final int currIndex = this.map.putIfAbsent(value, count); ++ ++ if (currIndex != Integer.MIN_VALUE) { ++ return false; // already in this list ++ } ++ ++ int[] list = this.byIndex; ++ ++ if (list.length == count) { ++ // resize required ++ list = this.byIndex = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative ++ } ++ ++ list[count] = value; ++ this.count = count + 1; ++ ++ return true; ++ } ++ ++ public boolean remove(final int value) { ++ final int index = this.map.remove(value); ++ if (index == Integer.MIN_VALUE) { ++ return false; ++ } ++ ++ // move the entry at the end to this index ++ final int endIndex = --this.count; ++ final int end = this.byIndex[endIndex]; ++ if (index != endIndex) { ++ // not empty after this call ++ this.map.put(end, index); ++ } ++ this.byIndex[index] = end; ++ this.byIndex[endIndex] = 0; ++ ++ return true; ++ } ++ ++ public void clear() { ++ this.count = 0; ++ this.map.clear(); ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2bae9949ef325d0001aa638150fbbdf968367e75 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java +@@ -0,0 +1,77 @@ ++package ca.spottedleaf.moonrise.common.list; ++ ++import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap; ++import java.util.Arrays; ++ ++public final class ShortList { ++ ++ private final Short2ShortOpenHashMap map = new Short2ShortOpenHashMap(); ++ { ++ this.map.defaultReturnValue(Short.MIN_VALUE); ++ } ++ ++ private static final short[] EMPTY_LIST = new short[0]; ++ ++ private short[] byIndex = EMPTY_LIST; ++ private short count; ++ ++ public int size() { ++ return (int)this.count; ++ } ++ ++ public short getRaw(final int index) { ++ return this.byIndex[index]; ++ } ++ ++ public void setMinCapacity(final int len) { ++ final short[] byIndex = this.byIndex; ++ if (byIndex.length < len) { ++ this.byIndex = Arrays.copyOf(byIndex, len); ++ } ++ } ++ ++ public boolean add(final short value) { ++ final int count = (int)this.count; ++ final short currIndex = this.map.putIfAbsent(value, (short)count); ++ ++ if (currIndex != Short.MIN_VALUE) { ++ return false; // already in this list ++ } ++ ++ short[] list = this.byIndex; ++ ++ if (list.length == count) { ++ // resize required ++ list = this.byIndex = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative ++ } ++ ++ list[count] = value; ++ this.count = (short)(count + 1); ++ ++ return true; ++ } ++ ++ public boolean remove(final short value) { ++ final short index = this.map.remove(value); ++ if (index == Short.MIN_VALUE) { ++ return false; ++ } ++ ++ // move the entry at the end to this index ++ final short endIndex = --this.count; ++ final short end = this.byIndex[endIndex]; ++ if (index != endIndex) { ++ // not empty after this call ++ this.map.put(end, index); ++ } ++ this.byIndex[(int)index] = end; ++ this.byIndex[(int)endIndex] = (short)0; ++ ++ return true; ++ } ++ ++ public void clear() { ++ this.count = (short)0; ++ this.map.clear(); ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c2d917c2eac55b8a4411a6e159f177f9428b1150 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java +@@ -0,0 +1,22 @@ ++package ca.spottedleaf.moonrise.common.misc; ++ ++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import java.lang.invoke.VarHandle; ++ ++public final class LazyRunnable implements Runnable { ++ ++ private volatile Runnable toRun; ++ private static final VarHandle TO_RUN_HANDLE = ConcurrentUtil.getVarHandle(LazyRunnable.class, "toRun", Runnable.class); ++ ++ public void setRunnable(final Runnable run) { ++ final Runnable prev = (Runnable)TO_RUN_HANDLE.compareAndExchange(this, (Runnable)null, run); ++ if (prev != null) { ++ throw new IllegalStateException("Runnable already set"); ++ } ++ } ++ ++ @Override ++ public void run() { ++ ((Runnable)TO_RUN_HANDLE.getVolatile(this)).run(); ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java +index ab093b0e8ac6f762921eb1d15f5217345c4eba05..bb44de17a37082e57f2292a4f470740be1d09b11 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java +@@ -4,13 +4,17 @@ import ca.spottedleaf.moonrise.common.list.ReferenceList; + import ca.spottedleaf.moonrise.common.util.CoordinateUtils; + import ca.spottedleaf.moonrise.common.util.MoonriseConstants; + import ca.spottedleaf.moonrise.common.util.ChunkSystem; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; + import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants; ++import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel; + import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; + import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; + import net.minecraft.core.BlockPos; + import net.minecraft.server.level.ServerLevel; + import net.minecraft.server.level.ServerPlayer; + import net.minecraft.world.level.ChunkPos; ++import java.util.ArrayList; + + public final class NearbyPlayers { + +@@ -20,7 +24,27 @@ public final class NearbyPlayers { + GENERAL_REALLY_SMALL, + TICK_VIEW_DISTANCE, + VIEW_DISTANCE, +- SPAWN_RANGE, // Moonrise - chunk tick iteration ++ // Moonrise start - chunk tick iteration ++ SPAWN_RANGE { ++ @Override ++ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ((ChunkTickServerLevel)world).moonrise$addPlayerTickingRequest(chunkX, chunkZ); ++ } ++ ++ @Override ++ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ((ChunkTickServerLevel)world).moonrise$removePlayerTickingRequest(chunkX, chunkZ); ++ } ++ }; ++ // Moonrise end - chunk tick iteration ++ ++ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ++ } ++ ++ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ++ } + } + + private static final NearbyMapType[] MAP_TYPES = NearbyMapType.values(); +@@ -37,6 +61,12 @@ public final class NearbyPlayers { + private final ServerLevel world; + private final Reference2ReferenceOpenHashMap players = new Reference2ReferenceOpenHashMap<>(); + private final Long2ReferenceOpenHashMap byChunk = new Long2ReferenceOpenHashMap<>(); ++ private final Long2ReferenceOpenHashMap>[] directByChunk = new Long2ReferenceOpenHashMap[TOTAL_MAP_TYPES]; ++ { ++ for (int i = 0; i < this.directByChunk.length; ++i) { ++ this.directByChunk[i] = new Long2ReferenceOpenHashMap<>(); ++ } ++ } + + public NearbyPlayers(final ServerLevel world) { + this.world = world; +@@ -70,6 +100,16 @@ public final class NearbyPlayers { + } + } + ++ public void clear() { ++ if (this.players.isEmpty()) { ++ return; ++ } ++ ++ for (final ServerPlayer player : new ArrayList<>(this.players.keySet())) { ++ this.removePlayer(player); ++ } ++ } ++ + public void tickPlayer(final ServerPlayer player) { + final TrackedPlayer[] players = this.players.get(player); + if (players == null) { +@@ -94,38 +134,41 @@ public final class NearbyPlayers { + return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); + } + +- public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { +- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); ++ public TrackedChunk getChunk(final int chunkX, final int chunkZ) { ++ return this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ } + +- return chunk == null ? null : chunk.players[type.ordinal()]; ++ public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); + } + + public ReferenceList getPlayers(final ChunkPos pos, final NearbyMapType type) { +- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); +- +- return chunk == null ? null : chunk.players[type.ordinal()]; ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); + } + + public ReferenceList getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) { +- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); +- +- return chunk == null ? null : chunk.players[type.ordinal()]; ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + } + + public ReferenceList getPlayersByBlock(final int blockX, final int blockZ, final NearbyMapType type) { +- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); +- +- return chunk == null ? null : chunk.players[type.ordinal()]; ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); + } + + public static final class TrackedChunk { + + private static final ServerPlayer[] EMPTY_PLAYERS_ARRAY = new ServerPlayer[0]; + ++ private final long chunkKey; ++ private final NearbyPlayers nearbyPlayers; + private final ReferenceList[] players = new ReferenceList[TOTAL_MAP_TYPES]; + private int nonEmptyLists; + private long updateCount; + ++ public TrackedChunk(final long chunkKey, final NearbyPlayers nearbyPlayers) { ++ this.chunkKey = chunkKey; ++ this.nearbyPlayers = nearbyPlayers; ++ } ++ + public boolean isEmpty() { + return this.nonEmptyLists == 0; + } +@@ -145,7 +188,9 @@ public final class NearbyPlayers { + final ReferenceList list = this.players[idx]; + if (list == null) { + ++this.nonEmptyLists; +- (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)).add(player); ++ final ReferenceList players = (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)); ++ this.nearbyPlayers.directByChunk[idx].put(this.chunkKey, players); ++ players.add(player); + return; + } + +@@ -169,6 +214,7 @@ public final class NearbyPlayers { + + if (list.size() == 0) { + this.players[idx] = null; ++ this.nearbyPlayers.directByChunk[idx].remove(this.chunkKey); + --this.nonEmptyLists; + } + } +@@ -187,9 +233,19 @@ public final class NearbyPlayers { + protected void addCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { + final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); + +- NearbyPlayers.this.byChunk.computeIfAbsent(chunkKey, (final long keyInMap) -> { +- return new TrackedChunk(); +- }).addPlayer(parameter, this.type); ++ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey); ++ final NearbyMapType type = this.type; ++ if (chunk != null) { ++ chunk.addPlayer(parameter, type); ++ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); ++ } else { ++ final TrackedChunk created = new TrackedChunk(chunkKey, NearbyPlayers.this); ++ NearbyPlayers.this.byChunk.put(chunkKey, created); ++ created.addPlayer(parameter, type); ++ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); ++ ++ ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$requestChunkData(chunkKey).nearbyPlayers = created; ++ } + } + + @Override +@@ -201,10 +257,16 @@ public final class NearbyPlayers { + throw new IllegalStateException("Chunk should exist at " + new ChunkPos(chunkKey)); + } + +- chunk.removePlayer(parameter, this.type); ++ final NearbyMapType type = this.type; ++ chunk.removePlayer(parameter, type); ++ type.removeFrom(parameter, NearbyPlayers.this.world, chunkX, chunkZ); + + if (chunk.isEmpty()) { + NearbyPlayers.this.byChunk.remove(chunkKey); ++ final ChunkData chunkData = ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$releaseChunkData(chunkKey); ++ if (chunkData != null) { ++ chunkData.nearbyPlayers = null; ++ } + } + } + } diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -index 0abba00741b39b69a7f167e5d2670f2565c9a752..96bbab283eb6c7e7863383fea0ddc62510391091 100644 +index 0abba00741b39b69a7f167e5d2670f2565c9a752..b61611351bf23efc1e90bab8a850ebbe6ffdd516 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -@@ -1,6 +1,6 @@ +@@ -1,6 +1,7 @@ package ca.spottedleaf.moonrise.common.util; -import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.PlatformHooks; import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk; import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader; -@@ -23,27 +23,27 @@ public final class ChunkSystem { +@@ -23,27 +24,27 @@ 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) { @@ -49,15 +730,278 @@ index 0abba00741b39b69a7f167e5d2670f2565c9a752..96bbab283eb6c7e7863383fea0ddc625 ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); } -@@ -67,7 +67,7 @@ public final class ChunkSystem { +@@ -67,7 +68,10 @@ public final class ChunkSystem { return getUpdatingChunkHolderCount(level) != 0; } - public static boolean screenEntity(final ServerLevel level, final Entity entity) { + public static boolean screenEntity(final ServerLevel level, final Entity entity, final boolean fromDisk, final boolean event) { ++ if (!PlatformHooks.get().screenEntity(level, entity, fromDisk, event)) { ++ return false; ++ } return true; } +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java +index ac6f284ee4469d16c5655328b2488d7612832353..97848869df61648fc415e4d39f409f433202c274 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java +@@ -3,8 +3,12 @@ package ca.spottedleaf.moonrise.common.util; + public final class MixinWorkarounds { + + // mixins tries to find the owner of the clone() method, which doesn't exist and NPEs ++ // https://github.com/FabricMC/Mixin/pull/147 + public static long[] clone(final long[] values) { + return values.clone(); + } + ++ public static byte[] clone(final byte[] values) { ++ return values.clone(); ++ } + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java +index 3abe0bd2a820352b85306d554bf14a4cf6123091..c125c70a68130be373acc989053a6c0e487be924 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java +@@ -1,45 +1,100 @@ + package ca.spottedleaf.moonrise.common.util; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool; ++import ca.spottedleaf.concurrentutil.executor.thread.PrioritisedThreadPool; ++import ca.spottedleaf.moonrise.common.PlatformHooks; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; +-import java.io.File; ++import java.util.concurrent.TimeUnit; ++import java.util.concurrent.atomic.AtomicInteger; ++import java.util.function.Consumer; + + public final class MoonriseCommon { + + private static final Logger LOGGER = LoggerFactory.getLogger(MoonriseCommon.class); + +- // Paper start +- public static PrioritisedThreadPool WORKER_POOL; +- public static int WORKER_THREADS; +- public static void init(io.papermc.paper.configuration.GlobalConfiguration.ChunkSystem chunkSystem) { +- // Paper end ++ public static final PrioritisedThreadPool WORKER_POOL = new PrioritisedThreadPool( ++ new Consumer<>() { ++ private final AtomicInteger idGenerator = new AtomicInteger(); ++ ++ @Override ++ public void accept(Thread thread) { ++ thread.setDaemon(true); ++ thread.setName(PlatformHooks.get().getBrand() + " Common Worker #" + this.idGenerator.getAndIncrement()); ++ thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { ++ @Override ++ public void uncaughtException(final Thread thread, final Throwable throwable) { ++ LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); ++ } ++ }); ++ } ++ } ++ ); ++ public static final long WORKER_QUEUE_HOLD_TIME = (long)(20.0e6); // 20ms ++ public static final int CLIENT_DIVISION = 0; ++ public static final PrioritisedThreadPool.ExecutorGroup RENDER_EXECUTOR_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(CLIENT_DIVISION, 0); ++ public static final int SERVER_DIVISION = 1; ++ public static final PrioritisedThreadPool.ExecutorGroup PARALLEL_GEN_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); ++ public static final PrioritisedThreadPool.ExecutorGroup RADIUS_AWARE_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); ++ public static final PrioritisedThreadPool.ExecutorGroup LOAD_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); ++ ++ public static void adjustWorkerThreads(final int configWorkerThreads, final int configIoThreads) { + int defaultWorkerThreads = Runtime.getRuntime().availableProcessors() / 2; + if (defaultWorkerThreads <= 4) { + defaultWorkerThreads = defaultWorkerThreads <= 3 ? 1 : 2; + } else { + defaultWorkerThreads = defaultWorkerThreads / 2; + } +- defaultWorkerThreads = Integer.getInteger("Paper.WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); // Paper ++ defaultWorkerThreads = Integer.getInteger(PlatformHooks.get().getBrand() + ".WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); + +- int workerThreads = chunkSystem.workerThreads; // Paper ++ int workerThreads = configWorkerThreads; + + if (workerThreads <= 0) { + workerThreads = defaultWorkerThreads; + } + +- WORKER_POOL = new PrioritisedThreadPool( +- "Paper Worker Pool", workerThreads, // Paper +- (final Thread thread, final Integer id) -> { +- thread.setName("Paper Common Worker #" + id.intValue()); // Paper ++ final int ioThreads = Math.max(1, configIoThreads); ++ ++ WORKER_POOL.adjustThreadCount(workerThreads); ++ IO_POOL.adjustThreadCount(ioThreads); ++ ++ LOGGER.info(PlatformHooks.get().getBrand() + " is using " + workerThreads + " worker threads, " + ioThreads + " I/O threads"); ++ } ++ ++ public static final PrioritisedThreadPool IO_POOL = new PrioritisedThreadPool( ++ new Consumer<>() { ++ private final AtomicInteger idGenerator = new AtomicInteger(); ++ ++ @Override ++ public void accept(final Thread thread) { ++ thread.setDaemon(true); ++ thread.setName(PlatformHooks.get().getBrand() + " I/O Worker #" + this.idGenerator.getAndIncrement()); + thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(final Thread thread, final Throwable throwable) { + LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); + } + }); +- }, (long)(20.0e6)); // 20ms +- WORKER_THREADS = workerThreads; ++ } ++ } ++ ); ++ public static final long IO_QUEUE_HOLD_TIME = (long)(100.0e6); // 100ms ++ public static final PrioritisedThreadPool.ExecutorGroup CLIENT_PROFILER_IO_GROUP = IO_POOL.createExecutorGroup(CLIENT_DIVISION, 0); ++ public static final PrioritisedThreadPool.ExecutorGroup SERVER_REGION_IO_GROUP = IO_POOL.createExecutorGroup(SERVER_DIVISION, 0); ++ ++ public static void haltExecutors() { ++ MoonriseCommon.WORKER_POOL.shutdown(false); ++ LOGGER.info("Awaiting termination of worker pool for up to 60s..."); ++ if (!MoonriseCommon.WORKER_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { ++ LOGGER.error("Worker pool did not shut down in time!"); ++ MoonriseCommon.WORKER_POOL.halt(false); ++ } ++ ++ MoonriseCommon.IO_POOL.shutdown(false); ++ LOGGER.info("Awaiting termination of I/O pool for up to 60s..."); ++ if (!MoonriseCommon.IO_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { ++ LOGGER.error("I/O pool did not shut down in time!"); ++ MoonriseCommon.IO_POOL.halt(false); ++ } + } + + private MoonriseCommon() {} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java +index 1cf32d7d1bbc8a0a3f7cb9024c793f6744199f64..559c959aff3c9deef867b9e425fba3e2e669cac6 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java +@@ -1,8 +1,10 @@ + package ca.spottedleaf.moonrise.common.util; + ++import ca.spottedleaf.moonrise.common.PlatformHooks; ++ + public final class MoonriseConstants { + +- public static final int MAX_VIEW_DISTANCE = 32; ++ public static final int MAX_VIEW_DISTANCE = Integer.getInteger(PlatformHooks.get().getBrand() + ".MaxViewDistance", 32); + + private MoonriseConstants() {} + +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java b/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a9ff1c1a70faf4b7a64b265932f07a8b8f00c1ff +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java +@@ -0,0 +1,52 @@ ++package ca.spottedleaf.moonrise.common.util; ++ ++import net.minecraft.world.level.levelgen.LegacyRandomSource; ++ ++/** ++ * Avoid costly CAS of superclass ++ */ ++public final class SimpleRandom extends LegacyRandomSource { ++ ++ private static final long MULTIPLIER = 25214903917L; ++ private static final long ADDEND = 11L; ++ private static final int BITS = 48; ++ private static final long MASK = (1L << BITS) - 1; ++ ++ private long value; ++ ++ public SimpleRandom(final long seed) { ++ super(0L); ++ this.value = seed; ++ } ++ ++ @Override ++ public void setSeed(final long seed) { ++ this.value = (seed ^ MULTIPLIER) & MASK; ++ } ++ ++ private long advanceSeed() { ++ return this.value = ((this.value * MULTIPLIER) + ADDEND) & MASK; ++ } ++ ++ @Override ++ public int next(final int bits) { ++ return (int)(this.advanceSeed() >>> (BITS - bits)); ++ } ++ ++ @Override ++ public int nextInt() { ++ final long seed = this.advanceSeed(); ++ return (int)(seed >>> (BITS - Integer.SIZE)); ++ } ++ ++ @Override ++ public int nextInt(final int bound) { ++ if (bound <= 0) { ++ throw new IllegalArgumentException(); ++ } ++ ++ // https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ ++ final long value = this.advanceSeed() >>> (BITS - Integer.SIZE); ++ return (int)((value * (long)bound) >>> Integer.SIZE); ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java +index 11b7f15755dde766140c29bedca456c80d53293f..217d1f908a36a5177ba3cbb80a33f73d4dab0fa0 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java +@@ -77,11 +77,15 @@ public class TickThread extends Thread { + } + + public TickThread(final Runnable run, final String name) { +- this(run, name, ID_GENERATOR.incrementAndGet()); ++ this(null, run, name); + } + +- private TickThread(final Runnable run, final String name, final int id) { +- super(run, name); ++ public TickThread(final ThreadGroup group, final Runnable run, final String name) { ++ this(group, run, name, ID_GENERATOR.incrementAndGet()); ++ } ++ ++ private TickThread(final ThreadGroup group, final Runnable run, final String name, final int id) { ++ super(group, run, name); + this.id = id; + } + +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java +index af9623240ff2d389aa7090623f507720e7dbab7d..efda2688ae1254a82ba7f6bf8bf597ef224cbb86 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java +@@ -8,11 +8,19 @@ public final class WorldUtil { + // min, max are inclusive + + public static int getMaxSection(final LevelHeightAccessor world) { +- return world.getMaxSection() - 1; // getMaxSection() is exclusive ++ return world.getMaxSectionY(); ++ } ++ ++ public static int getMaxSection(final Level world) { ++ return world.getMaxSectionY(); + } + + public static int getMinSection(final LevelHeightAccessor world) { +- return world.getMinSection(); ++ return world.getMinSectionY(); ++ } ++ ++ public static int getMinSection(final Level world) { ++ return world.getMinSectionY(); + } + + public static int getMaxLightSection(final LevelHeightAccessor world) { 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 6baa313b8201ed23193d7885c85606b0899ade3c..3eb38271b6ca26099b2da04c2d969e32fd72b2af 100644 --- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java diff --git a/patches/server/1073-fixup-Moonrise-optimisation-patches.patch b/patches/server/1073-fixup-Moonrise-optimisation-patches.patch index 42a3be51224c..031f4c876b01 100644 --- a/patches/server/1073-fixup-Moonrise-optimisation-patches.patch +++ b/patches/server/1073-fixup-Moonrise-optimisation-patches.patch @@ -4,696 +4,11 @@ Date: Mon, 21 Oct 2024 11:06:24 -0700 Subject: [PATCH] fixup! Moonrise optimisation patches -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java -new file mode 100644 -index 0000000000000000000000000000000000000000..69a20e9d72b02f28b349f24fd0ea08736888e642 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java -@@ -0,0 +1,115 @@ -+package ca.spottedleaf.moonrise.common; -+ -+import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder; -+import com.mojang.datafixers.DataFixer; -+import net.minecraft.core.BlockPos; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.server.level.GenerationChunkHolder; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.util.datafix.DataFixTypes; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.level.BlockGetter; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.ProtoChunk; -+import net.minecraft.world.level.chunk.storage.SerializableChunkData; -+import net.minecraft.world.level.entity.EntityTypeTest; -+import net.minecraft.world.phys.AABB; -+import java.util.List; -+import java.util.ServiceLoader; -+import java.util.function.Predicate; -+ -+public interface PlatformHooks { -+ public static PlatformHooks get() { -+ return Holder.INSTANCE; -+ } -+ -+ public String getBrand(); -+ -+ public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos); -+ -+ public Predicate maybeHasLightEmission(); -+ -+ public boolean hasCurrentlyLoadingChunk(); -+ -+ public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder); -+ -+ public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk); -+ -+ public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original); -+ -+ public boolean allowAsyncTicketUpdates(); -+ -+ public void onChunkHolderTicketChange(final ServerLevel world, final NewChunkHolder holder, final int oldLevel, final int newLevel); -+ -+ public void chunkUnloadFromWorld(final LevelChunk chunk); -+ -+ public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data); -+ -+ public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player); -+ -+ public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player); -+ -+ public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate predicate, -+ final List into); -+ -+ public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, -+ final AABB boundingBox, final Predicate predicate, -+ final List into, final int maxCount); -+ -+ public void entityMove(final Entity entity, final long oldSection, final long newSection); -+ -+ public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event); -+ -+ public boolean configFixMC224294(); -+ -+ public boolean configAutoConfigSendDistance(); -+ -+ public double configPlayerMaxLoadRate(); -+ -+ public double configPlayerMaxGenRate(); -+ -+ public double configPlayerMaxSendRate(); -+ -+ public int configPlayerMaxConcurrentLoads(); -+ -+ public int configPlayerMaxConcurrentGens(); -+ -+ public long configAutoSaveInterval(); -+ -+ public int configMaxAutoSavePerTick(); -+ -+ public boolean configFixMC159283(); -+ -+ // support for CB chunk mustNotSave -+ public boolean forceNoSave(final ChunkAccess chunk); -+ -+ public CompoundTag convertNBT(final DataFixTypes type, final DataFixer dataFixer, final CompoundTag nbt, -+ final int fromVersion, final int toVersion); -+ -+ public boolean hasMainChunkLoadHook(); -+ -+ public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData); -+ -+ public List modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List entities); -+ -+ public void unloadEntity(final Entity entity); -+ -+ public int modifyEntityTrackingRange(final Entity entity, final int currentRange); -+ -+ public static final class Holder { -+ private Holder() { -+ } -+ -+ private static final PlatformHooks INSTANCE; -+ -+ static { -+ INSTANCE = ServiceLoader.load(PlatformHooks.class, PlatformHooks.class.getClassLoader()).findFirst() -+ .orElseThrow(() -> new RuntimeException("Failed to locate PlatformHooks")); -+ } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java -index ba68998f6ef57b24c72fd833bd7de440de9501cc..7fed43a1e7bcf35c4d7fd3224837a47fedd59860 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java -@@ -13,15 +13,15 @@ import java.util.NoSuchElementException; - */ - public final class EntityList implements Iterable { - -- protected final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); -+ private final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); - { - this.entityToIndex.defaultReturnValue(Integer.MIN_VALUE); - } - -- protected static final Entity[] EMPTY_LIST = new Entity[0]; -+ private static final Entity[] EMPTY_LIST = new Entity[0]; - -- protected Entity[] entities = EMPTY_LIST; -- protected int count; -+ private Entity[] entities = EMPTY_LIST; -+ private int count; - - public int size() { - return this.count; -@@ -94,10 +94,9 @@ public final class EntityList implements Iterable { - - @Override - public Iterator iterator() { -- return new Iterator() { -- -- Entity lastRet; -- int current; -+ return new Iterator<>() { -+ private Entity lastRet; -+ private int current; - - @Override - public boolean hasNext() { -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java -deleted file mode 100644 -index fcfbca333234c09f7c056bbfcd9ac8860b20a8db..0000000000000000000000000000000000000000 ---- a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java -+++ /dev/null -@@ -1,125 +0,0 @@ --package ca.spottedleaf.moonrise.common.list; -- --import it.unimi.dsi.fastutil.longs.LongIterator; --import it.unimi.dsi.fastutil.shorts.Short2LongOpenHashMap; --import java.util.Arrays; --import net.minecraft.world.level.block.Block; --import net.minecraft.world.level.block.state.BlockState; --import net.minecraft.world.level.chunk.GlobalPalette; -- --public final class IBlockDataList { -- -- private static final GlobalPalette GLOBAL_PALETTE = new GlobalPalette<>(Block.BLOCK_STATE_REGISTRY); -- -- // map of location -> (index | (location << 16) | (palette id << 32)) -- private final Short2LongOpenHashMap map = new Short2LongOpenHashMap(2, 0.8f); -- { -- this.map.defaultReturnValue(Long.MAX_VALUE); -- } -- -- private static final long[] EMPTY_LIST = new long[0]; -- -- private long[] byIndex = EMPTY_LIST; -- private int size; -- -- public static int getLocationKey(final int x, final int y, final int z) { -- return (x & 15) | (((z & 15) << 4)) | ((y & 255) << (4 + 4)); -- } -- -- public static BlockState getBlockDataFromRaw(final long raw) { -- return GLOBAL_PALETTE.valueFor((int)(raw >>> 32)); -- } -- -- public static int getIndexFromRaw(final long raw) { -- return (int)(raw & 0xFFFF); -- } -- -- public static int getLocationFromRaw(final long raw) { -- return (int)((raw >>> 16) & 0xFFFF); -- } -- -- public static long getRawFromValues(final int index, final int location, final BlockState data) { -- return (long)index | ((long)location << 16) | (((long)GLOBAL_PALETTE.idFor(data)) << 32); -- } -- -- public static long setIndexRawValues(final long value, final int index) { -- return value & ~(0xFFFF) | (index); -- } -- -- public long add(final int x, final int y, final int z, final BlockState data) { -- return this.add(getLocationKey(x, y, z), data); -- } -- -- public long add(final int location, final BlockState data) { -- final long curr = this.map.get((short)location); -- -- if (curr == Long.MAX_VALUE) { -- final int index = this.size++; -- final long raw = getRawFromValues(index, location, data); -- this.map.put((short)location, raw); -- -- if (index >= this.byIndex.length) { -- this.byIndex = Arrays.copyOf(this.byIndex, (int)Math.max(4L, this.byIndex.length * 2L)); -- } -- -- this.byIndex[index] = raw; -- return raw; -- } else { -- final int index = getIndexFromRaw(curr); -- final long raw = this.byIndex[index] = getRawFromValues(index, location, data); -- -- this.map.put((short)location, raw); -- -- return raw; -- } -- } -- -- public long remove(final int x, final int y, final int z) { -- return this.remove(getLocationKey(x, y, z)); -- } -- -- public long remove(final int location) { -- final long ret = this.map.remove((short)location); -- final int index = getIndexFromRaw(ret); -- if (ret == Long.MAX_VALUE) { -- return ret; -- } -- -- // move the entry at the end to this index -- final int endIndex = --this.size; -- final long end = this.byIndex[endIndex]; -- if (index != endIndex) { -- // not empty after this call -- this.map.put((short)getLocationFromRaw(end), setIndexRawValues(end, index)); -- } -- this.byIndex[index] = end; -- this.byIndex[endIndex] = 0L; -- -- return ret; -- } -- -- public int size() { -- return this.size; -- } -- -- public long getRaw(final int index) { -- return this.byIndex[index]; -- } -- -- public int getLocation(final int index) { -- return getLocationFromRaw(this.getRaw(index)); -- } -- -- public BlockState getData(final int index) { -- return getBlockDataFromRaw(this.getRaw(index)); -- } -- -- public void clear() { -- this.size = 0; -- this.map.clear(); -- } -- -- public LongIterator getRawIterator() { -- return this.map.values().iterator(); -- } --} -\ No newline at end of file -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java -new file mode 100644 -index 0000000000000000000000000000000000000000..9f3b25bb2439f283f878db93973a02fcdcd14eed ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java -@@ -0,0 +1,77 @@ -+package ca.spottedleaf.moonrise.common.list; -+ -+import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; -+import java.util.Arrays; -+ -+public final class IntList { -+ -+ private final Int2IntOpenHashMap map = new Int2IntOpenHashMap(); -+ { -+ this.map.defaultReturnValue(Integer.MIN_VALUE); -+ } -+ -+ private static final int[] EMPTY_LIST = new int[0]; -+ -+ private int[] byIndex = EMPTY_LIST; -+ private int count; -+ -+ public int size() { -+ return this.count; -+ } -+ -+ public void setMinCapacity(final int len) { -+ final int[] byIndex = this.byIndex; -+ if (byIndex.length < len) { -+ this.byIndex = Arrays.copyOf(byIndex, len); -+ } -+ } -+ -+ public int getRaw(final int index) { -+ return this.byIndex[index]; -+ } -+ -+ public boolean add(final int value) { -+ final int count = this.count; -+ final int currIndex = this.map.putIfAbsent(value, count); -+ -+ if (currIndex != Integer.MIN_VALUE) { -+ return false; // already in this list -+ } -+ -+ int[] list = this.byIndex; -+ -+ if (list.length == count) { -+ // resize required -+ list = this.byIndex = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative -+ } -+ -+ list[count] = value; -+ this.count = count + 1; -+ -+ return true; -+ } -+ -+ public boolean remove(final int value) { -+ final int index = this.map.remove(value); -+ if (index == Integer.MIN_VALUE) { -+ return false; -+ } -+ -+ // move the entry at the end to this index -+ final int endIndex = --this.count; -+ final int end = this.byIndex[endIndex]; -+ if (index != endIndex) { -+ // not empty after this call -+ this.map.put(end, index); -+ } -+ this.byIndex[index] = end; -+ this.byIndex[endIndex] = 0; -+ -+ return true; -+ } -+ -+ public void clear() { -+ this.count = 0; -+ this.map.clear(); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java -new file mode 100644 -index 0000000000000000000000000000000000000000..2bae9949ef325d0001aa638150fbbdf968367e75 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java -@@ -0,0 +1,77 @@ -+package ca.spottedleaf.moonrise.common.list; -+ -+import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap; -+import java.util.Arrays; -+ -+public final class ShortList { -+ -+ private final Short2ShortOpenHashMap map = new Short2ShortOpenHashMap(); -+ { -+ this.map.defaultReturnValue(Short.MIN_VALUE); -+ } -+ -+ private static final short[] EMPTY_LIST = new short[0]; -+ -+ private short[] byIndex = EMPTY_LIST; -+ private short count; -+ -+ public int size() { -+ return (int)this.count; -+ } -+ -+ public short getRaw(final int index) { -+ return this.byIndex[index]; -+ } -+ -+ public void setMinCapacity(final int len) { -+ final short[] byIndex = this.byIndex; -+ if (byIndex.length < len) { -+ this.byIndex = Arrays.copyOf(byIndex, len); -+ } -+ } -+ -+ public boolean add(final short value) { -+ final int count = (int)this.count; -+ final short currIndex = this.map.putIfAbsent(value, (short)count); -+ -+ if (currIndex != Short.MIN_VALUE) { -+ return false; // already in this list -+ } -+ -+ short[] list = this.byIndex; -+ -+ if (list.length == count) { -+ // resize required -+ list = this.byIndex = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative -+ } -+ -+ list[count] = value; -+ this.count = (short)(count + 1); -+ -+ return true; -+ } -+ -+ public boolean remove(final short value) { -+ final short index = this.map.remove(value); -+ if (index == Short.MIN_VALUE) { -+ return false; -+ } -+ -+ // move the entry at the end to this index -+ final short endIndex = --this.count; -+ final short end = this.byIndex[endIndex]; -+ if (index != endIndex) { -+ // not empty after this call -+ this.map.put(end, index); -+ } -+ this.byIndex[(int)index] = end; -+ this.byIndex[(int)endIndex] = (short)0; -+ -+ return true; -+ } -+ -+ public void clear() { -+ this.count = (short)0; -+ this.map.clear(); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c2d917c2eac55b8a4411a6e159f177f9428b1150 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java -@@ -0,0 +1,22 @@ -+package ca.spottedleaf.moonrise.common.misc; -+ -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import java.lang.invoke.VarHandle; -+ -+public final class LazyRunnable implements Runnable { -+ -+ private volatile Runnable toRun; -+ private static final VarHandle TO_RUN_HANDLE = ConcurrentUtil.getVarHandle(LazyRunnable.class, "toRun", Runnable.class); -+ -+ public void setRunnable(final Runnable run) { -+ final Runnable prev = (Runnable)TO_RUN_HANDLE.compareAndExchange(this, (Runnable)null, run); -+ if (prev != null) { -+ throw new IllegalStateException("Runnable already set"); -+ } -+ } -+ -+ @Override -+ public void run() { -+ ((Runnable)TO_RUN_HANDLE.getVolatile(this)).run(); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java -index ab093b0e8ac6f762921eb1d15f5217345c4eba05..bb44de17a37082e57f2292a4f470740be1d09b11 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java -@@ -4,13 +4,17 @@ import ca.spottedleaf.moonrise.common.list.ReferenceList; - import ca.spottedleaf.moonrise.common.util.CoordinateUtils; - import ca.spottedleaf.moonrise.common.util.MoonriseConstants; - import ca.spottedleaf.moonrise.common.util.ChunkSystem; -+import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel; -+import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; - import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants; -+import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel; - import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; - import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; - import net.minecraft.core.BlockPos; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.server.level.ServerPlayer; - import net.minecraft.world.level.ChunkPos; -+import java.util.ArrayList; - - public final class NearbyPlayers { - -@@ -20,7 +24,27 @@ public final class NearbyPlayers { - GENERAL_REALLY_SMALL, - TICK_VIEW_DISTANCE, - VIEW_DISTANCE, -- SPAWN_RANGE, // Moonrise - chunk tick iteration -+ // Moonrise start - chunk tick iteration -+ SPAWN_RANGE { -+ @Override -+ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { -+ ((ChunkTickServerLevel)world).moonrise$addPlayerTickingRequest(chunkX, chunkZ); -+ } -+ -+ @Override -+ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { -+ ((ChunkTickServerLevel)world).moonrise$removePlayerTickingRequest(chunkX, chunkZ); -+ } -+ }; -+ // Moonrise end - chunk tick iteration -+ -+ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { -+ -+ } -+ -+ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { -+ -+ } - } - - private static final NearbyMapType[] MAP_TYPES = NearbyMapType.values(); -@@ -37,6 +61,12 @@ public final class NearbyPlayers { - private final ServerLevel world; - private final Reference2ReferenceOpenHashMap players = new Reference2ReferenceOpenHashMap<>(); - private final Long2ReferenceOpenHashMap byChunk = new Long2ReferenceOpenHashMap<>(); -+ private final Long2ReferenceOpenHashMap>[] directByChunk = new Long2ReferenceOpenHashMap[TOTAL_MAP_TYPES]; -+ { -+ for (int i = 0; i < this.directByChunk.length; ++i) { -+ this.directByChunk[i] = new Long2ReferenceOpenHashMap<>(); -+ } -+ } - - public NearbyPlayers(final ServerLevel world) { - this.world = world; -@@ -70,6 +100,16 @@ public final class NearbyPlayers { - } - } - -+ public void clear() { -+ if (this.players.isEmpty()) { -+ return; -+ } -+ -+ for (final ServerPlayer player : new ArrayList<>(this.players.keySet())) { -+ this.removePlayer(player); -+ } -+ } -+ - public void tickPlayer(final ServerPlayer player) { - final TrackedPlayer[] players = this.players.get(player); - if (players == null) { -@@ -94,38 +134,41 @@ public final class NearbyPlayers { - return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); - } - -- public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { -- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -+ public TrackedChunk getChunk(final int chunkX, final int chunkZ) { -+ return this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ } - -- return chunk == null ? null : chunk.players[type.ordinal()]; -+ public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { -+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); - } - - public ReferenceList getPlayers(final ChunkPos pos, final NearbyMapType type) { -- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -- -- return chunk == null ? null : chunk.players[type.ordinal()]; -+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); - } - - public ReferenceList getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) { -- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -- -- return chunk == null ? null : chunk.players[type.ordinal()]; -+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); - } - - public ReferenceList getPlayersByBlock(final int blockX, final int blockZ, final NearbyMapType type) { -- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); -- -- return chunk == null ? null : chunk.players[type.ordinal()]; -+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); - } - - public static final class TrackedChunk { - - private static final ServerPlayer[] EMPTY_PLAYERS_ARRAY = new ServerPlayer[0]; - -+ private final long chunkKey; -+ private final NearbyPlayers nearbyPlayers; - private final ReferenceList[] players = new ReferenceList[TOTAL_MAP_TYPES]; - private int nonEmptyLists; - private long updateCount; - -+ public TrackedChunk(final long chunkKey, final NearbyPlayers nearbyPlayers) { -+ this.chunkKey = chunkKey; -+ this.nearbyPlayers = nearbyPlayers; -+ } -+ - public boolean isEmpty() { - return this.nonEmptyLists == 0; - } -@@ -145,7 +188,9 @@ public final class NearbyPlayers { - final ReferenceList list = this.players[idx]; - if (list == null) { - ++this.nonEmptyLists; -- (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)).add(player); -+ final ReferenceList players = (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)); -+ this.nearbyPlayers.directByChunk[idx].put(this.chunkKey, players); -+ players.add(player); - return; - } - -@@ -169,6 +214,7 @@ public final class NearbyPlayers { - - if (list.size() == 0) { - this.players[idx] = null; -+ this.nearbyPlayers.directByChunk[idx].remove(this.chunkKey); - --this.nonEmptyLists; - } - } -@@ -187,9 +233,19 @@ public final class NearbyPlayers { - protected void addCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { - final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); - -- NearbyPlayers.this.byChunk.computeIfAbsent(chunkKey, (final long keyInMap) -> { -- return new TrackedChunk(); -- }).addPlayer(parameter, this.type); -+ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey); -+ final NearbyMapType type = this.type; -+ if (chunk != null) { -+ chunk.addPlayer(parameter, type); -+ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); -+ } else { -+ final TrackedChunk created = new TrackedChunk(chunkKey, NearbyPlayers.this); -+ NearbyPlayers.this.byChunk.put(chunkKey, created); -+ created.addPlayer(parameter, type); -+ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); -+ -+ ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$requestChunkData(chunkKey).nearbyPlayers = created; -+ } - } - - @Override -@@ -201,10 +257,16 @@ public final class NearbyPlayers { - throw new IllegalStateException("Chunk should exist at " + new ChunkPos(chunkKey)); - } - -- chunk.removePlayer(parameter, this.type); -+ final NearbyMapType type = this.type; -+ chunk.removePlayer(parameter, type); -+ type.removeFrom(parameter, NearbyPlayers.this.world, chunkX, chunkZ); - - if (chunk.isEmpty()) { - NearbyPlayers.this.byChunk.remove(chunkKey); -+ final ChunkData chunkData = ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$releaseChunkData(chunkKey); -+ if (chunkData != null) { -+ chunkData.nearbyPlayers = null; -+ } - } - } - } diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -index 96bbab283eb6c7e7863383fea0ddc62510391091..fc029c8fb22a7c8eeb23bfc171812f6da91c60fa 100644 +index b61611351bf23efc1e90bab8a850ebbe6ffdd516..fc029c8fb22a7c8eeb23bfc171812f6da91c60fa 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -@@ -1,15 +1,18 @@ - package ca.spottedleaf.moonrise.common.util; - - import ca.spottedleaf.concurrentutil.util.Priority; -+import ca.spottedleaf.moonrise.common.PlatformHooks; - import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; +@@ -6,11 +6,13 @@ import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk; import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader; import ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemServerChunkCache; @@ -707,17 +22,7 @@ index 96bbab283eb6c7e7863383fea0ddc62510391091..fc029c8fb22a7c8eeb23bfc171812f6d import net.minecraft.world.entity.Entity; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.LevelChunk; -@@ -68,6 +71,9 @@ public final class ChunkSystem { - } - - public static boolean screenEntity(final ServerLevel level, final Entity entity, final boolean fromDisk, final boolean event) { -+ if (!PlatformHooks.get().screenEntity(level, entity, fromDisk, event)) { -+ return false; -+ } - return true; - } - -@@ -76,7 +82,13 @@ public final class ChunkSystem { +@@ -80,7 +82,13 @@ public final class ChunkSystem { } public static void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder) { @@ -732,7 +37,7 @@ index 96bbab283eb6c7e7863383fea0ddc62510391091..fc029c8fb22a7c8eeb23bfc171812f6d } public static void onChunkPreBorder(final LevelChunk chunk, final ChunkHolder holder) { -@@ -108,16 +120,18 @@ public final class ChunkSystem { +@@ -112,16 +120,18 @@ public final class ChunkSystem { ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder() ); if (!((ChunkSystemLevelChunk)chunk).moonrise$isPostProcessingDone()) { @@ -752,266 +57,6 @@ index 96bbab283eb6c7e7863383fea0ddc62510391091..fc029c8fb22a7c8eeb23bfc171812f6d } public static void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java -index ac6f284ee4469d16c5655328b2488d7612832353..97848869df61648fc415e4d39f409f433202c274 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java -@@ -3,8 +3,12 @@ package ca.spottedleaf.moonrise.common.util; - public final class MixinWorkarounds { - - // mixins tries to find the owner of the clone() method, which doesn't exist and NPEs -+ // https://github.com/FabricMC/Mixin/pull/147 - public static long[] clone(final long[] values) { - return values.clone(); - } - -+ public static byte[] clone(final byte[] values) { -+ return values.clone(); -+ } - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java -index 3abe0bd2a820352b85306d554bf14a4cf6123091..c125c70a68130be373acc989053a6c0e487be924 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java -@@ -1,45 +1,100 @@ - package ca.spottedleaf.moonrise.common.util; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool; -+import ca.spottedleaf.concurrentutil.executor.thread.PrioritisedThreadPool; -+import ca.spottedleaf.moonrise.common.PlatformHooks; - import org.slf4j.Logger; - import org.slf4j.LoggerFactory; --import java.io.File; -+import java.util.concurrent.TimeUnit; -+import java.util.concurrent.atomic.AtomicInteger; -+import java.util.function.Consumer; - - public final class MoonriseCommon { - - private static final Logger LOGGER = LoggerFactory.getLogger(MoonriseCommon.class); - -- // Paper start -- public static PrioritisedThreadPool WORKER_POOL; -- public static int WORKER_THREADS; -- public static void init(io.papermc.paper.configuration.GlobalConfiguration.ChunkSystem chunkSystem) { -- // Paper end -+ public static final PrioritisedThreadPool WORKER_POOL = new PrioritisedThreadPool( -+ new Consumer<>() { -+ private final AtomicInteger idGenerator = new AtomicInteger(); -+ -+ @Override -+ public void accept(Thread thread) { -+ thread.setDaemon(true); -+ thread.setName(PlatformHooks.get().getBrand() + " Common Worker #" + this.idGenerator.getAndIncrement()); -+ thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { -+ @Override -+ public void uncaughtException(final Thread thread, final Throwable throwable) { -+ LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); -+ } -+ }); -+ } -+ } -+ ); -+ public static final long WORKER_QUEUE_HOLD_TIME = (long)(20.0e6); // 20ms -+ public static final int CLIENT_DIVISION = 0; -+ public static final PrioritisedThreadPool.ExecutorGroup RENDER_EXECUTOR_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(CLIENT_DIVISION, 0); -+ public static final int SERVER_DIVISION = 1; -+ public static final PrioritisedThreadPool.ExecutorGroup PARALLEL_GEN_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); -+ public static final PrioritisedThreadPool.ExecutorGroup RADIUS_AWARE_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); -+ public static final PrioritisedThreadPool.ExecutorGroup LOAD_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); -+ -+ public static void adjustWorkerThreads(final int configWorkerThreads, final int configIoThreads) { - int defaultWorkerThreads = Runtime.getRuntime().availableProcessors() / 2; - if (defaultWorkerThreads <= 4) { - defaultWorkerThreads = defaultWorkerThreads <= 3 ? 1 : 2; - } else { - defaultWorkerThreads = defaultWorkerThreads / 2; - } -- defaultWorkerThreads = Integer.getInteger("Paper.WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); // Paper -+ defaultWorkerThreads = Integer.getInteger(PlatformHooks.get().getBrand() + ".WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); - -- int workerThreads = chunkSystem.workerThreads; // Paper -+ int workerThreads = configWorkerThreads; - - if (workerThreads <= 0) { - workerThreads = defaultWorkerThreads; - } - -- WORKER_POOL = new PrioritisedThreadPool( -- "Paper Worker Pool", workerThreads, // Paper -- (final Thread thread, final Integer id) -> { -- thread.setName("Paper Common Worker #" + id.intValue()); // Paper -+ final int ioThreads = Math.max(1, configIoThreads); -+ -+ WORKER_POOL.adjustThreadCount(workerThreads); -+ IO_POOL.adjustThreadCount(ioThreads); -+ -+ LOGGER.info(PlatformHooks.get().getBrand() + " is using " + workerThreads + " worker threads, " + ioThreads + " I/O threads"); -+ } -+ -+ public static final PrioritisedThreadPool IO_POOL = new PrioritisedThreadPool( -+ new Consumer<>() { -+ private final AtomicInteger idGenerator = new AtomicInteger(); -+ -+ @Override -+ public void accept(final Thread thread) { -+ thread.setDaemon(true); -+ thread.setName(PlatformHooks.get().getBrand() + " I/O Worker #" + this.idGenerator.getAndIncrement()); - thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { - @Override - public void uncaughtException(final Thread thread, final Throwable throwable) { - LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); - } - }); -- }, (long)(20.0e6)); // 20ms -- WORKER_THREADS = workerThreads; -+ } -+ } -+ ); -+ public static final long IO_QUEUE_HOLD_TIME = (long)(100.0e6); // 100ms -+ public static final PrioritisedThreadPool.ExecutorGroup CLIENT_PROFILER_IO_GROUP = IO_POOL.createExecutorGroup(CLIENT_DIVISION, 0); -+ public static final PrioritisedThreadPool.ExecutorGroup SERVER_REGION_IO_GROUP = IO_POOL.createExecutorGroup(SERVER_DIVISION, 0); -+ -+ public static void haltExecutors() { -+ MoonriseCommon.WORKER_POOL.shutdown(false); -+ LOGGER.info("Awaiting termination of worker pool for up to 60s..."); -+ if (!MoonriseCommon.WORKER_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { -+ LOGGER.error("Worker pool did not shut down in time!"); -+ MoonriseCommon.WORKER_POOL.halt(false); -+ } -+ -+ MoonriseCommon.IO_POOL.shutdown(false); -+ LOGGER.info("Awaiting termination of I/O pool for up to 60s..."); -+ if (!MoonriseCommon.IO_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { -+ LOGGER.error("I/O pool did not shut down in time!"); -+ MoonriseCommon.IO_POOL.halt(false); -+ } - } - - private MoonriseCommon() {} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java -index 1cf32d7d1bbc8a0a3f7cb9024c793f6744199f64..559c959aff3c9deef867b9e425fba3e2e669cac6 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java -@@ -1,8 +1,10 @@ - package ca.spottedleaf.moonrise.common.util; - -+import ca.spottedleaf.moonrise.common.PlatformHooks; -+ - public final class MoonriseConstants { - -- public static final int MAX_VIEW_DISTANCE = 32; -+ public static final int MAX_VIEW_DISTANCE = Integer.getInteger(PlatformHooks.get().getBrand() + ".MaxViewDistance", 32); - - private MoonriseConstants() {} - -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java b/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java -new file mode 100644 -index 0000000000000000000000000000000000000000..a9ff1c1a70faf4b7a64b265932f07a8b8f00c1ff ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java -@@ -0,0 +1,52 @@ -+package ca.spottedleaf.moonrise.common.util; -+ -+import net.minecraft.world.level.levelgen.LegacyRandomSource; -+ -+/** -+ * Avoid costly CAS of superclass -+ */ -+public final class SimpleRandom extends LegacyRandomSource { -+ -+ private static final long MULTIPLIER = 25214903917L; -+ private static final long ADDEND = 11L; -+ private static final int BITS = 48; -+ private static final long MASK = (1L << BITS) - 1; -+ -+ private long value; -+ -+ public SimpleRandom(final long seed) { -+ super(0L); -+ this.value = seed; -+ } -+ -+ @Override -+ public void setSeed(final long seed) { -+ this.value = (seed ^ MULTIPLIER) & MASK; -+ } -+ -+ private long advanceSeed() { -+ return this.value = ((this.value * MULTIPLIER) + ADDEND) & MASK; -+ } -+ -+ @Override -+ public int next(final int bits) { -+ return (int)(this.advanceSeed() >>> (BITS - bits)); -+ } -+ -+ @Override -+ public int nextInt() { -+ final long seed = this.advanceSeed(); -+ return (int)(seed >>> (BITS - Integer.SIZE)); -+ } -+ -+ @Override -+ public int nextInt(final int bound) { -+ if (bound <= 0) { -+ throw new IllegalArgumentException(); -+ } -+ -+ // https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ -+ final long value = this.advanceSeed() >>> (BITS - Integer.SIZE); -+ return (int)((value * (long)bound) >>> Integer.SIZE); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java -index 11b7f15755dde766140c29bedca456c80d53293f..217d1f908a36a5177ba3cbb80a33f73d4dab0fa0 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java -@@ -77,11 +77,15 @@ public class TickThread extends Thread { - } - - public TickThread(final Runnable run, final String name) { -- this(run, name, ID_GENERATOR.incrementAndGet()); -+ this(null, run, name); - } - -- private TickThread(final Runnable run, final String name, final int id) { -- super(run, name); -+ public TickThread(final ThreadGroup group, final Runnable run, final String name) { -+ this(group, run, name, ID_GENERATOR.incrementAndGet()); -+ } -+ -+ private TickThread(final ThreadGroup group, final Runnable run, final String name, final int id) { -+ super(group, run, name); - this.id = id; - } - -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java -index af9623240ff2d389aa7090623f507720e7dbab7d..efda2688ae1254a82ba7f6bf8bf597ef224cbb86 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java -@@ -8,11 +8,19 @@ public final class WorldUtil { - // min, max are inclusive - - public static int getMaxSection(final LevelHeightAccessor world) { -- return world.getMaxSection() - 1; // getMaxSection() is exclusive -+ return world.getMaxSectionY(); -+ } -+ -+ public static int getMaxSection(final Level world) { -+ return world.getMaxSectionY(); - } - - public static int getMinSection(final LevelHeightAccessor world) { -- return world.getMinSection(); -+ return world.getMinSectionY(); -+ } -+ -+ public static int getMinSection(final Level world) { -+ return world.getMinSectionY(); - } - - public static int getMaxLightSection(final LevelHeightAccessor world) { diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java index aef4fc0d3c272febe675d1ac846b88e58b4e7533..93bc56daec4526f373c84763b8c7ccb4a30e800b 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java From ecf4d9715e235c8d26202404c66642ca7e90aa68 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 24 Oct 2024 08:18:20 -0700 Subject: [PATCH 061/119] Begin fixing issues See diff in the update text file --- moonrise_update_1_21_2.txt | 10 +- ....patch => 0821-fixup-ConcurrentUtil.patch} | 0 ...-Utils.patch => 0822-fixup-MC-Utils.patch} | 262 +- patches/server/0823-fixup-MC-Utils.patch | 117 + .../0824-fixup-Paper-config-files.patch | 87 + .../0825-Rewrite-dataconverter-system.patch} | 1860 ++++++++++---- .../0826-Moonrise-optimisation-patches.patch} | 2267 ++++++----------- ...timize-BlockPosition-helper-methods.patch} | 14 +- ...fixup-Moonrise-optimisation-patches.patch} | 778 +++--- ...ble-implementation-for-blockstate-st.patch | 345 --- ...lementation-for-blockstate-state-loo.patch | 343 --- 11 files changed, 3071 insertions(+), 3012 deletions(-) rename patches/server/{1069-fixup-ConcurrentUtil.patch => 0821-fixup-ConcurrentUtil.patch} (100%) rename patches/server/{1070-fixup-MC-Utils.patch => 0822-fixup-MC-Utils.patch} (83%) create mode 100644 patches/server/0823-fixup-MC-Utils.patch create mode 100644 patches/server/0824-fixup-Paper-config-files.patch rename patches/{unapplied/server/0982-Rewrite-dataconverter-system.patch => server/0825-Rewrite-dataconverter-system.patch} (96%) rename patches/{unapplied/server/0981-Moonrise-optimisation-patches.patch => server/0826-Moonrise-optimisation-patches.patch} (94%) rename patches/server/{1072-fixup-Optimize-BlockPosition-helper-methods.patch => 0827-fixup-Optimize-BlockPosition-helper-methods.patch} (85%) rename patches/server/{1073-fixup-Moonrise-optimisation-patches.patch => 0828-fixup-Moonrise-optimisation-patches.patch} (96%) delete mode 100644 patches/server/1071-Revert-Custom-table-implementation-for-blockstate-st.patch delete mode 100644 patches/unapplied/server/1005-Custom-table-implementation-for-blockstate-state-loo.patch diff --git a/moonrise_update_1_21_2.txt b/moonrise_update_1_21_2.txt index f7067cc55624..d6a3d5df42e0 100644 --- a/moonrise_update_1_21_2.txt +++ b/moonrise_update_1_21_2.txt @@ -13,12 +13,7 @@ add notes to moonrise patch: todo: - double check that the misc changes commit on dev/1.21.2 moonrise is applied - implement platformhooks -- delete old block state table patch -- in StateHolder, implement getNullableValue from blockstate_propertyaccess -- ChunkEntitySlices getChunkEntities(), callEntitiesLoadEvent(), callEntitiesUnloadEvent() - in ChunkEntitySlices, implement modifySavedEntities() by copying from old -- in ChunkEntitySlices, implement unload() Entity.setRemoved() -- change PersistentEntitySectionManager addEntity chunk system call to have event=true - implement PlayerChunkUnloadEvent in PlatformHooks#onChunkUnWatch - make sure chunk pos is passed in PlatformHooks#postLoadProtoChunk - implement chunk_system.ChunkMapMixin diff from reference @@ -32,11 +27,10 @@ todo: - implement chunk_system.ServerLevelMixin diff from reference - implement chunk_tick_iteration - implement collisions.ServerExplosionMixin diff from reference -- implement modifyEntityTrackingRange with org.spigotmc.TrackingRange.getEntityTrackingRange -- implement random_ticking.BiomeMixin diff from reference - implement starlight.LevelLightEngineMixin diff from reference - implement starlight.ThreadedLevelLightEngineMixin diff from reference - implement starlight.ChunkSerializerMixin diff from reference - implement starlight.SerializableChunkData$SectionData diff from reference - implement starlight.SerializableChunkDataMixin diff from reference - +- unfuck the chtunk system config diff +- chunk system: move get entity lookup reroute into the folia scheduler api patch diff --git a/patches/server/1069-fixup-ConcurrentUtil.patch b/patches/server/0821-fixup-ConcurrentUtil.patch similarity index 100% rename from patches/server/1069-fixup-ConcurrentUtil.patch rename to patches/server/0821-fixup-ConcurrentUtil.patch diff --git a/patches/server/1070-fixup-MC-Utils.patch b/patches/server/0822-fixup-MC-Utils.patch similarity index 83% rename from patches/server/1070-fixup-MC-Utils.patch rename to patches/server/0822-fixup-MC-Utils.patch index b68d600395c4..cc014ce7e8da 100644 --- a/patches/server/1070-fixup-MC-Utils.patch +++ b/patches/server/0822-fixup-MC-Utils.patch @@ -6,16 +6,16 @@ Subject: [PATCH] fixup! MC Utils diff --git a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java new file mode 100644 -index 0000000000000000000000000000000000000000..69a20e9d72b02f28b349f24fd0ea08736888e642 +index 0000000000000000000000000000000000000000..3c5ed66328ccf94c4744a191a7c63562dd08158d --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java @@ -0,0 +1,115 @@ +package ca.spottedleaf.moonrise.common; + -+import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder; +import com.mojang.datafixers.DataFixer; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; ++import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.GenerationChunkHolder; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; @@ -56,7 +56,7 @@ index 0000000000000000000000000000000000000000..69a20e9d72b02f28b349f24fd0ea0873 + + public boolean allowAsyncTicketUpdates(); + -+ public void onChunkHolderTicketChange(final ServerLevel world, final NewChunkHolder holder, final int oldLevel, final int newLevel); ++ public void onChunkHolderTicketChange(final ServerLevel world, final ChunkHolder holder, final int oldLevel, final int newLevel); + + public void chunkUnloadFromWorld(final LevelChunk chunk); + @@ -685,7 +685,7 @@ index ab093b0e8ac6f762921eb1d15f5217345c4eba05..bb44de17a37082e57f2292a4f470740b } } diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -index 0abba00741b39b69a7f167e5d2670f2565c9a752..b61611351bf23efc1e90bab8a850ebbe6ffdd516 100644 +index da323a1105347d5cf4b946df10ded78a953236f2..94bba2b71918d79f54b3e28c35e76098ba0afd8c 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java @@ -1,6 +1,7 @@ @@ -694,11 +694,11 @@ index 0abba00741b39b69a7f167e5d2670f2565c9a752..b61611351bf23efc1e90bab8a850ebbe -import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.util.Priority; +import ca.spottedleaf.moonrise.common.PlatformHooks; - import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; - import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk; - import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader; -@@ -23,27 +24,27 @@ public final class ChunkSystem { - private static final Logger LOGGER = LogUtils.getLogger(); + import com.mojang.logging.LogUtils; + import net.minecraft.server.level.ChunkHolder; + import net.minecraft.server.level.FullChunkStatus; +@@ -24,15 +25,15 @@ public final class ChunkSystem { + } public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) { - scheduleChunkTask(level, chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); @@ -707,30 +707,50 @@ index 0abba00741b39b69a7f167e5d2670f2565c9a752..b61611351bf23efc1e90bab8a850ebbe - public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) { + public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final Priority priority) { - ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkTask(chunkX, chunkZ, run, 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 ChunkStatus toStatus, final boolean addTicket, final Priority priority, final Consumer onComplete) { - ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, gen, toStatus, addTicket, priority, onComplete); - } + if (gen) { + scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); +@@ -59,7 +60,7 @@ public final class ChunkSystem { + 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 onComplete) { + final boolean addTicket, final Priority priority, final Consumer onComplete) { - ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); + if (!org.bukkit.Bukkit.isPrimaryThread()) { + scheduleChunkTask(level, chunkX, chunkZ, () -> { + scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); +@@ -113,13 +114,13 @@ public final class ChunkSystem { + } + loadCallback.accept(result.orElse(null)); + }, (final Runnable r) -> { +- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); ++ scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST); + }); } public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ, final FullChunkStatus toStatus, final boolean addTicket, - final PrioritisedExecutor.Priority priority, final Consumer onComplete) { + final Priority priority, final Consumer onComplete) { - ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); + // This method goes unused until the chunk system rewrite + if (toStatus == FullChunkStatus.INACCESSIBLE) { + throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status"); +@@ -196,7 +197,7 @@ public final class ChunkSystem { + } + loadCallback.accept(result.orElse(null)); + }, (final Runnable r) -> { +- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); ++ scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST); + }); } -@@ -67,7 +68,10 @@ public final class ChunkSystem { +@@ -220,7 +221,10 @@ public final class ChunkSystem { return getUpdatingChunkHolderCount(level) != 0; } @@ -1002,6 +1022,211 @@ index af9623240ff2d389aa7090623f507720e7dbab7d..efda2688ae1254a82ba7f6bf8bf597ef } public static int getMaxLightSection(final LevelHeightAccessor world) { +diff --git a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6f2dc0900dbf13a02410682eecda56cea4481346 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java +@@ -0,0 +1,199 @@ ++package ca.spottedleaf.moonrise.paper; ++ ++import ca.spottedleaf.moonrise.common.PlatformHooks; ++import com.mojang.datafixers.DataFixer; ++import net.minecraft.core.BlockPos; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.server.level.ChunkHolder; ++import net.minecraft.server.level.GenerationChunkHolder; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.util.datafix.DataFixTypes; ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.level.BlockGetter; ++import net.minecraft.world.level.ChunkPos; ++import net.minecraft.world.level.Level; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.chunk.ChunkAccess; ++import net.minecraft.world.level.chunk.LevelChunk; ++import net.minecraft.world.level.chunk.ProtoChunk; ++import net.minecraft.world.level.chunk.storage.SerializableChunkData; ++import net.minecraft.world.level.entity.EntityTypeTest; ++import net.minecraft.world.phys.AABB; ++import java.util.List; ++import java.util.function.Predicate; ++ ++public final class PaperHooks implements PlatformHooks { ++ ++ @Override ++ public String getBrand() { ++ return "Paper"; ++ } ++ ++ @Override ++ public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos) { ++ return blockState.getLightEmission(); ++ } ++ ++ @Override ++ public Predicate maybeHasLightEmission() { ++ return (final BlockState state) -> { ++ return state.getLightEmission() != 0; ++ }; ++ } ++ ++ @Override ++ public boolean hasCurrentlyLoadingChunk() { ++ return false; ++ } ++ ++ @Override ++ public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder) { ++ return null; ++ } ++ ++ @Override ++ public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk) { ++ ++ } ++ ++ @Override ++ public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original) { ++ ++ } ++ ++ @Override ++ public boolean allowAsyncTicketUpdates() { ++ return true; ++ } ++ ++ @Override ++ public void onChunkHolderTicketChange(final ServerLevel world, final ChunkHolder holder, final int oldLevel, final int newLevel) { ++ ++ } ++ ++ @Override ++ public void chunkUnloadFromWorld(final LevelChunk chunk) { ++ ++ } ++ ++ @Override ++ public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data) { ++ ++ } ++ ++ @Override ++ public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player) { ++ ++ } ++ ++ @Override ++ public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player) { ++ ++ } ++ ++ @Override ++ public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate predicate, final List into) { ++ ++ } ++ ++ @Override ++ public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, final AABB boundingBox, final Predicate predicate, final List into, final int maxCount) { ++ ++ } ++ ++ @Override ++ public void entityMove(final Entity entity, final long oldSection, final long newSection) { ++ ++ } ++ ++ @Override ++ public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event) { ++ return true; ++ } ++ ++ @Override ++ public boolean configFixMC224294() { ++ return true; ++ } ++ ++ @Override ++ public boolean configAutoConfigSendDistance() { ++ ++ } ++ ++ @Override ++ public double configPlayerMaxLoadRate() { ++ ++ } ++ ++ @Override ++ public double configPlayerMaxGenRate() { ++ ++ } ++ ++ @Override ++ public double configPlayerMaxSendRate() { ++ ++ } ++ ++ @Override ++ public int configPlayerMaxConcurrentLoads() { ++ ++ } ++ ++ @Override ++ public int configPlayerMaxConcurrentGens() { ++ ++ } ++ ++ @Override ++ public long configAutoSaveInterval() { ++ ++ } ++ ++ @Override ++ public int configMaxAutoSavePerTick() { ++ ++ } ++ ++ @Override ++ public boolean configFixMC159283() { ++ return true; ++ } ++ ++ @Override ++ public boolean forceNoSave(final ChunkAccess chunk) { ++ return chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave; ++ } ++ ++ @Override ++ public CompoundTag convertNBT(final DataFixTypes type, final DataFixer dataFixer, final CompoundTag nbt, final int fromVersion, final int toVersion) { ++ return type.update(dataFixer, nbt, fromVersion, toVersion); ++ } ++ ++ @Override ++ public boolean hasMainChunkLoadHook() { ++ return false; ++ } ++ ++ @Override ++ public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData) { ++ ++ } ++ ++ @Override ++ public List modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List entities) { ++ return entities; ++ } ++ ++ @Override ++ public void unloadEntity(final Entity entity) { ++ entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, org.bukkit.event.entity.EntityRemoveEvent.Cause.UNLOAD); ++ } ++ ++ @Override ++ public int modifyEntityTrackingRange(final Entity entity, final int currentRange) { ++ return org.spigotmc.TrackingRange.getEntityTrackingRange(entity, currentRange); ++ } ++} 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 6baa313b8201ed23193d7885c85606b0899ade3c..3eb38271b6ca26099b2da04c2d969e32fd72b2af 100644 --- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java @@ -1029,3 +1254,10 @@ index 6baa313b8201ed23193d7885c85606b0899ade3c..3eb38271b6ca26099b2da04c2d969e32 } // Paper end - chunk system hooks if (!this.addEntityUuid(entity)) { +diff --git a/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks b/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks +new file mode 100644 +index 0000000000000000000000000000000000000000..e57c3ca79677b1dfe7cf3db36f0406de7ea5bd0a +--- /dev/null ++++ b/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks +@@ -0,0 +1 @@ ++ca.spottedleaf.moonrise.paper.PaperHooks diff --git a/patches/server/0823-fixup-MC-Utils.patch b/patches/server/0823-fixup-MC-Utils.patch new file mode 100644 index 000000000000..ea919462737d --- /dev/null +++ b/patches/server/0823-fixup-MC-Utils.patch @@ -0,0 +1,117 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Wed, 23 Oct 2024 22:13:41 -0700 +Subject: [PATCH] fixup! MC Utils + + +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java +index 3c5ed66328ccf94c4744a191a7c63562dd08158d..deb64f7ebebcf6de91ffe0542d6b449a4db64da0 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java +@@ -1,5 +1,6 @@ + package ca.spottedleaf.moonrise.common; + ++import com.mojang.datafixers.DSL; + import com.mojang.datafixers.DataFixer; + import net.minecraft.core.BlockPos; + import net.minecraft.nbt.CompoundTag; +@@ -7,7 +8,6 @@ import net.minecraft.server.level.ChunkHolder; + import net.minecraft.server.level.GenerationChunkHolder; + import net.minecraft.server.level.ServerLevel; + import net.minecraft.server.level.ServerPlayer; +-import net.minecraft.util.datafix.DataFixTypes; + import net.minecraft.world.entity.Entity; + import net.minecraft.world.level.BlockGetter; + import net.minecraft.world.level.ChunkPos; +@@ -88,7 +88,7 @@ public interface PlatformHooks { + // support for CB chunk mustNotSave + public boolean forceNoSave(final ChunkAccess chunk); + +- public CompoundTag convertNBT(final DataFixTypes type, final DataFixer dataFixer, final CompoundTag nbt, ++ public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt, + final int fromVersion, final int toVersion); + + public boolean hasMainChunkLoadHook(); +@@ -99,6 +99,8 @@ public interface PlatformHooks { + + public void unloadEntity(final Entity entity); + ++ public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk); ++ + public int modifyEntityTrackingRange(final Entity entity, final int currentRange); + + public static final class Holder { +diff --git a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java +index 6f2dc0900dbf13a02410682eecda56cea4481346..ee514a767f69de69d86e1e88d70fe37c4ab84277 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java ++++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java +@@ -1,14 +1,16 @@ + package ca.spottedleaf.moonrise.paper; + + import ca.spottedleaf.moonrise.common.PlatformHooks; ++import com.mojang.datafixers.DSL; + import com.mojang.datafixers.DataFixer; ++import com.mojang.serialization.Dynamic; + import net.minecraft.core.BlockPos; + import net.minecraft.nbt.CompoundTag; ++import net.minecraft.nbt.NbtOps; + import net.minecraft.server.level.ChunkHolder; + import net.minecraft.server.level.GenerationChunkHolder; + import net.minecraft.server.level.ServerLevel; + import net.minecraft.server.level.ServerPlayer; +-import net.minecraft.util.datafix.DataFixTypes; + import net.minecraft.world.entity.Entity; + import net.minecraft.world.level.BlockGetter; + import net.minecraft.world.level.ChunkPos; +@@ -168,8 +170,11 @@ public final class PaperHooks implements PlatformHooks { + } + + @Override +- public CompoundTag convertNBT(final DataFixTypes type, final DataFixer dataFixer, final CompoundTag nbt, final int fromVersion, final int toVersion) { +- return type.update(dataFixer, nbt, fromVersion, toVersion); ++ public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt, ++ final int fromVersion, final int toVersion) { ++ return (CompoundTag)dataFixer.update( ++ type, new Dynamic<>(NbtOps.INSTANCE, nbt), fromVersion, toVersion ++ ).getValue(); + } + + @Override +@@ -192,6 +197,11 @@ public final class PaperHooks implements PlatformHooks { + entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, org.bukkit.event.entity.EntityRemoveEvent.Cause.UNLOAD); + } + ++ @Override ++ public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) { ++ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities()); ++ } ++ + @Override + public int modifyEntityTrackingRange(final Entity entity, final int currentRange) { + return org.spigotmc.TrackingRange.getEntityTrackingRange(entity, currentRange); +diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java +index f18c2b85ed9541f646f157184221e333d0ae58bd..aff4c3d63a97d5bbde004a616f7e14fca59b5ab9 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java ++++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java +@@ -168,7 +168,7 @@ public class ChunkStatusTasks { + }, context.mainThreadExecutor()); + } + +- private static void postLoadProtoChunk(ServerLevel world, List entities) { ++ public static void postLoadProtoChunk(ServerLevel world, List entities) { // Paper - public + if (!entities.isEmpty()) { + // CraftBukkit start - these are spawned serialized (DefinedStructure) and we don't call an add event below at the moment due to ordering complexities + world.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(entities, world, EntitySpawnReason.LOAD).filter((entity) -> { +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 3eb38271b6ca26099b2da04c2d969e32fd72b2af..5aa74c00a61282830d82359eae2b114e2a48b6d9 100644 +--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java ++++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java +@@ -97,7 +97,7 @@ public class PersistentEntitySectionManager implements A + // I don't want to know why this is a generic type. + Entity entityCasted = (Entity)entity; + boolean wasRemoved = entityCasted.isRemoved(); +- boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted, existing, false); ++ boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted, existing, true); + if ((!wasRemoved && entityCasted.isRemoved()) || !screened) { + // removed by callback + return false; diff --git a/patches/server/0824-fixup-Paper-config-files.patch b/patches/server/0824-fixup-Paper-config-files.patch new file mode 100644 index 000000000000..a5c6d251afe8 --- /dev/null +++ b/patches/server/0824-fixup-Paper-config-files.patch @@ -0,0 +1,87 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Thu, 24 Oct 2024 08:11:12 -0700 +Subject: [PATCH] fixup! Paper config files + + +diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +index 73e8a524925ed6f2580d3bd01616646fabafda78..4bfe7e987450afa433fcad1847f6130654769416 100644 +--- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java ++++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +@@ -30,6 +30,45 @@ public class GlobalConfiguration extends ConfigurationPart { + public static GlobalConfiguration get() { + return instance; + } ++ ++ public ChunkLoadingBasic chunkLoadingBasic; ++ ++ public class ChunkLoadingBasic extends ConfigurationPart { ++ @Comment("The maximum rate in chunks per second that the server will send to any individual player. Set to -1 to disable this limit.") ++ public double playerMaxChunkSendRate = 75.0; ++ ++ @Comment( ++ "The maximum rate at which chunks will load for any individual player. " + ++ "Note that this setting also affects chunk generations, since a chunk load is always first issued to test if a" + ++ "chunk is already generated. Set to -1 to disable this limit." ++ ) ++ public double playerMaxChunkLoadRate = 100.0; ++ ++ @Comment("The maximum rate at which chunks will generate for any individual player. Set to -1 to disable this limit.") ++ public double playerMaxChunkGenerateRate = -1.0; ++ } ++ ++ public ChunkLoadingAdvanced chunkLoadingAdvanced; ++ ++ public class ChunkLoadingAdvanced extends ConfigurationPart { ++ @Comment( ++ "Set to true if the server will match the chunk send radius that clients have configured" + ++ "in their view distance settings if the client is less-than the server's send distance." ++ ) ++ public boolean autoConfigSendDistance = true; ++ ++ @Comment( ++ "Specifies the maximum amount of concurrent chunk loads that an individual player can have." + ++ "Set to 0 to let the server configure it automatically per player, or set it to -1 to disable the limit." ++ ) ++ public int playerMaxConcurrentChunkLoads = 0; ++ ++ @Comment( ++ "Specifies the maximum amount of concurrent chunk generations that an individual player can have." + ++ "Set to 0 to let the server configure it automatically per player, or set it to -1 to disable the limit." ++ ) ++ public int playerMaxConcurrentChunkGenerates = 0; ++ } + static void set(GlobalConfiguration instance) { + GlobalConfiguration.instance = instance; + } +@@ -145,21 +184,6 @@ public class GlobalConfiguration extends ConfigurationPart { + public int incomingPacketThreshold = 300; + } + +- public ChunkLoading chunkLoading; +- +- public class ChunkLoading extends ConfigurationPart { +- public int minLoadRadius = 2; +- public int maxConcurrentSends = 2; +- public boolean autoconfigSendDistance = true; +- public double targetPlayerChunkSendRate = 100.0; +- public double globalMaxChunkSendRate = -1.0; +- public boolean enableFrustumPriority = false; +- public double globalMaxChunkLoadRate = -1.0; +- public double playerMaxConcurrentLoads = 20.0; +- public double globalMaxConcurrentLoads = 500.0; +- public double playerMaxChunkLoadRate = -1.0; +- } +- + public UnsupportedSettings unsupportedSettings; + + public class UnsupportedSettings extends ConfigurationPart { +@@ -218,7 +242,7 @@ public class GlobalConfiguration extends ConfigurationPart { + + @PostProcess + private void postProcess() { +- //io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.init(this); ++ ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.init(this); + } + } + diff --git a/patches/unapplied/server/0982-Rewrite-dataconverter-system.patch b/patches/server/0825-Rewrite-dataconverter-system.patch similarity index 96% rename from patches/unapplied/server/0982-Rewrite-dataconverter-system.patch rename to patches/server/0825-Rewrite-dataconverter-system.patch index b5c09ba07676..173d97a5b2cd 100644 --- a/patches/unapplied/server/0982-Rewrite-dataconverter-system.patch +++ b/patches/server/0825-Rewrite-dataconverter-system.patch @@ -196,10 +196,10 @@ index 0000000000000000000000000000000000000000..a27d3d41109271834b6c37fa22d4b80d +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/MCVersionRegistry.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/MCVersionRegistry.java new file mode 100644 -index 0000000000000000000000000000000000000000..69b5f9fe20c09ac0e72205ba8e4475c2dfea8313 +index 0000000000000000000000000000000000000000..056801570c6756a4b484633d79080aed740832a8 --- /dev/null +++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/MCVersionRegistry.java -@@ -0,0 +1,431 @@ +@@ -0,0 +1,440 @@ +package ca.spottedleaf.dataconverter.minecraft; + +import ca.spottedleaf.dataconverter.converters.DataConverter; @@ -233,216 +233,225 @@ index 0000000000000000000000000000000000000000..69b5f9fe20c09ac0e72205ba8e4475c2 + // Note: Some of these are nameless. + // Unless a data version is specified here, it will NOT have converters ran for it. Please add them on update! + final int[] converterVersions = new int[] { -+ 99, -+ 100, -+ 101, -+ 102, -+ 105, -+ 106, -+ 107, -+ 108, -+ 109, -+ 110, -+ 111, -+ 113, -+ 135, -+ 143, -+ 147, -+ 165, -+ 501, -+ 502, -+ 505, -+ 700, -+ 701, -+ 702, -+ 703, -+ 704, -+ 705, -+ 804, -+ 806, -+ 808, -+ 808, -+ 813, -+ 816, -+ 820, -+ 1022, -+ 1125, -+ 1344, -+ 1446, -+ 1450, -+ 1451, -+ 1451, -+ 1451, -+ 1451, -+ 1451, -+ 1451, -+ 1451, -+ 1451, -+ 1451, -+ 1456, -+ 1458, -+ 1460, -+ 1466, -+ 1470, -+ 1474, -+ 1475, -+ 1480, -+ 1481, -+ 1483, -+ 1484, -+ 1486, -+ 1487, -+ 1488, -+ 1490, -+ 1492, -+ 1494, -+ 1496, -+ 1500, -+ 1501, -+ 1502, -+ 1506, -+ 1510, -+ 1514, -+ 1515, -+ 1624, -+ 1800, -+ 1801, -+ 1802, -+ 1803, -+ 1904, -+ 1905, -+ 1906, -+ 1909, -+ 1911, -+ 1914, -+ 1917, -+ 1918, -+ 1920, -+ 1925, -+ 1928, -+ 1929, -+ 1931, -+ 1936, -+ 1946, -+ 1948, -+ 1953, -+ 1955, -+ 1961, -+ 1963, -+ 2100, -+ 2202, -+ 2209, -+ 2211, -+ 2218, -+ 2501, -+ 2502, -+ 2503, -+ 2505, -+ 2508, -+ 2509, -+ 2511, -+ 2514, -+ 2516, -+ 2518, -+ 2519, -+ 2522, -+ 2523, -+ 2527, -+ 2528, -+ 2529, -+ 2531, -+ 2533, -+ 2535, -+ 2538, -+ 2550, -+ 2551, -+ 2552, -+ 2553, -+ 2558, -+ 2568, -+ 2671, -+ 2679, -+ 2680, -+ 2684, -+ 2686, -+ 2688, -+ 2690, -+ 2691, -+ 2693, -+ 2696, -+ 2700, -+ 2701, -+ 2702, -+ 2704, -+ 2707, -+ 2710, -+ 2717, -+ 2825, -+ 2831, -+ 2832, -+ 2833, -+ 2838, -+ 2841, -+ 2842, -+ 2843, -+ 2846, -+ 2852, -+ 2967, -+ 2970, -+ 3077, -+ 3078, -+ 3081, -+ 3082, -+ 3083, -+ 3084, -+ 3086, -+ 3087, -+ 3088, -+ 3090, -+ 3093, -+ 3094, -+ 3097, -+ 3108, -+ 3201, -+ 3203, -+ 3204, -+ 3209, -+ 3214, -+ 3319, -+ 3322, -+ 3438, -+ 3439, -+ 3440, -+ 3441, -+ 3447, -+ 3448, -+ 3450, -+ 3451, -+ 3459, -+ 3564, -+ 3565, -+ 3566, -+ 3568, -+ 3683, -+ 3685, -+ 3692, -+ 3800, -+ 3803, -+ 3807, -+ 3808, -+ 3809, -+ 3812, -+ 3813, -+ 3814, -+ 3818, -+ 3820, -+ 3825, -+ 3828, -+ 3833, -+ 3939, -+ 3943, -+ 3945 -+ // All up to 1.21 ++ 99, ++ 100, ++ 101, ++ 102, ++ 105, ++ 106, ++ 107, ++ 108, ++ 109, ++ 110, ++ 111, ++ 113, ++ 135, ++ 143, ++ 147, ++ 165, ++ 501, ++ 502, ++ 505, ++ 700, ++ 701, ++ 702, ++ 703, ++ 704, ++ 705, ++ 804, ++ 806, ++ 808, ++ 808, ++ 813, ++ 816, ++ 820, ++ 1022, ++ 1125, ++ 1344, ++ 1446, ++ 1450, ++ 1451, ++ 1451, ++ 1451, ++ 1451, ++ 1451, ++ 1451, ++ 1451, ++ 1451, ++ 1451, ++ 1456, ++ 1458, ++ 1460, ++ 1466, ++ 1470, ++ 1474, ++ 1475, ++ 1480, ++ 1481, ++ 1483, ++ 1484, ++ 1486, ++ 1487, ++ 1488, ++ 1490, ++ 1492, ++ 1494, ++ 1496, ++ 1500, ++ 1501, ++ 1502, ++ 1506, ++ 1510, ++ 1514, ++ 1515, ++ 1624, ++ 1800, ++ 1801, ++ 1802, ++ 1803, ++ 1904, ++ 1905, ++ 1906, ++ 1909, ++ 1911, ++ 1914, ++ 1917, ++ 1918, ++ 1920, ++ 1925, ++ 1928, ++ 1929, ++ 1931, ++ 1936, ++ 1946, ++ 1948, ++ 1953, ++ 1955, ++ 1961, ++ 1963, ++ 2100, ++ 2202, ++ 2209, ++ 2211, ++ 2218, ++ 2501, ++ 2502, ++ 2503, ++ 2505, ++ 2508, ++ 2509, ++ 2511, ++ 2514, ++ 2516, ++ 2518, ++ 2519, ++ 2522, ++ 2523, ++ 2527, ++ 2528, ++ 2529, ++ 2531, ++ 2533, ++ 2535, ++ 2538, ++ 2550, ++ 2551, ++ 2552, ++ 2553, ++ 2558, ++ 2568, ++ 2671, ++ 2679, ++ 2680, ++ 2684, ++ 2686, ++ 2688, ++ 2690, ++ 2691, ++ 2693, ++ 2696, ++ 2700, ++ 2701, ++ 2702, ++ 2704, ++ 2707, ++ 2710, ++ 2717, ++ 2825, ++ 2831, ++ 2832, ++ 2833, ++ 2838, ++ 2841, ++ 2842, ++ 2843, ++ 2846, ++ 2852, ++ 2967, ++ 2970, ++ 3077, ++ 3078, ++ 3081, ++ 3082, ++ 3083, ++ 3084, ++ 3086, ++ 3087, ++ 3088, ++ 3090, ++ 3093, ++ 3094, ++ 3097, ++ 3108, ++ 3201, ++ 3203, ++ 3204, ++ 3209, ++ 3214, ++ 3319, ++ 3322, ++ 3438, ++ 3439, ++ 3440, ++ 3441, ++ 3447, ++ 3448, ++ 3450, ++ 3451, ++ 3459, ++ 3564, ++ 3565, ++ 3566, ++ 3568, ++ 3683, ++ 3685, ++ 3692, ++ 3800, ++ 3803, ++ 3807, ++ 3808, ++ 3809, ++ 3812, ++ 3813, ++ 3814, ++ 3818, ++ 3820, ++ 3825, ++ 3828, ++ 3833, ++ 3939, ++ 3943, ++ 3945, ++ 4054, ++ 4055, ++ 4057, ++ 4059, ++ 4061, ++ 4064, ++ 4067, ++ 4068, ++ 4081, ++ // All up to 1.21.3 + }; + Arrays.sort(converterVersions); + @@ -633,10 +642,10 @@ index 0000000000000000000000000000000000000000..69b5f9fe20c09ac0e72205ba8e4475c2 +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/MCVersions.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/MCVersions.java new file mode 100644 -index 0000000000000000000000000000000000000000..fe546060bd27eda27931d9757831f0e4f043e31d +index 0000000000000000000000000000000000000000..aaa45b3f97b4e67ca04ad9739d3f0197bec46671 --- /dev/null +++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/MCVersions.java -@@ -0,0 +1,539 @@ +@@ -0,0 +1,558 @@ +package ca.spottedleaf.dataconverter.minecraft; + +@SuppressWarnings("unused") @@ -1161,18 +1170,37 @@ index 0000000000000000000000000000000000000000..fe546060bd27eda27931d9757831f0e4 + public static final int V1_20_5 = 3837; + public static final int V1_20_6_RC1 = 3838; + public static final int V1_20_6 = 3839; -+ public static final int V2418WA = 3940; -+ public static final int V2419WA = 3941; -+ public static final int V2419WB = 3942; -+ public static final int V2420WA = 3944; -+ public static final int V2421WA = 3946; -+ public static final int V2421WB = 3947; -+ public static final int V_1_21_PRE1 = 3948; -+ public static final int V_1_21_PRE2 = 3949; -+ public static final int V_1_21_PRE3 = 3950; -+ public static final int V_1_21_PRE4 = 3951; -+ public static final int V_1_21_RC1 = 3952; -+ public static final int V_1_21 = 3953; ++ public static final int V24W18A = 3940; ++ public static final int V24W19A = 3941; ++ public static final int V24W19B = 3942; ++ public static final int V24W20A = 3944; ++ public static final int V24W21A = 3946; ++ public static final int V24W21B = 3947; ++ public static final int V1_21_PRE1 = 3948; ++ public static final int V1_21_PRE2 = 3949; ++ public static final int V1_21_PRE3 = 3950; ++ public static final int V1_21_PRE4 = 3951; ++ public static final int V1_21_RC1 = 3952; ++ public static final int V1_21 = 3953; ++ public static final int V1_21_RC = 3954; ++ public static final int V1_21_1 = 3955; ++ public static final int V24W33A = 4058; ++ public static final int V24W34A = 4060; ++ public static final int V24W35A = 4062; ++ public static final int V24W36A = 4063; ++ public static final int V24W37A = 4065; ++ public static final int V24W38A = 4066; ++ public static final int V24W39A = 4069; ++ public static final int V24W40A = 4072; ++ public static final int V1_21_2_PRE1 = 4073; ++ public static final int V1_21_2_PRE2 = 4074; ++ public static final int V1_21_2_PRE3 = 4075; ++ public static final int V1_21_2_PRE4 = 4076; ++ public static final int V1_21_2_PRE5 = 4077; ++ public static final int V1_21_2_RC1 = 4078; ++ public static final int V1_21_2_RC2 = 4079; ++ public static final int V1_21_2 = 4080; ++ public static final int V1_21_3 = 4082; + + private MCVersions() {} +} @@ -1260,10 +1288,10 @@ index 0000000000000000000000000000000000000000..b2a4d16e6a2f9d71dbfa692922671581 +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/attributes/ConverterAbstractAttributesRename.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/attributes/ConverterAbstractAttributesRename.java new file mode 100644 -index 0000000000000000000000000000000000000000..c465036923656e8c974cc447bb57169b1a882e88 +index 0000000000000000000000000000000000000000..f227c0565a0c475fcb06991b485507d50bbd2ad0 --- /dev/null +++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/attributes/ConverterAbstractAttributesRename.java -@@ -0,0 +1,57 @@ +@@ -0,0 +1,60 @@ +package ca.spottedleaf.dataconverter.minecraft.converters.attributes; + +import ca.spottedleaf.dataconverter.converters.DataConverter; @@ -1281,6 +1309,72 @@ index 0000000000000000000000000000000000000000..c465036923656e8c974cc447bb57169b + } + + public static void register(final int version, final int versionStep, final Function renamer) { ++ MCTypeRegistry.DATA_COMPONENTS.addStructureConverter(new DataConverter<>(version, versionStep) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType attributeModifiers = data.getMap("minecraft:attribute_modifiers"); ++ if (attributeModifiers == null) { ++ return null; ++ } ++ ++ final ListType modifiers = attributeModifiers.getList("modifiers", ObjectType.MAP); ++ if (modifiers == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = modifiers.size(); i < len; ++i) { ++ RenameHelper.renameString(modifiers.getMap(i), "type", renamer); ++ } ++ ++ return null; ++ } ++ }); ++ ++ final DataConverter, MapType> entityConverter = new DataConverter<>(version, versionStep) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType modifiers = data.getList("attributes", ObjectType.MAP); ++ if (modifiers == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = modifiers.size(); i < len; ++i) { ++ RenameHelper.renameString(modifiers.getMap(i), "id", renamer); ++ } ++ ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.ENTITY.addStructureConverter(entityConverter); ++ MCTypeRegistry.PLAYER.addStructureConverter(entityConverter); ++ } ++ ++ private ConverterAbstractAttributesRename() {} ++} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/attributes/ConverterAbstractOldAttributesRename.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/attributes/ConverterAbstractOldAttributesRename.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1b871c78e77015d0216a0ecc61aa05689ccfab10 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/attributes/ConverterAbstractOldAttributesRename.java +@@ -0,0 +1,57 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.attributes; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import java.util.function.Function; ++ ++public final class ConverterAbstractOldAttributesRename { ++ ++ public static void register(final int version, final Function renamer) { ++ register(version, 0, renamer); ++ } ++ ++ public static void register(final int version, final int versionStep, final Function renamer) { + final DataConverter, MapType> entityConverter = new DataConverter<>(version, versionStep) { + @Override + public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { @@ -1319,7 +1413,7 @@ index 0000000000000000000000000000000000000000..c465036923656e8c974cc447bb57169b + }); + } + -+ private ConverterAbstractAttributesRename() {} ++ private ConverterAbstractOldAttributesRename() {} +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/blockname/ConverterAbstractBlockRename.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/blockname/ConverterAbstractBlockRename.java new file mode 100644 @@ -9245,15 +9339,16 @@ index 0000000000000000000000000000000000000000..075574f33476882ddc6787e3b8bac864 +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/datatypes/MCTypeRegistry.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/datatypes/MCTypeRegistry.java new file mode 100644 -index 0000000000000000000000000000000000000000..f4d7700ab53753dd5ac3222fbfd7bdd11b48197c +index 0000000000000000000000000000000000000000..11f5081f0cfb6f0f16689c68836b1f2962a0321c --- /dev/null +++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/datatypes/MCTypeRegistry.java -@@ -0,0 +1,303 @@ +@@ -0,0 +1,325 @@ +package ca.spottedleaf.dataconverter.minecraft.datatypes; + +import ca.spottedleaf.dataconverter.minecraft.versions.*; +import com.mojang.logging.LogUtils; +import org.slf4j.Logger; ++import java.text.DecimalFormat; + +public final class MCTypeRegistry { + @@ -9303,12 +9398,20 @@ index 0000000000000000000000000000000000000000..f4d7700ab53753dd5ac3222fbfd7bdd1 + public static final MCValueType DATACONVERTER_CUSTOM_TYPE_COMMAND = new MCValueType("DC_Custom/Command"); + + static { ++ LOGGER.info("Initialising converters for DataConverter..."); ++ ++ final long start = System.nanoTime(); + try { + registerAll(); + } catch (final Throwable thr) { + LOGGER.error(LogUtils.FATAL_MARKER, "Failed to register data converters", thr); + throw new RuntimeException(thr); + } ++ final long end = System.nanoTime(); ++ ++ final DecimalFormat oneDecimalFormat = new DecimalFormat("#,##0.0"); ++ ++ LOGGER.info("Finished initialising converters for DataConverter in " + oneDecimalFormat.format((double)(end - start) / 1.0E6) + "ms"); + } + + private static void registerAll() { @@ -9548,6 +9651,19 @@ index 0000000000000000000000000000000000000000..f4d7700ab53753dd5ac3222fbfd7bdd1 + V3939.register(); + V3943.register(); + V3945.register(); ++ // V1.21.2 ++ V4054.register(); ++ V4055.register(); ++ V4057.register(); ++ V4059.register(); ++ V4061.register(); ++ V4064.register(); ++ V4067.register(); ++ V4068.register(); ++ V4070.register(); ++ V4071.register(); ++ // V1.21.3 ++ V4081.register(); + } + + private MCTypeRegistry() {} @@ -9707,10 +9823,10 @@ index 0000000000000000000000000000000000000000..7f88487e7db589070512fafef1eb243a +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/util/ComponentUtils.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/util/ComponentUtils.java new file mode 100644 -index 0000000000000000000000000000000000000000..7f8f9d002b286f166d6e59bbf77aff74af10731c +index 0000000000000000000000000000000000000000..17ded002b5546de8be4a5238c20ccfda460a98bb --- /dev/null +++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/util/ComponentUtils.java -@@ -0,0 +1,78 @@ +@@ -0,0 +1,82 @@ +package ca.spottedleaf.dataconverter.minecraft.util; + +import com.google.gson.JsonElement; @@ -9741,6 +9857,10 @@ index 0000000000000000000000000000000000000000..7f8f9d002b286f166d6e59bbf77aff74 + } + + public static String retrieveTranslationString(final String possibleJson) { ++ if (possibleJson == null) { ++ return null; ++ } ++ + try { + final JsonElement element = JsonParser.parseString(possibleJson); + @@ -9958,10 +10078,10 @@ index 0000000000000000000000000000000000000000..91b1d0be9d697a4fa8bc5b448b329df1 +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V101.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V101.java new file mode 100644 -index 0000000000000000000000000000000000000000..96ea4669d6ad893ba52af045082f9ccb90fe90bf +index 0000000000000000000000000000000000000000..32d54d5960088b547b3ca09bff28b0752dddd77c --- /dev/null +++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V101.java -@@ -0,0 +1,38 @@ +@@ -0,0 +1,45 @@ +package ca.spottedleaf.dataconverter.minecraft.versions; + +import ca.spottedleaf.dataconverter.converters.DataConverter; @@ -9996,6 +10116,13 @@ index 0000000000000000000000000000000000000000..96ea4669d6ad893ba52af045082f9ccb + return null; + } + }); ++ MCTypeRegistry.ENTITY.addConverterForId("Villager", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.setBoolean("CanPickUpLoot", true); ++ return null; ++ } ++ }); + } + + private V101() {} @@ -10094,10 +10221,10 @@ index 0000000000000000000000000000000000000000..00bb3cff8f3d220d65a18f9b82b4b536 +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V1022.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V1022.java new file mode 100644 -index 0000000000000000000000000000000000000000..c1510d9167f466d3b7e3756353224f12f3876442 +index 0000000000000000000000000000000000000000..4f35484ed524dbf09cf9e8b1bb999fc98ec0bb0f --- /dev/null +++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V1022.java -@@ -0,0 +1,41 @@ +@@ -0,0 +1,43 @@ +package ca.spottedleaf.dataconverter.minecraft.versions; + +import ca.spottedleaf.dataconverter.minecraft.MCVersions; @@ -10113,6 +10240,8 @@ index 0000000000000000000000000000000000000000..c1510d9167f466d3b7e3756353224f12 + MCTypeRegistry.PLAYER.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { + WalkerUtils.convert(MCTypeRegistry.ENTITY, data.getMap("RootVehicle"), "Entity", fromVersion, toVersion); + ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY, data, "ender_pearls", fromVersion, toVersion); ++ + WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, data, "Inventory", fromVersion, toVersion); + WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, data, "EnderItems", fromVersion, toVersion); + @@ -10882,10 +11011,10 @@ index 0000000000000000000000000000000000000000..b735165f9b296730b77339875255aa98 +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V135.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V135.java new file mode 100644 -index 0000000000000000000000000000000000000000..1c9f754332d8a2299b7e2e5565882da52948d3a9 +index 0000000000000000000000000000000000000000..b003819eb395039dca8141179b57632e90db1d4d --- /dev/null +++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V135.java -@@ -0,0 +1,60 @@ +@@ -0,0 +1,62 @@ +package ca.spottedleaf.dataconverter.minecraft.versions; + +import ca.spottedleaf.dataconverter.converters.DataConverter; @@ -10933,6 +11062,8 @@ index 0000000000000000000000000000000000000000..1c9f754332d8a2299b7e2e5565882da5 + WalkerUtils.convert(MCTypeRegistry.ENTITY, rootVehicle, "Entity", fromVersion, toVersion); + } + ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY, data, "ender_pearls", fromVersion, toVersion); ++ + return null; + }); + @@ -16279,14 +16410,14 @@ index 0000000000000000000000000000000000000000..9a4d47d78596e2275745673f31f772f0 +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V2523.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V2523.java new file mode 100644 -index 0000000000000000000000000000000000000000..af295e8800b6eb5c13bbb88d21b391e5cc4bee1a +index 0000000000000000000000000000000000000000..7777d83d63dc177f0bac72290ed2e5c3cbd028be --- /dev/null +++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V2523.java @@ -0,0 +1,41 @@ +package ca.spottedleaf.dataconverter.minecraft.versions; + +import ca.spottedleaf.dataconverter.minecraft.MCVersions; -+import ca.spottedleaf.dataconverter.minecraft.converters.attributes.ConverterAbstractAttributesRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.attributes.ConverterAbstractOldAttributesRename; +import com.google.common.collect.ImmutableMap; +import java.util.HashMap; +import java.util.Map; @@ -16319,7 +16450,7 @@ index 0000000000000000000000000000000000000000..af295e8800b6eb5c13bbb88d21b391e5 + ); + + public static void register() { -+ ConverterAbstractAttributesRename.register(VERSION, RENAMES::get); ++ ConverterAbstractOldAttributesRename.register(VERSION, RENAMES::get); + } + + private V2523() {} @@ -22437,14 +22568,14 @@ index 0000000000000000000000000000000000000000..920d7734d883d74e8334102b22cabce2 +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3814.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3814.java new file mode 100644 -index 0000000000000000000000000000000000000000..d3b156129452202aea1f3b9f32142c91b64dc777 +index 0000000000000000000000000000000000000000..c4cc52620afb728533efe988bf2066ffc947f2d6 --- /dev/null +++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3814.java @@ -0,0 +1,21 @@ +package ca.spottedleaf.dataconverter.minecraft.versions; + +import ca.spottedleaf.dataconverter.minecraft.MCVersions; -+import ca.spottedleaf.dataconverter.minecraft.converters.attributes.ConverterAbstractAttributesRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.attributes.ConverterAbstractOldAttributesRename; +import java.util.HashMap; +import java.util.Map; + @@ -22457,7 +22588,7 @@ index 0000000000000000000000000000000000000000..d3b156129452202aea1f3b9f32142c91 + Map.of("minecraft:horse.jump_strength", "minecraft:generic.jump_strength") + ); + -+ ConverterAbstractAttributesRename.register(VERSION, renames::get); ++ ConverterAbstractOldAttributesRename.register(VERSION, renames::get); + } + + private V3814() {} @@ -23116,10 +23247,10 @@ index 0000000000000000000000000000000000000000..f752bb2fca2e4cd438c0540460912d4b +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3833.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3833.java new file mode 100644 -index 0000000000000000000000000000000000000000..4581b9ce0734e552fd8810239e7b86f8b43513c5 +index 0000000000000000000000000000000000000000..f097881401855137f5d4ac25ba1468e635a702b5 --- /dev/null +++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3833.java -@@ -0,0 +1,37 @@ +@@ -0,0 +1,36 @@ +package ca.spottedleaf.dataconverter.minecraft.versions; + +import ca.spottedleaf.dataconverter.converters.DataConverter; @@ -23141,7 +23272,6 @@ index 0000000000000000000000000000000000000000..4581b9ce0734e552fd8810239e7b86f8 + return null; + } + -+ + final String id = NamespaceUtil.correctNamespace(item.getString("id", "minecraft:air")); + final int count = item.getInt("count", 0); + @@ -23217,7 +23347,7 @@ index 0000000000000000000000000000000000000000..632c8008484e844d962405c6ef8fb9f0 +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3943.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3943.java new file mode 100644 -index 0000000000000000000000000000000000000000..b769abe8c469b15983b433fb9b7de9f41528a4f9 +index 0000000000000000000000000000000000000000..1cd426cf78d62d428406caa319cc5c8649e7f36c --- /dev/null +++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3943.java @@ -0,0 +1,34 @@ @@ -23230,7 +23360,7 @@ index 0000000000000000000000000000000000000000..b769abe8c469b15983b433fb9b7de9f4 + +public final class V3943 { + -+ private static final int VERSION = MCVersions.V2419WB + 1; ++ private static final int VERSION = MCVersions.V24W19B + 1; + + public static void register() { + MCTypeRegistry.OPTIONS.addStructureConverter(new DataConverter<>(VERSION) { @@ -23257,10 +23387,10 @@ index 0000000000000000000000000000000000000000..b769abe8c469b15983b433fb9b7de9f4 +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3945.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3945.java new file mode 100644 -index 0000000000000000000000000000000000000000..aaeb3b9006b9ae2a8d3a28158bc17d05be0ba2fa +index 0000000000000000000000000000000000000000..74c13c46390e4533a9eb2c8ae5d9846db55efa94 --- /dev/null +++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3945.java -@@ -0,0 +1,246 @@ +@@ -0,0 +1,244 @@ +package ca.spottedleaf.dataconverter.minecraft.versions; + +import ca.spottedleaf.dataconverter.converters.DataConverter; @@ -23279,7 +23409,7 @@ index 0000000000000000000000000000000000000000..aaeb3b9006b9ae2a8d3a28158bc17d05 + +public final class V3945 { + -+ private static final int VERSION = MCVersions.V2420WA + 1; ++ private static final int VERSION = MCVersions.V24W20A + 1; + + private static final Map UUID_TO_ID = new HashMap<>( + ImmutableMap.builder() @@ -23397,9 +23527,7 @@ index 0000000000000000000000000000000000000000..aaeb3b9006b9ae2a8d3a28158bc17d05 + return retList; + } + -+ + public static void register() { -+ + MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { + @Override + public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { @@ -23507,154 +23635,111 @@ index 0000000000000000000000000000000000000000..aaeb3b9006b9ae2a8d3a28158bc17d05 + + private V3945() {} +} -diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V501.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V501.java -new file mode 100644 -index 0000000000000000000000000000000000000000..a7a4d6446b7765ac485af82df660aafab05955bf ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V501.java -@@ -0,0 +1,18 @@ -+package ca.spottedleaf.dataconverter.minecraft.versions; -+ -+import ca.spottedleaf.dataconverter.minecraft.MCVersions; -+ -+public final class V501 { -+ -+ private static final int VERSION = MCVersions.V16W20A; -+ -+ private static void registerMob(final String id) { -+ V100.registerEquipment(VERSION, id); -+ } -+ -+ public static void register() { -+ registerMob("PolarBear"); -+ } -+ -+ private V501() {} -+} -diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V502.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V502.java +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4054.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4054.java new file mode 100644 -index 0000000000000000000000000000000000000000..7f88b435378305a3a66e1e54b85afd9b019513ee +index 0000000000000000000000000000000000000000..d65e05285ef238aa8c6d660aa42fcd69e07d9430 --- /dev/null -+++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V502.java -@@ -0,0 +1,45 @@ ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4054.java +@@ -0,0 +1,46 @@ +package ca.spottedleaf.dataconverter.minecraft.versions; + +import ca.spottedleaf.dataconverter.converters.DataConverter; +import ca.spottedleaf.dataconverter.minecraft.MCVersions; -+import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; +import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.util.ComponentUtils; +import ca.spottedleaf.dataconverter.types.MapType; -+import java.util.concurrent.ThreadLocalRandom; + -+public final class V502 { ++public final class V4054 { + -+ private static final int VERSION = MCVersions.V16W20A + 1; ++ private static final int VERSION = MCVersions.V1_21_1 + 99; + + public static void register() { -+ ConverterAbstractItemRename.register(VERSION, (final String name) -> { -+ return "minecraft:cooked_fished".equals(name) ? "minecraft:cooked_fish" : null; ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:banner", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ convertComponents(data.getMap("components")); ++ return null; ++ } + }); -+ MCTypeRegistry.ENTITY.addConverterForId("Zombie", new DataConverter<>(VERSION) { ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:white_banner", new DataConverter<>(VERSION) { + @Override + public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { -+ if (!data.getBoolean("IsVillager")) { -+ return null; -+ } -+ -+ data.remove("IsVillager"); -+ -+ if (data.hasKey("ZombieType")) { -+ return null; -+ } -+ -+ int type = data.getInt("VillagerProfession", -1); -+ // Vanilla doesn't remove the profession tag, so we don't! -+ if (type < 0 || type >= 6) { -+ type = ThreadLocalRandom.current().nextInt(6); -+ } -+ -+ data.setInt("ZombieType", type); -+ ++ convertComponents(data.getMap("components")); + return null; + } + }); + } + -+ private V502() {} -+} -diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V505.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V505.java -new file mode 100644 -index 0000000000000000000000000000000000000000..3faf2c3265600141003355771f38a7879e0f769a ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V505.java -@@ -0,0 +1,23 @@ -+package ca.spottedleaf.dataconverter.minecraft.versions; -+ -+import ca.spottedleaf.dataconverter.converters.DataConverter; -+import ca.spottedleaf.dataconverter.minecraft.MCVersions; -+import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; -+import ca.spottedleaf.dataconverter.types.MapType; ++ private static void convertComponents(final MapType components) { ++ if (components == null) { ++ return; ++ } + -+public final class V505 { ++ final String itemNameKey = ComponentUtils.retrieveTranslationString(components.getString("minecraft:item_name")); + -+ private static final int VERSION = MCVersions.V16W21B + 1; ++ if (!"block.minecraft.ominous_banner".equals(itemNameKey)) { ++ return; ++ } + -+ public static void register() { -+ MCTypeRegistry.OPTIONS.addStructureConverter(new DataConverter<>(VERSION) { -+ @Override -+ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { -+ data.setString("useVbo", "true"); -+ return null; -+ } -+ }); ++ components.setString("minecraft:rarity", "uncommon"); ++ components.setString("minecraft:item_name", ComponentUtils.createTranslatableComponent("block.minecraft.ominous_banner")); + } + -+ private V505() {} ++ private V4054() {} +} -diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V700.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V700.java +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4055.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4055.java new file mode 100644 -index 0000000000000000000000000000000000000000..3b65108c6a1ac469bb8f81a933b6475f3ea9f63f +index 0000000000000000000000000000000000000000..45b141a651d954554fcca68f36c0b3344328d902 --- /dev/null -+++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V700.java -@@ -0,0 +1,32 @@ ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4055.java +@@ -0,0 +1,41 @@ +package ca.spottedleaf.dataconverter.minecraft.versions; + -+import ca.spottedleaf.dataconverter.converters.DataConverter; +import ca.spottedleaf.dataconverter.minecraft.MCVersions; -+import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; -+import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.minecraft.converters.attributes.ConverterAbstractAttributesRename; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; + -+public final class V700 { ++public final class V4055 { + -+ private static final int VERSION = MCVersions.V1_10_2 + 188; ++ private static final int VERSION = MCVersions.V1_21_1 + 100; + -+ private static void registerMob(final String id) { -+ V100.registerEquipment(VERSION, id); ++ private static final Prefix[] PREFIXES_TO_REMOVE = new Prefix[] { ++ new Prefix("generic."), ++ new Prefix("horse."), ++ new Prefix("player."), ++ new Prefix("zombie.") ++ }; ++ ++ private static record Prefix(String raw, String namespaced) { ++ public Prefix(final String raw) { ++ this(raw, NamespaceUtil.correctNamespace(raw)); ++ } + } + + public static void register() { -+ MCTypeRegistry.ENTITY.addConverterForId("Guardian", new DataConverter<>(VERSION) { -+ @Override -+ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { -+ if (data.getBoolean("Elder")) { -+ data.setString("id", "ElderGuardian"); ++ ConverterAbstractAttributesRename.register(VERSION, (final String input) -> { ++ final String namespacedInput = NamespaceUtil.correctNamespace(input); ++ ++ for (final Prefix prefix : PREFIXES_TO_REMOVE) { ++ if (!namespacedInput.startsWith(prefix.namespaced())) { ++ continue; + } -+ data.remove("Elder"); -+ return null; ++ ++ return "minecraft:".concat(namespacedInput.substring(prefix.namespaced().length())); + } -+ }); + -+ registerMob("ElderGuardian"); ++ return null; ++ }); + } + -+ private V700() {} ++ private V4055() {} +} -diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V701.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V701.java +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4057.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4057.java new file mode 100644 -index 0000000000000000000000000000000000000000..55f00e218f04e1e095ccc7d62282d87d7eb8f8c7 +index 0000000000000000000000000000000000000000..b0949ac2035662ba1c943b4bfab2f19e985e6864 --- /dev/null -+++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V701.java -@@ -0,0 +1,41 @@ ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4057.java +@@ -0,0 +1,33 @@ +package ca.spottedleaf.dataconverter.minecraft.versions; + +import ca.spottedleaf.dataconverter.converters.DataConverter; @@ -23662,66 +23747,848 @@ index 0000000000000000000000000000000000000000..55f00e218f04e1e095ccc7d62282d87d +import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; +import ca.spottedleaf.dataconverter.types.MapType; + -+public final class V701 { -+ -+ private static final int VERSION = MCVersions.V1_10_2 + 189; ++public final class V4057 { + -+ private static void registerMob(final String id) { -+ V100.registerEquipment(VERSION, id); -+ } ++ private static final int VERSION = MCVersions.V1_21_1 + 102; + + public static void register() { -+ MCTypeRegistry.ENTITY.addConverterForId("Skeleton", new DataConverter<>(VERSION) { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { + @Override + public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { -+ final int type = data.getInt("SkeletonType"); -+ data.remove("SkeletonType"); ++ final MapType carvingMasks = data.getMap("CarvingMasks"); ++ if (carvingMasks == null) { ++ return null; ++ } ++ data.remove("CarvingMasks"); + -+ switch (type) { -+ case 1: -+ data.setString("id", "WitherSkeleton"); -+ break; -+ case 2: -+ data.setString("id", "Stray"); -+ break; ++ final long[] airMask = carvingMasks.getLongs("AIR"); ++ if (airMask != null) { ++ data.setLongs("carving_mask", airMask); + } + + return null; + } + }); -+ -+ registerMob("WitherSkeleton"); -+ registerMob("Stray"); + } + -+ private V701() {} ++ private V4057() {} +} -diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V702.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V702.java +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4059.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4059.java new file mode 100644 -index 0000000000000000000000000000000000000000..c0d74b4822be60c637f26b2ef1e172fdf9e89d01 +index 0000000000000000000000000000000000000000..0047a20dab2ffd6b39a8bcb8ed9f3878f20e31c2 --- /dev/null -+++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V702.java -@@ -0,0 +1,56 @@ ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4059.java +@@ -0,0 +1,128 @@ +package ca.spottedleaf.dataconverter.minecraft.versions; + +import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataWalker; +import ca.spottedleaf.dataconverter.minecraft.MCVersions; +import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; +import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; +import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; + -+public final class V702 { -+ -+ private static final int VERSION = MCVersions.V1_10_2 + 190; ++public final class V4059 { + -+ private static void registerMob(final String id) { -+ V100.registerEquipment(VERSION, id); -+ } ++ private static final int VERSION = MCVersions.V24W33A + 1; + + public static void register() { -+ MCTypeRegistry.ENTITY.addConverterForId("Zombie", new DataConverter<>(VERSION) { -+ @Override -+ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ // previous version: 3818.3 ++ MCTypeRegistry.DATA_COMPONENTS.addStructureWalker(VERSION, new DataWalker<>() { ++ private static void walkBlockPredicates(final MapType root, final long fromVersion, final long toVersion) { ++ if (root.hasKey("blocks", ObjectType.STRING)) { ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, root, "blocks", fromVersion, toVersion); ++ } else if (root.hasKey("blocks", ObjectType.LIST)) { ++ WalkerUtils.convertList(MCTypeRegistry.BLOCK_NAME, root, "blocks", fromVersion, toVersion); ++ } ++ } ++ ++ @Override ++ public MapType walk(final MapType root, final long fromVersion, final long toVersion) { ++ WalkerUtils.convertListPath(MCTypeRegistry.ENTITY, root, "minecraft:bees", "entity_data", fromVersion, toVersion); ++ ++ WalkerUtils.convert(MCTypeRegistry.TILE_ENTITY, root, "minecraft:block_entity_data", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, root, "minecraft:bundle_contents", fromVersion, toVersion); ++ ++ final MapType canBreak = root.getMap("minecraft:can_break"); ++ if (canBreak != null) { ++ final ListType predicates = canBreak.getList("predicates", ObjectType.MAP); ++ if (predicates != null) { ++ for (int i = 0, len = predicates.size(); i < len; ++i) { ++ walkBlockPredicates(predicates.getMap(i), fromVersion, toVersion); ++ } ++ } ++ // Not handled by DFU: simple encoding does not require "predicates" ++ walkBlockPredicates(canBreak, fromVersion, toVersion); ++ } ++ ++ final MapType canPlaceOn = root.getMap("minecraft:can_place_on"); ++ if (canPlaceOn != null) { ++ final ListType predicates = canPlaceOn.getList("predicates", ObjectType.MAP); ++ if (predicates != null) { ++ for (int i = 0, len = predicates.size(); i < len; ++i) { ++ walkBlockPredicates(predicates.getMap(i), fromVersion, toVersion); ++ } ++ } ++ // Not handled by DFU: simple encoding does not require "predicates" ++ walkBlockPredicates(canPlaceOn, fromVersion, toVersion); ++ } ++ ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, root, "minecraft:charged_projectiles", fromVersion, toVersion); ++ WalkerUtils.convertListPath(MCTypeRegistry.ITEM_STACK, root, "minecraft:container", "item", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, root, "minecraft:entity_data", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_NAME, root, "minecraft:pot_decorations", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, root, "minecraft:use_remainder", fromVersion, toVersion); ++ ++ final MapType equippable = root.getMap("minecraft:equippable"); ++ if (equippable != null) { ++ WalkerUtils.convert(MCTypeRegistry.ENTITY_NAME, equippable, "allowed_entities", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY_NAME, equippable, "allowed_entities", fromVersion, toVersion); ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.DATA_COMPONENTS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType food = data.getMap("minecraft:food"); ++ if (food == null) { ++ return null; ++ } ++ ++ final TypeUtil typeUtil = data.getTypeUtil(); ++ ++ final float eatSeconds = food.getFloat("eat_seconds", 1.6F); ++ ++ final ListType oldEffects = food.getList("effects", ObjectType.MAP); ++ final ListType newEffects = typeUtil.createEmptyList(); ++ if (oldEffects != null) { ++ for (int i = 0, len = oldEffects.size(); i < len; ++i) { ++ final MapType oldEffect = oldEffects.getMap(i); ++ ++ final MapType newEffect = typeUtil.createEmptyMap(); ++ newEffects.addMap(newEffect); ++ ++ newEffect.setString("type", "minecraft:apply_effects"); ++ ++ final Object oldEffectEffect = oldEffect.getGeneric("effect"); ++ final ListType newEffectEffects = typeUtil.createEmptyList(); ++ newEffectEffects.addGeneric(oldEffectEffect); ++ newEffect.setList("effects", newEffectEffects); ++ ++ newEffect.setFloat("probability", oldEffect.getFloat("probability", 1.0F)); ++ } ++ } ++ ++ final Object convertsTo = food.getGeneric("using_converts_to"); ++ if (convertsTo != null) { ++ data.setGeneric("minecraft:use_remainder", convertsTo); ++ } ++ ++ food.remove("eat_seconds"); ++ food.remove("effects"); ++ food.remove("using_converts_to"); ++ ++ final MapType consumable = typeUtil.createEmptyMap(); ++ data.setMap("minecraft:consumable", consumable); ++ ++ consumable.setFloat("consume_seconds", eatSeconds); ++ consumable.setList("on_consume_effects", newEffects); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V4059() {} ++} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4061.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4061.java +new file mode 100644 +index 0000000000000000000000000000000000000000..630263a61b5db4207c1a5051e3e2249ab3dd3957 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4061.java +@@ -0,0 +1,112 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; ++import com.mojang.brigadier.exceptions.CommandSyntaxException; ++import com.mojang.datafixers.util.Pair; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.nbt.TagParser; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V4061 { ++ ++ private static final int VERSION = MCVersions.V24W34A + 1; ++ ++ private static final Map, MapType>, String> CONVERT_MAP = new HashMap<>(); ++ static { ++ addConversion("trial_chamber/breeze", "{simultaneous_mobs: 1.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:breeze\"}}, weight: 1}], ticks_between_spawn: 20, total_mobs: 2.0f, total_mobs_added_per_player: 1.0f}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], simultaneous_mobs: 2.0f, total_mobs: 4.0f}"); ++ addConversion("trial_chamber/melee/husk", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:husk\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], spawn_potentials: [{data: {entity: {id: \"minecraft:husk\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_melee\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/melee/spider", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:spider\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}],simultaneous_mobs: 4.0f, total_mobs: 12.0f}"); ++ addConversion("trial_chamber/melee/zombie", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:zombie\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}],spawn_potentials: [{data: {entity: {id: \"minecraft:zombie\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_melee\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/ranged/poison_skeleton", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:bogged\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}],spawn_potentials: [{data: {entity: {id: \"minecraft:bogged\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_ranged\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/ranged/skeleton", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:skeleton\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], spawn_potentials: [{data: {entity: {id: \"minecraft:skeleton\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_ranged\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/ranged/stray", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:stray\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], spawn_potentials: [{data: {entity: {id: \"minecraft:stray\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_ranged\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/slow_ranged/poison_skeleton", "{simultaneous_mobs: 4.0f, simultaneous_mobs_added_per_player: 2.0f, spawn_potentials: [{data: {entity: {id: \"minecraft:bogged\"}}, weight: 1}], ticks_between_spawn: 160}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], spawn_potentials: [{data: {entity: {id: \"minecraft:bogged\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_ranged\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/slow_ranged/skeleton", "{simultaneous_mobs: 4.0f, simultaneous_mobs_added_per_player: 2.0f, spawn_potentials: [{data: {entity: {id: \"minecraft:skeleton\"}}, weight: 1}], ticks_between_spawn: 160}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], spawn_potentials: [{data: {entity: {id: \"minecraft:skeleton\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_ranged\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/slow_ranged/stray", "{simultaneous_mobs: 4.0f, simultaneous_mobs_added_per_player: 2.0f, spawn_potentials: [{data: {entity: {id: \"minecraft:stray\"}}, weight: 1}], ticks_between_spawn: 160}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}],spawn_potentials: [{data: {entity: {id: \"minecraft:stray\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_ranged\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/small_melee/baby_zombie", "{simultaneous_mobs: 2.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {IsBaby: 1b, id: \"minecraft:zombie\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], spawn_potentials: [{data: {entity: {IsBaby: 1b, id: \"minecraft:zombie\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_melee\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/small_melee/cave_spider", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:cave_spider\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], simultaneous_mobs: 4.0f, total_mobs: 12.0f}"); ++ addConversion("trial_chamber/small_melee/silverfish", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:silverfish\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], simultaneous_mobs: 4.0f, total_mobs: 12.0f}"); ++ addConversion("trial_chamber/small_melee/slime", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {Size: 1, id: \"minecraft:slime\"}}, weight: 3}, {data: {entity: {Size: 2, id: \"minecraft:slime\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], simultaneous_mobs: 4.0f, total_mobs: 12.0f}"); ++ } ++ ++ private static void addConversion(final String keyPath, final String normalsNBT, final String ominoussNBT) { ++ final String fullKey = "minecraft:".concat(keyPath); ++ ++ final CompoundTag normalNBT = parseNBT(normalsNBT); ++ final MapType normalMapType = new NBTMapType(normalNBT); ++ final CompoundTag ominousNBT = parseNBT(ominoussNBT); ++ ++ final CompoundTag ominousMerged = normalNBT.copy().merge(ominousNBT); ++ ++ CONVERT_MAP.put(Pair.of(normalMapType, new NBTMapType(ominousNBT)), fullKey); ++ CONVERT_MAP.put(Pair.of(normalMapType, new NBTMapType(ominousMerged)), fullKey); ++ CONVERT_MAP.put(Pair.of(normalMapType, new NBTMapType(removeDefaults(ominousMerged.copy()))), fullKey); ++ } ++ ++ private static CompoundTag parseNBT(final String sNBT) { ++ try { ++ return TagParser.parseTag(sNBT); ++ } catch (final CommandSyntaxException ex) { ++ throw new IllegalArgumentException("Failed to parse NBT: " + sNBT, ex); ++ } ++ } ++ ++ private static CompoundTag removeDefaults(final CompoundTag config) { ++ if (config.getInt("spawn_range") == 4) { ++ config.remove("spawn_range"); ++ } ++ ++ if (config.getFloat("total_mobs") == 6.0F) { ++ config.remove("total_mobs"); ++ } ++ ++ if (config.getFloat("simultaneous_mobs") == 2.0F) { ++ config.remove("simultaneous_mobs"); ++ } ++ ++ if (config.getFloat("total_mobs_added_per_player") == 2.0F) { ++ config.remove("total_mobs_added_per_player"); ++ } ++ ++ if (config.getFloat("simultaneous_mobs_added_per_player") == 1.0F) { ++ config.remove("simultaneous_mobs_added_per_player"); ++ } ++ ++ if (config.getInt("ticks_between_spawn") == 40) { ++ config.remove("ticks_between_spawn"); ++ } ++ ++ return config; ++ } ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:trial_spawner", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType normalConfig = data.getMap("normal_config"); ++ final MapType ominousConfig = data.getMap("ominous_config"); ++ ++ if (normalConfig == null || ominousConfig == null) { ++ return null; ++ } ++ ++ final String newKey = CONVERT_MAP.get(new Pair<>(normalConfig, ominousConfig)); ++ if (newKey == null) { ++ return null; ++ } ++ ++ data.setString("normal_config", newKey.concat("/normal")); ++ data.setString("ominous_config", newKey.concat("/ominous")); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V4061() {} ++} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4064.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4064.java +new file mode 100644 +index 0000000000000000000000000000000000000000..85eb8f37f89faed8b366c1d1c850b028bfcb2164 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4064.java +@@ -0,0 +1,36 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4064 { ++ ++ private static final int VERSION = MCVersions.V24W36A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType components = data.getMap("components"); ++ if (components == null) { ++ return null; ++ } ++ ++ if (components.hasKey("minecraft:fire_resistant")) { ++ components.remove("minecraft:fire_resistant"); ++ ++ final MapType damageResistant = components.getTypeUtil().createEmptyMap(); ++ components.setMap("minecraft:damage_resistant", damageResistant); ++ ++ damageResistant.setString("types", "#minecraft:is_fire"); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V4064() {} ++} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4067.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4067.java +new file mode 100644 +index 0000000000000000000000000000000000000000..855c5a99951996ffe4eabb24a69321043cce41d7 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4067.java +@@ -0,0 +1,143 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.leveldat.ConverterRemoveFeatureFlag; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.Arrays; ++import java.util.HashMap; ++import java.util.HashSet; ++import java.util.Map; ++ ++public final class V4067 { ++ ++ private static final int VERSION = MCVersions.V24W38A + 1; ++ ++ private static final record BoatType(String name, String suffix) {} ++ private static final BoatType[] BOAT_TYPES = new BoatType[] { ++ new BoatType("oak", "boat"), ++ new BoatType("spruce", "boat"), ++ new BoatType("birch", "boat"), ++ new BoatType("jungle", "boat"), ++ new BoatType("acacia", "boat"), ++ new BoatType("cherry", "boat"), ++ new BoatType("dark_oak", "boat"), ++ new BoatType("mangrove", "boat"), ++ new BoatType("bamboo", "raft") ++ }; ++ ++ private static void registerChestBoat(final String id) { ++ MCTypeRegistry.ENTITY.addWalker(VERSION, id, new DataWalkerItemLists("Items")); ++ } ++ ++ public static void register() { ++ // minecraft:oak_boat is a simple entity ++ // minecraft:spruce_boat is a simple entity ++ // minecraft:birch_boat is a simple entity ++ // minecraft:jungle_boat is a simple entity ++ // minecraft:acacia_boat is a simple entity ++ // minecraft:cherry_boat is a simple entity ++ // minecraft:dark_oak_boat is a simple entity ++ // minecraft:mangrove_boat is a simple entity ++ // minecraft:bamboo_raft is a simple entity ++ ++ registerChestBoat("minecraft:oak_chest_boat"); ++ registerChestBoat("minecraft:spruce_chest_boat"); ++ registerChestBoat("minecraft:birch_chest_boat"); ++ registerChestBoat("minecraft:jungle_chest_boat"); ++ registerChestBoat("minecraft:acacia_chest_boat"); ++ registerChestBoat("minecraft:cherry_chest_boat"); ++ registerChestBoat("minecraft:dark_oak_chest_boat"); ++ registerChestBoat("minecraft:mangrove_chest_boat"); ++ registerChestBoat("minecraft:bamboo_chest_raft"); ++ ++ // we do not update V704 to set the new boat types, as the new ids are only registered here ++ // if we updated V704 to set the new boat types, then the registered walkers for the chest_boat would not run before ++ // V4067 as they are only registered here ++ ++ // to ensure that the id is correctly set eventually, we will force Type to the correct value based on the item id ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ private static final Map BOAT_TYPES_BY_ITEM_ID = new HashMap<>(); ++ static { ++ for (final BoatType boatType : BOAT_TYPES) { ++ BOAT_TYPES_BY_ITEM_ID.put(boatType.name() + "_" + boatType.suffix(), boatType.name()); ++ BOAT_TYPES_BY_ITEM_ID.put(boatType.name() + "_chest_" + boatType.suffix(), boatType.name()); ++ } ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String id = data.getString("id"); ++ final String boatType = BOAT_TYPES_BY_ITEM_ID.get(id); ++ ++ if (boatType == null) { ++ return null; ++ } ++ ++ final MapType components = data.getMap("components"); ++ if (components == null) { ++ return null; ++ } ++ ++ final MapType entityData = components.getMap("minecraft:entity_data"); ++ if (entityData == null) { ++ return null; ++ } ++ ++ entityData.setString("Type", boatType); ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ private static final Map NORMAL_REMAPPING = new HashMap<>(BOAT_TYPES.length); ++ static { ++ for (final BoatType type : BOAT_TYPES) { ++ NORMAL_REMAPPING.put(type.name(), type.name() + "_" + type.suffix()); ++ } ++ } ++ private static final Map CHEST_REMAPPING = new HashMap<>(BOAT_TYPES.length); ++ static { ++ for (final BoatType type : BOAT_TYPES) { ++ CHEST_REMAPPING.put(type.name(), type.name() + "_chest_" + type.suffix()); ++ } ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String id = data.getString("id"); ++ if (id == null) { ++ // wat ++ return null; ++ } ++ ++ final boolean normalBoat = id.equals("minecraft:boat"); ++ final boolean chestBoat = id.equals("minecraft:chest_boat"); ++ ++ if (!normalBoat && !chestBoat) { ++ return null; ++ } ++ ++ final String type = data.getString("Type"); ++ data.remove("Type"); ++ ++ if (normalBoat) { ++ data.setString("id", NORMAL_REMAPPING.getOrDefault(type, "minecraft:oak_boat")); ++ } else { ++ data.setString("id", CHEST_REMAPPING.getOrDefault(type, "minecraft:oak_chest_boat")); ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.LEVEL.addStructureConverter( ++ new ConverterRemoveFeatureFlag(VERSION, new HashSet<>(Arrays.asList("minecraft:bundle"))) ++ ); ++ } ++ ++ private V4067() {} ++} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4068.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4068.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3de9862f083e6a2a687b42eef36746aa846cc745 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4068.java +@@ -0,0 +1,64 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++import com.google.common.escape.Escaper; ++import com.google.common.escape.Escapers; ++ ++public final class V4068 { ++ public static final Escaper ESCAPER = Escapers.builder().addEscape('"', "\\\"").addEscape('\\', "\\\\").build(); ++ ++ private static final int VERSION = MCVersions.V24W38A + 2; ++ ++ private static void convertLock(final MapType root, final String srcPath, final String dstPath) { ++ if (root == null) { ++ return; ++ } ++ ++ final Object lockGeneric = root.getGeneric(srcPath); ++ if (lockGeneric == null) { ++ return; ++ } ++ ++ final TypeUtil typeUtil = root.getTypeUtil(); ++ ++ final MapType newLock = typeUtil.createEmptyMap(); ++ root.remove(srcPath); ++ root.setMap(dstPath, newLock); ++ ++ if (lockGeneric instanceof String lock) { ++ final MapType lockComponents = typeUtil.createEmptyMap(); ++ newLock.setMap("components", lockComponents); ++ ++ lockComponents.setString("minecraft:custom_name", ESCAPER.escape(lock)); ++ } ++ } ++ ++ public static void register() { ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType components = data.getMap("components"); ++ if (components == null) { ++ return null; ++ } ++ ++ convertLock(components, "minecraft:lock", "minecraft:lock"); ++ ++ return null; ++ } ++ }); ++ MCTypeRegistry.TILE_ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ convertLock(data, "Lock", "lock"); ++ return null; ++ } ++ }); ++ } ++ ++ private V4068() {} ++} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4070.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4070.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b85673d792d4b1c317d312ba607a0d30c2f57ea9 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4070.java +@@ -0,0 +1,22 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++ ++public final class V4070 { ++ ++ private static final int VERSION = MCVersions.V24W39A + 1; ++ ++ private static void registerChestBoat(final String id) { ++ MCTypeRegistry.ENTITY.addWalker(VERSION, id, new DataWalkerItemLists("Items")); ++ } ++ ++ public static void register() { ++ // minecraft:pale_oak_boat is a simple entity ++ ++ registerChestBoat("minecraft:pale_oak_chest_boat"); ++ } ++ ++ private V4070() {} ++} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4071.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4071.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3b0855353f40e8ce54b86305152aa35af9154c6f +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4071.java +@@ -0,0 +1,21 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V4071 { ++ ++ private static final int VERSION = MCVersions.V24W39A + 2; ++ ++ private static void registerMob(final String id) { ++ V100.registerEquipment(VERSION, 0, id); ++ } ++ ++ public static void register() { ++ registerMob("minecraft:creaking"); ++ registerMob("minecraft:creaking_transient"); ++ ++ // minecraft:creaking_heart is a simple tile entity? not sure what the difference is between remainder and optional ++ } ++ ++ private V4071() {} ++} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4081.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4081.java +new file mode 100644 +index 0000000000000000000000000000000000000000..22eae4d39c3887ef4991fd21856c32c43c543f88 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V4081.java +@@ -0,0 +1,27 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4081 { ++ ++ private static final int VERSION = MCVersions.V1_21_2 + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:salmon", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if ("large".equals(data.getString("type"))) { ++ return null; ++ } ++ ++ data.setString("type", "medium"); ++ return null; ++ } ++ }); ++ } ++ ++ private V4081() {} ++} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V501.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V501.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a7a4d6446b7765ac485af82df660aafab05955bf +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V501.java +@@ -0,0 +1,18 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V501 { ++ ++ private static final int VERSION = MCVersions.V16W20A; ++ ++ private static void registerMob(final String id) { ++ V100.registerEquipment(VERSION, id); ++ } ++ ++ public static void register() { ++ registerMob("PolarBear"); ++ } ++ ++ private V501() {} ++} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V502.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V502.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7f88b435378305a3a66e1e54b85afd9b019513ee +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V502.java +@@ -0,0 +1,45 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.concurrent.ThreadLocalRandom; ++ ++public final class V502 { ++ ++ private static final int VERSION = MCVersions.V16W20A + 1; ++ ++ public static void register() { ++ ConverterAbstractItemRename.register(VERSION, (final String name) -> { ++ return "minecraft:cooked_fished".equals(name) ? "minecraft:cooked_fish" : null; ++ }); ++ MCTypeRegistry.ENTITY.addConverterForId("Zombie", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (!data.getBoolean("IsVillager")) { ++ return null; ++ } ++ ++ data.remove("IsVillager"); ++ ++ if (data.hasKey("ZombieType")) { ++ return null; ++ } ++ ++ int type = data.getInt("VillagerProfession", -1); ++ // Vanilla doesn't remove the profession tag, so we don't! ++ if (type < 0 || type >= 6) { ++ type = ThreadLocalRandom.current().nextInt(6); ++ } ++ ++ data.setInt("ZombieType", type); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V502() {} ++} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V505.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V505.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3faf2c3265600141003355771f38a7879e0f769a +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V505.java +@@ -0,0 +1,23 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V505 { ++ ++ private static final int VERSION = MCVersions.V16W21B + 1; ++ ++ public static void register() { ++ MCTypeRegistry.OPTIONS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.setString("useVbo", "true"); ++ return null; ++ } ++ }); ++ } ++ ++ private V505() {} ++} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V700.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V700.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3b65108c6a1ac469bb8f81a933b6475f3ea9f63f +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V700.java +@@ -0,0 +1,32 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V700 { ++ ++ private static final int VERSION = MCVersions.V1_10_2 + 188; ++ ++ private static void registerMob(final String id) { ++ V100.registerEquipment(VERSION, id); ++ } ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("Guardian", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (data.getBoolean("Elder")) { ++ data.setString("id", "ElderGuardian"); ++ } ++ data.remove("Elder"); ++ return null; ++ } ++ }); ++ ++ registerMob("ElderGuardian"); ++ } ++ ++ private V700() {} ++} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V701.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V701.java +new file mode 100644 +index 0000000000000000000000000000000000000000..55f00e218f04e1e095ccc7d62282d87d7eb8f8c7 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V701.java +@@ -0,0 +1,41 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V701 { ++ ++ private static final int VERSION = MCVersions.V1_10_2 + 189; ++ ++ private static void registerMob(final String id) { ++ V100.registerEquipment(VERSION, id); ++ } ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("Skeleton", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final int type = data.getInt("SkeletonType"); ++ data.remove("SkeletonType"); ++ ++ switch (type) { ++ case 1: ++ data.setString("id", "WitherSkeleton"); ++ break; ++ case 2: ++ data.setString("id", "Stray"); ++ break; ++ } ++ ++ return null; ++ } ++ }); ++ ++ registerMob("WitherSkeleton"); ++ registerMob("Stray"); ++ } ++ ++ private V701() {} ++} +diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V702.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V702.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c0d74b4822be60c637f26b2ef1e172fdf9e89d01 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V702.java +@@ -0,0 +1,56 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V702 { ++ ++ private static final int VERSION = MCVersions.V1_10_2 + 190; ++ ++ private static void registerMob(final String id) { ++ V100.registerEquipment(VERSION, id); ++ } ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("Zombie", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { + final int zombieType = data.getInt("ZombieType"); + data.remove("ZombieType"); + @@ -28106,10 +28973,10 @@ index 0000000000000000000000000000000000000000..62c0f4073aff301bf5b3187e0d4446fd +} diff --git a/src/main/java/ca/spottedleaf/dataconverter/util/CommandArgumentUpgrader.java b/src/main/java/ca/spottedleaf/dataconverter/util/CommandArgumentUpgrader.java new file mode 100644 -index 0000000000000000000000000000000000000000..6f2a30eed4e9741a128b5a171edef6abedab7362 +index 0000000000000000000000000000000000000000..40da70d5cf584a9730f9fe81c355cf8513fba475 --- /dev/null +++ b/src/main/java/ca/spottedleaf/dataconverter/util/CommandArgumentUpgrader.java -@@ -0,0 +1,491 @@ +@@ -0,0 +1,592 @@ +package ca.spottedleaf.dataconverter.util; + +import ca.spottedleaf.dataconverter.minecraft.MCDataConverter; @@ -28156,6 +29023,7 @@ index 0000000000000000000000000000000000000000..6f2a30eed4e9741a128b5a171edef6ab +import net.minecraft.commands.arguments.ComponentArgument; +import net.minecraft.commands.arguments.CompoundTagArgument; +import net.minecraft.commands.arguments.ResourceLocationArgument; ++import net.minecraft.commands.arguments.blocks.BlockStateArgument; +import net.minecraft.commands.arguments.coordinates.Vec3Argument; +import net.minecraft.commands.arguments.item.ItemArgument; +import net.minecraft.core.Holder; @@ -28186,6 +29054,7 @@ index 0000000000000000000000000000000000000000..6f2a30eed4e9741a128b5a171edef6ab + return new CommandArgumentUpgrader(functionPermissionLevel, builder -> { + builder.registerReplacement(ItemArgument.class, (argument, ctx) -> new ItemParser_1_20_4()); + builder.registerReplacement(ComponentArgument.class, (argument, ctx) -> new ComponentParser_1_20_4()); ++ builder.registerReplacement(BlockStateArgument.class, (argument, ctx) -> new BlockStateParser_1_20_4()); + builder.registerExtraCommand(CommandArgumentUpgrader::registerSummon_1_20_4_to_1_20_5); + }); + } @@ -28367,6 +29236,105 @@ index 0000000000000000000000000000000000000000..6f2a30eed4e9741a128b5a171edef6ab + } + } + ++ private static class BlockStateParser_1_20_4 implements ArgumentType { ++ @Override ++ public UpgradedArgument parse(final StringReader reader) throws CommandSyntaxException { ++ String block = ResourceLocation.read(reader).toString(); ++ ++ StringBuilder properties = new StringBuilder(); ++ if (reader.canRead() && reader.peek() == '[') { ++ char c; ++ do { ++ c = reader.read(); ++ properties.append(c); ++ } while (reader.canRead() && c != ']'); ++ } ++ ++ if (!reader.canRead() || reader.peek() != '{') { ++ return new UpgradedArgument(block + properties); ++ } ++ ++ CompoundTag tag = new TagParser(reader).readStruct(); ++ boolean missId = !tag.contains("id", Tag.TAG_STRING); ++ if (missId) { // Data converter can't upgrade tile entities without it ++ tag.putString("id", CommandArgumentUpgrader.blockToTileEntity(block)); ++ } ++ tag = MCDataConverter.convertTag( ++ MCTypeRegistry.TILE_ENTITY, tag, MCVersions.V1_20_4, SharedConstants.getCurrentVersion().getDataVersion().getVersion() ++ ); ++ if (missId) { ++ tag.remove("id"); ++ } ++ ++ return new UpgradedArgument(block + properties + tag); ++ } ++ } ++ ++ private static String blockToTileEntity(String block) { ++ return switch (block) { ++ case "minecraft:acacia_sign", "minecraft:jungle_wall_sign", "minecraft:oak_sign", ++ "minecraft:cherry_sign", "minecraft:birch_wall_sign", "minecraft:dark_oak_sign", ++ "minecraft:mangrove_wall_sign", "minecraft:cherry_wall_sign", "minecraft:jungle_sign", ++ "minecraft:mangrove_sign", "minecraft:spruce_wall_sign", "minecraft:crimson_sign", ++ "minecraft:oak_wall_sign", "minecraft:crimson_wall_sign", "minecraft:bamboo_sign", ++ "minecraft:warped_wall_sign", "minecraft:bamboo_wall_sign", "minecraft:acacia_wall_sign", ++ "minecraft:spruce_sign", "minecraft:warped_sign", "minecraft:dark_oak_wall_sign", ++ "minecraft:birch_sign" ++ -> "minecraft:sign"; ++ case "minecraft:acacia_hanging_sign", "minecraft:crimson_wall_hanging_sign", ++ "minecraft:jungle_wall_hanging_sign", "minecraft:dark_oak_wall_hanging_sign", ++ "minecraft:crimson_hanging_sign", "minecraft:bamboo_wall_hanging_sign", ++ "minecraft:bamboo_hanging_sign", "minecraft:oak_wall_hanging_sign", ++ "minecraft:cherry_wall_hanging_sign", "minecraft:warped_wall_hanging_sign", ++ "minecraft:birch_hanging_sign", "minecraft:mangrove_hanging_sign", ++ "minecraft:birch_wall_hanging_sign", "minecraft:jungle_hanging_sign", ++ "minecraft:cherry_hanging_sign", "minecraft:spruce_hanging_sign", ++ "minecraft:warped_hanging_sign", "minecraft:mangrove_wall_hanging_sign", ++ "minecraft:spruce_wall_hanging_sign", "minecraft:dark_oak_hanging_sign", ++ "minecraft:oak_hanging_sign", "minecraft:acacia_wall_hanging_sign" ++ -> "minecraft:hanging_sign"; ++ case "minecraft:spawner" -> "minecraft:mob_spawner"; ++ case "minecraft:moving_piston" -> "minecraft:piston"; ++ case "minecraft:skeleton_skull" , "minecraft:skeleton_wall_skull", "minecraft:player_wall_head", ++ "minecraft:creeper_wall_head", "minecraft:zombie_head", "minecraft:wither_skeleton_skull", ++ "minecraft:creeper_head", "minecraft:wither_skeleton_wall_skull", "minecraft:dragon_head", ++ "minecraft:piglin_wall_head", "minecraft:dragon_wall_head", "minecraft:player_head", ++ "minecraft:zombie_wall_head", "minecraft:piglin_head" ++ -> "minecraft:skull"; ++ case "minecraft:black_banner", "minecraft:orange_wall_banner", "minecraft:gray_wall_banner", ++ "minecraft:magenta_banner", "minecraft:red_banner", "minecraft:brown_wall_banner", ++ "minecraft:pink_banner", "minecraft:light_blue_banner", "minecraft:cyan_wall_banner", ++ "minecraft:purple_banner", "minecraft:brown_banner", "minecraft:light_gray_wall_banner", ++ "minecraft:black_wall_banner", "minecraft:gray_banner", "minecraft:yellow_wall_banner", ++ "minecraft:light_gray_banner", "minecraft:red_wall_banner", "minecraft:light_blue_wall_banner", ++ "minecraft:pink_wall_banner", "minecraft:white_banner", "minecraft:green_wall_banner", ++ "minecraft:white_wall_banner", "minecraft:magenta_wall_banner", "minecraft:green_banner", ++ "minecraft:orange_banner", "minecraft:blue_wall_banner", "minecraft:cyan_banner", ++ "minecraft:purple_wall_banner", "minecraft:lime_wall_banner", "minecraft:yellow_banner", ++ "minecraft:lime_banner", "minecraft:blue_banner" ++ -> "minecraft:banner"; ++ case "minecraft:repeating_command_block", "minecraft:chain_command_block" ++ -> "minecraft:command_block"; ++ case "minecraft:brown_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:white_shulker_box", ++ "minecraft:green_shulker_box", "minecraft:black_shulker_box", "minecraft:lime_shulker_box", ++ "minecraft:pink_shulker_box", "minecraft:light_gray_shulker_box", "minecraft:magenta_shulker_box", ++ "minecraft:orange_shulker_box", "minecraft:purple_shulker_box", "minecraft:cyan_shulker_box", ++ "minecraft:yellow_shulker_box", "minecraft:red_shulker_box", "minecraft:blue_shulker_box", ++ "minecraft:gray_shulker_box" ++ -> "minecraft:shulker_box"; ++ case "minecraft:purple_bed", "minecraft:light_blue_bed", "minecraft:yellow_bed", ++ "minecraft:orange_bed", "minecraft:light_gray_bed", "minecraft:red_bed", ++ "minecraft:gray_bed", "minecraft:brown_bed", "minecraft:cyan_bed", "minecraft:magenta_bed", ++ "minecraft:green_bed", "minecraft:white_bed", "minecraft:black_bed", "minecraft:blue_bed", ++ "minecraft:pink_bed", "minecraft:lime_bed" ++ -> "minecraft:bed"; ++ case "minecraft:soul_campfire" -> "minecraft:campfire"; ++ case "minecraft:bee_nest" -> "minecraft:beehive"; ++ case "minecraft:suspicious_sand", "minecraft:suspicious_gravel" -> "minecraft:brushable_block"; ++ default -> block; ++ }; ++ } ++ + // important: leadingSlash should not just be the result of a startsWith on command, + // it should reflect whether the command use is in a place that will skip a leading slash when parsing + public String upgradeCommandArguments(final String command, final boolean leadingSlash) { @@ -28557,7 +29525,7 @@ index 0000000000000000000000000000000000000000..6f2a30eed4e9741a128b5a171edef6ab + new HolderLookup.Provider() { + + @Override -+ public Stream>> listRegistries() { ++ public Stream>> listRegistryKeys() { + return Stream.of(); + } + @@ -29218,52 +30186,72 @@ index 0000000000000000000000000000000000000000..5a6536377c9c1e1753e930ff2a6bb98e + return correct.equals(value) ? null : correct; + } +} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java -index 49160a30b8e19e5c5ada811fbcae2a05959524f3..5fca5dc7cdfa976bcc58dfcf0d14abb78a931475 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java -@@ -25,13 +25,21 @@ public final class ChunkSystemConverters { - public static CompoundTag convertPoiCompoundTag(final CompoundTag data, final ServerLevel world) { - final int dataVersion = getDataVersion(data, DEFAULT_POI_DATA_VERSION); - -- return DataFixTypes.POI_CHUNK.update(world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); -+ // Paper start - dataconverter -+ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( -+ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.POI_CHUNK, data, dataVersion, getCurrentVersion() -+ ); -+ // Paper end - dataconverter - } - - public static CompoundTag convertEntityChunkCompoundTag(final CompoundTag data, final ServerLevel world) { - final int dataVersion = getDataVersion(data, DEFAULT_ENTITY_CHUNK_DATA_VERSION); - -- return DataFixTypes.ENTITY_CHUNK.update(world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); -+ // Paper start - dataconverter -+ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( -+ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ENTITY_CHUNK, data, dataVersion, getCurrentVersion() -+ ); -+ // Paper end - dataconverter - } - - private ChunkSystemConverters() {} +diff --git a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java +index ee514a767f69de69d86e1e88d70fe37c4ab84277..be60439c43b887f0143e7713689fd2773066ba73 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java ++++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java +@@ -172,6 +172,43 @@ public final class PaperHooks implements PlatformHooks { + @Override + public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt, + final int fromVersion, final int toVersion) { ++ // Paper start - optimise data conversion ++ if (type == net.minecraft.util.datafix.fixes.References.PLAYER) { ++ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( ++ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.PLAYER, nbt, fromVersion, toVersion ++ ); ++ } ++ if (type == net.minecraft.util.datafix.fixes.References.CHUNK) { ++ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( ++ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.CHUNK, nbt, fromVersion, toVersion ++ ); ++ } ++ if (type == net.minecraft.util.datafix.fixes.References.STRUCTURE) { ++ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( ++ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.STRUCTURE, nbt, fromVersion, toVersion ++ ); ++ } ++ if (type == net.minecraft.util.datafix.fixes.References.POI_CHUNK) { ++ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( ++ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.POI_CHUNK, nbt, fromVersion, toVersion ++ ); ++ } ++ if (type == net.minecraft.util.datafix.fixes.References.ENTITY_CHUNK) { ++ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( ++ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ENTITY_CHUNK, nbt, fromVersion, toVersion ++ ); ++ } ++ if (type == net.minecraft.util.datafix.fixes.References.ITEM_STACK) { ++ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( ++ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ITEM_STACK, nbt, fromVersion, toVersion ++ ); ++ } ++ if (type == net.minecraft.util.datafix.fixes.References.ENTITY || type == net.minecraft.util.datafix.fixes.References.ENTITY_TREE) { ++ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( ++ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ENTITY, nbt, fromVersion, toVersion ++ ); ++ } ++ // Paper end - optimise data conversion + return (CompoundTag)dataFixer.update( + type, new Dynamic<>(NbtOps.INSTANCE, nbt), fromVersion, toVersion + ).getValue(); diff --git a/src/main/java/net/minecraft/data/structures/StructureUpdater.java b/src/main/java/net/minecraft/data/structures/StructureUpdater.java -index 6082d2a4dda21e1b1a9154629aaf0b282b154a42..d8fe611bb4e121dfe96ccd5b8e7949f91eeba023 100644 +index 967cae22838fc23c3404777fd5f9d0b63885eb90..6e7c06008b392846acb84f2b061118a597680627 100644 --- a/src/main/java/net/minecraft/data/structures/StructureUpdater.java +++ b/src/main/java/net/minecraft/data/structures/StructureUpdater.java @@ -27,7 +27,7 @@ public class StructureUpdater implements SnbtToNbt.Filter { - LOGGER.warn("SNBT Too old, do not forget to update: {} < {}: {}", i, 3937, name); + LOGGER.warn("SNBT Too old, do not forget to update: {} < {}: {}", i, 4053, name); } - CompoundTag compoundTag = DataFixTypes.STRUCTURE.updateToCurrentVersion(DataFixers.getDataFixer(), nbt, i); + CompoundTag compoundTag = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.STRUCTURE, nbt, i, net.minecraft.SharedConstants.getCurrentVersion().getDataVersion().getVersion()); // Paper - structureTemplate.load(BuiltInRegistries.BLOCK.asLookup(), compoundTag); + structureTemplate.load(BuiltInRegistries.BLOCK, compoundTag); return structureTemplate.save(new CompoundTag()); } diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -index 0cdc224656a2baa09b7dfbb249b6a96320ac43e0..8c270fee6ecdfbf2bf214428c6f7fcebc2087719 100644 +index 7d5e2e6e96ea9017334dddade54a9dcb37518642..092f7b6bba4e1291f76c2c09155f33803e93eb04 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -@@ -96,7 +96,7 @@ public class ChunkStorage implements AutoCloseable, ca.spottedleaf.moonrise.patc +@@ -86,7 +86,7 @@ public class ChunkStorage implements AutoCloseable { } else { try { // CraftBukkit start @@ -29272,7 +30260,7 @@ index 0cdc224656a2baa09b7dfbb249b6a96320ac43e0..8c270fee6ecdfbf2bf214428c6f7fceb CompoundTag level = nbttagcompound.getCompound("Level"); if (level.getBoolean("TerrainPopulated") && !level.getBoolean("LightPopulated")) { ServerChunkCache cps = (generatoraccess == null) ? null : ((ServerLevel) generatoraccess).getChunkSource(); -@@ -108,7 +108,7 @@ public class ChunkStorage implements AutoCloseable, ca.spottedleaf.moonrise.patc +@@ -98,7 +98,7 @@ public class ChunkStorage implements AutoCloseable { // CraftBukkit end if (i < 1493) { @@ -29281,7 +30269,7 @@ index 0cdc224656a2baa09b7dfbb249b6a96320ac43e0..8c270fee6ecdfbf2bf214428c6f7fceb if (nbttagcompound.getCompound("Level").getBoolean("hasLegacyStructureData")) { LegacyStructureDataHandler persistentstructurelegacy = this.getLegacyStructureHandler(resourcekey, supplier); -@@ -128,7 +128,7 @@ public class ChunkStorage implements AutoCloseable, ca.spottedleaf.moonrise.patc +@@ -116,7 +116,7 @@ public class ChunkStorage implements AutoCloseable { // Spigot end ChunkStorage.injectDatafixingContext(nbttagcompound, resourcekey, optional); @@ -29291,7 +30279,7 @@ index 0cdc224656a2baa09b7dfbb249b6a96320ac43e0..8c270fee6ecdfbf2bf214428c6f7fceb if (stopBelowZero) { nbttagcompound.putString("Status", net.minecraft.core.registries.BuiltInRegistries.CHUNK_STATUS.getKey(ChunkStatus.SPAWN).toString()); diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java -index aafb05c5e63903f5790a6bcb862c8d79588be5a6..c5085ebf4e801837010f3750c5e89576bb0c27a5 100644 +index e0e843f4f69013379ed70cb63d9b4f72163b828b..578d270d5b7efb9ac8f5dde539170f6021e2b786 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java @@ -32,13 +32,30 @@ public class SimpleRegionStorage implements AutoCloseable { @@ -29329,10 +30317,10 @@ index aafb05c5e63903f5790a6bcb862c8d79588be5a6..c5085ebf4e801837010f3750c5e89576 public CompletableFuture synchronize(boolean sync) { diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java b/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java -index 3694c5d2d522216cd2e6e91e502a56a08595ca84..9d282c263151c51cae84f8db00f6b8fa742fbad3 100644 +index 5f354b333a39b873915bedd57b647355ae5bdf56..c3586281c9594769593a6027ea0a78f7c76c0262 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java +++ b/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java -@@ -158,7 +158,7 @@ public class StructureCheck { +@@ -151,7 +151,7 @@ public class StructureCheck { CompoundTag compoundTag2; try { @@ -29355,7 +30343,7 @@ index 05a76f9d18638f10218161450470f07524b723ac..3ab22c384bb8a7772d389977a61d0e28 } diff --git a/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java b/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java -index e69d805701def93466ad7fa94f019ec4610efb47..427ee4d6f12a7abd8da0c65e0b9081b25824df40 100644 +index b5abdd1498a3d19559149c30ba959aa2bcf0246c..0c2e827f4ee53ed2723da60f08a6cf96769bbdfa 100644 --- a/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java +++ b/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java @@ -277,12 +277,21 @@ public class LevelStorageSource { @@ -29396,10 +30384,10 @@ index b54a3741cd3ba615c83c98985cb4b3c4c586ed7a..b148cf247acdd36f856d0495cde4cc5a return nbttagcompound; }); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 6e8838245b0792b15fd9788f2ce11f6503d0e070..9f2ddd47dc0658db2f95ef80543fb9a4d2f94f9f 100644 +index a5a3a0f0460252415c243dfe3019d103b9589c5b..e44ae64ef7cddbcee8c2f37e6606b2257c16bf65 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -511,7 +511,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -490,7 +490,7 @@ public final class CraftMagicNumbers implements UnsafeValues { net.minecraft.nbt.CompoundTag compound = deserializeNbtFromBytes(data); final int dataVersion = compound.getInt("DataVersion"); @@ -29408,7 +30396,7 @@ index 6e8838245b0792b15fd9788f2ce11f6503d0e070..9f2ddd47dc0658db2f95ef80543fb9a4 return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(MinecraftServer.getServer().registryAccess(), compound).orElseThrow()); } -@@ -532,7 +532,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -511,7 +511,7 @@ public final class CraftMagicNumbers implements UnsafeValues { net.minecraft.nbt.CompoundTag compound = deserializeNbtFromBytes(data); int dataVersion = compound.getInt("DataVersion"); diff --git a/patches/unapplied/server/0981-Moonrise-optimisation-patches.patch b/patches/server/0826-Moonrise-optimisation-patches.patch similarity index 94% rename from patches/unapplied/server/0981-Moonrise-optimisation-patches.patch rename to patches/server/0826-Moonrise-optimisation-patches.patch index 0a8d66874e0a..452ab610f1d5 100644 --- a/patches/unapplied/server/0981-Moonrise-optimisation-patches.patch +++ b/patches/server/0826-Moonrise-optimisation-patches.patch @@ -9,17 +9,21 @@ Currently includes: - Collision optimisations - Random block ticking optimisations - Chunk tick iteration optimisations + - Bitstorage optimisations + - Block/Biome Palette read optimisations + - StateHolder (BlockState/FluidState) property access optimisations + - Basic Fluid property read optimisations See https://github.com/Tuinity/Moonrise diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -index da323a1105347d5cf4b946df10ded78a953236f2..0abba00741b39b69a7f167e5d2670f2565c9a752 100644 +index 94bba2b71918d79f54b3e28c35e76098ba0afd8c..b61611351bf23efc1e90bab8a850ebbe6ffdd516 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -@@ -1,6 +1,10 @@ - package ca.spottedleaf.moonrise.common.util; +@@ -2,6 +2,10 @@ package ca.spottedleaf.moonrise.common.util; - import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; + import ca.spottedleaf.concurrentutil.util.Priority; + import ca.spottedleaf.moonrise.common.PlatformHooks; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; +import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk; +import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader; @@ -27,7 +31,7 @@ index da323a1105347d5cf4b946df10ded78a953236f2..0abba00741b39b69a7f167e5d2670f25 import com.mojang.logging.LogUtils; import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.FullChunkStatus; -@@ -17,203 +21,46 @@ import java.util.function.Consumer; +@@ -18,203 +22,46 @@ import java.util.function.Consumer; public final class ChunkSystem { private static final Logger LOGGER = LogUtils.getLogger(); @@ -38,16 +42,16 @@ index da323a1105347d5cf4b946df10ded78a953236f2..0abba00741b39b69a7f167e5d2670f25 - } public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) { - scheduleChunkTask(level, chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); + scheduleChunkTask(level, chunkX, chunkZ, run, Priority.NORMAL); } - public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) { + public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final Priority priority) { - level.chunkSource.mainThreadProcessor.execute(run); + ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkTask(chunkX, chunkZ, run, priority); } 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 ChunkStatus toStatus, final boolean addTicket, final Priority priority, final Consumer onComplete) { - if (gen) { - scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); @@ -75,7 +79,7 @@ index da323a1105347d5cf4b946df10ded78a953236f2..0abba00741b39b69a7f167e5d2670f25 - - 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 onComplete) { + final boolean addTicket, final Priority priority, final Consumer onComplete) { - if (!org.bukkit.Bukkit.isPrimaryThread()) { - scheduleChunkTask(level, chunkX, chunkZ, () -> { - scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); @@ -129,14 +133,14 @@ index da323a1105347d5cf4b946df10ded78a953236f2..0abba00741b39b69a7f167e5d2670f25 - } - loadCallback.accept(result.orElse(null)); - }, (final Runnable r) -> { -- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); +- scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST); - }); + ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); } public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ, final FullChunkStatus toStatus, final boolean addTicket, - final PrioritisedExecutor.Priority priority, final Consumer onComplete) { + final Priority priority, final Consumer onComplete) { - // This method goes unused until the chunk system rewrite - if (toStatus == FullChunkStatus.INACCESSIBLE) { - throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status"); @@ -213,7 +217,7 @@ index da323a1105347d5cf4b946df10ded78a953236f2..0abba00741b39b69a7f167e5d2670f25 - } - loadCallback.accept(result.orElse(null)); - }, (final Runnable r) -> { -- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); +- scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST); - }); + ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); } @@ -239,7 +243,7 @@ index da323a1105347d5cf4b946df10ded78a953236f2..0abba00741b39b69a7f167e5d2670f25 } public static boolean hasAnyChunkHolders(final ServerLevel level) { -@@ -232,52 +79,85 @@ public final class ChunkSystem { +@@ -236,52 +83,85 @@ public final class ChunkSystem { } @@ -342,6 +346,19 @@ index da323a1105347d5cf4b946df10ded78a953236f2..0abba00741b39b69a7f167e5d2670f25 } private ChunkSystem() {} +diff --git a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java +index be60439c43b887f0143e7713689fd2773066ba73..dc17aa5a0937c13d431e41779f241f2e81b11656 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java ++++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java +@@ -236,7 +236,7 @@ public final class PaperHooks implements PlatformHooks { + + @Override + public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) { +- net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities()); ++ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities(), chunk.getPos()); // Paper - rewrite chunk system - add ChunkPos param + } + + @Override diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java new file mode 100644 index 0000000000000000000000000000000000000000..aef4fc0d3c272febe675d1ac846b88e58b4e7533 @@ -4719,10 +4736,10 @@ index 0000000000000000000000000000000000000000..fd35e4db0c8fec8f86b8743bcc2b15ed +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java new file mode 100644 -index 0000000000000000000000000000000000000000..3f5edb756beb9c31b6f591a24b778d6ac2b0bf51 +index 0000000000000000000000000000000000000000..fb87d7ece6ebccfd0ffd2f1a609b45a0d2461d9e --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java -@@ -0,0 +1,21 @@ +@@ -0,0 +1,17 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.storage; + +import com.mojang.serialization.Dynamic; @@ -4735,10 +4752,6 @@ index 0000000000000000000000000000000000000000..3f5edb756beb9c31b6f591a24b778d6a + +public interface ChunkSystemSectionStorage { + -+ public CompoundTag moonrise$read(final int chunkX, final int chunkZ) throws IOException; -+ -+ public void moonrise$write(final int chunkX, final int chunkZ, final CompoundTag data) throws IOException; -+ + public RegionFileStorage moonrise$getRegionStorage(); + + public void moonrise$close() throws IOException; @@ -22216,10 +22229,10 @@ index 0000000000000000000000000000000000000000..85950a1aa732ab8c01ad28bec9e0de14 + } +} diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 450a1cc8f1624dce2daf52210d017e0732b1bdf7..a9dd0e5216e95afd98fd2200d110e2cc0b1b0dca 100644 +index b3f3408a986ae513c06e3b16b82e1c80d4604cd2..9bd509915b391e9d382fe47798e2c345b6e59a9a 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -31,6 +31,45 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -30,6 +30,45 @@ public class GlobalConfiguration extends ConfigurationPart { public static GlobalConfiguration get() { return instance; } @@ -22265,7 +22278,7 @@ index 450a1cc8f1624dce2daf52210d017e0732b1bdf7..a9dd0e5216e95afd98fd2200d110e2cc static void set(GlobalConfiguration instance) { GlobalConfiguration.instance = instance; } -@@ -146,21 +185,6 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -145,21 +184,6 @@ public class GlobalConfiguration extends ConfigurationPart { public int incomingPacketThreshold = 300; } @@ -22287,7 +22300,7 @@ index 450a1cc8f1624dce2daf52210d017e0732b1bdf7..a9dd0e5216e95afd98fd2200d110e2cc public UnsupportedSettings unsupportedSettings; public class UnsupportedSettings extends ConfigurationPart { -@@ -219,7 +243,7 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -218,7 +242,7 @@ public class GlobalConfiguration extends ConfigurationPart { @PostProcess private void postProcess() { @@ -22313,10 +22326,10 @@ index 0000000000000000000000000000000000000000..8424cf9d4617b4732d44cc460d25b044 + +} diff --git a/src/main/java/net/minecraft/core/Direction.java b/src/main/java/net/minecraft/core/Direction.java -index 03c45ee77276462818a6f774b5945b25924aa3f0..f15dd2ccb99ade10ac1e49b63e6f4080bd39b3c9 100644 +index 3fde5abde736b2c19d8819d9aec0397a0245ccd1..6548302d4983bf48cc6bc2b7f4833dc76b59fa5e 100644 --- a/src/main/java/net/minecraft/core/Direction.java +++ b/src/main/java/net/minecraft/core/Direction.java -@@ -27,7 +27,7 @@ import org.joml.Quaternionf; +@@ -28,7 +28,7 @@ import org.joml.Quaternionf; import org.joml.Vector3f; import org.joml.Vector4f; @@ -22325,7 +22338,7 @@ index 03c45ee77276462818a6f774b5945b25924aa3f0..f15dd2ccb99ade10ac1e49b63e6f4080 DOWN(0, 1, -1, "down", Direction.AxisDirection.NEGATIVE, Direction.Axis.Y, new Vec3i(0, -1, 0)), UP(1, 0, -1, "up", Direction.AxisDirection.POSITIVE, Direction.Axis.Y, new Vec3i(0, 1, 0)), NORTH(2, 3, 2, "north", Direction.AxisDirection.NEGATIVE, Direction.Axis.Z, new Vec3i(0, 0, -1)), -@@ -60,6 +60,46 @@ public enum Direction implements StringRepresentable { +@@ -62,6 +62,46 @@ public enum Direction implements StringRepresentable { private final int adjY; private final int adjZ; // Paper end - Perf: Inline shift direction fields @@ -22372,7 +22385,7 @@ index 03c45ee77276462818a6f774b5945b25924aa3f0..f15dd2ccb99ade10ac1e49b63e6f4080 private Direction( final int id, -@@ -134,14 +174,13 @@ public enum Direction implements StringRepresentable { +@@ -147,14 +187,13 @@ public enum Direction implements StringRepresentable { } public Quaternionf getRotation() { @@ -22394,7 +22407,7 @@ index 03c45ee77276462818a6f774b5945b25924aa3f0..f15dd2ccb99ade10ac1e49b63e6f4080 } public int get3DDataValue() { -@@ -165,7 +204,7 @@ public enum Direction implements StringRepresentable { +@@ -178,7 +217,7 @@ public enum Direction implements StringRepresentable { } public Direction getOpposite() { @@ -22403,7 +22416,7 @@ index 03c45ee77276462818a6f774b5945b25924aa3f0..f15dd2ccb99ade10ac1e49b63e6f4080 } public Direction getClockWise(Direction.Axis axis) { -@@ -551,4 +590,17 @@ public enum Direction implements StringRepresentable { +@@ -600,4 +639,17 @@ public enum Direction implements StringRepresentable { return this.faces.length; } } @@ -22422,7 +22435,7 @@ index 03c45ee77276462818a6f774b5945b25924aa3f0..f15dd2ccb99ade10ac1e49b63e6f4080 + // Paper end - optimise collisions } diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index c33f85b570f159ab465b5a10a8044a81f2797f43..244a19ecd0234fa1d7a6ecfea20751595688605d 100644 +index fc6ce3485dc890f5105a37fe3e344a1460867556..e114e687f2f4503546687fd6792226a643af8793 100644 --- a/src/main/java/net/minecraft/server/Main.java +++ b/src/main/java/net/minecraft/server/Main.java @@ -320,6 +320,7 @@ public class Main { @@ -22434,19 +22447,19 @@ index c33f85b570f159ab465b5a10a8044a81f2797f43..244a19ecd0234fa1d7a6ecfea2075159 DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, worldLoader.get(), thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), services, LoggerChunkProgressListener::createFromGameruleRadius); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index a093f29a0b75b5a9e2db2238698d2f3f4ac14ed1..999e9c8f842423e6f1a3e80902e9d076e01f6694 100644 +index 53c9be615a0f2939cd989e24e304e81e6e27f39d..7c388e230c4a88edf6212dd8990e8238d3265ebf 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -198,7 +198,7 @@ import org.bukkit.event.server.ServerLoadEvent; +@@ -205,7 +205,7 @@ import org.bukkit.event.server.ServerLoadEvent; import co.aikar.timings.MinecraftTimings; // Paper --public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource, AutoCloseable { -+public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource, AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer { // Paper - rewrite chunk system +-public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource { ++public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource, ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer { // Paper - rewrite chunk system private static MinecraftServer SERVER; // Paper public static final Logger LOGGER = LogUtils.getLogger(); -@@ -321,7 +321,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); @@ -22455,7 +22468,7 @@ index a093f29a0b75b5a9e2db2238698d2f3f4ac14ed1..999e9c8f842423e6f1a3e80902e9d076 ((MinecraftServer) atomicreference.get()).runServer(); }, "Server thread"); -@@ -340,6 +340,77 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { - return false; - } : this::haveTime); -+ // Paper start - rewrite chunk system -+ final Throwable crash = this.chunkSystemCrash; -+ if (crash != null) { -+ this.chunkSystemCrash = null; -+ throw new RuntimeException("Chunk system crash propagated to tick()", crash); -+ } -+ // Paper end - rewrite chunk system - this.profiler.popPush("nextTickWait"); - this.mayHaveDelayedTasks = true; - this.delayedTasksMaxNextTickTimeNanos = Math.max(Util.getNanos() + i, this.nextTickTimeNanos); -@@ -1390,6 +1462,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { + return false; + } : this::haveTime); ++ // Paper start - rewrite chunk system ++ final Throwable crash = this.chunkSystemCrash; ++ if (crash != null) { ++ this.chunkSystemCrash = null; ++ throw new RuntimeException("Chunk system crash propagated to tick()", crash); ++ } ++ // Paper end - rewrite chunk system + this.tickFrame.end(); + gameprofilerfiller.popPush("nextTickWait"); + this.mayHaveDelayedTasks = true; +@@ -1428,6 +1500,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -- for (final Entity entity : level.getEntities().getAll()) { -+ for (final Entity entity : level.moonrise$getEntityLookup().getAllCopy()) { // Paper - rewrite chunk system - if (entity.isRemoved()) { - continue; - } -@@ -2653,6 +2726,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> getTickingChunkFuture() { @@ -22911,11 +22915,12 @@ index 43513325b7052d388a63d63bd3a4edff48cf23c2..4db96543e2072e47040bb25a9d97ea6a } public boolean isReadyForSaving() { -- return this.getGenerationRefCount() == 0 && this.saveSync.isDone(); +- return this.saveSync.isDone(); + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } - private void addSaveDependency(CompletableFuture savingFuture) { + @Override + protected void addSaveDependency(CompletableFuture savingFuture) { - if (this.saveSync.isDone()) { - this.saveSync = savingFuture; - } else { @@ -22927,22 +22932,16 @@ index 43513325b7052d388a63d63bd3a4edff48cf23c2..4db96543e2072e47040bb25a9d97ea6a } - public void blockChanged(BlockPos pos) { -- LevelChunk chunk = this.getTickingChunk(); -+ LevelChunk chunk = this.playersSentChunkTo.size() == 0 ? null : this.getChunkToSend(); // Paper - rewrite chunk system - - if (chunk != null) { - int i = this.levelHeightAccessor.getSectionIndex(pos.getY()); -@@ -165,7 +245,7 @@ public class ChunkHolder extends GenerationChunkHolder { - - if (ichunkaccess != null) { - ichunkaccess.setUnsaved(true); +@@ -172,7 +252,7 @@ public class ChunkHolder extends GenerationChunkHolder { + return false; + } else { + ichunkaccess.markUnsaved(); - LevelChunk chunk = this.getTickingChunk(); + LevelChunk chunk = this.getChunkToSend(); // Paper - rewrite chunk system - if (chunk != null) { - int j = this.lightEngine.getMinLightSection(); -@@ -191,7 +271,7 @@ public class ChunkHolder extends GenerationChunkHolder { + if (chunk == null) { + return false; +@@ -207,7 +287,7 @@ public class ChunkHolder extends GenerationChunkHolder { List list; if (!this.skyChangedLightSectionFilter.isEmpty() || !this.blockChangedLightSectionFilter.isEmpty()) { @@ -22951,7 +22950,7 @@ index 43513325b7052d388a63d63bd3a4edff48cf23c2..4db96543e2072e47040bb25a9d97ea6a if (!list.isEmpty()) { ClientboundLightUpdatePacket packetplayoutlightupdate = new ClientboundLightUpdatePacket(chunk.getPos(), this.lightEngine, this.skyChangedLightSectionFilter, this.blockChangedLightSectionFilter); -@@ -203,7 +283,7 @@ public class ChunkHolder extends GenerationChunkHolder { +@@ -219,7 +299,7 @@ public class ChunkHolder extends GenerationChunkHolder { } if (this.hasChangedSections) { @@ -22960,7 +22959,7 @@ index 43513325b7052d388a63d63bd3a4edff48cf23c2..4db96543e2072e47040bb25a9d97ea6a for (int i = 0; i < this.changedBlocksPerSection.length; ++i) { ShortSet shortset = this.changedBlocksPerSection[i]; -@@ -269,201 +349,40 @@ public class ChunkHolder extends GenerationChunkHolder { +@@ -285,201 +365,48 @@ public class ChunkHolder extends GenerationChunkHolder { @Override public int getTicketLevel() { @@ -23006,10 +23005,10 @@ index 43513325b7052d388a63d63bd3a4edff48cf23c2..4db96543e2072e47040bb25a9d97ea6a + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } -- // CraftBukkit start -- // ChunkUnloadEvent: Called before the chunk is unloaded: isChunkLoaded is still true and chunk can still be modified by plugins. -- // SPIGOT-7780: Moved out of updateFutures to call all chunk unload events before calling updateHighestAllowedStatus for all chunks -- protected void callEventIfUnloading(ChunkMap playerchunkmap) { + // CraftBukkit start + // ChunkUnloadEvent: Called before the chunk is unloaded: isChunkLoaded is still true and chunk can still be modified by plugins. + // SPIGOT-7780: Moved out of updateFutures to call all chunk unload events before calling updateHighestAllowedStatus for all chunks + protected void callEventIfUnloading(ChunkMap playerchunkmap) { - FullChunkStatus oldFullChunkStatus = ChunkLevel.fullStatus(this.oldTicketLevel); - FullChunkStatus newFullChunkStatus = ChunkLevel.fullStatus(this.ticketLevel); - boolean oldIsFull = oldFullChunkStatus.isOrAfter(FullChunkStatus.FULL); @@ -23022,7 +23021,7 @@ index 43513325b7052d388a63d63bd3a4edff48cf23c2..4db96543e2072e47040bb25a9d97ea6a - // 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. -- chunk.setUnsaved(true); +- chunk.markUnsaved(); - chunk.unloadCallback(); - }); - } @@ -23035,9 +23034,10 @@ index 43513325b7052d388a63d63bd3a4edff48cf23c2..4db96543e2072e47040bb25a9d97ea6a - // Run callback right away if the future was already done - playerchunkmap.callbackExecutor.run(); - } -- } -- // CraftBukkit end -- ++ throw new UnsupportedOperationException(); // Paper - rewrite chunk system + } + // CraftBukkit end + protected void updateFutures(ChunkMap chunkLoadingManager, Executor executor) { - FullChunkStatus fullchunkstatus = ChunkLevel.fullStatus(this.oldTicketLevel); - FullChunkStatus fullchunkstatus1 = ChunkLevel.fullStatus(this.ticketLevel); @@ -23189,10 +23189,10 @@ index d9ad32acdf46a43a649334a3b736aeb7b3af21d1..fae17a075d7efaf24d916877dd5968eb public static final int RADIUS_AROUND_FULL_CHUNK = FULL_CHUNK_STEP.accumulatedDependencies().getRadius(); public static final int MAX_LEVEL = 33 + RADIUS_AROUND_FULL_CHUNK; diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6d23b639c 100644 +index ec19eb88705a07db45f1a3541571fb7f43efb5a9..60adb0caf3d6f03a57fc55303852070107f1736e 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -122,10 +122,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -125,10 +125,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider public static final int MIN_VIEW_DISTANCE = 2; public static final int MAX_VIEW_DISTANCE = 32; public static final int FORCED_TICKET_LEVEL = ChunkLevel.byStatus(FullChunkStatus.ENTITY_TICKING); @@ -23204,13 +23204,12 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 public final ServerLevel level; private final ThreadedLevelLightEngine lightEngine; private final BlockableEventLoop mainThreadExecutor; -@@ -135,21 +132,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -138,22 +135,18 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider private final PoiManager poiManager; public final LongSet toDrop; private boolean modified; -- private final ChunkTaskPriorityQueueSorter queueSorter; -- private final ProcessorHandle> worldgenMailbox; -- private final ProcessorHandle> mainThreadMailbox; +- private final ChunkTaskDispatcher worldgenTaskDispatcher; +- private final ChunkTaskDispatcher lightTaskDispatcher; + // Paper - rewrite chunk system public final ChunkProgressListener progressListener; private final ChunkStatusUpdateListener chunkStatusListener; @@ -23221,8 +23220,10 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 private final PlayerMap playerMap; public final Int2ObjectMap entityMap; private final Long2ByteMap chunkTypeCache; - private final Long2LongMap chunkSaveCooldowns; +- private final Long2LongMap nextChunkSaveTime; +- private final LongSet chunksToEagerlySave; - private final Queue unloadQueue; +- private final AtomicInteger activeChunkWrites; + // Paper - rewrite chunk system public int serverViewDistance; - private final WorldGenContext worldGenContext; @@ -23230,7 +23231,7 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback() public final CallbackExecutor callbackExecutor = new CallbackExecutor(); -@@ -174,22 +169,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -178,24 +171,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper start public final ChunkHolder getUnloadingChunkHolder(int chunkX, int chunkZ) { @@ -23250,32 +23251,32 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 this.playerMap = new PlayerMap(); this.entityMap = new Int2ObjectOpenHashMap(); this.chunkTypeCache = new Long2ByteOpenHashMap(); - this.chunkSaveCooldowns = new Long2LongOpenHashMap(); +- this.nextChunkSaveTime = new Long2LongOpenHashMap(); +- this.chunksToEagerlySave = new LongLinkedOpenHashSet(); - this.unloadQueue = Queues.newConcurrentLinkedQueue(); +- this.activeChunkWrites = new AtomicInteger(); + // Paper - rewrite chunk system Path path = session.getDimensionPath(world.dimension()); this.storageName = path.getFileName().toString(); -@@ -220,15 +213,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -223,14 +211,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.chunkStatusListener = chunkStatusChangeListener; - ProcessorMailbox threadedmailbox1 = ProcessorMailbox.create(executor, "light"); + ConsecutiveExecutor consecutiveexecutor1 = new ConsecutiveExecutor(executor, "light"); -- this.queueSorter = new ChunkTaskPriorityQueueSorter(ImmutableList.of(threadedmailbox, mailbox, threadedmailbox1), executor, Integer.MAX_VALUE); -- this.worldgenMailbox = this.queueSorter.getProcessor(threadedmailbox, false); -- this.mainThreadMailbox = this.queueSorter.getProcessor(mailbox, false); -- this.lightEngine = new ThreadedLevelLightEngine(chunkProvider, this, this.level.dimensionType().hasSkyLight(), threadedmailbox1, this.queueSorter.getProcessor(threadedmailbox1, false)); -+ // Paper - rewrite chunk system -+ this.lightEngine = new ThreadedLevelLightEngine(chunkProvider, this, this.level.dimensionType().hasSkyLight(), threadedmailbox1, null); // Paper - rewrite chunk system +- this.worldgenTaskDispatcher = new ChunkTaskDispatcher(consecutiveexecutor, executor); +- this.lightTaskDispatcher = new ChunkTaskDispatcher(consecutiveexecutor1, executor); +- this.lightEngine = new ThreadedLevelLightEngine(chunkProvider, this, this.level.dimensionType().hasSkyLight(), consecutiveexecutor1, this.lightTaskDispatcher); ++ this.lightEngine = new ThreadedLevelLightEngine(chunkProvider, this, this.level.dimensionType().hasSkyLight(), consecutiveexecutor1, null); // Paper - rewrite chunk system this.distanceManager = new ChunkMap.ChunkDistanceManager(executor, mainThreadExecutor); this.overworldDataStorage = persistentStateManagerFactory; this.poiManager = new PoiManager(new RegionStorageInfo(session.getLevelId(), world.dimension(), "poi"), path.resolve("poi"), dataFixer, dsync, iregistrycustom, world.getServer(), world); this.setServerViewDistance(viewDistance); -- this.worldGenContext = new WorldGenContext(world, chunkGenerator, structureTemplateManager, this.lightEngine, this.mainThreadMailbox); -+ this.worldGenContext = new WorldGenContext(world, chunkGenerator, structureTemplateManager, this.lightEngine, null); // Paper - rewrite chunk system +- this.worldGenContext = new WorldGenContext(world, chunkGenerator, structureTemplateManager, this.lightEngine, mainThreadExecutor, this::setChunkUnsaved); ++ this.worldGenContext = new WorldGenContext(world, chunkGenerator, structureTemplateManager, this.lightEngine, null, this::setChunkUnsaved); // Paper - rewrite chunk system } - // Paper start -@@ -259,23 +250,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + private void setChunkUnsaved(ChunkPos pos) { +@@ -265,23 +251,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } boolean isChunkTracked(ServerPlayer player, int chunkX, int chunkZ) { @@ -23301,7 +23302,7 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 } protected ThreadedLevelLightEngine getLightEngine() { -@@ -284,20 +263,22 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -290,20 +264,22 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @Nullable protected ChunkHolder getUpdatingChunkIfPresent(long pos) { @@ -23331,7 +23332,7 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 } public String getChunkDebugData(ChunkPos chunkPos) { -@@ -326,55 +307,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -332,56 +308,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } private CompletableFuture>> getChunkRangeFuture(ChunkHolder centerChunk, int margin, IntFunction distanceToStatus) { @@ -23342,27 +23343,28 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 - return chunkresult.map(List::of); - }); - } else { -- List>> list = new ArrayList(); +- int j = Mth.square(margin * 2 + 1); +- List>> list = new ArrayList(j); - ChunkPos chunkcoordintpair = centerChunk.getPos(); - -- for (int j = -margin; j <= margin; ++j) { -- for (int k = -margin; k <= margin; ++k) { -- int l = Math.max(Math.abs(k), Math.abs(j)); -- long i1 = ChunkPos.asLong(chunkcoordintpair.x + k, chunkcoordintpair.z + j); -- ChunkHolder playerchunk1 = this.getUpdatingChunkIfPresent(i1); +- for (int k = -margin; k <= margin; ++k) { +- for (int l = -margin; l <= margin; ++l) { +- int i1 = Math.max(Math.abs(l), Math.abs(k)); +- long j1 = ChunkPos.asLong(chunkcoordintpair.x + l, chunkcoordintpair.z + k); +- ChunkHolder playerchunk1 = this.getUpdatingChunkIfPresent(j1); - - if (playerchunk1 == null) { - return ChunkMap.UNLOADED_CHUNK_LIST_FUTURE; - } - -- ChunkStatus chunkstatus1 = (ChunkStatus) distanceToStatus.apply(l); +- ChunkStatus chunkstatus1 = (ChunkStatus) distanceToStatus.apply(i1); - - list.add(playerchunk1.scheduleChunkGenerationTask(chunkstatus1, this)); - } - } - - return Util.sequence(list).thenApply((list1) -> { -- List list2 = Lists.newArrayList(); +- List list2 = new ArrayList(list1.size()); - Iterator iterator = list1.iterator(); - - while (iterator.hasNext()) { @@ -23388,17 +23390,17 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 } public ReportedException debugFuturesAndCreateReportedException(IllegalStateException exception, String details) { -@@ -404,90 +337,23 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -411,49 +338,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public CompletableFuture> prepareEntityTickingChunk(ChunkHolder holder) { - return this.getChunkRangeFuture(holder, 2, (i) -> { - return ChunkStatus.FULL; -- }).thenApplyAsync((chunkresult) -> { +- }).thenApply((chunkresult) -> { - return chunkresult.map((list) -> { - return (LevelChunk) list.get(list.size() / 2); - }); -- }, this.mainThreadExecutor); +- }); + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } @@ -23424,7 +23426,7 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 - if (holder != null) { - holder.setTicketLevel(level); - } else { -- holder = new ChunkHolder(new ChunkPos(pos), level, this.level, this.lightEngine, this.queueSorter, this); +- holder = new ChunkHolder(new ChunkPos(pos), level, this.level, this.lightEngine, this::onLevelChange, this); - // Paper start - ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderCreate(this.level, holder); - // Paper end @@ -23439,16 +23441,20 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } + private void onLevelChange(ChunkPos pos, IntSupplier levelGetter, int targetLevel, IntConsumer levelSetter) { +@@ -463,52 +353,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + @Override public void close() throws IOException { - try { -- this.queueSorter.close(); +- this.worldgenTaskDispatcher.close(); +- this.lightTaskDispatcher.close(); - this.poiManager.close(); - } finally { - super.close(); - } -- + throw new UnsupportedOperationException("Use ServerChunkCache#close"); // Paper - rewrite chunk system + } protected void saveAllChunks(boolean flush) { @@ -23471,103 +23477,119 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 - }); - } while (mutableboolean.isTrue()); - +- this.poiManager.flushAll(); - this.processUnloads(() -> { - return true; - }); - this.flushWorker(); - } else { -- ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).forEach(this::saveChunkIfNeeded); -- } +- this.nextChunkSaveTime.clear(); +- long i = Util.getMillis(); +- Iterator objectiterator = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper - +- while (objectiterator.hasNext()) { +- ChunkHolder playerchunk = (ChunkHolder) objectiterator.next(); +- +- this.saveChunkIfNeeded(playerchunk, i); +- } +- } ++ // Paper start - rewrite chunk system + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.saveAllChunks( + flush, false, false + ); ++ // Paper end - rewrite chunk system + } - protected void tick(BooleanSupplier shouldKeepTicking) { -@@ -504,133 +370,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -526,143 +380,29 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public boolean hasWork() { -- return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || ca.spottedleaf.moonrise.common.util.ChunkSystem.hasAnyChunkHolders(this.level) || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); // Paper +- return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || ca.spottedleaf.moonrise.common.util.ChunkSystem.hasAnyChunkHolders(this.level) || !this.updatingChunkMap.isEmpty() || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.worldgenTaskDispatcher.hasWork() || this.lightTaskDispatcher.hasWork() || this.distanceManager.hasTickets(); + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } private void processUnloads(BooleanSupplier shouldKeepTicking) { -- LongIterator longiterator = this.toDrop.iterator(); -- int i = 0; -- -- while (longiterator.hasNext() && (shouldKeepTicking.getAsBoolean() || i < 200 || this.toDrop.size() > 2000)) { -- long j = longiterator.nextLong(); -- ChunkHolder playerchunk = (ChunkHolder) this.updatingChunkMap.get(j); +- for (LongIterator longiterator = this.toDrop.iterator(); longiterator.hasNext(); longiterator.remove()) { +- long i = longiterator.nextLong(); +- ChunkHolder playerchunk = (ChunkHolder) this.updatingChunkMap.get(i); - - if (playerchunk != null) { -- if (playerchunk.getGenerationRefCount() != 0) { -- continue; -- } -- -- this.updatingChunkMap.remove(j); -- this.pendingUnloads.put(j, playerchunk); +- this.updatingChunkMap.remove(i); +- this.pendingUnloads.put(i, playerchunk); - this.modified = true; -- ++i; -- this.scheduleUnload(j, playerchunk); +- this.scheduleUnload(i, playerchunk); - } -- -- longiterator.remove(); - } - -- int k = Math.max(0, this.unloadQueue.size() - 2000); +- int j = Math.max(0, this.unloadQueue.size() - 2000); - - Runnable runnable; - -- while ((shouldKeepTicking.getAsBoolean() || k > 0) && (runnable = (Runnable) this.unloadQueue.poll()) != null) { -- --k; +- while ((j > 0 || shouldKeepTicking.getAsBoolean()) && (runnable = (Runnable) this.unloadQueue.poll()) != null) { +- --j; - runnable.run(); - } - -- int l = 0; -- Iterator objectiterator = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper +- this.saveChunksEagerly(shouldKeepTicking); ++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.processUnloads(); // Paper - rewrite chunk system ++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.autoSave(); // Paper - rewrite chunk system + } + + private void saveChunksEagerly(BooleanSupplier shouldKeepTicking) { +- long i = Util.getMillis(); +- int j = 0; +- LongIterator longiterator = this.chunksToEagerlySave.iterator(); +- +- while (j < 20 && this.activeChunkWrites.get() < 128 && shouldKeepTicking.getAsBoolean() && longiterator.hasNext()) { +- long k = longiterator.nextLong(); +- ChunkHolder playerchunk = (ChunkHolder) this.visibleChunkMap.get(k); +- ChunkAccess ichunkaccess = playerchunk != null ? playerchunk.getLatestChunk() : null; - -- while (l < 20 && shouldKeepTicking.getAsBoolean() && objectiterator.hasNext()) { -- if (this.saveChunkIfNeeded((ChunkHolder) objectiterator.next())) { -- ++l; +- if (ichunkaccess != null && ichunkaccess.isUnsaved()) { +- if (this.saveChunkIfNeeded(playerchunk, i)) { +- ++j; +- longiterator.remove(); +- } +- } else { +- longiterator.remove(); - } - } -+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.processUnloads(); // Paper - rewrite chunk system -+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.autoSave(); // Paper - rewrite chunk system ++ throw new UnsupportedOperationException(); // Paper - rewrite chunk system } - private void scheduleUnload(long pos, ChunkHolder holder) { -- CompletableFuture completablefuture = holder.getSaveSyncFuture(); + private void scheduleUnload(long pos, ChunkHolder chunk) { +- CompletableFuture completablefuture = chunk.getSaveSyncFuture(); - Runnable runnable = () -> { -- if (!holder.isReadyForSaving()) { -- this.scheduleUnload(pos, holder); -- } else { -- ChunkAccess ichunkaccess = holder.getLatestChunk(); +- CompletableFuture completablefuture1 = chunk.getSaveSyncFuture(); - +- if (completablefuture1 != completablefuture) { +- this.scheduleUnload(pos, chunk); +- } else { +- ChunkAccess ichunkaccess = chunk.getLatestChunk(); - // Paper start - boolean removed; -- if ((removed = this.pendingUnloads.remove(pos, holder)) && ichunkaccess != null) { -- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, holder); +- if ((removed = this.pendingUnloads.remove(pos, chunk)) && ichunkaccess != null) { +- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, chunk); - // Paper end - LevelChunk chunk; - - if (ichunkaccess instanceof LevelChunk) { -- chunk = (LevelChunk) ichunkaccess; -- chunk.setLoaded(false); +- chunk1 = (LevelChunk) ichunkaccess; +- chunk1.setLoaded(false); - } - - this.save(ichunkaccess); - if (ichunkaccess instanceof LevelChunk) { -- chunk = (LevelChunk) ichunkaccess; -- this.level.unload(chunk); +- chunk1 = (LevelChunk) ichunkaccess; +- this.level.unload(chunk1); - } - - this.lightEngine.updateChunkStatus(ichunkaccess.getPos()); - this.lightEngine.tryScheduleUpdate(); - this.progressListener.onStatusChange(ichunkaccess.getPos(), (ChunkStatus) null); -- this.chunkSaveCooldowns.remove(ichunkaccess.getPos().toLong()); +- this.nextChunkSaveTime.remove(ichunkaccess.getPos().toLong()); - } else if (removed) { // Paper start - ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, holder); - } // Paper end @@ -23579,7 +23601,7 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 - Objects.requireNonNull(this.unloadQueue); - completablefuture.thenRunAsync(runnable, queue::add).whenComplete((ovoid, throwable) -> { - if (throwable != null) { -- ChunkMap.LOGGER.error("Failed to save chunk {}", holder.getPos(), throwable); +- ChunkMap.LOGGER.error("Failed to save chunk {}", chunk.getPos(), throwable); - } - - }); @@ -23598,20 +23620,25 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 } private CompletableFuture scheduleChunkLoad(ChunkPos pos) { -- return this.readChunk(pos).thenApply((optional) -> { -- return optional.filter((nbttagcompound) -> { -- boolean flag = ChunkMap.isChunkDataValid(nbttagcompound); +- CompletableFuture> completablefuture = this.readChunk(pos).thenApplyAsync((optional) -> { +- return optional.map((nbttagcompound) -> { +- SerializableChunkData serializablechunkdata = SerializableChunkData.parse(this.level, this.level.registryAccess(), nbttagcompound); - -- if (!flag) { +- if (serializablechunkdata == null) { - ChunkMap.LOGGER.error("Chunk file at {} is missing level data, skipping", pos); - } - -- return flag; +- return serializablechunkdata; - }); +- }, Util.backgroundExecutor().forName("parseChunk")); +- CompletableFuture completablefuture1 = this.poiManager.prefetch(pos); +- +- return completablefuture.thenCombine(completablefuture1, (optional, object) -> { +- return optional; - }).thenApplyAsync((optional) -> { -- this.level.getProfiler().incrementCounter("chunkLoad"); +- Profiler.get().incrementCounter("chunkLoad"); - if (optional.isPresent()) { -- ProtoChunk protochunk = ChunkSerializer.read(this.level, this.poiManager, this.storageInfo(), pos, (CompoundTag) optional.get()); +- ProtoChunk protochunk = ((SerializableChunkData) optional.get()).read(this.level, this.poiManager, this.storageInfo(), pos); - - this.markPosition(pos, protochunk.getPersistedStatus().getChunkType()); - return protochunk; @@ -23624,8 +23651,8 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } - private static boolean isChunkDataValid(CompoundTag nbt) { -@@ -690,137 +448,44 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + private ChunkAccess handleChunkLoadFailure(Throwable throwable, ChunkPos chunkPos) { +@@ -718,139 +458,43 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @Override public GenerationChunkHolder acquireGeneration(long pos) { @@ -23690,16 +23717,22 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } - private void runGenerationTask(ChunkGenerationTask chunkLoader) { -- this.worldgenMailbox.tell(ChunkTaskPriorityQueueSorter.message(chunkLoader.getCenter(), () -> { -- CompletableFuture completablefuture = chunkLoader.runUntilWait(); + private void runGenerationTask(ChunkGenerationTask loader) { +- GenerationChunkHolder generationchunkholder = loader.getCenter(); +- ChunkTaskDispatcher chunktaskdispatcher = this.worldgenTaskDispatcher; +- Runnable runnable = () -> { +- CompletableFuture completablefuture = loader.runUntilWait(); - - if (completablefuture != null) { - completablefuture.thenRun(() -> { -- this.runGenerationTask(chunkLoader); +- this.runGenerationTask(loader); - }); - } -- })); +- }; +- long i = generationchunkholder.getPos().toLong(); +- +- Objects.requireNonNull(generationchunkholder); +- chunktaskdispatcher.submit(runnable, i, generationchunkholder::getQueueLevel); + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } @@ -23716,24 +23749,21 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 - }); - CompletableFuture> completablefuture1 = completablefuture.thenApplyAsync((chunkresult) -> { - return chunkresult.map((list) -> { -- return (LevelChunk) list.get(list.size() / 2); -- }); -- }, (runnable) -> { -- this.mainThreadMailbox.tell(ChunkTaskPriorityQueueSorter.message(holder, runnable)); -- }).thenApplyAsync((chunkresult) -> { -- return chunkresult.ifSuccess((chunk) -> { -- chunk.postProcessGeneration(); +- LevelChunk chunk = (LevelChunk) list.get(list.size() / 2); +- +- chunk.postProcessGeneration(this.level); - this.level.startTickingChunk(chunk); - CompletableFuture completablefuture2 = holder.getSendSyncFuture(); - - if (completablefuture2.isDone()) { -- this.onChunkReadyToSend(chunk); +- this.onChunkReadyToSend(holder, chunk); - } else { - completablefuture2.thenAcceptAsync((object) -> { -- this.onChunkReadyToSend(chunk); +- this.onChunkReadyToSend(holder, chunk); - }, this.mainThreadExecutor); - } - +- return chunk; - }); - }, this.mainThreadExecutor); - @@ -23745,7 +23775,7 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } - private void onChunkReadyToSend(LevelChunk chunk) { + private void onChunkReadyToSend(ChunkHolder chunkHolder, LevelChunk chunk) { - ChunkPos chunkcoordintpair = chunk.getPos(); - Iterator iterator = this.playerMap.getAllPlayers().iterator(); - @@ -23756,44 +23786,44 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 - ChunkMap.markChunkPendingToSend(entityplayer, chunk); - } - } +- +- this.level.getChunkSource().onChunkReadyToSend(chunkHolder); + throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } public CompletableFuture> prepareAccessibleChunk(ChunkHolder holder) { -- return this.getChunkRangeFuture(holder, 1, ChunkLevel::getStatusAroundFullChunk).thenApplyAsync((chunkresult) -> { +- return this.getChunkRangeFuture(holder, 1, ChunkLevel::getStatusAroundFullChunk).thenApply((chunkresult) -> { - return chunkresult.map((list) -> { - return (LevelChunk) list.get(list.size() / 2); - }); -- }, (runnable) -> { -- this.mainThreadMailbox.tell(ChunkTaskPriorityQueueSorter.message(holder, runnable)); - }); + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } public int getTickingGenerated() { -@@ -828,135 +493,84 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -858,143 +502,83 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } - private boolean saveChunkIfNeeded(ChunkHolder chunkHolder) { + private boolean saveChunkIfNeeded(ChunkHolder chunkHolder, long currentTime) { - if (chunkHolder.wasAccessibleSinceLastSave() && chunkHolder.isReadyForSaving()) { - ChunkAccess ichunkaccess = chunkHolder.getLatestChunk(); - - if (!(ichunkaccess instanceof ImposterProtoChunk) && !(ichunkaccess instanceof LevelChunk)) { - return false; +- } else if (!ichunkaccess.isUnsaved()) { +- return false; - } else { -- long i = ichunkaccess.getPos().toLong(); -- long j = this.chunkSaveCooldowns.getOrDefault(i, -1L); -- long k = System.currentTimeMillis(); +- long j = ichunkaccess.getPos().toLong(); +- long k = this.nextChunkSaveTime.getOrDefault(j, -1L); - -- if (k < j) { +- if (currentTime < k) { - return false; - } else { - boolean flag = this.save(ichunkaccess); - - chunkHolder.refreshAccessibility(); - if (flag) { -- this.chunkSaveCooldowns.put(i, k + 10000L); +- this.nextChunkSaveTime.put(j, currentTime + 10000L); - } - - return flag; @@ -23807,10 +23837,9 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 public boolean save(ChunkAccess chunk) { - this.poiManager.flush(chunk.getPos()); -- if (!chunk.isUnsaved()) { +- if (!chunk.tryMarkSaved()) { - return false; - } else { -- chunk.setUnsaved(false); - ChunkPos chunkcoordintpair = chunk.getPos(); - - try { @@ -23826,11 +23855,20 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 - } - } - -- this.level.getProfiler().incrementCounter("chunkSave"); -- CompoundTag nbttagcompound = ChunkSerializer.write(this.level, chunk); +- Profiler.get().incrementCounter("chunkSave"); +- this.activeChunkWrites.incrementAndGet(); +- SerializableChunkData serializablechunkdata = SerializableChunkData.copyOf(this.level, chunk); +- +- Objects.requireNonNull(serializablechunkdata); +- CompletableFuture completablefuture = CompletableFuture.supplyAsync(serializablechunkdata::write, Util.backgroundExecutor()); +- +- Objects.requireNonNull(completablefuture); +- this.write(chunkcoordintpair, completablefuture::join).handle((ovoid, throwable) -> { +- if (throwable != null) { +- this.level.getServer().reportChunkSaveFailure(throwable, this.storageInfo(), chunkcoordintpair); +- } - -- this.write(chunkcoordintpair, nbttagcompound).exceptionally((throwable) -> { -- this.level.getServer().reportChunkSaveFailure(throwable, this.storageInfo(), chunkcoordintpair); +- this.activeChunkWrites.decrementAndGet(); - return null; - }); - this.markPosition(chunkcoordintpair, chunkstatus.getChunkType()); @@ -23863,7 +23901,7 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 - return false; - } - -- ChunkType chunktype = ChunkSerializer.getChunkTypeFromTag(nbttagcompound); +- ChunkType chunktype = SerializableChunkData.getChunkTypeFromTag(nbttagcompound); - - return this.markPosition(pos, chunktype) == 1; - } @@ -23917,8 +23955,8 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 private static void dropChunk(ServerPlayer player, ChunkPos pos) { - player.connection.chunkSender.dropChunk(player, pos); + // Paper - rewrite chunk system - } - ++ } ++ + // Paper start - rewrite chunk system + @Override + public CompletableFuture> read(final ChunkPos pos) { @@ -23954,13 +23992,12 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 + @Override + public void flushWorker() { + ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.flush(); -+ } + } + // Paper end - rewrite chunk system -+ + @Nullable public LevelChunk getChunkToSend(long pos) { - ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos); -@@ -1022,7 +636,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1061,7 +645,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } // CraftBukkit start @@ -23969,7 +24006,7 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 return this.upgradeChunkTag(this.level.getTypeKey(), this.overworldDataStorage, nbttagcompound, this.generator().getTypeNameForDataFixer(), chunkcoordintpair, this.level); // CraftBukkit end } -@@ -1113,19 +727,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1172,19 +756,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.updatePlayerPos(player); if (!flag1) { this.distanceManager.addPlayer(SectionPos.of((EntityAccess) player), player); @@ -23993,7 +24030,7 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 } } -@@ -1137,17 +753,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1196,17 +782,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void move(ServerPlayer player) { @@ -24012,7 +24049,7 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 SectionPos sectionposition = player.getLastSectionPos(); SectionPos sectionposition1 = SectionPos.of((EntityAccess) player); -@@ -1157,6 +763,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1216,6 +792,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider if (flag2 || flag != flag1) { this.updatePlayerPos(player); @@ -24020,7 +24057,7 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 if (!flag) { this.distanceManager.removePlayer(sectionposition, player); } -@@ -1173,70 +780,30 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1232,70 +809,30 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.playerMap.unIgnorePlayer(player); } @@ -24102,7 +24139,7 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 } public void addEntity(Entity entity) { -@@ -1263,6 +830,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1322,6 +859,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider ChunkMap.TrackedEntity playerchunkmap_entitytracker = new ChunkMap.TrackedEntity(entity, i, j, entitytypes.trackDeltas()); this.entityMap.put(entity.getId(), playerchunkmap_entitytracker); @@ -24115,7 +24152,7 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 playerchunkmap_entitytracker.updatePlayers(this.level.players()); if (entity instanceof ServerPlayer) { ServerPlayer entityplayer = (ServerPlayer) entity; -@@ -1303,16 +876,49 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1362,16 +905,49 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider playerchunkmap_entitytracker1.broadcastRemoved(); } @@ -24155,7 +24192,7 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 + continue; + } + ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity)tracker).moonrise$clearPlayers(); -+ } + } + } + // Paper end - optimise entity tracker + @@ -24164,13 +24201,13 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 + if (true) { + this.newTrackerTick(); + return; - } ++ } + // Paper end - optimise entity tracker + // Paper - rewrite chunk system List list = Lists.newArrayList(); List list1 = this.level.players(); -@@ -1419,27 +1025,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1478,27 +1054,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void waitForLightBeforeSending(ChunkPos centerPos, int radius) { @@ -24208,7 +24245,7 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 } @Nullable -@@ -1455,7 +1059,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1514,7 +1088,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } } @@ -24217,7 +24254,7 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 public final ServerEntity serverEntity; final Entity entity; -@@ -1463,6 +1067,84 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1522,6 +1096,84 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider SectionPos lastSectionPos; public final Set seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl @@ -24303,10 +24340,10 @@ index 4c1cf5798209297e1e8a634b63770e917a84a63c..48b8fa3dea0244f9a0f4e0b8850b17a6 this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit this.entity = entity; diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java -index 1e7b440cc2c1bf53210069b38286f67a7b97041b..2d2596f04f5addac38037a14a02c6e0622d0c485 100644 +index f7c2c03749d6be25bf33afd61e1da120770b3432..64da6726634fc223c0e6dcab4d83a6c8997ff196 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java -@@ -36,64 +36,58 @@ import net.minecraft.world.level.ChunkPos; +@@ -34,58 +34,56 @@ import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.chunk.LevelChunk; import org.slf4j.Logger; @@ -24322,10 +24359,8 @@ index 1e7b440cc2c1bf53210069b38286f67a7b97041b..2d2596f04f5addac38037a14a02c6e06 - private final DistanceManager.FixedPlayerDistanceChunkTracker naturalSpawnChunkCounter = new DistanceManager.FixedPlayerDistanceChunkTracker(8); - private final TickingTracker tickingTicketsTracker = new TickingTracker(); - private final DistanceManager.PlayerTicketTracker playerTicketManager = new DistanceManager.PlayerTicketTracker(32); -- final Set chunksToUpdateFutures = Sets.newHashSet(); -- final ChunkTaskPriorityQueueSorter ticketThrottler; -- final ProcessorHandle> ticketThrottlerInput; -- final ProcessorHandle ticketThrottlerReleaser; +- final Set chunksToUpdateFutures = new ReferenceOpenHashSet(); +- final ThrottlingChunkTaskDispatcher ticketDispatcher; - final LongSet ticketsToRelease = new LongOpenHashSet(); - final Executor mainThreadExecutor; + // Paper - rewrite chunk system @@ -24336,13 +24371,9 @@ index 1e7b440cc2c1bf53210069b38286f67a7b97041b..2d2596f04f5addac38037a14a02c6e06 + // Paper - rewrite chunk system protected DistanceManager(Executor workerExecutor, Executor mainThreadExecutor) { - Objects.requireNonNull(mainThreadExecutor); - ProcessorHandle mailbox = ProcessorHandle.of("player ticket throttler", mainThreadExecutor::execute); - ChunkTaskPriorityQueueSorter chunktaskqueuesorter = new ChunkTaskPriorityQueueSorter(ImmutableList.of(mailbox), workerExecutor, 4); + TaskScheduler taskscheduler = TaskScheduler.wrapExecutor("player ticket throttler", mainThreadExecutor); -- this.ticketThrottler = chunktaskqueuesorter; -- this.ticketThrottlerInput = chunktaskqueuesorter.getProcessor(mailbox, true); -- this.ticketThrottlerReleaser = chunktaskqueuesorter.getReleaseProcessor(mailbox); +- this.ticketDispatcher = new ThrottlingChunkTaskDispatcher(taskscheduler, workerExecutor, 4); - this.mainThreadExecutor = mainThreadExecutor; + // Paper - rewrite chunk system } @@ -24405,7 +24436,7 @@ index 1e7b440cc2c1bf53210069b38286f67a7b97041b..2d2596f04f5addac38037a14a02c6e06 } -@@ -110,91 +104,15 @@ public abstract class DistanceManager { +@@ -102,105 +100,15 @@ public abstract class DistanceManager { protected abstract ChunkHolder updateChunkScheduling(long pos, int level, @Nullable ChunkHolder holder, int k); public boolean runAllUpdates(ChunkMap chunkLoadingManager) { @@ -24420,17 +24451,31 @@ index 1e7b440cc2c1bf53210069b38286f67a7b97041b..2d2596f04f5addac38037a14a02c6e06 - } - - if (!this.chunksToUpdateFutures.isEmpty()) { +- Iterator iterator = this.chunksToUpdateFutures.iterator(); +- +- ChunkHolder playerchunk; +- - // CraftBukkit start - SPIGOT-7780: Call chunk unload events before updateHighestAllowedStatus -- this.chunksToUpdateFutures.forEach((playerchunk) -> { +- while (iterator.hasNext()) { +- playerchunk = (ChunkHolder) iterator.next(); - playerchunk.callEventIfUnloading(chunkLoadingManager); -- }); +- } +- +- iterator = this.chunksToUpdateFutures.iterator(); - // CraftBukkit end -- this.chunksToUpdateFutures.forEach((playerchunk) -> { +- +- while (iterator.hasNext()) { +- playerchunk = (ChunkHolder) iterator.next(); - playerchunk.updateHighestAllowedStatus(chunkLoadingManager); -- }); -- this.chunksToUpdateFutures.forEach((playerchunk) -> { +- } +- +- iterator = this.chunksToUpdateFutures.iterator(); +- +- while (iterator.hasNext()) { +- playerchunk = (ChunkHolder) iterator.next(); - playerchunk.updateFutures(chunkLoadingManager, this.mainThreadExecutor); -- }); +- } +- - this.chunksToUpdateFutures.clear(); - return true; - } else { @@ -24443,18 +24488,18 @@ index 1e7b440cc2c1bf53210069b38286f67a7b97041b..2d2596f04f5addac38037a14a02c6e06 - if (this.getTickets(j).stream().anyMatch((ticket) -> { - return ticket.getType() == TicketType.PLAYER; - })) { -- ChunkHolder playerchunk = chunkLoadingManager.getUpdatingChunkIfPresent(j); +- ChunkHolder playerchunk1 = chunkLoadingManager.getUpdatingChunkIfPresent(j); - -- if (playerchunk == null) { +- if (playerchunk1 == null) { - throw new IllegalStateException(); - } - -- CompletableFuture> completablefuture = playerchunk.getEntityTickingChunkFuture(); +- CompletableFuture> completablefuture = playerchunk1.getEntityTickingChunkFuture(); - - completablefuture.thenAccept((chunkresult) -> { - this.mainThreadExecutor.execute(() -> { -- this.ticketThrottlerReleaser.tell(ChunkTaskPriorityQueueSorter.release(() -> { -- }, j, false)); +- this.ticketDispatcher.release(j, () -> { +- }, false); - }); - }); - } @@ -24500,7 +24545,7 @@ index 1e7b440cc2c1bf53210069b38286f67a7b97041b..2d2596f04f5addac38037a14a02c6e06 } public void addTicket(TicketType type, ChunkPos pos, int level, T argument) { -@@ -213,13 +131,7 @@ public abstract class DistanceManager { +@@ -219,13 +127,7 @@ public abstract class DistanceManager { } public boolean addRegionTicketAtDistance(TicketType tickettype, ChunkPos chunkcoordintpair, int i, T t0) { @@ -24515,7 +24560,7 @@ index 1e7b440cc2c1bf53210069b38286f67a7b97041b..2d2596f04f5addac38037a14a02c6e06 } public void removeRegionTicket(TicketType type, ChunkPos pos, int radius, T argument) { -@@ -228,32 +140,21 @@ public abstract class DistanceManager { +@@ -234,32 +136,21 @@ public abstract class DistanceManager { } public boolean removeRegionTicketAtDistance(TicketType tickettype, ChunkPos chunkcoordintpair, int i, T t0) { @@ -24554,7 +24599,7 @@ index 1e7b440cc2c1bf53210069b38286f67a7b97041b..2d2596f04f5addac38037a14a02c6e06 } -@@ -264,9 +165,8 @@ public abstract class DistanceManager { +@@ -270,9 +161,8 @@ public abstract class DistanceManager { ((ObjectSet) this.playersPerChunk.computeIfAbsent(i, (j) -> { return new ObjectOpenHashSet(); })).add(player); @@ -24566,7 +24611,7 @@ index 1e7b440cc2c1bf53210069b38286f67a7b97041b..2d2596f04f5addac38037a14a02c6e06 } public void removePlayer(SectionPos pos, ServerPlayer player) { -@@ -278,151 +178,81 @@ public abstract class DistanceManager { +@@ -284,51 +174,49 @@ 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); @@ -24633,8 +24678,12 @@ index 1e7b440cc2c1bf53210069b38286f67a7b97041b..2d2596f04f5addac38037a14a02c6e06 + return this.spawnChunkTracker.hasObjectsNear(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkX(chunkPos), ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkZ(chunkPos)); // Paper - chunk tick iteration optimisation } + public LongIterator getSpawnCandidateChunks() { +@@ -337,47 +225,17 @@ public abstract class DistanceManager { + } + public String getDebugStatus() { -- return this.ticketThrottler.getDebugStatus(); +- return this.ticketDispatcher.getDebugStatus(); + return "No DistanceManager stats available"; // Paper - rewrite chunk system } @@ -24680,6 +24729,10 @@ index 1e7b440cc2c1bf53210069b38286f67a7b97041b..2d2596f04f5addac38037a14a02c6e06 + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } + public LongSet getTickingChunks() { +@@ -385,59 +243,21 @@ public abstract class DistanceManager { + } + public void removeTicketsOnClosing() { - ImmutableSet> immutableset = ImmutableSet.of(TicketType.UNKNOWN, TicketType.POST_TELEPORT, TicketType.FUTURE_AWAIT); // Paper - add additional tickets to preserve - ObjectIterator>>> objectiterator = this.tickets.long2ObjectEntrySet().fastIterator(); @@ -24741,7 +24794,7 @@ index 1e7b440cc2c1bf53210069b38286f67a7b97041b..2d2596f04f5addac38037a14a02c6e06 private class ChunkTicketTracker extends ChunkTracker { private static final int MAX_LEVEL = ChunkLevel.MAX_LEVEL + 1; -@@ -468,7 +298,7 @@ public abstract class DistanceManager { +@@ -483,7 +303,7 @@ public abstract class DistanceManager { public int runDistanceUpdates(int distance) { return this.runUpdates(distance); } @@ -24750,7 +24803,7 @@ index 1e7b440cc2c1bf53210069b38286f67a7b97041b..2d2596f04f5addac38037a14a02c6e06 private class FixedPlayerDistanceChunkTracker extends ChunkTracker { -@@ -548,6 +378,7 @@ public abstract class DistanceManager { +@@ -563,6 +383,7 @@ public abstract class DistanceManager { } } @@ -24758,7 +24811,7 @@ index 1e7b440cc2c1bf53210069b38286f67a7b97041b..2d2596f04f5addac38037a14a02c6e06 private class PlayerTicketTracker extends DistanceManager.FixedPlayerDistanceChunkTracker { private int viewDistance = 0; -@@ -642,5 +473,5 @@ public abstract class DistanceManager { +@@ -657,5 +478,5 @@ public abstract class DistanceManager { private boolean haveTicketFor(int distance) { return distance <= this.viewDistance; } @@ -24766,10 +24819,10 @@ index 1e7b440cc2c1bf53210069b38286f67a7b97041b..2d2596f04f5addac38037a14a02c6e06 + }*/ // Paper - rewrite chunk system } diff --git a/src/main/java/net/minecraft/server/level/GenerationChunkHolder.java b/src/main/java/net/minecraft/server/level/GenerationChunkHolder.java -index 3dc1daa3c6a04d3ff1a2353773b465fc380994a2..3575782f13a7f3c52e64dc5046803305d5c8ce12 100644 +index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a5fd7489a 100644 --- a/src/main/java/net/minecraft/server/level/GenerationChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/GenerationChunkHolder.java -@@ -27,249 +27,105 @@ public abstract class GenerationChunkHolder { +@@ -27,13 +27,7 @@ public abstract class GenerationChunkHolder { public static final ChunkResult UNLOADED_CHUNK = ChunkResult.error("Unloaded chunk"); public static final CompletableFuture> UNLOADED_CHUNK_FUTURE = CompletableFuture.completedFuture(UNLOADED_CHUNK); protected final ChunkPos pos; @@ -24779,10 +24832,12 @@ index 3dc1daa3c6a04d3ff1a2353773b465fc380994a2..3575782f13a7f3c52e64dc5046803305 - private final AtomicReferenceArray>> futures = new AtomicReferenceArray<>(CHUNK_STATUSES.size()); - private final AtomicReference task = new AtomicReference<>(); - private final AtomicInteger generationRefCount = new AtomicInteger(); +- private volatile CompletableFuture generationSaveSyncFuture = CompletableFuture.completedFuture(null); + // Paper - rewrite chunk system public GenerationChunkHolder(ChunkPos pos) { this.pos = pos; +@@ -43,243 +37,96 @@ public abstract class GenerationChunkHolder { } public CompletableFuture> scheduleChunkGenerationTask(ChunkStatus requestedStatus, ChunkMap chunkLoadingManager) { @@ -24988,24 +25043,29 @@ index 3dc1daa3c6a04d3ff1a2353773b465fc380994a2..3575782f13a7f3c52e64dc5046803305 + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } + protected abstract void addSaveDependency(CompletableFuture savingFuture); + public void increaseGenerationRefCount() { -- this.generationRefCount.incrementAndGet(); +- if (this.generationRefCount.getAndIncrement() == 0) { +- this.generationSaveSyncFuture = new CompletableFuture<>(); +- this.addSaveDependency(this.generationSaveSyncFuture); +- } + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } public void decreaseGenerationRefCount() { +- CompletableFuture completableFuture = this.generationSaveSyncFuture; - int i = this.generationRefCount.decrementAndGet(); +- if (i == 0) { +- completableFuture.complete(null); +- } +- - if (i < 0) { - throw new IllegalStateException("More releases than claims. Count: " + i); - } + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } - public int getGenerationRefCount() { -- return this.generationRefCount.get(); -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - @Nullable public ChunkAccess getChunkIfPresentUnchecked(ChunkStatus requestedStatus) { - CompletableFuture> completableFuture = this.futures.get(requestedStatus.getIndex()); @@ -25050,7 +25110,7 @@ index 3dc1daa3c6a04d3ff1a2353773b465fc380994a2..3575782f13a7f3c52e64dc5046803305 } public ChunkPos getPos() { -@@ -277,7 +133,7 @@ public abstract class GenerationChunkHolder { +@@ -287,7 +134,7 @@ public abstract class GenerationChunkHolder { } public FullChunkStatus getFullStatus() { @@ -25059,7 +25119,7 @@ index 3dc1daa3c6a04d3ff1a2353773b465fc380994a2..3575782f13a7f3c52e64dc5046803305 } public abstract int getTicketLevel(); -@@ -286,26 +142,15 @@ public abstract class GenerationChunkHolder { +@@ -296,26 +143,15 @@ public abstract class GenerationChunkHolder { @VisibleForDebug public List>>> getAllFutures() { @@ -25092,19 +25152,19 @@ index 3dc1daa3c6a04d3ff1a2353773b465fc380994a2..3575782f13a7f3c52e64dc5046803305 } } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9ccb3ffc375298fda4dca97803e65e39df8493eb 100644 +index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815d46bff2e 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -46,7 +46,7 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp - import net.minecraft.world.level.storage.DimensionDataStorage; +@@ -52,7 +52,7 @@ import net.minecraft.world.level.storage.DimensionDataStorage; import net.minecraft.world.level.storage.LevelStorageSource; + import org.slf4j.Logger; -public class ServerChunkCache extends ChunkSource { +public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemServerChunkCache { // Paper - rewrite chunk system - public static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); // Paper - private static final List CHUNK_STATUSES = ChunkStatus.getStatusList(); -@@ -71,6 +71,62 @@ public class ServerChunkCache extends ChunkSource { + private static final Logger LOGGER = LogUtils.getLogger(); + private final DistanceManager distanceManager; +@@ -78,6 +78,62 @@ public class ServerChunkCache extends ChunkSource { private final ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable fullChunks = new ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<>(); long chunkFutureAwaitCounter; // Paper end @@ -25167,7 +25227,7 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9ccb3ffc375298fda4dca97803e65e39 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 persistentStateManagerFactory) { this.level = world; -@@ -97,13 +153,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -109,13 +165,7 @@ public class ServerChunkCache extends ChunkSource { } // CraftBukkit end // Paper start @@ -25182,7 +25242,7 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9ccb3ffc375298fda4dca97803e65e39 @Nullable public ChunkAccess getChunkAtImmediately(int x, int z) { -@@ -174,63 +224,25 @@ public class ServerChunkCache extends ChunkSource { +@@ -186,63 +236,25 @@ public class ServerChunkCache extends ChunkSource { @Nullable @Override public ChunkAccess getChunk(int x, int z, ChunkStatus leastStatus, boolean create) { @@ -25197,18 +25257,18 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9ccb3ffc375298fda4dca97803e65e39 - return ifLoaded; - } - // Paper end - Perf: Optimise getChunkAt calls for loaded chunks -- ProfilerFiller gameprofilerfiller = this.level.getProfiler(); +- ProfilerFiller gameprofilerfiller = Profiler.get(); - - gameprofilerfiller.incrementCounter("getChunk"); - long k = ChunkPos.asLong(x, z); +- +- for (int l = 0; l < 4; ++l) { +- if (k == this.lastChunkPos[l] && leastStatus == this.lastChunkStatus[l]) { +- ChunkAccess ichunkaccess = this.lastChunk[l]; + // Paper start - rewrite chunk system + if (leastStatus == ChunkStatus.FULL) { + final LevelChunk ret = this.fullChunks.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(x, z)); -- for (int l = 0; l < 4; ++l) { -- if (k == this.lastChunkPos[l] && leastStatus == this.lastChunkStatus[l]) { -- ChunkAccess ichunkaccess = this.lastChunk[l]; -- - if (ichunkaccess != null) { // CraftBukkit - the chunk can become accessible in the meantime TODO for non-null chunks it might also make sense to check that the chunk's state hasn't changed in the meantime - return ichunkaccess; - } @@ -25256,7 +25316,7 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9ccb3ffc375298fda4dca97803e65e39 } private void clearCache() { -@@ -261,56 +273,59 @@ public class ServerChunkCache extends ChunkSource { +@@ -273,56 +285,59 @@ public class ServerChunkCache extends ChunkSource { } private CompletableFuture> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { @@ -25264,28 +25324,19 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9ccb3ffc375298fda4dca97803e65e39 - long k = chunkcoordintpair.toLong(); - int l = ChunkLevel.byStatus(leastStatus); - ChunkHolder playerchunk = this.getVisibleChunkIfPresent(k); -+ // Paper start - rewrite chunk system -+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.level, chunkX, chunkZ, "Scheduling chunk load off-main"); - +- - // CraftBukkit start - don't add new ticket for currently unloading chunk - boolean currentlyUnloading = false; - if (playerchunk != null) { - FullChunkStatus oldChunkState = ChunkLevel.fullStatus(playerchunk.oldTicketLevel); - FullChunkStatus currentChunkState = ChunkLevel.fullStatus(playerchunk.getTicketLevel()); - currentlyUnloading = (oldChunkState.isOrAfter(FullChunkStatus.FULL) && !currentChunkState.isOrAfter(FullChunkStatus.FULL)); -+ final int minLevel = ChunkLevel.byStatus(leastStatus); -+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkX, chunkZ); -+ -+ final boolean needsFullScheduling = leastStatus == ChunkStatus.FULL && (chunkHolder == null || !chunkHolder.getChunkStatus().isOrAfter(FullChunkStatus.FULL)); -+ -+ if ((chunkHolder == null || chunkHolder.getTicketLevel() > minLevel || needsFullScheduling) && !create) { -+ return ChunkHolder.UNLOADED_CHUNK_FUTURE; - } +- } - if (create && !currentlyUnloading) { - // CraftBukkit end - this.distanceManager.addTicket(TicketType.UNKNOWN, chunkcoordintpair, l, chunkcoordintpair); - if (this.chunkAbsent(playerchunk, l)) { -- ProfilerFiller gameprofilerfiller = this.level.getProfiler(); +- ProfilerFiller gameprofilerfiller = Profiler.get(); - - gameprofilerfiller.push("chunkLoad"); - this.runDistanceManagerUpdates(); @@ -25293,7 +25344,22 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9ccb3ffc375298fda4dca97803e65e39 - gameprofilerfiller.pop(); - if (this.chunkAbsent(playerchunk, l)) { - throw (IllegalStateException) Util.pauseInIde(new IllegalStateException("No chunk holder after ticket has been added")); +- } +- } ++ // Paper start - rewrite chunk system ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.level, chunkX, chunkZ, "Scheduling chunk load off-main"); ++ ++ final int minLevel = ChunkLevel.byStatus(leastStatus); ++ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkX, chunkZ); ++ ++ final boolean needsFullScheduling = leastStatus == ChunkStatus.FULL && (chunkHolder == null || !chunkHolder.getChunkStatus().isOrAfter(FullChunkStatus.FULL)); + ++ if ((chunkHolder == null || chunkHolder.getTicketLevel() > minLevel || needsFullScheduling) && !create) { ++ return ChunkHolder.UNLOADED_CHUNK_FUTURE; + } + +- return this.chunkAbsent(playerchunk, l) ? GenerationChunkHolder.UNLOADED_CHUNK_FUTURE : playerchunk.scheduleChunkGenerationTask(leastStatus, this.chunkMap); +- } + final ChunkAccess ifPresent = chunkHolder == null ? null : chunkHolder.getChunkIfPresent(leastStatus); + if (needsFullScheduling || ifPresent == null) { + // schedule @@ -25303,13 +25369,9 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9ccb3ffc375298fda4dca97803e65e39 + ret.complete(ChunkHolder.UNLOADED_CHUNK); + } else { + ret.complete(ChunkResult.of(chunk)); - } -- } -- } ++ } + }; - -- return this.chunkAbsent(playerchunk, l) ? GenerationChunkHolder.UNLOADED_CHUNK_FUTURE : playerchunk.scheduleChunkGenerationTask(leastStatus, this.chunkMap); -- } ++ + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().scheduleChunkLoad( + chunkX, chunkZ, leastStatus, true, + ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER, @@ -25352,7 +25414,7 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9ccb3ffc375298fda4dca97803e65e39 } @Override -@@ -323,16 +338,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -335,16 +350,7 @@ public class ServerChunkCache extends ChunkSource { } public boolean runDistanceManagerUpdates() { // Paper - public @@ -25370,13 +25432,17 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9ccb3ffc375298fda4dca97803e65e39 } // Paper start -@@ -342,13 +348,14 @@ public class ServerChunkCache extends ChunkSource { +@@ -354,17 +360,14 @@ public class ServerChunkCache extends ChunkSource { // Paper end public boolean isPositionTicking(long pos) { -- ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos); +- if (!this.level.shouldTickBlocksAt(pos)) { +- return false; +- } else { +- ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos); - -- return playerchunk == null ? false : (!this.level.shouldTickBlocksAt(pos) ? false : ((ChunkResult) playerchunk.getTickingChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).isSuccess()); +- return playerchunk == null ? false : ((ChunkResult) playerchunk.getTickingChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).isSuccess(); +- } + // Paper start - rewrite chunk system + final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder newChunkHolder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(pos); + return newChunkHolder != null && newChunkHolder.isTickingReady(); @@ -25389,14 +25455,16 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9ccb3ffc375298fda4dca97803e65e39 try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings this.chunkMap.saveAllChunks(flush); } // Paper - Timings -@@ -361,16 +368,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -377,17 +380,15 @@ public class ServerChunkCache extends ChunkSource { } public void close(boolean save) throws IOException { - if (save) { - this.save(true); - } -- // CraftBukkit end + // CraftBukkit end ++ // Paper - rewrite chunk system + this.dataStorage.close(); - this.lightEngine.close(); - this.chunkMap.close(); + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.close(save, true); // Paper - rewrite chunk system @@ -25405,114 +25473,18 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9ccb3ffc375298fda4dca97803e65e39 // CraftBukkit start - modelled on below public void purgeUnload() { + if (true) return; // Paper - rewrite chunk system - this.level.getProfiler().push("purge"); - this.distanceManager.purgeStaleTickets(); - this.runDistanceManagerUpdates(); -@@ -394,6 +397,7 @@ public class ServerChunkCache extends ChunkSource { - this.level.getProfiler().popPush("chunks"); + ProfilerFiller gameprofilerfiller = Profiler.get(); + + gameprofilerfiller.push("purge"); +@@ -415,6 +416,7 @@ public class ServerChunkCache extends ChunkSource { + gameprofilerfiller.popPush("chunks"); if (tickChunks) { this.level.timings.chunks.startTiming(); // Paper - timings + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getPlayerChunkLoader().tick(); // Paper - rewrite chunk system this.tickChunks(); this.level.timings.chunks.stopTiming(); // Paper - timings this.chunkMap.tick(); -@@ -408,6 +412,7 @@ public class ServerChunkCache extends ChunkSource { - } - - private void tickChunks() { -+ long chunksTicked = 0; // Paper - rewrite chunk system - long i = this.level.getGameTime(); - long j = i - this.lastInhabitedUpdate; - -@@ -417,18 +422,29 @@ public class ServerChunkCache extends ChunkSource { - - gameprofilerfiller.push("pollingChunks"); - gameprofilerfiller.push("filteringLoadedChunks"); -- List list = Lists.newArrayListWithCapacity(this.chunkMap.size()); -- Iterator iterator = this.chunkMap.getChunks().iterator(); -- if (this.level.getServer().tickRateManager().runsNormally()) this.level.timings.chunkTicks.startTiming(); // Paper -+ // Paper start - chunk tick iteration optimisations -+ List list; -+ { -+ final ca.spottedleaf.moonrise.common.list.ReferenceList tickingChunks = -+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel) this.level).moonrise$getTickingChunks(); - -- while (iterator.hasNext()) { -- ChunkHolder playerchunk = (ChunkHolder) iterator.next(); -- LevelChunk chunk = playerchunk.getTickingChunk(); -+ final ServerChunkCache.ChunkAndHolder[] raw = tickingChunks.getRawDataUnchecked(); -+ final int size = tickingChunks.size(); - -- if (chunk != null) { -- list.add(new ServerChunkCache.ChunkAndHolder(chunk, playerchunk)); -+ if (this.iterationCopy == null || this.iterationCopy.length < size) { -+ this.iterationCopy = new ServerChunkCache.ChunkAndHolder[raw.length]; - } -+ System.arraycopy(raw, 0, this.iterationCopy, 0, size); -+ -+ list = it.unimi.dsi.fastutil.objects.ObjectArrayList.wrap( -+ this.iterationCopy, size -+ ); - } -+ // Paper end - chunk tick iteration optimisations -+ Iterator iterator = null; // Paper - chunk tick iteration optimisations -+ if (this.level.getServer().tickRateManager().runsNormally()) this.level.timings.chunkTicks.startTiming(); // Paper -+ -+ // Paper - chunk tick iteration optimisations - - if (this.level.tickRateManager().runsNormally()) { - gameprofilerfiller.popPush("naturalSpawnCount"); -@@ -460,14 +476,19 @@ public class ServerChunkCache extends ChunkSource { - LevelChunk chunk1 = chunkproviderserver_a.chunk; - ChunkPos chunkcoordintpair = chunk1.getPos(); - -- if (this.level.isNaturalSpawningAllowed(chunkcoordintpair) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkcoordintpair)) { -+ if (true && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkcoordintpair)) { // Paper - rewrite chunk system - chunk1.incrementInhabitedTime(j); - if (flag && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkcoordintpair, true)) { // Spigot - NaturalSpawner.spawnForChunk(this.level, chunk1, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1); - } - -- if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { -+ if (true) { // Paper - rewrite chunk system - this.level.tickChunk(chunk1, l); -+ // Paper start - rewrite chunk system -+ if ((++chunksTicked & 7L) == 0L) { -+ ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.level.getServer()).moonrise$executeMidTickTasks(); -+ } -+ // Paper end - rewrite chunk system - } - } - } -@@ -482,22 +503,35 @@ public class ServerChunkCache extends ChunkSource { - } - - gameprofilerfiller.popPush("broadcast"); -- list.forEach((chunkproviderserver_a1) -> { -- this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing -- chunkproviderserver_a1.holder.broadcastChanges(chunkproviderserver_a1.chunk); -- this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing -- }); -+ // Paper start - chunk tick iteration optimisations -+ this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing -+ { -+ final it.unimi.dsi.fastutil.objects.ObjectArrayList chunks = (it.unimi.dsi.fastutil.objects.ObjectArrayList)list; -+ final ServerChunkCache.ChunkAndHolder[] raw = chunks.elements(); -+ final int size = chunks.size(); -+ -+ Objects.checkFromToIndex(0, size, raw.length); -+ for (int idx = 0; idx < size; ++idx) { -+ final ServerChunkCache.ChunkAndHolder holder = raw[idx]; -+ raw[idx] = null; -+ -+ holder.holder().broadcastChanges(holder.chunk()); -+ } -+ } -+ this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing -+ // Paper end - chunk tick iteration optimisations - gameprofilerfiller.pop(); - gameprofilerfiller.pop(); - } +@@ -546,11 +548,12 @@ public class ServerChunkCache extends ChunkSource { } private void getFullChunk(long pos, Consumer chunkConsumer) { @@ -25529,7 +25501,7 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9ccb3ffc375298fda4dca97803e65e39 } -@@ -591,6 +625,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -644,6 +647,12 @@ public class ServerChunkCache extends ChunkSource { this.chunkMap.setServerViewDistance(watchDistance); } @@ -25542,7 +25514,7 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9ccb3ffc375298fda4dca97803e65e39 public void setSimulationDistance(int simulationDistance) { this.distanceManager.updateSimulationDistance(simulationDistance); } -@@ -669,21 +709,19 @@ public class ServerChunkCache extends ChunkSource { +@@ -735,21 +744,19 @@ public class ServerChunkCache extends ChunkSource { @Override // CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task public boolean pollTask() { @@ -25571,10 +25543,10 @@ index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9ccb3ffc375298fda4dca97803e65e39 } } diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index 1d849ce4e2c85f149af25318b8ffb6dcef6c6788..12d86f27d04bffed8c3844e36b42fbc2f84dacff 100644 +index bc0f1aa61e68d2a8638d89c10bc5c71922d057f9..79c88b315481fe70f037bae834f2b07277cabcda 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -97,6 +97,11 @@ public class ServerEntity { +@@ -101,6 +101,11 @@ public class ServerEntity { } public void sendChanges() { @@ -25587,28 +25559,28 @@ index 1d849ce4e2c85f149af25318b8ffb6dcef6c6788..12d86f27d04bffed8c3844e36b42fbc2 if (!list.equals(this.lastPassengers)) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd941126a0b0f4 100644 +index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9fb00a037 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -184,7 +184,7 @@ import org.bukkit.event.weather.LightningStrikeEvent; +@@ -187,7 +187,7 @@ import org.bukkit.event.weather.LightningStrikeEvent; import org.bukkit.event.world.TimeSkipEvent; // CraftBukkit end --public class ServerLevel extends Level implements WorldGenLevel { -+public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevelReader { // Paper - rewrite chunk system +-public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLevel { ++public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLevel, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevelReader { // Paper - rewrite chunk system public static final BlockPos END_SPAWN_POINT = new BlockPos(100, 50, 0); public static final IntProvider RAIN_DELAY = UniformInt.of(12000, 180000); -@@ -200,7 +200,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -203,7 +203,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public final PrimaryLevelData serverLevelData; // CraftBukkit - type private int lastSpawnChunkRadius; - final EntityTickList entityTickList; + final EntityTickList entityTickList = new EntityTickList(); - public final PersistentEntitySectionManager entityManager; + // Paper - rewrite chunk system private final GameEventDispatcher gameEventDispatcher; public boolean noSave; private final SleepStatus sleepStatus; -@@ -271,15 +271,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -274,15 +274,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, java.util.function.Consumer> onLoad) { @@ -25625,7 +25597,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 int minBlockX = Mth.floor(axisalignedbb.minX - 1.0E-7D) - 3; int maxBlockX = Mth.floor(axisalignedbb.maxX + 1.0E-7D) + 3; -@@ -292,30 +284,160 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -295,30 +287,160 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe int minChunkZ = minBlockZ >> 4; int maxChunkZ = maxBlockZ >> 4; @@ -25800,7 +25772,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 } } } -@@ -323,22 +445,46 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -326,22 +448,46 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe for (int cx = minChunkX; cx <= maxChunkX; ++cx) { for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) { @@ -25857,7 +25829,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 // Add env and gen to constructor, IWorldDataServer -> WorldDataServer public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { -@@ -385,14 +531,13 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -375,14 +521,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe DataFixer datafixer = minecraftserver.getFixerUpper(); EntityPersistentStorage entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver); @@ -25875,7 +25847,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 return minecraftserver.overworld().getDataStorage(); }); this.chunkSource.getGeneratorState().ensureStructuresGenerated(); -@@ -420,6 +565,19 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -410,6 +555,19 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.randomSequences = (RandomSequences) Objects.requireNonNullElseGet(randomsequences, () -> { return (RandomSequences) this.getDataStorage().computeIfAbsent(RandomSequences.factory(l), "random_sequences"); }); @@ -25895,16 +25867,16 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit } -@@ -553,7 +711,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -542,7 +700,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe gameprofilerfiller.push("checkDespawn"); entity.checkDespawn(); gameprofilerfiller.pop(); -- if (this.chunkSource.chunkMap.getDistanceManager().inEntityTickingRange(entity.chunkPosition().toLong())) { -+ if (true || this.chunkSource.chunkMap.getDistanceManager().inEntityTickingRange(entity.chunkPosition().toLong())) { // Paper - rewrite chunk system +- if (entity instanceof ServerPlayer || this.chunkSource.chunkMap.getDistanceManager().inEntityTickingRange(entity.chunkPosition().toLong())) { ++ if (true) { // Paper - rewrite chunk system Entity entity1 = entity.getVehicle(); if (entity1 != null) { -@@ -578,13 +736,16 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -567,13 +725,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } gameprofilerfiller.push("entityManagement"); @@ -25923,7 +25895,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 } protected void tickTime() { -@@ -626,6 +787,63 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -613,6 +774,63 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe }); } @@ -25987,7 +25959,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 public void tickChunk(LevelChunk chunk, int randomTickSpeed) { ChunkPos chunkcoordintpair = chunk.getPos(); boolean flag = this.isRaining(); -@@ -675,35 +893,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -662,35 +880,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe gameprofilerfiller.popPush("tickBlocks"); timings.chunkTicksBlocks.startTiming(); // Paper if (randomTickSpeed > 0) { @@ -26024,9 +25996,9 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 } timings.chunkTicksBlocks.stopTiming(); // Paper -@@ -976,6 +1166,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -964,6 +1154,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (fluid1.is(fluid)) { - fluid1.tick(this, pos); + fluid1.tick(this, pos, iblockdata); } + // Paper start - rewrite chunk system + if ((++this.tickedBlocksOrFluids & 7L) != 0L) { @@ -26036,7 +26008,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 } -@@ -985,6 +1180,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -973,6 +1168,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (iblockdata.is(block)) { iblockdata.tick(this, pos, this.random); } @@ -26048,7 +26020,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 } -@@ -1061,6 +1261,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1049,6 +1249,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } public void save(@Nullable ProgressListener progressListener, boolean flush, boolean savingDisabled) { @@ -26060,7 +26032,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 ServerChunkCache chunkproviderserver = this.getChunkSource(); if (!savingDisabled) { -@@ -1076,16 +1281,21 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1064,16 +1269,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } timings.worldSaveChunks.startTiming(); // Paper @@ -26088,7 +26060,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 // CraftBukkit start - moved from MinecraftServer.saveChunks ServerLevel worldserver1 = this; -@@ -1218,7 +1428,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1213,7 +1423,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.removePlayerImmediately((ServerPlayer) entity, Entity.RemovalReason.DISCARDED); } @@ -26097,7 +26069,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 } // CraftBukkit start -@@ -1249,7 +1459,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1243,7 +1453,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } // CraftBukkit end @@ -26106,7 +26078,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 } } -@@ -1260,11 +1470,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1254,11 +1464,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public boolean tryAddFreshEntityWithPassengers(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { // CraftBukkit end @@ -26119,7 +26091,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 return false; } else { this.addFreshEntityWithPassengers(entity, reason); // CraftBukkit -@@ -1852,7 +2058,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1891,7 +2097,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } } @@ -26128,7 +26100,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 bufferedwriter.write(String.format(Locale.ROOT, "block_entity_tickers: %d\n", this.blockEntityTickers.size())); bufferedwriter.write(String.format(Locale.ROOT, "block_ticks: %d\n", this.getBlockTicks().count())); bufferedwriter.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count())); -@@ -1901,7 +2107,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1940,7 +2146,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe BufferedWriter bufferedwriter2 = Files.newBufferedWriter(path1); try { @@ -26137,7 +26109,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 } catch (Throwable throwable4) { if (bufferedwriter2 != null) { try { -@@ -1922,7 +2128,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1961,7 +2167,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe BufferedWriter bufferedwriter3 = Files.newBufferedWriter(path2); try { @@ -26146,7 +26118,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 } catch (Throwable throwable6) { if (bufferedwriter3 != null) { try { -@@ -2064,7 +2270,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2103,7 +2309,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @VisibleForTesting public String getWatchdogStats() { @@ -26155,7 +26127,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString(); }), this.blockEntityTickers.size(), ServerLevel.getTypeCount(this.blockEntityTickers, TickingBlockEntity::getType), this.getBlockTicks().count(), this.getFluidTicks().count(), this.gatherChunkSourceStats()); } -@@ -2094,15 +2300,25 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2133,15 +2339,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public LevelEntityGetter getEntities() { org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot @@ -26184,7 +26156,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 } public void startTickingChunk(LevelChunk chunk) { -@@ -2122,34 +2338,47 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2161,34 +2377,47 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public void close() throws IOException { super.close(); @@ -26239,7 +26211,7 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 } @Override -@@ -2175,7 +2404,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2234,7 +2463,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report); crashreportsystemdetails.setDetail("Loaded entity count", () -> { @@ -26249,10 +26221,10 @@ index 342682178950c8986fb3c86924811089f4de887d..f910e37a8e7cd0358c149d84bafd9411 return crashreportsystemdetails; } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 62ec627e80b87a92a2a51ba9fc3626a67636855f..30f53916a9e49165bcfef2bea2c0b50a26f5a8a3 100644 +index 1a7d2ade0e85dd5e6cd6c9202e3277cc2fa43d4a..ba15c34a3ea516d2d946d923551293ac05118926 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -200,7 +200,7 @@ import org.bukkit.event.player.PlayerToggleSneakEvent; +@@ -218,7 +218,7 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.inventory.MainHand; // CraftBukkit end @@ -26261,7 +26233,7 @@ index 62ec627e80b87a92a2a51ba9fc3626a67636855f..30f53916a9e49165bcfef2bea2c0b50a private static final Logger LOGGER = LogUtils.getLogger(); private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32; -@@ -297,6 +297,36 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -324,6 +324,36 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { public @Nullable String clientBrandName = null; // Paper - Brand support public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event @@ -26299,10 +26271,10 @@ index 62ec627e80b87a92a2a51ba9fc3626a67636855f..30f53916a9e49165bcfef2bea2c0b50a super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); this.chatVisibility = ChatVisiblity.FULL; diff --git a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -index 63fae619e9b4ed49585f88ea7c167b0ee5efd859..cc779de06773451d51f54040fc899e4f45110bc1 100644 +index 39d34f3728ae8d845d1bffc09f3ab8b64eb4d48b..653ba7bb4f4793d7a7cad903e9695ff49666985f 100644 --- a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java +++ b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -@@ -23,15 +23,128 @@ import net.minecraft.world.level.chunk.LightChunkGetter; +@@ -22,23 +22,135 @@ import net.minecraft.world.level.chunk.LightChunkGetter; import net.minecraft.world.level.lighting.LevelLightEngine; import org.slf4j.Logger; @@ -26310,11 +26282,11 @@ index 63fae619e9b4ed49585f88ea7c167b0ee5efd859..cc779de06773451d51f54040fc899e4f +public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCloseable, ca.spottedleaf.moonrise.patches.starlight.light.StarLightLightingProvider { // Paper - rewrite chunk system public static final int DEFAULT_BATCH_SIZE = 1000; private static final Logger LOGGER = LogUtils.getLogger(); -- private final ProcessorMailbox taskMailbox; +- private final ConsecutiveExecutor consecutiveExecutor; - private final ObjectList> lightTasks = new ObjectArrayList<>(); + // Paper - rewrite chunk sytem private final ChunkMap chunkMap; -- private final ProcessorHandle> sorterMailbox; +- private final ChunkTaskDispatcher taskDispatcher; + // Paper - rewrite chunk sytem private final int taskPerBatch = 1000; - private final AtomicBoolean scheduled = new AtomicBoolean(); @@ -26435,18 +26407,17 @@ index 63fae619e9b4ed49585f88ea7c167b0ee5efd859..cc779de06773451d51f54040fc899e4f + // Paper end - rewrite chunk system public ThreadedLevelLightEngine( - LightChunkGetter chunkProvider, -@@ -42,8 +155,7 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl + LightChunkGetter chunkProvider, ChunkMap chunkLoadingManager, boolean hasBlockLight, ConsecutiveExecutor processor, ChunkTaskDispatcher executor ) { super(chunkProvider, true, hasBlockLight); this.chunkMap = chunkLoadingManager; -- this.sorterMailbox = executor; -- this.taskMailbox = processor; +- this.taskDispatcher = executor; +- this.consecutiveExecutor = processor; + // Paper - rewrite chunk sytem } @Override -@@ -57,164 +169,73 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl +@@ -52,164 +164,73 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl @Override public void checkBlock(BlockPos pos) { @@ -26475,7 +26446,7 @@ index 63fae619e9b4ed49585f88ea7c167b0ee5efd859..cc779de06773451d51f54040fc899e4f - super.queueSectionData(LightLayer.SKY, SectionPos.of(pos, i), null); - } - -- for (int j = this.levelHeightAccessor.getMinSection(); j < this.levelHeightAccessor.getMaxSection(); j++) { +- for (int j = this.levelHeightAccessor.getMinSectionY(); j <= this.levelHeightAccessor.getMaxSectionY(); j++) { - super.updateSectionStatus(SectionPos.of(pos, j), true); - } - }, () -> "updateChunkStatus " + pos + " true")); @@ -26538,12 +26509,12 @@ index 63fae619e9b4ed49585f88ea7c167b0ee5efd859..cc779de06773451d51f54040fc899e4f } private void addTask(int x, int z, IntSupplier completedLevelSupplier, ThreadedLevelLightEngine.TaskType stage, Runnable task) { -- this.sorterMailbox.tell(ChunkTaskPriorityQueueSorter.message(() -> { +- this.taskDispatcher.submit(() -> { - this.lightTasks.add(Pair.of(stage, task)); - if (this.lightTasks.size() >= 1000) { - this.runUpdate(); - } -- }, ChunkPos.asLong(x, z), completedLevelSupplier)); +- }, ChunkPos.asLong(x, z), completedLevelSupplier); + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } @@ -26593,7 +26564,7 @@ index 63fae619e9b4ed49585f88ea7c167b0ee5efd859..cc779de06773451d51f54040fc899e4f public void tryScheduleUpdate() { - if ((!this.lightTasks.isEmpty() || super.hasLightWork()) && this.scheduled.compareAndSet(false, true)) { -- this.taskMailbox.tell(() -> { +- this.consecutiveExecutor.schedule(() -> { - this.runUpdate(); - this.scheduled.set(false); - }); @@ -26691,7 +26662,7 @@ index eba83b085435150e5954fd5d41dda9ce1d0601ad..daf543b51d8875b374688957ae4bc466 } } diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java -index b26a4a38144ec1b171db911bbf949b53ed35708f..5a8a33638ceb1d980ffc3e6dd86e7eb11dfd9375 100644 +index 2e72e92762877b28dd908711671e1dfb933de9b0..a1bfd9d9bf992c5516290ca9aabe12ab037faa18 100644 --- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java +++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java @@ -85,6 +85,36 @@ public class WorldGenRegion implements WorldGenLevel { @@ -26948,19 +26919,19 @@ index 50040c497a819cd1229042ab3cb057d34a32cacc..15c5164d0ef41a978c16ee317fa73e97 + // Paper end - block counting } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 76e9d34e5219fbae0095cf735b58833c29343573..6fe90b281c95062c0be14650c00b21b641c42394 100644 +index 8cdef637f6343119fc77f87e7478ee23e9b8efab..5410a0380c44629f1c9b4f0a8e6017cfc5a31a89 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -167,7 +167,7 @@ import org.bukkit.event.player.PlayerTeleportEvent; +@@ -175,7 +175,7 @@ import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.plugin.PluginManager; // CraftBukkit end --public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, CommandSource, ScoreHolder { -+public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, CommandSource, ScoreHolder, ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity, ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity { // Paper - rewrite chunk system // Paper - optimise entity tracker +-public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder { ++public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder, ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity, ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity { // Paper - rewrite chunk system // Paper - optimise entity tracker // CraftBukkit start private static final int CURRENT_LEVEL = 2; -@@ -455,6 +455,97 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -445,6 +445,97 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this.dimensions.makeBoundingBox(x, y, z); } // Paper end @@ -27058,7 +27029,7 @@ index 76e9d34e5219fbae0095cf735b58833c29343573..6fe90b281c95062c0be14650c00b21b6 public Entity(EntityType type, Level world) { this.id = Entity.ENTITY_COUNTER.incrementAndGet(); -@@ -1278,41 +1369,82 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1303,41 +1394,82 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } private Vec3 collide(Vec3 movement) { @@ -27168,7 +27139,7 @@ index 76e9d34e5219fbae0095cf735b58833c29343573..6fe90b281c95062c0be14650c00b21b6 } private static float[] collectCandidateStepUpHeights(AABB collisionBox, List collisions, float f, float stepHeight) { -@@ -2628,18 +2760,75 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2699,18 +2831,75 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public boolean isInWall() { @@ -27184,13 +27155,13 @@ index 76e9d34e5219fbae0095cf735b58833c29343573..6fe90b281c95062c0be14650c00b21b6 - BlockState iblockdata = this.level().getBlockState(blockposition); + final float reducedWith = this.dimensions.width() * 0.8F; + final AABB box = AABB.ofSize(this.getEyePosition(), reducedWith, 1.0E-6D, reducedWith); -+ -+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(box)) { -+ return false; -+ } - return !iblockdata.isAir() && iblockdata.isSuffocating(this.level(), blockposition) && Shapes.joinIsNotEmpty(iblockdata.getCollisionShape(this.level(), blockposition).move((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()), Shapes.create(axisalignedbb), BooleanOp.AND); - }); ++ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(box)) { ++ return false; ++ } ++ + final BlockPos.MutableBlockPos tempPos = new BlockPos.MutableBlockPos(); + + final int minX = Mth.floor(box.minX); @@ -27251,7 +27222,7 @@ index 76e9d34e5219fbae0095cf735b58833c29343573..6fe90b281c95062c0be14650c00b21b6 } public InteractionResult interact(Player player, InteractionHand hand) { -@@ -4026,14 +4215,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4180,14 +4369,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public Iterable getIndirectPassengers() { @@ -27276,7 +27247,7 @@ index 76e9d34e5219fbae0095cf735b58833c29343573..6fe90b281c95062c0be14650c00b21b6 } private Iterable getIndirectPassengers_old() { // Paper end - Optimize indirect passenger iteration -@@ -4398,6 +4590,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4543,6 +4735,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.setPosRaw(x, y, z, false); } public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) { @@ -27292,7 +27263,7 @@ index 76e9d34e5219fbae0095cf735b58833c29343573..6fe90b281c95062c0be14650c00b21b6 if (!checkPosition(this, x, y, z)) { return; } -@@ -4529,6 +4730,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4672,6 +4873,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public final void setRemoved(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { @@ -27304,17 +27275,17 @@ index 76e9d34e5219fbae0095cf735b58833c29343573..6fe90b281c95062c0be14650c00b21b6 + // Paper end - rewrite chunk system CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit end - final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers -@@ -4540,7 +4747,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + if (this.removalReason == null) { +@@ -4682,7 +4889,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.stopRiding(); } - this.getPassengers().forEach(Entity::stopRiding); + if (this.removalReason != Entity.RemovalReason.UNLOADED_TO_CHUNK) { this.getPassengers().forEach(Entity::stopRiding); } // Paper - rewrite chunk system this.levelCallback.onRemove(entity_removalreason); - // Paper start - Folia schedulers - if (!(this instanceof ServerPlayer) && entity_removalreason != RemovalReason.CHANGED_DIMENSION && !alreadyRemoved) { -@@ -4571,7 +4778,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + this.onRemoval(entity_removalreason); + } +@@ -4698,7 +4905,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public boolean shouldBeSaved() { @@ -27324,15 +27295,15 @@ index 76e9d34e5219fbae0095cf735b58833c29343573..6fe90b281c95062c0be14650c00b21b6 @Override diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -index fb63036d26d2b5370472b741b23bebd71e247463..d7a6eab60bf26916f78f858e224573560e581fef 100644 +index 96bc0ba60195e5e666d47b3a0b943b733986d96a..4cf6cb0abfeb7065c6d9381fb4194371c0cddc35 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -@@ -38,12 +38,153 @@ import net.minecraft.world.level.chunk.storage.RegionStorageInfo; +@@ -38,12 +38,130 @@ import net.minecraft.world.level.chunk.storage.RegionStorageInfo; import net.minecraft.world.level.chunk.storage.SectionStorage; import net.minecraft.world.level.chunk.storage.SimpleRegionStorage; --public class PoiManager extends SectionStorage { -+public class PoiManager extends SectionStorage implements ca.spottedleaf.moonrise.patches.chunk_system.level.poi.ChunkSystemPoiManager { // Paper - rewrite chunk system +-public class PoiManager extends SectionStorage { ++public class PoiManager extends SectionStorage implements ca.spottedleaf.moonrise.patches.chunk_system.level.poi.ChunkSystemPoiManager { // Paper - rewrite chunk system public static final int MAX_VILLAGE_DISTANCE = 6; public static final int VILLAGE_SECTION_SIZE = 1; private final PoiManager.DistanceTracker distanceTracker; @@ -27454,35 +27425,12 @@ index fb63036d26d2b5370472b741b23bebd71e247463..d7a6eab60bf26916f78f858e22457356 + this.checkConsistencyWithBlocks(SectionPos.of(chunkX, section, chunkZ), sections[section - minY]); + } + } -+ -+ @Override -+ public final void moonrise$close() throws java.io.IOException {} -+ -+ @Override -+ public final net.minecraft.nbt.CompoundTag moonrise$read(final int chunkX, final int chunkZ) throws java.io.IOException { -+ if (!ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.isRegionFileThread()) { -+ return ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.loadData( -+ this.world, chunkX, chunkZ, ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.RegionFileType.POI_DATA, -+ ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.getIOBlockingPriorityForCurrentThread() -+ ); -+ } -+ return this.moonrise$getRegionStorage().read(new ChunkPos(chunkX, chunkZ)); -+ } -+ -+ @Override -+ public final void moonrise$write(final int chunkX, final int chunkZ, final net.minecraft.nbt.CompoundTag data) throws java.io.IOException { -+ if (!ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.isRegionFileThread()) { -+ ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.scheduleSave(this.world, chunkX, chunkZ, data, ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.RegionFileType.POI_DATA); -+ return; -+ } -+ this.moonrise$getRegionStorage().write(new ChunkPos(chunkX, chunkZ), data); -+ } + // Paper end - rewrite chunk system + public PoiManager( RegionStorageInfo storageKey, Path directory, -@@ -62,6 +203,7 @@ public class PoiManager extends SectionStorage { +@@ -64,6 +182,7 @@ public class PoiManager extends SectionStorage { world ); this.distanceTracker = new PoiManager.DistanceTracker(); @@ -27490,7 +27438,7 @@ index fb63036d26d2b5370472b741b23bebd71e247463..d7a6eab60bf26916f78f858e22457356 } public void add(BlockPos pos, Holder type) { -@@ -195,8 +337,8 @@ public class PoiManager extends SectionStorage { +@@ -197,8 +316,8 @@ public class PoiManager extends SectionStorage { } public int sectionsToVillage(SectionPos pos) { @@ -27501,7 +27449,7 @@ index fb63036d26d2b5370472b741b23bebd71e247463..d7a6eab60bf26916f78f858e22457356 } boolean isVillageCenter(long pos) { -@@ -210,19 +352,26 @@ public class PoiManager extends SectionStorage { +@@ -212,19 +331,26 @@ public class PoiManager extends SectionStorage { @Override public void tick(BooleanSupplier shouldKeepTicking) { @@ -27534,7 +27482,7 @@ index fb63036d26d2b5370472b741b23bebd71e247463..d7a6eab60bf26916f78f858e22457356 } public void checkConsistencyWithBlocks(SectionPos sectionPos, LevelChunkSection chunkSection) { -@@ -259,7 +408,7 @@ public class PoiManager extends SectionStorage { +@@ -263,7 +389,7 @@ public class PoiManager extends SectionStorage { .map(sectionPos -> Pair.of(sectionPos, this.getOrLoad(sectionPos.asLong()))) .filter(pair -> !pair.getSecond().map(PoiSection::isValid).orElse(false)) .map(pair -> pair.getFirst().chunk()) @@ -27544,10 +27492,10 @@ index fb63036d26d2b5370472b741b23bebd71e247463..d7a6eab60bf26916f78f858e22457356 } diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java -index 971fb29a2c3dc713cb8ab1d2eed054cc16f9c93c..a6c0e89cb645693034f8e90ac2de8f2da457453c 100644 +index b9e0bc8f1e948614d986335de1f3d2df199eea81..f6f0d7c21ee81ff33d4af350c4d39aadfbe140df 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java -@@ -23,7 +23,7 @@ import net.minecraft.core.SectionPos; +@@ -23,13 +23,27 @@ import net.minecraft.core.SectionPos; import net.minecraft.util.VisibleForDebug; import org.slf4j.Logger; @@ -27556,9 +27504,8 @@ index 971fb29a2c3dc713cb8ab1d2eed054cc16f9c93c..a6c0e89cb645693034f8e90ac2de8f2d private static final Logger LOGGER = LogUtils.getLogger(); private final Short2ObjectMap records = new Short2ObjectOpenHashMap<>(); private final Map, Set> byType = Maps.newHashMap(); -@@ -42,6 +42,20 @@ public class PoiSection { - .orElseGet(Util.prefix("Failed to read POI section: ", LOGGER::error), () -> new PoiSection(updateListener, false, ImmutableList.of())); - } + private final Runnable setDirty; + private boolean isValid; + // Paper start - rewrite chunk system + private final Optional noAllocOptional = Optional.of((PoiSection)(Object)this);; @@ -27578,10 +27525,10 @@ index 971fb29a2c3dc713cb8ab1d2eed054cc16f9c93c..a6c0e89cb645693034f8e90ac2de8f2d this(updateListener, true, ImmutableList.of()); } diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -index 2f398750bfee5758ad8b1367b6fc14364e4de776..c292f58ba4b29395484dbbf8591e455f449581d8 100644 +index 2bb2b36f793d25b6e49d1a72bb665cfa9f212730..1362c33ca9ec524372b03c890385888ca6cfe2b0 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -359,7 +359,7 @@ public class ArmorStand extends LivingEntity { +@@ -364,7 +364,7 @@ public class ArmorStand extends LivingEntity { @Override protected void pushEntities() { if (!this.level().paperConfig().entities.armorStands.doCollisionEntityLookups) return; // Paper - Option to prevent armor stands from doing entity lookups @@ -27604,10 +27551,10 @@ index 3fa2964b979053ecbefc946c7fe76828de86d8f1..28bf0518f7d17099d7e4990defbeda67 public ClipContext(Vec3 start, Vec3 end, ClipContext.Block shapeType, ClipContext.Fluid fluidHandling, Entity entity) { diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java -index bd20bea7f76a7307f1698fb2dfef37125032d166..141b748abe80402731cdaf14a3d36aa7cef4f4bd 100644 +index e185a33b5b1f8e8e0a0e666b24ba3e9186a8a7ff..5d7a6e4b73f032db356e7ec369b150013e940ee6 100644 --- a/src/main/java/net/minecraft/world/level/EntityGetter.java +++ b/src/main/java/net/minecraft/world/level/EntityGetter.java -@@ -18,7 +18,7 @@ import net.minecraft.world.phys.shapes.BooleanOp; +@@ -15,7 +15,7 @@ import net.minecraft.world.phys.shapes.BooleanOp; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; @@ -27616,7 +27563,7 @@ index bd20bea7f76a7307f1698fb2dfef37125032d166..141b748abe80402731cdaf14a3d36aa7 List getEntities(@Nullable Entity except, AABB box, Predicate predicate); List getEntities(EntityTypeTest filter, AABB box, Predicate predicate); -@@ -33,21 +33,44 @@ public interface EntityGetter { +@@ -30,21 +30,44 @@ public interface EntityGetter { return this.getEntities(except, box, EntitySelector.NO_SPECTATORS); } @@ -27672,7 +27619,7 @@ index bd20bea7f76a7307f1698fb2dfef37125032d166..141b748abe80402731cdaf14a3d36aa7 } default List getEntitiesOfClass(Class entityClass, AABB box) { -@@ -55,23 +78,41 @@ public interface EntityGetter { +@@ -52,23 +75,41 @@ public interface EntityGetter { } default List getEntityCollisions(@Nullable Entity entity, AABB box) { @@ -27727,529 +27674,37 @@ index bd20bea7f76a7307f1698fb2dfef37125032d166..141b748abe80402731cdaf14a3d36aa7 } // Paper start - Affects Spawning API -diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index 2109257fde8606abda4f41427f690da3b96c0175..f696afd7e241bf1966a2d505b5d59bff824b43e4 100644 ---- a/src/main/java/net/minecraft/world/level/Explosion.java -+++ b/src/main/java/net/minecraft/world/level/Explosion.java -@@ -76,6 +76,247 @@ public class Explosion { - // CraftBukkit end - public boolean excludeSourceFromDamage = true; // Paper - Allow explosions to damage source +diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java +index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e86a982f8 100644 +--- a/src/main/java/net/minecraft/world/level/Level.java ++++ b/src/main/java/net/minecraft/world/level/Level.java +@@ -83,6 +83,7 @@ import net.minecraft.world.level.storage.LevelData; + import net.minecraft.world.level.storage.WritableLevelData; + import net.minecraft.world.phys.AABB; + import net.minecraft.world.phys.Vec3; ++import net.minecraft.world.phys.shapes.VoxelShape; + import net.minecraft.world.scores.Scoreboard; -+ // Paper start - optimise collisions -+ private static final double[] CACHED_RAYS; -+ static { -+ final it.unimi.dsi.fastutil.doubles.DoubleArrayList rayCoords = new it.unimi.dsi.fastutil.doubles.DoubleArrayList(); -+ -+ for (int x = 0; x <= 15; ++x) { -+ for (int y = 0; y <= 15; ++y) { -+ for (int z = 0; z <= 15; ++z) { -+ if ((x == 0 || x == 15) || (y == 0 || y == 15) || (z == 0 || z == 15)) { -+ double xDir = (double)((float)x / 15.0F * 2.0F - 1.0F); -+ double yDir = (double)((float)y / 15.0F * 2.0F - 1.0F); -+ double zDir = (double)((float)z / 15.0F * 2.0F - 1.0F); -+ -+ double mag = Math.sqrt( -+ xDir * xDir + yDir * yDir + zDir * zDir -+ ); -+ -+ rayCoords.add((xDir / mag) * (double)0.3F); -+ rayCoords.add((yDir / mag) * (double)0.3F); -+ rayCoords.add((zDir / mag) * (double)0.3F); -+ } -+ } -+ } -+ } + // CraftBukkit start +@@ -104,7 +105,7 @@ import org.bukkit.entity.SpawnCategory; + import org.bukkit.event.block.BlockPhysicsEvent; + // CraftBukkit end + +-public abstract class Level implements LevelAccessor, AutoCloseable { ++public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel, ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemEntityGetter, ca.spottedleaf.moonrise.patches.collisions.world.CollisionLevel { // Paper - rewrite chunk system // Paper - optimise collisions + + public static final Codec> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION); + public static final ResourceKey OVERWORLD = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld")); +@@ -190,6 +191,483 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + + public abstract ResourceKey getTypeKey(); + ++ // Paper start - rewrite chunk system ++ private ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup entityLookup; + -+ CACHED_RAYS = rayCoords.toDoubleArray(); -+ } -+ -+ private static final int CHUNK_CACHE_SHIFT = 2; -+ private static final int CHUNK_CACHE_MASK = (1 << CHUNK_CACHE_SHIFT) - 1; -+ private static final int CHUNK_CACHE_WIDTH = 1 << CHUNK_CACHE_SHIFT; -+ -+ private static final int BLOCK_EXPLOSION_CACHE_SHIFT = 3; -+ private static final int BLOCK_EXPLOSION_CACHE_MASK = (1 << BLOCK_EXPLOSION_CACHE_SHIFT) - 1; -+ private static final int BLOCK_EXPLOSION_CACHE_WIDTH = 1 << BLOCK_EXPLOSION_CACHE_SHIFT; -+ -+ // resistance = (res + 0.3F) * 0.3F; -+ // so for resistance = 0, we need res = -0.3F -+ private static final Float ZERO_RESISTANCE = Float.valueOf(-0.3f); -+ private it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap blockCache = null; -+ private long[] chunkPosCache = null; -+ private net.minecraft.world.level.chunk.LevelChunk[] chunkCache = null; -+ private ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache getOrCacheExplosionBlock(final int x, final int y, final int z, -+ final long key, final boolean calculateResistance) { -+ ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache ret = this.blockCache.get(key); -+ if (ret != null) { -+ return ret; -+ } -+ -+ BlockPos pos = new BlockPos(x, y, z); -+ -+ if (!this.level.isInWorldBounds(pos)) { -+ ret = new ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache(key, pos, null, null, 0.0f, true); -+ } else { -+ net.minecraft.world.level.chunk.LevelChunk chunk; -+ long chunkKey = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(x >> 4, z >> 4); -+ int chunkCacheKey = ((x >> 4) & CHUNK_CACHE_MASK) | (((z >> 4) << CHUNK_CACHE_SHIFT) & (CHUNK_CACHE_MASK << CHUNK_CACHE_SHIFT)); -+ if (this.chunkPosCache[chunkCacheKey] == chunkKey) { -+ chunk = this.chunkCache[chunkCacheKey]; -+ } else { -+ this.chunkPosCache[chunkCacheKey] = chunkKey; -+ this.chunkCache[chunkCacheKey] = chunk = this.level.getChunk(x >> 4, z >> 4); -+ } -+ -+ BlockState blockState = ((ca.spottedleaf.moonrise.patches.chunk_getblock.GetBlockChunk)chunk).moonrise$getBlock(x, y, z); -+ FluidState fluidState = blockState.getFluidState(); -+ -+ Optional resistance = !calculateResistance ? Optional.empty() : this.damageCalculator.getBlockExplosionResistance((Explosion)(Object)this, this.level, pos, blockState, fluidState); -+ -+ ret = new ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache( -+ key, pos, blockState, fluidState, -+ (resistance.orElse(ZERO_RESISTANCE).floatValue() + 0.3f) * 0.3f, -+ false -+ ); -+ } -+ -+ this.blockCache.put(key, ret); -+ -+ return ret; -+ } -+ -+ private boolean clipsAnything(final Vec3 from, final Vec3 to, -+ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext context, -+ final ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache[] blockCache, -+ final BlockPos.MutableBlockPos currPos) { -+ // assume that context.delegated = false -+ final double adjX = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON * (from.x - to.x); -+ final double adjY = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON * (from.y - to.y); -+ final double adjZ = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON * (from.z - to.z); -+ -+ if (adjX == 0.0 && adjY == 0.0 && adjZ == 0.0) { -+ return false; -+ } -+ -+ final double toXAdj = to.x - adjX; -+ final double toYAdj = to.y - adjY; -+ final double toZAdj = to.z - adjZ; -+ final double fromXAdj = from.x + adjX; -+ final double fromYAdj = from.y + adjY; -+ final double fromZAdj = from.z + adjZ; -+ -+ int currX = Mth.floor(fromXAdj); -+ int currY = Mth.floor(fromYAdj); -+ int currZ = Mth.floor(fromZAdj); -+ -+ final double diffX = toXAdj - fromXAdj; -+ final double diffY = toYAdj - fromYAdj; -+ final double diffZ = toZAdj - fromZAdj; -+ -+ final double dxDouble = Math.signum(diffX); -+ final double dyDouble = Math.signum(diffY); -+ final double dzDouble = Math.signum(diffZ); -+ -+ final int dx = (int)dxDouble; -+ final int dy = (int)dyDouble; -+ final int dz = (int)dzDouble; -+ -+ final double normalizedDiffX = diffX == 0.0 ? Double.MAX_VALUE : dxDouble / diffX; -+ final double normalizedDiffY = diffY == 0.0 ? Double.MAX_VALUE : dyDouble / diffY; -+ final double normalizedDiffZ = diffZ == 0.0 ? Double.MAX_VALUE : dzDouble / diffZ; -+ -+ double normalizedCurrX = normalizedDiffX * (diffX > 0.0 ? (1.0 - Mth.frac(fromXAdj)) : Mth.frac(fromXAdj)); -+ double normalizedCurrY = normalizedDiffY * (diffY > 0.0 ? (1.0 - Mth.frac(fromYAdj)) : Mth.frac(fromYAdj)); -+ double normalizedCurrZ = normalizedDiffZ * (diffZ > 0.0 ? (1.0 - Mth.frac(fromZAdj)) : Mth.frac(fromZAdj)); -+ -+ for (;;) { -+ currPos.set(currX, currY, currZ); -+ -+ // ClipContext.Block.COLLIDER -> BlockBehaviour.BlockStateBase::getCollisionShape -+ // ClipContext.Fluid.NONE -> ignore fluids -+ -+ // read block from cache -+ final long key = BlockPos.asLong(currX, currY, currZ); -+ -+ final int cacheKey = -+ (currX & BLOCK_EXPLOSION_CACHE_MASK) | -+ (currY & BLOCK_EXPLOSION_CACHE_MASK) << (BLOCK_EXPLOSION_CACHE_SHIFT) | -+ (currZ & BLOCK_EXPLOSION_CACHE_MASK) << (BLOCK_EXPLOSION_CACHE_SHIFT + BLOCK_EXPLOSION_CACHE_SHIFT); -+ ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache cachedBlock = blockCache[cacheKey]; -+ if (cachedBlock == null || cachedBlock.key != key) { -+ blockCache[cacheKey] = cachedBlock = this.getOrCacheExplosionBlock(currX, currY, currZ, key, false); -+ } -+ -+ final BlockState blockState = cachedBlock.blockState; -+ if (blockState != null && !((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockState).moonrise$emptyCollisionShape()) { -+ net.minecraft.world.phys.shapes.VoxelShape collision = cachedBlock.cachedCollisionShape; -+ if (collision == null) { -+ collision = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockState).moonrise$getConstantCollisionShape(); -+ if (collision == null) { -+ collision = blockState.getCollisionShape(this.level, currPos, context); -+ if (!context.isDelegated()) { -+ // if it was not delegated during this call, assume that for any future ones it will not be delegated -+ // again, and cache the result -+ cachedBlock.cachedCollisionShape = collision; -+ } -+ } else { -+ cachedBlock.cachedCollisionShape = collision; -+ } -+ } -+ -+ if (!collision.isEmpty() && collision.clip(from, to, currPos) != null) { -+ return true; -+ } -+ } -+ -+ if (normalizedCurrX > 1.0 && normalizedCurrY > 1.0 && normalizedCurrZ > 1.0) { -+ return false; -+ } -+ -+ // inc the smallest normalized coordinate -+ -+ if (normalizedCurrX < normalizedCurrY) { -+ if (normalizedCurrX < normalizedCurrZ) { -+ currX += dx; -+ normalizedCurrX += normalizedDiffX; -+ } else { -+ // x < y && x >= z <--> z < y && z <= x -+ currZ += dz; -+ normalizedCurrZ += normalizedDiffZ; -+ } -+ } else if (normalizedCurrY < normalizedCurrZ) { -+ // y <= x && y < z -+ currY += dy; -+ normalizedCurrY += normalizedDiffY; -+ } else { -+ // y <= x && z <= y <--> z <= y && z <= x -+ currZ += dz; -+ normalizedCurrZ += normalizedDiffZ; -+ } -+ } -+ } -+ -+ private float getSeenFraction(final Vec3 source, final Entity target, -+ final ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache[] blockCache, -+ final BlockPos.MutableBlockPos blockPos) { -+ final AABB boundingBox = target.getBoundingBox(); -+ final double diffX = boundingBox.maxX - boundingBox.minX; -+ final double diffY = boundingBox.maxY - boundingBox.minY; -+ final double diffZ = boundingBox.maxZ - boundingBox.minZ; -+ -+ final double incX = 1.0 / (diffX * 2.0 + 1.0); -+ final double incY = 1.0 / (diffY * 2.0 + 1.0); -+ final double incZ = 1.0 / (diffZ * 2.0 + 1.0); -+ -+ if (incX < 0.0 || incY < 0.0 || incZ < 0.0) { -+ return 0.0f; -+ } -+ -+ final double offX = (1.0 - Math.floor(1.0 / incX) * incX) * 0.5 + boundingBox.minX; -+ final double offY = boundingBox.minY; -+ final double offZ = (1.0 - Math.floor(1.0 / incZ) * incZ) * 0.5 + boundingBox.minZ; -+ -+ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext context = new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext(target); -+ -+ int totalRays = 0; -+ int missedRays = 0; -+ -+ for (double dx = 0.0; dx <= 1.0; dx += incX) { -+ final double fromX = Math.fma(dx, diffX, offX); -+ for (double dy = 0.0; dy <= 1.0; dy += incY) { -+ final double fromY = Math.fma(dy, diffY, offY); -+ for (double dz = 0.0; dz <= 1.0; dz += incZ) { -+ ++totalRays; -+ -+ final Vec3 from = new Vec3( -+ fromX, -+ fromY, -+ Math.fma(dz, diffZ, offZ) -+ ); -+ -+ if (!this.clipsAnything(from, source, context, blockCache, blockPos)) { -+ ++missedRays; -+ } -+ } -+ } -+ } -+ -+ return (float)missedRays / (float)totalRays; -+ } -+ // Paper end - optimise collisions -+ - public static DamageSource getDefaultDamageSource(Level world, @Nullable Entity source) { - return world.damageSources().explosion(source, Explosion.getIndirectSourceEntityInternal(source)); - } -@@ -168,68 +409,107 @@ public class Explosion { - } - // CraftBukkit end - this.level.gameEvent(this.source, (Holder) GameEvent.EXPLODE, new Vec3(this.x, this.y, this.z)); -- Set set = Sets.newHashSet(); -+ -+ // Paper start - collision optimisations -+ this.blockCache = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>(); -+ -+ this.chunkPosCache = new long[CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH]; -+ java.util.Arrays.fill(this.chunkPosCache, ChunkPos.INVALID_CHUNK_POS); -+ -+ this.chunkCache = new net.minecraft.world.level.chunk.LevelChunk[CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH]; -+ -+ final ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache[] blockCache = new ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache[BLOCK_EXPLOSION_CACHE_WIDTH * BLOCK_EXPLOSION_CACHE_WIDTH * BLOCK_EXPLOSION_CACHE_WIDTH]; -+ -+ // use initial cache value that is most likely to be used: the source position -+ final ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache initialCache; -+ { -+ final int blockX = Mth.floor(this.x); -+ final int blockY = Mth.floor(this.y); -+ final int blockZ = Mth.floor(this.z); -+ -+ final long key = BlockPos.asLong(blockX, blockY, blockZ); -+ -+ initialCache = this.getOrCacheExplosionBlock(blockX, blockY, blockZ, key, true); -+ } -+ // Paper end - collision optimisations -+ - boolean flag = true; - - int i; - int j; - -- for (int k = 0; k < 16; ++k) { -- for (i = 0; i < 16; ++i) { -- for (j = 0; j < 16; ++j) { -- if (k == 0 || k == 15 || i == 0 || i == 15 || j == 0 || j == 15) { -- double d0 = (double) ((float) k / 15.0F * 2.0F - 1.0F); -- double d1 = (double) ((float) i / 15.0F * 2.0F - 1.0F); -- double d2 = (double) ((float) j / 15.0F * 2.0F - 1.0F); -- double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2); -- -- d0 /= d3; -- d1 /= d3; -- d2 /= d3; -- float f = this.radius * (0.7F + this.level.random.nextFloat() * 0.6F); -- double d4 = this.x; -- double d5 = this.y; -- double d6 = this.z; -- -- for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) { -- BlockPos blockposition = BlockPos.containing(d4, d5, d6); -- BlockState iblockdata = this.level.getBlockState(blockposition); -- if (!iblockdata.isDestroyable()) continue; // Paper - Protect Bedrock and End Portal/Frames from being destroyed -- FluidState fluid = iblockdata.getFluidState(); // Paper - Perf: Optimize call to getFluid for explosions -- -- if (!this.level.isInWorldBounds(blockposition)) { -- break; -+ // Paper start - collision optimisations -+ for (int ray = 0, len = CACHED_RAYS.length; ray < len;) { -+ ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache cachedBlock = initialCache; -+ -+ double currX = this.x; -+ double currY = this.y; -+ double currZ = this.z; -+ -+ final double incX = CACHED_RAYS[ray]; -+ final double incY = CACHED_RAYS[ray + 1]; -+ final double incZ = CACHED_RAYS[ray + 2]; -+ -+ ray += 3; -+ float power = this.radius * (0.7F + this.level.random.nextFloat() * 0.6F); -+ do { -+ final int blockX = Mth.floor(currX); -+ final int blockY = Mth.floor(currY); -+ final int blockZ = Mth.floor(currZ); -+ -+ final long key = BlockPos.asLong(blockX, blockY, blockZ); -+ -+ if (cachedBlock.key != key) { -+ final int cacheKey = -+ (blockX & BLOCK_EXPLOSION_CACHE_MASK) | -+ (blockY & BLOCK_EXPLOSION_CACHE_MASK) << (BLOCK_EXPLOSION_CACHE_SHIFT) | -+ (blockZ & BLOCK_EXPLOSION_CACHE_MASK) << (BLOCK_EXPLOSION_CACHE_SHIFT + BLOCK_EXPLOSION_CACHE_SHIFT); -+ cachedBlock = blockCache[cacheKey]; -+ if (cachedBlock == null || cachedBlock.key != key) { -+ blockCache[cacheKey] = cachedBlock = this.getOrCacheExplosionBlock(blockX, blockY, blockZ, key, true); -+ } - } - -- Optional optional = this.damageCalculator.getBlockExplosionResistance(this, this.level, blockposition, iblockdata, fluid); -- -- if (optional.isPresent()) { -- f -= ((Float) optional.get() + 0.3F) * 0.3F; -+ if (cachedBlock.outOfWorld) { -+ break; - } -- -- if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this, this.level, blockposition, iblockdata, f)) { -- set.add(blockposition); -- // Paper start - prevent headless pistons from forming -- if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowHeadlessPistons && iblockdata.getBlock() == Blocks.MOVING_PISTON) { -- net.minecraft.world.level.block.entity.BlockEntity extension = this.level.getBlockEntity(blockposition); -- if (extension instanceof net.minecraft.world.level.block.piston.PistonMovingBlockEntity blockEntity && blockEntity.isSourcePiston()) { -- net.minecraft.core.Direction direction = iblockdata.getValue(net.minecraft.world.level.block.piston.PistonHeadBlock.FACING); -- set.add(blockposition.relative(direction.getOpposite())); -+ // Paper end - collision optimisations -+ BlockState iblockdata = cachedBlock.blockState; // Paper - optimise collisions -+ // Paper - collision optimisations -+ -+ // Paper start - collision optimisations -+ power -= cachedBlock.resistance; -+ -+ if (power > 0.0f && cachedBlock.shouldExplode == null && iblockdata.isDestroyable()) { // Paper - Protect Bedrock and End Portal/Frames from being destroyed -+ // note: we expect shouldBlockExplode to be pure with respect to power, as Vanilla currently is. -+ // basically, it is unused, which allows us to cache the result -+ final boolean shouldExplode = this.damageCalculator.shouldBlockExplode((Explosion)(Object)this, this.level, cachedBlock.immutablePos, cachedBlock.blockState, power); -+ cachedBlock.shouldExplode = shouldExplode ? Boolean.TRUE : Boolean.FALSE; -+ if (shouldExplode) { -+ if (this.fire || !cachedBlock.blockState.isAir()) { -+ this.toBlow.add(cachedBlock.immutablePos); -+ // Paper start - prevent headless pistons from forming -+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowHeadlessPistons && iblockdata.getBlock() == Blocks.MOVING_PISTON) { -+ net.minecraft.world.level.block.entity.BlockEntity extension = this.level.getBlockEntity(cachedBlock.immutablePos); // Paper - optimise collisions -+ if (extension instanceof net.minecraft.world.level.block.piston.PistonMovingBlockEntity blockEntity && blockEntity.isSourcePiston()) { -+ net.minecraft.core.Direction direction = iblockdata.getValue(net.minecraft.world.level.block.piston.PistonHeadBlock.FACING); -+ this.toBlow.add(cachedBlock.immutablePos.relative(direction.getOpposite())); // Paper - optimise collisions -+ } -+ } -+ // Paper end - prevent headless pistons from forming - } - } -- // Paper end - prevent headless pistons from forming - } - -- d4 += d0 * 0.30000001192092896D; -- d5 += d1 * 0.30000001192092896D; -- d6 += d2 * 0.30000001192092896D; -- } -+ power -= 0.22500001F; -+ currX += incX; -+ currY += incY; -+ currZ += incZ; -+ } while (power > 0.0f); -+ // Paper end - collision optimisations - } -- } -- } -- } - -- this.toBlow.addAll(set); -+ // Paper - optimise collisions - float f2 = this.radius * 2.0F; - - i = Mth.floor(this.x - (double) f2 - 1.0D); -@@ -242,6 +522,10 @@ public class Explosion { - Vec3 vec3d = new Vec3(this.x, this.y, this.z); - Iterator iterator = list.iterator(); - -+ // Paper start - optimise collisions -+ final BlockPos.MutableBlockPos blockPos = new BlockPos.MutableBlockPos(); -+ // Paper end - optimise collisions -+ - while (iterator.hasNext()) { - Entity entity = (Entity) iterator.next(); - -@@ -258,6 +542,7 @@ public class Explosion { - d8 /= d11; - d9 /= d11; - d10 /= d11; -+ final double seenFraction; // Paper - optimise collisions - if (this.damageCalculator.shouldDamageEntity(this, entity)) { - // CraftBukkit start - -@@ -273,6 +558,8 @@ public class Explosion { - - entity.lastDamageCancelled = false; - -+ seenFraction = (double)this.getBlockDensity(vec3d, entity, blockCache, blockPos); // Paper - optimise collisions -+ - if (entity instanceof EnderDragon) { - for (EnderDragonPart entityComplexPart : ((EnderDragon) entity).subEntities) { - // Calculate damage separately for each EntityComplexPart -@@ -281,16 +568,21 @@ public class Explosion { - } - } - } else { -- entity.hurt(this.damageSource, this.damageCalculator.getEntityDamageAmount(this, entity)); -+ // Paper start - optimise collisions -+ // inline getEntityDamageAmount so that we can avoid double calling getSeenPercent, which is the MOST -+ // expensive part of this loop!!!! -+ final double factor = (1.0 - d7) * seenFraction; -+ entity.hurt(this.damageSource, (float)((factor * factor + factor) / 2.0 * 7.0 * (double)f2 + 1.0)); -+ // Paper end - optimise collisions - } - - if (entity.lastDamageCancelled) { // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Skip entity if damage event was cancelled - continue; - } - // CraftBukkit end -- } -+ } else { seenFraction = (double)this.getBlockDensity(vec3d, entity, blockCache, blockPos); } // Paper - optimise collisions - -- double d12 = (1.0D - d7) * this.getBlockDensity(vec3d, entity) * (double) this.damageCalculator.getKnockbackMultiplier(entity); // Paper - Optimize explosions -+ double d12 = (1.0D - d7) * seenFraction * (double) this.damageCalculator.getKnockbackMultiplier(entity); // Paper - Optimize explosions // Paper - optimise collisions - double d13; - - if (entity instanceof LivingEntity) { -@@ -328,7 +620,11 @@ public class Explosion { - } - } - } -- -+ // Paper start - optimise collisions -+ this.blockCache = null; -+ this.chunkPosCache = null; -+ this.chunkCache = null; -+ // Paper end - optimise collisions - } - - public void finalizeExplosion(boolean particles) { -@@ -545,14 +841,14 @@ public class Explosion { - private BlockInteraction() {} - } - // Paper start - Optimize explosions -- private float getBlockDensity(Vec3 vec3d, Entity entity) { -+ private float getBlockDensity(Vec3 vec3d, Entity entity, ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache[] blockCache, BlockPos.MutableBlockPos blockPos) { // Paper - optimise collisions - if (!this.level.paperConfig().environment.optimizeExplosions) { -- return getSeenPercent(vec3d, entity); -+ return this.getSeenFraction(vec3d, entity, blockCache, blockPos); // Paper - optimise collisions - } - CacheKey key = new CacheKey(this, entity.getBoundingBox()); - Float blockDensity = this.level.explosionDensityCache.get(key); - if (blockDensity == null) { -- blockDensity = getSeenPercent(vec3d, entity); -+ blockDensity = this.getSeenFraction(vec3d, entity, blockCache, blockPos); // Paper - optimise collisions - this.level.explosionDensityCache.put(key, blockDensity); - } - -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 16e721ac80ba21511bdeccfccd055f7700bda61f..7a592a3c5491fc19ab33287e1e60b869a618497c 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -81,6 +81,7 @@ import net.minecraft.world.level.storage.LevelData; - import net.minecraft.world.level.storage.WritableLevelData; - import net.minecraft.world.phys.AABB; - import net.minecraft.world.phys.Vec3; -+import net.minecraft.world.phys.shapes.VoxelShape; - import net.minecraft.world.scores.Scoreboard; - - // CraftBukkit start -@@ -102,7 +103,7 @@ import org.bukkit.entity.SpawnCategory; - import org.bukkit.event.block.BlockPhysicsEvent; - // CraftBukkit end - --public abstract class Level implements LevelAccessor, AutoCloseable { -+public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel, ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemEntityGetter, ca.spottedleaf.moonrise.patches.collisions.world.CollisionLevel { // Paper - rewrite chunk system // Paper - optimise collisions - - public static final Codec> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION); - public static final ResourceKey OVERWORLD = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld")); -@@ -199,6 +200,483 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - - public abstract ResourceKey getTypeKey(); - -+ // Paper start - rewrite chunk system -+ private ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup entityLookup; -+ -+ @Override -+ public final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup moonrise$getEntityLookup() { -+ return this.entityLookup; ++ @Override ++ public final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup moonrise$getEntityLookup() { ++ return this.entityLookup; + } + + @Override @@ -28721,10 +28176,10 @@ index 16e721ac80ba21511bdeccfccd055f7700bda61f..7a592a3c5491fc19ab33287e1e60b869 + } + // Paper end - optimise random ticking + - protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator) { // Paper - create paper world config + protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator) { // Paper - create paper world config this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config -@@ -281,6 +759,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -271,6 +749,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime); this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); @@ -28736,7 +28191,7 @@ index 16e721ac80ba21511bdeccfccd055f7700bda61f..7a592a3c5491fc19ab33287e1e60b869 } // Paper start - Cancel hit for vanished players -@@ -549,7 +1032,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -535,7 +1018,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.setBlocksDirty(blockposition, iblockdata1, iblockdata2); } @@ -28745,7 +28200,7 @@ index 16e721ac80ba21511bdeccfccd055f7700bda61f..7a592a3c5491fc19ab33287e1e60b869 this.sendBlockUpdated(blockposition, iblockdata1, iblockdata, i); } -@@ -813,6 +1296,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -800,6 +1283,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Iterator iterator = this.blockEntityTickers.iterator(); boolean flag = this.tickRateManager().runsNormally(); @@ -28754,7 +28209,7 @@ index 16e721ac80ba21511bdeccfccd055f7700bda61f..7a592a3c5491fc19ab33287e1e60b869 int tilesThisCycle = 0; var toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet(); // Paper - Fix MC-117075; use removeAll toRemove.add(null); // Paper - Fix MC-117075 -@@ -828,6 +1313,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -815,6 +1300,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Spigot end } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { tickingblockentity.tick(); @@ -28766,7 +28221,7 @@ index 16e721ac80ba21511bdeccfccd055f7700bda61f..7a592a3c5491fc19ab33287e1e60b869 } } this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 -@@ -850,12 +1340,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -837,12 +1327,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable { entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Paper end - Prevent block entity and entity crashes } @@ -28788,7 +28243,7 @@ index 16e721ac80ba21511bdeccfccd055f7700bda61f..7a592a3c5491fc19ab33287e1e60b869 } // Paper end - Option to prevent armor stands from doing entity lookups -@@ -966,7 +1464,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -894,7 +1392,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } // Paper end - Perf: Optimize capturedTileEntities lookup // CraftBukkit end @@ -28797,24 +28252,22 @@ index 16e721ac80ba21511bdeccfccd055f7700bda61f..7a592a3c5491fc19ab33287e1e60b869 } public void setBlockEntity(BlockEntity blockEntity) { -@@ -1056,28 +1554,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - @Override - public List getEntities(@Nullable Entity except, AABB box, Predicate predicate) { - this.getProfiler().incrementCounter("getEntities"); -- List list = Lists.newArrayList(); -+ // Paper start - rewrite chunk system -+ final List ret = new java.util.ArrayList<>(); +@@ -986,26 +1484,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + Profiler.get().incrementCounter("getEntities"); + List list = Lists.newArrayList(); - this.getEntities().get(box, (entity1) -> { - if (entity1 != except && predicate.test(entity1)) { - list.add(entity1); - } -+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities(except, box, ret, predicate); ++ // Paper start - rewrite chunk system ++ final List ret = new java.util.ArrayList<>(); - if (entity1 instanceof EnderDragon) { - EnderDragonPart[] aentitycomplexpart = ((EnderDragon) entity1).getSubEntities(); - int i = aentitycomplexpart.length; -- ++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities(except, box, ret, predicate); + - for (int j = 0; j < i; ++j) { - EnderDragonPart entitycomplexpart = aentitycomplexpart[j]; - @@ -28831,22 +28284,23 @@ index 16e721ac80ba21511bdeccfccd055f7700bda61f..7a592a3c5491fc19ab33287e1e60b869 } @Override -@@ -1092,36 +1575,77 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1020,36 +1505,77 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.getEntities(filter, box, predicate, result, Integer.MAX_VALUE); } - public void getEntities(EntityTypeTest filter, AABB box, Predicate predicate, List result, int limit) { -+ // Paper start - rewrite chunk system -+ public void getEntities(final EntityTypeTest entityTypeTest, -+ final AABB boundingBox, final Predicate predicate, -+ final List into, final int maxCount) { - this.getProfiler().incrementCounter("getEntities"); +- Profiler.get().incrementCounter("getEntities"); - this.getEntities().get(filter, box, (entity) -> { - if (predicate.test(entity)) { - result.add(entity); - if (result.size() >= limit) { - return AbortableIterationConsumer.Continuation.ABORT; - } ++ // Paper start - rewrite chunk system ++ public void getEntities(final EntityTypeTest entityTypeTest, ++ final AABB boundingBox, final Predicate predicate, ++ final List into, final int maxCount) { ++ this.getProfiler().incrementCounter("getEntities"); + + if (entityTypeTest instanceof net.minecraft.world.entity.EntityType byType) { + if (maxCount != Integer.MAX_VALUE) { @@ -28931,7 +28385,7 @@ index 16e721ac80ba21511bdeccfccd055f7700bda61f..7a592a3c5491fc19ab33287e1e60b869 @Nullable public abstract Entity getEntity(int id); diff --git a/src/main/java/net/minecraft/world/level/LevelReader.java b/src/main/java/net/minecraft/world/level/LevelReader.java -index a0ae26d6197e1069ca09982b4f8b706c55ae8491..1a4dc4b2561dbaf01246b4fb46266b1ac84008b8 100644 +index 5eb8982678110fabb82a93c5ec67c666b7fde017..ade435de0af4ee3566fa4a490df53cddd2f6531c 100644 --- a/src/main/java/net/minecraft/world/level/LevelReader.java +++ b/src/main/java/net/minecraft/world/level/LevelReader.java @@ -22,7 +22,18 @@ import net.minecraft.world.level.dimension.DimensionType; @@ -28955,20 +28409,20 @@ index a0ae26d6197e1069ca09982b4f8b706c55ae8491..1a4dc4b2561dbaf01246b4fb46266b1a ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create); diff --git a/src/main/java/net/minecraft/world/level/biome/Biome.java b/src/main/java/net/minecraft/world/level/biome/Biome.java -index 15f82c9a1ce1fef2e951d1b3c7a65e64b82061ea..90c165c890a2d998e3b0af9b4310e3995ede6f64 100644 +index 8590de51b572c0f73d45aee60313d466e4671da5..b725eea9d3ca81d2ef7802f5d0346d924aa1f808 100644 --- a/src/main/java/net/minecraft/world/level/biome/Biome.java +++ b/src/main/java/net/minecraft/world/level/biome/Biome.java -@@ -111,20 +111,7 @@ public final class Biome { +@@ -112,20 +112,7 @@ public final class Biome { @Deprecated - public float getTemperature(BlockPos blockPos) { + public float getTemperature(BlockPos blockPos, int seaLevel) { - long l = blockPos.asLong(); - Long2FloatLinkedOpenHashMap long2FloatLinkedOpenHashMap = this.temperatureCache.get(); - float f = long2FloatLinkedOpenHashMap.get(l); - if (!Float.isNaN(f)) { - return f; - } else { -- float g = this.getHeightAdjustedTemperature(blockPos); +- float g = this.getHeightAdjustedTemperature(blockPos, seaLevel); - if (long2FloatLinkedOpenHashMap.size() == 1024) { - long2FloatLinkedOpenHashMap.removeFirstFloat(); - } @@ -28976,15 +28430,15 @@ index 15f82c9a1ce1fef2e951d1b3c7a65e64b82061ea..90c165c890a2d998e3b0af9b4310e399 - long2FloatLinkedOpenHashMap.put(l, g); - return g; - } -+ return this.getHeightAdjustedTemperature(blockPos); // Paper - optimise random ticking ++ return this.getHeightAdjustedTemperature(blockPos, seaLevel); // Paper - optimise random ticking } public boolean shouldFreeze(LevelReader world, BlockPos blockPos) { diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index 3b06c080afebde1d649f05eca0af938ba32931c1..29947de9eb6887f2e61516523ff08d8b581b0f53 100644 +index 4d140bd83ca0e1554afad80ec4fc6186188a79d8..3dd236d39535cfce866eb73673f8d7f1b6dc535c 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -279,7 +279,7 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -265,7 +265,7 @@ public class Block extends BlockBehaviour implements ItemLike { } public static boolean isShapeFullBlock(VoxelShape shape) { @@ -28994,21 +28448,21 @@ index 3b06c080afebde1d649f05eca0af938ba32931c1..29947de9eb6887f2e61516523ff08d8b public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) {} diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -index f2036917c5ba9f536087d7ee559704055469730e..d0109633e8bdf109cfc9178963d7b6cf92f8b189 100644 +index 0665ca48fe2f8ab1ce1c0306b11be19b06445f74..a4b4fd83d201fff005c738c84fa5c1bc55d670bd 100644 --- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -@@ -763,7 +763,7 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -793,7 +793,7 @@ public abstract class BlockBehaviour implements FeatureElement { boolean test(BlockState state, BlockGetter world, BlockPos pos); } - public abstract static class BlockStateBase extends StateHolder { + public abstract static class BlockStateBase extends StateHolder implements ca.spottedleaf.moonrise.patches.starlight.blockstate.StarlightAbstractBlockState, ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState { // Paper - rewrite chunk system // Paper - optimise collisions - private final int lightEmission; - private final boolean useShapeForLightOcclusion; -@@ -795,6 +795,76 @@ public abstract class BlockBehaviour implements FeatureElement { - private FluidState fluidState; - private boolean isRandomlyTicking; + private static final Direction[] DIRECTIONS = Direction.values(); + private static final VoxelShape[] EMPTY_OCCLUSION_SHAPES = (VoxelShape[]) Util.make(new VoxelShape[BlockBehaviour.BlockStateBase.DIRECTIONS.length], (avoxelshape) -> { +@@ -837,6 +837,76 @@ public abstract class BlockBehaviour implements FeatureElement { + private boolean propagatesSkylightDown; + private int lightBlock; + // Paper start - rewrite chunk system + private int opacityIfCached; @@ -29083,10 +28537,10 @@ index f2036917c5ba9f536087d7ee559704055469730e..d0109633e8bdf109cfc9178963d7b6cf protected BlockStateBase(Block block, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { super(block, propertyMap, codec); this.fluidState = Fluids.EMPTY.defaultFluidState(); -@@ -859,6 +929,43 @@ public abstract class BlockBehaviour implements FeatureElement { - this.shapeExceedsCube = this.cache == null || this.cache.largeCollisionShape; // Paper - moved from actual method to here +@@ -921,6 +991,43 @@ public abstract class BlockBehaviour implements FeatureElement { - this.legacySolid = this.calculateSolid(); + this.propagatesSkylightDown = ((Block) this.owner).propagatesSkylightDown(this.asState()); + this.lightBlock = ((Block) this.owner).getLightBlock(this.asState()); + // Paper start - rewrite chunk system + this.isConditionallyFullOpaque = this.canOcclude & this.useShapeForLightOcclusion; + this.opacityIfCached = this.cache == null || this.isConditionallyFullOpaque ? -1 : this.cache.lightBlock; @@ -29128,19 +28582,19 @@ index f2036917c5ba9f536087d7ee559704055469730e..d0109633e8bdf109cfc9178963d7b6cf public Block getBlock() { diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -index db4d95ce98eb1490d5306d1f74b282d27264871a..fba548c4e6d589323ec3ea5f6b269a6fe9faf6a1 100644 +index 37795b9e264c571efe9c718fa9996197dca4ed54..0601f454758cb1447cca2cbff4ef5fd7633fece5 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -@@ -57,7 +57,7 @@ import net.minecraft.world.ticks.SerializableTickContainer; +@@ -57,7 +57,7 @@ import net.minecraft.world.ticks.SavedTick; import net.minecraft.world.ticks.TickContainerAccess; import org.slf4j.Logger; --public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiomeSource, LightChunk, StructureAccess { -+public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiomeSource, LightChunk, StructureAccess, ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk { // Paper - rewrite chunk system +-public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, LightChunk, StructureAccess { ++public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, LightChunk, StructureAccess, ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk { // Paper - rewrite chunk system public static final int NO_FILLED_SECTION = -1; private static final Logger LOGGER = LogUtils.getLogger(); -@@ -77,7 +77,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom +@@ -77,7 +77,7 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh @Nullable protected BlendingData blendingData; public final Map heightmaps = Maps.newEnumMap(Heightmap.Types.class); @@ -29149,7 +28603,7 @@ index db4d95ce98eb1490d5306d1f74b282d27264871a..fba548c4e6d589323ec3ea5f6b269a6f private final Map structureStarts = Maps.newHashMap(); private final Map structuresRefences = Maps.newHashMap(); protected final Map pendingBlockEntities = Maps.newHashMap(); -@@ -90,6 +90,57 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom +@@ -90,6 +90,57 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh public org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer(ChunkAccess.DATA_TYPE_REGISTRY); // CraftBukkit end @@ -29207,7 +28661,7 @@ index db4d95ce98eb1490d5306d1f74b282d27264871a..fba548c4e6d589323ec3ea5f6b269a6f public ChunkAccess(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor heightLimitView, Registry biomeRegistry, long inhabitedTime, @Nullable LevelChunkSection[] sectionArray, @Nullable BlendingData blendingData) { this.locX = pos.x; this.locZ = pos.z; // Paper - reduce need for field lookups this.chunkPos = pos; this.coordinateKey = ChunkPos.asLong(locX, locZ); // Paper - cache long key -@@ -99,7 +150,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom +@@ -99,7 +150,7 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh this.inhabitedTime = inhabitedTime; this.postProcessing = new ShortList[heightLimitView.getSectionsCount()]; this.blendingData = blendingData; @@ -29216,7 +28670,7 @@ index db4d95ce98eb1490d5306d1f74b282d27264871a..fba548c4e6d589323ec3ea5f6b269a6f if (sectionArray != null) { if (this.sections.length == sectionArray.length) { System.arraycopy(sectionArray, 0, this.sections, 0, this.sections.length); -@@ -111,6 +162,16 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom +@@ -111,6 +162,16 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh ChunkAccess.replaceMissingSections(biomeRegistry, this.sections); // CraftBukkit start this.biomeRegistry = biomeRegistry; @@ -29233,12 +28687,12 @@ index db4d95ce98eb1490d5306d1f74b282d27264871a..fba548c4e6d589323ec3ea5f6b269a6f } public final Registry biomeRegistry; // CraftBukkit end -@@ -442,22 +503,22 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom +@@ -451,22 +512,22 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh @Override public Holder getNoiseBiome(int biomeX, int biomeY, int biomeZ) { - try { -- int l = QuartPos.fromBlock(this.getMinBuildHeight()); +- int l = QuartPos.fromBlock(this.getMinY()); - int i1 = l + QuartPos.fromBlock(this.getHeight()) - 1; - int j1 = Mth.clamp(biomeY, l, i1); - int k1 = this.getSectionIndex(QuartPos.toBlock(j1)); @@ -29271,7 +28725,7 @@ index db4d95ce98eb1490d5306d1f74b282d27264871a..fba548c4e6d589323ec3ea5f6b269a6f } // CraftBukkit start -@@ -514,12 +575,12 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom +@@ -523,12 +584,12 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh } public void initializeLightSources() { @@ -29285,21 +28739,21 @@ index db4d95ce98eb1490d5306d1f74b282d27264871a..fba548c4e6d589323ec3ea5f6b269a6f + return null; // Paper - rewrite chunk system } - public static record TicksToSave(SerializableTickContainer blocks, SerializableTickContainer fluids) { + public static record PackedTicks(List> blocks, List> fluids) { diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index 29697fad32dad3377eebc82d280ba48d3c1ad516..488938c32a48437721a71d294c77468f00c035b9 100644 +index 906f56d07c26ef3c2dc1a3b62e9349dd91a37742..975abf5948a75c7d0cab8f052af2c4e91bcef2a8 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -119,7 +119,7 @@ public abstract class ChunkGenerator { - return CompletableFuture.supplyAsync(Util.wrapThreadWithTaskName("init_biomes", () -> { + return CompletableFuture.supplyAsync(() -> { chunk.fillBiomesFromNoise(this.biomeSource, noiseConfig.sampler()); return chunk; -- }), Util.backgroundExecutor()); -+ }), Runnable::run); // Paper - rewrite chunk system +- }, Util.backgroundExecutor().forName("init_biomes")); ++ }, Runnable::run); // Paper - rewrite chunk system } - public abstract void applyCarvers(WorldGenRegion chunkRegion, long seed, RandomState noiseConfig, BiomeManager biomeAccess, StructureManager structureAccessor, ChunkAccess chunk, GenerationStep.Carving carverStep); -@@ -314,7 +314,7 @@ public abstract class ChunkGenerator { + public abstract void applyCarvers(WorldGenRegion chunkRegion, long seed, RandomState noiseConfig, BiomeManager biomeAccess, StructureManager structureAccessor, ChunkAccess chunk); +@@ -311,7 +311,7 @@ public abstract class ChunkGenerator { return Pair.of(placement.getLocatePos(pos), holder); } @@ -29363,10 +28817,10 @@ index dcc0acd259920463a4464213b9a5e793603852f9..ef4161884574d3d137e12591d983dc95 public BlockState getBlockState(BlockPos pos) { return Blocks.VOID_AIR.defaultBlockState(); diff --git a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java -index 365074be989aa4a178114fd5e9810f1a68640196..4af698930712389881601069a921f054c07935f2 100644 +index 7cce66d4c6efe6fd3cc22a6acf72878c964c61ae..30ee3df2278d0d9bd7478b49eda5fff27b8a504c 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java -@@ -31,7 +31,7 @@ import net.minecraft.world.level.material.FluidState; +@@ -30,7 +30,7 @@ import net.minecraft.world.level.material.FluidState; import net.minecraft.world.ticks.BlackholeTickAccess; import net.minecraft.world.ticks.TickContainerAccess; @@ -29375,7 +28829,7 @@ index 365074be989aa4a178114fd5e9810f1a68640196..4af698930712389881601069a921f054 private final LevelChunk wrapped; private final boolean allowWrites; -@@ -47,6 +47,48 @@ public class ImposterProtoChunk extends ProtoChunk { +@@ -46,6 +46,48 @@ public class ImposterProtoChunk extends ProtoChunk { this.allowWrites = propagateToWrapped; } @@ -29425,10 +28879,10 @@ index 365074be989aa4a178114fd5e9810f1a68640196..4af698930712389881601069a921f054 @Override public BlockEntity getBlockEntity(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 21946a93b6a2a3c79d15af1d6e7eabc537ba0125..d94e24cfc56c195a47665c212f8fcc901648a4a1 100644 +index 7181acfafad91aa5f6ab7ce663d9be4a1b65b02a..a61294befc2f855fcecb2336a2d5444ce60e0a3a 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -53,7 +53,7 @@ import net.minecraft.world.ticks.LevelChunkTicks; +@@ -54,7 +54,7 @@ import net.minecraft.world.ticks.LevelChunkTicks; import net.minecraft.world.ticks.TickContainerAccess; import org.slf4j.Logger; @@ -29437,7 +28891,7 @@ index 21946a93b6a2a3c79d15af1d6e7eabc537ba0125..d94e24cfc56c195a47665c212f8fcc90 static final Logger LOGGER = LogUtils.getLogger(); private static final TickingBlockEntity NULL_TICKER = new TickingBlockEntity() { -@@ -109,6 +109,14 @@ public class LevelChunk extends ChunkAccess { +@@ -113,6 +113,14 @@ public class LevelChunk extends ChunkAccess { this.postLoad = entityLoader; this.blockTicks = blockTickScheduler; this.fluidTicks = fluidTickScheduler; @@ -29452,7 +28906,7 @@ index 21946a93b6a2a3c79d15af1d6e7eabc537ba0125..d94e24cfc56c195a47665c212f8fcc90 } // CraftBukkit start -@@ -119,6 +127,39 @@ public class LevelChunk extends ChunkAccess { +@@ -123,6 +131,39 @@ public class LevelChunk extends ChunkAccess { // Paper start boolean loadedTicketLevel; // Paper end @@ -29492,14 +28946,14 @@ index 21946a93b6a2a3c79d15af1d6e7eabc537ba0125..d94e24cfc56c195a47665c212f8fcc90 public LevelChunk(ServerLevel world, ProtoChunk protoChunk, @Nullable LevelChunk.PostLoadProcessor entityLoader) { this(world, protoChunk.getPos(), protoChunk.getUpgradeData(), protoChunk.unpackBlockTicks(), protoChunk.unpackFluidTicks(), protoChunk.getInhabitedTime(), protoChunk.getSections(), entityLoader, protoChunk.getBlendingData()); -@@ -148,13 +189,19 @@ public class LevelChunk extends ChunkAccess { +@@ -152,13 +193,19 @@ public class LevelChunk extends ChunkAccess { } } - this.skyLightSources = protoChunk.skyLightSources; + // Paper - rewrite chunk system this.setLightCorrect(protoChunk.isLightCorrect()); - this.unsaved = true; + this.markUnsaved(); this.needsDecoration = true; // CraftBukkit // CraftBukkit start this.persistentDataContainer = protoChunk.persistentDataContainer; // SPIGOT-6814: copy PDC to account for 1.17 to 1.18 chunk upgrading. @@ -29512,9 +28966,9 @@ index 21946a93b6a2a3c79d15af1d6e7eabc537ba0125..d94e24cfc56c195a47665c212f8fcc90 + // Paper end - rewrite chunk system } - @Override -@@ -337,7 +384,7 @@ public class LevelChunk extends ChunkAccess { - ProfilerFiller gameprofilerfiller = this.level.getProfiler(); + public void setUnsavedListener(LevelChunk.UnsavedListener unsavedListener) { +@@ -361,7 +408,7 @@ public class LevelChunk extends ChunkAccess { + ProfilerFiller gameprofilerfiller = Profiler.get(); gameprofilerfiller.push("updateSkyLightSources"); - this.skyLightSources.update(this, j, i, l); @@ -29522,7 +28976,7 @@ index 21946a93b6a2a3c79d15af1d6e7eabc537ba0125..d94e24cfc56c195a47665c212f8fcc90 gameprofilerfiller.popPush("queueCheckLight"); this.level.getChunkSource().getLightEngine().checkBlock(blockposition); gameprofilerfiller.pop(); -@@ -602,11 +649,12 @@ public class LevelChunk extends ChunkAccess { +@@ -627,11 +674,12 @@ public class LevelChunk extends ChunkAccess { // CraftBukkit start public void loadCallback() { @@ -29536,7 +28990,7 @@ index 21946a93b6a2a3c79d15af1d6e7eabc537ba0125..d94e24cfc56c195a47665c212f8fcc90 if (server != null) { /* * If it's a new world, the first few chunks are generated inside -@@ -615,6 +663,7 @@ public class LevelChunk extends ChunkAccess { +@@ -640,6 +688,7 @@ public class LevelChunk extends ChunkAccess { */ org.bukkit.Chunk bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(bukkitChunk, this.needsDecoration)); @@ -29544,7 +28998,7 @@ index 21946a93b6a2a3c79d15af1d6e7eabc537ba0125..d94e24cfc56c195a47665c212f8fcc90 if (this.needsDecoration) { try (co.aikar.timings.Timing ignored = this.level.timings.chunkLoadPopulate.startTiming()) { // Paper -@@ -643,13 +692,15 @@ public class LevelChunk extends ChunkAccess { +@@ -668,13 +717,15 @@ public class LevelChunk extends ChunkAccess { } public void unloadCallback() { @@ -29562,7 +29016,7 @@ index 21946a93b6a2a3c79d15af1d6e7eabc537ba0125..d94e24cfc56c195a47665c212f8fcc90 // Paper start this.loadedTicketLevel = false; // Paper end -@@ -657,8 +708,27 @@ public class LevelChunk extends ChunkAccess { +@@ -682,8 +733,27 @@ public class LevelChunk extends ChunkAccess { @Override public boolean isUnsaved() { @@ -29591,7 +29045,7 @@ index 21946a93b6a2a3c79d15af1d6e7eabc537ba0125..d94e24cfc56c195a47665c212f8fcc90 // CraftBukkit end public boolean isEmpty() { -@@ -764,6 +834,7 @@ public class LevelChunk extends ChunkAccess { +@@ -791,6 +861,7 @@ public class LevelChunk extends ChunkAccess { this.pendingBlockEntities.clear(); this.upgradeData.upgrade(this); @@ -29600,7 +29054,7 @@ index 21946a93b6a2a3c79d15af1d6e7eabc537ba0125..d94e24cfc56c195a47665c212f8fcc90 @Nullable diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -index 90d1c3e23e753c29660f7d993b3c90ac022941c3..d7b8d984122ba6b6ef5a0be6e012a8828a1af22d 100644 +index 52f44f14bbda60fe771c351e01e6ff470d7371e6..161211124f3f8390530af7ab21f3a0f1025209c5 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java @@ -13,7 +13,7 @@ import net.minecraft.world.level.block.Blocks; @@ -29612,9 +29066,9 @@ index 90d1c3e23e753c29660f7d993b3c90ac022941c3..d7b8d984122ba6b6ef5a0be6e012a882 public static final int SECTION_WIDTH = 16; public static final int SECTION_HEIGHT = 16; -@@ -26,6 +26,28 @@ public class LevelChunkSection { - // CraftBukkit start - read/write - private PalettedContainer> biomes; +@@ -25,6 +25,28 @@ public class LevelChunkSection { + public final PalettedContainer states; + private PalettedContainer> biomes; // CraftBukkit - read/write + // Paper start - block counting + private static final it.unimi.dsi.fastutil.ints.IntArrayList FULL_LIST = new it.unimi.dsi.fastutil.ints.IntArrayList(16*16*16); @@ -29638,10 +29092,10 @@ index 90d1c3e23e753c29660f7d993b3c90ac022941c3..d7b8d984122ba6b6ef5a0be6e012a882 + } + // Paper end - block counting + - public LevelChunkSection(PalettedContainer datapaletteblock, PalettedContainer> palettedcontainerro) { - // CraftBukkit end - this.states = datapaletteblock; -@@ -92,6 +114,22 @@ public class LevelChunkSection { + private LevelChunkSection(LevelChunkSection section) { + this.nonEmptyBlockCount = section.nonEmptyBlockCount; + this.tickingBlockCount = section.tickingBlockCount; +@@ -98,6 +120,22 @@ public class LevelChunkSection { ++this.tickingFluidCount; } @@ -29664,7 +29118,7 @@ index 90d1c3e23e753c29660f7d993b3c90ac022941c3..d7b8d984122ba6b6ef5a0be6e012a882 return iblockdata1; } -@@ -112,40 +150,65 @@ public class LevelChunkSection { +@@ -118,40 +156,65 @@ public class LevelChunkSection { } public void recalcBlockCounts() { @@ -29751,7 +29205,7 @@ index 90d1c3e23e753c29660f7d993b3c90ac022941c3..d7b8d984122ba6b6ef5a0be6e012a882 } public PalettedContainer getStates() { -@@ -163,6 +226,7 @@ public class LevelChunkSection { +@@ -169,6 +232,7 @@ public class LevelChunkSection { datapaletteblock.read(buf); this.biomes = datapaletteblock; @@ -29760,7 +29214,7 @@ index 90d1c3e23e753c29660f7d993b3c90ac022941c3..d7b8d984122ba6b6ef5a0be6e012a882 public void readBiomes(FriendlyByteBuf buf) { diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -index 2fa0097a9374a89177e4f1068d1bfed30b8ff122..339cac6b34b9f2f53852cfcee821bec9e0286c50 100644 +index 112d1259dd37743076ff6c67ffd711d084ba8698..b46c58c952e183bd74854c3eb70d64979af70f18 100644 --- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java @@ -28,7 +28,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer @@ -29772,7 +29226,7 @@ index 2fa0097a9374a89177e4f1068d1bfed30b8ff122..339cac6b34b9f2f53852cfcee821bec9 private final PalettedContainer.Strategy strategy; // private final ThreadingDetector threadingDetector = new ThreadingDetector("PalettedContainer"); // Paper - unused -@@ -155,7 +155,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -161,7 +161,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer return this.get(this.strategy.getIndex(x, y, z)); } @@ -29782,13 +29236,13 @@ index 2fa0097a9374a89177e4f1068d1bfed30b8ff122..339cac6b34b9f2f53852cfcee821bec9 return data.palette.valueFor(data.storage.get(index)); } diff --git a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java -index 7f302405a88766c2112539d24d3dd2e513f94985..207dc31afcf5ca5a59ab27ee263aa10f94a79559 100644 +index 5321109ca638036572df9a7e17eafcef2b4f5112..5304254587372465c8ce821d7aa38b39a979f46b 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java -@@ -143,7 +143,7 @@ public class ProtoChunk extends ChunkAccess { +@@ -145,7 +145,7 @@ public class ProtoChunk extends ChunkAccess { } - if (LightEngine.hasDifferentLightProperties(this, pos, blockState, state)) { + if (LightEngine.hasDifferentLightProperties(blockState, state)) { - this.skyLightSources.update(this, m, j, o); + // Paper - rewrite chunk system this.lightEngine.checkBlock(pos); @@ -29808,7 +29262,7 @@ index b1058bf0dcda544a074f4d3772d7899b94f98927..b7bf82f6b6023bd628d3e7ea84d2d675 .step(ChunkStatus.FULL, builder -> builder.setTask(ChunkStatusTasks::full)) .build(); diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java -index 0baa4adf2a4401f9c955352f27e6f99957d1dff4..3723c07183e7b894cccf4d01bedf1d0d832c1910 100644 +index 4f84ff9cdb3303251e035a12ce9d8b9a0b58f46e..d80b7d555e02d1d4b82945373d383eaedbf4b976 100644 --- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java +++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java @@ -11,7 +11,7 @@ import net.minecraft.resources.ResourceLocation; @@ -29890,11 +29344,11 @@ index 0baa4adf2a4401f9c955352f27e6f99957d1dff4..3723c07183e7b894cccf4d01bedf1d0d this.chunkType = chunkType; this.heightmapsAfter = heightMapTypes; diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -index ae16cf5c803caae636860dd9b1a83abe479ca5a4..b993c4b2595e2879b25753c2e34530f3622c18fa 100644 +index aff4c3d63a97d5bbde004a616f7e14fca59b5ab9..d8dbaecc3c8ef59b0116f0ed4b1c06369b805e1d 100644 --- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java +++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -@@ -154,7 +154,7 @@ public class ChunkStatusTasks { - chunk1 = ((ImposterProtoChunk) protochunk).getWrapped(); +@@ -152,7 +152,7 @@ public class ChunkStatusTasks { + chunk1 = protochunkextension.getWrapped(); } else { chunk1 = new LevelChunk(worldserver, protochunk, ($) -> { // Paper - decompile fix - ChunkStatusTasks.postLoadProtoChunk(worldserver, protochunk.getEntities()); @@ -29902,16 +29356,16 @@ index ae16cf5c803caae636860dd9b1a83abe479ca5a4..b993c4b2595e2879b25753c2e34530f3 }); generationchunkholder.replaceProtoChunk(new ImposterProtoChunk(chunk1, false)); } -@@ -175,7 +175,7 @@ public class ChunkStatusTasks { - }); +@@ -168,7 +168,7 @@ public class ChunkStatusTasks { + }, context.mainThreadExecutor()); } -- private static void postLoadProtoChunk(ServerLevel world, List entities) { -+ public static void postLoadProtoChunk(ServerLevel world, List entities, ChunkPos pos) { // Paper - public, add ChunkPos param +- public static void postLoadProtoChunk(ServerLevel world, List entities) { // Paper - public ++ public static void postLoadProtoChunk(ServerLevel world, List entities, ChunkPos pos) { // Paper - public // Paper - rewrite chunk system - add ChunkPos param if (!entities.isEmpty()) { // CraftBukkit start - these are spawned serialized (DefinedStructure) and we don't call an add event below at the moment due to ordering complexities - world.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(entities, world).filter((entity) -> { -@@ -191,7 +191,7 @@ public class ChunkStatusTasks { + world.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(entities, world, EntitySpawnReason.LOAD).filter((entity) -> { +@@ -180,7 +180,7 @@ public class ChunkStatusTasks { } checkDupeUUID(world, entity); // Paper - duplicate uuid resolving return !needsRemoval; @@ -30035,128 +29489,8 @@ index f6e08a8334633ff1532616d051bed46b702d0091..4e56398a6fb8b97199f4c74ebebc1055 public static class Builder { private final ChunkStatus status; @Nullable -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index d42585bccb03f8ee1be5e37cfbe8520af4cc5454..cb5196f0ff7b9a59927c60b9d24c987a150e69f1 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -@@ -165,7 +165,7 @@ public class ChunkSerializer { - achunksection[k] = chunksection; - SectionPos sectionposition = SectionPos.of(chunkPos, b0); - -- poiStorage.checkConsistencyWithBlocks(sectionposition, chunksection); -+ // Paper - rewrite chunk system - moved to final load stage - } - - boolean flag3 = nbttagcompound1.contains("BlockLight", 7); -@@ -287,6 +287,8 @@ public class ChunkSerializer { - } - } - -+ ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.loadLightHook(world, chunkPos, nbt, (ChunkAccess)object1); // Paper - rewrite chunk system - note: it's ok to pass the raw value instead of wrapped -+ - if (chunktype == ChunkType.LEVELCHUNK) { - return new ImposterProtoChunk((LevelChunk) object1, false); - } else { -@@ -341,14 +343,44 @@ public class ChunkSerializer { - } - // CraftBukkit end - -+ // Paper start - async chunk saving -+ // must be called sync -+ public static ca.spottedleaf.moonrise.patches.chunk_system.async_save.AsyncChunkSaveData getAsyncSaveData(ServerLevel world, ChunkAccess chunk) { -+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(world, chunk.locX, chunk.locZ, "Preparing async chunk save data"); -+ -+ final CompoundTag tickLists = new CompoundTag(); -+ ChunkSerializer.saveTicks(world, tickLists, chunk.getTicksForSerialization()); -+ -+ ListTag blockEntitiesSerialized = new ListTag(); -+ for (final BlockPos blockPos : chunk.getBlockEntitiesPos()) { -+ final CompoundTag blockEntityNbt = chunk.getBlockEntityNbtForSaving(blockPos, world.registryAccess()); -+ if (blockEntityNbt != null) { -+ blockEntitiesSerialized.add(blockEntityNbt); -+ } -+ } -+ -+ return new ca.spottedleaf.moonrise.patches.chunk_system.async_save.AsyncChunkSaveData( -+ tickLists.get(BLOCK_TICKS_TAG), -+ tickLists.get(FLUID_TICKS_TAG), -+ blockEntitiesSerialized, -+ world.getGameTime() -+ ); -+ } -+ // Paper end - async chunk saving -+ - public static CompoundTag write(ServerLevel world, ChunkAccess chunk) { -+ // Paper start - async chunk saving -+ return saveChunk(world, chunk, null); -+ } -+ public static CompoundTag saveChunk(ServerLevel world, ChunkAccess chunk, ca.spottedleaf.moonrise.patches.chunk_system.async_save.AsyncChunkSaveData asyncsavedata) { -+ // Paper end - async chunk saving - ChunkPos chunkcoordintpair = chunk.getPos(); - CompoundTag nbttagcompound = NbtUtils.addCurrentDataVersion(new CompoundTag()); - - nbttagcompound.putInt("xPos", chunkcoordintpair.x); - nbttagcompound.putInt("yPos", chunk.getMinSection()); - nbttagcompound.putInt("zPos", chunkcoordintpair.z); -- nbttagcompound.putLong("LastUpdate", world.getGameTime()); -+ nbttagcompound.putLong("LastUpdate", asyncsavedata != null ? asyncsavedata.worldTime() : world.getGameTime()); // Paper - async chunk saving - nbttagcompound.putLong("InhabitedTime", chunk.getInhabitedTime()); - nbttagcompound.putString("Status", BuiltInRegistries.CHUNK_STATUS.getKey(chunk.getPersistedStatus()).toString()); - BlendingData blendingdata = chunk.getBlendingData(); -@@ -424,8 +456,17 @@ public class ChunkSerializer { - nbttagcompound.putBoolean("isLightOn", true); - } - -- ListTag nbttaglist1 = new ListTag(); -- Iterator iterator = chunk.getBlockEntitiesPos().iterator(); -+ // Paper start - async chunk saving -+ ListTag nbttaglist1; -+ Iterator iterator; -+ if (asyncsavedata != null) { -+ nbttaglist1 = asyncsavedata.blockEntities(); -+ iterator = java.util.Collections.emptyIterator(); -+ } else { -+ nbttaglist1 = new ListTag(); -+ iterator = chunk.getBlockEntitiesPos().iterator(); -+ } -+ // Paper end - async chunk saving - - CompoundTag nbttagcompound2; - -@@ -461,7 +502,14 @@ public class ChunkSerializer { - nbttagcompound.put("CarvingMasks", nbttagcompound2); - } - -+ // Paper start -+ if (asyncsavedata != null) { -+ nbttagcompound.put(BLOCK_TICKS_TAG, asyncsavedata.blockTickList()); -+ nbttagcompound.put(FLUID_TICKS_TAG, asyncsavedata.fluidTickList()); -+ } else { - ChunkSerializer.saveTicks(world, nbttagcompound, chunk.getTicksForSerialization()); -+ } -+ // Paper end - nbttagcompound.put("PostProcessing", ChunkSerializer.packOffsets(chunk.getPostProcessing())); - CompoundTag nbttagcompound3 = new CompoundTag(); - Iterator iterator1 = chunk.getHeightmaps().iterator(); -@@ -481,6 +529,7 @@ public class ChunkSerializer { - nbttagcompound.put("ChunkBukkitValues", chunk.persistentDataContainer.toTagCompound()); - } - // CraftBukkit end -+ ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.saveLightHook(world, chunk, nbttagcompound); // Paper - rewrite chunk system - return nbttagcompound; - } - -@@ -506,7 +555,7 @@ public class ChunkSerializer { - - return nbttaglist == null && nbttaglist1 == null ? null : (chunk) -> { - if (nbttaglist != null) { -- world.addLegacyChunkEntities(EntityType.loadEntitiesRecursive(nbttaglist, world)); -+ world.addLegacyChunkEntities(EntityType.loadEntitiesRecursive(nbttaglist, world), chunk.getPos()); // Paper - rewrite chunk system - } - - if (nbttaglist1 != null) { diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -index f0f5e9bb5ac65250f0a151f9f90b58468335a8c2..0cdc224656a2baa09b7dfbb249b6a96320ac43e0 100644 +index 092f7b6bba4e1291f76c2c09155f33803e93eb04..82b4638d3c5ec11cdb857dc2defd2113caff7965 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java @@ -28,21 +28,31 @@ import net.minecraft.world.level.dimension.LevelStem; @@ -30219,12 +29553,12 @@ index f0f5e9bb5ac65250f0a151f9f90b58468335a8c2..0cdc224656a2baa09b7dfbb249b6a963 + // Paper end - rewrite chunk system } - public CompletableFuture write(ChunkPos chunkPos, CompoundTag nbt) { -@@ -181,29 +199,54 @@ public class ChunkStorage implements AutoCloseable { - } - // Paper end - guard against serializing mismatching coordinates + public CompletableFuture write(ChunkPos chunkPos, Supplier nbtSupplier) { +@@ -185,29 +203,54 @@ public class ChunkStorage implements AutoCloseable { + }; + // Paper end - guard against possible chunk pos desync this.handleLegacyStructureIndex(chunkPos); -- return this.worker.store(chunkPos, nbt); +- return this.worker.store(chunkPos, guardedPosCheck); // Paper - guard against possible chunk pos desync + // Paper start - rewrite chunk system + try { + this.storage.write(chunkPos, nbt); @@ -30282,10 +29616,10 @@ index f0f5e9bb5ac65250f0a151f9f90b58468335a8c2..0cdc224656a2baa09b7dfbb249b6a963 } } diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java -index 36b8a9ac385e43f3212aca1b1f5bd7115bd00431..503ac0374e0c9f9993ad37bb8bd8cf1570d3615a 100644 +index a0cbccd2cf1ac785745d86c42b6f58fb8bad7ffa..16ca1c8672e5f0a27f8a30498c754a81cdec5191 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java -@@ -70,12 +70,12 @@ public class EntityStorage implements EntityPersistentStorage { +@@ -71,12 +71,12 @@ public class EntityStorage implements EntityPersistentStorage { } } @@ -30301,16 +29635,16 @@ index 36b8a9ac385e43f3212aca1b1f5bd7115bd00431..503ac0374e0c9f9993ad37bb8bd8cf15 } diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/IOWorker.java b/src/main/java/net/minecraft/world/level/chunk/storage/IOWorker.java -index 053504cc6c98be3b70bd1722e279d861694e015d..316bf111fe94ce7a71af71cd32c94fcf528d4365 100644 +index cb823d342e41b5861adfc847a313c265fb702a4c..2b1ea97199d5976e5ff4bd049c1e6c8b9b8a4177 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/IOWorker.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/IOWorker.java -@@ -32,7 +32,7 @@ public class IOWorker implements ChunkScanAccess, AutoCloseable { +@@ -30,7 +30,7 @@ public class IOWorker implements ChunkScanAccess, AutoCloseable { private static final Logger LOGGER = LogUtils.getLogger(); private final AtomicBoolean shutdownRequested = new AtomicBoolean(); - private final ProcessorMailbox mailbox; + private final PriorityConsecutiveExecutor consecutiveExecutor; - private final RegionFileStorage storage; + public final RegionFileStorage storage; // Paper - public - private final Map pendingWrites = Maps.newLinkedHashMap(); + private final SequencedMap pendingWrites = new LinkedHashMap<>(); private final Long2ObjectLinkedOpenHashMap> regionCacheForBlender = new Long2ObjectLinkedOpenHashMap<>(); private static final int REGION_CACHE_SIZE = 1024; 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 @@ -30538,25 +29872,25 @@ index 4c1212c6ef48594e766fa9e35a6e15916602d587..18054304e08c8a6346c0135a0e6a68e7 } diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java -index 092773bd39d77a0dbe22db97c11aecb4a297111c..c7ed3eb80f6e8b918434153093644776866aa220 100644 +index 93972352cd4881dccba9b90ccc8dcced3563e340..c3beb7fcad46a917d2b61bd0a0e98e5106056728 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java -@@ -31,10 +31,10 @@ import net.minecraft.world.level.ChunkPos; +@@ -40,10 +40,10 @@ import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.LevelHeightAccessor; import org.slf4j.Logger; --public class SectionStorage implements AutoCloseable { -+public abstract class SectionStorage implements AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.level.storage.ChunkSystemSectionStorage { // Paper - rewrite chunk system - private static final Logger LOGGER = LogUtils.getLogger(); +-public class SectionStorage implements AutoCloseable { ++public class SectionStorage implements AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.level.storage.ChunkSystemSectionStorage { // Paper - rewrite chunk system + static final Logger LOGGER = LogUtils.getLogger(); private static final String SECTIONS_TAG = "Sections"; - private final SimpleRegionStorage simpleRegionStorage; + // Paper - rewrite chunk system private final Long2ObjectMap> storage = new Long2ObjectOpenHashMap<>(); - private final LongLinkedOpenHashSet dirty = new LongLinkedOpenHashSet(); - private final Function> codec; -@@ -43,6 +43,15 @@ public class SectionStorage implements AutoCloseable { - private final ChunkIOErrorReporter errorReporter; - protected final LevelHeightAccessor levelHeightAccessor; + private final LongLinkedOpenHashSet dirtyChunks = new LongLinkedOpenHashSet(); + private final Codec

    codec; +@@ -57,6 +57,18 @@ public class SectionStorage implements AutoCloseable { + private final Long2ObjectMap>>> pendingLoads = new Long2ObjectOpenHashMap<>(); + private final Object loadLock = new Object(); + // Paper start - rewrite chunk system + private final RegionFileStorage regionStorage; @@ -30565,19 +29899,24 @@ index 092773bd39d77a0dbe22db97c11aecb4a297111c..c7ed3eb80f6e8b918434153093644776 + public final RegionFileStorage moonrise$getRegionStorage() { + return this.regionStorage; + } ++ ++ @Override ++ public void moonrise$close() throws IOException {} + // Paper end - rewrite chunk system + public SectionStorage( SimpleRegionStorage storageAccess, - Function> codecFactory, -@@ -51,12 +60,13 @@ public class SectionStorage implements AutoCloseable { + Codec

    codec, +@@ -67,7 +79,7 @@ public class SectionStorage implements AutoCloseable { ChunkIOErrorReporter errorHandler, LevelHeightAccessor world ) { - this.simpleRegionStorage = storageAccess; + // Paper - rewrite chunk system - this.codec = codecFactory; - this.factory = factory; + this.codec = codec; + this.packer = serializer; + this.unpacker = deserializer; +@@ -75,6 +87,7 @@ public class SectionStorage implements AutoCloseable { this.registryAccess = registryManager; this.errorReporter = errorHandler; this.levelHeightAccessor = world; @@ -30585,51 +29924,47 @@ index 092773bd39d77a0dbe22db97c11aecb4a297111c..c7ed3eb80f6e8b918434153093644776 } protected void tick(BooleanSupplier shouldKeepTicking) { -@@ -121,44 +131,17 @@ public class SectionStorage implements AutoCloseable { - } - - private CompletableFuture> tryRead(ChunkPos pos) { -- return this.simpleRegionStorage.read(pos).exceptionally(throwable -> { -- if (throwable instanceof IOException iOException) { -- LOGGER.error("Error reading chunk {} data from disk", pos, iOException); -- this.errorReporter.reportChunkLoadFailure(iOException, this.simpleRegionStorage.storageInfo(), pos); -- return Optional.empty(); -- } else { -- throw new CompletionException(throwable); -- } -- }); -+ // Paper start - rewrite chunk system -+ try { -+ return CompletableFuture.completedFuture(Optional.ofNullable(this.moonrise$read(pos.x, pos.z))); -+ } catch (final Throwable thr) { -+ return CompletableFuture.failedFuture(thr); -+ } -+ // Paper end - rewrite chunk system +@@ -188,60 +201,15 @@ public class SectionStorage implements AutoCloseable { + } + + private CompletableFuture>> tryRead(ChunkPos chunkPos) { +- RegistryOps registryOps = this.registryAccess.createSerializationContext(NbtOps.INSTANCE); +- return this.simpleRegionStorage +- .read(chunkPos) +- .thenApplyAsync( +- chunkNbt -> chunkNbt.map( +- nbt -> SectionStorage.PackedChunk.parse(this.codec, registryOps, nbt, this.simpleRegionStorage, this.levelHeightAccessor) +- ), +- Util.backgroundExecutor().forName("parseSection") +- ) +- .exceptionally(throwable -> { +- if (throwable instanceof IOException iOException) { +- LOGGER.error("Error reading chunk {} data from disk", chunkPos, iOException); +- this.errorReporter.reportChunkLoadFailure(iOException, this.simpleRegionStorage.storageInfo(), chunkPos); +- return Optional.empty(); +- } else { +- throw new CompletionException(throwable); +- } +- }); ++ throw new IllegalStateException("Only chunk system can write state, offending class:" + this.getClass().getName()); // Paper - rewrite chunk system } - private void readColumn(ChunkPos pos, RegistryOps ops, @Nullable CompoundTag nbt) { -- if (nbt == null) { -- for (int i = this.levelHeightAccessor.getMinSection(); i < this.levelHeightAccessor.getMaxSection(); i++) { -- this.storage.put(getKey(pos, i), Optional.empty()); + private void unpackChunk(ChunkPos chunkPos, @Nullable SectionStorage.PackedChunk

    result) { +- if (result == null) { +- for (int i = this.levelHeightAccessor.getMinSectionY(); i <= this.levelHeightAccessor.getMaxSectionY(); i++) { +- this.storage.put(getKey(chunkPos, i), Optional.empty()); - } - } else { -- Dynamic dynamic = new Dynamic<>(ops, nbt); -- int j = getVersion(dynamic); -- int k = SharedConstants.getCurrentVersion().getDataVersion().getVersion(); -- boolean bl = j != k; -- Dynamic dynamic2 = this.simpleRegionStorage.upgradeChunkTag(dynamic, j); -- OptionalDynamic optionalDynamic = dynamic2.get("Sections"); -- -- for (int l = this.levelHeightAccessor.getMinSection(); l < this.levelHeightAccessor.getMaxSection(); l++) { -- long m = getKey(pos, l); -- Optional optional = optionalDynamic.get(Integer.toString(l)) -- .result() -- .flatMap(dynamicx -> this.codec.apply(() -> this.setDirty(m)).parse(dynamicx).resultOrPartial(LOGGER::error)); -- this.storage.put(m, optional); -- optional.ifPresent(sections -> { -- this.onSectionLoad(m); +- boolean bl = result.versionChanged(); +- +- for (int j = this.levelHeightAccessor.getMinSectionY(); j <= this.levelHeightAccessor.getMaxSectionY(); j++) { +- long l = getKey(chunkPos, j); +- Optional optional = Optional.ofNullable(result.sectionsByY.get(j)).map(section -> this.unpacker.apply((P)section, () -> this.setDirty(l))); +- this.storage.put(l, optional); +- optional.ifPresent(object -> { +- this.onSectionLoad(l); - if (bl) { -- this.setDirty(m); +- this.setDirty(l); - } - }); - } @@ -30637,26 +29972,23 @@ index 092773bd39d77a0dbe22db97c11aecb4a297111c..c7ed3eb80f6e8b918434153093644776 + throw new IllegalStateException("Only chunk system can load in state, offending class:" + this.getClass().getName()); // Paper - rewrite chunk system } - private void writeColumn(ChunkPos pos) { -@@ -166,10 +149,13 @@ public class SectionStorage implements AutoCloseable { - Dynamic dynamic = this.writeColumn(pos, registryOps); - Tag tag = dynamic.getValue(); - if (tag instanceof CompoundTag) { + private void writeChunk(ChunkPos pos) { +- RegistryOps registryOps = this.registryAccess.createSerializationContext(NbtOps.INSTANCE); +- Dynamic dynamic = this.writeChunk(pos, registryOps); +- Tag tag = dynamic.getValue(); +- if (tag instanceof CompoundTag) { - this.simpleRegionStorage.write(pos, (CompoundTag)tag).exceptionally(throwable -> { - this.errorReporter.reportChunkSaveFailure(throwable, this.simpleRegionStorage.storageInfo(), pos); - return null; - }); -+ // Paper start - rewrite chunk system -+ try { -+ this.moonrise$write(pos.x, pos.z, (net.minecraft.nbt.CompoundTag)tag); -+ } catch (final IOException ex) { -+ LOGGER.error("Error writing poi chunk data to disk for chunk " + pos, ex); -+ } -+ // Paper end - rewrite chunk system - } else { - LOGGER.error("Expected compound tag, got {}", tag); - } -@@ -209,7 +195,7 @@ public class SectionStorage implements AutoCloseable { +- } else { +- LOGGER.error("Expected compound tag, got {}", tag); +- } ++ throw new IllegalStateException("Only chunk system can write state, offending class:" + this.getClass().getName()); // Paper - rewrite chunk system + } + + private Dynamic writeChunk(ChunkPos chunkPos, DynamicOps ops) { +@@ -277,7 +245,7 @@ public class SectionStorage implements AutoCloseable { protected void onSectionLoad(long pos) { } @@ -30664,17 +29996,18 @@ index 092773bd39d77a0dbe22db97c11aecb4a297111c..c7ed3eb80f6e8b918434153093644776 + public void setDirty(long pos) { // Paper - public Optional optional = this.storage.get(pos); if (optional != null && !optional.isEmpty()) { - this.dirty.add(pos); -@@ -236,6 +222,6 @@ public class SectionStorage implements AutoCloseable { + this.dirtyChunks.add(ChunkPos.asLong(SectionPos.x(pos), SectionPos.z(pos))); +@@ -298,7 +266,7 @@ public class SectionStorage implements AutoCloseable { @Override public void close() throws IOException { - this.simpleRegionStorage.close(); + this.moonrise$close(); // Paper - rewrite chunk system } - } + + static record PackedChunk(Int2ObjectMap sectionsByY, boolean versionChanged) { diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java -index e0e843f4f69013379ed70cb63d9b4f72163b828b..aafb05c5e63903f5790a6bcb862c8d79588be5a6 100644 +index 578d270d5b7efb9ac8f5dde539170f6021e2b786..c5085ebf4e801837010f3750c5e89576bb0c27a5 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java @@ -14,7 +14,7 @@ import net.minecraft.util.datafix.DataFixTypes; @@ -30759,15 +30092,15 @@ index 74a285b8b018a9c94ccea519f1ce8b9e2ef3cb64..d8b4196adf955f8d414688dc451caac2 } } diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -index fb0be805c86e311927f55e8f090592465195384e..996899cb18e6c29665b9de7a1cc97c9a4187924b 100644 +index 44e64d716eee71492f9a8d813934bb96463ece45..d52fcb82fdeab5b2e95b97a876c6e6701f569013 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java @@ -86,7 +86,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { - return CompletableFuture.supplyAsync(Util.wrapThreadWithTaskName("init_biomes", () -> { + return CompletableFuture.supplyAsync(() -> { this.doCreateBiomes(blender, noiseConfig, structureAccessor, chunk); return chunk; -- }), Util.backgroundExecutor()); -+ }), Runnable::run); // Paper - rewrite chunk system +- }, Util.backgroundExecutor().forName("init_biomes")); ++ }, Runnable::run); // Paper - rewrite chunk system } private void doCreateBiomes(Blender blender, RandomState noiseConfig, StructureManager structureAccessor, ChunkAccess chunk) { @@ -30775,13 +30108,13 @@ index fb0be805c86e311927f55e8f090592465195384e..996899cb18e6c29665b9de7a1cc97c9a } return ichunkaccess1; -- }), Util.backgroundExecutor()); -+ }), Runnable::run); // Paper - rewrite chunk system +- }, Util.backgroundExecutor().forName("wgen_fill_noise")); ++ }, Runnable::run); // Paper - rewrite chunk system } private ChunkAccess doFill(Blender blender, StructureManager structureAccessor, RandomState noiseConfig, ChunkAccess chunk, int minimumCellY, int cellHeight) { diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java b/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java -index c6181e14d85d454506534f9bbe856156c0d4a062..3694c5d2d522216cd2e6e91e502a56a08595ca84 100644 +index c3586281c9594769593a6027ea0a78f7c76c0262..decdb275e83fa6244aa3a24458872b42c49d04ed 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java +++ b/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java @@ -47,8 +47,13 @@ public class StructureCheck { @@ -30855,16 +30188,17 @@ index c6181e14d85d454506534f9bbe856156c0d4a062..3694c5d2d522216cd2e6e91e502a56a0 referencesByStructure.computeInt(structure, (feature, references) -> references == null ? 1 : references + 1); return referencesByStructure; diff --git a/src/main/java/net/minecraft/world/level/lighting/LevelLightEngine.java b/src/main/java/net/minecraft/world/level/lighting/LevelLightEngine.java -index 82e4fad11121167445df97060fb717fa86191297..b3e2bb9245be1bb2f587117b0f6016cba18e217f 100644 +index 8d90e783967280025d711c709facbcc87f611f8a..987e3397503cd07d3a2f172cede341297bc58dba 100644 --- a/src/main/java/net/minecraft/world/level/lighting/LevelLightEngine.java +++ b/src/main/java/net/minecraft/world/level/lighting/LevelLightEngine.java -@@ -9,145 +9,103 @@ import net.minecraft.world.level.LightLayer; +@@ -9,151 +9,111 @@ import net.minecraft.world.level.LightLayer; import net.minecraft.world.level.chunk.DataLayer; import net.minecraft.world.level.chunk.LightChunkGetter; -public class LevelLightEngine implements LightEventListener { -+public class LevelLightEngine implements LightEventListener, ca.spottedleaf.moonrise.patches.starlight.light.StarLightLightingProvider { ++public class LevelLightEngine implements LightEventListener, ca.spottedleaf.moonrise.patches.starlight.light.StarLightLightingProvider { // Paper - rewrite chunk system public static final int LIGHT_SECTION_PADDING = 1; + public static final LevelLightEngine EMPTY = new LevelLightEngine(); protected final LevelHeightAccessor levelHeightAccessor; - @Nullable - private final LightEngine blockEngine; @@ -30908,6 +30242,15 @@ index 82e4fad11121167445df97060fb717fa86191297..b3e2bb9245be1bb2f587117b0f6016cb + // Paper end - rewrite chunk system } + private LevelLightEngine() { + this.levelHeightAccessor = LevelHeightAccessor.create(0, 0); +- this.blockEngine = null; +- this.skyEngine = null; ++ // Paper start - rewrite chunk system ++ this.lightEngine = new ca.spottedleaf.moonrise.patches.starlight.light.StarLightInterface(null, false, false, (LevelLightEngine)(Object)this); ++ // Paper end - rewrite chunk system + } + @Override public void checkBlock(BlockPos pos) { - if (this.blockEngine != null) { @@ -31043,19 +30386,18 @@ index 82e4fad11121167445df97060fb717fa86191297..b3e2bb9245be1bb2f587117b0f6016cb + return this.lightEngine.getRawBrightness(pos, ambientDarkness); // Paper - rewrite chunk system } - public boolean lightOnInSection(SectionPos sectionPos) { -- long l = sectionPos.asLong(); + public boolean lightOnInColumn(long sectionPos) { - return this.blockEngine == null -- || this.blockEngine.storage.lightOnInSection(l) && (this.skyEngine == null || this.skyEngine.storage.lightOnInSection(l)); +- || this.blockEngine.storage.lightOnInColumn(sectionPos) && (this.skyEngine == null || this.skyEngine.storage.lightOnInColumn(sectionPos)); + throw new UnsupportedOperationException(); // Paper - rewrite chunk system // Paper - not implemented on server } public int getLightSectionCount() { diff --git a/src/main/java/net/minecraft/world/phys/AABB.java b/src/main/java/net/minecraft/world/phys/AABB.java -index c8f7c43134e7c51ce8af5b3c1a28c11db67715a2..29123f3a2f211c08d1a9ccf62ca9bc9822f90111 100644 +index 5dc2674b537f4a61b2e21a21bdb2e8dc090d3a3c..6cf6d4ec7b9e43c7b2b4c0e2fb080964ff588130 100644 --- a/src/main/java/net/minecraft/world/phys/AABB.java +++ b/src/main/java/net/minecraft/world/phys/AABB.java -@@ -326,7 +326,7 @@ public class AABB { +@@ -331,7 +331,7 @@ public class AABB { } @Nullable @@ -31063,7 +30405,7 @@ index c8f7c43134e7c51ce8af5b3c1a28c11db67715a2..29123f3a2f211c08d1a9ccf62ca9bc98 + public static Direction getDirection( // Paper - optimise collisions - public AABB box, Vec3 intersectingVector, double[] traceDistanceResult, @Nullable Direction approachDirection, double deltaX, double deltaY, double deltaZ ) { - if (deltaX > 1.0E-7) { + return getDirection( diff --git a/src/main/java/net/minecraft/world/phys/shapes/ArrayVoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/ArrayVoxelShape.java index 4fee67f7214b464b9e09862778e3ef187fcb8b72..31a54af04ab072a433d6df9fe37beb12243fea80 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/ArrayVoxelShape.java @@ -31360,7 +30702,7 @@ index 7ec02a7849437a18860aa0df7d9ddd71b2447d4c..5e45e49ab09344cb95736f4124b1c6e0 public OffsetDoubleList(DoubleList oldList, double offset) { this.delegate = oldList; diff --git a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java -index 0fdd2cdd8d215ca1523eda8ad7316cdd5f41a6b5..7ede56f77af1d40e10fde2e660d5794e4b37dc5d 100644 +index 5a0b0b47da3d796c391ac15eb573af25a1dfcd32..672a2038c6d8b31090403766460c6149a75adf8b 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java +++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java @@ -16,9 +16,15 @@ public final class Shapes { @@ -31451,7 +30793,10 @@ index 0fdd2cdd8d215ca1523eda8ad7316cdd5f41a6b5..7ede56f77af1d40e10fde2e660d5794e - DoubleArrayList.wrap(new double[]{minX, maxX}), - DoubleArrayList.wrap(new double[]{minY, maxY}), - DoubleArrayList.wrap(new double[]{minZ, maxZ}) -- ); ++ minX == 0.0 && maxX == 1.0 ? ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.ZERO_ONE : DoubleArrayList.wrap(new double[] { minX, maxX }), ++ minY == 0.0 && maxY == 1.0 ? ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.ZERO_ONE : DoubleArrayList.wrap(new double[] { minY, maxY }), ++ minZ == 0.0 && maxZ == 1.0 ? ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.ZERO_ONE : DoubleArrayList.wrap(new double[] { minZ, maxZ }) + ); - } else if (i == 0 && j == 0 && k == 0) { - return block(); - } else { @@ -31468,10 +30813,7 @@ index 0fdd2cdd8d215ca1523eda8ad7316cdd5f41a6b5..7ede56f77af1d40e10fde2e660d5794e - (int)Math.round(maxX * (double)l), - (int)Math.round(maxY * (double)m), - (int)Math.round(maxZ * (double)n) -+ minX == 0.0 && maxX == 1.0 ? ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.ZERO_ONE : DoubleArrayList.wrap(new double[] { minX, maxX }), -+ minY == 0.0 && maxY == 1.0 ? ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.ZERO_ONE : DoubleArrayList.wrap(new double[] { minY, maxY }), -+ minZ == 0.0 && maxZ == 1.0 ? ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.ZERO_ONE : DoubleArrayList.wrap(new double[] { minZ, maxZ }) - ); +- ); - return new CubeVoxelShape(bitSetDiscreteVoxelShape); } } else { @@ -31602,7 +30944,7 @@ index 0fdd2cdd8d215ca1523eda8ad7316cdd5f41a6b5..7ede56f77af1d40e10fde2e660d5794e } private static boolean joinIsNotEmpty( -@@ -219,70 +226,120 @@ public final class Shapes { +@@ -219,51 +226,116 @@ public final class Shapes { return maxDist; } @@ -31646,35 +30988,34 @@ index 0fdd2cdd8d215ca1523eda8ad7316cdd5f41a6b5..7ede56f77af1d40e10fde2e660d5794e + // Paper end - optimise collisions } - public static VoxelShape getFaceShape(VoxelShape shape, Direction direction) { -- if (shape == block()) { -- return block(); -- } else { +- public static boolean mergedFaceOccludes(VoxelShape one, VoxelShape two, Direction direction) { +- if (one != block() && two != block()) { - Direction.Axis axis = direction.getAxis(); -- boolean bl; -- int i; -- if (direction.getAxisDirection() == Direction.AxisDirection.POSITIVE) { -- bl = DoubleMath.fuzzyEquals(shape.max(axis), 1.0, 1.0E-7); -- i = shape.shape.getSize(axis) - 1; -- } else { -- bl = DoubleMath.fuzzyEquals(shape.min(axis), 0.0, 1.0E-7); -- i = 0; +- Direction.AxisDirection axisDirection = direction.getAxisDirection(); +- VoxelShape voxelShape = axisDirection == Direction.AxisDirection.POSITIVE ? one : two; +- VoxelShape voxelShape2 = axisDirection == Direction.AxisDirection.POSITIVE ? two : one; +- if (!DoubleMath.fuzzyEquals(voxelShape.max(axis), 1.0, 1.0E-7)) { +- voxelShape = empty(); - } -+ return ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$getFaceShapeClamped(direction); // Paper - optimise collisions -+ } - -- return (VoxelShape)(!bl ? empty() : new SliceShape(shape, axis, i)); -- } + // Paper start - optimise collisions + private static boolean mergedMayOccludeBlock(final VoxelShape shape1, final VoxelShape shape2) { + // if the combined bounds of the two shapes cannot occlude, then neither can the merged + final AABB bounds1 = shape1.bounds(); + final AABB bounds2 = shape2.bounds(); -+ + +- if (!DoubleMath.fuzzyEquals(voxelShape2.min(axis), 0.0, 1.0E-7)) { +- voxelShape2 = empty(); +- } + final double minX = Math.min(bounds1.minX, bounds2.minX); + final double minY = Math.min(bounds1.minY, bounds2.minY); + final double minZ = Math.min(bounds1.minZ, bounds2.minZ); -+ + +- return !joinIsNotEmpty( +- block(), +- joinUnoptimized(new SliceShape(voxelShape, axis, voxelShape.shape.getSize(axis) - 1), new SliceShape(voxelShape2, axis, 0), BooleanOp.OR), +- BooleanOp.ONLY_FIRST +- ); +- } else { + final double maxX = Math.max(bounds1.maxX, bounds2.maxX); + final double maxY = Math.max(bounds1.maxY, bounds2.maxY); + final double maxZ = Math.max(bounds1.maxZ, bounds2.maxZ); @@ -31682,38 +31023,20 @@ index 0fdd2cdd8d215ca1523eda8ad7316cdd5f41a6b5..7ede56f77af1d40e10fde2e660d5794e + return (minX <= ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON && maxX >= (1 - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)) && + (minY <= ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON && maxY >= (1 - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)) && + (minZ <= ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON && maxZ >= (1 - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)); - } ++ } + // Paper end - optimise collisions - -- public static boolean mergedFaceOccludes(VoxelShape one, VoxelShape two, Direction direction) { -- if (one != block() && two != block()) { -- Direction.Axis axis = direction.getAxis(); -- Direction.AxisDirection axisDirection = direction.getAxisDirection(); -- VoxelShape voxelShape = axisDirection == Direction.AxisDirection.POSITIVE ? one : two; -- VoxelShape voxelShape2 = axisDirection == Direction.AxisDirection.POSITIVE ? two : one; -- if (!DoubleMath.fuzzyEquals(voxelShape.max(axis), 1.0, 1.0E-7)) { -- voxelShape = empty(); -- } ++ + // Paper start - optimise collisions + public static boolean mergedFaceOccludes(final VoxelShape first, final VoxelShape second, final Direction direction) { + // see if any of the shapes on their own occludes, only if cached + if (((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$occludesFullBlockIfCached() || ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$occludesFullBlockIfCached()) { + return true; + } - -- if (!DoubleMath.fuzzyEquals(voxelShape2.min(axis), 0.0, 1.0E-7)) { -- voxelShape2 = empty(); -- } ++ + if (first.isEmpty() & second.isEmpty()) { + return false; + } - -- return !joinIsNotEmpty( -- block(), -- joinUnoptimized(new SliceShape(voxelShape, axis, voxelShape.shape.getSize(axis) - 1), new SliceShape(voxelShape2, axis, 0), BooleanOp.OR), -- BooleanOp.ONLY_FIRST -- ); -- } else { ++ + // we optimise getOpposite, so we can use it + // secondly, use our cache to retrieve sliced shape + final VoxelShape newFirst = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$getFaceShapeClamped(direction); @@ -31785,7 +31108,7 @@ index b07f1c58e00d232e7c83e6df3499e4b677645609..b88c71f27996d24d29048e06a69a0046 private static DiscreteVoxelShape makeSlice(DiscreteVoxelShape voxelSet, Direction.Axis axis, int sliceWidth) { diff --git a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java -index d440003ca4403511a964f61bcf67ac2cd75c5359..11824d39e72fa003b3a56aa9b8d679fe8e23a1a4 100644 +index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..d850a7de74150a04622da71d9614320f3d5d69e8 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java +++ b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java @@ -15,38 +15,505 @@ import net.minecraft.world.phys.AABB; @@ -32311,7 +31634,7 @@ index d440003ca4403511a964f61bcf67ac2cd75c5359..11824d39e72fa003b3a56aa9b8d679fe } public VoxelShape singleEncompassing() { -@@ -69,28 +536,95 @@ public abstract class VoxelShape { +@@ -69,7 +536,7 @@ public abstract class VoxelShape { public abstract DoubleList getCoords(Direction.Axis axis); public boolean isEmpty() { @@ -32319,6 +31642,10 @@ index d440003ca4403511a964f61bcf67ac2cd75c5359..11824d39e72fa003b3a56aa9b8d679fe + return this.isEmpty; // Paper - optimise collisions } + public VoxelShape move(Vec3 vec3d) { +@@ -77,24 +544,91 @@ public abstract class VoxelShape { + } + public VoxelShape move(double x, double y, double z) { - return (VoxelShape)(this.isEmpty() - ? Shapes.empty() @@ -32423,7 +31750,7 @@ index d440003ca4403511a964f61bcf67ac2cd75c5359..11824d39e72fa003b3a56aa9b8d679fe } public void forAllEdges(Shapes.DoubleLineConsumer consumer) { -@@ -127,9 +661,24 @@ public abstract class VoxelShape { +@@ -131,9 +665,24 @@ public abstract class VoxelShape { } public List toAabbs() { @@ -32451,7 +31778,7 @@ index d440003ca4403511a964f61bcf67ac2cd75c5359..11824d39e72fa003b3a56aa9b8d679fe } public double min(Direction.Axis axis, double from, double to) { -@@ -155,42 +704,63 @@ public abstract class VoxelShape { +@@ -159,42 +708,63 @@ public abstract class VoxelShape { } @Nullable @@ -32473,7 +31800,7 @@ index d440003ca4403511a964f61bcf67ac2cd75c5359..11824d39e72fa003b3a56aa9b8d679fe - this.findIndex(Direction.Axis.Y, vec32.y - (double)pos.getY()), - this.findIndex(Direction.Axis.Z, vec32.z - (double)pos.getZ()) - ) -- ? new BlockHitResult(vec32, Direction.getNearest(vec3.x, vec3.y, vec3.z).getOpposite(), pos, true) +- ? new BlockHitResult(vec32, Direction.getApproximateNearest(vec3.x, vec3.y, vec3.z).getOpposite(), pos, true) - : AABB.clip(this.toAabbs(), start, end, pos); + } + @@ -32544,8 +31871,8 @@ index d440003ca4403511a964f61bcf67ac2cd75c5359..11824d39e72fa003b3a56aa9b8d679fe } public VoxelShape getFaceShape(Direction facing) { -@@ -226,8 +796,29 @@ public abstract class VoxelShape { - } +@@ -249,9 +819,30 @@ public abstract class VoxelShape { + && DoubleMath.fuzzyEquals(doubleList.getDouble(1), 1.0, 1.0E-7); } - public double collide(Direction.Axis axis, AABB box, double maxDist) { @@ -32560,27 +31887,28 @@ index d440003ca4403511a964f61bcf67ac2cd75c5359..11824d39e72fa003b3a56aa9b8d679fe + } + switch (axis) { + case X: { -+ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.collideX((VoxelShape)(Object)this, source, source_move); ++ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.collideX((VoxelShape) (Object) this, source, source_move); + } + case Y: { -+ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.collideY((VoxelShape)(Object)this, source, source_move); ++ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.collideY((VoxelShape) (Object) this, source, source_move); + } + case Z: { -+ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.collideZ((VoxelShape)(Object)this, source, source_move); ++ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.collideZ((VoxelShape) (Object) this, source, source_move); + } + default: { + throw new RuntimeException("Unknown axis: " + axis); + } + } -+ // Paper end - optimise collisions } ++ // Paper end - optimise collisions protected double collideX(AxisCycle axisCycle, AABB box, double maxDist) { + if (this.isEmpty()) { diff --git a/src/main/java/net/minecraft/world/ticks/LevelChunkTicks.java b/src/main/java/net/minecraft/world/ticks/LevelChunkTicks.java -index 47c2b2da9799690291396effb9e1b06d71efc6fd..c42c0d1e4da30aa15f32d4ca524aeabd26fc50cf 100644 +index 26620c06d26a2c0eb957fbadc6ac3d7a309bff46..3858c83c58e78435a6e29de84c33faa2f26d593d 100644 --- a/src/main/java/net/minecraft/world/ticks/LevelChunkTicks.java +++ b/src/main/java/net/minecraft/world/ticks/LevelChunkTicks.java -@@ -18,7 +18,7 @@ import net.minecraft.core.BlockPos; +@@ -17,7 +17,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.nbt.ListTag; import net.minecraft.world.level.ChunkPos; @@ -32589,7 +31917,7 @@ index 47c2b2da9799690291396effb9e1b06d71efc6fd..c42c0d1e4da30aa15f32d4ca524aeabd private final Queue> tickQueue = new PriorityQueue<>(ScheduledTick.DRAIN_ORDER); @Nullable private List> pendingTicks; -@@ -26,6 +26,30 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon +@@ -25,6 +25,30 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon @Nullable private BiConsumer, ScheduledTick> onTickAdded; @@ -32620,7 +31948,7 @@ index 47c2b2da9799690291396effb9e1b06d71efc6fd..c42c0d1e4da30aa15f32d4ca524aeabd public LevelChunkTicks() { } -@@ -50,7 +74,7 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon +@@ -49,7 +73,7 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon public ScheduledTick poll() { ScheduledTick scheduledTick = this.tickQueue.poll(); if (scheduledTick != null) { @@ -32629,7 +31957,7 @@ index 47c2b2da9799690291396effb9e1b06d71efc6fd..c42c0d1e4da30aa15f32d4ca524aeabd } return scheduledTick; -@@ -59,7 +83,7 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon +@@ -58,7 +82,7 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon @Override public void schedule(ScheduledTick orderedTick) { if (this.ticksPerPosition.add(orderedTick)) { @@ -32638,7 +31966,7 @@ index 47c2b2da9799690291396effb9e1b06d71efc6fd..c42c0d1e4da30aa15f32d4ca524aeabd } } -@@ -81,7 +105,7 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon +@@ -80,7 +104,7 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon while (iterator.hasNext()) { ScheduledTick scheduledTick = iterator.next(); if (predicate.test(scheduledTick)) { @@ -32647,15 +31975,15 @@ index 47c2b2da9799690291396effb9e1b06d71efc6fd..c42c0d1e4da30aa15f32d4ca524aeabd this.ticksPerPosition.remove(scheduledTick); } } -@@ -98,6 +122,7 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon +@@ -110,6 +134,7 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon + } - @Override - public ListTag save(long l, Function function) { -+ this.lastSaved = l; // Paper - rewrite chunk system + public ListTag save(long time, Function typeToNameFunction) { ++ this.lastSaved = time; // Paper - rewrite chunk system ListTag listTag = new ListTag(); - if (this.pendingTicks != null) { - for (SavedTick savedTick : this.pendingTicks) { -@@ -114,6 +139,7 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon + + for (SavedTick savedTick : this.pack(time)) { +@@ -121,6 +146,7 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon public void unpack(long time) { if (this.pendingTicks != null) { @@ -32664,7 +31992,7 @@ index 47c2b2da9799690291396effb9e1b06d71efc6fd..c42c0d1e4da30aa15f32d4ca524aeabd for (SavedTick savedTick : this.pendingTicks) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java -index 69c7fe5bf5b914276a9f7a0e57ce668e569d91f9..33322b57b4c6922f4daad0f584733f0f24083911 100644 +index 887a17a0833064eb5701222e5fb6f5ccf9511588..ca1dd58229b7e39dffdd7a69c296dc5f652aa5e6 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -82,6 +82,12 @@ public class CraftChunk implements Chunk { @@ -32706,7 +32034,7 @@ index 69c7fe5bf5b914276a9f7a0e57ce668e569d91f9..33322b57b4c6922f4daad0f584733f0f - entityManager.ensureChunkQueuedForLoad(pair); // Start entity loading - - // SPIGOT-6772: Use entity mailbox and re-schedule entities if they get unloaded -- ProcessorMailbox mailbox = ((EntityStorage) entityManager.permanentStorage).entityDeserializerQueue; +- ConsecutiveExecutor mailbox = ((EntityStorage) entityManager.permanentStorage).entityDeserializerQueue; - BooleanSupplier supplier = () -> { - // only execute inbox if our entities are not present - if (entityManager.areEntitiesLoaded(pair)) { @@ -32744,10 +32072,10 @@ index 69c7fe5bf5b914276a9f7a0e57ce668e569d91f9..33322b57b4c6922f4daad0f584733f0f @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 35d1dcabb182b0a31727e5ddefe33955c804603b..0bad47a4d45e9ca399de98edd0956efb90d21062 100644 +index f85e8ec660bf588f694aa96e6e2ade478a9696b7..625f45b50654732231c835df867f9d84897dd211 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1430,7 +1430,7 @@ public final class CraftServer implements Server { +@@ -1356,7 +1356,7 @@ public final class CraftServer implements Server { // Paper - Put world into worldlist before initing the world; move up this.getServer().prepareLevels(internal.getChunkSource().chunkMap.progressListener, internal); @@ -32756,7 +32084,7 @@ index 35d1dcabb182b0a31727e5ddefe33955c804603b..0bad47a4d45e9ca399de98edd0956efb this.pluginManager.callEvent(new WorldLoadEvent(internal.getWorld())); return internal.getWorld(); -@@ -1475,7 +1475,7 @@ public final class CraftServer implements Server { +@@ -1401,7 +1401,7 @@ public final class CraftServer implements Server { } handle.getChunkSource().close(save); @@ -32765,7 +32093,7 @@ index 35d1dcabb182b0a31727e5ddefe33955c804603b..0bad47a4d45e9ca399de98edd0956efb handle.convertable.close(); } catch (Exception ex) { this.getLogger().log(Level.SEVERE, null, ex); -@@ -2511,7 +2511,7 @@ public final class CraftServer implements Server { +@@ -2368,7 +2368,7 @@ public final class CraftServer implements Server { @Override public boolean isPrimaryThread() { @@ -32775,10 +32103,10 @@ index 35d1dcabb182b0a31727e5ddefe33955c804603b..0bad47a4d45e9ca399de98edd0956efb // Paper start - Adventure diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 3e5d381c0f2cfaf46292db0819d4996edf6e8564..5ff343759cc0c5046a9d45e8f74d4e6ec63f0f91 100644 +index 03cef3e33de1cf2a1ad4c7a5ba9a65ee3b69ee52..570c129cac344d22da903c84e95e37fcc03703e9 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -461,10 +461,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -458,10 +458,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z)); if (playerChunk == null) return false; @@ -32796,7 +32124,7 @@ index 3e5d381c0f2cfaf46292db0819d4996edf6e8564..5ff343759cc0c5046a9d45e8f74d4e6e ClientboundLevelChunkWithLightPacket refreshPacket = new ClientboundLevelChunkWithLightPacket(chunk, this.world.getLightEngine(), null, null); for (ServerPlayer player : playersInRange) { -@@ -472,8 +476,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -469,8 +473,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { player.connection.send(refreshPacket); } @@ -32806,7 +32134,7 @@ index 3e5d381c0f2cfaf46292db0819d4996edf6e8564..5ff343759cc0c5046a9d45e8f74d4e6e return true; } -@@ -577,20 +580,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -574,20 +577,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public Collection getPluginChunkTickets(int x, int z) { DistanceManager chunkDistanceManager = this.world.getChunkSource().chunkMap.distanceManager; @@ -32828,7 +32156,7 @@ index 3e5d381c0f2cfaf46292db0819d4996edf6e8564..5ff343759cc0c5046a9d45e8f74d4e6e } @Override -@@ -598,7 +589,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -595,7 +586,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { Map> ret = new HashMap<>(); DistanceManager chunkDistanceManager = this.world.getChunkSource().chunkMap.distanceManager; @@ -32837,7 +32165,7 @@ index 3e5d381c0f2cfaf46292db0819d4996edf6e8564..5ff343759cc0c5046a9d45e8f74d4e6e long chunkKey = chunkTickets.getLongKey(); SortedArraySet> tickets = chunkTickets.getValue(); -@@ -1297,12 +1288,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1278,12 +1269,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public int getViewDistance() { @@ -32852,7 +32180,7 @@ index 3e5d381c0f2cfaf46292db0819d4996edf6e8564..5ff343759cc0c5046a9d45e8f74d4e6e } public BlockMetadataStore getBlockMetadata() { -@@ -2440,17 +2431,20 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2416,17 +2407,20 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setSimulationDistance(final int simulationDistance) { @@ -32877,10 +32205,10 @@ index 3e5d381c0f2cfaf46292db0819d4996edf6e8564..5ff343759cc0c5046a9d45e8f74d4e6e // Paper start - implement pointers diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 5f12c91ea598b4b133bf41532a9864645ebf6cea..e02fa642f11809607e30e22b51c65373edd70842 100644 +index cdc53abb5572fa57b4ec98a694c5583ad0982a05..e59572f05b69b8302b69de8cbcfbc889f67634b5 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3496,7 +3496,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3402,7 +3402,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setViewDistance(final int viewDistance) { @@ -32891,7 +32219,7 @@ index 5f12c91ea598b4b133bf41532a9864645ebf6cea..e02fa642f11809607e30e22b51c65373 } @Override -@@ -3506,7 +3508,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3412,7 +3414,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setSimulationDistance(final int simulationDistance) { @@ -32902,7 +32230,7 @@ index 5f12c91ea598b4b133bf41532a9864645ebf6cea..e02fa642f11809607e30e22b51c65373 } @Override -@@ -3516,6 +3520,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3422,6 +3426,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setSendViewDistance(final int viewDistance) { @@ -32913,10 +32241,10 @@ index 5f12c91ea598b4b133bf41532a9864645ebf6cea..e02fa642f11809607e30e22b51c65373 } } diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java -index 5717c0e1d6df07a4613356dc78d970d2101c68d7..cab7ca4218e5903b6a5e518af55457b9a1b5111c 100644 +index 625562a38bc78feae3ae4b50b9afefbd05ff767a..e34060c21755c61228ba91e468b7c92fc4c4cf0c 100644 --- a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java +++ b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java -@@ -263,7 +263,7 @@ public class CustomChunkGenerator extends InternalChunkGenerator { +@@ -262,7 +262,7 @@ public class CustomChunkGenerator extends InternalChunkGenerator { return ichunkaccess1; }; @@ -32926,10 +32254,10 @@ index 5717c0e1d6df07a4613356dc78d970d2101c68d7..cab7ca4218e5903b6a5e518af55457b9 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java -index fceed3d08ee6f4c171685986bb19d2be592eedc6..bf18f9ad7dec2b09ebfcb5ec6566f2556e842f22 100644 +index e444662ee4d9405eeea7caa41b9cd6b36586d840..504ab4b545e084c962ebd5f26d9336adc16030fb 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java +++ b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java -@@ -829,5 +829,12 @@ public abstract class DelegatedGeneratorAccess implements WorldGenLevel { +@@ -808,6 +808,13 @@ public abstract class DelegatedGeneratorAccess implements WorldGenLevel { public ChunkAccess getChunkIfLoadedImmediately(final int x, final int z) { return this.handle.getChunkIfLoadedImmediately(x, z); } @@ -32942,6 +32270,7 @@ index fceed3d08ee6f4c171685986bb19d2be592eedc6..bf18f9ad7dec2b09ebfcb5ec6566f255 + // Paper end - rewrite chunk system // Paper end } + diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java index ef2598760458833021ef1bee92137f42c9fe591f..1f23e775eba1c34e01145bd91b0ce26fed6ca9de 100644 --- a/src/main/java/org/spigotmc/AsyncCatcher.java diff --git a/patches/server/1072-fixup-Optimize-BlockPosition-helper-methods.patch b/patches/server/0827-fixup-Optimize-BlockPosition-helper-methods.patch similarity index 85% rename from patches/server/1072-fixup-Optimize-BlockPosition-helper-methods.patch rename to patches/server/0827-fixup-Optimize-BlockPosition-helper-methods.patch index f68e9eae926d..5a70b45e9548 100644 --- a/patches/server/1072-fixup-Optimize-BlockPosition-helper-methods.patch +++ b/patches/server/0827-fixup-Optimize-BlockPosition-helper-methods.patch @@ -5,10 +5,10 @@ Subject: [PATCH] fixup! Optimize BlockPosition helper methods diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java -index 2767d6f97e8b314d23a8e62f22dfd396f5660d31..7362d471f9c1858e0dd7832e1ff59e3e51d7f249 100644 +index 0d51fb4be8b49e3b57c3c55aff6bcf13d5c78ddd..a1d54d978d34d75475f92dfb806113586e7e449c 100644 --- a/src/main/java/net/minecraft/core/BlockPos.java +++ b/src/main/java/net/minecraft/core/BlockPos.java -@@ -161,7 +161,7 @@ public class BlockPos extends Vec3i { +@@ -162,7 +162,7 @@ public class BlockPos extends Vec3i { @Override public BlockPos above(int distance) { @@ -17,7 +17,7 @@ index 2767d6f97e8b314d23a8e62f22dfd396f5660d31..7362d471f9c1858e0dd7832e1ff59e3e } @Override -@@ -171,7 +171,7 @@ public class BlockPos extends Vec3i { +@@ -172,7 +172,7 @@ public class BlockPos extends Vec3i { @Override public BlockPos below(int i) { @@ -26,7 +26,7 @@ index 2767d6f97e8b314d23a8e62f22dfd396f5660d31..7362d471f9c1858e0dd7832e1ff59e3e } @Override -@@ -181,7 +181,7 @@ public class BlockPos extends Vec3i { +@@ -182,7 +182,7 @@ public class BlockPos extends Vec3i { @Override public BlockPos north(int distance) { @@ -35,7 +35,7 @@ index 2767d6f97e8b314d23a8e62f22dfd396f5660d31..7362d471f9c1858e0dd7832e1ff59e3e } @Override -@@ -191,7 +191,7 @@ public class BlockPos extends Vec3i { +@@ -192,7 +192,7 @@ public class BlockPos extends Vec3i { @Override public BlockPos south(int distance) { @@ -44,7 +44,7 @@ index 2767d6f97e8b314d23a8e62f22dfd396f5660d31..7362d471f9c1858e0dd7832e1ff59e3e } @Override -@@ -201,7 +201,7 @@ public class BlockPos extends Vec3i { +@@ -202,7 +202,7 @@ public class BlockPos extends Vec3i { @Override public BlockPos west(int distance) { @@ -53,7 +53,7 @@ index 2767d6f97e8b314d23a8e62f22dfd396f5660d31..7362d471f9c1858e0dd7832e1ff59e3e } @Override -@@ -211,7 +211,7 @@ public class BlockPos extends Vec3i { +@@ -212,7 +212,7 @@ public class BlockPos extends Vec3i { @Override public BlockPos east(int distance) { diff --git a/patches/server/1073-fixup-Moonrise-optimisation-patches.patch b/patches/server/0828-fixup-Moonrise-optimisation-patches.patch similarity index 96% rename from patches/server/1073-fixup-Moonrise-optimisation-patches.patch rename to patches/server/0828-fixup-Moonrise-optimisation-patches.patch index 031f4c876b01..e2197234c7b8 100644 --- a/patches/server/1073-fixup-Moonrise-optimisation-patches.patch +++ b/patches/server/0828-fixup-Moonrise-optimisation-patches.patch @@ -361,37 +361,35 @@ index 0000000000000000000000000000000000000000..b5335a2a8cb5dc7637c7112c8f719338 + } +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java -index 5fca5dc7cdfa976bcc58dfcf0d14abb78a931475..cee2c8efbe280e20c63e2d66464dc835cd328e4a 100644 +index 49160a30b8e19e5c5ada811fbcae2a05959524f3..44bb25554634af2ec0b2e9b3d9231304d5dff034 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java -@@ -1,5 +1,6 @@ +@@ -1,10 +1,11 @@ package ca.spottedleaf.moonrise.patches.chunk_system; +import ca.spottedleaf.moonrise.common.PlatformHooks; import net.minecraft.SharedConstants; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; -@@ -25,21 +26,13 @@ public final class ChunkSystemConverters { + import net.minecraft.server.level.ServerLevel; +-import net.minecraft.util.datafix.DataFixTypes; ++import net.minecraft.util.datafix.fixes.References; + + public final class ChunkSystemConverters { + +@@ -25,13 +26,13 @@ public final class ChunkSystemConverters { public static CompoundTag convertPoiCompoundTag(final CompoundTag data, final ServerLevel world) { final int dataVersion = getDataVersion(data, DEFAULT_POI_DATA_VERSION); -- // Paper start - dataconverter -- return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( -- ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.POI_CHUNK, data, dataVersion, getCurrentVersion() -- ); -- // Paper end - dataconverter -+ return PlatformHooks.get().convertNBT(DataFixTypes.POI_CHUNK, world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); +- return DataFixTypes.POI_CHUNK.update(world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); ++ return PlatformHooks.get().convertNBT(References.POI_CHUNK, world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); } public static CompoundTag convertEntityChunkCompoundTag(final CompoundTag data, final ServerLevel world) { final int dataVersion = getDataVersion(data, DEFAULT_ENTITY_CHUNK_DATA_VERSION); -- // Paper start - dataconverter -- return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( -- ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ENTITY_CHUNK, data, dataVersion, getCurrentVersion() -- ); -- // Paper end - dataconverter -+ return PlatformHooks.get().convertNBT(DataFixTypes.ENTITY_CHUNK, world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); +- return DataFixTypes.ENTITY_CHUNK.update(world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); ++ return PlatformHooks.get().convertNBT(References.ENTITY_CHUNK, world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); } private ChunkSystemConverters() {} @@ -3839,7 +3837,7 @@ index 883fe6401f1b9711fa544d18a815b4d638f580df..aacd543f03b35908011d0c2891e978cc + } diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -index 5c7f2471a0b15ac2e714527296ad2aa7291999eb..40dc7569c32b100d4eebbde9024ded2acbb2fb20 100644 +index 997b05167c19472acb98edac32d4548cc65efa8e..5ed6599d1f9a2edf8c904f3602b06d26d857600c 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java @@ -1,6 +1,8 @@ @@ -3898,27 +3896,16 @@ index 5c7f2471a0b15ac2e714527296ad2aa7291999eb..40dc7569c32b100d4eebbde9024ded2a } // Paper start - rewrite chunk system -@@ -100,18 +104,7 @@ public final class ChunkEntitySlices { +@@ -100,7 +104,7 @@ public final class ChunkEntitySlices { } final ListTag entitiesTag = new ListTag(); -- final java.util.Map, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk - for (final Entity entity : entities) { -- // Paper start - Entity load/save limit per chunk -- final EntityType entityType = entity.getType(); -- final int saveLimit = world.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1); -- if (saveLimit > -1) { -- if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) { -- continue; -- } -- savedEntityCounts.merge(entityType, 1, Integer::sum); -- } -- // Paper end - Entity load/save limit per chunk + for (final Entity entity : PlatformHooks.get().modifySavedEntities(world, chunkPos.x, chunkPos.z, entities)) { CompoundTag compoundTag = new CompoundTag(); if (entity.save(compoundTag)) { entitiesTag.add(compoundTag); -@@ -158,12 +151,12 @@ public final class ChunkEntitySlices { +@@ -147,12 +151,12 @@ public final class ChunkEntitySlices { continue; } if (entity.shouldBeSaved()) { @@ -3933,7 +3920,7 @@ index 5c7f2471a0b15ac2e714527296ad2aa7291999eb..40dc7569c32b100d4eebbde9024ded2a } } } -@@ -172,33 +165,6 @@ public final class ChunkEntitySlices { +@@ -161,34 +165,7 @@ public final class ChunkEntitySlices { return this.entities.size() != 0; } @@ -3964,10 +3951,12 @@ index 5c7f2471a0b15ac2e714527296ad2aa7291999eb..40dc7569c32b100d4eebbde9024ded2a - } - // Paper end - - private List getAllEntities() { +- private List getAllEntities() { ++ public List getAllEntities() { final int len = this.entities.size(); if (len == 0) { -@@ -262,6 +228,7 @@ public final class ChunkEntitySlices { + return new ArrayList<>(); +@@ -251,6 +228,7 @@ public final class ChunkEntitySlices { return false; } ((ChunkSystemEntity)entity).moonrise$setChunkStatus(this.status); @@ -3975,7 +3964,7 @@ index 5c7f2471a0b15ac2e714527296ad2aa7291999eb..40dc7569c32b100d4eebbde9024ded2a final int sectionIndex = chunkSection - this.minSection; this.allEntities.addEntity(entity, sectionIndex); -@@ -295,6 +262,7 @@ public final class ChunkEntitySlices { +@@ -284,6 +262,7 @@ public final class ChunkEntitySlices { return false; } ((ChunkSystemEntity)entity).moonrise$setChunkStatus(null); @@ -4287,7 +4276,7 @@ index fd35e4db0c8fec8f86b8743bcc2b15ed2e7433f1..bbf9d6c1c9525d97160806819a57be03 // completely empty, no point in storing this continue; diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java -index 3f5edb756beb9c31b6f591a24b778d6ac2b0bf51..23bd741dc0bfd48b8064a2b498d71cfa8f8145b2 100644 +index fb87d7ece6ebccfd0ffd2f1a609b45a0d2461d9e..524752744e37a2db0e3ea089468bdf497129bfef 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java @@ -1,12 +1,8 @@ @@ -4304,7 +4293,7 @@ index 3f5edb756beb9c31b6f591a24b778d6ac2b0bf51..23bd741dc0bfd48b8064a2b498d71cfa public interface ChunkSystemSectionStorage { diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -index a608f57ebca98eda88ad749d0aad021678be54f9..b2fa9883aefb07f64bb5db7e0052218d2ad09aba 100644 +index 852d75a73dae7448cbe1e2f5e164b235efa8a969..b2fa9883aefb07f64bb5db7e0052218d2ad09aba 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java @@ -1,7 +1,8 @@ @@ -4425,16 +4414,16 @@ index a608f57ebca98eda88ad749d0aad021678be54f9..b2fa9883aefb07f64bb5db7e0052218d // send view distances this.player.connection.send(this.updateClientChunkRadius(sendViewDistance)); this.player.connection.send(this.updateClientSimulationDistance(tickViewDistance)); -@@ -1079,8 +1078,7 @@ public final class RegionizedPlayerChunkLoader { +@@ -1078,5 +1077,9 @@ public final class RegionizedPlayerChunkLoader { + // now all tickets should be removed, which is all of our external state } - -- // For external checks -- public it.unimi.dsi.fastutil.longs.LongOpenHashSet getSentChunksRaw() { ++ + public LongOpenHashSet getSentChunksRaw() { - return this.sentChunks; - } ++ return this.sentChunks; ++ } } + } diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java index 58d3d1a47e9f2423c467bb329c2d5f4b58a8b5ef..f98df65eaed2abedc66f3a49790e0cfb65354ed9 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java @@ -6173,7 +6162,7 @@ index e0b26ccb63596748b80fc6a5e47e373ba811ba8b..5f4b99d8c5453f8ad2e600a57ea4e7da \ No newline at end of file +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java -index fbdf721e8b4cfe6cef4ee60c53c680cbfc858d88..98382575eb6cd48aa163264e4935c812db1f1aff 100644 +index fbdf721e8b4cfe6cef4ee60c53c680cbfc858d88..6ab353b0d2465c3680bb3c8d0852ba0f65c00fd2 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java @@ -1,7 +1,9 @@ @@ -6210,7 +6199,7 @@ index fbdf721e8b4cfe6cef4ee60c53c680cbfc858d88..98382575eb6cd48aa163264e4935c812 final ProtoChunk protoChunk = (ProtoChunk)this.fromChunk; chunk = new LevelChunk(this.world, protoChunk, (final LevelChunk unused) -> { - ChunkStatusTasks.postLoadProtoChunk(world, protoChunk.getEntities(), protoChunk.getPos()); // Paper - pass chunk pos -+ ChunkStatusTasks.postLoadProtoChunk(world, protoChunk.getEntities()); ++ PlatformHooks.get().postLoadProtoChunk(world, protoChunk); }); this.chunkHolder.replaceProtoChunk(new ImposterProtoChunk(chunk, false)); } @@ -9985,10 +9974,10 @@ index 57692a503e147a00ac4e1586cd78e12b71a80d3f..689ce367164e79e0426eeecb81dbbc52 public static void saveLightHook(final Level world, final ChunkAccess chunk, final CompoundTag nbt) { try { diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index a9dd0e5216e95afd98fd2200d110e2cc0b1b0dca..8371ce4e3df5ef8e39acd6e005209337cc76b451 100644 +index 9bd509915b391e9d382fe47798e2c345b6e59a9a..65c7e7a1b1a5472ee03149bb4ccd9f7d0229069b 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -243,6 +243,7 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -242,6 +242,7 @@ public class GlobalConfiguration extends ConfigurationPart { @PostProcess private void postProcess() { @@ -9997,12 +9986,12 @@ index a9dd0e5216e95afd98fd2200d110e2cc0b1b0dca..8371ce4e3df5ef8e39acd6e005209337 } } diff --git a/src/main/java/net/minecraft/core/MappedRegistry.java b/src/main/java/net/minecraft/core/MappedRegistry.java -index f22d22ebcedcc9c20225677844c86a1ad27c4211..ee1d39b6196c0f87ba473a15d3377e858922696c 100644 +index 71e04e5c1bc0722abf8ca2e0738bd60b6d7ae21c..8e0dfaf02343d74ce786e4fc647bc4c1d73c0014 100644 --- a/src/main/java/net/minecraft/core/MappedRegistry.java +++ b/src/main/java/net/minecraft/core/MappedRegistry.java -@@ -78,6 +78,19 @@ public class MappedRegistry implements WritableRegistry { - }; - private final Object tagAdditionLock = new Object(); +@@ -50,6 +50,19 @@ public class MappedRegistry implements WritableRegistry { + return this.getTags(); + } + // Paper start - fluid method optimisations + private void injectFluidRegister( @@ -10020,22 +10009,22 @@ index f22d22ebcedcc9c20225677844c86a1ad27c4211..ee1d39b6196c0f87ba473a15d3377e85 public MappedRegistry(ResourceKey> key, Lifecycle lifecycle) { this(key, lifecycle, false); } -@@ -145,6 +158,7 @@ public class MappedRegistry implements WritableRegistry { - this.toId.put(value, i); - this.registrationInfos.put(key, info); - this.registryLifecycle = this.registryLifecycle.add(info.lifecycle()); -+ this.injectFluidRegister(key, value); // Paper - fluid method optimisations - return reference; +@@ -114,6 +127,7 @@ public class MappedRegistry implements WritableRegistry { + this.toId.put(value, i); + this.registrationInfos.put(key, info); + this.registryLifecycle = this.registryLifecycle.add(info.lifecycle()); ++ this.injectFluidRegister(key, value); // Paper - fluid method optimisations + return reference; + } } - diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 696d075ca2883f3c37e35f983c4d020e5db89d16..25047b8536bc7e7a91ac0dfb82ad77099af6f125 100644 +index 7c388e230c4a88edf6212dd8990e8238d3265ebf..8a66012b7f2396031840c8c718f49f8aab716ee0 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1106,7 +1106,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop trackerEntities = entityLookup.trackerEntities; -@@ -927,21 +926,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -921,21 +920,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider if (tracker == null) { continue; } @@ -10099,7 +10088,7 @@ index af8cb316ac169aa8d98a88765b85bb013b9ba961..38de8d8ed2efa3476d4e906bdc4b5944 } } // Paper end - optimise entity tracker -@@ -1178,6 +1167,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1172,6 +1161,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.removePlayer(player); } } @@ -10111,7 +10100,7 @@ index af8cb316ac169aa8d98a88765b85bb013b9ba961..38de8d8ed2efa3476d4e906bdc4b5944 // Paper end - optimise entity tracker public TrackedEntity(final Entity entity, final int i, final int j, final boolean flag) { -@@ -1283,20 +1277,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1262,20 +1256,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } private int getEffectiveRange() { @@ -10147,10 +10136,10 @@ index af8cb316ac169aa8d98a88765b85bb013b9ba961..38de8d8ed2efa3476d4e906bdc4b5944 public void updatePlayers(List players) { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index dcb5651d1d9b10b40430fb2f713beedf68336704..b380509cc942a054ea176216210ba69f5b517ae9 100644 +index 22157cbc4e4bb1e4010116bdf7429815d46bff2e..23a13bfd23514cde6dcf8d59ba3b43d84f266aad 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -92,7 +92,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -99,7 +99,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler chunkTaskScheduler = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler(); final CompletableFuture completable = new CompletableFuture<>(); chunkTaskScheduler.scheduleChunkLoad( @@ -10159,7 +10148,7 @@ index dcb5651d1d9b10b40430fb2f713beedf68336704..b380509cc942a054ea176216210ba69f completable::complete ); -@@ -123,6 +123,15 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -130,6 +130,15 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon return ifPresent; } @@ -10175,7 +10164,7 @@ index dcb5651d1d9b10b40430fb2f713beedf68336704..b380509cc942a054ea176216210ba69f return load ? this.syncLoad(chunkX, chunkZ, toStatus) : null; } // Paper end - rewrite chunk system -@@ -242,7 +251,24 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -254,7 +263,24 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @Nullable @Override public LevelChunk getChunkNow(int chunkX, int chunkZ) { @@ -10201,7 +10190,7 @@ index dcb5651d1d9b10b40430fb2f713beedf68336704..b380509cc942a054ea176216210ba69f } private void clearCache() { -@@ -299,7 +325,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -311,7 +337,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().scheduleChunkLoad( chunkX, chunkZ, leastStatus, true, @@ -10210,7 +10199,7 @@ index dcb5651d1d9b10b40430fb2f713beedf68336704..b380509cc942a054ea176216210ba69f complete ); -@@ -556,7 +582,8 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -549,7 +575,8 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon private void getFullChunk(long pos, Consumer chunkConsumer) { // Paper start - rewrite chunk system @@ -10221,10 +10210,10 @@ index dcb5651d1d9b10b40430fb2f713beedf68336704..b380509cc942a054ea176216210ba69f chunkConsumer.accept(fullChunk); } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index f9abf63e12ea930275121b470e4e4906cff0fc12..55e81892b928a02e240aaa31dd501b0aacef8dbe 100644 +index af27a004f618912d6a5f1d2c82c8e7e9fb00a037..c7523387f0e9bbfe952abd237a936c8319f10200 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -799,11 +799,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -775,11 +775,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } // Paper start - optimise random ticking @@ -10240,7 +10229,7 @@ index f9abf63e12ea930275121b470e4e4906cff0fc12..55e81892b928a02e240aaa31dd501b0a final ChunkPos cpos = chunk.getPos(); final int offsetX = cpos.x << 4; -@@ -813,39 +815,32 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -789,39 +791,32 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe final int offsetY = (sectionIndex + minSection) << 4; final LevelChunkSection section = sections[sectionIndex]; final net.minecraft.world.level.chunk.PalettedContainer states = section.states; @@ -10289,7 +10278,7 @@ index f9abf63e12ea930275121b470e4e4906cff0fc12..55e81892b928a02e240aaa31dd501b0a } } } -@@ -856,6 +851,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -832,6 +827,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // Paper end - optimise random ticking public void tickChunk(LevelChunk chunk, int randomTickSpeed) { @@ -10297,8 +10286,8 @@ index f9abf63e12ea930275121b470e4e4906cff0fc12..55e81892b928a02e240aaa31dd501b0a ChunkPos chunkcoordintpair = chunk.getPos(); boolean flag = this.isRaining(); int j = chunkcoordintpair.getMinBlockX(); -@@ -863,7 +859,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - ProfilerFiller gameprofilerfiller = this.getProfiler(); +@@ -839,7 +835,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + ProfilerFiller gameprofilerfiller = Profiler.get(); gameprofilerfiller.push("thunder"); - if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - Option to disable thunder @@ -10306,7 +10295,7 @@ index f9abf63e12ea930275121b470e4e4906cff0fc12..55e81892b928a02e240aaa31dd501b0a BlockPos blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15)); if (this.isRainingAt(blockposition)) { -@@ -895,7 +891,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -871,7 +867,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (!this.paperConfig().environment.disableIceAndSnow) { // Paper - Option to disable ice and snow for (int l = 0; l < randomTickSpeed; ++l) { @@ -10316,10 +10305,10 @@ index f9abf63e12ea930275121b470e4e4906cff0fc12..55e81892b928a02e240aaa31dd501b0a } } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 5e2c4969e77c669acbb4a13c07033cb267c3d586..f1371f3b9ea0cda0cf146d876828a6823632463c 100644 +index 4fe3024e26b56c2d796acf703a1bc200ff309f09..7529b3d90e65036c7bf869af30475932d547b3ab 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1475,7 +1475,7 @@ public abstract class PlayerList { +@@ -1407,7 +1407,7 @@ public abstract class PlayerList { public void setViewDistance(int viewDistance) { this.viewDistance = viewDistance; @@ -10616,10 +10605,10 @@ index 15c5164d0ef41a978c16ee317fa73e97f2480207..1f9c436a632e4f110be61cf76fcfc3b7 return ret; } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..379456dd5c18ca627b9cf6a473fd0355e8d839ef 100644 +index 5410a0380c44629f1c9b4f0a8e6017cfc5a31a89..a3b0363fbc207ed9edc8a4d6619b6fff9389a9c7 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -461,6 +461,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -448,6 +448,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // Paper start - rewrite chunk system private final boolean isHardColliding = this.moonrise$isHardCollidingUncached(); private net.minecraft.server.level.FullChunkStatus chunkStatus; @@ -10627,7 +10616,7 @@ index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..379456dd5c18ca627b9cf6a473fd0355 private int sectionX = Integer.MIN_VALUE; private int sectionY = Integer.MIN_VALUE; private int sectionZ = Integer.MIN_VALUE; -@@ -481,6 +482,16 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -468,6 +469,16 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.chunkStatus = status; } @@ -10644,7 +10633,7 @@ index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..379456dd5c18ca627b9cf6a473fd0355 @Override public final int moonrise$getSectionX() { return this.sectionX; -@@ -529,6 +540,54 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -516,6 +527,54 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this.getIndirectPassengersStream().anyMatch((entity) -> entity instanceof Player); } // Paper end - rewrite chunk system @@ -10699,7 +10688,7 @@ index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..379456dd5c18ca627b9cf6a473fd0355 // Paper start - optimise entity tracker private net.minecraft.server.level.ChunkMap.TrackedEntity trackedEntity; -@@ -1465,73 +1524,67 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1402,73 +1461,67 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return movement; } @@ -10818,7 +10807,7 @@ index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..379456dd5c18ca627b9cf6a473fd0355 // Paper end - optimise collisions } -@@ -2853,64 +2906,99 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2836,64 +2889,99 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return false; } @@ -10935,11 +10924,11 @@ index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..379456dd5c18ca627b9cf6a473fd0355 + if (collisionShape.isEmpty()) { + continue; + } ++ ++ final AABB toCollide = boundingBox.move(-(double)blockX, -(double)blockY, -(double)blockZ); - if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersectNoEmpty(collisionShape, toCollide)) { - return true; -+ final AABB toCollide = boundingBox.move(-(double)blockX, -(double)blockY, -(double)blockZ); -+ + final AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)collisionShape).moonrise$getSingleAABBRepresentation(); + if (singleAABB != null) { + if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersect(singleAABB, toCollide)) { @@ -10959,7 +10948,7 @@ index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..379456dd5c18ca627b9cf6a473fd0355 } } } -@@ -4451,82 +4539,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4508,82 +4596,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return Mth.lerp(delta, this.yRotO, this.yRot); } @@ -10982,32 +10971,36 @@ index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..379456dd5c18ca627b9cf6a473fd0355 - Vec3 vec3d = Vec3.ZERO; - int k1 = 0; - BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); -+ } - +- - for (int l1 = i; l1 < j; ++l1) { - for (int i2 = k; i2 < l; ++i2) { - for (int j2 = i1; j2 < j1; ++j2) { - blockposition_mutableblockposition.set(l1, i2, j2); - FluidState fluid = this.level().getFluidState(blockposition_mutableblockposition); -+ final AABB boundingBox = this.getBoundingBox().deflate(1.0E-3); - +- - if (fluid.is(tag)) { - double d2 = (double) ((float) i2 + fluid.getHeight(this.level(), blockposition_mutableblockposition)); -+ final Level world = this.level; -+ final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(world); - +- - if (d2 >= axisalignedbb.minY) { - flag1 = true; - d1 = Math.max(d2 - axisalignedbb.minY, d1); - if (flag) { - Vec3 vec3d1 = fluid.getFlow(this.level(), blockposition_mutableblockposition); -+ final int minBlockX = Mth.floor(boundingBox.minX); -+ final int minBlockY = Math.max((minSection << 4), Mth.floor(boundingBox.minY)); -+ final int minBlockZ = Mth.floor(boundingBox.minZ); - +- - if (d1 < 0.4D) { - vec3d1 = vec3d1.scale(d1); - } ++ } ++ ++ final AABB boundingBox = this.getBoundingBox().deflate(1.0E-3); ++ ++ final Level world = this.level; ++ final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(world); ++ ++ final int minBlockX = Mth.floor(boundingBox.minX); ++ final int minBlockY = Math.max((minSection << 4), Mth.floor(boundingBox.minY)); ++ final int minBlockZ = Mth.floor(boundingBox.minZ); ++ + // note: bounds are exclusive in Vanilla, so we subtract 1 - our loop expects bounds to be inclusive + final int maxBlockX = Mth.ceil(boundingBox.maxX) - 1; + final int maxBlockY = Math.min((ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection(world) << 4) | 15, Mth.ceil(boundingBox.maxY) - 1); @@ -11015,9 +11008,7 @@ index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..379456dd5c18ca627b9cf6a473fd0355 + + final boolean isPushable = this.isPushedByFluid(); + final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); - -- vec3d = vec3d.add(vec3d1); -- ++k1; ++ + Vec3 pushVector = Vec3.ZERO; + double totalPushes = 0.0; + double maxHeightDiff = 0.0; @@ -11037,7 +11028,9 @@ index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..379456dd5c18ca627b9cf6a473fd0355 + for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { + for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { + final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, false).getSections(); -+ + +- vec3d = vec3d.add(vec3d1); +- ++k1; + // bound y + for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) { + final int sectionIdx = currChunkY - minSection; @@ -11066,10 +11059,7 @@ index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..379456dd5c18ca627b9cf6a473fd0355 + + if (fluidState.isEmpty() || !fluidState.is(fluid)) { + continue; - } -- // CraftBukkit start - store last lava contact location -- if (tag == FluidTags.LAVA) { -- this.lastLavaContact = blockposition_mutableblockposition.immutable(); ++ } + + mutablePos.set(currX | (currChunkX << 4), currY | (currChunkY << 4), currZ | (currChunkZ << 4)); + @@ -11085,7 +11075,10 @@ index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..379456dd5c18ca627b9cf6a473fd0355 + + if (!isPushable) { + continue; -+ } + } +- // CraftBukkit start - store last lava contact location +- if (tag == FluidTags.LAVA) { +- this.lastLavaContact = blockposition_mutableblockposition.immutable(); + + ++totalPushes; + @@ -11151,10 +11144,10 @@ index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..379456dd5c18ca627b9cf6a473fd0355 public boolean touchingUnloadedChunk() { AABB axisalignedbb = this.getBoundingBox().inflate(1.0D); diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -index a908bf1dc5e821dcf6981a8c21076fb0bdc6516d..42642b49a4ed6d06f52e4076dfb745b32a964a34 100644 +index 4cf6cb0abfeb7065c6d9381fb4194371c0cddc35..5930a430983061afddf20e3208ff2462ca1b78cd 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -@@ -73,8 +73,7 @@ public class PoiManager extends SectionStorage implements ca.spotted +@@ -73,8 +73,7 @@ public class PoiManager extends SectionStorage im ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Accessing poi chunk off-main"); @@ -11164,7 +11157,7 @@ index a908bf1dc5e821dcf6981a8c21076fb0bdc6516d..42642b49a4ed6d06f52e4076dfb745b3 return ret == null ? Optional.empty() : ret.getSectionForVanilla(chunkY); } -@@ -128,9 +127,13 @@ public class PoiManager extends SectionStorage implements ca.spotted +@@ -128,9 +127,13 @@ public class PoiManager extends SectionStorage im public final void moonrise$onUnload(final long coordinate) { // Paper - rewrite chunk system final int chunkX = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkX(coordinate); final int chunkZ = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkZ(coordinate); @@ -11180,7 +11173,7 @@ index a908bf1dc5e821dcf6981a8c21076fb0bdc6516d..42642b49a4ed6d06f52e4076dfb745b3 this.updateDistanceTracking(sectionPos); } } -@@ -139,8 +142,12 @@ public class PoiManager extends SectionStorage implements ca.spotted +@@ -139,8 +142,12 @@ public class PoiManager extends SectionStorage im public final void moonrise$loadInPoiChunk(final ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk poiChunk) { final int chunkX = poiChunk.chunkX; final int chunkZ = poiChunk.chunkZ; @@ -11194,35 +11187,7 @@ index a908bf1dc5e821dcf6981a8c21076fb0bdc6516d..42642b49a4ed6d06f52e4076dfb745b3 final PoiSection section = poiChunk.getSection(sectionY); if (section != null && !((ca.spottedleaf.moonrise.patches.chunk_system.level.poi.ChunkSystemPoiSection)section).moonrise$isEmpty()) { this.onSectionLoad(SectionPos.asLong(chunkX, sectionY, chunkZ)); -@@ -166,22 +173,15 @@ public class PoiManager extends SectionStorage implements ca.spotted - - @Override - public final net.minecraft.nbt.CompoundTag moonrise$read(final int chunkX, final int chunkZ) throws java.io.IOException { -- if (!ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.isRegionFileThread()) { -- return ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.loadData( -- this.world, chunkX, chunkZ, ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.RegionFileType.POI_DATA, -- ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.getIOBlockingPriorityForCurrentThread() -- ); -- } -- return this.moonrise$getRegionStorage().read(new ChunkPos(chunkX, chunkZ)); -+ return ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.loadData( -+ this.world, chunkX, chunkZ, ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionFileType.POI_DATA, -+ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.getIOBlockingPriorityForCurrentThread() -+ ); - } - - @Override - public final void moonrise$write(final int chunkX, final int chunkZ, final net.minecraft.nbt.CompoundTag data) throws java.io.IOException { -- if (!ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.isRegionFileThread()) { -- ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.scheduleSave(this.world, chunkX, chunkZ, data, ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.RegionFileType.POI_DATA); -- return; -- } -- this.moonrise$getRegionStorage().write(new ChunkPos(chunkX, chunkZ), data); -+ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.scheduleSave(this.world, chunkX, chunkZ, data, ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionFileType.POI_DATA); - } - // Paper end - rewrite chunk system - -@@ -359,8 +359,10 @@ public class PoiManager extends SectionStorage implements ca.spotted +@@ -316,8 +323,10 @@ public class PoiManager extends SectionStorage im } public int sectionsToVillage(SectionPos pos) { @@ -11236,11 +11201,11 @@ index a908bf1dc5e821dcf6981a8c21076fb0bdc6516d..42642b49a4ed6d06f52e4076dfb745b3 boolean isVillageCenter(long pos) { diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java -index 11e895d837794d79a76303b912092096bd7d07a8..f1458b0153f6a93875f2e439759324985fa13556 100644 +index f6f0d7c21ee81ff33d4af350c4d39aadfbe140df..712cbfc100e8aaf612d1d651dae64f57f892a768 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java -@@ -43,7 +43,7 @@ public class PoiSection implements ca.spottedleaf.moonrise.patches.chunk_system. - } +@@ -31,7 +31,7 @@ public class PoiSection implements ca.spottedleaf.moonrise.patches.chunk_system. + private boolean isValid; // Paper start - rewrite chunk system - private final Optional noAllocOptional = Optional.of((PoiSection)(Object)this);; @@ -11249,10 +11214,10 @@ index 11e895d837794d79a76303b912092096bd7d07a8..f1458b0153f6a93875f2e43975932498 @Override public final boolean moonrise$isEmpty() { diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 507671476c3d2d92a2fdb05be24443af27d26dcf..41ecc30c1e38bf84655464d539ced43549b35d20 100644 +index 332dc7e6bdfb5b3741764d4877185a2e86a982f8..40fe47c7c145587ac81f0f15c237ed72ea9c094d 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -280,26 +280,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -264,26 +264,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl } // Paper end - rewrite chunk system // Paper start - optimise collisions @@ -11280,7 +11245,7 @@ index 507671476c3d2d92a2fdb05be24443af27d26dcf..41ecc30c1e38bf84655464d539ced435 final AABB boundingBox = entity.getBoundingBox(); if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(boundingBox)) { return false; -@@ -329,7 +316,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -313,7 +300,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl final Vec3 to = clipContext.getTo(); final Vec3 from = clipContext.getFrom(); @@ -11289,7 +11254,7 @@ index 507671476c3d2d92a2fdb05be24443af27d26dcf..41ecc30c1e38bf84655464d539ced435 } private static final FluidState AIR_FLUIDSTATE = Fluids.EMPTY.defaultFluidState(); -@@ -383,7 +370,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -367,7 +354,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl int lastChunkY = Integer.MIN_VALUE; int lastChunkZ = Integer.MIN_VALUE; @@ -11298,7 +11263,7 @@ index 507671476c3d2d92a2fdb05be24443af27d26dcf..41ecc30c1e38bf84655464d539ced435 for (;;) { currPos.set(currX, currY, currZ); -@@ -466,7 +453,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -450,7 +437,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl * @author Spottedleaf */ @Override @@ -11307,7 +11272,7 @@ index 507671476c3d2d92a2fdb05be24443af27d26dcf..41ecc30c1e38bf84655464d539ced435 // can only do this in this class, as not everything that implements BlockGetter can retrieve chunks return fastClip(clipContext.getFrom(), clipContext.getTo(), (Level)(Object)this, clipContext); } -@@ -476,7 +463,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -460,7 +447,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl * @author Spottedleaf */ @Override @@ -11316,7 +11281,7 @@ index 507671476c3d2d92a2fdb05be24443af27d26dcf..41ecc30c1e38bf84655464d539ced435 return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisionsForBlocksOrWorldBorder((Level)(Object)this, entity, box, null, null, ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_ONLY, (final BlockState state, final BlockPos pos) -> { -@@ -502,8 +489,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -486,8 +473,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl * @author Spottedleaf */ @Override @@ -11327,7 +11292,7 @@ index 507671476c3d2d92a2fdb05be24443af27d26dcf..41ecc30c1e38bf84655464d539ced435 if (boundsShape.isEmpty()) { return java.util.Optional.empty(); } -@@ -562,103 +549,139 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -546,103 +533,139 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl * @author Spottedleaf */ @Override @@ -11387,12 +11352,12 @@ index 507671476c3d2d92a2fdb05be24443af27d26dcf..41ecc30c1e38bf84655464d539ced435 - lastChunk = (LevelChunk)chunkSource.getChunk(newChunkX, newChunkZ, ChunkStatus.FULL, false); - } + final ChunkSource chunkSource = this.getChunkSource(); -+ + +- if (lastChunk == null) { + for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { + for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { + final ChunkAccess chunk = chunkSource.getChunk(currChunkX, currChunkZ, ChunkStatus.FULL, false); - -- if (lastChunk == null) { ++ + if (chunk == null) { continue; } @@ -11537,7 +11502,7 @@ index 507671476c3d2d92a2fdb05be24443af27d26dcf..41ecc30c1e38bf84655464d539ced435 } } } -@@ -667,6 +690,74 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -651,6 +674,74 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl return java.util.Optional.ofNullable(selected); } // Paper end - optimise collisions @@ -11612,10 +11577,10 @@ index 507671476c3d2d92a2fdb05be24443af27d26dcf..41ecc30c1e38bf84655464d539ced435 // Paper start - optimise random ticking @Override public abstract Holder getUncachedNoiseBiome(final int x, final int y, final int z); -@@ -685,6 +776,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -669,6 +760,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl // Paper end - optimise random ticking - protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - create paper world config & Anti-Xray + protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator) { // Paper - create paper world config + // Paper start - getblock optimisations - cache world height/sections + final DimensionType dimType = holder.value(); + this.minY = dimType.minY(); @@ -11628,6 +11593,24 @@ index 507671476c3d2d92a2fdb05be24443af27d26dcf..41ecc30c1e38bf84655464d539ced435 this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config this.generator = gen; +@@ -1573,7 +1673,16 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + if (slices == null) { + return new org.bukkit.entity.Entity[0]; + } +- return slices.getChunkEntities(); ++ ++ List ret = new java.util.ArrayList<>(); ++ for (Entity entity : slices.getAllEntities()) { ++ org.bukkit.entity.Entity bukkit = entity.getBukkitEntity(); ++ if (bukkit != null && bukkit.isValid()) { ++ ret.add(bukkit); ++ } ++ } ++ ++ return ret.toArray(new org.bukkit.entity.Entity[0]); + } + // Paper end - rewrite chunk system + diff --git a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java index 01352cc83b25eb0e30b7e0ff521fc7c1b3d5155b..90f8360f547ce709fd13ee34f8e67d8bfa94b498 100644 --- a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java @@ -11643,11 +11626,11 @@ index 01352cc83b25eb0e30b7e0ff521fc7c1b3d5155b..90f8360f547ce709fd13ee34f8e67d8b public interface NoiseBiomeSource { diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -index d0109633e8bdf109cfc9178963d7b6cf92f8b189..ad9c85c19146970371106050ec009a96075769c1 100644 +index a4b4fd83d201fff005c738c84fa5c1bc55d670bd..8631655a181735df53f8a02c9eb98f0cc13f55bb 100644 --- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -@@ -796,18 +796,12 @@ public abstract class BlockBehaviour implements FeatureElement { - private boolean isRandomlyTicking; +@@ -838,18 +838,12 @@ public abstract class BlockBehaviour implements FeatureElement { + private int lightBlock; // Paper start - rewrite chunk system - private int opacityIfCached; @@ -11665,7 +11648,7 @@ index d0109633e8bdf109cfc9178963d7b6cf92f8b189..ad9c85c19146970371106050ec009a96 // Paper end - rewrite chunk system // Paper start - optimise collisions private static final int RANDOM_OFFSET = 704237939; -@@ -817,16 +811,22 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -859,16 +853,22 @@ public abstract class BlockBehaviour implements FeatureElement { private final int id2 = it.unimi.dsi.fastutil.HashCommon.murmurHash3(it.unimi.dsi.fastutil.HashCommon.murmurHash3(ID_GENERATOR.getAndIncrement() + RANDOM_OFFSET) + RANDOM_OFFSET); private boolean occludesFullBlock; private boolean emptyCollisionShape; @@ -11690,7 +11673,7 @@ index d0109633e8bdf109cfc9178963d7b6cf92f8b189..ad9c85c19146970371106050ec009a96 } @Override -@@ -844,6 +844,11 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -886,6 +886,11 @@ public abstract class BlockBehaviour implements FeatureElement { return this.emptyCollisionShape; } @@ -11702,7 +11685,7 @@ index d0109633e8bdf109cfc9178963d7b6cf92f8b189..ad9c85c19146970371106050ec009a96 @Override public final int moonrise$uniqueId1() { return this.id1; -@@ -855,14 +860,9 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -897,14 +902,9 @@ public abstract class BlockBehaviour implements FeatureElement { } @Override @@ -11718,8 +11701,8 @@ index d0109633e8bdf109cfc9178963d7b6cf92f8b189..ad9c85c19146970371106050ec009a96 // Paper end - optimise collisions protected BlockStateBase(Block block, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { -@@ -931,39 +931,37 @@ public abstract class BlockBehaviour implements FeatureElement { - this.legacySolid = this.calculateSolid(); +@@ -993,39 +993,37 @@ public abstract class BlockBehaviour implements FeatureElement { + this.lightBlock = ((Block) this.owner).getLightBlock(this.asState()); // Paper start - rewrite chunk system this.isConditionallyFullOpaque = this.canOcclude & this.useShapeForLightOcclusion; - this.opacityIfCached = this.cache == null || this.isConditionallyFullOpaque ? -1 : this.cache.lightBlock; @@ -11773,10 +11756,10 @@ index d0109633e8bdf109cfc9178963d7b6cf92f8b189..ad9c85c19146970371106050ec009a96 // Paper end - optimise collisions } diff --git a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java -index daedcfd867ed6171fb61bdcbded417a11c8a5b0f..97a7860b66be418399912307f8e68db9b4edf121 100644 +index 422b364764e0df16ca250b4939d7b226e69c0840..2df28ffc731bd77e0d7af3541cfd3741aa5af83b 100644 --- a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java +++ b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java -@@ -17,7 +17,7 @@ import java.util.stream.Collectors; +@@ -15,7 +15,7 @@ import java.util.stream.Collectors; import javax.annotation.Nullable; import net.minecraft.world.level.block.state.properties.Property; @@ -11785,13 +11768,13 @@ index daedcfd867ed6171fb61bdcbded417a11c8a5b0f..97a7860b66be418399912307f8e68db9 public static final String NAME_TAG = "Name"; public static final String PROPERTIES_TAG = "Properties"; public static final Function, Comparable>, String> PROPERTY_ENTRY_TO_STRING_FUNCTION = new Function, Comparable>, String>() { -@@ -36,14 +36,28 @@ public abstract class StateHolder { +@@ -34,14 +34,28 @@ public abstract class StateHolder { } }; protected final O owner; - private final Reference2ObjectArrayMap, Comparable> values; -+ private Reference2ObjectArrayMap, Comparable> values; // Paper - optimise blockstate property access - remove final - private Table, Comparable, S> neighbours; ++ private Reference2ObjectArrayMap, Comparable> values; // Paper - optimise blockstate property access - remove final + private Map, S[]> neighbours; protected final MapCodec propertiesCodec; + // Paper start - optimise blockstate property access @@ -11815,7 +11798,7 @@ index daedcfd867ed6171fb61bdcbded417a11c8a5b0f..97a7860b66be418399912307f8e68db9 } public > S cycle(Property property) { -@@ -80,20 +94,21 @@ public abstract class StateHolder { +@@ -67,20 +81,21 @@ public abstract class StateHolder { } public Collection> getProperties() { @@ -11844,22 +11827,21 @@ index daedcfd867ed6171fb61bdcbded417a11c8a5b0f..97a7860b66be418399912307f8e68db9 } public > Optional getOptionalValue(Property property) { -@@ -102,36 +117,52 @@ public abstract class StateHolder { +@@ -93,22 +108,30 @@ public abstract class StateHolder { + + @Nullable + public > T getNullableValue(Property property) { +- Comparable comparable = this.values.get(property); +- return comparable == null ? null : property.getValueClass().cast(comparable); ++ return property == null ? null : this.optimisedTable.get(this.tableIndex, property); // Paper - optimise blockstate property access } public , V extends T> S setValue(Property property, V value) { - Comparable comparable = this.values.get(property); - if (comparable == null) { - throw new IllegalArgumentException("Cannot set property " + property + " as it does not exist in " + this.owner); -- } else if (comparable.equals(value)) { -- return (S)this; - } else { -- S object = this.neighbours.get(property, value); -- if (object == null) { -- throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value"); -- } else { -- return object; -- } +- return this.setValueInternal(property, value, comparable); + // Paper start - optimise blockstate property access + final S ret = this.optimisedTable.set(this.tableIndex, property, value); + if (ret != null) { @@ -11871,19 +11853,11 @@ index daedcfd867ed6171fb61bdcbded417a11c8a5b0f..97a7860b66be418399912307f8e68db9 public , V extends T> S trySetValue(Property property, V value) { - Comparable comparable = this.values.get(property); -- if (comparable != null && !comparable.equals(value)) { -- S object = this.neighbours.get(property, value); -- if (object == null) { -- throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value"); -- } else { -- return object; -- } -- } else { -- return (S)this; +- return (S)(comparable == null ? this : this.setValueInternal(property, value, comparable)); + // Paper start - optimise blockstate property access + if (property == null) { + return (S)(StateHolder)(Object)this; - } ++ } + final S ret = this.optimisedTable.trySet(this.tableIndex, property, value, (S)(StateHolder)(Object)this); + if (ret != null) { + return ret; @@ -11892,34 +11866,45 @@ index daedcfd867ed6171fb61bdcbded417a11c8a5b0f..97a7860b66be418399912307f8e68db9 + // Paper end - optimise blockstate property access } + private , V extends T> S setValueInternal(Property property, V newValue, Comparable oldValue) { +@@ -125,18 +148,27 @@ public abstract class StateHolder { + } + public void populateNeighbours(Map, Comparable>, S> states) { +- if (this.neighbours != null) { +- throw new IllegalStateException(); +- } else { +- Map, S[]> map = new Reference2ObjectArrayMap<>(this.values.size()); + // Paper start - optimise blockstate property access + final Map, Comparable>, S> map = states; -+ if (true) { -+ if (this.optimisedTable.isLoaded()) { -+ return; -+ } -+ this.optimisedTable.loadInTable(map); -+ -+ // de-duplicate the tables -+ for (final Map.Entry, Comparable>, S> entry : map.entrySet()) { -+ final S value = entry.getValue(); -+ ((StateHolder)value).optimisedTable = this.optimisedTable; -+ } -+ -+ // remove values arrays -+ for (final Map.Entry, Comparable>, S> entry : map.entrySet()) { -+ final S value = entry.getValue(); -+ ((StateHolder)value).values = null; -+ } -+ ++ if (this.optimisedTable.isLoaded()) { + return; + } -+ // Paper end - optimise blockstate property access - if (this.neighbours != null) { - throw new IllegalStateException(); - } else { -@@ -158,7 +189,11 @@ public abstract class StateHolder { ++ this.optimisedTable.loadInTable(map); + +- for (Entry, Comparable> entry : this.values.entrySet()) { +- Property property = entry.getKey(); +- map.put(property, property.getPossibleValues().stream().map(value -> states.get(this.makeNeighbourValues(property, value))).toArray()); +- } ++ // de-duplicate the tables ++ for (final Map.Entry, Comparable>, S> entry : map.entrySet()) { ++ final S value = entry.getValue(); ++ ((StateHolder)value).optimisedTable = this.optimisedTable; ++ } + +- this.neighbours = map; ++ // remove values arrays ++ for (final Map.Entry, Comparable>, S> entry : map.entrySet()) { ++ final S value = entry.getValue(); ++ ((StateHolder)value).values = null; + } ++ ++ return; ++ // Paper end optimise blockstate property access + } + + private Map, Comparable> makeNeighbourValues(Property property, Comparable value) { +@@ -146,7 +178,11 @@ public abstract class StateHolder { } public Map, Comparable> getValues() { @@ -11933,16 +11918,18 @@ index daedcfd867ed6171fb61bdcbded417a11c8a5b0f..97a7860b66be418399912307f8e68db9 protected static > Codec codec(Codec codec, Function ownerToStateFunction) { diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java -index b63116b333b6e06494091a82588acfb639bddb71..054a2569b5b103835facef1e34867c60884e5c29 100644 +index ea76aa490358e9e1d13350ba0ea246ec2c423894..98058505d36baf74008da08339afc196713b14a7 100644 --- a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java +++ b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java -@@ -4,11 +4,21 @@ import com.google.common.collect.ImmutableSet; - import java.util.Collection; +@@ -3,13 +3,23 @@ package net.minecraft.world.level.block.state.properties; + import java.util.List; import java.util.Optional; --public class BooleanProperty extends Property { -+public class BooleanProperty extends Property implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access - private final ImmutableSet values = ImmutableSet.of(true, false); +-public final class BooleanProperty extends Property { ++public final class BooleanProperty extends Property implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access + private static final List VALUES = List.of(true, false); + private static final int TRUE_INDEX = 0; + private static final int FALSE_INDEX = 1; + // Paper start - optimise blockstate property access + private static final Boolean[] BY_ID = new Boolean[]{ Boolean.FALSE, Boolean.TRUE }; @@ -11953,24 +11940,25 @@ index b63116b333b6e06494091a82588acfb639bddb71..054a2569b5b103835facef1e34867c60 + } + // Paper end - optimise blockstate property access + - protected BooleanProperty(String name) { + private BooleanProperty(String name) { super(name, Boolean.class); + this.moonrise$setById(BY_ID); // Paper - optimise blockstate property access } @Override diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java -index 3097298fe356df98967cf4bdeaaede69dfe8a441..c23cb4ac167799e61ab9a4e1f43a5722d596332e 100644 +index 85a197232be9377c0313ec00e8f935551e2c60e0..30b2fce9e47ffcc3de1542b1d0f073f5640127a7 100644 --- a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java +++ b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java -@@ -11,10 +11,38 @@ import java.util.function.Predicate; +@@ -10,11 +10,39 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import net.minecraft.util.StringRepresentable; --public class EnumProperty & StringRepresentable> extends Property { -+public class EnumProperty & StringRepresentable> extends Property implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access - private final ImmutableSet values; - private final Map names = Maps.newHashMap(); +-public final class EnumProperty & StringRepresentable> extends Property { ++public final class EnumProperty & StringRepresentable> extends Property implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access + private final List values; + private final Map names; + private final int[] ordinalToIndex; + // Paper start - optimise blockstate property access + private int[] idLookupTable; @@ -11982,7 +11970,7 @@ index 3097298fe356df98967cf4bdeaaede69dfe8a441..c23cb4ac167799e61ab9a4e1f43a5722 + } + + private void init() { -+ final Collection values = this.getPossibleValues(); ++ final java.util.Collection values = this.getPossibleValues(); + final Class clazz = this.getValueClass(); + + int id = 0; @@ -12000,28 +11988,28 @@ index 3097298fe356df98967cf4bdeaaede69dfe8a441..c23cb4ac167799e61ab9a4e1f43a5722 + } + // Paper end - optimise blockstate property access + - protected EnumProperty(String name, Class type, Collection values) { + private EnumProperty(String name, Class type, List values) { super(name, type); - this.values = ImmutableSet.copyOf(values); -@@ -27,6 +55,7 @@ public class EnumProperty & StringRepresentable> extends Prope + if (values.isEmpty()) { +@@ -37,6 +65,7 @@ public final class EnumProperty & StringRepresentable> extends - this.names.put(string, enum_); + this.names = builder.buildOrThrow(); } + this.init(); // Paper - optimise blockstate property access } @Override diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java -index 3a850321a4bcc68058483b5fd53e829c425a68af..4a21ec538d7410159bb26b9bf3701605b5ef317f 100644 +index 55a87592a99105dbf57b26fb6ccba695295fce24..986365acc9983331a7982ea2e1eac2b0efe1506d 100644 --- a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java +++ b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java -@@ -6,11 +6,33 @@ import java.util.Collection; +@@ -5,11 +5,33 @@ import java.util.List; import java.util.Optional; - import java.util.Set; + import java.util.stream.IntStream; --public class IntegerProperty extends Property { -+public class IntegerProperty extends Property implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access - private final ImmutableSet values; +-public final class IntegerProperty extends Property { ++public final class IntegerProperty extends Property implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access + private final IntImmutableList values; public final int min; public final int max; @@ -12047,19 +12035,19 @@ index 3a850321a4bcc68058483b5fd53e829c425a68af..4a21ec538d7410159bb26b9bf3701605 + } + // Paper end - optimise blockstate property access + - protected IntegerProperty(String name, int min, int max) { + private IntegerProperty(String name, int min, int max) { super(name, Integer.class); if (min < 0) { -@@ -28,6 +50,7 @@ public class IntegerProperty extends Property { - - this.values = ImmutableSet.copyOf(set); +@@ -21,6 +43,7 @@ public final class IntegerProperty extends Property { + this.max = max; + this.values = IntImmutableList.toList(IntStream.range(min, max + 1)); } + this.init(); // Paper - optimise blockstate property access } @Override diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java -index 9055f15af0cae55effa6942913a9d7edf3857e07..e63a7541f43e5c8f92f348c4e49756b33698c668 100644 +index fcf04c5c58ff35d38c5bf0df562ae2f8dc98a0ee..0b116160924300a9d62ad5948bfaf276f0386e4d 100644 --- a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java +++ b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java @@ -10,7 +10,7 @@ import java.util.stream.Stream; @@ -12111,7 +12099,7 @@ index 9055f15af0cae55effa6942913a9d7edf3857e07..e63a7541f43e5c8f92f348c4e49756b3 public Property.Value value(T value) { diff --git a/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java b/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java -index c5e1040c239874dcf20b79472bf690ee7f0a9e5f..0f403e0c257b1304be2ede89b8529676dbe8c32b 100644 +index 98dbeaf8bde15940e5b5d5d1f13fd4bb32f0a10d..7beea075b5a7ef738a4ac0558b99f4c5708f2c4a 100644 --- a/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java +++ b/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java @@ -8,12 +8,19 @@ import net.minecraft.network.FriendlyByteBuf; @@ -12136,10 +12124,10 @@ index c5e1040c239874dcf20b79472bf690ee7f0a9e5f..0f403e0c257b1304be2ede89b8529676 this(idList, bits, listener); entries.forEach(this.values::add); 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 7c11853c5090fbc4fa5b3e73a69acf166158fdec..170df85f42410f4766b04e73fc3a95e6dc4a3b8a 100644 +index a61294befc2f855fcecb2336a2d5444ce60e0a3a..a0e51681731dc7b487d5b14ae0d44a881bd5cb09 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -53,7 +53,7 @@ import net.minecraft.world.ticks.LevelChunkTicks; +@@ -54,7 +54,7 @@ import net.minecraft.world.ticks.LevelChunkTicks; import net.minecraft.world.ticks.TickContainerAccess; import org.slf4j.Logger; @@ -12148,12 +12136,30 @@ index 7c11853c5090fbc4fa5b3e73a69acf166158fdec..170df85f42410f4766b04e73fc3a95e6 static final Logger LOGGER = LogUtils.getLogger(); private static final TickingBlockEntity NULL_TICKER = new TickingBlockEntity() { +@@ -688,7 +688,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p + */ + org.bukkit.Chunk bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); + server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(bukkitChunk, this.needsDecoration)); +- ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk().callEntitiesLoadEvent(); // Paper - rewrite chunk system ++ org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesLoadEvent(this.level, this.chunkPos, ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk().getAllEntities()); // Paper - rewrite chunk system + + if (this.needsDecoration) { + try (co.aikar.timings.Timing ignored = this.level.timings.chunkLoadPopulate.startTiming()) { // Paper +@@ -719,7 +719,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p + public void unloadCallback() { + if (!this.loadedTicketLevel) { LOGGER.error("Double calling chunk unload!", new Throwable()); } // Paper + org.bukkit.Server server = this.level.getCraftServer(); +- ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk().callEntitiesUnloadEvent(); // Paper - rewrite chunk system ++ org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesUnloadEvent(this.level, this.chunkPos, ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk().getAllEntities()); // Paper - rewrite chunk system + org.bukkit.Chunk bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); + org.bukkit.event.world.ChunkUnloadEvent unloadEvent = new org.bukkit.event.world.ChunkUnloadEvent(bukkitChunk, true); // Paper - rewrite chunk system - force save to true so that mustNotSave is correctly set below + server.getPluginManager().callEvent(unloadEvent); diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -index c3b1caa352b988ec44fa2b2eb0536517711f5460..df1b3f3ae48f66137484e0eb3f4c7323269e1a74 100644 +index 161211124f3f8390530af7ab21f3a0f1025209c5..4167ed830382c6a76bb281e9d753919925c6bd00 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -@@ -27,15 +27,17 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ - private PalettedContainer> biomes; +@@ -26,15 +26,17 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ + private PalettedContainer> biomes; // CraftBukkit - read/write // Paper start - block counting - private static final it.unimi.dsi.fastutil.ints.IntArrayList FULL_LIST = new it.unimi.dsi.fastutil.ints.IntArrayList(16*16*16); @@ -12174,7 +12180,7 @@ index c3b1caa352b988ec44fa2b2eb0536517711f5460..df1b3f3ae48f66137484e0eb3f4c7323 @Override public final int moonrise$getSpecialCollidingBlocks() { -@@ -43,7 +45,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ +@@ -42,7 +44,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ } @Override @@ -12183,7 +12189,7 @@ index c3b1caa352b988ec44fa2b2eb0536517711f5460..df1b3f3ae48f66137484e0eb3f4c7323 return this.tickingBlocks; } // Paper end - block counting -@@ -83,6 +85,45 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ +@@ -86,6 +88,45 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ return this.setBlockState(x, y, z, state, true); } @@ -12229,7 +12235,7 @@ index c3b1caa352b988ec44fa2b2eb0536517711f5460..df1b3f3ae48f66137484e0eb3f4c7323 public BlockState setBlockState(int x, int y, int z, BlockState state, boolean lock) { BlockState iblockdata1; -@@ -102,7 +143,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ +@@ -105,7 +146,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ } } @@ -12238,7 +12244,7 @@ index c3b1caa352b988ec44fa2b2eb0536517711f5460..df1b3f3ae48f66137484e0eb3f4c7323 --this.tickingFluidCount; } -@@ -113,25 +154,11 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ +@@ -116,25 +157,11 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ } } @@ -12266,7 +12272,7 @@ index c3b1caa352b988ec44fa2b2eb0536517711f5460..df1b3f3ae48f66137484e0eb3f4c7323 return iblockdata1; } -@@ -167,7 +194,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ +@@ -170,7 +197,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ final int paletteSize = palette.getSize(); final net.minecraft.util.BitStorage storage = data.storage(); @@ -12275,7 +12281,7 @@ index c3b1caa352b988ec44fa2b2eb0536517711f5460..df1b3f3ae48f66137484e0eb3f4c7323 if (paletteSize == 1) { counts = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1); counts.put(0, FULL_LIST); -@@ -175,10 +202,10 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ +@@ -178,10 +205,10 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ counts = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingBitStorage)storage).moonrise$countEntries(); } @@ -12289,7 +12295,7 @@ index c3b1caa352b988ec44fa2b2eb0536517711f5460..df1b3f3ae48f66137484e0eb3f4c7323 final int paletteCount = coordinates.size(); final BlockState state = palette.valueFor(paletteIdx); -@@ -188,25 +215,30 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ +@@ -191,25 +218,30 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ } if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(state)) { @@ -12327,7 +12333,7 @@ index c3b1caa352b988ec44fa2b2eb0536517711f5460..df1b3f3ae48f66137484e0eb3f4c7323 } } } -@@ -229,7 +261,11 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ +@@ -232,7 +264,11 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ datapaletteblock.read(buf); this.biomes = datapaletteblock; @@ -12341,7 +12347,7 @@ index c3b1caa352b988ec44fa2b2eb0536517711f5460..df1b3f3ae48f66137484e0eb3f4c7323 public void readBiomes(FriendlyByteBuf buf) { diff --git a/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java b/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java -index f4c3f2a49b8d023b8ef67529eba30cf31467d8bf..716eb6f406db4b81b8854de0ea693a72f9ca9d13 100644 +index bc4d9452bbeb05a691fd285603e49491f41d3ad2..f8d9892970c9092f7cc84434d4fbf34354ce1195 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java +++ b/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java @@ -7,13 +7,20 @@ import net.minecraft.network.FriendlyByteBuf; @@ -12367,7 +12373,7 @@ index f4c3f2a49b8d023b8ef67529eba30cf31467d8bf..716eb6f406db4b81b8854de0ea693a72 this.registry = idList; this.values = (T[])(new Object[1 << bits]); diff --git a/src/main/java/net/minecraft/world/level/chunk/Palette.java b/src/main/java/net/minecraft/world/level/chunk/Palette.java -index e379f39cc6e03723a5323d8392b4c10bfde65115..882284fe7beeb56a8b35ac6153ff41e84ebad27e 100644 +index b8922e4a13df535cdc5701e893a6e460b33ff90d..100807f8b8337f56f49cdb818ccc75be2f08ecd1 100644 --- a/src/main/java/net/minecraft/world/level/chunk/Palette.java +++ b/src/main/java/net/minecraft/world/level/chunk/Palette.java @@ -5,7 +5,7 @@ import java.util.function.Predicate; @@ -12380,11 +12386,11 @@ index e379f39cc6e03723a5323d8392b4c10bfde65115..882284fe7beeb56a8b35ac6153ff41e8 boolean maybeHas(Predicate predicate); diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -index 13d3c877b006a4975e7370713e3919c661e7890f..955862559b8c751b82082a5c0e02031324bf4805 100644 +index b46c58c952e183bd74854c3eb70d64979af70f18..533167eaa8bd39006fb1c7e193c81359973da9af 100644 --- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -@@ -41,6 +41,33 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - // this.threadingDetector.checkAndUnlock(); // Paper - disable this +@@ -71,6 +71,33 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + ); } + // Paper start - optimise palette reads @@ -12414,26 +12420,25 @@ index 13d3c877b006a4975e7370713e3919c661e7890f..955862559b8c751b82082a5c0e020313 + } + // Paper end - optimise palette reads + - // Paper start - Anti-Xray - Add preset values - @Deprecated @io.papermc.paper.annotation.DoNotUse public static Codec> codecRW(IdMap idList, Codec entryCodec, PalettedContainer.Strategy paletteProvider, T defaultValue) { return PalettedContainer.codecRW(idList, entryCodec, paletteProvider, defaultValue, null); } - public static Codec> codecRW(IdMap idList, Codec entryCodec, PalettedContainer.Strategy paletteProvider, T defaultValue, T @org.jetbrains.annotations.Nullable [] presetValues) { -@@ -113,6 +140,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - } - } - // Paper end + public PalettedContainer( + IdMap idList, + PalettedContainer.Strategy paletteProvider, +@@ -81,12 +108,14 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + this.registry = idList; + this.strategy = paletteProvider; + this.data = new PalettedContainer.Data<>(dataProvider, storage, dataProvider.factory().create(dataProvider.bits(), idList, this, paletteEntries)); + this.updateData(this.data); // Paper - optimise palette reads } - // Paper start - Anti-Xray - Add preset values -@@ -122,6 +150,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + private PalettedContainer(IdMap idList, PalettedContainer.Strategy paletteProvider, PalettedContainer.Data data) { this.registry = idList; this.strategy = paletteProvider; this.data = data; + this.updateData(this.data); // Paper - optimise palette reads } - // Paper start - Anti-Xray - Add preset values -@@ -133,6 +162,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + private PalettedContainer(PalettedContainer container) { +@@ -100,6 +129,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer this.registry = idList; this.data = this.createOrReuseData(null, 0); this.data.palette.idFor(object); @@ -12441,15 +12446,15 @@ index 13d3c877b006a4975e7370713e3919c661e7890f..955862559b8c751b82082a5c0e020313 } private PalettedContainer.Data createOrReuseData(@Nullable PalettedContainer.Data previousData, int bits) { -@@ -158,6 +188,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -115,6 +145,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer PalettedContainer.Data data2 = this.createOrReuseData(data, newBits); data2.copyFrom(data.palette, data.storage); this.data = data2; + this.updateData(this.data); // Paper - optimise palette reads - this.addPresetValues(); - return object == null ? -1 : data2.palette.idFor(object); - // Paper end -@@ -191,9 +222,12 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + return data2.palette.idFor(object); + } + +@@ -136,9 +167,12 @@ public class PalettedContainer implements PaletteResize, PalettedContainer } private synchronized T getAndSet(int index, T value) { // Paper - synchronize @@ -12465,7 +12470,7 @@ index 13d3c877b006a4975e7370713e3919c661e7890f..955862559b8c751b82082a5c0e020313 } public void set(int x, int y, int z, T value) { -@@ -217,8 +251,10 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -162,8 +196,10 @@ public class PalettedContainer implements PaletteResize, PalettedContainer } public T get(int index) { // Paper - public @@ -12478,15 +12483,15 @@ index 13d3c877b006a4975e7370713e3919c661e7890f..955862559b8c751b82082a5c0e020313 } @Override -@@ -238,6 +274,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -183,6 +219,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer data.palette.read(buf); buf.readLongArray(data.storage.getRaw()); this.data = data; + this.updateData(this.data); // Paper - optimise palette reads - this.addPresetValues(); // Paper - Anti-Xray - Add preset values (inefficient, but this isn't used by the server) } finally { this.release(); -@@ -386,7 +423,44 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + } +@@ -323,7 +360,44 @@ public class PalettedContainer implements PaletteResize, PalettedContainer void accept(T object, int count); } @@ -12533,7 +12538,7 @@ index 13d3c877b006a4975e7370713e3919c661e7890f..955862559b8c751b82082a5c0e020313 for (int i = 0; i < storage.getSize(); i++) { T object = palette.valueFor(storage.get(i)); diff --git a/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java b/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java -index 24b608cfcd6f39db02e682e5d8162dc4ad9fd6d6..3a06392a327f26d78c28fdcce39f74b130c4d906 100644 +index a45e6410600afc5464e5d29932c193786ce0a6fb..a1ba68c95c2cdebdc0d7782cce7895529918073c 100644 --- a/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java +++ b/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java @@ -8,12 +8,24 @@ import net.minecraft.network.FriendlyByteBuf; @@ -12587,10 +12592,10 @@ index 24b608cfcd6f39db02e682e5d8162dc4ad9fd6d6..3a06392a327f26d78c28fdcce39f74b1 @Override 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 1e0439cf3f4008fa430acb90b45f5bc4cdd6d7f2..e46bdcbf3514eaa6f4990a797a63c5041a142807 100644 +index f1237f6fd6414900ffbad0caee31aa83310eeef4..8071ce70d66909bb4bda45792bf329a939d6f918 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 -@@ -28,7 +28,7 @@ import net.minecraft.nbt.NbtIo; // Paper +@@ -25,7 +25,7 @@ import net.minecraft.util.profiling.jfr.JvmProfiler; import net.minecraft.world.level.ChunkPos; import org.slf4j.Logger; @@ -12599,13 +12604,13 @@ index 1e0439cf3f4008fa430acb90b45f5bc4cdd6d7f2..e46bdcbf3514eaa6f4990a797a63c504 private static final Logger LOGGER = LogUtils.getLogger(); private static final int SECTOR_BYTES = 4096; -@@ -51,6 +51,20 @@ public class RegionFile implements AutoCloseable { - private final IntBuffer timestamps; +@@ -49,6 +49,21 @@ public class RegionFile implements AutoCloseable { @VisibleForTesting protected final RegionBitmap usedSectors; + + // Paper start - rewrite chunk system + @Override -+ public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite(final CompoundTag data, final ChunkPos pos) throws IOException { ++ public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite(final net.minecraft.nbt.CompoundTag data, final ChunkPos pos) throws IOException { + final RegionFile.ChunkBuffer buffer = ((RegionFile)(Object)this).new ChunkBuffer(pos); + ((ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkBuffer)buffer).moonrise$setWriteOnClose(false); + @@ -12617,10 +12622,11 @@ index 1e0439cf3f4008fa430acb90b45f5bc4cdd6d7f2..e46bdcbf3514eaa6f4990a797a63c504 + ); + } + // Paper end - rewrite chunk system - // Paper start - Attempt to recalculate regionfile header if it is corrupt - private static long roundToSectors(long bytes) { - long sectors = bytes >>> 12; // 4096 = 2^12 -@@ -682,6 +696,16 @@ public class RegionFile implements AutoCloseable { ++ + public RegionFile(RegionStorageInfo storageKey, Path directory, Path path, boolean dsync) throws IOException { + this(storageKey, directory, path, RegionFileVersion.getSelected(), dsync); + } +@@ -220,6 +235,16 @@ public class RegionFile implements AutoCloseable { @Nullable private DataInputStream createExternalChunkInputStream(ChunkPos pos, byte flags) throws IOException { @@ -12637,10 +12643,10 @@ index 1e0439cf3f4008fa430acb90b45f5bc4cdd6d7f2..e46bdcbf3514eaa6f4990a797a63c504 Path path = this.getExternalChunkPath(pos); if (!Files.isRegularFile(path, new LinkOption[0])) { -@@ -978,10 +1002,29 @@ public class RegionFile implements AutoCloseable { - +@@ -443,10 +468,29 @@ public class RegionFile implements AutoCloseable { } - // Paper end + + public static final int MAX_CHUNK_SIZE = 500 * 1024 * 1024; // Paper - don't write garbage data to disk if writing serialization fails - private class ChunkBuffer extends ByteArrayOutputStream { + private class ChunkBuffer extends ByteArrayOutputStream implements ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkBuffer { // Paper - rewrite chunk system @@ -12668,7 +12674,7 @@ index 1e0439cf3f4008fa430acb90b45f5bc4cdd6d7f2..e46bdcbf3514eaa6f4990a797a63c504 public ChunkBuffer(final ChunkPos chunkcoordintpair) { super(8096); super.write(0); -@@ -1015,7 +1058,7 @@ public class RegionFile implements AutoCloseable { +@@ -480,7 +524,7 @@ public class RegionFile implements AutoCloseable { JvmProfiler.INSTANCE.onRegionFileWrite(RegionFile.this.info, this.pos, RegionFile.this.version, i); bytebuffer.putInt(0, i); @@ -12678,7 +12684,7 @@ index 1e0439cf3f4008fa430acb90b45f5bc4cdd6d7f2..e46bdcbf3514eaa6f4990a797a63c504 } 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 40689256711cc94a806ca1da346f4f62eda31526..b0ace4c7f25425a58c0707e7a7992446164bef88 100644 +index 18054304e08c8a6346c0135a0e6a68e77fe5c37c..9dbc9e2f9d5aab71720bb81803efe76e2f361f04 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 @@ -28,8 +28,8 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise @@ -12788,10 +12794,10 @@ index 40689256711cc94a806ca1da346f4f62eda31526..b0ace4c7f25425a58c0707e7a7992446 + } + } // Paper end - rewrite chunk system - // Paper start - recalculate region file headers - private final boolean isChunkData; -@@ -143,6 +234,12 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise - this.isChunkData = isChunkDataFolder(this.folder); // Paper - recalculate region file headers + + protected RegionFileStorage(RegionStorageInfo storageKey, Path directory, boolean dsync) { // Paper - protected +@@ -112,6 +203,12 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise + this.info = storageKey; } + // Paper start - rewrite chunk system @@ -12804,7 +12810,7 @@ index 40689256711cc94a806ca1da346f4f62eda31526..b0ace4c7f25425a58c0707e7a7992446 // Paper start - rewrite chunk system if (existingOnly) { diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -index 1c0712295695727ee9c4d430d4157b8e17cbd71f..7b8e5be1648ef8741aadabd6cbdcf991012c3ce2 100644 +index 261e5994d13f8bc30490b86691c80c0a21e7640a..f4fbcbb8ff6d2677af1a02a0801a323c06dce9b1 100644 --- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java @@ -55,6 +55,48 @@ public abstract class FlowingFluid extends Fluid { @@ -12856,12 +12862,12 @@ index 1c0712295695727ee9c4d430d4157b8e17cbd71f..7b8e5be1648ef8741aadabd6cbdcf991 public FlowingFluid() {} @Override -@@ -239,53 +281,70 @@ public abstract class FlowingFluid extends Fluid { +@@ -246,65 +288,70 @@ public abstract class FlowingFluid extends Fluid { } } -- private boolean canPassThroughWall(Direction face, BlockGetter world, BlockPos pos, BlockState state, BlockPos fromPos, BlockState fromState) { -- Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap; +- private static boolean canPassThroughWall(Direction face, BlockGetter world, BlockPos pos, BlockState state, BlockPos fromPos, BlockState fromState) { +- VoxelShape voxelshape = fromState.getCollisionShape(world, fromPos); + // Paper start - fluid method optimisations + private static boolean canPassThroughWall(final Direction direction, final BlockGetter level, + final BlockPos fromPos, final BlockState fromState, @@ -12871,56 +12877,71 @@ index 1c0712295695727ee9c4d430d4157b8e17cbd71f..7b8e5be1648ef8741aadabd6cbdcf991 + return true; + } -- if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) { -- object2bytelinkedopenhashmap = (Object2ByteLinkedOpenHashMap) FlowingFluid.OCCLUSION_CACHE.get(); -- } else { -- object2bytelinkedopenhashmap = null; +- if (voxelshape == Shapes.block()) { + if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$occludesFullBlock() | ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$occludesFullBlock()) { + // don't even try to cache simple cases -+ return false; - } + return false; +- } else { +- VoxelShape voxelshape1 = state.getCollisionShape(world, pos); +- +- if (voxelshape1 == Shapes.block()) { +- return false; +- } else if (voxelshape1 == Shapes.empty() && voxelshape == Shapes.empty()) { +- return true; +- } else { +- Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap; +- +- if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) { +- object2bytelinkedopenhashmap = (Object2ByteLinkedOpenHashMap) FlowingFluid.OCCLUSION_CACHE.get(); +- } else { +- object2bytelinkedopenhashmap = null; +- } ++ } -- Block.BlockStatePairKey block_a; +- FlowingFluid.BlockStatePairKey fluidtypeflowing_a; + final ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey[] cache = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$hasCache() & ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$hasCache() ? + COLLISION_OCCLUSION_CACHE.get() : null; -- if (object2bytelinkedopenhashmap != null) { -- block_a = new Block.BlockStatePairKey(state, fromState, face); -- byte b0 = object2bytelinkedopenhashmap.getAndMoveToFirst(block_a); +- if (object2bytelinkedopenhashmap != null) { +- fluidtypeflowing_a = new FlowingFluid.BlockStatePairKey(state, fromState, face); +- byte b0 = object2bytelinkedopenhashmap.getAndMoveToFirst(fluidtypeflowing_a); + final int keyIndex + = (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$uniqueId1() ^ ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$uniqueId2() ^ ((ca.spottedleaf.moonrise.patches.collisions.util.CollisionDirection)(Object)direction).moonrise$uniqueId()) + & (COLLISION_OCCLUSION_CACHE_SIZE - 1); -- if (b0 != 127) { -- return b0 != 0; +- if (b0 != 127) { +- return b0 != 0; +- } +- } else { +- fluidtypeflowing_a = null; +- } +- +- boolean flag = !Shapes.mergedFaceOccludes(voxelshape1, voxelshape, face); + if (cache != null) { + final ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey cached = cache[keyIndex]; + if (cached != null && cached.first() == fromState && cached.second() == toState && cached.direction() == direction) { + return cached.result(); - } -- } else { -- block_a = null; - } ++ } ++ } -- VoxelShape voxelshape = state.getCollisionShape(world, pos); -- VoxelShape voxelshape1 = fromState.getCollisionShape(world, fromPos); -- boolean flag = !Shapes.mergedFaceOccludes(voxelshape, voxelshape1, face); +- if (object2bytelinkedopenhashmap != null) { +- if (object2bytelinkedopenhashmap.size() == 200) { +- object2bytelinkedopenhashmap.removeLastByte(); +- } + final VoxelShape shape1 = fromState.getCollisionShape(level, fromPos); + final VoxelShape shape2 = toState.getCollisionShape(level, toPos); -- if (object2bytelinkedopenhashmap != null) { -- if (object2bytelinkedopenhashmap.size() == 200) { -- object2bytelinkedopenhashmap.removeLastByte(); -- } +- object2bytelinkedopenhashmap.putAndMoveToFirst(fluidtypeflowing_a, (byte) (flag ? 1 : 0)); +- } + final boolean result = !Shapes.mergedFaceOccludes(shape1, shape2, direction); -- object2bytelinkedopenhashmap.putAndMoveToFirst(block_a, (byte) (flag ? 1 : 0)); +- return flag; +- } + if (cache != null) { + // we can afford to replace in-use keys more often due to the excessive caching the collision patch does in mergedFaceOccludes + cache[keyIndex] = new ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey(fromState, toState, direction, result); } - -- return flag; ++ + return result; } + // Paper end - fluid method optimisations @@ -12951,12 +12972,12 @@ index 1c0712295695727ee9c4d430d4157b8e17cbd71f..7b8e5be1648ef8741aadabd6cbdcf991 + // Paper end - fluid method optimisations } - protected abstract boolean canConvertToSource(Level world); + protected abstract boolean canConvertToSource(ServerLevel world); diff --git a/src/main/java/net/minecraft/world/level/material/FluidState.java b/src/main/java/net/minecraft/world/level/material/FluidState.java -index 14bb12d2a0066e8b020f2e0e670a7a5c74633623..8ceeb053a391d1a53083eb0680cf34c453afcba2 100644 +index 87adfe152abd1b8b4d547034576883c5d1cdf134..2d50d72bf026d0cf9c546a3c6fc1859379bfd805 100644 --- a/src/main/java/net/minecraft/world/level/material/FluidState.java +++ b/src/main/java/net/minecraft/world/level/material/FluidState.java -@@ -21,12 +21,30 @@ import net.minecraft.world.level.block.state.properties.Property; +@@ -22,12 +22,30 @@ import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.VoxelShape; @@ -12988,7 +13009,7 @@ index 14bb12d2a0066e8b020f2e0e670a7a5c74633623..8ceeb053a391d1a53083eb0680cf34c4 public FluidState(Fluid fluid, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { super(fluid, propertyMap, codec); this.isEmpty = fluid.isEmpty(); // Paper - Perf: moved from isEmpty() -@@ -37,11 +55,11 @@ public final class FluidState extends StateHolder { +@@ -38,11 +56,11 @@ public final class FluidState extends StateHolder { } public boolean isSource() { @@ -13002,7 +13023,7 @@ index 14bb12d2a0066e8b020f2e0e670a7a5c74633623..8ceeb053a391d1a53083eb0680cf34c4 } public boolean isEmpty() { -@@ -53,11 +71,11 @@ public final class FluidState extends StateHolder { +@@ -54,11 +72,11 @@ public final class FluidState extends StateHolder { } public float getOwnHeight() { @@ -13016,7 +13037,7 @@ index 14bb12d2a0066e8b020f2e0e670a7a5c74633623..8ceeb053a391d1a53083eb0680cf34c4 } public boolean shouldRenderBackwardUpFace(BlockGetter world, BlockPos pos) { -@@ -83,7 +101,7 @@ public final class FluidState extends StateHolder { +@@ -84,7 +102,7 @@ public final class FluidState extends StateHolder { } public boolean isRandomlyTicking() { @@ -13024,8 +13045,8 @@ index 14bb12d2a0066e8b020f2e0e670a7a5c74633623..8ceeb053a391d1a53083eb0680cf34c4 + return this.isRandomlyTicking; // Paper - fluid method optimisations } - public void randomTick(Level world, BlockPos pos, RandomSource random) { -@@ -95,7 +113,12 @@ public final class FluidState extends StateHolder { + public void randomTick(ServerLevel world, BlockPos pos, RandomSource random) { +@@ -96,7 +114,12 @@ public final class FluidState extends StateHolder { } public BlockState createLegacyBlock() { @@ -13053,7 +13074,7 @@ index 1d36f8dcffd22cf844448d3d8351fb8718cf5227..fbe0c4b0fdbb992b7002f6afe1e74d63 final int minFullX = discreteVoxelShape.firstFull(Direction.Axis.X); final int minFullY = discreteVoxelShape.firstFull(Direction.Axis.Y); diff --git a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java -index c348171c150bf69d24303d0862e45ab78baddcab..4c8185fbc560a5c5304729e5827ae7762933ec36 100644 +index 672a2038c6d8b31090403766460c6149a75adf8b..513bed7f11aee667c87046db4cf912b80e8f3638 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java +++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java @@ -180,13 +180,13 @@ public final class Shapes { @@ -13072,32 +13093,8 @@ index c348171c150bf69d24303d0862e45ab78baddcab..4c8185fbc560a5c5304729e5827ae776 // Paper end - optimise collisions } -@@ -255,7 +255,22 @@ public final class Shapes { - } - - public static VoxelShape getFaceShape(VoxelShape shape, Direction direction) { -- return ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$getFaceShapeClamped(direction); // Paper - optimise collisions -+ if (shape == block()) { -+ return block(); -+ } else { -+ Direction.Axis axis = direction.getAxis(); -+ boolean bl; -+ int i; -+ if (direction.getAxisDirection() == Direction.AxisDirection.POSITIVE) { -+ bl = DoubleMath.fuzzyEquals(shape.max(axis), 1.0, 1.0E-7); -+ i = shape.shape.getSize(axis) - 1; -+ } else { -+ bl = DoubleMath.fuzzyEquals(shape.min(axis), 0.0, 1.0E-7); -+ i = 0; -+ } -+ -+ return (VoxelShape)(!bl ? empty() : new SliceShape(shape, axis, i)); -+ } - } - - // Paper start - optimise collisions diff --git a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java -index 11824d39e72fa003b3a56aa9b8d679fe8e23a1a4..c207e54dc52e67ba91dac5c6ce1391a77f597bcd 100644 +index d850a7de74150a04622da71d9614320f3d5d69e8..3f8e7e29c3e52211a29e6f0a32890f6b53bfd9a8 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java +++ b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java @@ -162,13 +162,13 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll @@ -13238,7 +13235,7 @@ index 11824d39e72fa003b3a56aa9b8d679fe8e23a1a4..c207e54dc52e67ba91dac5c6ce1391a7 } public abstract DoubleList getCoords(Direction.Axis axis); -@@ -547,9 +565,9 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll +@@ -551,9 +569,9 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll final ArrayVoxelShape ret = new ArrayVoxelShape( this.shape, @@ -13251,7 +13248,7 @@ index 11824d39e72fa003b3a56aa9b8d679fe8e23a1a4..c207e54dc52e67ba91dac5c6ce1391a7 ); final ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs cachedToAABBs = this.cachedToAABBs; -@@ -574,6 +592,11 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll +@@ -578,6 +596,11 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll final List aabbs = this.toAabbs(); @@ -13263,7 +13260,7 @@ index 11824d39e72fa003b3a56aa9b8d679fe8e23a1a4..c207e54dc52e67ba91dac5c6ce1391a7 if (aabbs.size() == 1) { final AABB singleAABB = aabbs.get(0); final VoxelShape ret = Shapes.create(singleAABB); -@@ -700,7 +723,32 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll +@@ -704,7 +727,32 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll } protected int findIndex(Direction.Axis axis, double coord) { @@ -13297,7 +13294,7 @@ index 11824d39e72fa003b3a56aa9b8d679fe8e23a1a4..c207e54dc52e67ba91dac5c6ce1391a7 } @Nullable -@@ -723,13 +771,13 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll +@@ -727,13 +775,13 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll final AABB singleAABB = this.singleAABBRepresentation; if (singleAABB != null) { if (singleAABB.contains(fromBehindOffsetX, fromBehindOffsetY, fromBehindOffsetZ)) { @@ -13313,20 +13310,23 @@ index 11824d39e72fa003b3a56aa9b8d679fe8e23a1a4..c207e54dc52e67ba91dac5c6ce1391a7 } return AABB.clip(((VoxelShape)(Object)this).toAabbs(), from, to, offset); -@@ -783,17 +831,23 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll +@@ -786,20 +834,24 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll + } } - private VoxelShape calculateFace(Direction direction) { -- Direction.Axis axis = direction.getAxis(); -- DoubleList doubleList = this.getCoords(axis); -- if (doubleList.size() == 2 -- && DoubleMath.fuzzyEquals(doubleList.getDouble(0), 0.0, 1.0E-7) -- && DoubleMath.fuzzyEquals(doubleList.getDouble(1), 1.0, 1.0E-7)) { +- private VoxelShape calculateFace(Direction facing) { +- Direction.Axis axis = facing.getAxis(); +- if (this.isCubeLikeAlong(axis)) { - return this; - } else { -- Direction.AxisDirection axisDirection = direction.getAxisDirection(); +- Direction.AxisDirection axisDirection = facing.getAxisDirection(); - int i = this.findIndex(axis, axisDirection == Direction.AxisDirection.POSITIVE ? 0.9999999 : 1.0E-7); -- return new SliceShape(this, axis, i); +- SliceShape sliceShape = new SliceShape(this, axis, i); +- if (sliceShape.isEmpty()) { +- return Shapes.empty(); +- } else { +- return (VoxelShape)(sliceShape.isCubeLike() ? Shapes.block() : sliceShape); ++ private VoxelShape calculateFace(Direction direction) { + // Paper start - optimise collisions + final Direction.Axis axis = direction.getAxis(); + switch (axis) { @@ -13341,9 +13341,9 @@ index 11824d39e72fa003b3a56aa9b8d679fe8e23a1a4..c207e54dc52e67ba91dac5c6ce1391a7 + } + default: { + throw new IllegalStateException("Unknown axis: " + axis); -+ } + } } + // Paper end - optimise collisions } - // Paper start - optimise collisions + protected boolean isCubeLike() { diff --git a/patches/server/1071-Revert-Custom-table-implementation-for-blockstate-st.patch b/patches/server/1071-Revert-Custom-table-implementation-for-blockstate-st.patch deleted file mode 100644 index fa362b310f73..000000000000 --- a/patches/server/1071-Revert-Custom-table-implementation-for-blockstate-st.patch +++ /dev/null @@ -1,345 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Mon, 21 Oct 2024 12:52:44 -0700 -Subject: [PATCH] Revert "Custom table implementation for blockstate state - lookups" - -This reverts commit 14a7e6521ba0ce6dc8ebf98a1ccce59a5ec6a194. - -TODO Replace via deleting the patch - -diff --git a/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java b/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java -deleted file mode 100644 -index 57d0cd3ad6f972e986c72a57f1a6e36003f190c2..0000000000000000000000000000000000000000 ---- a/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java -+++ /dev/null -@@ -1,160 +0,0 @@ --package io.papermc.paper.util.table; -- --import com.google.common.collect.Table; --import net.minecraft.world.level.block.state.StateHolder; --import net.minecraft.world.level.block.state.properties.Property; --import java.util.Collection; --import java.util.HashSet; --import java.util.Map; --import java.util.Set; -- --public final class ZeroCollidingReferenceStateTable { -- -- // upper 32 bits: starting index -- // lower 32 bits: bitset for contained ids -- protected final long[] this_index_table; -- protected final Comparable[] this_table; -- protected final StateHolder this_state; -- -- protected long[] index_table; -- protected StateHolder[][] value_table; -- -- public ZeroCollidingReferenceStateTable(final StateHolder state, final Map, Comparable> this_map) { -- this.this_state = state; -- this.this_index_table = this.create_table(this_map.keySet()); -- -- int max_id = -1; -- for (final Property property : this_map.keySet()) { -- final int id = lookup_vindex(property, this.this_index_table); -- if (id > max_id) { -- max_id = id; -- } -- } -- -- this.this_table = new Comparable[max_id + 1]; -- for (final Map.Entry, Comparable> entry : this_map.entrySet()) { -- this.this_table[lookup_vindex(entry.getKey(), this.this_index_table)] = entry.getValue(); -- } -- } -- -- public void loadInTable(final Table, Comparable, StateHolder> table, -- final Map, Comparable> this_map) { -- final Set> combined = new HashSet<>(table.rowKeySet()); -- combined.addAll(this_map.keySet()); -- -- this.index_table = this.create_table(combined); -- -- int max_id = -1; -- for (final Property property : combined) { -- final int id = lookup_vindex(property, this.index_table); -- if (id > max_id) { -- max_id = id; -- } -- } -- -- this.value_table = new StateHolder[max_id + 1][]; -- -- final Map, Map, StateHolder>> map = table.rowMap(); -- for (final Property property : map.keySet()) { -- final Map, StateHolder> propertyMap = map.get(property); -- -- final int id = lookup_vindex(property, this.index_table); -- final StateHolder[] states = this.value_table[id] = new StateHolder[property.getPossibleValues().size()]; -- -- for (final Map.Entry, StateHolder> entry : propertyMap.entrySet()) { -- if (entry.getValue() == null) { -- // TODO what -- continue; -- } -- -- states[((Property)property).getIdFor(entry.getKey())] = entry.getValue(); -- } -- } -- -- -- for (final Map.Entry, Comparable> entry : this_map.entrySet()) { -- final Property property = entry.getKey(); -- final int index = lookup_vindex(property, this.index_table); -- -- if (this.value_table[index] == null) { -- this.value_table[index] = new StateHolder[property.getPossibleValues().size()]; -- } -- -- this.value_table[index][((Property)property).getIdFor(entry.getValue())] = this.this_state; -- } -- } -- -- -- protected long[] create_table(final Collection> collection) { -- int max_id = -1; -- for (final Property property : collection) { -- final int id = property.getId(); -- if (id > max_id) { -- max_id = id; -- } -- } -- -- final long[] ret = new long[((max_id + 1) + 31) >>> 5]; // ceil((max_id + 1) / 32) -- -- for (final Property property : collection) { -- final int id = property.getId(); -- -- ret[id >>> 5] |= (1L << (id & 31)); -- } -- -- int total = 0; -- for (int i = 1, len = ret.length; i < len; ++i) { -- ret[i] |= (long)(total += Long.bitCount(ret[i - 1] & 0xFFFFFFFFL)) << 32; -- } -- -- return ret; -- } -- -- public Comparable get(final Property state) { -- final Comparable[] table = this.this_table; -- final int index = lookup_vindex(state, this.this_index_table); -- -- if (index < 0 || index >= table.length) { -- return null; -- } -- return table[index]; -- } -- -- public StateHolder get(final Property property, final Comparable with) { -- final int withId = ((Property)property).getIdFor(with); -- if (withId < 0) { -- return null; -- } -- -- final int index = lookup_vindex(property, this.index_table); -- final StateHolder[][] table = this.value_table; -- if (index < 0 || index >= table.length) { -- return null; -- } -- -- final StateHolder[] values = table[index]; -- -- if (withId >= values.length) { -- return null; -- } -- -- return values[withId]; -- } -- -- protected static int lookup_vindex(final Property property, final long[] index_table) { -- final int id = property.getId(); -- final long bitset_mask = (1L << (id & 31)); -- final long lower_mask = bitset_mask - 1; -- final int index = id >>> 5; -- if (index >= index_table.length) { -- return -1; -- } -- final long index_value = index_table[index]; -- final long contains_check = ((index_value & bitset_mask) - 1) >> (Long.SIZE - 1); // -1L if doesn't contain -- -- // index = total bits set in lower table values (upper 32 bits of index_value) plus total bits set in lower indices below id -- // contains_check is 0 if the bitset had id set, else it's -1: so index is unaffected if contains_check == 0, -- // otherwise it comes out as -1. -- return (int)(((index_value >>> 32) + Long.bitCount(index_value & lower_mask)) | contains_check); -- } --} -diff --git a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java -index 45744d86e9582a93a0cec26009deea091080fbbe..daedcfd867ed6171fb61bdcbded417a11c8a5b0f 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java -+++ b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java -@@ -39,13 +39,11 @@ public abstract class StateHolder { - private final Reference2ObjectArrayMap, Comparable> values; - private Table, Comparable, S> neighbours; - protected final MapCodec propertiesCodec; -- protected final io.papermc.paper.util.table.ZeroCollidingReferenceStateTable optimisedTable; // Paper - optimise state lookup - - protected StateHolder(O owner, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { - this.owner = owner; - this.values = propertyMap; - this.propertiesCodec = codec; -- this.optimisedTable = new io.papermc.paper.util.table.ZeroCollidingReferenceStateTable(this, propertyMap); // Paper - optimise state lookup - } - - public > S cycle(Property property) { -@@ -86,11 +84,11 @@ public abstract class StateHolder { - } - - public > boolean hasProperty(Property property) { -- return this.optimisedTable.get(property) != null; // Paper - optimise state lookup -+ return this.values.containsKey(property); - } - - public > T getValue(Property property) { -- Comparable comparable = this.optimisedTable.get(property); // Paper - optimise state lookup -+ Comparable comparable = this.values.get(property); - if (comparable == null) { - throw new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.owner); - } else { -@@ -99,18 +97,24 @@ public abstract class StateHolder { - } - - public > Optional getOptionalValue(Property property) { -- Comparable comparable = this.optimisedTable.get(property); // Paper - optimise state lookup -+ Comparable comparable = this.values.get(property); - return comparable == null ? Optional.empty() : Optional.of(property.getValueClass().cast(comparable)); - } - - public , V extends T> S setValue(Property property, V value) { -- // Paper start - optimise state lookup -- final S ret = (S)this.optimisedTable.get(property, value); -- if (ret == null) { -- throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value"); -+ Comparable comparable = this.values.get(property); -+ if (comparable == null) { -+ throw new IllegalArgumentException("Cannot set property " + property + " as it does not exist in " + this.owner); -+ } else if (comparable.equals(value)) { -+ return (S)this; -+ } else { -+ S object = this.neighbours.get(property, value); -+ if (object == null) { -+ throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value"); -+ } else { -+ return object; -+ } - } -- return ret; -- // Paper end - optimise state lookup - } - - public , V extends T> S trySetValue(Property property, V value) { -@@ -143,7 +147,7 @@ public abstract class StateHolder { - } - } - -- this.neighbours = (Table, Comparable, S>)(table.isEmpty() ? table : ArrayTable.create(table)); this.optimisedTable.loadInTable((Table)this.neighbours, this.values); // Paper - optimise state lookup -+ this.neighbours = (Table, Comparable, S>)(table.isEmpty() ? table : ArrayTable.create(table)); - } - } - -diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java -index ff5fd91257c4554c523682009efe1db83f53fd5b..b63116b333b6e06494091a82588acfb639bddb71 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java -+++ b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java -@@ -7,13 +7,6 @@ import java.util.Optional; - public class BooleanProperty extends Property { - private final ImmutableSet values = ImmutableSet.of(true, false); - -- // Paper start - optimise iblockdata state lookup -- @Override -- public final int getIdFor(final Boolean value) { -- return value.booleanValue() ? 1 : 0; -- } -- // Paper end - optimise iblockdata state lookup -- - protected BooleanProperty(String name) { - super(name, Boolean.class); - } -diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java -index 498c5abe0a9d024d77029719c621c1c8485791f3..3097298fe356df98967cf4bdeaaede69dfe8a441 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java -+++ b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java -@@ -15,15 +15,6 @@ public class EnumProperty & StringRepresentable> extends Prope - private final ImmutableSet values; - private final Map names = Maps.newHashMap(); - -- // Paper start - optimise iblockdata state lookup -- private int[] idLookupTable; -- -- @Override -- public final int getIdFor(final T value) { -- return this.idLookupTable[value.ordinal()]; -- } -- // Paper end - optimise iblockdata state lookup -- - protected EnumProperty(String name, Class type, Collection values) { - super(name, type); - this.values = ImmutableSet.copyOf(values); -@@ -36,14 +27,6 @@ public class EnumProperty & StringRepresentable> extends Prope - - this.names.put(string, enum_); - } -- // Paper start - optimise BlockState lookup -- int id = 0; -- this.idLookupTable = new int[type.getEnumConstants().length]; -- java.util.Arrays.fill(this.idLookupTable, -1); -- for (final T value : this.getPossibleValues()) { -- this.idLookupTable[value.ordinal()] = id++; -- } -- // Paper end - optimise BlockState lookup - } - - @Override -diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java -index 977504f2641d0133a572b0d5de85d058609343bb..3a850321a4bcc68058483b5fd53e829c425a68af 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java -+++ b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java -@@ -11,16 +11,6 @@ public class IntegerProperty extends Property { - public final int min; - public final int max; - -- // Paper start - optimise iblockdata state lookup -- @Override -- public final int getIdFor(final Integer value) { -- final int val = value.intValue(); -- final int ret = val - this.min; -- -- return ret | ((this.max - ret) >> 31); -- } -- // Paper end - optimise iblockdata state lookup -- - protected IntegerProperty(String name, int min, int max) { - super(name, Integer.class); - if (min < 0) { -diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java -index b9493e3762410aca8e683c32b5aef187c0bee082..9055f15af0cae55effa6942913a9d7edf3857e07 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java -+++ b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java -@@ -24,17 +24,6 @@ public abstract class Property> { - ); - private final Codec> valueCodec = this.codec.xmap(this::value, Property.Value::value); - -- // Paper start - optimise iblockdata state lookup -- private static final java.util.concurrent.atomic.AtomicInteger ID_GENERATOR = new java.util.concurrent.atomic.AtomicInteger(); -- private final int id = ID_GENERATOR.getAndIncrement(); -- -- public final int getId() { -- return this.id; -- } -- -- public abstract int getIdFor(final T value); -- // Paper end - optimise state lookup -- - protected Property(String name, Class type) { - this.clazz = type; - this.name = name; diff --git a/patches/unapplied/server/1005-Custom-table-implementation-for-blockstate-state-loo.patch b/patches/unapplied/server/1005-Custom-table-implementation-for-blockstate-state-loo.patch deleted file mode 100644 index 96d90abea3ba..000000000000 --- a/patches/unapplied/server/1005-Custom-table-implementation-for-blockstate-state-loo.patch +++ /dev/null @@ -1,343 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Thu, 11 Mar 2021 20:05:44 -0800 -Subject: [PATCH] Custom table implementation for blockstate state lookups - -Testing some redstone intensive machines showed to bring about a 10% -improvement. - -diff --git a/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java b/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java -new file mode 100644 -index 0000000000000000000000000000000000000000..57d0cd3ad6f972e986c72a57f1a6e36003f190c2 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java -@@ -0,0 +1,160 @@ -+package io.papermc.paper.util.table; -+ -+import com.google.common.collect.Table; -+import net.minecraft.world.level.block.state.StateHolder; -+import net.minecraft.world.level.block.state.properties.Property; -+import java.util.Collection; -+import java.util.HashSet; -+import java.util.Map; -+import java.util.Set; -+ -+public final class ZeroCollidingReferenceStateTable { -+ -+ // upper 32 bits: starting index -+ // lower 32 bits: bitset for contained ids -+ protected final long[] this_index_table; -+ protected final Comparable[] this_table; -+ protected final StateHolder this_state; -+ -+ protected long[] index_table; -+ protected StateHolder[][] value_table; -+ -+ public ZeroCollidingReferenceStateTable(final StateHolder state, final Map, Comparable> this_map) { -+ this.this_state = state; -+ this.this_index_table = this.create_table(this_map.keySet()); -+ -+ int max_id = -1; -+ for (final Property property : this_map.keySet()) { -+ final int id = lookup_vindex(property, this.this_index_table); -+ if (id > max_id) { -+ max_id = id; -+ } -+ } -+ -+ this.this_table = new Comparable[max_id + 1]; -+ for (final Map.Entry, Comparable> entry : this_map.entrySet()) { -+ this.this_table[lookup_vindex(entry.getKey(), this.this_index_table)] = entry.getValue(); -+ } -+ } -+ -+ public void loadInTable(final Table, Comparable, StateHolder> table, -+ final Map, Comparable> this_map) { -+ final Set> combined = new HashSet<>(table.rowKeySet()); -+ combined.addAll(this_map.keySet()); -+ -+ this.index_table = this.create_table(combined); -+ -+ int max_id = -1; -+ for (final Property property : combined) { -+ final int id = lookup_vindex(property, this.index_table); -+ if (id > max_id) { -+ max_id = id; -+ } -+ } -+ -+ this.value_table = new StateHolder[max_id + 1][]; -+ -+ final Map, Map, StateHolder>> map = table.rowMap(); -+ for (final Property property : map.keySet()) { -+ final Map, StateHolder> propertyMap = map.get(property); -+ -+ final int id = lookup_vindex(property, this.index_table); -+ final StateHolder[] states = this.value_table[id] = new StateHolder[property.getPossibleValues().size()]; -+ -+ for (final Map.Entry, StateHolder> entry : propertyMap.entrySet()) { -+ if (entry.getValue() == null) { -+ // TODO what -+ continue; -+ } -+ -+ states[((Property)property).getIdFor(entry.getKey())] = entry.getValue(); -+ } -+ } -+ -+ -+ for (final Map.Entry, Comparable> entry : this_map.entrySet()) { -+ final Property property = entry.getKey(); -+ final int index = lookup_vindex(property, this.index_table); -+ -+ if (this.value_table[index] == null) { -+ this.value_table[index] = new StateHolder[property.getPossibleValues().size()]; -+ } -+ -+ this.value_table[index][((Property)property).getIdFor(entry.getValue())] = this.this_state; -+ } -+ } -+ -+ -+ protected long[] create_table(final Collection> collection) { -+ int max_id = -1; -+ for (final Property property : collection) { -+ final int id = property.getId(); -+ if (id > max_id) { -+ max_id = id; -+ } -+ } -+ -+ final long[] ret = new long[((max_id + 1) + 31) >>> 5]; // ceil((max_id + 1) / 32) -+ -+ for (final Property property : collection) { -+ final int id = property.getId(); -+ -+ ret[id >>> 5] |= (1L << (id & 31)); -+ } -+ -+ int total = 0; -+ for (int i = 1, len = ret.length; i < len; ++i) { -+ ret[i] |= (long)(total += Long.bitCount(ret[i - 1] & 0xFFFFFFFFL)) << 32; -+ } -+ -+ return ret; -+ } -+ -+ public Comparable get(final Property state) { -+ final Comparable[] table = this.this_table; -+ final int index = lookup_vindex(state, this.this_index_table); -+ -+ if (index < 0 || index >= table.length) { -+ return null; -+ } -+ return table[index]; -+ } -+ -+ public StateHolder get(final Property property, final Comparable with) { -+ final int withId = ((Property)property).getIdFor(with); -+ if (withId < 0) { -+ return null; -+ } -+ -+ final int index = lookup_vindex(property, this.index_table); -+ final StateHolder[][] table = this.value_table; -+ if (index < 0 || index >= table.length) { -+ return null; -+ } -+ -+ final StateHolder[] values = table[index]; -+ -+ if (withId >= values.length) { -+ return null; -+ } -+ -+ return values[withId]; -+ } -+ -+ protected static int lookup_vindex(final Property property, final long[] index_table) { -+ final int id = property.getId(); -+ final long bitset_mask = (1L << (id & 31)); -+ final long lower_mask = bitset_mask - 1; -+ final int index = id >>> 5; -+ if (index >= index_table.length) { -+ return -1; -+ } -+ final long index_value = index_table[index]; -+ final long contains_check = ((index_value & bitset_mask) - 1) >> (Long.SIZE - 1); // -1L if doesn't contain -+ -+ // index = total bits set in lower table values (upper 32 bits of index_value) plus total bits set in lower indices below id -+ // contains_check is 0 if the bitset had id set, else it's -1: so index is unaffected if contains_check == 0, -+ // otherwise it comes out as -1. -+ return (int)(((index_value >>> 32) + Long.bitCount(index_value & lower_mask)) | contains_check); -+ } -+} -diff --git a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java -index daedcfd867ed6171fb61bdcbded417a11c8a5b0f..45744d86e9582a93a0cec26009deea091080fbbe 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java -+++ b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java -@@ -39,11 +39,13 @@ public abstract class StateHolder { - private final Reference2ObjectArrayMap, Comparable> values; - private Table, Comparable, S> neighbours; - protected final MapCodec propertiesCodec; -+ protected final io.papermc.paper.util.table.ZeroCollidingReferenceStateTable optimisedTable; // Paper - optimise state lookup - - protected StateHolder(O owner, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { - this.owner = owner; - this.values = propertyMap; - this.propertiesCodec = codec; -+ this.optimisedTable = new io.papermc.paper.util.table.ZeroCollidingReferenceStateTable(this, propertyMap); // Paper - optimise state lookup - } - - public > S cycle(Property property) { -@@ -84,11 +86,11 @@ public abstract class StateHolder { - } - - public > boolean hasProperty(Property property) { -- return this.values.containsKey(property); -+ return this.optimisedTable.get(property) != null; // Paper - optimise state lookup - } - - public > T getValue(Property property) { -- Comparable comparable = this.values.get(property); -+ Comparable comparable = this.optimisedTable.get(property); // Paper - optimise state lookup - if (comparable == null) { - throw new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.owner); - } else { -@@ -97,24 +99,18 @@ public abstract class StateHolder { - } - - public > Optional getOptionalValue(Property property) { -- Comparable comparable = this.values.get(property); -+ Comparable comparable = this.optimisedTable.get(property); // Paper - optimise state lookup - return comparable == null ? Optional.empty() : Optional.of(property.getValueClass().cast(comparable)); - } - - public , V extends T> S setValue(Property property, V value) { -- Comparable comparable = this.values.get(property); -- if (comparable == null) { -- throw new IllegalArgumentException("Cannot set property " + property + " as it does not exist in " + this.owner); -- } else if (comparable.equals(value)) { -- return (S)this; -- } else { -- S object = this.neighbours.get(property, value); -- if (object == null) { -- throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value"); -- } else { -- return object; -- } -+ // Paper start - optimise state lookup -+ final S ret = (S)this.optimisedTable.get(property, value); -+ if (ret == null) { -+ throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value"); - } -+ return ret; -+ // Paper end - optimise state lookup - } - - public , V extends T> S trySetValue(Property property, V value) { -@@ -147,7 +143,7 @@ public abstract class StateHolder { - } - } - -- this.neighbours = (Table, Comparable, S>)(table.isEmpty() ? table : ArrayTable.create(table)); -+ this.neighbours = (Table, Comparable, S>)(table.isEmpty() ? table : ArrayTable.create(table)); this.optimisedTable.loadInTable((Table)this.neighbours, this.values); // Paper - optimise state lookup - } - } - -diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java -index b63116b333b6e06494091a82588acfb639bddb71..ff5fd91257c4554c523682009efe1db83f53fd5b 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java -+++ b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java -@@ -7,6 +7,13 @@ import java.util.Optional; - public class BooleanProperty extends Property { - private final ImmutableSet values = ImmutableSet.of(true, false); - -+ // Paper start - optimise iblockdata state lookup -+ @Override -+ public final int getIdFor(final Boolean value) { -+ return value.booleanValue() ? 1 : 0; -+ } -+ // Paper end - optimise iblockdata state lookup -+ - protected BooleanProperty(String name) { - super(name, Boolean.class); - } -diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java -index 3097298fe356df98967cf4bdeaaede69dfe8a441..498c5abe0a9d024d77029719c621c1c8485791f3 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java -+++ b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java -@@ -15,6 +15,15 @@ public class EnumProperty & StringRepresentable> extends Prope - private final ImmutableSet values; - private final Map names = Maps.newHashMap(); - -+ // Paper start - optimise iblockdata state lookup -+ private int[] idLookupTable; -+ -+ @Override -+ public final int getIdFor(final T value) { -+ return this.idLookupTable[value.ordinal()]; -+ } -+ // Paper end - optimise iblockdata state lookup -+ - protected EnumProperty(String name, Class type, Collection values) { - super(name, type); - this.values = ImmutableSet.copyOf(values); -@@ -27,6 +36,14 @@ public class EnumProperty & StringRepresentable> extends Prope - - this.names.put(string, enum_); - } -+ // Paper start - optimise BlockState lookup -+ int id = 0; -+ this.idLookupTable = new int[type.getEnumConstants().length]; -+ java.util.Arrays.fill(this.idLookupTable, -1); -+ for (final T value : this.getPossibleValues()) { -+ this.idLookupTable[value.ordinal()] = id++; -+ } -+ // Paper end - optimise BlockState lookup - } - - @Override -diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java -index 3a850321a4bcc68058483b5fd53e829c425a68af..977504f2641d0133a572b0d5de85d058609343bb 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java -+++ b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java -@@ -11,6 +11,16 @@ public class IntegerProperty extends Property { - public final int min; - public final int max; - -+ // Paper start - optimise iblockdata state lookup -+ @Override -+ public final int getIdFor(final Integer value) { -+ final int val = value.intValue(); -+ final int ret = val - this.min; -+ -+ return ret | ((this.max - ret) >> 31); -+ } -+ // Paper end - optimise iblockdata state lookup -+ - protected IntegerProperty(String name, int min, int max) { - super(name, Integer.class); - if (min < 0) { -diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java -index 9055f15af0cae55effa6942913a9d7edf3857e07..b9493e3762410aca8e683c32b5aef187c0bee082 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java -+++ b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java -@@ -24,6 +24,17 @@ public abstract class Property> { - ); - private final Codec> valueCodec = this.codec.xmap(this::value, Property.Value::value); - -+ // Paper start - optimise iblockdata state lookup -+ private static final java.util.concurrent.atomic.AtomicInteger ID_GENERATOR = new java.util.concurrent.atomic.AtomicInteger(); -+ private final int id = ID_GENERATOR.getAndIncrement(); -+ -+ public final int getId() { -+ return this.id; -+ } -+ -+ public abstract int getIdFor(final T value); -+ // Paper end - optimise state lookup -+ - protected Property(String name, Class type) { - this.clazz = type; - this.name = name; From 8e569ba62a3b4bf39d1669b6423b99ccffa74182 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 24 Oct 2024 08:20:45 -0700 Subject: [PATCH 062/119] Merge patches --- patches/server/0822-fixup-MC-Utils.patch | 1263 -- ...ch => 0822-fixup-Paper-config-files.patch} | 4 +- patches/server/0823-fixup-MC-Utils.patch | 1318 +- ...> 0824-Rewrite-dataconverter-system.patch} | 0 ...timize-BlockPosition-helper-methods.patch} | 0 .../0826-Moonrise-optimisation-patches.patch | 8557 ++++++---- ...-fixup-Moonrise-optimisation-patches.patch | 13349 ---------------- 7 files changed, 6935 insertions(+), 17556 deletions(-) delete mode 100644 patches/server/0822-fixup-MC-Utils.patch rename patches/server/{0824-fixup-Paper-config-files.patch => 0822-fixup-Paper-config-files.patch} (95%) rename patches/server/{0825-Rewrite-dataconverter-system.patch => 0824-Rewrite-dataconverter-system.patch} (100%) rename patches/server/{0827-fixup-Optimize-BlockPosition-helper-methods.patch => 0825-fixup-Optimize-BlockPosition-helper-methods.patch} (100%) delete mode 100644 patches/server/0828-fixup-Moonrise-optimisation-patches.patch diff --git a/patches/server/0822-fixup-MC-Utils.patch b/patches/server/0822-fixup-MC-Utils.patch deleted file mode 100644 index cc014ce7e8da..000000000000 --- a/patches/server/0822-fixup-MC-Utils.patch +++ /dev/null @@ -1,1263 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Mon, 21 Oct 2024 12:21:54 -0700 -Subject: [PATCH] fixup! MC Utils - - -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java -new file mode 100644 -index 0000000000000000000000000000000000000000..3c5ed66328ccf94c4744a191a7c63562dd08158d ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java -@@ -0,0 +1,115 @@ -+package ca.spottedleaf.moonrise.common; -+ -+import com.mojang.datafixers.DataFixer; -+import net.minecraft.core.BlockPos; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.server.level.GenerationChunkHolder; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.util.datafix.DataFixTypes; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.level.BlockGetter; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.ProtoChunk; -+import net.minecraft.world.level.chunk.storage.SerializableChunkData; -+import net.minecraft.world.level.entity.EntityTypeTest; -+import net.minecraft.world.phys.AABB; -+import java.util.List; -+import java.util.ServiceLoader; -+import java.util.function.Predicate; -+ -+public interface PlatformHooks { -+ public static PlatformHooks get() { -+ return Holder.INSTANCE; -+ } -+ -+ public String getBrand(); -+ -+ public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos); -+ -+ public Predicate maybeHasLightEmission(); -+ -+ public boolean hasCurrentlyLoadingChunk(); -+ -+ public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder); -+ -+ public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk); -+ -+ public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original); -+ -+ public boolean allowAsyncTicketUpdates(); -+ -+ public void onChunkHolderTicketChange(final ServerLevel world, final ChunkHolder holder, final int oldLevel, final int newLevel); -+ -+ public void chunkUnloadFromWorld(final LevelChunk chunk); -+ -+ public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data); -+ -+ public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player); -+ -+ public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player); -+ -+ public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate predicate, -+ final List into); -+ -+ public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, -+ final AABB boundingBox, final Predicate predicate, -+ final List into, final int maxCount); -+ -+ public void entityMove(final Entity entity, final long oldSection, final long newSection); -+ -+ public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event); -+ -+ public boolean configFixMC224294(); -+ -+ public boolean configAutoConfigSendDistance(); -+ -+ public double configPlayerMaxLoadRate(); -+ -+ public double configPlayerMaxGenRate(); -+ -+ public double configPlayerMaxSendRate(); -+ -+ public int configPlayerMaxConcurrentLoads(); -+ -+ public int configPlayerMaxConcurrentGens(); -+ -+ public long configAutoSaveInterval(); -+ -+ public int configMaxAutoSavePerTick(); -+ -+ public boolean configFixMC159283(); -+ -+ // support for CB chunk mustNotSave -+ public boolean forceNoSave(final ChunkAccess chunk); -+ -+ public CompoundTag convertNBT(final DataFixTypes type, final DataFixer dataFixer, final CompoundTag nbt, -+ final int fromVersion, final int toVersion); -+ -+ public boolean hasMainChunkLoadHook(); -+ -+ public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData); -+ -+ public List modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List entities); -+ -+ public void unloadEntity(final Entity entity); -+ -+ public int modifyEntityTrackingRange(final Entity entity, final int currentRange); -+ -+ public static final class Holder { -+ private Holder() { -+ } -+ -+ private static final PlatformHooks INSTANCE; -+ -+ static { -+ INSTANCE = ServiceLoader.load(PlatformHooks.class, PlatformHooks.class.getClassLoader()).findFirst() -+ .orElseThrow(() -> new RuntimeException("Failed to locate PlatformHooks")); -+ } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java -index ba68998f6ef57b24c72fd833bd7de440de9501cc..7fed43a1e7bcf35c4d7fd3224837a47fedd59860 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java -@@ -13,15 +13,15 @@ import java.util.NoSuchElementException; - */ - public final class EntityList implements Iterable { - -- protected final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); -+ private final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); - { - this.entityToIndex.defaultReturnValue(Integer.MIN_VALUE); - } - -- protected static final Entity[] EMPTY_LIST = new Entity[0]; -+ private static final Entity[] EMPTY_LIST = new Entity[0]; - -- protected Entity[] entities = EMPTY_LIST; -- protected int count; -+ private Entity[] entities = EMPTY_LIST; -+ private int count; - - public int size() { - return this.count; -@@ -94,10 +94,9 @@ public final class EntityList implements Iterable { - - @Override - public Iterator iterator() { -- return new Iterator() { -- -- Entity lastRet; -- int current; -+ return new Iterator<>() { -+ private Entity lastRet; -+ private int current; - - @Override - public boolean hasNext() { -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java -deleted file mode 100644 -index fcfbca333234c09f7c056bbfcd9ac8860b20a8db..0000000000000000000000000000000000000000 ---- a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java -+++ /dev/null -@@ -1,125 +0,0 @@ --package ca.spottedleaf.moonrise.common.list; -- --import it.unimi.dsi.fastutil.longs.LongIterator; --import it.unimi.dsi.fastutil.shorts.Short2LongOpenHashMap; --import java.util.Arrays; --import net.minecraft.world.level.block.Block; --import net.minecraft.world.level.block.state.BlockState; --import net.minecraft.world.level.chunk.GlobalPalette; -- --public final class IBlockDataList { -- -- private static final GlobalPalette GLOBAL_PALETTE = new GlobalPalette<>(Block.BLOCK_STATE_REGISTRY); -- -- // map of location -> (index | (location << 16) | (palette id << 32)) -- private final Short2LongOpenHashMap map = new Short2LongOpenHashMap(2, 0.8f); -- { -- this.map.defaultReturnValue(Long.MAX_VALUE); -- } -- -- private static final long[] EMPTY_LIST = new long[0]; -- -- private long[] byIndex = EMPTY_LIST; -- private int size; -- -- public static int getLocationKey(final int x, final int y, final int z) { -- return (x & 15) | (((z & 15) << 4)) | ((y & 255) << (4 + 4)); -- } -- -- public static BlockState getBlockDataFromRaw(final long raw) { -- return GLOBAL_PALETTE.valueFor((int)(raw >>> 32)); -- } -- -- public static int getIndexFromRaw(final long raw) { -- return (int)(raw & 0xFFFF); -- } -- -- public static int getLocationFromRaw(final long raw) { -- return (int)((raw >>> 16) & 0xFFFF); -- } -- -- public static long getRawFromValues(final int index, final int location, final BlockState data) { -- return (long)index | ((long)location << 16) | (((long)GLOBAL_PALETTE.idFor(data)) << 32); -- } -- -- public static long setIndexRawValues(final long value, final int index) { -- return value & ~(0xFFFF) | (index); -- } -- -- public long add(final int x, final int y, final int z, final BlockState data) { -- return this.add(getLocationKey(x, y, z), data); -- } -- -- public long add(final int location, final BlockState data) { -- final long curr = this.map.get((short)location); -- -- if (curr == Long.MAX_VALUE) { -- final int index = this.size++; -- final long raw = getRawFromValues(index, location, data); -- this.map.put((short)location, raw); -- -- if (index >= this.byIndex.length) { -- this.byIndex = Arrays.copyOf(this.byIndex, (int)Math.max(4L, this.byIndex.length * 2L)); -- } -- -- this.byIndex[index] = raw; -- return raw; -- } else { -- final int index = getIndexFromRaw(curr); -- final long raw = this.byIndex[index] = getRawFromValues(index, location, data); -- -- this.map.put((short)location, raw); -- -- return raw; -- } -- } -- -- public long remove(final int x, final int y, final int z) { -- return this.remove(getLocationKey(x, y, z)); -- } -- -- public long remove(final int location) { -- final long ret = this.map.remove((short)location); -- final int index = getIndexFromRaw(ret); -- if (ret == Long.MAX_VALUE) { -- return ret; -- } -- -- // move the entry at the end to this index -- final int endIndex = --this.size; -- final long end = this.byIndex[endIndex]; -- if (index != endIndex) { -- // not empty after this call -- this.map.put((short)getLocationFromRaw(end), setIndexRawValues(end, index)); -- } -- this.byIndex[index] = end; -- this.byIndex[endIndex] = 0L; -- -- return ret; -- } -- -- public int size() { -- return this.size; -- } -- -- public long getRaw(final int index) { -- return this.byIndex[index]; -- } -- -- public int getLocation(final int index) { -- return getLocationFromRaw(this.getRaw(index)); -- } -- -- public BlockState getData(final int index) { -- return getBlockDataFromRaw(this.getRaw(index)); -- } -- -- public void clear() { -- this.size = 0; -- this.map.clear(); -- } -- -- public LongIterator getRawIterator() { -- return this.map.values().iterator(); -- } --} -\ No newline at end of file -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java -new file mode 100644 -index 0000000000000000000000000000000000000000..9f3b25bb2439f283f878db93973a02fcdcd14eed ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java -@@ -0,0 +1,77 @@ -+package ca.spottedleaf.moonrise.common.list; -+ -+import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; -+import java.util.Arrays; -+ -+public final class IntList { -+ -+ private final Int2IntOpenHashMap map = new Int2IntOpenHashMap(); -+ { -+ this.map.defaultReturnValue(Integer.MIN_VALUE); -+ } -+ -+ private static final int[] EMPTY_LIST = new int[0]; -+ -+ private int[] byIndex = EMPTY_LIST; -+ private int count; -+ -+ public int size() { -+ return this.count; -+ } -+ -+ public void setMinCapacity(final int len) { -+ final int[] byIndex = this.byIndex; -+ if (byIndex.length < len) { -+ this.byIndex = Arrays.copyOf(byIndex, len); -+ } -+ } -+ -+ public int getRaw(final int index) { -+ return this.byIndex[index]; -+ } -+ -+ public boolean add(final int value) { -+ final int count = this.count; -+ final int currIndex = this.map.putIfAbsent(value, count); -+ -+ if (currIndex != Integer.MIN_VALUE) { -+ return false; // already in this list -+ } -+ -+ int[] list = this.byIndex; -+ -+ if (list.length == count) { -+ // resize required -+ list = this.byIndex = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative -+ } -+ -+ list[count] = value; -+ this.count = count + 1; -+ -+ return true; -+ } -+ -+ public boolean remove(final int value) { -+ final int index = this.map.remove(value); -+ if (index == Integer.MIN_VALUE) { -+ return false; -+ } -+ -+ // move the entry at the end to this index -+ final int endIndex = --this.count; -+ final int end = this.byIndex[endIndex]; -+ if (index != endIndex) { -+ // not empty after this call -+ this.map.put(end, index); -+ } -+ this.byIndex[index] = end; -+ this.byIndex[endIndex] = 0; -+ -+ return true; -+ } -+ -+ public void clear() { -+ this.count = 0; -+ this.map.clear(); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java -new file mode 100644 -index 0000000000000000000000000000000000000000..2bae9949ef325d0001aa638150fbbdf968367e75 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java -@@ -0,0 +1,77 @@ -+package ca.spottedleaf.moonrise.common.list; -+ -+import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap; -+import java.util.Arrays; -+ -+public final class ShortList { -+ -+ private final Short2ShortOpenHashMap map = new Short2ShortOpenHashMap(); -+ { -+ this.map.defaultReturnValue(Short.MIN_VALUE); -+ } -+ -+ private static final short[] EMPTY_LIST = new short[0]; -+ -+ private short[] byIndex = EMPTY_LIST; -+ private short count; -+ -+ public int size() { -+ return (int)this.count; -+ } -+ -+ public short getRaw(final int index) { -+ return this.byIndex[index]; -+ } -+ -+ public void setMinCapacity(final int len) { -+ final short[] byIndex = this.byIndex; -+ if (byIndex.length < len) { -+ this.byIndex = Arrays.copyOf(byIndex, len); -+ } -+ } -+ -+ public boolean add(final short value) { -+ final int count = (int)this.count; -+ final short currIndex = this.map.putIfAbsent(value, (short)count); -+ -+ if (currIndex != Short.MIN_VALUE) { -+ return false; // already in this list -+ } -+ -+ short[] list = this.byIndex; -+ -+ if (list.length == count) { -+ // resize required -+ list = this.byIndex = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative -+ } -+ -+ list[count] = value; -+ this.count = (short)(count + 1); -+ -+ return true; -+ } -+ -+ public boolean remove(final short value) { -+ final short index = this.map.remove(value); -+ if (index == Short.MIN_VALUE) { -+ return false; -+ } -+ -+ // move the entry at the end to this index -+ final short endIndex = --this.count; -+ final short end = this.byIndex[endIndex]; -+ if (index != endIndex) { -+ // not empty after this call -+ this.map.put(end, index); -+ } -+ this.byIndex[(int)index] = end; -+ this.byIndex[(int)endIndex] = (short)0; -+ -+ return true; -+ } -+ -+ public void clear() { -+ this.count = (short)0; -+ this.map.clear(); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c2d917c2eac55b8a4411a6e159f177f9428b1150 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java -@@ -0,0 +1,22 @@ -+package ca.spottedleaf.moonrise.common.misc; -+ -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import java.lang.invoke.VarHandle; -+ -+public final class LazyRunnable implements Runnable { -+ -+ private volatile Runnable toRun; -+ private static final VarHandle TO_RUN_HANDLE = ConcurrentUtil.getVarHandle(LazyRunnable.class, "toRun", Runnable.class); -+ -+ public void setRunnable(final Runnable run) { -+ final Runnable prev = (Runnable)TO_RUN_HANDLE.compareAndExchange(this, (Runnable)null, run); -+ if (prev != null) { -+ throw new IllegalStateException("Runnable already set"); -+ } -+ } -+ -+ @Override -+ public void run() { -+ ((Runnable)TO_RUN_HANDLE.getVolatile(this)).run(); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java -index ab093b0e8ac6f762921eb1d15f5217345c4eba05..bb44de17a37082e57f2292a4f470740be1d09b11 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java -@@ -4,13 +4,17 @@ import ca.spottedleaf.moonrise.common.list.ReferenceList; - import ca.spottedleaf.moonrise.common.util.CoordinateUtils; - import ca.spottedleaf.moonrise.common.util.MoonriseConstants; - import ca.spottedleaf.moonrise.common.util.ChunkSystem; -+import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel; -+import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; - import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants; -+import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel; - import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; - import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; - import net.minecraft.core.BlockPos; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.server.level.ServerPlayer; - import net.minecraft.world.level.ChunkPos; -+import java.util.ArrayList; - - public final class NearbyPlayers { - -@@ -20,7 +24,27 @@ public final class NearbyPlayers { - GENERAL_REALLY_SMALL, - TICK_VIEW_DISTANCE, - VIEW_DISTANCE, -- SPAWN_RANGE, // Moonrise - chunk tick iteration -+ // Moonrise start - chunk tick iteration -+ SPAWN_RANGE { -+ @Override -+ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { -+ ((ChunkTickServerLevel)world).moonrise$addPlayerTickingRequest(chunkX, chunkZ); -+ } -+ -+ @Override -+ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { -+ ((ChunkTickServerLevel)world).moonrise$removePlayerTickingRequest(chunkX, chunkZ); -+ } -+ }; -+ // Moonrise end - chunk tick iteration -+ -+ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { -+ -+ } -+ -+ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { -+ -+ } - } - - private static final NearbyMapType[] MAP_TYPES = NearbyMapType.values(); -@@ -37,6 +61,12 @@ public final class NearbyPlayers { - private final ServerLevel world; - private final Reference2ReferenceOpenHashMap players = new Reference2ReferenceOpenHashMap<>(); - private final Long2ReferenceOpenHashMap byChunk = new Long2ReferenceOpenHashMap<>(); -+ private final Long2ReferenceOpenHashMap>[] directByChunk = new Long2ReferenceOpenHashMap[TOTAL_MAP_TYPES]; -+ { -+ for (int i = 0; i < this.directByChunk.length; ++i) { -+ this.directByChunk[i] = new Long2ReferenceOpenHashMap<>(); -+ } -+ } - - public NearbyPlayers(final ServerLevel world) { - this.world = world; -@@ -70,6 +100,16 @@ public final class NearbyPlayers { - } - } - -+ public void clear() { -+ if (this.players.isEmpty()) { -+ return; -+ } -+ -+ for (final ServerPlayer player : new ArrayList<>(this.players.keySet())) { -+ this.removePlayer(player); -+ } -+ } -+ - public void tickPlayer(final ServerPlayer player) { - final TrackedPlayer[] players = this.players.get(player); - if (players == null) { -@@ -94,38 +134,41 @@ public final class NearbyPlayers { - return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); - } - -- public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { -- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -+ public TrackedChunk getChunk(final int chunkX, final int chunkZ) { -+ return this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ } - -- return chunk == null ? null : chunk.players[type.ordinal()]; -+ public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { -+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); - } - - public ReferenceList getPlayers(final ChunkPos pos, final NearbyMapType type) { -- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -- -- return chunk == null ? null : chunk.players[type.ordinal()]; -+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); - } - - public ReferenceList getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) { -- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -- -- return chunk == null ? null : chunk.players[type.ordinal()]; -+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); - } - - public ReferenceList getPlayersByBlock(final int blockX, final int blockZ, final NearbyMapType type) { -- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); -- -- return chunk == null ? null : chunk.players[type.ordinal()]; -+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); - } - - public static final class TrackedChunk { - - private static final ServerPlayer[] EMPTY_PLAYERS_ARRAY = new ServerPlayer[0]; - -+ private final long chunkKey; -+ private final NearbyPlayers nearbyPlayers; - private final ReferenceList[] players = new ReferenceList[TOTAL_MAP_TYPES]; - private int nonEmptyLists; - private long updateCount; - -+ public TrackedChunk(final long chunkKey, final NearbyPlayers nearbyPlayers) { -+ this.chunkKey = chunkKey; -+ this.nearbyPlayers = nearbyPlayers; -+ } -+ - public boolean isEmpty() { - return this.nonEmptyLists == 0; - } -@@ -145,7 +188,9 @@ public final class NearbyPlayers { - final ReferenceList list = this.players[idx]; - if (list == null) { - ++this.nonEmptyLists; -- (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)).add(player); -+ final ReferenceList players = (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)); -+ this.nearbyPlayers.directByChunk[idx].put(this.chunkKey, players); -+ players.add(player); - return; - } - -@@ -169,6 +214,7 @@ public final class NearbyPlayers { - - if (list.size() == 0) { - this.players[idx] = null; -+ this.nearbyPlayers.directByChunk[idx].remove(this.chunkKey); - --this.nonEmptyLists; - } - } -@@ -187,9 +233,19 @@ public final class NearbyPlayers { - protected void addCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { - final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); - -- NearbyPlayers.this.byChunk.computeIfAbsent(chunkKey, (final long keyInMap) -> { -- return new TrackedChunk(); -- }).addPlayer(parameter, this.type); -+ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey); -+ final NearbyMapType type = this.type; -+ if (chunk != null) { -+ chunk.addPlayer(parameter, type); -+ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); -+ } else { -+ final TrackedChunk created = new TrackedChunk(chunkKey, NearbyPlayers.this); -+ NearbyPlayers.this.byChunk.put(chunkKey, created); -+ created.addPlayer(parameter, type); -+ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); -+ -+ ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$requestChunkData(chunkKey).nearbyPlayers = created; -+ } - } - - @Override -@@ -201,10 +257,16 @@ public final class NearbyPlayers { - throw new IllegalStateException("Chunk should exist at " + new ChunkPos(chunkKey)); - } - -- chunk.removePlayer(parameter, this.type); -+ final NearbyMapType type = this.type; -+ chunk.removePlayer(parameter, type); -+ type.removeFrom(parameter, NearbyPlayers.this.world, chunkX, chunkZ); - - if (chunk.isEmpty()) { - NearbyPlayers.this.byChunk.remove(chunkKey); -+ final ChunkData chunkData = ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$releaseChunkData(chunkKey); -+ if (chunkData != null) { -+ chunkData.nearbyPlayers = null; -+ } - } - } - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -index da323a1105347d5cf4b946df10ded78a953236f2..94bba2b71918d79f54b3e28c35e76098ba0afd8c 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -@@ -1,6 +1,7 @@ - package ca.spottedleaf.moonrise.common.util; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.util.Priority; -+import ca.spottedleaf.moonrise.common.PlatformHooks; - import com.mojang.logging.LogUtils; - import net.minecraft.server.level.ChunkHolder; - import net.minecraft.server.level.FullChunkStatus; -@@ -24,15 +25,15 @@ public final class ChunkSystem { - } - - public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) { -- scheduleChunkTask(level, chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); -+ scheduleChunkTask(level, chunkX, chunkZ, run, Priority.NORMAL); - } - -- public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) { -+ public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final 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 ChunkStatus toStatus, final boolean addTicket, final Priority priority, - final Consumer onComplete) { - if (gen) { - scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -@@ -59,7 +60,7 @@ public final class ChunkSystem { - - 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 onComplete) { -+ final boolean addTicket, final Priority priority, final Consumer onComplete) { - if (!org.bukkit.Bukkit.isPrimaryThread()) { - scheduleChunkTask(level, chunkX, chunkZ, () -> { - scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -@@ -113,13 +114,13 @@ public final class ChunkSystem { - } - loadCallback.accept(result.orElse(null)); - }, (final Runnable r) -> { -- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); -+ scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST); - }); - } - - public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ, - final FullChunkStatus toStatus, final boolean addTicket, -- final PrioritisedExecutor.Priority priority, final Consumer onComplete) { -+ final Priority priority, final Consumer onComplete) { - // This method goes unused until the chunk system rewrite - if (toStatus == FullChunkStatus.INACCESSIBLE) { - throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status"); -@@ -196,7 +197,7 @@ public final class ChunkSystem { - } - loadCallback.accept(result.orElse(null)); - }, (final Runnable r) -> { -- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); -+ scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST); - }); - } - -@@ -220,7 +221,10 @@ public final class ChunkSystem { - return getUpdatingChunkHolderCount(level) != 0; - } - -- public static boolean screenEntity(final ServerLevel level, final Entity entity) { -+ public static boolean screenEntity(final ServerLevel level, final Entity entity, final boolean fromDisk, final boolean event) { -+ if (!PlatformHooks.get().screenEntity(level, entity, fromDisk, event)) { -+ return false; -+ } - return true; - } - -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java -index ac6f284ee4469d16c5655328b2488d7612832353..97848869df61648fc415e4d39f409f433202c274 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java -@@ -3,8 +3,12 @@ package ca.spottedleaf.moonrise.common.util; - public final class MixinWorkarounds { - - // mixins tries to find the owner of the clone() method, which doesn't exist and NPEs -+ // https://github.com/FabricMC/Mixin/pull/147 - public static long[] clone(final long[] values) { - return values.clone(); - } - -+ public static byte[] clone(final byte[] values) { -+ return values.clone(); -+ } - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java -index 3abe0bd2a820352b85306d554bf14a4cf6123091..c125c70a68130be373acc989053a6c0e487be924 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java -@@ -1,45 +1,100 @@ - package ca.spottedleaf.moonrise.common.util; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool; -+import ca.spottedleaf.concurrentutil.executor.thread.PrioritisedThreadPool; -+import ca.spottedleaf.moonrise.common.PlatformHooks; - import org.slf4j.Logger; - import org.slf4j.LoggerFactory; --import java.io.File; -+import java.util.concurrent.TimeUnit; -+import java.util.concurrent.atomic.AtomicInteger; -+import java.util.function.Consumer; - - public final class MoonriseCommon { - - private static final Logger LOGGER = LoggerFactory.getLogger(MoonriseCommon.class); - -- // Paper start -- public static PrioritisedThreadPool WORKER_POOL; -- public static int WORKER_THREADS; -- public static void init(io.papermc.paper.configuration.GlobalConfiguration.ChunkSystem chunkSystem) { -- // Paper end -+ public static final PrioritisedThreadPool WORKER_POOL = new PrioritisedThreadPool( -+ new Consumer<>() { -+ private final AtomicInteger idGenerator = new AtomicInteger(); -+ -+ @Override -+ public void accept(Thread thread) { -+ thread.setDaemon(true); -+ thread.setName(PlatformHooks.get().getBrand() + " Common Worker #" + this.idGenerator.getAndIncrement()); -+ thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { -+ @Override -+ public void uncaughtException(final Thread thread, final Throwable throwable) { -+ LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); -+ } -+ }); -+ } -+ } -+ ); -+ public static final long WORKER_QUEUE_HOLD_TIME = (long)(20.0e6); // 20ms -+ public static final int CLIENT_DIVISION = 0; -+ public static final PrioritisedThreadPool.ExecutorGroup RENDER_EXECUTOR_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(CLIENT_DIVISION, 0); -+ public static final int SERVER_DIVISION = 1; -+ public static final PrioritisedThreadPool.ExecutorGroup PARALLEL_GEN_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); -+ public static final PrioritisedThreadPool.ExecutorGroup RADIUS_AWARE_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); -+ public static final PrioritisedThreadPool.ExecutorGroup LOAD_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); -+ -+ public static void adjustWorkerThreads(final int configWorkerThreads, final int configIoThreads) { - int defaultWorkerThreads = Runtime.getRuntime().availableProcessors() / 2; - if (defaultWorkerThreads <= 4) { - defaultWorkerThreads = defaultWorkerThreads <= 3 ? 1 : 2; - } else { - defaultWorkerThreads = defaultWorkerThreads / 2; - } -- defaultWorkerThreads = Integer.getInteger("Paper.WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); // Paper -+ defaultWorkerThreads = Integer.getInteger(PlatformHooks.get().getBrand() + ".WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); - -- int workerThreads = chunkSystem.workerThreads; // Paper -+ int workerThreads = configWorkerThreads; - - if (workerThreads <= 0) { - workerThreads = defaultWorkerThreads; - } - -- WORKER_POOL = new PrioritisedThreadPool( -- "Paper Worker Pool", workerThreads, // Paper -- (final Thread thread, final Integer id) -> { -- thread.setName("Paper Common Worker #" + id.intValue()); // Paper -+ final int ioThreads = Math.max(1, configIoThreads); -+ -+ WORKER_POOL.adjustThreadCount(workerThreads); -+ IO_POOL.adjustThreadCount(ioThreads); -+ -+ LOGGER.info(PlatformHooks.get().getBrand() + " is using " + workerThreads + " worker threads, " + ioThreads + " I/O threads"); -+ } -+ -+ public static final PrioritisedThreadPool IO_POOL = new PrioritisedThreadPool( -+ new Consumer<>() { -+ private final AtomicInteger idGenerator = new AtomicInteger(); -+ -+ @Override -+ public void accept(final Thread thread) { -+ thread.setDaemon(true); -+ thread.setName(PlatformHooks.get().getBrand() + " I/O Worker #" + this.idGenerator.getAndIncrement()); - thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { - @Override - public void uncaughtException(final Thread thread, final Throwable throwable) { - LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); - } - }); -- }, (long)(20.0e6)); // 20ms -- WORKER_THREADS = workerThreads; -+ } -+ } -+ ); -+ public static final long IO_QUEUE_HOLD_TIME = (long)(100.0e6); // 100ms -+ public static final PrioritisedThreadPool.ExecutorGroup CLIENT_PROFILER_IO_GROUP = IO_POOL.createExecutorGroup(CLIENT_DIVISION, 0); -+ public static final PrioritisedThreadPool.ExecutorGroup SERVER_REGION_IO_GROUP = IO_POOL.createExecutorGroup(SERVER_DIVISION, 0); -+ -+ public static void haltExecutors() { -+ MoonriseCommon.WORKER_POOL.shutdown(false); -+ LOGGER.info("Awaiting termination of worker pool for up to 60s..."); -+ if (!MoonriseCommon.WORKER_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { -+ LOGGER.error("Worker pool did not shut down in time!"); -+ MoonriseCommon.WORKER_POOL.halt(false); -+ } -+ -+ MoonriseCommon.IO_POOL.shutdown(false); -+ LOGGER.info("Awaiting termination of I/O pool for up to 60s..."); -+ if (!MoonriseCommon.IO_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { -+ LOGGER.error("I/O pool did not shut down in time!"); -+ MoonriseCommon.IO_POOL.halt(false); -+ } - } - - private MoonriseCommon() {} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java -index 1cf32d7d1bbc8a0a3f7cb9024c793f6744199f64..559c959aff3c9deef867b9e425fba3e2e669cac6 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java -@@ -1,8 +1,10 @@ - package ca.spottedleaf.moonrise.common.util; - -+import ca.spottedleaf.moonrise.common.PlatformHooks; -+ - public final class MoonriseConstants { - -- public static final int MAX_VIEW_DISTANCE = 32; -+ public static final int MAX_VIEW_DISTANCE = Integer.getInteger(PlatformHooks.get().getBrand() + ".MaxViewDistance", 32); - - private MoonriseConstants() {} - -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java b/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java -new file mode 100644 -index 0000000000000000000000000000000000000000..a9ff1c1a70faf4b7a64b265932f07a8b8f00c1ff ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java -@@ -0,0 +1,52 @@ -+package ca.spottedleaf.moonrise.common.util; -+ -+import net.minecraft.world.level.levelgen.LegacyRandomSource; -+ -+/** -+ * Avoid costly CAS of superclass -+ */ -+public final class SimpleRandom extends LegacyRandomSource { -+ -+ private static final long MULTIPLIER = 25214903917L; -+ private static final long ADDEND = 11L; -+ private static final int BITS = 48; -+ private static final long MASK = (1L << BITS) - 1; -+ -+ private long value; -+ -+ public SimpleRandom(final long seed) { -+ super(0L); -+ this.value = seed; -+ } -+ -+ @Override -+ public void setSeed(final long seed) { -+ this.value = (seed ^ MULTIPLIER) & MASK; -+ } -+ -+ private long advanceSeed() { -+ return this.value = ((this.value * MULTIPLIER) + ADDEND) & MASK; -+ } -+ -+ @Override -+ public int next(final int bits) { -+ return (int)(this.advanceSeed() >>> (BITS - bits)); -+ } -+ -+ @Override -+ public int nextInt() { -+ final long seed = this.advanceSeed(); -+ return (int)(seed >>> (BITS - Integer.SIZE)); -+ } -+ -+ @Override -+ public int nextInt(final int bound) { -+ if (bound <= 0) { -+ throw new IllegalArgumentException(); -+ } -+ -+ // https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ -+ final long value = this.advanceSeed() >>> (BITS - Integer.SIZE); -+ return (int)((value * (long)bound) >>> Integer.SIZE); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java -index 11b7f15755dde766140c29bedca456c80d53293f..217d1f908a36a5177ba3cbb80a33f73d4dab0fa0 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java -@@ -77,11 +77,15 @@ public class TickThread extends Thread { - } - - public TickThread(final Runnable run, final String name) { -- this(run, name, ID_GENERATOR.incrementAndGet()); -+ this(null, run, name); - } - -- private TickThread(final Runnable run, final String name, final int id) { -- super(run, name); -+ public TickThread(final ThreadGroup group, final Runnable run, final String name) { -+ this(group, run, name, ID_GENERATOR.incrementAndGet()); -+ } -+ -+ private TickThread(final ThreadGroup group, final Runnable run, final String name, final int id) { -+ super(group, run, name); - this.id = id; - } - -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java -index af9623240ff2d389aa7090623f507720e7dbab7d..efda2688ae1254a82ba7f6bf8bf597ef224cbb86 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java -@@ -8,11 +8,19 @@ public final class WorldUtil { - // min, max are inclusive - - public static int getMaxSection(final LevelHeightAccessor world) { -- return world.getMaxSection() - 1; // getMaxSection() is exclusive -+ return world.getMaxSectionY(); -+ } -+ -+ public static int getMaxSection(final Level world) { -+ return world.getMaxSectionY(); - } - - public static int getMinSection(final LevelHeightAccessor world) { -- return world.getMinSection(); -+ return world.getMinSectionY(); -+ } -+ -+ public static int getMinSection(final Level world) { -+ return world.getMinSectionY(); - } - - public static int getMaxLightSection(final LevelHeightAccessor world) { -diff --git a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java -new file mode 100644 -index 0000000000000000000000000000000000000000..6f2dc0900dbf13a02410682eecda56cea4481346 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java -@@ -0,0 +1,199 @@ -+package ca.spottedleaf.moonrise.paper; -+ -+import ca.spottedleaf.moonrise.common.PlatformHooks; -+import com.mojang.datafixers.DataFixer; -+import net.minecraft.core.BlockPos; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.server.level.GenerationChunkHolder; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.util.datafix.DataFixTypes; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.level.BlockGetter; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.ProtoChunk; -+import net.minecraft.world.level.chunk.storage.SerializableChunkData; -+import net.minecraft.world.level.entity.EntityTypeTest; -+import net.minecraft.world.phys.AABB; -+import java.util.List; -+import java.util.function.Predicate; -+ -+public final class PaperHooks implements PlatformHooks { -+ -+ @Override -+ public String getBrand() { -+ return "Paper"; -+ } -+ -+ @Override -+ public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos) { -+ return blockState.getLightEmission(); -+ } -+ -+ @Override -+ public Predicate maybeHasLightEmission() { -+ return (final BlockState state) -> { -+ return state.getLightEmission() != 0; -+ }; -+ } -+ -+ @Override -+ public boolean hasCurrentlyLoadingChunk() { -+ return false; -+ } -+ -+ @Override -+ public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder) { -+ return null; -+ } -+ -+ @Override -+ public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk) { -+ -+ } -+ -+ @Override -+ public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original) { -+ -+ } -+ -+ @Override -+ public boolean allowAsyncTicketUpdates() { -+ return true; -+ } -+ -+ @Override -+ public void onChunkHolderTicketChange(final ServerLevel world, final ChunkHolder holder, final int oldLevel, final int newLevel) { -+ -+ } -+ -+ @Override -+ public void chunkUnloadFromWorld(final LevelChunk chunk) { -+ -+ } -+ -+ @Override -+ public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data) { -+ -+ } -+ -+ @Override -+ public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player) { -+ -+ } -+ -+ @Override -+ public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player) { -+ -+ } -+ -+ @Override -+ public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate predicate, final List into) { -+ -+ } -+ -+ @Override -+ public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, final AABB boundingBox, final Predicate predicate, final List into, final int maxCount) { -+ -+ } -+ -+ @Override -+ public void entityMove(final Entity entity, final long oldSection, final long newSection) { -+ -+ } -+ -+ @Override -+ public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event) { -+ return true; -+ } -+ -+ @Override -+ public boolean configFixMC224294() { -+ return true; -+ } -+ -+ @Override -+ public boolean configAutoConfigSendDistance() { -+ -+ } -+ -+ @Override -+ public double configPlayerMaxLoadRate() { -+ -+ } -+ -+ @Override -+ public double configPlayerMaxGenRate() { -+ -+ } -+ -+ @Override -+ public double configPlayerMaxSendRate() { -+ -+ } -+ -+ @Override -+ public int configPlayerMaxConcurrentLoads() { -+ -+ } -+ -+ @Override -+ public int configPlayerMaxConcurrentGens() { -+ -+ } -+ -+ @Override -+ public long configAutoSaveInterval() { -+ -+ } -+ -+ @Override -+ public int configMaxAutoSavePerTick() { -+ -+ } -+ -+ @Override -+ public boolean configFixMC159283() { -+ return true; -+ } -+ -+ @Override -+ public boolean forceNoSave(final ChunkAccess chunk) { -+ return chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave; -+ } -+ -+ @Override -+ public CompoundTag convertNBT(final DataFixTypes type, final DataFixer dataFixer, final CompoundTag nbt, final int fromVersion, final int toVersion) { -+ return type.update(dataFixer, nbt, fromVersion, toVersion); -+ } -+ -+ @Override -+ public boolean hasMainChunkLoadHook() { -+ return false; -+ } -+ -+ @Override -+ public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData) { -+ -+ } -+ -+ @Override -+ public List modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List entities) { -+ return entities; -+ } -+ -+ @Override -+ public void unloadEntity(final Entity entity) { -+ entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, org.bukkit.event.entity.EntityRemoveEvent.Cause.UNLOAD); -+ } -+ -+ @Override -+ public int modifyEntityTrackingRange(final Entity entity, final int currentRange) { -+ return org.spigotmc.TrackingRange.getEntityTrackingRange(entity, currentRange); -+ } -+} -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 6baa313b8201ed23193d7885c85606b0899ade3c..3eb38271b6ca26099b2da04c2d969e32fd72b2af 100644 ---- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java -+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java -@@ -94,15 +94,13 @@ public class PersistentEntitySectionManager implements A - private boolean addEntity(T entity, boolean existing) { - org.spigotmc.AsyncCatcher.catchOp("Entity add"); // Paper - // 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(); -- boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted); -- if ((!wasRemoved && entityCasted.isRemoved()) || !screened) { -- // removed by callback -- return false; -- } -+ // I don't want to know why this is a generic type. -+ Entity entityCasted = (Entity)entity; -+ boolean wasRemoved = entityCasted.isRemoved(); -+ boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted, existing, false); -+ if ((!wasRemoved && entityCasted.isRemoved()) || !screened) { -+ // removed by callback -+ return false; - } - // Paper end - chunk system hooks - if (!this.addEntityUuid(entity)) { -diff --git a/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks b/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks -new file mode 100644 -index 0000000000000000000000000000000000000000..e57c3ca79677b1dfe7cf3db36f0406de7ea5bd0a ---- /dev/null -+++ b/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks -@@ -0,0 +1 @@ -+ca.spottedleaf.moonrise.paper.PaperHooks diff --git a/patches/server/0824-fixup-Paper-config-files.patch b/patches/server/0822-fixup-Paper-config-files.patch similarity index 95% rename from patches/server/0824-fixup-Paper-config-files.patch rename to patches/server/0822-fixup-Paper-config-files.patch index a5c6d251afe8..cdf7e80f80c6 100644 --- a/patches/server/0824-fixup-Paper-config-files.patch +++ b/patches/server/0822-fixup-Paper-config-files.patch @@ -5,7 +5,7 @@ Subject: [PATCH] fixup! Paper config files diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 73e8a524925ed6f2580d3bd01616646fabafda78..4bfe7e987450afa433fcad1847f6130654769416 100644 +index 73e8a524925ed6f2580d3bd01616646fabafda78..61893f8216ddaedd899b573322f3ad0088074ac5 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -30,6 +30,45 @@ public class GlobalConfiguration extends ConfigurationPart { @@ -81,7 +81,7 @@ index 73e8a524925ed6f2580d3bd01616646fabafda78..4bfe7e987450afa433fcad1847f61306 @PostProcess private void postProcess() { - //io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.init(this); -+ ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.init(this); ++ } } diff --git a/patches/server/0823-fixup-MC-Utils.patch b/patches/server/0823-fixup-MC-Utils.patch index ea919462737d..54f6874194e2 100644 --- a/patches/server/0823-fixup-MC-Utils.patch +++ b/patches/server/0823-fixup-MC-Utils.patch @@ -1,94 +1,1257 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf -Date: Wed, 23 Oct 2024 22:13:41 -0700 +Date: Mon, 21 Oct 2024 12:21:54 -0700 Subject: [PATCH] fixup! MC Utils diff --git a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java -index 3c5ed66328ccf94c4744a191a7c63562dd08158d..deb64f7ebebcf6de91ffe0542d6b449a4db64da0 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java +new file mode 100644 +index 0000000000000000000000000000000000000000..deb64f7ebebcf6de91ffe0542d6b449a4db64da0 +--- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java -@@ -1,5 +1,6 @@ - package ca.spottedleaf.moonrise.common; - +@@ -0,0 +1,117 @@ ++package ca.spottedleaf.moonrise.common; ++ +import com.mojang.datafixers.DSL; - import com.mojang.datafixers.DataFixer; ++import com.mojang.datafixers.DataFixer; ++import net.minecraft.core.BlockPos; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.server.level.ChunkHolder; ++import net.minecraft.server.level.GenerationChunkHolder; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.level.BlockGetter; ++import net.minecraft.world.level.ChunkPos; ++import net.minecraft.world.level.Level; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.chunk.ChunkAccess; ++import net.minecraft.world.level.chunk.LevelChunk; ++import net.minecraft.world.level.chunk.ProtoChunk; ++import net.minecraft.world.level.chunk.storage.SerializableChunkData; ++import net.minecraft.world.level.entity.EntityTypeTest; ++import net.minecraft.world.phys.AABB; ++import java.util.List; ++import java.util.ServiceLoader; ++import java.util.function.Predicate; ++ ++public interface PlatformHooks { ++ public static PlatformHooks get() { ++ return Holder.INSTANCE; ++ } ++ ++ public String getBrand(); ++ ++ public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos); ++ ++ public Predicate maybeHasLightEmission(); ++ ++ public boolean hasCurrentlyLoadingChunk(); ++ ++ public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder); ++ ++ public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk); ++ ++ public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original); ++ ++ public boolean allowAsyncTicketUpdates(); ++ ++ public void onChunkHolderTicketChange(final ServerLevel world, final ChunkHolder holder, final int oldLevel, final int newLevel); ++ ++ public void chunkUnloadFromWorld(final LevelChunk chunk); ++ ++ public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data); ++ ++ public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player); ++ ++ public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player); ++ ++ public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate predicate, ++ final List into); ++ ++ public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, ++ final AABB boundingBox, final Predicate predicate, ++ final List into, final int maxCount); ++ ++ public void entityMove(final Entity entity, final long oldSection, final long newSection); ++ ++ public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event); ++ ++ public boolean configFixMC224294(); ++ ++ public boolean configAutoConfigSendDistance(); ++ ++ public double configPlayerMaxLoadRate(); ++ ++ public double configPlayerMaxGenRate(); ++ ++ public double configPlayerMaxSendRate(); ++ ++ public int configPlayerMaxConcurrentLoads(); ++ ++ public int configPlayerMaxConcurrentGens(); ++ ++ public long configAutoSaveInterval(); ++ ++ public int configMaxAutoSavePerTick(); ++ ++ public boolean configFixMC159283(); ++ ++ // support for CB chunk mustNotSave ++ public boolean forceNoSave(final ChunkAccess chunk); ++ ++ public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt, ++ final int fromVersion, final int toVersion); ++ ++ public boolean hasMainChunkLoadHook(); ++ ++ public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData); ++ ++ public List modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List entities); ++ ++ public void unloadEntity(final Entity entity); ++ ++ public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk); ++ ++ public int modifyEntityTrackingRange(final Entity entity, final int currentRange); ++ ++ public static final class Holder { ++ private Holder() { ++ } ++ ++ private static final PlatformHooks INSTANCE; ++ ++ static { ++ INSTANCE = ServiceLoader.load(PlatformHooks.class, PlatformHooks.class.getClassLoader()).findFirst() ++ .orElseThrow(() -> new RuntimeException("Failed to locate PlatformHooks")); ++ } ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java +index ba68998f6ef57b24c72fd833bd7de440de9501cc..7fed43a1e7bcf35c4d7fd3224837a47fedd59860 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java +@@ -13,15 +13,15 @@ import java.util.NoSuchElementException; + */ + public final class EntityList implements Iterable { + +- protected final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); ++ private final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); + { + this.entityToIndex.defaultReturnValue(Integer.MIN_VALUE); + } + +- protected static final Entity[] EMPTY_LIST = new Entity[0]; ++ private static final Entity[] EMPTY_LIST = new Entity[0]; + +- protected Entity[] entities = EMPTY_LIST; +- protected int count; ++ private Entity[] entities = EMPTY_LIST; ++ private int count; + + public int size() { + return this.count; +@@ -94,10 +94,9 @@ public final class EntityList implements Iterable { + + @Override + public Iterator iterator() { +- return new Iterator() { +- +- Entity lastRet; +- int current; ++ return new Iterator<>() { ++ private Entity lastRet; ++ private int current; + + @Override + public boolean hasNext() { +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java +deleted file mode 100644 +index fcfbca333234c09f7c056bbfcd9ac8860b20a8db..0000000000000000000000000000000000000000 +--- a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java ++++ /dev/null +@@ -1,125 +0,0 @@ +-package ca.spottedleaf.moonrise.common.list; +- +-import it.unimi.dsi.fastutil.longs.LongIterator; +-import it.unimi.dsi.fastutil.shorts.Short2LongOpenHashMap; +-import java.util.Arrays; +-import net.minecraft.world.level.block.Block; +-import net.minecraft.world.level.block.state.BlockState; +-import net.minecraft.world.level.chunk.GlobalPalette; +- +-public final class IBlockDataList { +- +- private static final GlobalPalette GLOBAL_PALETTE = new GlobalPalette<>(Block.BLOCK_STATE_REGISTRY); +- +- // map of location -> (index | (location << 16) | (palette id << 32)) +- private final Short2LongOpenHashMap map = new Short2LongOpenHashMap(2, 0.8f); +- { +- this.map.defaultReturnValue(Long.MAX_VALUE); +- } +- +- private static final long[] EMPTY_LIST = new long[0]; +- +- private long[] byIndex = EMPTY_LIST; +- private int size; +- +- public static int getLocationKey(final int x, final int y, final int z) { +- return (x & 15) | (((z & 15) << 4)) | ((y & 255) << (4 + 4)); +- } +- +- public static BlockState getBlockDataFromRaw(final long raw) { +- return GLOBAL_PALETTE.valueFor((int)(raw >>> 32)); +- } +- +- public static int getIndexFromRaw(final long raw) { +- return (int)(raw & 0xFFFF); +- } +- +- public static int getLocationFromRaw(final long raw) { +- return (int)((raw >>> 16) & 0xFFFF); +- } +- +- public static long getRawFromValues(final int index, final int location, final BlockState data) { +- return (long)index | ((long)location << 16) | (((long)GLOBAL_PALETTE.idFor(data)) << 32); +- } +- +- public static long setIndexRawValues(final long value, final int index) { +- return value & ~(0xFFFF) | (index); +- } +- +- public long add(final int x, final int y, final int z, final BlockState data) { +- return this.add(getLocationKey(x, y, z), data); +- } +- +- public long add(final int location, final BlockState data) { +- final long curr = this.map.get((short)location); +- +- if (curr == Long.MAX_VALUE) { +- final int index = this.size++; +- final long raw = getRawFromValues(index, location, data); +- this.map.put((short)location, raw); +- +- if (index >= this.byIndex.length) { +- this.byIndex = Arrays.copyOf(this.byIndex, (int)Math.max(4L, this.byIndex.length * 2L)); +- } +- +- this.byIndex[index] = raw; +- return raw; +- } else { +- final int index = getIndexFromRaw(curr); +- final long raw = this.byIndex[index] = getRawFromValues(index, location, data); +- +- this.map.put((short)location, raw); +- +- return raw; +- } +- } +- +- public long remove(final int x, final int y, final int z) { +- return this.remove(getLocationKey(x, y, z)); +- } +- +- public long remove(final int location) { +- final long ret = this.map.remove((short)location); +- final int index = getIndexFromRaw(ret); +- if (ret == Long.MAX_VALUE) { +- return ret; +- } +- +- // move the entry at the end to this index +- final int endIndex = --this.size; +- final long end = this.byIndex[endIndex]; +- if (index != endIndex) { +- // not empty after this call +- this.map.put((short)getLocationFromRaw(end), setIndexRawValues(end, index)); +- } +- this.byIndex[index] = end; +- this.byIndex[endIndex] = 0L; +- +- return ret; +- } +- +- public int size() { +- return this.size; +- } +- +- public long getRaw(final int index) { +- return this.byIndex[index]; +- } +- +- public int getLocation(final int index) { +- return getLocationFromRaw(this.getRaw(index)); +- } +- +- public BlockState getData(final int index) { +- return getBlockDataFromRaw(this.getRaw(index)); +- } +- +- public void clear() { +- this.size = 0; +- this.map.clear(); +- } +- +- public LongIterator getRawIterator() { +- return this.map.values().iterator(); +- } +-} +\ No newline at end of file +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9f3b25bb2439f283f878db93973a02fcdcd14eed +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java +@@ -0,0 +1,77 @@ ++package ca.spottedleaf.moonrise.common.list; ++ ++import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; ++import java.util.Arrays; ++ ++public final class IntList { ++ ++ private final Int2IntOpenHashMap map = new Int2IntOpenHashMap(); ++ { ++ this.map.defaultReturnValue(Integer.MIN_VALUE); ++ } ++ ++ private static final int[] EMPTY_LIST = new int[0]; ++ ++ private int[] byIndex = EMPTY_LIST; ++ private int count; ++ ++ public int size() { ++ return this.count; ++ } ++ ++ public void setMinCapacity(final int len) { ++ final int[] byIndex = this.byIndex; ++ if (byIndex.length < len) { ++ this.byIndex = Arrays.copyOf(byIndex, len); ++ } ++ } ++ ++ public int getRaw(final int index) { ++ return this.byIndex[index]; ++ } ++ ++ public boolean add(final int value) { ++ final int count = this.count; ++ final int currIndex = this.map.putIfAbsent(value, count); ++ ++ if (currIndex != Integer.MIN_VALUE) { ++ return false; // already in this list ++ } ++ ++ int[] list = this.byIndex; ++ ++ if (list.length == count) { ++ // resize required ++ list = this.byIndex = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative ++ } ++ ++ list[count] = value; ++ this.count = count + 1; ++ ++ return true; ++ } ++ ++ public boolean remove(final int value) { ++ final int index = this.map.remove(value); ++ if (index == Integer.MIN_VALUE) { ++ return false; ++ } ++ ++ // move the entry at the end to this index ++ final int endIndex = --this.count; ++ final int end = this.byIndex[endIndex]; ++ if (index != endIndex) { ++ // not empty after this call ++ this.map.put(end, index); ++ } ++ this.byIndex[index] = end; ++ this.byIndex[endIndex] = 0; ++ ++ return true; ++ } ++ ++ public void clear() { ++ this.count = 0; ++ this.map.clear(); ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2bae9949ef325d0001aa638150fbbdf968367e75 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java +@@ -0,0 +1,77 @@ ++package ca.spottedleaf.moonrise.common.list; ++ ++import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap; ++import java.util.Arrays; ++ ++public final class ShortList { ++ ++ private final Short2ShortOpenHashMap map = new Short2ShortOpenHashMap(); ++ { ++ this.map.defaultReturnValue(Short.MIN_VALUE); ++ } ++ ++ private static final short[] EMPTY_LIST = new short[0]; ++ ++ private short[] byIndex = EMPTY_LIST; ++ private short count; ++ ++ public int size() { ++ return (int)this.count; ++ } ++ ++ public short getRaw(final int index) { ++ return this.byIndex[index]; ++ } ++ ++ public void setMinCapacity(final int len) { ++ final short[] byIndex = this.byIndex; ++ if (byIndex.length < len) { ++ this.byIndex = Arrays.copyOf(byIndex, len); ++ } ++ } ++ ++ public boolean add(final short value) { ++ final int count = (int)this.count; ++ final short currIndex = this.map.putIfAbsent(value, (short)count); ++ ++ if (currIndex != Short.MIN_VALUE) { ++ return false; // already in this list ++ } ++ ++ short[] list = this.byIndex; ++ ++ if (list.length == count) { ++ // resize required ++ list = this.byIndex = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative ++ } ++ ++ list[count] = value; ++ this.count = (short)(count + 1); ++ ++ return true; ++ } ++ ++ public boolean remove(final short value) { ++ final short index = this.map.remove(value); ++ if (index == Short.MIN_VALUE) { ++ return false; ++ } ++ ++ // move the entry at the end to this index ++ final short endIndex = --this.count; ++ final short end = this.byIndex[endIndex]; ++ if (index != endIndex) { ++ // not empty after this call ++ this.map.put(end, index); ++ } ++ this.byIndex[(int)index] = end; ++ this.byIndex[(int)endIndex] = (short)0; ++ ++ return true; ++ } ++ ++ public void clear() { ++ this.count = (short)0; ++ this.map.clear(); ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c2d917c2eac55b8a4411a6e159f177f9428b1150 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java +@@ -0,0 +1,22 @@ ++package ca.spottedleaf.moonrise.common.misc; ++ ++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import java.lang.invoke.VarHandle; ++ ++public final class LazyRunnable implements Runnable { ++ ++ private volatile Runnable toRun; ++ private static final VarHandle TO_RUN_HANDLE = ConcurrentUtil.getVarHandle(LazyRunnable.class, "toRun", Runnable.class); ++ ++ public void setRunnable(final Runnable run) { ++ final Runnable prev = (Runnable)TO_RUN_HANDLE.compareAndExchange(this, (Runnable)null, run); ++ if (prev != null) { ++ throw new IllegalStateException("Runnable already set"); ++ } ++ } ++ ++ @Override ++ public void run() { ++ ((Runnable)TO_RUN_HANDLE.getVolatile(this)).run(); ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java +index ab093b0e8ac6f762921eb1d15f5217345c4eba05..bb44de17a37082e57f2292a4f470740be1d09b11 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java +@@ -4,13 +4,17 @@ import ca.spottedleaf.moonrise.common.list.ReferenceList; + import ca.spottedleaf.moonrise.common.util.CoordinateUtils; + import ca.spottedleaf.moonrise.common.util.MoonriseConstants; + import ca.spottedleaf.moonrise.common.util.ChunkSystem; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; + import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants; ++import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel; + import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; + import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; import net.minecraft.core.BlockPos; - import net.minecraft.nbt.CompoundTag; -@@ -7,7 +8,6 @@ import net.minecraft.server.level.ChunkHolder; - import net.minecraft.server.level.GenerationChunkHolder; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; --import net.minecraft.util.datafix.DataFixTypes; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.ChunkPos; -@@ -88,7 +88,7 @@ public interface PlatformHooks { - // support for CB chunk mustNotSave - public boolean forceNoSave(final ChunkAccess chunk); ++import java.util.ArrayList; -- public CompoundTag convertNBT(final DataFixTypes type, final DataFixer dataFixer, final CompoundTag nbt, -+ public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt, - final int fromVersion, final int toVersion); + public final class NearbyPlayers { + +@@ -20,7 +24,27 @@ public final class NearbyPlayers { + GENERAL_REALLY_SMALL, + TICK_VIEW_DISTANCE, + VIEW_DISTANCE, +- SPAWN_RANGE, // Moonrise - chunk tick iteration ++ // Moonrise start - chunk tick iteration ++ SPAWN_RANGE { ++ @Override ++ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ((ChunkTickServerLevel)world).moonrise$addPlayerTickingRequest(chunkX, chunkZ); ++ } ++ ++ @Override ++ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ((ChunkTickServerLevel)world).moonrise$removePlayerTickingRequest(chunkX, chunkZ); ++ } ++ }; ++ // Moonrise end - chunk tick iteration ++ ++ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ++ } ++ ++ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ++ } + } - public boolean hasMainChunkLoadHook(); -@@ -99,6 +99,8 @@ public interface PlatformHooks { + private static final NearbyMapType[] MAP_TYPES = NearbyMapType.values(); +@@ -37,6 +61,12 @@ public final class NearbyPlayers { + private final ServerLevel world; + private final Reference2ReferenceOpenHashMap players = new Reference2ReferenceOpenHashMap<>(); + private final Long2ReferenceOpenHashMap byChunk = new Long2ReferenceOpenHashMap<>(); ++ private final Long2ReferenceOpenHashMap>[] directByChunk = new Long2ReferenceOpenHashMap[TOTAL_MAP_TYPES]; ++ { ++ for (int i = 0; i < this.directByChunk.length; ++i) { ++ this.directByChunk[i] = new Long2ReferenceOpenHashMap<>(); ++ } ++ } - public void unloadEntity(final Entity entity); + public NearbyPlayers(final ServerLevel world) { + this.world = world; +@@ -70,6 +100,16 @@ public final class NearbyPlayers { + } + } -+ public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk); ++ public void clear() { ++ if (this.players.isEmpty()) { ++ return; ++ } ++ ++ for (final ServerPlayer player : new ArrayList<>(this.players.keySet())) { ++ this.removePlayer(player); ++ } ++ } ++ + public void tickPlayer(final ServerPlayer player) { + final TrackedPlayer[] players = this.players.get(player); + if (players == null) { +@@ -94,38 +134,41 @@ public final class NearbyPlayers { + return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); + } + +- public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { +- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); ++ public TrackedChunk getChunk(final int chunkX, final int chunkZ) { ++ return this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ } + +- return chunk == null ? null : chunk.players[type.ordinal()]; ++ public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); + } + + public ReferenceList getPlayers(final ChunkPos pos, final NearbyMapType type) { +- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); +- +- return chunk == null ? null : chunk.players[type.ordinal()]; ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); + } + + public ReferenceList getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) { +- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); +- +- return chunk == null ? null : chunk.players[type.ordinal()]; ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + } + + public ReferenceList getPlayersByBlock(final int blockX, final int blockZ, final NearbyMapType type) { +- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); +- +- return chunk == null ? null : chunk.players[type.ordinal()]; ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); + } + + public static final class TrackedChunk { + + private static final ServerPlayer[] EMPTY_PLAYERS_ARRAY = new ServerPlayer[0]; + ++ private final long chunkKey; ++ private final NearbyPlayers nearbyPlayers; + private final ReferenceList[] players = new ReferenceList[TOTAL_MAP_TYPES]; + private int nonEmptyLists; + private long updateCount; + ++ public TrackedChunk(final long chunkKey, final NearbyPlayers nearbyPlayers) { ++ this.chunkKey = chunkKey; ++ this.nearbyPlayers = nearbyPlayers; ++ } ++ + public boolean isEmpty() { + return this.nonEmptyLists == 0; + } +@@ -145,7 +188,9 @@ public final class NearbyPlayers { + final ReferenceList list = this.players[idx]; + if (list == null) { + ++this.nonEmptyLists; +- (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)).add(player); ++ final ReferenceList players = (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)); ++ this.nearbyPlayers.directByChunk[idx].put(this.chunkKey, players); ++ players.add(player); + return; + } + +@@ -169,6 +214,7 @@ public final class NearbyPlayers { + + if (list.size() == 0) { + this.players[idx] = null; ++ this.nearbyPlayers.directByChunk[idx].remove(this.chunkKey); + --this.nonEmptyLists; + } + } +@@ -187,9 +233,19 @@ public final class NearbyPlayers { + protected void addCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { + final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); + +- NearbyPlayers.this.byChunk.computeIfAbsent(chunkKey, (final long keyInMap) -> { +- return new TrackedChunk(); +- }).addPlayer(parameter, this.type); ++ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey); ++ final NearbyMapType type = this.type; ++ if (chunk != null) { ++ chunk.addPlayer(parameter, type); ++ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); ++ } else { ++ final TrackedChunk created = new TrackedChunk(chunkKey, NearbyPlayers.this); ++ NearbyPlayers.this.byChunk.put(chunkKey, created); ++ created.addPlayer(parameter, type); ++ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); ++ ++ ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$requestChunkData(chunkKey).nearbyPlayers = created; ++ } + } + + @Override +@@ -201,10 +257,16 @@ public final class NearbyPlayers { + throw new IllegalStateException("Chunk should exist at " + new ChunkPos(chunkKey)); + } + +- chunk.removePlayer(parameter, this.type); ++ final NearbyMapType type = this.type; ++ chunk.removePlayer(parameter, type); ++ type.removeFrom(parameter, NearbyPlayers.this.world, chunkX, chunkZ); + + if (chunk.isEmpty()) { + NearbyPlayers.this.byChunk.remove(chunkKey); ++ final ChunkData chunkData = ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$releaseChunkData(chunkKey); ++ if (chunkData != null) { ++ chunkData.nearbyPlayers = null; ++ } + } + } + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java +index da323a1105347d5cf4b946df10ded78a953236f2..94bba2b71918d79f54b3e28c35e76098ba0afd8c 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java +@@ -1,6 +1,7 @@ + package ca.spottedleaf.moonrise.common.util; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.PlatformHooks; + import com.mojang.logging.LogUtils; + import net.minecraft.server.level.ChunkHolder; + import net.minecraft.server.level.FullChunkStatus; +@@ -24,15 +25,15 @@ public final class ChunkSystem { + } + + public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) { +- scheduleChunkTask(level, chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); ++ scheduleChunkTask(level, chunkX, chunkZ, run, Priority.NORMAL); + } + +- public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) { ++ public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final 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 ChunkStatus toStatus, final boolean addTicket, final Priority priority, + final Consumer onComplete) { + if (gen) { + scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); +@@ -59,7 +60,7 @@ public final class ChunkSystem { + + 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 onComplete) { ++ final boolean addTicket, final Priority priority, final Consumer onComplete) { + if (!org.bukkit.Bukkit.isPrimaryThread()) { + scheduleChunkTask(level, chunkX, chunkZ, () -> { + scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); +@@ -113,13 +114,13 @@ public final class ChunkSystem { + } + loadCallback.accept(result.orElse(null)); + }, (final Runnable r) -> { +- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); ++ scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST); + }); + } + + public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ, + final FullChunkStatus toStatus, final boolean addTicket, +- final PrioritisedExecutor.Priority priority, final Consumer onComplete) { ++ final Priority priority, final Consumer onComplete) { + // This method goes unused until the chunk system rewrite + if (toStatus == FullChunkStatus.INACCESSIBLE) { + throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status"); +@@ -196,7 +197,7 @@ public final class ChunkSystem { + } + loadCallback.accept(result.orElse(null)); + }, (final Runnable r) -> { +- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); ++ scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST); + }); + } + +@@ -220,7 +221,10 @@ public final class ChunkSystem { + return getUpdatingChunkHolderCount(level) != 0; + } + +- public static boolean screenEntity(final ServerLevel level, final Entity entity) { ++ public static boolean screenEntity(final ServerLevel level, final Entity entity, final boolean fromDisk, final boolean event) { ++ if (!PlatformHooks.get().screenEntity(level, entity, fromDisk, event)) { ++ return false; ++ } + return true; + } + +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java +index ac6f284ee4469d16c5655328b2488d7612832353..97848869df61648fc415e4d39f409f433202c274 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java +@@ -3,8 +3,12 @@ package ca.spottedleaf.moonrise.common.util; + public final class MixinWorkarounds { + + // mixins tries to find the owner of the clone() method, which doesn't exist and NPEs ++ // https://github.com/FabricMC/Mixin/pull/147 + public static long[] clone(final long[] values) { + return values.clone(); + } + ++ public static byte[] clone(final byte[] values) { ++ return values.clone(); ++ } + } +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java +index 3abe0bd2a820352b85306d554bf14a4cf6123091..c125c70a68130be373acc989053a6c0e487be924 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java +@@ -1,45 +1,100 @@ + package ca.spottedleaf.moonrise.common.util; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool; ++import ca.spottedleaf.concurrentutil.executor.thread.PrioritisedThreadPool; ++import ca.spottedleaf.moonrise.common.PlatformHooks; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; +-import java.io.File; ++import java.util.concurrent.TimeUnit; ++import java.util.concurrent.atomic.AtomicInteger; ++import java.util.function.Consumer; + + public final class MoonriseCommon { + + private static final Logger LOGGER = LoggerFactory.getLogger(MoonriseCommon.class); + +- // Paper start +- public static PrioritisedThreadPool WORKER_POOL; +- public static int WORKER_THREADS; +- public static void init(io.papermc.paper.configuration.GlobalConfiguration.ChunkSystem chunkSystem) { +- // Paper end ++ public static final PrioritisedThreadPool WORKER_POOL = new PrioritisedThreadPool( ++ new Consumer<>() { ++ private final AtomicInteger idGenerator = new AtomicInteger(); ++ ++ @Override ++ public void accept(Thread thread) { ++ thread.setDaemon(true); ++ thread.setName(PlatformHooks.get().getBrand() + " Common Worker #" + this.idGenerator.getAndIncrement()); ++ thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { ++ @Override ++ public void uncaughtException(final Thread thread, final Throwable throwable) { ++ LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); ++ } ++ }); ++ } ++ } ++ ); ++ public static final long WORKER_QUEUE_HOLD_TIME = (long)(20.0e6); // 20ms ++ public static final int CLIENT_DIVISION = 0; ++ public static final PrioritisedThreadPool.ExecutorGroup RENDER_EXECUTOR_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(CLIENT_DIVISION, 0); ++ public static final int SERVER_DIVISION = 1; ++ public static final PrioritisedThreadPool.ExecutorGroup PARALLEL_GEN_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); ++ public static final PrioritisedThreadPool.ExecutorGroup RADIUS_AWARE_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); ++ public static final PrioritisedThreadPool.ExecutorGroup LOAD_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); ++ ++ public static void adjustWorkerThreads(final int configWorkerThreads, final int configIoThreads) { + int defaultWorkerThreads = Runtime.getRuntime().availableProcessors() / 2; + if (defaultWorkerThreads <= 4) { + defaultWorkerThreads = defaultWorkerThreads <= 3 ? 1 : 2; + } else { + defaultWorkerThreads = defaultWorkerThreads / 2; + } +- defaultWorkerThreads = Integer.getInteger("Paper.WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); // Paper ++ defaultWorkerThreads = Integer.getInteger(PlatformHooks.get().getBrand() + ".WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); + +- int workerThreads = chunkSystem.workerThreads; // Paper ++ int workerThreads = configWorkerThreads; + + if (workerThreads <= 0) { + workerThreads = defaultWorkerThreads; + } + +- WORKER_POOL = new PrioritisedThreadPool( +- "Paper Worker Pool", workerThreads, // Paper +- (final Thread thread, final Integer id) -> { +- thread.setName("Paper Common Worker #" + id.intValue()); // Paper ++ final int ioThreads = Math.max(1, configIoThreads); ++ ++ WORKER_POOL.adjustThreadCount(workerThreads); ++ IO_POOL.adjustThreadCount(ioThreads); ++ ++ LOGGER.info(PlatformHooks.get().getBrand() + " is using " + workerThreads + " worker threads, " + ioThreads + " I/O threads"); ++ } ++ ++ public static final PrioritisedThreadPool IO_POOL = new PrioritisedThreadPool( ++ new Consumer<>() { ++ private final AtomicInteger idGenerator = new AtomicInteger(); ++ ++ @Override ++ public void accept(final Thread thread) { ++ thread.setDaemon(true); ++ thread.setName(PlatformHooks.get().getBrand() + " I/O Worker #" + this.idGenerator.getAndIncrement()); + thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(final Thread thread, final Throwable throwable) { + LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); + } + }); +- }, (long)(20.0e6)); // 20ms +- WORKER_THREADS = workerThreads; ++ } ++ } ++ ); ++ public static final long IO_QUEUE_HOLD_TIME = (long)(100.0e6); // 100ms ++ public static final PrioritisedThreadPool.ExecutorGroup CLIENT_PROFILER_IO_GROUP = IO_POOL.createExecutorGroup(CLIENT_DIVISION, 0); ++ public static final PrioritisedThreadPool.ExecutorGroup SERVER_REGION_IO_GROUP = IO_POOL.createExecutorGroup(SERVER_DIVISION, 0); ++ ++ public static void haltExecutors() { ++ MoonriseCommon.WORKER_POOL.shutdown(false); ++ LOGGER.info("Awaiting termination of worker pool for up to 60s..."); ++ if (!MoonriseCommon.WORKER_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { ++ LOGGER.error("Worker pool did not shut down in time!"); ++ MoonriseCommon.WORKER_POOL.halt(false); ++ } + - public int modifyEntityTrackingRange(final Entity entity, final int currentRange); ++ MoonriseCommon.IO_POOL.shutdown(false); ++ LOGGER.info("Awaiting termination of I/O pool for up to 60s..."); ++ if (!MoonriseCommon.IO_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { ++ LOGGER.error("I/O pool did not shut down in time!"); ++ MoonriseCommon.IO_POOL.halt(false); ++ } + } + + private MoonriseCommon() {} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java +index 1cf32d7d1bbc8a0a3f7cb9024c793f6744199f64..559c959aff3c9deef867b9e425fba3e2e669cac6 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java +@@ -1,8 +1,10 @@ + package ca.spottedleaf.moonrise.common.util; + ++import ca.spottedleaf.moonrise.common.PlatformHooks; ++ + public final class MoonriseConstants { + +- public static final int MAX_VIEW_DISTANCE = 32; ++ public static final int MAX_VIEW_DISTANCE = Integer.getInteger(PlatformHooks.get().getBrand() + ".MaxViewDistance", 32); + + private MoonriseConstants() {} - public static final class Holder { +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java b/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a9ff1c1a70faf4b7a64b265932f07a8b8f00c1ff +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java +@@ -0,0 +1,52 @@ ++package ca.spottedleaf.moonrise.common.util; ++ ++import net.minecraft.world.level.levelgen.LegacyRandomSource; ++ ++/** ++ * Avoid costly CAS of superclass ++ */ ++public final class SimpleRandom extends LegacyRandomSource { ++ ++ private static final long MULTIPLIER = 25214903917L; ++ private static final long ADDEND = 11L; ++ private static final int BITS = 48; ++ private static final long MASK = (1L << BITS) - 1; ++ ++ private long value; ++ ++ public SimpleRandom(final long seed) { ++ super(0L); ++ this.value = seed; ++ } ++ ++ @Override ++ public void setSeed(final long seed) { ++ this.value = (seed ^ MULTIPLIER) & MASK; ++ } ++ ++ private long advanceSeed() { ++ return this.value = ((this.value * MULTIPLIER) + ADDEND) & MASK; ++ } ++ ++ @Override ++ public int next(final int bits) { ++ return (int)(this.advanceSeed() >>> (BITS - bits)); ++ } ++ ++ @Override ++ public int nextInt() { ++ final long seed = this.advanceSeed(); ++ return (int)(seed >>> (BITS - Integer.SIZE)); ++ } ++ ++ @Override ++ public int nextInt(final int bound) { ++ if (bound <= 0) { ++ throw new IllegalArgumentException(); ++ } ++ ++ // https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ ++ final long value = this.advanceSeed() >>> (BITS - Integer.SIZE); ++ return (int)((value * (long)bound) >>> Integer.SIZE); ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java +index 11b7f15755dde766140c29bedca456c80d53293f..217d1f908a36a5177ba3cbb80a33f73d4dab0fa0 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java +@@ -77,11 +77,15 @@ public class TickThread extends Thread { + } + + public TickThread(final Runnable run, final String name) { +- this(run, name, ID_GENERATOR.incrementAndGet()); ++ this(null, run, name); + } + +- private TickThread(final Runnable run, final String name, final int id) { +- super(run, name); ++ public TickThread(final ThreadGroup group, final Runnable run, final String name) { ++ this(group, run, name, ID_GENERATOR.incrementAndGet()); ++ } ++ ++ private TickThread(final ThreadGroup group, final Runnable run, final String name, final int id) { ++ super(group, run, name); + this.id = id; + } + +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java +index af9623240ff2d389aa7090623f507720e7dbab7d..efda2688ae1254a82ba7f6bf8bf597ef224cbb86 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java +@@ -8,11 +8,19 @@ public final class WorldUtil { + // min, max are inclusive + + public static int getMaxSection(final LevelHeightAccessor world) { +- return world.getMaxSection() - 1; // getMaxSection() is exclusive ++ return world.getMaxSectionY(); ++ } ++ ++ public static int getMaxSection(final Level world) { ++ return world.getMaxSectionY(); + } + + public static int getMinSection(final LevelHeightAccessor world) { +- return world.getMinSection(); ++ return world.getMinSectionY(); ++ } ++ ++ public static int getMinSection(final Level world) { ++ return world.getMinSectionY(); + } + + public static int getMaxLightSection(final LevelHeightAccessor world) { diff --git a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java -index 6f2dc0900dbf13a02410682eecda56cea4481346..ee514a767f69de69d86e1e88d70fe37c4ab84277 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ee514a767f69de69d86e1e88d70fe37c4ab84277 +--- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java -@@ -1,14 +1,16 @@ - package ca.spottedleaf.moonrise.paper; - - import ca.spottedleaf.moonrise.common.PlatformHooks; +@@ -0,0 +1,209 @@ ++package ca.spottedleaf.moonrise.paper; ++ ++import ca.spottedleaf.moonrise.common.PlatformHooks; +import com.mojang.datafixers.DSL; - import com.mojang.datafixers.DataFixer; ++import com.mojang.datafixers.DataFixer; +import com.mojang.serialization.Dynamic; - import net.minecraft.core.BlockPos; - import net.minecraft.nbt.CompoundTag; ++import net.minecraft.core.BlockPos; ++import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; - import net.minecraft.server.level.ChunkHolder; - import net.minecraft.server.level.GenerationChunkHolder; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.server.level.ServerPlayer; --import net.minecraft.util.datafix.DataFixTypes; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.level.BlockGetter; - import net.minecraft.world.level.ChunkPos; -@@ -168,8 +170,11 @@ public final class PaperHooks implements PlatformHooks { - } - - @Override -- public CompoundTag convertNBT(final DataFixTypes type, final DataFixer dataFixer, final CompoundTag nbt, final int fromVersion, final int toVersion) { -- return type.update(dataFixer, nbt, fromVersion, toVersion); ++import net.minecraft.server.level.ChunkHolder; ++import net.minecraft.server.level.GenerationChunkHolder; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.level.BlockGetter; ++import net.minecraft.world.level.ChunkPos; ++import net.minecraft.world.level.Level; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.chunk.ChunkAccess; ++import net.minecraft.world.level.chunk.LevelChunk; ++import net.minecraft.world.level.chunk.ProtoChunk; ++import net.minecraft.world.level.chunk.storage.SerializableChunkData; ++import net.minecraft.world.level.entity.EntityTypeTest; ++import net.minecraft.world.phys.AABB; ++import java.util.List; ++import java.util.function.Predicate; ++ ++public final class PaperHooks implements PlatformHooks { ++ ++ @Override ++ public String getBrand() { ++ return "Paper"; ++ } ++ ++ @Override ++ public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos) { ++ return blockState.getLightEmission(); ++ } ++ ++ @Override ++ public Predicate maybeHasLightEmission() { ++ return (final BlockState state) -> { ++ return state.getLightEmission() != 0; ++ }; ++ } ++ ++ @Override ++ public boolean hasCurrentlyLoadingChunk() { ++ return false; ++ } ++ ++ @Override ++ public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder) { ++ return null; ++ } ++ ++ @Override ++ public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk) { ++ ++ } ++ ++ @Override ++ public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original) { ++ ++ } ++ ++ @Override ++ public boolean allowAsyncTicketUpdates() { ++ return true; ++ } ++ ++ @Override ++ public void onChunkHolderTicketChange(final ServerLevel world, final ChunkHolder holder, final int oldLevel, final int newLevel) { ++ ++ } ++ ++ @Override ++ public void chunkUnloadFromWorld(final LevelChunk chunk) { ++ ++ } ++ ++ @Override ++ public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data) { ++ ++ } ++ ++ @Override ++ public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player) { ++ ++ } ++ ++ @Override ++ public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player) { ++ ++ } ++ ++ @Override ++ public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate predicate, final List into) { ++ ++ } ++ ++ @Override ++ public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, final AABB boundingBox, final Predicate predicate, final List into, final int maxCount) { ++ ++ } ++ ++ @Override ++ public void entityMove(final Entity entity, final long oldSection, final long newSection) { ++ ++ } ++ ++ @Override ++ public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event) { ++ return true; ++ } ++ ++ @Override ++ public boolean configFixMC224294() { ++ return true; ++ } ++ ++ @Override ++ public boolean configAutoConfigSendDistance() { ++ ++ } ++ ++ @Override ++ public double configPlayerMaxLoadRate() { ++ ++ } ++ ++ @Override ++ public double configPlayerMaxGenRate() { ++ ++ } ++ ++ @Override ++ public double configPlayerMaxSendRate() { ++ ++ } ++ ++ @Override ++ public int configPlayerMaxConcurrentLoads() { ++ ++ } ++ ++ @Override ++ public int configPlayerMaxConcurrentGens() { ++ ++ } ++ ++ @Override ++ public long configAutoSaveInterval() { ++ ++ } ++ ++ @Override ++ public int configMaxAutoSavePerTick() { ++ ++ } ++ ++ @Override ++ public boolean configFixMC159283() { ++ return true; ++ } ++ ++ @Override ++ public boolean forceNoSave(final ChunkAccess chunk) { ++ return chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave; ++ } ++ ++ @Override + public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt, + final int fromVersion, final int toVersion) { + return (CompoundTag)dataFixer.update( + type, new Dynamic<>(NbtOps.INSTANCE, nbt), fromVersion, toVersion + ).getValue(); - } - - @Override -@@ -192,6 +197,11 @@ public final class PaperHooks implements PlatformHooks { - entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, org.bukkit.event.entity.EntityRemoveEvent.Cause.UNLOAD); - } - ++ } ++ ++ @Override ++ public boolean hasMainChunkLoadHook() { ++ return false; ++ } ++ ++ @Override ++ public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData) { ++ ++ } ++ ++ @Override ++ public List modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List entities) { ++ return entities; ++ } ++ ++ @Override ++ public void unloadEntity(final Entity entity) { ++ entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, org.bukkit.event.entity.EntityRemoveEvent.Cause.UNLOAD); ++ } ++ + @Override + public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) { + net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities()); + } + - @Override - public int modifyEntityTrackingRange(final Entity entity, final int currentRange) { - return org.spigotmc.TrackingRange.getEntityTrackingRange(entity, currentRange); ++ @Override ++ public int modifyEntityTrackingRange(final Entity entity, final int currentRange) { ++ return org.spigotmc.TrackingRange.getEntityTrackingRange(entity, currentRange); ++ } ++} +diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +index 61893f8216ddaedd899b573322f3ad0088074ac5..36b96e0ed5c0d25068ec4678eddd8a19a020d345 100644 +--- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java ++++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +@@ -242,7 +242,7 @@ public class GlobalConfiguration extends ConfigurationPart { + + @PostProcess + private void postProcess() { +- ++ ca.spottedleaf.moonrise.common.util.MoonriseCommon.adjustWorkerThreads(this.workerThreads, this.ioThreads); + } + } + diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java index f18c2b85ed9541f646f157184221e333d0ae58bd..aff4c3d63a97d5bbde004a616f7e14fca59b5ab9 100644 --- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java @@ -103,15 +1266,36 @@ index f18c2b85ed9541f646f157184221e333d0ae58bd..aff4c3d63a97d5bbde004a616f7e14fc // CraftBukkit start - these are spawned serialized (DefinedStructure) and we don't call an add event below at the moment due to ordering complexities world.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(entities, world, EntitySpawnReason.LOAD).filter((entity) -> { 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 3eb38271b6ca26099b2da04c2d969e32fd72b2af..5aa74c00a61282830d82359eae2b114e2a48b6d9 100644 +index 6baa313b8201ed23193d7885c85606b0899ade3c..5aa74c00a61282830d82359eae2b114e2a48b6d9 100644 --- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java +++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java -@@ -97,7 +97,7 @@ public class PersistentEntitySectionManager implements A - // I don't want to know why this is a generic type. - Entity entityCasted = (Entity)entity; - boolean wasRemoved = entityCasted.isRemoved(); -- boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted, existing, false); +@@ -94,15 +94,13 @@ public class PersistentEntitySectionManager implements A + private boolean addEntity(T entity, boolean existing) { + org.spigotmc.AsyncCatcher.catchOp("Entity add"); // Paper + // 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(); +- boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted); +- if ((!wasRemoved && entityCasted.isRemoved()) || !screened) { +- // removed by callback +- return false; +- } ++ // I don't want to know why this is a generic type. ++ Entity entityCasted = (Entity)entity; ++ boolean wasRemoved = entityCasted.isRemoved(); + boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted, existing, true); - if ((!wasRemoved && entityCasted.isRemoved()) || !screened) { - // removed by callback - return false; ++ if ((!wasRemoved && entityCasted.isRemoved()) || !screened) { ++ // removed by callback ++ return false; + } + // Paper end - chunk system hooks + if (!this.addEntityUuid(entity)) { +diff --git a/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks b/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks +new file mode 100644 +index 0000000000000000000000000000000000000000..e57c3ca79677b1dfe7cf3db36f0406de7ea5bd0a +--- /dev/null ++++ b/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks +@@ -0,0 +1 @@ ++ca.spottedleaf.moonrise.paper.PaperHooks diff --git a/patches/server/0825-Rewrite-dataconverter-system.patch b/patches/server/0824-Rewrite-dataconverter-system.patch similarity index 100% rename from patches/server/0825-Rewrite-dataconverter-system.patch rename to patches/server/0824-Rewrite-dataconverter-system.patch diff --git a/patches/server/0827-fixup-Optimize-BlockPosition-helper-methods.patch b/patches/server/0825-fixup-Optimize-BlockPosition-helper-methods.patch similarity index 100% rename from patches/server/0827-fixup-Optimize-BlockPosition-helper-methods.patch rename to patches/server/0825-fixup-Optimize-BlockPosition-helper-methods.patch diff --git a/patches/server/0826-Moonrise-optimisation-patches.patch b/patches/server/0826-Moonrise-optimisation-patches.patch index 452ab610f1d5..59a89d72686d 100644 --- a/patches/server/0826-Moonrise-optimisation-patches.patch +++ b/patches/server/0826-Moonrise-optimisation-patches.patch @@ -17,10 +17,10 @@ Currently includes: See https://github.com/Tuinity/Moonrise diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -index 94bba2b71918d79f54b3e28c35e76098ba0afd8c..b61611351bf23efc1e90bab8a850ebbe6ffdd516 100644 +index 94bba2b71918d79f54b3e28c35e76098ba0afd8c..fc029c8fb22a7c8eeb23bfc171812f6da91c60fa 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -@@ -2,6 +2,10 @@ package ca.spottedleaf.moonrise.common.util; +@@ -2,11 +2,17 @@ package ca.spottedleaf.moonrise.common.util; import ca.spottedleaf.concurrentutil.util.Priority; import ca.spottedleaf.moonrise.common.PlatformHooks; @@ -28,10 +28,17 @@ index 94bba2b71918d79f54b3e28c35e76098ba0afd8c..b61611351bf23efc1e90bab8a850ebbe +import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk; +import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader; +import ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemServerChunkCache; ++import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel; import com.mojang.logging.LogUtils; import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.FullChunkStatus; -@@ -18,203 +22,46 @@ import java.util.function.Consumer; + import net.minecraft.server.level.ServerLevel; + import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.server.level.progress.ChunkProgressListener; + import net.minecraft.world.entity.Entity; + import net.minecraft.world.level.chunk.ChunkAccess; + import net.minecraft.world.level.chunk.LevelChunk; +@@ -18,203 +24,46 @@ import java.util.function.Consumer; public final class ChunkSystem { private static final Logger LOGGER = LogUtils.getLogger(); @@ -243,17 +250,26 @@ index 94bba2b71918d79f54b3e28c35e76098ba0afd8c..b61611351bf23efc1e90bab8a850ebbe } public static boolean hasAnyChunkHolders(final ServerLevel level) { -@@ -236,52 +83,85 @@ public final class ChunkSystem { - +@@ -233,55 +82,96 @@ public final class ChunkSystem { } -- public static void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder) { + public static void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder) { ++ // Update progress listener for LevelLoadingScreen ++ final ChunkProgressListener progressListener = level.getChunkSource().chunkMap.progressListener; ++ if (progressListener != null) { ++ ChunkSystem.scheduleChunkTask(level, holder.getPos().x, holder.getPos().z, () -> { ++ progressListener.onStatusChange(holder.getPos(), null); ++ }); ++ } ++ } + + public static void onChunkPreBorder(final LevelChunk chunk, final ChunkHolder holder) { + ((ChunkSystemServerChunkCache)((ServerLevel)chunk.getLevel()).getChunkSource()) + .moonrise$setFullChunk(chunk.getPos().x, chunk.getPos().z, chunk); -+ } + } -+ public static void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder) { + public static void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder) { +- + ((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getLoadedChunks().add( + ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder() + ); @@ -278,10 +294,11 @@ index 94bba2b71918d79f54b3e28c35e76098ba0afd8c..b61611351bf23efc1e90bab8a850ebbe + ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder() + ); + if (!((ChunkSystemLevelChunk)chunk).moonrise$isPostProcessingDone()) { -+ chunk.postProcessGeneration(); ++ chunk.postProcessGeneration((ServerLevel)chunk.getLevel()); + } + ((ServerLevel)chunk.getLevel()).startTickingChunk(chunk); + ((ServerLevel)chunk.getLevel()).getChunkSource().chunkMap.tickingGenerated.incrementAndGet(); ++ ((ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$markChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration } public static void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) { @@ -289,6 +306,7 @@ index 94bba2b71918d79f54b3e28c35e76098ba0afd8c..b61611351bf23efc1e90bab8a850ebbe + ((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getTickingChunks().remove( + ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder() + ); ++ ((ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$removeChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration } public static void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { @@ -361,65 +379,318 @@ index be60439c43b887f0143e7713689fd2773066ba73..dc17aa5a0937c13d431e41779f241f2e @Override diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java new file mode 100644 -index 0000000000000000000000000000000000000000..aef4fc0d3c272febe675d1ac846b88e58b4e7533 +index 0000000000000000000000000000000000000000..93bc56daec4526f373c84763b8c7ccb4a30e800b --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java @@ -0,0 +1,10 @@ +package ca.spottedleaf.moonrise.patches.block_counting; + +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -+import it.unimi.dsi.fastutil.ints.IntArrayList; ++import it.unimi.dsi.fastutil.shorts.ShortArrayList; + +public interface BlockCountingBitStorage { + -+ public Int2ObjectOpenHashMap moonrise$countEntries(); ++ public Int2ObjectOpenHashMap moonrise$countEntries(); + +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java new file mode 100644 -index 0000000000000000000000000000000000000000..a08ddb0598d44368af5b6bace971ee31edf9919e +index 0000000000000000000000000000000000000000..0d1443a113c07d7655e7b927a899447f70db8fa9 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java @@ -0,0 +1,11 @@ +package ca.spottedleaf.moonrise.patches.block_counting; + -+import ca.spottedleaf.moonrise.common.list.IBlockDataList; ++import ca.spottedleaf.moonrise.common.list.ShortList; + +public interface BlockCountingChunkSection { + -+ public int moonrise$getSpecialCollidingBlocks(); ++ public boolean moonrise$hasSpecialCollidingBlocks(); + -+ public IBlockDataList moonrise$getTickingBlockList(); ++ public ShortList moonrise$getTickingBlockList(); + +} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_getblock/GetBlockChunk.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_getblock/GetBlockChunk.java +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccess.java b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccess.java new file mode 100644 -index 0000000000000000000000000000000000000000..08338917dc61c856eaba0b76e05c1497c458399d +index 0000000000000000000000000000000000000000..89e75b454695e174c5619104eeb15eb923a2d9a7 --- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_getblock/GetBlockChunk.java -@@ -0,0 +1,9 @@ -+package ca.spottedleaf.moonrise.patches.chunk_getblock; ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccess.java +@@ -0,0 +1,12 @@ ++package ca.spottedleaf.moonrise.patches.blockstate_propertyaccess; + -+import net.minecraft.world.level.block.state.BlockState; ++public interface PropertyAccess { + -+public interface GetBlockChunk { ++ public int moonrise$getId(); + -+ public BlockState moonrise$getBlock(final int x, final int y, final int z); ++ public int moonrise$getIdFor(final T value); ++ ++ public T moonrise$getById(final int id); ++ ++ public void moonrise$setById(final T[] values); ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccessStateHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccessStateHolder.java +new file mode 100644 +index 0000000000000000000000000000000000000000..01da52b9e8a786824f199a057b62ce0431ecbc43 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccessStateHolder.java +@@ -0,0 +1,7 @@ ++package ca.spottedleaf.moonrise.patches.blockstate_propertyaccess; ++ ++public interface PropertyAccessStateHolder { ++ ++ public long moonrise$getTableIndex(); ++ ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b5335a2a8cb5dc7637c7112c8f7193389d726489 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java +@@ -0,0 +1,230 @@ ++package ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.util; ++ ++import ca.spottedleaf.concurrentutil.util.IntegerUtil; ++import ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess; ++import ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccessStateHolder; ++import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; ++import it.unimi.dsi.fastutil.objects.AbstractObjectSet; ++import it.unimi.dsi.fastutil.objects.AbstractReference2ObjectMap; ++import it.unimi.dsi.fastutil.objects.ObjectIterator; ++import it.unimi.dsi.fastutil.objects.ObjectSet; ++import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; ++import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; ++import java.util.ArrayList; ++import java.util.Collection; ++import java.util.Collections; ++import java.util.Iterator; ++import java.util.List; ++import java.util.Map; ++import net.minecraft.world.level.block.state.StateHolder; ++import net.minecraft.world.level.block.state.properties.Property; ++ ++public final class ZeroCollidingReferenceStateTable { ++ ++ private final Int2ObjectOpenHashMap propertyToIndexer; ++ private S[] lookup; ++ private final Collection> properties; ++ ++ public ZeroCollidingReferenceStateTable(final Collection> properties) { ++ this.propertyToIndexer = new Int2ObjectOpenHashMap<>(properties.size()); ++ this.properties = new ReferenceOpenHashSet<>(properties); ++ ++ final List> sortedProperties = new ArrayList<>(properties); ++ ++ // important that each table sees the same property order given the same _set_ of properties, ++ // as each table will calculate the index for the block state ++ sortedProperties.sort((final Property p1, final Property p2) -> { ++ return Integer.compare( ++ ((PropertyAccess)p1).moonrise$getId(), ++ ((PropertyAccess)p2).moonrise$getId() ++ ); ++ }); ++ ++ int currentMultiple = 1; ++ for (final Property property : sortedProperties) { ++ final int totalValues = property.getPossibleValues().size(); ++ ++ this.propertyToIndexer.put( ++ ((PropertyAccess)property).moonrise$getId(), ++ new Indexer( ++ totalValues, ++ currentMultiple, ++ IntegerUtil.getUnsignedDivisorMagic((long)currentMultiple, 32), ++ IntegerUtil.getUnsignedDivisorMagic((long)totalValues, 32) ++ ) ++ ); ++ ++ currentMultiple *= totalValues; ++ } ++ } ++ ++ public > boolean hasProperty(final Property property) { ++ return this.propertyToIndexer.containsKey(((PropertyAccess)property).moonrise$getId()); ++ } ++ ++ public long getIndex(final StateHolder stateHolder) { ++ long ret = 0L; ++ ++ for (final Map.Entry, Comparable> entry : stateHolder.getValues().entrySet()) { ++ final Property property = entry.getKey(); ++ final Comparable value = entry.getValue(); ++ ++ final Indexer indexer = this.propertyToIndexer.get(((PropertyAccess)property).moonrise$getId()); ++ ++ ret += (((PropertyAccess)property).moonrise$getIdFor(value)) * indexer.multiple; ++ } ++ ++ return ret; ++ } ++ ++ public boolean isLoaded() { ++ return this.lookup != null; ++ } ++ ++ public void loadInTable(final Map, Comparable>, S> universe) { ++ if (this.lookup != null) { ++ throw new IllegalStateException(); ++ } ++ ++ this.lookup = (S[])new StateHolder[universe.size()]; ++ ++ for (final Map.Entry, Comparable>, S> entry : universe.entrySet()) { ++ final S value = entry.getValue(); ++ if (value == null) { ++ continue; ++ } ++ this.lookup[(int)((PropertyAccessStateHolder)(StateHolder)value).moonrise$getTableIndex()] = value; ++ } ++ ++ for (final S value : this.lookup) { ++ if (value == null) { ++ throw new IllegalStateException(); ++ } ++ } ++ } ++ ++ public > T get(final long index, final Property property) { ++ final Indexer indexer = this.propertyToIndexer.get(((PropertyAccess)property).moonrise$getId()); ++ if (indexer == null) { ++ return null; ++ } ++ ++ final long divided = (index * indexer.multipleDivMagic) >>> 32; ++ final long modded = (((divided * indexer.modMagic) & 0xFFFFFFFFL) * indexer.totalValues) >>> 32; ++ // equiv to: divided = index / multiple ++ // modded = divided % totalValues ++ ++ return ((PropertyAccess)property).moonrise$getById((int)modded); ++ } ++ ++ public > S set(final long index, final Property property, final T with) { ++ final int newValueId = ((PropertyAccess)property).moonrise$getIdFor(with); ++ if (newValueId < 0) { ++ return null; ++ } ++ ++ final Indexer indexer = this.propertyToIndexer.get(((PropertyAccess)property).moonrise$getId()); ++ if (indexer == null) { ++ return null; ++ } ++ ++ final long divided = (index * indexer.multipleDivMagic) >>> 32; ++ final long modded = (((divided * indexer.modMagic) & 0xFFFFFFFFL) * indexer.totalValues) >>> 32; ++ // equiv to: divided = index / multiple ++ // modded = divided % totalValues ++ ++ // subtract out the old value, add in the new ++ final long newIndex = (((long)newValueId - modded) * indexer.multiple) + index; ++ ++ return this.lookup[(int)newIndex]; ++ } ++ ++ public > S trySet(final long index, final Property property, final T with, final S dfl) { ++ final Indexer indexer = this.propertyToIndexer.get(((PropertyAccess)property).moonrise$getId()); ++ if (indexer == null) { ++ return dfl; ++ } ++ ++ final int newValueId = ((PropertyAccess)property).moonrise$getIdFor(with); ++ if (newValueId < 0) { ++ return null; ++ } ++ ++ final long divided = (index * indexer.multipleDivMagic) >>> 32; ++ final long modded = (((divided * indexer.modMagic) & 0xFFFFFFFFL) * indexer.totalValues) >>> 32; ++ // equiv to: divided = index / multiple ++ // modded = divided % totalValues ++ ++ // subtract out the old value, add in the new ++ final long newIndex = (((long)newValueId - modded) * indexer.multiple) + index; ++ ++ return this.lookup[(int)newIndex]; ++ } ++ ++ public Collection> getProperties() { ++ return Collections.unmodifiableCollection(this.properties); ++ } ++ ++ public Map, Comparable> getMapView(final long stateIndex) { ++ return new MapView(stateIndex); ++ } ++ ++ private static final record Indexer( ++ int totalValues, int multiple, long multipleDivMagic, long modMagic ++ ) {} ++ ++ private class MapView extends AbstractReference2ObjectMap, Comparable> { ++ private final long stateIndex; ++ private EntrySet entrySet; ++ ++ MapView(final long stateIndex) { ++ this.stateIndex = stateIndex; ++ } ++ ++ @Override ++ public boolean containsKey(final Object key) { ++ return key instanceof Property prop && ZeroCollidingReferenceStateTable.this.hasProperty(prop); ++ } ++ ++ @Override ++ public int size() { ++ return ZeroCollidingReferenceStateTable.this.properties.size(); ++ } ++ ++ @Override ++ public ObjectSet, Comparable>> reference2ObjectEntrySet() { ++ if (this.entrySet == null) ++ this.entrySet = new EntrySet(); ++ return this.entrySet; ++ } ++ ++ @Override ++ public Comparable get(final Object key) { ++ return key instanceof Property prop ? ZeroCollidingReferenceStateTable.this.get(this.stateIndex, prop) : null; ++ } ++ ++ class EntrySet extends AbstractObjectSet, Comparable>> { ++ @Override ++ public ObjectIterator, Comparable>> iterator() { ++ final Iterator> propIterator = ZeroCollidingReferenceStateTable.this.properties.iterator(); ++ return new ObjectIterator<>() { ++ @Override ++ public boolean hasNext() { ++ return propIterator.hasNext(); ++ } ++ ++ @Override ++ public Entry, Comparable> next() { ++ Property prop = propIterator.next(); ++ return new AbstractReference2ObjectMap.BasicEntry<>(prop, ZeroCollidingReferenceStateTable.this.get(MapView.this.stateIndex, prop)); ++ } ++ }; ++ } + ++ @Override ++ public int size() { ++ return ZeroCollidingReferenceStateTable.this.properties.size(); ++ } ++ } ++ } +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java new file mode 100644 -index 0000000000000000000000000000000000000000..49160a30b8e19e5c5ada811fbcae2a05959524f3 +index 0000000000000000000000000000000000000000..44bb25554634af2ec0b2e9b3d9231304d5dff034 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java -@@ -0,0 +1,38 @@ +@@ -0,0 +1,39 @@ +package ca.spottedleaf.moonrise.patches.chunk_system; + ++import ca.spottedleaf.moonrise.common.PlatformHooks; +import net.minecraft.SharedConstants; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import net.minecraft.server.level.ServerLevel; -+import net.minecraft.util.datafix.DataFixTypes; ++import net.minecraft.util.datafix.fixes.References; + +public final class ChunkSystemConverters { + @@ -440,84 +711,26 @@ index 0000000000000000000000000000000000000000..49160a30b8e19e5c5ada811fbcae2a05 + public static CompoundTag convertPoiCompoundTag(final CompoundTag data, final ServerLevel world) { + final int dataVersion = getDataVersion(data, DEFAULT_POI_DATA_VERSION); + -+ return DataFixTypes.POI_CHUNK.update(world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); ++ return PlatformHooks.get().convertNBT(References.POI_CHUNK, world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); + } + + public static CompoundTag convertEntityChunkCompoundTag(final CompoundTag data, final ServerLevel world) { + final int dataVersion = getDataVersion(data, DEFAULT_ENTITY_CHUNK_DATA_VERSION); + -+ return DataFixTypes.ENTITY_CHUNK.update(world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); ++ return PlatformHooks.get().convertNBT(References.ENTITY_CHUNK, world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); + } + + private ChunkSystemConverters() {} +} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemFeatures.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemFeatures.java -new file mode 100644 -index 0000000000000000000000000000000000000000..67f6dd9a4855611cfe242c2e37e90f6d27d4c823 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemFeatures.java -@@ -0,0 +1,36 @@ -+package ca.spottedleaf.moonrise.patches.chunk_system; -+ -+import ca.spottedleaf.moonrise.patches.chunk_system.async_save.AsyncChunkSaveData; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.level.chunk.ChunkAccess; -+ -+public final class ChunkSystemFeatures { -+ -+ public static boolean supportsAsyncChunkSave() { -+ // uncertain how to properly pass AsyncSaveData to ChunkSerializer#write -+ // additionally, there may be mods hooking into the write() call which may not be thread-safe to call -+ return true; -+ } -+ -+ public static AsyncChunkSaveData getAsyncSaveData(final ServerLevel world, final ChunkAccess chunk) { -+ return net.minecraft.world.level.chunk.storage.ChunkSerializer.getAsyncSaveData(world, chunk); -+ } -+ -+ public static CompoundTag saveChunkAsync(final ServerLevel world, final ChunkAccess chunk, final AsyncChunkSaveData asyncSaveData) { -+ return net.minecraft.world.level.chunk.storage.ChunkSerializer.saveChunk(world, chunk, asyncSaveData); -+ } -+ -+ public static boolean forceNoSave(final ChunkAccess chunk) { -+ // support for CB chunk mustNotSave -+ return chunk instanceof net.minecraft.world.level.chunk.LevelChunk levelChunk && levelChunk.mustNotSave; -+ } -+ -+ public static boolean supportsAsyncChunkDeserialization() { -+ // as it stands, the current problem with supporting this in Moonrise is that we are unsure that any mods -+ // hooking into ChunkSerializer#read() are thread-safe to call -+ return true; -+ } -+ -+ private ChunkSystemFeatures() {} -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/async_save/AsyncChunkSaveData.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/async_save/AsyncChunkSaveData.java -new file mode 100644 -index 0000000000000000000000000000000000000000..becd1c6d54ed6c912aee3a9178a970e2751d3694 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/async_save/AsyncChunkSaveData.java -@@ -0,0 +1,11 @@ -+package ca.spottedleaf.moonrise.patches.chunk_system.async_save; -+ -+import net.minecraft.nbt.ListTag; -+import net.minecraft.nbt.Tag; -+ -+public record AsyncChunkSaveData( -+ Tag blockTickList, // non-null if we had to go to the server's tick list -+ Tag fluidTickList, // non-null if we had to go to the server's tick list -+ ListTag blockEntities, -+ long worldTime -+) {} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java new file mode 100644 -index 0000000000000000000000000000000000000000..2c279854bdf214538380fa354e4298ec4bd9ac4e +index 0000000000000000000000000000000000000000..c7da23900228aab3a5673eb5adfada5091140319 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java -@@ -0,0 +1,39 @@ +@@ -0,0 +1,44 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.entity; + ++import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; +import net.minecraft.server.level.FullChunkStatus; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.monster.Shulker; @@ -537,6 +750,10 @@ index 0000000000000000000000000000000000000000..2c279854bdf214538380fa354e4298ec + + public void moonrise$setChunkStatus(final FullChunkStatus status); + ++ public ChunkData moonrise$getChunkData(); ++ ++ public void moonrise$setChunkData(final ChunkData chunkData); ++ + public int moonrise$getSectionX(); + + public void moonrise$setSectionX(final int x); @@ -557,12 +774,13 @@ index 0000000000000000000000000000000000000000..2c279854bdf214538380fa354e4298ec +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java new file mode 100644 -index 0000000000000000000000000000000000000000..73df26b27146bbad2106d57b22dd3c792ed3dd1d +index 0000000000000000000000000000000000000000..a814512fcfb85312474ae2c2c21443843bf57831 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java -@@ -0,0 +1,14 @@ +@@ -0,0 +1,31 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.io; + ++import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.chunk.storage.RegionFile; +import java.io.IOException; + @@ -574,63 +792,71 @@ index 0000000000000000000000000000000000000000..73df26b27146bbad2106d57b22dd3c79 + + public RegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException; + ++ public MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite( ++ final int chunkX, final int chunkZ, final CompoundTag compound ++ ) throws IOException; ++ ++ public void moonrise$finishWrite( ++ final int chunkX, final int chunkZ, final MoonriseRegionFileIO.RegionDataController.WriteData writeData ++ ) throws IOException; ++ ++ public MoonriseRegionFileIO.RegionDataController.ReadData moonrise$readData( ++ final int chunkX, final int chunkZ ++ ) throws IOException; ++ ++ // if the return value is null, then the caller needs to re-try with a new call to readData() ++ public CompoundTag moonrise$finishRead( ++ final int chunkX, final int chunkZ, final MoonriseRegionFileIO.RegionDataController.ReadData readData ++ ) throws IOException; +} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java new file mode 100644 -index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d8da6b215 +index 0000000000000000000000000000000000000000..99f6f3e58b11b8967e6f1c3391c190d9a860ab7f --- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java -@@ -0,0 +1,1240 @@ ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java +@@ -0,0 +1,1707 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.io; + +import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; ++import ca.spottedleaf.concurrentutil.completable.CallbackCompletable; ++import ca.spottedleaf.concurrentutil.completable.Completable; +import ca.spottedleaf.concurrentutil.executor.Cancellable; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedQueueExecutorThread; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadedTaskQueue; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.queue.PrioritisedTaskQueue; +import ca.spottedleaf.concurrentutil.function.BiLong1Function; +import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +import ca.spottedleaf.moonrise.common.util.TickThread; +import ca.spottedleaf.moonrise.common.util.WorldUtil; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; ++import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; +import net.minecraft.nbt.CompoundTag; ++import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.chunk.storage.RegionFile; +import net.minecraft.world.level.chunk.storage.RegionFileStorage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; ++import java.io.DataInputStream; ++import java.io.DataOutputStream; +import java.io.IOException; +import java.lang.invoke.VarHandle; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.atomic.AtomicInteger; ++import java.util.concurrent.atomic.AtomicLong; +import java.util.function.BiConsumer; +import java.util.function.Consumer; -+import java.util.function.Function; + -+/** -+ * Prioritised RegionFile I/O executor, responsible for all RegionFile access. -+ *

    -+ * All functions provided are MT-Safe, however certain ordering constraints are recommended: -+ *

  • -+ * Chunk saves may not occur for unloaded chunks. -+ *
  • -+ *
  • -+ * Tasks must be scheduled on the chunk scheduler thread. -+ *
  • -+ * By following these constraints, no chunk data loss should occur with the exception of underlying I/O problems. -+ *

    -+ */ -+public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { ++public final class MoonriseRegionFileIO { + -+ private static final Logger LOGGER = LoggerFactory.getLogger(RegionFileIOThread.class); ++ private static final int REGION_FILE_SHIFT = 5; ++ private static final Logger LOGGER = LoggerFactory.getLogger(MoonriseRegionFileIO.class); + + /** -+ * The kinds of region files controlled by the region file thread. Add more when needed, and ensure -+ * getControllerFor is updated. ++ * The types of RegionFiles controlled by the I/O thread(s). + */ + public static enum RegionFileType { + CHUNK_DATA, @@ -638,9 +864,7 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + ENTITY_DATA; + } + -+ private static final RegionFileType[] CACHED_REGIONFILE_TYPES = RegionFileType.values(); -+ -+ public static ChunkDataController getControllerFor(final ServerLevel world, final RegionFileType type) { ++ public static RegionDataController getControllerFor(final ServerLevel world, final RegionFileType type) { + switch (type) { + case CHUNK_DATA: + return ((ChunkSystemServerLevel)world).moonrise$getChunkDataController(); @@ -653,8 +877,10 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + } + } + ++ private static final RegionFileType[] CACHED_REGIONFILE_TYPES = RegionFileType.values(); ++ + /** -+ * Collects regionfile data for a certain chunk. ++ * Collects RegionFile data for a certain chunk. + */ + public static final class RegionFileData { + @@ -663,13 +889,13 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + private final Throwable[] throwables = new Throwable[CACHED_REGIONFILE_TYPES.length]; + + /** -+ * Sets the result associated with the specified regionfile type. Note that -+ * results can only be set once per regionfile type. ++ * Sets the result associated with the specified RegionFile type. Note that ++ * results can only be set once per RegionFile type. + * -+ * @param type The regionfile type. ++ * @param type The RegionFile type. + * @param data The result to set. + */ -+ public void setData(final RegionFileType type, final CompoundTag data) { ++ public void setData(final MoonriseRegionFileIO.RegionFileType type, final CompoundTag data) { + final int index = type.ordinal(); + + if (this.hasResult[index]) { @@ -680,13 +906,13 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + } + + /** -+ * Sets the result associated with the specified regionfile type. Note that -+ * results can only be set once per regionfile type. ++ * Sets the result associated with the specified RegionFile type. Note that ++ * results can only be set once per RegionFile type. + * -+ * @param type The regionfile type. ++ * @param type The RegionFile type. + * @param throwable The result to set. + */ -+ public void setThrowable(final RegionFileType type, final Throwable throwable) { ++ public void setThrowable(final MoonriseRegionFileIO.RegionFileType type, final Throwable throwable) { + final int index = type.ordinal(); + + if (this.hasResult[index]) { @@ -697,26 +923,26 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + } + + /** -+ * Returns whether there is a result for the specified regionfile type. ++ * Returns whether there is a result for the specified RegionFile type. + * -+ * @param type Specified regionfile type. ++ * @param type Specified RegionFile type. + * + * @return Whether a result exists for {@code type}. + */ -+ public boolean hasResult(final RegionFileType type) { ++ public boolean hasResult(final MoonriseRegionFileIO.RegionFileType type) { + return this.hasResult[type.ordinal()]; + } + + /** -+ * Returns the data result for the regionfile type. ++ * Returns the data result for the RegionFile type. + * -+ * @param type Specified regionfile type. ++ * @param type Specified RegionFile type. + * + * @throws IllegalArgumentException If the result has not been set for {@code type}. + * @return The data result for the specified type. If the result is a {@code Throwable}, + * then returns {@code null}. + */ -+ public CompoundTag getData(final RegionFileType type) { ++ public CompoundTag getData(final MoonriseRegionFileIO.RegionFileType type) { + final int index = type.ordinal(); + + if (!this.hasResult[index]) { @@ -727,15 +953,15 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + } + + /** -+ * Returns the throwable result for the regionfile type. ++ * Returns the throwable result for the RegionFile type. + * -+ * @param type Specified regionfile type. ++ * @param type Specified RegionFile type. + * + * @throws IllegalArgumentException If the result has not been set for {@code type}. + * @return The throwable result for the specified type. If the result is an {@code CompoundTag}, + * then returns {@code null}. + */ -+ public Throwable getThrowable(final RegionFileType type) { ++ public Throwable getThrowable(final MoonriseRegionFileIO.RegionFileType type) { + final int index = type.ordinal(); + + if (!this.hasResult[index]) { @@ -746,134 +972,55 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + } + } + -+ private static final Object INIT_LOCK = new Object(); -+ -+ static RegionFileIOThread[] threads; -+ -+ /* needs to be consistent given a set of parameters */ -+ static RegionFileIOThread selectThread(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { -+ if (threads == null) { -+ throw new IllegalStateException("Threads not initialised"); -+ } -+ -+ final int regionX = chunkX >> 5; -+ final int regionZ = chunkZ >> 5; -+ final int typeOffset = type.ordinal(); -+ -+ return threads[(System.identityHashCode(world) + regionX + regionZ + typeOffset) % threads.length]; -+ } -+ -+ /** -+ * Shuts down the I/O executor(s). Watis for all tasks to complete if specified. -+ * Tasks queued during this call might not be accepted, and tasks queued after will not be accepted. -+ * -+ * @param wait Whether to wait until all tasks have completed. -+ */ -+ public static void close(final boolean wait) { -+ for (int i = 0, len = threads.length; i < len; ++i) { -+ threads[i].close(false, true); -+ } -+ if (wait) { -+ RegionFileIOThread.flush(); -+ } -+ } -+ -+ public static long[] getExecutedTasks() { -+ final long[] ret = new long[threads.length]; -+ for (int i = 0, len = threads.length; i < len; ++i) { -+ ret[i] = threads[i].getTotalTasksExecuted(); ++ public static void flushRegionStorages(final ServerLevel world) throws IOException { ++ for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { ++ flushRegionStorages(world, type); + } -+ -+ return ret; + } + -+ public static long[] getTasksScheduled() { -+ final long[] ret = new long[threads.length]; -+ for (int i = 0, len = threads.length; i < len; ++i) { -+ ret[i] = threads[i].getTotalTasksScheduled(); -+ } -+ return ret; ++ public static void flushRegionStorages(final ServerLevel world, final RegionFileType type) throws IOException { ++ getControllerFor(world, type).getCache().flush(); + } + -+ public static void flush() { -+ for (int i = 0, len = threads.length; i < len; ++i) { -+ threads[i].waitUntilAllExecuted(); ++ public static void flush(final MinecraftServer server) { ++ for (final ServerLevel world : server.getAllLevels()) { ++ flush(world); + } + } + -+ public static void flushRegionStorages(final ServerLevel world) throws IOException { -+ for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { -+ getControllerFor(world, type).getCache().flush(); ++ public static void flush(final ServerLevel world) { ++ for (final RegionFileType regionFileType : CACHED_REGIONFILE_TYPES) { ++ flush(world, regionFileType); + } + } + -+ public static void partialFlush(final int totalTasksRemaining) { -+ long failures = 1L; // start out at 0.25ms -+ -+ for (;;) { -+ final long[] executed = getExecutedTasks(); -+ final long[] scheduled = getTasksScheduled(); -+ -+ long sum = 0; -+ for (int i = 0; i < executed.length; ++i) { -+ sum += scheduled[i] - executed[i]; -+ } ++ public static void flush(final ServerLevel world, final RegionFileType type) { ++ final RegionDataController taskController = getControllerFor(world, type); + -+ if (sum <= totalTasksRemaining) { -+ break; -+ } ++ long failures = 1L; // start at 0.13ms + -+ failures = ConcurrentUtil.linearLongBackoff(failures, 250_000L, 5_000_000L); // 500us, 5ms ++ while (taskController.hasTasks()) { ++ Thread.yield(); ++ failures = ConcurrentUtil.linearLongBackoff(failures, 125_000L, 5_000_000L); // 125us, 5ms + } + } + -+ /** -+ * Inits the executor with the specified number of threads. -+ * -+ * @param threads Specified number of threads. -+ */ -+ public static void init(final int threads) { -+ synchronized (INIT_LOCK) { -+ if (RegionFileIOThread.threads != null) { -+ throw new IllegalStateException("Already initialised threads"); ++ public static void partialFlush(final ServerLevel world, final int tasksRemaining) { ++ for (long failures = 1L;;) { // start at 0.13ms ++ long totalTasks = 0L; ++ for (final RegionFileType regionFileType : CACHED_REGIONFILE_TYPES) { ++ totalTasks += getControllerFor(world, regionFileType).getTotalWorkingTasks(); + } + -+ RegionFileIOThread.threads = new RegionFileIOThread[threads]; -+ -+ for (int i = 0; i < threads; ++i) { -+ RegionFileIOThread.threads[i] = new RegionFileIOThread(i); -+ RegionFileIOThread.threads[i].start(); ++ if (totalTasks > (long)tasksRemaining) { ++ Thread.yield(); ++ failures = ConcurrentUtil.linearLongBackoff(failures, 125_000L, 5_000_000L); // 125us, 5ms ++ } else { ++ return; + } + } + } + -+ public static void deinit() { -+ if (true) { // Paper -+ // TODO does this cause issues with mods? how to implement -+ close(true); -+ synchronized (INIT_LOCK) { -+ RegionFileIOThread.threads = null; -+ } -+ } else { RegionFileIOThread.flush(); } -+ } -+ -+ private RegionFileIOThread(final int threadNumber) { -+ super(new PrioritisedThreadedTaskQueue(), (int)(1.0e6)); // 1.0ms spinwait time -+ this.setName("RegionFile I/O Thread #" + threadNumber); -+ this.setPriority(Thread.NORM_PRIORITY - 2); // we keep priority close to normal because threads can wait on us -+ this.setUncaughtExceptionHandler((final Thread thread, final Throwable thr) -> { -+ LOGGER.error("Uncaught exception thrown from I/O thread, report this! Thread: " + thread.getName(), thr); -+ }); -+ } -+ -+ /** -+ * Returns whether the current thread is a regionfile I/O executor. -+ * @return Whether the current thread is a regionfile I/O executor. -+ */ -+ public static boolean isRegionFileThread() { -+ return Thread.currentThread() instanceof RegionFileIOThread; -+ } -+ + /** + * Returns the priority associated with blocking I/O based on the current thread. The goal is to avoid + * dumb plugins from taking away priority from threads we consider crucial. @@ -887,35 +1034,6 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + } + + /** -+ * Returns the current {@code CompoundTag} pending for write for the specified chunk & regionfile type. -+ * Note that this does not copy the result, so do not modify the result returned. -+ * -+ * @param world Specified world. -+ * @param chunkX Specified chunk x. -+ * @param chunkZ Specified chunk z. -+ * @param type Specified regionfile type. -+ * -+ * @return The compound tag associated for the specified chunk. {@code null} if no write was pending, or if {@code null} is the write pending. -+ */ -+ public static CompoundTag getPendingWrite(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { -+ final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -+ return thread.getPendingWriteInternal(world, chunkX, chunkZ, type); -+ } -+ -+ CompoundTag getPendingWriteInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { -+ final ChunkDataController taskController = getControllerFor(world, type); -+ final ChunkDataTask task = taskController.tasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ -+ if (task == null) { -+ return null; -+ } -+ -+ final CompoundTag ret = task.inProgressWrite; -+ -+ return ret == ChunkDataTask.NOTHING_TO_WRITE ? null : ret; -+ } -+ -+ /** + * Returns the priority for the specified regionfile type for the specified chunk. + * @param world Specified world. + * @param chunkX Specified chunk x. @@ -924,19 +1042,14 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + * @return The priority for the chunk + */ + public static Priority getPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { -+ final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -+ return thread.getPriorityInternal(world, chunkX, chunkZ, type); -+ } -+ -+ Priority getPriorityInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { -+ final ChunkDataController taskController = getControllerFor(world, type); -+ final ChunkDataTask task = taskController.tasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ final RegionDataController taskController = getControllerFor(world, type); ++ final ChunkIOTask task = taskController.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + + if (task == null) { + return Priority.COMPLETING; + } + -+ return task.prioritisedTask.getPriority(); ++ return task.getPriority(); + } + + /** @@ -957,7 +1070,7 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + public static void setPriority(final ServerLevel world, final int chunkX, final int chunkZ, + final Priority priority) { + for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { -+ RegionFileIOThread.setPriority(world, chunkX, chunkZ, type, priority); ++ MoonriseRegionFileIO.setPriority(world, chunkX, chunkZ, type, priority); + } + } + @@ -979,17 +1092,11 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + */ + public static void setPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, + final Priority priority) { -+ final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -+ thread.setPriorityInternal(world, chunkX, chunkZ, type, priority); -+ } -+ -+ void setPriorityInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -+ final Priority priority) { -+ final ChunkDataController taskController = getControllerFor(world, type); -+ final ChunkDataTask task = taskController.tasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ final RegionDataController taskController = getControllerFor(world, type); ++ final ChunkIOTask task = taskController.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + + if (task != null) { -+ task.prioritisedTask.setPriority(priority); ++ task.setPriority(priority); + } + } + @@ -1009,7 +1116,7 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + public static void raisePriority(final ServerLevel world, final int chunkX, final int chunkZ, + final Priority priority) { + for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { -+ RegionFileIOThread.raisePriority(world, chunkX, chunkZ, type, priority); ++ MoonriseRegionFileIO.raisePriority(world, chunkX, chunkZ, type, priority); + } + } + @@ -1029,17 +1136,11 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + */ + public static void raisePriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, + final Priority priority) { -+ final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -+ thread.raisePriorityInternal(world, chunkX, chunkZ, type, priority); -+ } -+ -+ void raisePriorityInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -+ final Priority priority) { -+ final ChunkDataController taskController = getControllerFor(world, type); -+ final ChunkDataTask task = taskController.tasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ final RegionDataController taskController = getControllerFor(world, type); ++ final ChunkIOTask task = taskController.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + + if (task != null) { -+ task.prioritisedTask.raisePriority(priority); ++ task.raisePriority(priority); + } + } + @@ -1059,7 +1160,7 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + public static void lowerPriority(final ServerLevel world, final int chunkX, final int chunkZ, + final Priority priority) { + for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { -+ RegionFileIOThread.lowerPriority(world, chunkX, chunkZ, type, priority); ++ MoonriseRegionFileIO.lowerPriority(world, chunkX, chunkZ, type, priority); + } + } + @@ -1079,17 +1180,11 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + */ + public static void lowerPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, + final Priority priority) { -+ final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -+ thread.lowerPriorityInternal(world, chunkX, chunkZ, type, priority); -+ } -+ -+ void lowerPriorityInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -+ final Priority priority) { -+ final ChunkDataController taskController = getControllerFor(world, type); -+ final ChunkDataTask task = taskController.tasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ final RegionDataController taskController = getControllerFor(world, type); ++ final ChunkIOTask task = taskController.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + + if (task != null) { -+ task.prioritisedTask.lowerPriority(priority); ++ task.lowerPriority(priority); + } + } + @@ -1116,7 +1211,7 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + */ + public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data, + final RegionFileType type) { -+ RegionFileIOThread.scheduleSave(world, chunkX, chunkZ, data, type, Priority.NORMAL); ++ MoonriseRegionFileIO.scheduleSave(world, chunkX, chunkZ, data, type, Priority.NORMAL); + } + + /** @@ -1143,37 +1238,112 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + */ + public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data, + final RegionFileType type, final Priority priority) { -+ final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -+ thread.scheduleSaveInternal(world, chunkX, chunkZ, data, type, priority); ++ scheduleSave( ++ world, chunkX, chunkZ, ++ (final BiConsumer consumer) -> { ++ consumer.accept(data, null); ++ }, null, type, priority ++ ); ++ } ++ ++ /** ++ * Schedules the chunk data to be written asynchronously. ++ *

    ++ * Impl notes: ++ *

    ++ *
  • ++ * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means ++ * saves must be scheduled before a chunk is unloaded. ++ *
  • ++ *
  • ++ * Writes may be called concurrently, although only the "later" write will go through. ++ *
  • ++ *
  • ++ * The specified write task, if not null, will have its priority controlled by the scheduler. ++ *
  • ++ * ++ * @param world Chunk's world ++ * @param chunkX Chunk's x coordinate ++ * @param chunkZ Chunk's z coordinate ++ * @param completable Chunk's pending data ++ * @param writeTask The task responsible for completing the pending chunk data ++ * @param type The regionfile type to write to. ++ * @param priority The minimum priority to schedule at. ++ * ++ * @throws IllegalStateException If the file io thread has shutdown. ++ */ ++ public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final CallbackCompletable completable, ++ final PrioritisedExecutor.PrioritisedTask writeTask, final RegionFileType type, final Priority priority) { ++ scheduleSave(world, chunkX, chunkZ, completable::addWaiter, writeTask, type, priority); ++ } ++ ++ /** ++ * Schedules the chunk data to be written asynchronously. ++ *

    ++ * Impl notes: ++ *

    ++ *
  • ++ * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means ++ * saves must be scheduled before a chunk is unloaded. ++ *
  • ++ *
  • ++ * Writes may be called concurrently, although only the "later" write will go through. ++ *
  • ++ *
  • ++ * The specified write task, if not null, will have its priority controlled by the scheduler. ++ *
  • ++ * ++ * @param world Chunk's world ++ * @param chunkX Chunk's x coordinate ++ * @param chunkZ Chunk's z coordinate ++ * @param completable Chunk's pending data ++ * @param writeTask The task responsible for completing the pending chunk data ++ * @param type The regionfile type to write to. ++ * @param priority The minimum priority to schedule at. ++ * ++ * @throws IllegalStateException If the file io thread has shutdown. ++ */ ++ public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final Completable completable, ++ final PrioritisedExecutor.PrioritisedTask writeTask, final RegionFileType type, final Priority priority) { ++ scheduleSave(world, chunkX, chunkZ, completable::whenComplete, writeTask, type, priority); + } + -+ void scheduleSaveInternal(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data, -+ final RegionFileType type, final Priority priority) { -+ final ChunkDataController taskController = getControllerFor(world, type); ++ private static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final Consumer> scheduler, ++ final PrioritisedExecutor.PrioritisedTask writeTask, final RegionFileType type, final Priority priority) { ++ final RegionDataController taskController = getControllerFor(world, type); + + final boolean[] created = new boolean[1]; -+ final long key = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ final ChunkDataTask task = taskController.tasks.compute(key, (final long keyInMap, final ChunkDataTask taskRunning) -> { -+ if (taskRunning == null || taskRunning.failedWrite) { -+ // no task is scheduled or the previous write failed - meaning we need to overwrite it ++ final ChunkIOTask.InProgressWrite write = new ChunkIOTask.InProgressWrite(writeTask); ++ final ChunkIOTask task = taskController.chunkTasks.compute(CoordinateUtils.getChunkKey(chunkX, chunkZ), ++ (final long keyInMap, final ChunkIOTask taskRunning) -> { ++ if (taskRunning == null || taskRunning.failedWrite) { ++ // no task is scheduled or the previous write failed - meaning we need to overwrite it ++ ++ // create task ++ final ChunkIOTask newTask = new ChunkIOTask( ++ world, taskController, chunkX, chunkZ, priority, new ChunkIOTask.InProgressRead() ++ ); + -+ // create task -+ final ChunkDataTask newTask = new ChunkDataTask(world, chunkX, chunkZ, taskController, RegionFileIOThread.this, priority); -+ newTask.inProgressWrite = data; -+ created[0] = true; ++ newTask.pushPendingWrite(write); + -+ return newTask; -+ } ++ created[0] = true; ++ ++ return newTask; ++ } + -+ taskRunning.inProgressWrite = data; ++ taskRunning.pushPendingWrite(write); + -+ return taskRunning; -+ }); ++ return taskRunning; ++ } ++ ); ++ ++ write.schedule(task, scheduler); + + if (created[0]) { -+ task.prioritisedTask.queue(); ++ taskController.startTask(task); ++ task.scheduleWriteCompress(); + } else { -+ task.prioritisedTask.raisePriority(priority); ++ task.raisePriority(priority); + } + } + @@ -1206,7 +1376,7 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + */ + public static Cancellable loadAllChunkData(final ServerLevel world, final int chunkX, final int chunkZ, + final Consumer onComplete, final boolean intendingToBlock) { -+ return RegionFileIOThread.loadAllChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, Priority.NORMAL); ++ return MoonriseRegionFileIO.loadAllChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, Priority.NORMAL); + } + + /** @@ -1240,7 +1410,7 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + public static Cancellable loadAllChunkData(final ServerLevel world, final int chunkX, final int chunkZ, + final Consumer onComplete, final boolean intendingToBlock, + final Priority priority) { -+ return RegionFileIOThread.loadChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, priority, CACHED_REGIONFILE_TYPES); ++ return MoonriseRegionFileIO.loadChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, priority, CACHED_REGIONFILE_TYPES); + } + + /** @@ -1274,7 +1444,7 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + public static Cancellable loadChunkData(final ServerLevel world, final int chunkX, final int chunkZ, + final Consumer onComplete, final boolean intendingToBlock, + final RegionFileType... types) { -+ return RegionFileIOThread.loadChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, Priority.NORMAL, types); ++ return MoonriseRegionFileIO.loadChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, Priority.NORMAL, types); + } + + /** @@ -1324,7 +1494,7 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + + for (int i = 0; i < expectedCompletions; ++i) { + final RegionFileType type = types[i]; -+ reads[i] = RegionFileIOThread.loadDataAsync(world, chunkX, chunkZ, type, ++ reads[i] = MoonriseRegionFileIO.loadDataAsync(world, chunkX, chunkZ, type, + (final CompoundTag data, final Throwable throwable) -> { + if (throwable != null) { + ret.setThrowable(type, throwable); @@ -1370,7 +1540,7 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + public static Cancellable loadDataAsync(final ServerLevel world, final int chunkX, final int chunkZ, + final RegionFileType type, final BiConsumer onComplete, + final boolean intendingToBlock) { -+ return RegionFileIOThread.loadDataAsync(world, chunkX, chunkZ, type, onComplete, intendingToBlock, Priority.NORMAL); ++ return MoonriseRegionFileIO.loadDataAsync(world, chunkX, chunkZ, type, onComplete, intendingToBlock, Priority.NORMAL); + } + + /** @@ -1403,57 +1573,62 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + public static Cancellable loadDataAsync(final ServerLevel world, final int chunkX, final int chunkZ, + final RegionFileType type, final BiConsumer onComplete, + final boolean intendingToBlock, final Priority priority) { -+ final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -+ return thread.loadDataAsyncInternal(world, chunkX, chunkZ, type, onComplete, intendingToBlock, priority); -+ } -+ -+ Cancellable loadDataAsyncInternal(final ServerLevel world, final int chunkX, final int chunkZ, -+ final RegionFileType type, final BiConsumer onComplete, -+ final boolean intendingToBlock, final Priority priority) { -+ final ChunkDataController taskController = getControllerFor(world, type); ++ final RegionDataController taskController = getControllerFor(world, type); + + final ImmediateCallbackCompletion callbackInfo = new ImmediateCallbackCompletion(); + + final long key = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ final BiLong1Function compute = (final long keyInMap, final ChunkDataTask running) -> { ++ final BiLong1Function compute = (final long keyInMap, final ChunkIOTask running) -> { + if (running == null) { + // not scheduled + + // set up task -+ final ChunkDataTask newTask = new ChunkDataTask( -+ world, chunkX, chunkZ, taskController, RegionFileIOThread.this, priority ++ final ChunkIOTask newTask = new ChunkIOTask( ++ world, taskController, chunkX, chunkZ, priority, new ChunkIOTask.InProgressRead() + ); -+ newTask.inProgressRead = new InProgressRead(); + newTask.inProgressRead.addToAsyncWaiters(onComplete); + -+ callbackInfo.tasksNeedsScheduling = true; ++ callbackInfo.tasksNeedReadScheduling = true; + return newTask; + } + -+ final CompoundTag pendingWrite = running.inProgressWrite; ++ final ChunkIOTask.InProgressWrite pendingWrite = running.inProgressWrite; + -+ if (pendingWrite == ChunkDataTask.NOTHING_TO_WRITE) { ++ if (pendingWrite == null) { + // need to add to waiters here, because the regionfile thread will use compute() to lock and check for cancellations + if (!running.inProgressRead.addToAsyncWaiters(onComplete)) { + callbackInfo.data = running.inProgressRead.value; + callbackInfo.throwable = running.inProgressRead.throwable; + callbackInfo.completeNow = true; ++ return running; + } ++ ++ callbackInfo.read = running.inProgressRead; ++ + return running; + } + + // at this stage we have to use the in progress write's data to avoid an order issue -+ callbackInfo.data = pendingWrite; -+ callbackInfo.throwable = null; -+ callbackInfo.completeNow = true; ++ ++ if (!pendingWrite.addToAsyncWaiters(onComplete)) { ++ // data is ready now ++ callbackInfo.data = pendingWrite.value; ++ callbackInfo.throwable = pendingWrite.throwable; ++ callbackInfo.completeNow = true; ++ return running; ++ } ++ ++ callbackInfo.write = pendingWrite; ++ + return running; + }; + -+ final ChunkDataTask ret = taskController.tasks.compute(key, compute); ++ final ChunkIOTask ret = taskController.chunkTasks.compute(key, compute); + + // needs to be scheduled -+ if (callbackInfo.tasksNeedsScheduling) { -+ ret.prioritisedTask.queue(); ++ if (callbackInfo.tasksNeedReadScheduling) { ++ taskController.startTask(ret); ++ ret.scheduleReadIO(); + } else if (callbackInfo.completeNow) { + try { + onComplete.accept(callbackInfo.data == null ? null : callbackInfo.data.copy(), callbackInfo.throwable); @@ -1462,10 +1637,21 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + } + } else { + // we're waiting on a task we didn't schedule, so raise its priority to what we want -+ ret.prioritisedTask.raisePriority(priority); ++ ret.raisePriority(priority); + } + -+ return new CancellableRead(onComplete, ret); ++ return new CancellableRead(onComplete, callbackInfo.read, callbackInfo.write); ++ } ++ ++ private static final class ImmediateCallbackCompletion { ++ ++ private CompoundTag data; ++ private Throwable throwable; ++ private boolean completeNow; ++ private boolean tasksNeedReadScheduling; ++ private ChunkIOTask.InProgressRead read; ++ private ChunkIOTask.InProgressWrite write; ++ + } + + /** @@ -1485,7 +1671,7 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + final Priority priority) throws IOException { + final CompletableFuture ret = new CompletableFuture<>(); + -+ RegionFileIOThread.loadDataAsync(world, chunkX, chunkZ, type, (final CompoundTag compound, final Throwable thr) -> { ++ MoonriseRegionFileIO.loadDataAsync(world, chunkX, chunkZ, type, (final CompoundTag compound, final Throwable thr) -> { + if (thr != null) { + ret.completeExceptionally(thr); + } else { @@ -1499,52 +1685,53 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + throw new IOException(ex); + } + } -+ -+ private static final class ImmediateCallbackCompletion { -+ -+ public CompoundTag data; -+ public Throwable throwable; -+ public boolean completeNow; -+ public boolean tasksNeedsScheduling; -+ -+ } -+ ++ + private static final class CancellableRead implements Cancellable { + + private BiConsumer callback; -+ private ChunkDataTask task; ++ private ChunkIOTask.InProgressRead read; ++ private ChunkIOTask.InProgressWrite write; + -+ CancellableRead(final BiConsumer callback, final ChunkDataTask task) { ++ private CancellableRead(final BiConsumer callback, ++ final ChunkIOTask.InProgressRead read, ++ final ChunkIOTask.InProgressWrite write) { + this.callback = callback; -+ this.task = task; ++ this.read = read; ++ this.write = write; + } + + @Override + public boolean cancel() { + final BiConsumer callback = this.callback; -+ final ChunkDataTask task = this.task; ++ final ChunkIOTask.InProgressRead read = this.read; ++ final ChunkIOTask.InProgressWrite write = this.write; + -+ if (callback == null || task == null) { ++ if (callback == null || (read == null && write == null)) { + return false; + } + + this.callback = null; -+ this.task = null; ++ this.read = null; ++ this.write = null; + -+ final InProgressRead read = task.inProgressRead; ++ if (read != null) { ++ return read.cancel(callback); ++ } ++ if (write != null) { ++ return write.cancel(callback); ++ } + -+ // read can be null if no read was scheduled (i.e no regionfile existed or chunk in regionfile didn't) -+ return read != null && read.cancel(callback); ++ // unreachable ++ throw new InternalError(); + } + } + + private static final class CancellableReads implements Cancellable { + + private Cancellable[] reads; -+ + private static final VarHandle READS_HANDLE = ConcurrentUtil.getVarHandle(CancellableReads.class, "reads", Cancellable[].class); + -+ CancellableReads(final Cancellable[] reads) { ++ private CancellableReads(final Cancellable[] reads) { + this.reads = reads; + } + @@ -1566,286 +1753,802 @@ index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d + } + } + -+ private static final class InProgressRead { ++ private static final class ChunkIOTask { + -+ private static final Logger LOGGER = LoggerFactory.getLogger(InProgressRead.class); ++ private final ServerLevel world; ++ private final RegionDataController regionDataController; ++ private final int chunkX; ++ private final int chunkZ; ++ private Priority priority; ++ private PrioritisedExecutor.PrioritisedTask currentTask; + -+ private CompoundTag value; -+ private Throwable throwable; -+ private final MultiThreadedQueue> callbacks = new MultiThreadedQueue<>(); ++ private final InProgressRead inProgressRead; ++ private volatile InProgressWrite inProgressWrite; ++ private final ReferenceOpenHashSet allPendingWrites = new ReferenceOpenHashSet<>(); + -+ public boolean hasNoWaiters() { -+ return this.callbacks.isEmpty(); -+ } ++ private RegionDataController.ReadData readData; ++ private RegionDataController.WriteData writeData; ++ private boolean failedWrite; + -+ public boolean addToAsyncWaiters(final BiConsumer callback) { -+ return this.callbacks.add(callback); ++ public ChunkIOTask(final ServerLevel world, final RegionDataController regionDataController, ++ final int chunkX, final int chunkZ, final Priority priority, final InProgressRead inProgressRead) { ++ this.world = world; ++ this.regionDataController = regionDataController; ++ this.chunkX = chunkX; ++ this.chunkZ = chunkZ; ++ this.priority = priority; ++ this.inProgressRead = inProgressRead; + } + -+ public boolean cancel(final BiConsumer callback) { -+ return this.callbacks.remove(callback); ++ public Priority getPriority() { ++ synchronized (this) { ++ return this.priority; ++ } + } + -+ public void complete(final ChunkDataTask task, final CompoundTag value, final Throwable throwable) { -+ this.value = value; -+ this.throwable = throwable; -+ -+ BiConsumer consumer; -+ while ((consumer = this.callbacks.pollOrBlockAdds()) != null) { -+ try { -+ consumer.accept(value == null ? null : value.copy(), throwable); -+ } catch (final Throwable thr) { -+ LOGGER.error("Callback " + ConcurrentUtil.genericToString(consumer) + " failed to handle chunk data for task " + task.toString(), thr); ++ // must hold lock on this object ++ private void updatePriority(final Priority priority) { ++ this.priority = priority; ++ if (this.currentTask != null) { ++ this.currentTask.setPriority(priority); ++ } ++ for (final InProgressWrite write : this.allPendingWrites) { ++ if (write.writeTask != null) { ++ write.writeTask.setPriority(priority); + } + } + } -+ } + -+ public static abstract class ChunkDataController { -+ -+ // ConcurrentHashMap synchronizes per chain, so reduce the chance of task's hashes colliding. -+ private final ConcurrentLong2ReferenceChainedHashTable tasks = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(8192, 0.5f); ++ public boolean setPriority(final Priority priority) { ++ synchronized (this) { ++ if (this.priority == priority) { ++ return false; ++ } + -+ public final RegionFileType type; ++ this.updatePriority(priority); + -+ public ChunkDataController(final RegionFileType type) { -+ this.type = type; ++ return true; ++ } + } + -+ public abstract RegionFileStorage getCache(); -+ -+ public abstract void writeData(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException; -+ -+ public abstract CompoundTag readData(final int chunkX, final int chunkZ) throws IOException; ++ public boolean raisePriority(final Priority priority) { ++ synchronized (this) { ++ if (this.priority.isHigherOrEqualPriority(priority)) { ++ return false; ++ } + -+ public boolean hasTasks() { -+ return !this.tasks.isEmpty(); -+ } ++ this.updatePriority(priority); + -+ public boolean doesRegionFileNotExist(final int chunkX, final int chunkZ) { -+ return ((ChunkSystemRegionFileStorage)(Object)this.getCache()).moonrise$doesRegionFileNotExistNoIO(chunkX, chunkZ); ++ return true; ++ } + } + -+ public T computeForRegionFile(final int chunkX, final int chunkZ, final boolean existingOnly, final Function function) { -+ final RegionFileStorage cache = this.getCache(); -+ final RegionFile regionFile; -+ synchronized (cache) { -+ try { -+ if (existingOnly) { -+ regionFile = ((ChunkSystemRegionFileStorage)(Object)cache).moonrise$getRegionFileIfExists(chunkX, chunkZ); -+ } else { -+ regionFile = cache.getRegionFile(new ChunkPos(chunkX, chunkZ), existingOnly); -+ } -+ } catch (final IOException ex) { -+ throw new RuntimeException(ex); ++ public boolean lowerPriority(final Priority priority) { ++ synchronized (this) { ++ if (this.priority.isLowerOrEqualPriority(priority)) { ++ return false; + } + -+ return function.apply(regionFile); ++ this.updatePriority(priority); ++ ++ return true; + } + } + -+ public T computeForRegionFileIfLoaded(final int chunkX, final int chunkZ, final Function function) { -+ final RegionFileStorage cache = this.getCache(); -+ final RegionFile regionFile; ++ private void pushPendingWrite(final InProgressWrite write) { ++ this.inProgressWrite = write; ++ synchronized (this) { ++ this.allPendingWrites.add(write); ++ if (write.writeTask != null) { ++ write.writeTask.setPriority(this.priority); ++ } ++ } ++ } + -+ synchronized (cache) { -+ regionFile = ((ChunkSystemRegionFileStorage)(Object)cache).moonrise$getRegionFileIfLoaded(chunkX, chunkZ); ++ private void pendingWriteComplete(final InProgressWrite write) { ++ synchronized (this) { ++ this.allPendingWrites.remove(write); ++ } ++ } + -+ return function.apply(regionFile); ++ public void scheduleReadIO() { ++ final PrioritisedExecutor.PrioritisedTask task; ++ synchronized (this) { ++ task = this.regionDataController.ioScheduler.createTask(this.chunkX, this.chunkZ, this::performReadIO, this.priority); ++ this.currentTask = task; + } ++ task.queue(); + } -+ } + -+ private static final class ChunkDataTask implements Runnable { ++ private void performReadIO() { ++ final InProgressRead read = this.inProgressRead; ++ final long chunkKey = CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ); + -+ private static final CompoundTag NOTHING_TO_WRITE = new CompoundTag(); ++ final boolean[] canRead = new boolean[] { true }; + -+ private static final Logger LOGGER = LoggerFactory.getLogger(ChunkDataTask.class); ++ if (read.hasNoWaiters()) { ++ // cancelled read? go to task controller to confirm ++ final ChunkIOTask inMap = this.regionDataController.chunkTasks.compute(chunkKey, (final long keyInMap, final ChunkIOTask valueInMap) -> { ++ if (valueInMap == null) { ++ throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkIOTask.this.toString() + ", report this!"); ++ } ++ if (valueInMap != ChunkIOTask.this) { ++ throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkIOTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); ++ } + -+ private InProgressRead inProgressRead; -+ private volatile CompoundTag inProgressWrite = NOTHING_TO_WRITE; // only needs to be acquire/release ++ if (!read.hasNoWaiters()) { ++ return valueInMap; ++ } else { ++ canRead[0] = false; ++ } + -+ private boolean failedWrite; ++ if (valueInMap.inProgressWrite != null) { ++ return valueInMap; ++ } + -+ private final ServerLevel world; -+ private final int chunkX; -+ private final int chunkZ; -+ private final ChunkDataController taskController; ++ return null; ++ }); + -+ private final PrioritisedTask prioritisedTask; ++ if (inMap == null) { ++ this.regionDataController.endTask(this); ++ // read is cancelled - and no write pending, so we're done ++ return; ++ } ++ // if there is a write in progress, we don't actually have to worry about waiters gaining new entries - ++ // the readers will just use the in progress write, so the value in canRead is good to use without ++ // further synchronisation. ++ } + -+ /* -+ * IO thread will perform reads before writes for a given chunk x and z -+ * -+ * How reads/writes are scheduled: -+ * -+ * If read is scheduled while scheduling write, take no special action and just schedule write -+ * If read is scheduled while scheduling read and no write is scheduled, chain the read task -+ * -+ * -+ * If write is scheduled while scheduling read, use the pending write data and ret immediately (so no read is scheduled) -+ * If write is scheduled while scheduling write (ignore read in progress), overwrite the write in progress data -+ * -+ * This allows the reads and writes to act as if they occur synchronously to the thread scheduling them, however -+ * it fails to properly propagate write failures thanks to writes overwriting each other -+ */ ++ if (canRead[0]) { ++ RegionDataController.ReadData readData = null; ++ Throwable throwable = null; + -+ public ChunkDataTask(final ServerLevel world, final int chunkX, final int chunkZ, final ChunkDataController taskController, -+ final PrioritisedExecutor executor, final Priority priority) { -+ this.world = world; -+ this.chunkX = chunkX; -+ this.chunkZ = chunkZ; -+ this.taskController = taskController; -+ this.prioritisedTask = executor.createTask(this, priority); ++ try { ++ readData = this.regionDataController.readData(this.chunkX, this.chunkZ); ++ } catch (final Throwable thr) { ++ throwable = thr; ++ LOGGER.error("Failed to read chunk data for task: " + this.toString(), thr); ++ } ++ ++ if (throwable != null) { ++ this.finishRead(null, throwable); ++ } else { ++ switch (readData.result()) { ++ case NO_DATA: ++ case SYNC_READ: { ++ this.finishRead(readData.syncRead(), null); ++ break; ++ } ++ case HAS_DATA: { ++ this.readData = readData; ++ this.scheduleReadDecompress(); ++ // read will handle write scheduling ++ return; ++ } ++ default: { ++ throw new IllegalStateException("Unknown state: " + readData.result()); ++ } ++ } ++ } ++ } ++ ++ if (!this.tryAbortWrite()) { ++ this.scheduleWriteCompress(); ++ } + } + -+ @Override -+ public String toString() { -+ return "Task for world: '" + WorldUtil.getWorldName(this.world) + "' at (" + this.chunkX + "," + this.chunkZ + -+ ") type: " + this.taskController.type.name() + ", hash: " + this.hashCode(); ++ private void scheduleReadDecompress() { ++ final PrioritisedExecutor.PrioritisedTask task; ++ synchronized (this) { ++ task = this.regionDataController.compressionExecutor.createTask(this::performReadDecompress, this.priority); ++ this.currentTask = task; ++ } ++ task.queue(); + } + -+ @Override -+ public void run() { -+ final InProgressRead read = this.inProgressRead; -+ final long chunkKey = CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ); ++ private void performReadDecompress() { ++ final RegionDataController.ReadData readData = this.readData; ++ this.readData = null; + -+ if (read != null) { -+ final boolean[] canRead = new boolean[] { true }; ++ CompoundTag compoundTag = null; ++ Throwable throwable = null; + -+ if (read.hasNoWaiters()) { -+ // cancelled read? go to task controller to confirm -+ final ChunkDataTask inMap = this.taskController.tasks.compute(chunkKey, (final long keyInMap, final ChunkDataTask valueInMap) -> { -+ if (valueInMap == null) { -+ throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkDataTask.this.toString() + ", report this!"); -+ } -+ if (valueInMap != ChunkDataTask.this) { -+ throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkDataTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); -+ } ++ try { ++ compoundTag = this.regionDataController.finishRead(this.chunkX, this.chunkZ, readData); ++ } catch (final Throwable thr) { ++ throwable = thr; ++ LOGGER.error("Failed to decompress chunk data for task: " + this.toString(), thr); ++ } + -+ if (!read.hasNoWaiters()) { -+ return valueInMap; -+ } else { -+ canRead[0] = false; -+ } ++ if (compoundTag == null) { ++ // need to re-try from the start ++ this.scheduleReadIO(); ++ return; ++ } + -+ return valueInMap.inProgressWrite == NOTHING_TO_WRITE ? null : valueInMap; -+ }); ++ this.finishRead(compoundTag, throwable); ++ if (!this.tryAbortWrite()) { ++ this.scheduleWriteCompress(); ++ } ++ } + -+ if (inMap == null) { -+ // read is cancelled - and no write pending, so we're done -+ return; -+ } -+ // if there is a write in progress, we don't actually have to worry about waiters gaining new entries - -+ // the readers will just use the in progress write, so the value in canRead is good to use without -+ // further synchronisation. -+ } ++ private void finishRead(final CompoundTag compoundTag, final Throwable throwable) { ++ this.inProgressRead.complete(this, compoundTag, throwable); ++ } + -+ if (canRead[0]) { -+ CompoundTag compound = null; -+ Throwable throwable = null; ++ public void scheduleWriteCompress() { ++ final InProgressWrite inProgressWrite = this.inProgressWrite; + -+ try { -+ compound = this.taskController.readData(this.chunkX, this.chunkZ); -+ } catch (final Throwable thr) { -+ throwable = thr; -+ LOGGER.error("Failed to read chunk data for task: " + this.toString(), thr); -+ } -+ read.complete(this, compound, throwable); -+ } ++ final PrioritisedExecutor.PrioritisedTask task; ++ synchronized (this) { ++ task = this.regionDataController.compressionExecutor.createTask(() -> { ++ ChunkIOTask.this.performWriteCompress(inProgressWrite); ++ }, this.priority); ++ this.currentTask = task; + } + -+ CompoundTag write = this.inProgressWrite; ++ inProgressWrite.addToWaiters(this, (final CompoundTag data, final Throwable throwable) -> { ++ task.queue(); ++ }); ++ } + -+ if (write == NOTHING_TO_WRITE) { -+ final ChunkDataTask inMap = this.taskController.tasks.compute(chunkKey, (final long keyInMap, final ChunkDataTask valueInMap) -> { ++ private boolean tryAbortWrite() { ++ final long chunkKey = CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ); ++ if (this.inProgressWrite == null) { ++ final ChunkIOTask inMap = this.regionDataController.chunkTasks.compute(chunkKey, (final long keyInMap, final ChunkIOTask valueInMap) -> { + if (valueInMap == null) { -+ throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkDataTask.this.toString() + ", report this!"); ++ throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkIOTask.this.toString() + ", report this!"); + } -+ if (valueInMap != ChunkDataTask.this) { -+ throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkDataTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); ++ if (valueInMap != ChunkIOTask.this) { ++ throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkIOTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); + } -+ return valueInMap.inProgressWrite == NOTHING_TO_WRITE ? null : valueInMap; ++ ++ if (valueInMap.inProgressWrite != null) { ++ return valueInMap; ++ } ++ ++ return null; + }); + + if (inMap == null) { -+ return; // set the task value to null, indicating we're done ++ this.regionDataController.endTask(this); ++ return true; // set the task value to null, indicating we're done + } // else: inProgressWrite changed, so now we have something to write + } + -+ for (;;) { -+ write = this.inProgressWrite; -+ final CompoundTag dataWritten = write; ++ return false; ++ } ++ ++ private void performWriteCompress(final InProgressWrite inProgressWrite) { ++ final CompoundTag write = inProgressWrite.value; ++ if (!inProgressWrite.isComplete()) { ++ throw new IllegalStateException("Should be writable"); ++ } + -+ boolean failedWrite = false; ++ RegionDataController.WriteData writeData = null; ++ boolean failedWrite = false; + -+ try { -+ this.taskController.writeData(this.chunkX, this.chunkZ, write); -+ } catch (final Throwable thr) { -+ if (thr instanceof RegionFileStorage.RegionFileSizeException) { ++ try { ++ writeData = this.regionDataController.startWrite(this.chunkX, this.chunkZ, write); ++ } catch (final Throwable thr) { ++ // TODO implement this? ++ /*if (thr instanceof RegionFileStorage.RegionFileSizeException) { + final int maxSize = RegionFile.MAX_CHUNK_SIZE / (1024 * 1024); + LOGGER.error("Chunk at (" + this.chunkX + "," + this.chunkZ + ") in '" + WorldUtil.getWorldName(this.world) + "' exceeds max size of " + maxSize + "MiB, it has been deleted from disk."); -+ } else { -+ failedWrite = thr instanceof IOException; -+ LOGGER.error("Failed to write chunk data for task: " + this.toString(), thr); -+ } ++ } else */ ++ { ++ failedWrite = thr instanceof IOException; ++ LOGGER.error("Failed to write chunk data for task: " + this.toString(), thr); + } ++ } + -+ final boolean finalFailWrite = failedWrite; -+ final boolean[] done = new boolean[] { false }; ++ if (writeData == null) { ++ // null if a throwable was encountered + -+ this.taskController.tasks.compute(chunkKey, (final long keyInMap, final ChunkDataTask valueInMap) -> { -+ if (valueInMap == null) { -+ throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkDataTask.this.toString() + ", report this!"); -+ } -+ if (valueInMap != ChunkDataTask.this) { -+ throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkDataTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); -+ } -+ if (valueInMap.inProgressWrite == dataWritten) { -+ valueInMap.failedWrite = finalFailWrite; -+ done[0] = true; -+ // keep the data in map if we failed the write so we can try to prevent data loss -+ return finalFailWrite ? valueInMap : null; -+ } -+ // different data than expected, means we need to retry write -+ return valueInMap; -+ }); ++ // we cannot continue to the I/O stage here, so try to complete + -+ if (done[0]) { ++ if (this.tryCompleteWrite(inProgressWrite, failedWrite)) { ++ return; ++ } else { ++ // fetch new data and try again ++ this.scheduleWriteCompress(); + return; + } ++ } else { ++ // writeData != null && !failedWrite ++ // we can continue to I/O stage ++ this.writeData = writeData; ++ this.scheduleWriteIO(inProgressWrite); ++ return; ++ } ++ } + -+ // fetch & write new data -+ continue; ++ private void scheduleWriteIO(final InProgressWrite inProgressWrite) { ++ final PrioritisedExecutor.PrioritisedTask task; ++ synchronized (this) { ++ task = this.regionDataController.ioScheduler.createTask(this.chunkX, this.chunkZ, () -> { ++ ChunkIOTask.this.runWriteIO(inProgressWrite); ++ }, this.priority); ++ this.currentTask = task; + } ++ task.queue(); + } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/ChunkDataController.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/ChunkDataController.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c35e0c29700be48dda3e53e7d2db224766ef17b7 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/ChunkDataController.java -@@ -0,0 +1,56 @@ -+package ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller; + -+import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; -+import ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkStorage; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.level.ChunkPos; ++ private void runWriteIO(final InProgressWrite inProgressWrite) { ++ RegionDataController.WriteData writeData = this.writeData; ++ this.writeData = null; ++ ++ boolean failedWrite = false; ++ ++ try { ++ this.regionDataController.finishWrite(this.chunkX, this.chunkZ, writeData); ++ } catch (final Throwable thr) { ++ failedWrite = thr instanceof IOException; ++ LOGGER.error("Failed to write chunk data for task: " + this.toString(), thr); ++ } ++ ++ if (!this.tryCompleteWrite(inProgressWrite, failedWrite)) { ++ // fetch new data and try again ++ this.scheduleWriteCompress(); ++ } ++ return; ++ } ++ ++ private boolean tryCompleteWrite(final InProgressWrite written, final boolean failedWrite) { ++ final long chunkKey = CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ); ++ ++ final boolean[] done = new boolean[] { false }; ++ ++ this.regionDataController.chunkTasks.compute(chunkKey, (final long keyInMap, final ChunkIOTask valueInMap) -> { ++ if (valueInMap == null) { ++ throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkIOTask.this.toString() + ", report this!"); ++ } ++ if (valueInMap != ChunkIOTask.this) { ++ throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkIOTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); ++ } ++ if (valueInMap.inProgressWrite == written) { ++ valueInMap.failedWrite = failedWrite; ++ done[0] = true; ++ // keep the data in map if we failed the write so we can try to prevent data loss ++ return failedWrite ? valueInMap : null; ++ } ++ // different data than expected, means we need to retry write ++ return valueInMap; ++ }); ++ ++ if (done[0]) { ++ this.regionDataController.endTask(this); ++ return true; ++ } ++ return false; ++ } ++ ++ @Override ++ public String toString() { ++ return "Task for world: '" + WorldUtil.getWorldName(this.world) + "' at (" + this.chunkX + "," ++ + this.chunkZ + ") type: " + this.regionDataController.type.name() + ", hash: " + this.hashCode(); ++ } ++ ++ private static final class InProgressRead { ++ ++ private static final Logger LOGGER = LoggerFactory.getLogger(InProgressRead.class); ++ ++ private CompoundTag value; ++ private Throwable throwable; ++ private final MultiThreadedQueue> callbacks = new MultiThreadedQueue<>(); ++ ++ public boolean hasNoWaiters() { ++ return this.callbacks.isEmpty(); ++ } ++ ++ public boolean addToAsyncWaiters(final BiConsumer callback) { ++ return this.callbacks.add(callback); ++ } ++ ++ public boolean cancel(final BiConsumer callback) { ++ return this.callbacks.remove(callback); ++ } ++ ++ public void complete(final ChunkIOTask task, final CompoundTag value, final Throwable throwable) { ++ this.value = value; ++ this.throwable = throwable; ++ ++ BiConsumer consumer; ++ while ((consumer = this.callbacks.pollOrBlockAdds()) != null) { ++ try { ++ consumer.accept(value == null ? null : value.copy(), throwable); ++ } catch (final Throwable thr) { ++ LOGGER.error("Callback " + ConcurrentUtil.genericToString(consumer) + " failed to handle chunk data (read) for task " + task.toString(), thr); ++ } ++ } ++ } ++ } ++ ++ private static final class InProgressWrite { ++ ++ private static final Logger LOGGER = LoggerFactory.getLogger(InProgressWrite.class); ++ ++ private CompoundTag value; ++ private Throwable throwable; ++ private volatile boolean complete; ++ private final MultiThreadedQueue> callbacks = new MultiThreadedQueue<>(); ++ ++ private final PrioritisedExecutor.PrioritisedTask writeTask; ++ ++ public InProgressWrite(final PrioritisedExecutor.PrioritisedTask writeTask) { ++ this.writeTask = writeTask; ++ } ++ ++ public boolean isComplete() { ++ return this.complete; ++ } ++ ++ public void schedule(final ChunkIOTask task, final Consumer> scheduler) { ++ scheduler.accept((final CompoundTag data, final Throwable throwable) -> { ++ InProgressWrite.this.complete(task, data, throwable); ++ }); ++ } ++ ++ public boolean addToAsyncWaiters(final BiConsumer callback) { ++ return this.callbacks.add(callback); ++ } ++ ++ public void addToWaiters(final ChunkIOTask task, final BiConsumer consumer) { ++ if (!this.callbacks.add(consumer)) { ++ this.syncAccept(task, consumer, this.value, this.throwable); ++ } ++ } ++ ++ private void syncAccept(final ChunkIOTask task, final BiConsumer consumer, final CompoundTag value, final Throwable throwable) { ++ try { ++ consumer.accept(value == null ? null : value.copy(), throwable); ++ } catch (final Throwable thr) { ++ LOGGER.error("Callback " + ConcurrentUtil.genericToString(consumer) + " failed to handle chunk data (write) for task " + task.toString(), thr); ++ } ++ } ++ ++ public void complete(final ChunkIOTask task, final CompoundTag value, final Throwable throwable) { ++ this.value = value; ++ this.throwable = throwable; ++ this.complete = true; ++ ++ task.pendingWriteComplete(this); ++ ++ BiConsumer consumer; ++ while ((consumer = this.callbacks.pollOrBlockAdds()) != null) { ++ this.syncAccept(task, consumer, value, throwable); ++ } ++ } ++ ++ public boolean cancel(final BiConsumer callback) { ++ return this.callbacks.remove(callback); ++ } ++ } ++ } ++ ++ public static abstract class RegionDataController { ++ ++ public final RegionFileType type; ++ private final PrioritisedExecutor compressionExecutor; ++ private final IOScheduler ioScheduler; ++ private final ConcurrentLong2ReferenceChainedHashTable chunkTasks = new ConcurrentLong2ReferenceChainedHashTable<>(); ++ ++ private final AtomicLong inProgressTasks = new AtomicLong(); ++ ++ public RegionDataController(final RegionFileType type, final PrioritisedExecutor ioExecutor, ++ final PrioritisedExecutor compressionExecutor) { ++ this.type = type; ++ this.compressionExecutor = compressionExecutor; ++ this.ioScheduler = new IOScheduler(ioExecutor); ++ } ++ ++ final void startTask(final ChunkIOTask task) { ++ this.inProgressTasks.getAndIncrement(); ++ } ++ ++ final void endTask(final ChunkIOTask task) { ++ this.inProgressTasks.getAndDecrement(); ++ } ++ ++ public boolean hasTasks() { ++ return this.inProgressTasks.get() != 0L; ++ } ++ ++ public long getTotalWorkingTasks() { ++ return this.inProgressTasks.get(); ++ } ++ ++ public abstract RegionFileStorage getCache(); ++ ++ public static record WriteData(CompoundTag input, WriteResult result, DataOutputStream output, IORunnable write) { ++ public static enum WriteResult { ++ WRITE, ++ DELETE; ++ } ++ } ++ ++ public abstract WriteData startWrite(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException; ++ ++ public abstract void finishWrite(final int chunkX, final int chunkZ, final WriteData writeData) throws IOException; ++ ++ public static record ReadData(ReadResult result, DataInputStream input, CompoundTag syncRead) { ++ public static enum ReadResult { ++ NO_DATA, ++ HAS_DATA, ++ SYNC_READ; ++ } ++ } ++ ++ public abstract ReadData readData(final int chunkX, final int chunkZ) throws IOException; ++ ++ // if the return value is null, then the caller needs to re-try with a new call to readData() ++ public abstract CompoundTag finishRead(final int chunkX, final int chunkZ, final ReadData readData) throws IOException; ++ ++ public static interface IORunnable { ++ ++ public void run(final RegionFile regionFile) throws IOException; ++ ++ } ++ } ++ ++ private static final class IOScheduler { ++ ++ private final ConcurrentLong2ReferenceChainedHashTable regionTasks = new ConcurrentLong2ReferenceChainedHashTable<>(); ++ private final PrioritisedExecutor executor; ++ ++ public IOScheduler(final PrioritisedExecutor executor) { ++ this.executor = executor; ++ } ++ ++ public PrioritisedExecutor.PrioritisedTask createTask(final int chunkX, final int chunkZ, ++ final Runnable run, final Priority priority) { ++ final PrioritisedExecutor.PrioritisedTask[] ret = new PrioritisedExecutor.PrioritisedTask[1]; ++ final long subOrder = this.executor.generateNextSubOrder(); ++ this.regionTasks.compute(CoordinateUtils.getChunkKey(chunkX >> REGION_FILE_SHIFT, chunkZ >> REGION_FILE_SHIFT), ++ (final long regionKey, final RegionIOTasks existing) -> { ++ final RegionIOTasks res; ++ if (existing != null) { ++ res = existing; ++ } else { ++ res = new RegionIOTasks(regionKey, IOScheduler.this); ++ } ++ ++ ret[0] = res.createTask(run, priority, subOrder); ++ ++ return res; ++ }); ++ ++ return ret[0]; ++ } ++ } ++ ++ private static final class RegionIOTasks implements Runnable { ++ ++ private static final Logger LOGGER = LoggerFactory.getLogger(RegionIOTasks.class); ++ ++ private final PrioritisedTaskQueue queue = new PrioritisedTaskQueue(); ++ private final long regionKey; ++ private final IOScheduler ioScheduler; ++ private long createdTasks; ++ private long executedTasks; ++ ++ private PrioritisedExecutor.PrioritisedTask task; ++ ++ public RegionIOTasks(final long regionKey, final IOScheduler ioScheduler) { ++ this.regionKey = regionKey; ++ this.ioScheduler = ioScheduler; ++ } ++ ++ public PrioritisedExecutor.PrioritisedTask createTask(final Runnable run, final Priority priority, ++ final long subOrder) { ++ ++this.createdTasks; ++ return new WrappedTask(this.queue.createTask(run, priority, subOrder)); ++ } ++ ++ private void adjustTaskPriority() { ++ final PrioritisedTaskQueue.PrioritySubOrderPair priority = this.queue.getHighestPrioritySubOrder(); ++ if (this.task == null) { ++ if (priority == null) { ++ return; ++ } ++ this.task = this.ioScheduler.executor.createTask(this, priority.priority(), priority.subOrder()); ++ this.task.queue(); ++ } else { ++ if (priority == null) { ++ throw new IllegalStateException(); ++ } else { ++ this.task.setPriorityAndSubOrder(priority.priority(), priority.subOrder()); ++ } ++ } ++ } ++ ++ @Override ++ public void run() { ++ final Runnable run; ++ synchronized (this) { ++ run = this.queue.pollTask(); ++ } ++ ++ try { ++ run.run(); ++ } finally { ++ synchronized (this) { ++ this.task = null; ++ this.adjustTaskPriority(); ++ } ++ this.ioScheduler.regionTasks.compute(this.regionKey, (final long keyInMap, final RegionIOTasks tasks) -> { ++ if (tasks != RegionIOTasks.this) { ++ throw new IllegalStateException("Region task mismatch"); ++ } ++ ++tasks.executedTasks; ++ if (tasks.createdTasks != tasks.executedTasks) { ++ return tasks; ++ } ++ ++ if (tasks.task != null) { ++ throw new IllegalStateException("Task may not be null when created==executed"); ++ } ++ ++ return null; ++ }); ++ } ++ } ++ ++ private final class WrappedTask implements PrioritisedExecutor.PrioritisedTask { ++ ++ private final PrioritisedExecutor.PrioritisedTask wrapped; ++ ++ public WrappedTask(final PrioritisedExecutor.PrioritisedTask wrap) { ++ this.wrapped = wrap; ++ } ++ ++ @Override ++ public PrioritisedExecutor getExecutor() { ++ return RegionIOTasks.this.ioScheduler.executor; ++ } ++ ++ @Override ++ public boolean queue() { ++ synchronized (RegionIOTasks.this) { ++ if (this.wrapped.queue()) { ++ RegionIOTasks.this.adjustTaskPriority(); ++ return true; ++ } ++ return false; ++ } ++ } ++ ++ @Override ++ public boolean isQueued() { ++ return this.wrapped.isQueued(); ++ } ++ ++ @Override ++ public boolean cancel() { ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public boolean execute() { ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public Priority getPriority() { ++ return this.wrapped.getPriority(); ++ } ++ ++ @Override ++ public boolean setPriority(final Priority priority) { ++ synchronized (RegionIOTasks.this) { ++ if (this.wrapped.setPriority(priority) && this.wrapped.isQueued()) { ++ RegionIOTasks.this.adjustTaskPriority(); ++ return true; ++ } ++ return false; ++ } ++ } ++ ++ @Override ++ public boolean raisePriority(final Priority priority) { ++ synchronized (RegionIOTasks.this) { ++ if (this.wrapped.raisePriority(priority) && this.wrapped.isQueued()) { ++ RegionIOTasks.this.adjustTaskPriority(); ++ return true; ++ } ++ return false; ++ } ++ } ++ ++ @Override ++ public boolean lowerPriority(final Priority priority) { ++ synchronized (RegionIOTasks.this) { ++ if (this.wrapped.lowerPriority(priority) && this.wrapped.isQueued()) { ++ RegionIOTasks.this.adjustTaskPriority(); ++ return true; ++ } ++ return false; ++ } ++ } ++ ++ @Override ++ public long getSubOrder() { ++ return this.wrapped.getSubOrder(); ++ } ++ ++ @Override ++ public boolean setSubOrder(final long subOrder) { ++ synchronized (RegionIOTasks.this) { ++ if (this.wrapped.setSubOrder(subOrder) && this.wrapped.isQueued()) { ++ RegionIOTasks.this.adjustTaskPriority(); ++ return true; ++ } ++ return false; ++ } ++ } ++ ++ @Override ++ public boolean raiseSubOrder(final long subOrder) { ++ synchronized (RegionIOTasks.this) { ++ if (this.wrapped.raiseSubOrder(subOrder) && this.wrapped.isQueued()) { ++ RegionIOTasks.this.adjustTaskPriority(); ++ return true; ++ } ++ return false; ++ } ++ } ++ ++ @Override ++ public boolean lowerSubOrder(final long subOrder) { ++ synchronized (RegionIOTasks.this) { ++ if (this.wrapped.lowerSubOrder(subOrder) && this.wrapped.isQueued()) { ++ RegionIOTasks.this.adjustTaskPriority(); ++ return true; ++ } ++ return false; ++ } ++ } ++ ++ @Override ++ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder) { ++ synchronized (RegionIOTasks.this) { ++ if (this.wrapped.setPriorityAndSubOrder(priority, subOrder) && this.wrapped.isQueued()) { ++ RegionIOTasks.this.adjustTaskPriority(); ++ return true; ++ } ++ return false; ++ } ++ } ++ } ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/ChunkDataController.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/ChunkDataController.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a36ab89f5c37f5f9ab0152f087bb4cf3560f8581 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/ChunkDataController.java +@@ -0,0 +1,50 @@ ++package ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller; ++ ++import ca.spottedleaf.moonrise.patches.chunk_system.io.ChunkSystemRegionFileStorage; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemChunkMap; ++import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; ++import ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkStorage; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.chunk.storage.RegionFileStorage; +import java.io.IOException; -+import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + -+public final class ChunkDataController extends RegionFileIOThread.ChunkDataController { ++public final class ChunkDataController extends MoonriseRegionFileIO.RegionDataController { + + private final ServerLevel world; + -+ public ChunkDataController(final ServerLevel world) { -+ super(RegionFileIOThread.RegionFileType.CHUNK_DATA); ++ public ChunkDataController(final ServerLevel world, final ChunkTaskScheduler taskScheduler) { ++ super(MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, taskScheduler.ioExecutor, taskScheduler.compressionExecutor); + this.world = world; + } + @@ -1855,43 +2558,37 @@ index 0000000000000000000000000000000000000000..c35e0c29700be48dda3e53e7d2db2247 + } + + @Override -+ public void writeData(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { -+ final CompletableFuture future = this.world.getChunkSource().chunkMap.write(new ChunkPos(chunkX, chunkZ), compound); ++ public WriteData startWrite(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$startWrite(chunkX, chunkZ, compound); ++ } + -+ try { -+ if (future != null) { -+ // rets non-null when sync writing (i.e. future should be completed here) -+ future.join(); -+ } -+ } catch (final CompletionException ex) { -+ if (ex.getCause() instanceof IOException ioException) { -+ throw ioException; -+ } -+ throw ex; -+ } ++ @Override ++ public void finishWrite(final int chunkX, final int chunkZ, final WriteData writeData) throws IOException { ++ ((ChunkSystemChunkMap)this.world.getChunkSource().chunkMap).moonrise$writeFinishCallback(new ChunkPos(chunkX, chunkZ)); ++ ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishWrite(chunkX, chunkZ, writeData); + } + + @Override -+ public CompoundTag readData(final int chunkX, final int chunkZ) throws IOException { -+ try { -+ return this.world.getChunkSource().chunkMap.read(new ChunkPos(chunkX, chunkZ)).join().orElse(null); -+ } catch (final CompletionException ex) { -+ if (ex.getCause() instanceof IOException ioException) { -+ throw ioException; -+ } -+ throw ex; -+ } ++ public ReadData readData(final int chunkX, final int chunkZ) throws IOException { ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$readData(chunkX, chunkZ); ++ } ++ ++ @Override ++ public CompoundTag finishRead(final int chunkX, final int chunkZ, final ReadData readData) throws IOException { ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishRead(chunkX, chunkZ, readData); + } +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/EntityDataController.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/EntityDataController.java new file mode 100644 -index 0000000000000000000000000000000000000000..fdd189ef056187941d43809c5d61cab717aecf60 +index 0000000000000000000000000000000000000000..828c868f68c2a20bf90d0f7ec253fdeb591f15f6 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/EntityDataController.java -@@ -0,0 +1,55 @@ +@@ -0,0 +1,73 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller; + -+import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.ChunkSystemRegionFileStorage; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; ++import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.chunk.storage.EntityStorage; @@ -1900,12 +2597,12 @@ index 0000000000000000000000000000000000000000..fdd189ef056187941d43809c5d61cab7 +import java.io.IOException; +import java.nio.file.Path; + -+public final class EntityDataController extends RegionFileIOThread.ChunkDataController { ++public final class EntityDataController extends MoonriseRegionFileIO.RegionDataController { + + private final EntityRegionFileStorage storage; + -+ public EntityDataController(final EntityRegionFileStorage storage) { -+ super(RegionFileIOThread.RegionFileType.ENTITY_DATA); ++ public EntityDataController(final EntityRegionFileStorage storage, final ChunkTaskScheduler taskScheduler) { ++ super(MoonriseRegionFileIO.RegionFileType.ENTITY_DATA, taskScheduler.ioExecutor, taskScheduler.compressionExecutor); + this.storage = storage; + } + @@ -1915,13 +2612,35 @@ index 0000000000000000000000000000000000000000..fdd189ef056187941d43809c5d61cab7 + } + + @Override -+ public void writeData(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { -+ this.storage.write(new ChunkPos(chunkX, chunkZ), compound); ++ public WriteData startWrite(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { ++ checkPosition(new ChunkPos(chunkX, chunkZ), compound); ++ ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$startWrite(chunkX, chunkZ, compound); ++ } ++ ++ @Override ++ public void finishWrite(final int chunkX, final int chunkZ, final WriteData writeData) throws IOException { ++ ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishWrite(chunkX, chunkZ, writeData); ++ } ++ ++ @Override ++ public ReadData readData(final int chunkX, final int chunkZ) throws IOException { ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$readData(chunkX, chunkZ); + } + + @Override -+ public CompoundTag readData(final int chunkX, final int chunkZ) throws IOException { -+ return this.storage.read(new ChunkPos(chunkX, chunkZ)); ++ public CompoundTag finishRead(final int chunkX, final int chunkZ, final ReadData readData) throws IOException { ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishRead(chunkX, chunkZ, readData); ++ } ++ ++ private static void checkPosition(final ChunkPos pos, final CompoundTag nbt) { ++ final ChunkPos nbtPos = nbt == null ? null : EntityStorage.readChunkPos(nbt); ++ if (nbtPos != null && !pos.equals(nbtPos)) { ++ throw new IllegalArgumentException( ++ "Entity chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + pos.toString() ++ + " but compound says coordinate is " + nbtPos ++ ); ++ } + } + + public static final class EntityRegionFileStorage extends RegionFileStorage { @@ -1933,38 +2652,34 @@ index 0000000000000000000000000000000000000000..fdd189ef056187941d43809c5d61cab7 + + @Override + public void write(final ChunkPos pos, final CompoundTag nbt) throws IOException { -+ final ChunkPos nbtPos = nbt == null ? null : EntityStorage.readChunkPos(nbt); -+ if (nbtPos != null && !pos.equals(nbtPos)) { -+ throw new IllegalArgumentException( -+ "Entity chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + pos.toString() -+ + " but compound says coordinate is " + nbtPos + " for world: " + this -+ ); -+ } ++ checkPosition(pos, nbt); + super.write(pos, nbt); + } + } +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/PoiDataController.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/PoiDataController.java new file mode 100644 -index 0000000000000000000000000000000000000000..af867f8fedd0bb8f675e94243aa1a3f17363483b +index 0000000000000000000000000000000000000000..bd0d782852f9cfe5bc0b5339ecf4d82c10332ec9 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/PoiDataController.java -@@ -0,0 +1,33 @@ +@@ -0,0 +1,45 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller; + -+import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.ChunkSystemRegionFileStorage; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; +import ca.spottedleaf.moonrise.patches.chunk_system.level.storage.ChunkSystemSectionStorage; ++import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.chunk.storage.RegionFileStorage; +import java.io.IOException; + -+public final class PoiDataController extends RegionFileIOThread.ChunkDataController { ++public final class PoiDataController extends MoonriseRegionFileIO.RegionDataController { + + private final ServerLevel world; + -+ public PoiDataController(final ServerLevel world) { -+ super(RegionFileIOThread.RegionFileType.POI_DATA); ++ public PoiDataController(final ServerLevel world, final ChunkTaskScheduler taskScheduler) { ++ super(MoonriseRegionFileIO.RegionFileType.POI_DATA, taskScheduler.ioExecutor, taskScheduler.compressionExecutor); + this.world = world; + } + @@ -1974,23 +2689,50 @@ index 0000000000000000000000000000000000000000..af867f8fedd0bb8f675e94243aa1a3f1 + } + + @Override -+ public void writeData(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { -+ ((ChunkSystemSectionStorage)this.world.getPoiManager()).moonrise$write(chunkX, chunkZ, compound); ++ public WriteData startWrite(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$startWrite(chunkX, chunkZ, compound); ++ } ++ ++ @Override ++ public void finishWrite(final int chunkX, final int chunkZ, final WriteData writeData) throws IOException { ++ ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishWrite(chunkX, chunkZ, writeData); ++ } ++ ++ @Override ++ public ReadData readData(final int chunkX, final int chunkZ) throws IOException { ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$readData(chunkX, chunkZ); + } + + @Override -+ public CompoundTag readData(final int chunkX, final int chunkZ) throws IOException { -+ return ((ChunkSystemSectionStorage)this.world.getPoiManager()).moonrise$read(chunkX, chunkZ); ++ public CompoundTag finishRead(final int chunkX, final int chunkZ, final ReadData readData) throws IOException { ++ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishRead(chunkX, chunkZ, readData); + } +} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemChunkMap.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemChunkMap.java +new file mode 100644 +index 0000000000000000000000000000000000000000..47a4d3376d08dde94a39254bec21473ff27f53e6 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemChunkMap.java +@@ -0,0 +1,10 @@ ++package ca.spottedleaf.moonrise.patches.chunk_system.level; ++ ++import net.minecraft.world.level.ChunkPos; ++import java.io.IOException; ++ ++public interface ChunkSystemChunkMap { ++ ++ public void moonrise$writeFinishCallback(final ChunkPos pos) throws IOException; ++ ++} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemLevel.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemLevel.java new file mode 100644 -index 0000000000000000000000000000000000000000..efcd9057f008f0b9cf0d22b2b21d1851205841e5 +index 0000000000000000000000000000000000000000..5d4d650186b18eb00782429d53d861564d8e4ba9 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemLevel.java -@@ -0,0 +1,22 @@ +@@ -0,0 +1,33 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level; + ++import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.LevelChunk; @@ -2010,6 +2752,16 @@ index 0000000000000000000000000000000000000000..efcd9057f008f0b9cf0d22b2b21d1851 + + public void moonrise$midTickTasks(); + ++ public ChunkData moonrise$getChunkData(final long chunkKey); ++ ++ public ChunkData moonrise$getChunkData(final int chunkX, final int chunkZ); ++ ++ public ChunkData moonrise$requestChunkData(final long chunkKey); ++ ++ public ChunkData moonrise$releaseChunkData(final long chunkKey); ++ ++ public boolean moonrise$areChunksLoaded(final int fromX, final int fromZ, final int toX, final int toZ); ++ +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemLevelReader.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemLevelReader.java new file mode 100644 @@ -2029,19 +2781,20 @@ index 0000000000000000000000000000000000000000..0b58701342d573fa43cdd06681534854 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java new file mode 100644 -index 0000000000000000000000000000000000000000..b8a87b7e6505feb76ce1bd58c84615256cf6faa6 +index 0000000000000000000000000000000000000000..9d46482476f9ed9032a2b0f89afc20e03ed42dbb --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java -@@ -0,0 +1,61 @@ +@@ -0,0 +1,64 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level; + -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.util.Priority; +import ca.spottedleaf.moonrise.common.list.ReferenceList; +import ca.spottedleaf.moonrise.common.misc.NearbyPlayers; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; +import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; +import net.minecraft.core.BlockPos; ++import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ServerChunkCache; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.status.ChunkStatus; @@ -2052,32 +2805,34 @@ index 0000000000000000000000000000000000000000..b8a87b7e6505feb76ce1bd58c8461525 + + public ChunkTaskScheduler moonrise$getChunkTaskScheduler(); + -+ public RegionFileIOThread.ChunkDataController moonrise$getChunkDataController(); ++ public MoonriseRegionFileIO.RegionDataController moonrise$getChunkDataController(); + -+ public RegionFileIOThread.ChunkDataController moonrise$getPoiChunkDataController(); ++ public MoonriseRegionFileIO.RegionDataController moonrise$getPoiChunkDataController(); + -+ public RegionFileIOThread.ChunkDataController moonrise$getEntityChunkDataController(); ++ public MoonriseRegionFileIO.RegionDataController moonrise$getEntityChunkDataController(); + + public int moonrise$getRegionChunkShift(); + -+ // Paper - marked closing not needed on CB ++ public boolean moonrise$isMarkedClosing(); ++ ++ public void moonrise$setMarkedClosing(final boolean value); + + public RegionizedPlayerChunkLoader moonrise$getPlayerChunkLoader(); + + public void moonrise$loadChunksAsync(final BlockPos pos, final int radiusBlocks, -+ final PrioritisedExecutor.Priority priority, ++ final Priority priority, + final Consumer> onLoad); + + public void moonrise$loadChunksAsync(final BlockPos pos, final int radiusBlocks, -+ final ChunkStatus chunkStatus, final PrioritisedExecutor.Priority priority, ++ final ChunkStatus chunkStatus, final Priority priority, + final Consumer> onLoad); + + public void moonrise$loadChunksAsync(final int minChunkX, final int maxChunkX, final int minChunkZ, final int maxChunkZ, -+ final PrioritisedExecutor.Priority priority, ++ final Priority priority, + final Consumer> onLoad); + + public void moonrise$loadChunksAsync(final int minChunkX, final int maxChunkX, final int minChunkZ, final int maxChunkZ, -+ final ChunkStatus chunkStatus, final PrioritisedExecutor.Priority priority, ++ final ChunkStatus chunkStatus, final Priority priority, + final Consumer> onLoad); + + public RegionizedPlayerChunkLoader.ViewDistanceHolder moonrise$getViewDistanceHolder(); @@ -2094,6 +2849,33 @@ index 0000000000000000000000000000000000000000..b8a87b7e6505feb76ce1bd58c8461525 + + public ReferenceList moonrise$getEntityTickingChunks(); +} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkData.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkData.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8b9dc582627b46843f4b5ea6f8c3df2d8cac46fa +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkData.java +@@ -0,0 +1,21 @@ ++package ca.spottedleaf.moonrise.patches.chunk_system.level.chunk; ++ ++import ca.spottedleaf.moonrise.common.misc.NearbyPlayers; ++ ++public final class ChunkData { ++ ++ private int referenceCount = 0; ++ public NearbyPlayers.TrackedChunk nearbyPlayers; // Moonrise - nearby players ++ ++ public ChunkData() { ++ ++ } ++ ++ public int increaseRef() { ++ return ++this.referenceCount; ++ } ++ ++ public int decreaseRef() { ++ return --this.referenceCount; ++ } ++} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemChunkHolder.java new file mode 100644 index 0000000000000000000000000000000000000000..7d049d750df88762566f13a9c4fc7574a2df4825 @@ -2160,18 +2942,21 @@ index 0000000000000000000000000000000000000000..f4bc44bb266763345c4e6f859c89352c +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemDistanceManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemDistanceManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..883fe6401f1b9711fa544d18a815b4d638f580df +index 0000000000000000000000000000000000000000..aacd543f03b35908011d0c2891e978cc093ebcf5 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemDistanceManager.java -@@ -0,0 +1,9 @@ +@@ -0,0 +1,12 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.chunk; + ++import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager; +import net.minecraft.server.level.ChunkMap; + +public interface ChunkSystemDistanceManager { + + public ChunkMap moonrise$getChunkMap(); + ++ public ChunkHolderManager moonrise$getChunkHolderManager(); ++ +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemLevelChunk.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemLevelChunk.java new file mode 100644 @@ -2194,13 +2979,15 @@ index 0000000000000000000000000000000000000000..5b092bca7027e37aeee8f4b852ad896d +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java new file mode 100644 -index 0000000000000000000000000000000000000000..997b05167c19472acb98edac32d4548cc65efa8e +index 0000000000000000000000000000000000000000..5ed6599d1f9a2edf8c904f3602b06d26d857600c --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -@@ -0,0 +1,819 @@ +@@ -0,0 +1,798 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.entity; + ++import ca.spottedleaf.moonrise.common.PlatformHooks; +import ca.spottedleaf.moonrise.common.list.EntityList; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; +import ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity; +import com.google.common.collect.ImmutableList; +import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; @@ -2213,6 +3000,7 @@ index 0000000000000000000000000000000000000000..997b05167c19472acb98edac32d4548c +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; ++import net.minecraft.world.entity.EntitySpawnReason; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.boss.EnderDragonPart; +import net.minecraft.world.entity.boss.enderdragon.EnderDragon; @@ -2226,7 +3014,6 @@ index 0000000000000000000000000000000000000000..997b05167c19472acb98edac32d4548c +import java.util.Iterator; +import java.util.List; +import java.util.function.Predicate; -+import org.bukkit.event.entity.EntityRemoveEvent; + +public final class ChunkEntitySlices { + @@ -2243,6 +3030,7 @@ index 0000000000000000000000000000000000000000..997b05167c19472acb98edac32d4548c + private final EntityList entities = new EntityList(); + + public FullChunkStatus status; ++ public final ChunkData chunkData; + + private boolean isTransient; + @@ -2255,7 +3043,7 @@ index 0000000000000000000000000000000000000000..997b05167c19472acb98edac32d4548c + } + + public ChunkEntitySlices(final Level world, final int chunkX, final int chunkZ, final FullChunkStatus status, -+ final int minSection, final int maxSection) { // inclusive, inclusive ++ final ChunkData chunkData, final int minSection, final int maxSection) { // inclusive, inclusive + this.minSection = minSection; + this.maxSection = maxSection; + this.chunkX = chunkX; @@ -2268,11 +3056,12 @@ index 0000000000000000000000000000000000000000..997b05167c19472acb98edac32d4548c + this.entitiesByType = new Reference2ObjectOpenHashMap<>(); + + this.status = status; ++ this.chunkData = chunkData; + } + + public static List readEntities(final ServerLevel world, final CompoundTag compoundTag) { + // TODO check this and below on update for format changes -+ return EntityType.loadEntitiesRecursive(compoundTag.getList("Entities", 10), world).collect(ImmutableList.toImmutableList()); ++ return EntityType.loadEntitiesRecursive(compoundTag.getList("Entities", 10), world, EntitySpawnReason.LOAD).collect(ImmutableList.toImmutableList()); + } + + // Paper start - rewrite chunk system @@ -2300,7 +3089,7 @@ index 0000000000000000000000000000000000000000..997b05167c19472acb98edac32d4548c + } + + final ListTag entitiesTag = new ListTag(); -+ for (final Entity entity : entities) { ++ for (final Entity entity : PlatformHooks.get().modifySavedEntities(world, chunkPos.x, chunkPos.z, entities)) { + CompoundTag compoundTag = new CompoundTag(); + if (entity.save(compoundTag)) { + entitiesTag.add(compoundTag); @@ -2347,12 +3136,12 @@ index 0000000000000000000000000000000000000000..997b05167c19472acb98edac32d4548c + continue; + } + if (entity.shouldBeSaved()) { -+ entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, EntityRemoveEvent.Cause.UNLOAD); ++ PlatformHooks.get().unloadEntity(entity); + if (entity.isVehicle()) { + // we cannot assume that these entities are contained within this chunk, because entities can + // desync - so we need to remove them all + for (final Entity passenger : entity.getIndirectPassengers()) { -+ passenger.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, EntityRemoveEvent.Cause.UNLOAD); ++ PlatformHooks.get().unloadEntity(passenger); + } + } + } @@ -2361,34 +3150,7 @@ index 0000000000000000000000000000000000000000..997b05167c19472acb98edac32d4548c + return this.entities.size() != 0; + } + -+ // Paper start -+ public org.bukkit.entity.Entity[] getChunkEntities() { -+ List ret = new java.util.ArrayList<>(); -+ final Entity[] entities = this.entities.getRawData(); -+ for (int i = 0, size = Math.min(entities.length, this.entities.size()); i < size; ++i) { -+ final Entity entity = entities[i]; -+ if (entity == null) { -+ continue; -+ } -+ final org.bukkit.entity.Entity bukkit = entity.getBukkitEntity(); -+ if (bukkit != null && bukkit.isValid()) { -+ ret.add(bukkit); -+ } -+ } -+ -+ return ret.toArray(new org.bukkit.entity.Entity[0]); -+ } -+ -+ public void callEntitiesLoadEvent() { -+ org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesLoadEvent(this.world, new ChunkPos(this.chunkX, this.chunkZ), this.getAllEntities()); -+ } -+ -+ public void callEntitiesUnloadEvent() { -+ org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesUnloadEvent(this.world, new ChunkPos(this.chunkX, this.chunkZ), this.getAllEntities()); -+ } -+ // Paper end -+ -+ private List getAllEntities() { ++ public List getAllEntities() { + final int len = this.entities.size(); + if (len == 0) { + return new ArrayList<>(); @@ -2451,6 +3213,7 @@ index 0000000000000000000000000000000000000000..997b05167c19472acb98edac32d4548c + return false; + } + ((ChunkSystemEntity)entity).moonrise$setChunkStatus(this.status); ++ ((ChunkSystemEntity)entity).moonrise$setChunkData(this.chunkData); + final int sectionIndex = chunkSection - this.minSection; + + this.allEntities.addEntity(entity, sectionIndex); @@ -2484,6 +3247,7 @@ index 0000000000000000000000000000000000000000..997b05167c19472acb98edac32d4548c + return false; + } + ((ChunkSystemEntity)entity).moonrise$setChunkStatus(null); ++ ((ChunkSystemEntity)entity).moonrise$setChunkData(null); + final int sectionIndex = chunkSection - this.minSection; + + this.allEntities.removeEntity(entity, sectionIndex); @@ -3019,7 +3783,7 @@ index 0000000000000000000000000000000000000000..997b05167c19472acb98edac32d4548c +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java new file mode 100644 -index 0000000000000000000000000000000000000000..efc0c1acc8239dd7b00211a1d3bfd3fc3b2c810c +index 0000000000000000000000000000000000000000..93335de8cf514dc8417e4b9b2d495663deda2904 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java @@ -0,0 +1,1083 @@ @@ -3071,8 +3835,6 @@ index 0000000000000000000000000000000000000000..efc0c1acc8239dd7b00211a1d3bfd3fc + + protected final SWMRLong2ObjectHashTable regions = new SWMRLong2ObjectHashTable<>(128, 0.5f); + -+ protected final int minSection; // inclusive -+ protected final int maxSection; // inclusive + protected final LevelCallback worldCallback; + + protected final ConcurrentLong2ReferenceChainedHashTable entityById = new ConcurrentLong2ReferenceChainedHashTable<>(); @@ -3081,8 +3843,6 @@ index 0000000000000000000000000000000000000000..efc0c1acc8239dd7b00211a1d3bfd3fc + + public EntityLookup(final Level world, final LevelCallback worldCallback) { + this.world = world; -+ this.minSection = WorldUtil.getMinSection(world); -+ this.maxSection = WorldUtil.getMaxSection(world); + this.worldCallback = worldCallback; + } + @@ -3116,7 +3876,7 @@ index 0000000000000000000000000000000000000000..efc0c1acc8239dd7b00211a1d3bfd3fc + + protected abstract void entityEndTicking(final Entity entity); + -+ protected abstract boolean screenEntity(final Entity entity); ++ protected abstract boolean screenEntity(final Entity entity, final boolean fromDisk, final boolean event); + + private static Entity maskNonAccessible(final Entity entity) { + if (entity == null) { @@ -3372,7 +4132,7 @@ index 0000000000000000000000000000000000000000..efc0c1acc8239dd7b00211a1d3bfd3fc + } + + protected void addRecursivelySafe(final Entity root, final boolean fromDisk) { -+ if (!this.addEntity(root, fromDisk)) { ++ if (!this.addEntity(root, fromDisk, true)) { + // possible we are a passenger, and so should dismount from any valid entity in the world + root.stopRiding(); + return; @@ -3411,7 +4171,11 @@ index 0000000000000000000000000000000000000000..efc0c1acc8239dd7b00211a1d3bfd3fc + } + + public boolean addNewEntity(final Entity entity) { -+ return this.addEntity(entity, false); ++ return this.addNewEntity(entity, true); ++ } ++ ++ public boolean addNewEntity(final Entity entity, final boolean event) { ++ return this.addEntity(entity, false, event); + } + + public static Visibility getEntityStatus(final Entity entity) { @@ -3422,10 +4186,10 @@ index 0000000000000000000000000000000000000000..efc0c1acc8239dd7b00211a1d3bfd3fc + return Visibility.fromFullChunkStatus(entityStatus == null ? FullChunkStatus.INACCESSIBLE : entityStatus); + } + -+ protected boolean addEntity(final Entity entity, final boolean fromDisk) { ++ protected boolean addEntity(final Entity entity, final boolean fromDisk, final boolean event) { + final BlockPos pos = entity.blockPosition(); + final int sectionX = pos.getX() >> 4; -+ final int sectionY = Mth.clamp(pos.getY() >> 4, this.minSection, this.maxSection); ++ final int sectionY = Mth.clamp(pos.getY() >> 4, WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world)); + final int sectionZ = pos.getZ() >> 4; + this.checkThread(sectionX, sectionZ, "Cannot add entity off-main thread"); + @@ -3439,7 +4203,7 @@ index 0000000000000000000000000000000000000000..efc0c1acc8239dd7b00211a1d3bfd3fc + return false; + } + -+ if (!this.screenEntity(entity)) { ++ if (!this.screenEntity(entity, fromDisk, event)) { + return false; + } + @@ -3544,7 +4308,7 @@ index 0000000000000000000000000000000000000000..efc0c1acc8239dd7b00211a1d3bfd3fc + final int sectionZ = ((ChunkSystemEntity)entity).moonrise$getSectionZ(); + final BlockPos newPos = entity.blockPosition(); + final int newSectionX = newPos.getX() >> 4; -+ final int newSectionY = Mth.clamp(newPos.getY() >> 4, this.minSection, this.maxSection); ++ final int newSectionY = Mth.clamp(newPos.getY() >> 4, WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world)); + final int newSectionZ = newPos.getZ() >> 4; + + if (newSectionX == sectionX && newSectionY == sectionY && newSectionZ == sectionZ) { @@ -3984,7 +4748,7 @@ index 0000000000000000000000000000000000000000..efc0c1acc8239dd7b00211a1d3bfd3fc + + public ChunkEntitySlices getOrCreateChunk(final int chunkX, final int chunkZ) { + final ChunkSlicesRegion region = this.getRegion(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT); -+ ChunkEntitySlices ret; ++ final ChunkEntitySlices ret; + if (region == null || (ret = region.get((chunkX & REGION_MASK) | ((chunkZ & REGION_MASK) << REGION_SHIFT))) == null) { + return this.createEntityChunk(chunkX, chunkZ, true); + } @@ -4082,7 +4846,7 @@ index 0000000000000000000000000000000000000000..efc0c1acc8239dd7b00211a1d3bfd3fc + @Override + public void onRemove(final Entity.RemovalReason reason) { + final Entity entity = this.entity; -+ EntityLookup.this.checkThread(entity, "Cannot remove entity off-main"); // Paper - rewrite chunk system ++ EntityLookup.this.checkThread(entity, "Cannot remove entity off-main"); + final Visibility tickingState = EntityLookup.getEntityStatus(entity); + + EntityLookup.this.removeEntity(entity); @@ -4106,15 +4870,15 @@ index 0000000000000000000000000000000000000000..efc0c1acc8239dd7b00211a1d3bfd3fc + public void onRemove(final Entity.RemovalReason reason) {} + } +} -\ No newline at end of file diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java new file mode 100644 -index 0000000000000000000000000000000000000000..edcde00206d068bd79175fea33efa05b0e8c1562 +index 0000000000000000000000000000000000000000..a038215156a163b0b1cbc870ada5b4ac85ed1335 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java -@@ -0,0 +1,123 @@ +@@ -0,0 +1,129 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.entity.client; + ++import ca.spottedleaf.moonrise.common.PlatformHooks; +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +import ca.spottedleaf.moonrise.common.util.WorldUtil; +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; @@ -4160,7 +4924,8 @@ index 0000000000000000000000000000000000000000..edcde00206d068bd79175fea33efa05b + + final ChunkEntitySlices ret = new ChunkEntitySlices( + this.world, chunkX, chunkZ, -+ ticking ? FullChunkStatus.ENTITY_TICKING : FullChunkStatus.FULL, WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) ++ ticking ? FullChunkStatus.ENTITY_TICKING : FullChunkStatus.FULL, null, ++ WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) + ); + + // note: not handled by superclass @@ -4178,7 +4943,11 @@ index 0000000000000000000000000000000000000000..edcde00206d068bd79175fea33efa05b + protected void entitySectionChangeCallback(final Entity entity, + final int oldSectionX, final int oldSectionY, final int oldSectionZ, + final int newSectionX, final int newSectionY, final int newSectionZ) { -+ ++ PlatformHooks.get().entityMove( ++ entity, ++ CoordinateUtils.getChunkSectionKey(oldSectionX, oldSectionY, oldSectionZ), ++ CoordinateUtils.getChunkSectionKey(newSectionX, newSectionY, newSectionZ) ++ ); + } + + @Override @@ -4212,7 +4981,7 @@ index 0000000000000000000000000000000000000000..edcde00206d068bd79175fea33efa05b + } + + @Override -+ protected boolean screenEntity(final Entity entity) { ++ protected boolean screenEntity(final Entity entity, final boolean fromDisk, final boolean event) { + return true; + } + @@ -4238,7 +5007,7 @@ index 0000000000000000000000000000000000000000..edcde00206d068bd79175fea33efa05b +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java new file mode 100644 -index 0000000000000000000000000000000000000000..465469e44346c50f30f3abd6b44f4173ccfcf248 +index 0000000000000000000000000000000000000000..2ff58cf753c60913ee73aae015182e9c5560d529 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java @@ -0,0 +1,114 @@ @@ -4276,7 +5045,7 @@ index 0000000000000000000000000000000000000000..465469e44346c50f30f3abd6b44f4173 + protected ChunkEntitySlices createEntityChunk(final int chunkX, final int chunkZ, final boolean transientChunk) { + final ChunkEntitySlices ret = new ChunkEntitySlices( + this.world, chunkX, chunkZ, FullChunkStatus.FULL, -+ WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) ++ null, WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) + ); + + // note: not handled by superclass @@ -4328,7 +5097,7 @@ index 0000000000000000000000000000000000000000..465469e44346c50f30f3abd6b44f4173 + } + + @Override -+ protected boolean screenEntity(final Entity entity) { ++ protected boolean screenEntity(final Entity entity, final boolean fromDisk, final boolean event) { + return true; + } + @@ -4358,13 +5127,15 @@ index 0000000000000000000000000000000000000000..465469e44346c50f30f3abd6b44f4173 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java new file mode 100644 -index 0000000000000000000000000000000000000000..dacf2b2988ce603879fe525a3418ac77f8a663f7 +index 0000000000000000000000000000000000000000..58d9187adc188b693b6becc400f766e069bf1bf5 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java -@@ -0,0 +1,113 @@ +@@ -0,0 +1,116 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server; + ++import ca.spottedleaf.moonrise.common.PlatformHooks; +import ca.spottedleaf.moonrise.common.list.ReferenceList; ++import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +import ca.spottedleaf.moonrise.common.util.TickThread; +import ca.spottedleaf.moonrise.common.util.ChunkSystem; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; @@ -4381,7 +5152,6 @@ index 0000000000000000000000000000000000000000..dacf2b2988ce603879fe525a3418ac77 + + private final ServerLevel serverWorld; + public final ReferenceList trackerEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY); // Moonrise - entity tracker -+ public final ReferenceList trackerUnloadedEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY); // Moonrise - entity tracker + + public ServerEntityLookup(final ServerLevel world, final LevelCallback worldCallback) { + super(world, worldCallback); @@ -4427,6 +5197,11 @@ index 0000000000000000000000000000000000000000..dacf2b2988ce603879fe525a3418ac77 + if (entity instanceof ServerPlayer player) { + ((ChunkSystemServerLevel)this.serverWorld).moonrise$getNearbyPlayers().tickPlayer(player); + } ++ PlatformHooks.get().entityMove( ++ entity, ++ CoordinateUtils.getChunkSectionKey(oldSectionX, oldSectionY, oldSectionZ), ++ CoordinateUtils.getChunkSectionKey(newSectionX, newSectionY, newSectionZ) ++ ); + } + + @Override @@ -4441,14 +5216,12 @@ index 0000000000000000000000000000000000000000..dacf2b2988ce603879fe525a3418ac77 + if (entity instanceof ServerPlayer player) { + ((ChunkSystemServerLevel)this.serverWorld).moonrise$getNearbyPlayers().removePlayer(player); + } -+ this.trackerUnloadedEntities.remove(entity); // Moonrise - entity tracker + } + + @Override + protected void entityStartLoaded(final Entity entity) { + // Moonrise start - entity tracker + this.trackerEntities.add(entity); -+ this.trackerUnloadedEntities.remove(entity); + // Moonrise end - entity tracker + } + @@ -4456,7 +5229,6 @@ index 0000000000000000000000000000000000000000..dacf2b2988ce603879fe525a3418ac77 + protected void entityEndLoaded(final Entity entity) { + // Moonrise start - entity tracker + this.trackerEntities.remove(entity); -+ this.trackerUnloadedEntities.add(entity); + // Moonrise end - entity tracker + } + @@ -4471,8 +5243,8 @@ index 0000000000000000000000000000000000000000..dacf2b2988ce603879fe525a3418ac77 + } + + @Override -+ protected boolean screenEntity(final Entity entity) { -+ return ChunkSystem.screenEntity(this.serverWorld, entity); ++ protected boolean screenEntity(final Entity entity, final boolean fromDisk, final boolean event) { ++ return ChunkSystem.screenEntity(this.serverWorld, entity, fromDisk, event); + } +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/ChunkSystemPoiManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/ChunkSystemPoiManager.java @@ -4518,16 +5290,15 @@ index 0000000000000000000000000000000000000000..89b956b8fdf1a0d862a843104511005e +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java new file mode 100644 -index 0000000000000000000000000000000000000000..fd35e4db0c8fec8f86b8743bcc2b15ed2e7433f1 +index 0000000000000000000000000000000000000000..bbf9d6c1c9525d97160806819a57be03eca290f1 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java -@@ -0,0 +1,212 @@ +@@ -0,0 +1,204 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.poi; + +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +import ca.spottedleaf.moonrise.common.util.TickThread; +import ca.spottedleaf.moonrise.common.util.WorldUtil; -+import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import net.minecraft.SharedConstants; +import net.minecraft.nbt.CompoundTag; @@ -4647,7 +5418,6 @@ index 0000000000000000000000000000000000000000..fd35e4db0c8fec8f86b8743bcc2b15ed + ret.putInt("DataVersion", SharedConstants.getCurrentVersion().getDataVersion().getVersion()); + + final ServerLevel world = this.world; -+ final PoiManager poiManager = world.getPoiManager(); + final int chunkX = this.chunkX; + final int chunkZ = this.chunkZ; + @@ -4657,13 +5427,8 @@ index 0000000000000000000000000000000000000000..fd35e4db0c8fec8f86b8743bcc2b15ed + continue; + } + -+ final long key = CoordinateUtils.getChunkSectionKey(chunkX, sectionY, chunkZ); -+ // codecs are honestly such a fucking disaster. What the fuck is this trash? -+ final Codec codec = PoiSection.codec(() -> { -+ poiManager.setDirty(key); -+ }); -+ -+ final DataResult serializedResult = codec.encodeStart(registryOps, section); ++ // I do not believe asynchronously converting to CompoundTag is worth the scheduling. ++ final DataResult serializedResult = PoiSection.Packed.CODEC.encodeStart(registryOps, section.pack()); + final int finalSectionY = sectionY; + final Tag serialized = serializedResult.resultOrPartial((final String description) -> { + LOGGER.error("Failed to serialize poi chunk for world: " + WorldUtil.getWorldName(world) + ", chunk: (" + chunkX + "," + finalSectionY + "," + chunkZ + "); description: " + description); @@ -4707,19 +5472,18 @@ index 0000000000000000000000000000000000000000..fd35e4db0c8fec8f86b8743bcc2b15ed + continue; + } + -+ final long coordinateKey = CoordinateUtils.getChunkSectionKey(chunkX, sectionY, chunkZ); -+ // codecs are honestly such a fucking disaster. What the fuck is this trash? -+ final Codec codec = PoiSection.codec(() -> { -+ poiManager.setDirty(coordinateKey); -+ }); -+ + final CompoundTag section = sections.getCompound(key); -+ final DataResult deserializeResult = codec.parse(registryOps, section); ++ final DataResult deserializeResult = PoiSection.Packed.CODEC.parse(registryOps, section); + final int finalSectionY = sectionY; -+ final PoiSection deserialized = deserializeResult.resultOrPartial((final String description) -> { ++ final PoiSection.Packed packed = deserializeResult.resultOrPartial((final String description) -> { + LOGGER.error("Failed to deserialize poi chunk for world: " + WorldUtil.getWorldName(world) + ", chunk: (" + chunkX + "," + finalSectionY + "," + chunkZ + "); description: " + description); + }).orElse(null); + ++ final long coordinateKey = CoordinateUtils.getChunkSectionKey(chunkX, sectionY, chunkZ); ++ final PoiSection deserialized = packed == null ? null : packed.unpack(() -> { ++ poiManager.setDirty(coordinateKey); ++ }); ++ + if (deserialized == null || ((ChunkSystemPoiSection)deserialized).moonrise$isEmpty()) { + // completely empty, no point in storing this + continue; @@ -4736,19 +5500,15 @@ index 0000000000000000000000000000000000000000..fd35e4db0c8fec8f86b8743bcc2b15ed +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java new file mode 100644 -index 0000000000000000000000000000000000000000..fb87d7ece6ebccfd0ffd2f1a609b45a0d2461d9e +index 0000000000000000000000000000000000000000..524752744e37a2db0e3ea089468bdf497129bfef --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java -@@ -0,0 +1,17 @@ +@@ -0,0 +1,13 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.storage; + -+import com.mojang.serialization.Dynamic; +import net.minecraft.nbt.CompoundTag; -+import net.minecraft.nbt.Tag; +import net.minecraft.world.level.chunk.storage.RegionFileStorage; +import java.io.IOException; -+import java.util.Optional; -+import java.util.concurrent.CompletableFuture; + +public interface ChunkSystemSectionStorage { + @@ -4780,14 +5540,15 @@ index 0000000000000000000000000000000000000000..003a857e70ead858e8437e3c1bfaf22f +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java new file mode 100644 -index 0000000000000000000000000000000000000000..852d75a73dae7448cbe1e2f5e164b235efa8a969 +index 0000000000000000000000000000000000000000..b2fa9883aefb07f64bb5db7e0052218d2ad09aba --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -@@ -0,0 +1,1082 @@ +@@ -0,0 +1,1085 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.player; + -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.PlatformHooks; +import ca.spottedleaf.moonrise.common.misc.AllocatingRateLimiter; +import ca.spottedleaf.moonrise.common.misc.SingleUserAreaMap; +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; @@ -5198,7 +5959,11 @@ index 0000000000000000000000000000000000000000..852d75a73dae7448cbe1e2f5e164b235 + if (this.sentChunks.add(CoordinateUtils.getChunkKey(chunkX, chunkZ))) { + ((ChunkSystemChunkHolder)((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager + .getChunkHolder(chunkX, chunkZ).vanillaChunkHolder).moonrise$addReceivedChunk(this.player); -+ PlayerChunkSender.sendChunk(this.player.connection, this.world, ((ChunkSystemLevel)this.world).moonrise$getFullChunkIfLoaded(chunkX, chunkZ)); ++ ++ final LevelChunk chunk = ((ChunkSystemLevel)this.world).moonrise$getFullChunkIfLoaded(chunkX, chunkZ); ++ ++ PlatformHooks.get().onChunkWatch(this.world, chunk, this.player); ++ PlayerChunkSender.sendChunk(this.player.connection, this.world, chunk); + return; + } + throw new IllegalStateException(); @@ -5212,17 +5977,12 @@ index 0000000000000000000000000000000000000000..852d75a73dae7448cbe1e2f5e164b235 + } + + private void sendUnloadChunkRaw(final int chunkX, final int chunkZ) { ++ PlatformHooks.get().onChunkUnWatch(this.world, new ChunkPos(chunkX, chunkZ), this.player); + // Note: Check PlayerChunkSender#dropChunk for other logic + // Note: drop isAlive() check so that chunks properly unload client-side when the player dies + ((ChunkSystemChunkHolder)((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager + .getChunkHolder(chunkX, chunkZ).vanillaChunkHolder).moonrise$removeReceivedChunk(this.player); -+ final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); -+ this.player.connection.send(new ClientboundForgetLevelChunkPacket(chunkPos)); -+ // Paper start - PlayerChunkUnloadEvent -+ if (io.papermc.paper.event.packet.PlayerChunkUnloadEvent.getHandlerList().getRegisteredListeners().length > 0) { -+ new io.papermc.paper.event.packet.PlayerChunkUnloadEvent(this.world.getWorld().getChunkAt(chunkPos.longKey), this.player.getBukkitEntity()).callEvent(); -+ } -+ // Paper end - PlayerChunkUnloadEvent ++ this.player.connection.send(new ClientboundForgetLevelChunkPacket(new ChunkPos(chunkX, chunkZ))); + } + + private final SingleUserAreaMap broadcastMap = new SingleUserAreaMap<>(this) { @@ -5315,7 +6075,7 @@ index 0000000000000000000000000000000000000000..852d75a73dae7448cbe1e2f5e164b235 + final int playerSendViewDistance, final int worldSendViewDistance) { + return Math.min( + loadViewDistance - 1, -+ playerSendViewDistance < 0 ? (!io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.autoConfigSendDistance || clientViewDistance < 0 ? (worldSendViewDistance < 0 ? (loadViewDistance - 1) : worldSendViewDistance) : clientViewDistance + 1) : playerSendViewDistance ++ playerSendViewDistance < 0 ? (!PlatformHooks.get().configAutoConfigSendDistance() || clientViewDistance < 0 ? (worldSendViewDistance < 0 ? (loadViewDistance - 1) : worldSendViewDistance) : clientViewDistance + 1) : playerSendViewDistance + ); + } + @@ -5340,26 +6100,26 @@ index 0000000000000000000000000000000000000000..852d75a73dae7448cbe1e2f5e164b235 + } + + private double getMaxChunkLoadRate() { -+ final double configRate = io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkLoadRate; ++ final double configRate = PlatformHooks.get().configPlayerMaxLoadRate(); + + return configRate <= 0.0 || configRate > (double)MAX_RATE ? (double)MAX_RATE : Math.max(1.0, configRate); + } + + private double getMaxChunkGenRate() { -+ final double configRate = io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkGenerateRate; ++ final double configRate = PlatformHooks.get().configPlayerMaxGenRate(); + + return configRate <= 0.0 || configRate > (double)MAX_RATE ? (double)MAX_RATE : Math.max(1.0, configRate); + } + + private double getMaxChunkSendRate() { -+ final double configRate = io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkSendRate; ++ final double configRate = PlatformHooks.get().configPlayerMaxSendRate(); + + return configRate <= 0.0 || configRate > (double)MAX_RATE ? (double)MAX_RATE : Math.max(1.0, configRate); + } + + private long getMaxChunkLoads() { + final long radiusChunks = (2L * this.lastLoadDistance + 1L) * (2L * this.lastLoadDistance + 1L); -+ long configLimit = io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkLoads; ++ long configLimit = (long)PlatformHooks.get().configPlayerMaxConcurrentLoads(); + if (configLimit == 0L) { + // by default, only allow 1/5th of the chunks in the view distance to be concurrently active + configLimit = Math.max(5L, radiusChunks / 5L); @@ -5373,7 +6133,7 @@ index 0000000000000000000000000000000000000000..852d75a73dae7448cbe1e2f5e164b235 + + private long getMaxChunkGenerates() { + final long radiusChunks = (2L * this.lastLoadDistance + 1L) * (2L * this.lastLoadDistance + 1L); -+ long configLimit = io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkGenerates; ++ long configLimit = (long)PlatformHooks.get().configPlayerMaxConcurrentGens(); + if (configLimit == 0L) { + // by default, only allow 1/5th of the chunks in the view distance to be concurrently active + configLimit = Math.max(5L, radiusChunks / 5L); @@ -5495,7 +6255,7 @@ index 0000000000000000000000000000000000000000..852d75a73dae7448cbe1e2f5e164b235 + final int queuedChunkX = CoordinateUtils.getChunkX(queuedLoadChunk); + final int queuedChunkZ = CoordinateUtils.getChunkZ(queuedLoadChunk); + ((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().scheduleChunkLoad( -+ queuedChunkX, queuedChunkZ, ChunkStatus.EMPTY, false, PrioritisedExecutor.Priority.NORMAL, null ++ queuedChunkX, queuedChunkZ, ChunkStatus.EMPTY, false, Priority.NORMAL, null + ); + if (this.removed) { + return; @@ -5611,7 +6371,7 @@ index 0000000000000000000000000000000000000000..852d75a73dae7448cbe1e2f5e164b235 + } + if (!((ChunkSystemLevelChunk)chunk).moonrise$isPostProcessingDone()) { + // not yet post-processed, need to do this so that tile entities can properly be sent to clients -+ chunk.postProcessGeneration(); ++ chunk.postProcessGeneration(this.world); + // check if there was any recursive action + if (this.removed || this.sendQueue.isEmpty() || this.sendQueue.firstLong() != pendingSend) { + return; @@ -5650,7 +6410,6 @@ index 0000000000000000000000000000000000000000..852d75a73dae7448cbe1e2f5e164b235 + final int clientViewDistance = getClientViewDistance(this.player); + final int sendViewDistance = getSendViewDistance(loadViewDistance, clientViewDistance, playerDistances.sendViewDistance, worldDistances.sendViewDistance); + -+ // TODO check PlayerList diff in paper chunk system patch + // send view distances + this.player.connection.send(this.updateClientChunkRadius(sendViewDistance)); + this.player.connection.send(this.updateClientSimulationDistance(tickViewDistance)); @@ -5864,6 +6623,10 @@ index 0000000000000000000000000000000000000000..852d75a73dae7448cbe1e2f5e164b235 + + // now all tickets should be removed, which is all of our external state + } ++ ++ public LongOpenHashSet getSentChunksRaw() { ++ return this.sentChunks; ++ } + } +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/queue/ChunkUnloadQueue.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/queue/ChunkUnloadQueue.java @@ -6019,21 +6782,21 @@ index 0000000000000000000000000000000000000000..7eafc5b7cba23d8dec92ecc1050afe3f \ No newline at end of file diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b58a8b5ef +index 0000000000000000000000000000000000000000..f98df65eaed2abedc66f3a49790e0cfb65354ed9 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -@@ -0,0 +1,1428 @@ +@@ -0,0 +1,1455 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; + -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; +import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.PlatformHooks; +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; -+import ca.spottedleaf.moonrise.common.util.MoonriseCommon; +import ca.spottedleaf.moonrise.common.util.TickThread; +import ca.spottedleaf.moonrise.common.util.WorldUtil; +import ca.spottedleaf.moonrise.common.util.ChunkSystem; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; +import ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk; @@ -6045,7 +6808,6 @@ index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b +import ca.spottedleaf.moonrise.patches.chunk_system.util.ChunkSystemSortedArraySet; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; -+import com.mojang.logging.LogUtils; +import it.unimi.dsi.fastutil.longs.Long2ByteLinkedOpenHashMap; +import it.unimi.dsi.fastutil.longs.Long2ByteMap; +import it.unimi.dsi.fastutil.longs.Long2IntMap; @@ -6065,7 +6827,9 @@ index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b +import net.minecraft.util.SortedArraySet; +import net.minecraft.util.Unit; +import net.minecraft.world.level.ChunkPos; ++import net.minecraft.world.level.chunk.LevelChunk; +import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.text.DecimalFormat; +import java.util.ArrayDeque; @@ -6083,7 +6847,7 @@ index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b + +public final class ChunkHolderManager { + -+ private static final Logger LOGGER = LogUtils.getClassLogger(); ++ private static final Logger LOGGER = LoggerFactory.getLogger(ChunkHolderManager.class); + + public static final int FULL_LOADED_TICKET_LEVEL = ChunkLevel.FULL_CHUNK_LEVEL; + public static final int BLOCK_TICKING_TICKET_LEVEL = ChunkLevel.BLOCK_TICKING_LEVEL; @@ -6214,7 +6978,7 @@ index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b + if (halt) { + LOGGER.info("Waiting 60s for chunk system to halt for world '" + WorldUtil.getWorldName(this.world) + "'"); + if (!this.taskScheduler.halt(true, TimeUnit.SECONDS.toNanos(60L))) { -+ LOGGER.warn("Failed to halt world generation/loading tasks for world '" + WorldUtil.getWorldName(this.world) + "'"); ++ LOGGER.warn("Failed to halt generation/loading tasks for world '" + WorldUtil.getWorldName(this.world) + "'"); + } else { + LOGGER.info("Halted chunk system for world '" + WorldUtil.getWorldName(this.world) + "'"); + } @@ -6224,21 +6988,21 @@ index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b + this.saveAllChunks(true, true, true); + } + -+ boolean hasTasks = false; -+ for (final RegionFileIOThread.RegionFileType type : RegionFileIOThread.RegionFileType.values()) { -+ if (RegionFileIOThread.getControllerFor(this.world, type).hasTasks()) { -+ hasTasks = true; -+ break; ++ MoonriseRegionFileIO.flush(this.world); ++ ++ if (halt) { ++ LOGGER.info("Waiting 60s for chunk I/O to halt for world '" + WorldUtil.getWorldName(this.world) + "'"); ++ if (!this.taskScheduler.haltIO(true, TimeUnit.SECONDS.toNanos(60L))) { ++ LOGGER.warn("Failed to halt I/O tasks for world '" + WorldUtil.getWorldName(this.world) + "'"); ++ } else { ++ LOGGER.info("Halted I/O scheduler for world '" + WorldUtil.getWorldName(this.world) + "'"); + } + } -+ if (hasTasks) { -+ RegionFileIOThread.flush(); -+ } + + // kill regionfile cache -+ for (final RegionFileIOThread.RegionFileType type : RegionFileIOThread.RegionFileType.values()) { ++ for (final MoonriseRegionFileIO.RegionFileType type : MoonriseRegionFileIO.RegionFileType.values()) { + try { -+ RegionFileIOThread.getControllerFor(this.world, type).getCache().close(); ++ MoonriseRegionFileIO.getControllerFor(this.world, type).getCache().close(); + } catch (final IOException ex) { + LOGGER.error("Failed to close '" + type.name() + "' regionfile cache for world '" + WorldUtil.getWorldName(this.world) + "'", ex); + } @@ -6255,8 +7019,8 @@ index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b + public void autoSave() { + final List reschedule = new ArrayList<>(); + final long currentTick = this.currentTick; -+ final long maxSaveTime = currentTick - Math.max(1L, this.world.paperConfig().chunks.autoSaveInterval.value()); -+ final int maxToSave = this.world.paperConfig().chunks.maxAutoSaveChunksPerTick; ++ final long maxSaveTime = currentTick - Math.max(1L, PlatformHooks.get().configAutoSaveInterval()); ++ final int maxToSave = PlatformHooks.get().configMaxAutoSavePerTick(); + for (int autoSaved = 0; autoSaved < maxToSave && !this.autoSaveQueue.isEmpty();) { + final NewChunkHolder holder = this.autoSaveQueue.first(); + @@ -6296,55 +7060,74 @@ index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b + + long start = System.nanoTime(); + long lastLog = start; -+ boolean needsFlush = false; -+ final int flushInterval = 50; ++ final int flushInterval = 200; ++ int lastFlush = 0; + + int savedChunk = 0; + int savedEntity = 0; + int savedPoi = 0; + ++ if (shutdown) { ++ // Normal unload process does not occur during shutdown: fire event manually ++ // for mods that expect ChunkEvent.Unload to fire on shutdown (before LevelEvent.Unload) ++ for (int i = 0, len = holders.size(); i < len; ++i) { ++ final NewChunkHolder holder = holders.get(i); ++ if (holder.getCurrentChunk() instanceof LevelChunk levelChunk) { ++ PlatformHooks.get().chunkUnloadFromWorld(levelChunk); ++ } ++ } ++ } + for (int i = 0, len = holders.size(); i < len; ++i) { + final NewChunkHolder holder = holders.get(i); + try { + final NewChunkHolder.SaveStat saveStat = holder.save(shutdown); + if (saveStat != null) { -+ ++saved; -+ needsFlush = flush; + if (saveStat.savedChunk()) { + ++savedChunk; ++ ++saved; + } + if (saveStat.savedEntityChunk()) { + ++savedEntity; ++ ++saved; + } + if (saveStat.savedPoiChunk()) { + ++savedPoi; ++ ++saved; + } + } + } catch (final Throwable thr) { + LOGGER.error("Failed to save chunk (" + holder.chunkX + "," + holder.chunkZ + ") in world '" + WorldUtil.getWorldName(this.world) + "'", thr); + } -+ if (needsFlush && (saved % flushInterval) == 0) { -+ needsFlush = false; -+ RegionFileIOThread.partialFlush(flushInterval / 2); ++ if (flush && (saved - lastFlush) > (flushInterval / 2)) { ++ lastFlush = saved; ++ MoonriseRegionFileIO.partialFlush(this.world, flushInterval / 2); + } + if (logProgress) { + final long currTime = System.nanoTime(); + if ((currTime - lastLog) > TimeUnit.SECONDS.toNanos(10L)) { + lastLog = currTime; -+ LOGGER.info("Saved " + saved + " chunks (" + format.format((double)(i+1)/(double)len * 100.0) + "%) in world '" + WorldUtil.getWorldName(this.world) + "'"); ++ LOGGER.info( ++ "Saved " + savedChunk + " block chunks, " + savedEntity + " entity chunks, " + savedPoi ++ + " poi chunks in world '" + WorldUtil.getWorldName(this.world) + "', progress: " ++ + format.format((double)(i+1)/(double)len * 100.0) ++ ); + } + } + } + if (flush) { -+ RegionFileIOThread.flush(); ++ MoonriseRegionFileIO.flush(this.world); + try { -+ RegionFileIOThread.flushRegionStorages(this.world); ++ MoonriseRegionFileIO.flushRegionStorages(this.world); + } catch (final IOException ex) { + LOGGER.error("Exception when flushing regions in world '" + WorldUtil.getWorldName(this.world) + "'", ex); + } + } + if (logProgress) { -+ LOGGER.info("Saved " + savedChunk + " block chunks, " + savedEntity + " entity chunks, " + savedPoi + " poi chunks in world '" + WorldUtil.getWorldName(this.world) + "' in " + format.format(1.0E-9 * (System.nanoTime() - start)) + "s"); ++ LOGGER.info( ++ "Saved " + savedChunk + " block chunks, " + savedEntity + " entity chunks, " + savedPoi ++ + " poi chunks in world '" + WorldUtil.getWorldName(this.world) + "' in " ++ + format.format(1.0E-9 * (System.nanoTime() - start)) + "s" ++ ); + } + } + @@ -6823,21 +7606,21 @@ index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b + return this.chunkHolders.get(position); + } + -+ public void raisePriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { ++ public void raisePriority(final int x, final int z, final Priority priority) { + final NewChunkHolder chunkHolder = this.getChunkHolder(x, z); + if (chunkHolder != null) { + chunkHolder.raisePriority(priority); + } + } + -+ public void setPriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { ++ public void setPriority(final int x, final int z, final Priority priority) { + final NewChunkHolder chunkHolder = this.getChunkHolder(x, z); + if (chunkHolder != null) { + chunkHolder.setPriority(priority); + } + } + -+ public void lowerPriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(final int x, final int z, final Priority priority) { + final NewChunkHolder chunkHolder = this.getChunkHolder(x, z); + if (chunkHolder != null) { + chunkHolder.lowerPriority(priority); @@ -6920,7 +7703,7 @@ index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b + final ChunkLoadTask.EntityDataLoadTask entityLoad = current.getEntityDataLoadTask(); + + if (entityLoad != null) { -+ entityLoad.raisePriority(PrioritisedExecutor.Priority.BLOCKING); ++ entityLoad.raisePriority(Priority.BLOCKING); + } + } + } @@ -6996,7 +7779,7 @@ index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b + final ChunkLoadTask.PoiDataLoadTask poiLoad = current.getPoiDataLoadTask(); + + if (poiLoad != null) { -+ poiLoad.raisePriority(PrioritisedExecutor.Priority.BLOCKING); ++ poiLoad.raisePriority(Priority.BLOCKING); + } + } + } finally { @@ -7043,7 +7826,7 @@ index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b + } + + ChunkHolderManager.this.processPendingFullUpdate(); -+ }, PrioritisedExecutor.Priority.HIGHEST); ++ }, Priority.HIGHEST); + } else { + final ArrayDeque pendingFullLoadUpdate = this.pendingFullLoadUpdate; + for (int i = 0, len = changedFullStatus.size(); i < len; ++i) { @@ -7053,11 +7836,10 @@ index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b + } + + private void removeChunkHolder(final NewChunkHolder holder) { -+ holder.markUnloaded(); ++ holder.onUnload(); + this.autoSaveQueue.remove(holder); + ChunkSystem.onChunkHolderDelete(this.world, holder.vanillaChunkHolder); + this.chunkHolders.remove(CoordinateUtils.getChunkKey(holder.chunkX, holder.chunkZ)); -+ + } + + // note: never call while inside the chunk system, this will absolutely break everything @@ -7338,6 +8120,9 @@ index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b + if (BLOCK_TICKET_UPDATES.get() == Boolean.TRUE) { + throw new IllegalStateException("Cannot update ticket level while unloading chunks or updating entity manager"); + } ++ if (!PlatformHooks.get().allowAsyncTicketUpdates() && !TickThread.isTickThread()) { ++ TickThread.ensureTickThread("Cannot asynchronously process ticket updates"); ++ } + + List changedFullStatus = null; + @@ -7353,10 +8138,15 @@ index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b + } + changedFullStatus = new ArrayList<>(); + -+ ret |= this.ticketLevelPropagator.performUpdates( -+ this.ticketLockArea, this.taskScheduler.schedulingLockArea, -+ scheduledTasks, changedFullStatus -+ ); ++ this.blockTicketUpdates(); ++ try { ++ ret |= this.ticketLevelPropagator.performUpdates( ++ this.ticketLockArea, this.taskScheduler.schedulingLockArea, ++ scheduledTasks, changedFullStatus ++ ); ++ } finally { ++ this.unblockTicketUpdates(Boolean.FALSE); ++ } + } + + if (changedFullStatus != null) { @@ -7453,23 +8243,24 @@ index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java new file mode 100644 -index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf01815f64c +index 0000000000000000000000000000000000000000..120ce31729dc8d4bba0901ca06d3212f3158d089 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java -@@ -0,0 +1,1041 @@ +@@ -0,0 +1,1037 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; + -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadedTaskQueue; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.queue.PrioritisedTaskQueue; ++import ca.spottedleaf.concurrentutil.executor.thread.PrioritisedThreadPool; +import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.config.moonrise.MoonriseConfig; +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +import ca.spottedleaf.moonrise.common.util.JsonUtil; +import ca.spottedleaf.moonrise.common.util.MoonriseCommon; +import ca.spottedleaf.moonrise.common.util.TickThread; +import ca.spottedleaf.moonrise.common.util.WorldUtil; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; +import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkStatus; +import ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer; @@ -7482,7 +8273,6 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 +import ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer; +import ca.spottedleaf.moonrise.patches.chunk_system.status.ChunkSystemChunkStep; +import ca.spottedleaf.moonrise.patches.chunk_system.util.ParallelSearchRadiusIteration; -+import com.mojang.logging.LogUtils; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import net.minecraft.CrashReport; @@ -7507,6 +8297,7 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 +import net.minecraft.world.level.chunk.status.ChunkStep; +import net.minecraft.world.phys.Vec3; +import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; +import java.io.File; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; @@ -7522,51 +8313,14 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + +public final class ChunkTaskScheduler { + -+ private static final Logger LOGGER = LogUtils.getClassLogger(); -+ -+ static int newChunkSystemIOThreads; -+ static int newChunkSystemGenParallelism; -+ static int newChunkSystemGenPopulationParallelism; -+ static int newChunkSystemLoadParallelism; -+ -+ private static boolean initialised = false; -+ -+ public static void init(io.papermc.paper.configuration.GlobalConfiguration.ChunkSystem chunkSystem) { -+ if (initialised) { -+ return; -+ } -+ initialised = true; -+ MoonriseCommon.init(chunkSystem); // Paper -+ newChunkSystemIOThreads = chunkSystem.ioThreads; -+ if (newChunkSystemIOThreads <= 0) { -+ newChunkSystemIOThreads = 1; -+ } else { -+ newChunkSystemIOThreads = Math.max(1, newChunkSystemIOThreads); -+ } -+ -+ String newChunkSystemGenParallelism = chunkSystem.genParallelism; -+ if (newChunkSystemGenParallelism.equalsIgnoreCase("default")) { -+ newChunkSystemGenParallelism = "true"; -+ } ++ private static final Logger LOGGER = LoggerFactory.getLogger(ChunkTaskScheduler.class); + -+ boolean useParallelGen; -+ if (newChunkSystemGenParallelism.equalsIgnoreCase("on") || newChunkSystemGenParallelism.equalsIgnoreCase("enabled") -+ || newChunkSystemGenParallelism.equalsIgnoreCase("true")) { -+ useParallelGen = true; -+ } else if (newChunkSystemGenParallelism.equalsIgnoreCase("off") || newChunkSystemGenParallelism.equalsIgnoreCase("disabled") -+ || newChunkSystemGenParallelism.equalsIgnoreCase("false")) { -+ useParallelGen = false; -+ } else { -+ throw new IllegalStateException("Invalid option for gen-parallelism: must be one of [on, off, enabled, disabled, true, false, default]"); ++ public static void init(final boolean useParallelGen) { ++ for (final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor executor : MoonriseCommon.RADIUS_AWARE_GROUP.getAllExecutors()) { ++ executor.setMaxParallelism(useParallelGen ? -1 : 1); + } + -+ ChunkTaskScheduler.newChunkSystemGenParallelism = MoonriseCommon.WORKER_THREADS; -+ ChunkTaskScheduler.newChunkSystemGenPopulationParallelism = useParallelGen ? MoonriseCommon.WORKER_THREADS : 1; -+ ChunkTaskScheduler.newChunkSystemLoadParallelism = MoonriseCommon.WORKER_THREADS; -+ -+ RegionFileIOThread.init(newChunkSystemIOThreads); -+ -+ LOGGER.info("Chunk system is using " + newChunkSystemIOThreads + " I/O threads, " + MoonriseCommon.WORKER_THREADS + " worker threads, and population gen parallelism of " + ChunkTaskScheduler.newChunkSystemGenPopulationParallelism + " threads"); ++ LOGGER.info("Chunk system is using population gen parallelism: " + useParallelGen); + } + + public static final TicketType CHUNK_LOAD = TicketType.create("chunk_system:chunk_load", Long::compareTo); @@ -7610,13 +8364,15 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + } + + public final ServerLevel world; -+ public final PrioritisedThreadPool workers; + public final RadiusAwarePrioritisedExecutor radiusAwareScheduler; -+ public final PrioritisedThreadPool.PrioritisedPoolExecutor parallelGenExecutor; -+ private final PrioritisedThreadPool.PrioritisedPoolExecutor radiusAwareGenExecutor; -+ public final PrioritisedThreadPool.PrioritisedPoolExecutor loadExecutor; ++ public final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor parallelGenExecutor; ++ private final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor radiusAwareGenExecutor; ++ public final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor loadExecutor; ++ public final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor ioExecutor; ++ public final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor compressionExecutor; ++ public final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor saveExecutor; + -+ private final PrioritisedThreadedTaskQueue mainThreadExecutor = new PrioritisedThreadedTaskQueue(); ++ private final PrioritisedTaskQueue mainThreadExecutor = new PrioritisedTaskQueue(); + + public final ChunkHolderManager chunkHolderManager; + @@ -7765,9 +8521,8 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + return this.lockShift; + } + -+ public ChunkTaskScheduler(final ServerLevel world, final PrioritisedThreadPool workers) { ++ public ChunkTaskScheduler(final ServerLevel world) { + this.world = world; -+ this.workers = workers; + // must be >= region shift (in paper, doesn't exist) and must be >= ticket propagator section shift + // it must be >= region shift since the regioniser assumes ticket updates do not occur in parallel for the region sections + // it must be >= ticket propagator section shift so that the ticket propagator can assume that owning a position implies owning @@ -7776,11 +8531,14 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + this.lockShift = Math.max(((ChunkSystemServerLevel)world).moonrise$getRegionChunkShift(), ThreadedTicketLevelPropagator.SECTION_SHIFT); + this.schedulingLockArea = new ReentrantAreaLock(this.getChunkSystemLockShift()); + -+ final String worldName = WorldUtil.getWorldName(world); -+ this.parallelGenExecutor = workers.createExecutor("Chunk parallel generation executor for world '" + worldName + "'", 1, Math.max(1, newChunkSystemGenParallelism)); -+ this.radiusAwareGenExecutor = workers.createExecutor("Chunk radius aware generator for world '" + worldName + "'", 1, Math.max(1, newChunkSystemGenPopulationParallelism)); -+ this.loadExecutor = workers.createExecutor("Chunk load executor for world '" + worldName + "'", 1, newChunkSystemLoadParallelism); -+ this.radiusAwareScheduler = new RadiusAwarePrioritisedExecutor(this.radiusAwareGenExecutor, Math.max(2, 1 + newChunkSystemGenPopulationParallelism)); ++ this.parallelGenExecutor = MoonriseCommon.PARALLEL_GEN_GROUP.createExecutor(-1, MoonriseCommon.WORKER_QUEUE_HOLD_TIME, 0); ++ this.radiusAwareGenExecutor = MoonriseCommon.RADIUS_AWARE_GROUP.createExecutor(1, MoonriseCommon.WORKER_QUEUE_HOLD_TIME, 0); ++ this.loadExecutor = MoonriseCommon.LOAD_GROUP.createExecutor(-1, MoonriseCommon.WORKER_QUEUE_HOLD_TIME, 0); ++ this.radiusAwareScheduler = new RadiusAwarePrioritisedExecutor(this.radiusAwareGenExecutor, 16); ++ this.ioExecutor = MoonriseCommon.SERVER_REGION_IO_GROUP.createExecutor(-1, MoonriseCommon.IO_QUEUE_HOLD_TIME, 0); ++ // we need a separate executor here so that on shutdown we can continue to process I/O tasks ++ this.compressionExecutor = MoonriseCommon.LOAD_GROUP.createExecutor(-1, MoonriseCommon.WORKER_QUEUE_HOLD_TIME, 0); ++ this.saveExecutor = MoonriseCommon.LOAD_GROUP.createExecutor(-1, MoonriseCommon.WORKER_QUEUE_HOLD_TIME, 0); + this.chunkHolderManager = new ChunkHolderManager(world, this); + } + @@ -7819,7 +8577,7 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + }; + + // this may not be good enough, specifically thanks to stupid ass plugins swallowing exceptions -+ this.scheduleChunkTask(chunkX, chunkZ, crash, PrioritisedExecutor.Priority.BLOCKING); ++ this.scheduleChunkTask(chunkX, chunkZ, crash, Priority.BLOCKING); + // so, make the main thread pick it up + ((ChunkSystemMinecraftServer)this.world.getServer()).moonrise$setChunkSystemCrash(new RuntimeException("Chunk system crash propagated from unrecoverableChunkSystemFailure", reportedException)); + } @@ -7829,20 +8587,20 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + return this.mainThreadExecutor.executeTask(); + } + -+ public void raisePriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { ++ public void raisePriority(final int x, final int z, final Priority priority) { + this.chunkHolderManager.raisePriority(x, z, priority); + } + -+ public void setPriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { ++ public void setPriority(final int x, final int z, final Priority priority) { + this.chunkHolderManager.setPriority(x, z, priority); + } + -+ public void lowerPriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(final int x, final int z, final Priority priority) { + this.chunkHolderManager.lowerPriority(x, z, priority); + } + + public void scheduleTickingState(final int chunkX, final int chunkZ, final FullChunkStatus toStatus, -+ final boolean addTicket, final PrioritisedExecutor.Priority priority, ++ final boolean addTicket, final Priority priority, + final Consumer onComplete) { + final int radius = toStatus.ordinal() - 1; // 0 -> BORDER, 1 -> TICKING, 2 -> ENTITY_TICKING + @@ -7938,7 +8696,7 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + } + + public void scheduleChunkLoad(final int chunkX, final int chunkZ, final boolean gen, final ChunkStatus toStatus, final boolean addTicket, -+ final PrioritisedExecutor.Priority priority, final Consumer onComplete) { ++ final Priority priority, final Consumer onComplete) { + if (gen) { + this.scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); + return; @@ -7962,7 +8720,7 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + + // only appropriate to use with syncLoadNonFull + public boolean beginChunkLoadForNonFullSync(final int chunkX, final int chunkZ, final ChunkStatus toStatus, -+ final PrioritisedExecutor.Priority priority) { ++ final Priority priority) { + final int accessRadius = getAccessRadius(toStatus); + final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); + final int minLevel = ChunkTaskScheduler.getTicketLevel(toStatus); @@ -8007,6 +8765,11 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + if (status == null || status.isOrAfter(ChunkStatus.FULL)) { + throw new IllegalArgumentException("Status: " + status); + } ++ ++ if (!TickThread.isTickThread()) { ++ return this.world.getChunkSource().getChunk(chunkX, chunkZ, status, true); ++ } ++ + ChunkAccess loaded = ((ChunkSystemServerLevel)this.world).moonrise$getSpecificChunkIfLoaded(chunkX, chunkZ, status); + if (loaded != null) { + return loaded; @@ -8017,7 +8780,7 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + this.chunkHolderManager.addTicketAtLevel(NON_FULL_CHUNK_LOAD, chunkX, chunkZ, ticketLevel, ticketId); + this.chunkHolderManager.processTicketUpdates(); + -+ this.beginChunkLoadForNonFullSync(chunkX, chunkZ, status, PrioritisedExecutor.Priority.BLOCKING); ++ this.beginChunkLoadForNonFullSync(chunkX, chunkZ, status, Priority.BLOCKING); + + // we could do a simple spinwait here, since we do not need to process tasks while performing this load + // but we process tasks only because it's a better use of the time spent @@ -8037,7 +8800,7 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + } + + public void scheduleChunkLoad(final int chunkX, final int chunkZ, final ChunkStatus toStatus, final boolean addTicket, -+ final PrioritisedExecutor.Priority priority, final Consumer onComplete) { ++ final Priority priority, final Consumer onComplete) { + if (!TickThread.isTickThreadFor(this.world, chunkX, chunkZ)) { + this.scheduleChunkTask(chunkX, chunkZ, () -> { + ChunkTaskScheduler.this.scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); @@ -8129,7 +8892,7 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + + private ChunkProgressionTask createTask(final int chunkX, final int chunkZ, final ChunkAccess chunk, + final NewChunkHolder chunkHolder, final StaticCache2D neighbours, -+ final ChunkStatus toStatus, final PrioritisedExecutor.Priority initialPriority) { ++ final ChunkStatus toStatus, final Priority initialPriority) { + if (toStatus == ChunkStatus.EMPTY) { + return new ChunkLoadTask(this, this.world, chunkX, chunkZ, chunkHolder, initialPriority); + } @@ -8145,7 +8908,7 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + + ChunkProgressionTask schedule(final int chunkX, final int chunkZ, final ChunkStatus targetStatus, final NewChunkHolder chunkHolder, + final List allTasks) { -+ return this.schedule(chunkX, chunkZ, targetStatus, chunkHolder, allTasks, chunkHolder.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL)); ++ return this.schedule(chunkX, chunkZ, targetStatus, chunkHolder, allTasks, chunkHolder.getEffectivePriority(Priority.NORMAL)); + } + + // rets new task scheduled for the _specified_ chunk @@ -8154,7 +8917,7 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + // schedule will ignore the generation target, so it should be checked by the caller to ensure the target is not regressed! + private ChunkProgressionTask schedule(final int chunkX, final int chunkZ, final ChunkStatus targetStatus, + final NewChunkHolder chunkHolder, final List allTasks, -+ final PrioritisedExecutor.Priority minPriority) { ++ final Priority minPriority) { + if (!this.schedulingLockArea.isHeldByCurrentThread(chunkX, chunkZ, getAccessRadius(targetStatus))) { + throw new IllegalStateException("Not holding scheduling lock"); + } @@ -8164,8 +8927,8 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + return null; + } + -+ final PrioritisedExecutor.Priority requestedPriority = PrioritisedExecutor.Priority.max( -+ minPriority, chunkHolder.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) ++ final Priority requestedPriority = Priority.max( ++ minPriority, chunkHolder.getEffectivePriority(Priority.NORMAL) + ); + final ChunkStatus currentGenStatus = chunkHolder.getCurrentGenStatus(); + final ChunkAccess chunk = chunkHolder.getCurrentChunk(); @@ -8202,7 +8965,7 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + + final int neighbourReadRadius = Math.max( + 0, -+ chunkPyramid.getStepTo(toStatus).getAccumulatedRadiusOf(ChunkStatus.EMPTY) ++ chunkStep.getAccumulatedRadiusOf(ChunkStatus.EMPTY) + ); + + boolean unGeneratedNeighbours = false; @@ -8242,7 +9005,7 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + + final ChunkProgressionTask task = this.createTask( + chunkX, chunkZ, chunk, chunkHolder, neighbours, toStatus, -+ chunkHolder.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) ++ chunkHolder.getEffectivePriority(Priority.NORMAL) + ); + allTasks.add(task); + @@ -8253,7 +9016,7 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + + // rets true if the neighbour is not at the required status, false otherwise + private boolean checkNeighbour(final int chunkX, final int chunkZ, final ChunkStatus requiredStatus, final NewChunkHolder center, -+ final List tasks, final PrioritisedExecutor.Priority minPriority) { ++ final List tasks, final Priority minPriority) { + final NewChunkHolder chunkHolder = this.chunkHolderManager.getChunkHolder(chunkX, chunkZ); + + if (chunkHolder == null) { @@ -8289,41 +9052,41 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + */ + @Deprecated + public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final Runnable run) { -+ return this.scheduleChunkTask(run, PrioritisedExecutor.Priority.NORMAL); ++ return this.scheduleChunkTask(run, Priority.NORMAL); + } + + /** + * @deprecated Chunk tasks must be tied to coordinates in the future + */ + @Deprecated -+ public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ return this.mainThreadExecutor.queueRunnable(run, priority); ++ public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final Runnable run, final Priority priority) { ++ return this.mainThreadExecutor.queueTask(run, priority); + } + + public PrioritisedExecutor.PrioritisedTask createChunkTask(final int chunkX, final int chunkZ, final Runnable run) { -+ return this.createChunkTask(chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); ++ return this.createChunkTask(chunkX, chunkZ, run, Priority.NORMAL); + } + + public PrioritisedExecutor.PrioritisedTask createChunkTask(final int chunkX, final int chunkZ, final Runnable run, -+ final PrioritisedExecutor.Priority priority) { ++ final Priority priority) { + return this.mainThreadExecutor.createTask(run, priority); + } + + public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final int chunkX, final int chunkZ, final Runnable run) { -+ return this.scheduleChunkTask(chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); ++ return this.scheduleChunkTask(chunkX, chunkZ, run, Priority.NORMAL); + } + + public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final int chunkX, final int chunkZ, final Runnable run, -+ final PrioritisedExecutor.Priority priority) { -+ return this.mainThreadExecutor.queueRunnable(run, priority); ++ final Priority priority) { ++ return this.mainThreadExecutor.queueTask(run, priority); + } + + public boolean halt(final boolean sync, final long maxWaitNS) { + this.radiusAwareGenExecutor.halt(); + this.parallelGenExecutor.halt(); + this.loadExecutor.halt(); -+ final long time = System.nanoTime(); + if (sync) { ++ final long time = System.nanoTime(); + for (long failures = 9L;; failures = ConcurrentUtil.linearLongBackoff(failures, 500_000L, 50_000_000L)) { + if ( + !this.radiusAwareGenExecutor.isActive() && @@ -8341,6 +9104,29 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 + return true; + } + ++ public boolean haltIO(final boolean sync, final long maxWaitNS) { ++ this.ioExecutor.halt(); ++ this.saveExecutor.halt(); ++ this.compressionExecutor.halt(); ++ if (sync) { ++ final long time = System.nanoTime(); ++ for (long failures = 9L;; failures = ConcurrentUtil.linearLongBackoff(failures, 500_000L, 50_000_000L)) { ++ if ( ++ !this.ioExecutor.isActive() && ++ !this.saveExecutor.isActive() && ++ !this.compressionExecutor.isActive() ++ ) { ++ return true; ++ } ++ if ((System.nanoTime() - time) >= maxWaitNS) { ++ return false; ++ } ++ } ++ } ++ ++ return true; ++ } ++ + public static final ArrayDeque WAITING_CHUNKS = new ArrayDeque<>(); // stack + + public static final class ChunkInfo { @@ -8500,25 +9286,27 @@ index 0000000000000000000000000000000000000000..8671a90e969d16c7a57ddc38fedb7cf0 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java new file mode 100644 -index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7e451416f +index 0000000000000000000000000000000000000000..381631e405895ba3eede1cd2e1011c64aadbd662 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -@@ -0,0 +1,2035 @@ +@@ -0,0 +1,1998 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; + -+import ca.spottedleaf.concurrentutil.completable.Completable; ++import ca.spottedleaf.concurrentutil.completable.CallbackCompletable; +import ca.spottedleaf.concurrentutil.executor.Cancellable; -+import ca.spottedleaf.concurrentutil.executor.standard.DelayedPrioritisedTask; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.PlatformHooks; ++import ca.spottedleaf.moonrise.common.misc.LazyRunnable; +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +import ca.spottedleaf.moonrise.common.util.TickThread; +import ca.spottedleaf.moonrise.common.util.WorldUtil; +import ca.spottedleaf.moonrise.common.util.ChunkSystem; -+import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystemFeatures; -+import ca.spottedleaf.moonrise.patches.chunk_system.async_save.AsyncChunkSaveData; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; +import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkHolder; +import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkStatus; @@ -8542,13 +9330,14 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 +import net.minecraft.server.level.ChunkLevel; +import net.minecraft.server.level.FullChunkStatus; +import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.progress.ChunkProgressListener; +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.ImposterProtoChunk; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.status.ChunkStatus; -+import net.minecraft.world.level.chunk.storage.ChunkSerializer; ++import net.minecraft.world.level.chunk.storage.SerializableChunkData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.lang.invoke.VarHandle; @@ -8564,6 +9353,8 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + + private static final Logger LOGGER = LoggerFactory.getLogger(NewChunkHolder.class); + ++ public final ChunkData holderData; ++ + public final ServerLevel world; + public final int chunkX; + public final int chunkZ; @@ -8595,7 +9386,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + if (this.entityChunk == null) { + ret = this.entityChunk = new ChunkEntitySlices( + this.world, this.chunkX, this.chunkZ, this.getChunkStatus(), -+ WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) ++ this.holderData, WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) + ); + + ret.setTransient(transientChunk); @@ -8679,7 +9470,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + // no tasks to schedule _for_ + } else { + entityDataLoadTask = this.entityDataLoadTask = new ChunkLoadTask.EntityDataLoadTask( -+ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) ++ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(Priority.NORMAL) + ); + entityDataLoadTask.addCallback(this::completeEntityLoad); + // need one schedule() per waiter @@ -8726,7 +9517,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + + if (this.entityDataLoadTask == null) { + this.entityDataLoadTask = new ChunkLoadTask.EntityDataLoadTask( -+ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) ++ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(Priority.NORMAL) + ); + this.entityDataLoadTask.addCallback(this::completeEntityLoad); + this.entityDataLoadTaskWaiters = new ArrayList<>(); @@ -8800,7 +9591,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + // no tasks to schedule _for_ + } else { + poiDataLoadTask = this.poiDataLoadTask = new ChunkLoadTask.PoiDataLoadTask( -+ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) ++ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(Priority.NORMAL) + ); + poiDataLoadTask.addCallback(this::completePoiLoad); + // need one schedule() per waiter @@ -8846,7 +9637,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + + if (this.poiDataLoadTask == null) { + this.poiDataLoadTask = new ChunkLoadTask.PoiDataLoadTask( -+ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) ++ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(Priority.NORMAL) + ); + this.poiDataLoadTask.addCallback(this::completePoiLoad); + this.poiDataLoadTaskWaiters = new ArrayList<>(); @@ -9025,15 +9816,15 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + // priority state + + // the target priority for this chunk to generate at -+ private PrioritisedExecutor.Priority priority = null; ++ private Priority priority = null; + private boolean priorityLocked; + + // the priority neighbouring chunks have requested this chunk generate at -+ private PrioritisedExecutor.Priority neighbourRequestedPriority = null; ++ private Priority neighbourRequestedPriority = null; + -+ public PrioritisedExecutor.Priority getEffectivePriority(final PrioritisedExecutor.Priority dfl) { -+ final PrioritisedExecutor.Priority neighbour = this.neighbourRequestedPriority; -+ final PrioritisedExecutor.Priority us = this.priority; ++ public Priority getEffectivePriority(final Priority dfl) { ++ final Priority neighbour = this.neighbourRequestedPriority; ++ final Priority us = this.priority; + + if (neighbour == null) { + return us == null ? dfl : us; @@ -9042,7 +9833,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + return neighbour; + } + -+ return PrioritisedExecutor.Priority.max(us, neighbour); ++ return Priority.max(us, neighbour); + } + + private void recalculateNeighbourRequestedPriority() { @@ -9051,18 +9842,18 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + return; + } + -+ PrioritisedExecutor.Priority max = null; ++ Priority max = null; + + for (final NewChunkHolder holder : this.neighboursWaitingForUs.keySet()) { -+ final PrioritisedExecutor.Priority neighbourPriority = holder.getEffectivePriority(null); ++ final Priority neighbourPriority = holder.getEffectivePriority(null); + if (neighbourPriority != null && (max == null || neighbourPriority.isHigherPriority(max))) { + max = neighbourPriority; + } + } + -+ final PrioritisedExecutor.Priority current = this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL); ++ final Priority current = this.getEffectivePriority(Priority.NORMAL); + this.neighbourRequestedPriority = max; -+ final PrioritisedExecutor.Priority next = this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL); ++ final Priority next = this.getEffectivePriority(Priority.NORMAL); + + if (current == next) { + return; @@ -9084,7 +9875,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + } + + // must hold scheduling lock -+ public void raisePriority(final PrioritisedExecutor.Priority priority) { ++ public void raisePriority(final Priority priority) { + if (this.priority != null && this.priority.isHigherOrEqualPriority(priority)) { + return; + } @@ -9097,13 +9888,13 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + } + + // must hold scheduling lock -+ public void setPriority(final PrioritisedExecutor.Priority priority) { ++ public void setPriority(final Priority priority) { + if (this.priorityLocked) { + return; + } -+ final PrioritisedExecutor.Priority old = this.getEffectivePriority(null); ++ final Priority old = this.getEffectivePriority(null); + this.priority = priority; -+ final PrioritisedExecutor.Priority newPriority = this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL); ++ final Priority newPriority = this.getEffectivePriority(Priority.NORMAL); + + if (old != newPriority) { + if (this.generationTask != null) { @@ -9115,7 +9906,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + } + + // must hold scheduling lock -+ public void lowerPriority(final PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(final Priority priority) { + if (this.priority != null && this.priority.isLowerOrEqualPriority(priority)) { + return; + } @@ -9138,7 +9929,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + } + + // ticket level state -+ public int oldTicketLevel = ChunkHolderManager.MAX_TICKET_LEVEL + 1; ++ private int oldTicketLevel = ChunkHolderManager.MAX_TICKET_LEVEL + 1; + private int currentTicketLevel = ChunkHolderManager.MAX_TICKET_LEVEL + 1; + + public int getTicketLevel() { @@ -9157,6 +9948,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + world.getLightEngine(), null, world.getChunkSource().chunkMap + ); + ((ChunkSystemChunkHolder)this.vanillaChunkHolder).moonrise$setRealChunkHolder(this); ++ this.holderData = ((ChunkSystemLevel)this.world).moonrise$requestChunkData(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + } + + public ChunkAccess getCurrentChunk() { @@ -9256,8 +10048,9 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + /** Unloaded from chunk map */ + private boolean unloaded; + -+ void markUnloaded() { ++ void onUnload() { + this.unloaded = true; ++ ((ChunkSystemLevel)this.world).moonrise$releaseChunkData(CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ)); + } + + private boolean inUnloadQueue = false; @@ -9294,9 +10087,10 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + private UnloadTask entityDataUnload; + private UnloadTask poiDataUnload; + -+ public static final record UnloadTask(Completable completable, DelayedPrioritisedTask task) {} ++ public static final record UnloadTask(CallbackCompletable completable, PrioritisedExecutor.PrioritisedTask task, ++ LazyRunnable toRun) {} + -+ public UnloadTask getUnloadTask(final RegionFileIOThread.RegionFileType type) { ++ public UnloadTask getUnloadTask(final MoonriseRegionFileIO.RegionFileType type) { + switch (type) { + case CHUNK_DATA: + return this.chunkDataUnload; @@ -9309,7 +10103,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + } + } + -+ private void removeUnloadTask(final RegionFileIOThread.RegionFileType type) { ++ private void removeUnloadTask(final MoonriseRegionFileIO.RegionFileType type) { + switch (type) { + case CHUNK_DATA: { + this.chunkDataUnload = null; @@ -9342,10 +10136,10 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + // chunk state + this.currentChunk = null; + this.currentGenStatus = null; -+ this.lastChunkCompletion = null; + for (int i = 0; i < this.chunkCompletions.length; ++i) { -+ CHUNK_COMPLETION_ARRAY_HANDLE.setVolatile(this.chunkCompletions, i, (ChunkCompletion)null); ++ CHUNK_COMPLETION_ARRAY_HANDLE.setRelease(this.chunkCompletions, i, (ChunkCompletion)null); + } ++ this.lastChunkCompletion = null; + // entity chunk state + this.entityChunk = null; + this.pendingEntityChunk = null; @@ -9357,22 +10151,23 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + this.priorityLocked = false; + + if (chunk != null) { -+ this.chunkDataUnload = new UnloadTask(new Completable<>(), new DelayedPrioritisedTask(PrioritisedExecutor.Priority.NORMAL)); ++ final LazyRunnable toRun = new LazyRunnable(); ++ this.chunkDataUnload = new UnloadTask(new CallbackCompletable<>(), this.scheduler.saveExecutor.createTask(toRun), toRun); + } + if (poiChunk != null) { -+ this.poiDataUnload = new UnloadTask(new Completable<>(), null); ++ this.poiDataUnload = new UnloadTask(new CallbackCompletable<>(), null, null); + } + if (entityChunk != null) { -+ this.entityDataUnload = new UnloadTask(new Completable<>(), null); ++ this.entityDataUnload = new UnloadTask(new CallbackCompletable<>(), null, null); + } + + return this.unloadState = (chunk != null || entityChunk != null || poiChunk != null) ? new UnloadState(this, chunk, entityChunk, poiChunk) : null; + } + + // data is null if failed or does not need to be saved -+ void completeAsyncUnloadDataSave(final RegionFileIOThread.RegionFileType type, final CompoundTag data) { ++ void completeAsyncUnloadDataSave(final MoonriseRegionFileIO.RegionFileType type, final CompoundTag data) { + if (data != null) { -+ RegionFileIOThread.scheduleSave(this.world, this.chunkX, this.chunkZ, data, type); ++ MoonriseRegionFileIO.scheduleSave(this.world, this.chunkX, this.chunkZ, data, type); + } + + this.getUnloadTask(type).completable().complete(data); @@ -9392,18 +10187,19 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + final ChunkEntitySlices entityChunk = state.entityChunk(); + final PoiChunk poiChunk = state.poiChunk(); + -+ final boolean shouldLevelChunkNotSave = ChunkSystemFeatures.forceNoSave(chunk); ++ final boolean shouldLevelChunkNotSave = PlatformHooks.get().forceNoSave(chunk); + + // unload chunk data + if (chunk != null) { + if (chunk instanceof LevelChunk levelChunk) { + levelChunk.setLoaded(false); ++ PlatformHooks.get().chunkUnloadFromWorld(levelChunk); + } + + if (!shouldLevelChunkNotSave) { + this.saveChunk(chunk, true); + } else { -+ this.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, null); ++ this.completeAsyncUnloadDataSave(MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, null); + } + + if (chunk instanceof LevelChunk levelChunk) { @@ -9572,6 +10368,9 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + if (oldUnloaded != newUnloaded) { + this.checkUnload(); + } ++ ++ // Don't really have a choice but to place this hook here ++ PlatformHooks.get().onChunkHolderTicketChange(this.world, this, oldLevel, newLevel); + } + + static final int NEIGHBOUR_RADIUS = 2; @@ -9617,24 +10416,6 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + private static final long CHUNK_LOADED_MASK_RAD1 = getLoadedMask(1); + private static final long CHUNK_LOADED_MASK_RAD2 = getLoadedMask(2); + -+ public static boolean areNeighboursFullLoaded(final long bitset, final int radius) { -+ switch (radius) { -+ case 0: { -+ return (bitset & CHUNK_LOADED_MASK_RAD0) == CHUNK_LOADED_MASK_RAD0; -+ } -+ case 1: { -+ return (bitset & CHUNK_LOADED_MASK_RAD1) == CHUNK_LOADED_MASK_RAD1; -+ } -+ case 2: { -+ return (bitset & CHUNK_LOADED_MASK_RAD2) == CHUNK_LOADED_MASK_RAD2; -+ } -+ -+ default: { -+ throw new IllegalArgumentException("Radius not recognized: " + radius); -+ } -+ } -+ } -+ + // only updated while holding scheduling lock + private FullChunkStatus pendingFullChunkStatus = FullChunkStatus.INACCESSIBLE; + // updated while holding no locks, but adds a ticket before to prevent pending status from dropping @@ -9869,6 +10650,17 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + } + + private void completeStatusConsumers(ChunkStatus status, final ChunkAccess chunk) { ++ // Update progress listener for LevelLoadingScreen ++ if (chunk != null) { ++ final ChunkProgressListener progressListener = this.world.getChunkSource().chunkMap.progressListener; ++ if (progressListener != null) { ++ final ChunkStatus finalStatus = status; ++ this.scheduler.scheduleChunkTask(this.chunkX, this.chunkZ, () -> { ++ progressListener.onStatusChange(this.vanillaChunkHolder.getPos(), finalStatus); ++ }); ++ } ++ } ++ + // need to tell future statuses to complete if cancelled + do { + this.completeStatusConsumers0(status, chunk); @@ -9892,7 +10684,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + LOGGER.error("Failed to process chunk status callback", thr); + } + } -+ }, PrioritisedExecutor.Priority.HIGHEST); ++ }, Priority.HIGHEST); + } + + private final Reference2ObjectOpenHashMap>> fullStatusWaiters = new Reference2ObjectOpenHashMap<>(); @@ -9920,7 +10712,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + LOGGER.error("Failed to process chunk status callback", thr); + } + } -+ }, PrioritisedExecutor.Priority.HIGHEST); ++ }, Priority.HIGHEST); + } + + // note: must hold scheduling lock @@ -10176,6 +10968,8 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + + public static final record SaveStat(boolean savedChunk, boolean savedEntityChunk, boolean savedPoiChunk) {} + ++ private static final MoonriseRegionFileIO.RegionFileType[] REGION_FILE_TYPES = MoonriseRegionFileIO.RegionFileType.values(); ++ + public SaveStat save(final boolean shutdown) { + TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Cannot save data off-main"); + @@ -10183,6 +10977,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + PoiChunk poi = this.getPoiChunk(); + ChunkEntitySlices entities = this.getEntityChunk(); + boolean executedUnloadTask = false; ++ final boolean[] executedUnloadTasks = new boolean[REGION_FILE_TYPES.length]; + + if (shutdown) { + // make sure that the async unloads complete @@ -10192,137 +10987,91 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + poi = this.unloadState.poiChunk(); + entities = this.unloadState.entityChunk(); + } -+ final UnloadTask chunkUnloadTask = this.chunkDataUnload; -+ final DelayedPrioritisedTask chunkDataUnloadTask = chunkUnloadTask == null ? null : chunkUnloadTask.task(); -+ if (chunkDataUnloadTask != null) { -+ final PrioritisedExecutor.PrioritisedTask unloadTask = chunkDataUnloadTask.getTask(); -+ if (unloadTask != null) { -+ executedUnloadTask = unloadTask.execute(); ++ for (final MoonriseRegionFileIO.RegionFileType regionFileType : REGION_FILE_TYPES) { ++ final UnloadTask unloadTask = this.getUnloadTask(regionFileType); ++ if (unloadTask == null) { ++ continue; + } -+ } -+ } -+ -+ final boolean forceNoSaveChunk = ChunkSystemFeatures.forceNoSave(chunk); -+ -+ // can only synchronously save worldgen chunks during shutdown -+ boolean canSaveChunk = !forceNoSaveChunk && (chunk != null && ((shutdown || chunk instanceof LevelChunk) && chunk.isUnsaved())); -+ boolean canSavePOI = !forceNoSaveChunk && (poi != null && poi.isDirty()); -+ boolean canSaveEntities = entities != null; + -+ if (canSaveChunk) { -+ canSaveChunk = this.saveChunk(chunk, false); -+ } -+ if (canSavePOI) { -+ canSavePOI = this.savePOI(poi, false); -+ } -+ if (canSaveEntities) { -+ // on shutdown, we need to force transient entity chunks to save -+ canSaveEntities = this.saveEntities(entities, shutdown); -+ if (shutdown) { -+ this.lastEntityUnload = null; ++ final PrioritisedExecutor.PrioritisedTask task = unloadTask.task(); ++ if (task != null && task.isQueued()) { ++ final boolean executed = task.execute(); ++ executedUnloadTask |= executed; ++ executedUnloadTasks[regionFileType.ordinal()] = executed; ++ } + } + } + -+ return executedUnloadTask | canSaveChunk | canSaveEntities | canSavePOI ? new SaveStat(executedUnloadTask || canSaveChunk, canSaveEntities, canSavePOI): null; -+ } -+ -+ static final class AsyncChunkSerializeTask implements Runnable { -+ -+ private final ServerLevel world; -+ private final ChunkAccess chunk; -+ private final AsyncChunkSaveData asyncSaveData; -+ private final NewChunkHolder toComplete; -+ -+ public AsyncChunkSerializeTask(final ServerLevel world, final ChunkAccess chunk, final AsyncChunkSaveData asyncSaveData, -+ final NewChunkHolder toComplete) { -+ this.world = world; -+ this.chunk = chunk; -+ this.asyncSaveData = asyncSaveData; -+ this.toComplete = toComplete; -+ } -+ -+ @Override -+ public void run() { -+ final CompoundTag toSerialize; -+ try { -+ toSerialize = ChunkSystemFeatures.saveChunkAsync(this.world, this.chunk, this.asyncSaveData); -+ } catch (final Throwable throwable) { -+ LOGGER.error("Failed to asynchronously save chunk " + this.chunk.getPos() + " for world '" + WorldUtil.getWorldName(this.world) + "', falling back to synchronous save", throwable); -+ final ChunkPos pos = this.chunk.getPos(); -+ ((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().scheduleChunkTask(pos.x, pos.z, () -> { -+ final CompoundTag synchronousSave; -+ try { -+ synchronousSave = ChunkSystemFeatures.saveChunkAsync(AsyncChunkSerializeTask.this.world, AsyncChunkSerializeTask.this.chunk, AsyncChunkSerializeTask.this.asyncSaveData); -+ } catch (final Throwable throwable2) { -+ LOGGER.error("Failed to synchronously save chunk " + AsyncChunkSerializeTask.this.chunk.getPos() + " for world '" + WorldUtil.getWorldName(AsyncChunkSerializeTask.this.world) + "', chunk data will be lost", throwable2); -+ AsyncChunkSerializeTask.this.toComplete.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, null); -+ return; -+ } ++ final boolean forceNoSaveChunk = PlatformHooks.get().forceNoSave(chunk); + -+ AsyncChunkSerializeTask.this.toComplete.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, synchronousSave); -+ LOGGER.info("Successfully serialized chunk " + AsyncChunkSerializeTask.this.chunk.getPos() + " for world '" + WorldUtil.getWorldName(AsyncChunkSerializeTask.this.world) + "' synchronously"); ++ // can only synchronously save worldgen chunks during shutdown ++ boolean canSaveChunk = !forceNoSaveChunk && (chunk != null && ((shutdown || chunk instanceof LevelChunk) && chunk.isUnsaved())); ++ boolean canSavePOI = !forceNoSaveChunk && (poi != null && poi.isDirty()); ++ boolean canSaveEntities = entities != null; + -+ }, PrioritisedExecutor.Priority.HIGHEST); -+ return; ++ if (canSaveChunk) { ++ canSaveChunk = this.saveChunk(chunk, false); ++ } ++ if (canSavePOI) { ++ canSavePOI = this.savePOI(poi, false); ++ } ++ if (canSaveEntities) { ++ // on shutdown, we need to force transient entity chunks to save ++ canSaveEntities = this.saveEntities(entities, shutdown); ++ if (shutdown) { ++ this.lastEntityUnload = null; + } -+ this.toComplete.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, toSerialize); + } + -+ @Override -+ public String toString() { -+ return "AsyncChunkSerializeTask{" + -+ "chunk={pos=" + this.chunk.getPos() + ",world=\"" + WorldUtil.getWorldName(this.world) + "\"}" + -+ "}"; -+ } ++ return executedUnloadTask | canSaveChunk | canSaveEntities | canSavePOI ? ++ new SaveStat( ++ canSaveChunk | executedUnloadTasks[MoonriseRegionFileIO.RegionFileType.CHUNK_DATA.ordinal()], ++ canSaveEntities | executedUnloadTasks[MoonriseRegionFileIO.RegionFileType.ENTITY_DATA.ordinal()], ++ canSavePOI | executedUnloadTasks[MoonriseRegionFileIO.RegionFileType.POI_DATA.ordinal()] ++ ) ++ : null; + } + + private boolean saveChunk(final ChunkAccess chunk, final boolean unloading) { + if (!chunk.isUnsaved()) { + if (unloading) { -+ this.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, null); ++ this.completeAsyncUnloadDataSave(MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, null); + } + return false; + } -+ boolean completing = false; -+ boolean failedAsyncPrepare = false; + try { -+ if (unloading && ChunkSystemFeatures.supportsAsyncChunkSave()) { -+ try { -+ final AsyncChunkSaveData asyncSaveData = ChunkSystemFeatures.getAsyncSaveData(this.world, chunk); ++ final SerializableChunkData chunkData = SerializableChunkData.copyOf(this.world, chunk); ++ PlatformHooks.get().chunkSyncSave(this.world, chunk, chunkData); + -+ final PrioritisedExecutor.PrioritisedTask task = this.scheduler.loadExecutor.createTask(new AsyncChunkSerializeTask(this.world, chunk, asyncSaveData, this)); ++ chunk.tryMarkSaved(); + -+ this.chunkDataUnload.task().setTask(task); ++ final CallbackCompletable completable = new CallbackCompletable<>(); + -+ chunk.setUnsaved(false); ++ final Runnable run = () -> { ++ final CompoundTag data = chunkData.write(); + -+ task.queue(); ++ completable.complete(data); + -+ return true; -+ } catch (final Throwable thr) { -+ LOGGER.error("Failed to prepare async chunk data (" + this.chunkX + "," + this.chunkZ + ") in world '" + WorldUtil.getWorldName(this.world) + "', falling back to synchronous save", thr); -+ failedAsyncPrepare = true; -+ // fall through to synchronous save ++ if (unloading) { ++ NewChunkHolder.this.completeAsyncUnloadDataSave(MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, data); + } -+ } -+ -+ final CompoundTag save = ChunkSerializer.write(this.world, chunk); ++ }; + ++ final PrioritisedExecutor.PrioritisedTask task; + if (unloading) { -+ completing = true; -+ this.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, save); -+ if (failedAsyncPrepare) { -+ LOGGER.info("Successfully serialized chunk data (" + this.chunkX + "," + this.chunkZ + ") in world '" + WorldUtil.getWorldName(this.world) + "' synchronously"); -+ } ++ this.chunkDataUnload.toRun().setRunnable(run); ++ task = this.chunkDataUnload.task(); + } else { -+ RegionFileIOThread.scheduleSave(this.world, this.chunkX, this.chunkZ, save, RegionFileIOThread.RegionFileType.CHUNK_DATA); ++ task = this.scheduler.saveExecutor.createTask(run); + } -+ chunk.setUnsaved(false); ++ ++ task.queue(); ++ ++ MoonriseRegionFileIO.scheduleSave( ++ this.world, this.chunkX, this.chunkZ, completable, task, MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, Priority.NORMAL ++ ); + } catch (final Throwable thr) { + LOGGER.error("Failed to save chunk data (" + this.chunkX + "," + this.chunkZ + ") in world '" + WorldUtil.getWorldName(this.world) + "'", thr); -+ if (unloading && !completing) { -+ this.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, null); -+ } + } + + return true; @@ -10340,7 +11089,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + return false; + } + try { -+ mergeFrom = RegionFileIOThread.loadData(this.world, this.chunkX, this.chunkZ, RegionFileIOThread.RegionFileType.ENTITY_DATA, PrioritisedExecutor.Priority.BLOCKING); ++ mergeFrom = MoonriseRegionFileIO.loadData(this.world, this.chunkX, this.chunkZ, MoonriseRegionFileIO.RegionFileType.ENTITY_DATA, Priority.BLOCKING); + } catch (final Exception ex) { + LOGGER.error("Cannot merge transient entities for chunk (" + this.chunkX + "," + this.chunkZ + ") in world '" + WorldUtil.getWorldName(this.world) + "', data on disk will be replaced", ex); + } @@ -10359,7 +11108,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + return false; + } + -+ RegionFileIOThread.scheduleSave(this.world, this.chunkX, this.chunkZ, save, RegionFileIOThread.RegionFileType.ENTITY_DATA); ++ MoonriseRegionFileIO.scheduleSave(this.world, this.chunkX, this.chunkZ, save, MoonriseRegionFileIO.RegionFileType.ENTITY_DATA); + this.lastEntitySaveNull = save == null; + if (unloading) { + this.lastEntityUnload = save; @@ -10383,7 +11132,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + return false; + } + -+ RegionFileIOThread.scheduleSave(this.world, this.chunkX, this.chunkZ, save, RegionFileIOThread.RegionFileType.POI_DATA); ++ MoonriseRegionFileIO.scheduleSave(this.world, this.chunkX, this.chunkZ, save, MoonriseRegionFileIO.RegionFileType.POI_DATA); + this.lastPoiSaveNull = save == null; + if (unloading) { + this.poiDataUnload.completable().complete(save); @@ -10430,7 +11179,7 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + return element == null ? JsonNull.INSTANCE : new JsonPrimitive(element.toString()); + } + -+ private static JsonObject serializeCompletable(final Completable completable) { ++ private static JsonObject serializeCompletable(final CallbackCompletable completable) { + final JsonObject ret = new JsonObject(); + + if (completable == null) { @@ -10525,13 +11274,13 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 + ret.add("poi_unload_completable", serializeCompletable(poiDataUnload == null ? null : poiDataUnload.completable())); + ret.add("chunk_unload_completable", serializeCompletable(chunkDataUnload == null ? null : chunkDataUnload.completable())); + -+ final DelayedPrioritisedTask unloadTask = chunkDataUnload == null ? null : chunkDataUnload.task(); ++ final PrioritisedExecutor.PrioritisedTask unloadTask = chunkDataUnload == null ? null : chunkDataUnload.task(); + if (unloadTask == null) { + ret.addProperty("unload_task_priority", "null"); -+ ret.addProperty("unload_task_priority_raw", "null"); ++ ret.addProperty("unload_task_suborder", Long.valueOf(0L)); + } else { + ret.addProperty("unload_task_priority", Objects.toString(unloadTask.getPriority())); -+ ret.addProperty("unload_task_priority_raw", Integer.valueOf(unloadTask.getPriorityInternal())); ++ ret.addProperty("unload_task_suborder", Long.valueOf(unloadTask.getSubOrder())); + } + + ret.addProperty("killed", Boolean.valueOf(this.unloaded)); @@ -10541,14 +11290,14 @@ index 0000000000000000000000000000000000000000..45eda96fd8a1acb87dbb69ce5495fec7 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/PriorityHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/PriorityHolder.java new file mode 100644 -index 0000000000000000000000000000000000000000..261e09454f49d04eb159c984ec695d7c7aa6a3a8 +index 0000000000000000000000000000000000000000..6b468c621b74449a6218391f6477cf63cfc98c7c --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/PriorityHolder.java @@ -0,0 +1,215 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; + -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; +import java.lang.invoke.VarHandle; + +public abstract class PriorityHolder { @@ -10575,8 +11324,8 @@ index 0000000000000000000000000000000000000000..261e09454f49d04eb159c984ec695d7c + PRIORITY_HANDLE.set((PriorityHolder)this, (int)val); + } + -+ protected PriorityHolder(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ protected PriorityHolder(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.setPriorityPlain(priority.priority); @@ -10616,7 +11365,7 @@ index 0000000000000000000000000000000000000000..261e09454f49d04eb159c984ec695d7c + return; + } + -+ this.scheduleTask(PrioritisedExecutor.Priority.getPriority(priority)); ++ this.scheduleTask(Priority.getPriority(priority)); + + int failures = 0; + for (;;) { @@ -10633,7 +11382,7 @@ index 0000000000000000000000000000000000000000..261e09454f49d04eb159c984ec695d7c + return; + } + -+ this.setPriorityScheduled(PrioritisedExecutor.Priority.getPriority(priority)); ++ this.setPriorityScheduled(Priority.getPriority(priority)); + + ++failures; + for (int i = 0; i < failures; ++i) { @@ -10642,19 +11391,19 @@ index 0000000000000000000000000000000000000000..261e09454f49d04eb159c984ec695d7c + } + } + -+ public final PrioritisedExecutor.Priority getPriority() { ++ public final Priority getPriority() { + final int ret = this.getPriorityVolatile(); + if ((ret & PRIORITY_EXECUTED) != 0) { -+ return PrioritisedExecutor.Priority.COMPLETING; ++ return Priority.COMPLETING; + } + if ((ret & PRIORITY_SCHEDULED) != 0) { + return this.getScheduledPriority(); + } -+ return PrioritisedExecutor.Priority.getPriority(ret); ++ return Priority.getPriority(ret); + } + -+ public final void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public final void lowerPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + @@ -10686,8 +11435,8 @@ index 0000000000000000000000000000000000000000..261e09454f49d04eb159c984ec695d7c + } + } + -+ public final void setPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public final void setPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + @@ -10715,8 +11464,8 @@ index 0000000000000000000000000000000000000000..261e09454f49d04eb159c984ec695d7c + } + } + -+ public final void raisePriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public final void raisePriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + @@ -10750,15 +11499,15 @@ index 0000000000000000000000000000000000000000..261e09454f49d04eb159c984ec695d7c + + protected abstract void cancelScheduled(); + -+ protected abstract PrioritisedExecutor.Priority getScheduledPriority(); ++ protected abstract Priority getScheduledPriority(); + -+ protected abstract void scheduleTask(final PrioritisedExecutor.Priority priority); ++ protected abstract void scheduleTask(final Priority priority); + -+ protected abstract void lowerPriorityScheduled(final PrioritisedExecutor.Priority priority); ++ protected abstract void lowerPriorityScheduled(final Priority priority); + -+ protected abstract void setPriorityScheduled(final PrioritisedExecutor.Priority priority); ++ protected abstract void setPriorityScheduled(final Priority priority); + -+ protected abstract void raisePriorityScheduled(final PrioritisedExecutor.Priority priority); ++ protected abstract void raisePriorityScheduled(final Priority priority); +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ThreadedTicketLevelPropagator.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ThreadedTicketLevelPropagator.java new file mode 100644 @@ -12225,17 +12974,17 @@ index 0000000000000000000000000000000000000000..310a8f80debadd64c2d962ebf83b7d05 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/executor/RadiusAwarePrioritisedExecutor.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/executor/RadiusAwarePrioritisedExecutor.java new file mode 100644 -index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373ba811ba8b +index 0000000000000000000000000000000000000000..5f4b99d8c5453f8ad2e600a57ea4e7dafa2d45f8 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/executor/RadiusAwarePrioritisedExecutor.java -@@ -0,0 +1,668 @@ +@@ -0,0 +1,729 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.executor; + -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.util.Priority; +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; +import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; -+ +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; @@ -12247,15 +12996,36 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + return Long.compare(t1.id, t2.id); + }; + -+ private final DependencyTree[] queues = new DependencyTree[PrioritisedExecutor.Priority.TOTAL_SCHEDULABLE_PRIORITIES]; ++ private final PrioritisedExecutor executor; ++ private final DependencyTree[] queues = new DependencyTree[Priority.TOTAL_SCHEDULABLE_PRIORITIES]; + private static final int NO_TASKS_QUEUED = -1; + private int selectedQueue = NO_TASKS_QUEUED; + private boolean canQueueTasks = true; + + public RadiusAwarePrioritisedExecutor(final PrioritisedExecutor executor, final int maxToSchedule) { ++ this.executor = executor; ++ + for (int i = 0; i < this.queues.length; ++i) { -+ this.queues[i] = new DependencyTree(this, executor, maxToSchedule, i); ++ this.queues[i] = new DependencyTree(this, executor, maxToSchedule); ++ } ++ } ++ ++ public void setMaxToSchedule(final int maxToSchedule) { ++ final List tasks; ++ ++ synchronized (this) { ++ for (final DependencyTree dependencyTree : this.queues) { ++ dependencyTree.maxToSchedule = maxToSchedule; ++ } ++ ++ if (this.selectedQueue == NO_TASKS_QUEUED || !this.canQueueTasks) { ++ return; ++ } ++ ++ tasks = this.queues[this.selectedQueue].tryPushTasks(); + } ++ ++ scheduleTasks(tasks); + } + + private boolean canQueueTasks() { @@ -12287,7 +13057,7 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + return null; + } + -+ private List queue(final Task task, final PrioritisedExecutor.Priority priority) { ++ private List queue(final Task task, final Priority priority) { + final int priorityId = priority.priority; + final DependencyTree queue = this.queues[priorityId]; + @@ -12310,7 +13080,7 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + return null; + } + -+ if (PrioritisedExecutor.Priority.isHigherPriority(priorityId, this.selectedQueue)) { ++ if (Priority.isHigherPriority(priorityId, this.selectedQueue)) { + // prevent the lower priority tree from queueing more tasks + this.canQueueTasks = false; + return null; @@ -12321,7 +13091,7 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + } + + public PrioritisedExecutor.PrioritisedTask createTask(final int chunkX, final int chunkZ, final int radius, -+ final Runnable run, final PrioritisedExecutor.Priority priority) { ++ final Runnable run, final Priority priority) { + if (radius < 0) { + throw new IllegalArgumentException("Radius must be > 0: " + radius); + } @@ -12330,11 +13100,11 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + + public PrioritisedExecutor.PrioritisedTask createTask(final int chunkX, final int chunkZ, final int radius, + final Runnable run) { -+ return this.createTask(chunkX, chunkZ, radius, run, PrioritisedExecutor.Priority.NORMAL); ++ return this.createTask(chunkX, chunkZ, radius, run, Priority.NORMAL); + } + + public PrioritisedExecutor.PrioritisedTask queueTask(final int chunkX, final int chunkZ, final int radius, -+ final Runnable run, final PrioritisedExecutor.Priority priority) { ++ final Runnable run, final Priority priority) { + final PrioritisedExecutor.PrioritisedTask ret = this.createTask(chunkX, chunkZ, radius, run, priority); + + ret.queue(); @@ -12351,15 +13121,15 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + return ret; + } + -+ public PrioritisedExecutor.PrioritisedTask createInfiniteRadiusTask(final Runnable run, final PrioritisedExecutor.Priority priority) { ++ public PrioritisedExecutor.PrioritisedTask createInfiniteRadiusTask(final Runnable run, final Priority priority) { + return new Task(this, 0, 0, -1, run, priority); + } + + public PrioritisedExecutor.PrioritisedTask createInfiniteRadiusTask(final Runnable run) { -+ return this.createInfiniteRadiusTask(run, PrioritisedExecutor.Priority.NORMAL); ++ return this.createInfiniteRadiusTask(run, Priority.NORMAL); + } + -+ public PrioritisedExecutor.PrioritisedTask queueInfiniteRadiusTask(final Runnable run, final PrioritisedExecutor.Priority priority) { ++ public PrioritisedExecutor.PrioritisedTask queueInfiniteRadiusTask(final Runnable run, final Priority priority) { + final PrioritisedExecutor.PrioritisedTask ret = this.createInfiniteRadiusTask(run, priority); + + ret.queue(); @@ -12368,20 +13138,27 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + } + + public PrioritisedExecutor.PrioritisedTask queueInfiniteRadiusTask(final Runnable run) { -+ final PrioritisedExecutor.PrioritisedTask ret = this.createInfiniteRadiusTask(run, PrioritisedExecutor.Priority.NORMAL); ++ final PrioritisedExecutor.PrioritisedTask ret = this.createInfiniteRadiusTask(run, Priority.NORMAL); + + ret.queue(); + + return ret; + } + ++ private static void scheduleTasks(final List toSchedule) { ++ if (toSchedule != null) { ++ for (int i = 0, len = toSchedule.size(); i < len; ++i) { ++ toSchedule.get(i).queue(); ++ } ++ } ++ } ++ + // all accesses must be synchronised by the radius aware object + private static final class DependencyTree { + + private final RadiusAwarePrioritisedExecutor scheduler; + private final PrioritisedExecutor executor; -+ private final int maxToSchedule; -+ private final int treeIndex; ++ private int maxToSchedule; + + private int currentlyExecuting; + private long idGenerator; @@ -12394,11 +13171,10 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + private final Long2ReferenceOpenHashMap nodeByPosition = new Long2ReferenceOpenHashMap<>(); + + public DependencyTree(final RadiusAwarePrioritisedExecutor scheduler, final PrioritisedExecutor executor, -+ final int maxToSchedule, final int treeIndex) { ++ final int maxToSchedule) { + this.scheduler = scheduler; + this.executor = executor; + this.maxToSchedule = maxToSchedule; -+ this.treeIndex = treeIndex; + } + + public boolean hasWaitingTasks() { @@ -12643,13 +13419,13 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + private final int chunkZ; + private final int radius; + private Runnable run; -+ private PrioritisedExecutor.Priority priority; ++ private Priority priority; + + private DependencyNode dependencyNode; + private PrioritisedExecutor.PrioritisedTask queuedTask; + + private Task(final RadiusAwarePrioritisedExecutor scheduler, final int chunkX, final int chunkZ, final int radius, -+ final Runnable run, final PrioritisedExecutor.Priority priority) { ++ final Runnable run, final Priority priority) { + this.scheduler = scheduler; + this.chunkX = chunkX; + this.chunkZ = chunkZ; @@ -12672,14 +13448,6 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + run.run(); + } + -+ private static void scheduleTasks(final List toSchedule) { -+ if (toSchedule != null) { -+ for (int i = 0, len = toSchedule.size(); i < len; ++i) { -+ toSchedule.get(i).queue(); -+ } -+ } -+ } -+ + private void returnNode() { + final List toSchedule; + synchronized (this.scheduler) { @@ -12692,6 +13460,11 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + } + + @Override ++ public PrioritisedExecutor getExecutor() { ++ return this.scheduler.executor; ++ } ++ ++ @Override + public void run() { + final Runnable run = this.run; + this.run = null; @@ -12706,7 +13479,7 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + public boolean queue() { + final List toSchedule; + synchronized (this.scheduler) { -+ if (this.queuedTask != null || this.dependencyNode != null || this.priority == PrioritisedExecutor.Priority.COMPLETING) { ++ if (this.queuedTask != null || this.dependencyNode != null || this.priority == Priority.COMPLETING) { + return false; + } + @@ -12718,15 +13491,22 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + } + + @Override ++ public boolean isQueued() { ++ synchronized (this.scheduler) { ++ return (this.queuedTask != null || this.dependencyNode != null) && this.priority != Priority.COMPLETING; ++ } ++ } ++ ++ @Override + public boolean cancel() { + final PrioritisedExecutor.PrioritisedTask task; + synchronized (this.scheduler) { + if ((task = this.queuedTask) == null) { -+ if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { ++ if (this.priority == Priority.COMPLETING) { + return false; + } + -+ this.priority = PrioritisedExecutor.Priority.COMPLETING; ++ this.priority = Priority.COMPLETING; + if (this.dependencyNode != null) { + this.dependencyNode.purged = true; + this.dependencyNode = null; @@ -12750,11 +13530,11 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + final PrioritisedExecutor.PrioritisedTask task; + synchronized (this.scheduler) { + if ((task = this.queuedTask) == null) { -+ if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { ++ if (this.priority == Priority.COMPLETING) { + return false; + } + -+ this.priority = PrioritisedExecutor.Priority.COMPLETING; ++ this.priority = Priority.COMPLETING; + if (this.dependencyNode != null) { + this.dependencyNode.purged = true; + this.dependencyNode = null; @@ -12774,7 +13554,7 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + } + + @Override -+ public PrioritisedExecutor.Priority getPriority() { ++ public Priority getPriority() { + final PrioritisedExecutor.PrioritisedTask task; + synchronized (this.scheduler) { + if ((task = this.queuedTask) == null) { @@ -12786,8 +13566,8 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + } + + @Override -+ public boolean setPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public boolean setPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + @@ -12795,7 +13575,7 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + List toSchedule = null; + synchronized (this.scheduler) { + if ((task = this.queuedTask) == null) { -+ if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { ++ if (this.priority == Priority.COMPLETING) { + return false; + } + @@ -12823,8 +13603,8 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + } + + @Override -+ public boolean raisePriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public boolean raisePriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + @@ -12832,7 +13612,7 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + List toSchedule = null; + synchronized (this.scheduler) { + if ((task = this.queuedTask) == null) { -+ if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { ++ if (this.priority == Priority.COMPLETING) { + return false; + } + @@ -12860,8 +13640,8 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + } + + @Override -+ public boolean lowerPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public boolean lowerPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + @@ -12869,7 +13649,7 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + List toSchedule = null; + synchronized (this.scheduler) { + if ((task = this.queuedTask) == null) { -+ if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { ++ if (this.priority == Priority.COMPLETING) { + return false; + } + @@ -12895,19 +13675,50 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b + + return true; + } ++ ++ @Override ++ public long getSubOrder() { ++ // TODO implement ++ return 0; ++ } ++ ++ @Override ++ public boolean setSubOrder(final long subOrder) { ++ // TODO implement ++ return false; ++ } ++ ++ @Override ++ public boolean raiseSubOrder(final long subOrder) { ++ // TODO implement ++ return false; ++ } ++ ++ @Override ++ public boolean lowerSubOrder(final long subOrder) { ++ // TODO implement ++ return false; ++ } ++ ++ @Override ++ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder) { ++ // TODO implement ++ return this.setPriority(priority); ++ } + } +} -\ No newline at end of file diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java new file mode 100644 -index 0000000000000000000000000000000000000000..fbdf721e8b4cfe6cef4ee60c53c680cbfc858d88 +index 0000000000000000000000000000000000000000..6ab353b0d2465c3680bb3c8d0852ba0f65c00fd2 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java -@@ -0,0 +1,142 @@ +@@ -0,0 +1,151 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; + -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.PlatformHooks; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; +import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk; +import ca.spottedleaf.moonrise.patches.chunk_system.level.poi.ChunkSystemPoiManager; @@ -12935,7 +13746,7 @@ index 0000000000000000000000000000000000000000..fbdf721e8b4cfe6cef4ee60c53c680cb + private final PrioritisedExecutor.PrioritisedTask convertToFullTask; + + public ChunkFullTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, final int chunkZ, -+ final NewChunkHolder chunkHolder, final ChunkAccess fromChunk, final PrioritisedExecutor.Priority priority) { ++ final NewChunkHolder chunkHolder, final ChunkAccess fromChunk, final Priority priority) { + super(scheduler, world, chunkX, chunkZ); + this.chunkHolder = chunkHolder; + this.fromChunk = fromChunk; @@ -12949,6 +13760,8 @@ index 0000000000000000000000000000000000000000..fbdf721e8b4cfe6cef4ee60c53c680cb + + @Override + public void run() { ++ final PlatformHooks platformHooks = PlatformHooks.get(); ++ + // See Vanilla ChunkPyramid#LOADING_PYRAMID.FULL for what this function should be doing + final LevelChunk chunk; + try { @@ -12967,7 +13780,7 @@ index 0000000000000000000000000000000000000000..fbdf721e8b4cfe6cef4ee60c53c680cb + final ServerLevel world = this.world; + final ProtoChunk protoChunk = (ProtoChunk)this.fromChunk; + chunk = new LevelChunk(this.world, protoChunk, (final LevelChunk unused) -> { -+ ChunkStatusTasks.postLoadProtoChunk(world, protoChunk.getEntities(), protoChunk.getPos()); // Paper - pass chunk pos ++ PlatformHooks.get().postLoadProtoChunk(world, protoChunk); + }); + this.chunkHolder.replaceProtoChunk(new ImposterProtoChunk(chunk, false)); + } @@ -12977,16 +13790,21 @@ index 0000000000000000000000000000000000000000..fbdf721e8b4cfe6cef4ee60c53c680cb + final NewChunkHolder chunkHolder = this.chunkHolder; + + chunk.setFullStatus(chunkHolder::getChunkStatus); -+ chunk.runPostLoad(); -+ // Unlike Vanilla, we load the entity chunk here, as we load the NBT in empty status (unlike Vanilla) -+ // This brings entity addition back in line with older versions of the game -+ // Since we load the NBT in the empty status, this will never block for I/O -+ ((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager.getOrCreateEntityChunk(this.chunkX, this.chunkZ, false); -+ -+ // we don't need the entitiesInLevel, not sure why it's there -+ chunk.setLoaded(true); -+ chunk.registerAllBlockEntitiesAfterLevelLoad(); -+ chunk.registerTickContainerInLevel(this.world); ++ try { ++ platformHooks.setCurrentlyLoading(this.chunkHolder.vanillaChunkHolder, chunk); ++ chunk.runPostLoad(); ++ // Unlike Vanilla, we load the entity chunk here, as we load the NBT in empty status (unlike Vanilla) ++ // This brings entity addition back in line with older versions of the game ++ // Since we load the NBT in the empty status, this will never block for I/O ++ ((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager.getOrCreateEntityChunk(this.chunkX, this.chunkZ, false); ++ chunk.setLoaded(true); ++ chunk.registerAllBlockEntitiesAfterLevelLoad(); ++ chunk.registerTickContainerInLevel(this.world); ++ chunk.setUnsavedListener(this.world.getChunkSource().chunkMap.worldGenContext.unsavedListener()); ++ platformHooks.chunkFullStatusComplete(chunk, (ProtoChunk)this.fromChunk); ++ } finally { ++ platformHooks.setCurrentlyLoading(this.chunkHolder.vanillaChunkHolder, null); ++ } + } catch (final Throwable throwable) { + this.complete(null, throwable); + return; @@ -13018,29 +13836,29 @@ index 0000000000000000000000000000000000000000..fbdf721e8b4cfe6cef4ee60c53c680cb + } + + @Override -+ public PrioritisedExecutor.Priority getPriority() { ++ public Priority getPriority() { + return this.convertToFullTask.getPriority(); + } + + @Override -+ public void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void lowerPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.convertToFullTask.lowerPriority(priority); + } + + @Override -+ public void setPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void setPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.convertToFullTask.setPriority(priority); + } + + @Override -+ public void raisePriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void raisePriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.convertToFullTask.raisePriority(priority); @@ -13048,13 +13866,13 @@ index 0000000000000000000000000000000000000000..fbdf721e8b4cfe6cef4ee60c53c680cb +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLightTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLightTask.java new file mode 100644 -index 0000000000000000000000000000000000000000..7c2e6752228fac175c4aa97fa3d817b8a938922f +index 0000000000000000000000000000000000000000..4538ccfaea83d217ed85eaf16e82393c7f286489 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLightTask.java @@ -0,0 +1,181 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; + -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.util.Priority; +import ca.spottedleaf.moonrise.common.util.WorldUtil; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.PriorityHolder; @@ -13079,9 +13897,9 @@ index 0000000000000000000000000000000000000000..7c2e6752228fac175c4aa97fa3d817b8 + private final LightTaskPriorityHolder priorityHolder; + + public ChunkLightTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, final int chunkZ, -+ final ChunkAccess chunk, final PrioritisedExecutor.Priority priority) { ++ final ChunkAccess chunk, final Priority priority) { + super(scheduler, world, chunkX, chunkZ); -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.priorityHolder = new LightTaskPriorityHolder(priority, this); @@ -13109,22 +13927,22 @@ index 0000000000000000000000000000000000000000..7c2e6752228fac175c4aa97fa3d817b8 + } + + @Override -+ public PrioritisedExecutor.Priority getPriority() { ++ public Priority getPriority() { + return this.priorityHolder.getPriority(); + } + + @Override -+ public void lowerPriority(final PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(final Priority priority) { + this.priorityHolder.raisePriority(priority); + } + + @Override -+ public void setPriority(final PrioritisedExecutor.Priority priority) { ++ public void setPriority(final Priority priority) { + this.priorityHolder.setPriority(priority); + } + + @Override -+ public void raisePriority(final PrioritisedExecutor.Priority priority) { ++ public void raisePriority(final Priority priority) { + this.priorityHolder.raisePriority(priority); + } + @@ -13132,7 +13950,7 @@ index 0000000000000000000000000000000000000000..7c2e6752228fac175c4aa97fa3d817b8 + + private final ChunkLightTask task; + -+ private LightTaskPriorityHolder(final PrioritisedExecutor.Priority priority, final ChunkLightTask task) { ++ private LightTaskPriorityHolder(final Priority priority, final ChunkLightTask task) { + super(priority); + this.task = task; + } @@ -13144,13 +13962,13 @@ index 0000000000000000000000000000000000000000..7c2e6752228fac175c4aa97fa3d817b8 + } + + @Override -+ protected PrioritisedExecutor.Priority getScheduledPriority() { ++ protected Priority getScheduledPriority() { + final ChunkLightTask task = this.task; + return ((StarLightLightingProvider)task.world.getChunkSource().getLightEngine()).starlight$getLightEngine().getServerLightQueue().getPriority(task.chunkX, task.chunkZ); + } + + @Override -+ protected void scheduleTask(final PrioritisedExecutor.Priority priority) { ++ protected void scheduleTask(final Priority priority) { + final ChunkLightTask task = this.task; + final StarLightInterface starLightInterface = ((StarLightLightingProvider)task.world.getChunkSource().getLightEngine()).starlight$getLightEngine(); + final StarLightInterface.ServerLightQueue lightQueue = starLightInterface.getServerLightQueue(); @@ -13159,7 +13977,7 @@ index 0000000000000000000000000000000000000000..7c2e6752228fac175c4aa97fa3d817b8 + } + + @Override -+ protected void lowerPriorityScheduled(final PrioritisedExecutor.Priority priority) { ++ protected void lowerPriorityScheduled(final Priority priority) { + final ChunkLightTask task = this.task; + final StarLightInterface starLightInterface = ((StarLightLightingProvider)task.world.getChunkSource().getLightEngine()).starlight$getLightEngine(); + final StarLightInterface.ServerLightQueue lightQueue = starLightInterface.getServerLightQueue(); @@ -13167,7 +13985,7 @@ index 0000000000000000000000000000000000000000..7c2e6752228fac175c4aa97fa3d817b8 + } + + @Override -+ protected void setPriorityScheduled(final PrioritisedExecutor.Priority priority) { ++ protected void setPriorityScheduled(final Priority priority) { + final ChunkLightTask task = this.task; + final StarLightInterface starLightInterface = ((StarLightLightingProvider)task.world.getChunkSource().getLightEngine()).starlight$getLightEngine(); + final StarLightInterface.ServerLightQueue lightQueue = starLightInterface.getServerLightQueue(); @@ -13175,7 +13993,7 @@ index 0000000000000000000000000000000000000000..7c2e6752228fac175c4aa97fa3d817b8 + } + + @Override -+ protected void raisePriorityScheduled(final PrioritisedExecutor.Priority priority) { ++ protected void raisePriorityScheduled(final Priority priority) { + final ChunkLightTask task = this.task; + final StarLightInterface starLightInterface = ((StarLightLightingProvider)task.world.getChunkSource().getLightEngine()).starlight$getLightEngine(); + final StarLightInterface.ServerLightQueue lightQueue = starLightInterface.getServerLightQueue(); @@ -13235,19 +14053,20 @@ index 0000000000000000000000000000000000000000..7c2e6752228fac175c4aa97fa3d817b8 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java new file mode 100644 -index 0000000000000000000000000000000000000000..1ab93f219246d0b4dcdfd0f685f47c13091425f8 +index 0000000000000000000000000000000000000000..e0a88615a8b6d58191f29b1ff1a26427f0a4c1a6 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java -@@ -0,0 +1,487 @@ +@@ -0,0 +1,494 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; + +import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.PlatformHooks; +import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystemConverters; -+import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystemFeatures; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; +import ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder; @@ -13259,7 +14078,7 @@ index 0000000000000000000000000000000000000000..1ab93f219246d0b4dcdfd0f685f47c13 +import net.minecraft.world.level.chunk.ProtoChunk; +import net.minecraft.world.level.chunk.UpgradeData; +import net.minecraft.world.level.chunk.status.ChunkStatus; -+import net.minecraft.world.level.chunk.storage.ChunkSerializer; ++import net.minecraft.world.level.chunk.storage.SerializableChunkData; +import net.minecraft.world.level.levelgen.blending.BlendingData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @@ -13282,7 +14101,7 @@ index 0000000000000000000000000000000000000000..1ab93f219246d0b4dcdfd0f685f47c13 + private final AtomicInteger taskCountToComplete = new AtomicInteger(3); // one for poi, one for entity, and one for chunk data + + public ChunkLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, final int chunkZ, -+ final NewChunkHolder chunkHolder, final PrioritisedExecutor.Priority priority) { ++ final NewChunkHolder chunkHolder, final Priority priority) { + super(scheduler, world, chunkX, chunkZ); + this.chunkHolder = chunkHolder; + this.loadTask = new ChunkDataLoadTask(scheduler, world, chunkX, chunkZ, priority); @@ -13411,12 +14230,12 @@ index 0000000000000000000000000000000000000000..1ab93f219246d0b4dcdfd0f685f47c13 + } + + @Override -+ public PrioritisedExecutor.Priority getPriority() { ++ public Priority getPriority() { + return this.loadTask.getPriority(); + } + + @Override -+ public void lowerPriority(final PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(final Priority priority) { + final EntityDataLoadTask entityLoad = this.chunkHolder.getEntityDataLoadTask(); + if (entityLoad != null) { + entityLoad.lowerPriority(priority); @@ -13432,7 +14251,7 @@ index 0000000000000000000000000000000000000000..1ab93f219246d0b4dcdfd0f685f47c13 + } + + @Override -+ public void setPriority(final PrioritisedExecutor.Priority priority) { ++ public void setPriority(final Priority priority) { + final EntityDataLoadTask entityLoad = this.chunkHolder.getEntityDataLoadTask(); + if (entityLoad != null) { + entityLoad.setPriority(priority); @@ -13448,7 +14267,7 @@ index 0000000000000000000000000000000000000000..1ab93f219246d0b4dcdfd0f685f47c13 + } + + @Override -+ public void raisePriority(final PrioritisedExecutor.Priority priority) { ++ public void raisePriority(final Priority priority) { + final EntityDataLoadTask entityLoad = this.chunkHolder.getEntityDataLoadTask(); + if (entityLoad != null) { + entityLoad.raisePriority(priority); @@ -13472,8 +14291,8 @@ index 0000000000000000000000000000000000000000..1ab93f219246d0b4dcdfd0f685f47c13 + protected static final VarHandle COMPLETED_HANDLE = ConcurrentUtil.getVarHandle(CallbackDataLoadTask.class, "completed", boolean.class); + + protected CallbackDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -+ final int chunkZ, final RegionFileIOThread.RegionFileType type, -+ final PrioritisedExecutor.Priority priority) { ++ final int chunkZ, final MoonriseRegionFileIO.RegionFileType type, ++ final Priority priority) { + super(scheduler, world, chunkX, chunkZ, type, priority); + } + @@ -13513,10 +14332,13 @@ index 0000000000000000000000000000000000000000..1ab93f219246d0b4dcdfd0f685f47c13 + } + } + -+ private static final class ChunkDataLoadTask extends CallbackDataLoadTask { ++ ++ private static record ReadChunk(ProtoChunk protoChunk, SerializableChunkData chunkData) {} ++ ++ private static final class ChunkDataLoadTask extends CallbackDataLoadTask { + private ChunkDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -+ final int chunkZ, final PrioritisedExecutor.Priority priority) { -+ super(scheduler, world, chunkX, chunkZ, RegionFileIOThread.RegionFileType.CHUNK_DATA, priority); ++ final int chunkZ, final Priority priority) { ++ super(scheduler, world, chunkX, chunkZ, MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, priority); + } + + @Override @@ -13530,40 +14352,42 @@ index 0000000000000000000000000000000000000000..1ab93f219246d0b4dcdfd0f685f47c13 + } + + @Override -+ protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final PrioritisedExecutor.Priority priority) { ++ protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final Priority priority) { + return this.scheduler.loadExecutor.createTask(run, priority); + } + + @Override -+ protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final PrioritisedExecutor.Priority priority) { ++ protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final Priority priority) { + return this.scheduler.createChunkTask(this.chunkX, this.chunkZ, run, priority); + } + + @Override -+ protected TaskResult completeOnMainOffMain(final CompoundTag data, final Throwable throwable) { ++ protected TaskResult completeOnMainOffMain(final ReadChunk data, final Throwable throwable) { + if (throwable != null) { + return new TaskResult<>(null, throwable); + } -+ if (data == null) { ++ ++ if (data == null || data.protoChunk() == null) { + return new TaskResult<>(this.getEmptyChunk(), null); + } + -+ if (ChunkSystemFeatures.supportsAsyncChunkDeserialization()) { -+ return this.deserialize(data); ++ if (!PlatformHooks.get().hasMainChunkLoadHook()) { ++ return new TaskResult<>(data.protoChunk(), null); + } -+ // need to deserialize on main thread ++ ++ // need to invoke the callback for loading on the main thread + return null; + } + + private ProtoChunk getEmptyChunk() { + return new ProtoChunk( + new ChunkPos(this.chunkX, this.chunkZ), UpgradeData.EMPTY, this.world, -+ this.world.registryAccess().registryOrThrow(Registries.BIOME), (BlendingData)null ++ this.world.registryAccess().lookupOrThrow(Registries.BIOME), (BlendingData)null + ); + } + + @Override -+ protected TaskResult runOffMain(final CompoundTag data, final Throwable throwable) { ++ protected TaskResult runOffMain(final CompoundTag data, final Throwable throwable) { + if (throwable != null) { + LOGGER.error("Failed to load chunk data for task: " + this.toString() + ", chunk data will be lost", throwable); + return new TaskResult<>(null, null); @@ -13575,42 +14399,43 @@ index 0000000000000000000000000000000000000000..1ab93f219246d0b4dcdfd0f685f47c13 + + try { + // run converters -+ final CompoundTag converted = this.world.getChunkSource().chunkMap.upgradeChunkTag(data, new net.minecraft.world.level.ChunkPos(this.chunkX, this.chunkZ)); ++ final CompoundTag converted = this.world.getChunkSource().chunkMap.upgradeChunkTag(data); + -+ return new TaskResult<>(converted, null); -+ } catch (final Throwable thr2) { -+ LOGGER.error("Failed to parse chunk data for task: " + this.toString() + ", chunk data will be lost", thr2); -+ return new TaskResult<>(null, null); -+ } -+ } ++ // unpack the data ++ final SerializableChunkData chunkData = SerializableChunkData.parse( ++ this.world, this.world.registryAccess(), converted ++ ); + -+ private TaskResult deserialize(final CompoundTag data) { -+ try { -+ final ChunkAccess deserialized = ChunkSerializer.read( -+ this.world, this.world.getPoiManager(), this.world.getChunkSource().chunkMap.storageInfo(), new ChunkPos(this.chunkX, this.chunkZ), data ++ if (chunkData == null) { ++ LOGGER.error("Deserialized chunk for task: " + this.toString() + " produced null, chunk data will be lost?"); ++ } ++ ++ // read into ProtoChunk ++ final ProtoChunk chunk = chunkData == null ? null : chunkData.read( ++ this.world, this.world.getPoiManager(), this.world.getChunkSource().chunkMap.storageInfo(), ++ new ChunkPos(this.chunkX, this.chunkZ) + ); -+ return new TaskResult<>(deserialized, null); ++ ++ return new TaskResult<>(new ReadChunk(chunk, chunkData), null); + } catch (final Throwable thr2) { + LOGGER.error("Failed to parse chunk data for task: " + this.toString() + ", chunk data will be lost", thr2); -+ return new TaskResult<>(this.getEmptyChunk(), null); ++ return new TaskResult<>(null, null); + } + } + + @Override -+ protected TaskResult runOnMain(final CompoundTag data, final Throwable throwable) { -+ // data != null && throwable == null -+ if (ChunkSystemFeatures.supportsAsyncChunkDeserialization()) { -+ throw new UnsupportedOperationException(); -+ } -+ return this.deserialize(data); ++ protected TaskResult runOnMain(final ReadChunk data, final Throwable throwable) { ++ PlatformHooks.get().mainChunkLoad(data.protoChunk(), data.chunkData()); ++ ++ return new TaskResult<>(data.protoChunk(), null); + } + } + + public static final class PoiDataLoadTask extends CallbackDataLoadTask { + + public PoiDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -+ final int chunkZ, final PrioritisedExecutor.Priority priority) { -+ super(scheduler, world, chunkX, chunkZ, RegionFileIOThread.RegionFileType.POI_DATA, priority); ++ final int chunkZ, final Priority priority) { ++ super(scheduler, world, chunkX, chunkZ, MoonriseRegionFileIO.RegionFileType.POI_DATA, priority); + } + + @Override @@ -13624,12 +14449,12 @@ index 0000000000000000000000000000000000000000..1ab93f219246d0b4dcdfd0f685f47c13 + } + + @Override -+ protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final PrioritisedExecutor.Priority priority) { ++ protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final Priority priority) { + return this.scheduler.loadExecutor.createTask(run, priority); + } + + @Override -+ protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final PrioritisedExecutor.Priority priority) { ++ protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final Priority priority) { + throw new UnsupportedOperationException(); + } + @@ -13671,8 +14496,8 @@ index 0000000000000000000000000000000000000000..1ab93f219246d0b4dcdfd0f685f47c13 + public static final class EntityDataLoadTask extends CallbackDataLoadTask { + + public EntityDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -+ final int chunkZ, final PrioritisedExecutor.Priority priority) { -+ super(scheduler, world, chunkX, chunkZ, RegionFileIOThread.RegionFileType.ENTITY_DATA, priority); ++ final int chunkZ, final Priority priority) { ++ super(scheduler, world, chunkX, chunkZ, MoonriseRegionFileIO.RegionFileType.ENTITY_DATA, priority); + } + + @Override @@ -13686,12 +14511,12 @@ index 0000000000000000000000000000000000000000..1ab93f219246d0b4dcdfd0f685f47c13 + } + + @Override -+ protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final PrioritisedExecutor.Priority priority) { ++ protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final Priority priority) { + return this.scheduler.loadExecutor.createTask(run, priority); + } + + @Override -+ protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final PrioritisedExecutor.Priority priority) { ++ protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final Priority priority) { + throw new UnsupportedOperationException(); + } + @@ -13728,15 +14553,15 @@ index 0000000000000000000000000000000000000000..1ab93f219246d0b4dcdfd0f685f47c13 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkProgressionTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkProgressionTask.java new file mode 100644 -index 0000000000000000000000000000000000000000..70e900b0f9c131900bf8b3f3ecbfbd5df5361205 +index 0000000000000000000000000000000000000000..002ee365aa70d8e6a6e6bd5c95988bd17db4395a --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkProgressionTask.java @@ -0,0 +1,101 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; + +import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; +import ca.spottedleaf.moonrise.common.util.WorldUtil; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; +import net.minecraft.server.level.ServerLevel; @@ -13780,15 +14605,15 @@ index 0000000000000000000000000000000000000000..70e900b0f9c131900bf8b3f3ecbfbd5d + /* May be called multiple times */ + public abstract void cancel(); + -+ public abstract PrioritisedExecutor.Priority getPriority(); ++ public abstract Priority getPriority(); + + /* Schedule lock is always held for the priority update calls */ + -+ public abstract void lowerPriority(final PrioritisedExecutor.Priority priority); ++ public abstract void lowerPriority(final Priority priority); + -+ public abstract void setPriority(final PrioritisedExecutor.Priority priority); ++ public abstract void setPriority(final Priority priority); + -+ public abstract void raisePriority(final PrioritisedExecutor.Priority priority); ++ public abstract void raisePriority(final Priority priority); + + public final void onComplete(final BiConsumer onComplete) { + if (!this.waiters.add(onComplete)) { @@ -13836,14 +14661,15 @@ index 0000000000000000000000000000000000000000..70e900b0f9c131900bf8b3f3ecbfbd5d \ No newline at end of file diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkUpgradeGenericStatusTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkUpgradeGenericStatusTask.java new file mode 100644 -index 0000000000000000000000000000000000000000..2c17d5589f15f1155be08be670d29acbe954a8fa +index 0000000000000000000000000000000000000000..25d8da4773dcee5096053e7e3788bfc224d705a7 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkUpgradeGenericStatusTask.java -@@ -0,0 +1,217 @@ +@@ -0,0 +1,218 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; + -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; +import ca.spottedleaf.moonrise.common.util.WorldUtil; +import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkStatus; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; @@ -13878,9 +14704,9 @@ index 0000000000000000000000000000000000000000..2c17d5589f15f1155be08be670d29acb + + public ChunkUpgradeGenericStatusTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, + final int chunkZ, final ChunkAccess chunk, final StaticCache2D neighbours, -+ final ChunkStatus toStatus, final PrioritisedExecutor.Priority priority) { ++ final ChunkStatus toStatus, final Priority priority) { + super(scheduler, world, chunkX, chunkZ); -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.fromChunk = chunk; @@ -14029,29 +14855,29 @@ index 0000000000000000000000000000000000000000..2c17d5589f15f1155be08be670d29acb + } + + @Override -+ public PrioritisedExecutor.Priority getPriority() { ++ public Priority getPriority() { + return this.generateTask.getPriority(); + } + + @Override -+ public void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void lowerPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.generateTask.lowerPriority(priority); + } + + @Override -+ public void setPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void setPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.generateTask.setPriority(priority); + } + + @Override -+ public void raisePriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void raisePriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.generateTask.raisePriority(priority); @@ -14059,19 +14885,20 @@ index 0000000000000000000000000000000000000000..2c17d5589f15f1155be08be670d29acb +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/GenericDataLoadTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/GenericDataLoadTask.java new file mode 100644 -index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be314b876c +index 0000000000000000000000000000000000000000..bdcd1879457bafcca4e76523aac0555968f37c0b --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/GenericDataLoadTask.java -@@ -0,0 +1,673 @@ +@@ -0,0 +1,674 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; + ++import ca.spottedleaf.concurrentutil.completable.CallbackCompletable; +import ca.spottedleaf.concurrentutil.completable.Completable; +import ca.spottedleaf.concurrentutil.executor.Cancellable; -+import ca.spottedleaf.concurrentutil.executor.standard.DelayedPrioritisedTask; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; +import ca.spottedleaf.moonrise.common.util.WorldUtil; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder; @@ -14112,11 +14939,11 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + protected final ServerLevel world; + protected final int chunkX; + protected final int chunkZ; -+ protected final RegionFileIOThread.RegionFileType type; ++ protected final MoonriseRegionFileIO.RegionFileType type; + + public GenericDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -+ final int chunkZ, final RegionFileIOThread.RegionFileType type, -+ final PrioritisedExecutor.Priority priority) { ++ final int chunkZ, final MoonriseRegionFileIO.RegionFileType type, ++ final Priority priority) { + this.scheduler = scheduler; + this.world = world; + this.chunkX = chunkX; @@ -14154,9 +14981,9 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + + protected abstract boolean hasOnMain(); + -+ protected abstract PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final PrioritisedExecutor.Priority priority); ++ protected abstract PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final Priority priority); + -+ protected abstract PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final PrioritisedExecutor.Priority priority); ++ protected abstract PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final Priority priority); + + protected abstract TaskResult runOffMain(final CompoundTag data, final Throwable throwable); + @@ -14173,7 +15000,7 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + ", type: " + this.type.toString() + "}"; + } + -+ public PrioritisedExecutor.Priority getPriority() { ++ public Priority getPriority() { + if (this.processOnMain != null) { + return this.processOnMain.getPriority(); + } else { @@ -14181,7 +15008,7 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + } + } + -+ public void lowerPriority(final PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(final Priority priority) { + // can't lower I/O tasks, we don't know what they affect + if (this.processOffMain != null) { + this.processOffMain.lowerPriority(priority); @@ -14191,7 +15018,7 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + } + } + -+ public void setPriority(final PrioritisedExecutor.Priority priority) { ++ public void setPriority(final Priority priority) { + // can't lower I/O tasks, we don't know what they affect + this.loadDataFromDiskTask.raisePriority(priority); + if (this.processOffMain != null) { @@ -14202,7 +15029,7 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + } + } + -+ public void raisePriority(final PrioritisedExecutor.Priority priority) { ++ public void raisePriority(final Priority priority) { + // can't lower I/O tasks, we don't know what they affect + this.loadDataFromDiskTask.raisePriority(priority); + if (this.processOffMain != null) { @@ -14447,10 +15274,10 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + private final int chunkX; + private final int chunkZ; + -+ private final RegionFileIOThread.RegionFileType type; ++ private final MoonriseRegionFileIO.RegionFileType type; + private Cancellable dataLoadTask; + private Cancellable dataUnloadCancellable; -+ private DelayedPrioritisedTask dataUnloadTask; ++ private PrioritisedExecutor.PrioritisedTask dataUnloadTask; + + private final BiConsumer onComplete; + private final AtomicBoolean scheduled = new AtomicBoolean(); @@ -14458,10 +15285,10 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + // onComplete should be caller sensitive, it may complete synchronously with schedule() - which does + // hold a priority lock. + public LoadDataFromDiskTask(final ServerLevel world, final int chunkX, final int chunkZ, -+ final RegionFileIOThread.RegionFileType type, ++ final MoonriseRegionFileIO.RegionFileType type, + final BiConsumer onComplete, -+ final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.world = world; @@ -14491,8 +15318,8 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + return (this.getPriorityVolatile() & PRIORITY_EXECUTED) != 0; + } + -+ public void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void lowerPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + @@ -14504,7 +15331,7 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + } + + if ((curr & PRIORITY_LOAD_SCHEDULED) != 0) { -+ RegionFileIOThread.lowerPriority(this.world, this.chunkX, this.chunkZ, this.type, priority); ++ MoonriseRegionFileIO.lowerPriority(this.world, this.chunkX, this.chunkZ, this.type, priority); + return; + } + @@ -14532,8 +15359,8 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + } + } + -+ public void setPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void setPriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + @@ -14545,7 +15372,7 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + } + + if ((curr & PRIORITY_LOAD_SCHEDULED) != 0) { -+ RegionFileIOThread.setPriority(this.world, this.chunkX, this.chunkZ, this.type, priority); ++ MoonriseRegionFileIO.setPriority(this.world, this.chunkX, this.chunkZ, this.type, priority); + return; + } + @@ -14569,8 +15396,8 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + } + } + -+ public void raisePriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { ++ public void raisePriority(final Priority priority) { ++ if (!Priority.isValidPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + @@ -14582,7 +15409,7 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + } + + if ((curr & PRIORITY_LOAD_SCHEDULED) != 0) { -+ RegionFileIOThread.raisePriority(this.world, this.chunkX, this.chunkZ, this.type, priority); ++ MoonriseRegionFileIO.raisePriority(this.world, this.chunkX, this.chunkZ, this.type, priority); + return; + } + @@ -14648,7 +15475,7 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + } // else: cancelled + }; + -+ final PrioritisedExecutor.Priority initialPriority = PrioritisedExecutor.Priority.getPriority(priority); ++ final Priority initialPriority = Priority.getPriority(priority); + boolean scheduledUnload = false; + + final NewChunkHolder holder = ((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.chunkX, this.chunkZ); @@ -14658,13 +15485,13 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + consumer.accept(data, null); + } else { + // need to schedule task -+ LoadDataFromDiskTask.this.schedule(false, consumer, PrioritisedExecutor.Priority.getPriority(LoadDataFromDiskTask.this.getPriorityVolatile() & ~PRIORITY_FLAGS)); ++ LoadDataFromDiskTask.this.schedule(false, consumer, Priority.getPriority(LoadDataFromDiskTask.this.getPriorityVolatile() & ~PRIORITY_FLAGS)); + } + }; + Cancellable unloadCancellable = null; + CompoundTag syncComplete = null; + final NewChunkHolder.UnloadTask unloadTask = holder.getUnloadTask(this.type); // can be null if no task exists -+ final Completable unloadCompletable = unloadTask == null ? null : unloadTask.completable(); ++ final CallbackCompletable unloadCompletable = unloadTask == null ? null : unloadTask.completable(); + if (unloadCompletable != null) { + unloadCancellable = unloadCompletable.addAsynchronousWaiter(unloadConsumer); + if (unloadCancellable == null) { @@ -14687,7 +15514,7 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + this.schedule(scheduledUnload, consumer, initialPriority); + } + -+ private void schedule(final boolean scheduledUnload, final BiConsumer consumer, final PrioritisedExecutor.Priority initialPriority) { ++ private void schedule(final boolean scheduledUnload, final BiConsumer consumer, final Priority initialPriority) { + int priority = this.getPriorityVolatile(); + + if ((priority & PRIORITY_EXECUTED) != 0) { @@ -14696,9 +15523,9 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + } + + if (!scheduledUnload) { -+ this.dataLoadTask = RegionFileIOThread.loadDataAsync( ++ this.dataLoadTask = MoonriseRegionFileIO.loadDataAsync( + this.world, this.chunkX, this.chunkZ, this.type, consumer, -+ initialPriority.isHigherPriority(PrioritisedExecutor.Priority.NORMAL), initialPriority ++ initialPriority.isHigherPriority(Priority.NORMAL), initialPriority + ); + } + @@ -14722,10 +15549,10 @@ index 0000000000000000000000000000000000000000..7a65d351b448873c6f2c145c975c92be + + if (scheduledUnload) { + if (this.dataUnloadTask != null) { -+ this.dataUnloadTask.setPriority(PrioritisedExecutor.Priority.getPriority(priority & ~PRIORITY_FLAGS)); ++ this.dataUnloadTask.setPriority(Priority.getPriority(priority & ~PRIORITY_FLAGS)); + } + } else { -+ RegionFileIOThread.setPriority(this.world, this.chunkX, this.chunkZ, this.type, PrioritisedExecutor.Priority.getPriority(priority & ~PRIORITY_FLAGS)); ++ MoonriseRegionFileIO.setPriority(this.world, this.chunkX, this.chunkZ, this.type, Priority.getPriority(priority & ~PRIORITY_FLAGS)); + } + + ++failures; @@ -14766,6 +15593,24 @@ index 0000000000000000000000000000000000000000..ea759ce6f10f2a5a4e107ab7528030fe + public ChunkStatus moonrise$getRequiredStatusAtRadius(final int radius); + +} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java +new file mode 100644 +index 0000000000000000000000000000000000000000..51c126735ace8fdde89ad97b5cab62f244212db0 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java +@@ -0,0 +1,12 @@ ++package ca.spottedleaf.moonrise.patches.chunk_system.storage; ++ ++import net.minecraft.world.level.chunk.storage.RegionFile; ++import java.io.IOException; ++ ++public interface ChunkSystemChunkBuffer { ++ public boolean moonrise$getWriteOnClose(); ++ ++ public void moonrise$setWriteOnClose(final boolean value); ++ ++ public void moonrise$write(final RegionFile regionFile) throws IOException; ++} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkStorage.java new file mode 100644 index 0000000000000000000000000000000000000000..129a35ff2db5b3bb6736810fc180796ce55e1875 @@ -14781,6 +15626,24 @@ index 0000000000000000000000000000000000000000..129a35ff2db5b3bb6736810fc180796c + public RegionFileStorage moonrise$getRegionStorage(); + +} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemRegionFile.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemRegionFile.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3bd1b59250dbab15097a64d515999b278636795a +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemRegionFile.java +@@ -0,0 +1,12 @@ ++package ca.spottedleaf.moonrise.patches.chunk_system.storage; ++ ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.world.level.ChunkPos; ++import java.io.IOException; ++ ++public interface ChunkSystemRegionFile { ++ ++ public MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite(final CompoundTag data, final ChunkPos pos) throws IOException; ++ ++} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ticket/ChunkSystemTicket.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ticket/ChunkSystemTicket.java new file mode 100644 index 0000000000000000000000000000000000000000..786e6ad17cd6216ef0aadaa7cf10044a0c19c933 @@ -14834,13 +15697,14 @@ index 0000000000000000000000000000000000000000..ce3bb903c9ccb7efa0f004cf79b291dc +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/ParallelSearchRadiusIteration.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/ParallelSearchRadiusIteration.java new file mode 100644 -index 0000000000000000000000000000000000000000..3a9a564edfdb99e006e4816cb8821bd1e9ecff43 +index 0000000000000000000000000000000000000000..93fd23027c00cef76562098306737272fda1350a --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/ParallelSearchRadiusIteration.java -@@ -0,0 +1,320 @@ +@@ -0,0 +1,321 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.util; + +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; ++import ca.spottedleaf.moonrise.common.util.MoonriseConstants; +import it.unimi.dsi.fastutil.HashCommon; +import it.unimi.dsi.fastutil.longs.LongArrayList; +import it.unimi.dsi.fastutil.longs.LongIterator; @@ -14853,7 +15717,7 @@ index 0000000000000000000000000000000000000000..3a9a564edfdb99e006e4816cb8821bd1 + + // expected that this list returns for a given radius, the set of chunks ordered + // by manhattan distance -+ private static final long[][] SEARCH_RADIUS_ITERATION_LIST = new long[64+2+1][]; ++ private static final long[][] SEARCH_RADIUS_ITERATION_LIST = new long[MoonriseConstants.MAX_VIEW_DISTANCE+2+1][]; + static { + for (int i = 0; i < SEARCH_RADIUS_ITERATION_LIST.length; ++i) { + // a BFS around -x, -z, +x, +z will give increasing manhatten distance @@ -15158,6 +16022,49 @@ index 0000000000000000000000000000000000000000..3a9a564edfdb99e006e4816cb8821bd1 + return ret.elements(); + } +} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/stream/ExternalChunkStreamMarker.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/stream/ExternalChunkStreamMarker.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7ef3dcca89ed7578c6c0f5565131889110063056 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/stream/ExternalChunkStreamMarker.java +@@ -0,0 +1,37 @@ ++package ca.spottedleaf.moonrise.patches.chunk_system.util.stream; ++ ++import java.io.DataInputStream; ++import java.io.FilterInputStream; ++import java.io.InputStream; ++import java.lang.reflect.Field; ++ ++/** ++ * Used to mark chunk data streams that are on external files ++ */ ++public class ExternalChunkStreamMarker extends DataInputStream { ++ ++ private static final Field IN_FIELD; ++ static { ++ Field field; ++ try { ++ field = FilterInputStream.class.getDeclaredField("in"); ++ field.setAccessible(true); ++ } catch (final Throwable throwable) { ++ field = null; ++ } ++ ++ IN_FIELD = field; ++ } ++ ++ private static InputStream getWrapped(final FilterInputStream in) { ++ try { ++ return (InputStream)IN_FIELD.get(in); ++ } catch (final Throwable throwable) { ++ return in; ++ } ++ } ++ ++ public ExternalChunkStreamMarker(final DataInputStream in) { ++ super(getWrapped(in)); ++ } ++} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/world/ChunkSystemEntityGetter.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/world/ChunkSystemEntityGetter.java new file mode 100644 index 0000000000000000000000000000000000000000..ea6b6ed27b212719feb31610faac974899688839 @@ -15230,22 +16137,65 @@ index 0000000000000000000000000000000000000000..f28fd0e01e2bdda0daf9d775e514a725 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java new file mode 100644 -index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a27385126 +index 0000000000000000000000000000000000000000..3abd4ad6379c383c3a31931255292b42d9435694 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java -@@ -0,0 +1,1853 @@ +@@ -0,0 +1,2189 @@ +package ca.spottedleaf.moonrise.patches.collisions; + ++import ca.spottedleaf.moonrise.common.util.WorldUtil; ++import ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemEntityGetter; ++import ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState; ++import ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity; ++import ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData; ++import ca.spottedleaf.moonrise.patches.collisions.shape.CollisionDiscreteVoxelShape; ++import ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape; ++import ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection; ++import it.unimi.dsi.fastutil.doubles.DoubleArrayList; ++import it.unimi.dsi.fastutil.doubles.DoubleList; ++import net.minecraft.core.BlockPos; ++import net.minecraft.core.Direction; ++import net.minecraft.util.Mth; ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.item.Item; ++import net.minecraft.world.level.Level; ++import net.minecraft.world.level.block.Blocks; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.border.WorldBorder; ++import net.minecraft.world.level.chunk.ChunkAccess; ++import net.minecraft.world.level.chunk.ChunkSource; ++import net.minecraft.world.level.chunk.LevelChunkSection; ++import net.minecraft.world.level.chunk.PalettedContainer; ++import net.minecraft.world.level.chunk.status.ChunkStatus; ++import net.minecraft.world.level.material.FluidState; ++import net.minecraft.world.phys.AABB; ++import net.minecraft.world.phys.Vec3; ++import net.minecraft.world.phys.shapes.ArrayVoxelShape; ++import net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape; ++import net.minecraft.world.phys.shapes.BooleanOp; ++import net.minecraft.world.phys.shapes.CollisionContext; ++import net.minecraft.world.phys.shapes.DiscreteVoxelShape; ++import net.minecraft.world.phys.shapes.EntityCollisionContext; ++import net.minecraft.world.phys.shapes.OffsetDoubleList; ++import net.minecraft.world.phys.shapes.Shapes; ++import net.minecraft.world.phys.shapes.SliceShape; ++import net.minecraft.world.phys.shapes.VoxelShape; ++import java.util.Arrays; ++import java.util.List; ++import java.util.Objects; ++import java.util.function.BiPredicate; ++import java.util.function.Predicate; ++ +public final class CollisionUtil { + + public static final double COLLISION_EPSILON = 1.0E-7; -+ public static final it.unimi.dsi.fastutil.doubles.DoubleArrayList ZERO_ONE = it.unimi.dsi.fastutil.doubles.DoubleArrayList.wrap(new double[] { 0.0, 1.0 }); ++ public static final DoubleArrayList ZERO_ONE = DoubleArrayList.wrap(new double[] { 0.0, 1.0 }); + + public static boolean isSpecialCollidingBlock(final net.minecraft.world.level.block.state.BlockBehaviour.BlockStateBase block) { -+ return block.hasLargeCollisionShape() || block.getBlock() == net.minecraft.world.level.block.Blocks.MOVING_PISTON; ++ return block.hasLargeCollisionShape() || block.getBlock() == Blocks.MOVING_PISTON; + } + -+ public static boolean isEmpty(final net.minecraft.world.phys.AABB aabb) { ++ public static boolean isEmpty(final AABB aabb) { + return (aabb.maxX - aabb.minX) < COLLISION_EPSILON || (aabb.maxY - aabb.minY) < COLLISION_EPSILON || (aabb.maxZ - aabb.minZ) < COLLISION_EPSILON; + } + @@ -15254,11 +16204,11 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + return (maxX - minX) < COLLISION_EPSILON || (maxY - minY) < COLLISION_EPSILON || (maxZ - minZ) < COLLISION_EPSILON; + } + -+ public static net.minecraft.world.phys.AABB getBoxForChunk(final int chunkX, final int chunkZ) { ++ public static AABB getBoxForChunk(final int chunkX, final int chunkZ) { + double x = (double)(chunkX << 4); + double z = (double)(chunkZ << 4); + // use a bounding box bigger than the chunk to prevent entities from entering it on move -+ return new net.minecraft.world.phys.AABB(x - 3*COLLISION_EPSILON, Double.NEGATIVE_INFINITY, z - 3*COLLISION_EPSILON, ++ return new AABB(x - 3*COLLISION_EPSILON, Double.NEGATIVE_INFINITY, z - 3*COLLISION_EPSILON, + x + (16.0 + 3*COLLISION_EPSILON), Double.POSITIVE_INFINITY, z + (16.0 + 3*COLLISION_EPSILON)); + } + @@ -15279,21 +16229,21 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + (minZ1 - maxZ2) < -COLLISION_EPSILON && (maxZ1 - minZ2) > COLLISION_EPSILON; + } + -+ public static boolean voxelShapeIntersect(final net.minecraft.world.phys.AABB box, final double minX, final double minY, final double minZ, ++ public static boolean voxelShapeIntersect(final AABB box, final double minX, final double minY, final double minZ, + final double maxX, final double maxY, final double maxZ) { + return (box.minX - maxX) < -COLLISION_EPSILON && (box.maxX - minX) > COLLISION_EPSILON && + (box.minY - maxY) < -COLLISION_EPSILON && (box.maxY - minY) > COLLISION_EPSILON && + (box.minZ - maxZ) < -COLLISION_EPSILON && (box.maxZ - minZ) > COLLISION_EPSILON; + } + -+ public static boolean voxelShapeIntersect(final net.minecraft.world.phys.AABB box1, final net.minecraft.world.phys.AABB box2) { ++ public static boolean voxelShapeIntersect(final AABB box1, final AABB box2) { + return (box1.minX - box2.maxX) < -COLLISION_EPSILON && (box1.maxX - box2.minX) > COLLISION_EPSILON && + (box1.minY - box2.maxY) < -COLLISION_EPSILON && (box1.maxY - box2.minY) > COLLISION_EPSILON && + (box1.minZ - box2.maxZ) < -COLLISION_EPSILON && (box1.maxZ - box2.minZ) > COLLISION_EPSILON; + } + + // assume !isEmpty(target) && abs(source_move) >= COLLISION_EPSILON -+ public static double collideX(final net.minecraft.world.phys.AABB target, final net.minecraft.world.phys.AABB source, final double source_move) { ++ public static double collideX(final AABB target, final AABB source, final double source_move) { + if ((source.minY - target.maxY) < -COLLISION_EPSILON && (source.maxY - target.minY) > COLLISION_EPSILON && + (source.minZ - target.maxZ) < -COLLISION_EPSILON && (source.maxZ - target.minZ) > COLLISION_EPSILON) { + if (source_move >= 0.0) { @@ -15314,7 +16264,7 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + } + + // assume !isEmpty(target) && abs(source_move) >= COLLISION_EPSILON -+ public static double collideY(final net.minecraft.world.phys.AABB target, final net.minecraft.world.phys.AABB source, final double source_move) { ++ public static double collideY(final AABB target, final AABB source, final double source_move) { + if ((source.minX - target.maxX) < -COLLISION_EPSILON && (source.maxX - target.minX) > COLLISION_EPSILON && + (source.minZ - target.maxZ) < -COLLISION_EPSILON && (source.maxZ - target.minZ) > COLLISION_EPSILON) { + if (source_move >= 0.0) { @@ -15335,7 +16285,7 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + } + + // assume !isEmpty(target) && abs(source_move) >= COLLISION_EPSILON -+ public static double collideZ(final net.minecraft.world.phys.AABB target, final net.minecraft.world.phys.AABB source, final double source_move) { ++ public static double collideZ(final AABB target, final AABB source, final double source_move) { + if ((source.minX - target.maxX) < -COLLISION_EPSILON && (source.maxX - target.minX) > COLLISION_EPSILON && + (source.minY - target.maxY) < -COLLISION_EPSILON && (source.maxY - target.minY) > COLLISION_EPSILON) { + if (source_move >= 0.0) { @@ -15357,22 +16307,233 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + + // startIndex and endIndex inclusive + // assumes indices are in range of array -+ private static int findFloor(final double[] values, final double value, int startIndex, int endIndex) { ++ public static int findFloor(final double[] values, final double value, int startIndex, int endIndex) { ++ Objects.checkFromToIndex(startIndex, endIndex + 1, values.length); + do { + final int middle = (startIndex + endIndex) >>> 1; + final double middleVal = values[middle]; + -+ if (value < middleVal) { -+ endIndex = middle - 1; -+ } else { -+ startIndex = middle + 1; ++ if (value < middleVal) { ++ endIndex = middle - 1; ++ } else { ++ startIndex = middle + 1; ++ } ++ } while (startIndex <= endIndex); ++ ++ return startIndex - 1; ++ } ++ ++ private static VoxelShape sliceShapeVanilla(final VoxelShape src, final Direction.Axis axis, ++ final int index) { ++ return new SliceShape(src, axis, index); ++ } ++ ++ private static DoubleList offsetList(final double[] src, final double by) { ++ final DoubleArrayList wrap = DoubleArrayList.wrap(src); ++ if (by == 0.0) { ++ return wrap; ++ } ++ return new OffsetDoubleList(wrap, by); ++ } ++ ++ private static VoxelShape sliceShapeOptimised(final VoxelShape src, final Direction.Axis axis, ++ final int index) { ++ // assume index in range ++ final double off_x = ((CollisionVoxelShape)src).moonrise$offsetX(); ++ final double off_y = ((CollisionVoxelShape)src).moonrise$offsetY(); ++ final double off_z = ((CollisionVoxelShape)src).moonrise$offsetZ(); ++ ++ final double[] coords_x = ((CollisionVoxelShape)src).moonrise$rootCoordinatesX(); ++ final double[] coords_y = ((CollisionVoxelShape)src).moonrise$rootCoordinatesY(); ++ final double[] coords_z = ((CollisionVoxelShape)src).moonrise$rootCoordinatesZ(); ++ ++ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)src).moonrise$getCachedVoxelData(); ++ ++ // note: size = coords.length - 1 ++ final int size_x = cached_shape_data.sizeX(); ++ final int size_y = cached_shape_data.sizeY(); ++ final int size_z = cached_shape_data.sizeZ(); ++ ++ final long[] bitset = cached_shape_data.voxelSet(); ++ ++ final DoubleList list_x; ++ final DoubleList list_y; ++ final DoubleList list_z; ++ final int shape_sx; ++ final int shape_ex; ++ final int shape_sy; ++ final int shape_ey; ++ final int shape_sz; ++ final int shape_ez; ++ ++ switch (axis) { ++ case X: { ++ // validate index ++ if (index < 0 || index >= size_x) { ++ return Shapes.empty(); ++ } ++ ++ // test if input is already "sliced" ++ if (coords_x.length == 2 && (coords_x[0] + off_x) == 0.0 && (coords_x[1] + off_x) == 1.0) { ++ return src; ++ } ++ ++ // test if result would be full box ++ if (coords_y.length == 2 && coords_z.length == 2 && ++ (coords_y[0] + off_y) == 0.0 && (coords_y[1] + off_y) == 1.0 && ++ (coords_z[0] + off_z) == 0.0 && (coords_z[1] + off_z) == 1.0) { ++ // note: size_y == size_z == 1 ++ final int bitIdx = 0 + 0*size_z + index*(size_z*size_y); ++ return (bitset[bitIdx >>> 6] & (1L << bitIdx)) == 0L ? Shapes.empty() : Shapes.block(); ++ } ++ ++ list_x = ZERO_ONE; ++ list_y = offsetList(coords_y, off_y); ++ list_z = offsetList(coords_z, off_z); ++ shape_sx = index; ++ shape_ex = index + 1; ++ shape_sy = 0; ++ shape_ey = size_y; ++ shape_sz = 0; ++ shape_ez = size_z; ++ ++ break; ++ } ++ case Y: { ++ // validate index ++ if (index < 0 || index >= size_y) { ++ return Shapes.empty(); ++ } ++ ++ // test if input is already "sliced" ++ if (coords_y.length == 2 && (coords_y[0] + off_y) == 0.0 && (coords_y[1] + off_y) == 1.0) { ++ return src; ++ } ++ ++ // test if result would be full box ++ if (coords_x.length == 2 && coords_z.length == 2 && ++ (coords_x[0] + off_x) == 0.0 && (coords_x[1] + off_x) == 1.0 && ++ (coords_z[0] + off_z) == 0.0 && (coords_z[1] + off_z) == 1.0) { ++ // note: size_x == size_z == 1 ++ final int bitIdx = 0 + index*size_z + 0*(size_z*size_y); ++ return (bitset[bitIdx >>> 6] & (1L << bitIdx)) == 0L ? Shapes.empty() : Shapes.block(); ++ } ++ ++ list_x = offsetList(coords_x, off_x); ++ list_y = ZERO_ONE; ++ list_z = offsetList(coords_z, off_z); ++ shape_sx = 0; ++ shape_ex = size_x; ++ shape_sy = index; ++ shape_ey = index + 1; ++ shape_sz = 0; ++ shape_ez = size_z; ++ ++ break; ++ } ++ case Z: { ++ // validate index ++ if (index < 0 || index >= size_z) { ++ return Shapes.empty(); ++ } ++ ++ // test if input is already "sliced" ++ if (coords_z.length == 2 && (coords_z[0] + off_z) == 0.0 && (coords_z[1] + off_z) == 1.0) { ++ return src; ++ } ++ ++ // test if result would be full box ++ if (coords_x.length == 2 && coords_y.length == 2 && ++ (coords_x[0] + off_x) == 0.0 && (coords_x[1] + off_x) == 1.0 && ++ (coords_y[0] + off_y) == 0.0 && (coords_y[1] + off_y) == 1.0) { ++ // note: size_x == size_y == 1 ++ final int bitIdx = index + 0*size_z + 0*(size_z*size_y); ++ return (bitset[bitIdx >>> 6] & (1L << bitIdx)) == 0L ? Shapes.empty() : Shapes.block(); ++ } ++ ++ list_x = offsetList(coords_x, off_x); ++ list_y = offsetList(coords_y, off_y); ++ list_z = ZERO_ONE; ++ shape_sx = 0; ++ shape_ex = size_x; ++ shape_sy = 0; ++ shape_ey = size_y; ++ shape_sz = index; ++ shape_ez = index + 1; ++ ++ break; ++ } ++ default: { ++ throw new IllegalStateException("Unknown axis: " + axis); ++ } ++ } ++ ++ final int local_len_x = shape_ex - shape_sx; ++ final int local_len_y = shape_ey - shape_sy; ++ final int local_len_z = shape_ez - shape_sz; ++ ++ final BitSetDiscreteVoxelShape shape = new BitSetDiscreteVoxelShape(local_len_x, local_len_y, local_len_z); ++ ++ final int bitset_mul_x = size_z*size_y; ++ final int idx_off = shape_sz + shape_sy*size_z + shape_sx*bitset_mul_x; ++ final int shape_mul_x = local_len_y*local_len_z; ++ for (int x = 0; x < local_len_x; ++x) { ++ boolean setX = false; ++ for (int y = 0; y < local_len_y; ++y) { ++ boolean setY = false; ++ for (int z = 0; z < local_len_z; ++z) { ++ final int unslicedIdx = idx_off + z + y*size_z + x*bitset_mul_x; ++ if ((bitset[unslicedIdx >>> 6] & (1L << unslicedIdx)) == 0L) { ++ continue; ++ } ++ ++ setY = true; ++ setX = true; ++ shape.zMin = Math.min(shape.zMin, z); ++ shape.zMax = Math.max(shape.zMax, z + 1); ++ ++ shape.storage.set( ++ z + y*local_len_z + x*shape_mul_x ++ ); ++ } ++ ++ if (setY) { ++ shape.yMin = Math.min(shape.yMin, y); ++ shape.yMax = Math.max(shape.yMax, y + 1); ++ } ++ } ++ if (setX) { ++ shape.xMin = Math.min(shape.xMin, x); ++ shape.xMax = Math.max(shape.xMax, x + 1); ++ } ++ } ++ ++ return shape.isEmpty() ? Shapes.empty() : new ArrayVoxelShape( ++ shape, list_x, list_y, list_z ++ ); ++ } ++ ++ private static final boolean DEBUG_SLICE_SHAPE = false; ++ ++ public static VoxelShape sliceShape(final VoxelShape src, final Direction.Axis axis, ++ final int index) { ++ final VoxelShape ret = sliceShapeOptimised(src, axis, index); ++ if (DEBUG_SLICE_SHAPE) { ++ final VoxelShape vanilla = sliceShapeVanilla(src, axis, index); ++ if (!equals(ret, vanilla)) { ++ // special case: SliceShape is not empty when it should be! ++ if (areAnyFull(ret.shape) || areAnyFull(vanilla.shape)) { ++ equals(ret, vanilla); ++ sliceShapeOptimised(src, axis, index); ++ throw new IllegalStateException("Slice shape mismatch"); ++ } + } -+ } while (startIndex <= endIndex); ++ } + -+ return startIndex - 1; ++ return ret; + } + -+ public static boolean voxelShapeIntersectNoEmpty(final net.minecraft.world.phys.shapes.VoxelShape voxel, final net.minecraft.world.phys.AABB aabb) { ++ public static boolean voxelShapeIntersectNoEmpty(final VoxelShape voxel, final AABB aabb) { + if (voxel.isEmpty()) { + return false; + } @@ -15380,15 +16541,15 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + // note: this function assumes that for any i in coords that coord[i + 1] - coord[i] > COLLISION_EPSILON is true + + // offsets that should be applied to coords -+ final double off_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetX(); -+ final double off_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetY(); -+ final double off_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetZ(); ++ final double off_x = ((CollisionVoxelShape)voxel).moonrise$offsetX(); ++ final double off_y = ((CollisionVoxelShape)voxel).moonrise$offsetY(); ++ final double off_z = ((CollisionVoxelShape)voxel).moonrise$offsetZ(); + -+ final double[] coords_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesX(); -+ final double[] coords_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesY(); -+ final double[] coords_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesZ(); ++ final double[] coords_x = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesX(); ++ final double[] coords_y = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesY(); ++ final double[] coords_z = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesZ(); + -+ final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cached_shape_data = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$getCachedVoxelData(); ++ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)voxel).moonrise$getCachedVoxelData(); + + // note: size = coords.length - 1 + final int size_x = cached_shape_data.sizeX(); @@ -15482,23 +16643,23 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + } + + // assume !target.isEmpty() && abs(source_move) >= COLLISION_EPSILON -+ public static double collideX(final net.minecraft.world.phys.shapes.VoxelShape target, final net.minecraft.world.phys.AABB source, final double source_move) { -+ final net.minecraft.world.phys.AABB single_aabb = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); ++ public static double collideX(final VoxelShape target, final AABB source, final double source_move) { ++ final AABB single_aabb = ((CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); + if (single_aabb != null) { + return collideX(single_aabb, source, source_move); + } + // note: this function assumes that for any i in coords that coord[i + 1] - coord[i] > COLLISION_EPSILON is true + + // offsets that should be applied to coords -+ final double off_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetX(); -+ final double off_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetY(); -+ final double off_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetZ(); ++ final double off_x = ((CollisionVoxelShape)target).moonrise$offsetX(); ++ final double off_y = ((CollisionVoxelShape)target).moonrise$offsetY(); ++ final double off_z = ((CollisionVoxelShape)target).moonrise$offsetZ(); + -+ final double[] coords_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesX(); -+ final double[] coords_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesY(); -+ final double[] coords_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); ++ final double[] coords_x = ((CollisionVoxelShape)target).moonrise$rootCoordinatesX(); ++ final double[] coords_y = ((CollisionVoxelShape)target).moonrise$rootCoordinatesY(); ++ final double[] coords_z = ((CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); + -+ final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cached_shape_data = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getCachedVoxelData(); ++ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)target).moonrise$getCachedVoxelData(); + + // note: size = coords.length - 1 + final int size_x = cached_shape_data.sizeX(); @@ -15640,23 +16801,23 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + } + } + -+ public static double collideY(final net.minecraft.world.phys.shapes.VoxelShape target, final net.minecraft.world.phys.AABB source, final double source_move) { -+ final net.minecraft.world.phys.AABB single_aabb = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); ++ public static double collideY(final VoxelShape target, final AABB source, final double source_move) { ++ final AABB single_aabb = ((CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); + if (single_aabb != null) { + return collideY(single_aabb, source, source_move); + } + // note: this function assumes that for any i in coords that coord[i + 1] - coord[i] > COLLISION_EPSILON is true + + // offsets that should be applied to coords -+ final double off_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetX(); -+ final double off_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetY(); -+ final double off_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetZ(); ++ final double off_x = ((CollisionVoxelShape)target).moonrise$offsetX(); ++ final double off_y = ((CollisionVoxelShape)target).moonrise$offsetY(); ++ final double off_z = ((CollisionVoxelShape)target).moonrise$offsetZ(); + -+ final double[] coords_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesX(); -+ final double[] coords_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesY(); -+ final double[] coords_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); ++ final double[] coords_x = ((CollisionVoxelShape)target).moonrise$rootCoordinatesX(); ++ final double[] coords_y = ((CollisionVoxelShape)target).moonrise$rootCoordinatesY(); ++ final double[] coords_z = ((CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); + -+ final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cached_shape_data = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getCachedVoxelData(); ++ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)target).moonrise$getCachedVoxelData(); + + // note: size = coords.length - 1 + final int size_x = cached_shape_data.sizeX(); @@ -15798,23 +16959,23 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + } + } + -+ public static double collideZ(final net.minecraft.world.phys.shapes.VoxelShape target, final net.minecraft.world.phys.AABB source, final double source_move) { -+ final net.minecraft.world.phys.AABB single_aabb = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); ++ public static double collideZ(final VoxelShape target, final AABB source, final double source_move) { ++ final AABB single_aabb = ((CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); + if (single_aabb != null) { + return collideZ(single_aabb, source, source_move); + } + // note: this function assumes that for any i in coords that coord[i + 1] - coord[i] > COLLISION_EPSILON is true + + // offsets that should be applied to coords -+ final double off_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetX(); -+ final double off_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetY(); -+ final double off_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetZ(); ++ final double off_x = ((CollisionVoxelShape)target).moonrise$offsetX(); ++ final double off_y = ((CollisionVoxelShape)target).moonrise$offsetY(); ++ final double off_z = ((CollisionVoxelShape)target).moonrise$offsetZ(); + -+ final double[] coords_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesX(); -+ final double[] coords_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesY(); -+ final double[] coords_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); ++ final double[] coords_x = ((CollisionVoxelShape)target).moonrise$rootCoordinatesX(); ++ final double[] coords_y = ((CollisionVoxelShape)target).moonrise$rootCoordinatesY(); ++ final double[] coords_z = ((CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); + -+ final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cached_shape_data = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getCachedVoxelData(); ++ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)target).moonrise$getCachedVoxelData(); + + // note: size = coords.length - 1 + final int size_x = cached_shape_data.sizeX(); @@ -15957,13 +17118,13 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + } + + // does not use epsilon -+ public static boolean strictlyContains(final net.minecraft.world.phys.shapes.VoxelShape voxel, final net.minecraft.world.phys.Vec3 point) { ++ public static boolean strictlyContains(final VoxelShape voxel, final Vec3 point) { + return strictlyContains(voxel, point.x, point.y, point.z); + } + + // does not use epsilon -+ public static boolean strictlyContains(final net.minecraft.world.phys.shapes.VoxelShape voxel, double x, double y, double z) { -+ final net.minecraft.world.phys.AABB single_aabb = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$getSingleAABBRepresentation(); ++ public static boolean strictlyContains(final VoxelShape voxel, double x, double y, double z) { ++ final AABB single_aabb = ((CollisionVoxelShape)voxel).moonrise$getSingleAABBRepresentation(); + if (single_aabb != null) { + return single_aabb.contains(x, y, z); + } @@ -15974,15 +17135,15 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + } + + // offset input -+ x -= ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetX(); -+ y -= ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetY(); -+ z -= ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetZ(); ++ x -= ((CollisionVoxelShape)voxel).moonrise$offsetX(); ++ y -= ((CollisionVoxelShape)voxel).moonrise$offsetY(); ++ z -= ((CollisionVoxelShape)voxel).moonrise$offsetZ(); + -+ final double[] coords_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesX(); -+ final double[] coords_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesY(); -+ final double[] coords_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesZ(); ++ final double[] coords_x = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesX(); ++ final double[] coords_y = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesY(); ++ final double[] coords_z = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesZ(); + -+ final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cached_shape_data = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$getCachedVoxelData(); ++ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)voxel).moonrise$getCachedVoxelData(); + + // note: size = coords.length - 1 + final int size_x = cached_shape_data.sizeX(); @@ -16024,10 +17185,10 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + return ((ft ? 1 : 0) << 1) | ((tf ? 1 : 0) << 2) | ((tt ? 1 : 0) << 3); + } + -+ private static net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape merge(final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataFirst, final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataSecond, -+ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedX, final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedY, -+ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedZ, -+ final int booleanOp) { ++ private static BitSetDiscreteVoxelShape merge(final CachedShapeData shapeDataFirst, final CachedShapeData shapeDataSecond, ++ final MergedVoxelCoordinateList mergedX, final MergedVoxelCoordinateList mergedY, ++ final MergedVoxelCoordinateList mergedZ, ++ final int booleanOp) { + final int sizeX = mergedX.voxels; + final int sizeY = mergedY.voxels; + final int sizeZ = mergedZ.voxels; @@ -16042,7 +17203,7 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + final int s2Mul2 = s2Mul1 * shapeDataSecond.sizeY(); + + // note: indices may contain -1, but nothing > size -+ final net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape ret = new net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape(sizeX, sizeY, sizeZ); ++ final BitSetDiscreteVoxelShape ret = new BitSetDiscreteVoxelShape(sizeX, sizeY, sizeZ); + + boolean empty = true; + @@ -16059,10 +17220,11 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + final int s1z = mergedZ.firstIndices[idxZ]; + final int s2z = mergedZ.secondIndices[idxZ]; + -+ int idx; ++ int idx1; ++ int idx2; + -+ final int isS1Full = (s1x | s1y | s1z) < 0 ? 0 : (int)((s1Voxels[(idx = s1z + s1y*s1Mul1 + s1x*s1Mul2) >>> 6] >>> idx) & 1L); -+ final int isS2Full = (s2x | s2y | s2z) < 0 ? 0 : (int)((s2Voxels[(idx = s2z + s2y*s2Mul1 + s2x*s2Mul2) >>> 6] >>> idx) & 1L); ++ final int isS1Full = (s1x | s1y | s1z) < 0 ? 0 : (int)((s1Voxels[(idx1 = s1z + s1y*s1Mul1 + s1x*s1Mul2) >>> 6] >>> idx1) & 1L); ++ final int isS2Full = (s2x | s2y | s2z) < 0 ? 0 : (int)((s2Voxels[(idx2 = s2z + s2y*s2Mul1 + s2x*s2Mul2) >>> 6] >>> idx2) & 1L); + + // idx ff -> 0 + // idx ft -> 1 @@ -16097,9 +17259,9 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + return empty ? null : ret; + } + -+ private static boolean isMergeEmpty(final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataFirst, final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataSecond, -+ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedX, final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedY, -+ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedZ, ++ private static boolean isMergeEmpty(final CachedShapeData shapeDataFirst, final CachedShapeData shapeDataSecond, ++ final MergedVoxelCoordinateList mergedX, final MergedVoxelCoordinateList mergedY, ++ final MergedVoxelCoordinateList mergedZ, + final int booleanOp) { + final int sizeX = mergedX.voxels; + final int sizeY = mergedY.voxels; @@ -16125,10 +17287,11 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + final int s1z = mergedZ.firstIndices[idxZ]; + final int s2z = mergedZ.secondIndices[idxZ]; + -+ int idx; ++ int idx1; ++ int idx2; + -+ final int isS1Full = (s1x | s1y | s1z) < 0 ? 0 : (int)((s1Voxels[(idx = s1z + s1y*s1Mul1 + s1x*s1Mul2) >>> 6] >>> idx) & 1L); -+ final int isS2Full = (s2x | s2y | s2z) < 0 ? 0 : (int)((s2Voxels[(idx = s2z + s2y*s2Mul1 + s2x*s2Mul2) >>> 6] >>> idx) & 1L); ++ final int isS1Full = (s1x | s1y | s1z) < 0 ? 0 : (int)((s1Voxels[(idx1 = s1z + s1y*s1Mul1 + s1x*s1Mul2) >>> 6] >>> idx1) & 1L); ++ final int isS2Full = (s2x | s2y | s2z) < 0 ? 0 : (int)((s2Voxels[(idx2 = s2z + s2y*s2Mul1 + s2x*s2Mul2) >>> 6] >>> idx2) & 1L); + + // idx ff -> 0 + // idx ft -> 1 @@ -16147,11 +17310,11 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + return true; + } + -+ public static net.minecraft.world.phys.shapes.VoxelShape joinOptimized(final net.minecraft.world.phys.shapes.VoxelShape first, final net.minecraft.world.phys.shapes.VoxelShape second, final net.minecraft.world.phys.shapes.BooleanOp operator) { ++ public static VoxelShape joinOptimized(final VoxelShape first, final VoxelShape second, final BooleanOp operator) { + return joinUnoptimized(first, second, operator).optimize(); + } + -+ public static net.minecraft.world.phys.shapes.VoxelShape joinUnoptimized(final net.minecraft.world.phys.shapes.VoxelShape first, final net.minecraft.world.phys.shapes.VoxelShape second, final net.minecraft.world.phys.shapes.BooleanOp operator) { ++ public static VoxelShape joinUnoptimized(final VoxelShape first, final VoxelShape second, final BooleanOp operator) { + final boolean ff = operator.apply(false, false); + if (ff) { + // technically, should be an infinite box but that's clearly an error @@ -16161,23 +17324,23 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + final boolean tt = operator.apply(true, true); + + if (first == second) { -+ return tt ? first : net.minecraft.world.phys.shapes.Shapes.empty(); ++ return tt ? first : Shapes.empty(); + } + + final boolean ft = operator.apply(false, true); + final boolean tf = operator.apply(true, false); + + if (first.isEmpty()) { -+ return ft ? second : net.minecraft.world.phys.shapes.Shapes.empty(); ++ return ft ? second : Shapes.empty(); + } + if (second.isEmpty()) { -+ return tf ? first : net.minecraft.world.phys.shapes.Shapes.empty(); ++ return tf ? first : Shapes.empty(); + } + + if (!tt) { + // try to check for no intersection, since tt = false -+ final net.minecraft.world.phys.AABB aabbF = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$getSingleAABBRepresentation(); -+ final net.minecraft.world.phys.AABB aabbS = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$getSingleAABBRepresentation(); ++ final AABB aabbF = ((CollisionVoxelShape)first).moonrise$getSingleAABBRepresentation(); ++ final AABB aabbS = ((CollisionVoxelShape)second).moonrise$getSingleAABBRepresentation(); + + final boolean intersect; + @@ -16198,7 +17361,7 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + + if (!intersect) { + if (!tf & !ft) { -+ return net.minecraft.world.phys.shapes.Shapes.empty(); ++ return Shapes.empty(); + } + if (!tf | !ft) { + return tf ? first : second; @@ -16206,50 +17369,50 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + } + } + -+ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedX = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( -+ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesX(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetX(), -+ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesX(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetX(), ++ final MergedVoxelCoordinateList mergedX = MergedVoxelCoordinateList.merge( ++ ((CollisionVoxelShape)first).moonrise$rootCoordinatesX(), ((CollisionVoxelShape)first).moonrise$offsetX(), ++ ((CollisionVoxelShape)second).moonrise$rootCoordinatesX(), ((CollisionVoxelShape)second).moonrise$offsetX(), + ft, tf + ); -+ if (mergedX == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { -+ return net.minecraft.world.phys.shapes.Shapes.empty(); ++ if (mergedX == null) { ++ return Shapes.empty(); + } -+ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedY = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( -+ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesY(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetY(), -+ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesY(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetY(), ++ final MergedVoxelCoordinateList mergedY = MergedVoxelCoordinateList.merge( ++ ((CollisionVoxelShape)first).moonrise$rootCoordinatesY(), ((CollisionVoxelShape)first).moonrise$offsetY(), ++ ((CollisionVoxelShape)second).moonrise$rootCoordinatesY(), ((CollisionVoxelShape)second).moonrise$offsetY(), + ft, tf + ); -+ if (mergedY == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { -+ return net.minecraft.world.phys.shapes.Shapes.empty(); ++ if (mergedY == null) { ++ return Shapes.empty(); + } -+ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedZ = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( -+ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesZ(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetZ(), -+ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesZ(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetZ(), ++ final MergedVoxelCoordinateList mergedZ = MergedVoxelCoordinateList.merge( ++ ((CollisionVoxelShape)first).moonrise$rootCoordinatesZ(), ((CollisionVoxelShape)first).moonrise$offsetZ(), ++ ((CollisionVoxelShape)second).moonrise$rootCoordinatesZ(), ((CollisionVoxelShape)second).moonrise$offsetZ(), + ft, tf + ); -+ if (mergedZ == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { -+ return net.minecraft.world.phys.shapes.Shapes.empty(); ++ if (mergedZ == null) { ++ return Shapes.empty(); + } + -+ final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataFirst = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$getCachedVoxelData(); -+ final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataSecond = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$getCachedVoxelData(); ++ final CachedShapeData shapeDataFirst = ((CollisionVoxelShape)first).moonrise$getCachedVoxelData(); ++ final CachedShapeData shapeDataSecond = ((CollisionVoxelShape)second).moonrise$getCachedVoxelData(); + -+ final net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape mergedShape = merge( ++ final BitSetDiscreteVoxelShape mergedShape = merge( + shapeDataFirst, shapeDataSecond, + mergedX, mergedY, mergedZ, + makeBitset(ft, tf, tt) + ); + + if (mergedShape == null) { -+ return net.minecraft.world.phys.shapes.Shapes.empty(); ++ return Shapes.empty(); + } + -+ return new net.minecraft.world.phys.shapes.ArrayVoxelShape( ++ return new ArrayVoxelShape( + mergedShape, mergedX.wrapCoords(), mergedY.wrapCoords(), mergedZ.wrapCoords() + ); + } + -+ public static boolean isJoinNonEmpty(final net.minecraft.world.phys.shapes.VoxelShape first, final net.minecraft.world.phys.shapes.VoxelShape second, final net.minecraft.world.phys.shapes.BooleanOp operator) { ++ public static boolean isJoinNonEmpty(final VoxelShape first, final VoxelShape second, final BooleanOp operator) { + final boolean ff = operator.apply(false, false); + if (ff) { + // technically, should be an infinite box but that's clearly an error @@ -16271,8 +17434,8 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + final boolean tf = operator.apply(true, false); + + // try to check intersection -+ final net.minecraft.world.phys.AABB aabbF = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$getSingleAABBRepresentation(); -+ final net.minecraft.world.phys.AABB aabbS = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$getSingleAABBRepresentation(); ++ final AABB aabbF = ((CollisionVoxelShape)first).moonrise$getSingleAABBRepresentation(); ++ final AABB aabbS = ((CollisionVoxelShape)second).moonrise$getSingleAABBRepresentation(); + + final boolean intersect; + @@ -16304,33 +17467,33 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + } + } + -+ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedX = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( -+ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesX(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetX(), -+ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesX(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetX(), ++ final MergedVoxelCoordinateList mergedX = MergedVoxelCoordinateList.merge( ++ ((CollisionVoxelShape)first).moonrise$rootCoordinatesX(), ((CollisionVoxelShape)first).moonrise$offsetX(), ++ ((CollisionVoxelShape)second).moonrise$rootCoordinatesX(), ((CollisionVoxelShape)second).moonrise$offsetX(), + ft, tf + ); -+ if (mergedX == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { ++ if (mergedX == null) { + return false; + } -+ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedY = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( -+ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesY(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetY(), -+ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesY(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetY(), ++ final MergedVoxelCoordinateList mergedY = MergedVoxelCoordinateList.merge( ++ ((CollisionVoxelShape)first).moonrise$rootCoordinatesY(), ((CollisionVoxelShape)first).moonrise$offsetY(), ++ ((CollisionVoxelShape)second).moonrise$rootCoordinatesY(), ((CollisionVoxelShape)second).moonrise$offsetY(), + ft, tf + ); -+ if (mergedY == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { ++ if (mergedY == null) { + return false; + } -+ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedZ = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( -+ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesZ(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetZ(), -+ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesZ(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetZ(), ++ final MergedVoxelCoordinateList mergedZ = MergedVoxelCoordinateList.merge( ++ ((CollisionVoxelShape)first).moonrise$rootCoordinatesZ(), ((CollisionVoxelShape)first).moonrise$offsetZ(), ++ ((CollisionVoxelShape)second).moonrise$rootCoordinatesZ(), ((CollisionVoxelShape)second).moonrise$offsetZ(), + ft, tf + ); -+ if (mergedZ == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { ++ if (mergedZ == null) { + return false; + } + -+ final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataFirst = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$getCachedVoxelData(); -+ final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataSecond = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$getCachedVoxelData(); ++ final CachedShapeData shapeDataFirst = ((CollisionVoxelShape)first).moonrise$getCachedVoxelData(); ++ final CachedShapeData shapeDataSecond = ((CollisionVoxelShape)second).moonrise$getCachedVoxelData(); + + return !isMergeEmpty( + shapeDataFirst, shapeDataSecond, @@ -16348,10 +17511,6 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + } + } + -+ private static final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList EMPTY = new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList( -+ new double[] { 0.0 }, 0.0, new int[0], new int[0], 0 -+ ); -+ + private static int[] getIndices(final int length) { + final int[] ret = new int[length]; + @@ -16378,25 +17537,25 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + this.voxels = voxels; + } + -+ public it.unimi.dsi.fastutil.doubles.DoubleList wrapCoords() { ++ public DoubleList wrapCoords() { + if (this.coordinateOffset == 0.0) { -+ return it.unimi.dsi.fastutil.doubles.DoubleArrayList.wrap(this.coordinates, this.voxels + 1); ++ return DoubleArrayList.wrap(this.coordinates, this.voxels + 1); + } -+ return new net.minecraft.world.phys.shapes.OffsetDoubleList(it.unimi.dsi.fastutil.doubles.DoubleArrayList.wrap(this.coordinates, this.voxels + 1), this.coordinateOffset); ++ return new OffsetDoubleList(DoubleArrayList.wrap(this.coordinates, this.voxels + 1), this.coordinateOffset); + } + + // assume coordinates.length > 1 -+ public static ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList getForSingle(final double[] coordinates, final double offset) { ++ public static MergedVoxelCoordinateList getForSingle(final double[] coordinates, final double offset) { + final int voxels = coordinates.length - 1; + final int[] indices = voxels < SIMPLE_INDICES_CACHE.length ? SIMPLE_INDICES_CACHE[voxels] : getIndices(voxels); + -+ return new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList(coordinates, offset, indices, indices, voxels); ++ return new MergedVoxelCoordinateList(coordinates, offset, indices, indices, voxels); + } + + // assume coordinates.length > 1 -+ public static ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList merge(final double[] firstCoordinates, final double firstOffset, -+ final double[] secondCoordinates, final double secondOffset, -+ final boolean ft, final boolean tf) { ++ public static MergedVoxelCoordinateList merge(final double[] firstCoordinates, final double firstOffset, ++ final double[] secondCoordinates, final double secondOffset, ++ final boolean ft, final boolean tf) { + if (firstCoordinates == secondCoordinates && firstOffset == secondOffset) { + return getForSingle(firstCoordinates, firstOffset); + } @@ -16486,13 +17645,13 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + } + } + -+ return resultSize <= 1 ? EMPTY : new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList(coordinates, 0.0, firstIndices, secondIndices, resultSize - 1); ++ return resultSize <= 1 ? null : new MergedVoxelCoordinateList(coordinates, 0.0, firstIndices, secondIndices, resultSize - 1); + } + } + -+ public static boolean equals(final net.minecraft.world.phys.shapes.DiscreteVoxelShape shape1, final net.minecraft.world.phys.shapes.DiscreteVoxelShape shape2) { -+ final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cachedShapeData1 = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionDiscreteVoxelShape)shape1).moonrise$getOrCreateCachedShapeData(); -+ final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cachedShapeData2 = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionDiscreteVoxelShape)shape2).moonrise$getOrCreateCachedShapeData(); ++ public static boolean equals(final DiscreteVoxelShape shape1, final DiscreteVoxelShape shape2) { ++ final CachedShapeData cachedShapeData1 = ((CollisionDiscreteVoxelShape)shape1).moonrise$getOrCreateCachedShapeData(); ++ final CachedShapeData cachedShapeData2 = ((CollisionDiscreteVoxelShape)shape2).moonrise$getOrCreateCachedShapeData(); + + final boolean isEmpty1 = cachedShapeData1.isEmpty(); + final boolean isEmpty2 = cachedShapeData2.isEmpty(); @@ -16501,7 +17660,7 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + return true; + } else if (isEmpty1 ^ isEmpty2) { + return false; -+ } ++ } // else: isEmpty1 = isEmpty2 = false + + if (cachedShapeData1.hasSingleAABB() != cachedShapeData2.hasSingleAABB()) { + return false; @@ -16517,153 +17676,237 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + return false; + } + -+ return java.util.Arrays.equals(cachedShapeData1.voxelSet(), cachedShapeData2.voxelSet()); ++ return Arrays.equals(cachedShapeData1.voxelSet(), cachedShapeData2.voxelSet()); + } + + // useful only for testing -+ public static boolean equals(final net.minecraft.world.phys.shapes.VoxelShape shape1, final net.minecraft.world.phys.shapes.VoxelShape shape2) { ++ public static boolean equals(final VoxelShape shape1, final VoxelShape shape2) { ++ if (shape1.isEmpty() & shape2.isEmpty()) { ++ return true; ++ } else if (shape1.isEmpty() ^ shape2.isEmpty()) { ++ return false; ++ } ++ + if (!equals(shape1.shape, shape2.shape)) { + return false; + } + -+ return shape1.getCoords(net.minecraft.core.Direction.Axis.X).equals(shape2.getCoords(net.minecraft.core.Direction.Axis.X)) && -+ shape1.getCoords(net.minecraft.core.Direction.Axis.Y).equals(shape2.getCoords(net.minecraft.core.Direction.Axis.Y)) && -+ shape1.getCoords(net.minecraft.core.Direction.Axis.Z).equals(shape2.getCoords(net.minecraft.core.Direction.Axis.Z)); ++ return shape1.getCoords(Direction.Axis.X).equals(shape2.getCoords(Direction.Axis.X)) && ++ shape1.getCoords(Direction.Axis.Y).equals(shape2.getCoords(Direction.Axis.Y)) && ++ shape1.getCoords(Direction.Axis.Z).equals(shape2.getCoords(Direction.Axis.Z)); ++ } ++ ++ public static boolean areAnyFull(final DiscreteVoxelShape shape) { ++ if (shape.isEmpty()) { ++ return false; ++ } ++ ++ final int sizeX = shape.getXSize(); ++ final int sizeY = shape.getYSize(); ++ final int sizeZ = shape.getZSize(); ++ ++ for (int x = 0; x < sizeX; ++x) { ++ for (int y = 0; y < sizeY; ++y) { ++ for (int z = 0; z < sizeZ; ++z) { ++ if (shape.isFull(x, y, z)) { ++ return true; ++ } ++ } ++ } ++ } ++ ++ return false; ++ } ++ ++ public static String shapeMismatch(final DiscreteVoxelShape shape1, final DiscreteVoxelShape shape2) { ++ final CachedShapeData cachedShapeData1 = ((CollisionDiscreteVoxelShape)shape1).moonrise$getOrCreateCachedShapeData(); ++ final CachedShapeData cachedShapeData2 = ((CollisionDiscreteVoxelShape)shape2).moonrise$getOrCreateCachedShapeData(); ++ ++ final boolean isEmpty1 = cachedShapeData1.isEmpty(); ++ final boolean isEmpty2 = cachedShapeData2.isEmpty(); ++ ++ if (isEmpty1 & isEmpty2) { ++ return null; ++ } else if (isEmpty1 ^ isEmpty2) { ++ return null; ++ } // else: isEmpty1 = isEmpty2 = false ++ ++ if (cachedShapeData1.sizeX() != cachedShapeData2.sizeX()) { ++ return "size x: " + cachedShapeData1.sizeX() + " != " + cachedShapeData2.sizeX(); ++ } ++ if (cachedShapeData1.sizeY() != cachedShapeData2.sizeY()) { ++ return "size y: " + cachedShapeData1.sizeY() + " != " + cachedShapeData2.sizeY(); ++ } ++ if (cachedShapeData1.sizeZ() != cachedShapeData2.sizeZ()) { ++ return "size z: " + cachedShapeData1.sizeZ() + " != " + cachedShapeData2.sizeZ(); ++ } ++ ++ final StringBuilder ret = new StringBuilder(); ++ ++ final int sizeX = cachedShapeData1.sizeX();; ++ final int sizeY = cachedShapeData1.sizeY(); ++ final int sizeZ = cachedShapeData1.sizeZ(); ++ ++ boolean first = true; ++ ++ for (int x = 0; x < sizeX; ++x) { ++ for (int y = 0; y < sizeY; ++y) { ++ for (int z = 0; z < sizeZ; ++z) { ++ final boolean isFull1 = shape1.isFull(x, y, z); ++ final boolean isFull2 = shape2.isFull(x, y, z); ++ ++ if (isFull1 == isFull2) { ++ continue; ++ } ++ ++ if (first) { ++ first = false; ++ } else { ++ ret.append(", "); ++ } ++ ++ ret.append("(").append(x).append(",").append(y).append(",").append(z) ++ .append("): shape1: ").append(isFull1).append(", shape2: ").append(isFull2); ++ } ++ } ++ } ++ ++ return ret.isEmpty() ? null : ret.toString(); + } + -+ public static net.minecraft.world.phys.AABB offsetX(final net.minecraft.world.phys.AABB box, final double dx) { -+ return new net.minecraft.world.phys.AABB(box.minX + dx, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); ++ public static AABB offsetX(final AABB box, final double dx) { ++ return new AABB(box.minX + dx, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); + } + -+ public static net.minecraft.world.phys.AABB offsetY(final net.minecraft.world.phys.AABB box, final double dy) { -+ return new net.minecraft.world.phys.AABB(box.minX, box.minY + dy, box.minZ, box.maxX, box.maxY + dy, box.maxZ); ++ public static AABB offsetY(final AABB box, final double dy) { ++ return new AABB(box.minX, box.minY + dy, box.minZ, box.maxX, box.maxY + dy, box.maxZ); + } + -+ public static net.minecraft.world.phys.AABB offsetZ(final net.minecraft.world.phys.AABB box, final double dz) { -+ return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ + dz, box.maxX, box.maxY, box.maxZ + dz); ++ public static AABB offsetZ(final AABB box, final double dz) { ++ return new AABB(box.minX, box.minY, box.minZ + dz, box.maxX, box.maxY, box.maxZ + dz); + } + -+ public static net.minecraft.world.phys.AABB expandRight(final net.minecraft.world.phys.AABB box, final double dx) { // dx > 0.0 -+ return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); ++ public static AABB expandRight(final AABB box, final double dx) { // dx > 0.0 ++ return new AABB(box.minX, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); + } + -+ public static net.minecraft.world.phys.AABB expandLeft(final net.minecraft.world.phys.AABB box, final double dx) { // dx < 0.0 -+ return new net.minecraft.world.phys.AABB(box.minX - dx, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ); ++ public static AABB expandLeft(final AABB box, final double dx) { // dx < 0.0 ++ return new AABB(box.minX - dx, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ); + } + -+ public static net.minecraft.world.phys.AABB expandUpwards(final net.minecraft.world.phys.AABB box, final double dy) { // dy > 0.0 -+ return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ, box.maxX, box.maxY + dy, box.maxZ); ++ public static AABB expandUpwards(final AABB box, final double dy) { // dy > 0.0 ++ return new AABB(box.minX, box.minY, box.minZ, box.maxX, box.maxY + dy, box.maxZ); + } + -+ public static net.minecraft.world.phys.AABB expandDownwards(final net.minecraft.world.phys.AABB box, final double dy) { // dy < 0.0 -+ return new net.minecraft.world.phys.AABB(box.minX, box.minY - dy, box.minZ, box.maxX, box.maxY, box.maxZ); ++ public static AABB expandDownwards(final AABB box, final double dy) { // dy < 0.0 ++ return new AABB(box.minX, box.minY - dy, box.minZ, box.maxX, box.maxY, box.maxZ); + } + -+ public static net.minecraft.world.phys.AABB expandForwards(final net.minecraft.world.phys.AABB box, final double dz) { // dz > 0.0 -+ return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ + dz); ++ public static AABB expandForwards(final AABB box, final double dz) { // dz > 0.0 ++ return new AABB(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ + dz); + } + -+ public static net.minecraft.world.phys.AABB expandBackwards(final net.minecraft.world.phys.AABB box, final double dz) { // dz < 0.0 -+ return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ - dz, box.maxX, box.maxY, box.maxZ); ++ public static AABB expandBackwards(final AABB box, final double dz) { // dz < 0.0 ++ return new AABB(box.minX, box.minY, box.minZ - dz, box.maxX, box.maxY, box.maxZ); + } + -+ public static net.minecraft.world.phys.AABB cutRight(final net.minecraft.world.phys.AABB box, final double dx) { // dx > 0.0 -+ return new net.minecraft.world.phys.AABB(box.maxX, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); ++ public static AABB cutRight(final AABB box, final double dx) { // dx > 0.0 ++ return new AABB(box.maxX, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); + } + -+ public static net.minecraft.world.phys.AABB cutLeft(final net.minecraft.world.phys.AABB box, final double dx) { // dx < 0.0 -+ return new net.minecraft.world.phys.AABB(box.minX + dx, box.minY, box.minZ, box.minX, box.maxY, box.maxZ); ++ public static AABB cutLeft(final AABB box, final double dx) { // dx < 0.0 ++ return new AABB(box.minX + dx, box.minY, box.minZ, box.minX, box.maxY, box.maxZ); + } + -+ public static net.minecraft.world.phys.AABB cutUpwards(final net.minecraft.world.phys.AABB box, final double dy) { // dy > 0.0 -+ return new net.minecraft.world.phys.AABB(box.minX, box.maxY, box.minZ, box.maxX, box.maxY + dy, box.maxZ); ++ public static AABB cutUpwards(final AABB box, final double dy) { // dy > 0.0 ++ return new AABB(box.minX, box.maxY, box.minZ, box.maxX, box.maxY + dy, box.maxZ); + } + -+ public static net.minecraft.world.phys.AABB cutDownwards(final net.minecraft.world.phys.AABB box, final double dy) { // dy < 0.0 -+ return new net.minecraft.world.phys.AABB(box.minX, box.minY + dy, box.minZ, box.maxX, box.minY, box.maxZ); ++ public static AABB cutDownwards(final AABB box, final double dy) { // dy < 0.0 ++ return new AABB(box.minX, box.minY + dy, box.minZ, box.maxX, box.minY, box.maxZ); + } + -+ public static net.minecraft.world.phys.AABB cutForwards(final net.minecraft.world.phys.AABB box, final double dz) { // dz > 0.0 -+ return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.maxZ, box.maxX, box.maxY, box.maxZ + dz); ++ public static AABB cutForwards(final AABB box, final double dz) { // dz > 0.0 ++ return new AABB(box.minX, box.minY, box.maxZ, box.maxX, box.maxY, box.maxZ + dz); + } + -+ public static net.minecraft.world.phys.AABB cutBackwards(final net.minecraft.world.phys.AABB box, final double dz) { // dz < 0.0 -+ return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ + dz, box.maxX, box.maxY, box.minZ); ++ public static AABB cutBackwards(final AABB box, final double dz) { // dz < 0.0 ++ return new AABB(box.minX, box.minY, box.minZ + dz, box.maxX, box.maxY, box.minZ); + } + -+ public static double performAABBCollisionsX(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { ++ public static double performAABBCollisionsX(final AABB currentBoundingBox, double value, final List potentialCollisions) { + for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { + if (Math.abs(value) < COLLISION_EPSILON) { + return 0.0; + } -+ final net.minecraft.world.phys.AABB target = potentialCollisions.get(i); ++ final AABB target = potentialCollisions.get(i); + value = collideX(target, currentBoundingBox, value); + } + -+ return value; ++ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; + } + -+ public static double performAABBCollisionsY(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { ++ public static double performAABBCollisionsY(final AABB currentBoundingBox, double value, final List potentialCollisions) { + for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { + if (Math.abs(value) < COLLISION_EPSILON) { + return 0.0; + } -+ final net.minecraft.world.phys.AABB target = potentialCollisions.get(i); ++ final AABB target = potentialCollisions.get(i); + value = collideY(target, currentBoundingBox, value); + } + -+ return value; ++ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; + } + -+ public static double performAABBCollisionsZ(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { ++ public static double performAABBCollisionsZ(final AABB currentBoundingBox, double value, final List potentialCollisions) { + for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { + if (Math.abs(value) < COLLISION_EPSILON) { + return 0.0; + } -+ final net.minecraft.world.phys.AABB target = potentialCollisions.get(i); ++ final AABB target = potentialCollisions.get(i); + value = collideZ(target, currentBoundingBox, value); + } + -+ return value; ++ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; + } + -+ public static double performVoxelCollisionsX(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { ++ public static double performVoxelCollisionsX(final AABB currentBoundingBox, double value, final List potentialCollisions) { + for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { + if (Math.abs(value) < COLLISION_EPSILON) { + return 0.0; + } -+ final net.minecraft.world.phys.shapes.VoxelShape target = potentialCollisions.get(i); ++ final VoxelShape target = potentialCollisions.get(i); + value = collideX(target, currentBoundingBox, value); + } + -+ return value; ++ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; + } + -+ public static double performVoxelCollisionsY(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { ++ public static double performVoxelCollisionsY(final AABB currentBoundingBox, double value, final List potentialCollisions) { + for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { + if (Math.abs(value) < COLLISION_EPSILON) { + return 0.0; + } -+ final net.minecraft.world.phys.shapes.VoxelShape target = potentialCollisions.get(i); ++ final VoxelShape target = potentialCollisions.get(i); + value = collideY(target, currentBoundingBox, value); + } + -+ return value; ++ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; + } + -+ public static double performVoxelCollisionsZ(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { ++ public static double performVoxelCollisionsZ(final AABB currentBoundingBox, double value, final List potentialCollisions) { + for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { + if (Math.abs(value) < COLLISION_EPSILON) { + return 0.0; + } -+ final net.minecraft.world.phys.shapes.VoxelShape target = potentialCollisions.get(i); ++ final VoxelShape target = potentialCollisions.get(i); + value = collideZ(target, currentBoundingBox, value); + } + -+ return value; ++ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; + } + -+ public static net.minecraft.world.phys.Vec3 performVoxelCollisions(final net.minecraft.world.phys.Vec3 moveVector, net.minecraft.world.phys.AABB axisalignedbb, final java.util.List potentialCollisions) { ++ public static Vec3 performVoxelCollisions(final Vec3 moveVector, AABB axisalignedbb, final List potentialCollisions) { + double x = moveVector.x; + double y = moveVector.y; + double z = moveVector.z; @@ -16695,10 +17938,10 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + z = performVoxelCollisionsZ(axisalignedbb, z, potentialCollisions); + } + -+ return new net.minecraft.world.phys.Vec3(x, y, z); ++ return new Vec3(x, y, z); + } + -+ public static net.minecraft.world.phys.Vec3 performAABBCollisions(final net.minecraft.world.phys.Vec3 moveVector, net.minecraft.world.phys.AABB axisalignedbb, final java.util.List potentialCollisions) { ++ public static Vec3 performAABBCollisions(final Vec3 moveVector, AABB axisalignedbb, final List potentialCollisions) { + double x = moveVector.x; + double y = moveVector.y; + double z = moveVector.z; @@ -16730,12 +17973,12 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + z = performAABBCollisionsZ(axisalignedbb, z, potentialCollisions); + } + -+ return new net.minecraft.world.phys.Vec3(x, y, z); ++ return new Vec3(x, y, z); + } + -+ public static net.minecraft.world.phys.Vec3 performCollisions(final net.minecraft.world.phys.Vec3 moveVector, net.minecraft.world.phys.AABB axisalignedbb, -+ final java.util.List voxels, -+ final java.util.List aabbs) { ++ public static Vec3 performCollisions(final Vec3 moveVector, AABB axisalignedbb, ++ final List voxels, ++ final List aabbs) { + if (voxels.isEmpty()) { + // fast track only AABBs + return performAABBCollisions(moveVector, axisalignedbb, aabbs); @@ -16776,14 +18019,14 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + z = performVoxelCollisionsZ(axisalignedbb, z, voxels); + } + -+ return new net.minecraft.world.phys.Vec3(x, y, z); ++ return new Vec3(x, y, z); + } + -+ public static boolean isCollidingWithBorder(final net.minecraft.world.level.border.WorldBorder worldborder, final net.minecraft.world.phys.AABB boundingBox) { ++ public static boolean isCollidingWithBorder(final WorldBorder worldborder, final AABB boundingBox) { + return isCollidingWithBorder(worldborder, boundingBox.minX, boundingBox.maxX, boundingBox.minZ, boundingBox.maxZ); + } + -+ public static boolean isCollidingWithBorder(final net.minecraft.world.level.border.WorldBorder worldborder, ++ public static boolean isCollidingWithBorder(final WorldBorder worldborder, + final double boxMinX, final double boxMaxX, + final double boxMinZ, final double boxMaxZ) { + final double borderMinX = Math.floor(worldborder.getMinX()); // -X @@ -16793,8 +18036,8 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + final double borderMaxZ = Math.ceil(worldborder.getMaxZ()); // +Z + + // inverted check for world border enclosing the specified box expanded by -EPSILON -+ return (borderMinX - boxMinX) > ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON || (borderMaxX - boxMaxX) < -ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON || -+ (borderMinZ - boxMinZ) > ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON || (borderMaxZ - boxMaxZ) < -ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON; ++ return (borderMinX - boxMinX) > CollisionUtil.COLLISION_EPSILON || (borderMaxX - boxMaxX) < -CollisionUtil.COLLISION_EPSILON || ++ (borderMinZ - boxMinZ) > CollisionUtil.COLLISION_EPSILON || (borderMaxZ - boxMaxZ) < -CollisionUtil.COLLISION_EPSILON; + } + + /* Math.max/min specify that any NaN argument results in a NaN return, unlike these functions */ @@ -16811,38 +18054,38 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + public static final int COLLISION_FLAG_CHECK_BORDER = 1 << 2; + public static final int COLLISION_FLAG_CHECK_ONLY = 1 << 3; + -+ public static boolean getCollisionsForBlocksOrWorldBorder(final net.minecraft.world.level.Level world, final net.minecraft.world.entity.Entity entity, final net.minecraft.world.phys.AABB aabb, -+ final java.util.List intoVoxel, final java.util.List intoAABB, -+ final int collisionFlags, final java.util.function.BiPredicate predicate) { ++ public static boolean getCollisionsForBlocksOrWorldBorder(final Level world, final Entity entity, final AABB aabb, ++ final List intoVoxel, final List intoAABB, ++ final int collisionFlags, final BiPredicate predicate) { + final boolean checkOnly = (collisionFlags & COLLISION_FLAG_CHECK_ONLY) != 0; + boolean ret = false; + + if ((collisionFlags & COLLISION_FLAG_CHECK_BORDER) != 0) { -+ final net.minecraft.world.level.border.WorldBorder worldBorder = world.getWorldBorder(); -+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isCollidingWithBorder(worldBorder, aabb) && entity != null && worldBorder.isInsideCloseToBorder(entity, aabb)) { ++ final WorldBorder worldBorder = world.getWorldBorder(); ++ if (CollisionUtil.isCollidingWithBorder(worldBorder, aabb) && entity != null && worldBorder.isInsideCloseToBorder(entity, aabb)) { + if (checkOnly) { + return true; + } else { -+ final net.minecraft.world.phys.shapes.VoxelShape borderShape = worldBorder.getCollisionShape(); ++ final VoxelShape borderShape = worldBorder.getCollisionShape(); + intoVoxel.add(borderShape); + ret = true; + } + } + } + -+ final int minSection = ((ca.spottedleaf.moonrise.patches.collisions.world.CollisionLevel)world).moonrise$getMinSection(); ++ final int minSection = WorldUtil.getMinSection(world); + -+ final int minBlockX = net.minecraft.util.Mth.floor(aabb.minX - COLLISION_EPSILON) - 1; -+ final int maxBlockX = net.minecraft.util.Mth.floor(aabb.maxX + COLLISION_EPSILON) + 1; ++ final int minBlockX = Mth.floor(aabb.minX - COLLISION_EPSILON) - 1; ++ final int maxBlockX = Mth.floor(aabb.maxX + COLLISION_EPSILON) + 1; + -+ final int minBlockY = Math.max((minSection << 4) - 1, net.minecraft.util.Mth.floor(aabb.minY - COLLISION_EPSILON) - 1); -+ final int maxBlockY = Math.min((((ca.spottedleaf.moonrise.patches.collisions.world.CollisionLevel)world).moonrise$getMaxSection() << 4) + 16, net.minecraft.util.Mth.floor(aabb.maxY + COLLISION_EPSILON) + 1); ++ final int minBlockY = Math.max((minSection << 4) - 1, Mth.floor(aabb.minY - COLLISION_EPSILON) - 1); ++ final int maxBlockY = Math.min((WorldUtil.getMaxSection(world) << 4) + 16, Mth.floor(aabb.maxY + COLLISION_EPSILON) + 1); + -+ final int minBlockZ = net.minecraft.util.Mth.floor(aabb.minZ - COLLISION_EPSILON) - 1; -+ final int maxBlockZ = net.minecraft.util.Mth.floor(aabb.maxZ + COLLISION_EPSILON) + 1; ++ final int minBlockZ = Mth.floor(aabb.minZ - COLLISION_EPSILON) - 1; ++ final int maxBlockZ = Mth.floor(aabb.maxZ + COLLISION_EPSILON) + 1; + -+ final net.minecraft.core.BlockPos.MutableBlockPos mutablePos = new net.minecraft.core.BlockPos.MutableBlockPos(); -+ final net.minecraft.world.phys.shapes.CollisionContext collisionShape = new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext(entity); ++ final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); ++ final CollisionContext collisionShape = new LazyEntityCollisionContext(entity); + + // special cases: + if (minBlockY > maxBlockY) { @@ -16860,11 +18103,11 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + final int maxChunkZ = maxBlockZ >> 4; + + final boolean loadChunks = (collisionFlags & COLLISION_FLAG_LOAD_CHUNKS) != 0; -+ final net.minecraft.world.level.chunk.ChunkSource chunkSource = world.getChunkSource(); ++ final ChunkSource chunkSource = world.getChunkSource(); + + for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { + for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { -+ final net.minecraft.world.level.chunk.ChunkAccess chunk = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, loadChunks); ++ final ChunkAccess chunk = chunkSource.getChunk(currChunkX, currChunkZ, ChunkStatus.FULL, loadChunks); + + if (chunk == null) { + if ((collisionFlags & COLLISION_FLAG_COLLIDE_WITH_UNLOADED_CHUNKS) != 0) { @@ -16878,7 +18121,7 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + continue; + } + -+ final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections(); ++ final LevelChunkSection[] sections = chunk.getSections(); + + // bound y + for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) { @@ -16886,16 +18129,16 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + if (sectionIdx < 0 || sectionIdx >= sections.length) { + continue; + } -+ final net.minecraft.world.level.chunk.LevelChunkSection section = sections[sectionIdx]; -+ if (section == null || section.hasOnlyAir()) { ++ final LevelChunkSection section = sections[sectionIdx]; ++ if (section.hasOnlyAir()) { + // empty + continue; + } + -+ final boolean hasSpecial = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$getSpecialCollidingBlocks() != 0; ++ final boolean hasSpecial = ((BlockCountingChunkSection)section).moonrise$hasSpecialCollidingBlocks(); + final int sectionAdjust = !hasSpecial ? 1 : 0; + -+ final net.minecraft.world.level.chunk.PalettedContainer blocks = section.states; ++ final PalettedContainer blocks = section.states; + + final int minXIterate = currChunkX == minChunkX ? (minBlockX & 15) + sectionAdjust : 0; + final int maxXIterate = currChunkX == maxChunkX ? (maxBlockX & 15) - sectionAdjust : 15; @@ -16919,21 +18162,21 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + continue; + } + -+ final net.minecraft.world.level.block.state.BlockState blockData = blocks.get(localBlockIndex); ++ final BlockState blockData = blocks.get(localBlockIndex); + -+ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockData).moonrise$emptyCollisionShape()) { ++ if (((CollisionBlockState)blockData).moonrise$emptyContextCollisionShape()) { + continue; + } + -+ net.minecraft.world.phys.shapes.VoxelShape blockCollision = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockData).moonrise$getConstantCollisionShape(); ++ VoxelShape blockCollision = ((CollisionBlockState)blockData).moonrise$getConstantContextCollisionShape(); + -+ if (edgeCount == 0 || ((edgeCount != 1 || blockData.hasLargeCollisionShape()) && (edgeCount != 2 || blockData.getBlock() == net.minecraft.world.level.block.Blocks.MOVING_PISTON))) { ++ if (edgeCount == 0 || ((edgeCount != 1 || blockData.hasLargeCollisionShape()) && (edgeCount != 2 || blockData.getBlock() == Blocks.MOVING_PISTON))) { + if (blockCollision == null) { + mutablePos.set(blockX, blockY, blockZ); + blockCollision = blockData.getCollisionShape(world, mutablePos, collisionShape); + } + -+ net.minecraft.world.phys.AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation(); ++ AABB singleAABB = ((CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation(); + if (singleAABB != null) { + singleAABB = singleAABB.move((double)blockX, (double)blockY, (double)blockZ); + if (!voxelShapeIntersect(aabb, singleAABB)) { @@ -16960,7 +18203,7 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + continue; + } + -+ final net.minecraft.world.phys.shapes.VoxelShape blockCollisionOffset = blockCollision.move((double)blockX, (double)blockY, (double)blockZ); ++ final VoxelShape blockCollisionOffset = blockCollision.move((double)blockX, (double)blockY, (double)blockZ); + + if (!voxelShapeIntersectNoEmpty(blockCollisionOffset, aabb)) { + continue; @@ -16991,8 +18234,8 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + return ret; + } + -+ public static boolean getEntityHardCollisions(final net.minecraft.world.level.Level world, final net.minecraft.world.entity.Entity entity, net.minecraft.world.phys.AABB aabb, -+ final java.util.List into, final int collisionFlags, final java.util.function.Predicate predicate) { ++ public static boolean getEntityHardCollisions(final Level world, final Entity entity, AABB aabb, ++ final List into, final int collisionFlags, final Predicate predicate) { + final boolean checkOnly = (collisionFlags & COLLISION_FLAG_CHECK_ONLY) != 0; + + boolean ret = false; @@ -17001,15 +18244,15 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + // Vanilla for hard collisions has this backwards, and they expand by +epsilon but this causes terrible problems + // specifically with boat collisions. + aabb = aabb.inflate(-COLLISION_EPSILON, -COLLISION_EPSILON, -COLLISION_EPSILON); -+ final java.util.List entities; -+ if (entity != null && ((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)entity).moonrise$isHardColliding()) { ++ final List entities; ++ if (entity != null && ((ChunkSystemEntity)entity).moonrise$isHardColliding()) { + entities = world.getEntities(entity, aabb, predicate); + } else { -+ entities = ((ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemEntityGetter)world).moonrise$getHardCollidingEntities(entity, aabb, predicate); ++ entities = ((ChunkSystemEntityGetter)world).moonrise$getHardCollidingEntities(entity, aabb, predicate); + } + + for (int i = 0, len = entities.size(); i < len; ++i) { -+ final net.minecraft.world.entity.Entity otherEntity = entities.get(i); ++ final Entity otherEntity = entities.get(i); + + if (otherEntity.isSpectator()) { + continue; @@ -17028,10 +18271,10 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + return ret; + } + -+ public static boolean getCollisions(final net.minecraft.world.level.Level world, final net.minecraft.world.entity.Entity entity, final net.minecraft.world.phys.AABB aabb, -+ final java.util.List intoVoxel, final java.util.List intoAABB, final int collisionFlags, -+ final java.util.function.BiPredicate blockPredicate, -+ final java.util.function.Predicate entityPredicate) { ++ public static boolean getCollisions(final Level world, final Entity entity, final AABB aabb, ++ final List intoVoxel, final List intoAABB, final int collisionFlags, ++ final BiPredicate blockPredicate, ++ final Predicate entityPredicate) { + if ((collisionFlags & COLLISION_FLAG_CHECK_ONLY) != 0) { + return getCollisionsForBlocksOrWorldBorder(world, entity, aabb, intoVoxel, intoAABB, collisionFlags, blockPredicate) + || getEntityHardCollisions(world, entity, aabb, intoAABB, collisionFlags, entityPredicate); @@ -17041,12 +18284,12 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + } + } + -+ public static final class LazyEntityCollisionContext extends net.minecraft.world.phys.shapes.EntityCollisionContext { ++ public static final class LazyEntityCollisionContext extends EntityCollisionContext { + -+ private net.minecraft.world.phys.shapes.CollisionContext delegate; ++ private CollisionContext delegate; + private boolean delegated; + -+ public LazyEntityCollisionContext(final net.minecraft.world.entity.Entity entity) { ++ public LazyEntityCollisionContext(final Entity entity) { + super(false, 0.0, null, null, entity); + } + @@ -17056,10 +18299,10 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + return delegated; + } + -+ public net.minecraft.world.phys.shapes.CollisionContext getDelegate() { ++ public CollisionContext getDelegate() { + this.delegated = true; -+ final net.minecraft.world.entity.Entity entity = this.getEntity(); -+ return this.delegate == null ? this.delegate = (entity == null ? net.minecraft.world.phys.shapes.CollisionContext.empty() : net.minecraft.world.phys.shapes.CollisionContext.of(entity)) : this.delegate; ++ final Entity entity = this.getEntity(); ++ return this.delegate == null ? this.delegate = (entity == null ? CollisionContext.empty() : CollisionContext.of(entity)) : this.delegate; + } + + @Override @@ -17068,17 +18311,17 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a + } + + @Override -+ public boolean isAbove(final net.minecraft.world.phys.shapes.VoxelShape shape, final net.minecraft.core.BlockPos pos, final boolean defaultValue) { ++ public boolean isAbove(final VoxelShape shape, final BlockPos pos, final boolean defaultValue) { + return this.getDelegate().isAbove(shape, pos, defaultValue); + } + + @Override -+ public boolean isHoldingItem(final net.minecraft.world.item.Item item) { ++ public boolean isHoldingItem(final Item item) { + return this.getDelegate().isHoldingItem(item); + } + + @Override -+ public boolean canStandOnFluid(final net.minecraft.world.level.material.FluidState state, final net.minecraft.world.level.material.FluidState fluidState) { ++ public boolean canStandOnFluid(final FluidState state, final FluidState fluidState) { + return this.getDelegate().canStandOnFluid(state, fluidState); + } + } @@ -17089,25 +18332,30 @@ index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/ExplosionBlockCache.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/ExplosionBlockCache.java new file mode 100644 -index 0000000000000000000000000000000000000000..eb7200657d5c7ac37ee93868ba43be0aefecac6d +index 0000000000000000000000000000000000000000..35c8aaf0bfa42717f45eed1d1072e1614874de91 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/ExplosionBlockCache.java -@@ -0,0 +1,23 @@ +@@ -0,0 +1,28 @@ +package ca.spottedleaf.moonrise.patches.collisions; + ++import net.minecraft.core.BlockPos; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.material.FluidState; ++import net.minecraft.world.phys.shapes.VoxelShape; ++ +public final class ExplosionBlockCache { + + public final long key; -+ public final net.minecraft.core.BlockPos immutablePos; -+ public final net.minecraft.world.level.block.state.BlockState blockState; -+ public final net.minecraft.world.level.material.FluidState fluidState; ++ public final BlockPos immutablePos; ++ public final BlockState blockState; ++ public final FluidState fluidState; + public final float resistance; + public final boolean outOfWorld; + public Boolean shouldExplode; // null -> not called yet -+ public net.minecraft.world.phys.shapes.VoxelShape cachedCollisionShape; ++ public VoxelShape cachedCollisionShape; + -+ public ExplosionBlockCache(final long key, final net.minecraft.core.BlockPos immutablePos, final net.minecraft.world.level.block.state.BlockState blockState, -+ final net.minecraft.world.level.material.FluidState fluidState, final float resistance, final boolean outOfWorld) { ++ public ExplosionBlockCache(final long key, final BlockPos immutablePos, final BlockState blockState, ++ final FluidState fluidState, final float resistance, final boolean outOfWorld) { + this.key = key; + this.immutablePos = immutablePos; + this.blockState = blockState; @@ -17118,12 +18366,14 @@ index 0000000000000000000000000000000000000000..eb7200657d5c7ac37ee93868ba43be0a +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/block/CollisionBlockState.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/block/CollisionBlockState.java new file mode 100644 -index 0000000000000000000000000000000000000000..02b29c563a298e06186de010de68a716bccba494 +index 0000000000000000000000000000000000000000..a38ab583200ebf68ca68fdddf2d12077720b72b7 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/block/CollisionBlockState.java -@@ -0,0 +1,26 @@ +@@ -0,0 +1,29 @@ +package ca.spottedleaf.moonrise.patches.collisions.block; + ++import net.minecraft.world.phys.shapes.VoxelShape; ++ +public interface CollisionBlockState { + + // note: this does not consider canOcclude, it is only based on the cached collision shape (i.e hasCache()) @@ -17133,6 +18383,9 @@ index 0000000000000000000000000000000000000000..02b29c563a298e06186de010de68a716 + // whether the cached collision shape exists and is empty + public boolean moonrise$emptyCollisionShape(); + ++ // whether the context-sensitive shape is constant and is empty ++ public boolean moonrise$emptyContextCollisionShape(); ++ + // indicates that occludesFullBlock is cached for the collision shape + public boolean moonrise$hasCache(); + @@ -17144,9 +18397,7 @@ index 0000000000000000000000000000000000000000..02b29c563a298e06186de010de68a716 + // value is still unique + public int moonrise$uniqueId2(); + -+ public net.minecraft.world.phys.shapes.VoxelShape moonrise$getConstantCollisionShape(); -+ -+ public net.minecraft.world.phys.AABB moonrise$getConstantCollisionAABB(); ++ public VoxelShape moonrise$getConstantContextCollisionShape(); +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CachedShapeData.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CachedShapeData.java new file mode 100644 @@ -17166,34 +18417,38 @@ index 0000000000000000000000000000000000000000..5a6b16be4b8c0cc92d017bc592bc4818 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CachedToAABBs.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CachedToAABBs.java new file mode 100644 -index 0000000000000000000000000000000000000000..5fe1dad9dad368911aedbe6ba7fcd8f9b0189d32 +index 0000000000000000000000000000000000000000..9d33ead3a97d86b371e4d9ad9fed80d789bed844 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CachedToAABBs.java -@@ -0,0 +1,35 @@ +@@ -0,0 +1,39 @@ +package ca.spottedleaf.moonrise.patches.collisions.shape; + ++import net.minecraft.world.phys.AABB; ++import java.util.ArrayList; ++import java.util.List; ++ +public record CachedToAABBs( -+ java.util.List aabbs, ++ List aabbs, + boolean isOffset, + double offX, double offY, double offZ +) { + -+ public ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs removeOffset() { -+ final java.util.List toOffset = this.aabbs; ++ public CachedToAABBs removeOffset() { ++ final List toOffset = this.aabbs; + final double offX = this.offX; + final double offY = this.offY; + final double offZ = this.offZ; + -+ final java.util.List ret = new java.util.ArrayList<>(toOffset.size()); ++ final List ret = new ArrayList<>(toOffset.size()); + + for (int i = 0, len = toOffset.size(); i < len; ++i) { + ret.add(toOffset.get(i).move(offX, offY, offZ)); + } + -+ return new ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs(ret, false, 0.0, 0.0, 0.0); ++ return new CachedToAABBs(ret, false, 0.0, 0.0, 0.0); + } + -+ public static ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs offset(final ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs cache, final double offX, final double offY, final double offZ) { ++ public static CachedToAABBs offset(final CachedToAABBs cache, final double offX, final double offY, final double offZ) { + if (offX == 0.0 && offY == 0.0 && offZ == 0.0) { + return cache; + } @@ -17202,12 +18457,12 @@ index 0000000000000000000000000000000000000000..5fe1dad9dad368911aedbe6ba7fcd8f9 + final double resY = cache.offY + offY; + final double resZ = cache.offZ + offZ; + -+ return new ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs(cache.aabbs, true, resX, resY, resZ); ++ return new CachedToAABBs(cache.aabbs, true, resX, resY, resZ); + } +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionDiscreteVoxelShape.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionDiscreteVoxelShape.java new file mode 100644 -index 0000000000000000000000000000000000000000..a09efadea9b733840bbe69830dd8f2a303fe656f +index 0000000000000000000000000000000000000000..07fe5e02c2d0a27d2fe37bb45761654dc2d02e5d --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionDiscreteVoxelShape.java @@ -0,0 +1,7 @@ @@ -17215,335 +18470,98 @@ index 0000000000000000000000000000000000000000..a09efadea9b733840bbe69830dd8f2a3 + +public interface CollisionDiscreteVoxelShape { + -+ public ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData moonrise$getOrCreateCachedShapeData(); ++ public CachedShapeData moonrise$getOrCreateCachedShapeData(); + +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionVoxelShape.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionVoxelShape.java new file mode 100644 -index 0000000000000000000000000000000000000000..70371eb87c11a106e8513cdbc8d938dda088f745 +index 0000000000000000000000000000000000000000..05d7b3f9d8659c259f3ed0537c57e6e43eb6e288 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionVoxelShape.java -@@ -0,0 +1,36 @@ -+package ca.spottedleaf.moonrise.patches.collisions.shape; -+ -+public interface CollisionVoxelShape { -+ -+ public double moonrise$offsetX(); -+ -+ public double moonrise$offsetY(); -+ -+ public double moonrise$offsetZ(); -+ -+ public double[] moonrise$rootCoordinatesX(); -+ -+ public double[] moonrise$rootCoordinatesY(); -+ -+ public double[] moonrise$rootCoordinatesZ(); -+ -+ public ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData moonrise$getCachedVoxelData(); -+ -+ // rets null if not possible to represent this shape as one AABB -+ public net.minecraft.world.phys.AABB moonrise$getSingleAABBRepresentation(); -+ -+ // ONLY USE INTERNALLY, ONLY FOR INITIALISING IN CONSTRUCTOR: VOXELSHAPES ARE STATIC -+ public void moonrise$initCache(); -+ -+ // this returns empty if not clamped to 1.0 or 0.0 depending on direction -+ public net.minecraft.world.phys.shapes.VoxelShape moonrise$getFaceShapeClamped(final net.minecraft.core.Direction direction); -+ -+ public boolean moonrise$isFullBlock(); -+ -+ public boolean moonrise$occludesFullBlock(); -+ -+ public boolean moonrise$occludesFullBlockIfCached(); -+ -+ // uses a cache internally -+ public net.minecraft.world.phys.shapes.VoxelShape moonrise$orUnoptimized(final net.minecraft.world.phys.shapes.VoxelShape other); -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/MergedORCache.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/MergedORCache.java -new file mode 100644 -index 0000000000000000000000000000000000000000..4217426d3eca5e5cd2bc37e509f84da1d6fed0b2 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/MergedORCache.java -@@ -0,0 +1,8 @@ +@@ -0,0 +1,40 @@ +package ca.spottedleaf.moonrise.patches.collisions.shape; + -+public record MergedORCache( -+ net.minecraft.world.phys.shapes.VoxelShape key, -+ net.minecraft.world.phys.shapes.VoxelShape result -+) { -+ -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/CollisionDirection.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/CollisionDirection.java -new file mode 100644 -index 0000000000000000000000000000000000000000..f62359e5d6aa9a9cdb015441dbdb6182dc302f02 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/CollisionDirection.java -@@ -0,0 +1,9 @@ -+package ca.spottedleaf.moonrise.patches.collisions.util; -+ -+public interface CollisionDirection { -+ -+ // note: this is HashCommon#murmurHash3(some unique id) and since murmurHash3 has an inverse function the returned -+ // value is still unique -+ public int moonrise$uniqueId(); -+ -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/EmptyStreamForMoveCall.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/EmptyStreamForMoveCall.java -new file mode 100644 -index 0000000000000000000000000000000000000000..673103f160cbe577c6e05f998706af4e6850011b ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/EmptyStreamForMoveCall.java -@@ -0,0 +1,225 @@ -+package ca.spottedleaf.moonrise.patches.collisions.util; -+ -+import java.util.Iterator; -+import java.util.Optional; -+import java.util.Spliterator; -+import java.util.stream.Stream; -+ -+public final class EmptyStreamForMoveCall implements java.util.stream.Stream { -+ -+ public static final ca.spottedleaf.moonrise.patches.collisions.util.EmptyStreamForMoveCall INSTANCE = new ca.spottedleaf.moonrise.patches.collisions.util.EmptyStreamForMoveCall(); -+ -+ @Override -+ public boolean noneMatch(java.util.function.Predicate predicate) { -+ return false; // important: ret false so the branch is never taken by mojang code -+ } -+ -+ @Override -+ public java.util.stream.Stream filter(java.util.function.Predicate predicate) { -+ return null; -+ } -+ -+ @Override -+ public java.util.stream.Stream map(java.util.function.Function mapper) { -+ return null; -+ } -+ -+ @Override -+ public java.util.stream.IntStream mapToInt(java.util.function.ToIntFunction mapper) { -+ return null; -+ } -+ -+ @Override -+ public java.util.stream.LongStream mapToLong(java.util.function.ToLongFunction mapper) { -+ return null; -+ } -+ -+ @Override -+ public java.util.stream.DoubleStream mapToDouble(java.util.function.ToDoubleFunction mapper) { -+ return null; -+ } -+ -+ @Override -+ public java.util.stream.Stream flatMap(java.util.function.Function> mapper) { -+ return null; -+ } -+ -+ @Override -+ public java.util.stream.IntStream flatMapToInt(java.util.function.Function mapper) { -+ return null; -+ } -+ -+ @Override -+ public java.util.stream.LongStream flatMapToLong(java.util.function.Function mapper) { -+ return null; -+ } -+ -+ @Override -+ public java.util.stream.DoubleStream flatMapToDouble(java.util.function.Function mapper) { -+ return null; -+ } -+ -+ @Override -+ public java.util.stream.Stream distinct() { -+ return null; -+ } -+ -+ @Override -+ public java.util.stream.Stream sorted() { -+ return null; -+ } -+ -+ @Override -+ public java.util.stream.Stream sorted(java.util.Comparator comparator) { -+ return null; -+ } -+ -+ @Override -+ public java.util.stream.Stream peek(java.util.function.Consumer action) { -+ return null; -+ } -+ -+ @Override -+ public java.util.stream.Stream limit(long maxSize) { -+ return null; -+ } -+ -+ @Override -+ public java.util.stream.Stream skip(long n) { -+ return null; -+ } -+ -+ @Override -+ public void forEach(java.util.function.Consumer action) { -+ -+ } -+ -+ @Override -+ public void forEachOrdered(java.util.function.Consumer action) { -+ -+ } -+ -+ @org.jetbrains.annotations.NotNull -+ @Override -+ public Object[] toArray() { -+ return new Object[0]; -+ } -+ -+ @org.jetbrains.annotations.NotNull -+ @Override -+ public
    A[] toArray(java.util.function.IntFunction generator) { -+ return null; -+ } -+ -+ @Override -+ public T reduce(T identity, java.util.function.BinaryOperator accumulator) { -+ return null; -+ } -+ -+ @org.jetbrains.annotations.NotNull -+ @Override -+ public Optional reduce(java.util.function.BinaryOperator accumulator) { -+ return java.util.Optional.empty(); -+ } -+ -+ @Override -+ public U reduce(U identity, java.util.function.BiFunction accumulator, java.util.function.BinaryOperator combiner) { -+ return null; -+ } -+ -+ @Override -+ public R collect(java.util.function.Supplier supplier, java.util.function.BiConsumer accumulator, java.util.function.BiConsumer combiner) { -+ return null; -+ } -+ -+ @Override -+ public R collect(java.util.stream.Collector collector) { -+ return null; -+ } -+ -+ @org.jetbrains.annotations.NotNull -+ @Override -+ public Optional min(java.util.Comparator comparator) { -+ return java.util.Optional.empty(); -+ } -+ -+ @org.jetbrains.annotations.NotNull -+ @Override -+ public Optional max(java.util.Comparator comparator) { -+ return java.util.Optional.empty(); -+ } ++import net.minecraft.core.Direction; ++import net.minecraft.world.phys.AABB; ++import net.minecraft.world.phys.shapes.VoxelShape; + -+ @Override -+ public long count() { -+ return 0; -+ } ++public interface CollisionVoxelShape { + -+ @Override -+ public boolean anyMatch(java.util.function.Predicate predicate) { -+ return false; -+ } ++ public double moonrise$offsetX(); + -+ @Override -+ public boolean allMatch(java.util.function.Predicate predicate) { -+ return false; -+ } ++ public double moonrise$offsetY(); + -+ @org.jetbrains.annotations.NotNull -+ @Override -+ public Optional findFirst() { -+ return java.util.Optional.empty(); -+ } ++ public double moonrise$offsetZ(); + -+ @org.jetbrains.annotations.NotNull -+ @Override -+ public Optional findAny() { -+ return java.util.Optional.empty(); -+ } ++ public double[] moonrise$rootCoordinatesX(); + ++ public double[] moonrise$rootCoordinatesY(); + -+ @org.jetbrains.annotations.NotNull -+ @Override -+ public Iterator iterator() { -+ return null; -+ } ++ public double[] moonrise$rootCoordinatesZ(); + -+ @org.jetbrains.annotations.NotNull -+ @Override -+ public Spliterator spliterator() { -+ return null; -+ } ++ public CachedShapeData moonrise$getCachedVoxelData(); + -+ @Override -+ public boolean isParallel() { -+ return false; -+ } ++ // rets null if not possible to represent this shape as one AABB ++ public AABB moonrise$getSingleAABBRepresentation(); + -+ @org.jetbrains.annotations.NotNull -+ @Override -+ public Stream sequential() { -+ return null; -+ } ++ // ONLY USE INTERNALLY, ONLY FOR INITIALISING IN CONSTRUCTOR: VOXELSHAPES ARE STATIC ++ public void moonrise$initCache(); + -+ @org.jetbrains.annotations.NotNull -+ @Override -+ public Stream parallel() { -+ return null; -+ } ++ // this returns empty if not clamped to 1.0 or 0.0 depending on direction ++ public VoxelShape moonrise$getFaceShapeClamped(final Direction direction); + -+ @org.jetbrains.annotations.NotNull -+ @Override -+ public Stream unordered() { -+ return null; -+ } ++ public boolean moonrise$isFullBlock(); + -+ @org.jetbrains.annotations.NotNull -+ @Override -+ public Stream onClose(Runnable closeHandler) { -+ return null; -+ } ++ public boolean moonrise$occludesFullBlock(); + -+ @Override -+ public void close() { ++ public boolean moonrise$occludesFullBlockIfCached(); + -+ } ++ // uses a cache internally ++ public VoxelShape moonrise$orUnoptimized(final VoxelShape other); +} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/MergedORCache.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/MergedORCache.java new file mode 100644 -index 0000000000000000000000000000000000000000..128267ff40b38c7b3ea0feb5133825cc6aae075b +index 0000000000000000000000000000000000000000..44831fc18efb7534dc6e4822f3c9b5cdc4dcc33e --- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java -@@ -0,0 +1,4 @@ -+package ca.spottedleaf.moonrise.patches.collisions.util; ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/MergedORCache.java +@@ -0,0 +1,10 @@ ++package ca.spottedleaf.moonrise.patches.collisions.shape; ++ ++import net.minecraft.world.phys.shapes.VoxelShape; ++ ++public record MergedORCache( ++ VoxelShape key, ++ VoxelShape result ++) { + -+public record FluidOcclusionCacheKey(net.minecraft.world.level.block.state.BlockState first, net.minecraft.world.level.block.state.BlockState second, net.minecraft.core.Direction direction, boolean result) { +} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/world/CollisionLevel.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/world/CollisionLevel.java +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/CollisionDirection.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/CollisionDirection.java new file mode 100644 -index 0000000000000000000000000000000000000000..e851e81e13edbad6316df63fcb7095d48f85c5b0 +index 0000000000000000000000000000000000000000..f62359e5d6aa9a9cdb015441dbdb6182dc302f02 --- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/world/CollisionLevel.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/CollisionDirection.java @@ -0,0 +1,9 @@ -+package ca.spottedleaf.moonrise.patches.collisions.world; ++package ca.spottedleaf.moonrise.patches.collisions.util; ++ ++public interface CollisionDirection { + -+public interface CollisionLevel { ++ // note: this is HashCommon#murmurHash3(some unique id) and since murmurHash3 has an inverse function the returned ++ // value is still unique ++ public int moonrise$uniqueId(); + -+ public int moonrise$getMinSection(); ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java +new file mode 100644 +index 0000000000000000000000000000000000000000..cf9ffdeff6bf0b62a45f7a44dbfe0dd7d17dc4f4 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java +@@ -0,0 +1,7 @@ ++package ca.spottedleaf.moonrise.patches.collisions.util; + -+ public int moonrise$getMaxSection(); ++import net.minecraft.core.Direction; ++import net.minecraft.world.level.block.state.BlockState; + ++public record FluidOcclusionCacheKey(BlockState first, BlockState second, Direction direction, boolean result) { +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerEntity.java b/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerEntity.java new file mode 100644 @@ -17564,10 +18582,10 @@ index 0000000000000000000000000000000000000000..5f5734c00ce8245a1ff69b2d4c303657 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerTrackedEntity.java b/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerTrackedEntity.java new file mode 100644 -index 0000000000000000000000000000000000000000..1fa07bef57d82c6d5242aaaf66011f0913515231 +index 0000000000000000000000000000000000000000..8e7472157a98de607c03769a91f64c8369fd3ea6 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerTrackedEntity.java -@@ -0,0 +1,13 @@ +@@ -0,0 +1,15 @@ +package ca.spottedleaf.moonrise.patches.entity_tracker; + +import ca.spottedleaf.moonrise.common.misc.NearbyPlayers; @@ -17580,21 +18598,77 @@ index 0000000000000000000000000000000000000000..1fa07bef57d82c6d5242aaaf66011f09 + + public void moonrise$clearPlayers(); + ++ public boolean moonrise$hasPlayers(); ++ ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPalette.java b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPalette.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4a7abd239a9c59aa98947e7993962d75e9051902 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPalette.java +@@ -0,0 +1,9 @@ ++package ca.spottedleaf.moonrise.patches.fast_palette; ++ ++public interface FastPalette { ++ ++ public default T[] moonrise$getRawPalette(final FastPaletteData src) { ++ return null; ++ } ++ ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPaletteData.java b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPaletteData.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4503f3495846a7d7ed082b9e24636044e4fbccd1 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPaletteData.java +@@ -0,0 +1,9 @@ ++package ca.spottedleaf.moonrise.patches.fast_palette; ++ ++public interface FastPaletteData { ++ ++ public T[] moonrise$getPalette(); ++ ++ public void moonrise$setPalette(final T[] palette); ++ ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/fluid/FluidFluidState.java b/src/main/java/ca/spottedleaf/moonrise/patches/fluid/FluidFluidState.java +new file mode 100644 +index 0000000000000000000000000000000000000000..107c97089354edd35f330582f5e0c8a18e792a6e +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/fluid/FluidFluidState.java +@@ -0,0 +1,5 @@ ++package ca.spottedleaf.moonrise.patches.fluid; ++ ++public interface FluidFluidState { ++ public void moonrise$initCaches(); ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/getblock/GetBlockChunk.java b/src/main/java/ca/spottedleaf/moonrise/patches/getblock/GetBlockChunk.java +new file mode 100644 +index 0000000000000000000000000000000000000000..540c14a6d2c216cd3ef2a9c4056e15712bf8cb8c +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/getblock/GetBlockChunk.java +@@ -0,0 +1,9 @@ ++package ca.spottedleaf.moonrise.patches.getblock; ++ ++import net.minecraft.world.level.block.state.BlockState; ++ ++public interface GetBlockChunk { ++ ++ public BlockState moonrise$getBlock(final int x, final int y, final int z); ++ +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/blockstate/StarlightAbstractBlockState.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/blockstate/StarlightAbstractBlockState.java new file mode 100644 -index 0000000000000000000000000000000000000000..2bfdf3721db9a45e36538d71cbefcb1d339e6c58 +index 0000000000000000000000000000000000000000..8e6d79b7c10ef25f5478b72c53c555423d615a2f --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/blockstate/StarlightAbstractBlockState.java -@@ -0,0 +1,9 @@ +@@ -0,0 +1,7 @@ +package ca.spottedleaf.moonrise.patches.starlight.blockstate; + +public interface StarlightAbstractBlockState { + + public boolean starlight$isConditionallyFullOpaque(); + -+ public int starlight$getOpacityIfCached(); -+ +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/chunk/StarlightChunk.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/chunk/StarlightChunk.java new file mode 100644 @@ -17622,15 +18696,17 @@ index 0000000000000000000000000000000000000000..ed80017c8f257b981d626a37ffc5480d +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/BlockStarLightEngine.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/BlockStarLightEngine.java new file mode 100644 -index 0000000000000000000000000000000000000000..154443ac1ee1d6d18b8ff0f40a307d638b213aeb +index 0000000000000000000000000000000000000000..fa7b784a89626e8528c249d7889a598bd7ee3d49 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/BlockStarLightEngine.java -@@ -0,0 +1,277 @@ +@@ -0,0 +1,280 @@ +package ca.spottedleaf.moonrise.patches.starlight.light; + ++import ca.spottedleaf.moonrise.common.PlatformHooks; +import ca.spottedleaf.moonrise.patches.starlight.blockstate.StarlightAbstractBlockState; +import ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk; +import net.minecraft.core.BlockPos; ++import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; @@ -17719,7 +18795,7 @@ index 0000000000000000000000000000000000000000..154443ac1ee1d6d18b8ff0f40a307d63 + + final int currentLevel = this.getLightLevel(worldX, worldY, worldZ); + final BlockState blockState = this.getBlockState(worldX, worldY, worldZ); -+ final int emittedLevel = blockState.getLightEmission() & emittedMask; ++ final int emittedLevel = (PlatformHooks.get().getLightEmission(blockState, lightAccess.getLevel(), this.lightEmissionPos.set(worldX, worldY, worldZ))) & emittedMask; + + this.setLightLevel(worldX, worldY, worldZ, emittedLevel); + // this accounts for change in emitted light that would cause an increase @@ -17747,37 +18823,32 @@ index 0000000000000000000000000000000000000000..154443ac1ee1d6d18b8ff0f40a307d63 + } + + protected final BlockPos.MutableBlockPos recalcCenterPos = new BlockPos.MutableBlockPos(); -+ protected final BlockPos.MutableBlockPos recalcNeighbourPos = new BlockPos.MutableBlockPos(); + + @Override + protected int calculateLightValue(final LightChunkGetter lightAccess, final int worldX, final int worldY, final int worldZ, + final int expect) { ++ this.recalcCenterPos.set(worldX, worldY, worldZ); ++ + final BlockState centerState = this.getBlockState(worldX, worldY, worldZ); -+ int level = centerState.getLightEmission() & 0xF; ++ final BlockGetter world = lightAccess.getLevel(); ++ int level = (PlatformHooks.get().getLightEmission(centerState, world, this.recalcCenterPos)) & this.emittedLightMask; + + if (level >= (15 - 1) || level > expect) { + return level; + } + -+ final int sectionOffset = this.chunkSectionIndexOffset; -+ final BlockState conditionallyOpaqueState; -+ int opacity = ((StarlightAbstractBlockState)centerState).starlight$getOpacityIfCached(); -+ -+ if (opacity == -1) { -+ this.recalcCenterPos.set(worldX, worldY, worldZ); -+ opacity = centerState.getLightBlock(lightAccess.getLevel(), this.recalcCenterPos); -+ if (((StarlightAbstractBlockState)centerState).starlight$isConditionallyFullOpaque()) { -+ conditionallyOpaqueState = centerState; -+ } else { -+ conditionallyOpaqueState = null; -+ } -+ } else if (opacity >= 15) { ++ final int opacity = Math.max(1, centerState.getLightBlock()); ++ if (opacity >= 15) { + return level; ++ } ++ final BlockState conditionallyOpaqueState; ++ if (((StarlightAbstractBlockState)centerState).starlight$isConditionallyFullOpaque()) { ++ conditionallyOpaqueState = centerState; + } else { + conditionallyOpaqueState = null; + } -+ opacity = Math.max(1, opacity); + ++ final int sectionOffset = this.chunkSectionIndexOffset; + for (final AxisDirection direction : AXIS_DIRECTIONS) { + final int offX = worldX + direction.x; + final int offY = worldY + direction.y; @@ -17797,9 +18868,8 @@ index 0000000000000000000000000000000000000000..154443ac1ee1d6d18b8ff0f40a307d63 + // here the block can be conditionally opaque (i.e light cannot propagate from it), so we need to test that + // we don't read the blockstate because most of the time this is false, so using the faster + // known transparency lookup results in a net win -+ this.recalcNeighbourPos.set(offX, offY, offZ); -+ final VoxelShape neighbourFace = neighbourState.getFaceOcclusionShape(lightAccess.getLevel(), this.recalcNeighbourPos, direction.opposite.nms); -+ final VoxelShape thisFace = conditionallyOpaqueState == null ? Shapes.empty() : conditionallyOpaqueState.getFaceOcclusionShape(lightAccess.getLevel(), this.recalcCenterPos, direction.nms); ++ final VoxelShape neighbourFace = neighbourState.getFaceOcclusionShape(direction.opposite.nms); ++ final VoxelShape thisFace = conditionallyOpaqueState == null ? Shapes.empty() : conditionallyOpaqueState.getFaceOcclusionShape(direction.nms); + if (Shapes.faceShapeOccludes(thisFace, neighbourFace)) { + // not allowed to propagate + continue; @@ -17833,30 +18903,34 @@ index 0000000000000000000000000000000000000000..154443ac1ee1d6d18b8ff0f40a307d63 + final int offX = chunk.getPos().x << 4; + final int offZ = chunk.getPos().z << 4; + ++ final PlatformHooks platformHooks = PlatformHooks.get(); ++ ++ final BlockGetter world = lightAccess.getLevel(); + final LevelChunkSection[] sections = chunk.getSections(); + for (int sectionY = this.minSection; sectionY <= this.maxSection; ++sectionY) { + final LevelChunkSection section = sections[sectionY - this.minSection]; -+ if (section == null || section.hasOnlyAir()) { ++ if (section.hasOnlyAir()) { + // no sources in empty sections + continue; + } -+ if (!section.maybeHas((final BlockState state) -> { -+ return state.getLightEmission() > 0; -+ })) { ++ if (!section.maybeHas(platformHooks.maybeHasLightEmission())) { + // no light sources in palette + continue; + } + final PalettedContainer states = section.states; + final int offY = sectionY << 4; + ++ final BlockPos.MutableBlockPos mutablePos = this.lightEmissionPos; + for (int index = 0; index < (16 * 16 * 16); ++index) { + final BlockState state = states.get(index); -+ if (state.getLightEmission() <= 0) { ++ mutablePos.set(offX | (index & 15), offY | (index >>> 8), offZ | ((index >>> 4) & 15)); ++ ++ if ((platformHooks.getLightEmission(state, world, mutablePos)) == 0) { + continue; + } + + // index = x | (z << 4) | (y << 8) -+ sources.add(new BlockPos(offX | (index & 15), offY | (index >>> 8), offZ | ((index >>> 4) & 15))); ++ sources.add(mutablePos.immutable()); + } + } + @@ -17866,12 +18940,15 @@ index 0000000000000000000000000000000000000000..154443ac1ee1d6d18b8ff0f40a307d63 + @Override + public void lightChunk(final LightChunkGetter lightAccess, final ChunkAccess chunk, final boolean needsEdgeChecks) { + // setup sources ++ final BlockGetter world = lightAccess.getLevel(); ++ final PlatformHooks platformHooks = PlatformHooks.get(); ++ + final int emittedMask = this.emittedLightMask; + final List positions = this.getSources(lightAccess, chunk); + for (int i = 0, len = positions.size(); i < len; ++i) { + final BlockPos pos = positions.get(i); + final BlockState blockState = this.getBlockState(pos.getX(), pos.getY(), pos.getZ()); -+ final int emittedLight = blockState.getLightEmission() & emittedMask; ++ final int emittedLight = platformHooks.getLightEmission(blockState, world, pos) & emittedMask; + + if (emittedLight <= this.getLightLevel(pos.getX(), pos.getY(), pos.getZ())) { + // some other source is brighter @@ -18351,10 +19428,10 @@ index 0000000000000000000000000000000000000000..4ca68a903e67606fc4ef0bfa9862a737 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/SkyStarLightEngine.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/SkyStarLightEngine.java new file mode 100644 -index 0000000000000000000000000000000000000000..fdbc015f498164c9d2c578cd84a73def568142a4 +index 0000000000000000000000000000000000000000..f9aef289e9a2d6f63c98c72c56ef32b8793f57f4 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/SkyStarLightEngine.java -@@ -0,0 +1,711 @@ +@@ -0,0 +1,681 @@ +package ca.spottedleaf.moonrise.patches.starlight.light; + +import ca.spottedleaf.moonrise.common.util.WorldUtil; @@ -18647,9 +19724,6 @@ index 0000000000000000000000000000000000000000..fdbc015f498164c9d2c578cd84a73def + ); + } + -+ protected final BlockPos.MutableBlockPos recalcCenterPos = new BlockPos.MutableBlockPos(); -+ protected final BlockPos.MutableBlockPos recalcNeighbourPos = new BlockPos.MutableBlockPos(); -+ + @Override + protected int calculateLightValue(final LightChunkGetter lightAccess, final int worldX, final int worldY, final int worldZ, + final int expect) { @@ -18659,20 +19733,13 @@ index 0000000000000000000000000000000000000000..fdbc015f498164c9d2c578cd84a73def + + final int sectionOffset = this.chunkSectionIndexOffset; + final BlockState centerState = this.getBlockState(worldX, worldY, worldZ); -+ int opacity = ((StarlightAbstractBlockState)centerState).starlight$getOpacityIfCached(); + + final BlockState conditionallyOpaqueState; -+ if (opacity < 0) { -+ this.recalcCenterPos.set(worldX, worldY, worldZ); -+ opacity = Math.max(1, centerState.getLightBlock(lightAccess.getLevel(), this.recalcCenterPos)); -+ if (((StarlightAbstractBlockState)centerState).starlight$isConditionallyFullOpaque()) { -+ conditionallyOpaqueState = centerState; -+ } else { -+ conditionallyOpaqueState = null; -+ } ++ final int opacity = Math.max(1, centerState.getLightBlock()); ++ if (((StarlightAbstractBlockState)centerState).starlight$isConditionallyFullOpaque()) { ++ conditionallyOpaqueState = centerState; + } else { + conditionallyOpaqueState = null; -+ opacity = Math.max(1, opacity); + } + + int level = 0; @@ -18697,9 +19764,8 @@ index 0000000000000000000000000000000000000000..fdbc015f498164c9d2c578cd84a73def + // here the block can be conditionally opaque (i.e light cannot propagate from it), so we need to test that + // we don't read the blockstate because most of the time this is false, so using the faster + // known transparency lookup results in a net win -+ this.recalcNeighbourPos.set(offX, offY, offZ); -+ final VoxelShape neighbourFace = neighbourState.getFaceOcclusionShape(lightAccess.getLevel(), this.recalcNeighbourPos, direction.opposite.nms); -+ final VoxelShape thisFace = conditionallyOpaqueState == null ? Shapes.empty() : conditionallyOpaqueState.getFaceOcclusionShape(lightAccess.getLevel(), this.recalcCenterPos, direction.nms); ++ final VoxelShape neighbourFace = neighbourState.getFaceOcclusionShape(direction.opposite.nms); ++ final VoxelShape thisFace = conditionallyOpaqueState == null ? Shapes.empty() : conditionallyOpaqueState.getFaceOcclusionShape(direction.nms); + if (Shapes.faceShapeOccludes(thisFace, neighbourFace)) { + // not allowed to propagate + continue; @@ -18967,7 +20033,6 @@ index 0000000000000000000000000000000000000000..fdbc015f498164c9d2c578cd84a73def + // clobbering the light values will result in broken propagation) + protected final int tryPropagateSkylight(final BlockGetter world, final int worldX, int startY, final int worldZ, + final boolean extrudeInitialised, final boolean delayLightSet) { -+ final BlockPos.MutableBlockPos mutablePos = this.mutablePos3; + final int encodeOffset = this.coordinateOffset; + final long propagateDirection = AxisDirection.POSITIVE_Y.everythingButThisDirection; // just don't check upwards. + @@ -18989,8 +20054,7 @@ index 0000000000000000000000000000000000000000..fdbc015f498164c9d2c578cd84a73def + + final VoxelShape fromShape; + if (((StarlightAbstractBlockState)above).starlight$isConditionallyFullOpaque()) { -+ this.mutablePos2.set(worldX, startY + 1, worldZ); -+ fromShape = above.getFaceOcclusionShape(world, this.mutablePos2, AxisDirection.NEGATIVE_Y.nms); ++ fromShape = above.getFaceOcclusionShape(AxisDirection.NEGATIVE_Y.nms); + if (Shapes.faceShapeOccludes(Shapes.empty(), fromShape)) { + // above wont let us propagate + break; @@ -18999,49 +20063,32 @@ index 0000000000000000000000000000000000000000..fdbc015f498164c9d2c578cd84a73def + fromShape = Shapes.empty(); + } + -+ final int opacityIfCached = ((StarlightAbstractBlockState)current).starlight$getOpacityIfCached(); + // does light propagate from the top down? -+ if (opacityIfCached != -1) { -+ if (opacityIfCached != 0) { -+ // we cannot propagate 15 through this -+ break; -+ } -+ // most of the time it falls here. -+ // add to propagate -+ // light set delayed until we determine if this nibble section is null -+ this.appendToIncreaseQueue( -+ ((worldX + (worldZ << 6) + (startY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | (15L << (6 + 6 + 16)) // we know we're at full lit here -+ | (propagateDirection << (6 + 6 + 16 + 4)) -+ ); -+ } else { -+ mutablePos.set(worldX, startY, worldZ); -+ long flags = 0L; -+ if (((StarlightAbstractBlockState)current).starlight$isConditionallyFullOpaque()) { -+ final VoxelShape cullingFace = current.getFaceOcclusionShape(world, mutablePos, AxisDirection.POSITIVE_Y.nms); -+ -+ if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { -+ // can't propagate here, we're done on this column. -+ break; -+ } -+ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -+ } ++ long flags = 0L; ++ if (((StarlightAbstractBlockState)current).starlight$isConditionallyFullOpaque()) { ++ final VoxelShape cullingFace = current.getFaceOcclusionShape(AxisDirection.POSITIVE_Y.nms); + -+ final int opacity = current.getLightBlock(world, mutablePos); -+ if (opacity > 0) { -+ // let the queued value (if any) handle it from here. ++ if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { ++ // can't propagate here, we're done on this column. + break; + } ++ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; ++ } + -+ // light set delayed until we determine if this nibble section is null -+ this.appendToIncreaseQueue( -+ ((worldX + (worldZ << 6) + (startY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | (15L << (6 + 6 + 16)) // we know we're at full lit here -+ | (propagateDirection << (6 + 6 + 16 + 4)) -+ | flags -+ ); ++ final int opacity = current.getLightBlock(); ++ if (opacity > 0) { ++ // let the queued value (if any) handle it from here. ++ break; + } + ++ // light set delayed until we determine if this nibble section is null ++ this.appendToIncreaseQueue( ++ ((worldX + (worldZ << 6) + (startY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | (15L << (6 + 6 + 16)) // we know we're at full lit here ++ | (propagateDirection << (6 + 6 + 16 + 4)) ++ | flags ++ ); ++ + above = current; + + if (this.getNibbleFromCache(worldX >> 4, startY >> 4, worldZ >> 4) == null) { @@ -19068,13 +20115,14 @@ index 0000000000000000000000000000000000000000..fdbc015f498164c9d2c578cd84a73def +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightEngine.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightEngine.java new file mode 100644 -index 0000000000000000000000000000000000000000..382c9e445af0d6ad2428fc22d0f63017c58191e2 +index 0000000000000000000000000000000000000000..8aeb5fb87f94a35659347a09a638420699b52a6f --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightEngine.java -@@ -0,0 +1,1573 @@ +@@ -0,0 +1,1438 @@ +package ca.spottedleaf.moonrise.patches.starlight.light; + +import ca.spottedleaf.concurrentutil.util.IntegerUtil; ++import ca.spottedleaf.moonrise.common.PlatformHooks; +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +import ca.spottedleaf.moonrise.common.util.WorldUtil; +import ca.spottedleaf.moonrise.patches.starlight.blockstate.StarlightAbstractBlockState; @@ -19117,9 +20165,9 @@ index 0000000000000000000000000000000000000000..382c9e445af0d6ad2428fc22d0f63017 + protected static enum AxisDirection { + + // Declaration order is important and relied upon. Do not change without modifying propagation code. -+ POSITIVE_X(1, 0, 0), NEGATIVE_X(-1, 0, 0), -+ POSITIVE_Z(0, 0, 1), NEGATIVE_Z(0, 0, -1), -+ POSITIVE_Y(0, 1, 0), NEGATIVE_Y(0, -1, 0); ++ POSITIVE_X(1, 0, 0, Direction.EAST) , NEGATIVE_X(-1, 0, 0, Direction.WEST), ++ POSITIVE_Z(0, 0, 1, Direction.SOUTH), NEGATIVE_Z(0, 0, -1, Direction.NORTH), ++ POSITIVE_Y(0, 1, 0, Direction.UP) , NEGATIVE_Y(0, -1, 0, Direction.DOWN); + + static { + POSITIVE_X.opposite = NEGATIVE_X; NEGATIVE_X.opposite = POSITIVE_X; @@ -19136,11 +20184,11 @@ index 0000000000000000000000000000000000000000..382c9e445af0d6ad2428fc22d0f63017 + public final long everythingButThisDirection; + public final long everythingButTheOppositeDirection; + -+ AxisDirection(final int x, final int y, final int z) { ++ AxisDirection(final int x, final int y, final int z, final Direction nms) { + this.x = x; + this.y = y; + this.z = z; -+ this.nms = Direction.fromDelta(x, y, z); ++ this.nms = nms; + this.everythingButThisDirection = (long)(ALL_DIRECTIONS_BITSET ^ (1 << this.ordinal())); + // positive is always even, negative is always odd. Flip the 1 bit to get the negative direction. + this.everythingButTheOppositeDirection = (long)(ALL_DIRECTIONS_BITSET ^ (1 << (this.ordinal() ^ 1))); @@ -19180,9 +20228,7 @@ index 0000000000000000000000000000000000000000..382c9e445af0d6ad2428fc22d0f63017 + // index = x + (z * 5) + protected final boolean[][] emptinessMapCache = new boolean[5 * 5][]; + -+ protected final BlockPos.MutableBlockPos mutablePos1 = new BlockPos.MutableBlockPos(); -+ protected final BlockPos.MutableBlockPos mutablePos2 = new BlockPos.MutableBlockPos(); -+ protected final BlockPos.MutableBlockPos mutablePos3 = new BlockPos.MutableBlockPos(); ++ protected final BlockPos.MutableBlockPos lightEmissionPos = new BlockPos.MutableBlockPos(); + + protected int encodeOffsetX; + protected int encodeOffsetY; @@ -20224,69 +21270,46 @@ index 0000000000000000000000000000000000000000..382c9e445af0d6ad2428fc22d0f63017 + if (blockState == null) { + continue; + } -+ final int opacityCached = ((StarlightAbstractBlockState)blockState).starlight$getOpacityIfCached(); -+ if (opacityCached != -1) { -+ final int targetLevel = propagatedLightLevel - Math.max(1, opacityCached); -+ if (targetLevel > currentLevel) { -+ currentNibble.set(localIndex, targetLevel); -+ this.postLightUpdate(offX, offY, offZ); -+ -+ if (targetLevel > 1) { -+ if (queueLength >= queue.length) { -+ queue = this.resizeIncreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)); -+ continue; -+ } -+ } -+ continue; -+ } else { -+ this.mutablePos1.set(offX, offY, offZ); -+ long flags = 0; -+ if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { -+ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms); -+ -+ if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) { -+ continue; -+ } -+ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -+ } ++ long flags = 0; ++ if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { ++ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(propagate.getOpposite().nms); + -+ final int opacity = blockState.getLightBlock(world, this.mutablePos1); -+ final int targetLevel = propagatedLightLevel - Math.max(1, opacity); -+ if (targetLevel <= currentLevel) { ++ if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) { + continue; + } ++ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; ++ } ++ ++ final int opacity = blockState.getLightBlock(); ++ final int targetLevel = propagatedLightLevel - Math.max(1, opacity); ++ if (targetLevel <= currentLevel) { ++ continue; ++ } + -+ currentNibble.set(localIndex, targetLevel); -+ this.postLightUpdate(offX, offY, offZ); ++ currentNibble.set(localIndex, targetLevel); ++ this.postLightUpdate(offX, offY, offZ); + -+ if (targetLevel > 1) { -+ if (queueLength >= queue.length) { -+ queue = this.resizeIncreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)) -+ | (flags); ++ if (targetLevel > 1) { ++ if (queueLength >= queue.length) { ++ queue = this.resizeIncreaseQueue(); + } -+ continue; ++ queue[queueLength++] = ++ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | ((targetLevel & 0xFL) << (6 + 6 + 16)) ++ | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)) ++ | (flags); + } ++ continue; + } + } else { + // we actually need to worry about our state here + final BlockState fromBlock = this.getBlockState(posX, posY, posZ); -+ this.mutablePos2.set(posX, posY, posZ); + for (final AxisDirection propagate : checkDirections) { + final int offX = posX + propagate.x; + final int offY = posY + propagate.y; + final int offZ = posZ + propagate.z; + -+ final VoxelShape fromShape = (((StarlightAbstractBlockState)fromBlock).starlight$isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(world, this.mutablePos2, propagate.nms) : Shapes.empty(); ++ final VoxelShape fromShape = (((StarlightAbstractBlockState)fromBlock).starlight$isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(propagate.nms) : Shapes.empty(); + + if (fromShape != Shapes.empty() && Shapes.faceShapeOccludes(Shapes.empty(), fromShape)) { + continue; @@ -20306,58 +21329,36 @@ index 0000000000000000000000000000000000000000..382c9e445af0d6ad2428fc22d0f63017 + if (blockState == null) { + continue; + } -+ final int opacityCached = ((StarlightAbstractBlockState)blockState).starlight$getOpacityIfCached(); -+ if (opacityCached != -1) { -+ final int targetLevel = propagatedLightLevel - Math.max(1, opacityCached); -+ if (targetLevel > currentLevel) { -+ currentNibble.set(localIndex, targetLevel); -+ this.postLightUpdate(offX, offY, offZ); -+ -+ if (targetLevel > 1) { -+ if (queueLength >= queue.length) { -+ queue = this.resizeIncreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)); -+ continue; -+ } -+ } -+ continue; -+ } else { -+ this.mutablePos1.set(offX, offY, offZ); -+ long flags = 0; -+ if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { -+ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms); -+ -+ if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { -+ continue; -+ } -+ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -+ } ++ long flags = 0; ++ if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { ++ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(propagate.getOpposite().nms); + -+ final int opacity = blockState.getLightBlock(world, this.mutablePos1); -+ final int targetLevel = propagatedLightLevel - Math.max(1, opacity); -+ if (targetLevel <= currentLevel) { ++ if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { + continue; + } ++ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; ++ } ++ ++ final int opacity = blockState.getLightBlock(); ++ final int targetLevel = propagatedLightLevel - Math.max(1, opacity); ++ if (targetLevel <= currentLevel) { ++ continue; ++ } + -+ currentNibble.set(localIndex, targetLevel); -+ this.postLightUpdate(offX, offY, offZ); ++ currentNibble.set(localIndex, targetLevel); ++ this.postLightUpdate(offX, offY, offZ); + -+ if (targetLevel > 1) { -+ if (queueLength >= queue.length) { -+ queue = this.resizeIncreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)) -+ | (flags); ++ if (targetLevel > 1) { ++ if (queueLength >= queue.length) { ++ queue = this.resizeIncreaseQueue(); + } -+ continue; ++ queue[queueLength++] = ++ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | ((targetLevel & 0xFL) << (6 + 6 + 16)) ++ | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)) ++ | (flags); + } ++ continue; + } + } + } @@ -20378,6 +21379,8 @@ index 0000000000000000000000000000000000000000..382c9e445af0d6ad2428fc22d0f63017 + final int sectionOffset = this.chunkSectionIndexOffset; + final int emittedMask = this.emittedLightMask; + ++ final PlatformHooks platformHooks = PlatformHooks.get(); ++ + while (queueReadIndex < queueLength) { + final long queueValue = queue[queueReadIndex++]; + @@ -20409,109 +21412,63 @@ index 0000000000000000000000000000000000000000..382c9e445af0d6ad2428fc22d0f63017 + if (blockState == null) { + continue; + } -+ final int opacityCached = ((StarlightAbstractBlockState)blockState).starlight$getOpacityIfCached(); -+ if (opacityCached != -1) { -+ final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacityCached)); -+ if (lightLevel > targetLevel) { -+ // it looks like another source propagated here, so re-propagate it -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((lightLevel & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | FLAG_RECHECK_LEVEL; -+ continue; -+ } -+ final int emittedLight = blockState.getLightEmission() & emittedMask; -+ if (emittedLight != 0) { -+ // re-propagate source -+ // note: do not set recheck level, or else the propagation will fail -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((emittedLight & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque() ? (FLAG_WRITE_LEVEL | FLAG_HAS_SIDED_TRANSPARENT_BLOCKS) : FLAG_WRITE_LEVEL); -+ } ++ this.lightEmissionPos.set(offX, offY, offZ); ++ long flags = 0; ++ if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { ++ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(propagate.getOpposite().nms); + -+ currentNibble.set(localIndex, 0); -+ this.postLightUpdate(offX, offY, offZ); -+ -+ if (targetLevel > 0) { // we actually need to propagate 0 just in case we find a neighbour... -+ if (queueLength >= queue.length) { -+ queue = this.resizeDecreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)); ++ if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) { + continue; + } -+ continue; -+ } else { -+ this.mutablePos1.set(offX, offY, offZ); -+ long flags = 0; -+ if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { -+ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms); -+ -+ if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) { -+ continue; -+ } -+ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -+ } ++ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; ++ } + -+ final int opacity = blockState.getLightBlock(world, this.mutablePos1); -+ final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacity)); -+ if (lightLevel > targetLevel) { -+ // it looks like another source propagated here, so re-propagate it -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((lightLevel & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (FLAG_RECHECK_LEVEL | flags); -+ continue; ++ final int opacity = blockState.getLightBlock(); ++ final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacity)); ++ if (lightLevel > targetLevel) { ++ // it looks like another source propagated here, so re-propagate it ++ if (increaseQueueLength >= increaseQueue.length) { ++ increaseQueue = this.resizeIncreaseQueue(); + } -+ final int emittedLight = blockState.getLightEmission() & emittedMask; -+ if (emittedLight != 0) { -+ // re-propagate source -+ // note: do not set recheck level, or else the propagation will fail -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((emittedLight & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (flags | FLAG_WRITE_LEVEL); ++ increaseQueue[increaseQueueLength++] = ++ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | ((lightLevel & 0xFL) << (6 + 6 + 16)) ++ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) ++ | (FLAG_RECHECK_LEVEL | flags); ++ continue; ++ } ++ final int emittedLight = (platformHooks.getLightEmission(blockState, world, this.lightEmissionPos)) & emittedMask; ++ if (emittedLight != 0) { ++ // re-propagate source ++ // note: do not set recheck level, or else the propagation will fail ++ if (increaseQueueLength >= increaseQueue.length) { ++ increaseQueue = this.resizeIncreaseQueue(); + } ++ increaseQueue[increaseQueueLength++] = ++ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | ((emittedLight & 0xFL) << (6 + 6 + 16)) ++ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) ++ | (flags | FLAG_WRITE_LEVEL); ++ } + -+ currentNibble.set(localIndex, 0); -+ this.postLightUpdate(offX, offY, offZ); ++ currentNibble.set(localIndex, 0); ++ this.postLightUpdate(offX, offY, offZ); + -+ if (targetLevel > 0) { -+ if (queueLength >= queue.length) { -+ queue = this.resizeDecreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)) -+ | flags; ++ if (targetLevel > 0) { ++ if (queueLength >= queue.length) { ++ queue = this.resizeDecreaseQueue(); + } -+ continue; ++ queue[queueLength++] = ++ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | ((targetLevel & 0xFL) << (6 + 6 + 16)) ++ | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)) ++ | flags; + } ++ continue; + } + } else { + // we actually need to worry about our state here + final BlockState fromBlock = this.getBlockState(posX, posY, posZ); -+ this.mutablePos2.set(posX, posY, posZ); + for (final AxisDirection propagate : checkDirections) { + final int offX = posX + propagate.x; + final int offY = posY + propagate.y; @@ -20520,7 +21477,7 @@ index 0000000000000000000000000000000000000000..382c9e445af0d6ad2428fc22d0f63017 + final int sectionIndex = (offX >> 4) + 5 * (offZ >> 4) + (5 * 5) * (offY >> 4) + sectionOffset; + final int localIndex = (offX & 15) | ((offZ & 15) << 4) | ((offY & 15) << 8); + -+ final VoxelShape fromShape = (((StarlightAbstractBlockState)fromBlock).starlight$isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(world, this.mutablePos2, propagate.nms) : Shapes.empty(); ++ final VoxelShape fromShape = (((StarlightAbstractBlockState)fromBlock).starlight$isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(propagate.nms) : Shapes.empty(); + + if (fromShape != Shapes.empty() && Shapes.faceShapeOccludes(Shapes.empty(), fromShape)) { + continue; @@ -20538,104 +21495,59 @@ index 0000000000000000000000000000000000000000..382c9e445af0d6ad2428fc22d0f63017 + if (blockState == null) { + continue; + } -+ final int opacityCached = ((StarlightAbstractBlockState)blockState).starlight$getOpacityIfCached(); -+ if (opacityCached != -1) { -+ final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacityCached)); -+ if (lightLevel > targetLevel) { -+ // it looks like another source propagated here, so re-propagate it -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((lightLevel & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | FLAG_RECHECK_LEVEL; -+ continue; -+ } -+ final int emittedLight = blockState.getLightEmission() & emittedMask; -+ if (emittedLight != 0) { -+ // re-propagate source -+ // note: do not set recheck level, or else the propagation will fail -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((emittedLight & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque() ? (FLAG_WRITE_LEVEL | FLAG_HAS_SIDED_TRANSPARENT_BLOCKS) : FLAG_WRITE_LEVEL); -+ } ++ this.lightEmissionPos.set(offX, offY, offZ); ++ long flags = 0; ++ if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { ++ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(propagate.getOpposite().nms); + -+ currentNibble.set(localIndex, 0); -+ this.postLightUpdate(offX, offY, offZ); -+ -+ if (targetLevel > 0) { // we actually need to propagate 0 just in case we find a neighbour... -+ if (queueLength >= queue.length) { -+ queue = this.resizeDecreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)); ++ if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { + continue; + } -+ continue; -+ } else { -+ this.mutablePos1.set(offX, offY, offZ); -+ long flags = 0; -+ if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { -+ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms); -+ -+ if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { -+ continue; -+ } -+ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -+ } ++ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; ++ } + -+ final int opacity = blockState.getLightBlock(world, this.mutablePos1); -+ final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacity)); -+ if (lightLevel > targetLevel) { -+ // it looks like another source propagated here, so re-propagate it -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((lightLevel & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (FLAG_RECHECK_LEVEL | flags); -+ continue; ++ final int opacity = blockState.getLightBlock(); ++ final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacity)); ++ if (lightLevel > targetLevel) { ++ // it looks like another source propagated here, so re-propagate it ++ if (increaseQueueLength >= increaseQueue.length) { ++ increaseQueue = this.resizeIncreaseQueue(); + } -+ final int emittedLight = blockState.getLightEmission() & emittedMask; -+ if (emittedLight != 0) { -+ // re-propagate source -+ // note: do not set recheck level, or else the propagation will fail -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((emittedLight & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (flags | FLAG_WRITE_LEVEL); ++ increaseQueue[increaseQueueLength++] = ++ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | ((lightLevel & 0xFL) << (6 + 6 + 16)) ++ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) ++ | (FLAG_RECHECK_LEVEL | flags); ++ continue; ++ } ++ final int emittedLight = (platformHooks.getLightEmission(blockState, world, this.lightEmissionPos)) & emittedMask; ++ if (emittedLight != 0) { ++ // re-propagate source ++ // note: do not set recheck level, or else the propagation will fail ++ if (increaseQueueLength >= increaseQueue.length) { ++ increaseQueue = this.resizeIncreaseQueue(); + } ++ increaseQueue[increaseQueueLength++] = ++ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | ((emittedLight & 0xFL) << (6 + 6 + 16)) ++ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) ++ | (flags | FLAG_WRITE_LEVEL); ++ } + -+ currentNibble.set(localIndex, 0); -+ this.postLightUpdate(offX, offY, offZ); ++ currentNibble.set(localIndex, 0); ++ this.postLightUpdate(offX, offY, offZ); + -+ if (targetLevel > 0) { // we actually need to propagate 0 just in case we find a neighbour... -+ if (queueLength >= queue.length) { -+ queue = this.resizeDecreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)) -+ | flags; ++ if (targetLevel > 0) { // we actually need to propagate 0 just in case we find a neighbour... ++ if (queueLength >= queue.length) { ++ queue = this.resizeDecreaseQueue(); + } -+ continue; ++ queue[queueLength++] = ++ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) ++ | ((targetLevel & 0xFL) << (6 + 6 + 16)) ++ | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)) ++ | flags; + } ++ continue; + } + } + } @@ -20647,15 +21559,16 @@ index 0000000000000000000000000000000000000000..382c9e445af0d6ad2428fc22d0f63017 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java new file mode 100644 -index 0000000000000000000000000000000000000000..c64ab41198a5e0c7cbcbe6452af11f82f5938862 +index 0000000000000000000000000000000000000000..571db5f9bf94745a8afe2cd313e593fb15db5e37 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java -@@ -0,0 +1,930 @@ +@@ -0,0 +1,931 @@ +package ca.spottedleaf.moonrise.patches.starlight.light; + +import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; ++import ca.spottedleaf.concurrentutil.util.Priority; +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +import ca.spottedleaf.moonrise.common.util.WorldUtil; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel; @@ -21398,34 +22311,34 @@ index 0000000000000000000000000000000000000000..c64ab41198a5e0c7cbcbe6452af11f82 + super(lightInterface); + } + -+ public void lowerPriority(final int chunkX, final int chunkZ, final PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(final int chunkX, final int chunkZ, final Priority priority) { + final ServerChunkTasks task = this.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + if (task != null) { + task.lowerPriority(priority); + } + } + -+ public void setPriority(final int chunkX, final int chunkZ, final PrioritisedExecutor.Priority priority) { ++ public void setPriority(final int chunkX, final int chunkZ, final Priority priority) { + final ServerChunkTasks task = this.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + if (task != null) { + task.setPriority(priority); + } + } + -+ public void raisePriority(final int chunkX, final int chunkZ, final PrioritisedExecutor.Priority priority) { ++ public void raisePriority(final int chunkX, final int chunkZ, final Priority priority) { + final ServerChunkTasks task = this.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + if (task != null) { + task.raisePriority(priority); + } + } + -+ public PrioritisedExecutor.Priority getPriority(final int chunkX, final int chunkZ) { ++ public Priority getPriority(final int chunkX, final int chunkZ) { + final ServerChunkTasks task = this.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + if (task != null) { + return task.getPriority(); + } + -+ return PrioritisedExecutor.Priority.COMPLETING; ++ return Priority.COMPLETING; + } + + @Override @@ -21469,7 +22382,7 @@ index 0000000000000000000000000000000000000000..c64ab41198a5e0c7cbcbe6452af11f82 + return ret; + } + -+ public ServerChunkTasks queueChunkLightTask(final ChunkPos pos, final BooleanSupplier lightTask, final PrioritisedExecutor.Priority priority) { ++ public ServerChunkTasks queueChunkLightTask(final ChunkPos pos, final BooleanSupplier lightTask, final Priority priority) { + final ServerChunkTasks ret = this.chunkTasks.compute(CoordinateUtils.getChunkKey(pos), (final long keyInMap, ServerChunkTasks valueInMap) -> { + if (valueInMap == null) { + valueInMap = new ServerChunkTasks( @@ -21532,11 +22445,11 @@ index 0000000000000000000000000000000000000000..c64ab41198a5e0c7cbcbe6452af11f82 + + public ServerChunkTasks(final long chunkCoordinate, final StarLightInterface lightEngine, + final ServerLightQueue queue) { -+ this(chunkCoordinate, lightEngine, queue, PrioritisedExecutor.Priority.NORMAL); ++ this(chunkCoordinate, lightEngine, queue, Priority.NORMAL); + } + + public ServerChunkTasks(final long chunkCoordinate, final StarLightInterface lightEngine, -+ final ServerLightQueue queue, final PrioritisedExecutor.Priority priority) { ++ final ServerLightQueue queue, final Priority priority) { + super(chunkCoordinate, lightEngine, queue); + this.task = ((ChunkSystemServerLevel)(ServerLevel)lightEngine.getWorld()).moonrise$getChunkTaskScheduler().radiusAwareScheduler.createTask( + CoordinateUtils.getChunkX(chunkCoordinate), CoordinateUtils.getChunkZ(chunkCoordinate), @@ -21556,19 +22469,19 @@ index 0000000000000000000000000000000000000000..c64ab41198a5e0c7cbcbe6452af11f82 + return this.task.cancel(); + } + -+ public PrioritisedExecutor.Priority getPriority() { ++ public Priority getPriority() { + return this.task.getPriority(); + } + -+ public void lowerPriority(final PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(final Priority priority) { + this.task.lowerPriority(priority); + } + -+ public void setPriority(final PrioritisedExecutor.Priority priority) { ++ public void setPriority(final Priority priority) { + this.task.setPriority(priority); + } + -+ public void raisePriority(final PrioritisedExecutor.Priority priority) { ++ public void raisePriority(final Priority priority) { + this.task.raisePriority(priority); + } + @@ -21616,12 +22529,31 @@ index 0000000000000000000000000000000000000000..7fe59ab70557aa6a484a02db2b2007fd + } + +} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/storage/StarlightSectionData.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/storage/StarlightSectionData.java +new file mode 100644 +index 0000000000000000000000000000000000000000..40d004afdc6449530f5bb2d7c7638b8ee3e3a577 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/storage/StarlightSectionData.java +@@ -0,0 +1,13 @@ ++package ca.spottedleaf.moonrise.patches.starlight.storage; ++ ++public interface StarlightSectionData { ++ ++ public int starlight$getBlockLightState(); ++ ++ public void starlight$setBlockLightState(final int state); ++ ++ public int starlight$getSkyLightState(); ++ ++ public void starlight$setSkyLightState(final int state); ++ ++} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/util/SaveUtil.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/util/SaveUtil.java new file mode 100644 -index 0000000000000000000000000000000000000000..57692a503e147a00ac4e1586cd78e12b71a80d3f +index 0000000000000000000000000000000000000000..689ce367164e79e0426eeecb81dbbc521d4bc742 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/util/SaveUtil.java -@@ -0,0 +1,188 @@ +@@ -0,0 +1,189 @@ +package ca.spottedleaf.moonrise.patches.starlight.util; + +import ca.spottedleaf.moonrise.common.util.WorldUtil; @@ -21638,19 +22570,20 @@ index 0000000000000000000000000000000000000000..57692a503e147a00ac4e1586cd78e12b +import net.minecraft.world.level.chunk.status.ChunkStatus; +import org.slf4j.Logger; + ++// note: keep in-sync with SerializableChunkDataMixin +public final class SaveUtil { + + private static final Logger LOGGER = LogUtils.getLogger(); + -+ private static final int STARLIGHT_LIGHT_VERSION = 9; ++ public static final int STARLIGHT_LIGHT_VERSION = 9; + + public static int getLightVersion() { + return STARLIGHT_LIGHT_VERSION; + } + -+ private static final String BLOCKLIGHT_STATE_TAG = "starlight.blocklight_state"; -+ private static final String SKYLIGHT_STATE_TAG = "starlight.skylight_state"; -+ private static final String STARLIGHT_VERSION_TAG = "starlight.light_version"; ++ public static final String BLOCKLIGHT_STATE_TAG = "starlight.blocklight_state"; ++ public static final String SKYLIGHT_STATE_TAG = "starlight.skylight_state"; ++ public static final String STARLIGHT_VERSION_TAG = "starlight.light_version"; + + public static void saveLightHook(final Level world, final ChunkAccess chunk, final CompoundTag nbt) { + try { @@ -22229,83 +23162,30 @@ index 0000000000000000000000000000000000000000..85950a1aa732ab8c01ad28bec9e0de14 + } +} diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index b3f3408a986ae513c06e3b16b82e1c80d4604cd2..9bd509915b391e9d382fe47798e2c345b6e59a9a 100644 +index 36b96e0ed5c0d25068ec4678eddd8a19a020d345..b59613e3d97a9ca7d11bda28508021a5e9a9e92f 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -30,6 +30,45 @@ public class GlobalConfiguration extends ConfigurationPart { - public static GlobalConfiguration get() { - return instance; - } -+ -+ public ChunkLoadingBasic chunkLoadingBasic; -+ -+ public class ChunkLoadingBasic extends ConfigurationPart { -+ @Comment("The maximum rate in chunks per second that the server will send to any individual player. Set to -1 to disable this limit.") -+ public double playerMaxChunkSendRate = 75.0; -+ -+ @Comment( -+ "The maximum rate at which chunks will load for any individual player. " + -+ "Note that this setting also affects chunk generations, since a chunk load is always first issued to test if a" + -+ "chunk is already generated. Set to -1 to disable this limit." -+ ) -+ public double playerMaxChunkLoadRate = 100.0; -+ -+ @Comment("The maximum rate at which chunks will generate for any individual player. Set to -1 to disable this limit.") -+ public double playerMaxChunkGenerateRate = -1.0; -+ } -+ -+ public ChunkLoadingAdvanced chunkLoadingAdvanced; -+ -+ public class ChunkLoadingAdvanced extends ConfigurationPart { -+ @Comment( -+ "Set to true if the server will match the chunk send radius that clients have configured" + -+ "in their view distance settings if the client is less-than the server's send distance." -+ ) -+ public boolean autoConfigSendDistance = true; -+ -+ @Comment( -+ "Specifies the maximum amount of concurrent chunk loads that an individual player can have." + -+ "Set to 0 to let the server configure it automatically per player, or set it to -1 to disable the limit." -+ ) -+ public int playerMaxConcurrentChunkLoads = 0; -+ -+ @Comment( -+ "Specifies the maximum amount of concurrent chunk generations that an individual player can have." + -+ "Set to 0 to let the server configure it automatically per player, or set it to -1 to disable the limit." -+ ) -+ public int playerMaxConcurrentChunkGenerates = 0; -+ } - static void set(GlobalConfiguration instance) { - GlobalConfiguration.instance = instance; - } -@@ -145,21 +184,6 @@ public class GlobalConfiguration extends ConfigurationPart { - public int incomingPacketThreshold = 300; - } - -- public ChunkLoading chunkLoading; -- -- public class ChunkLoading extends ConfigurationPart { -- public int minLoadRadius = 2; -- public int maxConcurrentSends = 2; -- public boolean autoconfigSendDistance = true; -- public double targetPlayerChunkSendRate = 100.0; -- public double globalMaxChunkSendRate = -1.0; -- public boolean enableFrustumPriority = false; -- public double globalMaxChunkLoadRate = -1.0; -- public double playerMaxConcurrentLoads = 20.0; -- public double globalMaxConcurrentLoads = 500.0; -- public double playerMaxChunkLoadRate = -1.0; -- } -- - public UnsupportedSettings unsupportedSettings; - - public class UnsupportedSettings extends ConfigurationPart { -@@ -218,7 +242,7 @@ public class GlobalConfiguration extends ConfigurationPart { - +@@ -243,6 +243,23 @@ public class GlobalConfiguration extends ConfigurationPart { @PostProcess private void postProcess() { -- //io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.init(this); -+ ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.init(this); + ca.spottedleaf.moonrise.common.util.MoonriseCommon.adjustWorkerThreads(this.workerThreads, this.ioThreads); ++ ++ String newChunkSystemGenParallelism = this.genParallelism; ++ if (newChunkSystemGenParallelism.equalsIgnoreCase("default")) { ++ newChunkSystemGenParallelism = "true"; ++ } ++ ++ boolean useParallelGen; ++ if (newChunkSystemGenParallelism.equalsIgnoreCase("on") || newChunkSystemGenParallelism.equalsIgnoreCase("enabled") ++ || newChunkSystemGenParallelism.equalsIgnoreCase("true")) { ++ useParallelGen = true; ++ } else if (newChunkSystemGenParallelism.equalsIgnoreCase("off") || newChunkSystemGenParallelism.equalsIgnoreCase("disabled") ++ || newChunkSystemGenParallelism.equalsIgnoreCase("false")) { ++ useParallelGen = false; ++ } else { ++ throw new IllegalStateException("Invalid option for gen-parallelism: must be one of [on, off, enabled, disabled, true, false, default]"); ++ } ++ ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.init(useParallelGen); } } @@ -22434,6 +23314,38 @@ index 3fde5abde736b2c19d8819d9aec0397a0245ccd1..6548302d4983bf48cc6bc2b7f4833dc7 + } + // Paper end - optimise collisions } +diff --git a/src/main/java/net/minecraft/core/MappedRegistry.java b/src/main/java/net/minecraft/core/MappedRegistry.java +index 71e04e5c1bc0722abf8ca2e0738bd60b6d7ae21c..8e0dfaf02343d74ce786e4fc647bc4c1d73c0014 100644 +--- a/src/main/java/net/minecraft/core/MappedRegistry.java ++++ b/src/main/java/net/minecraft/core/MappedRegistry.java +@@ -50,6 +50,19 @@ public class MappedRegistry implements WritableRegistry { + return this.getTags(); + } + ++ // Paper start - fluid method optimisations ++ private void injectFluidRegister( ++ final ResourceKey resourceKey, ++ final T object ++ ) { ++ if (resourceKey.registryKey() == (Object)net.minecraft.core.registries.Registries.FLUID) { ++ for (final net.minecraft.world.level.material.FluidState possibleState : ((net.minecraft.world.level.material.Fluid)object).getStateDefinition().getPossibleStates()) { ++ ((ca.spottedleaf.moonrise.patches.fluid.FluidFluidState)(Object)possibleState).moonrise$initCaches(); ++ } ++ } ++ } ++ // Paper end - fluid method optimisations ++ + public MappedRegistry(ResourceKey> key, Lifecycle lifecycle) { + this(key, lifecycle, false); + } +@@ -114,6 +127,7 @@ public class MappedRegistry implements WritableRegistry { + this.toId.put(value, i); + this.registrationInfos.put(key, info); + this.registryLifecycle = this.registryLifecycle.add(info.lifecycle()); ++ this.injectFluidRegister(key, value); // Paper - fluid method optimisations + return reference; + } + } diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java index fc6ce3485dc890f5105a37fe3e344a1460867556..e114e687f2f4503546687fd6792226a643af8793 100644 --- a/src/main/java/net/minecraft/server/Main.java @@ -22447,7 +23359,7 @@ index fc6ce3485dc890f5105a37fe3e344a1460867556..e114e687f2f4503546687fd6792226a6 DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, worldLoader.get(), thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), services, LoggerChunkProgressListener::createFromGameruleRadius); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 53c9be615a0f2939cd989e24e304e81e6e27f39d..7c388e230c4a88edf6212dd8990e8238d3265ebf 100644 +index 53c9be615a0f2939cd989e24e304e81e6e27f39d..8a66012b7f2396031840c8c718f49f8aab716ee0 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -205,7 +205,7 @@ import org.bukkit.event.server.ServerLoadEvent; @@ -22606,15 +23518,22 @@ index 53c9be615a0f2939cd989e24e304e81e6e27f39d..7c388e230c4a88edf6212dd8990e8238 this.isSaving = false; this.resources.close(); -@@ -1042,6 +1106,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { return false; } : this::haveTime); @@ -22628,7 +23547,7 @@ index 53c9be615a0f2939cd989e24e304e81e6e27f39d..7c388e230c4a88edf6212dd8990e8238 this.tickFrame.end(); gameprofilerfiller.popPush("nextTickWait"); this.mayHaveDelayedTasks = true; -@@ -1428,6 +1500,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> read(final ChunkPos pos) { @@ -23992,11 +24911,12 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..60adb0caf3d6f03a57fc553038520701 + @Override + public void flushWorker() { + ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.flush(); - } ++ } + // Paper end - rewrite chunk system - ++ @Nullable public LevelChunk getChunkToSend(long pos) { + ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos); @@ -1061,7 +645,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } @@ -24152,7 +25072,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..60adb0caf3d6f03a57fc553038520701 playerchunkmap_entitytracker.updatePlayers(this.level.players()); if (entity instanceof ServerPlayer) { ServerPlayer entityplayer = (ServerPlayer) entity; -@@ -1362,16 +905,49 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1362,16 +905,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider playerchunkmap_entitytracker1.broadcastRemoved(); } @@ -24163,7 +25083,6 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..60adb0caf3d6f03a57fc553038520701 - Iterator iterator = this.playerMap.getAllPlayers().iterator(); + // Paper start - optimise entity tracker + private void newTrackerTick() { -+ final ca.spottedleaf.moonrise.common.misc.NearbyPlayers nearbyPlayers = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getNearbyPlayers(); + final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup entityLookup = (ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup)((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getEntityLookup();; - while (iterator.hasNext()) { @@ -24176,38 +25095,28 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..60adb0caf3d6f03a57fc553038520701 + if (tracker == null) { + continue; + } -+ ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity)tracker).moonrise$tick(nearbyPlayers.getChunk(entity.chunkPosition())); -+ tracker.serverEntity.sendChanges(); -+ } -+ -+ // process unloads -+ final ca.spottedleaf.moonrise.common.list.ReferenceList unloadedEntities = entityLookup.trackerUnloadedEntities; -+ final Entity[] unloadedEntitiesRaw = java.util.Arrays.copyOf(unloadedEntities.getRawDataUnchecked(), unloadedEntities.size()); -+ unloadedEntities.clear(); - -- this.updateChunkTracking(entityplayer); -+ for (final Entity entity : unloadedEntitiesRaw) { -+ final ChunkMap.TrackedEntity tracker = ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$getTrackedEntity(); -+ if (tracker == null) { -+ continue; ++ ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity)tracker).moonrise$tick(((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)entity).moonrise$getChunkData().nearbyPlayers); ++ if (((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity)tracker).moonrise$hasPlayers() ++ || ((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)entity).moonrise$getChunkStatus().isOrAfter(FullChunkStatus.ENTITY_TICKING)) { ++ tracker.serverEntity.sendChanges(); + } -+ ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity)tracker).moonrise$clearPlayers(); - } ++ } + } + // Paper end - optimise entity tracker -+ + +- this.updateChunkTracking(entityplayer); + protected void tick() { + // Paper start - optimise entity tracker + if (true) { + this.newTrackerTick(); + return; -+ } + } + // Paper end - optimise entity tracker + // Paper - rewrite chunk system List list = Lists.newArrayList(); List list1 = this.level.players(); -@@ -1478,27 +1054,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1478,27 +1043,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void waitForLightBeforeSending(ChunkPos centerPos, int radius) { @@ -24245,7 +25154,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..60adb0caf3d6f03a57fc553038520701 } @Nullable -@@ -1514,7 +1088,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1514,7 +1077,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } } @@ -24254,7 +25163,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..60adb0caf3d6f03a57fc553038520701 public final ServerEntity serverEntity; final Entity entity; -@@ -1522,6 +1096,84 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1522,6 +1085,89 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider SectionPos lastSectionPos; public final Set seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl @@ -24334,11 +25243,51 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..60adb0caf3d6f03a57fc553038520701 + this.removePlayer(player); + } + } ++ ++ @Override ++ public final boolean moonrise$hasPlayers() { ++ return !this.seenBy.isEmpty(); ++ } + // Paper end - optimise entity tracker + public TrackedEntity(final Entity entity, final int i, final int j, final boolean flag) { this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit this.entity = entity; +@@ -1610,20 +1256,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + } + + private int getEffectiveRange() { +- int i = this.range; +- Iterator iterator = this.entity.getIndirectPassengers().iterator(); ++ // Paper start - optimise entity tracker ++ final Entity entity = this.entity; ++ int range = ca.spottedleaf.moonrise.common.PlatformHooks.get().modifyEntityTrackingRange(entity, this.range); + +- while (iterator.hasNext()) { +- Entity entity = (Entity) iterator.next(); +- int j = entity.getType().clientTrackingRange() * 16; +- j = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, j); // Paper ++ if (entity.getPassengers() == ImmutableList.of()) { ++ return this.scaledRange(range); ++ } + +- if (j > i) { +- i = j; +- } ++ // note: we change to List ++ final List passengers = (List)entity.getIndirectPassengers(); ++ for (int i = 0, len = passengers.size(); i < len; ++i) { ++ final Entity passenger = passengers.get(i); ++ // note: max should be branchless ++ range = Math.max(range, ca.spottedleaf.moonrise.common.PlatformHooks.get().modifyEntityTrackingRange(passenger, passenger.getType().clientTrackingRange() << 4)); + } + +- return this.scaledRange(i); ++ return this.scaledRange(range); ++ // Paper end - optimise entity tracker + } + + public void updatePlayers(List players) { diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java index f7c2c03749d6be25bf33afd61e1da120770b3432..64da6726634fc223c0e6dcab4d83a6c8997ff196 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java @@ -25152,7 +26101,7 @@ index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a } } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815d46bff2e 100644 +index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..23a13bfd23514cde6dcf8d59ba3b43d84f266aad 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -52,7 +52,7 @@ import net.minecraft.world.level.storage.DimensionDataStorage; @@ -25164,7 +26113,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815 private static final Logger LOGGER = LogUtils.getLogger(); private final DistanceManager distanceManager; -@@ -78,6 +78,62 @@ public class ServerChunkCache extends ChunkSource { +@@ -78,6 +78,71 @@ public class ServerChunkCache extends ChunkSource { private final ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable fullChunks = new ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<>(); long chunkFutureAwaitCounter; // Paper end @@ -25189,7 +26138,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815 + final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler chunkTaskScheduler = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler(); + final CompletableFuture completable = new CompletableFuture<>(); + chunkTaskScheduler.scheduleChunkLoad( -+ chunkX, chunkZ, toStatus, true, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.BLOCKING, ++ chunkX, chunkZ, toStatus, true, ca.spottedleaf.concurrentutil.util.Priority.BLOCKING, + completable::complete + ); + @@ -25220,6 +26169,15 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815 + return ifPresent; + } + ++ final ca.spottedleaf.moonrise.common.PlatformHooks platformHooks = ca.spottedleaf.moonrise.common.PlatformHooks.get(); ++ ++ if (platformHooks.hasCurrentlyLoadingChunk() && currentChunk != null) { ++ final ChunkAccess loading = platformHooks.getCurrentlyLoadingChunk(currentChunk.vanillaChunkHolder); ++ if (loading != null && ca.spottedleaf.moonrise.common.util.TickThread.isTickThread()) { ++ return loading; ++ } ++ } ++ + return load ? this.syncLoad(chunkX, chunkZ, toStatus) : null; + } + // Paper end - rewrite chunk system @@ -25227,7 +26185,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815 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 persistentStateManagerFactory) { this.level = world; -@@ -109,13 +165,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -109,13 +174,7 @@ public class ServerChunkCache extends ChunkSource { } // CraftBukkit end // Paper start @@ -25242,7 +26200,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815 @Nullable public ChunkAccess getChunkAtImmediately(int x, int z) { -@@ -186,63 +236,25 @@ public class ServerChunkCache extends ChunkSource { +@@ -186,63 +245,42 @@ public class ServerChunkCache extends ChunkSource { @Nullable @Override public ChunkAccess getChunk(int x, int z, ChunkStatus leastStatus, boolean create) { @@ -25261,14 +26219,14 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815 - - gameprofilerfiller.incrementCounter("getChunk"); - long k = ChunkPos.asLong(x, z); -- -- for (int l = 0; l < 4; ++l) { -- if (k == this.lastChunkPos[l] && leastStatus == this.lastChunkStatus[l]) { -- ChunkAccess ichunkaccess = this.lastChunk[l]; + // Paper start - rewrite chunk system + if (leastStatus == ChunkStatus.FULL) { + final LevelChunk ret = this.fullChunks.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(x, z)); +- for (int l = 0; l < 4; ++l) { +- if (k == this.lastChunkPos[l] && leastStatus == this.lastChunkStatus[l]) { +- ChunkAccess ichunkaccess = this.lastChunk[l]; +- - if (ichunkaccess != null) { // CraftBukkit - the chunk can become accessible in the meantime TODO for non-null chunks it might also make sense to check that the chunk's state hasn't changed in the meantime - return ichunkaccess; - } @@ -25311,12 +26269,28 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815 - return null; - } else { - return this.getChunkAtIfLoadedMainThread(chunkX, chunkZ); // Paper - Perf: Optimise getChunkAt calls for loaded chunks -- } -+ return this.fullChunks.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); // Paper - rewrite chunk system ++ // Paper start - rewrite chunk system ++ final LevelChunk ret = this.fullChunks.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ if (!ca.spottedleaf.moonrise.common.PlatformHooks.get().hasCurrentlyLoadingChunk()) { ++ return ret; + } ++ ++ if (ret != null || !ca.spottedleaf.moonrise.common.util.TickThread.isTickThread()) { ++ return ret; ++ } ++ ++ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder holder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler() ++ .chunkHolderManager.getChunkHolder(chunkX, chunkZ); ++ if (holder == null) { ++ return ret; ++ } ++ ++ return ca.spottedleaf.moonrise.common.PlatformHooks.get().getCurrentlyLoadingChunk(holder.vanillaChunkHolder); ++ // Paper end - rewrite chunk system } private void clearCache() { -@@ -273,56 +285,59 @@ public class ServerChunkCache extends ChunkSource { +@@ -273,56 +311,59 @@ public class ServerChunkCache extends ChunkSource { } private CompletableFuture> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { @@ -25374,7 +26348,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815 + + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().scheduleChunkLoad( + chunkX, chunkZ, leastStatus, true, -+ ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER, ++ ca.spottedleaf.concurrentutil.util.Priority.HIGHER, + complete + ); @@ -25414,7 +26388,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815 } @Override -@@ -335,16 +350,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -335,16 +376,7 @@ public class ServerChunkCache extends ChunkSource { } public boolean runDistanceManagerUpdates() { // Paper - public @@ -25432,7 +26406,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815 } // Paper start -@@ -354,17 +360,14 @@ public class ServerChunkCache extends ChunkSource { +@@ -354,17 +386,14 @@ public class ServerChunkCache extends ChunkSource { // Paper end public boolean isPositionTicking(long pos) { @@ -25455,7 +26429,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815 try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings this.chunkMap.saveAllChunks(flush); } // Paper - Timings -@@ -377,17 +380,15 @@ public class ServerChunkCache extends ChunkSource { +@@ -377,17 +406,15 @@ public class ServerChunkCache extends ChunkSource { } public void close(boolean save) throws IOException { @@ -25476,7 +26450,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815 ProfilerFiller gameprofilerfiller = Profiler.get(); gameprofilerfiller.push("purge"); -@@ -415,6 +416,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -415,6 +442,7 @@ public class ServerChunkCache extends ChunkSource { gameprofilerfiller.popPush("chunks"); if (tickChunks) { this.level.timings.chunks.startTiming(); // Paper - timings @@ -25484,7 +26458,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815 this.tickChunks(); this.level.timings.chunks.stopTiming(); // Paper - timings this.chunkMap.tick(); -@@ -546,11 +548,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -546,11 +574,13 @@ public class ServerChunkCache extends ChunkSource { } private void getFullChunk(long pos, Consumer chunkConsumer) { @@ -25493,7 +26467,8 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815 - if (playerchunk != null) { - ((ChunkResult) playerchunk.getFullChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).ifSuccess(chunkConsumer); + // Paper start - rewrite chunk system -+ final LevelChunk fullChunk = this.getChunkNow(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkX(pos), ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkZ(pos)); ++ // note: bypass currentlyLoaded from getChunkNow ++ final LevelChunk fullChunk = this.fullChunks.get(pos); + if (fullChunk != null) { + chunkConsumer.accept(fullChunk); } @@ -25501,7 +26476,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815 } -@@ -644,6 +647,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -644,6 +674,12 @@ public class ServerChunkCache extends ChunkSource { this.chunkMap.setServerViewDistance(watchDistance); } @@ -25514,7 +26489,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..22157cbc4e4bb1e4010116bdf7429815 public void setSimulationDistance(int simulationDistance) { this.distanceManager.updateSimulationDistance(simulationDistance); } -@@ -735,21 +744,19 @@ public class ServerChunkCache extends ChunkSource { +@@ -735,21 +771,19 @@ public class ServerChunkCache extends ChunkSource { @Override // CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task public boolean pollTask() { @@ -25559,7 +26534,7 @@ index bc0f1aa61e68d2a8638d89c10bc5c71922d057f9..79c88b315481fe70f037bae834f2b072 if (!list.equals(this.lastPassengers)) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9fb00a037 100644 +index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c8319f10200 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -187,7 +187,7 @@ import org.bukkit.event.weather.LightningStrikeEvent; @@ -25634,7 +26609,9 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 + public final LevelChunk moonrise$getFullChunkIfLoaded(final int chunkX, final int chunkZ) { + return this.chunkSource.getChunkNow(chunkX, chunkZ); + } -+ + +- int requiredChunks = (maxChunkX - minChunkX + 1) * (maxChunkZ - minChunkZ + 1); +- int[] loadedChunks = new int[1]; + @Override + public final ChunkAccess moonrise$getAnyChunkIfLoaded(final int chunkX, final int chunkZ) { + final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder newChunkHolder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); @@ -25644,7 +26621,8 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 + final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder.ChunkCompletion lastCompletion = newChunkHolder.getLastChunkCompletion(); + return lastCompletion == null ? null : lastCompletion.chunk(); + } -+ + +- Long holderIdentifier = Long.valueOf(chunkProvider.chunkFutureAwaitCounter++); + @Override + public final ChunkAccess moonrise$getSpecificChunkIfLoaded(final int chunkX, final int chunkZ, final net.minecraft.world.level.chunk.status.ChunkStatus leastStatus) { + final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder newChunkHolder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkX, chunkZ); @@ -25658,20 +26636,18 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 + public final void moonrise$midTickTasks() { + ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks(); + } -+ + +- java.util.function.Consumer consumer = (net.minecraft.world.level.chunk.ChunkAccess chunk) -> { + @Override + public final ChunkAccess moonrise$syncLoadNonFull(final int chunkX, final int chunkZ, final net.minecraft.world.level.chunk.status.ChunkStatus status) { + return this.moonrise$getChunkTaskScheduler().syncLoadNonFull(chunkX, chunkZ, status); + } - -- int requiredChunks = (maxChunkX - minChunkX + 1) * (maxChunkZ - minChunkZ + 1); -- int[] loadedChunks = new int[1]; ++ + @Override + public final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler moonrise$getChunkTaskScheduler() { + return this.chunkTaskScheduler; + } - -- Long holderIdentifier = Long.valueOf(chunkProvider.chunkFutureAwaitCounter++); ++ + @Override + public final ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.ChunkDataController moonrise$getChunkDataController() { + return this.chunkDataController; @@ -25681,8 +26657,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 + public final ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.ChunkDataController moonrise$getPoiChunkDataController() { + return this.poiDataController; + } - -- java.util.function.Consumer consumer = (net.minecraft.world.level.chunk.ChunkAccess chunk) -> { ++ + @Override + public final ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.ChunkDataController moonrise$getEntityChunkDataController() { + return this.entityDataController; @@ -25798,8 +26773,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 + @Override + public final long moonrise$getLastMidTickFailure() { + return this.lastMidTickFailure; - } -- // Paper end - optimise getPlayerByUUID ++ } + + @Override + public final void moonrise$setLastMidTickFailure(final long time) { @@ -25814,7 +26788,8 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 + @Override + public final ca.spottedleaf.moonrise.common.list.ReferenceList moonrise$getLoadedChunks() { + return this.loadedChunks; -+ } + } +- // Paper end - optimise getPlayerByUUID + + @Override + public final ca.spottedleaf.moonrise.common.list.ReferenceList moonrise$getTickingChunks() { @@ -25895,16 +26870,18 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 } protected void tickTime() { -@@ -613,6 +774,63 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -613,7 +774,60 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe }); } + // Paper start - optimise random ticking ++ private final ca.spottedleaf.moonrise.common.util.SimpleRandom simpleRandom = new ca.spottedleaf.moonrise.common.util.SimpleRandom(0L); ++ + private void optimiseRandomTick(final LevelChunk chunk, final int tickSpeed) { + final LevelChunkSection[] sections = chunk.getSections(); + final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection((ServerLevel)(Object)this); -+ final RandomSource random = this.random; -+ final boolean tickFluids = false; // Paper - not configurable - MC-224294 ++ final ca.spottedleaf.moonrise.common.util.SimpleRandom simpleRandom = this.simpleRandom; ++ final boolean doubleTickFluids = !ca.spottedleaf.moonrise.common.PlatformHooks.get().configFixMC224294(); + + final ChunkPos cpos = chunk.getPos(); + final int offsetX = cpos.x << 4; @@ -25914,39 +26891,32 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 + final int offsetY = (sectionIndex + minSection) << 4; + final LevelChunkSection section = sections[sectionIndex]; + final net.minecraft.world.level.chunk.PalettedContainer states = section.states; -+ if (section == null || !section.isRandomlyTickingBlocks()) { ++ if (!section.isRandomlyTickingBlocks()) { + continue; + } + -+ final ca.spottedleaf.moonrise.common.list.IBlockDataList tickList = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$getTickingBlockList(); -+ if (tickList.size() == 0) { -+ continue; -+ } ++ final ca.spottedleaf.moonrise.common.list.ShortList tickList = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$getTickingBlockList(); + + for (int i = 0; i < tickSpeed; ++i) { + final int tickingBlocks = tickList.size(); -+ final int index = random.nextInt() & ((16 * 16 * 16) - 1); ++ final int index = simpleRandom.nextInt() & ((16 * 16 * 16) - 1); + + if (index >= tickingBlocks) { + // most of the time we fall here + continue; + } + -+ final long raw = tickList.getRaw(index); -+ final int location = ca.spottedleaf.moonrise.common.list.IBlockDataList.getLocationFromRaw(raw); -+ final int randomX = (location & 15); -+ final int randomY = ((location >>> (4 + 4)) & 255); -+ final int randomZ = ((location >>> 4) & 15); -+ final BlockState state = states.get(randomX | (randomZ << 4) | (randomY << 8)); ++ final int location = (int)tickList.getRaw(index) & 0xFFFF; ++ final BlockState state = states.get(location); + + // do not use a mutable pos, as some random tick implementations store the input without calling immutable()! -+ final BlockPos pos = new BlockPos(randomX | offsetX, randomY | offsetY, randomZ | offsetZ); ++ final BlockPos pos = new BlockPos((location & 15) | offsetX, ((location >>> (4 + 4)) & 15) | offsetY, ((location >>> 4) & 15) | offsetZ); + -+ state.randomTick((ServerLevel)(Object)this, pos, random); -+ if (tickFluids) { ++ state.randomTick((ServerLevel)(Object)this, pos, simpleRandom); ++ if (doubleTickFluids) { + final FluidState fluidState = state.getFluidState(); + if (fluidState.isRandomlyTicking()) { -+ fluidState.randomTick((ServerLevel)(Object)this, pos, random); ++ fluidState.randomTick((ServerLevel)(Object)this, pos, simpleRandom); + } + } + } @@ -25957,9 +26927,29 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 + // Paper end - optimise random ticking + public void tickChunk(LevelChunk chunk, int randomTickSpeed) { ++ final ca.spottedleaf.moonrise.common.util.SimpleRandom simpleRandom = this.simpleRandom; // Paper - optimise random ticking ChunkPos chunkcoordintpair = chunk.getPos(); boolean flag = this.isRaining(); -@@ -662,35 +880,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + int j = chunkcoordintpair.getMinBlockX(); +@@ -621,7 +835,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + ProfilerFiller gameprofilerfiller = Profiler.get(); + + gameprofilerfiller.push("thunder"); +- if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - Option to disable thunder ++ if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && simpleRandom.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - Option to disable thunder // Paper - optimise random ticking + BlockPos blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15)); + + if (this.isRainingAt(blockposition)) { +@@ -653,7 +867,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + + if (!this.paperConfig().environment.disableIceAndSnow) { // Paper - Option to disable ice and snow + for (int l = 0; l < randomTickSpeed; ++l) { +- if (this.random.nextInt(48) == 0) { ++ if (simpleRandom.nextInt(48) == 0) { // Paper - optimise random ticking + this.tickPrecipitation(this.getBlockRandomPos(j, 0, k, 15)); + } + } +@@ -662,35 +876,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe gameprofilerfiller.popPush("tickBlocks"); timings.chunkTicksBlocks.startTiming(); // Paper if (randomTickSpeed > 0) { @@ -25996,7 +26986,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 } timings.chunkTicksBlocks.stopTiming(); // Paper -@@ -964,6 +1154,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -964,6 +1150,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (fluid1.is(fluid)) { fluid1.tick(this, pos, iblockdata); } @@ -26008,7 +26998,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 } -@@ -973,6 +1168,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -973,6 +1164,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (iblockdata.is(block)) { iblockdata.tick(this, pos, this.random); } @@ -26020,7 +27010,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 } -@@ -1049,6 +1249,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1049,6 +1245,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } public void save(@Nullable ProgressListener progressListener, boolean flush, boolean savingDisabled) { @@ -26032,7 +27022,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 ServerChunkCache chunkproviderserver = this.getChunkSource(); if (!savingDisabled) { -@@ -1064,16 +1269,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1064,16 +1265,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } timings.worldSaveChunks.startTiming(); // Paper @@ -26060,7 +27050,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 // CraftBukkit start - moved from MinecraftServer.saveChunks ServerLevel worldserver1 = this; -@@ -1213,7 +1423,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1213,7 +1419,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.removePlayerImmediately((ServerPlayer) entity, Entity.RemovalReason.DISCARDED); } @@ -26069,7 +27059,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 } // CraftBukkit start -@@ -1243,7 +1453,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1243,7 +1449,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } // CraftBukkit end @@ -26078,7 +27068,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 } } -@@ -1254,11 +1464,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1254,11 +1460,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public boolean tryAddFreshEntityWithPassengers(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { // CraftBukkit end @@ -26091,7 +27081,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 return false; } else { this.addFreshEntityWithPassengers(entity, reason); // CraftBukkit -@@ -1891,7 +2097,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1891,7 +2093,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } } @@ -26100,7 +27090,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 bufferedwriter.write(String.format(Locale.ROOT, "block_entity_tickers: %d\n", this.blockEntityTickers.size())); bufferedwriter.write(String.format(Locale.ROOT, "block_ticks: %d\n", this.getBlockTicks().count())); bufferedwriter.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count())); -@@ -1940,7 +2146,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1940,7 +2142,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe BufferedWriter bufferedwriter2 = Files.newBufferedWriter(path1); try { @@ -26109,7 +27099,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 } catch (Throwable throwable4) { if (bufferedwriter2 != null) { try { -@@ -1961,7 +2167,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1961,7 +2163,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe BufferedWriter bufferedwriter3 = Files.newBufferedWriter(path2); try { @@ -26118,7 +27108,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 } catch (Throwable throwable6) { if (bufferedwriter3 != null) { try { -@@ -2103,7 +2309,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2103,7 +2305,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @VisibleForTesting public String getWatchdogStats() { @@ -26127,7 +27117,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString(); }), this.blockEntityTickers.size(), ServerLevel.getTypeCount(this.blockEntityTickers, TickingBlockEntity::getType), this.getBlockTicks().count(), this.getFluidTicks().count(), this.gatherChunkSourceStats()); } -@@ -2133,15 +2339,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2133,15 +2335,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public LevelEntityGetter getEntities() { org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot @@ -26156,7 +27146,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 } public void startTickingChunk(LevelChunk chunk) { -@@ -2161,34 +2377,47 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2161,34 +2373,47 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public void close() throws IOException { super.close(); @@ -26211,7 +27201,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..af27a004f618912d6a5f1d2c82c8e7e9 } @Override -@@ -2234,7 +2463,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2234,7 +2459,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report); crashreportsystemdetails.setDetail("Loaded entity count", () -> { @@ -26715,8 +27705,21 @@ index cdd66e6ce96e2613afe7f06ca8da3cfaa6704b2d..32634e45ac8433648e49e47e20081e15 handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), null, null)); // Paper start - PlayerChunkLoadEvent if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) { +diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java +index 4fe3024e26b56c2d796acf703a1bc200ff309f09..7529b3d90e65036c7bf869af30475932d547b3ab 100644 +--- a/src/main/java/net/minecraft/server/players/PlayerList.java ++++ b/src/main/java/net/minecraft/server/players/PlayerList.java +@@ -1407,7 +1407,7 @@ public abstract class PlayerList { + + public void setViewDistance(int viewDistance) { + this.viewDistance = viewDistance; +- this.broadcastAll(new ClientboundSetChunkCacheRadiusPacket(viewDistance)); ++ //this.broadcastAll(new ClientboundSetChunkCacheRadiusPacket(viewDistance)); // Paper - rewrite chunk system + Iterator iterator = this.server.getAllLevels().iterator(); + + while (iterator.hasNext()) { diff --git a/src/main/java/net/minecraft/util/BitStorage.java b/src/main/java/net/minecraft/util/BitStorage.java -index 68648c5a5e3ff079f832092af0f2f801c42d1ede..19661e106612b8e4e152085fb398db7bd06acc23 100644 +index 68648c5a5e3ff079f832092af0f2f801c42d1ede..e4e153cb8899e70273aa150b8ea26907cf68b15c 100644 --- a/src/main/java/net/minecraft/util/BitStorage.java +++ b/src/main/java/net/minecraft/util/BitStorage.java @@ -2,7 +2,7 @@ package net.minecraft.util; @@ -26736,60 +27739,234 @@ index 68648c5a5e3ff079f832092af0f2f801c42d1ede..19661e106612b8e4e152085fb398db7b + // Paper start - block counting + // provide default impl in case mods implement this... + @Override -+ public default it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { -+ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(); ++ public default it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { ++ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(); + + final int size = this.getSize(); + for (int index = 0; index < size; ++index) { + final int paletteIdx = this.get(index); + ret.computeIfAbsent(paletteIdx, (final int key) -> { -+ return new it.unimi.dsi.fastutil.ints.IntArrayList(); -+ }).add(index); ++ return new it.unimi.dsi.fastutil.shorts.ShortArrayList(); ++ }).add((short)index); + } + + return ret; + } + // Paper end - block counting } +diff --git a/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java b/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java +index 61dee55417bc802e25b9ba2f271d32d8c12844a9..a8a260a3caaa8e5004069b833ecc8b17b2fc8db5 100644 +--- a/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java ++++ b/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java +@@ -7,7 +7,7 @@ import java.util.Iterator; + import javax.annotation.Nullable; + import net.minecraft.core.IdMap; + +-public class CrudeIncrementalIntIdentityHashBiMap implements IdMap { ++public class CrudeIncrementalIntIdentityHashBiMap implements IdMap, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Paper - optimise palette reads + private static final int NOT_FOUND = -1; + private static final Object EMPTY_SLOT = null; + private static final float LOADFACTOR = 0.8F; +@@ -17,6 +17,16 @@ public class CrudeIncrementalIntIdentityHashBiMap implements IdMap { + private int nextId; + private int size; + ++ // Paper start - optimise palette reads ++ private ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData reference; ++ ++ @Override ++ public final K[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData src) { ++ this.reference = src; ++ return this.byId; ++ } ++ // Paper end - optimise palette reads ++ + private CrudeIncrementalIntIdentityHashBiMap(int size) { + this.keys = (K[])(new Object[size]); + this.values = new int[size]; +@@ -88,6 +98,12 @@ public class CrudeIncrementalIntIdentityHashBiMap implements IdMap { + this.byId = crudeIncrementalIntIdentityHashBiMap.byId; + this.nextId = crudeIncrementalIntIdentityHashBiMap.nextId; + this.size = crudeIncrementalIntIdentityHashBiMap.size; ++ // Paper start - optimise palette reads ++ final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData ref = this.reference; ++ if (ref != null) { ++ ref.moonrise$setPalette(this.byId); ++ } ++ // Paper end - optimise palette reads + } + + public void addMapping(K value, int id) { diff --git a/src/main/java/net/minecraft/util/SimpleBitStorage.java b/src/main/java/net/minecraft/util/SimpleBitStorage.java -index 9f438d9c6eb05e43d24e4af68188a3d4c46a938c..8acf2f2491a8d9d13392c5e89b2bd5c9918285e1 100644 +index 9f438d9c6eb05e43d24e4af68188a3d4c46a938c..d99ec470b4653beab630999a5b2c1a6428b20c38 100644 --- a/src/main/java/net/minecraft/util/SimpleBitStorage.java +++ b/src/main/java/net/minecraft/util/SimpleBitStorage.java -@@ -362,6 +362,40 @@ public class SimpleBitStorage implements BitStorage { +@@ -208,6 +208,20 @@ public class SimpleBitStorage implements BitStorage { + private final int divideAdd; private final long divideAddUnsigned; // Paper - Perf: Optimize SimpleBitStorage + private final int divideShift; + ++ // Paper start - optimise bitstorage read/write operations ++ private static final int[] BETTER_MAGIC = new int[33]; ++ static { ++ // 20 bits of precision ++ // since index is always [0, 4095] (i.e 12 bits), multiplication by a magic value here (20 bits) ++ // fits exactly in an int and allows us to use integer arithmetic ++ for (int bits = 1; bits < BETTER_MAGIC.length; ++bits) { ++ BETTER_MAGIC[bits] = (int)ca.spottedleaf.concurrentutil.util.IntegerUtil.getUnsignedDivisorMagic(64L / bits, 20); ++ } ++ } ++ private final int magic; ++ private final int mulBits; ++ // Paper end - optimise bitstorage read/write operations ++ + public SimpleBitStorage(int elementBits, int size, int[] data) { + this(elementBits, size); + int i = 0; +@@ -261,6 +275,13 @@ public class SimpleBitStorage implements BitStorage { + } else { + this.data = new long[j]; + } ++ // Paper start - optimise bitstorage read/write operations ++ this.magic = BETTER_MAGIC[this.bits]; ++ this.mulBits = (64 / this.bits) * this.bits; ++ if (this.size > 4096) { ++ throw new IllegalStateException("Size > 4096 not supported"); ++ } ++ // Paper end - optimise bitstorage read/write operations + } + + private int cellIndex(int index) { +@@ -273,31 +294,54 @@ public class SimpleBitStorage implements BitStorage { + public final int getAndSet(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage + //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage + //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper - Perf: Optimize SimpleBitStorage +- int i = this.cellIndex(index); +- long l = this.data[i]; +- int j = (index - i * this.valuesPerLong) * this.bits; +- int k = (int)(l >> j & this.mask); +- this.data[i] = l & ~(this.mask << j) | ((long)value & this.mask) << j; +- return k; ++ // Paper start - optimise bitstorage read/write operations ++ final int full = this.magic * index; // 20 bits of magic + 12 bits of index = barely int ++ final int divQ = full >>> 20; ++ final int divR = (full & 0xFFFFF) * this.mulBits >>> 20; ++ ++ final long[] dataArray = this.data; ++ ++ final long data = dataArray[divQ]; ++ final long mask = this.mask; ++ ++ final long write = data & ~(mask << divR) | ((long)value & mask) << divR; ++ ++ dataArray[divQ] = write; ++ ++ return (int)(data >>> divR & mask); ++ // Paper end - optimise bitstorage read/write operations + } + + @Override + public final void set(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage + //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage + //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper - Perf: Optimize SimpleBitStorage +- int i = this.cellIndex(index); +- long l = this.data[i]; +- int j = (index - i * this.valuesPerLong) * this.bits; +- this.data[i] = l & ~(this.mask << j) | ((long)value & this.mask) << j; ++ // Paper start - optimise bitstorage read/write operations ++ final int full = this.magic * index; // 20 bits of magic + 12 bits of index = barely int ++ final int divQ = full >>> 20; ++ final int divR = (full & 0xFFFFF) * this.mulBits >>> 20; ++ ++ final long[] dataArray = this.data; ++ ++ final long data = dataArray[divQ]; ++ final long mask = this.mask; ++ ++ final long write = data & ~(mask << divR) | ((long)value & mask) << divR; ++ ++ dataArray[divQ] = write; ++ // Paper end - optimise bitstorage read/write operations + } + + @Override + public final int get(int index) { // Paper - Perf: Optimize SimpleBitStorage + //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage +- int i = this.cellIndex(index); +- long l = this.data[i]; +- int j = (index - i * this.valuesPerLong) * this.bits; +- return (int)(l >> j & this.mask); ++ // Paper start - optimise bitstorage read/write operations ++ final int full = this.magic * index; // 20 bits of magic + 12 bits of index = barely int ++ final int divQ = full >>> 20; ++ final int divR = (full & 0xFFFFF) * this.mulBits >>> 20; ++ ++ return (int)(this.data[divQ] >>> divR & this.mask); ++ // Paper end - optimise bitstorage read/write operations + } + + @Override +@@ -362,6 +406,67 @@ public class SimpleBitStorage implements BitStorage { return new SimpleBitStorage(this.bits, this.size, (long[])this.data.clone()); } + // Paper start - block counting + @Override -+ public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { ++ public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { + final int valuesPerLong = this.valuesPerLong; + final int bits = this.bits; -+ final long mask = this.mask; ++ final long mask = (1L << bits) - 1L; + final int size = this.size; + -+ // we may be backed by global palette, so limit bits for init capacity -+ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>( -+ 1 << Math.min(6, bits) -+ ); ++ if (bits <= 6) { ++ final it.unimi.dsi.fastutil.shorts.ShortArrayList[] byId = new it.unimi.dsi.fastutil.shorts.ShortArrayList[1 << bits]; ++ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1 << bits); ++ ++ int index = 0; ++ ++ for (long value : this.data) { ++ int li = 0; ++ do { ++ final int paletteIdx = (int)(value & mask); ++ value >>= bits; ++ ++li; + -+ int index = 0; ++ final it.unimi.dsi.fastutil.shorts.ShortArrayList coords = byId[paletteIdx]; ++ if (coords != null) { ++ coords.add((short)index++); ++ continue; ++ } else { ++ final it.unimi.dsi.fastutil.shorts.ShortArrayList newCoords = new it.unimi.dsi.fastutil.shorts.ShortArrayList(64); ++ byId[paletteIdx] = newCoords; ++ newCoords.add((short)index++); ++ ret.put(paletteIdx, newCoords); ++ continue; ++ } ++ } while (li < valuesPerLong && index < size); ++ } ++ ++ return ret; ++ } else { ++ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>( ++ 1 << 6 ++ ); + -+ for (long value : this.data) { -+ int li = 0; -+ do { -+ final int paletteIdx = (int)(value & mask); -+ value >>= bits; ++ int index = 0; + -+ ret.computeIfAbsent(paletteIdx, (final int key) -> { -+ return new it.unimi.dsi.fastutil.ints.IntArrayList(); -+ }).add(index); ++ for (long value : this.data) { ++ int li = 0; ++ do { ++ final int paletteIdx = (int)(value & mask); ++ value >>= bits; ++ ++li; + -+ ++li; -+ ++index; -+ } while (li < valuesPerLong && index < size); -+ } ++ ret.computeIfAbsent(paletteIdx, (final int key) -> { ++ return new it.unimi.dsi.fastutil.shorts.ShortArrayList(64); ++ }).add((short)index++); ++ } while (li < valuesPerLong && index < size); ++ } + -+ return ret; ++ return ret; ++ } + } + // Paper end - block counting + @@ -26892,7 +28069,7 @@ index ea72dcb064a35bc6245bc5c94d592efedd8faf41..87ee8e51dfa7657ed7d83fcbceef48bf this.comparator = comparator; if (initialCapacity < 0) { diff --git a/src/main/java/net/minecraft/util/ZeroBitStorage.java b/src/main/java/net/minecraft/util/ZeroBitStorage.java -index 50040c497a819cd1229042ab3cb057d34a32cacc..15c5164d0ef41a978c16ee317fa73e97f2480207 100644 +index 50040c497a819cd1229042ab3cb057d34a32cacc..1f9c436a632e4f110be61cf76fcfc3b7eb80334e 100644 --- a/src/main/java/net/minecraft/util/ZeroBitStorage.java +++ b/src/main/java/net/minecraft/util/ZeroBitStorage.java @@ -62,4 +62,22 @@ public class ZeroBitStorage implements BitStorage { @@ -26902,24 +28079,24 @@ index 50040c497a819cd1229042ab3cb057d34a32cacc..15c5164d0ef41a978c16ee317fa73e97 + + // Paper start - block counting + @Override -+ public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { ++ public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { + final int size = this.size; + -+ final int[] raw = new int[size]; ++ final short[] raw = new short[size]; + for (int i = 0; i < size; ++i) { -+ raw[i] = i; ++ raw[i] = (short)i; + } + -+ final it.unimi.dsi.fastutil.ints.IntArrayList coordinates = it.unimi.dsi.fastutil.ints.IntArrayList.wrap(raw, size); ++ final it.unimi.dsi.fastutil.shorts.ShortArrayList coordinates = it.unimi.dsi.fastutil.shorts.ShortArrayList.wrap(raw, size); + -+ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1); ++ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1); + ret.put(0, coordinates); + return ret; + } + // Paper end - block counting } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 8cdef637f6343119fc77f87e7478ee23e9b8efab..5410a0380c44629f1c9b4f0a8e6017cfc5a31a89 100644 +index 8cdef637f6343119fc77f87e7478ee23e9b8efab..a3b0363fbc207ed9edc8a4d6619b6fff9389a9c7 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -175,7 +175,7 @@ import org.bukkit.event.player.PlayerTeleportEvent; @@ -26931,13 +28108,14 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..5410a0380c44629f1c9b4f0a8e6017cf // CraftBukkit start private static final int CURRENT_LEVEL = 2; -@@ -445,6 +445,97 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -445,6 +445,156 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this.dimensions.makeBoundingBox(x, y, z); } // Paper end + // Paper start - rewrite chunk system + private final boolean isHardColliding = this.moonrise$isHardCollidingUncached(); + private net.minecraft.server.level.FullChunkStatus chunkStatus; ++ private ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData chunkData; + private int sectionX = Integer.MIN_VALUE; + private int sectionY = Integer.MIN_VALUE; + private int sectionZ = Integer.MIN_VALUE; @@ -26959,6 +28137,16 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..5410a0380c44629f1c9b4f0a8e6017cf + } + + @Override ++ public final ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData moonrise$getChunkData() { ++ return this.chunkData; ++ } ++ ++ @Override ++ public final void moonrise$setChunkData(final ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData chunkData) { ++ this.chunkData = chunkData; ++ } ++ ++ @Override + public final int moonrise$getSectionX() { + return this.sectionX; + } @@ -27006,6 +28194,54 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..5410a0380c44629f1c9b4f0a8e6017cf + return this.getIndirectPassengersStream().anyMatch((entity) -> entity instanceof Player); + } + // Paper end - rewrite chunk system ++ // Paper start - optimise collisions ++ private static float[] calculateStepHeights(final AABB box, final List voxels, final List aabbs, final float stepHeight, ++ final float collidedY) { ++ final FloatArraySet ret = new FloatArraySet(); ++ ++ for (int i = 0, len = voxels.size(); i < len; ++i) { ++ final VoxelShape shape = voxels.get(i); ++ ++ final double[] yCoords = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$rootCoordinatesY(); ++ final double yOffset = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$offsetY(); ++ ++ for (final double yUnoffset : yCoords) { ++ final double y = yUnoffset + yOffset; ++ ++ final float step = (float)(y - box.minY); ++ ++ if (step > stepHeight) { ++ break; ++ } ++ ++ if (step < 0.0f || !(step != collidedY)) { ++ continue; ++ } ++ ++ ret.add(step); ++ } ++ } ++ ++ for (int i = 0, len = aabbs.size(); i < len; ++i) { ++ final AABB shape = aabbs.get(i); ++ ++ final float step1 = (float)(shape.minY - box.minY); ++ final float step2 = (float)(shape.maxY - box.minY); ++ ++ if (!(step1 < 0.0f) && step1 != collidedY && !(step1 > stepHeight)) { ++ ret.add(step1); ++ } ++ ++ if (!(step2 < 0.0f) && step2 != collidedY && !(step2 > stepHeight)) { ++ ret.add(step2); ++ } ++ } ++ ++ final float[] steps = ret.toFloatArray(); ++ FloatArrays.unstableSort(steps); ++ return steps; ++ } ++ // Paper end - optimise collisions + // Paper start - optimise entity tracker + private net.minecraft.server.level.ChunkMap.TrackedEntity trackedEntity; + @@ -27029,7 +28265,7 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..5410a0380c44629f1c9b4f0a8e6017cf public Entity(EntityType type, Level world) { this.id = Entity.ENTITY_COUNTER.incrementAndGet(); -@@ -1303,41 +1394,82 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1303,41 +1453,76 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } private Vec3 collide(Vec3 movement) { @@ -27061,85 +28297,80 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..5410a0380c44629f1c9b4f0a8e6017cf - float[] afloat = Entity.collectCandidateStepUpHeights(axisalignedbb1, list1, this.maxUpStep(), f); - float[] afloat1 = afloat; - int i = afloat.length; -+ final Level world = this.level; -+ final AABB currBoundingBox = this.getBoundingBox(); ++ final AABB currentBox = this.getBoundingBox(); - for (int j = 0; j < i; ++j) { - float f1 = afloat1[j]; - Vec3 vec3d2 = Entity.collideWithShapes(new Vec3(movement.x, (double) f1, movement.z), axisalignedbb1, list1); -+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(currBoundingBox)) { -+ return movement; -+ } - -- if (vec3d2.horizontalDistanceSqr() > vec3d1.horizontalDistanceSqr()) { -- double d0 = axisalignedbb.minY - axisalignedbb1.minY; -+ final List potentialCollisionsBB = new ArrayList<>(); + final List potentialCollisionsVoxel = new ArrayList<>(); -+ final double stepHeight = (double)this.maxUpStep(); -+ final AABB collisionBox; -+ final boolean onGround = this.onGround; ++ final List potentialCollisionsBB = new ArrayList<>(); -- return vec3d2.add(0.0D, -d0, 0.0D); -+ if (xZero & zZero) { -+ if (movement.y > 0.0) { -+ collisionBox = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutUpwards(currBoundingBox, movement.y); -+ } else { -+ collisionBox = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutDownwards(currBoundingBox, movement.y); -+ } -+ } else { -+ // note: xZero == false or zZero == false -+ if (stepHeight > 0.0 && (onGround || (movement.y < 0.0))) { -+ // don't bother getting the collisions if we don't need them. -+ if (movement.y <= 0.0) { -+ collisionBox = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.expandUpwards(currBoundingBox.expandTowards(movement.x, movement.y, movement.z), stepHeight); -+ } else { -+ collisionBox = currBoundingBox.expandTowards(movement.x, Math.max(stepHeight, movement.y), movement.z); - } -+ } else { -+ collisionBox = currBoundingBox.expandTowards(movement.x, movement.y, movement.z); - } - } +- if (vec3d2.horizontalDistanceSqr() > vec3d1.horizontalDistanceSqr()) { +- double d0 = axisalignedbb.minY - axisalignedbb1.minY; ++ final AABB initialCollisionBox; ++ if (xZero & zZero) { ++ // note: xZero & zZero -> collision on x/z == 0 -> no step height calculation ++ // this specifically optimises entities standing still ++ initialCollisionBox = movement.y < 0.0 ? ++ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutDownwards(currentBox, movement.y) : ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutUpwards(currentBox, movement.y); ++ } else { ++ initialCollisionBox = currentBox.expandTowards(movement); ++ } -- return vec3d1; -+ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisions( -+ world, (Entity)(Object)this, collisionBox, potentialCollisionsVoxel, potentialCollisionsBB, -+ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_BORDER, -+ null, null +- return vec3d2.add(0.0D, -d0, 0.0D); +- } ++ final List entityAABBs = new ArrayList<>(); ++ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getEntityHardCollisions( ++ this.level, (Entity)(Object)this, initialCollisionBox, entityAABBs, 0, null + ); + -+ if (potentialCollisionsVoxel.isEmpty() && potentialCollisionsBB.isEmpty()) { -+ return movement; -+ } -+ -+ final Vec3 limitedMoveVector = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(movement, currBoundingBox, potentialCollisionsVoxel, potentialCollisionsBB); ++ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisionsForBlocksOrWorldBorder( ++ this.level, (Entity)(Object)this, initialCollisionBox, potentialCollisionsVoxel, potentialCollisionsBB, ++ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_BORDER, null ++ ); ++ potentialCollisionsBB.addAll(entityAABBs); ++ final Vec3 collided = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(movement, currentBox, potentialCollisionsVoxel, potentialCollisionsBB); + -+ if (stepHeight > 0.0 -+ && (onGround || (limitedMoveVector.y != movement.y && movement.y < 0.0)) -+ && (limitedMoveVector.x != movement.x || limitedMoveVector.z != movement.z)) { -+ Vec3 vec3d2 = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(new Vec3(movement.x, stepHeight, movement.z), currBoundingBox, potentialCollisionsVoxel, potentialCollisionsBB); -+ final Vec3 vec3d3 = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(new Vec3(0.0, stepHeight, 0.0), currBoundingBox.expandTowards(movement.x, 0.0, movement.z), potentialCollisionsVoxel, potentialCollisionsBB); ++ final boolean collidedX = collided.x != movement.x; ++ final boolean collidedY = collided.y != movement.y; ++ final boolean collidedZ = collided.z != movement.z; + -+ if (vec3d3.y < stepHeight) { -+ final Vec3 vec3d4 = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(new Vec3(movement.x, 0.0D, movement.z), currBoundingBox.move(vec3d3), potentialCollisionsVoxel, potentialCollisionsBB).add(vec3d3); ++ final boolean collidedDownwards = collidedY && movement.y < 0.0; + -+ if (vec3d4.horizontalDistanceSqr() > vec3d2.horizontalDistanceSqr()) { -+ vec3d2 = vec3d4; -+ } -+ } ++ final double stepHeight; + -+ if (vec3d2.horizontalDistanceSqr() > limitedMoveVector.horizontalDistanceSqr()) { -+ return vec3d2.add(ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(new Vec3(0.0D, -vec3d2.y + movement.y, 0.0D), currBoundingBox.move(vec3d2), potentialCollisionsVoxel, potentialCollisionsBB)); -+ } ++ if ((!collidedDownwards && !this.onGround) || (!collidedX && !collidedZ) || (stepHeight = (double)this.maxUpStep()) <= 0.0) { ++ return collided; ++ } + -+ return limitedMoveVector; -+ } else { -+ return limitedMoveVector; ++ final AABB collidedYBox = collidedDownwards ? currentBox.move(0.0, collided.y, 0.0) : currentBox; ++ AABB stepRetrievalBox = collidedYBox.expandTowards(movement.x, stepHeight, movement.z); ++ if (!collidedDownwards) { ++ stepRetrievalBox = stepRetrievalBox.expandTowards(0.0, (double)-1.0E-5F, 0.0); + } ++ ++ final List stepVoxels = new ArrayList<>(); ++ final List stepAABBs = entityAABBs; ++ ++ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisionsForBlocksOrWorldBorder( ++ this.level, (Entity)(Object)this, stepRetrievalBox, stepVoxels, stepAABBs, ++ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_BORDER, null ++ ); ++ ++ for (final float step : calculateStepHeights(collidedYBox, stepVoxels, stepAABBs, (float)stepHeight, (float)collided.y)) { ++ final Vec3 stepResult = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(new Vec3(movement.x, (double)step, movement.z), collidedYBox, stepVoxels, stepAABBs); ++ if (stepResult.horizontalDistanceSqr() > collided.horizontalDistanceSqr()) { ++ return stepResult.add(0.0, collidedYBox.minY - currentBox.minY, 0.0); + } + } + +- return vec3d1; ++ return collided; + // Paper end - optimise collisions } private static float[] collectCandidateStepUpHeights(AABB collisionBox, List collisions, float f, float stepHeight) { -@@ -2699,18 +2831,75 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2699,18 +2884,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public boolean isInWall() { @@ -27153,76 +28384,111 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..5410a0380c44629f1c9b4f0a8e6017cf - return BlockPos.betweenClosedStream(axisalignedbb).anyMatch((blockposition) -> { - BlockState iblockdata = this.level().getBlockState(blockposition); -+ final float reducedWith = this.dimensions.width() * 0.8F; -+ final AABB box = AABB.ofSize(this.getEyePosition(), reducedWith, 1.0E-6D, reducedWith); ++ final double reducedWith = (double)(this.dimensions.width() * 0.8F); ++ final AABB boundingBox = AABB.ofSize(this.getEyePosition(), reducedWith, 1.0E-6D, reducedWith); ++ final Level world = this.level; - return !iblockdata.isAir() && iblockdata.isSuffocating(this.level(), blockposition) && Shapes.joinIsNotEmpty(iblockdata.getCollisionShape(this.level(), blockposition).move((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()), Shapes.create(axisalignedbb), BooleanOp.AND); - }); -+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(box)) { ++ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(boundingBox)) { + return false; -+ } + } ++ ++ final int minBlockX = Mth.floor(boundingBox.minX); ++ final int minBlockY = Mth.floor(boundingBox.minY); ++ final int minBlockZ = Mth.floor(boundingBox.minZ); + -+ final BlockPos.MutableBlockPos tempPos = new BlockPos.MutableBlockPos(); ++ final int maxBlockX = Mth.floor(boundingBox.maxX); ++ final int maxBlockY = Mth.floor(boundingBox.maxY); ++ final int maxBlockZ = Mth.floor(boundingBox.maxZ); + -+ final int minX = Mth.floor(box.minX); -+ final int minY = Mth.floor(box.minY); -+ final int minZ = Mth.floor(box.minZ); -+ final int maxX = Mth.floor(box.maxX); -+ final int maxY = Mth.floor(box.maxY); -+ final int maxZ = Mth.floor(box.maxZ); ++ final int minChunkX = minBlockX >> 4; ++ final int minChunkY = minBlockY >> 4; ++ final int minChunkZ = minBlockZ >> 4; + -+ final net.minecraft.world.level.chunk.ChunkSource chunkProvider = this.level.getChunkSource(); ++ final int maxChunkX = maxBlockX >> 4; ++ final int maxChunkY = maxBlockY >> 4; ++ final int maxChunkZ = maxBlockZ >> 4; + -+ long lastChunkKey = ChunkPos.INVALID_CHUNK_POS; -+ net.minecraft.world.level.chunk.LevelChunk lastChunk = null; -+ for (int fz = minZ; fz <= maxZ; ++fz) { -+ tempPos.setZ(fz); -+ for (int fx = minX; fx <= maxX; ++fx) { -+ final int newChunkX = fx >> 4; -+ final int newChunkZ = fz >> 4; -+ final net.minecraft.world.level.chunk.LevelChunk chunk = lastChunkKey == (lastChunkKey = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(newChunkX, newChunkZ)) ? -+ lastChunk : (lastChunk = (net.minecraft.world.level.chunk.LevelChunk)chunkProvider.getChunk(newChunkX, newChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, true)); -+ tempPos.setX(fx); -+ for (int fy = minY; fy <= maxY; ++fy) { -+ tempPos.setY(fy); ++ final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(world); ++ final net.minecraft.world.level.chunk.ChunkSource chunkSource = world.getChunkSource(); ++ final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); + -+ final BlockState state = chunk.getBlockState(tempPos); ++ for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { ++ for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { ++ final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, true).getSections(); + -+ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)state).moonrise$emptyCollisionShape() || !state.isSuffocating(this.level, tempPos)) { ++ for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) { ++ final int sectionIdx = currChunkY - minSection; ++ if (sectionIdx < 0 || sectionIdx >= sections.length) { + continue; + } -+ -+ // Yes, it does not use the Entity context stuff. -+ final VoxelShape collisionShape = state.getCollisionShape(this.level, tempPos); -+ -+ if (collisionShape.isEmpty()) { ++ final net.minecraft.world.level.chunk.LevelChunkSection section = sections[sectionIdx]; ++ if (section.hasOnlyAir()) { ++ // empty + continue; + } + -+ final AABB toCollide = box.move(-(double)fx, -(double)fy, -(double)fz); ++ final net.minecraft.world.level.chunk.PalettedContainer blocks = section.states; + -+ final AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)collisionShape).moonrise$getSingleAABBRepresentation(); -+ if (singleAABB != null) { -+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersect(singleAABB, toCollide)) { -+ return true; -+ } -+ continue; -+ } ++ final int minXIterate = currChunkX == minChunkX ? (minBlockX & 15) : 0; ++ final int maxXIterate = currChunkX == maxChunkX ? (maxBlockX & 15) : 15; ++ final int minZIterate = currChunkZ == minChunkZ ? (minBlockZ & 15) : 0; ++ final int maxZIterate = currChunkZ == maxChunkZ ? (maxBlockZ & 15) : 15; ++ final int minYIterate = currChunkY == minChunkY ? (minBlockY & 15) : 0; ++ final int maxYIterate = currChunkY == maxChunkY ? (maxBlockY & 15) : 15; + -+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersectNoEmpty(collisionShape, toCollide)) { -+ return true; ++ for (int currY = minYIterate; currY <= maxYIterate; ++currY) { ++ final int blockY = currY | (currChunkY << 4); ++ mutablePos.setY(blockY); ++ for (int currZ = minZIterate; currZ <= maxZIterate; ++currZ) { ++ final int blockZ = currZ | (currChunkZ << 4); ++ mutablePos.setZ(blockZ); ++ for (int currX = minXIterate; currX <= maxXIterate; ++currX) { ++ final int blockX = currX | (currChunkX << 4); ++ mutablePos.setX(blockX); ++ ++ final BlockState blockState = blocks.get((currX) | (currZ << 4) | ((currY) << 8)); ++ ++ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockState).moonrise$emptyCollisionShape() ++ || !blockState.isSuffocating(world, mutablePos)) { ++ continue; ++ } ++ ++ // Yes, it does not use the Entity context stuff. ++ final VoxelShape collisionShape = blockState.getCollisionShape(world, mutablePos); ++ ++ if (collisionShape.isEmpty()) { ++ continue; ++ } ++ ++ final AABB toCollide = boundingBox.move(-(double)blockX, -(double)blockY, -(double)blockZ); ++ ++ final AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)collisionShape).moonrise$getSingleAABBRepresentation(); ++ if (singleAABB != null) { ++ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersect(singleAABB, toCollide)) { ++ return true; ++ } ++ continue; ++ } ++ ++ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersectNoEmpty(collisionShape, toCollide)) { ++ return true; ++ } ++ continue; ++ } ++ } + } -+ continue; + } + } - } ++ } + + return false; + // Paper end - optimise collisions } public InteractionResult interact(Player player, InteractionHand hand) { -@@ -4180,14 +4369,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4180,14 +4457,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public Iterable getIndirectPassengers() { @@ -27247,7 +28513,202 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..5410a0380c44629f1c9b4f0a8e6017cf } private Iterable getIndirectPassengers_old() { // Paper end - Optimize indirect passenger iteration -@@ -4543,6 +4735,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4316,82 +4596,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + return Mth.lerp(delta, this.yRotO, this.yRot); + } + +- public boolean updateFluidHeightAndDoFluidPushing(TagKey tag, double speed) { ++ // Paper start - optimise collisions ++ public boolean updateFluidHeightAndDoFluidPushing(final TagKey fluid, final double flowScale) { + if (this.touchingUnloadedChunk()) { + return false; +- } else { +- AABB axisalignedbb = this.getBoundingBox().deflate(0.001D); +- int i = Mth.floor(axisalignedbb.minX); +- int j = Mth.ceil(axisalignedbb.maxX); +- int k = Mth.floor(axisalignedbb.minY); +- int l = Mth.ceil(axisalignedbb.maxY); +- int i1 = Mth.floor(axisalignedbb.minZ); +- int j1 = Mth.ceil(axisalignedbb.maxZ); +- double d1 = 0.0D; +- boolean flag = this.isPushedByFluid(); +- boolean flag1 = false; +- Vec3 vec3d = Vec3.ZERO; +- int k1 = 0; +- BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); +- +- for (int l1 = i; l1 < j; ++l1) { +- for (int i2 = k; i2 < l; ++i2) { +- for (int j2 = i1; j2 < j1; ++j2) { +- blockposition_mutableblockposition.set(l1, i2, j2); +- FluidState fluid = this.level().getFluidState(blockposition_mutableblockposition); +- +- if (fluid.is(tag)) { +- double d2 = (double) ((float) i2 + fluid.getHeight(this.level(), blockposition_mutableblockposition)); +- +- if (d2 >= axisalignedbb.minY) { +- flag1 = true; +- d1 = Math.max(d2 - axisalignedbb.minY, d1); +- if (flag) { +- Vec3 vec3d1 = fluid.getFlow(this.level(), blockposition_mutableblockposition); +- +- if (d1 < 0.4D) { +- vec3d1 = vec3d1.scale(d1); +- } ++ } ++ ++ final AABB boundingBox = this.getBoundingBox().deflate(1.0E-3); ++ ++ final Level world = this.level; ++ final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(world); ++ ++ final int minBlockX = Mth.floor(boundingBox.minX); ++ final int minBlockY = Math.max((minSection << 4), Mth.floor(boundingBox.minY)); ++ final int minBlockZ = Mth.floor(boundingBox.minZ); ++ ++ // note: bounds are exclusive in Vanilla, so we subtract 1 - our loop expects bounds to be inclusive ++ final int maxBlockX = Mth.ceil(boundingBox.maxX) - 1; ++ final int maxBlockY = Math.min((ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection(world) << 4) | 15, Mth.ceil(boundingBox.maxY) - 1); ++ final int maxBlockZ = Mth.ceil(boundingBox.maxZ) - 1; ++ ++ final boolean isPushable = this.isPushedByFluid(); ++ final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); ++ ++ Vec3 pushVector = Vec3.ZERO; ++ double totalPushes = 0.0; ++ double maxHeightDiff = 0.0; ++ boolean inFluid = false; ++ ++ final int minChunkX = minBlockX >> 4; ++ final int maxChunkX = maxBlockX >> 4; ++ ++ final int minChunkY = minBlockY >> 4; ++ final int maxChunkY = maxBlockY >> 4; ++ ++ final int minChunkZ = minBlockZ >> 4; ++ final int maxChunkZ = maxBlockZ >> 4; ++ ++ final net.minecraft.world.level.chunk.ChunkSource chunkSource = world.getChunkSource(); ++ ++ for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { ++ for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { ++ final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, false).getSections(); ++ ++ // bound y ++ for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) { ++ final int sectionIdx = currChunkY - minSection; ++ if (sectionIdx < 0 || sectionIdx >= sections.length) { ++ continue; ++ } ++ final net.minecraft.world.level.chunk.LevelChunkSection section = sections[sectionIdx]; ++ if (section.hasOnlyAir()) { ++ // empty ++ continue; ++ } ++ ++ final net.minecraft.world.level.chunk.PalettedContainer blocks = section.states; ++ ++ final int minXIterate = currChunkX == minChunkX ? (minBlockX & 15) : 0; ++ final int maxXIterate = currChunkX == maxChunkX ? (maxBlockX & 15) : 15; ++ final int minZIterate = currChunkZ == minChunkZ ? (minBlockZ & 15) : 0; ++ final int maxZIterate = currChunkZ == maxChunkZ ? (maxBlockZ & 15) : 15; ++ final int minYIterate = currChunkY == minChunkY ? (minBlockY & 15) : 0; ++ final int maxYIterate = currChunkY == maxChunkY ? (maxBlockY & 15) : 15; ++ ++ for (int currY = minYIterate; currY <= maxYIterate; ++currY) { ++ for (int currZ = minZIterate; currZ <= maxZIterate; ++currZ) { ++ for (int currX = minXIterate; currX <= maxXIterate; ++currX) { ++ final FluidState fluidState = blocks.get((currX) | (currZ << 4) | ((currY) << 8)).getFluidState(); ++ ++ if (fluidState.isEmpty() || !fluidState.is(fluid)) { ++ continue; ++ } ++ ++ mutablePos.set(currX | (currChunkX << 4), currY | (currChunkY << 4), currZ | (currChunkZ << 4)); + +- vec3d = vec3d.add(vec3d1); +- ++k1; ++ final double height = (double)((float)mutablePos.getY() + fluidState.getHeight(world, mutablePos)); ++ final double diff = height - boundingBox.minY; ++ ++ if (diff < 0.0) { ++ continue; + } +- // CraftBukkit start - store last lava contact location +- if (tag == FluidTags.LAVA) { +- this.lastLavaContact = blockposition_mutableblockposition.immutable(); ++ ++ inFluid = true; ++ maxHeightDiff = Math.max(maxHeightDiff, diff); ++ ++ if (!isPushable) { ++ continue; ++ } ++ ++ ++totalPushes; ++ ++ final Vec3 flow = fluidState.getFlow(world, mutablePos); ++ ++ if (diff < 0.4) { ++ pushVector = pushVector.add(flow.scale(diff)); ++ } else { ++ pushVector = pushVector.add(flow); + } +- // CraftBukkit end + } + } + } + } + } ++ } + +- if (vec3d.length() > 0.0D) { +- if (k1 > 0) { +- vec3d = vec3d.scale(1.0D / (double) k1); +- } ++ this.fluidHeight.put(fluid, maxHeightDiff); + +- if (!(this instanceof Player)) { +- vec3d = vec3d.normalize(); +- } ++ if (pushVector.lengthSqr() == 0.0) { ++ return inFluid; ++ } + +- Vec3 vec3d2 = this.getDeltaMovement(); ++ // note: totalPushes != 0 as pushVector != 0 ++ pushVector = pushVector.scale(1.0 / totalPushes); ++ final Vec3 currMovement = this.getDeltaMovement(); + +- vec3d = vec3d.scale(speed); +- double d3 = 0.003D; ++ if (!((Entity)(Object)this instanceof Player)) { ++ pushVector = pushVector.normalize(); ++ } + +- if (Math.abs(vec3d2.x) < 0.003D && Math.abs(vec3d2.z) < 0.003D && vec3d.length() < 0.0045000000000000005D) { +- vec3d = vec3d.normalize().scale(0.0045000000000000005D); +- } ++ pushVector = pushVector.scale(flowScale); ++ if (Math.abs(currMovement.x) < 0.003 && Math.abs(currMovement.z) < 0.003 && pushVector.length() < 0.0045000000000000005) { ++ pushVector = pushVector.normalize().scale(0.0045000000000000005); ++ } + +- this.setDeltaMovement(this.getDeltaMovement().add(vec3d)); +- } ++ this.setDeltaMovement(currMovement.add(pushVector)); + +- this.fluidHeight.put(tag, d1); +- return flag1; +- } ++ // note: inFluid = true here as pushVector != 0 ++ return true; + } ++ // Paper end - optimise collisions + + public boolean touchingUnloadedChunk() { + AABB axisalignedbb = this.getBoundingBox().inflate(1.0D); +@@ -4543,6 +4877,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.setPosRaw(x, y, z, false); } public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) { @@ -27263,7 +28724,7 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..5410a0380c44629f1c9b4f0a8e6017cf if (!checkPosition(this, x, y, z)) { return; } -@@ -4672,6 +4873,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4672,6 +5015,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public final void setRemoved(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { @@ -27276,7 +28737,7 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..5410a0380c44629f1c9b4f0a8e6017cf CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit end if (this.removalReason == null) { -@@ -4682,7 +4889,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4682,7 +5031,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.stopRiding(); } @@ -27285,7 +28746,7 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..5410a0380c44629f1c9b4f0a8e6017cf this.levelCallback.onRemove(entity_removalreason); this.onRemoval(entity_removalreason); } -@@ -4698,7 +4905,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4698,7 +5047,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public boolean shouldBeSaved() { @@ -27295,10 +28756,10 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..5410a0380c44629f1c9b4f0a8e6017cf @Override diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -index 96bc0ba60195e5e666d47b3a0b943b733986d96a..4cf6cb0abfeb7065c6d9381fb4194371c0cddc35 100644 +index 96bc0ba60195e5e666d47b3a0b943b733986d96a..5930a430983061afddf20e3208ff2462ca1b78cd 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -@@ -38,12 +38,130 @@ import net.minecraft.world.level.chunk.storage.RegionStorageInfo; +@@ -38,12 +38,137 @@ import net.minecraft.world.level.chunk.storage.RegionStorageInfo; import net.minecraft.world.level.chunk.storage.SectionStorage; import net.minecraft.world.level.chunk.storage.SimpleRegionStorage; @@ -27338,8 +28799,7 @@ index 96bc0ba60195e5e666d47b3a0b943b733986d96a..4cf6cb0abfeb7065c6d9381fb4194371 + + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Accessing poi chunk off-main"); + -+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager manager = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager; -+ final ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk ret = manager.getPoiChunkIfLoaded(chunkX, chunkZ, true); ++ final ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk ret = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager.getPoiChunkIfLoaded(chunkX, chunkZ, true); + + return ret == null ? Optional.empty() : ret.getSectionForVanilla(chunkY); + } @@ -27393,9 +28853,13 @@ index 96bc0ba60195e5e666d47b3a0b943b733986d96a..4cf6cb0abfeb7065c6d9381fb4194371 + public final void moonrise$onUnload(final long coordinate) { // Paper - rewrite chunk system + final int chunkX = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkX(coordinate); + final int chunkZ = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkZ(coordinate); ++ ++ final int minY = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(this.world); ++ final int maxY = ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection(this.world); ++ + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Unloading poi chunk off-main"); -+ for (int section = this.levelHeightAccessor.getMinSection(); section < this.levelHeightAccessor.getMaxSection(); ++section) { -+ final long sectionPos = SectionPos.asLong(chunkX, section, chunkZ); ++ for (int sectionY = minY; sectionY <= maxY; ++sectionY) { ++ final long sectionPos = SectionPos.asLong(chunkX, sectionY, chunkZ); + this.updateDistanceTracking(sectionPos); + } + } @@ -27404,8 +28868,12 @@ index 96bc0ba60195e5e666d47b3a0b943b733986d96a..4cf6cb0abfeb7065c6d9381fb4194371 + public final void moonrise$loadInPoiChunk(final ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk poiChunk) { + final int chunkX = poiChunk.chunkX; + final int chunkZ = poiChunk.chunkZ; ++ ++ final int minY = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(this.world); ++ final int maxY = ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection(this.world); ++ + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Loading poi chunk off-main"); -+ for (int sectionY = this.levelHeightAccessor.getMinSection(); sectionY < this.levelHeightAccessor.getMaxSection(); ++sectionY) { ++ for (int sectionY = minY; sectionY <= maxY; ++sectionY) { + final PoiSection section = poiChunk.getSection(sectionY); + if (section != null && !((ca.spottedleaf.moonrise.patches.chunk_system.level.poi.ChunkSystemPoiSection)section).moonrise$isEmpty()) { + this.onSectionLoad(SectionPos.asLong(chunkX, sectionY, chunkZ)); @@ -27430,7 +28898,7 @@ index 96bc0ba60195e5e666d47b3a0b943b733986d96a..4cf6cb0abfeb7065c6d9381fb4194371 public PoiManager( RegionStorageInfo storageKey, Path directory, -@@ -64,6 +182,7 @@ public class PoiManager extends SectionStorage { +@@ -64,6 +189,7 @@ public class PoiManager extends SectionStorage { world ); this.distanceTracker = new PoiManager.DistanceTracker(); @@ -27438,18 +28906,20 @@ index 96bc0ba60195e5e666d47b3a0b943b733986d96a..4cf6cb0abfeb7065c6d9381fb4194371 } public void add(BlockPos pos, Holder type) { -@@ -197,8 +316,8 @@ public class PoiManager extends SectionStorage { +@@ -197,8 +323,10 @@ public class PoiManager extends SectionStorage { } public int sectionsToVillage(SectionPos pos) { - this.distanceTracker.runAllUpdates(); - return this.distanceTracker.getLevel(pos.asLong()); -+ this.villageDistanceTracker.propagateUpdates(); // Paper - rewrite chunk system -+ return convertBetweenLevels(this.villageDistanceTracker.getLevel(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkSectionKey(pos))); // Paper - rewrite chunk system ++ // Paper start - rewrite chunk system ++ this.villageDistanceTracker.propagateUpdates(); ++ return convertBetweenLevels(this.villageDistanceTracker.getLevel(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkSectionKey(pos))); ++ // Paper end - rewrite chunk system } boolean isVillageCenter(long pos) { -@@ -212,19 +331,26 @@ public class PoiManager extends SectionStorage { +@@ -212,19 +340,26 @@ public class PoiManager extends SectionStorage { @Override public void tick(BooleanSupplier shouldKeepTicking) { @@ -27482,7 +28952,7 @@ index 96bc0ba60195e5e666d47b3a0b943b733986d96a..4cf6cb0abfeb7065c6d9381fb4194371 } public void checkConsistencyWithBlocks(SectionPos sectionPos, LevelChunkSection chunkSection) { -@@ -263,7 +389,7 @@ public class PoiManager extends SectionStorage { +@@ -263,7 +398,7 @@ public class PoiManager extends SectionStorage { .map(sectionPos -> Pair.of(sectionPos, this.getOrLoad(sectionPos.asLong()))) .filter(pair -> !pair.getSecond().map(PoiSection::isValid).orElse(false)) .map(pair -> pair.getFirst().chunk()) @@ -27492,7 +28962,7 @@ index 96bc0ba60195e5e666d47b3a0b943b733986d96a..4cf6cb0abfeb7065c6d9381fb4194371 } diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java -index b9e0bc8f1e948614d986335de1f3d2df199eea81..f6f0d7c21ee81ff33d4af350c4d39aadfbe140df 100644 +index b9e0bc8f1e948614d986335de1f3d2df199eea81..712cbfc100e8aaf612d1d651dae64f57f892a768 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java @@ -23,13 +23,27 @@ import net.minecraft.core.SectionPos; @@ -27508,7 +28978,7 @@ index b9e0bc8f1e948614d986335de1f3d2df199eea81..f6f0d7c21ee81ff33d4af350c4d39aad private boolean isValid; + // Paper start - rewrite chunk system -+ private final Optional noAllocOptional = Optional.of((PoiSection)(Object)this);; ++ private final Optional noAllocOptional = Optional.of((PoiSection)(Object)this); + + @Override + public final boolean moonrise$isEmpty() { @@ -27675,7 +29145,7 @@ index e185a33b5b1f8e8e0a0e666b24ba3e9186a8a7ff..5d7a6e4b73f032db356e7ec369b15001 // Paper start - Affects Spawning API diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e86a982f8 100644 +index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72ea9c094d 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -83,6 +83,7 @@ import net.minecraft.world.level.storage.LevelData; @@ -27695,7 +29165,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e public static final Codec> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION); public static final ResourceKey OVERWORLD = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld")); -@@ -190,6 +191,483 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -190,7 +191,584 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public abstract ResourceKey getTypeKey(); @@ -27772,26 +29242,13 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e + } + // Paper end - rewrite chunk system + // Paper start - optimise collisions -+ private final int minSection; -+ private final int maxSection; -+ -+ @Override -+ public final int moonrise$getMinSection() { -+ return this.minSection; -+ } -+ -+ @Override -+ public final int moonrise$getMaxSection() { -+ return this.maxSection; -+ } -+ + /** + * Route to faster lookup. + * See {@link EntityGetter#isUnobstructed(Entity, VoxelShape)} for expected behavior + * @author Spottedleaf + */ + @Override -+ public final boolean isUnobstructed(final Entity entity) { ++ public boolean isUnobstructed(final Entity entity) { + final AABB boundingBox = entity.getBoundingBox(); + if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(boundingBox)) { + return false; @@ -27821,7 +29278,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e + final Vec3 to = clipContext.getTo(); + final Vec3 from = clipContext.getFrom(); + -+ return net.minecraft.world.phys.BlockHitResult.miss(to, Direction.getNearest(from.x - to.x, from.y - to.y, from.z - to.z), BlockPos.containing(to.x, to.y, to.z)); ++ return net.minecraft.world.phys.BlockHitResult.miss(to, Direction.getApproximateNearest(from.x - to.x, from.y - to.y, from.z - to.z), BlockPos.containing(to.x, to.y, to.z)); + } + + private static final FluidState AIR_FLUIDSTATE = Fluids.EMPTY.defaultFluidState(); @@ -27875,7 +29332,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e + int lastChunkY = Integer.MIN_VALUE; + int lastChunkZ = Integer.MIN_VALUE; + -+ final int minSection = ((ca.spottedleaf.moonrise.patches.collisions.world.CollisionLevel)level).moonrise$getMinSection(); ++ final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(level); + + for (;;) { + currPos.set(currX, currY, currZ); @@ -27958,7 +29415,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e + * @author Spottedleaf + */ + @Override -+ public final net.minecraft.world.phys.BlockHitResult clip(final ClipContext clipContext) { ++ public net.minecraft.world.phys.BlockHitResult clip(final ClipContext clipContext) { + // can only do this in this class, as not everything that implements BlockGetter can retrieve chunks + return fastClip(clipContext.getFrom(), clipContext.getTo(), (Level)(Object)this, clipContext); + } @@ -27968,7 +29425,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e + * @author Spottedleaf + */ + @Override -+ public final boolean collidesWithSuffocatingBlock(final Entity entity, final AABB box) { ++ public boolean collidesWithSuffocatingBlock(final Entity entity, final AABB box) { + return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisionsForBlocksOrWorldBorder((Level)(Object)this, entity, box, null, null, + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_ONLY, + (final BlockState state, final BlockPos pos) -> { @@ -27994,8 +29451,8 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e + * @author Spottedleaf + */ + @Override -+ public final java.util.Optional findFreePosition(final Entity entity, final VoxelShape boundsShape, final Vec3 fromPosition, -+ final double rangeX, final double rangeY, final double rangeZ) { ++ public java.util.Optional findFreePosition(final Entity entity, final VoxelShape boundsShape, final Vec3 fromPosition, ++ final double rangeX, final double rangeY, final double rangeZ) { + if (boundsShape.isEmpty()) { + return java.util.Optional.empty(); + } @@ -28054,111 +29511,215 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e + * @author Spottedleaf + */ + @Override -+ public final java.util.Optional findSupportingBlock(final Entity entity, final AABB aabb) { ++ public java.util.Optional findSupportingBlock(final Entity entity, final AABB aabb) { ++ final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection((Level)(Object)this); ++ + final int minBlockX = Mth.floor(aabb.minX - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) - 1; + final int maxBlockX = Mth.floor(aabb.maxX + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) + 1; + -+ final int minBlockY = Mth.floor(aabb.minY - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) - 1; -+ final int maxBlockY = Mth.floor(aabb.maxY + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) + 1; ++ final int minBlockY = Math.max((minSection << 4) - 1, Mth.floor(aabb.minY - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) - 1); ++ final int maxBlockY = Math.min((ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection((Level)(Object)this) << 4) + 16, Mth.floor(aabb.maxY + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) + 1); + + final int minBlockZ = Mth.floor(aabb.minZ - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) - 1; + final int maxBlockZ = Mth.floor(aabb.maxZ + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) + 1; + -+ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext collisionContext = null; ++ final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); ++ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext collisionShape = new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext(entity); ++ BlockPos selected = null; ++ double selectedDistance = Double.MAX_VALUE; ++ final Vec3 entityPos = entity.position(); ++ ++ // special cases: ++ if (minBlockY > maxBlockY) { ++ // no point in checking ++ return java.util.Optional.empty(); ++ } ++ ++ final int minChunkX = minBlockX >> 4; ++ final int maxChunkX = maxBlockX >> 4; ++ ++ final int minChunkY = minBlockY >> 4; ++ final int maxChunkY = maxBlockY >> 4; ++ ++ final int minChunkZ = minBlockZ >> 4; ++ final int maxChunkZ = maxBlockZ >> 4; ++ ++ final ChunkSource chunkSource = this.getChunkSource(); ++ ++ for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { ++ for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { ++ final ChunkAccess chunk = chunkSource.getChunk(currChunkX, currChunkZ, ChunkStatus.FULL, false); ++ ++ if (chunk == null) { ++ continue; ++ } ++ ++ final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections(); ++ ++ // bound y ++ for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) { ++ final int sectionIdx = currChunkY - minSection; ++ if (sectionIdx < 0 || sectionIdx >= sections.length) { ++ continue; ++ } ++ final net.minecraft.world.level.chunk.LevelChunkSection section = sections[sectionIdx]; ++ if (section.hasOnlyAir()) { ++ // empty ++ continue; ++ } ++ ++ final boolean hasSpecial = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$hasSpecialCollidingBlocks(); ++ final int sectionAdjust = !hasSpecial ? 1 : 0; ++ ++ final net.minecraft.world.level.chunk.PalettedContainer blocks = section.states; ++ ++ final int minXIterate = currChunkX == minChunkX ? (minBlockX & 15) + sectionAdjust : 0; ++ final int maxXIterate = currChunkX == maxChunkX ? (maxBlockX & 15) - sectionAdjust : 15; ++ final int minZIterate = currChunkZ == minChunkZ ? (minBlockZ & 15) + sectionAdjust : 0; ++ final int maxZIterate = currChunkZ == maxChunkZ ? (maxBlockZ & 15) - sectionAdjust : 15; ++ final int minYIterate = currChunkY == minChunkY ? (minBlockY & 15) + sectionAdjust : 0; ++ final int maxYIterate = currChunkY == maxChunkY ? (maxBlockY & 15) - sectionAdjust : 15; ++ ++ for (int currY = minYIterate; currY <= maxYIterate; ++currY) { ++ final int blockY = currY | (currChunkY << 4); ++ mutablePos.setY(blockY); ++ for (int currZ = minZIterate; currZ <= maxZIterate; ++currZ) { ++ final int blockZ = currZ | (currChunkZ << 4); ++ mutablePos.setZ(blockZ); ++ for (int currX = minXIterate; currX <= maxXIterate; ++currX) { ++ final int localBlockIndex = (currX) | (currZ << 4) | ((currY) << 8); ++ final int blockX = currX | (currChunkX << 4); ++ mutablePos.setX(blockX); ++ ++ final int edgeCount = hasSpecial ? ((blockX == minBlockX || blockX == maxBlockX) ? 1 : 0) + ++ ((blockY == minBlockY || blockY == maxBlockY) ? 1 : 0) + ++ ((blockZ == minBlockZ || blockZ == maxBlockZ) ? 1 : 0) : 0; ++ if (edgeCount == 3) { ++ continue; ++ } ++ ++ final double distance = mutablePos.distToCenterSqr(entityPos); ++ if (distance > selectedDistance || (distance == selectedDistance && selected.compareTo(mutablePos) >= 0)) { ++ continue; ++ } ++ ++ final BlockState blockData = blocks.get(localBlockIndex); + -+ final BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); -+ BlockPos selected = null; -+ double selectedDistance = Double.MAX_VALUE; ++ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockData).moonrise$emptyContextCollisionShape()) { ++ continue; ++ } + -+ final Vec3 entityPos = entity.position(); ++ VoxelShape blockCollision = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockData).moonrise$getConstantContextCollisionShape(); + -+ LevelChunk lastChunk = null; -+ int lastChunkX = Integer.MIN_VALUE; -+ int lastChunkZ = Integer.MIN_VALUE; ++ if (edgeCount == 0 || ((edgeCount != 1 || blockData.hasLargeCollisionShape()) && (edgeCount != 2 || blockData.getBlock() == Blocks.MOVING_PISTON))) { ++ if (blockCollision == null) { ++ blockCollision = blockData.getCollisionShape((Level)(Object)this, mutablePos, collisionShape); + -+ final ChunkSource chunkSource = this.getChunkSource(); ++ if (blockCollision.isEmpty()) { ++ continue; ++ } ++ } + -+ for (int currZ = minBlockZ; currZ <= maxBlockZ; ++currZ) { -+ pos.setZ(currZ); -+ for (int currX = minBlockX; currX <= maxBlockX; ++currX) { -+ pos.setX(currX); ++ // avoid VoxelShape#move by shifting the entity collision shape instead ++ final AABB shiftedAABB = aabb.move(-(double)blockX, -(double)blockY, -(double)blockZ); + -+ final int newChunkX = currX >> 4; -+ final int newChunkZ = currZ >> 4; ++ final AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation(); ++ if (singleAABB != null) { ++ if (!ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersect(singleAABB, shiftedAABB)) { ++ continue; ++ } + -+ if (((newChunkX ^ lastChunkX) | (newChunkZ ^ lastChunkZ)) != 0) { -+ lastChunkX = newChunkX; -+ lastChunkZ = newChunkZ; -+ lastChunk = (LevelChunk)chunkSource.getChunk(newChunkX, newChunkZ, ChunkStatus.FULL, false); -+ } ++ selected = mutablePos.immutable(); ++ selectedDistance = distance; ++ continue; ++ } + -+ if (lastChunk == null) { -+ continue; -+ } -+ for (int currY = minBlockY; currY <= maxBlockY; ++currY) { -+ int edgeCount = ((currX == minBlockX || currX == maxBlockX) ? 1 : 0) + -+ ((currY == minBlockY || currY == maxBlockY) ? 1 : 0) + -+ ((currZ == minBlockZ || currZ == maxBlockZ) ? 1 : 0); -+ if (edgeCount == 3) { -+ continue; ++ if (!ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersectNoEmpty(blockCollision, shiftedAABB)) { ++ continue; ++ } ++ ++ selected = mutablePos.immutable(); ++ selectedDistance = distance; ++ continue; ++ } ++ } ++ } + } ++ } ++ } ++ } + -+ pos.setY(currY); ++ return java.util.Optional.ofNullable(selected); ++ } ++ // Paper end - optimise collisions ++ // Paper start - getblock optimisations - cache world height/sections ++ private final int minY; ++ private final int height; ++ private final int maxY; ++ private final int minSectionY; ++ private final int maxSectionY; ++ private final int sectionsCount; + -+ final double distance = pos.distToCenterSqr(entityPos); -+ if (distance > selectedDistance || (distance == selectedDistance && selected.compareTo(pos) >= 0)) { -+ continue; -+ } ++ @Override ++ public int getMinY() { ++ return this.minY; ++ } + -+ final BlockState state = ((ca.spottedleaf.moonrise.patches.chunk_getblock.GetBlockChunk)lastChunk).moonrise$getBlock(currX, currY, currZ); -+ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)state).moonrise$emptyCollisionShape()) { -+ continue; -+ } ++ @Override ++ public int getHeight() { ++ return this.height; ++ } + -+ VoxelShape blockCollision = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)state).moonrise$getConstantCollisionShape(); ++ @Override ++ public int getMaxY() { ++ return this.maxY; ++ } + -+ if ((edgeCount != 1 || state.hasLargeCollisionShape()) && (edgeCount != 2 || state.getBlock() == Blocks.MOVING_PISTON)) { -+ if (collisionContext == null) { -+ collisionContext = new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext(entity); -+ } ++ @Override ++ public int getSectionsCount() { ++ return this.sectionsCount; ++ } + -+ if (blockCollision == null) { -+ blockCollision = state.getCollisionShape((Level)(Object)this, pos, collisionContext); -+ } ++ @Override ++ public int getMinSectionY() { ++ return this.minSectionY; ++ } + -+ if (blockCollision.isEmpty()) { -+ continue; -+ } ++ @Override ++ public int getMaxSectionY() { ++ return this.maxSectionY; ++ } + -+ // avoid VoxelShape#move by shifting the entity collision shape instead -+ final AABB shiftedAABB = aabb.move(-(double)currX, -(double)currY, -(double)currZ); ++ @Override ++ public boolean isInsideBuildHeight(final int blockY) { ++ return blockY >= this.minY && blockY <= this.maxY; ++ } + -+ final AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation(); -+ if (singleAABB != null) { -+ if (!ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersect(singleAABB, shiftedAABB)) { -+ continue; -+ } ++ @Override ++ public boolean isOutsideBuildHeight(final BlockPos pos) { ++ return this.isOutsideBuildHeight(pos.getY()); ++ } + -+ selected = pos.immutable(); -+ selectedDistance = distance; -+ continue; -+ } ++ @Override ++ public boolean isOutsideBuildHeight(final int blockY) { ++ return blockY < this.minY || blockY > this.maxY; ++ } + -+ if (!ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersectNoEmpty(blockCollision, shiftedAABB)) { -+ continue; -+ } ++ @Override ++ public int getSectionIndex(final int blockY) { ++ return (blockY >> 4) - this.minSectionY; ++ } + -+ selected = pos.immutable(); -+ selectedDistance = distance; -+ continue; -+ } -+ } -+ } -+ } ++ @Override ++ public int getSectionIndexFromSectionY(final int sectionY) { ++ return sectionY - this.minSectionY; ++ } + -+ return java.util.Optional.ofNullable(selected); ++ @Override ++ public int getSectionYFromSectionIndex(final int sectionIdx) { ++ return sectionIdx + this.minSectionY; + } -+ // Paper end - optimise collisions ++ // Paper end - getblock optimisations - cache world height/sections + // Paper start - optimise random ticking + @Override + public abstract Holder getUncachedNoiseBiome(final int x, final int y, final int z); @@ -28177,9 +29738,19 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e + // Paper end - optimise random ticking + protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator) { // Paper - create paper world config ++ // Paper start - getblock optimisations - cache world height/sections ++ final DimensionType dimType = holder.value(); ++ this.minY = dimType.minY(); ++ this.height = dimType.height(); ++ this.maxY = this.minY + this.height - 1; ++ this.minSectionY = this.minY >> 4; ++ this.maxSectionY = this.maxY >> 4; ++ this.sectionsCount = this.maxSectionY - this.minSectionY + 1; ++ // Paper end - getblock optimisations - cache world height/sections this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config -@@ -271,6 +749,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + this.generator = gen; +@@ -271,6 +849,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime); this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); @@ -28191,7 +29762,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e } // Paper start - Cancel hit for vanished players -@@ -535,7 +1018,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -535,7 +1118,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.setBlocksDirty(blockposition, iblockdata1, iblockdata2); } @@ -28200,7 +29771,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e this.sendBlockUpdated(blockposition, iblockdata1, iblockdata, i); } -@@ -800,6 +1283,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -800,6 +1383,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Iterator iterator = this.blockEntityTickers.iterator(); boolean flag = this.tickRateManager().runsNormally(); @@ -28209,7 +29780,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e int tilesThisCycle = 0; var toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet(); // Paper - Fix MC-117075; use removeAll toRemove.add(null); // Paper - Fix MC-117075 -@@ -815,6 +1300,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -815,6 +1400,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Spigot end } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { tickingblockentity.tick(); @@ -28221,7 +29792,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e } } this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 -@@ -837,12 +1327,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -837,12 +1427,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable { entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Paper end - Prevent block entity and entity crashes } @@ -28243,7 +29814,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e } // Paper end - Option to prevent armor stands from doing entity lookups -@@ -894,7 +1392,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -894,7 +1492,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } // Paper end - Perf: Optimize capturedTileEntities lookup // CraftBukkit end @@ -28252,7 +29823,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e } public void setBlockEntity(BlockEntity blockEntity) { -@@ -986,26 +1484,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -986,26 +1584,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { Profiler.get().incrementCounter("getEntities"); List list = Lists.newArrayList(); @@ -28260,17 +29831,17 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e - if (entity1 != except && predicate.test(entity1)) { - list.add(entity1); - } -+ // Paper start - rewrite chunk system -+ final List ret = new java.util.ArrayList<>(); - +- - if (entity1 instanceof EnderDragon) { - EnderDragonPart[] aentitycomplexpart = ((EnderDragon) entity1).getSubEntities(); - int i = aentitycomplexpart.length; -+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities(except, box, ret, predicate); ++ // Paper start - rewrite chunk system ++ final List ret = new java.util.ArrayList<>(); - for (int j = 0; j < i; ++j) { - EnderDragonPart entitycomplexpart = aentitycomplexpart[j]; -- ++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities(except, box, ret, predicate); + - if (entity1 != except && predicate.test(entitycomplexpart)) { - list.add(entitycomplexpart); - } @@ -28284,7 +29855,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e } @Override -@@ -1020,36 +1505,77 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1020,36 +1605,86 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.getEntities(filter, box, predicate, result, Integer.MAX_VALUE); } @@ -28359,7 +29930,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e + } else { + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities((Entity)null, boundingBox, (List)into, (Predicate)modifiedPredicate); + return; - } ++ } + } else { + if (maxCount != Integer.MAX_VALUE) { + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities(base, null, boundingBox, (List)into, (Predicate)modifiedPredicate, maxCount); @@ -28370,15 +29941,24 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..332dc7e6bdfb5b3741764d4877185a2e + } + } + } - -- return AbortableIterationConsumer.Continuation.CONTINUE; -- }); ++ + public org.bukkit.entity.Entity[] getChunkEntities(int chunkX, int chunkZ) { + ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices slices = ((ServerLevel)this).moonrise$getEntityLookup().getChunk(chunkX, chunkZ); + if (slices == null) { + return new org.bukkit.entity.Entity[0]; + } -+ return slices.getChunkEntities(); ++ ++ List ret = new java.util.ArrayList<>(); ++ for (Entity entity : slices.getAllEntities()) { ++ org.bukkit.entity.Entity bukkit = entity.getBukkitEntity(); ++ if (bukkit != null && bukkit.isValid()) { ++ ret.add(bukkit); + } ++ } + +- return AbortableIterationConsumer.Continuation.CONTINUE; +- }); ++ return ret.toArray(new org.bukkit.entity.Entity[0]); } + // Paper end - rewrite chunk system @@ -28434,6 +30014,20 @@ index 8590de51b572c0f73d45aee60313d466e4671da5..b725eea9d3ca81d2ef7802f5d0346d92 } public boolean shouldFreeze(LevelReader world, BlockPos blockPos) { +diff --git a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java +index 01352cc83b25eb0e30b7e0ff521fc7c1b3d5155b..90f8360f547ce709fd13ee34f8e67d8bfa94b498 100644 +--- a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java ++++ b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java +@@ -98,8 +98,7 @@ public class BiomeManager { + } + + private static double getFiddle(long l) { +- double d = (double)Math.floorMod(l >> 24, 1024) / 1024.0; +- return (d - 0.5) * 0.9; ++ return (double)(((l >> 24) & (1024 - 1)) - (1024/2)) * (0.9 / 1024.0); // Paper - avoid floorMod, fp division, and fp subtraction + } + + public interface NoiseBiomeSource { diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java index 4d140bd83ca0e1554afad80ec4fc6186188a79d8..3dd236d39535cfce866eb73673f8d7f1b6dc535c 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java @@ -28448,7 +30042,7 @@ index 4d140bd83ca0e1554afad80ec4fc6186188a79d8..3dd236d39535cfce866eb73673f8d7f1 public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) {} diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -index 0665ca48fe2f8ab1ce1c0306b11be19b06445f74..a4b4fd83d201fff005c738c84fa5c1bc55d670bd 100644 +index 0665ca48fe2f8ab1ce1c0306b11be19b06445f74..8631655a181735df53f8a02c9eb98f0cc13f55bb 100644 --- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java @@ -793,7 +793,7 @@ public abstract class BlockBehaviour implements FeatureElement { @@ -28465,18 +30059,12 @@ index 0665ca48fe2f8ab1ce1c0306b11be19b06445f74..a4b4fd83d201fff005c738c84fa5c1bc private int lightBlock; + // Paper start - rewrite chunk system -+ private int opacityIfCached; + private boolean isConditionallyFullOpaque; + + @Override + public final boolean starlight$isConditionallyFullOpaque() { + return this.isConditionallyFullOpaque; + } -+ -+ @Override -+ public final int starlight$getOpacityIfCached() { -+ return this.opacityIfCached; -+ } + // Paper end - rewrite chunk system + // Paper start - optimise collisions + private static final int RANDOM_OFFSET = 704237939; @@ -28486,101 +30074,448 @@ index 0665ca48fe2f8ab1ce1c0306b11be19b06445f74..a4b4fd83d201fff005c738c84fa5c1bc + private final int id2 = it.unimi.dsi.fastutil.HashCommon.murmurHash3(it.unimi.dsi.fastutil.HashCommon.murmurHash3(ID_GENERATOR.getAndIncrement() + RANDOM_OFFSET) + RANDOM_OFFSET); + private boolean occludesFullBlock; + private boolean emptyCollisionShape; ++ private boolean emptyConstantCollisionShape; + private VoxelShape constantCollisionShape; -+ private AABB constantAABBCollision; + -+ private static void initCaches(final VoxelShape shape) { -+ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$isFullBlock(); -+ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$occludesFullBlock(); -+ shape.toAabbs(); -+ if (!shape.isEmpty()) { -+ shape.bounds(); -+ } -+ } ++ private static void initCaches(final VoxelShape shape, final boolean neighbours) { ++ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$isFullBlock(); ++ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$occludesFullBlock(); ++ shape.toAabbs(); ++ if (!shape.isEmpty()) { ++ shape.bounds(); ++ } ++ if (neighbours) { ++ for (final Direction direction : DIRECTIONS_CACHED) { ++ initCaches(((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$getFaceShapeClamped(direction), false); ++ initCaches(shape.getFaceShape(direction), false); ++ } ++ } ++ } ++ ++ @Override ++ public final boolean moonrise$hasCache() { ++ return this.cache != null; ++ } ++ ++ @Override ++ public final boolean moonrise$occludesFullBlock() { ++ return this.occludesFullBlock; ++ } ++ ++ @Override ++ public final boolean moonrise$emptyCollisionShape() { ++ return this.emptyCollisionShape; ++ } ++ ++ @Override ++ public final boolean moonrise$emptyContextCollisionShape() { ++ return this.emptyConstantCollisionShape; ++ } ++ ++ @Override ++ public final int moonrise$uniqueId1() { ++ return this.id1; ++ } ++ ++ @Override ++ public final int moonrise$uniqueId2() { ++ return this.id2; ++ } ++ ++ @Override ++ public final VoxelShape moonrise$getConstantContextCollisionShape() { ++ return this.constantCollisionShape; ++ } ++ // Paper end - optimise collisions ++ + protected BlockStateBase(Block block, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { + super(block, propertyMap, codec); + this.fluidState = Fluids.EMPTY.defaultFluidState(); +@@ -921,6 +991,41 @@ public abstract class BlockBehaviour implements FeatureElement { + + this.propagatesSkylightDown = ((Block) this.owner).propagatesSkylightDown(this.asState()); + this.lightBlock = ((Block) this.owner).getLightBlock(this.asState()); ++ // Paper start - rewrite chunk system ++ this.isConditionallyFullOpaque = this.canOcclude & this.useShapeForLightOcclusion; ++ // Paper end - rewrite chunk system ++ // Paper start - optimise collisions ++ if (this.cache != null) { ++ final VoxelShape collisionShape = this.cache.collisionShape; ++ try { ++ this.constantCollisionShape = this.getCollisionShape(null, null, null); ++ } catch (final Throwable throwable) { ++ this.constantCollisionShape = null; ++ } ++ this.occludesFullBlock = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)collisionShape).moonrise$occludesFullBlock(); ++ this.emptyCollisionShape = collisionShape.isEmpty(); ++ this.emptyConstantCollisionShape = this.constantCollisionShape != null && this.constantCollisionShape.isEmpty(); ++ // init caches ++ initCaches(collisionShape, true); ++ if (this.constantCollisionShape != null) { ++ initCaches(this.constantCollisionShape, true); ++ } ++ } else { ++ this.occludesFullBlock = false; ++ this.emptyCollisionShape = false; ++ this.emptyConstantCollisionShape = false; ++ this.constantCollisionShape = null; ++ } ++ ++ if (this.occlusionShape != null) { ++ initCaches(this.occlusionShape, true); ++ } ++ if (this.occlusionShapesByFace != null) { ++ for (final VoxelShape shape : this.occlusionShapesByFace) { ++ initCaches(shape, true); ++ } ++ } ++ // Paper end - optimise collisions + } + + public Block getBlock() { +diff --git a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java +index 422b364764e0df16ca250b4939d7b226e69c0840..2df28ffc731bd77e0d7af3541cfd3741aa5af83b 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java ++++ b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java +@@ -15,7 +15,7 @@ import java.util.stream.Collectors; + import javax.annotation.Nullable; + import net.minecraft.world.level.block.state.properties.Property; + +-public abstract class StateHolder { ++public abstract class StateHolder implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccessStateHolder { // Paper - optimise blockstate property access + public static final String NAME_TAG = "Name"; + public static final String PROPERTIES_TAG = "Properties"; + public static final Function, Comparable>, String> PROPERTY_ENTRY_TO_STRING_FUNCTION = new Function, Comparable>, String>() { +@@ -34,14 +34,28 @@ public abstract class StateHolder { + } + }; + protected final O owner; +- private final Reference2ObjectArrayMap, Comparable> values; ++ private Reference2ObjectArrayMap, Comparable> values; // Paper - optimise blockstate property access - remove final + private Map, S[]> neighbours; + protected final MapCodec propertiesCodec; + ++ // Paper start - optimise blockstate property access ++ protected ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.util.ZeroCollidingReferenceStateTable optimisedTable; ++ protected final long tableIndex; ++ ++ @Override ++ public final long moonrise$getTableIndex() { ++ return this.tableIndex; ++ } ++ // Paper end - optimise blockstate property access ++ + protected StateHolder(O owner, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { + this.owner = owner; + this.values = propertyMap; + this.propertiesCodec = codec; ++ // Paper start - optimise blockstate property access ++ this.optimisedTable = new ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.util.ZeroCollidingReferenceStateTable<>(this.values.keySet()); ++ this.tableIndex = this.optimisedTable.getIndex((StateHolder)(Object)this); ++ // Paper end - optimise blockstate property access + } + + public > S cycle(Property property) { +@@ -67,20 +81,21 @@ public abstract class StateHolder { + } + + public Collection> getProperties() { +- return Collections.unmodifiableCollection(this.values.keySet()); ++ return this.optimisedTable.getProperties(); // Paper - optimise blockstate property access + } + + public > boolean hasProperty(Property property) { +- return this.values.containsKey(property); ++ return property != null && this.optimisedTable.hasProperty(property); // Paper - optimise blockstate property access + } + + public > T getValue(Property property) { +- Comparable comparable = this.values.get(property); +- if (comparable == null) { +- throw new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.owner); +- } else { +- return property.getValueClass().cast(comparable); ++ // Paper start - optimise blockstate property access ++ final T ret = this.optimisedTable.get(this.tableIndex, property); ++ if (ret != null) { ++ return ret; + } ++ throw new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.owner); ++ // Paper end - optimise blockstate property access + } + + public > Optional getOptionalValue(Property property) { +@@ -93,22 +108,30 @@ public abstract class StateHolder { + + @Nullable + public > T getNullableValue(Property property) { +- Comparable comparable = this.values.get(property); +- return comparable == null ? null : property.getValueClass().cast(comparable); ++ return property == null ? null : this.optimisedTable.get(this.tableIndex, property); // Paper - optimise blockstate property access + } + + public , V extends T> S setValue(Property property, V value) { +- Comparable comparable = this.values.get(property); +- if (comparable == null) { +- throw new IllegalArgumentException("Cannot set property " + property + " as it does not exist in " + this.owner); +- } else { +- return this.setValueInternal(property, value, comparable); ++ // Paper start - optimise blockstate property access ++ final S ret = this.optimisedTable.set(this.tableIndex, property, value); ++ if (ret != null) { ++ return ret; + } ++ throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner); ++ // Paper end - optimise blockstate property access + } + + public , V extends T> S trySetValue(Property property, V value) { +- Comparable comparable = this.values.get(property); +- return (S)(comparable == null ? this : this.setValueInternal(property, value, comparable)); ++ // Paper start - optimise blockstate property access ++ if (property == null) { ++ return (S)(StateHolder)(Object)this; ++ } ++ final S ret = this.optimisedTable.trySet(this.tableIndex, property, value, (S)(StateHolder)(Object)this); ++ if (ret != null) { ++ return ret; ++ } ++ throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner); ++ // Paper end - optimise blockstate property access + } + + private , V extends T> S setValueInternal(Property property, V newValue, Comparable oldValue) { +@@ -125,18 +148,27 @@ public abstract class StateHolder { + } + + public void populateNeighbours(Map, Comparable>, S> states) { +- if (this.neighbours != null) { +- throw new IllegalStateException(); +- } else { +- Map, S[]> map = new Reference2ObjectArrayMap<>(this.values.size()); ++ // Paper start - optimise blockstate property access ++ final Map, Comparable>, S> map = states; ++ if (this.optimisedTable.isLoaded()) { ++ return; ++ } ++ this.optimisedTable.loadInTable(map); + +- for (Entry, Comparable> entry : this.values.entrySet()) { +- Property property = entry.getKey(); +- map.put(property, property.getPossibleValues().stream().map(value -> states.get(this.makeNeighbourValues(property, value))).toArray()); +- } ++ // de-duplicate the tables ++ for (final Map.Entry, Comparable>, S> entry : map.entrySet()) { ++ final S value = entry.getValue(); ++ ((StateHolder)value).optimisedTable = this.optimisedTable; ++ } + +- this.neighbours = map; ++ // remove values arrays ++ for (final Map.Entry, Comparable>, S> entry : map.entrySet()) { ++ final S value = entry.getValue(); ++ ((StateHolder)value).values = null; + } ++ ++ return; ++ // Paper end optimise blockstate property access + } + + private Map, Comparable> makeNeighbourValues(Property property, Comparable value) { +@@ -146,7 +178,11 @@ public abstract class StateHolder { + } + + public Map, Comparable> getValues() { +- return this.values; ++ // Paper start - optimise blockstate property access ++ ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.util.ZeroCollidingReferenceStateTable table = this.optimisedTable; ++ // We have to use this.values until the table is loaded ++ return table.isLoaded() ? table.getMapView(this.tableIndex) : this.values; ++ // Paper end - optimise blockstate property access + } + + protected static > Codec codec(Codec codec, Function ownerToStateFunction) { +diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java +index ea76aa490358e9e1d13350ba0ea246ec2c423894..98058505d36baf74008da08339afc196713b14a7 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java ++++ b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java +@@ -3,13 +3,23 @@ package net.minecraft.world.level.block.state.properties; + import java.util.List; + import java.util.Optional; + +-public final class BooleanProperty extends Property { ++public final class BooleanProperty extends Property implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access + private static final List VALUES = List.of(true, false); + private static final int TRUE_INDEX = 0; + private static final int FALSE_INDEX = 1; + ++ // Paper start - optimise blockstate property access ++ private static final Boolean[] BY_ID = new Boolean[]{ Boolean.FALSE, Boolean.TRUE }; ++ ++ @Override ++ public final int moonrise$getIdFor(final Boolean value) { ++ return value.booleanValue() ? 1 : 0; ++ } ++ // Paper end - optimise blockstate property access ++ + private BooleanProperty(String name) { + super(name, Boolean.class); ++ this.moonrise$setById(BY_ID); // Paper - optimise blockstate property access + } + + @Override +diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java +index 85a197232be9377c0313ec00e8f935551e2c60e0..30b2fce9e47ffcc3de1542b1d0f073f5640127a7 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java ++++ b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java +@@ -10,11 +10,39 @@ import java.util.function.Predicate; + import java.util.stream.Collectors; + import net.minecraft.util.StringRepresentable; + +-public final class EnumProperty & StringRepresentable> extends Property { ++public final class EnumProperty & StringRepresentable> extends Property implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access + private final List values; + private final Map names; + private final int[] ordinalToIndex; + ++ // Paper start - optimise blockstate property access ++ private int[] idLookupTable; ++ ++ @Override ++ public final int moonrise$getIdFor(final T value) { ++ final Class target = this.getValueClass(); ++ return ((value.getClass() != target && value.getDeclaringClass() != target)) ? -1 : this.idLookupTable[value.ordinal()]; ++ } ++ ++ private void init() { ++ final java.util.Collection values = this.getPossibleValues(); ++ final Class clazz = this.getValueClass(); + -+ @Override -+ public final boolean moonrise$hasCache() { -+ return this.cache != null; -+ } ++ int id = 0; ++ this.idLookupTable = new int[clazz.getEnumConstants().length]; ++ Arrays.fill(this.idLookupTable, -1); ++ final T[] byId = (T[])java.lang.reflect.Array.newInstance(clazz, values.size()); + -+ @Override -+ public final boolean moonrise$occludesFullBlock() { -+ return this.occludesFullBlock; ++ for (final T value : values) { ++ final int valueId = id++; ++ this.idLookupTable[value.ordinal()] = valueId; ++ byId[valueId] = value; + } + -+ @Override -+ public final boolean moonrise$emptyCollisionShape() { -+ return this.emptyCollisionShape; -+ } ++ this.moonrise$setById(byId); ++ } ++ // Paper end - optimise blockstate property access + -+ @Override -+ public final int moonrise$uniqueId1() { -+ return this.id1; -+ } + private EnumProperty(String name, Class type, List values) { + super(name, type); + if (values.isEmpty()) { +@@ -37,6 +65,7 @@ public final class EnumProperty & StringRepresentable> extends + + this.names = builder.buildOrThrow(); + } ++ this.init(); // Paper - optimise blockstate property access + } + + @Override +diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java +index 55a87592a99105dbf57b26fb6ccba695295fce24..986365acc9983331a7982ea2e1eac2b0efe1506d 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java ++++ b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java +@@ -5,11 +5,33 @@ import java.util.List; + import java.util.Optional; + import java.util.stream.IntStream; + +-public final class IntegerProperty extends Property { ++public final class IntegerProperty extends Property implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access + private final IntImmutableList values; + public final int min; + public final int max; + ++ // Paper start - optimise blockstate property access ++ @Override ++ public final int moonrise$getIdFor(final Integer value) { ++ final int val = value.intValue(); ++ final int ret = val - this.min; + -+ @Override -+ public final int moonrise$uniqueId2() { -+ return this.id2; -+ } ++ return ret | ((this.max - ret) >> 31); ++ } + -+ @Override -+ public final VoxelShape moonrise$getConstantCollisionShape() { -+ return this.constantCollisionShape; -+ } ++ private void init() { ++ final int min = this.min; ++ final int max = this.max; + -+ @Override -+ public final AABB moonrise$getConstantCollisionAABB() { -+ return this.constantAABBCollision; ++ final Integer[] byId = new Integer[max - min + 1]; ++ for (int i = min; i <= max; ++i) { ++ byId[i - min] = Integer.valueOf(i); + } -+ // Paper end - optimise collisions + - protected BlockStateBase(Block block, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { - super(block, propertyMap, codec); - this.fluidState = Fluids.EMPTY.defaultFluidState(); -@@ -921,6 +991,43 @@ public abstract class BlockBehaviour implements FeatureElement { - - this.propagatesSkylightDown = ((Block) this.owner).propagatesSkylightDown(this.asState()); - this.lightBlock = ((Block) this.owner).getLightBlock(this.asState()); -+ // Paper start - rewrite chunk system -+ this.isConditionallyFullOpaque = this.canOcclude & this.useShapeForLightOcclusion; -+ this.opacityIfCached = this.cache == null || this.isConditionallyFullOpaque ? -1 : this.cache.lightBlock; -+ // Paper end - rewrite chunk system -+ // Paper start - optimise collisions -+ if (this.cache != null) { -+ final VoxelShape collisionShape = this.cache.collisionShape; -+ try { -+ this.constantCollisionShape = this.getCollisionShape(null, null, null); -+ this.constantAABBCollision = this.constantCollisionShape == null ? null : ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)this.constantCollisionShape).moonrise$getSingleAABBRepresentation(); -+ } catch (final Throwable throwable) { -+ this.constantCollisionShape = null; -+ this.constantAABBCollision = null; -+ } -+ this.occludesFullBlock = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)collisionShape).moonrise$occludesFullBlock(); -+ this.emptyCollisionShape = collisionShape.isEmpty(); -+ // init caches -+ initCaches(collisionShape); -+ if (collisionShape != Shapes.empty() && collisionShape != Shapes.block()) { -+ for (final Direction direction : DIRECTIONS_CACHED) { -+ // initialise the directional face shape cache as well -+ final VoxelShape shape = Shapes.getFaceShape(collisionShape, direction); -+ initCaches(shape); -+ } -+ } -+ if (this.cache.occlusionShapes != null) { -+ for (final VoxelShape shape : this.cache.occlusionShapes) { -+ initCaches(shape); -+ } -+ } -+ } else { -+ this.occludesFullBlock = false; -+ this.emptyCollisionShape = false; -+ this.constantCollisionShape = null; -+ this.constantAABBCollision = null; -+ } -+ // Paper end - optimise collisions ++ this.moonrise$setById(byId); ++ } ++ // Paper end - optimise blockstate property access ++ + private IntegerProperty(String name, int min, int max) { + super(name, Integer.class); + if (min < 0) { +@@ -21,6 +43,7 @@ public final class IntegerProperty extends Property { + this.max = max; + this.values = IntImmutableList.toList(IntStream.range(min, max + 1)); } ++ this.init(); // Paper - optimise blockstate property access + } - public Block getBlock() { + @Override +diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java +index fcf04c5c58ff35d38c5bf0df562ae2f8dc98a0ee..0b116160924300a9d62ad5948bfaf276f0386e4d 100644 +--- a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java ++++ b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java +@@ -10,7 +10,7 @@ import java.util.stream.Stream; + import javax.annotation.Nullable; + import net.minecraft.world.level.block.state.StateHolder; + +-public abstract class Property> { ++public abstract class Property> implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access + private final Class clazz; + private final String name; + @Nullable +@@ -24,9 +24,38 @@ public abstract class Property> { + ); + private final Codec> valueCodec = this.codec.xmap(this::value, Property.Value::value); + ++ // Paper start - optimise blockstate property access ++ private static final java.util.concurrent.atomic.AtomicInteger ID_GENERATOR = new java.util.concurrent.atomic.AtomicInteger(); ++ private final int id; ++ private T[] byId; ++ ++ @Override ++ public final int moonrise$getId() { ++ return this.id; ++ } ++ ++ @Override ++ public final T moonrise$getById(final int id) { ++ final T[] byId = this.byId; ++ return id < 0 || id >= byId.length ? null : this.byId[id]; ++ } ++ ++ @Override ++ public final void moonrise$setById(final T[] byId) { ++ if (this.byId != null) { ++ throw new IllegalStateException(); ++ } ++ this.byId = byId; ++ } ++ ++ @Override ++ public abstract int moonrise$getIdFor(final T value); ++ // Paper end - optimise blockstate property access ++ + protected Property(String name, Class type) { + this.clazz = type; + this.name = name; ++ this.id = ID_GENERATOR.getAndIncrement(); // Paper - optimise blockstate property access + } + + public Property.Value value(T value) { diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java index 37795b9e264c571efe9c718fa9996197dca4ed54..0601f454758cb1447cca2cbff4ef5fd7633fece5 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java @@ -28816,6 +30751,31 @@ index dcc0acd259920463a4464213b9a5e793603852f9..ef4161884574d3d137e12591d983dc95 @Override public BlockState getBlockState(BlockPos pos) { return Blocks.VOID_AIR.defaultBlockState(); +diff --git a/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java b/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java +index 98dbeaf8bde15940e5b5d5d1f13fd4bb32f0a10d..7beea075b5a7ef738a4ac0558b99f4c5708f2c4a 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java ++++ b/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java +@@ -8,12 +8,19 @@ import net.minecraft.network.FriendlyByteBuf; + import net.minecraft.network.VarInt; + import net.minecraft.util.CrudeIncrementalIntIdentityHashBiMap; + +-public class HashMapPalette implements Palette { ++public class HashMapPalette implements Palette, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Paper - optimise palette reads + private final IdMap registry; + private final CrudeIncrementalIntIdentityHashBiMap values; + private final PaletteResize resizeHandler; + private final int bits; + ++ // Paper start - optimise palette reads ++ @Override ++ public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData container) { ++ return ((ca.spottedleaf.moonrise.patches.fast_palette.FastPalette)this.values).moonrise$getRawPalette(container); ++ } ++ // Paper end - optimise palette reads ++ + public HashMapPalette(IdMap idList, int bits, PaletteResize listener, List entries) { + this(idList, bits, listener); + entries.forEach(this.values::add); diff --git a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java index 7cce66d4c6efe6fd3cc22a6acf72878c964c61ae..30ee3df2278d0d9bd7478b49eda5fff27b8a504c 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java @@ -28879,7 +30839,7 @@ index 7cce66d4c6efe6fd3cc22a6acf72878c964c61ae..30ee3df2278d0d9bd7478b49eda5fff2 @Override public BlockEntity getBlockEntity(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 7181acfafad91aa5f6ab7ce663d9be4a1b65b02a..a61294befc2f855fcecb2336a2d5444ce60e0a3a 100644 +index 7181acfafad91aa5f6ab7ce663d9be4a1b65b02a..a0e51681731dc7b487d5b14ae0d44a881bd5cb09 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -54,7 +54,7 @@ import net.minecraft.world.ticks.LevelChunkTicks; @@ -28887,7 +30847,7 @@ index 7181acfafad91aa5f6ab7ce663d9be4a1b65b02a..a61294befc2f855fcecb2336a2d5444c import org.slf4j.Logger; -public class LevelChunk extends ChunkAccess { -+public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk, ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk, ca.spottedleaf.moonrise.patches.chunk_getblock.GetBlockChunk { // Paper - rewrite chunk system // Paper - get block chunk optimisation ++public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk, ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk, ca.spottedleaf.moonrise.patches.getblock.GetBlockChunk { // Paper - rewrite chunk system // Paper - get block chunk optimisation static final Logger LOGGER = LogUtils.getLogger(); private static final TickingBlockEntity NULL_TICKER = new TickingBlockEntity() { @@ -28994,7 +30954,7 @@ index 7181acfafad91aa5f6ab7ce663d9be4a1b65b02a..a61294befc2f855fcecb2336a2d5444c */ org.bukkit.Chunk bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(bukkitChunk, this.needsDecoration)); -+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk().callEntitiesLoadEvent(); // Paper - rewrite chunk system ++ org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesLoadEvent(this.level, this.chunkPos, ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk().getAllEntities()); // Paper - rewrite chunk system if (this.needsDecoration) { try (co.aikar.timings.Timing ignored = this.level.timings.chunkLoadPopulate.startTiming()) { // Paper @@ -29004,7 +30964,7 @@ index 7181acfafad91aa5f6ab7ce663d9be4a1b65b02a..a61294befc2f855fcecb2336a2d5444c public void unloadCallback() { + if (!this.loadedTicketLevel) { LOGGER.error("Double calling chunk unload!", new Throwable()); } // Paper org.bukkit.Server server = this.level.getCraftServer(); -+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk().callEntitiesUnloadEvent(); // Paper - rewrite chunk system ++ org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesUnloadEvent(this.level, this.chunkPos, ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk().getAllEntities()); // Paper - rewrite chunk system org.bukkit.Chunk bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); - org.bukkit.event.world.ChunkUnloadEvent unloadEvent = new org.bukkit.event.world.ChunkUnloadEvent(bukkitChunk, this.isUnsaved()); + org.bukkit.event.world.ChunkUnloadEvent unloadEvent = new org.bukkit.event.world.ChunkUnloadEvent(bukkitChunk, true); // Paper - rewrite chunk system - force save to true so that mustNotSave is correctly set below @@ -29054,7 +31014,7 @@ index 7181acfafad91aa5f6ab7ce663d9be4a1b65b02a..a61294befc2f855fcecb2336a2d5444c @Nullable diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -index 52f44f14bbda60fe771c351e01e6ff470d7371e6..161211124f3f8390530af7ab21f3a0f1025209c5 100644 +index 52f44f14bbda60fe771c351e01e6ff470d7371e6..4167ed830382c6a76bb281e9d753919925c6bd00 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java @@ -13,7 +13,7 @@ import net.minecraft.world.level.block.Blocks; @@ -29066,20 +31026,22 @@ index 52f44f14bbda60fe771c351e01e6ff470d7371e6..161211124f3f8390530af7ab21f3a0f1 public static final int SECTION_WIDTH = 16; public static final int SECTION_HEIGHT = 16; -@@ -25,6 +25,28 @@ public class LevelChunkSection { +@@ -25,6 +25,30 @@ public class LevelChunkSection { public final PalettedContainer states; private PalettedContainer> biomes; // CraftBukkit - read/write + // Paper start - block counting -+ private static final it.unimi.dsi.fastutil.ints.IntArrayList FULL_LIST = new it.unimi.dsi.fastutil.ints.IntArrayList(16*16*16); ++ private static final it.unimi.dsi.fastutil.shorts.ShortArrayList FULL_LIST = new it.unimi.dsi.fastutil.shorts.ShortArrayList(16*16*16); + static { -+ for (int i = 0; i < (16*16*16); ++i) { ++ for (short i = 0; i < (16*16*16); ++i) { + FULL_LIST.add(i); + } + } + -+ private int specialCollidingBlocks; -+ private final ca.spottedleaf.moonrise.common.list.IBlockDataList tickingBlocks = new ca.spottedleaf.moonrise.common.list.IBlockDataList(); ++ private boolean isClient; ++ private static final short CLIENT_FORCED_SPECIAL_COLLIDING_BLOCKS = (short)9999; ++ private short specialCollidingBlocks; ++ private final ca.spottedleaf.moonrise.common.list.ShortList tickingBlocks = new ca.spottedleaf.moonrise.common.list.ShortList(); + + @Override + public final int moonrise$getSpecialCollidingBlocks() { @@ -29087,7 +31049,7 @@ index 52f44f14bbda60fe771c351e01e6ff470d7371e6..161211124f3f8390530af7ab21f3a0f1 + } + + @Override -+ public final ca.spottedleaf.moonrise.common.list.IBlockDataList moonrise$getTickingBlockList() { ++ public final ca.spottedleaf.moonrise.common.list.ShortList moonrise$getTickingBlockList() { + return this.tickingBlocks; + } + // Paper end - block counting @@ -29095,30 +31057,76 @@ index 52f44f14bbda60fe771c351e01e6ff470d7371e6..161211124f3f8390530af7ab21f3a0f1 private LevelChunkSection(LevelChunkSection section) { this.nonEmptyBlockCount = section.nonEmptyBlockCount; this.tickingBlockCount = section.tickingBlockCount; -@@ -98,6 +120,22 @@ public class LevelChunkSection { - ++this.tickingFluidCount; - } +@@ -64,6 +88,45 @@ public class LevelChunkSection { + return this.setBlockState(x, y, z, state, true); + } -+ // Paper start - block counting -+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(iblockdata1)) { -+ --this.specialCollidingBlocks; ++ // Paper start - block counting ++ private void updateBlockCallback(final int x, final int y, final int z, final BlockState newState, ++ final BlockState oldState) { ++ if (oldState == newState) { ++ return; + } -+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(state)) { -+ ++this.specialCollidingBlocks; ++ ++ if (this.isClient) { ++ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(newState)) { ++ this.specialCollidingBlocks = CLIENT_FORCED_SPECIAL_COLLIDING_BLOCKS; ++ } ++ return; + } + -+ if (iblockdata1.isRandomlyTicking()) { -+ this.tickingBlocks.remove(x, y, z); ++ final boolean isSpecialOld = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(oldState); ++ final boolean isSpecialNew = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(newState); ++ if (isSpecialOld != isSpecialNew) { ++ if (isSpecialOld) { ++ --this.specialCollidingBlocks; ++ } else { ++ ++this.specialCollidingBlocks; ++ } + } -+ if (state.isRandomlyTicking()) { -+ this.tickingBlocks.add(x, y, z, state); ++ ++ final boolean oldTicking = oldState.isRandomlyTicking(); ++ final boolean newTicking = newState.isRandomlyTicking(); ++ if (oldTicking != newTicking) { ++ final ca.spottedleaf.moonrise.common.list.ShortList tickingBlocks = this.tickingBlocks; ++ final short position = (short)(x | (z << 4) | (y << (4+4))); ++ ++ if (oldTicking) { ++ tickingBlocks.remove(position); ++ } else { ++ tickingBlocks.add(position); ++ } + } -+ // Paper end - block counting ++ } ++ // Paper end - block counting ++ + public BlockState setBlockState(int x, int y, int z, BlockState state, boolean lock) { + BlockState iblockdata1; + +@@ -83,7 +146,7 @@ public class LevelChunkSection { + } + } + +- if (!fluid.isEmpty()) { ++ if (!!fluid.isRandomlyTicking()) { // Paper - block counting + --this.tickingFluidCount; + } + +@@ -94,10 +157,12 @@ public class LevelChunkSection { + } + } + +- if (!fluid1.isEmpty()) { ++ if (!!fluid1.isRandomlyTicking()) { // Paper - block counting + ++this.tickingFluidCount; + } + ++ this.updateBlockCallback(x, y, z, state, iblockdata1); // Paper - block counting + return iblockdata1; } -@@ -118,40 +156,65 @@ public class LevelChunkSection { +@@ -118,40 +183,70 @@ public class LevelChunkSection { } public void recalcBlockCounts() { @@ -29137,47 +31145,52 @@ index 52f44f14bbda60fe771c351e01e6ff470d7371e6..161211124f3f8390530af7ab21f3a0f1 + final int paletteSize = palette.getSize(); + final net.minecraft.util.BitStorage storage = data.storage(); + -+ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap counts; ++ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap counts; + if (paletteSize == 1) { + counts = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1); + counts.put(0, FULL_LIST); + } else { + counts = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingBitStorage)storage).moonrise$countEntries(); + } ++ ++ for (final java.util.Iterator> iterator = counts.int2ObjectEntrySet().fastIterator(); iterator.hasNext();) { ++ final it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry entry = iterator.next(); ++ final int paletteIdx = entry.getIntKey(); ++ final it.unimi.dsi.fastutil.shorts.ShortArrayList coordinates = entry.getValue(); ++ final int paletteCount = coordinates.size(); - public int nonEmptyBlockCount; - public int tickingBlockCount; - public int tickingFluidCount; -+ for (final java.util.Iterator> iterator = counts.int2ObjectEntrySet().fastIterator(); iterator.hasNext();) { -+ final it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry entry = iterator.next(); -+ final int paletteIdx = entry.getIntKey(); -+ final it.unimi.dsi.fastutil.ints.IntArrayList coordinates = entry.getValue(); -+ final int paletteCount = coordinates.size(); - -- a(final LevelChunkSection chunksection) {} + final BlockState state = palette.valueFor(paletteIdx); -- public void accept(BlockState iblockdata, int i) { -- FluidState fluid = iblockdata.getFluidState(); +- a(final LevelChunkSection chunksection) {} + if (state.isAir()) { + continue; + } ++ ++ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(state)) { ++ this.specialCollidingBlocks += (short)paletteCount; ++ } ++ this.nonEmptyBlockCount += (short)paletteCount; ++ if (state.isRandomlyTicking()) { ++ this.tickingBlockCount += (short)paletteCount; ++ final short[] raw = coordinates.elements(); ++ final int rawLen = raw.length; ++ ++ final ca.spottedleaf.moonrise.common.list.ShortList tickingBlocks = this.tickingBlocks; + +- public void accept(BlockState iblockdata, int i) { +- FluidState fluid = iblockdata.getFluidState(); ++ tickingBlocks.setMinCapacity(Math.min((rawLen + tickingBlocks.size()) * 3 / 2, 16*16*16)); - if (!iblockdata.isAir()) { - this.nonEmptyBlockCount += i; - if (iblockdata.isRandomlyTicking()) { - this.tickingBlockCount += i; -+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(state)) { -+ this.specialCollidingBlocks += paletteCount; -+ } -+ this.nonEmptyBlockCount += paletteCount; -+ if (state.isRandomlyTicking()) { -+ this.tickingBlockCount += paletteCount; -+ final int[] raw = coordinates.elements(); -+ + java.util.Objects.checkFromToIndex(0, paletteCount, raw.length); + for (int i = 0; i < paletteCount; ++i) { -+ this.tickingBlocks.add(raw[i], state); ++ tickingBlocks.add(raw[i]); } } @@ -29185,10 +31198,10 @@ index 52f44f14bbda60fe771c351e01e6ff470d7371e6..161211124f3f8390530af7ab21f3a0f1 + if (!fluid.isEmpty()) { - this.nonEmptyBlockCount += i; -+ //this.nonEmptyBlockCount += count; // fix vanilla bug: make non empty block count correct ++ //this.nonEmptyBlockCount += count; // fix vanilla bug: make non-empty block count correct if (fluid.isRandomlyTicking()) { - this.tickingFluidCount += i; -+ this.tickingFluidCount += paletteCount; ++ this.tickingFluidCount += (short)paletteCount; } } - @@ -29205,16 +31218,59 @@ index 52f44f14bbda60fe771c351e01e6ff470d7371e6..161211124f3f8390530af7ab21f3a0f1 } public PalettedContainer getStates() { -@@ -169,6 +232,7 @@ public class LevelChunkSection { +@@ -169,6 +264,11 @@ public class LevelChunkSection { datapaletteblock.read(buf); this.biomes = datapaletteblock; -+ this.recalcBlockCounts(); // Paper - block counting ++ // Paper start - block counting ++ this.isClient = true; ++ // force has special colliding blocks to be true ++ this.specialCollidingBlocks = this.nonEmptyBlockCount != (short)0 && this.maybeHas(ca.spottedleaf.moonrise.patches.collisions.CollisionUtil::isSpecialCollidingBlock) ? CLIENT_FORCED_SPECIAL_COLLIDING_BLOCKS : (short)0; ++ // Paper end - block counting } public void readBiomes(FriendlyByteBuf buf) { +diff --git a/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java b/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java +index bc4d9452bbeb05a691fd285603e49491f41d3ad2..f8d9892970c9092f7cc84434d4fbf34354ce1195 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java ++++ b/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java +@@ -7,13 +7,20 @@ import net.minecraft.network.FriendlyByteBuf; + import net.minecraft.network.VarInt; + import org.apache.commons.lang3.Validate; + +-public class LinearPalette implements Palette { ++public class LinearPalette implements Palette, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Paper - optimise palette reads + private final IdMap registry; + private final T[] values; + private final PaletteResize resizeHandler; + private final int bits; + private int size; + ++ // Paper start - optimise palette reads ++ @Override ++ public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData container) { ++ return this.values; ++ } ++ // Paper end - optimise palette reads ++ + private LinearPalette(IdMap idList, int bits, PaletteResize listener, List list) { + this.registry = idList; + this.values = (T[])(new Object[1 << bits]); +diff --git a/src/main/java/net/minecraft/world/level/chunk/Palette.java b/src/main/java/net/minecraft/world/level/chunk/Palette.java +index b8922e4a13df535cdc5701e893a6e460b33ff90d..100807f8b8337f56f49cdb818ccc75be2f08ecd1 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/Palette.java ++++ b/src/main/java/net/minecraft/world/level/chunk/Palette.java +@@ -5,7 +5,7 @@ import java.util.function.Predicate; + import net.minecraft.core.IdMap; + import net.minecraft.network.FriendlyByteBuf; + +-public interface Palette { ++public interface Palette extends ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Paper - optimise palette reads + int idFor(T object); + + boolean maybeHas(Predicate predicate); diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -index 112d1259dd37743076ff6c67ffd711d084ba8698..b46c58c952e183bd74854c3eb70d64979af70f18 100644 +index 112d1259dd37743076ff6c67ffd711d084ba8698..533167eaa8bd39006fb1c7e193c81359973da9af 100644 --- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java @@ -28,7 +28,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer @@ -29226,15 +31282,156 @@ index 112d1259dd37743076ff6c67ffd711d084ba8698..b46c58c952e183bd74854c3eb70d6497 private final PalettedContainer.Strategy strategy; // private final ThreadingDetector threadingDetector = new ThreadingDetector("PalettedContainer"); // Paper - unused -@@ -161,7 +161,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -71,6 +71,33 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + ); + } + ++ // Paper start - optimise palette reads ++ private void updateData(final PalettedContainer.Data data) { ++ if (data != null) { ++ ((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData)(Object)data).moonrise$setPalette( ++ ((ca.spottedleaf.moonrise.patches.fast_palette.FastPalette)data.palette).moonrise$getRawPalette((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData)(Object)data) ++ ); ++ } ++ } ++ ++ private T readPaletteSlow(final PalettedContainer.Data data, final int paletteIdx) { ++ return data.palette.valueFor(paletteIdx); ++ } ++ ++ private T readPalette(final PalettedContainer.Data data, final int paletteIdx) { ++ final T[] palette = ((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData)(Object)data).moonrise$getPalette(); ++ if (palette == null) { ++ return this.readPaletteSlow(data, paletteIdx); ++ } ++ ++ final T ret = palette[paletteIdx]; ++ if (ret == null) { ++ throw new IllegalArgumentException("Palette index out of bounds"); ++ } ++ return ret; ++ } ++ // Paper end - optimise palette reads ++ + public PalettedContainer( + IdMap idList, + PalettedContainer.Strategy paletteProvider, +@@ -81,12 +108,14 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + this.registry = idList; + this.strategy = paletteProvider; + this.data = new PalettedContainer.Data<>(dataProvider, storage, dataProvider.factory().create(dataProvider.bits(), idList, this, paletteEntries)); ++ this.updateData(this.data); // Paper - optimise palette reads + } + + private PalettedContainer(IdMap idList, PalettedContainer.Strategy paletteProvider, PalettedContainer.Data data) { + this.registry = idList; + this.strategy = paletteProvider; + this.data = data; ++ this.updateData(this.data); // Paper - optimise palette reads + } + + private PalettedContainer(PalettedContainer container) { +@@ -100,6 +129,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + this.registry = idList; + this.data = this.createOrReuseData(null, 0); + this.data.palette.idFor(object); ++ this.updateData(this.data); // Paper - optimise palette reads + } + + private PalettedContainer.Data createOrReuseData(@Nullable PalettedContainer.Data previousData, int bits) { +@@ -115,6 +145,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + PalettedContainer.Data data2 = this.createOrReuseData(data, newBits); + data2.copyFrom(data.palette, data.storage); + this.data = data2; ++ this.updateData(this.data); // Paper - optimise palette reads + return data2.palette.idFor(object); + } + +@@ -136,9 +167,12 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + } + + private synchronized T getAndSet(int index, T value) { // Paper - synchronize +- int i = this.data.palette.idFor(value); +- int j = this.data.storage.getAndSet(index, i); +- return this.data.palette.valueFor(j); ++ // Paper start - optimise palette reads ++ final int paletteIdx = this.data.palette.idFor(value); ++ final PalettedContainer.Data data = this.data; ++ final int prev = data.storage.getAndSet(index, paletteIdx); ++ return this.readPalette(data, prev); ++ // Paper end - optimise palette reads + } + + public void set(int x, int y, int z, T value) { +@@ -161,9 +195,11 @@ public class PalettedContainer implements PaletteResize, PalettedContainer return this.get(this.strategy.getIndex(x, y, z)); } - protected T get(int index) { +- PalettedContainer.Data data = this.data; +- return data.palette.valueFor(data.storage.get(index)); + public T get(int index) { // Paper - public - PalettedContainer.Data data = this.data; - return data.palette.valueFor(data.storage.get(index)); ++ // Paper start - optimise palette reads ++ final PalettedContainer.Data data = this.data; ++ return this.readPalette(data, data.storage.get(index)); ++ // Paper end - optimise palette reads } + + @Override +@@ -183,6 +219,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + data.palette.read(buf); + buf.readLongArray(data.storage.getRaw()); + this.data = data; ++ this.updateData(this.data); // Paper - optimise palette reads + } finally { + this.release(); + } +@@ -323,7 +360,44 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + void accept(T object, int count); + } + +- static record Data(PalettedContainer.Configuration configuration, BitStorage storage, Palette palette) { ++ // Paper start - optimise palette reads ++ public static final class Data implements ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData { ++ ++ private final PalettedContainer.Configuration configuration; ++ private final BitStorage storage; ++ private final Palette palette; ++ ++ private T[] moonrise$palette; ++ ++ public Data(final PalettedContainer.Configuration configuration, final BitStorage storage, final Palette palette) { ++ this.configuration = configuration; ++ this.storage = storage; ++ this.palette = palette; ++ } ++ ++ public PalettedContainer.Configuration configuration() { ++ return this.configuration; ++ } ++ ++ public BitStorage storage() { ++ return this.storage; ++ } ++ ++ public Palette palette() { ++ return this.palette; ++ } ++ ++ @Override ++ public final T[] moonrise$getPalette() { ++ return this.moonrise$palette; ++ } ++ ++ @Override ++ public final void moonrise$setPalette(final T[] palette) { ++ this.moonrise$palette = palette; ++ } ++ // Paper end - optimise palette reads ++ + public void copyFrom(Palette palette, BitStorage storage) { + for (int i = 0; i < storage.getSize(); i++) { + T object = palette.valueFor(storage.get(i)); diff --git a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java index 5321109ca638036572df9a7e17eafcef2b4f5112..5304254587372465c8ce821d7aa38b39a979f46b 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java @@ -29248,6 +31445,60 @@ index 5321109ca638036572df9a7e17eafcef2b4f5112..5304254587372465c8ce821d7aa38b39 this.lightEngine.checkBlock(pos); } } +diff --git a/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java b/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java +index a45e6410600afc5464e5d29932c193786ce0a6fb..a1ba68c95c2cdebdc0d7782cce7895529918073c 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java ++++ b/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java +@@ -8,12 +8,24 @@ import net.minecraft.network.FriendlyByteBuf; + import net.minecraft.network.VarInt; + import org.apache.commons.lang3.Validate; + +-public class SingleValuePalette implements Palette { ++public class SingleValuePalette implements Palette, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Paper - optimise palette reads + private final IdMap registry; + @Nullable + private T value; + private final PaletteResize resizeHandler; + ++ // Paper start - optimise palette reads ++ private T[] rawPalette; ++ ++ @Override ++ public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData container) { ++ if (this.rawPalette != null) { ++ return this.rawPalette; ++ } ++ return this.rawPalette = (T[])new Object[] { this.value }; ++ } ++ // Paper end - optimise palette reads ++ + public SingleValuePalette(IdMap idList, PaletteResize listener, List entries) { + this.registry = idList; + this.resizeHandler = listener; +@@ -33,6 +45,11 @@ public class SingleValuePalette implements Palette { + return this.resizeHandler.onResize(1, object); + } else { + this.value = object; ++ // Paper start - optimise palette reads ++ if (this.rawPalette != null) { ++ this.rawPalette[0] = object; ++ } ++ // Paper end - optimise palette reads + return 0; + } + } +@@ -58,6 +75,11 @@ public class SingleValuePalette implements Palette { + @Override + public void read(FriendlyByteBuf buf) { + this.value = this.registry.byIdOrThrow(buf.readVarInt()); ++ // Paper start - optimise palette reads ++ if (this.rawPalette != null) { ++ this.rawPalette[0] = this.value; ++ } ++ // Paper end - optimise palette reads + } + + @Override diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkPyramid.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkPyramid.java index b1058bf0dcda544a074f4d3772d7899b94f98927..b7bf82f6b6023bd628d3e7ea84d2d6755a0d931a 100644 --- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkPyramid.java @@ -29647,8 +31898,100 @@ index cb823d342e41b5861adfc847a313c265fb702a4c..2b1ea97199d5976e5ff4bd049c1e6c8b private final SequencedMap pendingWrites = new LinkedHashMap<>(); private final Long2ObjectLinkedOpenHashMap> regionCacheForBlender = new Long2ObjectLinkedOpenHashMap<>(); private static final int REGION_CACHE_SIZE = 1024; +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 f1237f6fd6414900ffbad0caee31aa83310eeef4..8071ce70d66909bb4bda45792bf329a939d6f918 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 +@@ -25,7 +25,7 @@ import net.minecraft.util.profiling.jfr.JvmProfiler; + import net.minecraft.world.level.ChunkPos; + import org.slf4j.Logger; + +-public class RegionFile implements AutoCloseable { ++public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile { // Paper - rewrite chunk system + + private static final Logger LOGGER = LogUtils.getLogger(); + private static final int SECTOR_BYTES = 4096; +@@ -49,6 +49,21 @@ public class RegionFile implements AutoCloseable { + @VisibleForTesting + protected final RegionBitmap usedSectors; + ++ // Paper start - rewrite chunk system ++ @Override ++ public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite(final net.minecraft.nbt.CompoundTag data, final ChunkPos pos) throws IOException { ++ final RegionFile.ChunkBuffer buffer = ((RegionFile)(Object)this).new ChunkBuffer(pos); ++ ((ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkBuffer)buffer).moonrise$setWriteOnClose(false); ++ ++ final DataOutputStream out = new DataOutputStream(this.version.wrap(buffer)); ++ ++ return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData( ++ data, ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData.WriteResult.WRITE, ++ out, ((ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkBuffer)buffer)::moonrise$write ++ ); ++ } ++ // Paper end - rewrite chunk system ++ + public RegionFile(RegionStorageInfo storageKey, Path directory, Path path, boolean dsync) throws IOException { + this(storageKey, directory, path, RegionFileVersion.getSelected(), dsync); + } +@@ -220,6 +235,16 @@ public class RegionFile implements AutoCloseable { + + @Nullable + private DataInputStream createExternalChunkInputStream(ChunkPos pos, byte flags) throws IOException { ++ // Paper start - rewrite chunk system ++ final DataInputStream is = this.createExternalChunkInputStream0(pos, flags); ++ if (is == null) { ++ return is; ++ } ++ return new ca.spottedleaf.moonrise.patches.chunk_system.util.stream.ExternalChunkStreamMarker(is); ++ } ++ @Nullable ++ private DataInputStream createExternalChunkInputStream0(ChunkPos pos, byte flags) throws IOException { ++ // Paper end - rewrite chunk system + Path path = this.getExternalChunkPath(pos); + + if (!Files.isRegularFile(path, new LinkOption[0])) { +@@ -443,10 +468,29 @@ public class RegionFile implements AutoCloseable { + } + + public static final int MAX_CHUNK_SIZE = 500 * 1024 * 1024; // Paper - don't write garbage data to disk if writing serialization fails +- private class ChunkBuffer extends ByteArrayOutputStream { ++ private class ChunkBuffer extends ByteArrayOutputStream implements ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkBuffer { // Paper - rewrite chunk system + + private final ChunkPos pos; + ++ // Paper start - rewrite chunk system ++ private boolean writeOnClose = true; ++ ++ @Override ++ public final boolean moonrise$getWriteOnClose() { ++ return this.writeOnClose; ++ } ++ ++ @Override ++ public final void moonrise$setWriteOnClose(final boolean value) { ++ this.writeOnClose = value; ++ } ++ ++ @Override ++ public final void moonrise$write(final RegionFile regionFile) throws IOException { ++ regionFile.write(this.pos, ByteBuffer.wrap(this.buf, 0, this.count)); ++ } ++ // Paper end - rewrite chunk system ++ + public ChunkBuffer(final ChunkPos chunkcoordintpair) { + super(8096); + super.write(0); +@@ -480,7 +524,7 @@ public class RegionFile implements AutoCloseable { + + JvmProfiler.INSTANCE.onRegionFileWrite(RegionFile.this.info, this.pos, RegionFile.this.version, i); + bytebuffer.putInt(0, i); +- RegionFile.this.write(this.pos, bytebuffer); ++ if (this.writeOnClose) { RegionFile.this.write(this.pos, bytebuffer); } // Paper - rewrite chunk system + } + } + 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 4c1212c6ef48594e766fa9e35a6e15916602d587..18054304e08c8a6346c0135a0e6a68e77fe5c37c 100644 +index 4c1212c6ef48594e766fa9e35a6e15916602d587..9dbc9e2f9d5aab71720bb81803efe76e2f361f04 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 @@ -17,7 +17,7 @@ import net.minecraft.nbt.StreamTagVisitor; @@ -29660,15 +32003,15 @@ index 4c1212c6ef48594e766fa9e35a6e15916602d587..18054304e08c8a6346c0135a0e6a68e7 public static final String ANVIL_EXTENSION = ".mca"; private static final int MAX_CACHE_SIZE = 256; -@@ -26,33 +26,122 @@ public final class RegionFileStorage implements AutoCloseable { +@@ -26,33 +26,219 @@ public final class RegionFileStorage implements AutoCloseable { private final Path folder; private final boolean sync; - RegionFileStorage(RegionStorageInfo storageKey, Path directory, boolean dsync) { + // Paper start - rewrite chunk system + private static final int REGION_SHIFT = 5; -+ private static final int MAX_NON_EXISTING_CACHE = 1024 * 64; -+ private final it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet nonExistingRegionFiles = new it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet(MAX_NON_EXISTING_CACHE+1); ++ private static final int MAX_NON_EXISTING_CACHE = 1024 * 4; ++ private final it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet nonExistingRegionFiles = new it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet(); + private static String getRegionFileName(final int chunkX, final int chunkZ) { + return "r." + (chunkX >> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + ".mca"; + } @@ -29743,6 +32086,97 @@ index 4c1212c6ef48594e766fa9e35a6e15916602d587..18054304e08c8a6346c0135a0e6a68e7 + + return ret; + } ++ ++ @Override ++ public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite( ++ final int chunkX, final int chunkZ, final CompoundTag compound ++ ) throws IOException { ++ if (compound == null) { ++ return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData( ++ compound, ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData.WriteResult.DELETE, ++ null, null ++ ); ++ } ++ ++ final ChunkPos pos = new ChunkPos(chunkX, chunkZ); ++ final RegionFile regionFile = this.getRegionFile(pos); ++ ++ // note: not required to keep regionfile loaded after this call, as the write param takes a regionfile as input ++ // (and, the regionfile parameter is unused for writing until the write call) ++ final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData writeData = ((ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile)regionFile).moonrise$startWrite(compound, pos); ++ ++ try { ++ NbtIo.write(compound, writeData.output()); ++ } finally { ++ writeData.output().close(); ++ } ++ ++ return writeData; ++ } ++ ++ @Override ++ public final void moonrise$finishWrite( ++ final int chunkX, final int chunkZ, final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData writeData ++ ) throws IOException { ++ final ChunkPos pos = new ChunkPos(chunkX, chunkZ); ++ if (writeData.result() == ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData.WriteResult.DELETE) { ++ final RegionFile regionFile = this.moonrise$getRegionFileIfExists(chunkX, chunkZ); ++ if (regionFile != null) { ++ regionFile.clear(pos); ++ } // else: didn't exist ++ ++ return; ++ } ++ ++ writeData.write().run(this.getRegionFile(pos)); ++ } ++ ++ @Override ++ public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData moonrise$readData( ++ final int chunkX, final int chunkZ ++ ) throws IOException { ++ final RegionFile regionFile = this.moonrise$getRegionFileIfExists(chunkX, chunkZ); ++ ++ final DataInputStream input = regionFile == null ? null : regionFile.getChunkDataInputStream(new ChunkPos(chunkX, chunkZ)); ++ ++ if (input == null) { ++ return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData( ++ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.NO_DATA, null, null ++ ); ++ } ++ ++ final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData ret = new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData( ++ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.HAS_DATA, input, null ++ ); ++ ++ if (!(input instanceof ca.spottedleaf.moonrise.patches.chunk_system.util.stream.ExternalChunkStreamMarker)) { ++ // internal stream, which is fully read ++ return ret; ++ } ++ ++ final CompoundTag syncRead = this.moonrise$finishRead(chunkX, chunkZ, ret); ++ ++ if (syncRead == null) { ++ // need to try again ++ return this.moonrise$readData(chunkX, chunkZ); ++ } ++ ++ return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData( ++ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.SYNC_READ, null, syncRead ++ ); ++ } ++ ++ // if the return value is null, then the caller needs to re-try with a new call to readData() ++ @Override ++ public final CompoundTag moonrise$finishRead( ++ final int chunkX, final int chunkZ, final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData readData ++ ) throws IOException { ++ try { ++ return NbtIo.read(readData.input()); ++ } finally { ++ readData.input().close(); ++ } ++ } + // Paper end - rewrite chunk system + + protected RegionFileStorage(RegionStorageInfo storageKey, Path directory, boolean dsync) { // Paper - protected @@ -29754,6 +32188,17 @@ index 4c1212c6ef48594e766fa9e35a6e15916602d587..18054304e08c8a6346c0135a0e6a68e7 - private RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit - long i = ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ()); - RegionFile regionfile = (RegionFile) this.regionCache.getAndMoveToFirst(i); ++ // Paper start - rewrite chunk system ++ public RegionFile getRegionFile(ChunkPos chunkcoordintpair) throws IOException { ++ return this.getRegionFile(chunkcoordintpair, false); ++ } ++ // Paper end - rewrite chunk system + +- if (regionfile != null) { +- return regionfile; +- } else { +- if (this.regionCache.size() >= io.papermc.paper.configuration.GlobalConfiguration.get().misc.regionFileCacheSize) { // Paper - Sanitise RegionFileCache and make configurable +- ((RegionFile) this.regionCache.removeLast()).close(); + public RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit // Paper - public + // Paper start - rewrite chunk system + if (existingOnly) { @@ -29761,12 +32206,7 @@ index 4c1212c6ef48594e766fa9e35a6e15916602d587..18054304e08c8a6346c0135a0e6a68e7 + } + synchronized (this) { + final long key = ChunkPos.asLong(chunkcoordintpair.x >> REGION_SHIFT, chunkcoordintpair.z >> REGION_SHIFT); - -- if (regionfile != null) { -- return regionfile; -- } else { -- if (this.regionCache.size() >= io.papermc.paper.configuration.GlobalConfiguration.get().misc.regionFileCacheSize) { // Paper - Sanitise RegionFileCache and make configurable -- ((RegionFile) this.regionCache.removeLast()).close(); ++ + RegionFile ret = this.regionCache.getAndMoveToFirst(key); + if (ret != null) { + return ret; @@ -29799,7 +32239,7 @@ index 4c1212c6ef48594e766fa9e35a6e15916602d587..18054304e08c8a6346c0135a0e6a68e7 } @Nullable -@@ -132,8 +221,14 @@ public final class RegionFileStorage implements AutoCloseable { +@@ -132,8 +318,14 @@ public final class RegionFileStorage implements AutoCloseable { } @@ -29816,7 +32256,7 @@ index 4c1212c6ef48594e766fa9e35a6e15916602d587..18054304e08c8a6346c0135a0e6a68e7 // Paper start - Chunk save reattempt int attempts = 0; Exception lastException = null; -@@ -182,30 +277,37 @@ public final class RegionFileStorage implements AutoCloseable { +@@ -182,30 +374,37 @@ public final class RegionFileStorage implements AutoCloseable { } public void close() throws IOException { @@ -30393,6 +32833,257 @@ index 8d90e783967280025d711c709facbcc87f611f8a..987e3397503cd07d3a2f172cede34129 } public int getLightSectionCount() { +diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +index 261e5994d13f8bc30490b86691c80c0a21e7640a..f4fbcbb8ff6d2677af1a02a0801a323c06dce9b1 100644 +--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java ++++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +@@ -55,6 +55,48 @@ public abstract class FlowingFluid extends Fluid { + }); + private final Map shapes = Maps.newIdentityHashMap(); + ++ // Paper start - fluid method optimisations ++ private FluidState sourceFalling; ++ private FluidState sourceNotFalling; ++ ++ private static final int TOTAL_FLOWING_STATES = FALLING.getPossibleValues().size() * LEVEL.getPossibleValues().size(); ++ private static final int MIN_LEVEL = LEVEL.getPossibleValues().stream().sorted().findFirst().get().intValue(); ++ ++ // index = (falling ? 1 : 0) + level*2 ++ private FluidState[] flowingLookUp; ++ private volatile boolean init; ++ ++ private static final int COLLISION_OCCLUSION_CACHE_SIZE = 2048; ++ private static final ThreadLocal COLLISION_OCCLUSION_CACHE = ThreadLocal.withInitial(() -> new ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey[COLLISION_OCCLUSION_CACHE_SIZE]); ++ ++ ++ /** ++ * Due to init order, we need to use callbacks to initialise our state ++ */ ++ private void init() { ++ synchronized (this) { ++ if (this.init) { ++ return; ++ } ++ this.flowingLookUp = new FluidState[TOTAL_FLOWING_STATES]; ++ final FluidState defaultFlowState = this.getFlowing().defaultFluidState(); ++ for (int i = 0; i < TOTAL_FLOWING_STATES; ++i) { ++ final int falling = i & 1; ++ final int level = (i >>> 1) + MIN_LEVEL; ++ ++ this.flowingLookUp[i] = defaultFlowState.setValue(FALLING, falling == 1 ? Boolean.TRUE : Boolean.FALSE) ++ .setValue(LEVEL, Integer.valueOf(level)); ++ } ++ ++ final FluidState defaultFallState = this.getSource().defaultFluidState(); ++ this.sourceFalling = defaultFallState.setValue(FALLING, Boolean.TRUE); ++ this.sourceNotFalling = defaultFallState.setValue(FALLING, Boolean.FALSE); ++ ++ this.init = true; ++ } ++ } ++ // Paper end - fluid method optimisations ++ + public FlowingFluid() {} + + @Override +@@ -246,65 +288,70 @@ public abstract class FlowingFluid extends Fluid { + } + } + +- private static boolean canPassThroughWall(Direction face, BlockGetter world, BlockPos pos, BlockState state, BlockPos fromPos, BlockState fromState) { +- VoxelShape voxelshape = fromState.getCollisionShape(world, fromPos); ++ // Paper start - fluid method optimisations ++ private static boolean canPassThroughWall(final Direction direction, final BlockGetter level, ++ final BlockPos fromPos, final BlockState fromState, ++ final BlockPos toPos, final BlockState toState) { ++ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$emptyCollisionShape() & ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$emptyCollisionShape()) { ++ // don't even try to cache simple cases ++ return true; ++ } + +- if (voxelshape == Shapes.block()) { ++ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$occludesFullBlock() | ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$occludesFullBlock()) { ++ // don't even try to cache simple cases + return false; +- } else { +- VoxelShape voxelshape1 = state.getCollisionShape(world, pos); +- +- if (voxelshape1 == Shapes.block()) { +- return false; +- } else if (voxelshape1 == Shapes.empty() && voxelshape == Shapes.empty()) { +- return true; +- } else { +- Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap; +- +- if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) { +- object2bytelinkedopenhashmap = (Object2ByteLinkedOpenHashMap) FlowingFluid.OCCLUSION_CACHE.get(); +- } else { +- object2bytelinkedopenhashmap = null; +- } ++ } + +- FlowingFluid.BlockStatePairKey fluidtypeflowing_a; ++ final ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey[] cache = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$hasCache() & ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$hasCache() ? ++ COLLISION_OCCLUSION_CACHE.get() : null; + +- if (object2bytelinkedopenhashmap != null) { +- fluidtypeflowing_a = new FlowingFluid.BlockStatePairKey(state, fromState, face); +- byte b0 = object2bytelinkedopenhashmap.getAndMoveToFirst(fluidtypeflowing_a); ++ final int keyIndex ++ = (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$uniqueId1() ^ ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$uniqueId2() ^ ((ca.spottedleaf.moonrise.patches.collisions.util.CollisionDirection)(Object)direction).moonrise$uniqueId()) ++ & (COLLISION_OCCLUSION_CACHE_SIZE - 1); + +- if (b0 != 127) { +- return b0 != 0; +- } +- } else { +- fluidtypeflowing_a = null; +- } +- +- boolean flag = !Shapes.mergedFaceOccludes(voxelshape1, voxelshape, face); ++ if (cache != null) { ++ final ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey cached = cache[keyIndex]; ++ if (cached != null && cached.first() == fromState && cached.second() == toState && cached.direction() == direction) { ++ return cached.result(); ++ } ++ } + +- if (object2bytelinkedopenhashmap != null) { +- if (object2bytelinkedopenhashmap.size() == 200) { +- object2bytelinkedopenhashmap.removeLastByte(); +- } ++ final VoxelShape shape1 = fromState.getCollisionShape(level, fromPos); ++ final VoxelShape shape2 = toState.getCollisionShape(level, toPos); + +- object2bytelinkedopenhashmap.putAndMoveToFirst(fluidtypeflowing_a, (byte) (flag ? 1 : 0)); +- } ++ final boolean result = !Shapes.mergedFaceOccludes(shape1, shape2, direction); + +- return flag; +- } ++ if (cache != null) { ++ // we can afford to replace in-use keys more often due to the excessive caching the collision patch does in mergedFaceOccludes ++ cache[keyIndex] = new ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey(fromState, toState, direction, result); + } ++ ++ return result; + } ++ // Paper end - fluid method optimisations + + public abstract Fluid getFlowing(); + + public FluidState getFlowing(int level, boolean falling) { +- return (FluidState) ((FluidState) this.getFlowing().defaultFluidState().setValue(FlowingFluid.LEVEL, level)).setValue(FlowingFluid.FALLING, falling); ++ // Paper start - fluid method optimisations ++ final int amount = level; ++ if (!this.init) { ++ this.init(); ++ } ++ final int index = (falling ? 1 : 0) | ((amount - MIN_LEVEL) << 1); ++ return this.flowingLookUp[index]; ++ // Paper end - fluid method optimisations + } + + public abstract Fluid getSource(); + + public FluidState getSource(boolean falling) { +- return (FluidState) this.getSource().defaultFluidState().setValue(FlowingFluid.FALLING, falling); ++ // Paper start - fluid method optimisations ++ if (!this.init) { ++ this.init(); ++ } ++ return falling ? this.sourceFalling : this.sourceNotFalling; ++ // Paper end - fluid method optimisations + } + + protected abstract boolean canConvertToSource(ServerLevel world); +diff --git a/src/main/java/net/minecraft/world/level/material/FluidState.java b/src/main/java/net/minecraft/world/level/material/FluidState.java +index 87adfe152abd1b8b4d547034576883c5d1cdf134..2d50d72bf026d0cf9c546a3c6fc1859379bfd805 100644 +--- a/src/main/java/net/minecraft/world/level/material/FluidState.java ++++ b/src/main/java/net/minecraft/world/level/material/FluidState.java +@@ -22,12 +22,30 @@ import net.minecraft.world.level.block.state.properties.Property; + import net.minecraft.world.phys.Vec3; + import net.minecraft.world.phys.shapes.VoxelShape; + +-public final class FluidState extends StateHolder { ++public final class FluidState extends StateHolder implements ca.spottedleaf.moonrise.patches.fluid.FluidFluidState { // Paper - fluid method optimisations + public static final Codec CODEC = codec(BuiltInRegistries.FLUID.byNameCodec(), Fluid::defaultFluidState).stable(); + public static final int AMOUNT_MAX = 9; + public static final int AMOUNT_FULL = 8; + protected final boolean isEmpty; // Paper - Perf: moved from isEmpty() + ++ // Paper start - fluid method optimisations ++ private int amount; ++ //private boolean isEmpty; ++ private boolean isSource; ++ private float ownHeight; ++ private boolean isRandomlyTicking; ++ private BlockState legacyBlock; ++ ++ @Override ++ public final void moonrise$initCaches() { ++ this.amount = this.getType().getAmount((FluidState)(Object)this); ++ //this.isEmpty = this.getType().isEmpty(); ++ this.isSource = this.getType().isSource((FluidState)(Object)this); ++ this.ownHeight = this.getType().getOwnHeight((FluidState)(Object)this); ++ this.isRandomlyTicking = this.getType().isRandomlyTicking(); ++ } ++ // Paper end - fluid method optimisations ++ + public FluidState(Fluid fluid, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { + super(fluid, propertyMap, codec); + this.isEmpty = fluid.isEmpty(); // Paper - Perf: moved from isEmpty() +@@ -38,11 +56,11 @@ public final class FluidState extends StateHolder { + } + + public boolean isSource() { +- return this.getType().isSource(this); ++ return this.isSource; // Paper - fluid method optimisations + } + + public boolean isSourceOfType(Fluid fluid) { +- return this.owner == fluid && this.owner.isSource(this); ++ return this.isSource && this.owner == fluid; // Paper - fluid method optimisations + } + + public boolean isEmpty() { +@@ -54,11 +72,11 @@ public final class FluidState extends StateHolder { + } + + public float getOwnHeight() { +- return this.getType().getOwnHeight(this); ++ return this.ownHeight; // Paper - fluid method optimisations + } + + public int getAmount() { +- return this.getType().getAmount(this); ++ return this.amount; // Paper - fluid method optimisations + } + + public boolean shouldRenderBackwardUpFace(BlockGetter world, BlockPos pos) { +@@ -84,7 +102,7 @@ public final class FluidState extends StateHolder { + } + + public boolean isRandomlyTicking() { +- return this.getType().isRandomlyTicking(); ++ return this.isRandomlyTicking; // Paper - fluid method optimisations + } + + public void randomTick(ServerLevel world, BlockPos pos, RandomSource random) { +@@ -96,7 +114,12 @@ public final class FluidState extends StateHolder { + } + + public BlockState createLegacyBlock() { +- return this.getType().createLegacyBlock(this); ++ // Paper start - fluid method optimisations ++ if (this.legacyBlock != null) { ++ return this.legacyBlock; ++ } ++ return this.legacyBlock = this.getType().createLegacyBlock((FluidState)(Object)this); ++ // Paper end - fluid method optimisations + } + + @Nullable diff --git a/src/main/java/net/minecraft/world/phys/AABB.java b/src/main/java/net/minecraft/world/phys/AABB.java index 5dc2674b537f4a61b2e21a21bdb2e8dc090d3a3c..6cf6d4ec7b9e43c7b2b4c0e2fb080964ff588130 100644 --- a/src/main/java/net/minecraft/world/phys/AABB.java @@ -30602,7 +33293,7 @@ index d812949c7329ae2696b38dc792fa011ba87decb9..7743495c7ec3fc5e17947144457cef7b @Override diff --git a/src/main/java/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java -index 01693ba050b12b9debcdaefceeff9cbcd503b369..1d36f8dcffd22cf844448d3d8351fb8718cf5227 100644 +index 01693ba050b12b9debcdaefceeff9cbcd503b369..fbe0c4b0fdbb992b7002f6afe1e74d63cbb420f2 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java +++ b/src/main/java/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java @@ -3,12 +3,79 @@ package net.minecraft.world.phys.shapes; @@ -30664,7 +33355,7 @@ index 01693ba050b12b9debcdaefceeff9cbcd503b369..1d36f8dcffd22cf844448d3d8351fb87 + } + } + -+ final boolean hasSingleAABB = sizeX == 1 && sizeY == 1 && sizeZ == 1 && !isEmpty && discreteVoxelShape.isFull(0, 0, 0); ++ final boolean hasSingleAABB = sizeX == 1 && sizeY == 1 && sizeZ == 1 && !isEmpty && (voxelSet[0] & 1L) != 0L; + + final int minFullX = discreteVoxelShape.firstFull(Direction.Axis.X); + final int minFullY = discreteVoxelShape.firstFull(Direction.Axis.Y); @@ -30702,7 +33393,7 @@ index 7ec02a7849437a18860aa0df7d9ddd71b2447d4c..5e45e49ab09344cb95736f4124b1c6e0 public OffsetDoubleList(DoubleList oldList, double offset) { this.delegate = oldList; diff --git a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java -index 5a0b0b47da3d796c391ac15eb573af25a1dfcd32..672a2038c6d8b31090403766460c6149a75adf8b 100644 +index 5a0b0b47da3d796c391ac15eb573af25a1dfcd32..513bed7f11aee667c87046db4cf912b80e8f3638 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java +++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java @@ -16,9 +16,15 @@ public final class Shapes { @@ -30858,13 +33549,13 @@ index 5a0b0b47da3d796c391ac15eb573af25a1dfcd32..672a2038c6d8b31090403766460c6149 + final VoxelShape first = tmp[i]; + final VoxelShape second = tmp[next]; + -+ tmp[newSize++] = Shapes.or(first, second); ++ tmp[newSize++] = Shapes.joinUnoptimized(first, second, BooleanOp.OR); + } + } + size = newSize; + } + -+ return tmp[0]; ++ return tmp[0].optimize(); + // Paper end - optimise collisions } @@ -31108,10 +33799,10 @@ index b07f1c58e00d232e7c83e6df3499e4b677645609..b88c71f27996d24d29048e06a69a0046 private static DiscreteVoxelShape makeSlice(DiscreteVoxelShape voxelSet, Direction.Axis axis, int sliceWidth) { diff --git a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java -index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..d850a7de74150a04622da71d9614320f3d5d69e8 100644 +index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..3f8e7e29c3e52211a29e6f0a32890f6b53bfd9a8 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java +++ b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java -@@ -15,38 +15,505 @@ import net.minecraft.world.phys.AABB; +@@ -15,61 +15,546 @@ import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; @@ -31264,13 +33955,13 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..d850a7de74150a04622da71d9614320f + + if (direction.getAxisDirection() == Direction.AxisDirection.POSITIVE) { + if (DoubleMath.fuzzyEquals(this.max(axis), 1.0, ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)) { -+ ret = tryForceBlock(new SliceShape((VoxelShape)(Object)this, axis, this.shape.getSize(axis) - 1)); ++ ret = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.sliceShape((VoxelShape)(Object)this, axis, this.shape.getSize(axis) - 1); + } else { + ret = Shapes.empty(); + } + } else { + if (DoubleMath.fuzzyEquals(this.min(axis), 0.0, ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)) { -+ ret = tryForceBlock(new SliceShape((VoxelShape)(Object)this, axis, 0)); ++ ret = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.sliceShape((VoxelShape)(Object)this, axis, 0); + } else { + ret = Shapes.empty(); + } @@ -31281,23 +33972,6 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..d850a7de74150a04622da71d9614320f + return ret; + } + -+ private static VoxelShape tryForceBlock(final VoxelShape other) { -+ if (other == Shapes.block()) { -+ return other; -+ } -+ -+ final AABB otherAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)other).moonrise$getSingleAABBRepresentation(); -+ if (otherAABB == null) { -+ return other; -+ } -+ -+ if (((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)Shapes.block()).moonrise$getSingleAABBRepresentation().equals(otherAABB)) { -+ return Shapes.block(); -+ } -+ -+ return other; -+ } -+ + private boolean computeOccludesFullBlock() { + if (this.isEmpty) { + this.occludesFullBlock = Boolean.FALSE; @@ -31395,18 +34069,21 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..d850a7de74150a04622da71d9614320f + return result; + } + -+ private static DoubleList offsetList(final DoubleList src, final double by) { -+ if (src instanceof OffsetDoubleList offsetDoubleList) { -+ return new OffsetDoubleList(offsetDoubleList.delegate, by + offsetDoubleList.offset); ++ private static DoubleList offsetList(final double[] src, final double by) { ++ final it.unimi.dsi.fastutil.doubles.DoubleArrayList wrap = it.unimi.dsi.fastutil.doubles.DoubleArrayList.wrap(src); ++ if (by == 0.0) { ++ return wrap; + } -+ return new OffsetDoubleList(src, by); ++ return new OffsetDoubleList(wrap, by); + } + + private List toAabbsUncached() { -+ final List ret = new java.util.ArrayList<>(); ++ final List ret; + if (this.singleAABBRepresentation != null) { ++ ret = new java.util.ArrayList<>(1); + ret.add(this.singleAABBRepresentation); + } else { ++ ret = new java.util.ArrayList<>(); + final double[] coordsX = this.rootCoordinatesX; + final double[] coordsY = this.rootCoordinatesY; + final double[] coordsZ = this.rootCoordinatesZ; @@ -31528,6 +34205,26 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..d850a7de74150a04622da71d9614320f + final double minDistance = minDistanceArr[0]; + return new BlockHitResult(from.add(minDistance * diffX, minDistance * diffY, minDistance * diffZ), direction, offset, false); + } ++ ++ private VoxelShape calculateFaceDirect(final Direction direction, final Direction.Axis axis, final double[] coords, final double offset) { ++ if (coords.length == 2 && ++ DoubleMath.fuzzyEquals(coords[0] + offset, 0.0, ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) && ++ DoubleMath.fuzzyEquals(coords[1] + offset, 1.0, ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)) { ++ return (VoxelShape)(Object)this; ++ } ++ ++ final boolean positiveDir = direction.getAxisDirection() == Direction.AxisDirection.POSITIVE; ++ ++ // see findIndex ++ final int index = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.findFloor( ++ coords, (positiveDir ? (1.0 - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) : (0.0 + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)) - offset, ++ 0, coords.length - 1 ++ ); ++ ++ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.sliceShape( ++ (VoxelShape)(Object)this, axis, index ++ ); ++ } + // Paper end - optimise collisions + protected VoxelShape(DiscreteVoxelShape voxels) { @@ -31634,7 +34331,45 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..d850a7de74150a04622da71d9614320f } public VoxelShape singleEncompassing() { -@@ -69,7 +536,7 @@ public abstract class VoxelShape { +- return this.isEmpty() +- ? Shapes.empty() +- : Shapes.box( +- this.min(Direction.Axis.X), +- this.min(Direction.Axis.Y), +- this.min(Direction.Axis.Z), +- this.max(Direction.Axis.X), +- this.max(Direction.Axis.Y), +- this.max(Direction.Axis.Z) +- ); ++ // Paper start - optimise collisions ++ if (this.isEmpty) { ++ return Shapes.empty(); ++ } ++ return Shapes.create(this.bounds()); ++ // Paper end - optimise collisions + } + + protected double get(Direction.Axis axis, int index) { +- return this.getCoords(axis).getDouble(index); ++ // Paper start - optimise collisions ++ final int idx = index; ++ switch (axis) { ++ case X: { ++ return this.rootCoordinatesX[idx] + this.offsetX; ++ } ++ case Y: { ++ return this.rootCoordinatesY[idx] + this.offsetY; ++ } ++ case Z: { ++ return this.rootCoordinatesZ[idx] + this.offsetZ; ++ } ++ default: { ++ throw new IllegalStateException("Unknown axis: " + axis); ++ } ++ } ++ // Paper end - optimise collisions + } + public abstract DoubleList getCoords(Direction.Axis axis); public boolean isEmpty() { @@ -31643,7 +34378,7 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..d850a7de74150a04622da71d9614320f } public VoxelShape move(Vec3 vec3d) { -@@ -77,24 +544,91 @@ public abstract class VoxelShape { +@@ -77,24 +562,96 @@ public abstract class VoxelShape { } public VoxelShape move(double x, double y, double z) { @@ -31662,9 +34397,9 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..d850a7de74150a04622da71d9614320f + + final ArrayVoxelShape ret = new ArrayVoxelShape( + this.shape, -+ offsetList(this.getCoords(Direction.Axis.X), x), -+ offsetList(this.getCoords(Direction.Axis.Y), y), -+ offsetList(this.getCoords(Direction.Axis.Z), z) ++ offsetList(this.rootCoordinatesX, this.offsetX + x), ++ offsetList(this.rootCoordinatesY, this.offsetY + y), ++ offsetList(this.rootCoordinatesZ, this.offsetZ + z) + ); + + final ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs cachedToAABBs = this.cachedToAABBs; @@ -31696,6 +34431,11 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..d850a7de74150a04622da71d9614320f + + final List aabbs = this.toAabbs(); + ++ if (aabbs.isEmpty()) { ++ // We are a SliceShape, which does not properly fill isEmpty for every case ++ return Shapes.empty(); ++ } ++ + if (aabbs.size() == 1) { + final AABB singleAABB = aabbs.get(0); + final VoxelShape ret = Shapes.create(singleAABB); @@ -31750,7 +34490,7 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..d850a7de74150a04622da71d9614320f } public void forAllEdges(Shapes.DoubleLineConsumer consumer) { -@@ -131,9 +665,24 @@ public abstract class VoxelShape { +@@ -131,9 +688,24 @@ public abstract class VoxelShape { } public List toAabbs() { @@ -31778,7 +34518,37 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..d850a7de74150a04622da71d9614320f } public double min(Direction.Axis axis, double from, double to) { -@@ -159,42 +708,63 @@ public abstract class VoxelShape { +@@ -155,46 +727,92 @@ public abstract class VoxelShape { + } + + protected int findIndex(Direction.Axis axis, double coord) { +- return Mth.binarySearch(0, this.shape.getSize(axis) + 1, i -> coord < this.get(axis, i)) - 1; ++ // Paper start - optimise collisions ++ final double value = coord; ++ switch (axis) { ++ case X: { ++ final double[] values = this.rootCoordinatesX; ++ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.findFloor( ++ values, value - this.offsetX, 0, values.length - 1 ++ ); ++ } ++ case Y: { ++ final double[] values = this.rootCoordinatesY; ++ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.findFloor( ++ values, value - this.offsetY, 0, values.length - 1 ++ ); ++ } ++ case Z: { ++ final double[] values = this.rootCoordinatesZ; ++ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.findFloor( ++ values, value - this.offsetZ, 0, values.length - 1 ++ ); ++ } ++ default: { ++ throw new IllegalStateException("Unknown axis: " + axis); ++ } ++ } ++ // Paper end - optimise collisions } @Nullable @@ -31817,13 +34587,13 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..d850a7de74150a04622da71d9614320f + final AABB singleAABB = this.singleAABBRepresentation; + if (singleAABB != null) { + if (singleAABB.contains(fromBehindOffsetX, fromBehindOffsetY, fromBehindOffsetZ)) { -+ return new BlockHitResult(fromBehind, Direction.getNearest(directionOpposite.x, directionOpposite.y, directionOpposite.z).getOpposite(), offset, true); ++ return new BlockHitResult(fromBehind, Direction.getApproximateNearest(directionOpposite.x, directionOpposite.y, directionOpposite.z).getOpposite(), offset, true); } + return clip(singleAABB, from, to, offset); + } + + if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.strictlyContains((VoxelShape)(Object)this, fromBehindOffsetX, fromBehindOffsetY, fromBehindOffsetZ)) { -+ return new BlockHitResult(fromBehind, Direction.getNearest(directionOpposite.x, directionOpposite.y, directionOpposite.z).getOpposite(), offset, true); ++ return new BlockHitResult(fromBehind, Direction.getApproximateNearest(directionOpposite.x, directionOpposite.y, directionOpposite.z).getOpposite(), offset, true); } + + return AABB.clip(((VoxelShape)(Object)this).toAabbs(), from, to, offset); @@ -31871,7 +34641,44 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..d850a7de74150a04622da71d9614320f } public VoxelShape getFaceShape(Direction facing) { -@@ -249,9 +819,30 @@ public abstract class VoxelShape { +@@ -216,20 +834,24 @@ public abstract class VoxelShape { + } + } + +- private VoxelShape calculateFace(Direction facing) { +- Direction.Axis axis = facing.getAxis(); +- if (this.isCubeLikeAlong(axis)) { +- return this; +- } else { +- Direction.AxisDirection axisDirection = facing.getAxisDirection(); +- int i = this.findIndex(axis, axisDirection == Direction.AxisDirection.POSITIVE ? 0.9999999 : 1.0E-7); +- SliceShape sliceShape = new SliceShape(this, axis, i); +- if (sliceShape.isEmpty()) { +- return Shapes.empty(); +- } else { +- return (VoxelShape)(sliceShape.isCubeLike() ? Shapes.block() : sliceShape); ++ private VoxelShape calculateFace(Direction direction) { ++ // Paper start - optimise collisions ++ final Direction.Axis axis = direction.getAxis(); ++ switch (axis) { ++ case X: { ++ return this.calculateFaceDirect(direction, axis, this.rootCoordinatesX, this.offsetX); ++ } ++ case Y: { ++ return this.calculateFaceDirect(direction, axis, this.rootCoordinatesY, this.offsetY); ++ } ++ case Z: { ++ return this.calculateFaceDirect(direction, axis, this.rootCoordinatesZ, this.offsetZ); ++ } ++ default: { ++ throw new IllegalStateException("Unknown axis: " + axis); + } + } ++ // Paper end - optimise collisions + } + + protected boolean isCubeLike() { +@@ -249,9 +871,30 @@ public abstract class VoxelShape { && DoubleMath.fuzzyEquals(doubleList.getDouble(1), 1.0, 1.0E-7); } diff --git a/patches/server/0828-fixup-Moonrise-optimisation-patches.patch b/patches/server/0828-fixup-Moonrise-optimisation-patches.patch deleted file mode 100644 index e2197234c7b8..000000000000 --- a/patches/server/0828-fixup-Moonrise-optimisation-patches.patch +++ /dev/null @@ -1,13349 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Mon, 21 Oct 2024 11:06:24 -0700 -Subject: [PATCH] fixup! Moonrise optimisation patches - - -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -index b61611351bf23efc1e90bab8a850ebbe6ffdd516..fc029c8fb22a7c8eeb23bfc171812f6da91c60fa 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -@@ -6,11 +6,13 @@ import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel - import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk; - import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader; - import ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemServerChunkCache; -+import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel; - import com.mojang.logging.LogUtils; - import net.minecraft.server.level.ChunkHolder; - import net.minecraft.server.level.FullChunkStatus; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.server.level.progress.ChunkProgressListener; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.level.chunk.ChunkAccess; - import net.minecraft.world.level.chunk.LevelChunk; -@@ -80,7 +82,13 @@ public final class ChunkSystem { - } - - public static void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder) { -- -+ // Update progress listener for LevelLoadingScreen -+ final ChunkProgressListener progressListener = level.getChunkSource().chunkMap.progressListener; -+ if (progressListener != null) { -+ ChunkSystem.scheduleChunkTask(level, holder.getPos().x, holder.getPos().z, () -> { -+ progressListener.onStatusChange(holder.getPos(), null); -+ }); -+ } - } - - public static void onChunkPreBorder(final LevelChunk chunk, final ChunkHolder holder) { -@@ -112,16 +120,18 @@ public final class ChunkSystem { - ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder() - ); - if (!((ChunkSystemLevelChunk)chunk).moonrise$isPostProcessingDone()) { -- chunk.postProcessGeneration(); -+ chunk.postProcessGeneration((ServerLevel)chunk.getLevel()); - } - ((ServerLevel)chunk.getLevel()).startTickingChunk(chunk); - ((ServerLevel)chunk.getLevel()).getChunkSource().chunkMap.tickingGenerated.incrementAndGet(); -+ ((ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$markChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration - } - - public static void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) { - ((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getTickingChunks().remove( - ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder() - ); -+ ((ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$removeChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration - } - - public static void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java -index aef4fc0d3c272febe675d1ac846b88e58b4e7533..93bc56daec4526f373c84763b8c7ccb4a30e800b 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java -@@ -1,10 +1,10 @@ - package ca.spottedleaf.moonrise.patches.block_counting; - - import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; --import it.unimi.dsi.fastutil.ints.IntArrayList; -+import it.unimi.dsi.fastutil.shorts.ShortArrayList; - - public interface BlockCountingBitStorage { - -- public Int2ObjectOpenHashMap moonrise$countEntries(); -+ public Int2ObjectOpenHashMap moonrise$countEntries(); - - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java -index a08ddb0598d44368af5b6bace971ee31edf9919e..0d1443a113c07d7655e7b927a899447f70db8fa9 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java -@@ -1,11 +1,11 @@ - package ca.spottedleaf.moonrise.patches.block_counting; - --import ca.spottedleaf.moonrise.common.list.IBlockDataList; -+import ca.spottedleaf.moonrise.common.list.ShortList; - - public interface BlockCountingChunkSection { - -- public int moonrise$getSpecialCollidingBlocks(); -+ public boolean moonrise$hasSpecialCollidingBlocks(); - -- public IBlockDataList moonrise$getTickingBlockList(); -+ public ShortList moonrise$getTickingBlockList(); - - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccess.java b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccess.java -new file mode 100644 -index 0000000000000000000000000000000000000000..89e75b454695e174c5619104eeb15eb923a2d9a7 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccess.java -@@ -0,0 +1,12 @@ -+package ca.spottedleaf.moonrise.patches.blockstate_propertyaccess; -+ -+public interface PropertyAccess { -+ -+ public int moonrise$getId(); -+ -+ public int moonrise$getIdFor(final T value); -+ -+ public T moonrise$getById(final int id); -+ -+ public void moonrise$setById(final T[] values); -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccessStateHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccessStateHolder.java -new file mode 100644 -index 0000000000000000000000000000000000000000..01da52b9e8a786824f199a057b62ce0431ecbc43 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/PropertyAccessStateHolder.java -@@ -0,0 +1,7 @@ -+package ca.spottedleaf.moonrise.patches.blockstate_propertyaccess; -+ -+public interface PropertyAccessStateHolder { -+ -+ public long moonrise$getTableIndex(); -+ -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java -new file mode 100644 -index 0000000000000000000000000000000000000000..b5335a2a8cb5dc7637c7112c8f7193389d726489 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java -@@ -0,0 +1,230 @@ -+package ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.util; -+ -+import ca.spottedleaf.concurrentutil.util.IntegerUtil; -+import ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess; -+import ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccessStateHolder; -+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -+import it.unimi.dsi.fastutil.objects.AbstractObjectSet; -+import it.unimi.dsi.fastutil.objects.AbstractReference2ObjectMap; -+import it.unimi.dsi.fastutil.objects.ObjectIterator; -+import it.unimi.dsi.fastutil.objects.ObjectSet; -+import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; -+import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.Collections; -+import java.util.Iterator; -+import java.util.List; -+import java.util.Map; -+import net.minecraft.world.level.block.state.StateHolder; -+import net.minecraft.world.level.block.state.properties.Property; -+ -+public final class ZeroCollidingReferenceStateTable { -+ -+ private final Int2ObjectOpenHashMap propertyToIndexer; -+ private S[] lookup; -+ private final Collection> properties; -+ -+ public ZeroCollidingReferenceStateTable(final Collection> properties) { -+ this.propertyToIndexer = new Int2ObjectOpenHashMap<>(properties.size()); -+ this.properties = new ReferenceOpenHashSet<>(properties); -+ -+ final List> sortedProperties = new ArrayList<>(properties); -+ -+ // important that each table sees the same property order given the same _set_ of properties, -+ // as each table will calculate the index for the block state -+ sortedProperties.sort((final Property p1, final Property p2) -> { -+ return Integer.compare( -+ ((PropertyAccess)p1).moonrise$getId(), -+ ((PropertyAccess)p2).moonrise$getId() -+ ); -+ }); -+ -+ int currentMultiple = 1; -+ for (final Property property : sortedProperties) { -+ final int totalValues = property.getPossibleValues().size(); -+ -+ this.propertyToIndexer.put( -+ ((PropertyAccess)property).moonrise$getId(), -+ new Indexer( -+ totalValues, -+ currentMultiple, -+ IntegerUtil.getUnsignedDivisorMagic((long)currentMultiple, 32), -+ IntegerUtil.getUnsignedDivisorMagic((long)totalValues, 32) -+ ) -+ ); -+ -+ currentMultiple *= totalValues; -+ } -+ } -+ -+ public > boolean hasProperty(final Property property) { -+ return this.propertyToIndexer.containsKey(((PropertyAccess)property).moonrise$getId()); -+ } -+ -+ public long getIndex(final StateHolder stateHolder) { -+ long ret = 0L; -+ -+ for (final Map.Entry, Comparable> entry : stateHolder.getValues().entrySet()) { -+ final Property property = entry.getKey(); -+ final Comparable value = entry.getValue(); -+ -+ final Indexer indexer = this.propertyToIndexer.get(((PropertyAccess)property).moonrise$getId()); -+ -+ ret += (((PropertyAccess)property).moonrise$getIdFor(value)) * indexer.multiple; -+ } -+ -+ return ret; -+ } -+ -+ public boolean isLoaded() { -+ return this.lookup != null; -+ } -+ -+ public void loadInTable(final Map, Comparable>, S> universe) { -+ if (this.lookup != null) { -+ throw new IllegalStateException(); -+ } -+ -+ this.lookup = (S[])new StateHolder[universe.size()]; -+ -+ for (final Map.Entry, Comparable>, S> entry : universe.entrySet()) { -+ final S value = entry.getValue(); -+ if (value == null) { -+ continue; -+ } -+ this.lookup[(int)((PropertyAccessStateHolder)(StateHolder)value).moonrise$getTableIndex()] = value; -+ } -+ -+ for (final S value : this.lookup) { -+ if (value == null) { -+ throw new IllegalStateException(); -+ } -+ } -+ } -+ -+ public > T get(final long index, final Property property) { -+ final Indexer indexer = this.propertyToIndexer.get(((PropertyAccess)property).moonrise$getId()); -+ if (indexer == null) { -+ return null; -+ } -+ -+ final long divided = (index * indexer.multipleDivMagic) >>> 32; -+ final long modded = (((divided * indexer.modMagic) & 0xFFFFFFFFL) * indexer.totalValues) >>> 32; -+ // equiv to: divided = index / multiple -+ // modded = divided % totalValues -+ -+ return ((PropertyAccess)property).moonrise$getById((int)modded); -+ } -+ -+ public > S set(final long index, final Property property, final T with) { -+ final int newValueId = ((PropertyAccess)property).moonrise$getIdFor(with); -+ if (newValueId < 0) { -+ return null; -+ } -+ -+ final Indexer indexer = this.propertyToIndexer.get(((PropertyAccess)property).moonrise$getId()); -+ if (indexer == null) { -+ return null; -+ } -+ -+ final long divided = (index * indexer.multipleDivMagic) >>> 32; -+ final long modded = (((divided * indexer.modMagic) & 0xFFFFFFFFL) * indexer.totalValues) >>> 32; -+ // equiv to: divided = index / multiple -+ // modded = divided % totalValues -+ -+ // subtract out the old value, add in the new -+ final long newIndex = (((long)newValueId - modded) * indexer.multiple) + index; -+ -+ return this.lookup[(int)newIndex]; -+ } -+ -+ public > S trySet(final long index, final Property property, final T with, final S dfl) { -+ final Indexer indexer = this.propertyToIndexer.get(((PropertyAccess)property).moonrise$getId()); -+ if (indexer == null) { -+ return dfl; -+ } -+ -+ final int newValueId = ((PropertyAccess)property).moonrise$getIdFor(with); -+ if (newValueId < 0) { -+ return null; -+ } -+ -+ final long divided = (index * indexer.multipleDivMagic) >>> 32; -+ final long modded = (((divided * indexer.modMagic) & 0xFFFFFFFFL) * indexer.totalValues) >>> 32; -+ // equiv to: divided = index / multiple -+ // modded = divided % totalValues -+ -+ // subtract out the old value, add in the new -+ final long newIndex = (((long)newValueId - modded) * indexer.multiple) + index; -+ -+ return this.lookup[(int)newIndex]; -+ } -+ -+ public Collection> getProperties() { -+ return Collections.unmodifiableCollection(this.properties); -+ } -+ -+ public Map, Comparable> getMapView(final long stateIndex) { -+ return new MapView(stateIndex); -+ } -+ -+ private static final record Indexer( -+ int totalValues, int multiple, long multipleDivMagic, long modMagic -+ ) {} -+ -+ private class MapView extends AbstractReference2ObjectMap, Comparable> { -+ private final long stateIndex; -+ private EntrySet entrySet; -+ -+ MapView(final long stateIndex) { -+ this.stateIndex = stateIndex; -+ } -+ -+ @Override -+ public boolean containsKey(final Object key) { -+ return key instanceof Property prop && ZeroCollidingReferenceStateTable.this.hasProperty(prop); -+ } -+ -+ @Override -+ public int size() { -+ return ZeroCollidingReferenceStateTable.this.properties.size(); -+ } -+ -+ @Override -+ public ObjectSet, Comparable>> reference2ObjectEntrySet() { -+ if (this.entrySet == null) -+ this.entrySet = new EntrySet(); -+ return this.entrySet; -+ } -+ -+ @Override -+ public Comparable get(final Object key) { -+ return key instanceof Property prop ? ZeroCollidingReferenceStateTable.this.get(this.stateIndex, prop) : null; -+ } -+ -+ class EntrySet extends AbstractObjectSet, Comparable>> { -+ @Override -+ public ObjectIterator, Comparable>> iterator() { -+ final Iterator> propIterator = ZeroCollidingReferenceStateTable.this.properties.iterator(); -+ return new ObjectIterator<>() { -+ @Override -+ public boolean hasNext() { -+ return propIterator.hasNext(); -+ } -+ -+ @Override -+ public Entry, Comparable> next() { -+ Property prop = propIterator.next(); -+ return new AbstractReference2ObjectMap.BasicEntry<>(prop, ZeroCollidingReferenceStateTable.this.get(MapView.this.stateIndex, prop)); -+ } -+ }; -+ } -+ -+ @Override -+ public int size() { -+ return ZeroCollidingReferenceStateTable.this.properties.size(); -+ } -+ } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java -index 49160a30b8e19e5c5ada811fbcae2a05959524f3..44bb25554634af2ec0b2e9b3d9231304d5dff034 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java -@@ -1,10 +1,11 @@ - package ca.spottedleaf.moonrise.patches.chunk_system; - -+import ca.spottedleaf.moonrise.common.PlatformHooks; - import net.minecraft.SharedConstants; - import net.minecraft.nbt.CompoundTag; - import net.minecraft.nbt.Tag; - import net.minecraft.server.level.ServerLevel; --import net.minecraft.util.datafix.DataFixTypes; -+import net.minecraft.util.datafix.fixes.References; - - public final class ChunkSystemConverters { - -@@ -25,13 +26,13 @@ public final class ChunkSystemConverters { - public static CompoundTag convertPoiCompoundTag(final CompoundTag data, final ServerLevel world) { - final int dataVersion = getDataVersion(data, DEFAULT_POI_DATA_VERSION); - -- return DataFixTypes.POI_CHUNK.update(world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); -+ return PlatformHooks.get().convertNBT(References.POI_CHUNK, world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); - } - - public static CompoundTag convertEntityChunkCompoundTag(final CompoundTag data, final ServerLevel world) { - final int dataVersion = getDataVersion(data, DEFAULT_ENTITY_CHUNK_DATA_VERSION); - -- return DataFixTypes.ENTITY_CHUNK.update(world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); -+ return PlatformHooks.get().convertNBT(References.ENTITY_CHUNK, world.getServer().getFixerUpper(), data, dataVersion, getCurrentVersion()); - } - - private ChunkSystemConverters() {} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemFeatures.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemFeatures.java -deleted file mode 100644 -index 67f6dd9a4855611cfe242c2e37e90f6d27d4c823..0000000000000000000000000000000000000000 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemFeatures.java -+++ /dev/null -@@ -1,36 +0,0 @@ --package ca.spottedleaf.moonrise.patches.chunk_system; -- --import ca.spottedleaf.moonrise.patches.chunk_system.async_save.AsyncChunkSaveData; --import net.minecraft.nbt.CompoundTag; --import net.minecraft.server.level.ServerLevel; --import net.minecraft.world.level.chunk.ChunkAccess; -- --public final class ChunkSystemFeatures { -- -- public static boolean supportsAsyncChunkSave() { -- // uncertain how to properly pass AsyncSaveData to ChunkSerializer#write -- // additionally, there may be mods hooking into the write() call which may not be thread-safe to call -- return true; -- } -- -- public static AsyncChunkSaveData getAsyncSaveData(final ServerLevel world, final ChunkAccess chunk) { -- return net.minecraft.world.level.chunk.storage.ChunkSerializer.getAsyncSaveData(world, chunk); -- } -- -- public static CompoundTag saveChunkAsync(final ServerLevel world, final ChunkAccess chunk, final AsyncChunkSaveData asyncSaveData) { -- return net.minecraft.world.level.chunk.storage.ChunkSerializer.saveChunk(world, chunk, asyncSaveData); -- } -- -- public static boolean forceNoSave(final ChunkAccess chunk) { -- // support for CB chunk mustNotSave -- return chunk instanceof net.minecraft.world.level.chunk.LevelChunk levelChunk && levelChunk.mustNotSave; -- } -- -- public static boolean supportsAsyncChunkDeserialization() { -- // as it stands, the current problem with supporting this in Moonrise is that we are unsure that any mods -- // hooking into ChunkSerializer#read() are thread-safe to call -- return true; -- } -- -- private ChunkSystemFeatures() {} --} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/async_save/AsyncChunkSaveData.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/async_save/AsyncChunkSaveData.java -deleted file mode 100644 -index becd1c6d54ed6c912aee3a9178a970e2751d3694..0000000000000000000000000000000000000000 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/async_save/AsyncChunkSaveData.java -+++ /dev/null -@@ -1,11 +0,0 @@ --package ca.spottedleaf.moonrise.patches.chunk_system.async_save; -- --import net.minecraft.nbt.ListTag; --import net.minecraft.nbt.Tag; -- --public record AsyncChunkSaveData( -- Tag blockTickList, // non-null if we had to go to the server's tick list -- Tag fluidTickList, // non-null if we had to go to the server's tick list -- ListTag blockEntities, -- long worldTime --) {} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java -index 2c279854bdf214538380fa354e4298ec4bd9ac4e..c7da23900228aab3a5673eb5adfada5091140319 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java -@@ -1,5 +1,6 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.entity; - -+import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; - import net.minecraft.server.level.FullChunkStatus; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.entity.monster.Shulker; -@@ -19,6 +20,10 @@ public interface ChunkSystemEntity { - - public void moonrise$setChunkStatus(final FullChunkStatus status); - -+ public ChunkData moonrise$getChunkData(); -+ -+ public void moonrise$setChunkData(final ChunkData chunkData); -+ - public int moonrise$getSectionX(); - - public void moonrise$setSectionX(final int x); -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java -index 73df26b27146bbad2106d57b22dd3c792ed3dd1d..a814512fcfb85312474ae2c2c21443843bf57831 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java -@@ -1,5 +1,6 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.io; - -+import net.minecraft.nbt.CompoundTag; - import net.minecraft.world.level.chunk.storage.RegionFile; - import java.io.IOException; - -@@ -11,4 +12,20 @@ public interface ChunkSystemRegionFileStorage { - - public RegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException; - -+ public MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite( -+ final int chunkX, final int chunkZ, final CompoundTag compound -+ ) throws IOException; -+ -+ public void moonrise$finishWrite( -+ final int chunkX, final int chunkZ, final MoonriseRegionFileIO.RegionDataController.WriteData writeData -+ ) throws IOException; -+ -+ public MoonriseRegionFileIO.RegionDataController.ReadData moonrise$readData( -+ final int chunkX, final int chunkZ -+ ) throws IOException; -+ -+ // if the return value is null, then the caller needs to re-try with a new call to readData() -+ public CompoundTag moonrise$finishRead( -+ final int chunkX, final int chunkZ, final MoonriseRegionFileIO.RegionDataController.ReadData readData -+ ) throws IOException; - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java -new file mode 100644 -index 0000000000000000000000000000000000000000..99f6f3e58b11b8967e6f1c3391c190d9a860ab7f ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java -@@ -0,0 +1,1707 @@ -+package ca.spottedleaf.moonrise.patches.chunk_system.io; -+ -+import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; -+import ca.spottedleaf.concurrentutil.completable.CallbackCompletable; -+import ca.spottedleaf.concurrentutil.completable.Completable; -+import ca.spottedleaf.concurrentutil.executor.Cancellable; -+import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.queue.PrioritisedTaskQueue; -+import ca.spottedleaf.concurrentutil.function.BiLong1Function; -+import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.Priority; -+import ca.spottedleaf.moonrise.common.util.CoordinateUtils; -+import ca.spottedleaf.moonrise.common.util.TickThread; -+import ca.spottedleaf.moonrise.common.util.WorldUtil; -+import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; -+import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.server.MinecraftServer; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.level.chunk.storage.RegionFile; -+import net.minecraft.world.level.chunk.storage.RegionFileStorage; -+import org.slf4j.Logger; -+import org.slf4j.LoggerFactory; -+import java.io.DataInputStream; -+import java.io.DataOutputStream; -+import java.io.IOException; -+import java.lang.invoke.VarHandle; -+import java.util.concurrent.CompletableFuture; -+import java.util.concurrent.CompletionException; -+import java.util.concurrent.atomic.AtomicInteger; -+import java.util.concurrent.atomic.AtomicLong; -+import java.util.function.BiConsumer; -+import java.util.function.Consumer; -+ -+public final class MoonriseRegionFileIO { -+ -+ private static final int REGION_FILE_SHIFT = 5; -+ private static final Logger LOGGER = LoggerFactory.getLogger(MoonriseRegionFileIO.class); -+ -+ /** -+ * The types of RegionFiles controlled by the I/O thread(s). -+ */ -+ public static enum RegionFileType { -+ CHUNK_DATA, -+ POI_DATA, -+ ENTITY_DATA; -+ } -+ -+ public static RegionDataController getControllerFor(final ServerLevel world, final RegionFileType type) { -+ switch (type) { -+ case CHUNK_DATA: -+ return ((ChunkSystemServerLevel)world).moonrise$getChunkDataController(); -+ case POI_DATA: -+ return ((ChunkSystemServerLevel)world).moonrise$getPoiChunkDataController(); -+ case ENTITY_DATA: -+ return ((ChunkSystemServerLevel)world).moonrise$getEntityChunkDataController(); -+ default: -+ throw new IllegalStateException("Unknown controller type " + type); -+ } -+ } -+ -+ private static final RegionFileType[] CACHED_REGIONFILE_TYPES = RegionFileType.values(); -+ -+ /** -+ * Collects RegionFile data for a certain chunk. -+ */ -+ public static final class RegionFileData { -+ -+ private final boolean[] hasResult = new boolean[CACHED_REGIONFILE_TYPES.length]; -+ private final CompoundTag[] data = new CompoundTag[CACHED_REGIONFILE_TYPES.length]; -+ private final Throwable[] throwables = new Throwable[CACHED_REGIONFILE_TYPES.length]; -+ -+ /** -+ * Sets the result associated with the specified RegionFile type. Note that -+ * results can only be set once per RegionFile type. -+ * -+ * @param type The RegionFile type. -+ * @param data The result to set. -+ */ -+ public void setData(final MoonriseRegionFileIO.RegionFileType type, final CompoundTag data) { -+ final int index = type.ordinal(); -+ -+ if (this.hasResult[index]) { -+ throw new IllegalArgumentException("Result already exists for type " + type); -+ } -+ this.hasResult[index] = true; -+ this.data[index] = data; -+ } -+ -+ /** -+ * Sets the result associated with the specified RegionFile type. Note that -+ * results can only be set once per RegionFile type. -+ * -+ * @param type The RegionFile type. -+ * @param throwable The result to set. -+ */ -+ public void setThrowable(final MoonriseRegionFileIO.RegionFileType type, final Throwable throwable) { -+ final int index = type.ordinal(); -+ -+ if (this.hasResult[index]) { -+ throw new IllegalArgumentException("Result already exists for type " + type); -+ } -+ this.hasResult[index] = true; -+ this.throwables[index] = throwable; -+ } -+ -+ /** -+ * Returns whether there is a result for the specified RegionFile type. -+ * -+ * @param type Specified RegionFile type. -+ * -+ * @return Whether a result exists for {@code type}. -+ */ -+ public boolean hasResult(final MoonriseRegionFileIO.RegionFileType type) { -+ return this.hasResult[type.ordinal()]; -+ } -+ -+ /** -+ * Returns the data result for the RegionFile type. -+ * -+ * @param type Specified RegionFile type. -+ * -+ * @throws IllegalArgumentException If the result has not been set for {@code type}. -+ * @return The data result for the specified type. If the result is a {@code Throwable}, -+ * then returns {@code null}. -+ */ -+ public CompoundTag getData(final MoonriseRegionFileIO.RegionFileType type) { -+ final int index = type.ordinal(); -+ -+ if (!this.hasResult[index]) { -+ throw new IllegalArgumentException("Result does not exist for type " + type); -+ } -+ -+ return this.data[index]; -+ } -+ -+ /** -+ * Returns the throwable result for the RegionFile type. -+ * -+ * @param type Specified RegionFile type. -+ * -+ * @throws IllegalArgumentException If the result has not been set for {@code type}. -+ * @return The throwable result for the specified type. If the result is an {@code CompoundTag}, -+ * then returns {@code null}. -+ */ -+ public Throwable getThrowable(final MoonriseRegionFileIO.RegionFileType type) { -+ final int index = type.ordinal(); -+ -+ if (!this.hasResult[index]) { -+ throw new IllegalArgumentException("Result does not exist for type " + type); -+ } -+ -+ return this.throwables[index]; -+ } -+ } -+ -+ public static void flushRegionStorages(final ServerLevel world) throws IOException { -+ for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { -+ flushRegionStorages(world, type); -+ } -+ } -+ -+ public static void flushRegionStorages(final ServerLevel world, final RegionFileType type) throws IOException { -+ getControllerFor(world, type).getCache().flush(); -+ } -+ -+ public static void flush(final MinecraftServer server) { -+ for (final ServerLevel world : server.getAllLevels()) { -+ flush(world); -+ } -+ } -+ -+ public static void flush(final ServerLevel world) { -+ for (final RegionFileType regionFileType : CACHED_REGIONFILE_TYPES) { -+ flush(world, regionFileType); -+ } -+ } -+ -+ public static void flush(final ServerLevel world, final RegionFileType type) { -+ final RegionDataController taskController = getControllerFor(world, type); -+ -+ long failures = 1L; // start at 0.13ms -+ -+ while (taskController.hasTasks()) { -+ Thread.yield(); -+ failures = ConcurrentUtil.linearLongBackoff(failures, 125_000L, 5_000_000L); // 125us, 5ms -+ } -+ } -+ -+ public static void partialFlush(final ServerLevel world, final int tasksRemaining) { -+ for (long failures = 1L;;) { // start at 0.13ms -+ long totalTasks = 0L; -+ for (final RegionFileType regionFileType : CACHED_REGIONFILE_TYPES) { -+ totalTasks += getControllerFor(world, regionFileType).getTotalWorkingTasks(); -+ } -+ -+ if (totalTasks > (long)tasksRemaining) { -+ Thread.yield(); -+ failures = ConcurrentUtil.linearLongBackoff(failures, 125_000L, 5_000_000L); // 125us, 5ms -+ } else { -+ return; -+ } -+ } -+ } -+ -+ /** -+ * Returns the priority associated with blocking I/O based on the current thread. The goal is to avoid -+ * dumb plugins from taking away priority from threads we consider crucial. -+ * @return The priroity to use with blocking I/O on the current thread. -+ */ -+ public static Priority getIOBlockingPriorityForCurrentThread() { -+ if (TickThread.isTickThread()) { -+ return Priority.BLOCKING; -+ } -+ return Priority.HIGHEST; -+ } -+ -+ /** -+ * Returns the priority for the specified regionfile type for the specified chunk. -+ * @param world Specified world. -+ * @param chunkX Specified chunk x. -+ * @param chunkZ Specified chunk z. -+ * @param type Specified regionfile type. -+ * @return The priority for the chunk -+ */ -+ public static Priority getPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { -+ final RegionDataController taskController = getControllerFor(world, type); -+ final ChunkIOTask task = taskController.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ -+ if (task == null) { -+ return Priority.COMPLETING; -+ } -+ -+ return task.getPriority(); -+ } -+ -+ /** -+ * Sets the priority for all regionfile types for the specified chunk. Note that great care should -+ * be taken using this method, as there can be multiple tasks tied to the same chunk that want different -+ * priorities. -+ * -+ * @param world Specified world. -+ * @param chunkX Specified chunk x. -+ * @param chunkZ Specified chunk z. -+ * @param priority New priority. -+ * -+ * @see #raisePriority(ServerLevel, int, int, Priority) -+ * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) -+ * @see #lowerPriority(ServerLevel, int, int, Priority) -+ * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) -+ */ -+ public static void setPriority(final ServerLevel world, final int chunkX, final int chunkZ, -+ final Priority priority) { -+ for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { -+ MoonriseRegionFileIO.setPriority(world, chunkX, chunkZ, type, priority); -+ } -+ } -+ -+ /** -+ * Sets the priority for the specified regionfile type for the specified chunk. Note that great care should -+ * be taken using this method, as there can be multiple tasks tied to the same chunk that want different -+ * priorities. -+ * -+ * @param world Specified world. -+ * @param chunkX Specified chunk x. -+ * @param chunkZ Specified chunk z. -+ * @param type Specified regionfile type. -+ * @param priority New priority. -+ * -+ * @see #raisePriority(ServerLevel, int, int, Priority) -+ * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) -+ * @see #lowerPriority(ServerLevel, int, int, Priority) -+ * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) -+ */ -+ public static void setPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -+ final Priority priority) { -+ final RegionDataController taskController = getControllerFor(world, type); -+ final ChunkIOTask task = taskController.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ -+ if (task != null) { -+ task.setPriority(priority); -+ } -+ } -+ -+ /** -+ * Raises the priority for all regionfile types for the specified chunk. -+ * -+ * @param world Specified world. -+ * @param chunkX Specified chunk x. -+ * @param chunkZ Specified chunk z. -+ * @param priority New priority. -+ * -+ * @see #setPriority(ServerLevel, int, int, Priority) -+ * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) -+ * @see #lowerPriority(ServerLevel, int, int, Priority) -+ * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) -+ */ -+ public static void raisePriority(final ServerLevel world, final int chunkX, final int chunkZ, -+ final Priority priority) { -+ for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { -+ MoonriseRegionFileIO.raisePriority(world, chunkX, chunkZ, type, priority); -+ } -+ } -+ -+ /** -+ * Raises the priority for the specified regionfile type for the specified chunk. -+ * -+ * @param world Specified world. -+ * @param chunkX Specified chunk x. -+ * @param chunkZ Specified chunk z. -+ * @param type Specified regionfile type. -+ * @param priority New priority. -+ * -+ * @see #setPriority(ServerLevel, int, int, Priority) -+ * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) -+ * @see #lowerPriority(ServerLevel, int, int, Priority) -+ * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) -+ */ -+ public static void raisePriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -+ final Priority priority) { -+ final RegionDataController taskController = getControllerFor(world, type); -+ final ChunkIOTask task = taskController.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ -+ if (task != null) { -+ task.raisePriority(priority); -+ } -+ } -+ -+ /** -+ * Lowers the priority for all regionfile types for the specified chunk. -+ * -+ * @param world Specified world. -+ * @param chunkX Specified chunk x. -+ * @param chunkZ Specified chunk z. -+ * @param priority New priority. -+ * -+ * @see #raisePriority(ServerLevel, int, int, Priority) -+ * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) -+ * @see #setPriority(ServerLevel, int, int, Priority) -+ * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) -+ */ -+ public static void lowerPriority(final ServerLevel world, final int chunkX, final int chunkZ, -+ final Priority priority) { -+ for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { -+ MoonriseRegionFileIO.lowerPriority(world, chunkX, chunkZ, type, priority); -+ } -+ } -+ -+ /** -+ * Lowers the priority for the specified regionfile type for the specified chunk. -+ * -+ * @param world Specified world. -+ * @param chunkX Specified chunk x. -+ * @param chunkZ Specified chunk z. -+ * @param type Specified regionfile type. -+ * @param priority New priority. -+ * -+ * @see #raisePriority(ServerLevel, int, int, Priority) -+ * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) -+ * @see #setPriority(ServerLevel, int, int, Priority) -+ * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) -+ */ -+ public static void lowerPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -+ final Priority priority) { -+ final RegionDataController taskController = getControllerFor(world, type); -+ final ChunkIOTask task = taskController.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ -+ if (task != null) { -+ task.lowerPriority(priority); -+ } -+ } -+ -+ /** -+ * Schedules the chunk data to be written asynchronously. -+ *

    -+ * Impl notes: -+ *

    -+ *
  • -+ * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means -+ * saves must be scheduled before a chunk is unloaded. -+ *
  • -+ *
  • -+ * Writes may be called concurrently, although only the "later" write will go through. -+ *
  • -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param data Chunk's data -+ * @param type The regionfile type to write to. -+ * -+ * @throws IllegalStateException If the file io thread has shutdown. -+ */ -+ public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data, -+ final RegionFileType type) { -+ MoonriseRegionFileIO.scheduleSave(world, chunkX, chunkZ, data, type, Priority.NORMAL); -+ } -+ -+ /** -+ * Schedules the chunk data to be written asynchronously. -+ *

    -+ * Impl notes: -+ *

    -+ *
  • -+ * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means -+ * saves must be scheduled before a chunk is unloaded. -+ *
  • -+ *
  • -+ * Writes may be called concurrently, although only the "later" write will go through. -+ *
  • -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param data Chunk's data -+ * @param type The regionfile type to write to. -+ * @param priority The minimum priority to schedule at. -+ * -+ * @throws IllegalStateException If the file io thread has shutdown. -+ */ -+ public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data, -+ final RegionFileType type, final Priority priority) { -+ scheduleSave( -+ world, chunkX, chunkZ, -+ (final BiConsumer consumer) -> { -+ consumer.accept(data, null); -+ }, null, type, priority -+ ); -+ } -+ -+ /** -+ * Schedules the chunk data to be written asynchronously. -+ *

    -+ * Impl notes: -+ *

    -+ *
  • -+ * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means -+ * saves must be scheduled before a chunk is unloaded. -+ *
  • -+ *
  • -+ * Writes may be called concurrently, although only the "later" write will go through. -+ *
  • -+ *
  • -+ * The specified write task, if not null, will have its priority controlled by the scheduler. -+ *
  • -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param completable Chunk's pending data -+ * @param writeTask The task responsible for completing the pending chunk data -+ * @param type The regionfile type to write to. -+ * @param priority The minimum priority to schedule at. -+ * -+ * @throws IllegalStateException If the file io thread has shutdown. -+ */ -+ public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final CallbackCompletable completable, -+ final PrioritisedExecutor.PrioritisedTask writeTask, final RegionFileType type, final Priority priority) { -+ scheduleSave(world, chunkX, chunkZ, completable::addWaiter, writeTask, type, priority); -+ } -+ -+ /** -+ * Schedules the chunk data to be written asynchronously. -+ *

    -+ * Impl notes: -+ *

    -+ *
  • -+ * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means -+ * saves must be scheduled before a chunk is unloaded. -+ *
  • -+ *
  • -+ * Writes may be called concurrently, although only the "later" write will go through. -+ *
  • -+ *
  • -+ * The specified write task, if not null, will have its priority controlled by the scheduler. -+ *
  • -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param completable Chunk's pending data -+ * @param writeTask The task responsible for completing the pending chunk data -+ * @param type The regionfile type to write to. -+ * @param priority The minimum priority to schedule at. -+ * -+ * @throws IllegalStateException If the file io thread has shutdown. -+ */ -+ public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final Completable completable, -+ final PrioritisedExecutor.PrioritisedTask writeTask, final RegionFileType type, final Priority priority) { -+ scheduleSave(world, chunkX, chunkZ, completable::whenComplete, writeTask, type, priority); -+ } -+ -+ private static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final Consumer> scheduler, -+ final PrioritisedExecutor.PrioritisedTask writeTask, final RegionFileType type, final Priority priority) { -+ final RegionDataController taskController = getControllerFor(world, type); -+ -+ final boolean[] created = new boolean[1]; -+ final ChunkIOTask.InProgressWrite write = new ChunkIOTask.InProgressWrite(writeTask); -+ final ChunkIOTask task = taskController.chunkTasks.compute(CoordinateUtils.getChunkKey(chunkX, chunkZ), -+ (final long keyInMap, final ChunkIOTask taskRunning) -> { -+ if (taskRunning == null || taskRunning.failedWrite) { -+ // no task is scheduled or the previous write failed - meaning we need to overwrite it -+ -+ // create task -+ final ChunkIOTask newTask = new ChunkIOTask( -+ world, taskController, chunkX, chunkZ, priority, new ChunkIOTask.InProgressRead() -+ ); -+ -+ newTask.pushPendingWrite(write); -+ -+ created[0] = true; -+ -+ return newTask; -+ } -+ -+ taskRunning.pushPendingWrite(write); -+ -+ return taskRunning; -+ } -+ ); -+ -+ write.schedule(task, scheduler); -+ -+ if (created[0]) { -+ taskController.startTask(task); -+ task.scheduleWriteCompress(); -+ } else { -+ task.raisePriority(priority); -+ } -+ } -+ -+ /** -+ * Schedules a load to be executed asynchronously. This task will load all regionfile types, and then call -+ * {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean)} -+ * for single load. -+ *

    -+ * Impl notes: -+ *

    -+ *
  • -+ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -+ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -+ * data is undefined behaviour, and can cause deadlock. -+ *
  • -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param onComplete Consumer to execute once this task has completed -+ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -+ * of this call. -+ * -+ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -+ * -+ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) -+ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) -+ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) -+ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) -+ */ -+ public static Cancellable loadAllChunkData(final ServerLevel world, final int chunkX, final int chunkZ, -+ final Consumer onComplete, final boolean intendingToBlock) { -+ return MoonriseRegionFileIO.loadAllChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, Priority.NORMAL); -+ } -+ -+ /** -+ * Schedules a load to be executed asynchronously. This task will load all regionfile types, and then call -+ * {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority)} -+ * for single load. -+ *

    -+ * Impl notes: -+ *

    -+ *
  • -+ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -+ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -+ * data is undefined behaviour, and can cause deadlock. -+ *
  • -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param onComplete Consumer to execute once this task has completed -+ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -+ * of this call. -+ * @param priority The minimum priority to load the data at. -+ * -+ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -+ * -+ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) -+ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) -+ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) -+ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) -+ */ -+ public static Cancellable loadAllChunkData(final ServerLevel world, final int chunkX, final int chunkZ, -+ final Consumer onComplete, final boolean intendingToBlock, -+ final Priority priority) { -+ return MoonriseRegionFileIO.loadChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, priority, CACHED_REGIONFILE_TYPES); -+ } -+ -+ /** -+ * Schedules a load to be executed asynchronously. This task will load data for the specified regionfile type(s), and -+ * then call {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean)} -+ * for single load. -+ *

    -+ * Impl notes: -+ *

    -+ *
  • -+ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -+ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -+ * data is undefined behaviour, and can cause deadlock. -+ *
  • -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param onComplete Consumer to execute once this task has completed -+ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -+ * of this call. -+ * @param types The regionfile type(s) to load. -+ * -+ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -+ * -+ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) -+ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) -+ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) -+ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) -+ */ -+ public static Cancellable loadChunkData(final ServerLevel world, final int chunkX, final int chunkZ, -+ final Consumer onComplete, final boolean intendingToBlock, -+ final RegionFileType... types) { -+ return MoonriseRegionFileIO.loadChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, Priority.NORMAL, types); -+ } -+ -+ /** -+ * Schedules a load to be executed asynchronously. This task will load data for the specified regionfile type(s), and -+ * then call {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority)} -+ * for single load. -+ *

    -+ * Impl notes: -+ *

    -+ *
  • -+ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -+ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -+ * data is undefined behaviour, and can cause deadlock. -+ *
  • -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param onComplete Consumer to execute once this task has completed -+ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -+ * of this call. -+ * @param types The regionfile type(s) to load. -+ * @param priority The minimum priority to load the data at. -+ * -+ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -+ * -+ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) -+ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) -+ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) -+ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) -+ */ -+ public static Cancellable loadChunkData(final ServerLevel world, final int chunkX, final int chunkZ, -+ final Consumer onComplete, final boolean intendingToBlock, -+ final Priority priority, final RegionFileType... types) { -+ if (types == null) { -+ throw new NullPointerException("Types cannot be null"); -+ } -+ if (types.length == 0) { -+ throw new IllegalArgumentException("Types cannot be empty"); -+ } -+ -+ final RegionFileData ret = new RegionFileData(); -+ -+ final Cancellable[] reads = new CancellableRead[types.length]; -+ final AtomicInteger completions = new AtomicInteger(); -+ final int expectedCompletions = types.length; -+ -+ for (int i = 0; i < expectedCompletions; ++i) { -+ final RegionFileType type = types[i]; -+ reads[i] = MoonriseRegionFileIO.loadDataAsync(world, chunkX, chunkZ, type, -+ (final CompoundTag data, final Throwable throwable) -> { -+ if (throwable != null) { -+ ret.setThrowable(type, throwable); -+ } else { -+ ret.setData(type, data); -+ } -+ -+ if (completions.incrementAndGet() == expectedCompletions) { -+ onComplete.accept(ret); -+ } -+ }, intendingToBlock, priority); -+ } -+ -+ return new CancellableReads(reads); -+ } -+ -+ /** -+ * Schedules a load to be executed asynchronously. This task will load the specified regionfile type, and then call -+ * {@code onComplete}. -+ *

    -+ * Impl notes: -+ *

    -+ *
  • -+ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -+ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -+ * data is undefined behaviour, and can cause deadlock. -+ *
  • -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param onComplete Consumer to execute once this task has completed -+ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -+ * of this call. -+ * -+ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -+ * -+ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) -+ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) -+ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) -+ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) -+ */ -+ public static Cancellable loadDataAsync(final ServerLevel world, final int chunkX, final int chunkZ, -+ final RegionFileType type, final BiConsumer onComplete, -+ final boolean intendingToBlock) { -+ return MoonriseRegionFileIO.loadDataAsync(world, chunkX, chunkZ, type, onComplete, intendingToBlock, Priority.NORMAL); -+ } -+ -+ /** -+ * Schedules a load to be executed asynchronously. This task will load the specified regionfile type, and then call -+ * {@code onComplete}. -+ *

    -+ * Impl notes: -+ *

    -+ *
  • -+ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -+ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -+ * data is undefined behaviour, and can cause deadlock. -+ *
  • -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param onComplete Consumer to execute once this task has completed -+ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -+ * of this call. -+ * @param priority Minimum priority to load the data at. -+ * -+ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -+ * -+ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) -+ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) -+ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) -+ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) -+ */ -+ public static Cancellable loadDataAsync(final ServerLevel world, final int chunkX, final int chunkZ, -+ final RegionFileType type, final BiConsumer onComplete, -+ final boolean intendingToBlock, final Priority priority) { -+ final RegionDataController taskController = getControllerFor(world, type); -+ -+ final ImmediateCallbackCompletion callbackInfo = new ImmediateCallbackCompletion(); -+ -+ final long key = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ final BiLong1Function compute = (final long keyInMap, final ChunkIOTask running) -> { -+ if (running == null) { -+ // not scheduled -+ -+ // set up task -+ final ChunkIOTask newTask = new ChunkIOTask( -+ world, taskController, chunkX, chunkZ, priority, new ChunkIOTask.InProgressRead() -+ ); -+ newTask.inProgressRead.addToAsyncWaiters(onComplete); -+ -+ callbackInfo.tasksNeedReadScheduling = true; -+ return newTask; -+ } -+ -+ final ChunkIOTask.InProgressWrite pendingWrite = running.inProgressWrite; -+ -+ if (pendingWrite == null) { -+ // need to add to waiters here, because the regionfile thread will use compute() to lock and check for cancellations -+ if (!running.inProgressRead.addToAsyncWaiters(onComplete)) { -+ callbackInfo.data = running.inProgressRead.value; -+ callbackInfo.throwable = running.inProgressRead.throwable; -+ callbackInfo.completeNow = true; -+ return running; -+ } -+ -+ callbackInfo.read = running.inProgressRead; -+ -+ return running; -+ } -+ -+ // at this stage we have to use the in progress write's data to avoid an order issue -+ -+ if (!pendingWrite.addToAsyncWaiters(onComplete)) { -+ // data is ready now -+ callbackInfo.data = pendingWrite.value; -+ callbackInfo.throwable = pendingWrite.throwable; -+ callbackInfo.completeNow = true; -+ return running; -+ } -+ -+ callbackInfo.write = pendingWrite; -+ -+ return running; -+ }; -+ -+ final ChunkIOTask ret = taskController.chunkTasks.compute(key, compute); -+ -+ // needs to be scheduled -+ if (callbackInfo.tasksNeedReadScheduling) { -+ taskController.startTask(ret); -+ ret.scheduleReadIO(); -+ } else if (callbackInfo.completeNow) { -+ try { -+ onComplete.accept(callbackInfo.data == null ? null : callbackInfo.data.copy(), callbackInfo.throwable); -+ } catch (final Throwable thr) { -+ LOGGER.error("Callback " + ConcurrentUtil.genericToString(onComplete) + " synchronously failed to handle chunk data for task " + ret.toString(), thr); -+ } -+ } else { -+ // we're waiting on a task we didn't schedule, so raise its priority to what we want -+ ret.raisePriority(priority); -+ } -+ -+ return new CancellableRead(onComplete, callbackInfo.read, callbackInfo.write); -+ } -+ -+ private static final class ImmediateCallbackCompletion { -+ -+ private CompoundTag data; -+ private Throwable throwable; -+ private boolean completeNow; -+ private boolean tasksNeedReadScheduling; -+ private ChunkIOTask.InProgressRead read; -+ private ChunkIOTask.InProgressWrite write; -+ -+ } -+ -+ /** -+ * Schedules a load task to be executed asynchronously, and blocks on that task. -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param type Regionfile type -+ * @param priority Minimum priority to load the data at. -+ * -+ * @return The chunk data for the chunk. Note that a {@code null} result means the chunk or regionfile does not exist on disk. -+ * -+ * @throws IOException If the load fails for any reason -+ */ -+ public static CompoundTag loadData(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -+ final Priority priority) throws IOException { -+ final CompletableFuture ret = new CompletableFuture<>(); -+ -+ MoonriseRegionFileIO.loadDataAsync(world, chunkX, chunkZ, type, (final CompoundTag compound, final Throwable thr) -> { -+ if (thr != null) { -+ ret.completeExceptionally(thr); -+ } else { -+ ret.complete(compound); -+ } -+ }, true, priority); -+ -+ try { -+ return ret.join(); -+ } catch (final CompletionException ex) { -+ throw new IOException(ex); -+ } -+ } -+ -+ private static final class CancellableRead implements Cancellable { -+ -+ private BiConsumer callback; -+ private ChunkIOTask.InProgressRead read; -+ private ChunkIOTask.InProgressWrite write; -+ -+ private CancellableRead(final BiConsumer callback, -+ final ChunkIOTask.InProgressRead read, -+ final ChunkIOTask.InProgressWrite write) { -+ this.callback = callback; -+ this.read = read; -+ this.write = write; -+ } -+ -+ @Override -+ public boolean cancel() { -+ final BiConsumer callback = this.callback; -+ final ChunkIOTask.InProgressRead read = this.read; -+ final ChunkIOTask.InProgressWrite write = this.write; -+ -+ if (callback == null || (read == null && write == null)) { -+ return false; -+ } -+ -+ this.callback = null; -+ this.read = null; -+ this.write = null; -+ -+ if (read != null) { -+ return read.cancel(callback); -+ } -+ if (write != null) { -+ return write.cancel(callback); -+ } -+ -+ // unreachable -+ throw new InternalError(); -+ } -+ } -+ -+ private static final class CancellableReads implements Cancellable { -+ -+ private Cancellable[] reads; -+ private static final VarHandle READS_HANDLE = ConcurrentUtil.getVarHandle(CancellableReads.class, "reads", Cancellable[].class); -+ -+ private CancellableReads(final Cancellable[] reads) { -+ this.reads = reads; -+ } -+ -+ @Override -+ public boolean cancel() { -+ final Cancellable[] reads = (Cancellable[])READS_HANDLE.getAndSet((CancellableReads)this, (Cancellable[])null); -+ -+ if (reads == null) { -+ return false; -+ } -+ -+ boolean ret = false; -+ -+ for (final Cancellable read : reads) { -+ ret |= read.cancel(); -+ } -+ -+ return ret; -+ } -+ } -+ -+ private static final class ChunkIOTask { -+ -+ private final ServerLevel world; -+ private final RegionDataController regionDataController; -+ private final int chunkX; -+ private final int chunkZ; -+ private Priority priority; -+ private PrioritisedExecutor.PrioritisedTask currentTask; -+ -+ private final InProgressRead inProgressRead; -+ private volatile InProgressWrite inProgressWrite; -+ private final ReferenceOpenHashSet allPendingWrites = new ReferenceOpenHashSet<>(); -+ -+ private RegionDataController.ReadData readData; -+ private RegionDataController.WriteData writeData; -+ private boolean failedWrite; -+ -+ public ChunkIOTask(final ServerLevel world, final RegionDataController regionDataController, -+ final int chunkX, final int chunkZ, final Priority priority, final InProgressRead inProgressRead) { -+ this.world = world; -+ this.regionDataController = regionDataController; -+ this.chunkX = chunkX; -+ this.chunkZ = chunkZ; -+ this.priority = priority; -+ this.inProgressRead = inProgressRead; -+ } -+ -+ public Priority getPriority() { -+ synchronized (this) { -+ return this.priority; -+ } -+ } -+ -+ // must hold lock on this object -+ private void updatePriority(final Priority priority) { -+ this.priority = priority; -+ if (this.currentTask != null) { -+ this.currentTask.setPriority(priority); -+ } -+ for (final InProgressWrite write : this.allPendingWrites) { -+ if (write.writeTask != null) { -+ write.writeTask.setPriority(priority); -+ } -+ } -+ } -+ -+ public boolean setPriority(final Priority priority) { -+ synchronized (this) { -+ if (this.priority == priority) { -+ return false; -+ } -+ -+ this.updatePriority(priority); -+ -+ return true; -+ } -+ } -+ -+ public boolean raisePriority(final Priority priority) { -+ synchronized (this) { -+ if (this.priority.isHigherOrEqualPriority(priority)) { -+ return false; -+ } -+ -+ this.updatePriority(priority); -+ -+ return true; -+ } -+ } -+ -+ public boolean lowerPriority(final Priority priority) { -+ synchronized (this) { -+ if (this.priority.isLowerOrEqualPriority(priority)) { -+ return false; -+ } -+ -+ this.updatePriority(priority); -+ -+ return true; -+ } -+ } -+ -+ private void pushPendingWrite(final InProgressWrite write) { -+ this.inProgressWrite = write; -+ synchronized (this) { -+ this.allPendingWrites.add(write); -+ if (write.writeTask != null) { -+ write.writeTask.setPriority(this.priority); -+ } -+ } -+ } -+ -+ private void pendingWriteComplete(final InProgressWrite write) { -+ synchronized (this) { -+ this.allPendingWrites.remove(write); -+ } -+ } -+ -+ public void scheduleReadIO() { -+ final PrioritisedExecutor.PrioritisedTask task; -+ synchronized (this) { -+ task = this.regionDataController.ioScheduler.createTask(this.chunkX, this.chunkZ, this::performReadIO, this.priority); -+ this.currentTask = task; -+ } -+ task.queue(); -+ } -+ -+ private void performReadIO() { -+ final InProgressRead read = this.inProgressRead; -+ final long chunkKey = CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ); -+ -+ final boolean[] canRead = new boolean[] { true }; -+ -+ if (read.hasNoWaiters()) { -+ // cancelled read? go to task controller to confirm -+ final ChunkIOTask inMap = this.regionDataController.chunkTasks.compute(chunkKey, (final long keyInMap, final ChunkIOTask valueInMap) -> { -+ if (valueInMap == null) { -+ throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkIOTask.this.toString() + ", report this!"); -+ } -+ if (valueInMap != ChunkIOTask.this) { -+ throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkIOTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); -+ } -+ -+ if (!read.hasNoWaiters()) { -+ return valueInMap; -+ } else { -+ canRead[0] = false; -+ } -+ -+ if (valueInMap.inProgressWrite != null) { -+ return valueInMap; -+ } -+ -+ return null; -+ }); -+ -+ if (inMap == null) { -+ this.regionDataController.endTask(this); -+ // read is cancelled - and no write pending, so we're done -+ return; -+ } -+ // if there is a write in progress, we don't actually have to worry about waiters gaining new entries - -+ // the readers will just use the in progress write, so the value in canRead is good to use without -+ // further synchronisation. -+ } -+ -+ if (canRead[0]) { -+ RegionDataController.ReadData readData = null; -+ Throwable throwable = null; -+ -+ try { -+ readData = this.regionDataController.readData(this.chunkX, this.chunkZ); -+ } catch (final Throwable thr) { -+ throwable = thr; -+ LOGGER.error("Failed to read chunk data for task: " + this.toString(), thr); -+ } -+ -+ if (throwable != null) { -+ this.finishRead(null, throwable); -+ } else { -+ switch (readData.result()) { -+ case NO_DATA: -+ case SYNC_READ: { -+ this.finishRead(readData.syncRead(), null); -+ break; -+ } -+ case HAS_DATA: { -+ this.readData = readData; -+ this.scheduleReadDecompress(); -+ // read will handle write scheduling -+ return; -+ } -+ default: { -+ throw new IllegalStateException("Unknown state: " + readData.result()); -+ } -+ } -+ } -+ } -+ -+ if (!this.tryAbortWrite()) { -+ this.scheduleWriteCompress(); -+ } -+ } -+ -+ private void scheduleReadDecompress() { -+ final PrioritisedExecutor.PrioritisedTask task; -+ synchronized (this) { -+ task = this.regionDataController.compressionExecutor.createTask(this::performReadDecompress, this.priority); -+ this.currentTask = task; -+ } -+ task.queue(); -+ } -+ -+ private void performReadDecompress() { -+ final RegionDataController.ReadData readData = this.readData; -+ this.readData = null; -+ -+ CompoundTag compoundTag = null; -+ Throwable throwable = null; -+ -+ try { -+ compoundTag = this.regionDataController.finishRead(this.chunkX, this.chunkZ, readData); -+ } catch (final Throwable thr) { -+ throwable = thr; -+ LOGGER.error("Failed to decompress chunk data for task: " + this.toString(), thr); -+ } -+ -+ if (compoundTag == null) { -+ // need to re-try from the start -+ this.scheduleReadIO(); -+ return; -+ } -+ -+ this.finishRead(compoundTag, throwable); -+ if (!this.tryAbortWrite()) { -+ this.scheduleWriteCompress(); -+ } -+ } -+ -+ private void finishRead(final CompoundTag compoundTag, final Throwable throwable) { -+ this.inProgressRead.complete(this, compoundTag, throwable); -+ } -+ -+ public void scheduleWriteCompress() { -+ final InProgressWrite inProgressWrite = this.inProgressWrite; -+ -+ final PrioritisedExecutor.PrioritisedTask task; -+ synchronized (this) { -+ task = this.regionDataController.compressionExecutor.createTask(() -> { -+ ChunkIOTask.this.performWriteCompress(inProgressWrite); -+ }, this.priority); -+ this.currentTask = task; -+ } -+ -+ inProgressWrite.addToWaiters(this, (final CompoundTag data, final Throwable throwable) -> { -+ task.queue(); -+ }); -+ } -+ -+ private boolean tryAbortWrite() { -+ final long chunkKey = CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ); -+ if (this.inProgressWrite == null) { -+ final ChunkIOTask inMap = this.regionDataController.chunkTasks.compute(chunkKey, (final long keyInMap, final ChunkIOTask valueInMap) -> { -+ if (valueInMap == null) { -+ throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkIOTask.this.toString() + ", report this!"); -+ } -+ if (valueInMap != ChunkIOTask.this) { -+ throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkIOTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); -+ } -+ -+ if (valueInMap.inProgressWrite != null) { -+ return valueInMap; -+ } -+ -+ return null; -+ }); -+ -+ if (inMap == null) { -+ this.regionDataController.endTask(this); -+ return true; // set the task value to null, indicating we're done -+ } // else: inProgressWrite changed, so now we have something to write -+ } -+ -+ return false; -+ } -+ -+ private void performWriteCompress(final InProgressWrite inProgressWrite) { -+ final CompoundTag write = inProgressWrite.value; -+ if (!inProgressWrite.isComplete()) { -+ throw new IllegalStateException("Should be writable"); -+ } -+ -+ RegionDataController.WriteData writeData = null; -+ boolean failedWrite = false; -+ -+ try { -+ writeData = this.regionDataController.startWrite(this.chunkX, this.chunkZ, write); -+ } catch (final Throwable thr) { -+ // TODO implement this? -+ /*if (thr instanceof RegionFileStorage.RegionFileSizeException) { -+ final int maxSize = RegionFile.MAX_CHUNK_SIZE / (1024 * 1024); -+ LOGGER.error("Chunk at (" + this.chunkX + "," + this.chunkZ + ") in '" + WorldUtil.getWorldName(this.world) + "' exceeds max size of " + maxSize + "MiB, it has been deleted from disk."); -+ } else */ -+ { -+ failedWrite = thr instanceof IOException; -+ LOGGER.error("Failed to write chunk data for task: " + this.toString(), thr); -+ } -+ } -+ -+ if (writeData == null) { -+ // null if a throwable was encountered -+ -+ // we cannot continue to the I/O stage here, so try to complete -+ -+ if (this.tryCompleteWrite(inProgressWrite, failedWrite)) { -+ return; -+ } else { -+ // fetch new data and try again -+ this.scheduleWriteCompress(); -+ return; -+ } -+ } else { -+ // writeData != null && !failedWrite -+ // we can continue to I/O stage -+ this.writeData = writeData; -+ this.scheduleWriteIO(inProgressWrite); -+ return; -+ } -+ } -+ -+ private void scheduleWriteIO(final InProgressWrite inProgressWrite) { -+ final PrioritisedExecutor.PrioritisedTask task; -+ synchronized (this) { -+ task = this.regionDataController.ioScheduler.createTask(this.chunkX, this.chunkZ, () -> { -+ ChunkIOTask.this.runWriteIO(inProgressWrite); -+ }, this.priority); -+ this.currentTask = task; -+ } -+ task.queue(); -+ } -+ -+ private void runWriteIO(final InProgressWrite inProgressWrite) { -+ RegionDataController.WriteData writeData = this.writeData; -+ this.writeData = null; -+ -+ boolean failedWrite = false; -+ -+ try { -+ this.regionDataController.finishWrite(this.chunkX, this.chunkZ, writeData); -+ } catch (final Throwable thr) { -+ failedWrite = thr instanceof IOException; -+ LOGGER.error("Failed to write chunk data for task: " + this.toString(), thr); -+ } -+ -+ if (!this.tryCompleteWrite(inProgressWrite, failedWrite)) { -+ // fetch new data and try again -+ this.scheduleWriteCompress(); -+ } -+ return; -+ } -+ -+ private boolean tryCompleteWrite(final InProgressWrite written, final boolean failedWrite) { -+ final long chunkKey = CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ); -+ -+ final boolean[] done = new boolean[] { false }; -+ -+ this.regionDataController.chunkTasks.compute(chunkKey, (final long keyInMap, final ChunkIOTask valueInMap) -> { -+ if (valueInMap == null) { -+ throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkIOTask.this.toString() + ", report this!"); -+ } -+ if (valueInMap != ChunkIOTask.this) { -+ throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkIOTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); -+ } -+ if (valueInMap.inProgressWrite == written) { -+ valueInMap.failedWrite = failedWrite; -+ done[0] = true; -+ // keep the data in map if we failed the write so we can try to prevent data loss -+ return failedWrite ? valueInMap : null; -+ } -+ // different data than expected, means we need to retry write -+ return valueInMap; -+ }); -+ -+ if (done[0]) { -+ this.regionDataController.endTask(this); -+ return true; -+ } -+ return false; -+ } -+ -+ @Override -+ public String toString() { -+ return "Task for world: '" + WorldUtil.getWorldName(this.world) + "' at (" + this.chunkX + "," -+ + this.chunkZ + ") type: " + this.regionDataController.type.name() + ", hash: " + this.hashCode(); -+ } -+ -+ private static final class InProgressRead { -+ -+ private static final Logger LOGGER = LoggerFactory.getLogger(InProgressRead.class); -+ -+ private CompoundTag value; -+ private Throwable throwable; -+ private final MultiThreadedQueue> callbacks = new MultiThreadedQueue<>(); -+ -+ public boolean hasNoWaiters() { -+ return this.callbacks.isEmpty(); -+ } -+ -+ public boolean addToAsyncWaiters(final BiConsumer callback) { -+ return this.callbacks.add(callback); -+ } -+ -+ public boolean cancel(final BiConsumer callback) { -+ return this.callbacks.remove(callback); -+ } -+ -+ public void complete(final ChunkIOTask task, final CompoundTag value, final Throwable throwable) { -+ this.value = value; -+ this.throwable = throwable; -+ -+ BiConsumer consumer; -+ while ((consumer = this.callbacks.pollOrBlockAdds()) != null) { -+ try { -+ consumer.accept(value == null ? null : value.copy(), throwable); -+ } catch (final Throwable thr) { -+ LOGGER.error("Callback " + ConcurrentUtil.genericToString(consumer) + " failed to handle chunk data (read) for task " + task.toString(), thr); -+ } -+ } -+ } -+ } -+ -+ private static final class InProgressWrite { -+ -+ private static final Logger LOGGER = LoggerFactory.getLogger(InProgressWrite.class); -+ -+ private CompoundTag value; -+ private Throwable throwable; -+ private volatile boolean complete; -+ private final MultiThreadedQueue> callbacks = new MultiThreadedQueue<>(); -+ -+ private final PrioritisedExecutor.PrioritisedTask writeTask; -+ -+ public InProgressWrite(final PrioritisedExecutor.PrioritisedTask writeTask) { -+ this.writeTask = writeTask; -+ } -+ -+ public boolean isComplete() { -+ return this.complete; -+ } -+ -+ public void schedule(final ChunkIOTask task, final Consumer> scheduler) { -+ scheduler.accept((final CompoundTag data, final Throwable throwable) -> { -+ InProgressWrite.this.complete(task, data, throwable); -+ }); -+ } -+ -+ public boolean addToAsyncWaiters(final BiConsumer callback) { -+ return this.callbacks.add(callback); -+ } -+ -+ public void addToWaiters(final ChunkIOTask task, final BiConsumer consumer) { -+ if (!this.callbacks.add(consumer)) { -+ this.syncAccept(task, consumer, this.value, this.throwable); -+ } -+ } -+ -+ private void syncAccept(final ChunkIOTask task, final BiConsumer consumer, final CompoundTag value, final Throwable throwable) { -+ try { -+ consumer.accept(value == null ? null : value.copy(), throwable); -+ } catch (final Throwable thr) { -+ LOGGER.error("Callback " + ConcurrentUtil.genericToString(consumer) + " failed to handle chunk data (write) for task " + task.toString(), thr); -+ } -+ } -+ -+ public void complete(final ChunkIOTask task, final CompoundTag value, final Throwable throwable) { -+ this.value = value; -+ this.throwable = throwable; -+ this.complete = true; -+ -+ task.pendingWriteComplete(this); -+ -+ BiConsumer consumer; -+ while ((consumer = this.callbacks.pollOrBlockAdds()) != null) { -+ this.syncAccept(task, consumer, value, throwable); -+ } -+ } -+ -+ public boolean cancel(final BiConsumer callback) { -+ return this.callbacks.remove(callback); -+ } -+ } -+ } -+ -+ public static abstract class RegionDataController { -+ -+ public final RegionFileType type; -+ private final PrioritisedExecutor compressionExecutor; -+ private final IOScheduler ioScheduler; -+ private final ConcurrentLong2ReferenceChainedHashTable chunkTasks = new ConcurrentLong2ReferenceChainedHashTable<>(); -+ -+ private final AtomicLong inProgressTasks = new AtomicLong(); -+ -+ public RegionDataController(final RegionFileType type, final PrioritisedExecutor ioExecutor, -+ final PrioritisedExecutor compressionExecutor) { -+ this.type = type; -+ this.compressionExecutor = compressionExecutor; -+ this.ioScheduler = new IOScheduler(ioExecutor); -+ } -+ -+ final void startTask(final ChunkIOTask task) { -+ this.inProgressTasks.getAndIncrement(); -+ } -+ -+ final void endTask(final ChunkIOTask task) { -+ this.inProgressTasks.getAndDecrement(); -+ } -+ -+ public boolean hasTasks() { -+ return this.inProgressTasks.get() != 0L; -+ } -+ -+ public long getTotalWorkingTasks() { -+ return this.inProgressTasks.get(); -+ } -+ -+ public abstract RegionFileStorage getCache(); -+ -+ public static record WriteData(CompoundTag input, WriteResult result, DataOutputStream output, IORunnable write) { -+ public static enum WriteResult { -+ WRITE, -+ DELETE; -+ } -+ } -+ -+ public abstract WriteData startWrite(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException; -+ -+ public abstract void finishWrite(final int chunkX, final int chunkZ, final WriteData writeData) throws IOException; -+ -+ public static record ReadData(ReadResult result, DataInputStream input, CompoundTag syncRead) { -+ public static enum ReadResult { -+ NO_DATA, -+ HAS_DATA, -+ SYNC_READ; -+ } -+ } -+ -+ public abstract ReadData readData(final int chunkX, final int chunkZ) throws IOException; -+ -+ // if the return value is null, then the caller needs to re-try with a new call to readData() -+ public abstract CompoundTag finishRead(final int chunkX, final int chunkZ, final ReadData readData) throws IOException; -+ -+ public static interface IORunnable { -+ -+ public void run(final RegionFile regionFile) throws IOException; -+ -+ } -+ } -+ -+ private static final class IOScheduler { -+ -+ private final ConcurrentLong2ReferenceChainedHashTable regionTasks = new ConcurrentLong2ReferenceChainedHashTable<>(); -+ private final PrioritisedExecutor executor; -+ -+ public IOScheduler(final PrioritisedExecutor executor) { -+ this.executor = executor; -+ } -+ -+ public PrioritisedExecutor.PrioritisedTask createTask(final int chunkX, final int chunkZ, -+ final Runnable run, final Priority priority) { -+ final PrioritisedExecutor.PrioritisedTask[] ret = new PrioritisedExecutor.PrioritisedTask[1]; -+ final long subOrder = this.executor.generateNextSubOrder(); -+ this.regionTasks.compute(CoordinateUtils.getChunkKey(chunkX >> REGION_FILE_SHIFT, chunkZ >> REGION_FILE_SHIFT), -+ (final long regionKey, final RegionIOTasks existing) -> { -+ final RegionIOTasks res; -+ if (existing != null) { -+ res = existing; -+ } else { -+ res = new RegionIOTasks(regionKey, IOScheduler.this); -+ } -+ -+ ret[0] = res.createTask(run, priority, subOrder); -+ -+ return res; -+ }); -+ -+ return ret[0]; -+ } -+ } -+ -+ private static final class RegionIOTasks implements Runnable { -+ -+ private static final Logger LOGGER = LoggerFactory.getLogger(RegionIOTasks.class); -+ -+ private final PrioritisedTaskQueue queue = new PrioritisedTaskQueue(); -+ private final long regionKey; -+ private final IOScheduler ioScheduler; -+ private long createdTasks; -+ private long executedTasks; -+ -+ private PrioritisedExecutor.PrioritisedTask task; -+ -+ public RegionIOTasks(final long regionKey, final IOScheduler ioScheduler) { -+ this.regionKey = regionKey; -+ this.ioScheduler = ioScheduler; -+ } -+ -+ public PrioritisedExecutor.PrioritisedTask createTask(final Runnable run, final Priority priority, -+ final long subOrder) { -+ ++this.createdTasks; -+ return new WrappedTask(this.queue.createTask(run, priority, subOrder)); -+ } -+ -+ private void adjustTaskPriority() { -+ final PrioritisedTaskQueue.PrioritySubOrderPair priority = this.queue.getHighestPrioritySubOrder(); -+ if (this.task == null) { -+ if (priority == null) { -+ return; -+ } -+ this.task = this.ioScheduler.executor.createTask(this, priority.priority(), priority.subOrder()); -+ this.task.queue(); -+ } else { -+ if (priority == null) { -+ throw new IllegalStateException(); -+ } else { -+ this.task.setPriorityAndSubOrder(priority.priority(), priority.subOrder()); -+ } -+ } -+ } -+ -+ @Override -+ public void run() { -+ final Runnable run; -+ synchronized (this) { -+ run = this.queue.pollTask(); -+ } -+ -+ try { -+ run.run(); -+ } finally { -+ synchronized (this) { -+ this.task = null; -+ this.adjustTaskPriority(); -+ } -+ this.ioScheduler.regionTasks.compute(this.regionKey, (final long keyInMap, final RegionIOTasks tasks) -> { -+ if (tasks != RegionIOTasks.this) { -+ throw new IllegalStateException("Region task mismatch"); -+ } -+ ++tasks.executedTasks; -+ if (tasks.createdTasks != tasks.executedTasks) { -+ return tasks; -+ } -+ -+ if (tasks.task != null) { -+ throw new IllegalStateException("Task may not be null when created==executed"); -+ } -+ -+ return null; -+ }); -+ } -+ } -+ -+ private final class WrappedTask implements PrioritisedExecutor.PrioritisedTask { -+ -+ private final PrioritisedExecutor.PrioritisedTask wrapped; -+ -+ public WrappedTask(final PrioritisedExecutor.PrioritisedTask wrap) { -+ this.wrapped = wrap; -+ } -+ -+ @Override -+ public PrioritisedExecutor getExecutor() { -+ return RegionIOTasks.this.ioScheduler.executor; -+ } -+ -+ @Override -+ public boolean queue() { -+ synchronized (RegionIOTasks.this) { -+ if (this.wrapped.queue()) { -+ RegionIOTasks.this.adjustTaskPriority(); -+ return true; -+ } -+ return false; -+ } -+ } -+ -+ @Override -+ public boolean isQueued() { -+ return this.wrapped.isQueued(); -+ } -+ -+ @Override -+ public boolean cancel() { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public boolean execute() { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public Priority getPriority() { -+ return this.wrapped.getPriority(); -+ } -+ -+ @Override -+ public boolean setPriority(final Priority priority) { -+ synchronized (RegionIOTasks.this) { -+ if (this.wrapped.setPriority(priority) && this.wrapped.isQueued()) { -+ RegionIOTasks.this.adjustTaskPriority(); -+ return true; -+ } -+ return false; -+ } -+ } -+ -+ @Override -+ public boolean raisePriority(final Priority priority) { -+ synchronized (RegionIOTasks.this) { -+ if (this.wrapped.raisePriority(priority) && this.wrapped.isQueued()) { -+ RegionIOTasks.this.adjustTaskPriority(); -+ return true; -+ } -+ return false; -+ } -+ } -+ -+ @Override -+ public boolean lowerPriority(final Priority priority) { -+ synchronized (RegionIOTasks.this) { -+ if (this.wrapped.lowerPriority(priority) && this.wrapped.isQueued()) { -+ RegionIOTasks.this.adjustTaskPriority(); -+ return true; -+ } -+ return false; -+ } -+ } -+ -+ @Override -+ public long getSubOrder() { -+ return this.wrapped.getSubOrder(); -+ } -+ -+ @Override -+ public boolean setSubOrder(final long subOrder) { -+ synchronized (RegionIOTasks.this) { -+ if (this.wrapped.setSubOrder(subOrder) && this.wrapped.isQueued()) { -+ RegionIOTasks.this.adjustTaskPriority(); -+ return true; -+ } -+ return false; -+ } -+ } -+ -+ @Override -+ public boolean raiseSubOrder(final long subOrder) { -+ synchronized (RegionIOTasks.this) { -+ if (this.wrapped.raiseSubOrder(subOrder) && this.wrapped.isQueued()) { -+ RegionIOTasks.this.adjustTaskPriority(); -+ return true; -+ } -+ return false; -+ } -+ } -+ -+ @Override -+ public boolean lowerSubOrder(final long subOrder) { -+ synchronized (RegionIOTasks.this) { -+ if (this.wrapped.lowerSubOrder(subOrder) && this.wrapped.isQueued()) { -+ RegionIOTasks.this.adjustTaskPriority(); -+ return true; -+ } -+ return false; -+ } -+ } -+ -+ @Override -+ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder) { -+ synchronized (RegionIOTasks.this) { -+ if (this.wrapped.setPriorityAndSubOrder(priority, subOrder) && this.wrapped.isQueued()) { -+ RegionIOTasks.this.adjustTaskPriority(); -+ return true; -+ } -+ return false; -+ } -+ } -+ } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java -deleted file mode 100644 -index 3218cbf84f54daf06e84442d5eb1a36d8da6b215..0000000000000000000000000000000000000000 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java -+++ /dev/null -@@ -1,1240 +0,0 @@ --package ca.spottedleaf.moonrise.patches.chunk_system.io; -- --import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; --import ca.spottedleaf.concurrentutil.executor.Cancellable; --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedQueueExecutorThread; --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadedTaskQueue; --import ca.spottedleaf.concurrentutil.function.BiLong1Function; --import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; --import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; --import ca.spottedleaf.moonrise.common.util.CoordinateUtils; --import ca.spottedleaf.moonrise.common.util.TickThread; --import ca.spottedleaf.moonrise.common.util.WorldUtil; --import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; --import net.minecraft.nbt.CompoundTag; --import net.minecraft.server.level.ServerLevel; --import net.minecraft.world.level.ChunkPos; --import net.minecraft.world.level.chunk.storage.RegionFile; --import net.minecraft.world.level.chunk.storage.RegionFileStorage; --import org.slf4j.Logger; --import org.slf4j.LoggerFactory; --import java.io.IOException; --import java.lang.invoke.VarHandle; --import java.util.concurrent.CompletableFuture; --import java.util.concurrent.CompletionException; --import java.util.concurrent.atomic.AtomicInteger; --import java.util.function.BiConsumer; --import java.util.function.Consumer; --import java.util.function.Function; -- --/** -- * Prioritised RegionFile I/O executor, responsible for all RegionFile access. -- *

    -- * All functions provided are MT-Safe, however certain ordering constraints are recommended: -- *

  • -- * Chunk saves may not occur for unloaded chunks. -- *
  • -- *
  • -- * Tasks must be scheduled on the chunk scheduler thread. -- *
  • -- * By following these constraints, no chunk data loss should occur with the exception of underlying I/O problems. -- *

    -- */ --public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { -- -- private static final Logger LOGGER = LoggerFactory.getLogger(RegionFileIOThread.class); -- -- /** -- * The kinds of region files controlled by the region file thread. Add more when needed, and ensure -- * getControllerFor is updated. -- */ -- public static enum RegionFileType { -- CHUNK_DATA, -- POI_DATA, -- ENTITY_DATA; -- } -- -- private static final RegionFileType[] CACHED_REGIONFILE_TYPES = RegionFileType.values(); -- -- public static ChunkDataController getControllerFor(final ServerLevel world, final RegionFileType type) { -- switch (type) { -- case CHUNK_DATA: -- return ((ChunkSystemServerLevel)world).moonrise$getChunkDataController(); -- case POI_DATA: -- return ((ChunkSystemServerLevel)world).moonrise$getPoiChunkDataController(); -- case ENTITY_DATA: -- return ((ChunkSystemServerLevel)world).moonrise$getEntityChunkDataController(); -- default: -- throw new IllegalStateException("Unknown controller type " + type); -- } -- } -- -- /** -- * Collects regionfile data for a certain chunk. -- */ -- public static final class RegionFileData { -- -- private final boolean[] hasResult = new boolean[CACHED_REGIONFILE_TYPES.length]; -- private final CompoundTag[] data = new CompoundTag[CACHED_REGIONFILE_TYPES.length]; -- private final Throwable[] throwables = new Throwable[CACHED_REGIONFILE_TYPES.length]; -- -- /** -- * Sets the result associated with the specified regionfile type. Note that -- * results can only be set once per regionfile type. -- * -- * @param type The regionfile type. -- * @param data The result to set. -- */ -- public void setData(final RegionFileType type, final CompoundTag data) { -- final int index = type.ordinal(); -- -- if (this.hasResult[index]) { -- throw new IllegalArgumentException("Result already exists for type " + type); -- } -- this.hasResult[index] = true; -- this.data[index] = data; -- } -- -- /** -- * Sets the result associated with the specified regionfile type. Note that -- * results can only be set once per regionfile type. -- * -- * @param type The regionfile type. -- * @param throwable The result to set. -- */ -- public void setThrowable(final RegionFileType type, final Throwable throwable) { -- final int index = type.ordinal(); -- -- if (this.hasResult[index]) { -- throw new IllegalArgumentException("Result already exists for type " + type); -- } -- this.hasResult[index] = true; -- this.throwables[index] = throwable; -- } -- -- /** -- * Returns whether there is a result for the specified regionfile type. -- * -- * @param type Specified regionfile type. -- * -- * @return Whether a result exists for {@code type}. -- */ -- public boolean hasResult(final RegionFileType type) { -- return this.hasResult[type.ordinal()]; -- } -- -- /** -- * Returns the data result for the regionfile type. -- * -- * @param type Specified regionfile type. -- * -- * @throws IllegalArgumentException If the result has not been set for {@code type}. -- * @return The data result for the specified type. If the result is a {@code Throwable}, -- * then returns {@code null}. -- */ -- public CompoundTag getData(final RegionFileType type) { -- final int index = type.ordinal(); -- -- if (!this.hasResult[index]) { -- throw new IllegalArgumentException("Result does not exist for type " + type); -- } -- -- return this.data[index]; -- } -- -- /** -- * Returns the throwable result for the regionfile type. -- * -- * @param type Specified regionfile type. -- * -- * @throws IllegalArgumentException If the result has not been set for {@code type}. -- * @return The throwable result for the specified type. If the result is an {@code CompoundTag}, -- * then returns {@code null}. -- */ -- public Throwable getThrowable(final RegionFileType type) { -- final int index = type.ordinal(); -- -- if (!this.hasResult[index]) { -- throw new IllegalArgumentException("Result does not exist for type " + type); -- } -- -- return this.throwables[index]; -- } -- } -- -- private static final Object INIT_LOCK = new Object(); -- -- static RegionFileIOThread[] threads; -- -- /* needs to be consistent given a set of parameters */ -- static RegionFileIOThread selectThread(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { -- if (threads == null) { -- throw new IllegalStateException("Threads not initialised"); -- } -- -- final int regionX = chunkX >> 5; -- final int regionZ = chunkZ >> 5; -- final int typeOffset = type.ordinal(); -- -- return threads[(System.identityHashCode(world) + regionX + regionZ + typeOffset) % threads.length]; -- } -- -- /** -- * Shuts down the I/O executor(s). Watis for all tasks to complete if specified. -- * Tasks queued during this call might not be accepted, and tasks queued after will not be accepted. -- * -- * @param wait Whether to wait until all tasks have completed. -- */ -- public static void close(final boolean wait) { -- for (int i = 0, len = threads.length; i < len; ++i) { -- threads[i].close(false, true); -- } -- if (wait) { -- RegionFileIOThread.flush(); -- } -- } -- -- public static long[] getExecutedTasks() { -- final long[] ret = new long[threads.length]; -- for (int i = 0, len = threads.length; i < len; ++i) { -- ret[i] = threads[i].getTotalTasksExecuted(); -- } -- -- return ret; -- } -- -- public static long[] getTasksScheduled() { -- final long[] ret = new long[threads.length]; -- for (int i = 0, len = threads.length; i < len; ++i) { -- ret[i] = threads[i].getTotalTasksScheduled(); -- } -- return ret; -- } -- -- public static void flush() { -- for (int i = 0, len = threads.length; i < len; ++i) { -- threads[i].waitUntilAllExecuted(); -- } -- } -- -- public static void flushRegionStorages(final ServerLevel world) throws IOException { -- for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { -- getControllerFor(world, type).getCache().flush(); -- } -- } -- -- public static void partialFlush(final int totalTasksRemaining) { -- long failures = 1L; // start out at 0.25ms -- -- for (;;) { -- final long[] executed = getExecutedTasks(); -- final long[] scheduled = getTasksScheduled(); -- -- long sum = 0; -- for (int i = 0; i < executed.length; ++i) { -- sum += scheduled[i] - executed[i]; -- } -- -- if (sum <= totalTasksRemaining) { -- break; -- } -- -- failures = ConcurrentUtil.linearLongBackoff(failures, 250_000L, 5_000_000L); // 500us, 5ms -- } -- } -- -- /** -- * Inits the executor with the specified number of threads. -- * -- * @param threads Specified number of threads. -- */ -- public static void init(final int threads) { -- synchronized (INIT_LOCK) { -- if (RegionFileIOThread.threads != null) { -- throw new IllegalStateException("Already initialised threads"); -- } -- -- RegionFileIOThread.threads = new RegionFileIOThread[threads]; -- -- for (int i = 0; i < threads; ++i) { -- RegionFileIOThread.threads[i] = new RegionFileIOThread(i); -- RegionFileIOThread.threads[i].start(); -- } -- } -- } -- -- public static void deinit() { -- if (true) { // Paper -- // TODO does this cause issues with mods? how to implement -- close(true); -- synchronized (INIT_LOCK) { -- RegionFileIOThread.threads = null; -- } -- } else { RegionFileIOThread.flush(); } -- } -- -- private RegionFileIOThread(final int threadNumber) { -- super(new PrioritisedThreadedTaskQueue(), (int)(1.0e6)); // 1.0ms spinwait time -- this.setName("RegionFile I/O Thread #" + threadNumber); -- this.setPriority(Thread.NORM_PRIORITY - 2); // we keep priority close to normal because threads can wait on us -- this.setUncaughtExceptionHandler((final Thread thread, final Throwable thr) -> { -- LOGGER.error("Uncaught exception thrown from I/O thread, report this! Thread: " + thread.getName(), thr); -- }); -- } -- -- /** -- * Returns whether the current thread is a regionfile I/O executor. -- * @return Whether the current thread is a regionfile I/O executor. -- */ -- public static boolean isRegionFileThread() { -- return Thread.currentThread() instanceof RegionFileIOThread; -- } -- -- /** -- * Returns the priority associated with blocking I/O based on the current thread. The goal is to avoid -- * dumb plugins from taking away priority from threads we consider crucial. -- * @return The priroity to use with blocking I/O on the current thread. -- */ -- public static Priority getIOBlockingPriorityForCurrentThread() { -- if (TickThread.isTickThread()) { -- return Priority.BLOCKING; -- } -- return Priority.HIGHEST; -- } -- -- /** -- * Returns the current {@code CompoundTag} pending for write for the specified chunk & regionfile type. -- * Note that this does not copy the result, so do not modify the result returned. -- * -- * @param world Specified world. -- * @param chunkX Specified chunk x. -- * @param chunkZ Specified chunk z. -- * @param type Specified regionfile type. -- * -- * @return The compound tag associated for the specified chunk. {@code null} if no write was pending, or if {@code null} is the write pending. -- */ -- public static CompoundTag getPendingWrite(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { -- final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -- return thread.getPendingWriteInternal(world, chunkX, chunkZ, type); -- } -- -- CompoundTag getPendingWriteInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { -- final ChunkDataController taskController = getControllerFor(world, type); -- final ChunkDataTask task = taskController.tasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -- -- if (task == null) { -- return null; -- } -- -- final CompoundTag ret = task.inProgressWrite; -- -- return ret == ChunkDataTask.NOTHING_TO_WRITE ? null : ret; -- } -- -- /** -- * Returns the priority for the specified regionfile type for the specified chunk. -- * @param world Specified world. -- * @param chunkX Specified chunk x. -- * @param chunkZ Specified chunk z. -- * @param type Specified regionfile type. -- * @return The priority for the chunk -- */ -- public static Priority getPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { -- final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -- return thread.getPriorityInternal(world, chunkX, chunkZ, type); -- } -- -- Priority getPriorityInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { -- final ChunkDataController taskController = getControllerFor(world, type); -- final ChunkDataTask task = taskController.tasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -- -- if (task == null) { -- return Priority.COMPLETING; -- } -- -- return task.prioritisedTask.getPriority(); -- } -- -- /** -- * Sets the priority for all regionfile types for the specified chunk. Note that great care should -- * be taken using this method, as there can be multiple tasks tied to the same chunk that want different -- * priorities. -- * -- * @param world Specified world. -- * @param chunkX Specified chunk x. -- * @param chunkZ Specified chunk z. -- * @param priority New priority. -- * -- * @see #raisePriority(ServerLevel, int, int, Priority) -- * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) -- * @see #lowerPriority(ServerLevel, int, int, Priority) -- * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) -- */ -- public static void setPriority(final ServerLevel world, final int chunkX, final int chunkZ, -- final Priority priority) { -- for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { -- RegionFileIOThread.setPriority(world, chunkX, chunkZ, type, priority); -- } -- } -- -- /** -- * Sets the priority for the specified regionfile type for the specified chunk. Note that great care should -- * be taken using this method, as there can be multiple tasks tied to the same chunk that want different -- * priorities. -- * -- * @param world Specified world. -- * @param chunkX Specified chunk x. -- * @param chunkZ Specified chunk z. -- * @param type Specified regionfile type. -- * @param priority New priority. -- * -- * @see #raisePriority(ServerLevel, int, int, Priority) -- * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) -- * @see #lowerPriority(ServerLevel, int, int, Priority) -- * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) -- */ -- public static void setPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -- final Priority priority) { -- final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -- thread.setPriorityInternal(world, chunkX, chunkZ, type, priority); -- } -- -- void setPriorityInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -- final Priority priority) { -- final ChunkDataController taskController = getControllerFor(world, type); -- final ChunkDataTask task = taskController.tasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -- -- if (task != null) { -- task.prioritisedTask.setPriority(priority); -- } -- } -- -- /** -- * Raises the priority for all regionfile types for the specified chunk. -- * -- * @param world Specified world. -- * @param chunkX Specified chunk x. -- * @param chunkZ Specified chunk z. -- * @param priority New priority. -- * -- * @see #setPriority(ServerLevel, int, int, Priority) -- * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) -- * @see #lowerPriority(ServerLevel, int, int, Priority) -- * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) -- */ -- public static void raisePriority(final ServerLevel world, final int chunkX, final int chunkZ, -- final Priority priority) { -- for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { -- RegionFileIOThread.raisePriority(world, chunkX, chunkZ, type, priority); -- } -- } -- -- /** -- * Raises the priority for the specified regionfile type for the specified chunk. -- * -- * @param world Specified world. -- * @param chunkX Specified chunk x. -- * @param chunkZ Specified chunk z. -- * @param type Specified regionfile type. -- * @param priority New priority. -- * -- * @see #setPriority(ServerLevel, int, int, Priority) -- * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) -- * @see #lowerPriority(ServerLevel, int, int, Priority) -- * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) -- */ -- public static void raisePriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -- final Priority priority) { -- final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -- thread.raisePriorityInternal(world, chunkX, chunkZ, type, priority); -- } -- -- void raisePriorityInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -- final Priority priority) { -- final ChunkDataController taskController = getControllerFor(world, type); -- final ChunkDataTask task = taskController.tasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -- -- if (task != null) { -- task.prioritisedTask.raisePriority(priority); -- } -- } -- -- /** -- * Lowers the priority for all regionfile types for the specified chunk. -- * -- * @param world Specified world. -- * @param chunkX Specified chunk x. -- * @param chunkZ Specified chunk z. -- * @param priority New priority. -- * -- * @see #raisePriority(ServerLevel, int, int, Priority) -- * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) -- * @see #setPriority(ServerLevel, int, int, Priority) -- * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) -- */ -- public static void lowerPriority(final ServerLevel world, final int chunkX, final int chunkZ, -- final Priority priority) { -- for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { -- RegionFileIOThread.lowerPriority(world, chunkX, chunkZ, type, priority); -- } -- } -- -- /** -- * Lowers the priority for the specified regionfile type for the specified chunk. -- * -- * @param world Specified world. -- * @param chunkX Specified chunk x. -- * @param chunkZ Specified chunk z. -- * @param type Specified regionfile type. -- * @param priority New priority. -- * -- * @see #raisePriority(ServerLevel, int, int, Priority) -- * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) -- * @see #setPriority(ServerLevel, int, int, Priority) -- * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) -- */ -- public static void lowerPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -- final Priority priority) { -- final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -- thread.lowerPriorityInternal(world, chunkX, chunkZ, type, priority); -- } -- -- void lowerPriorityInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -- final Priority priority) { -- final ChunkDataController taskController = getControllerFor(world, type); -- final ChunkDataTask task = taskController.tasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -- -- if (task != null) { -- task.prioritisedTask.lowerPriority(priority); -- } -- } -- -- /** -- * Schedules the chunk data to be written asynchronously. -- *

    -- * Impl notes: -- *

    -- *
  • -- * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means -- * saves must be scheduled before a chunk is unloaded. -- *
  • -- *
  • -- * Writes may be called concurrently, although only the "later" write will go through. -- *
  • -- * -- * @param world Chunk's world -- * @param chunkX Chunk's x coordinate -- * @param chunkZ Chunk's z coordinate -- * @param data Chunk's data -- * @param type The regionfile type to write to. -- * -- * @throws IllegalStateException If the file io thread has shutdown. -- */ -- public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data, -- final RegionFileType type) { -- RegionFileIOThread.scheduleSave(world, chunkX, chunkZ, data, type, Priority.NORMAL); -- } -- -- /** -- * Schedules the chunk data to be written asynchronously. -- *

    -- * Impl notes: -- *

    -- *
  • -- * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means -- * saves must be scheduled before a chunk is unloaded. -- *
  • -- *
  • -- * Writes may be called concurrently, although only the "later" write will go through. -- *
  • -- * -- * @param world Chunk's world -- * @param chunkX Chunk's x coordinate -- * @param chunkZ Chunk's z coordinate -- * @param data Chunk's data -- * @param type The regionfile type to write to. -- * @param priority The minimum priority to schedule at. -- * -- * @throws IllegalStateException If the file io thread has shutdown. -- */ -- public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data, -- final RegionFileType type, final Priority priority) { -- final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -- thread.scheduleSaveInternal(world, chunkX, chunkZ, data, type, priority); -- } -- -- void scheduleSaveInternal(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data, -- final RegionFileType type, final Priority priority) { -- final ChunkDataController taskController = getControllerFor(world, type); -- -- final boolean[] created = new boolean[1]; -- final long key = CoordinateUtils.getChunkKey(chunkX, chunkZ); -- final ChunkDataTask task = taskController.tasks.compute(key, (final long keyInMap, final ChunkDataTask taskRunning) -> { -- if (taskRunning == null || taskRunning.failedWrite) { -- // no task is scheduled or the previous write failed - meaning we need to overwrite it -- -- // create task -- final ChunkDataTask newTask = new ChunkDataTask(world, chunkX, chunkZ, taskController, RegionFileIOThread.this, priority); -- newTask.inProgressWrite = data; -- created[0] = true; -- -- return newTask; -- } -- -- taskRunning.inProgressWrite = data; -- -- return taskRunning; -- }); -- -- if (created[0]) { -- task.prioritisedTask.queue(); -- } else { -- task.prioritisedTask.raisePriority(priority); -- } -- } -- -- /** -- * Schedules a load to be executed asynchronously. This task will load all regionfile types, and then call -- * {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean)} -- * for single load. -- *

    -- * Impl notes: -- *

    -- *
  • -- * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -- * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -- * data is undefined behaviour, and can cause deadlock. -- *
  • -- * -- * @param world Chunk's world -- * @param chunkX Chunk's x coordinate -- * @param chunkZ Chunk's z coordinate -- * @param onComplete Consumer to execute once this task has completed -- * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -- * of this call. -- * -- * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -- * -- * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) -- * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) -- * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) -- * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) -- */ -- public static Cancellable loadAllChunkData(final ServerLevel world, final int chunkX, final int chunkZ, -- final Consumer onComplete, final boolean intendingToBlock) { -- return RegionFileIOThread.loadAllChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, Priority.NORMAL); -- } -- -- /** -- * Schedules a load to be executed asynchronously. This task will load all regionfile types, and then call -- * {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority)} -- * for single load. -- *

    -- * Impl notes: -- *

    -- *
  • -- * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -- * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -- * data is undefined behaviour, and can cause deadlock. -- *
  • -- * -- * @param world Chunk's world -- * @param chunkX Chunk's x coordinate -- * @param chunkZ Chunk's z coordinate -- * @param onComplete Consumer to execute once this task has completed -- * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -- * of this call. -- * @param priority The minimum priority to load the data at. -- * -- * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -- * -- * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) -- * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) -- * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) -- * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) -- */ -- public static Cancellable loadAllChunkData(final ServerLevel world, final int chunkX, final int chunkZ, -- final Consumer onComplete, final boolean intendingToBlock, -- final Priority priority) { -- return RegionFileIOThread.loadChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, priority, CACHED_REGIONFILE_TYPES); -- } -- -- /** -- * Schedules a load to be executed asynchronously. This task will load data for the specified regionfile type(s), and -- * then call {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean)} -- * for single load. -- *

    -- * Impl notes: -- *

    -- *
  • -- * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -- * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -- * data is undefined behaviour, and can cause deadlock. -- *
  • -- * -- * @param world Chunk's world -- * @param chunkX Chunk's x coordinate -- * @param chunkZ Chunk's z coordinate -- * @param onComplete Consumer to execute once this task has completed -- * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -- * of this call. -- * @param types The regionfile type(s) to load. -- * -- * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -- * -- * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) -- * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) -- * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) -- * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) -- */ -- public static Cancellable loadChunkData(final ServerLevel world, final int chunkX, final int chunkZ, -- final Consumer onComplete, final boolean intendingToBlock, -- final RegionFileType... types) { -- return RegionFileIOThread.loadChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, Priority.NORMAL, types); -- } -- -- /** -- * Schedules a load to be executed asynchronously. This task will load data for the specified regionfile type(s), and -- * then call {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority)} -- * for single load. -- *

    -- * Impl notes: -- *

    -- *
  • -- * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -- * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -- * data is undefined behaviour, and can cause deadlock. -- *
  • -- * -- * @param world Chunk's world -- * @param chunkX Chunk's x coordinate -- * @param chunkZ Chunk's z coordinate -- * @param onComplete Consumer to execute once this task has completed -- * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -- * of this call. -- * @param types The regionfile type(s) to load. -- * @param priority The minimum priority to load the data at. -- * -- * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -- * -- * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) -- * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) -- * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) -- * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) -- */ -- public static Cancellable loadChunkData(final ServerLevel world, final int chunkX, final int chunkZ, -- final Consumer onComplete, final boolean intendingToBlock, -- final Priority priority, final RegionFileType... types) { -- if (types == null) { -- throw new NullPointerException("Types cannot be null"); -- } -- if (types.length == 0) { -- throw new IllegalArgumentException("Types cannot be empty"); -- } -- -- final RegionFileData ret = new RegionFileData(); -- -- final Cancellable[] reads = new CancellableRead[types.length]; -- final AtomicInteger completions = new AtomicInteger(); -- final int expectedCompletions = types.length; -- -- for (int i = 0; i < expectedCompletions; ++i) { -- final RegionFileType type = types[i]; -- reads[i] = RegionFileIOThread.loadDataAsync(world, chunkX, chunkZ, type, -- (final CompoundTag data, final Throwable throwable) -> { -- if (throwable != null) { -- ret.setThrowable(type, throwable); -- } else { -- ret.setData(type, data); -- } -- -- if (completions.incrementAndGet() == expectedCompletions) { -- onComplete.accept(ret); -- } -- }, intendingToBlock, priority); -- } -- -- return new CancellableReads(reads); -- } -- -- /** -- * Schedules a load to be executed asynchronously. This task will load the specified regionfile type, and then call -- * {@code onComplete}. -- *

    -- * Impl notes: -- *

    -- *
  • -- * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -- * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -- * data is undefined behaviour, and can cause deadlock. -- *
  • -- * -- * @param world Chunk's world -- * @param chunkX Chunk's x coordinate -- * @param chunkZ Chunk's z coordinate -- * @param onComplete Consumer to execute once this task has completed -- * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -- * of this call. -- * -- * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -- * -- * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) -- * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) -- * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) -- * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) -- */ -- public static Cancellable loadDataAsync(final ServerLevel world, final int chunkX, final int chunkZ, -- final RegionFileType type, final BiConsumer onComplete, -- final boolean intendingToBlock) { -- return RegionFileIOThread.loadDataAsync(world, chunkX, chunkZ, type, onComplete, intendingToBlock, Priority.NORMAL); -- } -- -- /** -- * Schedules a load to be executed asynchronously. This task will load the specified regionfile type, and then call -- * {@code onComplete}. -- *

    -- * Impl notes: -- *

    -- *
  • -- * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -- * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -- * data is undefined behaviour, and can cause deadlock. -- *
  • -- * -- * @param world Chunk's world -- * @param chunkX Chunk's x coordinate -- * @param chunkZ Chunk's z coordinate -- * @param onComplete Consumer to execute once this task has completed -- * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -- * of this call. -- * @param priority Minimum priority to load the data at. -- * -- * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -- * -- * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) -- * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) -- * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) -- * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) -- */ -- public static Cancellable loadDataAsync(final ServerLevel world, final int chunkX, final int chunkZ, -- final RegionFileType type, final BiConsumer onComplete, -- final boolean intendingToBlock, final Priority priority) { -- final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -- return thread.loadDataAsyncInternal(world, chunkX, chunkZ, type, onComplete, intendingToBlock, priority); -- } -- -- Cancellable loadDataAsyncInternal(final ServerLevel world, final int chunkX, final int chunkZ, -- final RegionFileType type, final BiConsumer onComplete, -- final boolean intendingToBlock, final Priority priority) { -- final ChunkDataController taskController = getControllerFor(world, type); -- -- final ImmediateCallbackCompletion callbackInfo = new ImmediateCallbackCompletion(); -- -- final long key = CoordinateUtils.getChunkKey(chunkX, chunkZ); -- final BiLong1Function compute = (final long keyInMap, final ChunkDataTask running) -> { -- if (running == null) { -- // not scheduled -- -- // set up task -- final ChunkDataTask newTask = new ChunkDataTask( -- world, chunkX, chunkZ, taskController, RegionFileIOThread.this, priority -- ); -- newTask.inProgressRead = new InProgressRead(); -- newTask.inProgressRead.addToAsyncWaiters(onComplete); -- -- callbackInfo.tasksNeedsScheduling = true; -- return newTask; -- } -- -- final CompoundTag pendingWrite = running.inProgressWrite; -- -- if (pendingWrite == ChunkDataTask.NOTHING_TO_WRITE) { -- // need to add to waiters here, because the regionfile thread will use compute() to lock and check for cancellations -- if (!running.inProgressRead.addToAsyncWaiters(onComplete)) { -- callbackInfo.data = running.inProgressRead.value; -- callbackInfo.throwable = running.inProgressRead.throwable; -- callbackInfo.completeNow = true; -- } -- return running; -- } -- -- // at this stage we have to use the in progress write's data to avoid an order issue -- callbackInfo.data = pendingWrite; -- callbackInfo.throwable = null; -- callbackInfo.completeNow = true; -- return running; -- }; -- -- final ChunkDataTask ret = taskController.tasks.compute(key, compute); -- -- // needs to be scheduled -- if (callbackInfo.tasksNeedsScheduling) { -- ret.prioritisedTask.queue(); -- } else if (callbackInfo.completeNow) { -- try { -- onComplete.accept(callbackInfo.data == null ? null : callbackInfo.data.copy(), callbackInfo.throwable); -- } catch (final Throwable thr) { -- LOGGER.error("Callback " + ConcurrentUtil.genericToString(onComplete) + " synchronously failed to handle chunk data for task " + ret.toString(), thr); -- } -- } else { -- // we're waiting on a task we didn't schedule, so raise its priority to what we want -- ret.prioritisedTask.raisePriority(priority); -- } -- -- return new CancellableRead(onComplete, ret); -- } -- -- /** -- * Schedules a load task to be executed asynchronously, and blocks on that task. -- * -- * @param world Chunk's world -- * @param chunkX Chunk's x coordinate -- * @param chunkZ Chunk's z coordinate -- * @param type Regionfile type -- * @param priority Minimum priority to load the data at. -- * -- * @return The chunk data for the chunk. Note that a {@code null} result means the chunk or regionfile does not exist on disk. -- * -- * @throws IOException If the load fails for any reason -- */ -- public static CompoundTag loadData(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -- final Priority priority) throws IOException { -- final CompletableFuture ret = new CompletableFuture<>(); -- -- RegionFileIOThread.loadDataAsync(world, chunkX, chunkZ, type, (final CompoundTag compound, final Throwable thr) -> { -- if (thr != null) { -- ret.completeExceptionally(thr); -- } else { -- ret.complete(compound); -- } -- }, true, priority); -- -- try { -- return ret.join(); -- } catch (final CompletionException ex) { -- throw new IOException(ex); -- } -- } -- -- private static final class ImmediateCallbackCompletion { -- -- public CompoundTag data; -- public Throwable throwable; -- public boolean completeNow; -- public boolean tasksNeedsScheduling; -- -- } -- -- private static final class CancellableRead implements Cancellable { -- -- private BiConsumer callback; -- private ChunkDataTask task; -- -- CancellableRead(final BiConsumer callback, final ChunkDataTask task) { -- this.callback = callback; -- this.task = task; -- } -- -- @Override -- public boolean cancel() { -- final BiConsumer callback = this.callback; -- final ChunkDataTask task = this.task; -- -- if (callback == null || task == null) { -- return false; -- } -- -- this.callback = null; -- this.task = null; -- -- final InProgressRead read = task.inProgressRead; -- -- // read can be null if no read was scheduled (i.e no regionfile existed or chunk in regionfile didn't) -- return read != null && read.cancel(callback); -- } -- } -- -- private static final class CancellableReads implements Cancellable { -- -- private Cancellable[] reads; -- -- private static final VarHandle READS_HANDLE = ConcurrentUtil.getVarHandle(CancellableReads.class, "reads", Cancellable[].class); -- -- CancellableReads(final Cancellable[] reads) { -- this.reads = reads; -- } -- -- @Override -- public boolean cancel() { -- final Cancellable[] reads = (Cancellable[])READS_HANDLE.getAndSet((CancellableReads)this, (Cancellable[])null); -- -- if (reads == null) { -- return false; -- } -- -- boolean ret = false; -- -- for (final Cancellable read : reads) { -- ret |= read.cancel(); -- } -- -- return ret; -- } -- } -- -- private static final class InProgressRead { -- -- private static final Logger LOGGER = LoggerFactory.getLogger(InProgressRead.class); -- -- private CompoundTag value; -- private Throwable throwable; -- private final MultiThreadedQueue> callbacks = new MultiThreadedQueue<>(); -- -- public boolean hasNoWaiters() { -- return this.callbacks.isEmpty(); -- } -- -- public boolean addToAsyncWaiters(final BiConsumer callback) { -- return this.callbacks.add(callback); -- } -- -- public boolean cancel(final BiConsumer callback) { -- return this.callbacks.remove(callback); -- } -- -- public void complete(final ChunkDataTask task, final CompoundTag value, final Throwable throwable) { -- this.value = value; -- this.throwable = throwable; -- -- BiConsumer consumer; -- while ((consumer = this.callbacks.pollOrBlockAdds()) != null) { -- try { -- consumer.accept(value == null ? null : value.copy(), throwable); -- } catch (final Throwable thr) { -- LOGGER.error("Callback " + ConcurrentUtil.genericToString(consumer) + " failed to handle chunk data for task " + task.toString(), thr); -- } -- } -- } -- } -- -- public static abstract class ChunkDataController { -- -- // ConcurrentHashMap synchronizes per chain, so reduce the chance of task's hashes colliding. -- private final ConcurrentLong2ReferenceChainedHashTable tasks = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(8192, 0.5f); -- -- public final RegionFileType type; -- -- public ChunkDataController(final RegionFileType type) { -- this.type = type; -- } -- -- public abstract RegionFileStorage getCache(); -- -- public abstract void writeData(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException; -- -- public abstract CompoundTag readData(final int chunkX, final int chunkZ) throws IOException; -- -- public boolean hasTasks() { -- return !this.tasks.isEmpty(); -- } -- -- public boolean doesRegionFileNotExist(final int chunkX, final int chunkZ) { -- return ((ChunkSystemRegionFileStorage)(Object)this.getCache()).moonrise$doesRegionFileNotExistNoIO(chunkX, chunkZ); -- } -- -- public T computeForRegionFile(final int chunkX, final int chunkZ, final boolean existingOnly, final Function function) { -- final RegionFileStorage cache = this.getCache(); -- final RegionFile regionFile; -- synchronized (cache) { -- try { -- if (existingOnly) { -- regionFile = ((ChunkSystemRegionFileStorage)(Object)cache).moonrise$getRegionFileIfExists(chunkX, chunkZ); -- } else { -- regionFile = cache.getRegionFile(new ChunkPos(chunkX, chunkZ), existingOnly); -- } -- } catch (final IOException ex) { -- throw new RuntimeException(ex); -- } -- -- return function.apply(regionFile); -- } -- } -- -- public T computeForRegionFileIfLoaded(final int chunkX, final int chunkZ, final Function function) { -- final RegionFileStorage cache = this.getCache(); -- final RegionFile regionFile; -- -- synchronized (cache) { -- regionFile = ((ChunkSystemRegionFileStorage)(Object)cache).moonrise$getRegionFileIfLoaded(chunkX, chunkZ); -- -- return function.apply(regionFile); -- } -- } -- } -- -- private static final class ChunkDataTask implements Runnable { -- -- private static final CompoundTag NOTHING_TO_WRITE = new CompoundTag(); -- -- private static final Logger LOGGER = LoggerFactory.getLogger(ChunkDataTask.class); -- -- private InProgressRead inProgressRead; -- private volatile CompoundTag inProgressWrite = NOTHING_TO_WRITE; // only needs to be acquire/release -- -- private boolean failedWrite; -- -- private final ServerLevel world; -- private final int chunkX; -- private final int chunkZ; -- private final ChunkDataController taskController; -- -- private final PrioritisedTask prioritisedTask; -- -- /* -- * IO thread will perform reads before writes for a given chunk x and z -- * -- * How reads/writes are scheduled: -- * -- * If read is scheduled while scheduling write, take no special action and just schedule write -- * If read is scheduled while scheduling read and no write is scheduled, chain the read task -- * -- * -- * If write is scheduled while scheduling read, use the pending write data and ret immediately (so no read is scheduled) -- * If write is scheduled while scheduling write (ignore read in progress), overwrite the write in progress data -- * -- * This allows the reads and writes to act as if they occur synchronously to the thread scheduling them, however -- * it fails to properly propagate write failures thanks to writes overwriting each other -- */ -- -- public ChunkDataTask(final ServerLevel world, final int chunkX, final int chunkZ, final ChunkDataController taskController, -- final PrioritisedExecutor executor, final Priority priority) { -- this.world = world; -- this.chunkX = chunkX; -- this.chunkZ = chunkZ; -- this.taskController = taskController; -- this.prioritisedTask = executor.createTask(this, priority); -- } -- -- @Override -- public String toString() { -- return "Task for world: '" + WorldUtil.getWorldName(this.world) + "' at (" + this.chunkX + "," + this.chunkZ + -- ") type: " + this.taskController.type.name() + ", hash: " + this.hashCode(); -- } -- -- @Override -- public void run() { -- final InProgressRead read = this.inProgressRead; -- final long chunkKey = CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ); -- -- if (read != null) { -- final boolean[] canRead = new boolean[] { true }; -- -- if (read.hasNoWaiters()) { -- // cancelled read? go to task controller to confirm -- final ChunkDataTask inMap = this.taskController.tasks.compute(chunkKey, (final long keyInMap, final ChunkDataTask valueInMap) -> { -- if (valueInMap == null) { -- throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkDataTask.this.toString() + ", report this!"); -- } -- if (valueInMap != ChunkDataTask.this) { -- throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkDataTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); -- } -- -- if (!read.hasNoWaiters()) { -- return valueInMap; -- } else { -- canRead[0] = false; -- } -- -- return valueInMap.inProgressWrite == NOTHING_TO_WRITE ? null : valueInMap; -- }); -- -- if (inMap == null) { -- // read is cancelled - and no write pending, so we're done -- return; -- } -- // if there is a write in progress, we don't actually have to worry about waiters gaining new entries - -- // the readers will just use the in progress write, so the value in canRead is good to use without -- // further synchronisation. -- } -- -- if (canRead[0]) { -- CompoundTag compound = null; -- Throwable throwable = null; -- -- try { -- compound = this.taskController.readData(this.chunkX, this.chunkZ); -- } catch (final Throwable thr) { -- throwable = thr; -- LOGGER.error("Failed to read chunk data for task: " + this.toString(), thr); -- } -- read.complete(this, compound, throwable); -- } -- } -- -- CompoundTag write = this.inProgressWrite; -- -- if (write == NOTHING_TO_WRITE) { -- final ChunkDataTask inMap = this.taskController.tasks.compute(chunkKey, (final long keyInMap, final ChunkDataTask valueInMap) -> { -- if (valueInMap == null) { -- throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkDataTask.this.toString() + ", report this!"); -- } -- if (valueInMap != ChunkDataTask.this) { -- throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkDataTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); -- } -- return valueInMap.inProgressWrite == NOTHING_TO_WRITE ? null : valueInMap; -- }); -- -- if (inMap == null) { -- return; // set the task value to null, indicating we're done -- } // else: inProgressWrite changed, so now we have something to write -- } -- -- for (;;) { -- write = this.inProgressWrite; -- final CompoundTag dataWritten = write; -- -- boolean failedWrite = false; -- -- try { -- this.taskController.writeData(this.chunkX, this.chunkZ, write); -- } catch (final Throwable thr) { -- if (thr instanceof RegionFileStorage.RegionFileSizeException) { -- final int maxSize = RegionFile.MAX_CHUNK_SIZE / (1024 * 1024); -- LOGGER.error("Chunk at (" + this.chunkX + "," + this.chunkZ + ") in '" + WorldUtil.getWorldName(this.world) + "' exceeds max size of " + maxSize + "MiB, it has been deleted from disk."); -- } else { -- failedWrite = thr instanceof IOException; -- LOGGER.error("Failed to write chunk data for task: " + this.toString(), thr); -- } -- } -- -- final boolean finalFailWrite = failedWrite; -- final boolean[] done = new boolean[] { false }; -- -- this.taskController.tasks.compute(chunkKey, (final long keyInMap, final ChunkDataTask valueInMap) -> { -- if (valueInMap == null) { -- throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkDataTask.this.toString() + ", report this!"); -- } -- if (valueInMap != ChunkDataTask.this) { -- throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkDataTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); -- } -- if (valueInMap.inProgressWrite == dataWritten) { -- valueInMap.failedWrite = finalFailWrite; -- done[0] = true; -- // keep the data in map if we failed the write so we can try to prevent data loss -- return finalFailWrite ? valueInMap : null; -- } -- // different data than expected, means we need to retry write -- return valueInMap; -- }); -- -- if (done[0]) { -- return; -- } -- -- // fetch & write new data -- continue; -- } -- } -- } --} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/ChunkDataController.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/ChunkDataController.java -index c35e0c29700be48dda3e53e7d2db224766ef17b7..a36ab89f5c37f5f9ab0152f087bb4cf3560f8581 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/ChunkDataController.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/ChunkDataController.java -@@ -1,22 +1,24 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller; - --import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.ChunkSystemRegionFileStorage; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; -+import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemChunkMap; -+import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; - import ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkStorage; - import net.minecraft.nbt.CompoundTag; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.world.level.ChunkPos; - import net.minecraft.world.level.chunk.storage.RegionFileStorage; - import java.io.IOException; --import java.util.Optional; - import java.util.concurrent.CompletableFuture; - import java.util.concurrent.CompletionException; - --public final class ChunkDataController extends RegionFileIOThread.ChunkDataController { -+public final class ChunkDataController extends MoonriseRegionFileIO.RegionDataController { - - private final ServerLevel world; - -- public ChunkDataController(final ServerLevel world) { -- super(RegionFileIOThread.RegionFileType.CHUNK_DATA); -+ public ChunkDataController(final ServerLevel world, final ChunkTaskScheduler taskScheduler) { -+ super(MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, taskScheduler.ioExecutor, taskScheduler.compressionExecutor); - this.world = world; - } - -@@ -26,31 +28,23 @@ public final class ChunkDataController extends RegionFileIOThread.ChunkDataContr - } - - @Override -- public void writeData(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { -- final CompletableFuture future = this.world.getChunkSource().chunkMap.write(new ChunkPos(chunkX, chunkZ), compound); -- -- try { -- if (future != null) { -- // rets non-null when sync writing (i.e. future should be completed here) -- future.join(); -- } -- } catch (final CompletionException ex) { -- if (ex.getCause() instanceof IOException ioException) { -- throw ioException; -- } -- throw ex; -- } -+ public WriteData startWrite(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { -+ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$startWrite(chunkX, chunkZ, compound); - } - - @Override -- public CompoundTag readData(final int chunkX, final int chunkZ) throws IOException { -- try { -- return this.world.getChunkSource().chunkMap.read(new ChunkPos(chunkX, chunkZ)).join().orElse(null); -- } catch (final CompletionException ex) { -- if (ex.getCause() instanceof IOException ioException) { -- throw ioException; -- } -- throw ex; -- } -+ public void finishWrite(final int chunkX, final int chunkZ, final WriteData writeData) throws IOException { -+ ((ChunkSystemChunkMap)this.world.getChunkSource().chunkMap).moonrise$writeFinishCallback(new ChunkPos(chunkX, chunkZ)); -+ ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishWrite(chunkX, chunkZ, writeData); -+ } -+ -+ @Override -+ public ReadData readData(final int chunkX, final int chunkZ) throws IOException { -+ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$readData(chunkX, chunkZ); -+ } -+ -+ @Override -+ public CompoundTag finishRead(final int chunkX, final int chunkZ, final ReadData readData) throws IOException { -+ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishRead(chunkX, chunkZ, readData); - } - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/EntityDataController.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/EntityDataController.java -index fdd189ef056187941d43809c5d61cab717aecf60..828c868f68c2a20bf90d0f7ec253fdeb591f15f6 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/EntityDataController.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/EntityDataController.java -@@ -1,6 +1,8 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller; - --import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.ChunkSystemRegionFileStorage; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; -+import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; - import net.minecraft.nbt.CompoundTag; - import net.minecraft.world.level.ChunkPos; - import net.minecraft.world.level.chunk.storage.EntityStorage; -@@ -9,12 +11,12 @@ import net.minecraft.world.level.chunk.storage.RegionStorageInfo; - import java.io.IOException; - import java.nio.file.Path; - --public final class EntityDataController extends RegionFileIOThread.ChunkDataController { -+public final class EntityDataController extends MoonriseRegionFileIO.RegionDataController { - - private final EntityRegionFileStorage storage; - -- public EntityDataController(final EntityRegionFileStorage storage) { -- super(RegionFileIOThread.RegionFileType.ENTITY_DATA); -+ public EntityDataController(final EntityRegionFileStorage storage, final ChunkTaskScheduler taskScheduler) { -+ super(MoonriseRegionFileIO.RegionFileType.ENTITY_DATA, taskScheduler.ioExecutor, taskScheduler.compressionExecutor); - this.storage = storage; - } - -@@ -24,13 +26,35 @@ public final class EntityDataController extends RegionFileIOThread.ChunkDataCont - } - - @Override -- public void writeData(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { -- this.storage.write(new ChunkPos(chunkX, chunkZ), compound); -+ public WriteData startWrite(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { -+ checkPosition(new ChunkPos(chunkX, chunkZ), compound); -+ -+ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$startWrite(chunkX, chunkZ, compound); -+ } -+ -+ @Override -+ public void finishWrite(final int chunkX, final int chunkZ, final WriteData writeData) throws IOException { -+ ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishWrite(chunkX, chunkZ, writeData); -+ } -+ -+ @Override -+ public ReadData readData(final int chunkX, final int chunkZ) throws IOException { -+ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$readData(chunkX, chunkZ); - } - - @Override -- public CompoundTag readData(final int chunkX, final int chunkZ) throws IOException { -- return this.storage.read(new ChunkPos(chunkX, chunkZ)); -+ public CompoundTag finishRead(final int chunkX, final int chunkZ, final ReadData readData) throws IOException { -+ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishRead(chunkX, chunkZ, readData); -+ } -+ -+ private static void checkPosition(final ChunkPos pos, final CompoundTag nbt) { -+ final ChunkPos nbtPos = nbt == null ? null : EntityStorage.readChunkPos(nbt); -+ if (nbtPos != null && !pos.equals(nbtPos)) { -+ throw new IllegalArgumentException( -+ "Entity chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + pos.toString() -+ + " but compound says coordinate is " + nbtPos -+ ); -+ } - } - - public static final class EntityRegionFileStorage extends RegionFileStorage { -@@ -42,13 +66,7 @@ public final class EntityDataController extends RegionFileIOThread.ChunkDataCont - - @Override - public void write(final ChunkPos pos, final CompoundTag nbt) throws IOException { -- final ChunkPos nbtPos = nbt == null ? null : EntityStorage.readChunkPos(nbt); -- if (nbtPos != null && !pos.equals(nbtPos)) { -- throw new IllegalArgumentException( -- "Entity chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + pos.toString() -- + " but compound says coordinate is " + nbtPos + " for world: " + this -- ); -- } -+ checkPosition(pos, nbt); - super.write(pos, nbt); - } - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/PoiDataController.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/PoiDataController.java -index af867f8fedd0bb8f675e94243aa1a3f17363483b..bd0d782852f9cfe5bc0b5339ecf4d82c10332ec9 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/PoiDataController.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/datacontroller/PoiDataController.java -@@ -1,18 +1,20 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller; - --import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.ChunkSystemRegionFileStorage; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; - import ca.spottedleaf.moonrise.patches.chunk_system.level.storage.ChunkSystemSectionStorage; -+import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; - import net.minecraft.nbt.CompoundTag; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.world.level.chunk.storage.RegionFileStorage; - import java.io.IOException; - --public final class PoiDataController extends RegionFileIOThread.ChunkDataController { -+public final class PoiDataController extends MoonriseRegionFileIO.RegionDataController { - - private final ServerLevel world; - -- public PoiDataController(final ServerLevel world) { -- super(RegionFileIOThread.RegionFileType.POI_DATA); -+ public PoiDataController(final ServerLevel world, final ChunkTaskScheduler taskScheduler) { -+ super(MoonriseRegionFileIO.RegionFileType.POI_DATA, taskScheduler.ioExecutor, taskScheduler.compressionExecutor); - this.world = world; - } - -@@ -22,12 +24,22 @@ public final class PoiDataController extends RegionFileIOThread.ChunkDataControl - } - - @Override -- public void writeData(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { -- ((ChunkSystemSectionStorage)this.world.getPoiManager()).moonrise$write(chunkX, chunkZ, compound); -+ public WriteData startWrite(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException { -+ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$startWrite(chunkX, chunkZ, compound); - } - - @Override -- public CompoundTag readData(final int chunkX, final int chunkZ) throws IOException { -- return ((ChunkSystemSectionStorage)this.world.getPoiManager()).moonrise$read(chunkX, chunkZ); -+ public void finishWrite(final int chunkX, final int chunkZ, final WriteData writeData) throws IOException { -+ ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishWrite(chunkX, chunkZ, writeData); -+ } -+ -+ @Override -+ public ReadData readData(final int chunkX, final int chunkZ) throws IOException { -+ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$readData(chunkX, chunkZ); -+ } -+ -+ @Override -+ public CompoundTag finishRead(final int chunkX, final int chunkZ, final ReadData readData) throws IOException { -+ return ((ChunkSystemRegionFileStorage)this.getCache()).moonrise$finishRead(chunkX, chunkZ, readData); - } - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemChunkMap.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemChunkMap.java -new file mode 100644 -index 0000000000000000000000000000000000000000..47a4d3376d08dde94a39254bec21473ff27f53e6 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemChunkMap.java -@@ -0,0 +1,10 @@ -+package ca.spottedleaf.moonrise.patches.chunk_system.level; -+ -+import net.minecraft.world.level.ChunkPos; -+import java.io.IOException; -+ -+public interface ChunkSystemChunkMap { -+ -+ public void moonrise$writeFinishCallback(final ChunkPos pos) throws IOException; -+ -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemLevel.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemLevel.java -index efcd9057f008f0b9cf0d22b2b21d1851205841e5..5d4d650186b18eb00782429d53d861564d8e4ba9 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemLevel.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemLevel.java -@@ -1,5 +1,6 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.level; - -+import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; - import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup; - import net.minecraft.world.level.chunk.ChunkAccess; - import net.minecraft.world.level.chunk.LevelChunk; -@@ -19,4 +20,14 @@ public interface ChunkSystemLevel { - - public void moonrise$midTickTasks(); - -+ public ChunkData moonrise$getChunkData(final long chunkKey); -+ -+ public ChunkData moonrise$getChunkData(final int chunkX, final int chunkZ); -+ -+ public ChunkData moonrise$requestChunkData(final long chunkKey); -+ -+ public ChunkData moonrise$releaseChunkData(final long chunkKey); -+ -+ public boolean moonrise$areChunksLoaded(final int fromX, final int fromZ, final int toX, final int toZ); -+ - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java -index b8a87b7e6505feb76ce1bd58c84615256cf6faa6..9d46482476f9ed9032a2b0f89afc20e03ed42dbb 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java -@@ -1,12 +1,13 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.level; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.util.Priority; - import ca.spottedleaf.moonrise.common.list.ReferenceList; - import ca.spottedleaf.moonrise.common.misc.NearbyPlayers; --import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; - import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader; - import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; - import net.minecraft.core.BlockPos; -+import net.minecraft.server.level.ChunkHolder; - import net.minecraft.server.level.ServerChunkCache; - import net.minecraft.world.level.chunk.ChunkAccess; - import net.minecraft.world.level.chunk.status.ChunkStatus; -@@ -17,32 +18,34 @@ public interface ChunkSystemServerLevel extends ChunkSystemLevel { - - public ChunkTaskScheduler moonrise$getChunkTaskScheduler(); - -- public RegionFileIOThread.ChunkDataController moonrise$getChunkDataController(); -+ public MoonriseRegionFileIO.RegionDataController moonrise$getChunkDataController(); - -- public RegionFileIOThread.ChunkDataController moonrise$getPoiChunkDataController(); -+ public MoonriseRegionFileIO.RegionDataController moonrise$getPoiChunkDataController(); - -- public RegionFileIOThread.ChunkDataController moonrise$getEntityChunkDataController(); -+ public MoonriseRegionFileIO.RegionDataController moonrise$getEntityChunkDataController(); - - public int moonrise$getRegionChunkShift(); - -- // Paper - marked closing not needed on CB -+ public boolean moonrise$isMarkedClosing(); -+ -+ public void moonrise$setMarkedClosing(final boolean value); - - public RegionizedPlayerChunkLoader moonrise$getPlayerChunkLoader(); - - public void moonrise$loadChunksAsync(final BlockPos pos, final int radiusBlocks, -- final PrioritisedExecutor.Priority priority, -+ final Priority priority, - final Consumer> onLoad); - - public void moonrise$loadChunksAsync(final BlockPos pos, final int radiusBlocks, -- final ChunkStatus chunkStatus, final PrioritisedExecutor.Priority priority, -+ final ChunkStatus chunkStatus, final Priority priority, - final Consumer> onLoad); - - public void moonrise$loadChunksAsync(final int minChunkX, final int maxChunkX, final int minChunkZ, final int maxChunkZ, -- final PrioritisedExecutor.Priority priority, -+ final Priority priority, - final Consumer> onLoad); - - public void moonrise$loadChunksAsync(final int minChunkX, final int maxChunkX, final int minChunkZ, final int maxChunkZ, -- final ChunkStatus chunkStatus, final PrioritisedExecutor.Priority priority, -+ final ChunkStatus chunkStatus, final Priority priority, - final Consumer> onLoad); - - public RegionizedPlayerChunkLoader.ViewDistanceHolder moonrise$getViewDistanceHolder(); -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkData.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkData.java -new file mode 100644 -index 0000000000000000000000000000000000000000..8b9dc582627b46843f4b5ea6f8c3df2d8cac46fa ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkData.java -@@ -0,0 +1,21 @@ -+package ca.spottedleaf.moonrise.patches.chunk_system.level.chunk; -+ -+import ca.spottedleaf.moonrise.common.misc.NearbyPlayers; -+ -+public final class ChunkData { -+ -+ private int referenceCount = 0; -+ public NearbyPlayers.TrackedChunk nearbyPlayers; // Moonrise - nearby players -+ -+ public ChunkData() { -+ -+ } -+ -+ public int increaseRef() { -+ return ++this.referenceCount; -+ } -+ -+ public int decreaseRef() { -+ return --this.referenceCount; -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemDistanceManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemDistanceManager.java -index 883fe6401f1b9711fa544d18a815b4d638f580df..aacd543f03b35908011d0c2891e978cc093ebcf5 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemDistanceManager.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemDistanceManager.java -@@ -1,9 +1,12 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.level.chunk; - -+import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager; - import net.minecraft.server.level.ChunkMap; - - public interface ChunkSystemDistanceManager { - - public ChunkMap moonrise$getChunkMap(); - -+ public ChunkHolderManager moonrise$getChunkHolderManager(); -+ - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -index 997b05167c19472acb98edac32d4548cc65efa8e..5ed6599d1f9a2edf8c904f3602b06d26d857600c 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -@@ -1,6 +1,8 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.level.entity; - -+import ca.spottedleaf.moonrise.common.PlatformHooks; - import ca.spottedleaf.moonrise.common.list.EntityList; -+import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; - import ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity; - import com.google.common.collect.ImmutableList; - import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; -@@ -13,6 +15,7 @@ import net.minecraft.server.level.FullChunkStatus; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.util.Mth; - import net.minecraft.world.entity.Entity; -+import net.minecraft.world.entity.EntitySpawnReason; - import net.minecraft.world.entity.EntityType; - import net.minecraft.world.entity.boss.EnderDragonPart; - import net.minecraft.world.entity.boss.enderdragon.EnderDragon; -@@ -26,7 +29,6 @@ import java.util.Arrays; - import java.util.Iterator; - import java.util.List; - import java.util.function.Predicate; --import org.bukkit.event.entity.EntityRemoveEvent; - - public final class ChunkEntitySlices { - -@@ -43,6 +45,7 @@ public final class ChunkEntitySlices { - private final EntityList entities = new EntityList(); - - public FullChunkStatus status; -+ public final ChunkData chunkData; - - private boolean isTransient; - -@@ -55,7 +58,7 @@ public final class ChunkEntitySlices { - } - - public ChunkEntitySlices(final Level world, final int chunkX, final int chunkZ, final FullChunkStatus status, -- final int minSection, final int maxSection) { // inclusive, inclusive -+ final ChunkData chunkData, final int minSection, final int maxSection) { // inclusive, inclusive - this.minSection = minSection; - this.maxSection = maxSection; - this.chunkX = chunkX; -@@ -68,11 +71,12 @@ public final class ChunkEntitySlices { - this.entitiesByType = new Reference2ObjectOpenHashMap<>(); - - this.status = status; -+ this.chunkData = chunkData; - } - - public static List readEntities(final ServerLevel world, final CompoundTag compoundTag) { - // TODO check this and below on update for format changes -- return EntityType.loadEntitiesRecursive(compoundTag.getList("Entities", 10), world).collect(ImmutableList.toImmutableList()); -+ return EntityType.loadEntitiesRecursive(compoundTag.getList("Entities", 10), world, EntitySpawnReason.LOAD).collect(ImmutableList.toImmutableList()); - } - - // Paper start - rewrite chunk system -@@ -100,7 +104,7 @@ public final class ChunkEntitySlices { - } - - final ListTag entitiesTag = new ListTag(); -- for (final Entity entity : entities) { -+ for (final Entity entity : PlatformHooks.get().modifySavedEntities(world, chunkPos.x, chunkPos.z, entities)) { - CompoundTag compoundTag = new CompoundTag(); - if (entity.save(compoundTag)) { - entitiesTag.add(compoundTag); -@@ -147,12 +151,12 @@ public final class ChunkEntitySlices { - continue; - } - if (entity.shouldBeSaved()) { -- entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, EntityRemoveEvent.Cause.UNLOAD); -+ PlatformHooks.get().unloadEntity(entity); - if (entity.isVehicle()) { - // we cannot assume that these entities are contained within this chunk, because entities can - // desync - so we need to remove them all - for (final Entity passenger : entity.getIndirectPassengers()) { -- passenger.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, EntityRemoveEvent.Cause.UNLOAD); -+ PlatformHooks.get().unloadEntity(passenger); - } - } - } -@@ -161,34 +165,7 @@ public final class ChunkEntitySlices { - return this.entities.size() != 0; - } - -- // Paper start -- public org.bukkit.entity.Entity[] getChunkEntities() { -- List ret = new java.util.ArrayList<>(); -- final Entity[] entities = this.entities.getRawData(); -- for (int i = 0, size = Math.min(entities.length, this.entities.size()); i < size; ++i) { -- final Entity entity = entities[i]; -- if (entity == null) { -- continue; -- } -- final org.bukkit.entity.Entity bukkit = entity.getBukkitEntity(); -- if (bukkit != null && bukkit.isValid()) { -- ret.add(bukkit); -- } -- } -- -- return ret.toArray(new org.bukkit.entity.Entity[0]); -- } -- -- public void callEntitiesLoadEvent() { -- org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesLoadEvent(this.world, new ChunkPos(this.chunkX, this.chunkZ), this.getAllEntities()); -- } -- -- public void callEntitiesUnloadEvent() { -- org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesUnloadEvent(this.world, new ChunkPos(this.chunkX, this.chunkZ), this.getAllEntities()); -- } -- // Paper end -- -- private List getAllEntities() { -+ public List getAllEntities() { - final int len = this.entities.size(); - if (len == 0) { - return new ArrayList<>(); -@@ -251,6 +228,7 @@ public final class ChunkEntitySlices { - return false; - } - ((ChunkSystemEntity)entity).moonrise$setChunkStatus(this.status); -+ ((ChunkSystemEntity)entity).moonrise$setChunkData(this.chunkData); - final int sectionIndex = chunkSection - this.minSection; - - this.allEntities.addEntity(entity, sectionIndex); -@@ -284,6 +262,7 @@ public final class ChunkEntitySlices { - return false; - } - ((ChunkSystemEntity)entity).moonrise$setChunkStatus(null); -+ ((ChunkSystemEntity)entity).moonrise$setChunkData(null); - final int sectionIndex = chunkSection - this.minSection; - - this.allEntities.removeEntity(entity, sectionIndex); -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java -index efc0c1acc8239dd7b00211a1d3bfd3fc3b2c810c..93335de8cf514dc8417e4b9b2d495663deda2904 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java -@@ -46,8 +46,6 @@ public abstract class EntityLookup implements LevelEntityGetter { - - protected final SWMRLong2ObjectHashTable regions = new SWMRLong2ObjectHashTable<>(128, 0.5f); - -- protected final int minSection; // inclusive -- protected final int maxSection; // inclusive - protected final LevelCallback worldCallback; - - protected final ConcurrentLong2ReferenceChainedHashTable entityById = new ConcurrentLong2ReferenceChainedHashTable<>(); -@@ -56,8 +54,6 @@ public abstract class EntityLookup implements LevelEntityGetter { - - public EntityLookup(final Level world, final LevelCallback worldCallback) { - this.world = world; -- this.minSection = WorldUtil.getMinSection(world); -- this.maxSection = WorldUtil.getMaxSection(world); - this.worldCallback = worldCallback; - } - -@@ -91,7 +87,7 @@ public abstract class EntityLookup implements LevelEntityGetter { - - protected abstract void entityEndTicking(final Entity entity); - -- protected abstract boolean screenEntity(final Entity entity); -+ protected abstract boolean screenEntity(final Entity entity, final boolean fromDisk, final boolean event); - - private static Entity maskNonAccessible(final Entity entity) { - if (entity == null) { -@@ -347,7 +343,7 @@ public abstract class EntityLookup implements LevelEntityGetter { - } - - protected void addRecursivelySafe(final Entity root, final boolean fromDisk) { -- if (!this.addEntity(root, fromDisk)) { -+ if (!this.addEntity(root, fromDisk, true)) { - // possible we are a passenger, and so should dismount from any valid entity in the world - root.stopRiding(); - return; -@@ -386,7 +382,11 @@ public abstract class EntityLookup implements LevelEntityGetter { - } - - public boolean addNewEntity(final Entity entity) { -- return this.addEntity(entity, false); -+ return this.addNewEntity(entity, true); -+ } -+ -+ public boolean addNewEntity(final Entity entity, final boolean event) { -+ return this.addEntity(entity, false, event); - } - - public static Visibility getEntityStatus(final Entity entity) { -@@ -397,10 +397,10 @@ public abstract class EntityLookup implements LevelEntityGetter { - return Visibility.fromFullChunkStatus(entityStatus == null ? FullChunkStatus.INACCESSIBLE : entityStatus); - } - -- protected boolean addEntity(final Entity entity, final boolean fromDisk) { -+ protected boolean addEntity(final Entity entity, final boolean fromDisk, final boolean event) { - final BlockPos pos = entity.blockPosition(); - final int sectionX = pos.getX() >> 4; -- final int sectionY = Mth.clamp(pos.getY() >> 4, this.minSection, this.maxSection); -+ final int sectionY = Mth.clamp(pos.getY() >> 4, WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world)); - final int sectionZ = pos.getZ() >> 4; - this.checkThread(sectionX, sectionZ, "Cannot add entity off-main thread"); - -@@ -414,7 +414,7 @@ public abstract class EntityLookup implements LevelEntityGetter { - return false; - } - -- if (!this.screenEntity(entity)) { -+ if (!this.screenEntity(entity, fromDisk, event)) { - return false; - } - -@@ -519,7 +519,7 @@ public abstract class EntityLookup implements LevelEntityGetter { - final int sectionZ = ((ChunkSystemEntity)entity).moonrise$getSectionZ(); - final BlockPos newPos = entity.blockPosition(); - final int newSectionX = newPos.getX() >> 4; -- final int newSectionY = Mth.clamp(newPos.getY() >> 4, this.minSection, this.maxSection); -+ final int newSectionY = Mth.clamp(newPos.getY() >> 4, WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world)); - final int newSectionZ = newPos.getZ() >> 4; - - if (newSectionX == sectionX && newSectionY == sectionY && newSectionZ == sectionZ) { -@@ -959,7 +959,7 @@ public abstract class EntityLookup implements LevelEntityGetter { - - public ChunkEntitySlices getOrCreateChunk(final int chunkX, final int chunkZ) { - final ChunkSlicesRegion region = this.getRegion(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT); -- ChunkEntitySlices ret; -+ final ChunkEntitySlices ret; - if (region == null || (ret = region.get((chunkX & REGION_MASK) | ((chunkZ & REGION_MASK) << REGION_SHIFT))) == null) { - return this.createEntityChunk(chunkX, chunkZ, true); - } -@@ -1057,7 +1057,7 @@ public abstract class EntityLookup implements LevelEntityGetter { - @Override - public void onRemove(final Entity.RemovalReason reason) { - final Entity entity = this.entity; -- EntityLookup.this.checkThread(entity, "Cannot remove entity off-main"); // Paper - rewrite chunk system -+ EntityLookup.this.checkThread(entity, "Cannot remove entity off-main"); - final Visibility tickingState = EntityLookup.getEntityStatus(entity); - - EntityLookup.this.removeEntity(entity); -@@ -1080,4 +1080,4 @@ public abstract class EntityLookup implements LevelEntityGetter { - @Override - public void onRemove(final Entity.RemovalReason reason) {} - } --} -\ No newline at end of file -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java -index edcde00206d068bd79175fea33efa05b0e8c1562..a038215156a163b0b1cbc870ada5b4ac85ed1335 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java -@@ -1,5 +1,6 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.level.entity.client; - -+import ca.spottedleaf.moonrise.common.PlatformHooks; - import ca.spottedleaf.moonrise.common.util.CoordinateUtils; - import ca.spottedleaf.moonrise.common.util.WorldUtil; - import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; -@@ -45,7 +46,8 @@ public final class ClientEntityLookup extends EntityLookup { - - final ChunkEntitySlices ret = new ChunkEntitySlices( - this.world, chunkX, chunkZ, -- ticking ? FullChunkStatus.ENTITY_TICKING : FullChunkStatus.FULL, WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) -+ ticking ? FullChunkStatus.ENTITY_TICKING : FullChunkStatus.FULL, null, -+ WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) - ); - - // note: not handled by superclass -@@ -63,7 +65,11 @@ public final class ClientEntityLookup extends EntityLookup { - protected void entitySectionChangeCallback(final Entity entity, - final int oldSectionX, final int oldSectionY, final int oldSectionZ, - final int newSectionX, final int newSectionY, final int newSectionZ) { -- -+ PlatformHooks.get().entityMove( -+ entity, -+ CoordinateUtils.getChunkSectionKey(oldSectionX, oldSectionY, oldSectionZ), -+ CoordinateUtils.getChunkSectionKey(newSectionX, newSectionY, newSectionZ) -+ ); - } - - @Override -@@ -97,7 +103,7 @@ public final class ClientEntityLookup extends EntityLookup { - } - - @Override -- protected boolean screenEntity(final Entity entity) { -+ protected boolean screenEntity(final Entity entity, final boolean fromDisk, final boolean event) { - return true; - } - -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java -index 465469e44346c50f30f3abd6b44f4173ccfcf248..2ff58cf753c60913ee73aae015182e9c5560d529 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java -@@ -32,7 +32,7 @@ public final class DefaultEntityLookup extends EntityLookup { - protected ChunkEntitySlices createEntityChunk(final int chunkX, final int chunkZ, final boolean transientChunk) { - final ChunkEntitySlices ret = new ChunkEntitySlices( - this.world, chunkX, chunkZ, FullChunkStatus.FULL, -- WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) -+ null, WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) - ); - - // note: not handled by superclass -@@ -84,7 +84,7 @@ public final class DefaultEntityLookup extends EntityLookup { - } - - @Override -- protected boolean screenEntity(final Entity entity) { -+ protected boolean screenEntity(final Entity entity, final boolean fromDisk, final boolean event) { - return true; - } - -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java -index dacf2b2988ce603879fe525a3418ac77f8a663f7..58d9187adc188b693b6becc400f766e069bf1bf5 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java -@@ -1,6 +1,8 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server; - -+import ca.spottedleaf.moonrise.common.PlatformHooks; - import ca.spottedleaf.moonrise.common.list.ReferenceList; -+import ca.spottedleaf.moonrise.common.util.CoordinateUtils; - import ca.spottedleaf.moonrise.common.util.TickThread; - import ca.spottedleaf.moonrise.common.util.ChunkSystem; - import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; -@@ -17,7 +19,6 @@ public final class ServerEntityLookup extends EntityLookup { - - private final ServerLevel serverWorld; - public final ReferenceList trackerEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY); // Moonrise - entity tracker -- public final ReferenceList trackerUnloadedEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY); // Moonrise - entity tracker - - public ServerEntityLookup(final ServerLevel world, final LevelCallback worldCallback) { - super(world, worldCallback); -@@ -63,6 +64,11 @@ public final class ServerEntityLookup extends EntityLookup { - if (entity instanceof ServerPlayer player) { - ((ChunkSystemServerLevel)this.serverWorld).moonrise$getNearbyPlayers().tickPlayer(player); - } -+ PlatformHooks.get().entityMove( -+ entity, -+ CoordinateUtils.getChunkSectionKey(oldSectionX, oldSectionY, oldSectionZ), -+ CoordinateUtils.getChunkSectionKey(newSectionX, newSectionY, newSectionZ) -+ ); - } - - @Override -@@ -77,14 +83,12 @@ public final class ServerEntityLookup extends EntityLookup { - if (entity instanceof ServerPlayer player) { - ((ChunkSystemServerLevel)this.serverWorld).moonrise$getNearbyPlayers().removePlayer(player); - } -- this.trackerUnloadedEntities.remove(entity); // Moonrise - entity tracker - } - - @Override - protected void entityStartLoaded(final Entity entity) { - // Moonrise start - entity tracker - this.trackerEntities.add(entity); -- this.trackerUnloadedEntities.remove(entity); - // Moonrise end - entity tracker - } - -@@ -92,7 +96,6 @@ public final class ServerEntityLookup extends EntityLookup { - protected void entityEndLoaded(final Entity entity) { - // Moonrise start - entity tracker - this.trackerEntities.remove(entity); -- this.trackerUnloadedEntities.add(entity); - // Moonrise end - entity tracker - } - -@@ -107,7 +110,7 @@ public final class ServerEntityLookup extends EntityLookup { - } - - @Override -- protected boolean screenEntity(final Entity entity) { -- return ChunkSystem.screenEntity(this.serverWorld, entity); -+ protected boolean screenEntity(final Entity entity, final boolean fromDisk, final boolean event) { -+ return ChunkSystem.screenEntity(this.serverWorld, entity, fromDisk, event); - } - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java -index fd35e4db0c8fec8f86b8743bcc2b15ed2e7433f1..bbf9d6c1c9525d97160806819a57be03eca290f1 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java -@@ -3,7 +3,6 @@ package ca.spottedleaf.moonrise.patches.chunk_system.level.poi; - import ca.spottedleaf.moonrise.common.util.CoordinateUtils; - import ca.spottedleaf.moonrise.common.util.TickThread; - import ca.spottedleaf.moonrise.common.util.WorldUtil; --import com.mojang.serialization.Codec; - import com.mojang.serialization.DataResult; - import net.minecraft.SharedConstants; - import net.minecraft.nbt.CompoundTag; -@@ -123,7 +122,6 @@ public final class PoiChunk { - ret.putInt("DataVersion", SharedConstants.getCurrentVersion().getDataVersion().getVersion()); - - final ServerLevel world = this.world; -- final PoiManager poiManager = world.getPoiManager(); - final int chunkX = this.chunkX; - final int chunkZ = this.chunkZ; - -@@ -133,13 +131,8 @@ public final class PoiChunk { - continue; - } - -- final long key = CoordinateUtils.getChunkSectionKey(chunkX, sectionY, chunkZ); -- // codecs are honestly such a fucking disaster. What the fuck is this trash? -- final Codec codec = PoiSection.codec(() -> { -- poiManager.setDirty(key); -- }); -- -- final DataResult serializedResult = codec.encodeStart(registryOps, section); -+ // I do not believe asynchronously converting to CompoundTag is worth the scheduling. -+ final DataResult serializedResult = PoiSection.Packed.CODEC.encodeStart(registryOps, section.pack()); - final int finalSectionY = sectionY; - final Tag serialized = serializedResult.resultOrPartial((final String description) -> { - LOGGER.error("Failed to serialize poi chunk for world: " + WorldUtil.getWorldName(world) + ", chunk: (" + chunkX + "," + finalSectionY + "," + chunkZ + "); description: " + description); -@@ -183,19 +176,18 @@ public final class PoiChunk { - continue; - } - -- final long coordinateKey = CoordinateUtils.getChunkSectionKey(chunkX, sectionY, chunkZ); -- // codecs are honestly such a fucking disaster. What the fuck is this trash? -- final Codec codec = PoiSection.codec(() -> { -- poiManager.setDirty(coordinateKey); -- }); -- - final CompoundTag section = sections.getCompound(key); -- final DataResult deserializeResult = codec.parse(registryOps, section); -+ final DataResult deserializeResult = PoiSection.Packed.CODEC.parse(registryOps, section); - final int finalSectionY = sectionY; -- final PoiSection deserialized = deserializeResult.resultOrPartial((final String description) -> { -+ final PoiSection.Packed packed = deserializeResult.resultOrPartial((final String description) -> { - LOGGER.error("Failed to deserialize poi chunk for world: " + WorldUtil.getWorldName(world) + ", chunk: (" + chunkX + "," + finalSectionY + "," + chunkZ + "); description: " + description); - }).orElse(null); - -+ final long coordinateKey = CoordinateUtils.getChunkSectionKey(chunkX, sectionY, chunkZ); -+ final PoiSection deserialized = packed == null ? null : packed.unpack(() -> { -+ poiManager.setDirty(coordinateKey); -+ }); -+ - if (deserialized == null || ((ChunkSystemPoiSection)deserialized).moonrise$isEmpty()) { - // completely empty, no point in storing this - continue; -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java -index fb87d7ece6ebccfd0ffd2f1a609b45a0d2461d9e..524752744e37a2db0e3ea089468bdf497129bfef 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/storage/ChunkSystemSectionStorage.java -@@ -1,12 +1,8 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.level.storage; - --import com.mojang.serialization.Dynamic; - import net.minecraft.nbt.CompoundTag; --import net.minecraft.nbt.Tag; - import net.minecraft.world.level.chunk.storage.RegionFileStorage; - import java.io.IOException; --import java.util.Optional; --import java.util.concurrent.CompletableFuture; - - public interface ChunkSystemSectionStorage { - -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -index 852d75a73dae7448cbe1e2f5e164b235efa8a969..b2fa9883aefb07f64bb5db7e0052218d2ad09aba 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -@@ -1,7 +1,8 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.player; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; - import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.Priority; -+import ca.spottedleaf.moonrise.common.PlatformHooks; - import ca.spottedleaf.moonrise.common.misc.AllocatingRateLimiter; - import ca.spottedleaf.moonrise.common.misc.SingleUserAreaMap; - import ca.spottedleaf.moonrise.common.util.CoordinateUtils; -@@ -412,7 +413,11 @@ public final class RegionizedPlayerChunkLoader { - if (this.sentChunks.add(CoordinateUtils.getChunkKey(chunkX, chunkZ))) { - ((ChunkSystemChunkHolder)((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager - .getChunkHolder(chunkX, chunkZ).vanillaChunkHolder).moonrise$addReceivedChunk(this.player); -- PlayerChunkSender.sendChunk(this.player.connection, this.world, ((ChunkSystemLevel)this.world).moonrise$getFullChunkIfLoaded(chunkX, chunkZ)); -+ -+ final LevelChunk chunk = ((ChunkSystemLevel)this.world).moonrise$getFullChunkIfLoaded(chunkX, chunkZ); -+ -+ PlatformHooks.get().onChunkWatch(this.world, chunk, this.player); -+ PlayerChunkSender.sendChunk(this.player.connection, this.world, chunk); - return; - } - throw new IllegalStateException(); -@@ -426,17 +431,12 @@ public final class RegionizedPlayerChunkLoader { - } - - private void sendUnloadChunkRaw(final int chunkX, final int chunkZ) { -+ PlatformHooks.get().onChunkUnWatch(this.world, new ChunkPos(chunkX, chunkZ), this.player); - // Note: Check PlayerChunkSender#dropChunk for other logic - // Note: drop isAlive() check so that chunks properly unload client-side when the player dies - ((ChunkSystemChunkHolder)((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager - .getChunkHolder(chunkX, chunkZ).vanillaChunkHolder).moonrise$removeReceivedChunk(this.player); -- final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); -- this.player.connection.send(new ClientboundForgetLevelChunkPacket(chunkPos)); -- // Paper start - PlayerChunkUnloadEvent -- if (io.papermc.paper.event.packet.PlayerChunkUnloadEvent.getHandlerList().getRegisteredListeners().length > 0) { -- new io.papermc.paper.event.packet.PlayerChunkUnloadEvent(this.world.getWorld().getChunkAt(chunkPos.longKey), this.player.getBukkitEntity()).callEvent(); -- } -- // Paper end - PlayerChunkUnloadEvent -+ this.player.connection.send(new ClientboundForgetLevelChunkPacket(new ChunkPos(chunkX, chunkZ))); - } - - private final SingleUserAreaMap broadcastMap = new SingleUserAreaMap<>(this) { -@@ -529,7 +529,7 @@ public final class RegionizedPlayerChunkLoader { - final int playerSendViewDistance, final int worldSendViewDistance) { - return Math.min( - loadViewDistance - 1, -- playerSendViewDistance < 0 ? (!io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.autoConfigSendDistance || clientViewDistance < 0 ? (worldSendViewDistance < 0 ? (loadViewDistance - 1) : worldSendViewDistance) : clientViewDistance + 1) : playerSendViewDistance -+ playerSendViewDistance < 0 ? (!PlatformHooks.get().configAutoConfigSendDistance() || clientViewDistance < 0 ? (worldSendViewDistance < 0 ? (loadViewDistance - 1) : worldSendViewDistance) : clientViewDistance + 1) : playerSendViewDistance - ); - } - -@@ -554,26 +554,26 @@ public final class RegionizedPlayerChunkLoader { - } - - private double getMaxChunkLoadRate() { -- final double configRate = io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkLoadRate; -+ final double configRate = PlatformHooks.get().configPlayerMaxLoadRate(); - - return configRate <= 0.0 || configRate > (double)MAX_RATE ? (double)MAX_RATE : Math.max(1.0, configRate); - } - - private double getMaxChunkGenRate() { -- final double configRate = io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkGenerateRate; -+ final double configRate = PlatformHooks.get().configPlayerMaxGenRate(); - - return configRate <= 0.0 || configRate > (double)MAX_RATE ? (double)MAX_RATE : Math.max(1.0, configRate); - } - - private double getMaxChunkSendRate() { -- final double configRate = io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkSendRate; -+ final double configRate = PlatformHooks.get().configPlayerMaxSendRate(); - - return configRate <= 0.0 || configRate > (double)MAX_RATE ? (double)MAX_RATE : Math.max(1.0, configRate); - } - - private long getMaxChunkLoads() { - final long radiusChunks = (2L * this.lastLoadDistance + 1L) * (2L * this.lastLoadDistance + 1L); -- long configLimit = io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkLoads; -+ long configLimit = (long)PlatformHooks.get().configPlayerMaxConcurrentLoads(); - if (configLimit == 0L) { - // by default, only allow 1/5th of the chunks in the view distance to be concurrently active - configLimit = Math.max(5L, radiusChunks / 5L); -@@ -587,7 +587,7 @@ public final class RegionizedPlayerChunkLoader { - - private long getMaxChunkGenerates() { - final long radiusChunks = (2L * this.lastLoadDistance + 1L) * (2L * this.lastLoadDistance + 1L); -- long configLimit = io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkGenerates; -+ long configLimit = (long)PlatformHooks.get().configPlayerMaxConcurrentGens(); - if (configLimit == 0L) { - // by default, only allow 1/5th of the chunks in the view distance to be concurrently active - configLimit = Math.max(5L, radiusChunks / 5L); -@@ -709,7 +709,7 @@ public final class RegionizedPlayerChunkLoader { - final int queuedChunkX = CoordinateUtils.getChunkX(queuedLoadChunk); - final int queuedChunkZ = CoordinateUtils.getChunkZ(queuedLoadChunk); - ((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().scheduleChunkLoad( -- queuedChunkX, queuedChunkZ, ChunkStatus.EMPTY, false, PrioritisedExecutor.Priority.NORMAL, null -+ queuedChunkX, queuedChunkZ, ChunkStatus.EMPTY, false, Priority.NORMAL, null - ); - if (this.removed) { - return; -@@ -825,7 +825,7 @@ public final class RegionizedPlayerChunkLoader { - } - if (!((ChunkSystemLevelChunk)chunk).moonrise$isPostProcessingDone()) { - // not yet post-processed, need to do this so that tile entities can properly be sent to clients -- chunk.postProcessGeneration(); -+ chunk.postProcessGeneration(this.world); - // check if there was any recursive action - if (this.removed || this.sendQueue.isEmpty() || this.sendQueue.firstLong() != pendingSend) { - return; -@@ -864,7 +864,6 @@ public final class RegionizedPlayerChunkLoader { - final int clientViewDistance = getClientViewDistance(this.player); - final int sendViewDistance = getSendViewDistance(loadViewDistance, clientViewDistance, playerDistances.sendViewDistance, worldDistances.sendViewDistance); - -- // TODO check PlayerList diff in paper chunk system patch - // send view distances - this.player.connection.send(this.updateClientChunkRadius(sendViewDistance)); - this.player.connection.send(this.updateClientSimulationDistance(tickViewDistance)); -@@ -1078,5 +1077,9 @@ public final class RegionizedPlayerChunkLoader { - - // now all tickets should be removed, which is all of our external state - } -+ -+ public LongOpenHashSet getSentChunksRaw() { -+ return this.sentChunks; -+ } - } - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -index 58d3d1a47e9f2423c467bb329c2d5f4b58a8b5ef..f98df65eaed2abedc66f3a49790e0cfb65354ed9 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -@@ -1,14 +1,14 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; - import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; - import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; -+import ca.spottedleaf.concurrentutil.util.Priority; -+import ca.spottedleaf.moonrise.common.PlatformHooks; - import ca.spottedleaf.moonrise.common.util.CoordinateUtils; --import ca.spottedleaf.moonrise.common.util.MoonriseCommon; - import ca.spottedleaf.moonrise.common.util.TickThread; - import ca.spottedleaf.moonrise.common.util.WorldUtil; - import ca.spottedleaf.moonrise.common.util.ChunkSystem; --import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; - import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; - import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; - import ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk; -@@ -20,7 +20,6 @@ import ca.spottedleaf.moonrise.patches.chunk_system.ticket.ChunkSystemTicket; - import ca.spottedleaf.moonrise.patches.chunk_system.util.ChunkSystemSortedArraySet; - import com.google.gson.JsonArray; - import com.google.gson.JsonObject; --import com.mojang.logging.LogUtils; - import it.unimi.dsi.fastutil.longs.Long2ByteLinkedOpenHashMap; - import it.unimi.dsi.fastutil.longs.Long2ByteMap; - import it.unimi.dsi.fastutil.longs.Long2IntMap; -@@ -40,7 +39,9 @@ import net.minecraft.server.level.TicketType; - import net.minecraft.util.SortedArraySet; - import net.minecraft.util.Unit; - import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.chunk.LevelChunk; - import org.slf4j.Logger; -+import org.slf4j.LoggerFactory; - import java.io.IOException; - import java.text.DecimalFormat; - import java.util.ArrayDeque; -@@ -58,7 +59,7 @@ import java.util.function.Predicate; - - public final class ChunkHolderManager { - -- private static final Logger LOGGER = LogUtils.getClassLogger(); -+ private static final Logger LOGGER = LoggerFactory.getLogger(ChunkHolderManager.class); - - public static final int FULL_LOADED_TICKET_LEVEL = ChunkLevel.FULL_CHUNK_LEVEL; - public static final int BLOCK_TICKING_TICKET_LEVEL = ChunkLevel.BLOCK_TICKING_LEVEL; -@@ -189,7 +190,7 @@ public final class ChunkHolderManager { - if (halt) { - LOGGER.info("Waiting 60s for chunk system to halt for world '" + WorldUtil.getWorldName(this.world) + "'"); - if (!this.taskScheduler.halt(true, TimeUnit.SECONDS.toNanos(60L))) { -- LOGGER.warn("Failed to halt world generation/loading tasks for world '" + WorldUtil.getWorldName(this.world) + "'"); -+ LOGGER.warn("Failed to halt generation/loading tasks for world '" + WorldUtil.getWorldName(this.world) + "'"); - } else { - LOGGER.info("Halted chunk system for world '" + WorldUtil.getWorldName(this.world) + "'"); - } -@@ -199,21 +200,21 @@ public final class ChunkHolderManager { - this.saveAllChunks(true, true, true); - } - -- boolean hasTasks = false; -- for (final RegionFileIOThread.RegionFileType type : RegionFileIOThread.RegionFileType.values()) { -- if (RegionFileIOThread.getControllerFor(this.world, type).hasTasks()) { -- hasTasks = true; -- break; -+ MoonriseRegionFileIO.flush(this.world); -+ -+ if (halt) { -+ LOGGER.info("Waiting 60s for chunk I/O to halt for world '" + WorldUtil.getWorldName(this.world) + "'"); -+ if (!this.taskScheduler.haltIO(true, TimeUnit.SECONDS.toNanos(60L))) { -+ LOGGER.warn("Failed to halt I/O tasks for world '" + WorldUtil.getWorldName(this.world) + "'"); -+ } else { -+ LOGGER.info("Halted I/O scheduler for world '" + WorldUtil.getWorldName(this.world) + "'"); - } - } -- if (hasTasks) { -- RegionFileIOThread.flush(); -- } - - // kill regionfile cache -- for (final RegionFileIOThread.RegionFileType type : RegionFileIOThread.RegionFileType.values()) { -+ for (final MoonriseRegionFileIO.RegionFileType type : MoonriseRegionFileIO.RegionFileType.values()) { - try { -- RegionFileIOThread.getControllerFor(this.world, type).getCache().close(); -+ MoonriseRegionFileIO.getControllerFor(this.world, type).getCache().close(); - } catch (final IOException ex) { - LOGGER.error("Failed to close '" + type.name() + "' regionfile cache for world '" + WorldUtil.getWorldName(this.world) + "'", ex); - } -@@ -230,8 +231,8 @@ public final class ChunkHolderManager { - public void autoSave() { - final List reschedule = new ArrayList<>(); - final long currentTick = this.currentTick; -- final long maxSaveTime = currentTick - Math.max(1L, this.world.paperConfig().chunks.autoSaveInterval.value()); -- final int maxToSave = this.world.paperConfig().chunks.maxAutoSaveChunksPerTick; -+ final long maxSaveTime = currentTick - Math.max(1L, PlatformHooks.get().configAutoSaveInterval()); -+ final int maxToSave = PlatformHooks.get().configMaxAutoSavePerTick(); - for (int autoSaved = 0; autoSaved < maxToSave && !this.autoSaveQueue.isEmpty();) { - final NewChunkHolder holder = this.autoSaveQueue.first(); - -@@ -271,55 +272,74 @@ public final class ChunkHolderManager { - - long start = System.nanoTime(); - long lastLog = start; -- boolean needsFlush = false; -- final int flushInterval = 50; -+ final int flushInterval = 200; -+ int lastFlush = 0; - - int savedChunk = 0; - int savedEntity = 0; - int savedPoi = 0; - -+ if (shutdown) { -+ // Normal unload process does not occur during shutdown: fire event manually -+ // for mods that expect ChunkEvent.Unload to fire on shutdown (before LevelEvent.Unload) -+ for (int i = 0, len = holders.size(); i < len; ++i) { -+ final NewChunkHolder holder = holders.get(i); -+ if (holder.getCurrentChunk() instanceof LevelChunk levelChunk) { -+ PlatformHooks.get().chunkUnloadFromWorld(levelChunk); -+ } -+ } -+ } - for (int i = 0, len = holders.size(); i < len; ++i) { - final NewChunkHolder holder = holders.get(i); - try { - final NewChunkHolder.SaveStat saveStat = holder.save(shutdown); - if (saveStat != null) { -- ++saved; -- needsFlush = flush; - if (saveStat.savedChunk()) { - ++savedChunk; -+ ++saved; - } - if (saveStat.savedEntityChunk()) { - ++savedEntity; -+ ++saved; - } - if (saveStat.savedPoiChunk()) { - ++savedPoi; -+ ++saved; - } - } - } catch (final Throwable thr) { - LOGGER.error("Failed to save chunk (" + holder.chunkX + "," + holder.chunkZ + ") in world '" + WorldUtil.getWorldName(this.world) + "'", thr); - } -- if (needsFlush && (saved % flushInterval) == 0) { -- needsFlush = false; -- RegionFileIOThread.partialFlush(flushInterval / 2); -+ if (flush && (saved - lastFlush) > (flushInterval / 2)) { -+ lastFlush = saved; -+ MoonriseRegionFileIO.partialFlush(this.world, flushInterval / 2); - } - if (logProgress) { - final long currTime = System.nanoTime(); - if ((currTime - lastLog) > TimeUnit.SECONDS.toNanos(10L)) { - lastLog = currTime; -- LOGGER.info("Saved " + saved + " chunks (" + format.format((double)(i+1)/(double)len * 100.0) + "%) in world '" + WorldUtil.getWorldName(this.world) + "'"); -+ LOGGER.info( -+ "Saved " + savedChunk + " block chunks, " + savedEntity + " entity chunks, " + savedPoi -+ + " poi chunks in world '" + WorldUtil.getWorldName(this.world) + "', progress: " -+ + format.format((double)(i+1)/(double)len * 100.0) -+ ); - } - } - } - if (flush) { -- RegionFileIOThread.flush(); -+ MoonriseRegionFileIO.flush(this.world); - try { -- RegionFileIOThread.flushRegionStorages(this.world); -+ MoonriseRegionFileIO.flushRegionStorages(this.world); - } catch (final IOException ex) { - LOGGER.error("Exception when flushing regions in world '" + WorldUtil.getWorldName(this.world) + "'", ex); - } - } - if (logProgress) { -- LOGGER.info("Saved " + savedChunk + " block chunks, " + savedEntity + " entity chunks, " + savedPoi + " poi chunks in world '" + WorldUtil.getWorldName(this.world) + "' in " + format.format(1.0E-9 * (System.nanoTime() - start)) + "s"); -+ LOGGER.info( -+ "Saved " + savedChunk + " block chunks, " + savedEntity + " entity chunks, " + savedPoi -+ + " poi chunks in world '" + WorldUtil.getWorldName(this.world) + "' in " -+ + format.format(1.0E-9 * (System.nanoTime() - start)) + "s" -+ ); - } - } - -@@ -798,21 +818,21 @@ public final class ChunkHolderManager { - return this.chunkHolders.get(position); - } - -- public void raisePriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { -+ public void raisePriority(final int x, final int z, final Priority priority) { - final NewChunkHolder chunkHolder = this.getChunkHolder(x, z); - if (chunkHolder != null) { - chunkHolder.raisePriority(priority); - } - } - -- public void setPriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { -+ public void setPriority(final int x, final int z, final Priority priority) { - final NewChunkHolder chunkHolder = this.getChunkHolder(x, z); - if (chunkHolder != null) { - chunkHolder.setPriority(priority); - } - } - -- public void lowerPriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { -+ public void lowerPriority(final int x, final int z, final Priority priority) { - final NewChunkHolder chunkHolder = this.getChunkHolder(x, z); - if (chunkHolder != null) { - chunkHolder.lowerPriority(priority); -@@ -895,7 +915,7 @@ public final class ChunkHolderManager { - final ChunkLoadTask.EntityDataLoadTask entityLoad = current.getEntityDataLoadTask(); - - if (entityLoad != null) { -- entityLoad.raisePriority(PrioritisedExecutor.Priority.BLOCKING); -+ entityLoad.raisePriority(Priority.BLOCKING); - } - } - } -@@ -971,7 +991,7 @@ public final class ChunkHolderManager { - final ChunkLoadTask.PoiDataLoadTask poiLoad = current.getPoiDataLoadTask(); - - if (poiLoad != null) { -- poiLoad.raisePriority(PrioritisedExecutor.Priority.BLOCKING); -+ poiLoad.raisePriority(Priority.BLOCKING); - } - } - } finally { -@@ -1018,7 +1038,7 @@ public final class ChunkHolderManager { - } - - ChunkHolderManager.this.processPendingFullUpdate(); -- }, PrioritisedExecutor.Priority.HIGHEST); -+ }, Priority.HIGHEST); - } else { - final ArrayDeque pendingFullLoadUpdate = this.pendingFullLoadUpdate; - for (int i = 0, len = changedFullStatus.size(); i < len; ++i) { -@@ -1028,11 +1048,10 @@ public final class ChunkHolderManager { - } - - private void removeChunkHolder(final NewChunkHolder holder) { -- holder.markUnloaded(); -+ holder.onUnload(); - this.autoSaveQueue.remove(holder); - ChunkSystem.onChunkHolderDelete(this.world, holder.vanillaChunkHolder); - this.chunkHolders.remove(CoordinateUtils.getChunkKey(holder.chunkX, holder.chunkZ)); -- - } - - // note: never call while inside the chunk system, this will absolutely break everything -@@ -1313,6 +1332,9 @@ public final class ChunkHolderManager { - if (BLOCK_TICKET_UPDATES.get() == Boolean.TRUE) { - throw new IllegalStateException("Cannot update ticket level while unloading chunks or updating entity manager"); - } -+ if (!PlatformHooks.get().allowAsyncTicketUpdates() && !TickThread.isTickThread()) { -+ TickThread.ensureTickThread("Cannot asynchronously process ticket updates"); -+ } - - List changedFullStatus = null; - -@@ -1328,10 +1350,15 @@ public final class ChunkHolderManager { - } - changedFullStatus = new ArrayList<>(); - -- ret |= this.ticketLevelPropagator.performUpdates( -- this.ticketLockArea, this.taskScheduler.schedulingLockArea, -- scheduledTasks, changedFullStatus -- ); -+ this.blockTicketUpdates(); -+ try { -+ ret |= this.ticketLevelPropagator.performUpdates( -+ this.ticketLockArea, this.taskScheduler.schedulingLockArea, -+ scheduledTasks, changedFullStatus -+ ); -+ } finally { -+ this.unblockTicketUpdates(Boolean.FALSE); -+ } - } - - if (changedFullStatus != null) { -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java -index 8671a90e969d16c7a57ddc38fedb7cf01815f64c..120ce31729dc8d4bba0901ca06d3212f3158d089 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java -@@ -1,16 +1,17 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool; --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadedTaskQueue; -+import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.queue.PrioritisedTaskQueue; -+import ca.spottedleaf.concurrentutil.executor.thread.PrioritisedThreadPool; - import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; - import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.Priority; -+import ca.spottedleaf.moonrise.common.config.moonrise.MoonriseConfig; - import ca.spottedleaf.moonrise.common.util.CoordinateUtils; - import ca.spottedleaf.moonrise.common.util.JsonUtil; - import ca.spottedleaf.moonrise.common.util.MoonriseCommon; - import ca.spottedleaf.moonrise.common.util.TickThread; - import ca.spottedleaf.moonrise.common.util.WorldUtil; --import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; - import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; - import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkStatus; - import ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer; -@@ -23,7 +24,6 @@ import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkUpgrade - import ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer; - import ca.spottedleaf.moonrise.patches.chunk_system.status.ChunkSystemChunkStep; - import ca.spottedleaf.moonrise.patches.chunk_system.util.ParallelSearchRadiusIteration; --import com.mojang.logging.LogUtils; - import com.google.gson.JsonArray; - import com.google.gson.JsonObject; - import net.minecraft.CrashReport; -@@ -48,6 +48,7 @@ import net.minecraft.world.level.chunk.status.ChunkStatus; - import net.minecraft.world.level.chunk.status.ChunkStep; - import net.minecraft.world.phys.Vec3; - import org.slf4j.Logger; -+import org.slf4j.LoggerFactory; - import java.io.File; - import java.time.LocalDateTime; - import java.time.format.DateTimeFormatter; -@@ -63,51 +64,14 @@ import java.util.function.Consumer; - - public final class ChunkTaskScheduler { - -- private static final Logger LOGGER = LogUtils.getClassLogger(); -+ private static final Logger LOGGER = LoggerFactory.getLogger(ChunkTaskScheduler.class); - -- static int newChunkSystemIOThreads; -- static int newChunkSystemGenParallelism; -- static int newChunkSystemGenPopulationParallelism; -- static int newChunkSystemLoadParallelism; -- -- private static boolean initialised = false; -- -- public static void init(io.papermc.paper.configuration.GlobalConfiguration.ChunkSystem chunkSystem) { -- if (initialised) { -- return; -- } -- initialised = true; -- MoonriseCommon.init(chunkSystem); // Paper -- newChunkSystemIOThreads = chunkSystem.ioThreads; -- if (newChunkSystemIOThreads <= 0) { -- newChunkSystemIOThreads = 1; -- } else { -- newChunkSystemIOThreads = Math.max(1, newChunkSystemIOThreads); -- } -- -- String newChunkSystemGenParallelism = chunkSystem.genParallelism; -- if (newChunkSystemGenParallelism.equalsIgnoreCase("default")) { -- newChunkSystemGenParallelism = "true"; -- } -- -- boolean useParallelGen; -- if (newChunkSystemGenParallelism.equalsIgnoreCase("on") || newChunkSystemGenParallelism.equalsIgnoreCase("enabled") -- || newChunkSystemGenParallelism.equalsIgnoreCase("true")) { -- useParallelGen = true; -- } else if (newChunkSystemGenParallelism.equalsIgnoreCase("off") || newChunkSystemGenParallelism.equalsIgnoreCase("disabled") -- || newChunkSystemGenParallelism.equalsIgnoreCase("false")) { -- useParallelGen = false; -- } else { -- throw new IllegalStateException("Invalid option for gen-parallelism: must be one of [on, off, enabled, disabled, true, false, default]"); -+ public static void init(final boolean useParallelGen) { -+ for (final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor executor : MoonriseCommon.RADIUS_AWARE_GROUP.getAllExecutors()) { -+ executor.setMaxParallelism(useParallelGen ? -1 : 1); - } - -- ChunkTaskScheduler.newChunkSystemGenParallelism = MoonriseCommon.WORKER_THREADS; -- ChunkTaskScheduler.newChunkSystemGenPopulationParallelism = useParallelGen ? MoonriseCommon.WORKER_THREADS : 1; -- ChunkTaskScheduler.newChunkSystemLoadParallelism = MoonriseCommon.WORKER_THREADS; -- -- RegionFileIOThread.init(newChunkSystemIOThreads); -- -- LOGGER.info("Chunk system is using " + newChunkSystemIOThreads + " I/O threads, " + MoonriseCommon.WORKER_THREADS + " worker threads, and population gen parallelism of " + ChunkTaskScheduler.newChunkSystemGenPopulationParallelism + " threads"); -+ LOGGER.info("Chunk system is using population gen parallelism: " + useParallelGen); - } - - public static final TicketType CHUNK_LOAD = TicketType.create("chunk_system:chunk_load", Long::compareTo); -@@ -151,13 +115,15 @@ public final class ChunkTaskScheduler { - } - - public final ServerLevel world; -- public final PrioritisedThreadPool workers; - public final RadiusAwarePrioritisedExecutor radiusAwareScheduler; -- public final PrioritisedThreadPool.PrioritisedPoolExecutor parallelGenExecutor; -- private final PrioritisedThreadPool.PrioritisedPoolExecutor radiusAwareGenExecutor; -- public final PrioritisedThreadPool.PrioritisedPoolExecutor loadExecutor; -+ public final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor parallelGenExecutor; -+ private final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor radiusAwareGenExecutor; -+ public final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor loadExecutor; -+ public final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor ioExecutor; -+ public final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor compressionExecutor; -+ public final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor saveExecutor; - -- private final PrioritisedThreadedTaskQueue mainThreadExecutor = new PrioritisedThreadedTaskQueue(); -+ private final PrioritisedTaskQueue mainThreadExecutor = new PrioritisedTaskQueue(); - - public final ChunkHolderManager chunkHolderManager; - -@@ -306,9 +272,8 @@ public final class ChunkTaskScheduler { - return this.lockShift; - } - -- public ChunkTaskScheduler(final ServerLevel world, final PrioritisedThreadPool workers) { -+ public ChunkTaskScheduler(final ServerLevel world) { - this.world = world; -- this.workers = workers; - // must be >= region shift (in paper, doesn't exist) and must be >= ticket propagator section shift - // it must be >= region shift since the regioniser assumes ticket updates do not occur in parallel for the region sections - // it must be >= ticket propagator section shift so that the ticket propagator can assume that owning a position implies owning -@@ -317,11 +282,14 @@ public final class ChunkTaskScheduler { - this.lockShift = Math.max(((ChunkSystemServerLevel)world).moonrise$getRegionChunkShift(), ThreadedTicketLevelPropagator.SECTION_SHIFT); - this.schedulingLockArea = new ReentrantAreaLock(this.getChunkSystemLockShift()); - -- final String worldName = WorldUtil.getWorldName(world); -- this.parallelGenExecutor = workers.createExecutor("Chunk parallel generation executor for world '" + worldName + "'", 1, Math.max(1, newChunkSystemGenParallelism)); -- this.radiusAwareGenExecutor = workers.createExecutor("Chunk radius aware generator for world '" + worldName + "'", 1, Math.max(1, newChunkSystemGenPopulationParallelism)); -- this.loadExecutor = workers.createExecutor("Chunk load executor for world '" + worldName + "'", 1, newChunkSystemLoadParallelism); -- this.radiusAwareScheduler = new RadiusAwarePrioritisedExecutor(this.radiusAwareGenExecutor, Math.max(2, 1 + newChunkSystemGenPopulationParallelism)); -+ this.parallelGenExecutor = MoonriseCommon.PARALLEL_GEN_GROUP.createExecutor(-1, MoonriseCommon.WORKER_QUEUE_HOLD_TIME, 0); -+ this.radiusAwareGenExecutor = MoonriseCommon.RADIUS_AWARE_GROUP.createExecutor(1, MoonriseCommon.WORKER_QUEUE_HOLD_TIME, 0); -+ this.loadExecutor = MoonriseCommon.LOAD_GROUP.createExecutor(-1, MoonriseCommon.WORKER_QUEUE_HOLD_TIME, 0); -+ this.radiusAwareScheduler = new RadiusAwarePrioritisedExecutor(this.radiusAwareGenExecutor, 16); -+ this.ioExecutor = MoonriseCommon.SERVER_REGION_IO_GROUP.createExecutor(-1, MoonriseCommon.IO_QUEUE_HOLD_TIME, 0); -+ // we need a separate executor here so that on shutdown we can continue to process I/O tasks -+ this.compressionExecutor = MoonriseCommon.LOAD_GROUP.createExecutor(-1, MoonriseCommon.WORKER_QUEUE_HOLD_TIME, 0); -+ this.saveExecutor = MoonriseCommon.LOAD_GROUP.createExecutor(-1, MoonriseCommon.WORKER_QUEUE_HOLD_TIME, 0); - this.chunkHolderManager = new ChunkHolderManager(world, this); - } - -@@ -360,7 +328,7 @@ public final class ChunkTaskScheduler { - }; - - // this may not be good enough, specifically thanks to stupid ass plugins swallowing exceptions -- this.scheduleChunkTask(chunkX, chunkZ, crash, PrioritisedExecutor.Priority.BLOCKING); -+ this.scheduleChunkTask(chunkX, chunkZ, crash, Priority.BLOCKING); - // so, make the main thread pick it up - ((ChunkSystemMinecraftServer)this.world.getServer()).moonrise$setChunkSystemCrash(new RuntimeException("Chunk system crash propagated from unrecoverableChunkSystemFailure", reportedException)); - } -@@ -370,20 +338,20 @@ public final class ChunkTaskScheduler { - return this.mainThreadExecutor.executeTask(); - } - -- public void raisePriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { -+ public void raisePriority(final int x, final int z, final Priority priority) { - this.chunkHolderManager.raisePriority(x, z, priority); - } - -- public void setPriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { -+ public void setPriority(final int x, final int z, final Priority priority) { - this.chunkHolderManager.setPriority(x, z, priority); - } - -- public void lowerPriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { -+ public void lowerPriority(final int x, final int z, final Priority priority) { - this.chunkHolderManager.lowerPriority(x, z, priority); - } - - public void scheduleTickingState(final int chunkX, final int chunkZ, final FullChunkStatus toStatus, -- final boolean addTicket, final PrioritisedExecutor.Priority priority, -+ final boolean addTicket, final Priority priority, - final Consumer onComplete) { - final int radius = toStatus.ordinal() - 1; // 0 -> BORDER, 1 -> TICKING, 2 -> ENTITY_TICKING - -@@ -479,7 +447,7 @@ public final class ChunkTaskScheduler { - } - - public void scheduleChunkLoad(final int chunkX, final int chunkZ, final boolean gen, final ChunkStatus toStatus, final boolean addTicket, -- final PrioritisedExecutor.Priority priority, final Consumer onComplete) { -+ final Priority priority, final Consumer onComplete) { - if (gen) { - this.scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); - return; -@@ -503,7 +471,7 @@ public final class ChunkTaskScheduler { - - // only appropriate to use with syncLoadNonFull - public boolean beginChunkLoadForNonFullSync(final int chunkX, final int chunkZ, final ChunkStatus toStatus, -- final PrioritisedExecutor.Priority priority) { -+ final Priority priority) { - final int accessRadius = getAccessRadius(toStatus); - final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); - final int minLevel = ChunkTaskScheduler.getTicketLevel(toStatus); -@@ -548,6 +516,11 @@ public final class ChunkTaskScheduler { - if (status == null || status.isOrAfter(ChunkStatus.FULL)) { - throw new IllegalArgumentException("Status: " + status); - } -+ -+ if (!TickThread.isTickThread()) { -+ return this.world.getChunkSource().getChunk(chunkX, chunkZ, status, true); -+ } -+ - ChunkAccess loaded = ((ChunkSystemServerLevel)this.world).moonrise$getSpecificChunkIfLoaded(chunkX, chunkZ, status); - if (loaded != null) { - return loaded; -@@ -558,7 +531,7 @@ public final class ChunkTaskScheduler { - this.chunkHolderManager.addTicketAtLevel(NON_FULL_CHUNK_LOAD, chunkX, chunkZ, ticketLevel, ticketId); - this.chunkHolderManager.processTicketUpdates(); - -- this.beginChunkLoadForNonFullSync(chunkX, chunkZ, status, PrioritisedExecutor.Priority.BLOCKING); -+ this.beginChunkLoadForNonFullSync(chunkX, chunkZ, status, Priority.BLOCKING); - - // we could do a simple spinwait here, since we do not need to process tasks while performing this load - // but we process tasks only because it's a better use of the time spent -@@ -578,7 +551,7 @@ public final class ChunkTaskScheduler { - } - - public void scheduleChunkLoad(final int chunkX, final int chunkZ, final ChunkStatus toStatus, final boolean addTicket, -- final PrioritisedExecutor.Priority priority, final Consumer onComplete) { -+ final Priority priority, final Consumer onComplete) { - if (!TickThread.isTickThreadFor(this.world, chunkX, chunkZ)) { - this.scheduleChunkTask(chunkX, chunkZ, () -> { - ChunkTaskScheduler.this.scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -@@ -670,7 +643,7 @@ public final class ChunkTaskScheduler { - - private ChunkProgressionTask createTask(final int chunkX, final int chunkZ, final ChunkAccess chunk, - final NewChunkHolder chunkHolder, final StaticCache2D neighbours, -- final ChunkStatus toStatus, final PrioritisedExecutor.Priority initialPriority) { -+ final ChunkStatus toStatus, final Priority initialPriority) { - if (toStatus == ChunkStatus.EMPTY) { - return new ChunkLoadTask(this, this.world, chunkX, chunkZ, chunkHolder, initialPriority); - } -@@ -686,7 +659,7 @@ public final class ChunkTaskScheduler { - - ChunkProgressionTask schedule(final int chunkX, final int chunkZ, final ChunkStatus targetStatus, final NewChunkHolder chunkHolder, - final List allTasks) { -- return this.schedule(chunkX, chunkZ, targetStatus, chunkHolder, allTasks, chunkHolder.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL)); -+ return this.schedule(chunkX, chunkZ, targetStatus, chunkHolder, allTasks, chunkHolder.getEffectivePriority(Priority.NORMAL)); - } - - // rets new task scheduled for the _specified_ chunk -@@ -695,7 +668,7 @@ public final class ChunkTaskScheduler { - // schedule will ignore the generation target, so it should be checked by the caller to ensure the target is not regressed! - private ChunkProgressionTask schedule(final int chunkX, final int chunkZ, final ChunkStatus targetStatus, - final NewChunkHolder chunkHolder, final List allTasks, -- final PrioritisedExecutor.Priority minPriority) { -+ final Priority minPriority) { - if (!this.schedulingLockArea.isHeldByCurrentThread(chunkX, chunkZ, getAccessRadius(targetStatus))) { - throw new IllegalStateException("Not holding scheduling lock"); - } -@@ -705,8 +678,8 @@ public final class ChunkTaskScheduler { - return null; - } - -- final PrioritisedExecutor.Priority requestedPriority = PrioritisedExecutor.Priority.max( -- minPriority, chunkHolder.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) -+ final Priority requestedPriority = Priority.max( -+ minPriority, chunkHolder.getEffectivePriority(Priority.NORMAL) - ); - final ChunkStatus currentGenStatus = chunkHolder.getCurrentGenStatus(); - final ChunkAccess chunk = chunkHolder.getCurrentChunk(); -@@ -743,7 +716,7 @@ public final class ChunkTaskScheduler { - - final int neighbourReadRadius = Math.max( - 0, -- chunkPyramid.getStepTo(toStatus).getAccumulatedRadiusOf(ChunkStatus.EMPTY) -+ chunkStep.getAccumulatedRadiusOf(ChunkStatus.EMPTY) - ); - - boolean unGeneratedNeighbours = false; -@@ -783,7 +756,7 @@ public final class ChunkTaskScheduler { - - final ChunkProgressionTask task = this.createTask( - chunkX, chunkZ, chunk, chunkHolder, neighbours, toStatus, -- chunkHolder.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) -+ chunkHolder.getEffectivePriority(Priority.NORMAL) - ); - allTasks.add(task); - -@@ -794,7 +767,7 @@ public final class ChunkTaskScheduler { - - // rets true if the neighbour is not at the required status, false otherwise - private boolean checkNeighbour(final int chunkX, final int chunkZ, final ChunkStatus requiredStatus, final NewChunkHolder center, -- final List tasks, final PrioritisedExecutor.Priority minPriority) { -+ final List tasks, final Priority minPriority) { - final NewChunkHolder chunkHolder = this.chunkHolderManager.getChunkHolder(chunkX, chunkZ); - - if (chunkHolder == null) { -@@ -830,41 +803,41 @@ public final class ChunkTaskScheduler { - */ - @Deprecated - public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final Runnable run) { -- return this.scheduleChunkTask(run, PrioritisedExecutor.Priority.NORMAL); -+ return this.scheduleChunkTask(run, Priority.NORMAL); - } - - /** - * @deprecated Chunk tasks must be tied to coordinates in the future - */ - @Deprecated -- public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final Runnable run, final PrioritisedExecutor.Priority priority) { -- return this.mainThreadExecutor.queueRunnable(run, priority); -+ public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final Runnable run, final Priority priority) { -+ return this.mainThreadExecutor.queueTask(run, priority); - } - - public PrioritisedExecutor.PrioritisedTask createChunkTask(final int chunkX, final int chunkZ, final Runnable run) { -- return this.createChunkTask(chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); -+ return this.createChunkTask(chunkX, chunkZ, run, Priority.NORMAL); - } - - public PrioritisedExecutor.PrioritisedTask createChunkTask(final int chunkX, final int chunkZ, final Runnable run, -- final PrioritisedExecutor.Priority priority) { -+ final Priority priority) { - return this.mainThreadExecutor.createTask(run, priority); - } - - public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final int chunkX, final int chunkZ, final Runnable run) { -- return this.scheduleChunkTask(chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); -+ return this.scheduleChunkTask(chunkX, chunkZ, run, Priority.NORMAL); - } - - public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final int chunkX, final int chunkZ, final Runnable run, -- final PrioritisedExecutor.Priority priority) { -- return this.mainThreadExecutor.queueRunnable(run, priority); -+ final Priority priority) { -+ return this.mainThreadExecutor.queueTask(run, priority); - } - - public boolean halt(final boolean sync, final long maxWaitNS) { - this.radiusAwareGenExecutor.halt(); - this.parallelGenExecutor.halt(); - this.loadExecutor.halt(); -- final long time = System.nanoTime(); - if (sync) { -+ final long time = System.nanoTime(); - for (long failures = 9L;; failures = ConcurrentUtil.linearLongBackoff(failures, 500_000L, 50_000_000L)) { - if ( - !this.radiusAwareGenExecutor.isActive() && -@@ -882,6 +855,29 @@ public final class ChunkTaskScheduler { - return true; - } - -+ public boolean haltIO(final boolean sync, final long maxWaitNS) { -+ this.ioExecutor.halt(); -+ this.saveExecutor.halt(); -+ this.compressionExecutor.halt(); -+ if (sync) { -+ final long time = System.nanoTime(); -+ for (long failures = 9L;; failures = ConcurrentUtil.linearLongBackoff(failures, 500_000L, 50_000_000L)) { -+ if ( -+ !this.ioExecutor.isActive() && -+ !this.saveExecutor.isActive() && -+ !this.compressionExecutor.isActive() -+ ) { -+ return true; -+ } -+ if ((System.nanoTime() - time) >= maxWaitNS) { -+ return false; -+ } -+ } -+ } -+ -+ return true; -+ } -+ - public static final ArrayDeque WAITING_CHUNKS = new ArrayDeque<>(); // stack - - public static final class ChunkInfo { -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -index 45eda96fd8a1acb87dbb69ce5495fec7e451416f..381631e405895ba3eede1cd2e1011c64aadbd662 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -@@ -1,18 +1,20 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; - --import ca.spottedleaf.concurrentutil.completable.Completable; -+import ca.spottedleaf.concurrentutil.completable.CallbackCompletable; - import ca.spottedleaf.concurrentutil.executor.Cancellable; --import ca.spottedleaf.concurrentutil.executor.standard.DelayedPrioritisedTask; --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; - import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; - import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.Priority; -+import ca.spottedleaf.moonrise.common.PlatformHooks; -+import ca.spottedleaf.moonrise.common.misc.LazyRunnable; - import ca.spottedleaf.moonrise.common.util.CoordinateUtils; - import ca.spottedleaf.moonrise.common.util.TickThread; - import ca.spottedleaf.moonrise.common.util.WorldUtil; - import ca.spottedleaf.moonrise.common.util.ChunkSystem; --import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystemFeatures; --import ca.spottedleaf.moonrise.patches.chunk_system.async_save.AsyncChunkSaveData; --import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; -+import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; -+import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel; - import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; - import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkHolder; - import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkStatus; -@@ -36,13 +38,14 @@ import net.minecraft.server.level.ChunkHolder; - import net.minecraft.server.level.ChunkLevel; - import net.minecraft.server.level.FullChunkStatus; - import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.progress.ChunkProgressListener; - 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.ImposterProtoChunk; - import net.minecraft.world.level.chunk.LevelChunk; - import net.minecraft.world.level.chunk.status.ChunkStatus; --import net.minecraft.world.level.chunk.storage.ChunkSerializer; -+import net.minecraft.world.level.chunk.storage.SerializableChunkData; - import org.slf4j.Logger; - import org.slf4j.LoggerFactory; - import java.lang.invoke.VarHandle; -@@ -58,6 +61,8 @@ public final class NewChunkHolder { - - private static final Logger LOGGER = LoggerFactory.getLogger(NewChunkHolder.class); - -+ public final ChunkData holderData; -+ - public final ServerLevel world; - public final int chunkX; - public final int chunkZ; -@@ -89,7 +94,7 @@ public final class NewChunkHolder { - if (this.entityChunk == null) { - ret = this.entityChunk = new ChunkEntitySlices( - this.world, this.chunkX, this.chunkZ, this.getChunkStatus(), -- WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) -+ this.holderData, WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) - ); - - ret.setTransient(transientChunk); -@@ -173,7 +178,7 @@ public final class NewChunkHolder { - // no tasks to schedule _for_ - } else { - entityDataLoadTask = this.entityDataLoadTask = new ChunkLoadTask.EntityDataLoadTask( -- this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) -+ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(Priority.NORMAL) - ); - entityDataLoadTask.addCallback(this::completeEntityLoad); - // need one schedule() per waiter -@@ -220,7 +225,7 @@ public final class NewChunkHolder { - - if (this.entityDataLoadTask == null) { - this.entityDataLoadTask = new ChunkLoadTask.EntityDataLoadTask( -- this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) -+ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(Priority.NORMAL) - ); - this.entityDataLoadTask.addCallback(this::completeEntityLoad); - this.entityDataLoadTaskWaiters = new ArrayList<>(); -@@ -294,7 +299,7 @@ public final class NewChunkHolder { - // no tasks to schedule _for_ - } else { - poiDataLoadTask = this.poiDataLoadTask = new ChunkLoadTask.PoiDataLoadTask( -- this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) -+ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(Priority.NORMAL) - ); - poiDataLoadTask.addCallback(this::completePoiLoad); - // need one schedule() per waiter -@@ -340,7 +345,7 @@ public final class NewChunkHolder { - - if (this.poiDataLoadTask == null) { - this.poiDataLoadTask = new ChunkLoadTask.PoiDataLoadTask( -- this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL) -+ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority(Priority.NORMAL) - ); - this.poiDataLoadTask.addCallback(this::completePoiLoad); - this.poiDataLoadTaskWaiters = new ArrayList<>(); -@@ -519,15 +524,15 @@ public final class NewChunkHolder { - // priority state - - // the target priority for this chunk to generate at -- private PrioritisedExecutor.Priority priority = null; -+ private Priority priority = null; - private boolean priorityLocked; - - // the priority neighbouring chunks have requested this chunk generate at -- private PrioritisedExecutor.Priority neighbourRequestedPriority = null; -+ private Priority neighbourRequestedPriority = null; - -- public PrioritisedExecutor.Priority getEffectivePriority(final PrioritisedExecutor.Priority dfl) { -- final PrioritisedExecutor.Priority neighbour = this.neighbourRequestedPriority; -- final PrioritisedExecutor.Priority us = this.priority; -+ public Priority getEffectivePriority(final Priority dfl) { -+ final Priority neighbour = this.neighbourRequestedPriority; -+ final Priority us = this.priority; - - if (neighbour == null) { - return us == null ? dfl : us; -@@ -536,7 +541,7 @@ public final class NewChunkHolder { - return neighbour; - } - -- return PrioritisedExecutor.Priority.max(us, neighbour); -+ return Priority.max(us, neighbour); - } - - private void recalculateNeighbourRequestedPriority() { -@@ -545,18 +550,18 @@ public final class NewChunkHolder { - return; - } - -- PrioritisedExecutor.Priority max = null; -+ Priority max = null; - - for (final NewChunkHolder holder : this.neighboursWaitingForUs.keySet()) { -- final PrioritisedExecutor.Priority neighbourPriority = holder.getEffectivePriority(null); -+ final Priority neighbourPriority = holder.getEffectivePriority(null); - if (neighbourPriority != null && (max == null || neighbourPriority.isHigherPriority(max))) { - max = neighbourPriority; - } - } - -- final PrioritisedExecutor.Priority current = this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL); -+ final Priority current = this.getEffectivePriority(Priority.NORMAL); - this.neighbourRequestedPriority = max; -- final PrioritisedExecutor.Priority next = this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL); -+ final Priority next = this.getEffectivePriority(Priority.NORMAL); - - if (current == next) { - return; -@@ -578,7 +583,7 @@ public final class NewChunkHolder { - } - - // must hold scheduling lock -- public void raisePriority(final PrioritisedExecutor.Priority priority) { -+ public void raisePriority(final Priority priority) { - if (this.priority != null && this.priority.isHigherOrEqualPriority(priority)) { - return; - } -@@ -591,13 +596,13 @@ public final class NewChunkHolder { - } - - // must hold scheduling lock -- public void setPriority(final PrioritisedExecutor.Priority priority) { -+ public void setPriority(final Priority priority) { - if (this.priorityLocked) { - return; - } -- final PrioritisedExecutor.Priority old = this.getEffectivePriority(null); -+ final Priority old = this.getEffectivePriority(null); - this.priority = priority; -- final PrioritisedExecutor.Priority newPriority = this.getEffectivePriority(PrioritisedExecutor.Priority.NORMAL); -+ final Priority newPriority = this.getEffectivePriority(Priority.NORMAL); - - if (old != newPriority) { - if (this.generationTask != null) { -@@ -609,7 +614,7 @@ public final class NewChunkHolder { - } - - // must hold scheduling lock -- public void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ public void lowerPriority(final Priority priority) { - if (this.priority != null && this.priority.isLowerOrEqualPriority(priority)) { - return; - } -@@ -632,7 +637,7 @@ public final class NewChunkHolder { - } - - // ticket level state -- public int oldTicketLevel = ChunkHolderManager.MAX_TICKET_LEVEL + 1; -+ private int oldTicketLevel = ChunkHolderManager.MAX_TICKET_LEVEL + 1; - private int currentTicketLevel = ChunkHolderManager.MAX_TICKET_LEVEL + 1; - - public int getTicketLevel() { -@@ -651,6 +656,7 @@ public final class NewChunkHolder { - world.getLightEngine(), null, world.getChunkSource().chunkMap - ); - ((ChunkSystemChunkHolder)this.vanillaChunkHolder).moonrise$setRealChunkHolder(this); -+ this.holderData = ((ChunkSystemLevel)this.world).moonrise$requestChunkData(CoordinateUtils.getChunkKey(chunkX, chunkZ)); - } - - public ChunkAccess getCurrentChunk() { -@@ -750,8 +756,9 @@ public final class NewChunkHolder { - /** Unloaded from chunk map */ - private boolean unloaded; - -- void markUnloaded() { -+ void onUnload() { - this.unloaded = true; -+ ((ChunkSystemLevel)this.world).moonrise$releaseChunkData(CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ)); - } - - private boolean inUnloadQueue = false; -@@ -788,9 +795,10 @@ public final class NewChunkHolder { - private UnloadTask entityDataUnload; - private UnloadTask poiDataUnload; - -- public static final record UnloadTask(Completable completable, DelayedPrioritisedTask task) {} -+ public static final record UnloadTask(CallbackCompletable completable, PrioritisedExecutor.PrioritisedTask task, -+ LazyRunnable toRun) {} - -- public UnloadTask getUnloadTask(final RegionFileIOThread.RegionFileType type) { -+ public UnloadTask getUnloadTask(final MoonriseRegionFileIO.RegionFileType type) { - switch (type) { - case CHUNK_DATA: - return this.chunkDataUnload; -@@ -803,7 +811,7 @@ public final class NewChunkHolder { - } - } - -- private void removeUnloadTask(final RegionFileIOThread.RegionFileType type) { -+ private void removeUnloadTask(final MoonriseRegionFileIO.RegionFileType type) { - switch (type) { - case CHUNK_DATA: { - this.chunkDataUnload = null; -@@ -836,10 +844,10 @@ public final class NewChunkHolder { - // chunk state - this.currentChunk = null; - this.currentGenStatus = null; -- this.lastChunkCompletion = null; - for (int i = 0; i < this.chunkCompletions.length; ++i) { -- CHUNK_COMPLETION_ARRAY_HANDLE.setVolatile(this.chunkCompletions, i, (ChunkCompletion)null); -+ CHUNK_COMPLETION_ARRAY_HANDLE.setRelease(this.chunkCompletions, i, (ChunkCompletion)null); - } -+ this.lastChunkCompletion = null; - // entity chunk state - this.entityChunk = null; - this.pendingEntityChunk = null; -@@ -851,22 +859,23 @@ public final class NewChunkHolder { - this.priorityLocked = false; - - if (chunk != null) { -- this.chunkDataUnload = new UnloadTask(new Completable<>(), new DelayedPrioritisedTask(PrioritisedExecutor.Priority.NORMAL)); -+ final LazyRunnable toRun = new LazyRunnable(); -+ this.chunkDataUnload = new UnloadTask(new CallbackCompletable<>(), this.scheduler.saveExecutor.createTask(toRun), toRun); - } - if (poiChunk != null) { -- this.poiDataUnload = new UnloadTask(new Completable<>(), null); -+ this.poiDataUnload = new UnloadTask(new CallbackCompletable<>(), null, null); - } - if (entityChunk != null) { -- this.entityDataUnload = new UnloadTask(new Completable<>(), null); -+ this.entityDataUnload = new UnloadTask(new CallbackCompletable<>(), null, null); - } - - return this.unloadState = (chunk != null || entityChunk != null || poiChunk != null) ? new UnloadState(this, chunk, entityChunk, poiChunk) : null; - } - - // data is null if failed or does not need to be saved -- void completeAsyncUnloadDataSave(final RegionFileIOThread.RegionFileType type, final CompoundTag data) { -+ void completeAsyncUnloadDataSave(final MoonriseRegionFileIO.RegionFileType type, final CompoundTag data) { - if (data != null) { -- RegionFileIOThread.scheduleSave(this.world, this.chunkX, this.chunkZ, data, type); -+ MoonriseRegionFileIO.scheduleSave(this.world, this.chunkX, this.chunkZ, data, type); - } - - this.getUnloadTask(type).completable().complete(data); -@@ -886,18 +895,19 @@ public final class NewChunkHolder { - final ChunkEntitySlices entityChunk = state.entityChunk(); - final PoiChunk poiChunk = state.poiChunk(); - -- final boolean shouldLevelChunkNotSave = ChunkSystemFeatures.forceNoSave(chunk); -+ final boolean shouldLevelChunkNotSave = PlatformHooks.get().forceNoSave(chunk); - - // unload chunk data - if (chunk != null) { - if (chunk instanceof LevelChunk levelChunk) { - levelChunk.setLoaded(false); -+ PlatformHooks.get().chunkUnloadFromWorld(levelChunk); - } - - if (!shouldLevelChunkNotSave) { - this.saveChunk(chunk, true); - } else { -- this.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, null); -+ this.completeAsyncUnloadDataSave(MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, null); - } - - if (chunk instanceof LevelChunk levelChunk) { -@@ -1066,6 +1076,9 @@ public final class NewChunkHolder { - if (oldUnloaded != newUnloaded) { - this.checkUnload(); - } -+ -+ // Don't really have a choice but to place this hook here -+ PlatformHooks.get().onChunkHolderTicketChange(this.world, this, oldLevel, newLevel); - } - - static final int NEIGHBOUR_RADIUS = 2; -@@ -1111,24 +1124,6 @@ public final class NewChunkHolder { - private static final long CHUNK_LOADED_MASK_RAD1 = getLoadedMask(1); - private static final long CHUNK_LOADED_MASK_RAD2 = getLoadedMask(2); - -- public static boolean areNeighboursFullLoaded(final long bitset, final int radius) { -- switch (radius) { -- case 0: { -- return (bitset & CHUNK_LOADED_MASK_RAD0) == CHUNK_LOADED_MASK_RAD0; -- } -- case 1: { -- return (bitset & CHUNK_LOADED_MASK_RAD1) == CHUNK_LOADED_MASK_RAD1; -- } -- case 2: { -- return (bitset & CHUNK_LOADED_MASK_RAD2) == CHUNK_LOADED_MASK_RAD2; -- } -- -- default: { -- throw new IllegalArgumentException("Radius not recognized: " + radius); -- } -- } -- } -- - // only updated while holding scheduling lock - private FullChunkStatus pendingFullChunkStatus = FullChunkStatus.INACCESSIBLE; - // updated while holding no locks, but adds a ticket before to prevent pending status from dropping -@@ -1363,6 +1358,17 @@ public final class NewChunkHolder { - } - - private void completeStatusConsumers(ChunkStatus status, final ChunkAccess chunk) { -+ // Update progress listener for LevelLoadingScreen -+ if (chunk != null) { -+ final ChunkProgressListener progressListener = this.world.getChunkSource().chunkMap.progressListener; -+ if (progressListener != null) { -+ final ChunkStatus finalStatus = status; -+ this.scheduler.scheduleChunkTask(this.chunkX, this.chunkZ, () -> { -+ progressListener.onStatusChange(this.vanillaChunkHolder.getPos(), finalStatus); -+ }); -+ } -+ } -+ - // need to tell future statuses to complete if cancelled - do { - this.completeStatusConsumers0(status, chunk); -@@ -1386,7 +1392,7 @@ public final class NewChunkHolder { - LOGGER.error("Failed to process chunk status callback", thr); - } - } -- }, PrioritisedExecutor.Priority.HIGHEST); -+ }, Priority.HIGHEST); - } - - private final Reference2ObjectOpenHashMap>> fullStatusWaiters = new Reference2ObjectOpenHashMap<>(); -@@ -1414,7 +1420,7 @@ public final class NewChunkHolder { - LOGGER.error("Failed to process chunk status callback", thr); - } - } -- }, PrioritisedExecutor.Priority.HIGHEST); -+ }, Priority.HIGHEST); - } - - // note: must hold scheduling lock -@@ -1670,6 +1676,8 @@ public final class NewChunkHolder { - - public static final record SaveStat(boolean savedChunk, boolean savedEntityChunk, boolean savedPoiChunk) {} - -+ private static final MoonriseRegionFileIO.RegionFileType[] REGION_FILE_TYPES = MoonriseRegionFileIO.RegionFileType.values(); -+ - public SaveStat save(final boolean shutdown) { - TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Cannot save data off-main"); - -@@ -1677,6 +1685,7 @@ public final class NewChunkHolder { - PoiChunk poi = this.getPoiChunk(); - ChunkEntitySlices entities = this.getEntityChunk(); - boolean executedUnloadTask = false; -+ final boolean[] executedUnloadTasks = new boolean[REGION_FILE_TYPES.length]; - - if (shutdown) { - // make sure that the async unloads complete -@@ -1686,17 +1695,22 @@ public final class NewChunkHolder { - poi = this.unloadState.poiChunk(); - entities = this.unloadState.entityChunk(); - } -- final UnloadTask chunkUnloadTask = this.chunkDataUnload; -- final DelayedPrioritisedTask chunkDataUnloadTask = chunkUnloadTask == null ? null : chunkUnloadTask.task(); -- if (chunkDataUnloadTask != null) { -- final PrioritisedExecutor.PrioritisedTask unloadTask = chunkDataUnloadTask.getTask(); -- if (unloadTask != null) { -- executedUnloadTask = unloadTask.execute(); -+ for (final MoonriseRegionFileIO.RegionFileType regionFileType : REGION_FILE_TYPES) { -+ final UnloadTask unloadTask = this.getUnloadTask(regionFileType); -+ if (unloadTask == null) { -+ continue; -+ } -+ -+ final PrioritisedExecutor.PrioritisedTask task = unloadTask.task(); -+ if (task != null && task.isQueued()) { -+ final boolean executed = task.execute(); -+ executedUnloadTask |= executed; -+ executedUnloadTasks[regionFileType.ordinal()] = executed; - } - } - } - -- final boolean forceNoSaveChunk = ChunkSystemFeatures.forceNoSave(chunk); -+ final boolean forceNoSaveChunk = PlatformHooks.get().forceNoSave(chunk); - - // can only synchronously save worldgen chunks during shutdown - boolean canSaveChunk = !forceNoSaveChunk && (chunk != null && ((shutdown || chunk instanceof LevelChunk) && chunk.isUnsaved())); -@@ -1717,106 +1731,55 @@ public final class NewChunkHolder { - } - } - -- return executedUnloadTask | canSaveChunk | canSaveEntities | canSavePOI ? new SaveStat(executedUnloadTask || canSaveChunk, canSaveEntities, canSavePOI): null; -- } -- -- static final class AsyncChunkSerializeTask implements Runnable { -- -- private final ServerLevel world; -- private final ChunkAccess chunk; -- private final AsyncChunkSaveData asyncSaveData; -- private final NewChunkHolder toComplete; -- -- public AsyncChunkSerializeTask(final ServerLevel world, final ChunkAccess chunk, final AsyncChunkSaveData asyncSaveData, -- final NewChunkHolder toComplete) { -- this.world = world; -- this.chunk = chunk; -- this.asyncSaveData = asyncSaveData; -- this.toComplete = toComplete; -- } -- -- @Override -- public void run() { -- final CompoundTag toSerialize; -- try { -- toSerialize = ChunkSystemFeatures.saveChunkAsync(this.world, this.chunk, this.asyncSaveData); -- } catch (final Throwable throwable) { -- LOGGER.error("Failed to asynchronously save chunk " + this.chunk.getPos() + " for world '" + WorldUtil.getWorldName(this.world) + "', falling back to synchronous save", throwable); -- final ChunkPos pos = this.chunk.getPos(); -- ((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().scheduleChunkTask(pos.x, pos.z, () -> { -- final CompoundTag synchronousSave; -- try { -- synchronousSave = ChunkSystemFeatures.saveChunkAsync(AsyncChunkSerializeTask.this.world, AsyncChunkSerializeTask.this.chunk, AsyncChunkSerializeTask.this.asyncSaveData); -- } catch (final Throwable throwable2) { -- LOGGER.error("Failed to synchronously save chunk " + AsyncChunkSerializeTask.this.chunk.getPos() + " for world '" + WorldUtil.getWorldName(AsyncChunkSerializeTask.this.world) + "', chunk data will be lost", throwable2); -- AsyncChunkSerializeTask.this.toComplete.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, null); -- return; -- } -- -- AsyncChunkSerializeTask.this.toComplete.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, synchronousSave); -- LOGGER.info("Successfully serialized chunk " + AsyncChunkSerializeTask.this.chunk.getPos() + " for world '" + WorldUtil.getWorldName(AsyncChunkSerializeTask.this.world) + "' synchronously"); -- -- }, PrioritisedExecutor.Priority.HIGHEST); -- return; -- } -- this.toComplete.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, toSerialize); -- } -- -- @Override -- public String toString() { -- return "AsyncChunkSerializeTask{" + -- "chunk={pos=" + this.chunk.getPos() + ",world=\"" + WorldUtil.getWorldName(this.world) + "\"}" + -- "}"; -- } -+ return executedUnloadTask | canSaveChunk | canSaveEntities | canSavePOI ? -+ new SaveStat( -+ canSaveChunk | executedUnloadTasks[MoonriseRegionFileIO.RegionFileType.CHUNK_DATA.ordinal()], -+ canSaveEntities | executedUnloadTasks[MoonriseRegionFileIO.RegionFileType.ENTITY_DATA.ordinal()], -+ canSavePOI | executedUnloadTasks[MoonriseRegionFileIO.RegionFileType.POI_DATA.ordinal()] -+ ) -+ : null; - } - - private boolean saveChunk(final ChunkAccess chunk, final boolean unloading) { - if (!chunk.isUnsaved()) { - if (unloading) { -- this.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, null); -+ this.completeAsyncUnloadDataSave(MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, null); - } - return false; - } -- boolean completing = false; -- boolean failedAsyncPrepare = false; - try { -- if (unloading && ChunkSystemFeatures.supportsAsyncChunkSave()) { -- try { -- final AsyncChunkSaveData asyncSaveData = ChunkSystemFeatures.getAsyncSaveData(this.world, chunk); -+ final SerializableChunkData chunkData = SerializableChunkData.copyOf(this.world, chunk); -+ PlatformHooks.get().chunkSyncSave(this.world, chunk, chunkData); - -- final PrioritisedExecutor.PrioritisedTask task = this.scheduler.loadExecutor.createTask(new AsyncChunkSerializeTask(this.world, chunk, asyncSaveData, this)); -+ chunk.tryMarkSaved(); - -- this.chunkDataUnload.task().setTask(task); -+ final CallbackCompletable completable = new CallbackCompletable<>(); - -- chunk.setUnsaved(false); -+ final Runnable run = () -> { -+ final CompoundTag data = chunkData.write(); - -- task.queue(); -+ completable.complete(data); - -- return true; -- } catch (final Throwable thr) { -- LOGGER.error("Failed to prepare async chunk data (" + this.chunkX + "," + this.chunkZ + ") in world '" + WorldUtil.getWorldName(this.world) + "', falling back to synchronous save", thr); -- failedAsyncPrepare = true; -- // fall through to synchronous save -+ if (unloading) { -+ NewChunkHolder.this.completeAsyncUnloadDataSave(MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, data); - } -- } -- -- final CompoundTag save = ChunkSerializer.write(this.world, chunk); -+ }; - -+ final PrioritisedExecutor.PrioritisedTask task; - if (unloading) { -- completing = true; -- this.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, save); -- if (failedAsyncPrepare) { -- LOGGER.info("Successfully serialized chunk data (" + this.chunkX + "," + this.chunkZ + ") in world '" + WorldUtil.getWorldName(this.world) + "' synchronously"); -- } -+ this.chunkDataUnload.toRun().setRunnable(run); -+ task = this.chunkDataUnload.task(); - } else { -- RegionFileIOThread.scheduleSave(this.world, this.chunkX, this.chunkZ, save, RegionFileIOThread.RegionFileType.CHUNK_DATA); -+ task = this.scheduler.saveExecutor.createTask(run); - } -- chunk.setUnsaved(false); -+ -+ task.queue(); -+ -+ MoonriseRegionFileIO.scheduleSave( -+ this.world, this.chunkX, this.chunkZ, completable, task, MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, Priority.NORMAL -+ ); - } catch (final Throwable thr) { - LOGGER.error("Failed to save chunk data (" + this.chunkX + "," + this.chunkZ + ") in world '" + WorldUtil.getWorldName(this.world) + "'", thr); -- if (unloading && !completing) { -- this.completeAsyncUnloadDataSave(RegionFileIOThread.RegionFileType.CHUNK_DATA, null); -- } - } - - return true; -@@ -1834,7 +1797,7 @@ public final class NewChunkHolder { - return false; - } - try { -- mergeFrom = RegionFileIOThread.loadData(this.world, this.chunkX, this.chunkZ, RegionFileIOThread.RegionFileType.ENTITY_DATA, PrioritisedExecutor.Priority.BLOCKING); -+ mergeFrom = MoonriseRegionFileIO.loadData(this.world, this.chunkX, this.chunkZ, MoonriseRegionFileIO.RegionFileType.ENTITY_DATA, Priority.BLOCKING); - } catch (final Exception ex) { - LOGGER.error("Cannot merge transient entities for chunk (" + this.chunkX + "," + this.chunkZ + ") in world '" + WorldUtil.getWorldName(this.world) + "', data on disk will be replaced", ex); - } -@@ -1853,7 +1816,7 @@ public final class NewChunkHolder { - return false; - } - -- RegionFileIOThread.scheduleSave(this.world, this.chunkX, this.chunkZ, save, RegionFileIOThread.RegionFileType.ENTITY_DATA); -+ MoonriseRegionFileIO.scheduleSave(this.world, this.chunkX, this.chunkZ, save, MoonriseRegionFileIO.RegionFileType.ENTITY_DATA); - this.lastEntitySaveNull = save == null; - if (unloading) { - this.lastEntityUnload = save; -@@ -1877,7 +1840,7 @@ public final class NewChunkHolder { - return false; - } - -- RegionFileIOThread.scheduleSave(this.world, this.chunkX, this.chunkZ, save, RegionFileIOThread.RegionFileType.POI_DATA); -+ MoonriseRegionFileIO.scheduleSave(this.world, this.chunkX, this.chunkZ, save, MoonriseRegionFileIO.RegionFileType.POI_DATA); - this.lastPoiSaveNull = save == null; - if (unloading) { - this.poiDataUnload.completable().complete(save); -@@ -1924,7 +1887,7 @@ public final class NewChunkHolder { - return element == null ? JsonNull.INSTANCE : new JsonPrimitive(element.toString()); - } - -- private static JsonObject serializeCompletable(final Completable completable) { -+ private static JsonObject serializeCompletable(final CallbackCompletable completable) { - final JsonObject ret = new JsonObject(); - - if (completable == null) { -@@ -2019,13 +1982,13 @@ public final class NewChunkHolder { - ret.add("poi_unload_completable", serializeCompletable(poiDataUnload == null ? null : poiDataUnload.completable())); - ret.add("chunk_unload_completable", serializeCompletable(chunkDataUnload == null ? null : chunkDataUnload.completable())); - -- final DelayedPrioritisedTask unloadTask = chunkDataUnload == null ? null : chunkDataUnload.task(); -+ final PrioritisedExecutor.PrioritisedTask unloadTask = chunkDataUnload == null ? null : chunkDataUnload.task(); - if (unloadTask == null) { - ret.addProperty("unload_task_priority", "null"); -- ret.addProperty("unload_task_priority_raw", "null"); -+ ret.addProperty("unload_task_suborder", Long.valueOf(0L)); - } else { - ret.addProperty("unload_task_priority", Objects.toString(unloadTask.getPriority())); -- ret.addProperty("unload_task_priority_raw", Integer.valueOf(unloadTask.getPriorityInternal())); -+ ret.addProperty("unload_task_suborder", Long.valueOf(unloadTask.getSubOrder())); - } - - ret.addProperty("killed", Boolean.valueOf(this.unloaded)); -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/PriorityHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/PriorityHolder.java -index 261e09454f49d04eb159c984ec695d7c7aa6a3a8..6b468c621b74449a6218391f6477cf63cfc98c7c 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/PriorityHolder.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/PriorityHolder.java -@@ -1,7 +1,7 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; - import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.Priority; - import java.lang.invoke.VarHandle; - - public abstract class PriorityHolder { -@@ -28,8 +28,8 @@ public abstract class PriorityHolder { - PRIORITY_HANDLE.set((PriorityHolder)this, (int)val); - } - -- protected PriorityHolder(final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ protected PriorityHolder(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - this.setPriorityPlain(priority.priority); -@@ -69,7 +69,7 @@ public abstract class PriorityHolder { - return; - } - -- this.scheduleTask(PrioritisedExecutor.Priority.getPriority(priority)); -+ this.scheduleTask(Priority.getPriority(priority)); - - int failures = 0; - for (;;) { -@@ -86,7 +86,7 @@ public abstract class PriorityHolder { - return; - } - -- this.setPriorityScheduled(PrioritisedExecutor.Priority.getPriority(priority)); -+ this.setPriorityScheduled(Priority.getPriority(priority)); - - ++failures; - for (int i = 0; i < failures; ++i) { -@@ -95,19 +95,19 @@ public abstract class PriorityHolder { - } - } - -- public final PrioritisedExecutor.Priority getPriority() { -+ public final Priority getPriority() { - final int ret = this.getPriorityVolatile(); - if ((ret & PRIORITY_EXECUTED) != 0) { -- return PrioritisedExecutor.Priority.COMPLETING; -+ return Priority.COMPLETING; - } - if ((ret & PRIORITY_SCHEDULED) != 0) { - return this.getScheduledPriority(); - } -- return PrioritisedExecutor.Priority.getPriority(ret); -+ return Priority.getPriority(ret); - } - -- public final void lowerPriority(final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ public final void lowerPriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - -@@ -139,8 +139,8 @@ public abstract class PriorityHolder { - } - } - -- public final void setPriority(final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ public final void setPriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - -@@ -168,8 +168,8 @@ public abstract class PriorityHolder { - } - } - -- public final void raisePriority(final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ public final void raisePriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - -@@ -203,13 +203,13 @@ public abstract class PriorityHolder { - - protected abstract void cancelScheduled(); - -- protected abstract PrioritisedExecutor.Priority getScheduledPriority(); -+ protected abstract Priority getScheduledPriority(); - -- protected abstract void scheduleTask(final PrioritisedExecutor.Priority priority); -+ protected abstract void scheduleTask(final Priority priority); - -- protected abstract void lowerPriorityScheduled(final PrioritisedExecutor.Priority priority); -+ protected abstract void lowerPriorityScheduled(final Priority priority); - -- protected abstract void setPriorityScheduled(final PrioritisedExecutor.Priority priority); -+ protected abstract void setPriorityScheduled(final Priority priority); - -- protected abstract void raisePriorityScheduled(final PrioritisedExecutor.Priority priority); -+ protected abstract void raisePriorityScheduled(final Priority priority); - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/executor/RadiusAwarePrioritisedExecutor.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/executor/RadiusAwarePrioritisedExecutor.java -index e0b26ccb63596748b80fc6a5e47e373ba811ba8b..5f4b99d8c5453f8ad2e600a57ea4e7dafa2d45f8 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/executor/RadiusAwarePrioritisedExecutor.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/executor/RadiusAwarePrioritisedExecutor.java -@@ -1,10 +1,10 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.executor; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.util.Priority; - import ca.spottedleaf.moonrise.common.util.CoordinateUtils; - import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; - import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; -- - import java.util.ArrayList; - import java.util.Comparator; - import java.util.List; -@@ -16,15 +16,36 @@ public class RadiusAwarePrioritisedExecutor { - return Long.compare(t1.id, t2.id); - }; - -- private final DependencyTree[] queues = new DependencyTree[PrioritisedExecutor.Priority.TOTAL_SCHEDULABLE_PRIORITIES]; -+ private final PrioritisedExecutor executor; -+ private final DependencyTree[] queues = new DependencyTree[Priority.TOTAL_SCHEDULABLE_PRIORITIES]; - private static final int NO_TASKS_QUEUED = -1; - private int selectedQueue = NO_TASKS_QUEUED; - private boolean canQueueTasks = true; - - public RadiusAwarePrioritisedExecutor(final PrioritisedExecutor executor, final int maxToSchedule) { -+ this.executor = executor; -+ - for (int i = 0; i < this.queues.length; ++i) { -- this.queues[i] = new DependencyTree(this, executor, maxToSchedule, i); -+ this.queues[i] = new DependencyTree(this, executor, maxToSchedule); -+ } -+ } -+ -+ public void setMaxToSchedule(final int maxToSchedule) { -+ final List tasks; -+ -+ synchronized (this) { -+ for (final DependencyTree dependencyTree : this.queues) { -+ dependencyTree.maxToSchedule = maxToSchedule; -+ } -+ -+ if (this.selectedQueue == NO_TASKS_QUEUED || !this.canQueueTasks) { -+ return; -+ } -+ -+ tasks = this.queues[this.selectedQueue].tryPushTasks(); - } -+ -+ scheduleTasks(tasks); - } - - private boolean canQueueTasks() { -@@ -56,7 +77,7 @@ public class RadiusAwarePrioritisedExecutor { - return null; - } - -- private List queue(final Task task, final PrioritisedExecutor.Priority priority) { -+ private List queue(final Task task, final Priority priority) { - final int priorityId = priority.priority; - final DependencyTree queue = this.queues[priorityId]; - -@@ -79,7 +100,7 @@ public class RadiusAwarePrioritisedExecutor { - return null; - } - -- if (PrioritisedExecutor.Priority.isHigherPriority(priorityId, this.selectedQueue)) { -+ if (Priority.isHigherPriority(priorityId, this.selectedQueue)) { - // prevent the lower priority tree from queueing more tasks - this.canQueueTasks = false; - return null; -@@ -90,7 +111,7 @@ public class RadiusAwarePrioritisedExecutor { - } - - public PrioritisedExecutor.PrioritisedTask createTask(final int chunkX, final int chunkZ, final int radius, -- final Runnable run, final PrioritisedExecutor.Priority priority) { -+ final Runnable run, final Priority priority) { - if (radius < 0) { - throw new IllegalArgumentException("Radius must be > 0: " + radius); - } -@@ -99,11 +120,11 @@ public class RadiusAwarePrioritisedExecutor { - - public PrioritisedExecutor.PrioritisedTask createTask(final int chunkX, final int chunkZ, final int radius, - final Runnable run) { -- return this.createTask(chunkX, chunkZ, radius, run, PrioritisedExecutor.Priority.NORMAL); -+ return this.createTask(chunkX, chunkZ, radius, run, Priority.NORMAL); - } - - public PrioritisedExecutor.PrioritisedTask queueTask(final int chunkX, final int chunkZ, final int radius, -- final Runnable run, final PrioritisedExecutor.Priority priority) { -+ final Runnable run, final Priority priority) { - final PrioritisedExecutor.PrioritisedTask ret = this.createTask(chunkX, chunkZ, radius, run, priority); - - ret.queue(); -@@ -120,15 +141,15 @@ public class RadiusAwarePrioritisedExecutor { - return ret; - } - -- public PrioritisedExecutor.PrioritisedTask createInfiniteRadiusTask(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ public PrioritisedExecutor.PrioritisedTask createInfiniteRadiusTask(final Runnable run, final Priority priority) { - return new Task(this, 0, 0, -1, run, priority); - } - - public PrioritisedExecutor.PrioritisedTask createInfiniteRadiusTask(final Runnable run) { -- return this.createInfiniteRadiusTask(run, PrioritisedExecutor.Priority.NORMAL); -+ return this.createInfiniteRadiusTask(run, Priority.NORMAL); - } - -- public PrioritisedExecutor.PrioritisedTask queueInfiniteRadiusTask(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ public PrioritisedExecutor.PrioritisedTask queueInfiniteRadiusTask(final Runnable run, final Priority priority) { - final PrioritisedExecutor.PrioritisedTask ret = this.createInfiniteRadiusTask(run, priority); - - ret.queue(); -@@ -137,20 +158,27 @@ public class RadiusAwarePrioritisedExecutor { - } - - public PrioritisedExecutor.PrioritisedTask queueInfiniteRadiusTask(final Runnable run) { -- final PrioritisedExecutor.PrioritisedTask ret = this.createInfiniteRadiusTask(run, PrioritisedExecutor.Priority.NORMAL); -+ final PrioritisedExecutor.PrioritisedTask ret = this.createInfiniteRadiusTask(run, Priority.NORMAL); - - ret.queue(); - - return ret; - } - -+ private static void scheduleTasks(final List toSchedule) { -+ if (toSchedule != null) { -+ for (int i = 0, len = toSchedule.size(); i < len; ++i) { -+ toSchedule.get(i).queue(); -+ } -+ } -+ } -+ - // all accesses must be synchronised by the radius aware object - private static final class DependencyTree { - - private final RadiusAwarePrioritisedExecutor scheduler; - private final PrioritisedExecutor executor; -- private final int maxToSchedule; -- private final int treeIndex; -+ private int maxToSchedule; - - private int currentlyExecuting; - private long idGenerator; -@@ -163,11 +191,10 @@ public class RadiusAwarePrioritisedExecutor { - private final Long2ReferenceOpenHashMap nodeByPosition = new Long2ReferenceOpenHashMap<>(); - - public DependencyTree(final RadiusAwarePrioritisedExecutor scheduler, final PrioritisedExecutor executor, -- final int maxToSchedule, final int treeIndex) { -+ final int maxToSchedule) { - this.scheduler = scheduler; - this.executor = executor; - this.maxToSchedule = maxToSchedule; -- this.treeIndex = treeIndex; - } - - public boolean hasWaitingTasks() { -@@ -412,13 +439,13 @@ public class RadiusAwarePrioritisedExecutor { - private final int chunkZ; - private final int radius; - private Runnable run; -- private PrioritisedExecutor.Priority priority; -+ private Priority priority; - - private DependencyNode dependencyNode; - private PrioritisedExecutor.PrioritisedTask queuedTask; - - private Task(final RadiusAwarePrioritisedExecutor scheduler, final int chunkX, final int chunkZ, final int radius, -- final Runnable run, final PrioritisedExecutor.Priority priority) { -+ final Runnable run, final Priority priority) { - this.scheduler = scheduler; - this.chunkX = chunkX; - this.chunkZ = chunkZ; -@@ -441,14 +468,6 @@ public class RadiusAwarePrioritisedExecutor { - run.run(); - } - -- private static void scheduleTasks(final List toSchedule) { -- if (toSchedule != null) { -- for (int i = 0, len = toSchedule.size(); i < len; ++i) { -- toSchedule.get(i).queue(); -- } -- } -- } -- - private void returnNode() { - final List toSchedule; - synchronized (this.scheduler) { -@@ -460,6 +479,11 @@ public class RadiusAwarePrioritisedExecutor { - scheduleTasks(toSchedule); - } - -+ @Override -+ public PrioritisedExecutor getExecutor() { -+ return this.scheduler.executor; -+ } -+ - @Override - public void run() { - final Runnable run = this.run; -@@ -475,7 +499,7 @@ public class RadiusAwarePrioritisedExecutor { - public boolean queue() { - final List toSchedule; - synchronized (this.scheduler) { -- if (this.queuedTask != null || this.dependencyNode != null || this.priority == PrioritisedExecutor.Priority.COMPLETING) { -+ if (this.queuedTask != null || this.dependencyNode != null || this.priority == Priority.COMPLETING) { - return false; - } - -@@ -486,16 +510,23 @@ public class RadiusAwarePrioritisedExecutor { - return true; - } - -+ @Override -+ public boolean isQueued() { -+ synchronized (this.scheduler) { -+ return (this.queuedTask != null || this.dependencyNode != null) && this.priority != Priority.COMPLETING; -+ } -+ } -+ - @Override - public boolean cancel() { - final PrioritisedExecutor.PrioritisedTask task; - synchronized (this.scheduler) { - if ((task = this.queuedTask) == null) { -- if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { -+ if (this.priority == Priority.COMPLETING) { - return false; - } - -- this.priority = PrioritisedExecutor.Priority.COMPLETING; -+ this.priority = Priority.COMPLETING; - if (this.dependencyNode != null) { - this.dependencyNode.purged = true; - this.dependencyNode = null; -@@ -519,11 +550,11 @@ public class RadiusAwarePrioritisedExecutor { - final PrioritisedExecutor.PrioritisedTask task; - synchronized (this.scheduler) { - if ((task = this.queuedTask) == null) { -- if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { -+ if (this.priority == Priority.COMPLETING) { - return false; - } - -- this.priority = PrioritisedExecutor.Priority.COMPLETING; -+ this.priority = Priority.COMPLETING; - if (this.dependencyNode != null) { - this.dependencyNode.purged = true; - this.dependencyNode = null; -@@ -543,7 +574,7 @@ public class RadiusAwarePrioritisedExecutor { - } - - @Override -- public PrioritisedExecutor.Priority getPriority() { -+ public Priority getPriority() { - final PrioritisedExecutor.PrioritisedTask task; - synchronized (this.scheduler) { - if ((task = this.queuedTask) == null) { -@@ -555,8 +586,8 @@ public class RadiusAwarePrioritisedExecutor { - } - - @Override -- public boolean setPriority(final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ public boolean setPriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - -@@ -564,7 +595,7 @@ public class RadiusAwarePrioritisedExecutor { - List toSchedule = null; - synchronized (this.scheduler) { - if ((task = this.queuedTask) == null) { -- if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { -+ if (this.priority == Priority.COMPLETING) { - return false; - } - -@@ -592,8 +623,8 @@ public class RadiusAwarePrioritisedExecutor { - } - - @Override -- public boolean raisePriority(final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ public boolean raisePriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - -@@ -601,7 +632,7 @@ public class RadiusAwarePrioritisedExecutor { - List toSchedule = null; - synchronized (this.scheduler) { - if ((task = this.queuedTask) == null) { -- if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { -+ if (this.priority == Priority.COMPLETING) { - return false; - } - -@@ -629,8 +660,8 @@ public class RadiusAwarePrioritisedExecutor { - } - - @Override -- public boolean lowerPriority(final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ public boolean lowerPriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - -@@ -638,7 +669,7 @@ public class RadiusAwarePrioritisedExecutor { - List toSchedule = null; - synchronized (this.scheduler) { - if ((task = this.queuedTask) == null) { -- if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { -+ if (this.priority == Priority.COMPLETING) { - return false; - } - -@@ -664,5 +695,35 @@ public class RadiusAwarePrioritisedExecutor { - - return true; - } -+ -+ @Override -+ public long getSubOrder() { -+ // TODO implement -+ return 0; -+ } -+ -+ @Override -+ public boolean setSubOrder(final long subOrder) { -+ // TODO implement -+ return false; -+ } -+ -+ @Override -+ public boolean raiseSubOrder(final long subOrder) { -+ // TODO implement -+ return false; -+ } -+ -+ @Override -+ public boolean lowerSubOrder(final long subOrder) { -+ // TODO implement -+ return false; -+ } -+ -+ @Override -+ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder) { -+ // TODO implement -+ return this.setPriority(priority); -+ } - } --} -\ No newline at end of file -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java -index fbdf721e8b4cfe6cef4ee60c53c680cbfc858d88..6ab353b0d2465c3680bb3c8d0852ba0f65c00fd2 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java -@@ -1,7 +1,9 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; - import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.Priority; -+import ca.spottedleaf.moonrise.common.PlatformHooks; - import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; - import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk; - import ca.spottedleaf.moonrise.patches.chunk_system.level.poi.ChunkSystemPoiManager; -@@ -29,7 +31,7 @@ public final class ChunkFullTask extends ChunkProgressionTask implements Runnabl - private final PrioritisedExecutor.PrioritisedTask convertToFullTask; - - public ChunkFullTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, final int chunkZ, -- final NewChunkHolder chunkHolder, final ChunkAccess fromChunk, final PrioritisedExecutor.Priority priority) { -+ final NewChunkHolder chunkHolder, final ChunkAccess fromChunk, final Priority priority) { - super(scheduler, world, chunkX, chunkZ); - this.chunkHolder = chunkHolder; - this.fromChunk = fromChunk; -@@ -43,6 +45,8 @@ public final class ChunkFullTask extends ChunkProgressionTask implements Runnabl - - @Override - public void run() { -+ final PlatformHooks platformHooks = PlatformHooks.get(); -+ - // See Vanilla ChunkPyramid#LOADING_PYRAMID.FULL for what this function should be doing - final LevelChunk chunk; - try { -@@ -61,7 +65,7 @@ public final class ChunkFullTask extends ChunkProgressionTask implements Runnabl - final ServerLevel world = this.world; - final ProtoChunk protoChunk = (ProtoChunk)this.fromChunk; - chunk = new LevelChunk(this.world, protoChunk, (final LevelChunk unused) -> { -- ChunkStatusTasks.postLoadProtoChunk(world, protoChunk.getEntities(), protoChunk.getPos()); // Paper - pass chunk pos -+ PlatformHooks.get().postLoadProtoChunk(world, protoChunk); - }); - this.chunkHolder.replaceProtoChunk(new ImposterProtoChunk(chunk, false)); - } -@@ -71,16 +75,21 @@ public final class ChunkFullTask extends ChunkProgressionTask implements Runnabl - final NewChunkHolder chunkHolder = this.chunkHolder; - - chunk.setFullStatus(chunkHolder::getChunkStatus); -- chunk.runPostLoad(); -- // Unlike Vanilla, we load the entity chunk here, as we load the NBT in empty status (unlike Vanilla) -- // This brings entity addition back in line with older versions of the game -- // Since we load the NBT in the empty status, this will never block for I/O -- ((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager.getOrCreateEntityChunk(this.chunkX, this.chunkZ, false); -- -- // we don't need the entitiesInLevel, not sure why it's there -- chunk.setLoaded(true); -- chunk.registerAllBlockEntitiesAfterLevelLoad(); -- chunk.registerTickContainerInLevel(this.world); -+ try { -+ platformHooks.setCurrentlyLoading(this.chunkHolder.vanillaChunkHolder, chunk); -+ chunk.runPostLoad(); -+ // Unlike Vanilla, we load the entity chunk here, as we load the NBT in empty status (unlike Vanilla) -+ // This brings entity addition back in line with older versions of the game -+ // Since we load the NBT in the empty status, this will never block for I/O -+ ((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager.getOrCreateEntityChunk(this.chunkX, this.chunkZ, false); -+ chunk.setLoaded(true); -+ chunk.registerAllBlockEntitiesAfterLevelLoad(); -+ chunk.registerTickContainerInLevel(this.world); -+ chunk.setUnsavedListener(this.world.getChunkSource().chunkMap.worldGenContext.unsavedListener()); -+ platformHooks.chunkFullStatusComplete(chunk, (ProtoChunk)this.fromChunk); -+ } finally { -+ platformHooks.setCurrentlyLoading(this.chunkHolder.vanillaChunkHolder, null); -+ } - } catch (final Throwable throwable) { - this.complete(null, throwable); - return; -@@ -112,29 +121,29 @@ public final class ChunkFullTask extends ChunkProgressionTask implements Runnabl - } - - @Override -- public PrioritisedExecutor.Priority getPriority() { -+ public Priority getPriority() { - return this.convertToFullTask.getPriority(); - } - - @Override -- public void lowerPriority(final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ public void lowerPriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - this.convertToFullTask.lowerPriority(priority); - } - - @Override -- public void setPriority(final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ public void setPriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - this.convertToFullTask.setPriority(priority); - } - - @Override -- public void raisePriority(final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ public void raisePriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - this.convertToFullTask.raisePriority(priority); -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLightTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLightTask.java -index 7c2e6752228fac175c4aa97fa3d817b8a938922f..4538ccfaea83d217ed85eaf16e82393c7f286489 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLightTask.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLightTask.java -@@ -1,6 +1,6 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.util.Priority; - import ca.spottedleaf.moonrise.common.util.WorldUtil; - import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; - import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.PriorityHolder; -@@ -25,9 +25,9 @@ public final class ChunkLightTask extends ChunkProgressionTask { - private final LightTaskPriorityHolder priorityHolder; - - public ChunkLightTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, final int chunkZ, -- final ChunkAccess chunk, final PrioritisedExecutor.Priority priority) { -+ final ChunkAccess chunk, final Priority priority) { - super(scheduler, world, chunkX, chunkZ); -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - this.priorityHolder = new LightTaskPriorityHolder(priority, this); -@@ -55,22 +55,22 @@ public final class ChunkLightTask extends ChunkProgressionTask { - } - - @Override -- public PrioritisedExecutor.Priority getPriority() { -+ public Priority getPriority() { - return this.priorityHolder.getPriority(); - } - - @Override -- public void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ public void lowerPriority(final Priority priority) { - this.priorityHolder.raisePriority(priority); - } - - @Override -- public void setPriority(final PrioritisedExecutor.Priority priority) { -+ public void setPriority(final Priority priority) { - this.priorityHolder.setPriority(priority); - } - - @Override -- public void raisePriority(final PrioritisedExecutor.Priority priority) { -+ public void raisePriority(final Priority priority) { - this.priorityHolder.raisePriority(priority); - } - -@@ -78,7 +78,7 @@ public final class ChunkLightTask extends ChunkProgressionTask { - - private final ChunkLightTask task; - -- private LightTaskPriorityHolder(final PrioritisedExecutor.Priority priority, final ChunkLightTask task) { -+ private LightTaskPriorityHolder(final Priority priority, final ChunkLightTask task) { - super(priority); - this.task = task; - } -@@ -90,13 +90,13 @@ public final class ChunkLightTask extends ChunkProgressionTask { - } - - @Override -- protected PrioritisedExecutor.Priority getScheduledPriority() { -+ protected Priority getScheduledPriority() { - final ChunkLightTask task = this.task; - return ((StarLightLightingProvider)task.world.getChunkSource().getLightEngine()).starlight$getLightEngine().getServerLightQueue().getPriority(task.chunkX, task.chunkZ); - } - - @Override -- protected void scheduleTask(final PrioritisedExecutor.Priority priority) { -+ protected void scheduleTask(final Priority priority) { - final ChunkLightTask task = this.task; - final StarLightInterface starLightInterface = ((StarLightLightingProvider)task.world.getChunkSource().getLightEngine()).starlight$getLightEngine(); - final StarLightInterface.ServerLightQueue lightQueue = starLightInterface.getServerLightQueue(); -@@ -105,7 +105,7 @@ public final class ChunkLightTask extends ChunkProgressionTask { - } - - @Override -- protected void lowerPriorityScheduled(final PrioritisedExecutor.Priority priority) { -+ protected void lowerPriorityScheduled(final Priority priority) { - final ChunkLightTask task = this.task; - final StarLightInterface starLightInterface = ((StarLightLightingProvider)task.world.getChunkSource().getLightEngine()).starlight$getLightEngine(); - final StarLightInterface.ServerLightQueue lightQueue = starLightInterface.getServerLightQueue(); -@@ -113,7 +113,7 @@ public final class ChunkLightTask extends ChunkProgressionTask { - } - - @Override -- protected void setPriorityScheduled(final PrioritisedExecutor.Priority priority) { -+ protected void setPriorityScheduled(final Priority priority) { - final ChunkLightTask task = this.task; - final StarLightInterface starLightInterface = ((StarLightLightingProvider)task.world.getChunkSource().getLightEngine()).starlight$getLightEngine(); - final StarLightInterface.ServerLightQueue lightQueue = starLightInterface.getServerLightQueue(); -@@ -121,7 +121,7 @@ public final class ChunkLightTask extends ChunkProgressionTask { - } - - @Override -- protected void raisePriorityScheduled(final PrioritisedExecutor.Priority priority) { -+ protected void raisePriorityScheduled(final Priority priority) { - final ChunkLightTask task = this.task; - final StarLightInterface starLightInterface = ((StarLightLightingProvider)task.world.getChunkSource().getLightEngine()).starlight$getLightEngine(); - final StarLightInterface.ServerLightQueue lightQueue = starLightInterface.getServerLightQueue(); -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java -index 1ab93f219246d0b4dcdfd0f685f47c13091425f8..e0a88615a8b6d58191f29b1ff1a26427f0a4c1a6 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java -@@ -1,12 +1,13 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; - - import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; - import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; - import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.Priority; -+import ca.spottedleaf.moonrise.common.PlatformHooks; - import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystemConverters; --import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystemFeatures; --import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; - import ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk; - import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; - import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder; -@@ -18,7 +19,7 @@ import net.minecraft.world.level.chunk.ChunkAccess; - import net.minecraft.world.level.chunk.ProtoChunk; - import net.minecraft.world.level.chunk.UpgradeData; - import net.minecraft.world.level.chunk.status.ChunkStatus; --import net.minecraft.world.level.chunk.storage.ChunkSerializer; -+import net.minecraft.world.level.chunk.storage.SerializableChunkData; - import net.minecraft.world.level.levelgen.blending.BlendingData; - import org.slf4j.Logger; - import org.slf4j.LoggerFactory; -@@ -41,7 +42,7 @@ public final class ChunkLoadTask extends ChunkProgressionTask { - private final AtomicInteger taskCountToComplete = new AtomicInteger(3); // one for poi, one for entity, and one for chunk data - - public ChunkLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, final int chunkZ, -- final NewChunkHolder chunkHolder, final PrioritisedExecutor.Priority priority) { -+ final NewChunkHolder chunkHolder, final Priority priority) { - super(scheduler, world, chunkX, chunkZ); - this.chunkHolder = chunkHolder; - this.loadTask = new ChunkDataLoadTask(scheduler, world, chunkX, chunkZ, priority); -@@ -170,12 +171,12 @@ public final class ChunkLoadTask extends ChunkProgressionTask { - } - - @Override -- public PrioritisedExecutor.Priority getPriority() { -+ public Priority getPriority() { - return this.loadTask.getPriority(); - } - - @Override -- public void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ public void lowerPriority(final Priority priority) { - final EntityDataLoadTask entityLoad = this.chunkHolder.getEntityDataLoadTask(); - if (entityLoad != null) { - entityLoad.lowerPriority(priority); -@@ -191,7 +192,7 @@ public final class ChunkLoadTask extends ChunkProgressionTask { - } - - @Override -- public void setPriority(final PrioritisedExecutor.Priority priority) { -+ public void setPriority(final Priority priority) { - final EntityDataLoadTask entityLoad = this.chunkHolder.getEntityDataLoadTask(); - if (entityLoad != null) { - entityLoad.setPriority(priority); -@@ -207,7 +208,7 @@ public final class ChunkLoadTask extends ChunkProgressionTask { - } - - @Override -- public void raisePriority(final PrioritisedExecutor.Priority priority) { -+ public void raisePriority(final Priority priority) { - final EntityDataLoadTask entityLoad = this.chunkHolder.getEntityDataLoadTask(); - if (entityLoad != null) { - entityLoad.raisePriority(priority); -@@ -231,8 +232,8 @@ public final class ChunkLoadTask extends ChunkProgressionTask { - protected static final VarHandle COMPLETED_HANDLE = ConcurrentUtil.getVarHandle(CallbackDataLoadTask.class, "completed", boolean.class); - - protected CallbackDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -- final int chunkZ, final RegionFileIOThread.RegionFileType type, -- final PrioritisedExecutor.Priority priority) { -+ final int chunkZ, final MoonriseRegionFileIO.RegionFileType type, -+ final Priority priority) { - super(scheduler, world, chunkX, chunkZ, type, priority); - } - -@@ -272,10 +273,13 @@ public final class ChunkLoadTask extends ChunkProgressionTask { - } - } - -- private static final class ChunkDataLoadTask extends CallbackDataLoadTask { -+ -+ private static record ReadChunk(ProtoChunk protoChunk, SerializableChunkData chunkData) {} -+ -+ private static final class ChunkDataLoadTask extends CallbackDataLoadTask { - private ChunkDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -- final int chunkZ, final PrioritisedExecutor.Priority priority) { -- super(scheduler, world, chunkX, chunkZ, RegionFileIOThread.RegionFileType.CHUNK_DATA, priority); -+ final int chunkZ, final Priority priority) { -+ super(scheduler, world, chunkX, chunkZ, MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, priority); - } - - @Override -@@ -289,40 +293,42 @@ public final class ChunkLoadTask extends ChunkProgressionTask { - } - - @Override -- protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final Priority priority) { - return this.scheduler.loadExecutor.createTask(run, priority); - } - - @Override -- protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final Priority priority) { - return this.scheduler.createChunkTask(this.chunkX, this.chunkZ, run, priority); - } - - @Override -- protected TaskResult completeOnMainOffMain(final CompoundTag data, final Throwable throwable) { -+ protected TaskResult completeOnMainOffMain(final ReadChunk data, final Throwable throwable) { - if (throwable != null) { - return new TaskResult<>(null, throwable); - } -- if (data == null) { -+ -+ if (data == null || data.protoChunk() == null) { - return new TaskResult<>(this.getEmptyChunk(), null); - } - -- if (ChunkSystemFeatures.supportsAsyncChunkDeserialization()) { -- return this.deserialize(data); -+ if (!PlatformHooks.get().hasMainChunkLoadHook()) { -+ return new TaskResult<>(data.protoChunk(), null); - } -- // need to deserialize on main thread -+ -+ // need to invoke the callback for loading on the main thread - return null; - } - - private ProtoChunk getEmptyChunk() { - return new ProtoChunk( - new ChunkPos(this.chunkX, this.chunkZ), UpgradeData.EMPTY, this.world, -- this.world.registryAccess().registryOrThrow(Registries.BIOME), (BlendingData)null -+ this.world.registryAccess().lookupOrThrow(Registries.BIOME), (BlendingData)null - ); - } - - @Override -- protected TaskResult runOffMain(final CompoundTag data, final Throwable throwable) { -+ protected TaskResult runOffMain(final CompoundTag data, final Throwable throwable) { - if (throwable != null) { - LOGGER.error("Failed to load chunk data for task: " + this.toString() + ", chunk data will be lost", throwable); - return new TaskResult<>(null, null); -@@ -334,42 +340,43 @@ public final class ChunkLoadTask extends ChunkProgressionTask { - - try { - // run converters -- final CompoundTag converted = this.world.getChunkSource().chunkMap.upgradeChunkTag(data, new net.minecraft.world.level.ChunkPos(this.chunkX, this.chunkZ)); -+ final CompoundTag converted = this.world.getChunkSource().chunkMap.upgradeChunkTag(data); - -- return new TaskResult<>(converted, null); -- } catch (final Throwable thr2) { -- LOGGER.error("Failed to parse chunk data for task: " + this.toString() + ", chunk data will be lost", thr2); -- return new TaskResult<>(null, null); -- } -- } -+ // unpack the data -+ final SerializableChunkData chunkData = SerializableChunkData.parse( -+ this.world, this.world.registryAccess(), converted -+ ); - -- private TaskResult deserialize(final CompoundTag data) { -- try { -- final ChunkAccess deserialized = ChunkSerializer.read( -- this.world, this.world.getPoiManager(), this.world.getChunkSource().chunkMap.storageInfo(), new ChunkPos(this.chunkX, this.chunkZ), data -+ if (chunkData == null) { -+ LOGGER.error("Deserialized chunk for task: " + this.toString() + " produced null, chunk data will be lost?"); -+ } -+ -+ // read into ProtoChunk -+ final ProtoChunk chunk = chunkData == null ? null : chunkData.read( -+ this.world, this.world.getPoiManager(), this.world.getChunkSource().chunkMap.storageInfo(), -+ new ChunkPos(this.chunkX, this.chunkZ) - ); -- return new TaskResult<>(deserialized, null); -+ -+ return new TaskResult<>(new ReadChunk(chunk, chunkData), null); - } catch (final Throwable thr2) { - LOGGER.error("Failed to parse chunk data for task: " + this.toString() + ", chunk data will be lost", thr2); -- return new TaskResult<>(this.getEmptyChunk(), null); -+ return new TaskResult<>(null, null); - } - } - - @Override -- protected TaskResult runOnMain(final CompoundTag data, final Throwable throwable) { -- // data != null && throwable == null -- if (ChunkSystemFeatures.supportsAsyncChunkDeserialization()) { -- throw new UnsupportedOperationException(); -- } -- return this.deserialize(data); -+ protected TaskResult runOnMain(final ReadChunk data, final Throwable throwable) { -+ PlatformHooks.get().mainChunkLoad(data.protoChunk(), data.chunkData()); -+ -+ return new TaskResult<>(data.protoChunk(), null); - } - } - - public static final class PoiDataLoadTask extends CallbackDataLoadTask { - - public PoiDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -- final int chunkZ, final PrioritisedExecutor.Priority priority) { -- super(scheduler, world, chunkX, chunkZ, RegionFileIOThread.RegionFileType.POI_DATA, priority); -+ final int chunkZ, final Priority priority) { -+ super(scheduler, world, chunkX, chunkZ, MoonriseRegionFileIO.RegionFileType.POI_DATA, priority); - } - - @Override -@@ -383,12 +390,12 @@ public final class ChunkLoadTask extends ChunkProgressionTask { - } - - @Override -- protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final Priority priority) { - return this.scheduler.loadExecutor.createTask(run, priority); - } - - @Override -- protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final Priority priority) { - throw new UnsupportedOperationException(); - } - -@@ -430,8 +437,8 @@ public final class ChunkLoadTask extends ChunkProgressionTask { - public static final class EntityDataLoadTask extends CallbackDataLoadTask { - - public EntityDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -- final int chunkZ, final PrioritisedExecutor.Priority priority) { -- super(scheduler, world, chunkX, chunkZ, RegionFileIOThread.RegionFileType.ENTITY_DATA, priority); -+ final int chunkZ, final Priority priority) { -+ super(scheduler, world, chunkX, chunkZ, MoonriseRegionFileIO.RegionFileType.ENTITY_DATA, priority); - } - - @Override -@@ -445,12 +452,12 @@ public final class ChunkLoadTask extends ChunkProgressionTask { - } - - @Override -- protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final Priority priority) { - return this.scheduler.loadExecutor.createTask(run, priority); - } - - @Override -- protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final Priority priority) { - throw new UnsupportedOperationException(); - } - -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkProgressionTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkProgressionTask.java -index 70e900b0f9c131900bf8b3f3ecbfbd5df5361205..002ee365aa70d8e6a6e6bd5c95988bd17db4395a 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkProgressionTask.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkProgressionTask.java -@@ -1,8 +1,8 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; - - import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; - import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.Priority; - import ca.spottedleaf.moonrise.common.util.WorldUtil; - import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; - import net.minecraft.server.level.ServerLevel; -@@ -46,15 +46,15 @@ public abstract class ChunkProgressionTask { - /* May be called multiple times */ - public abstract void cancel(); - -- public abstract PrioritisedExecutor.Priority getPriority(); -+ public abstract Priority getPriority(); - - /* Schedule lock is always held for the priority update calls */ - -- public abstract void lowerPriority(final PrioritisedExecutor.Priority priority); -+ public abstract void lowerPriority(final Priority priority); - -- public abstract void setPriority(final PrioritisedExecutor.Priority priority); -+ public abstract void setPriority(final Priority priority); - -- public abstract void raisePriority(final PrioritisedExecutor.Priority priority); -+ public abstract void raisePriority(final Priority priority); - - public final void onComplete(final BiConsumer onComplete) { - if (!this.waiters.add(onComplete)) { -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkUpgradeGenericStatusTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkUpgradeGenericStatusTask.java -index 2c17d5589f15f1155be08be670d29acbe954a8fa..25d8da4773dcee5096053e7e3788bfc224d705a7 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkUpgradeGenericStatusTask.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkUpgradeGenericStatusTask.java -@@ -1,7 +1,8 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; - import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.Priority; - import ca.spottedleaf.moonrise.common.util.WorldUtil; - import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkStatus; - import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; -@@ -36,9 +37,9 @@ public final class ChunkUpgradeGenericStatusTask extends ChunkProgressionTask im - - public ChunkUpgradeGenericStatusTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, - final int chunkZ, final ChunkAccess chunk, final StaticCache2D neighbours, -- final ChunkStatus toStatus, final PrioritisedExecutor.Priority priority) { -+ final ChunkStatus toStatus, final Priority priority) { - super(scheduler, world, chunkX, chunkZ); -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - this.fromChunk = chunk; -@@ -187,29 +188,29 @@ public final class ChunkUpgradeGenericStatusTask extends ChunkProgressionTask im - } - - @Override -- public PrioritisedExecutor.Priority getPriority() { -+ public Priority getPriority() { - return this.generateTask.getPriority(); - } - - @Override -- public void lowerPriority(final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ public void lowerPriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - this.generateTask.lowerPriority(priority); - } - - @Override -- public void setPriority(final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ public void setPriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - this.generateTask.setPriority(priority); - } - - @Override -- public void raisePriority(final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ public void raisePriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - this.generateTask.raisePriority(priority); -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/GenericDataLoadTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/GenericDataLoadTask.java -index 7a65d351b448873c6f2c145c975c92be314b876c..bdcd1879457bafcca4e76523aac0555968f37c0b 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/GenericDataLoadTask.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/GenericDataLoadTask.java -@@ -1,12 +1,13 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; - -+import ca.spottedleaf.concurrentutil.completable.CallbackCompletable; - import ca.spottedleaf.concurrentutil.completable.Completable; - import ca.spottedleaf.concurrentutil.executor.Cancellable; --import ca.spottedleaf.concurrentutil.executor.standard.DelayedPrioritisedTask; --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; - import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.Priority; - import ca.spottedleaf.moonrise.common.util.WorldUtil; --import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; -+import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; - import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; - import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; - import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder; -@@ -47,11 +48,11 @@ public abstract class GenericDataLoadTask { - protected final ServerLevel world; - protected final int chunkX; - protected final int chunkZ; -- protected final RegionFileIOThread.RegionFileType type; -+ protected final MoonriseRegionFileIO.RegionFileType type; - - public GenericDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -- final int chunkZ, final RegionFileIOThread.RegionFileType type, -- final PrioritisedExecutor.Priority priority) { -+ final int chunkZ, final MoonriseRegionFileIO.RegionFileType type, -+ final Priority priority) { - this.scheduler = scheduler; - this.world = world; - this.chunkX = chunkX; -@@ -89,9 +90,9 @@ public abstract class GenericDataLoadTask { - - protected abstract boolean hasOnMain(); - -- protected abstract PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final PrioritisedExecutor.Priority priority); -+ protected abstract PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final Priority priority); - -- protected abstract PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final PrioritisedExecutor.Priority priority); -+ protected abstract PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final Priority priority); - - protected abstract TaskResult runOffMain(final CompoundTag data, final Throwable throwable); - -@@ -108,7 +109,7 @@ public abstract class GenericDataLoadTask { - ", type: " + this.type.toString() + "}"; - } - -- public PrioritisedExecutor.Priority getPriority() { -+ public Priority getPriority() { - if (this.processOnMain != null) { - return this.processOnMain.getPriority(); - } else { -@@ -116,7 +117,7 @@ public abstract class GenericDataLoadTask { - } - } - -- public void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ public void lowerPriority(final Priority priority) { - // can't lower I/O tasks, we don't know what they affect - if (this.processOffMain != null) { - this.processOffMain.lowerPriority(priority); -@@ -126,7 +127,7 @@ public abstract class GenericDataLoadTask { - } - } - -- public void setPriority(final PrioritisedExecutor.Priority priority) { -+ public void setPriority(final Priority priority) { - // can't lower I/O tasks, we don't know what they affect - this.loadDataFromDiskTask.raisePriority(priority); - if (this.processOffMain != null) { -@@ -137,7 +138,7 @@ public abstract class GenericDataLoadTask { - } - } - -- public void raisePriority(final PrioritisedExecutor.Priority priority) { -+ public void raisePriority(final Priority priority) { - // can't lower I/O tasks, we don't know what they affect - this.loadDataFromDiskTask.raisePriority(priority); - if (this.processOffMain != null) { -@@ -382,10 +383,10 @@ public abstract class GenericDataLoadTask { - private final int chunkX; - private final int chunkZ; - -- private final RegionFileIOThread.RegionFileType type; -+ private final MoonriseRegionFileIO.RegionFileType type; - private Cancellable dataLoadTask; - private Cancellable dataUnloadCancellable; -- private DelayedPrioritisedTask dataUnloadTask; -+ private PrioritisedExecutor.PrioritisedTask dataUnloadTask; - - private final BiConsumer onComplete; - private final AtomicBoolean scheduled = new AtomicBoolean(); -@@ -393,10 +394,10 @@ public abstract class GenericDataLoadTask { - // onComplete should be caller sensitive, it may complete synchronously with schedule() - which does - // hold a priority lock. - public LoadDataFromDiskTask(final ServerLevel world, final int chunkX, final int chunkZ, -- final RegionFileIOThread.RegionFileType type, -+ final MoonriseRegionFileIO.RegionFileType type, - final BiConsumer onComplete, -- final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - this.world = world; -@@ -426,8 +427,8 @@ public abstract class GenericDataLoadTask { - return (this.getPriorityVolatile() & PRIORITY_EXECUTED) != 0; - } - -- public void lowerPriority(final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ public void lowerPriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - -@@ -439,7 +440,7 @@ public abstract class GenericDataLoadTask { - } - - if ((curr & PRIORITY_LOAD_SCHEDULED) != 0) { -- RegionFileIOThread.lowerPriority(this.world, this.chunkX, this.chunkZ, this.type, priority); -+ MoonriseRegionFileIO.lowerPriority(this.world, this.chunkX, this.chunkZ, this.type, priority); - return; - } - -@@ -467,8 +468,8 @@ public abstract class GenericDataLoadTask { - } - } - -- public void setPriority(final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ public void setPriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - -@@ -480,7 +481,7 @@ public abstract class GenericDataLoadTask { - } - - if ((curr & PRIORITY_LOAD_SCHEDULED) != 0) { -- RegionFileIOThread.setPriority(this.world, this.chunkX, this.chunkZ, this.type, priority); -+ MoonriseRegionFileIO.setPriority(this.world, this.chunkX, this.chunkZ, this.type, priority); - return; - } - -@@ -504,8 +505,8 @@ public abstract class GenericDataLoadTask { - } - } - -- public void raisePriority(final PrioritisedExecutor.Priority priority) { -- if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ public void raisePriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { - throw new IllegalArgumentException("Invalid priority " + priority); - } - -@@ -517,7 +518,7 @@ public abstract class GenericDataLoadTask { - } - - if ((curr & PRIORITY_LOAD_SCHEDULED) != 0) { -- RegionFileIOThread.raisePriority(this.world, this.chunkX, this.chunkZ, this.type, priority); -+ MoonriseRegionFileIO.raisePriority(this.world, this.chunkX, this.chunkZ, this.type, priority); - return; - } - -@@ -583,7 +584,7 @@ public abstract class GenericDataLoadTask { - } // else: cancelled - }; - -- final PrioritisedExecutor.Priority initialPriority = PrioritisedExecutor.Priority.getPriority(priority); -+ final Priority initialPriority = Priority.getPriority(priority); - boolean scheduledUnload = false; - - final NewChunkHolder holder = ((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.chunkX, this.chunkZ); -@@ -593,13 +594,13 @@ public abstract class GenericDataLoadTask { - consumer.accept(data, null); - } else { - // need to schedule task -- LoadDataFromDiskTask.this.schedule(false, consumer, PrioritisedExecutor.Priority.getPriority(LoadDataFromDiskTask.this.getPriorityVolatile() & ~PRIORITY_FLAGS)); -+ LoadDataFromDiskTask.this.schedule(false, consumer, Priority.getPriority(LoadDataFromDiskTask.this.getPriorityVolatile() & ~PRIORITY_FLAGS)); - } - }; - Cancellable unloadCancellable = null; - CompoundTag syncComplete = null; - final NewChunkHolder.UnloadTask unloadTask = holder.getUnloadTask(this.type); // can be null if no task exists -- final Completable unloadCompletable = unloadTask == null ? null : unloadTask.completable(); -+ final CallbackCompletable unloadCompletable = unloadTask == null ? null : unloadTask.completable(); - if (unloadCompletable != null) { - unloadCancellable = unloadCompletable.addAsynchronousWaiter(unloadConsumer); - if (unloadCancellable == null) { -@@ -622,7 +623,7 @@ public abstract class GenericDataLoadTask { - this.schedule(scheduledUnload, consumer, initialPriority); - } - -- private void schedule(final boolean scheduledUnload, final BiConsumer consumer, final PrioritisedExecutor.Priority initialPriority) { -+ private void schedule(final boolean scheduledUnload, final BiConsumer consumer, final Priority initialPriority) { - int priority = this.getPriorityVolatile(); - - if ((priority & PRIORITY_EXECUTED) != 0) { -@@ -631,9 +632,9 @@ public abstract class GenericDataLoadTask { - } - - if (!scheduledUnload) { -- this.dataLoadTask = RegionFileIOThread.loadDataAsync( -+ this.dataLoadTask = MoonriseRegionFileIO.loadDataAsync( - this.world, this.chunkX, this.chunkZ, this.type, consumer, -- initialPriority.isHigherPriority(PrioritisedExecutor.Priority.NORMAL), initialPriority -+ initialPriority.isHigherPriority(Priority.NORMAL), initialPriority - ); - } - -@@ -657,10 +658,10 @@ public abstract class GenericDataLoadTask { - - if (scheduledUnload) { - if (this.dataUnloadTask != null) { -- this.dataUnloadTask.setPriority(PrioritisedExecutor.Priority.getPriority(priority & ~PRIORITY_FLAGS)); -+ this.dataUnloadTask.setPriority(Priority.getPriority(priority & ~PRIORITY_FLAGS)); - } - } else { -- RegionFileIOThread.setPriority(this.world, this.chunkX, this.chunkZ, this.type, PrioritisedExecutor.Priority.getPriority(priority & ~PRIORITY_FLAGS)); -+ MoonriseRegionFileIO.setPriority(this.world, this.chunkX, this.chunkZ, this.type, Priority.getPriority(priority & ~PRIORITY_FLAGS)); - } - - ++failures; -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java -new file mode 100644 -index 0000000000000000000000000000000000000000..51c126735ace8fdde89ad97b5cab62f244212db0 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java -@@ -0,0 +1,12 @@ -+package ca.spottedleaf.moonrise.patches.chunk_system.storage; -+ -+import net.minecraft.world.level.chunk.storage.RegionFile; -+import java.io.IOException; -+ -+public interface ChunkSystemChunkBuffer { -+ public boolean moonrise$getWriteOnClose(); -+ -+ public void moonrise$setWriteOnClose(final boolean value); -+ -+ public void moonrise$write(final RegionFile regionFile) throws IOException; -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemRegionFile.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemRegionFile.java -new file mode 100644 -index 0000000000000000000000000000000000000000..3bd1b59250dbab15097a64d515999b278636795a ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemRegionFile.java -@@ -0,0 +1,12 @@ -+package ca.spottedleaf.moonrise.patches.chunk_system.storage; -+ -+import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.world.level.ChunkPos; -+import java.io.IOException; -+ -+public interface ChunkSystemRegionFile { -+ -+ public MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite(final CompoundTag data, final ChunkPos pos) throws IOException; -+ -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/ParallelSearchRadiusIteration.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/ParallelSearchRadiusIteration.java -index 3a9a564edfdb99e006e4816cb8821bd1e9ecff43..93fd23027c00cef76562098306737272fda1350a 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/ParallelSearchRadiusIteration.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/ParallelSearchRadiusIteration.java -@@ -1,6 +1,7 @@ - package ca.spottedleaf.moonrise.patches.chunk_system.util; - - import ca.spottedleaf.moonrise.common.util.CoordinateUtils; -+import ca.spottedleaf.moonrise.common.util.MoonriseConstants; - import it.unimi.dsi.fastutil.HashCommon; - import it.unimi.dsi.fastutil.longs.LongArrayList; - import it.unimi.dsi.fastutil.longs.LongIterator; -@@ -13,7 +14,7 @@ public final class ParallelSearchRadiusIteration { - - // expected that this list returns for a given radius, the set of chunks ordered - // by manhattan distance -- private static final long[][] SEARCH_RADIUS_ITERATION_LIST = new long[64+2+1][]; -+ private static final long[][] SEARCH_RADIUS_ITERATION_LIST = new long[MoonriseConstants.MAX_VIEW_DISTANCE+2+1][]; - static { - for (int i = 0; i < SEARCH_RADIUS_ITERATION_LIST.length; ++i) { - // a BFS around -x, -z, +x, +z will give increasing manhatten distance -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/stream/ExternalChunkStreamMarker.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/stream/ExternalChunkStreamMarker.java -new file mode 100644 -index 0000000000000000000000000000000000000000..7ef3dcca89ed7578c6c0f5565131889110063056 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/util/stream/ExternalChunkStreamMarker.java -@@ -0,0 +1,37 @@ -+package ca.spottedleaf.moonrise.patches.chunk_system.util.stream; -+ -+import java.io.DataInputStream; -+import java.io.FilterInputStream; -+import java.io.InputStream; -+import java.lang.reflect.Field; -+ -+/** -+ * Used to mark chunk data streams that are on external files -+ */ -+public class ExternalChunkStreamMarker extends DataInputStream { -+ -+ private static final Field IN_FIELD; -+ static { -+ Field field; -+ try { -+ field = FilterInputStream.class.getDeclaredField("in"); -+ field.setAccessible(true); -+ } catch (final Throwable throwable) { -+ field = null; -+ } -+ -+ IN_FIELD = field; -+ } -+ -+ private static InputStream getWrapped(final FilterInputStream in) { -+ try { -+ return (InputStream)IN_FIELD.get(in); -+ } catch (final Throwable throwable) { -+ return in; -+ } -+ } -+ -+ public ExternalChunkStreamMarker(final DataInputStream in) { -+ super(getWrapped(in)); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java -index 748ab4d637ce463272bae4fdbab6842a27385126..3abd4ad6379c383c3a31931255292b42d9435694 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java -@@ -1,15 +1,58 @@ - package ca.spottedleaf.moonrise.patches.collisions; - -+import ca.spottedleaf.moonrise.common.util.WorldUtil; -+import ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemEntityGetter; -+import ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState; -+import ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity; -+import ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData; -+import ca.spottedleaf.moonrise.patches.collisions.shape.CollisionDiscreteVoxelShape; -+import ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape; -+import ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection; -+import it.unimi.dsi.fastutil.doubles.DoubleArrayList; -+import it.unimi.dsi.fastutil.doubles.DoubleList; -+import net.minecraft.core.BlockPos; -+import net.minecraft.core.Direction; -+import net.minecraft.util.Mth; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.item.Item; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.block.Blocks; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.level.border.WorldBorder; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.ChunkSource; -+import net.minecraft.world.level.chunk.LevelChunkSection; -+import net.minecraft.world.level.chunk.PalettedContainer; -+import net.minecraft.world.level.chunk.status.ChunkStatus; -+import net.minecraft.world.level.material.FluidState; -+import net.minecraft.world.phys.AABB; -+import net.minecraft.world.phys.Vec3; -+import net.minecraft.world.phys.shapes.ArrayVoxelShape; -+import net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape; -+import net.minecraft.world.phys.shapes.BooleanOp; -+import net.minecraft.world.phys.shapes.CollisionContext; -+import net.minecraft.world.phys.shapes.DiscreteVoxelShape; -+import net.minecraft.world.phys.shapes.EntityCollisionContext; -+import net.minecraft.world.phys.shapes.OffsetDoubleList; -+import net.minecraft.world.phys.shapes.Shapes; -+import net.minecraft.world.phys.shapes.SliceShape; -+import net.minecraft.world.phys.shapes.VoxelShape; -+import java.util.Arrays; -+import java.util.List; -+import java.util.Objects; -+import java.util.function.BiPredicate; -+import java.util.function.Predicate; -+ - public final class CollisionUtil { - - public static final double COLLISION_EPSILON = 1.0E-7; -- public static final it.unimi.dsi.fastutil.doubles.DoubleArrayList ZERO_ONE = it.unimi.dsi.fastutil.doubles.DoubleArrayList.wrap(new double[] { 0.0, 1.0 }); -+ public static final DoubleArrayList ZERO_ONE = DoubleArrayList.wrap(new double[] { 0.0, 1.0 }); - - public static boolean isSpecialCollidingBlock(final net.minecraft.world.level.block.state.BlockBehaviour.BlockStateBase block) { -- return block.hasLargeCollisionShape() || block.getBlock() == net.minecraft.world.level.block.Blocks.MOVING_PISTON; -+ return block.hasLargeCollisionShape() || block.getBlock() == Blocks.MOVING_PISTON; - } - -- public static boolean isEmpty(final net.minecraft.world.phys.AABB aabb) { -+ public static boolean isEmpty(final AABB aabb) { - return (aabb.maxX - aabb.minX) < COLLISION_EPSILON || (aabb.maxY - aabb.minY) < COLLISION_EPSILON || (aabb.maxZ - aabb.minZ) < COLLISION_EPSILON; - } - -@@ -18,11 +61,11 @@ public final class CollisionUtil { - return (maxX - minX) < COLLISION_EPSILON || (maxY - minY) < COLLISION_EPSILON || (maxZ - minZ) < COLLISION_EPSILON; - } - -- public static net.minecraft.world.phys.AABB getBoxForChunk(final int chunkX, final int chunkZ) { -+ public static AABB getBoxForChunk(final int chunkX, final int chunkZ) { - double x = (double)(chunkX << 4); - double z = (double)(chunkZ << 4); - // use a bounding box bigger than the chunk to prevent entities from entering it on move -- return new net.minecraft.world.phys.AABB(x - 3*COLLISION_EPSILON, Double.NEGATIVE_INFINITY, z - 3*COLLISION_EPSILON, -+ return new AABB(x - 3*COLLISION_EPSILON, Double.NEGATIVE_INFINITY, z - 3*COLLISION_EPSILON, - x + (16.0 + 3*COLLISION_EPSILON), Double.POSITIVE_INFINITY, z + (16.0 + 3*COLLISION_EPSILON)); - } - -@@ -43,21 +86,21 @@ public final class CollisionUtil { - (minZ1 - maxZ2) < -COLLISION_EPSILON && (maxZ1 - minZ2) > COLLISION_EPSILON; - } - -- public static boolean voxelShapeIntersect(final net.minecraft.world.phys.AABB box, final double minX, final double minY, final double minZ, -+ public static boolean voxelShapeIntersect(final AABB box, final double minX, final double minY, final double minZ, - final double maxX, final double maxY, final double maxZ) { - return (box.minX - maxX) < -COLLISION_EPSILON && (box.maxX - minX) > COLLISION_EPSILON && - (box.minY - maxY) < -COLLISION_EPSILON && (box.maxY - minY) > COLLISION_EPSILON && - (box.minZ - maxZ) < -COLLISION_EPSILON && (box.maxZ - minZ) > COLLISION_EPSILON; - } - -- public static boolean voxelShapeIntersect(final net.minecraft.world.phys.AABB box1, final net.minecraft.world.phys.AABB box2) { -+ public static boolean voxelShapeIntersect(final AABB box1, final AABB box2) { - return (box1.minX - box2.maxX) < -COLLISION_EPSILON && (box1.maxX - box2.minX) > COLLISION_EPSILON && - (box1.minY - box2.maxY) < -COLLISION_EPSILON && (box1.maxY - box2.minY) > COLLISION_EPSILON && - (box1.minZ - box2.maxZ) < -COLLISION_EPSILON && (box1.maxZ - box2.minZ) > COLLISION_EPSILON; - } - - // assume !isEmpty(target) && abs(source_move) >= COLLISION_EPSILON -- public static double collideX(final net.minecraft.world.phys.AABB target, final net.minecraft.world.phys.AABB source, final double source_move) { -+ public static double collideX(final AABB target, final AABB source, final double source_move) { - if ((source.minY - target.maxY) < -COLLISION_EPSILON && (source.maxY - target.minY) > COLLISION_EPSILON && - (source.minZ - target.maxZ) < -COLLISION_EPSILON && (source.maxZ - target.minZ) > COLLISION_EPSILON) { - if (source_move >= 0.0) { -@@ -78,7 +121,7 @@ public final class CollisionUtil { - } - - // assume !isEmpty(target) && abs(source_move) >= COLLISION_EPSILON -- public static double collideY(final net.minecraft.world.phys.AABB target, final net.minecraft.world.phys.AABB source, final double source_move) { -+ public static double collideY(final AABB target, final AABB source, final double source_move) { - if ((source.minX - target.maxX) < -COLLISION_EPSILON && (source.maxX - target.minX) > COLLISION_EPSILON && - (source.minZ - target.maxZ) < -COLLISION_EPSILON && (source.maxZ - target.minZ) > COLLISION_EPSILON) { - if (source_move >= 0.0) { -@@ -99,7 +142,7 @@ public final class CollisionUtil { - } - - // assume !isEmpty(target) && abs(source_move) >= COLLISION_EPSILON -- public static double collideZ(final net.minecraft.world.phys.AABB target, final net.minecraft.world.phys.AABB source, final double source_move) { -+ public static double collideZ(final AABB target, final AABB source, final double source_move) { - if ((source.minX - target.maxX) < -COLLISION_EPSILON && (source.maxX - target.minX) > COLLISION_EPSILON && - (source.minY - target.maxY) < -COLLISION_EPSILON && (source.maxY - target.minY) > COLLISION_EPSILON) { - if (source_move >= 0.0) { -@@ -121,7 +164,8 @@ public final class CollisionUtil { - - // startIndex and endIndex inclusive - // assumes indices are in range of array -- private static int findFloor(final double[] values, final double value, int startIndex, int endIndex) { -+ public static int findFloor(final double[] values, final double value, int startIndex, int endIndex) { -+ Objects.checkFromToIndex(startIndex, endIndex + 1, values.length); - do { - final int middle = (startIndex + endIndex) >>> 1; - final double middleVal = values[middle]; -@@ -136,7 +180,217 @@ public final class CollisionUtil { - return startIndex - 1; - } - -- public static boolean voxelShapeIntersectNoEmpty(final net.minecraft.world.phys.shapes.VoxelShape voxel, final net.minecraft.world.phys.AABB aabb) { -+ private static VoxelShape sliceShapeVanilla(final VoxelShape src, final Direction.Axis axis, -+ final int index) { -+ return new SliceShape(src, axis, index); -+ } -+ -+ private static DoubleList offsetList(final double[] src, final double by) { -+ final DoubleArrayList wrap = DoubleArrayList.wrap(src); -+ if (by == 0.0) { -+ return wrap; -+ } -+ return new OffsetDoubleList(wrap, by); -+ } -+ -+ private static VoxelShape sliceShapeOptimised(final VoxelShape src, final Direction.Axis axis, -+ final int index) { -+ // assume index in range -+ final double off_x = ((CollisionVoxelShape)src).moonrise$offsetX(); -+ final double off_y = ((CollisionVoxelShape)src).moonrise$offsetY(); -+ final double off_z = ((CollisionVoxelShape)src).moonrise$offsetZ(); -+ -+ final double[] coords_x = ((CollisionVoxelShape)src).moonrise$rootCoordinatesX(); -+ final double[] coords_y = ((CollisionVoxelShape)src).moonrise$rootCoordinatesY(); -+ final double[] coords_z = ((CollisionVoxelShape)src).moonrise$rootCoordinatesZ(); -+ -+ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)src).moonrise$getCachedVoxelData(); -+ -+ // note: size = coords.length - 1 -+ final int size_x = cached_shape_data.sizeX(); -+ final int size_y = cached_shape_data.sizeY(); -+ final int size_z = cached_shape_data.sizeZ(); -+ -+ final long[] bitset = cached_shape_data.voxelSet(); -+ -+ final DoubleList list_x; -+ final DoubleList list_y; -+ final DoubleList list_z; -+ final int shape_sx; -+ final int shape_ex; -+ final int shape_sy; -+ final int shape_ey; -+ final int shape_sz; -+ final int shape_ez; -+ -+ switch (axis) { -+ case X: { -+ // validate index -+ if (index < 0 || index >= size_x) { -+ return Shapes.empty(); -+ } -+ -+ // test if input is already "sliced" -+ if (coords_x.length == 2 && (coords_x[0] + off_x) == 0.0 && (coords_x[1] + off_x) == 1.0) { -+ return src; -+ } -+ -+ // test if result would be full box -+ if (coords_y.length == 2 && coords_z.length == 2 && -+ (coords_y[0] + off_y) == 0.0 && (coords_y[1] + off_y) == 1.0 && -+ (coords_z[0] + off_z) == 0.0 && (coords_z[1] + off_z) == 1.0) { -+ // note: size_y == size_z == 1 -+ final int bitIdx = 0 + 0*size_z + index*(size_z*size_y); -+ return (bitset[bitIdx >>> 6] & (1L << bitIdx)) == 0L ? Shapes.empty() : Shapes.block(); -+ } -+ -+ list_x = ZERO_ONE; -+ list_y = offsetList(coords_y, off_y); -+ list_z = offsetList(coords_z, off_z); -+ shape_sx = index; -+ shape_ex = index + 1; -+ shape_sy = 0; -+ shape_ey = size_y; -+ shape_sz = 0; -+ shape_ez = size_z; -+ -+ break; -+ } -+ case Y: { -+ // validate index -+ if (index < 0 || index >= size_y) { -+ return Shapes.empty(); -+ } -+ -+ // test if input is already "sliced" -+ if (coords_y.length == 2 && (coords_y[0] + off_y) == 0.0 && (coords_y[1] + off_y) == 1.0) { -+ return src; -+ } -+ -+ // test if result would be full box -+ if (coords_x.length == 2 && coords_z.length == 2 && -+ (coords_x[0] + off_x) == 0.0 && (coords_x[1] + off_x) == 1.0 && -+ (coords_z[0] + off_z) == 0.0 && (coords_z[1] + off_z) == 1.0) { -+ // note: size_x == size_z == 1 -+ final int bitIdx = 0 + index*size_z + 0*(size_z*size_y); -+ return (bitset[bitIdx >>> 6] & (1L << bitIdx)) == 0L ? Shapes.empty() : Shapes.block(); -+ } -+ -+ list_x = offsetList(coords_x, off_x); -+ list_y = ZERO_ONE; -+ list_z = offsetList(coords_z, off_z); -+ shape_sx = 0; -+ shape_ex = size_x; -+ shape_sy = index; -+ shape_ey = index + 1; -+ shape_sz = 0; -+ shape_ez = size_z; -+ -+ break; -+ } -+ case Z: { -+ // validate index -+ if (index < 0 || index >= size_z) { -+ return Shapes.empty(); -+ } -+ -+ // test if input is already "sliced" -+ if (coords_z.length == 2 && (coords_z[0] + off_z) == 0.0 && (coords_z[1] + off_z) == 1.0) { -+ return src; -+ } -+ -+ // test if result would be full box -+ if (coords_x.length == 2 && coords_y.length == 2 && -+ (coords_x[0] + off_x) == 0.0 && (coords_x[1] + off_x) == 1.0 && -+ (coords_y[0] + off_y) == 0.0 && (coords_y[1] + off_y) == 1.0) { -+ // note: size_x == size_y == 1 -+ final int bitIdx = index + 0*size_z + 0*(size_z*size_y); -+ return (bitset[bitIdx >>> 6] & (1L << bitIdx)) == 0L ? Shapes.empty() : Shapes.block(); -+ } -+ -+ list_x = offsetList(coords_x, off_x); -+ list_y = offsetList(coords_y, off_y); -+ list_z = ZERO_ONE; -+ shape_sx = 0; -+ shape_ex = size_x; -+ shape_sy = 0; -+ shape_ey = size_y; -+ shape_sz = index; -+ shape_ez = index + 1; -+ -+ break; -+ } -+ default: { -+ throw new IllegalStateException("Unknown axis: " + axis); -+ } -+ } -+ -+ final int local_len_x = shape_ex - shape_sx; -+ final int local_len_y = shape_ey - shape_sy; -+ final int local_len_z = shape_ez - shape_sz; -+ -+ final BitSetDiscreteVoxelShape shape = new BitSetDiscreteVoxelShape(local_len_x, local_len_y, local_len_z); -+ -+ final int bitset_mul_x = size_z*size_y; -+ final int idx_off = shape_sz + shape_sy*size_z + shape_sx*bitset_mul_x; -+ final int shape_mul_x = local_len_y*local_len_z; -+ for (int x = 0; x < local_len_x; ++x) { -+ boolean setX = false; -+ for (int y = 0; y < local_len_y; ++y) { -+ boolean setY = false; -+ for (int z = 0; z < local_len_z; ++z) { -+ final int unslicedIdx = idx_off + z + y*size_z + x*bitset_mul_x; -+ if ((bitset[unslicedIdx >>> 6] & (1L << unslicedIdx)) == 0L) { -+ continue; -+ } -+ -+ setY = true; -+ setX = true; -+ shape.zMin = Math.min(shape.zMin, z); -+ shape.zMax = Math.max(shape.zMax, z + 1); -+ -+ shape.storage.set( -+ z + y*local_len_z + x*shape_mul_x -+ ); -+ } -+ -+ if (setY) { -+ shape.yMin = Math.min(shape.yMin, y); -+ shape.yMax = Math.max(shape.yMax, y + 1); -+ } -+ } -+ if (setX) { -+ shape.xMin = Math.min(shape.xMin, x); -+ shape.xMax = Math.max(shape.xMax, x + 1); -+ } -+ } -+ -+ return shape.isEmpty() ? Shapes.empty() : new ArrayVoxelShape( -+ shape, list_x, list_y, list_z -+ ); -+ } -+ -+ private static final boolean DEBUG_SLICE_SHAPE = false; -+ -+ public static VoxelShape sliceShape(final VoxelShape src, final Direction.Axis axis, -+ final int index) { -+ final VoxelShape ret = sliceShapeOptimised(src, axis, index); -+ if (DEBUG_SLICE_SHAPE) { -+ final VoxelShape vanilla = sliceShapeVanilla(src, axis, index); -+ if (!equals(ret, vanilla)) { -+ // special case: SliceShape is not empty when it should be! -+ if (areAnyFull(ret.shape) || areAnyFull(vanilla.shape)) { -+ equals(ret, vanilla); -+ sliceShapeOptimised(src, axis, index); -+ throw new IllegalStateException("Slice shape mismatch"); -+ } -+ } -+ } -+ -+ return ret; -+ } -+ -+ public static boolean voxelShapeIntersectNoEmpty(final VoxelShape voxel, final AABB aabb) { - if (voxel.isEmpty()) { - return false; - } -@@ -144,15 +398,15 @@ public final class CollisionUtil { - // note: this function assumes that for any i in coords that coord[i + 1] - coord[i] > COLLISION_EPSILON is true - - // offsets that should be applied to coords -- final double off_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetX(); -- final double off_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetY(); -- final double off_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetZ(); -+ final double off_x = ((CollisionVoxelShape)voxel).moonrise$offsetX(); -+ final double off_y = ((CollisionVoxelShape)voxel).moonrise$offsetY(); -+ final double off_z = ((CollisionVoxelShape)voxel).moonrise$offsetZ(); - -- final double[] coords_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesX(); -- final double[] coords_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesY(); -- final double[] coords_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesZ(); -+ final double[] coords_x = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesX(); -+ final double[] coords_y = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesY(); -+ final double[] coords_z = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesZ(); - -- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cached_shape_data = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$getCachedVoxelData(); -+ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)voxel).moonrise$getCachedVoxelData(); - - // note: size = coords.length - 1 - final int size_x = cached_shape_data.sizeX(); -@@ -246,23 +500,23 @@ public final class CollisionUtil { - } - - // assume !target.isEmpty() && abs(source_move) >= COLLISION_EPSILON -- public static double collideX(final net.minecraft.world.phys.shapes.VoxelShape target, final net.minecraft.world.phys.AABB source, final double source_move) { -- final net.minecraft.world.phys.AABB single_aabb = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); -+ public static double collideX(final VoxelShape target, final AABB source, final double source_move) { -+ final AABB single_aabb = ((CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); - if (single_aabb != null) { - return collideX(single_aabb, source, source_move); - } - // note: this function assumes that for any i in coords that coord[i + 1] - coord[i] > COLLISION_EPSILON is true - - // offsets that should be applied to coords -- final double off_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetX(); -- final double off_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetY(); -- final double off_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetZ(); -+ final double off_x = ((CollisionVoxelShape)target).moonrise$offsetX(); -+ final double off_y = ((CollisionVoxelShape)target).moonrise$offsetY(); -+ final double off_z = ((CollisionVoxelShape)target).moonrise$offsetZ(); - -- final double[] coords_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesX(); -- final double[] coords_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesY(); -- final double[] coords_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); -+ final double[] coords_x = ((CollisionVoxelShape)target).moonrise$rootCoordinatesX(); -+ final double[] coords_y = ((CollisionVoxelShape)target).moonrise$rootCoordinatesY(); -+ final double[] coords_z = ((CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); - -- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cached_shape_data = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getCachedVoxelData(); -+ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)target).moonrise$getCachedVoxelData(); - - // note: size = coords.length - 1 - final int size_x = cached_shape_data.sizeX(); -@@ -404,23 +658,23 @@ public final class CollisionUtil { - } - } - -- public static double collideY(final net.minecraft.world.phys.shapes.VoxelShape target, final net.minecraft.world.phys.AABB source, final double source_move) { -- final net.minecraft.world.phys.AABB single_aabb = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); -+ public static double collideY(final VoxelShape target, final AABB source, final double source_move) { -+ final AABB single_aabb = ((CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); - if (single_aabb != null) { - return collideY(single_aabb, source, source_move); - } - // note: this function assumes that for any i in coords that coord[i + 1] - coord[i] > COLLISION_EPSILON is true - - // offsets that should be applied to coords -- final double off_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetX(); -- final double off_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetY(); -- final double off_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetZ(); -+ final double off_x = ((CollisionVoxelShape)target).moonrise$offsetX(); -+ final double off_y = ((CollisionVoxelShape)target).moonrise$offsetY(); -+ final double off_z = ((CollisionVoxelShape)target).moonrise$offsetZ(); - -- final double[] coords_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesX(); -- final double[] coords_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesY(); -- final double[] coords_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); -+ final double[] coords_x = ((CollisionVoxelShape)target).moonrise$rootCoordinatesX(); -+ final double[] coords_y = ((CollisionVoxelShape)target).moonrise$rootCoordinatesY(); -+ final double[] coords_z = ((CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); - -- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cached_shape_data = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getCachedVoxelData(); -+ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)target).moonrise$getCachedVoxelData(); - - // note: size = coords.length - 1 - final int size_x = cached_shape_data.sizeX(); -@@ -562,23 +816,23 @@ public final class CollisionUtil { - } - } - -- public static double collideZ(final net.minecraft.world.phys.shapes.VoxelShape target, final net.minecraft.world.phys.AABB source, final double source_move) { -- final net.minecraft.world.phys.AABB single_aabb = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); -+ public static double collideZ(final VoxelShape target, final AABB source, final double source_move) { -+ final AABB single_aabb = ((CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation(); - if (single_aabb != null) { - return collideZ(single_aabb, source, source_move); - } - // note: this function assumes that for any i in coords that coord[i + 1] - coord[i] > COLLISION_EPSILON is true - - // offsets that should be applied to coords -- final double off_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetX(); -- final double off_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetY(); -- final double off_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$offsetZ(); -+ final double off_x = ((CollisionVoxelShape)target).moonrise$offsetX(); -+ final double off_y = ((CollisionVoxelShape)target).moonrise$offsetY(); -+ final double off_z = ((CollisionVoxelShape)target).moonrise$offsetZ(); - -- final double[] coords_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesX(); -- final double[] coords_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesY(); -- final double[] coords_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); -+ final double[] coords_x = ((CollisionVoxelShape)target).moonrise$rootCoordinatesX(); -+ final double[] coords_y = ((CollisionVoxelShape)target).moonrise$rootCoordinatesY(); -+ final double[] coords_z = ((CollisionVoxelShape)target).moonrise$rootCoordinatesZ(); - -- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cached_shape_data = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)target).moonrise$getCachedVoxelData(); -+ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)target).moonrise$getCachedVoxelData(); - - // note: size = coords.length - 1 - final int size_x = cached_shape_data.sizeX(); -@@ -721,13 +975,13 @@ public final class CollisionUtil { - } - - // does not use epsilon -- public static boolean strictlyContains(final net.minecraft.world.phys.shapes.VoxelShape voxel, final net.minecraft.world.phys.Vec3 point) { -+ public static boolean strictlyContains(final VoxelShape voxel, final Vec3 point) { - return strictlyContains(voxel, point.x, point.y, point.z); - } - - // does not use epsilon -- public static boolean strictlyContains(final net.minecraft.world.phys.shapes.VoxelShape voxel, double x, double y, double z) { -- final net.minecraft.world.phys.AABB single_aabb = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$getSingleAABBRepresentation(); -+ public static boolean strictlyContains(final VoxelShape voxel, double x, double y, double z) { -+ final AABB single_aabb = ((CollisionVoxelShape)voxel).moonrise$getSingleAABBRepresentation(); - if (single_aabb != null) { - return single_aabb.contains(x, y, z); - } -@@ -738,15 +992,15 @@ public final class CollisionUtil { - } - - // offset input -- x -= ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetX(); -- y -= ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetY(); -- z -= ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$offsetZ(); -+ x -= ((CollisionVoxelShape)voxel).moonrise$offsetX(); -+ y -= ((CollisionVoxelShape)voxel).moonrise$offsetY(); -+ z -= ((CollisionVoxelShape)voxel).moonrise$offsetZ(); - -- final double[] coords_x = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesX(); -- final double[] coords_y = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesY(); -- final double[] coords_z = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$rootCoordinatesZ(); -+ final double[] coords_x = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesX(); -+ final double[] coords_y = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesY(); -+ final double[] coords_z = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesZ(); - -- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cached_shape_data = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$getCachedVoxelData(); -+ final CachedShapeData cached_shape_data = ((CollisionVoxelShape)voxel).moonrise$getCachedVoxelData(); - - // note: size = coords.length - 1 - final int size_x = cached_shape_data.sizeX(); -@@ -788,10 +1042,10 @@ public final class CollisionUtil { - return ((ft ? 1 : 0) << 1) | ((tf ? 1 : 0) << 2) | ((tt ? 1 : 0) << 3); - } - -- private static net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape merge(final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataFirst, final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataSecond, -- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedX, final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedY, -- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedZ, -- final int booleanOp) { -+ private static BitSetDiscreteVoxelShape merge(final CachedShapeData shapeDataFirst, final CachedShapeData shapeDataSecond, -+ final MergedVoxelCoordinateList mergedX, final MergedVoxelCoordinateList mergedY, -+ final MergedVoxelCoordinateList mergedZ, -+ final int booleanOp) { - final int sizeX = mergedX.voxels; - final int sizeY = mergedY.voxels; - final int sizeZ = mergedZ.voxels; -@@ -806,7 +1060,7 @@ public final class CollisionUtil { - final int s2Mul2 = s2Mul1 * shapeDataSecond.sizeY(); - - // note: indices may contain -1, but nothing > size -- final net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape ret = new net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape(sizeX, sizeY, sizeZ); -+ final BitSetDiscreteVoxelShape ret = new BitSetDiscreteVoxelShape(sizeX, sizeY, sizeZ); - - boolean empty = true; - -@@ -823,10 +1077,11 @@ public final class CollisionUtil { - final int s1z = mergedZ.firstIndices[idxZ]; - final int s2z = mergedZ.secondIndices[idxZ]; - -- int idx; -+ int idx1; -+ int idx2; - -- final int isS1Full = (s1x | s1y | s1z) < 0 ? 0 : (int)((s1Voxels[(idx = s1z + s1y*s1Mul1 + s1x*s1Mul2) >>> 6] >>> idx) & 1L); -- final int isS2Full = (s2x | s2y | s2z) < 0 ? 0 : (int)((s2Voxels[(idx = s2z + s2y*s2Mul1 + s2x*s2Mul2) >>> 6] >>> idx) & 1L); -+ final int isS1Full = (s1x | s1y | s1z) < 0 ? 0 : (int)((s1Voxels[(idx1 = s1z + s1y*s1Mul1 + s1x*s1Mul2) >>> 6] >>> idx1) & 1L); -+ final int isS2Full = (s2x | s2y | s2z) < 0 ? 0 : (int)((s2Voxels[(idx2 = s2z + s2y*s2Mul1 + s2x*s2Mul2) >>> 6] >>> idx2) & 1L); - - // idx ff -> 0 - // idx ft -> 1 -@@ -861,9 +1116,9 @@ public final class CollisionUtil { - return empty ? null : ret; - } - -- private static boolean isMergeEmpty(final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataFirst, final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataSecond, -- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedX, final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedY, -- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedZ, -+ private static boolean isMergeEmpty(final CachedShapeData shapeDataFirst, final CachedShapeData shapeDataSecond, -+ final MergedVoxelCoordinateList mergedX, final MergedVoxelCoordinateList mergedY, -+ final MergedVoxelCoordinateList mergedZ, - final int booleanOp) { - final int sizeX = mergedX.voxels; - final int sizeY = mergedY.voxels; -@@ -889,10 +1144,11 @@ public final class CollisionUtil { - final int s1z = mergedZ.firstIndices[idxZ]; - final int s2z = mergedZ.secondIndices[idxZ]; - -- int idx; -+ int idx1; -+ int idx2; - -- final int isS1Full = (s1x | s1y | s1z) < 0 ? 0 : (int)((s1Voxels[(idx = s1z + s1y*s1Mul1 + s1x*s1Mul2) >>> 6] >>> idx) & 1L); -- final int isS2Full = (s2x | s2y | s2z) < 0 ? 0 : (int)((s2Voxels[(idx = s2z + s2y*s2Mul1 + s2x*s2Mul2) >>> 6] >>> idx) & 1L); -+ final int isS1Full = (s1x | s1y | s1z) < 0 ? 0 : (int)((s1Voxels[(idx1 = s1z + s1y*s1Mul1 + s1x*s1Mul2) >>> 6] >>> idx1) & 1L); -+ final int isS2Full = (s2x | s2y | s2z) < 0 ? 0 : (int)((s2Voxels[(idx2 = s2z + s2y*s2Mul1 + s2x*s2Mul2) >>> 6] >>> idx2) & 1L); - - // idx ff -> 0 - // idx ft -> 1 -@@ -911,11 +1167,11 @@ public final class CollisionUtil { - return true; - } - -- public static net.minecraft.world.phys.shapes.VoxelShape joinOptimized(final net.minecraft.world.phys.shapes.VoxelShape first, final net.minecraft.world.phys.shapes.VoxelShape second, final net.minecraft.world.phys.shapes.BooleanOp operator) { -+ public static VoxelShape joinOptimized(final VoxelShape first, final VoxelShape second, final BooleanOp operator) { - return joinUnoptimized(first, second, operator).optimize(); - } - -- public static net.minecraft.world.phys.shapes.VoxelShape joinUnoptimized(final net.minecraft.world.phys.shapes.VoxelShape first, final net.minecraft.world.phys.shapes.VoxelShape second, final net.minecraft.world.phys.shapes.BooleanOp operator) { -+ public static VoxelShape joinUnoptimized(final VoxelShape first, final VoxelShape second, final BooleanOp operator) { - final boolean ff = operator.apply(false, false); - if (ff) { - // technically, should be an infinite box but that's clearly an error -@@ -925,23 +1181,23 @@ public final class CollisionUtil { - final boolean tt = operator.apply(true, true); - - if (first == second) { -- return tt ? first : net.minecraft.world.phys.shapes.Shapes.empty(); -+ return tt ? first : Shapes.empty(); - } - - final boolean ft = operator.apply(false, true); - final boolean tf = operator.apply(true, false); - - if (first.isEmpty()) { -- return ft ? second : net.minecraft.world.phys.shapes.Shapes.empty(); -+ return ft ? second : Shapes.empty(); - } - if (second.isEmpty()) { -- return tf ? first : net.minecraft.world.phys.shapes.Shapes.empty(); -+ return tf ? first : Shapes.empty(); - } - - if (!tt) { - // try to check for no intersection, since tt = false -- final net.minecraft.world.phys.AABB aabbF = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$getSingleAABBRepresentation(); -- final net.minecraft.world.phys.AABB aabbS = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$getSingleAABBRepresentation(); -+ final AABB aabbF = ((CollisionVoxelShape)first).moonrise$getSingleAABBRepresentation(); -+ final AABB aabbS = ((CollisionVoxelShape)second).moonrise$getSingleAABBRepresentation(); - - final boolean intersect; - -@@ -962,7 +1218,7 @@ public final class CollisionUtil { - - if (!intersect) { - if (!tf & !ft) { -- return net.minecraft.world.phys.shapes.Shapes.empty(); -+ return Shapes.empty(); - } - if (!tf | !ft) { - return tf ? first : second; -@@ -970,50 +1226,50 @@ public final class CollisionUtil { - } - } - -- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedX = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( -- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesX(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetX(), -- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesX(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetX(), -+ final MergedVoxelCoordinateList mergedX = MergedVoxelCoordinateList.merge( -+ ((CollisionVoxelShape)first).moonrise$rootCoordinatesX(), ((CollisionVoxelShape)first).moonrise$offsetX(), -+ ((CollisionVoxelShape)second).moonrise$rootCoordinatesX(), ((CollisionVoxelShape)second).moonrise$offsetX(), - ft, tf - ); -- if (mergedX == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { -- return net.minecraft.world.phys.shapes.Shapes.empty(); -+ if (mergedX == null) { -+ return Shapes.empty(); - } -- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedY = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( -- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesY(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetY(), -- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesY(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetY(), -+ final MergedVoxelCoordinateList mergedY = MergedVoxelCoordinateList.merge( -+ ((CollisionVoxelShape)first).moonrise$rootCoordinatesY(), ((CollisionVoxelShape)first).moonrise$offsetY(), -+ ((CollisionVoxelShape)second).moonrise$rootCoordinatesY(), ((CollisionVoxelShape)second).moonrise$offsetY(), - ft, tf - ); -- if (mergedY == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { -- return net.minecraft.world.phys.shapes.Shapes.empty(); -+ if (mergedY == null) { -+ return Shapes.empty(); - } -- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedZ = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( -- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesZ(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetZ(), -- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesZ(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetZ(), -+ final MergedVoxelCoordinateList mergedZ = MergedVoxelCoordinateList.merge( -+ ((CollisionVoxelShape)first).moonrise$rootCoordinatesZ(), ((CollisionVoxelShape)first).moonrise$offsetZ(), -+ ((CollisionVoxelShape)second).moonrise$rootCoordinatesZ(), ((CollisionVoxelShape)second).moonrise$offsetZ(), - ft, tf - ); -- if (mergedZ == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { -- return net.minecraft.world.phys.shapes.Shapes.empty(); -+ if (mergedZ == null) { -+ return Shapes.empty(); - } - -- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataFirst = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$getCachedVoxelData(); -- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataSecond = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$getCachedVoxelData(); -+ final CachedShapeData shapeDataFirst = ((CollisionVoxelShape)first).moonrise$getCachedVoxelData(); -+ final CachedShapeData shapeDataSecond = ((CollisionVoxelShape)second).moonrise$getCachedVoxelData(); - -- final net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape mergedShape = merge( -+ final BitSetDiscreteVoxelShape mergedShape = merge( - shapeDataFirst, shapeDataSecond, - mergedX, mergedY, mergedZ, - makeBitset(ft, tf, tt) - ); - - if (mergedShape == null) { -- return net.minecraft.world.phys.shapes.Shapes.empty(); -+ return Shapes.empty(); - } - -- return new net.minecraft.world.phys.shapes.ArrayVoxelShape( -+ return new ArrayVoxelShape( - mergedShape, mergedX.wrapCoords(), mergedY.wrapCoords(), mergedZ.wrapCoords() - ); - } - -- public static boolean isJoinNonEmpty(final net.minecraft.world.phys.shapes.VoxelShape first, final net.minecraft.world.phys.shapes.VoxelShape second, final net.minecraft.world.phys.shapes.BooleanOp operator) { -+ public static boolean isJoinNonEmpty(final VoxelShape first, final VoxelShape second, final BooleanOp operator) { - final boolean ff = operator.apply(false, false); - if (ff) { - // technically, should be an infinite box but that's clearly an error -@@ -1035,8 +1291,8 @@ public final class CollisionUtil { - final boolean tf = operator.apply(true, false); - - // try to check intersection -- final net.minecraft.world.phys.AABB aabbF = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$getSingleAABBRepresentation(); -- final net.minecraft.world.phys.AABB aabbS = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$getSingleAABBRepresentation(); -+ final AABB aabbF = ((CollisionVoxelShape)first).moonrise$getSingleAABBRepresentation(); -+ final AABB aabbS = ((CollisionVoxelShape)second).moonrise$getSingleAABBRepresentation(); - - final boolean intersect; - -@@ -1068,33 +1324,33 @@ public final class CollisionUtil { - } - } - -- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedX = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( -- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesX(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetX(), -- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesX(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetX(), -+ final MergedVoxelCoordinateList mergedX = MergedVoxelCoordinateList.merge( -+ ((CollisionVoxelShape)first).moonrise$rootCoordinatesX(), ((CollisionVoxelShape)first).moonrise$offsetX(), -+ ((CollisionVoxelShape)second).moonrise$rootCoordinatesX(), ((CollisionVoxelShape)second).moonrise$offsetX(), - ft, tf - ); -- if (mergedX == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { -+ if (mergedX == null) { - return false; - } -- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedY = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( -- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesY(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetY(), -- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesY(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetY(), -+ final MergedVoxelCoordinateList mergedY = MergedVoxelCoordinateList.merge( -+ ((CollisionVoxelShape)first).moonrise$rootCoordinatesY(), ((CollisionVoxelShape)first).moonrise$offsetY(), -+ ((CollisionVoxelShape)second).moonrise$rootCoordinatesY(), ((CollisionVoxelShape)second).moonrise$offsetY(), - ft, tf - ); -- if (mergedY == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { -+ if (mergedY == null) { - return false; - } -- final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList mergedZ = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.merge( -- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$rootCoordinatesZ(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$offsetZ(), -- ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$rootCoordinatesZ(), ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$offsetZ(), -+ final MergedVoxelCoordinateList mergedZ = MergedVoxelCoordinateList.merge( -+ ((CollisionVoxelShape)first).moonrise$rootCoordinatesZ(), ((CollisionVoxelShape)first).moonrise$offsetZ(), -+ ((CollisionVoxelShape)second).moonrise$rootCoordinatesZ(), ((CollisionVoxelShape)second).moonrise$offsetZ(), - ft, tf - ); -- if (mergedZ == ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList.EMPTY) { -+ if (mergedZ == null) { - return false; - } - -- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataFirst = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$getCachedVoxelData(); -- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeDataSecond = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$getCachedVoxelData(); -+ final CachedShapeData shapeDataFirst = ((CollisionVoxelShape)first).moonrise$getCachedVoxelData(); -+ final CachedShapeData shapeDataSecond = ((CollisionVoxelShape)second).moonrise$getCachedVoxelData(); - - return !isMergeEmpty( - shapeDataFirst, shapeDataSecond, -@@ -1112,10 +1368,6 @@ public final class CollisionUtil { - } - } - -- private static final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList EMPTY = new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList( -- new double[] { 0.0 }, 0.0, new int[0], new int[0], 0 -- ); -- - private static int[] getIndices(final int length) { - final int[] ret = new int[length]; - -@@ -1142,25 +1394,25 @@ public final class CollisionUtil { - this.voxels = voxels; - } - -- public it.unimi.dsi.fastutil.doubles.DoubleList wrapCoords() { -+ public DoubleList wrapCoords() { - if (this.coordinateOffset == 0.0) { -- return it.unimi.dsi.fastutil.doubles.DoubleArrayList.wrap(this.coordinates, this.voxels + 1); -+ return DoubleArrayList.wrap(this.coordinates, this.voxels + 1); - } -- return new net.minecraft.world.phys.shapes.OffsetDoubleList(it.unimi.dsi.fastutil.doubles.DoubleArrayList.wrap(this.coordinates, this.voxels + 1), this.coordinateOffset); -+ return new OffsetDoubleList(DoubleArrayList.wrap(this.coordinates, this.voxels + 1), this.coordinateOffset); - } - - // assume coordinates.length > 1 -- public static ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList getForSingle(final double[] coordinates, final double offset) { -+ public static MergedVoxelCoordinateList getForSingle(final double[] coordinates, final double offset) { - final int voxels = coordinates.length - 1; - final int[] indices = voxels < SIMPLE_INDICES_CACHE.length ? SIMPLE_INDICES_CACHE[voxels] : getIndices(voxels); - -- return new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList(coordinates, offset, indices, indices, voxels); -+ return new MergedVoxelCoordinateList(coordinates, offset, indices, indices, voxels); - } - - // assume coordinates.length > 1 -- public static ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList merge(final double[] firstCoordinates, final double firstOffset, -- final double[] secondCoordinates, final double secondOffset, -- final boolean ft, final boolean tf) { -+ public static MergedVoxelCoordinateList merge(final double[] firstCoordinates, final double firstOffset, -+ final double[] secondCoordinates, final double secondOffset, -+ final boolean ft, final boolean tf) { - if (firstCoordinates == secondCoordinates && firstOffset == secondOffset) { - return getForSingle(firstCoordinates, firstOffset); - } -@@ -1250,13 +1502,13 @@ public final class CollisionUtil { - } - } - -- return resultSize <= 1 ? EMPTY : new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.MergedVoxelCoordinateList(coordinates, 0.0, firstIndices, secondIndices, resultSize - 1); -+ return resultSize <= 1 ? null : new MergedVoxelCoordinateList(coordinates, 0.0, firstIndices, secondIndices, resultSize - 1); - } - } - -- public static boolean equals(final net.minecraft.world.phys.shapes.DiscreteVoxelShape shape1, final net.minecraft.world.phys.shapes.DiscreteVoxelShape shape2) { -- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cachedShapeData1 = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionDiscreteVoxelShape)shape1).moonrise$getOrCreateCachedShapeData(); -- final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData cachedShapeData2 = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionDiscreteVoxelShape)shape2).moonrise$getOrCreateCachedShapeData(); -+ public static boolean equals(final DiscreteVoxelShape shape1, final DiscreteVoxelShape shape2) { -+ final CachedShapeData cachedShapeData1 = ((CollisionDiscreteVoxelShape)shape1).moonrise$getOrCreateCachedShapeData(); -+ final CachedShapeData cachedShapeData2 = ((CollisionDiscreteVoxelShape)shape2).moonrise$getOrCreateCachedShapeData(); - - final boolean isEmpty1 = cachedShapeData1.isEmpty(); - final boolean isEmpty2 = cachedShapeData2.isEmpty(); -@@ -1265,7 +1517,7 @@ public final class CollisionUtil { - return true; - } else if (isEmpty1 ^ isEmpty2) { - return false; -- } -+ } // else: isEmpty1 = isEmpty2 = false - - if (cachedShapeData1.hasSingleAABB() != cachedShapeData2.hasSingleAABB()) { - return false; -@@ -1281,153 +1533,237 @@ public final class CollisionUtil { - return false; - } - -- return java.util.Arrays.equals(cachedShapeData1.voxelSet(), cachedShapeData2.voxelSet()); -+ return Arrays.equals(cachedShapeData1.voxelSet(), cachedShapeData2.voxelSet()); - } - - // useful only for testing -- public static boolean equals(final net.minecraft.world.phys.shapes.VoxelShape shape1, final net.minecraft.world.phys.shapes.VoxelShape shape2) { -+ public static boolean equals(final VoxelShape shape1, final VoxelShape shape2) { -+ if (shape1.isEmpty() & shape2.isEmpty()) { -+ return true; -+ } else if (shape1.isEmpty() ^ shape2.isEmpty()) { -+ return false; -+ } -+ - if (!equals(shape1.shape, shape2.shape)) { - return false; - } - -- return shape1.getCoords(net.minecraft.core.Direction.Axis.X).equals(shape2.getCoords(net.minecraft.core.Direction.Axis.X)) && -- shape1.getCoords(net.minecraft.core.Direction.Axis.Y).equals(shape2.getCoords(net.minecraft.core.Direction.Axis.Y)) && -- shape1.getCoords(net.minecraft.core.Direction.Axis.Z).equals(shape2.getCoords(net.minecraft.core.Direction.Axis.Z)); -+ return shape1.getCoords(Direction.Axis.X).equals(shape2.getCoords(Direction.Axis.X)) && -+ shape1.getCoords(Direction.Axis.Y).equals(shape2.getCoords(Direction.Axis.Y)) && -+ shape1.getCoords(Direction.Axis.Z).equals(shape2.getCoords(Direction.Axis.Z)); -+ } -+ -+ public static boolean areAnyFull(final DiscreteVoxelShape shape) { -+ if (shape.isEmpty()) { -+ return false; -+ } -+ -+ final int sizeX = shape.getXSize(); -+ final int sizeY = shape.getYSize(); -+ final int sizeZ = shape.getZSize(); -+ -+ for (int x = 0; x < sizeX; ++x) { -+ for (int y = 0; y < sizeY; ++y) { -+ for (int z = 0; z < sizeZ; ++z) { -+ if (shape.isFull(x, y, z)) { -+ return true; -+ } -+ } -+ } -+ } -+ -+ return false; -+ } -+ -+ public static String shapeMismatch(final DiscreteVoxelShape shape1, final DiscreteVoxelShape shape2) { -+ final CachedShapeData cachedShapeData1 = ((CollisionDiscreteVoxelShape)shape1).moonrise$getOrCreateCachedShapeData(); -+ final CachedShapeData cachedShapeData2 = ((CollisionDiscreteVoxelShape)shape2).moonrise$getOrCreateCachedShapeData(); -+ -+ final boolean isEmpty1 = cachedShapeData1.isEmpty(); -+ final boolean isEmpty2 = cachedShapeData2.isEmpty(); -+ -+ if (isEmpty1 & isEmpty2) { -+ return null; -+ } else if (isEmpty1 ^ isEmpty2) { -+ return null; -+ } // else: isEmpty1 = isEmpty2 = false -+ -+ if (cachedShapeData1.sizeX() != cachedShapeData2.sizeX()) { -+ return "size x: " + cachedShapeData1.sizeX() + " != " + cachedShapeData2.sizeX(); -+ } -+ if (cachedShapeData1.sizeY() != cachedShapeData2.sizeY()) { -+ return "size y: " + cachedShapeData1.sizeY() + " != " + cachedShapeData2.sizeY(); -+ } -+ if (cachedShapeData1.sizeZ() != cachedShapeData2.sizeZ()) { -+ return "size z: " + cachedShapeData1.sizeZ() + " != " + cachedShapeData2.sizeZ(); -+ } -+ -+ final StringBuilder ret = new StringBuilder(); -+ -+ final int sizeX = cachedShapeData1.sizeX();; -+ final int sizeY = cachedShapeData1.sizeY(); -+ final int sizeZ = cachedShapeData1.sizeZ(); -+ -+ boolean first = true; -+ -+ for (int x = 0; x < sizeX; ++x) { -+ for (int y = 0; y < sizeY; ++y) { -+ for (int z = 0; z < sizeZ; ++z) { -+ final boolean isFull1 = shape1.isFull(x, y, z); -+ final boolean isFull2 = shape2.isFull(x, y, z); -+ -+ if (isFull1 == isFull2) { -+ continue; -+ } -+ -+ if (first) { -+ first = false; -+ } else { -+ ret.append(", "); -+ } -+ -+ ret.append("(").append(x).append(",").append(y).append(",").append(z) -+ .append("): shape1: ").append(isFull1).append(", shape2: ").append(isFull2); -+ } -+ } -+ } -+ -+ return ret.isEmpty() ? null : ret.toString(); - } - -- public static net.minecraft.world.phys.AABB offsetX(final net.minecraft.world.phys.AABB box, final double dx) { -- return new net.minecraft.world.phys.AABB(box.minX + dx, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); -+ public static AABB offsetX(final AABB box, final double dx) { -+ return new AABB(box.minX + dx, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); - } - -- public static net.minecraft.world.phys.AABB offsetY(final net.minecraft.world.phys.AABB box, final double dy) { -- return new net.minecraft.world.phys.AABB(box.minX, box.minY + dy, box.minZ, box.maxX, box.maxY + dy, box.maxZ); -+ public static AABB offsetY(final AABB box, final double dy) { -+ return new AABB(box.minX, box.minY + dy, box.minZ, box.maxX, box.maxY + dy, box.maxZ); - } - -- public static net.minecraft.world.phys.AABB offsetZ(final net.minecraft.world.phys.AABB box, final double dz) { -- return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ + dz, box.maxX, box.maxY, box.maxZ + dz); -+ public static AABB offsetZ(final AABB box, final double dz) { -+ return new AABB(box.minX, box.minY, box.minZ + dz, box.maxX, box.maxY, box.maxZ + dz); - } - -- public static net.minecraft.world.phys.AABB expandRight(final net.minecraft.world.phys.AABB box, final double dx) { // dx > 0.0 -- return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); -+ public static AABB expandRight(final AABB box, final double dx) { // dx > 0.0 -+ return new AABB(box.minX, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); - } - -- public static net.minecraft.world.phys.AABB expandLeft(final net.minecraft.world.phys.AABB box, final double dx) { // dx < 0.0 -- return new net.minecraft.world.phys.AABB(box.minX - dx, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ); -+ public static AABB expandLeft(final AABB box, final double dx) { // dx < 0.0 -+ return new AABB(box.minX - dx, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ); - } - -- public static net.minecraft.world.phys.AABB expandUpwards(final net.minecraft.world.phys.AABB box, final double dy) { // dy > 0.0 -- return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ, box.maxX, box.maxY + dy, box.maxZ); -+ public static AABB expandUpwards(final AABB box, final double dy) { // dy > 0.0 -+ return new AABB(box.minX, box.minY, box.minZ, box.maxX, box.maxY + dy, box.maxZ); - } - -- public static net.minecraft.world.phys.AABB expandDownwards(final net.minecraft.world.phys.AABB box, final double dy) { // dy < 0.0 -- return new net.minecraft.world.phys.AABB(box.minX, box.minY - dy, box.minZ, box.maxX, box.maxY, box.maxZ); -+ public static AABB expandDownwards(final AABB box, final double dy) { // dy < 0.0 -+ return new AABB(box.minX, box.minY - dy, box.minZ, box.maxX, box.maxY, box.maxZ); - } - -- public static net.minecraft.world.phys.AABB expandForwards(final net.minecraft.world.phys.AABB box, final double dz) { // dz > 0.0 -- return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ + dz); -+ public static AABB expandForwards(final AABB box, final double dz) { // dz > 0.0 -+ return new AABB(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ + dz); - } - -- public static net.minecraft.world.phys.AABB expandBackwards(final net.minecraft.world.phys.AABB box, final double dz) { // dz < 0.0 -- return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ - dz, box.maxX, box.maxY, box.maxZ); -+ public static AABB expandBackwards(final AABB box, final double dz) { // dz < 0.0 -+ return new AABB(box.minX, box.minY, box.minZ - dz, box.maxX, box.maxY, box.maxZ); - } - -- public static net.minecraft.world.phys.AABB cutRight(final net.minecraft.world.phys.AABB box, final double dx) { // dx > 0.0 -- return new net.minecraft.world.phys.AABB(box.maxX, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); -+ public static AABB cutRight(final AABB box, final double dx) { // dx > 0.0 -+ return new AABB(box.maxX, box.minY, box.minZ, box.maxX + dx, box.maxY, box.maxZ); - } - -- public static net.minecraft.world.phys.AABB cutLeft(final net.minecraft.world.phys.AABB box, final double dx) { // dx < 0.0 -- return new net.minecraft.world.phys.AABB(box.minX + dx, box.minY, box.minZ, box.minX, box.maxY, box.maxZ); -+ public static AABB cutLeft(final AABB box, final double dx) { // dx < 0.0 -+ return new AABB(box.minX + dx, box.minY, box.minZ, box.minX, box.maxY, box.maxZ); - } - -- public static net.minecraft.world.phys.AABB cutUpwards(final net.minecraft.world.phys.AABB box, final double dy) { // dy > 0.0 -- return new net.minecraft.world.phys.AABB(box.minX, box.maxY, box.minZ, box.maxX, box.maxY + dy, box.maxZ); -+ public static AABB cutUpwards(final AABB box, final double dy) { // dy > 0.0 -+ return new AABB(box.minX, box.maxY, box.minZ, box.maxX, box.maxY + dy, box.maxZ); - } - -- public static net.minecraft.world.phys.AABB cutDownwards(final net.minecraft.world.phys.AABB box, final double dy) { // dy < 0.0 -- return new net.minecraft.world.phys.AABB(box.minX, box.minY + dy, box.minZ, box.maxX, box.minY, box.maxZ); -+ public static AABB cutDownwards(final AABB box, final double dy) { // dy < 0.0 -+ return new AABB(box.minX, box.minY + dy, box.minZ, box.maxX, box.minY, box.maxZ); - } - -- public static net.minecraft.world.phys.AABB cutForwards(final net.minecraft.world.phys.AABB box, final double dz) { // dz > 0.0 -- return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.maxZ, box.maxX, box.maxY, box.maxZ + dz); -+ public static AABB cutForwards(final AABB box, final double dz) { // dz > 0.0 -+ return new AABB(box.minX, box.minY, box.maxZ, box.maxX, box.maxY, box.maxZ + dz); - } - -- public static net.minecraft.world.phys.AABB cutBackwards(final net.minecraft.world.phys.AABB box, final double dz) { // dz < 0.0 -- return new net.minecraft.world.phys.AABB(box.minX, box.minY, box.minZ + dz, box.maxX, box.maxY, box.minZ); -+ public static AABB cutBackwards(final AABB box, final double dz) { // dz < 0.0 -+ return new AABB(box.minX, box.minY, box.minZ + dz, box.maxX, box.maxY, box.minZ); - } - -- public static double performAABBCollisionsX(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { -+ public static double performAABBCollisionsX(final AABB currentBoundingBox, double value, final List potentialCollisions) { - for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { - if (Math.abs(value) < COLLISION_EPSILON) { - return 0.0; - } -- final net.minecraft.world.phys.AABB target = potentialCollisions.get(i); -+ final AABB target = potentialCollisions.get(i); - value = collideX(target, currentBoundingBox, value); - } - -- return value; -+ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; - } - -- public static double performAABBCollisionsY(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { -+ public static double performAABBCollisionsY(final AABB currentBoundingBox, double value, final List potentialCollisions) { - for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { - if (Math.abs(value) < COLLISION_EPSILON) { - return 0.0; - } -- final net.minecraft.world.phys.AABB target = potentialCollisions.get(i); -+ final AABB target = potentialCollisions.get(i); - value = collideY(target, currentBoundingBox, value); - } - -- return value; -+ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; - } - -- public static double performAABBCollisionsZ(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { -+ public static double performAABBCollisionsZ(final AABB currentBoundingBox, double value, final List potentialCollisions) { - for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { - if (Math.abs(value) < COLLISION_EPSILON) { - return 0.0; - } -- final net.minecraft.world.phys.AABB target = potentialCollisions.get(i); -+ final AABB target = potentialCollisions.get(i); - value = collideZ(target, currentBoundingBox, value); - } - -- return value; -+ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; - } - -- public static double performVoxelCollisionsX(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { -+ public static double performVoxelCollisionsX(final AABB currentBoundingBox, double value, final List potentialCollisions) { - for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { - if (Math.abs(value) < COLLISION_EPSILON) { - return 0.0; - } -- final net.minecraft.world.phys.shapes.VoxelShape target = potentialCollisions.get(i); -+ final VoxelShape target = potentialCollisions.get(i); - value = collideX(target, currentBoundingBox, value); - } - -- return value; -+ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; - } - -- public static double performVoxelCollisionsY(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { -+ public static double performVoxelCollisionsY(final AABB currentBoundingBox, double value, final List potentialCollisions) { - for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { - if (Math.abs(value) < COLLISION_EPSILON) { - return 0.0; - } -- final net.minecraft.world.phys.shapes.VoxelShape target = potentialCollisions.get(i); -+ final VoxelShape target = potentialCollisions.get(i); - value = collideY(target, currentBoundingBox, value); - } - -- return value; -+ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; - } - -- public static double performVoxelCollisionsZ(final net.minecraft.world.phys.AABB currentBoundingBox, double value, final java.util.List potentialCollisions) { -+ public static double performVoxelCollisionsZ(final AABB currentBoundingBox, double value, final List potentialCollisions) { - for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { - if (Math.abs(value) < COLLISION_EPSILON) { - return 0.0; - } -- final net.minecraft.world.phys.shapes.VoxelShape target = potentialCollisions.get(i); -+ final VoxelShape target = potentialCollisions.get(i); - value = collideZ(target, currentBoundingBox, value); - } - -- return value; -+ return Math.abs(value) < COLLISION_EPSILON ? 0.0 : value; - } - -- public static net.minecraft.world.phys.Vec3 performVoxelCollisions(final net.minecraft.world.phys.Vec3 moveVector, net.minecraft.world.phys.AABB axisalignedbb, final java.util.List potentialCollisions) { -+ public static Vec3 performVoxelCollisions(final Vec3 moveVector, AABB axisalignedbb, final List potentialCollisions) { - double x = moveVector.x; - double y = moveVector.y; - double z = moveVector.z; -@@ -1459,10 +1795,10 @@ public final class CollisionUtil { - z = performVoxelCollisionsZ(axisalignedbb, z, potentialCollisions); - } - -- return new net.minecraft.world.phys.Vec3(x, y, z); -+ return new Vec3(x, y, z); - } - -- public static net.minecraft.world.phys.Vec3 performAABBCollisions(final net.minecraft.world.phys.Vec3 moveVector, net.minecraft.world.phys.AABB axisalignedbb, final java.util.List potentialCollisions) { -+ public static Vec3 performAABBCollisions(final Vec3 moveVector, AABB axisalignedbb, final List potentialCollisions) { - double x = moveVector.x; - double y = moveVector.y; - double z = moveVector.z; -@@ -1494,12 +1830,12 @@ public final class CollisionUtil { - z = performAABBCollisionsZ(axisalignedbb, z, potentialCollisions); - } - -- return new net.minecraft.world.phys.Vec3(x, y, z); -+ return new Vec3(x, y, z); - } - -- public static net.minecraft.world.phys.Vec3 performCollisions(final net.minecraft.world.phys.Vec3 moveVector, net.minecraft.world.phys.AABB axisalignedbb, -- final java.util.List voxels, -- final java.util.List aabbs) { -+ public static Vec3 performCollisions(final Vec3 moveVector, AABB axisalignedbb, -+ final List voxels, -+ final List aabbs) { - if (voxels.isEmpty()) { - // fast track only AABBs - return performAABBCollisions(moveVector, axisalignedbb, aabbs); -@@ -1540,14 +1876,14 @@ public final class CollisionUtil { - z = performVoxelCollisionsZ(axisalignedbb, z, voxels); - } - -- return new net.minecraft.world.phys.Vec3(x, y, z); -+ return new Vec3(x, y, z); - } - -- public static boolean isCollidingWithBorder(final net.minecraft.world.level.border.WorldBorder worldborder, final net.minecraft.world.phys.AABB boundingBox) { -+ public static boolean isCollidingWithBorder(final WorldBorder worldborder, final AABB boundingBox) { - return isCollidingWithBorder(worldborder, boundingBox.minX, boundingBox.maxX, boundingBox.minZ, boundingBox.maxZ); - } - -- public static boolean isCollidingWithBorder(final net.minecraft.world.level.border.WorldBorder worldborder, -+ public static boolean isCollidingWithBorder(final WorldBorder worldborder, - final double boxMinX, final double boxMaxX, - final double boxMinZ, final double boxMaxZ) { - final double borderMinX = Math.floor(worldborder.getMinX()); // -X -@@ -1557,8 +1893,8 @@ public final class CollisionUtil { - final double borderMaxZ = Math.ceil(worldborder.getMaxZ()); // +Z - - // inverted check for world border enclosing the specified box expanded by -EPSILON -- return (borderMinX - boxMinX) > ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON || (borderMaxX - boxMaxX) < -ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON || -- (borderMinZ - boxMinZ) > ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON || (borderMaxZ - boxMaxZ) < -ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON; -+ return (borderMinX - boxMinX) > CollisionUtil.COLLISION_EPSILON || (borderMaxX - boxMaxX) < -CollisionUtil.COLLISION_EPSILON || -+ (borderMinZ - boxMinZ) > CollisionUtil.COLLISION_EPSILON || (borderMaxZ - boxMaxZ) < -CollisionUtil.COLLISION_EPSILON; - } - - /* Math.max/min specify that any NaN argument results in a NaN return, unlike these functions */ -@@ -1575,38 +1911,38 @@ public final class CollisionUtil { - public static final int COLLISION_FLAG_CHECK_BORDER = 1 << 2; - public static final int COLLISION_FLAG_CHECK_ONLY = 1 << 3; - -- public static boolean getCollisionsForBlocksOrWorldBorder(final net.minecraft.world.level.Level world, final net.minecraft.world.entity.Entity entity, final net.minecraft.world.phys.AABB aabb, -- final java.util.List intoVoxel, final java.util.List intoAABB, -- final int collisionFlags, final java.util.function.BiPredicate predicate) { -+ public static boolean getCollisionsForBlocksOrWorldBorder(final Level world, final Entity entity, final AABB aabb, -+ final List intoVoxel, final List intoAABB, -+ final int collisionFlags, final BiPredicate predicate) { - final boolean checkOnly = (collisionFlags & COLLISION_FLAG_CHECK_ONLY) != 0; - boolean ret = false; - - if ((collisionFlags & COLLISION_FLAG_CHECK_BORDER) != 0) { -- final net.minecraft.world.level.border.WorldBorder worldBorder = world.getWorldBorder(); -- if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isCollidingWithBorder(worldBorder, aabb) && entity != null && worldBorder.isInsideCloseToBorder(entity, aabb)) { -+ final WorldBorder worldBorder = world.getWorldBorder(); -+ if (CollisionUtil.isCollidingWithBorder(worldBorder, aabb) && entity != null && worldBorder.isInsideCloseToBorder(entity, aabb)) { - if (checkOnly) { - return true; - } else { -- final net.minecraft.world.phys.shapes.VoxelShape borderShape = worldBorder.getCollisionShape(); -+ final VoxelShape borderShape = worldBorder.getCollisionShape(); - intoVoxel.add(borderShape); - ret = true; - } - } - } - -- final int minSection = ((ca.spottedleaf.moonrise.patches.collisions.world.CollisionLevel)world).moonrise$getMinSection(); -+ final int minSection = WorldUtil.getMinSection(world); - -- final int minBlockX = net.minecraft.util.Mth.floor(aabb.minX - COLLISION_EPSILON) - 1; -- final int maxBlockX = net.minecraft.util.Mth.floor(aabb.maxX + COLLISION_EPSILON) + 1; -+ final int minBlockX = Mth.floor(aabb.minX - COLLISION_EPSILON) - 1; -+ final int maxBlockX = Mth.floor(aabb.maxX + COLLISION_EPSILON) + 1; - -- final int minBlockY = Math.max((minSection << 4) - 1, net.minecraft.util.Mth.floor(aabb.minY - COLLISION_EPSILON) - 1); -- final int maxBlockY = Math.min((((ca.spottedleaf.moonrise.patches.collisions.world.CollisionLevel)world).moonrise$getMaxSection() << 4) + 16, net.minecraft.util.Mth.floor(aabb.maxY + COLLISION_EPSILON) + 1); -+ final int minBlockY = Math.max((minSection << 4) - 1, Mth.floor(aabb.minY - COLLISION_EPSILON) - 1); -+ final int maxBlockY = Math.min((WorldUtil.getMaxSection(world) << 4) + 16, Mth.floor(aabb.maxY + COLLISION_EPSILON) + 1); - -- final int minBlockZ = net.minecraft.util.Mth.floor(aabb.minZ - COLLISION_EPSILON) - 1; -- final int maxBlockZ = net.minecraft.util.Mth.floor(aabb.maxZ + COLLISION_EPSILON) + 1; -+ final int minBlockZ = Mth.floor(aabb.minZ - COLLISION_EPSILON) - 1; -+ final int maxBlockZ = Mth.floor(aabb.maxZ + COLLISION_EPSILON) + 1; - -- final net.minecraft.core.BlockPos.MutableBlockPos mutablePos = new net.minecraft.core.BlockPos.MutableBlockPos(); -- final net.minecraft.world.phys.shapes.CollisionContext collisionShape = new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext(entity); -+ final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); -+ final CollisionContext collisionShape = new LazyEntityCollisionContext(entity); - - // special cases: - if (minBlockY > maxBlockY) { -@@ -1624,11 +1960,11 @@ public final class CollisionUtil { - final int maxChunkZ = maxBlockZ >> 4; - - final boolean loadChunks = (collisionFlags & COLLISION_FLAG_LOAD_CHUNKS) != 0; -- final net.minecraft.world.level.chunk.ChunkSource chunkSource = world.getChunkSource(); -+ final ChunkSource chunkSource = world.getChunkSource(); - - for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { - for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { -- final net.minecraft.world.level.chunk.ChunkAccess chunk = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, loadChunks); -+ final ChunkAccess chunk = chunkSource.getChunk(currChunkX, currChunkZ, ChunkStatus.FULL, loadChunks); - - if (chunk == null) { - if ((collisionFlags & COLLISION_FLAG_COLLIDE_WITH_UNLOADED_CHUNKS) != 0) { -@@ -1642,7 +1978,7 @@ public final class CollisionUtil { - continue; - } - -- final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections(); -+ final LevelChunkSection[] sections = chunk.getSections(); - - // bound y - for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) { -@@ -1650,16 +1986,16 @@ public final class CollisionUtil { - if (sectionIdx < 0 || sectionIdx >= sections.length) { - continue; - } -- final net.minecraft.world.level.chunk.LevelChunkSection section = sections[sectionIdx]; -- if (section == null || section.hasOnlyAir()) { -+ final LevelChunkSection section = sections[sectionIdx]; -+ if (section.hasOnlyAir()) { - // empty - continue; - } - -- final boolean hasSpecial = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$getSpecialCollidingBlocks() != 0; -+ final boolean hasSpecial = ((BlockCountingChunkSection)section).moonrise$hasSpecialCollidingBlocks(); - final int sectionAdjust = !hasSpecial ? 1 : 0; - -- final net.minecraft.world.level.chunk.PalettedContainer blocks = section.states; -+ final PalettedContainer blocks = section.states; - - final int minXIterate = currChunkX == minChunkX ? (minBlockX & 15) + sectionAdjust : 0; - final int maxXIterate = currChunkX == maxChunkX ? (maxBlockX & 15) - sectionAdjust : 15; -@@ -1683,21 +2019,21 @@ public final class CollisionUtil { - continue; - } - -- final net.minecraft.world.level.block.state.BlockState blockData = blocks.get(localBlockIndex); -+ final BlockState blockData = blocks.get(localBlockIndex); - -- if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockData).moonrise$emptyCollisionShape()) { -+ if (((CollisionBlockState)blockData).moonrise$emptyContextCollisionShape()) { - continue; - } - -- net.minecraft.world.phys.shapes.VoxelShape blockCollision = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockData).moonrise$getConstantCollisionShape(); -+ VoxelShape blockCollision = ((CollisionBlockState)blockData).moonrise$getConstantContextCollisionShape(); - -- if (edgeCount == 0 || ((edgeCount != 1 || blockData.hasLargeCollisionShape()) && (edgeCount != 2 || blockData.getBlock() == net.minecraft.world.level.block.Blocks.MOVING_PISTON))) { -+ if (edgeCount == 0 || ((edgeCount != 1 || blockData.hasLargeCollisionShape()) && (edgeCount != 2 || blockData.getBlock() == Blocks.MOVING_PISTON))) { - if (blockCollision == null) { - mutablePos.set(blockX, blockY, blockZ); - blockCollision = blockData.getCollisionShape(world, mutablePos, collisionShape); - } - -- net.minecraft.world.phys.AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation(); -+ AABB singleAABB = ((CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation(); - if (singleAABB != null) { - singleAABB = singleAABB.move((double)blockX, (double)blockY, (double)blockZ); - if (!voxelShapeIntersect(aabb, singleAABB)) { -@@ -1724,7 +2060,7 @@ public final class CollisionUtil { - continue; - } - -- final net.minecraft.world.phys.shapes.VoxelShape blockCollisionOffset = blockCollision.move((double)blockX, (double)blockY, (double)blockZ); -+ final VoxelShape blockCollisionOffset = blockCollision.move((double)blockX, (double)blockY, (double)blockZ); - - if (!voxelShapeIntersectNoEmpty(blockCollisionOffset, aabb)) { - continue; -@@ -1755,8 +2091,8 @@ public final class CollisionUtil { - return ret; - } - -- public static boolean getEntityHardCollisions(final net.minecraft.world.level.Level world, final net.minecraft.world.entity.Entity entity, net.minecraft.world.phys.AABB aabb, -- final java.util.List into, final int collisionFlags, final java.util.function.Predicate predicate) { -+ public static boolean getEntityHardCollisions(final Level world, final Entity entity, AABB aabb, -+ final List into, final int collisionFlags, final Predicate predicate) { - final boolean checkOnly = (collisionFlags & COLLISION_FLAG_CHECK_ONLY) != 0; - - boolean ret = false; -@@ -1765,15 +2101,15 @@ public final class CollisionUtil { - // Vanilla for hard collisions has this backwards, and they expand by +epsilon but this causes terrible problems - // specifically with boat collisions. - aabb = aabb.inflate(-COLLISION_EPSILON, -COLLISION_EPSILON, -COLLISION_EPSILON); -- final java.util.List entities; -- if (entity != null && ((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)entity).moonrise$isHardColliding()) { -+ final List entities; -+ if (entity != null && ((ChunkSystemEntity)entity).moonrise$isHardColliding()) { - entities = world.getEntities(entity, aabb, predicate); - } else { -- entities = ((ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemEntityGetter)world).moonrise$getHardCollidingEntities(entity, aabb, predicate); -+ entities = ((ChunkSystemEntityGetter)world).moonrise$getHardCollidingEntities(entity, aabb, predicate); - } - - for (int i = 0, len = entities.size(); i < len; ++i) { -- final net.minecraft.world.entity.Entity otherEntity = entities.get(i); -+ final Entity otherEntity = entities.get(i); - - if (otherEntity.isSpectator()) { - continue; -@@ -1792,10 +2128,10 @@ public final class CollisionUtil { - return ret; - } - -- public static boolean getCollisions(final net.minecraft.world.level.Level world, final net.minecraft.world.entity.Entity entity, final net.minecraft.world.phys.AABB aabb, -- final java.util.List intoVoxel, final java.util.List intoAABB, final int collisionFlags, -- final java.util.function.BiPredicate blockPredicate, -- final java.util.function.Predicate entityPredicate) { -+ public static boolean getCollisions(final Level world, final Entity entity, final AABB aabb, -+ final List intoVoxel, final List intoAABB, final int collisionFlags, -+ final BiPredicate blockPredicate, -+ final Predicate entityPredicate) { - if ((collisionFlags & COLLISION_FLAG_CHECK_ONLY) != 0) { - return getCollisionsForBlocksOrWorldBorder(world, entity, aabb, intoVoxel, intoAABB, collisionFlags, blockPredicate) - || getEntityHardCollisions(world, entity, aabb, intoAABB, collisionFlags, entityPredicate); -@@ -1805,12 +2141,12 @@ public final class CollisionUtil { - } - } - -- public static final class LazyEntityCollisionContext extends net.minecraft.world.phys.shapes.EntityCollisionContext { -+ public static final class LazyEntityCollisionContext extends EntityCollisionContext { - -- private net.minecraft.world.phys.shapes.CollisionContext delegate; -+ private CollisionContext delegate; - private boolean delegated; - -- public LazyEntityCollisionContext(final net.minecraft.world.entity.Entity entity) { -+ public LazyEntityCollisionContext(final Entity entity) { - super(false, 0.0, null, null, entity); - } - -@@ -1820,10 +2156,10 @@ public final class CollisionUtil { - return delegated; - } - -- public net.minecraft.world.phys.shapes.CollisionContext getDelegate() { -+ public CollisionContext getDelegate() { - this.delegated = true; -- final net.minecraft.world.entity.Entity entity = this.getEntity(); -- return this.delegate == null ? this.delegate = (entity == null ? net.minecraft.world.phys.shapes.CollisionContext.empty() : net.minecraft.world.phys.shapes.CollisionContext.of(entity)) : this.delegate; -+ final Entity entity = this.getEntity(); -+ return this.delegate == null ? this.delegate = (entity == null ? CollisionContext.empty() : CollisionContext.of(entity)) : this.delegate; - } - - @Override -@@ -1832,17 +2168,17 @@ public final class CollisionUtil { - } - - @Override -- public boolean isAbove(final net.minecraft.world.phys.shapes.VoxelShape shape, final net.minecraft.core.BlockPos pos, final boolean defaultValue) { -+ public boolean isAbove(final VoxelShape shape, final BlockPos pos, final boolean defaultValue) { - return this.getDelegate().isAbove(shape, pos, defaultValue); - } - - @Override -- public boolean isHoldingItem(final net.minecraft.world.item.Item item) { -+ public boolean isHoldingItem(final Item item) { - return this.getDelegate().isHoldingItem(item); - } - - @Override -- public boolean canStandOnFluid(final net.minecraft.world.level.material.FluidState state, final net.minecraft.world.level.material.FluidState fluidState) { -+ public boolean canStandOnFluid(final FluidState state, final FluidState fluidState) { - return this.getDelegate().canStandOnFluid(state, fluidState); - } - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/ExplosionBlockCache.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/ExplosionBlockCache.java -index eb7200657d5c7ac37ee93868ba43be0aefecac6d..35c8aaf0bfa42717f45eed1d1072e1614874de91 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/ExplosionBlockCache.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/ExplosionBlockCache.java -@@ -1,18 +1,23 @@ - package ca.spottedleaf.moonrise.patches.collisions; - -+import net.minecraft.core.BlockPos; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.level.material.FluidState; -+import net.minecraft.world.phys.shapes.VoxelShape; -+ - public final class ExplosionBlockCache { - - public final long key; -- public final net.minecraft.core.BlockPos immutablePos; -- public final net.minecraft.world.level.block.state.BlockState blockState; -- public final net.minecraft.world.level.material.FluidState fluidState; -+ public final BlockPos immutablePos; -+ public final BlockState blockState; -+ public final FluidState fluidState; - public final float resistance; - public final boolean outOfWorld; - public Boolean shouldExplode; // null -> not called yet -- public net.minecraft.world.phys.shapes.VoxelShape cachedCollisionShape; -+ public VoxelShape cachedCollisionShape; - -- public ExplosionBlockCache(final long key, final net.minecraft.core.BlockPos immutablePos, final net.minecraft.world.level.block.state.BlockState blockState, -- final net.minecraft.world.level.material.FluidState fluidState, final float resistance, final boolean outOfWorld) { -+ public ExplosionBlockCache(final long key, final BlockPos immutablePos, final BlockState blockState, -+ final FluidState fluidState, final float resistance, final boolean outOfWorld) { - this.key = key; - this.immutablePos = immutablePos; - this.blockState = blockState; -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/block/CollisionBlockState.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/block/CollisionBlockState.java -index 02b29c563a298e06186de010de68a716bccba494..a38ab583200ebf68ca68fdddf2d12077720b72b7 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/block/CollisionBlockState.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/block/CollisionBlockState.java -@@ -1,5 +1,7 @@ - package ca.spottedleaf.moonrise.patches.collisions.block; - -+import net.minecraft.world.phys.shapes.VoxelShape; -+ - public interface CollisionBlockState { - - // note: this does not consider canOcclude, it is only based on the cached collision shape (i.e hasCache()) -@@ -9,6 +11,9 @@ public interface CollisionBlockState { - // whether the cached collision shape exists and is empty - public boolean moonrise$emptyCollisionShape(); - -+ // whether the context-sensitive shape is constant and is empty -+ public boolean moonrise$emptyContextCollisionShape(); -+ - // indicates that occludesFullBlock is cached for the collision shape - public boolean moonrise$hasCache(); - -@@ -20,7 +25,5 @@ public interface CollisionBlockState { - // value is still unique - public int moonrise$uniqueId2(); - -- public net.minecraft.world.phys.shapes.VoxelShape moonrise$getConstantCollisionShape(); -- -- public net.minecraft.world.phys.AABB moonrise$getConstantCollisionAABB(); -+ public VoxelShape moonrise$getConstantContextCollisionShape(); - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CachedToAABBs.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CachedToAABBs.java -index 5fe1dad9dad368911aedbe6ba7fcd8f9b0189d32..9d33ead3a97d86b371e4d9ad9fed80d789bed844 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CachedToAABBs.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CachedToAABBs.java -@@ -1,27 +1,31 @@ - package ca.spottedleaf.moonrise.patches.collisions.shape; - -+import net.minecraft.world.phys.AABB; -+import java.util.ArrayList; -+import java.util.List; -+ - public record CachedToAABBs( -- java.util.List aabbs, -+ List aabbs, - boolean isOffset, - double offX, double offY, double offZ - ) { - -- public ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs removeOffset() { -- final java.util.List toOffset = this.aabbs; -+ public CachedToAABBs removeOffset() { -+ final List toOffset = this.aabbs; - final double offX = this.offX; - final double offY = this.offY; - final double offZ = this.offZ; - -- final java.util.List ret = new java.util.ArrayList<>(toOffset.size()); -+ final List ret = new ArrayList<>(toOffset.size()); - - for (int i = 0, len = toOffset.size(); i < len; ++i) { - ret.add(toOffset.get(i).move(offX, offY, offZ)); - } - -- return new ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs(ret, false, 0.0, 0.0, 0.0); -+ return new CachedToAABBs(ret, false, 0.0, 0.0, 0.0); - } - -- public static ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs offset(final ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs cache, final double offX, final double offY, final double offZ) { -+ public static CachedToAABBs offset(final CachedToAABBs cache, final double offX, final double offY, final double offZ) { - if (offX == 0.0 && offY == 0.0 && offZ == 0.0) { - return cache; - } -@@ -30,6 +34,6 @@ public record CachedToAABBs( - final double resY = cache.offY + offY; - final double resZ = cache.offZ + offZ; - -- return new ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs(cache.aabbs, true, resX, resY, resZ); -+ return new CachedToAABBs(cache.aabbs, true, resX, resY, resZ); - } - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionDiscreteVoxelShape.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionDiscreteVoxelShape.java -index a09efadea9b733840bbe69830dd8f2a303fe656f..07fe5e02c2d0a27d2fe37bb45761654dc2d02e5d 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionDiscreteVoxelShape.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionDiscreteVoxelShape.java -@@ -2,6 +2,6 @@ package ca.spottedleaf.moonrise.patches.collisions.shape; - - public interface CollisionDiscreteVoxelShape { - -- public ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData moonrise$getOrCreateCachedShapeData(); -+ public CachedShapeData moonrise$getOrCreateCachedShapeData(); - - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionVoxelShape.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionVoxelShape.java -index 70371eb87c11a106e8513cdbc8d938dda088f745..05d7b3f9d8659c259f3ed0537c57e6e43eb6e288 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionVoxelShape.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/CollisionVoxelShape.java -@@ -1,5 +1,9 @@ - package ca.spottedleaf.moonrise.patches.collisions.shape; - -+import net.minecraft.core.Direction; -+import net.minecraft.world.phys.AABB; -+import net.minecraft.world.phys.shapes.VoxelShape; -+ - public interface CollisionVoxelShape { - - public double moonrise$offsetX(); -@@ -14,16 +18,16 @@ public interface CollisionVoxelShape { - - public double[] moonrise$rootCoordinatesZ(); - -- public ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData moonrise$getCachedVoxelData(); -+ public CachedShapeData moonrise$getCachedVoxelData(); - - // rets null if not possible to represent this shape as one AABB -- public net.minecraft.world.phys.AABB moonrise$getSingleAABBRepresentation(); -+ public AABB moonrise$getSingleAABBRepresentation(); - - // ONLY USE INTERNALLY, ONLY FOR INITIALISING IN CONSTRUCTOR: VOXELSHAPES ARE STATIC - public void moonrise$initCache(); - - // this returns empty if not clamped to 1.0 or 0.0 depending on direction -- public net.minecraft.world.phys.shapes.VoxelShape moonrise$getFaceShapeClamped(final net.minecraft.core.Direction direction); -+ public VoxelShape moonrise$getFaceShapeClamped(final Direction direction); - - public boolean moonrise$isFullBlock(); - -@@ -32,5 +36,5 @@ public interface CollisionVoxelShape { - public boolean moonrise$occludesFullBlockIfCached(); - - // uses a cache internally -- public net.minecraft.world.phys.shapes.VoxelShape moonrise$orUnoptimized(final net.minecraft.world.phys.shapes.VoxelShape other); -+ public VoxelShape moonrise$orUnoptimized(final VoxelShape other); - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/MergedORCache.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/MergedORCache.java -index 4217426d3eca5e5cd2bc37e509f84da1d6fed0b2..44831fc18efb7534dc6e4822f3c9b5cdc4dcc33e 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/MergedORCache.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/shape/MergedORCache.java -@@ -1,8 +1,10 @@ - package ca.spottedleaf.moonrise.patches.collisions.shape; - -+import net.minecraft.world.phys.shapes.VoxelShape; -+ - public record MergedORCache( -- net.minecraft.world.phys.shapes.VoxelShape key, -- net.minecraft.world.phys.shapes.VoxelShape result -+ VoxelShape key, -+ VoxelShape result - ) { - - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/EmptyStreamForMoveCall.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/EmptyStreamForMoveCall.java -deleted file mode 100644 -index 673103f160cbe577c6e05f998706af4e6850011b..0000000000000000000000000000000000000000 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/EmptyStreamForMoveCall.java -+++ /dev/null -@@ -1,225 +0,0 @@ --package ca.spottedleaf.moonrise.patches.collisions.util; -- --import java.util.Iterator; --import java.util.Optional; --import java.util.Spliterator; --import java.util.stream.Stream; -- --public final class EmptyStreamForMoveCall implements java.util.stream.Stream { -- -- public static final ca.spottedleaf.moonrise.patches.collisions.util.EmptyStreamForMoveCall INSTANCE = new ca.spottedleaf.moonrise.patches.collisions.util.EmptyStreamForMoveCall(); -- -- @Override -- public boolean noneMatch(java.util.function.Predicate predicate) { -- return false; // important: ret false so the branch is never taken by mojang code -- } -- -- @Override -- public java.util.stream.Stream filter(java.util.function.Predicate predicate) { -- return null; -- } -- -- @Override -- public java.util.stream.Stream map(java.util.function.Function mapper) { -- return null; -- } -- -- @Override -- public java.util.stream.IntStream mapToInt(java.util.function.ToIntFunction mapper) { -- return null; -- } -- -- @Override -- public java.util.stream.LongStream mapToLong(java.util.function.ToLongFunction mapper) { -- return null; -- } -- -- @Override -- public java.util.stream.DoubleStream mapToDouble(java.util.function.ToDoubleFunction mapper) { -- return null; -- } -- -- @Override -- public java.util.stream.Stream flatMap(java.util.function.Function> mapper) { -- return null; -- } -- -- @Override -- public java.util.stream.IntStream flatMapToInt(java.util.function.Function mapper) { -- return null; -- } -- -- @Override -- public java.util.stream.LongStream flatMapToLong(java.util.function.Function mapper) { -- return null; -- } -- -- @Override -- public java.util.stream.DoubleStream flatMapToDouble(java.util.function.Function mapper) { -- return null; -- } -- -- @Override -- public java.util.stream.Stream distinct() { -- return null; -- } -- -- @Override -- public java.util.stream.Stream sorted() { -- return null; -- } -- -- @Override -- public java.util.stream.Stream sorted(java.util.Comparator comparator) { -- return null; -- } -- -- @Override -- public java.util.stream.Stream peek(java.util.function.Consumer action) { -- return null; -- } -- -- @Override -- public java.util.stream.Stream limit(long maxSize) { -- return null; -- } -- -- @Override -- public java.util.stream.Stream skip(long n) { -- return null; -- } -- -- @Override -- public void forEach(java.util.function.Consumer action) { -- -- } -- -- @Override -- public void forEachOrdered(java.util.function.Consumer action) { -- -- } -- -- @org.jetbrains.annotations.NotNull -- @Override -- public Object[] toArray() { -- return new Object[0]; -- } -- -- @org.jetbrains.annotations.NotNull -- @Override -- public
    A[] toArray(java.util.function.IntFunction generator) { -- return null; -- } -- -- @Override -- public T reduce(T identity, java.util.function.BinaryOperator accumulator) { -- return null; -- } -- -- @org.jetbrains.annotations.NotNull -- @Override -- public Optional reduce(java.util.function.BinaryOperator accumulator) { -- return java.util.Optional.empty(); -- } -- -- @Override -- public U reduce(U identity, java.util.function.BiFunction accumulator, java.util.function.BinaryOperator combiner) { -- return null; -- } -- -- @Override -- public R collect(java.util.function.Supplier supplier, java.util.function.BiConsumer accumulator, java.util.function.BiConsumer combiner) { -- return null; -- } -- -- @Override -- public R collect(java.util.stream.Collector collector) { -- return null; -- } -- -- @org.jetbrains.annotations.NotNull -- @Override -- public Optional min(java.util.Comparator comparator) { -- return java.util.Optional.empty(); -- } -- -- @org.jetbrains.annotations.NotNull -- @Override -- public Optional max(java.util.Comparator comparator) { -- return java.util.Optional.empty(); -- } -- -- @Override -- public long count() { -- return 0; -- } -- -- @Override -- public boolean anyMatch(java.util.function.Predicate predicate) { -- return false; -- } -- -- @Override -- public boolean allMatch(java.util.function.Predicate predicate) { -- return false; -- } -- -- @org.jetbrains.annotations.NotNull -- @Override -- public Optional findFirst() { -- return java.util.Optional.empty(); -- } -- -- @org.jetbrains.annotations.NotNull -- @Override -- public Optional findAny() { -- return java.util.Optional.empty(); -- } -- -- -- @org.jetbrains.annotations.NotNull -- @Override -- public Iterator iterator() { -- return null; -- } -- -- @org.jetbrains.annotations.NotNull -- @Override -- public Spliterator spliterator() { -- return null; -- } -- -- @Override -- public boolean isParallel() { -- return false; -- } -- -- @org.jetbrains.annotations.NotNull -- @Override -- public Stream sequential() { -- return null; -- } -- -- @org.jetbrains.annotations.NotNull -- @Override -- public Stream parallel() { -- return null; -- } -- -- @org.jetbrains.annotations.NotNull -- @Override -- public Stream unordered() { -- return null; -- } -- -- @org.jetbrains.annotations.NotNull -- @Override -- public Stream onClose(Runnable closeHandler) { -- return null; -- } -- -- @Override -- public void close() { -- -- } --} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java -index 128267ff40b38c7b3ea0feb5133825cc6aae075b..cf9ffdeff6bf0b62a45f7a44dbfe0dd7d17dc4f4 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/util/FluidOcclusionCacheKey.java -@@ -1,4 +1,7 @@ - package ca.spottedleaf.moonrise.patches.collisions.util; - --public record FluidOcclusionCacheKey(net.minecraft.world.level.block.state.BlockState first, net.minecraft.world.level.block.state.BlockState second, net.minecraft.core.Direction direction, boolean result) { -+import net.minecraft.core.Direction; -+import net.minecraft.world.level.block.state.BlockState; -+ -+public record FluidOcclusionCacheKey(BlockState first, BlockState second, Direction direction, boolean result) { - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/world/CollisionLevel.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/world/CollisionLevel.java -deleted file mode 100644 -index e851e81e13edbad6316df63fcb7095d48f85c5b0..0000000000000000000000000000000000000000 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/world/CollisionLevel.java -+++ /dev/null -@@ -1,9 +0,0 @@ --package ca.spottedleaf.moonrise.patches.collisions.world; -- --public interface CollisionLevel { -- -- public int moonrise$getMinSection(); -- -- public int moonrise$getMaxSection(); -- --} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerTrackedEntity.java b/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerTrackedEntity.java -index 1fa07bef57d82c6d5242aaaf66011f0913515231..8e7472157a98de607c03769a91f64c8369fd3ea6 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerTrackedEntity.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/entity_tracker/EntityTrackerTrackedEntity.java -@@ -10,4 +10,6 @@ public interface EntityTrackerTrackedEntity { - - public void moonrise$clearPlayers(); - -+ public boolean moonrise$hasPlayers(); -+ - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPalette.java b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPalette.java -new file mode 100644 -index 0000000000000000000000000000000000000000..4a7abd239a9c59aa98947e7993962d75e9051902 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPalette.java -@@ -0,0 +1,9 @@ -+package ca.spottedleaf.moonrise.patches.fast_palette; -+ -+public interface FastPalette { -+ -+ public default T[] moonrise$getRawPalette(final FastPaletteData src) { -+ return null; -+ } -+ -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPaletteData.java b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPaletteData.java -new file mode 100644 -index 0000000000000000000000000000000000000000..4503f3495846a7d7ed082b9e24636044e4fbccd1 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPaletteData.java -@@ -0,0 +1,9 @@ -+package ca.spottedleaf.moonrise.patches.fast_palette; -+ -+public interface FastPaletteData { -+ -+ public T[] moonrise$getPalette(); -+ -+ public void moonrise$setPalette(final T[] palette); -+ -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/fluid/FluidFluidState.java b/src/main/java/ca/spottedleaf/moonrise/patches/fluid/FluidFluidState.java -new file mode 100644 -index 0000000000000000000000000000000000000000..107c97089354edd35f330582f5e0c8a18e792a6e ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/fluid/FluidFluidState.java -@@ -0,0 +1,5 @@ -+package ca.spottedleaf.moonrise.patches.fluid; -+ -+public interface FluidFluidState { -+ public void moonrise$initCaches(); -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_getblock/GetBlockChunk.java b/src/main/java/ca/spottedleaf/moonrise/patches/getblock/GetBlockChunk.java -similarity index 75% -rename from src/main/java/ca/spottedleaf/moonrise/patches/chunk_getblock/GetBlockChunk.java -rename to src/main/java/ca/spottedleaf/moonrise/patches/getblock/GetBlockChunk.java -index 08338917dc61c856eaba0b76e05c1497c458399d..540c14a6d2c216cd3ef2a9c4056e15712bf8cb8c 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_getblock/GetBlockChunk.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/getblock/GetBlockChunk.java -@@ -1,4 +1,4 @@ --package ca.spottedleaf.moonrise.patches.chunk_getblock; -+package ca.spottedleaf.moonrise.patches.getblock; - - import net.minecraft.world.level.block.state.BlockState; - -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/blockstate/StarlightAbstractBlockState.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/blockstate/StarlightAbstractBlockState.java -index 2bfdf3721db9a45e36538d71cbefcb1d339e6c58..8e6d79b7c10ef25f5478b72c53c555423d615a2f 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/blockstate/StarlightAbstractBlockState.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/blockstate/StarlightAbstractBlockState.java -@@ -4,6 +4,4 @@ public interface StarlightAbstractBlockState { - - public boolean starlight$isConditionallyFullOpaque(); - -- public int starlight$getOpacityIfCached(); -- - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/BlockStarLightEngine.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/BlockStarLightEngine.java -index 154443ac1ee1d6d18b8ff0f40a307d638b213aeb..fa7b784a89626e8528c249d7889a598bd7ee3d49 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/BlockStarLightEngine.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/BlockStarLightEngine.java -@@ -1,8 +1,10 @@ - package ca.spottedleaf.moonrise.patches.starlight.light; - -+import ca.spottedleaf.moonrise.common.PlatformHooks; - import ca.spottedleaf.moonrise.patches.starlight.blockstate.StarlightAbstractBlockState; - import ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk; - import net.minecraft.core.BlockPos; -+import net.minecraft.world.level.BlockGetter; - import net.minecraft.world.level.Level; - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.chunk.ChunkAccess; -@@ -91,7 +93,7 @@ public final class BlockStarLightEngine extends StarLightEngine { - - final int currentLevel = this.getLightLevel(worldX, worldY, worldZ); - final BlockState blockState = this.getBlockState(worldX, worldY, worldZ); -- final int emittedLevel = blockState.getLightEmission() & emittedMask; -+ final int emittedLevel = (PlatformHooks.get().getLightEmission(blockState, lightAccess.getLevel(), this.lightEmissionPos.set(worldX, worldY, worldZ))) & emittedMask; - - this.setLightLevel(worldX, worldY, worldZ, emittedLevel); - // this accounts for change in emitted light that would cause an increase -@@ -119,37 +121,32 @@ public final class BlockStarLightEngine extends StarLightEngine { - } - - protected final BlockPos.MutableBlockPos recalcCenterPos = new BlockPos.MutableBlockPos(); -- protected final BlockPos.MutableBlockPos recalcNeighbourPos = new BlockPos.MutableBlockPos(); - - @Override - protected int calculateLightValue(final LightChunkGetter lightAccess, final int worldX, final int worldY, final int worldZ, - final int expect) { -+ this.recalcCenterPos.set(worldX, worldY, worldZ); -+ - final BlockState centerState = this.getBlockState(worldX, worldY, worldZ); -- int level = centerState.getLightEmission() & 0xF; -+ final BlockGetter world = lightAccess.getLevel(); -+ int level = (PlatformHooks.get().getLightEmission(centerState, world, this.recalcCenterPos)) & this.emittedLightMask; - - if (level >= (15 - 1) || level > expect) { - return level; - } - -- final int sectionOffset = this.chunkSectionIndexOffset; -- final BlockState conditionallyOpaqueState; -- int opacity = ((StarlightAbstractBlockState)centerState).starlight$getOpacityIfCached(); -- -- if (opacity == -1) { -- this.recalcCenterPos.set(worldX, worldY, worldZ); -- opacity = centerState.getLightBlock(lightAccess.getLevel(), this.recalcCenterPos); -- if (((StarlightAbstractBlockState)centerState).starlight$isConditionallyFullOpaque()) { -- conditionallyOpaqueState = centerState; -- } else { -- conditionallyOpaqueState = null; -- } -- } else if (opacity >= 15) { -+ final int opacity = Math.max(1, centerState.getLightBlock()); -+ if (opacity >= 15) { - return level; -+ } -+ final BlockState conditionallyOpaqueState; -+ if (((StarlightAbstractBlockState)centerState).starlight$isConditionallyFullOpaque()) { -+ conditionallyOpaqueState = centerState; - } else { - conditionallyOpaqueState = null; - } -- opacity = Math.max(1, opacity); - -+ final int sectionOffset = this.chunkSectionIndexOffset; - for (final AxisDirection direction : AXIS_DIRECTIONS) { - final int offX = worldX + direction.x; - final int offY = worldY + direction.y; -@@ -169,9 +166,8 @@ public final class BlockStarLightEngine extends StarLightEngine { - // here the block can be conditionally opaque (i.e light cannot propagate from it), so we need to test that - // we don't read the blockstate because most of the time this is false, so using the faster - // known transparency lookup results in a net win -- this.recalcNeighbourPos.set(offX, offY, offZ); -- final VoxelShape neighbourFace = neighbourState.getFaceOcclusionShape(lightAccess.getLevel(), this.recalcNeighbourPos, direction.opposite.nms); -- final VoxelShape thisFace = conditionallyOpaqueState == null ? Shapes.empty() : conditionallyOpaqueState.getFaceOcclusionShape(lightAccess.getLevel(), this.recalcCenterPos, direction.nms); -+ final VoxelShape neighbourFace = neighbourState.getFaceOcclusionShape(direction.opposite.nms); -+ final VoxelShape thisFace = conditionallyOpaqueState == null ? Shapes.empty() : conditionallyOpaqueState.getFaceOcclusionShape(direction.nms); - if (Shapes.faceShapeOccludes(thisFace, neighbourFace)) { - // not allowed to propagate - continue; -@@ -205,30 +201,34 @@ public final class BlockStarLightEngine extends StarLightEngine { - final int offX = chunk.getPos().x << 4; - final int offZ = chunk.getPos().z << 4; - -+ final PlatformHooks platformHooks = PlatformHooks.get(); -+ -+ final BlockGetter world = lightAccess.getLevel(); - final LevelChunkSection[] sections = chunk.getSections(); - for (int sectionY = this.minSection; sectionY <= this.maxSection; ++sectionY) { - final LevelChunkSection section = sections[sectionY - this.minSection]; -- if (section == null || section.hasOnlyAir()) { -+ if (section.hasOnlyAir()) { - // no sources in empty sections - continue; - } -- if (!section.maybeHas((final BlockState state) -> { -- return state.getLightEmission() > 0; -- })) { -+ if (!section.maybeHas(platformHooks.maybeHasLightEmission())) { - // no light sources in palette - continue; - } - final PalettedContainer states = section.states; - final int offY = sectionY << 4; - -+ final BlockPos.MutableBlockPos mutablePos = this.lightEmissionPos; - for (int index = 0; index < (16 * 16 * 16); ++index) { - final BlockState state = states.get(index); -- if (state.getLightEmission() <= 0) { -+ mutablePos.set(offX | (index & 15), offY | (index >>> 8), offZ | ((index >>> 4) & 15)); -+ -+ if ((platformHooks.getLightEmission(state, world, mutablePos)) == 0) { - continue; - } - - // index = x | (z << 4) | (y << 8) -- sources.add(new BlockPos(offX | (index & 15), offY | (index >>> 8), offZ | ((index >>> 4) & 15))); -+ sources.add(mutablePos.immutable()); - } - } - -@@ -238,12 +238,15 @@ public final class BlockStarLightEngine extends StarLightEngine { - @Override - public void lightChunk(final LightChunkGetter lightAccess, final ChunkAccess chunk, final boolean needsEdgeChecks) { - // setup sources -+ final BlockGetter world = lightAccess.getLevel(); -+ final PlatformHooks platformHooks = PlatformHooks.get(); -+ - final int emittedMask = this.emittedLightMask; - final List positions = this.getSources(lightAccess, chunk); - for (int i = 0, len = positions.size(); i < len; ++i) { - final BlockPos pos = positions.get(i); - final BlockState blockState = this.getBlockState(pos.getX(), pos.getY(), pos.getZ()); -- final int emittedLight = blockState.getLightEmission() & emittedMask; -+ final int emittedLight = platformHooks.getLightEmission(blockState, world, pos) & emittedMask; - - if (emittedLight <= this.getLightLevel(pos.getX(), pos.getY(), pos.getZ())) { - // some other source is brighter -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/SkyStarLightEngine.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/SkyStarLightEngine.java -index fdbc015f498164c9d2c578cd84a73def568142a4..f9aef289e9a2d6f63c98c72c56ef32b8793f57f4 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/SkyStarLightEngine.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/SkyStarLightEngine.java -@@ -290,9 +290,6 @@ public final class SkyStarLightEngine extends StarLightEngine { - ); - } - -- protected final BlockPos.MutableBlockPos recalcCenterPos = new BlockPos.MutableBlockPos(); -- protected final BlockPos.MutableBlockPos recalcNeighbourPos = new BlockPos.MutableBlockPos(); -- - @Override - protected int calculateLightValue(final LightChunkGetter lightAccess, final int worldX, final int worldY, final int worldZ, - final int expect) { -@@ -302,20 +299,13 @@ public final class SkyStarLightEngine extends StarLightEngine { - - final int sectionOffset = this.chunkSectionIndexOffset; - final BlockState centerState = this.getBlockState(worldX, worldY, worldZ); -- int opacity = ((StarlightAbstractBlockState)centerState).starlight$getOpacityIfCached(); - - final BlockState conditionallyOpaqueState; -- if (opacity < 0) { -- this.recalcCenterPos.set(worldX, worldY, worldZ); -- opacity = Math.max(1, centerState.getLightBlock(lightAccess.getLevel(), this.recalcCenterPos)); -- if (((StarlightAbstractBlockState)centerState).starlight$isConditionallyFullOpaque()) { -- conditionallyOpaqueState = centerState; -- } else { -- conditionallyOpaqueState = null; -- } -+ final int opacity = Math.max(1, centerState.getLightBlock()); -+ if (((StarlightAbstractBlockState)centerState).starlight$isConditionallyFullOpaque()) { -+ conditionallyOpaqueState = centerState; - } else { - conditionallyOpaqueState = null; -- opacity = Math.max(1, opacity); - } - - int level = 0; -@@ -340,9 +330,8 @@ public final class SkyStarLightEngine extends StarLightEngine { - // here the block can be conditionally opaque (i.e light cannot propagate from it), so we need to test that - // we don't read the blockstate because most of the time this is false, so using the faster - // known transparency lookup results in a net win -- this.recalcNeighbourPos.set(offX, offY, offZ); -- final VoxelShape neighbourFace = neighbourState.getFaceOcclusionShape(lightAccess.getLevel(), this.recalcNeighbourPos, direction.opposite.nms); -- final VoxelShape thisFace = conditionallyOpaqueState == null ? Shapes.empty() : conditionallyOpaqueState.getFaceOcclusionShape(lightAccess.getLevel(), this.recalcCenterPos, direction.nms); -+ final VoxelShape neighbourFace = neighbourState.getFaceOcclusionShape(direction.opposite.nms); -+ final VoxelShape thisFace = conditionallyOpaqueState == null ? Shapes.empty() : conditionallyOpaqueState.getFaceOcclusionShape(direction.nms); - if (Shapes.faceShapeOccludes(thisFace, neighbourFace)) { - // not allowed to propagate - continue; -@@ -610,7 +599,6 @@ public final class SkyStarLightEngine extends StarLightEngine { - // clobbering the light values will result in broken propagation) - protected final int tryPropagateSkylight(final BlockGetter world, final int worldX, int startY, final int worldZ, - final boolean extrudeInitialised, final boolean delayLightSet) { -- final BlockPos.MutableBlockPos mutablePos = this.mutablePos3; - final int encodeOffset = this.coordinateOffset; - final long propagateDirection = AxisDirection.POSITIVE_Y.everythingButThisDirection; // just don't check upwards. - -@@ -632,8 +620,7 @@ public final class SkyStarLightEngine extends StarLightEngine { - - final VoxelShape fromShape; - if (((StarlightAbstractBlockState)above).starlight$isConditionallyFullOpaque()) { -- this.mutablePos2.set(worldX, startY + 1, worldZ); -- fromShape = above.getFaceOcclusionShape(world, this.mutablePos2, AxisDirection.NEGATIVE_Y.nms); -+ fromShape = above.getFaceOcclusionShape(AxisDirection.NEGATIVE_Y.nms); - if (Shapes.faceShapeOccludes(Shapes.empty(), fromShape)) { - // above wont let us propagate - break; -@@ -642,49 +629,32 @@ public final class SkyStarLightEngine extends StarLightEngine { - fromShape = Shapes.empty(); - } - -- final int opacityIfCached = ((StarlightAbstractBlockState)current).starlight$getOpacityIfCached(); - // does light propagate from the top down? -- if (opacityIfCached != -1) { -- if (opacityIfCached != 0) { -- // we cannot propagate 15 through this -- break; -- } -- // most of the time it falls here. -- // add to propagate -- // light set delayed until we determine if this nibble section is null -- this.appendToIncreaseQueue( -- ((worldX + (worldZ << 6) + (startY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | (15L << (6 + 6 + 16)) // we know we're at full lit here -- | (propagateDirection << (6 + 6 + 16 + 4)) -- ); -- } else { -- mutablePos.set(worldX, startY, worldZ); -- long flags = 0L; -- if (((StarlightAbstractBlockState)current).starlight$isConditionallyFullOpaque()) { -- final VoxelShape cullingFace = current.getFaceOcclusionShape(world, mutablePos, AxisDirection.POSITIVE_Y.nms); -+ long flags = 0L; -+ if (((StarlightAbstractBlockState)current).starlight$isConditionallyFullOpaque()) { -+ final VoxelShape cullingFace = current.getFaceOcclusionShape(AxisDirection.POSITIVE_Y.nms); - -- if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { -- // can't propagate here, we're done on this column. -- break; -- } -- flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -- } -- -- final int opacity = current.getLightBlock(world, mutablePos); -- if (opacity > 0) { -- // let the queued value (if any) handle it from here. -+ if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { -+ // can't propagate here, we're done on this column. - break; - } -+ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -+ } - -- // light set delayed until we determine if this nibble section is null -- this.appendToIncreaseQueue( -- ((worldX + (worldZ << 6) + (startY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | (15L << (6 + 6 + 16)) // we know we're at full lit here -- | (propagateDirection << (6 + 6 + 16 + 4)) -- | flags -- ); -+ final int opacity = current.getLightBlock(); -+ if (opacity > 0) { -+ // let the queued value (if any) handle it from here. -+ break; - } - -+ // light set delayed until we determine if this nibble section is null -+ this.appendToIncreaseQueue( -+ ((worldX + (worldZ << 6) + (startY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | (15L << (6 + 6 + 16)) // we know we're at full lit here -+ | (propagateDirection << (6 + 6 + 16 + 4)) -+ | flags -+ ); -+ - above = current; - - if (this.getNibbleFromCache(worldX >> 4, startY >> 4, worldZ >> 4) == null) { -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightEngine.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightEngine.java -index 382c9e445af0d6ad2428fc22d0f63017c58191e2..8aeb5fb87f94a35659347a09a638420699b52a6f 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightEngine.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightEngine.java -@@ -1,6 +1,7 @@ - package ca.spottedleaf.moonrise.patches.starlight.light; - - import ca.spottedleaf.concurrentutil.util.IntegerUtil; -+import ca.spottedleaf.moonrise.common.PlatformHooks; - import ca.spottedleaf.moonrise.common.util.CoordinateUtils; - import ca.spottedleaf.moonrise.common.util.WorldUtil; - import ca.spottedleaf.moonrise.patches.starlight.blockstate.StarlightAbstractBlockState; -@@ -43,9 +44,9 @@ public abstract class StarLightEngine { - protected static enum AxisDirection { - - // Declaration order is important and relied upon. Do not change without modifying propagation code. -- POSITIVE_X(1, 0, 0), NEGATIVE_X(-1, 0, 0), -- POSITIVE_Z(0, 0, 1), NEGATIVE_Z(0, 0, -1), -- POSITIVE_Y(0, 1, 0), NEGATIVE_Y(0, -1, 0); -+ POSITIVE_X(1, 0, 0, Direction.EAST) , NEGATIVE_X(-1, 0, 0, Direction.WEST), -+ POSITIVE_Z(0, 0, 1, Direction.SOUTH), NEGATIVE_Z(0, 0, -1, Direction.NORTH), -+ POSITIVE_Y(0, 1, 0, Direction.UP) , NEGATIVE_Y(0, -1, 0, Direction.DOWN); - - static { - POSITIVE_X.opposite = NEGATIVE_X; NEGATIVE_X.opposite = POSITIVE_X; -@@ -62,11 +63,11 @@ public abstract class StarLightEngine { - public final long everythingButThisDirection; - public final long everythingButTheOppositeDirection; - -- AxisDirection(final int x, final int y, final int z) { -+ AxisDirection(final int x, final int y, final int z, final Direction nms) { - this.x = x; - this.y = y; - this.z = z; -- this.nms = Direction.fromDelta(x, y, z); -+ this.nms = nms; - this.everythingButThisDirection = (long)(ALL_DIRECTIONS_BITSET ^ (1 << this.ordinal())); - // positive is always even, negative is always odd. Flip the 1 bit to get the negative direction. - this.everythingButTheOppositeDirection = (long)(ALL_DIRECTIONS_BITSET ^ (1 << (this.ordinal() ^ 1))); -@@ -106,9 +107,7 @@ public abstract class StarLightEngine { - // index = x + (z * 5) - protected final boolean[][] emptinessMapCache = new boolean[5 * 5][]; - -- protected final BlockPos.MutableBlockPos mutablePos1 = new BlockPos.MutableBlockPos(); -- protected final BlockPos.MutableBlockPos mutablePos2 = new BlockPos.MutableBlockPos(); -- protected final BlockPos.MutableBlockPos mutablePos3 = new BlockPos.MutableBlockPos(); -+ protected final BlockPos.MutableBlockPos lightEmissionPos = new BlockPos.MutableBlockPos(); - - protected int encodeOffsetX; - protected int encodeOffsetY; -@@ -1150,69 +1149,46 @@ public abstract class StarLightEngine { - if (blockState == null) { - continue; - } -- final int opacityCached = ((StarlightAbstractBlockState)blockState).starlight$getOpacityIfCached(); -- if (opacityCached != -1) { -- final int targetLevel = propagatedLightLevel - Math.max(1, opacityCached); -- if (targetLevel > currentLevel) { -- currentNibble.set(localIndex, targetLevel); -- this.postLightUpdate(offX, offY, offZ); -- -- if (targetLevel > 1) { -- if (queueLength >= queue.length) { -- queue = this.resizeIncreaseQueue(); -- } -- queue[queueLength++] = -- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | ((targetLevel & 0xFL) << (6 + 6 + 16)) -- | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)); -- continue; -- } -- } -- continue; -- } else { -- this.mutablePos1.set(offX, offY, offZ); -- long flags = 0; -- if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { -- final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms); -+ long flags = 0; -+ if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { -+ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(propagate.getOpposite().nms); - -- if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) { -- continue; -- } -- flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -- } -- -- final int opacity = blockState.getLightBlock(world, this.mutablePos1); -- final int targetLevel = propagatedLightLevel - Math.max(1, opacity); -- if (targetLevel <= currentLevel) { -+ if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) { - continue; - } -+ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -+ } - -- currentNibble.set(localIndex, targetLevel); -- this.postLightUpdate(offX, offY, offZ); -+ final int opacity = blockState.getLightBlock(); -+ final int targetLevel = propagatedLightLevel - Math.max(1, opacity); -+ if (targetLevel <= currentLevel) { -+ continue; -+ } - -- if (targetLevel > 1) { -- if (queueLength >= queue.length) { -- queue = this.resizeIncreaseQueue(); -- } -- queue[queueLength++] = -- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | ((targetLevel & 0xFL) << (6 + 6 + 16)) -- | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)) -- | (flags); -+ currentNibble.set(localIndex, targetLevel); -+ this.postLightUpdate(offX, offY, offZ); -+ -+ if (targetLevel > 1) { -+ if (queueLength >= queue.length) { -+ queue = this.resizeIncreaseQueue(); - } -- continue; -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)) -+ | (flags); - } -+ continue; - } - } else { - // we actually need to worry about our state here - final BlockState fromBlock = this.getBlockState(posX, posY, posZ); -- this.mutablePos2.set(posX, posY, posZ); - for (final AxisDirection propagate : checkDirections) { - final int offX = posX + propagate.x; - final int offY = posY + propagate.y; - final int offZ = posZ + propagate.z; - -- final VoxelShape fromShape = (((StarlightAbstractBlockState)fromBlock).starlight$isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(world, this.mutablePos2, propagate.nms) : Shapes.empty(); -+ final VoxelShape fromShape = (((StarlightAbstractBlockState)fromBlock).starlight$isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(propagate.nms) : Shapes.empty(); - - if (fromShape != Shapes.empty() && Shapes.faceShapeOccludes(Shapes.empty(), fromShape)) { - continue; -@@ -1232,58 +1208,36 @@ public abstract class StarLightEngine { - if (blockState == null) { - continue; - } -- final int opacityCached = ((StarlightAbstractBlockState)blockState).starlight$getOpacityIfCached(); -- if (opacityCached != -1) { -- final int targetLevel = propagatedLightLevel - Math.max(1, opacityCached); -- if (targetLevel > currentLevel) { -- currentNibble.set(localIndex, targetLevel); -- this.postLightUpdate(offX, offY, offZ); -- -- if (targetLevel > 1) { -- if (queueLength >= queue.length) { -- queue = this.resizeIncreaseQueue(); -- } -- queue[queueLength++] = -- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | ((targetLevel & 0xFL) << (6 + 6 + 16)) -- | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)); -- continue; -- } -- } -- continue; -- } else { -- this.mutablePos1.set(offX, offY, offZ); -- long flags = 0; -- if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { -- final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms); -- -- if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { -- continue; -- } -- flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -- } -+ long flags = 0; -+ if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { -+ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(propagate.getOpposite().nms); - -- final int opacity = blockState.getLightBlock(world, this.mutablePos1); -- final int targetLevel = propagatedLightLevel - Math.max(1, opacity); -- if (targetLevel <= currentLevel) { -+ if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { - continue; - } -+ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -+ } - -- currentNibble.set(localIndex, targetLevel); -- this.postLightUpdate(offX, offY, offZ); -+ final int opacity = blockState.getLightBlock(); -+ final int targetLevel = propagatedLightLevel - Math.max(1, opacity); -+ if (targetLevel <= currentLevel) { -+ continue; -+ } - -- if (targetLevel > 1) { -- if (queueLength >= queue.length) { -- queue = this.resizeIncreaseQueue(); -- } -- queue[queueLength++] = -- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | ((targetLevel & 0xFL) << (6 + 6 + 16)) -- | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)) -- | (flags); -+ currentNibble.set(localIndex, targetLevel); -+ this.postLightUpdate(offX, offY, offZ); -+ -+ if (targetLevel > 1) { -+ if (queueLength >= queue.length) { -+ queue = this.resizeIncreaseQueue(); - } -- continue; -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)) -+ | (flags); - } -+ continue; - } - } - } -@@ -1304,6 +1258,8 @@ public abstract class StarLightEngine { - final int sectionOffset = this.chunkSectionIndexOffset; - final int emittedMask = this.emittedLightMask; - -+ final PlatformHooks platformHooks = PlatformHooks.get(); -+ - while (queueReadIndex < queueLength) { - final long queueValue = queue[queueReadIndex++]; - -@@ -1335,109 +1291,63 @@ public abstract class StarLightEngine { - if (blockState == null) { - continue; - } -- final int opacityCached = ((StarlightAbstractBlockState)blockState).starlight$getOpacityIfCached(); -- if (opacityCached != -1) { -- final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacityCached)); -- if (lightLevel > targetLevel) { -- // it looks like another source propagated here, so re-propagate it -- if (increaseQueueLength >= increaseQueue.length) { -- increaseQueue = this.resizeIncreaseQueue(); -- } -- increaseQueue[increaseQueueLength++] = -- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | ((lightLevel & 0xFL) << (6 + 6 + 16)) -- | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -- | FLAG_RECHECK_LEVEL; -- continue; -- } -- final int emittedLight = blockState.getLightEmission() & emittedMask; -- if (emittedLight != 0) { -- // re-propagate source -- // note: do not set recheck level, or else the propagation will fail -- if (increaseQueueLength >= increaseQueue.length) { -- increaseQueue = this.resizeIncreaseQueue(); -- } -- increaseQueue[increaseQueueLength++] = -- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | ((emittedLight & 0xFL) << (6 + 6 + 16)) -- | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -- | (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque() ? (FLAG_WRITE_LEVEL | FLAG_HAS_SIDED_TRANSPARENT_BLOCKS) : FLAG_WRITE_LEVEL); -- } -- -- currentNibble.set(localIndex, 0); -- this.postLightUpdate(offX, offY, offZ); -+ this.lightEmissionPos.set(offX, offY, offZ); -+ long flags = 0; -+ if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { -+ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(propagate.getOpposite().nms); - -- if (targetLevel > 0) { // we actually need to propagate 0 just in case we find a neighbour... -- if (queueLength >= queue.length) { -- queue = this.resizeDecreaseQueue(); -- } -- queue[queueLength++] = -- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | ((targetLevel & 0xFL) << (6 + 6 + 16)) -- | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)); -+ if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) { - continue; - } -- continue; -- } else { -- this.mutablePos1.set(offX, offY, offZ); -- long flags = 0; -- if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { -- final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms); -- -- if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) { -- continue; -- } -- flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -- } -+ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -+ } - -- final int opacity = blockState.getLightBlock(world, this.mutablePos1); -- final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacity)); -- if (lightLevel > targetLevel) { -- // it looks like another source propagated here, so re-propagate it -- if (increaseQueueLength >= increaseQueue.length) { -- increaseQueue = this.resizeIncreaseQueue(); -- } -- increaseQueue[increaseQueueLength++] = -- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | ((lightLevel & 0xFL) << (6 + 6 + 16)) -- | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -- | (FLAG_RECHECK_LEVEL | flags); -- continue; -+ final int opacity = blockState.getLightBlock(); -+ final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacity)); -+ if (lightLevel > targetLevel) { -+ // it looks like another source propagated here, so re-propagate it -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); - } -- final int emittedLight = blockState.getLightEmission() & emittedMask; -- if (emittedLight != 0) { -- // re-propagate source -- // note: do not set recheck level, or else the propagation will fail -- if (increaseQueueLength >= increaseQueue.length) { -- increaseQueue = this.resizeIncreaseQueue(); -- } -- increaseQueue[increaseQueueLength++] = -- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | ((emittedLight & 0xFL) << (6 + 6 + 16)) -- | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -- | (flags | FLAG_WRITE_LEVEL); -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((lightLevel & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (FLAG_RECHECK_LEVEL | flags); -+ continue; -+ } -+ final int emittedLight = (platformHooks.getLightEmission(blockState, world, this.lightEmissionPos)) & emittedMask; -+ if (emittedLight != 0) { -+ // re-propagate source -+ // note: do not set recheck level, or else the propagation will fail -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); - } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((emittedLight & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (flags | FLAG_WRITE_LEVEL); -+ } - -- currentNibble.set(localIndex, 0); -- this.postLightUpdate(offX, offY, offZ); -+ currentNibble.set(localIndex, 0); -+ this.postLightUpdate(offX, offY, offZ); - -- if (targetLevel > 0) { -- if (queueLength >= queue.length) { -- queue = this.resizeDecreaseQueue(); -- } -- queue[queueLength++] = -- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | ((targetLevel & 0xFL) << (6 + 6 + 16)) -- | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)) -- | flags; -+ if (targetLevel > 0) { -+ if (queueLength >= queue.length) { -+ queue = this.resizeDecreaseQueue(); - } -- continue; -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)) -+ | flags; - } -+ continue; - } - } else { - // we actually need to worry about our state here - final BlockState fromBlock = this.getBlockState(posX, posY, posZ); -- this.mutablePos2.set(posX, posY, posZ); - for (final AxisDirection propagate : checkDirections) { - final int offX = posX + propagate.x; - final int offY = posY + propagate.y; -@@ -1446,7 +1356,7 @@ public abstract class StarLightEngine { - final int sectionIndex = (offX >> 4) + 5 * (offZ >> 4) + (5 * 5) * (offY >> 4) + sectionOffset; - final int localIndex = (offX & 15) | ((offZ & 15) << 4) | ((offY & 15) << 8); - -- final VoxelShape fromShape = (((StarlightAbstractBlockState)fromBlock).starlight$isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(world, this.mutablePos2, propagate.nms) : Shapes.empty(); -+ final VoxelShape fromShape = (((StarlightAbstractBlockState)fromBlock).starlight$isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(propagate.nms) : Shapes.empty(); - - if (fromShape != Shapes.empty() && Shapes.faceShapeOccludes(Shapes.empty(), fromShape)) { - continue; -@@ -1464,104 +1374,59 @@ public abstract class StarLightEngine { - if (blockState == null) { - continue; - } -- final int opacityCached = ((StarlightAbstractBlockState)blockState).starlight$getOpacityIfCached(); -- if (opacityCached != -1) { -- final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacityCached)); -- if (lightLevel > targetLevel) { -- // it looks like another source propagated here, so re-propagate it -- if (increaseQueueLength >= increaseQueue.length) { -- increaseQueue = this.resizeIncreaseQueue(); -- } -- increaseQueue[increaseQueueLength++] = -- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | ((lightLevel & 0xFL) << (6 + 6 + 16)) -- | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -- | FLAG_RECHECK_LEVEL; -- continue; -- } -- final int emittedLight = blockState.getLightEmission() & emittedMask; -- if (emittedLight != 0) { -- // re-propagate source -- // note: do not set recheck level, or else the propagation will fail -- if (increaseQueueLength >= increaseQueue.length) { -- increaseQueue = this.resizeIncreaseQueue(); -- } -- increaseQueue[increaseQueueLength++] = -- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | ((emittedLight & 0xFL) << (6 + 6 + 16)) -- | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -- | (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque() ? (FLAG_WRITE_LEVEL | FLAG_HAS_SIDED_TRANSPARENT_BLOCKS) : FLAG_WRITE_LEVEL); -- } -- -- currentNibble.set(localIndex, 0); -- this.postLightUpdate(offX, offY, offZ); -+ this.lightEmissionPos.set(offX, offY, offZ); -+ long flags = 0; -+ if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { -+ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(propagate.getOpposite().nms); - -- if (targetLevel > 0) { // we actually need to propagate 0 just in case we find a neighbour... -- if (queueLength >= queue.length) { -- queue = this.resizeDecreaseQueue(); -- } -- queue[queueLength++] = -- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | ((targetLevel & 0xFL) << (6 + 6 + 16)) -- | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)); -+ if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { - continue; - } -- continue; -- } else { -- this.mutablePos1.set(offX, offY, offZ); -- long flags = 0; -- if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) { -- final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms); -- -- if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { -- continue; -- } -- flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -- } -+ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -+ } - -- final int opacity = blockState.getLightBlock(world, this.mutablePos1); -- final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacity)); -- if (lightLevel > targetLevel) { -- // it looks like another source propagated here, so re-propagate it -- if (increaseQueueLength >= increaseQueue.length) { -- increaseQueue = this.resizeIncreaseQueue(); -- } -- increaseQueue[increaseQueueLength++] = -- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | ((lightLevel & 0xFL) << (6 + 6 + 16)) -- | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -- | (FLAG_RECHECK_LEVEL | flags); -- continue; -+ final int opacity = blockState.getLightBlock(); -+ final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacity)); -+ if (lightLevel > targetLevel) { -+ // it looks like another source propagated here, so re-propagate it -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); - } -- final int emittedLight = blockState.getLightEmission() & emittedMask; -- if (emittedLight != 0) { -- // re-propagate source -- // note: do not set recheck level, or else the propagation will fail -- if (increaseQueueLength >= increaseQueue.length) { -- increaseQueue = this.resizeIncreaseQueue(); -- } -- increaseQueue[increaseQueueLength++] = -- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | ((emittedLight & 0xFL) << (6 + 6 + 16)) -- | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -- | (flags | FLAG_WRITE_LEVEL); -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((lightLevel & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (FLAG_RECHECK_LEVEL | flags); -+ continue; -+ } -+ final int emittedLight = (platformHooks.getLightEmission(blockState, world, this.lightEmissionPos)) & emittedMask; -+ if (emittedLight != 0) { -+ // re-propagate source -+ // note: do not set recheck level, or else the propagation will fail -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); - } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((emittedLight & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (flags | FLAG_WRITE_LEVEL); -+ } - -- currentNibble.set(localIndex, 0); -- this.postLightUpdate(offX, offY, offZ); -+ currentNibble.set(localIndex, 0); -+ this.postLightUpdate(offX, offY, offZ); - -- if (targetLevel > 0) { // we actually need to propagate 0 just in case we find a neighbour... -- if (queueLength >= queue.length) { -- queue = this.resizeDecreaseQueue(); -- } -- queue[queueLength++] = -- ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -- | ((targetLevel & 0xFL) << (6 + 6 + 16)) -- | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)) -- | flags; -+ if (targetLevel > 0) { // we actually need to propagate 0 just in case we find a neighbour... -+ if (queueLength >= queue.length) { -+ queue = this.resizeDecreaseQueue(); - } -- continue; -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)) -+ | flags; - } -+ continue; - } - } - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java -index c64ab41198a5e0c7cbcbe6452af11f82f5938862..571db5f9bf94745a8afe2cd313e593fb15db5e37 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java -@@ -1,8 +1,9 @@ - package ca.spottedleaf.moonrise.patches.starlight.light; - - import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; - import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; -+import ca.spottedleaf.concurrentutil.util.Priority; - import ca.spottedleaf.moonrise.common.util.CoordinateUtils; - import ca.spottedleaf.moonrise.common.util.WorldUtil; - import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel; -@@ -745,34 +746,34 @@ public final class StarLightInterface { - super(lightInterface); - } - -- public void lowerPriority(final int chunkX, final int chunkZ, final PrioritisedExecutor.Priority priority) { -+ public void lowerPriority(final int chunkX, final int chunkZ, final Priority priority) { - final ServerChunkTasks task = this.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); - if (task != null) { - task.lowerPriority(priority); - } - } - -- public void setPriority(final int chunkX, final int chunkZ, final PrioritisedExecutor.Priority priority) { -+ public void setPriority(final int chunkX, final int chunkZ, final Priority priority) { - final ServerChunkTasks task = this.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); - if (task != null) { - task.setPriority(priority); - } - } - -- public void raisePriority(final int chunkX, final int chunkZ, final PrioritisedExecutor.Priority priority) { -+ public void raisePriority(final int chunkX, final int chunkZ, final Priority priority) { - final ServerChunkTasks task = this.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); - if (task != null) { - task.raisePriority(priority); - } - } - -- public PrioritisedExecutor.Priority getPriority(final int chunkX, final int chunkZ) { -+ public Priority getPriority(final int chunkX, final int chunkZ) { - final ServerChunkTasks task = this.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); - if (task != null) { - return task.getPriority(); - } - -- return PrioritisedExecutor.Priority.COMPLETING; -+ return Priority.COMPLETING; - } - - @Override -@@ -816,7 +817,7 @@ public final class StarLightInterface { - return ret; - } - -- public ServerChunkTasks queueChunkLightTask(final ChunkPos pos, final BooleanSupplier lightTask, final PrioritisedExecutor.Priority priority) { -+ public ServerChunkTasks queueChunkLightTask(final ChunkPos pos, final BooleanSupplier lightTask, final Priority priority) { - final ServerChunkTasks ret = this.chunkTasks.compute(CoordinateUtils.getChunkKey(pos), (final long keyInMap, ServerChunkTasks valueInMap) -> { - if (valueInMap == null) { - valueInMap = new ServerChunkTasks( -@@ -879,11 +880,11 @@ public final class StarLightInterface { - - public ServerChunkTasks(final long chunkCoordinate, final StarLightInterface lightEngine, - final ServerLightQueue queue) { -- this(chunkCoordinate, lightEngine, queue, PrioritisedExecutor.Priority.NORMAL); -+ this(chunkCoordinate, lightEngine, queue, Priority.NORMAL); - } - - public ServerChunkTasks(final long chunkCoordinate, final StarLightInterface lightEngine, -- final ServerLightQueue queue, final PrioritisedExecutor.Priority priority) { -+ final ServerLightQueue queue, final Priority priority) { - super(chunkCoordinate, lightEngine, queue); - this.task = ((ChunkSystemServerLevel)(ServerLevel)lightEngine.getWorld()).moonrise$getChunkTaskScheduler().radiusAwareScheduler.createTask( - CoordinateUtils.getChunkX(chunkCoordinate), CoordinateUtils.getChunkZ(chunkCoordinate), -@@ -903,19 +904,19 @@ public final class StarLightInterface { - return this.task.cancel(); - } - -- public PrioritisedExecutor.Priority getPriority() { -+ public Priority getPriority() { - return this.task.getPriority(); - } - -- public void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ public void lowerPriority(final Priority priority) { - this.task.lowerPriority(priority); - } - -- public void setPriority(final PrioritisedExecutor.Priority priority) { -+ public void setPriority(final Priority priority) { - this.task.setPriority(priority); - } - -- public void raisePriority(final PrioritisedExecutor.Priority priority) { -+ public void raisePriority(final Priority priority) { - this.task.raisePriority(priority); - } - -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/storage/StarlightSectionData.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/storage/StarlightSectionData.java -new file mode 100644 -index 0000000000000000000000000000000000000000..40d004afdc6449530f5bb2d7c7638b8ee3e3a577 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/storage/StarlightSectionData.java -@@ -0,0 +1,13 @@ -+package ca.spottedleaf.moonrise.patches.starlight.storage; -+ -+public interface StarlightSectionData { -+ -+ public int starlight$getBlockLightState(); -+ -+ public void starlight$setBlockLightState(final int state); -+ -+ public int starlight$getSkyLightState(); -+ -+ public void starlight$setSkyLightState(final int state); -+ -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/util/SaveUtil.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/util/SaveUtil.java -index 57692a503e147a00ac4e1586cd78e12b71a80d3f..689ce367164e79e0426eeecb81dbbc521d4bc742 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/util/SaveUtil.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/util/SaveUtil.java -@@ -14,19 +14,20 @@ import net.minecraft.world.level.chunk.ChunkAccess; - import net.minecraft.world.level.chunk.status.ChunkStatus; - import org.slf4j.Logger; - -+// note: keep in-sync with SerializableChunkDataMixin - public final class SaveUtil { - - private static final Logger LOGGER = LogUtils.getLogger(); - -- private static final int STARLIGHT_LIGHT_VERSION = 9; -+ public static final int STARLIGHT_LIGHT_VERSION = 9; - - public static int getLightVersion() { - return STARLIGHT_LIGHT_VERSION; - } - -- private static final String BLOCKLIGHT_STATE_TAG = "starlight.blocklight_state"; -- private static final String SKYLIGHT_STATE_TAG = "starlight.skylight_state"; -- private static final String STARLIGHT_VERSION_TAG = "starlight.light_version"; -+ public static final String BLOCKLIGHT_STATE_TAG = "starlight.blocklight_state"; -+ public static final String SKYLIGHT_STATE_TAG = "starlight.skylight_state"; -+ public static final String STARLIGHT_VERSION_TAG = "starlight.light_version"; - - public static void saveLightHook(final Level world, final ChunkAccess chunk, final CompoundTag nbt) { - try { -diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 9bd509915b391e9d382fe47798e2c345b6e59a9a..65c7e7a1b1a5472ee03149bb4ccd9f7d0229069b 100644 ---- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -+++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -242,6 +242,7 @@ public class GlobalConfiguration extends ConfigurationPart { - - @PostProcess - private void postProcess() { -+ ca.spottedleaf.moonrise.common.util.MoonriseCommon.adjustWorkerThreads(this.workerThreads, this.ioThreads); - ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.init(this); - } - } -diff --git a/src/main/java/net/minecraft/core/MappedRegistry.java b/src/main/java/net/minecraft/core/MappedRegistry.java -index 71e04e5c1bc0722abf8ca2e0738bd60b6d7ae21c..8e0dfaf02343d74ce786e4fc647bc4c1d73c0014 100644 ---- a/src/main/java/net/minecraft/core/MappedRegistry.java -+++ b/src/main/java/net/minecraft/core/MappedRegistry.java -@@ -50,6 +50,19 @@ public class MappedRegistry implements WritableRegistry { - return this.getTags(); - } - -+ // Paper start - fluid method optimisations -+ private void injectFluidRegister( -+ final ResourceKey resourceKey, -+ final T object -+ ) { -+ if (resourceKey.registryKey() == (Object)net.minecraft.core.registries.Registries.FLUID) { -+ for (final net.minecraft.world.level.material.FluidState possibleState : ((net.minecraft.world.level.material.Fluid)object).getStateDefinition().getPossibleStates()) { -+ ((ca.spottedleaf.moonrise.patches.fluid.FluidFluidState)(Object)possibleState).moonrise$initCaches(); -+ } -+ } -+ } -+ // Paper end - fluid method optimisations -+ - public MappedRegistry(ResourceKey> key, Lifecycle lifecycle) { - this(key, lifecycle, false); - } -@@ -114,6 +127,7 @@ public class MappedRegistry implements WritableRegistry { - this.toId.put(value, i); - this.registrationInfos.put(key, info); - this.registryLifecycle = this.registryLifecycle.add(info.lifecycle()); -+ this.injectFluidRegister(key, value); // Paper - fluid method optimisations - return reference; - } - } -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 7c388e230c4a88edf6212dd8990e8238d3265ebf..8a66012b7f2396031840c8c718f49f8aab716ee0 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1106,7 +1106,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop trackerEntities = entityLookup.trackerEntities; -@@ -921,21 +920,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - if (tracker == null) { - continue; - } -- ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity)tracker).moonrise$tick(nearbyPlayers.getChunk(entity.chunkPosition())); -- tracker.serverEntity.sendChanges(); -- } -- -- // process unloads -- final ca.spottedleaf.moonrise.common.list.ReferenceList unloadedEntities = entityLookup.trackerUnloadedEntities; -- final Entity[] unloadedEntitiesRaw = java.util.Arrays.copyOf(unloadedEntities.getRawDataUnchecked(), unloadedEntities.size()); -- unloadedEntities.clear(); -- -- for (final Entity entity : unloadedEntitiesRaw) { -- final ChunkMap.TrackedEntity tracker = ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$getTrackedEntity(); -- if (tracker == null) { -- continue; -+ ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity)tracker).moonrise$tick(((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)entity).moonrise$getChunkData().nearbyPlayers); -+ if (((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity)tracker).moonrise$hasPlayers() -+ || ((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)entity).moonrise$getChunkStatus().isOrAfter(FullChunkStatus.ENTITY_TICKING)) { -+ tracker.serverEntity.sendChanges(); - } -- ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity)tracker).moonrise$clearPlayers(); - } - } - // Paper end - optimise entity tracker -@@ -1172,6 +1161,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - this.removePlayer(player); - } - } -+ -+ @Override -+ public final boolean moonrise$hasPlayers() { -+ return !this.seenBy.isEmpty(); -+ } - // Paper end - optimise entity tracker - - public TrackedEntity(final Entity entity, final int i, final int j, final boolean flag) { -@@ -1262,20 +1256,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - - private int getEffectiveRange() { -- int i = this.range; -- Iterator iterator = this.entity.getIndirectPassengers().iterator(); -+ // Paper start - optimise entity tracker -+ final Entity entity = this.entity; -+ int range = ca.spottedleaf.moonrise.common.PlatformHooks.get().modifyEntityTrackingRange(entity, this.range); - -- while (iterator.hasNext()) { -- Entity entity = (Entity) iterator.next(); -- int j = entity.getType().clientTrackingRange() * 16; -- j = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, j); // Paper -+ if (entity.getPassengers() == ImmutableList.of()) { -+ return this.scaledRange(range); -+ } - -- if (j > i) { -- i = j; -- } -+ // note: we change to List -+ final List passengers = (List)entity.getIndirectPassengers(); -+ for (int i = 0, len = passengers.size(); i < len; ++i) { -+ final Entity passenger = passengers.get(i); -+ // note: max should be branchless -+ range = Math.max(range, ca.spottedleaf.moonrise.common.PlatformHooks.get().modifyEntityTrackingRange(passenger, passenger.getType().clientTrackingRange() << 4)); - } - -- return this.scaledRange(i); -+ return this.scaledRange(range); -+ // Paper end - optimise entity tracker - } - - public void updatePlayers(List players) { -diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 22157cbc4e4bb1e4010116bdf7429815d46bff2e..23a13bfd23514cde6dcf8d59ba3b43d84f266aad 100644 ---- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java -+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -99,7 +99,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler chunkTaskScheduler = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler(); - final CompletableFuture completable = new CompletableFuture<>(); - chunkTaskScheduler.scheduleChunkLoad( -- chunkX, chunkZ, toStatus, true, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.BLOCKING, -+ chunkX, chunkZ, toStatus, true, ca.spottedleaf.concurrentutil.util.Priority.BLOCKING, - completable::complete - ); - -@@ -130,6 +130,15 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - return ifPresent; - } - -+ final ca.spottedleaf.moonrise.common.PlatformHooks platformHooks = ca.spottedleaf.moonrise.common.PlatformHooks.get(); -+ -+ if (platformHooks.hasCurrentlyLoadingChunk() && currentChunk != null) { -+ final ChunkAccess loading = platformHooks.getCurrentlyLoadingChunk(currentChunk.vanillaChunkHolder); -+ if (loading != null && ca.spottedleaf.moonrise.common.util.TickThread.isTickThread()) { -+ return loading; -+ } -+ } -+ - return load ? this.syncLoad(chunkX, chunkZ, toStatus) : null; - } - // Paper end - rewrite chunk system -@@ -254,7 +263,24 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - @Nullable - @Override - public LevelChunk getChunkNow(int chunkX, int chunkZ) { -- return this.fullChunks.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); // Paper - rewrite chunk system -+ // Paper start - rewrite chunk system -+ final LevelChunk ret = this.fullChunks.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ if (!ca.spottedleaf.moonrise.common.PlatformHooks.get().hasCurrentlyLoadingChunk()) { -+ return ret; -+ } -+ -+ if (ret != null || !ca.spottedleaf.moonrise.common.util.TickThread.isTickThread()) { -+ return ret; -+ } -+ -+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder holder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler() -+ .chunkHolderManager.getChunkHolder(chunkX, chunkZ); -+ if (holder == null) { -+ return ret; -+ } -+ -+ return ca.spottedleaf.moonrise.common.PlatformHooks.get().getCurrentlyLoadingChunk(holder.vanillaChunkHolder); -+ // Paper end - rewrite chunk system - } - - private void clearCache() { -@@ -311,7 +337,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - - ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().scheduleChunkLoad( - chunkX, chunkZ, leastStatus, true, -- ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER, -+ ca.spottedleaf.concurrentutil.util.Priority.HIGHER, - complete - ); - -@@ -549,7 +575,8 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - - private void getFullChunk(long pos, Consumer chunkConsumer) { - // Paper start - rewrite chunk system -- final LevelChunk fullChunk = this.getChunkNow(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkX(pos), ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkZ(pos)); -+ // note: bypass currentlyLoaded from getChunkNow -+ final LevelChunk fullChunk = this.fullChunks.get(pos); - if (fullChunk != null) { - chunkConsumer.accept(fullChunk); - } -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index af27a004f618912d6a5f1d2c82c8e7e9fb00a037..c7523387f0e9bbfe952abd237a936c8319f10200 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -775,11 +775,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - } - - // Paper start - optimise random ticking -+ private final ca.spottedleaf.moonrise.common.util.SimpleRandom simpleRandom = new ca.spottedleaf.moonrise.common.util.SimpleRandom(0L); -+ - private void optimiseRandomTick(final LevelChunk chunk, final int tickSpeed) { - final LevelChunkSection[] sections = chunk.getSections(); - final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection((ServerLevel)(Object)this); -- final RandomSource random = this.random; -- final boolean tickFluids = false; // Paper - not configurable - MC-224294 -+ final ca.spottedleaf.moonrise.common.util.SimpleRandom simpleRandom = this.simpleRandom; -+ final boolean doubleTickFluids = !ca.spottedleaf.moonrise.common.PlatformHooks.get().configFixMC224294(); - - final ChunkPos cpos = chunk.getPos(); - final int offsetX = cpos.x << 4; -@@ -789,39 +791,32 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - final int offsetY = (sectionIndex + minSection) << 4; - final LevelChunkSection section = sections[sectionIndex]; - final net.minecraft.world.level.chunk.PalettedContainer states = section.states; -- if (section == null || !section.isRandomlyTickingBlocks()) { -+ if (!section.isRandomlyTickingBlocks()) { - continue; - } - -- final ca.spottedleaf.moonrise.common.list.IBlockDataList tickList = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$getTickingBlockList(); -- if (tickList.size() == 0) { -- continue; -- } -+ final ca.spottedleaf.moonrise.common.list.ShortList tickList = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$getTickingBlockList(); - - for (int i = 0; i < tickSpeed; ++i) { - final int tickingBlocks = tickList.size(); -- final int index = random.nextInt() & ((16 * 16 * 16) - 1); -+ final int index = simpleRandom.nextInt() & ((16 * 16 * 16) - 1); - - if (index >= tickingBlocks) { - // most of the time we fall here - continue; - } - -- final long raw = tickList.getRaw(index); -- final int location = ca.spottedleaf.moonrise.common.list.IBlockDataList.getLocationFromRaw(raw); -- final int randomX = (location & 15); -- final int randomY = ((location >>> (4 + 4)) & 255); -- final int randomZ = ((location >>> 4) & 15); -- final BlockState state = states.get(randomX | (randomZ << 4) | (randomY << 8)); -+ final int location = (int)tickList.getRaw(index) & 0xFFFF; -+ final BlockState state = states.get(location); - - // do not use a mutable pos, as some random tick implementations store the input without calling immutable()! -- final BlockPos pos = new BlockPos(randomX | offsetX, randomY | offsetY, randomZ | offsetZ); -+ final BlockPos pos = new BlockPos((location & 15) | offsetX, ((location >>> (4 + 4)) & 15) | offsetY, ((location >>> 4) & 15) | offsetZ); - -- state.randomTick((ServerLevel)(Object)this, pos, random); -- if (tickFluids) { -+ state.randomTick((ServerLevel)(Object)this, pos, simpleRandom); -+ if (doubleTickFluids) { - final FluidState fluidState = state.getFluidState(); - if (fluidState.isRandomlyTicking()) { -- fluidState.randomTick((ServerLevel)(Object)this, pos, random); -+ fluidState.randomTick((ServerLevel)(Object)this, pos, simpleRandom); - } - } - } -@@ -832,6 +827,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - // Paper end - optimise random ticking - - public void tickChunk(LevelChunk chunk, int randomTickSpeed) { -+ final ca.spottedleaf.moonrise.common.util.SimpleRandom simpleRandom = this.simpleRandom; // Paper - optimise random ticking - ChunkPos chunkcoordintpair = chunk.getPos(); - boolean flag = this.isRaining(); - int j = chunkcoordintpair.getMinBlockX(); -@@ -839,7 +835,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - ProfilerFiller gameprofilerfiller = Profiler.get(); - - gameprofilerfiller.push("thunder"); -- if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - Option to disable thunder -+ if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && simpleRandom.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - Option to disable thunder // Paper - optimise random ticking - BlockPos blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15)); - - if (this.isRainingAt(blockposition)) { -@@ -871,7 +867,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - - if (!this.paperConfig().environment.disableIceAndSnow) { // Paper - Option to disable ice and snow - for (int l = 0; l < randomTickSpeed; ++l) { -- if (this.random.nextInt(48) == 0) { -+ if (simpleRandom.nextInt(48) == 0) { // Paper - optimise random ticking - this.tickPrecipitation(this.getBlockRandomPos(j, 0, k, 15)); - } - } -diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 4fe3024e26b56c2d796acf703a1bc200ff309f09..7529b3d90e65036c7bf869af30475932d547b3ab 100644 ---- a/src/main/java/net/minecraft/server/players/PlayerList.java -+++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1407,7 +1407,7 @@ public abstract class PlayerList { - - public void setViewDistance(int viewDistance) { - this.viewDistance = viewDistance; -- this.broadcastAll(new ClientboundSetChunkCacheRadiusPacket(viewDistance)); -+ //this.broadcastAll(new ClientboundSetChunkCacheRadiusPacket(viewDistance)); // Paper - rewrite chunk system - Iterator iterator = this.server.getAllLevels().iterator(); - - while (iterator.hasNext()) { -diff --git a/src/main/java/net/minecraft/util/BitStorage.java b/src/main/java/net/minecraft/util/BitStorage.java -index 19661e106612b8e4e152085fb398db7bd06acc23..e4e153cb8899e70273aa150b8ea26907cf68b15c 100644 ---- a/src/main/java/net/minecraft/util/BitStorage.java -+++ b/src/main/java/net/minecraft/util/BitStorage.java -@@ -24,15 +24,15 @@ public interface BitStorage extends ca.spottedleaf.moonrise.patches.block_counti - // Paper start - block counting - // provide default impl in case mods implement this... - @Override -- public default it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { -- final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(); -+ public default it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { -+ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(); - - final int size = this.getSize(); - for (int index = 0; index < size; ++index) { - final int paletteIdx = this.get(index); - ret.computeIfAbsent(paletteIdx, (final int key) -> { -- return new it.unimi.dsi.fastutil.ints.IntArrayList(); -- }).add(index); -+ return new it.unimi.dsi.fastutil.shorts.ShortArrayList(); -+ }).add((short)index); - } - - return ret; -diff --git a/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java b/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java -index 61dee55417bc802e25b9ba2f271d32d8c12844a9..a8a260a3caaa8e5004069b833ecc8b17b2fc8db5 100644 ---- a/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java -+++ b/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java -@@ -7,7 +7,7 @@ import java.util.Iterator; - import javax.annotation.Nullable; - import net.minecraft.core.IdMap; - --public class CrudeIncrementalIntIdentityHashBiMap implements IdMap { -+public class CrudeIncrementalIntIdentityHashBiMap implements IdMap, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Paper - optimise palette reads - private static final int NOT_FOUND = -1; - private static final Object EMPTY_SLOT = null; - private static final float LOADFACTOR = 0.8F; -@@ -17,6 +17,16 @@ public class CrudeIncrementalIntIdentityHashBiMap implements IdMap { - private int nextId; - private int size; - -+ // Paper start - optimise palette reads -+ private ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData reference; -+ -+ @Override -+ public final K[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData src) { -+ this.reference = src; -+ return this.byId; -+ } -+ // Paper end - optimise palette reads -+ - private CrudeIncrementalIntIdentityHashBiMap(int size) { - this.keys = (K[])(new Object[size]); - this.values = new int[size]; -@@ -88,6 +98,12 @@ public class CrudeIncrementalIntIdentityHashBiMap implements IdMap { - this.byId = crudeIncrementalIntIdentityHashBiMap.byId; - this.nextId = crudeIncrementalIntIdentityHashBiMap.nextId; - this.size = crudeIncrementalIntIdentityHashBiMap.size; -+ // Paper start - optimise palette reads -+ final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData ref = this.reference; -+ if (ref != null) { -+ ref.moonrise$setPalette(this.byId); -+ } -+ // Paper end - optimise palette reads - } - - public void addMapping(K value, int id) { -diff --git a/src/main/java/net/minecraft/util/SimpleBitStorage.java b/src/main/java/net/minecraft/util/SimpleBitStorage.java -index 8acf2f2491a8d9d13392c5e89b2bd5c9918285e1..d99ec470b4653beab630999a5b2c1a6428b20c38 100644 ---- a/src/main/java/net/minecraft/util/SimpleBitStorage.java -+++ b/src/main/java/net/minecraft/util/SimpleBitStorage.java -@@ -208,6 +208,20 @@ public class SimpleBitStorage implements BitStorage { - private final int divideAdd; private final long divideAddUnsigned; // Paper - Perf: Optimize SimpleBitStorage - private final int divideShift; - -+ // Paper start - optimise bitstorage read/write operations -+ private static final int[] BETTER_MAGIC = new int[33]; -+ static { -+ // 20 bits of precision -+ // since index is always [0, 4095] (i.e 12 bits), multiplication by a magic value here (20 bits) -+ // fits exactly in an int and allows us to use integer arithmetic -+ for (int bits = 1; bits < BETTER_MAGIC.length; ++bits) { -+ BETTER_MAGIC[bits] = (int)ca.spottedleaf.concurrentutil.util.IntegerUtil.getUnsignedDivisorMagic(64L / bits, 20); -+ } -+ } -+ private final int magic; -+ private final int mulBits; -+ // Paper end - optimise bitstorage read/write operations -+ - public SimpleBitStorage(int elementBits, int size, int[] data) { - this(elementBits, size); - int i = 0; -@@ -261,6 +275,13 @@ public class SimpleBitStorage implements BitStorage { - } else { - this.data = new long[j]; - } -+ // Paper start - optimise bitstorage read/write operations -+ this.magic = BETTER_MAGIC[this.bits]; -+ this.mulBits = (64 / this.bits) * this.bits; -+ if (this.size > 4096) { -+ throw new IllegalStateException("Size > 4096 not supported"); -+ } -+ // Paper end - optimise bitstorage read/write operations - } - - private int cellIndex(int index) { -@@ -273,31 +294,54 @@ public class SimpleBitStorage implements BitStorage { - public final int getAndSet(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage - //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage - //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper - Perf: Optimize SimpleBitStorage -- int i = this.cellIndex(index); -- long l = this.data[i]; -- int j = (index - i * this.valuesPerLong) * this.bits; -- int k = (int)(l >> j & this.mask); -- this.data[i] = l & ~(this.mask << j) | ((long)value & this.mask) << j; -- return k; -+ // Paper start - optimise bitstorage read/write operations -+ final int full = this.magic * index; // 20 bits of magic + 12 bits of index = barely int -+ final int divQ = full >>> 20; -+ final int divR = (full & 0xFFFFF) * this.mulBits >>> 20; -+ -+ final long[] dataArray = this.data; -+ -+ final long data = dataArray[divQ]; -+ final long mask = this.mask; -+ -+ final long write = data & ~(mask << divR) | ((long)value & mask) << divR; -+ -+ dataArray[divQ] = write; -+ -+ return (int)(data >>> divR & mask); -+ // Paper end - optimise bitstorage read/write operations - } - - @Override - public final void set(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage - //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage - //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper - Perf: Optimize SimpleBitStorage -- int i = this.cellIndex(index); -- long l = this.data[i]; -- int j = (index - i * this.valuesPerLong) * this.bits; -- this.data[i] = l & ~(this.mask << j) | ((long)value & this.mask) << j; -+ // Paper start - optimise bitstorage read/write operations -+ final int full = this.magic * index; // 20 bits of magic + 12 bits of index = barely int -+ final int divQ = full >>> 20; -+ final int divR = (full & 0xFFFFF) * this.mulBits >>> 20; -+ -+ final long[] dataArray = this.data; -+ -+ final long data = dataArray[divQ]; -+ final long mask = this.mask; -+ -+ final long write = data & ~(mask << divR) | ((long)value & mask) << divR; -+ -+ dataArray[divQ] = write; -+ // Paper end - optimise bitstorage read/write operations - } - - @Override - public final int get(int index) { // Paper - Perf: Optimize SimpleBitStorage - //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage -- int i = this.cellIndex(index); -- long l = this.data[i]; -- int j = (index - i * this.valuesPerLong) * this.bits; -- return (int)(l >> j & this.mask); -+ // Paper start - optimise bitstorage read/write operations -+ final int full = this.magic * index; // 20 bits of magic + 12 bits of index = barely int -+ final int divQ = full >>> 20; -+ final int divR = (full & 0xFFFFF) * this.mulBits >>> 20; -+ -+ return (int)(this.data[divQ] >>> divR & this.mask); -+ // Paper end - optimise bitstorage read/write operations - } - - @Override -@@ -364,35 +408,62 @@ public class SimpleBitStorage implements BitStorage { - - // Paper start - block counting - @Override -- public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { -+ public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { - final int valuesPerLong = this.valuesPerLong; - final int bits = this.bits; -- final long mask = this.mask; -+ final long mask = (1L << bits) - 1L; - final int size = this.size; - -- // we may be backed by global palette, so limit bits for init capacity -- final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>( -- 1 << Math.min(6, bits) -- ); -- -- int index = 0; -- -- for (long value : this.data) { -- int li = 0; -- do { -- final int paletteIdx = (int)(value & mask); -- value >>= bits; -+ if (bits <= 6) { -+ final it.unimi.dsi.fastutil.shorts.ShortArrayList[] byId = new it.unimi.dsi.fastutil.shorts.ShortArrayList[1 << bits]; -+ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1 << bits); -+ -+ int index = 0; -+ -+ for (long value : this.data) { -+ int li = 0; -+ do { -+ final int paletteIdx = (int)(value & mask); -+ value >>= bits; -+ ++li; -+ -+ final it.unimi.dsi.fastutil.shorts.ShortArrayList coords = byId[paletteIdx]; -+ if (coords != null) { -+ coords.add((short)index++); -+ continue; -+ } else { -+ final it.unimi.dsi.fastutil.shorts.ShortArrayList newCoords = new it.unimi.dsi.fastutil.shorts.ShortArrayList(64); -+ byId[paletteIdx] = newCoords; -+ newCoords.add((short)index++); -+ ret.put(paletteIdx, newCoords); -+ continue; -+ } -+ } while (li < valuesPerLong && index < size); -+ } - -- ret.computeIfAbsent(paletteIdx, (final int key) -> { -- return new it.unimi.dsi.fastutil.ints.IntArrayList(); -- }).add(index); -+ return ret; -+ } else { -+ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>( -+ 1 << 6 -+ ); -+ -+ int index = 0; -+ -+ for (long value : this.data) { -+ int li = 0; -+ do { -+ final int paletteIdx = (int)(value & mask); -+ value >>= bits; -+ ++li; -+ -+ ret.computeIfAbsent(paletteIdx, (final int key) -> { -+ return new it.unimi.dsi.fastutil.shorts.ShortArrayList(64); -+ }).add((short)index++); -+ } while (li < valuesPerLong && index < size); -+ } - -- ++li; -- ++index; -- } while (li < valuesPerLong && index < size); -+ return ret; - } -- -- return ret; - } - // Paper end - block counting - -diff --git a/src/main/java/net/minecraft/util/ZeroBitStorage.java b/src/main/java/net/minecraft/util/ZeroBitStorage.java -index 15c5164d0ef41a978c16ee317fa73e97f2480207..1f9c436a632e4f110be61cf76fcfc3b7eb80334e 100644 ---- a/src/main/java/net/minecraft/util/ZeroBitStorage.java -+++ b/src/main/java/net/minecraft/util/ZeroBitStorage.java -@@ -65,17 +65,17 @@ public class ZeroBitStorage implements BitStorage { - - // Paper start - block counting - @Override -- public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { -+ public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { - final int size = this.size; - -- final int[] raw = new int[size]; -+ final short[] raw = new short[size]; - for (int i = 0; i < size; ++i) { -- raw[i] = i; -+ raw[i] = (short)i; - } - -- final it.unimi.dsi.fastutil.ints.IntArrayList coordinates = it.unimi.dsi.fastutil.ints.IntArrayList.wrap(raw, size); -+ final it.unimi.dsi.fastutil.shorts.ShortArrayList coordinates = it.unimi.dsi.fastutil.shorts.ShortArrayList.wrap(raw, size); - -- final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1); -+ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1); - ret.put(0, coordinates); - return ret; - } -diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 5410a0380c44629f1c9b4f0a8e6017cfc5a31a89..a3b0363fbc207ed9edc8a4d6619b6fff9389a9c7 100644 ---- a/src/main/java/net/minecraft/world/entity/Entity.java -+++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -448,6 +448,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - // Paper start - rewrite chunk system - private final boolean isHardColliding = this.moonrise$isHardCollidingUncached(); - private net.minecraft.server.level.FullChunkStatus chunkStatus; -+ private ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData chunkData; - private int sectionX = Integer.MIN_VALUE; - private int sectionY = Integer.MIN_VALUE; - private int sectionZ = Integer.MIN_VALUE; -@@ -468,6 +469,16 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - this.chunkStatus = status; - } - -+ @Override -+ public final ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData moonrise$getChunkData() { -+ return this.chunkData; -+ } -+ -+ @Override -+ public final void moonrise$setChunkData(final ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData chunkData) { -+ this.chunkData = chunkData; -+ } -+ - @Override - public final int moonrise$getSectionX() { - return this.sectionX; -@@ -516,6 +527,54 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - return this.getIndirectPassengersStream().anyMatch((entity) -> entity instanceof Player); - } - // Paper end - rewrite chunk system -+ // Paper start - optimise collisions -+ private static float[] calculateStepHeights(final AABB box, final List voxels, final List aabbs, final float stepHeight, -+ final float collidedY) { -+ final FloatArraySet ret = new FloatArraySet(); -+ -+ for (int i = 0, len = voxels.size(); i < len; ++i) { -+ final VoxelShape shape = voxels.get(i); -+ -+ final double[] yCoords = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$rootCoordinatesY(); -+ final double yOffset = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$offsetY(); -+ -+ for (final double yUnoffset : yCoords) { -+ final double y = yUnoffset + yOffset; -+ -+ final float step = (float)(y - box.minY); -+ -+ if (step > stepHeight) { -+ break; -+ } -+ -+ if (step < 0.0f || !(step != collidedY)) { -+ continue; -+ } -+ -+ ret.add(step); -+ } -+ } -+ -+ for (int i = 0, len = aabbs.size(); i < len; ++i) { -+ final AABB shape = aabbs.get(i); -+ -+ final float step1 = (float)(shape.minY - box.minY); -+ final float step2 = (float)(shape.maxY - box.minY); -+ -+ if (!(step1 < 0.0f) && step1 != collidedY && !(step1 > stepHeight)) { -+ ret.add(step1); -+ } -+ -+ if (!(step2 < 0.0f) && step2 != collidedY && !(step2 > stepHeight)) { -+ ret.add(step2); -+ } -+ } -+ -+ final float[] steps = ret.toFloatArray(); -+ FloatArrays.unstableSort(steps); -+ return steps; -+ } -+ // Paper end - optimise collisions - // Paper start - optimise entity tracker - private net.minecraft.server.level.ChunkMap.TrackedEntity trackedEntity; - -@@ -1402,73 +1461,67 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - return movement; - } - -- final Level world = this.level; -- final AABB currBoundingBox = this.getBoundingBox(); -- -- if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(currBoundingBox)) { -- return movement; -- } -+ final AABB currentBox = this.getBoundingBox(); - -- final List potentialCollisionsBB = new ArrayList<>(); - final List potentialCollisionsVoxel = new ArrayList<>(); -- final double stepHeight = (double)this.maxUpStep(); -- final AABB collisionBox; -- final boolean onGround = this.onGround; -+ final List potentialCollisionsBB = new ArrayList<>(); - -+ final AABB initialCollisionBox; - if (xZero & zZero) { -- if (movement.y > 0.0) { -- collisionBox = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutUpwards(currBoundingBox, movement.y); -- } else { -- collisionBox = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutDownwards(currBoundingBox, movement.y); -- } -+ // note: xZero & zZero -> collision on x/z == 0 -> no step height calculation -+ // this specifically optimises entities standing still -+ initialCollisionBox = movement.y < 0.0 ? -+ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutDownwards(currentBox, movement.y) : ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutUpwards(currentBox, movement.y); - } else { -- // note: xZero == false or zZero == false -- if (stepHeight > 0.0 && (onGround || (movement.y < 0.0))) { -- // don't bother getting the collisions if we don't need them. -- if (movement.y <= 0.0) { -- collisionBox = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.expandUpwards(currBoundingBox.expandTowards(movement.x, movement.y, movement.z), stepHeight); -- } else { -- collisionBox = currBoundingBox.expandTowards(movement.x, Math.max(stepHeight, movement.y), movement.z); -- } -- } else { -- collisionBox = currBoundingBox.expandTowards(movement.x, movement.y, movement.z); -- } -+ initialCollisionBox = currentBox.expandTowards(movement); - } - -- ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisions( -- world, (Entity)(Object)this, collisionBox, potentialCollisionsVoxel, potentialCollisionsBB, -- ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_BORDER, -- null, null -+ final List entityAABBs = new ArrayList<>(); -+ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getEntityHardCollisions( -+ this.level, (Entity)(Object)this, initialCollisionBox, entityAABBs, 0, null - ); - -- if (potentialCollisionsVoxel.isEmpty() && potentialCollisionsBB.isEmpty()) { -- return movement; -- } -+ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisionsForBlocksOrWorldBorder( -+ this.level, (Entity)(Object)this, initialCollisionBox, potentialCollisionsVoxel, potentialCollisionsBB, -+ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_BORDER, null -+ ); -+ potentialCollisionsBB.addAll(entityAABBs); -+ final Vec3 collided = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(movement, currentBox, potentialCollisionsVoxel, potentialCollisionsBB); - -- final Vec3 limitedMoveVector = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(movement, currBoundingBox, potentialCollisionsVoxel, potentialCollisionsBB); -+ final boolean collidedX = collided.x != movement.x; -+ final boolean collidedY = collided.y != movement.y; -+ final boolean collidedZ = collided.z != movement.z; - -- if (stepHeight > 0.0 -- && (onGround || (limitedMoveVector.y != movement.y && movement.y < 0.0)) -- && (limitedMoveVector.x != movement.x || limitedMoveVector.z != movement.z)) { -- Vec3 vec3d2 = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(new Vec3(movement.x, stepHeight, movement.z), currBoundingBox, potentialCollisionsVoxel, potentialCollisionsBB); -- final Vec3 vec3d3 = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(new Vec3(0.0, stepHeight, 0.0), currBoundingBox.expandTowards(movement.x, 0.0, movement.z), potentialCollisionsVoxel, potentialCollisionsBB); -+ final boolean collidedDownwards = collidedY && movement.y < 0.0; - -- if (vec3d3.y < stepHeight) { -- final Vec3 vec3d4 = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(new Vec3(movement.x, 0.0D, movement.z), currBoundingBox.move(vec3d3), potentialCollisionsVoxel, potentialCollisionsBB).add(vec3d3); -+ final double stepHeight; - -- if (vec3d4.horizontalDistanceSqr() > vec3d2.horizontalDistanceSqr()) { -- vec3d2 = vec3d4; -- } -- } -+ if ((!collidedDownwards && !this.onGround) || (!collidedX && !collidedZ) || (stepHeight = (double)this.maxUpStep()) <= 0.0) { -+ return collided; -+ } - -- if (vec3d2.horizontalDistanceSqr() > limitedMoveVector.horizontalDistanceSqr()) { -- return vec3d2.add(ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(new Vec3(0.0D, -vec3d2.y + movement.y, 0.0D), currBoundingBox.move(vec3d2), potentialCollisionsVoxel, potentialCollisionsBB)); -- } -+ final AABB collidedYBox = collidedDownwards ? currentBox.move(0.0, collided.y, 0.0) : currentBox; -+ AABB stepRetrievalBox = collidedYBox.expandTowards(movement.x, stepHeight, movement.z); -+ if (!collidedDownwards) { -+ stepRetrievalBox = stepRetrievalBox.expandTowards(0.0, (double)-1.0E-5F, 0.0); -+ } - -- return limitedMoveVector; -- } else { -- return limitedMoveVector; -+ final List stepVoxels = new ArrayList<>(); -+ final List stepAABBs = entityAABBs; -+ -+ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisionsForBlocksOrWorldBorder( -+ this.level, (Entity)(Object)this, stepRetrievalBox, stepVoxels, stepAABBs, -+ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_BORDER, null -+ ); -+ -+ for (final float step : calculateStepHeights(collidedYBox, stepVoxels, stepAABBs, (float)stepHeight, (float)collided.y)) { -+ final Vec3 stepResult = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(new Vec3(movement.x, (double)step, movement.z), collidedYBox, stepVoxels, stepAABBs); -+ if (stepResult.horizontalDistanceSqr() > collided.horizontalDistanceSqr()) { -+ return stepResult.add(0.0, collidedYBox.minY - currentBox.minY, 0.0); -+ } - } -+ -+ return collided; - // Paper end - optimise collisions - } - -@@ -2836,64 +2889,99 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - return false; - } - -- final float reducedWith = this.dimensions.width() * 0.8F; -- final AABB box = AABB.ofSize(this.getEyePosition(), reducedWith, 1.0E-6D, reducedWith); -+ final double reducedWith = (double)(this.dimensions.width() * 0.8F); -+ final AABB boundingBox = AABB.ofSize(this.getEyePosition(), reducedWith, 1.0E-6D, reducedWith); -+ final Level world = this.level; - -- if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(box)) { -+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(boundingBox)) { - return false; - } - -- final BlockPos.MutableBlockPos tempPos = new BlockPos.MutableBlockPos(); -+ final int minBlockX = Mth.floor(boundingBox.minX); -+ final int minBlockY = Mth.floor(boundingBox.minY); -+ final int minBlockZ = Mth.floor(boundingBox.minZ); -+ -+ final int maxBlockX = Mth.floor(boundingBox.maxX); -+ final int maxBlockY = Mth.floor(boundingBox.maxY); -+ final int maxBlockZ = Mth.floor(boundingBox.maxZ); - -- final int minX = Mth.floor(box.minX); -- final int minY = Mth.floor(box.minY); -- final int minZ = Mth.floor(box.minZ); -- final int maxX = Mth.floor(box.maxX); -- final int maxY = Mth.floor(box.maxY); -- final int maxZ = Mth.floor(box.maxZ); -+ final int minChunkX = minBlockX >> 4; -+ final int minChunkY = minBlockY >> 4; -+ final int minChunkZ = minBlockZ >> 4; - -- final net.minecraft.world.level.chunk.ChunkSource chunkProvider = this.level.getChunkSource(); -+ final int maxChunkX = maxBlockX >> 4; -+ final int maxChunkY = maxBlockY >> 4; -+ final int maxChunkZ = maxBlockZ >> 4; - -- long lastChunkKey = ChunkPos.INVALID_CHUNK_POS; -- net.minecraft.world.level.chunk.LevelChunk lastChunk = null; -- for (int fz = minZ; fz <= maxZ; ++fz) { -- tempPos.setZ(fz); -- for (int fx = minX; fx <= maxX; ++fx) { -- final int newChunkX = fx >> 4; -- final int newChunkZ = fz >> 4; -- final net.minecraft.world.level.chunk.LevelChunk chunk = lastChunkKey == (lastChunkKey = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(newChunkX, newChunkZ)) ? -- lastChunk : (lastChunk = (net.minecraft.world.level.chunk.LevelChunk)chunkProvider.getChunk(newChunkX, newChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, true)); -- tempPos.setX(fx); -- for (int fy = minY; fy <= maxY; ++fy) { -- tempPos.setY(fy); -+ final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(world); -+ final net.minecraft.world.level.chunk.ChunkSource chunkSource = world.getChunkSource(); -+ final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); - -- final BlockState state = chunk.getBlockState(tempPos); -+ for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { -+ for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { -+ final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, true).getSections(); - -- if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)state).moonrise$emptyCollisionShape() || !state.isSuffocating(this.level, tempPos)) { -+ for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) { -+ final int sectionIdx = currChunkY - minSection; -+ if (sectionIdx < 0 || sectionIdx >= sections.length) { - continue; - } -- -- // Yes, it does not use the Entity context stuff. -- final VoxelShape collisionShape = state.getCollisionShape(this.level, tempPos); -- -- if (collisionShape.isEmpty()) { -+ final net.minecraft.world.level.chunk.LevelChunkSection section = sections[sectionIdx]; -+ if (section.hasOnlyAir()) { -+ // empty - continue; - } - -- final AABB toCollide = box.move(-(double)fx, -(double)fy, -(double)fz); -+ final net.minecraft.world.level.chunk.PalettedContainer blocks = section.states; -+ -+ final int minXIterate = currChunkX == minChunkX ? (minBlockX & 15) : 0; -+ final int maxXIterate = currChunkX == maxChunkX ? (maxBlockX & 15) : 15; -+ final int minZIterate = currChunkZ == minChunkZ ? (minBlockZ & 15) : 0; -+ final int maxZIterate = currChunkZ == maxChunkZ ? (maxBlockZ & 15) : 15; -+ final int minYIterate = currChunkY == minChunkY ? (minBlockY & 15) : 0; -+ final int maxYIterate = currChunkY == maxChunkY ? (maxBlockY & 15) : 15; -+ -+ for (int currY = minYIterate; currY <= maxYIterate; ++currY) { -+ final int blockY = currY | (currChunkY << 4); -+ mutablePos.setY(blockY); -+ for (int currZ = minZIterate; currZ <= maxZIterate; ++currZ) { -+ final int blockZ = currZ | (currChunkZ << 4); -+ mutablePos.setZ(blockZ); -+ for (int currX = minXIterate; currX <= maxXIterate; ++currX) { -+ final int blockX = currX | (currChunkX << 4); -+ mutablePos.setX(blockX); -+ -+ final BlockState blockState = blocks.get((currX) | (currZ << 4) | ((currY) << 8)); -+ -+ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockState).moonrise$emptyCollisionShape() -+ || !blockState.isSuffocating(world, mutablePos)) { -+ continue; -+ } - -- final AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)collisionShape).moonrise$getSingleAABBRepresentation(); -- if (singleAABB != null) { -- if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersect(singleAABB, toCollide)) { -- return true; -- } -- continue; -- } -+ // Yes, it does not use the Entity context stuff. -+ final VoxelShape collisionShape = blockState.getCollisionShape(world, mutablePos); -+ -+ if (collisionShape.isEmpty()) { -+ continue; -+ } -+ -+ final AABB toCollide = boundingBox.move(-(double)blockX, -(double)blockY, -(double)blockZ); - -- if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersectNoEmpty(collisionShape, toCollide)) { -- return true; -+ final AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)collisionShape).moonrise$getSingleAABBRepresentation(); -+ if (singleAABB != null) { -+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersect(singleAABB, toCollide)) { -+ return true; -+ } -+ continue; -+ } -+ -+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersectNoEmpty(collisionShape, toCollide)) { -+ return true; -+ } -+ continue; -+ } -+ } - } -- continue; - } - } - } -@@ -4508,82 +4596,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - return Mth.lerp(delta, this.yRotO, this.yRot); - } - -- public boolean updateFluidHeightAndDoFluidPushing(TagKey tag, double speed) { -+ // Paper start - optimise collisions -+ public boolean updateFluidHeightAndDoFluidPushing(final TagKey fluid, final double flowScale) { - if (this.touchingUnloadedChunk()) { - return false; -- } else { -- AABB axisalignedbb = this.getBoundingBox().deflate(0.001D); -- int i = Mth.floor(axisalignedbb.minX); -- int j = Mth.ceil(axisalignedbb.maxX); -- int k = Mth.floor(axisalignedbb.minY); -- int l = Mth.ceil(axisalignedbb.maxY); -- int i1 = Mth.floor(axisalignedbb.minZ); -- int j1 = Mth.ceil(axisalignedbb.maxZ); -- double d1 = 0.0D; -- boolean flag = this.isPushedByFluid(); -- boolean flag1 = false; -- Vec3 vec3d = Vec3.ZERO; -- int k1 = 0; -- BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); -- -- for (int l1 = i; l1 < j; ++l1) { -- for (int i2 = k; i2 < l; ++i2) { -- for (int j2 = i1; j2 < j1; ++j2) { -- blockposition_mutableblockposition.set(l1, i2, j2); -- FluidState fluid = this.level().getFluidState(blockposition_mutableblockposition); -- -- if (fluid.is(tag)) { -- double d2 = (double) ((float) i2 + fluid.getHeight(this.level(), blockposition_mutableblockposition)); -- -- if (d2 >= axisalignedbb.minY) { -- flag1 = true; -- d1 = Math.max(d2 - axisalignedbb.minY, d1); -- if (flag) { -- Vec3 vec3d1 = fluid.getFlow(this.level(), blockposition_mutableblockposition); -- -- if (d1 < 0.4D) { -- vec3d1 = vec3d1.scale(d1); -- } -+ } -+ -+ final AABB boundingBox = this.getBoundingBox().deflate(1.0E-3); -+ -+ final Level world = this.level; -+ final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(world); -+ -+ final int minBlockX = Mth.floor(boundingBox.minX); -+ final int minBlockY = Math.max((minSection << 4), Mth.floor(boundingBox.minY)); -+ final int minBlockZ = Mth.floor(boundingBox.minZ); -+ -+ // note: bounds are exclusive in Vanilla, so we subtract 1 - our loop expects bounds to be inclusive -+ final int maxBlockX = Mth.ceil(boundingBox.maxX) - 1; -+ final int maxBlockY = Math.min((ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection(world) << 4) | 15, Mth.ceil(boundingBox.maxY) - 1); -+ final int maxBlockZ = Mth.ceil(boundingBox.maxZ) - 1; -+ -+ final boolean isPushable = this.isPushedByFluid(); -+ final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); -+ -+ Vec3 pushVector = Vec3.ZERO; -+ double totalPushes = 0.0; -+ double maxHeightDiff = 0.0; -+ boolean inFluid = false; -+ -+ final int minChunkX = minBlockX >> 4; -+ final int maxChunkX = maxBlockX >> 4; -+ -+ final int minChunkY = minBlockY >> 4; -+ final int maxChunkY = maxBlockY >> 4; -+ -+ final int minChunkZ = minBlockZ >> 4; -+ final int maxChunkZ = maxBlockZ >> 4; -+ -+ final net.minecraft.world.level.chunk.ChunkSource chunkSource = world.getChunkSource(); -+ -+ for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { -+ for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { -+ final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunkSource.getChunk(currChunkX, currChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, false).getSections(); - -- vec3d = vec3d.add(vec3d1); -- ++k1; -+ // bound y -+ for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) { -+ final int sectionIdx = currChunkY - minSection; -+ if (sectionIdx < 0 || sectionIdx >= sections.length) { -+ continue; -+ } -+ final net.minecraft.world.level.chunk.LevelChunkSection section = sections[sectionIdx]; -+ if (section.hasOnlyAir()) { -+ // empty -+ continue; -+ } -+ -+ final net.minecraft.world.level.chunk.PalettedContainer blocks = section.states; -+ -+ final int minXIterate = currChunkX == minChunkX ? (minBlockX & 15) : 0; -+ final int maxXIterate = currChunkX == maxChunkX ? (maxBlockX & 15) : 15; -+ final int minZIterate = currChunkZ == minChunkZ ? (minBlockZ & 15) : 0; -+ final int maxZIterate = currChunkZ == maxChunkZ ? (maxBlockZ & 15) : 15; -+ final int minYIterate = currChunkY == minChunkY ? (minBlockY & 15) : 0; -+ final int maxYIterate = currChunkY == maxChunkY ? (maxBlockY & 15) : 15; -+ -+ for (int currY = minYIterate; currY <= maxYIterate; ++currY) { -+ for (int currZ = minZIterate; currZ <= maxZIterate; ++currZ) { -+ for (int currX = minXIterate; currX <= maxXIterate; ++currX) { -+ final FluidState fluidState = blocks.get((currX) | (currZ << 4) | ((currY) << 8)).getFluidState(); -+ -+ if (fluidState.isEmpty() || !fluidState.is(fluid)) { -+ continue; -+ } -+ -+ mutablePos.set(currX | (currChunkX << 4), currY | (currChunkY << 4), currZ | (currChunkZ << 4)); -+ -+ final double height = (double)((float)mutablePos.getY() + fluidState.getHeight(world, mutablePos)); -+ final double diff = height - boundingBox.minY; -+ -+ if (diff < 0.0) { -+ continue; -+ } -+ -+ inFluid = true; -+ maxHeightDiff = Math.max(maxHeightDiff, diff); -+ -+ if (!isPushable) { -+ continue; - } -- // CraftBukkit start - store last lava contact location -- if (tag == FluidTags.LAVA) { -- this.lastLavaContact = blockposition_mutableblockposition.immutable(); -+ -+ ++totalPushes; -+ -+ final Vec3 flow = fluidState.getFlow(world, mutablePos); -+ -+ if (diff < 0.4) { -+ pushVector = pushVector.add(flow.scale(diff)); -+ } else { -+ pushVector = pushVector.add(flow); - } -- // CraftBukkit end - } - } - } - } - } -+ } - -- if (vec3d.length() > 0.0D) { -- if (k1 > 0) { -- vec3d = vec3d.scale(1.0D / (double) k1); -- } -+ this.fluidHeight.put(fluid, maxHeightDiff); - -- if (!(this instanceof Player)) { -- vec3d = vec3d.normalize(); -- } -+ if (pushVector.lengthSqr() == 0.0) { -+ return inFluid; -+ } - -- Vec3 vec3d2 = this.getDeltaMovement(); -+ // note: totalPushes != 0 as pushVector != 0 -+ pushVector = pushVector.scale(1.0 / totalPushes); -+ final Vec3 currMovement = this.getDeltaMovement(); - -- vec3d = vec3d.scale(speed); -- double d3 = 0.003D; -+ if (!((Entity)(Object)this instanceof Player)) { -+ pushVector = pushVector.normalize(); -+ } - -- if (Math.abs(vec3d2.x) < 0.003D && Math.abs(vec3d2.z) < 0.003D && vec3d.length() < 0.0045000000000000005D) { -- vec3d = vec3d.normalize().scale(0.0045000000000000005D); -- } -+ pushVector = pushVector.scale(flowScale); -+ if (Math.abs(currMovement.x) < 0.003 && Math.abs(currMovement.z) < 0.003 && pushVector.length() < 0.0045000000000000005) { -+ pushVector = pushVector.normalize().scale(0.0045000000000000005); -+ } - -- this.setDeltaMovement(this.getDeltaMovement().add(vec3d)); -- } -+ this.setDeltaMovement(currMovement.add(pushVector)); - -- this.fluidHeight.put(tag, d1); -- return flag1; -- } -+ // note: inFluid = true here as pushVector != 0 -+ return true; - } -+ // Paper end - optimise collisions - - public boolean touchingUnloadedChunk() { - AABB axisalignedbb = this.getBoundingBox().inflate(1.0D); -diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -index 4cf6cb0abfeb7065c6d9381fb4194371c0cddc35..5930a430983061afddf20e3208ff2462ca1b78cd 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -+++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -@@ -73,8 +73,7 @@ public class PoiManager extends SectionStorage im - - ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Accessing poi chunk off-main"); - -- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager manager = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager; -- final ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk ret = manager.getPoiChunkIfLoaded(chunkX, chunkZ, true); -+ final ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk ret = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager.getPoiChunkIfLoaded(chunkX, chunkZ, true); - - return ret == null ? Optional.empty() : ret.getSectionForVanilla(chunkY); - } -@@ -128,9 +127,13 @@ public class PoiManager extends SectionStorage im - public final void moonrise$onUnload(final long coordinate) { // Paper - rewrite chunk system - final int chunkX = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkX(coordinate); - final int chunkZ = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkZ(coordinate); -+ -+ final int minY = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(this.world); -+ final int maxY = ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection(this.world); -+ - ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Unloading poi chunk off-main"); -- for (int section = this.levelHeightAccessor.getMinSection(); section < this.levelHeightAccessor.getMaxSection(); ++section) { -- final long sectionPos = SectionPos.asLong(chunkX, section, chunkZ); -+ for (int sectionY = minY; sectionY <= maxY; ++sectionY) { -+ final long sectionPos = SectionPos.asLong(chunkX, sectionY, chunkZ); - this.updateDistanceTracking(sectionPos); - } - } -@@ -139,8 +142,12 @@ public class PoiManager extends SectionStorage im - public final void moonrise$loadInPoiChunk(final ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk poiChunk) { - final int chunkX = poiChunk.chunkX; - final int chunkZ = poiChunk.chunkZ; -+ -+ final int minY = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(this.world); -+ final int maxY = ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection(this.world); -+ - ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Loading poi chunk off-main"); -- for (int sectionY = this.levelHeightAccessor.getMinSection(); sectionY < this.levelHeightAccessor.getMaxSection(); ++sectionY) { -+ for (int sectionY = minY; sectionY <= maxY; ++sectionY) { - final PoiSection section = poiChunk.getSection(sectionY); - if (section != null && !((ca.spottedleaf.moonrise.patches.chunk_system.level.poi.ChunkSystemPoiSection)section).moonrise$isEmpty()) { - this.onSectionLoad(SectionPos.asLong(chunkX, sectionY, chunkZ)); -@@ -316,8 +323,10 @@ public class PoiManager extends SectionStorage im - } - - public int sectionsToVillage(SectionPos pos) { -- this.villageDistanceTracker.propagateUpdates(); // Paper - rewrite chunk system -- return convertBetweenLevels(this.villageDistanceTracker.getLevel(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkSectionKey(pos))); // Paper - rewrite chunk system -+ // Paper start - rewrite chunk system -+ this.villageDistanceTracker.propagateUpdates(); -+ return convertBetweenLevels(this.villageDistanceTracker.getLevel(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkSectionKey(pos))); -+ // Paper end - rewrite chunk system - } - - boolean isVillageCenter(long pos) { -diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java -index f6f0d7c21ee81ff33d4af350c4d39aadfbe140df..712cbfc100e8aaf612d1d651dae64f57f892a768 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java -+++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java -@@ -31,7 +31,7 @@ public class PoiSection implements ca.spottedleaf.moonrise.patches.chunk_system. - private boolean isValid; - - // Paper start - rewrite chunk system -- private final Optional noAllocOptional = Optional.of((PoiSection)(Object)this);; -+ private final Optional noAllocOptional = Optional.of((PoiSection)(Object)this); - - @Override - public final boolean moonrise$isEmpty() { -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 332dc7e6bdfb5b3741764d4877185a2e86a982f8..40fe47c7c145587ac81f0f15c237ed72ea9c094d 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -264,26 +264,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - } - // Paper end - rewrite chunk system - // Paper start - optimise collisions -- private final int minSection; -- private final int maxSection; -- -- @Override -- public final int moonrise$getMinSection() { -- return this.minSection; -- } -- -- @Override -- public final int moonrise$getMaxSection() { -- return this.maxSection; -- } -- - /** - * Route to faster lookup. - * See {@link EntityGetter#isUnobstructed(Entity, VoxelShape)} for expected behavior - * @author Spottedleaf - */ - @Override -- public final boolean isUnobstructed(final Entity entity) { -+ public boolean isUnobstructed(final Entity entity) { - final AABB boundingBox = entity.getBoundingBox(); - if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(boundingBox)) { - return false; -@@ -313,7 +300,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - final Vec3 to = clipContext.getTo(); - final Vec3 from = clipContext.getFrom(); - -- return net.minecraft.world.phys.BlockHitResult.miss(to, Direction.getNearest(from.x - to.x, from.y - to.y, from.z - to.z), BlockPos.containing(to.x, to.y, to.z)); -+ return net.minecraft.world.phys.BlockHitResult.miss(to, Direction.getApproximateNearest(from.x - to.x, from.y - to.y, from.z - to.z), BlockPos.containing(to.x, to.y, to.z)); - } - - private static final FluidState AIR_FLUIDSTATE = Fluids.EMPTY.defaultFluidState(); -@@ -367,7 +354,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - int lastChunkY = Integer.MIN_VALUE; - int lastChunkZ = Integer.MIN_VALUE; - -- final int minSection = ((ca.spottedleaf.moonrise.patches.collisions.world.CollisionLevel)level).moonrise$getMinSection(); -+ final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(level); - - for (;;) { - currPos.set(currX, currY, currZ); -@@ -450,7 +437,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - * @author Spottedleaf - */ - @Override -- public final net.minecraft.world.phys.BlockHitResult clip(final ClipContext clipContext) { -+ public net.minecraft.world.phys.BlockHitResult clip(final ClipContext clipContext) { - // can only do this in this class, as not everything that implements BlockGetter can retrieve chunks - return fastClip(clipContext.getFrom(), clipContext.getTo(), (Level)(Object)this, clipContext); - } -@@ -460,7 +447,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - * @author Spottedleaf - */ - @Override -- public final boolean collidesWithSuffocatingBlock(final Entity entity, final AABB box) { -+ public boolean collidesWithSuffocatingBlock(final Entity entity, final AABB box) { - return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisionsForBlocksOrWorldBorder((Level)(Object)this, entity, box, null, null, - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_ONLY, - (final BlockState state, final BlockPos pos) -> { -@@ -486,8 +473,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - * @author Spottedleaf - */ - @Override -- public final java.util.Optional findFreePosition(final Entity entity, final VoxelShape boundsShape, final Vec3 fromPosition, -- final double rangeX, final double rangeY, final double rangeZ) { -+ public java.util.Optional findFreePosition(final Entity entity, final VoxelShape boundsShape, final Vec3 fromPosition, -+ final double rangeX, final double rangeY, final double rangeZ) { - if (boundsShape.isEmpty()) { - return java.util.Optional.empty(); - } -@@ -546,103 +533,139 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - * @author Spottedleaf - */ - @Override -- public final java.util.Optional findSupportingBlock(final Entity entity, final AABB aabb) { -+ public java.util.Optional findSupportingBlock(final Entity entity, final AABB aabb) { -+ final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection((Level)(Object)this); -+ - final int minBlockX = Mth.floor(aabb.minX - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) - 1; - final int maxBlockX = Mth.floor(aabb.maxX + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) + 1; - -- final int minBlockY = Mth.floor(aabb.minY - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) - 1; -- final int maxBlockY = Mth.floor(aabb.maxY + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) + 1; -+ final int minBlockY = Math.max((minSection << 4) - 1, Mth.floor(aabb.minY - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) - 1); -+ final int maxBlockY = Math.min((ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection((Level)(Object)this) << 4) + 16, Mth.floor(aabb.maxY + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) + 1); - - final int minBlockZ = Mth.floor(aabb.minZ - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) - 1; - final int maxBlockZ = Mth.floor(aabb.maxZ + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) + 1; - -- ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext collisionContext = null; -- -- final BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); -+ final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); -+ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext collisionShape = new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext(entity); - BlockPos selected = null; - double selectedDistance = Double.MAX_VALUE; -- - final Vec3 entityPos = entity.position(); - -- LevelChunk lastChunk = null; -- int lastChunkX = Integer.MIN_VALUE; -- int lastChunkZ = Integer.MIN_VALUE; -+ // special cases: -+ if (minBlockY > maxBlockY) { -+ // no point in checking -+ return java.util.Optional.empty(); -+ } - -- final ChunkSource chunkSource = this.getChunkSource(); -+ final int minChunkX = minBlockX >> 4; -+ final int maxChunkX = maxBlockX >> 4; - -- for (int currZ = minBlockZ; currZ <= maxBlockZ; ++currZ) { -- pos.setZ(currZ); -- for (int currX = minBlockX; currX <= maxBlockX; ++currX) { -- pos.setX(currX); -+ final int minChunkY = minBlockY >> 4; -+ final int maxChunkY = maxBlockY >> 4; - -- final int newChunkX = currX >> 4; -- final int newChunkZ = currZ >> 4; -+ final int minChunkZ = minBlockZ >> 4; -+ final int maxChunkZ = maxBlockZ >> 4; - -- if (((newChunkX ^ lastChunkX) | (newChunkZ ^ lastChunkZ)) != 0) { -- lastChunkX = newChunkX; -- lastChunkZ = newChunkZ; -- lastChunk = (LevelChunk)chunkSource.getChunk(newChunkX, newChunkZ, ChunkStatus.FULL, false); -- } -+ final ChunkSource chunkSource = this.getChunkSource(); - -- if (lastChunk == null) { -+ for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { -+ for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { -+ final ChunkAccess chunk = chunkSource.getChunk(currChunkX, currChunkZ, ChunkStatus.FULL, false); -+ -+ if (chunk == null) { - continue; - } -- for (int currY = minBlockY; currY <= maxBlockY; ++currY) { -- int edgeCount = ((currX == minBlockX || currX == maxBlockX) ? 1 : 0) + -- ((currY == minBlockY || currY == maxBlockY) ? 1 : 0) + -- ((currZ == minBlockZ || currZ == maxBlockZ) ? 1 : 0); -- if (edgeCount == 3) { -- continue; -- } - -- pos.setY(currY); -+ final net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections(); - -- final double distance = pos.distToCenterSqr(entityPos); -- if (distance > selectedDistance || (distance == selectedDistance && selected.compareTo(pos) >= 0)) { -+ // bound y -+ for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) { -+ final int sectionIdx = currChunkY - minSection; -+ if (sectionIdx < 0 || sectionIdx >= sections.length) { - continue; - } -- -- final BlockState state = ((ca.spottedleaf.moonrise.patches.chunk_getblock.GetBlockChunk)lastChunk).moonrise$getBlock(currX, currY, currZ); -- if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)state).moonrise$emptyCollisionShape()) { -+ final net.minecraft.world.level.chunk.LevelChunkSection section = sections[sectionIdx]; -+ if (section.hasOnlyAir()) { -+ // empty - continue; - } - -- VoxelShape blockCollision = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)state).moonrise$getConstantCollisionShape(); -- -- if ((edgeCount != 1 || state.hasLargeCollisionShape()) && (edgeCount != 2 || state.getBlock() == Blocks.MOVING_PISTON)) { -- if (collisionContext == null) { -- collisionContext = new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext(entity); -- } -- -- if (blockCollision == null) { -- blockCollision = state.getCollisionShape((Level)(Object)this, pos, collisionContext); -- } -- -- if (blockCollision.isEmpty()) { -- continue; -- } -- -- // avoid VoxelShape#move by shifting the entity collision shape instead -- final AABB shiftedAABB = aabb.move(-(double)currX, -(double)currY, -(double)currZ); -- -- final AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation(); -- if (singleAABB != null) { -- if (!ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersect(singleAABB, shiftedAABB)) { -- continue; -+ final boolean hasSpecial = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$hasSpecialCollidingBlocks(); -+ final int sectionAdjust = !hasSpecial ? 1 : 0; -+ -+ final net.minecraft.world.level.chunk.PalettedContainer blocks = section.states; -+ -+ final int minXIterate = currChunkX == minChunkX ? (minBlockX & 15) + sectionAdjust : 0; -+ final int maxXIterate = currChunkX == maxChunkX ? (maxBlockX & 15) - sectionAdjust : 15; -+ final int minZIterate = currChunkZ == minChunkZ ? (minBlockZ & 15) + sectionAdjust : 0; -+ final int maxZIterate = currChunkZ == maxChunkZ ? (maxBlockZ & 15) - sectionAdjust : 15; -+ final int minYIterate = currChunkY == minChunkY ? (minBlockY & 15) + sectionAdjust : 0; -+ final int maxYIterate = currChunkY == maxChunkY ? (maxBlockY & 15) - sectionAdjust : 15; -+ -+ for (int currY = minYIterate; currY <= maxYIterate; ++currY) { -+ final int blockY = currY | (currChunkY << 4); -+ mutablePos.setY(blockY); -+ for (int currZ = minZIterate; currZ <= maxZIterate; ++currZ) { -+ final int blockZ = currZ | (currChunkZ << 4); -+ mutablePos.setZ(blockZ); -+ for (int currX = minXIterate; currX <= maxXIterate; ++currX) { -+ final int localBlockIndex = (currX) | (currZ << 4) | ((currY) << 8); -+ final int blockX = currX | (currChunkX << 4); -+ mutablePos.setX(blockX); -+ -+ final int edgeCount = hasSpecial ? ((blockX == minBlockX || blockX == maxBlockX) ? 1 : 0) + -+ ((blockY == minBlockY || blockY == maxBlockY) ? 1 : 0) + -+ ((blockZ == minBlockZ || blockZ == maxBlockZ) ? 1 : 0) : 0; -+ if (edgeCount == 3) { -+ continue; -+ } -+ -+ final double distance = mutablePos.distToCenterSqr(entityPos); -+ if (distance > selectedDistance || (distance == selectedDistance && selected.compareTo(mutablePos) >= 0)) { -+ continue; -+ } -+ -+ final BlockState blockData = blocks.get(localBlockIndex); -+ -+ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockData).moonrise$emptyContextCollisionShape()) { -+ continue; -+ } -+ -+ VoxelShape blockCollision = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockData).moonrise$getConstantContextCollisionShape(); -+ -+ if (edgeCount == 0 || ((edgeCount != 1 || blockData.hasLargeCollisionShape()) && (edgeCount != 2 || blockData.getBlock() == Blocks.MOVING_PISTON))) { -+ if (blockCollision == null) { -+ blockCollision = blockData.getCollisionShape((Level)(Object)this, mutablePos, collisionShape); -+ -+ if (blockCollision.isEmpty()) { -+ continue; -+ } -+ } -+ -+ // avoid VoxelShape#move by shifting the entity collision shape instead -+ final AABB shiftedAABB = aabb.move(-(double)blockX, -(double)blockY, -(double)blockZ); -+ -+ final AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation(); -+ if (singleAABB != null) { -+ if (!ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersect(singleAABB, shiftedAABB)) { -+ continue; -+ } -+ -+ selected = mutablePos.immutable(); -+ selectedDistance = distance; -+ continue; -+ } -+ -+ if (!ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersectNoEmpty(blockCollision, shiftedAABB)) { -+ continue; -+ } -+ -+ selected = mutablePos.immutable(); -+ selectedDistance = distance; -+ continue; -+ } - } -- -- selected = pos.immutable(); -- selectedDistance = distance; -- continue; - } -- -- if (!ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.voxelShapeIntersectNoEmpty(blockCollision, shiftedAABB)) { -- continue; -- } -- -- selected = pos.immutable(); -- selectedDistance = distance; -- continue; - } - } - } -@@ -651,6 +674,74 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - return java.util.Optional.ofNullable(selected); - } - // Paper end - optimise collisions -+ // Paper start - getblock optimisations - cache world height/sections -+ private final int minY; -+ private final int height; -+ private final int maxY; -+ private final int minSectionY; -+ private final int maxSectionY; -+ private final int sectionsCount; -+ -+ @Override -+ public int getMinY() { -+ return this.minY; -+ } -+ -+ @Override -+ public int getHeight() { -+ return this.height; -+ } -+ -+ @Override -+ public int getMaxY() { -+ return this.maxY; -+ } -+ -+ @Override -+ public int getSectionsCount() { -+ return this.sectionsCount; -+ } -+ -+ @Override -+ public int getMinSectionY() { -+ return this.minSectionY; -+ } -+ -+ @Override -+ public int getMaxSectionY() { -+ return this.maxSectionY; -+ } -+ -+ @Override -+ public boolean isInsideBuildHeight(final int blockY) { -+ return blockY >= this.minY && blockY <= this.maxY; -+ } -+ -+ @Override -+ public boolean isOutsideBuildHeight(final BlockPos pos) { -+ return this.isOutsideBuildHeight(pos.getY()); -+ } -+ -+ @Override -+ public boolean isOutsideBuildHeight(final int blockY) { -+ return blockY < this.minY || blockY > this.maxY; -+ } -+ -+ @Override -+ public int getSectionIndex(final int blockY) { -+ return (blockY >> 4) - this.minSectionY; -+ } -+ -+ @Override -+ public int getSectionIndexFromSectionY(final int sectionY) { -+ return sectionY - this.minSectionY; -+ } -+ -+ @Override -+ public int getSectionYFromSectionIndex(final int sectionIdx) { -+ return sectionIdx + this.minSectionY; -+ } -+ // Paper end - getblock optimisations - cache world height/sections - // Paper start - optimise random ticking - @Override - public abstract Holder getUncachedNoiseBiome(final int x, final int y, final int z); -@@ -669,6 +760,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - // Paper end - optimise random ticking - - protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator) { // Paper - create paper world config -+ // Paper start - getblock optimisations - cache world height/sections -+ final DimensionType dimType = holder.value(); -+ this.minY = dimType.minY(); -+ this.height = dimType.height(); -+ this.maxY = this.minY + this.height - 1; -+ this.minSectionY = this.minY >> 4; -+ this.maxSectionY = this.maxY >> 4; -+ this.sectionsCount = this.maxSectionY - this.minSectionY + 1; -+ // Paper end - getblock optimisations - cache world height/sections - this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot - this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config - this.generator = gen; -@@ -1573,7 +1673,16 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - if (slices == null) { - return new org.bukkit.entity.Entity[0]; - } -- return slices.getChunkEntities(); -+ -+ List ret = new java.util.ArrayList<>(); -+ for (Entity entity : slices.getAllEntities()) { -+ org.bukkit.entity.Entity bukkit = entity.getBukkitEntity(); -+ if (bukkit != null && bukkit.isValid()) { -+ ret.add(bukkit); -+ } -+ } -+ -+ return ret.toArray(new org.bukkit.entity.Entity[0]); - } - // Paper end - rewrite chunk system - -diff --git a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java -index 01352cc83b25eb0e30b7e0ff521fc7c1b3d5155b..90f8360f547ce709fd13ee34f8e67d8bfa94b498 100644 ---- a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java -+++ b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java -@@ -98,8 +98,7 @@ public class BiomeManager { - } - - private static double getFiddle(long l) { -- double d = (double)Math.floorMod(l >> 24, 1024) / 1024.0; -- return (d - 0.5) * 0.9; -+ return (double)(((l >> 24) & (1024 - 1)) - (1024/2)) * (0.9 / 1024.0); // Paper - avoid floorMod, fp division, and fp subtraction - } - - public interface NoiseBiomeSource { -diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -index a4b4fd83d201fff005c738c84fa5c1bc55d670bd..8631655a181735df53f8a02c9eb98f0cc13f55bb 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -+++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -@@ -838,18 +838,12 @@ public abstract class BlockBehaviour implements FeatureElement { - private int lightBlock; - - // Paper start - rewrite chunk system -- private int opacityIfCached; - private boolean isConditionallyFullOpaque; - - @Override - public final boolean starlight$isConditionallyFullOpaque() { - return this.isConditionallyFullOpaque; - } -- -- @Override -- public final int starlight$getOpacityIfCached() { -- return this.opacityIfCached; -- } - // Paper end - rewrite chunk system - // Paper start - optimise collisions - private static final int RANDOM_OFFSET = 704237939; -@@ -859,16 +853,22 @@ public abstract class BlockBehaviour implements FeatureElement { - private final int id2 = it.unimi.dsi.fastutil.HashCommon.murmurHash3(it.unimi.dsi.fastutil.HashCommon.murmurHash3(ID_GENERATOR.getAndIncrement() + RANDOM_OFFSET) + RANDOM_OFFSET); - private boolean occludesFullBlock; - private boolean emptyCollisionShape; -+ private boolean emptyConstantCollisionShape; - private VoxelShape constantCollisionShape; -- private AABB constantAABBCollision; - -- private static void initCaches(final VoxelShape shape) { -+ private static void initCaches(final VoxelShape shape, final boolean neighbours) { - ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$isFullBlock(); - ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$occludesFullBlock(); - shape.toAabbs(); - if (!shape.isEmpty()) { - shape.bounds(); - } -+ if (neighbours) { -+ for (final Direction direction : DIRECTIONS_CACHED) { -+ initCaches(((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$getFaceShapeClamped(direction), false); -+ initCaches(shape.getFaceShape(direction), false); -+ } -+ } - } - - @Override -@@ -886,6 +886,11 @@ public abstract class BlockBehaviour implements FeatureElement { - return this.emptyCollisionShape; - } - -+ @Override -+ public final boolean moonrise$emptyContextCollisionShape() { -+ return this.emptyConstantCollisionShape; -+ } -+ - @Override - public final int moonrise$uniqueId1() { - return this.id1; -@@ -897,14 +902,9 @@ public abstract class BlockBehaviour implements FeatureElement { - } - - @Override -- public final VoxelShape moonrise$getConstantCollisionShape() { -+ public final VoxelShape moonrise$getConstantContextCollisionShape() { - return this.constantCollisionShape; - } -- -- @Override -- public final AABB moonrise$getConstantCollisionAABB() { -- return this.constantAABBCollision; -- } - // Paper end - optimise collisions - - protected BlockStateBase(Block block, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { -@@ -993,39 +993,37 @@ public abstract class BlockBehaviour implements FeatureElement { - this.lightBlock = ((Block) this.owner).getLightBlock(this.asState()); - // Paper start - rewrite chunk system - this.isConditionallyFullOpaque = this.canOcclude & this.useShapeForLightOcclusion; -- this.opacityIfCached = this.cache == null || this.isConditionallyFullOpaque ? -1 : this.cache.lightBlock; - // Paper end - rewrite chunk system - // Paper start - optimise collisions - if (this.cache != null) { - final VoxelShape collisionShape = this.cache.collisionShape; - try { - this.constantCollisionShape = this.getCollisionShape(null, null, null); -- this.constantAABBCollision = this.constantCollisionShape == null ? null : ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)this.constantCollisionShape).moonrise$getSingleAABBRepresentation(); - } catch (final Throwable throwable) { - this.constantCollisionShape = null; -- this.constantAABBCollision = null; - } - this.occludesFullBlock = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)collisionShape).moonrise$occludesFullBlock(); - this.emptyCollisionShape = collisionShape.isEmpty(); -+ this.emptyConstantCollisionShape = this.constantCollisionShape != null && this.constantCollisionShape.isEmpty(); - // init caches -- initCaches(collisionShape); -- if (collisionShape != Shapes.empty() && collisionShape != Shapes.block()) { -- for (final Direction direction : DIRECTIONS_CACHED) { -- // initialise the directional face shape cache as well -- final VoxelShape shape = Shapes.getFaceShape(collisionShape, direction); -- initCaches(shape); -- } -- } -- if (this.cache.occlusionShapes != null) { -- for (final VoxelShape shape : this.cache.occlusionShapes) { -- initCaches(shape); -- } -+ initCaches(collisionShape, true); -+ if (this.constantCollisionShape != null) { -+ initCaches(this.constantCollisionShape, true); - } - } else { - this.occludesFullBlock = false; - this.emptyCollisionShape = false; -+ this.emptyConstantCollisionShape = false; - this.constantCollisionShape = null; -- this.constantAABBCollision = null; -+ } -+ -+ if (this.occlusionShape != null) { -+ initCaches(this.occlusionShape, true); -+ } -+ if (this.occlusionShapesByFace != null) { -+ for (final VoxelShape shape : this.occlusionShapesByFace) { -+ initCaches(shape, true); -+ } - } - // Paper end - optimise collisions - } -diff --git a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java -index 422b364764e0df16ca250b4939d7b226e69c0840..2df28ffc731bd77e0d7af3541cfd3741aa5af83b 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java -+++ b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java -@@ -15,7 +15,7 @@ import java.util.stream.Collectors; - import javax.annotation.Nullable; - import net.minecraft.world.level.block.state.properties.Property; - --public abstract class StateHolder { -+public abstract class StateHolder implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccessStateHolder { // Paper - optimise blockstate property access - public static final String NAME_TAG = "Name"; - public static final String PROPERTIES_TAG = "Properties"; - public static final Function, Comparable>, String> PROPERTY_ENTRY_TO_STRING_FUNCTION = new Function, Comparable>, String>() { -@@ -34,14 +34,28 @@ public abstract class StateHolder { - } - }; - protected final O owner; -- private final Reference2ObjectArrayMap, Comparable> values; -+ private Reference2ObjectArrayMap, Comparable> values; // Paper - optimise blockstate property access - remove final - private Map, S[]> neighbours; - protected final MapCodec propertiesCodec; - -+ // Paper start - optimise blockstate property access -+ protected ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.util.ZeroCollidingReferenceStateTable optimisedTable; -+ protected final long tableIndex; -+ -+ @Override -+ public final long moonrise$getTableIndex() { -+ return this.tableIndex; -+ } -+ // Paper end - optimise blockstate property access -+ - protected StateHolder(O owner, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { - this.owner = owner; - this.values = propertyMap; - this.propertiesCodec = codec; -+ // Paper start - optimise blockstate property access -+ this.optimisedTable = new ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.util.ZeroCollidingReferenceStateTable<>(this.values.keySet()); -+ this.tableIndex = this.optimisedTable.getIndex((StateHolder)(Object)this); -+ // Paper end - optimise blockstate property access - } - - public > S cycle(Property property) { -@@ -67,20 +81,21 @@ public abstract class StateHolder { - } - - public Collection> getProperties() { -- return Collections.unmodifiableCollection(this.values.keySet()); -+ return this.optimisedTable.getProperties(); // Paper - optimise blockstate property access - } - - public > boolean hasProperty(Property property) { -- return this.values.containsKey(property); -+ return property != null && this.optimisedTable.hasProperty(property); // Paper - optimise blockstate property access - } - - public > T getValue(Property property) { -- Comparable comparable = this.values.get(property); -- if (comparable == null) { -- throw new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.owner); -- } else { -- return property.getValueClass().cast(comparable); -+ // Paper start - optimise blockstate property access -+ final T ret = this.optimisedTable.get(this.tableIndex, property); -+ if (ret != null) { -+ return ret; - } -+ throw new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.owner); -+ // Paper end - optimise blockstate property access - } - - public > Optional getOptionalValue(Property property) { -@@ -93,22 +108,30 @@ public abstract class StateHolder { - - @Nullable - public > T getNullableValue(Property property) { -- Comparable comparable = this.values.get(property); -- return comparable == null ? null : property.getValueClass().cast(comparable); -+ return property == null ? null : this.optimisedTable.get(this.tableIndex, property); // Paper - optimise blockstate property access - } - - public , V extends T> S setValue(Property property, V value) { -- Comparable comparable = this.values.get(property); -- if (comparable == null) { -- throw new IllegalArgumentException("Cannot set property " + property + " as it does not exist in " + this.owner); -- } else { -- return this.setValueInternal(property, value, comparable); -+ // Paper start - optimise blockstate property access -+ final S ret = this.optimisedTable.set(this.tableIndex, property, value); -+ if (ret != null) { -+ return ret; - } -+ throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner); -+ // Paper end - optimise blockstate property access - } - - public , V extends T> S trySetValue(Property property, V value) { -- Comparable comparable = this.values.get(property); -- return (S)(comparable == null ? this : this.setValueInternal(property, value, comparable)); -+ // Paper start - optimise blockstate property access -+ if (property == null) { -+ return (S)(StateHolder)(Object)this; -+ } -+ final S ret = this.optimisedTable.trySet(this.tableIndex, property, value, (S)(StateHolder)(Object)this); -+ if (ret != null) { -+ return ret; -+ } -+ throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner); -+ // Paper end - optimise blockstate property access - } - - private , V extends T> S setValueInternal(Property property, V newValue, Comparable oldValue) { -@@ -125,18 +148,27 @@ public abstract class StateHolder { - } - - public void populateNeighbours(Map, Comparable>, S> states) { -- if (this.neighbours != null) { -- throw new IllegalStateException(); -- } else { -- Map, S[]> map = new Reference2ObjectArrayMap<>(this.values.size()); -+ // Paper start - optimise blockstate property access -+ final Map, Comparable>, S> map = states; -+ if (this.optimisedTable.isLoaded()) { -+ return; -+ } -+ this.optimisedTable.loadInTable(map); - -- for (Entry, Comparable> entry : this.values.entrySet()) { -- Property property = entry.getKey(); -- map.put(property, property.getPossibleValues().stream().map(value -> states.get(this.makeNeighbourValues(property, value))).toArray()); -- } -+ // de-duplicate the tables -+ for (final Map.Entry, Comparable>, S> entry : map.entrySet()) { -+ final S value = entry.getValue(); -+ ((StateHolder)value).optimisedTable = this.optimisedTable; -+ } - -- this.neighbours = map; -+ // remove values arrays -+ for (final Map.Entry, Comparable>, S> entry : map.entrySet()) { -+ final S value = entry.getValue(); -+ ((StateHolder)value).values = null; - } -+ -+ return; -+ // Paper end optimise blockstate property access - } - - private Map, Comparable> makeNeighbourValues(Property property, Comparable value) { -@@ -146,7 +178,11 @@ public abstract class StateHolder { - } - - public Map, Comparable> getValues() { -- return this.values; -+ // Paper start - optimise blockstate property access -+ ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.util.ZeroCollidingReferenceStateTable table = this.optimisedTable; -+ // We have to use this.values until the table is loaded -+ return table.isLoaded() ? table.getMapView(this.tableIndex) : this.values; -+ // Paper end - optimise blockstate property access - } - - protected static > Codec codec(Codec codec, Function ownerToStateFunction) { -diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java -index ea76aa490358e9e1d13350ba0ea246ec2c423894..98058505d36baf74008da08339afc196713b14a7 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java -+++ b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java -@@ -3,13 +3,23 @@ package net.minecraft.world.level.block.state.properties; - import java.util.List; - import java.util.Optional; - --public final class BooleanProperty extends Property { -+public final class BooleanProperty extends Property implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access - private static final List VALUES = List.of(true, false); - private static final int TRUE_INDEX = 0; - private static final int FALSE_INDEX = 1; - -+ // Paper start - optimise blockstate property access -+ private static final Boolean[] BY_ID = new Boolean[]{ Boolean.FALSE, Boolean.TRUE }; -+ -+ @Override -+ public final int moonrise$getIdFor(final Boolean value) { -+ return value.booleanValue() ? 1 : 0; -+ } -+ // Paper end - optimise blockstate property access -+ - private BooleanProperty(String name) { - super(name, Boolean.class); -+ this.moonrise$setById(BY_ID); // Paper - optimise blockstate property access - } - - @Override -diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java -index 85a197232be9377c0313ec00e8f935551e2c60e0..30b2fce9e47ffcc3de1542b1d0f073f5640127a7 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java -+++ b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java -@@ -10,11 +10,39 @@ import java.util.function.Predicate; - import java.util.stream.Collectors; - import net.minecraft.util.StringRepresentable; - --public final class EnumProperty & StringRepresentable> extends Property { -+public final class EnumProperty & StringRepresentable> extends Property implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access - private final List values; - private final Map names; - private final int[] ordinalToIndex; - -+ // Paper start - optimise blockstate property access -+ private int[] idLookupTable; -+ -+ @Override -+ public final int moonrise$getIdFor(final T value) { -+ final Class target = this.getValueClass(); -+ return ((value.getClass() != target && value.getDeclaringClass() != target)) ? -1 : this.idLookupTable[value.ordinal()]; -+ } -+ -+ private void init() { -+ final java.util.Collection values = this.getPossibleValues(); -+ final Class clazz = this.getValueClass(); -+ -+ int id = 0; -+ this.idLookupTable = new int[clazz.getEnumConstants().length]; -+ Arrays.fill(this.idLookupTable, -1); -+ final T[] byId = (T[])java.lang.reflect.Array.newInstance(clazz, values.size()); -+ -+ for (final T value : values) { -+ final int valueId = id++; -+ this.idLookupTable[value.ordinal()] = valueId; -+ byId[valueId] = value; -+ } -+ -+ this.moonrise$setById(byId); -+ } -+ // Paper end - optimise blockstate property access -+ - private EnumProperty(String name, Class type, List values) { - super(name, type); - if (values.isEmpty()) { -@@ -37,6 +65,7 @@ public final class EnumProperty & StringRepresentable> extends - - this.names = builder.buildOrThrow(); - } -+ this.init(); // Paper - optimise blockstate property access - } - - @Override -diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java -index 55a87592a99105dbf57b26fb6ccba695295fce24..986365acc9983331a7982ea2e1eac2b0efe1506d 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java -+++ b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java -@@ -5,11 +5,33 @@ import java.util.List; - import java.util.Optional; - import java.util.stream.IntStream; - --public final class IntegerProperty extends Property { -+public final class IntegerProperty extends Property implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access - private final IntImmutableList values; - public final int min; - public final int max; - -+ // Paper start - optimise blockstate property access -+ @Override -+ public final int moonrise$getIdFor(final Integer value) { -+ final int val = value.intValue(); -+ final int ret = val - this.min; -+ -+ return ret | ((this.max - ret) >> 31); -+ } -+ -+ private void init() { -+ final int min = this.min; -+ final int max = this.max; -+ -+ final Integer[] byId = new Integer[max - min + 1]; -+ for (int i = min; i <= max; ++i) { -+ byId[i - min] = Integer.valueOf(i); -+ } -+ -+ this.moonrise$setById(byId); -+ } -+ // Paper end - optimise blockstate property access -+ - private IntegerProperty(String name, int min, int max) { - super(name, Integer.class); - if (min < 0) { -@@ -21,6 +43,7 @@ public final class IntegerProperty extends Property { - this.max = max; - this.values = IntImmutableList.toList(IntStream.range(min, max + 1)); - } -+ this.init(); // Paper - optimise blockstate property access - } - - @Override -diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java -index fcf04c5c58ff35d38c5bf0df562ae2f8dc98a0ee..0b116160924300a9d62ad5948bfaf276f0386e4d 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java -+++ b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java -@@ -10,7 +10,7 @@ import java.util.stream.Stream; - import javax.annotation.Nullable; - import net.minecraft.world.level.block.state.StateHolder; - --public abstract class Property> { -+public abstract class Property> implements ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.PropertyAccess { // Paper - optimise blockstate property access - private final Class clazz; - private final String name; - @Nullable -@@ -24,9 +24,38 @@ public abstract class Property> { - ); - private final Codec> valueCodec = this.codec.xmap(this::value, Property.Value::value); - -+ // Paper start - optimise blockstate property access -+ private static final java.util.concurrent.atomic.AtomicInteger ID_GENERATOR = new java.util.concurrent.atomic.AtomicInteger(); -+ private final int id; -+ private T[] byId; -+ -+ @Override -+ public final int moonrise$getId() { -+ return this.id; -+ } -+ -+ @Override -+ public final T moonrise$getById(final int id) { -+ final T[] byId = this.byId; -+ return id < 0 || id >= byId.length ? null : this.byId[id]; -+ } -+ -+ @Override -+ public final void moonrise$setById(final T[] byId) { -+ if (this.byId != null) { -+ throw new IllegalStateException(); -+ } -+ this.byId = byId; -+ } -+ -+ @Override -+ public abstract int moonrise$getIdFor(final T value); -+ // Paper end - optimise blockstate property access -+ - protected Property(String name, Class type) { - this.clazz = type; - this.name = name; -+ this.id = ID_GENERATOR.getAndIncrement(); // Paper - optimise blockstate property access - } - - public Property.Value value(T value) { -diff --git a/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java b/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java -index 98dbeaf8bde15940e5b5d5d1f13fd4bb32f0a10d..7beea075b5a7ef738a4ac0558b99f4c5708f2c4a 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java -+++ b/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java -@@ -8,12 +8,19 @@ import net.minecraft.network.FriendlyByteBuf; - import net.minecraft.network.VarInt; - import net.minecraft.util.CrudeIncrementalIntIdentityHashBiMap; - --public class HashMapPalette implements Palette { -+public class HashMapPalette implements Palette, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Paper - optimise palette reads - private final IdMap registry; - private final CrudeIncrementalIntIdentityHashBiMap values; - private final PaletteResize resizeHandler; - private final int bits; - -+ // Paper start - optimise palette reads -+ @Override -+ public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData container) { -+ return ((ca.spottedleaf.moonrise.patches.fast_palette.FastPalette)this.values).moonrise$getRawPalette(container); -+ } -+ // Paper end - optimise palette reads -+ - public HashMapPalette(IdMap idList, int bits, PaletteResize listener, List entries) { - this(idList, bits, listener); - entries.forEach(this.values::add); -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 a61294befc2f855fcecb2336a2d5444ce60e0a3a..a0e51681731dc7b487d5b14ae0d44a881bd5cb09 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -54,7 +54,7 @@ import net.minecraft.world.ticks.LevelChunkTicks; - import net.minecraft.world.ticks.TickContainerAccess; - import org.slf4j.Logger; - --public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk, ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk, ca.spottedleaf.moonrise.patches.chunk_getblock.GetBlockChunk { // Paper - rewrite chunk system // Paper - get block chunk optimisation -+public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk, ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk, ca.spottedleaf.moonrise.patches.getblock.GetBlockChunk { // Paper - rewrite chunk system // Paper - get block chunk optimisation - - static final Logger LOGGER = LogUtils.getLogger(); - private static final TickingBlockEntity NULL_TICKER = new TickingBlockEntity() { -@@ -688,7 +688,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p - */ - org.bukkit.Chunk bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); - server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(bukkitChunk, this.needsDecoration)); -- ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk().callEntitiesLoadEvent(); // Paper - rewrite chunk system -+ org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesLoadEvent(this.level, this.chunkPos, ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk().getAllEntities()); // Paper - rewrite chunk system - - if (this.needsDecoration) { - try (co.aikar.timings.Timing ignored = this.level.timings.chunkLoadPopulate.startTiming()) { // Paper -@@ -719,7 +719,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p - public void unloadCallback() { - if (!this.loadedTicketLevel) { LOGGER.error("Double calling chunk unload!", new Throwable()); } // Paper - org.bukkit.Server server = this.level.getCraftServer(); -- ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk().callEntitiesUnloadEvent(); // Paper - rewrite chunk system -+ org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesUnloadEvent(this.level, this.chunkPos, ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk().getAllEntities()); // Paper - rewrite chunk system - org.bukkit.Chunk bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); - org.bukkit.event.world.ChunkUnloadEvent unloadEvent = new org.bukkit.event.world.ChunkUnloadEvent(bukkitChunk, true); // Paper - rewrite chunk system - force save to true so that mustNotSave is correctly set below - server.getPluginManager().callEvent(unloadEvent); -diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -index 161211124f3f8390530af7ab21f3a0f1025209c5..4167ed830382c6a76bb281e9d753919925c6bd00 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -@@ -26,15 +26,17 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ - private PalettedContainer> biomes; // CraftBukkit - read/write - - // Paper start - block counting -- private static final it.unimi.dsi.fastutil.ints.IntArrayList FULL_LIST = new it.unimi.dsi.fastutil.ints.IntArrayList(16*16*16); -+ private static final it.unimi.dsi.fastutil.shorts.ShortArrayList FULL_LIST = new it.unimi.dsi.fastutil.shorts.ShortArrayList(16*16*16); - static { -- for (int i = 0; i < (16*16*16); ++i) { -+ for (short i = 0; i < (16*16*16); ++i) { - FULL_LIST.add(i); - } - } - -- private int specialCollidingBlocks; -- private final ca.spottedleaf.moonrise.common.list.IBlockDataList tickingBlocks = new ca.spottedleaf.moonrise.common.list.IBlockDataList(); -+ private boolean isClient; -+ private static final short CLIENT_FORCED_SPECIAL_COLLIDING_BLOCKS = (short)9999; -+ private short specialCollidingBlocks; -+ private final ca.spottedleaf.moonrise.common.list.ShortList tickingBlocks = new ca.spottedleaf.moonrise.common.list.ShortList(); - - @Override - public final int moonrise$getSpecialCollidingBlocks() { -@@ -42,7 +44,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ - } - - @Override -- public final ca.spottedleaf.moonrise.common.list.IBlockDataList moonrise$getTickingBlockList() { -+ public final ca.spottedleaf.moonrise.common.list.ShortList moonrise$getTickingBlockList() { - return this.tickingBlocks; - } - // Paper end - block counting -@@ -86,6 +88,45 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ - return this.setBlockState(x, y, z, state, true); - } - -+ // Paper start - block counting -+ private void updateBlockCallback(final int x, final int y, final int z, final BlockState newState, -+ final BlockState oldState) { -+ if (oldState == newState) { -+ return; -+ } -+ -+ if (this.isClient) { -+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(newState)) { -+ this.specialCollidingBlocks = CLIENT_FORCED_SPECIAL_COLLIDING_BLOCKS; -+ } -+ return; -+ } -+ -+ final boolean isSpecialOld = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(oldState); -+ final boolean isSpecialNew = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(newState); -+ if (isSpecialOld != isSpecialNew) { -+ if (isSpecialOld) { -+ --this.specialCollidingBlocks; -+ } else { -+ ++this.specialCollidingBlocks; -+ } -+ } -+ -+ final boolean oldTicking = oldState.isRandomlyTicking(); -+ final boolean newTicking = newState.isRandomlyTicking(); -+ if (oldTicking != newTicking) { -+ final ca.spottedleaf.moonrise.common.list.ShortList tickingBlocks = this.tickingBlocks; -+ final short position = (short)(x | (z << 4) | (y << (4+4))); -+ -+ if (oldTicking) { -+ tickingBlocks.remove(position); -+ } else { -+ tickingBlocks.add(position); -+ } -+ } -+ } -+ // Paper end - block counting -+ - public BlockState setBlockState(int x, int y, int z, BlockState state, boolean lock) { - BlockState iblockdata1; - -@@ -105,7 +146,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ - } - } - -- if (!fluid.isEmpty()) { -+ if (!!fluid.isRandomlyTicking()) { // Paper - block counting - --this.tickingFluidCount; - } - -@@ -116,25 +157,11 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ - } - } - -- if (!fluid1.isEmpty()) { -+ if (!!fluid1.isRandomlyTicking()) { // Paper - block counting - ++this.tickingFluidCount; - } - -- // Paper start - block counting -- if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(iblockdata1)) { -- --this.specialCollidingBlocks; -- } -- if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(state)) { -- ++this.specialCollidingBlocks; -- } -- -- if (iblockdata1.isRandomlyTicking()) { -- this.tickingBlocks.remove(x, y, z); -- } -- if (state.isRandomlyTicking()) { -- this.tickingBlocks.add(x, y, z, state); -- } -- // Paper end - block counting -+ this.updateBlockCallback(x, y, z, state, iblockdata1); // Paper - block counting - - return iblockdata1; - } -@@ -170,7 +197,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ - final int paletteSize = palette.getSize(); - final net.minecraft.util.BitStorage storage = data.storage(); - -- final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap counts; -+ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap counts; - if (paletteSize == 1) { - counts = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1); - counts.put(0, FULL_LIST); -@@ -178,10 +205,10 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ - counts = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingBitStorage)storage).moonrise$countEntries(); - } - -- for (final java.util.Iterator> iterator = counts.int2ObjectEntrySet().fastIterator(); iterator.hasNext();) { -- final it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry entry = iterator.next(); -+ for (final java.util.Iterator> iterator = counts.int2ObjectEntrySet().fastIterator(); iterator.hasNext();) { -+ final it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry entry = iterator.next(); - final int paletteIdx = entry.getIntKey(); -- final it.unimi.dsi.fastutil.ints.IntArrayList coordinates = entry.getValue(); -+ final it.unimi.dsi.fastutil.shorts.ShortArrayList coordinates = entry.getValue(); - final int paletteCount = coordinates.size(); - - final BlockState state = palette.valueFor(paletteIdx); -@@ -191,25 +218,30 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ - } - - if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(state)) { -- this.specialCollidingBlocks += paletteCount; -+ this.specialCollidingBlocks += (short)paletteCount; - } -- this.nonEmptyBlockCount += paletteCount; -+ this.nonEmptyBlockCount += (short)paletteCount; - if (state.isRandomlyTicking()) { -- this.tickingBlockCount += paletteCount; -- final int[] raw = coordinates.elements(); -+ this.tickingBlockCount += (short)paletteCount; -+ final short[] raw = coordinates.elements(); -+ final int rawLen = raw.length; -+ -+ final ca.spottedleaf.moonrise.common.list.ShortList tickingBlocks = this.tickingBlocks; -+ -+ tickingBlocks.setMinCapacity(Math.min((rawLen + tickingBlocks.size()) * 3 / 2, 16*16*16)); - - java.util.Objects.checkFromToIndex(0, paletteCount, raw.length); - for (int i = 0; i < paletteCount; ++i) { -- this.tickingBlocks.add(raw[i], state); -+ tickingBlocks.add(raw[i]); - } - } - - final FluidState fluid = state.getFluidState(); - - if (!fluid.isEmpty()) { -- //this.nonEmptyBlockCount += count; // fix vanilla bug: make non empty block count correct -+ //this.nonEmptyBlockCount += count; // fix vanilla bug: make non-empty block count correct - if (fluid.isRandomlyTicking()) { -- this.tickingFluidCount += paletteCount; -+ this.tickingFluidCount += (short)paletteCount; - } - } - } -@@ -232,7 +264,11 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ - - datapaletteblock.read(buf); - this.biomes = datapaletteblock; -- this.recalcBlockCounts(); // Paper - block counting -+ // Paper start - block counting -+ this.isClient = true; -+ // force has special colliding blocks to be true -+ this.specialCollidingBlocks = this.nonEmptyBlockCount != (short)0 && this.maybeHas(ca.spottedleaf.moonrise.patches.collisions.CollisionUtil::isSpecialCollidingBlock) ? CLIENT_FORCED_SPECIAL_COLLIDING_BLOCKS : (short)0; -+ // Paper end - block counting - } - - public void readBiomes(FriendlyByteBuf buf) { -diff --git a/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java b/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java -index bc4d9452bbeb05a691fd285603e49491f41d3ad2..f8d9892970c9092f7cc84434d4fbf34354ce1195 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java -+++ b/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java -@@ -7,13 +7,20 @@ import net.minecraft.network.FriendlyByteBuf; - import net.minecraft.network.VarInt; - import org.apache.commons.lang3.Validate; - --public class LinearPalette implements Palette { -+public class LinearPalette implements Palette, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Paper - optimise palette reads - private final IdMap registry; - private final T[] values; - private final PaletteResize resizeHandler; - private final int bits; - private int size; - -+ // Paper start - optimise palette reads -+ @Override -+ public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData container) { -+ return this.values; -+ } -+ // Paper end - optimise palette reads -+ - private LinearPalette(IdMap idList, int bits, PaletteResize listener, List list) { - this.registry = idList; - this.values = (T[])(new Object[1 << bits]); -diff --git a/src/main/java/net/minecraft/world/level/chunk/Palette.java b/src/main/java/net/minecraft/world/level/chunk/Palette.java -index b8922e4a13df535cdc5701e893a6e460b33ff90d..100807f8b8337f56f49cdb818ccc75be2f08ecd1 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/Palette.java -+++ b/src/main/java/net/minecraft/world/level/chunk/Palette.java -@@ -5,7 +5,7 @@ import java.util.function.Predicate; - import net.minecraft.core.IdMap; - import net.minecraft.network.FriendlyByteBuf; - --public interface Palette { -+public interface Palette extends ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Paper - optimise palette reads - int idFor(T object); - - boolean maybeHas(Predicate predicate); -diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -index b46c58c952e183bd74854c3eb70d64979af70f18..533167eaa8bd39006fb1c7e193c81359973da9af 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -@@ -71,6 +71,33 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - ); - } - -+ // Paper start - optimise palette reads -+ private void updateData(final PalettedContainer.Data data) { -+ if (data != null) { -+ ((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData)(Object)data).moonrise$setPalette( -+ ((ca.spottedleaf.moonrise.patches.fast_palette.FastPalette)data.palette).moonrise$getRawPalette((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData)(Object)data) -+ ); -+ } -+ } -+ -+ private T readPaletteSlow(final PalettedContainer.Data data, final int paletteIdx) { -+ return data.palette.valueFor(paletteIdx); -+ } -+ -+ private T readPalette(final PalettedContainer.Data data, final int paletteIdx) { -+ final T[] palette = ((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData)(Object)data).moonrise$getPalette(); -+ if (palette == null) { -+ return this.readPaletteSlow(data, paletteIdx); -+ } -+ -+ final T ret = palette[paletteIdx]; -+ if (ret == null) { -+ throw new IllegalArgumentException("Palette index out of bounds"); -+ } -+ return ret; -+ } -+ // Paper end - optimise palette reads -+ - public PalettedContainer( - IdMap idList, - PalettedContainer.Strategy paletteProvider, -@@ -81,12 +108,14 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - this.registry = idList; - this.strategy = paletteProvider; - this.data = new PalettedContainer.Data<>(dataProvider, storage, dataProvider.factory().create(dataProvider.bits(), idList, this, paletteEntries)); -+ this.updateData(this.data); // Paper - optimise palette reads - } - - private PalettedContainer(IdMap idList, PalettedContainer.Strategy paletteProvider, PalettedContainer.Data data) { - this.registry = idList; - this.strategy = paletteProvider; - this.data = data; -+ this.updateData(this.data); // Paper - optimise palette reads - } - - private PalettedContainer(PalettedContainer container) { -@@ -100,6 +129,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - this.registry = idList; - this.data = this.createOrReuseData(null, 0); - this.data.palette.idFor(object); -+ this.updateData(this.data); // Paper - optimise palette reads - } - - private PalettedContainer.Data createOrReuseData(@Nullable PalettedContainer.Data previousData, int bits) { -@@ -115,6 +145,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - PalettedContainer.Data data2 = this.createOrReuseData(data, newBits); - data2.copyFrom(data.palette, data.storage); - this.data = data2; -+ this.updateData(this.data); // Paper - optimise palette reads - return data2.palette.idFor(object); - } - -@@ -136,9 +167,12 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - } - - private synchronized T getAndSet(int index, T value) { // Paper - synchronize -- int i = this.data.palette.idFor(value); -- int j = this.data.storage.getAndSet(index, i); -- return this.data.palette.valueFor(j); -+ // Paper start - optimise palette reads -+ final int paletteIdx = this.data.palette.idFor(value); -+ final PalettedContainer.Data data = this.data; -+ final int prev = data.storage.getAndSet(index, paletteIdx); -+ return this.readPalette(data, prev); -+ // Paper end - optimise palette reads - } - - public void set(int x, int y, int z, T value) { -@@ -162,8 +196,10 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - } - - public T get(int index) { // Paper - public -- PalettedContainer.Data data = this.data; -- return data.palette.valueFor(data.storage.get(index)); -+ // Paper start - optimise palette reads -+ final PalettedContainer.Data data = this.data; -+ return this.readPalette(data, data.storage.get(index)); -+ // Paper end - optimise palette reads - } - - @Override -@@ -183,6 +219,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - data.palette.read(buf); - buf.readLongArray(data.storage.getRaw()); - this.data = data; -+ this.updateData(this.data); // Paper - optimise palette reads - } finally { - this.release(); - } -@@ -323,7 +360,44 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - void accept(T object, int count); - } - -- static record Data(PalettedContainer.Configuration configuration, BitStorage storage, Palette palette) { -+ // Paper start - optimise palette reads -+ public static final class Data implements ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData { -+ -+ private final PalettedContainer.Configuration configuration; -+ private final BitStorage storage; -+ private final Palette palette; -+ -+ private T[] moonrise$palette; -+ -+ public Data(final PalettedContainer.Configuration configuration, final BitStorage storage, final Palette palette) { -+ this.configuration = configuration; -+ this.storage = storage; -+ this.palette = palette; -+ } -+ -+ public PalettedContainer.Configuration configuration() { -+ return this.configuration; -+ } -+ -+ public BitStorage storage() { -+ return this.storage; -+ } -+ -+ public Palette palette() { -+ return this.palette; -+ } -+ -+ @Override -+ public final T[] moonrise$getPalette() { -+ return this.moonrise$palette; -+ } -+ -+ @Override -+ public final void moonrise$setPalette(final T[] palette) { -+ this.moonrise$palette = palette; -+ } -+ // Paper end - optimise palette reads -+ - public void copyFrom(Palette palette, BitStorage storage) { - for (int i = 0; i < storage.getSize(); i++) { - T object = palette.valueFor(storage.get(i)); -diff --git a/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java b/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java -index a45e6410600afc5464e5d29932c193786ce0a6fb..a1ba68c95c2cdebdc0d7782cce7895529918073c 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java -+++ b/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java -@@ -8,12 +8,24 @@ import net.minecraft.network.FriendlyByteBuf; - import net.minecraft.network.VarInt; - import org.apache.commons.lang3.Validate; - --public class SingleValuePalette implements Palette { -+public class SingleValuePalette implements Palette, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Paper - optimise palette reads - private final IdMap registry; - @Nullable - private T value; - private final PaletteResize resizeHandler; - -+ // Paper start - optimise palette reads -+ private T[] rawPalette; -+ -+ @Override -+ public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData container) { -+ if (this.rawPalette != null) { -+ return this.rawPalette; -+ } -+ return this.rawPalette = (T[])new Object[] { this.value }; -+ } -+ // Paper end - optimise palette reads -+ - public SingleValuePalette(IdMap idList, PaletteResize listener, List entries) { - this.registry = idList; - this.resizeHandler = listener; -@@ -33,6 +45,11 @@ public class SingleValuePalette implements Palette { - return this.resizeHandler.onResize(1, object); - } else { - this.value = object; -+ // Paper start - optimise palette reads -+ if (this.rawPalette != null) { -+ this.rawPalette[0] = object; -+ } -+ // Paper end - optimise palette reads - return 0; - } - } -@@ -58,6 +75,11 @@ public class SingleValuePalette implements Palette { - @Override - public void read(FriendlyByteBuf buf) { - this.value = this.registry.byIdOrThrow(buf.readVarInt()); -+ // Paper start - optimise palette reads -+ if (this.rawPalette != null) { -+ this.rawPalette[0] = this.value; -+ } -+ // Paper end - optimise palette reads - } - - @Override -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 f1237f6fd6414900ffbad0caee31aa83310eeef4..8071ce70d66909bb4bda45792bf329a939d6f918 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 -@@ -25,7 +25,7 @@ import net.minecraft.util.profiling.jfr.JvmProfiler; - import net.minecraft.world.level.ChunkPos; - import org.slf4j.Logger; - --public class RegionFile implements AutoCloseable { -+public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile { // Paper - rewrite chunk system - - private static final Logger LOGGER = LogUtils.getLogger(); - private static final int SECTOR_BYTES = 4096; -@@ -49,6 +49,21 @@ public class RegionFile implements AutoCloseable { - @VisibleForTesting - protected final RegionBitmap usedSectors; - -+ // Paper start - rewrite chunk system -+ @Override -+ public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite(final net.minecraft.nbt.CompoundTag data, final ChunkPos pos) throws IOException { -+ final RegionFile.ChunkBuffer buffer = ((RegionFile)(Object)this).new ChunkBuffer(pos); -+ ((ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkBuffer)buffer).moonrise$setWriteOnClose(false); -+ -+ final DataOutputStream out = new DataOutputStream(this.version.wrap(buffer)); -+ -+ return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData( -+ data, ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData.WriteResult.WRITE, -+ out, ((ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkBuffer)buffer)::moonrise$write -+ ); -+ } -+ // Paper end - rewrite chunk system -+ - public RegionFile(RegionStorageInfo storageKey, Path directory, Path path, boolean dsync) throws IOException { - this(storageKey, directory, path, RegionFileVersion.getSelected(), dsync); - } -@@ -220,6 +235,16 @@ public class RegionFile implements AutoCloseable { - - @Nullable - private DataInputStream createExternalChunkInputStream(ChunkPos pos, byte flags) throws IOException { -+ // Paper start - rewrite chunk system -+ final DataInputStream is = this.createExternalChunkInputStream0(pos, flags); -+ if (is == null) { -+ return is; -+ } -+ return new ca.spottedleaf.moonrise.patches.chunk_system.util.stream.ExternalChunkStreamMarker(is); -+ } -+ @Nullable -+ private DataInputStream createExternalChunkInputStream0(ChunkPos pos, byte flags) throws IOException { -+ // Paper end - rewrite chunk system - Path path = this.getExternalChunkPath(pos); - - if (!Files.isRegularFile(path, new LinkOption[0])) { -@@ -443,10 +468,29 @@ public class RegionFile implements AutoCloseable { - } - - public static final int MAX_CHUNK_SIZE = 500 * 1024 * 1024; // Paper - don't write garbage data to disk if writing serialization fails -- private class ChunkBuffer extends ByteArrayOutputStream { -+ private class ChunkBuffer extends ByteArrayOutputStream implements ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkBuffer { // Paper - rewrite chunk system - - private final ChunkPos pos; - -+ // Paper start - rewrite chunk system -+ private boolean writeOnClose = true; -+ -+ @Override -+ public final boolean moonrise$getWriteOnClose() { -+ return this.writeOnClose; -+ } -+ -+ @Override -+ public final void moonrise$setWriteOnClose(final boolean value) { -+ this.writeOnClose = value; -+ } -+ -+ @Override -+ public final void moonrise$write(final RegionFile regionFile) throws IOException { -+ regionFile.write(this.pos, ByteBuffer.wrap(this.buf, 0, this.count)); -+ } -+ // Paper end - rewrite chunk system -+ - public ChunkBuffer(final ChunkPos chunkcoordintpair) { - super(8096); - super.write(0); -@@ -480,7 +524,7 @@ public class RegionFile implements AutoCloseable { - - JvmProfiler.INSTANCE.onRegionFileWrite(RegionFile.this.info, this.pos, RegionFile.this.version, i); - bytebuffer.putInt(0, i); -- RegionFile.this.write(this.pos, bytebuffer); -+ if (this.writeOnClose) { RegionFile.this.write(this.pos, bytebuffer); } // Paper - rewrite chunk system - } - } - -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 18054304e08c8a6346c0135a0e6a68e77fe5c37c..9dbc9e2f9d5aab71720bb81803efe76e2f361f04 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 -@@ -28,8 +28,8 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise - - // Paper start - rewrite chunk system - private static final int REGION_SHIFT = 5; -- private static final int MAX_NON_EXISTING_CACHE = 1024 * 64; -- private final it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet nonExistingRegionFiles = new it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet(MAX_NON_EXISTING_CACHE+1); -+ private static final int MAX_NON_EXISTING_CACHE = 1024 * 4; -+ private final it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet nonExistingRegionFiles = new it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet(); - private static String getRegionFileName(final int chunkX, final int chunkZ) { - return "r." + (chunkX >> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + ".mca"; - } -@@ -104,6 +104,97 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise - - return ret; - } -+ -+ @Override -+ public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite( -+ final int chunkX, final int chunkZ, final CompoundTag compound -+ ) throws IOException { -+ if (compound == null) { -+ return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData( -+ compound, ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData.WriteResult.DELETE, -+ null, null -+ ); -+ } -+ -+ final ChunkPos pos = new ChunkPos(chunkX, chunkZ); -+ final RegionFile regionFile = this.getRegionFile(pos); -+ -+ // note: not required to keep regionfile loaded after this call, as the write param takes a regionfile as input -+ // (and, the regionfile parameter is unused for writing until the write call) -+ final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData writeData = ((ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile)regionFile).moonrise$startWrite(compound, pos); -+ -+ try { -+ NbtIo.write(compound, writeData.output()); -+ } finally { -+ writeData.output().close(); -+ } -+ -+ return writeData; -+ } -+ -+ @Override -+ public final void moonrise$finishWrite( -+ final int chunkX, final int chunkZ, final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData writeData -+ ) throws IOException { -+ final ChunkPos pos = new ChunkPos(chunkX, chunkZ); -+ if (writeData.result() == ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData.WriteResult.DELETE) { -+ final RegionFile regionFile = this.moonrise$getRegionFileIfExists(chunkX, chunkZ); -+ if (regionFile != null) { -+ regionFile.clear(pos); -+ } // else: didn't exist -+ -+ return; -+ } -+ -+ writeData.write().run(this.getRegionFile(pos)); -+ } -+ -+ @Override -+ public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData moonrise$readData( -+ final int chunkX, final int chunkZ -+ ) throws IOException { -+ final RegionFile regionFile = this.moonrise$getRegionFileIfExists(chunkX, chunkZ); -+ -+ final DataInputStream input = regionFile == null ? null : regionFile.getChunkDataInputStream(new ChunkPos(chunkX, chunkZ)); -+ -+ if (input == null) { -+ return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData( -+ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.NO_DATA, null, null -+ ); -+ } -+ -+ final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData ret = new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData( -+ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.HAS_DATA, input, null -+ ); -+ -+ if (!(input instanceof ca.spottedleaf.moonrise.patches.chunk_system.util.stream.ExternalChunkStreamMarker)) { -+ // internal stream, which is fully read -+ return ret; -+ } -+ -+ final CompoundTag syncRead = this.moonrise$finishRead(chunkX, chunkZ, ret); -+ -+ if (syncRead == null) { -+ // need to try again -+ return this.moonrise$readData(chunkX, chunkZ); -+ } -+ -+ return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData( -+ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.SYNC_READ, null, syncRead -+ ); -+ } -+ -+ // if the return value is null, then the caller needs to re-try with a new call to readData() -+ @Override -+ public final CompoundTag moonrise$finishRead( -+ final int chunkX, final int chunkZ, final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData readData -+ ) throws IOException { -+ try { -+ return NbtIo.read(readData.input()); -+ } finally { -+ readData.input().close(); -+ } -+ } - // Paper end - rewrite chunk system - - protected RegionFileStorage(RegionStorageInfo storageKey, Path directory, boolean dsync) { // Paper - protected -@@ -112,6 +203,12 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise - this.info = storageKey; - } - -+ // Paper start - rewrite chunk system -+ public RegionFile getRegionFile(ChunkPos chunkcoordintpair) throws IOException { -+ return this.getRegionFile(chunkcoordintpair, false); -+ } -+ // Paper end - rewrite chunk system -+ - public RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit // Paper - public - // Paper start - rewrite chunk system - if (existingOnly) { -diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -index 261e5994d13f8bc30490b86691c80c0a21e7640a..f4fbcbb8ff6d2677af1a02a0801a323c06dce9b1 100644 ---- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -+++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -@@ -55,6 +55,48 @@ public abstract class FlowingFluid extends Fluid { - }); - private final Map shapes = Maps.newIdentityHashMap(); - -+ // Paper start - fluid method optimisations -+ private FluidState sourceFalling; -+ private FluidState sourceNotFalling; -+ -+ private static final int TOTAL_FLOWING_STATES = FALLING.getPossibleValues().size() * LEVEL.getPossibleValues().size(); -+ private static final int MIN_LEVEL = LEVEL.getPossibleValues().stream().sorted().findFirst().get().intValue(); -+ -+ // index = (falling ? 1 : 0) + level*2 -+ private FluidState[] flowingLookUp; -+ private volatile boolean init; -+ -+ private static final int COLLISION_OCCLUSION_CACHE_SIZE = 2048; -+ private static final ThreadLocal COLLISION_OCCLUSION_CACHE = ThreadLocal.withInitial(() -> new ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey[COLLISION_OCCLUSION_CACHE_SIZE]); -+ -+ -+ /** -+ * Due to init order, we need to use callbacks to initialise our state -+ */ -+ private void init() { -+ synchronized (this) { -+ if (this.init) { -+ return; -+ } -+ this.flowingLookUp = new FluidState[TOTAL_FLOWING_STATES]; -+ final FluidState defaultFlowState = this.getFlowing().defaultFluidState(); -+ for (int i = 0; i < TOTAL_FLOWING_STATES; ++i) { -+ final int falling = i & 1; -+ final int level = (i >>> 1) + MIN_LEVEL; -+ -+ this.flowingLookUp[i] = defaultFlowState.setValue(FALLING, falling == 1 ? Boolean.TRUE : Boolean.FALSE) -+ .setValue(LEVEL, Integer.valueOf(level)); -+ } -+ -+ final FluidState defaultFallState = this.getSource().defaultFluidState(); -+ this.sourceFalling = defaultFallState.setValue(FALLING, Boolean.TRUE); -+ this.sourceNotFalling = defaultFallState.setValue(FALLING, Boolean.FALSE); -+ -+ this.init = true; -+ } -+ } -+ // Paper end - fluid method optimisations -+ - public FlowingFluid() {} - - @Override -@@ -246,65 +288,70 @@ public abstract class FlowingFluid extends Fluid { - } - } - -- private static boolean canPassThroughWall(Direction face, BlockGetter world, BlockPos pos, BlockState state, BlockPos fromPos, BlockState fromState) { -- VoxelShape voxelshape = fromState.getCollisionShape(world, fromPos); -+ // Paper start - fluid method optimisations -+ private static boolean canPassThroughWall(final Direction direction, final BlockGetter level, -+ final BlockPos fromPos, final BlockState fromState, -+ final BlockPos toPos, final BlockState toState) { -+ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$emptyCollisionShape() & ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$emptyCollisionShape()) { -+ // don't even try to cache simple cases -+ return true; -+ } - -- if (voxelshape == Shapes.block()) { -+ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$occludesFullBlock() | ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$occludesFullBlock()) { -+ // don't even try to cache simple cases - return false; -- } else { -- VoxelShape voxelshape1 = state.getCollisionShape(world, pos); -- -- if (voxelshape1 == Shapes.block()) { -- return false; -- } else if (voxelshape1 == Shapes.empty() && voxelshape == Shapes.empty()) { -- return true; -- } else { -- Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap; -- -- if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) { -- object2bytelinkedopenhashmap = (Object2ByteLinkedOpenHashMap) FlowingFluid.OCCLUSION_CACHE.get(); -- } else { -- object2bytelinkedopenhashmap = null; -- } -+ } - -- FlowingFluid.BlockStatePairKey fluidtypeflowing_a; -+ final ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey[] cache = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$hasCache() & ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$hasCache() ? -+ COLLISION_OCCLUSION_CACHE.get() : null; - -- if (object2bytelinkedopenhashmap != null) { -- fluidtypeflowing_a = new FlowingFluid.BlockStatePairKey(state, fromState, face); -- byte b0 = object2bytelinkedopenhashmap.getAndMoveToFirst(fluidtypeflowing_a); -+ final int keyIndex -+ = (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$uniqueId1() ^ ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$uniqueId2() ^ ((ca.spottedleaf.moonrise.patches.collisions.util.CollisionDirection)(Object)direction).moonrise$uniqueId()) -+ & (COLLISION_OCCLUSION_CACHE_SIZE - 1); - -- if (b0 != 127) { -- return b0 != 0; -- } -- } else { -- fluidtypeflowing_a = null; -- } -- -- boolean flag = !Shapes.mergedFaceOccludes(voxelshape1, voxelshape, face); -+ if (cache != null) { -+ final ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey cached = cache[keyIndex]; -+ if (cached != null && cached.first() == fromState && cached.second() == toState && cached.direction() == direction) { -+ return cached.result(); -+ } -+ } - -- if (object2bytelinkedopenhashmap != null) { -- if (object2bytelinkedopenhashmap.size() == 200) { -- object2bytelinkedopenhashmap.removeLastByte(); -- } -+ final VoxelShape shape1 = fromState.getCollisionShape(level, fromPos); -+ final VoxelShape shape2 = toState.getCollisionShape(level, toPos); - -- object2bytelinkedopenhashmap.putAndMoveToFirst(fluidtypeflowing_a, (byte) (flag ? 1 : 0)); -- } -+ final boolean result = !Shapes.mergedFaceOccludes(shape1, shape2, direction); - -- return flag; -- } -+ if (cache != null) { -+ // we can afford to replace in-use keys more often due to the excessive caching the collision patch does in mergedFaceOccludes -+ cache[keyIndex] = new ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey(fromState, toState, direction, result); - } -+ -+ return result; - } -+ // Paper end - fluid method optimisations - - public abstract Fluid getFlowing(); - - public FluidState getFlowing(int level, boolean falling) { -- return (FluidState) ((FluidState) this.getFlowing().defaultFluidState().setValue(FlowingFluid.LEVEL, level)).setValue(FlowingFluid.FALLING, falling); -+ // Paper start - fluid method optimisations -+ final int amount = level; -+ if (!this.init) { -+ this.init(); -+ } -+ final int index = (falling ? 1 : 0) | ((amount - MIN_LEVEL) << 1); -+ return this.flowingLookUp[index]; -+ // Paper end - fluid method optimisations - } - - public abstract Fluid getSource(); - - public FluidState getSource(boolean falling) { -- return (FluidState) this.getSource().defaultFluidState().setValue(FlowingFluid.FALLING, falling); -+ // Paper start - fluid method optimisations -+ if (!this.init) { -+ this.init(); -+ } -+ return falling ? this.sourceFalling : this.sourceNotFalling; -+ // Paper end - fluid method optimisations - } - - protected abstract boolean canConvertToSource(ServerLevel world); -diff --git a/src/main/java/net/minecraft/world/level/material/FluidState.java b/src/main/java/net/minecraft/world/level/material/FluidState.java -index 87adfe152abd1b8b4d547034576883c5d1cdf134..2d50d72bf026d0cf9c546a3c6fc1859379bfd805 100644 ---- a/src/main/java/net/minecraft/world/level/material/FluidState.java -+++ b/src/main/java/net/minecraft/world/level/material/FluidState.java -@@ -22,12 +22,30 @@ import net.minecraft.world.level.block.state.properties.Property; - import net.minecraft.world.phys.Vec3; - import net.minecraft.world.phys.shapes.VoxelShape; - --public final class FluidState extends StateHolder { -+public final class FluidState extends StateHolder implements ca.spottedleaf.moonrise.patches.fluid.FluidFluidState { // Paper - fluid method optimisations - public static final Codec CODEC = codec(BuiltInRegistries.FLUID.byNameCodec(), Fluid::defaultFluidState).stable(); - public static final int AMOUNT_MAX = 9; - public static final int AMOUNT_FULL = 8; - protected final boolean isEmpty; // Paper - Perf: moved from isEmpty() - -+ // Paper start - fluid method optimisations -+ private int amount; -+ //private boolean isEmpty; -+ private boolean isSource; -+ private float ownHeight; -+ private boolean isRandomlyTicking; -+ private BlockState legacyBlock; -+ -+ @Override -+ public final void moonrise$initCaches() { -+ this.amount = this.getType().getAmount((FluidState)(Object)this); -+ //this.isEmpty = this.getType().isEmpty(); -+ this.isSource = this.getType().isSource((FluidState)(Object)this); -+ this.ownHeight = this.getType().getOwnHeight((FluidState)(Object)this); -+ this.isRandomlyTicking = this.getType().isRandomlyTicking(); -+ } -+ // Paper end - fluid method optimisations -+ - public FluidState(Fluid fluid, Reference2ObjectArrayMap, Comparable> propertyMap, MapCodec codec) { - super(fluid, propertyMap, codec); - this.isEmpty = fluid.isEmpty(); // Paper - Perf: moved from isEmpty() -@@ -38,11 +56,11 @@ public final class FluidState extends StateHolder { - } - - public boolean isSource() { -- return this.getType().isSource(this); -+ return this.isSource; // Paper - fluid method optimisations - } - - public boolean isSourceOfType(Fluid fluid) { -- return this.owner == fluid && this.owner.isSource(this); -+ return this.isSource && this.owner == fluid; // Paper - fluid method optimisations - } - - public boolean isEmpty() { -@@ -54,11 +72,11 @@ public final class FluidState extends StateHolder { - } - - public float getOwnHeight() { -- return this.getType().getOwnHeight(this); -+ return this.ownHeight; // Paper - fluid method optimisations - } - - public int getAmount() { -- return this.getType().getAmount(this); -+ return this.amount; // Paper - fluid method optimisations - } - - public boolean shouldRenderBackwardUpFace(BlockGetter world, BlockPos pos) { -@@ -84,7 +102,7 @@ public final class FluidState extends StateHolder { - } - - public boolean isRandomlyTicking() { -- return this.getType().isRandomlyTicking(); -+ return this.isRandomlyTicking; // Paper - fluid method optimisations - } - - public void randomTick(ServerLevel world, BlockPos pos, RandomSource random) { -@@ -96,7 +114,12 @@ public final class FluidState extends StateHolder { - } - - public BlockState createLegacyBlock() { -- return this.getType().createLegacyBlock(this); -+ // Paper start - fluid method optimisations -+ if (this.legacyBlock != null) { -+ return this.legacyBlock; -+ } -+ return this.legacyBlock = this.getType().createLegacyBlock((FluidState)(Object)this); -+ // Paper end - fluid method optimisations - } - - @Nullable -diff --git a/src/main/java/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java -index 1d36f8dcffd22cf844448d3d8351fb8718cf5227..fbe0c4b0fdbb992b7002f6afe1e74d63cbb420f2 100644 ---- a/src/main/java/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java -+++ b/src/main/java/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java -@@ -57,7 +57,7 @@ public abstract class DiscreteVoxelShape implements ca.spottedleaf.moonrise.patc - } - } - -- final boolean hasSingleAABB = sizeX == 1 && sizeY == 1 && sizeZ == 1 && !isEmpty && discreteVoxelShape.isFull(0, 0, 0); -+ final boolean hasSingleAABB = sizeX == 1 && sizeY == 1 && sizeZ == 1 && !isEmpty && (voxelSet[0] & 1L) != 0L; - - final int minFullX = discreteVoxelShape.firstFull(Direction.Axis.X); - final int minFullY = discreteVoxelShape.firstFull(Direction.Axis.Y); -diff --git a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java -index 672a2038c6d8b31090403766460c6149a75adf8b..513bed7f11aee667c87046db4cf912b80e8f3638 100644 ---- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java -+++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java -@@ -180,13 +180,13 @@ public final class Shapes { - final VoxelShape first = tmp[i]; - final VoxelShape second = tmp[next]; - -- tmp[newSize++] = Shapes.or(first, second); -+ tmp[newSize++] = Shapes.joinUnoptimized(first, second, BooleanOp.OR); - } - } - size = newSize; - } - -- return tmp[0]; -+ return tmp[0].optimize(); - // Paper end - optimise collisions - } - -diff --git a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java -index d850a7de74150a04622da71d9614320f3d5d69e8..3f8e7e29c3e52211a29e6f0a32890f6b53bfd9a8 100644 ---- a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java -+++ b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java -@@ -162,13 +162,13 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll - - if (direction.getAxisDirection() == Direction.AxisDirection.POSITIVE) { - if (DoubleMath.fuzzyEquals(this.max(axis), 1.0, ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)) { -- ret = tryForceBlock(new SliceShape((VoxelShape)(Object)this, axis, this.shape.getSize(axis) - 1)); -+ ret = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.sliceShape((VoxelShape)(Object)this, axis, this.shape.getSize(axis) - 1); - } else { - ret = Shapes.empty(); - } - } else { - if (DoubleMath.fuzzyEquals(this.min(axis), 0.0, ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)) { -- ret = tryForceBlock(new SliceShape((VoxelShape)(Object)this, axis, 0)); -+ ret = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.sliceShape((VoxelShape)(Object)this, axis, 0); - } else { - ret = Shapes.empty(); - } -@@ -179,23 +179,6 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll - return ret; - } - -- private static VoxelShape tryForceBlock(final VoxelShape other) { -- if (other == Shapes.block()) { -- return other; -- } -- -- final AABB otherAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)other).moonrise$getSingleAABBRepresentation(); -- if (otherAABB == null) { -- return other; -- } -- -- if (((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)Shapes.block()).moonrise$getSingleAABBRepresentation().equals(otherAABB)) { -- return Shapes.block(); -- } -- -- return other; -- } -- - private boolean computeOccludesFullBlock() { - if (this.isEmpty) { - this.occludesFullBlock = Boolean.FALSE; -@@ -293,18 +276,21 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll - return result; - } - -- private static DoubleList offsetList(final DoubleList src, final double by) { -- if (src instanceof OffsetDoubleList offsetDoubleList) { -- return new OffsetDoubleList(offsetDoubleList.delegate, by + offsetDoubleList.offset); -+ private static DoubleList offsetList(final double[] src, final double by) { -+ final it.unimi.dsi.fastutil.doubles.DoubleArrayList wrap = it.unimi.dsi.fastutil.doubles.DoubleArrayList.wrap(src); -+ if (by == 0.0) { -+ return wrap; - } -- return new OffsetDoubleList(src, by); -+ return new OffsetDoubleList(wrap, by); - } - - private List toAabbsUncached() { -- final List ret = new java.util.ArrayList<>(); -+ final List ret; - if (this.singleAABBRepresentation != null) { -+ ret = new java.util.ArrayList<>(1); - ret.add(this.singleAABBRepresentation); - } else { -+ ret = new java.util.ArrayList<>(); - final double[] coordsX = this.rootCoordinatesX; - final double[] coordsY = this.rootCoordinatesY; - final double[] coordsZ = this.rootCoordinatesZ; -@@ -426,6 +412,26 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll - final double minDistance = minDistanceArr[0]; - return new BlockHitResult(from.add(minDistance * diffX, minDistance * diffY, minDistance * diffZ), direction, offset, false); - } -+ -+ private VoxelShape calculateFaceDirect(final Direction direction, final Direction.Axis axis, final double[] coords, final double offset) { -+ if (coords.length == 2 && -+ DoubleMath.fuzzyEquals(coords[0] + offset, 0.0, ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) && -+ DoubleMath.fuzzyEquals(coords[1] + offset, 1.0, ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)) { -+ return (VoxelShape)(Object)this; -+ } -+ -+ final boolean positiveDir = direction.getAxisDirection() == Direction.AxisDirection.POSITIVE; -+ -+ // see findIndex -+ final int index = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.findFloor( -+ coords, (positiveDir ? (1.0 - ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) : (0.0 + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)) - offset, -+ 0, coords.length - 1 -+ ); -+ -+ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.sliceShape( -+ (VoxelShape)(Object)this, axis, index -+ ); -+ } - // Paper end - optimise collisions - - protected VoxelShape(DiscreteVoxelShape voxels) { -@@ -517,20 +523,32 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll - } - - public VoxelShape singleEncompassing() { -- return this.isEmpty() -- ? Shapes.empty() -- : Shapes.box( -- this.min(Direction.Axis.X), -- this.min(Direction.Axis.Y), -- this.min(Direction.Axis.Z), -- this.max(Direction.Axis.X), -- this.max(Direction.Axis.Y), -- this.max(Direction.Axis.Z) -- ); -+ // Paper start - optimise collisions -+ if (this.isEmpty) { -+ return Shapes.empty(); -+ } -+ return Shapes.create(this.bounds()); -+ // Paper end - optimise collisions - } - - protected double get(Direction.Axis axis, int index) { -- return this.getCoords(axis).getDouble(index); -+ // Paper start - optimise collisions -+ final int idx = index; -+ switch (axis) { -+ case X: { -+ return this.rootCoordinatesX[idx] + this.offsetX; -+ } -+ case Y: { -+ return this.rootCoordinatesY[idx] + this.offsetY; -+ } -+ case Z: { -+ return this.rootCoordinatesZ[idx] + this.offsetZ; -+ } -+ default: { -+ throw new IllegalStateException("Unknown axis: " + axis); -+ } -+ } -+ // Paper end - optimise collisions - } - - public abstract DoubleList getCoords(Direction.Axis axis); -@@ -551,9 +569,9 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll - - final ArrayVoxelShape ret = new ArrayVoxelShape( - this.shape, -- offsetList(this.getCoords(Direction.Axis.X), x), -- offsetList(this.getCoords(Direction.Axis.Y), y), -- offsetList(this.getCoords(Direction.Axis.Z), z) -+ offsetList(this.rootCoordinatesX, this.offsetX + x), -+ offsetList(this.rootCoordinatesY, this.offsetY + y), -+ offsetList(this.rootCoordinatesZ, this.offsetZ + z) - ); - - final ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs cachedToAABBs = this.cachedToAABBs; -@@ -578,6 +596,11 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll - - final List aabbs = this.toAabbs(); - -+ if (aabbs.isEmpty()) { -+ // We are a SliceShape, which does not properly fill isEmpty for every case -+ return Shapes.empty(); -+ } -+ - if (aabbs.size() == 1) { - final AABB singleAABB = aabbs.get(0); - final VoxelShape ret = Shapes.create(singleAABB); -@@ -704,7 +727,32 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll - } - - protected int findIndex(Direction.Axis axis, double coord) { -- return Mth.binarySearch(0, this.shape.getSize(axis) + 1, i -> coord < this.get(axis, i)) - 1; -+ // Paper start - optimise collisions -+ final double value = coord; -+ switch (axis) { -+ case X: { -+ final double[] values = this.rootCoordinatesX; -+ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.findFloor( -+ values, value - this.offsetX, 0, values.length - 1 -+ ); -+ } -+ case Y: { -+ final double[] values = this.rootCoordinatesY; -+ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.findFloor( -+ values, value - this.offsetY, 0, values.length - 1 -+ ); -+ } -+ case Z: { -+ final double[] values = this.rootCoordinatesZ; -+ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.findFloor( -+ values, value - this.offsetZ, 0, values.length - 1 -+ ); -+ } -+ default: { -+ throw new IllegalStateException("Unknown axis: " + axis); -+ } -+ } -+ // Paper end - optimise collisions - } - - @Nullable -@@ -727,13 +775,13 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll - final AABB singleAABB = this.singleAABBRepresentation; - if (singleAABB != null) { - if (singleAABB.contains(fromBehindOffsetX, fromBehindOffsetY, fromBehindOffsetZ)) { -- return new BlockHitResult(fromBehind, Direction.getNearest(directionOpposite.x, directionOpposite.y, directionOpposite.z).getOpposite(), offset, true); -+ return new BlockHitResult(fromBehind, Direction.getApproximateNearest(directionOpposite.x, directionOpposite.y, directionOpposite.z).getOpposite(), offset, true); - } - return clip(singleAABB, from, to, offset); - } - - if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.strictlyContains((VoxelShape)(Object)this, fromBehindOffsetX, fromBehindOffsetY, fromBehindOffsetZ)) { -- return new BlockHitResult(fromBehind, Direction.getNearest(directionOpposite.x, directionOpposite.y, directionOpposite.z).getOpposite(), offset, true); -+ return new BlockHitResult(fromBehind, Direction.getApproximateNearest(directionOpposite.x, directionOpposite.y, directionOpposite.z).getOpposite(), offset, true); - } - - return AABB.clip(((VoxelShape)(Object)this).toAabbs(), from, to, offset); -@@ -786,20 +834,24 @@ public abstract class VoxelShape implements ca.spottedleaf.moonrise.patches.coll - } - } - -- private VoxelShape calculateFace(Direction facing) { -- Direction.Axis axis = facing.getAxis(); -- if (this.isCubeLikeAlong(axis)) { -- return this; -- } else { -- Direction.AxisDirection axisDirection = facing.getAxisDirection(); -- int i = this.findIndex(axis, axisDirection == Direction.AxisDirection.POSITIVE ? 0.9999999 : 1.0E-7); -- SliceShape sliceShape = new SliceShape(this, axis, i); -- if (sliceShape.isEmpty()) { -- return Shapes.empty(); -- } else { -- return (VoxelShape)(sliceShape.isCubeLike() ? Shapes.block() : sliceShape); -+ private VoxelShape calculateFace(Direction direction) { -+ // Paper start - optimise collisions -+ final Direction.Axis axis = direction.getAxis(); -+ switch (axis) { -+ case X: { -+ return this.calculateFaceDirect(direction, axis, this.rootCoordinatesX, this.offsetX); -+ } -+ case Y: { -+ return this.calculateFaceDirect(direction, axis, this.rootCoordinatesY, this.offsetY); -+ } -+ case Z: { -+ return this.calculateFaceDirect(direction, axis, this.rootCoordinatesZ, this.offsetZ); -+ } -+ default: { -+ throw new IllegalStateException("Unknown axis: " + axis); - } - } -+ // Paper end - optimise collisions - } - - protected boolean isCubeLike() { From 3b316215d7d8940b81ddf6e5fde8c24fbd387f39 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 24 Oct 2024 08:36:07 -0700 Subject: [PATCH 063/119] Implement config hooks in PaperHooks --- moonrise_update_1_21_2.txt | 9 ------ patches/server/0823-fixup-MC-Utils.patch | 28 +++++++++---------- .../0824-Rewrite-dataconverter-system.patch | 2 +- .../0826-Moonrise-optimisation-patches.patch | 8 +++--- 4 files changed, 19 insertions(+), 28 deletions(-) diff --git a/moonrise_update_1_21_2.txt b/moonrise_update_1_21_2.txt index d6a3d5df42e0..c7942be4eba1 100644 --- a/moonrise_update_1_21_2.txt +++ b/moonrise_update_1_21_2.txt @@ -3,16 +3,8 @@ https://github.com/Tuinity/Moonrise/compare/6a2c6d27df11d417c1fefa749109d8e87599 need to compare the diffs -add notes to moonrise patch: - - implemented fast palette patch - - implemented better bitstorage magic patch - - implemented blockstate property patch (replaced old paper one) - - implemented fluid patch - - todo: - double check that the misc changes commit on dev/1.21.2 moonrise is applied -- implement platformhooks - in ChunkEntitySlices, implement modifySavedEntities() by copying from old - implement PlayerChunkUnloadEvent in PlatformHooks#onChunkUnWatch - make sure chunk pos is passed in PlatformHooks#postLoadProtoChunk @@ -32,5 +24,4 @@ todo: - implement starlight.ChunkSerializerMixin diff from reference - implement starlight.SerializableChunkData$SectionData diff from reference - implement starlight.SerializableChunkDataMixin diff from reference -- unfuck the chtunk system config diff - chunk system: move get entity lookup reroute into the folia scheduler api patch diff --git a/patches/server/0823-fixup-MC-Utils.patch b/patches/server/0823-fixup-MC-Utils.patch index 54f6874194e2..60653c117b07 100644 --- a/patches/server/0823-fixup-MC-Utils.patch +++ b/patches/server/0823-fixup-MC-Utils.patch @@ -6,7 +6,7 @@ Subject: [PATCH] fixup! MC Utils diff --git a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java new file mode 100644 -index 0000000000000000000000000000000000000000..deb64f7ebebcf6de91ffe0542d6b449a4db64da0 +index 0000000000000000000000000000000000000000..6c98d420ea84c10ef4f15d4deb3f04e610ed8548 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java @@ -0,0 +1,117 @@ @@ -91,9 +91,9 @@ index 0000000000000000000000000000000000000000..deb64f7ebebcf6de91ffe0542d6b449a + + public int configPlayerMaxConcurrentGens(); + -+ public long configAutoSaveInterval(); ++ public long configAutoSaveInterval(final ServerLevel world); + -+ public int configMaxAutoSavePerTick(); ++ public int configMaxAutoSavePerTick(final ServerLevel world); + + public boolean configFixMC159283(); + @@ -1026,7 +1026,7 @@ index af9623240ff2d389aa7090623f507720e7dbab7d..efda2688ae1254a82ba7f6bf8bf597ef public static int getMaxLightSection(final LevelHeightAccessor world) { diff --git a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java new file mode 100644 -index 0000000000000000000000000000000000000000..ee514a767f69de69d86e1e88d70fe37c4ab84277 +index 0000000000000000000000000000000000000000..1aa6be257ce594d7a69fdff008cd29014a04fd75 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java @@ -0,0 +1,209 @@ @@ -1153,42 +1153,42 @@ index 0000000000000000000000000000000000000000..ee514a767f69de69d86e1e88d70fe37c + + @Override + public boolean configAutoConfigSendDistance() { -+ ++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.autoConfigSendDistance; + } + + @Override + public double configPlayerMaxLoadRate() { -+ ++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkLoadRate; + } + + @Override + public double configPlayerMaxGenRate() { -+ ++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkGenerateRate; + } + + @Override + public double configPlayerMaxSendRate() { -+ ++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkSendRate; + } + + @Override + public int configPlayerMaxConcurrentLoads() { -+ ++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkLoads; + } + + @Override + public int configPlayerMaxConcurrentGens() { -+ ++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkGenerates; + } + + @Override -+ public long configAutoSaveInterval() { -+ ++ public long configAutoSaveInterval(final ServerLevel world) { ++ return world.paperConfig().chunks.autoSaveInterval.value(); + } + + @Override -+ public int configMaxAutoSavePerTick() { -+ ++ public int configMaxAutoSavePerTick(final ServerLevel world) { ++ return world.paperConfig().chunks.maxAutoSaveChunksPerTick; + } + + @Override diff --git a/patches/server/0824-Rewrite-dataconverter-system.patch b/patches/server/0824-Rewrite-dataconverter-system.patch index 173d97a5b2cd..21a091394df8 100644 --- a/patches/server/0824-Rewrite-dataconverter-system.patch +++ b/patches/server/0824-Rewrite-dataconverter-system.patch @@ -30187,7 +30187,7 @@ index 0000000000000000000000000000000000000000..5a6536377c9c1e1753e930ff2a6bb98e + } +} diff --git a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java -index ee514a767f69de69d86e1e88d70fe37c4ab84277..be60439c43b887f0143e7713689fd2773066ba73 100644 +index 1aa6be257ce594d7a69fdff008cd29014a04fd75..c8f2457ab3b28f2c3a6b500bcea40261669c24a4 100644 --- a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java +++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java @@ -172,6 +172,43 @@ public final class PaperHooks implements PlatformHooks { diff --git a/patches/server/0826-Moonrise-optimisation-patches.patch b/patches/server/0826-Moonrise-optimisation-patches.patch index 59a89d72686d..c6845bb1a837 100644 --- a/patches/server/0826-Moonrise-optimisation-patches.patch +++ b/patches/server/0826-Moonrise-optimisation-patches.patch @@ -365,7 +365,7 @@ index 94bba2b71918d79f54b3e28c35e76098ba0afd8c..fc029c8fb22a7c8eeb23bfc171812f6d private ChunkSystem() {} diff --git a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java -index be60439c43b887f0143e7713689fd2773066ba73..dc17aa5a0937c13d431e41779f241f2e81b11656 100644 +index c8f2457ab3b28f2c3a6b500bcea40261669c24a4..ca8b6a926dfff3fdd6b04228809a4480366120b2 100644 --- a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java +++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java @@ -236,7 +236,7 @@ public final class PaperHooks implements PlatformHooks { @@ -6782,7 +6782,7 @@ index 0000000000000000000000000000000000000000..7eafc5b7cba23d8dec92ecc1050afe3f \ No newline at end of file diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..f98df65eaed2abedc66f3a49790e0cfb65354ed9 +index 0000000000000000000000000000000000000000..a0e5fc2eff605e17704f0726d20e79cbb3d88d6d --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java @@ -0,0 +1,1455 @@ @@ -7019,8 +7019,8 @@ index 0000000000000000000000000000000000000000..f98df65eaed2abedc66f3a49790e0cfb + public void autoSave() { + final List reschedule = new ArrayList<>(); + final long currentTick = this.currentTick; -+ final long maxSaveTime = currentTick - Math.max(1L, PlatformHooks.get().configAutoSaveInterval()); -+ final int maxToSave = PlatformHooks.get().configMaxAutoSavePerTick(); ++ final long maxSaveTime = currentTick - Math.max(1L, PlatformHooks.get().configAutoSaveInterval(this.world)); ++ final int maxToSave = PlatformHooks.get().configMaxAutoSavePerTick(this.world); + for (int autoSaved = 0; autoSaved < maxToSave && !this.autoSaveQueue.isEmpty();) { + final NewChunkHolder holder = this.autoSaveQueue.first(); + From e9c58f5451829038f2e5f89055c95fdfb748715d Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 24 Oct 2024 10:06:01 -0700 Subject: [PATCH 064/119] Implement chunk tick iteration optimisations --- moonrise_update_1_21_2.txt | 1 - patches/server/0823-fixup-MC-Utils.patch | 23 + .../0826-Moonrise-optimisation-patches.patch | 433 +++++++++++++++--- 3 files changed, 383 insertions(+), 74 deletions(-) diff --git a/moonrise_update_1_21_2.txt b/moonrise_update_1_21_2.txt index c7942be4eba1..2ff8731cdf03 100644 --- a/moonrise_update_1_21_2.txt +++ b/moonrise_update_1_21_2.txt @@ -17,7 +17,6 @@ todo: - implement chunk_system.SectionStorageMixin diff from reference - implement chunk_system.SerializableChunkDataMixin diff from reference - implement chunk_system.ServerLevelMixin diff from reference -- implement chunk_tick_iteration - implement collisions.ServerExplosionMixin diff from reference - implement starlight.LevelLightEngineMixin diff from reference - implement starlight.ThreadedLevelLightEngineMixin diff from reference diff --git a/patches/server/0823-fixup-MC-Utils.patch b/patches/server/0823-fixup-MC-Utils.patch index 60653c117b07..32b0c1c0ce26 100644 --- a/patches/server/0823-fixup-MC-Utils.patch +++ b/patches/server/0823-fixup-MC-Utils.patch @@ -686,6 +686,29 @@ index ab093b0e8ac6f762921eb1d15f5217345c4eba05..bb44de17a37082e57f2292a4f470740b } } } +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java +index efefd94b652228d877db5dbca8b28354ad42529f..90560769d09538f7a740753a41a3b8e017b0b92a 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java +@@ -2,6 +2,7 @@ package ca.spottedleaf.moonrise.common.misc; + + import ca.spottedleaf.concurrentutil.util.IntPairUtil; + import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; ++import it.unimi.dsi.fastutil.longs.LongSet; + import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; + import it.unimi.dsi.fastutil.objects.ReferenceSet; + +@@ -14,6 +15,10 @@ public final class PositionCountingAreaMap { + return this.counters.keySet(); + } + ++ public LongSet getPositions() { ++ return this.positions.keySet(); ++ } ++ + public int getTotalPositions() { + return this.positions.size(); + } diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java index da323a1105347d5cf4b946df10ded78a953236f2..94bba2b71918d79f54b3e28c35e76098ba0afd8c 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java diff --git a/patches/server/0826-Moonrise-optimisation-patches.patch b/patches/server/0826-Moonrise-optimisation-patches.patch index c6845bb1a837..536918d0f396 100644 --- a/patches/server/0826-Moonrise-optimisation-patches.patch +++ b/patches/server/0826-Moonrise-optimisation-patches.patch @@ -16135,6 +16135,31 @@ index 0000000000000000000000000000000000000000..f28fd0e01e2bdda0daf9d775e514a725 + final boolean oldIgnore, final boolean newIgnore); + +} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickServerLevel.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickServerLevel.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6af03fd7807d4c71dbf85028d18dc850978ef429 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickServerLevel.java +@@ -0,0 +1,19 @@ ++package ca.spottedleaf.moonrise.patches.chunk_tick_iteration; ++ ++import ca.spottedleaf.moonrise.common.list.ReferenceList; ++import net.minecraft.server.level.ServerChunkCache; ++import net.minecraft.world.level.chunk.LevelChunk; ++ ++public interface ChunkTickServerLevel { ++ ++ public ReferenceList moonrise$getPlayerTickingChunks(); ++ ++ public void moonrise$markChunkForPlayerTicking(final LevelChunk chunk); ++ ++ public void moonrise$removeChunkForPlayerTicking(final LevelChunk chunk); ++ ++ public void moonrise$addPlayerTickingRequest(final int chunkX, final int chunkZ); ++ ++ public void moonrise$removePlayerTickingRequest(final int chunkX, final int chunkZ); ++ ++} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..3abd4ad6379c383c3a31931255292b42d9435694 @@ -24108,7 +24133,7 @@ index d9ad32acdf46a43a649334a3b736aeb7b3af21d1..fae17a075d7efaf24d916877dd5968eb public static final int RADIUS_AROUND_FULL_CHUNK = FULL_CHUNK_STEP.accumulatedDependencies().getRadius(); public static final int MAX_LEVEL = 33 + RADIUS_AROUND_FULL_CHUNK; diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index ec19eb88705a07db45f1a3541571fb7f43efb5a9..64b9738584fe2efd1ce4a3d7e2c75e091adc2504 100644 +index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d550097ec 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -125,10 +125,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -24926,7 +24951,117 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..64b9738584fe2efd1ce4a3d7e2c75e09 return this.upgradeChunkTag(this.level.getTypeKey(), this.overworldDataStorage, nbttagcompound, this.generator().getTypeNameForDataFixer(), chunkcoordintpair, this.level); // CraftBukkit end } -@@ -1172,19 +756,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1071,7 +655,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + + while (longiterator.hasNext()) { + long i = longiterator.nextLong(); +- ChunkHolder playerchunk = (ChunkHolder) this.visibleChunkMap.get(i); ++ ChunkHolder playerchunk = (ChunkHolder) this.getVisibleChunkIfPresent(i); // Paper - rewrite chunk system + + if (playerchunk != null && this.anyPlayerCloseEnoughForSpawningInternal(playerchunk.getPos())) { + callback.accept(playerchunk); +@@ -1086,7 +670,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + } + + boolean anyPlayerCloseEnoughForSpawning(ChunkPos chunkcoordintpair, boolean reducedRange) { +- return !this.distanceManager.hasPlayersNearby(chunkcoordintpair.toLong()) ? false : this.anyPlayerCloseEnoughForSpawningInternal(chunkcoordintpair, reducedRange); ++ return this.anyPlayerCloseEnoughForSpawningInternal(chunkcoordintpair, reducedRange); // Paper - chunk tick iteration optimisation + // Spigot end + } + +@@ -1104,16 +688,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + //double blockRange = (reducedRange) ? Math.pow(chunkRange << 4, 2) : 16384.0D; // Paper - use from event + double blockRange = 16384.0D; // Paper + // Spigot end +- Iterator iterator = this.playerMap.getAllPlayers().iterator(); +- +- ServerPlayer entityplayer; ++ // Paper start - chunk tick iteration optimisation ++ final ca.spottedleaf.moonrise.common.list.ReferenceList players = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getNearbyPlayers().getPlayers( ++ chunkcoordintpair, ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.SPAWN_RANGE ++ ); ++ if (players == null) { ++ return false; ++ } + +- do { +- if (!iterator.hasNext()) { +- return false; +- } ++ final ServerPlayer[] raw = players.getRawDataUnchecked(); ++ final int len = players.size(); + +- entityplayer = (ServerPlayer) iterator.next(); ++ Objects.checkFromIndexSize(0, len, raw.length); ++ for (int i = 0; i < len; ++i) { ++ final ServerPlayer entityplayer = raw[i]; + // Paper start - PlayerNaturallySpawnCreaturesEvent + com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event; + blockRange = 16384.0D; +@@ -1123,33 +711,47 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + blockRange = (double) ((event.getSpawnRadius() << 4) * (event.getSpawnRadius() << 4)); + } + // Paper end - PlayerNaturallySpawnCreaturesEvent +- } while (!this.playerIsCloseEnoughForSpawning(entityplayer, chunkcoordintpair, blockRange)); // Spigot ++ if (this.playerIsCloseEnoughForSpawning(entityplayer, chunkcoordintpair, blockRange)) { ++ return true; ++ } ++ } + +- return true; ++ return false; ++ // Paper end - chunk tick iteration optimisation + } + + public List getPlayersCloseForSpawning(ChunkPos pos) { +- long i = pos.toLong(); ++ // Paper start - chunk tick iteration optimisation ++ final ca.spottedleaf.moonrise.common.list.ReferenceList players = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getNearbyPlayers().getPlayers( ++ pos, ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.SPAWN_RANGE ++ ); ++ if (players == null) { ++ return new ArrayList<>(); ++ } + +- if (!this.distanceManager.hasPlayersNearby(i)) { +- return List.of(); +- } else { +- Builder builder = ImmutableList.builder(); +- Iterator iterator = this.playerMap.getAllPlayers().iterator(); ++ List ret = null; + +- while (iterator.hasNext()) { +- ServerPlayer entityplayer = (ServerPlayer) iterator.next(); ++ final ServerPlayer[] raw = players.getRawDataUnchecked(); ++ final int len = players.size(); + +- if (this.playerIsCloseEnoughForSpawning(entityplayer, pos, 16384.0D)) { // Spigot +- builder.add(entityplayer); ++ Objects.checkFromIndexSize(0, len, raw.length); ++ for (int i = 0; i < len; ++i) { ++ final ServerPlayer player = raw[i]; ++ if (this.playerIsCloseEnoughForSpawning(player, pos, 16384.0D)) { // Spigot ++ if (ret == null) { ++ ret = new ArrayList<>(len - i); ++ ret.add(player); ++ } else { ++ ret.add(player); + } + } +- +- return builder.build(); + } ++ ++ return ret == null ? new ArrayList<>() : ret; ++ // Paper end - chunk tick iteration optimisation + } + +- private boolean playerIsCloseEnoughForSpawning(ServerPlayer entityplayer, ChunkPos chunkcoordintpair, double range) { // Spigot ++ public boolean playerIsCloseEnoughForSpawning(ServerPlayer entityplayer, ChunkPos chunkcoordintpair, double range) { // Spigot // Paper - chunk tick iteration optimisation - public + if (entityplayer.isSpectator()) { + return false; + } else { +@@ -1172,19 +774,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.updatePlayerPos(player); if (!flag1) { this.distanceManager.addPlayer(SectionPos.of((EntityAccess) player), player); @@ -24950,7 +25085,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..64b9738584fe2efd1ce4a3d7e2c75e09 } } -@@ -1196,17 +782,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1196,17 +800,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void move(ServerPlayer player) { @@ -24969,7 +25104,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..64b9738584fe2efd1ce4a3d7e2c75e09 SectionPos sectionposition = player.getLastSectionPos(); SectionPos sectionposition1 = SectionPos.of((EntityAccess) player); -@@ -1216,6 +792,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1216,6 +810,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider if (flag2 || flag != flag1) { this.updatePlayerPos(player); @@ -24977,7 +25112,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..64b9738584fe2efd1ce4a3d7e2c75e09 if (!flag) { this.distanceManager.removePlayer(sectionposition, player); } -@@ -1232,70 +809,30 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1232,70 +827,30 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.playerMap.unIgnorePlayer(player); } @@ -25059,7 +25194,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..64b9738584fe2efd1ce4a3d7e2c75e09 } public void addEntity(Entity entity) { -@@ -1322,6 +859,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1322,6 +877,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider ChunkMap.TrackedEntity playerchunkmap_entitytracker = new ChunkMap.TrackedEntity(entity, i, j, entitytypes.trackDeltas()); this.entityMap.put(entity.getId(), playerchunkmap_entitytracker); @@ -25072,7 +25207,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..64b9738584fe2efd1ce4a3d7e2c75e09 playerchunkmap_entitytracker.updatePlayers(this.level.players()); if (entity instanceof ServerPlayer) { ServerPlayer entityplayer = (ServerPlayer) entity; -@@ -1362,16 +905,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1362,16 +923,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider playerchunkmap_entitytracker1.broadcastRemoved(); } @@ -25116,7 +25251,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..64b9738584fe2efd1ce4a3d7e2c75e09 List list = Lists.newArrayList(); List list1 = this.level.players(); -@@ -1478,27 +1043,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1478,27 +1061,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void waitForLightBeforeSending(ChunkPos centerPos, int radius) { @@ -25154,7 +25289,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..64b9738584fe2efd1ce4a3d7e2c75e09 } @Nullable -@@ -1514,7 +1077,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1514,7 +1095,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } } @@ -25163,7 +25298,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..64b9738584fe2efd1ce4a3d7e2c75e09 public final ServerEntity serverEntity; final Entity entity; -@@ -1522,6 +1085,89 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1522,6 +1103,89 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider SectionPos lastSectionPos; public final Set seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl @@ -25253,7 +25388,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..64b9738584fe2efd1ce4a3d7e2c75e09 public TrackedEntity(final Entity entity, final int i, final int j, final boolean flag) { this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit this.entity = entity; -@@ -1610,20 +1256,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1610,20 +1274,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } private int getEffectiveRange() { @@ -25289,7 +25424,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..64b9738584fe2efd1ce4a3d7e2c75e09 public void updatePlayers(List players) { diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java -index f7c2c03749d6be25bf33afd61e1da120770b3432..64da6726634fc223c0e6dcab4d83a6c8997ff196 100644 +index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973bc1b35904 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java @@ -34,58 +34,56 @@ import net.minecraft.world.level.ChunkPos; @@ -25560,7 +25695,7 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..64da6726634fc223c0e6dcab4d83a6c8 } public void removePlayer(SectionPos pos, ServerPlayer player) { -@@ -284,51 +174,49 @@ public abstract class DistanceManager { +@@ -284,160 +174,89 @@ 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); @@ -25628,7 +25763,9 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..64da6726634fc223c0e6dcab4d83a6c8 } public LongIterator getSpawnCandidateChunks() { -@@ -337,47 +225,17 @@ public abstract class DistanceManager { +- this.naturalSpawnChunkCounter.runAllUpdates(); +- return this.naturalSpawnChunkCounter.chunks.keySet().iterator(); ++ return this.spawnChunkTracker.getPositions().iterator(); // Paper - chunk tick iteration optimisation } public String getDebugStatus() { @@ -25668,18 +25805,19 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..64da6726634fc223c0e6dcab4d83a6c8 - } catch (IOException ioexception) { - DistanceManager.LOGGER.error("Failed to dump tickets to {}", path, ioexception); - } -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system ++ throw new UnsupportedOperationException(); // Paper - rewrite chunk system } @VisibleForTesting TickingTracker tickingTracker() { - return this.tickingTicketsTracker; -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system ++ throw new UnsupportedOperationException(); // Paper - rewrite chunk system } public LongSet getTickingChunks() { -@@ -385,59 +243,21 @@ public abstract class DistanceManager { +- return this.tickingTicketsTracker.getTickingChunks(); ++ throw new UnsupportedOperationException(); // Paper - rewrite chunk system } public void removeTicketsOnClosing() { @@ -25743,7 +25881,7 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..64da6726634fc223c0e6dcab4d83a6c8 private class ChunkTicketTracker extends ChunkTracker { private static final int MAX_LEVEL = ChunkLevel.MAX_LEVEL + 1; -@@ -483,7 +303,7 @@ public abstract class DistanceManager { +@@ -483,7 +302,7 @@ public abstract class DistanceManager { public int runDistanceUpdates(int distance) { return this.runUpdates(distance); } @@ -25752,7 +25890,7 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..64da6726634fc223c0e6dcab4d83a6c8 private class FixedPlayerDistanceChunkTracker extends ChunkTracker { -@@ -563,6 +383,7 @@ public abstract class DistanceManager { +@@ -563,6 +382,7 @@ public abstract class DistanceManager { } } @@ -25760,7 +25898,7 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..64da6726634fc223c0e6dcab4d83a6c8 private class PlayerTicketTracker extends DistanceManager.FixedPlayerDistanceChunkTracker { private int viewDistance = 0; -@@ -657,5 +478,5 @@ public abstract class DistanceManager { +@@ -657,5 +477,5 @@ public abstract class DistanceManager { private boolean haveTicketFor(int distance) { return distance <= this.viewDistance; } @@ -26101,7 +26239,7 @@ index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a } } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..23a13bfd23514cde6dcf8d59ba3b43d84f266aad 100644 +index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..06d0e164363ac8641fad177e0a490bd033be6594 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -52,7 +52,7 @@ import net.minecraft.world.level.storage.DimensionDataStorage; @@ -26113,7 +26251,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..23a13bfd23514cde6dcf8d59ba3b43d8 private static final Logger LOGGER = LogUtils.getLogger(); private final DistanceManager distanceManager; -@@ -78,6 +78,71 @@ public class ServerChunkCache extends ChunkSource { +@@ -78,6 +78,100 @@ public class ServerChunkCache extends ChunkSource { private final ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable fullChunks = new ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<>(); long chunkFutureAwaitCounter; // Paper end @@ -26181,11 +26319,40 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..23a13bfd23514cde6dcf8d59ba3b43d8 + return load ? this.syncLoad(chunkX, chunkZ, toStatus) : null; + } + // Paper end - rewrite chunk system -+ private ServerChunkCache.ChunkAndHolder[] iterationCopy; // Paper - chunk tick iteration optimisations ++ // Paper start - chunk tick iteration optimisations ++ private final ca.spottedleaf.moonrise.common.util.SimpleRandom shuffleRandom = new ca.spottedleaf.moonrise.common.util.SimpleRandom(0L); ++ private boolean isChunkNearPlayer(final ChunkMap chunkMap, final ChunkPos chunkPos, final LevelChunk levelChunk) { ++ final ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData chunkData = ((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkHolder)((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk)levelChunk).moonrise$getChunkAndHolder().holder()) ++ .moonrise$getRealChunkHolder().holderData; ++ final ca.spottedleaf.moonrise.common.misc.NearbyPlayers.TrackedChunk nearbyPlayers = chunkData.nearbyPlayers; ++ if (nearbyPlayers == null) { ++ return false; ++ } ++ ++ final ca.spottedleaf.moonrise.common.list.ReferenceList players = nearbyPlayers.getPlayers(ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.SPAWN_RANGE); ++ ++ if (players == null) { ++ return false; ++ } ++ ++ final ServerPlayer[] raw = players.getRawDataUnchecked(); ++ final int len = players.size(); ++ ++ Objects.checkFromIndexSize(0, len, raw.length); ++ for (int i = 0; i < len; ++i) { ++ if (chunkMap.playerIsCloseEnoughForSpawning(raw[i], chunkPos, 16384.0D)) { // Spigot (reducedRange = false) ++ return true; ++ } ++ } ++ ++ return false; ++ } ++ // Paper end - chunk tick iteration optimisations ++ 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 persistentStateManagerFactory) { this.level = world; -@@ -109,13 +174,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -109,13 +203,7 @@ public class ServerChunkCache extends ChunkSource { } // CraftBukkit end // Paper start @@ -26200,7 +26367,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..23a13bfd23514cde6dcf8d59ba3b43d8 @Nullable public ChunkAccess getChunkAtImmediately(int x, int z) { -@@ -186,63 +245,42 @@ public class ServerChunkCache extends ChunkSource { +@@ -186,63 +274,42 @@ public class ServerChunkCache extends ChunkSource { @Nullable @Override public ChunkAccess getChunk(int x, int z, ChunkStatus leastStatus, boolean create) { @@ -26273,7 +26440,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..23a13bfd23514cde6dcf8d59ba3b43d8 + final LevelChunk ret = this.fullChunks.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); + if (!ca.spottedleaf.moonrise.common.PlatformHooks.get().hasCurrentlyLoadingChunk()) { + return ret; - } ++ } + + if (ret != null || !ca.spottedleaf.moonrise.common.util.TickThread.isTickThread()) { + return ret; @@ -26283,14 +26450,14 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..23a13bfd23514cde6dcf8d59ba3b43d8 + .chunkHolderManager.getChunkHolder(chunkX, chunkZ); + if (holder == null) { + return ret; -+ } + } + + return ca.spottedleaf.moonrise.common.PlatformHooks.get().getCurrentlyLoadingChunk(holder.vanillaChunkHolder); + // Paper end - rewrite chunk system } private void clearCache() { -@@ -273,56 +311,59 @@ public class ServerChunkCache extends ChunkSource { +@@ -273,56 +340,59 @@ public class ServerChunkCache extends ChunkSource { } private CompletableFuture> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { @@ -26388,7 +26555,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..23a13bfd23514cde6dcf8d59ba3b43d8 } @Override -@@ -335,16 +376,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -335,16 +405,7 @@ public class ServerChunkCache extends ChunkSource { } public boolean runDistanceManagerUpdates() { // Paper - public @@ -26406,7 +26573,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..23a13bfd23514cde6dcf8d59ba3b43d8 } // Paper start -@@ -354,17 +386,14 @@ public class ServerChunkCache extends ChunkSource { +@@ -354,17 +415,14 @@ public class ServerChunkCache extends ChunkSource { // Paper end public boolean isPositionTicking(long pos) { @@ -26429,7 +26596,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..23a13bfd23514cde6dcf8d59ba3b43d8 try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings this.chunkMap.saveAllChunks(flush); } // Paper - Timings -@@ -377,17 +406,15 @@ public class ServerChunkCache extends ChunkSource { +@@ -377,17 +435,15 @@ public class ServerChunkCache extends ChunkSource { } public void close(boolean save) throws IOException { @@ -26450,7 +26617,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..23a13bfd23514cde6dcf8d59ba3b43d8 ProfilerFiller gameprofilerfiller = Profiler.get(); gameprofilerfiller.push("purge"); -@@ -415,6 +442,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -415,6 +471,7 @@ public class ServerChunkCache extends ChunkSource { gameprofilerfiller.popPush("chunks"); if (tickChunks) { this.level.timings.chunks.startTiming(); // Paper - timings @@ -26458,7 +26625,51 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..23a13bfd23514cde6dcf8d59ba3b43d8 this.tickChunks(); this.level.timings.chunks.stopTiming(); // Paper - timings this.chunkMap.tick(); -@@ -546,11 +574,13 @@ public class ServerChunkCache extends ChunkSource { +@@ -445,7 +502,10 @@ public class ServerChunkCache extends ChunkSource { + gameprofilerfiller.push("filteringTickingChunks"); + this.collectTickingChunks(list); + gameprofilerfiller.popPush("shuffleChunks"); +- Util.shuffle(list, this.level.random); ++ // Paper start - chunk tick iteration optimisation ++ this.shuffleRandom.setSeed(this.level.random.nextLong()); ++ Util.shuffle(list, this.shuffleRandom); ++ // Paper end - chunk tick iteration optimisation + this.tickChunks(gameprofilerfiller, j, list); + gameprofilerfiller.pop(); + } finally { +@@ -478,14 +538,26 @@ public class ServerChunkCache extends ChunkSource { + } + + private void collectTickingChunks(List chunks) { +- this.chunkMap.forEachSpawnCandidateChunk((playerchunk) -> { +- LevelChunk chunk = playerchunk.getTickingChunk(); ++ // Paper start - chunk tick iteration optimisation ++ final ca.spottedleaf.moonrise.common.list.ReferenceList tickingChunks = ++ ((ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel)this.level).moonrise$getPlayerTickingChunks(); ++ ++ final ServerChunkCache.ChunkAndHolder[] raw = tickingChunks.getRawDataUnchecked(); ++ final int size = tickingChunks.size(); + +- if (chunk != null && this.level.isNaturalSpawningAllowed(playerchunk.getPos())) { +- chunks.add(chunk); ++ final ChunkMap chunkMap = this.chunkMap; ++ ++ for (int i = 0; i < size; ++i) { ++ final ServerChunkCache.ChunkAndHolder chunkAndHolder = raw[i]; ++ final LevelChunk levelChunk = chunkAndHolder.chunk(); ++ ++ if (!this.isChunkNearPlayer(chunkMap, levelChunk.getPos(), levelChunk)) { ++ continue; + } + +- }); ++ chunks.add(levelChunk); ++ } ++ // Paper end - chunk tick iteration optimisation + } + + private void tickChunks(ProfilerFiller profiler, long timeDelta, List chunks) { +@@ -546,11 +618,13 @@ public class ServerChunkCache extends ChunkSource { } private void getFullChunk(long pos, Consumer chunkConsumer) { @@ -26476,7 +26687,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..23a13bfd23514cde6dcf8d59ba3b43d8 } -@@ -644,6 +674,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -644,6 +718,12 @@ public class ServerChunkCache extends ChunkSource { this.chunkMap.setServerViewDistance(watchDistance); } @@ -26489,7 +26700,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..23a13bfd23514cde6dcf8d59ba3b43d8 public void setSimulationDistance(int simulationDistance) { this.distanceManager.updateSimulationDistance(simulationDistance); } -@@ -735,21 +771,19 @@ public class ServerChunkCache extends ChunkSource { +@@ -735,21 +815,19 @@ public class ServerChunkCache extends ChunkSource { @Override // CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task public boolean pollTask() { @@ -26534,7 +26745,7 @@ index bc0f1aa61e68d2a8638d89c10bc5c71922d057f9..79c88b315481fe70f037bae834f2b072 if (!list.equals(this.lastPassengers)) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c8319f10200 100644 +index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21276a41c9 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -187,7 +187,7 @@ import org.bukkit.event.weather.LightningStrikeEvent; @@ -26542,7 +26753,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 // CraftBukkit end -public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLevel { -+public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLevel, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevelReader { // Paper - rewrite chunk system ++public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLevel, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevelReader, ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel { // Paper - rewrite chunk system // Paper - chunk tick iteration public static final BlockPos END_SPAWN_POINT = new BlockPos(100, 50, 0); public static final IntProvider RAIN_DELAY = UniformInt.of(12000, 180000); @@ -26609,9 +26820,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 + public final LevelChunk moonrise$getFullChunkIfLoaded(final int chunkX, final int chunkZ) { + return this.chunkSource.getChunkNow(chunkX, chunkZ); + } - -- int requiredChunks = (maxChunkX - minChunkX + 1) * (maxChunkZ - minChunkZ + 1); -- int[] loadedChunks = new int[1]; ++ + @Override + public final ChunkAccess moonrise$getAnyChunkIfLoaded(final int chunkX, final int chunkZ) { + final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder newChunkHolder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); @@ -26621,8 +26830,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 + final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder.ChunkCompletion lastCompletion = newChunkHolder.getLastChunkCompletion(); + return lastCompletion == null ? null : lastCompletion.chunk(); + } - -- Long holderIdentifier = Long.valueOf(chunkProvider.chunkFutureAwaitCounter++); ++ + @Override + public final ChunkAccess moonrise$getSpecificChunkIfLoaded(final int chunkX, final int chunkZ, final net.minecraft.world.level.chunk.status.ChunkStatus leastStatus) { + final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder newChunkHolder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkX, chunkZ); @@ -26636,8 +26844,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 + public final void moonrise$midTickTasks() { + ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks(); + } - -- java.util.function.Consumer consumer = (net.minecraft.world.level.chunk.ChunkAccess chunk) -> { ++ + @Override + public final ChunkAccess moonrise$syncLoadNonFull(final int chunkX, final int chunkZ, final net.minecraft.world.level.chunk.status.ChunkStatus status) { + return this.moonrise$getChunkTaskScheduler().syncLoadNonFull(chunkX, chunkZ, status); @@ -26685,7 +26892,9 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 + priority, onLoad + ); + } -+ + +- int requiredChunks = (maxChunkX - minChunkX + 1) * (maxChunkZ - minChunkZ + 1); +- int[] loadedChunks = new int[1]; + @Override + public final void moonrise$loadChunksAsync(final BlockPos pos, final int radiusBlocks, + final net.minecraft.world.level.chunk.status.ChunkStatus chunkStatus, final ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, @@ -26698,14 +26907,16 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 + chunkStatus, priority, onLoad + ); + } -+ + +- Long holderIdentifier = Long.valueOf(chunkProvider.chunkFutureAwaitCounter++); + @Override + public final void moonrise$loadChunksAsync(final int minChunkX, final int maxChunkX, final int minChunkZ, final int maxChunkZ, + final ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, + final java.util.function.Consumer> onLoad) { + this.moonrise$loadChunksAsync(minChunkX, maxChunkX, minChunkZ, maxChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, priority, onLoad); + } -+ + +- java.util.function.Consumer consumer = (net.minecraft.world.level.chunk.ChunkAccess chunk) -> { + @Override + public final void moonrise$loadChunksAsync(final int minChunkX, final int maxChunkX, final int minChunkZ, final int maxChunkZ, + final net.minecraft.world.level.chunk.status.ChunkStatus chunkStatus, final ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, @@ -26747,7 +26958,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 } } } -@@ -326,22 +448,46 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -326,22 +448,122 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe for (int cx = minChunkX; cx <= maxChunkX; ++cx) { for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) { @@ -26768,7 +26979,8 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 - return player != null && player.level() == this ? player : null; + public final ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder moonrise$getViewDistanceHolder() { + return this.viewDistanceHolder; -+ } + } +- // Paper end - optimise getPlayerByUUID + + @Override + public final long moonrise$getLastMidTickFailure() { @@ -26788,8 +27000,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 + @Override + public final ca.spottedleaf.moonrise.common.list.ReferenceList moonrise$getLoadedChunks() { + return this.loadedChunks; - } -- // Paper end - optimise getPlayerByUUID ++ } + + @Override + public final ca.spottedleaf.moonrise.common.list.ReferenceList moonrise$getTickingChunks() { @@ -26801,10 +27012,86 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 + return this.entityTickingChunks; + } + // Paper end - rewrite chunk system ++ // Paper start - chunk tick iteration ++ private static final ServerChunkCache.ChunkAndHolder[] EMPTY_PLAYER_CHUNK_HOLDERS = new ServerChunkCache.ChunkAndHolder[0]; ++ private final ca.spottedleaf.moonrise.common.list.ReferenceList playerTickingChunks = new ca.spottedleaf.moonrise.common.list.ReferenceList<>(EMPTY_PLAYER_CHUNK_HOLDERS); ++ private final it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap playerTickingRequests = new it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap(); ++ ++ @Override ++ public final ca.spottedleaf.moonrise.common.list.ReferenceList moonrise$getPlayerTickingChunks() { ++ return this.playerTickingChunks; ++ } ++ ++ @Override ++ public final void moonrise$markChunkForPlayerTicking(final LevelChunk chunk) { ++ final ChunkPos pos = chunk.getPos(); ++ if (!this.playerTickingRequests.containsKey(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(pos))) { ++ return; ++ } ++ ++ this.playerTickingChunks.add(((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()); ++ } ++ ++ @Override ++ public final void moonrise$removeChunkForPlayerTicking(final LevelChunk chunk) { ++ this.playerTickingChunks.remove(((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()); ++ } ++ ++ @Override ++ public final void moonrise$addPlayerTickingRequest(final int chunkX, final int chunkZ) { ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel)(Object)this, chunkX, chunkZ, "Cannot add ticking request async"); ++ ++ final long chunkKey = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ); ++ ++ if (this.playerTickingRequests.addTo(chunkKey, 1) != 0) { ++ // already added ++ return; ++ } ++ ++ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)(ServerLevel)(Object)this).moonrise$getChunkTaskScheduler() ++ .chunkHolderManager.getChunkHolder(chunkKey); ++ ++ if (chunkHolder == null || !chunkHolder.isTickingReady()) { ++ return; ++ } ++ ++ this.playerTickingChunks.add( ++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk)(LevelChunk)chunkHolder.getCurrentChunk()).moonrise$getChunkAndHolder() ++ ); ++ } ++ ++ @Override ++ public final void moonrise$removePlayerTickingRequest(final int chunkX, final int chunkZ) { ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel)(Object)this, chunkX, chunkZ, "Cannot remove ticking request async"); ++ ++ final long chunkKey = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ); ++ final int val = this.playerTickingRequests.addTo(chunkKey, -1); ++ ++ if (val <= 0) { ++ throw new IllegalStateException("Negative counter"); ++ } ++ ++ if (val != 1) { ++ // still has at least one request ++ return; ++ } ++ ++ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)(ServerLevel)(Object)this).moonrise$getChunkTaskScheduler() ++ .chunkHolderManager.getChunkHolder(chunkKey); ++ ++ if (chunkHolder == null || !chunkHolder.isTickingReady()) { ++ return; ++ } ++ ++ this.playerTickingChunks.remove( ++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk)(LevelChunk)chunkHolder.getCurrentChunk()).moonrise$getChunkAndHolder() ++ ); ++ } ++ // Paper end - chunk tick iteration // Add env and gen to constructor, IWorldDataServer -> WorldDataServer public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { -@@ -375,14 +521,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -375,14 +597,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe DataFixer datafixer = minecraftserver.getFixerUpper(); EntityPersistentStorage entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver); @@ -26822,7 +27109,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 return minecraftserver.overworld().getDataStorage(); }); this.chunkSource.getGeneratorState().ensureStructuresGenerated(); -@@ -410,6 +555,19 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -410,6 +631,19 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.randomSequences = (RandomSequences) Objects.requireNonNullElseGet(randomsequences, () -> { return (RandomSequences) this.getDataStorage().computeIfAbsent(RandomSequences.factory(l), "random_sequences"); }); @@ -26842,7 +27129,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit } -@@ -542,7 +700,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -542,7 +776,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe gameprofilerfiller.push("checkDespawn"); entity.checkDespawn(); gameprofilerfiller.pop(); @@ -26851,7 +27138,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 Entity entity1 = entity.getVehicle(); if (entity1 != null) { -@@ -567,13 +725,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -567,13 +801,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } gameprofilerfiller.push("entityManagement"); @@ -26870,7 +27157,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 } protected void tickTime() { -@@ -613,7 +774,60 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -613,7 +850,60 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe }); } @@ -26931,7 +27218,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 ChunkPos chunkcoordintpair = chunk.getPos(); boolean flag = this.isRaining(); int j = chunkcoordintpair.getMinBlockX(); -@@ -621,7 +835,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -621,7 +911,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe ProfilerFiller gameprofilerfiller = Profiler.get(); gameprofilerfiller.push("thunder"); @@ -26940,7 +27227,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 BlockPos blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15)); if (this.isRainingAt(blockposition)) { -@@ -653,7 +867,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -653,7 +943,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (!this.paperConfig().environment.disableIceAndSnow) { // Paper - Option to disable ice and snow for (int l = 0; l < randomTickSpeed; ++l) { @@ -26949,7 +27236,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 this.tickPrecipitation(this.getBlockRandomPos(j, 0, k, 15)); } } -@@ -662,35 +876,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -662,35 +952,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe gameprofilerfiller.popPush("tickBlocks"); timings.chunkTicksBlocks.startTiming(); // Paper if (randomTickSpeed > 0) { @@ -26986,7 +27273,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 } timings.chunkTicksBlocks.stopTiming(); // Paper -@@ -964,6 +1150,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -964,6 +1226,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (fluid1.is(fluid)) { fluid1.tick(this, pos, iblockdata); } @@ -26998,7 +27285,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 } -@@ -973,6 +1164,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -973,6 +1240,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (iblockdata.is(block)) { iblockdata.tick(this, pos, this.random); } @@ -27010,7 +27297,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 } -@@ -1049,6 +1245,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1049,6 +1321,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } public void save(@Nullable ProgressListener progressListener, boolean flush, boolean savingDisabled) { @@ -27022,7 +27309,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 ServerChunkCache chunkproviderserver = this.getChunkSource(); if (!savingDisabled) { -@@ -1064,16 +1265,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1064,16 +1341,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } timings.worldSaveChunks.startTiming(); // Paper @@ -27050,7 +27337,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 // CraftBukkit start - moved from MinecraftServer.saveChunks ServerLevel worldserver1 = this; -@@ -1213,7 +1419,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1213,7 +1495,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.removePlayerImmediately((ServerPlayer) entity, Entity.RemovalReason.DISCARDED); } @@ -27059,7 +27346,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 } // CraftBukkit start -@@ -1243,7 +1449,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1243,7 +1525,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } // CraftBukkit end @@ -27068,7 +27355,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 } } -@@ -1254,11 +1460,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1254,11 +1536,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public boolean tryAddFreshEntityWithPassengers(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { // CraftBukkit end @@ -27081,7 +27368,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 return false; } else { this.addFreshEntityWithPassengers(entity, reason); // CraftBukkit -@@ -1891,7 +2093,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1891,7 +2169,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } } @@ -27090,7 +27377,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 bufferedwriter.write(String.format(Locale.ROOT, "block_entity_tickers: %d\n", this.blockEntityTickers.size())); bufferedwriter.write(String.format(Locale.ROOT, "block_ticks: %d\n", this.getBlockTicks().count())); bufferedwriter.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count())); -@@ -1940,7 +2142,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1940,7 +2218,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe BufferedWriter bufferedwriter2 = Files.newBufferedWriter(path1); try { @@ -27099,7 +27386,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 } catch (Throwable throwable4) { if (bufferedwriter2 != null) { try { -@@ -1961,7 +2163,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1961,7 +2239,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe BufferedWriter bufferedwriter3 = Files.newBufferedWriter(path2); try { @@ -27108,7 +27395,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 } catch (Throwable throwable6) { if (bufferedwriter3 != null) { try { -@@ -2103,7 +2305,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2103,7 +2381,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @VisibleForTesting public String getWatchdogStats() { @@ -27117,7 +27404,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString(); }), this.blockEntityTickers.size(), ServerLevel.getTypeCount(this.blockEntityTickers, TickingBlockEntity::getType), this.getBlockTicks().count(), this.getFluidTicks().count(), this.gatherChunkSourceStats()); } -@@ -2133,15 +2335,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2133,15 +2411,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public LevelEntityGetter getEntities() { org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot @@ -27146,7 +27433,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 } public void startTickingChunk(LevelChunk chunk) { -@@ -2161,34 +2373,47 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2161,34 +2449,47 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public void close() throws IOException { super.close(); @@ -27201,7 +27488,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..c7523387f0e9bbfe952abd237a936c83 } @Override -@@ -2234,7 +2459,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2234,7 +2535,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report); crashreportsystemdetails.setDetail("Loaded entity count", () -> { From 2a95ad1df30578b1879b01ac036e058a77824a26 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 24 Oct 2024 10:16:56 -0700 Subject: [PATCH 065/119] Implement explosion optimisations --- moonrise_update_1_21_2.txt | 1 - .../0826-Moonrise-optimisation-patches.patch | 439 ++++++++++++++++++ 2 files changed, 439 insertions(+), 1 deletion(-) diff --git a/moonrise_update_1_21_2.txt b/moonrise_update_1_21_2.txt index 2ff8731cdf03..c889f78d91a8 100644 --- a/moonrise_update_1_21_2.txt +++ b/moonrise_update_1_21_2.txt @@ -17,7 +17,6 @@ todo: - implement chunk_system.SectionStorageMixin diff from reference - implement chunk_system.SerializableChunkDataMixin diff from reference - implement chunk_system.ServerLevelMixin diff from reference -- implement collisions.ServerExplosionMixin diff from reference - implement starlight.LevelLightEngineMixin diff from reference - implement starlight.ThreadedLevelLightEngineMixin diff from reference - implement starlight.ChunkSerializerMixin diff from reference diff --git a/patches/server/0826-Moonrise-optimisation-patches.patch b/patches/server/0826-Moonrise-optimisation-patches.patch index 536918d0f396..936f34e74040 100644 --- a/patches/server/0826-Moonrise-optimisation-patches.patch +++ b/patches/server/0826-Moonrise-optimisation-patches.patch @@ -30275,6 +30275,445 @@ index 5eb8982678110fabb82a93c5ec67c666b7fde017..ade435de0af4ee3566fa4a490df53cdd @Nullable ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create); +diff --git a/src/main/java/net/minecraft/world/level/ServerExplosion.java b/src/main/java/net/minecraft/world/level/ServerExplosion.java +index 86656de31b1e33381eddd3ef210122118b31e620..c7fd8ce0dae838d91915a1c7a34152bed3ac7682 100644 +--- a/src/main/java/net/minecraft/world/level/ServerExplosion.java ++++ b/src/main/java/net/minecraft/world/level/ServerExplosion.java +@@ -64,6 +64,249 @@ public class ServerExplosion implements Explosion { + public float yield; + // CraftBukkit end + public boolean excludeSourceFromDamage = true; // Paper - Allow explosions to damage source ++ // Paper start - collisions optimisations ++ private static final double[] CACHED_RAYS; ++ static { ++ final it.unimi.dsi.fastutil.doubles.DoubleArrayList rayCoords = new it.unimi.dsi.fastutil.doubles.DoubleArrayList(); ++ ++ for (int x = 0; x <= 15; ++x) { ++ for (int y = 0; y <= 15; ++y) { ++ for (int z = 0; z <= 15; ++z) { ++ if ((x == 0 || x == 15) || (y == 0 || y == 15) || (z == 0 || z == 15)) { ++ double xDir = (double)((float)x / 15.0F * 2.0F - 1.0F); ++ double yDir = (double)((float)y / 15.0F * 2.0F - 1.0F); ++ double zDir = (double)((float)z / 15.0F * 2.0F - 1.0F); ++ ++ double mag = Math.sqrt( ++ xDir * xDir + yDir * yDir + zDir * zDir ++ ); ++ ++ rayCoords.add((xDir / mag) * (double)0.3F); ++ rayCoords.add((yDir / mag) * (double)0.3F); ++ rayCoords.add((zDir / mag) * (double)0.3F); ++ } ++ } ++ } ++ } ++ ++ CACHED_RAYS = rayCoords.toDoubleArray(); ++ } ++ ++ private static final int CHUNK_CACHE_SHIFT = 2; ++ private static final int CHUNK_CACHE_MASK = (1 << CHUNK_CACHE_SHIFT) - 1; ++ private static final int CHUNK_CACHE_WIDTH = 1 << CHUNK_CACHE_SHIFT; ++ ++ private static final int BLOCK_EXPLOSION_CACHE_SHIFT = 3; ++ private static final int BLOCK_EXPLOSION_CACHE_MASK = (1 << BLOCK_EXPLOSION_CACHE_SHIFT) - 1; ++ private static final int BLOCK_EXPLOSION_CACHE_WIDTH = 1 << BLOCK_EXPLOSION_CACHE_SHIFT; ++ ++ // resistance = (res + 0.3F) * 0.3F; ++ // so for resistance = 0, we need res = -0.3F ++ private static final Float ZERO_RESISTANCE = Float.valueOf(-0.3f); ++ private it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap blockCache = null; ++ private long[] chunkPosCache = null; ++ private net.minecraft.world.level.chunk.LevelChunk[] chunkCache = null; ++ private ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache[] directMappedBlockCache; ++ private BlockPos.MutableBlockPos mutablePos; ++ ++ private ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache getOrCacheExplosionBlock(final int x, final int y, final int z, ++ final long key, final boolean calculateResistance) { ++ ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache ret = this.blockCache.get(key); ++ if (ret != null) { ++ return ret; ++ } ++ ++ BlockPos pos = new BlockPos(x, y, z); ++ ++ if (!this.level.isInWorldBounds(pos)) { ++ ret = new ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache(key, pos, null, null, 0.0f, true); ++ } else { ++ net.minecraft.world.level.chunk.LevelChunk chunk; ++ long chunkKey = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(x >> 4, z >> 4); ++ int chunkCacheKey = ((x >> 4) & CHUNK_CACHE_MASK) | (((z >> 4) << CHUNK_CACHE_SHIFT) & (CHUNK_CACHE_MASK << CHUNK_CACHE_SHIFT)); ++ if (this.chunkPosCache[chunkCacheKey] == chunkKey) { ++ chunk = this.chunkCache[chunkCacheKey]; ++ } else { ++ this.chunkPosCache[chunkCacheKey] = chunkKey; ++ this.chunkCache[chunkCacheKey] = chunk = this.level.getChunk(x >> 4, z >> 4); ++ } ++ ++ BlockState blockState = ((ca.spottedleaf.moonrise.patches.getblock.GetBlockChunk)chunk).moonrise$getBlock(x, y, z); ++ FluidState fluidState = blockState.getFluidState(); ++ ++ Optional resistance = !calculateResistance ? Optional.empty() : this.damageCalculator.getBlockExplosionResistance((Explosion)(Object)this, this.level, pos, blockState, fluidState); ++ ++ ret = new ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache( ++ key, pos, blockState, fluidState, ++ (resistance.orElse(ZERO_RESISTANCE).floatValue() + 0.3f) * 0.3f, ++ false ++ ); ++ } ++ ++ this.blockCache.put(key, ret); ++ ++ return ret; ++ } ++ ++ private boolean clipsAnything(final Vec3 from, final Vec3 to, ++ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext context, ++ final ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache[] blockCache, ++ final BlockPos.MutableBlockPos currPos) { ++ // assume that context.delegated = false ++ final double adjX = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON * (from.x - to.x); ++ final double adjY = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON * (from.y - to.y); ++ final double adjZ = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON * (from.z - to.z); ++ ++ if (adjX == 0.0 && adjY == 0.0 && adjZ == 0.0) { ++ return false; ++ } ++ ++ final double toXAdj = to.x - adjX; ++ final double toYAdj = to.y - adjY; ++ final double toZAdj = to.z - adjZ; ++ final double fromXAdj = from.x + adjX; ++ final double fromYAdj = from.y + adjY; ++ final double fromZAdj = from.z + adjZ; ++ ++ int currX = Mth.floor(fromXAdj); ++ int currY = Mth.floor(fromYAdj); ++ int currZ = Mth.floor(fromZAdj); ++ ++ final double diffX = toXAdj - fromXAdj; ++ final double diffY = toYAdj - fromYAdj; ++ final double diffZ = toZAdj - fromZAdj; ++ ++ final double dxDouble = Math.signum(diffX); ++ final double dyDouble = Math.signum(diffY); ++ final double dzDouble = Math.signum(diffZ); ++ ++ final int dx = (int)dxDouble; ++ final int dy = (int)dyDouble; ++ final int dz = (int)dzDouble; ++ ++ final double normalizedDiffX = diffX == 0.0 ? Double.MAX_VALUE : dxDouble / diffX; ++ final double normalizedDiffY = diffY == 0.0 ? Double.MAX_VALUE : dyDouble / diffY; ++ final double normalizedDiffZ = diffZ == 0.0 ? Double.MAX_VALUE : dzDouble / diffZ; ++ ++ double normalizedCurrX = normalizedDiffX * (diffX > 0.0 ? (1.0 - Mth.frac(fromXAdj)) : Mth.frac(fromXAdj)); ++ double normalizedCurrY = normalizedDiffY * (diffY > 0.0 ? (1.0 - Mth.frac(fromYAdj)) : Mth.frac(fromYAdj)); ++ double normalizedCurrZ = normalizedDiffZ * (diffZ > 0.0 ? (1.0 - Mth.frac(fromZAdj)) : Mth.frac(fromZAdj)); ++ ++ for (;;) { ++ currPos.set(currX, currY, currZ); ++ ++ // ClipContext.Block.COLLIDER -> BlockBehaviour.BlockStateBase::getCollisionShape ++ // ClipContext.Fluid.NONE -> ignore fluids ++ ++ // read block from cache ++ final long key = BlockPos.asLong(currX, currY, currZ); ++ ++ final int cacheKey = ++ (currX & BLOCK_EXPLOSION_CACHE_MASK) | ++ (currY & BLOCK_EXPLOSION_CACHE_MASK) << (BLOCK_EXPLOSION_CACHE_SHIFT) | ++ (currZ & BLOCK_EXPLOSION_CACHE_MASK) << (BLOCK_EXPLOSION_CACHE_SHIFT + BLOCK_EXPLOSION_CACHE_SHIFT); ++ ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache cachedBlock = blockCache[cacheKey]; ++ if (cachedBlock == null || cachedBlock.key != key) { ++ blockCache[cacheKey] = cachedBlock = this.getOrCacheExplosionBlock(currX, currY, currZ, key, false); ++ } ++ ++ final BlockState blockState = cachedBlock.blockState; ++ if (blockState != null && !((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockState).moonrise$emptyContextCollisionShape()) { ++ net.minecraft.world.phys.shapes.VoxelShape collision = cachedBlock.cachedCollisionShape; ++ if (collision == null) { ++ collision = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)blockState).moonrise$getConstantContextCollisionShape(); ++ if (collision == null) { ++ collision = blockState.getCollisionShape(this.level, currPos, context); ++ if (!context.isDelegated()) { ++ // if it was not delegated during this call, assume that for any future ones it will not be delegated ++ // again, and cache the result ++ cachedBlock.cachedCollisionShape = collision; ++ } ++ } else { ++ cachedBlock.cachedCollisionShape = collision; ++ } ++ } ++ ++ if (!collision.isEmpty() && collision.clip(from, to, currPos) != null) { ++ return true; ++ } ++ } ++ ++ if (normalizedCurrX > 1.0 && normalizedCurrY > 1.0 && normalizedCurrZ > 1.0) { ++ return false; ++ } ++ ++ // inc the smallest normalized coordinate ++ ++ if (normalizedCurrX < normalizedCurrY) { ++ if (normalizedCurrX < normalizedCurrZ) { ++ currX += dx; ++ normalizedCurrX += normalizedDiffX; ++ } else { ++ // x < y && x >= z <--> z < y && z <= x ++ currZ += dz; ++ normalizedCurrZ += normalizedDiffZ; ++ } ++ } else if (normalizedCurrY < normalizedCurrZ) { ++ // y <= x && y < z ++ currY += dy; ++ normalizedCurrY += normalizedDiffY; ++ } else { ++ // y <= x && z <= y <--> z <= y && z <= x ++ currZ += dz; ++ normalizedCurrZ += normalizedDiffZ; ++ } ++ } ++ } ++ ++ private float getSeenFraction(final Vec3 source, final Entity target, ++ final ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache[] blockCache, ++ final BlockPos.MutableBlockPos blockPos) { ++ final AABB boundingBox = target.getBoundingBox(); ++ final double diffX = boundingBox.maxX - boundingBox.minX; ++ final double diffY = boundingBox.maxY - boundingBox.minY; ++ final double diffZ = boundingBox.maxZ - boundingBox.minZ; ++ ++ final double incX = 1.0 / (diffX * 2.0 + 1.0); ++ final double incY = 1.0 / (diffY * 2.0 + 1.0); ++ final double incZ = 1.0 / (diffZ * 2.0 + 1.0); ++ ++ if (incX < 0.0 || incY < 0.0 || incZ < 0.0) { ++ return 0.0f; ++ } ++ ++ final double offX = (1.0 - Math.floor(1.0 / incX) * incX) * 0.5 + boundingBox.minX; ++ final double offY = boundingBox.minY; ++ final double offZ = (1.0 - Math.floor(1.0 / incZ) * incZ) * 0.5 + boundingBox.minZ; ++ ++ final ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext context = new ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.LazyEntityCollisionContext(target); ++ ++ int totalRays = 0; ++ int missedRays = 0; ++ ++ for (double dx = 0.0; dx <= 1.0; dx += incX) { ++ final double fromX = Math.fma(dx, diffX, offX); ++ for (double dy = 0.0; dy <= 1.0; dy += incY) { ++ final double fromY = Math.fma(dy, diffY, offY); ++ for (double dz = 0.0; dz <= 1.0; dz += incZ) { ++ ++totalRays; ++ ++ final Vec3 from = new Vec3( ++ fromX, ++ fromY, ++ Math.fma(dz, diffZ, offZ) ++ ); ++ ++ if (!this.clipsAnything(from, source, context, blockCache, blockPos)) { ++ ++missedRays; ++ } ++ } ++ } ++ } ++ ++ return (float)missedRays / (float)totalRays; ++ } ++ // Paper end - collisions optimisations + + public ServerExplosion(ServerLevel world, @Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, Vec3 pos, float power, boolean createFire, Explosion.BlockInteraction destructionType) { + this.level = world; +@@ -127,64 +370,91 @@ public class ServerExplosion implements Explosion { + } + + private List calculateExplodedPositions() { +- Set set = new HashSet(); +- boolean flag = true; +- +- for (int i = 0; i < 16; ++i) { +- for (int j = 0; j < 16; ++j) { +- for (int k = 0; k < 16; ++k) { +- if (i == 0 || i == 15 || j == 0 || j == 15 || k == 0 || k == 15) { +- double d0 = (double) ((float) i / 15.0F * 2.0F - 1.0F); +- double d1 = (double) ((float) j / 15.0F * 2.0F - 1.0F); +- double d2 = (double) ((float) k / 15.0F * 2.0F - 1.0F); +- double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2); +- +- d0 /= d3; +- d1 /= d3; +- d2 /= d3; +- float f = this.radius * (0.7F + this.level.random.nextFloat() * 0.6F); +- double d4 = this.center.x; +- double d5 = this.center.y; +- double d6 = this.center.z; +- +- for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) { +- BlockPos blockposition = BlockPos.containing(d4, d5, d6); +- BlockState iblockdata = this.level.getBlockState(blockposition); +- FluidState fluid = iblockdata.getFluidState(); // Paper - Perf: Optimize call to getFluid for explosions +- +- if (!this.level.isInWorldBounds(blockposition)) { +- break; +- } ++ // Paper start - collision optimisations ++ final ObjectArrayList ret = new ObjectArrayList<>(); + +- Optional optional = this.damageCalculator.getBlockExplosionResistance(this, this.level, blockposition, iblockdata, fluid); ++ final Vec3 center = this.center; + +- if (optional.isPresent()) { +- f -= ((Float) optional.get() + 0.3F) * 0.3F; +- } ++ final ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache[] blockCache = this.directMappedBlockCache; + +- if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this, this.level, blockposition, iblockdata, f)) { +- set.add(blockposition); +- // Paper start - prevent headless pistons from forming +- if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowHeadlessPistons && iblockdata.getBlock() == Blocks.MOVING_PISTON) { +- net.minecraft.world.level.block.entity.BlockEntity extension = this.level.getBlockEntity(blockposition); +- if (extension instanceof net.minecraft.world.level.block.piston.PistonMovingBlockEntity blockEntity && blockEntity.isSourcePiston()) { +- net.minecraft.core.Direction direction = iblockdata.getValue(net.minecraft.world.level.block.piston.PistonHeadBlock.FACING); +- set.add(blockposition.relative(direction.getOpposite())); +- } +- } +- // Paper end - prevent headless pistons from forming +- } ++ // use initial cache value that is most likely to be used: the source position ++ final ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache initialCache; ++ { ++ final int blockX = Mth.floor(center.x); ++ final int blockY = Mth.floor(center.y); ++ final int blockZ = Mth.floor(center.z); ++ ++ final long key = BlockPos.asLong(blockX, blockY, blockZ); ++ ++ initialCache = this.getOrCacheExplosionBlock(blockX, blockY, blockZ, key, true); ++ } + +- d4 += d0 * 0.30000001192092896D; +- d5 += d1 * 0.30000001192092896D; +- d6 += d2 * 0.30000001192092896D; ++ // only ~1/3rd of the loop iterations in vanilla will result in a ray, as it is iterating the perimeter of ++ // a 16x16x16 cube ++ // we can cache the rays and their normals as well, so that we eliminate the excess iterations / checks and ++ // calculations in one go ++ // additional aggressive caching of block retrieval is very significant, as at low power (i.e tnt) most ++ // block retrievals are not unique ++ for (int ray = 0, len = CACHED_RAYS.length; ray < len;) { ++ ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache cachedBlock = initialCache; ++ ++ double currX = center.x; ++ double currY = center.y; ++ double currZ = center.z; ++ ++ final double incX = CACHED_RAYS[ray]; ++ final double incY = CACHED_RAYS[ray + 1]; ++ final double incZ = CACHED_RAYS[ray + 2]; ++ ++ ray += 3; ++ ++ float power = this.radius * (0.7F + this.level.random.nextFloat() * 0.6F); ++ ++ do { ++ final int blockX = Mth.floor(currX); ++ final int blockY = Mth.floor(currY); ++ final int blockZ = Mth.floor(currZ); ++ ++ final long key = BlockPos.asLong(blockX, blockY, blockZ); ++ ++ if (cachedBlock.key != key) { ++ final int cacheKey = ++ (blockX & BLOCK_EXPLOSION_CACHE_MASK) | ++ (blockY & BLOCK_EXPLOSION_CACHE_MASK) << (BLOCK_EXPLOSION_CACHE_SHIFT) | ++ (blockZ & BLOCK_EXPLOSION_CACHE_MASK) << (BLOCK_EXPLOSION_CACHE_SHIFT + BLOCK_EXPLOSION_CACHE_SHIFT); ++ cachedBlock = blockCache[cacheKey]; ++ if (cachedBlock == null || cachedBlock.key != key) { ++ blockCache[cacheKey] = cachedBlock = this.getOrCacheExplosionBlock(blockX, blockY, blockZ, key, true); ++ } ++ } ++ ++ if (cachedBlock.outOfWorld) { ++ break; ++ } ++ ++ power -= cachedBlock.resistance; ++ ++ if (power > 0.0f && cachedBlock.shouldExplode == null) { ++ // note: we expect shouldBlockExplode to be pure with respect to power, as Vanilla currently is. ++ // basically, it is unused, which allows us to cache the result ++ final boolean shouldExplode = this.damageCalculator.shouldBlockExplode((Explosion)(Object)this, this.level, cachedBlock.immutablePos, cachedBlock.blockState, power); ++ cachedBlock.shouldExplode = shouldExplode ? Boolean.TRUE : Boolean.FALSE; ++ if (shouldExplode) { ++ if (this.fire || !cachedBlock.blockState.isAir()) { ++ ret.add(cachedBlock.immutablePos); + } + } + } +- } ++ ++ power -= 0.22500001F; ++ currX += incX; ++ currY += incY; ++ currZ += incZ; ++ } while (power > 0.0f); + } + +- return new ObjectArrayList(set); ++ return ret; ++ // Paper end - collision optimisations + } + + private void hurtEntities() { +@@ -390,6 +660,14 @@ public class ServerExplosion implements Explosion { + return; + } + // CraftBukkit end ++ // Paper start - collision optimisations ++ this.blockCache = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>(); ++ this.chunkPosCache = new long[CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH]; ++ java.util.Arrays.fill(this.chunkPosCache, ChunkPos.INVALID_CHUNK_POS); ++ this.chunkCache = new net.minecraft.world.level.chunk.LevelChunk[CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH]; ++ this.directMappedBlockCache = new ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache[BLOCK_EXPLOSION_CACHE_WIDTH * BLOCK_EXPLOSION_CACHE_WIDTH * BLOCK_EXPLOSION_CACHE_WIDTH]; ++ this.mutablePos = new BlockPos.MutableBlockPos(); ++ // Paper end - collision optimisations + this.level.gameEvent(this.source, (Holder) GameEvent.EXPLODE, this.center); + List list = this.calculateExplodedPositions(); + +@@ -405,6 +683,13 @@ public class ServerExplosion implements Explosion { + if (this.fire) { + this.createFire(list); + } ++ // Paper start - collision optimisations ++ this.blockCache = null; ++ this.chunkPosCache = null; ++ this.chunkCache = null; ++ this.directMappedBlockCache = null; ++ this.mutablePos = null; ++ // Paper end - collision optimisations + + } + +@@ -494,12 +779,12 @@ public class ServerExplosion implements Explosion { + // Paper start - Optimize explosions + private float getBlockDensity(Vec3 vec3d, Entity entity) { + if (!this.level.paperConfig().environment.optimizeExplosions) { +- return getSeenPercent(vec3d, entity); ++ return this.getSeenFraction(vec3d, entity, this.directMappedBlockCache, this.mutablePos); // Paper - collision optimisations + } + CacheKey key = new CacheKey(this, entity.getBoundingBox()); + Float blockDensity = this.level.explosionDensityCache.get(key); + if (blockDensity == null) { +- blockDensity = getSeenPercent(vec3d, entity); ++ blockDensity = this.getSeenFraction(vec3d, entity, this.directMappedBlockCache, this.mutablePos); // Paper - collision optimisations + this.level.explosionDensityCache.put(key, blockDensity); + } + diff --git a/src/main/java/net/minecraft/world/level/biome/Biome.java b/src/main/java/net/minecraft/world/level/biome/Biome.java index 8590de51b572c0f73d45aee60313d466e4671da5..b725eea9d3ca81d2ef7802f5d0346d924aa1f808 100644 --- a/src/main/java/net/minecraft/world/level/biome/Biome.java From 16d2c9defedbf0eac94e342cbbe6b21b7748c88f Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 24 Oct 2024 10:39:36 -0700 Subject: [PATCH 066/119] Implement Starlight --- moonrise_update_1_21_2.txt | 7 +- .../0826-Moonrise-optimisation-patches.patch | 291 +++++++++++++++++- 2 files changed, 287 insertions(+), 11 deletions(-) diff --git a/moonrise_update_1_21_2.txt b/moonrise_update_1_21_2.txt index c889f78d91a8..c1f541edbc34 100644 --- a/moonrise_update_1_21_2.txt +++ b/moonrise_update_1_21_2.txt @@ -1,5 +1,5 @@ reference comparison: -https://github.com/Tuinity/Moonrise/compare/6a2c6d27df11d417c1fefa749109d8e87599e8c2...03784b8c69c299db4af4f9984565e5752617d9dc +https://github.com/Tuinity/Moonrise/compare/6a2c6d27df11d417c1fefa749109d8e87599e8c2...f22335f0b65e205831c74a7b4b8f4d93fff54fd5 need to compare the diffs @@ -17,9 +17,4 @@ todo: - implement chunk_system.SectionStorageMixin diff from reference - implement chunk_system.SerializableChunkDataMixin diff from reference - implement chunk_system.ServerLevelMixin diff from reference -- implement starlight.LevelLightEngineMixin diff from reference -- implement starlight.ThreadedLevelLightEngineMixin diff from reference -- implement starlight.ChunkSerializerMixin diff from reference -- implement starlight.SerializableChunkData$SectionData diff from reference -- implement starlight.SerializableChunkDataMixin diff from reference - chunk system: move get entity lookup reroute into the folia scheduler api patch diff --git a/patches/server/0826-Moonrise-optimisation-patches.patch b/patches/server/0826-Moonrise-optimisation-patches.patch index 936f34e74040..d3b83d533f91 100644 --- a/patches/server/0826-Moonrise-optimisation-patches.patch +++ b/patches/server/0826-Moonrise-optimisation-patches.patch @@ -27548,10 +27548,10 @@ index 1a7d2ade0e85dd5e6cd6c9202e3277cc2fa43d4a..ba15c34a3ea516d2d946d923551293ac super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); this.chatVisibility = ChatVisiblity.FULL; diff --git a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -index 39d34f3728ae8d845d1bffc09f3ab8b64eb4d48b..653ba7bb4f4793d7a7cad903e9695ff49666985f 100644 +index 39d34f3728ae8d845d1bffc09f3ab8b64eb4d48b..3e82adf061bd0ec0100ca4d16ec9b157bddf99a7 100644 --- a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java +++ b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -@@ -22,23 +22,135 @@ import net.minecraft.world.level.chunk.LightChunkGetter; +@@ -22,23 +22,134 @@ import net.minecraft.world.level.chunk.LightChunkGetter; import net.minecraft.world.level.lighting.LevelLightEngine; import org.slf4j.Logger; @@ -27577,8 +27577,7 @@ index 39d34f3728ae8d845d1bffc09f3ab8b64eb4d48b..653ba7bb4f4793d7a7cad903e9695ff4 + + final ChunkAccess center = this.starlight$getLightEngine().getAnyChunkNow(chunkX, chunkZ); + if (center == null || !center.getPersistedStatus().isOrAfter(net.minecraft.world.level.chunk.status.ChunkStatus.LIGHT)) { -+ // do not accept updates in unlit chunks, unless we might be generating a chunk. thanks to the amazing -+ // chunk scheduling, we could be lighting and generating a chunk at the same time ++ // do not accept updates in unlit chunks, unless we might be generating a chunk + return; + } + @@ -27694,7 +27693,7 @@ index 39d34f3728ae8d845d1bffc09f3ab8b64eb4d48b..653ba7bb4f4793d7a7cad903e9695ff4 } @Override -@@ -52,164 +164,73 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl +@@ -52,164 +163,73 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl @Override public void checkBlock(BlockPos pos) { @@ -33172,6 +33171,288 @@ index 93972352cd4881dccba9b90ccc8dcced3563e340..c3beb7fcad46a917d2b61bd0a0e98e51 } static record PackedChunk(Int2ObjectMap sectionsByY, boolean versionChanged) { +diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +index d7a204216332ccbd6bece23bd507be0366ea4d61..5698e04fd1210eadc9a5091a59bf408a789081fb 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java ++++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +@@ -128,7 +128,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + long j = nbt.getLong("InhabitedTime"); + ChunkStatus chunkstatus = ChunkStatus.byName(nbt.getString("Status")); + UpgradeData chunkconverter = nbt.contains("UpgradeData", 10) ? new UpgradeData(nbt.getCompound("UpgradeData"), world) : UpgradeData.EMPTY; +- boolean flag = nbt.getBoolean("isLightOn"); ++ boolean flag = chunkstatus.isOrAfter(ChunkStatus.LIGHT) && (nbt.get("isLightOn") != null && nbt.getInt(ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.STARLIGHT_VERSION_TAG) == ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.STARLIGHT_LIGHT_VERSION); // Paper - starlight + DataResult dataresult; + Logger logger; + BlendingData.Packed blendingdata_d; +@@ -208,7 +208,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + Codec>> codec = makeBiomeCodecRW(iregistry); // CraftBukkit - read/write + + for (int i1 = 0; i1 < nbttaglist2.size(); ++i1) { +- CompoundTag nbttagcompound3 = nbttaglist2.getCompound(i1); ++ CompoundTag nbttagcompound3 = nbttaglist2.getCompound(i1); final CompoundTag sectionData = nbttagcompound3; // Paper - starlight - OBFHELPER + byte b0 = nbttagcompound3.getByte("Y"); + LevelChunkSection chunksection; + +@@ -241,7 +241,17 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + DataLayer nibblearray = nbttagcompound3.contains("BlockLight", 7) ? new DataLayer(nbttagcompound3.getByteArray("BlockLight")) : null; + DataLayer nibblearray1 = nbttagcompound3.contains("SkyLight", 7) ? new DataLayer(nbttagcompound3.getByteArray("SkyLight")) : null; + +- list4.add(new SerializableChunkData.SectionData(b0, chunksection, nibblearray, nibblearray1)); ++ // Paper start - starlight ++ SerializableChunkData.SectionData serializableChunkData = new SerializableChunkData.SectionData(b0, chunksection, nibblearray, nibblearray1); ++ if (sectionData.contains(ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.BLOCKLIGHT_STATE_TAG, Tag.TAG_ANY_NUMERIC)) { ++ ((ca.spottedleaf.moonrise.patches.starlight.storage.StarlightSectionData)(Object)serializableChunkData).starlight$setBlockLightState(sectionData.getInt(ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.BLOCKLIGHT_STATE_TAG)); ++ } ++ ++ if (sectionData.contains(ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.SKYLIGHT_STATE_TAG, Tag.TAG_ANY_NUMERIC)) { ++ ((ca.spottedleaf.moonrise.patches.starlight.storage.StarlightSectionData)(Object)serializableChunkData).starlight$setSkyLightState(sectionData.getInt(ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.SKYLIGHT_STATE_TAG)); ++ } ++ list4.add(serializableChunkData); ++ // Paper end - starlight + } + + // CraftBukkit - ChunkBukkitValues +@@ -249,6 +259,47 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + } + } + ++ // Paper start - starlight ++ private ProtoChunk loadStarlightLightData(final ServerLevel world, final ProtoChunk ret) { ++ ++ final boolean hasSkyLight = world.dimensionType().hasSkyLight(); ++ final int minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinLightSection(world); ++ ++ final ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray[] blockNibbles = ca.spottedleaf.moonrise.patches.starlight.light.StarLightEngine.getFilledEmptyLight(world); ++ final ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray[] skyNibbles = ca.spottedleaf.moonrise.patches.starlight.light.StarLightEngine.getFilledEmptyLight(world); ++ ++ for (final SerializableChunkData.SectionData sectionData : this.sectionData) { ++ final int y = sectionData.y(); ++ final DataLayer blockLight = sectionData.blockLight(); ++ final DataLayer skyLight = sectionData.skyLight(); ++ ++ final int blockState = ((ca.spottedleaf.moonrise.patches.starlight.storage.StarlightSectionData)(Object)sectionData).starlight$getBlockLightState(); ++ final int skyState = ((ca.spottedleaf.moonrise.patches.starlight.storage.StarlightSectionData)(Object)sectionData).starlight$getSkyLightState(); ++ ++ if (blockState >= 0) { ++ if (blockLight != null) { ++ blockNibbles[y - minSection] = new ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray(ca.spottedleaf.moonrise.common.util.MixinWorkarounds.clone(blockLight.getData()), blockState); // clone for data safety ++ } else { ++ blockNibbles[y - minSection] = new ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray(null, blockState); ++ } ++ } ++ ++ if (skyState >= 0 && hasSkyLight) { ++ if (skyLight != null) { ++ skyNibbles[y - minSection] = new ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray(ca.spottedleaf.moonrise.common.util.MixinWorkarounds.clone(skyLight.getData()), skyState); // clone for data safety ++ } else { ++ skyNibbles[y - minSection] = new ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray(null, skyState); ++ } ++ } ++ } ++ ++ ((ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk)ret).starlight$setBlockNibbles(blockNibbles); ++ ((ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk)ret).starlight$setSkyNibbles(skyNibbles); ++ ++ return ret; ++ } ++ // Paper end - starlight ++ + public ProtoChunk read(ServerLevel world, PoiManager poiStorage, RegionStorageInfo key, ChunkPos expectedPos) { + if (!Objects.equals(expectedPos, this.chunkPos)) { + SerializableChunkData.LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", new Object[]{expectedPos, expectedPos, this.chunkPos}); +@@ -347,7 +398,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + } + + if (chunktype == ChunkType.LEVELCHUNK) { +- return new ImposterProtoChunk((LevelChunk) object, false); ++ return this.loadStarlightLightData(world, new ImposterProtoChunk((LevelChunk) object, false)); // Paper - starlight + } else { + ProtoChunk protochunk1 = (ProtoChunk) object; + Iterator iterator2 = this.entities.iterator(); +@@ -370,7 +421,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + protochunk1.setCarvingMask(new CarvingMask(this.carvingMask, ((ChunkAccess) object).getMinY())); + } + +- return protochunk1; ++ return this.loadStarlightLightData(world, protochunk1); // Paper - starlight + } + } + +@@ -393,24 +444,48 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + throw new IllegalArgumentException("Chunk can't be serialized: " + String.valueOf(chunk)); + } else { + ChunkPos chunkcoordintpair = chunk.getPos(); +- List list = new ArrayList(); ++ List list = new ArrayList(); final List sections = list; // Paper - starlight - OBFHELPER + LevelChunkSection[] achunksection = chunk.getSections(); + ThreadedLevelLightEngine lightenginethreaded = world.getChunkSource().getLightEngine(); + +- for (int i = lightenginethreaded.getMinLightSection(); i < lightenginethreaded.getMaxLightSection(); ++i) { +- int j = chunk.getSectionIndexFromSectionY(i); +- boolean flag = j >= 0 && j < achunksection.length; +- DataLayer nibblearray = lightenginethreaded.getLayerListener(LightLayer.BLOCK).getDataLayerData(SectionPos.of(chunkcoordintpair, i)); +- DataLayer nibblearray1 = lightenginethreaded.getLayerListener(LightLayer.SKY).getDataLayerData(SectionPos.of(chunkcoordintpair, i)); +- DataLayer nibblearray2 = nibblearray != null && !nibblearray.isEmpty() ? nibblearray.copy() : null; +- DataLayer nibblearray3 = nibblearray1 != null && !nibblearray1.isEmpty() ? nibblearray1.copy() : null; ++ // Paper start - starlight ++ final int minLightSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinLightSection(world); ++ final int maxLightSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxLightSection(world); ++ final int minBlockSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(world); ++ ++ final LevelChunkSection[] chunkSections = chunk.getSections(); ++ final ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray[] blockNibbles = ((ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk)chunk).starlight$getBlockNibbles(); ++ final ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray[] skyNibbles = ((ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk)chunk).starlight$getSkyNibbles(); ++ ++ for (int lightSection = minLightSection; lightSection <= maxLightSection; ++lightSection) { ++ final int lightSectionIdx = lightSection - minLightSection; ++ final int blockSectionIdx = lightSection - minBlockSection; ++ ++ final LevelChunkSection chunkSection = (blockSectionIdx >= 0 && blockSectionIdx < chunkSections.length) ? chunkSections[blockSectionIdx].copy() : null; ++ final ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray.SaveState blockNibble = blockNibbles[lightSectionIdx].getSaveState(); ++ final ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray.SaveState skyNibble = skyNibbles[lightSectionIdx].getSaveState(); ++ ++ if (chunkSection == null && blockNibble == null && skyNibble == null) { ++ continue; ++ } ++ ++ final SerializableChunkData.SectionData sectionData = new SerializableChunkData.SectionData( ++ lightSection, chunkSection, ++ blockNibble == null ? null : (blockNibble.data == null ? null : new DataLayer(blockNibble.data)), ++ skyNibble == null ? null : (skyNibble.data == null ? null : new DataLayer(skyNibble.data)) ++ ); + +- if (flag || nibblearray2 != null || nibblearray3 != null) { +- LevelChunkSection chunksection = flag ? achunksection[j].copy() : null; ++ if (blockNibble != null) { ++ ((ca.spottedleaf.moonrise.patches.starlight.storage.StarlightSectionData)(Object)sectionData).starlight$setBlockLightState(blockNibble.state); ++ } + +- list.add(new SerializableChunkData.SectionData(i, chunksection, nibblearray2, nibblearray3)); ++ if (skyNibble != null) { ++ ((ca.spottedleaf.moonrise.patches.starlight.storage.StarlightSectionData)(Object)sectionData).starlight$setSkyLightState(skyNibble.state); + } ++ ++ sections.add(sectionData); + } ++ // Paper end - starlight + + List list1 = new ArrayList(chunk.getBlockEntitiesPos().size()); + Iterator iterator = chunk.getBlockEntitiesPos().iterator(); +@@ -509,8 +584,8 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + Iterator iterator = this.sectionData.iterator(); + + while (iterator.hasNext()) { +- SerializableChunkData.SectionData serializablechunkdata_b = (SerializableChunkData.SectionData) iterator.next(); +- CompoundTag nbttagcompound1 = new CompoundTag(); ++ SerializableChunkData.SectionData serializablechunkdata_b = (SerializableChunkData.SectionData) iterator.next(); final SerializableChunkData.SectionData sectionData = serializablechunkdata_b; // Paper - starlight - OBFHELPER ++ CompoundTag nbttagcompound1 = new CompoundTag(); final CompoundTag sectionNBT = nbttagcompound1; // Paper - starlight - OBFHELPER + LevelChunkSection chunksection = serializablechunkdata_b.chunkSection; + + if (chunksection != null) { +@@ -526,6 +601,19 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + nbttagcompound1.putByteArray("SkyLight", serializablechunkdata_b.skyLight.getData()); + } + ++ // Paper start - starlight ++ final int blockState = ((ca.spottedleaf.moonrise.patches.starlight.storage.StarlightSectionData)(Object)sectionData).starlight$getBlockLightState(); ++ final int skyState = ((ca.spottedleaf.moonrise.patches.starlight.storage.StarlightSectionData)(Object)sectionData).starlight$getSkyLightState(); ++ ++ if (blockState > 0) { ++ sectionNBT.putInt(ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.BLOCKLIGHT_STATE_TAG, blockState); ++ } ++ ++ if (skyState > 0) { ++ sectionNBT.putInt(ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.SKYLIGHT_STATE_TAG, skyState); ++ } ++ // Paper end - starlight ++ + if (!nbttagcompound1.isEmpty()) { + nbttagcompound1.putByte("Y", (byte) serializablechunkdata_b.y); + nbttaglist.add(nbttagcompound1); +@@ -565,6 +653,14 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + nbttagcompound.put("ChunkBukkitValues", this.persistentDataContainer); + } + // CraftBukkit end ++ // Paper start - starlight ++ if (this.lightCorrect && !this.chunkStatus.isBefore(net.minecraft.world.level.chunk.status.ChunkStatus.LIGHT)) { ++ // clobber vanilla value to force vanilla to relight ++ nbttagcompound.putBoolean("isLightOn", false); ++ // store our light version ++ nbttagcompound.putInt(ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.STARLIGHT_VERSION_TAG, ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.STARLIGHT_LIGHT_VERSION); ++ } ++ // Paper end - starlight + return nbttagcompound; + } + +@@ -744,7 +840,67 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + return nbttaglist; + } + +- public static record SectionData(int y, @Nullable LevelChunkSection chunkSection, @Nullable DataLayer blockLight, @Nullable DataLayer skyLight) { ++ // Paper start - starlight - convert from record ++ public static final class SectionData implements ca.spottedleaf.moonrise.patches.starlight.storage.StarlightSectionData { // Paper - starlight - our diff ++ private final int y; ++ @javax.annotation.Nullable ++ private final net.minecraft.world.level.chunk.LevelChunkSection chunkSection; ++ @javax.annotation.Nullable ++ private final net.minecraft.world.level.chunk.DataLayer blockLight; ++ @javax.annotation.Nullable ++ private final net.minecraft.world.level.chunk.DataLayer skyLight; ++ ++ // Paper start - starlight - our diff ++ private int blockLightState = -1; ++ private int skyLightState = -1; ++ ++ @Override ++ public final int starlight$getBlockLightState() { ++ return this.blockLightState; ++ } ++ ++ @Override ++ public final void starlight$setBlockLightState(final int state) { ++ this.blockLightState = state; ++ } ++ ++ @Override ++ public final int starlight$getSkyLightState() { ++ return this.skyLightState; ++ } ++ ++ @Override ++ public final void starlight$setSkyLightState(final int state) { ++ this.skyLightState = state; ++ } ++ // Paper end - starlight - our diff ++ ++ public SectionData(int y, @javax.annotation.Nullable net.minecraft.world.level.chunk.LevelChunkSection chunkSection, @javax.annotation.Nullable net.minecraft.world.level.chunk.DataLayer blockLight, @javax.annotation.Nullable net.minecraft.world.level.chunk.DataLayer skyLight) { ++ this.y = y; ++ this.chunkSection = chunkSection; ++ this.blockLight = blockLight; ++ this.skyLight = skyLight; ++ } ++ ++ public int y() { ++ return y; ++ } ++ ++ @javax.annotation.Nullable ++ public net.minecraft.world.level.chunk.LevelChunkSection chunkSection() { ++ return chunkSection; ++ } ++ ++ @javax.annotation.Nullable ++ public net.minecraft.world.level.chunk.DataLayer blockLight() { ++ return blockLight; ++ } ++ ++ @javax.annotation.Nullable ++ public net.minecraft.world.level.chunk.DataLayer skyLight() { ++ return skyLight; ++ } ++ // Paper end - starlight - convert from record + + } + diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java index 578d270d5b7efb9ac8f5dde539170f6021e2b786..c5085ebf4e801837010f3750c5e89576bb0c27a5 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java From 3d7b5708efda4037fd5cf937f23c370e3ead7363 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 24 Oct 2024 11:11:56 -0700 Subject: [PATCH 067/119] Implement chunk system --- moonrise_update_1_21_2.txt | 9 - .../0826-Moonrise-optimisation-patches.patch | 463 +++++++++++------- 2 files changed, 291 insertions(+), 181 deletions(-) diff --git a/moonrise_update_1_21_2.txt b/moonrise_update_1_21_2.txt index c1f541edbc34..a44227c478b9 100644 --- a/moonrise_update_1_21_2.txt +++ b/moonrise_update_1_21_2.txt @@ -8,13 +8,4 @@ todo: - in ChunkEntitySlices, implement modifySavedEntities() by copying from old - implement PlayerChunkUnloadEvent in PlatformHooks#onChunkUnWatch - make sure chunk pos is passed in PlatformHooks#postLoadProtoChunk -- implement chunk_system.ChunkMapMixin diff from reference -- implement chunk_system.ChunkStorageMixin diff from reference -- implement chunk_system.DistanceManagerMixin diff from reference -- implement chunk_system.GenerationChunkHolderMixin diff from reference -- implement chunk_system.LevelChunkMixin diff from reference -- implement chunk_system.LevelMixin diff from reference -- implement chunk_system.SectionStorageMixin diff from reference -- implement chunk_system.SerializableChunkDataMixin diff from reference -- implement chunk_system.ServerLevelMixin diff from reference - chunk system: move get entity lookup reroute into the folia scheduler api patch diff --git a/patches/server/0826-Moonrise-optimisation-patches.patch b/patches/server/0826-Moonrise-optimisation-patches.patch index d3b83d533f91..86127997090e 100644 --- a/patches/server/0826-Moonrise-optimisation-patches.patch +++ b/patches/server/0826-Moonrise-optimisation-patches.patch @@ -2781,10 +2781,10 @@ index 0000000000000000000000000000000000000000..0b58701342d573fa43cdd06681534854 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java new file mode 100644 -index 0000000000000000000000000000000000000000..9d46482476f9ed9032a2b0f89afc20e03ed42dbb +index 0000000000000000000000000000000000000000..c278f8ef806f0b45c28cc3040c7db052cb51e053 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java -@@ -0,0 +1,64 @@ +@@ -0,0 +1,62 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level; + +import ca.spottedleaf.concurrentutil.util.Priority; @@ -2813,9 +2813,7 @@ index 0000000000000000000000000000000000000000..9d46482476f9ed9032a2b0f89afc20e0 + + public int moonrise$getRegionChunkShift(); + -+ public boolean moonrise$isMarkedClosing(); -+ -+ public void moonrise$setMarkedClosing(final boolean value); ++ // Paper + + public RegionizedPlayerChunkLoader moonrise$getPlayerChunkLoader(); + @@ -24133,9 +24131,18 @@ index d9ad32acdf46a43a649334a3b736aeb7b3af21d1..fae17a075d7efaf24d916877dd5968eb public static final int RADIUS_AROUND_FULL_CHUNK = FULL_CHUNK_STEP.accumulatedDependencies().getRadius(); public static final int MAX_LEVEL = 33 + RADIUS_AROUND_FULL_CHUNK; diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d550097ec 100644 +index ec19eb88705a07db45f1a3541571fb7f43efb5a9..f0debbe01160a8060f9f8a6e48c8c88f7fbf632b 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +@@ -110,7 +110,7 @@ import org.slf4j.Logger; + import org.bukkit.craftbukkit.generator.CustomChunkGenerator; + // CraftBukkit end + +-public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider, GeneratingChunkMap { ++public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider, GeneratingChunkMap, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemChunkMap { // Paper - rewrite chunk system + + private static final ChunkResult> UNLOADED_CHUNK_LIST_RESULT = ChunkResult.error("Unloaded chunks found in range"); + private static final CompletableFuture>> UNLOADED_CHUNK_LIST_FUTURE = CompletableFuture.completedFuture(ChunkMap.UNLOADED_CHUNK_LIST_RESULT); @@ -125,10 +125,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider public static final int MIN_VIEW_DISTANCE = 2; public static final int MAX_VIEW_DISTANCE = 32; @@ -24175,7 +24182,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback() public final CallbackExecutor callbackExecutor = new CallbackExecutor(); -@@ -178,24 +171,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -178,24 +171,26 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper start public final ChunkHolder getUnloadingChunkHolder(int chunkX, int chunkZ) { @@ -24183,6 +24190,13 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d + return null; // Paper - rewrite chunk system } // Paper end ++ // Paper start - rewrite chunk system ++ @Override ++ public final void moonrise$writeFinishCallback(final ChunkPos pos) throws IOException { ++ // see ChunkStorage#write ++ this.handleLegacyStructureIndex(pos); ++ } ++ // Paper end - rewrite chunk system public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor executor, BlockableEventLoop mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory, int viewDistance, boolean dsync) { super(new RegionStorageInfo(session.getLevelId(), world.dimension(), "chunk"), session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync); @@ -24203,7 +24217,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d Path path = session.getDimensionPath(world.dimension()); this.storageName = path.getFileName().toString(); -@@ -223,14 +211,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -223,18 +218,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.chunkStatusListener = chunkStatusChangeListener; ConsecutiveExecutor consecutiveexecutor1 = new ConsecutiveExecutor(executor, "light"); @@ -24220,7 +24234,12 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d } private void setChunkUnsaved(ChunkPos pos) { -@@ -265,23 +251,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +- this.chunksToEagerlySave.add(pos.toLong()); ++ // Paper - rewrite chunk system + } + + // Paper start +@@ -265,23 +258,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } boolean isChunkTracked(ServerPlayer player, int chunkX, int chunkZ) { @@ -24246,7 +24265,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d } protected ThreadedLevelLightEngine getLightEngine() { -@@ -290,20 +264,22 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -290,20 +271,22 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @Nullable protected ChunkHolder getUpdatingChunkIfPresent(long pos) { @@ -24276,7 +24295,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d } public String getChunkDebugData(ChunkPos chunkPos) { -@@ -332,56 +308,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -332,56 +315,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } private CompletableFuture>> getChunkRangeFuture(ChunkHolder centerChunk, int margin, IntFunction distanceToStatus) { @@ -24334,7 +24353,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d } public ReportedException debugFuturesAndCreateReportedException(IllegalStateException exception, String details) { -@@ -411,49 +338,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -411,104 +345,30 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public CompletableFuture> prepareEntityTickingChunk(ChunkHolder holder) { @@ -24386,7 +24405,10 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d } private void onLevelChange(ChunkPos pos, IntSupplier levelGetter, int targetLevel, IntConsumer levelSetter) { -@@ -463,52 +353,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +- this.worldgenTaskDispatcher.onLevelChange(pos, levelGetter, targetLevel, levelSetter); +- this.lightTaskDispatcher.onLevelChange(pos, levelGetter, targetLevel, levelSetter); ++ throw new UnsupportedOperationException(); // Paper - rewrite chunk system + } @Override public void close() throws IOException { @@ -24445,7 +24467,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d } -@@ -526,143 +380,29 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -526,143 +386,29 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public boolean hasWork() { @@ -24596,7 +24618,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d } private ChunkAccess handleChunkLoadFailure(Throwable throwable, ChunkPos chunkPos) { -@@ -718,139 +458,43 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -718,139 +464,43 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @Override public GenerationChunkHolder acquireGeneration(long pos) { @@ -24745,7 +24767,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d } public int getTickingGenerated() { -@@ -858,144 +502,84 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -858,144 +508,80 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } private boolean saveChunkIfNeeded(ChunkHolder chunkHolder, long currentTime) { @@ -24899,50 +24921,46 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d private static void dropChunk(ServerPlayer player, ChunkPos pos) { - player.connection.chunkSender.dropChunk(player, pos); + // Paper - rewrite chunk system - } - ++ } ++ + // Paper start - rewrite chunk system + @Override + public CompletableFuture> read(final ChunkPos pos) { -+ if (!ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.isRegionFileThread()) { -+ try { -+ return CompletableFuture.completedFuture( -+ Optional.ofNullable( -+ ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.loadData( -+ this.level, pos.x, pos.z, ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.RegionFileType.CHUNK_DATA, -+ ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.getIOBlockingPriorityForCurrentThread() -+ ) -+ ) -+ ); -+ } catch (final Throwable thr) { -+ return CompletableFuture.failedFuture(thr); -+ } -+ } -+ return super.read(pos); ++ final CompletableFuture> ret = new CompletableFuture<>(); ++ ++ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.loadDataAsync( ++ this.level, pos.x, pos.z, ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, ++ (final CompoundTag data, final Throwable thr) -> { ++ if (thr != null) { ++ ret.completeExceptionally(thr); ++ } else { ++ ret.complete(Optional.ofNullable(data)); ++ } ++ }, false ++ ); ++ ++ return ret; + } + + @Override -+ public CompletableFuture write(final ChunkPos pos, final CompoundTag tag) { -+ if (!ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.isRegionFileThread()) { -+ ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.scheduleSave( -+ this.level, pos.x, pos.z, tag, -+ ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.RegionFileType.CHUNK_DATA); -+ return null; -+ } -+ super.write(pos, tag); ++ public CompletableFuture write(final ChunkPos pos, final Supplier tag) { ++ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.scheduleSave( ++ this.level, pos.x, pos.z, tag.get(), ++ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionFileType.CHUNK_DATA ++ ); + return null; -+ } -+ + } + + @Override + public void flushWorker() { -+ ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.flush(); ++ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.flush(this.level); + } + // Paper end - rewrite chunk system + @Nullable public LevelChunk getChunkToSend(long pos) { ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos); -@@ -1061,7 +645,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1061,7 +647,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } // CraftBukkit start @@ -24951,7 +24969,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d return this.upgradeChunkTag(this.level.getTypeKey(), this.overworldDataStorage, nbttagcompound, this.generator().getTypeNameForDataFixer(), chunkcoordintpair, this.level); // CraftBukkit end } -@@ -1071,7 +655,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1071,7 +657,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider while (longiterator.hasNext()) { long i = longiterator.nextLong(); @@ -24960,7 +24978,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d if (playerchunk != null && this.anyPlayerCloseEnoughForSpawningInternal(playerchunk.getPos())) { callback.accept(playerchunk); -@@ -1086,7 +670,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1086,7 +672,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } boolean anyPlayerCloseEnoughForSpawning(ChunkPos chunkcoordintpair, boolean reducedRange) { @@ -24969,7 +24987,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d // Spigot end } -@@ -1104,16 +688,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1104,16 +690,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider //double blockRange = (reducedRange) ? Math.pow(chunkRange << 4, 2) : 16384.0D; // Paper - use from event double blockRange = 16384.0D; // Paper // Spigot end @@ -24998,7 +25016,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d // Paper start - PlayerNaturallySpawnCreaturesEvent com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event; blockRange = 16384.0D; -@@ -1123,33 +711,47 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1123,33 +713,47 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider blockRange = (double) ((event.getSpawnRadius() << 4) * (event.getSpawnRadius() << 4)); } // Paper end - PlayerNaturallySpawnCreaturesEvent @@ -25061,7 +25079,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d if (entityplayer.isSpectator()) { return false; } else { -@@ -1172,19 +774,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1172,19 +776,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.updatePlayerPos(player); if (!flag1) { this.distanceManager.addPlayer(SectionPos.of((EntityAccess) player), player); @@ -25085,7 +25103,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d } } -@@ -1196,17 +800,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1196,17 +802,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void move(ServerPlayer player) { @@ -25104,7 +25122,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d SectionPos sectionposition = player.getLastSectionPos(); SectionPos sectionposition1 = SectionPos.of((EntityAccess) player); -@@ -1216,6 +810,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1216,6 +812,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider if (flag2 || flag != flag1) { this.updatePlayerPos(player); @@ -25112,7 +25130,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d if (!flag) { this.distanceManager.removePlayer(sectionposition, player); } -@@ -1232,70 +827,30 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1232,70 +829,30 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.playerMap.unIgnorePlayer(player); } @@ -25194,7 +25212,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d } public void addEntity(Entity entity) { -@@ -1322,6 +877,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1322,6 +879,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider ChunkMap.TrackedEntity playerchunkmap_entitytracker = new ChunkMap.TrackedEntity(entity, i, j, entitytypes.trackDeltas()); this.entityMap.put(entity.getId(), playerchunkmap_entitytracker); @@ -25207,7 +25225,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d playerchunkmap_entitytracker.updatePlayers(this.level.players()); if (entity instanceof ServerPlayer) { ServerPlayer entityplayer = (ServerPlayer) entity; -@@ -1362,16 +923,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1362,16 +925,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider playerchunkmap_entitytracker1.broadcastRemoved(); } @@ -25251,7 +25269,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d List list = Lists.newArrayList(); List list1 = this.level.players(); -@@ -1478,27 +1061,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1478,27 +1063,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void waitForLightBeforeSending(ChunkPos centerPos, int radius) { @@ -25289,7 +25307,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d } @Nullable -@@ -1514,7 +1095,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1514,7 +1097,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } } @@ -25298,7 +25316,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d public final ServerEntity serverEntity; final Entity entity; -@@ -1522,6 +1103,89 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1522,6 +1105,89 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider SectionPos lastSectionPos; public final Set seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl @@ -25388,7 +25406,7 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d public TrackedEntity(final Entity entity, final int i, final int j, final boolean flag) { this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit this.entity = entity; -@@ -1610,20 +1274,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1610,20 +1276,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } private int getEffectiveRange() { @@ -25424,10 +25442,10 @@ index ec19eb88705a07db45f1a3541571fb7f43efb5a9..885c5e58e785e82f53574d05694bf48d public void updatePlayers(List players) { diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java -index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973bc1b35904 100644 +index f7c2c03749d6be25bf33afd61e1da120770b3432..7a9e7fc688e48d18a6a884f02f768ae652326aae 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java -@@ -34,58 +34,56 @@ import net.minecraft.world.level.ChunkPos; +@@ -34,58 +34,57 @@ import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.chunk.LevelChunk; import org.slf4j.Logger; @@ -25474,7 +25492,8 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973b - while (iterator.hasNext()) { - Ticket ticket = (Ticket) iterator.next(); + // Paper start - rewrite chunk system -+ public ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager getChunkHolderManager() { ++ @Override ++ public final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager moonrise$getChunkHolderManager() { + return ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.moonrise$getChunkMap().level).moonrise$getChunkTaskScheduler().chunkHolderManager; + } + // Paper end - rewrite chunk system @@ -25516,11 +25535,11 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973b + // Paper end - chunk tick iteration optimisation + + protected void purgeStaleTickets() { -+ this.getChunkHolderManager().tick(); // Paper - rewrite chunk system ++ this.moonrise$getChunkHolderManager().tick(); // Paper - rewrite chunk system } -@@ -102,105 +100,15 @@ public abstract class DistanceManager { +@@ -102,105 +101,15 @@ public abstract class DistanceManager { protected abstract ChunkHolder updateChunkScheduling(long pos, int level, @Nullable ChunkHolder holder, int k); public boolean runAllUpdates(ChunkMap chunkLoadingManager) { @@ -25594,7 +25613,7 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973b - - return flag; - } -+ return this.getChunkHolderManager().processTicketUpdates(); // Paper - rewrite chunk system ++ return this.moonrise$getChunkHolderManager().processTicketUpdates(); // Paper - rewrite chunk system } boolean addTicket(long i, Ticket ticket) { // CraftBukkit - void -> boolean @@ -25608,7 +25627,7 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973b - } - - return ticket == ticket1; // CraftBukkit -+ return this.getChunkHolderManager().addTicketAtLevel((TicketType)ticket.getType(), i, ticket.getTicketLevel(), ticket.key); // Paper - rewrite chunk system ++ return this.moonrise$getChunkHolderManager().addTicketAtLevel((TicketType)ticket.getType(), i, ticket.getTicketLevel(), ticket.key); // Paper - rewrite chunk system } boolean removeTicket(long i, Ticket ticket) { // CraftBukkit - void -> boolean @@ -25625,11 +25644,11 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973b - - this.ticketTracker.update(i, DistanceManager.getTicketLevelAt(arraysetsorted), false); - return removed; // CraftBukkit -+ return this.getChunkHolderManager().removeTicketAtLevel((TicketType)ticket.getType(), i, ticket.getTicketLevel(), ticket.key); // Paper - rewrite chunk system ++ return this.moonrise$getChunkHolderManager().removeTicketAtLevel((TicketType)ticket.getType(), i, ticket.getTicketLevel(), ticket.key); // Paper - rewrite chunk system } public void addTicket(TicketType type, ChunkPos pos, int level, T argument) { -@@ -219,13 +127,7 @@ public abstract class DistanceManager { +@@ -219,13 +128,7 @@ public abstract class DistanceManager { } public boolean addRegionTicketAtDistance(TicketType tickettype, ChunkPos chunkcoordintpair, int i, T t0) { @@ -25640,11 +25659,11 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973b - boolean added = this.addTicket(j, ticket); // CraftBukkit - this.tickingTicketsTracker.addTicket(j, ticket); - return added; // CraftBukkit -+ return this.getChunkHolderManager().addTicketAtLevel(tickettype, chunkcoordintpair, ChunkLevel.byStatus(FullChunkStatus.FULL) - i, t0); // Paper - rewrite chunk system ++ return this.moonrise$getChunkHolderManager().addTicketAtLevel(tickettype, chunkcoordintpair, ChunkLevel.byStatus(FullChunkStatus.FULL) - i, t0); // Paper - rewrite chunk system } public void removeRegionTicket(TicketType type, ChunkPos pos, int radius, T argument) { -@@ -234,32 +136,21 @@ public abstract class DistanceManager { +@@ -234,32 +137,21 @@ public abstract class DistanceManager { } public boolean removeRegionTicketAtDistance(TicketType tickettype, ChunkPos chunkcoordintpair, int i, T t0) { @@ -25655,7 +25674,7 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973b - boolean removed = this.removeTicket(j, ticket); // CraftBukkit - this.tickingTicketsTracker.removeTicket(j, ticket); - return removed; // CraftBukkit -+ return this.getChunkHolderManager().removeTicketAtLevel(tickettype, chunkcoordintpair, ChunkLevel.byStatus(FullChunkStatus.FULL) - i, t0); // Paper - rewrite chunk system ++ return this.moonrise$getChunkHolderManager().removeTicketAtLevel(tickettype, chunkcoordintpair, ChunkLevel.byStatus(FullChunkStatus.FULL) - i, t0); // Paper - rewrite chunk system } private SortedArraySet> getTickets(long position) { @@ -25673,17 +25692,17 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973b if (forced) { - this.addTicket(i, ticket); - this.tickingTicketsTracker.addTicket(i, ticket); -+ this.getChunkHolderManager().addTicketAtLevel(TicketType.FORCED, pos, ChunkMap.FORCED_TICKET_LEVEL, pos); ++ this.moonrise$getChunkHolderManager().addTicketAtLevel(TicketType.FORCED, pos, ChunkMap.FORCED_TICKET_LEVEL, pos); } else { - this.removeTicket(i, ticket); - this.tickingTicketsTracker.removeTicket(i, ticket); -+ this.getChunkHolderManager().removeTicketAtLevel(TicketType.FORCED, pos, ChunkMap.FORCED_TICKET_LEVEL, pos); ++ this.moonrise$getChunkHolderManager().removeTicketAtLevel(TicketType.FORCED, pos, ChunkMap.FORCED_TICKET_LEVEL, pos); } + // Paper end - rewrite chunk system } -@@ -270,9 +161,8 @@ public abstract class DistanceManager { +@@ -270,9 +162,8 @@ public abstract class DistanceManager { ((ObjectSet) this.playersPerChunk.computeIfAbsent(i, (j) -> { return new ObjectOpenHashSet(); })).add(player); @@ -25695,7 +25714,7 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973b } public void removePlayer(SectionPos pos, ServerPlayer player) { -@@ -284,160 +174,89 @@ public abstract class DistanceManager { +@@ -284,160 +175,89 @@ 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); @@ -25716,7 +25735,7 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973b public boolean inEntityTickingRange(long chunkPos) { - return ChunkLevel.isEntityTicking(this.tickingTicketsTracker.getLevel(chunkPos)); + // Paper start - rewrite chunk system -+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.getChunkHolderManager().getChunkHolder(chunkPos); ++ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkHolderManager().getChunkHolder(chunkPos); + return chunkHolder != null && chunkHolder.isEntityTickingReady(); + // Paper end - rewrite chunk system } @@ -25724,7 +25743,7 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973b public boolean inBlockTickingRange(long chunkPos) { - return ChunkLevel.isBlockTicking(this.tickingTicketsTracker.getLevel(chunkPos)); + // Paper start - rewrite chunk system -+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.getChunkHolderManager().getChunkHolder(chunkPos); ++ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkHolderManager().getChunkHolder(chunkPos); + return chunkHolder != null && chunkHolder.isTickingReady(); + // Paper end - rewrite chunk system } @@ -25733,7 +25752,7 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973b - SortedArraySet> arraysetsorted = (SortedArraySet) this.tickets.get(pos); - - return arraysetsorted != null && !arraysetsorted.isEmpty() ? ((Ticket) arraysetsorted.first()).toString() : "no_ticket"; -+ return this.getChunkHolderManager().getTicketDebugString(pos); // Paper - rewrite chunk system ++ return this.moonrise$getChunkHolderManager().getTicketDebugString(pos); // Paper - rewrite chunk system } protected void updatePlayerTickets(int viewDistance) { @@ -25873,7 +25892,7 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973b - } - } - } -+ this.getChunkHolderManager().removeAllTicketsFor(ticketType, ticketLevel, ticketIdentifier); // Paper - rewrite chunk system ++ this.moonrise$getChunkHolderManager().removeAllTicketsFor(ticketType, ticketLevel, ticketIdentifier); // Paper - rewrite chunk system } // CraftBukkit end @@ -25881,7 +25900,7 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973b private class ChunkTicketTracker extends ChunkTracker { private static final int MAX_LEVEL = ChunkLevel.MAX_LEVEL + 1; -@@ -483,7 +302,7 @@ public abstract class DistanceManager { +@@ -483,7 +303,7 @@ public abstract class DistanceManager { public int runDistanceUpdates(int distance) { return this.runUpdates(distance); } @@ -25890,7 +25909,7 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973b private class FixedPlayerDistanceChunkTracker extends ChunkTracker { -@@ -563,6 +382,7 @@ public abstract class DistanceManager { +@@ -563,6 +383,7 @@ public abstract class DistanceManager { } } @@ -25898,7 +25917,7 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..31804ddfc2d190c641b8ab477d52973b private class PlayerTicketTracker extends DistanceManager.FixedPlayerDistanceChunkTracker { private int viewDistance = 0; -@@ -657,5 +477,5 @@ public abstract class DistanceManager { +@@ -657,5 +478,5 @@ public abstract class DistanceManager { private boolean haveTicketFor(int distance) { return distance <= this.viewDistance; } @@ -26239,7 +26258,7 @@ index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a } } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..06d0e164363ac8641fad177e0a490bd033be6594 100644 +index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..aea24a874c5d7d0ca40c604e72e07a867ede2482 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -52,7 +52,7 @@ import net.minecraft.world.level.storage.DimensionDataStorage; @@ -26669,6 +26688,15 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..06d0e164363ac8641fad177e0a490bd0 } private void tickChunks(ProfilerFiller profiler, long timeDelta, List chunks) { +@@ -529,7 +601,7 @@ public class ServerChunkCache extends ChunkSource { + NaturalSpawner.spawnForChunk(this.level, chunk, spawnercreature_d, list1); + } + +- if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { ++ if (true) { // Paper - rewrite chunk system + this.level.tickChunk(chunk, k); + } + } @@ -546,11 +618,13 @@ public class ServerChunkCache extends ChunkSource { } @@ -26745,7 +26773,7 @@ index bc0f1aa61e68d2a8638d89c10bc5c71922d057f9..79c88b315481fe70f037bae834f2b072 if (!list.equals(this.lastPassengers)) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21276a41c9 100644 +index 509a67aff07bcdcad47eb77e923d442349a4f20c..e01cbfa395a2ed1056313296fac9c91631e94a01 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -187,7 +187,7 @@ import org.bukkit.event.weather.LightningStrikeEvent; @@ -26783,7 +26811,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 int minBlockX = Mth.floor(axisalignedbb.minX - 1.0E-7D) - 3; int maxBlockX = Mth.floor(axisalignedbb.maxX + 1.0E-7D) + 3; -@@ -295,30 +287,160 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -295,30 +287,159 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe int minChunkZ = minBlockZ >> 4; int maxChunkZ = maxBlockZ >> 4; @@ -26801,7 +26829,6 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 + } + // Paper end - optimise getPlayerByUUID + // Paper start - rewrite chunk system -+ private boolean markedClosing; + private final ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder viewDistanceHolder = new ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder(); + private final ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader chunkLoader = new ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader((ServerLevel)(Object)this); + private final ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.EntityDataController entityDataController; @@ -26839,34 +26866,38 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 + } + return newChunkHolder.getChunkIfPresentUnchecked(leastStatus); + } -+ + +- int requiredChunks = (maxChunkX - minChunkX + 1) * (maxChunkZ - minChunkZ + 1); +- int[] loadedChunks = new int[1]; + @Override + public final void moonrise$midTickTasks() { + ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks(); + } -+ + +- Long holderIdentifier = Long.valueOf(chunkProvider.chunkFutureAwaitCounter++); + @Override + public final ChunkAccess moonrise$syncLoadNonFull(final int chunkX, final int chunkZ, final net.minecraft.world.level.chunk.status.ChunkStatus status) { + return this.moonrise$getChunkTaskScheduler().syncLoadNonFull(chunkX, chunkZ, status); + } -+ + +- java.util.function.Consumer consumer = (net.minecraft.world.level.chunk.ChunkAccess chunk) -> { + @Override + public final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler moonrise$getChunkTaskScheduler() { + return this.chunkTaskScheduler; + } + + @Override -+ public final ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.ChunkDataController moonrise$getChunkDataController() { ++ public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController moonrise$getChunkDataController() { + return this.chunkDataController; + } + + @Override -+ public final ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.ChunkDataController moonrise$getPoiChunkDataController() { ++ public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController moonrise$getPoiChunkDataController() { + return this.poiDataController; + } + + @Override -+ public final ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread.ChunkDataController moonrise$getEntityChunkDataController() { ++ public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController moonrise$getEntityChunkDataController() { + return this.entityDataController; + } + @@ -26882,7 +26913,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 + + @Override + public final void moonrise$loadChunksAsync(final BlockPos pos, final int radiusBlocks, -+ final ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, ++ final ca.spottedleaf.concurrentutil.util.Priority priority, + final java.util.function.Consumer> onLoad) { + this.moonrise$loadChunksAsync( + (pos.getX() - radiusBlocks) >> 4, @@ -26892,12 +26923,10 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 + priority, onLoad + ); + } - -- int requiredChunks = (maxChunkX - minChunkX + 1) * (maxChunkZ - minChunkZ + 1); -- int[] loadedChunks = new int[1]; ++ + @Override + public final void moonrise$loadChunksAsync(final BlockPos pos, final int radiusBlocks, -+ final net.minecraft.world.level.chunk.status.ChunkStatus chunkStatus, final ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, ++ final net.minecraft.world.level.chunk.status.ChunkStatus chunkStatus, final ca.spottedleaf.concurrentutil.util.Priority priority, + final java.util.function.Consumer> onLoad) { + this.moonrise$loadChunksAsync( + (pos.getX() - radiusBlocks) >> 4, @@ -26907,19 +26936,17 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 + chunkStatus, priority, onLoad + ); + } - -- Long holderIdentifier = Long.valueOf(chunkProvider.chunkFutureAwaitCounter++); ++ + @Override + public final void moonrise$loadChunksAsync(final int minChunkX, final int maxChunkX, final int minChunkZ, final int maxChunkZ, -+ final ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, ++ final ca.spottedleaf.concurrentutil.util.Priority priority, + final java.util.function.Consumer> onLoad) { + this.moonrise$loadChunksAsync(minChunkX, maxChunkX, minChunkZ, maxChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, priority, onLoad); + } - -- java.util.function.Consumer consumer = (net.minecraft.world.level.chunk.ChunkAccess chunk) -> { ++ + @Override + public final void moonrise$loadChunksAsync(final int minChunkX, final int maxChunkX, final int minChunkZ, final int maxChunkZ, -+ final net.minecraft.world.level.chunk.status.ChunkStatus chunkStatus, final ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, ++ final net.minecraft.world.level.chunk.status.ChunkStatus chunkStatus, final ca.spottedleaf.concurrentutil.util.Priority priority, + final java.util.function.Consumer> onLoad) { + final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler chunkTaskScheduler = this.moonrise$getChunkTaskScheduler(); + final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager chunkHolderManager = chunkTaskScheduler.chunkHolderManager; @@ -26958,7 +26985,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 } } } -@@ -326,22 +448,122 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -326,22 +447,137 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe for (int cx = minChunkX; cx <= maxChunkX; ++cx) { for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) { @@ -27011,6 +27038,21 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 + public final ca.spottedleaf.moonrise.common.list.ReferenceList moonrise$getEntityTickingChunks() { + return this.entityTickingChunks; + } ++ ++ @Override ++ public final boolean moonrise$areChunksLoaded(final int fromX, final int fromZ, final int toX, final int toZ) { ++ final ServerChunkCache chunkSource = this.chunkSource; ++ ++ for (int currZ = fromZ; currZ <= toZ; ++currZ) { ++ for (int currX = fromX; currX <= toX; ++currX) { ++ if (!chunkSource.hasChunk(currX, currZ)) { ++ return false; ++ } ++ } ++ } ++ ++ return true; ++ } + // Paper end - rewrite chunk system + // Paper start - chunk tick iteration + private static final ServerChunkCache.ChunkAndHolder[] EMPTY_PLAYER_CHUNK_HOLDERS = new ServerChunkCache.ChunkAndHolder[0]; @@ -27091,7 +27133,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 // Add env and gen to constructor, IWorldDataServer -> WorldDataServer public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { -@@ -375,14 +597,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -375,14 +611,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe DataFixer datafixer = minecraftserver.getFixerUpper(); EntityPersistentStorage entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver); @@ -27109,27 +27151,28 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 return minecraftserver.overworld().getDataStorage(); }); this.chunkSource.getGeneratorState().ensureStructuresGenerated(); -@@ -410,6 +631,19 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -410,6 +645,20 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.randomSequences = (RandomSequences) Objects.requireNonNullElseGet(randomsequences, () -> { return (RandomSequences) this.getDataStorage().computeIfAbsent(RandomSequences.factory(l), "random_sequences"); }); + // Paper start - rewrite chunk system ++ this.moonrise$setEntityLookup(new ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup((ServerLevel)(Object)this, ((ServerLevel)(Object)this).new EntityCallbacks())); ++ this.chunkTaskScheduler = new ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler((ServerLevel)(Object)this); + this.entityDataController = new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.EntityDataController( + new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.EntityDataController.EntityRegionFileStorage( + new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), + convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), + minecraftserver.forceSynchronousWrites() -+ ) ++ ), ++ this.chunkTaskScheduler + ); -+ this.poiDataController = new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.PoiDataController((ServerLevel)(Object)this); -+ this.chunkDataController = new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.ChunkDataController((ServerLevel)(Object)this); -+ this.moonrise$setEntityLookup(new ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup((ServerLevel)(Object)this, ((ServerLevel)(Object)this).new EntityCallbacks())); -+ this.chunkTaskScheduler = new ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler((ServerLevel)(Object)this, ca.spottedleaf.moonrise.common.util.MoonriseCommon.WORKER_POOL); ++ this.poiDataController = new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.PoiDataController((ServerLevel)(Object)this, this.chunkTaskScheduler); ++ this.chunkDataController = new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.ChunkDataController((ServerLevel)(Object)this, this.chunkTaskScheduler); + // Paper end - rewrite chunk system this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit } -@@ -542,7 +776,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -542,7 +791,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe gameprofilerfiller.push("checkDespawn"); entity.checkDespawn(); gameprofilerfiller.pop(); @@ -27138,7 +27181,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 Entity entity1 = entity.getVehicle(); if (entity1 != null) { -@@ -567,13 +801,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -567,13 +816,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } gameprofilerfiller.push("entityManagement"); @@ -27157,7 +27200,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 } protected void tickTime() { -@@ -613,7 +850,60 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -613,7 +865,60 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe }); } @@ -27218,7 +27261,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 ChunkPos chunkcoordintpair = chunk.getPos(); boolean flag = this.isRaining(); int j = chunkcoordintpair.getMinBlockX(); -@@ -621,7 +911,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -621,7 +926,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe ProfilerFiller gameprofilerfiller = Profiler.get(); gameprofilerfiller.push("thunder"); @@ -27227,7 +27270,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 BlockPos blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15)); if (this.isRainingAt(blockposition)) { -@@ -653,7 +943,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -653,7 +958,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (!this.paperConfig().environment.disableIceAndSnow) { // Paper - Option to disable ice and snow for (int l = 0; l < randomTickSpeed; ++l) { @@ -27236,7 +27279,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 this.tickPrecipitation(this.getBlockRandomPos(j, 0, k, 15)); } } -@@ -662,35 +952,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -662,35 +967,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe gameprofilerfiller.popPush("tickBlocks"); timings.chunkTicksBlocks.startTiming(); // Paper if (randomTickSpeed > 0) { @@ -27273,7 +27316,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 } timings.chunkTicksBlocks.stopTiming(); // Paper -@@ -964,6 +1226,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -964,6 +1241,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (fluid1.is(fluid)) { fluid1.tick(this, pos, iblockdata); } @@ -27285,7 +27328,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 } -@@ -973,6 +1240,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -973,6 +1255,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (iblockdata.is(block)) { iblockdata.tick(this, pos, this.random); } @@ -27297,7 +27340,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 } -@@ -1049,6 +1321,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1049,6 +1336,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } public void save(@Nullable ProgressListener progressListener, boolean flush, boolean savingDisabled) { @@ -27309,7 +27352,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 ServerChunkCache chunkproviderserver = this.getChunkSource(); if (!savingDisabled) { -@@ -1064,16 +1341,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1064,16 +1356,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } timings.worldSaveChunks.startTiming(); // Paper @@ -27337,7 +27380,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 // CraftBukkit start - moved from MinecraftServer.saveChunks ServerLevel worldserver1 = this; -@@ -1213,7 +1495,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1213,7 +1510,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.removePlayerImmediately((ServerPlayer) entity, Entity.RemovalReason.DISCARDED); } @@ -27346,7 +27389,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 } // CraftBukkit start -@@ -1243,7 +1525,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1243,7 +1540,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } // CraftBukkit end @@ -27355,7 +27398,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 } } -@@ -1254,11 +1536,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1254,11 +1551,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public boolean tryAddFreshEntityWithPassengers(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { // CraftBukkit end @@ -27368,7 +27411,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 return false; } else { this.addFreshEntityWithPassengers(entity, reason); // CraftBukkit -@@ -1891,7 +2169,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1891,7 +2184,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } } @@ -27377,7 +27420,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 bufferedwriter.write(String.format(Locale.ROOT, "block_entity_tickers: %d\n", this.blockEntityTickers.size())); bufferedwriter.write(String.format(Locale.ROOT, "block_ticks: %d\n", this.getBlockTicks().count())); bufferedwriter.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count())); -@@ -1940,7 +2218,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1940,7 +2233,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe BufferedWriter bufferedwriter2 = Files.newBufferedWriter(path1); try { @@ -27386,7 +27429,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 } catch (Throwable throwable4) { if (bufferedwriter2 != null) { try { -@@ -1961,7 +2239,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1961,7 +2254,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe BufferedWriter bufferedwriter3 = Files.newBufferedWriter(path2); try { @@ -27395,7 +27438,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 } catch (Throwable throwable6) { if (bufferedwriter3 != null) { try { -@@ -2103,7 +2381,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2103,7 +2396,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @VisibleForTesting public String getWatchdogStats() { @@ -27404,7 +27447,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString(); }), this.blockEntityTickers.size(), ServerLevel.getTypeCount(this.blockEntityTickers, TickingBlockEntity::getType), this.getBlockTicks().count(), this.getFluidTicks().count(), this.gatherChunkSourceStats()); } -@@ -2133,15 +2411,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2133,15 +2426,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public LevelEntityGetter getEntities() { org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot @@ -27433,7 +27476,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 } public void startTickingChunk(LevelChunk chunk) { -@@ -2161,34 +2449,47 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2161,34 +2464,47 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public void close() throws IOException { super.close(); @@ -27488,7 +27531,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e8010f7eaacd83efc93826b38495fd21 } @Override -@@ -2234,7 +2535,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2234,7 +2550,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report); crashreportsystemdetails.setDetail("Loaded entity count", () -> { @@ -29431,7 +29474,7 @@ index e185a33b5b1f8e8e0a0e666b24ba3e9186a8a7ff..5d7a6e4b73f032db356e7ec369b15001 // Paper start - Affects Spawning API diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72ea9c094d 100644 +index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..0c1d1139a68c06ba056dcfe96284e3e92def0ccc 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -83,6 +83,7 @@ import net.minecraft.world.level.storage.LevelData; @@ -29451,12 +29494,13 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 public static final Codec> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION); public static final ResourceKey OVERWORLD = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld")); -@@ -190,7 +191,584 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -190,7 +191,639 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public abstract ResourceKey getTypeKey(); + // Paper start - rewrite chunk system + private ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup entityLookup; ++ private final ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable chunkData = new ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<>(); + + @Override + public final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup moonrise$getEntityLookup() { @@ -29464,7 +29508,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 + } + + @Override -+ public void moonrise$setEntityLookup(final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup entityLookup) { ++ public final void moonrise$setEntityLookup(final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup entityLookup) { + if (this.entityLookup != null && !(this.entityLookup instanceof ca.spottedleaf.moonrise.patches.chunk_system.level.entity.dfl.DefaultEntityLookup)) { + throw new IllegalStateException("Entity lookup already initialised"); + } @@ -29473,7 +29517,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 + + @Override + public final List getEntitiesOfClass(final Class entityClass, final AABB boundingBox, final Predicate predicate) { -+ this.getProfiler().incrementCounter("getEntities"); ++ Profiler.get().incrementCounter("getEntities"); + final List ret = new java.util.ArrayList<>(); + + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities(entityClass, null, boundingBox, ret, predicate); @@ -29483,7 +29527,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 + + @Override + public final List moonrise$getHardCollidingEntities(final Entity entity, final AABB box, final Predicate predicate) { -+ this.getProfiler().incrementCounter("getEntities"); ++ Profiler.get().incrementCounter("getEntities"); + final List ret = new java.util.ArrayList<>(); + + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getHardCollidingEntities(entity, box, ret, predicate); @@ -29493,7 +29537,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 + + @Override + public LevelChunk moonrise$getFullChunkIfLoaded(final int chunkX, final int chunkZ) { -+ return this.getChunkSource().getChunk(chunkX, chunkZ, false); ++ return (LevelChunk)this.getChunkSource().getChunk(chunkX, chunkZ, ChunkStatus.FULL, false); + } + + @Override @@ -29510,6 +29554,60 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 + public void moonrise$midTickTasks() { + // no-op on ClientLevel + } ++ ++ @Override ++ public final ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData moonrise$getChunkData(final long chunkKey) { ++ return this.chunkData.get(chunkKey); ++ } ++ ++ @Override ++ public final ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData moonrise$getChunkData(final int chunkX, final int chunkZ) { ++ return this.chunkData.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ } ++ ++ @Override ++ public final ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData moonrise$requestChunkData(final long chunkKey) { ++ return this.chunkData.compute(chunkKey, (final long keyInMap, final ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData valueInMap) -> { ++ if (valueInMap == null) { ++ final ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData ret = new ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData(); ++ ret.increaseRef(); ++ return ret; ++ } ++ ++ valueInMap.increaseRef(); ++ return valueInMap; ++ }); ++ } ++ ++ @Override ++ public final ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData moonrise$releaseChunkData(final long chunkKey) { ++ return this.chunkData.compute(chunkKey, (final long keyInMap, final ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData chunkData) -> { ++ return chunkData.decreaseRef() == 0 ? null : chunkData; ++ }); ++ } ++ ++ @Override ++ public boolean moonrise$areChunksLoaded(final int fromX, final int fromZ, final int toX, final int toZ) { ++ final ChunkSource chunkSource = this.getChunkSource(); ++ ++ for (int currZ = fromZ; currZ <= toZ; ++currZ) { ++ for (int currX = fromX; currX <= toX; ++currX) { ++ if (!chunkSource.hasChunk(currX, currZ)) { ++ return false; ++ } ++ } ++ } ++ ++ return true; ++ } ++ ++ @Override ++ public boolean hasChunksAt(final int minBlockX, final int minBlockZ, final int maxBlockX, final int maxBlockZ) { ++ return this.moonrise$areChunksLoaded( ++ minBlockX >> 4, minBlockZ >> 4, maxBlockX >> 4, maxBlockZ >> 4 ++ ); ++ } ++ + /** + * @reason Turn all getChunk(x, z, status) calls into virtual invokes, instead of interface invokes: + * 1. The interface invoke is expensive @@ -30036,7 +30134,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config this.generator = gen; -@@ -271,6 +849,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -271,6 +904,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime); this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); @@ -30048,7 +30146,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 } // Paper start - Cancel hit for vanished players -@@ -535,7 +1118,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -535,7 +1173,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.setBlocksDirty(blockposition, iblockdata1, iblockdata2); } @@ -30057,7 +30155,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 this.sendBlockUpdated(blockposition, iblockdata1, iblockdata, i); } -@@ -800,6 +1383,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -800,6 +1438,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Iterator iterator = this.blockEntityTickers.iterator(); boolean flag = this.tickRateManager().runsNormally(); @@ -30066,7 +30164,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 int tilesThisCycle = 0; var toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet(); // Paper - Fix MC-117075; use removeAll toRemove.add(null); // Paper - Fix MC-117075 -@@ -815,6 +1400,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -815,6 +1455,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Spigot end } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { tickingblockentity.tick(); @@ -30078,7 +30176,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 } } this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 -@@ -837,12 +1427,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -837,12 +1482,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable { entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Paper end - Prevent block entity and entity crashes } @@ -30100,7 +30198,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 } // Paper end - Option to prevent armor stands from doing entity lookups -@@ -894,7 +1492,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -894,7 +1547,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } // Paper end - Perf: Optimize capturedTileEntities lookup // CraftBukkit end @@ -30109,7 +30207,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 } public void setBlockEntity(BlockEntity blockEntity) { -@@ -986,26 +1584,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -986,26 +1639,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable { Profiler.get().incrementCounter("getEntities"); List list = Lists.newArrayList(); @@ -30133,7 +30231,8 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 - } - } - } -- ++ ca.spottedleaf.moonrise.common.PlatformHooks.get().addToGetEntities((Level)(Object)this, except, box, predicate, ret); + - }); - return list; + return ret; @@ -30141,30 +30240,31 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 } @Override -@@ -1020,36 +1605,86 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1020,36 +1662,94 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.getEntities(filter, box, predicate, result, Integer.MAX_VALUE); } - public void getEntities(EntityTypeTest filter, AABB box, Predicate predicate, List result, int limit) { -- Profiler.get().incrementCounter("getEntities"); ++ // Paper start - rewrite chunk system ++ public void getEntities(final EntityTypeTest entityTypeTest, ++ final AABB boundingBox, final Predicate predicate, ++ final List into, final int maxCount) { + Profiler.get().incrementCounter("getEntities"); - this.getEntities().get(filter, box, (entity) -> { - if (predicate.test(entity)) { - result.add(entity); - if (result.size() >= limit) { - return AbortableIterationConsumer.Continuation.ABORT; - } -+ // Paper start - rewrite chunk system -+ public void getEntities(final EntityTypeTest entityTypeTest, -+ final AABB boundingBox, final Predicate predicate, -+ final List into, final int maxCount) { -+ this.getProfiler().incrementCounter("getEntities"); + + if (entityTypeTest instanceof net.minecraft.world.entity.EntityType byType) { + if (maxCount != Integer.MAX_VALUE) { + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities(byType, boundingBox, into, predicate, maxCount); ++ ca.spottedleaf.moonrise.common.PlatformHooks.get().addToGetEntities((Level)(Object)this, entityTypeTest, boundingBox, predicate, into, maxCount); + return; + } else { + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities(byType, boundingBox, into, predicate); ++ ca.spottedleaf.moonrise.common.PlatformHooks.get().addToGetEntities((Level)(Object)this, entityTypeTest, boundingBox, predicate, into, maxCount); + return; } + } @@ -30175,9 +30275,11 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 + if (entityTypeTest == null) { + if (maxCount != Integer.MAX_VALUE) { + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities((Entity)null, boundingBox, (List)into, (Predicate)predicate, maxCount); ++ ca.spottedleaf.moonrise.common.PlatformHooks.get().addToGetEntities((Level)(Object)this, entityTypeTest, boundingBox, predicate, into, maxCount); + return; + } else { + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities((Entity)null, boundingBox, (List)into, (Predicate)predicate); ++ ca.spottedleaf.moonrise.common.PlatformHooks.get().addToGetEntities((Level)(Object)this, entityTypeTest, boundingBox, predicate, into, maxCount); + return; + } + } @@ -30212,22 +30314,28 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 + if (base == null || base == Entity.class) { + if (maxCount != Integer.MAX_VALUE) { + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities((Entity)null, boundingBox, (List)into, (Predicate)modifiedPredicate, maxCount); ++ ca.spottedleaf.moonrise.common.PlatformHooks.get().addToGetEntities((Level)(Object)this, entityTypeTest, boundingBox, predicate, into, maxCount); + return; + } else { + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities((Entity)null, boundingBox, (List)into, (Predicate)modifiedPredicate); ++ ca.spottedleaf.moonrise.common.PlatformHooks.get().addToGetEntities((Level)(Object)this, entityTypeTest, boundingBox, predicate, into, maxCount); + return; + } + } else { + if (maxCount != Integer.MAX_VALUE) { + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities(base, null, boundingBox, (List)into, (Predicate)modifiedPredicate, maxCount); ++ ca.spottedleaf.moonrise.common.PlatformHooks.get().addToGetEntities((Level)(Object)this, entityTypeTest, boundingBox, predicate, into, maxCount); + return; + } else { + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities(base, null, boundingBox, (List)into, (Predicate)modifiedPredicate); ++ ca.spottedleaf.moonrise.common.PlatformHooks.get().addToGetEntities((Level)(Object)this, entityTypeTest, boundingBox, predicate, into, maxCount); + return; -+ } + } + } + } -+ + +- return AbortableIterationConsumer.Continuation.CONTINUE; +- }); + public org.bukkit.entity.Entity[] getChunkEntities(int chunkX, int chunkZ) { + ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices slices = ((ServerLevel)this).moonrise$getEntityLookup().getChunk(chunkX, chunkZ); + if (slices == null) { @@ -30239,11 +30347,9 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..40fe47c7c145587ac81f0f15c237ed72 + org.bukkit.entity.Entity bukkit = entity.getBukkitEntity(); + if (bukkit != null && bukkit.isValid()) { + ret.add(bukkit); - } ++ } + } - -- return AbortableIterationConsumer.Continuation.CONTINUE; -- }); ++ + return ret.toArray(new org.bukkit.entity.Entity[0]); } + // Paper end - rewrite chunk system @@ -31564,7 +31670,7 @@ index 7cce66d4c6efe6fd3cc22a6acf72878c964c61ae..30ee3df2278d0d9bd7478b49eda5fff2 @Override public BlockEntity getBlockEntity(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 7181acfafad91aa5f6ab7ce663d9be4a1b65b02a..a0e51681731dc7b487d5b14ae0d44a881bd5cb09 100644 +index 7181acfafad91aa5f6ab7ce663d9be4a1b65b02a..040a9232c624ee44e95ee4443baf39a670b09296 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -54,7 +54,7 @@ import net.minecraft.world.ticks.LevelChunkTicks; @@ -31701,7 +31807,7 @@ index 7181acfafad91aa5f6ab7ce663d9be4a1b65b02a..a0e51681731dc7b487d5b14ae0d44a88 // Paper start this.loadedTicketLevel = false; // Paper end -@@ -682,8 +733,27 @@ public class LevelChunk extends ChunkAccess { +@@ -682,8 +733,31 @@ public class LevelChunk extends ChunkAccess { @Override public boolean isUnsaved() { @@ -31719,18 +31825,22 @@ index 7181acfafad91aa5f6ab7ce663d9be4a1b65b02a..a0e51681731dc7b487d5b14ae0d44a88 + + // Paper start - rewrite chunk system + @Override -+ public void setUnsaved(final boolean needsSaving) { -+ if (!needsSaving) { -+ ((ca.spottedleaf.moonrise.patches.chunk_system.ticks.ChunkSystemLevelChunkTicks)this.blockTicks).moonrise$clearDirty(); -+ ((ca.spottedleaf.moonrise.patches.chunk_system.ticks.ChunkSystemLevelChunkTicks)this.fluidTicks).moonrise$clearDirty(); ++ public boolean tryMarkSaved() { ++ if (!this.isUnsaved()) { ++ return false; + } -+ super.setUnsaved(needsSaving); ++ ((ca.spottedleaf.moonrise.patches.chunk_system.ticks.ChunkSystemLevelChunkTicks)this.blockTicks).moonrise$clearDirty(); ++ ((ca.spottedleaf.moonrise.patches.chunk_system.ticks.ChunkSystemLevelChunkTicks)this.fluidTicks).moonrise$clearDirty(); ++ ++ super.tryMarkSaved(); ++ ++ return true; } + // Paper end - rewrite chunk system // CraftBukkit end public boolean isEmpty() { -@@ -791,6 +861,7 @@ public class LevelChunk extends ChunkAccess { +@@ -791,6 +865,7 @@ public class LevelChunk extends ChunkAccess { this.pendingBlockEntities.clear(); this.upgradeData.upgrade(this); @@ -32466,7 +32576,7 @@ index f6e08a8334633ff1532616d051bed46b702d0091..4e56398a6fb8b97199f4c74ebebc1055 private final ChunkStatus status; @Nullable diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -index 092f7b6bba4e1291f76c2c09155f33803e93eb04..82b4638d3c5ec11cdb857dc2defd2113caff7965 100644 +index 092f7b6bba4e1291f76c2c09155f33803e93eb04..46f4b6706a1ca24ff6fc28960ad01a067109819f 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java @@ -28,21 +28,31 @@ import net.minecraft.world.level.dimension.LevelStem; @@ -32537,7 +32647,7 @@ index 092f7b6bba4e1291f76c2c09155f33803e93eb04..82b4638d3c5ec11cdb857dc2defd2113 - return this.worker.store(chunkPos, guardedPosCheck); // Paper - guard against possible chunk pos desync + // Paper start - rewrite chunk system + try { -+ this.storage.write(chunkPos, nbt); ++ this.storage.write(chunkPos, guardedPosCheck.get()); + return CompletableFuture.completedFuture(null); + } catch (final Throwable throwable) { + return CompletableFuture.failedFuture(throwable); @@ -33172,7 +33282,7 @@ index 93972352cd4881dccba9b90ccc8dcced3563e340..c3beb7fcad46a917d2b61bd0a0e98e51 static record PackedChunk(Int2ObjectMap sectionsByY, boolean versionChanged) { diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index d7a204216332ccbd6bece23bd507be0366ea4d61..5698e04fd1210eadc9a5091a59bf408a789081fb 100644 +index d7a204216332ccbd6bece23bd507be0366ea4d61..7f1e3d5faa420315b0de63b267d90ccfb855cf04 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java @@ -128,7 +128,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun @@ -33260,6 +33370,15 @@ index d7a204216332ccbd6bece23bd507be0366ea4d61..5698e04fd1210eadc9a5091a59bf408a public ProtoChunk read(ServerLevel world, PoiManager poiStorage, RegionStorageInfo key, ChunkPos expectedPos) { if (!Objects.equals(expectedPos, this.chunkPos)) { SerializableChunkData.LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", new Object[]{expectedPos, expectedPos, this.chunkPos}); +@@ -270,7 +321,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + + if (serializablechunkdata_b.chunkSection != null) { + achunksection[world.getSectionIndexFromSectionY(serializablechunkdata_b.y)] = serializablechunkdata_b.chunkSection; +- poiStorage.checkConsistencyWithBlocks(sectionposition, serializablechunkdata_b.chunkSection); ++ //poiStorage.checkConsistencyWithBlocks(sectionposition, serializablechunkdata_b.chunkSection); // Paper - rewrite chunk system + } + + boolean flag2 = serializablechunkdata_b.blockLight != null; @@ -347,7 +398,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun } @@ -35917,7 +36036,7 @@ index f85e8ec660bf588f694aa96e6e2ade478a9696b7..625f45b50654732231c835df867f9d84 // Paper start - Adventure diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 03cef3e33de1cf2a1ad4c7a5ba9a65ee3b69ee52..570c129cac344d22da903c84e95e37fcc03703e9 100644 +index 03cef3e33de1cf2a1ad4c7a5ba9a65ee3b69ee52..3b81839fa92ecf3846435dd4b7e0dc238b2ab1be 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -458,10 +458,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -35966,7 +36085,7 @@ index 03cef3e33de1cf2a1ad4c7a5ba9a65ee3b69ee52..570c129cac344d22da903c84e95e37fc - } - - return ret.build(); -+ return chunkDistanceManager.getChunkHolderManager().getPluginChunkTickets(x, z); // Paper - rewrite chunk system ++ return chunkDistanceManager.moonrise$getChunkHolderManager().getPluginChunkTickets(x, z); // Paper - rewrite chunk system } @Override @@ -35975,7 +36094,7 @@ index 03cef3e33de1cf2a1ad4c7a5ba9a65ee3b69ee52..570c129cac344d22da903c84e95e37fc DistanceManager chunkDistanceManager = this.world.getChunkSource().chunkMap.distanceManager; - for (Long2ObjectMap.Entry>> chunkTickets : chunkDistanceManager.tickets.long2ObjectEntrySet()) { -+ for (Long2ObjectMap.Entry>> chunkTickets : chunkDistanceManager.getChunkHolderManager().getTicketsCopy().long2ObjectEntrySet()) { // Paper - rewrite chunk system ++ for (Long2ObjectMap.Entry>> chunkTickets : chunkDistanceManager.moonrise$getChunkHolderManager().getTicketsCopy().long2ObjectEntrySet()) { // Paper - rewrite chunk system long chunkKey = chunkTickets.getLongKey(); SortedArraySet> tickets = chunkTickets.getValue(); From 1d341dfda38c58541bd10ae39170d24a8e03d776 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 24 Oct 2024 11:20:51 -0700 Subject: [PATCH 068/119] Fix some compile errors from patches --- patches/server/0823-fixup-MC-Utils.patch | 13 +++++ .../server/0826-fixup-More-Teleport-API.patch | 19 ++++++++ patches/server/0827-fixup-Timings-v2.patch | 18 +++++++ ... 0828-Moonrise-optimisation-patches.patch} | 47 +++++++++---------- 4 files changed, 71 insertions(+), 26 deletions(-) create mode 100644 patches/server/0826-fixup-More-Teleport-API.patch create mode 100644 patches/server/0827-fixup-Timings-v2.patch rename patches/server/{0826-Moonrise-optimisation-patches.patch => 0828-Moonrise-optimisation-patches.patch} (99%) diff --git a/patches/server/0823-fixup-MC-Utils.patch b/patches/server/0823-fixup-MC-Utils.patch index 32b0c1c0ce26..7d2b8ba6e985 100644 --- a/patches/server/0823-fixup-MC-Utils.patch +++ b/patches/server/0823-fixup-MC-Utils.patch @@ -1275,6 +1275,19 @@ index 61893f8216ddaedd899b573322f3ad0088074ac5..36b96e0ed5c0d25068ec4678eddd8a19 } } +diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java +index 509a67aff07bcdcad47eb77e923d442349a4f20c..537a755d097d7713404d83dc47cd17828b15a906 100644 +--- a/src/main/java/net/minecraft/server/level/ServerLevel.java ++++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +@@ -272,7 +272,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + return true; + } + +- public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, ++ public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.util.Priority priority, + java.util.function.Consumer> onLoad) { + if (Thread.currentThread() != this.thread) { + this.getChunkSource().mainThreadProcessor.execute(() -> { diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java index f18c2b85ed9541f646f157184221e333d0ae58bd..aff4c3d63a97d5bbde004a616f7e14fca59b5ab9 100644 --- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java diff --git a/patches/server/0826-fixup-More-Teleport-API.patch b/patches/server/0826-fixup-More-Teleport-API.patch new file mode 100644 index 000000000000..a1918a78df2d --- /dev/null +++ b/patches/server/0826-fixup-More-Teleport-API.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Thu, 24 Oct 2024 11:13:42 -0700 +Subject: [PATCH] fixup! More Teleport API + + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +index f473df7a5aea6a89fb1eed28c9071b7eb3269cf8..4209434ff066670000dadb0c59fea297f03300f4 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +@@ -1020,7 +1020,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { + java.util.concurrent.CompletableFuture 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) -> { ++ this instanceof CraftPlayer ? ca.spottedleaf.concurrentutil.util.Priority.HIGHER : ca.spottedleaf.concurrentutil.util.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()); diff --git a/patches/server/0827-fixup-Timings-v2.patch b/patches/server/0827-fixup-Timings-v2.patch new file mode 100644 index 000000000000..f2b8af09f436 --- /dev/null +++ b/patches/server/0827-fixup-Timings-v2.patch @@ -0,0 +1,18 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Thu, 24 Oct 2024 11:17:10 -0700 +Subject: [PATCH] fixup! Timings v2 + + +diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..350bfa9c891130b1aa2ab973e86668de187ee1e0 100644 +--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java ++++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +@@ -427,7 +427,6 @@ public class ServerChunkCache extends ChunkSource { + gameprofilerfiller.pop(); + this.clearCache(); + } +- if (this.level.getServer().tickRateManager().runsNormally()) this.level.timings.chunkTicks.startTiming(); // Paper + + private void tickChunks() { + long i = this.level.getGameTime(); diff --git a/patches/server/0826-Moonrise-optimisation-patches.patch b/patches/server/0828-Moonrise-optimisation-patches.patch similarity index 99% rename from patches/server/0826-Moonrise-optimisation-patches.patch rename to patches/server/0828-Moonrise-optimisation-patches.patch index 86127997090e..530e6cefdf53 100644 --- a/patches/server/0826-Moonrise-optimisation-patches.patch +++ b/patches/server/0828-Moonrise-optimisation-patches.patch @@ -8241,10 +8241,10 @@ index 0000000000000000000000000000000000000000..a0e5fc2eff605e17704f0726d20e79cb +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java new file mode 100644 -index 0000000000000000000000000000000000000000..120ce31729dc8d4bba0901ca06d3212f3158d089 +index 0000000000000000000000000000000000000000..f3c453773e0413276935ca653b60bbe64fa4b169 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java -@@ -0,0 +1,1037 @@ +@@ -0,0 +1,1036 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; + +import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; @@ -8253,7 +8253,6 @@ index 0000000000000000000000000000000000000000..120ce31729dc8d4bba0901ca06d3212f +import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; +import ca.spottedleaf.concurrentutil.util.Priority; -+import ca.spottedleaf.moonrise.common.config.moonrise.MoonriseConfig; +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +import ca.spottedleaf.moonrise.common.util.JsonUtil; +import ca.spottedleaf.moonrise.common.util.MoonriseCommon; @@ -26258,7 +26257,7 @@ index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a } } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..aea24a874c5d7d0ca40c604e72e07a867ede2482 100644 +index 350bfa9c891130b1aa2ab973e86668de187ee1e0..4b5985c284faac7b06c0f99d53065f5060ecff4a 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -52,7 +52,7 @@ import net.minecraft.world.level.storage.DimensionDataStorage; @@ -26644,7 +26643,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..aea24a874c5d7d0ca40c604e72e07a86 this.tickChunks(); this.level.timings.chunks.stopTiming(); // Paper - timings this.chunkMap.tick(); -@@ -445,7 +502,10 @@ public class ServerChunkCache extends ChunkSource { +@@ -444,7 +501,10 @@ public class ServerChunkCache extends ChunkSource { gameprofilerfiller.push("filteringTickingChunks"); this.collectTickingChunks(list); gameprofilerfiller.popPush("shuffleChunks"); @@ -26656,7 +26655,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..aea24a874c5d7d0ca40c604e72e07a86 this.tickChunks(gameprofilerfiller, j, list); gameprofilerfiller.pop(); } finally { -@@ -478,14 +538,26 @@ public class ServerChunkCache extends ChunkSource { +@@ -477,14 +537,26 @@ public class ServerChunkCache extends ChunkSource { } private void collectTickingChunks(List chunks) { @@ -26688,7 +26687,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..aea24a874c5d7d0ca40c604e72e07a86 } private void tickChunks(ProfilerFiller profiler, long timeDelta, List chunks) { -@@ -529,7 +601,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -528,7 +600,7 @@ public class ServerChunkCache extends ChunkSource { NaturalSpawner.spawnForChunk(this.level, chunk, spawnercreature_d, list1); } @@ -26697,7 +26696,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..aea24a874c5d7d0ca40c604e72e07a86 this.level.tickChunk(chunk, k); } } -@@ -546,11 +618,13 @@ public class ServerChunkCache extends ChunkSource { +@@ -545,11 +617,13 @@ public class ServerChunkCache extends ChunkSource { } private void getFullChunk(long pos, Consumer chunkConsumer) { @@ -26715,7 +26714,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..aea24a874c5d7d0ca40c604e72e07a86 } -@@ -644,6 +718,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -643,6 +717,12 @@ public class ServerChunkCache extends ChunkSource { this.chunkMap.setServerViewDistance(watchDistance); } @@ -26728,7 +26727,7 @@ index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..aea24a874c5d7d0ca40c604e72e07a86 public void setSimulationDistance(int simulationDistance) { this.distanceManager.updateSimulationDistance(simulationDistance); } -@@ -735,21 +815,19 @@ public class ServerChunkCache extends ChunkSource { +@@ -734,21 +814,19 @@ public class ServerChunkCache extends ChunkSource { @Override // CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task public boolean pollTask() { @@ -26773,7 +26772,7 @@ index bc0f1aa61e68d2a8638d89c10bc5c71922d057f9..79c88b315481fe70f037bae834f2b072 if (!list.equals(this.lastPassengers)) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 509a67aff07bcdcad47eb77e923d442349a4f20c..e01cbfa395a2ed1056313296fac9c91631e94a01 100644 +index 537a755d097d7713404d83dc47cd17828b15a906..f657bf73c4d5965dda2490e259aabbf082a0a98e 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -187,7 +187,7 @@ import org.bukkit.event.weather.LightningStrikeEvent; @@ -26796,7 +26795,7 @@ index 509a67aff07bcdcad47eb77e923d442349a4f20c..e01cbfa395a2ed1056313296fac9c916 private final SleepStatus sleepStatus; @@ -274,15 +274,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, + public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.util.Priority priority, java.util.function.Consumer> onLoad) { - if (Thread.currentThread() != this.thread) { - this.getChunkSource().mainThreadProcessor.execute(() -> { @@ -29474,7 +29473,7 @@ index e185a33b5b1f8e8e0a0e666b24ba3e9186a8a7ff..5d7a6e4b73f032db356e7ec369b15001 // Paper start - Affects Spawning API diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..0c1d1139a68c06ba056dcfe96284e3e92def0ccc 100644 +index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..5d4a49d009aee30cd3e83b18ecd5e9399eeb2d56 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -83,6 +83,7 @@ import net.minecraft.world.level.storage.LevelData; @@ -29490,7 +29489,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..0c1d1139a68c06ba056dcfe96284e3e9 // CraftBukkit end -public abstract class Level implements LevelAccessor, AutoCloseable { -+public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel, ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemEntityGetter, ca.spottedleaf.moonrise.patches.collisions.world.CollisionLevel { // Paper - rewrite chunk system // Paper - optimise collisions ++public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel, ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemEntityGetter { // Paper - rewrite chunk system // Paper - optimise collisions public static final Codec> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION); public static final ResourceKey OVERWORLD = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld")); @@ -30134,19 +30133,15 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..0c1d1139a68c06ba056dcfe96284e3e9 this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config this.generator = gen; -@@ -271,6 +904,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -271,6 +904,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime); this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); + this.entityLookup = new ca.spottedleaf.moonrise.patches.chunk_system.level.entity.dfl.DefaultEntityLookup(this); // Paper - rewrite chunk system -+ // Paper start - optimise collisions -+ this.minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(this); -+ this.maxSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection(this); -+ // Paper end - optimise collisions } // Paper start - Cancel hit for vanished players -@@ -535,7 +1173,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -535,7 +1169,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.setBlocksDirty(blockposition, iblockdata1, iblockdata2); } @@ -30155,7 +30150,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..0c1d1139a68c06ba056dcfe96284e3e9 this.sendBlockUpdated(blockposition, iblockdata1, iblockdata, i); } -@@ -800,6 +1438,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -800,6 +1434,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Iterator iterator = this.blockEntityTickers.iterator(); boolean flag = this.tickRateManager().runsNormally(); @@ -30164,7 +30159,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..0c1d1139a68c06ba056dcfe96284e3e9 int tilesThisCycle = 0; var toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet(); // Paper - Fix MC-117075; use removeAll toRemove.add(null); // Paper - Fix MC-117075 -@@ -815,6 +1455,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -815,6 +1451,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Spigot end } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { tickingblockentity.tick(); @@ -30176,7 +30171,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..0c1d1139a68c06ba056dcfe96284e3e9 } } this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 -@@ -837,12 +1482,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -837,12 +1478,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable { entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Paper end - Prevent block entity and entity crashes } @@ -30198,7 +30193,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..0c1d1139a68c06ba056dcfe96284e3e9 } // Paper end - Option to prevent armor stands from doing entity lookups -@@ -894,7 +1547,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -894,7 +1543,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } // Paper end - Perf: Optimize capturedTileEntities lookup // CraftBukkit end @@ -30207,7 +30202,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..0c1d1139a68c06ba056dcfe96284e3e9 } public void setBlockEntity(BlockEntity blockEntity) { -@@ -986,26 +1639,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -986,26 +1635,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable { Profiler.get().incrementCounter("getEntities"); List list = Lists.newArrayList(); @@ -30240,7 +30235,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..0c1d1139a68c06ba056dcfe96284e3e9 } @Override -@@ -1020,36 +1662,94 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1020,36 +1658,94 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.getEntities(filter, box, predicate, result, Integer.MAX_VALUE); } From 6daedd74c9dd477d19209cce6c78551e27beba98 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 24 Oct 2024 11:22:17 -0700 Subject: [PATCH 069/119] Prepare rebase --- ...fixup-ConcurrentUtil.patch => 1821-fixup-ConcurrentUtil.patch} | 0 ...per-config-files.patch => 1822-fixup-Paper-config-files.patch} | 0 .../{0823-fixup-MC-Utils.patch => 1823-fixup-MC-Utils.patch} | 0 ...erter-system.patch => 1824-Rewrite-dataconverter-system.patch} | 0 ...tch => 1825-fixup-Optimize-BlockPosition-helper-methods.patch} | 0 ...More-Teleport-API.patch => 1826-fixup-More-Teleport-API.patch} | 0 .../{0827-fixup-Timings-v2.patch => 1827-fixup-Timings-v2.patch} | 0 ...ion-patches.patch => 1828-Moonrise-optimisation-patches.patch} | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename patches/server/{0821-fixup-ConcurrentUtil.patch => 1821-fixup-ConcurrentUtil.patch} (100%) rename patches/server/{0822-fixup-Paper-config-files.patch => 1822-fixup-Paper-config-files.patch} (100%) rename patches/server/{0823-fixup-MC-Utils.patch => 1823-fixup-MC-Utils.patch} (100%) rename patches/server/{0824-Rewrite-dataconverter-system.patch => 1824-Rewrite-dataconverter-system.patch} (100%) rename patches/server/{0825-fixup-Optimize-BlockPosition-helper-methods.patch => 1825-fixup-Optimize-BlockPosition-helper-methods.patch} (100%) rename patches/server/{0826-fixup-More-Teleport-API.patch => 1826-fixup-More-Teleport-API.patch} (100%) rename patches/server/{0827-fixup-Timings-v2.patch => 1827-fixup-Timings-v2.patch} (100%) rename patches/server/{0828-Moonrise-optimisation-patches.patch => 1828-Moonrise-optimisation-patches.patch} (100%) diff --git a/patches/server/0821-fixup-ConcurrentUtil.patch b/patches/server/1821-fixup-ConcurrentUtil.patch similarity index 100% rename from patches/server/0821-fixup-ConcurrentUtil.patch rename to patches/server/1821-fixup-ConcurrentUtil.patch diff --git a/patches/server/0822-fixup-Paper-config-files.patch b/patches/server/1822-fixup-Paper-config-files.patch similarity index 100% rename from patches/server/0822-fixup-Paper-config-files.patch rename to patches/server/1822-fixup-Paper-config-files.patch diff --git a/patches/server/0823-fixup-MC-Utils.patch b/patches/server/1823-fixup-MC-Utils.patch similarity index 100% rename from patches/server/0823-fixup-MC-Utils.patch rename to patches/server/1823-fixup-MC-Utils.patch diff --git a/patches/server/0824-Rewrite-dataconverter-system.patch b/patches/server/1824-Rewrite-dataconverter-system.patch similarity index 100% rename from patches/server/0824-Rewrite-dataconverter-system.patch rename to patches/server/1824-Rewrite-dataconverter-system.patch diff --git a/patches/server/0825-fixup-Optimize-BlockPosition-helper-methods.patch b/patches/server/1825-fixup-Optimize-BlockPosition-helper-methods.patch similarity index 100% rename from patches/server/0825-fixup-Optimize-BlockPosition-helper-methods.patch rename to patches/server/1825-fixup-Optimize-BlockPosition-helper-methods.patch diff --git a/patches/server/0826-fixup-More-Teleport-API.patch b/patches/server/1826-fixup-More-Teleport-API.patch similarity index 100% rename from patches/server/0826-fixup-More-Teleport-API.patch rename to patches/server/1826-fixup-More-Teleport-API.patch diff --git a/patches/server/0827-fixup-Timings-v2.patch b/patches/server/1827-fixup-Timings-v2.patch similarity index 100% rename from patches/server/0827-fixup-Timings-v2.patch rename to patches/server/1827-fixup-Timings-v2.patch diff --git a/patches/server/0828-Moonrise-optimisation-patches.patch b/patches/server/1828-Moonrise-optimisation-patches.patch similarity index 100% rename from patches/server/0828-Moonrise-optimisation-patches.patch rename to patches/server/1828-Moonrise-optimisation-patches.patch From 75e3409cec7315a081928a237c73ffee3eb4e050 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 24 Oct 2024 11:51:29 -0700 Subject: [PATCH 070/119] Complete rebase, start review --- moonrise_update_1_21_2.txt | 6 +- ....patch => 0973-fixup-ConcurrentUtil.patch} | 0 ...ch => 0974-fixup-Paper-config-files.patch} | 8 +- ...-Utils.patch => 0975-fixup-MC-Utils.patch} | 6 +- ...> 0976-Rewrite-dataconverter-system.patch} | 6 +- ...timize-BlockPosition-helper-methods.patch} | 0 ...tch => 0978-fixup-More-Teleport-API.patch} | 4 +- ...s-v2.patch => 0979-fixup-Timings-v2.patch} | 0 ... 0980-Moonrise-optimisation-patches.patch} | 237 ++++++++++-------- 9 files changed, 139 insertions(+), 128 deletions(-) rename patches/server/{1821-fixup-ConcurrentUtil.patch => 0973-fixup-ConcurrentUtil.patch} (100%) rename patches/server/{1822-fixup-Paper-config-files.patch => 0974-fixup-Paper-config-files.patch} (92%) rename patches/server/{1823-fixup-MC-Utils.patch => 0975-fixup-MC-Utils.patch} (99%) rename patches/server/{1824-Rewrite-dataconverter-system.patch => 0976-Rewrite-dataconverter-system.patch} (99%) rename patches/server/{1825-fixup-Optimize-BlockPosition-helper-methods.patch => 0977-fixup-Optimize-BlockPosition-helper-methods.patch} (100%) rename patches/server/{1826-fixup-More-Teleport-API.patch => 0978-fixup-More-Teleport-API.patch} (90%) rename patches/server/{1827-fixup-Timings-v2.patch => 0979-fixup-Timings-v2.patch} (100%) rename patches/server/{1828-Moonrise-optimisation-patches.patch => 0980-Moonrise-optimisation-patches.patch} (99%) diff --git a/moonrise_update_1_21_2.txt b/moonrise_update_1_21_2.txt index a44227c478b9..3ecdcaf3b337 100644 --- a/moonrise_update_1_21_2.txt +++ b/moonrise_update_1_21_2.txt @@ -1,11 +1,7 @@ reference comparison: https://github.com/Tuinity/Moonrise/compare/6a2c6d27df11d417c1fefa749109d8e87599e8c2...f22335f0b65e205831c74a7b4b8f4d93fff54fd5 -need to compare the diffs todo: -- double check that the misc changes commit on dev/1.21.2 moonrise is applied +- need to compare the diffs - in ChunkEntitySlices, implement modifySavedEntities() by copying from old -- implement PlayerChunkUnloadEvent in PlatformHooks#onChunkUnWatch -- make sure chunk pos is passed in PlatformHooks#postLoadProtoChunk -- chunk system: move get entity lookup reroute into the folia scheduler api patch diff --git a/patches/server/1821-fixup-ConcurrentUtil.patch b/patches/server/0973-fixup-ConcurrentUtil.patch similarity index 100% rename from patches/server/1821-fixup-ConcurrentUtil.patch rename to patches/server/0973-fixup-ConcurrentUtil.patch diff --git a/patches/server/1822-fixup-Paper-config-files.patch b/patches/server/0974-fixup-Paper-config-files.patch similarity index 92% rename from patches/server/1822-fixup-Paper-config-files.patch rename to patches/server/0974-fixup-Paper-config-files.patch index cdf7e80f80c6..a40bcad94711 100644 --- a/patches/server/1822-fixup-Paper-config-files.patch +++ b/patches/server/0974-fixup-Paper-config-files.patch @@ -5,10 +5,10 @@ Subject: [PATCH] fixup! Paper config files diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 73e8a524925ed6f2580d3bd01616646fabafda78..61893f8216ddaedd899b573322f3ad0088074ac5 100644 +index 450a1cc8f1624dce2daf52210d017e0732b1bdf7..4954ed9edf1e1f54cc164e48817eb5b75ea87ce0 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -30,6 +30,45 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -31,6 +31,45 @@ public class GlobalConfiguration extends ConfigurationPart { public static GlobalConfiguration get() { return instance; } @@ -54,7 +54,7 @@ index 73e8a524925ed6f2580d3bd01616646fabafda78..61893f8216ddaedd899b573322f3ad00 static void set(GlobalConfiguration instance) { GlobalConfiguration.instance = instance; } -@@ -145,21 +184,6 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -146,21 +185,6 @@ public class GlobalConfiguration extends ConfigurationPart { public int incomingPacketThreshold = 300; } @@ -76,7 +76,7 @@ index 73e8a524925ed6f2580d3bd01616646fabafda78..61893f8216ddaedd899b573322f3ad00 public UnsupportedSettings unsupportedSettings; public class UnsupportedSettings extends ConfigurationPart { -@@ -218,7 +242,7 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -219,7 +243,7 @@ public class GlobalConfiguration extends ConfigurationPart { @PostProcess private void postProcess() { diff --git a/patches/server/1823-fixup-MC-Utils.patch b/patches/server/0975-fixup-MC-Utils.patch similarity index 99% rename from patches/server/1823-fixup-MC-Utils.patch rename to patches/server/0975-fixup-MC-Utils.patch index 7d2b8ba6e985..269928078799 100644 --- a/patches/server/1823-fixup-MC-Utils.patch +++ b/patches/server/0975-fixup-MC-Utils.patch @@ -1263,10 +1263,10 @@ index 0000000000000000000000000000000000000000..1aa6be257ce594d7a69fdff008cd2901 + } +} diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 61893f8216ddaedd899b573322f3ad0088074ac5..36b96e0ed5c0d25068ec4678eddd8a19a020d345 100644 +index 4954ed9edf1e1f54cc164e48817eb5b75ea87ce0..8a0cb603cd4dbfa1839e0f4e1606876cbb373277 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -242,7 +242,7 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -243,7 +243,7 @@ public class GlobalConfiguration extends ConfigurationPart { @PostProcess private void postProcess() { @@ -1276,7 +1276,7 @@ index 61893f8216ddaedd899b573322f3ad0088074ac5..36b96e0ed5c0d25068ec4678eddd8a19 } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 509a67aff07bcdcad47eb77e923d442349a4f20c..537a755d097d7713404d83dc47cd17828b15a906 100644 +index 2aa4437a76d29cdd793680734a36a41c6133ab91..0cf4f9d60337cfe89075a79eabfd182cdec91695 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -272,7 +272,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/1824-Rewrite-dataconverter-system.patch b/patches/server/0976-Rewrite-dataconverter-system.patch similarity index 99% rename from patches/server/1824-Rewrite-dataconverter-system.patch rename to patches/server/0976-Rewrite-dataconverter-system.patch index 21a091394df8..90d6b4c94707 100644 --- a/patches/server/1824-Rewrite-dataconverter-system.patch +++ b/patches/server/0976-Rewrite-dataconverter-system.patch @@ -30384,10 +30384,10 @@ index b54a3741cd3ba615c83c98985cb4b3c4c586ed7a..b148cf247acdd36f856d0495cde4cc5a return nbttagcompound; }); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index a5a3a0f0460252415c243dfe3019d103b9589c5b..e44ae64ef7cddbcee8c2f37e6606b2257c16bf65 100644 +index b24ccbff89db873f5bdf62cbebcca0049b94a8d5..1cda41b104935743cb18e19acca24ad0a1673bb6 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -490,7 +490,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -511,7 +511,7 @@ public final class CraftMagicNumbers implements UnsafeValues { net.minecraft.nbt.CompoundTag compound = deserializeNbtFromBytes(data); final int dataVersion = compound.getInt("DataVersion"); @@ -30396,7 +30396,7 @@ index a5a3a0f0460252415c243dfe3019d103b9589c5b..e44ae64ef7cddbcee8c2f37e6606b225 return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(MinecraftServer.getServer().registryAccess(), compound).orElseThrow()); } -@@ -511,7 +511,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -532,7 +532,7 @@ public final class CraftMagicNumbers implements UnsafeValues { net.minecraft.nbt.CompoundTag compound = deserializeNbtFromBytes(data); int dataVersion = compound.getInt("DataVersion"); diff --git a/patches/server/1825-fixup-Optimize-BlockPosition-helper-methods.patch b/patches/server/0977-fixup-Optimize-BlockPosition-helper-methods.patch similarity index 100% rename from patches/server/1825-fixup-Optimize-BlockPosition-helper-methods.patch rename to patches/server/0977-fixup-Optimize-BlockPosition-helper-methods.patch diff --git a/patches/server/1826-fixup-More-Teleport-API.patch b/patches/server/0978-fixup-More-Teleport-API.patch similarity index 90% rename from patches/server/1826-fixup-More-Teleport-API.patch rename to patches/server/0978-fixup-More-Teleport-API.patch index a1918a78df2d..f3e4c5eea5c7 100644 --- a/patches/server/1826-fixup-More-Teleport-API.patch +++ b/patches/server/0978-fixup-More-Teleport-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] fixup! More Teleport API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index f473df7a5aea6a89fb1eed28c9071b7eb3269cf8..4209434ff066670000dadb0c59fea297f03300f4 100644 +index c1d3dd2bd217efd6914bceb1027fa12b06c22a55..7536ab5c22d97a074c08a95fff6bc756d61e387d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1020,7 +1020,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1060,7 +1060,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { java.util.concurrent.CompletableFuture ret = new java.util.concurrent.CompletableFuture<>(); world.loadChunksForMoveAsync(getHandle().getBoundingBoxAt(locationClone.getX(), locationClone.getY(), locationClone.getZ()), diff --git a/patches/server/1827-fixup-Timings-v2.patch b/patches/server/0979-fixup-Timings-v2.patch similarity index 100% rename from patches/server/1827-fixup-Timings-v2.patch rename to patches/server/0979-fixup-Timings-v2.patch diff --git a/patches/server/1828-Moonrise-optimisation-patches.patch b/patches/server/0980-Moonrise-optimisation-patches.patch similarity index 99% rename from patches/server/1828-Moonrise-optimisation-patches.patch rename to patches/server/0980-Moonrise-optimisation-patches.patch index 530e6cefdf53..c9f3fac9b9f5 100644 --- a/patches/server/1828-Moonrise-optimisation-patches.patch +++ b/patches/server/0980-Moonrise-optimisation-patches.patch @@ -5538,10 +5538,10 @@ index 0000000000000000000000000000000000000000..003a857e70ead858e8437e3c1bfaf22f +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java new file mode 100644 -index 0000000000000000000000000000000000000000..b2fa9883aefb07f64bb5db7e0052218d2ad09aba +index 0000000000000000000000000000000000000000..5a6defc4c4d30c06d4bba856847feb176950ca1e --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -@@ -0,0 +1,1085 @@ +@@ -0,0 +1,1090 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.player; + +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; @@ -5981,6 +5981,11 @@ index 0000000000000000000000000000000000000000..b2fa9883aefb07f64bb5db7e0052218d + ((ChunkSystemChunkHolder)((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager + .getChunkHolder(chunkX, chunkZ).vanillaChunkHolder).moonrise$removeReceivedChunk(this.player); + this.player.connection.send(new ClientboundForgetLevelChunkPacket(new ChunkPos(chunkX, chunkZ))); ++ // Paper start - PlayerChunkUnloadEvent ++ if (io.papermc.paper.event.packet.PlayerChunkUnloadEvent.getHandlerList().getRegisteredListeners().length > 0) { ++ new io.papermc.paper.event.packet.PlayerChunkUnloadEvent(player.getBukkitEntity().getWorld().getChunkAt(new ChunkPos(chunkX, chunkZ).longKey), player.getBukkitEntity()).callEvent(); ++ } ++ // Paper end - PlayerChunkUnloadEvent + } + + private final SingleUserAreaMap broadcastMap = new SingleUserAreaMap<>(this) { @@ -23184,10 +23189,10 @@ index 0000000000000000000000000000000000000000..85950a1aa732ab8c01ad28bec9e0de14 + } +} diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 36b96e0ed5c0d25068ec4678eddd8a19a020d345..b59613e3d97a9ca7d11bda28508021a5e9a9e92f 100644 +index 8a0cb603cd4dbfa1839e0f4e1606876cbb373277..e4df6312fc676ab2d573f060b007e0442d60a6a9 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -243,6 +243,23 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -244,6 +244,23 @@ public class GlobalConfiguration extends ConfigurationPart { @PostProcess private void postProcess() { ca.spottedleaf.moonrise.common.util.MoonriseCommon.adjustWorkerThreads(this.workerThreads, this.ioThreads); @@ -23381,7 +23386,7 @@ index fc6ce3485dc890f5105a37fe3e344a1460867556..e114e687f2f4503546687fd6792226a6 DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, worldLoader.get(), thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), services, LoggerChunkProgressListener::createFromGameruleRadius); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 53c9be615a0f2939cd989e24e304e81e6e27f39d..8a66012b7f2396031840c8c718f49f8aab716ee0 100644 +index 21660e4284cfabb333a3edf9224c892ef80b2403..a73e4aaee436405caf88ac0ebe3ed7451310247c 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -205,7 +205,7 @@ import org.bukkit.event.server.ServerLoadEvent; @@ -23480,7 +23485,7 @@ index 53c9be615a0f2939cd989e24e304e81e6e27f39d..8a66012b7f2396031840c8c718f49f8a public MinecraftServer(OptionSet options, WorldLoader.DataLoadContext worldLoader, Thread thread, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PackRepository resourcepackrepository, WorldStem worldstem, Proxy proxy, DataFixer datafixer, Services services, ChunkProgressListenerFactory worldloadlistenerfactory) { super("Server"); SERVER = this; // Paper - better singleton -@@ -673,7 +744,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { return false; } : this::haveTime); @@ -23569,7 +23574,7 @@ index 53c9be615a0f2939cd989e24e304e81e6e27f39d..8a66012b7f2396031840c8c718f49f8a this.tickFrame.end(); gameprofilerfiller.popPush("nextTickWait"); this.mayHaveDelayedTasks = true; -@@ -1428,6 +1507,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop getEntities() { org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot @@ -27475,7 +27480,7 @@ index 537a755d097d7713404d83dc47cd17828b15a906..f657bf73c4d5965dda2490e259aabbf0 } public void startTickingChunk(LevelChunk chunk) { -@@ -2161,34 +2464,47 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2184,34 +2487,47 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public void close() throws IOException { super.close(); @@ -27530,7 +27535,7 @@ index 537a755d097d7713404d83dc47cd17828b15a906..f657bf73c4d5965dda2490e259aabbf0 } @Override -@@ -2234,7 +2550,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2267,7 +2583,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report); crashreportsystemdetails.setDetail("Loaded entity count", () -> { @@ -27540,7 +27545,7 @@ index 537a755d097d7713404d83dc47cd17828b15a906..f657bf73c4d5965dda2490e259aabbf0 return crashreportsystemdetails; } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 1a7d2ade0e85dd5e6cd6c9202e3277cc2fa43d4a..ba15c34a3ea516d2d946d923551293ac05118926 100644 +index 52b18f2c333b7535929bb4e52e65cf5fb0f5692f..cff36fc36829194c7fe5991f2a55d23ad18017a6 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -218,7 +218,7 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; @@ -27980,7 +27985,7 @@ index eba83b085435150e5954fd5d41dda9ce1d0601ad..daf543b51d8875b374688957ae4bc466 } } diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java -index 2e72e92762877b28dd908711671e1dfb933de9b0..a1bfd9d9bf992c5516290ca9aabe12ab037faa18 100644 +index b7d29389a357f142237cecd75f8ca91cf1eb6b5b..e4b0dc3121101d54394a0c3a413dabf8103b2ea6 100644 --- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java +++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java @@ -85,6 +85,36 @@ public class WorldGenRegion implements WorldGenLevel { @@ -28034,10 +28039,10 @@ index cdd66e6ce96e2613afe7f06ca8da3cfaa6704b2d..32634e45ac8433648e49e47e20081e15 // Paper start - PlayerChunkLoadEvent if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 4fe3024e26b56c2d796acf703a1bc200ff309f09..7529b3d90e65036c7bf869af30475932d547b3ab 100644 +index a4937d11b79cef41f3fbf79282c0c435e794dbfe..be7f437a8d2bf1d5c2314848cbf9379c5cf25fde 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1407,7 +1407,7 @@ public abstract class PlayerList { +@@ -1416,7 +1416,7 @@ public abstract class PlayerList { public void setViewDistance(int viewDistance) { this.viewDistance = viewDistance; @@ -28424,7 +28429,7 @@ index 50040c497a819cd1229042ab3cb057d34a32cacc..1f9c436a632e4f110be61cf76fcfc3b7 + // Paper end - block counting } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 8cdef637f6343119fc77f87e7478ee23e9b8efab..a3b0363fbc207ed9edc8a4d6619b6fff9389a9c7 100644 +index 3d4bb855dec45685d6e336d913903341f0ca4a11..4e005543cba9cfad6aeb39094cb856f5406c585a 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -175,7 +175,7 @@ import org.bukkit.event.player.PlayerTeleportEvent; @@ -28436,7 +28441,7 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..a3b0363fbc207ed9edc8a4d6619b6fff // CraftBukkit start private static final int CURRENT_LEVEL = 2; -@@ -445,6 +445,156 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -457,6 +457,156 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this.dimensions.makeBoundingBox(x, y, z); } // Paper end @@ -28593,7 +28598,7 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..a3b0363fbc207ed9edc8a4d6619b6fff public Entity(EntityType type, Level world) { this.id = Entity.ENTITY_COUNTER.incrementAndGet(); -@@ -1303,41 +1453,76 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1320,41 +1470,76 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } private Vec3 collide(Vec3 movement) { @@ -28698,7 +28703,7 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..a3b0363fbc207ed9edc8a4d6619b6fff } private static float[] collectCandidateStepUpHeights(AABB collisionBox, List collisions, float f, float stepHeight) { -@@ -2699,18 +2884,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2742,18 +2927,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public boolean isInWall() { @@ -28816,7 +28821,7 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..a3b0363fbc207ed9edc8a4d6619b6fff } public InteractionResult interact(Player player, InteractionHand hand) { -@@ -4180,14 +4457,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4224,14 +4501,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public Iterable getIndirectPassengers() { @@ -28841,7 +28846,7 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..a3b0363fbc207ed9edc8a4d6619b6fff } private Iterable getIndirectPassengers_old() { // Paper end - Optimize indirect passenger iteration -@@ -4316,82 +4596,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4360,82 +4640,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return Mth.lerp(delta, this.yRotO, this.yRot); } @@ -29036,7 +29041,7 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..a3b0363fbc207ed9edc8a4d6619b6fff public boolean touchingUnloadedChunk() { AABB axisalignedbb = this.getBoundingBox().inflate(1.0D); -@@ -4543,6 +4877,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4587,6 +4921,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.setPosRaw(x, y, z, false); } public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) { @@ -29052,7 +29057,7 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..a3b0363fbc207ed9edc8a4d6619b6fff if (!checkPosition(this, x, y, z)) { return; } -@@ -4672,6 +5015,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4716,6 +5059,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public final void setRemoved(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { @@ -29064,8 +29069,8 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..a3b0363fbc207ed9edc8a4d6619b6fff + // Paper end - rewrite chunk system CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit end - if (this.removalReason == null) { -@@ -4682,7 +5031,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers +@@ -4727,7 +5076,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.stopRiding(); } @@ -29073,8 +29078,8 @@ index 8cdef637f6343119fc77f87e7478ee23e9b8efab..a3b0363fbc207ed9edc8a4d6619b6fff + if (this.removalReason != Entity.RemovalReason.UNLOADED_TO_CHUNK) { this.getPassengers().forEach(Entity::stopRiding); } // Paper - rewrite chunk system this.levelCallback.onRemove(entity_removalreason); this.onRemoval(entity_removalreason); - } -@@ -4698,7 +5047,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + // Paper start - Folia schedulers +@@ -4759,7 +5108,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public boolean shouldBeSaved() { @@ -29323,7 +29328,7 @@ index b9e0bc8f1e948614d986335de1f3d2df199eea81..712cbfc100e8aaf612d1d651dae64f57 this(updateListener, true, ImmutableList.of()); } diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -index 2bb2b36f793d25b6e49d1a72bb665cfa9f212730..1362c33ca9ec524372b03c890385888ca6cfe2b0 100644 +index 63f02cdc67d9e88cc6998d0ae9d139c83e85b447..70b8023c3badc745f342d5b0ab54699e3923826a 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java @@ -364,7 +364,7 @@ public class ArmorStand extends LivingEntity { @@ -29473,7 +29478,7 @@ index e185a33b5b1f8e8e0a0e666b24ba3e9186a8a7ff..5d7a6e4b73f032db356e7ec369b15001 // Paper start - Affects Spawning API diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..5d4a49d009aee30cd3e83b18ecd5e9399eeb2d56 100644 +index 1b899473c6deeaa1aef9007d8b7bcec98580e61c..1f4ff796a1f69b9c60d32d407b5579e89433089c 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -83,6 +83,7 @@ import net.minecraft.world.level.storage.LevelData; @@ -29493,7 +29498,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..5d4a49d009aee30cd3e83b18ecd5e939 public static final Codec> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION); public static final ResourceKey OVERWORLD = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld")); -@@ -190,7 +191,639 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -200,7 +201,639 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public abstract ResourceKey getTypeKey(); @@ -30133,7 +30138,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..5d4a49d009aee30cd3e83b18ecd5e939 this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config this.generator = gen; -@@ -271,6 +904,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -281,6 +914,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime); this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); @@ -30141,7 +30146,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..5d4a49d009aee30cd3e83b18ecd5e939 } // Paper start - Cancel hit for vanished players -@@ -535,7 +1169,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -549,7 +1183,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.setBlocksDirty(blockposition, iblockdata1, iblockdata2); } @@ -30150,7 +30155,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..5d4a49d009aee30cd3e83b18ecd5e939 this.sendBlockUpdated(blockposition, iblockdata1, iblockdata, i); } -@@ -800,6 +1434,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -815,6 +1449,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Iterator iterator = this.blockEntityTickers.iterator(); boolean flag = this.tickRateManager().runsNormally(); @@ -30159,7 +30164,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..5d4a49d009aee30cd3e83b18ecd5e939 int tilesThisCycle = 0; var toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet(); // Paper - Fix MC-117075; use removeAll toRemove.add(null); // Paper - Fix MC-117075 -@@ -815,6 +1451,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -830,6 +1466,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Spigot end } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { tickingblockentity.tick(); @@ -30171,7 +30176,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..5d4a49d009aee30cd3e83b18ecd5e939 } } this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 -@@ -837,12 +1478,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -852,12 +1493,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable { entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Paper end - Prevent block entity and entity crashes } @@ -30193,7 +30198,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..5d4a49d009aee30cd3e83b18ecd5e939 } // Paper end - Option to prevent armor stands from doing entity lookups -@@ -894,7 +1543,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -909,7 +1558,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } // Paper end - Perf: Optimize capturedTileEntities lookup // CraftBukkit end @@ -30202,7 +30207,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..5d4a49d009aee30cd3e83b18ecd5e939 } public void setBlockEntity(BlockEntity blockEntity) { -@@ -986,26 +1635,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1001,26 +1650,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable { Profiler.get().incrementCounter("getEntities"); List list = Lists.newArrayList(); @@ -30235,7 +30240,7 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..5d4a49d009aee30cd3e83b18ecd5e939 } @Override -@@ -1020,36 +1658,94 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1035,36 +1673,94 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.getEntities(filter, box, predicate, result, Integer.MAX_VALUE); } @@ -30376,7 +30381,7 @@ index 5eb8982678110fabb82a93c5ec67c666b7fde017..ade435de0af4ee3566fa4a490df53cdd ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create); diff --git a/src/main/java/net/minecraft/world/level/ServerExplosion.java b/src/main/java/net/minecraft/world/level/ServerExplosion.java -index 86656de31b1e33381eddd3ef210122118b31e620..c7fd8ce0dae838d91915a1c7a34152bed3ac7682 100644 +index fd1ecedfab037e377e4dded61539689bacc90f80..bbbd451ff184be8fa13bd93d53c89a9502f9951a 100644 --- a/src/main/java/net/minecraft/world/level/ServerExplosion.java +++ b/src/main/java/net/minecraft/world/level/ServerExplosion.java @@ -64,6 +64,249 @@ public class ServerExplosion implements Explosion { @@ -30629,7 +30634,7 @@ index 86656de31b1e33381eddd3ef210122118b31e620..c7fd8ce0dae838d91915a1c7a34152be public ServerExplosion(ServerLevel world, @Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, Vec3 pos, float power, boolean createFire, Explosion.BlockInteraction destructionType) { this.level = world; -@@ -127,64 +370,91 @@ public class ServerExplosion implements Explosion { +@@ -127,65 +370,101 @@ public class ServerExplosion implements Explosion { } private List calculateExplodedPositions() { @@ -30656,6 +30661,7 @@ index 86656de31b1e33381eddd3ef210122118b31e620..c7fd8ce0dae838d91915a1c7a34152be - for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) { - BlockPos blockposition = BlockPos.containing(d4, d5, d6); - BlockState iblockdata = this.level.getBlockState(blockposition); +- if (!iblockdata.isDestroyable()) continue; // Paper - Protect Bedrock and End Portal/Frames from being destroyed - FluidState fluid = iblockdata.getFluidState(); // Paper - Perf: Optimize call to getFluid for explosions - - if (!this.level.isInWorldBounds(blockposition)) { @@ -30681,9 +30687,6 @@ index 86656de31b1e33381eddd3ef210122118b31e620..c7fd8ce0dae838d91915a1c7a34152be - net.minecraft.core.Direction direction = iblockdata.getValue(net.minecraft.world.level.block.piston.PistonHeadBlock.FACING); - set.add(blockposition.relative(direction.getOpposite())); - } -- } -- // Paper end - prevent headless pistons from forming -- } + // use initial cache value that is most likely to be used: the source position + final ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache initialCache; + { @@ -30695,10 +30698,7 @@ index 86656de31b1e33381eddd3ef210122118b31e620..c7fd8ce0dae838d91915a1c7a34152be + + initialCache = this.getOrCacheExplosionBlock(blockX, blockY, blockZ, key, true); + } - -- d4 += d0 * 0.30000001192092896D; -- d5 += d1 * 0.30000001192092896D; -- d6 += d2 * 0.30000001192092896D; ++ + // only ~1/3rd of the loop iterations in vanilla will result in a ray, as it is iterating the perimeter of + // a 16x16x16 cube + // we can cache the rays and their normals as well, so that we eliminate the excess iterations / checks and @@ -30741,17 +30741,32 @@ index 86656de31b1e33381eddd3ef210122118b31e620..c7fd8ce0dae838d91915a1c7a34152be + if (cachedBlock.outOfWorld) { + break; + } ++ final BlockState iblockdata = cachedBlock.blockState; + + power -= cachedBlock.resistance; + + if (power > 0.0f && cachedBlock.shouldExplode == null) { + // note: we expect shouldBlockExplode to be pure with respect to power, as Vanilla currently is. + // basically, it is unused, which allows us to cache the result -+ final boolean shouldExplode = this.damageCalculator.shouldBlockExplode((Explosion)(Object)this, this.level, cachedBlock.immutablePos, cachedBlock.blockState, power); ++ final boolean shouldExplode = iblockdata.isDestroyable() && this.damageCalculator.shouldBlockExplode((Explosion)(Object)this, this.level, cachedBlock.immutablePos, cachedBlock.blockState, power); // Paper - Protect Bedrock and End Portal/Frames from being destroyed + cachedBlock.shouldExplode = shouldExplode ? Boolean.TRUE : Boolean.FALSE; + if (shouldExplode) { + if (this.fire || !cachedBlock.blockState.isAir()) { + ret.add(cachedBlock.immutablePos); ++ // Paper start - prevent headless pistons from forming ++ if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowHeadlessPistons && iblockdata.getBlock() == Blocks.MOVING_PISTON) { ++ net.minecraft.world.level.block.entity.BlockEntity extension = this.level.getBlockEntity(cachedBlock.immutablePos); // Paper - optimise collisions ++ if (extension instanceof net.minecraft.world.level.block.piston.PistonMovingBlockEntity blockEntity && blockEntity.isSourcePiston()) { ++ net.minecraft.core.Direction direction = iblockdata.getValue(net.minecraft.world.level.block.piston.PistonHeadBlock.FACING); ++ ret.add(cachedBlock.immutablePos.relative(direction.getOpposite())); // Paper - optimise collisions + } +- // Paper end - prevent headless pistons from forming + } +- +- d4 += d0 * 0.30000001192092896D; +- d5 += d1 * 0.30000001192092896D; +- d6 += d2 * 0.30000001192092896D; ++ // Paper end - prevent headless pistons from forming } } } @@ -30770,7 +30785,7 @@ index 86656de31b1e33381eddd3ef210122118b31e620..c7fd8ce0dae838d91915a1c7a34152be } private void hurtEntities() { -@@ -390,6 +660,14 @@ public class ServerExplosion implements Explosion { +@@ -391,6 +670,14 @@ public class ServerExplosion implements Explosion { return; } // CraftBukkit end @@ -30785,7 +30800,7 @@ index 86656de31b1e33381eddd3ef210122118b31e620..c7fd8ce0dae838d91915a1c7a34152be this.level.gameEvent(this.source, (Holder) GameEvent.EXPLODE, this.center); List list = this.calculateExplodedPositions(); -@@ -405,6 +683,13 @@ public class ServerExplosion implements Explosion { +@@ -406,6 +693,13 @@ public class ServerExplosion implements Explosion { if (this.fire) { this.createFire(list); } @@ -30799,7 +30814,7 @@ index 86656de31b1e33381eddd3ef210122118b31e620..c7fd8ce0dae838d91915a1c7a34152be } -@@ -494,12 +779,12 @@ public class ServerExplosion implements Explosion { +@@ -495,12 +789,12 @@ public class ServerExplosion implements Explosion { // Paper start - Optimize explosions private float getBlockDensity(Vec3 vec3d, Entity entity) { if (!this.level.paperConfig().environment.optimizeExplosions) { @@ -30855,10 +30870,10 @@ index 01352cc83b25eb0e30b7e0ff521fc7c1b3d5155b..90f8360f547ce709fd13ee34f8e67d8b public interface NoiseBiomeSource { diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index 4d140bd83ca0e1554afad80ec4fc6186188a79d8..3dd236d39535cfce866eb73673f8d7f1b6dc535c 100644 +index 729c3d8279b13d21c65ede89ea50869b69d5bfe6..fa19720fbb911842db42a4eb0ccf8406cb27c137 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -265,7 +265,7 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -278,7 +278,7 @@ public class Block extends BlockBehaviour implements ItemLike { } public static boolean isShapeFullBlock(VoxelShape shape) { @@ -30868,7 +30883,7 @@ index 4d140bd83ca0e1554afad80ec4fc6186188a79d8..3dd236d39535cfce866eb73673f8d7f1 public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) {} diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -index 0665ca48fe2f8ab1ce1c0306b11be19b06445f74..8631655a181735df53f8a02c9eb98f0cc13f55bb 100644 +index 95d30c2db7e291d65c24feb114b0f3598d280912..99fd67a78539133adf78d65e2c520ff3dd260301 100644 --- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java @@ -793,7 +793,7 @@ public abstract class BlockBehaviour implements FeatureElement { @@ -31502,7 +31517,7 @@ index 37795b9e264c571efe9c718fa9996197dca4ed54..0601f454758cb1447cca2cbff4ef5fd7 public static record PackedTicks(List> blocks, List> fluids) { diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index 906f56d07c26ef3c2dc1a3b62e9349dd91a37742..975abf5948a75c7d0cab8f052af2c4e91bcef2a8 100644 +index 4cbc68d8e950f8d7c8b00535b82e916964c88ce0..12148b80794f620799e44f59f0251bb27e74f2c9 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -119,7 +119,7 @@ public abstract class ChunkGenerator { @@ -31514,7 +31529,7 @@ index 906f56d07c26ef3c2dc1a3b62e9349dd91a37742..975abf5948a75c7d0cab8f052af2c4e9 } public abstract void applyCarvers(WorldGenRegion chunkRegion, long seed, RandomState noiseConfig, BiomeManager biomeAccess, StructureManager structureAccessor, ChunkAccess chunk); -@@ -311,7 +311,7 @@ public abstract class ChunkGenerator { +@@ -314,7 +314,7 @@ public abstract class ChunkGenerator { return Pair.of(placement.getLocatePos(pos), holder); } @@ -31665,7 +31680,7 @@ index 7cce66d4c6efe6fd3cc22a6acf72878c964c61ae..30ee3df2278d0d9bd7478b49eda5fff2 @Override public BlockEntity getBlockEntity(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 7181acfafad91aa5f6ab7ce663d9be4a1b65b02a..040a9232c624ee44e95ee4443baf39a670b09296 100644 +index 325d1e38a72a4b30f30261267e9adfb8a8726b11..86b018042590c3ce115555639e7791c521cecffc 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -54,7 +54,7 @@ import net.minecraft.world.ticks.LevelChunkTicks; @@ -32729,7 +32744,7 @@ index cb823d342e41b5861adfc847a313c265fb702a4c..2b1ea97199d5976e5ff4bd049c1e6c8b private final Long2ObjectLinkedOpenHashMap> regionCacheForBlender = new Long2ObjectLinkedOpenHashMap<>(); private static final int REGION_CACHE_SIZE = 1024; 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 f1237f6fd6414900ffbad0caee31aa83310eeef4..8071ce70d66909bb4bda45792bf329a939d6f918 100644 +index e858436bcf1b234d4bc6e6a117f5224d5c2d9f90..47560d1763d2e70e609cec63ea2defde3d012eb1 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 @@ -25,7 +25,7 @@ import net.minecraft.util.profiling.jfr.JvmProfiler; @@ -32761,7 +32776,7 @@ index f1237f6fd6414900ffbad0caee31aa83310eeef4..8071ce70d66909bb4bda45792bf329a9 + // Paper end - rewrite chunk system + public RegionFile(RegionStorageInfo storageKey, Path directory, Path path, boolean dsync) throws IOException { - this(storageKey, directory, path, RegionFileVersion.getSelected(), dsync); + this(storageKey, directory, path, RegionFileVersion.getCompressionFormat(), dsync); // Paper - Configurable region compression format } @@ -220,6 +235,16 @@ public class RegionFile implements AutoCloseable { @@ -33277,7 +33292,7 @@ index 93972352cd4881dccba9b90ccc8dcced3563e340..c3beb7fcad46a917d2b61bd0a0e98e51 static record PackedChunk(Int2ObjectMap sectionsByY, boolean versionChanged) { diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index d7a204216332ccbd6bece23bd507be0366ea4d61..7f1e3d5faa420315b0de63b267d90ccfb855cf04 100644 +index b86b3bf713668999a21c4120b1d16c295531b2ad..eb8f5d2efe7c32ddda4763e2ebe0653050101efd 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java @@ -128,7 +128,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun @@ -33383,7 +33398,7 @@ index d7a204216332ccbd6bece23bd507be0366ea4d61..7f1e3d5faa420315b0de63b267d90ccf } else { ProtoChunk protochunk1 = (ProtoChunk) object; Iterator iterator2 = this.entities.iterator(); -@@ -370,7 +421,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -377,7 +428,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun protochunk1.setCarvingMask(new CarvingMask(this.carvingMask, ((ChunkAccess) object).getMinY())); } @@ -33392,7 +33407,7 @@ index d7a204216332ccbd6bece23bd507be0366ea4d61..7f1e3d5faa420315b0de63b267d90ccf } } -@@ -393,24 +444,48 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -400,24 +451,48 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun throw new IllegalArgumentException("Chunk can't be serialized: " + String.valueOf(chunk)); } else { ChunkPos chunkcoordintpair = chunk.getPos(); @@ -33416,11 +33431,14 @@ index d7a204216332ccbd6bece23bd507be0366ea4d61..7f1e3d5faa420315b0de63b267d90ccf + final LevelChunkSection[] chunkSections = chunk.getSections(); + final ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray[] blockNibbles = ((ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk)chunk).starlight$getBlockNibbles(); + final ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray[] skyNibbles = ((ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk)chunk).starlight$getSkyNibbles(); -+ + +- if (flag || nibblearray2 != null || nibblearray3 != null) { +- LevelChunkSection chunksection = flag ? achunksection[j].copy() : null; + for (int lightSection = minLightSection; lightSection <= maxLightSection; ++lightSection) { + final int lightSectionIdx = lightSection - minLightSection; + final int blockSectionIdx = lightSection - minBlockSection; -+ + +- list.add(new SerializableChunkData.SectionData(i, chunksection, nibblearray2, nibblearray3)); + final LevelChunkSection chunkSection = (blockSectionIdx >= 0 && blockSectionIdx < chunkSections.length) ? chunkSections[blockSectionIdx].copy() : null; + final ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray.SaveState blockNibble = blockNibbles[lightSectionIdx].getSaveState(); + final ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray.SaveState skyNibble = skyNibbles[lightSectionIdx].getSaveState(); @@ -33434,17 +33452,14 @@ index d7a204216332ccbd6bece23bd507be0366ea4d61..7f1e3d5faa420315b0de63b267d90ccf + blockNibble == null ? null : (blockNibble.data == null ? null : new DataLayer(blockNibble.data)), + skyNibble == null ? null : (skyNibble.data == null ? null : new DataLayer(skyNibble.data)) + ); - -- if (flag || nibblearray2 != null || nibblearray3 != null) { -- LevelChunkSection chunksection = flag ? achunksection[j].copy() : null; ++ + if (blockNibble != null) { + ((ca.spottedleaf.moonrise.patches.starlight.storage.StarlightSectionData)(Object)sectionData).starlight$setBlockLightState(blockNibble.state); -+ } - -- list.add(new SerializableChunkData.SectionData(i, chunksection, nibblearray2, nibblearray3)); + } ++ + if (skyNibble != null) { + ((ca.spottedleaf.moonrise.patches.starlight.storage.StarlightSectionData)(Object)sectionData).starlight$setSkyLightState(skyNibble.state); - } ++ } + + sections.add(sectionData); } @@ -33452,7 +33467,7 @@ index d7a204216332ccbd6bece23bd507be0366ea4d61..7f1e3d5faa420315b0de63b267d90ccf List list1 = new ArrayList(chunk.getBlockEntitiesPos().size()); Iterator iterator = chunk.getBlockEntitiesPos().iterator(); -@@ -509,8 +584,8 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -516,8 +591,8 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun Iterator iterator = this.sectionData.iterator(); while (iterator.hasNext()) { @@ -33463,7 +33478,7 @@ index d7a204216332ccbd6bece23bd507be0366ea4d61..7f1e3d5faa420315b0de63b267d90ccf LevelChunkSection chunksection = serializablechunkdata_b.chunkSection; if (chunksection != null) { -@@ -526,6 +601,19 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -533,6 +608,19 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun nbttagcompound1.putByteArray("SkyLight", serializablechunkdata_b.skyLight.getData()); } @@ -33483,7 +33498,7 @@ index d7a204216332ccbd6bece23bd507be0366ea4d61..7f1e3d5faa420315b0de63b267d90ccf if (!nbttagcompound1.isEmpty()) { nbttagcompound1.putByte("Y", (byte) serializablechunkdata_b.y); nbttaglist.add(nbttagcompound1); -@@ -565,6 +653,14 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -572,6 +660,14 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun nbttagcompound.put("ChunkBukkitValues", this.persistentDataContainer); } // CraftBukkit end @@ -33498,7 +33513,7 @@ index d7a204216332ccbd6bece23bd507be0366ea4d61..7f1e3d5faa420315b0de63b267d90ccf return nbttagcompound; } -@@ -744,7 +840,67 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -758,7 +854,67 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun return nbttaglist; } @@ -35920,7 +35935,7 @@ index 26620c06d26a2c0eb957fbadc6ac3d7a309bff46..3858c83c58e78435a6e29de84c33faa2 for (SavedTick savedTick : this.pendingTicks) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java -index 887a17a0833064eb5701222e5fb6f5ccf9511588..ca1dd58229b7e39dffdd7a69c296dc5f652aa5e6 100644 +index 5fc9e8e969debb3e15ed474b36a1c48b086d0449..47424d897ba706bc5f80ab563de130c873ccff2f 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -82,6 +82,12 @@ public class CraftChunk implements Chunk { @@ -36000,10 +36015,10 @@ index 887a17a0833064eb5701222e5fb6f5ccf9511588..ca1dd58229b7e39dffdd7a69c296dc5f @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index f85e8ec660bf588f694aa96e6e2ade478a9696b7..625f45b50654732231c835df867f9d84897dd211 100644 +index 6235d7caede85f4cf21dadde18d8080004672349..bfa2fc2e1ca9b68f5bf8b2e1ba6db4692ef4f73e 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1356,7 +1356,7 @@ public final class CraftServer implements Server { +@@ -1421,7 +1421,7 @@ public final class CraftServer implements Server { // Paper - Put world into worldlist before initing the world; move up this.getServer().prepareLevels(internal.getChunkSource().chunkMap.progressListener, internal); @@ -36012,7 +36027,7 @@ index f85e8ec660bf588f694aa96e6e2ade478a9696b7..625f45b50654732231c835df867f9d84 this.pluginManager.callEvent(new WorldLoadEvent(internal.getWorld())); return internal.getWorld(); -@@ -1401,7 +1401,7 @@ public final class CraftServer implements Server { +@@ -1466,7 +1466,7 @@ public final class CraftServer implements Server { } handle.getChunkSource().close(save); @@ -36021,7 +36036,7 @@ index f85e8ec660bf588f694aa96e6e2ade478a9696b7..625f45b50654732231c835df867f9d84 handle.convertable.close(); } catch (Exception ex) { this.getLogger().log(Level.SEVERE, null, ex); -@@ -2368,7 +2368,7 @@ public final class CraftServer implements Server { +@@ -2478,7 +2478,7 @@ public final class CraftServer implements Server { @Override public boolean isPrimaryThread() { @@ -36031,10 +36046,10 @@ index f85e8ec660bf588f694aa96e6e2ade478a9696b7..625f45b50654732231c835df867f9d84 // Paper start - Adventure diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 03cef3e33de1cf2a1ad4c7a5ba9a65ee3b69ee52..3b81839fa92ecf3846435dd4b7e0dc238b2ab1be 100644 +index 149377347fc632358a8bb97e644b1c4ab9be413d..2cef4788cce4467ba87d7982dbc559215917bce0 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -458,10 +458,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -467,10 +467,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z)); if (playerChunk == null) return false; @@ -36052,7 +36067,7 @@ index 03cef3e33de1cf2a1ad4c7a5ba9a65ee3b69ee52..3b81839fa92ecf3846435dd4b7e0dc23 ClientboundLevelChunkWithLightPacket refreshPacket = new ClientboundLevelChunkWithLightPacket(chunk, this.world.getLightEngine(), null, null); for (ServerPlayer player : playersInRange) { -@@ -469,8 +473,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -478,8 +482,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { player.connection.send(refreshPacket); } @@ -36062,7 +36077,7 @@ index 03cef3e33de1cf2a1ad4c7a5ba9a65ee3b69ee52..3b81839fa92ecf3846435dd4b7e0dc23 return true; } -@@ -574,20 +577,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -583,20 +586,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public Collection getPluginChunkTickets(int x, int z) { DistanceManager chunkDistanceManager = this.world.getChunkSource().chunkMap.distanceManager; @@ -36084,7 +36099,7 @@ index 03cef3e33de1cf2a1ad4c7a5ba9a65ee3b69ee52..3b81839fa92ecf3846435dd4b7e0dc23 } @Override -@@ -595,7 +586,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -604,7 +595,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { Map> ret = new HashMap<>(); DistanceManager chunkDistanceManager = this.world.getChunkSource().chunkMap.distanceManager; @@ -36093,7 +36108,7 @@ index 03cef3e33de1cf2a1ad4c7a5ba9a65ee3b69ee52..3b81839fa92ecf3846435dd4b7e0dc23 long chunkKey = chunkTickets.getLongKey(); SortedArraySet> tickets = chunkTickets.getValue(); -@@ -1278,12 +1269,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1307,12 +1298,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public int getViewDistance() { @@ -36108,7 +36123,7 @@ index 03cef3e33de1cf2a1ad4c7a5ba9a65ee3b69ee52..3b81839fa92ecf3846435dd4b7e0dc23 } public BlockMetadataStore getBlockMetadata() { -@@ -2416,17 +2407,20 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2453,17 +2444,20 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setSimulationDistance(final int simulationDistance) { @@ -36133,10 +36148,10 @@ index 03cef3e33de1cf2a1ad4c7a5ba9a65ee3b69ee52..3b81839fa92ecf3846435dd4b7e0dc23 // Paper start - implement pointers diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index cdc53abb5572fa57b4ec98a694c5583ad0982a05..e59572f05b69b8302b69de8cbcfbc889f67634b5 100644 +index 8d16575c74b81ada4e4efe70e8f077f07cd0a3f0..d010e34543474fe5d108b2e862041c5921ab97dd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3402,7 +3402,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3523,7 +3523,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setViewDistance(final int viewDistance) { @@ -36147,7 +36162,7 @@ index cdc53abb5572fa57b4ec98a694c5583ad0982a05..e59572f05b69b8302b69de8cbcfbc889 } @Override -@@ -3412,7 +3414,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3533,7 +3535,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setSimulationDistance(final int simulationDistance) { @@ -36158,7 +36173,7 @@ index cdc53abb5572fa57b4ec98a694c5583ad0982a05..e59572f05b69b8302b69de8cbcfbc889 } @Override -@@ -3422,6 +3426,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3543,6 +3547,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setSendViewDistance(final int viewDistance) { @@ -36182,10 +36197,10 @@ index 625562a38bc78feae3ae4b50b9afefbd05ff767a..e34060c21755c61228ba91e468b7c92f @Override diff --git a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java -index e444662ee4d9405eeea7caa41b9cd6b36586d840..504ab4b545e084c962ebd5f26d9336adc16030fb 100644 +index 54c4434662d057a08800918641b95708cda61207..37458e8fd5d57acbf90a6bea4e66797cb07f69fa 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java +++ b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java -@@ -808,6 +808,13 @@ public abstract class DelegatedGeneratorAccess implements WorldGenLevel { +@@ -810,6 +810,13 @@ public abstract class DelegatedGeneratorAccess implements WorldGenLevel { public ChunkAccess getChunkIfLoadedImmediately(final int x, final int z) { return this.handle.getChunkIfLoadedImmediately(x, z); } From f1a11a6e3fc5c3b3b68df8008aab527ec92bfa6b Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Thu, 24 Oct 2024 12:47:34 -0700 Subject: [PATCH 071/119] Finish mixin diff review The mixin diff review looks OK, but need to check the patch diff now. --- moonrise_update_1_21_2.txt | 7 ++----- .../0980-Moonrise-optimisation-patches.patch | 20 ++++++++++++------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/moonrise_update_1_21_2.txt b/moonrise_update_1_21_2.txt index 3ecdcaf3b337..27f8176a6ec7 100644 --- a/moonrise_update_1_21_2.txt +++ b/moonrise_update_1_21_2.txt @@ -1,7 +1,4 @@ -reference comparison: -https://github.com/Tuinity/Moonrise/compare/6a2c6d27df11d417c1fefa749109d8e87599e8c2...f22335f0b65e205831c74a7b4b8f4d93fff54fd5 - - todo: -- need to compare the diffs +- need to compare the patch diff for moonrise - in ChunkEntitySlices, implement modifySavedEntities() by copying from old +- port poi_lookup? diff --git a/patches/server/0980-Moonrise-optimisation-patches.patch b/patches/server/0980-Moonrise-optimisation-patches.patch index c9f3fac9b9f5..4db77860f7b7 100644 --- a/patches/server/0980-Moonrise-optimisation-patches.patch +++ b/patches/server/0980-Moonrise-optimisation-patches.patch @@ -23635,7 +23635,7 @@ index 39c9c0dad159744da8322c3dfa3bfae448f73241..3ed19896a0e06fe834953e6450f23abd } diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java -index b9ab241b930edc63a39dbbcf14cd0b5edacb9ea9..3b5b6799b6e7832d7cc7d73afb5f2ca04fee6060 100644 +index b9ab241b930edc63a39dbbcf14cd0b5edacb9ea9..8dd9375f2ad2c65a773a3195aeff1f977e09e7e0 100644 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java @@ -32,46 +32,125 @@ import net.minecraft.world.level.lighting.LevelLightEngine; @@ -23795,7 +23795,7 @@ index b9ab241b930edc63a39dbbcf14cd0b5edacb9ea9..3b5b6799b6e7832d7cc7d73afb5f2ca0 return this.getFullChunkNowUnchecked(); } -@@ -89,59 +168,60 @@ public class ChunkHolder extends GenerationChunkHolder { +@@ -89,64 +168,65 @@ public class ChunkHolder extends GenerationChunkHolder { // CraftBukkit end public CompletableFuture> getTickingChunkFuture() { @@ -23878,6 +23878,12 @@ index b9ab241b930edc63a39dbbcf14cd0b5edacb9ea9..3b5b6799b6e7832d7cc7d73afb5f2ca0 } + public boolean blockChanged(BlockPos pos) { +- LevelChunk chunk = this.getTickingChunk(); ++ LevelChunk chunk = this.playersSentChunkTo.size() == 0 ? null : this.getChunkToSend(); // Paper - rewrite chunk system + + if (chunk == null) { + return false; @@ -172,7 +252,7 @@ public class ChunkHolder extends GenerationChunkHolder { return false; } else { @@ -31015,7 +31021,7 @@ index 95d30c2db7e291d65c24feb114b0f3598d280912..99fd67a78539133adf78d65e2c520ff3 public Block getBlock() { diff --git a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java -index 422b364764e0df16ca250b4939d7b226e69c0840..2df28ffc731bd77e0d7af3541cfd3741aa5af83b 100644 +index 422b364764e0df16ca250b4939d7b226e69c0840..815ee11aa5ed3448ff255e9c36d769478de477bd 100644 --- a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java +++ b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java @@ -15,7 +15,7 @@ import java.util.stream.Collectors; @@ -31032,7 +31038,7 @@ index 422b364764e0df16ca250b4939d7b226e69c0840..2df28ffc731bd77e0d7af3541cfd3741 }; protected final O owner; - private final Reference2ObjectArrayMap, Comparable> values; -+ private Reference2ObjectArrayMap, Comparable> values; // Paper - optimise blockstate property access - remove final ++ private Reference2ObjectArrayMap, Comparable> values; // Paper - optimise blockstate property access - remove final private Map, S[]> neighbours; protected final MapCodec propertiesCodec; @@ -31859,7 +31865,7 @@ index 325d1e38a72a4b30f30261267e9adfb8a8726b11..86b018042590c3ce115555639e7791c5 @Nullable diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -index 52f44f14bbda60fe771c351e01e6ff470d7371e6..4167ed830382c6a76bb281e9d753919925c6bd00 100644 +index 52f44f14bbda60fe771c351e01e6ff470d7371e6..b85f354afa23ddf7e24facdb0516407ee2725bee 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java @@ -13,7 +13,7 @@ import net.minecraft.world.level.block.Blocks; @@ -31889,8 +31895,8 @@ index 52f44f14bbda60fe771c351e01e6ff470d7371e6..4167ed830382c6a76bb281e9d7539199 + private final ca.spottedleaf.moonrise.common.list.ShortList tickingBlocks = new ca.spottedleaf.moonrise.common.list.ShortList(); + + @Override -+ public final int moonrise$getSpecialCollidingBlocks() { -+ return this.specialCollidingBlocks; ++ public final boolean moonrise$hasSpecialCollidingBlocks() { ++ return this.specialCollidingBlocks != 0; + } + + @Override From a911f4a1672e52d3b558fd58d64a291e3500336d Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 25 Oct 2024 11:24:51 -0700 Subject: [PATCH 072/119] Prepare rebase --- ...fixup-ConcurrentUtil.patch => 2973-fixup-ConcurrentUtil.patch} | 0 .../{0975-fixup-MC-Utils.patch => 2975-fixup-MC-Utils.patch} | 0 ...erter-system.patch => 2976-Rewrite-dataconverter-system.patch} | 0 ...tch => 2977-fixup-Optimize-BlockPosition-helper-methods.patch} | 0 ...More-Teleport-API.patch => 2978-fixup-More-Teleport-API.patch} | 0 .../{0979-fixup-Timings-v2.patch => 2979-fixup-Timings-v2.patch} | 0 ...ion-patches.patch => 2980-Moonrise-optimisation-patches.patch} | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename patches/server/{0973-fixup-ConcurrentUtil.patch => 2973-fixup-ConcurrentUtil.patch} (100%) rename patches/server/{0975-fixup-MC-Utils.patch => 2975-fixup-MC-Utils.patch} (100%) rename patches/server/{0976-Rewrite-dataconverter-system.patch => 2976-Rewrite-dataconverter-system.patch} (100%) rename patches/server/{0977-fixup-Optimize-BlockPosition-helper-methods.patch => 2977-fixup-Optimize-BlockPosition-helper-methods.patch} (100%) rename patches/server/{0978-fixup-More-Teleport-API.patch => 2978-fixup-More-Teleport-API.patch} (100%) rename patches/server/{0979-fixup-Timings-v2.patch => 2979-fixup-Timings-v2.patch} (100%) rename patches/server/{0980-Moonrise-optimisation-patches.patch => 2980-Moonrise-optimisation-patches.patch} (100%) diff --git a/patches/server/0973-fixup-ConcurrentUtil.patch b/patches/server/2973-fixup-ConcurrentUtil.patch similarity index 100% rename from patches/server/0973-fixup-ConcurrentUtil.patch rename to patches/server/2973-fixup-ConcurrentUtil.patch diff --git a/patches/server/0975-fixup-MC-Utils.patch b/patches/server/2975-fixup-MC-Utils.patch similarity index 100% rename from patches/server/0975-fixup-MC-Utils.patch rename to patches/server/2975-fixup-MC-Utils.patch diff --git a/patches/server/0976-Rewrite-dataconverter-system.patch b/patches/server/2976-Rewrite-dataconverter-system.patch similarity index 100% rename from patches/server/0976-Rewrite-dataconverter-system.patch rename to patches/server/2976-Rewrite-dataconverter-system.patch diff --git a/patches/server/0977-fixup-Optimize-BlockPosition-helper-methods.patch b/patches/server/2977-fixup-Optimize-BlockPosition-helper-methods.patch similarity index 100% rename from patches/server/0977-fixup-Optimize-BlockPosition-helper-methods.patch rename to patches/server/2977-fixup-Optimize-BlockPosition-helper-methods.patch diff --git a/patches/server/0978-fixup-More-Teleport-API.patch b/patches/server/2978-fixup-More-Teleport-API.patch similarity index 100% rename from patches/server/0978-fixup-More-Teleport-API.patch rename to patches/server/2978-fixup-More-Teleport-API.patch diff --git a/patches/server/0979-fixup-Timings-v2.patch b/patches/server/2979-fixup-Timings-v2.patch similarity index 100% rename from patches/server/0979-fixup-Timings-v2.patch rename to patches/server/2979-fixup-Timings-v2.patch diff --git a/patches/server/0980-Moonrise-optimisation-patches.patch b/patches/server/2980-Moonrise-optimisation-patches.patch similarity index 100% rename from patches/server/0980-Moonrise-optimisation-patches.patch rename to patches/server/2980-Moonrise-optimisation-patches.patch From 35ef2932bee3b0bda4afbb5cca7a76e5af58f351 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 25 Oct 2024 11:40:25 -0700 Subject: [PATCH 073/119] Finish rebase --- ....patch => 1037-fixup-ConcurrentUtil.patch} | 0 ...ch => 1038-fixup-Paper-config-files.patch} | 0 ...-Utils.patch => 1039-fixup-MC-Utils.patch} | 21 +- ...> 1040-Rewrite-dataconverter-system.patch} | 8 +- ...timize-BlockPosition-helper-methods.patch} | 2 +- ...tch => 1042-fixup-More-Teleport-API.patch} | 4 +- ... 1043-Moonrise-optimisation-patches.patch} | 297 +++++++++--------- patches/server/2979-fixup-Timings-v2.patch | 18 -- 8 files changed, 161 insertions(+), 189 deletions(-) rename patches/server/{2973-fixup-ConcurrentUtil.patch => 1037-fixup-ConcurrentUtil.patch} (100%) rename patches/server/{0974-fixup-Paper-config-files.patch => 1038-fixup-Paper-config-files.patch} (100%) rename patches/server/{2975-fixup-MC-Utils.patch => 1039-fixup-MC-Utils.patch} (99%) rename patches/server/{2976-Rewrite-dataconverter-system.patch => 1040-Rewrite-dataconverter-system.patch} (99%) rename patches/server/{2977-fixup-Optimize-BlockPosition-helper-methods.patch => 1041-fixup-Optimize-BlockPosition-helper-methods.patch} (96%) rename patches/server/{2978-fixup-More-Teleport-API.patch => 1042-fixup-More-Teleport-API.patch} (90%) rename patches/server/{2980-Moonrise-optimisation-patches.patch => 1043-Moonrise-optimisation-patches.patch} (99%) delete mode 100644 patches/server/2979-fixup-Timings-v2.patch diff --git a/patches/server/2973-fixup-ConcurrentUtil.patch b/patches/server/1037-fixup-ConcurrentUtil.patch similarity index 100% rename from patches/server/2973-fixup-ConcurrentUtil.patch rename to patches/server/1037-fixup-ConcurrentUtil.patch diff --git a/patches/server/0974-fixup-Paper-config-files.patch b/patches/server/1038-fixup-Paper-config-files.patch similarity index 100% rename from patches/server/0974-fixup-Paper-config-files.patch rename to patches/server/1038-fixup-Paper-config-files.patch diff --git a/patches/server/2975-fixup-MC-Utils.patch b/patches/server/1039-fixup-MC-Utils.patch similarity index 99% rename from patches/server/2975-fixup-MC-Utils.patch rename to patches/server/1039-fixup-MC-Utils.patch index 269928078799..06f2a7898c20 100644 --- a/patches/server/2975-fixup-MC-Utils.patch +++ b/patches/server/1039-fixup-MC-Utils.patch @@ -1022,14 +1022,14 @@ index 11b7f15755dde766140c29bedca456c80d53293f..217d1f908a36a5177ba3cbb80a33f73d } diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java -index af9623240ff2d389aa7090623f507720e7dbab7d..efda2688ae1254a82ba7f6bf8bf597ef224cbb86 100644 +index 561a1a3ff418393d0a0db58de91b336f4c33aa4e..efda2688ae1254a82ba7f6bf8bf597ef224cbb86 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java -@@ -8,11 +8,19 @@ public final class WorldUtil { +@@ -8,13 +8,21 @@ public final class WorldUtil { // min, max are inclusive public static int getMaxSection(final LevelHeightAccessor world) { -- return world.getMaxSection() - 1; // getMaxSection() is exclusive +- return world.getMaxSectionY() - 1; // getMaxSection() is exclusive + return world.getMaxSectionY(); + } + @@ -1038,15 +1038,16 @@ index af9623240ff2d389aa7090623f507720e7dbab7d..efda2688ae1254a82ba7f6bf8bf597ef } public static int getMinSection(final LevelHeightAccessor world) { -- return world.getMinSection(); + return world.getMinSectionY(); + } + ++ public static int getMinSection(final Level world) { + return world.getMinSectionY(); + } + -+ public static int getMinSection(final Level world) { -+ return world.getMinSectionY(); - } - public static int getMaxLightSection(final LevelHeightAccessor world) { + return getMaxSection(world) + 1; + } diff --git a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java new file mode 100644 index 0000000000000000000000000000000000000000..1aa6be257ce594d7a69fdff008cd29014a04fd75 @@ -1276,10 +1277,10 @@ index 4954ed9edf1e1f54cc164e48817eb5b75ea87ce0..8a0cb603cd4dbfa1839e0f4e1606876c } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 2aa4437a76d29cdd793680734a36a41c6133ab91..0cf4f9d60337cfe89075a79eabfd182cdec91695 100644 +index c17824fa01c4682c2b97bb60bfa401a1a2ef9c12..878bd04b63f257cc625953e45b953beb06917107 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -272,7 +272,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -271,7 +271,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return true; } diff --git a/patches/server/2976-Rewrite-dataconverter-system.patch b/patches/server/1040-Rewrite-dataconverter-system.patch similarity index 99% rename from patches/server/2976-Rewrite-dataconverter-system.patch rename to patches/server/1040-Rewrite-dataconverter-system.patch index 90d6b4c94707..c56d13c8730e 100644 --- a/patches/server/2976-Rewrite-dataconverter-system.patch +++ b/patches/server/1040-Rewrite-dataconverter-system.patch @@ -30343,7 +30343,7 @@ index 05a76f9d18638f10218161450470f07524b723ac..3ab22c384bb8a7772d389977a61d0e28 } diff --git a/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java b/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java -index b5abdd1498a3d19559149c30ba959aa2bcf0246c..0c2e827f4ee53ed2723da60f08a6cf96769bbdfa 100644 +index 79397b3c76e4b9d2ee03dfa16c2daf4f71ae8b4d..cdca5ae69991cc068bfbc0686b5defb3604a5440 100644 --- a/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java +++ b/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java @@ -277,12 +277,21 @@ public class LevelStorageSource { @@ -30384,10 +30384,10 @@ index b54a3741cd3ba615c83c98985cb4b3c4c586ed7a..b148cf247acdd36f856d0495cde4cc5a return nbttagcompound; }); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index b24ccbff89db873f5bdf62cbebcca0049b94a8d5..1cda41b104935743cb18e19acca24ad0a1673bb6 100644 +index 2a5c5e9e04d90c4e218b200bb55ff6bf2877ad73..bc53c263682ada9eebcaccc13e741844d310a7a6 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -511,7 +511,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -507,7 +507,7 @@ public final class CraftMagicNumbers implements UnsafeValues { net.minecraft.nbt.CompoundTag compound = deserializeNbtFromBytes(data); final int dataVersion = compound.getInt("DataVersion"); @@ -30396,7 +30396,7 @@ index b24ccbff89db873f5bdf62cbebcca0049b94a8d5..1cda41b104935743cb18e19acca24ad0 return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(MinecraftServer.getServer().registryAccess(), compound).orElseThrow()); } -@@ -532,7 +532,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -561,7 +561,7 @@ public final class CraftMagicNumbers implements UnsafeValues { net.minecraft.nbt.CompoundTag compound = deserializeNbtFromBytes(data); int dataVersion = compound.getInt("DataVersion"); diff --git a/patches/server/2977-fixup-Optimize-BlockPosition-helper-methods.patch b/patches/server/1041-fixup-Optimize-BlockPosition-helper-methods.patch similarity index 96% rename from patches/server/2977-fixup-Optimize-BlockPosition-helper-methods.patch rename to patches/server/1041-fixup-Optimize-BlockPosition-helper-methods.patch index 5a70b45e9548..061b6c4ffe8d 100644 --- a/patches/server/2977-fixup-Optimize-BlockPosition-helper-methods.patch +++ b/patches/server/1041-fixup-Optimize-BlockPosition-helper-methods.patch @@ -5,7 +5,7 @@ Subject: [PATCH] fixup! Optimize BlockPosition helper methods diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java -index 0d51fb4be8b49e3b57c3c55aff6bcf13d5c78ddd..a1d54d978d34d75475f92dfb806113586e7e449c 100644 +index a5dab9b1652ac76372d88316e2c165eed6317891..f58a94efafbc01d402cd03a108bb90f60930a316 100644 --- a/src/main/java/net/minecraft/core/BlockPos.java +++ b/src/main/java/net/minecraft/core/BlockPos.java @@ -162,7 +162,7 @@ public class BlockPos extends Vec3i { diff --git a/patches/server/2978-fixup-More-Teleport-API.patch b/patches/server/1042-fixup-More-Teleport-API.patch similarity index 90% rename from patches/server/2978-fixup-More-Teleport-API.patch rename to patches/server/1042-fixup-More-Teleport-API.patch index f3e4c5eea5c7..9ef4eadd58e2 100644 --- a/patches/server/2978-fixup-More-Teleport-API.patch +++ b/patches/server/1042-fixup-More-Teleport-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] fixup! More Teleport API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index c1d3dd2bd217efd6914bceb1027fa12b06c22a55..7536ab5c22d97a074c08a95fff6bc756d61e387d 100644 +index 64c6f54cc4d0c22bc972b808cb92925cc7526db2..179886dcbda29c5cdb7dbd43e44951ae38d9df96 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1060,7 +1060,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1064,7 +1064,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { java.util.concurrent.CompletableFuture ret = new java.util.concurrent.CompletableFuture<>(); world.loadChunksForMoveAsync(getHandle().getBoundingBoxAt(locationClone.getX(), locationClone.getY(), locationClone.getZ()), diff --git a/patches/server/2980-Moonrise-optimisation-patches.patch b/patches/server/1043-Moonrise-optimisation-patches.patch similarity index 99% rename from patches/server/2980-Moonrise-optimisation-patches.patch rename to patches/server/1043-Moonrise-optimisation-patches.patch index 4db77860f7b7..6c028f78a60a 100644 --- a/patches/server/2980-Moonrise-optimisation-patches.patch +++ b/patches/server/1043-Moonrise-optimisation-patches.patch @@ -23342,7 +23342,7 @@ index 3fde5abde736b2c19d8819d9aec0397a0245ccd1..6548302d4983bf48cc6bc2b7f4833dc7 + // Paper end - optimise collisions } diff --git a/src/main/java/net/minecraft/core/MappedRegistry.java b/src/main/java/net/minecraft/core/MappedRegistry.java -index 71e04e5c1bc0722abf8ca2e0738bd60b6d7ae21c..8e0dfaf02343d74ce786e4fc647bc4c1d73c0014 100644 +index 063630c1ffcce099139c59d598fc5a210e21f640..a61153c5d99bdc26f37a10f33baf839e943e17e1 100644 --- a/src/main/java/net/minecraft/core/MappedRegistry.java +++ b/src/main/java/net/minecraft/core/MappedRegistry.java @@ -50,6 +50,19 @@ public class MappedRegistry implements WritableRegistry { @@ -23386,7 +23386,7 @@ index fc6ce3485dc890f5105a37fe3e344a1460867556..e114e687f2f4503546687fd6792226a6 DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, worldLoader.get(), thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), services, LoggerChunkProgressListener::createFromGameruleRadius); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 21660e4284cfabb333a3edf9224c892ef80b2403..a73e4aaee436405caf88ac0ebe3ed7451310247c 100644 +index 6d0cfaaf414931d9fd8eee417f4b70ac6679de10..407463d7c6ba5d69e722613fa41ffc0a500123b9 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -205,7 +205,7 @@ import org.bukkit.event.server.ServerLoadEvent; @@ -23582,7 +23582,7 @@ index 21660e4284cfabb333a3edf9224c892ef80b2403..a73e4aaee436405caf88ac0ebe3ed745 return true; } else { boolean ret = false; // Paper - force execution of all worlds, do not just bias the first -@@ -2731,6 +2811,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> onLoad) { @@ -26821,7 +26821,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 int minBlockX = Mth.floor(axisalignedbb.minX - 1.0E-7D) - 3; int maxBlockX = Mth.floor(axisalignedbb.maxX + 1.0E-7D) + 3; -@@ -295,30 +287,159 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -294,30 +286,159 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe int minChunkZ = minBlockZ >> 4; int maxChunkZ = maxBlockZ >> 4; @@ -26995,7 +26995,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 } } } -@@ -326,22 +447,137 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -325,22 +446,137 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe for (int cx = minChunkX; cx <= maxChunkX; ++cx) { for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) { @@ -27143,7 +27143,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 // Add env and gen to constructor, IWorldDataServer -> WorldDataServer public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { -@@ -375,14 +611,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -374,14 +610,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe DataFixer datafixer = minecraftserver.getFixerUpper(); EntityPersistentStorage entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver); @@ -27161,7 +27161,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 return minecraftserver.overworld().getDataStorage(); }); this.chunkSource.getGeneratorState().ensureStructuresGenerated(); -@@ -410,6 +645,20 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -409,6 +644,20 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.randomSequences = (RandomSequences) Objects.requireNonNullElseGet(randomsequences, () -> { return (RandomSequences) this.getDataStorage().computeIfAbsent(RandomSequences.factory(l), "random_sequences"); }); @@ -27182,7 +27182,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit } -@@ -542,7 +791,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -541,7 +790,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe gameprofilerfiller.push("checkDespawn"); entity.checkDespawn(); gameprofilerfiller.pop(); @@ -27191,7 +27191,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 Entity entity1 = entity.getVehicle(); if (entity1 != null) { -@@ -567,13 +816,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -566,13 +815,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } gameprofilerfiller.push("entityManagement"); @@ -27210,7 +27210,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 } protected void tickTime() { -@@ -613,7 +865,60 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -612,7 +864,60 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe }); } @@ -27271,7 +27271,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 ChunkPos chunkcoordintpair = chunk.getPos(); boolean flag = this.isRaining(); int j = chunkcoordintpair.getMinBlockX(); -@@ -621,7 +926,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -620,7 +925,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe ProfilerFiller gameprofilerfiller = Profiler.get(); gameprofilerfiller.push("thunder"); @@ -27280,7 +27280,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 BlockPos blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15)); if (this.isRainingAt(blockposition)) { -@@ -653,7 +958,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -652,7 +957,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (!this.paperConfig().environment.disableIceAndSnow) { // Paper - Option to disable ice and snow for (int l = 0; l < randomTickSpeed; ++l) { @@ -27289,7 +27289,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 this.tickPrecipitation(this.getBlockRandomPos(j, 0, k, 15)); } } -@@ -662,35 +967,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -661,35 +966,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe gameprofilerfiller.popPush("tickBlocks"); timings.chunkTicksBlocks.startTiming(); // Paper if (randomTickSpeed > 0) { @@ -27326,7 +27326,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 } timings.chunkTicksBlocks.stopTiming(); // Paper -@@ -964,6 +1241,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -963,6 +1240,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (fluid1.is(fluid)) { fluid1.tick(this, pos, iblockdata); } @@ -27338,7 +27338,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 } -@@ -973,6 +1255,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -972,6 +1254,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (iblockdata.is(block)) { iblockdata.tick(this, pos, this.random); } @@ -27350,7 +27350,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 } -@@ -1049,6 +1336,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1060,6 +1347,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } public void save(@Nullable ProgressListener progressListener, boolean flush, boolean savingDisabled) { @@ -27362,7 +27362,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 ServerChunkCache chunkproviderserver = this.getChunkSource(); if (!savingDisabled) { -@@ -1064,16 +1356,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1075,16 +1367,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } timings.worldSaveChunks.startTiming(); // Paper @@ -27390,7 +27390,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 // CraftBukkit start - moved from MinecraftServer.saveChunks ServerLevel worldserver1 = this; -@@ -1213,7 +1510,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1224,7 +1521,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.removePlayerImmediately((ServerPlayer) entity, Entity.RemovalReason.DISCARDED); } @@ -27399,7 +27399,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 } // CraftBukkit start -@@ -1244,7 +1541,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1255,7 +1552,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } // CraftBukkit end @@ -27408,7 +27408,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 } } -@@ -1255,11 +1552,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1266,11 +1563,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public boolean tryAddFreshEntityWithPassengers(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { // CraftBukkit end @@ -27421,7 +27421,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 return false; } else { this.addFreshEntityWithPassengers(entity, reason); // CraftBukkit -@@ -1914,7 +2207,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1930,7 +2223,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } } @@ -27430,7 +27430,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 bufferedwriter.write(String.format(Locale.ROOT, "block_entity_tickers: %d\n", this.blockEntityTickers.size())); bufferedwriter.write(String.format(Locale.ROOT, "block_ticks: %d\n", this.getBlockTicks().count())); bufferedwriter.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count())); -@@ -1963,7 +2256,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1979,7 +2272,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe BufferedWriter bufferedwriter2 = Files.newBufferedWriter(path1); try { @@ -27439,7 +27439,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 } catch (Throwable throwable4) { if (bufferedwriter2 != null) { try { -@@ -1984,7 +2277,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2000,7 +2293,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe BufferedWriter bufferedwriter3 = Files.newBufferedWriter(path2); try { @@ -27448,7 +27448,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 } catch (Throwable throwable6) { if (bufferedwriter3 != null) { try { -@@ -2126,7 +2419,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2142,7 +2435,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @VisibleForTesting public String getWatchdogStats() { @@ -27457,7 +27457,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString(); }), this.blockEntityTickers.size(), ServerLevel.getTypeCount(this.blockEntityTickers, TickingBlockEntity::getType), this.getBlockTicks().count(), this.getFluidTicks().count(), this.gatherChunkSourceStats()); } -@@ -2156,15 +2449,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2172,15 +2465,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public LevelEntityGetter getEntities() { org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot @@ -27486,7 +27486,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 } public void startTickingChunk(LevelChunk chunk) { -@@ -2184,34 +2487,47 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2200,34 +2503,47 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public void close() throws IOException { super.close(); @@ -27541,7 +27541,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 } @Override -@@ -2267,7 +2583,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2283,7 +2599,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report); crashreportsystemdetails.setDetail("Loaded entity count", () -> { @@ -27551,7 +27551,7 @@ index 0cf4f9d60337cfe89075a79eabfd182cdec91695..7066a51f0f13915e2378be364b1144f7 return crashreportsystemdetails; } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 52b18f2c333b7535929bb4e52e65cf5fb0f5692f..cff36fc36829194c7fe5991f2a55d23ad18017a6 100644 +index e2527f3e2b96df539c765ae23c83a09d3298d430..8ceeebb561046933cba0725e15732fa074226884 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -218,7 +218,7 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; @@ -28031,24 +28031,11 @@ index b7d29389a357f142237cecd75f8ca91cf1eb6b5b..e4b0dc3121101d54394a0c3a413dabf8 public WorldGenRegion(ServerLevel world, StaticCache2D chunks, ChunkStep generationStep, ChunkAccess centerPos) { this.generatingStep = generationStep; this.cache = chunks; -diff --git a/src/main/java/net/minecraft/server/network/PlayerChunkSender.java b/src/main/java/net/minecraft/server/network/PlayerChunkSender.java -index cdd66e6ce96e2613afe7f06ca8da3cfaa6704b2d..32634e45ac8433648e49e47e20081e15ad41ff15 100644 ---- a/src/main/java/net/minecraft/server/network/PlayerChunkSender.java -+++ b/src/main/java/net/minecraft/server/network/PlayerChunkSender.java -@@ -78,7 +78,7 @@ public class PlayerChunkSender { - } - } - -- private static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) { -+ public static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) { // Paper - public - handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), null, null)); - // Paper start - PlayerChunkLoadEvent - if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index a4937d11b79cef41f3fbf79282c0c435e794dbfe..be7f437a8d2bf1d5c2314848cbf9379c5cf25fde 100644 +index 90c469193ecf9d04dd9e3f1a38157d47c5094985..bbefb529607d1cffe8917b883389494a8fa126c0 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1416,7 +1416,7 @@ public abstract class PlayerList { +@@ -1422,7 +1422,7 @@ public abstract class PlayerList { public void setViewDistance(int viewDistance) { this.viewDistance = viewDistance; @@ -28435,7 +28422,7 @@ index 50040c497a819cd1229042ab3cb057d34a32cacc..1f9c436a632e4f110be61cf76fcfc3b7 + // Paper end - block counting } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 3d4bb855dec45685d6e336d913903341f0ca4a11..4e005543cba9cfad6aeb39094cb856f5406c585a 100644 +index faa239dcb9b7b608911b464c3665c8b064ee6c41..68dec563d9725daa0044781395a840ac5d61b9b5 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -175,7 +175,7 @@ import org.bukkit.event.player.PlayerTeleportEvent; @@ -28447,7 +28434,7 @@ index 3d4bb855dec45685d6e336d913903341f0ca4a11..4e005543cba9cfad6aeb39094cb856f5 // CraftBukkit start private static final int CURRENT_LEVEL = 2; -@@ -457,6 +457,156 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -460,6 +460,156 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this.dimensions.makeBoundingBox(x, y, z); } // Paper end @@ -28604,7 +28591,7 @@ index 3d4bb855dec45685d6e336d913903341f0ca4a11..4e005543cba9cfad6aeb39094cb856f5 public Entity(EntityType type, Level world) { this.id = Entity.ENTITY_COUNTER.incrementAndGet(); -@@ -1320,41 +1470,76 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1365,41 +1515,76 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } private Vec3 collide(Vec3 movement) { @@ -28709,7 +28696,7 @@ index 3d4bb855dec45685d6e336d913903341f0ca4a11..4e005543cba9cfad6aeb39094cb856f5 } private static float[] collectCandidateStepUpHeights(AABB collisionBox, List collisions, float f, float stepHeight) { -@@ -2742,18 +2927,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2787,18 +2972,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public boolean isInWall() { @@ -28827,7 +28814,7 @@ index 3d4bb855dec45685d6e336d913903341f0ca4a11..4e005543cba9cfad6aeb39094cb856f5 } public InteractionResult interact(Player player, InteractionHand hand) { -@@ -4224,14 +4501,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4269,14 +4546,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public Iterable getIndirectPassengers() { @@ -28852,7 +28839,7 @@ index 3d4bb855dec45685d6e336d913903341f0ca4a11..4e005543cba9cfad6aeb39094cb856f5 } private Iterable getIndirectPassengers_old() { // Paper end - Optimize indirect passenger iteration -@@ -4360,82 +4640,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4405,82 +4685,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return Mth.lerp(delta, this.yRotO, this.yRot); } @@ -29047,7 +29034,7 @@ index 3d4bb855dec45685d6e336d913903341f0ca4a11..4e005543cba9cfad6aeb39094cb856f5 public boolean touchingUnloadedChunk() { AABB axisalignedbb = this.getBoundingBox().inflate(1.0D); -@@ -4587,6 +4921,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4632,6 +4966,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.setPosRaw(x, y, z, false); } public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) { @@ -29063,7 +29050,7 @@ index 3d4bb855dec45685d6e336d913903341f0ca4a11..4e005543cba9cfad6aeb39094cb856f5 if (!checkPosition(this, x, y, z)) { return; } -@@ -4716,6 +5059,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4761,6 +5104,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public final void setRemoved(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { @@ -29076,7 +29063,7 @@ index 3d4bb855dec45685d6e336d913903341f0ca4a11..4e005543cba9cfad6aeb39094cb856f5 CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit end final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers -@@ -4727,7 +5076,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4772,7 +5121,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.stopRiding(); } @@ -29085,7 +29072,7 @@ index 3d4bb855dec45685d6e336d913903341f0ca4a11..4e005543cba9cfad6aeb39094cb856f5 this.levelCallback.onRemove(entity_removalreason); this.onRemoval(entity_removalreason); // Paper start - Folia schedulers -@@ -4759,7 +5108,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4804,7 +5153,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public boolean shouldBeSaved() { @@ -29484,7 +29471,7 @@ index e185a33b5b1f8e8e0a0e666b24ba3e9186a8a7ff..5d7a6e4b73f032db356e7ec369b15001 // Paper start - Affects Spawning API diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 1b899473c6deeaa1aef9007d8b7bcec98580e61c..1f4ff796a1f69b9c60d32d407b5579e89433089c 100644 +index ce6c9b82a64a32c4b952d1839260015b1a446365..bb2d3ba2065b6bf67af24a8630ac2d58169fe783 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -83,6 +83,7 @@ import net.minecraft.world.level.storage.LevelData; @@ -29504,7 +29491,7 @@ index 1b899473c6deeaa1aef9007d8b7bcec98580e61c..1f4ff796a1f69b9c60d32d407b5579e8 public static final Codec> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION); public static final ResourceKey OVERWORLD = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld")); -@@ -200,7 +201,639 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -207,7 +208,639 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public abstract ResourceKey getTypeKey(); @@ -30131,7 +30118,7 @@ index 1b899473c6deeaa1aef9007d8b7bcec98580e61c..1f4ff796a1f69b9c60d32d407b5579e8 + } + // Paper end - optimise random ticking + - protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator) { // Paper - create paper world config + protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - create paper world config & Anti-Xray + // Paper start - getblock optimisations - cache world height/sections + final DimensionType dimType = holder.value(); + this.minY = dimType.minY(); @@ -30144,15 +30131,15 @@ index 1b899473c6deeaa1aef9007d8b7bcec98580e61c..1f4ff796a1f69b9c60d32d407b5579e8 this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config this.generator = gen; -@@ -281,6 +914,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - this.timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings +@@ -289,6 +922,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime); this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); + this.chunkPacketBlockController = this.paperConfig().anticheat.antiXray.enabled ? new com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray(this, executor) : com.destroystokyo.paper.antixray.ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray + this.entityLookup = new ca.spottedleaf.moonrise.patches.chunk_system.level.entity.dfl.DefaultEntityLookup(this); // Paper - rewrite chunk system } // Paper start - Cancel hit for vanished players -@@ -549,7 +1183,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -558,7 +1192,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.setBlocksDirty(blockposition, iblockdata1, iblockdata2); } @@ -30161,7 +30148,7 @@ index 1b899473c6deeaa1aef9007d8b7bcec98580e61c..1f4ff796a1f69b9c60d32d407b5579e8 this.sendBlockUpdated(blockposition, iblockdata1, iblockdata, i); } -@@ -815,6 +1449,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -824,6 +1458,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Iterator iterator = this.blockEntityTickers.iterator(); boolean flag = this.tickRateManager().runsNormally(); @@ -30170,7 +30157,7 @@ index 1b899473c6deeaa1aef9007d8b7bcec98580e61c..1f4ff796a1f69b9c60d32d407b5579e8 int tilesThisCycle = 0; var toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet(); // Paper - Fix MC-117075; use removeAll toRemove.add(null); // Paper - Fix MC-117075 -@@ -830,6 +1466,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -839,6 +1475,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Spigot end } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { tickingblockentity.tick(); @@ -30182,7 +30169,7 @@ index 1b899473c6deeaa1aef9007d8b7bcec98580e61c..1f4ff796a1f69b9c60d32d407b5579e8 } } this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 -@@ -852,12 +1493,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -861,12 +1502,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable { entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Paper end - Prevent block entity and entity crashes } @@ -30204,7 +30191,7 @@ index 1b899473c6deeaa1aef9007d8b7bcec98580e61c..1f4ff796a1f69b9c60d32d407b5579e8 } // Paper end - Option to prevent armor stands from doing entity lookups -@@ -909,7 +1558,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -918,7 +1567,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } // Paper end - Perf: Optimize capturedTileEntities lookup // CraftBukkit end @@ -30213,7 +30200,7 @@ index 1b899473c6deeaa1aef9007d8b7bcec98580e61c..1f4ff796a1f69b9c60d32d407b5579e8 } public void setBlockEntity(BlockEntity blockEntity) { -@@ -1001,26 +1650,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1010,26 +1659,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable { Profiler.get().incrementCounter("getEntities"); List list = Lists.newArrayList(); @@ -30246,7 +30233,7 @@ index 1b899473c6deeaa1aef9007d8b7bcec98580e61c..1f4ff796a1f69b9c60d32d407b5579e8 } @Override -@@ -1035,36 +1673,94 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1044,36 +1682,94 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.getEntities(filter, box, predicate, result, Integer.MAX_VALUE); } @@ -31364,7 +31351,7 @@ index fcf04c5c58ff35d38c5bf0df562ae2f8dc98a0ee..0b116160924300a9d62ad5948bfaf276 public Property.Value value(T value) { diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -index 37795b9e264c571efe9c718fa9996197dca4ed54..0601f454758cb1447cca2cbff4ef5fd7633fece5 100644 +index 63d7d6b93119d96d753230472df30a9dedd889dc..a402e2f774cfc062afab8d86969f3e6f38874063 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java @@ -57,7 +57,7 @@ import net.minecraft.world.ticks.SavedTick; @@ -31453,7 +31440,7 @@ index 37795b9e264c571efe9c718fa9996197dca4ed54..0601f454758cb1447cca2cbff4ef5fd7 if (this.sections.length == sectionArray.length) { System.arraycopy(sectionArray, 0, this.sections, 0, this.sections.length); @@ -111,6 +162,16 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh - ChunkAccess.replaceMissingSections(biomeRegistry, this.sections); + this.replaceMissingSections(biomeRegistry, this.sections); // Paper - Anti-Xray - make it a non-static method // CraftBukkit start this.biomeRegistry = biomeRegistry; + // Paper start - rewrite chunk system @@ -31469,7 +31456,7 @@ index 37795b9e264c571efe9c718fa9996197dca4ed54..0601f454758cb1447cca2cbff4ef5fd7 } public final Registry biomeRegistry; // CraftBukkit end -@@ -451,22 +512,22 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh +@@ -452,22 +513,22 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh @Override public Holder getNoiseBiome(int biomeX, int biomeY, int biomeZ) { @@ -31507,7 +31494,7 @@ index 37795b9e264c571efe9c718fa9996197dca4ed54..0601f454758cb1447cca2cbff4ef5fd7 } // CraftBukkit start -@@ -523,12 +584,12 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh +@@ -524,12 +585,12 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh } public void initializeLightSources() { @@ -31523,7 +31510,7 @@ index 37795b9e264c571efe9c718fa9996197dca4ed54..0601f454758cb1447cca2cbff4ef5fd7 public static record PackedTicks(List> blocks, List> fluids) { diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index 4cbc68d8e950f8d7c8b00535b82e916964c88ce0..12148b80794f620799e44f59f0251bb27e74f2c9 100644 +index 582065b2d4e818c0edec36b2e9847f8ed3266b10..b5114f84b2df2f4606702b892d32d484225d9dcf 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -119,7 +119,7 @@ public abstract class ChunkGenerator { @@ -31624,7 +31611,7 @@ index 98dbeaf8bde15940e5b5d5d1f13fd4bb32f0a10d..7beea075b5a7ef738a4ac0558b99f4c5 this(idList, bits, listener); entries.forEach(this.values::add); diff --git a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java -index 7cce66d4c6efe6fd3cc22a6acf72878c964c61ae..30ee3df2278d0d9bd7478b49eda5fff27b8a504c 100644 +index f38700e5fbeeb8a913272d4464b8aa325d511dac..1eb8022f3e31603322e6c56516304afc9a11bbec 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java @@ -30,7 +30,7 @@ import net.minecraft.world.level.material.FluidState; @@ -31686,7 +31673,7 @@ index 7cce66d4c6efe6fd3cc22a6acf72878c964c61ae..30ee3df2278d0d9bd7478b49eda5fff2 @Override public BlockEntity getBlockEntity(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 325d1e38a72a4b30f30261267e9adfb8a8726b11..86b018042590c3ce115555639e7791c521cecffc 100644 +index 71dfd0abb930ecf4f1ba900c80c161fa2a858685..e03d57f58a9f962cd429e8851fb3f35f3491e2c0 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -54,7 +54,7 @@ import net.minecraft.world.ticks.LevelChunkTicks; @@ -31865,7 +31852,7 @@ index 325d1e38a72a4b30f30261267e9adfb8a8726b11..86b018042590c3ce115555639e7791c5 @Nullable diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -index 52f44f14bbda60fe771c351e01e6ff470d7371e6..b85f354afa23ddf7e24facdb0516407ee2725bee 100644 +index 3dab36d00ea48101807ba40c7a7358b7eed12747..e4ae25c83ab9dd1aaa530a5456275ef63cdb8511 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java @@ -13,7 +13,7 @@ import net.minecraft.world.level.block.Blocks; @@ -31908,7 +31895,7 @@ index 52f44f14bbda60fe771c351e01e6ff470d7371e6..b85f354afa23ddf7e24facdb0516407e private LevelChunkSection(LevelChunkSection section) { this.nonEmptyBlockCount = section.nonEmptyBlockCount; this.tickingBlockCount = section.tickingBlockCount; -@@ -64,6 +88,45 @@ public class LevelChunkSection { +@@ -67,6 +91,45 @@ public class LevelChunkSection { return this.setBlockState(x, y, z, state, true); } @@ -31954,7 +31941,7 @@ index 52f44f14bbda60fe771c351e01e6ff470d7371e6..b85f354afa23ddf7e24facdb0516407e public BlockState setBlockState(int x, int y, int z, BlockState state, boolean lock) { BlockState iblockdata1; -@@ -83,7 +146,7 @@ public class LevelChunkSection { +@@ -86,7 +149,7 @@ public class LevelChunkSection { } } @@ -31963,7 +31950,7 @@ index 52f44f14bbda60fe771c351e01e6ff470d7371e6..b85f354afa23ddf7e24facdb0516407e --this.tickingFluidCount; } -@@ -94,10 +157,12 @@ public class LevelChunkSection { +@@ -97,10 +160,12 @@ public class LevelChunkSection { } } @@ -31977,7 +31964,7 @@ index 52f44f14bbda60fe771c351e01e6ff470d7371e6..b85f354afa23ddf7e24facdb0516407e return iblockdata1; } -@@ -118,40 +183,70 @@ public class LevelChunkSection { +@@ -121,40 +186,70 @@ public class LevelChunkSection { } public void recalcBlockCounts() { @@ -32069,7 +32056,7 @@ index 52f44f14bbda60fe771c351e01e6ff470d7371e6..b85f354afa23ddf7e24facdb0516407e } public PalettedContainer getStates() { -@@ -169,6 +264,11 @@ public class LevelChunkSection { +@@ -172,6 +267,11 @@ public class LevelChunkSection { datapaletteblock.read(buf); this.biomes = datapaletteblock; @@ -32121,19 +32108,19 @@ index b8922e4a13df535cdc5701e893a6e460b33ff90d..100807f8b8337f56f49cdb818ccc75be boolean maybeHas(Predicate predicate); diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -index 112d1259dd37743076ff6c67ffd711d084ba8698..533167eaa8bd39006fb1c7e193c81359973da9af 100644 +index 69d6f203366df658e1ade55d917f0aa2b8a49be9..8b84bf2272556ac3321cbf16361d7f48a1cc6873 100644 --- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -@@ -28,7 +28,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - private static final int MIN_PALETTE_BITS = 0; +@@ -29,7 +29,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer private final PaletteResize dummyPaletteResize = (newSize, added) -> 0; public final IdMap registry; + private final T @org.jetbrains.annotations.Nullable [] presetValues; // Paper - Anti-Xray - Add preset values - private volatile PalettedContainer.Data data; + public volatile PalettedContainer.Data data; // Paper - optimise collisions - public private final PalettedContainer.Strategy strategy; // private final ThreadingDetector threadingDetector = new ThreadingDetector("PalettedContainer"); // Paper - unused -@@ -71,6 +71,33 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -77,6 +77,33 @@ public class PalettedContainer implements PaletteResize, PalettedContainer ); } @@ -32164,25 +32151,26 @@ index 112d1259dd37743076ff6c67ffd711d084ba8698..533167eaa8bd39006fb1c7e193c81359 + } + // Paper end - optimise palette reads + + // Paper start - Anti-Xray - Add preset values + @Deprecated @io.papermc.paper.annotation.DoNotUse public PalettedContainer(IdMap idList, PalettedContainer.Strategy paletteProvider, PalettedContainer.Configuration dataProvider, BitStorage storage, List paletteEntries) { this(idList, paletteProvider, dataProvider, storage, paletteEntries, null, null); } public PalettedContainer( - IdMap idList, - PalettedContainer.Strategy paletteProvider, -@@ -81,12 +108,14 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - this.registry = idList; - this.strategy = paletteProvider; - this.data = new PalettedContainer.Data<>(dataProvider, storage, dataProvider.factory().create(dataProvider.bits(), idList, this, paletteEntries)); +@@ -113,6 +140,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + } + } + // Paper end + this.updateData(this.data); // Paper - optimise palette reads } - private PalettedContainer(IdMap idList, PalettedContainer.Strategy paletteProvider, PalettedContainer.Data data) { + // Paper start - Anti-Xray - Add preset values +@@ -122,6 +150,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer this.registry = idList; this.strategy = paletteProvider; this.data = data; + this.updateData(this.data); // Paper - optimise palette reads } - private PalettedContainer(PalettedContainer container) { -@@ -100,6 +129,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + private PalettedContainer(PalettedContainer container, T @org.jetbrains.annotations.Nullable [] presetValues) { // Paper - Anti-Xray - Add preset values +@@ -140,6 +169,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer this.registry = idList; this.data = this.createOrReuseData(null, 0); this.data.palette.idFor(object); @@ -32190,15 +32178,15 @@ index 112d1259dd37743076ff6c67ffd711d084ba8698..533167eaa8bd39006fb1c7e193c81359 } private PalettedContainer.Data createOrReuseData(@Nullable PalettedContainer.Data previousData, int bits) { -@@ -115,6 +145,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - PalettedContainer.Data data2 = this.createOrReuseData(data, newBits); +@@ -166,6 +196,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer data2.copyFrom(data.palette, data.storage); this.data = data2; + this.addPresetValues(); + this.updateData(this.data); // Paper - optimise palette reads - return data2.palette.idFor(object); + return object == null ? -1 : data2.palette.idFor(object); + // Paper end } - -@@ -136,9 +167,12 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -198,9 +229,12 @@ public class PalettedContainer implements PaletteResize, PalettedContainer } private synchronized T getAndSet(int index, T value) { // Paper - synchronize @@ -32214,7 +32202,7 @@ index 112d1259dd37743076ff6c67ffd711d084ba8698..533167eaa8bd39006fb1c7e193c81359 } public void set(int x, int y, int z, T value) { -@@ -161,9 +195,11 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -223,9 +257,11 @@ public class PalettedContainer implements PaletteResize, PalettedContainer return this.get(this.strategy.getIndex(x, y, z)); } @@ -32229,15 +32217,15 @@ index 112d1259dd37743076ff6c67ffd711d084ba8698..533167eaa8bd39006fb1c7e193c81359 } @Override -@@ -183,6 +219,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - data.palette.read(buf); +@@ -246,6 +282,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer buf.readLongArray(data.storage.getRaw()); this.data = data; + this.addPresetValues(); // Paper - Anti-Xray - Add preset values (inefficient, but this isn't used by the server) + this.updateData(this.data); // Paper - optimise palette reads } finally { this.release(); } -@@ -323,7 +360,44 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -394,7 +431,44 @@ public class PalettedContainer implements PaletteResize, PalettedContainer void accept(T object, int count); } @@ -32284,10 +32272,10 @@ index 112d1259dd37743076ff6c67ffd711d084ba8698..533167eaa8bd39006fb1c7e193c81359 for (int i = 0; i < storage.getSize(); i++) { T object = palette.valueFor(storage.get(i)); diff --git a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java -index 5321109ca638036572df9a7e17eafcef2b4f5112..5304254587372465c8ce821d7aa38b39a979f46b 100644 +index 4d5704df4a7ac6e148774f1a986d46bfb7e95f95..360edef3634bc61f36e41d63d168449df5d50933 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java -@@ -145,7 +145,7 @@ public class ProtoChunk extends ChunkAccess { +@@ -149,7 +149,7 @@ public class ProtoChunk extends ChunkAccess { } if (LightEngine.hasDifferentLightProperties(blockState, state)) { @@ -32750,10 +32738,10 @@ index cb823d342e41b5861adfc847a313c265fb702a4c..2b1ea97199d5976e5ff4bd049c1e6c8b private final Long2ObjectLinkedOpenHashMap> regionCacheForBlender = new Long2ObjectLinkedOpenHashMap<>(); private static final int REGION_CACHE_SIZE = 1024; 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 e858436bcf1b234d4bc6e6a117f5224d5c2d9f90..47560d1763d2e70e609cec63ea2defde3d012eb1 100644 +index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..e9e1ab1a5be996bc648a53dc4d4123a6b966c437 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 -@@ -25,7 +25,7 @@ import net.minecraft.util.profiling.jfr.JvmProfiler; +@@ -28,7 +28,7 @@ import net.minecraft.nbt.NbtIo; // Paper import net.minecraft.world.level.ChunkPos; import org.slf4j.Logger; @@ -32762,7 +32750,7 @@ index e858436bcf1b234d4bc6e6a117f5224d5c2d9f90..47560d1763d2e70e609cec63ea2defde private static final Logger LOGGER = LogUtils.getLogger(); private static final int SECTOR_BYTES = 4096; -@@ -49,6 +49,21 @@ public class RegionFile implements AutoCloseable { +@@ -52,6 +52,21 @@ public class RegionFile implements AutoCloseable { @VisibleForTesting protected final RegionBitmap usedSectors; @@ -32784,7 +32772,7 @@ index e858436bcf1b234d4bc6e6a117f5224d5c2d9f90..47560d1763d2e70e609cec63ea2defde public RegionFile(RegionStorageInfo storageKey, Path directory, Path path, boolean dsync) throws IOException { this(storageKey, directory, path, RegionFileVersion.getCompressionFormat(), dsync); // Paper - Configurable region compression format } -@@ -220,6 +235,16 @@ public class RegionFile implements AutoCloseable { +@@ -224,6 +239,16 @@ public class RegionFile implements AutoCloseable { @Nullable private DataInputStream createExternalChunkInputStream(ChunkPos pos, byte flags) throws IOException { @@ -32801,10 +32789,10 @@ index e858436bcf1b234d4bc6e6a117f5224d5c2d9f90..47560d1763d2e70e609cec63ea2defde Path path = this.getExternalChunkPath(pos); if (!Files.isRegularFile(path, new LinkOption[0])) { -@@ -443,10 +468,29 @@ public class RegionFile implements AutoCloseable { - } +@@ -515,10 +540,29 @@ public class RegionFile implements AutoCloseable { - public static final int MAX_CHUNK_SIZE = 500 * 1024 * 1024; // Paper - don't write garbage data to disk if writing serialization fails + } + // Paper end - private class ChunkBuffer extends ByteArrayOutputStream { + private class ChunkBuffer extends ByteArrayOutputStream implements ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkBuffer { // Paper - rewrite chunk system @@ -32832,7 +32820,7 @@ index e858436bcf1b234d4bc6e6a117f5224d5c2d9f90..47560d1763d2e70e609cec63ea2defde public ChunkBuffer(final ChunkPos chunkcoordintpair) { super(8096); super.write(0); -@@ -480,7 +524,7 @@ public class RegionFile implements AutoCloseable { +@@ -552,7 +596,7 @@ public class RegionFile implements AutoCloseable { JvmProfiler.INSTANCE.onRegionFileWrite(RegionFile.this.info, this.pos, RegionFile.this.version, i); bytebuffer.putInt(0, i); @@ -32842,7 +32830,7 @@ index e858436bcf1b234d4bc6e6a117f5224d5c2d9f90..47560d1763d2e70e609cec63ea2defde } 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 4c1212c6ef48594e766fa9e35a6e15916602d587..9dbc9e2f9d5aab71720bb81803efe76e2f361f04 100644 +index 2a0f7ab0b616fe07baac437372e3933186064dd5..2d5c1b91b814316bf9f2f22bcd30adacc8970b01 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 @@ -17,7 +17,7 @@ import net.minecraft.nbt.StreamTagVisitor; @@ -33089,8 +33077,8 @@ index 4c1212c6ef48594e766fa9e35a6e15916602d587..9dbc9e2f9d5aab71720bb81803efe76e + // Paper end - rewrite chunk system } - @Nullable -@@ -132,8 +318,14 @@ public final class RegionFileStorage implements AutoCloseable { + // Paper start +@@ -175,8 +361,14 @@ public final class RegionFileStorage implements AutoCloseable { } @@ -33107,7 +33095,7 @@ index 4c1212c6ef48594e766fa9e35a6e15916602d587..9dbc9e2f9d5aab71720bb81803efe76e // Paper start - Chunk save reattempt int attempts = 0; Exception lastException = null; -@@ -182,30 +374,37 @@ public final class RegionFileStorage implements AutoCloseable { +@@ -226,30 +418,37 @@ public final class RegionFileStorage implements AutoCloseable { } public void close() throws IOException { @@ -33298,10 +33286,10 @@ index 93972352cd4881dccba9b90ccc8dcced3563e340..c3beb7fcad46a917d2b61bd0a0e98e51 static record PackedChunk(Int2ObjectMap sectionsByY, boolean versionChanged) { diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index b86b3bf713668999a21c4120b1d16c295531b2ad..eb8f5d2efe7c32ddda4763e2ebe0653050101efd 100644 +index eba3e34e5b129050bf6eaed6ce4e690357a3de20..83c87b56205b68010016b58b7f6e4d02f1fa5681 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -@@ -128,7 +128,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -129,7 +129,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun long j = nbt.getLong("InhabitedTime"); ChunkStatus chunkstatus = ChunkStatus.byName(nbt.getString("Status")); UpgradeData chunkconverter = nbt.contains("UpgradeData", 10) ? new UpgradeData(nbt.getCompound("UpgradeData"), world) : UpgradeData.EMPTY; @@ -33310,7 +33298,7 @@ index b86b3bf713668999a21c4120b1d16c295531b2ad..eb8f5d2efe7c32ddda4763e2ebe06530 DataResult dataresult; Logger logger; BlendingData.Packed blendingdata_d; -@@ -208,7 +208,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -209,7 +209,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun Codec>> codec = makeBiomeCodecRW(iregistry); // CraftBukkit - read/write for (int i1 = 0; i1 < nbttaglist2.size(); ++i1) { @@ -33319,7 +33307,7 @@ index b86b3bf713668999a21c4120b1d16c295531b2ad..eb8f5d2efe7c32ddda4763e2ebe06530 byte b0 = nbttagcompound3.getByte("Y"); LevelChunkSection chunksection; -@@ -241,7 +241,17 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -246,7 +246,17 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun DataLayer nibblearray = nbttagcompound3.contains("BlockLight", 7) ? new DataLayer(nbttagcompound3.getByteArray("BlockLight")) : null; DataLayer nibblearray1 = nbttagcompound3.contains("SkyLight", 7) ? new DataLayer(nbttagcompound3.getByteArray("SkyLight")) : null; @@ -33338,7 +33326,7 @@ index b86b3bf713668999a21c4120b1d16c295531b2ad..eb8f5d2efe7c32ddda4763e2ebe06530 } // CraftBukkit - ChunkBukkitValues -@@ -249,6 +259,47 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -254,6 +264,47 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun } } @@ -33386,7 +33374,7 @@ index b86b3bf713668999a21c4120b1d16c295531b2ad..eb8f5d2efe7c32ddda4763e2ebe06530 public ProtoChunk read(ServerLevel world, PoiManager poiStorage, RegionStorageInfo key, ChunkPos expectedPos) { if (!Objects.equals(expectedPos, this.chunkPos)) { SerializableChunkData.LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", new Object[]{expectedPos, expectedPos, this.chunkPos}); -@@ -270,7 +321,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -275,7 +326,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun if (serializablechunkdata_b.chunkSection != null) { achunksection[world.getSectionIndexFromSectionY(serializablechunkdata_b.y)] = serializablechunkdata_b.chunkSection; @@ -33395,7 +33383,7 @@ index b86b3bf713668999a21c4120b1d16c295531b2ad..eb8f5d2efe7c32ddda4763e2ebe06530 } boolean flag2 = serializablechunkdata_b.blockLight != null; -@@ -347,7 +398,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -352,7 +403,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun } if (chunktype == ChunkType.LEVELCHUNK) { @@ -33404,7 +33392,7 @@ index b86b3bf713668999a21c4120b1d16c295531b2ad..eb8f5d2efe7c32ddda4763e2ebe06530 } else { ProtoChunk protochunk1 = (ProtoChunk) object; Iterator iterator2 = this.entities.iterator(); -@@ -377,7 +428,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -382,7 +433,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun protochunk1.setCarvingMask(new CarvingMask(this.carvingMask, ((ChunkAccess) object).getMinY())); } @@ -33413,7 +33401,7 @@ index b86b3bf713668999a21c4120b1d16c295531b2ad..eb8f5d2efe7c32ddda4763e2ebe06530 } } -@@ -400,24 +451,48 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -405,24 +456,48 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun throw new IllegalArgumentException("Chunk can't be serialized: " + String.valueOf(chunk)); } else { ChunkPos chunkcoordintpair = chunk.getPos(); @@ -33473,7 +33461,7 @@ index b86b3bf713668999a21c4120b1d16c295531b2ad..eb8f5d2efe7c32ddda4763e2ebe06530 List list1 = new ArrayList(chunk.getBlockEntitiesPos().size()); Iterator iterator = chunk.getBlockEntitiesPos().iterator(); -@@ -516,8 +591,8 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -521,8 +596,8 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun Iterator iterator = this.sectionData.iterator(); while (iterator.hasNext()) { @@ -33484,7 +33472,7 @@ index b86b3bf713668999a21c4120b1d16c295531b2ad..eb8f5d2efe7c32ddda4763e2ebe06530 LevelChunkSection chunksection = serializablechunkdata_b.chunkSection; if (chunksection != null) { -@@ -533,6 +608,19 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -538,6 +613,19 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun nbttagcompound1.putByteArray("SkyLight", serializablechunkdata_b.skyLight.getData()); } @@ -33504,7 +33492,7 @@ index b86b3bf713668999a21c4120b1d16c295531b2ad..eb8f5d2efe7c32ddda4763e2ebe06530 if (!nbttagcompound1.isEmpty()) { nbttagcompound1.putByte("Y", (byte) serializablechunkdata_b.y); nbttaglist.add(nbttagcompound1); -@@ -572,6 +660,14 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -577,6 +665,14 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun nbttagcompound.put("ChunkBukkitValues", this.persistentDataContainer); } // CraftBukkit end @@ -33519,7 +33507,7 @@ index b86b3bf713668999a21c4120b1d16c295531b2ad..eb8f5d2efe7c32ddda4763e2ebe06530 return nbttagcompound; } -@@ -758,7 +854,67 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -763,7 +859,67 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun return nbttaglist; } @@ -33674,7 +33662,7 @@ index 74a285b8b018a9c94ccea519f1ce8b9e2ef3cb64..d8b4196adf955f8d414688dc451caac2 } } diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -index 44e64d716eee71492f9a8d813934bb96463ece45..d52fcb82fdeab5b2e95b97a876c6e6701f569013 100644 +index 1fcc2b287ed723cf51720f80e68f18f4a15cf429..3f39d6c786d9dfdd9ad591e08ff05fcbb41a1df6 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java @@ -86,7 +86,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { @@ -34535,7 +34523,7 @@ index 7ec02a7849437a18860aa0df7d9ddd71b2447d4c..5e45e49ab09344cb95736f4124b1c6e0 public OffsetDoubleList(DoubleList oldList, double offset) { this.delegate = oldList; diff --git a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java -index 5a0b0b47da3d796c391ac15eb573af25a1dfcd32..513bed7f11aee667c87046db4cf912b80e8f3638 100644 +index 76d7435e6fe81a3f1d24b35eae72d06232a1792b..ca3a2419252721bb3b3b719eb19afb5f175394c0 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java +++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java @@ -16,9 +16,15 @@ public final class Shapes { @@ -35941,7 +35929,7 @@ index 26620c06d26a2c0eb957fbadc6ac3d7a309bff46..3858c83c58e78435a6e29de84c33faa2 for (SavedTick savedTick : this.pendingTicks) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java -index 5fc9e8e969debb3e15ed474b36a1c48b086d0449..47424d897ba706bc5f80ab563de130c873ccff2f 100644 +index f65cc95ab28e8a3b21eac2b16bd9ebe97e56e571..0074bc0e7147dc3a8c538e796f14ac9bf8725896 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -82,6 +82,12 @@ public class CraftChunk implements Chunk { @@ -36021,7 +36009,7 @@ index 5fc9e8e969debb3e15ed474b36a1c48b086d0449..47424d897ba706bc5f80ab563de130c8 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 6235d7caede85f4cf21dadde18d8080004672349..bfa2fc2e1ca9b68f5bf8b2e1ba6db4692ef4f73e 100644 +index 8348ab336029848eab1cbe9b67b056abf1f5866f..a34e40e273a79a234c3d79b6ad360ce3a4d35ba3 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1421,7 +1421,7 @@ public final class CraftServer implements Server { @@ -36052,10 +36040,10 @@ index 6235d7caede85f4cf21dadde18d8080004672349..bfa2fc2e1ca9b68f5bf8b2e1ba6db469 // Paper start - Adventure diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 149377347fc632358a8bb97e644b1c4ab9be413d..2cef4788cce4467ba87d7982dbc559215917bce0 100644 +index b2eb8cf1de3b4b81587531bb4c0d4b512f5d5d5d..d4800a19d91562d6c55ac9bc5ed33a2c0de5a34f 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -467,10 +467,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -508,10 +508,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z)); if (playerChunk == null) return false; @@ -36071,11 +36059,11 @@ index 149377347fc632358a8bb97e644b1c4ab9be413d..2cef4788cce4467ba87d7982dbc55921 - if (playersInRange.isEmpty()) return; + if (playersInRange.isEmpty()) return true; // Paper - chunk system - ClientboundLevelChunkWithLightPacket refreshPacket = new ClientboundLevelChunkWithLightPacket(chunk, this.world.getLightEngine(), null, null); - for (ServerPlayer player : playersInRange) { -@@ -478,8 +482,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { - - player.connection.send(refreshPacket); + // Paper start - Anti-Xray bypass + final Map refreshPackets = new HashMap<>(); +@@ -524,8 +528,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { + })); + // Paper end - Anti-Xray bypass } - }); - }); @@ -36083,7 +36071,7 @@ index 149377347fc632358a8bb97e644b1c4ab9be413d..2cef4788cce4467ba87d7982dbc55921 return true; } -@@ -583,20 +586,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -629,20 +632,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public Collection getPluginChunkTickets(int x, int z) { DistanceManager chunkDistanceManager = this.world.getChunkSource().chunkMap.distanceManager; @@ -36105,7 +36093,7 @@ index 149377347fc632358a8bb97e644b1c4ab9be413d..2cef4788cce4467ba87d7982dbc55921 } @Override -@@ -604,7 +595,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -650,7 +641,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { Map> ret = new HashMap<>(); DistanceManager chunkDistanceManager = this.world.getChunkSource().chunkMap.distanceManager; @@ -36114,7 +36102,7 @@ index 149377347fc632358a8bb97e644b1c4ab9be413d..2cef4788cce4467ba87d7982dbc55921 long chunkKey = chunkTickets.getLongKey(); SortedArraySet> tickets = chunkTickets.getValue(); -@@ -1307,12 +1298,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1353,12 +1344,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public int getViewDistance() { @@ -36129,7 +36117,7 @@ index 149377347fc632358a8bb97e644b1c4ab9be413d..2cef4788cce4467ba87d7982dbc55921 } public BlockMetadataStore getBlockMetadata() { -@@ -2453,17 +2444,20 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2496,17 +2487,20 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void setSimulationDistance(final int simulationDistance) { @@ -36154,10 +36142,10 @@ index 149377347fc632358a8bb97e644b1c4ab9be413d..2cef4788cce4467ba87d7982dbc55921 // Paper start - implement pointers diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 8d16575c74b81ada4e4efe70e8f077f07cd0a3f0..d010e34543474fe5d108b2e862041c5921ab97dd 100644 +index d5dc7ecb9c4dddfd2c92d89b27c15512a0822b08..ed29e06422aa5e73adfaf9578cda3dfc5777f64c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3523,7 +3523,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3531,7 +3531,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setViewDistance(final int viewDistance) { @@ -36168,7 +36156,7 @@ index 8d16575c74b81ada4e4efe70e8f077f07cd0a3f0..d010e34543474fe5d108b2e862041c59 } @Override -@@ -3533,7 +3535,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3541,7 +3543,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setSimulationDistance(final int simulationDistance) { @@ -36179,7 +36167,7 @@ index 8d16575c74b81ada4e4efe70e8f077f07cd0a3f0..d010e34543474fe5d108b2e862041c59 } @Override -@@ -3543,6 +3547,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3551,7 +3555,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setSendViewDistance(final int viewDistance) { @@ -36188,7 +36176,8 @@ index 8d16575c74b81ada4e4efe70e8f077f07cd0a3f0..d010e34543474fe5d108b2e862041c59 + ((ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer)this.getHandle()) + .moonrise$getViewDistanceHolder().setSendViewDistance(viewDistance); } - } + + // Paper start - entity effect API diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java index 625562a38bc78feae3ae4b50b9afefbd05ff767a..e34060c21755c61228ba91e468b7c92fc4c4cf0c 100644 --- a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java diff --git a/patches/server/2979-fixup-Timings-v2.patch b/patches/server/2979-fixup-Timings-v2.patch deleted file mode 100644 index f2b8af09f436..000000000000 --- a/patches/server/2979-fixup-Timings-v2.patch +++ /dev/null @@ -1,18 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Thu, 24 Oct 2024 11:17:10 -0700 -Subject: [PATCH] fixup! Timings v2 - - -diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 7e5714fea4cda68b9ae21031c0e0d39061b07e2f..350bfa9c891130b1aa2ab973e86668de187ee1e0 100644 ---- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java -+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -427,7 +427,6 @@ public class ServerChunkCache extends ChunkSource { - gameprofilerfiller.pop(); - this.clearCache(); - } -- if (this.level.getServer().tickRateManager().runsNormally()) this.level.timings.chunkTicks.startTiming(); // Paper - - private void tickChunks() { - long i = this.level.getGameTime(); From 9ecf77e8841ac9c9ef26e6e6c9dc05d3d76638eb Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 25 Oct 2024 11:46:53 -0700 Subject: [PATCH 074/119] Fix compile issues --- patches/server/1039-fixup-MC-Utils.patch | 19 +++++++++++++++++++ .../1043-Moonrise-optimisation-patches.patch | 10 +++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/patches/server/1039-fixup-MC-Utils.patch b/patches/server/1039-fixup-MC-Utils.patch index 06f2a7898c20..b3d1e1136d03 100644 --- a/patches/server/1039-fixup-MC-Utils.patch +++ b/patches/server/1039-fixup-MC-Utils.patch @@ -1329,6 +1329,25 @@ index 6baa313b8201ed23193d7885c85606b0899ade3c..5aa74c00a61282830d82359eae2b114e } // Paper end - chunk system hooks if (!this.addEntityUuid(entity)) { +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index b2eb8cf1de3b4b81587531bb4c0d4b512f5d5d5d..6dc3fc701d1e16a51d99f934ea3dc192363a6762 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -2466,11 +2466,11 @@ public class CraftWorld extends CraftRegionAccessor implements World { + } + } + +- ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority; ++ ca.spottedleaf.concurrentutil.util.Priority priority; + if (urgent) { +- priority = ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER; ++ priority = ca.spottedleaf.concurrentutil.util.Priority.HIGHER; + } else { +- priority = ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL; ++ priority = ca.spottedleaf.concurrentutil.util.Priority.NORMAL; + } + + java.util.concurrent.CompletableFuture ret = new java.util.concurrent.CompletableFuture<>(); diff --git a/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks b/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks new file mode 100644 index 0000000000000000000000000000000000000000..e57c3ca79677b1dfe7cf3db36f0406de7ea5bd0a diff --git a/patches/server/1043-Moonrise-optimisation-patches.patch b/patches/server/1043-Moonrise-optimisation-patches.patch index 6c028f78a60a..3f638ea9d165 100644 --- a/patches/server/1043-Moonrise-optimisation-patches.patch +++ b/patches/server/1043-Moonrise-optimisation-patches.patch @@ -9288,7 +9288,7 @@ index 0000000000000000000000000000000000000000..f3c453773e0413276935ca653b60bbe6 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java new file mode 100644 -index 0000000000000000000000000000000000000000..381631e405895ba3eede1cd2e1011c64aadbd662 +index 0000000000000000000000000000000000000000..eafa4e6d55cd0f9314ac0f2b96a7f48fbb5e1a4c --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java @@ -0,0 +1,1998 @@ @@ -10372,7 +10372,7 @@ index 0000000000000000000000000000000000000000..381631e405895ba3eede1cd2e1011c64 + } + + // Don't really have a choice but to place this hook here -+ PlatformHooks.get().onChunkHolderTicketChange(this.world, this, oldLevel, newLevel); ++ PlatformHooks.get().onChunkHolderTicketChange(this.world, this.vanillaChunkHolder, oldLevel, newLevel); + } + + static final int NEIGHBOUR_RADIUS = 2; @@ -14055,7 +14055,7 @@ index 0000000000000000000000000000000000000000..4538ccfaea83d217ed85eaf16e82393c +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java new file mode 100644 -index 0000000000000000000000000000000000000000..e0a88615a8b6d58191f29b1ff1a26427f0a4c1a6 +index 0000000000000000000000000000000000000000..1440c9e2b106616884edcb20201113320817ed9f --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java @@ -0,0 +1,494 @@ @@ -14401,7 +14401,7 @@ index 0000000000000000000000000000000000000000..e0a88615a8b6d58191f29b1ff1a26427 + + try { + // run converters -+ final CompoundTag converted = this.world.getChunkSource().chunkMap.upgradeChunkTag(data); ++ final CompoundTag converted = this.world.getChunkSource().chunkMap.upgradeChunkTag(data, new ChunkPos(this.chunkX, this.chunkZ)); // Paper + + // unpack the data + final SerializableChunkData chunkData = SerializableChunkData.parse( @@ -36040,7 +36040,7 @@ index 8348ab336029848eab1cbe9b67b056abf1f5866f..a34e40e273a79a234c3d79b6ad360ce3 // Paper start - Adventure diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index b2eb8cf1de3b4b81587531bb4c0d4b512f5d5d5d..d4800a19d91562d6c55ac9bc5ed33a2c0de5a34f 100644 +index 6dc3fc701d1e16a51d99f934ea3dc192363a6762..2058671a77cac4cfa6494461a5142abae14402b6 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -508,10 +508,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { From 62e3bcdc3bb7da4d268038e7d06c25fab01b3e2c Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 25 Oct 2024 12:11:20 -0700 Subject: [PATCH 075/119] Review patch-to-patch diff Looks OK --- moonrise_update_1_21_2.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/moonrise_update_1_21_2.txt b/moonrise_update_1_21_2.txt index 27f8176a6ec7..48e29a4a8254 100644 --- a/moonrise_update_1_21_2.txt +++ b/moonrise_update_1_21_2.txt @@ -1,4 +1,3 @@ todo: -- need to compare the patch diff for moonrise - in ChunkEntitySlices, implement modifySavedEntities() by copying from old - port poi_lookup? From b711764991073ae1556969a9a86a4501c8767be0 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 25 Oct 2024 12:24:15 -0700 Subject: [PATCH 076/119] Rebase fixups --- patches/server/0005-Paper-config-files.patch | 60 +- patches/server/0007-ConcurrentUtil.patch | 12734 ++++++++-------- patches/server/0009-MC-Utils.patch | 998 +- patches/server/0010-Adventure.patch | 2 +- patches/server/0023-Timings-v2.patch | 2 +- patches/server/0036-Entity-Origin-API.patch | 2 +- patches/server/0045-Disable-thunder.patch | 2 +- .../server/0046-Disable-ice-and-snow.patch | 2 +- ...le-spawn-chances-for-skeleton-horses.patch | 2 +- ...ckPhysicsEvent-if-a-plugin-has-a-lis.patch | 2 +- ...Entity-AddTo-RemoveFrom-World-Events.patch | 2 +- ...g-BlockPlaceEvent-triggering-physics.patch | 2 +- .../0101-Fix-global-sound-handling.patch | 2 +- ...rovide-E-TE-Chunk-count-stat-methods.patch | 2 +- ...ld.spawnParticle-API-and-add-Builder.patch | 4 +- .../server/0202-Expand-Explosions-API.patch | 4 +- ...6-Implement-World.getEntity-UUID-API.patch | 2 +- .../0207-InventoryCloseEvent-Reason-API.patch | 2 +- ...ies-option-to-debug-dupe-uuid-issues.patch | 2 +- ...ptimize-BlockPosition-helper-methods.patch | 14 +- ...loadChunk-int-int-false-load-unconve.patch | 2 +- patches/server/0252-Add-sun-related-API.patch | 2 +- ...nd-additions-to-the-spawn-reason-API.patch | 2 +- .../0297-Duplicate-UUID-Resolve-Option.patch | 2 +- ...ptimise-EntityGetter-getPlayerByUUID.patch | 2 +- .../0310-Add-debug-for-sync-chunk-loads.patch | 2 +- ...-PlayerChunkMap-adds-crashing-server.patch | 2 +- ...ld-Difficulty-Remembering-Difficulty.patch | 2 +- ...-Plugin-Tickets-to-API-Chunk-Methods.patch | 2 +- ...geEvent-not-firing-for-all-use-cases.patch | 4 +- ...p-capture-to-capture-all-items-added.patch | 2 +- .../0456-Add-WorldGameRuleChangeEvent.patch | 2 +- patches/server/0464-Remove-stale-POIs.patch | 2 +- patches/server/0480-Add-EntityMoveEvent.patch | 2 +- ...disable-pathfinding-updates-on-block.patch | 2 +- patches/server/0512-More-World-API.patch | 2 +- ...cause-to-Weather-ThunderChangeEvents.patch | 4 +- .../0549-add-per-world-spawn-limits.patch | 2 +- ...etChunkIfLoadedImmediately-in-places.patch | 2 +- ...o-find-targets-for-lightning-strikes.patch | 4 +- ...-logic-for-inventories-on-chunk-unlo.patch | 2 +- ...0593-Improve-and-expand-AsyncCatcher.patch | 30 +- ...aper-mobcaps-and-paper-playermobcaps.patch | 2 +- ...ally-inline-methods-in-BlockPosition.patch | 2 +- ...entory-not-closing-on-entity-removal.patch | 2 +- ...vanilla-BiomeProvider-from-WorldInfo.patch | 4 +- ...0667-Fix-falling-block-spawn-methods.patch | 2 +- patches/server/0695-Don-t-tick-markers.patch | 2 +- ...mpty-items-from-being-added-to-world.patch | 2 +- patches/server/0716-More-Teleport-API.patch | 4 +- ...-on-plugins-accessing-faraway-chunks.patch | 2 +- patches/server/0723-Collision-API.patch | 2 +- .../0735-Configurable-chat-thread-limit.patch | 4 +- .../0740-Fix-a-bunch-of-vanilla-bugs.patch | 2 +- ...ry-onTrackingStart-during-navigation.patch | 2 +- ...global-player-list-where-appropriate.patch | 2 +- .../0773-Add-Sneaking-API-for-Entities.patch | 2 +- .../server/0787-Add-Entity-Body-Yaw-API.patch | 2 +- ...nts-being-fired-from-unloaded-chunks.patch | 2 +- ...Folia-scheduler-and-owned-region-API.patch | 2 +- ...0839-Only-capture-actual-tree-growth.patch | 2 +- .../server/0846-Bandaid-fix-for-Effect.patch | 2 +- ...-API-for-an-entity-s-scoreboard-name.patch | 2 +- patches/server/0858-Expand-Pose-API.patch | 2 +- ...ix-missing-map-initialize-event-call.patch | 2 +- ...predicate-for-blocks-when-raytracing.patch | 2 +- ...ingEffect-powers-lightning-rods-and-.patch | 2 +- ...g-event-call-for-entity-teleport-API.patch | 2 +- ...n-t-fire-sync-events-during-worldgen.patch | 2 +- .../server/0900-Add-Structure-check-API.patch | 2 +- ...25-Add-BlockBreakProgressUpdateEvent.patch | 2 +- patches/server/0928-More-Raid-API.patch | 2 +- ...ing-message-for-initial-server-start.patch | 2 +- ...0-Configurable-max-block-fluid-ticks.patch | 2 +- ...972-disable-forced-empty-world-ticks.patch | 2 +- ...item-frames-performance-and-bug-fixe.patch | 2 +- .../0978-Entity-Activation-Range-2.0.patch | 2 +- patches/server/0979-Anti-Xray.patch | 4 +- ...-Optimize-Bit-Operations-by-inlining.patch | 2 +- .../0992-Properly-resend-entities.patch | 2 +- patches/server/1020-Add-FeatureFlag-API.patch | 2 +- .../1028-Improve-entity-effect-API.patch | 2 +- .../1032-Void-damage-configuration-API.patch | 2 +- ...> 1037-Rewrite-dataconverter-system.patch} | 0 .../server/1037-fixup-ConcurrentUtil.patch | 6177 -------- ... 1038-Moonrise-optimisation-patches.patch} | 0 .../1038-fixup-Paper-config-files.patch | 87 - patches/server/1039-fixup-MC-Utils.patch | 1357 -- ...ptimize-BlockPosition-helper-methods.patch | 64 - .../server/1042-fixup-More-Teleport-API.patch | 19 - 90 files changed, 7364 insertions(+), 14350 deletions(-) rename patches/server/{1040-Rewrite-dataconverter-system.patch => 1037-Rewrite-dataconverter-system.patch} (100%) delete mode 100644 patches/server/1037-fixup-ConcurrentUtil.patch rename patches/server/{1043-Moonrise-optimisation-patches.patch => 1038-Moonrise-optimisation-patches.patch} (100%) delete mode 100644 patches/server/1038-fixup-Paper-config-files.patch delete mode 100644 patches/server/1039-fixup-MC-Utils.patch delete mode 100644 patches/server/1041-fixup-Optimize-BlockPosition-helper-methods.patch delete mode 100644 patches/server/1042-fixup-More-Teleport-API.patch diff --git a/patches/server/0005-Paper-config-files.patch b/patches/server/0005-Paper-config-files.patch index 553c9188755f..3303f32c8ae6 100644 --- a/patches/server/0005-Paper-config-files.patch +++ b/patches/server/0005-Paper-config-files.patch @@ -487,10 +487,10 @@ index 0000000000000000000000000000000000000000..d9502ba028a96f9cc846f9ed428bd806 +} diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java new file mode 100644 -index 0000000000000000000000000000000000000000..b92bfd89e32becde2e7630c6116c16f8a4f6614a +index 0000000000000000000000000000000000000000..7e88b1fc1ff700a7771b38f139f4472eaeaf8714 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -0,0 +1,331 @@ +@@ -0,0 +1,355 @@ +package io.papermc.paper.configuration; + +import co.aikar.timings.MinecraftTimings; @@ -523,6 +523,45 @@ index 0000000000000000000000000000000000000000..b92bfd89e32becde2e7630c6116c16f8 + public static GlobalConfiguration get() { + return instance; + } ++ ++ public ChunkLoadingBasic chunkLoadingBasic; ++ ++ public class ChunkLoadingBasic extends ConfigurationPart { ++ @Comment("The maximum rate in chunks per second that the server will send to any individual player. Set to -1 to disable this limit.") ++ public double playerMaxChunkSendRate = 75.0; ++ ++ @Comment( ++ "The maximum rate at which chunks will load for any individual player. " + ++ "Note that this setting also affects chunk generations, since a chunk load is always first issued to test if a" + ++ "chunk is already generated. Set to -1 to disable this limit." ++ ) ++ public double playerMaxChunkLoadRate = 100.0; ++ ++ @Comment("The maximum rate at which chunks will generate for any individual player. Set to -1 to disable this limit.") ++ public double playerMaxChunkGenerateRate = -1.0; ++ } ++ ++ public ChunkLoadingAdvanced chunkLoadingAdvanced; ++ ++ public class ChunkLoadingAdvanced extends ConfigurationPart { ++ @Comment( ++ "Set to true if the server will match the chunk send radius that clients have configured" + ++ "in their view distance settings if the client is less-than the server's send distance." ++ ) ++ public boolean autoConfigSendDistance = true; ++ ++ @Comment( ++ "Specifies the maximum amount of concurrent chunk loads that an individual player can have." + ++ "Set to 0 to let the server configure it automatically per player, or set it to -1 to disable the limit." ++ ) ++ public int playerMaxConcurrentChunkLoads = 0; ++ ++ @Comment( ++ "Specifies the maximum amount of concurrent chunk generations that an individual player can have." + ++ "Set to 0 to let the server configure it automatically per player, or set it to -1 to disable the limit." ++ ) ++ public int playerMaxConcurrentChunkGenerates = 0; ++ } + static void set(GlobalConfiguration instance) { + GlobalConfiguration.instance = instance; + } @@ -638,21 +677,6 @@ index 0000000000000000000000000000000000000000..b92bfd89e32becde2e7630c6116c16f8 + public int incomingPacketThreshold = 300; + } + -+ public ChunkLoading chunkLoading; -+ -+ public class ChunkLoading extends ConfigurationPart { -+ public int minLoadRadius = 2; -+ public int maxConcurrentSends = 2; -+ public boolean autoconfigSendDistance = true; -+ public double targetPlayerChunkSendRate = 100.0; -+ public double globalMaxChunkSendRate = -1.0; -+ public boolean enableFrustumPriority = false; -+ public double globalMaxChunkLoadRate = -1.0; -+ public double playerMaxConcurrentLoads = 20.0; -+ public double globalMaxConcurrentLoads = 500.0; -+ public double playerMaxChunkLoadRate = -1.0; -+ } -+ + public UnsupportedSettings unsupportedSettings; + + public class UnsupportedSettings extends ConfigurationPart { @@ -711,7 +735,7 @@ index 0000000000000000000000000000000000000000..b92bfd89e32becde2e7630c6116c16f8 + + @PostProcess + private void postProcess() { -+ //io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.init(this); ++ + } + } + diff --git a/patches/server/0007-ConcurrentUtil.patch b/patches/server/0007-ConcurrentUtil.patch index 44a4f07316de..b285b3c6e347 100644 --- a/patches/server/0007-ConcurrentUtil.patch +++ b/patches/server/0007-ConcurrentUtil.patch @@ -1431,167 +1431,12 @@ index 0000000000000000000000000000000000000000..f84a622dc29750139ac280f480b7cd13 + } + } +} -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/collection/SRSWLinkedQueue.java b/src/main/java/ca/spottedleaf/concurrentutil/collection/SRSWLinkedQueue.java +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/completable/CallbackCompletable.java b/src/main/java/ca/spottedleaf/concurrentutil/completable/CallbackCompletable.java new file mode 100644 -index 0000000000000000000000000000000000000000..094eff418b4e3bffce020d650931b4d9e58fa9ed +index 0000000000000000000000000000000000000000..6bad6f8ecc0944d2f406924c7de7e227ff1e70fa --- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/collection/SRSWLinkedQueue.java -@@ -0,0 +1,149 @@ -+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.ConcurrentModificationException; -+ -+/** -+ * Single reader thread single writer thread queue. The reader side of the queue is ordered by acquire semantics, -+ * and the writer side of the queue is ordered by release semantics. -+ */ -+// TODO test -+public class SRSWLinkedQueue { -+ -+ // always non-null -+ protected LinkedNode head; -+ -+ // always non-null -+ protected LinkedNode tail; -+ -+ /* IMPL NOTE: Leave hashCode and equals to their defaults */ -+ -+ public SRSWLinkedQueue() { -+ final LinkedNode dummy = new LinkedNode<>(null, null); -+ this.head = this.tail = dummy; -+ } -+ -+ /** -+ * Must be the reader thread. -+ * -+ *

    -+ * Returns, without removing, the first element of this queue. -+ *

    -+ * @return Returns, without removing, the first element of this queue. -+ */ -+ public E peekFirst() { -+ LinkedNode head = this.head; -+ E ret = head.getElementPlain(); -+ if (ret == null) { -+ head = head.getNextAcquire(); -+ if (head == null) { -+ // empty -+ return null; -+ } -+ // update head reference for next poll() call -+ this.head = head; -+ // guaranteed to be non-null -+ ret = head.getElementPlain(); -+ if (ret == null) { -+ throw new ConcurrentModificationException("Multiple reader threads"); -+ } -+ } -+ -+ return ret; -+ } -+ -+ /** -+ * Must be the reader thread. -+ * -+ *

    -+ * Returns and removes the first element of this queue. -+ *

    -+ * @return Returns and removes the first element of this queue. -+ */ -+ public E poll() { -+ LinkedNode head = this.head; -+ E ret = head.getElementPlain(); -+ if (ret == null) { -+ head = head.getNextAcquire(); -+ if (head == null) { -+ // empty -+ return null; -+ } -+ // guaranteed to be non-null -+ ret = head.getElementPlain(); -+ if (ret == null) { -+ throw new ConcurrentModificationException("Multiple reader threads"); -+ } -+ } -+ -+ head.setElementPlain(null); -+ LinkedNode next = head.getNextAcquire(); -+ this.head = next == null ? head : next; -+ -+ return ret; -+ } -+ -+ /** -+ * Must be the writer thread. -+ * -+ *

    -+ * Adds the element to the end of the queue. -+ *

    -+ * -+ * @throws NullPointerException If the provided element is null -+ */ -+ public void addLast(final E element) { -+ Validate.notNull(element, "Provided element cannot be null"); -+ final LinkedNode append = new LinkedNode<>(element, null); -+ -+ this.tail.setNextRelease(append); -+ this.tail = append; -+ } -+ -+ protected static final class LinkedNode { -+ -+ protected volatile Object element; -+ protected volatile LinkedNode 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 next) { -+ ELEMENT_HANDLE.set(this, element); -+ NEXT_HANDLE.set(this, next); -+ } -+ -+ /* element */ -+ -+ @SuppressWarnings("unchecked") -+ protected final E getElementPlain() { -+ return (E)ELEMENT_HANDLE.get(this); -+ } -+ -+ protected final void setElementPlain(final E update) { -+ ELEMENT_HANDLE.set(this, (Object)update); -+ } -+ /* next */ -+ -+ @SuppressWarnings("unchecked") -+ protected final LinkedNode getNextPlain() { -+ return (LinkedNode)NEXT_HANDLE.get(this); -+ } -+ -+ @SuppressWarnings("unchecked") -+ protected final LinkedNode getNextAcquire() { -+ return (LinkedNode)NEXT_HANDLE.getAcquire(this); -+ } -+ -+ protected final void setNextPlain(final LinkedNode next) { -+ NEXT_HANDLE.set(this, next); -+ } -+ -+ protected final void setNextRelease(final LinkedNode next) { -+ NEXT_HANDLE.setRelease(this, next); -+ } -+ } -+} -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..46d1bd01542ebeeffc0006a5c585a50dbbbff907 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/completable/Completable.java -@@ -0,0 +1,112 @@ ++++ b/src/main/java/ca/spottedleaf/concurrentutil/completable/CallbackCompletable.java +@@ -0,0 +1,110 @@ +package ca.spottedleaf.concurrentutil.completable; + +import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; @@ -1601,9 +1446,9 @@ index 0000000000000000000000000000000000000000..46d1bd01542ebeeffc0006a5c585a50d +import org.slf4j.LoggerFactory; +import java.util.function.BiConsumer; + -+public final class Completable { ++public final class CallbackCompletable { + -+ private static final Logger LOGGER = LoggerFactory.getLogger(Completable.class); ++ private static final Logger LOGGER = LoggerFactory.getLogger(CallbackCompletable.class); + + private final MultiThreadedQueue> waiters = new MultiThreadedQueue<>(); + private T result; @@ -1655,8 +1500,6 @@ index 0000000000000000000000000000000000000000..46d1bd01542ebeeffc0006a5c585a50d + private void completeWaiter(final BiConsumer 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); + } @@ -1700,612 +1543,853 @@ index 0000000000000000000000000000000000000000..46d1bd01542ebeeffc0006a5c585a50d + + @Override + public boolean cancel() { -+ return Completable.this.waiters.remove(this.waiter); ++ return CallbackCompletable.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 +\ No newline at end of file +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..18d646676fd022afd64afaac30ec1bd283a73b0e +index 0000000000000000000000000000000000000000..365616439fa079017d648ed7f6ddf6950a691adf --- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/BaseExecutor.java -@@ -0,0 +1,208 @@ -+package ca.spottedleaf.concurrentutil.executor; ++++ b/src/main/java/ca/spottedleaf/concurrentutil/completable/Completable.java +@@ -0,0 +1,737 @@ ++package ca.spottedleaf.concurrentutil.completable; + +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import java.util.function.BooleanSupplier; ++import ca.spottedleaf.concurrentutil.util.Validate; ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; ++import java.lang.invoke.VarHandle; ++import java.util.concurrent.CompletableFuture; ++import java.util.concurrent.CompletionException; ++import java.util.concurrent.CompletionStage; ++import java.util.concurrent.Executor; ++import java.util.concurrent.ForkJoinPool; ++import java.util.concurrent.locks.LockSupport; ++import java.util.function.BiConsumer; ++import java.util.function.BiFunction; ++import java.util.function.Consumer; ++import java.util.function.Function; ++import java.util.function.Supplier; + -+/** -+ * Base implementation for an abstract queue of tasks which are executed either synchronously or asynchronously. -+ * -+ *

    -+ * The implementation supports tracking task executions using {@link #getTotalTasksScheduled()} and -+ * {@link #getTotalTasksExecuted()}, and optionally shutting down the executor using {@link #shutdown()} -+ *

    -+ * -+ *

    -+ * The base implementation does not provide a method to queue a task for execution, rather that is specified in -+ * the specific implementation. However, it is required that a specific implementation provides a method to -+ * queue a task or create a task. A queued task is one which will eventually be executed, -+ * and a created task must be queued to execute via {@link BaseTask#queue()} or be executed manually via -+ * {@link BaseTask#execute()}. This choice of delaying the queueing of a task may be useful to provide a task handle -+ * which may be cancelled or adjusted before the actual real task logic is ready to be executed. -+ *

    -+ */ -+public interface BaseExecutor { ++public final class Completable { + -+ /** -+ * 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(); ++ private static final Logger LOGGER = LoggerFactory.getLogger(Completable.class); ++ private static final Function DEFAULT_EXCEPTION_HANDLER = (final Throwable thr) -> { ++ LOGGER.error("Unhandled exception during Completable operation", thr); ++ return thr; ++ }; + -+ return completed == scheduled; ++ public static Executor getDefaultExecutor() { ++ return ForkJoinPool.commonPool(); + } + -+ /** -+ * Returns the number of tasks that have been scheduled or execute or are pending to be scheduled. -+ */ -+ public long getTotalTasksScheduled(); ++ private static final Transform COMPLETED_STACK = new Transform<>(null, null, null, null) { ++ @Override ++ public void run() {} ++ }; ++ private volatile Transform completeStack; ++ private static final VarHandle COMPLETE_STACK_HANDLE = ConcurrentUtil.getVarHandle(Completable.class, "completeStack", Transform.class); + -+ /** -+ * Returns the number of tasks that have fully been executed. -+ */ -+ public long getTotalTasksExecuted(); ++ private static final Object NULL_MASK = new Object(); ++ private volatile Object result; ++ private static final VarHandle RESULT_HANDLE = ConcurrentUtil.getVarHandle(Completable.class, "result", Object.class); + -+ /** -+ * Waits until this queue has had all of its tasks executed (NOT removed). See {@link #haveAllTasksExecuted()} -+ *

    -+ * 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. -+ *

    -+ *

    -+ * 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. -+ *

    -+ *

    -+ * Note: Interruptions to the the current thread have no effect. Interrupt status is also not affected by this call. -+ *

    -+ * -+ * @throws IllegalStateException If the current thread is not allowed to wait -+ */ -+ public default void waitUntilAllExecuted() throws IllegalStateException { -+ long failures = 1L; // start at 0.25ms ++ private Object getResultPlain() { ++ return (Object)RESULT_HANDLE.get(this); ++ } + -+ while (!this.haveAllTasksExecuted()) { -+ Thread.yield(); -+ failures = ConcurrentUtil.linearLongBackoff(failures, 250_000L, 5_000_000L); // 500us, 5ms -+ } ++ private Object getResultVolatile() { ++ return (Object)RESULT_HANDLE.getVolatile(this); + } + -+ /** -+ * Executes the next available task. -+ * -+ * @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; ++ private void pushStackOrRun(final Transform push) { ++ int failures = 0; ++ for (Transform curr = (Transform)COMPLETE_STACK_HANDLE.getVolatile(this);;) { ++ if (curr == COMPLETED_STACK) { ++ push.execute(); ++ return; ++ } + -+ /** -+ * 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; ++ push.next = curr; ++ ++ for (int i = 0; i < failures; ++i) { ++ ConcurrentUtil.backoff(); ++ } ++ ++ if (curr == (curr = (Transform)COMPLETE_STACK_HANDLE.compareAndExchange(this, curr, push))) { ++ return; ++ } ++ push.next = null; ++ ++failures; + } ++ } + -+ while (this.executeTask()); ++ private void propagateStack() { ++ Transform topStack = (Transform)COMPLETE_STACK_HANDLE.getAndSet(this, COMPLETED_STACK); ++ while (topStack != null) { ++ topStack.execute(); ++ topStack = topStack.next; ++ } ++ } + -+ return true; ++ private static Object maskNull(final Object res) { ++ return res == null ? NULL_MASK : res; + } + -+ /** -+ * Waits and executes tasks until the condition returns {@code true}. -+ *

    -+ * WARNING: This function is not suitable for waiting until a deadline! -+ * Use {@link #executeUntil(long)} or {@link #executeConditionally(BooleanSupplier, long)} instead. -+ *

    -+ */ -+ 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 ++ private static Object unmaskNull(final Object res) { ++ return res == NULL_MASK ? null : res; ++ } ++ ++ private static Executor checkExecutor(final Executor executor) { ++ return Validate.notNull(executor, "Executor may not be null"); ++ } ++ ++ public Completable() {} ++ ++ private Completable(final Object complete) { ++ COMPLETE_STACK_HANDLE.set(this, COMPLETED_STACK); ++ RESULT_HANDLE.setRelease(this, complete); ++ } ++ ++ public static Completable completed(final T value) { ++ return new Completable<>(maskNull(value)); ++ } ++ ++ public static Completable failed(final Throwable ex) { ++ Validate.notNull(ex, "Exception may not be null"); ++ ++ return new Completable<>(new ExceptionResult(ex)); ++ } ++ ++ public static Completable supplied(final Supplier supplier) { ++ return supplied(supplier, DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public static Completable supplied(final Supplier supplier, final Function exceptionHandler) { ++ try { ++ return completed(supplier.get()); ++ } catch (final Throwable throwable) { ++ Throwable complete; ++ try { ++ complete = exceptionHandler.apply(throwable); ++ } catch (final Throwable thr2) { ++ throwable.addSuppressed(thr2); ++ complete = throwable; + } ++ return failed(complete); + } + } + -+ /** -+ * Waits and executes tasks until the condition returns {@code true} or {@code System.nanoTime() - deadline >= 0}. -+ */ -+ 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 < 0L) && !condition.getAsBoolean() && (System.nanoTime() - deadline < 0L)) { -+ if (this.executeTask()) { -+ failures = failures >>> 2; -+ } else { -+ failures = ConcurrentUtil.linearLongBackoffDeadline(failures, 100_000L, 10_000_000L, deadline); // 100us, 10ms ++ public static Completable suppliedAsync(final Supplier supplier, final Executor executor) { ++ return suppliedAsync(supplier, executor, DEFAULT_EXCEPTION_HANDLER); ++ } ++ ++ public static Completable suppliedAsync(final Supplier supplier, final Executor executor, final Function exceptionHandler) { ++ final Completable ret = new Completable<>(); ++ ++ class AsyncSuppliedCompletable implements Runnable, CompletableFuture.AsynchronousCompletionTask { ++ @Override ++ public void run() { ++ try { ++ ret.complete(supplier.get()); ++ } catch (final Throwable throwable) { ++ Throwable complete; ++ try { ++ complete = exceptionHandler.apply(throwable); ++ } catch (final Throwable thr2) { ++ throwable.addSuppressed(thr2); ++ complete = throwable; ++ } ++ ret.completeExceptionally(complete); ++ } + } + } -+ } + -+ /** -+ * Waits and executes tasks until {@code System.nanoTime() - deadline >= 0}. -+ */ -+ public default void executeUntil(final long deadline) { -+ long failures = 0; -+ while (System.nanoTime() - deadline < 0L) { -+ if (this.executeTask()) { -+ failures = failures >>> 2; -+ } else { -+ failures = ConcurrentUtil.linearLongBackoffDeadline(failures, 100_000L, 10_000_000L, deadline); // 100us, 10ms ++ try { ++ executor.execute(new AsyncSuppliedCompletable()); ++ } catch (final Throwable throwable) { ++ Throwable complete; ++ try { ++ complete = exceptionHandler.apply(throwable); ++ } catch (final Throwable thr2) { ++ throwable.addSuppressed(thr2); ++ complete = throwable; + } ++ ret.completeExceptionally(complete); + } ++ ++ return ret; + } + -+ /** -+ * Prevent further additions to this queue. Attempts to add after this call has completed (potentially during) will -+ * result in {@link IllegalStateException} being thrown. -+ *

    -+ * This operation is atomic with respect to other shutdown calls -+ *

    -+ *

    -+ * After this call has completed, regardless of return value, this queue will be shutdown. -+ *

    -+ * -+ * @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 -+ * @see #isShutdown() -+ */ -+ public default boolean shutdown() throws UnsupportedOperationException { -+ throw new UnsupportedOperationException(); ++ private boolean completeRaw(final Object value) { ++ if ((Object)RESULT_HANDLE.getVolatile(this) != null || !(boolean)RESULT_HANDLE.compareAndSet(this, (Object)null, value)) { ++ return false; ++ } ++ ++ this.propagateStack(); ++ return true; + } + -+ /** -+ * Returns whether this queue has shut down. Effectively, whether new tasks will be rejected - this method -+ * does not indicate whether all the tasks scheduled have been executed. -+ * @return Returns whether this queue has shut down. -+ * @see #waitUntilAllExecuted() -+ */ -+ public default boolean isShutdown() { -+ return false; ++ public boolean complete(final T result) { ++ return this.completeRaw(maskNull(result)); + } + -+ /** -+ * Task object returned for any {@link BaseExecutor} scheduled task. -+ * @see BaseExecutor -+ */ -+ public static interface BaseTask extends Cancellable { ++ public boolean completeExceptionally(final Throwable exception) { ++ Validate.notNull(exception, "Exception may not be null"); + -+ /** -+ * 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(); ++ return this.completeRaw(new ExceptionResult(exception)); ++ } + -+ /** -+ * 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(); ++ public boolean isDone() { ++ return this.getResultVolatile() != null; ++ } + -+ /** -+ * Executes this task. This will also mark the task as completing. -+ *

    -+ * Exceptions thrown from the runnable will be rethrown. -+ *

    -+ * -+ * @return {@code true} if this task was executed, {@code false} if it was already marked as completed. -+ */ -+ public boolean execute(); ++ public boolean isNormallyComplete() { ++ return this.getResultVolatile() != null && !(this.getResultVolatile() instanceof ExceptionResult); + } -+} -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 { ++ public boolean isExceptionallyComplete() { ++ return this.getResultVolatile() instanceof ExceptionResult; ++ } + -+ /** -+ * 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; ++ public Throwable getException() { ++ final Object res = this.getResultVolatile(); ++ if (res == null) { ++ return null; ++ } + -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import java.lang.invoke.VarHandle; ++ if (!(res instanceof ExceptionResult exRes)) { ++ throw new IllegalStateException("Not completed exceptionally"); ++ } + -+public class DelayedPrioritisedTask { ++ return exRes.ex; ++ } + -+ protected volatile int priority; -+ protected static final VarHandle PRIORITY_HANDLE = ConcurrentUtil.getVarHandle(DelayedPrioritisedTask.class, "priority", int.class); ++ public T getNow(final T dfl) throws CompletionException { ++ final Object res = this.getResultVolatile(); ++ if (res == null) { ++ return dfl; ++ } + -+ protected static final int PRIORITY_SET = Integer.MIN_VALUE >>> 0; ++ if (res instanceof ExceptionResult exRes) { ++ throw new CompletionException(exRes.ex); ++ } + -+ protected final int getPriorityVolatile() { -+ return (int)PRIORITY_HANDLE.getVolatile((DelayedPrioritisedTask)this); ++ return (T)unmaskNull(res); + } + -+ protected final int compareAndExchangePriorityVolatile(final int expect, final int update) { -+ return (int)PRIORITY_HANDLE.compareAndExchange((DelayedPrioritisedTask)this, (int)expect, (int)update); ++ public T join() throws CompletionException { ++ if (this.isDone()) { ++ return this.getNow(null); ++ } ++ ++ final UnparkTransform unparkTransform = new UnparkTransform<>(this, Thread.currentThread()); ++ ++ this.pushStackOrRun(unparkTransform); ++ ++ boolean interuptted = false; ++ while (!unparkTransform.isReleasable()) { ++ try { ++ ForkJoinPool.managedBlock(unparkTransform); ++ } catch (final InterruptedException ex) { ++ interuptted = true; ++ } ++ } ++ ++ if (interuptted) { ++ Thread.currentThread().interrupt(); ++ } ++ ++ return this.getNow(null); + } + -+ protected final int getAndOrPriorityVolatile(final int val) { -+ return (int)PRIORITY_HANDLE.getAndBitwiseOr((DelayedPrioritisedTask)this, (int)val); ++ public CompletableFuture toFuture() { ++ final Object rawResult = this.getResultVolatile(); ++ if (rawResult != null) { ++ if (rawResult instanceof ExceptionResult exRes) { ++ return CompletableFuture.failedFuture(exRes.ex); ++ } else { ++ return CompletableFuture.completedFuture((T)unmaskNull(rawResult)); ++ } ++ } ++ ++ final CompletableFuture ret = new CompletableFuture<>(); ++ ++ class ToFuture implements BiConsumer { ++ ++ @Override ++ public void accept(final T res, final Throwable ex) { ++ if (ex != null) { ++ ret.completeExceptionally(ex); ++ } else { ++ ret.complete(res); ++ } ++ } ++ } ++ ++ this.whenComplete(new ToFuture()); ++ ++ return ret; + } + -+ protected final void setPriorityPlain(final int val) { -+ PRIORITY_HANDLE.set((DelayedPrioritisedTask)this, (int)val); ++ public static Completable fromFuture(final CompletionStage stage) { ++ final Completable ret = new Completable<>(); ++ ++ class FromFuture implements BiConsumer { ++ @Override ++ public void accept(final T res, final Throwable ex) { ++ if (ex != null) { ++ ret.completeExceptionally(ex); ++ } else { ++ ret.complete(res); ++ } ++ } ++ } ++ ++ stage.whenComplete(new FromFuture()); ++ ++ return ret; + } + -+ 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); ++ public Completable thenApply(final Function function) { ++ return this.thenApply(function, DEFAULT_EXCEPTION_HANDLER); + } + -+ protected PrioritisedExecutor.PrioritisedTask getTaskVolatile() { -+ return (PrioritisedExecutor.PrioritisedTask)TASK_HANDLE.getVolatile((DelayedPrioritisedTask)this); ++ public Completable thenApply(final Function function, final Function exceptionHandler) { ++ Validate.notNull(function, "Function may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); ++ ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new ApplyTransform<>(null, this, ret, exceptionHandler, function)); ++ return ret; + } + -+ 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 Completable thenApplyAsync(final Function function) { ++ return this.thenApplyAsync(function, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); + } + -+ public DelayedPrioritisedTask(final PrioritisedExecutor.Priority priority) { -+ this.setPriorityPlain(priority.priority); ++ public Completable thenApplyAsync(final Function function, final Executor executor) { ++ return this.thenApplyAsync(function, executor, DEFAULT_EXCEPTION_HANDLER); + } + -+ // only public for debugging -+ public int getPriorityInternal() { -+ return this.getPriorityVolatile(); ++ public Completable thenApplyAsync(final Function function, final Executor executor, final Function exceptionHandler) { ++ Validate.notNull(function, "Function may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); ++ ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new ApplyTransform<>(checkExecutor(executor), this, ret, exceptionHandler, function)); ++ return ret; + } + -+ public PrioritisedExecutor.PrioritisedTask getTask() { -+ return this.getTaskVolatile(); ++ ++ public Completable thenAccept(final Consumer consumer) { ++ return this.thenAccept(consumer, DEFAULT_EXCEPTION_HANDLER); + } + -+ public void setTask(final PrioritisedExecutor.PrioritisedTask task) { -+ int priority = this.getPriorityVolatile(); ++ public Completable thenAccept(final Consumer consumer, final Function exceptionHandler) { ++ Validate.notNull(consumer, "Consumer may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); + -+ if (this.compareAndExchangeTaskVolatile(null, task) != null) { -+ throw new IllegalStateException("setTask() called twice"); -+ } ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new AcceptTransform<>(null, this, ret, exceptionHandler, consumer)); ++ return ret; ++ } + -+ int failures = 0; -+ for (;;) { -+ task.setPriority(PrioritisedExecutor.Priority.getPriority(priority)); ++ public Completable thenAcceptAsync(final Consumer consumer) { ++ return this.thenAcceptAsync(consumer, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); ++ } + -+ if (priority == (priority = this.compareAndExchangePriorityVolatile(priority, priority | PRIORITY_SET))) { -+ return; -+ } ++ public Completable thenAcceptAsync(final Consumer consumer, final Executor executor) { ++ return this.thenAcceptAsync(consumer, executor, DEFAULT_EXCEPTION_HANDLER); ++ } + -+ ++failures; -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ } ++ public Completable thenAcceptAsync(final Consumer consumer, final Executor executor, final Function exceptionHandler) { ++ Validate.notNull(consumer, "Consumer may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); ++ ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new AcceptTransform<>(checkExecutor(executor), this, ret, exceptionHandler, consumer)); ++ return ret; + } + -+ public PrioritisedExecutor.Priority getPriority() { -+ final int priority = this.getPriorityVolatile(); -+ if ((priority & PRIORITY_SET) != 0) { -+ return this.task.getPriority(); -+ } + -+ return PrioritisedExecutor.Priority.getPriority(priority); ++ public Completable thenRun(final Runnable run) { ++ return this.thenRun(run, DEFAULT_EXCEPTION_HANDLER); + } + -+ public void raisePriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } ++ public Completable thenRun(final Runnable run, final Function exceptionHandler) { ++ Validate.notNull(run, "Run may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); + -+ int failures = 0; -+ for (int curr = this.getPriorityVolatile();;) { -+ if ((curr & PRIORITY_SET) != 0) { -+ this.getTaskPlain().raisePriority(priority); -+ return; -+ } ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new RunTransform<>(null, this, ret, exceptionHandler, run)); ++ return ret; ++ } + -+ if (!priority.isLowerPriority(curr)) { -+ return; -+ } ++ public Completable thenRunAsync(final Runnable run) { ++ return this.thenRunAsync(run, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); ++ } + -+ if (curr == (curr = this.compareAndExchangePriorityVolatile(curr, priority.priority))) { -+ return; -+ } ++ public Completable thenRunAsync(final Runnable run, final Executor executor) { ++ return this.thenRunAsync(run, executor, DEFAULT_EXCEPTION_HANDLER); ++ } + -+ // failed, retry ++ public Completable thenRunAsync(final Runnable run, final Executor executor, final Function exceptionHandler) { ++ Validate.notNull(run, "Run may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); + -+ ++failures; -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ } ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new RunTransform<>(checkExecutor(executor), this, ret, exceptionHandler, run)); ++ return ret; + } + -+ 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; -+ } ++ public Completable handle(final BiFunction function) { ++ return this.handle(function, DEFAULT_EXCEPTION_HANDLER); ++ } + -+ if (curr == (curr = this.compareAndExchangePriorityVolatile(curr, priority.priority))) { -+ return; -+ } ++ public Completable handle(final BiFunction function, ++ final Function exceptionHandler) { ++ Validate.notNull(function, "Function may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); + -+ // failed, retry ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new HandleTransform<>(null, this, ret, exceptionHandler, function)); ++ return ret; ++ } + -+ ++failures; -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ } ++ public Completable handleAsync(final BiFunction function) { ++ return this.handleAsync(function, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); + } + -+ public void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } ++ public Completable handleAsync(final BiFunction function, ++ final Executor executor) { ++ return this.handleAsync(function, executor, DEFAULT_EXCEPTION_HANDLER); ++ } + -+ int failures = 0; -+ for (int curr = this.getPriorityVolatile();;) { -+ if ((curr & PRIORITY_SET) != 0) { -+ this.getTaskPlain().lowerPriority(priority); -+ return; -+ } ++ public Completable handleAsync(final BiFunction function, ++ final Executor executor, ++ final Function exceptionHandler) { ++ Validate.notNull(function, "Function may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); + -+ if (!priority.isHigherPriority(curr)) { -+ return; -+ } ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new HandleTransform<>(checkExecutor(executor), this, ret, exceptionHandler, function)); ++ return ret; ++ } + -+ if (curr == (curr = this.compareAndExchangePriorityVolatile(curr, priority.priority))) { -+ return; -+ } + -+ // failed, retry ++ public Completable whenComplete(final BiConsumer consumer) { ++ return this.whenComplete(consumer, DEFAULT_EXCEPTION_HANDLER); ++ } + -+ ++failures; -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ } ++ public Completable whenComplete(final BiConsumer consumer, final Function exceptionHandler) { ++ Validate.notNull(consumer, "Consumer may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); ++ ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new WhenTransform<>(null, this, ret, exceptionHandler, consumer)); ++ return ret; + } -+} -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..91beb6f23f257cf265fe3150f760892e605f217a ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedExecutor.java -@@ -0,0 +1,276 @@ -+package ca.spottedleaf.concurrentutil.executor.standard; + -+import ca.spottedleaf.concurrentutil.executor.BaseExecutor; ++ public Completable whenCompleteAsync(final BiConsumer consumer) { ++ return this.whenCompleteAsync(consumer, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); ++ } + -+/** -+ * Implementation of {@link BaseExecutor} which schedules tasks to be executed by a given priority. -+ * @see BaseExecutor -+ */ -+public interface PrioritisedExecutor extends BaseExecutor { ++ public Completable whenCompleteAsync(final BiConsumer consumer, final Executor executor) { ++ return this.whenCompleteAsync(consumer, executor, DEFAULT_EXCEPTION_HANDLER); ++ } + -+ public static enum Priority { ++ public Completable whenCompleteAsync(final BiConsumer consumer, final Executor executor, ++ final Function exceptionHandler) { ++ Validate.notNull(consumer, "Consumer may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); + -+ /** -+ * Priority value indicating the task has completed or is being completed. -+ * This priority cannot be used to schedule tasks. -+ */ -+ COMPLETING(-1), ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new WhenTransform<>(checkExecutor(executor), this, ret, exceptionHandler, consumer)); ++ return ret; ++ } + -+ /** -+ * 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(), ++ public Completable exceptionally(final Function function) { ++ return this.exceptionally(function, DEFAULT_EXCEPTION_HANDLER); ++ } + -+ /** -+ * Two priorities above normal. -+ */ -+ HIGHER(), ++ public Completable exceptionally(final Function function, final Function exceptionHandler) { ++ Validate.notNull(function, "Function may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); + -+ /** -+ * One priority above normal. -+ */ -+ HIGH(), ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new ExceptionallyTransform<>(null, this, ret, exceptionHandler, function)); ++ return ret; ++ } + -+ /** -+ * Default priority. -+ */ -+ NORMAL(), ++ public Completable exceptionallyAsync(final Function function) { ++ return this.exceptionallyAsync(function, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); ++ } + -+ /** -+ * One priority below normal. -+ */ -+ LOW(), ++ public Completable exceptionallyAsync(final Function function, final Executor executor) { ++ return this.exceptionallyAsync(function, executor, DEFAULT_EXCEPTION_HANDLER); ++ } + -+ /** -+ * Two priorities below normal. -+ */ -+ LOWER(), ++ public Completable exceptionallyAsync(final Function function, final Executor executor, ++ final Function exceptionHandler) { ++ Validate.notNull(function, "Function may not be null"); ++ Validate.notNull(exceptionHandler, "Exception handler may not be null"); + -+ /** -+ * Use for tasks that should eventually execute, but are not needed to. -+ */ -+ LOWEST(), ++ final Completable ret = new Completable<>(); ++ this.pushStackOrRun(new ExceptionallyTransform<>(checkExecutor(executor), this, ret, exceptionHandler, function)); ++ return ret; ++ } + -+ /** -+ * Use for tasks that can be delayed indefinitely. -+ */ -+ IDLE(); ++ private static final class ExceptionResult { ++ public final Throwable ex; + -+ // returns whether the priority can be scheduled -+ public static boolean isValidPriority(final Priority priority) { -+ return priority != null && priority != Priority.COMPLETING; ++ public ExceptionResult(final Throwable ex) { ++ this.ex = ex; + } ++ } + -+ // returns the higher priority of the two -+ public static Priority max(final Priority p1, final Priority p2) { -+ return p1.isHigherOrEqualPriority(p2) ? p1 : p2; -+ } ++ private static abstract class Transform implements Runnable, CompletableFuture.AsynchronousCompletionTask { + -+ // returns the lower priroity of the two -+ public static Priority min(final Priority p1, final Priority p2) { -+ return p1.isLowerOrEqualPriority(p2) ? p1 : p2; -+ } ++ private Transform next; + -+ public boolean isHigherOrEqualPriority(final Priority than) { -+ return this.priority <= than.priority; -+ } ++ private final Executor executor; ++ protected final Completable from; ++ protected final Completable to; ++ protected final Function exceptionHandler; + -+ public boolean isHigherPriority(final Priority than) { -+ return this.priority < than.priority; ++ protected Transform(final Executor executor, final Completable from, final Completable to, ++ final Function exceptionHandler) { ++ this.executor = executor; ++ this.from = from; ++ this.to = to; ++ this.exceptionHandler = exceptionHandler; + } + -+ public boolean isLowerOrEqualPriority(final Priority than) { -+ return this.priority >= than.priority; -+ } ++ // force interface call to become virtual call ++ @Override ++ public abstract void run(); + -+ public boolean isLowerPriority(final Priority than) { -+ return this.priority > than.priority; ++ protected void failed(final Throwable throwable) { ++ Throwable complete; ++ try { ++ complete = this.exceptionHandler.apply(throwable); ++ } catch (final Throwable thr2) { ++ throwable.addSuppressed(thr2); ++ complete = throwable; ++ } ++ this.to.completeExceptionally(complete); + } + -+ public boolean isHigherOrEqualPriority(final int than) { -+ return this.priority <= than; -+ } ++ public void execute() { ++ if (this.executor == null) { ++ this.run(); ++ return; ++ } + -+ public boolean isHigherPriority(final int than) { -+ return this.priority < than; ++ try { ++ this.executor.execute(this); ++ } catch (final Throwable throwable) { ++ this.failed(throwable); ++ } + } ++ } + -+ public boolean isLowerOrEqualPriority(final int than) { -+ return this.priority >= than; ++ private static final class ApplyTransform extends Transform { ++ ++ private final Function function; ++ ++ public ApplyTransform(final Executor executor, final Completable from, final Completable to, ++ final Function exceptionHandler, ++ final Function function) { ++ super(executor, from, to, exceptionHandler); ++ this.function = function; + } + -+ public boolean isLowerPriority(final int than) { -+ return this.priority > than; ++ @Override ++ public void run() { ++ final Object result = this.from.getResultPlain(); ++ try { ++ if (result instanceof ExceptionResult exRes) { ++ this.to.completeExceptionally(exRes.ex); ++ } else { ++ this.to.complete(this.function.apply((T)unmaskNull(result))); ++ } ++ } catch (final Throwable throwable) { ++ this.failed(throwable); ++ } + } ++ } + -+ public static boolean isHigherOrEqualPriority(final int priority, final int than) { -+ return priority <= than; ++ private static final class AcceptTransform extends Transform { ++ private final Consumer consumer; ++ ++ public AcceptTransform(final Executor executor, final Completable from, final Completable to, ++ final Function exceptionHandler, ++ final Consumer consumer) { ++ super(executor, from, to, exceptionHandler); ++ this.consumer = consumer; + } + -+ public static boolean isHigherPriority(final int priority, final int than) { -+ return priority < than; ++ @Override ++ public void run() { ++ final Object result = this.from.getResultPlain(); ++ try { ++ if (result instanceof ExceptionResult exRes) { ++ this.to.completeExceptionally(exRes.ex); ++ } else { ++ this.consumer.accept((T)unmaskNull(result)); ++ this.to.complete(null); ++ } ++ } catch (final Throwable throwable) { ++ this.failed(throwable); ++ } + } ++ } ++ ++ private static final class RunTransform extends Transform { ++ private final Runnable run; + -+ public static boolean isLowerOrEqualPriority(final int priority, final int than) { -+ return priority >= than; ++ public RunTransform(final Executor executor, final Completable from, final Completable to, ++ final Function exceptionHandler, ++ final Runnable run) { ++ super(executor, from, to, exceptionHandler); ++ this.run = run; + } + -+ public static boolean isLowerPriority(final int priority, final int than) { -+ return priority > than; ++ @Override ++ public void run() { ++ final Object result = this.from.getResultPlain(); ++ try { ++ if (result instanceof ExceptionResult exRes) { ++ this.to.completeExceptionally(exRes.ex); ++ } else { ++ this.run.run(); ++ this.to.complete(null); ++ } ++ } catch (final Throwable throwable) { ++ this.failed(throwable); ++ } + } ++ } + -+ static final Priority[] PRIORITIES = Priority.values(); ++ private static final class HandleTransform extends Transform { + -+ /** includes special priorities */ -+ public static final int TOTAL_PRIORITIES = PRIORITIES.length; ++ private final BiFunction function; + -+ public static final int TOTAL_SCHEDULABLE_PRIORITIES = TOTAL_PRIORITIES - 1; ++ public HandleTransform(final Executor executor, final Completable from, final Completable to, ++ final Function exceptionHandler, ++ final BiFunction function) { ++ super(executor, from, to, exceptionHandler); ++ this.function = function; ++ } + -+ public static Priority getPriority(final int priority) { -+ return PRIORITIES[priority + 1]; ++ @Override ++ public void run() { ++ final Object result = this.from.getResultPlain(); ++ try { ++ if (result instanceof ExceptionResult exRes) { ++ this.to.complete(this.function.apply(null, exRes.ex)); ++ } else { ++ this.to.complete(this.function.apply((T)unmaskNull(result), null)); ++ } ++ } catch (final Throwable throwable) { ++ this.failed(throwable); ++ } + } ++ } ++ ++ private static final class WhenTransform extends Transform { + -+ private static int priorityCounter; ++ private final BiConsumer consumer; ++ ++ public WhenTransform(final Executor executor, final Completable from, final Completable to, ++ final Function exceptionHandler, ++ final BiConsumer consumer) { ++ super(executor, from, to, exceptionHandler); ++ this.consumer = consumer; ++ } + -+ private static int nextCounter() { -+ return priorityCounter++; ++ @Override ++ public void run() { ++ final Object result = this.from.getResultPlain(); ++ try { ++ if (result instanceof ExceptionResult exRes) { ++ this.consumer.accept(null, exRes.ex); ++ this.to.completeExceptionally(exRes.ex); ++ } else { ++ final T unmasked = (T)unmaskNull(result); ++ this.consumer.accept(unmasked, null); ++ this.to.complete(unmasked); ++ } ++ } catch (final Throwable throwable) { ++ this.failed(throwable); ++ } + } ++ } + -+ public final int priority; ++ private static final class ExceptionallyTransform extends Transform { ++ private final Function function; + -+ Priority() { -+ this(nextCounter()); ++ public ExceptionallyTransform(final Executor executor, final Completable from, final Completable to, ++ final Function exceptionHandler, ++ final Function function) { ++ super(executor, from, to, exceptionHandler); ++ this.function = function; + } + -+ Priority(final int priority) { -+ this.priority = priority; ++ @Override ++ public void run() { ++ final Object result = this.from.getResultPlain(); ++ try { ++ if (result instanceof ExceptionResult exRes) { ++ this.to.complete(this.function.apply(exRes.ex)); ++ } else { ++ this.to.complete((T)unmaskNull(result)); ++ } ++ } catch (final Throwable throwable) { ++ this.failed(throwable); ++ } + } + } + -+ /** -+ * Executes the next available task. -+ *

    -+ * If there is a task with priority {@link PrioritisedExecutor.Priority#BLOCKING} available, then that such task is executed. -+ *

    ++ private static final class UnparkTransform extends Transform implements ForkJoinPool.ManagedBlocker { ++ ++ private volatile Thread thread; ++ ++ public UnparkTransform(final Completable from, final Thread target) { ++ super(null, from, null, null); ++ this.thread = target; ++ } ++ ++ @Override ++ public void run() { ++ final Thread t = this.thread; ++ this.thread = null; ++ LockSupport.unpark(t); ++ } ++ ++ @Override ++ public boolean block() throws InterruptedException { ++ while (!this.isReleasable()) { ++ if (Thread.interrupted()) { ++ throw new InterruptedException(); ++ } ++ LockSupport.park(this); ++ } ++ ++ return true; ++ } ++ ++ @Override ++ public boolean isReleasable() { ++ return this.thread == null; ++ } ++ } ++} +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/PrioritisedExecutor.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/PrioritisedExecutor.java +new file mode 100644 +index 0000000000000000000000000000000000000000..17cbaee1e89bd3f6d905e640d20d0119ab0570a0 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/PrioritisedExecutor.java +@@ -0,0 +1,271 @@ ++package ca.spottedleaf.concurrentutil.executor; ++ ++import ca.spottedleaf.concurrentutil.util.Priority; ++ ++public interface PrioritisedExecutor { ++ ++ /** ++ * Returns the number of tasks that have been scheduled are pending to be scheduled. ++ */ ++ public long getTotalTasksScheduled(); ++ ++ /** ++ * Returns the number of tasks that have been executed. ++ */ ++ public long getTotalTasksExecuted(); ++ ++ /** ++ * Generates the next suborder id. ++ * @return The next suborder id. ++ */ ++ public long generateNextSubOrder(); ++ ++ /** ++ * Executes the next available task. ++ *

    ++ * If there is a task with priority {@link Priority#BLOCKING} available, then that such task is executed. ++ *

    + *

    -+ * If there is a task with priority {@link PrioritisedExecutor.Priority#IDLE} available then that task is only executed ++ * If there is a task with priority {@link Priority#IDLE} available then that task is only executed + * when there are no other tasks available with a higher priority. + *

    + *

    -+ * If there are no tasks that have priority {@link PrioritisedExecutor.Priority#BLOCKING} or {@link PrioritisedExecutor.Priority#IDLE}, then ++ * If there are no tasks that have priority {@link Priority#BLOCKING} or {@link Priority#IDLE}, then + * this function will be biased to execute tasks that have higher priorities. + *

    + * + * @return {@code true} if a task was executed, {@code false} otherwise + * @throws IllegalStateException If the current thread is not allowed to execute a task + */ -+ @Override + public boolean executeTask() throws IllegalStateException; + + /** ++ * Prevent further additions to this executor. Attempts to add after this call has completed (potentially during) will ++ * result in {@link IllegalStateException} being thrown. ++ *

    ++ * This operation is atomic with respect to other shutdown calls ++ *

    ++ *

    ++ * After this call has completed, regardless of return value, this executor will be shutdown. ++ *

    ++ * ++ * @return {@code true} if the executor was shutdown, {@code false} if it has shut down already ++ * @see #isShutdown() ++ */ ++ public boolean shutdown(); ++ ++ /** ++ * Returns whether this executor has shut down. Effectively, returns whether new tasks will be rejected. ++ * This method does not indicate whether all the tasks scheduled have been executed. ++ * @return Returns whether this executor has shut down. ++ */ ++ public boolean isShutdown(); ++ ++ /** + * Queues or executes a task at {@link Priority#NORMAL} priority. + * @param task The task to run. + * -+ * @throws IllegalStateException If this queue has shutdown. ++ * @throws IllegalStateException If this executor 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 ++ * associated with the parameter + */ -+ public default PrioritisedTask queueRunnable(final Runnable task) { -+ return this.queueRunnable(task, Priority.NORMAL); -+ } ++ public PrioritisedTask queueTask(final Runnable task); + + /** + * Queues or executes a task. @@ -2313,50 +2397,107 @@ index 0000000000000000000000000000000000000000..91beb6f23f257cf265fe3150f760892e + * @param task The task to run. + * @param priority The priority for the task. + * -+ * @throws IllegalStateException If this queue has shutdown. ++ * @throws IllegalStateException If this executor 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 ++ * associated with the parameter + */ -+ public PrioritisedTask queueRunnable(final Runnable task, final Priority priority); ++ public PrioritisedTask queueTask(final Runnable task, final Priority priority); + + /** -+ * Creates, but does not execute or queue the task. The task must later be queued via {@link BaseTask#queue()}. ++ * Queues or executes a task. + * + * @param task The task to run. ++ * @param priority The priority for the task. ++ * @param subOrder The task's suborder. + * -+ * @throws IllegalStateException If this queue has shutdown. ++ * @throws IllegalStateException If this executor 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 ++ * @return {@code null} if the current thread immediately executed the task, else returns the prioritised task ++ * associated with the parameter + */ -+ public default PrioritisedTask createTask(final Runnable task) { -+ return this.createTask(task, Priority.NORMAL); -+ } ++ public PrioritisedTask queueTask(final Runnable task, final Priority priority, final long subOrder); ++ ++ /** ++ * Creates, but does not queue or execute, a task at {@link Priority#NORMAL} priority. ++ * @param task The task to run. ++ * ++ * @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 PrioritisedTask createTask(final Runnable task); + + /** -+ * Creates, but does not execute or queue the task. The task must later be queued via {@link BaseTask#queue()}. ++ * Creates, but does not queue or execute, a task at {@link Priority#NORMAL} priority. + * + * @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 ++ * @return {@code null} if the current thread immediately executed the task, else returns the prioritised task ++ * associated with the parameter + */ + public PrioritisedTask createTask(final Runnable task, final Priority priority); + + /** -+ * Extension of {@link ca.spottedleaf.concurrentutil.executor.BaseExecutor.BaseTask} which adds functions -+ * to retrieve and modify the task's associated priority. ++ * Creates, but does not queue or execute, a task at {@link Priority#NORMAL} priority. ++ * ++ * @param task The task to run. ++ * @param priority The priority for the task. ++ * @param subOrder The task's suborder. + * -+ * @see ca.spottedleaf.concurrentutil.executor.BaseExecutor.BaseTask ++ * @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 static interface PrioritisedTask extends BaseTask { ++ public PrioritisedTask createTask(final Runnable task, final Priority priority, final long subOrder); ++ ++ public static interface PrioritisedTask extends Cancellable { ++ ++ /** ++ * Returns the executor associated with this task. ++ * @return The executor associated with this task. ++ */ ++ public PrioritisedExecutor getExecutor(); ++ ++ /** ++ * Causes a lazily queued task to become queued or executed ++ * ++ * @throws IllegalStateException If the backing executor has shutdown ++ * @return {@code true} If the task was queued, {@code false} if the task was already queued/cancelled/executed ++ */ ++ public boolean queue(); ++ ++ /** ++ * Returns whether this task has been queued and is not completing. ++ * @return {@code true} If the task has been queued, {@code false} if the task has not been queued or is marked ++ * as completing. ++ */ ++ public boolean isQueued(); ++ ++ /** ++ * 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. ++ *

    ++ * Exceptions thrown from the runnable will be rethrown. ++ *

    ++ * ++ * @return {@code true} if this task was executed, {@code false} if it was already marked as completed. ++ */ ++ public boolean execute(); + + /** + * Returns the current priority. Note that {@link Priority#COMPLETING} will be returned @@ -2371,7 +2512,7 @@ index 0000000000000000000000000000000000000000..91beb6f23f257cf265fe3150f760892e + * + * @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. ++ * this task was scheduled on was shutdown, or if the priority was already at the specified level. + */ + public boolean setPriority(final Priority priority); + @@ -2381,7 +2522,8 @@ index 0000000000000000000000000000000000000000..91beb6f23f257cf265fe3150f760892e + * @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. ++ * @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 Priority priority); + @@ -2391,7417 +2533,7165 @@ index 0000000000000000000000000000000000000000..91beb6f23f257cf265fe3150f760892e + * @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. ++ * @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 Priority priority); ++ ++ /** ++ * Returns the suborder id associated with this task. ++ * @return The suborder id associated with this task. ++ */ ++ public long getSubOrder(); ++ ++ /** ++ * Sets the suborder id associated with this task. Ths function has no effect when this task ++ * is completing or is completed. ++ * ++ * @param subOrder Specified new sub order. ++ * ++ * @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 current suborder is the same as the new sub order. ++ */ ++ public boolean setSubOrder(final long subOrder); ++ ++ /** ++ * Attempts to raise the suborder to the suborder specified. ++ * ++ * @param subOrder Specified new sub order. ++ * ++ * @return {@code false} if the current task is completing, {@code true} if the suborder was raised to the ++ * specified suborder or was already at the specified suborder or higher. ++ */ ++ public boolean raiseSubOrder(final long subOrder); ++ ++ /** ++ * Attempts to lower the suborder to the suborder specified. ++ * ++ * @param subOrder Specified new sub order. ++ * ++ * @return {@code false} if the current task is completing, {@code true} if the suborder was lowered to the ++ * specified suborder or was already at the specified suborder or lower. ++ */ ++ public boolean lowerSubOrder(final long subOrder); ++ ++ /** ++ * Sets the priority and suborder id associated with this task. Ths function has no effect when this task ++ * is completing or is completed. ++ * ++ * @param priority Priority specified ++ * @param subOrder Specified new sub order. ++ * @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 current priority and suborder are the same as ++ * the parameters. ++ */ ++ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder); + } +} -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedQueueExecutorThread.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedQueueExecutorThread.java +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/queue/PrioritisedTaskQueue.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/queue/PrioritisedTaskQueue.java new file mode 100644 -index 0000000000000000000000000000000000000000..d1683ba6350e530373944f98192c0f2baf241e70 +index 0000000000000000000000000000000000000000..edb8c6611bdc9aced2714b963e00bbb7829603d2 --- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedQueueExecutorThread.java -@@ -0,0 +1,301 @@ -+package ca.spottedleaf.concurrentutil.executor.standard; ++++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/queue/PrioritisedTaskQueue.java +@@ -0,0 +1,454 @@ ++package ca.spottedleaf.concurrentutil.executor.queue; + ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import org.slf4j.Logger; -+import org.slf4j.LoggerFactory; ++import ca.spottedleaf.concurrentutil.util.Priority; +import java.lang.invoke.VarHandle; -+import java.util.concurrent.locks.LockSupport; -+ -+/** -+ * Thread which will continuously drain from a specified queue. -+ *

    -+ * 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. -+ *

    -+ */ -+public class PrioritisedQueueExecutorThread extends Thread implements PrioritisedExecutor { ++import java.util.Comparator; ++import java.util.Map; ++import java.util.concurrent.ConcurrentSkipListMap; ++import java.util.concurrent.atomic.AtomicBoolean; ++import java.util.concurrent.atomic.AtomicLong; + -+ private static final Logger LOGGER = LoggerFactory.getLogger(PrioritisedQueueExecutorThread.class); ++public final class PrioritisedTaskQueue implements PrioritisedExecutor { + -+ protected final PrioritisedExecutor queue; ++ /** ++ * Required for tie-breaking in the queue ++ */ ++ private final AtomicLong taskIdGenerator = new AtomicLong(); ++ private final AtomicLong scheduledTasks = new AtomicLong(); ++ private final AtomicLong executedTasks = new AtomicLong(); ++ private final AtomicLong subOrderGenerator = new AtomicLong(); ++ private final AtomicBoolean shutdown = new AtomicBoolean(); ++ private final ConcurrentSkipListMap tasks = new ConcurrentSkipListMap<>(PrioritisedQueuedTask.COMPARATOR); + -+ protected volatile boolean threadShutdown; ++ @Override ++ public long getTotalTasksScheduled() { ++ return this.scheduledTasks.get(); ++ } + -+ protected volatile boolean threadParked; -+ protected static final VarHandle THREAD_PARKED_HANDLE = ConcurrentUtil.getVarHandle(PrioritisedQueueExecutorThread.class, "threadParked", boolean.class); ++ @Override ++ public long getTotalTasksExecuted() { ++ return this.executedTasks.get(); ++ } + -+ protected volatile boolean halted; ++ @Override ++ public long generateNextSubOrder() { ++ return this.subOrderGenerator.getAndIncrement(); ++ } + -+ protected final long spinWaitTime; ++ @Override ++ public boolean shutdown() { ++ return !this.shutdown.getAndSet(true); ++ } + -+ static final long DEFAULT_SPINWAIT_TIME = (long)(0.1e6);// 0.1ms ++ @Override ++ public boolean isShutdown() { ++ return this.shutdown.get(); ++ } + -+ public PrioritisedQueueExecutorThread(final PrioritisedExecutor queue) { -+ this(queue, DEFAULT_SPINWAIT_TIME); // 0.1ms ++ public PrioritisedTask peekFirst() { ++ final Map.Entry firstEntry = this.tasks.firstEntry(); ++ return firstEntry == null ? null : firstEntry.getKey().task; + } + -+ public PrioritisedQueueExecutorThread(final PrioritisedExecutor queue, final long spinWaitTime) { // in ns -+ this.queue = queue; -+ this.spinWaitTime = spinWaitTime; ++ public Priority getHighestPriority() { ++ final Map.Entry firstEntry = this.tasks.firstEntry(); ++ return firstEntry == null ? null : Priority.getPriority(firstEntry.getKey().priority); + } + -+ @Override -+ public void run() { -+ final long spinWaitTime = this.spinWaitTime; ++ public boolean hasNoScheduledTasks() { ++ final long executedTasks = this.executedTasks.get(); ++ final long scheduledTasks = this.scheduledTasks.get(); + -+ main_loop: -+ for (;;) { -+ this.pollTasks(); ++ return executedTasks == scheduledTasks; ++ } + -+ // spinwait ++ public PrioritySubOrderPair getHighestPrioritySubOrder() { ++ final Map.Entry firstEntry = this.tasks.firstEntry(); ++ if (firstEntry == null) { ++ return null; ++ } + -+ final long start = System.nanoTime(); ++ final PrioritisedQueuedTask.Holder holder = firstEntry.getKey(); + -+ 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 ++ return new PrioritySubOrderPair(Priority.getPriority(holder.priority), holder.subOrder); ++ } + -+ if (this.pollTasks()) { -+ // restart loop, found tasks -+ continue main_loop; ++ public Runnable pollTask() { ++ for (;;) { ++ final Map.Entry firstEntry = this.tasks.pollFirstEntry(); ++ if (firstEntry != null) { ++ final PrioritisedQueuedTask.Holder task = firstEntry.getKey(); ++ task.markRemoved(); ++ if (!task.task.cancel()) { ++ continue; + } ++ return task.task.execute; ++ } + -+ if (this.handleClose()) { -+ return; // we're done -+ } ++ return null; ++ } ++ } + -+ if ((System.nanoTime() - start) >= spinWaitTime) { -+ break; ++ @Override ++ public boolean executeTask() { ++ for (;;) { ++ final Map.Entry firstEntry = this.tasks.pollFirstEntry(); ++ if (firstEntry != null) { ++ final PrioritisedQueuedTask.Holder task = firstEntry.getKey(); ++ task.markRemoved(); ++ if (!task.task.execute()) { ++ continue; + } ++ return true; + } + -+ if (this.handleClose()) { -+ return; -+ } ++ return false; ++ } ++ } + -+ this.setThreadParkedVolatile(true); ++ @Override ++ public PrioritisedTask createTask(final Runnable task) { ++ return this.createTask(task, Priority.NORMAL, this.generateNextSubOrder()); ++ } + -+ // 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; -+ } ++ @Override ++ public PrioritisedTask createTask(final Runnable task, final Priority priority) { ++ return this.createTask(task, priority, this.generateNextSubOrder()); ++ } + -+ if (this.handleClose()) { -+ return; -+ } ++ @Override ++ public PrioritisedTask createTask(final Runnable task, final Priority priority, final long subOrder) { ++ return new PrioritisedQueuedTask(task, priority, subOrder); ++ } + -+ // 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"); -+ } -+ } ++ @Override ++ public PrioritisedTask queueTask(final Runnable task) { ++ return this.queueTask(task, Priority.NORMAL, this.generateNextSubOrder()); + } + -+ /** -+ * Attempts to poll as many tasks as possible, returning when finished. -+ * @return Whether any tasks were executed. -+ */ -+ 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; ++ @Override ++ public PrioritisedTask queueTask(final Runnable task, final Priority priority) { ++ return this.queueTask(task, priority, this.generateNextSubOrder()); + } + -+ protected boolean handleClose() { -+ if (this.threadShutdown) { -+ this.pollTasks(); // this ensures we've emptied the queue -+ return true; -+ } -+ return false; -+ } ++ @Override ++ public PrioritisedTask queueTask(final Runnable task, final Priority priority, final long subOrder) { ++ final PrioritisedQueuedTask ret = new PrioritisedQueuedTask(task, priority, subOrder); + -+ /** -+ * 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; -+ } ++ ret.queue(); + -+ @Override -+ public PrioritisedTask createTask(final Runnable task, final Priority priority) { -+ final PrioritisedTask queueTask = this.queue.createTask(task, priority); ++ return ret; ++ } + -+ // need to override queue() to notify us of tasks -+ return new PrioritisedTask() { -+ @Override -+ public Priority getPriority() { -+ return queueTask.getPriority(); ++ private final class PrioritisedQueuedTask implements PrioritisedExecutor.PrioritisedTask { ++ public static final Comparator COMPARATOR = (final PrioritisedQueuedTask.Holder t1, final PrioritisedQueuedTask.Holder t2) -> { ++ final int priorityCompare = t1.priority - t2.priority; ++ if (priorityCompare != 0) { ++ return priorityCompare; + } + -+ @Override -+ public boolean setPriority(final Priority priority) { -+ return queueTask.setPriority(priority); ++ final int subOrderCompare = Long.compare(t1.subOrder, t2.subOrder); ++ if (subOrderCompare != 0) { ++ return subOrderCompare; + } + -+ @Override -+ public boolean raisePriority(final Priority priority) { -+ return queueTask.raisePriority(priority); -+ } ++ return Long.compare(t1.id, t2.id); ++ }; + -+ @Override -+ public boolean lowerPriority(final Priority priority) { -+ return queueTask.lowerPriority(priority); -+ } ++ private static final class Holder { ++ private final PrioritisedQueuedTask task; ++ private final int priority; ++ private final long subOrder; ++ private final long id; + -+ @Override -+ public boolean queue() { -+ final boolean ret = queueTask.queue(); -+ if (ret) { -+ PrioritisedQueueExecutorThread.this.notifyTasks(); -+ } -+ return ret; -+ } ++ private volatile boolean removed; ++ private static final VarHandle REMOVED_HANDLE = ConcurrentUtil.getVarHandle(Holder.class, "removed", boolean.class); + -+ @Override -+ public boolean cancel() { -+ return queueTask.cancel(); ++ private Holder(final PrioritisedQueuedTask task, final int priority, final long subOrder, ++ final long id) { ++ this.task = task; ++ this.priority = priority; ++ this.subOrder = subOrder; ++ this.id = id; + } + -+ @Override -+ public boolean execute() { -+ return queueTask.execute(); ++ /** ++ * Returns true if marked as removed ++ */ ++ public boolean markRemoved() { ++ return !(boolean)REMOVED_HANDLE.getAndSet((Holder)this, (boolean)true); + } -+ }; -+ } -+ -+ @Override -+ public PrioritisedTask queueRunnable(final Runnable task, final Priority priority) { -+ final PrioritisedTask ret = this.queue.queueRunnable(task, priority); -+ -+ this.notifyTasks(); ++ } + -+ return ret; -+ } ++ private final long id; ++ private final Runnable execute; + -+ @Override -+ public boolean haveAllTasksExecuted() { -+ return this.queue.haveAllTasksExecuted(); -+ } ++ private Priority priority; ++ private long subOrder; ++ private Holder holder; + -+ @Override -+ public long getTotalTasksExecuted() { -+ return this.queue.getTotalTasksExecuted(); -+ } ++ public PrioritisedQueuedTask(final Runnable execute, final Priority priority, final long subOrder) { ++ if (!Priority.isValidPriority(priority)) { ++ throw new IllegalArgumentException("Invalid priority " + priority); ++ } + -+ @Override -+ public long getTotalTasksScheduled() { -+ return this.queue.getTotalTasksScheduled(); -+ } ++ this.execute = execute; ++ this.priority = priority; ++ this.subOrder = subOrder; ++ this.id = PrioritisedTaskQueue.this.taskIdGenerator.getAndIncrement(); ++ } + -+ /** -+ * {@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"); ++ @Override ++ public PrioritisedExecutor getExecutor() { ++ return PrioritisedTaskQueue.this; + } -+ this.queue.waitUntilAllExecuted(); -+ } + -+ /** -+ * {@inheritDoc} -+ * @throws IllegalStateException Always -+ */ -+ @Override -+ public boolean executeTask() throws IllegalStateException { -+ throw new IllegalStateException(); -+ } ++ @Override ++ public boolean queue() { ++ synchronized (this) { ++ if (this.holder != null || this.priority == Priority.COMPLETING) { ++ return false; ++ } + -+ /** -+ * Closes this queue executor's queue. Optionally waits for all tasks in queue to be executed if {@code wait} is true. -+ *

    -+ * This function is MT-Safe. -+ *

    -+ * @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; ++ if (PrioritisedTaskQueue.this.isShutdown()) { ++ throw new IllegalStateException("Queue is shutdown"); ++ } + -+ // force thread to respond to the shutdown -+ this.setThreadParkedVolatile(false); -+ LockSupport.unpark(this); ++ final Holder holder = new Holder(this, this.priority.priority, this.subOrder, this.id); ++ this.holder = holder; + -+ if (wait) { -+ this.waitUntilAllExecuted(); -+ } ++ PrioritisedTaskQueue.this.scheduledTasks.getAndIncrement(); ++ PrioritisedTaskQueue.this.tasks.put(holder, Boolean.TRUE); ++ } + -+ return ret; -+ } ++ if (PrioritisedTaskQueue.this.isShutdown()) { ++ this.cancel(); ++ throw new IllegalStateException("Queue is shutdown"); ++ } + + -+ /** -+ * Causes this thread to exit without draining the queue. To ensure tasks are completed, use {@link #close(boolean, boolean)}. -+ *

    -+ * This is not safe to call with {@link #close(boolean, boolean)} if wait = true, in which case -+ * the waiting thread may block indefinitely. -+ *

    -+ *

    -+ * This function is MT-Safe. -+ *

    -+ * @param killQueue Whether to shutdown this thread's queue -+ * @see #close(boolean, boolean) -+ */ -+ public void halt(final boolean killQueue) { -+ if (killQueue) { -+ this.queue.shutdown(); ++ return true; + } -+ this.threadShutdown = true; -+ this.halted = true; + -+ // force thread to respond to the shutdown -+ this.setThreadParkedVolatile(false); -+ LockSupport.unpark(this); -+ } ++ @Override ++ public boolean isQueued() { ++ synchronized (this) { ++ return this.holder != null && this.priority != Priority.COMPLETING; ++ } ++ } + -+ protected final boolean getThreadParkedVolatile() { -+ return (boolean)THREAD_PARKED_HANDLE.getVolatile(this); -+ } ++ @Override ++ public boolean cancel() { ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING) { ++ return false; ++ } + -+ protected final boolean exchangeThreadParkedVolatile(final boolean value) { -+ return (boolean)THREAD_PARKED_HANDLE.getAndSet(this, value); -+ } ++ this.priority = Priority.COMPLETING; + -+ 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..2ba36e29d0d8693f2f5e6c6d195ca27f2a5099aa ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedThreadPool.java -@@ -0,0 +1,632 @@ -+package ca.spottedleaf.concurrentutil.executor.standard; ++ if (this.holder != null) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ PrioritisedTaskQueue.this.executedTasks.getAndIncrement(); ++ } + -+import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; -+import org.slf4j.Logger; -+import org.slf4j.LoggerFactory; -+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; ++ return true; ++ } ++ } + -+public final class PrioritisedThreadPool { ++ @Override ++ public boolean execute() { ++ final boolean increaseExecuted; + -+ private static final Logger LOGGER = LoggerFactory.getLogger(PrioritisedThreadPool.class); ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING) { ++ return false; ++ } + -+ private final PrioritisedThread[] threads; -+ private final TreeSet queues = new TreeSet<>(PrioritisedPoolExecutorImpl.comparator()); -+ private final String name; -+ private final long queueMaxHoldTime; ++ this.priority = Priority.COMPLETING; + -+ private final ReferenceOpenHashSet nonShutdownQueues = new ReferenceOpenHashSet<>(); -+ private final ReferenceOpenHashSet activeQueues = new ReferenceOpenHashSet<>(); ++ if (increaseExecuted = (this.holder != null)) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ } ++ } + -+ private boolean shutdown; ++ try { ++ this.execute.run(); ++ return true; ++ } finally { ++ if (increaseExecuted) { ++ PrioritisedTaskQueue.this.executedTasks.getAndIncrement(); ++ } ++ } ++ } + -+ private long schedulingIdGenerator; ++ @Override ++ public Priority getPriority() { ++ synchronized (this) { ++ return this.priority; ++ } ++ } + -+ private static final long DEFAULT_QUEUE_HOLD_TIME = (long)(5.0e6); ++ @Override ++ public boolean setPriority(final Priority priority) { ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING || this.priority == priority) { ++ return false; ++ } + -+ /** -+ * @param name Specified debug name of this thread pool -+ * @param threads The number of threads to use -+ */ -+ public PrioritisedThreadPool(final String name, final int threads) { -+ this(name, threads, null); -+ } ++ this.priority = priority; + -+ /** -+ * @param name Specified debug name of this thread pool -+ * @param threads The number of threads to use -+ * @param threadModifier Invoked for each created thread with its incremental id before starting them -+ */ -+ public PrioritisedThreadPool(final String name, final int threads, final BiConsumer threadModifier) { -+ this(name, threads, threadModifier, DEFAULT_QUEUE_HOLD_TIME); // 5ms -+ } ++ if (this.holder != null) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); ++ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); ++ } + -+ /** -+ * @param name Specified debug name of this thread pool -+ * @param threads The number of threads to use -+ * @param threadModifier Invoked for each created thread with its incremental id before starting them -+ * @param queueHoldTime The maximum amount of time to spend executing tasks in a specific queue before attempting -+ * to switch to another queue, per thread -+ */ -+ public PrioritisedThreadPool(final String name, final int threads, final BiConsumer 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"); ++ return true; ++ } + } -+ this.name = name; -+ this.queueMaxHoldTime = queueHoldTime; + -+ this.threads = new PrioritisedThread[threads]; -+ for (int i = 0; i < threads; ++i) { -+ this.threads[i] = new PrioritisedThread(this); ++ @Override ++ public boolean raisePriority(final Priority priority) { ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING || this.priority.isHigherOrEqualPriority(priority)) { ++ return false; ++ } + -+ // 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); -+ }); ++ this.priority = priority; + -+ // let thread modifier override defaults -+ if (threadModifier != null) { -+ threadModifier.accept(this.threads[i], Integer.valueOf(i)); -+ } ++ if (this.holder != null) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); ++ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); ++ } + -+ // now the thread can start -+ this.threads[i].start(); ++ return true; ++ } + } -+ } + -+ /** -+ * Returns an array representing the threads backing this thread pool. -+ */ -+ public Thread[] getThreads() { -+ return Arrays.copyOf(this.threads, this.threads.length, Thread[].class); -+ } ++ @Override ++ public boolean lowerPriority(Priority priority) { ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING || this.priority.isLowerOrEqualPriority(priority)) { ++ return false; ++ } + -+ /** -+ * Creates and returns a {@link PrioritisedPoolExecutor} to schedule tasks onto. The returned executor will execute -+ * tasks on this thread pool only. -+ * @param name The debug name of the executor. -+ * @param minParallelism The minimum number of threads to be executing tasks from the returned executor -+ * before threads may be allocated to other queues in this thread pool. -+ * @param parallelism The maximum number of threads which may be executing tasks from the returned executor. -+ * @throws IllegalStateException If this thread pool is shut down -+ */ -+ public PrioritisedPoolExecutor createExecutor(final String name, final int minParallelism, 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), -+ Math.min(Math.max(0, minParallelism), this.threads.length) -+ ); ++ this.priority = priority; + -+ this.nonShutdownQueues.add(ret); ++ if (this.holder != null) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); ++ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); ++ } + -+ synchronized (this.activeQueues) { -+ this.activeQueues.add(ret); ++ return true; + } ++ } + -+ return ret; ++ @Override ++ public long getSubOrder() { ++ synchronized (this) { ++ return this.subOrder; ++ } + } -+ } + -+ /** -+ * 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 queuesToShutdown; -+ synchronized (this.nonShutdownQueues) { -+ this.shutdown = true; -+ queuesToShutdown = new ArrayList<>(this.nonShutdownQueues); -+ } -+ -+ for (final PrioritisedPoolExecutorImpl queue : queuesToShutdown) { -+ queue.shutdown(); -+ } -+ } ++ @Override ++ public boolean setSubOrder(final long subOrder) { ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING || this.subOrder == subOrder) { ++ return false; ++ } + ++ this.subOrder = subOrder; + -+ for (final PrioritisedThread thread : this.threads) { -+ // can't kill queue, queue is null -+ thread.halt(false); -+ } -+ } ++ if (this.holder != null) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); ++ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); ++ } + -+ /** -+ * 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); ++ return true; ++ } + } -+ } + -+ /** -+ * 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); -+ } ++ @Override ++ public boolean raiseSubOrder(long subOrder) { ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING || this.subOrder >= subOrder) { ++ return false; ++ } + -+ 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; -+ } ++ this.subOrder = subOrder; + -+ try { -+ thread.join(Math.max(1L, (deadline - current) / (1000 * 1000))); -+ } catch (final InterruptedException ex) { -+ if (interruptable) { -+ throw ex; -+ } -+ interrupted = true; ++ if (this.holder != null) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); + } ++ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); ++ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); + } -+ } + -+ return true; -+ } finally { -+ if (interrupted) { -+ Thread.currentThread().interrupt(); ++ return true; + } + } -+ } + -+ /** -+ * Shuts down this thread pool, optionally waiting for all tasks to be executed. -+ * This function will invoke {@link PrioritisedPoolExecutor#shutdown()} on all created executors on this -+ * thread pool. -+ * @param wait Whether to wait for tasks to be executed -+ */ -+ public void shutdown(final boolean wait) { -+ final ArrayList queuesToShutdown; -+ synchronized (this.nonShutdownQueues) { -+ this.shutdown = true; -+ queuesToShutdown = new ArrayList<>(this.nonShutdownQueues); -+ } ++ @Override ++ public boolean lowerSubOrder(final long subOrder) { ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING || this.subOrder <= subOrder) { ++ return false; ++ } + -+ for (final PrioritisedPoolExecutorImpl queue : queuesToShutdown) { -+ queue.shutdown(); -+ } ++ this.subOrder = subOrder; + -+ for (final PrioritisedThread thread : this.threads) { -+ // none of these can be true or else NPE -+ thread.close(false, false); -+ } ++ if (this.holder != null) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); ++ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); ++ } + -+ if (wait) { -+ final ArrayList queues; -+ synchronized (this.activeQueues) { -+ queues = new ArrayList<>(this.activeQueues); -+ } -+ for (final PrioritisedPoolExecutorImpl queue : queues) { -+ queue.waitUntilAllExecuted(); ++ return true; + } + } -+ } -+ -+ protected static final class PrioritisedThread extends PrioritisedQueueExecutorThread { + -+ protected final PrioritisedThreadPool pool; -+ protected final AtomicBoolean alertedHighPriority = new AtomicBoolean(); ++ @Override ++ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder) { ++ synchronized (this) { ++ if (this.priority == Priority.COMPLETING || (this.priority == priority && this.subOrder == subOrder)) { ++ return false; ++ } + -+ public PrioritisedThread(final PrioritisedThreadPool pool) { -+ super(null); -+ this.pool = pool; -+ } ++ this.priority = priority; ++ this.subOrder = subOrder; + -+ public boolean alertHighPriorityExecutor() { -+ if (!this.notifyTasks()) { -+ if (!this.alertedHighPriority.get()) { -+ this.alertedHighPriority.set(true); ++ if (this.holder != null) { ++ if (this.holder.markRemoved()) { ++ PrioritisedTaskQueue.this.tasks.remove(this.holder); ++ } ++ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); ++ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); + } -+ return false; -+ } + -+ return true; ++ return true; ++ } + } ++ } + -+ private boolean isAlertedHighPriority() { -+ return this.alertedHighPriority.get() && this.alertedHighPriority.getAndSet(false); -+ } ++ public static record PrioritySubOrderPair(Priority priority, long subOrder) {} ++} +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedQueueExecutorThread.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedQueueExecutorThread.java +new file mode 100644 +index 0000000000000000000000000000000000000000..f5367a13aaa02f0f929813c00a67e6ac7c8652cb +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedQueueExecutorThread.java +@@ -0,0 +1,402 @@ ++package ca.spottedleaf.concurrentutil.executor.thread; + -+ @Override -+ protected boolean pollTasks() { -+ final PrioritisedThreadPool pool = this.pool; -+ final TreeSet queues = this.pool.queues; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; ++import java.lang.invoke.VarHandle; ++import java.util.concurrent.locks.LockSupport; + -+ 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; -+ } ++/** ++ * Thread which will continuously drain from a specified queue. ++ *

    ++ * 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, use the methods provided on this class to schedule tasks. ++ *

    ++ */ ++public class PrioritisedQueueExecutorThread extends Thread implements PrioritisedExecutor { + -+ 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... -+ } ++ private static final Logger LOGGER = LoggerFactory.getLogger(PrioritisedQueueExecutorThread.class); + -+ // 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); ++ protected final PrioritisedExecutor queue; + -+ 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; -+ } ++ protected volatile boolean threadShutdown; + -+ // 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; -+ } -+ } -+ } ++ protected volatile boolean threadParked; ++ protected static final VarHandle THREAD_PARKED_HANDLE = ConcurrentUtil.getVarHandle(PrioritisedQueueExecutorThread.class, "threadParked", boolean.class); + -+ return ret; -+ } -+ } ++ protected volatile boolean halted; + -+ public interface PrioritisedPoolExecutor extends PrioritisedExecutor { ++ protected final long spinWaitTime; + -+ /** -+ * Removes this queue from the thread pool without shutting the queue down or waiting for queued tasks to be executed -+ */ -+ public void halt(); ++ protected static final long DEFAULT_SPINWAIT_TIME = (long)(0.1e6);// 0.1ms + -+ /** -+ * 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(); ++ public PrioritisedQueueExecutorThread(final PrioritisedExecutor queue) { ++ this(queue, DEFAULT_SPINWAIT_TIME); // 0.1ms + } + -+ protected static final class PrioritisedPoolExecutorImpl extends PrioritisedThreadedTaskQueue implements PrioritisedPoolExecutor { ++ public PrioritisedQueueExecutorThread(final PrioritisedExecutor queue, final long spinWaitTime) { // in ns ++ this.queue = queue; ++ this.spinWaitTime = spinWaitTime; ++ } + -+ protected final PrioritisedThreadPool pool; -+ protected final long[] priorityCounts = new long[Priority.TOTAL_SCHEDULABLE_PRIORITIES]; -+ protected long schedulingId; -+ protected int concurrentExecutors; -+ protected Priority scheduledPriority; ++ @Override ++ public final void run() { ++ try { ++ this.begin(); ++ this.doRun(); ++ } finally { ++ this.die(); ++ } ++ } + -+ protected final String name; -+ protected final int maximumExecutors; -+ protected final int minimumExecutors; -+ protected boolean isQueued; ++ public final void doRun() { ++ final long spinWaitTime = this.spinWaitTime; + -+ public PrioritisedPoolExecutorImpl(final PrioritisedThreadPool pool, final String name, final int maximumExecutors, final int minimumExecutors) { -+ this.pool = pool; -+ this.name = name; -+ this.maximumExecutors = maximumExecutors; -+ this.minimumExecutors = minimumExecutors; -+ } ++ main_loop: ++ for (;;) { ++ this.pollTasks(); + -+ public static Comparator comparator() { -+ return (final PrioritisedPoolExecutorImpl p1, final PrioritisedPoolExecutorImpl p2) -> { -+ if (p1 == p2) { -+ return 0; -+ } ++ // spinwait + -+ final int belowMin1 = p1.minimumExecutors - p1.concurrentExecutors; -+ final int belowMin2 = p2.minimumExecutors - p2.concurrentExecutors; ++ final long start = System.nanoTime(); + -+ // test minimum executors -+ if (belowMin1 > 0 || belowMin2 > 0) { -+ // want the largest belowMin to be first -+ final int minCompare = Integer.compare(belowMin2, belowMin1); ++ 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 (minCompare != 0) { -+ return minCompare; -+ } ++ if (this.pollTasks()) { ++ // restart loop, found tasks ++ continue main_loop; + } + -+ // prefer higher priority -+ final int priorityCompare = p1.scheduledPriority.ordinal() - p2.scheduledPriority.ordinal(); -+ if (priorityCompare != 0) { -+ return priorityCompare; ++ if (this.handleClose()) { ++ return; // we're done + } + -+ // 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 ((System.nanoTime() - start) >= spinWaitTime) { ++ break; + } ++ } + -+ // if all else fails here we just choose whichever executor was queued first -+ return Long.compare(p1.schedulingId, p2.schedulingId); -+ }; -+ } ++ if (this.handleClose()) { ++ return; ++ } + -+ private boolean isHalted; ++ this.setThreadParkedVolatile(true); + -+ @Override -+ public void halt() { -+ final PrioritisedThreadPool pool = this.pool; -+ final TreeSet 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); ++ // 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; + } -+ } -+ -+ @Override -+ public boolean isActive() { -+ final PrioritisedThreadPool pool = this.pool; -+ final TreeSet queues = pool.queues; + -+ synchronized (queues) { -+ if (this.concurrentExecutors != 0) { -+ return true; -+ } -+ synchronized (pool.activeQueues) { -+ if (pool.activeQueues.contains(this)) { -+ return true; -+ } -+ } ++ if (this.handleClose()) { ++ return; + } + -+ return false; ++ // 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"); ++ } + } ++ } + -+ 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(); ++ protected void begin() {} + -+ if (from == null && to == Priority.COMPLETING) { -+ throw new IllegalStateException("Cannot complete task without queueing it first"); -+ } ++ protected void die() {} + -+ // we should only notify for queueing of tasks, not changing priorities -+ final boolean shouldNotifyTasks = from == null; ++ /** ++ * Attempts to poll as many tasks as possible, returning when finished. ++ * @return Whether any tasks were executed. ++ */ ++ protected boolean pollTasks() { ++ boolean ret = false; + -+ 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; ++ for (;;) { ++ if (this.halted) { ++ break; + } -+ -+ // 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) { ++ try { ++ if (!this.queue.executeTask()) { + 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 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; -+ } -+ } ++ ret = true; ++ } catch (final Throwable throwable) { ++ LOGGER.error("Exception thrown from prioritized runnable task in thread '" + this.getName() + "'", throwable); + } + } + -+ @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 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 ++ return ret; ++ } + -+ if (this.isQueued) { -+ queues.remove(this); -+ this.scheduledPriority = Priority.HIGHEST; -+ queues.add(this); -+ } else { -+ this.scheduledPriority = Priority.HIGHEST; -+ } -+ } ++ protected boolean handleClose() { ++ if (this.threadShutdown) { ++ this.pollTasks(); // this ensures we've emptied the queue ++ return true; ++ } ++ return false; ++ } + -+ return ret; ++ /** ++ * 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; + } -+} -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..3e8401b1b1f833c4f01bc87059a2f48d761d989f ---- /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; ++ @Override ++ public long getTotalTasksExecuted() { ++ return this.queue.getTotalTasksExecuted(); ++ } + -+public class PrioritisedThreadedTaskQueue implements PrioritisedExecutor { ++ @Override ++ public long getTotalTasksScheduled() { ++ return this.queue.getTotalTasksScheduled(); ++ } + -+ protected final ArrayDeque[] queues = new ArrayDeque[Priority.TOTAL_SCHEDULABLE_PRIORITIES]; { -+ for (int i = 0; i < Priority.TOTAL_SCHEDULABLE_PRIORITIES; ++i) { -+ this.queues[i] = new ArrayDeque<>(); -+ } ++ @Override ++ public long generateNextSubOrder() { ++ return this.queue.generateNextSubOrder(); + } + -+ // 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(); ++ @Override ++ public boolean shutdown() { ++ throw new UnsupportedOperationException(); ++ } + -+ // 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; ++ @Override ++ public boolean isShutdown() { ++ return false; ++ } + -+ protected long taskIdGenerator = 0; ++ /** ++ * {@inheritDoc} ++ * @throws IllegalStateException Always ++ */ ++ @Override ++ public boolean executeTask() throws IllegalStateException { ++ throw new IllegalStateException(); ++ } + + @Override -+ public PrioritisedExecutor.PrioritisedTask queueRunnable(final Runnable task, final Priority priority) throws IllegalStateException, IllegalArgumentException { -+ if (!Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Priority " + priority + " is invalid"); -+ } -+ if (task == null) { -+ throw new NullPointerException("Task cannot be null"); -+ } ++ public PrioritisedTask queueTask(final Runnable task) { ++ final PrioritisedTask ret = this.createTask(task); + -+ 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"); -+ } ++ ret.queue(); ++ ++ return ret; ++ } + -+ final PrioritisedTask ret; ++ @Override ++ public PrioritisedTask queueTask(final Runnable task, final Priority priority) { ++ final PrioritisedTask ret = this.createTask(task, priority); + -+ synchronized (this.queues) { -+ if (this.hasShutdown) { -+ throw new IllegalStateException("Queue has shutdown"); -+ } -+ this.getAndAddTotalScheduledTasksVolatile(1L); ++ ret.queue(); + -+ ret = new PrioritisedTask(this.taskIdGenerator++, task, priority, this); ++ return ret; ++ } + -+ this.queues[ret.priority.priority].add(ret); ++ @Override ++ public PrioritisedTask queueTask(final Runnable task, final Priority priority, final long subOrder) { ++ final PrioritisedTask ret = this.createTask(task, priority, subOrder); + -+ // call priority change callback (note: only after we successfully queue!) -+ this.priorityChange(ret, null, priority); -+ } ++ ret.queue(); + + return ret; + } + ++ + @Override -+ public PrioritisedExecutor.PrioritisedTask createTask(final Runnable task, final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Priority " + priority + " is invalid"); -+ } -+ if (task == null) { -+ throw new NullPointerException("Task cannot be null"); -+ } ++ public PrioritisedTask createTask(Runnable task) { ++ final PrioritisedTask queueTask = this.queue.createTask(task); + -+ return new PrioritisedTask(task, priority, this); ++ return new WrappedTask(queueTask); + } + + @Override -+ public long getTotalTasksScheduled() { -+ return this.totalScheduledTasks.get(); ++ public PrioritisedTask createTask(final Runnable task, final Priority priority) { ++ final PrioritisedTask queueTask = this.queue.createTask(task, priority); ++ ++ return new WrappedTask(queueTask); + } + + @Override -+ public long getTotalTasksExecuted() { -+ return this.totalCompletedTasks.get(); -+ } ++ public PrioritisedTask createTask(final Runnable task, final Priority priority, final long subOrder) { ++ final PrioritisedTask queueTask = this.queue.createTask(task, priority, subOrder); + -+ // 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) {} ++ return new WrappedTask(queueTask); ++ } + + /** -+ * Polls the highest priority task currently available. {@code null} if none. This will mark the -+ * returned task as completed. ++ * Closes this queue executor's queue. Optionally waits for all tasks in queue to be executed if {@code wait} is true. ++ *

    ++ * This function is MT-Safe. ++ *

    ++ * @param wait If this call is to wait until this thread shuts down. ++ * @param killQueue Whether to shutdown this thread's queue ++ * @return whether this thread shut down the queue ++ * @see #halt(boolean) + */ -+ protected PrioritisedTask poll() { -+ return this.poll(Priority.IDLE); -+ } ++ public boolean close(final boolean wait, final boolean killQueue) { ++ final boolean ret = killQueue && this.queue.shutdown(); ++ this.threadShutdown = true; + -+ protected PrioritisedTask poll(final Priority minPriority) { -+ final ArrayDeque[] queues = this.queues; -+ synchronized (queues) { -+ final int max = minPriority.priority; -+ for (int i = 0; i <= max; ++i) { -+ final ArrayDeque queue = queues[i]; -+ PrioritisedTask task; -+ while ((task = queue.pollFirst()) != null) { -+ if (task.trySetCompleting(i)) { -+ return task; ++ // force thread to respond to the shutdown ++ this.setThreadParkedVolatile(false); ++ LockSupport.unpark(this); ++ ++ if (wait) { ++ boolean interrupted = false; ++ for (;;) { ++ if (this.isAlive()) { ++ if (interrupted) { ++ Thread.currentThread().interrupt(); + } ++ break; ++ } ++ try { ++ this.join(); ++ } catch (final InterruptedException ex) { ++ interrupted = true; + } + } + } + -+ return null; ++ return ret; + } + ++ + /** -+ * 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. ++ * Causes this thread to exit without draining the queue. To ensure tasks are completed, use {@link #close(boolean, boolean)}. ++ *

    ++ * This is not safe to call with {@link #close(boolean, boolean)} if wait = true, in which case ++ * the waiting thread may block indefinitely. ++ *

    ++ *

    ++ * This function is MT-Safe. ++ *

    ++ * @param killQueue Whether to shutdown this thread's queue ++ * @see #close(boolean, boolean) + */ -+ @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; ++ public void halt(final boolean killQueue) { ++ if (killQueue) { ++ this.queue.shutdown(); + } -+ return true; -+ } -+ -+ @Override -+ public boolean isShutdown() { -+ return this.hasShutdown; -+ } -+ -+ /* totalScheduledTasks */ ++ this.threadShutdown = true; ++ this.halted = true; + -+ protected final long getTotalScheduledTasksVolatile() { -+ return this.totalScheduledTasks.get(); ++ // force thread to respond to the shutdown ++ this.setThreadParkedVolatile(false); ++ LockSupport.unpark(this); + } + -+ protected final long getAndAddTotalScheduledTasksVolatile(final long value) { -+ return this.totalScheduledTasks.getAndAdd(value); ++ protected final boolean getThreadParkedVolatile() { ++ return (boolean)THREAD_PARKED_HANDLE.getVolatile(this); + } + -+ /* totalCompletedTasks */ -+ -+ protected final long getTotalCompletedTasksVolatile() { -+ return this.totalCompletedTasks.get(); ++ protected final boolean exchangeThreadParkedVolatile(final boolean value) { ++ return (boolean)THREAD_PARKED_HANDLE.getAndSet(this, value); + } + -+ protected final long getAndAddTotalCompletedTasksVolatile(final long value) { -+ return this.totalCompletedTasks.getAndAdd(value); ++ protected final void setThreadParkedVolatile(final boolean value) { ++ THREAD_PARKED_HANDLE.setVolatile(this, 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 Priority priority; -+ -+ protected PrioritisedTask(final long id, final Runnable runnable, final Priority priority, final PrioritisedThreadedTaskQueue queue) { -+ if (!Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } ++ /** ++ * Required so that queue() can notify (unpark) this thread ++ */ ++ private final class WrappedTask implements PrioritisedTask { ++ private final PrioritisedTask queueTask; + -+ this.priority = priority; -+ this.runnable = runnable; -+ this.queue = queue; -+ this.id = id; ++ public WrappedTask(final PrioritisedTask queueTask) { ++ this.queueTask = queueTask; + } + -+ protected PrioritisedTask(final Runnable runnable, final Priority priority, final PrioritisedThreadedTaskQueue queue) { -+ if (!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 PrioritisedExecutor getExecutor() { ++ return PrioritisedQueueExecutorThread.this; + } + + @Override + public boolean queue() { -+ if (this.queue.hasShutdown) { -+ throw new IllegalStateException("Queue has shutdown"); ++ final boolean ret = this.queueTask.queue(); ++ if (ret) { ++ PrioritisedQueueExecutorThread.this.notifyTasks(); + } ++ return ret; ++ } + -+ synchronized (this.queue.queues) { -+ if (this.queue.hasShutdown) { -+ throw new IllegalStateException("Queue has shutdown"); -+ } -+ -+ final Priority priority = this.priority; -+ if (priority == 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; -+ } ++ @Override ++ public boolean isQueued() { ++ return this.queueTask.isQueued(); + } + -+ protected boolean trySetCompleting(final int minPriority) { -+ final Priority oldPriority = this.priority; -+ if (oldPriority != Priority.COMPLETING && oldPriority.isHigherOrEqualPriority(minPriority)) { -+ this.priority = Priority.COMPLETING; -+ if (this.id != NOT_SCHEDULED_ID) { -+ this.queue.priorityChange(this, oldPriority, Priority.COMPLETING); -+ } -+ return true; -+ } ++ @Override ++ public boolean cancel() { ++ return this.queueTask.cancel(); ++ } + -+ return false; ++ @Override ++ public boolean execute() { ++ return this.queueTask.execute(); + } + + @Override + public Priority getPriority() { -+ return this.priority; ++ return this.queueTask.getPriority(); + } + + @Override + public boolean setPriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } -+ synchronized (this.queue.queues) { -+ final Priority curr = this.priority; -+ -+ if (curr == Priority.COMPLETING) { -+ return false; -+ } -+ -+ if (curr == priority) { -+ return true; -+ } ++ return this.queueTask.setPriority(priority); ++ } + -+ this.priority = priority; -+ if (this.id != NOT_SCHEDULED_ID) { -+ this.queue.queues[priority.priority].add(this); ++ @Override ++ public boolean raisePriority(final Priority priority) { ++ return this.queueTask.raisePriority(priority); ++ } + -+ // call priority change callback -+ this.queue.priorityChange(this, curr, priority); -+ } -+ } ++ @Override ++ public boolean lowerPriority(final Priority priority) { ++ return this.queueTask.lowerPriority(priority); ++ } + -+ return true; ++ @Override ++ public long getSubOrder() { ++ return this.queueTask.getSubOrder(); + } + + @Override -+ public boolean raisePriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } ++ public boolean setSubOrder(final long subOrder) { ++ return this.queueTask.setSubOrder(subOrder); ++ } + -+ synchronized (this.queue.queues) { -+ final Priority curr = this.priority; ++ @Override ++ public boolean raiseSubOrder(final long subOrder) { ++ return this.queueTask.raiseSubOrder(subOrder); ++ } + -+ if (curr == Priority.COMPLETING) { -+ return false; -+ } ++ @Override ++ public boolean lowerSubOrder(final long subOrder) { ++ return this.queueTask.lowerSubOrder(subOrder); ++ } + -+ if (curr.isHigherOrEqualPriority(priority)) { -+ return true; -+ } ++ @Override ++ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder) { ++ return this.queueTask.setPriorityAndSubOrder(priority, subOrder); ++ } ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedThreadPool.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedThreadPool.java +new file mode 100644 +index 0000000000000000000000000000000000000000..cb9df914a9a6d0d3f58fa58d8c93f4f583416cd1 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedThreadPool.java +@@ -0,0 +1,741 @@ ++package ca.spottedleaf.concurrentutil.executor.thread; + -+ this.priority = priority; -+ if (this.id != NOT_SCHEDULED_ID) { -+ this.queue.queues[priority.priority].add(this); ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.queue.PrioritisedTaskQueue; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.concurrentutil.util.TimeUtil; ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; ++import java.lang.reflect.Array; ++import java.util.Arrays; ++import java.util.concurrent.atomic.AtomicBoolean; ++import java.util.concurrent.atomic.AtomicLong; ++import java.util.function.Consumer; + -+ // call priority change callback -+ this.queue.priorityChange(this, curr, priority); -+ } -+ } ++public final class PrioritisedThreadPool { + -+ return true; ++ private static final Logger LOGGER = LoggerFactory.getLogger(PrioritisedThreadPool.class); ++ ++ private final Consumer threadModifier; ++ private final COWArrayList executors = new COWArrayList<>(ExecutorGroup.class); ++ private final COWArrayList threads = new COWArrayList<>(PrioritisedThread.class); ++ private final COWArrayList aliveThreads = new COWArrayList<>(PrioritisedThread.class); ++ ++ private static final Priority HIGH_PRIORITY_NOTIFY_THRESHOLD = Priority.HIGH; ++ private static final Priority QUEUE_SHUTDOWN_PRIORITY = Priority.HIGH; ++ ++ private boolean shutdown; ++ ++ public PrioritisedThreadPool(final Consumer threadModifier) { ++ this.threadModifier = threadModifier; ++ ++ if (threadModifier == null) { ++ throw new NullPointerException("Thread factory may not be null"); + } ++ } + -+ @Override -+ public boolean lowerPriority(final Priority priority) { -+ if (!Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } ++ public Thread[] getAliveThreads() { ++ final PrioritisedThread[] threads = this.aliveThreads.getArray(); + -+ synchronized (this.queue.queues) { -+ final Priority curr = this.priority; ++ return Arrays.copyOf(threads, threads.length, Thread[].class); ++ } + -+ if (curr == Priority.COMPLETING) { -+ return false; -+ } ++ public Thread[] getCoreThreads() { ++ final PrioritisedThread[] threads = this.threads.getArray(); + -+ if (curr.isLowerOrEqualPriority(priority)) { -+ return true; -+ } ++ return Arrays.copyOf(threads, threads.length, Thread[].class); ++ } + -+ this.priority = priority; -+ if (this.id != NOT_SCHEDULED_ID) { -+ this.queue.queues[priority.priority].add(this); ++ /** ++ * Prevents creation of new queues, shutdowns all non-shutdown queues if specified ++ */ ++ public void halt(final boolean shutdownQueues) { ++ synchronized (this) { ++ this.shutdown = true; ++ } + -+ // call priority change callback -+ this.queue.priorityChange(this, curr, priority); ++ if (shutdownQueues) { ++ for (final ExecutorGroup group : this.executors.getArray()) { ++ for (final ExecutorGroup.ThreadPoolExecutor executor : group.executors.getArray()) { ++ executor.shutdown(); + } + } ++ } + -+ return true; ++ for (final PrioritisedThread thread : this.threads.getArray()) { ++ thread.halt(false); + } ++ } + -+ @Override -+ public boolean cancel() { -+ final long id; -+ synchronized (this.queue.queues) { -+ final Priority oldPriority = this.priority; -+ if (oldPriority == Priority.COMPLETING) { -+ return 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); ++ } ++ } + -+ this.priority = Priority.COMPLETING; -+ // call priority change callback -+ if ((id = this.id) != NOT_SCHEDULED_ID) { -+ this.queue.priorityChange(this, oldPriority, Priority.COMPLETING); ++ /** ++ * 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.aliveThreads.getArray()) { ++ for (;;) { ++ if (!thread.isAlive()) { ++ break; ++ } ++ final long current = System.nanoTime(); ++ if (current >= deadline && msToWait > 0L) { ++ return false; ++ } ++ ++ try { ++ thread.join(msToWait <= 0L ? 0L : Math.max(1L, (deadline - current) / (1000 * 1000))); ++ } catch (final InterruptedException ex) { ++ if (interruptable) { ++ throw ex; ++ } ++ interrupted = true; ++ } + } + } -+ this.runnable = null; -+ if (id != NOT_SCHEDULED_ID) { -+ this.queue.getAndAddTotalCompletedTasksVolatile(1L); -+ } ++ + return true; ++ } finally { ++ if (interrupted) { ++ Thread.currentThread().interrupt(); ++ } + } ++ } + -+ 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); -+ } ++ /** ++ * Shuts down this thread pool, optionally waiting for all tasks to be executed. ++ * This function will invoke {@link PrioritisedExecutor#shutdown()} on all created executors on this ++ * thread pool. ++ * @param wait Whether to wait for tasks to be executed ++ */ ++ public void shutdown(final boolean wait) { ++ synchronized (this) { ++ this.shutdown = true; ++ } ++ ++ for (final ExecutorGroup group : this.executors.getArray()) { ++ for (final ExecutorGroup.ThreadPoolExecutor executor : group.executors.getArray()) { ++ executor.shutdown(); + } + } + -+ @Override -+ public boolean execute() { -+ synchronized (this.queue.queues) { -+ final Priority oldPriority = this.priority; -+ if (oldPriority == Priority.COMPLETING) { -+ return false; -+ } + -+ this.priority = Priority.COMPLETING; -+ // call priority change callback -+ if (this.id != NOT_SCHEDULED_ID) { -+ this.queue.priorityChange(this, oldPriority, Priority.COMPLETING); -+ } -+ } ++ for (final PrioritisedThread thread : this.threads.getArray()) { ++ // none of these can be true or else NPE ++ thread.close(false, false); ++ } + -+ this.executeInternal(); -+ return true; ++ if (wait) { ++ this.join(0L); + } + } -+} -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/function/BiLong1Function.java b/src/main/java/ca/spottedleaf/concurrentutil/function/BiLong1Function.java -new file mode 100644 -index 0000000000000000000000000000000000000000..94bfd7c56ffcea7d6491e94a7804bc3bd60fe9c3 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/function/BiLong1Function.java -@@ -0,0 +1,8 @@ -+package ca.spottedleaf.concurrentutil.function; -+ -+@FunctionalInterface -+public interface BiLong1Function { + -+ public R apply(final long t1, final T t2); ++ private void die(final PrioritisedThread thread) { ++ this.aliveThreads.remove(thread); ++ } + -+} -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/function/BiLongObjectConsumer.java b/src/main/java/ca/spottedleaf/concurrentutil/function/BiLongObjectConsumer.java -new file mode 100644 -index 0000000000000000000000000000000000000000..8e7eef07960a18d0593688eba55adfa1c85efadf ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/function/BiLongObjectConsumer.java -@@ -0,0 +1,8 @@ -+package ca.spottedleaf.concurrentutil.function; ++ public void adjustThreadCount(final int threads) { ++ synchronized (this) { ++ if (this.shutdown) { ++ return; ++ } + -+@FunctionalInterface -+public interface BiLongObjectConsumer { ++ final PrioritisedThread[] currentThreads = this.threads.getArray(); ++ if (threads == currentThreads.length) { ++ // no adjustment needed ++ return; ++ } + -+ public void accept(final long key, final V value); ++ if (threads < currentThreads.length) { ++ // we need to trim threads ++ for (int i = 0, difference = currentThreads.length - threads; i < difference; ++i) { ++ final PrioritisedThread remove = currentThreads[currentThreads.length - i - 1]; + -+} -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/lock/ReentrantAreaLock.java b/src/main/java/ca/spottedleaf/concurrentutil/lock/ReentrantAreaLock.java -new file mode 100644 -index 0000000000000000000000000000000000000000..7ffe4379b06c03c56abbcbdee3bb720894a10702 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/lock/ReentrantAreaLock.java -@@ -0,0 +1,350 @@ -+package ca.spottedleaf.concurrentutil.lock; ++ remove.halt(false); ++ this.threads.remove(remove); ++ } ++ } else { ++ // we need to add threads ++ for (int i = 0, difference = threads - currentThreads.length; i < difference; ++i) { ++ final PrioritisedThread thread = new PrioritisedThread(); + -+import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; -+import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; -+import ca.spottedleaf.concurrentutil.util.IntPairUtil; -+import java.util.Objects; -+import java.util.concurrent.locks.LockSupport; ++ this.threadModifier.accept(thread); ++ this.aliveThreads.add(thread); ++ this.threads.add(thread); + -+public final class ReentrantAreaLock { ++ thread.start(); ++ } ++ } ++ } ++ } + -+ public final int coordinateShift; ++ private static int compareInsideGroup(final ExecutorGroup.ThreadPoolExecutor src, final Priority srcPriority, ++ final ExecutorGroup.ThreadPoolExecutor dst, final Priority dstPriority) { ++ final int priorityCompare = srcPriority.ordinal() - dstPriority.ordinal(); ++ if (priorityCompare != 0) { ++ return priorityCompare; ++ } + -+ // aggressive load factor to reduce contention -+ private final ConcurrentLong2ReferenceChainedHashTable nodes = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(128, 0.2f); ++ final int parallelismCompare = src.currentParallelism - dst.currentParallelism; ++ if (parallelismCompare != 0) { ++ return parallelismCompare; ++ } + -+ public ReentrantAreaLock(final int coordinateShift) { -+ this.coordinateShift = coordinateShift; ++ return TimeUtil.compareTimes(src.lastRetrieved, dst.lastRetrieved); + } + -+ public boolean isHeldByCurrentThread(final int x, final int z) { -+ final Thread currThread = Thread.currentThread(); -+ final int shift = this.coordinateShift; -+ final int sectionX = x >> shift; -+ final int sectionZ = z >> shift; ++ private static int compareOutsideGroup(final ExecutorGroup.ThreadPoolExecutor src, final Priority srcPriority, ++ final ExecutorGroup.ThreadPoolExecutor dst, final Priority dstPriority) { ++ if (src.getGroup().division == dst.getGroup().division) { ++ // can only compare priorities inside the same division ++ final int priorityCompare = srcPriority.ordinal() - dstPriority.ordinal(); ++ if (priorityCompare != 0) { ++ return priorityCompare; ++ } ++ } + -+ final long coordinate = IntPairUtil.key(sectionX, sectionZ); -+ final Node node = this.nodes.get(coordinate); ++ final int parallelismCompare = src.getGroup().currentParallelism - dst.getGroup().currentParallelism; ++ if (parallelismCompare != 0) { ++ return parallelismCompare; ++ } + -+ return node != null && node.thread == currThread; ++ return TimeUtil.compareTimes(src.lastRetrieved, dst.lastRetrieved); + } + -+ public boolean isHeldByCurrentThread(final int centerX, final int centerZ, final int radius) { -+ return this.isHeldByCurrentThread(centerX - radius, centerZ - radius, centerX + radius, centerZ + radius); -+ } ++ private ExecutorGroup.ThreadPoolExecutor obtainQueue() { ++ final long time = System.nanoTime(); ++ synchronized (this) { ++ ExecutorGroup.ThreadPoolExecutor ret = null; ++ Priority retPriority = null; ++ ++ for (final ExecutorGroup executorGroup : this.executors.getArray()) { ++ ExecutorGroup.ThreadPoolExecutor highest = null; ++ Priority highestPriority = null; ++ for (final ExecutorGroup.ThreadPoolExecutor executor : executorGroup.executors.getArray()) { ++ final int maxParallelism = executor.maxParallelism; ++ if (maxParallelism > 0 && executor.currentParallelism >= maxParallelism) { ++ continue; ++ } + -+ public boolean isHeldByCurrentThread(final int fromX, final int fromZ, final int toX, final int toZ) { -+ if (fromX > toX || fromZ > toZ) { -+ throw new IllegalArgumentException(); -+ } ++ final Priority priority = executor.getTargetPriority(); + -+ final Thread currThread = Thread.currentThread(); -+ final int shift = this.coordinateShift; -+ final int fromSectionX = fromX >> shift; -+ final int fromSectionZ = fromZ >> shift; -+ final int toSectionX = toX >> shift; -+ final int toSectionZ = toZ >> shift; ++ if (priority == null) { ++ continue; ++ } + -+ for (int currZ = fromSectionZ; currZ <= toSectionZ; ++currZ) { -+ for (int currX = fromSectionX; currX <= toSectionX; ++currX) { -+ final long coordinate = IntPairUtil.key(currX, currZ); ++ if (highestPriority == null || compareInsideGroup(highest, highestPriority, executor, priority) > 0) { ++ highest = executor; ++ highestPriority = priority; ++ } ++ } + -+ final Node node = this.nodes.get(coordinate); ++ if (highest == null) { ++ continue; ++ } + -+ if (node == null || node.thread != currThread) { -+ return false; ++ if (ret == null || compareOutsideGroup(ret, retPriority, highest, highestPriority) > 0) { ++ ret = highest; ++ retPriority = highestPriority; + } + } -+ } + -+ return true; -+ } ++ if (ret != null) { ++ ret.lastRetrieved = time; ++ ++ret.currentParallelism; ++ ++ret.getGroup().currentParallelism; ++ return ret; ++ } + -+ public Node tryLock(final int x, final int z) { -+ return this.tryLock(x, z, x, z); ++ return ret; ++ } + } + -+ public Node tryLock(final int centerX, final int centerZ, final int radius) { -+ return this.tryLock(centerX - radius, centerZ - radius, centerX + radius, centerZ + radius); ++ private void returnQueue(final ExecutorGroup.ThreadPoolExecutor executor) { ++ synchronized (this) { ++ --executor.currentParallelism; ++ --executor.getGroup().currentParallelism; ++ } ++ ++ if (executor.isShutdown() && executor.queue.hasNoScheduledTasks()) { ++ executor.getGroup().executors.remove(executor); ++ } + } + -+ public Node tryLock(final int fromX, final int fromZ, final int toX, final int toZ) { -+ if (fromX > toX || fromZ > toZ) { -+ throw new IllegalArgumentException(); ++ private void notifyAllThreads() { ++ for (final PrioritisedThread thread : this.threads.getArray()) { ++ thread.notifyTasks(); + } ++ } + -+ final Thread currThread = Thread.currentThread(); -+ final int shift = this.coordinateShift; -+ final int fromSectionX = fromX >> shift; -+ final int fromSectionZ = fromZ >> shift; -+ final int toSectionX = toX >> shift; -+ final int toSectionZ = toZ >> shift; ++ public ExecutorGroup createExecutorGroup(final int division, final int flags) { ++ synchronized (this) { ++ if (this.shutdown) { ++ throw new IllegalStateException("Queue is shutdown: " + this.toString()); ++ } + -+ final long[] areaAffected = new long[(toSectionX - fromSectionX + 1) * (toSectionZ - fromSectionZ + 1)]; -+ int areaAffectedLen = 0; ++ final ExecutorGroup ret = new ExecutorGroup(division, flags); + -+ final Node ret = new Node(this, areaAffected, currThread); ++ this.executors.add(ret); + -+ boolean failed = false; ++ return ret; ++ } ++ } + -+ // try to fast acquire area -+ for (int currZ = fromSectionZ; currZ <= toSectionZ; ++currZ) { -+ for (int currX = fromSectionX; currX <= toSectionX; ++currX) { -+ final long coordinate = IntPairUtil.key(currX, currZ); ++ private final class PrioritisedThread extends PrioritisedQueueExecutorThread { + -+ final Node prev = this.nodes.putIfAbsent(coordinate, ret); ++ private final AtomicBoolean alertedHighPriority = new AtomicBoolean(); + -+ if (prev == null) { -+ areaAffected[areaAffectedLen++] = coordinate; -+ continue; -+ } ++ public PrioritisedThread() { ++ super(null); ++ } + -+ if (prev.thread != currThread) { -+ failed = true; -+ break; ++ public boolean alertHighPriorityExecutor() { ++ if (!this.notifyTasks()) { ++ if (!this.alertedHighPriority.get()) { ++ this.alertedHighPriority.set(true); + } ++ return false; + } ++ ++ return true; + } + -+ if (!failed) { -+ return ret; ++ private boolean isAlertedHighPriority() { ++ return this.alertedHighPriority.get() && this.alertedHighPriority.getAndSet(false); + } + -+ // failed, undo logic -+ if (areaAffectedLen != 0) { -+ for (int i = 0; i < areaAffectedLen; ++i) { -+ final long key = areaAffected[i]; ++ @Override ++ protected void die() { ++ PrioritisedThreadPool.this.die(this); ++ } + -+ if (this.nodes.remove(key) != ret) { -+ throw new IllegalStateException(); ++ @Override ++ protected boolean pollTasks() { ++ boolean ret = false; ++ ++ for (;;) { ++ if (this.halted) { ++ break; + } -+ } + -+ areaAffectedLen = 0; ++ final ExecutorGroup.ThreadPoolExecutor executor = PrioritisedThreadPool.this.obtainQueue(); ++ if (executor == null) { ++ break; ++ } ++ final long deadline = System.nanoTime() + executor.queueMaxHoldTime; ++ do { ++ try { ++ if (this.halted || executor.halt) { ++ break; ++ } ++ if (!executor.executeTask()) { ++ // no more tasks, try next queue ++ break; ++ } ++ ret = true; ++ } catch (final Throwable throwable) { ++ LOGGER.error("Exception thrown from thread '" + this.getName() + "' in queue '" + executor.toString() + "'", throwable); ++ } ++ } while (!this.isAlertedHighPriority() && System.nanoTime() <= deadline); + -+ // since we inserted, we need to drain waiters -+ Thread unpark; -+ while ((unpark = ret.pollOrBlockAdds()) != null) { -+ LockSupport.unpark(unpark); ++ PrioritisedThreadPool.this.returnQueue(executor); + } -+ } + -+ return null; -+ } + -+ public Node lock(final int x, final int z) { -+ final Thread currThread = Thread.currentThread(); -+ final int shift = this.coordinateShift; -+ final int sectionX = x >> shift; -+ final int sectionZ = z >> shift; ++ return ret; ++ } ++ } + -+ final long coordinate = IntPairUtil.key(sectionX, sectionZ); -+ final long[] areaAffected = new long[1]; -+ areaAffected[0] = coordinate; ++ public final class ExecutorGroup { + -+ final Node ret = new Node(this, areaAffected, currThread); ++ private final AtomicLong subOrderGenerator = new AtomicLong(); ++ private final COWArrayList executors = new COWArrayList<>(ThreadPoolExecutor.class); + -+ for (long failures = 0L;;) { -+ final Node park; ++ private final int division; ++ private int currentParallelism; + -+ // try to fast acquire area -+ { -+ final Node prev = this.nodes.putIfAbsent(coordinate, ret); ++ private ExecutorGroup(final int division, final int flags) { ++ this.division = division; ++ } + -+ if (prev == null) { -+ ret.areaAffectedLen = 1; -+ return ret; -+ } else if (prev.thread != currThread) { -+ park = prev; -+ } else { -+ // only one node we would want to acquire, and it's owned by this thread already -+ // areaAffectedLen = 0 already -+ return ret; -+ } -+ } ++ public ThreadPoolExecutor[] getAllExecutors() { ++ return this.executors.getArray().clone(); ++ } + -+ ++failures; ++ private PrioritisedThreadPool getThreadPool() { ++ return PrioritisedThreadPool.this; ++ } + -+ if (failures > 128L && park.add(currThread)) { -+ LockSupport.park(); -+ } else { -+ // high contention, spin wait -+ if (failures < 128L) { -+ for (long i = 0; i < failures; ++i) { -+ Thread.onSpinWait(); -+ } -+ failures = failures << 1; -+ } else if (failures < 1_200L) { -+ LockSupport.parkNanos(1_000L); -+ failures = failures + 1L; -+ } else { // scale 0.1ms (100us) per failure -+ Thread.yield(); -+ LockSupport.parkNanos(100_000L * failures); -+ failures = failures + 1L; ++ public ThreadPoolExecutor createExecutor(final int maxParallelism, final long queueMaxHoldTime, final int flags) { ++ synchronized (PrioritisedThreadPool.this) { ++ if (PrioritisedThreadPool.this.shutdown) { ++ throw new IllegalStateException("Queue is shutdown: " + PrioritisedThreadPool.this.toString()); + } -+ } -+ } -+ } + -+ public Node lock(final int centerX, final int centerZ, final int radius) { -+ return this.lock(centerX - radius, centerZ - radius, centerX + radius, centerZ + radius); -+ } ++ final ThreadPoolExecutor ret = new ThreadPoolExecutor(maxParallelism, queueMaxHoldTime, flags); + -+ public Node lock(final int fromX, final int fromZ, final int toX, final int toZ) { -+ if (fromX > toX || fromZ > toZ) { -+ throw new IllegalArgumentException(); ++ this.executors.add(ret); ++ ++ return ret; ++ } + } + -+ final Thread currThread = Thread.currentThread(); -+ final int shift = this.coordinateShift; -+ final int fromSectionX = fromX >> shift; -+ final int fromSectionZ = fromZ >> shift; -+ final int toSectionX = toX >> shift; -+ final int toSectionZ = toZ >> shift; ++ public final class ThreadPoolExecutor implements PrioritisedExecutor { + -+ if (((fromSectionX ^ toSectionX) | (fromSectionZ ^ toSectionZ)) == 0) { -+ return this.lock(fromX, fromZ); -+ } ++ private final PrioritisedTaskQueue queue = new PrioritisedTaskQueue(); + -+ final long[] areaAffected = new long[(toSectionX - fromSectionX + 1) * (toSectionZ - fromSectionZ + 1)]; -+ int areaAffectedLen = 0; ++ private volatile int maxParallelism; ++ private final long queueMaxHoldTime; ++ private volatile int currentParallelism; ++ private volatile boolean halt; ++ private long lastRetrieved = System.nanoTime(); + -+ final Node ret = new Node(this, areaAffected, currThread); ++ private ThreadPoolExecutor(final int maxParallelism, final long queueMaxHoldTime, final int flags) { ++ this.maxParallelism = maxParallelism; ++ this.queueMaxHoldTime = queueMaxHoldTime; ++ } + -+ for (long failures = 0L;;) { -+ Node park = null; -+ boolean addedToArea = false; -+ boolean alreadyOwned = false; -+ boolean allOwned = true; ++ private ExecutorGroup getGroup() { ++ return ExecutorGroup.this; ++ } + -+ // try to fast acquire area -+ for (int currZ = fromSectionZ; currZ <= toSectionZ; ++currZ) { -+ for (int currX = fromSectionX; currX <= toSectionX; ++currX) { -+ final long coordinate = IntPairUtil.key(currX, currZ); ++ private boolean canNotify() { ++ if (this.halt) { ++ return false; ++ } + -+ final Node prev = this.nodes.putIfAbsent(coordinate, ret); ++ final int max = this.maxParallelism; ++ return max < 0 || this.currentParallelism < max; ++ } + -+ if (prev == null) { -+ addedToArea = true; -+ allOwned = false; -+ areaAffected[areaAffectedLen++] = coordinate; -+ continue; ++ private void notifyHighPriority() { ++ if (!this.canNotify()) { ++ return; ++ } ++ for (final PrioritisedThread thread : this.getGroup().getThreadPool().threads.getArray()) { ++ if (thread.alertHighPriorityExecutor()) { ++ return; + } ++ } ++ } + -+ if (prev.thread != currThread) { -+ park = prev; -+ alreadyOwned = true; -+ break; ++ private void notifyScheduled() { ++ if (!this.canNotify()) { ++ return; ++ } ++ for (final PrioritisedThread thread : this.getGroup().getThreadPool().threads.getArray()) { ++ if (thread.notifyTasks()) { ++ return; + } + } + } + -+ // check for failure -+ if ((park != null && addedToArea) || (park == null && alreadyOwned && !allOwned)) { -+ // failure to acquire: added and we need to block, or improper lock usage -+ for (int i = 0; i < areaAffectedLen; ++i) { -+ final long key = areaAffected[i]; ++ /** ++ * Removes this queue from the thread pool without shutting the queue down or waiting for queued tasks to be executed ++ */ ++ public void halt() { ++ this.halt = true; + -+ if (this.nodes.remove(key) != ret) { -+ throw new IllegalStateException(); ++ ExecutorGroup.this.executors.remove(this); ++ } ++ ++ /** ++ * 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() { ++ if (this.halt) { ++ return this.currentParallelism > 0; ++ } else { ++ if (!this.isShutdown()) { ++ return true; + } ++ ++ return !this.queue.hasNoScheduledTasks(); + } ++ } + -+ areaAffectedLen = 0; ++ @Override ++ public boolean shutdown() { ++ if (!this.queue.shutdown()) { ++ return false; ++ } + -+ // since we inserted, we need to drain waiters -+ Thread unpark; -+ while ((unpark = ret.pollOrBlockAdds()) != null) { -+ LockSupport.unpark(unpark); ++ if (this.queue.hasNoScheduledTasks()) { ++ ExecutorGroup.this.executors.remove(this); + } ++ ++ return true; + } + -+ if (park == null) { -+ if (alreadyOwned && !allOwned) { -+ throw new IllegalStateException("Improper lock usage: Should never acquire intersecting areas"); ++ @Override ++ public boolean isShutdown() { ++ return this.queue.isShutdown(); ++ } ++ ++ public void setMaxParallelism(final int maxParallelism) { ++ this.maxParallelism = maxParallelism; ++ // assume that we could have increased the parallelism ++ if (this.getTargetPriority() != null) { ++ ExecutorGroup.this.getThreadPool().notifyAllThreads(); + } -+ ret.areaAffectedLen = areaAffectedLen; -+ return ret; + } + -+ // failed ++ Priority getTargetPriority() { ++ final Priority ret = this.queue.getHighestPriority(); ++ if (!this.isShutdown()) { ++ return ret; ++ } + -+ ++failures; ++ return ret == null ? QUEUE_SHUTDOWN_PRIORITY : Priority.max(ret, QUEUE_SHUTDOWN_PRIORITY); ++ } + -+ if (failures > 128L && park.add(currThread)) { -+ LockSupport.park(park); -+ } else { -+ // high contention, spin wait -+ if (failures < 128L) { -+ for (long i = 0; i < failures; ++i) { -+ Thread.onSpinWait(); -+ } -+ failures = failures << 1; -+ } else if (failures < 1_200L) { -+ LockSupport.parkNanos(1_000L); -+ failures = failures + 1L; -+ } else { // scale 0.1ms (100us) per failure -+ Thread.yield(); -+ LockSupport.parkNanos(100_000L * failures); -+ failures = failures + 1L; -+ } ++ @Override ++ public long getTotalTasksScheduled() { ++ return this.queue.getTotalTasksScheduled(); + } + -+ if (addedToArea) { -+ // try again, so we need to allow adds so that other threads can properly block on us -+ ret.allowAdds(); ++ @Override ++ public long getTotalTasksExecuted() { ++ return this.queue.getTotalTasksExecuted(); + } -+ } -+ } + -+ public void unlock(final Node node) { -+ if (node.lock != this) { -+ throw new IllegalStateException("Unlock target lock mismatch"); -+ } ++ @Override ++ public long generateNextSubOrder() { ++ return ExecutorGroup.this.subOrderGenerator.getAndIncrement(); ++ } + -+ final long[] areaAffected = node.areaAffected; -+ final int areaAffectedLen = node.areaAffectedLen; ++ @Override ++ public boolean executeTask() { ++ return this.queue.executeTask(); ++ } + -+ if (areaAffectedLen == 0) { -+ // here we are not in the node map, and so do not need to remove from the node map or unblock any waiters -+ return; -+ } ++ @Override ++ public PrioritisedTask queueTask(final Runnable task) { ++ final PrioritisedTask ret = this.createTask(task); + -+ Objects.checkFromToIndex(0, areaAffectedLen, areaAffected.length); ++ ret.queue(); + -+ // remove from node map; allowing other threads to lock -+ for (int i = 0; i < areaAffectedLen; ++i) { -+ final long coordinate = areaAffected[i]; -+ if (this.nodes.remove(coordinate, node) != node) { -+ throw new IllegalStateException(); ++ return ret; + } -+ } + -+ Thread unpark; -+ while ((unpark = node.pollOrBlockAdds()) != null) { -+ LockSupport.unpark(unpark); -+ } -+ } -+ -+ public static final class Node extends MultiThreadedQueue { -+ -+ private final ReentrantAreaLock lock; -+ private final long[] areaAffected; -+ private int areaAffectedLen; -+ private final Thread thread; ++ @Override ++ public PrioritisedTask queueTask(final Runnable task, final Priority priority) { ++ final PrioritisedTask ret = this.createTask(task, priority); + -+ private Node(final ReentrantAreaLock lock, final long[] areaAffected, final Thread thread) { -+ this.lock = lock; -+ this.areaAffected = areaAffected; -+ this.thread = thread; -+ } ++ ret.queue(); + -+ @Override -+ public String toString() { -+ return "Node{" + -+ "areaAffected=" + IntPairUtil.toString(this.areaAffected, 0, this.areaAffectedLen) + -+ ", thread=" + this.thread + -+ '}'; -+ } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/map/ConcurrentLong2ReferenceChainedHashTable.java b/src/main/java/ca/spottedleaf/concurrentutil/map/ConcurrentLong2ReferenceChainedHashTable.java -new file mode 100644 -index 0000000000000000000000000000000000000000..d701998b376579ec652fb94823befa3cc0bc4090 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/map/ConcurrentLong2ReferenceChainedHashTable.java -@@ -0,0 +1,1684 @@ -+package ca.spottedleaf.concurrentutil.map; ++ return ret; ++ } + -+import ca.spottedleaf.concurrentutil.function.BiLong1Function; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.HashUtil; -+import ca.spottedleaf.concurrentutil.util.IntegerUtil; -+import ca.spottedleaf.concurrentutil.util.ThrowUtil; -+import ca.spottedleaf.concurrentutil.util.Validate; -+import java.lang.invoke.VarHandle; -+import java.util.Arrays; -+import java.util.Iterator; -+import java.util.NoSuchElementException; -+import java.util.PrimitiveIterator; -+import java.util.concurrent.atomic.LongAdder; -+import java.util.function.BiFunction; -+import java.util.function.Consumer; -+import java.util.function.Function; -+import java.util.function.LongConsumer; -+import java.util.function.LongFunction; -+import java.util.function.Predicate; ++ @Override ++ public PrioritisedTask queueTask(final Runnable task, final Priority priority, final long subOrder) { ++ final PrioritisedTask ret = this.createTask(task, priority, subOrder); + -+/** -+ * Concurrent hashtable implementation supporting mapping arbitrary {@code long} values onto non-null {@code Object} -+ * values with support for multiple writer and multiple reader threads. -+ * -+ *

    Happens-before relationship

    -+ *

    -+ * As with {@link java.util.concurrent.ConcurrentMap}, there is a happens-before relationship between actions in one thread -+ * prior to writing to the map and access to the results of those actions in another thread. -+ *

    -+ * -+ *

    Atomicity of functional methods

    -+ *

    -+ * Functional methods are functions declared in this class which possibly perform a write (remove, replace, or modify) -+ * to an entry in this map as a result of invoking a function on an input parameter. For example, {@link #compute(long, BiLong1Function)}, -+ * {@link #merge(long, Object, BiFunction)} and {@link #removeIf(long, Predicate)} are examples of functional methods. -+ * Functional methods will be performed atomically, that is, the input parameter is guaranteed to only be invoked at most -+ * once per function call. The consequence of this behavior however is that a critical lock for a bin entry is held, which -+ * means that if the input parameter invocation makes additional calls to write into this hash table that the result -+ * is undefined and deadlock-prone. -+ *

    -+ * -+ * @param -+ * @see java.util.concurrent.ConcurrentMap -+ */ -+public class ConcurrentLong2ReferenceChainedHashTable { ++ ret.queue(); + -+ 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; ++ return ret; ++ } + -+ protected final LongAdder size = new LongAdder(); -+ protected final float loadFactor; ++ @Override ++ public PrioritisedTask createTask(final Runnable task) { ++ return this.createTask(task, Priority.NORMAL); ++ } + -+ protected volatile TableEntry[] table; ++ @Override ++ public PrioritisedTask createTask(final Runnable task, final Priority priority) { ++ return this.createTask(task, priority, this.generateNextSubOrder()); ++ } + -+ protected static final int THRESHOLD_NO_RESIZE = -1; -+ protected static final int THRESHOLD_RESIZING = -2; -+ protected volatile int threshold; -+ protected static final VarHandle THRESHOLD_HANDLE = ConcurrentUtil.getVarHandle(ConcurrentLong2ReferenceChainedHashTable.class, "threshold", int.class); ++ @Override ++ public PrioritisedTask createTask(final Runnable task, final Priority priority, final long subOrder) { ++ return new WrappedTask(this.queue.createTask(task, priority, subOrder)); ++ } + -+ protected final int getThresholdAcquire() { -+ return (int)THRESHOLD_HANDLE.getAcquire(this); -+ } ++ private final class WrappedTask implements PrioritisedTask { + -+ protected final int getThresholdVolatile() { -+ return (int)THRESHOLD_HANDLE.getVolatile(this); -+ } ++ private final PrioritisedTask wrapped; + -+ protected final void setThresholdPlain(final int threshold) { -+ THRESHOLD_HANDLE.set(this, threshold); -+ } ++ private WrappedTask(final PrioritisedTask wrapped) { ++ this.wrapped = wrapped; ++ } + -+ protected final void setThresholdRelease(final int threshold) { -+ THRESHOLD_HANDLE.setRelease(this, threshold); -+ } ++ @Override ++ public PrioritisedExecutor getExecutor() { ++ return ThreadPoolExecutor.this; ++ } + -+ protected final void setThresholdVolatile(final int threshold) { -+ THRESHOLD_HANDLE.setVolatile(this, threshold); -+ } ++ @Override ++ public boolean queue() { ++ if (this.wrapped.queue()) { ++ final Priority priority = this.getPriority(); ++ if (priority != Priority.COMPLETING) { ++ if (priority.isHigherOrEqualPriority(HIGH_PRIORITY_NOTIFY_THRESHOLD)) { ++ ThreadPoolExecutor.this.notifyHighPriority(); ++ } else { ++ ThreadPoolExecutor.this.notifyScheduled(); ++ } ++ } ++ return true; ++ } + -+ protected final int compareExchangeThresholdVolatile(final int expect, final int update) { -+ return (int)THRESHOLD_HANDLE.compareAndExchange(this, expect, update); -+ } ++ return false; ++ } + -+ public ConcurrentLong2ReferenceChainedHashTable() { -+ this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR); -+ } ++ @Override ++ public boolean isQueued() { ++ return this.wrapped.isQueued(); ++ } + -+ protected static int getTargetThreshold(final int capacity, final float loadFactor) { -+ final double ret = (double)capacity * (double)loadFactor; -+ if (Double.isInfinite(ret) || ret >= ((double)Integer.MAX_VALUE)) { -+ return THRESHOLD_NO_RESIZE; -+ } ++ @Override ++ public boolean cancel() { ++ return this.wrapped.cancel(); ++ } + -+ return (int)Math.ceil(ret); -+ } ++ @Override ++ public boolean execute() { ++ return this.wrapped.execute(); ++ } + -+ 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); -+ } ++ @Override ++ public Priority getPriority() { ++ return this.wrapped.getPriority(); ++ } + -+ protected ConcurrentLong2ReferenceChainedHashTable(final int capacity, final float loadFactor) { -+ final int tableSize = getCapacityFor(capacity); ++ @Override ++ public boolean setPriority(final Priority priority) { ++ if (this.wrapped.setPriority(priority)) { ++ if (priority.isHigherOrEqualPriority(HIGH_PRIORITY_NOTIFY_THRESHOLD)) { ++ ThreadPoolExecutor.this.notifyHighPriority(); ++ } ++ return true; ++ } + -+ if (loadFactor <= 0.0 || !Float.isFinite(loadFactor)) { -+ throw new IllegalArgumentException("Invalid load factor: " + loadFactor); -+ } ++ return false; ++ } + -+ if (tableSize == MAXIMUM_CAPACITY) { -+ this.setThresholdPlain(THRESHOLD_NO_RESIZE); -+ } else { -+ this.setThresholdPlain(getTargetThreshold(tableSize, loadFactor)); -+ } ++ @Override ++ public boolean raisePriority(final Priority priority) { ++ if (this.wrapped.raisePriority(priority)) { ++ if (priority.isHigherOrEqualPriority(HIGH_PRIORITY_NOTIFY_THRESHOLD)) { ++ ThreadPoolExecutor.this.notifyHighPriority(); ++ } ++ return true; ++ } + -+ this.loadFactor = loadFactor; -+ // noinspection unchecked -+ this.table = (TableEntry[])new TableEntry[tableSize]; -+ } ++ return false; ++ } + -+ public static ConcurrentLong2ReferenceChainedHashTable createWithCapacity(final int capacity) { -+ return createWithCapacity(capacity, DEFAULT_LOAD_FACTOR); -+ } ++ @Override ++ public boolean lowerPriority(final Priority priority) { ++ return this.wrapped.lowerPriority(priority); ++ } + -+ public static ConcurrentLong2ReferenceChainedHashTable createWithCapacity(final int capacity, final float loadFactor) { -+ return new ConcurrentLong2ReferenceChainedHashTable<>(capacity, loadFactor); -+ } ++ @Override ++ public long getSubOrder() { ++ return this.wrapped.getSubOrder(); ++ } + -+ public static ConcurrentLong2ReferenceChainedHashTable createWithExpected(final int expected) { -+ return createWithExpected(expected, DEFAULT_LOAD_FACTOR); -+ } ++ @Override ++ public boolean setSubOrder(final long subOrder) { ++ return this.wrapped.setSubOrder(subOrder); ++ } + -+ public static ConcurrentLong2ReferenceChainedHashTable createWithExpected(final int expected, final float loadFactor) { -+ final int capacity = (int)Math.ceil((double)expected / (double)loadFactor); ++ @Override ++ public boolean raiseSubOrder(final long subOrder) { ++ return this.wrapped.raiseSubOrder(subOrder); ++ } + -+ return createWithCapacity(capacity, loadFactor); -+ } ++ @Override ++ public boolean lowerSubOrder(final long subOrder) { ++ return this.wrapped.lowerSubOrder(subOrder); ++ } + -+ /** must be deterministic given a key */ -+ protected static int getHash(final long key) { -+ return (int)HashUtil.mix(key); -+ } ++ @Override ++ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder) { ++ if (this.wrapped.setPriorityAndSubOrder(priority, subOrder)) { ++ if (priority.isHigherOrEqualPriority(HIGH_PRIORITY_NOTIFY_THRESHOLD)) { ++ ThreadPoolExecutor.this.notifyHighPriority(); ++ } ++ return true; ++ } + -+ /** -+ * Returns the load factor associated with this map. -+ */ -+ public final float getLoadFactor() { -+ return this.loadFactor; ++ return false; ++ } ++ } ++ } + } + -+ protected static TableEntry getAtIndexVolatile(final TableEntry[] table, final int index) { -+ //noinspection unchecked -+ return (TableEntry)TableEntry.TABLE_ENTRY_ARRAY_HANDLE.getVolatile(table, index); -+ } ++ private static final class COWArrayList { + -+ protected static void setAtIndexRelease(final TableEntry[] table, final int index, final TableEntry value) { -+ TableEntry.TABLE_ENTRY_ARRAY_HANDLE.setRelease(table, index, value); -+ } ++ private volatile E[] array; + -+ protected static void setAtIndexVolatile(final TableEntry[] table, final int index, final TableEntry value) { -+ TableEntry.TABLE_ENTRY_ARRAY_HANDLE.setVolatile(table, index, value); -+ } ++ public COWArrayList(final Class clazz) { ++ this.array = (E[])Array.newInstance(clazz, 0); ++ } + -+ protected static TableEntry compareAndExchangeAtIndexVolatile(final TableEntry[] table, final int index, -+ final TableEntry expect, final TableEntry update) { -+ //noinspection unchecked -+ return (TableEntry)TableEntry.TABLE_ENTRY_ARRAY_HANDLE.compareAndExchange(table, index, expect, update); -+ } ++ public E[] getArray() { ++ return this.array; ++ } + -+ /** -+ * Returns the possible node associated with the key, or {@code null} if there is no such node. The node -+ * returned may have a {@code null} {@link TableEntry#value}, in which case the node is a placeholder for -+ * a compute/computeIfAbsent call. The placeholder node should not be considered mapped in order to preserve -+ * happens-before relationships between writes and reads in the map. -+ */ -+ protected final TableEntry getNode(final long key) { -+ final int hash = getHash(key); ++ public void add(final E element) { ++ synchronized (this) { ++ final E[] array = this.array; + -+ TableEntry[] table = this.table; -+ for (;;) { -+ TableEntry node = getAtIndexVolatile(table, hash & (table.length - 1)); ++ final E[] copy = Arrays.copyOf(array, array.length + 1); ++ copy[array.length] = element; + -+ if (node == null) { -+ // node == null -+ return node; ++ this.array = copy; + } ++ } + -+ if (node.resize) { -+ table = (TableEntry[])node.getValuePlain(); -+ continue; -+ } ++ public boolean remove(final E element) { ++ synchronized (this) { ++ final E[] array = this.array; ++ int index = -1; ++ for (int i = 0, len = array.length; i < len; ++i) { ++ if (array[i] == element) { ++ index = i; ++ break; ++ } ++ } + -+ for (; node != null; node = node.getNextVolatile()) { -+ if (node.key == key) { -+ return node; ++ if (index == -1) { ++ return false; + } ++ ++ final E[] copy = (E[])Array.newInstance(array.getClass().getComponentType(), array.length - 1); ++ ++ System.arraycopy(array, 0, copy, 0, index); ++ System.arraycopy(array, index + 1, copy, index, (array.length - 1) - index); ++ ++ this.array = copy; + } + -+ // node == null -+ return node; ++ return true; + } + } ++} +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/function/BiLong1Function.java b/src/main/java/ca/spottedleaf/concurrentutil/function/BiLong1Function.java +new file mode 100644 +index 0000000000000000000000000000000000000000..94bfd7c56ffcea7d6491e94a7804bc3bd60fe9c3 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/function/BiLong1Function.java +@@ -0,0 +1,8 @@ ++package ca.spottedleaf.concurrentutil.function; + -+ /** -+ * Returns the currently mapped value associated with the specified key, or {@code null} if there is none. -+ * -+ * @param key Specified key -+ */ -+ public V get(final long key) { -+ final TableEntry node = this.getNode(key); -+ return node == null ? null : node.getValueVolatile(); -+ } ++@FunctionalInterface ++public interface BiLong1Function { + -+ /** -+ * Returns the currently mapped value associated with the specified key, or the specified default value if there is none. -+ * -+ * @param key Specified key -+ * @param defaultValue Specified default value -+ */ -+ public V getOrDefault(final long key, final V defaultValue) { -+ final TableEntry node = this.getNode(key); -+ if (node == null) { -+ return defaultValue; -+ } ++ public R apply(final long t1, final T t2); + -+ final V ret = node.getValueVolatile(); -+ if (ret == null) { -+ // ret == null for nodes pre-allocated to compute() and friends -+ return defaultValue; -+ } ++} +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/function/BiLongObjectConsumer.java b/src/main/java/ca/spottedleaf/concurrentutil/function/BiLongObjectConsumer.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8e7eef07960a18d0593688eba55adfa1c85efadf +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/function/BiLongObjectConsumer.java +@@ -0,0 +1,8 @@ ++package ca.spottedleaf.concurrentutil.function; + -+ return ret; -+ } ++@FunctionalInterface ++public interface BiLongObjectConsumer { + -+ /** -+ * Returns whether the specified key is mapped to some value. -+ * @param key Specified key -+ */ -+ public boolean containsKey(final long key) { -+ // cannot use getNode, as the node may be a placeholder for compute() -+ return this.get(key) != null; -+ } ++ public void accept(final long key, final V value); + -+ /** -+ * Returns whether the specified value has a key mapped to it. -+ * @param value Specified value -+ * @throws NullPointerException If value is null -+ */ -+ public boolean containsValue(final V value) { -+ Validate.notNull(value, "Value cannot be null"); ++} +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/lock/ReentrantAreaLock.java b/src/main/java/ca/spottedleaf/concurrentutil/lock/ReentrantAreaLock.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7ffe4379b06c03c56abbcbdee3bb720894a10702 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/lock/ReentrantAreaLock.java +@@ -0,0 +1,350 @@ ++package ca.spottedleaf.concurrentutil.lock; + -+ final NodeIterator iterator = new NodeIterator<>(this.table); ++import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; ++import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; ++import ca.spottedleaf.concurrentutil.util.IntPairUtil; ++import java.util.Objects; ++import java.util.concurrent.locks.LockSupport; + -+ TableEntry node; -+ while ((node = iterator.findNext()) != null) { -+ // need to use acquire here to ensure the happens-before relationship -+ if (node.getValueAcquire() == value) { -+ return true; -+ } -+ } ++public final class ReentrantAreaLock { + -+ return false; ++ public final int coordinateShift; ++ ++ // aggressive load factor to reduce contention ++ private final ConcurrentLong2ReferenceChainedHashTable nodes = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(128, 0.2f); ++ ++ public ReentrantAreaLock(final int coordinateShift) { ++ this.coordinateShift = coordinateShift; + } + -+ /** -+ * Returns the number of mappings in this map. -+ */ -+ public int size() { -+ final long ret = this.size.sum(); ++ public boolean isHeldByCurrentThread(final int x, final int z) { ++ final Thread currThread = Thread.currentThread(); ++ final int shift = this.coordinateShift; ++ final int sectionX = x >> shift; ++ final int sectionZ = z >> shift; + -+ if (ret <= 0L) { -+ return 0; -+ } -+ if (ret >= (long)Integer.MAX_VALUE) { -+ return Integer.MAX_VALUE; -+ } ++ final long coordinate = IntPairUtil.key(sectionX, sectionZ); ++ final Node node = this.nodes.get(coordinate); + -+ return (int)ret; ++ return node != null && node.thread == currThread; + } + -+ /** -+ * Returns whether this map has no mappings. -+ */ -+ public boolean isEmpty() { -+ return this.size.sum() <= 0L; ++ public boolean isHeldByCurrentThread(final int centerX, final int centerZ, final int radius) { ++ return this.isHeldByCurrentThread(centerX - radius, centerZ - radius, centerX + radius, centerZ + radius); + } + -+ /** -+ * Adds count to size and checks threshold for resizing -+ */ -+ protected final void addSize(final long count) { -+ this.size.add(count); ++ public boolean isHeldByCurrentThread(final int fromX, final int fromZ, final int toX, final int toZ) { ++ if (fromX > toX || fromZ > toZ) { ++ throw new IllegalArgumentException(); ++ } + -+ final int threshold = this.getThresholdAcquire(); ++ final Thread currThread = Thread.currentThread(); ++ final int shift = this.coordinateShift; ++ final int fromSectionX = fromX >> shift; ++ final int fromSectionZ = fromZ >> shift; ++ final int toSectionX = toX >> shift; ++ final int toSectionZ = toZ >> shift; + -+ if (threshold < 0L) { -+ // resizing or no resizing allowed, in either cases we do not need to do anything -+ return; -+ } ++ for (int currZ = fromSectionZ; currZ <= toSectionZ; ++currZ) { ++ for (int currX = fromSectionX; currX <= toSectionX; ++currX) { ++ final long coordinate = IntPairUtil.key(currX, currZ); + -+ final long sum = this.size.sum(); ++ final Node node = this.nodes.get(coordinate); + -+ if (sum < (long)threshold) { -+ return; ++ if (node == null || node.thread != currThread) { ++ return false; ++ } ++ } + } + -+ if (threshold != this.compareExchangeThresholdVolatile(threshold, THRESHOLD_RESIZING)) { -+ // some other thread resized -+ return; -+ } ++ return true; ++ } + -+ // create new table -+ this.resize(sum); ++ public Node tryLock(final int x, final int z) { ++ return this.tryLock(x, z, x, z); + } + -+ /** -+ * Resizes table, only invoke for the thread which has successfully updated threshold to {@link #THRESHOLD_RESIZING} -+ * @param sum Estimate of current mapping count, must be >= old threshold -+ */ -+ private void resize(final long sum) { -+ int capacity; ++ public Node tryLock(final int centerX, final int centerZ, final int radius) { ++ return this.tryLock(centerX - radius, centerZ - radius, centerX + radius, centerZ + radius); ++ } + -+ // add 1.0, as sum may equal threshold (in which case, sum / loadFactor = current capacity) -+ // adding 1.0 should at least raise the size by a factor of two due to usage of roundCeilLog2 -+ final double targetD = ((double)sum / (double)this.loadFactor) + 1.0; -+ if (targetD >= (double)MAXIMUM_CAPACITY) { -+ capacity = MAXIMUM_CAPACITY; -+ } else { -+ capacity = (int)Math.ceil(targetD); -+ capacity = IntegerUtil.roundCeilLog2(capacity); -+ if (capacity > MAXIMUM_CAPACITY) { -+ capacity = MAXIMUM_CAPACITY; -+ } ++ public Node tryLock(final int fromX, final int fromZ, final int toX, final int toZ) { ++ if (fromX > toX || fromZ > toZ) { ++ throw new IllegalArgumentException(); + } + -+ // create new table data ++ final Thread currThread = Thread.currentThread(); ++ final int shift = this.coordinateShift; ++ final int fromSectionX = fromX >> shift; ++ final int fromSectionZ = fromZ >> shift; ++ final int toSectionX = toX >> shift; ++ final int toSectionZ = toZ >> shift; + -+ final TableEntry[] newTable = new TableEntry[capacity]; -+ // noinspection unchecked -+ final TableEntry resizeNode = new TableEntry<>(0L, (V)newTable, true); ++ final long[] areaAffected = new long[(toSectionX - fromSectionX + 1) * (toSectionZ - fromSectionZ + 1)]; ++ int areaAffectedLen = 0; + -+ // transfer nodes from old table ++ final Node ret = new Node(this, areaAffected, currThread); + -+ // does not need to be volatile read, just plain -+ final TableEntry[] oldTable = this.table; ++ boolean failed = false; + -+ // when resizing, the old entries at bin i (where i = hash % oldTable.length) are assigned to -+ // bin k in the new table (where k = hash % newTable.length) -+ // since both table lengths are powers of two (specifically, newTable is a multiple of oldTable), -+ // the possible number of locations in the new table to assign any given i is newTable.length/oldTable.length ++ // try to fast acquire area ++ for (int currZ = fromSectionZ; currZ <= toSectionZ; ++currZ) { ++ for (int currX = fromSectionX; currX <= toSectionX; ++currX) { ++ final long coordinate = IntPairUtil.key(currX, currZ); + -+ // we can build the new linked nodes for the new table by using a work array sized to newTable.length/oldTable.length -+ // which holds the _last_ entry in the chain per bin ++ final Node prev = this.nodes.putIfAbsent(coordinate, ret); + -+ final int capOldShift = IntegerUtil.floorLog2(oldTable.length); -+ final int capDiffShift = IntegerUtil.floorLog2(capacity) - capOldShift; ++ if (prev == null) { ++ areaAffected[areaAffectedLen++] = coordinate; ++ continue; ++ } + -+ if (capDiffShift == 0) { -+ throw new IllegalStateException("Resizing to same size"); ++ if (prev.thread != currThread) { ++ failed = true; ++ break; ++ } ++ } + } + -+ final TableEntry[] work = new TableEntry[1 << capDiffShift]; // typically, capDiffShift = 1 ++ if (!failed) { ++ return ret; ++ } + -+ for (int i = 0, len = oldTable.length; i < len; ++i) { -+ TableEntry binNode = getAtIndexVolatile(oldTable, i); ++ // failed, undo logic ++ if (areaAffectedLen != 0) { ++ for (int i = 0; i < areaAffectedLen; ++i) { ++ final long key = areaAffected[i]; + -+ for (;;) { -+ if (binNode == null) { -+ // just need to replace the bin node, do not need to move anything -+ if (null == (binNode = compareAndExchangeAtIndexVolatile(oldTable, i, null, resizeNode))) { -+ break; -+ } // else: binNode != null, fall through ++ if (this.nodes.remove(key) != ret) { ++ throw new IllegalStateException(); + } ++ } + -+ // need write lock to block other writers -+ synchronized (binNode) { -+ if (binNode != (binNode = getAtIndexVolatile(oldTable, i))) { -+ continue; -+ } ++ areaAffectedLen = 0; + -+ // an important detail of resizing is that we do not need to be concerned with synchronisation on -+ // writes to the new table, as no access to any nodes on bin i on oldTable will occur until a thread -+ // sees the resizeNode -+ // specifically, as long as the resizeNode is release written there are no cases where another thread -+ // will see our writes to the new table ++ // since we inserted, we need to drain waiters ++ Thread unpark; ++ while ((unpark = ret.pollOrBlockAdds()) != null) { ++ LockSupport.unpark(unpark); ++ } ++ } + -+ TableEntry next = binNode.getNextPlain(); ++ return null; ++ } + -+ if (next == null) { -+ // simple case: do not use work array ++ public Node lock(final int x, final int z) { ++ final Thread currThread = Thread.currentThread(); ++ final int shift = this.coordinateShift; ++ final int sectionX = x >> shift; ++ final int sectionZ = z >> shift; + -+ // do not need to create new node, readers only need to see the state of the map at the -+ // beginning of a call, so any additions onto _next_ don't really matter -+ // additionally, the old node is replaced so that writers automatically forward to the new table, -+ // which resolves any issues -+ newTable[getHash(binNode.key) & (capacity - 1)] = binNode; -+ } else { -+ // reset for next usage -+ Arrays.fill(work, null); ++ final long coordinate = IntPairUtil.key(sectionX, sectionZ); ++ final long[] areaAffected = new long[1]; ++ areaAffected[0] = coordinate; + -+ for (TableEntry curr = binNode; curr != null; curr = curr.getNextPlain()) { -+ final int newTableIdx = getHash(curr.key) & (capacity - 1); -+ final int workIdx = newTableIdx >>> capOldShift; ++ final Node ret = new Node(this, areaAffected, currThread); + -+ final TableEntry replace = new TableEntry<>(curr.key, curr.getValuePlain()); ++ for (long failures = 0L;;) { ++ final Node park; + -+ final TableEntry workNode = work[workIdx]; -+ work[workIdx] = replace; ++ // try to fast acquire area ++ { ++ final Node prev = this.nodes.putIfAbsent(coordinate, ret); + -+ if (workNode == null) { -+ newTable[newTableIdx] = replace; -+ continue; -+ } else { -+ workNode.setNextPlain(replace); -+ continue; -+ } -+ } -+ } ++ if (prev == null) { ++ ret.areaAffectedLen = 1; ++ return ret; ++ } else if (prev.thread != currThread) { ++ park = prev; ++ } else { ++ // only one node we would want to acquire, and it's owned by this thread already ++ // areaAffectedLen = 0 already ++ return ret; ++ } ++ } + -+ setAtIndexRelease(oldTable, i, resizeNode); -+ break; ++ ++failures; ++ ++ if (failures > 128L && park.add(currThread)) { ++ LockSupport.park(); ++ } else { ++ // high contention, spin wait ++ if (failures < 128L) { ++ for (long i = 0; i < failures; ++i) { ++ Thread.onSpinWait(); ++ } ++ failures = failures << 1; ++ } else if (failures < 1_200L) { ++ LockSupport.parkNanos(1_000L); ++ failures = failures + 1L; ++ } else { // scale 0.1ms (100us) per failure ++ Thread.yield(); ++ LockSupport.parkNanos(100_000L * failures); ++ failures = failures + 1L; + } + } + } ++ } + -+ // calculate new threshold -+ final int newThreshold; -+ if (capacity == MAXIMUM_CAPACITY) { -+ newThreshold = THRESHOLD_NO_RESIZE; -+ } else { -+ newThreshold = getTargetThreshold(capacity, loadFactor); ++ public Node lock(final int centerX, final int centerZ, final int radius) { ++ return this.lock(centerX - radius, centerZ - radius, centerX + radius, centerZ + radius); ++ } ++ ++ public Node lock(final int fromX, final int fromZ, final int toX, final int toZ) { ++ if (fromX > toX || fromZ > toZ) { ++ throw new IllegalArgumentException(); + } + -+ this.table = newTable; -+ // finish resize operation by releasing hold on threshold -+ this.setThresholdVolatile(newThreshold); -+ } ++ final Thread currThread = Thread.currentThread(); ++ final int shift = this.coordinateShift; ++ final int fromSectionX = fromX >> shift; ++ final int fromSectionZ = fromZ >> shift; ++ final int toSectionX = toX >> shift; ++ final int toSectionZ = toZ >> shift; + -+ /** -+ * Subtracts count from size -+ */ -+ protected final void subSize(final long count) { -+ this.size.add(-count); -+ } ++ if (((fromSectionX ^ toSectionX) | (fromSectionZ ^ toSectionZ)) == 0) { ++ return this.lock(fromX, fromZ); ++ } + -+ /** -+ * Atomically updates the value associated with {@code key} to {@code value}, or inserts a new mapping with {@code key} -+ * mapped to {@code value}. -+ * @param key Specified key -+ * @param value Specified value -+ * @throws NullPointerException If value is null -+ * @return Old value previously associated with key, or {@code null} if none. -+ */ -+ public V put(final long key, final V value) { -+ Validate.notNull(value, "Value may not be null"); ++ final long[] areaAffected = new long[(toSectionX - fromSectionX + 1) * (toSectionZ - fromSectionZ + 1)]; ++ int areaAffectedLen = 0; + -+ final int hash = getHash(key); ++ final Node ret = new Node(this, areaAffected, currThread); + -+ TableEntry[] table = this.table; -+ table_loop: -+ for (;;) { -+ final int index = hash & (table.length - 1); ++ for (long failures = 0L;;) { ++ Node park = null; ++ boolean addedToArea = false; ++ boolean alreadyOwned = false; ++ boolean allOwned = true; + -+ TableEntry node = getAtIndexVolatile(table, index); -+ node_loop: -+ for (;;) { -+ if (node == null) { -+ if (null == (node = compareAndExchangeAtIndexVolatile(table, index, null, new TableEntry<>(key, value)))) { -+ // successfully inserted -+ this.addSize(1L); -+ return null; -+ } // else: node != null, fall through -+ } ++ // try to fast acquire area ++ for (int currZ = fromSectionZ; currZ <= toSectionZ; ++currZ) { ++ for (int currX = fromSectionX; currX <= toSectionX; ++currX) { ++ final long coordinate = IntPairUtil.key(currX, currZ); + -+ if (node.resize) { -+ table = (TableEntry[])node.getValuePlain(); -+ continue table_loop; -+ } ++ final Node prev = this.nodes.putIfAbsent(coordinate, ret); + -+ synchronized (node) { -+ if (node != (node = getAtIndexVolatile(table, index))) { -+ continue node_loop; -+ } -+ // plain reads are fine during synchronised access, as we are the only writer -+ TableEntry prev = null; -+ for (; node != null; prev = node, node = node.getNextPlain()) { -+ if (node.key == key) { -+ final V ret = node.getValuePlain(); -+ node.setValueVolatile(value); -+ return ret; -+ } ++ if (prev == null) { ++ addedToArea = true; ++ allOwned = false; ++ areaAffected[areaAffectedLen++] = coordinate; ++ continue; + } + -+ // volatile ordering ensured by addSize(), but we need release here -+ // to ensure proper ordering with reads and other writes -+ prev.setNextRelease(new TableEntry<>(key, value)); ++ if (prev.thread != currThread) { ++ park = prev; ++ alreadyOwned = true; ++ break; ++ } + } -+ -+ this.addSize(1L); -+ return null; + } -+ } -+ } -+ -+ /** -+ * Atomically inserts a new mapping with {@code key} mapped to {@code value} if and only if {@code key} is not -+ * currently mapped to some value. -+ * @param key Specified key -+ * @param value Specified value -+ * @throws NullPointerException If value is null -+ * @return Value currently associated with key, or {@code null} if none and {@code value} was associated. -+ */ -+ public V putIfAbsent(final long key, final V value) { -+ Validate.notNull(value, "Value may not be null"); + -+ final int hash = getHash(key); -+ -+ TableEntry[] table = this.table; -+ table_loop: -+ for (;;) { -+ final int index = hash & (table.length - 1); ++ // check for failure ++ if ((park != null && addedToArea) || (park == null && alreadyOwned && !allOwned)) { ++ // failure to acquire: added and we need to block, or improper lock usage ++ for (int i = 0; i < areaAffectedLen; ++i) { ++ final long key = areaAffected[i]; + -+ TableEntry node = getAtIndexVolatile(table, index); -+ node_loop: -+ for (;;) { -+ if (node == null) { -+ if (null == (node = compareAndExchangeAtIndexVolatile(table, index, null, new TableEntry<>(key, value)))) { -+ // successfully inserted -+ this.addSize(1L); -+ return null; -+ } // else: node != null, fall through ++ if (this.nodes.remove(key) != ret) { ++ throw new IllegalStateException(); ++ } + } + -+ if (node.resize) { -+ table = (TableEntry[])node.getValuePlain(); -+ continue table_loop; -+ } ++ areaAffectedLen = 0; + -+ // optimise ifAbsent calls: check if first node is key before attempting lock acquire -+ if (node.key == key) { -+ final V ret = node.getValueVolatile(); -+ if (ret != null) { -+ return ret; -+ } // else: fall back to lock to read the node ++ // since we inserted, we need to drain waiters ++ Thread unpark; ++ while ((unpark = ret.pollOrBlockAdds()) != null) { ++ LockSupport.unpark(unpark); + } ++ } + -+ synchronized (node) { -+ if (node != (node = getAtIndexVolatile(table, index))) { -+ continue node_loop; -+ } -+ // plain reads are fine during synchronised access, as we are the only writer -+ TableEntry prev = null; -+ for (; node != null; prev = node, node = node.getNextPlain()) { -+ if (node.key == key) { -+ return node.getValuePlain(); -+ } -+ } -+ -+ // volatile ordering ensured by addSize(), but we need release here -+ // to ensure proper ordering with reads and other writes -+ prev.setNextRelease(new TableEntry<>(key, value)); ++ if (park == null) { ++ if (alreadyOwned && !allOwned) { ++ throw new IllegalStateException("Improper lock usage: Should never acquire intersecting areas"); + } -+ -+ this.addSize(1L); -+ return null; ++ ret.areaAffectedLen = areaAffectedLen; ++ return ret; + } -+ } -+ } + -+ /** -+ * Atomically updates the value associated with {@code key} to {@code value}, or does nothing if {@code key} is not -+ * associated with a value. -+ * @param key Specified key -+ * @param value Specified value -+ * @throws NullPointerException If value is null -+ * @return Old value previously associated with key, or {@code null} if none. -+ */ -+ public V replace(final long key, final V value) { -+ Validate.notNull(value, "Value may not be null"); -+ -+ final int hash = getHash(key); -+ -+ TableEntry[] table = this.table; -+ table_loop: -+ for (;;) { -+ final int index = hash & (table.length - 1); -+ -+ TableEntry node = getAtIndexVolatile(table, index); -+ node_loop: -+ for (;;) { -+ if (node == null) { -+ return null; -+ } -+ -+ if (node.resize) { -+ table = (TableEntry[])node.getValuePlain(); -+ continue table_loop; -+ } ++ // failed + -+ synchronized (node) { -+ if (node != (node = getAtIndexVolatile(table, index))) { -+ continue node_loop; -+ } ++ ++failures; + -+ // plain reads are fine during synchronised access, as we are the only writer -+ for (; node != null; node = node.getNextPlain()) { -+ if (node.key == key) { -+ final V ret = node.getValuePlain(); -+ node.setValueVolatile(value); -+ return ret; -+ } ++ if (failures > 128L && park.add(currThread)) { ++ LockSupport.park(park); ++ } else { ++ // high contention, spin wait ++ if (failures < 128L) { ++ for (long i = 0; i < failures; ++i) { ++ Thread.onSpinWait(); + } ++ failures = failures << 1; ++ } else if (failures < 1_200L) { ++ LockSupport.parkNanos(1_000L); ++ failures = failures + 1L; ++ } else { // scale 0.1ms (100us) per failure ++ Thread.yield(); ++ LockSupport.parkNanos(100_000L * failures); ++ failures = failures + 1L; + } ++ } + -+ return null; ++ if (addedToArea) { ++ // try again, so we need to allow adds so that other threads can properly block on us ++ ret.allowAdds(); + } + } + } + -+ /** -+ * Atomically updates the value associated with {@code key} to {@code update} if the currently associated -+ * value is reference equal to {@code expect}, otherwise does nothing. -+ * @param key Specified key -+ * @param expect Expected value to check current mapped value with -+ * @param update Update value to replace mapped value with -+ * @throws NullPointerException If value is null -+ * @return If the currently mapped value is not reference equal to {@code expect}, then returns the currently mapped -+ * value. If the key is not mapped to any value, then returns {@code null}. If neither of the two cases are -+ * true, then returns {@code expect}. -+ */ -+ public V replace(final long key, final V expect, final V update) { -+ Validate.notNull(expect, "Expect may not be null"); -+ Validate.notNull(update, "Update may not be null"); ++ public void unlock(final Node node) { ++ if (node.lock != this) { ++ throw new IllegalStateException("Unlock target lock mismatch"); ++ } + -+ final int hash = getHash(key); ++ final long[] areaAffected = node.areaAffected; ++ final int areaAffectedLen = node.areaAffectedLen; + -+ TableEntry[] table = this.table; -+ table_loop: -+ for (;;) { -+ final int index = hash & (table.length - 1); ++ if (areaAffectedLen == 0) { ++ // here we are not in the node map, and so do not need to remove from the node map or unblock any waiters ++ return; ++ } + -+ TableEntry node = getAtIndexVolatile(table, index); -+ node_loop: -+ for (;;) { -+ if (node == null) { -+ return null; -+ } ++ Objects.checkFromToIndex(0, areaAffectedLen, areaAffected.length); + -+ if (node.resize) { -+ table = (TableEntry[])node.getValuePlain(); -+ continue table_loop; -+ } ++ // remove from node map; allowing other threads to lock ++ for (int i = 0; i < areaAffectedLen; ++i) { ++ final long coordinate = areaAffected[i]; ++ if (this.nodes.remove(coordinate, node) != node) { ++ throw new IllegalStateException(); ++ } ++ } + -+ synchronized (node) { -+ if (node != (node = getAtIndexVolatile(table, index))) { -+ continue node_loop; -+ } ++ Thread unpark; ++ while ((unpark = node.pollOrBlockAdds()) != null) { ++ LockSupport.unpark(unpark); ++ } ++ } + -+ // plain reads are fine during synchronised access, as we are the only writer -+ for (; node != null; node = node.getNextPlain()) { -+ if (node.key == key) { -+ final V ret = node.getValuePlain(); ++ public static final class Node extends MultiThreadedQueue { + -+ if (ret != expect) { -+ return ret; -+ } ++ private final ReentrantAreaLock lock; ++ private final long[] areaAffected; ++ private int areaAffectedLen; ++ private final Thread thread; + -+ node.setValueVolatile(update); -+ return ret; -+ } -+ } -+ } ++ private Node(final ReentrantAreaLock lock, final long[] areaAffected, final Thread thread) { ++ this.lock = lock; ++ this.areaAffected = areaAffected; ++ this.thread = thread; ++ } + -+ return null; -+ } ++ @Override ++ public String toString() { ++ return "Node{" + ++ "areaAffected=" + IntPairUtil.toString(this.areaAffected, 0, this.areaAffectedLen) + ++ ", thread=" + this.thread + ++ '}'; + } + } ++} +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/map/ConcurrentLong2ReferenceChainedHashTable.java b/src/main/java/ca/spottedleaf/concurrentutil/map/ConcurrentLong2ReferenceChainedHashTable.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6918f130099e6c19e20a47bfdb54915cdd13732a +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/map/ConcurrentLong2ReferenceChainedHashTable.java +@@ -0,0 +1,1704 @@ ++package ca.spottedleaf.concurrentutil.map; + -+ /** -+ * Atomically removes the mapping for the specified key and returns the value it was associated with. If the key -+ * is not mapped to a value, then does nothing and returns {@code null}. -+ * @param key Specified key -+ * @return Old value previously associated with key, or {@code null} if none. -+ */ -+ public V remove(final long key) { -+ final int hash = getHash(key); ++import ca.spottedleaf.concurrentutil.function.BiLong1Function; ++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.HashUtil; ++import ca.spottedleaf.concurrentutil.util.IntegerUtil; ++import ca.spottedleaf.concurrentutil.util.ThrowUtil; ++import ca.spottedleaf.concurrentutil.util.Validate; ++import java.lang.invoke.VarHandle; ++import java.util.Arrays; ++import java.util.Iterator; ++import java.util.NoSuchElementException; ++import java.util.PrimitiveIterator; ++import java.util.concurrent.atomic.LongAdder; ++import java.util.function.BiFunction; ++import java.util.function.Consumer; ++import java.util.function.Function; ++import java.util.function.LongConsumer; ++import java.util.function.LongFunction; ++import java.util.function.Predicate; + -+ TableEntry[] table = this.table; -+ table_loop: -+ for (;;) { -+ final int index = hash & (table.length - 1); ++/** ++ * Concurrent hashtable implementation supporting mapping arbitrary {@code long} values onto non-null {@code Object} ++ * values with support for multiple writer and multiple reader threads. ++ * ++ *

    Happens-before relationship

    ++ *

    ++ * As with {@link java.util.concurrent.ConcurrentMap}, there is a happens-before relationship between actions in one thread ++ * prior to writing to the map and access to the results of those actions in another thread. ++ *

    ++ * ++ *

    Atomicity of functional methods

    ++ *

    ++ * Functional methods are functions declared in this class which possibly perform a write (remove, replace, or modify) ++ * to an entry in this map as a result of invoking a function on an input parameter. For example, {@link #compute(long, BiLong1Function)}, ++ * {@link #merge(long, Object, BiFunction)} and {@link #removeIf(long, Predicate)} are examples of functional methods. ++ * Functional methods will be performed atomically, that is, the input parameter is guaranteed to only be invoked at most ++ * once per function call. The consequence of this behavior however is that a critical lock for a bin entry is held, which ++ * means that if the input parameter invocation makes additional calls to write into this hash table that the result ++ * is undefined and deadlock-prone. ++ *

    ++ * ++ * @param ++ * @see java.util.concurrent.ConcurrentMap ++ */ ++public class ConcurrentLong2ReferenceChainedHashTable implements Iterable> { + -+ TableEntry node = getAtIndexVolatile(table, index); -+ node_loop: -+ for (;;) { -+ if (node == null) { -+ return null; -+ } ++ 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; + -+ if (node.resize) { -+ table = (TableEntry[])node.getValuePlain(); -+ continue table_loop; -+ } ++ protected final LongAdder size = new LongAdder(); ++ protected final float loadFactor; + -+ boolean removed = false; -+ V ret = null; ++ protected volatile TableEntry[] table; + -+ synchronized (node) { -+ if (node != (node = getAtIndexVolatile(table, index))) { -+ continue node_loop; -+ } ++ protected static final int THRESHOLD_NO_RESIZE = -1; ++ protected static final int THRESHOLD_RESIZING = -2; ++ protected volatile int threshold; ++ protected static final VarHandle THRESHOLD_HANDLE = ConcurrentUtil.getVarHandle(ConcurrentLong2ReferenceChainedHashTable.class, "threshold", int.class); + -+ TableEntry prev = null; ++ protected final int getThresholdAcquire() { ++ return (int)THRESHOLD_HANDLE.getAcquire(this); ++ } + -+ // plain reads are fine during synchronised access, as we are the only writer -+ for (; node != null; prev = node, node = node.getNextPlain()) { -+ if (node.key == key) { -+ ret = node.getValuePlain(); -+ removed = true; ++ protected final int getThresholdVolatile() { ++ return (int)THRESHOLD_HANDLE.getVolatile(this); ++ } + -+ // volatile ordering ensured by addSize(), but we need release here -+ // to ensure proper ordering with reads and other writes -+ if (prev == null) { -+ setAtIndexRelease(table, index, node.getNextPlain()); -+ } else { -+ prev.setNextRelease(node.getNextPlain()); -+ } ++ protected final void setThresholdPlain(final int threshold) { ++ THRESHOLD_HANDLE.set(this, threshold); ++ } + -+ break; -+ } -+ } -+ } ++ protected final void setThresholdRelease(final int threshold) { ++ THRESHOLD_HANDLE.setRelease(this, threshold); ++ } + -+ if (removed) { -+ this.subSize(1L); -+ } ++ protected final void setThresholdVolatile(final int threshold) { ++ THRESHOLD_HANDLE.setVolatile(this, threshold); ++ } + -+ return ret; -+ } ++ protected final int compareExchangeThresholdVolatile(final int expect, final int update) { ++ return (int)THRESHOLD_HANDLE.compareAndExchange(this, expect, update); ++ } ++ ++ public ConcurrentLong2ReferenceChainedHashTable() { ++ this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR); ++ } ++ ++ protected static int getTargetThreshold(final int capacity, final float loadFactor) { ++ final double ret = (double)capacity * (double)loadFactor; ++ if (Double.isInfinite(ret) || ret >= ((double)Integer.MAX_VALUE)) { ++ return THRESHOLD_NO_RESIZE; + } ++ ++ return (int)Math.ceil(ret); + } + -+ /** -+ * Atomically removes the mapping for the specified key if it is mapped to {@code expect} and returns {@code expect}. If the key -+ * is not mapped to a value, then does nothing and returns {@code null}. If the key is mapped to a value that is not reference -+ * equal to {@code expect}, then returns that value. -+ * @param key Specified key -+ * @param expect Specified expected value -+ * @return The specified expected value if the key was mapped to {@code expect}. If -+ * the key is not mapped to any value, then returns {@code null}. If neither of those cases are true, -+ * then returns the current (non-null) mapped value for key. -+ */ -+ public V remove(final long key, final V expect) { -+ final int hash = getHash(key); ++ 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); ++ } + -+ TableEntry[] table = this.table; -+ table_loop: -+ for (;;) { -+ final int index = hash & (table.length - 1); ++ protected ConcurrentLong2ReferenceChainedHashTable(final int capacity, final float loadFactor) { ++ final int tableSize = getCapacityFor(capacity); + -+ TableEntry node = getAtIndexVolatile(table, index); -+ node_loop: -+ for (;;) { -+ if (node == null) { -+ return null; -+ } ++ if (loadFactor <= 0.0 || !Float.isFinite(loadFactor)) { ++ throw new IllegalArgumentException("Invalid load factor: " + loadFactor); ++ } + -+ if (node.resize) { -+ table = (TableEntry[])node.getValuePlain(); -+ continue table_loop; -+ } ++ if (tableSize == MAXIMUM_CAPACITY) { ++ this.setThresholdPlain(THRESHOLD_NO_RESIZE); ++ } else { ++ this.setThresholdPlain(getTargetThreshold(tableSize, loadFactor)); ++ } + -+ boolean removed = false; -+ V ret = null; ++ this.loadFactor = loadFactor; ++ // noinspection unchecked ++ this.table = (TableEntry[])new TableEntry[tableSize]; ++ } + -+ synchronized (node) { -+ if (node != (node = getAtIndexVolatile(table, index))) { -+ continue node_loop; -+ } ++ public static ConcurrentLong2ReferenceChainedHashTable createWithCapacity(final int capacity) { ++ return createWithCapacity(capacity, DEFAULT_LOAD_FACTOR); ++ } + -+ TableEntry prev = null; ++ public static ConcurrentLong2ReferenceChainedHashTable createWithCapacity(final int capacity, final float loadFactor) { ++ return new ConcurrentLong2ReferenceChainedHashTable<>(capacity, loadFactor); ++ } + -+ // plain reads are fine during synchronised access, as we are the only writer -+ for (; node != null; prev = node, node = node.getNextPlain()) { -+ if (node.key == key) { -+ ret = node.getValuePlain(); -+ if (ret == expect) { -+ removed = true; ++ public static ConcurrentLong2ReferenceChainedHashTable createWithExpected(final int expected) { ++ return createWithExpected(expected, DEFAULT_LOAD_FACTOR); ++ } + -+ // volatile ordering ensured by addSize(), but we need release here -+ // to ensure proper ordering with reads and other writes -+ if (prev == null) { -+ setAtIndexRelease(table, index, node.getNextPlain()); -+ } else { -+ prev.setNextRelease(node.getNextPlain()); -+ } -+ } -+ break; -+ } -+ } -+ } ++ public static ConcurrentLong2ReferenceChainedHashTable createWithExpected(final int expected, final float loadFactor) { ++ final int capacity = (int)Math.ceil((double)expected / (double)loadFactor); + -+ if (removed) { -+ this.subSize(1L); -+ } ++ return createWithCapacity(capacity, loadFactor); ++ } + -+ return ret; -+ } -+ } ++ /** must be deterministic given a key */ ++ protected static int getHash(final long key) { ++ return (int)HashUtil.mix(key); + } + + /** -+ * Atomically removes the mapping for the specified key the predicate returns true for its currently mapped value. If the key -+ * is not mapped to a value, then does nothing and returns {@code null}. -+ * -+ *

    -+ * This function is a "functional methods" as defined by {@link ConcurrentLong2ReferenceChainedHashTable}. -+ *

    -+ * -+ * @param key Specified key -+ * @param predicate Specified predicate -+ * @throws NullPointerException If predicate is null -+ * @return The specified expected value if the key was mapped to {@code expect}. If -+ * the key is not mapped to any value, then returns {@code null}. If neither of those cases are true, -+ * then returns the current (non-null) mapped value for key. ++ * Returns the load factor associated with this map. + */ -+ public V removeIf(final long key, final Predicate predicate) { -+ Validate.notNull(predicate, "Predicate may not be null"); -+ -+ final int hash = getHash(key); ++ public final float getLoadFactor() { ++ return this.loadFactor; ++ } + -+ TableEntry[] table = this.table; -+ table_loop: -+ for (;;) { -+ final int index = hash & (table.length - 1); ++ protected static TableEntry getAtIndexVolatile(final TableEntry[] table, final int index) { ++ //noinspection unchecked ++ return (TableEntry)TableEntry.TABLE_ENTRY_ARRAY_HANDLE.getVolatile(table, index); ++ } + -+ TableEntry node = getAtIndexVolatile(table, index); -+ node_loop: -+ for (;;) { -+ if (node == null) { -+ return null; -+ } ++ protected static void setAtIndexRelease(final TableEntry[] table, final int index, final TableEntry value) { ++ TableEntry.TABLE_ENTRY_ARRAY_HANDLE.setRelease(table, index, value); ++ } + -+ if (node.resize) { -+ table = (TableEntry[])node.getValuePlain(); -+ continue table_loop; -+ } ++ protected static void setAtIndexVolatile(final TableEntry[] table, final int index, final TableEntry value) { ++ TableEntry.TABLE_ENTRY_ARRAY_HANDLE.setVolatile(table, index, value); ++ } + -+ boolean removed = false; -+ V ret = null; ++ protected static TableEntry compareAndExchangeAtIndexVolatile(final TableEntry[] table, final int index, ++ final TableEntry expect, final TableEntry update) { ++ //noinspection unchecked ++ return (TableEntry)TableEntry.TABLE_ENTRY_ARRAY_HANDLE.compareAndExchange(table, index, expect, update); ++ } + -+ synchronized (node) { -+ if (node != (node = getAtIndexVolatile(table, index))) { -+ continue node_loop; -+ } ++ /** ++ * Returns the possible node associated with the key, or {@code null} if there is no such node. The node ++ * returned may have a {@code null} {@link TableEntry#value}, in which case the node is a placeholder for ++ * a compute/computeIfAbsent call. The placeholder node should not be considered mapped in order to preserve ++ * happens-before relationships between writes and reads in the map. ++ */ ++ protected final TableEntry getNode(final long key) { ++ final int hash = getHash(key); + -+ TableEntry prev = null; ++ TableEntry[] table = this.table; ++ for (;;) { ++ TableEntry node = getAtIndexVolatile(table, hash & (table.length - 1)); + -+ // plain reads are fine during synchronised access, as we are the only writer -+ for (; node != null; prev = node, node = node.getNextPlain()) { -+ if (node.key == key) { -+ ret = node.getValuePlain(); -+ if (predicate.test(ret)) { -+ removed = true; ++ if (node == null) { ++ // node == null ++ return node; ++ } + -+ // volatile ordering ensured by addSize(), but we need release here -+ // to ensure proper ordering with reads and other writes -+ if (prev == null) { -+ setAtIndexRelease(table, index, node.getNextPlain()); -+ } else { -+ prev.setNextRelease(node.getNextPlain()); -+ } -+ } -+ break; -+ } -+ } -+ } ++ if (node.resize) { ++ // noinspection unchecked ++ table = (TableEntry[])node.getValuePlain(); ++ continue; ++ } + -+ if (removed) { -+ this.subSize(1L); ++ for (; node != null; node = node.getNextVolatile()) { ++ if (node.key == key) { ++ return node; + } -+ -+ return ret; + } ++ ++ // node == null ++ return node; + } + } + + /** -+ * See {@link java.util.concurrent.ConcurrentMap#compute(Object, BiFunction)} -+ *

    -+ * This function is a "functional methods" as defined by {@link ConcurrentLong2ReferenceChainedHashTable}. -+ *

    ++ * Returns the currently mapped value associated with the specified key, or {@code null} if there is none. ++ * ++ * @param key Specified key + */ -+ public V compute(final long key, final BiLong1Function function) { -+ final int hash = getHash(key); -+ -+ TableEntry[] table = this.table; -+ table_loop: -+ for (;;) { -+ final int index = hash & (table.length - 1); ++ public V get(final long key) { ++ final TableEntry node = this.getNode(key); ++ return node == null ? null : node.getValueVolatile(); ++ } + -+ TableEntry node = getAtIndexVolatile(table, index); -+ node_loop: -+ for (;;) { -+ V ret = null; -+ if (node == null) { -+ final TableEntry insert = new TableEntry<>(key, null); ++ /** ++ * Returns the currently mapped value associated with the specified key, or the specified default value if there is none. ++ * ++ * @param key Specified key ++ * @param defaultValue Specified default value ++ */ ++ public V getOrDefault(final long key, final V defaultValue) { ++ final TableEntry node = this.getNode(key); ++ if (node == null) { ++ return defaultValue; ++ } + -+ boolean added = false; -+ -+ synchronized (insert) { -+ if (null == (node = compareAndExchangeAtIndexVolatile(table, index, null, insert))) { -+ try { -+ ret = function.apply(key, null); -+ } catch (final Throwable throwable) { -+ setAtIndexVolatile(table, index, null); -+ ThrowUtil.throwUnchecked(throwable); -+ // unreachable -+ return null; -+ } -+ -+ if (ret == null) { -+ setAtIndexVolatile(table, index, null); -+ return ret; -+ } else { -+ // volatile ordering ensured by addSize(), but we need release here -+ // to ensure proper ordering with reads and other writes -+ insert.setValueRelease(ret); -+ added = true; -+ } -+ } // else: node != null, fall through -+ } -+ -+ if (added) { -+ this.addSize(1L); -+ return ret; -+ } -+ } -+ -+ if (node.resize) { -+ table = (TableEntry[])node.getValuePlain(); -+ continue table_loop; -+ } -+ -+ boolean removed = false; -+ boolean added = false; -+ -+ synchronized (node) { -+ if (node != (node = getAtIndexVolatile(table, index))) { -+ continue node_loop; -+ } -+ // plain reads are fine during synchronised access, as we are the only writer -+ TableEntry prev = null; -+ for (; node != null; prev = node, node = node.getNextPlain()) { -+ if (node.key == key) { -+ final V old = node.getValuePlain(); -+ -+ final V computed = function.apply(key, old); -+ -+ if (computed != null) { -+ node.setValueVolatile(computed); -+ return computed; -+ } -+ -+ // volatile ordering ensured by addSize(), but we need release here -+ // to ensure proper ordering with reads and other writes -+ if (prev == null) { -+ setAtIndexRelease(table, index, node.getNextPlain()); -+ } else { -+ prev.setNextRelease(node.getNextPlain()); -+ } -+ -+ removed = true; -+ break; -+ } -+ } -+ -+ if (!removed) { -+ final V computed = function.apply(key, null); -+ if (computed != null) { -+ // volatile ordering ensured by addSize(), but we need release here -+ // to ensure proper ordering with reads and other writes -+ prev.setNextRelease(new TableEntry<>(key, computed)); -+ ret = computed; -+ added = true; -+ } -+ } -+ } -+ -+ if (removed) { -+ this.subSize(1L); -+ } -+ if (added) { -+ this.addSize(1L); -+ } -+ -+ return ret; -+ } -+ } -+ } -+ -+ /** -+ * See {@link java.util.concurrent.ConcurrentMap#computeIfAbsent(Object, Function)} -+ *

    -+ * This function is a "functional methods" as defined by {@link ConcurrentLong2ReferenceChainedHashTable}. -+ *

    -+ */ -+ public V computeIfAbsent(final long key, final LongFunction function) { -+ final int hash = getHash(key); -+ -+ TableEntry[] table = this.table; -+ table_loop: -+ for (;;) { -+ final int index = hash & (table.length - 1); -+ -+ TableEntry node = getAtIndexVolatile(table, index); -+ node_loop: -+ for (;;) { -+ V ret = null; -+ if (node == null) { -+ final TableEntry insert = new TableEntry<>(key, null); -+ -+ boolean added = false; -+ -+ synchronized (insert) { -+ if (null == (node = compareAndExchangeAtIndexVolatile(table, index, null, insert))) { -+ try { -+ ret = function.apply(key); -+ } catch (final Throwable throwable) { -+ setAtIndexVolatile(table, index, null); -+ ThrowUtil.throwUnchecked(throwable); -+ // unreachable -+ return null; -+ } -+ -+ if (ret == null) { -+ setAtIndexVolatile(table, index, null); -+ return null; -+ } else { -+ // volatile ordering ensured by addSize(), but we need release here -+ // to ensure proper ordering with reads and other writes -+ insert.setValueRelease(ret); -+ added = true; -+ } -+ } // else: node != null, fall through -+ } -+ -+ if (added) { -+ this.addSize(1L); -+ return ret; -+ } -+ } -+ -+ if (node.resize) { -+ table = (TableEntry[])node.getValuePlain(); -+ continue table_loop; -+ } -+ -+ // optimise ifAbsent calls: check if first node is key before attempting lock acquire -+ if (node.key == key) { -+ ret = node.getValueVolatile(); -+ if (ret != null) { -+ return ret; -+ } // else: fall back to lock to read the node -+ } -+ -+ boolean added = false; -+ -+ synchronized (node) { -+ if (node != (node = getAtIndexVolatile(table, index))) { -+ continue node_loop; -+ } -+ // plain reads are fine during synchronised access, as we are the only writer -+ TableEntry prev = null; -+ for (; node != null; prev = node, node = node.getNextPlain()) { -+ if (node.key == key) { -+ ret = node.getValuePlain(); -+ return ret; -+ } -+ } -+ -+ final V computed = function.apply(key); -+ if (computed != null) { -+ // volatile ordering ensured by addSize(), but we need release here -+ // to ensure proper ordering with reads and other writes -+ prev.setNextRelease(new TableEntry<>(key, computed)); -+ ret = computed; -+ added = true; -+ } -+ } -+ -+ if (added) { -+ this.addSize(1L); -+ } -+ -+ return ret; -+ } -+ } -+ } -+ -+ /** -+ * See {@link java.util.concurrent.ConcurrentMap#computeIfPresent(Object, BiFunction)} -+ *

    -+ * This function is a "functional methods" as defined by {@link ConcurrentLong2ReferenceChainedHashTable}. -+ *

    -+ */ -+ public V computeIfPresent(final long key, final BiLong1Function function) { -+ final int hash = getHash(key); -+ -+ TableEntry[] table = this.table; -+ table_loop: -+ for (;;) { -+ final int index = hash & (table.length - 1); -+ -+ TableEntry node = getAtIndexVolatile(table, index); -+ node_loop: -+ for (;;) { -+ if (node == null) { -+ return null; -+ } -+ -+ if (node.resize) { -+ table = (TableEntry[])node.getValuePlain(); -+ continue table_loop; -+ } -+ -+ boolean removed = false; -+ -+ synchronized (node) { -+ if (node != (node = getAtIndexVolatile(table, index))) { -+ continue node_loop; -+ } -+ // plain reads are fine during synchronised access, as we are the only writer -+ TableEntry prev = null; -+ for (; node != null; prev = node, node = node.getNextPlain()) { -+ if (node.key == key) { -+ final V old = node.getValuePlain(); -+ -+ final V computed = function.apply(key, old); -+ -+ if (computed != null) { -+ node.setValueVolatile(computed); -+ return computed; -+ } -+ -+ // volatile ordering ensured by addSize(), but we need release here -+ // to ensure proper ordering with reads and other writes -+ if (prev == null) { -+ setAtIndexRelease(table, index, node.getNextPlain()); -+ } else { -+ prev.setNextRelease(node.getNextPlain()); -+ } -+ -+ removed = true; -+ break; -+ } -+ } -+ } -+ -+ if (removed) { -+ this.subSize(1L); -+ } -+ -+ return null; -+ } -+ } -+ } -+ -+ /** -+ * See {@link java.util.concurrent.ConcurrentMap#merge(Object, Object, BiFunction)} -+ *

    -+ * This function is a "functional methods" as defined by {@link ConcurrentLong2ReferenceChainedHashTable}. -+ *

    -+ */ -+ public V merge(final long key, final V def, final BiFunction function) { -+ Validate.notNull(def, "Default value may not be null"); -+ -+ final int hash = getHash(key); -+ -+ TableEntry[] table = this.table; -+ table_loop: -+ for (;;) { -+ final int index = hash & (table.length - 1); -+ -+ TableEntry node = getAtIndexVolatile(table, index); -+ node_loop: -+ for (;;) { -+ if (node == null) { -+ if (null == (node = compareAndExchangeAtIndexVolatile(table, index, null, new TableEntry<>(key, def)))) { -+ // successfully inserted -+ this.addSize(1L); -+ return def; -+ } // else: node != null, fall through -+ } -+ -+ if (node.resize) { -+ table = (TableEntry[])node.getValuePlain(); -+ continue table_loop; -+ } -+ -+ boolean removed = false; -+ boolean added = false; -+ V ret = null; -+ -+ synchronized (node) { -+ if (node != (node = getAtIndexVolatile(table, index))) { -+ continue node_loop; -+ } -+ // plain reads are fine during synchronised access, as we are the only writer -+ TableEntry prev = null; -+ for (; node != null; prev = node, node = node.getNextPlain()) { -+ if (node.key == key) { -+ final V old = node.getValuePlain(); -+ -+ final V computed = function.apply(old, def); -+ -+ if (computed != null) { -+ node.setValueVolatile(computed); -+ return computed; -+ } -+ -+ // volatile ordering ensured by addSize(), but we need release here -+ // to ensure proper ordering with reads and other writes -+ if (prev == null) { -+ setAtIndexRelease(table, index, node.getNextPlain()); -+ } else { -+ prev.setNextRelease(node.getNextPlain()); -+ } -+ -+ removed = true; -+ break; -+ } -+ } -+ -+ if (!removed) { -+ // volatile ordering ensured by addSize(), but we need release here -+ // to ensure proper ordering with reads and other writes -+ prev.setNextRelease(new TableEntry<>(key, def)); -+ ret = def; -+ added = true; -+ } -+ } -+ -+ if (removed) { -+ this.subSize(1L); -+ } -+ if (added) { -+ this.addSize(1L); -+ } -+ -+ return ret; -+ } -+ } -+ } -+ -+ /** -+ * Removes at least all entries currently mapped at the beginning of this call. May not remove entries added during -+ * this call. As a result, only if this map is not modified during the call, that all entries will be removed by -+ * the end of the call. -+ * -+ *

    -+ * This function is not atomic. -+ *

    -+ */ -+ public void clear() { -+ // it is possible to optimise this to directly interact with the table, -+ // but we do need to be careful when interacting with resized tables, -+ // and the NodeIterator already does this logic -+ final NodeIterator nodeIterator = new NodeIterator<>(this.table); -+ -+ TableEntry node; -+ while ((node = nodeIterator.findNext()) != null) { -+ this.remove(node.key); -+ } -+ } -+ -+ /** -+ * Returns an iterator over the entries in this map. The iterator is only guaranteed to see entries that were -+ * added before the beginning of this call, but it may see entries added during. -+ */ -+ public Iterator> entryIterator() { -+ return new EntryIterator<>(this); -+ } -+ -+ /** -+ * Returns an iterator over the keys in this map. The iterator is only guaranteed to see keys that were -+ * added before the beginning of this call, but it may see keys added during. -+ */ -+ public PrimitiveIterator.OfLong keyIterator() { -+ return new KeyIterator<>(this); -+ } -+ -+ /** -+ * Returns an iterator over the values in this map. The iterator is only guaranteed to see values that were -+ * added before the beginning of this call, but it may see values added during. -+ */ -+ public Iterator valueIterator() { -+ return new ValueIterator<>(this); -+ } -+ -+ protected static final class EntryIterator extends BaseIteratorImpl> { -+ -+ protected EntryIterator(final ConcurrentLong2ReferenceChainedHashTable map) { -+ super(map); -+ } -+ -+ @Override -+ public TableEntry next() throws NoSuchElementException { -+ return this.nextNode(); -+ } -+ -+ @Override -+ public void forEachRemaining(final Consumer> action) { -+ Validate.notNull(action, "Action may not be null"); -+ while (this.hasNext()) { -+ action.accept(this.next()); -+ } -+ } -+ } -+ -+ protected static final class KeyIterator extends BaseIteratorImpl implements PrimitiveIterator.OfLong { -+ -+ protected KeyIterator(final ConcurrentLong2ReferenceChainedHashTable map) { -+ super(map); -+ } -+ -+ @Override -+ public Long next() throws NoSuchElementException { -+ return Long.valueOf(this.nextNode().key); -+ } -+ -+ @Override -+ public long nextLong() { -+ return this.nextNode().key; ++ final V ret = node.getValueVolatile(); ++ if (ret == null) { ++ // ret == null for nodes pre-allocated to compute() and friends ++ return defaultValue; + } + -+ @Override -+ public void forEachRemaining(final Consumer action) { -+ Validate.notNull(action, "Action may not be null"); ++ return ret; ++ } + -+ if (action instanceof LongConsumer longConsumer) { -+ this.forEachRemaining(longConsumer); -+ return; -+ } ++ /** ++ * Returns whether the specified key is mapped to some value. ++ * @param key Specified key ++ */ ++ public boolean containsKey(final long key) { ++ // cannot use getNode, as the node may be a placeholder for compute() ++ return this.get(key) != null; ++ } + -+ while (this.hasNext()) { -+ action.accept(this.next()); -+ } -+ } ++ /** ++ * Returns whether the specified value has a key mapped to it. ++ * @param value Specified value ++ * @throws NullPointerException If value is null ++ */ ++ public boolean containsValue(final V value) { ++ Validate.notNull(value, "Value cannot be null"); + -+ @Override -+ public void forEachRemaining(final LongConsumer action) { -+ Validate.notNull(action, "Action may not be null"); -+ while (this.hasNext()) { -+ action.accept(this.nextLong()); ++ final NodeIterator iterator = new NodeIterator<>(this.table); ++ ++ TableEntry node; ++ while ((node = iterator.findNext()) != null) { ++ // need to use acquire here to ensure the happens-before relationship ++ if (node.getValueAcquire() == value) { ++ return true; + } + } ++ ++ return false; + } + -+ protected static final class ValueIterator extends BaseIteratorImpl { ++ /** ++ * Returns the number of mappings in this map. ++ */ ++ public int size() { ++ final long ret = this.size.sum(); + -+ protected ValueIterator(final ConcurrentLong2ReferenceChainedHashTable map) { -+ super(map); ++ if (ret < 0L) { ++ return 0; + } -+ -+ @Override -+ public V next() throws NoSuchElementException { -+ return this.nextNode().getValueVolatile(); ++ if (ret > (long)Integer.MAX_VALUE) { ++ return Integer.MAX_VALUE; + } + -+ @Override -+ public void forEachRemaining(final Consumer action) { -+ Validate.notNull(action, "Action may not be null"); -+ while (this.hasNext()) { -+ action.accept(this.next()); -+ } -+ } ++ return (int)ret; + } + -+ protected static abstract class BaseIteratorImpl extends NodeIterator implements Iterator { -+ -+ protected final ConcurrentLong2ReferenceChainedHashTable map; -+ protected TableEntry lastReturned; -+ protected TableEntry nextToReturn; ++ /** ++ * Returns whether this map has no mappings. ++ */ ++ public boolean isEmpty() { ++ return this.size.sum() <= 0L; ++ } + -+ protected BaseIteratorImpl(final ConcurrentLong2ReferenceChainedHashTable map) { -+ super(map.table); -+ this.map = map; -+ } ++ /** ++ * Adds count to size and checks threshold for resizing ++ */ ++ protected final void addSize(final long count) { ++ this.size.add(count); + -+ @Override -+ public final boolean hasNext() { -+ if (this.nextToReturn != null) { -+ return true; -+ } ++ final int threshold = this.getThresholdAcquire(); + -+ return (this.nextToReturn = this.findNext()) != null; ++ if (threshold < 0L) { ++ // resizing or no resizing allowed, in either cases we do not need to do anything ++ return; + } + -+ protected final TableEntry nextNode() throws NoSuchElementException { -+ TableEntry ret = this.nextToReturn; -+ if (ret != null) { -+ this.lastReturned = ret; -+ this.nextToReturn = null; -+ return ret; -+ } -+ ret = this.findNext(); -+ if (ret != null) { -+ this.lastReturned = ret; -+ return ret; -+ } -+ throw new NoSuchElementException(); -+ } ++ final long sum = this.size.sum(); + -+ @Override -+ public final void remove() { -+ final TableEntry lastReturned = this.nextToReturn; -+ if (lastReturned == null) { -+ throw new NoSuchElementException(); -+ } -+ this.lastReturned = null; -+ this.map.remove(lastReturned.key); ++ if (sum < (long)threshold) { ++ return; + } + -+ @Override -+ public abstract T next() throws NoSuchElementException; -+ -+ // overwritten by subclasses to avoid indirection on hasNext() and next() -+ @Override -+ public abstract void forEachRemaining(final Consumer action); -+ } -+ -+ protected static class NodeIterator { -+ -+ protected TableEntry[] currentTable; -+ protected ResizeChain resizeChain; -+ protected TableEntry last; -+ protected int nextBin; -+ protected int increment; -+ -+ protected NodeIterator(final TableEntry[] baseTable) { -+ this.currentTable = baseTable; -+ this.increment = 1; ++ if (threshold != this.compareExchangeThresholdVolatile(threshold, THRESHOLD_RESIZING)) { ++ // some other thread resized ++ return; + } + -+ private TableEntry[] pullResizeChain(final int index) { -+ final ResizeChain resizeChain = this.resizeChain; -+ if (resizeChain == null) { -+ this.currentTable = null; -+ return null; -+ } -+ -+ final ResizeChain prevChain = resizeChain.prev; -+ this.resizeChain = prevChain; -+ if (prevChain == null) { -+ this.currentTable = null; -+ return null; -+ } -+ -+ final TableEntry[] newTable = prevChain.table; ++ // create new table ++ this.resize(sum); ++ } + -+ // we recover the original index by modding by the new table length, as the increments applied to the index -+ // are a multiple of the new table's length -+ int newIdx = index & (newTable.length - 1); ++ /** ++ * Resizes table, only invoke for the thread which has successfully updated threshold to {@link #THRESHOLD_RESIZING} ++ * @param sum Estimate of current mapping count, must be >= old threshold ++ */ ++ private void resize(final long sum) { ++ int capacity; + -+ // the increment is always the previous table's length -+ final ResizeChain nextPrevChain = prevChain.prev; -+ final int increment; -+ if (nextPrevChain == null) { -+ increment = 1; -+ } else { -+ increment = nextPrevChain.table.length; ++ // add 1.0, as sum may equal threshold (in which case, sum / loadFactor = current capacity) ++ // adding 1.0 should at least raise the size by a factor of two due to usage of roundCeilLog2 ++ final double targetD = ((double)sum / (double)this.loadFactor) + 1.0; ++ if (targetD >= (double)MAXIMUM_CAPACITY) { ++ capacity = MAXIMUM_CAPACITY; ++ } else { ++ capacity = (int)Math.ceil(targetD); ++ capacity = IntegerUtil.roundCeilLog2(capacity); ++ if (capacity > MAXIMUM_CAPACITY) { ++ capacity = MAXIMUM_CAPACITY; + } -+ -+ // done with the upper table, so we can skip the resize node -+ newIdx += increment; -+ -+ this.increment = increment; -+ this.nextBin = newIdx; -+ this.currentTable = newTable; -+ -+ return newTable; + } + -+ private TableEntry[] pushResizeChain(final TableEntry[] table, final TableEntry entry) { -+ final ResizeChain chain = this.resizeChain; ++ // create new table data + -+ if (chain == null) { -+ final TableEntry[] nextTable = (TableEntry[])entry.getValuePlain(); ++ // noinspection unchecked ++ final TableEntry[] newTable = new TableEntry[capacity]; ++ // noinspection unchecked ++ final TableEntry resizeNode = new TableEntry<>(0L, (V)newTable, true); + -+ final ResizeChain oldChain = new ResizeChain<>(table, null, null); -+ final ResizeChain currChain = new ResizeChain<>(nextTable, oldChain, null); -+ oldChain.next = currChain; ++ // transfer nodes from old table + -+ this.increment = table.length; -+ this.resizeChain = currChain; -+ this.currentTable = nextTable; ++ // does not need to be volatile read, just plain ++ final TableEntry[] oldTable = this.table; + -+ return nextTable; -+ } else { -+ ResizeChain currChain = chain.next; -+ if (currChain == null) { -+ final TableEntry[] ret = (TableEntry[])entry.getValuePlain(); -+ currChain = new ResizeChain<>(ret, chain, null); -+ chain.next = currChain; ++ // when resizing, the old entries at bin i (where i = hash % oldTable.length) are assigned to ++ // bin k in the new table (where k = hash % newTable.length) ++ // since both table lengths are powers of two (specifically, newTable is a multiple of oldTable), ++ // the possible number of locations in the new table to assign any given i is newTable.length/oldTable.length + -+ this.increment = table.length; -+ this.resizeChain = currChain; -+ this.currentTable = ret; ++ // we can build the new linked nodes for the new table by using a work array sized to newTable.length/oldTable.length ++ // which holds the _last_ entry in the chain per bin + -+ return ret; -+ } else { -+ this.increment = table.length; -+ this.resizeChain = currChain; -+ return this.currentTable = currChain.table; -+ } -+ } ++ final int capOldShift = IntegerUtil.floorLog2(oldTable.length); ++ final int capDiffShift = IntegerUtil.floorLog2(capacity) - capOldShift; ++ ++ if (capDiffShift == 0) { ++ throw new IllegalStateException("Resizing to same size"); + } + -+ protected final TableEntry findNext() { -+ for (;;) { -+ final TableEntry last = this.last; -+ if (last != null) { -+ final TableEntry next = last.getNextVolatile(); -+ if (next != null) { -+ this.last = next; -+ if (next.getValuePlain() == null) { -+ // compute() node not yet available -+ continue; -+ } -+ return next; -+ } -+ } ++ // noinspection unchecked ++ final TableEntry[] work = new TableEntry[1 << capDiffShift]; // typically, capDiffShift = 1 + -+ TableEntry[] table = this.currentTable; ++ for (int i = 0, len = oldTable.length; i < len; ++i) { ++ TableEntry binNode = getAtIndexVolatile(oldTable, i); + -+ if (table == null) { -+ return null; ++ for (;;) { ++ if (binNode == null) { ++ // just need to replace the bin node, do not need to move anything ++ if (null == (binNode = compareAndExchangeAtIndexVolatile(oldTable, i, null, resizeNode))) { ++ break; ++ } // else: binNode != null, fall through + } + -+ int idx = this.nextBin; -+ int increment = this.increment; -+ for (;;) { -+ if (idx >= table.length) { -+ table = this.pullResizeChain(idx); -+ idx = this.nextBin; -+ increment = this.increment; -+ if (table != null) { -+ continue; -+ } else { -+ this.last = null; -+ return null; -+ } -+ } -+ -+ final TableEntry entry = getAtIndexVolatile(table, idx); -+ if (entry == null) { -+ idx += increment; ++ // need write lock to block other writers ++ synchronized (binNode) { ++ if (binNode != (binNode = getAtIndexVolatile(oldTable, i))) { + continue; + } + -+ if (entry.resize) { -+ // push onto resize chain -+ table = this.pushResizeChain(table, entry); -+ increment = this.increment; -+ continue; -+ } ++ // an important detail of resizing is that we do not need to be concerned with synchronisation on ++ // writes to the new table, as no access to any nodes on bin i on oldTable will occur until a thread ++ // sees the resizeNode ++ // specifically, as long as the resizeNode is release written there are no cases where another thread ++ // will see our writes to the new table + -+ this.last = entry; -+ this.nextBin = idx + increment; -+ if (entry.getValuePlain() != null) { -+ return entry; ++ TableEntry next = binNode.getNextPlain(); ++ ++ if (next == null) { ++ // simple case: do not use work array ++ ++ // do not need to create new node, readers only need to see the state of the map at the ++ // beginning of a call, so any additions onto _next_ don't really matter ++ // additionally, the old node is replaced so that writers automatically forward to the new table, ++ // which resolves any issues ++ newTable[getHash(binNode.key) & (capacity - 1)] = binNode; + } else { -+ // compute() node not yet available -+ break; -+ } -+ } -+ } -+ } ++ // reset for next usage ++ Arrays.fill(work, null); + -+ protected static final class ResizeChain { ++ for (TableEntry curr = binNode; curr != null; curr = curr.getNextPlain()) { ++ final int newTableIdx = getHash(curr.key) & (capacity - 1); ++ final int workIdx = newTableIdx >>> capOldShift; + -+ protected final TableEntry[] table; -+ protected final ResizeChain prev; -+ protected ResizeChain next; ++ final TableEntry replace = new TableEntry<>(curr.key, curr.getValuePlain()); + -+ protected ResizeChain(final TableEntry[] table, final ResizeChain prev, final ResizeChain next) { -+ this.table = table; -+ this.prev = prev; -+ this.next = next; ++ final TableEntry workNode = work[workIdx]; ++ work[workIdx] = replace; ++ ++ if (workNode == null) { ++ newTable[newTableIdx] = replace; ++ continue; ++ } else { ++ workNode.setNextPlain(replace); ++ continue; ++ } ++ } ++ } ++ ++ setAtIndexRelease(oldTable, i, resizeNode); ++ break; ++ } + } + } -+ } + -+ public static final class TableEntry { ++ // calculate new threshold ++ final int newThreshold; ++ if (capacity == MAXIMUM_CAPACITY) { ++ newThreshold = THRESHOLD_NO_RESIZE; ++ } else { ++ newThreshold = getTargetThreshold(capacity, loadFactor); ++ } + -+ protected static final VarHandle TABLE_ENTRY_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(TableEntry[].class); ++ this.table = newTable; ++ // finish resize operation by releasing hold on threshold ++ this.setThresholdVolatile(newThreshold); ++ } + -+ protected final boolean resize; ++ /** ++ * Subtracts count from size ++ */ ++ protected final void subSize(final long count) { ++ this.size.add(-count); ++ } + -+ protected final long key; ++ /** ++ * Atomically updates the value associated with {@code key} to {@code value}, or inserts a new mapping with {@code key} ++ * mapped to {@code value}. ++ * @param key Specified key ++ * @param value Specified value ++ * @throws NullPointerException If value is null ++ * @return Old value previously associated with key, or {@code null} if none. ++ */ ++ public V put(final long key, final V value) { ++ Validate.notNull(value, "Value may not be null"); + -+ protected volatile V value; -+ protected static final VarHandle VALUE_HANDLE = ConcurrentUtil.getVarHandle(TableEntry.class, "value", Object.class); ++ final int hash = getHash(key); + -+ protected final V getValuePlain() { -+ //noinspection unchecked -+ return (V)VALUE_HANDLE.get(this); -+ } ++ TableEntry[] table = this.table; ++ table_loop: ++ for (;;) { ++ final int index = hash & (table.length - 1); + -+ protected final V getValueAcquire() { -+ //noinspection unchecked -+ return (V)VALUE_HANDLE.getAcquire(this); -+ } ++ TableEntry node = getAtIndexVolatile(table, index); ++ node_loop: ++ for (;;) { ++ if (node == null) { ++ if (null == (node = compareAndExchangeAtIndexVolatile(table, index, null, new TableEntry<>(key, value)))) { ++ // successfully inserted ++ this.addSize(1L); ++ return null; ++ } // else: node != null, fall through ++ } + -+ protected final V getValueVolatile() { -+ //noinspection unchecked -+ return (V)VALUE_HANDLE.getVolatile(this); -+ } ++ if (node.resize) { ++ table = (TableEntry[])node.getValuePlain(); ++ continue table_loop; ++ } + -+ protected final void setValuePlain(final V value) { -+ VALUE_HANDLE.set(this, (Object)value); -+ } ++ synchronized (node) { ++ if (node != (node = getAtIndexVolatile(table, index))) { ++ continue node_loop; ++ } ++ // plain reads are fine during synchronised access, as we are the only writer ++ TableEntry prev = null; ++ for (; node != null; prev = node, node = node.getNextPlain()) { ++ if (node.key == key) { ++ final V ret = node.getValuePlain(); ++ node.setValueVolatile(value); ++ return ret; ++ } ++ } + -+ protected final void setValueRelease(final V value) { -+ VALUE_HANDLE.setRelease(this, (Object)value); -+ } ++ // volatile ordering ensured by addSize(), but we need release here ++ // to ensure proper ordering with reads and other writes ++ prev.setNextRelease(new TableEntry<>(key, value)); ++ } + -+ protected final void setValueVolatile(final V value) { -+ VALUE_HANDLE.setVolatile(this, (Object)value); ++ this.addSize(1L); ++ return null; ++ } + } ++ } + -+ protected volatile TableEntry next; -+ protected static final VarHandle NEXT_HANDLE = ConcurrentUtil.getVarHandle(TableEntry.class, "next", TableEntry.class); -+ -+ protected final TableEntry getNextPlain() { -+ //noinspection unchecked -+ return (TableEntry)NEXT_HANDLE.get(this); -+ } ++ /** ++ * Atomically inserts a new mapping with {@code key} mapped to {@code value} if and only if {@code key} is not ++ * currently mapped to some value. ++ * @param key Specified key ++ * @param value Specified value ++ * @throws NullPointerException If value is null ++ * @return Value currently associated with key, or {@code null} if none and {@code value} was associated. ++ */ ++ public V putIfAbsent(final long key, final V value) { ++ Validate.notNull(value, "Value may not be null"); + -+ protected final TableEntry getNextVolatile() { -+ //noinspection unchecked -+ return (TableEntry)NEXT_HANDLE.getVolatile(this); -+ } ++ final int hash = getHash(key); + -+ protected final void setNextPlain(final TableEntry next) { -+ NEXT_HANDLE.set(this, next); -+ } ++ TableEntry[] table = this.table; ++ table_loop: ++ for (;;) { ++ final int index = hash & (table.length - 1); + -+ protected final void setNextRelease(final TableEntry next) { -+ NEXT_HANDLE.setRelease(this, next); -+ } ++ TableEntry node = getAtIndexVolatile(table, index); ++ node_loop: ++ for (;;) { ++ if (node == null) { ++ if (null == (node = compareAndExchangeAtIndexVolatile(table, index, null, new TableEntry<>(key, value)))) { ++ // successfully inserted ++ this.addSize(1L); ++ return null; ++ } // else: node != null, fall through ++ } + -+ protected final void setNextVolatile(final TableEntry next) { -+ NEXT_HANDLE.setVolatile(this, next); -+ } ++ if (node.resize) { ++ // noinspection unchecked ++ table = (TableEntry[])node.getValuePlain(); ++ continue table_loop; ++ } + -+ public TableEntry(final long key, final V value) { -+ this.resize = false; -+ this.key = key; -+ this.setValuePlain(value); -+ } ++ // optimise ifAbsent calls: check if first node is key before attempting lock acquire ++ if (node.key == key) { ++ final V ret = node.getValueVolatile(); ++ if (ret != null) { ++ return ret; ++ } // else: fall back to lock to read the node ++ } + -+ public TableEntry(final long key, final V value, final boolean resize) { -+ this.resize = resize; -+ this.key = key; -+ this.setValuePlain(value); -+ } ++ synchronized (node) { ++ if (node != (node = getAtIndexVolatile(table, index))) { ++ continue node_loop; ++ } ++ // plain reads are fine during synchronised access, as we are the only writer ++ TableEntry prev = null; ++ for (; node != null; prev = node, node = node.getNextPlain()) { ++ if (node.key == key) { ++ return node.getValuePlain(); ++ } ++ } + -+ public long getKey() { -+ return this.key; -+ } ++ // volatile ordering ensured by addSize(), but we need release here ++ // to ensure proper ordering with reads and other writes ++ prev.setNextRelease(new TableEntry<>(key, value)); ++ } + -+ public V getValue() { -+ return this.getValueVolatile(); ++ this.addSize(1L); ++ return null; ++ } + } + } -+} -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..83965350d292ccf42a34520d84dcda3f88146cff ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/map/SWMRHashTable.java -@@ -0,0 +1,1656 @@ -+package ca.spottedleaf.concurrentutil.map; + -+import ca.spottedleaf.concurrentutil.util.CollectionUtil; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.HashUtil; -+import ca.spottedleaf.concurrentutil.util.IntegerUtil; -+import ca.spottedleaf.concurrentutil.util.Validate; -+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; ++ /** ++ * Atomically updates the value associated with {@code key} to {@code value}, or does nothing if {@code key} is not ++ * associated with a value. ++ * @param key Specified key ++ * @param value Specified value ++ * @throws NullPointerException If value is null ++ * @return Old value previously associated with key, or {@code null} if none. ++ */ ++ public V replace(final long key, final V value) { ++ Validate.notNull(value, "Value may not be null"); + -+/** -+ *

    -+ * Note: Not really tested, use at your own risk. -+ *

    -+ * 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. -+ *

    -+ * 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. -+ *

    -+ *

    -+ * Subclasses should override {@link #clone()} to return correct instances of this class. -+ *

    -+ * @param {@inheritDoc} -+ * @param {@inheritDoc} -+ */ -+public class SWMRHashTable implements Map, Iterable> { ++ final int hash = getHash(key); + -+ protected int size; ++ TableEntry[] table = this.table; ++ table_loop: ++ for (;;) { ++ final int index = hash & (table.length - 1); + -+ protected TableEntry[] table; ++ TableEntry node = getAtIndexVolatile(table, index); ++ node_loop: ++ for (;;) { ++ if (node == null) { ++ return null; ++ } + -+ protected final float loadFactor; ++ if (node.resize) { ++ // noinspection unchecked ++ table = (TableEntry[])node.getValuePlain(); ++ continue table_loop; ++ } + -+ 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); ++ synchronized (node) { ++ if (node != (node = getAtIndexVolatile(table, index))) { ++ continue node_loop; ++ } + -+ /* size */ ++ // plain reads are fine during synchronised access, as we are the only writer ++ for (; node != null; node = node.getNextPlain()) { ++ if (node.key == key) { ++ final V ret = node.getValuePlain(); ++ node.setValueVolatile(value); ++ return ret; ++ } ++ } ++ } + -+ protected final int getSizePlain() { -+ return (int)SIZE_HANDLE.get(this); ++ return null; ++ } ++ } + } + -+ protected final int getSizeOpaque() { -+ return (int)SIZE_HANDLE.getOpaque(this); -+ } ++ /** ++ * Atomically updates the value associated with {@code key} to {@code update} if the currently associated ++ * value is reference equal to {@code expect}, otherwise does nothing. ++ * @param key Specified key ++ * @param expect Expected value to check current mapped value with ++ * @param update Update value to replace mapped value with ++ * @throws NullPointerException If value is null ++ * @return If the currently mapped value is not reference equal to {@code expect}, then returns the currently mapped ++ * value. If the key is not mapped to any value, then returns {@code null}. If neither of the two cases are ++ * true, then returns {@code expect}. ++ */ ++ public V replace(final long key, final V expect, final V update) { ++ Validate.notNull(expect, "Expect may not be null"); ++ Validate.notNull(update, "Update may not be null"); + -+ protected final int getSizeAcquire() { -+ return (int)SIZE_HANDLE.getAcquire(this); -+ } ++ final int hash = getHash(key); + -+ protected final void setSizePlain(final int value) { -+ SIZE_HANDLE.set(this, value); -+ } ++ TableEntry[] table = this.table; ++ table_loop: ++ for (;;) { ++ final int index = hash & (table.length - 1); + -+ protected final void setSizeOpaque(final int value) { -+ SIZE_HANDLE.setOpaque(this, value); -+ } ++ TableEntry node = getAtIndexVolatile(table, index); ++ node_loop: ++ for (;;) { ++ if (node == null) { ++ return null; ++ } + -+ protected final void setSizeRelease(final int value) { -+ SIZE_HANDLE.setRelease(this, value); -+ } ++ if (node.resize) { ++ // noinspection unchecked ++ table = (TableEntry[])node.getValuePlain(); ++ continue table_loop; ++ } + -+ /* table */ ++ synchronized (node) { ++ if (node != (node = getAtIndexVolatile(table, index))) { ++ continue node_loop; ++ } + -+ protected final TableEntry[] getTablePlain() { -+ //noinspection unchecked -+ return (TableEntry[])TABLE_HANDLE.get(this); -+ } ++ // plain reads are fine during synchronised access, as we are the only writer ++ for (; node != null; node = node.getNextPlain()) { ++ if (node.key == key) { ++ final V ret = node.getValuePlain(); + -+ protected final TableEntry[] getTableAcquire() { -+ //noinspection unchecked -+ return (TableEntry[])TABLE_HANDLE.getAcquire(this); -+ } ++ if (ret != expect) { ++ return ret; ++ } + -+ protected final void setTablePlain(final TableEntry[] table) { -+ TABLE_HANDLE.set(this, table); -+ } ++ node.setValueVolatile(update); ++ return ret; ++ } ++ } ++ } + -+ protected final void setTableRelease(final TableEntry[] table) { -+ TABLE_HANDLE.setRelease(this, table); ++ return null; ++ } ++ } + } + -+ 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}. ++ * Atomically removes the mapping for the specified key and returns the value it was associated with. If the key ++ * is not mapped to a value, then does nothing and returns {@code null}. ++ * @param key Specified key ++ * @return Old value previously associated with key, or {@code null} if none. + */ -+ public SWMRHashTable() { -+ this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR); -+ } ++ public V remove(final long key) { ++ final int hash = getHash(key); + -+ /** -+ * 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); -+ } ++ TableEntry[] table = this.table; ++ table_loop: ++ for (;;) { ++ final int index = hash & (table.length - 1); + -+ /** -+ * 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); ++ TableEntry node = getAtIndexVolatile(table, index); ++ node_loop: ++ for (;;) { ++ if (node == null) { ++ return null; ++ } + -+ if (loadFactor <= 0.0 || !Float.isFinite(loadFactor)) { -+ throw new IllegalArgumentException("Invalid load factor: " + loadFactor); -+ } ++ if (node.resize) { ++ // noinspection unchecked ++ table = (TableEntry[])node.getValuePlain(); ++ continue table_loop; ++ } + -+ //noinspection unchecked -+ final TableEntry[] table = new TableEntry[tableSize]; -+ this.setTablePlain(table); ++ boolean removed = false; ++ V ret = null; + -+ if (tableSize == MAXIMUM_CAPACITY) { -+ this.threshold = -1; -+ } else { -+ this.threshold = getTargetCapacity(tableSize, loadFactor); -+ } ++ synchronized (node) { ++ if (node != (node = getAtIndexVolatile(table, index))) { ++ continue node_loop; ++ } ++ ++ TableEntry prev = null; ++ ++ // plain reads are fine during synchronised access, as we are the only writer ++ for (; node != null; prev = node, node = node.getNextPlain()) { ++ if (node.key == key) { ++ ret = node.getValuePlain(); ++ removed = true; ++ ++ // volatile ordering ensured by addSize(), but we need release here ++ // to ensure proper ordering with reads and other writes ++ if (prev == null) { ++ setAtIndexRelease(table, index, node.getNextPlain()); ++ } else { ++ prev.setNextRelease(node.getNextPlain()); ++ } + -+ this.loadFactor = loadFactor; -+ } ++ break; ++ } ++ } ++ } + -+ /** -+ * 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 other) { -+ this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, other); -+ } ++ if (removed) { ++ this.subSize(1L); ++ } + -+ /** -+ * 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 other) { -+ this(capacity, DEFAULT_LOAD_FACTOR, other); ++ return ret; ++ } ++ } + } + + /** -+ * 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. ++ * Atomically removes the mapping for the specified key if it is mapped to {@code expect} and returns {@code expect}. If the key ++ * is not mapped to a value, then does nothing and returns {@code null}. If the key is mapped to a value that is not reference ++ * equal to {@code expect}, then returns that value. ++ * @param key Specified key ++ * @param expect Specified expected value ++ * @return The specified expected value if the key was mapped to {@code expect}. If ++ * the key is not mapped to any value, then returns {@code null}. If neither of those cases are true, ++ * then returns the current (non-null) mapped value for key. + */ -+ public SWMRHashTable(final int capacity, final float loadFactor, final Map other) { -+ this(Math.max(Validate.notNull(other, "Null map").size(), capacity), loadFactor); -+ this.putAll(other); -+ } -+ -+ protected static TableEntry getAtIndexOpaque(final TableEntry[] table, final int index) { -+ // noinspection unchecked -+ return (TableEntry)TableEntry.TABLE_ENTRY_ARRAY_HANDLE.getOpaque(table, index); -+ } -+ -+ protected static void setAtIndexRelease(final TableEntry[] table, final int index, final TableEntry value) { -+ TableEntry.TABLE_ENTRY_ARRAY_HANDLE.setRelease(table, index, value); -+ } -+ -+ public final float getLoadFactor() { -+ return this.loadFactor; -+ } ++ public V remove(final long key, final V expect) { ++ final int hash = getHash(key); + -+ 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); -+ } ++ TableEntry[] table = this.table; ++ table_loop: ++ for (;;) { ++ final int index = hash & (table.length - 1); + -+ /** Callers must still use acquire when reading the value of the entry. */ -+ protected final TableEntry getEntryForOpaque(final K key) { -+ final int hash = SWMRHashTable.getHash(key); -+ final TableEntry[] table = this.getTableAcquire(); ++ TableEntry node = getAtIndexVolatile(table, index); ++ node_loop: ++ for (;;) { ++ if (node == null) { ++ return null; ++ } + -+ for (TableEntry curr = getAtIndexOpaque(table, hash & (table.length - 1)); curr != null; curr = curr.getNextOpaque()) { -+ if (hash == curr.hash && (key == curr.key || curr.key.equals(key))) { -+ return curr; -+ } -+ } ++ if (node.resize) { ++ // noinspection unchecked ++ table = (TableEntry[])node.getValuePlain(); ++ continue table_loop; ++ } + -+ return null; -+ } ++ boolean removed = false; ++ V ret = null; + -+ protected final TableEntry getEntryForPlain(final K key) { -+ final int hash = SWMRHashTable.getHash(key); -+ final TableEntry[] table = this.getTablePlain(); ++ synchronized (node) { ++ if (node != (node = getAtIndexVolatile(table, index))) { ++ continue node_loop; ++ } + -+ for (TableEntry curr = table[hash & (table.length - 1)]; curr != null; curr = curr.getNextPlain()) { -+ if (hash == curr.hash && (key == curr.key || curr.key.equals(key))) { -+ return curr; -+ } -+ } ++ TableEntry prev = null; + -+ return null; -+ } ++ // plain reads are fine during synchronised access, as we are the only writer ++ for (; node != null; prev = node, node = node.getNextPlain()) { ++ if (node.key == key) { ++ ret = node.getValuePlain(); ++ if (ret == expect) { ++ removed = true; + -+ /* MT-Safe */ ++ // volatile ordering ensured by addSize(), but we need release here ++ // to ensure proper ordering with reads and other writes ++ if (prev == null) { ++ setAtIndexRelease(table, index, node.getNextPlain()); ++ } else { ++ prev.setNextRelease(node.getNextPlain()); ++ } ++ } ++ break; ++ } ++ } ++ } + -+ /** must be deterministic given a key */ -+ private static int getHash(final Object key) { -+ int hash = key == null ? 0 : key.hashCode(); -+ return HashUtil.mix(hash); -+ } ++ if (removed) { ++ this.subSize(1L); ++ } + -+ // 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 ret; ++ } + } -+ -+ return (int)ret; + } + + /** -+ * {@inheritDoc} ++ * Atomically removes the mapping for the specified key the predicate returns true for its currently mapped value. If the key ++ * is not mapped to a value, then does nothing and returns {@code null}. ++ * ++ *

    ++ * This function is a "functional methods" as defined by {@link ConcurrentLong2ReferenceChainedHashTable}. ++ *

    ++ * ++ * @param key Specified key ++ * @param predicate Specified predicate ++ * @throws NullPointerException If predicate is null ++ * @return The specified expected value if the key was mapped to {@code expect}. If ++ * the key is not mapped to any value, then returns {@code null}. If neither of those cases are true, ++ * then returns the current (non-null) mapped value for key. + */ -+ @Override -+ public boolean equals(final Object obj) { -+ if (this == obj) { -+ return true; -+ } -+ /* Make no attempt to deal with concurrent modifications */ -+ if (!(obj instanceof Map other)) { -+ return false; -+ } ++ public V removeIf(final long key, final Predicate predicate) { ++ Validate.notNull(predicate, "Predicate may not be null"); + -+ if (this.size() != other.size()) { -+ return false; -+ } ++ final int hash = getHash(key); + -+ final TableEntry[] table = this.getTableAcquire(); ++ TableEntry[] table = this.table; ++ table_loop: ++ for (;;) { ++ final int index = hash & (table.length - 1); + -+ for (int i = 0, len = table.length; i < len; ++i) { -+ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { -+ final V value = curr.getValueAcquire(); ++ TableEntry node = getAtIndexVolatile(table, index); ++ node_loop: ++ for (;;) { ++ if (node == null) { ++ return null; ++ } + -+ final Object otherValue = other.get(curr.key); -+ if (otherValue == null || (value != otherValue && value.equals(otherValue))) { -+ return false; ++ if (node.resize) { ++ // noinspection unchecked ++ table = (TableEntry[])node.getValuePlain(); ++ continue table_loop; + } -+ } -+ } + -+ return true; -+ } ++ boolean removed = false; ++ V ret = null; + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public int hashCode() { -+ /* Make no attempt to deal with concurrent modifications */ -+ int hash = 0; -+ final TableEntry[] table = this.getTableAcquire(); ++ synchronized (node) { ++ if (node != (node = getAtIndexVolatile(table, index))) { ++ continue node_loop; ++ } + -+ for (int i = 0, len = table.length; i < len; ++i) { -+ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { -+ hash += curr.hashCode(); -+ } -+ } ++ TableEntry prev = null; + -+ return hash; -+ } ++ // plain reads are fine during synchronised access, as we are the only writer ++ for (; node != null; prev = node, node = node.getNextPlain()) { ++ if (node.key == key) { ++ ret = node.getValuePlain(); ++ if (predicate.test(ret)) { ++ removed = true; + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public String toString() { -+ final StringBuilder builder = new StringBuilder(64); -+ builder.append("SWMRHashTable:{"); ++ // volatile ordering ensured by addSize(), but we need release here ++ // to ensure proper ordering with reads and other writes ++ if (prev == null) { ++ setAtIndexRelease(table, index, node.getNextPlain()); ++ } else { ++ prev.setNextRelease(node.getNextPlain()); ++ } ++ } ++ break; ++ } ++ } ++ } + -+ this.forEach((final K key, final V value) -> { -+ builder.append("{key: \"").append(key).append("\", value: \"").append(value).append("\"}"); -+ }); ++ if (removed) { ++ this.subSize(1L); ++ } + -+ return builder.append('}').toString(); ++ return ret; ++ } ++ } + } + + /** -+ * {@inheritDoc} ++ * See {@link java.util.concurrent.ConcurrentMap#compute(Object, BiFunction)} ++ *

    ++ * This function is a "functional methods" as defined by {@link ConcurrentLong2ReferenceChainedHashTable}. ++ *

    + */ -+ @Override -+ public SWMRHashTable clone() { -+ return new SWMRHashTable<>(this.getTableAcquire().length, this.loadFactor, this); -+ } ++ public V compute(final long key, final BiLong1Function function) { ++ final int hash = getHash(key); + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public Iterator> iterator() { -+ return new EntryIterator<>(this.getTableAcquire(), this); -+ } ++ TableEntry[] table = this.table; ++ table_loop: ++ for (;;) { ++ final int index = hash & (table.length - 1); + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public void forEach(final Consumer> action) { -+ Validate.notNull(action, "Null action"); ++ TableEntry node = getAtIndexVolatile(table, index); ++ node_loop: ++ for (;;) { ++ V ret = null; ++ if (node == null) { ++ final TableEntry insert = new TableEntry<>(key, null); + -+ final TableEntry[] table = this.getTableAcquire(); -+ for (int i = 0, len = table.length; i < len; ++i) { -+ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { -+ action.accept(curr); -+ } -+ } -+ } ++ boolean added = false; + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public void forEach(final BiConsumer action) { -+ Validate.notNull(action, "Null action"); ++ synchronized (insert) { ++ if (null == (node = compareAndExchangeAtIndexVolatile(table, index, null, insert))) { ++ try { ++ ret = function.apply(key, null); ++ } catch (final Throwable throwable) { ++ setAtIndexVolatile(table, index, null); ++ ThrowUtil.throwUnchecked(throwable); ++ // unreachable ++ return null; ++ } + -+ final TableEntry[] table = this.getTableAcquire(); -+ for (int i = 0, len = table.length; i < len; ++i) { -+ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { -+ final V value = curr.getValueAcquire(); ++ if (ret == null) { ++ setAtIndexVolatile(table, index, null); ++ return ret; ++ } else { ++ // volatile ordering ensured by addSize(), but we need release here ++ // to ensure proper ordering with reads and other writes ++ insert.setValueRelease(ret); ++ added = true; ++ } ++ } // else: node != null, fall through ++ } + -+ action.accept(curr.key, value); -+ } -+ } -+ } ++ if (added) { ++ this.addSize(1L); ++ return ret; ++ } ++ } + -+ /** -+ * Provides the specified consumer with all keys contained within this map. -+ * @param action The specified consumer. -+ */ -+ public void forEachKey(final Consumer action) { -+ Validate.notNull(action, "Null action"); ++ if (node.resize) { ++ // noinspection unchecked ++ table = (TableEntry[])node.getValuePlain(); ++ continue table_loop; ++ } + -+ final TableEntry[] table = this.getTableAcquire(); -+ for (int i = 0, len = table.length; i < len; ++i) { -+ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { -+ action.accept(curr.key); -+ } -+ } -+ } ++ boolean removed = false; ++ boolean added = false; + -+ /** -+ * 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 action) { -+ Validate.notNull(action, "Null action"); ++ synchronized (node) { ++ if (node != (node = getAtIndexVolatile(table, index))) { ++ continue node_loop; ++ } ++ // plain reads are fine during synchronised access, as we are the only writer ++ TableEntry prev = null; ++ for (; node != null; prev = node, node = node.getNextPlain()) { ++ if (node.key == key) { ++ final V old = node.getValuePlain(); + -+ final TableEntry[] table = this.getTableAcquire(); -+ for (int i = 0, len = table.length; i < len; ++i) { -+ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { -+ final V value = curr.getValueAcquire(); ++ final V computed = function.apply(key, old); + -+ action.accept(value); -+ } -+ } -+ } ++ if (computed != null) { ++ node.setValueVolatile(computed); ++ return computed; ++ } + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public V get(final Object key) { -+ Validate.notNull(key, "Null key"); ++ // volatile ordering ensured by addSize(), but we need release here ++ // to ensure proper ordering with reads and other writes ++ if (prev == null) { ++ setAtIndexRelease(table, index, node.getNextPlain()); ++ } else { ++ prev.setNextRelease(node.getNextPlain()); ++ } + -+ //noinspection unchecked -+ final TableEntry entry = this.getEntryForOpaque((K)key); -+ return entry == null ? null : entry.getValueAcquire(); -+ } ++ removed = true; ++ break; ++ } ++ } + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public boolean containsKey(final Object key) { -+ Validate.notNull(key, "Null key"); ++ if (!removed) { ++ final V computed = function.apply(key, null); ++ if (computed != null) { ++ // volatile ordering ensured by addSize(), but we need release here ++ // to ensure proper ordering with reads and other writes ++ prev.setNextRelease(new TableEntry<>(key, computed)); ++ ret = computed; ++ added = true; ++ } ++ } ++ } + -+ // note: we need to use getValueAcquire, so that the reads from this map are ordered by acquire semantics -+ return this.get(key) != null; ++ if (removed) { ++ this.subSize(1L); ++ } ++ if (added) { ++ this.addSize(1L); ++ } ++ ++ return ret; ++ } ++ } + } + + /** -+ * 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. ++ * See {@link java.util.concurrent.ConcurrentMap#computeIfAbsent(Object, Function)} ++ *

    ++ * This function is a "functional methods" as defined by {@link ConcurrentLong2ReferenceChainedHashTable}. ++ *

    + */ -+ public boolean contains(final Object key, final Object value) { -+ Validate.notNull(key, "Null key"); ++ public V computeIfAbsent(final long key, final LongFunction function) { ++ final int hash = getHash(key); + -+ //noinspection unchecked -+ final TableEntry entry = this.getEntryForOpaque((K)key); ++ TableEntry[] table = this.table; ++ table_loop: ++ for (;;) { ++ final int index = hash & (table.length - 1); + -+ if (entry == null) { -+ return false; -+ } ++ TableEntry node = getAtIndexVolatile(table, index); ++ node_loop: ++ for (;;) { ++ V ret = null; ++ if (node == null) { ++ final TableEntry insert = new TableEntry<>(key, null); + -+ final V entryVal = entry.getValueAcquire(); -+ return entryVal == value || entryVal.equals(value); -+ } ++ boolean added = false; + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public boolean containsValue(final Object value) { -+ Validate.notNull(value, "Null value"); ++ synchronized (insert) { ++ if (null == (node = compareAndExchangeAtIndexVolatile(table, index, null, insert))) { ++ try { ++ ret = function.apply(key); ++ } catch (final Throwable throwable) { ++ setAtIndexVolatile(table, index, null); ++ ThrowUtil.throwUnchecked(throwable); ++ // unreachable ++ return null; ++ } + -+ final TableEntry[] table = this.getTableAcquire(); -+ for (int i = 0, len = table.length; i < len; ++i) { -+ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { -+ final V currVal = curr.getValueAcquire(); -+ if (currVal == value || currVal.equals(value)) { -+ return true; ++ if (ret == null) { ++ setAtIndexVolatile(table, index, null); ++ return null; ++ } else { ++ // volatile ordering ensured by addSize(), but we need release here ++ // to ensure proper ordering with reads and other writes ++ insert.setValueRelease(ret); ++ added = true; ++ } ++ } // else: node != null, fall through ++ } ++ ++ if (added) { ++ this.addSize(1L); ++ return ret; ++ } ++ } ++ ++ if (node.resize) { ++ // noinspection unchecked ++ table = (TableEntry[])node.getValuePlain(); ++ continue table_loop; + } -+ } -+ } + -+ return false; -+ } ++ // optimise ifAbsent calls: check if first node is key before attempting lock acquire ++ if (node.key == key) { ++ ret = node.getValueVolatile(); ++ if (ret != null) { ++ return ret; ++ } // else: fall back to lock to read the node ++ } + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public V getOrDefault(final Object key, final V defaultValue) { -+ Validate.notNull(key, "Null key"); ++ boolean added = false; + -+ //noinspection unchecked -+ final TableEntry entry = this.getEntryForOpaque((K)key); ++ synchronized (node) { ++ if (node != (node = getAtIndexVolatile(table, index))) { ++ continue node_loop; ++ } ++ // plain reads are fine during synchronised access, as we are the only writer ++ TableEntry prev = null; ++ for (; node != null; prev = node, node = node.getNextPlain()) { ++ if (node.key == key) { ++ ret = node.getValuePlain(); ++ return ret; ++ } ++ } + -+ return entry == null ? defaultValue : entry.getValueAcquire(); -+ } ++ final V computed = function.apply(key); ++ if (computed != null) { ++ // volatile ordering ensured by addSize(), but we need release here ++ // to ensure proper ordering with reads and other writes ++ prev.setNextRelease(new TableEntry<>(key, computed)); ++ ret = computed; ++ added = true; ++ } ++ } + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public int size() { -+ return this.getSizeAcquire(); ++ if (added) { ++ this.addSize(1L); ++ } ++ ++ return ret; ++ } ++ } + } + + /** -+ * {@inheritDoc} ++ * See {@link java.util.concurrent.ConcurrentMap#computeIfPresent(Object, BiFunction)} ++ *

    ++ * This function is a "functional methods" as defined by {@link ConcurrentLong2ReferenceChainedHashTable}. ++ *

    + */ -+ @Override -+ public boolean isEmpty() { -+ return this.getSizeAcquire() == 0; -+ } -+ -+ protected KeySet keyset; -+ protected ValueCollection values; -+ protected EntrySet entrySet; -+ -+ @Override -+ public Set keySet() { -+ return this.keyset == null ? this.keyset = new KeySet<>(this) : this.keyset; -+ } ++ public V computeIfPresent(final long key, final BiLong1Function function) { ++ final int hash = getHash(key); + -+ @Override -+ public Collection values() { -+ return this.values == null ? this.values = new ValueCollection<>(this) : this.values; -+ } ++ TableEntry[] table = this.table; ++ table_loop: ++ for (;;) { ++ final int index = hash & (table.length - 1); + -+ @Override -+ public Set> entrySet() { -+ return this.entrySet == null ? this.entrySet = new EntrySet<>(this) : this.entrySet; -+ } ++ TableEntry node = getAtIndexVolatile(table, index); ++ node_loop: ++ for (;;) { ++ if (node == null) { ++ return null; ++ } + -+ /* Non-MT-Safe */ ++ if (node.resize) { ++ // noinspection unchecked ++ table = (TableEntry[])node.getValuePlain(); ++ continue table_loop; ++ } + -+ protected int threshold; ++ boolean removed = false; + -+ protected final void checkResize(final int minCapacity) { -+ if (minCapacity <= this.threshold || this.threshold < 0) { -+ return; -+ } ++ synchronized (node) { ++ if (node != (node = getAtIndexVolatile(table, index))) { ++ continue node_loop; ++ } ++ // plain reads are fine during synchronised access, as we are the only writer ++ TableEntry prev = null; ++ for (; node != null; prev = node, node = node.getNextPlain()) { ++ if (node.key == key) { ++ final V old = node.getValuePlain(); + -+ final TableEntry[] 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; -+ } ++ final V computed = function.apply(key, old); + -+ //noinspection unchecked -+ final TableEntry[] newTable = new TableEntry[newCapacity]; -+ final int indexMask = newCapacity - 1; ++ if (computed != null) { ++ node.setValueVolatile(computed); ++ return computed; ++ } + -+ for (int i = 0, len = table.length; i < len; ++i) { -+ for (TableEntry entry = table[i]; entry != null; entry = entry.getNextPlain()) { -+ final int hash = entry.hash; -+ final int index = hash & indexMask; ++ // volatile ordering ensured by addSize(), but we need release here ++ // to ensure proper ordering with reads and other writes ++ if (prev == null) { ++ setAtIndexRelease(table, index, node.getNextPlain()); ++ } else { ++ prev.setNextRelease(node.getNextPlain()); ++ } + -+ /* we need to create a new entry since there could be reading threads */ -+ final TableEntry insert = new TableEntry<>(hash, entry.key, entry.getValuePlain()); ++ removed = true; ++ break; ++ } ++ } ++ } + -+ final TableEntry prev = newTable[index]; ++ if (removed) { ++ this.subSize(1L); ++ } + -+ newTable[index] = insert; -+ insert.setNextPlain(prev); ++ return null; + } + } -+ -+ 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); ++ /** ++ * See {@link java.util.concurrent.ConcurrentMap#merge(Object, Object, BiFunction)} ++ *

    ++ * This function is a "functional methods" as defined by {@link ConcurrentLong2ReferenceChainedHashTable}. ++ *

    ++ */ ++ public V merge(final long key, final V def, final BiFunction function) { ++ Validate.notNull(def, "Default value may not be null"); + -+ return newSize; -+ } ++ final int hash = getHash(key); + -+ protected final int removeFromSize(final int num) { -+ final int newSize = this.getSizePlain() - num; ++ TableEntry[] table = this.table; ++ table_loop: ++ for (;;) { ++ final int index = hash & (table.length - 1); + -+ this.setSizeOpaque(newSize); ++ TableEntry node = getAtIndexVolatile(table, index); ++ node_loop: ++ for (;;) { ++ if (node == null) { ++ if (null == (node = compareAndExchangeAtIndexVolatile(table, index, null, new TableEntry<>(key, def)))) { ++ // successfully inserted ++ this.addSize(1L); ++ return def; ++ } // else: node != null, fall through ++ } + -+ return newSize; -+ } ++ if (node.resize) { ++ // noinspection unchecked ++ table = (TableEntry[])node.getValuePlain(); ++ continue table_loop; ++ } + -+ /* Cannot be used to perform downsizing */ -+ protected final int removeFromSizePlain(final int num) { -+ final int newSize = this.getSizePlain() - num; ++ boolean removed = false; ++ boolean added = false; ++ V ret = null; + -+ this.setSizePlain(newSize); ++ synchronized (node) { ++ if (node != (node = getAtIndexVolatile(table, index))) { ++ continue node_loop; ++ } ++ // plain reads are fine during synchronised access, as we are the only writer ++ TableEntry prev = null; ++ for (; node != null; prev = node, node = node.getNextPlain()) { ++ if (node.key == key) { ++ final V old = node.getValuePlain(); + -+ return newSize; -+ } ++ final V computed = function.apply(old, def); + -+ protected final V put(final K key, final V value, final boolean onlyIfAbsent) { -+ final TableEntry[] table = this.getTablePlain(); -+ final int hash = SWMRHashTable.getHash(key); -+ final int index = hash & (table.length - 1); ++ if (computed != null) { ++ node.setValueVolatile(computed); ++ return computed; ++ } + -+ final TableEntry head = table[index]; -+ if (head == null) { -+ final TableEntry insert = new TableEntry<>(hash, key, value); -+ setAtIndexRelease(table, index, insert); -+ this.addToSize(1); -+ return null; -+ } ++ // volatile ordering ensured by addSize(), but we need release here ++ // to ensure proper ordering with reads and other writes ++ if (prev == null) { ++ setAtIndexRelease(table, index, node.getNextPlain()); ++ } else { ++ prev.setNextRelease(node.getNextPlain()); ++ } + -+ for (TableEntry curr = head;;) { -+ if (curr.hash == hash && (key == curr.key || curr.key.equals(key))) { -+ if (onlyIfAbsent) { -+ return curr.getValuePlain(); ++ removed = true; ++ break; ++ } ++ } ++ ++ if (!removed) { ++ // volatile ordering ensured by addSize(), but we need release here ++ // to ensure proper ordering with reads and other writes ++ prev.setNextRelease(new TableEntry<>(key, def)); ++ ret = def; ++ added = true; ++ } + } + -+ final V currVal = curr.getValuePlain(); -+ curr.setValueRelease(value); -+ return currVal; -+ } ++ if (removed) { ++ this.subSize(1L); ++ } ++ if (added) { ++ this.addSize(1L); ++ } + -+ final TableEntry next = curr.getNextPlain(); -+ if (next != null) { -+ curr = next; -+ continue; ++ return ret; + } -+ -+ final TableEntry 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. ++ * Removes at least all entries currently mapped at the beginning of this call. May not remove entries added during ++ * this call. As a result, only if this map is not modified during the call, that all entries will be removed by ++ * the end of the call. ++ * ++ *

    ++ * This function is not atomic. ++ *

    + */ -+ public int removeIf(final BiPredicate predicate) { -+ Validate.notNull(predicate, "Null predicate"); -+ -+ int removed = 0; ++ public void clear() { ++ // it is possible to optimise this to directly interact with the table, ++ // but we do need to be careful when interacting with resized tables, ++ // and the NodeIterator already does this logic ++ final NodeIterator nodeIterator = new NodeIterator<>(this.table); + -+ final TableEntry[] table = this.getTablePlain(); ++ TableEntry node; ++ while ((node = nodeIterator.findNext()) != null) { ++ this.remove(node.key); ++ } ++ } + -+ bin_iteration_loop: -+ for (int i = 0, len = table.length; i < len; ++i) { -+ TableEntry curr = table[i]; -+ if (curr == null) { -+ continue; -+ } ++ /** ++ * Returns an iterator over the entries in this map. The iterator is only guaranteed to see entries that were ++ * added before the beginning of this call, but it may see entries added during. ++ */ ++ public Iterator> entryIterator() { ++ return new EntryIterator<>(this); ++ } + -+ /* Handle bin nodes first */ -+ while (predicate.test(curr.key, curr.getValuePlain())) { -+ ++removed; -+ this.removeFromSizePlain(1); /* required in case predicate throws an exception */ ++ @Override ++ public final Iterator> iterator() { ++ return this.entryIterator(); ++ } + -+ setAtIndexRelease(table, i, curr = curr.getNextPlain()); ++ /** ++ * Returns an iterator over the keys in this map. The iterator is only guaranteed to see keys that were ++ * added before the beginning of this call, but it may see keys added during. ++ */ ++ public PrimitiveIterator.OfLong keyIterator() { ++ return new KeyIterator<>(this); ++ } + -+ if (curr == null) { -+ continue bin_iteration_loop; -+ } -+ } ++ /** ++ * Returns an iterator over the values in this map. The iterator is only guaranteed to see values that were ++ * added before the beginning of this call, but it may see values added during. ++ */ ++ public Iterator valueIterator() { ++ return new ValueIterator<>(this); ++ } + -+ TableEntry prev; ++ protected static final class EntryIterator extends BaseIteratorImpl> { + -+ /* curr at this point is the bin node */ ++ public EntryIterator(final ConcurrentLong2ReferenceChainedHashTable map) { ++ super(map); ++ } + -+ 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 */ ++ @Override ++ public TableEntry next() throws NoSuchElementException { ++ return this.nextNode(); ++ } + -+ prev.setNextRelease(curr = curr.getNextPlain()); -+ } else { -+ prev = curr; -+ curr = curr.getNextPlain(); -+ } ++ @Override ++ public void forEachRemaining(final Consumer> action) { ++ Validate.notNull(action, "Action may not be null"); ++ while (this.hasNext()) { ++ action.accept(this.next()); + } + } -+ -+ 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> predicate) { -+ Validate.notNull(predicate, "Null predicate"); ++ protected static final class KeyIterator extends BaseIteratorImpl implements PrimitiveIterator.OfLong { + -+ int removed = 0; ++ public KeyIterator(final ConcurrentLong2ReferenceChainedHashTable map) { ++ super(map); ++ } + -+ final TableEntry[] table = this.getTablePlain(); ++ @Override ++ public Long next() throws NoSuchElementException { ++ return Long.valueOf(this.nextNode().key); ++ } + -+ bin_iteration_loop: -+ for (int i = 0, len = table.length; i < len; ++i) { -+ TableEntry curr = table[i]; -+ if (curr == null) { -+ continue; -+ } ++ @Override ++ public long nextLong() { ++ return this.nextNode().key; ++ } + -+ /* Handle bin nodes first */ -+ while (predicate.test(curr)) { -+ ++removed; -+ this.removeFromSizePlain(1); /* required in case predicate throws an exception */ ++ @Override ++ public void forEachRemaining(final Consumer action) { ++ Validate.notNull(action, "Action may not be null"); + -+ setAtIndexRelease(table, i, curr = curr.getNextPlain()); ++ if (action instanceof LongConsumer longConsumer) { ++ this.forEachRemaining(longConsumer); ++ return; ++ } + -+ if (curr == null) { -+ continue bin_iteration_loop; -+ } ++ while (this.hasNext()) { ++ action.accept(this.next()); + } ++ } + -+ TableEntry prev; ++ @Override ++ public void forEachRemaining(final LongConsumer action) { ++ Validate.notNull(action, "Action may not be null"); ++ while (this.hasNext()) { ++ action.accept(this.nextLong()); ++ } ++ } ++ } + -+ /* curr at this point is the bin node */ ++ protected static final class ValueIterator extends BaseIteratorImpl { + -+ 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 */ ++ public ValueIterator(final ConcurrentLong2ReferenceChainedHashTable map) { ++ super(map); ++ } + -+ prev.setNextRelease(curr = curr.getNextPlain()); -+ } else { -+ prev = curr; -+ curr = curr.getNextPlain(); -+ } -+ } ++ @Override ++ public V next() throws NoSuchElementException { ++ return this.nextNode().getValueVolatile(); + } + -+ return removed; ++ @Override ++ public void forEachRemaining(final Consumer action) { ++ Validate.notNull(action, "Action may not be null"); ++ while (this.hasNext()) { ++ action.accept(this.next()); ++ } ++ } + } + -+ /** -+ * {@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); -+ } ++ protected static abstract class BaseIteratorImpl extends NodeIterator implements Iterator { + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public V putIfAbsent(final K key, final V value) { -+ Validate.notNull(key, "Null key"); -+ Validate.notNull(value, "Null value"); ++ protected final ConcurrentLong2ReferenceChainedHashTable map; ++ protected TableEntry lastReturned; ++ protected TableEntry nextToReturn; + -+ return this.put(key, value, true); -+ } ++ protected BaseIteratorImpl(final ConcurrentLong2ReferenceChainedHashTable map) { ++ super(map.table); ++ this.map = map; ++ } + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public boolean remove(final Object key, final Object value) { -+ Validate.notNull(key, "Null key"); -+ Validate.notNull(value, "Null value"); ++ @Override ++ public final boolean hasNext() { ++ if (this.nextToReturn != null) { ++ return true; ++ } + -+ final TableEntry[] table = this.getTablePlain(); -+ final int hash = SWMRHashTable.getHash(key); -+ final int index = hash & (table.length - 1); ++ return (this.nextToReturn = this.findNext()) != null; ++ } + -+ final TableEntry head = table[index]; -+ if (head == null) { -+ return false; ++ protected final TableEntry nextNode() throws NoSuchElementException { ++ TableEntry ret = this.nextToReturn; ++ if (ret != null) { ++ this.lastReturned = ret; ++ this.nextToReturn = null; ++ return ret; ++ } ++ ret = this.findNext(); ++ if (ret != null) { ++ this.lastReturned = ret; ++ return ret; ++ } ++ throw new NoSuchElementException(); + } + -+ if (head.hash == hash && (head.key == key || head.key.equals(key))) { -+ final V currVal = head.getValuePlain(); -+ -+ if (currVal != value && !currVal.equals(value)) { -+ return false; ++ @Override ++ public final void remove() { ++ final TableEntry lastReturned = this.lastReturned; ++ if (lastReturned == null) { ++ throw new NoSuchElementException(); + } ++ this.lastReturned = null; ++ this.map.remove(lastReturned.key); ++ } + -+ setAtIndexRelease(table, index, head.getNextPlain()); -+ this.removeFromSize(1); ++ @Override ++ public abstract T next() throws NoSuchElementException; + -+ return true; -+ } ++ // overwritten by subclasses to avoid indirection on hasNext() and next() ++ @Override ++ public abstract void forEachRemaining(final Consumer action); ++ } + -+ for (TableEntry 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(); ++ protected static class NodeIterator { + -+ if (currVal != value && !currVal.equals(value)) { -+ return false; -+ } ++ protected TableEntry[] currentTable; ++ protected ResizeChain resizeChain; ++ protected TableEntry last; ++ protected int nextBin; ++ protected int increment; + -+ prev.setNextRelease(curr.getNextPlain()); -+ this.removeFromSize(1); ++ protected NodeIterator(final TableEntry[] baseTable) { ++ this.currentTable = baseTable; ++ this.increment = 1; ++ } + -+ return true; ++ private TableEntry[] pullResizeChain(final int index) { ++ final ResizeChain resizeChain = this.resizeChain; ++ if (resizeChain == null) { ++ this.currentTable = null; ++ return null; + } -+ } + -+ return false; -+ } ++ final ResizeChain prevChain = resizeChain.prev; ++ this.resizeChain = prevChain; ++ if (prevChain == null) { ++ this.currentTable = null; ++ return null; ++ } + -+ protected final V remove(final Object key, final int hash) { -+ final TableEntry[] table = this.getTablePlain(); -+ final int index = (table.length - 1) & hash; ++ final TableEntry[] newTable = prevChain.table; + -+ final TableEntry head = table[index]; -+ if (head == null) { -+ return null; -+ } ++ // we recover the original index by modding by the new table length, as the increments applied to the index ++ // are a multiple of the new table's length ++ int newIdx = index & (newTable.length - 1); + -+ if (hash == head.hash && (head.key == key || head.key.equals(key))) { -+ setAtIndexRelease(table, index, head.getNextPlain()); -+ this.removeFromSize(1); ++ // the increment is always the previous table's length ++ final ResizeChain nextPrevChain = prevChain.prev; ++ final int increment; ++ if (nextPrevChain == null) { ++ increment = 1; ++ } else { ++ increment = nextPrevChain.table.length; ++ } + -+ return head.getValuePlain(); -+ } ++ // done with the upper table, so we can skip the resize node ++ newIdx += increment; + -+ for (TableEntry 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); ++ this.increment = increment; ++ this.nextBin = newIdx; ++ this.currentTable = newTable; + -+ return curr.getValuePlain(); -+ } ++ return newTable; + } + -+ return null; -+ } ++ private TableEntry[] pushResizeChain(final TableEntry[] table, final TableEntry entry) { ++ final ResizeChain chain = this.resizeChain; + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public V remove(final Object key) { -+ Validate.notNull(key, "Null key"); ++ if (chain == null) { ++ // noinspection unchecked ++ final TableEntry[] nextTable = (TableEntry[])entry.getValuePlain(); + -+ return this.remove(key, SWMRHashTable.getHash(key)); -+ } ++ final ResizeChain oldChain = new ResizeChain<>(table, null, null); ++ final ResizeChain currChain = new ResizeChain<>(nextTable, oldChain, null); ++ oldChain.next = currChain; + -+ /** -+ * {@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"); ++ this.increment = table.length; ++ this.resizeChain = currChain; ++ this.currentTable = nextTable; + -+ final TableEntry entry = this.getEntryForPlain(key); -+ if (entry == null) { -+ return false; -+ } ++ return nextTable; ++ } else { ++ ResizeChain currChain = chain.next; ++ if (currChain == null) { ++ // noinspection unchecked ++ final TableEntry[] ret = (TableEntry[])entry.getValuePlain(); ++ currChain = new ResizeChain<>(ret, chain, null); ++ chain.next = currChain; + -+ final V currValue = entry.getValuePlain(); -+ if (currValue == oldValue || currValue.equals(oldValue)) { -+ entry.setValueRelease(newValue); -+ return true; ++ this.increment = table.length; ++ this.resizeChain = currChain; ++ this.currentTable = ret; ++ ++ return ret; ++ } else { ++ this.increment = table.length; ++ this.resizeChain = currChain; ++ return this.currentTable = currChain.table; ++ } ++ } + } + -+ return false; -+ } ++ protected final TableEntry findNext() { ++ for (;;) { ++ final TableEntry last = this.last; ++ if (last != null) { ++ final TableEntry next = last.getNextVolatile(); ++ if (next != null) { ++ this.last = next; ++ if (next.getValuePlain() == null) { ++ // compute() node not yet available ++ continue; ++ } ++ return next; ++ } ++ } + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public V replace(final K key, final V value) { -+ Validate.notNull(key, "Null key"); -+ Validate.notNull(value, "Null value"); ++ TableEntry[] table = this.currentTable; + -+ final TableEntry entry = this.getEntryForPlain(key); -+ if (entry == null) { -+ return null; -+ } ++ if (table == null) { ++ return null; ++ } + -+ final V prev = entry.getValuePlain(); -+ entry.setValueRelease(value); -+ return prev; -+ } ++ int idx = this.nextBin; ++ int increment = this.increment; ++ for (;;) { ++ if (idx >= table.length) { ++ table = this.pullResizeChain(idx); ++ idx = this.nextBin; ++ increment = this.increment; ++ if (table != null) { ++ continue; ++ } else { ++ this.last = null; ++ return null; ++ } ++ } + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public void replaceAll(final BiFunction function) { -+ Validate.notNull(function, "Null function"); ++ final TableEntry entry = getAtIndexVolatile(table, idx); ++ if (entry == null) { ++ idx += increment; ++ continue; ++ } + -+ final TableEntry[] table = this.getTablePlain(); -+ for (int i = 0, len = table.length; i < len; ++i) { -+ for (TableEntry curr = table[i]; curr != null; curr = curr.getNextPlain()) { -+ final V value = curr.getValuePlain(); ++ if (entry.resize) { ++ // push onto resize chain ++ table = this.pushResizeChain(table, entry); ++ increment = this.increment; ++ continue; ++ } + -+ final V newValue = function.apply(curr.key, value); -+ if (newValue == null) { -+ throw new NullPointerException(); ++ this.last = entry; ++ this.nextBin = idx + increment; ++ if (entry.getValuePlain() != null) { ++ return entry; ++ } else { ++ // compute() node not yet available ++ break; ++ } + } -+ -+ curr.setValueRelease(newValue); + } + } -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public void putAll(final Map 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} -+ *

    -+ * 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. -+ *

    -+ */ -+ @Override -+ public void clear() { -+ Arrays.fill(this.getTablePlain(), null); -+ this.setSizeRelease(0); ++ protected static final class ResizeChain { ++ ++ public final TableEntry[] table; ++ public final ResizeChain prev; ++ public ResizeChain next; ++ ++ public ResizeChain(final TableEntry[] table, final ResizeChain prev, final ResizeChain next) { ++ this.table = table; ++ this.prev = prev; ++ this.next = next; ++ } ++ } + } + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public V compute(final K key, final BiFunction remappingFunction) { -+ Validate.notNull(key, "Null key"); -+ Validate.notNull(remappingFunction, "Null remappingFunction"); ++ public static final class TableEntry { + -+ final int hash = SWMRHashTable.getHash(key); -+ final TableEntry[] table = this.getTablePlain(); -+ final int index = hash & (table.length - 1); ++ private static final VarHandle TABLE_ENTRY_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(TableEntry[].class); + -+ for (TableEntry curr = table[index], prev = null;;prev = curr, curr = curr.getNextPlain()) { -+ if (curr == null) { -+ final V newVal = remappingFunction.apply(key ,null); ++ private final boolean resize; + -+ if (newVal == null) { -+ return null; -+ } ++ private final long key; + -+ final TableEntry insert = new TableEntry<>(hash, key, newVal); -+ if (prev == null) { -+ setAtIndexRelease(table, index, insert); -+ } else { -+ prev.setNextRelease(insert); -+ } ++ private volatile V value; ++ private static final VarHandle VALUE_HANDLE = ConcurrentUtil.getVarHandle(TableEntry.class, "value", Object.class); + -+ this.addToSize(1); ++ private V getValuePlain() { ++ //noinspection unchecked ++ return (V)VALUE_HANDLE.get(this); ++ } + -+ return newVal; -+ } ++ private V getValueAcquire() { ++ //noinspection unchecked ++ return (V)VALUE_HANDLE.getAcquire(this); ++ } + -+ if (curr.hash == hash && (curr.key == key || curr.key.equals(key))) { -+ final V newVal = remappingFunction.apply(key, curr.getValuePlain()); ++ private V getValueVolatile() { ++ //noinspection unchecked ++ return (V)VALUE_HANDLE.getVolatile(this); ++ } + -+ if (newVal != null) { -+ curr.setValueRelease(newVal); -+ return newVal; -+ } ++ private void setValuePlain(final V value) { ++ VALUE_HANDLE.set(this, (Object)value); ++ } + -+ if (prev == null) { -+ setAtIndexRelease(table, index, curr.getNextPlain()); -+ } else { -+ prev.setNextRelease(curr.getNextPlain()); -+ } ++ private void setValueRelease(final V value) { ++ VALUE_HANDLE.setRelease(this, (Object)value); ++ } + -+ this.removeFromSize(1); ++ private void setValueVolatile(final V value) { ++ VALUE_HANDLE.setVolatile(this, (Object)value); ++ } + -+ return null; -+ } ++ private volatile TableEntry next; ++ private static final VarHandle NEXT_HANDLE = ConcurrentUtil.getVarHandle(TableEntry.class, "next", TableEntry.class); ++ ++ private TableEntry getNextPlain() { ++ //noinspection unchecked ++ return (TableEntry)NEXT_HANDLE.get(this); + } -+ } + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public V computeIfPresent(final K key, final BiFunction remappingFunction) { -+ Validate.notNull(key, "Null key"); -+ Validate.notNull(remappingFunction, "Null remappingFunction"); ++ private TableEntry getNextVolatile() { ++ //noinspection unchecked ++ return (TableEntry)NEXT_HANDLE.getVolatile(this); ++ } + -+ final int hash = SWMRHashTable.getHash(key); -+ final TableEntry[] table = this.getTablePlain(); -+ final int index = hash & (table.length - 1); ++ private void setNextPlain(final TableEntry next) { ++ NEXT_HANDLE.set(this, next); ++ } + -+ for (TableEntry curr = table[index], prev = null; curr != null; prev = curr, curr = curr.getNextPlain()) { -+ if (curr.hash != hash || (curr.key != key && !curr.key.equals(key))) { -+ continue; -+ } ++ private void setNextRelease(final TableEntry next) { ++ NEXT_HANDLE.setRelease(this, next); ++ } + -+ final V newVal = remappingFunction.apply(key, curr.getValuePlain()); -+ if (newVal != null) { -+ curr.setValueRelease(newVal); -+ return newVal; -+ } ++ private void setNextVolatile(final TableEntry next) { ++ NEXT_HANDLE.setVolatile(this, next); ++ } + -+ if (prev == null) { -+ setAtIndexRelease(table, index, curr.getNextPlain()); -+ } else { -+ prev.setNextRelease(curr.getNextPlain()); -+ } ++ public TableEntry(final long key, final V value) { ++ this.resize = false; ++ this.key = key; ++ this.setValuePlain(value); ++ } + -+ this.removeFromSize(1); ++ public TableEntry(final long key, final V value, final boolean resize) { ++ this.resize = resize; ++ this.key = key; ++ this.setValuePlain(value); ++ } + -+ return null; ++ public long getKey() { ++ return this.key; + } + -+ return null; ++ public V getValue() { ++ return this.getValueVolatile(); ++ } + } ++} +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..83965350d292ccf42a34520d84dcda3f88146cff +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/map/SWMRHashTable.java +@@ -0,0 +1,1656 @@ ++package ca.spottedleaf.concurrentutil.map; + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public V computeIfAbsent(final K key, final Function mappingFunction) { -+ Validate.notNull(key, "Null key"); -+ Validate.notNull(mappingFunction, "Null mappingFunction"); ++import ca.spottedleaf.concurrentutil.util.CollectionUtil; ++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.HashUtil; ++import ca.spottedleaf.concurrentutil.util.IntegerUtil; ++import ca.spottedleaf.concurrentutil.util.Validate; ++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; + -+ final int hash = SWMRHashTable.getHash(key); -+ final TableEntry[] table = this.getTablePlain(); -+ final int index = hash & (table.length - 1); ++/** ++ *

    ++ * Note: Not really tested, use at your own risk. ++ *

    ++ * 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. ++ *

    ++ * 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. ++ *

    ++ *

    ++ * Subclasses should override {@link #clone()} to return correct instances of this class. ++ *

    ++ * @param {@inheritDoc} ++ * @param {@inheritDoc} ++ */ ++public class SWMRHashTable implements Map, Iterable> { + -+ for (TableEntry 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; -+ } ++ protected int size; + -+ final V newVal = mappingFunction.apply(key); ++ protected TableEntry[] table; + -+ if (newVal == null) { -+ return null; -+ } ++ protected final float loadFactor; + -+ final TableEntry insert = new TableEntry<>(hash, key, newVal); -+ if (prev == null) { -+ setAtIndexRelease(table, index, insert); -+ } else { -+ prev.setNextRelease(insert); -+ } ++ 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); + -+ this.addToSize(1); ++ /* size */ + -+ return newVal; -+ } ++ protected final int getSizePlain() { ++ return (int)SIZE_HANDLE.get(this); + } + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public V merge(final K key, final V value, final BiFunction remappingFunction) { -+ Validate.notNull(key, "Null key"); -+ Validate.notNull(value, "Null value"); -+ Validate.notNull(remappingFunction, "Null remappingFunction"); -+ -+ final int hash = SWMRHashTable.getHash(key); -+ final TableEntry[] table = this.getTablePlain(); -+ final int index = hash & (table.length - 1); -+ -+ for (TableEntry curr = table[index], prev = null;;prev = curr, curr = curr.getNextPlain()) { -+ if (curr == null) { -+ final TableEntry insert = new TableEntry<>(hash, key, value); -+ if (prev == null) { -+ setAtIndexRelease(table, index, insert); -+ } else { -+ prev.setNextRelease(insert); -+ } ++ protected final int getSizeOpaque() { ++ return (int)SIZE_HANDLE.getOpaque(this); ++ } + -+ this.addToSize(1); ++ protected final int getSizeAcquire() { ++ return (int)SIZE_HANDLE.getAcquire(this); ++ } + -+ return value; -+ } ++ protected final void setSizePlain(final int value) { ++ SIZE_HANDLE.set(this, value); ++ } + -+ if (curr.hash == hash && (curr.key == key || curr.key.equals(key))) { -+ final V newVal = remappingFunction.apply(curr.getValuePlain(), value); ++ protected final void setSizeOpaque(final int value) { ++ SIZE_HANDLE.setOpaque(this, value); ++ } + -+ if (newVal != null) { -+ curr.setValueRelease(newVal); -+ return newVal; -+ } ++ protected final void setSizeRelease(final int value) { ++ SIZE_HANDLE.setRelease(this, value); ++ } + -+ if (prev == null) { -+ setAtIndexRelease(table, index, curr.getNextPlain()); -+ } else { -+ prev.setNextRelease(curr.getNextPlain()); -+ } ++ /* table */ + -+ this.removeFromSize(1); ++ protected final TableEntry[] getTablePlain() { ++ //noinspection unchecked ++ return (TableEntry[])TABLE_HANDLE.get(this); ++ } + -+ return null; -+ } -+ } ++ protected final TableEntry[] getTableAcquire() { ++ //noinspection unchecked ++ return (TableEntry[])TABLE_HANDLE.getAcquire(this); + } + -+ protected static final class TableEntry implements Map.Entry { ++ protected final void setTablePlain(final TableEntry[] table) { ++ TABLE_HANDLE.set(this, table); ++ } + -+ protected static final VarHandle TABLE_ENTRY_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(TableEntry[].class); ++ protected final void setTableRelease(final TableEntry[] table) { ++ TABLE_HANDLE.setRelease(this, table); ++ } + -+ protected final int hash; -+ protected final K key; -+ protected V value; ++ 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; + -+ protected TableEntry next; ++ /** ++ * Constructs this map with a capacity of {@code 16} and load factor of {@code 0.75f}. ++ */ ++ public SWMRHashTable() { ++ this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR); ++ } + -+ 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); ++ /** ++ * 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); ++ } + -+ /* value */ ++ /** ++ * 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); + -+ protected final V getValuePlain() { -+ //noinspection unchecked -+ return (V)VALUE_HANDLE.get(this); ++ if (loadFactor <= 0.0 || !Float.isFinite(loadFactor)) { ++ throw new IllegalArgumentException("Invalid load factor: " + loadFactor); + } + -+ protected final V getValueAcquire() { -+ //noinspection unchecked -+ return (V)VALUE_HANDLE.getAcquire(this); -+ } ++ //noinspection unchecked ++ final TableEntry[] table = new TableEntry[tableSize]; ++ this.setTablePlain(table); + -+ protected final void setValueRelease(final V to) { -+ VALUE_HANDLE.setRelease(this, to); ++ if (tableSize == MAXIMUM_CAPACITY) { ++ this.threshold = -1; ++ } else { ++ this.threshold = getTargetCapacity(tableSize, loadFactor); + } + -+ /* next */ ++ this.loadFactor = loadFactor; ++ } + -+ protected final TableEntry getNextPlain() { -+ //noinspection unchecked -+ return (TableEntry)NEXT_HANDLE.get(this); -+ } ++ /** ++ * 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 other) { ++ this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, other); ++ } + -+ protected final TableEntry getNextOpaque() { -+ //noinspection unchecked -+ return (TableEntry)NEXT_HANDLE.getOpaque(this); -+ } ++ /** ++ * 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 other) { ++ this(capacity, DEFAULT_LOAD_FACTOR, other); ++ } + -+ protected final void setNextPlain(final TableEntry next) { -+ NEXT_HANDLE.set(this, next); -+ } ++ /** ++ * 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 other) { ++ this(Math.max(Validate.notNull(other, "Null map").size(), capacity), loadFactor); ++ this.putAll(other); ++ } + -+ protected final void setNextRelease(final TableEntry next) { -+ NEXT_HANDLE.setRelease(this, next); -+ } ++ protected static TableEntry getAtIndexOpaque(final TableEntry[] table, final int index) { ++ // noinspection unchecked ++ return (TableEntry)TableEntry.TABLE_ENTRY_ARRAY_HANDLE.getOpaque(table, index); ++ } + -+ protected TableEntry(final int hash, final K key, final V value) { -+ this.hash = hash; -+ this.key = key; -+ this.value = value; -+ } ++ protected static void setAtIndexRelease(final TableEntry[] table, final int index, final TableEntry value) { ++ TableEntry.TABLE_ENTRY_ARRAY_HANDLE.setRelease(table, index, value); ++ } + -+ @Override -+ public K getKey() { -+ return this.key; -+ } ++ public final float getLoadFactor() { ++ return this.loadFactor; ++ } + -+ @Override -+ public V getValue() { -+ return this.getValueAcquire(); ++ protected static int getCapacityFor(final int capacity) { ++ if (capacity <= 0) { ++ throw new IllegalArgumentException("Invalid capacity: " + capacity); + } -+ -+ @Override -+ public V setValue(final V value) { -+ throw new UnsupportedOperationException(); ++ if (capacity >= MAXIMUM_CAPACITY) { ++ return MAXIMUM_CAPACITY; + } ++ return IntegerUtil.roundCeilLog2(capacity); ++ } + -+ protected static int hash(final Object key, final Object value) { -+ return key.hashCode() ^ (value == null ? 0 : value.hashCode()); -+ } ++ /** Callers must still use acquire when reading the value of the entry. */ ++ protected final TableEntry getEntryForOpaque(final K key) { ++ final int hash = SWMRHashTable.getHash(key); ++ final TableEntry[] table = this.getTableAcquire(); + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public int hashCode() { -+ return hash(this.key, this.getValueAcquire()); ++ for (TableEntry curr = getAtIndexOpaque(table, hash & (table.length - 1)); curr != null; curr = curr.getNextOpaque()) { ++ if (hash == curr.hash && (key == curr.key || curr.key.equals(key))) { ++ return curr; ++ } + } + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public boolean equals(final Object obj) { -+ if (this == obj) { -+ return true; -+ } ++ return null; ++ } + -+ if (!(obj instanceof Map.Entry other)) { -+ return false; -+ } -+ final Object otherKey = other.getKey(); -+ final Object otherValue = other.getValue(); ++ protected final TableEntry getEntryForPlain(final K key) { ++ final int hash = SWMRHashTable.getHash(key); ++ final TableEntry[] table = this.getTablePlain(); + -+ final K thisKey = this.getKey(); -+ final V thisVal = this.getValueAcquire(); -+ return (thisKey == otherKey || thisKey.equals(otherKey)) && -+ (thisVal == otherValue || thisVal.equals(otherValue)); ++ for (TableEntry 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; ++ } + -+ protected static abstract class TableEntryIterator implements Iterator { ++ /* MT-Safe */ + -+ protected final TableEntry[] table; -+ protected final SWMRHashTable map; ++ /** must be deterministic given a key */ ++ private static int getHash(final Object key) { ++ int hash = key == null ? 0 : key.hashCode(); ++ return HashUtil.mix(hash); ++ } + -+ /* bin which our current element resides on */ -+ protected int tableIndex; ++ // 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; ++ } + -+ protected TableEntry currEntry; /* curr entry, null if no more to iterate or if curr was removed or if we've just init'd */ -+ protected TableEntry nextEntry; /* may not be on the same bin as currEntry */ ++ return (int)ret; ++ } + -+ protected TableEntryIterator(final TableEntry[] table, final SWMRHashTable map) { -+ this.table = table; -+ this.map = map; -+ int tableIndex = 0; -+ for (int len = table.length; tableIndex < len; ++tableIndex) { -+ final TableEntry entry = getAtIndexOpaque(table, tableIndex); -+ if (entry != null) { -+ this.nextEntry = entry; -+ this.tableIndex = tableIndex + 1; -+ return; -+ } -+ } -+ this.tableIndex = tableIndex; ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public boolean equals(final Object obj) { ++ if (this == obj) { ++ return true; + } -+ -+ @Override -+ public boolean hasNext() { -+ return this.nextEntry != null; ++ /* Make no attempt to deal with concurrent modifications */ ++ if (!(obj instanceof Map other)) { ++ return false; + } + -+ protected final TableEntry advanceEntry() { -+ final TableEntry[] table = this.table; -+ final int tableLength = table.length; -+ int tableIndex = this.tableIndex; -+ final TableEntry curr = this.nextEntry; -+ if (curr == null) { -+ return null; -+ } -+ -+ this.currEntry = curr; -+ -+ // set up nextEntry ++ if (this.size() != other.size()) { ++ return false; ++ } + -+ // find next in chain -+ TableEntry next = curr.getNextOpaque(); ++ final TableEntry[] table = this.getTableAcquire(); + -+ if (next != null) { -+ this.nextEntry = next; -+ return curr; -+ } ++ for (int i = 0, len = table.length; i < len; ++i) { ++ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { ++ final V value = curr.getValueAcquire(); + -+ // nothing in chain, so find next available bin -+ for (;tableIndex < tableLength; ++tableIndex) { -+ next = getAtIndexOpaque(table, tableIndex); -+ if (next != null) { -+ this.nextEntry = next; -+ this.tableIndex = tableIndex + 1; -+ return curr; ++ final Object otherValue = other.get(curr.key); ++ if (otherValue == null || (value != otherValue && value.equals(otherValue))) { ++ return false; + } + } -+ -+ this.nextEntry = null; -+ this.tableIndex = tableIndex; -+ return curr; + } + -+ @Override -+ public void remove() { -+ final TableEntry curr = this.currEntry; -+ if (curr == null) { -+ throw new IllegalStateException(); -+ } ++ return true; ++ } + -+ this.map.remove(curr.key, curr.hash); ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public int hashCode() { ++ /* Make no attempt to deal with concurrent modifications */ ++ int hash = 0; ++ final TableEntry[] table = this.getTableAcquire(); + -+ this.currEntry = null; ++ for (int i = 0, len = table.length; i < len; ++i) { ++ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { ++ hash += curr.hashCode(); ++ } + } ++ ++ return hash; + } + -+ protected static final class ValueIterator extends TableEntryIterator { ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public String toString() { ++ final StringBuilder builder = new StringBuilder(64); ++ builder.append("SWMRHashTable:{"); + -+ protected ValueIterator(final TableEntry[] table, final SWMRHashTable map) { -+ super(table, map); -+ } ++ this.forEach((final K key, final V value) -> { ++ builder.append("{key: \"").append(key).append("\", value: \"").append(value).append("\"}"); ++ }); + -+ @Override -+ public V next() { -+ final TableEntry entry = this.advanceEntry(); ++ return builder.append('}').toString(); ++ } + -+ if (entry == null) { -+ throw new NoSuchElementException(); -+ } ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public SWMRHashTable clone() { ++ return new SWMRHashTable<>(this.getTableAcquire().length, this.loadFactor, this); ++ } + -+ return entry.getValueAcquire(); -+ } ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public Iterator> iterator() { ++ return new EntryIterator<>(this.getTableAcquire(), this); + } + -+ protected static final class KeyIterator extends TableEntryIterator { ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public void forEach(final Consumer> action) { ++ Validate.notNull(action, "Null action"); + -+ protected KeyIterator(final TableEntry[] table, final SWMRHashTable map) { -+ super(table, map); ++ final TableEntry[] table = this.getTableAcquire(); ++ for (int i = 0, len = table.length; i < len; ++i) { ++ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { ++ action.accept(curr); ++ } + } ++ } + -+ @Override -+ public K next() { -+ final TableEntry curr = this.advanceEntry(); ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public void forEach(final BiConsumer action) { ++ Validate.notNull(action, "Null action"); + -+ if (curr == null) { -+ throw new NoSuchElementException(); -+ } ++ final TableEntry[] table = this.getTableAcquire(); ++ for (int i = 0, len = table.length; i < len; ++i) { ++ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { ++ final V value = curr.getValueAcquire(); + -+ return curr.key; ++ action.accept(curr.key, value); ++ } + } + } + -+ protected static final class EntryIterator extends TableEntryIterator> { ++ /** ++ * Provides the specified consumer with all keys contained within this map. ++ * @param action The specified consumer. ++ */ ++ public void forEachKey(final Consumer action) { ++ Validate.notNull(action, "Null action"); + -+ protected EntryIterator(final TableEntry[] table, final SWMRHashTable map) { -+ super(table, map); ++ final TableEntry[] table = this.getTableAcquire(); ++ for (int i = 0, len = table.length; i < len; ++i) { ++ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { ++ action.accept(curr.key); ++ } + } ++ } + -+ @Override -+ public Map.Entry next() { -+ final TableEntry curr = this.advanceEntry(); ++ /** ++ * 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 action) { ++ Validate.notNull(action, "Null action"); + -+ if (curr == null) { -+ throw new NoSuchElementException(); -+ } ++ final TableEntry[] table = this.getTableAcquire(); ++ for (int i = 0, len = table.length; i < len; ++i) { ++ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { ++ final V value = curr.getValueAcquire(); + -+ return curr; ++ action.accept(value); ++ } + } + } + -+ protected static abstract class ViewCollection implements Collection { ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public V get(final Object key) { ++ Validate.notNull(key, "Null key"); + -+ protected final SWMRHashTable map; ++ //noinspection unchecked ++ final TableEntry entry = this.getEntryForOpaque((K)key); ++ return entry == null ? null : entry.getValueAcquire(); ++ } + -+ protected ViewCollection(final SWMRHashTable map) { -+ this.map = map; -+ } ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public boolean containsKey(final Object key) { ++ Validate.notNull(key, "Null key"); + -+ @Override -+ public boolean add(final T element) { -+ throw new UnsupportedOperationException(); -+ } ++ // note: we need to use getValueAcquire, so that the reads from this map are ordered by acquire semantics ++ return this.get(key) != null; ++ } + -+ @Override -+ public boolean addAll(final Collection collections) { -+ throw new UnsupportedOperationException(); -+ } ++ /** ++ * 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"); + -+ @Override -+ public boolean removeAll(final Collection collection) { -+ Validate.notNull(collection, "Null collection"); ++ //noinspection unchecked ++ final TableEntry entry = this.getEntryForOpaque((K)key); + -+ boolean modified = false; -+ for (final Object element : collection) { -+ modified |= this.remove(element); -+ } -+ return modified; ++ if (entry == null) { ++ return false; + } + -+ @Override -+ public int size() { -+ return this.map.size(); -+ } ++ final V entryVal = entry.getValueAcquire(); ++ return entryVal == value || entryVal.equals(value); ++ } + -+ @Override -+ public boolean isEmpty() { -+ return this.size() == 0; -+ } ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public boolean containsValue(final Object value) { ++ Validate.notNull(value, "Null value"); + -+ @Override -+ public void clear() { -+ this.map.clear(); ++ final TableEntry[] table = this.getTableAcquire(); ++ for (int i = 0, len = table.length; i < len; ++i) { ++ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { ++ final V currVal = curr.getValueAcquire(); ++ if (currVal == value || currVal.equals(value)) { ++ return true; ++ } ++ } + } + -+ @Override -+ public boolean containsAll(final Collection collection) { -+ Validate.notNull(collection, "Null collection"); ++ return false; ++ } + -+ for (final Object element : collection) { -+ if (!this.contains(element)) { -+ return false; -+ } -+ } ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public V getOrDefault(final Object key, final V defaultValue) { ++ Validate.notNull(key, "Null key"); + -+ return true; -+ } ++ //noinspection unchecked ++ final TableEntry entry = this.getEntryForOpaque((K)key); ++ ++ return entry == null ? defaultValue : entry.getValueAcquire(); ++ } + -+ @Override -+ public Object[] toArray() { -+ final List list = new ArrayList<>(this.size()); ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public int size() { ++ return this.getSizeAcquire(); ++ } + -+ this.forEach(list::add); ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public boolean isEmpty() { ++ return this.getSizeAcquire() == 0; ++ } + -+ return list.toArray(); -+ } ++ protected KeySet keyset; ++ protected ValueCollection values; ++ protected EntrySet entrySet; + -+ @Override -+ public E[] toArray(final E[] array) { -+ final List list = new ArrayList<>(this.size()); ++ @Override ++ public Set keySet() { ++ return this.keyset == null ? this.keyset = new KeySet<>(this) : this.keyset; ++ } + -+ this.forEach(list::add); ++ @Override ++ public Collection values() { ++ return this.values == null ? this.values = new ValueCollection<>(this) : this.values; ++ } + -+ return list.toArray(array); -+ } ++ @Override ++ public Set> entrySet() { ++ return this.entrySet == null ? this.entrySet = new EntrySet<>(this) : this.entrySet; ++ } + -+ @Override -+ public E[] toArray(final IntFunction generator) { -+ final List list = new ArrayList<>(this.size()); ++ /* Non-MT-Safe */ + -+ this.forEach(list::add); ++ protected int threshold; + -+ return list.toArray(generator); ++ protected final void checkResize(final int minCapacity) { ++ if (minCapacity <= this.threshold || this.threshold < 0) { ++ return; + } + -+ @Override -+ public int hashCode() { -+ int hash = 0; -+ for (final T element : this) { -+ hash += element == null ? 0 : element.hashCode(); -+ } -+ return hash; ++ final TableEntry[] table = this.getTablePlain(); ++ int newCapacity = minCapacity >= MAXIMUM_CAPACITY ? MAXIMUM_CAPACITY : IntegerUtil.roundCeilLog2(minCapacity); ++ if (newCapacity < 0) { ++ newCapacity = MAXIMUM_CAPACITY; + } -+ -+ @Override -+ public Spliterator spliterator() { // TODO implement -+ return Spliterators.spliterator(this, Spliterator.NONNULL); ++ if (newCapacity <= table.length) { ++ if (newCapacity == MAXIMUM_CAPACITY) { ++ return; ++ } ++ newCapacity = table.length << 1; + } -+ } + -+ protected static abstract class ViewSet extends ViewCollection implements Set { ++ //noinspection unchecked ++ final TableEntry[] newTable = new TableEntry[newCapacity]; ++ final int indexMask = newCapacity - 1; + -+ protected ViewSet(final SWMRHashTable map) { -+ super(map); -+ } ++ for (int i = 0, len = table.length; i < len; ++i) { ++ for (TableEntry entry = table[i]; entry != null; entry = entry.getNextPlain()) { ++ final int hash = entry.hash; ++ final int index = hash & indexMask; + -+ @Override -+ public boolean equals(final Object obj) { -+ if (this == obj) { -+ return true; -+ } ++ /* we need to create a new entry since there could be reading threads */ ++ final TableEntry insert = new TableEntry<>(hash, entry.key, entry.getValuePlain()); + -+ if (!(obj instanceof Set)) { -+ return false; -+ } ++ final TableEntry prev = newTable[index]; + -+ final Set other = (Set)obj; -+ if (other.size() != this.size()) { -+ return false; ++ newTable[index] = insert; ++ insert.setNextPlain(prev); + } ++ } + -+ return this.containsAll(other); ++ 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 static final class EntrySet extends ViewSet> implements Set> { ++ protected final int addToSize(final int num) { ++ final int newSize = this.getSizePlain() + num; + -+ protected EntrySet(final SWMRHashTable map) { -+ super(map); -+ } ++ this.setSizeOpaque(newSize); ++ this.checkResize(newSize); + -+ @Override -+ public boolean remove(final Object object) { -+ if (!(object instanceof Map.Entry entry)) { -+ return false; -+ } ++ return newSize; ++ } + -+ final Object key; -+ final Object value; ++ protected final int removeFromSize(final int num) { ++ final int newSize = this.getSizePlain() - num; + -+ try { -+ key = entry.getKey(); -+ value = entry.getValue(); -+ } catch (final IllegalStateException ex) { -+ return false; -+ } ++ this.setSizeOpaque(newSize); + -+ return this.map.remove(key, value); -+ } ++ return newSize; ++ } + -+ @Override -+ public boolean removeIf(final Predicate> filter) { -+ Validate.notNull(filter, "Null filter"); ++ /* Cannot be used to perform downsizing */ ++ protected final int removeFromSizePlain(final int num) { ++ final int newSize = this.getSizePlain() - num; + -+ return this.map.removeEntryIf(filter) != 0; -+ } ++ this.setSizePlain(newSize); + -+ @Override -+ public boolean retainAll(final Collection collection) { -+ Validate.notNull(collection, "Null collection"); ++ return newSize; ++ } + -+ return this.map.removeEntryIf((final Map.Entry entry) -> { -+ return !collection.contains(entry); -+ }) != 0; -+ } ++ protected final V put(final K key, final V value, final boolean onlyIfAbsent) { ++ final TableEntry[] table = this.getTablePlain(); ++ final int hash = SWMRHashTable.getHash(key); ++ final int index = hash & (table.length - 1); + -+ @Override -+ public Iterator> iterator() { -+ return new EntryIterator<>(this.map.getTableAcquire(), this.map); ++ final TableEntry head = table[index]; ++ if (head == null) { ++ final TableEntry insert = new TableEntry<>(hash, key, value); ++ setAtIndexRelease(table, index, insert); ++ this.addToSize(1); ++ return null; + } + -+ @Override -+ public void forEach(final Consumer> action) { -+ this.map.forEach(action); -+ } ++ for (TableEntry curr = head;;) { ++ if (curr.hash == hash && (key == curr.key || curr.key.equals(key))) { ++ if (onlyIfAbsent) { ++ return curr.getValuePlain(); ++ } + -+ @Override -+ public boolean contains(final Object object) { -+ if (!(object instanceof Map.Entry entry)) { -+ return false; ++ final V currVal = curr.getValuePlain(); ++ curr.setValueRelease(value); ++ return currVal; + } + -+ final Object key; -+ final Object value; -+ -+ try { -+ key = entry.getKey(); -+ value = entry.getValue(); -+ } catch (final IllegalStateException ex) { -+ return false; ++ final TableEntry next = curr.getNextPlain(); ++ if (next != null) { ++ curr = next; ++ continue; + } + -+ return this.map.contains(key, value); -+ } ++ final TableEntry insert = new TableEntry<>(hash, key, value); + -+ @Override -+ public String toString() { -+ return CollectionUtil.toString(this, "SWMRHashTableEntrySet"); ++ curr.setNextRelease(insert); ++ this.addToSize(1); ++ return null; + } + } + -+ protected static final class KeySet extends ViewSet { -+ -+ protected KeySet(final SWMRHashTable map) { -+ super(map); -+ } -+ -+ @Override -+ public Iterator iterator() { -+ return new KeyIterator<>(this.map.getTableAcquire(), this.map); -+ } ++ /** ++ * 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 predicate) { ++ Validate.notNull(predicate, "Null predicate"); + -+ @Override -+ public void forEach(final Consumer action) { -+ Validate.notNull(action, "Null action"); ++ int removed = 0; + -+ this.map.forEachKey(action); -+ } ++ final TableEntry[] table = this.getTablePlain(); + -+ @Override -+ public boolean contains(final Object key) { -+ Validate.notNull(key, "Null key"); ++ bin_iteration_loop: ++ for (int i = 0, len = table.length; i < len; ++i) { ++ TableEntry curr = table[i]; ++ if (curr == null) { ++ continue; ++ } + -+ return this.map.containsKey(key); -+ } ++ /* Handle bin nodes first */ ++ while (predicate.test(curr.key, curr.getValuePlain())) { ++ ++removed; ++ this.removeFromSizePlain(1); /* required in case predicate throws an exception */ + -+ @Override -+ public boolean remove(final Object key) { -+ Validate.notNull(key, "Null key"); ++ setAtIndexRelease(table, i, curr = curr.getNextPlain()); + -+ return this.map.remove(key) != null; -+ } ++ if (curr == null) { ++ continue bin_iteration_loop; ++ } ++ } + -+ @Override -+ public boolean retainAll(final Collection collection) { -+ Validate.notNull(collection, "Null collection"); ++ TableEntry prev; + -+ return this.map.removeIf((final K key, final V value) -> { -+ return !collection.contains(key); -+ }) != 0; -+ } ++ /* curr at this point is the bin node */ + -+ @Override -+ public boolean removeIf(final Predicate filter) { -+ Validate.notNull(filter, "Null filter"); ++ 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 */ + -+ return this.map.removeIf((final K key, final V value) -> { -+ return filter.test(key); -+ }) != 0; ++ prev.setNextRelease(curr = curr.getNextPlain()); ++ } else { ++ prev = curr; ++ curr = curr.getNextPlain(); ++ } ++ } + } + -+ @Override -+ public String toString() { -+ return CollectionUtil.toString(this, "SWMRHashTableKeySet"); -+ } ++ return removed; + } + -+ protected static final class ValueCollection extends ViewSet implements Collection { -+ -+ protected ValueCollection(final SWMRHashTable map) { -+ super(map); -+ } -+ -+ @Override -+ public Iterator iterator() { -+ return new ValueIterator<>(this.map.getTableAcquire(), this.map); -+ } ++ /** ++ * 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> predicate) { ++ Validate.notNull(predicate, "Null predicate"); + -+ @Override -+ public void forEach(final Consumer action) { -+ Validate.notNull(action, "Null action"); ++ int removed = 0; + -+ this.map.forEachValue(action); -+ } ++ final TableEntry[] table = this.getTablePlain(); + -+ @Override -+ public boolean contains(final Object object) { -+ Validate.notNull(object, "Null object"); ++ bin_iteration_loop: ++ for (int i = 0, len = table.length; i < len; ++i) { ++ TableEntry curr = table[i]; ++ if (curr == null) { ++ continue; ++ } + -+ return this.map.containsValue(object); -+ } ++ /* Handle bin nodes first */ ++ while (predicate.test(curr)) { ++ ++removed; ++ this.removeFromSizePlain(1); /* required in case predicate throws an exception */ + -+ @Override -+ public boolean remove(final Object object) { -+ Validate.notNull(object, "Null object"); ++ setAtIndexRelease(table, i, curr = curr.getNextPlain()); + -+ final Iterator itr = this.iterator(); -+ while (itr.hasNext()) { -+ final V val = itr.next(); -+ if (val == object || val.equals(object)) { -+ itr.remove(); -+ return true; ++ if (curr == null) { ++ continue bin_iteration_loop; + } + } + -+ return false; -+ } ++ TableEntry prev; + -+ @Override -+ public boolean removeIf(final Predicate filter) { -+ Validate.notNull(filter, "Null filter"); ++ /* curr at this point is the bin node */ + -+ return this.map.removeIf((final K key, final V value) -> { -+ return filter.test(value); -+ }) != 0; ++ 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(); ++ } ++ } + } + -+ @Override -+ public boolean retainAll(final Collection collection) { -+ Validate.notNull(collection, "Null collection"); ++ return removed; ++ } + -+ return this.map.removeIf((final K key, final V value) -> { -+ return !collection.contains(value); -+ }) != 0; -+ } ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public V put(final K key, final V value) { ++ Validate.notNull(key, "Null key"); ++ Validate.notNull(value, "Null value"); + -+ @Override -+ public String toString() { -+ return CollectionUtil.toString(this, "SWMRHashTableValues"); -+ } ++ return this.put(key, value, false); + } -+} -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..bb301a9f4e3ac919552eef68afc73569d50674db ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/map/SWMRLong2ObjectHashTable.java -@@ -0,0 +1,674 @@ -+package ca.spottedleaf.concurrentutil.map; + -+import ca.spottedleaf.concurrentutil.function.BiLongObjectConsumer; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.HashUtil; -+import ca.spottedleaf.concurrentutil.util.IntegerUtil; -+import ca.spottedleaf.concurrentutil.util.Validate; -+import java.lang.invoke.VarHandle; -+import java.util.Arrays; -+import java.util.function.Consumer; -+import java.util.function.LongConsumer; ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public V putIfAbsent(final K key, final V value) { ++ Validate.notNull(key, "Null key"); ++ Validate.notNull(value, "Null value"); + -+// trimmed down version of SWMRHashTable -+public class SWMRLong2ObjectHashTable { ++ return this.put(key, value, true); ++ } + -+ protected int size; ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public boolean remove(final Object key, final Object value) { ++ Validate.notNull(key, "Null key"); ++ Validate.notNull(value, "Null value"); + -+ protected TableEntry[] table; ++ final TableEntry[] table = this.getTablePlain(); ++ final int hash = SWMRHashTable.getHash(key); ++ final int index = hash & (table.length - 1); + -+ protected final float loadFactor; ++ final TableEntry head = table[index]; ++ if (head == null) { ++ return false; ++ } + -+ 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); ++ if (head.hash == hash && (head.key == key || head.key.equals(key))) { ++ final V currVal = head.getValuePlain(); + -+ /* size */ ++ if (currVal != value && !currVal.equals(value)) { ++ return false; ++ } + -+ protected final int getSizePlain() { -+ return (int)SIZE_HANDLE.get(this); -+ } ++ setAtIndexRelease(table, index, head.getNextPlain()); ++ this.removeFromSize(1); + -+ protected final int getSizeOpaque() { -+ return (int)SIZE_HANDLE.getOpaque(this); -+ } ++ return true; ++ } + -+ protected final int getSizeAcquire() { -+ return (int)SIZE_HANDLE.getAcquire(this); -+ } ++ for (TableEntry 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(); + -+ protected final void setSizePlain(final int value) { -+ SIZE_HANDLE.set(this, value); -+ } ++ if (currVal != value && !currVal.equals(value)) { ++ return false; ++ } + -+ protected final void setSizeOpaque(final int value) { -+ SIZE_HANDLE.setOpaque(this, value); -+ } ++ prev.setNextRelease(curr.getNextPlain()); ++ this.removeFromSize(1); + -+ protected final void setSizeRelease(final int value) { -+ SIZE_HANDLE.setRelease(this, value); ++ return true; ++ } ++ } ++ ++ return false; + } + -+ /* table */ ++ protected final V remove(final Object key, final int hash) { ++ final TableEntry[] table = this.getTablePlain(); ++ final int index = (table.length - 1) & hash; + -+ protected final TableEntry[] getTablePlain() { -+ //noinspection unchecked -+ return (TableEntry[])TABLE_HANDLE.get(this); -+ } ++ final TableEntry head = table[index]; ++ if (head == null) { ++ return null; ++ } + -+ protected final TableEntry[] getTableAcquire() { -+ //noinspection unchecked -+ return (TableEntry[])TABLE_HANDLE.getAcquire(this); -+ } ++ if (hash == head.hash && (head.key == key || head.key.equals(key))) { ++ setAtIndexRelease(table, index, head.getNextPlain()); ++ this.removeFromSize(1); + -+ protected final void setTablePlain(final TableEntry[] table) { -+ TABLE_HANDLE.set(this, table); -+ } ++ return head.getValuePlain(); ++ } + -+ protected final void setTableRelease(final TableEntry[] table) { -+ TABLE_HANDLE.setRelease(this, table); -+ } ++ for (TableEntry 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); + -+ 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; ++ return curr.getValuePlain(); ++ } ++ } + -+ /** -+ * Constructs this map with a capacity of {@code 16} and load factor of {@code 0.75f}. -+ */ -+ public SWMRLong2ObjectHashTable() { -+ this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR); ++ return null; + } + + /** -+ * Constructs this map with the specified capacity and load factor of {@code 0.75f}. -+ * @param capacity specified initial capacity, > 0 ++ * {@inheritDoc} + */ -+ public SWMRLong2ObjectHashTable(final int capacity) { -+ this(capacity, DEFAULT_LOAD_FACTOR); ++ @Override ++ public V remove(final Object key) { ++ Validate.notNull(key, "Null key"); ++ ++ return this.remove(key, SWMRHashTable.getHash(key)); + } + + /** -+ * Constructs this map with the specified capacity and load factor. -+ * @param capacity specified capacity, > 0 -+ * @param loadFactor specified load factor, > 0 && finite ++ * {@inheritDoc} + */ -+ public SWMRLong2ObjectHashTable(final int capacity, final float loadFactor) { -+ final int tableSize = getCapacityFor(capacity); ++ @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"); + -+ if (loadFactor <= 0.0 || !Float.isFinite(loadFactor)) { -+ throw new IllegalArgumentException("Invalid load factor: " + loadFactor); ++ final TableEntry entry = this.getEntryForPlain(key); ++ if (entry == null) { ++ return false; + } + -+ //noinspection unchecked -+ final TableEntry[] table = new TableEntry[tableSize]; -+ this.setTablePlain(table); -+ -+ if (tableSize == MAXIMUM_CAPACITY) { -+ this.threshold = -1; -+ } else { -+ this.threshold = getTargetCapacity(tableSize, loadFactor); ++ final V currValue = entry.getValuePlain(); ++ if (currValue == oldValue || currValue.equals(oldValue)) { ++ entry.setValueRelease(newValue); ++ return true; + } + -+ this.loadFactor = loadFactor; ++ return false; + } + + /** -+ * 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. ++ * {@inheritDoc} + */ -+ public SWMRLong2ObjectHashTable(final SWMRLong2ObjectHashTable other) { -+ this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, other); ++ @Override ++ public V replace(final K key, final V value) { ++ Validate.notNull(key, "Null key"); ++ Validate.notNull(value, "Null value"); ++ ++ final TableEntry entry = this.getEntryForPlain(key); ++ if (entry == null) { ++ return null; ++ } ++ ++ final V prev = entry.getValuePlain(); ++ entry.setValueRelease(value); ++ return prev; + } + + /** -+ * 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. ++ * {@inheritDoc} + */ -+ public SWMRLong2ObjectHashTable(final int capacity, final SWMRLong2ObjectHashTable other) { -+ this(capacity, DEFAULT_LOAD_FACTOR, other); ++ @Override ++ public void replaceAll(final BiFunction function) { ++ Validate.notNull(function, "Null function"); ++ ++ final TableEntry[] table = this.getTablePlain(); ++ for (int i = 0, len = table.length; i < len; ++i) { ++ for (TableEntry 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); ++ } ++ } + } + + /** -+ * 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. ++ * {@inheritDoc} + */ -+ public SWMRLong2ObjectHashTable(final int capacity, final float loadFactor, final SWMRLong2ObjectHashTable other) { -+ this(Math.max(Validate.notNull(other, "Null map").size(), capacity), loadFactor); -+ this.putAll(other); -+ } ++ @Override ++ public void putAll(final Map map) { ++ Validate.notNull(map, "Null map"); + -+ protected static TableEntry getAtIndexOpaque(final TableEntry[] table, final int index) { -+ // noinspection unchecked -+ return (TableEntry)TableEntry.TABLE_ENTRY_ARRAY_HANDLE.getOpaque(table, index); ++ final int size = map.size(); ++ this.checkResize(Math.max(this.getSizePlain() + size/2, size)); /* preemptively resize */ ++ map.forEach(this::put); + } + -+ protected static void setAtIndexRelease(final TableEntry[] table, final int index, final TableEntry value) { -+ TableEntry.TABLE_ENTRY_ARRAY_HANDLE.setRelease(table, index, value); ++ /** ++ * {@inheritDoc} ++ *

    ++ * 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. ++ *

    ++ */ ++ @Override ++ public void clear() { ++ Arrays.fill(this.getTablePlain(), null); ++ this.setSizeRelease(0); + } + -+ public final float getLoadFactor() { -+ return this.loadFactor; -+ } ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public V compute(final K key, final BiFunction remappingFunction) { ++ Validate.notNull(key, "Null key"); ++ Validate.notNull(remappingFunction, "Null remappingFunction"); + -+ 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); -+ } ++ final int hash = SWMRHashTable.getHash(key); ++ final TableEntry[] table = this.getTablePlain(); ++ final int index = hash & (table.length - 1); + -+ /** Callers must still use acquire when reading the value of the entry. */ -+ protected final TableEntry getEntryForOpaque(final long key) { -+ final int hash = SWMRLong2ObjectHashTable.getHash(key); -+ final TableEntry[] table = this.getTableAcquire(); ++ for (TableEntry curr = table[index], prev = null;;prev = curr, curr = curr.getNextPlain()) { ++ if (curr == null) { ++ final V newVal = remappingFunction.apply(key ,null); + -+ for (TableEntry curr = getAtIndexOpaque(table, hash & (table.length - 1)); curr != null; curr = curr.getNextOpaque()) { -+ if (key == curr.key) { -+ return curr; -+ } -+ } ++ if (newVal == null) { ++ return null; ++ } + -+ return null; -+ } ++ final TableEntry insert = new TableEntry<>(hash, key, newVal); ++ if (prev == null) { ++ setAtIndexRelease(table, index, insert); ++ } else { ++ prev.setNextRelease(insert); ++ } + -+ protected final TableEntry getEntryForPlain(final long key) { -+ final int hash = SWMRLong2ObjectHashTable.getHash(key); -+ final TableEntry[] table = this.getTablePlain(); ++ this.addToSize(1); + -+ for (TableEntry curr = table[hash & (table.length - 1)]; curr != null; curr = curr.getNextPlain()) { -+ if (key == curr.key) { -+ return curr; ++ return newVal; + } -+ } + -+ return null; -+ } ++ if (curr.hash == hash && (curr.key == key || curr.key.equals(key))) { ++ final V newVal = remappingFunction.apply(key, curr.getValuePlain()); + -+ /* MT-Safe */ ++ if (newVal != null) { ++ curr.setValueRelease(newVal); ++ return newVal; ++ } + -+ /** must be deterministic given a key */ -+ protected static int getHash(final long key) { -+ return (int)HashUtil.mix(key); -+ } ++ if (prev == null) { ++ setAtIndexRelease(table, index, curr.getNextPlain()); ++ } else { ++ prev.setNextRelease(curr.getNextPlain()); ++ } + -+ // 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; -+ } ++ this.removeFromSize(1); + -+ return (int)ret; ++ return null; ++ } ++ } + } + + /** + * {@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 other)) { -+ return false; -+ } -+ -+ if (this.size() != other.size()) { -+ return false; -+ } ++ public V computeIfPresent(final K key, final BiFunction remappingFunction) { ++ Validate.notNull(key, "Null key"); ++ Validate.notNull(remappingFunction, "Null remappingFunction"); + -+ final TableEntry[] table = this.getTableAcquire(); ++ final int hash = SWMRHashTable.getHash(key); ++ final TableEntry[] table = this.getTablePlain(); ++ final int index = hash & (table.length - 1); + -+ for (int i = 0, len = table.length; i < len; ++i) { -+ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { -+ final V value = curr.getValueAcquire(); ++ for (TableEntry 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 Object otherValue = other.get(curr.key); -+ if (otherValue == null || (value != otherValue && value.equals(otherValue))) { -+ return false; -+ } ++ final V newVal = remappingFunction.apply(key, curr.getValuePlain()); ++ if (newVal != null) { ++ curr.setValueRelease(newVal); ++ return newVal; + } -+ } + -+ return true; -+ } ++ if (prev == null) { ++ setAtIndexRelease(table, index, curr.getNextPlain()); ++ } else { ++ prev.setNextRelease(curr.getNextPlain()); ++ } + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public int hashCode() { -+ /* Make no attempt to deal with concurrent modifications */ -+ int hash = 0; -+ final TableEntry[] table = this.getTableAcquire(); ++ this.removeFromSize(1); + -+ for (int i = 0, len = table.length; i < len; ++i) { -+ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { -+ hash += curr.hashCode(); -+ } ++ return null; + } + -+ return hash; ++ return null; + } + + /** + * {@inheritDoc} + */ + @Override -+ public String toString() { -+ final StringBuilder builder = new StringBuilder(64); -+ builder.append("SingleWriterMultiReaderHashMap:{"); ++ public V computeIfAbsent(final K key, final Function mappingFunction) { ++ Validate.notNull(key, "Null key"); ++ Validate.notNull(mappingFunction, "Null mappingFunction"); + -+ this.forEach((final long key, final V value) -> { -+ builder.append("{key: \"").append(key).append("\", value: \"").append(value).append("\"}"); -+ }); ++ final int hash = SWMRHashTable.getHash(key); ++ final TableEntry[] table = this.getTablePlain(); ++ final int index = hash & (table.length - 1); + -+ return builder.append('}').toString(); -+ } ++ for (TableEntry 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; ++ } + -+ /** -+ * {@inheritDoc} -+ */ -+ @Override -+ public SWMRLong2ObjectHashTable clone() { -+ return new SWMRLong2ObjectHashTable<>(this.getTableAcquire().length, this.loadFactor, this); -+ } ++ final V newVal = mappingFunction.apply(key); + -+ /** -+ * {@inheritDoc} -+ */ -+ public void forEach(final Consumer> action) { -+ Validate.notNull(action, "Null action"); ++ if (newVal == null) { ++ return null; ++ } + -+ final TableEntry[] table = this.getTableAcquire(); -+ for (int i = 0, len = table.length; i < len; ++i) { -+ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { -+ action.accept(curr); ++ final TableEntry insert = new TableEntry<>(hash, key, newVal); ++ if (prev == null) { ++ setAtIndexRelease(table, index, insert); ++ } else { ++ prev.setNextRelease(insert); + } ++ ++ this.addToSize(1); ++ ++ return newVal; + } + } + + /** + * {@inheritDoc} + */ -+ public void forEach(final BiLongObjectConsumer action) { -+ Validate.notNull(action, "Null action"); ++ @Override ++ public V merge(final K key, final V value, final BiFunction remappingFunction) { ++ Validate.notNull(key, "Null key"); ++ Validate.notNull(value, "Null value"); ++ Validate.notNull(remappingFunction, "Null remappingFunction"); + -+ final TableEntry[] table = this.getTableAcquire(); -+ for (int i = 0, len = table.length; i < len; ++i) { -+ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { -+ final V value = curr.getValueAcquire(); ++ final int hash = SWMRHashTable.getHash(key); ++ final TableEntry[] table = this.getTablePlain(); ++ final int index = hash & (table.length - 1); + -+ action.accept(curr.key, value); -+ } -+ } -+ } ++ for (TableEntry curr = table[index], prev = null;;prev = curr, curr = curr.getNextPlain()) { ++ if (curr == null) { ++ final TableEntry insert = new TableEntry<>(hash, key, value); ++ if (prev == null) { ++ setAtIndexRelease(table, index, insert); ++ } else { ++ prev.setNextRelease(insert); ++ } + -+ /** -+ * 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"); ++ this.addToSize(1); + -+ final TableEntry[] table = this.getTableAcquire(); -+ for (int i = 0, len = table.length; i < len; ++i) { -+ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { -+ action.accept(curr.key); ++ return value; + } -+ } -+ } + -+ /** -+ * 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 action) { -+ Validate.notNull(action, "Null action"); ++ if (curr.hash == hash && (curr.key == key || curr.key.equals(key))) { ++ final V newVal = remappingFunction.apply(curr.getValuePlain(), value); + -+ final TableEntry[] table = this.getTableAcquire(); -+ for (int i = 0, len = table.length; i < len; ++i) { -+ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { -+ final V value = curr.getValueAcquire(); ++ if (newVal != null) { ++ curr.setValueRelease(newVal); ++ return newVal; ++ } + -+ action.accept(value); ++ if (prev == null) { ++ setAtIndexRelease(table, index, curr.getNextPlain()); ++ } else { ++ prev.setNextRelease(curr.getNextPlain()); ++ } ++ ++ this.removeFromSize(1); ++ ++ return null; + } + } + } + -+ /** -+ * {@inheritDoc} -+ */ -+ public V get(final long key) { -+ final TableEntry entry = this.getEntryForOpaque(key); -+ return entry == null ? null : entry.getValueAcquire(); -+ } ++ protected static final class TableEntry implements Map.Entry { + -+ /** -+ * {@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; -+ } ++ protected static final VarHandle TABLE_ENTRY_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(TableEntry[].class); + -+ /** -+ * {@inheritDoc} -+ */ -+ public V getOrDefault(final long key, final V defaultValue) { -+ final TableEntry entry = this.getEntryForOpaque(key); ++ protected final int hash; ++ protected final K key; ++ protected V value; + -+ return entry == null ? defaultValue : entry.getValueAcquire(); -+ } ++ protected TableEntry next; + -+ /** -+ * {@inheritDoc} -+ */ -+ public int size() { -+ return this.getSizeAcquire(); -+ } ++ 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); + -+ /** -+ * {@inheritDoc} -+ */ -+ public boolean isEmpty() { -+ return this.getSizeAcquire() == 0; -+ } ++ /* value */ + -+ /* Non-MT-Safe */ ++ protected final V getValuePlain() { ++ //noinspection unchecked ++ return (V)VALUE_HANDLE.get(this); ++ } + -+ protected int threshold; ++ protected final V getValueAcquire() { ++ //noinspection unchecked ++ return (V)VALUE_HANDLE.getAcquire(this); ++ } + -+ protected final void checkResize(final int minCapacity) { -+ if (minCapacity <= this.threshold || this.threshold < 0) { -+ return; ++ protected final void setValueRelease(final V to) { ++ VALUE_HANDLE.setRelease(this, to); + } + -+ final TableEntry[] table = this.getTablePlain(); -+ int newCapacity = minCapacity >= MAXIMUM_CAPACITY ? MAXIMUM_CAPACITY : IntegerUtil.roundCeilLog2(minCapacity); -+ if (newCapacity < 0) { -+ newCapacity = MAXIMUM_CAPACITY; ++ /* next */ ++ ++ protected final TableEntry getNextPlain() { ++ //noinspection unchecked ++ return (TableEntry)NEXT_HANDLE.get(this); + } -+ if (newCapacity <= table.length) { -+ if (newCapacity == MAXIMUM_CAPACITY) { -+ return; -+ } -+ newCapacity = table.length << 1; ++ ++ protected final TableEntry getNextOpaque() { ++ //noinspection unchecked ++ return (TableEntry)NEXT_HANDLE.getOpaque(this); + } + -+ //noinspection unchecked -+ final TableEntry[] newTable = new TableEntry[newCapacity]; -+ final int indexMask = newCapacity - 1; ++ protected final void setNextPlain(final TableEntry next) { ++ NEXT_HANDLE.set(this, next); ++ } + -+ for (int i = 0, len = table.length; i < len; ++i) { -+ for (TableEntry entry = table[i]; entry != null; entry = entry.getNextPlain()) { -+ final long key = entry.key; -+ final int hash = SWMRLong2ObjectHashTable.getHash(key); -+ final int index = hash & indexMask; ++ protected final void setNextRelease(final TableEntry next) { ++ NEXT_HANDLE.setRelease(this, next); ++ } + -+ /* we need to create a new entry since there could be reading threads */ -+ final TableEntry insert = new TableEntry<>(key, entry.getValuePlain()); ++ protected TableEntry(final int hash, final K key, final V value) { ++ this.hash = hash; ++ this.key = key; ++ this.value = value; ++ } + -+ final TableEntry prev = newTable[index]; ++ @Override ++ public K getKey() { ++ return this.key; ++ } + -+ newTable[index] = insert; -+ insert.setNextPlain(prev); -+ } ++ @Override ++ public V getValue() { ++ return this.getValueAcquire(); ++ } ++ ++ @Override ++ public V setValue(final V value) { ++ throw new UnsupportedOperationException(); ++ } ++ ++ 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()); + } + -+ if (newCapacity == MAXIMUM_CAPACITY) { -+ this.threshold = -1; /* No more resizing */ -+ } else { -+ this.threshold = getTargetCapacity(newCapacity, this.loadFactor); ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public boolean equals(final Object obj) { ++ if (this == obj) { ++ return true; ++ } ++ ++ if (!(obj instanceof Map.Entry other)) { ++ return false; ++ } ++ 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)); + } -+ 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; ++ protected static abstract class TableEntryIterator implements Iterator { + -+ this.setSizeOpaque(newSize); ++ protected final TableEntry[] table; ++ protected final SWMRHashTable map; + -+ return newSize; -+ } ++ /* bin which our current element resides on */ ++ protected int tableIndex; + -+ protected final V put(final long key, final V value, final boolean onlyIfAbsent) { -+ final TableEntry[] table = this.getTablePlain(); -+ final int hash = SWMRLong2ObjectHashTable.getHash(key); -+ final int index = hash & (table.length - 1); ++ protected TableEntry currEntry; /* curr entry, null if no more to iterate or if curr was removed or if we've just init'd */ ++ protected TableEntry nextEntry; /* may not be on the same bin as currEntry */ + -+ final TableEntry head = table[index]; -+ if (head == null) { -+ final TableEntry insert = new TableEntry<>(key, value); -+ setAtIndexRelease(table, index, insert); -+ this.addToSize(1); -+ return null; ++ protected TableEntryIterator(final TableEntry[] table, final SWMRHashTable map) { ++ this.table = table; ++ this.map = map; ++ int tableIndex = 0; ++ for (int len = table.length; tableIndex < len; ++tableIndex) { ++ final TableEntry entry = getAtIndexOpaque(table, tableIndex); ++ if (entry != null) { ++ this.nextEntry = entry; ++ this.tableIndex = tableIndex + 1; ++ return; ++ } ++ } ++ this.tableIndex = tableIndex; + } + -+ for (TableEntry curr = head;;) { -+ if (key == curr.key) { -+ if (onlyIfAbsent) { -+ return curr.getValuePlain(); -+ } ++ @Override ++ public boolean hasNext() { ++ return this.nextEntry != null; ++ } + -+ final V currVal = curr.getValuePlain(); -+ curr.setValueRelease(value); -+ return currVal; ++ protected final TableEntry advanceEntry() { ++ final TableEntry[] table = this.table; ++ final int tableLength = table.length; ++ int tableIndex = this.tableIndex; ++ final TableEntry curr = this.nextEntry; ++ if (curr == null) { ++ return null; + } + -+ final TableEntry next = curr.getNextPlain(); ++ this.currEntry = curr; ++ ++ // set up nextEntry ++ ++ // find next in chain ++ TableEntry next = curr.getNextOpaque(); ++ + if (next != null) { -+ curr = next; -+ continue; ++ this.nextEntry = next; ++ return curr; + } + -+ final TableEntry insert = new TableEntry<>(key, value); ++ // nothing in chain, so find next available bin ++ for (;tableIndex < tableLength; ++tableIndex) { ++ next = getAtIndexOpaque(table, tableIndex); ++ if (next != null) { ++ this.nextEntry = next; ++ this.tableIndex = tableIndex + 1; ++ return curr; ++ } ++ } + -+ curr.setNextRelease(insert); -+ this.addToSize(1); -+ return null; ++ this.nextEntry = null; ++ this.tableIndex = tableIndex; ++ return curr; + } -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public V put(final long key, final V value) { -+ Validate.notNull(value, "Null value"); + -+ return this.put(key, value, false); -+ } ++ @Override ++ public void remove() { ++ final TableEntry curr = this.currEntry; ++ if (curr == null) { ++ throw new IllegalStateException(); ++ } + -+ /** -+ * {@inheritDoc} -+ */ -+ public V putIfAbsent(final long key, final V value) { -+ Validate.notNull(value, "Null value"); ++ this.map.remove(curr.key, curr.hash); + -+ return this.put(key, value, true); ++ this.currEntry = null; ++ } + } + -+ protected final V remove(final long key, final int hash) { -+ final TableEntry[] table = this.getTablePlain(); -+ final int index = (table.length - 1) & hash; ++ protected static final class ValueIterator extends TableEntryIterator { + -+ final TableEntry head = table[index]; -+ if (head == null) { -+ return null; ++ protected ValueIterator(final TableEntry[] table, final SWMRHashTable map) { ++ super(table, map); + } + -+ if (head.key == key) { -+ setAtIndexRelease(table, index, head.getNextPlain()); -+ this.removeFromSize(1); ++ @Override ++ public V next() { ++ final TableEntry entry = this.advanceEntry(); + -+ return head.getValuePlain(); ++ if (entry == null) { ++ throw new NoSuchElementException(); ++ } ++ ++ return entry.getValueAcquire(); + } ++ } + -+ for (TableEntry curr = head.getNextPlain(), prev = head; curr != null; prev = curr, curr = curr.getNextPlain()) { -+ if (key == curr.key) { -+ prev.setNextRelease(curr.getNextPlain()); -+ this.removeFromSize(1); ++ protected static final class KeyIterator extends TableEntryIterator { + -+ return curr.getValuePlain(); -+ } ++ protected KeyIterator(final TableEntry[] table, final SWMRHashTable map) { ++ super(table, map); + } + -+ return null; -+ } ++ @Override ++ public K next() { ++ final TableEntry curr = this.advanceEntry(); + -+ protected final V remove(final long key, final int hash, final V expect) { -+ final TableEntry[] table = this.getTablePlain(); -+ final int index = (table.length - 1) & hash; ++ if (curr == null) { ++ throw new NoSuchElementException(); ++ } + -+ final TableEntry head = table[index]; -+ if (head == null) { -+ return null; ++ return curr.key; + } ++ } + -+ if (head.key == key) { -+ final V val = head.value; -+ if (val == expect || val.equals(expect)) { -+ setAtIndexRelease(table, index, head.getNextPlain()); -+ this.removeFromSize(1); ++ protected static final class EntryIterator extends TableEntryIterator> { + -+ return head.getValuePlain(); -+ } else { -+ return null; -+ } ++ protected EntryIterator(final TableEntry[] table, final SWMRHashTable map) { ++ super(table, map); + } + -+ for (TableEntry curr = head.getNextPlain(), prev = head; curr != null; prev = curr, curr = curr.getNextPlain()) { -+ if (key == curr.key) { -+ final V val = curr.value; -+ if (val == expect || val.equals(expect)) { -+ prev.setNextRelease(curr.getNextPlain()); -+ this.removeFromSize(1); ++ @Override ++ public Map.Entry next() { ++ final TableEntry curr = this.advanceEntry(); + -+ return curr.getValuePlain(); -+ } else { -+ return null; -+ } ++ if (curr == null) { ++ throw new NoSuchElementException(); + } -+ } + -+ return null; ++ return curr; ++ } + } + -+ /** -+ * {@inheritDoc} -+ */ -+ public V remove(final long key) { -+ return this.remove(key, SWMRLong2ObjectHashTable.getHash(key)); -+ } ++ protected static abstract class ViewCollection implements Collection { + -+ public boolean remove(final long key, final V expect) { -+ return this.remove(key, SWMRLong2ObjectHashTable.getHash(key), expect) != null; -+ } ++ protected final SWMRHashTable map; + -+ /** -+ * {@inheritDoc} -+ */ -+ public void putAll(final SWMRLong2ObjectHashTable map) { -+ Validate.notNull(map, "Null map"); ++ protected ViewCollection(final SWMRHashTable map) { ++ this.map = map; ++ } + -+ final int size = map.size(); -+ this.checkResize(Math.max(this.getSizePlain() + size/2, size)); /* preemptively resize */ -+ map.forEach(this::put); -+ } ++ @Override ++ public boolean add(final T element) { ++ throw new UnsupportedOperationException(); ++ } + -+ /** -+ * {@inheritDoc} -+ *

    -+ * 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. -+ *

    -+ */ -+ public void clear() { -+ Arrays.fill(this.getTablePlain(), null); -+ this.setSizeRelease(0); -+ } ++ @Override ++ public boolean addAll(final Collection collections) { ++ throw new UnsupportedOperationException(); ++ } + -+ public static final class TableEntry { ++ @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; ++ } + -+ protected static final VarHandle TABLE_ENTRY_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(TableEntry[].class); ++ @Override ++ public int size() { ++ return this.map.size(); ++ } + -+ protected final long key; -+ protected V value; ++ @Override ++ public boolean isEmpty() { ++ return this.size() == 0; ++ } + -+ protected TableEntry next; ++ @Override ++ public void clear() { ++ this.map.clear(); ++ } + -+ 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); ++ @Override ++ public boolean containsAll(final Collection collection) { ++ Validate.notNull(collection, "Null collection"); + -+ /* value */ ++ for (final Object element : collection) { ++ if (!this.contains(element)) { ++ return false; ++ } ++ } + -+ protected final V getValuePlain() { -+ //noinspection unchecked -+ return (V)VALUE_HANDLE.get(this); ++ return true; + } + -+ protected final V getValueAcquire() { -+ //noinspection unchecked -+ return (V)VALUE_HANDLE.getAcquire(this); -+ } ++ @Override ++ public Object[] toArray() { ++ final List list = new ArrayList<>(this.size()); + -+ protected final void setValueRelease(final V to) { -+ VALUE_HANDLE.setRelease(this, to); ++ this.forEach(list::add); ++ ++ return list.toArray(); + } + -+ /* next */ ++ @Override ++ public E[] toArray(final E[] array) { ++ final List list = new ArrayList<>(this.size()); + -+ protected final TableEntry getNextPlain() { -+ //noinspection unchecked -+ return (TableEntry)NEXT_HANDLE.get(this); -+ } ++ this.forEach(list::add); + -+ protected final TableEntry getNextOpaque() { -+ //noinspection unchecked -+ return (TableEntry)NEXT_HANDLE.getOpaque(this); ++ return list.toArray(array); + } + -+ protected final void setNextPlain(final TableEntry next) { -+ NEXT_HANDLE.set(this, next); -+ } ++ @Override ++ public E[] toArray(final IntFunction generator) { ++ final List list = new ArrayList<>(this.size()); + -+ protected final void setNextRelease(final TableEntry next) { -+ NEXT_HANDLE.setRelease(this, next); -+ } ++ this.forEach(list::add); + -+ protected TableEntry(final long key, final V value) { -+ this.key = key; -+ this.value = value; ++ return list.toArray(generator); + } + -+ public long getKey() { -+ return this.key; ++ @Override ++ public int hashCode() { ++ int hash = 0; ++ for (final T element : this) { ++ hash += element == null ? 0 : element.hashCode(); ++ } ++ return hash; + } + -+ public V getValue() { -+ return this.getValueAcquire(); ++ @Override ++ public Spliterator spliterator() { // TODO implement ++ return Spliterators.spliterator(this, Spliterator.NONNULL); + } + } -+} -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/scheduler/SchedulerThreadPool.java b/src/main/java/ca/spottedleaf/concurrentutil/scheduler/SchedulerThreadPool.java -new file mode 100644 -index 0000000000000000000000000000000000000000..8197ccb1c4e5878dbd8007b5fb514640765ec8e4 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/scheduler/SchedulerThreadPool.java -@@ -0,0 +1,558 @@ -+package ca.spottedleaf.concurrentutil.scheduler; + -+import ca.spottedleaf.concurrentutil.set.LinkedSortedSet; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.TimeUtil; -+import java.lang.invoke.VarHandle; -+import java.util.BitSet; -+import java.util.Comparator; -+import java.util.PriorityQueue; -+import java.util.concurrent.ThreadFactory; -+import java.util.concurrent.atomic.AtomicInteger; -+import java.util.concurrent.atomic.AtomicLong; -+import java.util.concurrent.locks.LockSupport; -+import java.util.function.BooleanSupplier; ++ protected static abstract class ViewSet extends ViewCollection implements Set { + -+public class SchedulerThreadPool { ++ protected ViewSet(final SWMRHashTable map) { ++ super(map); ++ } + -+ public static final long DEADLINE_NOT_SET = Long.MIN_VALUE; ++ @Override ++ public boolean equals(final Object obj) { ++ if (this == obj) { ++ return true; ++ } + -+ private static final Comparator TICK_COMPARATOR_BY_TIME = (final SchedulableTick t1, final SchedulableTick t2) -> { -+ final int timeCompare = TimeUtil.compareTimes(t1.scheduledStart, t2.scheduledStart); -+ if (timeCompare != 0) { -+ return timeCompare; ++ if (!(obj instanceof Set)) { ++ return false; ++ } ++ ++ final Set other = (Set)obj; ++ if (other.size() != this.size()) { ++ return false; ++ } ++ ++ return this.containsAll(other); + } ++ } + -+ return Long.compare(t1.id, t2.id); -+ }; ++ protected static final class EntrySet extends ViewSet> implements Set> { + -+ private final TickThreadRunner[] runners; -+ private final Thread[] threads; -+ private final LinkedSortedSet awaiting = new LinkedSortedSet<>(TICK_COMPARATOR_BY_TIME); -+ private final PriorityQueue queued = new PriorityQueue<>(TICK_COMPARATOR_BY_TIME); -+ private final BitSet idleThreads; ++ protected EntrySet(final SWMRHashTable map) { ++ super(map); ++ } + -+ private final Object scheduleLock = new Object(); ++ @Override ++ public boolean remove(final Object object) { ++ if (!(object instanceof Map.Entry entry)) { ++ return false; ++ } + -+ private volatile boolean halted; ++ final Object key; ++ final Object value; + -+ /** -+ * Creates, but does not start, a scheduler thread pool with the specified number of threads -+ * created using the specified thread factory. -+ * @param threads Specified number of threads -+ * @param threadFactory Specified thread factory -+ * @see #start() -+ */ -+ public SchedulerThreadPool(final int threads, final ThreadFactory threadFactory) { -+ final BitSet idleThreads = new BitSet(threads); -+ for (int i = 0; i < threads; ++i) { -+ idleThreads.set(i); ++ try { ++ key = entry.getKey(); ++ value = entry.getValue(); ++ } catch (final IllegalStateException ex) { ++ return false; ++ } ++ ++ return this.map.remove(key, value); + } -+ this.idleThreads = idleThreads; + -+ final TickThreadRunner[] runners = new TickThreadRunner[threads]; -+ final Thread[] t = new Thread[threads]; -+ for (int i = 0; i < threads; ++i) { -+ runners[i] = new TickThreadRunner(i, this); -+ t[i] = threadFactory.newThread(runners[i]); ++ @Override ++ public boolean removeIf(final Predicate> filter) { ++ Validate.notNull(filter, "Null filter"); ++ ++ return this.map.removeEntryIf(filter) != 0; + } + -+ this.threads = t; -+ this.runners = runners; -+ } ++ @Override ++ public boolean retainAll(final Collection collection) { ++ Validate.notNull(collection, "Null collection"); + -+ /** -+ * Starts the threads in this pool. -+ */ -+ public void start() { -+ for (final Thread thread : this.threads) { -+ thread.start(); ++ return this.map.removeEntryIf((final Map.Entry entry) -> { ++ return !collection.contains(entry); ++ }) != 0; + } -+ } + -+ /** -+ * Attempts to prevent further execution of tasks, optionally waiting for the scheduler threads to die. -+ * -+ * @param sync Whether to wait for the scheduler threads to die. -+ * @param maxWaitNS The maximum time, in ns, to wait for the scheduler threads to die. -+ * @return {@code true} if sync was false, or if sync was true and the scheduler threads died before the timeout. -+ * Otherwise, returns {@code false} if the time elapsed exceeded the maximum wait time. -+ */ -+ public boolean halt(final boolean sync, final long maxWaitNS) { -+ this.halted = true; -+ for (final Thread thread : this.threads) { -+ // force response to halt -+ LockSupport.unpark(thread); ++ @Override ++ public Iterator> iterator() { ++ return new EntryIterator<>(this.map.getTableAcquire(), this.map); + } -+ final long time = System.nanoTime(); -+ if (sync) { -+ // start at 10 * 0.5ms -> 5ms -+ for (long failures = 9L;; failures = ConcurrentUtil.linearLongBackoff(failures, 500_000L, 50_000_000L)) { -+ boolean allDead = true; -+ for (final Thread thread : this.threads) { -+ if (thread.isAlive()) { -+ allDead = false; -+ break; -+ } -+ } -+ if (allDead) { -+ return true; -+ } -+ if ((System.nanoTime() - time) >= maxWaitNS) { -+ return false; -+ } -+ } ++ ++ @Override ++ public void forEach(final Consumer> action) { ++ this.map.forEach(action); + } + -+ return true; -+ } ++ @Override ++ public boolean contains(final Object object) { ++ if (!(object instanceof Map.Entry entry)) { ++ return false; ++ } + -+ /** -+ * Returns an array of the underlying scheduling threads. -+ */ -+ public Thread[] getThreads() { -+ return this.threads.clone(); ++ 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"); ++ } + } + -+ private void insertFresh(final SchedulableTick task) { -+ final TickThreadRunner[] runners = this.runners; ++ protected static final class KeySet extends ViewSet { + -+ final int firstIdleThread = this.idleThreads.nextSetBit(0); ++ protected KeySet(final SWMRHashTable map) { ++ super(map); ++ } + -+ if (firstIdleThread != -1) { -+ // push to idle thread -+ this.idleThreads.clear(firstIdleThread); -+ final TickThreadRunner runner = runners[firstIdleThread]; -+ task.awaitingLink = this.awaiting.addLast(task); -+ runner.acceptTask(task); -+ return; ++ @Override ++ public Iterator iterator() { ++ return new KeyIterator<>(this.map.getTableAcquire(), this.map); + } + -+ // try to replace the last awaiting task -+ final SchedulableTick last = this.awaiting.last(); ++ @Override ++ public void forEach(final Consumer action) { ++ Validate.notNull(action, "Null action"); + -+ if (last != null && TICK_COMPARATOR_BY_TIME.compare(task, last) < 0) { -+ // need to replace the last task -+ this.awaiting.pollLast(); -+ last.awaitingLink = null; -+ task.awaitingLink = this.awaiting.addLast(task); -+ // need to add task to queue to be picked up later -+ this.queued.add(last); ++ this.map.forEachKey(action); ++ } + -+ final TickThreadRunner runner = last.ownedBy; -+ runner.replaceTask(task); ++ @Override ++ public boolean contains(final Object key) { ++ Validate.notNull(key, "Null key"); + -+ return; ++ return this.map.containsKey(key); + } + -+ // add to queue, will be picked up later -+ this.queued.add(task); -+ } ++ @Override ++ public boolean remove(final Object key) { ++ Validate.notNull(key, "Null key"); + -+ private void takeTask(final TickThreadRunner runner, final SchedulableTick tick) { -+ if (!this.awaiting.remove(tick.awaitingLink)) { -+ throw new IllegalStateException("Task is not in awaiting"); ++ return this.map.remove(key) != null; + } -+ tick.awaitingLink = null; -+ } + -+ private SchedulableTick returnTask(final TickThreadRunner runner, final SchedulableTick reschedule) { -+ if (reschedule != null) { -+ this.queued.add(reschedule); ++ @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; + } -+ final SchedulableTick ret = this.queued.poll(); -+ if (ret == null) { -+ this.idleThreads.set(runner.id); -+ } else { -+ ret.awaitingLink = this.awaiting.addLast(ret); ++ ++ @Override ++ public boolean removeIf(final Predicate filter) { ++ Validate.notNull(filter, "Null filter"); ++ ++ return this.map.removeIf((final K key, final V value) -> { ++ return filter.test(key); ++ }) != 0; + } + -+ return ret; ++ @Override ++ public String toString() { ++ return CollectionUtil.toString(this, "SWMRHashTableKeySet"); ++ } + } + -+ /** -+ * Schedules the specified task to be executed on this thread pool. -+ * @param task Specified task -+ * @throws IllegalStateException If the task is already scheduled -+ * @see SchedulableTick -+ */ -+ public void schedule(final SchedulableTick task) { -+ synchronized (this.scheduleLock) { -+ if (!task.tryMarkScheduled()) { -+ throw new IllegalStateException("Task " + task + " is already scheduled or cancelled"); -+ } ++ protected static final class ValueCollection extends ViewSet implements Collection { + -+ task.schedulerOwnedBy = this; ++ protected ValueCollection(final SWMRHashTable map) { ++ super(map); ++ } + -+ this.insertFresh(task); ++ @Override ++ public Iterator iterator() { ++ return new ValueIterator<>(this.map.getTableAcquire(), this.map); + } -+ } + -+ /** -+ * Updates the tasks scheduled start to the maximum of its current scheduled start and the specified -+ * new start. If the task is not scheduled, returns {@code false}. Otherwise, returns whether the -+ * scheduled start was updated. Undefined behavior of the specified task is scheduled in another executor. -+ * @param task Specified task -+ * @param newStart Specified new start -+ */ -+ public boolean updateTickStartToMax(final SchedulableTick task, final long newStart) { -+ synchronized (this.scheduleLock) { -+ if (TimeUtil.compareTimes(newStart, task.getScheduledStart()) <= 0) { -+ return false; -+ } -+ if (this.queued.remove(task)) { -+ task.setScheduledStart(newStart); -+ this.queued.add(task); -+ return true; -+ } -+ if (task.awaitingLink != null) { -+ this.awaiting.remove(task.awaitingLink); -+ task.awaitingLink = null; ++ @Override ++ public void forEach(final Consumer action) { ++ Validate.notNull(action, "Null action"); + -+ // re-queue task -+ task.setScheduledStart(newStart); -+ this.queued.add(task); ++ this.map.forEachValue(action); ++ } + -+ // now we need to replace the task the runner was waiting for -+ final TickThreadRunner runner = task.ownedBy; -+ final SchedulableTick replace = this.queued.poll(); ++ @Override ++ public boolean contains(final Object object) { ++ Validate.notNull(object, "Null object"); + -+ // replace cannot be null, since we have added a task to queued -+ if (replace != task) { -+ runner.replaceTask(replace); -+ } ++ return this.map.containsValue(object); ++ } + -+ return true; ++ @Override ++ public boolean remove(final Object object) { ++ Validate.notNull(object, "Null object"); ++ ++ final Iterator itr = this.iterator(); ++ while (itr.hasNext()) { ++ final V val = itr.next(); ++ if (val == object || val.equals(object)) { ++ itr.remove(); ++ return true; ++ } + } + + return false; + } -+ } -+ -+ /** -+ * Returns {@code null} if the task is not scheduled, returns {@code TRUE} if the task was cancelled -+ * and was queued to execute, returns {@code FALSE} if the task was cancelled but was executing. -+ */ -+ public Boolean tryRetire(final SchedulableTick task) { -+ if (task.schedulerOwnedBy != this) { -+ return null; -+ } + -+ synchronized (this.scheduleLock) { -+ if (this.queued.remove(task)) { -+ // cancelled, and no runner owns it - so return -+ return Boolean.TRUE; -+ } -+ if (task.awaitingLink != null) { -+ this.awaiting.remove(task.awaitingLink); -+ task.awaitingLink = null; -+ // here we need to replace the task the runner was waiting for -+ final TickThreadRunner runner = task.ownedBy; -+ final SchedulableTick replace = this.queued.poll(); ++ @Override ++ public boolean removeIf(final Predicate filter) { ++ Validate.notNull(filter, "Null filter"); + -+ if (replace == null) { -+ // nothing to replace with, set to idle -+ this.idleThreads.set(runner.id); -+ runner.forceIdle(); -+ } else { -+ runner.replaceTask(replace); -+ } ++ return this.map.removeIf((final K key, final V value) -> { ++ return filter.test(value); ++ }) != 0; ++ } + -+ return Boolean.TRUE; -+ } ++ @Override ++ public boolean retainAll(final Collection collection) { ++ Validate.notNull(collection, "Null collection"); + -+ // could not find it in queue -+ return task.tryMarkCancelled() ? Boolean.FALSE : null; ++ return this.map.removeIf((final K key, final V value) -> { ++ return !collection.contains(value); ++ }) != 0; + } -+ } + -+ /** -+ * Indicates that intermediate tasks are available to be executed by the task. -+ *

    -+ * Note: currently a no-op -+ *

    -+ * @param task The specified task -+ * @see SchedulableTick -+ */ -+ public void notifyTasks(final SchedulableTick task) { -+ // Not implemented ++ @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..bb301a9f4e3ac919552eef68afc73569d50674db +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/map/SWMRLong2ObjectHashTable.java +@@ -0,0 +1,674 @@ ++package ca.spottedleaf.concurrentutil.map; + -+ /** -+ * Represents a tickable task that can be scheduled into a {@link SchedulerThreadPool}. -+ *

    -+ * A tickable task is expected to run on a fixed interval, which is determined by -+ * the {@link SchedulerThreadPool}. -+ *

    -+ *

    -+ * A tickable task can have intermediate tasks that can be executed before its tick method is ran. Instead of -+ * the {@link SchedulerThreadPool} parking in-between ticks, the scheduler will instead drain -+ * intermediate tasks from scheduled tasks. The parsing of intermediate tasks allows the scheduler to take -+ * advantage of downtime to reduce the intermediate task load from tasks once they begin ticking. -+ *

    -+ *

    -+ * It is guaranteed that {@link #runTick()} and {@link #runTasks(BooleanSupplier)} are never -+ * invoked in parallel. -+ * It is required that when intermediate tasks are scheduled, that {@link SchedulerThreadPool#notifyTasks(SchedulableTick)} -+ * is invoked for any scheduled task - otherwise, {@link #runTasks(BooleanSupplier)} may not be invoked to -+ * parse intermediate tasks. -+ *

    -+ */ -+ public static abstract class SchedulableTick { -+ private static final AtomicLong ID_GENERATOR = new AtomicLong(); -+ public final long id = ID_GENERATOR.getAndIncrement(); ++import ca.spottedleaf.concurrentutil.function.BiLongObjectConsumer; ++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.HashUtil; ++import ca.spottedleaf.concurrentutil.util.IntegerUtil; ++import ca.spottedleaf.concurrentutil.util.Validate; ++import java.lang.invoke.VarHandle; ++import java.util.Arrays; ++import java.util.function.Consumer; ++import java.util.function.LongConsumer; + -+ private static final int SCHEDULE_STATE_NOT_SCHEDULED = 0; -+ private static final int SCHEDULE_STATE_SCHEDULED = 1; -+ private static final int SCHEDULE_STATE_CANCELLED = 2; ++// trimmed down version of SWMRHashTable ++public class SWMRLong2ObjectHashTable { + -+ private final AtomicInteger scheduled = new AtomicInteger(); -+ private SchedulerThreadPool schedulerOwnedBy; -+ private long scheduledStart = DEADLINE_NOT_SET; -+ private TickThreadRunner ownedBy; ++ protected int size; + -+ private LinkedSortedSet.Link awaitingLink; ++ protected TableEntry[] table; + -+ private boolean tryMarkScheduled() { -+ return this.scheduled.compareAndSet(SCHEDULE_STATE_NOT_SCHEDULED, SCHEDULE_STATE_SCHEDULED); -+ } ++ protected final float loadFactor; + -+ private boolean tryMarkCancelled() { -+ return this.scheduled.compareAndSet(SCHEDULE_STATE_SCHEDULED, SCHEDULE_STATE_CANCELLED); -+ } ++ 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); + -+ private boolean isScheduled() { -+ return this.scheduled.get() == SCHEDULE_STATE_SCHEDULED; -+ } ++ /* size */ + -+ protected final long getScheduledStart() { -+ return this.scheduledStart; -+ } ++ protected final int getSizePlain() { ++ return (int)SIZE_HANDLE.get(this); ++ } + -+ /** -+ * If this task is scheduled, then this may only be invoked during {@link #runTick()}, -+ * and {@link #runTasks(BooleanSupplier)} -+ */ -+ protected final void setScheduledStart(final long value) { -+ this.scheduledStart = value; -+ } ++ protected final int getSizeOpaque() { ++ return (int)SIZE_HANDLE.getOpaque(this); ++ } + -+ /** -+ * Executes the tick. -+ *

    -+ * It is the callee's responsibility to invoke {@link #setScheduledStart(long)} to adjust the start of -+ * the next tick. -+ *

    -+ * @return {@code true} if the task should continue to be scheduled, {@code false} otherwise. -+ */ -+ public abstract boolean runTick(); ++ protected final int getSizeAcquire() { ++ return (int)SIZE_HANDLE.getAcquire(this); ++ } + -+ /** -+ * Returns whether this task has any intermediate tasks that can be executed. -+ */ -+ public abstract boolean hasTasks(); ++ protected final void setSizePlain(final int value) { ++ SIZE_HANDLE.set(this, value); ++ } + -+ /** -+ * Returns {@code null} if this task should not be scheduled, otherwise returns -+ * {@code Boolean.TRUE} if there are more intermediate tasks to execute and -+ * {@code Boolean.FALSE} if there are no more intermediate tasks to execute. -+ */ -+ public abstract Boolean runTasks(final BooleanSupplier canContinue); ++ protected final void setSizeOpaque(final int value) { ++ SIZE_HANDLE.setOpaque(this, value); ++ } + -+ @Override -+ public String toString() { -+ return "SchedulableTick:{" + -+ "class=" + this.getClass().getName() + "," + -+ "scheduled_state=" + this.scheduled.get() + "," -+ + "}"; -+ } ++ protected final void setSizeRelease(final int value) { ++ SIZE_HANDLE.setRelease(this, value); + } + -+ private static final class TickThreadRunner implements Runnable { ++ /* table */ + -+ /** -+ * There are no tasks in this thread's runqueue, so it is parked. -+ *

    -+ * stateTarget = null -+ *

    -+ */ -+ private static final int STATE_IDLE = 0; ++ protected final TableEntry[] getTablePlain() { ++ //noinspection unchecked ++ return (TableEntry[])TABLE_HANDLE.get(this); ++ } + -+ /** -+ * The runner is waiting to tick a task, as it has no intermediate tasks to execute. -+ *

    -+ * stateTarget = the task awaiting tick -+ *

    -+ */ -+ private static final int STATE_AWAITING_TICK = 1; ++ protected final TableEntry[] getTableAcquire() { ++ //noinspection unchecked ++ return (TableEntry[])TABLE_HANDLE.getAcquire(this); ++ } + -+ /** -+ * The runner is executing a tick for one of the tasks that was in its runqueue. -+ *

    -+ * stateTarget = the task being ticked -+ *

    -+ */ -+ private static final int STATE_EXECUTING_TICK = 2; ++ protected final void setTablePlain(final TableEntry[] table) { ++ TABLE_HANDLE.set(this, table); ++ } + -+ public final int id; -+ public final SchedulerThreadPool scheduler; ++ protected final void setTableRelease(final TableEntry[] table) { ++ TABLE_HANDLE.setRelease(this, table); ++ } + -+ private volatile Thread thread; -+ private volatile TickThreadRunnerState state = new TickThreadRunnerState(null, STATE_IDLE); -+ private static final VarHandle STATE_HANDLE = ConcurrentUtil.getVarHandle(TickThreadRunner.class, "state", TickThreadRunnerState.class); ++ 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; + -+ private void setStatePlain(final TickThreadRunnerState state) { -+ STATE_HANDLE.set(this, state); -+ } ++ /** ++ * Constructs this map with a capacity of {@code 16} and load factor of {@code 0.75f}. ++ */ ++ public SWMRLong2ObjectHashTable() { ++ this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR); ++ } + -+ private void setStateOpaque(final TickThreadRunnerState state) { -+ STATE_HANDLE.setOpaque(this, state); -+ } ++ /** ++ * 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); ++ } + -+ private void setStateVolatile(final TickThreadRunnerState state) { -+ STATE_HANDLE.setVolatile(this, state); ++ /** ++ * 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); + } + -+ private static record TickThreadRunnerState(SchedulableTick stateTarget, int state) {} ++ //noinspection unchecked ++ final TableEntry[] table = new TableEntry[tableSize]; ++ this.setTablePlain(table); + -+ public TickThreadRunner(final int id, final SchedulerThreadPool scheduler) { -+ this.id = id; -+ this.scheduler = scheduler; ++ if (tableSize == MAXIMUM_CAPACITY) { ++ this.threshold = -1; ++ } else { ++ this.threshold = getTargetCapacity(tableSize, loadFactor); + } + -+ private Thread getRunnerThread() { -+ return this.thread; ++ 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 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 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 other) { ++ this(Math.max(Validate.notNull(other, "Null map").size(), capacity), loadFactor); ++ this.putAll(other); ++ } ++ ++ protected static TableEntry getAtIndexOpaque(final TableEntry[] table, final int index) { ++ // noinspection unchecked ++ return (TableEntry)TableEntry.TABLE_ENTRY_ARRAY_HANDLE.getOpaque(table, index); ++ } ++ ++ protected static void setAtIndexRelease(final TableEntry[] table, final int index, final TableEntry value) { ++ TableEntry.TABLE_ENTRY_ARRAY_HANDLE.setRelease(table, index, value); ++ } ++ ++ 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); ++ } + -+ private void acceptTask(final SchedulableTick task) { -+ if (task.ownedBy != null) { -+ throw new IllegalStateException("Already owned by another runner"); -+ } -+ task.ownedBy = this; -+ final TickThreadRunnerState state = this.state; -+ if (state.state != STATE_IDLE) { -+ throw new IllegalStateException("Cannot accept task in state " + state); ++ /** Callers must still use acquire when reading the value of the entry. */ ++ protected final TableEntry getEntryForOpaque(final long key) { ++ final int hash = SWMRLong2ObjectHashTable.getHash(key); ++ final TableEntry[] table = this.getTableAcquire(); ++ ++ for (TableEntry curr = getAtIndexOpaque(table, hash & (table.length - 1)); curr != null; curr = curr.getNextOpaque()) { ++ if (key == curr.key) { ++ return curr; + } -+ this.setStateVolatile(new TickThreadRunnerState(task, STATE_AWAITING_TICK)); -+ LockSupport.unpark(this.getRunnerThread()); + } + -+ private void replaceTask(final SchedulableTick task) { -+ final TickThreadRunnerState state = this.state; -+ if (state.state != STATE_AWAITING_TICK) { -+ throw new IllegalStateException("Cannot replace task in state " + state); -+ } -+ if (task.ownedBy != null) { -+ throw new IllegalStateException("Already owned by another runner"); ++ return null; ++ } ++ ++ protected final TableEntry getEntryForPlain(final long key) { ++ final int hash = SWMRLong2ObjectHashTable.getHash(key); ++ final TableEntry[] table = this.getTablePlain(); ++ ++ for (TableEntry curr = table[hash & (table.length - 1)]; curr != null; curr = curr.getNextPlain()) { ++ if (key == curr.key) { ++ return curr; + } -+ task.ownedBy = this; ++ } + -+ state.stateTarget.ownedBy = null; ++ return null; ++ } + -+ this.setStateVolatile(new TickThreadRunnerState(task, STATE_AWAITING_TICK)); -+ LockSupport.unpark(this.getRunnerThread()); ++ /* MT-Safe */ ++ ++ /** must be deterministic given a key */ ++ protected static int getHash(final long key) { ++ return (int)HashUtil.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; + } + -+ private void forceIdle() { -+ final TickThreadRunnerState state = this.state; -+ if (state.state != STATE_AWAITING_TICK) { -+ throw new IllegalStateException("Cannot replace task in state " + state); -+ } -+ state.stateTarget.ownedBy = null; -+ this.setStateOpaque(new TickThreadRunnerState(null, STATE_IDLE)); -+ // no need to unpark ++ 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 other)) { ++ return false; + } + -+ private boolean takeTask(final TickThreadRunnerState state, final SchedulableTick task) { -+ synchronized (this.scheduler.scheduleLock) { -+ if (this.state != state) { ++ if (this.size() != other.size()) { ++ return false; ++ } ++ ++ final TableEntry[] table = this.getTableAcquire(); ++ ++ for (int i = 0, len = table.length; i < len; ++i) { ++ for (TableEntry curr = getAtIndexOpaque(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; + } -+ this.setStatePlain(new TickThreadRunnerState(task, STATE_EXECUTING_TICK)); -+ this.scheduler.takeTask(this, task); -+ return true; + } + } + -+ private void returnTask(final SchedulableTick task, final boolean reschedule) { -+ synchronized (this.scheduler.scheduleLock) { -+ task.ownedBy = null; ++ return true; ++ } + -+ final SchedulableTick newWait = this.scheduler.returnTask(this, reschedule && task.isScheduled() ? task : null); -+ if (newWait == null) { -+ this.setStatePlain(new TickThreadRunnerState(null, STATE_IDLE)); -+ } else { -+ if (newWait.ownedBy != null) { -+ throw new IllegalStateException("Already owned by another runner"); -+ } -+ newWait.ownedBy = this; -+ this.setStatePlain(new TickThreadRunnerState(newWait, STATE_AWAITING_TICK)); -+ } ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public int hashCode() { ++ /* Make no attempt to deal with concurrent modifications */ ++ int hash = 0; ++ final TableEntry[] table = this.getTableAcquire(); ++ ++ for (int i = 0, len = table.length; i < len; ++i) { ++ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { ++ hash += curr.hashCode(); + } + } + -+ @Override -+ public void run() { -+ this.thread = Thread.currentThread(); ++ return hash; ++ } + -+ main_state_loop: -+ for (;;) { -+ final TickThreadRunnerState startState = this.state; -+ final int startStateType = startState.state; -+ final SchedulableTick startStateTask = startState.stateTarget; ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public String toString() { ++ final StringBuilder builder = new StringBuilder(64); ++ builder.append("SingleWriterMultiReaderHashMap:{"); + -+ if (this.scheduler.halted) { -+ return; -+ } ++ this.forEach((final long key, final V value) -> { ++ builder.append("{key: \"").append(key).append("\", value: \"").append(value).append("\"}"); ++ }); + -+ switch (startStateType) { -+ case STATE_IDLE: { -+ while (this.state.state == STATE_IDLE) { -+ LockSupport.park(); -+ if (this.scheduler.halted) { -+ return; -+ } -+ } -+ continue main_state_loop; -+ } ++ return builder.append('}').toString(); ++ } + -+ case STATE_AWAITING_TICK: { -+ final long deadline = startStateTask.getScheduledStart(); -+ for (;;) { -+ if (this.state != startState) { -+ continue main_state_loop; -+ } -+ final long diff = deadline - System.nanoTime(); -+ if (diff <= 0L) { -+ break; -+ } -+ LockSupport.parkNanos(startState, diff); -+ if (this.scheduler.halted) { -+ return; -+ } -+ } ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public SWMRLong2ObjectHashTable clone() { ++ return new SWMRLong2ObjectHashTable<>(this.getTableAcquire().length, this.loadFactor, this); ++ } + -+ if (!this.takeTask(startState, startStateTask)) { -+ continue main_state_loop; -+ } ++ /** ++ * {@inheritDoc} ++ */ ++ public void forEach(final Consumer> action) { ++ Validate.notNull(action, "Null action"); + -+ // TODO exception handling -+ final boolean reschedule = startStateTask.runTick(); ++ final TableEntry[] table = this.getTableAcquire(); ++ for (int i = 0, len = table.length; i < len; ++i) { ++ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { ++ action.accept(curr); ++ } ++ } ++ } + -+ this.returnTask(startStateTask, reschedule); ++ /** ++ * {@inheritDoc} ++ */ ++ public void forEach(final BiLongObjectConsumer action) { ++ Validate.notNull(action, "Null action"); + -+ continue main_state_loop; -+ } ++ final TableEntry[] table = this.getTableAcquire(); ++ for (int i = 0, len = table.length; i < len; ++i) { ++ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { ++ final V value = curr.getValueAcquire(); + -+ case STATE_EXECUTING_TICK: { -+ throw new IllegalStateException("Tick execution must be set by runner thread, not by any other thread"); -+ } ++ action.accept(curr.key, value); ++ } ++ } ++ } + -+ default: { -+ throw new IllegalStateException("Unknown state: " + startState); -+ } -+ } ++ /** ++ * 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[] table = this.getTableAcquire(); ++ for (int i = 0, len = table.length; i < len; ++i) { ++ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { ++ action.accept(curr.key); + } + } + } -+} -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedSortedSet.java b/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedSortedSet.java -new file mode 100644 -index 0000000000000000000000000000000000000000..212bc9ae2fc7d37d4a089a2921b00de1e97f7cc1 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedSortedSet.java -@@ -0,0 +1,272 @@ -+package ca.spottedleaf.concurrentutil.set; + -+import java.util.Comparator; -+import java.util.Iterator; -+import java.util.NoSuchElementException; ++ /** ++ * 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 action) { ++ Validate.notNull(action, "Null action"); + -+public final class LinkedSortedSet implements Iterable { ++ final TableEntry[] table = this.getTableAcquire(); ++ for (int i = 0, len = table.length; i < len; ++i) { ++ for (TableEntry curr = getAtIndexOpaque(table, i); curr != null; curr = curr.getNextOpaque()) { ++ final V value = curr.getValueAcquire(); + -+ public final Comparator comparator; ++ action.accept(value); ++ } ++ } ++ } + -+ protected Link head; -+ protected Link tail; ++ /** ++ * {@inheritDoc} ++ */ ++ public V get(final long key) { ++ final TableEntry entry = this.getEntryForOpaque(key); ++ return entry == null ? null : entry.getValueAcquire(); ++ } + -+ public LinkedSortedSet() { -+ this((Comparator)Comparator.naturalOrder()); ++ /** ++ * {@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; + } + -+ public LinkedSortedSet(final Comparator comparator) { -+ this.comparator = comparator; ++ /** ++ * {@inheritDoc} ++ */ ++ public V getOrDefault(final long key, final V defaultValue) { ++ final TableEntry entry = this.getEntryForOpaque(key); ++ ++ return entry == null ? defaultValue : entry.getValueAcquire(); + } + -+ public void clear() { -+ this.head = this.tail = null; ++ /** ++ * {@inheritDoc} ++ */ ++ public int size() { ++ return this.getSizeAcquire(); + } + ++ /** ++ * {@inheritDoc} ++ */ + public boolean isEmpty() { -+ return this.head == null; ++ return this.getSizeAcquire() == 0; + } + -+ public E first() { -+ final Link head = this.head; -+ return head == null ? null : head.element; -+ } ++ /* Non-MT-Safe */ + -+ public E last() { -+ final Link tail = this.tail; -+ return tail == null ? null : tail.element; -+ } ++ protected int threshold; + -+ public boolean containsFirst(final E element) { -+ final Comparator comparator = this.comparator; -+ for (Link curr = this.head; curr != null; curr = curr.next) { -+ if (comparator.compare(element, curr.element) == 0) { -+ return true; -+ } ++ protected final void checkResize(final int minCapacity) { ++ if (minCapacity <= this.threshold || this.threshold < 0) { ++ return; + } -+ return false; -+ } + -+ public boolean containsLast(final E element) { -+ final Comparator comparator = this.comparator; -+ for (Link curr = this.tail; curr != null; curr = curr.prev) { -+ if (comparator.compare(element, curr.element) == 0) { -+ return true; ++ final TableEntry[] 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; + } -+ return false; -+ } + -+ private void removeNode(final Link node) { -+ final Link prev = node.prev; -+ final Link next = node.next; ++ //noinspection unchecked ++ final TableEntry[] newTable = new TableEntry[newCapacity]; ++ final int indexMask = newCapacity - 1; + -+ // help GC -+ node.element = null; -+ node.prev = null; -+ node.next = null; ++ for (int i = 0, len = table.length; i < len; ++i) { ++ for (TableEntry entry = table[i]; entry != null; entry = entry.getNextPlain()) { ++ final long key = entry.key; ++ final int hash = SWMRLong2ObjectHashTable.getHash(key); ++ final int index = hash & indexMask; + -+ if (prev == null) { -+ this.head = next; -+ } else { -+ prev.next = next; ++ /* we need to create a new entry since there could be reading threads */ ++ final TableEntry insert = new TableEntry<>(key, entry.getValuePlain()); ++ ++ final TableEntry prev = newTable[index]; ++ ++ newTable[index] = insert; ++ insert.setNextPlain(prev); ++ } + } + -+ if (next == null) { -+ this.tail = prev; ++ if (newCapacity == MAXIMUM_CAPACITY) { ++ this.threshold = -1; /* No more resizing */ + } else { -+ next.prev = prev; ++ this.threshold = getTargetCapacity(newCapacity, this.loadFactor); + } ++ this.setTableRelease(newTable); /* use release to publish entries in table */ + } + -+ public boolean remove(final Link link) { -+ if (link.element == null) { -+ return false; -+ } -+ -+ this.removeNode(link); -+ return true; -+ } ++ protected final int addToSize(final int num) { ++ final int newSize = this.getSizePlain() + num; + -+ public boolean removeFirst(final E element) { -+ final Comparator comparator = this.comparator; -+ for (Link curr = this.head; curr != null; curr = curr.next) { -+ if (comparator.compare(element, curr.element) == 0) { -+ this.removeNode(curr); -+ return true; -+ } -+ } -+ return false; -+ } ++ this.setSizeOpaque(newSize); ++ this.checkResize(newSize); + -+ public boolean removeLast(final E element) { -+ final Comparator comparator = this.comparator; -+ for (Link curr = this.tail; curr != null; curr = curr.prev) { -+ if (comparator.compare(element, curr.element) == 0) { -+ this.removeNode(curr); -+ return true; -+ } -+ } -+ return false; ++ return newSize; + } + -+ @Override -+ public Iterator iterator() { -+ return new Iterator<>() { -+ private Link next = LinkedSortedSet.this.head; ++ protected final int removeFromSize(final int num) { ++ final int newSize = this.getSizePlain() - num; + -+ @Override -+ public boolean hasNext() { -+ return this.next != null; -+ } ++ this.setSizeOpaque(newSize); + -+ @Override -+ public E next() { -+ final Link next = this.next; -+ if (next == null) { -+ throw new NoSuchElementException(); -+ } -+ this.next = next.next; -+ return next.element; -+ } -+ }; ++ return newSize; + } + -+ public E pollFirst() { -+ final Link head = this.head; ++ protected final V put(final long key, final V value, final boolean onlyIfAbsent) { ++ final TableEntry[] table = this.getTablePlain(); ++ final int hash = SWMRLong2ObjectHashTable.getHash(key); ++ final int index = hash & (table.length - 1); ++ ++ final TableEntry head = table[index]; + if (head == null) { ++ final TableEntry insert = new TableEntry<>(key, value); ++ setAtIndexRelease(table, index, insert); ++ this.addToSize(1); + return null; + } + -+ final E ret = head.element; -+ final Link next = head.next; ++ for (TableEntry curr = head;;) { ++ if (key == curr.key) { ++ if (onlyIfAbsent) { ++ return curr.getValuePlain(); ++ } + -+ // unlink head -+ this.head = next; -+ if (next == null) { -+ this.tail = null; -+ } else { -+ next.prev = null; -+ } ++ final V currVal = curr.getValuePlain(); ++ curr.setValueRelease(value); ++ return currVal; ++ } + -+ // help GC -+ head.element = null; -+ head.next = null; ++ final TableEntry next = curr.getNextPlain(); ++ if (next != null) { ++ curr = next; ++ continue; ++ } + -+ return ret; -+ } ++ final TableEntry insert = new TableEntry<>(key, value); + -+ public E pollLast() { -+ final Link tail = this.tail; -+ if (tail == null) { ++ curr.setNextRelease(insert); ++ this.addToSize(1); + return null; + } ++ } + -+ final E ret = tail.element; -+ final Link prev = tail.prev; ++ /** ++ * {@inheritDoc} ++ */ ++ public V put(final long key, final V value) { ++ Validate.notNull(value, "Null value"); + -+ // unlink tail -+ this.tail = prev; -+ if (prev == null) { -+ this.head = null; -+ } else { -+ prev.next = null; -+ } ++ return this.put(key, value, false); ++ } + -+ // help GC -+ tail.element = null; -+ tail.prev = null; ++ /** ++ * {@inheritDoc} ++ */ ++ public V putIfAbsent(final long key, final V value) { ++ Validate.notNull(value, "Null value"); + -+ return ret; ++ return this.put(key, value, true); + } + -+ public Link addLast(final E element) { -+ final Comparator comparator = this.comparator; ++ protected final V remove(final long key, final int hash) { ++ final TableEntry[] table = this.getTablePlain(); ++ final int index = (table.length - 1) & hash; + -+ Link curr = this.tail; -+ if (curr != null) { -+ int compare; ++ final TableEntry head = table[index]; ++ if (head == null) { ++ return null; ++ } + -+ while ((compare = comparator.compare(element, curr.element)) < 0) { -+ Link prev = curr; -+ curr = curr.prev; -+ if (curr != null) { -+ continue; -+ } -+ return this.head = prev.prev = new Link<>(element, null, prev); -+ } ++ if (head.key == key) { ++ setAtIndexRelease(table, index, head.getNextPlain()); ++ this.removeFromSize(1); + -+ if (compare != 0) { -+ // insert after curr -+ final Link next = curr.next; -+ final Link insert = new Link<>(element, curr, next); -+ curr.next = insert; ++ return head.getValuePlain(); ++ } + -+ if (next == null) { -+ this.tail = insert; -+ } else { -+ next.prev = insert; -+ } -+ return insert; -+ } ++ for (TableEntry curr = head.getNextPlain(), prev = head; curr != null; prev = curr, curr = curr.getNextPlain()) { ++ if (key == curr.key) { ++ prev.setNextRelease(curr.getNextPlain()); ++ this.removeFromSize(1); + -+ return null; -+ } else { -+ return this.head = this.tail = new Link<>(element); ++ return curr.getValuePlain(); ++ } + } ++ ++ return null; + } + -+ public Link addFirst(final E element) { -+ final Comparator comparator = this.comparator; ++ protected final V remove(final long key, final int hash, final V expect) { ++ final TableEntry[] table = this.getTablePlain(); ++ final int index = (table.length - 1) & hash; ++ ++ final TableEntry head = table[index]; ++ if (head == null) { ++ return null; ++ } + -+ Link curr = this.head; -+ if (curr != null) { -+ int compare; ++ if (head.key == key) { ++ final V val = head.value; ++ if (val == expect || val.equals(expect)) { ++ setAtIndexRelease(table, index, head.getNextPlain()); ++ this.removeFromSize(1); + -+ while ((compare = comparator.compare(element, curr.element)) > 0) { -+ Link prev = curr; -+ curr = curr.next; -+ if (curr != null) { -+ continue; -+ } -+ return this.tail = prev.next = new Link<>(element, prev, null); ++ return head.getValuePlain(); ++ } else { ++ return null; + } ++ } + -+ if (compare != 0) { -+ // insert before curr -+ final Link prev = curr.prev; -+ final Link insert = new Link<>(element, prev, curr); -+ curr.prev = insert; ++ for (TableEntry curr = head.getNextPlain(), prev = head; curr != null; prev = curr, curr = curr.getNextPlain()) { ++ if (key == curr.key) { ++ final V val = curr.value; ++ if (val == expect || val.equals(expect)) { ++ prev.setNextRelease(curr.getNextPlain()); ++ this.removeFromSize(1); + -+ if (prev == null) { -+ this.head = insert; ++ return curr.getValuePlain(); + } else { -+ prev.next = insert; ++ return null; + } -+ return insert; + } -+ -+ return null; -+ } else { -+ return this.head = this.tail = new Link<>(element); + } ++ ++ return null; + } + -+ public static final class Link { -+ private E element; -+ private Link prev; -+ private Link next; ++ /** ++ * {@inheritDoc} ++ */ ++ public V remove(final long key) { ++ return this.remove(key, SWMRLong2ObjectHashTable.getHash(key)); ++ } + -+ private Link() {} ++ public boolean remove(final long key, final V expect) { ++ return this.remove(key, SWMRLong2ObjectHashTable.getHash(key), expect) != null; ++ } + -+ private Link(final E element) { -+ this.element = element; -+ } ++ /** ++ * {@inheritDoc} ++ */ ++ public void putAll(final SWMRLong2ObjectHashTable map) { ++ Validate.notNull(map, "Null map"); + -+ private Link(final E element, final Link prev, final Link next) { -+ this.element = element; -+ this.prev = prev; -+ this.next = next; -+ } ++ final int size = map.size(); ++ this.checkResize(Math.max(this.getSizePlain() + size/2, size)); /* preemptively resize */ ++ map.forEach(this::put); + } -+} -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; ++ /** ++ * {@inheritDoc} ++ *

    ++ * 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. ++ *

    ++ */ ++ public void clear() { ++ Arrays.fill(this.getTablePlain(), null); ++ this.setSizeRelease(0); ++ } + -+public final class ArrayUtil { ++ public static final class TableEntry { + -+ public static final VarHandle BOOLEAN_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(boolean[].class); ++ protected static final VarHandle TABLE_ENTRY_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(TableEntry[].class); + -+ public static final VarHandle BYTE_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(byte[].class); ++ protected final long key; ++ protected V value; + -+ public static final VarHandle SHORT_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(short[].class); ++ protected TableEntry next; + -+ public static final VarHandle INT_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(int[].class); ++ 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); + -+ public static final VarHandle LONG_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(long[].class); ++ /* value */ + -+ public static final VarHandle OBJECT_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(Object[].class); ++ protected final V getValuePlain() { ++ //noinspection unchecked ++ return (V)VALUE_HANDLE.get(this); ++ } + -+ private ArrayUtil() { -+ throw new RuntimeException(); -+ } ++ protected final V getValueAcquire() { ++ //noinspection unchecked ++ return (V)VALUE_HANDLE.getAcquire(this); ++ } + -+ /* byte array */ ++ protected final void setValueRelease(final V to) { ++ VALUE_HANDLE.setRelease(this, to); ++ } + -+ public static byte getPlain(final byte[] array, final int index) { -+ return (byte)BYTE_ARRAY_HANDLE.get(array, index); -+ } ++ /* next */ + -+ public static byte getOpaque(final byte[] array, final int index) { -+ return (byte)BYTE_ARRAY_HANDLE.getOpaque(array, index); -+ } ++ protected final TableEntry getNextPlain() { ++ //noinspection unchecked ++ return (TableEntry)NEXT_HANDLE.get(this); ++ } + -+ public static byte getAcquire(final byte[] array, final int index) { -+ return (byte)BYTE_ARRAY_HANDLE.getAcquire(array, index); -+ } ++ protected final TableEntry getNextOpaque() { ++ //noinspection unchecked ++ return (TableEntry)NEXT_HANDLE.getOpaque(this); ++ } + -+ public static byte getVolatile(final byte[] array, final int index) { -+ return (byte)BYTE_ARRAY_HANDLE.getVolatile(array, index); -+ } ++ protected final void setNextPlain(final TableEntry next) { ++ NEXT_HANDLE.set(this, next); ++ } + -+ public static void setPlain(final byte[] array, final int index, final byte value) { -+ BYTE_ARRAY_HANDLE.set(array, index, value); -+ } ++ protected final void setNextRelease(final TableEntry next) { ++ NEXT_HANDLE.setRelease(this, next); ++ } + -+ public static void setOpaque(final byte[] array, final int index, final byte value) { -+ BYTE_ARRAY_HANDLE.setOpaque(array, index, value); -+ } ++ protected TableEntry(final long key, final V value) { ++ this.key = key; ++ this.value = value; ++ } + -+ public static void setRelease(final byte[] array, final int index, final byte value) { -+ BYTE_ARRAY_HANDLE.setRelease(array, index, value); -+ } ++ public long getKey() { ++ return this.key; ++ } + -+ public static void setVolatile(final byte[] array, final int index, final byte value) { -+ BYTE_ARRAY_HANDLE.setVolatile(array, index, value); ++ public V getValue() { ++ return this.getValueAcquire(); ++ } + } ++} +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/scheduler/SchedulerThreadPool.java b/src/main/java/ca/spottedleaf/concurrentutil/scheduler/SchedulerThreadPool.java +new file mode 100644 +index 0000000000000000000000000000000000000000..85e6ef636d435a0ee4bf3e0760b0c87422c520a1 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/scheduler/SchedulerThreadPool.java +@@ -0,0 +1,564 @@ ++package ca.spottedleaf.concurrentutil.scheduler; + -+ public static void setVolatileContended(final byte[] array, final int index, final byte param) { -+ int failures = 0; ++import ca.spottedleaf.concurrentutil.set.LinkedSortedSet; ++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import ca.spottedleaf.concurrentutil.util.TimeUtil; ++import java.lang.invoke.VarHandle; ++import java.util.BitSet; ++import java.util.Comparator; ++import java.util.PriorityQueue; ++import java.util.concurrent.ThreadFactory; ++import java.util.concurrent.atomic.AtomicInteger; ++import java.util.concurrent.atomic.AtomicLong; ++import java.util.concurrent.locks.LockSupport; ++import java.util.function.BooleanSupplier; + -+ for (byte curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } ++/** ++ * @deprecated To be replaced ++ */ ++@Deprecated ++public class SchedulerThreadPool { + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) { -+ return; -+ } ++ public static final long DEADLINE_NOT_SET = Long.MIN_VALUE; ++ ++ private static final Comparator TICK_COMPARATOR_BY_TIME = (final SchedulableTick t1, final SchedulableTick t2) -> { ++ final int timeCompare = TimeUtil.compareTimes(t1.scheduledStart, t2.scheduledStart); ++ if (timeCompare != 0) { ++ return timeCompare; + } -+ } + -+ 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); -+ } ++ return Long.compare(t1.id, t2.id); ++ }; + -+ public static byte getAndAddVolatile(final byte[] array, final int index, final byte param) { -+ return (byte)BYTE_ARRAY_HANDLE.getAndAdd(array, index, param); -+ } ++ private final TickThreadRunner[] runners; ++ private final Thread[] threads; ++ private final LinkedSortedSet awaiting = new LinkedSortedSet<>(TICK_COMPARATOR_BY_TIME); ++ private final PriorityQueue queued = new PriorityQueue<>(TICK_COMPARATOR_BY_TIME); ++ private final BitSet idleThreads; + -+ public static byte getAndAndVolatile(final byte[] array, final int index, final byte param) { -+ return (byte)BYTE_ARRAY_HANDLE.getAndBitwiseAnd(array, index, param); -+ } ++ private final Object scheduleLock = new Object(); + -+ public static byte getAndOrVolatile(final byte[] array, final int index, final byte param) { -+ return (byte)BYTE_ARRAY_HANDLE.getAndBitwiseOr(array, index, param); -+ } ++ private volatile boolean halted; + -+ public static byte getAndXorVolatile(final byte[] array, final int index, final byte param) { -+ return (byte)BYTE_ARRAY_HANDLE.getAndBitwiseXor(array, index, param); -+ } ++ /** ++ * Creates, but does not start, a scheduler thread pool with the specified number of threads ++ * created using the specified thread factory. ++ * @param threads Specified number of threads ++ * @param threadFactory Specified thread factory ++ * @see #start() ++ */ ++ public SchedulerThreadPool(final int threads, final ThreadFactory threadFactory) { ++ final BitSet idleThreads = new BitSet(threads); ++ for (int i = 0; i < threads; ++i) { ++ idleThreads.set(i); ++ } ++ this.idleThreads = idleThreads; + -+ public static byte getAndSetVolatile(final byte[] array, final int index, final byte param) { -+ return (byte)BYTE_ARRAY_HANDLE.getAndSet(array, index, param); -+ } ++ final TickThreadRunner[] runners = new TickThreadRunner[threads]; ++ final Thread[] t = new Thread[threads]; ++ for (int i = 0; i < threads; ++i) { ++ runners[i] = new TickThreadRunner(i, this); ++ t[i] = threadFactory.newThread(runners[i]); ++ } + -+ 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); ++ this.threads = t; ++ this.runners = runners; + } + -+ 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; -+ } ++ /** ++ * Starts the threads in this pool. ++ */ ++ public void start() { ++ for (final Thread thread : this.threads) { ++ thread.start(); + } + } + -+ 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; ++ /** ++ * Attempts to prevent further execution of tasks, optionally waiting for the scheduler threads to die. ++ * ++ * @param sync Whether to wait for the scheduler threads to die. ++ * @param maxWaitNS The maximum time, in ns, to wait for the scheduler threads to die. ++ * @return {@code true} if sync was false, or if sync was true and the scheduler threads died before the timeout. ++ * Otherwise, returns {@code false} if the time elapsed exceeded the maximum wait time. ++ */ ++ public boolean halt(final boolean sync, final long maxWaitNS) { ++ this.halted = true; ++ for (final Thread thread : this.threads) { ++ // force response to halt ++ LockSupport.unpark(thread); ++ } ++ final long time = System.nanoTime(); ++ if (sync) { ++ // start at 10 * 0.5ms -> 5ms ++ for (long failures = 9L;; failures = ConcurrentUtil.linearLongBackoff(failures, 500_000L, 50_000_000L)) { ++ boolean allDead = true; ++ for (final Thread thread : this.threads) { ++ if (thread.isAlive()) { ++ allDead = false; ++ break; ++ } ++ } ++ if (allDead) { ++ return true; ++ } ++ if ((System.nanoTime() - time) >= maxWaitNS) { ++ return false; ++ } + } + } -+ } -+ -+ 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(); -+ } ++ return true; ++ } + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (byte) (curr | param)))) { -+ return curr; -+ } -+ } ++ /** ++ * Returns an array of the underlying scheduling threads. ++ */ ++ public Thread[] getThreads() { ++ return this.threads.clone(); + } + -+ public static byte getAndXorVolatileContended(final byte[] array, final int index, final byte param) { -+ int failures = 0; ++ private void insertFresh(final SchedulableTick task) { ++ final TickThreadRunner[] runners = this.runners; + -+ for (byte curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } ++ final int firstIdleThread = this.idleThreads.nextSetBit(0); + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (byte) (curr ^ param)))) { -+ return curr; -+ } ++ if (firstIdleThread != -1) { ++ // push to idle thread ++ this.idleThreads.clear(firstIdleThread); ++ final TickThreadRunner runner = runners[firstIdleThread]; ++ task.awaitingLink = this.awaiting.addLast(task); ++ runner.acceptTask(task); ++ return; + } -+ } -+ -+ 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(); -+ } ++ // try to replace the last awaiting task ++ final SchedulableTick last = this.awaiting.last(); + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) { -+ return curr; -+ } -+ } -+ } ++ if (last != null && TICK_COMPARATOR_BY_TIME.compare(task, last) < 0) { ++ // need to replace the last task ++ this.awaiting.pollLast(); ++ last.awaitingLink = null; ++ task.awaitingLink = this.awaiting.addLast(task); ++ // need to add task to queue to be picked up later ++ this.queued.add(last); + -+ /* short array */ ++ final TickThreadRunner runner = last.ownedBy; ++ runner.replaceTask(task); + -+ public static short getPlain(final short[] array, final int index) { -+ return (short)SHORT_ARRAY_HANDLE.get(array, index); -+ } ++ return; ++ } + -+ public static short getOpaque(final short[] array, final int index) { -+ return (short)SHORT_ARRAY_HANDLE.getOpaque(array, index); ++ // add to queue, will be picked up later ++ this.queued.add(task); + } + -+ public static short getAcquire(final short[] array, final int index) { -+ return (short)SHORT_ARRAY_HANDLE.getAcquire(array, index); ++ private void takeTask(final TickThreadRunner runner, final SchedulableTick tick) { ++ if (!this.awaiting.remove(tick.awaitingLink)) { ++ throw new IllegalStateException("Task is not in awaiting"); ++ } ++ tick.awaitingLink = null; + } + -+ public static short getVolatile(final short[] array, final int index) { -+ return (short)SHORT_ARRAY_HANDLE.getVolatile(array, index); -+ } ++ private SchedulableTick returnTask(final TickThreadRunner runner, final SchedulableTick reschedule) { ++ if (reschedule != null) { ++ this.queued.add(reschedule); ++ } ++ final SchedulableTick ret = this.queued.poll(); ++ if (ret == null) { ++ this.idleThreads.set(runner.id); ++ } else { ++ ret.awaitingLink = this.awaiting.addLast(ret); ++ } + -+ public static void setPlain(final short[] array, final int index, final short value) { -+ SHORT_ARRAY_HANDLE.set(array, index, value); ++ return ret; + } + -+ public static void setOpaque(final short[] array, final int index, final short value) { -+ SHORT_ARRAY_HANDLE.setOpaque(array, index, value); -+ } ++ /** ++ * Schedules the specified task to be executed on this thread pool. ++ * @param task Specified task ++ * @throws IllegalStateException If the task is already scheduled ++ * @see SchedulableTick ++ */ ++ public void schedule(final SchedulableTick task) { ++ synchronized (this.scheduleLock) { ++ if (!task.tryMarkScheduled()) { ++ throw new IllegalStateException("Task " + task + " is already scheduled or cancelled"); ++ } + -+ public static void setRelease(final short[] array, final int index, final short value) { -+ SHORT_ARRAY_HANDLE.setRelease(array, index, value); -+ } ++ task.schedulerOwnedBy = this; + -+ public static void setVolatile(final short[] array, final int index, final short value) { -+ SHORT_ARRAY_HANDLE.setVolatile(array, index, value); ++ this.insertFresh(task); ++ } + } + -+ 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(); ++ /** ++ * Updates the tasks scheduled start to the maximum of its current scheduled start and the specified ++ * new start. If the task is not scheduled, returns {@code false}. Otherwise, returns whether the ++ * scheduled start was updated. Undefined behavior of the specified task is scheduled in another executor. ++ * @param task Specified task ++ * @param newStart Specified new start ++ */ ++ public boolean updateTickStartToMax(final SchedulableTick task, final long newStart) { ++ synchronized (this.scheduleLock) { ++ if (TimeUtil.compareTimes(newStart, task.getScheduledStart()) <= 0) { ++ return false; + } -+ -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) { -+ return; ++ if (this.queued.remove(task)) { ++ task.setScheduledStart(newStart); ++ this.queued.add(task); ++ return true; + } -+ } -+ } ++ if (task.awaitingLink != null) { ++ this.awaiting.remove(task.awaitingLink); ++ task.awaitingLink = null; + -+ 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); -+ } ++ // re-queue task ++ task.setScheduledStart(newStart); ++ this.queued.add(task); + -+ public static short getAndAddVolatile(final short[] array, final int index, final short param) { -+ return (short)SHORT_ARRAY_HANDLE.getAndAdd(array, index, param); -+ } ++ // now we need to replace the task the runner was waiting for ++ final TickThreadRunner runner = task.ownedBy; ++ final SchedulableTick replace = this.queued.poll(); + -+ public static short getAndAndVolatile(final short[] array, final int index, final short param) { -+ return (short)SHORT_ARRAY_HANDLE.getAndBitwiseAnd(array, index, param); -+ } ++ // replace cannot be null, since we have added a task to queued ++ if (replace != task) { ++ runner.replaceTask(replace); ++ } + -+ public static short getAndOrVolatile(final short[] array, final int index, final short param) { -+ return (short)SHORT_ARRAY_HANDLE.getAndBitwiseOr(array, index, param); -+ } ++ return true; ++ } + -+ public static short getAndXorVolatile(final short[] array, final int index, final short param) { -+ return (short)SHORT_ARRAY_HANDLE.getAndBitwiseXor(array, index, param); ++ return false; ++ } + } + -+ public static short getAndSetVolatile(final short[] array, final int index, final short param) { -+ return (short)SHORT_ARRAY_HANDLE.getAndSet(array, index, param); -+ } ++ /** ++ * Returns {@code null} if the task is not scheduled, returns {@code TRUE} if the task was cancelled ++ * and was queued to execute, returns {@code FALSE} if the task was cancelled but was executing. ++ */ ++ public Boolean tryRetire(final SchedulableTick task) { ++ if (task.schedulerOwnedBy != this) { ++ return null; ++ } + -+ 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); -+ } ++ synchronized (this.scheduleLock) { ++ if (this.queued.remove(task)) { ++ // cancelled, and no runner owns it - so return ++ return Boolean.TRUE; ++ } ++ if (task.awaitingLink != null) { ++ this.awaiting.remove(task.awaitingLink); ++ task.awaitingLink = null; ++ // here we need to replace the task the runner was waiting for ++ final TickThreadRunner runner = task.ownedBy; ++ final SchedulableTick replace = this.queued.poll(); + -+ public static short getAndAddVolatileContended(final short[] array, final int index, final short param) { -+ int failures = 0; ++ if (replace == null) { ++ // nothing to replace with, set to idle ++ this.idleThreads.set(runner.id); ++ runner.forceIdle(); ++ } else { ++ runner.replaceTask(replace); ++ } + -+ for (short curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); ++ return Boolean.TRUE; + } + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (short) (curr + param)))) { -+ return curr; -+ } ++ // could not find it in queue ++ return task.tryMarkCancelled() ? Boolean.FALSE : null; + } + } + -+ 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; -+ } -+ } ++ /** ++ * Indicates that intermediate tasks are available to be executed by the task. ++ *

    ++ * Note: currently a no-op ++ *

    ++ * @param task The specified task ++ * @see SchedulableTick ++ */ ++ public void notifyTasks(final SchedulableTick task) { ++ // Not implemented + } + -+ public static short getAndOrVolatileContended(final short[] array, final int index, final short param) { -+ int failures = 0; ++ /** ++ * Represents a tickable task that can be scheduled into a {@link SchedulerThreadPool}. ++ *

    ++ * A tickable task is expected to run on a fixed interval, which is determined by ++ * the {@link SchedulerThreadPool}. ++ *

    ++ *

    ++ * A tickable task can have intermediate tasks that can be executed before its tick method is ran. Instead of ++ * the {@link SchedulerThreadPool} parking in-between ticks, the scheduler will instead drain ++ * intermediate tasks from scheduled tasks. The parsing of intermediate tasks allows the scheduler to take ++ * advantage of downtime to reduce the intermediate task load from tasks once they begin ticking. ++ *

    ++ *

    ++ * It is guaranteed that {@link #runTick()} and {@link #runTasks(BooleanSupplier)} are never ++ * invoked in parallel. ++ * It is required that when intermediate tasks are scheduled, that {@link SchedulerThreadPool#notifyTasks(SchedulableTick)} ++ * is invoked for any scheduled task - otherwise, {@link #runTasks(BooleanSupplier)} may not be invoked to ++ * parse intermediate tasks. ++ *

    ++ * @deprecated To be replaced ++ */ ++ @Deprecated ++ public static abstract class SchedulableTick { ++ private static final AtomicLong ID_GENERATOR = new AtomicLong(); ++ public final long id = ID_GENERATOR.getAndIncrement(); + -+ for (short curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } ++ private static final int SCHEDULE_STATE_NOT_SCHEDULED = 0; ++ private static final int SCHEDULE_STATE_SCHEDULED = 1; ++ private static final int SCHEDULE_STATE_CANCELLED = 2; + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (short) (curr | param)))) { -+ return curr; -+ } -+ } -+ } ++ private final AtomicInteger scheduled = new AtomicInteger(); ++ private SchedulerThreadPool schedulerOwnedBy; ++ private long scheduledStart = DEADLINE_NOT_SET; ++ private TickThreadRunner ownedBy; + -+ public static short getAndXorVolatileContended(final short[] array, final int index, final short param) { -+ int failures = 0; ++ private LinkedSortedSet.Link awaitingLink; + -+ for (short curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } ++ private boolean tryMarkScheduled() { ++ return this.scheduled.compareAndSet(SCHEDULE_STATE_NOT_SCHEDULED, SCHEDULE_STATE_SCHEDULED); ++ } + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (short) (curr ^ param)))) { -+ return curr; -+ } ++ private boolean tryMarkCancelled() { ++ return this.scheduled.compareAndSet(SCHEDULE_STATE_SCHEDULED, SCHEDULE_STATE_CANCELLED); + } -+ } + -+ public static short getAndSetVolatileContended(final short[] array, final int index, final short param) { -+ int failures = 0; ++ private boolean isScheduled() { ++ return this.scheduled.get() == SCHEDULE_STATE_SCHEDULED; ++ } + -+ for (short curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } ++ protected final long getScheduledStart() { ++ return this.scheduledStart; ++ } + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) { -+ return curr; -+ } ++ /** ++ * If this task is scheduled, then this may only be invoked during {@link #runTick()}, ++ * and {@link #runTasks(BooleanSupplier)} ++ */ ++ protected final void setScheduledStart(final long value) { ++ this.scheduledStart = value; + } -+ } + -+ /* int array */ ++ /** ++ * Executes the tick. ++ *

    ++ * It is the callee's responsibility to invoke {@link #setScheduledStart(long)} to adjust the start of ++ * the next tick. ++ *

    ++ * @return {@code true} if the task should continue to be scheduled, {@code false} otherwise. ++ */ ++ public abstract boolean runTick(); + -+ public static int getPlain(final int[] array, final int index) { -+ return (int)INT_ARRAY_HANDLE.get(array, index); -+ } ++ /** ++ * Returns whether this task has any intermediate tasks that can be executed. ++ */ ++ public abstract boolean hasTasks(); + -+ public static int getOpaque(final int[] array, final int index) { -+ return (int)INT_ARRAY_HANDLE.getOpaque(array, index); -+ } ++ /** ++ * Returns {@code null} if this task should not be scheduled, otherwise returns ++ * {@code Boolean.TRUE} if there are more intermediate tasks to execute and ++ * {@code Boolean.FALSE} if there are no more intermediate tasks to execute. ++ */ ++ public abstract Boolean runTasks(final BooleanSupplier canContinue); + -+ public static int getAcquire(final int[] array, final int index) { -+ return (int)INT_ARRAY_HANDLE.getAcquire(array, index); ++ @Override ++ public String toString() { ++ return "SchedulableTick:{" + ++ "class=" + this.getClass().getName() + "," + ++ "scheduled_state=" + this.scheduled.get() + "," ++ + "}"; ++ } + } + -+ public static int getVolatile(final int[] array, final int index) { -+ return (int)INT_ARRAY_HANDLE.getVolatile(array, index); -+ } ++ private static final class TickThreadRunner implements Runnable { + -+ public static void setPlain(final int[] array, final int index, final int value) { -+ INT_ARRAY_HANDLE.set(array, index, value); -+ } ++ /** ++ * There are no tasks in this thread's runqueue, so it is parked. ++ *

    ++ * stateTarget = null ++ *

    ++ */ ++ private static final int STATE_IDLE = 0; + -+ public static void setOpaque(final int[] array, final int index, final int value) { -+ INT_ARRAY_HANDLE.setOpaque(array, index, value); -+ } ++ /** ++ * The runner is waiting to tick a task, as it has no intermediate tasks to execute. ++ *

    ++ * stateTarget = the task awaiting tick ++ *

    ++ */ ++ private static final int STATE_AWAITING_TICK = 1; + -+ public static void setRelease(final int[] array, final int index, final int value) { -+ INT_ARRAY_HANDLE.setRelease(array, index, value); -+ } ++ /** ++ * The runner is executing a tick for one of the tasks that was in its runqueue. ++ *

    ++ * stateTarget = the task being ticked ++ *

    ++ */ ++ private static final int STATE_EXECUTING_TICK = 2; + -+ public static void setVolatile(final int[] array, final int index, final int value) { -+ INT_ARRAY_HANDLE.setVolatile(array, index, value); -+ } ++ public final int id; ++ public final SchedulerThreadPool scheduler; + -+ public static void setVolatileContended(final int[] array, final int index, final int param) { -+ int failures = 0; ++ private volatile Thread thread; ++ private volatile TickThreadRunnerState state = new TickThreadRunnerState(null, STATE_IDLE); ++ private static final VarHandle STATE_HANDLE = ConcurrentUtil.getVarHandle(TickThreadRunner.class, "state", TickThreadRunnerState.class); + -+ for (int curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } ++ private void setStatePlain(final TickThreadRunnerState state) { ++ STATE_HANDLE.set(this, state); ++ } + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) { -+ return; -+ } ++ private void setStateOpaque(final TickThreadRunnerState state) { ++ STATE_HANDLE.setOpaque(this, state); + } -+ } + -+ 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); -+ } ++ private void setStateVolatile(final TickThreadRunnerState state) { ++ STATE_HANDLE.setVolatile(this, state); ++ } + -+ public static int getAndAddVolatile(final int[] array, final int index, final int param) { -+ return (int)INT_ARRAY_HANDLE.getAndAdd(array, index, param); -+ } ++ private static record TickThreadRunnerState(SchedulableTick stateTarget, int state) {} + -+ public static int getAndAndVolatile(final int[] array, final int index, final int param) { -+ return (int)INT_ARRAY_HANDLE.getAndBitwiseAnd(array, index, param); -+ } ++ public TickThreadRunner(final int id, final SchedulerThreadPool scheduler) { ++ this.id = id; ++ this.scheduler = scheduler; ++ } + -+ public static int getAndOrVolatile(final int[] array, final int index, final int param) { -+ return (int)INT_ARRAY_HANDLE.getAndBitwiseOr(array, index, param); -+ } ++ private Thread getRunnerThread() { ++ return this.thread; ++ } + -+ public static int getAndXorVolatile(final int[] array, final int index, final int param) { -+ return (int)INT_ARRAY_HANDLE.getAndBitwiseXor(array, index, param); -+ } ++ private void acceptTask(final SchedulableTick task) { ++ if (task.ownedBy != null) { ++ throw new IllegalStateException("Already owned by another runner"); ++ } ++ task.ownedBy = this; ++ final TickThreadRunnerState state = this.state; ++ if (state.state != STATE_IDLE) { ++ throw new IllegalStateException("Cannot accept task in state " + state); ++ } ++ this.setStateVolatile(new TickThreadRunnerState(task, STATE_AWAITING_TICK)); ++ LockSupport.unpark(this.getRunnerThread()); ++ } + -+ public static int getAndSetVolatile(final int[] array, final int index, final int param) { -+ return (int)INT_ARRAY_HANDLE.getAndSet(array, index, param); -+ } ++ private void replaceTask(final SchedulableTick task) { ++ final TickThreadRunnerState state = this.state; ++ if (state.state != STATE_AWAITING_TICK) { ++ throw new IllegalStateException("Cannot replace task in state " + state); ++ } ++ if (task.ownedBy != null) { ++ throw new IllegalStateException("Already owned by another runner"); ++ } ++ task.ownedBy = this; + -+ 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); -+ } ++ state.stateTarget.ownedBy = null; + -+ public static int getAndAddVolatileContended(final int[] array, final int index, final int param) { -+ int failures = 0; ++ this.setStateVolatile(new TickThreadRunnerState(task, STATE_AWAITING_TICK)); ++ LockSupport.unpark(this.getRunnerThread()); ++ } + -+ for (int curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); ++ private void forceIdle() { ++ final TickThreadRunnerState state = this.state; ++ if (state.state != STATE_AWAITING_TICK) { ++ throw new IllegalStateException("Cannot replace task in state " + state); + } ++ state.stateTarget.ownedBy = null; ++ this.setStateOpaque(new TickThreadRunnerState(null, STATE_IDLE)); ++ // no need to unpark ++ } + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (int) (curr + param)))) { -+ return curr; ++ private boolean takeTask(final TickThreadRunnerState state, final SchedulableTick task) { ++ synchronized (this.scheduler.scheduleLock) { ++ if (this.state != state) { ++ return false; ++ } ++ this.setStatePlain(new TickThreadRunnerState(task, STATE_EXECUTING_TICK)); ++ this.scheduler.takeTask(this, task); ++ return true; + } + } -+ } + -+ 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(); -+ } ++ private void returnTask(final SchedulableTick task, final boolean reschedule) { ++ synchronized (this.scheduler.scheduleLock) { ++ task.ownedBy = null; + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (int) (curr & param)))) { -+ return curr; ++ final SchedulableTick newWait = this.scheduler.returnTask(this, reschedule && task.isScheduled() ? task : null); ++ if (newWait == null) { ++ this.setStatePlain(new TickThreadRunnerState(null, STATE_IDLE)); ++ } else { ++ if (newWait.ownedBy != null) { ++ throw new IllegalStateException("Already owned by another runner"); ++ } ++ newWait.ownedBy = this; ++ this.setStatePlain(new TickThreadRunnerState(newWait, STATE_AWAITING_TICK)); ++ } + } + } -+ } + -+ public static int getAndOrVolatileContended(final int[] array, final int index, final int param) { -+ int failures = 0; ++ @Override ++ public void run() { ++ this.thread = Thread.currentThread(); + -+ for (int curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } ++ main_state_loop: ++ for (;;) { ++ final TickThreadRunnerState startState = this.state; ++ final int startStateType = startState.state; ++ final SchedulableTick startStateTask = startState.stateTarget; + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (int) (curr | param)))) { -+ return curr; -+ } -+ } -+ } ++ if (this.scheduler.halted) { ++ return; ++ } + -+ public static int getAndXorVolatileContended(final int[] array, final int index, final int param) { -+ int failures = 0; ++ switch (startStateType) { ++ case STATE_IDLE: { ++ while (this.state.state == STATE_IDLE) { ++ LockSupport.park(); ++ if (this.scheduler.halted) { ++ return; ++ } ++ } ++ continue main_state_loop; ++ } + -+ for (int curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } ++ case STATE_AWAITING_TICK: { ++ final long deadline = startStateTask.getScheduledStart(); ++ for (;;) { ++ if (this.state != startState) { ++ continue main_state_loop; ++ } ++ final long diff = deadline - System.nanoTime(); ++ if (diff <= 0L) { ++ break; ++ } ++ LockSupport.parkNanos(startState, diff); ++ if (this.scheduler.halted) { ++ return; ++ } ++ } + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (int) (curr ^ param)))) { -+ return curr; -+ } -+ } -+ } ++ if (!this.takeTask(startState, startStateTask)) { ++ continue main_state_loop; ++ } + -+ public static int getAndSetVolatileContended(final int[] array, final int index, final int param) { -+ int failures = 0; ++ // TODO exception handling ++ final boolean reschedule = startStateTask.runTick(); + -+ for (int curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } ++ this.returnTask(startStateTask, reschedule); + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) { -+ return curr; ++ continue main_state_loop; ++ } ++ ++ case STATE_EXECUTING_TICK: { ++ throw new IllegalStateException("Tick execution must be set by runner thread, not by any other thread"); ++ } ++ ++ default: { ++ throw new IllegalStateException("Unknown state: " + startState); ++ } ++ } + } + } + } ++} +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedSortedSet.java b/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedSortedSet.java +new file mode 100644 +index 0000000000000000000000000000000000000000..82c4c11b0b564c97ac92bd5f54e3754a7ba95184 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedSortedSet.java +@@ -0,0 +1,270 @@ ++package ca.spottedleaf.concurrentutil.set; + -+ /* long array */ ++import java.util.Comparator; ++import java.util.Iterator; ++import java.util.NoSuchElementException; + -+ public static long getPlain(final long[] array, final int index) { -+ return (long)LONG_ARRAY_HANDLE.get(array, index); -+ } ++public final class LinkedSortedSet implements Iterable { + -+ public static long getOpaque(final long[] array, final int index) { -+ return (long)LONG_ARRAY_HANDLE.getOpaque(array, index); -+ } ++ public final Comparator comparator; ++ ++ private Link head; ++ private Link tail; + -+ public static long getAcquire(final long[] array, final int index) { -+ return (long)LONG_ARRAY_HANDLE.getAcquire(array, index); ++ public LinkedSortedSet() { ++ this((Comparator)Comparator.naturalOrder()); + } + -+ public static long getVolatile(final long[] array, final int index) { -+ return (long)LONG_ARRAY_HANDLE.getVolatile(array, index); ++ public LinkedSortedSet(final Comparator comparator) { ++ this.comparator = comparator; + } + -+ public static void setPlain(final long[] array, final int index, final long value) { -+ LONG_ARRAY_HANDLE.set(array, index, value); ++ public void clear() { ++ this.head = this.tail = null; + } + -+ public static void setOpaque(final long[] array, final int index, final long value) { -+ LONG_ARRAY_HANDLE.setOpaque(array, index, value); ++ public boolean isEmpty() { ++ return this.head == null; + } + -+ public static void setRelease(final long[] array, final int index, final long value) { -+ LONG_ARRAY_HANDLE.setRelease(array, index, value); ++ public E first() { ++ final Link head = this.head; ++ return head == null ? null : head.element; + } + -+ public static void setVolatile(final long[] array, final int index, final long value) { -+ LONG_ARRAY_HANDLE.setVolatile(array, index, value); ++ public E last() { ++ final Link tail = this.tail; ++ return tail == null ? null : tail.element; + } + -+ 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 boolean containsFirst(final E element) { ++ final Comparator comparator = this.comparator; ++ for (Link curr = this.head; curr != null; curr = curr.next) { ++ if (comparator.compare(element, curr.element) == 0) { ++ return true; + } + } ++ return false; + } + -+ 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 boolean containsLast(final E element) { ++ final Comparator comparator = this.comparator; ++ for (Link curr = this.tail; curr != null; curr = curr.prev) { ++ if (comparator.compare(element, curr.element) == 0) { ++ return true; ++ } ++ } ++ return false; + } + -+ public static long getAndAddVolatile(final long[] array, final int index, final long param) { -+ return (long)LONG_ARRAY_HANDLE.getAndAdd(array, index, param); -+ } ++ private void removeNode(final Link node) { ++ final Link prev = node.prev; ++ final Link next = node.next; + -+ public static long getAndAndVolatile(final long[] array, final int index, final long param) { -+ return (long)LONG_ARRAY_HANDLE.getAndBitwiseAnd(array, index, param); -+ } ++ // help GC ++ node.element = null; ++ node.prev = null; ++ node.next = null; + -+ public static long getAndOrVolatile(final long[] array, final int index, final long param) { -+ return (long)LONG_ARRAY_HANDLE.getAndBitwiseOr(array, index, param); -+ } ++ if (prev == null) { ++ this.head = next; ++ } else { ++ prev.next = next; ++ } + -+ public static long getAndXorVolatile(final long[] array, final int index, final long param) { -+ return (long)LONG_ARRAY_HANDLE.getAndBitwiseXor(array, index, param); ++ if (next == null) { ++ this.tail = prev; ++ } else { ++ next.prev = prev; ++ } + } + -+ public static long getAndSetVolatile(final long[] array, final int index, final long param) { -+ return (long)LONG_ARRAY_HANDLE.getAndSet(array, index, param); -+ } ++ public boolean remove(final Link link) { ++ if (link.element == null) { ++ return false; ++ } + -+ 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); ++ this.removeNode(link); ++ return true; + } + -+ 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(); ++ public boolean removeFirst(final E element) { ++ final Comparator comparator = this.comparator; ++ for (Link curr = this.head; curr != null; curr = curr.next) { ++ if (comparator.compare(element, curr.element) == 0) { ++ this.removeNode(curr); ++ return true; + } ++ } ++ return false; ++ } + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (long) (curr + param)))) { -+ return curr; ++ public boolean removeLast(final E element) { ++ final Comparator comparator = this.comparator; ++ for (Link curr = this.tail; curr != null; curr = curr.prev) { ++ if (comparator.compare(element, curr.element) == 0) { ++ this.removeNode(curr); ++ return true; + } + } ++ return false; + } + -+ public static long getAndAndVolatileContended(final long[] array, final int index, final long param) { -+ int failures = 0; ++ @Override ++ public Iterator iterator() { ++ return new Iterator<>() { ++ private Link next = LinkedSortedSet.this.head; + -+ for (long curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); ++ @Override ++ public boolean hasNext() { ++ return this.next != null; + } + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (long) (curr & param)))) { -+ return curr; ++ @Override ++ public E next() { ++ final Link next = this.next; ++ if (next == null) { ++ throw new NoSuchElementException(); ++ } ++ this.next = next.next; ++ return next.element; + } -+ } ++ }; + } + -+ public static long getAndOrVolatileContended(final long[] array, final int index, final long param) { -+ int failures = 0; ++ public E pollFirst() { ++ final Link head = this.head; ++ if (head == null) { ++ return null; ++ } + -+ for (long curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } ++ final E ret = head.element; ++ final Link next = head.next; + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (long) (curr | param)))) { -+ return curr; -+ } ++ // unlink head ++ this.head = next; ++ if (next == null) { ++ this.tail = null; ++ } else { ++ next.prev = null; + } ++ ++ // help GC ++ head.element = null; ++ head.next = null; ++ ++ return ret; + } + -+ public static long getAndXorVolatileContended(final long[] array, final int index, final long param) { -+ int failures = 0; ++ public E pollLast() { ++ final Link tail = this.tail; ++ if (tail == null) { ++ return null; ++ } + -+ for (long curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } ++ final E ret = tail.element; ++ final Link prev = tail.prev; + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (long) (curr ^ param)))) { -+ return curr; -+ } ++ // unlink tail ++ this.tail = prev; ++ if (prev == null) { ++ this.head = null; ++ } else { ++ prev.next = null; + } ++ ++ // help GC ++ tail.element = null; ++ tail.prev = null; ++ ++ return ret; + } + -+ public static long getAndSetVolatileContended(final long[] array, final int index, final long param) { -+ int failures = 0; ++ public Link addLast(final E element) { ++ final Comparator comparator = this.comparator; + -+ for (long curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); ++ Link curr = this.tail; ++ if (curr != null) { ++ int compare; ++ ++ while ((compare = comparator.compare(element, curr.element)) < 0) { ++ Link prev = curr; ++ curr = curr.prev; ++ if (curr != null) { ++ continue; ++ } ++ return this.head = prev.prev = new Link<>(element, null, prev); + } + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) { -+ return curr; ++ if (compare != 0) { ++ // insert after curr ++ final Link next = curr.next; ++ final Link insert = new Link<>(element, curr, next); ++ curr.next = insert; ++ ++ if (next == null) { ++ this.tail = insert; ++ } else { ++ next.prev = insert; ++ } ++ return insert; + } ++ ++ return null; ++ } else { ++ return this.head = this.tail = new Link<>(element); + } + } + -+ /* boolean array */ ++ public Link addFirst(final E element) { ++ final Comparator comparator = this.comparator; + -+ public static boolean getPlain(final boolean[] array, final int index) { -+ return (boolean)BOOLEAN_ARRAY_HANDLE.get(array, index); -+ } ++ Link curr = this.head; ++ if (curr != null) { ++ int compare; + -+ public static boolean getOpaque(final boolean[] array, final int index) { -+ return (boolean)BOOLEAN_ARRAY_HANDLE.getOpaque(array, index); -+ } ++ while ((compare = comparator.compare(element, curr.element)) > 0) { ++ Link prev = curr; ++ curr = curr.next; ++ if (curr != null) { ++ continue; ++ } ++ return this.tail = prev.next = new Link<>(element, prev, null); ++ } + -+ public static boolean getAcquire(final boolean[] array, final int index) { -+ return (boolean)BOOLEAN_ARRAY_HANDLE.getAcquire(array, index); -+ } ++ if (compare != 0) { ++ // insert before curr ++ final Link prev = curr.prev; ++ final Link insert = new Link<>(element, prev, curr); ++ curr.prev = insert; + -+ public static boolean getVolatile(final boolean[] array, final int index) { -+ return (boolean)BOOLEAN_ARRAY_HANDLE.getVolatile(array, index); -+ } ++ if (prev == null) { ++ this.head = insert; ++ } else { ++ prev.next = insert; ++ } ++ return insert; ++ } + -+ public static void setPlain(final boolean[] array, final int index, final boolean value) { -+ BOOLEAN_ARRAY_HANDLE.set(array, index, value); ++ return null; ++ } else { ++ return this.head = this.tail = new Link<>(element); ++ } + } + -+ public static void setOpaque(final boolean[] array, final int index, final boolean value) { -+ BOOLEAN_ARRAY_HANDLE.setOpaque(array, index, value); -+ } ++ public static final class Link { ++ private E element; ++ private Link prev; ++ private Link next; + -+ public static void setRelease(final boolean[] array, final int index, final boolean value) { -+ BOOLEAN_ARRAY_HANDLE.setRelease(array, index, value); -+ } ++ private Link(final E element) { ++ this.element = element; ++ } + -+ public static void setVolatile(final boolean[] array, final int index, final boolean value) { -+ BOOLEAN_ARRAY_HANDLE.setVolatile(array, index, value); ++ private Link(final E element, final Link prev, final Link next) { ++ this.element = element; ++ this.prev = prev; ++ this.next = next; ++ } + } ++} +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedUnsortedList.java b/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedUnsortedList.java +new file mode 100644 +index 0000000000000000000000000000000000000000..bd8eb4f25d1dee00fbf9c05c14b0d94c5c641a55 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedUnsortedList.java +@@ -0,0 +1,204 @@ ++package ca.spottedleaf.concurrentutil.set; + -+ public static void setVolatileContended(final boolean[] array, final int index, final boolean param) { -+ int failures = 0; ++import java.util.Iterator; ++import java.util.NoSuchElementException; ++import java.util.Objects; + -+ for (boolean curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } ++public final class LinkedUnsortedList implements Iterable { + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) { -+ return; -+ } -+ } -+ } ++ private Link head; ++ private Link tail; + -+ 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 LinkedUnsortedList() {} + -+ public static boolean getAndOrVolatile(final boolean[] array, final int index, final boolean param) { -+ return (boolean)BOOLEAN_ARRAY_HANDLE.getAndBitwiseOr(array, index, param); ++ public void clear() { ++ this.head = this.tail = null; + } + -+ public static boolean getAndXorVolatile(final boolean[] array, final int index, final boolean param) { -+ return (boolean)BOOLEAN_ARRAY_HANDLE.getAndBitwiseXor(array, index, param); ++ public boolean isEmpty() { ++ return this.head == null; + } + -+ public static boolean getAndSetVolatile(final boolean[] array, final int index, final boolean param) { -+ return (boolean)BOOLEAN_ARRAY_HANDLE.getAndSet(array, index, param); ++ public E first() { ++ final Link head = this.head; ++ return head == null ? null : head.element; + } + -+ 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 E last() { ++ final Link tail = this.tail; ++ return tail == null ? null : tail.element; + } + -+ 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(); ++ public boolean containsFirst(final E element) { ++ for (Link curr = this.head; curr != null; curr = curr.next) { ++ if (Objects.equals(element, curr.element)) { ++ return true; + } ++ } ++ return false; ++ } + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (boolean) (curr & param)))) { -+ return curr; ++ public boolean containsLast(final E element) { ++ for (Link curr = this.tail; curr != null; curr = curr.prev) { ++ if (Objects.equals(element, curr.element)) { ++ return true; + } + } ++ return false; + } + -+ public static boolean getAndOrVolatileContended(final boolean[] array, final int index, final boolean param) { -+ int failures = 0; ++ private void removeNode(final Link node) { ++ final Link prev = node.prev; ++ final Link next = node.next; + -+ for (boolean curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } ++ // help GC ++ node.element = null; ++ node.prev = null; ++ node.next = null; + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (boolean) (curr | param)))) { -+ return curr; -+ } ++ if (prev == null) { ++ this.head = next; ++ } else { ++ prev.next = next; ++ } ++ ++ if (next == null) { ++ this.tail = prev; ++ } else { ++ next.prev = prev; + } + } + -+ public static boolean getAndXorVolatileContended(final boolean[] array, final int index, final boolean param) { -+ int failures = 0; ++ public boolean remove(final Link link) { ++ if (link.element == null) { ++ return false; ++ } + -+ for (boolean curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } ++ this.removeNode(link); ++ return true; ++ } + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (boolean) (curr ^ param)))) { -+ return curr; ++ public boolean removeFirst(final E element) { ++ for (Link curr = this.head; curr != null; curr = curr.next) { ++ if (Objects.equals(element, curr.element)) { ++ this.removeNode(curr); ++ return true; + } + } ++ return false; + } + -+ 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; ++ public boolean removeLast(final E element) { ++ for (Link curr = this.tail; curr != null; curr = curr.prev) { ++ if (Objects.equals(element, curr.element)) { ++ this.removeNode(curr); ++ return true; + } + } ++ return false; + } + -+ @SuppressWarnings("unchecked") -+ public static T getPlain(final T[] array, final int index) { -+ final Object ret = OBJECT_ARRAY_HANDLE.get((Object[])array, index); -+ return (T)ret; -+ } ++ @Override ++ public Iterator iterator() { ++ return new Iterator<>() { ++ private Link next = LinkedUnsortedList.this.head; + -+ @SuppressWarnings("unchecked") -+ public static T getOpaque(final T[] array, final int index) { -+ final Object ret = OBJECT_ARRAY_HANDLE.getOpaque((Object[])array, index); -+ return (T)ret; -+ } ++ @Override ++ public boolean hasNext() { ++ return this.next != null; ++ } + -+ @SuppressWarnings("unchecked") -+ public static T getAcquire(final T[] array, final int index) { -+ final Object ret = OBJECT_ARRAY_HANDLE.getAcquire((Object[])array, index); -+ return (T)ret; ++ @Override ++ public E next() { ++ final Link next = this.next; ++ if (next == null) { ++ throw new NoSuchElementException(); ++ } ++ this.next = next.next; ++ return next.element; ++ } ++ }; + } + -+ @SuppressWarnings("unchecked") -+ public static T getVolatile(final T[] array, final int index) { -+ final Object ret = OBJECT_ARRAY_HANDLE.getVolatile((Object[])array, index); -+ return (T)ret; -+ } ++ public E pollFirst() { ++ final Link head = this.head; ++ if (head == null) { ++ return null; ++ } + -+ public static void setPlain(final T[] array, final int index, final T value) { -+ OBJECT_ARRAY_HANDLE.set((Object[])array, index, (Object)value); -+ } ++ final E ret = head.element; ++ final Link next = head.next; + -+ public static void setOpaque(final T[] array, final int index, final T value) { -+ OBJECT_ARRAY_HANDLE.setOpaque((Object[])array, index, (Object)value); -+ } ++ // unlink head ++ this.head = next; ++ if (next == null) { ++ this.tail = null; ++ } else { ++ next.prev = null; ++ } + -+ public static void setRelease(final T[] array, final int index, final T value) { -+ OBJECT_ARRAY_HANDLE.setRelease((Object[])array, index, (Object)value); -+ } ++ // help GC ++ head.element = null; ++ head.next = null; + -+ public static void setVolatile(final T[] array, final int index, final T value) { -+ OBJECT_ARRAY_HANDLE.setVolatile((Object[])array, index, (Object)value); ++ return ret; + } + -+ public static void setVolatileContended(final T[] array, final int index, final T param) { -+ int failures = 0; ++ public E pollLast() { ++ final Link tail = this.tail; ++ if (tail == null) { ++ return null; ++ } + -+ for (T curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } ++ final E ret = tail.element; ++ final Link prev = tail.prev; + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) { -+ return; -+ } ++ // unlink tail ++ this.tail = prev; ++ if (prev == null) { ++ this.head = null; ++ } else { ++ prev.next = null; + } -+ } + -+ @SuppressWarnings("unchecked") -+ public static 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; ++ // help GC ++ tail.element = null; ++ tail.prev = null; ++ ++ return ret; + } + -+ @SuppressWarnings("unchecked") -+ public static 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; ++ public Link addLast(final E element) { ++ final Link curr = this.tail; ++ if (curr != null) { ++ return this.tail = new Link<>(element, curr, null); ++ } else { ++ return this.head = this.tail = new Link<>(element); ++ } + } + -+ @SuppressWarnings("unchecked") -+ public static 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 Link addFirst(final E element) { ++ final Link curr = this.head; ++ if (curr != null) { ++ return this.head = new Link<>(element, null, curr); ++ } else { ++ return this.head = this.tail = new Link<>(element); ++ } + } + -+ public static T getAndSetVolatileContended(final T[] array, final int index, final T param) { -+ int failures = 0; ++ public static final class Link { ++ private E element; ++ private Link prev; ++ private Link next; + -+ for (T curr = getVolatile(array, index);;++failures) { -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } ++ private Link(final E element) { ++ this.element = element; ++ } + -+ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) { -+ return curr; -+ } ++ private Link(final E element, final Link prev, final Link next) { ++ this.element = element; ++ this.prev = prev; ++ this.next = next; + } + } +} @@ -10185,10 +10075,10 @@ index 0000000000000000000000000000000000000000..4e61c477a56e645228d5a2015c268169 +} diff --git a/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java b/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java new file mode 100644 -index 0000000000000000000000000000000000000000..77699c5fa9681f9ec7aa05cbb50eb60828e193ab +index 0000000000000000000000000000000000000000..9d7b9b8158cd01d12adbd7896ff77bee9828e101 --- /dev/null +++ b/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java -@@ -0,0 +1,176 @@ +@@ -0,0 +1,196 @@ +package ca.spottedleaf.concurrentutil.util; + +public final class IntegerUtil { @@ -10361,11 +10251,183 @@ index 0000000000000000000000000000000000000000..77699c5fa9681f9ec7aa05cbb50eb608 + return (mask ^ val) - mask; // if val < 0, then (0 ^ val) - 0 else (-1 ^ val) + 1 + } + ++ // https://lemire.me/blog/2019/02/08/faster-remainders-when-the-divisor-is-a-constant-beating-compilers-and-libdivide ++ /** ++ * ++ * Usage: ++ *
    ++     * {@code
    ++     *     static final long mult = getSimpleMultiplier(divisor, bits);
    ++     *     long x = ...;
    ++     *     long magic = x * mult;
    ++     *     long divQ = magic >>> bits;
    ++     *     long divR = ((magic & ((1 << bits) - 1)) * divisor) >>> bits;
    ++     * }
    ++     * 
    ++ * ++ * @param bits The number of bits of precision for the returned result ++ */ ++ public static long getUnsignedDivisorMagic(final long divisor, final int bits) { ++ return (((1L << bits) - 1L) / divisor) + 1; ++ } ++ + private IntegerUtil() { + throw new RuntimeException(); + } +} \ No newline at end of file +diff --git a/src/main/java/ca/spottedleaf/concurrentutil/util/Priority.java b/src/main/java/ca/spottedleaf/concurrentutil/util/Priority.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2919bbaa07b70f182438c3be8f9ebbe0649809b6 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/concurrentutil/util/Priority.java +@@ -0,0 +1,145 @@ ++package ca.spottedleaf.concurrentutil.util; ++ ++public 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 Priority max(final Priority p1, final Priority p2) { ++ return p1.isHigherOrEqualPriority(p2) ? p1 : p2; ++ } ++ ++ // returns the lower priroity of the two ++ public static 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 Priority[] PRIORITIES = 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 Priority getPriority(final int priority) { ++ return PRIORITIES[priority + 1]; ++ } ++ ++ private static int priorityCounter; ++ ++ private static int nextCounter() { ++ return priorityCounter++; ++ } ++ ++ public final int priority; ++ ++ private Priority() { ++ this(nextCounter()); ++ } ++ ++ private Priority(final int priority) { ++ this.priority = priority; ++ } ++} +\ No newline at end of file diff --git a/src/main/java/ca/spottedleaf/concurrentutil/util/ThrowUtil.java b/src/main/java/ca/spottedleaf/concurrentutil/util/ThrowUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..a3a8b5c6795c4d116e094e4c910553416f565b93 diff --git a/patches/server/0009-MC-Utils.patch b/patches/server/0009-MC-Utils.patch index 310d5c2f29f1..b7549f7365ac 100644 --- a/patches/server/0009-MC-Utils.patch +++ b/patches/server/0009-MC-Utils.patch @@ -12,12 +12,135 @@ public net.minecraft.server.level.ServerChunkCache mainThreadProcessor public net.minecraft.server.level.ServerChunkCache$MainThreadExecutor public net.minecraft.world.level.chunk.LevelChunkSection states +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6c98d420ea84c10ef4f15d4deb3f04e610ed8548 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java +@@ -0,0 +1,117 @@ ++package ca.spottedleaf.moonrise.common; ++ ++import com.mojang.datafixers.DSL; ++import com.mojang.datafixers.DataFixer; ++import net.minecraft.core.BlockPos; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.server.level.ChunkHolder; ++import net.minecraft.server.level.GenerationChunkHolder; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.level.BlockGetter; ++import net.minecraft.world.level.ChunkPos; ++import net.minecraft.world.level.Level; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.chunk.ChunkAccess; ++import net.minecraft.world.level.chunk.LevelChunk; ++import net.minecraft.world.level.chunk.ProtoChunk; ++import net.minecraft.world.level.chunk.storage.SerializableChunkData; ++import net.minecraft.world.level.entity.EntityTypeTest; ++import net.minecraft.world.phys.AABB; ++import java.util.List; ++import java.util.ServiceLoader; ++import java.util.function.Predicate; ++ ++public interface PlatformHooks { ++ public static PlatformHooks get() { ++ return Holder.INSTANCE; ++ } ++ ++ public String getBrand(); ++ ++ public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos); ++ ++ public Predicate maybeHasLightEmission(); ++ ++ public boolean hasCurrentlyLoadingChunk(); ++ ++ public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder); ++ ++ public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk); ++ ++ public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original); ++ ++ public boolean allowAsyncTicketUpdates(); ++ ++ public void onChunkHolderTicketChange(final ServerLevel world, final ChunkHolder holder, final int oldLevel, final int newLevel); ++ ++ public void chunkUnloadFromWorld(final LevelChunk chunk); ++ ++ public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data); ++ ++ public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player); ++ ++ public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player); ++ ++ public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate predicate, ++ final List into); ++ ++ public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, ++ final AABB boundingBox, final Predicate predicate, ++ final List into, final int maxCount); ++ ++ public void entityMove(final Entity entity, final long oldSection, final long newSection); ++ ++ public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event); ++ ++ public boolean configFixMC224294(); ++ ++ public boolean configAutoConfigSendDistance(); ++ ++ public double configPlayerMaxLoadRate(); ++ ++ public double configPlayerMaxGenRate(); ++ ++ public double configPlayerMaxSendRate(); ++ ++ public int configPlayerMaxConcurrentLoads(); ++ ++ public int configPlayerMaxConcurrentGens(); ++ ++ public long configAutoSaveInterval(final ServerLevel world); ++ ++ public int configMaxAutoSavePerTick(final ServerLevel world); ++ ++ public boolean configFixMC159283(); ++ ++ // support for CB chunk mustNotSave ++ public boolean forceNoSave(final ChunkAccess chunk); ++ ++ public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt, ++ final int fromVersion, final int toVersion); ++ ++ public boolean hasMainChunkLoadHook(); ++ ++ public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData); ++ ++ public List modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List entities); ++ ++ public void unloadEntity(final Entity entity); ++ ++ public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk); ++ ++ public int modifyEntityTrackingRange(final Entity entity, final int currentRange); ++ ++ public static final class Holder { ++ private Holder() { ++ } ++ ++ private static final PlatformHooks INSTANCE; ++ ++ static { ++ INSTANCE = ServiceLoader.load(PlatformHooks.class, PlatformHooks.class.getClassLoader()).findFirst() ++ .orElseThrow(() -> new RuntimeException("Failed to locate PlatformHooks")); ++ } ++ } ++} diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java new file mode 100644 -index 0000000000000000000000000000000000000000..ba68998f6ef57b24c72fd833bd7de440de9501cc +index 0000000000000000000000000000000000000000..7fed43a1e7bcf35c4d7fd3224837a47fedd59860 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java -@@ -0,0 +1,129 @@ +@@ -0,0 +1,128 @@ +package ca.spottedleaf.moonrise.common.list; + +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; @@ -33,15 +156,15 @@ index 0000000000000000000000000000000000000000..ba68998f6ef57b24c72fd833bd7de440 + */ +public final class EntityList implements Iterable { + -+ protected final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); ++ private final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); + { + this.entityToIndex.defaultReturnValue(Integer.MIN_VALUE); + } + -+ protected static final Entity[] EMPTY_LIST = new Entity[0]; ++ private static final Entity[] EMPTY_LIST = new Entity[0]; + -+ protected Entity[] entities = EMPTY_LIST; -+ protected int count; ++ private Entity[] entities = EMPTY_LIST; ++ private int count; + + public int size() { + return this.count; @@ -114,10 +237,9 @@ index 0000000000000000000000000000000000000000..ba68998f6ef57b24c72fd833bd7de440 + + @Override + public Iterator iterator() { -+ return new Iterator() { -+ -+ Entity lastRet; -+ int current; ++ return new Iterator<>() { ++ private Entity lastRet; ++ private int current; + + @Override + public boolean hasNext() { @@ -147,138 +269,89 @@ index 0000000000000000000000000000000000000000..ba68998f6ef57b24c72fd833bd7de440 + }; + } +} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java new file mode 100644 -index 0000000000000000000000000000000000000000..fcfbca333234c09f7c056bbfcd9ac8860b20a8db +index 0000000000000000000000000000000000000000..9f3b25bb2439f283f878db93973a02fcdcd14eed --- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java -@@ -0,0 +1,125 @@ ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java +@@ -0,0 +1,77 @@ +package ca.spottedleaf.moonrise.common.list; + -+import it.unimi.dsi.fastutil.longs.LongIterator; -+import it.unimi.dsi.fastutil.shorts.Short2LongOpenHashMap; ++import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; +import java.util.Arrays; -+import net.minecraft.world.level.block.Block; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.level.chunk.GlobalPalette; + -+public final class IBlockDataList { ++public final class IntList { + -+ private static final GlobalPalette GLOBAL_PALETTE = new GlobalPalette<>(Block.BLOCK_STATE_REGISTRY); -+ -+ // map of location -> (index | (location << 16) | (palette id << 32)) -+ private final Short2LongOpenHashMap map = new Short2LongOpenHashMap(2, 0.8f); ++ private final Int2IntOpenHashMap map = new Int2IntOpenHashMap(); + { -+ this.map.defaultReturnValue(Long.MAX_VALUE); -+ } -+ -+ private static final long[] EMPTY_LIST = new long[0]; -+ -+ private long[] byIndex = EMPTY_LIST; -+ private int size; -+ -+ public static int getLocationKey(final int x, final int y, final int z) { -+ return (x & 15) | (((z & 15) << 4)) | ((y & 255) << (4 + 4)); -+ } -+ -+ public static BlockState getBlockDataFromRaw(final long raw) { -+ return GLOBAL_PALETTE.valueFor((int)(raw >>> 32)); ++ this.map.defaultReturnValue(Integer.MIN_VALUE); + } + -+ public static int getIndexFromRaw(final long raw) { -+ return (int)(raw & 0xFFFF); -+ } ++ private static final int[] EMPTY_LIST = new int[0]; + -+ public static int getLocationFromRaw(final long raw) { -+ return (int)((raw >>> 16) & 0xFFFF); -+ } ++ private int[] byIndex = EMPTY_LIST; ++ private int count; + -+ public static long getRawFromValues(final int index, final int location, final BlockState data) { -+ return (long)index | ((long)location << 16) | (((long)GLOBAL_PALETTE.idFor(data)) << 32); ++ public int size() { ++ return this.count; + } + -+ public static long setIndexRawValues(final long value, final int index) { -+ return value & ~(0xFFFF) | (index); ++ public void setMinCapacity(final int len) { ++ final int[] byIndex = this.byIndex; ++ if (byIndex.length < len) { ++ this.byIndex = Arrays.copyOf(byIndex, len); ++ } + } + -+ public long add(final int x, final int y, final int z, final BlockState data) { -+ return this.add(getLocationKey(x, y, z), data); ++ public int getRaw(final int index) { ++ return this.byIndex[index]; + } + -+ public long add(final int location, final BlockState data) { -+ final long curr = this.map.get((short)location); -+ -+ if (curr == Long.MAX_VALUE) { -+ final int index = this.size++; -+ final long raw = getRawFromValues(index, location, data); -+ this.map.put((short)location, raw); -+ -+ if (index >= this.byIndex.length) { -+ this.byIndex = Arrays.copyOf(this.byIndex, (int)Math.max(4L, this.byIndex.length * 2L)); -+ } ++ public boolean add(final int value) { ++ final int count = this.count; ++ final int currIndex = this.map.putIfAbsent(value, count); + -+ this.byIndex[index] = raw; -+ return raw; -+ } else { -+ final int index = getIndexFromRaw(curr); -+ final long raw = this.byIndex[index] = getRawFromValues(index, location, data); ++ if (currIndex != Integer.MIN_VALUE) { ++ return false; // already in this list ++ } + -+ this.map.put((short)location, raw); ++ int[] list = this.byIndex; + -+ return raw; ++ if (list.length == count) { ++ // resize required ++ list = this.byIndex = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative + } -+ } + -+ public long remove(final int x, final int y, final int z) { -+ return this.remove(getLocationKey(x, y, z)); ++ list[count] = value; ++ this.count = count + 1; ++ ++ return true; + } + -+ public long remove(final int location) { -+ final long ret = this.map.remove((short)location); -+ final int index = getIndexFromRaw(ret); -+ if (ret == Long.MAX_VALUE) { -+ return ret; ++ public boolean remove(final int value) { ++ final int index = this.map.remove(value); ++ if (index == Integer.MIN_VALUE) { ++ return false; + } + + // move the entry at the end to this index -+ final int endIndex = --this.size; -+ final long end = this.byIndex[endIndex]; ++ final int endIndex = --this.count; ++ final int end = this.byIndex[endIndex]; + if (index != endIndex) { + // not empty after this call -+ this.map.put((short)getLocationFromRaw(end), setIndexRawValues(end, index)); ++ this.map.put(end, index); + } + this.byIndex[index] = end; -+ this.byIndex[endIndex] = 0L; -+ -+ return ret; -+ } -+ -+ public int size() { -+ return this.size; -+ } -+ -+ public long getRaw(final int index) { -+ return this.byIndex[index]; -+ } ++ this.byIndex[endIndex] = 0; + -+ public int getLocation(final int index) { -+ return getLocationFromRaw(this.getRaw(index)); -+ } -+ -+ public BlockState getData(final int index) { -+ return getBlockDataFromRaw(this.getRaw(index)); ++ return true; + } + + public void clear() { -+ this.size = 0; ++ this.count = 0; + this.map.clear(); + } -+ -+ public LongIterator getRawIterator() { -+ return this.map.values().iterator(); -+ } +} -\ No newline at end of file diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java new file mode 100644 index 0000000000000000000000000000000000000000..c21e00812f1aaa1279834a0562d360d6b89e146c @@ -745,6 +818,89 @@ index 0000000000000000000000000000000000000000..2e876b918672e8ef3b5197b7e6b15972 + }; + } +} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2bae9949ef325d0001aa638150fbbdf968367e75 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java +@@ -0,0 +1,77 @@ ++package ca.spottedleaf.moonrise.common.list; ++ ++import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap; ++import java.util.Arrays; ++ ++public final class ShortList { ++ ++ private final Short2ShortOpenHashMap map = new Short2ShortOpenHashMap(); ++ { ++ this.map.defaultReturnValue(Short.MIN_VALUE); ++ } ++ ++ private static final short[] EMPTY_LIST = new short[0]; ++ ++ private short[] byIndex = EMPTY_LIST; ++ private short count; ++ ++ public int size() { ++ return (int)this.count; ++ } ++ ++ public short getRaw(final int index) { ++ return this.byIndex[index]; ++ } ++ ++ public void setMinCapacity(final int len) { ++ final short[] byIndex = this.byIndex; ++ if (byIndex.length < len) { ++ this.byIndex = Arrays.copyOf(byIndex, len); ++ } ++ } ++ ++ public boolean add(final short value) { ++ final int count = (int)this.count; ++ final short currIndex = this.map.putIfAbsent(value, (short)count); ++ ++ if (currIndex != Short.MIN_VALUE) { ++ return false; // already in this list ++ } ++ ++ short[] list = this.byIndex; ++ ++ if (list.length == count) { ++ // resize required ++ list = this.byIndex = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative ++ } ++ ++ list[count] = value; ++ this.count = (short)(count + 1); ++ ++ return true; ++ } ++ ++ public boolean remove(final short value) { ++ final short index = this.map.remove(value); ++ if (index == Short.MIN_VALUE) { ++ return false; ++ } ++ ++ // move the entry at the end to this index ++ final short endIndex = --this.count; ++ final short end = this.byIndex[endIndex]; ++ if (index != endIndex) { ++ // not empty after this call ++ this.map.put(end, index); ++ } ++ this.byIndex[(int)index] = end; ++ this.byIndex[(int)endIndex] = (short)0; ++ ++ return true; ++ } ++ ++ public void clear() { ++ this.count = (short)0; ++ this.map.clear(); ++ } ++} diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/SortedList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/SortedList.java new file mode 100644 index 0000000000000000000000000000000000000000..db92261a6cb3758391108361096417c61bc82cdc @@ -2413,25 +2569,57 @@ index 0000000000000000000000000000000000000000..ab2fa1563d5e32a5313dfcc1da411cab + } + } +} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c2d917c2eac55b8a4411a6e159f177f9428b1150 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java +@@ -0,0 +1,22 @@ ++package ca.spottedleaf.moonrise.common.misc; ++ ++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; ++import java.lang.invoke.VarHandle; ++ ++public final class LazyRunnable implements Runnable { ++ ++ private volatile Runnable toRun; ++ private static final VarHandle TO_RUN_HANDLE = ConcurrentUtil.getVarHandle(LazyRunnable.class, "toRun", Runnable.class); ++ ++ public void setRunnable(final Runnable run) { ++ final Runnable prev = (Runnable)TO_RUN_HANDLE.compareAndExchange(this, (Runnable)null, run); ++ if (prev != null) { ++ throw new IllegalStateException("Runnable already set"); ++ } ++ } ++ ++ @Override ++ public void run() { ++ ((Runnable)TO_RUN_HANDLE.getVolatile(this)).run(); ++ } ++} diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java new file mode 100644 -index 0000000000000000000000000000000000000000..ab093b0e8ac6f762921eb1d15f5217345c4eba05 +index 0000000000000000000000000000000000000000..bb44de17a37082e57f2292a4f470740be1d09b11 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java -@@ -0,0 +1,211 @@ +@@ -0,0 +1,273 @@ +package ca.spottedleaf.moonrise.common.misc; + +import ca.spottedleaf.moonrise.common.list.ReferenceList; +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +import ca.spottedleaf.moonrise.common.util.MoonriseConstants; +import ca.spottedleaf.moonrise.common.util.ChunkSystem; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; +import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants; ++import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel; +import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; +import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.level.ChunkPos; ++import java.util.ArrayList; + +public final class NearbyPlayers { + @@ -2441,7 +2629,27 @@ index 0000000000000000000000000000000000000000..ab093b0e8ac6f762921eb1d15f521734 + GENERAL_REALLY_SMALL, + TICK_VIEW_DISTANCE, + VIEW_DISTANCE, -+ SPAWN_RANGE, // Moonrise - chunk tick iteration ++ // Moonrise start - chunk tick iteration ++ SPAWN_RANGE { ++ @Override ++ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ((ChunkTickServerLevel)world).moonrise$addPlayerTickingRequest(chunkX, chunkZ); ++ } ++ ++ @Override ++ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ((ChunkTickServerLevel)world).moonrise$removePlayerTickingRequest(chunkX, chunkZ); ++ } ++ }; ++ // Moonrise end - chunk tick iteration ++ ++ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ++ } ++ ++ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { ++ ++ } + } + + private static final NearbyMapType[] MAP_TYPES = NearbyMapType.values(); @@ -2458,6 +2666,12 @@ index 0000000000000000000000000000000000000000..ab093b0e8ac6f762921eb1d15f521734 + private final ServerLevel world; + private final Reference2ReferenceOpenHashMap players = new Reference2ReferenceOpenHashMap<>(); + private final Long2ReferenceOpenHashMap byChunk = new Long2ReferenceOpenHashMap<>(); ++ private final Long2ReferenceOpenHashMap>[] directByChunk = new Long2ReferenceOpenHashMap[TOTAL_MAP_TYPES]; ++ { ++ for (int i = 0; i < this.directByChunk.length; ++i) { ++ this.directByChunk[i] = new Long2ReferenceOpenHashMap<>(); ++ } ++ } + + public NearbyPlayers(final ServerLevel world) { + this.world = world; @@ -2491,6 +2705,16 @@ index 0000000000000000000000000000000000000000..ab093b0e8ac6f762921eb1d15f521734 + } + } + ++ public void clear() { ++ if (this.players.isEmpty()) { ++ return; ++ } ++ ++ for (final ServerPlayer player : new ArrayList<>(this.players.keySet())) { ++ this.removePlayer(player); ++ } ++ } ++ + public void tickPlayer(final ServerPlayer player) { + final TrackedPlayer[] players = this.players.get(player); + if (players == null) { @@ -2515,38 +2739,41 @@ index 0000000000000000000000000000000000000000..ab093b0e8ac6f762921eb1d15f521734 + return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); + } + -+ public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { -+ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); ++ public TrackedChunk getChunk(final int chunkX, final int chunkZ) { ++ return this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ } + -+ return chunk == null ? null : chunk.players[type.ordinal()]; ++ public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); + } + + public ReferenceList getPlayers(final ChunkPos pos, final NearbyMapType type) { -+ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -+ -+ return chunk == null ? null : chunk.players[type.ordinal()]; ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); + } + + public ReferenceList getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) { -+ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ -+ return chunk == null ? null : chunk.players[type.ordinal()]; ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + } + + public ReferenceList getPlayersByBlock(final int blockX, final int blockZ, final NearbyMapType type) { -+ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); -+ -+ return chunk == null ? null : chunk.players[type.ordinal()]; ++ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); + } + + public static final class TrackedChunk { + + private static final ServerPlayer[] EMPTY_PLAYERS_ARRAY = new ServerPlayer[0]; + ++ private final long chunkKey; ++ private final NearbyPlayers nearbyPlayers; + private final ReferenceList[] players = new ReferenceList[TOTAL_MAP_TYPES]; + private int nonEmptyLists; + private long updateCount; + ++ public TrackedChunk(final long chunkKey, final NearbyPlayers nearbyPlayers) { ++ this.chunkKey = chunkKey; ++ this.nearbyPlayers = nearbyPlayers; ++ } ++ + public boolean isEmpty() { + return this.nonEmptyLists == 0; + } @@ -2566,7 +2793,9 @@ index 0000000000000000000000000000000000000000..ab093b0e8ac6f762921eb1d15f521734 + final ReferenceList list = this.players[idx]; + if (list == null) { + ++this.nonEmptyLists; -+ (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)).add(player); ++ final ReferenceList players = (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)); ++ this.nearbyPlayers.directByChunk[idx].put(this.chunkKey, players); ++ players.add(player); + return; + } + @@ -2590,6 +2819,7 @@ index 0000000000000000000000000000000000000000..ab093b0e8ac6f762921eb1d15f521734 + + if (list.size() == 0) { + this.players[idx] = null; ++ this.nearbyPlayers.directByChunk[idx].remove(this.chunkKey); + --this.nonEmptyLists; + } + } @@ -2608,9 +2838,19 @@ index 0000000000000000000000000000000000000000..ab093b0e8ac6f762921eb1d15f521734 + protected void addCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { + final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); + -+ NearbyPlayers.this.byChunk.computeIfAbsent(chunkKey, (final long keyInMap) -> { -+ return new TrackedChunk(); -+ }).addPlayer(parameter, this.type); ++ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey); ++ final NearbyMapType type = this.type; ++ if (chunk != null) { ++ chunk.addPlayer(parameter, type); ++ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); ++ } else { ++ final TrackedChunk created = new TrackedChunk(chunkKey, NearbyPlayers.this); ++ NearbyPlayers.this.byChunk.put(chunkKey, created); ++ created.addPlayer(parameter, type); ++ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); ++ ++ ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$requestChunkData(chunkKey).nearbyPlayers = created; ++ } + } + + @Override @@ -2622,24 +2862,31 @@ index 0000000000000000000000000000000000000000..ab093b0e8ac6f762921eb1d15f521734 + throw new IllegalStateException("Chunk should exist at " + new ChunkPos(chunkKey)); + } + -+ chunk.removePlayer(parameter, this.type); ++ final NearbyMapType type = this.type; ++ chunk.removePlayer(parameter, type); ++ type.removeFrom(parameter, NearbyPlayers.this.world, chunkX, chunkZ); + + if (chunk.isEmpty()) { + NearbyPlayers.this.byChunk.remove(chunkKey); ++ final ChunkData chunkData = ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$releaseChunkData(chunkKey); ++ if (chunkData != null) { ++ chunkData.nearbyPlayers = null; ++ } + } + } + } +} diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java new file mode 100644 -index 0000000000000000000000000000000000000000..efefd94b652228d877db5dbca8b28354ad42529f +index 0000000000000000000000000000000000000000..90560769d09538f7a740753a41a3b8e017b0b92a --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java -@@ -0,0 +1,94 @@ +@@ -0,0 +1,99 @@ +package ca.spottedleaf.moonrise.common.misc; + +import ca.spottedleaf.concurrentutil.util.IntPairUtil; +import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; ++import it.unimi.dsi.fastutil.longs.LongSet; +import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; +import it.unimi.dsi.fastutil.objects.ReferenceSet; + @@ -2652,6 +2899,10 @@ index 0000000000000000000000000000000000000000..efefd94b652228d877db5dbca8b28354 + return this.counters.keySet(); + } + ++ public LongSet getPositions() { ++ return this.positions.keySet(); ++ } ++ + public int getTotalPositions() { + return this.positions.size(); + } @@ -3060,13 +3311,14 @@ index 0000000000000000000000000000000000000000..4123edddc556c47f3f8d83523c125fd2 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java new file mode 100644 -index 0000000000000000000000000000000000000000..da323a1105347d5cf4b946df10ded78a953236f2 +index 0000000000000000000000000000000000000000..94bba2b71918d79f54b3e28c35e76098ba0afd8c --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -@@ -0,0 +1,284 @@ +@@ -0,0 +1,288 @@ +package ca.spottedleaf.moonrise.common.util; + -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.util.Priority; ++import ca.spottedleaf.moonrise.common.PlatformHooks; +import com.mojang.logging.LogUtils; +import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.FullChunkStatus; @@ -3090,15 +3342,15 @@ index 0000000000000000000000000000000000000000..da323a1105347d5cf4b946df10ded78a + } + + public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) { -+ scheduleChunkTask(level, chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); ++ scheduleChunkTask(level, chunkX, chunkZ, run, Priority.NORMAL); + } + -+ public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) { ++ public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final 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 ChunkStatus toStatus, final boolean addTicket, final Priority priority, + final Consumer onComplete) { + if (gen) { + scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); @@ -3125,7 +3377,7 @@ index 0000000000000000000000000000000000000000..da323a1105347d5cf4b946df10ded78a + + 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 onComplete) { ++ final boolean addTicket, final Priority priority, final Consumer onComplete) { + if (!org.bukkit.Bukkit.isPrimaryThread()) { + scheduleChunkTask(level, chunkX, chunkZ, () -> { + scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); @@ -3179,13 +3431,13 @@ index 0000000000000000000000000000000000000000..da323a1105347d5cf4b946df10ded78a + } + loadCallback.accept(result.orElse(null)); + }, (final Runnable r) -> { -+ scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); ++ scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST); + }); + } + + public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ, + final FullChunkStatus toStatus, final boolean addTicket, -+ final PrioritisedExecutor.Priority priority, final Consumer onComplete) { ++ final Priority priority, final Consumer onComplete) { + // This method goes unused until the chunk system rewrite + if (toStatus == FullChunkStatus.INACCESSIBLE) { + throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status"); @@ -3262,7 +3514,7 @@ index 0000000000000000000000000000000000000000..da323a1105347d5cf4b946df10ded78a + } + loadCallback.accept(result.orElse(null)); + }, (final Runnable r) -> { -+ scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); ++ scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST); + }); + } + @@ -3286,7 +3538,10 @@ index 0000000000000000000000000000000000000000..da323a1105347d5cf4b946df10ded78a + return getUpdatingChunkHolderCount(level) != 0; + } + -+ public static boolean screenEntity(final ServerLevel level, final Entity entity) { ++ public static boolean screenEntity(final ServerLevel level, final Entity entity, final boolean fromDisk, final boolean event) { ++ if (!PlatformHooks.get().screenEntity(level, entity, fromDisk, event)) { ++ return false; ++ } + return true; + } + @@ -3640,93 +3895,212 @@ index 0000000000000000000000000000000000000000..91efda726b87a8a8f28dee84e31b6a70 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java new file mode 100644 -index 0000000000000000000000000000000000000000..ac6f284ee4469d16c5655328b2488d7612832353 +index 0000000000000000000000000000000000000000..97848869df61648fc415e4d39f409f433202c274 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java -@@ -0,0 +1,10 @@ +@@ -0,0 +1,14 @@ +package ca.spottedleaf.moonrise.common.util; + +public final class MixinWorkarounds { + + // mixins tries to find the owner of the clone() method, which doesn't exist and NPEs ++ // https://github.com/FabricMC/Mixin/pull/147 + public static long[] clone(final long[] values) { + return values.clone(); + } + ++ public static byte[] clone(final byte[] values) { ++ return values.clone(); ++ } +} diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java new file mode 100644 -index 0000000000000000000000000000000000000000..3abe0bd2a820352b85306d554bf14a4cf6123091 +index 0000000000000000000000000000000000000000..c125c70a68130be373acc989053a6c0e487be924 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java -@@ -0,0 +1,46 @@ +@@ -0,0 +1,101 @@ +package ca.spottedleaf.moonrise.common.util; + -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool; ++import ca.spottedleaf.concurrentutil.executor.thread.PrioritisedThreadPool; ++import ca.spottedleaf.moonrise.common.PlatformHooks; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -+import java.io.File; ++import java.util.concurrent.TimeUnit; ++import java.util.concurrent.atomic.AtomicInteger; ++import java.util.function.Consumer; + +public final class MoonriseCommon { + + private static final Logger LOGGER = LoggerFactory.getLogger(MoonriseCommon.class); + -+ // Paper start -+ public static PrioritisedThreadPool WORKER_POOL; -+ public static int WORKER_THREADS; -+ public static void init(io.papermc.paper.configuration.GlobalConfiguration.ChunkSystem chunkSystem) { -+ // Paper end ++ public static final PrioritisedThreadPool WORKER_POOL = new PrioritisedThreadPool( ++ new Consumer<>() { ++ private final AtomicInteger idGenerator = new AtomicInteger(); ++ ++ @Override ++ public void accept(Thread thread) { ++ thread.setDaemon(true); ++ thread.setName(PlatformHooks.get().getBrand() + " Common Worker #" + this.idGenerator.getAndIncrement()); ++ thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { ++ @Override ++ public void uncaughtException(final Thread thread, final Throwable throwable) { ++ LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); ++ } ++ }); ++ } ++ } ++ ); ++ public static final long WORKER_QUEUE_HOLD_TIME = (long)(20.0e6); // 20ms ++ public static final int CLIENT_DIVISION = 0; ++ public static final PrioritisedThreadPool.ExecutorGroup RENDER_EXECUTOR_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(CLIENT_DIVISION, 0); ++ public static final int SERVER_DIVISION = 1; ++ public static final PrioritisedThreadPool.ExecutorGroup PARALLEL_GEN_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); ++ public static final PrioritisedThreadPool.ExecutorGroup RADIUS_AWARE_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); ++ public static final PrioritisedThreadPool.ExecutorGroup LOAD_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); ++ ++ public static void adjustWorkerThreads(final int configWorkerThreads, final int configIoThreads) { + int defaultWorkerThreads = Runtime.getRuntime().availableProcessors() / 2; + if (defaultWorkerThreads <= 4) { + defaultWorkerThreads = defaultWorkerThreads <= 3 ? 1 : 2; + } else { + defaultWorkerThreads = defaultWorkerThreads / 2; + } -+ defaultWorkerThreads = Integer.getInteger("Paper.WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); // Paper ++ defaultWorkerThreads = Integer.getInteger(PlatformHooks.get().getBrand() + ".WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); + -+ int workerThreads = chunkSystem.workerThreads; // Paper ++ int workerThreads = configWorkerThreads; + + if (workerThreads <= 0) { + workerThreads = defaultWorkerThreads; + } + -+ WORKER_POOL = new PrioritisedThreadPool( -+ "Paper Worker Pool", workerThreads, // Paper -+ (final Thread thread, final Integer id) -> { -+ thread.setName("Paper Common Worker #" + id.intValue()); // Paper ++ final int ioThreads = Math.max(1, configIoThreads); ++ ++ WORKER_POOL.adjustThreadCount(workerThreads); ++ IO_POOL.adjustThreadCount(ioThreads); ++ ++ LOGGER.info(PlatformHooks.get().getBrand() + " is using " + workerThreads + " worker threads, " + ioThreads + " I/O threads"); ++ } ++ ++ public static final PrioritisedThreadPool IO_POOL = new PrioritisedThreadPool( ++ new Consumer<>() { ++ private final AtomicInteger idGenerator = new AtomicInteger(); ++ ++ @Override ++ public void accept(final Thread thread) { ++ thread.setDaemon(true); ++ thread.setName(PlatformHooks.get().getBrand() + " I/O Worker #" + this.idGenerator.getAndIncrement()); + thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(final Thread thread, final Throwable throwable) { + LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); + } + }); -+ }, (long)(20.0e6)); // 20ms -+ WORKER_THREADS = workerThreads; ++ } ++ } ++ ); ++ public static final long IO_QUEUE_HOLD_TIME = (long)(100.0e6); // 100ms ++ public static final PrioritisedThreadPool.ExecutorGroup CLIENT_PROFILER_IO_GROUP = IO_POOL.createExecutorGroup(CLIENT_DIVISION, 0); ++ public static final PrioritisedThreadPool.ExecutorGroup SERVER_REGION_IO_GROUP = IO_POOL.createExecutorGroup(SERVER_DIVISION, 0); ++ ++ public static void haltExecutors() { ++ MoonriseCommon.WORKER_POOL.shutdown(false); ++ LOGGER.info("Awaiting termination of worker pool for up to 60s..."); ++ if (!MoonriseCommon.WORKER_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { ++ LOGGER.error("Worker pool did not shut down in time!"); ++ MoonriseCommon.WORKER_POOL.halt(false); ++ } ++ ++ MoonriseCommon.IO_POOL.shutdown(false); ++ LOGGER.info("Awaiting termination of I/O pool for up to 60s..."); ++ if (!MoonriseCommon.IO_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { ++ LOGGER.error("I/O pool did not shut down in time!"); ++ MoonriseCommon.IO_POOL.halt(false); ++ } + } + + private MoonriseCommon() {} +} diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java new file mode 100644 -index 0000000000000000000000000000000000000000..1cf32d7d1bbc8a0a3f7cb9024c793f6744199f64 +index 0000000000000000000000000000000000000000..559c959aff3c9deef867b9e425fba3e2e669cac6 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java -@@ -0,0 +1,9 @@ +@@ -0,0 +1,11 @@ +package ca.spottedleaf.moonrise.common.util; + ++import ca.spottedleaf.moonrise.common.PlatformHooks; ++ +public final class MoonriseConstants { + -+ public static final int MAX_VIEW_DISTANCE = 32; ++ public static final int MAX_VIEW_DISTANCE = Integer.getInteger(PlatformHooks.get().getBrand() + ".MaxViewDistance", 32); + + private MoonriseConstants() {} + +} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java b/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a9ff1c1a70faf4b7a64b265932f07a8b8f00c1ff +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java +@@ -0,0 +1,52 @@ ++package ca.spottedleaf.moonrise.common.util; ++ ++import net.minecraft.world.level.levelgen.LegacyRandomSource; ++ ++/** ++ * Avoid costly CAS of superclass ++ */ ++public final class SimpleRandom extends LegacyRandomSource { ++ ++ private static final long MULTIPLIER = 25214903917L; ++ private static final long ADDEND = 11L; ++ private static final int BITS = 48; ++ private static final long MASK = (1L << BITS) - 1; ++ ++ private long value; ++ ++ public SimpleRandom(final long seed) { ++ super(0L); ++ this.value = seed; ++ } ++ ++ @Override ++ public void setSeed(final long seed) { ++ this.value = (seed ^ MULTIPLIER) & MASK; ++ } ++ ++ private long advanceSeed() { ++ return this.value = ((this.value * MULTIPLIER) + ADDEND) & MASK; ++ } ++ ++ @Override ++ public int next(final int bits) { ++ return (int)(this.advanceSeed() >>> (BITS - bits)); ++ } ++ ++ @Override ++ public int nextInt() { ++ final long seed = this.advanceSeed(); ++ return (int)(seed >>> (BITS - Integer.SIZE)); ++ } ++ ++ @Override ++ public int nextInt(final int bound) { ++ if (bound <= 0) { ++ throw new IllegalArgumentException(); ++ } ++ ++ // https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ ++ final long value = this.advanceSeed() >>> (BITS - Integer.SIZE); ++ return (int)((value * (long)bound) >>> Integer.SIZE); ++ } ++} diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java new file mode 100644 -index 0000000000000000000000000000000000000000..11b7f15755dde766140c29bedca456c80d53293f +index 0000000000000000000000000000000000000000..217d1f908a36a5177ba3cbb80a33f73d4dab0fa0 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java -@@ -0,0 +1,139 @@ +@@ -0,0 +1,143 @@ +package ca.spottedleaf.moonrise.common.util; + +import net.minecraft.core.BlockPos; @@ -3806,11 +4180,15 @@ index 0000000000000000000000000000000000000000..11b7f15755dde766140c29bedca456c8 + } + + public TickThread(final Runnable run, final String name) { -+ this(run, name, ID_GENERATOR.incrementAndGet()); ++ this(null, run, name); ++ } ++ ++ public TickThread(final ThreadGroup group, final Runnable run, final String name) { ++ this(group, run, name, ID_GENERATOR.incrementAndGet()); + } + -+ private TickThread(final Runnable run, final String name, final int id) { -+ super(run, name); ++ private TickThread(final ThreadGroup group, final Runnable run, final String name, final int id) { ++ super(group, run, name); + this.id = id; + } + @@ -3868,10 +4246,10 @@ index 0000000000000000000000000000000000000000..11b7f15755dde766140c29bedca456c8 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java new file mode 100644 -index 0000000000000000000000000000000000000000..561a1a3ff418393d0a0db58de91b336f4c33aa4e +index 0000000000000000000000000000000000000000..efda2688ae1254a82ba7f6bf8bf597ef224cbb86 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java -@@ -0,0 +1,54 @@ +@@ -0,0 +1,62 @@ +package ca.spottedleaf.moonrise.common.util; + +import net.minecraft.world.level.Level; @@ -3882,13 +4260,21 @@ index 0000000000000000000000000000000000000000..561a1a3ff418393d0a0db58de91b336f + // min, max are inclusive + + public static int getMaxSection(final LevelHeightAccessor world) { -+ return world.getMaxSectionY() - 1; // getMaxSection() is exclusive ++ return world.getMaxSectionY(); ++ } ++ ++ public static int getMaxSection(final Level world) { ++ return world.getMaxSectionY(); + } + + public static int getMinSection(final LevelHeightAccessor world) { + return world.getMinSectionY(); + } + ++ public static int getMinSection(final Level world) { ++ return world.getMinSectionY(); ++ } ++ + public static int getMaxLightSection(final LevelHeightAccessor world) { + return getMaxSection(world) + 1; + } @@ -3926,6 +4312,221 @@ index 0000000000000000000000000000000000000000..561a1a3ff418393d0a0db58de91b336f + throw new RuntimeException(); + } +} +diff --git a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1aa6be257ce594d7a69fdff008cd29014a04fd75 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java +@@ -0,0 +1,209 @@ ++package ca.spottedleaf.moonrise.paper; ++ ++import ca.spottedleaf.moonrise.common.PlatformHooks; ++import com.mojang.datafixers.DSL; ++import com.mojang.datafixers.DataFixer; ++import com.mojang.serialization.Dynamic; ++import net.minecraft.core.BlockPos; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.nbt.NbtOps; ++import net.minecraft.server.level.ChunkHolder; ++import net.minecraft.server.level.GenerationChunkHolder; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.level.BlockGetter; ++import net.minecraft.world.level.ChunkPos; ++import net.minecraft.world.level.Level; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.chunk.ChunkAccess; ++import net.minecraft.world.level.chunk.LevelChunk; ++import net.minecraft.world.level.chunk.ProtoChunk; ++import net.minecraft.world.level.chunk.storage.SerializableChunkData; ++import net.minecraft.world.level.entity.EntityTypeTest; ++import net.minecraft.world.phys.AABB; ++import java.util.List; ++import java.util.function.Predicate; ++ ++public final class PaperHooks implements PlatformHooks { ++ ++ @Override ++ public String getBrand() { ++ return "Paper"; ++ } ++ ++ @Override ++ public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos) { ++ return blockState.getLightEmission(); ++ } ++ ++ @Override ++ public Predicate maybeHasLightEmission() { ++ return (final BlockState state) -> { ++ return state.getLightEmission() != 0; ++ }; ++ } ++ ++ @Override ++ public boolean hasCurrentlyLoadingChunk() { ++ return false; ++ } ++ ++ @Override ++ public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder) { ++ return null; ++ } ++ ++ @Override ++ public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk) { ++ ++ } ++ ++ @Override ++ public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original) { ++ ++ } ++ ++ @Override ++ public boolean allowAsyncTicketUpdates() { ++ return true; ++ } ++ ++ @Override ++ public void onChunkHolderTicketChange(final ServerLevel world, final ChunkHolder holder, final int oldLevel, final int newLevel) { ++ ++ } ++ ++ @Override ++ public void chunkUnloadFromWorld(final LevelChunk chunk) { ++ ++ } ++ ++ @Override ++ public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data) { ++ ++ } ++ ++ @Override ++ public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player) { ++ ++ } ++ ++ @Override ++ public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player) { ++ ++ } ++ ++ @Override ++ public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate predicate, final List into) { ++ ++ } ++ ++ @Override ++ public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, final AABB boundingBox, final Predicate predicate, final List into, final int maxCount) { ++ ++ } ++ ++ @Override ++ public void entityMove(final Entity entity, final long oldSection, final long newSection) { ++ ++ } ++ ++ @Override ++ public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event) { ++ return true; ++ } ++ ++ @Override ++ public boolean configFixMC224294() { ++ return true; ++ } ++ ++ @Override ++ public boolean configAutoConfigSendDistance() { ++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.autoConfigSendDistance; ++ } ++ ++ @Override ++ public double configPlayerMaxLoadRate() { ++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkLoadRate; ++ } ++ ++ @Override ++ public double configPlayerMaxGenRate() { ++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkGenerateRate; ++ } ++ ++ @Override ++ public double configPlayerMaxSendRate() { ++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkSendRate; ++ } ++ ++ @Override ++ public int configPlayerMaxConcurrentLoads() { ++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkLoads; ++ } ++ ++ @Override ++ public int configPlayerMaxConcurrentGens() { ++ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkGenerates; ++ } ++ ++ @Override ++ public long configAutoSaveInterval(final ServerLevel world) { ++ return world.paperConfig().chunks.autoSaveInterval.value(); ++ } ++ ++ @Override ++ public int configMaxAutoSavePerTick(final ServerLevel world) { ++ return world.paperConfig().chunks.maxAutoSaveChunksPerTick; ++ } ++ ++ @Override ++ public boolean configFixMC159283() { ++ return true; ++ } ++ ++ @Override ++ public boolean forceNoSave(final ChunkAccess chunk) { ++ return chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave; ++ } ++ ++ @Override ++ public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt, ++ final int fromVersion, final int toVersion) { ++ return (CompoundTag)dataFixer.update( ++ type, new Dynamic<>(NbtOps.INSTANCE, nbt), fromVersion, toVersion ++ ).getValue(); ++ } ++ ++ @Override ++ public boolean hasMainChunkLoadHook() { ++ return false; ++ } ++ ++ @Override ++ public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData) { ++ ++ } ++ ++ @Override ++ public List modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List entities) { ++ return entities; ++ } ++ ++ @Override ++ public void unloadEntity(final Entity entity) { ++ entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, org.bukkit.event.entity.EntityRemoveEvent.Cause.UNLOAD); ++ } ++ ++ @Override ++ public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) { ++ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities()); ++ } ++ ++ @Override ++ public int modifyEntityTrackingRange(final Entity entity, final int currentRange) { ++ return org.spigotmc.TrackingRange.getEntityTrackingRange(entity, currentRange); ++ } ++} diff --git a/src/main/java/com/mojang/logging/LogUtils.java b/src/main/java/com/mojang/logging/LogUtils.java index 46cab7a8c7b87ab01b26074b04f5a02b3907cfc4..49019b4a9bc4e634d54a9b0acaf9229a5c896f85 100644 --- a/src/main/java/com/mojang/logging/LogUtils.java @@ -3940,6 +4541,19 @@ index 46cab7a8c7b87ab01b26074b04f5a02b3907cfc4..49019b4a9bc4e634d54a9b0acaf9229a + } + // Paper end } +diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +index 7e88b1fc1ff700a7771b38f139f4472eaeaf8714..904d2f96a60e72aa089fdfe6be08044b04f995c1 100644 +--- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java ++++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +@@ -242,7 +242,7 @@ public class GlobalConfiguration extends ConfigurationPart { + + @PostProcess + private void postProcess() { +- ++ ca.spottedleaf.moonrise.common.util.MoonriseCommon.adjustWorkerThreads(this.workerThreads, this.ioThreads); + } + } + diff --git a/src/main/java/io/papermc/paper/util/IntervalledCounter.java b/src/main/java/io/papermc/paper/util/IntervalledCounter.java new file mode 100644 index 0000000000000000000000000000000000000000..197224e31175252d8438a8df585bbb65f2288d7f @@ -4822,7 +5436,7 @@ index 9cdcab885a915990a679f3fc9ae6885f7d125bfd..c615510f3f59292715bcff1bd9e4e896 if (!this.level.shouldTickBlocksAt(pos)) { return false; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index f6a3606b972064c4ec78487374e6197c0c447e27..6fe373de360570b528b8133043ef3bb9ba12529d 100644 +index f6a3606b972064c4ec78487374e6197c0c447e27..c6ded1ac73ddbc0336000f77c0f99fa20551a0de 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -239,6 +239,98 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -4859,7 +5473,7 @@ index f6a3606b972064c4ec78487374e6197c0c447e27..6fe373de360570b528b8133043ef3bb9 + return true; + } + -+ public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, ++ public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.util.Priority priority, + java.util.function.Consumer> onLoad) { + if (Thread.currentThread() != this.thread) { + this.getChunkSource().mainThreadProcessor.execute(() -> { @@ -5513,24 +6127,35 @@ index 8bd5fb4971be46a51534c202e10a362723ad8664..5321109ca638036572df9a7e17eafcef @Override public BlockState getBlockState(BlockPos pos) { int i = pos.getY(); +diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java +index 3f552ee8f90566edddb5943311a14309e4bebb61..412caefe776df6c8e931f6a1a48ea2525ec6610e 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java ++++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java +@@ -168,7 +168,7 @@ public class ChunkStatusTasks { + }, context.mainThreadExecutor()); + } + +- private static void postLoadProtoChunk(ServerLevel world, List entities) { ++ public static void postLoadProtoChunk(ServerLevel world, List entities) { // Paper - public + if (!entities.isEmpty()) { + // CraftBukkit start - these are spawned serialized (DefinedStructure) and we don't call an add event below at the moment due to ordering complexities + world.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(entities, world, EntitySpawnReason.LOAD).filter((entity) -> { 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 34933c5324126f9afdc5cba9dea997ace8f01806..1cfc906317f07a44f06a4adf021c44e34a2f1d07 100644 +index 34933c5324126f9afdc5cba9dea997ace8f01806..4eb0b0969325f39a7ae65492cccd482515a50142 100644 --- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java +++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java -@@ -91,6 +91,18 @@ public class PersistentEntitySectionManager implements A +@@ -91,6 +91,16 @@ public class PersistentEntitySectionManager 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(); -+ boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted); -+ if ((!wasRemoved && entityCasted.isRemoved()) || !screened) { -+ // removed by callback -+ return false; -+ } ++ // I don't want to know why this is a generic type. ++ Entity entityCasted = (Entity)entity; ++ boolean wasRemoved = entityCasted.isRemoved(); ++ boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted, existing, true); ++ if ((!wasRemoved && entityCasted.isRemoved()) || !screened) { ++ // removed by callback ++ return false; + } + // Paper end - chunk system hooks if (!this.addEntityUuid(entity)) { @@ -5551,7 +6176,7 @@ index 3882ae04173cd125fe490692a6bc2b4d8b20ff7b..eb61712ea067b277e7f32f887e3528fa + } } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 799444e4101283c972a160742a9e2548e604173f..456c58877490feab6be3577d34c89ea776568617 100644 +index 799444e4101283c972a160742a9e2548e604173f..8b58884d6cb1088a2fffb36a99bfe4dc568326d1 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -256,8 +256,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -5587,11 +6212,11 @@ index 799444e4101283c972a160742a9e2548e604173f..456c58877490feab6be3577d34c89ea7 + } + } + -+ ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority; ++ ca.spottedleaf.concurrentutil.util.Priority priority; + if (urgent) { -+ priority = ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER; ++ priority = ca.spottedleaf.concurrentutil.util.Priority.HIGHER; + } else { -+ priority = ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL; ++ priority = ca.spottedleaf.concurrentutil.util.Priority.NORMAL; + } + + java.util.concurrent.CompletableFuture ret = new java.util.concurrent.CompletableFuture<>(); @@ -5774,3 +6399,10 @@ index 1bf87b4915edf341ad55f8274cef324e0bc28547..3591b79481ac17bd02e59ac3c623d1c6 MONSTER, ANIMAL, RAIDER, +diff --git a/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks b/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks +new file mode 100644 +index 0000000000000000000000000000000000000000..e57c3ca79677b1dfe7cf3db36f0406de7ea5bd0a +--- /dev/null ++++ b/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks +@@ -0,0 +1 @@ ++ca.spottedleaf.moonrise.paper.PaperHooks diff --git a/patches/server/0010-Adventure.patch b/patches/server/0010-Adventure.patch index a8d9cacd7474..7375271d2050 100644 --- a/patches/server/0010-Adventure.patch +++ b/patches/server/0010-Adventure.patch @@ -3558,7 +3558,7 @@ index cbdb1a56a97150c164515a4ce6d3ba06428bf321..b214e7b302abbfe1641485a05f1371ac public URI getUrl() { return this.handle.link(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 456c58877490feab6be3577d34c89ea776568617..274c9cc32d7f65456d184db7f61bc4b159f890f8 100644 +index 8b58884d6cb1088a2fffb36a99bfe4dc568326d1..9a79b948264150d0f7a843a8ddd2ea9245ae66f3 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -166,6 +166,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0023-Timings-v2.patch b/patches/server/0023-Timings-v2.patch index 4e5f30f3df77..6ac52a48c75e 100644 --- a/patches/server/0023-Timings-v2.patch +++ b/patches/server/0023-Timings-v2.patch @@ -1118,7 +1118,7 @@ index c615510f3f59292715bcff1bd9e4e896c9733436..93422468474189343cdc1e29f06f6dfb } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 6fe373de360570b528b8133043ef3bb9ba12529d..d82f4255faac84ce6af47e86707f5c035529ab5d 100644 +index c6ded1ac73ddbc0336000f77c0f99fa20551a0de..a1565304c436258b561d97a6cc7aacecf68816b7 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 @@ diff --git a/patches/server/0036-Entity-Origin-API.patch b/patches/server/0036-Entity-Origin-API.patch index 0762019efff1..e1281dbfae6d 100644 --- a/patches/server/0036-Entity-Origin-API.patch +++ b/patches/server/0036-Entity-Origin-API.patch @@ -5,7 +5,7 @@ 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 d82f4255faac84ce6af47e86707f5c035529ab5d..a31371dd479f5d87ff62728504563815bb5e22f8 100644 +index a1565304c436258b561d97a6cc7aacecf68816b7..e2e949dbd8be52dc6a00414f0f79746ee554acd7 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2212,6 +2212,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0045-Disable-thunder.patch b/patches/server/0045-Disable-thunder.patch index ab1379c28eba..b0c60085d2d4 100644 --- a/patches/server/0045-Disable-thunder.patch +++ b/patches/server/0045-Disable-thunder.patch @@ -5,7 +5,7 @@ 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 a31371dd479f5d87ff62728504563815bb5e22f8..f1145c190b8cb50a800d9324b25aa884b7de9606 100644 +index e2e949dbd8be52dc6a00414f0f79746ee554acd7..1e012aef9a515b2e312565e8fe7652f38e080e4b 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -603,7 +603,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0046-Disable-ice-and-snow.patch b/patches/server/0046-Disable-ice-and-snow.patch index 7f43a10174d5..8ba40908f9f4 100644 --- a/patches/server/0046-Disable-ice-and-snow.patch +++ b/patches/server/0046-Disable-ice-and-snow.patch @@ -5,7 +5,7 @@ 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 f1145c190b8cb50a800d9324b25aa884b7de9606..77d61f16b5b45fbe78deaf90f4ae4b126546c3e9 100644 +index 1e012aef9a515b2e312565e8fe7652f38e080e4b..821df759e3410428b4558e22042c79f29238ebe2 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -633,11 +633,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch b/patches/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch index 3a7066283ff9..2a2c4f2b31f7 100644 --- a/patches/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch +++ b/patches/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch @@ -5,7 +5,7 @@ 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 77d61f16b5b45fbe78deaf90f4ae4b126546c3e9..63f99fb1dde13854ad9be1a57441bd1b1a40c8d6 100644 +index 821df759e3410428b4558e22042c79f29238ebe2..b80af01529206bf55ed028dac41798f91da22f51 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -608,7 +608,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch b/patches/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch index 07883924deb9..426276647c1c 100644 --- a/patches/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch +++ b/patches/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch @@ -18,7 +18,7 @@ index 254e34f80ed0d06f200a78c60f34b4ffc5e5ed85..b8a60520cc10383f22d810ca8061ed25 gameprofilerfiller.push(() -> { String s = String.valueOf(worldserver); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 63f99fb1dde13854ad9be1a57441bd1b1a40c8d6..9aa60bb30ce5f2deddcb8b228ebafac766f02f93 100644 +index b80af01529206bf55ed028dac41798f91da22f51..237a0b4dd0e1c437a021e1d2104e6d523b1f745a 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -230,6 +230,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch b/patches/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch index 5171c96a5209..e529f629a621 100644 --- a/patches/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch +++ b/patches/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Entity AddTo/RemoveFrom World Events diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 9aa60bb30ce5f2deddcb8b228ebafac766f02f93..d773a56d2bea90669f0b65908d990c2fc5313652 100644 +index 237a0b4dd0e1c437a021e1d2104e6d523b1f745a..6ec83b72bb9f762d606fcbf4b93c70f2b025f48f 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2224,6 +2224,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch b/patches/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch index a2348e6b778a..f087a2a35fe5 100644 --- a/patches/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch +++ b/patches/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch @@ -5,7 +5,7 @@ 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 d773a56d2bea90669f0b65908d990c2fc5313652..8dc2b2d8ba32aefc11eb23054b902650fac76adf 100644 +index 6ec83b72bb9f762d606fcbf4b93c70f2b025f48f..5a9c703a252d0c1c57c23ef021e57cdd1de31585 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1402,11 +1402,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0101-Fix-global-sound-handling.patch b/patches/server/0101-Fix-global-sound-handling.patch index e96dd9f673ff..1c4cad79e331 100644 --- a/patches/server/0101-Fix-global-sound-handling.patch +++ b/patches/server/0101-Fix-global-sound-handling.patch @@ -11,7 +11,7 @@ Co-authored-by: lexikiq Co-authored-by: Aikar diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 8dc2b2d8ba32aefc11eb23054b902650fac76adf..21c3d771a3dd921767c2cba1e11583d015879ca9 100644 +index 5a9c703a252d0c1c57c23ef021e57cdd1de31585..022ec2ff1c5a6a1de867b2a6dafb339d55a0905d 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1335,7 +1335,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch b/patches/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch index 00007012a24c..ad688961b8cf 100644 --- a/patches/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch +++ b/patches/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch @@ -20,7 +20,7 @@ index 658ceb9c43bb48f88596cd7270e276a369a3937e..b34663ba24a0925c7fe65b354f4029c5 private final List 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 274c9cc32d7f65456d184db7f61bc4b159f890f8..8cf4ecc5065ade18f0d13eaf0a786912ecb4dd08 100644 +index 9a79b948264150d0f7a843a8ddd2ea9245ae66f3..9389c0ebdcaba5022bdae47b2b2ff06b40406127 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -168,6 +168,56 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0186-Expand-World.spawnParticle-API-and-add-Builder.patch b/patches/server/0186-Expand-World.spawnParticle-API-and-add-Builder.patch index bc692b5fa693..8fcc3562f248 100644 --- a/patches/server/0186-Expand-World.spawnParticle-API-and-add-Builder.patch +++ b/patches/server/0186-Expand-World.spawnParticle-API-and-add-Builder.patch @@ -10,7 +10,7 @@ Adds an option to control the force mode of the particle. This adds a new Builder API which is much friendlier to use. diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 21c3d771a3dd921767c2cba1e11583d015879ca9..252f1deea98a6eb83ac99adea3ea7a3c229c0f07 100644 +index 022ec2ff1c5a6a1de867b2a6dafb339d55a0905d..17cb827bc90d980d73719776fca967a1d307ce0a 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1566,12 +1566,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -34,7 +34,7 @@ index 21c3d771a3dd921767c2cba1e11583d015879ca9..252f1deea98a6eb83ac99adea3ea7a3c 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 8cf4ecc5065ade18f0d13eaf0a786912ecb4dd08..4b2742c0841bd686ee637e1d6dc011e13b0df192 100644 +index 9389c0ebdcaba5022bdae47b2b2ff06b40406127..5231548e886e884f565ff6cc5d45518141fbab2d 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1992,8 +1992,19 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0202-Expand-Explosions-API.patch b/patches/server/0202-Expand-Explosions-API.patch index b454b3ebcf59..b9a5452eb8d6 100644 --- a/patches/server/0202-Expand-Explosions-API.patch +++ b/patches/server/0202-Expand-Explosions-API.patch @@ -9,7 +9,7 @@ Co-authored-by: Esoteric Enderman <90862990+EsotericEnderman@users.noreply.githu Co-authored-by: Bjarne Koll diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 252f1deea98a6eb83ac99adea3ea7a3c229c0f07..a4709b08ea90e15533a3e1b1d22d16e004556243 100644 +index 17cb827bc90d980d73719776fca967a1d307ce0a..6283f3496f122d4b0c4ac297943baf469e44aee3 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1449,6 +1449,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -54,7 +54,7 @@ index 9f37d7284c81d529551107e2836627977efabd65..d1878f597c3d8119e9b248f4fe8af435 while (iterator.hasNext()) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 4b2742c0841bd686ee637e1d6dc011e13b0df192..22543e032f9202d590ac3924b537bb43efba9c93 100644 +index 5231548e886e884f565ff6cc5d45518141fbab2d..e285c8486c36e8d2bc4ddc43e0029943ea5c7fe7 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -784,6 +784,11 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0206-Implement-World.getEntity-UUID-API.patch b/patches/server/0206-Implement-World.getEntity-UUID-API.patch index cb1b631e5dc1..5e9929379abf 100644 --- a/patches/server/0206-Implement-World.getEntity-UUID-API.patch +++ b/patches/server/0206-Implement-World.getEntity-UUID-API.patch @@ -5,7 +5,7 @@ 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 22543e032f9202d590ac3924b537bb43efba9c93..1982385aa0e4984544d2aef88f5cafd5c0d5a49a 100644 +index e285c8486c36e8d2bc4ddc43e0029943ea5c7fe7..e9840a1159419593145d166b54e523fd3e6684f0 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1137,6 +1137,15 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0207-InventoryCloseEvent-Reason-API.patch b/patches/server/0207-InventoryCloseEvent-Reason-API.patch index d0f2f2b3fcc6..968d1a87f8e6 100644 --- a/patches/server/0207-InventoryCloseEvent-Reason-API.patch +++ b/patches/server/0207-InventoryCloseEvent-Reason-API.patch @@ -7,7 +7,7 @@ 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 a4709b08ea90e15533a3e1b1d22d16e004556243..438c936fceede5b21435e1f37f2372072a9d4571 100644 +index 6283f3496f122d4b0c4ac297943baf469e44aee3..425c22fe94e83d880b331cbfb16dc67f22def1c7 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1234,7 +1234,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0224-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch b/patches/server/0224-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch index c1032d9949c9..4338c3faf291 100644 --- a/patches/server/0224-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch +++ b/patches/server/0224-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add Debug Entities option to debug dupe uuid issues diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 438c936fceede5b21435e1f37f2372072a9d4571..3f4d3e2f45c2b2228a333076ec1f34228560593e 100644 +index 425c22fe94e83d880b331cbfb16dc67f22def1c7..a12d5de8834bbc3176be3d2c8353b2d4372dbc1d 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1196,6 +1196,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0229-Optimize-BlockPosition-helper-methods.patch b/patches/server/0229-Optimize-BlockPosition-helper-methods.patch index 44418eff5a78..5c3a739bd054 100644 --- a/patches/server/0229-Optimize-BlockPosition-helper-methods.patch +++ b/patches/server/0229-Optimize-BlockPosition-helper-methods.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Optimize BlockPosition helper methods diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java -index 83e7c141d947f8f8096fed1da716560494bc5c62..eea8bea0f40db8d36c59e628babf788fa920df94 100644 +index 83e7c141d947f8f8096fed1da716560494bc5c62..8e00fd1a1fb0d73e800395f4b9fffdbdb6c6b5cb 100644 --- a/src/main/java/net/minecraft/core/BlockPos.java +++ b/src/main/java/net/minecraft/core/BlockPos.java @@ -157,67 +157,84 @@ public class BlockPos extends Vec3i { @@ -19,7 +19,7 @@ index 83e7c141d947f8f8096fed1da716560494bc5c62..eea8bea0f40db8d36c59e628babf788f @Override public BlockPos above(int distance) { - return this.relative(Direction.UP, distance); -+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY() + distance, this.getZ()); // Paper - Perf: Optimize BlockPosition ++ return distance == 0 ? this.immutable() : new BlockPos(this.getX(), this.getY() + distance, this.getZ()); // Paper - Perf: Optimize BlockPosition } @Override @@ -31,7 +31,7 @@ index 83e7c141d947f8f8096fed1da716560494bc5c62..eea8bea0f40db8d36c59e628babf788f @Override public BlockPos below(int i) { - return this.relative(Direction.DOWN, i); -+ return i == 0 ? this : new BlockPos(this.getX(), this.getY() - i, this.getZ()); // Paper - Perf: Optimize BlockPosition ++ return i == 0 ? this.immutable() : new BlockPos(this.getX(), this.getY() - i, this.getZ()); // Paper - Perf: Optimize BlockPosition } @Override @@ -43,7 +43,7 @@ index 83e7c141d947f8f8096fed1da716560494bc5c62..eea8bea0f40db8d36c59e628babf788f @Override public BlockPos north(int distance) { - return this.relative(Direction.NORTH, distance); -+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY(), this.getZ() - distance); // Paper - Perf: Optimize BlockPosition ++ return distance == 0 ? this.immutable() : new BlockPos(this.getX(), this.getY(), this.getZ() - distance); // Paper - Perf: Optimize BlockPosition } @Override @@ -55,7 +55,7 @@ index 83e7c141d947f8f8096fed1da716560494bc5c62..eea8bea0f40db8d36c59e628babf788f @Override public BlockPos south(int distance) { - return this.relative(Direction.SOUTH, distance); -+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY(), this.getZ() + distance); // Paper - Perf: Optimize BlockPosition ++ return distance == 0 ? this.immutable() : new BlockPos(this.getX(), this.getY(), this.getZ() + distance); // Paper - Perf: Optimize BlockPosition } @Override @@ -67,7 +67,7 @@ index 83e7c141d947f8f8096fed1da716560494bc5c62..eea8bea0f40db8d36c59e628babf788f @Override public BlockPos west(int distance) { - return this.relative(Direction.WEST, distance); -+ return distance == 0 ? this : new BlockPos(this.getX() - distance, this.getY(), this.getZ()); // Paper - Perf: Optimize BlockPosition ++ return distance == 0 ? this.immutable() : new BlockPos(this.getX() - distance, this.getY(), this.getZ()); // Paper - Perf: Optimize BlockPosition } @Override @@ -79,7 +79,7 @@ index 83e7c141d947f8f8096fed1da716560494bc5c62..eea8bea0f40db8d36c59e628babf788f @Override public BlockPos east(int distance) { - return this.relative(Direction.EAST, distance); -+ return distance == 0 ? this : new BlockPos(this.getX() + distance, this.getY(), this.getZ()); // Paper - Perf: Optimize BlockPosition ++ return distance == 0 ? this.immutable() : new BlockPos(this.getX() + distance, this.getY(), this.getZ()); // Paper - Perf: Optimize BlockPosition } @Override diff --git a/patches/server/0238-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch b/patches/server/0238-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch index 79a35711a9cb..bb06c999cf47 100644 --- a/patches/server/0238-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch +++ b/patches/server/0238-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch @@ -6,7 +6,7 @@ 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 1982385aa0e4984544d2aef88f5cafd5c0d5a49a..0a53b01094bd8070e57fb3c967c1129a53bd7ff8 100644 +index e9840a1159419593145d166b54e523fd3e6684f0..a8e738941d8cd6373eb0ae5259da8e763a695657 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -438,7 +438,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0252-Add-sun-related-API.patch b/patches/server/0252-Add-sun-related-API.patch index 63382c55de54..2c323e679fb2 100644 --- a/patches/server/0252-Add-sun-related-API.patch +++ b/patches/server/0252-Add-sun-related-API.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Add sun related API public net.minecraft.world.entity.Mob isSunBurnTick()Z diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 0a53b01094bd8070e57fb3c967c1129a53bd7ff8..d723486f1582b232fbf78898a56caa3a13954417 100644 +index a8e738941d8cd6373eb0ae5259da8e763a695657..d5f8c07480b1dc6b6f97e8ebc74b50493f011f45 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -762,6 +762,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch b/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch index 2e0766fbd74b..206e8d576df6 100644 --- a/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch +++ b/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch @@ -26,7 +26,7 @@ index f55832ce841621daab4d3a910650ab6562cefcda..f635da34335cd2901adf975fcd74c5c6 }); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 3f4d3e2f45c2b2228a333076ec1f34228560593e..64c1fd62a865adb1e11edd326a1a5ccdc98f13ed 100644 +index a12d5de8834bbc3176be3d2c8353b2d4372dbc1d..1976acc359d03447507b32c9032700f4603628f0 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1202,6 +1202,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0297-Duplicate-UUID-Resolve-Option.patch b/patches/server/0297-Duplicate-UUID-Resolve-Option.patch index 502d6dcc289c..b42bece1fca0 100644 --- a/patches/server/0297-Duplicate-UUID-Resolve-Option.patch +++ b/patches/server/0297-Duplicate-UUID-Resolve-Option.patch @@ -33,7 +33,7 @@ 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/world/level/chunk/status/ChunkStatusTasks.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -index 3f552ee8f90566edddb5943311a14309e4bebb61..f18c2b85ed9541f646f157184221e333d0ae58bd 100644 +index 412caefe776df6c8e931f6a1a48ea2525ec6610e..aff4c3d63a97d5bbde004a616f7e14fca59b5ab9 100644 --- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java +++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java @@ -178,10 +178,51 @@ public class ChunkStatusTasks { diff --git a/patches/server/0301-Optimise-EntityGetter-getPlayerByUUID.patch b/patches/server/0301-Optimise-EntityGetter-getPlayerByUUID.patch index e0992abebba1..30f3d7dfdc7e 100644 --- a/patches/server/0301-Optimise-EntityGetter-getPlayerByUUID.patch +++ b/patches/server/0301-Optimise-EntityGetter-getPlayerByUUID.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Optimise EntityGetter#getPlayerByUUID Use the PlayerList 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 64c1fd62a865adb1e11edd326a1a5ccdc98f13ed..c7a1328e6642ad6c76179bddec117c4281577e86 100644 +index 1976acc359d03447507b32c9032700f4603628f0..a0a38a78987f05fe47b5a85a49659e7469674210 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -333,6 +333,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0310-Add-debug-for-sync-chunk-loads.patch b/patches/server/0310-Add-debug-for-sync-chunk-loads.patch index a27b5deba212..3bdd0ab20d92 100644 --- a/patches/server/0310-Add-debug-for-sync-chunk-loads.patch +++ b/patches/server/0310-Add-debug-for-sync-chunk-loads.patch @@ -314,7 +314,7 @@ index 9ab43b4273975d7599f8eee2f95773f2984b7c37..350bfa9c891130b1aa2ab973e86668de chunkproviderserver_b.managedBlock(completablefuture::isDone); this.level.timings.syncChunkLoad.stopTiming(); // Paper diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index c7a1328e6642ad6c76179bddec117c4281577e86..e2984ccee4e01b260109d038969f9ff3ea21b87f 100644 +index a0a38a78987f05fe47b5a85a49659e7469674210..6e3765b00272548318fca647a80c56ad634b7ecc 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -412,6 +412,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0328-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch b/patches/server/0328-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch index 3a9e4f516e8c..9607433b9d1e 100644 --- a/patches/server/0328-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch +++ b/patches/server/0328-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch @@ -25,7 +25,7 @@ index f8decd2f1841da947a3cff5b275efff63ba37def..926e1ebfe3a011a28fb82b855511aaab 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 e2984ccee4e01b260109d038969f9ff3ea21b87f..090d2fde891346ee634a8964b562715f4dd206d0 100644 +index 6e3765b00272548318fca647a80c56ad634b7ecc..609c2e1946c86deabb885d7d703cf42273839f1e 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2232,7 +2232,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch b/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch index 06d3e294ce60..df2237cf9a11 100644 --- a/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch +++ b/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch @@ -104,7 +104,7 @@ index f80164bf8fde13a8702f09e1e1d8aab3ba075e42..acf213f47aea597824e2301e422435fb for (SpawnCategory spawnCategory : SpawnCategory.values()) { if (CraftSpawnCategory.isValidForLimits(spawnCategory)) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index d723486f1582b232fbf78898a56caa3a13954417..e558ce7fddf6835dd78391b2fbc05ee22af059bd 100644 +index d5f8c07480b1dc6b6f97e8ebc74b50493f011f45..84028e959f697fade97640b9b35e5433fcf894ce 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1177,7 +1177,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0373-Add-Plugin-Tickets-to-API-Chunk-Methods.patch b/patches/server/0373-Add-Plugin-Tickets-to-API-Chunk-Methods.patch index e6e5474ade8f..1d3e93eeab58 100644 --- a/patches/server/0373-Add-Plugin-Tickets-to-API-Chunk-Methods.patch +++ b/patches/server/0373-Add-Plugin-Tickets-to-API-Chunk-Methods.patch @@ -44,7 +44,7 @@ index acf213f47aea597824e2301e422435fbb77098fb..dfe625f406ac323ede270d3773e71b09 this.printSaveWarning = false; this.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 e558ce7fddf6835dd78391b2fbc05ee22af059bd..3ea157df3df6f590195191f2c24faead703a0bf8 100644 +index 84028e959f697fade97640b9b35e5433fcf894ce..55daddd0d80a18a3c044f48a47a0a13ef3a68943 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -270,7 +270,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0392-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch b/patches/server/0392-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch index 44e149484c9b..1f6976450054 100644 --- a/patches/server/0392-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch +++ b/patches/server/0392-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch @@ -5,7 +5,7 @@ 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 090d2fde891346ee634a8964b562715f4dd206d0..465b6a1bbdbb193c6ecf5fd1598e1e4a4f8dbbbc 100644 +index 609c2e1946c86deabb885d7d703cf42273839f1e..97ce1e1d877d34581f0475066f604d5a1f349d90 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1730,7 +1730,9 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -19,7 +19,7 @@ index 090d2fde891346ee634a8964b562715f4dd206d0..465b6a1bbdbb193c6ecf5fd1598e1e4a } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 3ea157df3df6f590195191f2c24faead703a0bf8..04ef1c3433d3ac8a58f0d460877e176668e0fc8f 100644 +index 55daddd0d80a18a3c044f48a47a0a13ef3a68943..b0fbb828306194fd91f0e62244d5db6404b4f10a 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -250,12 +250,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0407-Extend-block-drop-capture-to-capture-all-items-added.patch b/patches/server/0407-Extend-block-drop-capture-to-capture-all-items-added.patch index 12a14918c34e..29e625b19582 100644 --- a/patches/server/0407-Extend-block-drop-capture-to-capture-all-items-added.patch +++ b/patches/server/0407-Extend-block-drop-capture-to-capture-all-items-added.patch @@ -6,7 +6,7 @@ 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 465b6a1bbdbb193c6ecf5fd1598e1e4a4f8dbbbc..a3ce6feff0826dcfb2a11b0f6cd01a5368c2de3a 100644 +index 97ce1e1d877d34581f0475066f604d5a1f349d90..ca1c8cc67fe00dc7ad5e942a387f95cbad415e86 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1223,6 +1223,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0456-Add-WorldGameRuleChangeEvent.patch b/patches/server/0456-Add-WorldGameRuleChangeEvent.patch index 7925a1810ace..b03d1f41d621 100644 --- a/patches/server/0456-Add-WorldGameRuleChangeEvent.patch +++ b/patches/server/0456-Add-WorldGameRuleChangeEvent.patch @@ -64,7 +64,7 @@ index 7ea92a0b0f5d4eb6bd873e61c42bc0499d5d2028..09299e45552eb998fd02123c3921c065 public int get() { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 04ef1c3433d3ac8a58f0d460877e176668e0fc8f..5541a9f197777124dd908e3f56050b49df821acc 100644 +index b0fbb828306194fd91f0e62244d5db6404b4f10a..e19e5f1223f8b4fae9292a936dd05b9170610134 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1899,9 +1899,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0464-Remove-stale-POIs.patch b/patches/server/0464-Remove-stale-POIs.patch index 70792fa6b322..1574ebae111a 100644 --- a/patches/server/0464-Remove-stale-POIs.patch +++ b/patches/server/0464-Remove-stale-POIs.patch @@ -5,7 +5,7 @@ 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 a3ce6feff0826dcfb2a11b0f6cd01a5368c2de3a..d62d6a345837e1b63c1a1393f18e367ac0ef4c30 100644 +index ca1c8cc67fe00dc7ad5e942a387f95cbad415e86..840651df480dfc6e494240aaa46ea4063171c0de 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1805,6 +1805,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0480-Add-EntityMoveEvent.patch b/patches/server/0480-Add-EntityMoveEvent.patch index 7de1d3e93c1b..a37da973da80 100644 --- a/patches/server/0480-Add-EntityMoveEvent.patch +++ b/patches/server/0480-Add-EntityMoveEvent.patch @@ -17,7 +17,7 @@ index c7fde30d2ea24a78d177ee38a121f02c2c71b141..223123bf689dc62abaff8086447e9258 gameprofilerfiller.push(() -> { String s = String.valueOf(worldserver); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index d62d6a345837e1b63c1a1393f18e367ac0ef4c30..b91ed08e8d9fbd399834d19ef01ebe5692d1ee4a 100644 +index 840651df480dfc6e494240aaa46ea4063171c0de..12f46c94710830f464ff27a3d415140c36065e10 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -231,6 +231,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0481-added-option-to-disable-pathfinding-updates-on-block.patch b/patches/server/0481-added-option-to-disable-pathfinding-updates-on-block.patch index 385032783495..c2bfd19f1422 100644 --- a/patches/server/0481-added-option-to-disable-pathfinding-updates-on-block.patch +++ b/patches/server/0481-added-option-to-disable-pathfinding-updates-on-block.patch @@ -5,7 +5,7 @@ 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 b91ed08e8d9fbd399834d19ef01ebe5692d1ee4a..d696ec118367f64fa7151189a4ace58287329851 100644 +index 12f46c94710830f464ff27a3d415140c36065e10..8352e42a3dceb33477c5885433d24840e1332b87 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1387,6 +1387,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0512-More-World-API.patch b/patches/server/0512-More-World-API.patch index ee3ec71b36ad..3fdba120da2f 100644 --- a/patches/server/0512-More-World-API.patch +++ b/patches/server/0512-More-World-API.patch @@ -5,7 +5,7 @@ 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 5541a9f197777124dd908e3f56050b49df821acc..de1d312d67bcdadbf7797a71909b4030e29a71f6 100644 +index e19e5f1223f8b4fae9292a936dd05b9170610134..e44a78a34aa572b10deb3f343c238cad1c521ab4 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -2145,6 +2145,28 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0536-Add-cause-to-Weather-ThunderChangeEvents.patch b/patches/server/0536-Add-cause-to-Weather-ThunderChangeEvents.patch index 575d5d07465f..9e50f7f9b71e 100644 --- a/patches/server/0536-Add-cause-to-Weather-ThunderChangeEvents.patch +++ b/patches/server/0536-Add-cause-to-Weather-ThunderChangeEvents.patch @@ -5,7 +5,7 @@ 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 d696ec118367f64fa7151189a4ace58287329851..355b60f8d0d600973da673db5a954345f3a0094d 100644 +index 8352e42a3dceb33477c5885433d24840e1332b87..1be314ed35d07e6db9a3f6a4f493b0f4bb59a45f 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -431,8 +431,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -95,7 +95,7 @@ index 6a3959095e57f76b3a092b32d26ff91cf1c5e068..0fa16ff37f09ecfda104b751e48bf246 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 de1d312d67bcdadbf7797a71909b4030e29a71f6..bbc5d6834e52d2fb92fd41156ba0ae0600282b59 100644 +index e44a78a34aa572b10deb3f343c238cad1c521ab4..07986523451a755515c912e5cab5172195b929de 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1220,7 +1220,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0549-add-per-world-spawn-limits.patch b/patches/server/0549-add-per-world-spawn-limits.patch index 080727bf9b08..ef9111f7fc4e 100644 --- a/patches/server/0549-add-per-world-spawn-limits.patch +++ b/patches/server/0549-add-per-world-spawn-limits.patch @@ -5,7 +5,7 @@ Subject: [PATCH] add per world spawn limits diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index bbc5d6834e52d2fb92fd41156ba0ae0600282b59..6aa21f31b5d766cf6c9a94243dde652fbcb3cc61 100644 +index 07986523451a755515c912e5cab5172195b929de..9e0f2900dea70c471ea73b190b8aa2d9abd37ee6 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -226,6 +226,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0555-Use-getChunkIfLoadedImmediately-in-places.patch b/patches/server/0555-Use-getChunkIfLoadedImmediately-in-places.patch index 54ff2754886f..a5b4d06295df 100644 --- a/patches/server/0555-Use-getChunkIfLoadedImmediately-in-places.patch +++ b/patches/server/0555-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 355b60f8d0d600973da673db5a954345f3a0094d..83f3f05ffe61d77417bce50ce7ae6a8671605e9e 100644 +index 1be314ed35d07e6db9a3f6a4f493b0f4bb59a45f..d8f7d7512db9432f67b07e7d64a6a9349dfab245 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -234,7 +234,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0579-Add-methods-to-find-targets-for-lightning-strikes.patch b/patches/server/0579-Add-methods-to-find-targets-for-lightning-strikes.patch index 154b2264caf5..6727d31ea681 100644 --- a/patches/server/0579-Add-methods-to-find-targets-for-lightning-strikes.patch +++ b/patches/server/0579-Add-methods-to-find-targets-for-lightning-strikes.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Add methods to find targets for lightning strikes public net.minecraft.server.level.ServerLevel findLightningRod(Lnet/minecraft/core/BlockPos;)Ljava/util/Optional; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 83f3f05ffe61d77417bce50ce7ae6a8671605e9e..bd99c1ca778270dc80ba83b46dbd178890dd7b53 100644 +index d8f7d7512db9432f67b07e7d64a6a9349dfab245..3137738307bb7b43190fa65da26e0b038012a9f4 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -751,6 +751,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -31,7 +31,7 @@ index 83f3f05ffe61d77417bce50ce7ae6a8671605e9e..bd99c1ca778270dc80ba83b46dbd1788 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 6aa21f31b5d766cf6c9a94243dde652fbcb3cc61..f4a866f7648413a9ade527efe0643b04e17baeb7 100644 +index 9e0f2900dea70c471ea73b190b8aa2d9abd37ee6..06ccf20081ecd2b56f9e5aeef988804fef10df73 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -695,6 +695,23 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0591-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch b/patches/server/0591-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch index eefcbc16a90a..8404f01faa07 100644 --- a/patches/server/0591-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch +++ b/patches/server/0591-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch @@ -9,7 +9,7 @@ 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 bd99c1ca778270dc80ba83b46dbd178890dd7b53..cf2b5de61eae020513c50e0903637c55b711fd1b 100644 +index 3137738307bb7b43190fa65da26e0b038012a9f4..0485312d40dca972d2477b8d4a4725ff25deacbc 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1269,9 +1269,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0593-Improve-and-expand-AsyncCatcher.patch b/patches/server/0593-Improve-and-expand-AsyncCatcher.patch index 4fa63c470258..921cb5a829ab 100644 --- a/patches/server/0593-Improve-and-expand-AsyncCatcher.patch +++ b/patches/server/0593-Improve-and-expand-AsyncCatcher.patch @@ -42,7 +42,7 @@ index 1cb118c12e1b09cb6ae8d3b6949212b46c91b85b..21f9fc5c3111dc126d0197a02bb61541 this.effectsToProcess.add(new ProcessableEffect(mobeffect, cause)); return true; 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 1cfc906317f07a44f06a4adf021c44e34a2f1d07..6baa313b8201ed23193d7885c85606b0899ade3c 100644 +index 4eb0b0969325f39a7ae65492cccd482515a50142..5aa74c00a61282830d82359eae2b114e2a48b6d9 100644 --- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java +++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java @@ -78,6 +78,7 @@ public class PersistentEntitySectionManager implements A @@ -59,9 +59,9 @@ index 1cfc906317f07a44f06a4adf021c44e34a2f1d07..6baa313b8201ed23193d7885c85606b0 private boolean addEntity(T entity, boolean existing) { + org.spigotmc.AsyncCatcher.catchOp("Entity add"); // Paper // Paper start - chunk system hooks - if (existing) { - // I don't want to know why this is a generic type. -@@ -146,19 +148,23 @@ public class PersistentEntitySectionManager implements A + // I don't want to know why this is a generic type. + Entity entityCasted = (Entity)entity; +@@ -144,19 +146,23 @@ public class PersistentEntitySectionManager implements A } void startTicking(T entity) { @@ -85,7 +85,7 @@ index 1cfc906317f07a44f06a4adf021c44e34a2f1d07..6baa313b8201ed23193d7885c85606b0 this.callbacks.onTrackingEnd(entity); this.visibleEntityStorage.remove(entity); } -@@ -170,6 +176,7 @@ public class PersistentEntitySectionManager implements A +@@ -168,6 +174,7 @@ public class PersistentEntitySectionManager implements A } public void updateChunkStatus(ChunkPos chunkPos, Visibility trackingStatus) { @@ -93,7 +93,7 @@ index 1cfc906317f07a44f06a4adf021c44e34a2f1d07..6baa313b8201ed23193d7885c85606b0 long i = chunkPos.toLong(); if (trackingStatus == Visibility.HIDDEN) { -@@ -214,6 +221,7 @@ public class PersistentEntitySectionManager implements A +@@ -212,6 +219,7 @@ public class PersistentEntitySectionManager implements A } public void ensureChunkQueuedForLoad(long chunkPos) { @@ -101,7 +101,7 @@ index 1cfc906317f07a44f06a4adf021c44e34a2f1d07..6baa313b8201ed23193d7885c85606b0 PersistentEntitySectionManager.ChunkLoadStatus persistententitysectionmanager_b = (PersistentEntitySectionManager.ChunkLoadStatus) this.chunkLoadStatuses.get(chunkPos); if (persistententitysectionmanager_b == PersistentEntitySectionManager.ChunkLoadStatus.FRESH) { -@@ -258,6 +266,7 @@ public class PersistentEntitySectionManager implements A +@@ -256,6 +264,7 @@ public class PersistentEntitySectionManager implements A } private void requestChunkLoad(long chunkPos) { @@ -109,7 +109,7 @@ index 1cfc906317f07a44f06a4adf021c44e34a2f1d07..6baa313b8201ed23193d7885c85606b0 this.chunkLoadStatuses.put(chunkPos, PersistentEntitySectionManager.ChunkLoadStatus.PENDING); ChunkPos chunkcoordintpair = new ChunkPos(chunkPos); CompletableFuture completablefuture = this.permanentStorage.loadEntities(chunkcoordintpair); -@@ -271,6 +280,7 @@ public class PersistentEntitySectionManager implements A +@@ -269,6 +278,7 @@ public class PersistentEntitySectionManager implements A } private boolean processChunkUnload(long chunkPos) { @@ -117,7 +117,7 @@ index 1cfc906317f07a44f06a4adf021c44e34a2f1d07..6baa313b8201ed23193d7885c85606b0 boolean flag = this.storeChunkSections(chunkPos, (entityaccess) -> { entityaccess.getPassengersAndSelf().forEach(this::unloadEntity); }, true); // CraftBukkit - add boolean for event call -@@ -295,6 +305,7 @@ public class PersistentEntitySectionManager implements A +@@ -293,6 +303,7 @@ public class PersistentEntitySectionManager implements A } private void processPendingLoads() { @@ -125,7 +125,7 @@ index 1cfc906317f07a44f06a4adf021c44e34a2f1d07..6baa313b8201ed23193d7885c85606b0 ChunkEntities chunkentities; // CraftBukkit - decompile error while ((chunkentities = (ChunkEntities) this.loadingInbox.poll()) != null) { -@@ -311,6 +322,7 @@ public class PersistentEntitySectionManager implements A +@@ -309,6 +320,7 @@ public class PersistentEntitySectionManager implements A } public void tick() { @@ -133,7 +133,7 @@ index 1cfc906317f07a44f06a4adf021c44e34a2f1d07..6baa313b8201ed23193d7885c85606b0 this.processPendingLoads(); this.processUnloads(); } -@@ -331,6 +343,7 @@ public class PersistentEntitySectionManager implements A +@@ -329,6 +341,7 @@ public class PersistentEntitySectionManager implements A } public void autoSave() { @@ -141,7 +141,7 @@ index 1cfc906317f07a44f06a4adf021c44e34a2f1d07..6baa313b8201ed23193d7885c85606b0 this.getAllChunksToSave().forEach((java.util.function.LongConsumer) (i) -> { // CraftBukkit - decompile error boolean flag = this.chunkVisibility.get(i) == Visibility.HIDDEN; -@@ -345,6 +358,7 @@ public class PersistentEntitySectionManager implements A +@@ -343,6 +356,7 @@ public class PersistentEntitySectionManager implements A } public void saveAll() { @@ -149,7 +149,7 @@ index 1cfc906317f07a44f06a4adf021c44e34a2f1d07..6baa313b8201ed23193d7885c85606b0 LongSet longset = this.getAllChunksToSave(); while (!longset.isEmpty()) { -@@ -452,6 +466,7 @@ public class PersistentEntitySectionManager implements A +@@ -450,6 +464,7 @@ public class PersistentEntitySectionManager implements A long i = SectionPos.asLong(blockposition); if (i != this.currentSectionKey) { @@ -157,7 +157,7 @@ index 1cfc906317f07a44f06a4adf021c44e34a2f1d07..6baa313b8201ed23193d7885c85606b0 Visibility visibility = this.currentSection.getStatus(); if (!this.currentSection.remove(this.entity)) { -@@ -506,6 +521,7 @@ public class PersistentEntitySectionManager implements A +@@ -504,6 +519,7 @@ public class PersistentEntitySectionManager implements A @Override public void onRemove(Entity.RemovalReason reason) { @@ -166,7 +166,7 @@ index 1cfc906317f07a44f06a4adf021c44e34a2f1d07..6baa313b8201ed23193d7885c85606b0 PersistentEntitySectionManager.LOGGER.warn("Entity {} wasn't found in section {} (destroying due to {})", new Object[]{this.entity, SectionPos.of(this.currentSectionKey), reason}); } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index f4a866f7648413a9ade527efe0643b04e17baeb7..e221ec75905387bc0b65b816847a224b969b71fe 100644 +index 06ccf20081ecd2b56f9e5aeef988804fef10df73..f10b9898f180b231ce793cc03488df5a359b0ac0 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1770,6 +1770,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0594-Add-paper-mobcaps-and-paper-playermobcaps.patch b/patches/server/0594-Add-paper-mobcaps-and-paper-playermobcaps.patch index 7c4af597be7e..b998ef75b4d5 100644 --- a/patches/server/0594-Add-paper-mobcaps-and-paper-playermobcaps.patch +++ b/patches/server/0594-Add-paper-mobcaps-and-paper-playermobcaps.patch @@ -294,7 +294,7 @@ index 35e5a3dc58f93b85f93ec5301cc9b5c7505503bc..f69504676d2f48f3778f489ec1e08e2b } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index e221ec75905387bc0b65b816847a224b969b71fe..9811fffb16ab7b28e3a9eb5276fb18156c4ebf12 100644 +index f10b9898f180b231ce793cc03488df5a359b0ac0..5050c9a9d5369a829f5b47a56b7621de05c9a6de 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1728,9 +1728,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0596-Manually-inline-methods-in-BlockPosition.patch b/patches/server/0596-Manually-inline-methods-in-BlockPosition.patch index 90699bfbcfd1..89987ab3d210 100644 --- a/patches/server/0596-Manually-inline-methods-in-BlockPosition.patch +++ b/patches/server/0596-Manually-inline-methods-in-BlockPosition.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Manually inline methods in BlockPosition diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java -index eea8bea0f40db8d36c59e628babf788fa920df94..0d51fb4be8b49e3b57c3c55aff6bcf13d5c78ddd 100644 +index 8e00fd1a1fb0d73e800395f4b9fffdbdb6c6b5cb..a1d54d978d34d75475f92dfb806113586e7e449c 100644 --- a/src/main/java/net/minecraft/core/BlockPos.java +++ b/src/main/java/net/minecraft/core/BlockPos.java @@ -576,9 +576,9 @@ public class BlockPos extends Vec3i { diff --git a/patches/server/0605-Fix-merchant-inventory-not-closing-on-entity-removal.patch b/patches/server/0605-Fix-merchant-inventory-not-closing-on-entity-removal.patch index 0969b0e6445a..4b017db5b613 100644 --- a/patches/server/0605-Fix-merchant-inventory-not-closing-on-entity-removal.patch +++ b/patches/server/0605-Fix-merchant-inventory-not-closing-on-entity-removal.patch @@ -5,7 +5,7 @@ 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 cf2b5de61eae020513c50e0903637c55b711fd1b..0fbd077c1d3dddc97c8c99effa936470562b02a4 100644 +index 0485312d40dca972d2477b8d4a4725ff25deacbc..3ca2c0d937dc840ac64fb1efd73dbc5b045bc77d 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2328,6 +2328,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0642-Expose-vanilla-BiomeProvider-from-WorldInfo.patch b/patches/server/0642-Expose-vanilla-BiomeProvider-from-WorldInfo.patch index 9c88848d1de8..56b9aa820a87 100644 --- a/patches/server/0642-Expose-vanilla-BiomeProvider-from-WorldInfo.patch +++ b/patches/server/0642-Expose-vanilla-BiomeProvider-from-WorldInfo.patch @@ -18,7 +18,7 @@ index ec6f8a055131addd2ce95e76d8e781d0595dde76..7e85d9e00f41abb26fbf0e21e70ab820 biomeProvider = gen.getDefaultBiomeProvider(worldInfo); } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 0fbd077c1d3dddc97c8c99effa936470562b02a4..f46393f68ce7ff45302d6aef78b33b18fd10339b 100644 +index 3ca2c0d937dc840ac64fb1efd73dbc5b045bc77d..9ac6d2e87bbad00c9b97028b0e9c2a42cf29801b 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -359,7 +359,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -44,7 +44,7 @@ index f69504676d2f48f3778f489ec1e08e2b3dec85cc..d30c1e853bb2e27922a00d890dffca15 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 9811fffb16ab7b28e3a9eb5276fb18156c4ebf12..da761980a12dc08ca77dadc8773b4467a48637f9 100644 +index 5050c9a9d5369a829f5b47a56b7621de05c9a6de..0ff12d4e74c14b2b0ecf06d720c5e06edb35fcdb 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -216,6 +216,39 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0667-Fix-falling-block-spawn-methods.patch b/patches/server/0667-Fix-falling-block-spawn-methods.patch index 631a80ae7308..771588bb1233 100644 --- a/patches/server/0667-Fix-falling-block-spawn-methods.patch +++ b/patches/server/0667-Fix-falling-block-spawn-methods.patch @@ -11,7 +11,7 @@ Restores the API behavior from previous versions of the server public net.minecraft.world.entity.item.FallingBlockEntity (Lnet/minecraft/world/level/Level;DDDLnet/minecraft/world/level/block/state/BlockState;)V diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index da761980a12dc08ca77dadc8773b4467a48637f9..4bcd91f946dd6157a345ae8e7d049bff051911b3 100644 +index 0ff12d4e74c14b2b0ecf06d720c5e06edb35fcdb..9240460b9ec582ac01d3074c9bc923191bf0ad95 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1405,7 +1405,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0695-Don-t-tick-markers.patch b/patches/server/0695-Don-t-tick-markers.patch index b6d708b61bf2..c20ce6004468 100644 --- a/patches/server/0695-Don-t-tick-markers.patch +++ b/patches/server/0695-Don-t-tick-markers.patch @@ -23,7 +23,7 @@ index 67fcba634f8183bb33834ac3b2c3dcfb8d87129e..777b789fdcdf297309cfb36fc7f77e3f } }); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index f46393f68ce7ff45302d6aef78b33b18fd10339b..d226b51933d25f9a31f285d7715d162302835b02 100644 +index 9ac6d2e87bbad00c9b97028b0e9c2a42cf29801b..cb33c53d441d2d535b48cb80f5ac445b52cd98be 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2249,6 +2249,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0710-Prevent-empty-items-from-being-added-to-world.patch b/patches/server/0710-Prevent-empty-items-from-being-added-to-world.patch index ce2a1d53592f..9c6532791944 100644 --- a/patches/server/0710-Prevent-empty-items-from-being-added-to-world.patch +++ b/patches/server/0710-Prevent-empty-items-from-being-added-to-world.patch @@ -7,7 +7,7 @@ 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 d226b51933d25f9a31f285d7715d162302835b02..100661b77466152a651d22daa7df992c28fbbecb 100644 +index cb33c53d441d2d535b48cb80f5ac445b52cd98be..f9f00a3862ab829e7695b1da484cb752bdef5c4f 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1230,6 +1230,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0716-More-Teleport-API.patch b/patches/server/0716-More-Teleport-API.patch index 850f742352b2..c2d39bdc6395 100644 --- a/patches/server/0716-More-Teleport-API.patch +++ b/patches/server/0716-More-Teleport-API.patch @@ -29,7 +29,7 @@ index ac2ad33a44ce04d9673adc08ff21a167d606e4db..349da8b85b7a122977fcad80a3996051 positionmoverotation = new PositionMoveRotation(CraftLocation.toVec3D(to), Vec3.ZERO, to.getYaw(), to.getPitch()); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 4e6afa243d6108cb946a8a7cf96c4036a3c2ac0c..43786eacc72cdf3bb209d3dfb1808ea9d021a52e 100644 +index 4e6afa243d6108cb946a8a7cf96c4036a3c2ac0c..a314e401ee8a306dc12a2d98a3d400ae611a6e5a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -222,15 +222,36 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { @@ -86,7 +86,7 @@ index 4e6afa243d6108cb946a8a7cf96c4036a3c2ac0c..43786eacc72cdf3bb209d3dfb1808ea9 + java.util.concurrent.CompletableFuture 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) -> { ++ this instanceof CraftPlayer ? ca.spottedleaf.concurrentutil.util.Priority.HIGHER : ca.spottedleaf.concurrentutil.util.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()); diff --git a/patches/server/0720-Warn-on-plugins-accessing-faraway-chunks.patch b/patches/server/0720-Warn-on-plugins-accessing-faraway-chunks.patch index ebdb019a1b43..c1e4213d1cb6 100644 --- a/patches/server/0720-Warn-on-plugins-accessing-faraway-chunks.patch +++ b/patches/server/0720-Warn-on-plugins-accessing-faraway-chunks.patch @@ -18,7 +18,7 @@ index 8269bf24f5e17f9e3936659aa0cbc9d4f95fb665..a6f538372830f3f80740ef503733736e 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 4bcd91f946dd6157a345ae8e7d049bff051911b3..67d6840faea539b41ba3abb6d94b28e417a84511 100644 +index 9240460b9ec582ac01d3074c9bc923191bf0ad95..c0f5e4497e1ffc93f56fc2b5748bcf76569e8c3a 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -309,9 +309,24 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0723-Collision-API.patch b/patches/server/0723-Collision-API.patch index 892f39211ed4..6f4b6366a8dd 100644 --- a/patches/server/0723-Collision-API.patch +++ b/patches/server/0723-Collision-API.patch @@ -22,7 +22,7 @@ index a7748f4b7c5a1630937c702b3fd5fded93793d64..a93a879117ee1eb06842242aa03f757a // 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 43786eacc72cdf3bb209d3dfb1808ea9d021a52e..775675483c1f90fbe8e9e5eadab7d791e81983f5 100644 +index a314e401ee8a306dc12a2d98a3d400ae611a6e5a..01513cd747a0e18e3839e83bf5795aadb7d1e0e9 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -1194,4 +1194,20 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { diff --git a/patches/server/0735-Configurable-chat-thread-limit.patch b/patches/server/0735-Configurable-chat-thread-limit.patch index 882f700d25f6..1432c0659448 100644 --- a/patches/server/0735-Configurable-chat-thread-limit.patch +++ b/patches/server/0735-Configurable-chat-thread-limit.patch @@ -22,10 +22,10 @@ is actually processed, this is honestly really just exposed for the misnomers or who just wanna ensure that this won't grow over a specific size if chat gets stupidly active diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index b92bfd89e32becde2e7630c6116c16f8a4f6614a..73e8a524925ed6f2580d3bd01616646fabafda78 100644 +index 904d2f96a60e72aa089fdfe6be08044b04f995c1..36b96e0ed5c0d25068ec4678eddd8a19a020d345 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -303,7 +303,18 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -327,7 +327,18 @@ public class GlobalConfiguration extends ConfigurationPart { @PostProcess private void postProcess() { diff --git a/patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch b/patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch index 52154e4e5a35..69ca61a6dc2b 100644 --- a/patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch +++ b/patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch @@ -104,7 +104,7 @@ index 75854574aa8d4aef35d84ba4c0fc7df9a67ae48c..3f3124bbb5077a18c3d3afac7748a47e return this.anyPlayerCloseEnoughForSpawning(pos, false); } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 100661b77466152a651d22daa7df992c28fbbecb..79fabd52eb3a08ec9c9ab2ec5d6ff4a31a02a292 100644 +index f9f00a3862ab829e7695b1da484cb752bdef5c4f..fbee72c0b6e7d73cb0a999330ac7871bb8a7d7e4 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -764,7 +764,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0741-Remove-unnecessary-onTrackingStart-during-navigation.patch b/patches/server/0741-Remove-unnecessary-onTrackingStart-during-navigation.patch index 9cef4dcb920a..b26563ecdf18 100644 --- a/patches/server/0741-Remove-unnecessary-onTrackingStart-during-navigation.patch +++ b/patches/server/0741-Remove-unnecessary-onTrackingStart-during-navigation.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Remove unnecessary onTrackingStart during navigation warning diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 79fabd52eb3a08ec9c9ab2ec5d6ff4a31a02a292..4b2309d27867eddc50093e895503e02184e1b825 100644 +index fbee72c0b6e7d73cb0a999330ac7871bb8a7d7e4..18d39f4a8b1b15960a9b8351d46a62bea848f9c8 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2267,7 +2267,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0761-check-global-player-list-where-appropriate.patch b/patches/server/0761-check-global-player-list-where-appropriate.patch index 586cac4e1920..e96a666062de 100644 --- a/patches/server/0761-check-global-player-list-where-appropriate.patch +++ b/patches/server/0761-check-global-player-list-where-appropriate.patch @@ -7,7 +7,7 @@ Makes certain entities check all players when searching for a player instead of just checking players in their world. diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 4b2309d27867eddc50093e895503e02184e1b825..3eaeeb3ec715d92fe99e14c37e224cb1e80a467b 100644 +index 18d39f4a8b1b15960a9b8351d46a62bea848f9c8..79acbaf880d5f47efd210627a60ce1e930b63e39 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2383,4 +2383,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0773-Add-Sneaking-API-for-Entities.patch b/patches/server/0773-Add-Sneaking-API-for-Entities.patch index 27bb5274f83b..40141ca398c1 100644 --- a/patches/server/0773-Add-Sneaking-API-for-Entities.patch +++ b/patches/server/0773-Add-Sneaking-API-for-Entities.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add Sneaking API for Entities diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 775675483c1f90fbe8e9e5eadab7d791e81983f5..5e413803f9bdc898a9a644cb123363cbdf447ad8 100644 +index 01513cd747a0e18e3839e83bf5795aadb7d1e0e9..8a715159917950091e8efd48eaca6a54488fb896 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -875,6 +875,18 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { diff --git a/patches/server/0787-Add-Entity-Body-Yaw-API.patch b/patches/server/0787-Add-Entity-Body-Yaw-API.patch index bac79c9d6914..2a926f1388a2 100644 --- a/patches/server/0787-Add-Entity-Body-Yaw-API.patch +++ b/patches/server/0787-Add-Entity-Body-Yaw-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add Entity Body Yaw API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 5e413803f9bdc898a9a644cb123363cbdf447ad8..f473df7a5aea6a89fb1eed28c9071b7eb3269cf8 100644 +index 8a715159917950091e8efd48eaca6a54488fb896..4209434ff066670000dadb0c59fea297f03300f4 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -1184,6 +1184,33 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { diff --git a/patches/server/0801-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch b/patches/server/0801-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch index 7621693e89ad..bb2d2b2c3159 100644 --- a/patches/server/0801-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch +++ b/patches/server/0801-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Prevent GameEvents being fired from unloaded chunks diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 3eaeeb3ec715d92fe99e14c37e224cb1e80a467b..509a67aff07bcdcad47eb77e923d442349a4f20c 100644 +index 79acbaf880d5f47efd210627a60ce1e930b63e39..537a755d097d7713404d83dc47cd17828b15a906 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1385,6 +1385,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0836-Folia-scheduler-and-owned-region-API.patch b/patches/server/0836-Folia-scheduler-and-owned-region-API.patch index ed91fc99abe7..ebfcdcbcc257 100644 --- a/patches/server/0836-Folia-scheduler-and-owned-region-API.patch +++ b/patches/server/0836-Folia-scheduler-and-owned-region-API.patch @@ -1330,7 +1330,7 @@ index 1310bdd5ced5941b2ab4ed1f15365722c0b8252d..0193505562d7bdc6d2ab91b637a916cd ConfigurationSerialization.registerClass(CraftOfflinePlayer.class); ConfigurationSerialization.registerClass(CraftPlayerProfile.class); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index f473df7a5aea6a89fb1eed28c9071b7eb3269cf8..d57798d6a53334eacf8235c0fd0f28d7719593fe 100644 +index 4209434ff066670000dadb0c59fea297f03300f4..df199c1cffa7795126ab83af67e184238ddb211d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -71,6 +71,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { diff --git a/patches/server/0839-Only-capture-actual-tree-growth.patch b/patches/server/0839-Only-capture-actual-tree-growth.patch index 63a72d6ca21e..58fb59ab7ddd 100644 --- a/patches/server/0839-Only-capture-actual-tree-growth.patch +++ b/patches/server/0839-Only-capture-actual-tree-growth.patch @@ -17,7 +17,7 @@ index f8f570a97789ab16e57774f233506a289277d5d9..18304349c9ab24657c4152aff800dba9 } } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 509a67aff07bcdcad47eb77e923d442349a4f20c..1cb5e107a391ab56942cdb2d1cae7d5646a85ec6 100644 +index 537a755d097d7713404d83dc47cd17828b15a906..9270584d74edf5c1af473b1a13f7edca74cc1ec7 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2228,6 +2228,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0846-Bandaid-fix-for-Effect.patch b/patches/server/0846-Bandaid-fix-for-Effect.patch index 26b1a9f2368d..8c6534f28eff 100644 --- a/patches/server/0846-Bandaid-fix-for-Effect.patch +++ b/patches/server/0846-Bandaid-fix-for-Effect.patch @@ -68,7 +68,7 @@ index 71733f918ed84b9879ac1b142ef6205c5e768a9c..c856384019eff2f2d0bb831ebe1ccb0f break; case BONE_MEAL_USE: diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 67d6840faea539b41ba3abb6d94b28e417a84511..b646f882de3ab04d54d07e9e944c261c310b58fd 100644 +index c0f5e4497e1ffc93f56fc2b5748bcf76569e8c3a..188bd33f46b6baaa3fc21c9da6fa9a9d004e899e 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1382,7 +1382,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0848-API-for-an-entity-s-scoreboard-name.patch b/patches/server/0848-API-for-an-entity-s-scoreboard-name.patch index ac005db8216d..68f3c7789a89 100644 --- a/patches/server/0848-API-for-an-entity-s-scoreboard-name.patch +++ b/patches/server/0848-API-for-an-entity-s-scoreboard-name.patch @@ -7,7 +7,7 @@ Was obtainable through different methods, but you had to use different methods depending on the implementation of Entity you were working with. diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index d57798d6a53334eacf8235c0fd0f28d7719593fe..0d2d1b6eab153aea6015bd69f2bad58e67d065c3 100644 +index df199c1cffa7795126ab83af67e184238ddb211d..dd84f7d6874a799aa09349fe0a1bd6ebb4cea2dd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -1264,4 +1264,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { diff --git a/patches/server/0858-Expand-Pose-API.patch b/patches/server/0858-Expand-Pose-API.patch index 891dd712d64f..5fcd53b27b55 100644 --- a/patches/server/0858-Expand-Pose-API.patch +++ b/patches/server/0858-Expand-Pose-API.patch @@ -25,7 +25,7 @@ index d8331b2d4ad3ebebb6ecbbf083f3464dad38f623..63e68376d1854f4f7ff1a1d0a11fcec1 if (pose == this.getPose()) { return; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 0d2d1b6eab153aea6015bd69f2bad58e67d065c3..9c8e2731ca37a16cb538da27190c085bbc9791e3 100644 +index dd84f7d6874a799aa09349fe0a1bd6ebb4cea2dd..11a08ff211a9a32a825519ddb1736e02cf7f685e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -900,6 +900,20 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { diff --git a/patches/server/0881-Fix-missing-map-initialize-event-call.patch b/patches/server/0881-Fix-missing-map-initialize-event-call.patch index 795f551f59dd..f2047845c647 100644 --- a/patches/server/0881-Fix-missing-map-initialize-event-call.patch +++ b/patches/server/0881-Fix-missing-map-initialize-event-call.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Fix missing map initialize event call public net.minecraft.world.level.storage.DimensionDataStorage readSavedData(Ljava/util/function/Function;Lnet/minecraft/util/datafix/DataFixTypes;Ljava/lang/String;)Lnet/minecraft/world/level/saveddata/SavedData; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 1cb5e107a391ab56942cdb2d1cae7d5646a85ec6..7acb24c2a34fdcbcb1c0e3cc03b01996689667d3 100644 +index 9270584d74edf5c1af473b1a13f7edca74cc1ec7..1bacbb0d0bd5198d0f946a959b2335d6fba0ca88 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1726,13 +1726,29 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0890-Add-predicate-for-blocks-when-raytracing.patch b/patches/server/0890-Add-predicate-for-blocks-when-raytracing.patch index ea7280cbe567..fdeae8627c1f 100644 --- a/patches/server/0890-Add-predicate-for-blocks-when-raytracing.patch +++ b/patches/server/0890-Add-predicate-for-blocks-when-raytracing.patch @@ -47,7 +47,7 @@ index 7e1a332168357b9af14dbe3299549c2c93903fa6..93738c7dea1ea3d19013a47380391274 Vec3 vec3d = raytrace1.getFrom().subtract(raytrace1.getTo()); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index b646f882de3ab04d54d07e9e944c261c310b58fd..69da1555f68e7603fd355307c3458688b92bc37f 100644 +index 188bd33f46b6baaa3fc21c9da6fa9a9d004e899e..041a6042a91f2a8933d7f9bcb44bb78894ffd405 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1116,9 +1116,15 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0893-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch b/patches/server/0893-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch index ba091fe8416a..ac9852081f26 100644 --- a/patches/server/0893-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch +++ b/patches/server/0893-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch @@ -45,7 +45,7 @@ index 152ecd38814089333b8d61538297ce720756d2c3..12127b14babf646711d3a118416453c4 if (world instanceof ServerLevel) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 69da1555f68e7603fd355307c3458688b92bc37f..6d1d387598a15c5b79bca4f496eb9375e9c9376d 100644 +index 041a6042a91f2a8933d7f9bcb44bb78894ffd405..b1ad6c47d3d42c93411753d4505ac9142b1697d3 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -742,7 +742,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0897-Fix-missing-event-call-for-entity-teleport-API.patch b/patches/server/0897-Fix-missing-event-call-for-entity-teleport-API.patch index 90e9f0e67108..c00c1e49bd4e 100644 --- a/patches/server/0897-Fix-missing-event-call-for-entity-teleport-API.patch +++ b/patches/server/0897-Fix-missing-event-call-for-entity-teleport-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix missing event call for entity teleport API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 9c8e2731ca37a16cb538da27190c085bbc9791e3..c1d3dd2bd217efd6914bceb1027fa12b06c22a55 100644 +index 11a08ff211a9a32a825519ddb1736e02cf7f685e..7536ab5c22d97a074c08a95fff6bc756d61e387d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -259,6 +259,17 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { diff --git a/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch b/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch index d3a68412bc69..75049231278b 100644 --- a/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch +++ b/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch @@ -19,7 +19,7 @@ where generation happened directly to a ServerLevel and the entity still has the flag set. diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 7acb24c2a34fdcbcb1c0e3cc03b01996689667d3..7a713fd31a2155b1c77c54817a67e354b1d4640d 100644 +index 1bacbb0d0bd5198d0f946a959b2335d6fba0ca88..a628da8a0ed7ae2c7b46df3881bd75dc5b4fd607 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1219,6 +1219,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0900-Add-Structure-check-API.patch b/patches/server/0900-Add-Structure-check-API.patch index 5bbc01bd9f2a..d138a01f44b9 100644 --- a/patches/server/0900-Add-Structure-check-API.patch +++ b/patches/server/0900-Add-Structure-check-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add Structure check API diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 6d1d387598a15c5b79bca4f496eb9375e9c9376d..50b3f5c185b8bb7965226c97a37faf714f5beb0a 100644 +index b1ad6c47d3d42c93411753d4505ac9142b1697d3..34e8afae13085f0a9ce0c916d911c88c395418e0 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -250,6 +250,15 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0925-Add-BlockBreakProgressUpdateEvent.patch b/patches/server/0925-Add-BlockBreakProgressUpdateEvent.patch index 81399fe283d2..2c5061f42f46 100644 --- a/patches/server/0925-Add-BlockBreakProgressUpdateEvent.patch +++ b/patches/server/0925-Add-BlockBreakProgressUpdateEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add BlockBreakProgressUpdateEvent diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 7a713fd31a2155b1c77c54817a67e354b1d4640d..942eb8c1ef575de53b1591b39014a39edb054a1f 100644 +index a628da8a0ed7ae2c7b46df3881bd75dc5b4fd607..99e6021bc0dc5775f4443bdb77debd535a2cf29f 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1315,6 +1315,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0928-More-Raid-API.patch b/patches/server/0928-More-Raid-API.patch index daaeb2bdea2e..2039ffa00df2 100644 --- a/patches/server/0928-More-Raid-API.patch +++ b/patches/server/0928-More-Raid-API.patch @@ -86,7 +86,7 @@ index b8ce1c1c2447f9cff1717bfcfd6eb911ade0d4b3..51f21af9d75769abdcba713b9aa33392 + // Paper end - more Raid API } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 50b3f5c185b8bb7965226c97a37faf714f5beb0a..51b10d9cceb4dfbea5e1d82d0404948c6cdc5944 100644 +index 34e8afae13085f0a9ce0c916d911c88c395418e0..406a3b4a6e213879a9b262d2ffa9ba404cf31cc1 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -2326,6 +2326,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0929-Add-onboarding-message-for-initial-server-start.patch b/patches/server/0929-Add-onboarding-message-for-initial-server-start.patch index df74ef81615f..d5378f34f1b0 100644 --- a/patches/server/0929-Add-onboarding-message-for-initial-server-start.patch +++ b/patches/server/0929-Add-onboarding-message-for-initial-server-start.patch @@ -17,7 +17,7 @@ index d9502ba028a96f9cc846f9ed428bd8066b857ca3..87e5f614ba988547a827486740db217e node = loader.load(); this.verifyGlobalConfigVersion(node); diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 73e8a524925ed6f2580d3bd01616646fabafda78..450a1cc8f1624dce2daf52210d017e0732b1bdf7 100644 +index 36b96e0ed5c0d25068ec4678eddd8a19a020d345..8a0cb603cd4dbfa1839e0f4e1606876cbb373277 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -27,6 +27,7 @@ public class GlobalConfiguration extends ConfigurationPart { diff --git a/patches/server/0930-Configurable-max-block-fluid-ticks.patch b/patches/server/0930-Configurable-max-block-fluid-ticks.patch index 4699e81a989d..15cd7fb486ff 100644 --- a/patches/server/0930-Configurable-max-block-fluid-ticks.patch +++ b/patches/server/0930-Configurable-max-block-fluid-ticks.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Configurable max block/fluid ticks diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 942eb8c1ef575de53b1591b39014a39edb054a1f..46a678ad3487d92e4c63731457bb4a421c2f07c2 100644 +index 99e6021bc0dc5775f4443bdb77debd535a2cf29f..eed2d1ec425bbd34563fae9e69a4518ec154fc23 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -492,9 +492,9 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0972-disable-forced-empty-world-ticks.patch b/patches/server/0972-disable-forced-empty-world-ticks.patch index cf5993dc22c1..343cd32ea2e0 100644 --- a/patches/server/0972-disable-forced-empty-world-ticks.patch +++ b/patches/server/0972-disable-forced-empty-world-ticks.patch @@ -5,7 +5,7 @@ Subject: [PATCH] disable forced empty world ticks diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 46a678ad3487d92e4c63731457bb4a421c2f07c2..86d6a01f94b5140932eb86b9523c6e3e43864a09 100644 +index eed2d1ec425bbd34563fae9e69a4518ec154fc23..982d44b539e189f4a857e72554cc81f8a4501ad6 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -519,7 +519,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0974-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/patches/server/0974-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch index 009447d68166..f4600638dab1 100644 --- a/patches/server/0974-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch +++ b/patches/server/0974-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch @@ -13,7 +13,7 @@ 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 86d6a01f94b5140932eb86b9523c6e3e43864a09..bbfe17233d23bbb787656ebedc92fdd2de56daed 100644 +index 982d44b539e189f4a857e72554cc81f8a4501ad6..fe610561e6fbb9bc547d27123793395fb0ad80aa 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2363,6 +2363,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/0978-Entity-Activation-Range-2.0.patch b/patches/server/0978-Entity-Activation-Range-2.0.patch index f340e669a8f8..65d38450a6a0 100644 --- a/patches/server/0978-Entity-Activation-Range-2.0.patch +++ b/patches/server/0978-Entity-Activation-Range-2.0.patch @@ -17,7 +17,7 @@ Adds villagers as separate config public net.minecraft.world.entity.Entity isInsidePortal diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index bbfe17233d23bbb787656ebedc92fdd2de56daed..3fb8370abd10bb702b969c43490c79352b0242df 100644 +index fe610561e6fbb9bc547d27123793395fb0ad80aa..ce5fd95cabadd7c92726c401ae35e05dde3e30f6 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; diff --git a/patches/server/0979-Anti-Xray.patch b/patches/server/0979-Anti-Xray.patch index 3a140d851c3a..dba0bf0bbcec 100644 --- a/patches/server/0979-Anti-Xray.patch +++ b/patches/server/0979-Anti-Xray.patch @@ -1104,7 +1104,7 @@ index 183b2191fa1c1b27adedf39593e1b5a223fb1279..8ead66c134688b11dca15f6509147e72 private ClientboundLevelChunkWithLightPacket(RegistryFriendlyByteBuf buf) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 3fb8370abd10bb702b969c43490c79352b0242df..c17824fa01c4682c2b97bb60bfa401a1a2ef9c12 100644 +index ce5fd95cabadd7c92726c401ae35e05dde3e30f6..878bd04b63f257cc625953e45b953beb06917107 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -344,7 +344,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -1604,7 +1604,7 @@ index 52710b4196dde7118eb1438a2f78b7c9557e00f8..8348ab336029848eab1cbe9b67b056ab @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 51b10d9cceb4dfbea5e1d82d0404948c6cdc5944..d3c845a997ad464cc25676443f567e6ada9ab360 100644 +index 406a3b4a6e213879a9b262d2ffa9ba404cf31cc1..367e662c2ca370f569fc65e3f74ec322140630db 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -472,11 +472,16 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0985-Optimize-Bit-Operations-by-inlining.patch b/patches/server/0985-Optimize-Bit-Operations-by-inlining.patch index 02b75062fb66..2c71fd115348 100644 --- a/patches/server/0985-Optimize-Bit-Operations-by-inlining.patch +++ b/patches/server/0985-Optimize-Bit-Operations-by-inlining.patch @@ -7,7 +7,7 @@ Inline bit operations and reduce instruction count to make these hot operations faster diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java -index 0d51fb4be8b49e3b57c3c55aff6bcf13d5c78ddd..a5dab9b1652ac76372d88316e2c165eed6317891 100644 +index a1d54d978d34d75475f92dfb806113586e7e449c..f58a94efafbc01d402cd03a108bb90f60930a316 100644 --- a/src/main/java/net/minecraft/core/BlockPos.java +++ b/src/main/java/net/minecraft/core/BlockPos.java @@ -50,15 +50,17 @@ public class BlockPos extends Vec3i { diff --git a/patches/server/0992-Properly-resend-entities.patch b/patches/server/0992-Properly-resend-entities.patch index 6acf6d708b63..dbadaf99bb7b 100644 --- a/patches/server/0992-Properly-resend-entities.patch +++ b/patches/server/0992-Properly-resend-entities.patch @@ -236,7 +236,7 @@ index 04760d8ba7c560bd9d11191c666715ae8c3e4bff..768f90682cd10045c16337fecc2702f5 // CraftBukkit end diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index c1d3dd2bd217efd6914bceb1027fa12b06c22a55..ca95a36b0149d4b8a67c3b42316c5d9d0415f5dd 100644 +index 7536ab5c22d97a074c08a95fff6bc756d61e387d..b0e49ad831f1ebc6b126bf82c5fddaebffb91312 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -1013,7 +1013,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { diff --git a/patches/server/1020-Add-FeatureFlag-API.patch b/patches/server/1020-Add-FeatureFlag-API.patch index dc614e582a10..cc3530746f0b 100644 --- a/patches/server/1020-Add-FeatureFlag-API.patch +++ b/patches/server/1020-Add-FeatureFlag-API.patch @@ -162,7 +162,7 @@ index f0bd7d01f56bb792886354ca4f199e46c2cf7503..adc6741e0e017660fbd39a62b69be1e6 + // Paper end - feature flag API } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index d3c845a997ad464cc25676443f567e6ada9ab360..125a427bd23df17773f50ecf8babc72f9502cba7 100644 +index 367e662c2ca370f569fc65e3f74ec322140630db..7d360620bd78f28f366815a019c57e5058d9f2a3 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -2379,10 +2379,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/1028-Improve-entity-effect-API.patch b/patches/server/1028-Improve-entity-effect-API.patch index cc5195f74b51..6599dd255e85 100644 --- a/patches/server/1028-Improve-entity-effect-API.patch +++ b/patches/server/1028-Improve-entity-effect-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Improve entity effect API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index ca95a36b0149d4b8a67c3b42316c5d9d0415f5dd..64c6f54cc4d0c22bc972b808cb92925cc7526db2 100644 +index b0e49ad831f1ebc6b126bf82c5fddaebffb91312..179886dcbda29c5cdb7dbd43e44951ae38d9df96 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -1300,4 +1300,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { diff --git a/patches/server/1032-Void-damage-configuration-API.patch b/patches/server/1032-Void-damage-configuration-API.patch index b71b4b8314d2..afa0337fd755 100644 --- a/patches/server/1032-Void-damage-configuration-API.patch +++ b/patches/server/1032-Void-damage-configuration-API.patch @@ -33,7 +33,7 @@ index 6db0613904c172fb6ae7e868f542f56aeaa63a5e..22b3d3d945cbddae25abfca7d900324c protected void updateSwingTime() { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 125a427bd23df17773f50ecf8babc72f9502cba7..b2eb8cf1de3b4b81587531bb4c0d4b512f5d5d5d 100644 +index 7d360620bd78f28f366815a019c57e5058d9f2a3..6dc3fc701d1e16a51d99f934ea3dc192363a6762 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -167,6 +167,41 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/1040-Rewrite-dataconverter-system.patch b/patches/server/1037-Rewrite-dataconverter-system.patch similarity index 100% rename from patches/server/1040-Rewrite-dataconverter-system.patch rename to patches/server/1037-Rewrite-dataconverter-system.patch diff --git a/patches/server/1037-fixup-ConcurrentUtil.patch b/patches/server/1037-fixup-ConcurrentUtil.patch deleted file mode 100644 index 60d57a16567c..000000000000 --- a/patches/server/1037-fixup-ConcurrentUtil.patch +++ /dev/null @@ -1,6177 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Mon, 21 Oct 2024 11:47:34 -0700 -Subject: [PATCH] fixup! ConcurrentUtil - - -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/collection/SRSWLinkedQueue.java b/src/main/java/ca/spottedleaf/concurrentutil/collection/SRSWLinkedQueue.java -deleted file mode 100644 -index 094eff418b4e3bffce020d650931b4d9e58fa9ed..0000000000000000000000000000000000000000 ---- a/src/main/java/ca/spottedleaf/concurrentutil/collection/SRSWLinkedQueue.java -+++ /dev/null -@@ -1,149 +0,0 @@ --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.ConcurrentModificationException; -- --/** -- * Single reader thread single writer thread queue. The reader side of the queue is ordered by acquire semantics, -- * and the writer side of the queue is ordered by release semantics. -- */ --// TODO test --public class SRSWLinkedQueue { -- -- // always non-null -- protected LinkedNode head; -- -- // always non-null -- protected LinkedNode tail; -- -- /* IMPL NOTE: Leave hashCode and equals to their defaults */ -- -- public SRSWLinkedQueue() { -- final LinkedNode dummy = new LinkedNode<>(null, null); -- this.head = this.tail = dummy; -- } -- -- /** -- * Must be the reader thread. -- * -- *

    -- * Returns, without removing, the first element of this queue. -- *

    -- * @return Returns, without removing, the first element of this queue. -- */ -- public E peekFirst() { -- LinkedNode head = this.head; -- E ret = head.getElementPlain(); -- if (ret == null) { -- head = head.getNextAcquire(); -- if (head == null) { -- // empty -- return null; -- } -- // update head reference for next poll() call -- this.head = head; -- // guaranteed to be non-null -- ret = head.getElementPlain(); -- if (ret == null) { -- throw new ConcurrentModificationException("Multiple reader threads"); -- } -- } -- -- return ret; -- } -- -- /** -- * Must be the reader thread. -- * -- *

    -- * Returns and removes the first element of this queue. -- *

    -- * @return Returns and removes the first element of this queue. -- */ -- public E poll() { -- LinkedNode head = this.head; -- E ret = head.getElementPlain(); -- if (ret == null) { -- head = head.getNextAcquire(); -- if (head == null) { -- // empty -- return null; -- } -- // guaranteed to be non-null -- ret = head.getElementPlain(); -- if (ret == null) { -- throw new ConcurrentModificationException("Multiple reader threads"); -- } -- } -- -- head.setElementPlain(null); -- LinkedNode next = head.getNextAcquire(); -- this.head = next == null ? head : next; -- -- return ret; -- } -- -- /** -- * Must be the writer thread. -- * -- *

    -- * Adds the element to the end of the queue. -- *

    -- * -- * @throws NullPointerException If the provided element is null -- */ -- public void addLast(final E element) { -- Validate.notNull(element, "Provided element cannot be null"); -- final LinkedNode append = new LinkedNode<>(element, null); -- -- this.tail.setNextRelease(append); -- this.tail = append; -- } -- -- protected static final class LinkedNode { -- -- protected volatile Object element; -- protected volatile LinkedNode 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 next) { -- ELEMENT_HANDLE.set(this, element); -- NEXT_HANDLE.set(this, next); -- } -- -- /* element */ -- -- @SuppressWarnings("unchecked") -- protected final E getElementPlain() { -- return (E)ELEMENT_HANDLE.get(this); -- } -- -- protected final void setElementPlain(final E update) { -- ELEMENT_HANDLE.set(this, (Object)update); -- } -- /* next */ -- -- @SuppressWarnings("unchecked") -- protected final LinkedNode getNextPlain() { -- return (LinkedNode)NEXT_HANDLE.get(this); -- } -- -- @SuppressWarnings("unchecked") -- protected final LinkedNode getNextAcquire() { -- return (LinkedNode)NEXT_HANDLE.getAcquire(this); -- } -- -- protected final void setNextPlain(final LinkedNode next) { -- NEXT_HANDLE.set(this, next); -- } -- -- protected final void setNextRelease(final LinkedNode next) { -- NEXT_HANDLE.setRelease(this, next); -- } -- } --} -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/completable/CallbackCompletable.java b/src/main/java/ca/spottedleaf/concurrentutil/completable/CallbackCompletable.java -new file mode 100644 -index 0000000000000000000000000000000000000000..6bad6f8ecc0944d2f406924c7de7e227ff1e70fa ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/completable/CallbackCompletable.java -@@ -0,0 +1,110 @@ -+package ca.spottedleaf.concurrentutil.completable; -+ -+import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; -+import ca.spottedleaf.concurrentutil.executor.Cancellable; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import org.slf4j.Logger; -+import org.slf4j.LoggerFactory; -+import java.util.function.BiConsumer; -+ -+public final class CallbackCompletable { -+ -+ private static final Logger LOGGER = LoggerFactory.getLogger(CallbackCompletable.class); -+ -+ private final MultiThreadedQueue> 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; -+ } -+ -+ /** -+ * Adds a waiter that should only be completed asynchronously by the complete() calls. If complete() -+ * has already been called, returns {@code null} and does not invoke the specified consumer. -+ * @param consumer Consumer to be executed on completion -+ * @throws NullPointerException If consumer is null -+ * @return A cancellable which will control the execution of the specified consumer -+ */ -+ public Cancellable addAsynchronousWaiter(final BiConsumer 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 waiter; -+ while ((waiter = this.waiters.pollOrBlockAdds()) != null) { -+ this.completeWaiter(waiter, result, throwable); -+ } -+ } -+ -+ private void completeWaiter(final BiConsumer consumer, final T result, final Throwable throwable) { -+ try { -+ consumer.accept(result, throwable); -+ } catch (final Throwable throwable2) { -+ LOGGER.error("Failed to complete callback " + ConcurrentUtil.genericToString(consumer), throwable2); -+ } -+ } -+ -+ /** -+ * Adds a waiter that will be completed asynchronously by the complete() calls. If complete() -+ * has already been called, then invokes the consumer synchronously with the completed result. -+ * @param consumer Consumer to be executed on completion -+ * @throws NullPointerException If consumer is null -+ * @return A cancellable which will control the execution of the specified consumer -+ */ -+ public Cancellable addWaiter(final BiConsumer 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 waiter; -+ -+ private CancellableImpl(final BiConsumer waiter) { -+ this.waiter = waiter; -+ } -+ -+ @Override -+ public boolean cancel() { -+ return CallbackCompletable.this.waiters.remove(this.waiter); -+ } -+ } -+} -\ No newline at end of file -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/completable/Completable.java b/src/main/java/ca/spottedleaf/concurrentutil/completable/Completable.java -index 46d1bd01542ebeeffc0006a5c585a50dbbbff907..365616439fa079017d648ed7f6ddf6950a691adf 100644 ---- a/src/main/java/ca/spottedleaf/concurrentutil/completable/Completable.java -+++ b/src/main/java/ca/spottedleaf/concurrentutil/completable/Completable.java -@@ -1,112 +1,737 @@ - package ca.spottedleaf.concurrentutil.completable; - --import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; --import ca.spottedleaf.concurrentutil.executor.Cancellable; - import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.Validate; - import org.slf4j.Logger; - import org.slf4j.LoggerFactory; -+import java.lang.invoke.VarHandle; -+import java.util.concurrent.CompletableFuture; -+import java.util.concurrent.CompletionException; -+import java.util.concurrent.CompletionStage; -+import java.util.concurrent.Executor; -+import java.util.concurrent.ForkJoinPool; -+import java.util.concurrent.locks.LockSupport; - import java.util.function.BiConsumer; -+import java.util.function.BiFunction; -+import java.util.function.Consumer; -+import java.util.function.Function; -+import java.util.function.Supplier; - - public final class Completable { - - private static final Logger LOGGER = LoggerFactory.getLogger(Completable.class); -+ private static final Function DEFAULT_EXCEPTION_HANDLER = (final Throwable thr) -> { -+ LOGGER.error("Unhandled exception during Completable operation", thr); -+ return thr; -+ }; - -- private final MultiThreadedQueue> waiters = new MultiThreadedQueue<>(); -- private T result; -- private Throwable throwable; -- private volatile boolean completed; -+ public static Executor getDefaultExecutor() { -+ return ForkJoinPool.commonPool(); -+ } -+ -+ private static final Transform COMPLETED_STACK = new Transform<>(null, null, null, null) { -+ @Override -+ public void run() {} -+ }; -+ private volatile Transform completeStack; -+ private static final VarHandle COMPLETE_STACK_HANDLE = ConcurrentUtil.getVarHandle(Completable.class, "completeStack", Transform.class); -+ -+ private static final Object NULL_MASK = new Object(); -+ private volatile Object result; -+ private static final VarHandle RESULT_HANDLE = ConcurrentUtil.getVarHandle(Completable.class, "result", Object.class); - -- public boolean isCompleted() { -- return this.completed; -+ private Object getResultPlain() { -+ return (Object)RESULT_HANDLE.get(this); - } - -- /** -- * Note: Can only use after calling {@link #addAsynchronousWaiter(BiConsumer)}, as this function performs zero -- * synchronisation -- */ -- public T getResult() { -- return this.result; -+ private Object getResultVolatile() { -+ return (Object)RESULT_HANDLE.getVolatile(this); - } - -- /** -- * Note: Can only use after calling {@link #addAsynchronousWaiter(BiConsumer)}, as this function performs zero -- * synchronisation -- */ -- public Throwable getThrowable() { -- return this.throwable; -+ private void pushStackOrRun(final Transform push) { -+ int failures = 0; -+ for (Transform curr = (Transform)COMPLETE_STACK_HANDLE.getVolatile(this);;) { -+ if (curr == COMPLETED_STACK) { -+ push.execute(); -+ return; -+ } -+ -+ push.next = curr; -+ -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ -+ if (curr == (curr = (Transform)COMPLETE_STACK_HANDLE.compareAndExchange(this, curr, push))) { -+ return; -+ } -+ push.next = null; -+ ++failures; -+ } - } - -- /** -- * Adds a waiter that should only be completed asynchronously by the complete() calls. If complete() -- * has already been called, returns {@code null} and does not invoke the specified consumer. -- * @param consumer Consumer to be executed on completion -- * @throws NullPointerException If consumer is null -- * @return A cancellable which will control the execution of the specified consumer -- */ -- public Cancellable addAsynchronousWaiter(final BiConsumer consumer) { -- if (this.waiters.add(consumer)) { -- return new CancellableImpl(consumer); -+ private void propagateStack() { -+ Transform topStack = (Transform)COMPLETE_STACK_HANDLE.getAndSet(this, COMPLETED_STACK); -+ while (topStack != null) { -+ topStack.execute(); -+ topStack = topStack.next; - } -- return null; - } - -- private void completeAllWaiters(final T result, final Throwable throwable) { -- this.completed = true; -- BiConsumer waiter; -- while ((waiter = this.waiters.pollOrBlockAdds()) != null) { -- this.completeWaiter(waiter, result, throwable); -+ private static Object maskNull(final Object res) { -+ return res == null ? NULL_MASK : res; -+ } -+ -+ private static Object unmaskNull(final Object res) { -+ return res == NULL_MASK ? null : res; -+ } -+ -+ private static Executor checkExecutor(final Executor executor) { -+ return Validate.notNull(executor, "Executor may not be null"); -+ } -+ -+ public Completable() {} -+ -+ private Completable(final Object complete) { -+ COMPLETE_STACK_HANDLE.set(this, COMPLETED_STACK); -+ RESULT_HANDLE.setRelease(this, complete); -+ } -+ -+ public static Completable completed(final T value) { -+ return new Completable<>(maskNull(value)); -+ } -+ -+ public static Completable failed(final Throwable ex) { -+ Validate.notNull(ex, "Exception may not be null"); -+ -+ return new Completable<>(new ExceptionResult(ex)); -+ } -+ -+ public static Completable supplied(final Supplier supplier) { -+ return supplied(supplier, DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public static Completable supplied(final Supplier supplier, final Function exceptionHandler) { -+ try { -+ return completed(supplier.get()); -+ } catch (final Throwable throwable) { -+ Throwable complete; -+ try { -+ complete = exceptionHandler.apply(throwable); -+ } catch (final Throwable thr2) { -+ throwable.addSuppressed(thr2); -+ complete = throwable; -+ } -+ return failed(complete); - } - } - -- private void completeWaiter(final BiConsumer consumer, final T result, final Throwable throwable) { -+ public static Completable suppliedAsync(final Supplier supplier, final Executor executor) { -+ return suppliedAsync(supplier, executor, DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public static Completable suppliedAsync(final Supplier supplier, final Executor executor, final Function exceptionHandler) { -+ final Completable ret = new Completable<>(); -+ -+ class AsyncSuppliedCompletable implements Runnable, CompletableFuture.AsynchronousCompletionTask { -+ @Override -+ public void run() { -+ try { -+ ret.complete(supplier.get()); -+ } catch (final Throwable throwable) { -+ Throwable complete; -+ try { -+ complete = exceptionHandler.apply(throwable); -+ } catch (final Throwable thr2) { -+ throwable.addSuppressed(thr2); -+ complete = throwable; -+ } -+ ret.completeExceptionally(complete); -+ } -+ } -+ } -+ - 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); -+ executor.execute(new AsyncSuppliedCompletable()); -+ } catch (final Throwable throwable) { -+ Throwable complete; -+ try { -+ complete = exceptionHandler.apply(throwable); -+ } catch (final Throwable thr2) { -+ throwable.addSuppressed(thr2); -+ complete = throwable; -+ } -+ ret.completeExceptionally(complete); -+ } -+ -+ return ret; -+ } -+ -+ private boolean completeRaw(final Object value) { -+ if ((Object)RESULT_HANDLE.getVolatile(this) != null || !(boolean)RESULT_HANDLE.compareAndSet(this, (Object)null, value)) { -+ return false; -+ } -+ -+ this.propagateStack(); -+ return true; -+ } -+ -+ public boolean complete(final T result) { -+ return this.completeRaw(maskNull(result)); -+ } -+ -+ public boolean completeExceptionally(final Throwable exception) { -+ Validate.notNull(exception, "Exception may not be null"); -+ -+ return this.completeRaw(new ExceptionResult(exception)); -+ } -+ -+ public boolean isDone() { -+ return this.getResultVolatile() != null; -+ } -+ -+ public boolean isNormallyComplete() { -+ return this.getResultVolatile() != null && !(this.getResultVolatile() instanceof ExceptionResult); -+ } -+ -+ public boolean isExceptionallyComplete() { -+ return this.getResultVolatile() instanceof ExceptionResult; -+ } -+ -+ public Throwable getException() { -+ final Object res = this.getResultVolatile(); -+ if (res == null) { -+ return null; -+ } -+ -+ if (!(res instanceof ExceptionResult exRes)) { -+ throw new IllegalStateException("Not completed exceptionally"); -+ } -+ -+ return exRes.ex; -+ } -+ -+ public T getNow(final T dfl) throws CompletionException { -+ final Object res = this.getResultVolatile(); -+ if (res == null) { -+ return dfl; -+ } -+ -+ if (res instanceof ExceptionResult exRes) { -+ throw new CompletionException(exRes.ex); -+ } -+ -+ return (T)unmaskNull(res); -+ } -+ -+ public T join() throws CompletionException { -+ if (this.isDone()) { -+ return this.getNow(null); -+ } -+ -+ final UnparkTransform unparkTransform = new UnparkTransform<>(this, Thread.currentThread()); -+ -+ this.pushStackOrRun(unparkTransform); -+ -+ boolean interuptted = false; -+ while (!unparkTransform.isReleasable()) { -+ try { -+ ForkJoinPool.managedBlock(unparkTransform); -+ } catch (final InterruptedException ex) { -+ interuptted = true; -+ } -+ } -+ -+ if (interuptted) { -+ Thread.currentThread().interrupt(); -+ } -+ -+ return this.getNow(null); -+ } -+ -+ public CompletableFuture toFuture() { -+ final Object rawResult = this.getResultVolatile(); -+ if (rawResult != null) { -+ if (rawResult instanceof ExceptionResult exRes) { -+ return CompletableFuture.failedFuture(exRes.ex); -+ } else { -+ return CompletableFuture.completedFuture((T)unmaskNull(rawResult)); -+ } -+ } -+ -+ final CompletableFuture ret = new CompletableFuture<>(); -+ -+ class ToFuture implements BiConsumer { -+ -+ @Override -+ public void accept(final T res, final Throwable ex) { -+ if (ex != null) { -+ ret.completeExceptionally(ex); -+ } else { -+ ret.complete(res); -+ } -+ } -+ } -+ -+ this.whenComplete(new ToFuture()); -+ -+ return ret; -+ } -+ -+ public static Completable fromFuture(final CompletionStage stage) { -+ final Completable ret = new Completable<>(); -+ -+ class FromFuture implements BiConsumer { -+ @Override -+ public void accept(final T res, final Throwable ex) { -+ if (ex != null) { -+ ret.completeExceptionally(ex); -+ } else { -+ ret.complete(res); -+ } -+ } -+ } -+ -+ stage.whenComplete(new FromFuture()); -+ -+ return ret; -+ } -+ -+ -+ public Completable thenApply(final Function function) { -+ return this.thenApply(function, DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable thenApply(final Function function, final Function exceptionHandler) { -+ Validate.notNull(function, "Function may not be null"); -+ Validate.notNull(exceptionHandler, "Exception handler may not be null"); -+ -+ final Completable ret = new Completable<>(); -+ this.pushStackOrRun(new ApplyTransform<>(null, this, ret, exceptionHandler, function)); -+ return ret; -+ } -+ -+ public Completable thenApplyAsync(final Function function) { -+ return this.thenApplyAsync(function, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable thenApplyAsync(final Function function, final Executor executor) { -+ return this.thenApplyAsync(function, executor, DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable thenApplyAsync(final Function function, final Executor executor, final Function exceptionHandler) { -+ Validate.notNull(function, "Function may not be null"); -+ Validate.notNull(exceptionHandler, "Exception handler may not be null"); -+ -+ final Completable ret = new Completable<>(); -+ this.pushStackOrRun(new ApplyTransform<>(checkExecutor(executor), this, ret, exceptionHandler, function)); -+ return ret; -+ } -+ -+ -+ public Completable thenAccept(final Consumer consumer) { -+ return this.thenAccept(consumer, DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable thenAccept(final Consumer consumer, final Function exceptionHandler) { -+ Validate.notNull(consumer, "Consumer may not be null"); -+ Validate.notNull(exceptionHandler, "Exception handler may not be null"); -+ -+ final Completable ret = new Completable<>(); -+ this.pushStackOrRun(new AcceptTransform<>(null, this, ret, exceptionHandler, consumer)); -+ return ret; -+ } -+ -+ public Completable thenAcceptAsync(final Consumer consumer) { -+ return this.thenAcceptAsync(consumer, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable thenAcceptAsync(final Consumer consumer, final Executor executor) { -+ return this.thenAcceptAsync(consumer, executor, DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable thenAcceptAsync(final Consumer consumer, final Executor executor, final Function exceptionHandler) { -+ Validate.notNull(consumer, "Consumer may not be null"); -+ Validate.notNull(exceptionHandler, "Exception handler may not be null"); -+ -+ final Completable ret = new Completable<>(); -+ this.pushStackOrRun(new AcceptTransform<>(checkExecutor(executor), this, ret, exceptionHandler, consumer)); -+ return ret; -+ } -+ -+ -+ public Completable thenRun(final Runnable run) { -+ return this.thenRun(run, DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable thenRun(final Runnable run, final Function exceptionHandler) { -+ Validate.notNull(run, "Run may not be null"); -+ Validate.notNull(exceptionHandler, "Exception handler may not be null"); -+ -+ final Completable ret = new Completable<>(); -+ this.pushStackOrRun(new RunTransform<>(null, this, ret, exceptionHandler, run)); -+ return ret; -+ } -+ -+ public Completable thenRunAsync(final Runnable run) { -+ return this.thenRunAsync(run, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable thenRunAsync(final Runnable run, final Executor executor) { -+ return this.thenRunAsync(run, executor, DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable thenRunAsync(final Runnable run, final Executor executor, final Function exceptionHandler) { -+ Validate.notNull(run, "Run may not be null"); -+ Validate.notNull(exceptionHandler, "Exception handler may not be null"); -+ -+ final Completable ret = new Completable<>(); -+ this.pushStackOrRun(new RunTransform<>(checkExecutor(executor), this, ret, exceptionHandler, run)); -+ return ret; -+ } -+ -+ -+ public Completable handle(final BiFunction function) { -+ return this.handle(function, DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable handle(final BiFunction function, -+ final Function exceptionHandler) { -+ Validate.notNull(function, "Function may not be null"); -+ Validate.notNull(exceptionHandler, "Exception handler may not be null"); -+ -+ final Completable ret = new Completable<>(); -+ this.pushStackOrRun(new HandleTransform<>(null, this, ret, exceptionHandler, function)); -+ return ret; -+ } -+ -+ public Completable handleAsync(final BiFunction function) { -+ return this.handleAsync(function, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable handleAsync(final BiFunction function, -+ final Executor executor) { -+ return this.handleAsync(function, executor, DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable handleAsync(final BiFunction function, -+ final Executor executor, -+ final Function exceptionHandler) { -+ Validate.notNull(function, "Function may not be null"); -+ Validate.notNull(exceptionHandler, "Exception handler may not be null"); -+ -+ final Completable ret = new Completable<>(); -+ this.pushStackOrRun(new HandleTransform<>(checkExecutor(executor), this, ret, exceptionHandler, function)); -+ return ret; -+ } -+ -+ -+ public Completable whenComplete(final BiConsumer consumer) { -+ return this.whenComplete(consumer, DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable whenComplete(final BiConsumer consumer, final Function exceptionHandler) { -+ Validate.notNull(consumer, "Consumer may not be null"); -+ Validate.notNull(exceptionHandler, "Exception handler may not be null"); -+ -+ final Completable ret = new Completable<>(); -+ this.pushStackOrRun(new WhenTransform<>(null, this, ret, exceptionHandler, consumer)); -+ return ret; -+ } -+ -+ public Completable whenCompleteAsync(final BiConsumer consumer) { -+ return this.whenCompleteAsync(consumer, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable whenCompleteAsync(final BiConsumer consumer, final Executor executor) { -+ return this.whenCompleteAsync(consumer, executor, DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable whenCompleteAsync(final BiConsumer consumer, final Executor executor, -+ final Function exceptionHandler) { -+ Validate.notNull(consumer, "Consumer may not be null"); -+ Validate.notNull(exceptionHandler, "Exception handler may not be null"); -+ -+ final Completable ret = new Completable<>(); -+ this.pushStackOrRun(new WhenTransform<>(checkExecutor(executor), this, ret, exceptionHandler, consumer)); -+ return ret; -+ } -+ -+ -+ public Completable exceptionally(final Function function) { -+ return this.exceptionally(function, DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable exceptionally(final Function function, final Function exceptionHandler) { -+ Validate.notNull(function, "Function may not be null"); -+ Validate.notNull(exceptionHandler, "Exception handler may not be null"); -+ -+ final Completable ret = new Completable<>(); -+ this.pushStackOrRun(new ExceptionallyTransform<>(null, this, ret, exceptionHandler, function)); -+ return ret; -+ } -+ -+ public Completable exceptionallyAsync(final Function function) { -+ return this.exceptionallyAsync(function, getDefaultExecutor(), DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable exceptionallyAsync(final Function function, final Executor executor) { -+ return this.exceptionallyAsync(function, executor, DEFAULT_EXCEPTION_HANDLER); -+ } -+ -+ public Completable exceptionallyAsync(final Function function, final Executor executor, -+ final Function exceptionHandler) { -+ Validate.notNull(function, "Function may not be null"); -+ Validate.notNull(exceptionHandler, "Exception handler may not be null"); -+ -+ final Completable ret = new Completable<>(); -+ this.pushStackOrRun(new ExceptionallyTransform<>(checkExecutor(executor), this, ret, exceptionHandler, function)); -+ return ret; -+ } -+ -+ private static final class ExceptionResult { -+ public final Throwable ex; -+ -+ public ExceptionResult(final Throwable ex) { -+ this.ex = ex; - } - } - -- /** -- * Adds a waiter that will be completed asynchronously by the complete() calls. If complete() -- * has already been called, then invokes the consumer synchronously with the completed result. -- * @param consumer Consumer to be executed on completion -- * @throws NullPointerException If consumer is null -- * @return A cancellable which will control the execution of the specified consumer -- */ -- public Cancellable addWaiter(final BiConsumer consumer) { -- if (this.waiters.add(consumer)) { -- return new CancellableImpl(consumer); -+ private static abstract class Transform implements Runnable, CompletableFuture.AsynchronousCompletionTask { -+ -+ private Transform next; -+ -+ private final Executor executor; -+ protected final Completable from; -+ protected final Completable to; -+ protected final Function exceptionHandler; -+ -+ protected Transform(final Executor executor, final Completable from, final Completable to, -+ final Function exceptionHandler) { -+ this.executor = executor; -+ this.from = from; -+ this.to = to; -+ this.exceptionHandler = exceptionHandler; -+ } -+ -+ // force interface call to become virtual call -+ @Override -+ public abstract void run(); -+ -+ protected void failed(final Throwable throwable) { -+ Throwable complete; -+ try { -+ complete = this.exceptionHandler.apply(throwable); -+ } catch (final Throwable thr2) { -+ throwable.addSuppressed(thr2); -+ complete = throwable; -+ } -+ this.to.completeExceptionally(complete); -+ } -+ -+ public void execute() { -+ if (this.executor == null) { -+ this.run(); -+ return; -+ } -+ -+ try { -+ this.executor.execute(this); -+ } catch (final Throwable throwable) { -+ this.failed(throwable); -+ } -+ } -+ } -+ -+ private static final class ApplyTransform extends Transform { -+ -+ private final Function function; -+ -+ public ApplyTransform(final Executor executor, final Completable from, final Completable to, -+ final Function exceptionHandler, -+ final Function function) { -+ super(executor, from, to, exceptionHandler); -+ this.function = function; -+ } -+ -+ @Override -+ public void run() { -+ final Object result = this.from.getResultPlain(); -+ try { -+ if (result instanceof ExceptionResult exRes) { -+ this.to.completeExceptionally(exRes.ex); -+ } else { -+ this.to.complete(this.function.apply((T)unmaskNull(result))); -+ } -+ } catch (final Throwable throwable) { -+ this.failed(throwable); -+ } - } -- this.completeWaiter(consumer, this.result, this.throwable); -- return new CancellableImpl(consumer); - } - -- public void complete(final T result) { -- this.result = result; -- this.completeAllWaiters(result, null); -+ private static final class AcceptTransform extends Transform { -+ private final Consumer consumer; -+ -+ public AcceptTransform(final Executor executor, final Completable from, final Completable to, -+ final Function exceptionHandler, -+ final Consumer consumer) { -+ super(executor, from, to, exceptionHandler); -+ this.consumer = consumer; -+ } -+ -+ @Override -+ public void run() { -+ final Object result = this.from.getResultPlain(); -+ try { -+ if (result instanceof ExceptionResult exRes) { -+ this.to.completeExceptionally(exRes.ex); -+ } else { -+ this.consumer.accept((T)unmaskNull(result)); -+ this.to.complete(null); -+ } -+ } catch (final Throwable throwable) { -+ this.failed(throwable); -+ } -+ } - } - -- public void completeWithThrowable(final Throwable throwable) { -- if (throwable == null) { -- throw new NullPointerException("Throwable cannot be null"); -+ private static final class RunTransform extends Transform { -+ private final Runnable run; -+ -+ public RunTransform(final Executor executor, final Completable from, final Completable to, -+ final Function exceptionHandler, -+ final Runnable run) { -+ super(executor, from, to, exceptionHandler); -+ this.run = run; -+ } -+ -+ @Override -+ public void run() { -+ final Object result = this.from.getResultPlain(); -+ try { -+ if (result instanceof ExceptionResult exRes) { -+ this.to.completeExceptionally(exRes.ex); -+ } else { -+ this.run.run(); -+ this.to.complete(null); -+ } -+ } catch (final Throwable throwable) { -+ this.failed(throwable); -+ } - } -- this.throwable = throwable; -- this.completeAllWaiters(null, throwable); - } - -- private final class CancellableImpl implements Cancellable { -+ private static final class HandleTransform extends Transform { -+ -+ private final BiFunction function; -+ -+ public HandleTransform(final Executor executor, final Completable from, final Completable to, -+ final Function exceptionHandler, -+ final BiFunction function) { -+ super(executor, from, to, exceptionHandler); -+ this.function = function; -+ } - -- private final BiConsumer waiter; -+ @Override -+ public void run() { -+ final Object result = this.from.getResultPlain(); -+ try { -+ if (result instanceof ExceptionResult exRes) { -+ this.to.complete(this.function.apply(null, exRes.ex)); -+ } else { -+ this.to.complete(this.function.apply((T)unmaskNull(result), null)); -+ } -+ } catch (final Throwable throwable) { -+ this.failed(throwable); -+ } -+ } -+ } -+ -+ private static final class WhenTransform extends Transform { -+ -+ private final BiConsumer consumer; -+ -+ public WhenTransform(final Executor executor, final Completable from, final Completable to, -+ final Function exceptionHandler, -+ final BiConsumer consumer) { -+ super(executor, from, to, exceptionHandler); -+ this.consumer = consumer; -+ } -+ -+ @Override -+ public void run() { -+ final Object result = this.from.getResultPlain(); -+ try { -+ if (result instanceof ExceptionResult exRes) { -+ this.consumer.accept(null, exRes.ex); -+ this.to.completeExceptionally(exRes.ex); -+ } else { -+ final T unmasked = (T)unmaskNull(result); -+ this.consumer.accept(unmasked, null); -+ this.to.complete(unmasked); -+ } -+ } catch (final Throwable throwable) { -+ this.failed(throwable); -+ } -+ } -+ } -+ -+ private static final class ExceptionallyTransform extends Transform { -+ private final Function function; -+ -+ public ExceptionallyTransform(final Executor executor, final Completable from, final Completable to, -+ final Function exceptionHandler, -+ final Function function) { -+ super(executor, from, to, exceptionHandler); -+ this.function = function; -+ } -+ -+ @Override -+ public void run() { -+ final Object result = this.from.getResultPlain(); -+ try { -+ if (result instanceof ExceptionResult exRes) { -+ this.to.complete(this.function.apply(exRes.ex)); -+ } else { -+ this.to.complete((T)unmaskNull(result)); -+ } -+ } catch (final Throwable throwable) { -+ this.failed(throwable); -+ } -+ } -+ } -+ -+ private static final class UnparkTransform extends Transform implements ForkJoinPool.ManagedBlocker { -+ -+ private volatile Thread thread; -+ -+ public UnparkTransform(final Completable from, final Thread target) { -+ super(null, from, null, null); -+ this.thread = target; -+ } -+ -+ @Override -+ public void run() { -+ final Thread t = this.thread; -+ this.thread = null; -+ LockSupport.unpark(t); -+ } -+ -+ @Override -+ public boolean block() throws InterruptedException { -+ while (!this.isReleasable()) { -+ if (Thread.interrupted()) { -+ throw new InterruptedException(); -+ } -+ LockSupport.park(this); -+ } - -- private CancellableImpl(final BiConsumer waiter) { -- this.waiter = waiter; -+ return true; - } - - @Override -- public boolean cancel() { -- return Completable.this.waiters.remove(this.waiter); -+ public boolean isReleasable() { -+ return this.thread == null; - } - } - } -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/BaseExecutor.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/BaseExecutor.java -deleted file mode 100644 -index 18d646676fd022afd64afaac30ec1bd283a73b0e..0000000000000000000000000000000000000000 ---- a/src/main/java/ca/spottedleaf/concurrentutil/executor/BaseExecutor.java -+++ /dev/null -@@ -1,208 +0,0 @@ --package ca.spottedleaf.concurrentutil.executor; -- --import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; --import java.util.function.BooleanSupplier; -- --/** -- * Base implementation for an abstract queue of tasks which are executed either synchronously or asynchronously. -- * -- *

    -- * The implementation supports tracking task executions using {@link #getTotalTasksScheduled()} and -- * {@link #getTotalTasksExecuted()}, and optionally shutting down the executor using {@link #shutdown()} -- *

    -- * -- *

    -- * The base implementation does not provide a method to queue a task for execution, rather that is specified in -- * the specific implementation. However, it is required that a specific implementation provides a method to -- * queue a task or create a task. A queued task is one which will eventually be executed, -- * and a created task must be queued to execute via {@link BaseTask#queue()} or be executed manually via -- * {@link BaseTask#execute()}. This choice of delaying the queueing of a task may be useful to provide a task handle -- * which may be cancelled or adjusted before the actual real task logic is ready to be executed. -- *

    -- */ --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()} -- *

    -- * 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. -- *

    -- *

    -- * 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. -- *

    -- *

    -- * Note: Interruptions to the the current thread have no effect. Interrupt status is also not affected by this call. -- *

    -- * -- * @throws IllegalStateException If the current thread is not allowed to wait -- */ -- public default void waitUntilAllExecuted() throws IllegalStateException { -- long failures = 1L; // start at 0.25ms -- -- while (!this.haveAllTasksExecuted()) { -- Thread.yield(); -- failures = ConcurrentUtil.linearLongBackoff(failures, 250_000L, 5_000_000L); // 500us, 5ms -- } -- } -- -- /** -- * Executes the next available task. -- * -- * @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}. -- *

    -- * WARNING: This function is not suitable for waiting until a deadline! -- * Use {@link #executeUntil(long)} or {@link #executeConditionally(BooleanSupplier, long)} instead. -- *

    -- */ -- 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 >= 0}. -- */ -- 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 < 0L) && !condition.getAsBoolean() && (System.nanoTime() - deadline < 0L)) { -- 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 >= 0}. -- */ -- public default void executeUntil(final long deadline) { -- long failures = 0; -- while (System.nanoTime() - deadline < 0L) { -- 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. -- *

    -- * This operation is atomic with respect to other shutdown calls -- *

    -- *

    -- * After this call has completed, regardless of return value, this queue will be shutdown. -- *

    -- * -- * @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 -- * @see #isShutdown() -- */ -- 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 the tasks scheduled have been executed. -- * @return Returns whether this queue has shut down. -- * @see #waitUntilAllExecuted() -- */ -- public default boolean isShutdown() { -- return false; -- } -- -- /** -- * Task object returned for any {@link BaseExecutor} scheduled task. -- * @see BaseExecutor -- */ -- 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. -- *

    -- * Exceptions thrown from the runnable will be rethrown. -- *

    -- * -- * @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/PrioritisedExecutor.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/PrioritisedExecutor.java -new file mode 100644 -index 0000000000000000000000000000000000000000..17cbaee1e89bd3f6d905e640d20d0119ab0570a0 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/PrioritisedExecutor.java -@@ -0,0 +1,271 @@ -+package ca.spottedleaf.concurrentutil.executor; -+ -+import ca.spottedleaf.concurrentutil.util.Priority; -+ -+public interface PrioritisedExecutor { -+ -+ /** -+ * Returns the number of tasks that have been scheduled are pending to be scheduled. -+ */ -+ public long getTotalTasksScheduled(); -+ -+ /** -+ * Returns the number of tasks that have been executed. -+ */ -+ public long getTotalTasksExecuted(); -+ -+ /** -+ * Generates the next suborder id. -+ * @return The next suborder id. -+ */ -+ public long generateNextSubOrder(); -+ -+ /** -+ * Executes the next available task. -+ *

    -+ * If there is a task with priority {@link Priority#BLOCKING} available, then that such task is executed. -+ *

    -+ *

    -+ * If there is a task with priority {@link Priority#IDLE} available then that task is only executed -+ * when there are no other tasks available with a higher priority. -+ *

    -+ *

    -+ * If there are no tasks that have priority {@link Priority#BLOCKING} or {@link Priority#IDLE}, then -+ * this function will be biased to execute tasks that have higher priorities. -+ *

    -+ * -+ * @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; -+ -+ /** -+ * Prevent further additions to this executor. Attempts to add after this call has completed (potentially during) will -+ * result in {@link IllegalStateException} being thrown. -+ *

    -+ * This operation is atomic with respect to other shutdown calls -+ *

    -+ *

    -+ * After this call has completed, regardless of return value, this executor will be shutdown. -+ *

    -+ * -+ * @return {@code true} if the executor was shutdown, {@code false} if it has shut down already -+ * @see #isShutdown() -+ */ -+ public boolean shutdown(); -+ -+ /** -+ * Returns whether this executor has shut down. Effectively, returns whether new tasks will be rejected. -+ * This method does not indicate whether all the tasks scheduled have been executed. -+ * @return Returns whether this executor has shut down. -+ */ -+ public boolean isShutdown(); -+ -+ /** -+ * Queues or executes a task at {@link Priority#NORMAL} priority. -+ * @param task The task to run. -+ * -+ * @throws IllegalStateException If this executor 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 PrioritisedTask queueTask(final Runnable task); -+ -+ /** -+ * Queues or executes a task. -+ * -+ * @param task The task to run. -+ * @param priority The priority for the task. -+ * -+ * @throws IllegalStateException If this executor 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 queueTask(final Runnable task, final Priority priority); -+ -+ /** -+ * Queues or executes a task. -+ * -+ * @param task The task to run. -+ * @param priority The priority for the task. -+ * @param subOrder The task's suborder. -+ * -+ * @throws IllegalStateException If this executor 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 queueTask(final Runnable task, final Priority priority, final long subOrder); -+ -+ /** -+ * Creates, but does not queue or execute, a task at {@link Priority#NORMAL} priority. -+ * @param task The task to run. -+ * -+ * @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 PrioritisedTask createTask(final Runnable task); -+ -+ /** -+ * Creates, but does not queue or execute, a task at {@link Priority#NORMAL} priority. -+ * -+ * @param task The task to run. -+ * @param priority The priority for the task. -+ * -+ * @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 createTask(final Runnable task, final Priority priority); -+ -+ /** -+ * Creates, but does not queue or execute, a task at {@link Priority#NORMAL} priority. -+ * -+ * @param task The task to run. -+ * @param priority The priority for the task. -+ * @param subOrder The task's suborder. -+ * -+ * @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 createTask(final Runnable task, final Priority priority, final long subOrder); -+ -+ public static interface PrioritisedTask extends Cancellable { -+ -+ /** -+ * Returns the executor associated with this task. -+ * @return The executor associated with this task. -+ */ -+ public PrioritisedExecutor getExecutor(); -+ -+ /** -+ * Causes a lazily queued task to become queued or executed -+ * -+ * @throws IllegalStateException If the backing executor has shutdown -+ * @return {@code true} If the task was queued, {@code false} if the task was already queued/cancelled/executed -+ */ -+ public boolean queue(); -+ -+ /** -+ * Returns whether this task has been queued and is not completing. -+ * @return {@code true} If the task has been queued, {@code false} if the task has not been queued or is marked -+ * as completing. -+ */ -+ public boolean isQueued(); -+ -+ /** -+ * 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. -+ *

    -+ * Exceptions thrown from the runnable will be rethrown. -+ *

    -+ * -+ * @return {@code true} if this task was executed, {@code false} if it was already marked as completed. -+ */ -+ public boolean execute(); -+ -+ /** -+ * Returns the current priority. Note that {@link Priority#COMPLETING} will be returned -+ * if this task is completing or has completed. -+ */ -+ public 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 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 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 Priority priority); -+ -+ /** -+ * Returns the suborder id associated with this task. -+ * @return The suborder id associated with this task. -+ */ -+ public long getSubOrder(); -+ -+ /** -+ * Sets the suborder id associated with this task. Ths function has no effect when this task -+ * is completing or is completed. -+ * -+ * @param subOrder Specified new sub order. -+ * -+ * @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 current suborder is the same as the new sub order. -+ */ -+ public boolean setSubOrder(final long subOrder); -+ -+ /** -+ * Attempts to raise the suborder to the suborder specified. -+ * -+ * @param subOrder Specified new sub order. -+ * -+ * @return {@code false} if the current task is completing, {@code true} if the suborder was raised to the -+ * specified suborder or was already at the specified suborder or higher. -+ */ -+ public boolean raiseSubOrder(final long subOrder); -+ -+ /** -+ * Attempts to lower the suborder to the suborder specified. -+ * -+ * @param subOrder Specified new sub order. -+ * -+ * @return {@code false} if the current task is completing, {@code true} if the suborder was lowered to the -+ * specified suborder or was already at the specified suborder or lower. -+ */ -+ public boolean lowerSubOrder(final long subOrder); -+ -+ /** -+ * Sets the priority and suborder id associated with this task. Ths function has no effect when this task -+ * is completing or is completed. -+ * -+ * @param priority Priority specified -+ * @param subOrder Specified new sub order. -+ * @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 current priority and suborder are the same as -+ * the parameters. -+ */ -+ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/queue/PrioritisedTaskQueue.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/queue/PrioritisedTaskQueue.java -new file mode 100644 -index 0000000000000000000000000000000000000000..edb8c6611bdc9aced2714b963e00bbb7829603d2 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/queue/PrioritisedTaskQueue.java -@@ -0,0 +1,454 @@ -+package ca.spottedleaf.concurrentutil.executor.queue; -+ -+import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.Priority; -+import java.lang.invoke.VarHandle; -+import java.util.Comparator; -+import java.util.Map; -+import java.util.concurrent.ConcurrentSkipListMap; -+import java.util.concurrent.atomic.AtomicBoolean; -+import java.util.concurrent.atomic.AtomicLong; -+ -+public final class PrioritisedTaskQueue implements PrioritisedExecutor { -+ -+ /** -+ * Required for tie-breaking in the queue -+ */ -+ private final AtomicLong taskIdGenerator = new AtomicLong(); -+ private final AtomicLong scheduledTasks = new AtomicLong(); -+ private final AtomicLong executedTasks = new AtomicLong(); -+ private final AtomicLong subOrderGenerator = new AtomicLong(); -+ private final AtomicBoolean shutdown = new AtomicBoolean(); -+ private final ConcurrentSkipListMap tasks = new ConcurrentSkipListMap<>(PrioritisedQueuedTask.COMPARATOR); -+ -+ @Override -+ public long getTotalTasksScheduled() { -+ return this.scheduledTasks.get(); -+ } -+ -+ @Override -+ public long getTotalTasksExecuted() { -+ return this.executedTasks.get(); -+ } -+ -+ @Override -+ public long generateNextSubOrder() { -+ return this.subOrderGenerator.getAndIncrement(); -+ } -+ -+ @Override -+ public boolean shutdown() { -+ return !this.shutdown.getAndSet(true); -+ } -+ -+ @Override -+ public boolean isShutdown() { -+ return this.shutdown.get(); -+ } -+ -+ public PrioritisedTask peekFirst() { -+ final Map.Entry firstEntry = this.tasks.firstEntry(); -+ return firstEntry == null ? null : firstEntry.getKey().task; -+ } -+ -+ public Priority getHighestPriority() { -+ final Map.Entry firstEntry = this.tasks.firstEntry(); -+ return firstEntry == null ? null : Priority.getPriority(firstEntry.getKey().priority); -+ } -+ -+ public boolean hasNoScheduledTasks() { -+ final long executedTasks = this.executedTasks.get(); -+ final long scheduledTasks = this.scheduledTasks.get(); -+ -+ return executedTasks == scheduledTasks; -+ } -+ -+ public PrioritySubOrderPair getHighestPrioritySubOrder() { -+ final Map.Entry firstEntry = this.tasks.firstEntry(); -+ if (firstEntry == null) { -+ return null; -+ } -+ -+ final PrioritisedQueuedTask.Holder holder = firstEntry.getKey(); -+ -+ return new PrioritySubOrderPair(Priority.getPriority(holder.priority), holder.subOrder); -+ } -+ -+ public Runnable pollTask() { -+ for (;;) { -+ final Map.Entry firstEntry = this.tasks.pollFirstEntry(); -+ if (firstEntry != null) { -+ final PrioritisedQueuedTask.Holder task = firstEntry.getKey(); -+ task.markRemoved(); -+ if (!task.task.cancel()) { -+ continue; -+ } -+ return task.task.execute; -+ } -+ -+ return null; -+ } -+ } -+ -+ @Override -+ public boolean executeTask() { -+ for (;;) { -+ final Map.Entry firstEntry = this.tasks.pollFirstEntry(); -+ if (firstEntry != null) { -+ final PrioritisedQueuedTask.Holder task = firstEntry.getKey(); -+ task.markRemoved(); -+ if (!task.task.execute()) { -+ continue; -+ } -+ return true; -+ } -+ -+ return false; -+ } -+ } -+ -+ @Override -+ public PrioritisedTask createTask(final Runnable task) { -+ return this.createTask(task, Priority.NORMAL, this.generateNextSubOrder()); -+ } -+ -+ @Override -+ public PrioritisedTask createTask(final Runnable task, final Priority priority) { -+ return this.createTask(task, priority, this.generateNextSubOrder()); -+ } -+ -+ @Override -+ public PrioritisedTask createTask(final Runnable task, final Priority priority, final long subOrder) { -+ return new PrioritisedQueuedTask(task, priority, subOrder); -+ } -+ -+ @Override -+ public PrioritisedTask queueTask(final Runnable task) { -+ return this.queueTask(task, Priority.NORMAL, this.generateNextSubOrder()); -+ } -+ -+ @Override -+ public PrioritisedTask queueTask(final Runnable task, final Priority priority) { -+ return this.queueTask(task, priority, this.generateNextSubOrder()); -+ } -+ -+ @Override -+ public PrioritisedTask queueTask(final Runnable task, final Priority priority, final long subOrder) { -+ final PrioritisedQueuedTask ret = new PrioritisedQueuedTask(task, priority, subOrder); -+ -+ ret.queue(); -+ -+ return ret; -+ } -+ -+ private final class PrioritisedQueuedTask implements PrioritisedExecutor.PrioritisedTask { -+ public static final Comparator COMPARATOR = (final PrioritisedQueuedTask.Holder t1, final PrioritisedQueuedTask.Holder t2) -> { -+ final int priorityCompare = t1.priority - t2.priority; -+ if (priorityCompare != 0) { -+ return priorityCompare; -+ } -+ -+ final int subOrderCompare = Long.compare(t1.subOrder, t2.subOrder); -+ if (subOrderCompare != 0) { -+ return subOrderCompare; -+ } -+ -+ return Long.compare(t1.id, t2.id); -+ }; -+ -+ private static final class Holder { -+ private final PrioritisedQueuedTask task; -+ private final int priority; -+ private final long subOrder; -+ private final long id; -+ -+ private volatile boolean removed; -+ private static final VarHandle REMOVED_HANDLE = ConcurrentUtil.getVarHandle(Holder.class, "removed", boolean.class); -+ -+ private Holder(final PrioritisedQueuedTask task, final int priority, final long subOrder, -+ final long id) { -+ this.task = task; -+ this.priority = priority; -+ this.subOrder = subOrder; -+ this.id = id; -+ } -+ -+ /** -+ * Returns true if marked as removed -+ */ -+ public boolean markRemoved() { -+ return !(boolean)REMOVED_HANDLE.getAndSet((Holder)this, (boolean)true); -+ } -+ } -+ -+ private final long id; -+ private final Runnable execute; -+ -+ private Priority priority; -+ private long subOrder; -+ private Holder holder; -+ -+ public PrioritisedQueuedTask(final Runnable execute, final Priority priority, final long subOrder) { -+ if (!Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } -+ -+ this.execute = execute; -+ this.priority = priority; -+ this.subOrder = subOrder; -+ this.id = PrioritisedTaskQueue.this.taskIdGenerator.getAndIncrement(); -+ } -+ -+ @Override -+ public PrioritisedExecutor getExecutor() { -+ return PrioritisedTaskQueue.this; -+ } -+ -+ @Override -+ public boolean queue() { -+ synchronized (this) { -+ if (this.holder != null || this.priority == Priority.COMPLETING) { -+ return false; -+ } -+ -+ if (PrioritisedTaskQueue.this.isShutdown()) { -+ throw new IllegalStateException("Queue is shutdown"); -+ } -+ -+ final Holder holder = new Holder(this, this.priority.priority, this.subOrder, this.id); -+ this.holder = holder; -+ -+ PrioritisedTaskQueue.this.scheduledTasks.getAndIncrement(); -+ PrioritisedTaskQueue.this.tasks.put(holder, Boolean.TRUE); -+ } -+ -+ if (PrioritisedTaskQueue.this.isShutdown()) { -+ this.cancel(); -+ throw new IllegalStateException("Queue is shutdown"); -+ } -+ -+ -+ return true; -+ } -+ -+ @Override -+ public boolean isQueued() { -+ synchronized (this) { -+ return this.holder != null && this.priority != Priority.COMPLETING; -+ } -+ } -+ -+ @Override -+ public boolean cancel() { -+ synchronized (this) { -+ if (this.priority == Priority.COMPLETING) { -+ return false; -+ } -+ -+ this.priority = Priority.COMPLETING; -+ -+ if (this.holder != null) { -+ if (this.holder.markRemoved()) { -+ PrioritisedTaskQueue.this.tasks.remove(this.holder); -+ } -+ PrioritisedTaskQueue.this.executedTasks.getAndIncrement(); -+ } -+ -+ return true; -+ } -+ } -+ -+ @Override -+ public boolean execute() { -+ final boolean increaseExecuted; -+ -+ synchronized (this) { -+ if (this.priority == Priority.COMPLETING) { -+ return false; -+ } -+ -+ this.priority = Priority.COMPLETING; -+ -+ if (increaseExecuted = (this.holder != null)) { -+ if (this.holder.markRemoved()) { -+ PrioritisedTaskQueue.this.tasks.remove(this.holder); -+ } -+ } -+ } -+ -+ try { -+ this.execute.run(); -+ return true; -+ } finally { -+ if (increaseExecuted) { -+ PrioritisedTaskQueue.this.executedTasks.getAndIncrement(); -+ } -+ } -+ } -+ -+ @Override -+ public Priority getPriority() { -+ synchronized (this) { -+ return this.priority; -+ } -+ } -+ -+ @Override -+ public boolean setPriority(final Priority priority) { -+ synchronized (this) { -+ if (this.priority == Priority.COMPLETING || this.priority == priority) { -+ return false; -+ } -+ -+ this.priority = priority; -+ -+ if (this.holder != null) { -+ if (this.holder.markRemoved()) { -+ PrioritisedTaskQueue.this.tasks.remove(this.holder); -+ } -+ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); -+ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); -+ } -+ -+ return true; -+ } -+ } -+ -+ @Override -+ public boolean raisePriority(final Priority priority) { -+ synchronized (this) { -+ if (this.priority == Priority.COMPLETING || this.priority.isHigherOrEqualPriority(priority)) { -+ return false; -+ } -+ -+ this.priority = priority; -+ -+ if (this.holder != null) { -+ if (this.holder.markRemoved()) { -+ PrioritisedTaskQueue.this.tasks.remove(this.holder); -+ } -+ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); -+ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); -+ } -+ -+ return true; -+ } -+ } -+ -+ @Override -+ public boolean lowerPriority(Priority priority) { -+ synchronized (this) { -+ if (this.priority == Priority.COMPLETING || this.priority.isLowerOrEqualPriority(priority)) { -+ return false; -+ } -+ -+ this.priority = priority; -+ -+ if (this.holder != null) { -+ if (this.holder.markRemoved()) { -+ PrioritisedTaskQueue.this.tasks.remove(this.holder); -+ } -+ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); -+ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); -+ } -+ -+ return true; -+ } -+ } -+ -+ @Override -+ public long getSubOrder() { -+ synchronized (this) { -+ return this.subOrder; -+ } -+ } -+ -+ @Override -+ public boolean setSubOrder(final long subOrder) { -+ synchronized (this) { -+ if (this.priority == Priority.COMPLETING || this.subOrder == subOrder) { -+ return false; -+ } -+ -+ this.subOrder = subOrder; -+ -+ if (this.holder != null) { -+ if (this.holder.markRemoved()) { -+ PrioritisedTaskQueue.this.tasks.remove(this.holder); -+ } -+ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); -+ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); -+ } -+ -+ return true; -+ } -+ } -+ -+ @Override -+ public boolean raiseSubOrder(long subOrder) { -+ synchronized (this) { -+ if (this.priority == Priority.COMPLETING || this.subOrder >= subOrder) { -+ return false; -+ } -+ -+ this.subOrder = subOrder; -+ -+ if (this.holder != null) { -+ if (this.holder.markRemoved()) { -+ PrioritisedTaskQueue.this.tasks.remove(this.holder); -+ } -+ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); -+ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); -+ } -+ -+ return true; -+ } -+ } -+ -+ @Override -+ public boolean lowerSubOrder(final long subOrder) { -+ synchronized (this) { -+ if (this.priority == Priority.COMPLETING || this.subOrder <= subOrder) { -+ return false; -+ } -+ -+ this.subOrder = subOrder; -+ -+ if (this.holder != null) { -+ if (this.holder.markRemoved()) { -+ PrioritisedTaskQueue.this.tasks.remove(this.holder); -+ } -+ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); -+ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); -+ } -+ -+ return true; -+ } -+ } -+ -+ @Override -+ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder) { -+ synchronized (this) { -+ if (this.priority == Priority.COMPLETING || (this.priority == priority && this.subOrder == subOrder)) { -+ return false; -+ } -+ -+ this.priority = priority; -+ this.subOrder = subOrder; -+ -+ if (this.holder != null) { -+ if (this.holder.markRemoved()) { -+ PrioritisedTaskQueue.this.tasks.remove(this.holder); -+ } -+ this.holder = new Holder(this, priority.priority, this.subOrder, this.id); -+ PrioritisedTaskQueue.this.tasks.put(this.holder, Boolean.TRUE); -+ } -+ -+ return true; -+ } -+ } -+ } -+ -+ public static record PrioritySubOrderPair(Priority priority, long subOrder) {} -+} -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/DelayedPrioritisedTask.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/DelayedPrioritisedTask.java -deleted file mode 100644 -index 3ce10053d4ec51855ad7012abb5d97df1c0e557a..0000000000000000000000000000000000000000 ---- a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/DelayedPrioritisedTask.java -+++ /dev/null -@@ -1,170 +0,0 @@ --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 -deleted file mode 100644 -index 91beb6f23f257cf265fe3150f760892e605f217a..0000000000000000000000000000000000000000 ---- a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedExecutor.java -+++ /dev/null -@@ -1,276 +0,0 @@ --package ca.spottedleaf.concurrentutil.executor.standard; -- --import ca.spottedleaf.concurrentutil.executor.BaseExecutor; -- --/** -- * Implementation of {@link BaseExecutor} which schedules tasks to be executed by a given priority. -- * @see 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 Priority max(final Priority p1, final Priority p2) { -- return p1.isHigherOrEqualPriority(p2) ? p1 : p2; -- } -- -- // returns the lower priroity of the two -- public static 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 Priority[] PRIORITIES = 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 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; -- } -- } -- -- /** -- * Executes the next available task. -- *

    -- * If there is a task with priority {@link PrioritisedExecutor.Priority#BLOCKING} available, then that such task is executed. -- *

    -- *

    -- * 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. -- *

    -- *

    -- * 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. -- *

    -- * -- * @return {@code true} if a task was executed, {@code false} otherwise -- * @throws IllegalStateException If the current thread is not allowed to execute a task -- */ -- @Override -- public boolean executeTask() throws IllegalStateException; -- -- /** -- * 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, 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 Priority priority); -- -- /** -- * Creates, but does not execute or queue the task. The task must later be queued via {@link 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 PrioritisedTask createTask(final Runnable task) { -- return this.createTask(task, Priority.NORMAL); -- } -- -- /** -- * Creates, but does not execute or queue the task. The task must later be queued via {@link 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 PrioritisedTask createTask(final Runnable task, final Priority priority); -- -- /** -- * Extension of {@link ca.spottedleaf.concurrentutil.executor.BaseExecutor.BaseTask} which adds functions -- * to retrieve and modify the task's associated priority. -- * -- * @see ca.spottedleaf.concurrentutil.executor.BaseExecutor.BaseTask -- */ -- public static interface PrioritisedTask extends BaseTask { -- -- /** -- * Returns the current priority. Note that {@link Priority#COMPLETING} will be returned -- * if this task is completing or has completed. -- */ -- public 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 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 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 Priority priority); -- } --} -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedThreadPool.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedThreadPool.java -deleted file mode 100644 -index 2ba36e29d0d8693f2f5e6c6d195ca27f2a5099aa..0000000000000000000000000000000000000000 ---- a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedThreadPool.java -+++ /dev/null -@@ -1,632 +0,0 @@ --package ca.spottedleaf.concurrentutil.executor.standard; -- --import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; --import org.slf4j.Logger; --import org.slf4j.LoggerFactory; --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 = LoggerFactory.getLogger(PrioritisedThreadPool.class); -- -- private final PrioritisedThread[] threads; -- private final TreeSet queues = new TreeSet<>(PrioritisedPoolExecutorImpl.comparator()); -- private final String name; -- private final long queueMaxHoldTime; -- -- private final ReferenceOpenHashSet nonShutdownQueues = new ReferenceOpenHashSet<>(); -- private final ReferenceOpenHashSet activeQueues = new ReferenceOpenHashSet<>(); -- -- private boolean shutdown; -- -- private long schedulingIdGenerator; -- -- private static final long DEFAULT_QUEUE_HOLD_TIME = (long)(5.0e6); -- -- /** -- * @param name Specified debug name of this thread pool -- * @param threads The number of threads to use -- */ -- public PrioritisedThreadPool(final String name, final int threads) { -- this(name, threads, null); -- } -- -- /** -- * @param name Specified debug name of this thread pool -- * @param threads The number of threads to use -- * @param threadModifier Invoked for each created thread with its incremental id before starting them -- */ -- public PrioritisedThreadPool(final String name, final int threads, final BiConsumer threadModifier) { -- this(name, threads, threadModifier, DEFAULT_QUEUE_HOLD_TIME); // 5ms -- } -- -- /** -- * @param name Specified debug name of this thread pool -- * @param threads The number of threads to use -- * @param threadModifier Invoked for each created thread with its incremental id before starting them -- * @param queueHoldTime The maximum amount of time to spend executing tasks in a specific queue before attempting -- * to switch to another queue, per thread -- */ -- public PrioritisedThreadPool(final String name, final int threads, final BiConsumer 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(); -- } -- } -- -- /** -- * Returns an array representing the threads backing this thread pool. -- */ -- public Thread[] getThreads() { -- return Arrays.copyOf(this.threads, this.threads.length, Thread[].class); -- } -- -- /** -- * Creates and returns a {@link PrioritisedPoolExecutor} to schedule tasks onto. The returned executor will execute -- * tasks on this thread pool only. -- * @param name The debug name of the executor. -- * @param minParallelism The minimum number of threads to be executing tasks from the returned executor -- * before threads may be allocated to other queues in this thread pool. -- * @param parallelism The maximum number of threads which may be executing tasks from the returned executor. -- * @throws IllegalStateException If this thread pool is shut down -- */ -- public PrioritisedPoolExecutor createExecutor(final String name, final int minParallelism, 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), -- Math.min(Math.max(0, minParallelism), 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 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(); -- } -- } -- } -- -- /** -- * Shuts down this thread pool, optionally waiting for all tasks to be executed. -- * This function will invoke {@link PrioritisedPoolExecutor#shutdown()} on all created executors on this -- * thread pool. -- * @param wait Whether to wait for tasks to be executed -- */ -- public void shutdown(final boolean wait) { -- final ArrayList 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 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 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 final int minimumExecutors; -- protected boolean isQueued; -- -- public PrioritisedPoolExecutorImpl(final PrioritisedThreadPool pool, final String name, final int maximumExecutors, final int minimumExecutors) { -- this.pool = pool; -- this.name = name; -- this.maximumExecutors = maximumExecutors; -- this.minimumExecutors = minimumExecutors; -- } -- -- public static Comparator comparator() { -- return (final PrioritisedPoolExecutorImpl p1, final PrioritisedPoolExecutorImpl p2) -> { -- if (p1 == p2) { -- return 0; -- } -- -- final int belowMin1 = p1.minimumExecutors - p1.concurrentExecutors; -- final int belowMin2 = p2.minimumExecutors - p2.concurrentExecutors; -- -- // test minimum executors -- if (belowMin1 > 0 || belowMin2 > 0) { -- // want the largest belowMin to be first -- final int minCompare = Integer.compare(belowMin2, belowMin1); -- -- if (minCompare != 0) { -- return minCompare; -- } -- } -- -- // 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 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 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 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 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 -deleted file mode 100644 -index 3e8401b1b1f833c4f01bc87059a2f48d761d989f..0000000000000000000000000000000000000000 ---- a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedThreadedTaskQueue.java -+++ /dev/null -@@ -1,378 +0,0 @@ --package ca.spottedleaf.concurrentutil.executor.standard; -- --import java.util.ArrayDeque; --import java.util.concurrent.atomic.AtomicLong; -- --public class PrioritisedThreadedTaskQueue implements PrioritisedExecutor { -- -- protected final ArrayDeque[] 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 Priority priority) throws IllegalStateException, IllegalArgumentException { -- if (!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 (!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 Priority minPriority) { -- final ArrayDeque[] queues = this.queues; -- synchronized (queues) { -- final int max = minPriority.priority; -- for (int i = 0; i <= max; ++i) { -- final ArrayDeque 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 Priority priority; -- -- protected PrioritisedTask(final long id, final Runnable runnable, final Priority priority, final PrioritisedThreadedTaskQueue queue) { -- if (!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 Priority priority, final PrioritisedThreadedTaskQueue queue) { -- if (!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 Priority priority = this.priority; -- if (priority == 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 Priority oldPriority = this.priority; -- if (oldPriority != Priority.COMPLETING && oldPriority.isHigherOrEqualPriority(minPriority)) { -- this.priority = Priority.COMPLETING; -- if (this.id != NOT_SCHEDULED_ID) { -- this.queue.priorityChange(this, oldPriority, Priority.COMPLETING); -- } -- return true; -- } -- -- return false; -- } -- -- @Override -- public Priority getPriority() { -- return this.priority; -- } -- -- @Override -- public boolean setPriority(final Priority priority) { -- if (!Priority.isValidPriority(priority)) { -- throw new IllegalArgumentException("Invalid priority " + priority); -- } -- synchronized (this.queue.queues) { -- final Priority curr = this.priority; -- -- if (curr == 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 Priority priority) { -- if (!Priority.isValidPriority(priority)) { -- throw new IllegalArgumentException("Invalid priority " + priority); -- } -- -- synchronized (this.queue.queues) { -- final Priority curr = this.priority; -- -- if (curr == 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 Priority priority) { -- if (!Priority.isValidPriority(priority)) { -- throw new IllegalArgumentException("Invalid priority " + priority); -- } -- -- synchronized (this.queue.queues) { -- final Priority curr = this.priority; -- -- if (curr == 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 == Priority.COMPLETING) { -- return false; -- } -- -- this.priority = Priority.COMPLETING; -- // call priority change callback -- if ((id = this.id) != NOT_SCHEDULED_ID) { -- this.queue.priorityChange(this, oldPriority, 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 == Priority.COMPLETING) { -- return false; -- } -- -- this.priority = Priority.COMPLETING; -- // call priority change callback -- if (this.id != NOT_SCHEDULED_ID) { -- this.queue.priorityChange(this, oldPriority, Priority.COMPLETING); -- } -- } -- -- this.executeInternal(); -- return true; -- } -- } --} -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedQueueExecutorThread.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedQueueExecutorThread.java -similarity index 60% -rename from src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedQueueExecutorThread.java -rename to src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedQueueExecutorThread.java -index d1683ba6350e530373944f98192c0f2baf241e70..f5367a13aaa02f0f929813c00a67e6ac7c8652cb 100644 ---- a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedQueueExecutorThread.java -+++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedQueueExecutorThread.java -@@ -1,6 +1,8 @@ --package ca.spottedleaf.concurrentutil.executor.standard; -+package ca.spottedleaf.concurrentutil.executor.thread; - -+import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; - import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.concurrentutil.util.Priority; - import org.slf4j.Logger; - import org.slf4j.LoggerFactory; - import java.lang.invoke.VarHandle; -@@ -11,8 +13,7 @@ import java.util.concurrent.locks.LockSupport; - *

    - * 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. -+ * of task scheduling, use the methods provided on this class to schedule tasks. - *

    - */ - public class PrioritisedQueueExecutorThread extends Thread implements PrioritisedExecutor { -@@ -30,7 +31,7 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise - - protected final long spinWaitTime; - -- static final long DEFAULT_SPINWAIT_TIME = (long)(0.1e6);// 0.1ms -+ protected static final long DEFAULT_SPINWAIT_TIME = (long)(0.1e6);// 0.1ms - - public PrioritisedQueueExecutorThread(final PrioritisedExecutor queue) { - this(queue, DEFAULT_SPINWAIT_TIME); // 0.1ms -@@ -42,7 +43,16 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise - } - - @Override -- public void run() { -+ public final void run() { -+ try { -+ this.begin(); -+ this.doRun(); -+ } finally { -+ this.die(); -+ } -+ } -+ -+ public final void doRun() { - final long spinWaitTime = this.spinWaitTime; - - main_loop: -@@ -80,7 +90,7 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise - 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) -+ // (i.e. it will not notify us) - if (this.pollTasks()) { - this.setThreadParkedVolatile(false); - continue; -@@ -99,6 +109,10 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise - } - } - -+ protected void begin() {} -+ -+ protected void die() {} -+ - /** - * Attempts to poll as many tasks as possible, returning when finished. - * @return Whether any tasks were executed. -@@ -115,8 +129,6 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise - 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); - } -@@ -146,95 +158,86 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise - } - - @Override -- public PrioritisedTask createTask(final Runnable task, final Priority priority) { -- final 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); -- } -+ public long getTotalTasksExecuted() { -+ return this.queue.getTotalTasksExecuted(); -+ } - -- @Override -- public boolean raisePriority(final Priority priority) { -- return queueTask.raisePriority(priority); -- } -+ @Override -+ public long getTotalTasksScheduled() { -+ return this.queue.getTotalTasksScheduled(); -+ } - -- @Override -- public boolean lowerPriority(final Priority priority) { -- return queueTask.lowerPriority(priority); -- } -+ @Override -+ public long generateNextSubOrder() { -+ return this.queue.generateNextSubOrder(); -+ } - -- @Override -- public boolean queue() { -- final boolean ret = queueTask.queue(); -- if (ret) { -- PrioritisedQueueExecutorThread.this.notifyTasks(); -- } -- return ret; -- } -+ @Override -+ public boolean shutdown() { -+ throw new UnsupportedOperationException(); -+ } - -- @Override -- public boolean cancel() { -- return queueTask.cancel(); -- } -+ @Override -+ public boolean isShutdown() { -+ return false; -+ } - -- @Override -- public boolean execute() { -- return queueTask.execute(); -- } -- }; -+ /** -+ * {@inheritDoc} -+ * @throws IllegalStateException Always -+ */ -+ @Override -+ public boolean executeTask() throws IllegalStateException { -+ throw new IllegalStateException(); - } - - @Override -- public PrioritisedTask queueRunnable(final Runnable task, final Priority priority) { -- final PrioritisedTask ret = this.queue.queueRunnable(task, priority); -+ public PrioritisedTask queueTask(final Runnable task) { -+ final PrioritisedTask ret = this.createTask(task); - -- this.notifyTasks(); -+ ret.queue(); - - return ret; - } - - @Override -- public boolean haveAllTasksExecuted() { -- return this.queue.haveAllTasksExecuted(); -+ public PrioritisedTask queueTask(final Runnable task, final Priority priority) { -+ final PrioritisedTask ret = this.createTask(task, priority); -+ -+ ret.queue(); -+ -+ return ret; - } - - @Override -- public long getTotalTasksExecuted() { -- return this.queue.getTotalTasksExecuted(); -+ public PrioritisedTask queueTask(final Runnable task, final Priority priority, final long subOrder) { -+ final PrioritisedTask ret = this.createTask(task, priority, subOrder); -+ -+ ret.queue(); -+ -+ return ret; - } - -+ - @Override -- public long getTotalTasksScheduled() { -- return this.queue.getTotalTasksScheduled(); -+ public PrioritisedTask createTask(Runnable task) { -+ final PrioritisedTask queueTask = this.queue.createTask(task); -+ -+ return new WrappedTask(queueTask); - } - -- /** -- * {@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(); -+ public PrioritisedTask createTask(final Runnable task, final Priority priority) { -+ final PrioritisedTask queueTask = this.queue.createTask(task, priority); -+ -+ return new WrappedTask(queueTask); - } - -- /** -- * {@inheritDoc} -- * @throws IllegalStateException Always -- */ - @Override -- public boolean executeTask() throws IllegalStateException { -- throw new IllegalStateException(); -+ public PrioritisedTask createTask(final Runnable task, final Priority priority, final long subOrder) { -+ final PrioritisedTask queueTask = this.queue.createTask(task, priority, subOrder); -+ -+ return new WrappedTask(queueTask); - } - - /** -@@ -242,7 +245,7 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise - *

    - * This function is MT-Safe. - *

    -- * @param wait If this call is to wait until the queue is empty and there are no tasks executing in the queue. -+ * @param wait If this call is to wait until this thread shuts down. - * @param killQueue Whether to shutdown this thread's queue - * @return whether this thread shut down the queue - * @see #halt(boolean) -@@ -256,7 +259,20 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise - LockSupport.unpark(this); - - if (wait) { -- this.waitUntilAllExecuted(); -+ boolean interrupted = false; -+ for (;;) { -+ if (this.isAlive()) { -+ if (interrupted) { -+ Thread.currentThread().interrupt(); -+ } -+ break; -+ } -+ try { -+ this.join(); -+ } catch (final InterruptedException ex) { -+ interrupted = true; -+ } -+ } - } - - return ret; -@@ -298,4 +314,89 @@ public class PrioritisedQueueExecutorThread extends Thread implements Prioritise - protected final void setThreadParkedVolatile(final boolean value) { - THREAD_PARKED_HANDLE.setVolatile(this, value); - } -+ -+ /** -+ * Required so that queue() can notify (unpark) this thread -+ */ -+ private final class WrappedTask implements PrioritisedTask { -+ private final PrioritisedTask queueTask; -+ -+ public WrappedTask(final PrioritisedTask queueTask) { -+ this.queueTask = queueTask; -+ } -+ -+ @Override -+ public PrioritisedExecutor getExecutor() { -+ return PrioritisedQueueExecutorThread.this; -+ } -+ -+ @Override -+ public boolean queue() { -+ final boolean ret = this.queueTask.queue(); -+ if (ret) { -+ PrioritisedQueueExecutorThread.this.notifyTasks(); -+ } -+ return ret; -+ } -+ -+ @Override -+ public boolean isQueued() { -+ return this.queueTask.isQueued(); -+ } -+ -+ @Override -+ public boolean cancel() { -+ return this.queueTask.cancel(); -+ } -+ -+ @Override -+ public boolean execute() { -+ return this.queueTask.execute(); -+ } -+ -+ @Override -+ public Priority getPriority() { -+ return this.queueTask.getPriority(); -+ } -+ -+ @Override -+ public boolean setPriority(final Priority priority) { -+ return this.queueTask.setPriority(priority); -+ } -+ -+ @Override -+ public boolean raisePriority(final Priority priority) { -+ return this.queueTask.raisePriority(priority); -+ } -+ -+ @Override -+ public boolean lowerPriority(final Priority priority) { -+ return this.queueTask.lowerPriority(priority); -+ } -+ -+ @Override -+ public long getSubOrder() { -+ return this.queueTask.getSubOrder(); -+ } -+ -+ @Override -+ public boolean setSubOrder(final long subOrder) { -+ return this.queueTask.setSubOrder(subOrder); -+ } -+ -+ @Override -+ public boolean raiseSubOrder(final long subOrder) { -+ return this.queueTask.raiseSubOrder(subOrder); -+ } -+ -+ @Override -+ public boolean lowerSubOrder(final long subOrder) { -+ return this.queueTask.lowerSubOrder(subOrder); -+ } -+ -+ @Override -+ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder) { -+ return this.queueTask.setPriorityAndSubOrder(priority, subOrder); -+ } -+ } - } -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedThreadPool.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedThreadPool.java -new file mode 100644 -index 0000000000000000000000000000000000000000..cb9df914a9a6d0d3f58fa58d8c93f4f583416cd1 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/thread/PrioritisedThreadPool.java -@@ -0,0 +1,741 @@ -+package ca.spottedleaf.concurrentutil.executor.thread; -+ -+import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.queue.PrioritisedTaskQueue; -+import ca.spottedleaf.concurrentutil.util.Priority; -+import ca.spottedleaf.concurrentutil.util.TimeUtil; -+import org.slf4j.Logger; -+import org.slf4j.LoggerFactory; -+import java.lang.reflect.Array; -+import java.util.Arrays; -+import java.util.concurrent.atomic.AtomicBoolean; -+import java.util.concurrent.atomic.AtomicLong; -+import java.util.function.Consumer; -+ -+public final class PrioritisedThreadPool { -+ -+ private static final Logger LOGGER = LoggerFactory.getLogger(PrioritisedThreadPool.class); -+ -+ private final Consumer threadModifier; -+ private final COWArrayList executors = new COWArrayList<>(ExecutorGroup.class); -+ private final COWArrayList threads = new COWArrayList<>(PrioritisedThread.class); -+ private final COWArrayList aliveThreads = new COWArrayList<>(PrioritisedThread.class); -+ -+ private static final Priority HIGH_PRIORITY_NOTIFY_THRESHOLD = Priority.HIGH; -+ private static final Priority QUEUE_SHUTDOWN_PRIORITY = Priority.HIGH; -+ -+ private boolean shutdown; -+ -+ public PrioritisedThreadPool(final Consumer threadModifier) { -+ this.threadModifier = threadModifier; -+ -+ if (threadModifier == null) { -+ throw new NullPointerException("Thread factory may not be null"); -+ } -+ } -+ -+ public Thread[] getAliveThreads() { -+ final PrioritisedThread[] threads = this.aliveThreads.getArray(); -+ -+ return Arrays.copyOf(threads, threads.length, Thread[].class); -+ } -+ -+ public Thread[] getCoreThreads() { -+ final PrioritisedThread[] threads = this.threads.getArray(); -+ -+ return Arrays.copyOf(threads, threads.length, Thread[].class); -+ } -+ -+ /** -+ * Prevents creation of new queues, shutdowns all non-shutdown queues if specified -+ */ -+ public void halt(final boolean shutdownQueues) { -+ synchronized (this) { -+ this.shutdown = true; -+ } -+ -+ if (shutdownQueues) { -+ for (final ExecutorGroup group : this.executors.getArray()) { -+ for (final ExecutorGroup.ThreadPoolExecutor executor : group.executors.getArray()) { -+ executor.shutdown(); -+ } -+ } -+ } -+ -+ for (final PrioritisedThread thread : this.threads.getArray()) { -+ 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.aliveThreads.getArray()) { -+ for (;;) { -+ if (!thread.isAlive()) { -+ break; -+ } -+ final long current = System.nanoTime(); -+ if (current >= deadline && msToWait > 0L) { -+ return false; -+ } -+ -+ try { -+ thread.join(msToWait <= 0L ? 0L : 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(); -+ } -+ } -+ } -+ -+ /** -+ * Shuts down this thread pool, optionally waiting for all tasks to be executed. -+ * This function will invoke {@link PrioritisedExecutor#shutdown()} on all created executors on this -+ * thread pool. -+ * @param wait Whether to wait for tasks to be executed -+ */ -+ public void shutdown(final boolean wait) { -+ synchronized (this) { -+ this.shutdown = true; -+ } -+ -+ for (final ExecutorGroup group : this.executors.getArray()) { -+ for (final ExecutorGroup.ThreadPoolExecutor executor : group.executors.getArray()) { -+ executor.shutdown(); -+ } -+ } -+ -+ -+ for (final PrioritisedThread thread : this.threads.getArray()) { -+ // none of these can be true or else NPE -+ thread.close(false, false); -+ } -+ -+ if (wait) { -+ this.join(0L); -+ } -+ } -+ -+ private void die(final PrioritisedThread thread) { -+ this.aliveThreads.remove(thread); -+ } -+ -+ public void adjustThreadCount(final int threads) { -+ synchronized (this) { -+ if (this.shutdown) { -+ return; -+ } -+ -+ final PrioritisedThread[] currentThreads = this.threads.getArray(); -+ if (threads == currentThreads.length) { -+ // no adjustment needed -+ return; -+ } -+ -+ if (threads < currentThreads.length) { -+ // we need to trim threads -+ for (int i = 0, difference = currentThreads.length - threads; i < difference; ++i) { -+ final PrioritisedThread remove = currentThreads[currentThreads.length - i - 1]; -+ -+ remove.halt(false); -+ this.threads.remove(remove); -+ } -+ } else { -+ // we need to add threads -+ for (int i = 0, difference = threads - currentThreads.length; i < difference; ++i) { -+ final PrioritisedThread thread = new PrioritisedThread(); -+ -+ this.threadModifier.accept(thread); -+ this.aliveThreads.add(thread); -+ this.threads.add(thread); -+ -+ thread.start(); -+ } -+ } -+ } -+ } -+ -+ private static int compareInsideGroup(final ExecutorGroup.ThreadPoolExecutor src, final Priority srcPriority, -+ final ExecutorGroup.ThreadPoolExecutor dst, final Priority dstPriority) { -+ final int priorityCompare = srcPriority.ordinal() - dstPriority.ordinal(); -+ if (priorityCompare != 0) { -+ return priorityCompare; -+ } -+ -+ final int parallelismCompare = src.currentParallelism - dst.currentParallelism; -+ if (parallelismCompare != 0) { -+ return parallelismCompare; -+ } -+ -+ return TimeUtil.compareTimes(src.lastRetrieved, dst.lastRetrieved); -+ } -+ -+ private static int compareOutsideGroup(final ExecutorGroup.ThreadPoolExecutor src, final Priority srcPriority, -+ final ExecutorGroup.ThreadPoolExecutor dst, final Priority dstPriority) { -+ if (src.getGroup().division == dst.getGroup().division) { -+ // can only compare priorities inside the same division -+ final int priorityCompare = srcPriority.ordinal() - dstPriority.ordinal(); -+ if (priorityCompare != 0) { -+ return priorityCompare; -+ } -+ } -+ -+ final int parallelismCompare = src.getGroup().currentParallelism - dst.getGroup().currentParallelism; -+ if (parallelismCompare != 0) { -+ return parallelismCompare; -+ } -+ -+ return TimeUtil.compareTimes(src.lastRetrieved, dst.lastRetrieved); -+ } -+ -+ private ExecutorGroup.ThreadPoolExecutor obtainQueue() { -+ final long time = System.nanoTime(); -+ synchronized (this) { -+ ExecutorGroup.ThreadPoolExecutor ret = null; -+ Priority retPriority = null; -+ -+ for (final ExecutorGroup executorGroup : this.executors.getArray()) { -+ ExecutorGroup.ThreadPoolExecutor highest = null; -+ Priority highestPriority = null; -+ for (final ExecutorGroup.ThreadPoolExecutor executor : executorGroup.executors.getArray()) { -+ final int maxParallelism = executor.maxParallelism; -+ if (maxParallelism > 0 && executor.currentParallelism >= maxParallelism) { -+ continue; -+ } -+ -+ final Priority priority = executor.getTargetPriority(); -+ -+ if (priority == null) { -+ continue; -+ } -+ -+ if (highestPriority == null || compareInsideGroup(highest, highestPriority, executor, priority) > 0) { -+ highest = executor; -+ highestPriority = priority; -+ } -+ } -+ -+ if (highest == null) { -+ continue; -+ } -+ -+ if (ret == null || compareOutsideGroup(ret, retPriority, highest, highestPriority) > 0) { -+ ret = highest; -+ retPriority = highestPriority; -+ } -+ } -+ -+ if (ret != null) { -+ ret.lastRetrieved = time; -+ ++ret.currentParallelism; -+ ++ret.getGroup().currentParallelism; -+ return ret; -+ } -+ -+ return ret; -+ } -+ } -+ -+ private void returnQueue(final ExecutorGroup.ThreadPoolExecutor executor) { -+ synchronized (this) { -+ --executor.currentParallelism; -+ --executor.getGroup().currentParallelism; -+ } -+ -+ if (executor.isShutdown() && executor.queue.hasNoScheduledTasks()) { -+ executor.getGroup().executors.remove(executor); -+ } -+ } -+ -+ private void notifyAllThreads() { -+ for (final PrioritisedThread thread : this.threads.getArray()) { -+ thread.notifyTasks(); -+ } -+ } -+ -+ public ExecutorGroup createExecutorGroup(final int division, final int flags) { -+ synchronized (this) { -+ if (this.shutdown) { -+ throw new IllegalStateException("Queue is shutdown: " + this.toString()); -+ } -+ -+ final ExecutorGroup ret = new ExecutorGroup(division, flags); -+ -+ this.executors.add(ret); -+ -+ return ret; -+ } -+ } -+ -+ private final class PrioritisedThread extends PrioritisedQueueExecutorThread { -+ -+ private final AtomicBoolean alertedHighPriority = new AtomicBoolean(); -+ -+ public PrioritisedThread() { -+ super(null); -+ } -+ -+ 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 void die() { -+ PrioritisedThreadPool.this.die(this); -+ } -+ -+ @Override -+ protected boolean pollTasks() { -+ boolean ret = false; -+ -+ for (;;) { -+ if (this.halted) { -+ break; -+ } -+ -+ final ExecutorGroup.ThreadPoolExecutor executor = PrioritisedThreadPool.this.obtainQueue(); -+ if (executor == null) { -+ break; -+ } -+ final long deadline = System.nanoTime() + executor.queueMaxHoldTime; -+ do { -+ try { -+ if (this.halted || executor.halt) { -+ break; -+ } -+ if (!executor.executeTask()) { -+ // no more tasks, try next queue -+ break; -+ } -+ ret = true; -+ } catch (final Throwable throwable) { -+ LOGGER.error("Exception thrown from thread '" + this.getName() + "' in queue '" + executor.toString() + "'", throwable); -+ } -+ } while (!this.isAlertedHighPriority() && System.nanoTime() <= deadline); -+ -+ PrioritisedThreadPool.this.returnQueue(executor); -+ } -+ -+ -+ return ret; -+ } -+ } -+ -+ public final class ExecutorGroup { -+ -+ private final AtomicLong subOrderGenerator = new AtomicLong(); -+ private final COWArrayList executors = new COWArrayList<>(ThreadPoolExecutor.class); -+ -+ private final int division; -+ private int currentParallelism; -+ -+ private ExecutorGroup(final int division, final int flags) { -+ this.division = division; -+ } -+ -+ public ThreadPoolExecutor[] getAllExecutors() { -+ return this.executors.getArray().clone(); -+ } -+ -+ private PrioritisedThreadPool getThreadPool() { -+ return PrioritisedThreadPool.this; -+ } -+ -+ public ThreadPoolExecutor createExecutor(final int maxParallelism, final long queueMaxHoldTime, final int flags) { -+ synchronized (PrioritisedThreadPool.this) { -+ if (PrioritisedThreadPool.this.shutdown) { -+ throw new IllegalStateException("Queue is shutdown: " + PrioritisedThreadPool.this.toString()); -+ } -+ -+ final ThreadPoolExecutor ret = new ThreadPoolExecutor(maxParallelism, queueMaxHoldTime, flags); -+ -+ this.executors.add(ret); -+ -+ return ret; -+ } -+ } -+ -+ public final class ThreadPoolExecutor implements PrioritisedExecutor { -+ -+ private final PrioritisedTaskQueue queue = new PrioritisedTaskQueue(); -+ -+ private volatile int maxParallelism; -+ private final long queueMaxHoldTime; -+ private volatile int currentParallelism; -+ private volatile boolean halt; -+ private long lastRetrieved = System.nanoTime(); -+ -+ private ThreadPoolExecutor(final int maxParallelism, final long queueMaxHoldTime, final int flags) { -+ this.maxParallelism = maxParallelism; -+ this.queueMaxHoldTime = queueMaxHoldTime; -+ } -+ -+ private ExecutorGroup getGroup() { -+ return ExecutorGroup.this; -+ } -+ -+ private boolean canNotify() { -+ if (this.halt) { -+ return false; -+ } -+ -+ final int max = this.maxParallelism; -+ return max < 0 || this.currentParallelism < max; -+ } -+ -+ private void notifyHighPriority() { -+ if (!this.canNotify()) { -+ return; -+ } -+ for (final PrioritisedThread thread : this.getGroup().getThreadPool().threads.getArray()) { -+ if (thread.alertHighPriorityExecutor()) { -+ return; -+ } -+ } -+ } -+ -+ private void notifyScheduled() { -+ if (!this.canNotify()) { -+ return; -+ } -+ for (final PrioritisedThread thread : this.getGroup().getThreadPool().threads.getArray()) { -+ if (thread.notifyTasks()) { -+ return; -+ } -+ } -+ } -+ -+ /** -+ * Removes this queue from the thread pool without shutting the queue down or waiting for queued tasks to be executed -+ */ -+ public void halt() { -+ this.halt = true; -+ -+ ExecutorGroup.this.executors.remove(this); -+ } -+ -+ /** -+ * 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() { -+ if (this.halt) { -+ return this.currentParallelism > 0; -+ } else { -+ if (!this.isShutdown()) { -+ return true; -+ } -+ -+ return !this.queue.hasNoScheduledTasks(); -+ } -+ } -+ -+ @Override -+ public boolean shutdown() { -+ if (!this.queue.shutdown()) { -+ return false; -+ } -+ -+ if (this.queue.hasNoScheduledTasks()) { -+ ExecutorGroup.this.executors.remove(this); -+ } -+ -+ return true; -+ } -+ -+ @Override -+ public boolean isShutdown() { -+ return this.queue.isShutdown(); -+ } -+ -+ public void setMaxParallelism(final int maxParallelism) { -+ this.maxParallelism = maxParallelism; -+ // assume that we could have increased the parallelism -+ if (this.getTargetPriority() != null) { -+ ExecutorGroup.this.getThreadPool().notifyAllThreads(); -+ } -+ } -+ -+ Priority getTargetPriority() { -+ final Priority ret = this.queue.getHighestPriority(); -+ if (!this.isShutdown()) { -+ return ret; -+ } -+ -+ return ret == null ? QUEUE_SHUTDOWN_PRIORITY : Priority.max(ret, QUEUE_SHUTDOWN_PRIORITY); -+ } -+ -+ @Override -+ public long getTotalTasksScheduled() { -+ return this.queue.getTotalTasksScheduled(); -+ } -+ -+ @Override -+ public long getTotalTasksExecuted() { -+ return this.queue.getTotalTasksExecuted(); -+ } -+ -+ @Override -+ public long generateNextSubOrder() { -+ return ExecutorGroup.this.subOrderGenerator.getAndIncrement(); -+ } -+ -+ @Override -+ public boolean executeTask() { -+ return this.queue.executeTask(); -+ } -+ -+ @Override -+ public PrioritisedTask queueTask(final Runnable task) { -+ final PrioritisedTask ret = this.createTask(task); -+ -+ ret.queue(); -+ -+ return ret; -+ } -+ -+ @Override -+ public PrioritisedTask queueTask(final Runnable task, final Priority priority) { -+ final PrioritisedTask ret = this.createTask(task, priority); -+ -+ ret.queue(); -+ -+ return ret; -+ } -+ -+ @Override -+ public PrioritisedTask queueTask(final Runnable task, final Priority priority, final long subOrder) { -+ final PrioritisedTask ret = this.createTask(task, priority, subOrder); -+ -+ ret.queue(); -+ -+ return ret; -+ } -+ -+ @Override -+ public PrioritisedTask createTask(final Runnable task) { -+ return this.createTask(task, Priority.NORMAL); -+ } -+ -+ @Override -+ public PrioritisedTask createTask(final Runnable task, final Priority priority) { -+ return this.createTask(task, priority, this.generateNextSubOrder()); -+ } -+ -+ @Override -+ public PrioritisedTask createTask(final Runnable task, final Priority priority, final long subOrder) { -+ return new WrappedTask(this.queue.createTask(task, priority, subOrder)); -+ } -+ -+ private final class WrappedTask implements PrioritisedTask { -+ -+ private final PrioritisedTask wrapped; -+ -+ private WrappedTask(final PrioritisedTask wrapped) { -+ this.wrapped = wrapped; -+ } -+ -+ @Override -+ public PrioritisedExecutor getExecutor() { -+ return ThreadPoolExecutor.this; -+ } -+ -+ @Override -+ public boolean queue() { -+ if (this.wrapped.queue()) { -+ final Priority priority = this.getPriority(); -+ if (priority != Priority.COMPLETING) { -+ if (priority.isHigherOrEqualPriority(HIGH_PRIORITY_NOTIFY_THRESHOLD)) { -+ ThreadPoolExecutor.this.notifyHighPriority(); -+ } else { -+ ThreadPoolExecutor.this.notifyScheduled(); -+ } -+ } -+ return true; -+ } -+ -+ return false; -+ } -+ -+ @Override -+ public boolean isQueued() { -+ return this.wrapped.isQueued(); -+ } -+ -+ @Override -+ public boolean cancel() { -+ return this.wrapped.cancel(); -+ } -+ -+ @Override -+ public boolean execute() { -+ return this.wrapped.execute(); -+ } -+ -+ @Override -+ public Priority getPriority() { -+ return this.wrapped.getPriority(); -+ } -+ -+ @Override -+ public boolean setPriority(final Priority priority) { -+ if (this.wrapped.setPriority(priority)) { -+ if (priority.isHigherOrEqualPriority(HIGH_PRIORITY_NOTIFY_THRESHOLD)) { -+ ThreadPoolExecutor.this.notifyHighPriority(); -+ } -+ return true; -+ } -+ -+ return false; -+ } -+ -+ @Override -+ public boolean raisePriority(final Priority priority) { -+ if (this.wrapped.raisePriority(priority)) { -+ if (priority.isHigherOrEqualPriority(HIGH_PRIORITY_NOTIFY_THRESHOLD)) { -+ ThreadPoolExecutor.this.notifyHighPriority(); -+ } -+ return true; -+ } -+ -+ return false; -+ } -+ -+ @Override -+ public boolean lowerPriority(final Priority priority) { -+ return this.wrapped.lowerPriority(priority); -+ } -+ -+ @Override -+ public long getSubOrder() { -+ return this.wrapped.getSubOrder(); -+ } -+ -+ @Override -+ public boolean setSubOrder(final long subOrder) { -+ return this.wrapped.setSubOrder(subOrder); -+ } -+ -+ @Override -+ public boolean raiseSubOrder(final long subOrder) { -+ return this.wrapped.raiseSubOrder(subOrder); -+ } -+ -+ @Override -+ public boolean lowerSubOrder(final long subOrder) { -+ return this.wrapped.lowerSubOrder(subOrder); -+ } -+ -+ @Override -+ public boolean setPriorityAndSubOrder(final Priority priority, final long subOrder) { -+ if (this.wrapped.setPriorityAndSubOrder(priority, subOrder)) { -+ if (priority.isHigherOrEqualPriority(HIGH_PRIORITY_NOTIFY_THRESHOLD)) { -+ ThreadPoolExecutor.this.notifyHighPriority(); -+ } -+ return true; -+ } -+ -+ return false; -+ } -+ } -+ } -+ } -+ -+ private static final class COWArrayList { -+ -+ private volatile E[] array; -+ -+ public COWArrayList(final Class clazz) { -+ this.array = (E[])Array.newInstance(clazz, 0); -+ } -+ -+ public E[] getArray() { -+ return this.array; -+ } -+ -+ public void add(final E element) { -+ synchronized (this) { -+ final E[] array = this.array; -+ -+ final E[] copy = Arrays.copyOf(array, array.length + 1); -+ copy[array.length] = element; -+ -+ this.array = copy; -+ } -+ } -+ -+ public boolean remove(final E element) { -+ synchronized (this) { -+ final E[] array = this.array; -+ int index = -1; -+ for (int i = 0, len = array.length; i < len; ++i) { -+ if (array[i] == element) { -+ index = i; -+ break; -+ } -+ } -+ -+ if (index == -1) { -+ return false; -+ } -+ -+ final E[] copy = (E[])Array.newInstance(array.getClass().getComponentType(), array.length - 1); -+ -+ System.arraycopy(array, 0, copy, 0, index); -+ System.arraycopy(array, index + 1, copy, index, (array.length - 1) - index); -+ -+ this.array = copy; -+ } -+ -+ return true; -+ } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/map/ConcurrentLong2ReferenceChainedHashTable.java b/src/main/java/ca/spottedleaf/concurrentutil/map/ConcurrentLong2ReferenceChainedHashTable.java -index d701998b376579ec652fb94823befa3cc0bc4090..6918f130099e6c19e20a47bfdb54915cdd13732a 100644 ---- a/src/main/java/ca/spottedleaf/concurrentutil/map/ConcurrentLong2ReferenceChainedHashTable.java -+++ b/src/main/java/ca/spottedleaf/concurrentutil/map/ConcurrentLong2ReferenceChainedHashTable.java -@@ -43,7 +43,7 @@ import java.util.function.Predicate; - * @param - * @see java.util.concurrent.ConcurrentMap - */ --public class ConcurrentLong2ReferenceChainedHashTable { -+public class ConcurrentLong2ReferenceChainedHashTable implements Iterable> { - - protected static final int DEFAULT_CAPACITY = 16; - protected static final float DEFAULT_LOAD_FACTOR = 0.75f; -@@ -192,6 +192,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - } - - if (node.resize) { -+ // noinspection unchecked - table = (TableEntry[])node.getValuePlain(); - continue; - } -@@ -274,10 +275,10 @@ public class ConcurrentLong2ReferenceChainedHashTable { - public int size() { - final long ret = this.size.sum(); - -- if (ret <= 0L) { -+ if (ret < 0L) { - return 0; - } -- if (ret >= (long)Integer.MAX_VALUE) { -+ if (ret > (long)Integer.MAX_VALUE) { - return Integer.MAX_VALUE; - } - -@@ -341,6 +342,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - - // create new table data - -+ // noinspection unchecked - final TableEntry[] newTable = new TableEntry[capacity]; - // noinspection unchecked - final TableEntry resizeNode = new TableEntry<>(0L, (V)newTable, true); -@@ -365,6 +367,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - throw new IllegalStateException("Resizing to same size"); - } - -+ // noinspection unchecked - final TableEntry[] work = new TableEntry[1 << capDiffShift]; // typically, capDiffShift = 1 - - for (int i = 0, len = oldTable.length; i < len; ++i) { -@@ -538,6 +541,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - } - - if (node.resize) { -+ // noinspection unchecked - table = (TableEntry[])node.getValuePlain(); - continue table_loop; - } -@@ -599,6 +603,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - } - - if (node.resize) { -+ // noinspection unchecked - table = (TableEntry[])node.getValuePlain(); - continue table_loop; - } -@@ -653,6 +658,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - } - - if (node.resize) { -+ // noinspection unchecked - table = (TableEntry[])node.getValuePlain(); - continue table_loop; - } -@@ -704,6 +710,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - } - - if (node.resize) { -+ // noinspection unchecked - table = (TableEntry[])node.getValuePlain(); - continue table_loop; - } -@@ -772,6 +779,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - } - - if (node.resize) { -+ // noinspection unchecked - table = (TableEntry[])node.getValuePlain(); - continue table_loop; - } -@@ -848,6 +856,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - } - - if (node.resize) { -+ // noinspection unchecked - table = (TableEntry[])node.getValuePlain(); - continue table_loop; - } -@@ -944,6 +953,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - } - - if (node.resize) { -+ // noinspection unchecked - table = (TableEntry[])node.getValuePlain(); - continue table_loop; - } -@@ -1058,6 +1068,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - } - - if (node.resize) { -+ // noinspection unchecked - table = (TableEntry[])node.getValuePlain(); - continue table_loop; - } -@@ -1126,6 +1137,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - } - - if (node.resize) { -+ // noinspection unchecked - table = (TableEntry[])node.getValuePlain(); - continue table_loop; - } -@@ -1200,6 +1212,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - } - - if (node.resize) { -+ // noinspection unchecked - table = (TableEntry[])node.getValuePlain(); - continue table_loop; - } -@@ -1288,6 +1301,11 @@ public class ConcurrentLong2ReferenceChainedHashTable { - return new EntryIterator<>(this); - } - -+ @Override -+ public final Iterator> iterator() { -+ return this.entryIterator(); -+ } -+ - /** - * Returns an iterator over the keys in this map. The iterator is only guaranteed to see keys that were - * added before the beginning of this call, but it may see keys added during. -@@ -1306,7 +1324,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - - protected static final class EntryIterator extends BaseIteratorImpl> { - -- protected EntryIterator(final ConcurrentLong2ReferenceChainedHashTable map) { -+ public EntryIterator(final ConcurrentLong2ReferenceChainedHashTable map) { - super(map); - } - -@@ -1326,7 +1344,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - - protected static final class KeyIterator extends BaseIteratorImpl implements PrimitiveIterator.OfLong { - -- protected KeyIterator(final ConcurrentLong2ReferenceChainedHashTable map) { -+ public KeyIterator(final ConcurrentLong2ReferenceChainedHashTable map) { - super(map); - } - -@@ -1365,7 +1383,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - - protected static final class ValueIterator extends BaseIteratorImpl { - -- protected ValueIterator(final ConcurrentLong2ReferenceChainedHashTable map) { -+ public ValueIterator(final ConcurrentLong2ReferenceChainedHashTable map) { - super(map); - } - -@@ -1420,7 +1438,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - - @Override - public final void remove() { -- final TableEntry lastReturned = this.nextToReturn; -+ final TableEntry lastReturned = this.lastReturned; - if (lastReturned == null) { - throw new NoSuchElementException(); - } -@@ -1492,6 +1510,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - final ResizeChain chain = this.resizeChain; - - if (chain == null) { -+ // noinspection unchecked - final TableEntry[] nextTable = (TableEntry[])entry.getValuePlain(); - - final ResizeChain oldChain = new ResizeChain<>(table, null, null); -@@ -1506,6 +1525,7 @@ public class ConcurrentLong2ReferenceChainedHashTable { - } else { - ResizeChain currChain = chain.next; - if (currChain == null) { -+ // noinspection unchecked - final TableEntry[] ret = (TableEntry[])entry.getValuePlain(); - currChain = new ResizeChain<>(ret, chain, null); - chain.next = currChain; -@@ -1586,11 +1606,11 @@ public class ConcurrentLong2ReferenceChainedHashTable { - - protected static final class ResizeChain { - -- protected final TableEntry[] table; -- protected final ResizeChain prev; -- protected ResizeChain next; -+ public final TableEntry[] table; -+ public final ResizeChain prev; -+ public ResizeChain next; - -- protected ResizeChain(final TableEntry[] table, final ResizeChain prev, final ResizeChain next) { -+ public ResizeChain(final TableEntry[] table, final ResizeChain prev, final ResizeChain next) { - this.table = table; - this.prev = prev; - this.next = next; -@@ -1600,64 +1620,64 @@ public class ConcurrentLong2ReferenceChainedHashTable { - - public static final class TableEntry { - -- protected static final VarHandle TABLE_ENTRY_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(TableEntry[].class); -+ private static final VarHandle TABLE_ENTRY_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(TableEntry[].class); - -- protected final boolean resize; -+ private final boolean resize; - -- protected final long key; -+ private final long key; - -- protected volatile V value; -- protected static final VarHandle VALUE_HANDLE = ConcurrentUtil.getVarHandle(TableEntry.class, "value", Object.class); -+ private volatile V value; -+ private static final VarHandle VALUE_HANDLE = ConcurrentUtil.getVarHandle(TableEntry.class, "value", Object.class); - -- protected final V getValuePlain() { -+ private V getValuePlain() { - //noinspection unchecked - return (V)VALUE_HANDLE.get(this); - } - -- protected final V getValueAcquire() { -+ private V getValueAcquire() { - //noinspection unchecked - return (V)VALUE_HANDLE.getAcquire(this); - } - -- protected final V getValueVolatile() { -+ private V getValueVolatile() { - //noinspection unchecked - return (V)VALUE_HANDLE.getVolatile(this); - } - -- protected final void setValuePlain(final V value) { -+ private void setValuePlain(final V value) { - VALUE_HANDLE.set(this, (Object)value); - } - -- protected final void setValueRelease(final V value) { -+ private void setValueRelease(final V value) { - VALUE_HANDLE.setRelease(this, (Object)value); - } - -- protected final void setValueVolatile(final V value) { -+ private void setValueVolatile(final V value) { - VALUE_HANDLE.setVolatile(this, (Object)value); - } - -- protected volatile TableEntry next; -- protected static final VarHandle NEXT_HANDLE = ConcurrentUtil.getVarHandle(TableEntry.class, "next", TableEntry.class); -+ private volatile TableEntry next; -+ private static final VarHandle NEXT_HANDLE = ConcurrentUtil.getVarHandle(TableEntry.class, "next", TableEntry.class); - -- protected final TableEntry getNextPlain() { -+ private TableEntry getNextPlain() { - //noinspection unchecked - return (TableEntry)NEXT_HANDLE.get(this); - } - -- protected final TableEntry getNextVolatile() { -+ private TableEntry getNextVolatile() { - //noinspection unchecked - return (TableEntry)NEXT_HANDLE.getVolatile(this); - } - -- protected final void setNextPlain(final TableEntry next) { -+ private void setNextPlain(final TableEntry next) { - NEXT_HANDLE.set(this, next); - } - -- protected final void setNextRelease(final TableEntry next) { -+ private void setNextRelease(final TableEntry next) { - NEXT_HANDLE.setRelease(this, next); - } - -- protected final void setNextVolatile(final TableEntry next) { -+ private void setNextVolatile(final TableEntry next) { - NEXT_HANDLE.setVolatile(this, next); - } - -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/scheduler/SchedulerThreadPool.java b/src/main/java/ca/spottedleaf/concurrentutil/scheduler/SchedulerThreadPool.java -index 8197ccb1c4e5878dbd8007b5fb514640765ec8e4..85e6ef636d435a0ee4bf3e0760b0c87422c520a1 100644 ---- a/src/main/java/ca/spottedleaf/concurrentutil/scheduler/SchedulerThreadPool.java -+++ b/src/main/java/ca/spottedleaf/concurrentutil/scheduler/SchedulerThreadPool.java -@@ -13,6 +13,10 @@ import java.util.concurrent.atomic.AtomicLong; - import java.util.concurrent.locks.LockSupport; - import java.util.function.BooleanSupplier; - -+/** -+ * @deprecated To be replaced -+ */ -+@Deprecated - public class SchedulerThreadPool { - - public static final long DEADLINE_NOT_SET = Long.MIN_VALUE; -@@ -297,7 +301,9 @@ public class SchedulerThreadPool { - * is invoked for any scheduled task - otherwise, {@link #runTasks(BooleanSupplier)} may not be invoked to - * parse intermediate tasks. - *

    -+ * @deprecated To be replaced - */ -+ @Deprecated - public static abstract class SchedulableTick { - private static final AtomicLong ID_GENERATOR = new AtomicLong(); - public final long id = ID_GENERATOR.getAndIncrement(); -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedSortedSet.java b/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedSortedSet.java -index 212bc9ae2fc7d37d4a089a2921b00de1e97f7cc1..82c4c11b0b564c97ac92bd5f54e3754a7ba95184 100644 ---- a/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedSortedSet.java -+++ b/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedSortedSet.java -@@ -8,8 +8,8 @@ public final class LinkedSortedSet implements Iterable { - - public final Comparator comparator; - -- protected Link head; -- protected Link tail; -+ private Link head; -+ private Link tail; - - public LinkedSortedSet() { - this((Comparator)Comparator.naturalOrder()); -@@ -257,8 +257,6 @@ public final class LinkedSortedSet implements Iterable { - private Link prev; - private Link next; - -- private Link() {} -- - private Link(final E element) { - this.element = element; - } -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedUnsortedList.java b/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedUnsortedList.java -new file mode 100644 -index 0000000000000000000000000000000000000000..bd8eb4f25d1dee00fbf9c05c14b0d94c5c641a55 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/set/LinkedUnsortedList.java -@@ -0,0 +1,204 @@ -+package ca.spottedleaf.concurrentutil.set; -+ -+import java.util.Iterator; -+import java.util.NoSuchElementException; -+import java.util.Objects; -+ -+public final class LinkedUnsortedList implements Iterable { -+ -+ private Link head; -+ private Link tail; -+ -+ public LinkedUnsortedList() {} -+ -+ public void clear() { -+ this.head = this.tail = null; -+ } -+ -+ public boolean isEmpty() { -+ return this.head == null; -+ } -+ -+ public E first() { -+ final Link head = this.head; -+ return head == null ? null : head.element; -+ } -+ -+ public E last() { -+ final Link tail = this.tail; -+ return tail == null ? null : tail.element; -+ } -+ -+ public boolean containsFirst(final E element) { -+ for (Link curr = this.head; curr != null; curr = curr.next) { -+ if (Objects.equals(element, curr.element)) { -+ return true; -+ } -+ } -+ return false; -+ } -+ -+ public boolean containsLast(final E element) { -+ for (Link curr = this.tail; curr != null; curr = curr.prev) { -+ if (Objects.equals(element, curr.element)) { -+ return true; -+ } -+ } -+ return false; -+ } -+ -+ private void removeNode(final Link node) { -+ final Link prev = node.prev; -+ final Link next = node.next; -+ -+ // help GC -+ node.element = null; -+ node.prev = null; -+ node.next = null; -+ -+ if (prev == null) { -+ this.head = next; -+ } else { -+ prev.next = next; -+ } -+ -+ if (next == null) { -+ this.tail = prev; -+ } else { -+ next.prev = prev; -+ } -+ } -+ -+ public boolean remove(final Link link) { -+ if (link.element == null) { -+ return false; -+ } -+ -+ this.removeNode(link); -+ return true; -+ } -+ -+ public boolean removeFirst(final E element) { -+ for (Link curr = this.head; curr != null; curr = curr.next) { -+ if (Objects.equals(element, curr.element)) { -+ this.removeNode(curr); -+ return true; -+ } -+ } -+ return false; -+ } -+ -+ public boolean removeLast(final E element) { -+ for (Link curr = this.tail; curr != null; curr = curr.prev) { -+ if (Objects.equals(element, curr.element)) { -+ this.removeNode(curr); -+ return true; -+ } -+ } -+ return false; -+ } -+ -+ @Override -+ public Iterator iterator() { -+ return new Iterator<>() { -+ private Link next = LinkedUnsortedList.this.head; -+ -+ @Override -+ public boolean hasNext() { -+ return this.next != null; -+ } -+ -+ @Override -+ public E next() { -+ final Link next = this.next; -+ if (next == null) { -+ throw new NoSuchElementException(); -+ } -+ this.next = next.next; -+ return next.element; -+ } -+ }; -+ } -+ -+ public E pollFirst() { -+ final Link head = this.head; -+ if (head == null) { -+ return null; -+ } -+ -+ final E ret = head.element; -+ final Link next = head.next; -+ -+ // unlink head -+ this.head = next; -+ if (next == null) { -+ this.tail = null; -+ } else { -+ next.prev = null; -+ } -+ -+ // help GC -+ head.element = null; -+ head.next = null; -+ -+ return ret; -+ } -+ -+ public E pollLast() { -+ final Link tail = this.tail; -+ if (tail == null) { -+ return null; -+ } -+ -+ final E ret = tail.element; -+ final Link prev = tail.prev; -+ -+ // unlink tail -+ this.tail = prev; -+ if (prev == null) { -+ this.head = null; -+ } else { -+ prev.next = null; -+ } -+ -+ // help GC -+ tail.element = null; -+ tail.prev = null; -+ -+ return ret; -+ } -+ -+ public Link addLast(final E element) { -+ final Link curr = this.tail; -+ if (curr != null) { -+ return this.tail = new Link<>(element, curr, null); -+ } else { -+ return this.head = this.tail = new Link<>(element); -+ } -+ } -+ -+ public Link addFirst(final E element) { -+ final Link curr = this.head; -+ if (curr != null) { -+ return this.head = new Link<>(element, null, curr); -+ } else { -+ return this.head = this.tail = new Link<>(element); -+ } -+ } -+ -+ public static final class Link { -+ private E element; -+ private Link prev; -+ private Link next; -+ -+ private Link(final E element) { -+ this.element = element; -+ } -+ -+ private Link(final E element, final Link prev, final Link next) { -+ this.element = element; -+ this.prev = prev; -+ this.next = next; -+ } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/util/ArrayUtil.java b/src/main/java/ca/spottedleaf/concurrentutil/util/ArrayUtil.java -deleted file mode 100644 -index ebb1ab06165addb173fea4d295001fe37f4e79d3..0000000000000000000000000000000000000000 ---- a/src/main/java/ca/spottedleaf/concurrentutil/util/ArrayUtil.java -+++ /dev/null -@@ -1,816 +0,0 @@ --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 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 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 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 getVolatile(final T[] array, final int index) { -- final Object ret = OBJECT_ARRAY_HANDLE.getVolatile((Object[])array, index); -- return (T)ret; -- } -- -- public static void setPlain(final T[] array, final int index, final T value) { -- OBJECT_ARRAY_HANDLE.set((Object[])array, index, (Object)value); -- } -- -- public static void setOpaque(final T[] array, final int index, final T value) { -- OBJECT_ARRAY_HANDLE.setOpaque((Object[])array, index, (Object)value); -- } -- -- public static void setRelease(final T[] array, final int index, final T value) { -- OBJECT_ARRAY_HANDLE.setRelease((Object[])array, index, (Object)value); -- } -- -- public static void setVolatile(final T[] array, final int index, final T value) { -- OBJECT_ARRAY_HANDLE.setVolatile((Object[])array, index, (Object)value); -- } -- -- public static 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 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 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 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 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/IntegerUtil.java b/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java -index 77699c5fa9681f9ec7aa05cbb50eb60828e193ab..9d7b9b8158cd01d12adbd7896ff77bee9828e101 100644 ---- a/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java -+++ b/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java -@@ -170,6 +170,26 @@ public final class IntegerUtil { - return (mask ^ val) - mask; // if val < 0, then (0 ^ val) - 0 else (-1 ^ val) + 1 - } - -+ // https://lemire.me/blog/2019/02/08/faster-remainders-when-the-divisor-is-a-constant-beating-compilers-and-libdivide -+ /** -+ * -+ * Usage: -+ *
    -+     * {@code
    -+     *     static final long mult = getSimpleMultiplier(divisor, bits);
    -+     *     long x = ...;
    -+     *     long magic = x * mult;
    -+     *     long divQ = magic >>> bits;
    -+     *     long divR = ((magic & ((1 << bits) - 1)) * divisor) >>> bits;
    -+     * }
    -+     * 
    -+ * -+ * @param bits The number of bits of precision for the returned result -+ */ -+ public static long getUnsignedDivisorMagic(final long divisor, final int bits) { -+ return (((1L << bits) - 1L) / divisor) + 1; -+ } -+ - private IntegerUtil() { - throw new RuntimeException(); - } -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/util/Priority.java b/src/main/java/ca/spottedleaf/concurrentutil/util/Priority.java -new file mode 100644 -index 0000000000000000000000000000000000000000..2919bbaa07b70f182438c3be8f9ebbe0649809b6 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/util/Priority.java -@@ -0,0 +1,145 @@ -+package ca.spottedleaf.concurrentutil.util; -+ -+public 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 Priority max(final Priority p1, final Priority p2) { -+ return p1.isHigherOrEqualPriority(p2) ? p1 : p2; -+ } -+ -+ // returns the lower priroity of the two -+ public static 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 Priority[] PRIORITIES = 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 Priority getPriority(final int priority) { -+ return PRIORITIES[priority + 1]; -+ } -+ -+ private static int priorityCounter; -+ -+ private static int nextCounter() { -+ return priorityCounter++; -+ } -+ -+ public final int priority; -+ -+ private Priority() { -+ this(nextCounter()); -+ } -+ -+ private Priority(final int priority) { -+ this.priority = priority; -+ } -+} -\ No newline at end of file diff --git a/patches/server/1043-Moonrise-optimisation-patches.patch b/patches/server/1038-Moonrise-optimisation-patches.patch similarity index 100% rename from patches/server/1043-Moonrise-optimisation-patches.patch rename to patches/server/1038-Moonrise-optimisation-patches.patch diff --git a/patches/server/1038-fixup-Paper-config-files.patch b/patches/server/1038-fixup-Paper-config-files.patch deleted file mode 100644 index a40bcad94711..000000000000 --- a/patches/server/1038-fixup-Paper-config-files.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Thu, 24 Oct 2024 08:11:12 -0700 -Subject: [PATCH] fixup! Paper config files - - -diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 450a1cc8f1624dce2daf52210d017e0732b1bdf7..4954ed9edf1e1f54cc164e48817eb5b75ea87ce0 100644 ---- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -+++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -31,6 +31,45 @@ public class GlobalConfiguration extends ConfigurationPart { - public static GlobalConfiguration get() { - return instance; - } -+ -+ public ChunkLoadingBasic chunkLoadingBasic; -+ -+ public class ChunkLoadingBasic extends ConfigurationPart { -+ @Comment("The maximum rate in chunks per second that the server will send to any individual player. Set to -1 to disable this limit.") -+ public double playerMaxChunkSendRate = 75.0; -+ -+ @Comment( -+ "The maximum rate at which chunks will load for any individual player. " + -+ "Note that this setting also affects chunk generations, since a chunk load is always first issued to test if a" + -+ "chunk is already generated. Set to -1 to disable this limit." -+ ) -+ public double playerMaxChunkLoadRate = 100.0; -+ -+ @Comment("The maximum rate at which chunks will generate for any individual player. Set to -1 to disable this limit.") -+ public double playerMaxChunkGenerateRate = -1.0; -+ } -+ -+ public ChunkLoadingAdvanced chunkLoadingAdvanced; -+ -+ public class ChunkLoadingAdvanced extends ConfigurationPart { -+ @Comment( -+ "Set to true if the server will match the chunk send radius that clients have configured" + -+ "in their view distance settings if the client is less-than the server's send distance." -+ ) -+ public boolean autoConfigSendDistance = true; -+ -+ @Comment( -+ "Specifies the maximum amount of concurrent chunk loads that an individual player can have." + -+ "Set to 0 to let the server configure it automatically per player, or set it to -1 to disable the limit." -+ ) -+ public int playerMaxConcurrentChunkLoads = 0; -+ -+ @Comment( -+ "Specifies the maximum amount of concurrent chunk generations that an individual player can have." + -+ "Set to 0 to let the server configure it automatically per player, or set it to -1 to disable the limit." -+ ) -+ public int playerMaxConcurrentChunkGenerates = 0; -+ } - static void set(GlobalConfiguration instance) { - GlobalConfiguration.instance = instance; - } -@@ -146,21 +185,6 @@ public class GlobalConfiguration extends ConfigurationPart { - public int incomingPacketThreshold = 300; - } - -- public ChunkLoading chunkLoading; -- -- public class ChunkLoading extends ConfigurationPart { -- public int minLoadRadius = 2; -- public int maxConcurrentSends = 2; -- public boolean autoconfigSendDistance = true; -- public double targetPlayerChunkSendRate = 100.0; -- public double globalMaxChunkSendRate = -1.0; -- public boolean enableFrustumPriority = false; -- public double globalMaxChunkLoadRate = -1.0; -- public double playerMaxConcurrentLoads = 20.0; -- public double globalMaxConcurrentLoads = 500.0; -- public double playerMaxChunkLoadRate = -1.0; -- } -- - public UnsupportedSettings unsupportedSettings; - - public class UnsupportedSettings extends ConfigurationPart { -@@ -219,7 +243,7 @@ public class GlobalConfiguration extends ConfigurationPart { - - @PostProcess - private void postProcess() { -- //io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.init(this); -+ - } - } - diff --git a/patches/server/1039-fixup-MC-Utils.patch b/patches/server/1039-fixup-MC-Utils.patch deleted file mode 100644 index b3d1e1136d03..000000000000 --- a/patches/server/1039-fixup-MC-Utils.patch +++ /dev/null @@ -1,1357 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Mon, 21 Oct 2024 12:21:54 -0700 -Subject: [PATCH] fixup! MC Utils - - -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java -new file mode 100644 -index 0000000000000000000000000000000000000000..6c98d420ea84c10ef4f15d4deb3f04e610ed8548 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java -@@ -0,0 +1,117 @@ -+package ca.spottedleaf.moonrise.common; -+ -+import com.mojang.datafixers.DSL; -+import com.mojang.datafixers.DataFixer; -+import net.minecraft.core.BlockPos; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.server.level.GenerationChunkHolder; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.level.BlockGetter; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.ProtoChunk; -+import net.minecraft.world.level.chunk.storage.SerializableChunkData; -+import net.minecraft.world.level.entity.EntityTypeTest; -+import net.minecraft.world.phys.AABB; -+import java.util.List; -+import java.util.ServiceLoader; -+import java.util.function.Predicate; -+ -+public interface PlatformHooks { -+ public static PlatformHooks get() { -+ return Holder.INSTANCE; -+ } -+ -+ public String getBrand(); -+ -+ public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos); -+ -+ public Predicate maybeHasLightEmission(); -+ -+ public boolean hasCurrentlyLoadingChunk(); -+ -+ public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder); -+ -+ public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk); -+ -+ public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original); -+ -+ public boolean allowAsyncTicketUpdates(); -+ -+ public void onChunkHolderTicketChange(final ServerLevel world, final ChunkHolder holder, final int oldLevel, final int newLevel); -+ -+ public void chunkUnloadFromWorld(final LevelChunk chunk); -+ -+ public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data); -+ -+ public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player); -+ -+ public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player); -+ -+ public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate predicate, -+ final List into); -+ -+ public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, -+ final AABB boundingBox, final Predicate predicate, -+ final List into, final int maxCount); -+ -+ public void entityMove(final Entity entity, final long oldSection, final long newSection); -+ -+ public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event); -+ -+ public boolean configFixMC224294(); -+ -+ public boolean configAutoConfigSendDistance(); -+ -+ public double configPlayerMaxLoadRate(); -+ -+ public double configPlayerMaxGenRate(); -+ -+ public double configPlayerMaxSendRate(); -+ -+ public int configPlayerMaxConcurrentLoads(); -+ -+ public int configPlayerMaxConcurrentGens(); -+ -+ public long configAutoSaveInterval(final ServerLevel world); -+ -+ public int configMaxAutoSavePerTick(final ServerLevel world); -+ -+ public boolean configFixMC159283(); -+ -+ // support for CB chunk mustNotSave -+ public boolean forceNoSave(final ChunkAccess chunk); -+ -+ public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt, -+ final int fromVersion, final int toVersion); -+ -+ public boolean hasMainChunkLoadHook(); -+ -+ public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData); -+ -+ public List modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List entities); -+ -+ public void unloadEntity(final Entity entity); -+ -+ public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk); -+ -+ public int modifyEntityTrackingRange(final Entity entity, final int currentRange); -+ -+ public static final class Holder { -+ private Holder() { -+ } -+ -+ private static final PlatformHooks INSTANCE; -+ -+ static { -+ INSTANCE = ServiceLoader.load(PlatformHooks.class, PlatformHooks.class.getClassLoader()).findFirst() -+ .orElseThrow(() -> new RuntimeException("Failed to locate PlatformHooks")); -+ } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java -index ba68998f6ef57b24c72fd833bd7de440de9501cc..7fed43a1e7bcf35c4d7fd3224837a47fedd59860 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java -@@ -13,15 +13,15 @@ import java.util.NoSuchElementException; - */ - public final class EntityList implements Iterable { - -- protected final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); -+ private final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); - { - this.entityToIndex.defaultReturnValue(Integer.MIN_VALUE); - } - -- protected static final Entity[] EMPTY_LIST = new Entity[0]; -+ private static final Entity[] EMPTY_LIST = new Entity[0]; - -- protected Entity[] entities = EMPTY_LIST; -- protected int count; -+ private Entity[] entities = EMPTY_LIST; -+ private int count; - - public int size() { - return this.count; -@@ -94,10 +94,9 @@ public final class EntityList implements Iterable { - - @Override - public Iterator iterator() { -- return new Iterator() { -- -- Entity lastRet; -- int current; -+ return new Iterator<>() { -+ private Entity lastRet; -+ private int current; - - @Override - public boolean hasNext() { -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java -deleted file mode 100644 -index fcfbca333234c09f7c056bbfcd9ac8860b20a8db..0000000000000000000000000000000000000000 ---- a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java -+++ /dev/null -@@ -1,125 +0,0 @@ --package ca.spottedleaf.moonrise.common.list; -- --import it.unimi.dsi.fastutil.longs.LongIterator; --import it.unimi.dsi.fastutil.shorts.Short2LongOpenHashMap; --import java.util.Arrays; --import net.minecraft.world.level.block.Block; --import net.minecraft.world.level.block.state.BlockState; --import net.minecraft.world.level.chunk.GlobalPalette; -- --public final class IBlockDataList { -- -- private static final GlobalPalette GLOBAL_PALETTE = new GlobalPalette<>(Block.BLOCK_STATE_REGISTRY); -- -- // map of location -> (index | (location << 16) | (palette id << 32)) -- private final Short2LongOpenHashMap map = new Short2LongOpenHashMap(2, 0.8f); -- { -- this.map.defaultReturnValue(Long.MAX_VALUE); -- } -- -- private static final long[] EMPTY_LIST = new long[0]; -- -- private long[] byIndex = EMPTY_LIST; -- private int size; -- -- public static int getLocationKey(final int x, final int y, final int z) { -- return (x & 15) | (((z & 15) << 4)) | ((y & 255) << (4 + 4)); -- } -- -- public static BlockState getBlockDataFromRaw(final long raw) { -- return GLOBAL_PALETTE.valueFor((int)(raw >>> 32)); -- } -- -- public static int getIndexFromRaw(final long raw) { -- return (int)(raw & 0xFFFF); -- } -- -- public static int getLocationFromRaw(final long raw) { -- return (int)((raw >>> 16) & 0xFFFF); -- } -- -- public static long getRawFromValues(final int index, final int location, final BlockState data) { -- return (long)index | ((long)location << 16) | (((long)GLOBAL_PALETTE.idFor(data)) << 32); -- } -- -- public static long setIndexRawValues(final long value, final int index) { -- return value & ~(0xFFFF) | (index); -- } -- -- public long add(final int x, final int y, final int z, final BlockState data) { -- return this.add(getLocationKey(x, y, z), data); -- } -- -- public long add(final int location, final BlockState data) { -- final long curr = this.map.get((short)location); -- -- if (curr == Long.MAX_VALUE) { -- final int index = this.size++; -- final long raw = getRawFromValues(index, location, data); -- this.map.put((short)location, raw); -- -- if (index >= this.byIndex.length) { -- this.byIndex = Arrays.copyOf(this.byIndex, (int)Math.max(4L, this.byIndex.length * 2L)); -- } -- -- this.byIndex[index] = raw; -- return raw; -- } else { -- final int index = getIndexFromRaw(curr); -- final long raw = this.byIndex[index] = getRawFromValues(index, location, data); -- -- this.map.put((short)location, raw); -- -- return raw; -- } -- } -- -- public long remove(final int x, final int y, final int z) { -- return this.remove(getLocationKey(x, y, z)); -- } -- -- public long remove(final int location) { -- final long ret = this.map.remove((short)location); -- final int index = getIndexFromRaw(ret); -- if (ret == Long.MAX_VALUE) { -- return ret; -- } -- -- // move the entry at the end to this index -- final int endIndex = --this.size; -- final long end = this.byIndex[endIndex]; -- if (index != endIndex) { -- // not empty after this call -- this.map.put((short)getLocationFromRaw(end), setIndexRawValues(end, index)); -- } -- this.byIndex[index] = end; -- this.byIndex[endIndex] = 0L; -- -- return ret; -- } -- -- public int size() { -- return this.size; -- } -- -- public long getRaw(final int index) { -- return this.byIndex[index]; -- } -- -- public int getLocation(final int index) { -- return getLocationFromRaw(this.getRaw(index)); -- } -- -- public BlockState getData(final int index) { -- return getBlockDataFromRaw(this.getRaw(index)); -- } -- -- public void clear() { -- this.size = 0; -- this.map.clear(); -- } -- -- public LongIterator getRawIterator() { -- return this.map.values().iterator(); -- } --} -\ No newline at end of file -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java -new file mode 100644 -index 0000000000000000000000000000000000000000..9f3b25bb2439f283f878db93973a02fcdcd14eed ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java -@@ -0,0 +1,77 @@ -+package ca.spottedleaf.moonrise.common.list; -+ -+import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; -+import java.util.Arrays; -+ -+public final class IntList { -+ -+ private final Int2IntOpenHashMap map = new Int2IntOpenHashMap(); -+ { -+ this.map.defaultReturnValue(Integer.MIN_VALUE); -+ } -+ -+ private static final int[] EMPTY_LIST = new int[0]; -+ -+ private int[] byIndex = EMPTY_LIST; -+ private int count; -+ -+ public int size() { -+ return this.count; -+ } -+ -+ public void setMinCapacity(final int len) { -+ final int[] byIndex = this.byIndex; -+ if (byIndex.length < len) { -+ this.byIndex = Arrays.copyOf(byIndex, len); -+ } -+ } -+ -+ public int getRaw(final int index) { -+ return this.byIndex[index]; -+ } -+ -+ public boolean add(final int value) { -+ final int count = this.count; -+ final int currIndex = this.map.putIfAbsent(value, count); -+ -+ if (currIndex != Integer.MIN_VALUE) { -+ return false; // already in this list -+ } -+ -+ int[] list = this.byIndex; -+ -+ if (list.length == count) { -+ // resize required -+ list = this.byIndex = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative -+ } -+ -+ list[count] = value; -+ this.count = count + 1; -+ -+ return true; -+ } -+ -+ public boolean remove(final int value) { -+ final int index = this.map.remove(value); -+ if (index == Integer.MIN_VALUE) { -+ return false; -+ } -+ -+ // move the entry at the end to this index -+ final int endIndex = --this.count; -+ final int end = this.byIndex[endIndex]; -+ if (index != endIndex) { -+ // not empty after this call -+ this.map.put(end, index); -+ } -+ this.byIndex[index] = end; -+ this.byIndex[endIndex] = 0; -+ -+ return true; -+ } -+ -+ public void clear() { -+ this.count = 0; -+ this.map.clear(); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java -new file mode 100644 -index 0000000000000000000000000000000000000000..2bae9949ef325d0001aa638150fbbdf968367e75 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java -@@ -0,0 +1,77 @@ -+package ca.spottedleaf.moonrise.common.list; -+ -+import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap; -+import java.util.Arrays; -+ -+public final class ShortList { -+ -+ private final Short2ShortOpenHashMap map = new Short2ShortOpenHashMap(); -+ { -+ this.map.defaultReturnValue(Short.MIN_VALUE); -+ } -+ -+ private static final short[] EMPTY_LIST = new short[0]; -+ -+ private short[] byIndex = EMPTY_LIST; -+ private short count; -+ -+ public int size() { -+ return (int)this.count; -+ } -+ -+ public short getRaw(final int index) { -+ return this.byIndex[index]; -+ } -+ -+ public void setMinCapacity(final int len) { -+ final short[] byIndex = this.byIndex; -+ if (byIndex.length < len) { -+ this.byIndex = Arrays.copyOf(byIndex, len); -+ } -+ } -+ -+ public boolean add(final short value) { -+ final int count = (int)this.count; -+ final short currIndex = this.map.putIfAbsent(value, (short)count); -+ -+ if (currIndex != Short.MIN_VALUE) { -+ return false; // already in this list -+ } -+ -+ short[] list = this.byIndex; -+ -+ if (list.length == count) { -+ // resize required -+ list = this.byIndex = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative -+ } -+ -+ list[count] = value; -+ this.count = (short)(count + 1); -+ -+ return true; -+ } -+ -+ public boolean remove(final short value) { -+ final short index = this.map.remove(value); -+ if (index == Short.MIN_VALUE) { -+ return false; -+ } -+ -+ // move the entry at the end to this index -+ final short endIndex = --this.count; -+ final short end = this.byIndex[endIndex]; -+ if (index != endIndex) { -+ // not empty after this call -+ this.map.put(end, index); -+ } -+ this.byIndex[(int)index] = end; -+ this.byIndex[(int)endIndex] = (short)0; -+ -+ return true; -+ } -+ -+ public void clear() { -+ this.count = (short)0; -+ this.map.clear(); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c2d917c2eac55b8a4411a6e159f177f9428b1150 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java -@@ -0,0 +1,22 @@ -+package ca.spottedleaf.moonrise.common.misc; -+ -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import java.lang.invoke.VarHandle; -+ -+public final class LazyRunnable implements Runnable { -+ -+ private volatile Runnable toRun; -+ private static final VarHandle TO_RUN_HANDLE = ConcurrentUtil.getVarHandle(LazyRunnable.class, "toRun", Runnable.class); -+ -+ public void setRunnable(final Runnable run) { -+ final Runnable prev = (Runnable)TO_RUN_HANDLE.compareAndExchange(this, (Runnable)null, run); -+ if (prev != null) { -+ throw new IllegalStateException("Runnable already set"); -+ } -+ } -+ -+ @Override -+ public void run() { -+ ((Runnable)TO_RUN_HANDLE.getVolatile(this)).run(); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java -index ab093b0e8ac6f762921eb1d15f5217345c4eba05..bb44de17a37082e57f2292a4f470740be1d09b11 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java -@@ -4,13 +4,17 @@ import ca.spottedleaf.moonrise.common.list.ReferenceList; - import ca.spottedleaf.moonrise.common.util.CoordinateUtils; - import ca.spottedleaf.moonrise.common.util.MoonriseConstants; - import ca.spottedleaf.moonrise.common.util.ChunkSystem; -+import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel; -+import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; - import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants; -+import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel; - import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; - import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; - import net.minecraft.core.BlockPos; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.server.level.ServerPlayer; - import net.minecraft.world.level.ChunkPos; -+import java.util.ArrayList; - - public final class NearbyPlayers { - -@@ -20,7 +24,27 @@ public final class NearbyPlayers { - GENERAL_REALLY_SMALL, - TICK_VIEW_DISTANCE, - VIEW_DISTANCE, -- SPAWN_RANGE, // Moonrise - chunk tick iteration -+ // Moonrise start - chunk tick iteration -+ SPAWN_RANGE { -+ @Override -+ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { -+ ((ChunkTickServerLevel)world).moonrise$addPlayerTickingRequest(chunkX, chunkZ); -+ } -+ -+ @Override -+ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { -+ ((ChunkTickServerLevel)world).moonrise$removePlayerTickingRequest(chunkX, chunkZ); -+ } -+ }; -+ // Moonrise end - chunk tick iteration -+ -+ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { -+ -+ } -+ -+ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) { -+ -+ } - } - - private static final NearbyMapType[] MAP_TYPES = NearbyMapType.values(); -@@ -37,6 +61,12 @@ public final class NearbyPlayers { - private final ServerLevel world; - private final Reference2ReferenceOpenHashMap players = new Reference2ReferenceOpenHashMap<>(); - private final Long2ReferenceOpenHashMap byChunk = new Long2ReferenceOpenHashMap<>(); -+ private final Long2ReferenceOpenHashMap>[] directByChunk = new Long2ReferenceOpenHashMap[TOTAL_MAP_TYPES]; -+ { -+ for (int i = 0; i < this.directByChunk.length; ++i) { -+ this.directByChunk[i] = new Long2ReferenceOpenHashMap<>(); -+ } -+ } - - public NearbyPlayers(final ServerLevel world) { - this.world = world; -@@ -70,6 +100,16 @@ public final class NearbyPlayers { - } - } - -+ public void clear() { -+ if (this.players.isEmpty()) { -+ return; -+ } -+ -+ for (final ServerPlayer player : new ArrayList<>(this.players.keySet())) { -+ this.removePlayer(player); -+ } -+ } -+ - public void tickPlayer(final ServerPlayer player) { - final TrackedPlayer[] players = this.players.get(player); - if (players == null) { -@@ -94,38 +134,41 @@ public final class NearbyPlayers { - return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); - } - -- public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { -- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -+ public TrackedChunk getChunk(final int chunkX, final int chunkZ) { -+ return this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ } - -- return chunk == null ? null : chunk.players[type.ordinal()]; -+ public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { -+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); - } - - public ReferenceList getPlayers(final ChunkPos pos, final NearbyMapType type) { -- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -- -- return chunk == null ? null : chunk.players[type.ordinal()]; -+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos)); - } - - public ReferenceList getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) { -- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -- -- return chunk == null ? null : chunk.players[type.ordinal()]; -+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); - } - - public ReferenceList getPlayersByBlock(final int blockX, final int blockZ, final NearbyMapType type) { -- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); -- -- return chunk == null ? null : chunk.players[type.ordinal()]; -+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); - } - - public static final class TrackedChunk { - - private static final ServerPlayer[] EMPTY_PLAYERS_ARRAY = new ServerPlayer[0]; - -+ private final long chunkKey; -+ private final NearbyPlayers nearbyPlayers; - private final ReferenceList[] players = new ReferenceList[TOTAL_MAP_TYPES]; - private int nonEmptyLists; - private long updateCount; - -+ public TrackedChunk(final long chunkKey, final NearbyPlayers nearbyPlayers) { -+ this.chunkKey = chunkKey; -+ this.nearbyPlayers = nearbyPlayers; -+ } -+ - public boolean isEmpty() { - return this.nonEmptyLists == 0; - } -@@ -145,7 +188,9 @@ public final class NearbyPlayers { - final ReferenceList list = this.players[idx]; - if (list == null) { - ++this.nonEmptyLists; -- (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)).add(player); -+ final ReferenceList players = (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)); -+ this.nearbyPlayers.directByChunk[idx].put(this.chunkKey, players); -+ players.add(player); - return; - } - -@@ -169,6 +214,7 @@ public final class NearbyPlayers { - - if (list.size() == 0) { - this.players[idx] = null; -+ this.nearbyPlayers.directByChunk[idx].remove(this.chunkKey); - --this.nonEmptyLists; - } - } -@@ -187,9 +233,19 @@ public final class NearbyPlayers { - protected void addCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { - final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); - -- NearbyPlayers.this.byChunk.computeIfAbsent(chunkKey, (final long keyInMap) -> { -- return new TrackedChunk(); -- }).addPlayer(parameter, this.type); -+ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey); -+ final NearbyMapType type = this.type; -+ if (chunk != null) { -+ chunk.addPlayer(parameter, type); -+ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); -+ } else { -+ final TrackedChunk created = new TrackedChunk(chunkKey, NearbyPlayers.this); -+ NearbyPlayers.this.byChunk.put(chunkKey, created); -+ created.addPlayer(parameter, type); -+ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ); -+ -+ ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$requestChunkData(chunkKey).nearbyPlayers = created; -+ } - } - - @Override -@@ -201,10 +257,16 @@ public final class NearbyPlayers { - throw new IllegalStateException("Chunk should exist at " + new ChunkPos(chunkKey)); - } - -- chunk.removePlayer(parameter, this.type); -+ final NearbyMapType type = this.type; -+ chunk.removePlayer(parameter, type); -+ type.removeFrom(parameter, NearbyPlayers.this.world, chunkX, chunkZ); - - if (chunk.isEmpty()) { - NearbyPlayers.this.byChunk.remove(chunkKey); -+ final ChunkData chunkData = ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$releaseChunkData(chunkKey); -+ if (chunkData != null) { -+ chunkData.nearbyPlayers = null; -+ } - } - } - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java -index efefd94b652228d877db5dbca8b28354ad42529f..90560769d09538f7a740753a41a3b8e017b0b92a 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java -@@ -2,6 +2,7 @@ package ca.spottedleaf.moonrise.common.misc; - - import ca.spottedleaf.concurrentutil.util.IntPairUtil; - import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; -+import it.unimi.dsi.fastutil.longs.LongSet; - import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; - import it.unimi.dsi.fastutil.objects.ReferenceSet; - -@@ -14,6 +15,10 @@ public final class PositionCountingAreaMap { - return this.counters.keySet(); - } - -+ public LongSet getPositions() { -+ return this.positions.keySet(); -+ } -+ - public int getTotalPositions() { - return this.positions.size(); - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -index da323a1105347d5cf4b946df10ded78a953236f2..94bba2b71918d79f54b3e28c35e76098ba0afd8c 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java -@@ -1,6 +1,7 @@ - package ca.spottedleaf.moonrise.common.util; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.util.Priority; -+import ca.spottedleaf.moonrise.common.PlatformHooks; - import com.mojang.logging.LogUtils; - import net.minecraft.server.level.ChunkHolder; - import net.minecraft.server.level.FullChunkStatus; -@@ -24,15 +25,15 @@ public final class ChunkSystem { - } - - public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) { -- scheduleChunkTask(level, chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); -+ scheduleChunkTask(level, chunkX, chunkZ, run, Priority.NORMAL); - } - -- public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) { -+ public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final 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 ChunkStatus toStatus, final boolean addTicket, final Priority priority, - final Consumer onComplete) { - if (gen) { - scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -@@ -59,7 +60,7 @@ public final class ChunkSystem { - - 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 onComplete) { -+ final boolean addTicket, final Priority priority, final Consumer onComplete) { - if (!org.bukkit.Bukkit.isPrimaryThread()) { - scheduleChunkTask(level, chunkX, chunkZ, () -> { - scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -@@ -113,13 +114,13 @@ public final class ChunkSystem { - } - loadCallback.accept(result.orElse(null)); - }, (final Runnable r) -> { -- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); -+ scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST); - }); - } - - public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ, - final FullChunkStatus toStatus, final boolean addTicket, -- final PrioritisedExecutor.Priority priority, final Consumer onComplete) { -+ final Priority priority, final Consumer onComplete) { - // This method goes unused until the chunk system rewrite - if (toStatus == FullChunkStatus.INACCESSIBLE) { - throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status"); -@@ -196,7 +197,7 @@ public final class ChunkSystem { - } - loadCallback.accept(result.orElse(null)); - }, (final Runnable r) -> { -- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); -+ scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST); - }); - } - -@@ -220,7 +221,10 @@ public final class ChunkSystem { - return getUpdatingChunkHolderCount(level) != 0; - } - -- public static boolean screenEntity(final ServerLevel level, final Entity entity) { -+ public static boolean screenEntity(final ServerLevel level, final Entity entity, final boolean fromDisk, final boolean event) { -+ if (!PlatformHooks.get().screenEntity(level, entity, fromDisk, event)) { -+ return false; -+ } - return true; - } - -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java -index ac6f284ee4469d16c5655328b2488d7612832353..97848869df61648fc415e4d39f409f433202c274 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java -@@ -3,8 +3,12 @@ package ca.spottedleaf.moonrise.common.util; - public final class MixinWorkarounds { - - // mixins tries to find the owner of the clone() method, which doesn't exist and NPEs -+ // https://github.com/FabricMC/Mixin/pull/147 - public static long[] clone(final long[] values) { - return values.clone(); - } - -+ public static byte[] clone(final byte[] values) { -+ return values.clone(); -+ } - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java -index 3abe0bd2a820352b85306d554bf14a4cf6123091..c125c70a68130be373acc989053a6c0e487be924 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java -@@ -1,45 +1,100 @@ - package ca.spottedleaf.moonrise.common.util; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool; -+import ca.spottedleaf.concurrentutil.executor.thread.PrioritisedThreadPool; -+import ca.spottedleaf.moonrise.common.PlatformHooks; - import org.slf4j.Logger; - import org.slf4j.LoggerFactory; --import java.io.File; -+import java.util.concurrent.TimeUnit; -+import java.util.concurrent.atomic.AtomicInteger; -+import java.util.function.Consumer; - - public final class MoonriseCommon { - - private static final Logger LOGGER = LoggerFactory.getLogger(MoonriseCommon.class); - -- // Paper start -- public static PrioritisedThreadPool WORKER_POOL; -- public static int WORKER_THREADS; -- public static void init(io.papermc.paper.configuration.GlobalConfiguration.ChunkSystem chunkSystem) { -- // Paper end -+ public static final PrioritisedThreadPool WORKER_POOL = new PrioritisedThreadPool( -+ new Consumer<>() { -+ private final AtomicInteger idGenerator = new AtomicInteger(); -+ -+ @Override -+ public void accept(Thread thread) { -+ thread.setDaemon(true); -+ thread.setName(PlatformHooks.get().getBrand() + " Common Worker #" + this.idGenerator.getAndIncrement()); -+ thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { -+ @Override -+ public void uncaughtException(final Thread thread, final Throwable throwable) { -+ LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); -+ } -+ }); -+ } -+ } -+ ); -+ public static final long WORKER_QUEUE_HOLD_TIME = (long)(20.0e6); // 20ms -+ public static final int CLIENT_DIVISION = 0; -+ public static final PrioritisedThreadPool.ExecutorGroup RENDER_EXECUTOR_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(CLIENT_DIVISION, 0); -+ public static final int SERVER_DIVISION = 1; -+ public static final PrioritisedThreadPool.ExecutorGroup PARALLEL_GEN_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); -+ public static final PrioritisedThreadPool.ExecutorGroup RADIUS_AWARE_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); -+ public static final PrioritisedThreadPool.ExecutorGroup LOAD_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); -+ -+ public static void adjustWorkerThreads(final int configWorkerThreads, final int configIoThreads) { - int defaultWorkerThreads = Runtime.getRuntime().availableProcessors() / 2; - if (defaultWorkerThreads <= 4) { - defaultWorkerThreads = defaultWorkerThreads <= 3 ? 1 : 2; - } else { - defaultWorkerThreads = defaultWorkerThreads / 2; - } -- defaultWorkerThreads = Integer.getInteger("Paper.WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); // Paper -+ defaultWorkerThreads = Integer.getInteger(PlatformHooks.get().getBrand() + ".WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); - -- int workerThreads = chunkSystem.workerThreads; // Paper -+ int workerThreads = configWorkerThreads; - - if (workerThreads <= 0) { - workerThreads = defaultWorkerThreads; - } - -- WORKER_POOL = new PrioritisedThreadPool( -- "Paper Worker Pool", workerThreads, // Paper -- (final Thread thread, final Integer id) -> { -- thread.setName("Paper Common Worker #" + id.intValue()); // Paper -+ final int ioThreads = Math.max(1, configIoThreads); -+ -+ WORKER_POOL.adjustThreadCount(workerThreads); -+ IO_POOL.adjustThreadCount(ioThreads); -+ -+ LOGGER.info(PlatformHooks.get().getBrand() + " is using " + workerThreads + " worker threads, " + ioThreads + " I/O threads"); -+ } -+ -+ public static final PrioritisedThreadPool IO_POOL = new PrioritisedThreadPool( -+ new Consumer<>() { -+ private final AtomicInteger idGenerator = new AtomicInteger(); -+ -+ @Override -+ public void accept(final Thread thread) { -+ thread.setDaemon(true); -+ thread.setName(PlatformHooks.get().getBrand() + " I/O Worker #" + this.idGenerator.getAndIncrement()); - thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { - @Override - public void uncaughtException(final Thread thread, final Throwable throwable) { - LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); - } - }); -- }, (long)(20.0e6)); // 20ms -- WORKER_THREADS = workerThreads; -+ } -+ } -+ ); -+ public static final long IO_QUEUE_HOLD_TIME = (long)(100.0e6); // 100ms -+ public static final PrioritisedThreadPool.ExecutorGroup CLIENT_PROFILER_IO_GROUP = IO_POOL.createExecutorGroup(CLIENT_DIVISION, 0); -+ public static final PrioritisedThreadPool.ExecutorGroup SERVER_REGION_IO_GROUP = IO_POOL.createExecutorGroup(SERVER_DIVISION, 0); -+ -+ public static void haltExecutors() { -+ MoonriseCommon.WORKER_POOL.shutdown(false); -+ LOGGER.info("Awaiting termination of worker pool for up to 60s..."); -+ if (!MoonriseCommon.WORKER_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { -+ LOGGER.error("Worker pool did not shut down in time!"); -+ MoonriseCommon.WORKER_POOL.halt(false); -+ } -+ -+ MoonriseCommon.IO_POOL.shutdown(false); -+ LOGGER.info("Awaiting termination of I/O pool for up to 60s..."); -+ if (!MoonriseCommon.IO_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { -+ LOGGER.error("I/O pool did not shut down in time!"); -+ MoonriseCommon.IO_POOL.halt(false); -+ } - } - - private MoonriseCommon() {} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java -index 1cf32d7d1bbc8a0a3f7cb9024c793f6744199f64..559c959aff3c9deef867b9e425fba3e2e669cac6 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java -@@ -1,8 +1,10 @@ - package ca.spottedleaf.moonrise.common.util; - -+import ca.spottedleaf.moonrise.common.PlatformHooks; -+ - public final class MoonriseConstants { - -- public static final int MAX_VIEW_DISTANCE = 32; -+ public static final int MAX_VIEW_DISTANCE = Integer.getInteger(PlatformHooks.get().getBrand() + ".MaxViewDistance", 32); - - private MoonriseConstants() {} - -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java b/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java -new file mode 100644 -index 0000000000000000000000000000000000000000..a9ff1c1a70faf4b7a64b265932f07a8b8f00c1ff ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java -@@ -0,0 +1,52 @@ -+package ca.spottedleaf.moonrise.common.util; -+ -+import net.minecraft.world.level.levelgen.LegacyRandomSource; -+ -+/** -+ * Avoid costly CAS of superclass -+ */ -+public final class SimpleRandom extends LegacyRandomSource { -+ -+ private static final long MULTIPLIER = 25214903917L; -+ private static final long ADDEND = 11L; -+ private static final int BITS = 48; -+ private static final long MASK = (1L << BITS) - 1; -+ -+ private long value; -+ -+ public SimpleRandom(final long seed) { -+ super(0L); -+ this.value = seed; -+ } -+ -+ @Override -+ public void setSeed(final long seed) { -+ this.value = (seed ^ MULTIPLIER) & MASK; -+ } -+ -+ private long advanceSeed() { -+ return this.value = ((this.value * MULTIPLIER) + ADDEND) & MASK; -+ } -+ -+ @Override -+ public int next(final int bits) { -+ return (int)(this.advanceSeed() >>> (BITS - bits)); -+ } -+ -+ @Override -+ public int nextInt() { -+ final long seed = this.advanceSeed(); -+ return (int)(seed >>> (BITS - Integer.SIZE)); -+ } -+ -+ @Override -+ public int nextInt(final int bound) { -+ if (bound <= 0) { -+ throw new IllegalArgumentException(); -+ } -+ -+ // https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ -+ final long value = this.advanceSeed() >>> (BITS - Integer.SIZE); -+ return (int)((value * (long)bound) >>> Integer.SIZE); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java -index 11b7f15755dde766140c29bedca456c80d53293f..217d1f908a36a5177ba3cbb80a33f73d4dab0fa0 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java -@@ -77,11 +77,15 @@ public class TickThread extends Thread { - } - - public TickThread(final Runnable run, final String name) { -- this(run, name, ID_GENERATOR.incrementAndGet()); -+ this(null, run, name); - } - -- private TickThread(final Runnable run, final String name, final int id) { -- super(run, name); -+ public TickThread(final ThreadGroup group, final Runnable run, final String name) { -+ this(group, run, name, ID_GENERATOR.incrementAndGet()); -+ } -+ -+ private TickThread(final ThreadGroup group, final Runnable run, final String name, final int id) { -+ super(group, run, name); - this.id = id; - } - -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java -index 561a1a3ff418393d0a0db58de91b336f4c33aa4e..efda2688ae1254a82ba7f6bf8bf597ef224cbb86 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java -@@ -8,13 +8,21 @@ public final class WorldUtil { - // min, max are inclusive - - public static int getMaxSection(final LevelHeightAccessor world) { -- return world.getMaxSectionY() - 1; // getMaxSection() is exclusive -+ return world.getMaxSectionY(); -+ } -+ -+ public static int getMaxSection(final Level world) { -+ return world.getMaxSectionY(); - } - - public static int getMinSection(final LevelHeightAccessor world) { - return world.getMinSectionY(); - } - -+ public static int getMinSection(final Level world) { -+ return world.getMinSectionY(); -+ } -+ - public static int getMaxLightSection(final LevelHeightAccessor world) { - return getMaxSection(world) + 1; - } -diff --git a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java -new file mode 100644 -index 0000000000000000000000000000000000000000..1aa6be257ce594d7a69fdff008cd29014a04fd75 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java -@@ -0,0 +1,209 @@ -+package ca.spottedleaf.moonrise.paper; -+ -+import ca.spottedleaf.moonrise.common.PlatformHooks; -+import com.mojang.datafixers.DSL; -+import com.mojang.datafixers.DataFixer; -+import com.mojang.serialization.Dynamic; -+import net.minecraft.core.BlockPos; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.nbt.NbtOps; -+import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.server.level.GenerationChunkHolder; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.level.BlockGetter; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.ProtoChunk; -+import net.minecraft.world.level.chunk.storage.SerializableChunkData; -+import net.minecraft.world.level.entity.EntityTypeTest; -+import net.minecraft.world.phys.AABB; -+import java.util.List; -+import java.util.function.Predicate; -+ -+public final class PaperHooks implements PlatformHooks { -+ -+ @Override -+ public String getBrand() { -+ return "Paper"; -+ } -+ -+ @Override -+ public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos) { -+ return blockState.getLightEmission(); -+ } -+ -+ @Override -+ public Predicate maybeHasLightEmission() { -+ return (final BlockState state) -> { -+ return state.getLightEmission() != 0; -+ }; -+ } -+ -+ @Override -+ public boolean hasCurrentlyLoadingChunk() { -+ return false; -+ } -+ -+ @Override -+ public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder) { -+ return null; -+ } -+ -+ @Override -+ public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk) { -+ -+ } -+ -+ @Override -+ public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original) { -+ -+ } -+ -+ @Override -+ public boolean allowAsyncTicketUpdates() { -+ return true; -+ } -+ -+ @Override -+ public void onChunkHolderTicketChange(final ServerLevel world, final ChunkHolder holder, final int oldLevel, final int newLevel) { -+ -+ } -+ -+ @Override -+ public void chunkUnloadFromWorld(final LevelChunk chunk) { -+ -+ } -+ -+ @Override -+ public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data) { -+ -+ } -+ -+ @Override -+ public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player) { -+ -+ } -+ -+ @Override -+ public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player) { -+ -+ } -+ -+ @Override -+ public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate predicate, final List into) { -+ -+ } -+ -+ @Override -+ public void addToGetEntities(final Level world, final EntityTypeTest entityTypeTest, final AABB boundingBox, final Predicate predicate, final List into, final int maxCount) { -+ -+ } -+ -+ @Override -+ public void entityMove(final Entity entity, final long oldSection, final long newSection) { -+ -+ } -+ -+ @Override -+ public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event) { -+ return true; -+ } -+ -+ @Override -+ public boolean configFixMC224294() { -+ return true; -+ } -+ -+ @Override -+ public boolean configAutoConfigSendDistance() { -+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.autoConfigSendDistance; -+ } -+ -+ @Override -+ public double configPlayerMaxLoadRate() { -+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkLoadRate; -+ } -+ -+ @Override -+ public double configPlayerMaxGenRate() { -+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkGenerateRate; -+ } -+ -+ @Override -+ public double configPlayerMaxSendRate() { -+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkSendRate; -+ } -+ -+ @Override -+ public int configPlayerMaxConcurrentLoads() { -+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkLoads; -+ } -+ -+ @Override -+ public int configPlayerMaxConcurrentGens() { -+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkGenerates; -+ } -+ -+ @Override -+ public long configAutoSaveInterval(final ServerLevel world) { -+ return world.paperConfig().chunks.autoSaveInterval.value(); -+ } -+ -+ @Override -+ public int configMaxAutoSavePerTick(final ServerLevel world) { -+ return world.paperConfig().chunks.maxAutoSaveChunksPerTick; -+ } -+ -+ @Override -+ public boolean configFixMC159283() { -+ return true; -+ } -+ -+ @Override -+ public boolean forceNoSave(final ChunkAccess chunk) { -+ return chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave; -+ } -+ -+ @Override -+ public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt, -+ final int fromVersion, final int toVersion) { -+ return (CompoundTag)dataFixer.update( -+ type, new Dynamic<>(NbtOps.INSTANCE, nbt), fromVersion, toVersion -+ ).getValue(); -+ } -+ -+ @Override -+ public boolean hasMainChunkLoadHook() { -+ return false; -+ } -+ -+ @Override -+ public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData) { -+ -+ } -+ -+ @Override -+ public List modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List entities) { -+ return entities; -+ } -+ -+ @Override -+ public void unloadEntity(final Entity entity) { -+ entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, org.bukkit.event.entity.EntityRemoveEvent.Cause.UNLOAD); -+ } -+ -+ @Override -+ public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) { -+ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities()); -+ } -+ -+ @Override -+ public int modifyEntityTrackingRange(final Entity entity, final int currentRange) { -+ return org.spigotmc.TrackingRange.getEntityTrackingRange(entity, currentRange); -+ } -+} -diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 4954ed9edf1e1f54cc164e48817eb5b75ea87ce0..8a0cb603cd4dbfa1839e0f4e1606876cbb373277 100644 ---- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -+++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -243,7 +243,7 @@ public class GlobalConfiguration extends ConfigurationPart { - - @PostProcess - private void postProcess() { -- -+ ca.spottedleaf.moonrise.common.util.MoonriseCommon.adjustWorkerThreads(this.workerThreads, this.ioThreads); - } - } - -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index c17824fa01c4682c2b97bb60bfa401a1a2ef9c12..878bd04b63f257cc625953e45b953beb06917107 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -271,7 +271,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - return true; - } - -- public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, -+ public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.util.Priority priority, - java.util.function.Consumer> onLoad) { - if (Thread.currentThread() != this.thread) { - this.getChunkSource().mainThreadProcessor.execute(() -> { -diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -index f18c2b85ed9541f646f157184221e333d0ae58bd..aff4c3d63a97d5bbde004a616f7e14fca59b5ab9 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -+++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -@@ -168,7 +168,7 @@ public class ChunkStatusTasks { - }, context.mainThreadExecutor()); - } - -- private static void postLoadProtoChunk(ServerLevel world, List entities) { -+ public static void postLoadProtoChunk(ServerLevel world, List entities) { // Paper - public - if (!entities.isEmpty()) { - // CraftBukkit start - these are spawned serialized (DefinedStructure) and we don't call an add event below at the moment due to ordering complexities - world.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(entities, world, EntitySpawnReason.LOAD).filter((entity) -> { -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 6baa313b8201ed23193d7885c85606b0899ade3c..5aa74c00a61282830d82359eae2b114e2a48b6d9 100644 ---- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java -+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java -@@ -94,15 +94,13 @@ public class PersistentEntitySectionManager implements A - private boolean addEntity(T entity, boolean existing) { - org.spigotmc.AsyncCatcher.catchOp("Entity add"); // Paper - // 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(); -- boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted); -- if ((!wasRemoved && entityCasted.isRemoved()) || !screened) { -- // removed by callback -- return false; -- } -+ // I don't want to know why this is a generic type. -+ Entity entityCasted = (Entity)entity; -+ boolean wasRemoved = entityCasted.isRemoved(); -+ boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted, existing, true); -+ if ((!wasRemoved && entityCasted.isRemoved()) || !screened) { -+ // removed by callback -+ return false; - } - // Paper end - chunk system hooks - if (!this.addEntityUuid(entity)) { -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index b2eb8cf1de3b4b81587531bb4c0d4b512f5d5d5d..6dc3fc701d1e16a51d99f934ea3dc192363a6762 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2466,11 +2466,11 @@ public class CraftWorld extends CraftRegionAccessor implements World { - } - } - -- ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority; -+ ca.spottedleaf.concurrentutil.util.Priority priority; - if (urgent) { -- priority = ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER; -+ priority = ca.spottedleaf.concurrentutil.util.Priority.HIGHER; - } else { -- priority = ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL; -+ priority = ca.spottedleaf.concurrentutil.util.Priority.NORMAL; - } - - java.util.concurrent.CompletableFuture ret = new java.util.concurrent.CompletableFuture<>(); -diff --git a/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks b/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks -new file mode 100644 -index 0000000000000000000000000000000000000000..e57c3ca79677b1dfe7cf3db36f0406de7ea5bd0a ---- /dev/null -+++ b/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks -@@ -0,0 +1 @@ -+ca.spottedleaf.moonrise.paper.PaperHooks diff --git a/patches/server/1041-fixup-Optimize-BlockPosition-helper-methods.patch b/patches/server/1041-fixup-Optimize-BlockPosition-helper-methods.patch deleted file mode 100644 index 061b6c4ffe8d..000000000000 --- a/patches/server/1041-fixup-Optimize-BlockPosition-helper-methods.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Mon, 21 Oct 2024 19:13:43 -0700 -Subject: [PATCH] fixup! Optimize BlockPosition helper methods - - -diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java -index a5dab9b1652ac76372d88316e2c165eed6317891..f58a94efafbc01d402cd03a108bb90f60930a316 100644 ---- a/src/main/java/net/minecraft/core/BlockPos.java -+++ b/src/main/java/net/minecraft/core/BlockPos.java -@@ -162,7 +162,7 @@ public class BlockPos extends Vec3i { - - @Override - public BlockPos above(int distance) { -- return distance == 0 ? this : new BlockPos(this.getX(), this.getY() + distance, this.getZ()); // Paper - Perf: Optimize BlockPosition -+ return distance == 0 ? this.immutable() : new BlockPos(this.getX(), this.getY() + distance, this.getZ()); // Paper - Perf: Optimize BlockPosition - } - - @Override -@@ -172,7 +172,7 @@ public class BlockPos extends Vec3i { - - @Override - public BlockPos below(int i) { -- return i == 0 ? this : new BlockPos(this.getX(), this.getY() - i, this.getZ()); // Paper - Perf: Optimize BlockPosition -+ return i == 0 ? this.immutable() : new BlockPos(this.getX(), this.getY() - i, this.getZ()); // Paper - Perf: Optimize BlockPosition - } - - @Override -@@ -182,7 +182,7 @@ public class BlockPos extends Vec3i { - - @Override - public BlockPos north(int distance) { -- return distance == 0 ? this : new BlockPos(this.getX(), this.getY(), this.getZ() - distance); // Paper - Perf: Optimize BlockPosition -+ return distance == 0 ? this.immutable() : new BlockPos(this.getX(), this.getY(), this.getZ() - distance); // Paper - Perf: Optimize BlockPosition - } - - @Override -@@ -192,7 +192,7 @@ public class BlockPos extends Vec3i { - - @Override - public BlockPos south(int distance) { -- return distance == 0 ? this : new BlockPos(this.getX(), this.getY(), this.getZ() + distance); // Paper - Perf: Optimize BlockPosition -+ return distance == 0 ? this.immutable() : new BlockPos(this.getX(), this.getY(), this.getZ() + distance); // Paper - Perf: Optimize BlockPosition - } - - @Override -@@ -202,7 +202,7 @@ public class BlockPos extends Vec3i { - - @Override - public BlockPos west(int distance) { -- return distance == 0 ? this : new BlockPos(this.getX() - distance, this.getY(), this.getZ()); // Paper - Perf: Optimize BlockPosition -+ return distance == 0 ? this.immutable() : new BlockPos(this.getX() - distance, this.getY(), this.getZ()); // Paper - Perf: Optimize BlockPosition - } - - @Override -@@ -212,7 +212,7 @@ public class BlockPos extends Vec3i { - - @Override - public BlockPos east(int distance) { -- return distance == 0 ? this : new BlockPos(this.getX() + distance, this.getY(), this.getZ()); // Paper - Perf: Optimize BlockPosition -+ return distance == 0 ? this.immutable() : new BlockPos(this.getX() + distance, this.getY(), this.getZ()); // Paper - Perf: Optimize BlockPosition - } - - @Override diff --git a/patches/server/1042-fixup-More-Teleport-API.patch b/patches/server/1042-fixup-More-Teleport-API.patch deleted file mode 100644 index 9ef4eadd58e2..000000000000 --- a/patches/server/1042-fixup-More-Teleport-API.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Thu, 24 Oct 2024 11:13:42 -0700 -Subject: [PATCH] fixup! More Teleport API - - -diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 64c6f54cc4d0c22bc972b808cb92925cc7526db2..179886dcbda29c5cdb7dbd43e44951ae38d9df96 100644 ---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1064,7 +1064,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { - java.util.concurrent.CompletableFuture 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) -> { -+ this instanceof CraftPlayer ? ca.spottedleaf.concurrentutil.util.Priority.HIGHER : ca.spottedleaf.concurrentutil.util.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()); From 2e76d3f1e200c567e62337e0d50ddcb01e3ea895 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Fri, 25 Oct 2024 12:47:24 -0700 Subject: [PATCH 077/119] Specify mainCapabilityAttribute for paper-api --- build.gradle.kts | 2 +- patches/api/0465-Brigadier-based-command-API.patch | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9f0522ccbd4d..20ab99b72be3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,7 @@ import kotlin.io.path.* plugins { java `maven-publish` - id("io.papermc.paperweight.core") version "1.7.3" + id("io.papermc.paperweight.core") version "1.7.4" } allprojects { diff --git a/patches/api/0465-Brigadier-based-command-API.patch b/patches/api/0465-Brigadier-based-command-API.patch index 069f7c4c4a58..2d29373bc2b2 100644 --- a/patches/api/0465-Brigadier-based-command-API.patch +++ b/patches/api/0465-Brigadier-based-command-API.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Brigadier based command API Co-authored-by: Jake Potrebic diff --git a/build.gradle.kts b/build.gradle.kts -index 6c8464d9e862b1b4dbf7a77e25446aa870803dae..e7c96be769fde8375b9a1b128cc7ce474144d16d 100644 +index 6c8464d9e862b1b4dbf7a77e25446aa870803dae..254fd96d3950b4494c7e43547b00b5175ee53c93 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -27,6 +27,7 @@ configurations.api { @@ -17,18 +17,22 @@ index 6c8464d9e862b1b4dbf7a77e25446aa870803dae..e7c96be769fde8375b9a1b128cc7ce47 // api dependencies are listed transitively to API consumers api("com.google.guava:guava:32.1.2-jre") api("com.google.code.gson:gson:2.10.1") -@@ -93,9 +94,29 @@ sourceSets { +@@ -93,9 +94,33 @@ sourceSets { } } // Paper end +// Paper start - brigadier API +val outgoingVariants = arrayOf("runtimeElements", "apiElements", "sourcesElements", "javadocElements") ++val mainCapability = "${project.group}:${project.name}:${project.version}" +configurations { + val outgoing = outgoingVariants.map { named(it) } + for (config in outgoing) { + config { ++ attributes { ++ attribute(io.papermc.paperweight.util.mainCapabilityAttribute, mainCapability) ++ } + outgoing { -+ capability("${project.group}:${project.name}:${project.version}") ++ capability(mainCapability) + capability("io.papermc.paper:paper-mojangapi:${project.version}") + capability("com.destroystokyo.paper:paper-mojangapi:${project.version}") + } From e4efb590e49d30c9abe606838572aa5b4e9b5572 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 25 Oct 2024 12:47:52 -0700 Subject: [PATCH 078/119] fix compile issues --- ...tch => 0400-Add-PlayerFailMoveEvent.patch} | 0 ...-custom-statistic-criteria-creation.patch} | 0 ...tch => 0402-SculkCatalyst-bloom-API.patch} | 0 ...API-for-an-entity-s-scoreboard-name.patch} | 0 ...lace-methods-with-old-StructureType.patch} | 4 ++-- ... => 0405-Add-Listing-API-for-Player.patch} | 0 ...d-BlockFace-during-BlockDamageEvent.patch} | 0 ...h => 0407-Fix-NPE-on-Boat-getStatus.patch} | 0 ...e-API.patch => 0408-Expand-Pose-API.patch} | 0 ...MerchantRecipe-add-copy-constructor.patch} | 0 ...patch => 0410-More-DragonBattle-API.patch} | 0 ...tch => 0411-Add-PlayerPickItemEvent.patch} | 0 ...=> 0412-Allow-trident-custom-damage.patch} | 0 ...pose-hand-during-BlockCanBuildEvent.patch} | 0 ...t-setBurnTime-to-valid-short-values.patch} | 0 ... 0415-Add-OfflinePlayer-isConnected.patch} | 0 ...titleOverride-to-InventoryOpenEvent.patch} | 0 ...roper-checking-of-empty-item-stacks.patch} | 0 ...dItemsEvent-throwing-exception-when.patch} | 0 ...> 0419-Add-player-idle-duration-API.patch} | 0 ...e-collision-shape-of-a-block-before.patch} | 0 ...redicate-for-blocks-when-raytracing.patch} | 0 ...h-event-for-all-player-interactions.patch} | 0 ...Attribute-Modifier-API-improvements.patch} | 0 ... => 0424-Expand-LingeringPotion-API.patch} | 0 ...y-durability-check-in-ItemStack-isS.patch} | 0 ...tch => 0426-Add-Structure-check-API.patch} | 0 ...427-Experimental-annotations-change.patch} | 0 ...tch => 0428-Add-more-scoreboard-API.patch} | 0 ...stry.patch => 0429-Improve-Registry.patch} | 0 ...h => 0430-Add-experience-points-API.patch} | 0 ...h => 0431-Add-missing-InventoryType.patch} | 0 ...h => 0432-Add-drops-to-shear-events.patch} | 0 ... => 0433-Add-HiddenPotionEffect-API.patch} | 0 ...> 0434-Add-PlayerShieldDisableEvent.patch} | 0 ...mpty-String-in-NamespacedKey.fromSt.patch} | 0 ...-Add-BlockStateMeta-clearBlockState.patch} | 0 ...37-Expose-LootTable-of-DecoratedPot.patch} | 0 ...h => 0438-Add-ShulkerDuplicateEvent.patch} | 0 ...dd-api-for-spawn-egg-texture-colors.patch} | 0 ... => 0440-Add-Lifecycle-Event-system.patch} | 0 ...patch => 0441-ItemStack-Tooltip-API.patch} | 0 ...Snapshot-includeLightData-parameter.patch} | 0 ...PI.patch => 0443-Add-FluidState-API.patch} | 0 ...patch => 0444-add-number-format-api.patch} | 0 ...patch => 0445-improve-BanList-types.patch} | 8 ++++---- ...=> 0446-Suspicious-Effect-Entry-API.patch} | 0 ....patch => 0447-Fix-DamageSource-API.patch} | 0 ...I.patch => 0448-Expanded-Hopper-API.patch} | 0 ...tables-to-prevent-unexpected-issues.patch} | 0 ...0-Add-BlockBreakProgressUpdateEvent.patch} | 0 ...=> 0451-Deprecate-ItemStack-setType.patch} | 0 ...s.patch => 0452-Item-Mutation-Fixes.patch} | 0 ...> 0453-API-for-checking-sent-chunks.patch} | 0 ...ch => 0454-Add-CartographyItemEvent.patch} | 0 ...aid-API.patch => 0455-More-Raid-API.patch} | 0 ...0456-Fix-SpawnerEntry-Equipment-API.patch} | 0 ...emFlags.patch => 0457-Fix-ItemFlags.patch} | 0 ...ifying-library-loader-jars-bytecode.patch} | 0 ...0459-Add-hook-to-remap-library-jars.patch} | 0 ...=> 0460-Add-GameMode-isInvulnerable.patch} | 0 ...61-Expose-hasColor-to-leather-armor.patch} | 0 ...-API-to-get-player-ha-proxy-address.patch} | 0 ....patch => 0463-More-Chest-Block-API.patch} | 0 ...=> 0464-Brigadier-based-command-API.patch} | 0 ... => 0465-Fix-issues-with-recipe-API.patch} | 0 ...66-Fix-equipment-slot-and-group-API.patch} | 0 ...lugin-to-use-Paper-PluginLoader-API.patch} | 0 ...atch => 0468-General-ItemMeta-fixes.patch} | 0 ...469-Add-missing-fishing-event-state.patch} | 0 ...ate-InvAction-HOTBAR_MOVE_AND_READD.patch} | 0 ...h => 0471-Registry-Modification-API.patch} | 0 ...troduce-registry-entry-and-builders.patch} | 0 ...3-Proxy-ItemStack-to-CraftItemStack.patch} | 0 ...-accessible-directly-from-ItemStack.patch} | 0 ...h => 0475-Fix-HelpCommand-searching.patch} | 0 ...atch => 0476-add-Plugin-getDataPath.patch} | 0 ...0477-Fix-PickupStatus-getting-reset.patch} | 0 ...anPlaceOn-and-CanDestroy-NBT-values.patch} | 0 ...tandardMessenger-exception-messages.patch} | 0 ... 0480-Add-even-more-Enchantment-API.patch} | 0 ...ble-API.patch => 0481-Leashable-API.patch} | 0 ...482-Add-enchantment-seed-update-API.patch} | 0 ...removal-all-OldEnum-related-methods.patch} | 0 ...I.patch => 0484-Add-FeatureFlag-API.patch} | 0 ....patch => 0485-Tag-Lifecycle-Events.patch} | 0 ... => 0486-Item-serialization-as-json.patch} | 0 ...487-create-TileStateInventoryHolder.patch} | 0 ...evels-with-enchantment-registry-set.patch} | 0 ...h => 0489-Improve-entity-effect-API.patch} | 0 ...me.patch => 0490-Add-recipeBrewTime.patch} | 0 ...91-Add-PlayerInsertLecternBookEvent.patch} | 0 ... 0492-Void-damage-configuration-API.patch} | 0 ...I.patch => 0493-Add-Offline-PDC-API.patch} | 0 ...w-bypassEnchantmentLevelRestriction.patch} | 0 ...removing-recipes-from-RecipeIterator.patch | 8 +++----- .../1039-API-for-checking-sent-chunks.patch} | 19 ++----------------- ...040-Fix-CraftWorld-isChunkGenerated.patch} | 6 +++--- ...-API-for-updating-recipes-on-clients.patch | 0 99 files changed, 14 insertions(+), 31 deletions(-) rename patches/api/{0401-Add-PlayerFailMoveEvent.patch => 0400-Add-PlayerFailMoveEvent.patch} (100%) rename patches/api/{0402-Fix-custom-statistic-criteria-creation.patch => 0401-Fix-custom-statistic-criteria-creation.patch} (100%) rename patches/api/{0403-SculkCatalyst-bloom-API.patch => 0402-SculkCatalyst-bloom-API.patch} (100%) rename patches/api/{0404-API-for-an-entity-s-scoreboard-name.patch => 0403-API-for-an-entity-s-scoreboard-name.patch} (100%) rename patches/api/{0405-Deprecate-and-replace-methods-with-old-StructureType.patch => 0404-Deprecate-and-replace-methods-with-old-StructureType.patch} (97%) rename patches/api/{0406-Add-Listing-API-for-Player.patch => 0405-Add-Listing-API-for-Player.patch} (100%) rename patches/api/{0407-Expose-clicked-BlockFace-during-BlockDamageEvent.patch => 0406-Expose-clicked-BlockFace-during-BlockDamageEvent.patch} (100%) rename patches/api/{0408-Fix-NPE-on-Boat-getStatus.patch => 0407-Fix-NPE-on-Boat-getStatus.patch} (100%) rename patches/api/{0409-Expand-Pose-API.patch => 0408-Expand-Pose-API.patch} (100%) rename patches/api/{0410-MerchantRecipe-add-copy-constructor.patch => 0409-MerchantRecipe-add-copy-constructor.patch} (100%) rename patches/api/{0411-More-DragonBattle-API.patch => 0410-More-DragonBattle-API.patch} (100%) rename patches/api/{0412-Add-PlayerPickItemEvent.patch => 0411-Add-PlayerPickItemEvent.patch} (100%) rename patches/api/{0413-Allow-trident-custom-damage.patch => 0412-Allow-trident-custom-damage.patch} (100%) rename patches/api/{0414-Expose-hand-during-BlockCanBuildEvent.patch => 0413-Expose-hand-during-BlockCanBuildEvent.patch} (100%) rename patches/api/{0415-Limit-setBurnTime-to-valid-short-values.patch => 0414-Limit-setBurnTime-to-valid-short-values.patch} (100%) rename patches/api/{0416-Add-OfflinePlayer-isConnected.patch => 0415-Add-OfflinePlayer-isConnected.patch} (100%) rename patches/api/{0417-Add-titleOverride-to-InventoryOpenEvent.patch => 0416-Add-titleOverride-to-InventoryOpenEvent.patch} (100%) rename patches/api/{0418-Allow-proper-checking-of-empty-item-stacks.patch => 0417-Allow-proper-checking-of-empty-item-stacks.patch} (100%) rename patches/api/{0419-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch => 0418-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch} (100%) rename patches/api/{0420-Add-player-idle-duration-API.patch => 0419-Add-player-idle-duration-API.patch} (100%) rename patches/api/{0421-Add-API-to-get-the-collision-shape-of-a-block-before.patch => 0420-Add-API-to-get-the-collision-shape-of-a-block-before.patch} (100%) rename patches/api/{0422-Add-predicate-for-blocks-when-raytracing.patch => 0421-Add-predicate-for-blocks-when-raytracing.patch} (100%) rename patches/api/{0423-Add-hand-to-fish-event-for-all-player-interactions.patch => 0422-Add-hand-to-fish-event-for-all-player-interactions.patch} (100%) rename patches/api/{0424-Attribute-Modifier-API-improvements.patch => 0423-Attribute-Modifier-API-improvements.patch} (100%) rename patches/api/{0425-Expand-LingeringPotion-API.patch => 0424-Expand-LingeringPotion-API.patch} (100%) rename patches/api/{0426-Remove-unnecessary-durability-check-in-ItemStack-isS.patch => 0425-Remove-unnecessary-durability-check-in-ItemStack-isS.patch} (100%) rename patches/api/{0427-Add-Structure-check-API.patch => 0426-Add-Structure-check-API.patch} (100%) rename patches/api/{0428-Experimental-annotations-change.patch => 0427-Experimental-annotations-change.patch} (100%) rename patches/api/{0429-Add-more-scoreboard-API.patch => 0428-Add-more-scoreboard-API.patch} (100%) rename patches/api/{0430-Improve-Registry.patch => 0429-Improve-Registry.patch} (100%) rename patches/api/{0431-Add-experience-points-API.patch => 0430-Add-experience-points-API.patch} (100%) rename patches/api/{0432-Add-missing-InventoryType.patch => 0431-Add-missing-InventoryType.patch} (100%) rename patches/api/{0433-Add-drops-to-shear-events.patch => 0432-Add-drops-to-shear-events.patch} (100%) rename patches/api/{0434-Add-HiddenPotionEffect-API.patch => 0433-Add-HiddenPotionEffect-API.patch} (100%) rename patches/api/{0435-Add-PlayerShieldDisableEvent.patch => 0434-Add-PlayerShieldDisableEvent.patch} (100%) rename patches/api/{0436-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch => 0435-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch} (100%) rename patches/api/{0437-Add-BlockStateMeta-clearBlockState.patch => 0436-Add-BlockStateMeta-clearBlockState.patch} (100%) rename patches/api/{0438-Expose-LootTable-of-DecoratedPot.patch => 0437-Expose-LootTable-of-DecoratedPot.patch} (100%) rename patches/api/{0439-Add-ShulkerDuplicateEvent.patch => 0438-Add-ShulkerDuplicateEvent.patch} (100%) rename patches/api/{0440-Add-api-for-spawn-egg-texture-colors.patch => 0439-Add-api-for-spawn-egg-texture-colors.patch} (100%) rename patches/api/{0441-Add-Lifecycle-Event-system.patch => 0440-Add-Lifecycle-Event-system.patch} (100%) rename patches/api/{0442-ItemStack-Tooltip-API.patch => 0441-ItemStack-Tooltip-API.patch} (100%) rename patches/api/{0443-Add-getChunkSnapshot-includeLightData-parameter.patch => 0442-Add-getChunkSnapshot-includeLightData-parameter.patch} (100%) rename patches/api/{0444-Add-FluidState-API.patch => 0443-Add-FluidState-API.patch} (100%) rename patches/api/{0445-add-number-format-api.patch => 0444-add-number-format-api.patch} (100%) rename patches/api/{0446-improve-BanList-types.patch => 0445-improve-BanList-types.patch} (94%) rename patches/api/{0447-Suspicious-Effect-Entry-API.patch => 0446-Suspicious-Effect-Entry-API.patch} (100%) rename patches/api/{0448-Fix-DamageSource-API.patch => 0447-Fix-DamageSource-API.patch} (100%) rename patches/api/{0449-Expanded-Hopper-API.patch => 0448-Expanded-Hopper-API.patch} (100%) rename patches/api/{0450-Clone-mutables-to-prevent-unexpected-issues.patch => 0449-Clone-mutables-to-prevent-unexpected-issues.patch} (100%) rename patches/api/{0451-Add-BlockBreakProgressUpdateEvent.patch => 0450-Add-BlockBreakProgressUpdateEvent.patch} (100%) rename patches/api/{0452-Deprecate-ItemStack-setType.patch => 0451-Deprecate-ItemStack-setType.patch} (100%) rename patches/api/{0453-Item-Mutation-Fixes.patch => 0452-Item-Mutation-Fixes.patch} (100%) rename patches/api/{0454-API-for-checking-sent-chunks.patch => 0453-API-for-checking-sent-chunks.patch} (100%) rename patches/api/{0455-Add-CartographyItemEvent.patch => 0454-Add-CartographyItemEvent.patch} (100%) rename patches/api/{0456-More-Raid-API.patch => 0455-More-Raid-API.patch} (100%) rename patches/api/{0457-Fix-SpawnerEntry-Equipment-API.patch => 0456-Fix-SpawnerEntry-Equipment-API.patch} (100%) rename patches/api/{0458-Fix-ItemFlags.patch => 0457-Fix-ItemFlags.patch} (100%) rename patches/api/{0459-Allow-modifying-library-loader-jars-bytecode.patch => 0458-Allow-modifying-library-loader-jars-bytecode.patch} (100%) rename patches/api/{0460-Add-hook-to-remap-library-jars.patch => 0459-Add-hook-to-remap-library-jars.patch} (100%) rename patches/api/{0461-Add-GameMode-isInvulnerable.patch => 0460-Add-GameMode-isInvulnerable.patch} (100%) rename patches/api/{0462-Expose-hasColor-to-leather-armor.patch => 0461-Expose-hasColor-to-leather-armor.patch} (100%) rename patches/api/{0463-Added-API-to-get-player-ha-proxy-address.patch => 0462-Added-API-to-get-player-ha-proxy-address.patch} (100%) rename patches/api/{0464-More-Chest-Block-API.patch => 0463-More-Chest-Block-API.patch} (100%) rename patches/api/{0465-Brigadier-based-command-API.patch => 0464-Brigadier-based-command-API.patch} (100%) rename patches/api/{0466-Fix-issues-with-recipe-API.patch => 0465-Fix-issues-with-recipe-API.patch} (100%) rename patches/api/{0467-Fix-equipment-slot-and-group-API.patch => 0466-Fix-equipment-slot-and-group-API.patch} (100%) rename patches/api/{0468-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch => 0467-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch} (100%) rename patches/api/{0469-General-ItemMeta-fixes.patch => 0468-General-ItemMeta-fixes.patch} (100%) rename patches/api/{0470-Add-missing-fishing-event-state.patch => 0469-Add-missing-fishing-event-state.patch} (100%) rename patches/api/{0471-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch => 0470-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch} (100%) rename patches/api/{0472-Registry-Modification-API.patch => 0471-Registry-Modification-API.patch} (100%) rename patches/api/{0473-Introduce-registry-entry-and-builders.patch => 0472-Introduce-registry-entry-and-builders.patch} (100%) rename patches/api/{0474-Proxy-ItemStack-to-CraftItemStack.patch => 0473-Proxy-ItemStack-to-CraftItemStack.patch} (100%) rename patches/api/{0475-Make-a-PDC-view-accessible-directly-from-ItemStack.patch => 0474-Make-a-PDC-view-accessible-directly-from-ItemStack.patch} (100%) rename patches/api/{0476-Fix-HelpCommand-searching.patch => 0475-Fix-HelpCommand-searching.patch} (100%) rename patches/api/{0477-add-Plugin-getDataPath.patch => 0476-add-Plugin-getDataPath.patch} (100%) rename patches/api/{0478-Fix-PickupStatus-getting-reset.patch => 0477-Fix-PickupStatus-getting-reset.patch} (100%) rename patches/api/{0479-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch => 0478-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch} (100%) rename patches/api/{0480-Improve-StandardMessenger-exception-messages.patch => 0479-Improve-StandardMessenger-exception-messages.patch} (100%) rename patches/api/{0481-Add-even-more-Enchantment-API.patch => 0480-Add-even-more-Enchantment-API.patch} (100%) rename patches/api/{0482-Leashable-API.patch => 0481-Leashable-API.patch} (100%) rename patches/api/{0483-Add-enchantment-seed-update-API.patch => 0482-Add-enchantment-seed-update-API.patch} (100%) rename patches/api/{0484-Deprecate-for-removal-all-OldEnum-related-methods.patch => 0483-Deprecate-for-removal-all-OldEnum-related-methods.patch} (100%) rename patches/api/{0485-Add-FeatureFlag-API.patch => 0484-Add-FeatureFlag-API.patch} (100%) rename patches/api/{0486-Tag-Lifecycle-Events.patch => 0485-Tag-Lifecycle-Events.patch} (100%) rename patches/api/{0487-Item-serialization-as-json.patch => 0486-Item-serialization-as-json.patch} (100%) rename patches/api/{0488-create-TileStateInventoryHolder.patch => 0487-create-TileStateInventoryHolder.patch} (100%) rename patches/api/{0489-Add-enchantWithLevels-with-enchantment-registry-set.patch => 0488-Add-enchantWithLevels-with-enchantment-registry-set.patch} (100%) rename patches/api/{0490-Improve-entity-effect-API.patch => 0489-Improve-entity-effect-API.patch} (100%) rename patches/api/{0491-Add-recipeBrewTime.patch => 0490-Add-recipeBrewTime.patch} (100%) rename patches/api/{0492-Add-PlayerInsertLecternBookEvent.patch => 0491-Add-PlayerInsertLecternBookEvent.patch} (100%) rename patches/api/{0493-Void-damage-configuration-API.patch => 0492-Void-damage-configuration-API.patch} (100%) rename patches/api/{0494-Add-Offline-PDC-API.patch => 0493-Add-Offline-PDC-API.patch} (100%) rename patches/api/{0495-Add-AnvilView-bypassEnchantmentLevelRestriction.patch => 0494-Add-AnvilView-bypassEnchantmentLevelRestriction.patch} (100%) rename patches/{unapplied/server/1008-API-for-checking-sent-chunks.patch => server/1039-API-for-checking-sent-chunks.patch} (66%) rename patches/{unapplied/server/1022-Fix-CraftWorld-isChunkGenerated.patch => server/1040-Fix-CraftWorld-isChunkGenerated.patch} (88%) rename patches/{ => unapplied}/api/0400-API-for-updating-recipes-on-clients.patch (100%) diff --git a/patches/api/0401-Add-PlayerFailMoveEvent.patch b/patches/api/0400-Add-PlayerFailMoveEvent.patch similarity index 100% rename from patches/api/0401-Add-PlayerFailMoveEvent.patch rename to patches/api/0400-Add-PlayerFailMoveEvent.patch diff --git a/patches/api/0402-Fix-custom-statistic-criteria-creation.patch b/patches/api/0401-Fix-custom-statistic-criteria-creation.patch similarity index 100% rename from patches/api/0402-Fix-custom-statistic-criteria-creation.patch rename to patches/api/0401-Fix-custom-statistic-criteria-creation.patch diff --git a/patches/api/0403-SculkCatalyst-bloom-API.patch b/patches/api/0402-SculkCatalyst-bloom-API.patch similarity index 100% rename from patches/api/0403-SculkCatalyst-bloom-API.patch rename to patches/api/0402-SculkCatalyst-bloom-API.patch diff --git a/patches/api/0404-API-for-an-entity-s-scoreboard-name.patch b/patches/api/0403-API-for-an-entity-s-scoreboard-name.patch similarity index 100% rename from patches/api/0404-API-for-an-entity-s-scoreboard-name.patch rename to patches/api/0403-API-for-an-entity-s-scoreboard-name.patch diff --git a/patches/api/0405-Deprecate-and-replace-methods-with-old-StructureType.patch b/patches/api/0404-Deprecate-and-replace-methods-with-old-StructureType.patch similarity index 97% rename from patches/api/0405-Deprecate-and-replace-methods-with-old-StructureType.patch rename to patches/api/0404-Deprecate-and-replace-methods-with-old-StructureType.patch index a832ca9f1d91..f09ff7714f41 100644 --- a/patches/api/0405-Deprecate-and-replace-methods-with-old-StructureType.patch +++ b/patches/api/0404-Deprecate-and-replace-methods-with-old-StructureType.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Deprecate and replace methods with old StructureType diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 52c601328bbf5c1642aa620c8bb466a9d2d231be..c8fa12acaf52cd3923a7a8702ccc50cfdc9170a2 100644 +index 50efe16bb80c618c3dfae03b70c8c165183af8ec..85ad1f7f0de9a6f9048981c3ee509b42ddbeef1a 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java @@ -949,9 +949,6 @@ public final class Bukkit { @@ -84,7 +84,7 @@ index 52c601328bbf5c1642aa620c8bb466a9d2d231be..c8fa12acaf52cd3923a7a8702ccc50cf /** * Reloads the server, refreshing settings and plugin information. diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 8ba2fbaab7428a42b506fd000fbc162f68ddaed1..50ffca9bccfb582d58ccb13f0decf66e5d91aef3 100644 +index 1b8d6a3333a4fa9155b79644e683e2343c134e12..640ef81d204f480f4af83d420c7e968ce569a38d 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -817,16 +817,15 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi diff --git a/patches/api/0406-Add-Listing-API-for-Player.patch b/patches/api/0405-Add-Listing-API-for-Player.patch similarity index 100% rename from patches/api/0406-Add-Listing-API-for-Player.patch rename to patches/api/0405-Add-Listing-API-for-Player.patch diff --git a/patches/api/0407-Expose-clicked-BlockFace-during-BlockDamageEvent.patch b/patches/api/0406-Expose-clicked-BlockFace-during-BlockDamageEvent.patch similarity index 100% rename from patches/api/0407-Expose-clicked-BlockFace-during-BlockDamageEvent.patch rename to patches/api/0406-Expose-clicked-BlockFace-during-BlockDamageEvent.patch diff --git a/patches/api/0408-Fix-NPE-on-Boat-getStatus.patch b/patches/api/0407-Fix-NPE-on-Boat-getStatus.patch similarity index 100% rename from patches/api/0408-Fix-NPE-on-Boat-getStatus.patch rename to patches/api/0407-Fix-NPE-on-Boat-getStatus.patch diff --git a/patches/api/0409-Expand-Pose-API.patch b/patches/api/0408-Expand-Pose-API.patch similarity index 100% rename from patches/api/0409-Expand-Pose-API.patch rename to patches/api/0408-Expand-Pose-API.patch diff --git a/patches/api/0410-MerchantRecipe-add-copy-constructor.patch b/patches/api/0409-MerchantRecipe-add-copy-constructor.patch similarity index 100% rename from patches/api/0410-MerchantRecipe-add-copy-constructor.patch rename to patches/api/0409-MerchantRecipe-add-copy-constructor.patch diff --git a/patches/api/0411-More-DragonBattle-API.patch b/patches/api/0410-More-DragonBattle-API.patch similarity index 100% rename from patches/api/0411-More-DragonBattle-API.patch rename to patches/api/0410-More-DragonBattle-API.patch diff --git a/patches/api/0412-Add-PlayerPickItemEvent.patch b/patches/api/0411-Add-PlayerPickItemEvent.patch similarity index 100% rename from patches/api/0412-Add-PlayerPickItemEvent.patch rename to patches/api/0411-Add-PlayerPickItemEvent.patch diff --git a/patches/api/0413-Allow-trident-custom-damage.patch b/patches/api/0412-Allow-trident-custom-damage.patch similarity index 100% rename from patches/api/0413-Allow-trident-custom-damage.patch rename to patches/api/0412-Allow-trident-custom-damage.patch diff --git a/patches/api/0414-Expose-hand-during-BlockCanBuildEvent.patch b/patches/api/0413-Expose-hand-during-BlockCanBuildEvent.patch similarity index 100% rename from patches/api/0414-Expose-hand-during-BlockCanBuildEvent.patch rename to patches/api/0413-Expose-hand-during-BlockCanBuildEvent.patch diff --git a/patches/api/0415-Limit-setBurnTime-to-valid-short-values.patch b/patches/api/0414-Limit-setBurnTime-to-valid-short-values.patch similarity index 100% rename from patches/api/0415-Limit-setBurnTime-to-valid-short-values.patch rename to patches/api/0414-Limit-setBurnTime-to-valid-short-values.patch diff --git a/patches/api/0416-Add-OfflinePlayer-isConnected.patch b/patches/api/0415-Add-OfflinePlayer-isConnected.patch similarity index 100% rename from patches/api/0416-Add-OfflinePlayer-isConnected.patch rename to patches/api/0415-Add-OfflinePlayer-isConnected.patch diff --git a/patches/api/0417-Add-titleOverride-to-InventoryOpenEvent.patch b/patches/api/0416-Add-titleOverride-to-InventoryOpenEvent.patch similarity index 100% rename from patches/api/0417-Add-titleOverride-to-InventoryOpenEvent.patch rename to patches/api/0416-Add-titleOverride-to-InventoryOpenEvent.patch diff --git a/patches/api/0418-Allow-proper-checking-of-empty-item-stacks.patch b/patches/api/0417-Allow-proper-checking-of-empty-item-stacks.patch similarity index 100% rename from patches/api/0418-Allow-proper-checking-of-empty-item-stacks.patch rename to patches/api/0417-Allow-proper-checking-of-empty-item-stacks.patch diff --git a/patches/api/0419-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch b/patches/api/0418-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch similarity index 100% rename from patches/api/0419-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch rename to patches/api/0418-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch diff --git a/patches/api/0420-Add-player-idle-duration-API.patch b/patches/api/0419-Add-player-idle-duration-API.patch similarity index 100% rename from patches/api/0420-Add-player-idle-duration-API.patch rename to patches/api/0419-Add-player-idle-duration-API.patch diff --git a/patches/api/0421-Add-API-to-get-the-collision-shape-of-a-block-before.patch b/patches/api/0420-Add-API-to-get-the-collision-shape-of-a-block-before.patch similarity index 100% rename from patches/api/0421-Add-API-to-get-the-collision-shape-of-a-block-before.patch rename to patches/api/0420-Add-API-to-get-the-collision-shape-of-a-block-before.patch diff --git a/patches/api/0422-Add-predicate-for-blocks-when-raytracing.patch b/patches/api/0421-Add-predicate-for-blocks-when-raytracing.patch similarity index 100% rename from patches/api/0422-Add-predicate-for-blocks-when-raytracing.patch rename to patches/api/0421-Add-predicate-for-blocks-when-raytracing.patch diff --git a/patches/api/0423-Add-hand-to-fish-event-for-all-player-interactions.patch b/patches/api/0422-Add-hand-to-fish-event-for-all-player-interactions.patch similarity index 100% rename from patches/api/0423-Add-hand-to-fish-event-for-all-player-interactions.patch rename to patches/api/0422-Add-hand-to-fish-event-for-all-player-interactions.patch diff --git a/patches/api/0424-Attribute-Modifier-API-improvements.patch b/patches/api/0423-Attribute-Modifier-API-improvements.patch similarity index 100% rename from patches/api/0424-Attribute-Modifier-API-improvements.patch rename to patches/api/0423-Attribute-Modifier-API-improvements.patch diff --git a/patches/api/0425-Expand-LingeringPotion-API.patch b/patches/api/0424-Expand-LingeringPotion-API.patch similarity index 100% rename from patches/api/0425-Expand-LingeringPotion-API.patch rename to patches/api/0424-Expand-LingeringPotion-API.patch diff --git a/patches/api/0426-Remove-unnecessary-durability-check-in-ItemStack-isS.patch b/patches/api/0425-Remove-unnecessary-durability-check-in-ItemStack-isS.patch similarity index 100% rename from patches/api/0426-Remove-unnecessary-durability-check-in-ItemStack-isS.patch rename to patches/api/0425-Remove-unnecessary-durability-check-in-ItemStack-isS.patch diff --git a/patches/api/0427-Add-Structure-check-API.patch b/patches/api/0426-Add-Structure-check-API.patch similarity index 100% rename from patches/api/0427-Add-Structure-check-API.patch rename to patches/api/0426-Add-Structure-check-API.patch diff --git a/patches/api/0428-Experimental-annotations-change.patch b/patches/api/0427-Experimental-annotations-change.patch similarity index 100% rename from patches/api/0428-Experimental-annotations-change.patch rename to patches/api/0427-Experimental-annotations-change.patch diff --git a/patches/api/0429-Add-more-scoreboard-API.patch b/patches/api/0428-Add-more-scoreboard-API.patch similarity index 100% rename from patches/api/0429-Add-more-scoreboard-API.patch rename to patches/api/0428-Add-more-scoreboard-API.patch diff --git a/patches/api/0430-Improve-Registry.patch b/patches/api/0429-Improve-Registry.patch similarity index 100% rename from patches/api/0430-Improve-Registry.patch rename to patches/api/0429-Improve-Registry.patch diff --git a/patches/api/0431-Add-experience-points-API.patch b/patches/api/0430-Add-experience-points-API.patch similarity index 100% rename from patches/api/0431-Add-experience-points-API.patch rename to patches/api/0430-Add-experience-points-API.patch diff --git a/patches/api/0432-Add-missing-InventoryType.patch b/patches/api/0431-Add-missing-InventoryType.patch similarity index 100% rename from patches/api/0432-Add-missing-InventoryType.patch rename to patches/api/0431-Add-missing-InventoryType.patch diff --git a/patches/api/0433-Add-drops-to-shear-events.patch b/patches/api/0432-Add-drops-to-shear-events.patch similarity index 100% rename from patches/api/0433-Add-drops-to-shear-events.patch rename to patches/api/0432-Add-drops-to-shear-events.patch diff --git a/patches/api/0434-Add-HiddenPotionEffect-API.patch b/patches/api/0433-Add-HiddenPotionEffect-API.patch similarity index 100% rename from patches/api/0434-Add-HiddenPotionEffect-API.patch rename to patches/api/0433-Add-HiddenPotionEffect-API.patch diff --git a/patches/api/0435-Add-PlayerShieldDisableEvent.patch b/patches/api/0434-Add-PlayerShieldDisableEvent.patch similarity index 100% rename from patches/api/0435-Add-PlayerShieldDisableEvent.patch rename to patches/api/0434-Add-PlayerShieldDisableEvent.patch diff --git a/patches/api/0436-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch b/patches/api/0435-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch similarity index 100% rename from patches/api/0436-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch rename to patches/api/0435-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch diff --git a/patches/api/0437-Add-BlockStateMeta-clearBlockState.patch b/patches/api/0436-Add-BlockStateMeta-clearBlockState.patch similarity index 100% rename from patches/api/0437-Add-BlockStateMeta-clearBlockState.patch rename to patches/api/0436-Add-BlockStateMeta-clearBlockState.patch diff --git a/patches/api/0438-Expose-LootTable-of-DecoratedPot.patch b/patches/api/0437-Expose-LootTable-of-DecoratedPot.patch similarity index 100% rename from patches/api/0438-Expose-LootTable-of-DecoratedPot.patch rename to patches/api/0437-Expose-LootTable-of-DecoratedPot.patch diff --git a/patches/api/0439-Add-ShulkerDuplicateEvent.patch b/patches/api/0438-Add-ShulkerDuplicateEvent.patch similarity index 100% rename from patches/api/0439-Add-ShulkerDuplicateEvent.patch rename to patches/api/0438-Add-ShulkerDuplicateEvent.patch diff --git a/patches/api/0440-Add-api-for-spawn-egg-texture-colors.patch b/patches/api/0439-Add-api-for-spawn-egg-texture-colors.patch similarity index 100% rename from patches/api/0440-Add-api-for-spawn-egg-texture-colors.patch rename to patches/api/0439-Add-api-for-spawn-egg-texture-colors.patch diff --git a/patches/api/0441-Add-Lifecycle-Event-system.patch b/patches/api/0440-Add-Lifecycle-Event-system.patch similarity index 100% rename from patches/api/0441-Add-Lifecycle-Event-system.patch rename to patches/api/0440-Add-Lifecycle-Event-system.patch diff --git a/patches/api/0442-ItemStack-Tooltip-API.patch b/patches/api/0441-ItemStack-Tooltip-API.patch similarity index 100% rename from patches/api/0442-ItemStack-Tooltip-API.patch rename to patches/api/0441-ItemStack-Tooltip-API.patch diff --git a/patches/api/0443-Add-getChunkSnapshot-includeLightData-parameter.patch b/patches/api/0442-Add-getChunkSnapshot-includeLightData-parameter.patch similarity index 100% rename from patches/api/0443-Add-getChunkSnapshot-includeLightData-parameter.patch rename to patches/api/0442-Add-getChunkSnapshot-includeLightData-parameter.patch diff --git a/patches/api/0444-Add-FluidState-API.patch b/patches/api/0443-Add-FluidState-API.patch similarity index 100% rename from patches/api/0444-Add-FluidState-API.patch rename to patches/api/0443-Add-FluidState-API.patch diff --git a/patches/api/0445-add-number-format-api.patch b/patches/api/0444-add-number-format-api.patch similarity index 100% rename from patches/api/0445-add-number-format-api.patch rename to patches/api/0444-add-number-format-api.patch diff --git a/patches/api/0446-improve-BanList-types.patch b/patches/api/0445-improve-BanList-types.patch similarity index 94% rename from patches/api/0446-improve-BanList-types.patch rename to patches/api/0445-improve-BanList-types.patch index bfb2a6a550f7..0c89e083a6ce 100644 --- a/patches/api/0446-improve-BanList-types.patch +++ b/patches/api/0445-improve-BanList-types.patch @@ -70,10 +70,10 @@ index a77c0411a68a9bad33ddfb335b7a996a843e478c..739d9d3ec789e58c10c8d818a9ca59ce /** * Banned player names diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index c8fa12acaf52cd3923a7a8702ccc50cfdc9170a2..e20e4239a5a1f952e1c70e899549989d5e42f73c 100644 +index 85ad1f7f0de9a6f9048981c3ee509b42ddbeef1a..2d466b308b2f8bd31c50f5d05416eadf20c9cb71 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -1663,11 +1663,27 @@ public final class Bukkit { +@@ -1611,11 +1611,27 @@ public final class Bukkit { * @param The ban target * * @return a ban list of the specified type @@ -102,10 +102,10 @@ index c8fa12acaf52cd3923a7a8702ccc50cfdc9170a2..e20e4239a5a1f952e1c70e899549989d /** * Gets a set containing all player operators. diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 50ffca9bccfb582d58ccb13f0decf66e5d91aef3..6246251caf2c6f025c824b8e7a944b8d48751fa1 100644 +index 640ef81d204f480f4af83d420c7e968ce569a38d..20750c09d819d62f32491db8672936b929e1098e 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -1425,10 +1425,25 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -1374,10 +1374,25 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi * @param The ban target * * @return a ban list of the specified type diff --git a/patches/api/0447-Suspicious-Effect-Entry-API.patch b/patches/api/0446-Suspicious-Effect-Entry-API.patch similarity index 100% rename from patches/api/0447-Suspicious-Effect-Entry-API.patch rename to patches/api/0446-Suspicious-Effect-Entry-API.patch diff --git a/patches/api/0448-Fix-DamageSource-API.patch b/patches/api/0447-Fix-DamageSource-API.patch similarity index 100% rename from patches/api/0448-Fix-DamageSource-API.patch rename to patches/api/0447-Fix-DamageSource-API.patch diff --git a/patches/api/0449-Expanded-Hopper-API.patch b/patches/api/0448-Expanded-Hopper-API.patch similarity index 100% rename from patches/api/0449-Expanded-Hopper-API.patch rename to patches/api/0448-Expanded-Hopper-API.patch diff --git a/patches/api/0450-Clone-mutables-to-prevent-unexpected-issues.patch b/patches/api/0449-Clone-mutables-to-prevent-unexpected-issues.patch similarity index 100% rename from patches/api/0450-Clone-mutables-to-prevent-unexpected-issues.patch rename to patches/api/0449-Clone-mutables-to-prevent-unexpected-issues.patch diff --git a/patches/api/0451-Add-BlockBreakProgressUpdateEvent.patch b/patches/api/0450-Add-BlockBreakProgressUpdateEvent.patch similarity index 100% rename from patches/api/0451-Add-BlockBreakProgressUpdateEvent.patch rename to patches/api/0450-Add-BlockBreakProgressUpdateEvent.patch diff --git a/patches/api/0452-Deprecate-ItemStack-setType.patch b/patches/api/0451-Deprecate-ItemStack-setType.patch similarity index 100% rename from patches/api/0452-Deprecate-ItemStack-setType.patch rename to patches/api/0451-Deprecate-ItemStack-setType.patch diff --git a/patches/api/0453-Item-Mutation-Fixes.patch b/patches/api/0452-Item-Mutation-Fixes.patch similarity index 100% rename from patches/api/0453-Item-Mutation-Fixes.patch rename to patches/api/0452-Item-Mutation-Fixes.patch diff --git a/patches/api/0454-API-for-checking-sent-chunks.patch b/patches/api/0453-API-for-checking-sent-chunks.patch similarity index 100% rename from patches/api/0454-API-for-checking-sent-chunks.patch rename to patches/api/0453-API-for-checking-sent-chunks.patch diff --git a/patches/api/0455-Add-CartographyItemEvent.patch b/patches/api/0454-Add-CartographyItemEvent.patch similarity index 100% rename from patches/api/0455-Add-CartographyItemEvent.patch rename to patches/api/0454-Add-CartographyItemEvent.patch diff --git a/patches/api/0456-More-Raid-API.patch b/patches/api/0455-More-Raid-API.patch similarity index 100% rename from patches/api/0456-More-Raid-API.patch rename to patches/api/0455-More-Raid-API.patch diff --git a/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch b/patches/api/0456-Fix-SpawnerEntry-Equipment-API.patch similarity index 100% rename from patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch rename to patches/api/0456-Fix-SpawnerEntry-Equipment-API.patch diff --git a/patches/api/0458-Fix-ItemFlags.patch b/patches/api/0457-Fix-ItemFlags.patch similarity index 100% rename from patches/api/0458-Fix-ItemFlags.patch rename to patches/api/0457-Fix-ItemFlags.patch diff --git a/patches/api/0459-Allow-modifying-library-loader-jars-bytecode.patch b/patches/api/0458-Allow-modifying-library-loader-jars-bytecode.patch similarity index 100% rename from patches/api/0459-Allow-modifying-library-loader-jars-bytecode.patch rename to patches/api/0458-Allow-modifying-library-loader-jars-bytecode.patch diff --git a/patches/api/0460-Add-hook-to-remap-library-jars.patch b/patches/api/0459-Add-hook-to-remap-library-jars.patch similarity index 100% rename from patches/api/0460-Add-hook-to-remap-library-jars.patch rename to patches/api/0459-Add-hook-to-remap-library-jars.patch diff --git a/patches/api/0461-Add-GameMode-isInvulnerable.patch b/patches/api/0460-Add-GameMode-isInvulnerable.patch similarity index 100% rename from patches/api/0461-Add-GameMode-isInvulnerable.patch rename to patches/api/0460-Add-GameMode-isInvulnerable.patch diff --git a/patches/api/0462-Expose-hasColor-to-leather-armor.patch b/patches/api/0461-Expose-hasColor-to-leather-armor.patch similarity index 100% rename from patches/api/0462-Expose-hasColor-to-leather-armor.patch rename to patches/api/0461-Expose-hasColor-to-leather-armor.patch diff --git a/patches/api/0463-Added-API-to-get-player-ha-proxy-address.patch b/patches/api/0462-Added-API-to-get-player-ha-proxy-address.patch similarity index 100% rename from patches/api/0463-Added-API-to-get-player-ha-proxy-address.patch rename to patches/api/0462-Added-API-to-get-player-ha-proxy-address.patch diff --git a/patches/api/0464-More-Chest-Block-API.patch b/patches/api/0463-More-Chest-Block-API.patch similarity index 100% rename from patches/api/0464-More-Chest-Block-API.patch rename to patches/api/0463-More-Chest-Block-API.patch diff --git a/patches/api/0465-Brigadier-based-command-API.patch b/patches/api/0464-Brigadier-based-command-API.patch similarity index 100% rename from patches/api/0465-Brigadier-based-command-API.patch rename to patches/api/0464-Brigadier-based-command-API.patch diff --git a/patches/api/0466-Fix-issues-with-recipe-API.patch b/patches/api/0465-Fix-issues-with-recipe-API.patch similarity index 100% rename from patches/api/0466-Fix-issues-with-recipe-API.patch rename to patches/api/0465-Fix-issues-with-recipe-API.patch diff --git a/patches/api/0467-Fix-equipment-slot-and-group-API.patch b/patches/api/0466-Fix-equipment-slot-and-group-API.patch similarity index 100% rename from patches/api/0467-Fix-equipment-slot-and-group-API.patch rename to patches/api/0466-Fix-equipment-slot-and-group-API.patch diff --git a/patches/api/0468-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch b/patches/api/0467-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch similarity index 100% rename from patches/api/0468-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch rename to patches/api/0467-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch diff --git a/patches/api/0469-General-ItemMeta-fixes.patch b/patches/api/0468-General-ItemMeta-fixes.patch similarity index 100% rename from patches/api/0469-General-ItemMeta-fixes.patch rename to patches/api/0468-General-ItemMeta-fixes.patch diff --git a/patches/api/0470-Add-missing-fishing-event-state.patch b/patches/api/0469-Add-missing-fishing-event-state.patch similarity index 100% rename from patches/api/0470-Add-missing-fishing-event-state.patch rename to patches/api/0469-Add-missing-fishing-event-state.patch diff --git a/patches/api/0471-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch b/patches/api/0470-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch similarity index 100% rename from patches/api/0471-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch rename to patches/api/0470-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch diff --git a/patches/api/0472-Registry-Modification-API.patch b/patches/api/0471-Registry-Modification-API.patch similarity index 100% rename from patches/api/0472-Registry-Modification-API.patch rename to patches/api/0471-Registry-Modification-API.patch diff --git a/patches/api/0473-Introduce-registry-entry-and-builders.patch b/patches/api/0472-Introduce-registry-entry-and-builders.patch similarity index 100% rename from patches/api/0473-Introduce-registry-entry-and-builders.patch rename to patches/api/0472-Introduce-registry-entry-and-builders.patch diff --git a/patches/api/0474-Proxy-ItemStack-to-CraftItemStack.patch b/patches/api/0473-Proxy-ItemStack-to-CraftItemStack.patch similarity index 100% rename from patches/api/0474-Proxy-ItemStack-to-CraftItemStack.patch rename to patches/api/0473-Proxy-ItemStack-to-CraftItemStack.patch diff --git a/patches/api/0475-Make-a-PDC-view-accessible-directly-from-ItemStack.patch b/patches/api/0474-Make-a-PDC-view-accessible-directly-from-ItemStack.patch similarity index 100% rename from patches/api/0475-Make-a-PDC-view-accessible-directly-from-ItemStack.patch rename to patches/api/0474-Make-a-PDC-view-accessible-directly-from-ItemStack.patch diff --git a/patches/api/0476-Fix-HelpCommand-searching.patch b/patches/api/0475-Fix-HelpCommand-searching.patch similarity index 100% rename from patches/api/0476-Fix-HelpCommand-searching.patch rename to patches/api/0475-Fix-HelpCommand-searching.patch diff --git a/patches/api/0477-add-Plugin-getDataPath.patch b/patches/api/0476-add-Plugin-getDataPath.patch similarity index 100% rename from patches/api/0477-add-Plugin-getDataPath.patch rename to patches/api/0476-add-Plugin-getDataPath.patch diff --git a/patches/api/0478-Fix-PickupStatus-getting-reset.patch b/patches/api/0477-Fix-PickupStatus-getting-reset.patch similarity index 100% rename from patches/api/0478-Fix-PickupStatus-getting-reset.patch rename to patches/api/0477-Fix-PickupStatus-getting-reset.patch diff --git a/patches/api/0479-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch b/patches/api/0478-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch similarity index 100% rename from patches/api/0479-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch rename to patches/api/0478-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch diff --git a/patches/api/0480-Improve-StandardMessenger-exception-messages.patch b/patches/api/0479-Improve-StandardMessenger-exception-messages.patch similarity index 100% rename from patches/api/0480-Improve-StandardMessenger-exception-messages.patch rename to patches/api/0479-Improve-StandardMessenger-exception-messages.patch diff --git a/patches/api/0481-Add-even-more-Enchantment-API.patch b/patches/api/0480-Add-even-more-Enchantment-API.patch similarity index 100% rename from patches/api/0481-Add-even-more-Enchantment-API.patch rename to patches/api/0480-Add-even-more-Enchantment-API.patch diff --git a/patches/api/0482-Leashable-API.patch b/patches/api/0481-Leashable-API.patch similarity index 100% rename from patches/api/0482-Leashable-API.patch rename to patches/api/0481-Leashable-API.patch diff --git a/patches/api/0483-Add-enchantment-seed-update-API.patch b/patches/api/0482-Add-enchantment-seed-update-API.patch similarity index 100% rename from patches/api/0483-Add-enchantment-seed-update-API.patch rename to patches/api/0482-Add-enchantment-seed-update-API.patch diff --git a/patches/api/0484-Deprecate-for-removal-all-OldEnum-related-methods.patch b/patches/api/0483-Deprecate-for-removal-all-OldEnum-related-methods.patch similarity index 100% rename from patches/api/0484-Deprecate-for-removal-all-OldEnum-related-methods.patch rename to patches/api/0483-Deprecate-for-removal-all-OldEnum-related-methods.patch diff --git a/patches/api/0485-Add-FeatureFlag-API.patch b/patches/api/0484-Add-FeatureFlag-API.patch similarity index 100% rename from patches/api/0485-Add-FeatureFlag-API.patch rename to patches/api/0484-Add-FeatureFlag-API.patch diff --git a/patches/api/0486-Tag-Lifecycle-Events.patch b/patches/api/0485-Tag-Lifecycle-Events.patch similarity index 100% rename from patches/api/0486-Tag-Lifecycle-Events.patch rename to patches/api/0485-Tag-Lifecycle-Events.patch diff --git a/patches/api/0487-Item-serialization-as-json.patch b/patches/api/0486-Item-serialization-as-json.patch similarity index 100% rename from patches/api/0487-Item-serialization-as-json.patch rename to patches/api/0486-Item-serialization-as-json.patch diff --git a/patches/api/0488-create-TileStateInventoryHolder.patch b/patches/api/0487-create-TileStateInventoryHolder.patch similarity index 100% rename from patches/api/0488-create-TileStateInventoryHolder.patch rename to patches/api/0487-create-TileStateInventoryHolder.patch diff --git a/patches/api/0489-Add-enchantWithLevels-with-enchantment-registry-set.patch b/patches/api/0488-Add-enchantWithLevels-with-enchantment-registry-set.patch similarity index 100% rename from patches/api/0489-Add-enchantWithLevels-with-enchantment-registry-set.patch rename to patches/api/0488-Add-enchantWithLevels-with-enchantment-registry-set.patch diff --git a/patches/api/0490-Improve-entity-effect-API.patch b/patches/api/0489-Improve-entity-effect-API.patch similarity index 100% rename from patches/api/0490-Improve-entity-effect-API.patch rename to patches/api/0489-Improve-entity-effect-API.patch diff --git a/patches/api/0491-Add-recipeBrewTime.patch b/patches/api/0490-Add-recipeBrewTime.patch similarity index 100% rename from patches/api/0491-Add-recipeBrewTime.patch rename to patches/api/0490-Add-recipeBrewTime.patch diff --git a/patches/api/0492-Add-PlayerInsertLecternBookEvent.patch b/patches/api/0491-Add-PlayerInsertLecternBookEvent.patch similarity index 100% rename from patches/api/0492-Add-PlayerInsertLecternBookEvent.patch rename to patches/api/0491-Add-PlayerInsertLecternBookEvent.patch diff --git a/patches/api/0493-Void-damage-configuration-API.patch b/patches/api/0492-Void-damage-configuration-API.patch similarity index 100% rename from patches/api/0493-Void-damage-configuration-API.patch rename to patches/api/0492-Void-damage-configuration-API.patch diff --git a/patches/api/0494-Add-Offline-PDC-API.patch b/patches/api/0493-Add-Offline-PDC-API.patch similarity index 100% rename from patches/api/0494-Add-Offline-PDC-API.patch rename to patches/api/0493-Add-Offline-PDC-API.patch diff --git a/patches/api/0495-Add-AnvilView-bypassEnchantmentLevelRestriction.patch b/patches/api/0494-Add-AnvilView-bypassEnchantmentLevelRestriction.patch similarity index 100% rename from patches/api/0495-Add-AnvilView-bypassEnchantmentLevelRestriction.patch rename to patches/api/0494-Add-AnvilView-bypassEnchantmentLevelRestriction.patch diff --git a/patches/server/0969-Fix-removing-recipes-from-RecipeIterator.patch b/patches/server/0969-Fix-removing-recipes-from-RecipeIterator.patch index 636f3d2440d1..a8f124b45808 100644 --- a/patches/server/0969-Fix-removing-recipes-from-RecipeIterator.patch +++ b/patches/server/0969-Fix-removing-recipes-from-RecipeIterator.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Fix removing recipes from RecipeIterator public net.minecraft.world.item.crafting.RecipeManager byName diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java b/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java -index 4e0f7564f04d5d566660a2623fb1b325e3b4e67c..39d2d67bf478beb4c72e41e6f59337893cf47e69 100644 +index 4e0f7564f04d5d566660a2623fb1b325e3b4e67c..ca0c82fdd7bd1c2055e84253d90b17857c51b771 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java @@ -9,6 +9,7 @@ import org.bukkit.inventory.Recipe; @@ -18,7 +18,7 @@ index 4e0f7564f04d5d566660a2623fb1b325e3b4e67c..39d2d67bf478beb4c72e41e6f5933789 public RecipeIterator() { this.recipes = MinecraftServer.getServer().getRecipeManager().recipes.byType.entries().iterator(); -@@ -21,11 +22,19 @@ public class RecipeIterator implements Iterator { +@@ -21,11 +22,17 @@ public class RecipeIterator implements Iterator { @Override public Recipe next() { @@ -32,9 +32,7 @@ index 4e0f7564f04d5d566660a2623fb1b325e3b4e67c..39d2d67bf478beb4c72e41e6f5933789 @Override public void remove() { + // Paper start - fix removing recipes from RecipeIterator -+ if (this.currentRecipe instanceof org.bukkit.Keyed keyed) { -+ MinecraftServer.getServer().getRecipeManager().byName.remove(org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(keyed.getKey())); -+ } ++ if (true) throw new UnsupportedOperationException(); + // Paper end - fix removing recipes from RecipeIterator this.recipes.remove(); } diff --git a/patches/unapplied/server/1008-API-for-checking-sent-chunks.patch b/patches/server/1039-API-for-checking-sent-chunks.patch similarity index 66% rename from patches/unapplied/server/1008-API-for-checking-sent-chunks.patch rename to patches/server/1039-API-for-checking-sent-chunks.patch index 1ff508b7278d..7f0201844b96 100644 --- a/patches/unapplied/server/1008-API-for-checking-sent-chunks.patch +++ b/patches/server/1039-API-for-checking-sent-chunks.patch @@ -4,26 +4,11 @@ Date: Mon, 8 Apr 2024 16:43:16 +0200 Subject: [PATCH] API for checking sent chunks -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -index 852d75a73dae7448cbe1e2f5e164b235efa8a969..a608f57ebca98eda88ad749d0aad021678be54f9 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -@@ -1078,5 +1078,10 @@ public final class RegionizedPlayerChunkLoader { - - // now all tickets should be removed, which is all of our external state - } -+ -+ // For external checks -+ public it.unimi.dsi.fastutil.longs.LongOpenHashSet getSentChunksRaw() { -+ return this.sentChunks; -+ } - } - } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index e02fa642f11809607e30e22b51c65373edd70842..ad740739437be632fc7fedec488a7d0c49534688 100644 +index ed29e06422aa5e73adfaf9578cda3dfc5777f64c..550e175c7fec97818644933a4e4f7805e54d7d5f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3483,6 +3483,35 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3518,6 +3518,35 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end diff --git a/patches/unapplied/server/1022-Fix-CraftWorld-isChunkGenerated.patch b/patches/server/1040-Fix-CraftWorld-isChunkGenerated.patch similarity index 88% rename from patches/unapplied/server/1022-Fix-CraftWorld-isChunkGenerated.patch rename to patches/server/1040-Fix-CraftWorld-isChunkGenerated.patch index c402325cb569..a1a60d71b0c1 100644 --- a/patches/unapplied/server/1022-Fix-CraftWorld-isChunkGenerated.patch +++ b/patches/server/1040-Fix-CraftWorld-isChunkGenerated.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Fix CraftWorld#isChunkGenerated The upstream implementation is returning true for non-full chunks. diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 8221597951c5e768fa8af23adc1a57871c76f3a6..90d4834f97d3ba996d46493246b1947511553424 100644 +index 2058671a77cac4cfa6494461a5142abae14402b6..d41c81158c00931e6b11093cce141f6a3085ba05 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -372,11 +372,28 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -417,11 +417,28 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean isChunkGenerated(int x, int z) { @@ -29,7 +29,7 @@ index 8221597951c5e768fa8af23adc1a57871c76f3a6..90d4834f97d3ba996d46493246b19475 } + final java.util.concurrent.CompletableFuture future = new java.util.concurrent.CompletableFuture<>(); + ca.spottedleaf.moonrise.common.util.ChunkSystem.scheduleChunkLoad( -+ this.world, x, z, false, ChunkStatus.EMPTY, true, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, future::complete ++ this.world, x, z, false, ChunkStatus.EMPTY, true, ca.spottedleaf.concurrentutil.util.Priority.NORMAL, future::complete + ); + world.getChunkSource().mainThreadProcessor.managedBlock(future::isDone); + return future.thenApply(c -> { diff --git a/patches/api/0400-API-for-updating-recipes-on-clients.patch b/patches/unapplied/api/0400-API-for-updating-recipes-on-clients.patch similarity index 100% rename from patches/api/0400-API-for-updating-recipes-on-clients.patch rename to patches/unapplied/api/0400-API-for-updating-recipes-on-clients.patch From 683ce2062eef97381b7b2254d06eb170ac203059 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 25 Oct 2024 12:57:20 -0700 Subject: [PATCH 079/119] Fix Anti-Xray using wrong data in chunk deserialize --- patches/server/0979-Anti-Xray.patch | 13 ++++++++++--- .../server/1038-Moonrise-optimisation-patches.patch | 11 +---------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/patches/server/0979-Anti-Xray.patch b/patches/server/0979-Anti-Xray.patch index dba0bf0bbcec..7ab86199c5d7 100644 --- a/patches/server/0979-Anti-Xray.patch +++ b/patches/server/0979-Anti-Xray.patch @@ -1519,7 +1519,7 @@ index 303e59be721d0e16e8822cf4e407595348ee7abf..51f74dd7b276e858889803d7f341d735 int getSerializedSize(); diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index b86b3bf713668999a21c4120b1d16c295531b2ad..eba3e34e5b129050bf6eaed6ce4e690357a3de20 100644 +index b86b3bf713668999a21c4120b1d16c295531b2ad..4bc7fa3324e9af3abce2acf960c7b0650aca2e36 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java @@ -79,7 +79,7 @@ import org.slf4j.Logger; @@ -1539,7 +1539,14 @@ index b86b3bf713668999a21c4120b1d16c295531b2ad..eba3e34e5b129050bf6eaed6ce4e6903 if (!nbt.contains("Status", 8)) { return null; } else { -@@ -214,13 +215,17 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -208,19 +209,23 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + Codec>> codec = makeBiomeCodecRW(iregistry); // CraftBukkit - read/write + + for (int i1 = 0; i1 < nbttaglist2.size(); ++i1) { +- CompoundTag nbttagcompound3 = nbttaglist2.getCompound(i1); ++ CompoundTag nbttagcompound3 = nbttaglist2.getCompound(i1); final CompoundTag sectionData = nbttagcompound3; // Paper - Anti-Xray - OBFHELPER + byte b0 = nbttagcompound3.getByte("Y"); + LevelChunkSection chunksection; if (b0 >= world.getMinSectionY() && b0 <= world.getMaxSectionY()) { PalettedContainer datapaletteblock; @@ -1550,7 +1557,7 @@ index b86b3bf713668999a21c4120b1d16c295531b2ad..eba3e34e5b129050bf6eaed6ce4e6903 if (nbttagcompound3.contains("block_states", 10)) { - datapaletteblock = (PalettedContainer) SerializableChunkData.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, nbttagcompound3.getCompound("block_states")).promotePartial((s1) -> { + Codec> blockStateCodec = presetBlockStates == null ? BLOCK_STATE_CODEC : PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), presetBlockStates); // Paper - Anti-Xray -+ datapaletteblock = blockStateCodec.parse(NbtOps.INSTANCE, nbttagcompound1.getCompound("block_states")).promotePartial((s1) -> { // Paper - Anti-Xray ++ datapaletteblock = blockStateCodec.parse(NbtOps.INSTANCE, sectionData.getCompound("block_states")).promotePartial((s1) -> { // Paper - Anti-Xray logErrors(chunkcoordintpair, b0, s1); }).getOrThrow(SerializableChunkData.ChunkReadException::new); } else { diff --git a/patches/server/1038-Moonrise-optimisation-patches.patch b/patches/server/1038-Moonrise-optimisation-patches.patch index 3f638ea9d165..1ee8b3dec8f4 100644 --- a/patches/server/1038-Moonrise-optimisation-patches.patch +++ b/patches/server/1038-Moonrise-optimisation-patches.patch @@ -33286,7 +33286,7 @@ index 93972352cd4881dccba9b90ccc8dcced3563e340..c3beb7fcad46a917d2b61bd0a0e98e51 static record PackedChunk(Int2ObjectMap sectionsByY, boolean versionChanged) { diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index eba3e34e5b129050bf6eaed6ce4e690357a3de20..83c87b56205b68010016b58b7f6e4d02f1fa5681 100644 +index 4bc7fa3324e9af3abce2acf960c7b0650aca2e36..e939810f3cc094a4b17f0b60a441773997cb788f 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java @@ -129,7 +129,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun @@ -33298,15 +33298,6 @@ index eba3e34e5b129050bf6eaed6ce4e690357a3de20..83c87b56205b68010016b58b7f6e4d02 DataResult dataresult; Logger logger; BlendingData.Packed blendingdata_d; -@@ -209,7 +209,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun - Codec>> codec = makeBiomeCodecRW(iregistry); // CraftBukkit - read/write - - for (int i1 = 0; i1 < nbttaglist2.size(); ++i1) { -- CompoundTag nbttagcompound3 = nbttaglist2.getCompound(i1); -+ CompoundTag nbttagcompound3 = nbttaglist2.getCompound(i1); final CompoundTag sectionData = nbttagcompound3; // Paper - starlight - OBFHELPER - byte b0 = nbttagcompound3.getByte("Y"); - LevelChunkSection chunksection; - @@ -246,7 +246,17 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun DataLayer nibblearray = nbttagcompound3.contains("BlockLight", 7) ? new DataLayer(nbttagcompound3.getByteArray("BlockLight")) : null; DataLayer nibblearray1 = nbttagcompound3.contains("SkyLight", 7) ? new DataLayer(nbttagcompound3.getByteArray("SkyLight")) : null; From e92607cd21db8a6665a40898801c36a0d24f2d8c Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 25 Oct 2024 13:19:27 -0700 Subject: [PATCH 080/119] Fix MSPT command Used wrong variable for tick length --- .../server/0322-Add-tick-times-API-and-mspt-command.patch | 8 ++++---- patches/server/0348-misc-debugging-dumps.patch | 2 +- .../0355-Wait-for-Async-Tasks-during-shutdown.patch | 2 +- ...-Fix-Per-World-Difficulty-Remembering-Difficulty.patch | 2 +- patches/server/0403-Cache-block-data-strings.patch | 2 +- ...deop-kicking-non-whitelisted-player-when-white-l.patch | 2 +- .../server/0457-Add-ServerResourcesReloadedEvent.patch | 2 +- patches/server/0480-Add-EntityMoveEvent.patch | 2 +- ...9-forced-whitelist-use-configurable-kick-message.patch | 2 +- patches/server/0539-Add-PlayerKickEvent-causes.patch | 2 +- ...0642-Expose-vanilla-BiomeProvider-from-WorldInfo.patch | 2 +- ...ute-chunk-tasks-fairly-for-worlds-while-waiting-.patch | 2 +- ...on-to-have-default-CustomSpawners-in-custom-worl.patch | 2 +- ...ut-world-into-worldlist-before-initing-the-world.patch | 2 +- patches/server/0665-Custom-Potion-Mixes.patch | 2 +- ...row-exception-on-world-create-while-being-ticked.patch | 2 +- .../0728-Fix-plugin-loggers-on-server-shutdown.patch | 2 +- .../0766-Fix-premature-player-kicks-on-shutdown.patch | 2 +- .../0836-Folia-scheduler-and-owned-region-API.patch | 2 +- ...-Add-onboarding-message-for-initial-server-start.patch | 2 +- patches/server/0956-Brigadier-based-command-API.patch | 2 +- patches/server/0983-Optimize-Hoppers.patch | 2 +- patches/server/1021-Tag-Lifecycle-Events.patch | 2 +- patches/server/1038-Moonrise-optimisation-patches.patch | 2 +- 24 files changed, 27 insertions(+), 27 deletions(-) diff --git a/patches/server/0322-Add-tick-times-API-and-mspt-command.patch b/patches/server/0322-Add-tick-times-API-and-mspt-command.patch index d0480d54b792..ebc083a44658 100644 --- a/patches/server/0322-Add-tick-times-API-and-mspt-command.patch +++ b/patches/server/0322-Add-tick-times-API-and-mspt-command.patch @@ -125,7 +125,7 @@ index 72f2e81b9905a0d57ed8e2a88578f62d5235c456..7b58b2d6297800c2dcdbf7539e5ab8e7 public static void registerCommands(final MinecraftServer server) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 5f84618775d66d50557fa71f77fa322c2d1da791..708552756a33339ce9eefe48c9999a2ec08f7e1c 100644 +index 5f84618775d66d50557fa71f77fa322c2d1da791..4f446f24e8468b2427528548edde0512c9fae5b0 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -264,6 +264,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop void loadContentsFromNetwork( diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index b37e49bd25ed327e03250415799c0777f95bd57b..6d0cfaaf414931d9fd8eee417f4b70ac6679de10 100644 +index d25bc0cf0c05de8e9e7366104560d74961d74a8a..be1588c0a757a2d86fbedc1c89f47fd7c60d84f4 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -2251,7 +2251,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Date: Fri, 25 Oct 2024 22:33:37 +0200 Subject: [PATCH 081/119] Fix crafting (and server icon) --- patches/server/0489-Improve-ServerGUI.patch | 647 +++++++++--------- .../0957-Fix-issues-with-Recipe-API.patch | 12 +- 2 files changed, 333 insertions(+), 326 deletions(-) diff --git a/patches/server/0489-Improve-ServerGUI.patch b/patches/server/0489-Improve-ServerGUI.patch index 48a151cd82f1..8dde1d1a9bc4 100644 --- a/patches/server/0489-Improve-ServerGUI.patch +++ b/patches/server/0489-Improve-ServerGUI.patch @@ -102,330 +102,329 @@ new file mode 100644 index 0000000000000000000000000000000000000000..8b924977b7886df9ab8790b1e4ff9b1c04a2af45 GIT binary patch literal 16900 -zcmaf)RZtymu&!}kXmDLfg1h^|-QC?ixG&s2I0Sch5AG1$U4m2?7EFMOsQs1p)$M^xuU52LS<5tyS|A0z!B~T1;5Y)8HZp -zUh9YE!*I`C!>au1!lt}?^7%)ymXa9F0E8%U6cA@Hs@r2|t2YjT?MMEK&sF!xR;P(1 -zJxFf8OgT_&`%_^18f74-j~9B>_v*F_4QG7P$=~I&{g0k-!dKZ;dhG_Yv84aKQ7`JU -zJ^ehid=1+b=_P#o97{5v??~H!^zyIS&U_=f-+Z&XS28Q#IuJUNE}ApzE+z8$!_(s%I3_!)=jTdGmXzz2p&3&czvSwVkj_PR|SM`xDjT-m<)@wFKtJ!fY -z+A9f&c$RQF&Z%Ui9@S9nRjlxMs@)Z5_OxNu^|5JS^tNFPeEv!Mp+fj^Yc}Scf482J -z_jv2_UYgabd?1AMePOH(|ApkUIjM`|sON7?4||4r>}#l#)Nj}LPNV67U-a5cAqgk9 -z4hA)b1i?G`_{?Is2NgH3=G*Y_oV4G*#y>w?4I7fSpx2h|vD&hsqdFVmofnVkNpM8o -zEDOkF7WVse0CrXXeH^X&Y+X5Ugeg(@8XVq_7ngH%kQ4q8to@(w`VD%+t{VjBlZzMA{89 -z;%$e2aiD==VT$}%!%lBbY3xicyog$jB!Djxd7vpR6bXArR{Oqv(5MfWsJg3Yy -zcUpf*M1f-z9ik)^?H|-}` -zxbJl0Xc<(adaW`;Xc^eA&$kJ4EZWH)dOO+mFzw;MBfNjA5<1ZP>E3RWzD|&L1WdK! -z2k&T-AdM3|);yD$reQ{x9G{_#6R5f}9%tdjf-W#_wS$qa(*X;ot*Gkja`g1Q_eN^= -z`0%;Ho3r-6zU-m(+)f%v8KxzXfn20UBXua$j&hd^L+a{0lv^F@IS92IL#!_sffCl2&zHVp_~j(J1np!W5n69+~xPAJ6}_zBa%4jtFt9W -z{@f*=wRJ|ZitBopGm@A{J`xa&M -z)PY`TF0^X2?f!}827nOWNuI-}Ne-gU_A_rT89Qjihq3d_{Ugx}ge|kRq}v@?<-}sM1htR5<=} -zI1L1)$lG(bP|&c#@>`Np6h0xGHe-S%SWq_O*_rH`M&)M5xj9Un#*HS!PqE5 -zISo-XF(NX8c$<8iK|uH&>qt?Q&-b}D+Tgr7t>MFp&WJTZFnPZ1>|RTVqu7iauEwTX -zVJi3CHpH3>2eq__Ox+k#@Bzl=K|7STdhX7MT{c8Ce71~q9Y&PXH}*iaRuCUgMZj4H -z)QyHub -z_qnc(rzc$MCNk878`Sofx_>n{BwDNL?TS=$RO_S6!R*Ey=`(aG@LbB{HGQ+@MqP=h -zu&0VvO0ab!36xlai&*>Xc+6_xPmdSo9TasQ3?*TY!)%lYzD(AZ0HWie+au=#fiLo& -zU+O6Y`-6UchQAZ*C2TI_f~f(2hrMt6KE)jP36+(ZZfle23Dx>Inkk_7xY0&pkp)+N -z%^^0b-mA7bkD<)a8%J{cvSRJ2S;}#v9g(doR}TQ3QGy%7T$YWkQuW{|T0eu$!D%Gg -zhIpru$xwR_h!F-%c~|@zigH-C2m=8{D8VNnCdFPc6Rfz(8f#dDmuUW@`u=TQn?l6ex-ha;(`` -zrS1uS-(@|j8cS+#fW*WdM9k{Fbp6f|!@JL%Gh}@yEWnTjE-DYfVpx0s5?hF9Qzi@Lf>~6Pm?DX{;HP^Q242(r1D1_=jrbppWF;PQk_!Ls -zS?3Zy6SOYNhA^`C9Gr`$aM+kF+PqIpNc~b)YOTag^;@K{!LHyR#-D?kKh>QZn&JHs -z(S}LQ;l-T8IWrlT$vDeig`Pf3fs);`cyZgTesw;vUk*#=1ZlB5zS``R@)U;`I^|DW -z?`Wu5^KI6hZo2(M-a~zF#>3kiX?zjyY=f@)xk3s24jF8WN!RqnV5qMC{5IS-?p~l` -z*Od<2Atam`NRWyKlq2%T>WdXRFci|p)_QD!{us*BG6#&@1J>-ygf`d(+Yt%AR?$|m -zG2&h}ZNhe;3iL&t-&Bo~bSQvwc_uqFF*q*u<%r&3Io&Jc -z8X3Bs8jXqH@NHmV7BRmCYCHHs=Nrep*-}>qojz9eD&96O%Es8n$%gaSnOL~VE%6i@ -z&N;!@pfy%G7dw?+2y1|uMDE?45uzNTNB_7>aX);UvtG>N2^CK4jXJOIypMJdF8LKU -zTYqIdp7&|wl19M2-A~xsFLDE9e-nocdK3)_YdtcQ)W%k7bx|ihJbIc=Z5ZyZ^yh9L -zz(%H87tSJzNkw!4yq5hajBkYU#kO&cksLk7!K-`GO(iyvT=U{|HBlNQU1VB|)w$-~ -z!`vE~Br`P8J<1%ly9{1OIZc%XlCTOPAdcit!jhpR;%=Zn+J^5sT)?#vtC4a+pY5iB -zJDz5Ru-Z>~+fH$VWPdd~FVQ(AT}O25HPC_wANYArttZij2ISLx>m75xSQO6+R*;0g -zmeuq!90F_}HX%kFZpuj4@q)SDa3k?+Bb2PrSZjTt%acFjLT3$4HPduPZ4Sfv?#~)_ -z*x>rvxpNnXh2P;_1YzBnVcqa9VK{mn1MhEaK>}|FhPXm?dB28(cqh2Ag&XIAnbGh%w38mufD688Vg0{`stk3i+PA1e~X7W%o(N09G -z(V+dK5Ra`6>fQc$6V4g$Mc;jTrbmt|ZcfPDi&luFxnBGk{2GGnMACo~C5VWy9A^BK -z%9O|VK>O{=o7e@%H==p}Gh9?4J3)S(^K@|@-bpGMlMM#a6u}N>;hDZ{$m0w+?{P+i -zv!bb`WN0Gnx5bB0s;!iJeK(?O@&xo_Yr==8dbs9N^gw0u(XKa5#%g4gLt%5d9^x&bUp+ -zI*CuQXb^F)LGcsTq00ke&-aZbA7b?Ow}kNZFJJuWYsoo#JJ -zd^|iHd;0^2Lk8)L=de&2-C9OWIvMMW>WH|w6peAk$qJ4MH%Wu;|h=~A6+4h{@J3knK0*pJ@vag9^60=vvWcI&Lb_(VX2 -zy)N7VOA=(g{REg_f)&_ekDo9i1vl8j0R0zl47}1}4kDqz)m%np1-97YCtxX^_8Eb1U&2>fjdHvFw8)9n=PT=mS{*wNJdpIN5Au>lfU5v4<160teocH-d>QHxOk-7@IW}47m1u$uA~w=(B0jA`kk+l2DCPaOxmP~ndvI$ -zYkm8H%IFn;s^>pUrvz6NLyr<`Ro3Korg8A+&kfO!G6vn2h>XJTf5yvnnk!b`Vn06= -zO|u}x(#U)>eRZq|c{Ep6$&^P+2{n)IUvm+$hJWpRp@dc$Pc5;};;;?#x;>0!Q&lV! -z`h5GsX89Y7O)`a6U8!1!!`XBAGrQC|6pr$y?Yi~{n@H;dTYvsSV}Guzrbl=`^4UoI -z8~S7M#L3iCl4D&LZY7p{pxhZgK`flMwzluNP~zogXL!BoNYnrwRFOn1!FLoBg%hgK -zT2%$)cYHjmbW$l?<>3q586J5ELJKn1OZfwK6zZEGypC8YxWSi_nBA+Z_&{j*y_tMb -z6C6(s<>8a1YQkTymwXrrI?Xm2Z(XHsp-_~6s;*Hc@MZxKw?mh=jIMvB--jM9zQDT5 -z_##%J(qN!>z*rOmA{Oc8*IOL7NzRt42R1uBo;?F>^ndx{qY!eko1xoqPknBbx`jeg -zBK1!If?!CHwgxmCjWr7V)0^wAxV{-lm1HGp@U)MCwN_MeX3LZ*jEL+Um3h1ahneA%41;uV#JudJYWnF4<o}yV;v9^YzeZ9DJPbxV -zCaJz8JMuzS|;y@^GISocc73^ZoFw_q)lcpJX%zS -z?3#&5BtAW>(BMlU0{VA<|F{5pf0gcm5ueT^9u0&(YN^<63?O&=!S{pn(` -zLg_%W?ebF_1IK2E8}fXKJRN7Sd1NEd3=zE}{Ff-55EeRtg*n1;E66aMQp_*vt;2W-BHy(2b;Flg4sLL8j`MDJ -zAbfu?@{0+Il12eRII46kiNKmt05>iU=h -z$)Irsw!hHw5wf7*gjxln_O`c8!(m4}pSsbqKLIVrd=!}5jW}+WPlzQ;+_e-& -z?Dy<48J&+h3*@LUmFxqzh_g>rb^`iEl)hiDf5($dZZJpaL!%i&d@Buf3+M~(|w0IKfQ -za3X0Srk%nLvE~Ab9|gBtt2_H<(fw_Zha@}t^K>=dbE+8{uYX2|#N=bmI)Wc;T*rwV -zwd5A@i2kamPB6hHF1AG?W!pUo_~vz+3wdlN<%QSGe!5}^qJ59h?#udS@qUf7 -zv-9ZWcl%ZgYEV62Ov?klP4Ypq+COVB -zzbpQbKJ4p#FTFlCeU?M~M)FWg!L^__)A~q8ym6&0c0f4_^d1Qsf;q;YQPHwFTKQaY -z@}^_vfdLrw7oSN5$O~22BEUPFgd#kF2FBsIH_Toz2Nw=v^=tZBu!NT|Lp7qp(fZ&&7q@7C0rFJD6; -z(%|4PztN>6GF#&@{I1tbNIIaALQ8ulFL8_Y1vGk-QMPKSZe0HpMtxgqkoct%kuq`w -z#x-}Cb*!ytPr?%+STtAMUu{{K-N%@g062$UWI7UOQm3=mc9wknbhD2qEj-!b^P -z%oYhuwx~lumz_3B^a7bYyyq-71@Fw*7ULPhNJocwr5CvLRsE<~sh>maF=R1p!hO** -zh+7MfH?17kb@`xEls`270@5OICG>$(UstdYt%lJ^wwiJK8I1@$5SE2?UF-^CtL8@; -zs4{#zGZBM@8f^QW&S9I{2Bl9>kdJkdQs6??R6c{5q%l*?6D-aNSM(>Zc4);q<1&7n -zVSb1AZyvYG&77Xtb`dpP1hGZw+U_-uc%-;be&gSUcbi*hJ9V!?LnI5O4d&1TOrlrE -z11&b|=uC!5&O5GB^zm!T#ncJ-bmy8|`YuXV_zy3)jPFmR0m -zFLy&N`z42~p5XU|+fn|GAIE2AfPi3JbxB>QXQ+7$3m_ug7v}~qfMAh#5*_)0mSKO^ -z)R>_thix1PNC=^T>X5@o5Ik^s!>_0nb%0+Qu?l@fMu||fRMI8(eq@a06~$a6goXp4 -zTc(!CW&GU`Z?7*~C%0!|`Po;Y-B>bq8(=^Pt0w>CW3cOKf|^OmN3o|I)zb~mlpR!VZRWgf3r$DjB6U@% -zJ!v9xOZ<+LBarT*ahaknq^miC#W^ANPQ%<$&RHDpEBCU_M(sbvsugC-mYh-fO{Sw9 -z2eEARzci;On#5;xRA{kHL-zc9^rxh(B6&XXZ*i0bo|+5(tR}B*i$>CjH@i(J`<5N< -zm*!QawcKB`2qVVWN|!2bmCj+qMz_>lyQe41Uc6GYo8|ZmgRouOWH<`fPtitAzEwsVe{gYe@!;OmfY1hA^J^GP2Zh7jc0#tW -zV;K{f-a2?ll{FjAo&kmu**_ByBXvrN+H7%pUgwrk*v>}T<%nfg$(O1#f`vAf;$Wwj -zK4OU>ekZ7*cXG`zK^{1Jk?6U1Z!$nXMaDUqNo}Oc<%5yn3pWZ=j1+|nlh9DXMmgJp -zw$>=#X^n__>Lz7RpGg`FbOM{jMF-I&Mx~Gtq{nwcJ*VwE0OFOdSNksknPO9!AjUy9a^u}; -zl{GfA#HVPd@8C*|vf;gcdLXrJL?MukrGr%c^ -z`dR^O=T^5*G@CU0fpX=d2?dv}l#Z}rvrURI+yrK9#ndWZg69>4-LW#tEa5!`s{Zgq -z8R@zhQOojaXAAXjJW6}a5>uV1LhgG$u5JQ_EBF0C=A-S5S2BuoH^CBy68!ST^VMKp -z5t!x0xnCI*Lk$t%?=aM?bAC5Sk&8&Qiu@hZj7DiJ;6#WZd1Z764c#+#;>O(U9%lfW -z>suxqZ)SVz&lYoFmEAcgM7u2vPU$2e-Hjzv>AJy1PeOk$DMk`K`~^i^seLl#HX2s@ -z&vS?_kECyji(-+eKdk1750r)$2U(RhTgkZT@l<$kC`GSck-TzG(h{pKG1aJhxkqgZ -zItykNw;mTU?xiP8Q;PAKW4yNPGkd;&0<^_8y4rHh6AzZ1@@Og1z$t3+RoVK`LOEWpvj)dqZ+bn-ZI_R@g2TDm -zUOXS$8{AioF8c*Kd%YqEKoqkyqA= -z;h>9H=F|lLAffO3sj^3_YLHV~t7o60Afgf+&g?fx9El~tAP}$YS=MFe#gI{HMPF+3A4XgD2y6V7pZ8*{ -zm8;APEKL9wC2F|aO=CXGJo^TSmQpb}X_X3Im%nsfn-Yr)Ip(;&N*#Ay_m3?ila&Xh -zA6V?kP!$WD1kP``H7hg@QY|w7?54~1UuB*oXqD_ePJg`i3GPV0EM`;%joWPh;8C{7 -zYdmIemNAl|da??P+nTE06i%eXK303w@_~!CLz4QEZFdnUm~0^2U*Dh4GePdBsTQhV -zsihVr6*e(LETK(_Y=c5vXJenfn3=4BLe-LG|E6?ccR#tlx)pG=|6cC;SaBt^!li5R -zcPgX&c2MsDL}~N-O+3=a0$|oiwZm$c)<&SyI4_0A@|JEcP=7FY3^?#Of0zNSfD^&A$%$p{mSW|9&i*6 -zj(_qDpxvBQ=^ptttH-vj$9~Va*80<33lpe5w3*6)d5BABGb>2&T7!J8KM%t$O}n*W -zJo+7yk8gR<_bN{XJ|u{lon5UfZc>HMFjulERk&KL*jqG{qadfz)xhuQcg|aymb_Y? -zVYhel3JJX|M+K*)DQMX1IZ`*_*vfscZkpLiT)9gL=cKs}uA(KzRP<4d8#RxOLcE#D -zJP9@OB>kt#JaeOXaqm4Kc^GYiehxcy4(-(f*^`-a9<3OAl0lXjMU1hK=(Co4O{$8%UM|E#&*;l(B?QsiT24bqlr*B{Z7V`VuFjMMHlGAysOT^==1z=5qZQ_2R -z-1qLb)#p6A6j}B#jg`CWg~=F5uJg4=mk4 -zMbEFlbNEc>OXUCT5piF*6@<3E+@D1YQ`=LOmdxBa$alJ^s;X9Vnwl%91RCi4CyD~~ -zEfY~;r~^+zF4y_)m=yu>0s3+B%|pI?8RS^ct^$kP#XRzE>S#R+#~GhIc~p)Cii4cW -z9H*m(D~n23;e5HIw0*7&$Qv-cSkS?#GB%E4^9a4Zdg>n0VB=s|P>wkUFR@1Py;++p -zX;6LW6tT+67ZSct6f1(Z{;9<&8!$Q%dsr@?heJCLyu$kE{QNwMcpba!S7M2R5q^_F -z1m`x@%z~KAD3f^-kF`7BW3BU>kYEeLw+hLBNDUxD$O}Z7ySX3c -zb)wd!i4k24wW1_C2@tbyw%f-8qhJmP`&caiZ`w$^LAjZS5Sn#m^9yX>OCkC~g$Cc7>RooBAs^cU -zIlTk#)OXQ82-Til1rliQ85sNCA>X3OzZ4b&8XPSua_&2S?i?lbG}vKCBGdB|nXS>g -zJ0*+o--w^syM8BpvQ@ycNTP2WG0U^*#8-MC0N=cB;m&`}!LXiv%vI8XM1O%D865l( -z{g6XRuw=jeOMjz9WK|@yzj!yA9i}KA0|SHG1bi12L)S{x7e=_kAN~FN)m7xbSP^arS9Rd{|t-bdQUEl`8{54zNMvQ -zmVu~1GPeH>P7JxwZV*CX5cIQzmo3E{siDMziZ%E7Tl9Q4KN4`#}D9_*vX?k}pO!=)gn7_4Bb4bJT -zqDaOnV(7U1_j;to@cwADU9mBc-@BdBUmAHSzyI{7YGVPi_y~b*r-e;$%CQnDe?9;8 -zfw~{4mSb>(|FgeRQE<@@i1>JZxfuACaFBgBIQO3(xsqo~Se?tnEhWOPgi|!6k69%H -zBXMEw6q@;gX1q%5b}P&*(QhwjwHm7%kJPg>aV1XSsKm6t<)rE6*j;x$hUQ|hu`kT) -zV+}ADC0AEh_W-HRr1Y}-%^FExK~@Y^t(ANZuuEJ`p#^k<`-MWnN77L2@X=9jV+>R; -zXOQ`#-WMm65hugihkOgXY4OID(WpNU{=B$ZDs8X^hCKKCdranviTkKK>$2J_;-Ga6 -z>WBEX7GD$0K(CoP7J96eYCwj_U5&HrOXJSWm=N0MQ^#7X5>(8zV6XiWLH3_ZhnV9@qF1Eb95#jw+CTK -zcnC_X6?w!ouwb8!t?ZeXbU*`_*tn=L1`tKaPq~o#XH-LT(pdaeEr(+5o7_BF^YP^9 -z=s=xqrRelm)Z^rj$VCV;RnXkG!NaMn=)gAL=kN77LMYwzIqFtY;-;Q!9U{UKkl*Z; -zxmwdAck=k)YYlsT2UM!0spVa*x7IFL)Qt{!?hIJJcZxQPc`eiw~~Oj@Tz_oM0xtx3Lb{5kxu -zyBD?uz>WN#g_E*U&crG80;MCX-DnFuJuz_nIeOw6$6c?&s+F|L2zU?5G!ekeS!llo -zFPgW-3Pcj`}O?5W?ab_h%Gy97f=v~(o -zy&qFFhNcAIGR5-l!~O!ti+&6tBv?y$VCZ!G*COZC^Rd=v3DD{VK&YZV`0rM0q-=5@nOTtcx@ -z-`GfyVTF_)=xoTY-xG)BHAl-#;@k>0Kap5G)B~X77JGh`U;(W#+Xleny2|+?3X~v9 -z@j4(Oa(GxV=hv@n1U4Y(PY6pg$c&Ot;)efq)~zTw>;uHy`pS!hYaNUHxEYhbgRg4R -z+}+}7o`g)4OPEQ|;tiYeawTA$%HmQyClOH{QqjoI$3uxnpv;6|Hoy*8NC^3e-^$N* -zqqby_w*0S5T>t%`@v?z_`@m;FByBE`COSJ7m_~uq^-Bim*HTzq_chCA9jeHpXN(2n -zwRqW7h)`1w=SY~Q#F+#wWc43wU)ql>D-{W#MMi*+Rc<(sqj$1IsI?*Vo~~JX4iGFY -zSjVn{Ia}(<$;mhGkK6li&$laGUX5+PgyS=U#yks+rN3QUeb1{R0P)Mr;duDNP0Yns -zOl80yG--mz(9cLJmrW%6skc}}J*KYlL*%B2MMfm>8W3{uoeA1tCC=;U0l+}4z>%rz1`1Gu3qlk(DUqGWSub-M#qTbUB+d9M069OLgJ6ct8Id?;aM)g-r9s^V6BrQ}Q;SCiP`udh7DC -zQX$nG;n1i3pom{#4@R?{E?z&>^3sL?I2rH<%HigVl9la73e4N^TR>PE}F -zsi3VDlCxI}2NOm!ndIQSbW~gNZ4rN(jki^a>Fbq! -zqTN5 -zzb`nx8&_h%Jrt7lQxR^o;6yE0jUGfj6BHagGKnEIbC?*Yeh-mN_p6 -zlPomN>R(3=k&0Ki-xElR=54S -ziifTvyozV0-H|T?}miG^F_wtBpw#IDTI~O&zZ=pp6zI7~U;(eX9v~ -z%_Rrklp$gbO-9{o@iq>QY$8+WLWjtqUprlw=!9l&&i<-B;;B?gDuUYF04x={Q|PYo -z11qyPuIW6^msVN_PE8KdAMXa}bHL6LC^fQ9sh369#H1cfF?JZ}v`b#V$&6F1HA?9- -z8rMp!9QAw;KUupJE(75s%Q_j;=twh?gcLwR?pti!=J%3LhEmj*cmxEL#xOjNHpVeK -zJkF%}PF#r=gweO>TUjCt`~eJ7()chG!YE-`x^-8vG;ltjSQ*{>Exm{gthe@Wqr_;) -z0wt5sLc;HhZgRcM=_rjYuGPk6qTcdMHcs}#u#-NnrJ>ijEn2POpi%bVAyH$%NC@JW -z!9x#~LZ0#)=w{X8oW39GR&eJl^`<7%yQQ1IMRYe1(f#2jGXHCzX6=QT%WeN8>DptC -zHdSdtJVzrAI(JAmUV3k0>(|f-Xp$15@*N%7K>n%=8xkhRkB3QAUtf=ah{(e3zoSSq -z_gFfN{zLz`jCqlr&;1O+r(+F_Z0oUu;MXftO1`Y -z9;O;>OCXbj;jbt_S7jVfllzmVYhq*#nMM~j1j#8VFg%#?vdErxSYKI2XR#z#^jrF| -z60VzCe$K!`P7W(fGZ`zDbu=Gj|Fluc!xb3b3?KS{Jm5T)ZILV)F5q8zrZN3x1!?Fl -zj24#65txQAH>pypq52gcF^Lw8LkW1LoMwVHld&c-soCEOJ`7#g5|?z#rkMgkK7BD? -zv5)5fIFMR6Y+7b6;Ou);_P~PlRc2e$)>HPum(WG>M&1%61LbYx=>T1OuOHP=A_2Ml -zUJa0_6*NB&eSM@;e}$dm67YWg_RVCo!)>o6Rkzh4GG20Rk8#RK+5)kj -zy-EvI3s#yE&SmNou7&*UrnmOiQ_-c!M98x?rSX}WW}0I7mNW&~u)Vo_w^FUmMKUp> -z8k)=i)!=z!;!K+sl(Lhz*Vd$PEuCsaMon#-vS>REEy6K+i5a(<$=x(75fa)xG@=%o -zR1GQOG=s!5g(EG{JieFH*|kCh7=CEGG~xLSIY@MDuIiAnc`G2Ge{P@B(m6G -z!ibqfOA9p9!7d%@C@Z6Oj!J3yF%OjokW8F{Y}gut?pbEsRm(4LL??RqN~(!1fsK#O -zx=08kW?ie)L(K_4s$=P~flB)?RT~0m>*m4)K}Eg&^ysOF8lN -zUHK0Q90oI&{$mRN4;~O7eZ2)RYWiOSNUxax118K@axIASH?!$hWNTeE-m< -z9|d2NgO0N~GYHc0yR$}HApgS_*(Si(CRarIKe5r*$mNd^46r(X7=_aLFxEIYsbgvH -znrzh|J#4IY*379ZTcw$}tG6{QE7PnE4Rz`3%NtHKG_U~aaSk@Sx>k@6ej8+~c|Yc1 -zO&By$u_ANpr;D`5D&%W#Fdl9`BhvdZ5`UZwLv{1Hpy9lA>ut_To&@^KV8eBInUrO5 -zh52}zCbS}L24&AucCm_(e?;?E_ef|R)nd$k+BOlW94v|UU~blRLjQ0ZP-4r2%|3Mn -z>o)c|#p9v2Mo^cLhvg|xC^b2rL@3y2qYKOs?@M}`_`2q==9(4=kTk_PZBIhX-PBrZ -zr~4n>by9I>XJ-@K+>o8|G;Pd^cW)?r)m~#|TJhd}QmeX{jlF$FjtCHM4zkU<60>Zs -z%Hys(I^Fbs!^Li)<*(mdMDF~twQ_bC9DMnUdoO<&F-3^A3(9GW4BH?t7v#5rXa(*RMsaFXpk@rOtgnql#(8*wa~=>H&U=;wN0Q<% -z=~0Qf+>{j>5oC?u{)Ajpd<^k1GgPzB2_X=HLz81#(ra*Wz}OO-za_H(wqrv+ -zz0y`v?a{P}lFJz=@BUy(A)pd~b{ghG$JJ7r@AlNxR+>kt6nYMil7}v99Ja?<@UZ3T -zeP1&kMRSM{5+R84Gc9j#ct$;ly+^es_n)lXhG>_EcB%`8iYCWLpCv8)3~8MaxHrGc -zWH36`!Flt6p(JJsBEPqrE&gHZ?iZtxyx?@fgPx*GS)go(Nf7>mW01|;SB);nF)3s-o4wF7D!)tc}@L$K1~NQb -z#Yr2Tunx+&wm$nlh2CtbCg8*b5`pf^Y+pukoQ>UqK#>9GQek~Po6Bh899xq^a4oaN -z9sDuzXNM=T^ExFYu?oyxI-}8y%D;slDQ*$`e5+$KKq!pF-*Qc6*L_WdXk^K$IEown -zc`-GIjJQlcjeh%cL}$EWcnajL%v-BuW@70M(BzzY-<$NJlWQg2rNIpwvZO(rx6c;G -z_UBD)7Cj+GP^Rw?)N_Nikx*qcIPWa%MBy?TL-6TWG;|5d3z|f%7il*;Ac9f={o-sOWXfH2ow& -z+F%t%kw65bbTBi=kaCFWiK~y^%2iyKohma@H`Ql2SmxhqN|;zqx3*C&8_FG(8wPqn -z80VlP%Gr)DvZLLlMf_OsXDo*4wm909tv4{~9yF8NS%e&sJ#dPsVWzk;(a?)XK|KjU -zmKml2h#A~>%-bFxM<7`wSX>`I?z8$Ca++fy%HqqV=8QYYD~bl^Hz_tBVxFF`f!?T6 -z!OC4>a={OOkbTFV#ew8k2GrG${kNo(rcXXA_NWUqI*@?8f!7jnu3$bUg%u}bhY5Q));;cCAc0gS -zHeTk{K!dAfJ6}@_zTLUn#qe2z2>ZdYkePg(!A+9v>R>`9$hU~PuED*xe7hANwC~xc -zzMc7YMmZr7Iy0P~w;nbL>dml8nV{FL;+xs}qjWkGV5~K1I6DPEC&#K9z5E?@9vBT9 -zvo#L&#*9687;Wd0D#-M4&3F8(7sFq)qrj$;8%`og3#@6+hSB^|^UtXtP#SOBvdY^G -znH{rdVJq%P=QxzF3KPx3etK`XD%|1rVH#OZ35YdYtyAh8`vg5MWd_yI4)jPAmo4j_!3e<(RzCocf`Y+$BAs988hq->eMY}S?z>|#t_c*3a#|wBAi{r! -z{dW0rO)!J3t~1!Um(@E{ATxo*eW!!k$}$1~;aQ@PPH8`A%_SDxVmA)U!Hw)$KXA7$ -zqdYbaY15D(b-OI$URl0+-TYf+!wm}Fwiu|ApRr6t288`7`y!ZbjuZgH`OF0cwYAez -zqSFt2_caUMO6L4Xk>1Be-C -zNHX4bgVd8eU&h^$7@$FnL%%Qp$e+fZ(4dAotr#y7!RrZ>u)-F!F&*jOE8kA5rqU|| -zkg!kLmDxaol3FWgZ=YGJwHYE#cf7j}8z24RotEJKC)?r64}@x}^89m-1nf0~ -z*_bz@JP+Ml3hd*HWuOR@sNVh74L-Sw?LaYKwKo+rvy}#|aFc!~jT1o|KFR)cI+)Bn -z7Gg?S>|0zfR!%gT?WBBV*!!8j6W>|lJse7F&5>m#;ooWbRQhP@izf8nK?3n;AClTI -z6#M340iQgXluMzeY19}<(0FQ=O$wq@ql-?Y9&<2A-S>4Nw#z1Z-(eOaL`iCMI&1sAHP4i1wfU%}{TH10ti=qYU -zDz0-eM;$$6p`VP-jrsMCM}MB&A!(m3WE#f9F_{oZS)?8^0-?^g11w23S(X*2v9^k* -zKU)$N`g+?WLff<~UDFNP<{vgF`ivNrY!#|!D3|%nvN;axyiKQdEH}n|UAvW!JH2@P -z6TzqIA6}zL<{b4pMQp)4ffz(REKD*y3@}3^xF7ui{>6upo0Tm&dOIrt&>JXx_VQrn -z?-nhZdK!u;m!%$urT+S%i$tA>aj?l1`%j#jH%{|kdYyAos^NAM25jH<6TePW$nes= -z1!HeZ;$v}XEv4u4(RnINU~U}A*?wwCqU9m|k--nxsx^vf5AeRn$pVh?0Mnuc`C!uLu2;Vg{7)wfw`U -zX;*Wa;BHUq-TwcZ=lb=LAJ!W;9=uX-aQwln)6svvPf%SQ<1JdhQIPpzpQJ_KDid+% -z!(xv_|7G`-+M9p4uk#~(Mx)cG<|di_EPs|%wf~Qb+;nQM%q9N4&z7FNB6Z+G+^+MR -zj)|=QD8BER{dSeRdtd$LH*1N?VC!qI+*y}-;)|d!tvt|0N -zm5Vlct%>!zH1~C#{PXnRXO%R17-p8ep7o3QUvcWms)tYH$`9TvKIF>&@BVzZ?VI=h -zpErH+ydwvGOs@R*Hs)&kpXVngrCvTXb;0-d@xj~oPM7_l|L;HY`3dlY6p$IBU;poR -XXyugpZ1#qMfq}u()z4*}Q$iB}^Bg|U +zcmaicV|1Ng^k&Q(Hn!T>_Kj`Zc4OO48rwD-Gw*(Xv_UIGaL4*?7e3`t5-R2lSh^xqd84Cs4}W^FDQn9zijsF13M{zVR~<`0dB +z;hww3Rk_uLO*yyZ^N(arMN#SjFcHEi60E_fZug`IjtJ^LVtno=lKj+Jze{_WszRIN1X*HUTCH>C_wc;+D)6YYT +z*RWmTUi`Puu_Uwkj6-qwu_Ue*kO&$%=o%J?6*rej_Ock3znkGIb6 +zWm&yS2Z9LS7slFgUx+?ilDgQBdj7`ruw|IVzJ@wV{&tD)G@SPTMW@9Wl5lcsuU~6` +z7raw|%Or|@Pnlh`7!!rA1H$`p;zz}+92Tp2bFmKDAL`nrC>)<{qBHso +zvJ6|o^vMxL?frh4XZ`3WdH7s_NI0p@{EElbnX*!yp;Vtx&K&w$&to`sW +z79>enm;xWhu;ZKKIN}-h!eBKZM6j$9~*Q(SlE*i_bHS0o#tPY +z5-j+ww|x>h9%`RLUixM!e%f0qVAe5GH83X6?!#^_j-M@lO@*-aD%NMF2;Hg^Wgh@}elrPA3o_&(- +zeNyws4es~%;K1o+pfG(Z!G-nFWzl7)ejRNxY?M~uI=I&MYuz@4>GLH*ptjlQJ`LYr +z*KIIVzBhKHIDwe`X2hc@gsdjzXxX%b<_#kc$vIHFi2)-XM1=fs(`g?0)M{lcJXwp< +zBgIdDXM&n-=+_%;1a?sE$oeN{r%w=8tFfAlQopAk +z%wrVN=r>)oZ0w7^M~Xi~qp6lEaABgF(ck7V3Un;@cg|ODuD7@fw~OZ;^TQV +z$&4AiUj}-4;o`6JV$Y4C2G +z8hVweUdzl78hWzD|&J_)oRr2JdJP +zA&lca);^P(q@hQb9-kqNXVo9An7Q3NoAtyRQw-@JUDD$oluryjE +z3{zzbZhStP-K;xw@Yxf-B=4h(p=4f`k8p2DH$>qQLPR!szD!2|vJ}J`C6=EoRwG^+ +z;`ZDv1SGVO+?IqSxpxSM^_V~@2E+~dZQdl+oz;TP1MX+XXwugMy?Z5AoZ7#R33Y@T +zM)w4;9L0szO3>6i#4fV3q49@wu&`zcvQ!d8!m*dpn&7pp0Y=;QbiyOzhC7)Ki7tDt +zXaIqysWqx53ZgHlO)|YRDG**$7&F{0a8VEECY`3;yx)F>2;4Xr&gC;Iqiqx;orWkF +z8xk0Ty-mK&z`^~Fbs#S;;Qd@1ZFJh4R`+H>Wx$xgn>^oka;w9~QfR>rS7lYHG?D#o +z6Jo`Qg_-DP +zX@kdURs~L5?afF*73QF!=HQ?vIysP;FNCMBfA*}*&%$eDHh5L|y~D=C^v8(wdtcYZ +z)8Q|56BuZ~3~KpF-oKg|5Uf@Ac15Z>sP<9hpm(E>^cgr8dMxGhn7mnWA+JPK+EGR; +zCfK+V1&Xi1M6CUFIA+oJqr(aF3W_=ph7h;IVlqq&xJ=d(CqczQwL>f*A$gJW_|iZw +z&>!^cGyI)UH(_%jFMta0ci8K;?^D#C4_`@%@wP6R4qvs8y@ecdj|*ia7Exg3*BpG4 +z%Dqav(-_hWolzv04-3Ygs)Z~U$`R?hQq2Is2`RWS%z4?!GF2CryzMjCEFg_Y%K+yz +zG8tm;0X{;XG5?BBT|pMZ296(fGUtoF_$Ryrso&s;Cc!g3a;pYOn-tjPvW+1)iAQ)I +zaPyG(wl0MZUqz_Z!4+oEh$t>QIaiZ+J1|fQdfugliOCAg+6D!~3<-k#gA8N#Rk3@5 +z&u3Yevetsi3m`sm2Ntt>FV(PfME~wR=LFu+2@Noy&wr###hgP3mjy&H03re#97OQ% +zsZ;NtktNoC?s@G44Num-@G1zw*?jMf)dA`SWJHyI-Lp=m +zyv8V97L8$~?>Sf(&Ee27TQvEf=-_%~EL56_n`*ZRVS`=4Ka4&HGjr9P8e3rf;8BK& +z&0s~H!Z|V-mPt9vUj?5&%Sa@;XK~`TS$ylgW4|1h&I!<9c6_zoDdR2)FLErHw%Sow +zwc_2ZKizcAMchMvZ^6OY8)uiUt&RwA(`3@dzgihQ1MSrNi;ruq-C+?oVa@U0x +z(>^4ei3Bedg+!LX52G(u@W4P&3sdv45%OawU(*aQat~OuEf?Hi6Zi>__qCd)nw0_j +zvUwA_6WQ5tnFsl_AZNz8L8L*=L4?0A>inj9l&C`AC71u=H +z?bu{Q_=al@1+|F&El|te2eQB@?#+g(D(LjFx>w=0X;CJ|CQc@tuin_)Rd$KH$Y9P9 +z${MAq+Ns2`>_SLAfKm9~%?U2bK6>hiDEbdUD#NMd$hR*wFx8TxWVY3Za +zM&tRPhR$htT-*KlZT-SGBy4YD;6aZfAz^Jt1`=ABifztn#D_;u)2WTa-Bo^EKL;=o +zDc6Ov2x3ybU1B6gkFjv-UvyFl^(EFkIb4ht2Z(*io4 +zW(6^Rp7OMxVh73mYH?bkbxgXB=+TL>U^8OY>=P$oXPkGAmF?6#80T +z+e?24uzuJC8?nCu`7)ef&Nu8x+`0%wOB9wmZ^(+|&$!T80~3uj?NRH)aNhf~#vN9e +zem1VW#bKd$SZ4ufS0-pzoJ%P7UWdT@8yg`1+kpYLV153t;UJy~P8@7sO+#{ePIXcSgw}v2XayA<>Jxh}D)tMOGRgJY0QEJs` +z{>aB;ssVeqKi-6L#(PnBpPuOu<4Rf*GWVk8BdMCd} +zc^_!LU3n2YWBEk1?0<%f@MkB;t#h0%&cixNCZn@Lft$eDVl6z=l@Ga}k<7cF5n!!o +zXet^Q3;AyG!j)+$=3U>7D5cEf)=YMZ)jSZ?)!6EoSa3kU!3W2Xn`K`PqR|ML`Ju!A)|K2`l1>ErJG>o*qIC72B&jHYe36od@P! +zi)qQ9Y7g*>N;Y4;sSLlPxvM;q-Tzw2m;Zx=x>{mk0;Ed5zA?Hb1FrDGc6-;m+iSFU +zc22aC&R^-iyw5vE$D?GWWo7A5o@@>d3_uD92sGM_-tlsdQ?ZbAnF4LsSxDj&0TFgO +zFbB*@;0<;Y0es>tB&~M12_up)gRS(Ce{seFR$9$~MC8~S%gCTV+2AIiH`gndEW2~H +z`z|RK5KuxIccy|!;Bkm8puw0EcWFE{ij71G*o4( +z0~y!3%z_nq1kdh3x<;XVQS{_v?Q3|H1so1Z#CL|Zm2Z&7-mTO?&1?U-oogOAE4Cm{ +z`d4o(XCnWH-J^hx&?7X^xHns&B`u2*skUy`s~w=0252bVaZy(}U?e5?u>fG!UbYaS +z4Gz$YBX|~|U$??YUR+zxw2g5F_OJB7viI^}qx|ouEswnc0o{D4T~~|912EVr9)4P& +zS=*@uBmgy>GC)sz_8A$Iga2y-R#LKP$zyVe7P=4Vrn@Q)Fp6mG;Nall=^07<{OPT~ +zPDD~5M}Py>^H&ikOMCrXaXjFMyNuyNg$gXaPOE4z3=$o3Jt(guFuvAQbA?*MR;Dx}r~+zsgJ +zzCtQ*$r?UAKNl$E39K|(pdcV17*;zU{VtG7{)QDicnC&XAit07AxkJs2xbNxkEh-l +ztI=-hZ#0{5e0{huHk5pMKFXUdk-_HT=8j~#**>ze%L-Vq--ELbc7OqlEqqgfDL$7| +z^zia3^m~7il#>&4bK{s6W!C%o9eQ_nw_LRXoq&)qk2e`~Carh!_+@C+^?4E@nB?8v +zrP(B~aF_-3_5wx4#3EgX2f|T2iDX6dBot9e+}zxz-+7y;fop?^#LWumnJ%(ER<|F> +z44(0)x_-m7iZI17bV#w5<;|{V>IZ-R+z|XI2d!L0M$z{_~PzI|b} +z_>I9TkwT-USfkDEyuoB7YJe7^SUeW*JCd>d31w)Viag>w +zE)Hcnu_U(A@CEh^w;UM0IVsDf+yNUB)lCpiM=a>2dMSVx95URpuHBLGh>h8fgM&77%eeba~6*@>lA8=;7iEw2QP4d^IvP +z8fpiWc?lq5kxp*C)nS|HY^i2ov(x?A!{1u(mk%xyJ_nmAsx{Zt=LV=Ta0-O}2|y4O +z5yIAhMw5|xp3lvw|Ps$0W*KZd^Wlj=W@{AaG=^es3_){Y~Jis`IYYiWN~ho|DLil1qRD5 +zN6xAlvXG=U-8`VKVHr!k-;5Bi)EfnJRTtvY$;jR$#e%~lxMV?xboY;JA{IT_^y}D0 +zw1mJ8tVoSO-(}absB6M8b$Zqe)Ok0$OkaA#I +z48@e8TAlv;PmB6dbP|{7<%qt@Ea>I;PRL4)=M`_G!A40Y$Xy1Mum)I0#!3<77H4)u +zI6c{)TUsy&o^*@2H9Bp>QJA#S8$`zN?+@z^IIQL|VxYEQfVw~Oc}Wq!FS`G2T=aDu +z-DMYe(1$x=331oN(i#yV%?Q)lcY`}FpGRp*74@@$fX%pE+dAGOh5QRhJ&mcaXOhk4 +zLi_pirw^Zws;d9n^#IE8T1ypZDX|crNABquU?iL2;Ql%4Vg5cNBt}OJdbLKnEi|`g2q%v70%eM&7 +z5gdFefu8Ix3n54MC +zW40SGT11ajrrm5AI24T?-2$|VMsU%VX}AMmt>Pr~B}#An{>%QG>_1FQYV^)CExzx2 +z&7E_9c!fpiCLci|F3H*eM2DQQRtQp4>V2RP=KX3ZVw#OXuFxj$VDmM&HQD{*dc7301976VQyI69%EFvxxn>qC&Lo-`%ImvM +zCv>AXKPcD26Z_;m`1pw)uF6Mp=RnShU^yM81!?jbl!v#-kSa#RLhSOG0?yp1YB6Jr +zW=GrO|0zIRSHiH?DYiO+$EpdMkwz#4I6V(J12-W0+dAo4J*?nDQrFI<*}a92Y%1bU +z`RC_4tyg7>R(8{ +zA8*g?PWv##WoF+p0bJe>whg#+(1_+A+)9HS$|n?k;(r=Le*vR;57rn)2& +zEkD8KBSZm#3Drt?t!*#s#>0+yUNysIKRg=t`KSOcSHieiUP0z8F_$tZ(ciPnq_o~@ +z%-{zhbs{i7 +zt~8q8%WO|MF(FE_ye*bl_-@NcA!S9$IMb6x0`e_oNF!hy5a)H^H)5)t(}ek4a1Nc~FF4@f;5aO%aB&3O%B8NuMWWCzYb`d> +zQ-&3)G|5M|pzcLy>pA(p=?3&XKn+v0^`HNsS?M0eb+60BxF|&Y{?>MI^x``)Vp}1V +z;<0N$BUc(0=p=y>zD3k_I~ +zMC>T|rn!T!wN%lqT@ +z&Afsj|04$m&CH2M?F|6yeqb+e`&JWTP^~~z(;c>5;z6RuFKe)%3j|YzeZB9c)5E08 +zvX9?L9%?PT7Vu(RAIXR}s*=I*@Qp<*vA{&7B2uwdBH$_I`33U5di9weG|3 +zx-Iy`1L`R>G-q<+w-{f5qc<7ls}^cT4Y^Qi+meHXFIDgqkt0wpdBZGY?LB+q9&o`T +zd18L5%R+44Ml^UNbEw58BXP#{+I#J1$;VGO`#6Grd<=RWgP+T+ktE6H^>C;%(}szj +zK;wt^oW!yG4Fz=zm4zKw@$Wdo`VJm=879kp$F&$uMP_qiKSB4L@SV)g55F9Rb=3ocrK>iqIRR9n!X0Do*Ldi{9M&^sg&T_TZz~>`tbXc$p%%BI% +z#MahUA?U0t#2ZA4_41*w&52#TXU^_G4)$#uGOnpIb{Gs?Bge_xP|beH;cUSBec^gk +zu;a`And#3j5LZ)LALL9lQ0{$A?tzx&K6M(;#M))7n&`7KTkT>KvjI7O4?mTa;X`81yn7WAir6 +z^Dv#2{~#3{X=5gyP*2v`3yoLJl)--n2rC2}*3n8(L~4ohHzT6QbyEu{!K3q#&p9Lp +z?3#RrZR0JWoh5V%Au%m2?uSB&RO!i99khjDd#7P;NaxJ<_f>mYXQOtXqBZifoWn1d5WC&hmG;&Gv(>!l)|)selJ-m-pz9Og@*rA +z%Xl~n+gHI_Rjy513U_dEaq-~ZLm%H7RpVbREoW=Zu*D?n%JFyy6(v}{RCOy +z>_wu--o5bv-4rRuWG0oN3a2+(f)C6nR0%>9HdI1mB`d{jE6Q4vSf>>{@~N-bGMc6~ +zn=1MB2?XIjZuOC!s@-pN5{60UUw-L4f1L-3Ohud?4)I$4Y&#w^A*ij(1$$3|Vskv} +z#YKCOBnHKh5QN8fd|k)wI{^HZj_1!`{L&>R(m@P^tYk*J)5>eCrio9{j>kWLDCGrM +z*O<)utCbjQiH>aHzD!~>SNyzV|B?uyizaR*!v`(g6N5ks=aSqWHk#wzbQOx2Ehc(>s +zfl`oSK+EzLOKDeK?n#pu;5qF1g-8bXyN##%K`x2R14CxOh8w&P-kz4U}>3Q=A& +zwAa>sCXe?|fR^Y+S9_jW;=!_GK`1Bc2HY6Y)*s}A##+#}239~LV&Q~wL&4n_6^@vW +z;nGUYJ$5-C#kJr2EtD&Ty$t-H)#GyT->}39LWB1gdo%LwqR8{YbRBL*-FCEc5iY{; +z#TpZ~y8yolNKuWi&enqz%<*)Y)j#ff)9q1ezkI|N7|zr3b=T|b>+m?)d% +zKJ;1@L~w8ZQn0MxZS*{ew-;Ohn^Jl!+U{m|QvgB~tai**t#d>0E=CMjN*SZ+36QnO +z4NrSN!Cd>9SLf?=!Hjh+ek}c}ND_U`vvi9(MS>7nGZ*lPm%4(7(bhfuTHod8y%;N{YO_KMV}N<7D)x5snD;XG +zzCOH#WK2$4mAvQWFCCZW#F8TRInJ+=$6eR`V~dES6+!6-=6lkVCHyCW^Bb-$@=b%3 +zi%hxQwAp^EOp|zR61~UikJsM89qE@P3@X5J>+K)hO6K`Z$80UqhLV&|mVt3wQ#G4H +zi4>T}s*jr9pkN+B@=LbuMW8^kzEFQde*yOdnXiUws9u#OD8dYzm?0F`qCm7pBCNNz +zOJB@PR!5?2&9Zw_Jg~i=TwmStKiYq1_@$ +zZKB*^u}y2o({7rV#Nl+8$2T5 +zthMF3X`+*;4Q-~&-*4NzrU=7>#}h=jB}<^tsAch7Ac~Vq;V7 +ziknpCHOP}_P8F&VE%6e`WG~EVa?$ra`knKZrYWbIZ_w@4vO+{B!(Pb&!YhY8pCfe= +zjxF8x>Zh3;#gw`fu})grVJcf=Ohg_Xc9m?(57$!NXQ#N%;Q{V}EjtmA$m<@Ie2(h2j9T2Xq=0<2R#daW&$ +z85=lCIqjn+?h$SF4u|?#DOOKg9>2c{9GSdlh{<(WR;Mb+bxH>u95roevUiqSmcdG* +zEL`{Qv+mA#hjLxuC*l?ROBgDsPYkDNU%;m09$2^ni=SVA=kS_) +z_h->URCbhQr89T-a-Gg9Dk?P`CT8-=f%@A28AYMmma&Ks#DNDsr^|eI%nHBQ0Nps* +z<{@u^G-9krSD|^{Vm?_nRkW_T!;E*n95To#4sxn;9FH2W%&T043S^Vg_Bk^^&J9*H +z=-^Zd6GYUG(CMkA?hy<&4Tc5fn4$3ys+ZiGw!07qHH1zPDzAJY;{8Oj#B1-LTAZ>D +zKqX)c%j0#o|H%z2zdkxYKaV6<&nEMgP`q%2&v+2dsa++rFeWoOnf$VkCAY6|8|kw{ +zdwe(maC?oeGlx#HVClH?)W&QZ`+=l3PIeQ%9cb~nWxJ9)YD|MPt`v?0-3bMcbZ<2Z +zG7xSnH{QoOr#C@?R{C$168|JMfCxcPAVuEhewgQpYO@AfbP3Fw+|Vi7h~L@$6ydj5 +zyf7_h9Rp$0Gii0mkT9xddqw>hIVCXV203~$D~swIj_)TV=zX)@-tK6Hb66mM;EywH +zsMV;{!i^8fvae3b)iz7_f6$4yU2i-b%Bh|o@eU2$RD^G(AtWlyl0^8dxd<9 +zCi_xU0%&wFugtmc%-uOk=xMY?lR%{7BQRZ~b8}1<=DQI)v2*#3|70VNVV*?SK4O}0 +z-HEICfCoyTwy@{F=Ac>4KISQEgQLDcj|>j}hzn(*RSn +zZw&u6!^Z2~7ae&u`+{IHYm_vxJJ@RRZ!LoCjQ2ecK6E;AqeyJZxfuAC +zaFBgBIQO4DawgA~vN)BCS%`;S38kn@9kWOTMq)$V$+z&4nDQvH*{(1#N58$C)v2#; +zJW|ch#FaXRBNNj6mX)HNV{_ScADWB7#Jn(Th}B15lvrI|-2fj-=SL1AY +zQrI&y#`tyxRIyenc$G7)m}|d;5&h;8q8?ap1~7v{vEXIAhojO|^XI$6=K!f+>;5yx +zJJXiq*Z?mW;Ak{?4<=)9$$a@6Q*=1_%}Nx&bGA3oqS%{I)k3y{#DALAzrPw)h(FU +zj}8a8Xte($dBpT +z_ZLeg50aO#zhmy?M*+dS#c4NyP>CZSyS+OOi>@2;)lr;&A$)(OEO;kV+bz6O57by +zyW>9>Ij2^Du|A83(r~$46%S7?Ancv(6R +zJK?TL+k$9p$KMJgY}hdrTzyS}0it==hvU?8YM**7M}l@-W{&s26~NM6 +z#U8(RCX-=6Lw%{$D&=aKSfE%aJ<__RASP1DaZcJPva<-yi3NH#t$OuNk6wlp&CD~1 +zanJ|7AhF;l{a^)Qhr_9Bo;2ZG8=}0whx#r7zZ6W`Fs5 +zJEbvhZVJVsORu$w4Y1HyT1E4?Vka&kS*mSpBuKM>OAT~3W;g7KLGzfQWF~QJ1)H6S +zFCOXwP_auqzKSygLBPB}EH;Q1gXb@Wm*lZWfM<8NWGZM_*$8Ze)0+^IpqCyco5T+P +z>!edzc-RMsx%H6~4%a*u{&6!V2Xf)f8oOKEEtBAhvI#TkSv+Ago-TMSQ(2q}=S0FP +zL(1v}1vp6Ya1@zfO!}Dq3ke|~@mmFXu2dHEQWpO$6X$;c8V@V*w>NACSkmSKF-THX +zXc85Wu2(uhx0b@}vaeA-YhO(oJ!8ZlugSxzOn{tnI7h@dCB`UVE~EEY_ww_|qDlb| +zQh0>qvDy{uar91x0J$!N&ch{3*B*?y730`NAZJT0IXU?T1Oo1Zc+QnB&!+ZYLh%_v +zV;)6DQs1sEzvoxu0r{lou-yG%CgwotYzFK>vqr!e>KRehvaz@y)fTge`_wgV2*|2H +zVl|vbxEx$3ymn~uGqN65%FYqJ<_)*Uqs49;KY2h*(Xa?Tk7AFfl-xf>irJoUyL*;0 +z19&1GQV*5Ni~#kTnaq0ymCiLjk_=0q&=&|cG{r57n*6NwV6zJl5K*ED&DsZy8iEL_rr +zgsLXr6cN9-S7dCo0TeKI3ByoGNNBIG{4b4m4=LB^FstU0B?!6TBZ1v~zn%e*Xk=B) +z@_rySE6iHcIxSfbe^sRAkjZKFfR!7A5uNa|Q%HSV{);)`X_I$=Rz#g9)RV +zjIuDE+A6IDHt@Noy^%sCnU|?kL3tCMU12QN7688MFeYr;%^{CT)BqX<4rY8gFNo(^2<+x6~@> +z0Y;8%xJK3sk3si!JoTyNPRqf>i>%mkw_b{g-~}-aAljQww_S1L53kdn=uMDZM5$#ndk +z&22o*u=b&^trc3UMGkzzrL*~$;t?gd{w8WCC+z$)6{fY`v4CL%;?|JZtR3}&oLz8* +zT?G#HsX)xAYvWho@h=pJpzsjcWp0%LD4s08onG)Nb4)MY=8K^XfVvcKVvP||0{idF +zr>Wx=dX&);ID@-|u5Y#BAa0c8rW_t)Xfo4c@By|jKCCPsr7DjJ6t;eTIrmF;CpM`~(ysWB=S@seY-cC;IYp7eGp3%$l} +z)oc?3jDrN<0qs>+yfj#>o^%eHp8`K^wUK{qUM_Xl#K;;VHK+>&$DqLQV1~BoxLuBrt&0}DAhEKn_^ER` +zz-29QNvC|8F%an87xNYKcn*LCu89T8nVkc&?~&O83)5GbY)slt*#=)i7s;A_C=2r7N7+fk`X1KngTDCyUEafq@X5m_z1=DeiD@Q38P{+Ou8AdwgrjC5 +zajlbj!7Ae^jZ~9GGnmvF%|dV*Siz7~1$lG}zFHP5%BV8TD09lQN!w79WRZ;`=PM(z +z0;YT`0PcRb5SM~SQ_OKjwTc~?W_G_IPe||U$;Um2U%fe+7X>%Nvy!xcXUbbT1miw0 +z=$X7_W&m0ay!h~`ae>C68mu@al*ia7R0saqO=sn$tE@ww372nWLhU^>%{WE>Eoln8 +zaeH(5Zly+xlW1Z@B{Z2HqS52V*oh`BC}k&quf19RS}N6$l#0qGWzl9DQkZ@85(#UMH4E) +z!&hPrOmR$HRF*}2C{e3A#U3h9d)gN68^|>O9=TO4Ga~u#5kl0}_*QP9IxEl~Ce;Vj +zS3zvyQ+p-TKYiV8z>J$akDBH=i$W7}&)8|aN%_17$7$H|;eKWRKgAtrMwoyE;#kJp +z>iJ{R+d4p$2q2;Y5EBQ7>@E&mk*MzVW>!EDsQ9Pd1Icl|=0d^U2HU!hP6MLe0bwp2 +zA=U!|OQM?{{^8dU?o^&w|I~Y5fw~zw)IT&*mzBRUy1Ljo^-=Z`fvN|N_JgxG~k*Hc%03VftQZkoi*AD{-11-bt2%}_=-R;7ZY`jOzsFyAEWb! +zVJNLPL#@4|8iv-c@m4Lu!^Uc7?VOsDWty>@T6^QN67|~9P?w&boWVpR2)d)gI@s*$ +zT0uPct)H#x^_Y(_q2El&g2<(pF8niAzCde(;c)XAp3awn@Z)3{qMO$l1?#O_cXL+a +zB+yS96Q;w{xIBw9%-h2xp$%a(D0`Noi$$31BbukCM_lu$4sG_+rWsH9U`eD0eY3t3 +z@`vkyB5OW$_NhyNPE(&_JPvYO1XVd%SiaJPVza|ZguGogD*p`OzJ!Odk4wR7o=G7; +zQFEN*_9WQcO`Vliy5G@VCnZ;Qb~fJ44e1$o^Tw=L_lA;Z-8Dw0CC}X_m5Q_J*xP61 +z2tVQGAnU9PA@k;{9QL{c=-~c_joC`W*8qxTI)7}foE-)SU;g6SD;S1P5oGCta0DrC +zGXz?khB$Fn{Ycwuk%t&RTyJ!Mz8mnC0U+AYu}PkaA-t-gE*25%;RVKNKyWz!scpu6 +zZDKFBX5S4#lCQK!Ip%UxMsP%cC4T!8d`;mo#M{(B)h;Ilk3UVA`-O^+JuQDuUnt-K +z=jEH2NuzvVs7mGT0rJ;Nz54;;pVk-{O`o<8h5~yAG9cx)%sJ+#d0-B8j!9{+{>1@9 +zYiz-m^g@6wE8^*umZD0JhIN!|&Ok-?2XhJ@B|oI&FfS^$rs90JhlZBoJW`e5b9j^- +zWO>uD9oB-o4QKEBn$akVeT1MeUX-s%#m~lPXZR!_h7SU~%Y_rx{QlrO`$o+{oUb!PIS+x5N +z+{O+YLa6?IE1#&A?RMZ&J}!O!vj>Os^y>J_BMi^Cu8;>FP)!5eagStg`4k8`f<9)s +zLv>uniXJHc5tD}2a*xO+UycHT8lGykAS#tq7H&?$Q|yXO#aH{77;M;}%#Rn*u_i#Q#=kFoCjB +zxM)O)sW@_wx=K{lJ|iyESH0iv9Nr111eP3eEA!SenTb%U12{RS*7qj0=;%^Kd#QiJ +ziYTEU=jFY{zWsSqmqmw<7L@5T1o7NxWhht`9gu$(b|QZnjVAE)D;lyC=>~hv=8piE3T9#-QVKCSaq-q&xr*zuRbfKtru+;Kkp5Si5+<6{tz}rp +zigZWmiiYYR#xdxCbhhJz=wN$k9zPcR8H;AJErv2><3*Bm51h&CEJlpT9yo5`1`w{pnaAJ%0k=ISmg0E +zo$J6^H1-w0!^WV5w|yx36dtal`WN}DGpD-gqYjDTfjIaLtR}xxCDSo6v=}KHRM^9@ +z&T;nw5x5ee(K3%Z3QQF%sMId_cIRpr&3g$f><9ZoX7X_c7g4f{y)mf(?;`TLI@jLv +z?N)ryzDJ)LsBZU+VnRH0X1E}KJ!}%#n_-hEY9w +z`8(=7Fd9^wGY;{_ggJK@ZR?yW!1!^^d;F^x%}=DG(7K8XMm$L~K*Np|t>vZmA5%Y| +zINrWxnZFq_J7&ksTGEluekfNRCX$8u^xk+?w8Q1iII^7LA8Wc=uh=>E34C14fN(+~ +zjb&LKSzG|ur8^cG=n*d|U)DK;5`-D7c>o{;1qb8{cYdL5^ll*Y29ag^ZWs(}{Dq?& +z7Vt6fu%BVSoqvD;RYW!I!KS^e-kCz_2@FvAByt<`2mpvxlE{aWp)% +z7->KZs4&!M+Z9|_;(QrbPRGNC2zLU&;bq*v@zaDlNR7 +zR!OB(0w7?XvMI3w1tc_A&fY$=RO&K>9q)K{?KeL9#X2nl`k!ouFF)XFC@Tui*%L4~ +zwNvTu3}=K5TH;uDS!^k3d+!l_hx$f?(hkYU(6NBYx@mz*Y6dZ7D@JF^5^p{aiT5zv +z;Xjc--#|sw407DGZz<4^FBXBq5F)zwTQ|65$~FTfyft2wOiY&QG(ydKoz#wa?YKny +z)9C@EX0c#XN}}K5dNFdMNo^+Os>0sS^c;E5Ky4zm)q;>J{J+z3sdUj)7tN@@gZSf7 +zJ|wiD$oI`e{Xe-gDV9P_(x}i7AaPVJn&m~NMi(84-RGbXy6@{lY?h66ze7!6Ee=i! +zInre-6PCHrI9+8v4+)Zge*esLVEy0*)t)o|)801Zf98hgQ=EZH2bpZ=)5NN_2yjw# +zP8Ewr(5WN{8DJpt*e!|G(gvZ5Pxywag$Agdns%%4+IH>|FMw9b +zKb<-v)*Cb*Ao~hb;B*`Ee&trZYBi`{$ru%gmKbuXcPNb3lD3H3Jimki7;BEFp{bxX +zFJ7Rk<~$d5(AGs1%w=$DDrj&3=?C4wX`U{m8^^=Z8R3YTB_A>ZAOkmldWl +zwo0ZyTNCB`dfUZA+chm*()HWtA2!JQ3>g${8%Vr% +zasf==&095e)fG}M%iIsk{PaQ>2|D59ppz^2pExvb9Ou9EI^`kN!0aXr*u3p0ex0b4 +z=AnHH#@v>`#o*LjN-yB0^^l)H2Nm=yD3|>1aNigv$f`s680kxF8B%d>SUG)YF0R~W +z$TI5rvll2~&q4RSwu3})*@1!~z4l}@NsY#MwV(2Y=hbLZh-ce*Eq3<#rZ +zxra}au9h@`-JaCDeW|)St?N40z`g~4rjZ?xu=?#W;cJyHNPXCV2DuxD%N1A2hAlFH +zwTJm(6XPn#dA&{dq>&yd{5Lp=pa<%$*em=~TdQ%rn_v#5`>I!IS>M^uNpl#N|wC@HMBcRTMT#SL;d7 +z<(&BuA6dLkkx|8fWw@PXzCeCBgDx@HJs@)L+j8y~gZ)7)${p-|O7{G? +z&|M6FI|A*^d_U+Of-3`+w(c~-YsQby|NH)g|G7xv|Nek^|Jex)g~z+)I0xPC0460S +LFIp>X81%mY^Bg|U literal 0 HcmV?d00001 diff --git a/patches/server/0957-Fix-issues-with-Recipe-API.patch b/patches/server/0957-Fix-issues-with-Recipe-API.patch index 17a8c00f6436..63c059ad013f 100644 --- a/patches/server/0957-Fix-issues-with-Recipe-API.patch +++ b/patches/server/0957-Fix-issues-with-Recipe-API.patch @@ -18,7 +18,7 @@ index dd02af6574dd97404bc9c02c9ead84e1dd537efe..980fea65899ef5f37808506b822fd3de } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java -index a30950287646524c4906574d193ec7ce94b4eb34..d270e17f10cc8abe3f5209d82991fcb0b2bb1ba7 100644 +index a30950287646524c4906574d193ec7ce94b4eb34..e89fecf25555195314998e5317baa3a49be61aa3 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java @@ -38,6 +38,10 @@ public interface CraftRecipe extends Recipe { @@ -32,7 +32,15 @@ index a30950287646524c4906574d193ec7ce94b4eb34..d270e17f10cc8abe3f5209d82991fcb0 } else { throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit); } -@@ -58,7 +62,7 @@ public interface CraftRecipe extends Recipe { +@@ -51,14 +55,14 @@ public interface CraftRecipe extends Recipe { + } + + public static RecipeChoice toBukkit(Optional list) { +- return list.map(CraftRecipe::toBukkit).orElse(null); ++ return list.map(CraftRecipe::toBukkit).orElse(RecipeChoice.empty()); // Paper - fix issue with recipe API + } + + public static RecipeChoice toBukkit(Ingredient list) { List> items = list.items(); if (items.isEmpty()) { From 61136fe43bb61538716c68c6049cc0bd15d40190 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 25 Oct 2024 14:06:01 -0700 Subject: [PATCH 082/119] Add max minecarft speed gamerule config --- patches/server/0005-Paper-config-files.patch | 5 +- patches/server/0009-MC-Utils.patch | 2 +- patches/server/0489-Improve-ServerGUI.patch | 647 +++++++++--------- .../0735-Configurable-chat-thread-limit.patch | 2 +- ...ing-message-for-initial-server-start.patch | 2 +- .../1038-Moonrise-optimisation-patches.patch | 2 +- ...nfig-for-max-minecart-speed-gamerule.patch | 19 + 7 files changed, 350 insertions(+), 329 deletions(-) create mode 100644 patches/server/1041-Add-config-for-max-minecart-speed-gamerule.patch diff --git a/patches/server/0005-Paper-config-files.patch b/patches/server/0005-Paper-config-files.patch index 3303f32c8ae6..0256844bd941 100644 --- a/patches/server/0005-Paper-config-files.patch +++ b/patches/server/0005-Paper-config-files.patch @@ -487,10 +487,10 @@ index 0000000000000000000000000000000000000000..d9502ba028a96f9cc846f9ed428bd806 +} diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java new file mode 100644 -index 0000000000000000000000000000000000000000..7e88b1fc1ff700a7771b38f139f4472eaeaf8714 +index 0000000000000000000000000000000000000000..e845592621f931ae94b0f7007d5d8cf417c7086b --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -0,0 +1,355 @@ +@@ -0,0 +1,356 @@ +package io.papermc.paper.configuration; + +import co.aikar.timings.MinecraftTimings; @@ -835,6 +835,7 @@ index 0000000000000000000000000000000000000000..7e88b1fc1ff700a7771b38f139f4472e + public IntOr.Default compressionLevel = IntOr.Default.USE_DEFAULT; + @Comment("Defines the leniency distance added on the server to the interaction range of a player when validating interact packets.") + public DoubleOr.Default clientInteractionLeniencyDistance = DoubleOr.Default.USE_DEFAULT; ++ public IntOr.Default maxMinecartGamerule = io.papermc.paper.configuration.type.number.IntOr.Default.USE_DEFAULT; + } + + public BlockUpdates blockUpdates; diff --git a/patches/server/0009-MC-Utils.patch b/patches/server/0009-MC-Utils.patch index b7549f7365ac..10229c032639 100644 --- a/patches/server/0009-MC-Utils.patch +++ b/patches/server/0009-MC-Utils.patch @@ -4542,7 +4542,7 @@ index 46cab7a8c7b87ab01b26074b04f5a02b3907cfc4..49019b4a9bc4e634d54a9b0acaf9229a + // Paper end } diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 7e88b1fc1ff700a7771b38f139f4472eaeaf8714..904d2f96a60e72aa089fdfe6be08044b04f995c1 100644 +index e845592621f931ae94b0f7007d5d8cf417c7086b..61ad89ab1811b6a0b6248982b9c6e57354609cfd 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -242,7 +242,7 @@ public class GlobalConfiguration extends ConfigurationPart { diff --git a/patches/server/0489-Improve-ServerGUI.patch b/patches/server/0489-Improve-ServerGUI.patch index 8dde1d1a9bc4..48a151cd82f1 100644 --- a/patches/server/0489-Improve-ServerGUI.patch +++ b/patches/server/0489-Improve-ServerGUI.patch @@ -102,329 +102,330 @@ new file mode 100644 index 0000000000000000000000000000000000000000..8b924977b7886df9ab8790b1e4ff9b1c04a2af45 GIT binary patch literal 16900 -zcmaicV|1Ng^k&Q(Hn!T>_Kj`Zc4OO48rwD-Gw*(Xv_UIGaL4*?7e3`t5-R2lSh^xqd84Cs4}W^FDQn9zijsF13M{zVR~<`0dB -z;hww3Rk_uLO*yyZ^N(arMN#SjFcHEi60E_fZug`IjtJ^LVtno=lKj+Jze{_WszRIN1X*HUTCH>C_wc;+D)6YYT -z*RWmTUi`Puu_Uwkj6-qwu_Ue*kO&$%=o%J?6*rej_Ock3znkGIb6 -zWm&yS2Z9LS7slFgUx+?ilDgQBdj7`ruw|IVzJ@wV{&tD)G@SPTMW@9Wl5lcsuU~6` -z7raw|%Or|@Pnlh`7!!rA1H$`p;zz}+92Tp2bFmKDAL`nrC>)<{qBHso -zvJ6|o^vMxL?frh4XZ`3WdH7s_NI0p@{EElbnX*!yp;Vtx&K&w$&to`sW -z79>enm;xWhu;ZKKIN}-h!eBKZM6j$9~*Q(SlE*i_bHS0o#tPY -z5-j+ww|x>h9%`RLUixM!e%f0qVAe5GH83X6?!#^_j-M@lO@*-aD%NMF2;Hg^Wgh@}elrPA3o_&(- -zeNyws4es~%;K1o+pfG(Z!G-nFWzl7)ejRNxY?M~uI=I&MYuz@4>GLH*ptjlQJ`LYr -z*KIIVzBhKHIDwe`X2hc@gsdjzXxX%b<_#kc$vIHFi2)-XM1=fs(`g?0)M{lcJXwp< -zBgIdDXM&n-=+_%;1a?sE$oeN{r%w=8tFfAlQopAk -z%wrVN=r>)oZ0w7^M~Xi~qp6lEaABgF(ck7V3Un;@cg|ODuD7@fw~OZ;^TQV -z$&4AiUj}-4;o`6JV$Y4C2G -z8hVweUdzl78hWzD|&J_)oRr2JdJP -zA&lca);^P(q@hQb9-kqNXVo9An7Q3NoAtyRQw-@JUDD$oluryjE -z3{zzbZhStP-K;xw@Yxf-B=4h(p=4f`k8p2DH$>qQLPR!szD!2|vJ}J`C6=EoRwG^+ -z;`ZDv1SGVO+?IqSxpxSM^_V~@2E+~dZQdl+oz;TP1MX+XXwugMy?Z5AoZ7#R33Y@T -zM)w4;9L0szO3>6i#4fV3q49@wu&`zcvQ!d8!m*dpn&7pp0Y=;QbiyOzhC7)Ki7tDt -zXaIqysWqx53ZgHlO)|YRDG**$7&F{0a8VEECY`3;yx)F>2;4Xr&gC;Iqiqx;orWkF -z8xk0Ty-mK&z`^~Fbs#S;;Qd@1ZFJh4R`+H>Wx$xgn>^oka;w9~QfR>rS7lYHG?D#o -z6Jo`Qg_-DP -zX@kdURs~L5?afF*73QF!=HQ?vIysP;FNCMBfA*}*&%$eDHh5L|y~D=C^v8(wdtcYZ -z)8Q|56BuZ~3~KpF-oKg|5Uf@Ac15Z>sP<9hpm(E>^cgr8dMxGhn7mnWA+JPK+EGR; -zCfK+V1&Xi1M6CUFIA+oJqr(aF3W_=ph7h;IVlqq&xJ=d(CqczQwL>f*A$gJW_|iZw -z&>!^cGyI)UH(_%jFMta0ci8K;?^D#C4_`@%@wP6R4qvs8y@ecdj|*ia7Exg3*BpG4 -z%Dqav(-_hWolzv04-3Ygs)Z~U$`R?hQq2Is2`RWS%z4?!GF2CryzMjCEFg_Y%K+yz -zG8tm;0X{;XG5?BBT|pMZ296(fGUtoF_$Ryrso&s;Cc!g3a;pYOn-tjPvW+1)iAQ)I -zaPyG(wl0MZUqz_Z!4+oEh$t>QIaiZ+J1|fQdfugliOCAg+6D!~3<-k#gA8N#Rk3@5 -z&u3Yevetsi3m`sm2Ntt>FV(PfME~wR=LFu+2@Noy&wr###hgP3mjy&H03re#97OQ% -zsZ;NtktNoC?s@G44Num-@G1zw*?jMf)dA`SWJHyI-Lp=m -zyv8V97L8$~?>Sf(&Ee27TQvEf=-_%~EL56_n`*ZRVS`=4Ka4&HGjr9P8e3rf;8BK& -z&0s~H!Z|V-mPt9vUj?5&%Sa@;XK~`TS$ylgW4|1h&I!<9c6_zoDdR2)FLErHw%Sow -zwc_2ZKizcAMchMvZ^6OY8)uiUt&RwA(`3@dzgihQ1MSrNi;ruq-C+?oVa@U0x -z(>^4ei3Bedg+!LX52G(u@W4P&3sdv45%OawU(*aQat~OuEf?Hi6Zi>__qCd)nw0_j -zvUwA_6WQ5tnFsl_AZNz8L8L*=L4?0A>inj9l&C`AC71u=H -z?bu{Q_=al@1+|F&El|te2eQB@?#+g(D(LjFx>w=0X;CJ|CQc@tuin_)Rd$KH$Y9P9 -z${MAq+Ns2`>_SLAfKm9~%?U2bK6>hiDEbdUD#NMd$hR*wFx8TxWVY3Za -zM&tRPhR$htT-*KlZT-SGBy4YD;6aZfAz^Jt1`=ABifztn#D_;u)2WTa-Bo^EKL;=o -zDc6Ov2x3ybU1B6gkFjv-UvyFl^(EFkIb4ht2Z(*io4 -zW(6^Rp7OMxVh73mYH?bkbxgXB=+TL>U^8OY>=P$oXPkGAmF?6#80T -z+e?24uzuJC8?nCu`7)ef&Nu8x+`0%wOB9wmZ^(+|&$!T80~3uj?NRH)aNhf~#vN9e -zem1VW#bKd$SZ4ufS0-pzoJ%P7UWdT@8yg`1+kpYLV153t;UJy~P8@7sO+#{ePIXcSgw}v2XayA<>Jxh}D)tMOGRgJY0QEJs` -z{>aB;ssVeqKi-6L#(PnBpPuOu<4Rf*GWVk8BdMCd} -zc^_!LU3n2YWBEk1?0<%f@MkB;t#h0%&cixNCZn@Lft$eDVl6z=l@Ga}k<7cF5n!!o -zXet^Q3;AyG!j)+$=3U>7D5cEf)=YMZ)jSZ?)!6EoSa3kU!3W2Xn`K`PqR|ML`Ju!A)|K2`l1>ErJG>o*qIC72B&jHYe36od@P! -zi)qQ9Y7g*>N;Y4;sSLlPxvM;q-Tzw2m;Zx=x>{mk0;Ed5zA?Hb1FrDGc6-;m+iSFU -zc22aC&R^-iyw5vE$D?GWWo7A5o@@>d3_uD92sGM_-tlsdQ?ZbAnF4LsSxDj&0TFgO -zFbB*@;0<;Y0es>tB&~M12_up)gRS(Ce{seFR$9$~MC8~S%gCTV+2AIiH`gndEW2~H -z`z|RK5KuxIccy|!;Bkm8puw0EcWFE{ij71G*o4( -z0~y!3%z_nq1kdh3x<;XVQS{_v?Q3|H1so1Z#CL|Zm2Z&7-mTO?&1?U-oogOAE4Cm{ -z`d4o(XCnWH-J^hx&?7X^xHns&B`u2*skUy`s~w=0252bVaZy(}U?e5?u>fG!UbYaS -z4Gz$YBX|~|U$??YUR+zxw2g5F_OJB7viI^}qx|ouEswnc0o{D4T~~|912EVr9)4P& -zS=*@uBmgy>GC)sz_8A$Iga2y-R#LKP$zyVe7P=4Vrn@Q)Fp6mG;Nall=^07<{OPT~ -zPDD~5M}Py>^H&ikOMCrXaXjFMyNuyNg$gXaPOE4z3=$o3Jt(guFuvAQbA?*MR;Dx}r~+zsgJ -zzCtQ*$r?UAKNl$E39K|(pdcV17*;zU{VtG7{)QDicnC&XAit07AxkJs2xbNxkEh-l -ztI=-hZ#0{5e0{huHk5pMKFXUdk-_HT=8j~#**>ze%L-Vq--ELbc7OqlEqqgfDL$7| -z^zia3^m~7il#>&4bK{s6W!C%o9eQ_nw_LRXoq&)qk2e`~Carh!_+@C+^?4E@nB?8v -zrP(B~aF_-3_5wx4#3EgX2f|T2iDX6dBot9e+}zxz-+7y;fop?^#LWumnJ%(ER<|F> -z44(0)x_-m7iZI17bV#w5<;|{V>IZ-R+z|XI2d!L0M$z{_~PzI|b} -z_>I9TkwT-USfkDEyuoB7YJe7^SUeW*JCd>d31w)Viag>w -zE)Hcnu_U(A@CEh^w;UM0IVsDf+yNUB)lCpiM=a>2dMSVx95URpuHBLGh>h8fgM&77%eeba~6*@>lA8=;7iEw2QP4d^IvP -z8fpiWc?lq5kxp*C)nS|HY^i2ov(x?A!{1u(mk%xyJ_nmAsx{Zt=LV=Ta0-O}2|y4O -z5yIAhMw5|xp3lvw|Ps$0W*KZd^Wlj=W@{AaG=^es3_){Y~Jis`IYYiWN~ho|DLil1qRD5 -zN6xAlvXG=U-8`VKVHr!k-;5Bi)EfnJRTtvY$;jR$#e%~lxMV?xboY;JA{IT_^y}D0 -zw1mJ8tVoSO-(}absB6M8b$Zqe)Ok0$OkaA#I -z48@e8TAlv;PmB6dbP|{7<%qt@Ea>I;PRL4)=M`_G!A40Y$Xy1Mum)I0#!3<77H4)u -zI6c{)TUsy&o^*@2H9Bp>QJA#S8$`zN?+@z^IIQL|VxYEQfVw~Oc}Wq!FS`G2T=aDu -z-DMYe(1$x=331oN(i#yV%?Q)lcY`}FpGRp*74@@$fX%pE+dAGOh5QRhJ&mcaXOhk4 -zLi_pirw^Zws;d9n^#IE8T1ypZDX|crNABquU?iL2;Ql%4Vg5cNBt}OJdbLKnEi|`g2q%v70%eM&7 -z5gdFefu8Ix3n54MC -zW40SGT11ajrrm5AI24T?-2$|VMsU%VX}AMmt>Pr~B}#An{>%QG>_1FQYV^)CExzx2 -z&7E_9c!fpiCLci|F3H*eM2DQQRtQp4>V2RP=KX3ZVw#OXuFxj$VDmM&HQD{*dc7301976VQyI69%EFvxxn>qC&Lo-`%ImvM -zCv>AXKPcD26Z_;m`1pw)uF6Mp=RnShU^yM81!?jbl!v#-kSa#RLhSOG0?yp1YB6Jr -zW=GrO|0zIRSHiH?DYiO+$EpdMkwz#4I6V(J12-W0+dAo4J*?nDQrFI<*}a92Y%1bU -z`RC_4tyg7>R(8{ -zA8*g?PWv##WoF+p0bJe>whg#+(1_+A+)9HS$|n?k;(r=Le*vR;57rn)2& -zEkD8KBSZm#3Drt?t!*#s#>0+yUNysIKRg=t`KSOcSHieiUP0z8F_$tZ(ciPnq_o~@ -z%-{zhbs{i7 -zt~8q8%WO|MF(FE_ye*bl_-@NcA!S9$IMb6x0`e_oNF!hy5a)H^H)5)t(}ek4a1Nc~FF4@f;5aO%aB&3O%B8NuMWWCzYb`d> -zQ-&3)G|5M|pzcLy>pA(p=?3&XKn+v0^`HNsS?M0eb+60BxF|&Y{?>MI^x``)Vp}1V -z;<0N$BUc(0=p=y>zD3k_I~ -zMC>T|rn!T!wN%lqT@ -z&Afsj|04$m&CH2M?F|6yeqb+e`&JWTP^~~z(;c>5;z6RuFKe)%3j|YzeZB9c)5E08 -zvX9?L9%?PT7Vu(RAIXR}s*=I*@Qp<*vA{&7B2uwdBH$_I`33U5di9weG|3 -zx-Iy`1L`R>G-q<+w-{f5qc<7ls}^cT4Y^Qi+meHXFIDgqkt0wpdBZGY?LB+q9&o`T -zd18L5%R+44Ml^UNbEw58BXP#{+I#J1$;VGO`#6Grd<=RWgP+T+ktE6H^>C;%(}szj -zK;wt^oW!yG4Fz=zm4zKw@$Wdo`VJm=879kp$F&$uMP_qiKSB4L@SV)g55F9Rb=3ocrK>iqIRR9n!X0Do*Ldi{9M&^sg&T_TZz~>`tbXc$p%%BI% -z#MahUA?U0t#2ZA4_41*w&52#TXU^_G4)$#uGOnpIb{Gs?Bge_xP|beH;cUSBec^gk -zu;a`And#3j5LZ)LALL9lQ0{$A?tzx&K6M(;#M))7n&`7KTkT>KvjI7O4?mTa;X`81yn7WAir6 -z^Dv#2{~#3{X=5gyP*2v`3yoLJl)--n2rC2}*3n8(L~4ohHzT6QbyEu{!K3q#&p9Lp -z?3#RrZR0JWoh5V%Au%m2?uSB&RO!i99khjDd#7P;NaxJ<_f>mYXQOtXqBZifoWn1d5WC&hmG;&Gv(>!l)|)selJ-m-pz9Og@*rA -z%Xl~n+gHI_Rjy513U_dEaq-~ZLm%H7RpVbREoW=Zu*D?n%JFyy6(v}{RCOy -z>_wu--o5bv-4rRuWG0oN3a2+(f)C6nR0%>9HdI1mB`d{jE6Q4vSf>>{@~N-bGMc6~ -zn=1MB2?XIjZuOC!s@-pN5{60UUw-L4f1L-3Ohud?4)I$4Y&#w^A*ij(1$$3|Vskv} -z#YKCOBnHKh5QN8fd|k)wI{^HZj_1!`{L&>R(m@P^tYk*J)5>eCrio9{j>kWLDCGrM -z*O<)utCbjQiH>aHzD!~>SNyzV|B?uyizaR*!v`(g6N5ks=aSqWHk#wzbQOx2Ehc(>s -zfl`oSK+EzLOKDeK?n#pu;5qF1g-8bXyN##%K`x2R14CxOh8w&P-kz4U}>3Q=A& -zwAa>sCXe?|fR^Y+S9_jW;=!_GK`1Bc2HY6Y)*s}A##+#}239~LV&Q~wL&4n_6^@vW -z;nGUYJ$5-C#kJr2EtD&Ty$t-H)#GyT->}39LWB1gdo%LwqR8{YbRBL*-FCEc5iY{; -z#TpZ~y8yolNKuWi&enqz%<*)Y)j#ff)9q1ezkI|N7|zr3b=T|b>+m?)d% -zKJ;1@L~w8ZQn0MxZS*{ew-;Ohn^Jl!+U{m|QvgB~tai**t#d>0E=CMjN*SZ+36QnO -z4NrSN!Cd>9SLf?=!Hjh+ek}c}ND_U`vvi9(MS>7nGZ*lPm%4(7(bhfuTHod8y%;N{YO_KMV}N<7D)x5snD;XG -zzCOH#WK2$4mAvQWFCCZW#F8TRInJ+=$6eR`V~dES6+!6-=6lkVCHyCW^Bb-$@=b%3 -zi%hxQwAp^EOp|zR61~UikJsM89qE@P3@X5J>+K)hO6K`Z$80UqhLV&|mVt3wQ#G4H -zi4>T}s*jr9pkN+B@=LbuMW8^kzEFQde*yOdnXiUws9u#OD8dYzm?0F`qCm7pBCNNz -zOJB@PR!5?2&9Zw_Jg~i=TwmStKiYq1_@$ -zZKB*^u}y2o({7rV#Nl+8$2T5 -zthMF3X`+*;4Q-~&-*4NzrU=7>#}h=jB}<^tsAch7Ac~Vq;V7 -ziknpCHOP}_P8F&VE%6e`WG~EVa?$ra`knKZrYWbIZ_w@4vO+{B!(Pb&!YhY8pCfe= -zjxF8x>Zh3;#gw`fu})grVJcf=Ohg_Xc9m?(57$!NXQ#N%;Q{V}EjtmA$m<@Ie2(h2j9T2Xq=0<2R#daW&$ -z85=lCIqjn+?h$SF4u|?#DOOKg9>2c{9GSdlh{<(WR;Mb+bxH>u95roevUiqSmcdG* -zEL`{Qv+mA#hjLxuC*l?ROBgDsPYkDNU%;m09$2^ni=SVA=kS_) -z_h->URCbhQr89T-a-Gg9Dk?P`CT8-=f%@A28AYMmma&Ks#DNDsr^|eI%nHBQ0Nps* -z<{@u^G-9krSD|^{Vm?_nRkW_T!;E*n95To#4sxn;9FH2W%&T043S^Vg_Bk^^&J9*H -z=-^Zd6GYUG(CMkA?hy<&4Tc5fn4$3ys+ZiGw!07qHH1zPDzAJY;{8Oj#B1-LTAZ>D -zKqX)c%j0#o|H%z2zdkxYKaV6<&nEMgP`q%2&v+2dsa++rFeWoOnf$VkCAY6|8|kw{ -zdwe(maC?oeGlx#HVClH?)W&QZ`+=l3PIeQ%9cb~nWxJ9)YD|MPt`v?0-3bMcbZ<2Z -zG7xSnH{QoOr#C@?R{C$168|JMfCxcPAVuEhewgQpYO@AfbP3Fw+|Vi7h~L@$6ydj5 -zyf7_h9Rp$0Gii0mkT9xddqw>hIVCXV203~$D~swIj_)TV=zX)@-tK6Hb66mM;EywH -zsMV;{!i^8fvae3b)iz7_f6$4yU2i-b%Bh|o@eU2$RD^G(AtWlyl0^8dxd<9 -zCi_xU0%&wFugtmc%-uOk=xMY?lR%{7BQRZ~b8}1<=DQI)v2*#3|70VNVV*?SK4O}0 -z-HEICfCoyTwy@{F=Ac>4KISQEgQLDcj|>j}hzn(*RSn -zZw&u6!^Z2~7ae&u`+{IHYm_vxJJ@RRZ!LoCjQ2ecK6E;AqeyJZxfuAC -zaFBgBIQO4DawgA~vN)BCS%`;S38kn@9kWOTMq)$V$+z&4nDQvH*{(1#N58$C)v2#; -zJW|ch#FaXRBNNj6mX)HNV{_ScADWB7#Jn(Th}B15lvrI|-2fj-=SL1AY -zQrI&y#`tyxRIyenc$G7)m}|d;5&h;8q8?ap1~7v{vEXIAhojO|^XI$6=K!f+>;5yx -zJJXiq*Z?mW;Ak{?4<=)9$$a@6Q*=1_%}Nx&bGA3oqS%{I)k3y{#DALAzrPw)h(FU -zj}8a8Xte($dBpT -z_ZLeg50aO#zhmy?M*+dS#c4NyP>CZSyS+OOi>@2;)lr;&A$)(OEO;kV+bz6O57by -zyW>9>Ij2^Du|A83(r~$46%S7?Ancv(6R -zJK?TL+k$9p$KMJgY}hdrTzyS}0it==hvU?8YM**7M}l@-W{&s26~NM6 -z#U8(RCX-=6Lw%{$D&=aKSfE%aJ<__RASP1DaZcJPva<-yi3NH#t$OuNk6wlp&CD~1 -zanJ|7AhF;l{a^)Qhr_9Bo;2ZG8=}0whx#r7zZ6W`Fs5 -zJEbvhZVJVsORu$w4Y1HyT1E4?Vka&kS*mSpBuKM>OAT~3W;g7KLGzfQWF~QJ1)H6S -zFCOXwP_auqzKSygLBPB}EH;Q1gXb@Wm*lZWfM<8NWGZM_*$8Ze)0+^IpqCyco5T+P -z>!edzc-RMsx%H6~4%a*u{&6!V2Xf)f8oOKEEtBAhvI#TkSv+Ago-TMSQ(2q}=S0FP -zL(1v}1vp6Ya1@zfO!}Dq3ke|~@mmFXu2dHEQWpO$6X$;c8V@V*w>NACSkmSKF-THX -zXc85Wu2(uhx0b@}vaeA-YhO(oJ!8ZlugSxzOn{tnI7h@dCB`UVE~EEY_ww_|qDlb| -zQh0>qvDy{uar91x0J$!N&ch{3*B*?y730`NAZJT0IXU?T1Oo1Zc+QnB&!+ZYLh%_v -zV;)6DQs1sEzvoxu0r{lou-yG%CgwotYzFK>vqr!e>KRehvaz@y)fTge`_wgV2*|2H -zVl|vbxEx$3ymn~uGqN65%FYqJ<_)*Uqs49;KY2h*(Xa?Tk7AFfl-xf>irJoUyL*;0 -z19&1GQV*5Ni~#kTnaq0ymCiLjk_=0q&=&|cG{r57n*6NwV6zJl5K*ED&DsZy8iEL_rr -zgsLXr6cN9-S7dCo0TeKI3ByoGNNBIG{4b4m4=LB^FstU0B?!6TBZ1v~zn%e*Xk=B) -z@_rySE6iHcIxSfbe^sRAkjZKFfR!7A5uNa|Q%HSV{);)`X_I$=Rz#g9)RV -zjIuDE+A6IDHt@Noy^%sCnU|?kL3tCMU12QN7688MFeYr;%^{CT)BqX<4rY8gFNo(^2<+x6~@> -z0Y;8%xJK3sk3si!JoTyNPRqf>i>%mkw_b{g-~}-aAljQww_S1L53kdn=uMDZM5$#ndk -z&22o*u=b&^trc3UMGkzzrL*~$;t?gd{w8WCC+z$)6{fY`v4CL%;?|JZtR3}&oLz8* -zT?G#HsX)xAYvWho@h=pJpzsjcWp0%LD4s08onG)Nb4)MY=8K^XfVvcKVvP||0{idF -zr>Wx=dX&);ID@-|u5Y#BAa0c8rW_t)Xfo4c@By|jKCCPsr7DjJ6t;eTIrmF;CpM`~(ysWB=S@seY-cC;IYp7eGp3%$l} -z)oc?3jDrN<0qs>+yfj#>o^%eHp8`K^wUK{qUM_Xl#K;;VHK+>&$DqLQV1~BoxLuBrt&0}DAhEKn_^ER` -zz-29QNvC|8F%an87xNYKcn*LCu89T8nVkc&?~&O83)5GbY)slt*#=)i7s;A_C=2r7N7+fk`X1KngTDCyUEafq@X5m_z1=DeiD@Q38P{+Ou8AdwgrjC5 -zajlbj!7Ae^jZ~9GGnmvF%|dV*Siz7~1$lG}zFHP5%BV8TD09lQN!w79WRZ;`=PM(z -z0;YT`0PcRb5SM~SQ_OKjwTc~?W_G_IPe||U$;Um2U%fe+7X>%Nvy!xcXUbbT1miw0 -z=$X7_W&m0ay!h~`ae>C68mu@al*ia7R0saqO=sn$tE@ww372nWLhU^>%{WE>Eoln8 -zaeH(5Zly+xlW1Z@B{Z2HqS52V*oh`BC}k&quf19RS}N6$l#0qGWzl9DQkZ@85(#UMH4E) -z!&hPrOmR$HRF*}2C{e3A#U3h9d)gN68^|>O9=TO4Ga~u#5kl0}_*QP9IxEl~Ce;Vj -zS3zvyQ+p-TKYiV8z>J$akDBH=i$W7}&)8|aN%_17$7$H|;eKWRKgAtrMwoyE;#kJp -z>iJ{R+d4p$2q2;Y5EBQ7>@E&mk*MzVW>!EDsQ9Pd1Icl|=0d^U2HU!hP6MLe0bwp2 -zA=U!|OQM?{{^8dU?o^&w|I~Y5fw~zw)IT&*mzBRUy1Ljo^-=Z`fvN|N_JgxG~k*Hc%03VftQZkoi*AD{-11-bt2%}_=-R;7ZY`jOzsFyAEWb! -zVJNLPL#@4|8iv-c@m4Lu!^Uc7?VOsDWty>@T6^QN67|~9P?w&boWVpR2)d)gI@s*$ -zT0uPct)H#x^_Y(_q2El&g2<(pF8niAzCde(;c)XAp3awn@Z)3{qMO$l1?#O_cXL+a -zB+yS96Q;w{xIBw9%-h2xp$%a(D0`Noi$$31BbukCM_lu$4sG_+rWsH9U`eD0eY3t3 -z@`vkyB5OW$_NhyNPE(&_JPvYO1XVd%SiaJPVza|ZguGogD*p`OzJ!Odk4wR7o=G7; -zQFEN*_9WQcO`Vliy5G@VCnZ;Qb~fJ44e1$o^Tw=L_lA;Z-8Dw0CC}X_m5Q_J*xP61 -z2tVQGAnU9PA@k;{9QL{c=-~c_joC`W*8qxTI)7}foE-)SU;g6SD;S1P5oGCta0DrC -zGXz?khB$Fn{Ycwuk%t&RTyJ!Mz8mnC0U+AYu}PkaA-t-gE*25%;RVKNKyWz!scpu6 -zZDKFBX5S4#lCQK!Ip%UxMsP%cC4T!8d`;mo#M{(B)h;Ilk3UVA`-O^+JuQDuUnt-K -z=jEH2NuzvVs7mGT0rJ;Nz54;;pVk-{O`o<8h5~yAG9cx)%sJ+#d0-B8j!9{+{>1@9 -zYiz-m^g@6wE8^*umZD0JhIN!|&Ok-?2XhJ@B|oI&FfS^$rs90JhlZBoJW`e5b9j^- -zWO>uD9oB-o4QKEBn$akVeT1MeUX-s%#m~lPXZR!_h7SU~%Y_rx{QlrO`$o+{oUb!PIS+x5N -z+{O+YLa6?IE1#&A?RMZ&J}!O!vj>Os^y>J_BMi^Cu8;>FP)!5eagStg`4k8`f<9)s -zLv>uniXJHc5tD}2a*xO+UycHT8lGykAS#tq7H&?$Q|yXO#aH{77;M;}%#Rn*u_i#Q#=kFoCjB -zxM)O)sW@_wx=K{lJ|iyESH0iv9Nr111eP3eEA!SenTb%U12{RS*7qj0=;%^Kd#QiJ -ziYTEU=jFY{zWsSqmqmw<7L@5T1o7NxWhht`9gu$(b|QZnjVAE)D;lyC=>~hv=8piE3T9#-QVKCSaq-q&xr*zuRbfKtru+;Kkp5Si5+<6{tz}rp -zigZWmiiYYR#xdxCbhhJz=wN$k9zPcR8H;AJErv2><3*Bm51h&CEJlpT9yo5`1`w{pnaAJ%0k=ISmg0E -zo$J6^H1-w0!^WV5w|yx36dtal`WN}DGpD-gqYjDTfjIaLtR}xxCDSo6v=}KHRM^9@ -z&T;nw5x5ee(K3%Z3QQF%sMId_cIRpr&3g$f><9ZoX7X_c7g4f{y)mf(?;`TLI@jLv -z?N)ryzDJ)LsBZU+VnRH0X1E}KJ!}%#n_-hEY9w -z`8(=7Fd9^wGY;{_ggJK@ZR?yW!1!^^d;F^x%}=DG(7K8XMm$L~K*Np|t>vZmA5%Y| -zINrWxnZFq_J7&ksTGEluekfNRCX$8u^xk+?w8Q1iII^7LA8Wc=uh=>E34C14fN(+~ -zjb&LKSzG|ur8^cG=n*d|U)DK;5`-D7c>o{;1qb8{cYdL5^ll*Y29ag^ZWs(}{Dq?& -z7Vt6fu%BVSoqvD;RYW!I!KS^e-kCz_2@FvAByt<`2mpvxlE{aWp)% -z7->KZs4&!M+Z9|_;(QrbPRGNC2zLU&;bq*v@zaDlNR7 -zR!OB(0w7?XvMI3w1tc_A&fY$=RO&K>9q)K{?KeL9#X2nl`k!ouFF)XFC@Tui*%L4~ -zwNvTu3}=K5TH;uDS!^k3d+!l_hx$f?(hkYU(6NBYx@mz*Y6dZ7D@JF^5^p{aiT5zv -z;Xjc--#|sw407DGZz<4^FBXBq5F)zwTQ|65$~FTfyft2wOiY&QG(ydKoz#wa?YKny -z)9C@EX0c#XN}}K5dNFdMNo^+Os>0sS^c;E5Ky4zm)q;>J{J+z3sdUj)7tN@@gZSf7 -zJ|wiD$oI`e{Xe-gDV9P_(x}i7AaPVJn&m~NMi(84-RGbXy6@{lY?h66ze7!6Ee=i! -zInre-6PCHrI9+8v4+)Zge*esLVEy0*)t)o|)801Zf98hgQ=EZH2bpZ=)5NN_2yjw# -zP8Ewr(5WN{8DJpt*e!|G(gvZ5Pxywag$Agdns%%4+IH>|FMw9b -zKb<-v)*Cb*Ao~hb;B*`Ee&trZYBi`{$ru%gmKbuXcPNb3lD3H3Jimki7;BEFp{bxX -zFJ7Rk<~$d5(AGs1%w=$DDrj&3=?C4wX`U{m8^^=Z8R3YTB_A>ZAOkmldWl -zwo0ZyTNCB`dfUZA+chm*()HWtA2!JQ3>g${8%Vr% -zasf==&095e)fG}M%iIsk{PaQ>2|D59ppz^2pExvb9Ou9EI^`kN!0aXr*u3p0ex0b4 -z=AnHH#@v>`#o*LjN-yB0^^l)H2Nm=yD3|>1aNigv$f`s680kxF8B%d>SUG)YF0R~W -z$TI5rvll2~&q4RSwu3})*@1!~z4l}@NsY#MwV(2Y=hbLZh-ce*Eq3<#rZ -zxra}au9h@`-JaCDeW|)St?N40z`g~4rjZ?xu=?#W;cJyHNPXCV2DuxD%N1A2hAlFH -zwTJm(6XPn#dA&{dq>&yd{5Lp=pa<%$*em=~TdQ%rn_v#5`>I!IS>M^uNpl#N|wC@HMBcRTMT#SL;d7 -z<(&BuA6dLkkx|8fWw@PXzCeCBgDx@HJs@)L+j8y~gZ)7)${p-|O7{G? -z&|M6FI|A*^d_U+Of-3`+w(c~-YsQby|NH)g|G7xv|Nek^|Jex)g~z+)I0xPC0460S -LFIp>X81%mY^Bg|U +zcmaf)RZtymu&!}kXmDLfg1h^|-QC?ixG&s2I0Sch5AG1$U4m2?7EFMOsQs1p)$M^xuU52LS<5tyS|A0z!B~T1;5Y)8HZp +zUh9YE!*I`C!>au1!lt}?^7%)ymXa9F0E8%U6cA@Hs@r2|t2YjT?MMEK&sF!xR;P(1 +zJxFf8OgT_&`%_^18f74-j~9B>_v*F_4QG7P$=~I&{g0k-!dKZ;dhG_Yv84aKQ7`JU +zJ^ehid=1+b=_P#o97{5v??~H!^zyIS&U_=f-+Z&XS28Q#IuJUNE}ApzE+z8$!_(s%I3_!)=jTdGmXzz2p&3&czvSwVkj_PR|SM`xDjT-m<)@wFKtJ!fY +z+A9f&c$RQF&Z%Ui9@S9nRjlxMs@)Z5_OxNu^|5JS^tNFPeEv!Mp+fj^Yc}Scf482J +z_jv2_UYgabd?1AMePOH(|ApkUIjM`|sON7?4||4r>}#l#)Nj}LPNV67U-a5cAqgk9 +z4hA)b1i?G`_{?Is2NgH3=G*Y_oV4G*#y>w?4I7fSpx2h|vD&hsqdFVmofnVkNpM8o +zEDOkF7WVse0CrXXeH^X&Y+X5Ugeg(@8XVq_7ngH%kQ4q8to@(w`VD%+t{VjBlZzMA{89 +z;%$e2aiD==VT$}%!%lBbY3xicyog$jB!Djxd7vpR6bXArR{Oqv(5MfWsJg3Yy +zcUpf*M1f-z9ik)^?H|-}` +zxbJl0Xc<(adaW`;Xc^eA&$kJ4EZWH)dOO+mFzw;MBfNjA5<1ZP>E3RWzD|&L1WdK! +z2k&T-AdM3|);yD$reQ{x9G{_#6R5f}9%tdjf-W#_wS$qa(*X;ot*Gkja`g1Q_eN^= +z`0%;Ho3r-6zU-m(+)f%v8KxzXfn20UBXua$j&hd^L+a{0lv^F@IS92IL#!_sffCl2&zHVp_~j(J1np!W5n69+~xPAJ6}_zBa%4jtFt9W +z{@f*=wRJ|ZitBopGm@A{J`xa&M +z)PY`TF0^X2?f!}827nOWNuI-}Ne-gU_A_rT89Qjihq3d_{Ugx}ge|kRq}v@?<-}sM1htR5<=} +zI1L1)$lG(bP|&c#@>`Np6h0xGHe-S%SWq_O*_rH`M&)M5xj9Un#*HS!PqE5 +zISo-XF(NX8c$<8iK|uH&>qt?Q&-b}D+Tgr7t>MFp&WJTZFnPZ1>|RTVqu7iauEwTX +zVJi3CHpH3>2eq__Ox+k#@Bzl=K|7STdhX7MT{c8Ce71~q9Y&PXH}*iaRuCUgMZj4H +z)QyHub +z_qnc(rzc$MCNk878`Sofx_>n{BwDNL?TS=$RO_S6!R*Ey=`(aG@LbB{HGQ+@MqP=h +zu&0VvO0ab!36xlai&*>Xc+6_xPmdSo9TasQ3?*TY!)%lYzD(AZ0HWie+au=#fiLo& +zU+O6Y`-6UchQAZ*C2TI_f~f(2hrMt6KE)jP36+(ZZfle23Dx>Inkk_7xY0&pkp)+N +z%^^0b-mA7bkD<)a8%J{cvSRJ2S;}#v9g(doR}TQ3QGy%7T$YWkQuW{|T0eu$!D%Gg +zhIpru$xwR_h!F-%c~|@zigH-C2m=8{D8VNnCdFPc6Rfz(8f#dDmuUW@`u=TQn?l6ex-ha;(`` +zrS1uS-(@|j8cS+#fW*WdM9k{Fbp6f|!@JL%Gh}@yEWnTjE-DYfVpx0s5?hF9Qzi@Lf>~6Pm?DX{;HP^Q242(r1D1_=jrbppWF;PQk_!Ls +zS?3Zy6SOYNhA^`C9Gr`$aM+kF+PqIpNc~b)YOTag^;@K{!LHyR#-D?kKh>QZn&JHs +z(S}LQ;l-T8IWrlT$vDeig`Pf3fs);`cyZgTesw;vUk*#=1ZlB5zS``R@)U;`I^|DW +z?`Wu5^KI6hZo2(M-a~zF#>3kiX?zjyY=f@)xk3s24jF8WN!RqnV5qMC{5IS-?p~l` +z*Od<2Atam`NRWyKlq2%T>WdXRFci|p)_QD!{us*BG6#&@1J>-ygf`d(+Yt%AR?$|m +zG2&h}ZNhe;3iL&t-&Bo~bSQvwc_uqFF*q*u<%r&3Io&Jc +z8X3Bs8jXqH@NHmV7BRmCYCHHs=Nrep*-}>qojz9eD&96O%Es8n$%gaSnOL~VE%6i@ +z&N;!@pfy%G7dw?+2y1|uMDE?45uzNTNB_7>aX);UvtG>N2^CK4jXJOIypMJdF8LKU +zTYqIdp7&|wl19M2-A~xsFLDE9e-nocdK3)_YdtcQ)W%k7bx|ihJbIc=Z5ZyZ^yh9L +zz(%H87tSJzNkw!4yq5hajBkYU#kO&cksLk7!K-`GO(iyvT=U{|HBlNQU1VB|)w$-~ +z!`vE~Br`P8J<1%ly9{1OIZc%XlCTOPAdcit!jhpR;%=Zn+J^5sT)?#vtC4a+pY5iB +zJDz5Ru-Z>~+fH$VWPdd~FVQ(AT}O25HPC_wANYArttZij2ISLx>m75xSQO6+R*;0g +zmeuq!90F_}HX%kFZpuj4@q)SDa3k?+Bb2PrSZjTt%acFjLT3$4HPduPZ4Sfv?#~)_ +z*x>rvxpNnXh2P;_1YzBnVcqa9VK{mn1MhEaK>}|FhPXm?dB28(cqh2Ag&XIAnbGh%w38mufD688Vg0{`stk3i+PA1e~X7W%o(N09G +z(V+dK5Ra`6>fQc$6V4g$Mc;jTrbmt|ZcfPDi&luFxnBGk{2GGnMACo~C5VWy9A^BK +z%9O|VK>O{=o7e@%H==p}Gh9?4J3)S(^K@|@-bpGMlMM#a6u}N>;hDZ{$m0w+?{P+i +zv!bb`WN0Gnx5bB0s;!iJeK(?O@&xo_Yr==8dbs9N^gw0u(XKa5#%g4gLt%5d9^x&bUp+ +zI*CuQXb^F)LGcsTq00ke&-aZbA7b?Ow}kNZFJJuWYsoo#JJ +zd^|iHd;0^2Lk8)L=de&2-C9OWIvMMW>WH|w6peAk$qJ4MH%Wu;|h=~A6+4h{@J3knK0*pJ@vag9^60=vvWcI&Lb_(VX2 +zy)N7VOA=(g{REg_f)&_ekDo9i1vl8j0R0zl47}1}4kDqz)m%np1-97YCtxX^_8Eb1U&2>fjdHvFw8)9n=PT=mS{*wNJdpIN5Au>lfU5v4<160teocH-d>QHxOk-7@IW}47m1u$uA~w=(B0jA`kk+l2DCPaOxmP~ndvI$ +zYkm8H%IFn;s^>pUrvz6NLyr<`Ro3Korg8A+&kfO!G6vn2h>XJTf5yvnnk!b`Vn06= +zO|u}x(#U)>eRZq|c{Ep6$&^P+2{n)IUvm+$hJWpRp@dc$Pc5;};;;?#x;>0!Q&lV! +z`h5GsX89Y7O)`a6U8!1!!`XBAGrQC|6pr$y?Yi~{n@H;dTYvsSV}Guzrbl=`^4UoI +z8~S7M#L3iCl4D&LZY7p{pxhZgK`flMwzluNP~zogXL!BoNYnrwRFOn1!FLoBg%hgK +zT2%$)cYHjmbW$l?<>3q586J5ELJKn1OZfwK6zZEGypC8YxWSi_nBA+Z_&{j*y_tMb +z6C6(s<>8a1YQkTymwXrrI?Xm2Z(XHsp-_~6s;*Hc@MZxKw?mh=jIMvB--jM9zQDT5 +z_##%J(qN!>z*rOmA{Oc8*IOL7NzRt42R1uBo;?F>^ndx{qY!eko1xoqPknBbx`jeg +zBK1!If?!CHwgxmCjWr7V)0^wAxV{-lm1HGp@U)MCwN_MeX3LZ*jEL+Um3h1ahneA%41;uV#JudJYWnF4<o}yV;v9^YzeZ9DJPbxV +zCaJz8JMuzS|;y@^GISocc73^ZoFw_q)lcpJX%zS +z?3#&5BtAW>(BMlU0{VA<|F{5pf0gcm5ueT^9u0&(YN^<63?O&=!S{pn(` +zLg_%W?ebF_1IK2E8}fXKJRN7Sd1NEd3=zE}{Ff-55EeRtg*n1;E66aMQp_*vt;2W-BHy(2b;Flg4sLL8j`MDJ +zAbfu?@{0+Il12eRII46kiNKmt05>iU=h +z$)Irsw!hHw5wf7*gjxln_O`c8!(m4}pSsbqKLIVrd=!}5jW}+WPlzQ;+_e-& +z?Dy<48J&+h3*@LUmFxqzh_g>rb^`iEl)hiDf5($dZZJpaL!%i&d@Buf3+M~(|w0IKfQ +za3X0Srk%nLvE~Ab9|gBtt2_H<(fw_Zha@}t^K>=dbE+8{uYX2|#N=bmI)Wc;T*rwV +zwd5A@i2kamPB6hHF1AG?W!pUo_~vz+3wdlN<%QSGe!5}^qJ59h?#udS@qUf7 +zv-9ZWcl%ZgYEV62Ov?klP4Ypq+COVB +zzbpQbKJ4p#FTFlCeU?M~M)FWg!L^__)A~q8ym6&0c0f4_^d1Qsf;q;YQPHwFTKQaY +z@}^_vfdLrw7oSN5$O~22BEUPFgd#kF2FBsIH_Toz2Nw=v^=tZBu!NT|Lp7qp(fZ&&7q@7C0rFJD6; +z(%|4PztN>6GF#&@{I1tbNIIaALQ8ulFL8_Y1vGk-QMPKSZe0HpMtxgqkoct%kuq`w +z#x-}Cb*!ytPr?%+STtAMUu{{K-N%@g062$UWI7UOQm3=mc9wknbhD2qEj-!b^P +z%oYhuwx~lumz_3B^a7bYyyq-71@Fw*7ULPhNJocwr5CvLRsE<~sh>maF=R1p!hO** +zh+7MfH?17kb@`xEls`270@5OICG>$(UstdYt%lJ^wwiJK8I1@$5SE2?UF-^CtL8@; +zs4{#zGZBM@8f^QW&S9I{2Bl9>kdJkdQs6??R6c{5q%l*?6D-aNSM(>Zc4);q<1&7n +zVSb1AZyvYG&77Xtb`dpP1hGZw+U_-uc%-;be&gSUcbi*hJ9V!?LnI5O4d&1TOrlrE +z11&b|=uC!5&O5GB^zm!T#ncJ-bmy8|`YuXV_zy3)jPFmR0m +zFLy&N`z42~p5XU|+fn|GAIE2AfPi3JbxB>QXQ+7$3m_ug7v}~qfMAh#5*_)0mSKO^ +z)R>_thix1PNC=^T>X5@o5Ik^s!>_0nb%0+Qu?l@fMu||fRMI8(eq@a06~$a6goXp4 +zTc(!CW&GU`Z?7*~C%0!|`Po;Y-B>bq8(=^Pt0w>CW3cOKf|^OmN3o|I)zb~mlpR!VZRWgf3r$DjB6U@% +zJ!v9xOZ<+LBarT*ahaknq^miC#W^ANPQ%<$&RHDpEBCU_M(sbvsugC-mYh-fO{Sw9 +z2eEARzci;On#5;xRA{kHL-zc9^rxh(B6&XXZ*i0bo|+5(tR}B*i$>CjH@i(J`<5N< +zm*!QawcKB`2qVVWN|!2bmCj+qMz_>lyQe41Uc6GYo8|ZmgRouOWH<`fPtitAzEwsVe{gYe@!;OmfY1hA^J^GP2Zh7jc0#tW +zV;K{f-a2?ll{FjAo&kmu**_ByBXvrN+H7%pUgwrk*v>}T<%nfg$(O1#f`vAf;$Wwj +zK4OU>ekZ7*cXG`zK^{1Jk?6U1Z!$nXMaDUqNo}Oc<%5yn3pWZ=j1+|nlh9DXMmgJp +zw$>=#X^n__>Lz7RpGg`FbOM{jMF-I&Mx~Gtq{nwcJ*VwE0OFOdSNksknPO9!AjUy9a^u}; +zl{GfA#HVPd@8C*|vf;gcdLXrJL?MukrGr%c^ +z`dR^O=T^5*G@CU0fpX=d2?dv}l#Z}rvrURI+yrK9#ndWZg69>4-LW#tEa5!`s{Zgq +z8R@zhQOojaXAAXjJW6}a5>uV1LhgG$u5JQ_EBF0C=A-S5S2BuoH^CBy68!ST^VMKp +z5t!x0xnCI*Lk$t%?=aM?bAC5Sk&8&Qiu@hZj7DiJ;6#WZd1Z764c#+#;>O(U9%lfW +z>suxqZ)SVz&lYoFmEAcgM7u2vPU$2e-Hjzv>AJy1PeOk$DMk`K`~^i^seLl#HX2s@ +z&vS?_kECyji(-+eKdk1750r)$2U(RhTgkZT@l<$kC`GSck-TzG(h{pKG1aJhxkqgZ +zItykNw;mTU?xiP8Q;PAKW4yNPGkd;&0<^_8y4rHh6AzZ1@@Og1z$t3+RoVK`LOEWpvj)dqZ+bn-ZI_R@g2TDm +zUOXS$8{AioF8c*Kd%YqEKoqkyqA= +z;h>9H=F|lLAffO3sj^3_YLHV~t7o60Afgf+&g?fx9El~tAP}$YS=MFe#gI{HMPF+3A4XgD2y6V7pZ8*{ +zm8;APEKL9wC2F|aO=CXGJo^TSmQpb}X_X3Im%nsfn-Yr)Ip(;&N*#Ay_m3?ila&Xh +zA6V?kP!$WD1kP``H7hg@QY|w7?54~1UuB*oXqD_ePJg`i3GPV0EM`;%joWPh;8C{7 +zYdmIemNAl|da??P+nTE06i%eXK303w@_~!CLz4QEZFdnUm~0^2U*Dh4GePdBsTQhV +zsihVr6*e(LETK(_Y=c5vXJenfn3=4BLe-LG|E6?ccR#tlx)pG=|6cC;SaBt^!li5R +zcPgX&c2MsDL}~N-O+3=a0$|oiwZm$c)<&SyI4_0A@|JEcP=7FY3^?#Of0zNSfD^&A$%$p{mSW|9&i*6 +zj(_qDpxvBQ=^ptttH-vj$9~Va*80<33lpe5w3*6)d5BABGb>2&T7!J8KM%t$O}n*W +zJo+7yk8gR<_bN{XJ|u{lon5UfZc>HMFjulERk&KL*jqG{qadfz)xhuQcg|aymb_Y? +zVYhel3JJX|M+K*)DQMX1IZ`*_*vfscZkpLiT)9gL=cKs}uA(KzRP<4d8#RxOLcE#D +zJP9@OB>kt#JaeOXaqm4Kc^GYiehxcy4(-(f*^`-a9<3OAl0lXjMU1hK=(Co4O{$8%UM|E#&*;l(B?QsiT24bqlr*B{Z7V`VuFjMMHlGAysOT^==1z=5qZQ_2R +z-1qLb)#p6A6j}B#jg`CWg~=F5uJg4=mk4 +zMbEFlbNEc>OXUCT5piF*6@<3E+@D1YQ`=LOmdxBa$alJ^s;X9Vnwl%91RCi4CyD~~ +zEfY~;r~^+zF4y_)m=yu>0s3+B%|pI?8RS^ct^$kP#XRzE>S#R+#~GhIc~p)Cii4cW +z9H*m(D~n23;e5HIw0*7&$Qv-cSkS?#GB%E4^9a4Zdg>n0VB=s|P>wkUFR@1Py;++p +zX;6LW6tT+67ZSct6f1(Z{;9<&8!$Q%dsr@?heJCLyu$kE{QNwMcpba!S7M2R5q^_F +z1m`x@%z~KAD3f^-kF`7BW3BU>kYEeLw+hLBNDUxD$O}Z7ySX3c +zb)wd!i4k24wW1_C2@tbyw%f-8qhJmP`&caiZ`w$^LAjZS5Sn#m^9yX>OCkC~g$Cc7>RooBAs^cU +zIlTk#)OXQ82-Til1rliQ85sNCA>X3OzZ4b&8XPSua_&2S?i?lbG}vKCBGdB|nXS>g +zJ0*+o--w^syM8BpvQ@ycNTP2WG0U^*#8-MC0N=cB;m&`}!LXiv%vI8XM1O%D865l( +z{g6XRuw=jeOMjz9WK|@yzj!yA9i}KA0|SHG1bi12L)S{x7e=_kAN~FN)m7xbSP^arS9Rd{|t-bdQUEl`8{54zNMvQ +zmVu~1GPeH>P7JxwZV*CX5cIQzmo3E{siDMziZ%E7Tl9Q4KN4`#}D9_*vX?k}pO!=)gn7_4Bb4bJT +zqDaOnV(7U1_j;to@cwADU9mBc-@BdBUmAHSzyI{7YGVPi_y~b*r-e;$%CQnDe?9;8 +zfw~{4mSb>(|FgeRQE<@@i1>JZxfuACaFBgBIQO3(xsqo~Se?tnEhWOPgi|!6k69%H +zBXMEw6q@;gX1q%5b}P&*(QhwjwHm7%kJPg>aV1XSsKm6t<)rE6*j;x$hUQ|hu`kT) +zV+}ADC0AEh_W-HRr1Y}-%^FExK~@Y^t(ANZuuEJ`p#^k<`-MWnN77L2@X=9jV+>R; +zXOQ`#-WMm65hugihkOgXY4OID(WpNU{=B$ZDs8X^hCKKCdranviTkKK>$2J_;-Ga6 +z>WBEX7GD$0K(CoP7J96eYCwj_U5&HrOXJSWm=N0MQ^#7X5>(8zV6XiWLH3_ZhnV9@qF1Eb95#jw+CTK +zcnC_X6?w!ouwb8!t?ZeXbU*`_*tn=L1`tKaPq~o#XH-LT(pdaeEr(+5o7_BF^YP^9 +z=s=xqrRelm)Z^rj$VCV;RnXkG!NaMn=)gAL=kN77LMYwzIqFtY;-;Q!9U{UKkl*Z; +zxmwdAck=k)YYlsT2UM!0spVa*x7IFL)Qt{!?hIJJcZxQPc`eiw~~Oj@Tz_oM0xtx3Lb{5kxu +zyBD?uz>WN#g_E*U&crG80;MCX-DnFuJuz_nIeOw6$6c?&s+F|L2zU?5G!ekeS!llo +zFPgW-3Pcj`}O?5W?ab_h%Gy97f=v~(o +zy&qFFhNcAIGR5-l!~O!ti+&6tBv?y$VCZ!G*COZC^Rd=v3DD{VK&YZV`0rM0q-=5@nOTtcx@ +z-`GfyVTF_)=xoTY-xG)BHAl-#;@k>0Kap5G)B~X77JGh`U;(W#+Xleny2|+?3X~v9 +z@j4(Oa(GxV=hv@n1U4Y(PY6pg$c&Ot;)efq)~zTw>;uHy`pS!hYaNUHxEYhbgRg4R +z+}+}7o`g)4OPEQ|;tiYeawTA$%HmQyClOH{QqjoI$3uxnpv;6|Hoy*8NC^3e-^$N* +zqqby_w*0S5T>t%`@v?z_`@m;FByBE`COSJ7m_~uq^-Bim*HTzq_chCA9jeHpXN(2n +zwRqW7h)`1w=SY~Q#F+#wWc43wU)ql>D-{W#MMi*+Rc<(sqj$1IsI?*Vo~~JX4iGFY +zSjVn{Ia}(<$;mhGkK6li&$laGUX5+PgyS=U#yks+rN3QUeb1{R0P)Mr;duDNP0Yns +zOl80yG--mz(9cLJmrW%6skc}}J*KYlL*%B2MMfm>8W3{uoeA1tCC=;U0l+}4z>%rz1`1Gu3qlk(DUqGWSub-M#qTbUB+d9M069OLgJ6ct8Id?;aM)g-r9s^V6BrQ}Q;SCiP`udh7DC +zQX$nG;n1i3pom{#4@R?{E?z&>^3sL?I2rH<%HigVl9la73e4N^TR>PE}F +zsi3VDlCxI}2NOm!ndIQSbW~gNZ4rN(jki^a>Fbq! +zqTN5 +zzb`nx8&_h%Jrt7lQxR^o;6yE0jUGfj6BHagGKnEIbC?*Yeh-mN_p6 +zlPomN>R(3=k&0Ki-xElR=54S +ziifTvyozV0-H|T?}miG^F_wtBpw#IDTI~O&zZ=pp6zI7~U;(eX9v~ +z%_Rrklp$gbO-9{o@iq>QY$8+WLWjtqUprlw=!9l&&i<-B;;B?gDuUYF04x={Q|PYo +z11qyPuIW6^msVN_PE8KdAMXa}bHL6LC^fQ9sh369#H1cfF?JZ}v`b#V$&6F1HA?9- +z8rMp!9QAw;KUupJE(75s%Q_j;=twh?gcLwR?pti!=J%3LhEmj*cmxEL#xOjNHpVeK +zJkF%}PF#r=gweO>TUjCt`~eJ7()chG!YE-`x^-8vG;ltjSQ*{>Exm{gthe@Wqr_;) +z0wt5sLc;HhZgRcM=_rjYuGPk6qTcdMHcs}#u#-NnrJ>ijEn2POpi%bVAyH$%NC@JW +z!9x#~LZ0#)=w{X8oW39GR&eJl^`<7%yQQ1IMRYe1(f#2jGXHCzX6=QT%WeN8>DptC +zHdSdtJVzrAI(JAmUV3k0>(|f-Xp$15@*N%7K>n%=8xkhRkB3QAUtf=ah{(e3zoSSq +z_gFfN{zLz`jCqlr&;1O+r(+F_Z0oUu;MXftO1`Y +z9;O;>OCXbj;jbt_S7jVfllzmVYhq*#nMM~j1j#8VFg%#?vdErxSYKI2XR#z#^jrF| +z60VzCe$K!`P7W(fGZ`zDbu=Gj|Fluc!xb3b3?KS{Jm5T)ZILV)F5q8zrZN3x1!?Fl +zj24#65txQAH>pypq52gcF^Lw8LkW1LoMwVHld&c-soCEOJ`7#g5|?z#rkMgkK7BD? +zv5)5fIFMR6Y+7b6;Ou);_P~PlRc2e$)>HPum(WG>M&1%61LbYx=>T1OuOHP=A_2Ml +zUJa0_6*NB&eSM@;e}$dm67YWg_RVCo!)>o6Rkzh4GG20Rk8#RK+5)kj +zy-EvI3s#yE&SmNou7&*UrnmOiQ_-c!M98x?rSX}WW}0I7mNW&~u)Vo_w^FUmMKUp> +z8k)=i)!=z!;!K+sl(Lhz*Vd$PEuCsaMon#-vS>REEy6K+i5a(<$=x(75fa)xG@=%o +zR1GQOG=s!5g(EG{JieFH*|kCh7=CEGG~xLSIY@MDuIiAnc`G2Ge{P@B(m6G +z!ibqfOA9p9!7d%@C@Z6Oj!J3yF%OjokW8F{Y}gut?pbEsRm(4LL??RqN~(!1fsK#O +zx=08kW?ie)L(K_4s$=P~flB)?RT~0m>*m4)K}Eg&^ysOF8lN +zUHK0Q90oI&{$mRN4;~O7eZ2)RYWiOSNUxax118K@axIASH?!$hWNTeE-m< +z9|d2NgO0N~GYHc0yR$}HApgS_*(Si(CRarIKe5r*$mNd^46r(X7=_aLFxEIYsbgvH +znrzh|J#4IY*379ZTcw$}tG6{QE7PnE4Rz`3%NtHKG_U~aaSk@Sx>k@6ej8+~c|Yc1 +zO&By$u_ANpr;D`5D&%W#Fdl9`BhvdZ5`UZwLv{1Hpy9lA>ut_To&@^KV8eBInUrO5 +zh52}zCbS}L24&AucCm_(e?;?E_ef|R)nd$k+BOlW94v|UU~blRLjQ0ZP-4r2%|3Mn +z>o)c|#p9v2Mo^cLhvg|xC^b2rL@3y2qYKOs?@M}`_`2q==9(4=kTk_PZBIhX-PBrZ +zr~4n>by9I>XJ-@K+>o8|G;Pd^cW)?r)m~#|TJhd}QmeX{jlF$FjtCHM4zkU<60>Zs +z%Hys(I^Fbs!^Li)<*(mdMDF~twQ_bC9DMnUdoO<&F-3^A3(9GW4BH?t7v#5rXa(*RMsaFXpk@rOtgnql#(8*wa~=>H&U=;wN0Q<% +z=~0Qf+>{j>5oC?u{)Ajpd<^k1GgPzB2_X=HLz81#(ra*Wz}OO-za_H(wqrv+ +zz0y`v?a{P}lFJz=@BUy(A)pd~b{ghG$JJ7r@AlNxR+>kt6nYMil7}v99Ja?<@UZ3T +zeP1&kMRSM{5+R84Gc9j#ct$;ly+^es_n)lXhG>_EcB%`8iYCWLpCv8)3~8MaxHrGc +zWH36`!Flt6p(JJsBEPqrE&gHZ?iZtxyx?@fgPx*GS)go(Nf7>mW01|;SB);nF)3s-o4wF7D!)tc}@L$K1~NQb +z#Yr2Tunx+&wm$nlh2CtbCg8*b5`pf^Y+pukoQ>UqK#>9GQek~Po6Bh899xq^a4oaN +z9sDuzXNM=T^ExFYu?oyxI-}8y%D;slDQ*$`e5+$KKq!pF-*Qc6*L_WdXk^K$IEown +zc`-GIjJQlcjeh%cL}$EWcnajL%v-BuW@70M(BzzY-<$NJlWQg2rNIpwvZO(rx6c;G +z_UBD)7Cj+GP^Rw?)N_Nikx*qcIPWa%MBy?TL-6TWG;|5d3z|f%7il*;Ac9f={o-sOWXfH2ow& +z+F%t%kw65bbTBi=kaCFWiK~y^%2iyKohma@H`Ql2SmxhqN|;zqx3*C&8_FG(8wPqn +z80VlP%Gr)DvZLLlMf_OsXDo*4wm909tv4{~9yF8NS%e&sJ#dPsVWzk;(a?)XK|KjU +zmKml2h#A~>%-bFxM<7`wSX>`I?z8$Ca++fy%HqqV=8QYYD~bl^Hz_tBVxFF`f!?T6 +z!OC4>a={OOkbTFV#ew8k2GrG${kNo(rcXXA_NWUqI*@?8f!7jnu3$bUg%u}bhY5Q));;cCAc0gS +zHeTk{K!dAfJ6}@_zTLUn#qe2z2>ZdYkePg(!A+9v>R>`9$hU~PuED*xe7hANwC~xc +zzMc7YMmZr7Iy0P~w;nbL>dml8nV{FL;+xs}qjWkGV5~K1I6DPEC&#K9z5E?@9vBT9 +zvo#L&#*9687;Wd0D#-M4&3F8(7sFq)qrj$;8%`og3#@6+hSB^|^UtXtP#SOBvdY^G +znH{rdVJq%P=QxzF3KPx3etK`XD%|1rVH#OZ35YdYtyAh8`vg5MWd_yI4)jPAmo4j_!3e<(RzCocf`Y+$BAs988hq->eMY}S?z>|#t_c*3a#|wBAi{r! +z{dW0rO)!J3t~1!Um(@E{ATxo*eW!!k$}$1~;aQ@PPH8`A%_SDxVmA)U!Hw)$KXA7$ +zqdYbaY15D(b-OI$URl0+-TYf+!wm}Fwiu|ApRr6t288`7`y!ZbjuZgH`OF0cwYAez +zqSFt2_caUMO6L4Xk>1Be-C +zNHX4bgVd8eU&h^$7@$FnL%%Qp$e+fZ(4dAotr#y7!RrZ>u)-F!F&*jOE8kA5rqU|| +zkg!kLmDxaol3FWgZ=YGJwHYE#cf7j}8z24RotEJKC)?r64}@x}^89m-1nf0~ +z*_bz@JP+Ml3hd*HWuOR@sNVh74L-Sw?LaYKwKo+rvy}#|aFc!~jT1o|KFR)cI+)Bn +z7Gg?S>|0zfR!%gT?WBBV*!!8j6W>|lJse7F&5>m#;ooWbRQhP@izf8nK?3n;AClTI +z6#M340iQgXluMzeY19}<(0FQ=O$wq@ql-?Y9&<2A-S>4Nw#z1Z-(eOaL`iCMI&1sAHP4i1wfU%}{TH10ti=qYU +zDz0-eM;$$6p`VP-jrsMCM}MB&A!(m3WE#f9F_{oZS)?8^0-?^g11w23S(X*2v9^k* +zKU)$N`g+?WLff<~UDFNP<{vgF`ivNrY!#|!D3|%nvN;axyiKQdEH}n|UAvW!JH2@P +z6TzqIA6}zL<{b4pMQp)4ffz(REKD*y3@}3^xF7ui{>6upo0Tm&dOIrt&>JXx_VQrn +z?-nhZdK!u;m!%$urT+S%i$tA>aj?l1`%j#jH%{|kdYyAos^NAM25jH<6TePW$nes= +z1!HeZ;$v}XEv4u4(RnINU~U}A*?wwCqU9m|k--nxsx^vf5AeRn$pVh?0Mnuc`C!uLu2;Vg{7)wfw`U +zX;*Wa;BHUq-TwcZ=lb=LAJ!W;9=uX-aQwln)6svvPf%SQ<1JdhQIPpzpQJ_KDid+% +z!(xv_|7G`-+M9p4uk#~(Mx)cG<|di_EPs|%wf~Qb+;nQM%q9N4&z7FNB6Z+G+^+MR +zj)|=QD8BER{dSeRdtd$LH*1N?VC!qI+*y}-;)|d!tvt|0N +zm5Vlct%>!zH1~C#{PXnRXO%R17-p8ep7o3QUvcWms)tYH$`9TvKIF>&@BVzZ?VI=h +zpErH+ydwvGOs@R*Hs)&kpXVngrCvTXb;0-d@xj~oPM7_l|L;HY`3dlY6p$IBU;poR +XXyugpZ1#qMfq}u()z4*}Q$iB}^Bg|U literal 0 HcmV?d00001 diff --git a/patches/server/0735-Configurable-chat-thread-limit.patch b/patches/server/0735-Configurable-chat-thread-limit.patch index 1432c0659448..a33f8940e21a 100644 --- a/patches/server/0735-Configurable-chat-thread-limit.patch +++ b/patches/server/0735-Configurable-chat-thread-limit.patch @@ -22,7 +22,7 @@ is actually processed, this is honestly really just exposed for the misnomers or who just wanna ensure that this won't grow over a specific size if chat gets stupidly active diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 904d2f96a60e72aa089fdfe6be08044b04f995c1..36b96e0ed5c0d25068ec4678eddd8a19a020d345 100644 +index 61ad89ab1811b6a0b6248982b9c6e57354609cfd..b8b22b92da8ae14bf1fa91fffa64af29552ce7dd 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -327,7 +327,18 @@ public class GlobalConfiguration extends ConfigurationPart { diff --git a/patches/server/0929-Add-onboarding-message-for-initial-server-start.patch b/patches/server/0929-Add-onboarding-message-for-initial-server-start.patch index 14f6aa902dc0..e208c53c898a 100644 --- a/patches/server/0929-Add-onboarding-message-for-initial-server-start.patch +++ b/patches/server/0929-Add-onboarding-message-for-initial-server-start.patch @@ -17,7 +17,7 @@ index d9502ba028a96f9cc846f9ed428bd8066b857ca3..87e5f614ba988547a827486740db217e node = loader.load(); this.verifyGlobalConfigVersion(node); diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 36b96e0ed5c0d25068ec4678eddd8a19a020d345..8a0cb603cd4dbfa1839e0f4e1606876cbb373277 100644 +index b8b22b92da8ae14bf1fa91fffa64af29552ce7dd..45d14ea9b76e3c081b47f71b9604066aafcf0362 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -27,6 +27,7 @@ public class GlobalConfiguration extends ConfigurationPart { diff --git a/patches/server/1038-Moonrise-optimisation-patches.patch b/patches/server/1038-Moonrise-optimisation-patches.patch index d39fa0eab58b..d0c3212ab7e1 100644 --- a/patches/server/1038-Moonrise-optimisation-patches.patch +++ b/patches/server/1038-Moonrise-optimisation-patches.patch @@ -23189,7 +23189,7 @@ index 0000000000000000000000000000000000000000..85950a1aa732ab8c01ad28bec9e0de14 + } +} diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 8a0cb603cd4dbfa1839e0f4e1606876cbb373277..e4df6312fc676ab2d573f060b007e0442d60a6a9 100644 +index 45d14ea9b76e3c081b47f71b9604066aafcf0362..1fffbb92cae6c575470e8b0b15a0693ffa5bc20a 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -244,6 +244,23 @@ public class GlobalConfiguration extends ConfigurationPart { diff --git a/patches/server/1041-Add-config-for-max-minecart-speed-gamerule.patch b/patches/server/1041-Add-config-for-max-minecart-speed-gamerule.patch new file mode 100644 index 000000000000..0f017c93c55d --- /dev/null +++ b/patches/server/1041-Add-config-for-max-minecart-speed-gamerule.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Fri, 25 Oct 2024 14:04:54 -0700 +Subject: [PATCH] Add config for max minecart speed gamerule + + +diff --git a/src/main/java/net/minecraft/world/level/GameRules.java b/src/main/java/net/minecraft/world/level/GameRules.java +index 4ae47c2c5a6bcfbf932d000a80974463e2d3818d..22ca759954420ace26cafab4c10b69d5f906ded3 100644 +--- a/src/main/java/net/minecraft/world/level/GameRules.java ++++ b/src/main/java/net/minecraft/world/level/GameRules.java +@@ -120,7 +120,7 @@ public class GameRules { + public static final GameRules.Key RULE_GLOBAL_SOUND_EVENTS = GameRules.register("globalSoundEvents", GameRules.Category.MISC, GameRules.BooleanValue.create(true)); + public static final GameRules.Key RULE_DO_VINES_SPREAD = GameRules.register("doVinesSpread", GameRules.Category.UPDATES, GameRules.BooleanValue.create(true)); + public static final GameRules.Key RULE_ENDER_PEARLS_VANISH_ON_DEATH = GameRules.register("enderPearlsVanishOnDeath", GameRules.Category.PLAYER, GameRules.BooleanValue.create(true)); +- public static final GameRules.Key RULE_MINECART_MAX_SPEED = GameRules.register("minecartMaxSpeed", GameRules.Category.MISC, GameRules.IntegerValue.create(8, 1, 1000, FeatureFlagSet.of(FeatureFlags.MINECART_IMPROVEMENTS), (minecraftserver, gamerules_gameruleint) -> { ++ public static final GameRules.Key RULE_MINECART_MAX_SPEED = GameRules.register("minecartMaxSpeed", GameRules.Category.MISC, GameRules.IntegerValue.create(8, 1, io.papermc.paper.configuration.GlobalConfiguration.get().misc.maxMinecartGamerule.or(1000), FeatureFlagSet.of(FeatureFlags.MINECART_IMPROVEMENTS), (minecraftserver, gamerules_gameruleint) -> { // Paper - max minecart speed config + })); + public static final GameRules.Key RULE_SPAWN_CHUNK_RADIUS = GameRules.register("spawnChunkRadius", GameRules.Category.MISC, GameRules.IntegerValue.create(2, 0, 32, FeatureFlagSet.of(), (minecraftserver, gamerules_gameruleint) -> { + ServerLevel worldserver = minecraftserver; // CraftBukkit - per-world From ba1ee87e70d4e7b0fff2ee3ec7ce0118ee1cc9af Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 25 Oct 2024 14:10:40 -0700 Subject: [PATCH 083/119] Revert "Add max minecarft speed gamerule config" This reverts commit 61136fe43bb61538716c68c6049cc0bd15d40190. --- patches/server/0005-Paper-config-files.patch | 5 +- patches/server/0009-MC-Utils.patch | 2 +- patches/server/0489-Improve-ServerGUI.patch | 647 +++++++++--------- .../0735-Configurable-chat-thread-limit.patch | 2 +- ...ing-message-for-initial-server-start.patch | 2 +- .../1038-Moonrise-optimisation-patches.patch | 2 +- ...nfig-for-max-minecart-speed-gamerule.patch | 19 - 7 files changed, 329 insertions(+), 350 deletions(-) delete mode 100644 patches/server/1041-Add-config-for-max-minecart-speed-gamerule.patch diff --git a/patches/server/0005-Paper-config-files.patch b/patches/server/0005-Paper-config-files.patch index 0256844bd941..3303f32c8ae6 100644 --- a/patches/server/0005-Paper-config-files.patch +++ b/patches/server/0005-Paper-config-files.patch @@ -487,10 +487,10 @@ index 0000000000000000000000000000000000000000..d9502ba028a96f9cc846f9ed428bd806 +} diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java new file mode 100644 -index 0000000000000000000000000000000000000000..e845592621f931ae94b0f7007d5d8cf417c7086b +index 0000000000000000000000000000000000000000..7e88b1fc1ff700a7771b38f139f4472eaeaf8714 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -0,0 +1,356 @@ +@@ -0,0 +1,355 @@ +package io.papermc.paper.configuration; + +import co.aikar.timings.MinecraftTimings; @@ -835,7 +835,6 @@ index 0000000000000000000000000000000000000000..e845592621f931ae94b0f7007d5d8cf4 + public IntOr.Default compressionLevel = IntOr.Default.USE_DEFAULT; + @Comment("Defines the leniency distance added on the server to the interaction range of a player when validating interact packets.") + public DoubleOr.Default clientInteractionLeniencyDistance = DoubleOr.Default.USE_DEFAULT; -+ public IntOr.Default maxMinecartGamerule = io.papermc.paper.configuration.type.number.IntOr.Default.USE_DEFAULT; + } + + public BlockUpdates blockUpdates; diff --git a/patches/server/0009-MC-Utils.patch b/patches/server/0009-MC-Utils.patch index 10229c032639..b7549f7365ac 100644 --- a/patches/server/0009-MC-Utils.patch +++ b/patches/server/0009-MC-Utils.patch @@ -4542,7 +4542,7 @@ index 46cab7a8c7b87ab01b26074b04f5a02b3907cfc4..49019b4a9bc4e634d54a9b0acaf9229a + // Paper end } diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index e845592621f931ae94b0f7007d5d8cf417c7086b..61ad89ab1811b6a0b6248982b9c6e57354609cfd 100644 +index 7e88b1fc1ff700a7771b38f139f4472eaeaf8714..904d2f96a60e72aa089fdfe6be08044b04f995c1 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -242,7 +242,7 @@ public class GlobalConfiguration extends ConfigurationPart { diff --git a/patches/server/0489-Improve-ServerGUI.patch b/patches/server/0489-Improve-ServerGUI.patch index 48a151cd82f1..8dde1d1a9bc4 100644 --- a/patches/server/0489-Improve-ServerGUI.patch +++ b/patches/server/0489-Improve-ServerGUI.patch @@ -102,330 +102,329 @@ new file mode 100644 index 0000000000000000000000000000000000000000..8b924977b7886df9ab8790b1e4ff9b1c04a2af45 GIT binary patch literal 16900 -zcmaf)RZtymu&!}kXmDLfg1h^|-QC?ixG&s2I0Sch5AG1$U4m2?7EFMOsQs1p)$M^xuU52LS<5tyS|A0z!B~T1;5Y)8HZp -zUh9YE!*I`C!>au1!lt}?^7%)ymXa9F0E8%U6cA@Hs@r2|t2YjT?MMEK&sF!xR;P(1 -zJxFf8OgT_&`%_^18f74-j~9B>_v*F_4QG7P$=~I&{g0k-!dKZ;dhG_Yv84aKQ7`JU -zJ^ehid=1+b=_P#o97{5v??~H!^zyIS&U_=f-+Z&XS28Q#IuJUNE}ApzE+z8$!_(s%I3_!)=jTdGmXzz2p&3&czvSwVkj_PR|SM`xDjT-m<)@wFKtJ!fY -z+A9f&c$RQF&Z%Ui9@S9nRjlxMs@)Z5_OxNu^|5JS^tNFPeEv!Mp+fj^Yc}Scf482J -z_jv2_UYgabd?1AMePOH(|ApkUIjM`|sON7?4||4r>}#l#)Nj}LPNV67U-a5cAqgk9 -z4hA)b1i?G`_{?Is2NgH3=G*Y_oV4G*#y>w?4I7fSpx2h|vD&hsqdFVmofnVkNpM8o -zEDOkF7WVse0CrXXeH^X&Y+X5Ugeg(@8XVq_7ngH%kQ4q8to@(w`VD%+t{VjBlZzMA{89 -z;%$e2aiD==VT$}%!%lBbY3xicyog$jB!Djxd7vpR6bXArR{Oqv(5MfWsJg3Yy -zcUpf*M1f-z9ik)^?H|-}` -zxbJl0Xc<(adaW`;Xc^eA&$kJ4EZWH)dOO+mFzw;MBfNjA5<1ZP>E3RWzD|&L1WdK! -z2k&T-AdM3|);yD$reQ{x9G{_#6R5f}9%tdjf-W#_wS$qa(*X;ot*Gkja`g1Q_eN^= -z`0%;Ho3r-6zU-m(+)f%v8KxzXfn20UBXua$j&hd^L+a{0lv^F@IS92IL#!_sffCl2&zHVp_~j(J1np!W5n69+~xPAJ6}_zBa%4jtFt9W -z{@f*=wRJ|ZitBopGm@A{J`xa&M -z)PY`TF0^X2?f!}827nOWNuI-}Ne-gU_A_rT89Qjihq3d_{Ugx}ge|kRq}v@?<-}sM1htR5<=} -zI1L1)$lG(bP|&c#@>`Np6h0xGHe-S%SWq_O*_rH`M&)M5xj9Un#*HS!PqE5 -zISo-XF(NX8c$<8iK|uH&>qt?Q&-b}D+Tgr7t>MFp&WJTZFnPZ1>|RTVqu7iauEwTX -zVJi3CHpH3>2eq__Ox+k#@Bzl=K|7STdhX7MT{c8Ce71~q9Y&PXH}*iaRuCUgMZj4H -z)QyHub -z_qnc(rzc$MCNk878`Sofx_>n{BwDNL?TS=$RO_S6!R*Ey=`(aG@LbB{HGQ+@MqP=h -zu&0VvO0ab!36xlai&*>Xc+6_xPmdSo9TasQ3?*TY!)%lYzD(AZ0HWie+au=#fiLo& -zU+O6Y`-6UchQAZ*C2TI_f~f(2hrMt6KE)jP36+(ZZfle23Dx>Inkk_7xY0&pkp)+N -z%^^0b-mA7bkD<)a8%J{cvSRJ2S;}#v9g(doR}TQ3QGy%7T$YWkQuW{|T0eu$!D%Gg -zhIpru$xwR_h!F-%c~|@zigH-C2m=8{D8VNnCdFPc6Rfz(8f#dDmuUW@`u=TQn?l6ex-ha;(`` -zrS1uS-(@|j8cS+#fW*WdM9k{Fbp6f|!@JL%Gh}@yEWnTjE-DYfVpx0s5?hF9Qzi@Lf>~6Pm?DX{;HP^Q242(r1D1_=jrbppWF;PQk_!Ls -zS?3Zy6SOYNhA^`C9Gr`$aM+kF+PqIpNc~b)YOTag^;@K{!LHyR#-D?kKh>QZn&JHs -z(S}LQ;l-T8IWrlT$vDeig`Pf3fs);`cyZgTesw;vUk*#=1ZlB5zS``R@)U;`I^|DW -z?`Wu5^KI6hZo2(M-a~zF#>3kiX?zjyY=f@)xk3s24jF8WN!RqnV5qMC{5IS-?p~l` -z*Od<2Atam`NRWyKlq2%T>WdXRFci|p)_QD!{us*BG6#&@1J>-ygf`d(+Yt%AR?$|m -zG2&h}ZNhe;3iL&t-&Bo~bSQvwc_uqFF*q*u<%r&3Io&Jc -z8X3Bs8jXqH@NHmV7BRmCYCHHs=Nrep*-}>qojz9eD&96O%Es8n$%gaSnOL~VE%6i@ -z&N;!@pfy%G7dw?+2y1|uMDE?45uzNTNB_7>aX);UvtG>N2^CK4jXJOIypMJdF8LKU -zTYqIdp7&|wl19M2-A~xsFLDE9e-nocdK3)_YdtcQ)W%k7bx|ihJbIc=Z5ZyZ^yh9L -zz(%H87tSJzNkw!4yq5hajBkYU#kO&cksLk7!K-`GO(iyvT=U{|HBlNQU1VB|)w$-~ -z!`vE~Br`P8J<1%ly9{1OIZc%XlCTOPAdcit!jhpR;%=Zn+J^5sT)?#vtC4a+pY5iB -zJDz5Ru-Z>~+fH$VWPdd~FVQ(AT}O25HPC_wANYArttZij2ISLx>m75xSQO6+R*;0g -zmeuq!90F_}HX%kFZpuj4@q)SDa3k?+Bb2PrSZjTt%acFjLT3$4HPduPZ4Sfv?#~)_ -z*x>rvxpNnXh2P;_1YzBnVcqa9VK{mn1MhEaK>}|FhPXm?dB28(cqh2Ag&XIAnbGh%w38mufD688Vg0{`stk3i+PA1e~X7W%o(N09G -z(V+dK5Ra`6>fQc$6V4g$Mc;jTrbmt|ZcfPDi&luFxnBGk{2GGnMACo~C5VWy9A^BK -z%9O|VK>O{=o7e@%H==p}Gh9?4J3)S(^K@|@-bpGMlMM#a6u}N>;hDZ{$m0w+?{P+i -zv!bb`WN0Gnx5bB0s;!iJeK(?O@&xo_Yr==8dbs9N^gw0u(XKa5#%g4gLt%5d9^x&bUp+ -zI*CuQXb^F)LGcsTq00ke&-aZbA7b?Ow}kNZFJJuWYsoo#JJ -zd^|iHd;0^2Lk8)L=de&2-C9OWIvMMW>WH|w6peAk$qJ4MH%Wu;|h=~A6+4h{@J3knK0*pJ@vag9^60=vvWcI&Lb_(VX2 -zy)N7VOA=(g{REg_f)&_ekDo9i1vl8j0R0zl47}1}4kDqz)m%np1-97YCtxX^_8Eb1U&2>fjdHvFw8)9n=PT=mS{*wNJdpIN5Au>lfU5v4<160teocH-d>QHxOk-7@IW}47m1u$uA~w=(B0jA`kk+l2DCPaOxmP~ndvI$ -zYkm8H%IFn;s^>pUrvz6NLyr<`Ro3Korg8A+&kfO!G6vn2h>XJTf5yvnnk!b`Vn06= -zO|u}x(#U)>eRZq|c{Ep6$&^P+2{n)IUvm+$hJWpRp@dc$Pc5;};;;?#x;>0!Q&lV! -z`h5GsX89Y7O)`a6U8!1!!`XBAGrQC|6pr$y?Yi~{n@H;dTYvsSV}Guzrbl=`^4UoI -z8~S7M#L3iCl4D&LZY7p{pxhZgK`flMwzluNP~zogXL!BoNYnrwRFOn1!FLoBg%hgK -zT2%$)cYHjmbW$l?<>3q586J5ELJKn1OZfwK6zZEGypC8YxWSi_nBA+Z_&{j*y_tMb -z6C6(s<>8a1YQkTymwXrrI?Xm2Z(XHsp-_~6s;*Hc@MZxKw?mh=jIMvB--jM9zQDT5 -z_##%J(qN!>z*rOmA{Oc8*IOL7NzRt42R1uBo;?F>^ndx{qY!eko1xoqPknBbx`jeg -zBK1!If?!CHwgxmCjWr7V)0^wAxV{-lm1HGp@U)MCwN_MeX3LZ*jEL+Um3h1ahneA%41;uV#JudJYWnF4<o}yV;v9^YzeZ9DJPbxV -zCaJz8JMuzS|;y@^GISocc73^ZoFw_q)lcpJX%zS -z?3#&5BtAW>(BMlU0{VA<|F{5pf0gcm5ueT^9u0&(YN^<63?O&=!S{pn(` -zLg_%W?ebF_1IK2E8}fXKJRN7Sd1NEd3=zE}{Ff-55EeRtg*n1;E66aMQp_*vt;2W-BHy(2b;Flg4sLL8j`MDJ -zAbfu?@{0+Il12eRII46kiNKmt05>iU=h -z$)Irsw!hHw5wf7*gjxln_O`c8!(m4}pSsbqKLIVrd=!}5jW}+WPlzQ;+_e-& -z?Dy<48J&+h3*@LUmFxqzh_g>rb^`iEl)hiDf5($dZZJpaL!%i&d@Buf3+M~(|w0IKfQ -za3X0Srk%nLvE~Ab9|gBtt2_H<(fw_Zha@}t^K>=dbE+8{uYX2|#N=bmI)Wc;T*rwV -zwd5A@i2kamPB6hHF1AG?W!pUo_~vz+3wdlN<%QSGe!5}^qJ59h?#udS@qUf7 -zv-9ZWcl%ZgYEV62Ov?klP4Ypq+COVB -zzbpQbKJ4p#FTFlCeU?M~M)FWg!L^__)A~q8ym6&0c0f4_^d1Qsf;q;YQPHwFTKQaY -z@}^_vfdLrw7oSN5$O~22BEUPFgd#kF2FBsIH_Toz2Nw=v^=tZBu!NT|Lp7qp(fZ&&7q@7C0rFJD6; -z(%|4PztN>6GF#&@{I1tbNIIaALQ8ulFL8_Y1vGk-QMPKSZe0HpMtxgqkoct%kuq`w -z#x-}Cb*!ytPr?%+STtAMUu{{K-N%@g062$UWI7UOQm3=mc9wknbhD2qEj-!b^P -z%oYhuwx~lumz_3B^a7bYyyq-71@Fw*7ULPhNJocwr5CvLRsE<~sh>maF=R1p!hO** -zh+7MfH?17kb@`xEls`270@5OICG>$(UstdYt%lJ^wwiJK8I1@$5SE2?UF-^CtL8@; -zs4{#zGZBM@8f^QW&S9I{2Bl9>kdJkdQs6??R6c{5q%l*?6D-aNSM(>Zc4);q<1&7n -zVSb1AZyvYG&77Xtb`dpP1hGZw+U_-uc%-;be&gSUcbi*hJ9V!?LnI5O4d&1TOrlrE -z11&b|=uC!5&O5GB^zm!T#ncJ-bmy8|`YuXV_zy3)jPFmR0m -zFLy&N`z42~p5XU|+fn|GAIE2AfPi3JbxB>QXQ+7$3m_ug7v}~qfMAh#5*_)0mSKO^ -z)R>_thix1PNC=^T>X5@o5Ik^s!>_0nb%0+Qu?l@fMu||fRMI8(eq@a06~$a6goXp4 -zTc(!CW&GU`Z?7*~C%0!|`Po;Y-B>bq8(=^Pt0w>CW3cOKf|^OmN3o|I)zb~mlpR!VZRWgf3r$DjB6U@% -zJ!v9xOZ<+LBarT*ahaknq^miC#W^ANPQ%<$&RHDpEBCU_M(sbvsugC-mYh-fO{Sw9 -z2eEARzci;On#5;xRA{kHL-zc9^rxh(B6&XXZ*i0bo|+5(tR}B*i$>CjH@i(J`<5N< -zm*!QawcKB`2qVVWN|!2bmCj+qMz_>lyQe41Uc6GYo8|ZmgRouOWH<`fPtitAzEwsVe{gYe@!;OmfY1hA^J^GP2Zh7jc0#tW -zV;K{f-a2?ll{FjAo&kmu**_ByBXvrN+H7%pUgwrk*v>}T<%nfg$(O1#f`vAf;$Wwj -zK4OU>ekZ7*cXG`zK^{1Jk?6U1Z!$nXMaDUqNo}Oc<%5yn3pWZ=j1+|nlh9DXMmgJp -zw$>=#X^n__>Lz7RpGg`FbOM{jMF-I&Mx~Gtq{nwcJ*VwE0OFOdSNksknPO9!AjUy9a^u}; -zl{GfA#HVPd@8C*|vf;gcdLXrJL?MukrGr%c^ -z`dR^O=T^5*G@CU0fpX=d2?dv}l#Z}rvrURI+yrK9#ndWZg69>4-LW#tEa5!`s{Zgq -z8R@zhQOojaXAAXjJW6}a5>uV1LhgG$u5JQ_EBF0C=A-S5S2BuoH^CBy68!ST^VMKp -z5t!x0xnCI*Lk$t%?=aM?bAC5Sk&8&Qiu@hZj7DiJ;6#WZd1Z764c#+#;>O(U9%lfW -z>suxqZ)SVz&lYoFmEAcgM7u2vPU$2e-Hjzv>AJy1PeOk$DMk`K`~^i^seLl#HX2s@ -z&vS?_kECyji(-+eKdk1750r)$2U(RhTgkZT@l<$kC`GSck-TzG(h{pKG1aJhxkqgZ -zItykNw;mTU?xiP8Q;PAKW4yNPGkd;&0<^_8y4rHh6AzZ1@@Og1z$t3+RoVK`LOEWpvj)dqZ+bn-ZI_R@g2TDm -zUOXS$8{AioF8c*Kd%YqEKoqkyqA= -z;h>9H=F|lLAffO3sj^3_YLHV~t7o60Afgf+&g?fx9El~tAP}$YS=MFe#gI{HMPF+3A4XgD2y6V7pZ8*{ -zm8;APEKL9wC2F|aO=CXGJo^TSmQpb}X_X3Im%nsfn-Yr)Ip(;&N*#Ay_m3?ila&Xh -zA6V?kP!$WD1kP``H7hg@QY|w7?54~1UuB*oXqD_ePJg`i3GPV0EM`;%joWPh;8C{7 -zYdmIemNAl|da??P+nTE06i%eXK303w@_~!CLz4QEZFdnUm~0^2U*Dh4GePdBsTQhV -zsihVr6*e(LETK(_Y=c5vXJenfn3=4BLe-LG|E6?ccR#tlx)pG=|6cC;SaBt^!li5R -zcPgX&c2MsDL}~N-O+3=a0$|oiwZm$c)<&SyI4_0A@|JEcP=7FY3^?#Of0zNSfD^&A$%$p{mSW|9&i*6 -zj(_qDpxvBQ=^ptttH-vj$9~Va*80<33lpe5w3*6)d5BABGb>2&T7!J8KM%t$O}n*W -zJo+7yk8gR<_bN{XJ|u{lon5UfZc>HMFjulERk&KL*jqG{qadfz)xhuQcg|aymb_Y? -zVYhel3JJX|M+K*)DQMX1IZ`*_*vfscZkpLiT)9gL=cKs}uA(KzRP<4d8#RxOLcE#D -zJP9@OB>kt#JaeOXaqm4Kc^GYiehxcy4(-(f*^`-a9<3OAl0lXjMU1hK=(Co4O{$8%UM|E#&*;l(B?QsiT24bqlr*B{Z7V`VuFjMMHlGAysOT^==1z=5qZQ_2R -z-1qLb)#p6A6j}B#jg`CWg~=F5uJg4=mk4 -zMbEFlbNEc>OXUCT5piF*6@<3E+@D1YQ`=LOmdxBa$alJ^s;X9Vnwl%91RCi4CyD~~ -zEfY~;r~^+zF4y_)m=yu>0s3+B%|pI?8RS^ct^$kP#XRzE>S#R+#~GhIc~p)Cii4cW -z9H*m(D~n23;e5HIw0*7&$Qv-cSkS?#GB%E4^9a4Zdg>n0VB=s|P>wkUFR@1Py;++p -zX;6LW6tT+67ZSct6f1(Z{;9<&8!$Q%dsr@?heJCLyu$kE{QNwMcpba!S7M2R5q^_F -z1m`x@%z~KAD3f^-kF`7BW3BU>kYEeLw+hLBNDUxD$O}Z7ySX3c -zb)wd!i4k24wW1_C2@tbyw%f-8qhJmP`&caiZ`w$^LAjZS5Sn#m^9yX>OCkC~g$Cc7>RooBAs^cU -zIlTk#)OXQ82-Til1rliQ85sNCA>X3OzZ4b&8XPSua_&2S?i?lbG}vKCBGdB|nXS>g -zJ0*+o--w^syM8BpvQ@ycNTP2WG0U^*#8-MC0N=cB;m&`}!LXiv%vI8XM1O%D865l( -z{g6XRuw=jeOMjz9WK|@yzj!yA9i}KA0|SHG1bi12L)S{x7e=_kAN~FN)m7xbSP^arS9Rd{|t-bdQUEl`8{54zNMvQ -zmVu~1GPeH>P7JxwZV*CX5cIQzmo3E{siDMziZ%E7Tl9Q4KN4`#}D9_*vX?k}pO!=)gn7_4Bb4bJT -zqDaOnV(7U1_j;to@cwADU9mBc-@BdBUmAHSzyI{7YGVPi_y~b*r-e;$%CQnDe?9;8 -zfw~{4mSb>(|FgeRQE<@@i1>JZxfuACaFBgBIQO3(xsqo~Se?tnEhWOPgi|!6k69%H -zBXMEw6q@;gX1q%5b}P&*(QhwjwHm7%kJPg>aV1XSsKm6t<)rE6*j;x$hUQ|hu`kT) -zV+}ADC0AEh_W-HRr1Y}-%^FExK~@Y^t(ANZuuEJ`p#^k<`-MWnN77L2@X=9jV+>R; -zXOQ`#-WMm65hugihkOgXY4OID(WpNU{=B$ZDs8X^hCKKCdranviTkKK>$2J_;-Ga6 -z>WBEX7GD$0K(CoP7J96eYCwj_U5&HrOXJSWm=N0MQ^#7X5>(8zV6XiWLH3_ZhnV9@qF1Eb95#jw+CTK -zcnC_X6?w!ouwb8!t?ZeXbU*`_*tn=L1`tKaPq~o#XH-LT(pdaeEr(+5o7_BF^YP^9 -z=s=xqrRelm)Z^rj$VCV;RnXkG!NaMn=)gAL=kN77LMYwzIqFtY;-;Q!9U{UKkl*Z; -zxmwdAck=k)YYlsT2UM!0spVa*x7IFL)Qt{!?hIJJcZxQPc`eiw~~Oj@Tz_oM0xtx3Lb{5kxu -zyBD?uz>WN#g_E*U&crG80;MCX-DnFuJuz_nIeOw6$6c?&s+F|L2zU?5G!ekeS!llo -zFPgW-3Pcj`}O?5W?ab_h%Gy97f=v~(o -zy&qFFhNcAIGR5-l!~O!ti+&6tBv?y$VCZ!G*COZC^Rd=v3DD{VK&YZV`0rM0q-=5@nOTtcx@ -z-`GfyVTF_)=xoTY-xG)BHAl-#;@k>0Kap5G)B~X77JGh`U;(W#+Xleny2|+?3X~v9 -z@j4(Oa(GxV=hv@n1U4Y(PY6pg$c&Ot;)efq)~zTw>;uHy`pS!hYaNUHxEYhbgRg4R -z+}+}7o`g)4OPEQ|;tiYeawTA$%HmQyClOH{QqjoI$3uxnpv;6|Hoy*8NC^3e-^$N* -zqqby_w*0S5T>t%`@v?z_`@m;FByBE`COSJ7m_~uq^-Bim*HTzq_chCA9jeHpXN(2n -zwRqW7h)`1w=SY~Q#F+#wWc43wU)ql>D-{W#MMi*+Rc<(sqj$1IsI?*Vo~~JX4iGFY -zSjVn{Ia}(<$;mhGkK6li&$laGUX5+PgyS=U#yks+rN3QUeb1{R0P)Mr;duDNP0Yns -zOl80yG--mz(9cLJmrW%6skc}}J*KYlL*%B2MMfm>8W3{uoeA1tCC=;U0l+}4z>%rz1`1Gu3qlk(DUqGWSub-M#qTbUB+d9M069OLgJ6ct8Id?;aM)g-r9s^V6BrQ}Q;SCiP`udh7DC -zQX$nG;n1i3pom{#4@R?{E?z&>^3sL?I2rH<%HigVl9la73e4N^TR>PE}F -zsi3VDlCxI}2NOm!ndIQSbW~gNZ4rN(jki^a>Fbq! -zqTN5 -zzb`nx8&_h%Jrt7lQxR^o;6yE0jUGfj6BHagGKnEIbC?*Yeh-mN_p6 -zlPomN>R(3=k&0Ki-xElR=54S -ziifTvyozV0-H|T?}miG^F_wtBpw#IDTI~O&zZ=pp6zI7~U;(eX9v~ -z%_Rrklp$gbO-9{o@iq>QY$8+WLWjtqUprlw=!9l&&i<-B;;B?gDuUYF04x={Q|PYo -z11qyPuIW6^msVN_PE8KdAMXa}bHL6LC^fQ9sh369#H1cfF?JZ}v`b#V$&6F1HA?9- -z8rMp!9QAw;KUupJE(75s%Q_j;=twh?gcLwR?pti!=J%3LhEmj*cmxEL#xOjNHpVeK -zJkF%}PF#r=gweO>TUjCt`~eJ7()chG!YE-`x^-8vG;ltjSQ*{>Exm{gthe@Wqr_;) -z0wt5sLc;HhZgRcM=_rjYuGPk6qTcdMHcs}#u#-NnrJ>ijEn2POpi%bVAyH$%NC@JW -z!9x#~LZ0#)=w{X8oW39GR&eJl^`<7%yQQ1IMRYe1(f#2jGXHCzX6=QT%WeN8>DptC -zHdSdtJVzrAI(JAmUV3k0>(|f-Xp$15@*N%7K>n%=8xkhRkB3QAUtf=ah{(e3zoSSq -z_gFfN{zLz`jCqlr&;1O+r(+F_Z0oUu;MXftO1`Y -z9;O;>OCXbj;jbt_S7jVfllzmVYhq*#nMM~j1j#8VFg%#?vdErxSYKI2XR#z#^jrF| -z60VzCe$K!`P7W(fGZ`zDbu=Gj|Fluc!xb3b3?KS{Jm5T)ZILV)F5q8zrZN3x1!?Fl -zj24#65txQAH>pypq52gcF^Lw8LkW1LoMwVHld&c-soCEOJ`7#g5|?z#rkMgkK7BD? -zv5)5fIFMR6Y+7b6;Ou);_P~PlRc2e$)>HPum(WG>M&1%61LbYx=>T1OuOHP=A_2Ml -zUJa0_6*NB&eSM@;e}$dm67YWg_RVCo!)>o6Rkzh4GG20Rk8#RK+5)kj -zy-EvI3s#yE&SmNou7&*UrnmOiQ_-c!M98x?rSX}WW}0I7mNW&~u)Vo_w^FUmMKUp> -z8k)=i)!=z!;!K+sl(Lhz*Vd$PEuCsaMon#-vS>REEy6K+i5a(<$=x(75fa)xG@=%o -zR1GQOG=s!5g(EG{JieFH*|kCh7=CEGG~xLSIY@MDuIiAnc`G2Ge{P@B(m6G -z!ibqfOA9p9!7d%@C@Z6Oj!J3yF%OjokW8F{Y}gut?pbEsRm(4LL??RqN~(!1fsK#O -zx=08kW?ie)L(K_4s$=P~flB)?RT~0m>*m4)K}Eg&^ysOF8lN -zUHK0Q90oI&{$mRN4;~O7eZ2)RYWiOSNUxax118K@axIASH?!$hWNTeE-m< -z9|d2NgO0N~GYHc0yR$}HApgS_*(Si(CRarIKe5r*$mNd^46r(X7=_aLFxEIYsbgvH -znrzh|J#4IY*379ZTcw$}tG6{QE7PnE4Rz`3%NtHKG_U~aaSk@Sx>k@6ej8+~c|Yc1 -zO&By$u_ANpr;D`5D&%W#Fdl9`BhvdZ5`UZwLv{1Hpy9lA>ut_To&@^KV8eBInUrO5 -zh52}zCbS}L24&AucCm_(e?;?E_ef|R)nd$k+BOlW94v|UU~blRLjQ0ZP-4r2%|3Mn -z>o)c|#p9v2Mo^cLhvg|xC^b2rL@3y2qYKOs?@M}`_`2q==9(4=kTk_PZBIhX-PBrZ -zr~4n>by9I>XJ-@K+>o8|G;Pd^cW)?r)m~#|TJhd}QmeX{jlF$FjtCHM4zkU<60>Zs -z%Hys(I^Fbs!^Li)<*(mdMDF~twQ_bC9DMnUdoO<&F-3^A3(9GW4BH?t7v#5rXa(*RMsaFXpk@rOtgnql#(8*wa~=>H&U=;wN0Q<% -z=~0Qf+>{j>5oC?u{)Ajpd<^k1GgPzB2_X=HLz81#(ra*Wz}OO-za_H(wqrv+ -zz0y`v?a{P}lFJz=@BUy(A)pd~b{ghG$JJ7r@AlNxR+>kt6nYMil7}v99Ja?<@UZ3T -zeP1&kMRSM{5+R84Gc9j#ct$;ly+^es_n)lXhG>_EcB%`8iYCWLpCv8)3~8MaxHrGc -zWH36`!Flt6p(JJsBEPqrE&gHZ?iZtxyx?@fgPx*GS)go(Nf7>mW01|;SB);nF)3s-o4wF7D!)tc}@L$K1~NQb -z#Yr2Tunx+&wm$nlh2CtbCg8*b5`pf^Y+pukoQ>UqK#>9GQek~Po6Bh899xq^a4oaN -z9sDuzXNM=T^ExFYu?oyxI-}8y%D;slDQ*$`e5+$KKq!pF-*Qc6*L_WdXk^K$IEown -zc`-GIjJQlcjeh%cL}$EWcnajL%v-BuW@70M(BzzY-<$NJlWQg2rNIpwvZO(rx6c;G -z_UBD)7Cj+GP^Rw?)N_Nikx*qcIPWa%MBy?TL-6TWG;|5d3z|f%7il*;Ac9f={o-sOWXfH2ow& -z+F%t%kw65bbTBi=kaCFWiK~y^%2iyKohma@H`Ql2SmxhqN|;zqx3*C&8_FG(8wPqn -z80VlP%Gr)DvZLLlMf_OsXDo*4wm909tv4{~9yF8NS%e&sJ#dPsVWzk;(a?)XK|KjU -zmKml2h#A~>%-bFxM<7`wSX>`I?z8$Ca++fy%HqqV=8QYYD~bl^Hz_tBVxFF`f!?T6 -z!OC4>a={OOkbTFV#ew8k2GrG${kNo(rcXXA_NWUqI*@?8f!7jnu3$bUg%u}bhY5Q));;cCAc0gS -zHeTk{K!dAfJ6}@_zTLUn#qe2z2>ZdYkePg(!A+9v>R>`9$hU~PuED*xe7hANwC~xc -zzMc7YMmZr7Iy0P~w;nbL>dml8nV{FL;+xs}qjWkGV5~K1I6DPEC&#K9z5E?@9vBT9 -zvo#L&#*9687;Wd0D#-M4&3F8(7sFq)qrj$;8%`og3#@6+hSB^|^UtXtP#SOBvdY^G -znH{rdVJq%P=QxzF3KPx3etK`XD%|1rVH#OZ35YdYtyAh8`vg5MWd_yI4)jPAmo4j_!3e<(RzCocf`Y+$BAs988hq->eMY}S?z>|#t_c*3a#|wBAi{r! -z{dW0rO)!J3t~1!Um(@E{ATxo*eW!!k$}$1~;aQ@PPH8`A%_SDxVmA)U!Hw)$KXA7$ -zqdYbaY15D(b-OI$URl0+-TYf+!wm}Fwiu|ApRr6t288`7`y!ZbjuZgH`OF0cwYAez -zqSFt2_caUMO6L4Xk>1Be-C -zNHX4bgVd8eU&h^$7@$FnL%%Qp$e+fZ(4dAotr#y7!RrZ>u)-F!F&*jOE8kA5rqU|| -zkg!kLmDxaol3FWgZ=YGJwHYE#cf7j}8z24RotEJKC)?r64}@x}^89m-1nf0~ -z*_bz@JP+Ml3hd*HWuOR@sNVh74L-Sw?LaYKwKo+rvy}#|aFc!~jT1o|KFR)cI+)Bn -z7Gg?S>|0zfR!%gT?WBBV*!!8j6W>|lJse7F&5>m#;ooWbRQhP@izf8nK?3n;AClTI -z6#M340iQgXluMzeY19}<(0FQ=O$wq@ql-?Y9&<2A-S>4Nw#z1Z-(eOaL`iCMI&1sAHP4i1wfU%}{TH10ti=qYU -zDz0-eM;$$6p`VP-jrsMCM}MB&A!(m3WE#f9F_{oZS)?8^0-?^g11w23S(X*2v9^k* -zKU)$N`g+?WLff<~UDFNP<{vgF`ivNrY!#|!D3|%nvN;axyiKQdEH}n|UAvW!JH2@P -z6TzqIA6}zL<{b4pMQp)4ffz(REKD*y3@}3^xF7ui{>6upo0Tm&dOIrt&>JXx_VQrn -z?-nhZdK!u;m!%$urT+S%i$tA>aj?l1`%j#jH%{|kdYyAos^NAM25jH<6TePW$nes= -z1!HeZ;$v}XEv4u4(RnINU~U}A*?wwCqU9m|k--nxsx^vf5AeRn$pVh?0Mnuc`C!uLu2;Vg{7)wfw`U -zX;*Wa;BHUq-TwcZ=lb=LAJ!W;9=uX-aQwln)6svvPf%SQ<1JdhQIPpzpQJ_KDid+% -z!(xv_|7G`-+M9p4uk#~(Mx)cG<|di_EPs|%wf~Qb+;nQM%q9N4&z7FNB6Z+G+^+MR -zj)|=QD8BER{dSeRdtd$LH*1N?VC!qI+*y}-;)|d!tvt|0N -zm5Vlct%>!zH1~C#{PXnRXO%R17-p8ep7o3QUvcWms)tYH$`9TvKIF>&@BVzZ?VI=h -zpErH+ydwvGOs@R*Hs)&kpXVngrCvTXb;0-d@xj~oPM7_l|L;HY`3dlY6p$IBU;poR -XXyugpZ1#qMfq}u()z4*}Q$iB}^Bg|U +zcmaicV|1Ng^k&Q(Hn!T>_Kj`Zc4OO48rwD-Gw*(Xv_UIGaL4*?7e3`t5-R2lSh^xqd84Cs4}W^FDQn9zijsF13M{zVR~<`0dB +z;hww3Rk_uLO*yyZ^N(arMN#SjFcHEi60E_fZug`IjtJ^LVtno=lKj+Jze{_WszRIN1X*HUTCH>C_wc;+D)6YYT +z*RWmTUi`Puu_Uwkj6-qwu_Ue*kO&$%=o%J?6*rej_Ock3znkGIb6 +zWm&yS2Z9LS7slFgUx+?ilDgQBdj7`ruw|IVzJ@wV{&tD)G@SPTMW@9Wl5lcsuU~6` +z7raw|%Or|@Pnlh`7!!rA1H$`p;zz}+92Tp2bFmKDAL`nrC>)<{qBHso +zvJ6|o^vMxL?frh4XZ`3WdH7s_NI0p@{EElbnX*!yp;Vtx&K&w$&to`sW +z79>enm;xWhu;ZKKIN}-h!eBKZM6j$9~*Q(SlE*i_bHS0o#tPY +z5-j+ww|x>h9%`RLUixM!e%f0qVAe5GH83X6?!#^_j-M@lO@*-aD%NMF2;Hg^Wgh@}elrPA3o_&(- +zeNyws4es~%;K1o+pfG(Z!G-nFWzl7)ejRNxY?M~uI=I&MYuz@4>GLH*ptjlQJ`LYr +z*KIIVzBhKHIDwe`X2hc@gsdjzXxX%b<_#kc$vIHFi2)-XM1=fs(`g?0)M{lcJXwp< +zBgIdDXM&n-=+_%;1a?sE$oeN{r%w=8tFfAlQopAk +z%wrVN=r>)oZ0w7^M~Xi~qp6lEaABgF(ck7V3Un;@cg|ODuD7@fw~OZ;^TQV +z$&4AiUj}-4;o`6JV$Y4C2G +z8hVweUdzl78hWzD|&J_)oRr2JdJP +zA&lca);^P(q@hQb9-kqNXVo9An7Q3NoAtyRQw-@JUDD$oluryjE +z3{zzbZhStP-K;xw@Yxf-B=4h(p=4f`k8p2DH$>qQLPR!szD!2|vJ}J`C6=EoRwG^+ +z;`ZDv1SGVO+?IqSxpxSM^_V~@2E+~dZQdl+oz;TP1MX+XXwugMy?Z5AoZ7#R33Y@T +zM)w4;9L0szO3>6i#4fV3q49@wu&`zcvQ!d8!m*dpn&7pp0Y=;QbiyOzhC7)Ki7tDt +zXaIqysWqx53ZgHlO)|YRDG**$7&F{0a8VEECY`3;yx)F>2;4Xr&gC;Iqiqx;orWkF +z8xk0Ty-mK&z`^~Fbs#S;;Qd@1ZFJh4R`+H>Wx$xgn>^oka;w9~QfR>rS7lYHG?D#o +z6Jo`Qg_-DP +zX@kdURs~L5?afF*73QF!=HQ?vIysP;FNCMBfA*}*&%$eDHh5L|y~D=C^v8(wdtcYZ +z)8Q|56BuZ~3~KpF-oKg|5Uf@Ac15Z>sP<9hpm(E>^cgr8dMxGhn7mnWA+JPK+EGR; +zCfK+V1&Xi1M6CUFIA+oJqr(aF3W_=ph7h;IVlqq&xJ=d(CqczQwL>f*A$gJW_|iZw +z&>!^cGyI)UH(_%jFMta0ci8K;?^D#C4_`@%@wP6R4qvs8y@ecdj|*ia7Exg3*BpG4 +z%Dqav(-_hWolzv04-3Ygs)Z~U$`R?hQq2Is2`RWS%z4?!GF2CryzMjCEFg_Y%K+yz +zG8tm;0X{;XG5?BBT|pMZ296(fGUtoF_$Ryrso&s;Cc!g3a;pYOn-tjPvW+1)iAQ)I +zaPyG(wl0MZUqz_Z!4+oEh$t>QIaiZ+J1|fQdfugliOCAg+6D!~3<-k#gA8N#Rk3@5 +z&u3Yevetsi3m`sm2Ntt>FV(PfME~wR=LFu+2@Noy&wr###hgP3mjy&H03re#97OQ% +zsZ;NtktNoC?s@G44Num-@G1zw*?jMf)dA`SWJHyI-Lp=m +zyv8V97L8$~?>Sf(&Ee27TQvEf=-_%~EL56_n`*ZRVS`=4Ka4&HGjr9P8e3rf;8BK& +z&0s~H!Z|V-mPt9vUj?5&%Sa@;XK~`TS$ylgW4|1h&I!<9c6_zoDdR2)FLErHw%Sow +zwc_2ZKizcAMchMvZ^6OY8)uiUt&RwA(`3@dzgihQ1MSrNi;ruq-C+?oVa@U0x +z(>^4ei3Bedg+!LX52G(u@W4P&3sdv45%OawU(*aQat~OuEf?Hi6Zi>__qCd)nw0_j +zvUwA_6WQ5tnFsl_AZNz8L8L*=L4?0A>inj9l&C`AC71u=H +z?bu{Q_=al@1+|F&El|te2eQB@?#+g(D(LjFx>w=0X;CJ|CQc@tuin_)Rd$KH$Y9P9 +z${MAq+Ns2`>_SLAfKm9~%?U2bK6>hiDEbdUD#NMd$hR*wFx8TxWVY3Za +zM&tRPhR$htT-*KlZT-SGBy4YD;6aZfAz^Jt1`=ABifztn#D_;u)2WTa-Bo^EKL;=o +zDc6Ov2x3ybU1B6gkFjv-UvyFl^(EFkIb4ht2Z(*io4 +zW(6^Rp7OMxVh73mYH?bkbxgXB=+TL>U^8OY>=P$oXPkGAmF?6#80T +z+e?24uzuJC8?nCu`7)ef&Nu8x+`0%wOB9wmZ^(+|&$!T80~3uj?NRH)aNhf~#vN9e +zem1VW#bKd$SZ4ufS0-pzoJ%P7UWdT@8yg`1+kpYLV153t;UJy~P8@7sO+#{ePIXcSgw}v2XayA<>Jxh}D)tMOGRgJY0QEJs` +z{>aB;ssVeqKi-6L#(PnBpPuOu<4Rf*GWVk8BdMCd} +zc^_!LU3n2YWBEk1?0<%f@MkB;t#h0%&cixNCZn@Lft$eDVl6z=l@Ga}k<7cF5n!!o +zXet^Q3;AyG!j)+$=3U>7D5cEf)=YMZ)jSZ?)!6EoSa3kU!3W2Xn`K`PqR|ML`Ju!A)|K2`l1>ErJG>o*qIC72B&jHYe36od@P! +zi)qQ9Y7g*>N;Y4;sSLlPxvM;q-Tzw2m;Zx=x>{mk0;Ed5zA?Hb1FrDGc6-;m+iSFU +zc22aC&R^-iyw5vE$D?GWWo7A5o@@>d3_uD92sGM_-tlsdQ?ZbAnF4LsSxDj&0TFgO +zFbB*@;0<;Y0es>tB&~M12_up)gRS(Ce{seFR$9$~MC8~S%gCTV+2AIiH`gndEW2~H +z`z|RK5KuxIccy|!;Bkm8puw0EcWFE{ij71G*o4( +z0~y!3%z_nq1kdh3x<;XVQS{_v?Q3|H1so1Z#CL|Zm2Z&7-mTO?&1?U-oogOAE4Cm{ +z`d4o(XCnWH-J^hx&?7X^xHns&B`u2*skUy`s~w=0252bVaZy(}U?e5?u>fG!UbYaS +z4Gz$YBX|~|U$??YUR+zxw2g5F_OJB7viI^}qx|ouEswnc0o{D4T~~|912EVr9)4P& +zS=*@uBmgy>GC)sz_8A$Iga2y-R#LKP$zyVe7P=4Vrn@Q)Fp6mG;Nall=^07<{OPT~ +zPDD~5M}Py>^H&ikOMCrXaXjFMyNuyNg$gXaPOE4z3=$o3Jt(guFuvAQbA?*MR;Dx}r~+zsgJ +zzCtQ*$r?UAKNl$E39K|(pdcV17*;zU{VtG7{)QDicnC&XAit07AxkJs2xbNxkEh-l +ztI=-hZ#0{5e0{huHk5pMKFXUdk-_HT=8j~#**>ze%L-Vq--ELbc7OqlEqqgfDL$7| +z^zia3^m~7il#>&4bK{s6W!C%o9eQ_nw_LRXoq&)qk2e`~Carh!_+@C+^?4E@nB?8v +zrP(B~aF_-3_5wx4#3EgX2f|T2iDX6dBot9e+}zxz-+7y;fop?^#LWumnJ%(ER<|F> +z44(0)x_-m7iZI17bV#w5<;|{V>IZ-R+z|XI2d!L0M$z{_~PzI|b} +z_>I9TkwT-USfkDEyuoB7YJe7^SUeW*JCd>d31w)Viag>w +zE)Hcnu_U(A@CEh^w;UM0IVsDf+yNUB)lCpiM=a>2dMSVx95URpuHBLGh>h8fgM&77%eeba~6*@>lA8=;7iEw2QP4d^IvP +z8fpiWc?lq5kxp*C)nS|HY^i2ov(x?A!{1u(mk%xyJ_nmAsx{Zt=LV=Ta0-O}2|y4O +z5yIAhMw5|xp3lvw|Ps$0W*KZd^Wlj=W@{AaG=^es3_){Y~Jis`IYYiWN~ho|DLil1qRD5 +zN6xAlvXG=U-8`VKVHr!k-;5Bi)EfnJRTtvY$;jR$#e%~lxMV?xboY;JA{IT_^y}D0 +zw1mJ8tVoSO-(}absB6M8b$Zqe)Ok0$OkaA#I +z48@e8TAlv;PmB6dbP|{7<%qt@Ea>I;PRL4)=M`_G!A40Y$Xy1Mum)I0#!3<77H4)u +zI6c{)TUsy&o^*@2H9Bp>QJA#S8$`zN?+@z^IIQL|VxYEQfVw~Oc}Wq!FS`G2T=aDu +z-DMYe(1$x=331oN(i#yV%?Q)lcY`}FpGRp*74@@$fX%pE+dAGOh5QRhJ&mcaXOhk4 +zLi_pirw^Zws;d9n^#IE8T1ypZDX|crNABquU?iL2;Ql%4Vg5cNBt}OJdbLKnEi|`g2q%v70%eM&7 +z5gdFefu8Ix3n54MC +zW40SGT11ajrrm5AI24T?-2$|VMsU%VX}AMmt>Pr~B}#An{>%QG>_1FQYV^)CExzx2 +z&7E_9c!fpiCLci|F3H*eM2DQQRtQp4>V2RP=KX3ZVw#OXuFxj$VDmM&HQD{*dc7301976VQyI69%EFvxxn>qC&Lo-`%ImvM +zCv>AXKPcD26Z_;m`1pw)uF6Mp=RnShU^yM81!?jbl!v#-kSa#RLhSOG0?yp1YB6Jr +zW=GrO|0zIRSHiH?DYiO+$EpdMkwz#4I6V(J12-W0+dAo4J*?nDQrFI<*}a92Y%1bU +z`RC_4tyg7>R(8{ +zA8*g?PWv##WoF+p0bJe>whg#+(1_+A+)9HS$|n?k;(r=Le*vR;57rn)2& +zEkD8KBSZm#3Drt?t!*#s#>0+yUNysIKRg=t`KSOcSHieiUP0z8F_$tZ(ciPnq_o~@ +z%-{zhbs{i7 +zt~8q8%WO|MF(FE_ye*bl_-@NcA!S9$IMb6x0`e_oNF!hy5a)H^H)5)t(}ek4a1Nc~FF4@f;5aO%aB&3O%B8NuMWWCzYb`d> +zQ-&3)G|5M|pzcLy>pA(p=?3&XKn+v0^`HNsS?M0eb+60BxF|&Y{?>MI^x``)Vp}1V +z;<0N$BUc(0=p=y>zD3k_I~ +zMC>T|rn!T!wN%lqT@ +z&Afsj|04$m&CH2M?F|6yeqb+e`&JWTP^~~z(;c>5;z6RuFKe)%3j|YzeZB9c)5E08 +zvX9?L9%?PT7Vu(RAIXR}s*=I*@Qp<*vA{&7B2uwdBH$_I`33U5di9weG|3 +zx-Iy`1L`R>G-q<+w-{f5qc<7ls}^cT4Y^Qi+meHXFIDgqkt0wpdBZGY?LB+q9&o`T +zd18L5%R+44Ml^UNbEw58BXP#{+I#J1$;VGO`#6Grd<=RWgP+T+ktE6H^>C;%(}szj +zK;wt^oW!yG4Fz=zm4zKw@$Wdo`VJm=879kp$F&$uMP_qiKSB4L@SV)g55F9Rb=3ocrK>iqIRR9n!X0Do*Ldi{9M&^sg&T_TZz~>`tbXc$p%%BI% +z#MahUA?U0t#2ZA4_41*w&52#TXU^_G4)$#uGOnpIb{Gs?Bge_xP|beH;cUSBec^gk +zu;a`And#3j5LZ)LALL9lQ0{$A?tzx&K6M(;#M))7n&`7KTkT>KvjI7O4?mTa;X`81yn7WAir6 +z^Dv#2{~#3{X=5gyP*2v`3yoLJl)--n2rC2}*3n8(L~4ohHzT6QbyEu{!K3q#&p9Lp +z?3#RrZR0JWoh5V%Au%m2?uSB&RO!i99khjDd#7P;NaxJ<_f>mYXQOtXqBZifoWn1d5WC&hmG;&Gv(>!l)|)selJ-m-pz9Og@*rA +z%Xl~n+gHI_Rjy513U_dEaq-~ZLm%H7RpVbREoW=Zu*D?n%JFyy6(v}{RCOy +z>_wu--o5bv-4rRuWG0oN3a2+(f)C6nR0%>9HdI1mB`d{jE6Q4vSf>>{@~N-bGMc6~ +zn=1MB2?XIjZuOC!s@-pN5{60UUw-L4f1L-3Ohud?4)I$4Y&#w^A*ij(1$$3|Vskv} +z#YKCOBnHKh5QN8fd|k)wI{^HZj_1!`{L&>R(m@P^tYk*J)5>eCrio9{j>kWLDCGrM +z*O<)utCbjQiH>aHzD!~>SNyzV|B?uyizaR*!v`(g6N5ks=aSqWHk#wzbQOx2Ehc(>s +zfl`oSK+EzLOKDeK?n#pu;5qF1g-8bXyN##%K`x2R14CxOh8w&P-kz4U}>3Q=A& +zwAa>sCXe?|fR^Y+S9_jW;=!_GK`1Bc2HY6Y)*s}A##+#}239~LV&Q~wL&4n_6^@vW +z;nGUYJ$5-C#kJr2EtD&Ty$t-H)#GyT->}39LWB1gdo%LwqR8{YbRBL*-FCEc5iY{; +z#TpZ~y8yolNKuWi&enqz%<*)Y)j#ff)9q1ezkI|N7|zr3b=T|b>+m?)d% +zKJ;1@L~w8ZQn0MxZS*{ew-;Ohn^Jl!+U{m|QvgB~tai**t#d>0E=CMjN*SZ+36QnO +z4NrSN!Cd>9SLf?=!Hjh+ek}c}ND_U`vvi9(MS>7nGZ*lPm%4(7(bhfuTHod8y%;N{YO_KMV}N<7D)x5snD;XG +zzCOH#WK2$4mAvQWFCCZW#F8TRInJ+=$6eR`V~dES6+!6-=6lkVCHyCW^Bb-$@=b%3 +zi%hxQwAp^EOp|zR61~UikJsM89qE@P3@X5J>+K)hO6K`Z$80UqhLV&|mVt3wQ#G4H +zi4>T}s*jr9pkN+B@=LbuMW8^kzEFQde*yOdnXiUws9u#OD8dYzm?0F`qCm7pBCNNz +zOJB@PR!5?2&9Zw_Jg~i=TwmStKiYq1_@$ +zZKB*^u}y2o({7rV#Nl+8$2T5 +zthMF3X`+*;4Q-~&-*4NzrU=7>#}h=jB}<^tsAch7Ac~Vq;V7 +ziknpCHOP}_P8F&VE%6e`WG~EVa?$ra`knKZrYWbIZ_w@4vO+{B!(Pb&!YhY8pCfe= +zjxF8x>Zh3;#gw`fu})grVJcf=Ohg_Xc9m?(57$!NXQ#N%;Q{V}EjtmA$m<@Ie2(h2j9T2Xq=0<2R#daW&$ +z85=lCIqjn+?h$SF4u|?#DOOKg9>2c{9GSdlh{<(WR;Mb+bxH>u95roevUiqSmcdG* +zEL`{Qv+mA#hjLxuC*l?ROBgDsPYkDNU%;m09$2^ni=SVA=kS_) +z_h->URCbhQr89T-a-Gg9Dk?P`CT8-=f%@A28AYMmma&Ks#DNDsr^|eI%nHBQ0Nps* +z<{@u^G-9krSD|^{Vm?_nRkW_T!;E*n95To#4sxn;9FH2W%&T043S^Vg_Bk^^&J9*H +z=-^Zd6GYUG(CMkA?hy<&4Tc5fn4$3ys+ZiGw!07qHH1zPDzAJY;{8Oj#B1-LTAZ>D +zKqX)c%j0#o|H%z2zdkxYKaV6<&nEMgP`q%2&v+2dsa++rFeWoOnf$VkCAY6|8|kw{ +zdwe(maC?oeGlx#HVClH?)W&QZ`+=l3PIeQ%9cb~nWxJ9)YD|MPt`v?0-3bMcbZ<2Z +zG7xSnH{QoOr#C@?R{C$168|JMfCxcPAVuEhewgQpYO@AfbP3Fw+|Vi7h~L@$6ydj5 +zyf7_h9Rp$0Gii0mkT9xddqw>hIVCXV203~$D~swIj_)TV=zX)@-tK6Hb66mM;EywH +zsMV;{!i^8fvae3b)iz7_f6$4yU2i-b%Bh|o@eU2$RD^G(AtWlyl0^8dxd<9 +zCi_xU0%&wFugtmc%-uOk=xMY?lR%{7BQRZ~b8}1<=DQI)v2*#3|70VNVV*?SK4O}0 +z-HEICfCoyTwy@{F=Ac>4KISQEgQLDcj|>j}hzn(*RSn +zZw&u6!^Z2~7ae&u`+{IHYm_vxJJ@RRZ!LoCjQ2ecK6E;AqeyJZxfuAC +zaFBgBIQO4DawgA~vN)BCS%`;S38kn@9kWOTMq)$V$+z&4nDQvH*{(1#N58$C)v2#; +zJW|ch#FaXRBNNj6mX)HNV{_ScADWB7#Jn(Th}B15lvrI|-2fj-=SL1AY +zQrI&y#`tyxRIyenc$G7)m}|d;5&h;8q8?ap1~7v{vEXIAhojO|^XI$6=K!f+>;5yx +zJJXiq*Z?mW;Ak{?4<=)9$$a@6Q*=1_%}Nx&bGA3oqS%{I)k3y{#DALAzrPw)h(FU +zj}8a8Xte($dBpT +z_ZLeg50aO#zhmy?M*+dS#c4NyP>CZSyS+OOi>@2;)lr;&A$)(OEO;kV+bz6O57by +zyW>9>Ij2^Du|A83(r~$46%S7?Ancv(6R +zJK?TL+k$9p$KMJgY}hdrTzyS}0it==hvU?8YM**7M}l@-W{&s26~NM6 +z#U8(RCX-=6Lw%{$D&=aKSfE%aJ<__RASP1DaZcJPva<-yi3NH#t$OuNk6wlp&CD~1 +zanJ|7AhF;l{a^)Qhr_9Bo;2ZG8=}0whx#r7zZ6W`Fs5 +zJEbvhZVJVsORu$w4Y1HyT1E4?Vka&kS*mSpBuKM>OAT~3W;g7KLGzfQWF~QJ1)H6S +zFCOXwP_auqzKSygLBPB}EH;Q1gXb@Wm*lZWfM<8NWGZM_*$8Ze)0+^IpqCyco5T+P +z>!edzc-RMsx%H6~4%a*u{&6!V2Xf)f8oOKEEtBAhvI#TkSv+Ago-TMSQ(2q}=S0FP +zL(1v}1vp6Ya1@zfO!}Dq3ke|~@mmFXu2dHEQWpO$6X$;c8V@V*w>NACSkmSKF-THX +zXc85Wu2(uhx0b@}vaeA-YhO(oJ!8ZlugSxzOn{tnI7h@dCB`UVE~EEY_ww_|qDlb| +zQh0>qvDy{uar91x0J$!N&ch{3*B*?y730`NAZJT0IXU?T1Oo1Zc+QnB&!+ZYLh%_v +zV;)6DQs1sEzvoxu0r{lou-yG%CgwotYzFK>vqr!e>KRehvaz@y)fTge`_wgV2*|2H +zVl|vbxEx$3ymn~uGqN65%FYqJ<_)*Uqs49;KY2h*(Xa?Tk7AFfl-xf>irJoUyL*;0 +z19&1GQV*5Ni~#kTnaq0ymCiLjk_=0q&=&|cG{r57n*6NwV6zJl5K*ED&DsZy8iEL_rr +zgsLXr6cN9-S7dCo0TeKI3ByoGNNBIG{4b4m4=LB^FstU0B?!6TBZ1v~zn%e*Xk=B) +z@_rySE6iHcIxSfbe^sRAkjZKFfR!7A5uNa|Q%HSV{);)`X_I$=Rz#g9)RV +zjIuDE+A6IDHt@Noy^%sCnU|?kL3tCMU12QN7688MFeYr;%^{CT)BqX<4rY8gFNo(^2<+x6~@> +z0Y;8%xJK3sk3si!JoTyNPRqf>i>%mkw_b{g-~}-aAljQww_S1L53kdn=uMDZM5$#ndk +z&22o*u=b&^trc3UMGkzzrL*~$;t?gd{w8WCC+z$)6{fY`v4CL%;?|JZtR3}&oLz8* +zT?G#HsX)xAYvWho@h=pJpzsjcWp0%LD4s08onG)Nb4)MY=8K^XfVvcKVvP||0{idF +zr>Wx=dX&);ID@-|u5Y#BAa0c8rW_t)Xfo4c@By|jKCCPsr7DjJ6t;eTIrmF;CpM`~(ysWB=S@seY-cC;IYp7eGp3%$l} +z)oc?3jDrN<0qs>+yfj#>o^%eHp8`K^wUK{qUM_Xl#K;;VHK+>&$DqLQV1~BoxLuBrt&0}DAhEKn_^ER` +zz-29QNvC|8F%an87xNYKcn*LCu89T8nVkc&?~&O83)5GbY)slt*#=)i7s;A_C=2r7N7+fk`X1KngTDCyUEafq@X5m_z1=DeiD@Q38P{+Ou8AdwgrjC5 +zajlbj!7Ae^jZ~9GGnmvF%|dV*Siz7~1$lG}zFHP5%BV8TD09lQN!w79WRZ;`=PM(z +z0;YT`0PcRb5SM~SQ_OKjwTc~?W_G_IPe||U$;Um2U%fe+7X>%Nvy!xcXUbbT1miw0 +z=$X7_W&m0ay!h~`ae>C68mu@al*ia7R0saqO=sn$tE@ww372nWLhU^>%{WE>Eoln8 +zaeH(5Zly+xlW1Z@B{Z2HqS52V*oh`BC}k&quf19RS}N6$l#0qGWzl9DQkZ@85(#UMH4E) +z!&hPrOmR$HRF*}2C{e3A#U3h9d)gN68^|>O9=TO4Ga~u#5kl0}_*QP9IxEl~Ce;Vj +zS3zvyQ+p-TKYiV8z>J$akDBH=i$W7}&)8|aN%_17$7$H|;eKWRKgAtrMwoyE;#kJp +z>iJ{R+d4p$2q2;Y5EBQ7>@E&mk*MzVW>!EDsQ9Pd1Icl|=0d^U2HU!hP6MLe0bwp2 +zA=U!|OQM?{{^8dU?o^&w|I~Y5fw~zw)IT&*mzBRUy1Ljo^-=Z`fvN|N_JgxG~k*Hc%03VftQZkoi*AD{-11-bt2%}_=-R;7ZY`jOzsFyAEWb! +zVJNLPL#@4|8iv-c@m4Lu!^Uc7?VOsDWty>@T6^QN67|~9P?w&boWVpR2)d)gI@s*$ +zT0uPct)H#x^_Y(_q2El&g2<(pF8niAzCde(;c)XAp3awn@Z)3{qMO$l1?#O_cXL+a +zB+yS96Q;w{xIBw9%-h2xp$%a(D0`Noi$$31BbukCM_lu$4sG_+rWsH9U`eD0eY3t3 +z@`vkyB5OW$_NhyNPE(&_JPvYO1XVd%SiaJPVza|ZguGogD*p`OzJ!Odk4wR7o=G7; +zQFEN*_9WQcO`Vliy5G@VCnZ;Qb~fJ44e1$o^Tw=L_lA;Z-8Dw0CC}X_m5Q_J*xP61 +z2tVQGAnU9PA@k;{9QL{c=-~c_joC`W*8qxTI)7}foE-)SU;g6SD;S1P5oGCta0DrC +zGXz?khB$Fn{Ycwuk%t&RTyJ!Mz8mnC0U+AYu}PkaA-t-gE*25%;RVKNKyWz!scpu6 +zZDKFBX5S4#lCQK!Ip%UxMsP%cC4T!8d`;mo#M{(B)h;Ilk3UVA`-O^+JuQDuUnt-K +z=jEH2NuzvVs7mGT0rJ;Nz54;;pVk-{O`o<8h5~yAG9cx)%sJ+#d0-B8j!9{+{>1@9 +zYiz-m^g@6wE8^*umZD0JhIN!|&Ok-?2XhJ@B|oI&FfS^$rs90JhlZBoJW`e5b9j^- +zWO>uD9oB-o4QKEBn$akVeT1MeUX-s%#m~lPXZR!_h7SU~%Y_rx{QlrO`$o+{oUb!PIS+x5N +z+{O+YLa6?IE1#&A?RMZ&J}!O!vj>Os^y>J_BMi^Cu8;>FP)!5eagStg`4k8`f<9)s +zLv>uniXJHc5tD}2a*xO+UycHT8lGykAS#tq7H&?$Q|yXO#aH{77;M;}%#Rn*u_i#Q#=kFoCjB +zxM)O)sW@_wx=K{lJ|iyESH0iv9Nr111eP3eEA!SenTb%U12{RS*7qj0=;%^Kd#QiJ +ziYTEU=jFY{zWsSqmqmw<7L@5T1o7NxWhht`9gu$(b|QZnjVAE)D;lyC=>~hv=8piE3T9#-QVKCSaq-q&xr*zuRbfKtru+;Kkp5Si5+<6{tz}rp +zigZWmiiYYR#xdxCbhhJz=wN$k9zPcR8H;AJErv2><3*Bm51h&CEJlpT9yo5`1`w{pnaAJ%0k=ISmg0E +zo$J6^H1-w0!^WV5w|yx36dtal`WN}DGpD-gqYjDTfjIaLtR}xxCDSo6v=}KHRM^9@ +z&T;nw5x5ee(K3%Z3QQF%sMId_cIRpr&3g$f><9ZoX7X_c7g4f{y)mf(?;`TLI@jLv +z?N)ryzDJ)LsBZU+VnRH0X1E}KJ!}%#n_-hEY9w +z`8(=7Fd9^wGY;{_ggJK@ZR?yW!1!^^d;F^x%}=DG(7K8XMm$L~K*Np|t>vZmA5%Y| +zINrWxnZFq_J7&ksTGEluekfNRCX$8u^xk+?w8Q1iII^7LA8Wc=uh=>E34C14fN(+~ +zjb&LKSzG|ur8^cG=n*d|U)DK;5`-D7c>o{;1qb8{cYdL5^ll*Y29ag^ZWs(}{Dq?& +z7Vt6fu%BVSoqvD;RYW!I!KS^e-kCz_2@FvAByt<`2mpvxlE{aWp)% +z7->KZs4&!M+Z9|_;(QrbPRGNC2zLU&;bq*v@zaDlNR7 +zR!OB(0w7?XvMI3w1tc_A&fY$=RO&K>9q)K{?KeL9#X2nl`k!ouFF)XFC@Tui*%L4~ +zwNvTu3}=K5TH;uDS!^k3d+!l_hx$f?(hkYU(6NBYx@mz*Y6dZ7D@JF^5^p{aiT5zv +z;Xjc--#|sw407DGZz<4^FBXBq5F)zwTQ|65$~FTfyft2wOiY&QG(ydKoz#wa?YKny +z)9C@EX0c#XN}}K5dNFdMNo^+Os>0sS^c;E5Ky4zm)q;>J{J+z3sdUj)7tN@@gZSf7 +zJ|wiD$oI`e{Xe-gDV9P_(x}i7AaPVJn&m~NMi(84-RGbXy6@{lY?h66ze7!6Ee=i! +zInre-6PCHrI9+8v4+)Zge*esLVEy0*)t)o|)801Zf98hgQ=EZH2bpZ=)5NN_2yjw# +zP8Ewr(5WN{8DJpt*e!|G(gvZ5Pxywag$Agdns%%4+IH>|FMw9b +zKb<-v)*Cb*Ao~hb;B*`Ee&trZYBi`{$ru%gmKbuXcPNb3lD3H3Jimki7;BEFp{bxX +zFJ7Rk<~$d5(AGs1%w=$DDrj&3=?C4wX`U{m8^^=Z8R3YTB_A>ZAOkmldWl +zwo0ZyTNCB`dfUZA+chm*()HWtA2!JQ3>g${8%Vr% +zasf==&095e)fG}M%iIsk{PaQ>2|D59ppz^2pExvb9Ou9EI^`kN!0aXr*u3p0ex0b4 +z=AnHH#@v>`#o*LjN-yB0^^l)H2Nm=yD3|>1aNigv$f`s680kxF8B%d>SUG)YF0R~W +z$TI5rvll2~&q4RSwu3})*@1!~z4l}@NsY#MwV(2Y=hbLZh-ce*Eq3<#rZ +zxra}au9h@`-JaCDeW|)St?N40z`g~4rjZ?xu=?#W;cJyHNPXCV2DuxD%N1A2hAlFH +zwTJm(6XPn#dA&{dq>&yd{5Lp=pa<%$*em=~TdQ%rn_v#5`>I!IS>M^uNpl#N|wC@HMBcRTMT#SL;d7 +z<(&BuA6dLkkx|8fWw@PXzCeCBgDx@HJs@)L+j8y~gZ)7)${p-|O7{G? +z&|M6FI|A*^d_U+Of-3`+w(c~-YsQby|NH)g|G7xv|Nek^|Jex)g~z+)I0xPC0460S +LFIp>X81%mY^Bg|U literal 0 HcmV?d00001 diff --git a/patches/server/0735-Configurable-chat-thread-limit.patch b/patches/server/0735-Configurable-chat-thread-limit.patch index a33f8940e21a..1432c0659448 100644 --- a/patches/server/0735-Configurable-chat-thread-limit.patch +++ b/patches/server/0735-Configurable-chat-thread-limit.patch @@ -22,7 +22,7 @@ is actually processed, this is honestly really just exposed for the misnomers or who just wanna ensure that this won't grow over a specific size if chat gets stupidly active diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 61ad89ab1811b6a0b6248982b9c6e57354609cfd..b8b22b92da8ae14bf1fa91fffa64af29552ce7dd 100644 +index 904d2f96a60e72aa089fdfe6be08044b04f995c1..36b96e0ed5c0d25068ec4678eddd8a19a020d345 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -327,7 +327,18 @@ public class GlobalConfiguration extends ConfigurationPart { diff --git a/patches/server/0929-Add-onboarding-message-for-initial-server-start.patch b/patches/server/0929-Add-onboarding-message-for-initial-server-start.patch index e208c53c898a..14f6aa902dc0 100644 --- a/patches/server/0929-Add-onboarding-message-for-initial-server-start.patch +++ b/patches/server/0929-Add-onboarding-message-for-initial-server-start.patch @@ -17,7 +17,7 @@ index d9502ba028a96f9cc846f9ed428bd8066b857ca3..87e5f614ba988547a827486740db217e node = loader.load(); this.verifyGlobalConfigVersion(node); diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index b8b22b92da8ae14bf1fa91fffa64af29552ce7dd..45d14ea9b76e3c081b47f71b9604066aafcf0362 100644 +index 36b96e0ed5c0d25068ec4678eddd8a19a020d345..8a0cb603cd4dbfa1839e0f4e1606876cbb373277 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -27,6 +27,7 @@ public class GlobalConfiguration extends ConfigurationPart { diff --git a/patches/server/1038-Moonrise-optimisation-patches.patch b/patches/server/1038-Moonrise-optimisation-patches.patch index d0c3212ab7e1..d39fa0eab58b 100644 --- a/patches/server/1038-Moonrise-optimisation-patches.patch +++ b/patches/server/1038-Moonrise-optimisation-patches.patch @@ -23189,7 +23189,7 @@ index 0000000000000000000000000000000000000000..85950a1aa732ab8c01ad28bec9e0de14 + } +} diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 45d14ea9b76e3c081b47f71b9604066aafcf0362..1fffbb92cae6c575470e8b0b15a0693ffa5bc20a 100644 +index 8a0cb603cd4dbfa1839e0f4e1606876cbb373277..e4df6312fc676ab2d573f060b007e0442d60a6a9 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -244,6 +244,23 @@ public class GlobalConfiguration extends ConfigurationPart { diff --git a/patches/server/1041-Add-config-for-max-minecart-speed-gamerule.patch b/patches/server/1041-Add-config-for-max-minecart-speed-gamerule.patch deleted file mode 100644 index 0f017c93c55d..000000000000 --- a/patches/server/1041-Add-config-for-max-minecart-speed-gamerule.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Fri, 25 Oct 2024 14:04:54 -0700 -Subject: [PATCH] Add config for max minecart speed gamerule - - -diff --git a/src/main/java/net/minecraft/world/level/GameRules.java b/src/main/java/net/minecraft/world/level/GameRules.java -index 4ae47c2c5a6bcfbf932d000a80974463e2d3818d..22ca759954420ace26cafab4c10b69d5f906ded3 100644 ---- a/src/main/java/net/minecraft/world/level/GameRules.java -+++ b/src/main/java/net/minecraft/world/level/GameRules.java -@@ -120,7 +120,7 @@ public class GameRules { - public static final GameRules.Key RULE_GLOBAL_SOUND_EVENTS = GameRules.register("globalSoundEvents", GameRules.Category.MISC, GameRules.BooleanValue.create(true)); - public static final GameRules.Key RULE_DO_VINES_SPREAD = GameRules.register("doVinesSpread", GameRules.Category.UPDATES, GameRules.BooleanValue.create(true)); - public static final GameRules.Key RULE_ENDER_PEARLS_VANISH_ON_DEATH = GameRules.register("enderPearlsVanishOnDeath", GameRules.Category.PLAYER, GameRules.BooleanValue.create(true)); -- public static final GameRules.Key RULE_MINECART_MAX_SPEED = GameRules.register("minecartMaxSpeed", GameRules.Category.MISC, GameRules.IntegerValue.create(8, 1, 1000, FeatureFlagSet.of(FeatureFlags.MINECART_IMPROVEMENTS), (minecraftserver, gamerules_gameruleint) -> { -+ public static final GameRules.Key RULE_MINECART_MAX_SPEED = GameRules.register("minecartMaxSpeed", GameRules.Category.MISC, GameRules.IntegerValue.create(8, 1, io.papermc.paper.configuration.GlobalConfiguration.get().misc.maxMinecartGamerule.or(1000), FeatureFlagSet.of(FeatureFlags.MINECART_IMPROVEMENTS), (minecraftserver, gamerules_gameruleint) -> { // Paper - max minecart speed config - })); - public static final GameRules.Key RULE_SPAWN_CHUNK_RADIUS = GameRules.register("spawnChunkRadius", GameRules.Category.MISC, GameRules.IntegerValue.create(2, 0, 32, FeatureFlagSet.of(), (minecraftserver, gamerules_gameruleint) -> { - ServerLevel worldserver = minecraftserver; // CraftBukkit - per-world From cf03bed519e1a2f74366dd97709b5d72d403b82e Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 25 Oct 2024 14:22:01 -0700 Subject: [PATCH 084/119] Add startup flag to disable gamerule limits -DPaper.DisableGameRuleLimits=true will disable gamerule limits --- patches/server/0489-Improve-ServerGUI.patch | 647 +++++++++--------- ...rtup-flag-to-disable-gamerule-limits.patch | 38 + 2 files changed, 362 insertions(+), 323 deletions(-) create mode 100644 patches/server/1041-Add-startup-flag-to-disable-gamerule-limits.patch diff --git a/patches/server/0489-Improve-ServerGUI.patch b/patches/server/0489-Improve-ServerGUI.patch index 8dde1d1a9bc4..48a151cd82f1 100644 --- a/patches/server/0489-Improve-ServerGUI.patch +++ b/patches/server/0489-Improve-ServerGUI.patch @@ -102,329 +102,330 @@ new file mode 100644 index 0000000000000000000000000000000000000000..8b924977b7886df9ab8790b1e4ff9b1c04a2af45 GIT binary patch literal 16900 -zcmaicV|1Ng^k&Q(Hn!T>_Kj`Zc4OO48rwD-Gw*(Xv_UIGaL4*?7e3`t5-R2lSh^xqd84Cs4}W^FDQn9zijsF13M{zVR~<`0dB -z;hww3Rk_uLO*yyZ^N(arMN#SjFcHEi60E_fZug`IjtJ^LVtno=lKj+Jze{_WszRIN1X*HUTCH>C_wc;+D)6YYT -z*RWmTUi`Puu_Uwkj6-qwu_Ue*kO&$%=o%J?6*rej_Ock3znkGIb6 -zWm&yS2Z9LS7slFgUx+?ilDgQBdj7`ruw|IVzJ@wV{&tD)G@SPTMW@9Wl5lcsuU~6` -z7raw|%Or|@Pnlh`7!!rA1H$`p;zz}+92Tp2bFmKDAL`nrC>)<{qBHso -zvJ6|o^vMxL?frh4XZ`3WdH7s_NI0p@{EElbnX*!yp;Vtx&K&w$&to`sW -z79>enm;xWhu;ZKKIN}-h!eBKZM6j$9~*Q(SlE*i_bHS0o#tPY -z5-j+ww|x>h9%`RLUixM!e%f0qVAe5GH83X6?!#^_j-M@lO@*-aD%NMF2;Hg^Wgh@}elrPA3o_&(- -zeNyws4es~%;K1o+pfG(Z!G-nFWzl7)ejRNxY?M~uI=I&MYuz@4>GLH*ptjlQJ`LYr -z*KIIVzBhKHIDwe`X2hc@gsdjzXxX%b<_#kc$vIHFi2)-XM1=fs(`g?0)M{lcJXwp< -zBgIdDXM&n-=+_%;1a?sE$oeN{r%w=8tFfAlQopAk -z%wrVN=r>)oZ0w7^M~Xi~qp6lEaABgF(ck7V3Un;@cg|ODuD7@fw~OZ;^TQV -z$&4AiUj}-4;o`6JV$Y4C2G -z8hVweUdzl78hWzD|&J_)oRr2JdJP -zA&lca);^P(q@hQb9-kqNXVo9An7Q3NoAtyRQw-@JUDD$oluryjE -z3{zzbZhStP-K;xw@Yxf-B=4h(p=4f`k8p2DH$>qQLPR!szD!2|vJ}J`C6=EoRwG^+ -z;`ZDv1SGVO+?IqSxpxSM^_V~@2E+~dZQdl+oz;TP1MX+XXwugMy?Z5AoZ7#R33Y@T -zM)w4;9L0szO3>6i#4fV3q49@wu&`zcvQ!d8!m*dpn&7pp0Y=;QbiyOzhC7)Ki7tDt -zXaIqysWqx53ZgHlO)|YRDG**$7&F{0a8VEECY`3;yx)F>2;4Xr&gC;Iqiqx;orWkF -z8xk0Ty-mK&z`^~Fbs#S;;Qd@1ZFJh4R`+H>Wx$xgn>^oka;w9~QfR>rS7lYHG?D#o -z6Jo`Qg_-DP -zX@kdURs~L5?afF*73QF!=HQ?vIysP;FNCMBfA*}*&%$eDHh5L|y~D=C^v8(wdtcYZ -z)8Q|56BuZ~3~KpF-oKg|5Uf@Ac15Z>sP<9hpm(E>^cgr8dMxGhn7mnWA+JPK+EGR; -zCfK+V1&Xi1M6CUFIA+oJqr(aF3W_=ph7h;IVlqq&xJ=d(CqczQwL>f*A$gJW_|iZw -z&>!^cGyI)UH(_%jFMta0ci8K;?^D#C4_`@%@wP6R4qvs8y@ecdj|*ia7Exg3*BpG4 -z%Dqav(-_hWolzv04-3Ygs)Z~U$`R?hQq2Is2`RWS%z4?!GF2CryzMjCEFg_Y%K+yz -zG8tm;0X{;XG5?BBT|pMZ296(fGUtoF_$Ryrso&s;Cc!g3a;pYOn-tjPvW+1)iAQ)I -zaPyG(wl0MZUqz_Z!4+oEh$t>QIaiZ+J1|fQdfugliOCAg+6D!~3<-k#gA8N#Rk3@5 -z&u3Yevetsi3m`sm2Ntt>FV(PfME~wR=LFu+2@Noy&wr###hgP3mjy&H03re#97OQ% -zsZ;NtktNoC?s@G44Num-@G1zw*?jMf)dA`SWJHyI-Lp=m -zyv8V97L8$~?>Sf(&Ee27TQvEf=-_%~EL56_n`*ZRVS`=4Ka4&HGjr9P8e3rf;8BK& -z&0s~H!Z|V-mPt9vUj?5&%Sa@;XK~`TS$ylgW4|1h&I!<9c6_zoDdR2)FLErHw%Sow -zwc_2ZKizcAMchMvZ^6OY8)uiUt&RwA(`3@dzgihQ1MSrNi;ruq-C+?oVa@U0x -z(>^4ei3Bedg+!LX52G(u@W4P&3sdv45%OawU(*aQat~OuEf?Hi6Zi>__qCd)nw0_j -zvUwA_6WQ5tnFsl_AZNz8L8L*=L4?0A>inj9l&C`AC71u=H -z?bu{Q_=al@1+|F&El|te2eQB@?#+g(D(LjFx>w=0X;CJ|CQc@tuin_)Rd$KH$Y9P9 -z${MAq+Ns2`>_SLAfKm9~%?U2bK6>hiDEbdUD#NMd$hR*wFx8TxWVY3Za -zM&tRPhR$htT-*KlZT-SGBy4YD;6aZfAz^Jt1`=ABifztn#D_;u)2WTa-Bo^EKL;=o -zDc6Ov2x3ybU1B6gkFjv-UvyFl^(EFkIb4ht2Z(*io4 -zW(6^Rp7OMxVh73mYH?bkbxgXB=+TL>U^8OY>=P$oXPkGAmF?6#80T -z+e?24uzuJC8?nCu`7)ef&Nu8x+`0%wOB9wmZ^(+|&$!T80~3uj?NRH)aNhf~#vN9e -zem1VW#bKd$SZ4ufS0-pzoJ%P7UWdT@8yg`1+kpYLV153t;UJy~P8@7sO+#{ePIXcSgw}v2XayA<>Jxh}D)tMOGRgJY0QEJs` -z{>aB;ssVeqKi-6L#(PnBpPuOu<4Rf*GWVk8BdMCd} -zc^_!LU3n2YWBEk1?0<%f@MkB;t#h0%&cixNCZn@Lft$eDVl6z=l@Ga}k<7cF5n!!o -zXet^Q3;AyG!j)+$=3U>7D5cEf)=YMZ)jSZ?)!6EoSa3kU!3W2Xn`K`PqR|ML`Ju!A)|K2`l1>ErJG>o*qIC72B&jHYe36od@P! -zi)qQ9Y7g*>N;Y4;sSLlPxvM;q-Tzw2m;Zx=x>{mk0;Ed5zA?Hb1FrDGc6-;m+iSFU -zc22aC&R^-iyw5vE$D?GWWo7A5o@@>d3_uD92sGM_-tlsdQ?ZbAnF4LsSxDj&0TFgO -zFbB*@;0<;Y0es>tB&~M12_up)gRS(Ce{seFR$9$~MC8~S%gCTV+2AIiH`gndEW2~H -z`z|RK5KuxIccy|!;Bkm8puw0EcWFE{ij71G*o4( -z0~y!3%z_nq1kdh3x<;XVQS{_v?Q3|H1so1Z#CL|Zm2Z&7-mTO?&1?U-oogOAE4Cm{ -z`d4o(XCnWH-J^hx&?7X^xHns&B`u2*skUy`s~w=0252bVaZy(}U?e5?u>fG!UbYaS -z4Gz$YBX|~|U$??YUR+zxw2g5F_OJB7viI^}qx|ouEswnc0o{D4T~~|912EVr9)4P& -zS=*@uBmgy>GC)sz_8A$Iga2y-R#LKP$zyVe7P=4Vrn@Q)Fp6mG;Nall=^07<{OPT~ -zPDD~5M}Py>^H&ikOMCrXaXjFMyNuyNg$gXaPOE4z3=$o3Jt(guFuvAQbA?*MR;Dx}r~+zsgJ -zzCtQ*$r?UAKNl$E39K|(pdcV17*;zU{VtG7{)QDicnC&XAit07AxkJs2xbNxkEh-l -ztI=-hZ#0{5e0{huHk5pMKFXUdk-_HT=8j~#**>ze%L-Vq--ELbc7OqlEqqgfDL$7| -z^zia3^m~7il#>&4bK{s6W!C%o9eQ_nw_LRXoq&)qk2e`~Carh!_+@C+^?4E@nB?8v -zrP(B~aF_-3_5wx4#3EgX2f|T2iDX6dBot9e+}zxz-+7y;fop?^#LWumnJ%(ER<|F> -z44(0)x_-m7iZI17bV#w5<;|{V>IZ-R+z|XI2d!L0M$z{_~PzI|b} -z_>I9TkwT-USfkDEyuoB7YJe7^SUeW*JCd>d31w)Viag>w -zE)Hcnu_U(A@CEh^w;UM0IVsDf+yNUB)lCpiM=a>2dMSVx95URpuHBLGh>h8fgM&77%eeba~6*@>lA8=;7iEw2QP4d^IvP -z8fpiWc?lq5kxp*C)nS|HY^i2ov(x?A!{1u(mk%xyJ_nmAsx{Zt=LV=Ta0-O}2|y4O -z5yIAhMw5|xp3lvw|Ps$0W*KZd^Wlj=W@{AaG=^es3_){Y~Jis`IYYiWN~ho|DLil1qRD5 -zN6xAlvXG=U-8`VKVHr!k-;5Bi)EfnJRTtvY$;jR$#e%~lxMV?xboY;JA{IT_^y}D0 -zw1mJ8tVoSO-(}absB6M8b$Zqe)Ok0$OkaA#I -z48@e8TAlv;PmB6dbP|{7<%qt@Ea>I;PRL4)=M`_G!A40Y$Xy1Mum)I0#!3<77H4)u -zI6c{)TUsy&o^*@2H9Bp>QJA#S8$`zN?+@z^IIQL|VxYEQfVw~Oc}Wq!FS`G2T=aDu -z-DMYe(1$x=331oN(i#yV%?Q)lcY`}FpGRp*74@@$fX%pE+dAGOh5QRhJ&mcaXOhk4 -zLi_pirw^Zws;d9n^#IE8T1ypZDX|crNABquU?iL2;Ql%4Vg5cNBt}OJdbLKnEi|`g2q%v70%eM&7 -z5gdFefu8Ix3n54MC -zW40SGT11ajrrm5AI24T?-2$|VMsU%VX}AMmt>Pr~B}#An{>%QG>_1FQYV^)CExzx2 -z&7E_9c!fpiCLci|F3H*eM2DQQRtQp4>V2RP=KX3ZVw#OXuFxj$VDmM&HQD{*dc7301976VQyI69%EFvxxn>qC&Lo-`%ImvM -zCv>AXKPcD26Z_;m`1pw)uF6Mp=RnShU^yM81!?jbl!v#-kSa#RLhSOG0?yp1YB6Jr -zW=GrO|0zIRSHiH?DYiO+$EpdMkwz#4I6V(J12-W0+dAo4J*?nDQrFI<*}a92Y%1bU -z`RC_4tyg7>R(8{ -zA8*g?PWv##WoF+p0bJe>whg#+(1_+A+)9HS$|n?k;(r=Le*vR;57rn)2& -zEkD8KBSZm#3Drt?t!*#s#>0+yUNysIKRg=t`KSOcSHieiUP0z8F_$tZ(ciPnq_o~@ -z%-{zhbs{i7 -zt~8q8%WO|MF(FE_ye*bl_-@NcA!S9$IMb6x0`e_oNF!hy5a)H^H)5)t(}ek4a1Nc~FF4@f;5aO%aB&3O%B8NuMWWCzYb`d> -zQ-&3)G|5M|pzcLy>pA(p=?3&XKn+v0^`HNsS?M0eb+60BxF|&Y{?>MI^x``)Vp}1V -z;<0N$BUc(0=p=y>zD3k_I~ -zMC>T|rn!T!wN%lqT@ -z&Afsj|04$m&CH2M?F|6yeqb+e`&JWTP^~~z(;c>5;z6RuFKe)%3j|YzeZB9c)5E08 -zvX9?L9%?PT7Vu(RAIXR}s*=I*@Qp<*vA{&7B2uwdBH$_I`33U5di9weG|3 -zx-Iy`1L`R>G-q<+w-{f5qc<7ls}^cT4Y^Qi+meHXFIDgqkt0wpdBZGY?LB+q9&o`T -zd18L5%R+44Ml^UNbEw58BXP#{+I#J1$;VGO`#6Grd<=RWgP+T+ktE6H^>C;%(}szj -zK;wt^oW!yG4Fz=zm4zKw@$Wdo`VJm=879kp$F&$uMP_qiKSB4L@SV)g55F9Rb=3ocrK>iqIRR9n!X0Do*Ldi{9M&^sg&T_TZz~>`tbXc$p%%BI% -z#MahUA?U0t#2ZA4_41*w&52#TXU^_G4)$#uGOnpIb{Gs?Bge_xP|beH;cUSBec^gk -zu;a`And#3j5LZ)LALL9lQ0{$A?tzx&K6M(;#M))7n&`7KTkT>KvjI7O4?mTa;X`81yn7WAir6 -z^Dv#2{~#3{X=5gyP*2v`3yoLJl)--n2rC2}*3n8(L~4ohHzT6QbyEu{!K3q#&p9Lp -z?3#RrZR0JWoh5V%Au%m2?uSB&RO!i99khjDd#7P;NaxJ<_f>mYXQOtXqBZifoWn1d5WC&hmG;&Gv(>!l)|)selJ-m-pz9Og@*rA -z%Xl~n+gHI_Rjy513U_dEaq-~ZLm%H7RpVbREoW=Zu*D?n%JFyy6(v}{RCOy -z>_wu--o5bv-4rRuWG0oN3a2+(f)C6nR0%>9HdI1mB`d{jE6Q4vSf>>{@~N-bGMc6~ -zn=1MB2?XIjZuOC!s@-pN5{60UUw-L4f1L-3Ohud?4)I$4Y&#w^A*ij(1$$3|Vskv} -z#YKCOBnHKh5QN8fd|k)wI{^HZj_1!`{L&>R(m@P^tYk*J)5>eCrio9{j>kWLDCGrM -z*O<)utCbjQiH>aHzD!~>SNyzV|B?uyizaR*!v`(g6N5ks=aSqWHk#wzbQOx2Ehc(>s -zfl`oSK+EzLOKDeK?n#pu;5qF1g-8bXyN##%K`x2R14CxOh8w&P-kz4U}>3Q=A& -zwAa>sCXe?|fR^Y+S9_jW;=!_GK`1Bc2HY6Y)*s}A##+#}239~LV&Q~wL&4n_6^@vW -z;nGUYJ$5-C#kJr2EtD&Ty$t-H)#GyT->}39LWB1gdo%LwqR8{YbRBL*-FCEc5iY{; -z#TpZ~y8yolNKuWi&enqz%<*)Y)j#ff)9q1ezkI|N7|zr3b=T|b>+m?)d% -zKJ;1@L~w8ZQn0MxZS*{ew-;Ohn^Jl!+U{m|QvgB~tai**t#d>0E=CMjN*SZ+36QnO -z4NrSN!Cd>9SLf?=!Hjh+ek}c}ND_U`vvi9(MS>7nGZ*lPm%4(7(bhfuTHod8y%;N{YO_KMV}N<7D)x5snD;XG -zzCOH#WK2$4mAvQWFCCZW#F8TRInJ+=$6eR`V~dES6+!6-=6lkVCHyCW^Bb-$@=b%3 -zi%hxQwAp^EOp|zR61~UikJsM89qE@P3@X5J>+K)hO6K`Z$80UqhLV&|mVt3wQ#G4H -zi4>T}s*jr9pkN+B@=LbuMW8^kzEFQde*yOdnXiUws9u#OD8dYzm?0F`qCm7pBCNNz -zOJB@PR!5?2&9Zw_Jg~i=TwmStKiYq1_@$ -zZKB*^u}y2o({7rV#Nl+8$2T5 -zthMF3X`+*;4Q-~&-*4NzrU=7>#}h=jB}<^tsAch7Ac~Vq;V7 -ziknpCHOP}_P8F&VE%6e`WG~EVa?$ra`knKZrYWbIZ_w@4vO+{B!(Pb&!YhY8pCfe= -zjxF8x>Zh3;#gw`fu})grVJcf=Ohg_Xc9m?(57$!NXQ#N%;Q{V}EjtmA$m<@Ie2(h2j9T2Xq=0<2R#daW&$ -z85=lCIqjn+?h$SF4u|?#DOOKg9>2c{9GSdlh{<(WR;Mb+bxH>u95roevUiqSmcdG* -zEL`{Qv+mA#hjLxuC*l?ROBgDsPYkDNU%;m09$2^ni=SVA=kS_) -z_h->URCbhQr89T-a-Gg9Dk?P`CT8-=f%@A28AYMmma&Ks#DNDsr^|eI%nHBQ0Nps* -z<{@u^G-9krSD|^{Vm?_nRkW_T!;E*n95To#4sxn;9FH2W%&T043S^Vg_Bk^^&J9*H -z=-^Zd6GYUG(CMkA?hy<&4Tc5fn4$3ys+ZiGw!07qHH1zPDzAJY;{8Oj#B1-LTAZ>D -zKqX)c%j0#o|H%z2zdkxYKaV6<&nEMgP`q%2&v+2dsa++rFeWoOnf$VkCAY6|8|kw{ -zdwe(maC?oeGlx#HVClH?)W&QZ`+=l3PIeQ%9cb~nWxJ9)YD|MPt`v?0-3bMcbZ<2Z -zG7xSnH{QoOr#C@?R{C$168|JMfCxcPAVuEhewgQpYO@AfbP3Fw+|Vi7h~L@$6ydj5 -zyf7_h9Rp$0Gii0mkT9xddqw>hIVCXV203~$D~swIj_)TV=zX)@-tK6Hb66mM;EywH -zsMV;{!i^8fvae3b)iz7_f6$4yU2i-b%Bh|o@eU2$RD^G(AtWlyl0^8dxd<9 -zCi_xU0%&wFugtmc%-uOk=xMY?lR%{7BQRZ~b8}1<=DQI)v2*#3|70VNVV*?SK4O}0 -z-HEICfCoyTwy@{F=Ac>4KISQEgQLDcj|>j}hzn(*RSn -zZw&u6!^Z2~7ae&u`+{IHYm_vxJJ@RRZ!LoCjQ2ecK6E;AqeyJZxfuAC -zaFBgBIQO4DawgA~vN)BCS%`;S38kn@9kWOTMq)$V$+z&4nDQvH*{(1#N58$C)v2#; -zJW|ch#FaXRBNNj6mX)HNV{_ScADWB7#Jn(Th}B15lvrI|-2fj-=SL1AY -zQrI&y#`tyxRIyenc$G7)m}|d;5&h;8q8?ap1~7v{vEXIAhojO|^XI$6=K!f+>;5yx -zJJXiq*Z?mW;Ak{?4<=)9$$a@6Q*=1_%}Nx&bGA3oqS%{I)k3y{#DALAzrPw)h(FU -zj}8a8Xte($dBpT -z_ZLeg50aO#zhmy?M*+dS#c4NyP>CZSyS+OOi>@2;)lr;&A$)(OEO;kV+bz6O57by -zyW>9>Ij2^Du|A83(r~$46%S7?Ancv(6R -zJK?TL+k$9p$KMJgY}hdrTzyS}0it==hvU?8YM**7M}l@-W{&s26~NM6 -z#U8(RCX-=6Lw%{$D&=aKSfE%aJ<__RASP1DaZcJPva<-yi3NH#t$OuNk6wlp&CD~1 -zanJ|7AhF;l{a^)Qhr_9Bo;2ZG8=}0whx#r7zZ6W`Fs5 -zJEbvhZVJVsORu$w4Y1HyT1E4?Vka&kS*mSpBuKM>OAT~3W;g7KLGzfQWF~QJ1)H6S -zFCOXwP_auqzKSygLBPB}EH;Q1gXb@Wm*lZWfM<8NWGZM_*$8Ze)0+^IpqCyco5T+P -z>!edzc-RMsx%H6~4%a*u{&6!V2Xf)f8oOKEEtBAhvI#TkSv+Ago-TMSQ(2q}=S0FP -zL(1v}1vp6Ya1@zfO!}Dq3ke|~@mmFXu2dHEQWpO$6X$;c8V@V*w>NACSkmSKF-THX -zXc85Wu2(uhx0b@}vaeA-YhO(oJ!8ZlugSxzOn{tnI7h@dCB`UVE~EEY_ww_|qDlb| -zQh0>qvDy{uar91x0J$!N&ch{3*B*?y730`NAZJT0IXU?T1Oo1Zc+QnB&!+ZYLh%_v -zV;)6DQs1sEzvoxu0r{lou-yG%CgwotYzFK>vqr!e>KRehvaz@y)fTge`_wgV2*|2H -zVl|vbxEx$3ymn~uGqN65%FYqJ<_)*Uqs49;KY2h*(Xa?Tk7AFfl-xf>irJoUyL*;0 -z19&1GQV*5Ni~#kTnaq0ymCiLjk_=0q&=&|cG{r57n*6NwV6zJl5K*ED&DsZy8iEL_rr -zgsLXr6cN9-S7dCo0TeKI3ByoGNNBIG{4b4m4=LB^FstU0B?!6TBZ1v~zn%e*Xk=B) -z@_rySE6iHcIxSfbe^sRAkjZKFfR!7A5uNa|Q%HSV{);)`X_I$=Rz#g9)RV -zjIuDE+A6IDHt@Noy^%sCnU|?kL3tCMU12QN7688MFeYr;%^{CT)BqX<4rY8gFNo(^2<+x6~@> -z0Y;8%xJK3sk3si!JoTyNPRqf>i>%mkw_b{g-~}-aAljQww_S1L53kdn=uMDZM5$#ndk -z&22o*u=b&^trc3UMGkzzrL*~$;t?gd{w8WCC+z$)6{fY`v4CL%;?|JZtR3}&oLz8* -zT?G#HsX)xAYvWho@h=pJpzsjcWp0%LD4s08onG)Nb4)MY=8K^XfVvcKVvP||0{idF -zr>Wx=dX&);ID@-|u5Y#BAa0c8rW_t)Xfo4c@By|jKCCPsr7DjJ6t;eTIrmF;CpM`~(ysWB=S@seY-cC;IYp7eGp3%$l} -z)oc?3jDrN<0qs>+yfj#>o^%eHp8`K^wUK{qUM_Xl#K;;VHK+>&$DqLQV1~BoxLuBrt&0}DAhEKn_^ER` -zz-29QNvC|8F%an87xNYKcn*LCu89T8nVkc&?~&O83)5GbY)slt*#=)i7s;A_C=2r7N7+fk`X1KngTDCyUEafq@X5m_z1=DeiD@Q38P{+Ou8AdwgrjC5 -zajlbj!7Ae^jZ~9GGnmvF%|dV*Siz7~1$lG}zFHP5%BV8TD09lQN!w79WRZ;`=PM(z -z0;YT`0PcRb5SM~SQ_OKjwTc~?W_G_IPe||U$;Um2U%fe+7X>%Nvy!xcXUbbT1miw0 -z=$X7_W&m0ay!h~`ae>C68mu@al*ia7R0saqO=sn$tE@ww372nWLhU^>%{WE>Eoln8 -zaeH(5Zly+xlW1Z@B{Z2HqS52V*oh`BC}k&quf19RS}N6$l#0qGWzl9DQkZ@85(#UMH4E) -z!&hPrOmR$HRF*}2C{e3A#U3h9d)gN68^|>O9=TO4Ga~u#5kl0}_*QP9IxEl~Ce;Vj -zS3zvyQ+p-TKYiV8z>J$akDBH=i$W7}&)8|aN%_17$7$H|;eKWRKgAtrMwoyE;#kJp -z>iJ{R+d4p$2q2;Y5EBQ7>@E&mk*MzVW>!EDsQ9Pd1Icl|=0d^U2HU!hP6MLe0bwp2 -zA=U!|OQM?{{^8dU?o^&w|I~Y5fw~zw)IT&*mzBRUy1Ljo^-=Z`fvN|N_JgxG~k*Hc%03VftQZkoi*AD{-11-bt2%}_=-R;7ZY`jOzsFyAEWb! -zVJNLPL#@4|8iv-c@m4Lu!^Uc7?VOsDWty>@T6^QN67|~9P?w&boWVpR2)d)gI@s*$ -zT0uPct)H#x^_Y(_q2El&g2<(pF8niAzCde(;c)XAp3awn@Z)3{qMO$l1?#O_cXL+a -zB+yS96Q;w{xIBw9%-h2xp$%a(D0`Noi$$31BbukCM_lu$4sG_+rWsH9U`eD0eY3t3 -z@`vkyB5OW$_NhyNPE(&_JPvYO1XVd%SiaJPVza|ZguGogD*p`OzJ!Odk4wR7o=G7; -zQFEN*_9WQcO`Vliy5G@VCnZ;Qb~fJ44e1$o^Tw=L_lA;Z-8Dw0CC}X_m5Q_J*xP61 -z2tVQGAnU9PA@k;{9QL{c=-~c_joC`W*8qxTI)7}foE-)SU;g6SD;S1P5oGCta0DrC -zGXz?khB$Fn{Ycwuk%t&RTyJ!Mz8mnC0U+AYu}PkaA-t-gE*25%;RVKNKyWz!scpu6 -zZDKFBX5S4#lCQK!Ip%UxMsP%cC4T!8d`;mo#M{(B)h;Ilk3UVA`-O^+JuQDuUnt-K -z=jEH2NuzvVs7mGT0rJ;Nz54;;pVk-{O`o<8h5~yAG9cx)%sJ+#d0-B8j!9{+{>1@9 -zYiz-m^g@6wE8^*umZD0JhIN!|&Ok-?2XhJ@B|oI&FfS^$rs90JhlZBoJW`e5b9j^- -zWO>uD9oB-o4QKEBn$akVeT1MeUX-s%#m~lPXZR!_h7SU~%Y_rx{QlrO`$o+{oUb!PIS+x5N -z+{O+YLa6?IE1#&A?RMZ&J}!O!vj>Os^y>J_BMi^Cu8;>FP)!5eagStg`4k8`f<9)s -zLv>uniXJHc5tD}2a*xO+UycHT8lGykAS#tq7H&?$Q|yXO#aH{77;M;}%#Rn*u_i#Q#=kFoCjB -zxM)O)sW@_wx=K{lJ|iyESH0iv9Nr111eP3eEA!SenTb%U12{RS*7qj0=;%^Kd#QiJ -ziYTEU=jFY{zWsSqmqmw<7L@5T1o7NxWhht`9gu$(b|QZnjVAE)D;lyC=>~hv=8piE3T9#-QVKCSaq-q&xr*zuRbfKtru+;Kkp5Si5+<6{tz}rp -zigZWmiiYYR#xdxCbhhJz=wN$k9zPcR8H;AJErv2><3*Bm51h&CEJlpT9yo5`1`w{pnaAJ%0k=ISmg0E -zo$J6^H1-w0!^WV5w|yx36dtal`WN}DGpD-gqYjDTfjIaLtR}xxCDSo6v=}KHRM^9@ -z&T;nw5x5ee(K3%Z3QQF%sMId_cIRpr&3g$f><9ZoX7X_c7g4f{y)mf(?;`TLI@jLv -z?N)ryzDJ)LsBZU+VnRH0X1E}KJ!}%#n_-hEY9w -z`8(=7Fd9^wGY;{_ggJK@ZR?yW!1!^^d;F^x%}=DG(7K8XMm$L~K*Np|t>vZmA5%Y| -zINrWxnZFq_J7&ksTGEluekfNRCX$8u^xk+?w8Q1iII^7LA8Wc=uh=>E34C14fN(+~ -zjb&LKSzG|ur8^cG=n*d|U)DK;5`-D7c>o{;1qb8{cYdL5^ll*Y29ag^ZWs(}{Dq?& -z7Vt6fu%BVSoqvD;RYW!I!KS^e-kCz_2@FvAByt<`2mpvxlE{aWp)% -z7->KZs4&!M+Z9|_;(QrbPRGNC2zLU&;bq*v@zaDlNR7 -zR!OB(0w7?XvMI3w1tc_A&fY$=RO&K>9q)K{?KeL9#X2nl`k!ouFF)XFC@Tui*%L4~ -zwNvTu3}=K5TH;uDS!^k3d+!l_hx$f?(hkYU(6NBYx@mz*Y6dZ7D@JF^5^p{aiT5zv -z;Xjc--#|sw407DGZz<4^FBXBq5F)zwTQ|65$~FTfyft2wOiY&QG(ydKoz#wa?YKny -z)9C@EX0c#XN}}K5dNFdMNo^+Os>0sS^c;E5Ky4zm)q;>J{J+z3sdUj)7tN@@gZSf7 -zJ|wiD$oI`e{Xe-gDV9P_(x}i7AaPVJn&m~NMi(84-RGbXy6@{lY?h66ze7!6Ee=i! -zInre-6PCHrI9+8v4+)Zge*esLVEy0*)t)o|)801Zf98hgQ=EZH2bpZ=)5NN_2yjw# -zP8Ewr(5WN{8DJpt*e!|G(gvZ5Pxywag$Agdns%%4+IH>|FMw9b -zKb<-v)*Cb*Ao~hb;B*`Ee&trZYBi`{$ru%gmKbuXcPNb3lD3H3Jimki7;BEFp{bxX -zFJ7Rk<~$d5(AGs1%w=$DDrj&3=?C4wX`U{m8^^=Z8R3YTB_A>ZAOkmldWl -zwo0ZyTNCB`dfUZA+chm*()HWtA2!JQ3>g${8%Vr% -zasf==&095e)fG}M%iIsk{PaQ>2|D59ppz^2pExvb9Ou9EI^`kN!0aXr*u3p0ex0b4 -z=AnHH#@v>`#o*LjN-yB0^^l)H2Nm=yD3|>1aNigv$f`s680kxF8B%d>SUG)YF0R~W -z$TI5rvll2~&q4RSwu3})*@1!~z4l}@NsY#MwV(2Y=hbLZh-ce*Eq3<#rZ -zxra}au9h@`-JaCDeW|)St?N40z`g~4rjZ?xu=?#W;cJyHNPXCV2DuxD%N1A2hAlFH -zwTJm(6XPn#dA&{dq>&yd{5Lp=pa<%$*em=~TdQ%rn_v#5`>I!IS>M^uNpl#N|wC@HMBcRTMT#SL;d7 -z<(&BuA6dLkkx|8fWw@PXzCeCBgDx@HJs@)L+j8y~gZ)7)${p-|O7{G? -z&|M6FI|A*^d_U+Of-3`+w(c~-YsQby|NH)g|G7xv|Nek^|Jex)g~z+)I0xPC0460S -LFIp>X81%mY^Bg|U +zcmaf)RZtymu&!}kXmDLfg1h^|-QC?ixG&s2I0Sch5AG1$U4m2?7EFMOsQs1p)$M^xuU52LS<5tyS|A0z!B~T1;5Y)8HZp +zUh9YE!*I`C!>au1!lt}?^7%)ymXa9F0E8%U6cA@Hs@r2|t2YjT?MMEK&sF!xR;P(1 +zJxFf8OgT_&`%_^18f74-j~9B>_v*F_4QG7P$=~I&{g0k-!dKZ;dhG_Yv84aKQ7`JU +zJ^ehid=1+b=_P#o97{5v??~H!^zyIS&U_=f-+Z&XS28Q#IuJUNE}ApzE+z8$!_(s%I3_!)=jTdGmXzz2p&3&czvSwVkj_PR|SM`xDjT-m<)@wFKtJ!fY +z+A9f&c$RQF&Z%Ui9@S9nRjlxMs@)Z5_OxNu^|5JS^tNFPeEv!Mp+fj^Yc}Scf482J +z_jv2_UYgabd?1AMePOH(|ApkUIjM`|sON7?4||4r>}#l#)Nj}LPNV67U-a5cAqgk9 +z4hA)b1i?G`_{?Is2NgH3=G*Y_oV4G*#y>w?4I7fSpx2h|vD&hsqdFVmofnVkNpM8o +zEDOkF7WVse0CrXXeH^X&Y+X5Ugeg(@8XVq_7ngH%kQ4q8to@(w`VD%+t{VjBlZzMA{89 +z;%$e2aiD==VT$}%!%lBbY3xicyog$jB!Djxd7vpR6bXArR{Oqv(5MfWsJg3Yy +zcUpf*M1f-z9ik)^?H|-}` +zxbJl0Xc<(adaW`;Xc^eA&$kJ4EZWH)dOO+mFzw;MBfNjA5<1ZP>E3RWzD|&L1WdK! +z2k&T-AdM3|);yD$reQ{x9G{_#6R5f}9%tdjf-W#_wS$qa(*X;ot*Gkja`g1Q_eN^= +z`0%;Ho3r-6zU-m(+)f%v8KxzXfn20UBXua$j&hd^L+a{0lv^F@IS92IL#!_sffCl2&zHVp_~j(J1np!W5n69+~xPAJ6}_zBa%4jtFt9W +z{@f*=wRJ|ZitBopGm@A{J`xa&M +z)PY`TF0^X2?f!}827nOWNuI-}Ne-gU_A_rT89Qjihq3d_{Ugx}ge|kRq}v@?<-}sM1htR5<=} +zI1L1)$lG(bP|&c#@>`Np6h0xGHe-S%SWq_O*_rH`M&)M5xj9Un#*HS!PqE5 +zISo-XF(NX8c$<8iK|uH&>qt?Q&-b}D+Tgr7t>MFp&WJTZFnPZ1>|RTVqu7iauEwTX +zVJi3CHpH3>2eq__Ox+k#@Bzl=K|7STdhX7MT{c8Ce71~q9Y&PXH}*iaRuCUgMZj4H +z)QyHub +z_qnc(rzc$MCNk878`Sofx_>n{BwDNL?TS=$RO_S6!R*Ey=`(aG@LbB{HGQ+@MqP=h +zu&0VvO0ab!36xlai&*>Xc+6_xPmdSo9TasQ3?*TY!)%lYzD(AZ0HWie+au=#fiLo& +zU+O6Y`-6UchQAZ*C2TI_f~f(2hrMt6KE)jP36+(ZZfle23Dx>Inkk_7xY0&pkp)+N +z%^^0b-mA7bkD<)a8%J{cvSRJ2S;}#v9g(doR}TQ3QGy%7T$YWkQuW{|T0eu$!D%Gg +zhIpru$xwR_h!F-%c~|@zigH-C2m=8{D8VNnCdFPc6Rfz(8f#dDmuUW@`u=TQn?l6ex-ha;(`` +zrS1uS-(@|j8cS+#fW*WdM9k{Fbp6f|!@JL%Gh}@yEWnTjE-DYfVpx0s5?hF9Qzi@Lf>~6Pm?DX{;HP^Q242(r1D1_=jrbppWF;PQk_!Ls +zS?3Zy6SOYNhA^`C9Gr`$aM+kF+PqIpNc~b)YOTag^;@K{!LHyR#-D?kKh>QZn&JHs +z(S}LQ;l-T8IWrlT$vDeig`Pf3fs);`cyZgTesw;vUk*#=1ZlB5zS``R@)U;`I^|DW +z?`Wu5^KI6hZo2(M-a~zF#>3kiX?zjyY=f@)xk3s24jF8WN!RqnV5qMC{5IS-?p~l` +z*Od<2Atam`NRWyKlq2%T>WdXRFci|p)_QD!{us*BG6#&@1J>-ygf`d(+Yt%AR?$|m +zG2&h}ZNhe;3iL&t-&Bo~bSQvwc_uqFF*q*u<%r&3Io&Jc +z8X3Bs8jXqH@NHmV7BRmCYCHHs=Nrep*-}>qojz9eD&96O%Es8n$%gaSnOL~VE%6i@ +z&N;!@pfy%G7dw?+2y1|uMDE?45uzNTNB_7>aX);UvtG>N2^CK4jXJOIypMJdF8LKU +zTYqIdp7&|wl19M2-A~xsFLDE9e-nocdK3)_YdtcQ)W%k7bx|ihJbIc=Z5ZyZ^yh9L +zz(%H87tSJzNkw!4yq5hajBkYU#kO&cksLk7!K-`GO(iyvT=U{|HBlNQU1VB|)w$-~ +z!`vE~Br`P8J<1%ly9{1OIZc%XlCTOPAdcit!jhpR;%=Zn+J^5sT)?#vtC4a+pY5iB +zJDz5Ru-Z>~+fH$VWPdd~FVQ(AT}O25HPC_wANYArttZij2ISLx>m75xSQO6+R*;0g +zmeuq!90F_}HX%kFZpuj4@q)SDa3k?+Bb2PrSZjTt%acFjLT3$4HPduPZ4Sfv?#~)_ +z*x>rvxpNnXh2P;_1YzBnVcqa9VK{mn1MhEaK>}|FhPXm?dB28(cqh2Ag&XIAnbGh%w38mufD688Vg0{`stk3i+PA1e~X7W%o(N09G +z(V+dK5Ra`6>fQc$6V4g$Mc;jTrbmt|ZcfPDi&luFxnBGk{2GGnMACo~C5VWy9A^BK +z%9O|VK>O{=o7e@%H==p}Gh9?4J3)S(^K@|@-bpGMlMM#a6u}N>;hDZ{$m0w+?{P+i +zv!bb`WN0Gnx5bB0s;!iJeK(?O@&xo_Yr==8dbs9N^gw0u(XKa5#%g4gLt%5d9^x&bUp+ +zI*CuQXb^F)LGcsTq00ke&-aZbA7b?Ow}kNZFJJuWYsoo#JJ +zd^|iHd;0^2Lk8)L=de&2-C9OWIvMMW>WH|w6peAk$qJ4MH%Wu;|h=~A6+4h{@J3knK0*pJ@vag9^60=vvWcI&Lb_(VX2 +zy)N7VOA=(g{REg_f)&_ekDo9i1vl8j0R0zl47}1}4kDqz)m%np1-97YCtxX^_8Eb1U&2>fjdHvFw8)9n=PT=mS{*wNJdpIN5Au>lfU5v4<160teocH-d>QHxOk-7@IW}47m1u$uA~w=(B0jA`kk+l2DCPaOxmP~ndvI$ +zYkm8H%IFn;s^>pUrvz6NLyr<`Ro3Korg8A+&kfO!G6vn2h>XJTf5yvnnk!b`Vn06= +zO|u}x(#U)>eRZq|c{Ep6$&^P+2{n)IUvm+$hJWpRp@dc$Pc5;};;;?#x;>0!Q&lV! +z`h5GsX89Y7O)`a6U8!1!!`XBAGrQC|6pr$y?Yi~{n@H;dTYvsSV}Guzrbl=`^4UoI +z8~S7M#L3iCl4D&LZY7p{pxhZgK`flMwzluNP~zogXL!BoNYnrwRFOn1!FLoBg%hgK +zT2%$)cYHjmbW$l?<>3q586J5ELJKn1OZfwK6zZEGypC8YxWSi_nBA+Z_&{j*y_tMb +z6C6(s<>8a1YQkTymwXrrI?Xm2Z(XHsp-_~6s;*Hc@MZxKw?mh=jIMvB--jM9zQDT5 +z_##%J(qN!>z*rOmA{Oc8*IOL7NzRt42R1uBo;?F>^ndx{qY!eko1xoqPknBbx`jeg +zBK1!If?!CHwgxmCjWr7V)0^wAxV{-lm1HGp@U)MCwN_MeX3LZ*jEL+Um3h1ahneA%41;uV#JudJYWnF4<o}yV;v9^YzeZ9DJPbxV +zCaJz8JMuzS|;y@^GISocc73^ZoFw_q)lcpJX%zS +z?3#&5BtAW>(BMlU0{VA<|F{5pf0gcm5ueT^9u0&(YN^<63?O&=!S{pn(` +zLg_%W?ebF_1IK2E8}fXKJRN7Sd1NEd3=zE}{Ff-55EeRtg*n1;E66aMQp_*vt;2W-BHy(2b;Flg4sLL8j`MDJ +zAbfu?@{0+Il12eRII46kiNKmt05>iU=h +z$)Irsw!hHw5wf7*gjxln_O`c8!(m4}pSsbqKLIVrd=!}5jW}+WPlzQ;+_e-& +z?Dy<48J&+h3*@LUmFxqzh_g>rb^`iEl)hiDf5($dZZJpaL!%i&d@Buf3+M~(|w0IKfQ +za3X0Srk%nLvE~Ab9|gBtt2_H<(fw_Zha@}t^K>=dbE+8{uYX2|#N=bmI)Wc;T*rwV +zwd5A@i2kamPB6hHF1AG?W!pUo_~vz+3wdlN<%QSGe!5}^qJ59h?#udS@qUf7 +zv-9ZWcl%ZgYEV62Ov?klP4Ypq+COVB +zzbpQbKJ4p#FTFlCeU?M~M)FWg!L^__)A~q8ym6&0c0f4_^d1Qsf;q;YQPHwFTKQaY +z@}^_vfdLrw7oSN5$O~22BEUPFgd#kF2FBsIH_Toz2Nw=v^=tZBu!NT|Lp7qp(fZ&&7q@7C0rFJD6; +z(%|4PztN>6GF#&@{I1tbNIIaALQ8ulFL8_Y1vGk-QMPKSZe0HpMtxgqkoct%kuq`w +z#x-}Cb*!ytPr?%+STtAMUu{{K-N%@g062$UWI7UOQm3=mc9wknbhD2qEj-!b^P +z%oYhuwx~lumz_3B^a7bYyyq-71@Fw*7ULPhNJocwr5CvLRsE<~sh>maF=R1p!hO** +zh+7MfH?17kb@`xEls`270@5OICG>$(UstdYt%lJ^wwiJK8I1@$5SE2?UF-^CtL8@; +zs4{#zGZBM@8f^QW&S9I{2Bl9>kdJkdQs6??R6c{5q%l*?6D-aNSM(>Zc4);q<1&7n +zVSb1AZyvYG&77Xtb`dpP1hGZw+U_-uc%-;be&gSUcbi*hJ9V!?LnI5O4d&1TOrlrE +z11&b|=uC!5&O5GB^zm!T#ncJ-bmy8|`YuXV_zy3)jPFmR0m +zFLy&N`z42~p5XU|+fn|GAIE2AfPi3JbxB>QXQ+7$3m_ug7v}~qfMAh#5*_)0mSKO^ +z)R>_thix1PNC=^T>X5@o5Ik^s!>_0nb%0+Qu?l@fMu||fRMI8(eq@a06~$a6goXp4 +zTc(!CW&GU`Z?7*~C%0!|`Po;Y-B>bq8(=^Pt0w>CW3cOKf|^OmN3o|I)zb~mlpR!VZRWgf3r$DjB6U@% +zJ!v9xOZ<+LBarT*ahaknq^miC#W^ANPQ%<$&RHDpEBCU_M(sbvsugC-mYh-fO{Sw9 +z2eEARzci;On#5;xRA{kHL-zc9^rxh(B6&XXZ*i0bo|+5(tR}B*i$>CjH@i(J`<5N< +zm*!QawcKB`2qVVWN|!2bmCj+qMz_>lyQe41Uc6GYo8|ZmgRouOWH<`fPtitAzEwsVe{gYe@!;OmfY1hA^J^GP2Zh7jc0#tW +zV;K{f-a2?ll{FjAo&kmu**_ByBXvrN+H7%pUgwrk*v>}T<%nfg$(O1#f`vAf;$Wwj +zK4OU>ekZ7*cXG`zK^{1Jk?6U1Z!$nXMaDUqNo}Oc<%5yn3pWZ=j1+|nlh9DXMmgJp +zw$>=#X^n__>Lz7RpGg`FbOM{jMF-I&Mx~Gtq{nwcJ*VwE0OFOdSNksknPO9!AjUy9a^u}; +zl{GfA#HVPd@8C*|vf;gcdLXrJL?MukrGr%c^ +z`dR^O=T^5*G@CU0fpX=d2?dv}l#Z}rvrURI+yrK9#ndWZg69>4-LW#tEa5!`s{Zgq +z8R@zhQOojaXAAXjJW6}a5>uV1LhgG$u5JQ_EBF0C=A-S5S2BuoH^CBy68!ST^VMKp +z5t!x0xnCI*Lk$t%?=aM?bAC5Sk&8&Qiu@hZj7DiJ;6#WZd1Z764c#+#;>O(U9%lfW +z>suxqZ)SVz&lYoFmEAcgM7u2vPU$2e-Hjzv>AJy1PeOk$DMk`K`~^i^seLl#HX2s@ +z&vS?_kECyji(-+eKdk1750r)$2U(RhTgkZT@l<$kC`GSck-TzG(h{pKG1aJhxkqgZ +zItykNw;mTU?xiP8Q;PAKW4yNPGkd;&0<^_8y4rHh6AzZ1@@Og1z$t3+RoVK`LOEWpvj)dqZ+bn-ZI_R@g2TDm +zUOXS$8{AioF8c*Kd%YqEKoqkyqA= +z;h>9H=F|lLAffO3sj^3_YLHV~t7o60Afgf+&g?fx9El~tAP}$YS=MFe#gI{HMPF+3A4XgD2y6V7pZ8*{ +zm8;APEKL9wC2F|aO=CXGJo^TSmQpb}X_X3Im%nsfn-Yr)Ip(;&N*#Ay_m3?ila&Xh +zA6V?kP!$WD1kP``H7hg@QY|w7?54~1UuB*oXqD_ePJg`i3GPV0EM`;%joWPh;8C{7 +zYdmIemNAl|da??P+nTE06i%eXK303w@_~!CLz4QEZFdnUm~0^2U*Dh4GePdBsTQhV +zsihVr6*e(LETK(_Y=c5vXJenfn3=4BLe-LG|E6?ccR#tlx)pG=|6cC;SaBt^!li5R +zcPgX&c2MsDL}~N-O+3=a0$|oiwZm$c)<&SyI4_0A@|JEcP=7FY3^?#Of0zNSfD^&A$%$p{mSW|9&i*6 +zj(_qDpxvBQ=^ptttH-vj$9~Va*80<33lpe5w3*6)d5BABGb>2&T7!J8KM%t$O}n*W +zJo+7yk8gR<_bN{XJ|u{lon5UfZc>HMFjulERk&KL*jqG{qadfz)xhuQcg|aymb_Y? +zVYhel3JJX|M+K*)DQMX1IZ`*_*vfscZkpLiT)9gL=cKs}uA(KzRP<4d8#RxOLcE#D +zJP9@OB>kt#JaeOXaqm4Kc^GYiehxcy4(-(f*^`-a9<3OAl0lXjMU1hK=(Co4O{$8%UM|E#&*;l(B?QsiT24bqlr*B{Z7V`VuFjMMHlGAysOT^==1z=5qZQ_2R +z-1qLb)#p6A6j}B#jg`CWg~=F5uJg4=mk4 +zMbEFlbNEc>OXUCT5piF*6@<3E+@D1YQ`=LOmdxBa$alJ^s;X9Vnwl%91RCi4CyD~~ +zEfY~;r~^+zF4y_)m=yu>0s3+B%|pI?8RS^ct^$kP#XRzE>S#R+#~GhIc~p)Cii4cW +z9H*m(D~n23;e5HIw0*7&$Qv-cSkS?#GB%E4^9a4Zdg>n0VB=s|P>wkUFR@1Py;++p +zX;6LW6tT+67ZSct6f1(Z{;9<&8!$Q%dsr@?heJCLyu$kE{QNwMcpba!S7M2R5q^_F +z1m`x@%z~KAD3f^-kF`7BW3BU>kYEeLw+hLBNDUxD$O}Z7ySX3c +zb)wd!i4k24wW1_C2@tbyw%f-8qhJmP`&caiZ`w$^LAjZS5Sn#m^9yX>OCkC~g$Cc7>RooBAs^cU +zIlTk#)OXQ82-Til1rliQ85sNCA>X3OzZ4b&8XPSua_&2S?i?lbG}vKCBGdB|nXS>g +zJ0*+o--w^syM8BpvQ@ycNTP2WG0U^*#8-MC0N=cB;m&`}!LXiv%vI8XM1O%D865l( +z{g6XRuw=jeOMjz9WK|@yzj!yA9i}KA0|SHG1bi12L)S{x7e=_kAN~FN)m7xbSP^arS9Rd{|t-bdQUEl`8{54zNMvQ +zmVu~1GPeH>P7JxwZV*CX5cIQzmo3E{siDMziZ%E7Tl9Q4KN4`#}D9_*vX?k}pO!=)gn7_4Bb4bJT +zqDaOnV(7U1_j;to@cwADU9mBc-@BdBUmAHSzyI{7YGVPi_y~b*r-e;$%CQnDe?9;8 +zfw~{4mSb>(|FgeRQE<@@i1>JZxfuACaFBgBIQO3(xsqo~Se?tnEhWOPgi|!6k69%H +zBXMEw6q@;gX1q%5b}P&*(QhwjwHm7%kJPg>aV1XSsKm6t<)rE6*j;x$hUQ|hu`kT) +zV+}ADC0AEh_W-HRr1Y}-%^FExK~@Y^t(ANZuuEJ`p#^k<`-MWnN77L2@X=9jV+>R; +zXOQ`#-WMm65hugihkOgXY4OID(WpNU{=B$ZDs8X^hCKKCdranviTkKK>$2J_;-Ga6 +z>WBEX7GD$0K(CoP7J96eYCwj_U5&HrOXJSWm=N0MQ^#7X5>(8zV6XiWLH3_ZhnV9@qF1Eb95#jw+CTK +zcnC_X6?w!ouwb8!t?ZeXbU*`_*tn=L1`tKaPq~o#XH-LT(pdaeEr(+5o7_BF^YP^9 +z=s=xqrRelm)Z^rj$VCV;RnXkG!NaMn=)gAL=kN77LMYwzIqFtY;-;Q!9U{UKkl*Z; +zxmwdAck=k)YYlsT2UM!0spVa*x7IFL)Qt{!?hIJJcZxQPc`eiw~~Oj@Tz_oM0xtx3Lb{5kxu +zyBD?uz>WN#g_E*U&crG80;MCX-DnFuJuz_nIeOw6$6c?&s+F|L2zU?5G!ekeS!llo +zFPgW-3Pcj`}O?5W?ab_h%Gy97f=v~(o +zy&qFFhNcAIGR5-l!~O!ti+&6tBv?y$VCZ!G*COZC^Rd=v3DD{VK&YZV`0rM0q-=5@nOTtcx@ +z-`GfyVTF_)=xoTY-xG)BHAl-#;@k>0Kap5G)B~X77JGh`U;(W#+Xleny2|+?3X~v9 +z@j4(Oa(GxV=hv@n1U4Y(PY6pg$c&Ot;)efq)~zTw>;uHy`pS!hYaNUHxEYhbgRg4R +z+}+}7o`g)4OPEQ|;tiYeawTA$%HmQyClOH{QqjoI$3uxnpv;6|Hoy*8NC^3e-^$N* +zqqby_w*0S5T>t%`@v?z_`@m;FByBE`COSJ7m_~uq^-Bim*HTzq_chCA9jeHpXN(2n +zwRqW7h)`1w=SY~Q#F+#wWc43wU)ql>D-{W#MMi*+Rc<(sqj$1IsI?*Vo~~JX4iGFY +zSjVn{Ia}(<$;mhGkK6li&$laGUX5+PgyS=U#yks+rN3QUeb1{R0P)Mr;duDNP0Yns +zOl80yG--mz(9cLJmrW%6skc}}J*KYlL*%B2MMfm>8W3{uoeA1tCC=;U0l+}4z>%rz1`1Gu3qlk(DUqGWSub-M#qTbUB+d9M069OLgJ6ct8Id?;aM)g-r9s^V6BrQ}Q;SCiP`udh7DC +zQX$nG;n1i3pom{#4@R?{E?z&>^3sL?I2rH<%HigVl9la73e4N^TR>PE}F +zsi3VDlCxI}2NOm!ndIQSbW~gNZ4rN(jki^a>Fbq! +zqTN5 +zzb`nx8&_h%Jrt7lQxR^o;6yE0jUGfj6BHagGKnEIbC?*Yeh-mN_p6 +zlPomN>R(3=k&0Ki-xElR=54S +ziifTvyozV0-H|T?}miG^F_wtBpw#IDTI~O&zZ=pp6zI7~U;(eX9v~ +z%_Rrklp$gbO-9{o@iq>QY$8+WLWjtqUprlw=!9l&&i<-B;;B?gDuUYF04x={Q|PYo +z11qyPuIW6^msVN_PE8KdAMXa}bHL6LC^fQ9sh369#H1cfF?JZ}v`b#V$&6F1HA?9- +z8rMp!9QAw;KUupJE(75s%Q_j;=twh?gcLwR?pti!=J%3LhEmj*cmxEL#xOjNHpVeK +zJkF%}PF#r=gweO>TUjCt`~eJ7()chG!YE-`x^-8vG;ltjSQ*{>Exm{gthe@Wqr_;) +z0wt5sLc;HhZgRcM=_rjYuGPk6qTcdMHcs}#u#-NnrJ>ijEn2POpi%bVAyH$%NC@JW +z!9x#~LZ0#)=w{X8oW39GR&eJl^`<7%yQQ1IMRYe1(f#2jGXHCzX6=QT%WeN8>DptC +zHdSdtJVzrAI(JAmUV3k0>(|f-Xp$15@*N%7K>n%=8xkhRkB3QAUtf=ah{(e3zoSSq +z_gFfN{zLz`jCqlr&;1O+r(+F_Z0oUu;MXftO1`Y +z9;O;>OCXbj;jbt_S7jVfllzmVYhq*#nMM~j1j#8VFg%#?vdErxSYKI2XR#z#^jrF| +z60VzCe$K!`P7W(fGZ`zDbu=Gj|Fluc!xb3b3?KS{Jm5T)ZILV)F5q8zrZN3x1!?Fl +zj24#65txQAH>pypq52gcF^Lw8LkW1LoMwVHld&c-soCEOJ`7#g5|?z#rkMgkK7BD? +zv5)5fIFMR6Y+7b6;Ou);_P~PlRc2e$)>HPum(WG>M&1%61LbYx=>T1OuOHP=A_2Ml +zUJa0_6*NB&eSM@;e}$dm67YWg_RVCo!)>o6Rkzh4GG20Rk8#RK+5)kj +zy-EvI3s#yE&SmNou7&*UrnmOiQ_-c!M98x?rSX}WW}0I7mNW&~u)Vo_w^FUmMKUp> +z8k)=i)!=z!;!K+sl(Lhz*Vd$PEuCsaMon#-vS>REEy6K+i5a(<$=x(75fa)xG@=%o +zR1GQOG=s!5g(EG{JieFH*|kCh7=CEGG~xLSIY@MDuIiAnc`G2Ge{P@B(m6G +z!ibqfOA9p9!7d%@C@Z6Oj!J3yF%OjokW8F{Y}gut?pbEsRm(4LL??RqN~(!1fsK#O +zx=08kW?ie)L(K_4s$=P~flB)?RT~0m>*m4)K}Eg&^ysOF8lN +zUHK0Q90oI&{$mRN4;~O7eZ2)RYWiOSNUxax118K@axIASH?!$hWNTeE-m< +z9|d2NgO0N~GYHc0yR$}HApgS_*(Si(CRarIKe5r*$mNd^46r(X7=_aLFxEIYsbgvH +znrzh|J#4IY*379ZTcw$}tG6{QE7PnE4Rz`3%NtHKG_U~aaSk@Sx>k@6ej8+~c|Yc1 +zO&By$u_ANpr;D`5D&%W#Fdl9`BhvdZ5`UZwLv{1Hpy9lA>ut_To&@^KV8eBInUrO5 +zh52}zCbS}L24&AucCm_(e?;?E_ef|R)nd$k+BOlW94v|UU~blRLjQ0ZP-4r2%|3Mn +z>o)c|#p9v2Mo^cLhvg|xC^b2rL@3y2qYKOs?@M}`_`2q==9(4=kTk_PZBIhX-PBrZ +zr~4n>by9I>XJ-@K+>o8|G;Pd^cW)?r)m~#|TJhd}QmeX{jlF$FjtCHM4zkU<60>Zs +z%Hys(I^Fbs!^Li)<*(mdMDF~twQ_bC9DMnUdoO<&F-3^A3(9GW4BH?t7v#5rXa(*RMsaFXpk@rOtgnql#(8*wa~=>H&U=;wN0Q<% +z=~0Qf+>{j>5oC?u{)Ajpd<^k1GgPzB2_X=HLz81#(ra*Wz}OO-za_H(wqrv+ +zz0y`v?a{P}lFJz=@BUy(A)pd~b{ghG$JJ7r@AlNxR+>kt6nYMil7}v99Ja?<@UZ3T +zeP1&kMRSM{5+R84Gc9j#ct$;ly+^es_n)lXhG>_EcB%`8iYCWLpCv8)3~8MaxHrGc +zWH36`!Flt6p(JJsBEPqrE&gHZ?iZtxyx?@fgPx*GS)go(Nf7>mW01|;SB);nF)3s-o4wF7D!)tc}@L$K1~NQb +z#Yr2Tunx+&wm$nlh2CtbCg8*b5`pf^Y+pukoQ>UqK#>9GQek~Po6Bh899xq^a4oaN +z9sDuzXNM=T^ExFYu?oyxI-}8y%D;slDQ*$`e5+$KKq!pF-*Qc6*L_WdXk^K$IEown +zc`-GIjJQlcjeh%cL}$EWcnajL%v-BuW@70M(BzzY-<$NJlWQg2rNIpwvZO(rx6c;G +z_UBD)7Cj+GP^Rw?)N_Nikx*qcIPWa%MBy?TL-6TWG;|5d3z|f%7il*;Ac9f={o-sOWXfH2ow& +z+F%t%kw65bbTBi=kaCFWiK~y^%2iyKohma@H`Ql2SmxhqN|;zqx3*C&8_FG(8wPqn +z80VlP%Gr)DvZLLlMf_OsXDo*4wm909tv4{~9yF8NS%e&sJ#dPsVWzk;(a?)XK|KjU +zmKml2h#A~>%-bFxM<7`wSX>`I?z8$Ca++fy%HqqV=8QYYD~bl^Hz_tBVxFF`f!?T6 +z!OC4>a={OOkbTFV#ew8k2GrG${kNo(rcXXA_NWUqI*@?8f!7jnu3$bUg%u}bhY5Q));;cCAc0gS +zHeTk{K!dAfJ6}@_zTLUn#qe2z2>ZdYkePg(!A+9v>R>`9$hU~PuED*xe7hANwC~xc +zzMc7YMmZr7Iy0P~w;nbL>dml8nV{FL;+xs}qjWkGV5~K1I6DPEC&#K9z5E?@9vBT9 +zvo#L&#*9687;Wd0D#-M4&3F8(7sFq)qrj$;8%`og3#@6+hSB^|^UtXtP#SOBvdY^G +znH{rdVJq%P=QxzF3KPx3etK`XD%|1rVH#OZ35YdYtyAh8`vg5MWd_yI4)jPAmo4j_!3e<(RzCocf`Y+$BAs988hq->eMY}S?z>|#t_c*3a#|wBAi{r! +z{dW0rO)!J3t~1!Um(@E{ATxo*eW!!k$}$1~;aQ@PPH8`A%_SDxVmA)U!Hw)$KXA7$ +zqdYbaY15D(b-OI$URl0+-TYf+!wm}Fwiu|ApRr6t288`7`y!ZbjuZgH`OF0cwYAez +zqSFt2_caUMO6L4Xk>1Be-C +zNHX4bgVd8eU&h^$7@$FnL%%Qp$e+fZ(4dAotr#y7!RrZ>u)-F!F&*jOE8kA5rqU|| +zkg!kLmDxaol3FWgZ=YGJwHYE#cf7j}8z24RotEJKC)?r64}@x}^89m-1nf0~ +z*_bz@JP+Ml3hd*HWuOR@sNVh74L-Sw?LaYKwKo+rvy}#|aFc!~jT1o|KFR)cI+)Bn +z7Gg?S>|0zfR!%gT?WBBV*!!8j6W>|lJse7F&5>m#;ooWbRQhP@izf8nK?3n;AClTI +z6#M340iQgXluMzeY19}<(0FQ=O$wq@ql-?Y9&<2A-S>4Nw#z1Z-(eOaL`iCMI&1sAHP4i1wfU%}{TH10ti=qYU +zDz0-eM;$$6p`VP-jrsMCM}MB&A!(m3WE#f9F_{oZS)?8^0-?^g11w23S(X*2v9^k* +zKU)$N`g+?WLff<~UDFNP<{vgF`ivNrY!#|!D3|%nvN;axyiKQdEH}n|UAvW!JH2@P +z6TzqIA6}zL<{b4pMQp)4ffz(REKD*y3@}3^xF7ui{>6upo0Tm&dOIrt&>JXx_VQrn +z?-nhZdK!u;m!%$urT+S%i$tA>aj?l1`%j#jH%{|kdYyAos^NAM25jH<6TePW$nes= +z1!HeZ;$v}XEv4u4(RnINU~U}A*?wwCqU9m|k--nxsx^vf5AeRn$pVh?0Mnuc`C!uLu2;Vg{7)wfw`U +zX;*Wa;BHUq-TwcZ=lb=LAJ!W;9=uX-aQwln)6svvPf%SQ<1JdhQIPpzpQJ_KDid+% +z!(xv_|7G`-+M9p4uk#~(Mx)cG<|di_EPs|%wf~Qb+;nQM%q9N4&z7FNB6Z+G+^+MR +zj)|=QD8BER{dSeRdtd$LH*1N?VC!qI+*y}-;)|d!tvt|0N +zm5Vlct%>!zH1~C#{PXnRXO%R17-p8ep7o3QUvcWms)tYH$`9TvKIF>&@BVzZ?VI=h +zpErH+ydwvGOs@R*Hs)&kpXVngrCvTXb;0-d@xj~oPM7_l|L;HY`3dlY6p$IBU;poR +XXyugpZ1#qMfq}u()z4*}Q$iB}^Bg|U literal 0 HcmV?d00001 diff --git a/patches/server/1041-Add-startup-flag-to-disable-gamerule-limits.patch b/patches/server/1041-Add-startup-flag-to-disable-gamerule-limits.patch new file mode 100644 index 000000000000..426dd76265f1 --- /dev/null +++ b/patches/server/1041-Add-startup-flag-to-disable-gamerule-limits.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Fri, 25 Oct 2024 14:20:40 -0700 +Subject: [PATCH] Add startup flag to disable gamerule limits + +-DPaper.DisableGameRuleLimits=true will disable gamerule limits + +diff --git a/src/main/java/net/minecraft/world/level/GameRules.java b/src/main/java/net/minecraft/world/level/GameRules.java +index 4ae47c2c5a6bcfbf932d000a80974463e2d3818d..467696a78791d65a66eb380e97d33123a5a12e61 100644 +--- a/src/main/java/net/minecraft/world/level/GameRules.java ++++ b/src/main/java/net/minecraft/world/level/GameRules.java +@@ -36,6 +36,14 @@ import org.slf4j.Logger; + + public class GameRules { + ++ // Paper start - allow disabling gamerule limits ++ private static final boolean DISABLE_LIMITS = Boolean.getBoolean("Paper.DisableGameRuleLimits"); ++ ++ private static int limit(final int limit, final int unlimited) { ++ return DISABLE_LIMITS ? unlimited : limit; ++ } ++ // Paper end - allow disabling gamerule limits ++ + public static final int DEFAULT_RANDOM_TICK_SPEED = 3; + static final Logger LOGGER = LogUtils.getLogger(); + private static final Map, GameRules.Type> GAME_RULE_TYPES = Maps.newTreeMap(Comparator.comparing((gamerules_gamerulekey) -> { +@@ -120,9 +128,9 @@ public class GameRules { + public static final GameRules.Key RULE_GLOBAL_SOUND_EVENTS = GameRules.register("globalSoundEvents", GameRules.Category.MISC, GameRules.BooleanValue.create(true)); + public static final GameRules.Key RULE_DO_VINES_SPREAD = GameRules.register("doVinesSpread", GameRules.Category.UPDATES, GameRules.BooleanValue.create(true)); + public static final GameRules.Key RULE_ENDER_PEARLS_VANISH_ON_DEATH = GameRules.register("enderPearlsVanishOnDeath", GameRules.Category.PLAYER, GameRules.BooleanValue.create(true)); +- public static final GameRules.Key RULE_MINECART_MAX_SPEED = GameRules.register("minecartMaxSpeed", GameRules.Category.MISC, GameRules.IntegerValue.create(8, 1, 1000, FeatureFlagSet.of(FeatureFlags.MINECART_IMPROVEMENTS), (minecraftserver, gamerules_gameruleint) -> { ++ public static final GameRules.Key RULE_MINECART_MAX_SPEED = GameRules.register("minecartMaxSpeed", GameRules.Category.MISC, GameRules.IntegerValue.create(8, 1, limit(1000, Integer.MAX_VALUE), FeatureFlagSet.of(FeatureFlags.MINECART_IMPROVEMENTS), (minecraftserver, gamerules_gameruleint) -> { // Paper - allow disabling gamerule limits + })); +- public static final GameRules.Key RULE_SPAWN_CHUNK_RADIUS = GameRules.register("spawnChunkRadius", GameRules.Category.MISC, GameRules.IntegerValue.create(2, 0, 32, FeatureFlagSet.of(), (minecraftserver, gamerules_gameruleint) -> { ++ public static final GameRules.Key RULE_SPAWN_CHUNK_RADIUS = GameRules.register("spawnChunkRadius", GameRules.Category.MISC, GameRules.IntegerValue.create(2, 0, limit(32, Integer.MAX_VALUE), FeatureFlagSet.of(), (minecraftserver, gamerules_gameruleint) -> { // Paper - allow disabling gamerule limits + ServerLevel worldserver = minecraftserver; // CraftBukkit - per-world + + worldserver.setDefaultSpawnPos(worldserver.getSharedSpawnPos(), worldserver.getSharedSpawnAngle()); From be2edeac2b42ab3d76d9462cd7fab584e13dee9c Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 25 Oct 2024 15:04:29 -0700 Subject: [PATCH 085/119] Fix boats/minecarts not dropping when destroyed Diff to clone the item was lost, which meant that the spawned item was air. --- .../0344-Fix-item-duplication-and-teleport-issues.patch | 5 +++-- ...9-Ensure-Entity-position-and-AABB-are-never-invalid.patch | 2 +- ...ix-Entity-Teleportation-and-cancel-velocity-if-tele.patch | 2 +- ...xpose-the-Entity-Counter-to-allow-plugins-to-use-va.patch | 2 +- patches/server/0410-Entity-isTicking.patch | 2 +- .../0435-Climbing-should-not-bypass-cramming-gamerule.patch | 2 +- patches/server/0446-MC-4-Fix-item-position-desync.patch | 2 +- ...Collision-option-for-requiring-a-player-participant.patch | 2 +- patches/server/0477-Expand-EntityUnleashEvent.patch | 2 +- .../server/0571-Optimize-indirect-passenger-iteration.patch | 2 +- patches/server/0578-Add-back-EntityPortalExitEvent.patch | 2 +- patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch | 2 +- .../server/0616-Update-head-rotation-in-missing-places.patch | 2 +- .../0622-don-t-attempt-to-teleport-dead-entities.patch | 2 +- .../0632-Forward-CraftEntity-in-teleport-command.patch | 2 +- patches/server/0651-Freeze-Tick-Lock-API.patch | 2 +- ...Ensure-entity-passenger-world-matches-ridden-entity.patch | 2 +- .../0702-Prevent-entity-loading-causing-async-lookups.patch | 2 +- .../0714-Add-various-missing-EntityDropItemEvent-calls.patch | 2 +- ...ix-EntityCombustEvent-cancellation-cant-fully-preve.patch | 2 +- patches/server/0768-Player-Entity-Tracking-Events.patch | 2 +- patches/server/0775-Improve-PortalEvents.patch | 2 +- ...xpose-pre-collision-moving-velocity-to-VehicleBlock.patch | 2 +- .../0810-Refresh-ProjectileSource-for-projectiles.patch | 2 +- .../0824-Don-t-load-chunks-for-supporting-block-checks.patch | 2 +- .../server/0836-Folia-scheduler-and-owned-region-API.patch | 2 +- patches/server/0858-Expand-Pose-API.patch | 2 +- patches/server/0865-Fix-slot-desync.patch | 2 +- .../server/0899-Don-t-fire-sync-events-during-worldgen.patch | 2 +- .../server/0902-Restore-vanilla-entity-drops-behavior.patch | 4 ++-- patches/server/0934-Fix-DamageSource-API.patch | 2 +- patches/server/0978-Entity-Activation-Range-2.0.patch | 2 +- .../server/0981-Optimize-Collision-to-not-load-chunks.patch | 2 +- patches/server/0992-Properly-resend-entities.patch | 2 +- patches/server/1032-Void-damage-configuration-API.patch | 2 +- patches/server/1038-Moonrise-optimisation-patches.patch | 2 +- 36 files changed, 39 insertions(+), 38 deletions(-) diff --git a/patches/server/0344-Fix-item-duplication-and-teleport-issues.patch b/patches/server/0344-Fix-item-duplication-and-teleport-issues.patch index 128a755a9584..77d7c3a5b207 100644 --- a/patches/server/0344-Fix-item-duplication-and-teleport-issues.patch +++ b/patches/server/0344-Fix-item-duplication-and-teleport-issues.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 5b8e264098f1b713de15f714bae59d3efda365cf..6f1e09087cf2d8dbb61882473b220100e3b0369a 100644 +index 5b8e264098f1b713de15f714bae59d3efda365cf..d5f96ed753e8298085e40c6181285cd6ea838ca2 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2630,11 +2630,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -28,7 +28,8 @@ index 5b8e264098f1b713de15f714bae59d3efda365cf..6f1e09087cf2d8dbb61882473b220100 return null; } // CraftBukkit end - ItemEntity entityitem = new ItemEntity(world, this.getX(), this.getY() + (double) yOffset, this.getZ(), stack); +- ItemEntity entityitem = new ItemEntity(world, this.getX(), this.getY() + (double) yOffset, this.getZ(), stack); ++ ItemEntity entityitem = new ItemEntity(world, this.getX(), this.getY() + (double) yOffset, this.getZ(), stack.copy()); // Paper - copy so we can destroy original + stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe entityitem.setDefaultPickUpDelay(); diff --git a/patches/server/0369-Ensure-Entity-position-and-AABB-are-never-invalid.patch b/patches/server/0369-Ensure-Entity-position-and-AABB-are-never-invalid.patch index acac658b4dff..09ccee390d5d 100644 --- a/patches/server/0369-Ensure-Entity-position-and-AABB-are-never-invalid.patch +++ b/patches/server/0369-Ensure-Entity-position-and-AABB-are-never-invalid.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Ensure Entity position and AABB are never invalid Co-authored-by: Spottedleaf diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 6f1e09087cf2d8dbb61882473b220100e3b0369a..a3e096525f89b7b66efa7987f9744618074ca38a 100644 +index d5f96ed753e8298085e40c6181285cd6ea838ca2..8993c16254ac05d509bd8ac1cd21e7cc7c4097b8 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -677,8 +677,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch b/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch index 6b069e9a8cd8..b792cb8eef18 100644 --- a/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch +++ b/patches/server/0404-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch @@ -22,7 +22,7 @@ index 49039d929681891beb76b8c7f6e6d8bb614a7bf0..b634a90e87f52c79b74c256c13b659b5 this.lastGoodY = this.awaitingPositionFromClient.y; this.lastGoodZ = this.awaitingPositionFromClient.z; diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index a3e096525f89b7b66efa7987f9744618074ca38a..9e4483d31330dfe82fd794c9cfb8d2aa318a39ea 100644 +index 8993c16254ac05d509bd8ac1cd21e7cc7c4097b8..2c9e57436469f94beb45f656a1df71aba7b1e408 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -179,6 +179,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0408-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch b/patches/server/0408-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch index 3dec9f876b2f..f7644c3d3711 100644 --- a/patches/server/0408-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch +++ b/patches/server/0408-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Expose the Entity Counter to allow plugins to use valid and diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 9e4483d31330dfe82fd794c9cfb8d2aa318a39ea..b55ca652e0828bc34848ad4f1ebb9001832550dc 100644 +index 2c9e57436469f94beb45f656a1df71aba7b1e408..c3e28cc070993be5afe9323c2c2d54ffc81d82f3 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -4704,4 +4704,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0410-Entity-isTicking.patch b/patches/server/0410-Entity-isTicking.patch index d4311d3a19b8..ce1685263561 100644 --- a/patches/server/0410-Entity-isTicking.patch +++ b/patches/server/0410-Entity-isTicking.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Entity#isTicking diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index b55ca652e0828bc34848ad4f1ebb9001832550dc..8cb02a0aeab64e0333c61aa3b30685ad1a169c48 100644 +index c3e28cc070993be5afe9323c2c2d54ffc81d82f3..6cefe8e0de375d3b192cc8be2b553a2dcbe098f5 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -4709,5 +4709,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0435-Climbing-should-not-bypass-cramming-gamerule.patch b/patches/server/0435-Climbing-should-not-bypass-cramming-gamerule.patch index fec776eb5759..cd37306a9235 100644 --- a/patches/server/0435-Climbing-should-not-bypass-cramming-gamerule.patch +++ b/patches/server/0435-Climbing-should-not-bypass-cramming-gamerule.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Climbing should not bypass cramming gamerule diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 8cb02a0aeab64e0333c61aa3b30685ad1a169c48..2e9a836f16eace80b010d5a0421901f7a1af8622 100644 +index 6cefe8e0de375d3b192cc8be2b553a2dcbe098f5..7feed6383fdc367796ccb943bd086814ec989e6d 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2195,6 +2195,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0446-MC-4-Fix-item-position-desync.patch b/patches/server/0446-MC-4-Fix-item-position-desync.patch index 93bbd49bf563..f4858b59c3e8 100644 --- a/patches/server/0446-MC-4-Fix-item-position-desync.patch +++ b/patches/server/0446-MC-4-Fix-item-position-desync.patch @@ -28,7 +28,7 @@ index 488ebd443903af812913437f1ade3002093f2470..a043ac10834562d357ef0b5aded2e916 public Vec3 decode(long x, long y, long z) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 2e9a836f16eace80b010d5a0421901f7a1af8622..be547b0ef3b91da97fbc270cc00d922ba9c5896e 100644 +index 7feed6383fdc367796ccb943bd086814ec989e6d..7c07ffaabce7a3964114b0859ad0028d52c662cc 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -4449,6 +4449,16 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0469-Collision-option-for-requiring-a-player-participant.patch b/patches/server/0469-Collision-option-for-requiring-a-player-participant.patch index a3eef4b0344f..f939c99a2459 100644 --- a/patches/server/0469-Collision-option-for-requiring-a-player-participant.patch +++ b/patches/server/0469-Collision-option-for-requiring-a-player-participant.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Collision option for requiring a player participant diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index be547b0ef3b91da97fbc270cc00d922ba9c5896e..07aff05e2e8cd36ebb6b9fb9d2f19b95c5f9bfc4 100644 +index 7c07ffaabce7a3964114b0859ad0028d52c662cc..0d10abc918e31bf8a529706b3350c80dec11b313 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2024,6 +2024,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0477-Expand-EntityUnleashEvent.patch b/patches/server/0477-Expand-EntityUnleashEvent.patch index 09c4e7f7eb73..214eb8dd8ceb 100644 --- a/patches/server/0477-Expand-EntityUnleashEvent.patch +++ b/patches/server/0477-Expand-EntityUnleashEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Expand EntityUnleashEvent diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 07aff05e2e8cd36ebb6b9fb9d2f19b95c5f9bfc4..bb2cfec32b63d3786f9ec255d4beef7065245cae 100644 +index 0d10abc918e31bf8a529706b3350c80dec11b313..3479b7c89741ba93e49e7e51fe4b45bb14fbc419 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2689,12 +2689,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0571-Optimize-indirect-passenger-iteration.patch b/patches/server/0571-Optimize-indirect-passenger-iteration.patch index ea5798ac84d3..dcb94ae6027f 100644 --- a/patches/server/0571-Optimize-indirect-passenger-iteration.patch +++ b/patches/server/0571-Optimize-indirect-passenger-iteration.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Optimize indirect passenger iteration diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index bb2cfec32b63d3786f9ec255d4beef7065245cae..674df993333ddee13415a4379b81dadc68489af7 100644 +index 3479b7c89741ba93e49e7e51fe4b45bb14fbc419..fe9cdd104d6203233a90068b55e0876be4964afe 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -4087,20 +4087,34 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0578-Add-back-EntityPortalExitEvent.patch b/patches/server/0578-Add-back-EntityPortalExitEvent.patch index c739f7010ebc..2ddd256c17c9 100644 --- a/patches/server/0578-Add-back-EntityPortalExitEvent.patch +++ b/patches/server/0578-Add-back-EntityPortalExitEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add back EntityPortalExitEvent diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 674df993333ddee13415a4379b81dadc68489af7..cb6a167ed778073be9f9e1f2eb27b46547b0a3ce 100644 +index fe9cdd104d6203233a90068b55e0876be4964afe..8dc2684a748e19e14c3efedf58be5efba99a45b4 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -3491,7 +3491,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch b/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch index 3464fbf215c8..5a6f0f60003a 100644 --- a/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch +++ b/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Add Raw Byte Entity Serialization public net.minecraft.world.entity.Entity setLevel(Lnet/minecraft/world/level/Level;)V diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index cb6a167ed778073be9f9e1f2eb27b46547b0a3ce..3bac521f0be372198c8b83d514f3d14a041b76cd 100644 +index 8dc2684a748e19e14c3efedf58be5efba99a45b4..11b3a0ece27cb2c01b908a9ac0c3d75f407f5ed0 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2260,6 +2260,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0616-Update-head-rotation-in-missing-places.patch b/patches/server/0616-Update-head-rotation-in-missing-places.patch index 379a0515459e..c1f529129db3 100644 --- a/patches/server/0616-Update-head-rotation-in-missing-places.patch +++ b/patches/server/0616-Update-head-rotation-in-missing-places.patch @@ -8,7 +8,7 @@ This is because bukkit uses a separate head rotation field for yaw. This issue only applies to players. diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 3bac521f0be372198c8b83d514f3d14a041b76cd..366c3165783d3856d9f47f0dd4a594016d9f41ed 100644 +index 11b3a0ece27cb2c01b908a9ac0c3d75f407f5ed0..7b01d1cd5db771a1b6ee030664070ffb75579a4c 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -1914,6 +1914,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0622-don-t-attempt-to-teleport-dead-entities.patch b/patches/server/0622-don-t-attempt-to-teleport-dead-entities.patch index cefb2c7fc0f0..89c8f26c2c18 100644 --- a/patches/server/0622-don-t-attempt-to-teleport-dead-entities.patch +++ b/patches/server/0622-don-t-attempt-to-teleport-dead-entities.patch @@ -5,7 +5,7 @@ Subject: [PATCH] don't attempt to teleport dead entities diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 366c3165783d3856d9f47f0dd4a594016d9f41ed..8b5dc4b3ddb89fcc286c432400e3bc94b8787e4c 100644 +index 7b01d1cd5db771a1b6ee030664070ffb75579a4c..34cbb7c48535da774527b40f2e99f6f1d31c377d 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -713,7 +713,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0632-Forward-CraftEntity-in-teleport-command.patch b/patches/server/0632-Forward-CraftEntity-in-teleport-command.patch index 1af3ec979c6b..908c4651291b 100644 --- a/patches/server/0632-Forward-CraftEntity-in-teleport-command.patch +++ b/patches/server/0632-Forward-CraftEntity-in-teleport-command.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Forward CraftEntity in teleport command diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 8b5dc4b3ddb89fcc286c432400e3bc94b8787e4c..ef923b1cdbe6276d6dc9776bd9e5a508bd021fc0 100644 +index 34cbb7c48535da774527b40f2e99f6f1d31c377d..3df8cfccba9bc4420b37dcbdfc4a12c720b51205 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -3480,6 +3480,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0651-Freeze-Tick-Lock-API.patch b/patches/server/0651-Freeze-Tick-Lock-API.patch index 76a992877a6b..0244ffe42018 100644 --- a/patches/server/0651-Freeze-Tick-Lock-API.patch +++ b/patches/server/0651-Freeze-Tick-Lock-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Freeze Tick Lock API diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index ef923b1cdbe6276d6dc9776bd9e5a508bd021fc0..681295efe26a75af61d9ac311e002dfb26ffd8c6 100644 +index 3df8cfccba9bc4420b37dcbdfc4a12c720b51205..4f9ebf7a577223d85ceaad0babd2d0b4f492b6df 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -414,6 +414,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0681-Ensure-entity-passenger-world-matches-ridden-entity.patch b/patches/server/0681-Ensure-entity-passenger-world-matches-ridden-entity.patch index 6a4d8ee24859..62372a6087fc 100644 --- a/patches/server/0681-Ensure-entity-passenger-world-matches-ridden-entity.patch +++ b/patches/server/0681-Ensure-entity-passenger-world-matches-ridden-entity.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Ensure entity passenger world matches ridden entity Bad plugins doing this would cause some obvious problems... diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 681295efe26a75af61d9ac311e002dfb26ffd8c6..e1da49ec70f03940ce7c0fa23bcbc5cfb2494fc6 100644 +index 4f9ebf7a577223d85ceaad0babd2d0b4f492b6df..a4a07dc11edf3738698deed929cc224ff7114684 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2802,7 +2802,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0702-Prevent-entity-loading-causing-async-lookups.patch b/patches/server/0702-Prevent-entity-loading-causing-async-lookups.patch index ee2ca735fdee..97d528c05ac1 100644 --- a/patches/server/0702-Prevent-entity-loading-causing-async-lookups.patch +++ b/patches/server/0702-Prevent-entity-loading-causing-async-lookups.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Prevent entity loading causing async lookups diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index e1da49ec70f03940ce7c0fa23bcbc5cfb2494fc6..37111113f6ab6d77c558b10c4162758135db99b0 100644 +index a4a07dc11edf3738698deed929cc224ff7114684..73428cefa737e430c3c8c0d59e1fa763114b8c5a 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -724,6 +724,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch b/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch index 410a98a9238c..8e1fc7a091ae 100644 --- a/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch +++ b/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add various missing EntityDropItemEvent calls diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 37111113f6ab6d77c558b10c4162758135db99b0..911b6391455402922e8bd52cfe9e5694231c81c3 100644 +index 73428cefa737e430c3c8c0d59e1fa763114b8c5a..619879bc0a05e16d450b4f7bb766b371e986193c 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2672,6 +2672,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0755-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch b/patches/server/0755-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch index ff618c759549..ab6fac6da32f 100644 --- a/patches/server/0755-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch +++ b/patches/server/0755-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Fix EntityCombustEvent cancellation cant fully prevent diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 911b6391455402922e8bd52cfe9e5694231c81c3..31cb6c4357afc934a5e6e1a7a9222ac54175459d 100644 +index 619879bc0a05e16d450b4f7bb766b371e986193c..8aabd17178543eab0724a05226e4741ead85ea87 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -3320,6 +3320,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0768-Player-Entity-Tracking-Events.patch b/patches/server/0768-Player-Entity-Tracking-Events.patch index 3cf77bc532c2..e3837eb40f7f 100644 --- a/patches/server/0768-Player-Entity-Tracking-Events.patch +++ b/patches/server/0768-Player-Entity-Tracking-Events.patch @@ -21,7 +21,7 @@ index 3f3124bbb5077a18c3d3afac7748a47e84b8fe35..7810df9c5045a78c2731ee416366da4f } else if (this.seenBy.remove(player.connection)) { this.serverEntity.removePairing(player); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 31cb6c4357afc934a5e6e1a7a9222ac54175459d..1f8362f0aeb03921a6876abbc6f83d8c3464bd6a 100644 +index 8aabd17178543eab0724a05226e4741ead85ea87..47a2cd3ea7c88681929351c6db9090149e2c4f2e 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -4069,7 +4069,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0775-Improve-PortalEvents.patch b/patches/server/0775-Improve-PortalEvents.patch index 6968fe1a3570..a4cf96f882ce 100644 --- a/patches/server/0775-Improve-PortalEvents.patch +++ b/patches/server/0775-Improve-PortalEvents.patch @@ -18,7 +18,7 @@ index 25b1e8bec23465f0e9a17f156bdff7fe716db84c..f05a9fd321a4af28e9771bbf39d73f80 // Paper start - gateway-specific teleport event if (this.portalProcess != null && this.portalProcess.isSamePortal(((net.minecraft.world.level.block.EndGatewayBlock) net.minecraft.world.level.block.Blocks.END_GATEWAY)) && this.serverLevel().getBlockEntity(this.portalProcess.getEntryPosition()) instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity theEndGatewayBlockEntity) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 1f8362f0aeb03921a6876abbc6f83d8c3464bd6a..1d21914ee8193cee8d7a8273f8e6932697b15c3c 100644 +index 47a2cd3ea7c88681929351c6db9090149e2c4f2e..37419819758574631486886307f3133a8a3c1c36 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -3740,7 +3740,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0780-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch b/patches/server/0780-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch index 98305f38a5e3..c08dab2b2da1 100644 --- a/patches/server/0780-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch +++ b/patches/server/0780-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Expose pre-collision moving velocity to diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 1d21914ee8193cee8d7a8273f8e6932697b15c3c..6c4171aa43afa679946c8d8a08445bf5741aba8e 100644 +index 37419819758574631486886307f3133a8a3c1c36..0e52f67f0185cba47838f0a99a97b4d70314c8fa 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -968,6 +968,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0810-Refresh-ProjectileSource-for-projectiles.patch b/patches/server/0810-Refresh-ProjectileSource-for-projectiles.patch index b44397440aec..eee4855e6b1a 100644 --- a/patches/server/0810-Refresh-ProjectileSource-for-projectiles.patch +++ b/patches/server/0810-Refresh-ProjectileSource-for-projectiles.patch @@ -14,7 +14,7 @@ clearing the owner. Co-authored-by: Warrior <50800980+Warriorrrr@users.noreply.github.com> diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 6c4171aa43afa679946c8d8a08445bf5741aba8e..ebd2bf1c16833ea8157bc3e3ef1f5730f646294f 100644 +index 0e52f67f0185cba47838f0a99a97b4d70314c8fa..e126f1d5117a5826c5bfec20719633d7ca5f2870 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -393,6 +393,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0824-Don-t-load-chunks-for-supporting-block-checks.patch b/patches/server/0824-Don-t-load-chunks-for-supporting-block-checks.patch index bcb87c44482a..5f0cc1154678 100644 --- a/patches/server/0824-Don-t-load-chunks-for-supporting-block-checks.patch +++ b/patches/server/0824-Don-t-load-chunks-for-supporting-block-checks.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Don't load chunks for supporting block checks diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index ebd2bf1c16833ea8157bc3e3ef1f5730f646294f..82d7d0038b269ea310571eb1c109ddd2afac39f7 100644 +index e126f1d5117a5826c5bfec20719633d7ca5f2870..3444b1a2da80b85e2b1928d69ff0dd980c5fb34f 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -1228,7 +1228,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0836-Folia-scheduler-and-owned-region-API.patch b/patches/server/0836-Folia-scheduler-and-owned-region-API.patch index 0fc8f21cba8c..6b800bc3f7d5 100644 --- a/patches/server/0836-Folia-scheduler-and-owned-region-API.patch +++ b/patches/server/0836-Folia-scheduler-and-owned-region-API.patch @@ -1185,7 +1185,7 @@ index f9212fc2db00531da1618780e231e8ad21285907..a9063533ea4b2b349d476127b99c8222 this.players.remove(entityplayer); this.playersByName.remove(entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 82d7d0038b269ea310571eb1c109ddd2afac39f7..d8331b2d4ad3ebebb6ecbbf083f3464dad38f623 100644 +index 3444b1a2da80b85e2b1928d69ff0dd980c5fb34f..463dd4f91212318b51174c5d2f4d25ba95c25f50 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -262,10 +262,21 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0858-Expand-Pose-API.patch b/patches/server/0858-Expand-Pose-API.patch index 5fcd53b27b55..47312a863501 100644 --- a/patches/server/0858-Expand-Pose-API.patch +++ b/patches/server/0858-Expand-Pose-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Expand Pose API diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index d8331b2d4ad3ebebb6ecbbf083f3464dad38f623..63e68376d1854f4f7ff1a1d0a11fcec1b8c3b61a 100644 +index 463dd4f91212318b51174c5d2f4d25ba95c25f50..eadea35bcb9c2a8d65789e09dbabe7cb4a126542 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -427,6 +427,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0865-Fix-slot-desync.patch b/patches/server/0865-Fix-slot-desync.patch index 5b0a3d572157..deb1575edeb0 100644 --- a/patches/server/0865-Fix-slot-desync.patch +++ b/patches/server/0865-Fix-slot-desync.patch @@ -40,7 +40,7 @@ index c50c3d11700aadd4c0e7114b4b6d5c5d15a33ac4..af7696900171ea6b7941251046bfc10c if (event.isCancelled()) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 63e68376d1854f4f7ff1a1d0a11fcec1b8c3b61a..e9142414c7d247ae2a27c0bc9ea2be3bb8e3db16 100644 +index eadea35bcb9c2a8d65789e09dbabe7cb4a126542..c0539c8826a60cbe25855319cc174fb1520798c0 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2752,8 +2752,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch b/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch index 75049231278b..389d1d5fde69 100644 --- a/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch +++ b/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch @@ -31,7 +31,7 @@ index 1bacbb0d0bd5198d0f946a959b2335d6fba0ca88..a628da8a0ed7ae2c7b46df3881bd75dc if (entity.valid) { MinecraftServer.LOGGER.error("Attempted Double World add on {}", entity, new Throwable()); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index e9142414c7d247ae2a27c0bc9ea2be3bb8e3db16..1d66c35b1092b8101f0a803d8c087e5a958875b1 100644 +index c0539c8826a60cbe25855319cc174fb1520798c0..02b9d280486a23d8eef650566dfaa10ac0b96c9c 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -631,7 +631,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch b/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch index 74f4887dcee1..bbad1a93c726 100644 --- a/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch +++ b/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch @@ -37,7 +37,7 @@ index 419fcb4cd97cf10a2601e02024b999a51a0ff952..df21cd1bd2a3dda7169edbea18bbfdf0 loot.addAll(this.drops); this.drops.clear(); // SPIGOT-5188: make sure to clear diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 1d66c35b1092b8101f0a803d8c087e5a958875b1..aac1d620bf4cd1f18243f8c53cd32ab16fdeb616 100644 +index 02b9d280486a23d8eef650566dfaa10ac0b96c9c..cdc5ea3dd9559c076049c86a9fdb4e8bf85ff6c0 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2678,19 +2678,45 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -80,7 +80,7 @@ index 1d66c35b1092b8101f0a803d8c087e5a958875b1..aac1d620bf4cd1f18243f8c53cd32ab1 return null; } // CraftBukkit end - ItemEntity entityitem = new ItemEntity(world, this.getX(), this.getY() + (double) yOffset, this.getZ(), stack); + ItemEntity entityitem = new ItemEntity(world, this.getX(), this.getY() + (double) yOffset, this.getZ(), stack.copy()); // Paper - copy so we can destroy original stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe - entityitem.setDefaultPickUpDelay(); diff --git a/patches/server/0934-Fix-DamageSource-API.patch b/patches/server/0934-Fix-DamageSource-API.patch index f42e69a0af12..113d204beef2 100644 --- a/patches/server/0934-Fix-DamageSource-API.patch +++ b/patches/server/0934-Fix-DamageSource-API.patch @@ -84,7 +84,7 @@ index fddbdb7322a2063996a28c5c3d93c265188b1256..be87cb3cfa15a7d889118cdc4b87232e public DamageSource sonicBoom(Entity attacker) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index aac1d620bf4cd1f18243f8c53cd32ab16fdeb616..5c0d64c70a94d20ff0e72aed490ef2973eb7ea74 100644 +index cdc5ea3dd9559c076049c86a9fdb4e8bf85ff6c0..23095ace5a6aa6fd6cc1d5defa4a783ccb637b1d 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -3388,7 +3388,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0978-Entity-Activation-Range-2.0.patch b/patches/server/0978-Entity-Activation-Range-2.0.patch index 65d38450a6a0..6a879cf17f30 100644 --- a/patches/server/0978-Entity-Activation-Range-2.0.patch +++ b/patches/server/0978-Entity-Activation-Range-2.0.patch @@ -105,7 +105,7 @@ index fe610561e6fbb9bc547d27123793395fb0ad80aa..ce5fd95cabadd7c92726c401ae35e05d } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 5c0d64c70a94d20ff0e72aed490ef2973eb7ea74..996506b879c90642eaeac757b31f3e11e798a6b5 100644 +index 23095ace5a6aa6fd6cc1d5defa4a783ccb637b1d..9a37a898eba0cd9ab18ec5ee241cf054c8a71b32 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -420,6 +420,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch b/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch index 0f89ea94cae8..daa6249dc3bf 100644 --- a/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch +++ b/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch @@ -26,7 +26,7 @@ index d12ac1b045c6721255780c5afbbad6e7103629eb..59cc1702079f1d182bdbe8068aa37b5b if (teleporttransition.missingRespawnBlock()) { entityplayer1.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0F)); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 996506b879c90642eaeac757b31f3e11e798a6b5..87136591e2a8421b46e124b0093c56da87aec61b 100644 +index 9a37a898eba0cd9ab18ec5ee241cf054c8a71b32..aa7d3383c773d3537335e449636f33d69cde12bb 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -258,6 +258,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0992-Properly-resend-entities.patch b/patches/server/0992-Properly-resend-entities.patch index dbadaf99bb7b..e7bcb808c95c 100644 --- a/patches/server/0992-Properly-resend-entities.patch +++ b/patches/server/0992-Properly-resend-entities.patch @@ -134,7 +134,7 @@ index 59cc1702079f1d182bdbe8068aa37b5b979aa64d..90c469193ecf9d04dd9e3f1a38157d47 } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 87136591e2a8421b46e124b0093c56da87aec61b..7784ff17216a25c6dbf26648831c04734300dad1 100644 +index aa7d3383c773d3537335e449636f33d69cde12bb..6a0472eaae9ad890692862590b8d23110e48536d 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -598,13 +598,45 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/1032-Void-damage-configuration-API.patch b/patches/server/1032-Void-damage-configuration-API.patch index afa0337fd755..6270e63ff888 100644 --- a/patches/server/1032-Void-damage-configuration-API.patch +++ b/patches/server/1032-Void-damage-configuration-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Void damage configuration API diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 7784ff17216a25c6dbf26648831c04734300dad1..faa239dcb9b7b608911b464c3665c8b064ee6c41 100644 +index 6a0472eaae9ad890692862590b8d23110e48536d..7d16f9935407931823ad3e420f336c7ec69528b2 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -853,8 +853,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/1038-Moonrise-optimisation-patches.patch b/patches/server/1038-Moonrise-optimisation-patches.patch index d39fa0eab58b..06e5e26ee476 100644 --- a/patches/server/1038-Moonrise-optimisation-patches.patch +++ b/patches/server/1038-Moonrise-optimisation-patches.patch @@ -28422,7 +28422,7 @@ index 50040c497a819cd1229042ab3cb057d34a32cacc..1f9c436a632e4f110be61cf76fcfc3b7 + // Paper end - block counting } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index faa239dcb9b7b608911b464c3665c8b064ee6c41..68dec563d9725daa0044781395a840ac5d61b9b5 100644 +index 7d16f9935407931823ad3e420f336c7ec69528b2..b36a915e6d337d7ec3f797bf1773b14c5b231d76 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -175,7 +175,7 @@ import org.bukkit.event.player.PlayerTeleportEvent; From b14d336442a1928e21ad2eb28768bd0632961682 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Fri, 25 Oct 2024 18:13:48 -0700 Subject: [PATCH 086/119] Apply watchdoge patches --- patches/server/0023-Timings-v2.patch | 21 +- ...024-Further-improve-server-tick-loop.patch | 2 +- ...0033-Expose-server-build-information.patch | 4 +- patches/server/0043-Optimize-explosions.patch | 2 +- ...ckPhysicsEvent-if-a-plugin-has-a-lis.patch | 4 +- .../0088-Configurable-Player-Collision.patch | 2 +- ...-possibility-for-getServer-singleton.patch | 4 +- .../0097-Async-GameProfileCache-saving.patch | 2 +- ...le-async-calls-to-restart-the-server.patch | 2 +- ...nt-extended-PaperServerListPingEvent.patch | 4 +- ...dd-Early-Warning-Feature-to-WatchDog.patch | 2 +- ...er-Thread-Pool-and-Thread-Priorities.patch | 2 +- .../0261-Optimize-World-Time-Updates.patch | 4 +- .../0274-Async-command-map-building.patch | 2 +- patches/server/0281-Server-Tick-Events.patch | 6 +- ...-Add-tick-times-API-and-mspt-command.patch | 6 +- .../server/0348-misc-debugging-dumps.patch | 2 +- ...Wait-for-Async-Tasks-during-shutdown.patch | 2 +- ...ld-Difficulty-Remembering-Difficulty.patch | 6 +- .../0403-Cache-block-data-strings.patch | 4 +- ...-non-whitelisted-player-when-white-l.patch | 4 +- ...457-Add-ServerResourcesReloadedEvent.patch | 6 +- patches/server/0480-Add-EntityMoveEvent.patch | 4 +- patches/server/0489-Improve-ServerGUI.patch | 647 +++++++++--------- ...telist-use-configurable-kick-message.patch | 4 +- .../0539-Add-PlayerKickEvent-causes.patch | 4 +- ...vanilla-BiomeProvider-from-WorldInfo.patch | 2 +- ...sks-fairly-for-worlds-while-waiting-.patch | 2 +- ...efault-CustomSpawners-in-custom-worl.patch | 2 +- ...o-worldlist-before-initing-the-world.patch | 2 +- patches/server/0665-Custom-Potion-Mixes.patch | 4 +- ...n-on-world-create-while-being-ticked.patch | 8 +- ...ix-plugin-loggers-on-server-shutdown.patch | 2 +- ...x-premature-player-kicks-on-shutdown.patch | 4 +- ...Folia-scheduler-and-owned-region-API.patch | 4 +- ...ing-message-for-initial-server-start.patch | 2 +- .../0956-Brigadier-based-command-API.patch | 6 +- patches/server/0983-Optimize-Hoppers.patch | 4 +- .../server/1021-Tag-Lifecycle-Events.patch | 4 +- .../1038-Moonrise-optimisation-patches.patch | 4 +- .../1042-Improved-Watchdog-Support.patch} | 90 ++- ...-more-information-in-watchdog-dumps.patch} | 30 +- 42 files changed, 459 insertions(+), 463 deletions(-) rename patches/{unapplied/server/1016-Improved-Watchdog-Support.patch => server/1042-Improved-Watchdog-Support.patch} (88%) rename patches/{unapplied/server/1027-Detail-more-information-in-watchdog-dumps.patch => server/1043-Detail-more-information-in-watchdog-dumps.patch} (92%) diff --git a/patches/server/0023-Timings-v2.patch b/patches/server/0023-Timings-v2.patch index 6ac52a48c75e..92fc3f0b70a3 100644 --- a/patches/server/0023-Timings-v2.patch +++ b/patches/server/0023-Timings-v2.patch @@ -714,7 +714,7 @@ index f7197f1347251a37dd0f6d9ffa2f09bc3a4e1233..d0d36a57ec4896bcb74970f8fb24d8f3 } catch (Exception exception) { if (exception instanceof ReportedException) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 3322865949fe5ddaab2dffc39260b75093f0f204..638d648be24c9907bab6dcb671f42c4cf569e2d7 100644 +index 3322865949fe5ddaab2dffc39260b75093f0f204..a76e2f5d29315d21212ff121f0047bf1140ad5ef 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -203,7 +203,7 @@ import org.bukkit.craftbukkit.Main; @@ -771,16 +771,15 @@ index 3322865949fe5ddaab2dffc39260b75093f0f204..638d648be24c9907bab6dcb671f42c4c }); } finally { this.waitingForNextTick = false; -@@ -1370,7 +1383,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { entityplayer.connection.suspendFlushing(); }); @@ -865,7 +864,7 @@ index 3322865949fe5ddaab2dffc39260b75093f0f204..638d648be24c9907bab6dcb671f42c4c // Send time updates to everyone, it will get the right time from the world the player is in. if (this.tickCount % 20 == 0) { for (int i = 0; i < this.getPlayerList().players.size(); ++i) { -@@ -1533,7 +1555,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { this.stopRecordingMetrics(); -@@ -2624,9 +2626,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop completablefuture = CompletableFuture.supplyAsync(() -> { Stream stream = dataPacks.stream(); // CraftBukkit - decompile error PackRepository resourcepackrepository = this.packRepository; -@@ -2228,6 +2234,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent diff --git a/patches/server/0489-Improve-ServerGUI.patch b/patches/server/0489-Improve-ServerGUI.patch index 48a151cd82f1..8dde1d1a9bc4 100644 --- a/patches/server/0489-Improve-ServerGUI.patch +++ b/patches/server/0489-Improve-ServerGUI.patch @@ -102,330 +102,329 @@ new file mode 100644 index 0000000000000000000000000000000000000000..8b924977b7886df9ab8790b1e4ff9b1c04a2af45 GIT binary patch literal 16900 -zcmaf)RZtymu&!}kXmDLfg1h^|-QC?ixG&s2I0Sch5AG1$U4m2?7EFMOsQs1p)$M^xuU52LS<5tyS|A0z!B~T1;5Y)8HZp -zUh9YE!*I`C!>au1!lt}?^7%)ymXa9F0E8%U6cA@Hs@r2|t2YjT?MMEK&sF!xR;P(1 -zJxFf8OgT_&`%_^18f74-j~9B>_v*F_4QG7P$=~I&{g0k-!dKZ;dhG_Yv84aKQ7`JU -zJ^ehid=1+b=_P#o97{5v??~H!^zyIS&U_=f-+Z&XS28Q#IuJUNE}ApzE+z8$!_(s%I3_!)=jTdGmXzz2p&3&czvSwVkj_PR|SM`xDjT-m<)@wFKtJ!fY -z+A9f&c$RQF&Z%Ui9@S9nRjlxMs@)Z5_OxNu^|5JS^tNFPeEv!Mp+fj^Yc}Scf482J -z_jv2_UYgabd?1AMePOH(|ApkUIjM`|sON7?4||4r>}#l#)Nj}LPNV67U-a5cAqgk9 -z4hA)b1i?G`_{?Is2NgH3=G*Y_oV4G*#y>w?4I7fSpx2h|vD&hsqdFVmofnVkNpM8o -zEDOkF7WVse0CrXXeH^X&Y+X5Ugeg(@8XVq_7ngH%kQ4q8to@(w`VD%+t{VjBlZzMA{89 -z;%$e2aiD==VT$}%!%lBbY3xicyog$jB!Djxd7vpR6bXArR{Oqv(5MfWsJg3Yy -zcUpf*M1f-z9ik)^?H|-}` -zxbJl0Xc<(adaW`;Xc^eA&$kJ4EZWH)dOO+mFzw;MBfNjA5<1ZP>E3RWzD|&L1WdK! -z2k&T-AdM3|);yD$reQ{x9G{_#6R5f}9%tdjf-W#_wS$qa(*X;ot*Gkja`g1Q_eN^= -z`0%;Ho3r-6zU-m(+)f%v8KxzXfn20UBXua$j&hd^L+a{0lv^F@IS92IL#!_sffCl2&zHVp_~j(J1np!W5n69+~xPAJ6}_zBa%4jtFt9W -z{@f*=wRJ|ZitBopGm@A{J`xa&M -z)PY`TF0^X2?f!}827nOWNuI-}Ne-gU_A_rT89Qjihq3d_{Ugx}ge|kRq}v@?<-}sM1htR5<=} -zI1L1)$lG(bP|&c#@>`Np6h0xGHe-S%SWq_O*_rH`M&)M5xj9Un#*HS!PqE5 -zISo-XF(NX8c$<8iK|uH&>qt?Q&-b}D+Tgr7t>MFp&WJTZFnPZ1>|RTVqu7iauEwTX -zVJi3CHpH3>2eq__Ox+k#@Bzl=K|7STdhX7MT{c8Ce71~q9Y&PXH}*iaRuCUgMZj4H -z)QyHub -z_qnc(rzc$MCNk878`Sofx_>n{BwDNL?TS=$RO_S6!R*Ey=`(aG@LbB{HGQ+@MqP=h -zu&0VvO0ab!36xlai&*>Xc+6_xPmdSo9TasQ3?*TY!)%lYzD(AZ0HWie+au=#fiLo& -zU+O6Y`-6UchQAZ*C2TI_f~f(2hrMt6KE)jP36+(ZZfle23Dx>Inkk_7xY0&pkp)+N -z%^^0b-mA7bkD<)a8%J{cvSRJ2S;}#v9g(doR}TQ3QGy%7T$YWkQuW{|T0eu$!D%Gg -zhIpru$xwR_h!F-%c~|@zigH-C2m=8{D8VNnCdFPc6Rfz(8f#dDmuUW@`u=TQn?l6ex-ha;(`` -zrS1uS-(@|j8cS+#fW*WdM9k{Fbp6f|!@JL%Gh}@yEWnTjE-DYfVpx0s5?hF9Qzi@Lf>~6Pm?DX{;HP^Q242(r1D1_=jrbppWF;PQk_!Ls -zS?3Zy6SOYNhA^`C9Gr`$aM+kF+PqIpNc~b)YOTag^;@K{!LHyR#-D?kKh>QZn&JHs -z(S}LQ;l-T8IWrlT$vDeig`Pf3fs);`cyZgTesw;vUk*#=1ZlB5zS``R@)U;`I^|DW -z?`Wu5^KI6hZo2(M-a~zF#>3kiX?zjyY=f@)xk3s24jF8WN!RqnV5qMC{5IS-?p~l` -z*Od<2Atam`NRWyKlq2%T>WdXRFci|p)_QD!{us*BG6#&@1J>-ygf`d(+Yt%AR?$|m -zG2&h}ZNhe;3iL&t-&Bo~bSQvwc_uqFF*q*u<%r&3Io&Jc -z8X3Bs8jXqH@NHmV7BRmCYCHHs=Nrep*-}>qojz9eD&96O%Es8n$%gaSnOL~VE%6i@ -z&N;!@pfy%G7dw?+2y1|uMDE?45uzNTNB_7>aX);UvtG>N2^CK4jXJOIypMJdF8LKU -zTYqIdp7&|wl19M2-A~xsFLDE9e-nocdK3)_YdtcQ)W%k7bx|ihJbIc=Z5ZyZ^yh9L -zz(%H87tSJzNkw!4yq5hajBkYU#kO&cksLk7!K-`GO(iyvT=U{|HBlNQU1VB|)w$-~ -z!`vE~Br`P8J<1%ly9{1OIZc%XlCTOPAdcit!jhpR;%=Zn+J^5sT)?#vtC4a+pY5iB -zJDz5Ru-Z>~+fH$VWPdd~FVQ(AT}O25HPC_wANYArttZij2ISLx>m75xSQO6+R*;0g -zmeuq!90F_}HX%kFZpuj4@q)SDa3k?+Bb2PrSZjTt%acFjLT3$4HPduPZ4Sfv?#~)_ -z*x>rvxpNnXh2P;_1YzBnVcqa9VK{mn1MhEaK>}|FhPXm?dB28(cqh2Ag&XIAnbGh%w38mufD688Vg0{`stk3i+PA1e~X7W%o(N09G -z(V+dK5Ra`6>fQc$6V4g$Mc;jTrbmt|ZcfPDi&luFxnBGk{2GGnMACo~C5VWy9A^BK -z%9O|VK>O{=o7e@%H==p}Gh9?4J3)S(^K@|@-bpGMlMM#a6u}N>;hDZ{$m0w+?{P+i -zv!bb`WN0Gnx5bB0s;!iJeK(?O@&xo_Yr==8dbs9N^gw0u(XKa5#%g4gLt%5d9^x&bUp+ -zI*CuQXb^F)LGcsTq00ke&-aZbA7b?Ow}kNZFJJuWYsoo#JJ -zd^|iHd;0^2Lk8)L=de&2-C9OWIvMMW>WH|w6peAk$qJ4MH%Wu;|h=~A6+4h{@J3knK0*pJ@vag9^60=vvWcI&Lb_(VX2 -zy)N7VOA=(g{REg_f)&_ekDo9i1vl8j0R0zl47}1}4kDqz)m%np1-97YCtxX^_8Eb1U&2>fjdHvFw8)9n=PT=mS{*wNJdpIN5Au>lfU5v4<160teocH-d>QHxOk-7@IW}47m1u$uA~w=(B0jA`kk+l2DCPaOxmP~ndvI$ -zYkm8H%IFn;s^>pUrvz6NLyr<`Ro3Korg8A+&kfO!G6vn2h>XJTf5yvnnk!b`Vn06= -zO|u}x(#U)>eRZq|c{Ep6$&^P+2{n)IUvm+$hJWpRp@dc$Pc5;};;;?#x;>0!Q&lV! -z`h5GsX89Y7O)`a6U8!1!!`XBAGrQC|6pr$y?Yi~{n@H;dTYvsSV}Guzrbl=`^4UoI -z8~S7M#L3iCl4D&LZY7p{pxhZgK`flMwzluNP~zogXL!BoNYnrwRFOn1!FLoBg%hgK -zT2%$)cYHjmbW$l?<>3q586J5ELJKn1OZfwK6zZEGypC8YxWSi_nBA+Z_&{j*y_tMb -z6C6(s<>8a1YQkTymwXrrI?Xm2Z(XHsp-_~6s;*Hc@MZxKw?mh=jIMvB--jM9zQDT5 -z_##%J(qN!>z*rOmA{Oc8*IOL7NzRt42R1uBo;?F>^ndx{qY!eko1xoqPknBbx`jeg -zBK1!If?!CHwgxmCjWr7V)0^wAxV{-lm1HGp@U)MCwN_MeX3LZ*jEL+Um3h1ahneA%41;uV#JudJYWnF4<o}yV;v9^YzeZ9DJPbxV -zCaJz8JMuzS|;y@^GISocc73^ZoFw_q)lcpJX%zS -z?3#&5BtAW>(BMlU0{VA<|F{5pf0gcm5ueT^9u0&(YN^<63?O&=!S{pn(` -zLg_%W?ebF_1IK2E8}fXKJRN7Sd1NEd3=zE}{Ff-55EeRtg*n1;E66aMQp_*vt;2W-BHy(2b;Flg4sLL8j`MDJ -zAbfu?@{0+Il12eRII46kiNKmt05>iU=h -z$)Irsw!hHw5wf7*gjxln_O`c8!(m4}pSsbqKLIVrd=!}5jW}+WPlzQ;+_e-& -z?Dy<48J&+h3*@LUmFxqzh_g>rb^`iEl)hiDf5($dZZJpaL!%i&d@Buf3+M~(|w0IKfQ -za3X0Srk%nLvE~Ab9|gBtt2_H<(fw_Zha@}t^K>=dbE+8{uYX2|#N=bmI)Wc;T*rwV -zwd5A@i2kamPB6hHF1AG?W!pUo_~vz+3wdlN<%QSGe!5}^qJ59h?#udS@qUf7 -zv-9ZWcl%ZgYEV62Ov?klP4Ypq+COVB -zzbpQbKJ4p#FTFlCeU?M~M)FWg!L^__)A~q8ym6&0c0f4_^d1Qsf;q;YQPHwFTKQaY -z@}^_vfdLrw7oSN5$O~22BEUPFgd#kF2FBsIH_Toz2Nw=v^=tZBu!NT|Lp7qp(fZ&&7q@7C0rFJD6; -z(%|4PztN>6GF#&@{I1tbNIIaALQ8ulFL8_Y1vGk-QMPKSZe0HpMtxgqkoct%kuq`w -z#x-}Cb*!ytPr?%+STtAMUu{{K-N%@g062$UWI7UOQm3=mc9wknbhD2qEj-!b^P -z%oYhuwx~lumz_3B^a7bYyyq-71@Fw*7ULPhNJocwr5CvLRsE<~sh>maF=R1p!hO** -zh+7MfH?17kb@`xEls`270@5OICG>$(UstdYt%lJ^wwiJK8I1@$5SE2?UF-^CtL8@; -zs4{#zGZBM@8f^QW&S9I{2Bl9>kdJkdQs6??R6c{5q%l*?6D-aNSM(>Zc4);q<1&7n -zVSb1AZyvYG&77Xtb`dpP1hGZw+U_-uc%-;be&gSUcbi*hJ9V!?LnI5O4d&1TOrlrE -z11&b|=uC!5&O5GB^zm!T#ncJ-bmy8|`YuXV_zy3)jPFmR0m -zFLy&N`z42~p5XU|+fn|GAIE2AfPi3JbxB>QXQ+7$3m_ug7v}~qfMAh#5*_)0mSKO^ -z)R>_thix1PNC=^T>X5@o5Ik^s!>_0nb%0+Qu?l@fMu||fRMI8(eq@a06~$a6goXp4 -zTc(!CW&GU`Z?7*~C%0!|`Po;Y-B>bq8(=^Pt0w>CW3cOKf|^OmN3o|I)zb~mlpR!VZRWgf3r$DjB6U@% -zJ!v9xOZ<+LBarT*ahaknq^miC#W^ANPQ%<$&RHDpEBCU_M(sbvsugC-mYh-fO{Sw9 -z2eEARzci;On#5;xRA{kHL-zc9^rxh(B6&XXZ*i0bo|+5(tR}B*i$>CjH@i(J`<5N< -zm*!QawcKB`2qVVWN|!2bmCj+qMz_>lyQe41Uc6GYo8|ZmgRouOWH<`fPtitAzEwsVe{gYe@!;OmfY1hA^J^GP2Zh7jc0#tW -zV;K{f-a2?ll{FjAo&kmu**_ByBXvrN+H7%pUgwrk*v>}T<%nfg$(O1#f`vAf;$Wwj -zK4OU>ekZ7*cXG`zK^{1Jk?6U1Z!$nXMaDUqNo}Oc<%5yn3pWZ=j1+|nlh9DXMmgJp -zw$>=#X^n__>Lz7RpGg`FbOM{jMF-I&Mx~Gtq{nwcJ*VwE0OFOdSNksknPO9!AjUy9a^u}; -zl{GfA#HVPd@8C*|vf;gcdLXrJL?MukrGr%c^ -z`dR^O=T^5*G@CU0fpX=d2?dv}l#Z}rvrURI+yrK9#ndWZg69>4-LW#tEa5!`s{Zgq -z8R@zhQOojaXAAXjJW6}a5>uV1LhgG$u5JQ_EBF0C=A-S5S2BuoH^CBy68!ST^VMKp -z5t!x0xnCI*Lk$t%?=aM?bAC5Sk&8&Qiu@hZj7DiJ;6#WZd1Z764c#+#;>O(U9%lfW -z>suxqZ)SVz&lYoFmEAcgM7u2vPU$2e-Hjzv>AJy1PeOk$DMk`K`~^i^seLl#HX2s@ -z&vS?_kECyji(-+eKdk1750r)$2U(RhTgkZT@l<$kC`GSck-TzG(h{pKG1aJhxkqgZ -zItykNw;mTU?xiP8Q;PAKW4yNPGkd;&0<^_8y4rHh6AzZ1@@Og1z$t3+RoVK`LOEWpvj)dqZ+bn-ZI_R@g2TDm -zUOXS$8{AioF8c*Kd%YqEKoqkyqA= -z;h>9H=F|lLAffO3sj^3_YLHV~t7o60Afgf+&g?fx9El~tAP}$YS=MFe#gI{HMPF+3A4XgD2y6V7pZ8*{ -zm8;APEKL9wC2F|aO=CXGJo^TSmQpb}X_X3Im%nsfn-Yr)Ip(;&N*#Ay_m3?ila&Xh -zA6V?kP!$WD1kP``H7hg@QY|w7?54~1UuB*oXqD_ePJg`i3GPV0EM`;%joWPh;8C{7 -zYdmIemNAl|da??P+nTE06i%eXK303w@_~!CLz4QEZFdnUm~0^2U*Dh4GePdBsTQhV -zsihVr6*e(LETK(_Y=c5vXJenfn3=4BLe-LG|E6?ccR#tlx)pG=|6cC;SaBt^!li5R -zcPgX&c2MsDL}~N-O+3=a0$|oiwZm$c)<&SyI4_0A@|JEcP=7FY3^?#Of0zNSfD^&A$%$p{mSW|9&i*6 -zj(_qDpxvBQ=^ptttH-vj$9~Va*80<33lpe5w3*6)d5BABGb>2&T7!J8KM%t$O}n*W -zJo+7yk8gR<_bN{XJ|u{lon5UfZc>HMFjulERk&KL*jqG{qadfz)xhuQcg|aymb_Y? -zVYhel3JJX|M+K*)DQMX1IZ`*_*vfscZkpLiT)9gL=cKs}uA(KzRP<4d8#RxOLcE#D -zJP9@OB>kt#JaeOXaqm4Kc^GYiehxcy4(-(f*^`-a9<3OAl0lXjMU1hK=(Co4O{$8%UM|E#&*;l(B?QsiT24bqlr*B{Z7V`VuFjMMHlGAysOT^==1z=5qZQ_2R -z-1qLb)#p6A6j}B#jg`CWg~=F5uJg4=mk4 -zMbEFlbNEc>OXUCT5piF*6@<3E+@D1YQ`=LOmdxBa$alJ^s;X9Vnwl%91RCi4CyD~~ -zEfY~;r~^+zF4y_)m=yu>0s3+B%|pI?8RS^ct^$kP#XRzE>S#R+#~GhIc~p)Cii4cW -z9H*m(D~n23;e5HIw0*7&$Qv-cSkS?#GB%E4^9a4Zdg>n0VB=s|P>wkUFR@1Py;++p -zX;6LW6tT+67ZSct6f1(Z{;9<&8!$Q%dsr@?heJCLyu$kE{QNwMcpba!S7M2R5q^_F -z1m`x@%z~KAD3f^-kF`7BW3BU>kYEeLw+hLBNDUxD$O}Z7ySX3c -zb)wd!i4k24wW1_C2@tbyw%f-8qhJmP`&caiZ`w$^LAjZS5Sn#m^9yX>OCkC~g$Cc7>RooBAs^cU -zIlTk#)OXQ82-Til1rliQ85sNCA>X3OzZ4b&8XPSua_&2S?i?lbG}vKCBGdB|nXS>g -zJ0*+o--w^syM8BpvQ@ycNTP2WG0U^*#8-MC0N=cB;m&`}!LXiv%vI8XM1O%D865l( -z{g6XRuw=jeOMjz9WK|@yzj!yA9i}KA0|SHG1bi12L)S{x7e=_kAN~FN)m7xbSP^arS9Rd{|t-bdQUEl`8{54zNMvQ -zmVu~1GPeH>P7JxwZV*CX5cIQzmo3E{siDMziZ%E7Tl9Q4KN4`#}D9_*vX?k}pO!=)gn7_4Bb4bJT -zqDaOnV(7U1_j;to@cwADU9mBc-@BdBUmAHSzyI{7YGVPi_y~b*r-e;$%CQnDe?9;8 -zfw~{4mSb>(|FgeRQE<@@i1>JZxfuACaFBgBIQO3(xsqo~Se?tnEhWOPgi|!6k69%H -zBXMEw6q@;gX1q%5b}P&*(QhwjwHm7%kJPg>aV1XSsKm6t<)rE6*j;x$hUQ|hu`kT) -zV+}ADC0AEh_W-HRr1Y}-%^FExK~@Y^t(ANZuuEJ`p#^k<`-MWnN77L2@X=9jV+>R; -zXOQ`#-WMm65hugihkOgXY4OID(WpNU{=B$ZDs8X^hCKKCdranviTkKK>$2J_;-Ga6 -z>WBEX7GD$0K(CoP7J96eYCwj_U5&HrOXJSWm=N0MQ^#7X5>(8zV6XiWLH3_ZhnV9@qF1Eb95#jw+CTK -zcnC_X6?w!ouwb8!t?ZeXbU*`_*tn=L1`tKaPq~o#XH-LT(pdaeEr(+5o7_BF^YP^9 -z=s=xqrRelm)Z^rj$VCV;RnXkG!NaMn=)gAL=kN77LMYwzIqFtY;-;Q!9U{UKkl*Z; -zxmwdAck=k)YYlsT2UM!0spVa*x7IFL)Qt{!?hIJJcZxQPc`eiw~~Oj@Tz_oM0xtx3Lb{5kxu -zyBD?uz>WN#g_E*U&crG80;MCX-DnFuJuz_nIeOw6$6c?&s+F|L2zU?5G!ekeS!llo -zFPgW-3Pcj`}O?5W?ab_h%Gy97f=v~(o -zy&qFFhNcAIGR5-l!~O!ti+&6tBv?y$VCZ!G*COZC^Rd=v3DD{VK&YZV`0rM0q-=5@nOTtcx@ -z-`GfyVTF_)=xoTY-xG)BHAl-#;@k>0Kap5G)B~X77JGh`U;(W#+Xleny2|+?3X~v9 -z@j4(Oa(GxV=hv@n1U4Y(PY6pg$c&Ot;)efq)~zTw>;uHy`pS!hYaNUHxEYhbgRg4R -z+}+}7o`g)4OPEQ|;tiYeawTA$%HmQyClOH{QqjoI$3uxnpv;6|Hoy*8NC^3e-^$N* -zqqby_w*0S5T>t%`@v?z_`@m;FByBE`COSJ7m_~uq^-Bim*HTzq_chCA9jeHpXN(2n -zwRqW7h)`1w=SY~Q#F+#wWc43wU)ql>D-{W#MMi*+Rc<(sqj$1IsI?*Vo~~JX4iGFY -zSjVn{Ia}(<$;mhGkK6li&$laGUX5+PgyS=U#yks+rN3QUeb1{R0P)Mr;duDNP0Yns -zOl80yG--mz(9cLJmrW%6skc}}J*KYlL*%B2MMfm>8W3{uoeA1tCC=;U0l+}4z>%rz1`1Gu3qlk(DUqGWSub-M#qTbUB+d9M069OLgJ6ct8Id?;aM)g-r9s^V6BrQ}Q;SCiP`udh7DC -zQX$nG;n1i3pom{#4@R?{E?z&>^3sL?I2rH<%HigVl9la73e4N^TR>PE}F -zsi3VDlCxI}2NOm!ndIQSbW~gNZ4rN(jki^a>Fbq! -zqTN5 -zzb`nx8&_h%Jrt7lQxR^o;6yE0jUGfj6BHagGKnEIbC?*Yeh-mN_p6 -zlPomN>R(3=k&0Ki-xElR=54S -ziifTvyozV0-H|T?}miG^F_wtBpw#IDTI~O&zZ=pp6zI7~U;(eX9v~ -z%_Rrklp$gbO-9{o@iq>QY$8+WLWjtqUprlw=!9l&&i<-B;;B?gDuUYF04x={Q|PYo -z11qyPuIW6^msVN_PE8KdAMXa}bHL6LC^fQ9sh369#H1cfF?JZ}v`b#V$&6F1HA?9- -z8rMp!9QAw;KUupJE(75s%Q_j;=twh?gcLwR?pti!=J%3LhEmj*cmxEL#xOjNHpVeK -zJkF%}PF#r=gweO>TUjCt`~eJ7()chG!YE-`x^-8vG;ltjSQ*{>Exm{gthe@Wqr_;) -z0wt5sLc;HhZgRcM=_rjYuGPk6qTcdMHcs}#u#-NnrJ>ijEn2POpi%bVAyH$%NC@JW -z!9x#~LZ0#)=w{X8oW39GR&eJl^`<7%yQQ1IMRYe1(f#2jGXHCzX6=QT%WeN8>DptC -zHdSdtJVzrAI(JAmUV3k0>(|f-Xp$15@*N%7K>n%=8xkhRkB3QAUtf=ah{(e3zoSSq -z_gFfN{zLz`jCqlr&;1O+r(+F_Z0oUu;MXftO1`Y -z9;O;>OCXbj;jbt_S7jVfllzmVYhq*#nMM~j1j#8VFg%#?vdErxSYKI2XR#z#^jrF| -z60VzCe$K!`P7W(fGZ`zDbu=Gj|Fluc!xb3b3?KS{Jm5T)ZILV)F5q8zrZN3x1!?Fl -zj24#65txQAH>pypq52gcF^Lw8LkW1LoMwVHld&c-soCEOJ`7#g5|?z#rkMgkK7BD? -zv5)5fIFMR6Y+7b6;Ou);_P~PlRc2e$)>HPum(WG>M&1%61LbYx=>T1OuOHP=A_2Ml -zUJa0_6*NB&eSM@;e}$dm67YWg_RVCo!)>o6Rkzh4GG20Rk8#RK+5)kj -zy-EvI3s#yE&SmNou7&*UrnmOiQ_-c!M98x?rSX}WW}0I7mNW&~u)Vo_w^FUmMKUp> -z8k)=i)!=z!;!K+sl(Lhz*Vd$PEuCsaMon#-vS>REEy6K+i5a(<$=x(75fa)xG@=%o -zR1GQOG=s!5g(EG{JieFH*|kCh7=CEGG~xLSIY@MDuIiAnc`G2Ge{P@B(m6G -z!ibqfOA9p9!7d%@C@Z6Oj!J3yF%OjokW8F{Y}gut?pbEsRm(4LL??RqN~(!1fsK#O -zx=08kW?ie)L(K_4s$=P~flB)?RT~0m>*m4)K}Eg&^ysOF8lN -zUHK0Q90oI&{$mRN4;~O7eZ2)RYWiOSNUxax118K@axIASH?!$hWNTeE-m< -z9|d2NgO0N~GYHc0yR$}HApgS_*(Si(CRarIKe5r*$mNd^46r(X7=_aLFxEIYsbgvH -znrzh|J#4IY*379ZTcw$}tG6{QE7PnE4Rz`3%NtHKG_U~aaSk@Sx>k@6ej8+~c|Yc1 -zO&By$u_ANpr;D`5D&%W#Fdl9`BhvdZ5`UZwLv{1Hpy9lA>ut_To&@^KV8eBInUrO5 -zh52}zCbS}L24&AucCm_(e?;?E_ef|R)nd$k+BOlW94v|UU~blRLjQ0ZP-4r2%|3Mn -z>o)c|#p9v2Mo^cLhvg|xC^b2rL@3y2qYKOs?@M}`_`2q==9(4=kTk_PZBIhX-PBrZ -zr~4n>by9I>XJ-@K+>o8|G;Pd^cW)?r)m~#|TJhd}QmeX{jlF$FjtCHM4zkU<60>Zs -z%Hys(I^Fbs!^Li)<*(mdMDF~twQ_bC9DMnUdoO<&F-3^A3(9GW4BH?t7v#5rXa(*RMsaFXpk@rOtgnql#(8*wa~=>H&U=;wN0Q<% -z=~0Qf+>{j>5oC?u{)Ajpd<^k1GgPzB2_X=HLz81#(ra*Wz}OO-za_H(wqrv+ -zz0y`v?a{P}lFJz=@BUy(A)pd~b{ghG$JJ7r@AlNxR+>kt6nYMil7}v99Ja?<@UZ3T -zeP1&kMRSM{5+R84Gc9j#ct$;ly+^es_n)lXhG>_EcB%`8iYCWLpCv8)3~8MaxHrGc -zWH36`!Flt6p(JJsBEPqrE&gHZ?iZtxyx?@fgPx*GS)go(Nf7>mW01|;SB);nF)3s-o4wF7D!)tc}@L$K1~NQb -z#Yr2Tunx+&wm$nlh2CtbCg8*b5`pf^Y+pukoQ>UqK#>9GQek~Po6Bh899xq^a4oaN -z9sDuzXNM=T^ExFYu?oyxI-}8y%D;slDQ*$`e5+$KKq!pF-*Qc6*L_WdXk^K$IEown -zc`-GIjJQlcjeh%cL}$EWcnajL%v-BuW@70M(BzzY-<$NJlWQg2rNIpwvZO(rx6c;G -z_UBD)7Cj+GP^Rw?)N_Nikx*qcIPWa%MBy?TL-6TWG;|5d3z|f%7il*;Ac9f={o-sOWXfH2ow& -z+F%t%kw65bbTBi=kaCFWiK~y^%2iyKohma@H`Ql2SmxhqN|;zqx3*C&8_FG(8wPqn -z80VlP%Gr)DvZLLlMf_OsXDo*4wm909tv4{~9yF8NS%e&sJ#dPsVWzk;(a?)XK|KjU -zmKml2h#A~>%-bFxM<7`wSX>`I?z8$Ca++fy%HqqV=8QYYD~bl^Hz_tBVxFF`f!?T6 -z!OC4>a={OOkbTFV#ew8k2GrG${kNo(rcXXA_NWUqI*@?8f!7jnu3$bUg%u}bhY5Q));;cCAc0gS -zHeTk{K!dAfJ6}@_zTLUn#qe2z2>ZdYkePg(!A+9v>R>`9$hU~PuED*xe7hANwC~xc -zzMc7YMmZr7Iy0P~w;nbL>dml8nV{FL;+xs}qjWkGV5~K1I6DPEC&#K9z5E?@9vBT9 -zvo#L&#*9687;Wd0D#-M4&3F8(7sFq)qrj$;8%`og3#@6+hSB^|^UtXtP#SOBvdY^G -znH{rdVJq%P=QxzF3KPx3etK`XD%|1rVH#OZ35YdYtyAh8`vg5MWd_yI4)jPAmo4j_!3e<(RzCocf`Y+$BAs988hq->eMY}S?z>|#t_c*3a#|wBAi{r! -z{dW0rO)!J3t~1!Um(@E{ATxo*eW!!k$}$1~;aQ@PPH8`A%_SDxVmA)U!Hw)$KXA7$ -zqdYbaY15D(b-OI$URl0+-TYf+!wm}Fwiu|ApRr6t288`7`y!ZbjuZgH`OF0cwYAez -zqSFt2_caUMO6L4Xk>1Be-C -zNHX4bgVd8eU&h^$7@$FnL%%Qp$e+fZ(4dAotr#y7!RrZ>u)-F!F&*jOE8kA5rqU|| -zkg!kLmDxaol3FWgZ=YGJwHYE#cf7j}8z24RotEJKC)?r64}@x}^89m-1nf0~ -z*_bz@JP+Ml3hd*HWuOR@sNVh74L-Sw?LaYKwKo+rvy}#|aFc!~jT1o|KFR)cI+)Bn -z7Gg?S>|0zfR!%gT?WBBV*!!8j6W>|lJse7F&5>m#;ooWbRQhP@izf8nK?3n;AClTI -z6#M340iQgXluMzeY19}<(0FQ=O$wq@ql-?Y9&<2A-S>4Nw#z1Z-(eOaL`iCMI&1sAHP4i1wfU%}{TH10ti=qYU -zDz0-eM;$$6p`VP-jrsMCM}MB&A!(m3WE#f9F_{oZS)?8^0-?^g11w23S(X*2v9^k* -zKU)$N`g+?WLff<~UDFNP<{vgF`ivNrY!#|!D3|%nvN;axyiKQdEH}n|UAvW!JH2@P -z6TzqIA6}zL<{b4pMQp)4ffz(REKD*y3@}3^xF7ui{>6upo0Tm&dOIrt&>JXx_VQrn -z?-nhZdK!u;m!%$urT+S%i$tA>aj?l1`%j#jH%{|kdYyAos^NAM25jH<6TePW$nes= -z1!HeZ;$v}XEv4u4(RnINU~U}A*?wwCqU9m|k--nxsx^vf5AeRn$pVh?0Mnuc`C!uLu2;Vg{7)wfw`U -zX;*Wa;BHUq-TwcZ=lb=LAJ!W;9=uX-aQwln)6svvPf%SQ<1JdhQIPpzpQJ_KDid+% -z!(xv_|7G`-+M9p4uk#~(Mx)cG<|di_EPs|%wf~Qb+;nQM%q9N4&z7FNB6Z+G+^+MR -zj)|=QD8BER{dSeRdtd$LH*1N?VC!qI+*y}-;)|d!tvt|0N -zm5Vlct%>!zH1~C#{PXnRXO%R17-p8ep7o3QUvcWms)tYH$`9TvKIF>&@BVzZ?VI=h -zpErH+ydwvGOs@R*Hs)&kpXVngrCvTXb;0-d@xj~oPM7_l|L;HY`3dlY6p$IBU;poR -XXyugpZ1#qMfq}u()z4*}Q$iB}^Bg|U +zcmaicV|1Ng^k&Q(Hn!T>_Kj`Zc4OO48rwD-Gw*(Xv_UIGaL4*?7e3`t5-R2lSh^xqd84Cs4}W^FDQn9zijsF13M{zVR~<`0dB +z;hww3Rk_uLO*yyZ^N(arMN#SjFcHEi60E_fZug`IjtJ^LVtno=lKj+Jze{_WszRIN1X*HUTCH>C_wc;+D)6YYT +z*RWmTUi`Puu_Uwkj6-qwu_Ue*kO&$%=o%J?6*rej_Ock3znkGIb6 +zWm&yS2Z9LS7slFgUx+?ilDgQBdj7`ruw|IVzJ@wV{&tD)G@SPTMW@9Wl5lcsuU~6` +z7raw|%Or|@Pnlh`7!!rA1H$`p;zz}+92Tp2bFmKDAL`nrC>)<{qBHso +zvJ6|o^vMxL?frh4XZ`3WdH7s_NI0p@{EElbnX*!yp;Vtx&K&w$&to`sW +z79>enm;xWhu;ZKKIN}-h!eBKZM6j$9~*Q(SlE*i_bHS0o#tPY +z5-j+ww|x>h9%`RLUixM!e%f0qVAe5GH83X6?!#^_j-M@lO@*-aD%NMF2;Hg^Wgh@}elrPA3o_&(- +zeNyws4es~%;K1o+pfG(Z!G-nFWzl7)ejRNxY?M~uI=I&MYuz@4>GLH*ptjlQJ`LYr +z*KIIVzBhKHIDwe`X2hc@gsdjzXxX%b<_#kc$vIHFi2)-XM1=fs(`g?0)M{lcJXwp< +zBgIdDXM&n-=+_%;1a?sE$oeN{r%w=8tFfAlQopAk +z%wrVN=r>)oZ0w7^M~Xi~qp6lEaABgF(ck7V3Un;@cg|ODuD7@fw~OZ;^TQV +z$&4AiUj}-4;o`6JV$Y4C2G +z8hVweUdzl78hWzD|&J_)oRr2JdJP +zA&lca);^P(q@hQb9-kqNXVo9An7Q3NoAtyRQw-@JUDD$oluryjE +z3{zzbZhStP-K;xw@Yxf-B=4h(p=4f`k8p2DH$>qQLPR!szD!2|vJ}J`C6=EoRwG^+ +z;`ZDv1SGVO+?IqSxpxSM^_V~@2E+~dZQdl+oz;TP1MX+XXwugMy?Z5AoZ7#R33Y@T +zM)w4;9L0szO3>6i#4fV3q49@wu&`zcvQ!d8!m*dpn&7pp0Y=;QbiyOzhC7)Ki7tDt +zXaIqysWqx53ZgHlO)|YRDG**$7&F{0a8VEECY`3;yx)F>2;4Xr&gC;Iqiqx;orWkF +z8xk0Ty-mK&z`^~Fbs#S;;Qd@1ZFJh4R`+H>Wx$xgn>^oka;w9~QfR>rS7lYHG?D#o +z6Jo`Qg_-DP +zX@kdURs~L5?afF*73QF!=HQ?vIysP;FNCMBfA*}*&%$eDHh5L|y~D=C^v8(wdtcYZ +z)8Q|56BuZ~3~KpF-oKg|5Uf@Ac15Z>sP<9hpm(E>^cgr8dMxGhn7mnWA+JPK+EGR; +zCfK+V1&Xi1M6CUFIA+oJqr(aF3W_=ph7h;IVlqq&xJ=d(CqczQwL>f*A$gJW_|iZw +z&>!^cGyI)UH(_%jFMta0ci8K;?^D#C4_`@%@wP6R4qvs8y@ecdj|*ia7Exg3*BpG4 +z%Dqav(-_hWolzv04-3Ygs)Z~U$`R?hQq2Is2`RWS%z4?!GF2CryzMjCEFg_Y%K+yz +zG8tm;0X{;XG5?BBT|pMZ296(fGUtoF_$Ryrso&s;Cc!g3a;pYOn-tjPvW+1)iAQ)I +zaPyG(wl0MZUqz_Z!4+oEh$t>QIaiZ+J1|fQdfugliOCAg+6D!~3<-k#gA8N#Rk3@5 +z&u3Yevetsi3m`sm2Ntt>FV(PfME~wR=LFu+2@Noy&wr###hgP3mjy&H03re#97OQ% +zsZ;NtktNoC?s@G44Num-@G1zw*?jMf)dA`SWJHyI-Lp=m +zyv8V97L8$~?>Sf(&Ee27TQvEf=-_%~EL56_n`*ZRVS`=4Ka4&HGjr9P8e3rf;8BK& +z&0s~H!Z|V-mPt9vUj?5&%Sa@;XK~`TS$ylgW4|1h&I!<9c6_zoDdR2)FLErHw%Sow +zwc_2ZKizcAMchMvZ^6OY8)uiUt&RwA(`3@dzgihQ1MSrNi;ruq-C+?oVa@U0x +z(>^4ei3Bedg+!LX52G(u@W4P&3sdv45%OawU(*aQat~OuEf?Hi6Zi>__qCd)nw0_j +zvUwA_6WQ5tnFsl_AZNz8L8L*=L4?0A>inj9l&C`AC71u=H +z?bu{Q_=al@1+|F&El|te2eQB@?#+g(D(LjFx>w=0X;CJ|CQc@tuin_)Rd$KH$Y9P9 +z${MAq+Ns2`>_SLAfKm9~%?U2bK6>hiDEbdUD#NMd$hR*wFx8TxWVY3Za +zM&tRPhR$htT-*KlZT-SGBy4YD;6aZfAz^Jt1`=ABifztn#D_;u)2WTa-Bo^EKL;=o +zDc6Ov2x3ybU1B6gkFjv-UvyFl^(EFkIb4ht2Z(*io4 +zW(6^Rp7OMxVh73mYH?bkbxgXB=+TL>U^8OY>=P$oXPkGAmF?6#80T +z+e?24uzuJC8?nCu`7)ef&Nu8x+`0%wOB9wmZ^(+|&$!T80~3uj?NRH)aNhf~#vN9e +zem1VW#bKd$SZ4ufS0-pzoJ%P7UWdT@8yg`1+kpYLV153t;UJy~P8@7sO+#{ePIXcSgw}v2XayA<>Jxh}D)tMOGRgJY0QEJs` +z{>aB;ssVeqKi-6L#(PnBpPuOu<4Rf*GWVk8BdMCd} +zc^_!LU3n2YWBEk1?0<%f@MkB;t#h0%&cixNCZn@Lft$eDVl6z=l@Ga}k<7cF5n!!o +zXet^Q3;AyG!j)+$=3U>7D5cEf)=YMZ)jSZ?)!6EoSa3kU!3W2Xn`K`PqR|ML`Ju!A)|K2`l1>ErJG>o*qIC72B&jHYe36od@P! +zi)qQ9Y7g*>N;Y4;sSLlPxvM;q-Tzw2m;Zx=x>{mk0;Ed5zA?Hb1FrDGc6-;m+iSFU +zc22aC&R^-iyw5vE$D?GWWo7A5o@@>d3_uD92sGM_-tlsdQ?ZbAnF4LsSxDj&0TFgO +zFbB*@;0<;Y0es>tB&~M12_up)gRS(Ce{seFR$9$~MC8~S%gCTV+2AIiH`gndEW2~H +z`z|RK5KuxIccy|!;Bkm8puw0EcWFE{ij71G*o4( +z0~y!3%z_nq1kdh3x<;XVQS{_v?Q3|H1so1Z#CL|Zm2Z&7-mTO?&1?U-oogOAE4Cm{ +z`d4o(XCnWH-J^hx&?7X^xHns&B`u2*skUy`s~w=0252bVaZy(}U?e5?u>fG!UbYaS +z4Gz$YBX|~|U$??YUR+zxw2g5F_OJB7viI^}qx|ouEswnc0o{D4T~~|912EVr9)4P& +zS=*@uBmgy>GC)sz_8A$Iga2y-R#LKP$zyVe7P=4Vrn@Q)Fp6mG;Nall=^07<{OPT~ +zPDD~5M}Py>^H&ikOMCrXaXjFMyNuyNg$gXaPOE4z3=$o3Jt(guFuvAQbA?*MR;Dx}r~+zsgJ +zzCtQ*$r?UAKNl$E39K|(pdcV17*;zU{VtG7{)QDicnC&XAit07AxkJs2xbNxkEh-l +ztI=-hZ#0{5e0{huHk5pMKFXUdk-_HT=8j~#**>ze%L-Vq--ELbc7OqlEqqgfDL$7| +z^zia3^m~7il#>&4bK{s6W!C%o9eQ_nw_LRXoq&)qk2e`~Carh!_+@C+^?4E@nB?8v +zrP(B~aF_-3_5wx4#3EgX2f|T2iDX6dBot9e+}zxz-+7y;fop?^#LWumnJ%(ER<|F> +z44(0)x_-m7iZI17bV#w5<;|{V>IZ-R+z|XI2d!L0M$z{_~PzI|b} +z_>I9TkwT-USfkDEyuoB7YJe7^SUeW*JCd>d31w)Viag>w +zE)Hcnu_U(A@CEh^w;UM0IVsDf+yNUB)lCpiM=a>2dMSVx95URpuHBLGh>h8fgM&77%eeba~6*@>lA8=;7iEw2QP4d^IvP +z8fpiWc?lq5kxp*C)nS|HY^i2ov(x?A!{1u(mk%xyJ_nmAsx{Zt=LV=Ta0-O}2|y4O +z5yIAhMw5|xp3lvw|Ps$0W*KZd^Wlj=W@{AaG=^es3_){Y~Jis`IYYiWN~ho|DLil1qRD5 +zN6xAlvXG=U-8`VKVHr!k-;5Bi)EfnJRTtvY$;jR$#e%~lxMV?xboY;JA{IT_^y}D0 +zw1mJ8tVoSO-(}absB6M8b$Zqe)Ok0$OkaA#I +z48@e8TAlv;PmB6dbP|{7<%qt@Ea>I;PRL4)=M`_G!A40Y$Xy1Mum)I0#!3<77H4)u +zI6c{)TUsy&o^*@2H9Bp>QJA#S8$`zN?+@z^IIQL|VxYEQfVw~Oc}Wq!FS`G2T=aDu +z-DMYe(1$x=331oN(i#yV%?Q)lcY`}FpGRp*74@@$fX%pE+dAGOh5QRhJ&mcaXOhk4 +zLi_pirw^Zws;d9n^#IE8T1ypZDX|crNABquU?iL2;Ql%4Vg5cNBt}OJdbLKnEi|`g2q%v70%eM&7 +z5gdFefu8Ix3n54MC +zW40SGT11ajrrm5AI24T?-2$|VMsU%VX}AMmt>Pr~B}#An{>%QG>_1FQYV^)CExzx2 +z&7E_9c!fpiCLci|F3H*eM2DQQRtQp4>V2RP=KX3ZVw#OXuFxj$VDmM&HQD{*dc7301976VQyI69%EFvxxn>qC&Lo-`%ImvM +zCv>AXKPcD26Z_;m`1pw)uF6Mp=RnShU^yM81!?jbl!v#-kSa#RLhSOG0?yp1YB6Jr +zW=GrO|0zIRSHiH?DYiO+$EpdMkwz#4I6V(J12-W0+dAo4J*?nDQrFI<*}a92Y%1bU +z`RC_4tyg7>R(8{ +zA8*g?PWv##WoF+p0bJe>whg#+(1_+A+)9HS$|n?k;(r=Le*vR;57rn)2& +zEkD8KBSZm#3Drt?t!*#s#>0+yUNysIKRg=t`KSOcSHieiUP0z8F_$tZ(ciPnq_o~@ +z%-{zhbs{i7 +zt~8q8%WO|MF(FE_ye*bl_-@NcA!S9$IMb6x0`e_oNF!hy5a)H^H)5)t(}ek4a1Nc~FF4@f;5aO%aB&3O%B8NuMWWCzYb`d> +zQ-&3)G|5M|pzcLy>pA(p=?3&XKn+v0^`HNsS?M0eb+60BxF|&Y{?>MI^x``)Vp}1V +z;<0N$BUc(0=p=y>zD3k_I~ +zMC>T|rn!T!wN%lqT@ +z&Afsj|04$m&CH2M?F|6yeqb+e`&JWTP^~~z(;c>5;z6RuFKe)%3j|YzeZB9c)5E08 +zvX9?L9%?PT7Vu(RAIXR}s*=I*@Qp<*vA{&7B2uwdBH$_I`33U5di9weG|3 +zx-Iy`1L`R>G-q<+w-{f5qc<7ls}^cT4Y^Qi+meHXFIDgqkt0wpdBZGY?LB+q9&o`T +zd18L5%R+44Ml^UNbEw58BXP#{+I#J1$;VGO`#6Grd<=RWgP+T+ktE6H^>C;%(}szj +zK;wt^oW!yG4Fz=zm4zKw@$Wdo`VJm=879kp$F&$uMP_qiKSB4L@SV)g55F9Rb=3ocrK>iqIRR9n!X0Do*Ldi{9M&^sg&T_TZz~>`tbXc$p%%BI% +z#MahUA?U0t#2ZA4_41*w&52#TXU^_G4)$#uGOnpIb{Gs?Bge_xP|beH;cUSBec^gk +zu;a`And#3j5LZ)LALL9lQ0{$A?tzx&K6M(;#M))7n&`7KTkT>KvjI7O4?mTa;X`81yn7WAir6 +z^Dv#2{~#3{X=5gyP*2v`3yoLJl)--n2rC2}*3n8(L~4ohHzT6QbyEu{!K3q#&p9Lp +z?3#RrZR0JWoh5V%Au%m2?uSB&RO!i99khjDd#7P;NaxJ<_f>mYXQOtXqBZifoWn1d5WC&hmG;&Gv(>!l)|)selJ-m-pz9Og@*rA +z%Xl~n+gHI_Rjy513U_dEaq-~ZLm%H7RpVbREoW=Zu*D?n%JFyy6(v}{RCOy +z>_wu--o5bv-4rRuWG0oN3a2+(f)C6nR0%>9HdI1mB`d{jE6Q4vSf>>{@~N-bGMc6~ +zn=1MB2?XIjZuOC!s@-pN5{60UUw-L4f1L-3Ohud?4)I$4Y&#w^A*ij(1$$3|Vskv} +z#YKCOBnHKh5QN8fd|k)wI{^HZj_1!`{L&>R(m@P^tYk*J)5>eCrio9{j>kWLDCGrM +z*O<)utCbjQiH>aHzD!~>SNyzV|B?uyizaR*!v`(g6N5ks=aSqWHk#wzbQOx2Ehc(>s +zfl`oSK+EzLOKDeK?n#pu;5qF1g-8bXyN##%K`x2R14CxOh8w&P-kz4U}>3Q=A& +zwAa>sCXe?|fR^Y+S9_jW;=!_GK`1Bc2HY6Y)*s}A##+#}239~LV&Q~wL&4n_6^@vW +z;nGUYJ$5-C#kJr2EtD&Ty$t-H)#GyT->}39LWB1gdo%LwqR8{YbRBL*-FCEc5iY{; +z#TpZ~y8yolNKuWi&enqz%<*)Y)j#ff)9q1ezkI|N7|zr3b=T|b>+m?)d% +zKJ;1@L~w8ZQn0MxZS*{ew-;Ohn^Jl!+U{m|QvgB~tai**t#d>0E=CMjN*SZ+36QnO +z4NrSN!Cd>9SLf?=!Hjh+ek}c}ND_U`vvi9(MS>7nGZ*lPm%4(7(bhfuTHod8y%;N{YO_KMV}N<7D)x5snD;XG +zzCOH#WK2$4mAvQWFCCZW#F8TRInJ+=$6eR`V~dES6+!6-=6lkVCHyCW^Bb-$@=b%3 +zi%hxQwAp^EOp|zR61~UikJsM89qE@P3@X5J>+K)hO6K`Z$80UqhLV&|mVt3wQ#G4H +zi4>T}s*jr9pkN+B@=LbuMW8^kzEFQde*yOdnXiUws9u#OD8dYzm?0F`qCm7pBCNNz +zOJB@PR!5?2&9Zw_Jg~i=TwmStKiYq1_@$ +zZKB*^u}y2o({7rV#Nl+8$2T5 +zthMF3X`+*;4Q-~&-*4NzrU=7>#}h=jB}<^tsAch7Ac~Vq;V7 +ziknpCHOP}_P8F&VE%6e`WG~EVa?$ra`knKZrYWbIZ_w@4vO+{B!(Pb&!YhY8pCfe= +zjxF8x>Zh3;#gw`fu})grVJcf=Ohg_Xc9m?(57$!NXQ#N%;Q{V}EjtmA$m<@Ie2(h2j9T2Xq=0<2R#daW&$ +z85=lCIqjn+?h$SF4u|?#DOOKg9>2c{9GSdlh{<(WR;Mb+bxH>u95roevUiqSmcdG* +zEL`{Qv+mA#hjLxuC*l?ROBgDsPYkDNU%;m09$2^ni=SVA=kS_) +z_h->URCbhQr89T-a-Gg9Dk?P`CT8-=f%@A28AYMmma&Ks#DNDsr^|eI%nHBQ0Nps* +z<{@u^G-9krSD|^{Vm?_nRkW_T!;E*n95To#4sxn;9FH2W%&T043S^Vg_Bk^^&J9*H +z=-^Zd6GYUG(CMkA?hy<&4Tc5fn4$3ys+ZiGw!07qHH1zPDzAJY;{8Oj#B1-LTAZ>D +zKqX)c%j0#o|H%z2zdkxYKaV6<&nEMgP`q%2&v+2dsa++rFeWoOnf$VkCAY6|8|kw{ +zdwe(maC?oeGlx#HVClH?)W&QZ`+=l3PIeQ%9cb~nWxJ9)YD|MPt`v?0-3bMcbZ<2Z +zG7xSnH{QoOr#C@?R{C$168|JMfCxcPAVuEhewgQpYO@AfbP3Fw+|Vi7h~L@$6ydj5 +zyf7_h9Rp$0Gii0mkT9xddqw>hIVCXV203~$D~swIj_)TV=zX)@-tK6Hb66mM;EywH +zsMV;{!i^8fvae3b)iz7_f6$4yU2i-b%Bh|o@eU2$RD^G(AtWlyl0^8dxd<9 +zCi_xU0%&wFugtmc%-uOk=xMY?lR%{7BQRZ~b8}1<=DQI)v2*#3|70VNVV*?SK4O}0 +z-HEICfCoyTwy@{F=Ac>4KISQEgQLDcj|>j}hzn(*RSn +zZw&u6!^Z2~7ae&u`+{IHYm_vxJJ@RRZ!LoCjQ2ecK6E;AqeyJZxfuAC +zaFBgBIQO4DawgA~vN)BCS%`;S38kn@9kWOTMq)$V$+z&4nDQvH*{(1#N58$C)v2#; +zJW|ch#FaXRBNNj6mX)HNV{_ScADWB7#Jn(Th}B15lvrI|-2fj-=SL1AY +zQrI&y#`tyxRIyenc$G7)m}|d;5&h;8q8?ap1~7v{vEXIAhojO|^XI$6=K!f+>;5yx +zJJXiq*Z?mW;Ak{?4<=)9$$a@6Q*=1_%}Nx&bGA3oqS%{I)k3y{#DALAzrPw)h(FU +zj}8a8Xte($dBpT +z_ZLeg50aO#zhmy?M*+dS#c4NyP>CZSyS+OOi>@2;)lr;&A$)(OEO;kV+bz6O57by +zyW>9>Ij2^Du|A83(r~$46%S7?Ancv(6R +zJK?TL+k$9p$KMJgY}hdrTzyS}0it==hvU?8YM**7M}l@-W{&s26~NM6 +z#U8(RCX-=6Lw%{$D&=aKSfE%aJ<__RASP1DaZcJPva<-yi3NH#t$OuNk6wlp&CD~1 +zanJ|7AhF;l{a^)Qhr_9Bo;2ZG8=}0whx#r7zZ6W`Fs5 +zJEbvhZVJVsORu$w4Y1HyT1E4?Vka&kS*mSpBuKM>OAT~3W;g7KLGzfQWF~QJ1)H6S +zFCOXwP_auqzKSygLBPB}EH;Q1gXb@Wm*lZWfM<8NWGZM_*$8Ze)0+^IpqCyco5T+P +z>!edzc-RMsx%H6~4%a*u{&6!V2Xf)f8oOKEEtBAhvI#TkSv+Ago-TMSQ(2q}=S0FP +zL(1v}1vp6Ya1@zfO!}Dq3ke|~@mmFXu2dHEQWpO$6X$;c8V@V*w>NACSkmSKF-THX +zXc85Wu2(uhx0b@}vaeA-YhO(oJ!8ZlugSxzOn{tnI7h@dCB`UVE~EEY_ww_|qDlb| +zQh0>qvDy{uar91x0J$!N&ch{3*B*?y730`NAZJT0IXU?T1Oo1Zc+QnB&!+ZYLh%_v +zV;)6DQs1sEzvoxu0r{lou-yG%CgwotYzFK>vqr!e>KRehvaz@y)fTge`_wgV2*|2H +zVl|vbxEx$3ymn~uGqN65%FYqJ<_)*Uqs49;KY2h*(Xa?Tk7AFfl-xf>irJoUyL*;0 +z19&1GQV*5Ni~#kTnaq0ymCiLjk_=0q&=&|cG{r57n*6NwV6zJl5K*ED&DsZy8iEL_rr +zgsLXr6cN9-S7dCo0TeKI3ByoGNNBIG{4b4m4=LB^FstU0B?!6TBZ1v~zn%e*Xk=B) +z@_rySE6iHcIxSfbe^sRAkjZKFfR!7A5uNa|Q%HSV{);)`X_I$=Rz#g9)RV +zjIuDE+A6IDHt@Noy^%sCnU|?kL3tCMU12QN7688MFeYr;%^{CT)BqX<4rY8gFNo(^2<+x6~@> +z0Y;8%xJK3sk3si!JoTyNPRqf>i>%mkw_b{g-~}-aAljQww_S1L53kdn=uMDZM5$#ndk +z&22o*u=b&^trc3UMGkzzrL*~$;t?gd{w8WCC+z$)6{fY`v4CL%;?|JZtR3}&oLz8* +zT?G#HsX)xAYvWho@h=pJpzsjcWp0%LD4s08onG)Nb4)MY=8K^XfVvcKVvP||0{idF +zr>Wx=dX&);ID@-|u5Y#BAa0c8rW_t)Xfo4c@By|jKCCPsr7DjJ6t;eTIrmF;CpM`~(ysWB=S@seY-cC;IYp7eGp3%$l} +z)oc?3jDrN<0qs>+yfj#>o^%eHp8`K^wUK{qUM_Xl#K;;VHK+>&$DqLQV1~BoxLuBrt&0}DAhEKn_^ER` +zz-29QNvC|8F%an87xNYKcn*LCu89T8nVkc&?~&O83)5GbY)slt*#=)i7s;A_C=2r7N7+fk`X1KngTDCyUEafq@X5m_z1=DeiD@Q38P{+Ou8AdwgrjC5 +zajlbj!7Ae^jZ~9GGnmvF%|dV*Siz7~1$lG}zFHP5%BV8TD09lQN!w79WRZ;`=PM(z +z0;YT`0PcRb5SM~SQ_OKjwTc~?W_G_IPe||U$;Um2U%fe+7X>%Nvy!xcXUbbT1miw0 +z=$X7_W&m0ay!h~`ae>C68mu@al*ia7R0saqO=sn$tE@ww372nWLhU^>%{WE>Eoln8 +zaeH(5Zly+xlW1Z@B{Z2HqS52V*oh`BC}k&quf19RS}N6$l#0qGWzl9DQkZ@85(#UMH4E) +z!&hPrOmR$HRF*}2C{e3A#U3h9d)gN68^|>O9=TO4Ga~u#5kl0}_*QP9IxEl~Ce;Vj +zS3zvyQ+p-TKYiV8z>J$akDBH=i$W7}&)8|aN%_17$7$H|;eKWRKgAtrMwoyE;#kJp +z>iJ{R+d4p$2q2;Y5EBQ7>@E&mk*MzVW>!EDsQ9Pd1Icl|=0d^U2HU!hP6MLe0bwp2 +zA=U!|OQM?{{^8dU?o^&w|I~Y5fw~zw)IT&*mzBRUy1Ljo^-=Z`fvN|N_JgxG~k*Hc%03VftQZkoi*AD{-11-bt2%}_=-R;7ZY`jOzsFyAEWb! +zVJNLPL#@4|8iv-c@m4Lu!^Uc7?VOsDWty>@T6^QN67|~9P?w&boWVpR2)d)gI@s*$ +zT0uPct)H#x^_Y(_q2El&g2<(pF8niAzCde(;c)XAp3awn@Z)3{qMO$l1?#O_cXL+a +zB+yS96Q;w{xIBw9%-h2xp$%a(D0`Noi$$31BbukCM_lu$4sG_+rWsH9U`eD0eY3t3 +z@`vkyB5OW$_NhyNPE(&_JPvYO1XVd%SiaJPVza|ZguGogD*p`OzJ!Odk4wR7o=G7; +zQFEN*_9WQcO`Vliy5G@VCnZ;Qb~fJ44e1$o^Tw=L_lA;Z-8Dw0CC}X_m5Q_J*xP61 +z2tVQGAnU9PA@k;{9QL{c=-~c_joC`W*8qxTI)7}foE-)SU;g6SD;S1P5oGCta0DrC +zGXz?khB$Fn{Ycwuk%t&RTyJ!Mz8mnC0U+AYu}PkaA-t-gE*25%;RVKNKyWz!scpu6 +zZDKFBX5S4#lCQK!Ip%UxMsP%cC4T!8d`;mo#M{(B)h;Ilk3UVA`-O^+JuQDuUnt-K +z=jEH2NuzvVs7mGT0rJ;Nz54;;pVk-{O`o<8h5~yAG9cx)%sJ+#d0-B8j!9{+{>1@9 +zYiz-m^g@6wE8^*umZD0JhIN!|&Ok-?2XhJ@B|oI&FfS^$rs90JhlZBoJW`e5b9j^- +zWO>uD9oB-o4QKEBn$akVeT1MeUX-s%#m~lPXZR!_h7SU~%Y_rx{QlrO`$o+{oUb!PIS+x5N +z+{O+YLa6?IE1#&A?RMZ&J}!O!vj>Os^y>J_BMi^Cu8;>FP)!5eagStg`4k8`f<9)s +zLv>uniXJHc5tD}2a*xO+UycHT8lGykAS#tq7H&?$Q|yXO#aH{77;M;}%#Rn*u_i#Q#=kFoCjB +zxM)O)sW@_wx=K{lJ|iyESH0iv9Nr111eP3eEA!SenTb%U12{RS*7qj0=;%^Kd#QiJ +ziYTEU=jFY{zWsSqmqmw<7L@5T1o7NxWhht`9gu$(b|QZnjVAE)D;lyC=>~hv=8piE3T9#-QVKCSaq-q&xr*zuRbfKtru+;Kkp5Si5+<6{tz}rp +zigZWmiiYYR#xdxCbhhJz=wN$k9zPcR8H;AJErv2><3*Bm51h&CEJlpT9yo5`1`w{pnaAJ%0k=ISmg0E +zo$J6^H1-w0!^WV5w|yx36dtal`WN}DGpD-gqYjDTfjIaLtR}xxCDSo6v=}KHRM^9@ +z&T;nw5x5ee(K3%Z3QQF%sMId_cIRpr&3g$f><9ZoX7X_c7g4f{y)mf(?;`TLI@jLv +z?N)ryzDJ)LsBZU+VnRH0X1E}KJ!}%#n_-hEY9w +z`8(=7Fd9^wGY;{_ggJK@ZR?yW!1!^^d;F^x%}=DG(7K8XMm$L~K*Np|t>vZmA5%Y| +zINrWxnZFq_J7&ksTGEluekfNRCX$8u^xk+?w8Q1iII^7LA8Wc=uh=>E34C14fN(+~ +zjb&LKSzG|ur8^cG=n*d|U)DK;5`-D7c>o{;1qb8{cYdL5^ll*Y29ag^ZWs(}{Dq?& +z7Vt6fu%BVSoqvD;RYW!I!KS^e-kCz_2@FvAByt<`2mpvxlE{aWp)% +z7->KZs4&!M+Z9|_;(QrbPRGNC2zLU&;bq*v@zaDlNR7 +zR!OB(0w7?XvMI3w1tc_A&fY$=RO&K>9q)K{?KeL9#X2nl`k!ouFF)XFC@Tui*%L4~ +zwNvTu3}=K5TH;uDS!^k3d+!l_hx$f?(hkYU(6NBYx@mz*Y6dZ7D@JF^5^p{aiT5zv +z;Xjc--#|sw407DGZz<4^FBXBq5F)zwTQ|65$~FTfyft2wOiY&QG(ydKoz#wa?YKny +z)9C@EX0c#XN}}K5dNFdMNo^+Os>0sS^c;E5Ky4zm)q;>J{J+z3sdUj)7tN@@gZSf7 +zJ|wiD$oI`e{Xe-gDV9P_(x}i7AaPVJn&m~NMi(84-RGbXy6@{lY?h66ze7!6Ee=i! +zInre-6PCHrI9+8v4+)Zge*esLVEy0*)t)o|)801Zf98hgQ=EZH2bpZ=)5NN_2yjw# +zP8Ewr(5WN{8DJpt*e!|G(gvZ5Pxywag$Agdns%%4+IH>|FMw9b +zKb<-v)*Cb*Ao~hb;B*`Ee&trZYBi`{$ru%gmKbuXcPNb3lD3H3Jimki7;BEFp{bxX +zFJ7Rk<~$d5(AGs1%w=$DDrj&3=?C4wX`U{m8^^=Z8R3YTB_A>ZAOkmldWl +zwo0ZyTNCB`dfUZA+chm*()HWtA2!JQ3>g${8%Vr% +zasf==&095e)fG}M%iIsk{PaQ>2|D59ppz^2pExvb9Ou9EI^`kN!0aXr*u3p0ex0b4 +z=AnHH#@v>`#o*LjN-yB0^^l)H2Nm=yD3|>1aNigv$f`s680kxF8B%d>SUG)YF0R~W +z$TI5rvll2~&q4RSwu3})*@1!~z4l}@NsY#MwV(2Y=hbLZh-ce*Eq3<#rZ +zxra}au9h@`-JaCDeW|)St?N40z`g~4rjZ?xu=?#W;cJyHNPXCV2DuxD%N1A2hAlFH +zwTJm(6XPn#dA&{dq>&yd{5Lp=pa<%$*em=~TdQ%rn_v#5`>I!IS>M^uNpl#N|wC@HMBcRTMT#SL;d7 +z<(&BuA6dLkkx|8fWw@PXzCeCBgDx@HJs@)L+j8y~gZ)7)${p-|O7{G? +z&|M6FI|A*^d_U+Of-3`+w(c~-YsQby|NH)g|G7xv|Nek^|Jex)g~z+)I0xPC0460S +LFIp>X81%mY^Bg|U literal 0 HcmV?d00001 diff --git a/patches/server/0499-forced-whitelist-use-configurable-kick-message.patch b/patches/server/0499-forced-whitelist-use-configurable-kick-message.patch index 6ed293a5e200..6dcbff2ff81d 100644 --- a/patches/server/0499-forced-whitelist-use-configurable-kick-message.patch +++ b/patches/server/0499-forced-whitelist-use-configurable-kick-message.patch @@ -5,10 +5,10 @@ Subject: [PATCH] forced whitelist: use configurable kick message diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 79f5907bd6f00dc152f00e596993ca5275de336c..a7057a1d13288eeb8b0113bd83fa29588fb1725e 100644 +index a6435cc675bca502994a31d2f2d91257c8c1fa2f..1cf78a61a5737aafd4e9384dc76af1a9fbc98621 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2368,7 +2368,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); -@@ -1658,7 +1659,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent -@@ -1724,6 +1727,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { @@ -2269,7 +2269,7 @@ index 62bb046b8f74862c2d8cb369209c1e0cc5544a75..2ce5a4248971123c0832323bc6a3d470 this.packRepository.setSelected(dataPacks); WorldDataConfiguration worlddataconfiguration = new WorldDataConfiguration(MinecraftServer.getSelectedPacks(this.packRepository, true), this.worldData.enabledFeatures()); -@@ -2275,6 +2277,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent diff --git a/patches/server/1021-Tag-Lifecycle-Events.patch b/patches/server/1021-Tag-Lifecycle-Events.patch index a2c9dbb957c2..a247efaccc60 100644 --- a/patches/server/1021-Tag-Lifecycle-Events.patch +++ b/patches/server/1021-Tag-Lifecycle-Events.patch @@ -474,10 +474,10 @@ index fdc88e52235a152dbe3cca273990b4b68f8daaf8..13797035494a1e010e1da529fb46040f static void loadContentsFromNetwork( diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index d25bc0cf0c05de8e9e7366104560d74961d74a8a..be1588c0a757a2d86fbedc1c89f47fd7c60d84f4 100644 +index 7981abcea38196658556d403cbb588a7ddfff6ba..257e7cf628af0e539e14f836ca47280ae97bd90d 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2251,7 +2251,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoopmap(resourcepackrepository::getPack).filter(Objects::nonNull).map(Pack::open).collect(ImmutableList.toImmutableList()); // CraftBukkit - decompile error // Paper - decompile error // todo: is this needed anymore? }, this).thenCompose((immutablelist) -> { MultiPackResourceManager resourcemanager = new MultiPackResourceManager(PackType.SERVER_DATA, immutablelist); diff --git a/patches/server/1038-Moonrise-optimisation-patches.patch b/patches/server/1038-Moonrise-optimisation-patches.patch index 06e5e26ee476..2160af1a6b52 100644 --- a/patches/server/1038-Moonrise-optimisation-patches.patch +++ b/patches/server/1038-Moonrise-optimisation-patches.patch @@ -23386,7 +23386,7 @@ index fc6ce3485dc890f5105a37fe3e344a1460867556..e114e687f2f4503546687fd6792226a6 DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, worldLoader.get(), thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), services, LoggerChunkProgressListener::createFromGameruleRadius); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index be1588c0a757a2d86fbedc1c89f47fd7c60d84f4..38060a14181f6bcbd36ee4c91fdb20fae30c534a 100644 +index 257e7cf628af0e539e14f836ca47280ae97bd90d..0b095c559c6a95ba2d9d7717d527cc2d8b7b6354 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -205,7 +205,7 @@ import org.bukkit.event.server.ServerLoadEvent; @@ -23582,7 +23582,7 @@ index be1588c0a757a2d86fbedc1c89f47fd7c60d84f4..38060a14181f6bcbd36ee4c91fdb20fa return true; } else { boolean ret = false; // Paper - force execution of all worlds, do not just bias the first -@@ -2732,6 +2812,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; // Paper - don't store the vanilla dispatcher @@ -127,7 +127,7 @@ index c13b4f39c19dd6a62ae39688bde5a4739b391e59..d25d500a2206d4f7e821de3766e8a523 // CraftBukkit end // Spigot start public static final int TPS = 20; -@@ -319,6 +319,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); Thread thread = new ca.spottedleaf.moonrise.common.util.TickThread(() -> { // Paper - rewrite chunk system -@@ -488,6 +491,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements Profiler - try { - task.run(); - } catch (Exception var3) { -+ if (var3.getCause() instanceof ThreadDeath) throw var3; // Paper - LOGGER.error(LogUtils.FATAL_MARKER, "Error executing task on {}", this.name(), var3); - } +@@ -168,6 +168,6 @@ public abstract class BlockableEventLoop implements Profiler + public static boolean isNonRecoverable(Throwable exception) { + return exception instanceof ReportedException reportedException + ? isNonRecoverable(reportedException.getCause()) +- : exception instanceof OutOfMemoryError || exception instanceof StackOverflowError; ++ : exception instanceof OutOfMemoryError || exception instanceof StackOverflowError || exception instanceof ThreadDeath; // Paper } + } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 5c4eaa6bcf20b0fcec14bd5ef76ea6f29a8613a2..e2a0487089eb5a7bdc1433e4c75f69d8e9f9d5f9 100644 +index bb2d3ba2065b6bf67af24a8630ac2d58169fe783..044985030607bc20a61666dee7dd2659ae4553b5 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -1419,6 +1419,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1495,6 +1495,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl try { tickConsumer.accept(entity); } catch (Throwable throwable) { @@ -341,10 +339,10 @@ index 5c4eaa6bcf20b0fcec14bd5ef76ea6f29a8613a2..e2a0487089eb5a7bdc1433e4c75f69d8 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 b1a6dc25b04ab6a43e8d62378e14d88d1c60bbbe..7c11853c5090fbc4fa5b3e73a69acf166158fdec 100644 +index e03d57f58a9f962cd429e8851fb3f35f3491e2c0..1313ac2ff9f1b9fccab54b0c200b9dfa7a4edd00 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -1044,6 +1044,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p +@@ -1081,6 +1081,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p gameprofilerfiller.pop(); } catch (Throwable throwable) { diff --git a/patches/unapplied/server/1027-Detail-more-information-in-watchdog-dumps.patch b/patches/server/1043-Detail-more-information-in-watchdog-dumps.patch similarity index 92% rename from patches/unapplied/server/1027-Detail-more-information-in-watchdog-dumps.patch rename to patches/server/1043-Detail-more-information-in-watchdog-dumps.patch index d82b120f853d..6c08ae9d363e 100644 --- a/patches/unapplied/server/1027-Detail-more-information-in-watchdog-dumps.patch +++ b/patches/server/1043-Detail-more-information-in-watchdog-dumps.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Detail more information in watchdog dumps - Dump player name, player uuid, position, and world for packet handling diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java -index 90a2c61c42cba7e38f167eccdd7a951a947963c4..3e550f8e7cd4f4e16f499a8a2a4b95420270f07a 100644 +index fff8d15d44613a075b9793c2a41520212166eb3b..4a8356a714ed50d4a32bcf046a2e16491bef014b 100644 --- a/src/main/java/net/minecraft/network/Connection.java +++ b/src/main/java/net/minecraft/network/Connection.java @@ -632,7 +632,13 @@ public class Connection extends SimpleChannelInboundHandler> { @@ -76,10 +76,10 @@ index d0d36a57ec4896bcb74970f8fb24d8f3e17db133..e2c24813f59c2fd075c740ac1842a38f }); 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 9e1af229f52a8ac09833901ad53bd154fed34a4f..c5698b05cc3ea4cb1bc6789c30f2aab76748d491 100644 +index 3b55367865b3583e11ef886678114d4d4b294e8c..a7420e4522e0dff72ce7f8a791b9cd4bfa270106 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1199,7 +1199,26 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1262,7 +1262,26 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } @@ -106,10 +106,10 @@ index 9e1af229f52a8ac09833901ad53bd154fed34a4f..c5698b05cc3ea4cb1bc6789c30f2aab7 ++TimingHistory.entityTicks; // Paper - timings // Spigot start co.aikar.timings.Timing timer; // Paper -@@ -1239,7 +1258,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - this.tickPassenger(entity, entity1); +@@ -1301,7 +1320,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2 } - // } finally { timer.stopTiming(); } // Paper - timings - move up + // } finally { timer.stopTiming(); } // Paper - timings // EAR 2 - + // Paper start - log detailed entity tick information + } finally { @@ -120,12 +120,12 @@ index 9e1af229f52a8ac09833901ad53bd154fed34a4f..c5698b05cc3ea4cb1bc6789c30f2aab7 + // Paper end - log detailed entity tick information } - private void tickPassenger(Entity vehicle, Entity passenger) { + private void tickPassenger(Entity vehicle, Entity passenger, boolean isActive) { // Paper - EAR 2 diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 2a49bbc2c7b06a065cd33575e6807594529bd1bc..bc45c74987974b4828201e06fc8b1f3fbc0af8b4 100644 +index b36a915e6d337d7ec3f797bf1773b14c5b231d76..6817015f0cf39df03029e36cd845d590618031dc 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -1086,8 +1086,43 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1171,8 +1171,43 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this.onGround; } @@ -154,7 +154,7 @@ index 2a49bbc2c7b06a065cd33575e6807594529bd1bc..bc45c74987974b4828201e06fc8b1f3f + } + // Paper end - detailed watchdog information + - public void move(MoverType movementType, Vec3 movement) { + public void move(MoverType type, Vec3 movement) { final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity + // Paper start - detailed watchdog information + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot move an entity off-main"); @@ -169,8 +169,8 @@ index 2a49bbc2c7b06a065cd33575e6807594529bd1bc..bc45c74987974b4828201e06fc8b1f3f if (this.noPhysics) { this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z); } else { -@@ -1257,6 +1292,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - this.level().getProfiler().pop(); +@@ -1293,6 +1328,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + gameprofilerfiller.pop(); } } + // Paper start - detailed watchdog information @@ -182,8 +182,8 @@ index 2a49bbc2c7b06a065cd33575e6807594529bd1bc..bc45c74987974b4828201e06fc8b1f3f + // Paper end - detailed watchdog information } - private boolean isStateClimbable(BlockState state) { -@@ -4552,7 +4594,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + private void applyMovementEmissionAndPlaySound(Entity.MovementEmission moveEffect, Vec3 movement, BlockPos landingPos, BlockState landingState) { +@@ -4884,7 +4926,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public void setDeltaMovement(Vec3 velocity) { @@ -193,7 +193,7 @@ index 2a49bbc2c7b06a065cd33575e6807594529bd1bc..bc45c74987974b4828201e06fc8b1f3f } public void addDeltaMovement(Vec3 velocity) { -@@ -4658,7 +4702,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4990,7 +5034,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } // Paper end - Fix MC-4 if (this.position.x != x || this.position.y != y || this.position.z != z) { From 2946dbb832e32297837453d87481da4108a10fe7 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Sat, 26 Oct 2024 15:11:09 +0100 Subject: [PATCH 087/119] Update WorldServer#serverlevelData mapping --- build-data/reobf-mappings-patch.tiny | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-data/reobf-mappings-patch.tiny b/build-data/reobf-mappings-patch.tiny index 6bd89f5e427e..b14d9ed34563 100644 --- a/build-data/reobf-mappings-patch.tiny +++ b/build-data/reobf-mappings-patch.tiny @@ -14,7 +14,7 @@ tiny 2 0 mojang+yarn spigot # CraftBukkit changes type c net/minecraft/server/level/ServerLevel net/minecraft/server/level/WorldServer - f Lnet/minecraft/world/level/storage/PrimaryLevelData; serverLevelData K + f Lnet/minecraft/world/level/storage/PrimaryLevelData; serverLevelData L c net/minecraft/world/level/chunk/LevelChunk net/minecraft/world/level/chunk/Chunk f Lnet/minecraft/server/level/ServerLevel; level r From 98af0e0d3bf1dd275f15d64d2debb386e84d7862 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Sat, 26 Oct 2024 18:03:25 +0200 Subject: [PATCH 088/119] update generator --- paper-api-generator/build.gradle.kts | 2 +- .../paper/entity/ai/VanillaGoal.java | 6 +- .../registry/keys/BannerPatternKeys.java | 2 +- .../paper/registry/keys/BiomeKeys.java | 12 +- .../paper/registry/keys/BlockTypeKeys.java | 219 +++- .../paper/registry/keys/CatVariantKeys.java | 2 +- .../paper/registry/keys/DamageTypeKeys.java | 16 +- .../paper/registry/keys/EnchantmentKeys.java | 2 +- .../paper/registry/keys/FrogVariantKeys.java | 2 +- .../paper/registry/keys/GameEventKeys.java | 2 +- .../paper/registry/keys/InstrumentKeys.java | 2 +- .../paper/registry/keys/ItemTypeKeys.java | 1093 +++++++++++------ .../paper/registry/keys/JukeboxSongKeys.java | 2 +- .../registry/keys/MapDecorationTypeKeys.java | 2 +- .../paper/registry/keys/MenuTypeKeys.java | 2 +- .../paper/registry/keys/MobEffectKeys.java | 2 +- .../paper/registry/keys/StructureKeys.java | 2 +- .../registry/keys/StructureTypeKeys.java | 2 +- .../paper/registry/keys/TrimMaterialKeys.java | 2 +- .../paper/registry/keys/TrimPatternKeys.java | 2 +- .../registry/keys/VillagerProfessionKeys.java | 2 +- .../paper/registry/keys/VillagerTypeKeys.java | 2 +- .../paper/registry/keys/WolfVariantKeys.java | 2 +- .../keys/tags/EnchantmentTagKeys.java | 2 +- .../registry/keys/tags/ItemTypeTagKeys.java | 173 ++- .../main/java/io/papermc/generator/Main.java | 24 +- .../generator/types/GeneratedKeyType.java | 32 +- .../generator/types/GeneratedTagKeyType.java | 10 +- .../generator/types/SimpleGenerator.java | 1 - .../types/goal/MobGoalGenerator.java | 41 - .../generator/types/goal/MobGoalNames.java | 4 + .../generator/utils/CollectingContext.java | 4 +- .../papermc/generator/utils/Formatting.java | 8 +- .../papermc/generator/utils/TagCollector.java | 2 +- paper-api-generator/wideners.at | 3 +- patches/api/0004-Code-Generation.patch | 10 +- ...0427-Experimental-annotations-change.patch | 13 + .../server/0350-Implement-Mob-Goal-API.patch | 7 +- patches/server/0553-Missing-Entity-API.patch | 2 +- 39 files changed, 1244 insertions(+), 474 deletions(-) diff --git a/paper-api-generator/build.gradle.kts b/paper-api-generator/build.gradle.kts index 05d16d0b9510..62ceb696a547 100644 --- a/paper-api-generator/build.gradle.kts +++ b/paper-api-generator/build.gradle.kts @@ -15,7 +15,7 @@ dependencies { implementation("com.squareup:javapoet:1.13.0") implementation(project(":paper-api")) implementation("io.github.classgraph:classgraph:4.8.47") - implementation("org.jetbrains:annotations:24.0.1") + implementation("org.jetbrains:annotations:24.1.0") testImplementation("org.junit.jupiter:junit-jupiter:5.10.2") testRuntimeOnly("org.junit.platform:junit-platform-launcher") } diff --git a/paper-api-generator/generated/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/paper-api-generator/generated/com/destroystokyo/paper/entity/ai/VanillaGoal.java index 02411466bdcf..e0aa5b925cbd 100644 --- a/paper-api-generator/generated/com/destroystokyo/paper/entity/ai/VanillaGoal.java +++ b/paper-api-generator/generated/com/destroystokyo/paper/entity/ai/VanillaGoal.java @@ -66,7 +66,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") public interface VanillaGoal extends Goal { GoalKey RANDOM_STAND = create("random_stand", AbstractHorse.class); @@ -102,6 +102,10 @@ public interface VanillaGoal extends Goal { GoalKey BEE_WANDER = create("bee_wander", Bee.class); + GoalKey VALIDATE_FLOWER = create("validate_flower", Bee.class); + + GoalKey VALIDATE_HIVE = create("validate_hive", Bee.class); + GoalKey BLAZE_ATTACK = create("blaze_attack", Blaze.class); GoalKey CAT_AVOID_ENTITY = create("cat_avoid_entity", Cat.class); diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/BannerPatternKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/BannerPatternKeys.java index e585ebb00aba..33e501a6fa5e 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/BannerPatternKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/BannerPatternKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class BannerPatternKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/BiomeKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/BiomeKeys.java index f0c6abf8bf66..83a5d59ea072 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/BiomeKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/BiomeKeys.java @@ -6,6 +6,7 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; +import org.bukkit.MinecraftExperimental; import org.bukkit.block.Biome; import org.checkerframework.checker.nullness.qual.NonNull; import org.jetbrains.annotations.ApiStatus; @@ -23,7 +24,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class BiomeKeys { /** @@ -299,6 +300,15 @@ public final class BiomeKeys { */ public static final TypedKey OLD_GROWTH_SPRUCE_TAIGA = create(key("old_growth_spruce_taiga")); + /** + * {@code minecraft:pale_garden} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_GARDEN = create(key("pale_garden")); + /** * {@code minecraft:plains} * diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/BlockTypeKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/BlockTypeKeys.java index 3daa9b638cf3..d2b100a27a85 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/BlockTypeKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/BlockTypeKeys.java @@ -6,6 +6,7 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; +import org.bukkit.MinecraftExperimental; import org.bukkit.block.BlockType; import org.checkerframework.checker.nullness.qual.NonNull; import org.jetbrains.annotations.ApiStatus; @@ -23,7 +24,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class BlockTypeKeys { /** @@ -1622,6 +1623,15 @@ public final class BlockTypeKeys { */ public static final TypedKey CRAFTING_TABLE = create(key("crafting_table")); + /** + * {@code minecraft:creaking_heart} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey CREAKING_HEART = create(key("creaking_heart")); + /** * {@code minecraft:creeper_head} * @@ -4562,6 +4572,186 @@ public final class BlockTypeKeys { */ public static final TypedKey PACKED_MUD = create(key("packed_mud")); + /** + * {@code minecraft:pale_hanging_moss} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_HANGING_MOSS = create(key("pale_hanging_moss")); + + /** + * {@code minecraft:pale_moss_block} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_MOSS_BLOCK = create(key("pale_moss_block")); + + /** + * {@code minecraft:pale_moss_carpet} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_MOSS_CARPET = create(key("pale_moss_carpet")); + + /** + * {@code minecraft:pale_oak_button} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_BUTTON = create(key("pale_oak_button")); + + /** + * {@code minecraft:pale_oak_door} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_DOOR = create(key("pale_oak_door")); + + /** + * {@code minecraft:pale_oak_fence} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_FENCE = create(key("pale_oak_fence")); + + /** + * {@code minecraft:pale_oak_fence_gate} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_FENCE_GATE = create(key("pale_oak_fence_gate")); + + /** + * {@code minecraft:pale_oak_hanging_sign} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_HANGING_SIGN = create(key("pale_oak_hanging_sign")); + + /** + * {@code minecraft:pale_oak_leaves} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_LEAVES = create(key("pale_oak_leaves")); + + /** + * {@code minecraft:pale_oak_log} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_LOG = create(key("pale_oak_log")); + + /** + * {@code minecraft:pale_oak_planks} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_PLANKS = create(key("pale_oak_planks")); + + /** + * {@code minecraft:pale_oak_pressure_plate} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_PRESSURE_PLATE = create(key("pale_oak_pressure_plate")); + + /** + * {@code minecraft:pale_oak_sapling} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_SAPLING = create(key("pale_oak_sapling")); + + /** + * {@code minecraft:pale_oak_sign} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_SIGN = create(key("pale_oak_sign")); + + /** + * {@code minecraft:pale_oak_slab} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_SLAB = create(key("pale_oak_slab")); + + /** + * {@code minecraft:pale_oak_stairs} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_STAIRS = create(key("pale_oak_stairs")); + + /** + * {@code minecraft:pale_oak_trapdoor} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_TRAPDOOR = create(key("pale_oak_trapdoor")); + + /** + * {@code minecraft:pale_oak_wall_hanging_sign} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_WALL_HANGING_SIGN = create(key("pale_oak_wall_hanging_sign")); + + /** + * {@code minecraft:pale_oak_wall_sign} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_WALL_SIGN = create(key("pale_oak_wall_sign")); + + /** + * {@code minecraft:pale_oak_wood} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_WOOD = create(key("pale_oak_wood")); + /** * {@code minecraft:pearlescent_froglight} * @@ -5143,6 +5333,15 @@ public final class BlockTypeKeys { */ public static final TypedKey POTTED_OXEYE_DAISY = create(key("potted_oxeye_daisy")); + /** + * {@code minecraft:potted_pale_oak_sapling} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey POTTED_PALE_OAK_SAPLING = create(key("potted_pale_oak_sapling")); + /** * {@code minecraft:potted_pink_tulip} * @@ -6410,6 +6609,24 @@ public final class BlockTypeKeys { */ public static final TypedKey STRIPPED_OAK_WOOD = create(key("stripped_oak_wood")); + /** + * {@code minecraft:stripped_pale_oak_log} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey STRIPPED_PALE_OAK_LOG = create(key("stripped_pale_oak_log")); + + /** + * {@code minecraft:stripped_pale_oak_wood} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey STRIPPED_PALE_OAK_WOOD = create(key("stripped_pale_oak_wood")); + /** * {@code minecraft:stripped_spruce_log} * diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/CatVariantKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/CatVariantKeys.java index a8cbc4c9a01c..98acbdf85800 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/CatVariantKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/CatVariantKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class CatVariantKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/DamageTypeKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/DamageTypeKeys.java index 9cb651fb14d2..d89a584a1e5d 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/DamageTypeKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/DamageTypeKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class DamageTypeKeys { /** @@ -82,6 +82,13 @@ public final class DamageTypeKeys { */ public static final TypedKey DRY_OUT = create(key("dry_out")); + /** + * {@code minecraft:ender_pearl} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENDER_PEARL = create(key("ender_pearl")); + /** * {@code minecraft:explosion} * @@ -201,6 +208,13 @@ public final class DamageTypeKeys { */ public static final TypedKey LIGHTNING_BOLT = create(key("lightning_bolt")); + /** + * {@code minecraft:mace_smash} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MACE_SMASH = create(key("mace_smash")); + /** * {@code minecraft:magic} * diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/EnchantmentKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/EnchantmentKeys.java index 8a7b691af62a..cf19e146cdae 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/EnchantmentKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/EnchantmentKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class EnchantmentKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/FrogVariantKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/FrogVariantKeys.java index 2b9c007e4922..7cbe222657ec 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/FrogVariantKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/FrogVariantKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class FrogVariantKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/GameEventKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/GameEventKeys.java index e8a8e5f89a71..d3751e33e295 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/GameEventKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/GameEventKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class GameEventKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/InstrumentKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/InstrumentKeys.java index 4d59a6b6e1b2..98b44173be72 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/InstrumentKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/InstrumentKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class InstrumentKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/ItemTypeKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/ItemTypeKeys.java index 052d12963087..9750f7a2018e 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/ItemTypeKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/ItemTypeKeys.java @@ -6,6 +6,7 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; +import org.bukkit.MinecraftExperimental; import org.bukkit.inventory.ItemType; import org.checkerframework.checker.nullness.qual.NonNull; import org.jetbrains.annotations.ApiStatus; @@ -23,7 +24,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class ItemTypeKeys { /** @@ -698,6 +699,13 @@ public final class ItemTypeKeys { */ public static final TypedKey BLACK_BED = create(key("black_bed")); + /** + * {@code minecraft:black_bundle} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey BLACK_BUNDLE = create(key("black_bundle")); + /** * {@code minecraft:black_candle} * @@ -852,6 +860,13 @@ public final class ItemTypeKeys { */ public static final TypedKey BLUE_BED = create(key("blue_bed")); + /** + * {@code minecraft:blue_bundle} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey BLUE_BUNDLE = create(key("blue_bundle")); + /** * {@code minecraft:blue_candle} * @@ -992,6 +1007,13 @@ public final class ItemTypeKeys { */ public static final TypedKey BOOKSHELF = create(key("bookshelf")); + /** + * {@code minecraft:bordure_indented_banner_pattern} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey BORDURE_INDENTED_BANNER_PATTERN = create(key("bordure_indented_banner_pattern")); + /** * {@code minecraft:bow} * @@ -1111,6 +1133,13 @@ public final class ItemTypeKeys { */ public static final TypedKey BROWN_BED = create(key("brown_bed")); + /** + * {@code minecraft:brown_bundle} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey BROWN_BUNDLE = create(key("brown_bundle")); + /** * {@code minecraft:brown_candle} * @@ -2014,6 +2043,24 @@ public final class ItemTypeKeys { */ public static final TypedKey CRAFTING_TABLE = create(key("crafting_table")); + /** + * {@code minecraft:creaking_heart} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey CREAKING_HEART = create(key("creaking_heart")); + + /** + * {@code minecraft:creaking_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey CREAKING_SPAWN_EGG = create(key("creaking_spawn_egg")); + /** * {@code minecraft:creeper_banner_pattern} * @@ -2224,6 +2271,13 @@ public final class ItemTypeKeys { */ public static final TypedKey CYAN_BED = create(key("cyan_bed")); + /** + * {@code minecraft:cyan_bundle} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey CYAN_BUNDLE = create(key("cyan_bundle")); + /** * {@code minecraft:cyan_candle} * @@ -2889,6 +2943,20 @@ public final class ItemTypeKeys { */ public static final TypedKey DROWNED_SPAWN_EGG = create(key("drowned_spawn_egg")); + /** + * {@code minecraft:dune_armor_trim_smithing_template} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey DUNE_ARMOR_TRIM_SMITHING_TEMPLATE = create(key("dune_armor_trim_smithing_template")); + + /** + * {@code minecraft:echo_shard} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ECHO_SHARD = create(key("echo_shard")); + /** * {@code minecraft:elder_guardian_spawn_egg} * @@ -2946,371 +3014,644 @@ public final class ItemTypeKeys { public static final TypedKey EXPERIENCE_BOTTLE = create(key("experience_bottle")); /** - * {@code minecraft:fire_charge} + * {@code minecraft:explorer_pottery_sherd} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey FIRE_CHARGE = create(key("fire_charge")); + public static final TypedKey EXPLORER_POTTERY_SHERD = create(key("explorer_pottery_sherd")); /** - * {@code minecraft:firework_rocket} + * {@code minecraft:exposed_copper_bulb} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey FIREWORK_ROCKET = create(key("firework_rocket")); + public static final TypedKey EXPOSED_COPPER_BULB = create(key("exposed_copper_bulb")); /** - * {@code minecraft:firework_star} + * {@code minecraft:exposed_copper_grate} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey FIREWORK_STAR = create(key("firework_star")); + public static final TypedKey EXPOSED_COPPER_GRATE = create(key("exposed_copper_grate")); /** - * {@code minecraft:flower_pot} + * {@code minecraft:eye_armor_trim_smithing_template} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey FLOWER_POT = create(key("flower_pot")); + public static final TypedKey EYE_ARMOR_TRIM_SMITHING_TEMPLATE = create(key("eye_armor_trim_smithing_template")); /** - * {@code minecraft:fox_spawn_egg} + * {@code minecraft:field_masoned_banner_pattern} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey FOX_SPAWN_EGG = create(key("fox_spawn_egg")); + public static final TypedKey FIELD_MASONED_BANNER_PATTERN = create(key("field_masoned_banner_pattern")); /** - * {@code minecraft:frog_spawn_egg} + * {@code minecraft:fire_charge} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey FROG_SPAWN_EGG = create(key("frog_spawn_egg")); + public static final TypedKey FIRE_CHARGE = create(key("fire_charge")); /** - * {@code minecraft:ghast_spawn_egg} + * {@code minecraft:firework_rocket} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey GHAST_SPAWN_EGG = create(key("ghast_spawn_egg")); + public static final TypedKey FIREWORK_ROCKET = create(key("firework_rocket")); /** - * {@code minecraft:glow_item_frame} + * {@code minecraft:firework_star} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey GLOW_ITEM_FRAME = create(key("glow_item_frame")); + public static final TypedKey FIREWORK_STAR = create(key("firework_star")); /** - * {@code minecraft:glow_squid_spawn_egg} + * {@code minecraft:fletching_table} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey GLOW_SQUID_SPAWN_EGG = create(key("glow_squid_spawn_egg")); + public static final TypedKey FLETCHING_TABLE = create(key("fletching_table")); /** - * {@code minecraft:goat_spawn_egg} + * {@code minecraft:flow_armor_trim_smithing_template} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey GOAT_SPAWN_EGG = create(key("goat_spawn_egg")); + public static final TypedKey FLOW_ARMOR_TRIM_SMITHING_TEMPLATE = create(key("flow_armor_trim_smithing_template")); /** - * {@code minecraft:golden_carrot} + * {@code minecraft:flow_banner_pattern} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey GOLDEN_CARROT = create(key("golden_carrot")); + public static final TypedKey FLOW_BANNER_PATTERN = create(key("flow_banner_pattern")); /** - * {@code minecraft:golden_horse_armor} + * {@code minecraft:flow_pottery_sherd} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey GOLDEN_HORSE_ARMOR = create(key("golden_horse_armor")); + public static final TypedKey FLOW_POTTERY_SHERD = create(key("flow_pottery_sherd")); /** - * {@code minecraft:gray_banner} + * {@code minecraft:flower_banner_pattern} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey GRAY_BANNER = create(key("gray_banner")); + public static final TypedKey FLOWER_BANNER_PATTERN = create(key("flower_banner_pattern")); /** - * {@code minecraft:green_banner} + * {@code minecraft:flower_pot} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey GREEN_BANNER = create(key("green_banner")); + public static final TypedKey FLOWER_POT = create(key("flower_pot")); /** - * {@code minecraft:guardian_spawn_egg} + * {@code minecraft:fox_spawn_egg} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey GUARDIAN_SPAWN_EGG = create(key("guardian_spawn_egg")); + public static final TypedKey FOX_SPAWN_EGG = create(key("fox_spawn_egg")); /** - * {@code minecraft:hoglin_spawn_egg} + * {@code minecraft:friend_pottery_sherd} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey HOGLIN_SPAWN_EGG = create(key("hoglin_spawn_egg")); + public static final TypedKey FRIEND_POTTERY_SHERD = create(key("friend_pottery_sherd")); /** - * {@code minecraft:horse_spawn_egg} + * {@code minecraft:frog_spawn_egg} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey HORSE_SPAWN_EGG = create(key("horse_spawn_egg")); + public static final TypedKey FROG_SPAWN_EGG = create(key("frog_spawn_egg")); /** - * {@code minecraft:husk_spawn_egg} + * {@code minecraft:frogspawn} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey HUSK_SPAWN_EGG = create(key("husk_spawn_egg")); + public static final TypedKey FROGSPAWN = create(key("frogspawn")); /** - * {@code minecraft:iron_golem_spawn_egg} + * {@code minecraft:ghast_spawn_egg} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey IRON_GOLEM_SPAWN_EGG = create(key("iron_golem_spawn_egg")); + public static final TypedKey GHAST_SPAWN_EGG = create(key("ghast_spawn_egg")); /** - * {@code minecraft:iron_horse_armor} + * {@code minecraft:gilded_blackstone} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey IRON_HORSE_ARMOR = create(key("iron_horse_armor")); + public static final TypedKey GILDED_BLACKSTONE = create(key("gilded_blackstone")); /** - * {@code minecraft:iron_nugget} + * {@code minecraft:globe_banner_pattern} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey IRON_NUGGET = create(key("iron_nugget")); + public static final TypedKey GLOBE_BANNER_PATTERN = create(key("globe_banner_pattern")); /** - * {@code minecraft:item_frame} + * {@code minecraft:glow_berries} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey ITEM_FRAME = create(key("item_frame")); + public static final TypedKey GLOW_BERRIES = create(key("glow_berries")); /** - * {@code minecraft:knowledge_book} + * {@code minecraft:glow_item_frame} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey KNOWLEDGE_BOOK = create(key("knowledge_book")); + public static final TypedKey GLOW_ITEM_FRAME = create(key("glow_item_frame")); /** - * {@code minecraft:lead} + * {@code minecraft:glow_squid_spawn_egg} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey LEAD = create(key("lead")); + public static final TypedKey GLOW_SQUID_SPAWN_EGG = create(key("glow_squid_spawn_egg")); /** - * {@code minecraft:leather_horse_armor} + * {@code minecraft:goat_horn} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey LEATHER_HORSE_ARMOR = create(key("leather_horse_armor")); + public static final TypedKey GOAT_HORN = create(key("goat_horn")); /** - * {@code minecraft:light_blue_banner} + * {@code minecraft:goat_spawn_egg} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey LIGHT_BLUE_BANNER = create(key("light_blue_banner")); + public static final TypedKey GOAT_SPAWN_EGG = create(key("goat_spawn_egg")); /** - * {@code minecraft:light_gray_banner} + * {@code minecraft:golden_carrot} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey LIGHT_GRAY_BANNER = create(key("light_gray_banner")); + public static final TypedKey GOLDEN_CARROT = create(key("golden_carrot")); /** - * {@code minecraft:lime_banner} + * {@code minecraft:golden_horse_armor} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey LIME_BANNER = create(key("lime_banner")); + public static final TypedKey GOLDEN_HORSE_ARMOR = create(key("golden_horse_armor")); /** - * {@code minecraft:lingering_potion} + * {@code minecraft:gray_banner} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey LINGERING_POTION = create(key("lingering_potion")); + public static final TypedKey GRAY_BANNER = create(key("gray_banner")); /** - * {@code minecraft:llama_spawn_egg} + * {@code minecraft:gray_candle} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey LLAMA_SPAWN_EGG = create(key("llama_spawn_egg")); + public static final TypedKey GRAY_CANDLE = create(key("gray_candle")); /** - * {@code minecraft:mace} + * {@code minecraft:green_banner} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey MACE = create(key("mace")); + public static final TypedKey GREEN_BANNER = create(key("green_banner")); /** - * {@code minecraft:magenta_banner} + * {@code minecraft:green_candle} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey MAGENTA_BANNER = create(key("magenta_banner")); + public static final TypedKey GREEN_CANDLE = create(key("green_candle")); /** - * {@code minecraft:magma_cube_spawn_egg} + * {@code minecraft:grindstone} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey MAGMA_CUBE_SPAWN_EGG = create(key("magma_cube_spawn_egg")); + public static final TypedKey GRINDSTONE = create(key("grindstone")); /** - * {@code minecraft:map} + * {@code minecraft:guardian_spawn_egg} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey MAP = create(key("map")); + public static final TypedKey GUARDIAN_SPAWN_EGG = create(key("guardian_spawn_egg")); /** - * {@code minecraft:mooshroom_spawn_egg} + * {@code minecraft:guster_banner_pattern} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey MOOSHROOM_SPAWN_EGG = create(key("mooshroom_spawn_egg")); + public static final TypedKey GUSTER_BANNER_PATTERN = create(key("guster_banner_pattern")); /** - * {@code minecraft:mule_spawn_egg} + * {@code minecraft:guster_pottery_sherd} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey MULE_SPAWN_EGG = create(key("mule_spawn_egg")); + public static final TypedKey GUSTER_POTTERY_SHERD = create(key("guster_pottery_sherd")); /** - * {@code minecraft:music_disc_5} + * {@code minecraft:heart_of_the_sea} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey MUSIC_DISC_5 = create(key("music_disc_5")); + public static final TypedKey HEART_OF_THE_SEA = create(key("heart_of_the_sea")); /** - * {@code minecraft:disc_fragment_5} + * {@code minecraft:heart_pottery_sherd} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey DISC_FRAGMENT_5 = create(key("disc_fragment_5")); + public static final TypedKey HEART_POTTERY_SHERD = create(key("heart_pottery_sherd")); /** - * {@code minecraft:dispenser} + * {@code minecraft:heartbreak_pottery_sherd} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey DISPENSER = create(key("dispenser")); + public static final TypedKey HEARTBREAK_POTTERY_SHERD = create(key("heartbreak_pottery_sherd")); /** - * {@code minecraft:dragon_egg} + * {@code minecraft:hoglin_spawn_egg} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey DRAGON_EGG = create(key("dragon_egg")); + public static final TypedKey HOGLIN_SPAWN_EGG = create(key("hoglin_spawn_egg")); /** - * {@code minecraft:dried_kelp} + * {@code minecraft:honey_bottle} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey DRIED_KELP = create(key("dried_kelp")); + public static final TypedKey HONEY_BOTTLE = create(key("honey_bottle")); /** - * {@code minecraft:dried_kelp_block} + * {@code minecraft:honeycomb} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey DRIED_KELP_BLOCK = create(key("dried_kelp_block")); + public static final TypedKey HONEYCOMB = create(key("honeycomb")); /** - * {@code minecraft:dripstone_block} + * {@code minecraft:honeycomb_block} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey DRIPSTONE_BLOCK = create(key("dripstone_block")); + public static final TypedKey HONEYCOMB_BLOCK = create(key("honeycomb_block")); /** - * {@code minecraft:dropper} + * {@code minecraft:horse_spawn_egg} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey DROPPER = create(key("dropper")); + public static final TypedKey HORSE_SPAWN_EGG = create(key("horse_spawn_egg")); /** - * {@code minecraft:dune_armor_trim_smithing_template} + * {@code minecraft:host_armor_trim_smithing_template} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey DUNE_ARMOR_TRIM_SMITHING_TEMPLATE = create(key("dune_armor_trim_smithing_template")); + public static final TypedKey HOST_ARMOR_TRIM_SMITHING_TEMPLATE = create(key("host_armor_trim_smithing_template")); /** - * {@code minecraft:echo_shard} + * {@code minecraft:howl_pottery_sherd} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey ECHO_SHARD = create(key("echo_shard")); + public static final TypedKey HOWL_POTTERY_SHERD = create(key("howl_pottery_sherd")); /** - * {@code minecraft:egg} + * {@code minecraft:husk_spawn_egg} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey EGG = create(key("egg")); + public static final TypedKey HUSK_SPAWN_EGG = create(key("husk_spawn_egg")); /** - * {@code minecraft:elytra} + * {@code minecraft:iron_golem_spawn_egg} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey ELYTRA = create(key("elytra")); + public static final TypedKey IRON_GOLEM_SPAWN_EGG = create(key("iron_golem_spawn_egg")); /** - * {@code minecraft:emerald} + * {@code minecraft:iron_horse_armor} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey EMERALD = create(key("emerald")); + public static final TypedKey IRON_HORSE_ARMOR = create(key("iron_horse_armor")); /** - * {@code minecraft:emerald_block} + * {@code minecraft:iron_nugget} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey EMERALD_BLOCK = create(key("emerald_block")); + public static final TypedKey IRON_NUGGET = create(key("iron_nugget")); /** - * {@code minecraft:emerald_ore} + * {@code minecraft:item_frame} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey EMERALD_ORE = create(key("emerald_ore")); + public static final TypedKey ITEM_FRAME = create(key("item_frame")); /** - * {@code minecraft:enchanted_golden_apple} + * {@code minecraft:knowledge_book} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey ENCHANTED_GOLDEN_APPLE = create(key("enchanted_golden_apple")); + public static final TypedKey KNOWLEDGE_BOOK = create(key("knowledge_book")); /** - * {@code minecraft:enchanting_table} + * {@code minecraft:lantern} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LANTERN = create(key("lantern")); + + /** + * {@code minecraft:large_amethyst_bud} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LARGE_AMETHYST_BUD = create(key("large_amethyst_bud")); + + /** + * {@code minecraft:lead} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LEAD = create(key("lead")); + + /** + * {@code minecraft:leather_horse_armor} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LEATHER_HORSE_ARMOR = create(key("leather_horse_armor")); + + /** + * {@code minecraft:light_blue_banner} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LIGHT_BLUE_BANNER = create(key("light_blue_banner")); + + /** + * {@code minecraft:light_blue_candle} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LIGHT_BLUE_CANDLE = create(key("light_blue_candle")); + + /** + * {@code minecraft:light_gray_banner} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LIGHT_GRAY_BANNER = create(key("light_gray_banner")); + + /** + * {@code minecraft:light_gray_candle} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LIGHT_GRAY_CANDLE = create(key("light_gray_candle")); + + /** + * {@code minecraft:lime_banner} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LIME_BANNER = create(key("lime_banner")); + + /** + * {@code minecraft:lime_candle} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LIME_CANDLE = create(key("lime_candle")); + + /** + * {@code minecraft:lingering_potion} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LINGERING_POTION = create(key("lingering_potion")); + + /** + * {@code minecraft:llama_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LLAMA_SPAWN_EGG = create(key("llama_spawn_egg")); + + /** + * {@code minecraft:lodestone} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LODESTONE = create(key("lodestone")); + + /** + * {@code minecraft:loom} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LOOM = create(key("loom")); + + /** + * {@code minecraft:mace} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MACE = create(key("mace")); + + /** + * {@code minecraft:magenta_banner} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MAGENTA_BANNER = create(key("magenta_banner")); + + /** + * {@code minecraft:magenta_candle} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MAGENTA_CANDLE = create(key("magenta_candle")); + + /** + * {@code minecraft:magma_cube_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MAGMA_CUBE_SPAWN_EGG = create(key("magma_cube_spawn_egg")); + + /** + * {@code minecraft:map} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MAP = create(key("map")); + + /** + * {@code minecraft:medium_amethyst_bud} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MEDIUM_AMETHYST_BUD = create(key("medium_amethyst_bud")); + + /** + * {@code minecraft:miner_pottery_sherd} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MINER_POTTERY_SHERD = create(key("miner_pottery_sherd")); + + /** + * {@code minecraft:mojang_banner_pattern} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MOJANG_BANNER_PATTERN = create(key("mojang_banner_pattern")); + + /** + * {@code minecraft:mooshroom_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MOOSHROOM_SPAWN_EGG = create(key("mooshroom_spawn_egg")); + + /** + * {@code minecraft:mourner_pottery_sherd} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MOURNER_POTTERY_SHERD = create(key("mourner_pottery_sherd")); + + /** + * {@code minecraft:mule_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MULE_SPAWN_EGG = create(key("mule_spawn_egg")); + + /** + * {@code minecraft:music_disc_5} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MUSIC_DISC_5 = create(key("music_disc_5")); + + /** + * {@code minecraft:disc_fragment_5} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey DISC_FRAGMENT_5 = create(key("disc_fragment_5")); + + /** + * {@code minecraft:dispenser} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey DISPENSER = create(key("dispenser")); + + /** + * {@code minecraft:dragon_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey DRAGON_EGG = create(key("dragon_egg")); + + /** + * {@code minecraft:dried_kelp} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey DRIED_KELP = create(key("dried_kelp")); + + /** + * {@code minecraft:dried_kelp_block} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey DRIED_KELP_BLOCK = create(key("dried_kelp_block")); + + /** + * {@code minecraft:dripstone_block} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey DRIPSTONE_BLOCK = create(key("dripstone_block")); + + /** + * {@code minecraft:dropper} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey DROPPER = create(key("dropper")); + + /** + * {@code minecraft:egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey EGG = create(key("egg")); + + /** + * {@code minecraft:elytra} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ELYTRA = create(key("elytra")); + + /** + * {@code minecraft:emerald} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey EMERALD = create(key("emerald")); + + /** + * {@code minecraft:emerald_block} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey EMERALD_BLOCK = create(key("emerald_block")); + + /** + * {@code minecraft:emerald_ore} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey EMERALD_ORE = create(key("emerald_ore")); + + /** + * {@code minecraft:enchanted_golden_apple} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENCHANTED_GOLDEN_APPLE = create(key("enchanted_golden_apple")); + + /** + * {@code minecraft:enchanting_table} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ @@ -3386,13 +3727,6 @@ public final class ItemTypeKeys { */ public static final TypedKey ENDER_PEARL = create(key("ender_pearl")); - /** - * {@code minecraft:explorer_pottery_sherd} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey EXPLORER_POTTERY_SHERD = create(key("explorer_pottery_sherd")); - /** * {@code minecraft:exposed_chiseled_copper} * @@ -3407,13 +3741,6 @@ public final class ItemTypeKeys { */ public static final TypedKey EXPOSED_COPPER = create(key("exposed_copper")); - /** - * {@code minecraft:exposed_copper_bulb} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey EXPOSED_COPPER_BULB = create(key("exposed_copper_bulb")); - /** * {@code minecraft:exposed_copper_door} * @@ -3421,13 +3748,6 @@ public final class ItemTypeKeys { */ public static final TypedKey EXPOSED_COPPER_DOOR = create(key("exposed_copper_door")); - /** - * {@code minecraft:exposed_copper_grate} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey EXPOSED_COPPER_GRATE = create(key("exposed_copper_grate")); - /** * {@code minecraft:exposed_copper_trapdoor} * @@ -3456,13 +3776,6 @@ public final class ItemTypeKeys { */ public static final TypedKey EXPOSED_CUT_COPPER_STAIRS = create(key("exposed_cut_copper_stairs")); - /** - * {@code minecraft:eye_armor_trim_smithing_template} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey EYE_ARMOR_TRIM_SMITHING_TEMPLATE = create(key("eye_armor_trim_smithing_template")); - /** * {@code minecraft:farmland} * @@ -3526,13 +3839,6 @@ public final class ItemTypeKeys { */ public static final TypedKey FISHING_ROD = create(key("fishing_rod")); - /** - * {@code minecraft:fletching_table} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey FLETCHING_TABLE = create(key("fletching_table")); - /** * {@code minecraft:flint} * @@ -3547,34 +3853,6 @@ public final class ItemTypeKeys { */ public static final TypedKey FLINT_AND_STEEL = create(key("flint_and_steel")); - /** - * {@code minecraft:flow_armor_trim_smithing_template} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey FLOW_ARMOR_TRIM_SMITHING_TEMPLATE = create(key("flow_armor_trim_smithing_template")); - - /** - * {@code minecraft:flow_banner_pattern} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey FLOW_BANNER_PATTERN = create(key("flow_banner_pattern")); - - /** - * {@code minecraft:flow_pottery_sherd} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey FLOW_POTTERY_SHERD = create(key("flow_pottery_sherd")); - - /** - * {@code minecraft:flower_banner_pattern} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey FLOWER_BANNER_PATTERN = create(key("flower_banner_pattern")); - /** * {@code minecraft:flowering_azalea} * @@ -3589,20 +3867,6 @@ public final class ItemTypeKeys { */ public static final TypedKey FLOWERING_AZALEA_LEAVES = create(key("flowering_azalea_leaves")); - /** - * {@code minecraft:friend_pottery_sherd} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey FRIEND_POTTERY_SHERD = create(key("friend_pottery_sherd")); - - /** - * {@code minecraft:frogspawn} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey FROGSPAWN = create(key("frogspawn")); - /** * {@code minecraft:furnace} * @@ -3624,13 +3888,6 @@ public final class ItemTypeKeys { */ public static final TypedKey GHAST_TEAR = create(key("ghast_tear")); - /** - * {@code minecraft:gilded_blackstone} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GILDED_BLACKSTONE = create(key("gilded_blackstone")); - /** * {@code minecraft:glass} * @@ -3659,20 +3916,6 @@ public final class ItemTypeKeys { */ public static final TypedKey GLISTERING_MELON_SLICE = create(key("glistering_melon_slice")); - /** - * {@code minecraft:globe_banner_pattern} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GLOBE_BANNER_PATTERN = create(key("globe_banner_pattern")); - - /** - * {@code minecraft:glow_berries} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GLOW_BERRIES = create(key("glow_berries")); - /** * {@code minecraft:glow_ink_sac} * @@ -3701,13 +3944,6 @@ public final class ItemTypeKeys { */ public static final TypedKey GLOWSTONE_DUST = create(key("glowstone_dust")); - /** - * {@code minecraft:goat_horn} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GOAT_HORN = create(key("goat_horn")); - /** * {@code minecraft:gold_block} * @@ -3856,11 +4092,11 @@ public final class ItemTypeKeys { public static final TypedKey GRAY_BED = create(key("gray_bed")); /** - * {@code minecraft:gray_candle} + * {@code minecraft:gray_bundle} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey GRAY_CANDLE = create(key("gray_candle")); + public static final TypedKey GRAY_BUNDLE = create(key("gray_bundle")); /** * {@code minecraft:gray_carpet} @@ -3940,11 +4176,11 @@ public final class ItemTypeKeys { public static final TypedKey GREEN_BED = create(key("green_bed")); /** - * {@code minecraft:green_candle} + * {@code minecraft:green_bundle} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey GREEN_CANDLE = create(key("green_candle")); + public static final TypedKey GREEN_BUNDLE = create(key("green_bundle")); /** * {@code minecraft:green_carpet} @@ -3993,133 +4229,70 @@ public final class ItemTypeKeys { * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey GREEN_STAINED_GLASS = create(key("green_stained_glass")); - - /** - * {@code minecraft:green_stained_glass_pane} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GREEN_STAINED_GLASS_PANE = create(key("green_stained_glass_pane")); - - /** - * {@code minecraft:green_terracotta} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GREEN_TERRACOTTA = create(key("green_terracotta")); - - /** - * {@code minecraft:green_wool} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GREEN_WOOL = create(key("green_wool")); - - /** - * {@code minecraft:grindstone} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GRINDSTONE = create(key("grindstone")); - - /** - * {@code minecraft:gunpowder} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GUNPOWDER = create(key("gunpowder")); - - /** - * {@code minecraft:guster_banner_pattern} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GUSTER_BANNER_PATTERN = create(key("guster_banner_pattern")); - - /** - * {@code minecraft:guster_pottery_sherd} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GUSTER_POTTERY_SHERD = create(key("guster_pottery_sherd")); - - /** - * {@code minecraft:hanging_roots} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey HANGING_ROOTS = create(key("hanging_roots")); - - /** - * {@code minecraft:hay_block} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey HAY_BLOCK = create(key("hay_block")); + public static final TypedKey GREEN_STAINED_GLASS = create(key("green_stained_glass")); /** - * {@code minecraft:heart_of_the_sea} + * {@code minecraft:green_stained_glass_pane} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey HEART_OF_THE_SEA = create(key("heart_of_the_sea")); + public static final TypedKey GREEN_STAINED_GLASS_PANE = create(key("green_stained_glass_pane")); /** - * {@code minecraft:heart_pottery_sherd} + * {@code minecraft:green_terracotta} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey HEART_POTTERY_SHERD = create(key("heart_pottery_sherd")); + public static final TypedKey GREEN_TERRACOTTA = create(key("green_terracotta")); /** - * {@code minecraft:heartbreak_pottery_sherd} + * {@code minecraft:green_wool} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey HEARTBREAK_POTTERY_SHERD = create(key("heartbreak_pottery_sherd")); + public static final TypedKey GREEN_WOOL = create(key("green_wool")); /** - * {@code minecraft:heavy_core} + * {@code minecraft:gunpowder} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey HEAVY_CORE = create(key("heavy_core")); + public static final TypedKey GUNPOWDER = create(key("gunpowder")); /** - * {@code minecraft:heavy_weighted_pressure_plate} + * {@code minecraft:hanging_roots} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey HEAVY_WEIGHTED_PRESSURE_PLATE = create(key("heavy_weighted_pressure_plate")); + public static final TypedKey HANGING_ROOTS = create(key("hanging_roots")); /** - * {@code minecraft:honey_block} + * {@code minecraft:hay_block} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey HONEY_BLOCK = create(key("honey_block")); + public static final TypedKey HAY_BLOCK = create(key("hay_block")); /** - * {@code minecraft:honey_bottle} + * {@code minecraft:heavy_core} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey HONEY_BOTTLE = create(key("honey_bottle")); + public static final TypedKey HEAVY_CORE = create(key("heavy_core")); /** - * {@code minecraft:honeycomb} + * {@code minecraft:heavy_weighted_pressure_plate} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey HONEYCOMB = create(key("honeycomb")); + public static final TypedKey HEAVY_WEIGHTED_PRESSURE_PLATE = create(key("heavy_weighted_pressure_plate")); /** - * {@code minecraft:honeycomb_block} + * {@code minecraft:honey_block} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey HONEYCOMB_BLOCK = create(key("honeycomb_block")); + public static final TypedKey HONEY_BLOCK = create(key("honey_block")); /** * {@code minecraft:hopper} @@ -4156,20 +4329,6 @@ public final class ItemTypeKeys { */ public static final TypedKey HORN_CORAL_FAN = create(key("horn_coral_fan")); - /** - * {@code minecraft:host_armor_trim_smithing_template} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey HOST_ARMOR_TRIM_SMITHING_TEMPLATE = create(key("host_armor_trim_smithing_template")); - - /** - * {@code minecraft:howl_pottery_sherd} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey HOWL_POTTERY_SHERD = create(key("howl_pottery_sherd")); - /** * {@code minecraft:ice} * @@ -4492,13 +4651,6 @@ public final class ItemTypeKeys { */ public static final TypedKey LADDER = create(key("ladder")); - /** - * {@code minecraft:lantern} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey LANTERN = create(key("lantern")); - /** * {@code minecraft:lapis_block} * @@ -4520,13 +4672,6 @@ public final class ItemTypeKeys { */ public static final TypedKey LAPIS_ORE = create(key("lapis_ore")); - /** - * {@code minecraft:large_amethyst_bud} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey LARGE_AMETHYST_BUD = create(key("large_amethyst_bud")); - /** * {@code minecraft:large_fern} * @@ -4605,11 +4750,11 @@ public final class ItemTypeKeys { public static final TypedKey LIGHT_BLUE_BED = create(key("light_blue_bed")); /** - * {@code minecraft:light_blue_candle} + * {@code minecraft:light_blue_bundle} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey LIGHT_BLUE_CANDLE = create(key("light_blue_candle")); + public static final TypedKey LIGHT_BLUE_BUNDLE = create(key("light_blue_bundle")); /** * {@code minecraft:light_blue_carpet} @@ -4689,11 +4834,11 @@ public final class ItemTypeKeys { public static final TypedKey LIGHT_GRAY_BED = create(key("light_gray_bed")); /** - * {@code minecraft:light_gray_candle} + * {@code minecraft:light_gray_bundle} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey LIGHT_GRAY_CANDLE = create(key("light_gray_candle")); + public static final TypedKey LIGHT_GRAY_BUNDLE = create(key("light_gray_bundle")); /** * {@code minecraft:light_gray_carpet} @@ -4808,11 +4953,11 @@ public final class ItemTypeKeys { public static final TypedKey LIME_BED = create(key("lime_bed")); /** - * {@code minecraft:lime_candle} + * {@code minecraft:lime_bundle} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey LIME_CANDLE = create(key("lime_candle")); + public static final TypedKey LIME_BUNDLE = create(key("lime_bundle")); /** * {@code minecraft:lime_carpet} @@ -4884,20 +5029,6 @@ public final class ItemTypeKeys { */ public static final TypedKey LIME_WOOL = create(key("lime_wool")); - /** - * {@code minecraft:lodestone} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey LODESTONE = create(key("lodestone")); - - /** - * {@code minecraft:loom} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey LOOM = create(key("loom")); - /** * {@code minecraft:magenta_bed} * @@ -4906,11 +5037,11 @@ public final class ItemTypeKeys { public static final TypedKey MAGENTA_BED = create(key("magenta_bed")); /** - * {@code minecraft:magenta_candle} + * {@code minecraft:magenta_bundle} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey MAGENTA_CANDLE = create(key("magenta_candle")); + public static final TypedKey MAGENTA_BUNDLE = create(key("magenta_bundle")); /** * {@code minecraft:magenta_carpet} @@ -5122,13 +5253,6 @@ public final class ItemTypeKeys { */ public static final TypedKey MANGROVE_WOOD = create(key("mangrove_wood")); - /** - * {@code minecraft:medium_amethyst_bud} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey MEDIUM_AMETHYST_BUD = create(key("medium_amethyst_bud")); - /** * {@code minecraft:melon} * @@ -5164,20 +5288,6 @@ public final class ItemTypeKeys { */ public static final TypedKey MINECART = create(key("minecart")); - /** - * {@code minecraft:miner_pottery_sherd} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey MINER_POTTERY_SHERD = create(key("miner_pottery_sherd")); - - /** - * {@code minecraft:mojang_banner_pattern} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey MOJANG_BANNER_PATTERN = create(key("mojang_banner_pattern")); - /** * {@code minecraft:moss_block} * @@ -5248,13 +5358,6 @@ public final class ItemTypeKeys { */ public static final TypedKey MOSSY_STONE_BRICKS = create(key("mossy_stone_bricks")); - /** - * {@code minecraft:mourner_pottery_sherd} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey MOURNER_POTTERY_SHERD = create(key("mourner_pottery_sherd")); - /** * {@code minecraft:mud} * @@ -5829,6 +5932,13 @@ public final class ItemTypeKeys { */ public static final TypedKey ORANGE_BED = create(key("orange_bed")); + /** + * {@code minecraft:orange_bundle} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ORANGE_BUNDLE = create(key("orange_bundle")); + /** * {@code minecraft:orange_candle} * @@ -6004,6 +6114,186 @@ public final class ItemTypeKeys { */ public static final TypedKey PAINTING = create(key("painting")); + /** + * {@code minecraft:pale_hanging_moss} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_HANGING_MOSS = create(key("pale_hanging_moss")); + + /** + * {@code minecraft:pale_moss_block} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_MOSS_BLOCK = create(key("pale_moss_block")); + + /** + * {@code minecraft:pale_moss_carpet} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_MOSS_CARPET = create(key("pale_moss_carpet")); + + /** + * {@code minecraft:pale_oak_boat} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_BOAT = create(key("pale_oak_boat")); + + /** + * {@code minecraft:pale_oak_button} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_BUTTON = create(key("pale_oak_button")); + + /** + * {@code minecraft:pale_oak_chest_boat} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_CHEST_BOAT = create(key("pale_oak_chest_boat")); + + /** + * {@code minecraft:pale_oak_door} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_DOOR = create(key("pale_oak_door")); + + /** + * {@code minecraft:pale_oak_fence} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_FENCE = create(key("pale_oak_fence")); + + /** + * {@code minecraft:pale_oak_fence_gate} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_FENCE_GATE = create(key("pale_oak_fence_gate")); + + /** + * {@code minecraft:pale_oak_hanging_sign} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_HANGING_SIGN = create(key("pale_oak_hanging_sign")); + + /** + * {@code minecraft:pale_oak_leaves} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_LEAVES = create(key("pale_oak_leaves")); + + /** + * {@code minecraft:pale_oak_log} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_LOG = create(key("pale_oak_log")); + + /** + * {@code minecraft:pale_oak_planks} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_PLANKS = create(key("pale_oak_planks")); + + /** + * {@code minecraft:pale_oak_pressure_plate} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_PRESSURE_PLATE = create(key("pale_oak_pressure_plate")); + + /** + * {@code minecraft:pale_oak_sapling} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_SAPLING = create(key("pale_oak_sapling")); + + /** + * {@code minecraft:pale_oak_sign} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_SIGN = create(key("pale_oak_sign")); + + /** + * {@code minecraft:pale_oak_slab} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_SLAB = create(key("pale_oak_slab")); + + /** + * {@code minecraft:pale_oak_stairs} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_STAIRS = create(key("pale_oak_stairs")); + + /** + * {@code minecraft:pale_oak_trapdoor} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_TRAPDOOR = create(key("pale_oak_trapdoor")); + + /** + * {@code minecraft:pale_oak_wood} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey PALE_OAK_WOOD = create(key("pale_oak_wood")); + /** * {@code minecraft:panda_spawn_egg} * @@ -6116,6 +6406,13 @@ public final class ItemTypeKeys { */ public static final TypedKey PINK_BED = create(key("pink_bed")); + /** + * {@code minecraft:pink_bundle} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey PINK_BUNDLE = create(key("pink_bundle")); + /** * {@code minecraft:pink_candle} * @@ -6641,6 +6938,13 @@ public final class ItemTypeKeys { */ public static final TypedKey PURPLE_BED = create(key("purple_bed")); + /** + * {@code minecraft:purple_bundle} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey PURPLE_BUNDLE = create(key("purple_bundle")); + /** * {@code minecraft:purple_candle} * @@ -6907,6 +7211,13 @@ public final class ItemTypeKeys { */ public static final TypedKey RED_BED = create(key("red_bed")); + /** + * {@code minecraft:red_bundle} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey RED_BUNDLE = create(key("red_bundle")); + /** * {@code minecraft:red_candle} * @@ -8097,6 +8408,24 @@ public final class ItemTypeKeys { */ public static final TypedKey STRIPPED_OAK_WOOD = create(key("stripped_oak_wood")); + /** + * {@code minecraft:stripped_pale_oak_log} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey STRIPPED_PALE_OAK_LOG = create(key("stripped_pale_oak_log")); + + /** + * {@code minecraft:stripped_pale_oak_wood} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TypedKey STRIPPED_PALE_OAK_WOOD = create(key("stripped_pale_oak_wood")); + /** * {@code minecraft:stripped_spruce_log} * @@ -9028,6 +9357,13 @@ public final class ItemTypeKeys { */ public static final TypedKey WHITE_BED = create(key("white_bed")); + /** + * {@code minecraft:white_bundle} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey WHITE_BUNDLE = create(key("white_bundle")); + /** * {@code minecraft:white_candle} * @@ -9238,6 +9574,13 @@ public final class ItemTypeKeys { */ public static final TypedKey YELLOW_BED = create(key("yellow_bed")); + /** + * {@code minecraft:yellow_bundle} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey YELLOW_BUNDLE = create(key("yellow_bundle")); + /** * {@code minecraft:yellow_candle} * diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/JukeboxSongKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/JukeboxSongKeys.java index 4789b7e5717f..c001a5b46e1e 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/JukeboxSongKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/JukeboxSongKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class JukeboxSongKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java index 6aa67743ec97..ac4d4b0c6422 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class MapDecorationTypeKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/MenuTypeKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/MenuTypeKeys.java index 98e9563029f9..b2ad502cc91a 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/MenuTypeKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/MenuTypeKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class MenuTypeKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/MobEffectKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/MobEffectKeys.java index 621705fe8ade..d4f7f8372d05 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/MobEffectKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/MobEffectKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class MobEffectKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/StructureKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/StructureKeys.java index a49c8cff2eb0..902e04a8c98b 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/StructureKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/StructureKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class StructureKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/StructureTypeKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/StructureTypeKeys.java index 353c0fa3022e..5a2547a6a1f1 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/StructureTypeKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/StructureTypeKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class StructureTypeKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/TrimMaterialKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/TrimMaterialKeys.java index e75f850a3169..775ee696bc0c 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/TrimMaterialKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/TrimMaterialKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class TrimMaterialKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/TrimPatternKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/TrimPatternKeys.java index 65d2d63e8541..f136c6079c08 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/TrimPatternKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/TrimPatternKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class TrimPatternKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/VillagerProfessionKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/VillagerProfessionKeys.java index 6d8d0801bfab..9942699938d6 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/VillagerProfessionKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/VillagerProfessionKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class VillagerProfessionKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/VillagerTypeKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/VillagerTypeKeys.java index 524880dbaa44..f2033c1164d6 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/VillagerTypeKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/VillagerTypeKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class VillagerTypeKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/WolfVariantKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/WolfVariantKeys.java index 7108d41c8d1f..ab6358053532 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/WolfVariantKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/WolfVariantKeys.java @@ -23,7 +23,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class WolfVariantKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/EnchantmentTagKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/EnchantmentTagKeys.java index 5d2a22742f57..e1f25062d428 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/EnchantmentTagKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/EnchantmentTagKeys.java @@ -24,7 +24,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class EnchantmentTagKeys { /** diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/ItemTypeTagKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/ItemTypeTagKeys.java index b0a153f67010..8ec601a311ea 100644 --- a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/ItemTypeTagKeys.java +++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/ItemTypeTagKeys.java @@ -6,6 +6,7 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.tag.TagKey; import net.kyori.adventure.key.Key; +import org.bukkit.MinecraftExperimental; import org.bukkit.inventory.ItemType; import org.checkerframework.checker.nullness.qual.NonNull; import org.jetbrains.annotations.ApiStatus; @@ -23,7 +24,7 @@ "unused", "SpellCheckingInspection" }) -@GeneratedFrom("1.21.1") +@GeneratedFrom("1.21.3") @ApiStatus.Experimental public final class ItemTypeTagKeys { /** @@ -131,6 +132,20 @@ public final class ItemTypeTagKeys { */ public static final TagKey BREAKS_DECORATED_POTS = create(key("breaks_decorated_pots")); + /** + * {@code #minecraft:brewing_fuel} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey BREWING_FUEL = create(key("brewing_fuel")); + + /** + * {@code #minecraft:bundles} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey BUNDLES = create(key("bundles")); + /** * {@code #minecraft:buttons} * @@ -292,6 +307,13 @@ public final class ItemTypeTagKeys { */ public static final TagKey DIAMOND_ORES = create(key("diamond_ores")); + /** + * {@code #minecraft:diamond_tool_materials} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey DIAMOND_TOOL_MATERIALS = create(key("diamond_tool_materials")); + /** * {@code #minecraft:dirt} * @@ -306,6 +328,13 @@ public final class ItemTypeTagKeys { */ public static final TagKey DOORS = create(key("doors")); + /** + * {@code #minecraft:duplicates_allays} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey DUPLICATES_ALLAYS = create(key("duplicates_allays")); + /** * {@code #minecraft:dyeable} * @@ -509,6 +538,20 @@ public final class ItemTypeTagKeys { */ public static final TagKey FROG_FOOD = create(key("frog_food")); + /** + * {@code #minecraft:furnace_minecart_fuel} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey FURNACE_MINECART_FUEL = create(key("furnace_minecart_fuel")); + + /** + * {@code #minecraft:gaze_disguise_equipment} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey GAZE_DISGUISE_EQUIPMENT = create(key("gaze_disguise_equipment")); + /** * {@code #minecraft:goat_food} * @@ -523,6 +566,13 @@ public final class ItemTypeTagKeys { */ public static final TagKey GOLD_ORES = create(key("gold_ores")); + /** + * {@code #minecraft:gold_tool_materials} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey GOLD_TOOL_MATERIALS = create(key("gold_tool_materials")); + /** * {@code #minecraft:hanging_signs} * @@ -579,6 +629,13 @@ public final class ItemTypeTagKeys { */ public static final TagKey IRON_ORES = create(key("iron_ores")); + /** + * {@code #minecraft:iron_tool_materials} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey IRON_TOOL_MATERIALS = create(key("iron_tool_materials")); + /** * {@code #minecraft:jungle_logs} * @@ -649,6 +706,13 @@ public final class ItemTypeTagKeys { */ public static final TagKey MANGROVE_LOGS = create(key("mangrove_logs")); + /** + * {@code #minecraft:map_invisibility_equipment} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey MAP_INVISIBILITY_EQUIPMENT = create(key("map_invisibility_equipment")); + /** * {@code #minecraft:meat} * @@ -656,6 +720,13 @@ public final class ItemTypeTagKeys { */ public static final TagKey MEAT = create(key("meat")); + /** + * {@code #minecraft:netherite_tool_materials} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey NETHERITE_TOOL_MATERIALS = create(key("netherite_tool_materials")); + /** * {@code #minecraft:non_flammable_wood} * @@ -684,6 +755,22 @@ public final class ItemTypeTagKeys { */ public static final TagKey OCELOT_FOOD = create(key("ocelot_food")); + /** + * {@code #minecraft:pale_oak_logs} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + @ApiStatus.Experimental + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) + public static final TagKey PALE_OAK_LOGS = create(key("pale_oak_logs")); + + /** + * {@code #minecraft:panda_eats_from_ground} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey PANDA_EATS_FROM_GROUND = create(key("panda_eats_from_ground")); + /** * {@code #minecraft:panda_food} * @@ -740,6 +827,13 @@ public final class ItemTypeTagKeys { */ public static final TagKey PIGLIN_REPELLENTS = create(key("piglin_repellents")); + /** + * {@code #minecraft:piglin_safe_armor} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey PIGLIN_SAFE_ARMOR = create(key("piglin_safe_armor")); + /** * {@code #minecraft:planks} * @@ -768,6 +862,62 @@ public final class ItemTypeTagKeys { */ public static final TagKey REDSTONE_ORES = create(key("redstone_ores")); + /** + * {@code #minecraft:repairs_chain_armor} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey REPAIRS_CHAIN_ARMOR = create(key("repairs_chain_armor")); + + /** + * {@code #minecraft:repairs_diamond_armor} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey REPAIRS_DIAMOND_ARMOR = create(key("repairs_diamond_armor")); + + /** + * {@code #minecraft:repairs_gold_armor} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey REPAIRS_GOLD_ARMOR = create(key("repairs_gold_armor")); + + /** + * {@code #minecraft:repairs_iron_armor} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey REPAIRS_IRON_ARMOR = create(key("repairs_iron_armor")); + + /** + * {@code #minecraft:repairs_leather_armor} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey REPAIRS_LEATHER_ARMOR = create(key("repairs_leather_armor")); + + /** + * {@code #minecraft:repairs_netherite_armor} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey REPAIRS_NETHERITE_ARMOR = create(key("repairs_netherite_armor")); + + /** + * {@code #minecraft:repairs_turtle_helmet} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey REPAIRS_TURTLE_HELMET = create(key("repairs_turtle_helmet")); + + /** + * {@code #minecraft:repairs_wolf_armor} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey REPAIRS_WOLF_ARMOR = create(key("repairs_wolf_armor")); + /** * {@code #minecraft:sand} * @@ -796,6 +946,13 @@ public final class ItemTypeTagKeys { */ public static final TagKey SHOVELS = create(key("shovels")); + /** + * {@code #minecraft:shulker_boxes} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey SHULKER_BOXES = create(key("shulker_boxes")); + /** * {@code #minecraft:signs} * @@ -957,6 +1114,13 @@ public final class ItemTypeTagKeys { */ public static final TagKey TURTLE_FOOD = create(key("turtle_food")); + /** + * {@code #minecraft:villager_picks_up} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey VILLAGER_PICKS_UP = create(key("villager_picks_up")); + /** * {@code #minecraft:villager_plantable_seeds} * @@ -1034,6 +1198,13 @@ public final class ItemTypeTagKeys { */ public static final TagKey WOODEN_STAIRS = create(key("wooden_stairs")); + /** + * {@code #minecraft:wooden_tool_materials} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey WOODEN_TOOL_MATERIALS = create(key("wooden_tool_materials")); + /** * {@code #minecraft:wooden_trapdoors} * diff --git a/paper-api-generator/src/main/java/io/papermc/generator/Main.java b/paper-api-generator/src/main/java/io/papermc/generator/Main.java index bec7a0c37362..129009f519f1 100644 --- a/paper-api-generator/src/main/java/io/papermc/generator/Main.java +++ b/paper-api-generator/src/main/java/io/papermc/generator/Main.java @@ -7,22 +7,25 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.List; import java.util.Map; import net.minecraft.SharedConstants; import net.minecraft.commands.Commands; +import net.minecraft.core.HolderLookup; import net.minecraft.core.LayeredRegistryAccess; +import net.minecraft.core.Registry; import net.minecraft.core.RegistryAccess; import net.minecraft.resources.RegistryDataLoader; import net.minecraft.server.Bootstrap; import net.minecraft.server.RegistryLayer; import net.minecraft.server.ReloadableServerResources; -import net.minecraft.server.WorldLoader; import net.minecraft.server.packs.PackType; import net.minecraft.server.packs.repository.Pack; import net.minecraft.server.packs.repository.PackRepository; import net.minecraft.server.packs.repository.ServerPacksSource; import net.minecraft.server.packs.resources.MultiPackResourceManager; import net.minecraft.tags.TagKey; +import net.minecraft.tags.TagLoader; import net.minecraft.world.flag.FeatureFlags; import org.apache.commons.io.file.PathUtils; import org.slf4j.Logger; @@ -42,11 +45,22 @@ public final class Main { resourceRepository.reload(); final MultiPackResourceManager resourceManager = new MultiPackResourceManager(PackType.SERVER_DATA, resourceRepository.getAvailablePacks().stream().map(Pack::open).toList()); LayeredRegistryAccess layers = RegistryLayer.createRegistryAccess(); - layers = WorldLoader.loadAndReplaceLayer(resourceManager, layers, RegistryLayer.WORLDGEN, RegistryDataLoader.WORLDGEN_REGISTRIES); + final List> pendingTags = TagLoader.loadTagsForExistingRegistries(resourceManager, layers.getLayer(RegistryLayer.STATIC)); + final List> worldGenLayer = TagLoader.buildUpdatedLookups(layers.getAccessForLoading(RegistryLayer.WORLDGEN), pendingTags); + final RegistryAccess.Frozen frozenWorldgenRegistries = RegistryDataLoader.load(resourceManager, worldGenLayer, RegistryDataLoader.WORLDGEN_REGISTRIES); + layers = layers.replaceFrom(RegistryLayer.WORLDGEN, frozenWorldgenRegistries); REGISTRY_ACCESS = layers.compositeAccess().freeze(); - final ReloadableServerResources datapack = ReloadableServerResources.loadResources(resourceManager, layers, FeatureFlags.REGISTRY.allFlags(), Commands.CommandSelection.DEDICATED, 0, MoreExecutors.directExecutor(), MoreExecutors.directExecutor()).join(); - datapack.updateRegistryTags(); - + final ReloadableServerResources reloadableServerResources = ReloadableServerResources.loadResources( + resourceManager, + layers, + pendingTags, + FeatureFlags.VANILLA_SET, + Commands.CommandSelection.DEDICATED, + 0, + MoreExecutors.directExecutor(), + MoreExecutors.directExecutor() + ).join(); + reloadableServerResources.updateStaticRegistryTags(); EXPERIMENTAL_TAGS = TagCollector.grabExperimental(resourceManager); } diff --git a/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedKeyType.java b/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedKeyType.java index cf6846134a57..54ed67b2b7bf 100644 --- a/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedKeyType.java +++ b/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedKeyType.java @@ -23,14 +23,19 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import javax.lang.model.SourceVersion; import net.kyori.adventure.key.Key; import net.minecraft.core.Holder; import net.minecraft.core.HolderLookup; import net.minecraft.core.Registry; import net.minecraft.core.RegistrySetBuilder; +import net.minecraft.core.registries.Registries; import net.minecraft.data.registries.VanillaRegistries; +import net.minecraft.data.registries.WinterDropRegistries; import net.minecraft.resources.ResourceKey; import net.minecraft.world.flag.FeatureElement; +import net.minecraft.world.flag.FeatureFlags; +import org.bukkit.MinecraftExperimental; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.framework.qual.DefaultQualifier; @@ -51,7 +56,8 @@ public class GeneratedKeyType extends SimpleGenerator { private static final Map>, RegistrySetBuilder.RegistryBootstrap> VANILLA_REGISTRY_ENTRIES = VanillaRegistries.BUILDER.entries.stream() .collect(Collectors.toMap(RegistrySetBuilder.RegistryStub::key, RegistrySetBuilder.RegistryStub::bootstrap)); - private static final Map>, RegistrySetBuilder.RegistryBootstrap> EXPERIMENTAL_REGISTRY_ENTRIES = Collections.emptyMap(); // Update for Experimental API + private static final Map>, RegistrySetBuilder.RegistryBootstrap> EXPERIMENTAL_REGISTRY_ENTRIES = WinterDropRegistries.BUILDER.entries.stream() + .collect(Collectors.toMap(RegistrySetBuilder.RegistryStub::key, RegistrySetBuilder.RegistryStub::bootstrap)); // Update for Experimental API private static final Map, String> REGISTRY_KEY_FIELD_NAMES; static { @@ -116,6 +122,13 @@ private TypeSpec.Builder keyHolderType() { ); } + @Deprecated + private static final Map JUKEBOX_SONG_NAMES = Map.of( + "5", "FIVE", + "11", "ELEVEN", + "13", "THIRTEEN" + ); + @Override protected TypeSpec getTypeSpec() { final TypeName typedKey = ParameterizedTypeName.get(TypedKey.class, this.apiType); @@ -123,19 +136,23 @@ protected TypeSpec getTypeSpec() { final TypeSpec.Builder typeBuilder = this.keyHolderType(); final MethodSpec.Builder createMethod = this.createMethod(typedKey); - final Registry registry = Main.REGISTRY_ACCESS.registryOrThrow(this.registryKey); + final Registry registry = Main.REGISTRY_ACCESS.lookupOrThrow(this.registryKey); final Set> experimental = this.collectExperimentalKeys(registry); boolean allExperimental = true; - for (final Holder.Reference reference : registry.holders().sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath())).toList()) { + for (final Holder.Reference reference : registry.listElements().sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath())).toList()) { final ResourceKey key = reference.key(); final String keyPath = key.location().getPath(); - final String fieldName = Formatting.formatKeyAsField(keyPath); + String fieldName = Formatting.formatKeyAsField(keyPath); + if (!SourceVersion.isIdentifier(fieldName) && this.registryKey.equals(Registries.JUKEBOX_SONG) && JUKEBOX_SONG_NAMES.containsKey(fieldName)) { + fieldName = JUKEBOX_SONG_NAMES.get(fieldName); + } + final FieldSpec.Builder fieldBuilder = FieldSpec.builder(typedKey, fieldName, PUBLIC, STATIC, FINAL) .initializer("$N(key($S))", createMethod.build(), keyPath) .addJavadoc(Javadocs.getVersionDependentField("{@code $L}"), key.location().toString()); if (experimental.contains(key)) { - fieldBuilder.addAnnotations(experimentalAnnotations(null)); // Update for Experimental API + fieldBuilder.addAnnotations(experimentalAnnotations(MinecraftExperimental.Requires.WINTER_DROP)); // Update for Experimental API } else { allExperimental = false; } @@ -150,6 +167,7 @@ protected TypeSpec getTypeSpec() { return typeBuilder.addMethod(createMethod.build()).build(); } + // todo at some point this should be per feature data pack not all merged private Set> collectExperimentalKeys(final Registry registry) { if (FeatureElement.FILTERED_REGISTRIES.contains(registry.key())) { return this.collectExperimentalKeysBuiltIn(registry); @@ -159,8 +177,8 @@ private Set> collectExperimentalKeys(final Registry registry) } private Set> collectExperimentalKeysBuiltIn(final Registry registry) { - final HolderLookup.RegistryLookup filteredLookup = registry.asLookup().filterElements(v -> { - return false; // Update for Experimental API + final HolderLookup.RegistryLookup filteredLookup = registry.filterElements(v -> { + return v instanceof final FeatureElement featureElement && FeatureFlags.isExperimental(featureElement.requiredFeatures()); // Update for Experimental API }); return filteredLookup.listElementIds().collect(Collectors.toUnmodifiableSet()); } diff --git a/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedTagKeyType.java b/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedTagKeyType.java index ff8d8b612c37..446611a45dd6 100644 --- a/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedTagKeyType.java +++ b/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedTagKeyType.java @@ -16,6 +16,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import net.kyori.adventure.key.Key; @@ -105,16 +106,17 @@ protected TypeSpec getTypeSpec() { final TypeSpec.Builder typeBuilder = this.keyHolderType(); final MethodSpec.Builder createMethod = this.createMethod(tagKey); - final Registry registry = Main.REGISTRY_ACCESS.registryOrThrow(this.registryKey); + final Registry registry = Main.REGISTRY_ACCESS.lookupOrThrow(this.registryKey); final AtomicBoolean allExperimental = new AtomicBoolean(true); - registry.getTagNames().sorted(Formatting.alphabeticKeyOrder(nmsTagKey -> nmsTagKey.location().getPath())).forEach(nmsTagKey -> { + registry.listTagIds().sorted(Formatting.alphabeticKeyOrder(nmsTagKey -> nmsTagKey.location().getPath())).forEach(nmsTagKey -> { final String fieldName = Formatting.formatKeyAsField(nmsTagKey.location().getPath()); final FieldSpec.Builder fieldBuilder = FieldSpec.builder(tagKey, fieldName, PUBLIC, STATIC, FINAL) .initializer("$N(key($S))", createMethod.build(), nmsTagKey.location().getPath()) .addJavadoc(Javadocs.getVersionDependentField("{@code $L}"), "#" + nmsTagKey.location()); - if (Main.EXPERIMENTAL_TAGS.containsKey(nmsTagKey)) { - fieldBuilder.addAnnotations(experimentalAnnotations(MinecraftExperimental.Requires.TRADE_REBALANCE)); // Update for Experimental API + final String featureFlagName = Main.EXPERIMENTAL_TAGS.get(nmsTagKey); + if (featureFlagName != null) { + fieldBuilder.addAnnotations(experimentalAnnotations(MinecraftExperimental.Requires.valueOf(featureFlagName.toUpperCase(Locale.ENGLISH)))); // Update for Experimental API } else { allExperimental.set(false); } diff --git a/paper-api-generator/src/main/java/io/papermc/generator/types/SimpleGenerator.java b/paper-api-generator/src/main/java/io/papermc/generator/types/SimpleGenerator.java index b4c1095c84aa..3608b449f821 100644 --- a/paper-api-generator/src/main/java/io/papermc/generator/types/SimpleGenerator.java +++ b/paper-api-generator/src/main/java/io/papermc/generator/types/SimpleGenerator.java @@ -31,5 +31,4 @@ public void writeToFile(Path parent) throws IOException { builder.build().writeTo(parent, StandardCharsets.UTF_8); } - } diff --git a/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalGenerator.java b/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalGenerator.java index ffe3c485724a..86e2294ae7d0 100644 --- a/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalGenerator.java +++ b/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalGenerator.java @@ -1,6 +1,5 @@ package io.papermc.generator.types.goal; -import com.destroystokyo.paper.entity.RangedEntity; import com.destroystokyo.paper.entity.ai.GoalKey; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.FieldSpec; @@ -19,44 +18,10 @@ import io.papermc.generator.utils.Javadocs; import java.util.Comparator; import java.util.List; -import javax.lang.model.element.Modifier; import net.minecraft.world.entity.ai.goal.Goal; import net.minecraft.world.entity.ai.goal.WrappedGoal; import org.bukkit.NamespacedKey; -import org.bukkit.entity.AbstractHorse; -import org.bukkit.entity.Blaze; -import org.bukkit.entity.Cat; -import org.bukkit.entity.Creature; -import org.bukkit.entity.Dolphin; -import org.bukkit.entity.Drowned; -import org.bukkit.entity.Enderman; -import org.bukkit.entity.Evoker; -import org.bukkit.entity.Fish; -import org.bukkit.entity.Fox; -import org.bukkit.entity.Ghast; -import org.bukkit.entity.Llama; import org.bukkit.entity.Mob; -import org.bukkit.entity.Monster; -import org.bukkit.entity.Panda; -import org.bukkit.entity.Parrot; -import org.bukkit.entity.PigZombie; -import org.bukkit.entity.PolarBear; -import org.bukkit.entity.Rabbit; -import org.bukkit.entity.Raider; -import org.bukkit.entity.Ravager; -import org.bukkit.entity.Shulker; -import org.bukkit.entity.Silverfish; -import org.bukkit.entity.SkeletonHorse; -import org.bukkit.entity.Slime; -import org.bukkit.entity.Spellcaster; -import org.bukkit.entity.Spider; -import org.bukkit.entity.Squid; -import org.bukkit.entity.Tameable; -import org.bukkit.entity.TraderLlama; -import org.bukkit.entity.Turtle; -import org.bukkit.entity.Vex; -import org.bukkit.entity.Vindicator; -import org.bukkit.entity.WanderingTrader; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.framework.qual.DefaultQualifier; import org.jetbrains.annotations.Nullable; @@ -134,10 +99,4 @@ protected TypeSpec getTypeSpec() { protected JavaFile.Builder file(JavaFile.Builder builder) { return builder; } - - record DeprecatedEntry(Class entity, String entryName, @Nullable String removalVersion, - @Nullable String removedVersion) { - - } - } diff --git a/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalNames.java b/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalNames.java index 1bd6342f6191..07c6d5071972 100644 --- a/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalNames.java +++ b/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalNames.java @@ -236,6 +236,9 @@ public class MobGoalNames { bukkitMap.put(net.minecraft.world.entity.monster.breeze.Breeze.class, org.bukkit.entity.Breeze.class); bukkitMap.put(net.minecraft.world.entity.animal.armadillo.Armadillo.class, org.bukkit.entity.Armadillo.class); bukkitMap.put(net.minecraft.world.entity.monster.Bogged.class, org.bukkit.entity.Bogged.class); + bukkitMap.put(net.minecraft.world.entity.monster.creaking.Creaking.class, org.bukkit.entity.Creaking.class); + bukkitMap.put(net.minecraft.world.entity.monster.creaking.CreakingTransient.class, org.bukkit.entity.CreakingTransient.class); + bukkitMap.put(net.minecraft.world.entity.animal.AgeableWaterCreature.class, org.bukkit.entity.Squid.class); // close enough // } @@ -268,6 +271,7 @@ public static String getUsableName(String name) { name = cut; } } + name = name.replace("PathfinderGoal", ""); name = name.replace("TargetGoal", ""); name = name.replace("Goal", ""); diff --git a/paper-api-generator/src/main/java/io/papermc/generator/utils/CollectingContext.java b/paper-api-generator/src/main/java/io/papermc/generator/utils/CollectingContext.java index bb0687aa24dd..c2fbaa2a0518 100644 --- a/paper-api-generator/src/main/java/io/papermc/generator/utils/CollectingContext.java +++ b/paper-api-generator/src/main/java/io/papermc/generator/utils/CollectingContext.java @@ -18,11 +18,11 @@ public record CollectingContext(Set> registered, @Override public Holder.Reference register(final ResourceKey resourceKey, final @NonNull T t, final Lifecycle lifecycle) { this.registered.add(resourceKey); - return Holder.Reference.createStandAlone(this.registry.holderOwner(), resourceKey); + return Holder.Reference.createStandAlone(this.registry, resourceKey); } @Override public HolderGetter lookup(final ResourceKey> resourceKey) { - return Main.REGISTRY_ACCESS.registryOrThrow(resourceKey).asLookup(); + return Main.REGISTRY_ACCESS.lookupOrThrow(resourceKey); } } diff --git a/paper-api-generator/src/main/java/io/papermc/generator/utils/Formatting.java b/paper-api-generator/src/main/java/io/papermc/generator/utils/Formatting.java index 0006e07c53ab..b703a32455b3 100644 --- a/paper-api-generator/src/main/java/io/papermc/generator/utils/Formatting.java +++ b/paper-api-generator/src/main/java/io/papermc/generator/utils/Formatting.java @@ -1,6 +1,5 @@ package io.papermc.generator.utils; -import java.util.Map; import java.util.Optional; import org.apache.commons.lang3.math.NumberUtils; import java.util.Comparator; @@ -13,13 +12,8 @@ public final class Formatting { private static final Pattern ILLEGAL_FIELD_CHARACTERS = Pattern.compile("[.-/]"); - private static final Map MANUAL_OVERRIDES = Map.of( - "5", "five", - "11", "eleven", - "13", "thirteen" - ); public static String formatKeyAsField(String path) { - return ILLEGAL_FIELD_CHARACTERS.matcher(MANUAL_OVERRIDES.getOrDefault(path, path).toUpperCase(Locale.ROOT)).replaceAll("_"); + return ILLEGAL_FIELD_CHARACTERS.matcher(path.toUpperCase(Locale.ROOT)).replaceAll("_"); } public static Optional formatTagKey(String tagDir, String resourcePath) { diff --git a/paper-api-generator/src/main/java/io/papermc/generator/utils/TagCollector.java b/paper-api-generator/src/main/java/io/papermc/generator/utils/TagCollector.java index 2c537dba939c..546e136b4a74 100644 --- a/paper-api-generator/src/main/java/io/papermc/generator/utils/TagCollector.java +++ b/paper-api-generator/src/main/java/io/papermc/generator/utils/TagCollector.java @@ -47,7 +47,7 @@ public static Map, String> grabExperimental(final MultiPackResourceMan return; } - result.put(entry.value().getTagNames() + result.put(entry.value().listTagIds() .filter(tagKey -> tagKey.location().getPath().equals(path)) .findFirst() .orElseThrow(), packId); diff --git a/paper-api-generator/wideners.at b/paper-api-generator/wideners.at index 6928316973df..60a5d241e7a6 100644 --- a/paper-api-generator/wideners.at +++ b/paper-api-generator/wideners.at @@ -3,5 +3,6 @@ public net/minecraft/server/WorldLoader loadAndReplaceLayer(Lnet/minecraft/serve # for auto-marking experimental stuff public net/minecraft/core/RegistrySetBuilder entries public net/minecraft/core/RegistrySetBuilder$RegistryStub -public net/minecraft/data/registries/UpdateOneTwentyOneRegistries BUILDER public net/minecraft/data/registries/VanillaRegistries BUILDER +public net/minecraft/data/registries/WinterDropRegistries BUILDER +public net/minecraft/data/registries/TradeRebalanceRegistries BUILDER diff --git a/patches/api/0004-Code-Generation.patch b/patches/api/0004-Code-Generation.patch index a53a0638102c..cc7000b9c682 100644 --- a/patches/api/0004-Code-Generation.patch +++ b/patches/api/0004-Code-Generation.patch @@ -366,13 +366,17 @@ index 0000000000000000000000000000000000000000..99375deaa6b90b33cd6a77e0df651236 +record TypedKeyImpl(Key key, RegistryKey registryKey) implements TypedKey { +} diff --git a/src/main/java/org/bukkit/MinecraftExperimental.java b/src/main/java/org/bukkit/MinecraftExperimental.java -index b7845523e8587e13b86516c0012fe097d904846c..765a691f5b4f91425bb3057ceb4bbff06c6df1e8 100644 +index b7845523e8587e13b86516c0012fe097d904846c..d92a75f610cb2a95203b3f22dc67bdbfb5c3405a 100644 --- a/src/main/java/org/bukkit/MinecraftExperimental.java +++ b/src/main/java/org/bukkit/MinecraftExperimental.java -@@ -48,5 +48,6 @@ public @interface MinecraftExperimental { +@@ -48,5 +48,10 @@ public @interface MinecraftExperimental { public enum Requires { WINTER_DROP, -+ TRADE_REBALANCE // Paper ++ // Paper start ++ TRADE_REBALANCE, ++ REDSTONE_EXPERIMENTS, ++ MINECART_IMPROVEMENTS ++ // Paper end } } diff --git a/patches/api/0427-Experimental-annotations-change.patch b/patches/api/0427-Experimental-annotations-change.patch index 9c079b178f05..5660d684cebf 100644 --- a/patches/api/0427-Experimental-annotations-change.patch +++ b/patches/api/0427-Experimental-annotations-change.patch @@ -30,6 +30,19 @@ index a96600443a0997c3a696a637422ab66ee1884fb0..20eb27ee041f77f295eb271f878c524c public static final FeatureFlag MINECART_IMPROVEMENTS = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("minecart_improvements")); } +diff --git a/src/main/java/org/bukkit/GameRule.java b/src/main/java/org/bukkit/GameRule.java +index 8b6584fae0a9d5cccbe350d889fa8b4a14c78ca3..89f1820ae94c48f51a44df750904bb285013720c 100644 +--- a/src/main/java/org/bukkit/GameRule.java ++++ b/src/main/java/org/bukkit/GameRule.java +@@ -287,6 +287,8 @@ public final class GameRule implements net.kyori.adventure.translation.Transl + * The maximum speed of minecarts (when the new movement algorithm is + * enabled). + */ ++ @MinecraftExperimental(MinecraftExperimental.Requires.MINECART_IMPROVEMENTS) // Paper - add missing annotation ++ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation + public static final GameRule MINECART_MAX_SPEED = new GameRule<>("minecartMaxSpeed", Integer.class); + + /** diff --git a/src/main/java/org/bukkit/block/Crafter.java b/src/main/java/org/bukkit/block/Crafter.java index 8d2dd78fc588a6817dfede8040b9909a7d5bde67..f737a2aae3f57a1bfe4cf68ea66f603da4eebd47 100644 --- a/src/main/java/org/bukkit/block/Crafter.java diff --git a/patches/server/0350-Implement-Mob-Goal-API.patch b/patches/server/0350-Implement-Mob-Goal-API.patch index 0c648f76d45b..445aa535d1fe 100644 --- a/patches/server/0350-Implement-Mob-Goal-API.patch +++ b/patches/server/0350-Implement-Mob-Goal-API.patch @@ -18,10 +18,10 @@ index da2f9c5afb2994f403a1128af0f7acbd6b73b862..38585b7f0b8e1e287b37820924a1b0d4 testImplementation("org.hamcrest:hamcrest:2.2") diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java new file mode 100644 -index 0000000000000000000000000000000000000000..c99eafab2103c7f5bca7ffba68a10bd853df055f +index 0000000000000000000000000000000000000000..05e793e722bbb367ca64cd7f26156fa3dabb8474 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java -@@ -0,0 +1,377 @@ +@@ -0,0 +1,380 @@ +package com.destroystokyo.paper.entity.ai; + +import com.destroystokyo.paper.entity.RangedEntity; @@ -271,6 +271,9 @@ index 0000000000000000000000000000000000000000..c99eafab2103c7f5bca7ffba68a10bd8 + bukkitMap.put(Breeze.class, org.bukkit.entity.Breeze.class); + bukkitMap.put(net.minecraft.world.entity.animal.armadillo.Armadillo.class, org.bukkit.entity.Armadillo.class); + bukkitMap.put(net.minecraft.world.entity.monster.Bogged.class, org.bukkit.entity.Bogged.class); ++ bukkitMap.put(net.minecraft.world.entity.monster.creaking.Creaking.class, org.bukkit.entity.Creaking.class); ++ bukkitMap.put(net.minecraft.world.entity.monster.creaking.CreakingTransient.class, org.bukkit.entity.CreakingTransient.class); ++ bukkitMap.put(net.minecraft.world.entity.animal.AgeableWaterCreature.class, org.bukkit.entity.Squid.class); // close enough + } + + public static String getUsableName(Class clazz) { diff --git a/patches/server/0553-Missing-Entity-API.patch b/patches/server/0553-Missing-Entity-API.patch index b583f5319160..64f88445fb30 100644 --- a/patches/server/0553-Missing-Entity-API.patch +++ b/patches/server/0553-Missing-Entity-API.patch @@ -45,7 +45,7 @@ Co-authored-by: maxcom1 <46265094+maxcom1@users.noreply.github.com> Co-authored-by: TotalledZebra diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java -index c99eafab2103c7f5bca7ffba68a10bd853df055f..f7241c5292f1c012404eea11256813fbc2c2df1a 100644 +index 05e793e722bbb367ca64cd7f26156fa3dabb8474..3470720466fc81f977c18e3a97bb918926025a22 100644 --- a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java +++ b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java @@ -164,7 +164,7 @@ public class MobGoalHelper { From 20507b45cf23941272020f71dce5763ce53e6409 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Sat, 26 Oct 2024 17:49:28 +0200 Subject: [PATCH 089/119] Apply more patches --- ...44-Entity-load-save-limit-per-chunk.patch} | 16 +-- ...ulate-regionfile-header-if-it-is-co.patch} | 112 +++++++++--------- .../1046-Bundle-spark.patch} | 38 +++--- 3 files changed, 83 insertions(+), 83 deletions(-) rename patches/{unapplied/server/1000-Entity-load-save-limit-per-chunk.patch => server/1044-Entity-load-save-limit-per-chunk.patch} (88%) rename patches/{unapplied/server/1031-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch => server/1045-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch} (90%) rename patches/{unapplied/server/1032-Bundle-spark.patch => server/1046-Bundle-spark.patch} (93%) diff --git a/patches/unapplied/server/1000-Entity-load-save-limit-per-chunk.patch b/patches/server/1044-Entity-load-save-limit-per-chunk.patch similarity index 88% rename from patches/unapplied/server/1000-Entity-load-save-limit-per-chunk.patch rename to patches/server/1044-Entity-load-save-limit-per-chunk.patch index 9a5959e34ff9..0b3fc48e435d 100644 --- a/patches/unapplied/server/1000-Entity-load-save-limit-per-chunk.patch +++ b/patches/server/1044-Entity-load-save-limit-per-chunk.patch @@ -9,15 +9,15 @@ defaults are only included for certain entites, this allows setting limits for any entity type. diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -index 997b05167c19472acb98edac32d4548cc65efa8e..5c7f2471a0b15ac2e714527296ad2aa7291999eb 100644 +index 5ed6599d1f9a2edf8c904f3602b06d26d857600c..b3c993a790fc3fab6a408c731deb297f74c959ce 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -@@ -100,7 +100,18 @@ public final class ChunkEntitySlices { +@@ -104,7 +104,18 @@ public final class ChunkEntitySlices { } final ListTag entitiesTag = new ListTag(); + final java.util.Map, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk - for (final Entity entity : entities) { + for (final Entity entity : PlatformHooks.get().modifySavedEntities(world, chunkPos.x, chunkPos.z, entities)) { + // Paper start - Entity load/save limit per chunk + final EntityType entityType = entity.getType(); + final int saveLimit = world.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1); @@ -32,17 +32,17 @@ index 997b05167c19472acb98edac32d4548cc65efa8e..5c7f2471a0b15ac2e714527296ad2aa7 if (entity.save(compoundTag)) { entitiesTag.add(compoundTag); diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 842b0cec0397d7ae5166617627340ffac0e35db1..cb61462d4691a055a4b25f7b953609d8a154fdfe 100644 +index e56050bef4a5aaa0fca17192dab4cf5e6a55fbae..3a8af3c6164da68eac0faeb436b8d9d8159fd4bd 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -649,9 +649,20 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -715,9 +715,20 @@ public class EntityType implements FeatureElement, EntityTypeT final Spliterator spliterator = entityNbtList.spliterator(); return StreamSupport.stream(new Spliterator() { + final java.util.Map, Integer> loadedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk public boolean tryAdvance(Consumer consumer) { return spliterator.tryAdvance((nbtbase) -> { - EntityType.loadEntityRecursive((CompoundTag) nbtbase, world, (entity) -> { + EntityType.loadEntityRecursive((CompoundTag) nbtbase, world, reason, (entity) -> { + // Paper start - Entity load/save limit per chunk + final EntityType entityType = entity.getType(); + final int saveLimit = world.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1); @@ -57,10 +57,10 @@ index 842b0cec0397d7ae5166617627340ffac0e35db1..cb61462d4691a055a4b25f7b953609d8 return entity; }); diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java -index 503ac0374e0c9f9993ad37bb8bd8cf1570d3615a..d4a505ef4af9ded02aeb1a817bcbe5b1a912a5b3 100644 +index 16ca1c8672e5f0a27f8a30498c754a81cdec5191..356d010506fd21f3c752e4aa86c46c1106fdde3b 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java -@@ -92,7 +92,18 @@ public class EntityStorage implements EntityPersistentStorage { +@@ -93,7 +93,18 @@ public class EntityStorage implements EntityPersistentStorage { } } else { ListTag listTag = new ListTag(); diff --git a/patches/unapplied/server/1031-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch b/patches/server/1045-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch similarity index 90% rename from patches/unapplied/server/1031-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch rename to patches/server/1045-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch index 114443675bc2..5c2ab9cfcd9a 100644 --- a/patches/unapplied/server/1031-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch +++ b/patches/server/1045-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch @@ -9,38 +9,6 @@ we instead drop the current regionfile header and recalculate - hoping that at least then we don't swap chunks, and maybe recover them all. -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index 711541a9b12b823c1da779ed6027a53e9078a733..4bd048387651250135f963303c78c17f8473cfee 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -@@ -72,6 +72,18 @@ import net.minecraft.world.ticks.ProtoChunkTicks; - import org.slf4j.Logger; - - public class ChunkSerializer { -+ // Paper start - Attempt to recalculate regionfile header if it is corrupt -+ // TODO: Check on update -+ public static long getLastWorldSaveTime(CompoundTag chunkData) { -+ final int dataVersion = ChunkStorage.getVersion(chunkData); -+ if (dataVersion < 2842) { // Level tag is removed after this version -+ final CompoundTag levelData = chunkData.getCompound("Level"); -+ return levelData.getLong("LastUpdate"); -+ } else { -+ return chunkData.getLong("LastUpdate"); -+ } -+ } -+ // Paper end - Attempt to recalculate regionfile header if it is corrupt - - public static final Codec> BLOCK_STATE_CODEC = PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), null); // Paper - Anti-Xray - Add preset block states - private static final Logger LOGGER = LogUtils.getLogger(); -@@ -384,7 +396,7 @@ public class ChunkSerializer { - nbttagcompound.putInt("xPos", chunkcoordintpair.x); - nbttagcompound.putInt("yPos", chunk.getMinSection()); - nbttagcompound.putInt("zPos", chunkcoordintpair.z); -- nbttagcompound.putLong("LastUpdate", asyncsavedata != null ? asyncsavedata.worldTime() : world.getGameTime()); // Paper - async chunk saving -+ nbttagcompound.putLong("LastUpdate", asyncsavedata != null ? asyncsavedata.worldTime() : world.getGameTime()); // Paper - async chunk saving // Paper - diff on change - nbttagcompound.putLong("InhabitedTime", chunk.getInhabitedTime()); - nbttagcompound.putString("Status", BuiltInRegistries.CHUNK_STATUS.getKey(chunk.getPersistedStatus()).toString()); - BlendingData blendingdata = chunk.getBlendingData(); diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionBitmap.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionBitmap.java index a23dc2f8f4475de1ee35bf18a7a8a53233ccac12..226af44fd469053451a0403a95ffb446face9530 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionBitmap.java @@ -74,10 +42,10 @@ index a23dc2f8f4475de1ee35bf18a7a8a53233ccac12..226af44fd469053451a0403a95ffb446 this.used.set(start, start + size); } 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 e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..1e0439cf3f4008fa430acb90b45f5bc4cdd6d7f2 100644 +index e9e1ab1a5be996bc648a53dc4d4123a6b966c437..6a465d9b12c92b5385c394fef7456630be97c04d 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 -@@ -51,6 +51,354 @@ public class RegionFile implements AutoCloseable { +@@ -51,6 +51,354 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche private final IntBuffer timestamps; @VisibleForTesting protected final RegionBitmap usedSectors; @@ -191,7 +159,7 @@ index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..1e0439cf3f4008fa430acb90b45f5bc4 + continue; + } + -+ ChunkPos chunkPos = ChunkSerializer.getChunkCoordinate(compound); ++ ChunkPos chunkPos = SerializableChunkData.getChunkCoordinate(compound); + if (!inSameRegionfile(ourLowerLeftPosition, chunkPos)) { + LOGGER.error("Ignoring absolute chunk " + chunkPos + " in regionfile as it is not contained in the bounds of the regionfile '" + this.path.toAbsolutePath() + "'. It should be in regionfile (" + (chunkPos.x >> 5) + "," + (chunkPos.z >> 5) + ")"); + continue; @@ -200,7 +168,7 @@ index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..1e0439cf3f4008fa430acb90b45f5bc4 + + CompoundTag otherCompound = compounds[location]; + -+ if (otherCompound != null && ChunkSerializer.getLastWorldSaveTime(otherCompound) > ChunkSerializer.getLastWorldSaveTime(compound)) { ++ if (otherCompound != null && SerializableChunkData.getLastWorldSaveTime(otherCompound) > SerializableChunkData.getLastWorldSaveTime(compound)) { + continue; // don't overwrite newer data. + } + @@ -210,7 +178,7 @@ index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..1e0439cf3f4008fa430acb90b45f5bc4 + if (Files.exists(aikarOversizedFile)) { + try { + CompoundTag aikarOversizedCompound = this.getOversizedData(chunkPos.x, chunkPos.z); -+ if (ChunkSerializer.getLastWorldSaveTime(compound) == ChunkSerializer.getLastWorldSaveTime(aikarOversizedCompound)) { ++ if (SerializableChunkData.getLastWorldSaveTime(compound) == SerializableChunkData.getLastWorldSaveTime(aikarOversizedCompound)) { + // best we got for an id. hope it's good enough + isAikarOversized = true; + } @@ -288,12 +256,12 @@ index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..1e0439cf3f4008fa430acb90b45f5bc4 + continue; + } + -+ if (!ChunkSerializer.getChunkCoordinate(compound).equals(oversizedCoords)) { -+ LOGGER.error("Can't use oversized chunk stored in " + regionFile.toAbsolutePath() + ", got absolute chunkpos: " + ChunkSerializer.getChunkCoordinate(compound) + ", expected " + oversizedCoords); ++ if (!SerializableChunkData.getChunkCoordinate(compound).equals(oversizedCoords)) { ++ LOGGER.error("Can't use oversized chunk stored in " + regionFile.toAbsolutePath() + ", got absolute chunkpos: " + SerializableChunkData.getChunkCoordinate(compound) + ", expected " + oversizedCoords); + continue; + } + -+ if (compounds[location] == null || ChunkSerializer.getLastWorldSaveTime(compound) > ChunkSerializer.getLastWorldSaveTime(compounds[location])) { ++ if (compounds[location] == null || SerializableChunkData.getLastWorldSaveTime(compound) > SerializableChunkData.getLastWorldSaveTime(compounds[location])) { + oversized[location] = true; + oversizedCompressionTypes[location] = compression; + } @@ -430,9 +398,9 @@ index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..1e0439cf3f4008fa430acb90b45f5bc4 + final boolean canRecalcHeader; // final forces compile fail on new constructor + // Paper end - Attempt to recalculate regionfile header if it is corrupt - public RegionFile(RegionStorageInfo storageKey, Path directory, Path path, boolean dsync) throws IOException { - this(storageKey, directory, path, RegionFileVersion.getCompressionFormat(), dsync); // Paper - Configurable region compression format -@@ -67,6 +415,7 @@ public class RegionFile implements AutoCloseable { + // Paper start - rewrite chunk system + @Override +@@ -82,6 +430,7 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche throw new IllegalArgumentException("Expected directory, got " + String.valueOf(directory.toAbsolutePath())); } else { this.externalFileDir = directory; @@ -440,7 +408,7 @@ index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..1e0439cf3f4008fa430acb90b45f5bc4 this.offsets = this.header.asIntBuffer(); ((java.nio.Buffer) this.offsets).limit(1024); // CraftBukkit - decompile error ((java.nio.Buffer) this.header).position(4096); // CraftBukkit - decompile error -@@ -86,14 +435,16 @@ public class RegionFile implements AutoCloseable { +@@ -101,14 +450,16 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche RegionFile.LOGGER.warn("Region file {} has truncated header: {}", path, i); } @@ -462,7 +430,7 @@ index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..1e0439cf3f4008fa430acb90b45f5bc4 // Spigot start if (j1 == 255) { // We're maxed out, so we need to read the proper length from the section -@@ -102,21 +453,66 @@ public class RegionFile implements AutoCloseable { +@@ -117,21 +468,66 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche j1 = (realLen.getInt(0) + 4) / 4096 + 1; } // Spigot end @@ -533,7 +501,7 @@ index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..1e0439cf3f4008fa430acb90b45f5bc4 } } -@@ -127,11 +523,36 @@ public class RegionFile implements AutoCloseable { +@@ -142,11 +538,36 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche } private Path getExternalChunkPath(ChunkPos chunkPos) { @@ -571,7 +539,7 @@ index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..1e0439cf3f4008fa430acb90b45f5bc4 @Nullable public synchronized DataInputStream getChunkDataInputStream(ChunkPos pos) throws IOException { int i = this.getOffset(pos); -@@ -155,6 +576,11 @@ public class RegionFile implements AutoCloseable { +@@ -170,6 +591,11 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche ((java.nio.Buffer) bytebuffer).flip(); // CraftBukkit - decompile error if (bytebuffer.remaining() < 5) { RegionFile.LOGGER.error("Chunk {} header is truncated: expected {} but read {}", new Object[]{pos, l, bytebuffer.remaining()}); @@ -583,7 +551,7 @@ index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..1e0439cf3f4008fa430acb90b45f5bc4 return null; } else { int i1 = bytebuffer.getInt(); -@@ -162,6 +588,11 @@ public class RegionFile implements AutoCloseable { +@@ -177,6 +603,11 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche if (i1 == 0) { RegionFile.LOGGER.warn("Chunk {} is allocated, but stream is missing", pos); @@ -595,7 +563,7 @@ index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..1e0439cf3f4008fa430acb90b45f5bc4 return null; } else { int j1 = i1 - 1; -@@ -169,18 +600,45 @@ public class RegionFile implements AutoCloseable { +@@ -184,18 +615,45 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche if (RegionFile.isExternalStreamChunk(b0)) { if (j1 != 0) { RegionFile.LOGGER.warn("Chunk has both internal and external streams"); @@ -643,7 +611,7 @@ index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..1e0439cf3f4008fa430acb90b45f5bc4 } } } -@@ -366,10 +824,15 @@ public class RegionFile implements AutoCloseable { +@@ -391,10 +849,15 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche } private ByteBuffer createExternalStub() { @@ -661,11 +629,11 @@ index e761b63eebc1e76b2bb1cb887d83d0b63ad6ec90..1e0439cf3f4008fa430acb90b45f5bc4 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 0615fd82b71efb9a397de01615050e6d906c2844..40689256711cc94a806ca1da346f4f62eda31526 100644 +index 2d5c1b91b814316bf9f2f22bcd30adacc8970b01..78922c3e9a69db1774dd846047b79e9523d7cf41 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 -@@ -105,11 +105,42 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise - return ret; +@@ -196,11 +196,42 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise + } } // Paper end - rewrite chunk system + // Paper start - recalculate region file headers @@ -706,14 +674,14 @@ index 0615fd82b71efb9a397de01615050e6d906c2844..40689256711cc94a806ca1da346f4f62 + this.isChunkData = isChunkDataFolder(this.folder); // Paper - recalculate region file headers } - public RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit // Paper - public -@@ -203,6 +234,19 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise + // Paper start - rewrite chunk system +@@ -300,6 +331,19 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise try { if (datainputstream != null) { nbttagcompound = NbtIo.read((DataInput) datainputstream); + // Paper start - recover from corrupt regionfile header + if (this.isChunkData) { -+ ChunkPos chunkPos = ChunkSerializer.getChunkCoordinate(nbttagcompound); ++ ChunkPos chunkPos = SerializableChunkData.getChunkCoordinate(nbttagcompound); + if (!chunkPos.equals(pos)) { + net.minecraft.server.MinecraftServer.LOGGER.error("Attempting to read chunk data at " + pos + " but got chunk data for " + chunkPos + " instead! Attempting regionfile recalculation for regionfile " + regionfile.getPath().toAbsolutePath()); + if (regionfile.recalculateHeader()) { @@ -740,3 +708,35 @@ index ef68b57ef1d8d7cb317c417569dd23a777fba4ad..f4a39f49b354c560d614483db1cd3dfc private static final Object2ObjectMap VERSIONS_BY_NAME = new Object2ObjectOpenHashMap<>(); public static final RegionFileVersion VERSION_GZIP = register( new RegionFileVersion( +diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +index e939810f3cc094a4b17f0b60a441773997cb788f..057c92d182e643cebb1f27e296e0fc4b0e688bea 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java ++++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +@@ -103,6 +103,18 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + } + } + // Paper end - guard against serializing mismatching coordinates ++ // Paper start - Attempt to recalculate regionfile header if it is corrupt ++ // TODO: Check on update ++ public static long getLastWorldSaveTime(final CompoundTag chunkData) { ++ final int dataVersion = ChunkStorage.getVersion(chunkData); ++ if (dataVersion < 2842) { // Level tag is removed after this version ++ final CompoundTag levelData = chunkData.getCompound("Level"); ++ return levelData.getLong("LastUpdate"); ++ } else { ++ return chunkData.getLong("LastUpdate"); ++ } ++ } ++ // Paper end - Attempt to recalculate regionfile header if it is corrupt + + // Paper start - Do not let the server load chunks from newer versions + private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().getDataVersion().getVersion(); +@@ -563,7 +575,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + nbttagcompound.putInt("xPos", this.chunkPos.x); + nbttagcompound.putInt("yPos", this.minSectionY); + nbttagcompound.putInt("zPos", this.chunkPos.z); +- nbttagcompound.putLong("LastUpdate", this.lastUpdateTime); ++ nbttagcompound.putLong("LastUpdate", this.lastUpdateTime); // Paper - Diff on change + nbttagcompound.putLong("InhabitedTime", this.inhabitedTime); + nbttagcompound.putString("Status", BuiltInRegistries.CHUNK_STATUS.getKey(this.chunkStatus).toString()); + DataResult dataresult; // CraftBukkit - decompile error diff --git a/patches/unapplied/server/1032-Bundle-spark.patch b/patches/server/1046-Bundle-spark.patch similarity index 93% rename from patches/unapplied/server/1032-Bundle-spark.patch rename to patches/server/1046-Bundle-spark.patch index 403f8733bc07..585f155a2006 100644 --- a/patches/unapplied/server/1032-Bundle-spark.patch +++ b/patches/server/1046-Bundle-spark.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Bundle spark diff --git a/build.gradle.kts b/build.gradle.kts -index a0f086ec054c456067ee07bf3c7685e2b9458d72..2ed184ccaa963ba1ea007628d2472f31c053be98 100644 +index 9966576652ed6007d2228237f292c1dc83ede485..9b3a6b336cb1344d4e74e0e4f7c50ffd1e1b8955 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -62,6 +62,10 @@ dependencies { @@ -269,10 +269,10 @@ index 6b8ed8a0baaf4a57d20e57cec3400af5561ddd79..48604e7f96adc9e226e034054c5e2bad } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index aa38e3b297209cc121e7dc7a6ac9588c18bf9357..696d075ca2883f3c37e35f983c4d020e5db89d16 100644 +index 79f3dc4f53dce892c4756b0850352e0ca2eb95a6..de80ac827c8ac3630d68b73cb425d4b56f7d2cd7 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -751,6 +751,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Date: Sat, 26 Oct 2024 19:11:37 +0200 Subject: [PATCH 090/119] fix item meta --- .../0166-Fix-Spigot-annotation-mistakes.patch | 13 +++ .../server/0953-General-ItemMeta-fixes.patch | 92 +++++++++++++++---- ...958-Fix-equipment-slot-and-group-API.patch | 6 +- ...CanPlaceOn-and-CanDestroy-NBT-values.patch | 4 +- 4 files changed, 90 insertions(+), 25 deletions(-) diff --git a/patches/api/0166-Fix-Spigot-annotation-mistakes.patch b/patches/api/0166-Fix-Spigot-annotation-mistakes.patch index 8107a6a7af36..bcff5eb5a0c4 100644 --- a/patches/api/0166-Fix-Spigot-annotation-mistakes.patch +++ b/patches/api/0166-Fix-Spigot-annotation-mistakes.patch @@ -1845,6 +1845,19 @@ index 32055a8890425e0b819930f3059da5ea9dfca553..26a336dade83baee97d20eb39a058925 + //@Deprecated // Paper int getMapId(); + /** +diff --git a/src/main/java/org/bukkit/inventory/meta/components/EquippableComponent.java b/src/main/java/org/bukkit/inventory/meta/components/EquippableComponent.java +index c56e81eb71bccc03378aea71096fdf66b4bfa784..16713c9d4cfaed5ad509b4075121e44c55a8cc76 100644 +--- a/src/main/java/org/bukkit/inventory/meta/components/EquippableComponent.java ++++ b/src/main/java/org/bukkit/inventory/meta/components/EquippableComponent.java +@@ -37,7 +37,7 @@ public interface EquippableComponent extends ConfigurationSerializable { + * + * @return the sound + */ +- @Nullable ++ @NotNull // Paper + Sound getEquipSound(); + /** diff --git a/src/main/java/org/bukkit/map/MapCanvas.java b/src/main/java/org/bukkit/map/MapCanvas.java index edef478786bb7456af29ca960009873095830050..e8ac449e6280827beb6d2699df75b1d52a922c9b 100644 diff --git a/patches/server/0953-General-ItemMeta-fixes.patch b/patches/server/0953-General-ItemMeta-fixes.patch index 9b0956d39b1c..ce6a04d22fb7 100644 --- a/patches/server/0953-General-ItemMeta-fixes.patch +++ b/patches/server/0953-General-ItemMeta-fixes.patch @@ -1049,7 +1049,7 @@ index 566d893a413fd04b99e83dc2da8fe958a48492a8..a944803771d514572f94b4e98a6d4435 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411fcb433c8c 100644 +index 13b19adc21ece31476b2980c5bc01a50f15df634..a6e2281bfac94f1e19836d9c8415d8270387b16d 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -199,9 +199,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @@ -1177,7 +1177,33 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f if (lore == null) { this.lore = null; } else { -@@ -1692,7 +1699,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1596,6 +1603,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + + @Override + public void setUseRemainder(ItemStack useRemainder) { ++ Preconditions.checkArgument(useRemainder == null || !useRemainder.isEmpty(), "Item cannot be empty"); // Paper + this.useRemainder = useRemainder; + } + +@@ -1606,7 +1614,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + + @Override + public UseCooldownComponent getUseCooldown() { +- return (this.hasUseCooldown()) ? new CraftUseCooldownComponent(this.useCooldown) : new CraftUseCooldownComponent(new UseCooldown(0)); ++ return (this.hasUseCooldown()) ? new CraftUseCooldownComponent(this.useCooldown) : new CraftUseCooldownComponent(new UseCooldown(1.0F)); // Paper - Create a valid use_cooldown component + } + + @Override +@@ -1656,7 +1664,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + + @Override + public void setEquippable(EquippableComponent equippable) { +- this.equippable = (equippable == null) ? null : new CraftEquippableComponent((CraftEquippableComponent) this.equippable); ++ this.equippable = (equippable == null) ? null : new CraftEquippableComponent((CraftEquippableComponent) equippable); // Paper + } + + @Override +@@ -1692,7 +1700,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public Multimap getAttributeModifiers(@Nullable EquipmentSlot slot) { @@ -1186,7 +1212,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f SetMultimap result = LinkedHashMultimap.create(); for (Map.Entry entry : this.attributeModifiers.entries()) { if (entry.getValue().getSlot() == null || entry.getValue().getSlot() == slot) { -@@ -1705,6 +1712,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1705,6 +1713,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public Collection getAttributeModifiers(@Nonnull Attribute attribute) { Preconditions.checkNotNull(attribute, "Attribute cannot be null"); @@ -1194,7 +1220,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f return this.attributeModifiers.containsKey(attribute) ? ImmutableList.copyOf(this.attributeModifiers.get(attribute)) : null; } -@@ -1712,22 +1720,33 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1712,22 +1721,33 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { public boolean addAttributeModifier(@Nonnull Attribute attribute, @Nonnull AttributeModifier modifier) { Preconditions.checkNotNull(attribute, "Attribute cannot be null"); Preconditions.checkNotNull(modifier, "AttributeModifier cannot be null"); @@ -1232,7 +1258,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f Iterator> iterator = attributeModifiers.entries().iterator(); while (iterator.hasNext()) { -@@ -1737,6 +1756,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1737,6 +1757,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { iterator.remove(); continue; } @@ -1240,7 +1266,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f this.attributeModifiers.put(next.getKey(), next.getValue()); } } -@@ -1744,13 +1764,13 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1744,13 +1765,13 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public boolean removeAttributeModifier(@Nonnull Attribute attribute) { Preconditions.checkNotNull(attribute, "Attribute cannot be null"); @@ -1256,7 +1282,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f int removed = 0; Iterator> iter = this.attributeModifiers.entries().iterator(); -@@ -1770,7 +1790,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1770,7 +1791,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { public boolean removeAttributeModifier(@Nonnull Attribute attribute, @Nonnull AttributeModifier modifier) { Preconditions.checkNotNull(attribute, "Attribute cannot be null"); Preconditions.checkNotNull(modifier, "AttributeModifier cannot be null"); @@ -1265,7 +1291,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f int removed = 0; Iterator> iter = this.attributeModifiers.entries().iterator(); -@@ -1792,7 +1812,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1792,7 +1813,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public String getAsString() { @@ -1274,7 +1300,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f this.applyToItem(tag); DataComponentPatch patch = tag.build(); net.minecraft.nbt.Tag nbt = DataComponentPatch.CODEC.encodeStart(MinecraftServer.getDefaultRegistryAccess().createSerializationContext(NbtOps.INSTANCE), patch).getOrThrow(); -@@ -1801,7 +1821,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1801,7 +1822,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public String getAsComponentString() { @@ -1283,7 +1309,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f this.applyToItem(tag); DataComponentPatch patch = tag.build(); -@@ -1841,6 +1861,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1841,6 +1862,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { if (first == null || second == null) { return false; } @@ -1291,7 +1317,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f for (Map.Entry entry : first.entries()) { if (!second.containsEntry(entry.getKey(), entry.getValue())) { return false; -@@ -1856,19 +1877,33 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1856,19 +1878,33 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public boolean hasDamage() { @@ -1327,7 +1353,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f @Override public boolean hasMaxDamage() { return this.maxDamage != null; -@@ -1882,6 +1917,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1882,6 +1918,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public void setMaxDamage(Integer maxDamage) { @@ -1335,7 +1361,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f this.maxDamage = maxDamage; } -@@ -1914,7 +1950,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1914,7 +1951,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { && (this.hasEnchantable() ? that.hasEnchantable() && this.enchantableValue.equals(that.enchantableValue) : !that.hasEnchantable()) && (this.hasBlockData() ? that.hasBlockData() && this.blockData.equals(that.blockData) : !that.hasBlockData()) && (this.hasRepairCost() ? that.hasRepairCost() && this.repairCost == that.repairCost : !that.hasRepairCost()) @@ -1344,7 +1370,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f && (this.unhandledTags.equals(that.unhandledTags)) && (this.removedTags.equals(that.removedTags)) && (Objects.equals(this.customTag, that.customTag)) -@@ -1935,7 +1971,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1935,7 +1972,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { && (this.hasTool() ? that.hasTool() && this.tool.equals(that.tool) : !that.hasTool()) && (this.hasEquippable() ? that.hasEquippable() && this.equippable.equals(that.equippable) : !that.hasEquippable()) && (this.hasJukeboxPlayable() ? that.hasJukeboxPlayable() && this.jukebox.equals(that.jukebox) : !that.hasJukeboxPlayable()) @@ -1353,7 +1379,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f && (this.hasMaxDamage() ? that.hasMaxDamage() && this.maxDamage.equals(that.maxDamage) : !that.hasMaxDamage()) && (this.canPlaceOnPredicates != null ? that.canPlaceOnPredicates != null && this.canPlaceOnPredicates.equals(that.canPlaceOnPredicates) : that.canPlaceOnPredicates == null) // Paper && (this.canBreakPredicates != null ? that.canBreakPredicates != null && this.canBreakPredicates.equals(that.canBreakPredicates) : that.canBreakPredicates == null) // Paper -@@ -1988,9 +2024,9 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1988,9 +2025,9 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { hash = 61 * hash + (this.hasTool() ? this.tool.hashCode() : 0); hash = 61 * hash + (this.hasJukeboxPlayable() ? this.jukebox.hashCode() : 0); hash = 61 * hash + (this.hasEquippable() ? this.equippable.hashCode() : 0); @@ -1366,7 +1392,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f hash = 61 * hash + (this.canPlaceOnPredicates != null ? this.canPlaceOnPredicates.hashCode() : 0); // Paper hash = 61 * hash + (this.canBreakPredicates != null ? this.canBreakPredicates.hashCode() : 0); // Paper hash = 61 * hash + this.version; -@@ -2011,7 +2047,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2011,7 +2048,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { if (this.enchantments != null) { clone.enchantments = new EnchantmentMap(this.enchantments); // Paper } @@ -1375,7 +1401,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f clone.attributeModifiers = LinkedHashMultimap.create(this.attributeModifiers); } if (this.customTag != null) { -@@ -2178,7 +2214,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2178,7 +2215,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { builder.put(CraftMetaItem.JUKEBOX_PLAYABLE.BUKKIT, this.jukebox); } @@ -1384,7 +1410,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f builder.put(CraftMetaItem.DAMAGE.BUKKIT, this.damage); } -@@ -2279,7 +2315,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2279,7 +2316,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { } static void serializeModifiers(Multimap modifiers, ImmutableMap.Builder builder, ItemMetaKey key) { @@ -1393,7 +1419,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f return; } -@@ -2361,7 +2397,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2361,7 +2398,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { // Paper start - improve checking handled tags @org.jetbrains.annotations.VisibleForTesting public static final Map, Set>> HANDLED_DCTS_PER_TYPE = new HashMap<>(); @@ -1402,7 +1428,7 @@ index 13b19adc21ece31476b2980c5bc01a50f15df634..63567251d101b5e50ffd7e2825b1411f CraftMetaItem.NAME.TYPE, CraftMetaItem.ITEM_NAME.TYPE, CraftMetaItem.LORE.TYPE, -@@ -2437,7 +2473,12 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2437,7 +2474,12 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { // Paper end - improve checking handled data component types protected static Optional getOrEmpty(DataComponentPatch tag, ItemMetaKeyType type) { @@ -2027,6 +2053,19 @@ index e00b757d6059715e8697428008fcb3e6e7abbe2e..dcf02bd0f7f4c67f5ab98003cc932b96 + } + // Paper end - General ItemMeta Fixes } +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftEquippableComponent.java b/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftEquippableComponent.java +index 1f1589bcdb9e3abde7d25eac65326df1e7ed75ab..9b4c2502e45af4e7a58ff352f0f99c34d233f755 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftEquippableComponent.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftEquippableComponent.java +@@ -170,7 +170,7 @@ public final class CraftEquippableComponent implements EquippableComponent { + + @Override + public void setAllowedEntities(Tag tag) { +- Preconditions.checkArgument(tag instanceof CraftEntityTag, "tag must be an entity tag"); ++ Preconditions.checkArgument(tag == null || tag instanceof CraftEntityTag, "tag must be an entity tag"); // Paper + + this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.model(), this.handle.cameraOverlay(), + (tag != null) ? Optional.of(((CraftEntityTag) tag).getHandle()) : Optional.empty(), diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftToolComponent.java b/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftToolComponent.java index 9a4a1d903c22e9d2a0cbda95ceb8b1dcfb29112e..4f7914f96207feda67cd910213bb624df4802a06 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftToolComponent.java @@ -2063,6 +2102,19 @@ index 9a4a1d903c22e9d2a0cbda95ceb8b1dcfb29112e..4f7914f96207feda67cd910213bb624d this.handle = new Tool.Rule(this.handle.blocks(), Optional.ofNullable(speed), this.handle.correctForDrops()); } +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftUseCooldownComponent.java b/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftUseCooldownComponent.java +index 952e7fa022161d1d21ba1a4f43abe5ee221dee4b..0f86ff23cc6a2f617fc5ef67e576e1e3cb29034c 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftUseCooldownComponent.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftUseCooldownComponent.java +@@ -55,7 +55,7 @@ public final class CraftUseCooldownComponent implements UseCooldownComponent { + + @Override + public void setCooldownSeconds(float eatSeconds) { +- Preconditions.checkArgument(eatSeconds >= 0, "eatSeconds cannot be less than 0"); ++ Preconditions.checkArgument(eatSeconds > 0, "eatSeconds must be positive"); // Paper + + this.handle = new UseCooldown(eatSeconds, this.handle.cooldownGroup()); + } diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/DeprecatedItemMetaCustomValueTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/DeprecatedItemMetaCustomValueTest.java index 9cc1ef5c9221dd7d2069b280f0c91ce9439a995a..1c80fe7549d70ae16c7b755c22752549261f072a 100644 --- a/src/test/java/org/bukkit/craftbukkit/inventory/DeprecatedItemMetaCustomValueTest.java diff --git a/patches/server/0958-Fix-equipment-slot-and-group-API.patch b/patches/server/0958-Fix-equipment-slot-and-group-API.patch index 962f6d77b249..3248a82d098e 100644 --- a/patches/server/0958-Fix-equipment-slot-and-group-API.patch +++ b/patches/server/0958-Fix-equipment-slot-and-group-API.patch @@ -52,10 +52,10 @@ index e62baea16df017f1e394e3c706157e158066eb93..656c9a6d8cd42891141ee29ec91ab5d1 throw new IllegalArgumentException("Could not get slot " + slot + " - not a valid slot for PlayerInventory"); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index 63567251d101b5e50ffd7e2825b1411fcb433c8c..450c5aa14b4195eb7123492c7a111ec6f40ce412 100644 +index a6e2281bfac94f1e19836d9c8415d8270387b16d..a4d6c95e55722c9a0e381d7b84916787240cea8e 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -@@ -1702,7 +1702,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1703,7 +1703,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { if (this.attributeModifiers == null) return LinkedHashMultimap.create(); // Paper - don't change the components SetMultimap result = LinkedHashMultimap.create(); for (Map.Entry entry : this.attributeModifiers.entries()) { @@ -64,7 +64,7 @@ index 63567251d101b5e50ffd7e2825b1411fcb433c8c..450c5aa14b4195eb7123492c7a111ec6 result.put(entry.getKey(), entry.getValue()); } } -@@ -1776,9 +1776,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -1777,9 +1777,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { while (iter.hasNext()) { Map.Entry entry = iter.next(); diff --git a/patches/server/1007-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch b/patches/server/1007-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch index e1242464ddbb..282bdd1de1e9 100644 --- a/patches/server/1007-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch +++ b/patches/server/1007-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add API for CanPlaceOn and CanDestroy NBT values diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index 450c5aa14b4195eb7123492c7a111ec6f40ce412..3b3c15c8bd8591aa173343251d7a504c6004e9d2 100644 +index a4d6c95e55722c9a0e381d7b84916787240cea8e..188684a480c8ae2b761ed12ca0b1d256cef67538 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -@@ -2498,4 +2498,119 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { +@@ -2499,4 +2499,119 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { } // Paper end From 7d67d3f4f49ca061001d5d091557b8275c3a4e50 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Sat, 26 Oct 2024 19:41:56 +0200 Subject: [PATCH 091/119] fix DamageTypeTags init --- paper-api-generator/wideners.at | 2 -- .../api/0495-fix-DamageTypeTags-init.patch | 21 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 patches/api/0495-fix-DamageTypeTags-init.patch diff --git a/paper-api-generator/wideners.at b/paper-api-generator/wideners.at index 60a5d241e7a6..6c8ce1529e1f 100644 --- a/paper-api-generator/wideners.at +++ b/paper-api-generator/wideners.at @@ -1,5 +1,3 @@ -public net/minecraft/server/WorldLoader loadAndReplaceLayer(Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/core/LayeredRegistryAccess;Lnet/minecraft/server/RegistryLayer;Ljava/util/List;)Lnet/minecraft/core/LayeredRegistryAccess; - # for auto-marking experimental stuff public net/minecraft/core/RegistrySetBuilder entries public net/minecraft/core/RegistrySetBuilder$RegistryStub diff --git a/patches/api/0495-fix-DamageTypeTags-init.patch b/patches/api/0495-fix-DamageTypeTags-init.patch new file mode 100644 index 000000000000..2d775b1322ad --- /dev/null +++ b/patches/api/0495-fix-DamageTypeTags-init.patch @@ -0,0 +1,21 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> +Date: Sat, 26 Oct 2024 19:29:41 +0200 +Subject: [PATCH] fix DamageTypeTags init + + +diff --git a/src/main/java/org/bukkit/tag/DamageTypeTags.java b/src/main/java/org/bukkit/tag/DamageTypeTags.java +index 12d14ab2947517eedc563acf647857f13021f80c..c02d92b607dfc998e81b7722464cefd867c80072 100644 +--- a/src/main/java/org/bukkit/tag/DamageTypeTags.java ++++ b/src/main/java/org/bukkit/tag/DamageTypeTags.java +@@ -158,9 +158,8 @@ public final class DamageTypeTags { + @ApiStatus.Internal + public static final String REGISTRY_DAMAGE_TYPES = "damage_types"; + +- @NotNull + private static Tag getTag(String key) { +- return Objects.requireNonNull(Bukkit.getTag(REGISTRY_DAMAGE_TYPES, NamespacedKey.minecraft(key), DamageType.class)); ++ return Bukkit.getTag(REGISTRY_DAMAGE_TYPES, NamespacedKey.minecraft(key), DamageType.class); // Paper - bypasses_cooldown is not defined in vanilla + } + + private DamageTypeTags() { From 09718757bfae5296edbd61b70938fffd2b11f1a2 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sat, 26 Oct 2024 12:50:32 -0700 Subject: [PATCH 092/119] re-add improve perf of mass crafts --- ...7-Improve-performance-of-mass-crafts.patch | 92 ++++++++++++ ...2-Improve-performance-of-mass-crafts.patch | 138 ------------------ 2 files changed, 92 insertions(+), 138 deletions(-) create mode 100644 patches/server/1047-Improve-performance-of-mass-crafts.patch delete mode 100644 patches/unapplied/server/1012-Improve-performance-of-mass-crafts.patch diff --git a/patches/server/1047-Improve-performance-of-mass-crafts.patch b/patches/server/1047-Improve-performance-of-mass-crafts.patch new file mode 100644 index 000000000000..57f901bc5f8d --- /dev/null +++ b/patches/server/1047-Improve-performance-of-mass-crafts.patch @@ -0,0 +1,92 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sun, 13 Aug 2023 15:41:52 -0700 +Subject: [PATCH] Improve performance of mass crafts + +When the server crafts all available items in CraftingMenu or InventoryMenu the game +checks either 4 or 9 times for each individual craft for a matching recipe for that container. +This check can be expensive if 64 total crafts are being performed with the recipe matching logic +being run 64 * 9 + 64 times. A breakdown of those times is below. This patch caches the last matching +recipe so that it is checked first and only if it doesn't match does the rest of the matching logic run. + +Shift-click crafts are processed one at a time, so shift clicking on an item in the result of a iron block craft +where all the 9 inputs are full stacks of iron will run 64 iron block crafts. For each of those crafts, the +'remaining' blocks are calculated. This is due to recipes that have leftover items like buckets. This is done +for each craft, and done once to get the full 9 leftover items which are usually air. Then 1 item is removed +from each of the 9 inputs and each time that happens, logic is triggered to update the result itemstack. So +for each craft, that logic is run 9 times (hence the 64 * 9). The + 64 is from the 64 checks for remaining items. + +After this patch, the full iteration over all recipes checking for a match should run once for a full craft to find the +initial recipe match. Then that recipe will be checked first for all future recipe match checks. + +diff --git a/src/main/java/net/minecraft/world/inventory/CraftingContainer.java b/src/main/java/net/minecraft/world/inventory/CraftingContainer.java +index 779d107a4d07820529273af5931421c09d1dc27f..4f6c8c43f5150e340704682accfbe2a5b1c5db19 100644 +--- a/src/main/java/net/minecraft/world/inventory/CraftingContainer.java ++++ b/src/main/java/net/minecraft/world/inventory/CraftingContainer.java +@@ -18,11 +18,11 @@ public interface CraftingContainer extends Container, StackedContentsCompatible + List getItems(); + + // CraftBukkit start +- default RecipeHolder getCurrentRecipe() { ++ default RecipeHolder getCurrentRecipe() { // Paper - use correct generic + return null; + } + +- default void setCurrentRecipe(RecipeHolder recipe) { ++ default void setCurrentRecipe(RecipeHolder recipe) { // Paper - use correct generic + } + // CraftBukkit end + +diff --git a/src/main/java/net/minecraft/world/inventory/CraftingMenu.java b/src/main/java/net/minecraft/world/inventory/CraftingMenu.java +index 6b3006a8543265664a2e54898ece92c66afb9c21..2e4043248c3ac7a54d894d76b99adc26518d3866 100644 +--- a/src/main/java/net/minecraft/world/inventory/CraftingMenu.java ++++ b/src/main/java/net/minecraft/world/inventory/CraftingMenu.java +@@ -56,6 +56,7 @@ public class CraftingMenu extends AbstractCraftingMenu { + CraftingInput craftinginput = craftingInventory.asCraftInput(); + ServerPlayer entityplayer = (ServerPlayer) player; + ItemStack itemstack = ItemStack.EMPTY; ++ if (recipe == null) recipe = craftingInventory.getCurrentRecipe(); // Paper - Perf: Improve mass crafting; check last recipe used first + Optional> optional = world.getServer().getRecipeManager().getRecipeFor(RecipeType.CRAFTING, craftinginput, world, recipe); + craftingInventory.setCurrentRecipe(optional.orElse(null)); // CraftBukkit + +diff --git a/src/main/java/net/minecraft/world/inventory/ResultSlot.java b/src/main/java/net/minecraft/world/inventory/ResultSlot.java +index 1ea4f0800598a75ba74ce033378749d1abe4009b..ff30071f3ef37d1b28cf86e26ce4f7477335a07a 100644 +--- a/src/main/java/net/minecraft/world/inventory/ResultSlot.java ++++ b/src/main/java/net/minecraft/world/inventory/ResultSlot.java +@@ -72,7 +72,7 @@ public class ResultSlot extends Slot { + private NonNullList getRemainingItems(CraftingInput input, Level world) { + return world instanceof ServerLevel serverLevel + ? serverLevel.recipeAccess() +- .getRecipeFor(RecipeType.CRAFTING, input, serverLevel) ++ .getRecipeFor(RecipeType.CRAFTING, input, serverLevel, this.craftSlots.getCurrentRecipe()) // Paper - Perf: Improve mass crafting; check last recipe used first + .map(recipe -> recipe.value().getRemainingItems(input)) + .orElseGet(() -> copyAllInputItems(input)) + : CraftingRecipe.defaultCraftingReminder(input); +diff --git a/src/main/java/net/minecraft/world/inventory/TransientCraftingContainer.java b/src/main/java/net/minecraft/world/inventory/TransientCraftingContainer.java +index 32d49d759f95d27ca04b843bbb2c2fd22ebd7e4a..a458f7b8270dc1d5902e0d131dbf9e66209e26be 100644 +--- a/src/main/java/net/minecraft/world/inventory/TransientCraftingContainer.java ++++ b/src/main/java/net/minecraft/world/inventory/TransientCraftingContainer.java +@@ -27,7 +27,7 @@ public class TransientCraftingContainer implements CraftingContainer { + + // CraftBukkit start - add fields + public List transaction = new java.util.ArrayList(); +- private RecipeHolder currentRecipe; ++ private RecipeHolder currentRecipe; // Paper - use correct generic + public Container resultInventory; + private Player owner; + private int maxStack = MAX_STACK; +@@ -72,12 +72,12 @@ public class TransientCraftingContainer implements CraftingContainer { + } + + @Override +- public RecipeHolder getCurrentRecipe() { ++ public RecipeHolder getCurrentRecipe() { // Paper - use correct generic + return this.currentRecipe; + } + + @Override +- public void setCurrentRecipe(RecipeHolder currentRecipe) { ++ public void setCurrentRecipe(RecipeHolder currentRecipe) { // Paper - use correct generic + this.currentRecipe = currentRecipe; + } + diff --git a/patches/unapplied/server/1012-Improve-performance-of-mass-crafts.patch b/patches/unapplied/server/1012-Improve-performance-of-mass-crafts.patch deleted file mode 100644 index 15701b21e0d9..000000000000 --- a/patches/unapplied/server/1012-Improve-performance-of-mass-crafts.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sun, 13 Aug 2023 15:41:52 -0700 -Subject: [PATCH] Improve performance of mass crafts - -When the server crafts all available items in CraftingMenu or InventoryMenu the game -checks either 4 or 9 times for each individual craft for a matching recipe for that container. -This check can be expensive if 64 total crafts are being performed with the recipe matching logic -being run 64 * 9 + 64 times. A breakdown of those times is below. This patch caches the last matching -recipe so that it is checked first and only if it doesn't match does the rest of the matching logic run. - -Shift-click crafts are processed one at a time, so shift clicking on an item in the result of a iron block craft -where all the 9 inputs are full stacks of iron will run 64 iron block crafts. For each of those crafts, the -'remaining' blocks are calculated. This is due to recipes that have leftover items like buckets. This is done -for each craft, and done once to get the full 9 leftover items which are usually air. Then 1 item is removed -from each of the 9 inputs and each time that happens, logic is triggered to update the result itemstack. So -for each craft, that logic is run 9 times (hence the 64 * 9). The + 64 is from the 64 checks for remaining items. - -After this patch, the full iteration over all recipes checking for a match should run once for a full craft to find the -initial recipe match. Then that recipe will be checked first for all future recipe match checks. - -diff --git a/src/main/java/net/minecraft/world/inventory/CraftingContainer.java b/src/main/java/net/minecraft/world/inventory/CraftingContainer.java -index 779d107a4d07820529273af5931421c09d1dc27f..4f6c8c43f5150e340704682accfbe2a5b1c5db19 100644 ---- a/src/main/java/net/minecraft/world/inventory/CraftingContainer.java -+++ b/src/main/java/net/minecraft/world/inventory/CraftingContainer.java -@@ -18,11 +18,11 @@ public interface CraftingContainer extends Container, StackedContentsCompatible - List getItems(); - - // CraftBukkit start -- default RecipeHolder getCurrentRecipe() { -+ default RecipeHolder getCurrentRecipe() { // Paper - use correct generic - return null; - } - -- default void setCurrentRecipe(RecipeHolder recipe) { -+ default void setCurrentRecipe(RecipeHolder recipe) { // Paper - use correct generic - } - // CraftBukkit end - -diff --git a/src/main/java/net/minecraft/world/inventory/CraftingMenu.java b/src/main/java/net/minecraft/world/inventory/CraftingMenu.java -index b572c905b2ef3cf79202c5f35eefd6a636e872f5..f9e4714cb0ee74505ed72200abed7756aa68dc90 100644 ---- a/src/main/java/net/minecraft/world/inventory/CraftingMenu.java -+++ b/src/main/java/net/minecraft/world/inventory/CraftingMenu.java -@@ -79,6 +79,7 @@ public class CraftingMenu extends RecipeBookMenu - CraftingInput craftinginput = craftingInventory.asCraftInput(); - ServerPlayer entityplayer = (ServerPlayer) player; - ItemStack itemstack = ItemStack.EMPTY; -+ if (recipe == null) recipe = craftingInventory.getCurrentRecipe(); // Paper - Perf: Improve mass crafting; check last recipe used first - Optional> optional = world.getServer().getRecipeManager().getRecipeFor(RecipeType.CRAFTING, craftinginput, world, recipe); - craftingInventory.setCurrentRecipe(optional.orElse(null)); // CraftBukkit - -diff --git a/src/main/java/net/minecraft/world/inventory/ResultSlot.java b/src/main/java/net/minecraft/world/inventory/ResultSlot.java -index c75bc6bec06bb7c32eea81c0bc89441beb3d1150..37a89bf79017eb65f82276b054a70ddb5eb5e549 100644 ---- a/src/main/java/net/minecraft/world/inventory/ResultSlot.java -+++ b/src/main/java/net/minecraft/world/inventory/ResultSlot.java -@@ -63,7 +63,7 @@ public class ResultSlot extends Slot { - CraftingInput craftingInput = positioned.input(); - int i = positioned.left(); - int j = positioned.top(); -- NonNullList nonNullList = player.level().getRecipeManager().getRemainingItemsFor(RecipeType.CRAFTING, craftingInput, player.level()); -+ NonNullList nonNullList = player.level().getRecipeManager().getRemainingItemsFor(RecipeType.CRAFTING, craftingInput, player.level(), this.craftSlots.getCurrentRecipe()); // Paper - Perf: Improve mass crafting; check last recipe used first - - for (int k = 0; k < craftingInput.height(); k++) { - for (int l = 0; l < craftingInput.width(); l++) { -diff --git a/src/main/java/net/minecraft/world/inventory/TransientCraftingContainer.java b/src/main/java/net/minecraft/world/inventory/TransientCraftingContainer.java -index 341e1f70602ecdb4782c9cd74fa19135ac230d90..42207462c4e720677a5ddbba4129dae60420aaa3 100644 ---- a/src/main/java/net/minecraft/world/inventory/TransientCraftingContainer.java -+++ b/src/main/java/net/minecraft/world/inventory/TransientCraftingContainer.java -@@ -27,7 +27,7 @@ public class TransientCraftingContainer implements CraftingContainer { - - // CraftBukkit start - add fields - public List transaction = new java.util.ArrayList(); -- private RecipeHolder currentRecipe; -+ private RecipeHolder currentRecipe; // Paper - use correct generic - public Container resultInventory; - private Player owner; - private int maxStack = MAX_STACK; -@@ -72,12 +72,12 @@ public class TransientCraftingContainer implements CraftingContainer { - } - - @Override -- public RecipeHolder getCurrentRecipe() { -+ public RecipeHolder getCurrentRecipe() { // Paper - use correct generic - return this.currentRecipe; - } - - @Override -- public void setCurrentRecipe(RecipeHolder currentRecipe) { -+ public void setCurrentRecipe(RecipeHolder currentRecipe) { // Paper - use correct generic - this.currentRecipe = currentRecipe; - } - -diff --git a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java -index 407f3c1938b5b5d893b09705fe4930dbdafa3c8e..de7c77c1b25680ecc65f0f43f2391aff269a974f 100644 ---- a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java -+++ b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java -@@ -111,13 +111,20 @@ public class RecipeManager extends SimpleJsonResourceReloadListener { - } - - public > Optional> getRecipeFor(RecipeType type, I input, Level world, @Nullable RecipeHolder recipe) { -- // CraftBukkit start -- List> list = this.byType(type).stream().filter((recipeholder1) -> { -- return recipeholder1.value().matches(input, world); -- }).toList(); -- Optional> recipe1 = (list.isEmpty() || input.isEmpty()) ? Optional.empty() : (recipe != null && recipe.value().matches(input, world) ? Optional.of(recipe) : Optional.of(list.getLast())); // CraftBukkit - SPIGOT-4638: last recipe gets priority -- return recipe1; -- // CraftBukkit end -+ // Paper start - fix upstream's complete screw up of checking last used recipe -+ if (input.isEmpty()) { -+ return Optional.empty(); -+ } else if (recipe != null && recipe.value().matches(input, world)) { -+ return Optional.of(recipe); -+ } else { -+ // CraftBukkit start -+ List> list = this.byType(type).stream().filter((recipeholder1) -> { -+ return recipeholder1.value().matches(input, world); -+ }).toList(); -+ return list.isEmpty() ? Optional.empty() : Optional.of(list.getLast()); // CraftBukkit - SPIGOT-4638: last recipe gets priority -+ // CraftBukkit end -+ } -+ // Paper end - } - - public > List> getAllRecipesFor(RecipeType type) { -@@ -137,7 +144,12 @@ public class RecipeManager extends SimpleJsonResourceReloadListener { - } - - public > NonNullList getRemainingItemsFor(RecipeType type, I input, Level world) { -- Optional> optional = this.getRecipeFor(type, input, world); -+ // Paper start - Perf: improve performance of mass crafts -+ return this.getRemainingItemsFor(type, input, world, null); -+ } -+ public > NonNullList getRemainingItemsFor(RecipeType type, I input, Level world, @Nullable RecipeHolder previousRecipe) { -+ Optional> optional = this.getRecipeFor(type, input, world, previousRecipe); -+ // Paper end - Perf: improve performance of mass crafts - - if (optional.isPresent()) { - return ((RecipeHolder) optional.get()).value().getRemainingItems(input); From bcf52fe5fd7b178e3c72f53762c8e32ca7910dc4 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Sun, 27 Oct 2024 09:24:59 +0100 Subject: [PATCH 093/119] Delete some old patches --- .../removed/1.21/0393-Fix-SPIGOT-5989.patch | 63 - .../0562-Fix-dangerous-end-portal-logic.patch | 88 - patches/removed/1.21/0993-Starlight.patch | 5429 ---- .../1.21/0994-Rewrite-chunk-system.patch | 21846 ---------------- ...rove-exact-choice-recipe-ingredients.patch | 0 .../0451-Fix-harming-potion-dupe.patch | 0 ...ies-in-dispense-events-regarding-sta.patch | 0 ...-API-for-updating-recipes-on-clients.patch | 0 ...cing-for-EntityLiving-hasLineOfSight.patch | 0 9 files changed, 27426 deletions(-) delete mode 100644 patches/removed/1.21/0393-Fix-SPIGOT-5989.patch delete mode 100644 patches/removed/1.21/0562-Fix-dangerous-end-portal-logic.patch delete mode 100644 patches/removed/1.21/0993-Starlight.patch delete mode 100644 patches/removed/1.21/0994-Rewrite-chunk-system.patch rename patches/{later => unapplied/server}/0277-Improve-exact-choice-recipe-ingredients.patch (100%) rename patches/{later => unapplied/server}/0451-Fix-harming-potion-dupe.patch (100%) rename patches/{later => unapplied/server}/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch (100%) rename patches/{later => unapplied/server}/0845-API-for-updating-recipes-on-clients.patch (100%) rename patches/{later => unapplied/server}/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch (100%) diff --git a/patches/removed/1.21/0393-Fix-SPIGOT-5989.patch b/patches/removed/1.21/0393-Fix-SPIGOT-5989.patch deleted file mode 100644 index 5b41e0742c55..000000000000 --- a/patches/removed/1.21/0393-Fix-SPIGOT-5989.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: JRoy -Date: Wed, 15 Jul 2020 21:42:52 -0400 -Subject: [PATCH] Fix SPIGOT-5989 - -Before this fix, if a player was respawning to a respawn anchor and -the respawn location was modified away from the anchor with the -PlayerRespawnEvent, the anchor would still lose some charge. -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 935061ed5c22b48e43d27fe0840cc69fb60d5344..97a3f29414cd9f11e6a790cb30f7ef25a836b06c 100644 ---- a/src/main/java/net/minecraft/server/players/PlayerList.java -+++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -804,6 +804,7 @@ public abstract class PlayerList { - // Paper start - Add PlayerPostRespawnEvent - boolean isBedSpawn = false; - boolean isRespawn = false; -+ boolean isLocAltered = false; // Paper - Fix SPIGOT-5989 - // Paper end - Add PlayerPostRespawnEvent - - // CraftBukkit start - fire PlayerRespawnEvent -@@ -814,7 +815,7 @@ public abstract class PlayerList { - Optional optional; - - if (blockposition != null) { -- optional = net.minecraft.world.entity.player.Player.findRespawnPositionAndUseSpawnBlock(worldserver1, blockposition, f, flag1, flag); -+ optional = net.minecraft.world.entity.player.Player.findRespawnPositionAndUseSpawnBlock(worldserver1, blockposition, f, flag1, true); // Paper - Fix SPIGOT-5989 - } else { - optional = Optional.empty(); - } -@@ -858,7 +859,12 @@ public abstract class PlayerList { - } - // Spigot End - -- location = respawnEvent.getRespawnLocation(); -+ // Paper start - Fix SPIGOT-5989 -+ if (!location.equals(respawnEvent.getRespawnLocation()) ) { -+ location = respawnEvent.getRespawnLocation(); -+ isLocAltered = true; -+ } -+ // Paper end - Fix SPIGOT-5989 - if (!flag) entityplayer.reset(); // SPIGOT-4785 - isRespawn = true; // Paper - Add PlayerPostRespawnEvent - } else { -@@ -896,8 +902,14 @@ public abstract class PlayerList { - } - // entityplayer1.initInventoryMenu(); - entityplayer1.setHealth(entityplayer1.getHealth()); -- if (flag2) { -- entityplayer1.connection.send(new ClientboundSoundPacket(SoundEvents.RESPAWN_ANCHOR_DEPLETE, SoundSource.BLOCKS, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 1.0F, 1.0F, worldserver1.getRandom().nextLong())); -+ // Paper start - Fix SPIGOT-5989 -+ if (flag2 && !isLocAltered) { -+ if (!flag1) { -+ BlockState data = worldserver1.getBlockState(blockposition); -+ worldserver1.setBlock(blockposition, data.setValue(net.minecraft.world.level.block.RespawnAnchorBlock.CHARGE, data.getValue(net.minecraft.world.level.block.RespawnAnchorBlock.CHARGE) - 1), 3); -+ } -+ entityplayer1.connection.send(new ClientboundSoundPacket(SoundEvents.RESPAWN_ANCHOR_DEPLETE, SoundSource.BLOCKS, (double) location.getX(), (double) location.getY(), (double) location.getZ(), 1.0F, 1.0F, worldserver1.getRandom().nextLong())); -+ // Paper end - Fix SPIGOT-5989 - } - // Added from changeDimension - this.sendAllPlayerInfo(entityplayer); // Update health, etc... diff --git a/patches/removed/1.21/0562-Fix-dangerous-end-portal-logic.patch b/patches/removed/1.21/0562-Fix-dangerous-end-portal-logic.patch deleted file mode 100644 index 88c7e811e1bb..000000000000 --- a/patches/removed/1.21/0562-Fix-dangerous-end-portal-logic.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Fri, 4 Jun 2021 17:06:52 -0400 -Subject: [PATCH] Fix dangerous end portal logic - -End portals could teleport entities during move calls. Stupid -logic given the caller will never expect that kind of thing, -and will result in all kinds of dupes. - -Move the tick logic into the post tick, where portaling was -designed to happen in the first place. - -diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 21150f44e4f71aba3801d5392e45243112d012c0..b4670fc653721283f95bb61ac57c306b224b7fb7 100644 ---- a/src/main/java/net/minecraft/world/entity/Entity.java -+++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -422,6 +422,36 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - return this.originWorld; - } - // Paper end - Entity origin API -+ // Paper start - make end portalling safe -+ public BlockPos portalBlock; -+ public ServerLevel portalWorld; -+ public void tickEndPortal() { -+ BlockPos pos = this.portalBlock; -+ ServerLevel world = this.portalWorld; -+ this.portalBlock = null; -+ this.portalWorld = null; -+ -+ if (pos == null || world == null || world != this.level) { -+ return; -+ } -+ -+ if (this.isPassenger() || this.isVehicle() || !this.canChangeDimensions() || this.isRemoved() || !this.valid || !this.isAlive()) { -+ return; -+ } -+ -+ ResourceKey resourcekey = world.getTypeKey() == LevelStem.END ? Level.OVERWORLD : Level.END; // CraftBukkit - SPIGOT-6152: send back to main overworld in custom ends -+ ServerLevel worldserver = world.getServer().getLevel(resourcekey); -+ -+ org.bukkit.event.entity.EntityPortalEnterEvent event = new org.bukkit.event.entity.EntityPortalEnterEvent(this.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ())); -+ event.callEvent(); -+ -+ if (this instanceof ServerPlayer) { -+ ((ServerPlayer) this).changeDimension(worldserver, PlayerTeleportEvent.TeleportCause.END_PORTAL); -+ return; -+ } -+ this.teleportTo(worldserver, null); -+ } -+ // Paper end - make end portalling safe - public float getBukkitYaw() { - return this.yRot; - } -@@ -2833,6 +2863,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - } - - this.processPortalCooldown(); -+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowUnsafeEndPortalTeleportation) this.tickEndPortal(); // Paper - make end portalling safe - } - } - -diff --git a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java -index a2de13a366e4a462b746dab035372838127f4994..7272d70c672b54dcf595beafd7a2ed33c96e35cb 100644 ---- a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java -@@ -61,16 +61,13 @@ public class EndPortalBlock extends BaseEntityBlock { - // return; // CraftBukkit - always fire event in case plugins wish to change it - } - -- // CraftBukkit start - Entity in portal -- EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ())); -- world.getCraftServer().getPluginManager().callEvent(event); -- -- if (entity instanceof ServerPlayer) { -- ((ServerPlayer) entity).changeDimension(worldserver, PlayerTeleportEvent.TeleportCause.END_PORTAL); -- return; -+ // Paper start - move all of this logic into portal tick -+ entity.portalWorld = ((ServerLevel)world); -+ entity.portalBlock = pos.immutable(); -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowUnsafeEndPortalTeleportation) { -+ entity.tickEndPortal(); - } -- // CraftBukkit end -- entity.changeDimension(worldserver); -+ // Paper end - move all of this logic into portal tick - } - - } diff --git a/patches/removed/1.21/0993-Starlight.patch b/patches/removed/1.21/0993-Starlight.patch deleted file mode 100644 index bc604e348c66..000000000000 --- a/patches/removed/1.21/0993-Starlight.patch +++ /dev/null @@ -1,5429 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Wed, 28 Oct 2020 16:51:55 -0700 -Subject: [PATCH] Starlight - -See https://github.com/PaperMC/Starlight - -== AT == -public net.minecraft.server.level.ChunkHolder broadcast(Lnet/minecraft/network/protocol/Packet;Z)V - -diff --git a/src/main/java/ca/spottedleaf/starlight/common/light/BlockStarLightEngine.java b/src/main/java/ca/spottedleaf/starlight/common/light/BlockStarLightEngine.java -new file mode 100644 -index 0000000000000000000000000000000000000000..3732a940d9603cf502983afbc4663113d1400be8 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/starlight/common/light/BlockStarLightEngine.java -@@ -0,0 +1,275 @@ -+package ca.spottedleaf.starlight.common.light; -+ -+import net.minecraft.core.BlockPos; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.status.ChunkStatus; -+import net.minecraft.world.level.chunk.LevelChunkSection; -+import net.minecraft.world.level.chunk.LightChunkGetter; -+import net.minecraft.world.level.chunk.PalettedContainer; -+import net.minecraft.world.phys.shapes.Shapes; -+import net.minecraft.world.phys.shapes.VoxelShape; -+import java.util.ArrayList; -+import java.util.List; -+import java.util.Set; -+ -+public final class BlockStarLightEngine extends StarLightEngine { -+ -+ public BlockStarLightEngine(final Level world) { -+ super(false, world); -+ } -+ -+ @Override -+ protected boolean[] getEmptinessMap(final ChunkAccess chunk) { -+ return chunk.getBlockEmptinessMap(); -+ } -+ -+ @Override -+ protected void setEmptinessMap(final ChunkAccess chunk, final boolean[] to) { -+ chunk.setBlockEmptinessMap(to); -+ } -+ -+ @Override -+ protected SWMRNibbleArray[] getNibblesOnChunk(final ChunkAccess chunk) { -+ return chunk.getBlockNibbles(); -+ } -+ -+ @Override -+ protected void setNibbles(final ChunkAccess chunk, final SWMRNibbleArray[] to) { -+ chunk.setBlockNibbles(to); -+ } -+ -+ @Override -+ protected boolean canUseChunk(final ChunkAccess chunk) { -+ return chunk.getStatus().isOrAfter(ChunkStatus.LIGHT) && (this.isClientSide || chunk.isLightCorrect()); -+ } -+ -+ @Override -+ protected void setNibbleNull(final int chunkX, final int chunkY, final int chunkZ) { -+ final SWMRNibbleArray nibble = this.getNibbleFromCache(chunkX, chunkY, chunkZ); -+ if (nibble != null) { -+ // de-initialisation is not as straightforward as with sky data, since deinit of block light is typically -+ // because a block was removed - which can decrease light. with sky data, block breaking can only result -+ // in increases, and thus the existing sky block check will actually correctly propagate light through -+ // a null section. so in order to propagate decreases correctly, we can do a couple of things: not remove -+ // the data section, or do edge checks on ALL axis (x, y, z). however I do not want edge checks running -+ // for clients at all, as they are expensive. so we don't remove the section, but to maintain the appearence -+ // of vanilla data management we "hide" them. -+ nibble.setHidden(); -+ } -+ } -+ -+ @Override -+ protected void initNibble(final int chunkX, final int chunkY, final int chunkZ, final boolean extrude, final boolean initRemovedNibbles) { -+ if (chunkY < this.minLightSection || chunkY > this.maxLightSection || this.getChunkInCache(chunkX, chunkZ) == null) { -+ return; -+ } -+ -+ final SWMRNibbleArray nibble = this.getNibbleFromCache(chunkX, chunkY, chunkZ); -+ if (nibble == null) { -+ if (!initRemovedNibbles) { -+ throw new IllegalStateException(); -+ } else { -+ this.setNibbleInCache(chunkX, chunkY, chunkZ, new SWMRNibbleArray()); -+ } -+ } else { -+ nibble.setNonNull(); -+ } -+ } -+ -+ @Override -+ protected final void checkBlock(final LightChunkGetter lightAccess, final int worldX, final int worldY, final int worldZ) { -+ // blocks can change opacity -+ // blocks can change emitted light -+ // blocks can change direction of propagation -+ -+ final int encodeOffset = this.coordinateOffset; -+ final int emittedMask = this.emittedLightMask; -+ -+ final int currentLevel = this.getLightLevel(worldX, worldY, worldZ); -+ final BlockState blockState = this.getBlockState(worldX, worldY, worldZ); -+ final int emittedLevel = blockState.getLightEmission() & emittedMask; -+ -+ this.setLightLevel(worldX, worldY, worldZ, emittedLevel); -+ // this accounts for change in emitted light that would cause an increase -+ if (emittedLevel != 0) { -+ this.appendToIncreaseQueue( -+ ((worldX + (worldZ << 6) + (worldY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | (emittedLevel & 0xFL) << (6 + 6 + 16) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (blockState.isConditionallyFullOpaque() ? FLAG_HAS_SIDED_TRANSPARENT_BLOCKS : 0) -+ ); -+ } -+ // this also accounts for a change in emitted light that would cause a decrease -+ // this also accounts for the change of direction of propagation (i.e old block was full transparent, new block is full opaque or vice versa) -+ // as it checks all neighbours (even if current level is 0) -+ this.appendToDecreaseQueue( -+ ((worldX + (worldZ << 6) + (worldY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | (currentLevel & 0xFL) << (6 + 6 + 16) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ // always keep sided transparent false here, new block might be conditionally transparent which would -+ // prevent us from decreasing sources in the directions where the new block is opaque -+ // if it turns out we were wrong to de-propagate the source, the re-propagate logic WILL always -+ // catch that and fix it. -+ ); -+ // re-propagating neighbours (done by the decrease queue) will also account for opacity changes in this block -+ } -+ -+ protected final BlockPos.MutableBlockPos recalcCenterPos = new BlockPos.MutableBlockPos(); -+ protected final BlockPos.MutableBlockPos recalcNeighbourPos = new BlockPos.MutableBlockPos(); -+ -+ @Override -+ protected int calculateLightValue(final LightChunkGetter lightAccess, final int worldX, final int worldY, final int worldZ, -+ final int expect) { -+ final BlockState centerState = this.getBlockState(worldX, worldY, worldZ); -+ int level = centerState.getLightEmission() & 0xF; -+ -+ if (level >= (15 - 1) || level > expect) { -+ return level; -+ } -+ -+ final int sectionOffset = this.chunkSectionIndexOffset; -+ final BlockState conditionallyOpaqueState; -+ int opacity = centerState.getOpacityIfCached(); -+ -+ if (opacity == -1) { -+ this.recalcCenterPos.set(worldX, worldY, worldZ); -+ opacity = centerState.getLightBlock(lightAccess.getLevel(), this.recalcCenterPos); -+ if (centerState.isConditionallyFullOpaque()) { -+ conditionallyOpaqueState = centerState; -+ } else { -+ conditionallyOpaqueState = null; -+ } -+ } else if (opacity >= 15) { -+ return level; -+ } else { -+ conditionallyOpaqueState = null; -+ } -+ opacity = Math.max(1, opacity); -+ -+ for (final AxisDirection direction : AXIS_DIRECTIONS) { -+ final int offX = worldX + direction.x; -+ final int offY = worldY + direction.y; -+ final int offZ = worldZ + direction.z; -+ -+ final int sectionIndex = (offX >> 4) + 5 * (offZ >> 4) + (5 * 5) * (offY >> 4) + sectionOffset; -+ -+ final int neighbourLevel = this.getLightLevel(sectionIndex, (offX & 15) | ((offZ & 15) << 4) | ((offY & 15) << 8)); -+ -+ if ((neighbourLevel - 1) <= level) { -+ // don't need to test transparency, we know it wont affect the result. -+ continue; -+ } -+ -+ final BlockState neighbourState = this.getBlockState(offX, offY, offZ); -+ if (neighbourState.isConditionallyFullOpaque()) { -+ // here the block can be conditionally opaque (i.e light cannot propagate from it), so we need to test that -+ // we don't read the blockstate because most of the time this is false, so using the faster -+ // known transparency lookup results in a net win -+ this.recalcNeighbourPos.set(offX, offY, offZ); -+ final VoxelShape neighbourFace = neighbourState.getFaceOcclusionShape(lightAccess.getLevel(), this.recalcNeighbourPos, direction.opposite.nms); -+ final VoxelShape thisFace = conditionallyOpaqueState == null ? Shapes.empty() : conditionallyOpaqueState.getFaceOcclusionShape(lightAccess.getLevel(), this.recalcCenterPos, direction.nms); -+ if (Shapes.faceShapeOccludes(thisFace, neighbourFace)) { -+ // not allowed to propagate -+ continue; -+ } -+ } -+ -+ // passed transparency, -+ -+ final int calculated = neighbourLevel - opacity; -+ level = Math.max(calculated, level); -+ if (level > expect) { -+ return level; -+ } -+ } -+ -+ return level; -+ } -+ -+ @Override -+ protected void propagateBlockChanges(final LightChunkGetter lightAccess, final ChunkAccess atChunk, final Set positions) { -+ for (final BlockPos pos : positions) { -+ this.checkBlock(lightAccess, pos.getX(), pos.getY(), pos.getZ()); -+ } -+ -+ this.performLightDecrease(lightAccess); -+ } -+ -+ protected List getSources(final LightChunkGetter lightAccess, final ChunkAccess chunk) { -+ final List sources = new ArrayList<>(); -+ -+ final int offX = chunk.getPos().x << 4; -+ final int offZ = chunk.getPos().z << 4; -+ -+ final LevelChunkSection[] sections = chunk.getSections(); -+ for (int sectionY = this.minSection; sectionY <= this.maxSection; ++sectionY) { -+ final LevelChunkSection section = sections[sectionY - this.minSection]; -+ if (section == null || section.hasOnlyAir()) { -+ // no sources in empty sections -+ continue; -+ } -+ if (!section.maybeHas((final BlockState state) -> { -+ return state.getLightEmission() > 0; -+ })) { -+ // no light sources in palette -+ continue; -+ } -+ final PalettedContainer states = section.states; -+ final int offY = sectionY << 4; -+ -+ for (int index = 0; index < (16 * 16 * 16); ++index) { -+ final BlockState state = states.get(index); -+ if (state.getLightEmission() <= 0) { -+ continue; -+ } -+ -+ // index = x | (z << 4) | (y << 8) -+ sources.add(new BlockPos(offX | (index & 15), offY | (index >>> 8), offZ | ((index >>> 4) & 15))); -+ } -+ } -+ -+ return sources; -+ } -+ -+ @Override -+ public void lightChunk(final LightChunkGetter lightAccess, final ChunkAccess chunk, final boolean needsEdgeChecks) { -+ // setup sources -+ final int emittedMask = this.emittedLightMask; -+ final List positions = this.getSources(lightAccess, chunk); -+ for (int i = 0, len = positions.size(); i < len; ++i) { -+ final BlockPos pos = positions.get(i); -+ final BlockState blockState = this.getBlockState(pos.getX(), pos.getY(), pos.getZ()); -+ final int emittedLight = blockState.getLightEmission() & emittedMask; -+ -+ if (emittedLight <= this.getLightLevel(pos.getX(), pos.getY(), pos.getZ())) { -+ // some other source is brighter -+ continue; -+ } -+ -+ this.appendToIncreaseQueue( -+ ((pos.getX() + (pos.getZ() << 6) + (pos.getY() << (6 + 6)) + this.coordinateOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | (emittedLight & 0xFL) << (6 + 6 + 16) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (blockState.isConditionallyFullOpaque() ? FLAG_HAS_SIDED_TRANSPARENT_BLOCKS : 0) -+ ); -+ -+ -+ // propagation wont set this for us -+ this.setLightLevel(pos.getX(), pos.getY(), pos.getZ(), emittedLight); -+ } -+ -+ if (needsEdgeChecks) { -+ // not required to propagate here, but this will reduce the hit of the edge checks -+ this.performLightIncrease(lightAccess); -+ -+ // verify neighbour edges -+ this.checkChunkEdges(lightAccess, chunk, this.minLightSection, this.maxLightSection); -+ } else { -+ this.propagateNeighbourLevels(lightAccess, chunk, this.minLightSection, this.maxLightSection); -+ -+ this.performLightIncrease(lightAccess); -+ } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/starlight/common/light/SWMRNibbleArray.java b/src/main/java/ca/spottedleaf/starlight/common/light/SWMRNibbleArray.java -new file mode 100644 -index 0000000000000000000000000000000000000000..4ffb4ffe01c4628d52742c5c0bbd35220eea6294 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/starlight/common/light/SWMRNibbleArray.java -@@ -0,0 +1,440 @@ -+package ca.spottedleaf.starlight.common.light; -+ -+import net.minecraft.world.level.chunk.DataLayer; -+import java.util.ArrayDeque; -+import java.util.Arrays; -+ -+// SWMR -> Single Writer Multi Reader Nibble Array -+public final class SWMRNibbleArray { -+ -+ /* -+ * Null nibble - nibble does not exist, and should not be written to. Just like vanilla - null -+ * nibbles are always 0 - and they are never written to directly. Only initialised/uninitialised -+ * nibbles can be written to. -+ * -+ * Uninitialised nibble - They are all 0, but the backing array isn't initialised. -+ * -+ * Initialised nibble - Has light data. -+ */ -+ -+ protected static final int INIT_STATE_NULL = 0; // null -+ protected static final int INIT_STATE_UNINIT = 1; // uninitialised -+ protected static final int INIT_STATE_INIT = 2; // initialised -+ protected static final int INIT_STATE_HIDDEN = 3; // initialised, but conversion to Vanilla data should be treated as if NULL -+ -+ public static final int ARRAY_SIZE = 16 * 16 * 16 / (8/4); // blocks / bytes per block -+ // this allows us to maintain only 1 byte array when we're not updating -+ static final ThreadLocal> WORKING_BYTES_POOL = ThreadLocal.withInitial(ArrayDeque::new); -+ -+ private static byte[] allocateBytes() { -+ final byte[] inPool = WORKING_BYTES_POOL.get().pollFirst(); -+ if (inPool != null) { -+ return inPool; -+ } -+ -+ return new byte[ARRAY_SIZE]; -+ } -+ -+ private static void freeBytes(final byte[] bytes) { -+ WORKING_BYTES_POOL.get().addFirst(bytes); -+ } -+ -+ public static SWMRNibbleArray fromVanilla(final DataLayer nibble) { -+ if (nibble == null) { -+ return new SWMRNibbleArray(null, true); -+ } else if (nibble.isEmpty()) { -+ return new SWMRNibbleArray(); -+ } else { -+ return new SWMRNibbleArray(nibble.getData().clone()); // make sure we don't write to the parameter later -+ } -+ } -+ -+ protected int stateUpdating; -+ protected volatile int stateVisible; -+ -+ protected byte[] storageUpdating; -+ protected boolean updatingDirty; // only returns whether storageUpdating is dirty -+ protected volatile byte[] storageVisible; -+ -+ public SWMRNibbleArray() { -+ this(null, false); // lazy init -+ } -+ -+ public SWMRNibbleArray(final byte[] bytes) { -+ this(bytes, false); -+ } -+ -+ public SWMRNibbleArray(final byte[] bytes, final boolean isNullNibble) { -+ if (bytes != null && bytes.length != ARRAY_SIZE) { -+ throw new IllegalArgumentException("Data of wrong length: " + bytes.length); -+ } -+ this.stateVisible = this.stateUpdating = bytes == null ? (isNullNibble ? INIT_STATE_NULL : INIT_STATE_UNINIT) : INIT_STATE_INIT; -+ this.storageUpdating = this.storageVisible = bytes; -+ } -+ -+ public SWMRNibbleArray(final byte[] bytes, final int state) { -+ if (bytes != null && bytes.length != ARRAY_SIZE) { -+ throw new IllegalArgumentException("Data of wrong length: " + bytes.length); -+ } -+ if (bytes == null && (state == INIT_STATE_INIT || state == INIT_STATE_HIDDEN)) { -+ throw new IllegalArgumentException("Data cannot be null and have state be initialised"); -+ } -+ this.stateUpdating = this.stateVisible = state; -+ this.storageUpdating = this.storageVisible = bytes; -+ } -+ -+ @Override -+ public String toString() { -+ StringBuilder stringBuilder = new StringBuilder(); -+ stringBuilder.append("State: "); -+ switch (this.stateVisible) { -+ case INIT_STATE_NULL: -+ stringBuilder.append("null"); -+ break; -+ case INIT_STATE_UNINIT: -+ stringBuilder.append("uninitialised"); -+ break; -+ case INIT_STATE_INIT: -+ stringBuilder.append("initialised"); -+ break; -+ case INIT_STATE_HIDDEN: -+ stringBuilder.append("hidden"); -+ break; -+ default: -+ stringBuilder.append("unknown"); -+ break; -+ } -+ stringBuilder.append("\nData:\n"); -+ -+ final byte[] data = this.storageVisible; -+ if (data != null) { -+ for (int i = 0; i < 4096; ++i) { -+ // Copied from NibbleArray#toString -+ final int level = ((data[i >>> 1] >>> ((i & 1) << 2)) & 0xF); -+ -+ stringBuilder.append(Integer.toHexString(level)); -+ if ((i & 15) == 15) { -+ stringBuilder.append("\n"); -+ } -+ -+ if ((i & 255) == 255) { -+ stringBuilder.append("\n"); -+ } -+ } -+ } else { -+ stringBuilder.append("null"); -+ } -+ -+ return stringBuilder.toString(); -+ } -+ -+ public SaveState getSaveState() { -+ synchronized (this) { -+ final int state = this.stateVisible; -+ final byte[] data = this.storageVisible; -+ if (state == INIT_STATE_NULL) { -+ return null; -+ } -+ if (state == INIT_STATE_UNINIT) { -+ return new SaveState(null, state); -+ } -+ final boolean zero = isAllZero(data); -+ if (zero) { -+ return state == INIT_STATE_INIT ? new SaveState(null, INIT_STATE_UNINIT) : null; -+ } else { -+ return new SaveState(data.clone(), state); -+ } -+ } -+ } -+ -+ protected static boolean isAllZero(final byte[] data) { -+ for (int i = 0; i < (ARRAY_SIZE >>> 4); ++i) { -+ byte whole = data[i << 4]; -+ -+ for (int k = 1; k < (1 << 4); ++k) { -+ whole |= data[(i << 4) | k]; -+ } -+ -+ if (whole != 0) { -+ return false; -+ } -+ } -+ -+ return true; -+ } -+ -+ // operation type: updating on src, updating on other -+ public void extrudeLower(final SWMRNibbleArray other) { -+ if (other.stateUpdating == INIT_STATE_NULL) { -+ throw new IllegalArgumentException(); -+ } -+ -+ if (other.storageUpdating == null) { -+ this.setUninitialised(); -+ return; -+ } -+ -+ final byte[] src = other.storageUpdating; -+ final byte[] into; -+ -+ if (!this.updatingDirty) { -+ if (this.storageUpdating != null) { -+ into = this.storageUpdating = allocateBytes(); -+ } else { -+ this.storageUpdating = into = allocateBytes(); -+ this.stateUpdating = INIT_STATE_INIT; -+ } -+ this.updatingDirty = true; -+ } else { -+ into = this.storageUpdating; -+ } -+ -+ final int start = 0; -+ final int end = (15 | (15 << 4)) >>> 1; -+ -+ /* x | (z << 4) | (y << 8) */ -+ for (int y = 0; y <= 15; ++y) { -+ System.arraycopy(src, start, into, y << (8 - 1), end - start + 1); -+ } -+ } -+ -+ // operation type: updating -+ public void setFull() { -+ if (this.stateUpdating != INIT_STATE_HIDDEN) { -+ this.stateUpdating = INIT_STATE_INIT; -+ } -+ Arrays.fill(this.storageUpdating == null || !this.updatingDirty ? this.storageUpdating = allocateBytes() : this.storageUpdating, (byte)-1); -+ this.updatingDirty = true; -+ } -+ -+ // operation type: updating -+ public void setZero() { -+ if (this.stateUpdating != INIT_STATE_HIDDEN) { -+ this.stateUpdating = INIT_STATE_INIT; -+ } -+ Arrays.fill(this.storageUpdating == null || !this.updatingDirty ? this.storageUpdating = allocateBytes() : this.storageUpdating, (byte)0); -+ this.updatingDirty = true; -+ } -+ -+ // operation type: updating -+ public void setNonNull() { -+ if (this.stateUpdating == INIT_STATE_HIDDEN) { -+ this.stateUpdating = INIT_STATE_INIT; -+ return; -+ } -+ if (this.stateUpdating != INIT_STATE_NULL) { -+ return; -+ } -+ this.stateUpdating = INIT_STATE_UNINIT; -+ } -+ -+ // operation type: updating -+ public void setNull() { -+ this.stateUpdating = INIT_STATE_NULL; -+ if (this.updatingDirty && this.storageUpdating != null) { -+ freeBytes(this.storageUpdating); -+ } -+ this.storageUpdating = null; -+ this.updatingDirty = false; -+ } -+ -+ // operation type: updating -+ public void setUninitialised() { -+ this.stateUpdating = INIT_STATE_UNINIT; -+ if (this.storageUpdating != null && this.updatingDirty) { -+ freeBytes(this.storageUpdating); -+ } -+ this.storageUpdating = null; -+ this.updatingDirty = false; -+ } -+ -+ // operation type: updating -+ public void setHidden() { -+ if (this.stateUpdating == INIT_STATE_HIDDEN) { -+ return; -+ } -+ if (this.stateUpdating != INIT_STATE_INIT) { -+ this.setNull(); -+ } else { -+ this.stateUpdating = INIT_STATE_HIDDEN; -+ } -+ } -+ -+ // operation type: updating -+ public boolean isDirty() { -+ return this.stateUpdating != this.stateVisible || this.updatingDirty; -+ } -+ -+ // operation type: updating -+ public boolean isNullNibbleUpdating() { -+ return this.stateUpdating == INIT_STATE_NULL; -+ } -+ -+ // operation type: visible -+ public boolean isNullNibbleVisible() { -+ return this.stateVisible == INIT_STATE_NULL; -+ } -+ -+ // opeartion type: updating -+ public boolean isUninitialisedUpdating() { -+ return this.stateUpdating == INIT_STATE_UNINIT; -+ } -+ -+ // operation type: visible -+ public boolean isUninitialisedVisible() { -+ return this.stateVisible == INIT_STATE_UNINIT; -+ } -+ -+ // operation type: updating -+ public boolean isInitialisedUpdating() { -+ return this.stateUpdating == INIT_STATE_INIT; -+ } -+ -+ // operation type: visible -+ public boolean isInitialisedVisible() { -+ return this.stateVisible == INIT_STATE_INIT; -+ } -+ -+ // operation type: updating -+ public boolean isHiddenUpdating() { -+ return this.stateUpdating == INIT_STATE_HIDDEN; -+ } -+ -+ // operation type: updating -+ public boolean isHiddenVisible() { -+ return this.stateVisible == INIT_STATE_HIDDEN; -+ } -+ -+ // operation type: updating -+ protected void swapUpdatingAndMarkDirty() { -+ if (this.updatingDirty) { -+ return; -+ } -+ -+ if (this.storageUpdating == null) { -+ this.storageUpdating = allocateBytes(); -+ Arrays.fill(this.storageUpdating, (byte)0); -+ } else { -+ System.arraycopy(this.storageUpdating, 0, this.storageUpdating = allocateBytes(), 0, ARRAY_SIZE); -+ } -+ -+ if (this.stateUpdating != INIT_STATE_HIDDEN) { -+ this.stateUpdating = INIT_STATE_INIT; -+ } -+ this.updatingDirty = true; -+ } -+ -+ // operation type: updating -+ public boolean updateVisible() { -+ if (!this.isDirty()) { -+ return false; -+ } -+ -+ synchronized (this) { -+ if (this.stateUpdating == INIT_STATE_NULL || this.stateUpdating == INIT_STATE_UNINIT) { -+ this.storageVisible = null; -+ } else { -+ if (this.storageVisible == null) { -+ this.storageVisible = this.storageUpdating.clone(); -+ } else { -+ if (this.storageUpdating != this.storageVisible) { -+ System.arraycopy(this.storageUpdating, 0, this.storageVisible, 0, ARRAY_SIZE); -+ } -+ } -+ -+ if (this.storageUpdating != this.storageVisible) { -+ freeBytes(this.storageUpdating); -+ } -+ this.storageUpdating = this.storageVisible; -+ } -+ this.updatingDirty = false; -+ this.stateVisible = this.stateUpdating; -+ } -+ -+ return true; -+ } -+ -+ // operation type: visible -+ public DataLayer toVanillaNibble() { -+ synchronized (this) { -+ switch (this.stateVisible) { -+ case INIT_STATE_HIDDEN: -+ case INIT_STATE_NULL: -+ return null; -+ case INIT_STATE_UNINIT: -+ return new DataLayer(); -+ case INIT_STATE_INIT: -+ return new DataLayer(this.storageVisible.clone()); -+ default: -+ throw new IllegalStateException(); -+ } -+ } -+ } -+ -+ /* x | (z << 4) | (y << 8) */ -+ -+ // operation type: updating -+ public int getUpdating(final int x, final int y, final int z) { -+ return this.getUpdating((x & 15) | ((z & 15) << 4) | ((y & 15) << 8)); -+ } -+ -+ // operation type: updating -+ public int getUpdating(final int index) { -+ // indices range from 0 -> 4096 -+ final byte[] bytes = this.storageUpdating; -+ if (bytes == null) { -+ return 0; -+ } -+ final byte value = bytes[index >>> 1]; -+ -+ // if we are an even index, we want lower 4 bits -+ // if we are an odd index, we want upper 4 bits -+ return ((value >>> ((index & 1) << 2)) & 0xF); -+ } -+ -+ // operation type: visible -+ public int getVisible(final int x, final int y, final int z) { -+ return this.getVisible((x & 15) | ((z & 15) << 4) | ((y & 15) << 8)); -+ } -+ -+ // operation type: visible -+ public int getVisible(final int index) { -+ // indices range from 0 -> 4096 -+ final byte[] visibleBytes = this.storageVisible; -+ if (visibleBytes == null) { -+ return 0; -+ } -+ final byte value = visibleBytes[index >>> 1]; -+ -+ // if we are an even index, we want lower 4 bits -+ // if we are an odd index, we want upper 4 bits -+ return ((value >>> ((index & 1) << 2)) & 0xF); -+ } -+ -+ // operation type: updating -+ public void set(final int x, final int y, final int z, final int value) { -+ this.set((x & 15) | ((z & 15) << 4) | ((y & 15) << 8), value); -+ } -+ -+ // operation type: updating -+ public void set(final int index, final int value) { -+ if (!this.updatingDirty) { -+ this.swapUpdatingAndMarkDirty(); -+ } -+ final int shift = (index & 1) << 2; -+ final int i = index >>> 1; -+ -+ this.storageUpdating[i] = (byte)((this.storageUpdating[i] & (0xF0 >>> shift)) | (value << shift)); -+ } -+ -+ public static final class SaveState { -+ -+ public final byte[] data; -+ public final int state; -+ -+ public SaveState(final byte[] data, final int state) { -+ this.data = data; -+ this.state = state; -+ } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/starlight/common/light/SkyStarLightEngine.java b/src/main/java/ca/spottedleaf/starlight/common/light/SkyStarLightEngine.java -new file mode 100644 -index 0000000000000000000000000000000000000000..43a2cce467d29f81ba57d77c03608e57857dd579 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/starlight/common/light/SkyStarLightEngine.java -@@ -0,0 +1,709 @@ -+package ca.spottedleaf.starlight.common.light; -+ -+import ca.spottedleaf.starlight.common.util.WorldUtil; -+import it.unimi.dsi.fastutil.shorts.ShortCollection; -+import it.unimi.dsi.fastutil.shorts.ShortIterator; -+import net.minecraft.core.BlockPos; -+import net.minecraft.world.level.BlockGetter; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.status.ChunkStatus; -+import net.minecraft.world.level.chunk.LevelChunkSection; -+import net.minecraft.world.level.chunk.LightChunkGetter; -+import net.minecraft.world.phys.shapes.Shapes; -+import net.minecraft.world.phys.shapes.VoxelShape; -+import java.util.Arrays; -+import java.util.Set; -+ -+public final class SkyStarLightEngine extends StarLightEngine { -+ -+ /* -+ Specification for managing the initialisation and de-initialisation of skylight nibble arrays: -+ -+ Skylight nibble initialisation requires that non-empty chunk sections have 1 radius nibbles non-null. -+ -+ This presents some problems, as vanilla is only guaranteed to have 0 radius neighbours loaded when editing blocks. -+ However starlight fixes this so that it has 1 radius loaded. Still, we don't actually have guarantees -+ that we have the necessary chunks loaded to de-initialise neighbour sections (but we do have enough to de-initialise -+ our own) - we need a radius of 2 to de-initialise neighbour nibbles. -+ How do we solve this? -+ -+ Each chunk will store the last known "emptiness" of sections for each of their 1 radius neighbour chunk sections. -+ If the chunk does not have full data, then its nibbles are NOT de-initialised. This is because obviously the -+ chunk did not go through the light stage yet - or its neighbours are not lit. In either case, once the last -+ known "emptiness" of neighbouring sections is filled with data, the chunk will run a full check of the data -+ to see if any of its nibbles need to be de-initialised. -+ -+ The emptiness map allows us to de-initialise neighbour nibbles if the neighbour has it filled with data, -+ and if it doesn't have data then we know it will correctly de-initialise once it fills up. -+ -+ Unlike vanilla, we store whether nibbles are uninitialised on disk - so we don't need any dumb hacking -+ around those. -+ */ -+ -+ protected final int[] heightMapBlockChange = new int[16 * 16]; -+ { -+ Arrays.fill(this.heightMapBlockChange, Integer.MIN_VALUE); // clear heightmap -+ } -+ -+ protected final boolean[] nullPropagationCheckCache; -+ -+ public SkyStarLightEngine(final Level world) { -+ super(true, world); -+ this.nullPropagationCheckCache = new boolean[WorldUtil.getTotalLightSections(world)]; -+ } -+ -+ @Override -+ protected void initNibble(final int chunkX, final int chunkY, final int chunkZ, final boolean extrude, final boolean initRemovedNibbles) { -+ if (chunkY < this.minLightSection || chunkY > this.maxLightSection || this.getChunkInCache(chunkX, chunkZ) == null) { -+ return; -+ } -+ SWMRNibbleArray nibble = this.getNibbleFromCache(chunkX, chunkY, chunkZ); -+ if (nibble == null) { -+ if (!initRemovedNibbles) { -+ throw new IllegalStateException(); -+ } else { -+ this.setNibbleInCache(chunkX, chunkY, chunkZ, nibble = new SWMRNibbleArray(null, true)); -+ } -+ } -+ this.initNibble(nibble, chunkX, chunkY, chunkZ, extrude); -+ } -+ -+ @Override -+ protected void setNibbleNull(final int chunkX, final int chunkY, final int chunkZ) { -+ final SWMRNibbleArray nibble = this.getNibbleFromCache(chunkX, chunkY, chunkZ); -+ if (nibble != null) { -+ nibble.setNull(); -+ } -+ } -+ -+ protected final void initNibble(final SWMRNibbleArray currNibble, final int chunkX, final int chunkY, final int chunkZ, final boolean extrude) { -+ if (!currNibble.isNullNibbleUpdating()) { -+ // already initialised -+ return; -+ } -+ -+ final boolean[] emptinessMap = this.getEmptinessMap(chunkX, chunkZ); -+ -+ // are we above this chunk's lowest empty section? -+ int lowestY = this.minLightSection - 1; -+ for (int currY = this.maxSection; currY >= this.minSection; --currY) { -+ if (emptinessMap == null) { -+ // cannot delay nibble init for lit chunks, as we need to init to propagate into them. -+ final LevelChunkSection current = this.getChunkSection(chunkX, currY, chunkZ); -+ if (current == null || current.hasOnlyAir()) { -+ continue; -+ } -+ } else { -+ if (emptinessMap[currY - this.minSection]) { -+ continue; -+ } -+ } -+ -+ // should always be full lit here -+ lowestY = currY; -+ break; -+ } -+ -+ if (chunkY > lowestY) { -+ // we need to set this one to full -+ final SWMRNibbleArray nibble = this.getNibbleFromCache(chunkX, chunkY, chunkZ); -+ nibble.setNonNull(); -+ nibble.setFull(); -+ return; -+ } -+ -+ if (extrude) { -+ // this nibble is going to depend solely on the skylight data above it -+ // find first non-null data above (there does exist one, as we just found it above) -+ for (int currY = chunkY + 1; currY <= this.maxLightSection; ++currY) { -+ final SWMRNibbleArray nibble = this.getNibbleFromCache(chunkX, currY, chunkZ); -+ if (nibble != null && !nibble.isNullNibbleUpdating()) { -+ currNibble.setNonNull(); -+ currNibble.extrudeLower(nibble); -+ break; -+ } -+ } -+ } else { -+ currNibble.setNonNull(); -+ } -+ } -+ -+ protected final void rewriteNibbleCacheForSkylight(final ChunkAccess chunk) { -+ for (int index = 0, max = this.nibbleCache.length; index < max; ++index) { -+ final SWMRNibbleArray nibble = this.nibbleCache[index]; -+ if (nibble != null && nibble.isNullNibbleUpdating()) { -+ // stop propagation in these areas -+ this.nibbleCache[index] = null; -+ nibble.updateVisible(); -+ } -+ } -+ } -+ -+ // rets whether neighbours were init'd -+ -+ protected final boolean checkNullSection(final int chunkX, final int chunkY, final int chunkZ, -+ final boolean extrudeInitialised) { -+ // null chunk sections may have nibble neighbours in the horizontal 1 radius that are -+ // non-null. Propagation to these neighbours is necessary. -+ // What makes this easy is we know none of these neighbours are non-empty (otherwise -+ // this nibble would be initialised). So, we don't have to initialise -+ // the neighbours in the full 1 radius, because there's no worry that any "paths" -+ // to the neighbours on this horizontal plane are blocked. -+ if (chunkY < this.minLightSection || chunkY > this.maxLightSection || this.nullPropagationCheckCache[chunkY - this.minLightSection]) { -+ return false; -+ } -+ this.nullPropagationCheckCache[chunkY - this.minLightSection] = true; -+ -+ // check horizontal neighbours -+ boolean needInitNeighbours = false; -+ neighbour_search: -+ for (int dz = -1; dz <= 1; ++dz) { -+ for (int dx = -1; dx <= 1; ++dx) { -+ final SWMRNibbleArray nibble = this.getNibbleFromCache(dx + chunkX, chunkY, dz + chunkZ); -+ if (nibble != null && !nibble.isNullNibbleUpdating()) { -+ needInitNeighbours = true; -+ break neighbour_search; -+ } -+ } -+ } -+ -+ if (needInitNeighbours) { -+ for (int dz = -1; dz <= 1; ++dz) { -+ for (int dx = -1; dx <= 1; ++dx) { -+ this.initNibble(dx + chunkX, chunkY, dz + chunkZ, (dx | dz) == 0 ? extrudeInitialised : true, true); -+ } -+ } -+ } -+ -+ return needInitNeighbours; -+ } -+ -+ protected final int getLightLevelExtruded(final int worldX, final int worldY, final int worldZ) { -+ final int chunkX = worldX >> 4; -+ int chunkY = worldY >> 4; -+ final int chunkZ = worldZ >> 4; -+ -+ SWMRNibbleArray nibble = this.getNibbleFromCache(chunkX, chunkY, chunkZ); -+ if (nibble != null) { -+ return nibble.getUpdating(worldX, worldY, worldZ); -+ } -+ -+ for (;;) { -+ if (++chunkY > this.maxLightSection) { -+ return 15; -+ } -+ -+ nibble = this.getNibbleFromCache(chunkX, chunkY, chunkZ); -+ -+ if (nibble != null) { -+ return nibble.getUpdating(worldX, 0, worldZ); -+ } -+ } -+ } -+ -+ @Override -+ protected boolean[] getEmptinessMap(final ChunkAccess chunk) { -+ return chunk.getSkyEmptinessMap(); -+ } -+ -+ @Override -+ protected void setEmptinessMap(final ChunkAccess chunk, final boolean[] to) { -+ chunk.setSkyEmptinessMap(to); -+ } -+ -+ @Override -+ protected SWMRNibbleArray[] getNibblesOnChunk(final ChunkAccess chunk) { -+ return chunk.getSkyNibbles(); -+ } -+ -+ @Override -+ protected void setNibbles(final ChunkAccess chunk, final SWMRNibbleArray[] to) { -+ chunk.setSkyNibbles(to); -+ } -+ -+ @Override -+ protected boolean canUseChunk(final ChunkAccess chunk) { -+ // can only use chunks for sky stuff if their sections have been init'd -+ return chunk.getStatus().isOrAfter(ChunkStatus.LIGHT) && (this.isClientSide || chunk.isLightCorrect()); -+ } -+ -+ @Override -+ protected void checkChunkEdges(final LightChunkGetter lightAccess, final ChunkAccess chunk, final int fromSection, -+ final int toSection) { -+ Arrays.fill(this.nullPropagationCheckCache, false); -+ this.rewriteNibbleCacheForSkylight(chunk); -+ final int chunkX = chunk.getPos().x; -+ final int chunkZ = chunk.getPos().z; -+ for (int y = toSection; y >= fromSection; --y) { -+ this.checkNullSection(chunkX, y, chunkZ, true); -+ } -+ -+ super.checkChunkEdges(lightAccess, chunk, fromSection, toSection); -+ } -+ -+ @Override -+ protected void checkChunkEdges(final LightChunkGetter lightAccess, final ChunkAccess chunk, final ShortCollection sections) { -+ Arrays.fill(this.nullPropagationCheckCache, false); -+ this.rewriteNibbleCacheForSkylight(chunk); -+ final int chunkX = chunk.getPos().x; -+ final int chunkZ = chunk.getPos().z; -+ for (final ShortIterator iterator = sections.iterator(); iterator.hasNext();) { -+ final int y = (int)iterator.nextShort(); -+ this.checkNullSection(chunkX, y, chunkZ, true); -+ } -+ -+ super.checkChunkEdges(lightAccess, chunk, sections); -+ } -+ -+ @Override -+ protected void checkBlock(final LightChunkGetter lightAccess, final int worldX, final int worldY, final int worldZ) { -+ // blocks can change opacity -+ // blocks can change direction of propagation -+ -+ // same logic applies from BlockStarLightEngine#checkBlock -+ -+ final int encodeOffset = this.coordinateOffset; -+ -+ final int currentLevel = this.getLightLevel(worldX, worldY, worldZ); -+ -+ if (currentLevel == 15) { -+ // must re-propagate clobbered source -+ this.appendToIncreaseQueue( -+ ((worldX + (worldZ << 6) + (worldY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | (currentLevel & 0xFL) << (6 + 6 + 16) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | FLAG_HAS_SIDED_TRANSPARENT_BLOCKS // don't know if the block is conditionally transparent -+ ); -+ } else { -+ this.setLightLevel(worldX, worldY, worldZ, 0); -+ } -+ -+ this.appendToDecreaseQueue( -+ ((worldX + (worldZ << 6) + (worldY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | (currentLevel & 0xFL) << (6 + 6 + 16) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ ); -+ } -+ -+ protected final BlockPos.MutableBlockPos recalcCenterPos = new BlockPos.MutableBlockPos(); -+ protected final BlockPos.MutableBlockPos recalcNeighbourPos = new BlockPos.MutableBlockPos(); -+ -+ @Override -+ protected int calculateLightValue(final LightChunkGetter lightAccess, final int worldX, final int worldY, final int worldZ, -+ final int expect) { -+ if (expect == 15) { -+ return expect; -+ } -+ -+ final int sectionOffset = this.chunkSectionIndexOffset; -+ final BlockState centerState = this.getBlockState(worldX, worldY, worldZ); -+ int opacity = centerState.getOpacityIfCached(); -+ -+ final BlockState conditionallyOpaqueState; -+ if (opacity < 0) { -+ this.recalcCenterPos.set(worldX, worldY, worldZ); -+ opacity = Math.max(1, centerState.getLightBlock(lightAccess.getLevel(), this.recalcCenterPos)); -+ if (centerState.isConditionallyFullOpaque()) { -+ conditionallyOpaqueState = centerState; -+ } else { -+ conditionallyOpaqueState = null; -+ } -+ } else { -+ conditionallyOpaqueState = null; -+ opacity = Math.max(1, opacity); -+ } -+ -+ int level = 0; -+ -+ for (final AxisDirection direction : AXIS_DIRECTIONS) { -+ final int offX = worldX + direction.x; -+ final int offY = worldY + direction.y; -+ final int offZ = worldZ + direction.z; -+ -+ final int sectionIndex = (offX >> 4) + 5 * (offZ >> 4) + (5 * 5) * (offY >> 4) + sectionOffset; -+ -+ final int neighbourLevel = this.getLightLevel(sectionIndex, (offX & 15) | ((offZ & 15) << 4) | ((offY & 15) << 8)); -+ -+ if ((neighbourLevel - 1) <= level) { -+ // don't need to test transparency, we know it wont affect the result. -+ continue; -+ } -+ -+ final BlockState neighbourState = this.getBlockState(offX, offY, offZ); -+ -+ if (neighbourState.isConditionallyFullOpaque()) { -+ // here the block can be conditionally opaque (i.e light cannot propagate from it), so we need to test that -+ // we don't read the blockstate because most of the time this is false, so using the faster -+ // known transparency lookup results in a net win -+ this.recalcNeighbourPos.set(offX, offY, offZ); -+ final VoxelShape neighbourFace = neighbourState.getFaceOcclusionShape(lightAccess.getLevel(), this.recalcNeighbourPos, direction.opposite.nms); -+ final VoxelShape thisFace = conditionallyOpaqueState == null ? Shapes.empty() : conditionallyOpaqueState.getFaceOcclusionShape(lightAccess.getLevel(), this.recalcCenterPos, direction.nms); -+ if (Shapes.faceShapeOccludes(thisFace, neighbourFace)) { -+ // not allowed to propagate -+ continue; -+ } -+ } -+ -+ final int calculated = neighbourLevel - opacity; -+ level = Math.max(calculated, level); -+ if (level > expect) { -+ return level; -+ } -+ } -+ -+ return level; -+ } -+ -+ @Override -+ protected void propagateBlockChanges(final LightChunkGetter lightAccess, final ChunkAccess atChunk, final Set positions) { -+ this.rewriteNibbleCacheForSkylight(atChunk); -+ Arrays.fill(this.nullPropagationCheckCache, false); -+ -+ final BlockGetter world = lightAccess.getLevel(); -+ final int chunkX = atChunk.getPos().x; -+ final int chunkZ = atChunk.getPos().z; -+ final int heightMapOffset = chunkX * -16 + (chunkZ * (-16 * 16)); -+ -+ // setup heightmap for changes -+ for (final BlockPos pos : positions) { -+ final int index = pos.getX() + (pos.getZ() << 4) + heightMapOffset; -+ final int curr = this.heightMapBlockChange[index]; -+ if (pos.getY() > curr) { -+ this.heightMapBlockChange[index] = pos.getY(); -+ } -+ } -+ -+ // note: light sets are delayed while processing skylight source changes due to how -+ // nibbles are initialised, as we want to avoid clobbering nibble values so what when -+ // below nibbles are initialised they aren't reading from partially modified nibbles -+ -+ // now we can recalculate the sources for the changed columns -+ for (int index = 0; index < (16 * 16); ++index) { -+ final int maxY = this.heightMapBlockChange[index]; -+ if (maxY == Integer.MIN_VALUE) { -+ // not changed -+ continue; -+ } -+ this.heightMapBlockChange[index] = Integer.MIN_VALUE; // restore default for next caller -+ -+ final int columnX = (index & 15) | (chunkX << 4); -+ final int columnZ = (index >>> 4) | (chunkZ << 4); -+ -+ // try and propagate from the above y -+ // delay light set until after processing all sources to setup -+ final int maxPropagationY = this.tryPropagateSkylight(world, columnX, maxY, columnZ, true, true); -+ -+ // maxPropagationY is now the highest block that could not be propagated to -+ -+ // remove all sources below that are 15 -+ final long propagateDirection = AxisDirection.POSITIVE_Y.everythingButThisDirection; -+ final int encodeOffset = this.coordinateOffset; -+ -+ if (this.getLightLevelExtruded(columnX, maxPropagationY, columnZ) == 15) { -+ // ensure section is checked -+ this.checkNullSection(columnX >> 4, maxPropagationY >> 4, columnZ >> 4, true); -+ -+ for (int currY = maxPropagationY; currY >= (this.minLightSection << 4); --currY) { -+ if ((currY & 15) == 15) { -+ // ensure section is checked -+ this.checkNullSection(columnX >> 4, (currY >> 4), columnZ >> 4, true); -+ } -+ -+ // ensure section below is always checked -+ final SWMRNibbleArray nibble = this.getNibbleFromCache(columnX >> 4, currY >> 4, columnZ >> 4); -+ if (nibble == null) { -+ // advance currY to the the top of the section below -+ currY = (currY) & (~15); -+ // note: this value ^ is actually 1 above the top, but the loop decrements by 1 so we actually -+ // end up there -+ continue; -+ } -+ -+ if (nibble.getUpdating(columnX, currY, columnZ) != 15) { -+ break; -+ } -+ -+ // delay light set until after processing all sources to setup -+ this.appendToDecreaseQueue( -+ ((columnX + (columnZ << 6) + (currY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | (15L << (6 + 6 + 16)) -+ | (propagateDirection << (6 + 6 + 16 + 4)) -+ // do not set transparent blocks for the same reason we don't in the checkBlock method -+ ); -+ } -+ } -+ } -+ -+ // delayed light sets are processed here, and must be processed before checkBlock as checkBlock reads -+ // immediate light value -+ this.processDelayedIncreases(); -+ this.processDelayedDecreases(); -+ -+ for (final BlockPos pos : positions) { -+ this.checkBlock(lightAccess, pos.getX(), pos.getY(), pos.getZ()); -+ } -+ -+ this.performLightDecrease(lightAccess); -+ } -+ -+ protected final int[] heightMapGen = new int[32 * 32]; -+ -+ @Override -+ protected void lightChunk(final LightChunkGetter lightAccess, final ChunkAccess chunk, final boolean needsEdgeChecks) { -+ this.rewriteNibbleCacheForSkylight(chunk); -+ Arrays.fill(this.nullPropagationCheckCache, false); -+ -+ final BlockGetter world = lightAccess.getLevel(); -+ final ChunkPos chunkPos = chunk.getPos(); -+ final int chunkX = chunkPos.x; -+ final int chunkZ = chunkPos.z; -+ -+ final LevelChunkSection[] sections = chunk.getSections(); -+ -+ int highestNonEmptySection = this.maxSection; -+ while (highestNonEmptySection == (this.minSection - 1) || -+ sections[highestNonEmptySection - this.minSection] == null || sections[highestNonEmptySection - this.minSection].hasOnlyAir()) { -+ this.checkNullSection(chunkX, highestNonEmptySection, chunkZ, false); -+ // try propagate FULL to neighbours -+ -+ // check neighbours to see if we need to propagate into them -+ for (final AxisDirection direction : ONLY_HORIZONTAL_DIRECTIONS) { -+ final int neighbourX = chunkX + direction.x; -+ final int neighbourZ = chunkZ + direction.z; -+ final SWMRNibbleArray neighbourNibble = this.getNibbleFromCache(neighbourX, highestNonEmptySection, neighbourZ); -+ if (neighbourNibble == null) { -+ // unloaded neighbour -+ // most of the time we fall here -+ continue; -+ } -+ -+ // it looks like we need to propagate into the neighbour -+ -+ final int incX; -+ final int incZ; -+ final int startX; -+ final int startZ; -+ -+ if (direction.x != 0) { -+ // x direction -+ incX = 0; -+ incZ = 1; -+ -+ if (direction.x < 0) { -+ // negative -+ startX = chunkX << 4; -+ } else { -+ startX = chunkX << 4 | 15; -+ } -+ startZ = chunkZ << 4; -+ } else { -+ // z direction -+ incX = 1; -+ incZ = 0; -+ -+ if (direction.z < 0) { -+ // negative -+ startZ = chunkZ << 4; -+ } else { -+ startZ = chunkZ << 4 | 15; -+ } -+ startX = chunkX << 4; -+ } -+ -+ final int encodeOffset = this.coordinateOffset; -+ final long propagateDirection = 1L << direction.ordinal(); // we only want to check in this direction -+ -+ for (int currY = highestNonEmptySection << 4, maxY = currY | 15; currY <= maxY; ++currY) { -+ for (int i = 0, currX = startX, currZ = startZ; i < 16; ++i, currX += incX, currZ += incZ) { -+ this.appendToIncreaseQueue( -+ ((currX + (currZ << 6) + (currY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | (15L << (6 + 6 + 16)) // we know we're at full lit here -+ | (propagateDirection << (6 + 6 + 16 + 4)) -+ // no transparent flag, we know for a fact there are no blocks here that could be directionally transparent (as the section is EMPTY) -+ ); -+ } -+ } -+ } -+ -+ if (highestNonEmptySection-- == (this.minSection - 1)) { -+ break; -+ } -+ } -+ -+ if (highestNonEmptySection >= this.minSection) { -+ // fill out our other sources -+ final int minX = chunkPos.x << 4; -+ final int maxX = chunkPos.x << 4 | 15; -+ final int minZ = chunkPos.z << 4; -+ final int maxZ = chunkPos.z << 4 | 15; -+ final int startY = highestNonEmptySection << 4 | 15; -+ for (int currZ = minZ; currZ <= maxZ; ++currZ) { -+ for (int currX = minX; currX <= maxX; ++currX) { -+ this.tryPropagateSkylight(world, currX, startY + 1, currZ, false, false); -+ } -+ } -+ } // else: apparently the chunk is empty -+ -+ if (needsEdgeChecks) { -+ // not required to propagate here, but this will reduce the hit of the edge checks -+ this.performLightIncrease(lightAccess); -+ -+ for (int y = highestNonEmptySection; y >= this.minLightSection; --y) { -+ this.checkNullSection(chunkX, y, chunkZ, false); -+ } -+ // no need to rewrite the nibble cache again -+ super.checkChunkEdges(lightAccess, chunk, this.minLightSection, highestNonEmptySection); -+ } else { -+ for (int y = highestNonEmptySection; y >= this.minLightSection; --y) { -+ this.checkNullSection(chunkX, y, chunkZ, false); -+ } -+ this.propagateNeighbourLevels(lightAccess, chunk, this.minLightSection, highestNonEmptySection); -+ -+ this.performLightIncrease(lightAccess); -+ } -+ } -+ -+ protected final void processDelayedIncreases() { -+ // copied from performLightIncrease -+ final long[] queue = this.increaseQueue; -+ final int decodeOffsetX = -this.encodeOffsetX; -+ final int decodeOffsetY = -this.encodeOffsetY; -+ final int decodeOffsetZ = -this.encodeOffsetZ; -+ -+ for (int i = 0, len = this.increaseQueueInitialLength; i < len; ++i) { -+ final long queueValue = queue[i]; -+ -+ final int posX = ((int)queueValue & 63) + decodeOffsetX; -+ final int posZ = (((int)queueValue >>> 6) & 63) + decodeOffsetZ; -+ final int posY = (((int)queueValue >>> 12) & ((1 << 16) - 1)) + decodeOffsetY; -+ final int propagatedLightLevel = (int)((queueValue >>> (6 + 6 + 16)) & 0xF); -+ -+ this.setLightLevel(posX, posY, posZ, propagatedLightLevel); -+ } -+ } -+ -+ protected final void processDelayedDecreases() { -+ // copied from performLightDecrease -+ final long[] queue = this.decreaseQueue; -+ final int decodeOffsetX = -this.encodeOffsetX; -+ final int decodeOffsetY = -this.encodeOffsetY; -+ final int decodeOffsetZ = -this.encodeOffsetZ; -+ -+ for (int i = 0, len = this.decreaseQueueInitialLength; i < len; ++i) { -+ final long queueValue = queue[i]; -+ -+ final int posX = ((int)queueValue & 63) + decodeOffsetX; -+ final int posZ = (((int)queueValue >>> 6) & 63) + decodeOffsetZ; -+ final int posY = (((int)queueValue >>> 12) & ((1 << 16) - 1)) + decodeOffsetY; -+ -+ this.setLightLevel(posX, posY, posZ, 0); -+ } -+ } -+ -+ // delaying the light set is useful for block changes since they need to worry about initialising nibblearrays -+ // while also queueing light at the same time (initialising nibblearrays might depend on nibbles above, so -+ // clobbering the light values will result in broken propagation) -+ protected final int tryPropagateSkylight(final BlockGetter world, final int worldX, int startY, final int worldZ, -+ final boolean extrudeInitialised, final boolean delayLightSet) { -+ final BlockPos.MutableBlockPos mutablePos = this.mutablePos3; -+ final int encodeOffset = this.coordinateOffset; -+ final long propagateDirection = AxisDirection.POSITIVE_Y.everythingButThisDirection; // just don't check upwards. -+ -+ if (this.getLightLevelExtruded(worldX, startY + 1, worldZ) != 15) { -+ return startY; -+ } -+ -+ // ensure this section is always checked -+ this.checkNullSection(worldX >> 4, startY >> 4, worldZ >> 4, extrudeInitialised); -+ -+ BlockState above = this.getBlockState(worldX, startY + 1, worldZ); -+ -+ for (;startY >= (this.minLightSection << 4); --startY) { -+ if ((startY & 15) == 15) { -+ // ensure this section is always checked -+ this.checkNullSection(worldX >> 4, startY >> 4, worldZ >> 4, extrudeInitialised); -+ } -+ final BlockState current = this.getBlockState(worldX, startY, worldZ); -+ -+ final VoxelShape fromShape; -+ if (above.isConditionallyFullOpaque()) { -+ this.mutablePos2.set(worldX, startY + 1, worldZ); -+ fromShape = above.getFaceOcclusionShape(world, this.mutablePos2, AxisDirection.NEGATIVE_Y.nms); -+ if (Shapes.faceShapeOccludes(Shapes.empty(), fromShape)) { -+ // above wont let us propagate -+ break; -+ } -+ } else { -+ fromShape = Shapes.empty(); -+ } -+ -+ final int opacityIfCached = current.getOpacityIfCached(); -+ // does light propagate from the top down? -+ if (opacityIfCached != -1) { -+ if (opacityIfCached != 0) { -+ // we cannot propagate 15 through this -+ break; -+ } -+ // most of the time it falls here. -+ // add to propagate -+ // light set delayed until we determine if this nibble section is null -+ this.appendToIncreaseQueue( -+ ((worldX + (worldZ << 6) + (startY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | (15L << (6 + 6 + 16)) // we know we're at full lit here -+ | (propagateDirection << (6 + 6 + 16 + 4)) -+ ); -+ } else { -+ mutablePos.set(worldX, startY, worldZ); -+ long flags = 0L; -+ if (current.isConditionallyFullOpaque()) { -+ final VoxelShape cullingFace = current.getFaceOcclusionShape(world, mutablePos, AxisDirection.POSITIVE_Y.nms); -+ -+ if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { -+ // can't propagate here, we're done on this column. -+ break; -+ } -+ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -+ } -+ -+ final int opacity = current.getLightBlock(world, mutablePos); -+ if (opacity > 0) { -+ // let the queued value (if any) handle it from here. -+ break; -+ } -+ -+ // light set delayed until we determine if this nibble section is null -+ this.appendToIncreaseQueue( -+ ((worldX + (worldZ << 6) + (startY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | (15L << (6 + 6 + 16)) // we know we're at full lit here -+ | (propagateDirection << (6 + 6 + 16 + 4)) -+ | flags -+ ); -+ } -+ -+ above = current; -+ -+ if (this.getNibbleFromCache(worldX >> 4, startY >> 4, worldZ >> 4) == null) { -+ // we skip empty sections here, as this is just an easy way of making sure the above block -+ // can propagate through air. -+ -+ // nothing can propagate in null sections, remove the queue entry for it -+ --this.increaseQueueInitialLength; -+ -+ // advance currY to the the top of the section below -+ startY = (startY) & (~15); -+ // note: this value ^ is actually 1 above the top, but the loop decrements by 1 so we actually -+ // end up there -+ -+ // make sure this is marked as AIR -+ above = AIR_BLOCK_STATE; -+ } else if (!delayLightSet) { -+ this.setLightLevel(worldX, startY, worldZ, 15); -+ } -+ } -+ -+ return startY; -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/starlight/common/light/StarLightEngine.java b/src/main/java/ca/spottedleaf/starlight/common/light/StarLightEngine.java -new file mode 100644 -index 0000000000000000000000000000000000000000..ad1eeebe6de219143492b94da309cb54ae9e0a5b ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/starlight/common/light/StarLightEngine.java -@@ -0,0 +1,1572 @@ -+package ca.spottedleaf.starlight.common.light; -+ -+import ca.spottedleaf.starlight.common.util.CoordinateUtils; -+import ca.spottedleaf.starlight.common.util.IntegerUtil; -+import ca.spottedleaf.starlight.common.util.WorldUtil; -+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -+import it.unimi.dsi.fastutil.shorts.ShortCollection; -+import it.unimi.dsi.fastutil.shorts.ShortIterator; -+import net.minecraft.core.BlockPos; -+import net.minecraft.core.Direction; -+import net.minecraft.core.SectionPos; -+import net.minecraft.world.level.BlockGetter; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.LevelHeightAccessor; -+import net.minecraft.world.level.LightLayer; -+import net.minecraft.world.level.block.Blocks; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.LevelChunkSection; -+import net.minecraft.world.level.chunk.LightChunkGetter; -+import net.minecraft.world.phys.shapes.Shapes; -+import net.minecraft.world.phys.shapes.VoxelShape; -+import java.util.ArrayList; -+import java.util.Arrays; -+import java.util.List; -+import java.util.Set; -+import java.util.function.Consumer; -+import java.util.function.IntConsumer; -+ -+public abstract class StarLightEngine { -+ -+ protected static final BlockState AIR_BLOCK_STATE = Blocks.AIR.defaultBlockState(); -+ -+ protected static final AxisDirection[] DIRECTIONS = AxisDirection.values(); -+ protected static final AxisDirection[] AXIS_DIRECTIONS = DIRECTIONS; -+ protected static final AxisDirection[] ONLY_HORIZONTAL_DIRECTIONS = new AxisDirection[] { -+ AxisDirection.POSITIVE_X, AxisDirection.NEGATIVE_X, -+ AxisDirection.POSITIVE_Z, AxisDirection.NEGATIVE_Z -+ }; -+ -+ protected static enum AxisDirection { -+ -+ // Declaration order is important and relied upon. Do not change without modifying propagation code. -+ POSITIVE_X(1, 0, 0), NEGATIVE_X(-1, 0, 0), -+ POSITIVE_Z(0, 0, 1), NEGATIVE_Z(0, 0, -1), -+ POSITIVE_Y(0, 1, 0), NEGATIVE_Y(0, -1, 0); -+ -+ static { -+ POSITIVE_X.opposite = NEGATIVE_X; NEGATIVE_X.opposite = POSITIVE_X; -+ POSITIVE_Z.opposite = NEGATIVE_Z; NEGATIVE_Z.opposite = POSITIVE_Z; -+ POSITIVE_Y.opposite = NEGATIVE_Y; NEGATIVE_Y.opposite = POSITIVE_Y; -+ } -+ -+ protected AxisDirection opposite; -+ -+ public final int x; -+ public final int y; -+ public final int z; -+ public final Direction nms; -+ public final long everythingButThisDirection; -+ public final long everythingButTheOppositeDirection; -+ -+ AxisDirection(final int x, final int y, final int z) { -+ this.x = x; -+ this.y = y; -+ this.z = z; -+ this.nms = Direction.fromDelta(x, y, z); -+ this.everythingButThisDirection = (long)(ALL_DIRECTIONS_BITSET ^ (1 << this.ordinal())); -+ // positive is always even, negative is always odd. Flip the 1 bit to get the negative direction. -+ this.everythingButTheOppositeDirection = (long)(ALL_DIRECTIONS_BITSET ^ (1 << (this.ordinal() ^ 1))); -+ } -+ -+ public AxisDirection getOpposite() { -+ return this.opposite; -+ } -+ } -+ -+ // I'd like to thank https://www.seedofandromeda.com/blogs/29-fast-flood-fill-lighting-in-a-blocky-voxel-game-pt-1 -+ // for explaining how light propagates via breadth-first search -+ -+ // While the above is a good start to understanding the general idea of what the general principles are, it's not -+ // exactly how the vanilla light engine should behave for minecraft. -+ -+ // similar to the above, except the chunk section indices vary from [-1, 1], or [0, 2] -+ // for the y chunk section it's from [minLightSection, maxLightSection] or [0, maxLightSection - minLightSection] -+ // index = x + (z * 5) + (y * 25) -+ // null index indicates the chunk section doesn't exist (empty or out of bounds) -+ protected final LevelChunkSection[] sectionCache; -+ -+ // the exact same as above, except for storing fast access to SWMRNibbleArray -+ // for the y chunk section it's from [minLightSection, maxLightSection] or [0, maxLightSection - minLightSection] -+ // index = x + (z * 5) + (y * 25) -+ protected final SWMRNibbleArray[] nibbleCache; -+ -+ // the exact same as above, except for storing fast access to nibbles to call change callbacks for -+ // for the y chunk section it's from [minLightSection, maxLightSection] or [0, maxLightSection - minLightSection] -+ // index = x + (z * 5) + (y * 25) -+ protected final boolean[] notifyUpdateCache; -+ -+ // always initialsed during start of lighting. -+ // index = x + (z * 5) -+ protected final ChunkAccess[] chunkCache = new ChunkAccess[5 * 5]; -+ -+ // index = x + (z * 5) -+ protected final boolean[][] emptinessMapCache = new boolean[5 * 5][]; -+ -+ protected final BlockPos.MutableBlockPos mutablePos1 = new BlockPos.MutableBlockPos(); -+ protected final BlockPos.MutableBlockPos mutablePos2 = new BlockPos.MutableBlockPos(); -+ protected final BlockPos.MutableBlockPos mutablePos3 = new BlockPos.MutableBlockPos(); -+ -+ protected int encodeOffsetX; -+ protected int encodeOffsetY; -+ protected int encodeOffsetZ; -+ -+ protected int coordinateOffset; -+ -+ protected int chunkOffsetX; -+ protected int chunkOffsetY; -+ protected int chunkOffsetZ; -+ -+ protected int chunkIndexOffset; -+ protected int chunkSectionIndexOffset; -+ -+ protected final boolean skylightPropagator; -+ protected final int emittedLightMask; -+ protected final boolean isClientSide; -+ -+ protected final Level world; -+ protected final int minLightSection; -+ protected final int maxLightSection; -+ protected final int minSection; -+ protected final int maxSection; -+ -+ protected StarLightEngine(final boolean skylightPropagator, final Level world) { -+ this.skylightPropagator = skylightPropagator; -+ this.emittedLightMask = skylightPropagator ? 0 : 0xF; -+ this.isClientSide = world.isClientSide; -+ this.world = world; -+ this.minLightSection = WorldUtil.getMinLightSection(world); -+ this.maxLightSection = WorldUtil.getMaxLightSection(world); -+ this.minSection = WorldUtil.getMinSection(world); -+ this.maxSection = WorldUtil.getMaxSection(world); -+ -+ this.sectionCache = new LevelChunkSection[5 * 5 * ((this.maxLightSection - this.minLightSection + 1) + 2)]; // add two extra sections for buffer -+ this.nibbleCache = new SWMRNibbleArray[5 * 5 * ((this.maxLightSection - this.minLightSection + 1) + 2)]; // add two extra sections for buffer -+ this.notifyUpdateCache = new boolean[5 * 5 * ((this.maxLightSection - this.minLightSection + 1) + 2)]; // add two extra sections for buffer -+ } -+ -+ protected final void setupEncodeOffset(final int centerX, final int centerY, final int centerZ) { -+ // 31 = center + encodeOffset -+ this.encodeOffsetX = 31 - centerX; -+ this.encodeOffsetY = (-(this.minLightSection - 1) << 4); // we want 0 to be the smallest encoded value -+ this.encodeOffsetZ = 31 - centerZ; -+ -+ // coordinateIndex = x | (z << 6) | (y << 12) -+ this.coordinateOffset = this.encodeOffsetX + (this.encodeOffsetZ << 6) + (this.encodeOffsetY << 12); -+ -+ // 2 = (centerX >> 4) + chunkOffset -+ this.chunkOffsetX = 2 - (centerX >> 4); -+ this.chunkOffsetY = -(this.minLightSection - 1); // lowest should be 0 -+ this.chunkOffsetZ = 2 - (centerZ >> 4); -+ -+ // chunk index = x + (5 * z) -+ this.chunkIndexOffset = this.chunkOffsetX + (5 * this.chunkOffsetZ); -+ -+ // chunk section index = x + (5 * z) + ((5*5) * y) -+ this.chunkSectionIndexOffset = this.chunkIndexOffset + ((5 * 5) * this.chunkOffsetY); -+ } -+ -+ protected final void setupCaches(final LightChunkGetter chunkProvider, final int centerX, final int centerY, final int centerZ, -+ final boolean relaxed, final boolean tryToLoadChunksFor2Radius) { -+ final int centerChunkX = centerX >> 4; -+ final int centerChunkY = centerY >> 4; -+ final int centerChunkZ = centerZ >> 4; -+ -+ this.setupEncodeOffset(centerChunkX * 16 + 7, centerChunkY * 16 + 7, centerChunkZ * 16 + 7); -+ -+ final int radius = tryToLoadChunksFor2Radius ? 2 : 1; -+ -+ for (int dz = -radius; dz <= radius; ++dz) { -+ for (int dx = -radius; dx <= radius; ++dx) { -+ final int cx = centerChunkX + dx; -+ final int cz = centerChunkZ + dz; -+ final boolean isTwoRadius = Math.max(IntegerUtil.branchlessAbs(dx), IntegerUtil.branchlessAbs(dz)) == 2; -+ final ChunkAccess chunk = (ChunkAccess)chunkProvider.getChunkForLighting(cx, cz); -+ -+ if (chunk == null) { -+ if (relaxed | isTwoRadius) { -+ continue; -+ } -+ throw new IllegalArgumentException("Trying to propagate light update before 1 radius neighbours ready"); -+ } -+ -+ if (!this.canUseChunk(chunk)) { -+ continue; -+ } -+ -+ this.setChunkInCache(cx, cz, chunk); -+ this.setEmptinessMapCache(cx, cz, this.getEmptinessMap(chunk)); -+ if (!isTwoRadius) { -+ this.setBlocksForChunkInCache(cx, cz, chunk.getSections()); -+ this.setNibblesForChunkInCache(cx, cz, this.getNibblesOnChunk(chunk)); -+ } -+ } -+ } -+ } -+ -+ protected final ChunkAccess getChunkInCache(final int chunkX, final int chunkZ) { -+ return this.chunkCache[chunkX + 5*chunkZ + this.chunkIndexOffset]; -+ } -+ -+ protected final void setChunkInCache(final int chunkX, final int chunkZ, final ChunkAccess chunk) { -+ this.chunkCache[chunkX + 5*chunkZ + this.chunkIndexOffset] = chunk; -+ } -+ -+ protected final LevelChunkSection getChunkSection(final int chunkX, final int chunkY, final int chunkZ) { -+ return this.sectionCache[chunkX + 5*chunkZ + (5 * 5) * chunkY + this.chunkSectionIndexOffset]; -+ } -+ -+ protected final void setChunkSectionInCache(final int chunkX, final int chunkY, final int chunkZ, final LevelChunkSection section) { -+ this.sectionCache[chunkX + 5*chunkZ + 5*5*chunkY + this.chunkSectionIndexOffset] = section; -+ } -+ -+ protected final void setBlocksForChunkInCache(final int chunkX, final int chunkZ, final LevelChunkSection[] sections) { -+ for (int cy = this.minLightSection; cy <= this.maxLightSection; ++cy) { -+ this.setChunkSectionInCache(chunkX, cy, chunkZ, -+ sections == null ? null : (cy >= this.minSection && cy <= this.maxSection ? sections[cy - this.minSection] : null)); -+ } -+ } -+ -+ protected final SWMRNibbleArray getNibbleFromCache(final int chunkX, final int chunkY, final int chunkZ) { -+ return this.nibbleCache[chunkX + 5*chunkZ + (5 * 5) * chunkY + this.chunkSectionIndexOffset]; -+ } -+ -+ protected final SWMRNibbleArray[] getNibblesForChunkFromCache(final int chunkX, final int chunkZ) { -+ final SWMRNibbleArray[] ret = new SWMRNibbleArray[this.maxLightSection - this.minLightSection + 1]; -+ -+ for (int cy = this.minLightSection; cy <= this.maxLightSection; ++cy) { -+ ret[cy - this.minLightSection] = this.nibbleCache[chunkX + 5*chunkZ + (cy * (5 * 5)) + this.chunkSectionIndexOffset]; -+ } -+ -+ return ret; -+ } -+ -+ protected final void setNibbleInCache(final int chunkX, final int chunkY, final int chunkZ, final SWMRNibbleArray nibble) { -+ this.nibbleCache[chunkX + 5*chunkZ + (5 * 5) * chunkY + this.chunkSectionIndexOffset] = nibble; -+ } -+ -+ protected final void setNibblesForChunkInCache(final int chunkX, final int chunkZ, final SWMRNibbleArray[] nibbles) { -+ for (int cy = this.minLightSection; cy <= this.maxLightSection; ++cy) { -+ this.setNibbleInCache(chunkX, cy, chunkZ, nibbles == null ? null : nibbles[cy - this.minLightSection]); -+ } -+ } -+ -+ protected final void updateVisible(final LightChunkGetter lightAccess) { -+ for (int index = 0, max = this.nibbleCache.length; index < max; ++index) { -+ final SWMRNibbleArray nibble = this.nibbleCache[index]; -+ if (!this.notifyUpdateCache[index] && (nibble == null || !nibble.isDirty())) { -+ continue; -+ } -+ -+ final int chunkX = (index % 5) - this.chunkOffsetX; -+ final int chunkZ = ((index / 5) % 5) - this.chunkOffsetZ; -+ final int ySections = (this.maxSection - this.minSection) + 1; -+ final int chunkY = ((index / (5*5)) % (ySections + 2 + 2)) - this.chunkOffsetY; -+ if ((nibble != null && nibble.updateVisible()) || this.notifyUpdateCache[index]) { -+ lightAccess.onLightUpdate(this.skylightPropagator ? LightLayer.SKY : LightLayer.BLOCK, SectionPos.of(chunkX, chunkY, chunkZ)); -+ } -+ } -+ } -+ -+ protected final void destroyCaches() { -+ Arrays.fill(this.sectionCache, null); -+ Arrays.fill(this.nibbleCache, null); -+ Arrays.fill(this.chunkCache, null); -+ Arrays.fill(this.emptinessMapCache, null); -+ if (this.isClientSide) { -+ Arrays.fill(this.notifyUpdateCache, false); -+ } -+ } -+ -+ protected final BlockState getBlockState(final int worldX, final int worldY, final int worldZ) { -+ final LevelChunkSection section = this.sectionCache[(worldX >> 4) + 5 * (worldZ >> 4) + (5 * 5) * (worldY >> 4) + this.chunkSectionIndexOffset]; -+ -+ if (section != null) { -+ return section.hasOnlyAir() ? AIR_BLOCK_STATE : section.getBlockState(worldX & 15, worldY & 15, worldZ & 15); -+ } -+ -+ return AIR_BLOCK_STATE; -+ } -+ -+ protected final BlockState getBlockState(final int sectionIndex, final int localIndex) { -+ final LevelChunkSection section = this.sectionCache[sectionIndex]; -+ -+ if (section != null) { -+ return section.hasOnlyAir() ? AIR_BLOCK_STATE : section.states.get(localIndex); -+ } -+ -+ return AIR_BLOCK_STATE; -+ } -+ -+ protected final int getLightLevel(final int worldX, final int worldY, final int worldZ) { -+ final SWMRNibbleArray nibble = this.nibbleCache[(worldX >> 4) + 5 * (worldZ >> 4) + (5 * 5) * (worldY >> 4) + this.chunkSectionIndexOffset]; -+ -+ return nibble == null ? 0 : nibble.getUpdating((worldX & 15) | ((worldZ & 15) << 4) | ((worldY & 15) << 8)); -+ } -+ -+ protected final int getLightLevel(final int sectionIndex, final int localIndex) { -+ final SWMRNibbleArray nibble = this.nibbleCache[sectionIndex]; -+ -+ return nibble == null ? 0 : nibble.getUpdating(localIndex); -+ } -+ -+ protected final void setLightLevel(final int worldX, final int worldY, final int worldZ, final int level) { -+ final int sectionIndex = (worldX >> 4) + 5 * (worldZ >> 4) + (5 * 5) * (worldY >> 4) + this.chunkSectionIndexOffset; -+ final SWMRNibbleArray nibble = this.nibbleCache[sectionIndex]; -+ -+ if (nibble != null) { -+ nibble.set((worldX & 15) | ((worldZ & 15) << 4) | ((worldY & 15) << 8), level); -+ if (this.isClientSide) { -+ int cx1 = (worldX - 1) >> 4; -+ int cx2 = (worldX + 1) >> 4; -+ int cy1 = (worldY - 1) >> 4; -+ int cy2 = (worldY + 1) >> 4; -+ int cz1 = (worldZ - 1) >> 4; -+ int cz2 = (worldZ + 1) >> 4; -+ for (int x = cx1; x <= cx2; ++x) { -+ for (int y = cy1; y <= cy2; ++y) { -+ for (int z = cz1; z <= cz2; ++z) { -+ this.notifyUpdateCache[x + 5 * z + (5 * 5) * y + this.chunkSectionIndexOffset] = true; -+ } -+ } -+ } -+ } -+ } -+ } -+ -+ protected final void postLightUpdate(final int worldX, final int worldY, final int worldZ) { -+ if (this.isClientSide) { -+ int cx1 = (worldX - 1) >> 4; -+ int cx2 = (worldX + 1) >> 4; -+ int cy1 = (worldY - 1) >> 4; -+ int cy2 = (worldY + 1) >> 4; -+ int cz1 = (worldZ - 1) >> 4; -+ int cz2 = (worldZ + 1) >> 4; -+ for (int x = cx1; x <= cx2; ++x) { -+ for (int y = cy1; y <= cy2; ++y) { -+ for (int z = cz1; z <= cz2; ++z) { -+ this.notifyUpdateCache[x + (5 * z) + (5 * 5 * y) + this.chunkSectionIndexOffset] = true; -+ } -+ } -+ } -+ } -+ } -+ -+ protected final void setLightLevel(final int sectionIndex, final int localIndex, final int worldX, final int worldY, final int worldZ, final int level) { -+ final SWMRNibbleArray nibble = this.nibbleCache[sectionIndex]; -+ -+ if (nibble != null) { -+ nibble.set(localIndex, level); -+ if (this.isClientSide) { -+ int cx1 = (worldX - 1) >> 4; -+ int cx2 = (worldX + 1) >> 4; -+ int cy1 = (worldY - 1) >> 4; -+ int cy2 = (worldY + 1) >> 4; -+ int cz1 = (worldZ - 1) >> 4; -+ int cz2 = (worldZ + 1) >> 4; -+ for (int x = cx1; x <= cx2; ++x) { -+ for (int y = cy1; y <= cy2; ++y) { -+ for (int z = cz1; z <= cz2; ++z) { -+ this.notifyUpdateCache[x + (5 * z) + (5 * 5 * y) + this.chunkSectionIndexOffset] = true; -+ } -+ } -+ } -+ } -+ } -+ } -+ -+ protected final boolean[] getEmptinessMap(final int chunkX, final int chunkZ) { -+ return this.emptinessMapCache[chunkX + 5*chunkZ + this.chunkIndexOffset]; -+ } -+ -+ protected final void setEmptinessMapCache(final int chunkX, final int chunkZ, final boolean[] emptinessMap) { -+ this.emptinessMapCache[chunkX + 5*chunkZ + this.chunkIndexOffset] = emptinessMap; -+ } -+ -+ public static SWMRNibbleArray[] getFilledEmptyLight(final LevelHeightAccessor world) { -+ return getFilledEmptyLight(WorldUtil.getTotalLightSections(world)); -+ } -+ -+ private static SWMRNibbleArray[] getFilledEmptyLight(final int totalLightSections) { -+ final SWMRNibbleArray[] ret = new SWMRNibbleArray[totalLightSections]; -+ -+ for (int i = 0, len = ret.length; i < len; ++i) { -+ ret[i] = new SWMRNibbleArray(null, true); -+ } -+ -+ return ret; -+ } -+ -+ protected abstract boolean[] getEmptinessMap(final ChunkAccess chunk); -+ -+ protected abstract void setEmptinessMap(final ChunkAccess chunk, final boolean[] to); -+ -+ protected abstract SWMRNibbleArray[] getNibblesOnChunk(final ChunkAccess chunk); -+ -+ protected abstract void setNibbles(final ChunkAccess chunk, final SWMRNibbleArray[] to); -+ -+ protected abstract boolean canUseChunk(final ChunkAccess chunk); -+ -+ public final void blocksChangedInChunk(final LightChunkGetter lightAccess, final int chunkX, final int chunkZ, -+ final Set positions, final Boolean[] changedSections) { -+ this.setupCaches(lightAccess, chunkX * 16 + 7, 128, chunkZ * 16 + 7, true, true); -+ try { -+ final ChunkAccess chunk = this.getChunkInCache(chunkX, chunkZ); -+ if (chunk == null) { -+ return; -+ } -+ if (changedSections != null) { -+ final boolean[] ret = this.handleEmptySectionChanges(lightAccess, chunk, changedSections, false); -+ if (ret != null) { -+ this.setEmptinessMap(chunk, ret); -+ } -+ } -+ if (!positions.isEmpty()) { -+ this.propagateBlockChanges(lightAccess, chunk, positions); -+ } -+ this.updateVisible(lightAccess); -+ } finally { -+ this.destroyCaches(); -+ } -+ } -+ -+ // subclasses should not initialise caches, as this will always be done by the super call -+ // subclasses should not invoke updateVisible, as this will always be done by the super call -+ protected abstract void propagateBlockChanges(final LightChunkGetter lightAccess, final ChunkAccess atChunk, final Set positions); -+ -+ protected abstract void checkBlock(final LightChunkGetter lightAccess, final int worldX, final int worldY, final int worldZ); -+ -+ // if ret > expect, then the real value is at least ret (early returns if ret > expect, rather than calculating actual) -+ // if ret == expect, then expect is the correct light value for pos -+ // if ret < expect, then ret is the real light value -+ protected abstract int calculateLightValue(final LightChunkGetter lightAccess, final int worldX, final int worldY, final int worldZ, -+ final int expect); -+ -+ protected final int[] chunkCheckDelayedUpdatesCenter = new int[16 * 16]; -+ protected final int[] chunkCheckDelayedUpdatesNeighbour = new int[16 * 16]; -+ -+ protected void checkChunkEdge(final LightChunkGetter lightAccess, final ChunkAccess chunk, -+ final int chunkX, final int chunkY, final int chunkZ) { -+ final SWMRNibbleArray currNibble = this.getNibbleFromCache(chunkX, chunkY, chunkZ); -+ if (currNibble == null) { -+ return; -+ } -+ -+ for (final AxisDirection direction : ONLY_HORIZONTAL_DIRECTIONS) { -+ final int neighbourOffX = direction.x; -+ final int neighbourOffZ = direction.z; -+ -+ final SWMRNibbleArray neighbourNibble = this.getNibbleFromCache(chunkX + neighbourOffX, -+ chunkY, chunkZ + neighbourOffZ); -+ -+ if (neighbourNibble == null) { -+ continue; -+ } -+ -+ if (!currNibble.isInitialisedUpdating() && !neighbourNibble.isInitialisedUpdating()) { -+ // both are zero, nothing to check. -+ continue; -+ } -+ -+ // this chunk -+ final int incX; -+ final int incZ; -+ final int startX; -+ final int startZ; -+ -+ if (neighbourOffX != 0) { -+ // x direction -+ incX = 0; -+ incZ = 1; -+ -+ if (direction.x < 0) { -+ // negative -+ startX = chunkX << 4; -+ } else { -+ startX = chunkX << 4 | 15; -+ } -+ startZ = chunkZ << 4; -+ } else { -+ // z direction -+ incX = 1; -+ incZ = 0; -+ -+ if (neighbourOffZ < 0) { -+ // negative -+ startZ = chunkZ << 4; -+ } else { -+ startZ = chunkZ << 4 | 15; -+ } -+ startX = chunkX << 4; -+ } -+ -+ int centerDelayedChecks = 0; -+ int neighbourDelayedChecks = 0; -+ for (int currY = chunkY << 4, maxY = currY | 15; currY <= maxY; ++currY) { -+ for (int i = 0, currX = startX, currZ = startZ; i < 16; ++i, currX += incX, currZ += incZ) { -+ final int neighbourX = currX + neighbourOffX; -+ final int neighbourZ = currZ + neighbourOffZ; -+ -+ final int currentIndex = (currX & 15) | -+ ((currZ & 15)) << 4 | -+ ((currY & 15) << 8); -+ final int currentLevel = currNibble.getUpdating(currentIndex); -+ -+ final int neighbourIndex = -+ (neighbourX & 15) | -+ ((neighbourZ & 15)) << 4 | -+ ((currY & 15) << 8); -+ final int neighbourLevel = neighbourNibble.getUpdating(neighbourIndex); -+ -+ // the checks are delayed because the checkBlock method clobbers light values - which then -+ // affect later calculate light value operations. While they don't affect it in a behaviourly significant -+ // way, they do have a negative performance impact due to simply queueing more values -+ -+ if (this.calculateLightValue(lightAccess, currX, currY, currZ, currentLevel) != currentLevel) { -+ this.chunkCheckDelayedUpdatesCenter[centerDelayedChecks++] = currentIndex; -+ } -+ -+ if (this.calculateLightValue(lightAccess, neighbourX, currY, neighbourZ, neighbourLevel) != neighbourLevel) { -+ this.chunkCheckDelayedUpdatesNeighbour[neighbourDelayedChecks++] = neighbourIndex; -+ } -+ } -+ } -+ -+ final int currentChunkOffX = chunkX << 4; -+ final int currentChunkOffZ = chunkZ << 4; -+ final int neighbourChunkOffX = (chunkX + direction.x) << 4; -+ final int neighbourChunkOffZ = (chunkZ + direction.z) << 4; -+ final int chunkOffY = chunkY << 4; -+ for (int i = 0, len = Math.max(centerDelayedChecks, neighbourDelayedChecks); i < len; ++i) { -+ // try to queue neighbouring data together -+ // index = x | (z << 4) | (y << 8) -+ if (i < centerDelayedChecks) { -+ final int value = this.chunkCheckDelayedUpdatesCenter[i]; -+ this.checkBlock(lightAccess, currentChunkOffX | (value & 15), -+ chunkOffY | (value >>> 8), -+ currentChunkOffZ | ((value >>> 4) & 0xF)); -+ } -+ if (i < neighbourDelayedChecks) { -+ final int value = this.chunkCheckDelayedUpdatesNeighbour[i]; -+ this.checkBlock(lightAccess, neighbourChunkOffX | (value & 15), -+ chunkOffY | (value >>> 8), -+ neighbourChunkOffZ | ((value >>> 4) & 0xF)); -+ } -+ } -+ } -+ } -+ -+ protected void checkChunkEdges(final LightChunkGetter lightAccess, final ChunkAccess chunk, final ShortCollection sections) { -+ final ChunkPos chunkPos = chunk.getPos(); -+ final int chunkX = chunkPos.x; -+ final int chunkZ = chunkPos.z; -+ -+ for (final ShortIterator iterator = sections.iterator(); iterator.hasNext();) { -+ this.checkChunkEdge(lightAccess, chunk, chunkX, iterator.nextShort(), chunkZ); -+ } -+ -+ this.performLightDecrease(lightAccess); -+ } -+ -+ // subclasses should not initialise caches, as this will always be done by the super call -+ // subclasses should not invoke updateVisible, as this will always be done by the super call -+ // verifies that light levels on this chunks edges are consistent with this chunk's neighbours -+ // edges. if they are not, they are decreased (effectively performing the logic in checkBlock). -+ // This does not resolve skylight source problems. -+ protected void checkChunkEdges(final LightChunkGetter lightAccess, final ChunkAccess chunk, final int fromSection, final int toSection) { -+ final ChunkPos chunkPos = chunk.getPos(); -+ final int chunkX = chunkPos.x; -+ final int chunkZ = chunkPos.z; -+ -+ for (int currSectionY = toSection; currSectionY >= fromSection; --currSectionY) { -+ this.checkChunkEdge(lightAccess, chunk, chunkX, currSectionY, chunkZ); -+ } -+ -+ this.performLightDecrease(lightAccess); -+ } -+ -+ // pulls light from neighbours, and adds them into the increase queue. does not actually propagate. -+ protected final void propagateNeighbourLevels(final LightChunkGetter lightAccess, final ChunkAccess chunk, final int fromSection, final int toSection) { -+ final ChunkPos chunkPos = chunk.getPos(); -+ final int chunkX = chunkPos.x; -+ final int chunkZ = chunkPos.z; -+ -+ for (int currSectionY = toSection; currSectionY >= fromSection; --currSectionY) { -+ final SWMRNibbleArray currNibble = this.getNibbleFromCache(chunkX, currSectionY, chunkZ); -+ if (currNibble == null) { -+ continue; -+ } -+ for (final AxisDirection direction : ONLY_HORIZONTAL_DIRECTIONS) { -+ final int neighbourOffX = direction.x; -+ final int neighbourOffZ = direction.z; -+ -+ final SWMRNibbleArray neighbourNibble = this.getNibbleFromCache(chunkX + neighbourOffX, -+ currSectionY, chunkZ + neighbourOffZ); -+ -+ if (neighbourNibble == null || !neighbourNibble.isInitialisedUpdating()) { -+ // can't pull from 0 -+ continue; -+ } -+ -+ // neighbour chunk -+ final int incX; -+ final int incZ; -+ final int startX; -+ final int startZ; -+ -+ if (neighbourOffX != 0) { -+ // x direction -+ incX = 0; -+ incZ = 1; -+ -+ if (direction.x < 0) { -+ // negative -+ startX = (chunkX << 4) - 1; -+ } else { -+ startX = (chunkX << 4) + 16; -+ } -+ startZ = chunkZ << 4; -+ } else { -+ // z direction -+ incX = 1; -+ incZ = 0; -+ -+ if (neighbourOffZ < 0) { -+ // negative -+ startZ = (chunkZ << 4) - 1; -+ } else { -+ startZ = (chunkZ << 4) + 16; -+ } -+ startX = chunkX << 4; -+ } -+ -+ final long propagateDirection = 1L << direction.getOpposite().ordinal(); // we only want to check in this direction towards this chunk -+ final int encodeOffset = this.coordinateOffset; -+ -+ for (int currY = currSectionY << 4, maxY = currY | 15; currY <= maxY; ++currY) { -+ for (int i = 0, currX = startX, currZ = startZ; i < 16; ++i, currX += incX, currZ += incZ) { -+ final int level = neighbourNibble.getUpdating( -+ (currX & 15) -+ | ((currZ & 15) << 4) -+ | ((currY & 15) << 8) -+ ); -+ -+ if (level <= 1) { -+ // nothing to propagate -+ continue; -+ } -+ -+ this.appendToIncreaseQueue( -+ ((currX + (currZ << 6) + (currY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((level & 0xFL) << (6 + 6 + 16)) -+ | (propagateDirection << (6 + 6 + 16 + 4)) -+ | FLAG_HAS_SIDED_TRANSPARENT_BLOCKS // don't know if the current block is transparent, must check. -+ ); -+ } -+ } -+ } -+ } -+ } -+ -+ public static Boolean[] getEmptySectionsForChunk(final ChunkAccess chunk) { -+ final LevelChunkSection[] sections = chunk.getSections(); -+ final Boolean[] ret = new Boolean[sections.length]; -+ -+ for (int i = 0; i < sections.length; ++i) { -+ if (sections[i] == null || sections[i].hasOnlyAir()) { -+ ret[i] = Boolean.TRUE; -+ } else { -+ ret[i] = Boolean.FALSE; -+ } -+ } -+ -+ return ret; -+ } -+ -+ public final void forceHandleEmptySectionChanges(final LightChunkGetter lightAccess, final ChunkAccess chunk, final Boolean[] emptinessChanges) { -+ final int chunkX = chunk.getPos().x; -+ final int chunkZ = chunk.getPos().z; -+ this.setupCaches(lightAccess, chunkX * 16 + 7, 128, chunkZ * 16 + 7, true, true); -+ try { -+ // force current chunk into cache -+ this.setChunkInCache(chunkX, chunkZ, chunk); -+ this.setBlocksForChunkInCache(chunkX, chunkZ, chunk.getSections()); -+ this.setNibblesForChunkInCache(chunkX, chunkZ, this.getNibblesOnChunk(chunk)); -+ this.setEmptinessMapCache(chunkX, chunkZ, this.getEmptinessMap(chunk)); -+ -+ final boolean[] ret = this.handleEmptySectionChanges(lightAccess, chunk, emptinessChanges, false); -+ if (ret != null) { -+ this.setEmptinessMap(chunk, ret); -+ } -+ this.updateVisible(lightAccess); -+ } finally { -+ this.destroyCaches(); -+ } -+ } -+ -+ public final void handleEmptySectionChanges(final LightChunkGetter lightAccess, final int chunkX, final int chunkZ, -+ final Boolean[] emptinessChanges) { -+ this.setupCaches(lightAccess, chunkX * 16 + 7, 128, chunkZ * 16 + 7, true, true); -+ try { -+ final ChunkAccess chunk = this.getChunkInCache(chunkX, chunkZ); -+ if (chunk == null) { -+ return; -+ } -+ final boolean[] ret = this.handleEmptySectionChanges(lightAccess, chunk, emptinessChanges, false); -+ if (ret != null) { -+ this.setEmptinessMap(chunk, ret); -+ } -+ this.updateVisible(lightAccess); -+ } finally { -+ this.destroyCaches(); -+ } -+ } -+ -+ protected abstract void initNibble(final int chunkX, final int chunkY, final int chunkZ, final boolean extrude, final boolean initRemovedNibbles); -+ -+ protected abstract void setNibbleNull(final int chunkX, final int chunkY, final int chunkZ); -+ -+ // subclasses should not initialise caches, as this will always be done by the super call -+ // subclasses should not invoke updateVisible, as this will always be done by the super call -+ // subclasses are guaranteed that this is always called before a changed block set -+ // newChunk specifies whether the changes describe a "first load" of a chunk or changes to existing, already loaded chunks -+ // rets non-null when the emptiness map changed and needs to be updated -+ protected final boolean[] handleEmptySectionChanges(final LightChunkGetter lightAccess, final ChunkAccess chunk, -+ final Boolean[] emptinessChanges, final boolean unlit) { -+ final Level world = (Level)lightAccess.getLevel(); -+ final int chunkX = chunk.getPos().x; -+ final int chunkZ = chunk.getPos().z; -+ -+ boolean[] chunkEmptinessMap = this.getEmptinessMap(chunkX, chunkZ); -+ boolean[] ret = null; -+ final boolean needsInit = unlit || chunkEmptinessMap == null; -+ if (needsInit) { -+ this.setEmptinessMapCache(chunkX, chunkZ, ret = chunkEmptinessMap = new boolean[WorldUtil.getTotalSections(world)]); -+ } -+ -+ // update emptiness map -+ for (int sectionIndex = (emptinessChanges.length - 1); sectionIndex >= 0; --sectionIndex) { -+ Boolean valueBoxed = emptinessChanges[sectionIndex]; -+ if (valueBoxed == null) { -+ if (!needsInit) { -+ continue; -+ } -+ final LevelChunkSection section = this.getChunkSection(chunkX, sectionIndex + this.minSection, chunkZ); -+ emptinessChanges[sectionIndex] = valueBoxed = section == null || section.hasOnlyAir() ? Boolean.TRUE : Boolean.FALSE; -+ } -+ chunkEmptinessMap[sectionIndex] = valueBoxed.booleanValue(); -+ } -+ -+ // now init neighbour nibbles -+ for (int sectionIndex = (emptinessChanges.length - 1); sectionIndex >= 0; --sectionIndex) { -+ final Boolean valueBoxed = emptinessChanges[sectionIndex]; -+ final int sectionY = sectionIndex + this.minSection; -+ if (valueBoxed == null) { -+ continue; -+ } -+ -+ final boolean empty = valueBoxed.booleanValue(); -+ -+ if (empty) { -+ continue; -+ } -+ -+ for (int dz = -1; dz <= 1; ++dz) { -+ for (int dx = -1; dx <= 1; ++dx) { -+ // if we're not empty, we also need to initialise nibbles -+ // note: if we're unlit, we absolutely do not want to extrude, as light data isn't set up -+ final boolean extrude = (dx | dz) != 0 || !unlit; -+ for (int dy = 1; dy >= -1; --dy) { -+ this.initNibble(dx + chunkX, dy + sectionY, dz + chunkZ, extrude, false); -+ } -+ } -+ } -+ } -+ -+ // check for de-init and lazy-init -+ // lazy init is when chunks are being lit, so at the time they weren't loaded when their neighbours were running -+ // init checks. -+ for (int dz = -1; dz <= 1; ++dz) { -+ for (int dx = -1; dx <= 1; ++dx) { -+ // does this neighbour have 1 radius loaded? -+ boolean neighboursLoaded = true; -+ neighbour_loaded_search: -+ for (int dz2 = -1; dz2 <= 1; ++dz2) { -+ for (int dx2 = -1; dx2 <= 1; ++dx2) { -+ if (this.getEmptinessMap(dx + dx2 + chunkX, dz + dz2 + chunkZ) == null) { -+ neighboursLoaded = false; -+ break neighbour_loaded_search; -+ } -+ } -+ } -+ -+ for (int sectionY = this.maxLightSection; sectionY >= this.minLightSection; --sectionY) { -+ // check neighbours to see if we need to de-init this one -+ boolean allEmpty = true; -+ neighbour_search: -+ for (int dy2 = -1; dy2 <= 1; ++dy2) { -+ for (int dz2 = -1; dz2 <= 1; ++dz2) { -+ for (int dx2 = -1; dx2 <= 1; ++dx2) { -+ final int y = sectionY + dy2; -+ if (y < this.minSection || y > this.maxSection) { -+ // empty -+ continue; -+ } -+ final boolean[] emptinessMap = this.getEmptinessMap(dx + dx2 + chunkX, dz + dz2 + chunkZ); -+ if (emptinessMap != null) { -+ if (!emptinessMap[y - this.minSection]) { -+ allEmpty = false; -+ break neighbour_search; -+ } -+ } else { -+ final LevelChunkSection section = this.getChunkSection(dx + dx2 + chunkX, y, dz + dz2 + chunkZ); -+ if (section != null && !section.hasOnlyAir()) { -+ allEmpty = false; -+ break neighbour_search; -+ } -+ } -+ } -+ } -+ } -+ -+ if (allEmpty & neighboursLoaded) { -+ // can only de-init when neighbours are loaded -+ // de-init is fine to delay, as de-init is just an optimisation - it's not required for lighting -+ // to be correct -+ -+ // all were empty, so de-init -+ this.setNibbleNull(dx + chunkX, sectionY, dz + chunkZ); -+ } else if (!allEmpty) { -+ // must init -+ final boolean extrude = (dx | dz) != 0 || !unlit; -+ this.initNibble(dx + chunkX, sectionY, dz + chunkZ, extrude, false); -+ } -+ } -+ } -+ } -+ -+ return ret; -+ } -+ -+ public final void checkChunkEdges(final LightChunkGetter lightAccess, final int chunkX, final int chunkZ) { -+ this.setupCaches(lightAccess, chunkX * 16 + 7, 128, chunkZ * 16 + 7, true, false); -+ try { -+ final ChunkAccess chunk = this.getChunkInCache(chunkX, chunkZ); -+ if (chunk == null) { -+ return; -+ } -+ this.checkChunkEdges(lightAccess, chunk, this.minLightSection, this.maxLightSection); -+ this.updateVisible(lightAccess); -+ } finally { -+ this.destroyCaches(); -+ } -+ } -+ -+ public final void checkChunkEdges(final LightChunkGetter lightAccess, final int chunkX, final int chunkZ, final ShortCollection sections) { -+ this.setupCaches(lightAccess, chunkX * 16 + 7, 128, chunkZ * 16 + 7, true, false); -+ try { -+ final ChunkAccess chunk = this.getChunkInCache(chunkX, chunkZ); -+ if (chunk == null) { -+ return; -+ } -+ this.checkChunkEdges(lightAccess, chunk, sections); -+ this.updateVisible(lightAccess); -+ } finally { -+ this.destroyCaches(); -+ } -+ } -+ -+ // subclasses should not initialise caches, as this will always be done by the super call -+ // subclasses should not invoke updateVisible, as this will always be done by the super call -+ // needsEdgeChecks applies when possibly loading vanilla data, which means we need to validate the current -+ // chunks light values with respect to neighbours -+ // subclasses should note that the emptiness changes are propagated BEFORE this is called, so this function -+ // does not need to detect empty chunks itself (and it should do no handling for them either!) -+ protected abstract void lightChunk(final LightChunkGetter lightAccess, final ChunkAccess chunk, final boolean needsEdgeChecks); -+ -+ public final void light(final LightChunkGetter lightAccess, final ChunkAccess chunk, final Boolean[] emptySections) { -+ final int chunkX = chunk.getPos().x; -+ final int chunkZ = chunk.getPos().z; -+ this.setupCaches(lightAccess, chunkX * 16 + 7, 128, chunkZ * 16 + 7, true, true); -+ -+ try { -+ final SWMRNibbleArray[] nibbles = getFilledEmptyLight(this.maxLightSection - this.minLightSection + 1); -+ // force current chunk into cache -+ this.setChunkInCache(chunkX, chunkZ, chunk); -+ this.setBlocksForChunkInCache(chunkX, chunkZ, chunk.getSections()); -+ this.setNibblesForChunkInCache(chunkX, chunkZ, nibbles); -+ this.setEmptinessMapCache(chunkX, chunkZ, this.getEmptinessMap(chunk)); -+ -+ final boolean[] ret = this.handleEmptySectionChanges(lightAccess, chunk, emptySections, true); -+ if (ret != null) { -+ this.setEmptinessMap(chunk, ret); -+ } -+ this.lightChunk(lightAccess, chunk, true); -+ this.setNibbles(chunk, nibbles); -+ this.updateVisible(lightAccess); -+ } finally { -+ this.destroyCaches(); -+ } -+ } -+ -+ public final void relightChunks(final LightChunkGetter lightAccess, final Set chunks, -+ final Consumer chunkLightCallback, final IntConsumer onComplete) { -+ // it's recommended for maximum performance that the set is ordered according to a BFS from the center of -+ // the region of chunks to relight -+ // it's required that tickets are added for each chunk to keep them loaded -+ final Long2ObjectOpenHashMap nibblesByChunk = new Long2ObjectOpenHashMap<>(); -+ final Long2ObjectOpenHashMap emptinessMapByChunk = new Long2ObjectOpenHashMap<>(); -+ -+ final int[] neighbourLightOrder = new int[] { -+ // d = 0 -+ 0, 0, -+ // d = 1 -+ -1, 0, -+ 0, -1, -+ 1, 0, -+ 0, 1, -+ // d = 2 -+ -1, 1, -+ 1, 1, -+ -1, -1, -+ 1, -1, -+ }; -+ -+ int lightCalls = 0; -+ -+ for (final ChunkPos chunkPos : chunks) { -+ final int chunkX = chunkPos.x; -+ final int chunkZ = chunkPos.z; -+ final ChunkAccess chunk = (ChunkAccess)lightAccess.getChunkForLighting(chunkX, chunkZ); -+ if (chunk == null || !this.canUseChunk(chunk)) { -+ throw new IllegalStateException(); -+ } -+ -+ for (int i = 0, len = neighbourLightOrder.length; i < len; i += 2) { -+ final int dx = neighbourLightOrder[i]; -+ final int dz = neighbourLightOrder[i + 1]; -+ final int neighbourX = dx + chunkX; -+ final int neighbourZ = dz + chunkZ; -+ -+ final ChunkAccess neighbour = (ChunkAccess)lightAccess.getChunkForLighting(neighbourX, neighbourZ); -+ if (neighbour == null || !this.canUseChunk(neighbour)) { -+ continue; -+ } -+ -+ if (nibblesByChunk.get(CoordinateUtils.getChunkKey(neighbourX, neighbourZ)) != null) { -+ // lit already called for neighbour, no need to light it now -+ continue; -+ } -+ -+ // light neighbour chunk -+ this.setupEncodeOffset(neighbourX * 16 + 7, 128, neighbourZ * 16 + 7); -+ try { -+ // insert all neighbouring chunks for this neighbour that we have data for -+ for (int dz2 = -1; dz2 <= 1; ++dz2) { -+ for (int dx2 = -1; dx2 <= 1; ++dx2) { -+ final int neighbourX2 = neighbourX + dx2; -+ final int neighbourZ2 = neighbourZ + dz2; -+ final long key = CoordinateUtils.getChunkKey(neighbourX2, neighbourZ2); -+ final ChunkAccess neighbour2 = (ChunkAccess)lightAccess.getChunkForLighting(neighbourX2, neighbourZ2); -+ if (neighbour2 == null || !this.canUseChunk(neighbour2)) { -+ continue; -+ } -+ -+ final SWMRNibbleArray[] nibbles = nibblesByChunk.get(key); -+ if (nibbles == null) { -+ // we haven't lit this chunk -+ continue; -+ } -+ -+ this.setChunkInCache(neighbourX2, neighbourZ2, neighbour2); -+ this.setBlocksForChunkInCache(neighbourX2, neighbourZ2, neighbour2.getSections()); -+ this.setNibblesForChunkInCache(neighbourX2, neighbourZ2, nibbles); -+ this.setEmptinessMapCache(neighbourX2, neighbourZ2, emptinessMapByChunk.get(key)); -+ } -+ } -+ -+ final long key = CoordinateUtils.getChunkKey(neighbourX, neighbourZ); -+ -+ // now insert the neighbour chunk and light it -+ final SWMRNibbleArray[] nibbles = getFilledEmptyLight(this.world); -+ nibblesByChunk.put(key, nibbles); -+ -+ this.setChunkInCache(neighbourX, neighbourZ, neighbour); -+ this.setBlocksForChunkInCache(neighbourX, neighbourZ, neighbour.getSections()); -+ this.setNibblesForChunkInCache(neighbourX, neighbourZ, nibbles); -+ -+ final boolean[] neighbourEmptiness = this.handleEmptySectionChanges(lightAccess, neighbour, getEmptySectionsForChunk(neighbour), true); -+ emptinessMapByChunk.put(key, neighbourEmptiness); -+ if (chunks.contains(new ChunkPos(neighbourX, neighbourZ))) { -+ this.setEmptinessMap(neighbour, neighbourEmptiness); -+ } -+ -+ this.lightChunk(lightAccess, neighbour, false); -+ } finally { -+ this.destroyCaches(); -+ } -+ } -+ -+ // done lighting all neighbours, so the chunk is now fully lit -+ -+ // make sure nibbles are fully updated before calling back -+ final SWMRNibbleArray[] nibbles = nibblesByChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ for (final SWMRNibbleArray nibble : nibbles) { -+ nibble.updateVisible(); -+ } -+ -+ this.setNibbles(chunk, nibbles); -+ -+ for (int y = this.minLightSection; y <= this.maxLightSection; ++y) { -+ lightAccess.onLightUpdate(this.skylightPropagator ? LightLayer.SKY : LightLayer.BLOCK, SectionPos.of(chunkX, y, chunkX)); -+ } -+ -+ // now do callback -+ if (chunkLightCallback != null) { -+ chunkLightCallback.accept(chunkPos); -+ } -+ ++lightCalls; -+ } -+ -+ if (onComplete != null) { -+ onComplete.accept(lightCalls); -+ } -+ } -+ -+ // contains: -+ // lower (6 + 6 + 16) = 28 bits: encoded coordinate position (x | (z << 6) | (y << (6 + 6)))) -+ // next 4 bits: propagated light level (0, 15] -+ // next 6 bits: propagation direction bitset -+ // next 24 bits: unused -+ // last 3 bits: state flags -+ // state flags: -+ // whether the increase propagator needs to write the propagated level to the position, used to avoid cascading light -+ // updates for block sources -+ protected static final long FLAG_WRITE_LEVEL = Long.MIN_VALUE >>> 2; -+ // whether the propagation needs to check if its current level is equal to the expected level -+ // used only in increase propagation -+ protected static final long FLAG_RECHECK_LEVEL = Long.MIN_VALUE >>> 1; -+ // whether the propagation needs to consider if its block is conditionally transparent -+ protected static final long FLAG_HAS_SIDED_TRANSPARENT_BLOCKS = Long.MIN_VALUE; -+ -+ protected long[] increaseQueue = new long[16 * 16 * 16]; -+ protected int increaseQueueInitialLength; -+ protected long[] decreaseQueue = new long[16 * 16 * 16]; -+ protected int decreaseQueueInitialLength; -+ -+ protected final long[] resizeIncreaseQueue() { -+ return this.increaseQueue = Arrays.copyOf(this.increaseQueue, this.increaseQueue.length * 2); -+ } -+ -+ protected final long[] resizeDecreaseQueue() { -+ return this.decreaseQueue = Arrays.copyOf(this.decreaseQueue, this.decreaseQueue.length * 2); -+ } -+ -+ protected final void appendToIncreaseQueue(final long value) { -+ final int idx = this.increaseQueueInitialLength++; -+ long[] queue = this.increaseQueue; -+ if (idx >= queue.length) { -+ queue = this.resizeIncreaseQueue(); -+ queue[idx] = value; -+ } else { -+ queue[idx] = value; -+ } -+ } -+ -+ protected final void appendToDecreaseQueue(final long value) { -+ final int idx = this.decreaseQueueInitialLength++; -+ long[] queue = this.decreaseQueue; -+ if (idx >= queue.length) { -+ queue = this.resizeDecreaseQueue(); -+ queue[idx] = value; -+ } else { -+ queue[idx] = value; -+ } -+ } -+ -+ protected static final AxisDirection[][] OLD_CHECK_DIRECTIONS = new AxisDirection[1 << 6][]; -+ protected static final int ALL_DIRECTIONS_BITSET = (1 << 6) - 1; -+ static { -+ for (int i = 0; i < OLD_CHECK_DIRECTIONS.length; ++i) { -+ final List directions = new ArrayList<>(); -+ for (int bitset = i, len = Integer.bitCount(i), index = 0; index < len; ++index, bitset ^= IntegerUtil.getTrailingBit(bitset)) { -+ directions.add(AXIS_DIRECTIONS[IntegerUtil.trailingZeros(bitset)]); -+ } -+ OLD_CHECK_DIRECTIONS[i] = directions.toArray(new AxisDirection[0]); -+ } -+ } -+ -+ protected final void performLightIncrease(final LightChunkGetter lightAccess) { -+ final BlockGetter world = lightAccess.getLevel(); -+ long[] queue = this.increaseQueue; -+ int queueReadIndex = 0; -+ int queueLength = this.increaseQueueInitialLength; -+ this.increaseQueueInitialLength = 0; -+ final int decodeOffsetX = -this.encodeOffsetX; -+ final int decodeOffsetY = -this.encodeOffsetY; -+ final int decodeOffsetZ = -this.encodeOffsetZ; -+ final int encodeOffset = this.coordinateOffset; -+ final int sectionOffset = this.chunkSectionIndexOffset; -+ -+ while (queueReadIndex < queueLength) { -+ final long queueValue = queue[queueReadIndex++]; -+ -+ final int posX = ((int)queueValue & 63) + decodeOffsetX; -+ final int posZ = (((int)queueValue >>> 6) & 63) + decodeOffsetZ; -+ final int posY = (((int)queueValue >>> 12) & ((1 << 16) - 1)) + decodeOffsetY; -+ final int propagatedLightLevel = (int)((queueValue >>> (6 + 6 + 16)) & 0xFL); -+ final AxisDirection[] checkDirections = OLD_CHECK_DIRECTIONS[(int)((queueValue >>> (6 + 6 + 16 + 4)) & 63L)]; -+ -+ if ((queueValue & FLAG_RECHECK_LEVEL) != 0L) { -+ if (this.getLightLevel(posX, posY, posZ) != propagatedLightLevel) { -+ // not at the level we expect, so something changed. -+ continue; -+ } -+ } else if ((queueValue & FLAG_WRITE_LEVEL) != 0L) { -+ // these are used to restore block sources after a propagation decrease -+ this.setLightLevel(posX, posY, posZ, propagatedLightLevel); -+ } -+ -+ if ((queueValue & FLAG_HAS_SIDED_TRANSPARENT_BLOCKS) == 0L) { -+ // we don't need to worry about our state here. -+ for (final AxisDirection propagate : checkDirections) { -+ final int offX = posX + propagate.x; -+ final int offY = posY + propagate.y; -+ final int offZ = posZ + propagate.z; -+ -+ final int sectionIndex = (offX >> 4) + 5 * (offZ >> 4) + (5 * 5) * (offY >> 4) + sectionOffset; -+ final int localIndex = (offX & 15) | ((offZ & 15) << 4) | ((offY & 15) << 8); -+ -+ final SWMRNibbleArray currentNibble = this.nibbleCache[sectionIndex]; -+ final int currentLevel; -+ if (currentNibble == null || (currentLevel = currentNibble.getUpdating(localIndex)) >= (propagatedLightLevel - 1)) { -+ continue; // already at the level we want or unloaded -+ } -+ -+ final BlockState blockState = this.getBlockState(sectionIndex, localIndex); -+ if (blockState == null) { -+ continue; -+ } -+ final int opacityCached = blockState.getOpacityIfCached(); -+ if (opacityCached != -1) { -+ final int targetLevel = propagatedLightLevel - Math.max(1, opacityCached); -+ if (targetLevel > currentLevel) { -+ currentNibble.set(localIndex, targetLevel); -+ this.postLightUpdate(offX, offY, offZ); -+ -+ if (targetLevel > 1) { -+ if (queueLength >= queue.length) { -+ queue = this.resizeIncreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)); -+ continue; -+ } -+ } -+ continue; -+ } else { -+ this.mutablePos1.set(offX, offY, offZ); -+ long flags = 0; -+ if (blockState.isConditionallyFullOpaque()) { -+ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms); -+ -+ if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) { -+ continue; -+ } -+ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -+ } -+ -+ final int opacity = blockState.getLightBlock(world, this.mutablePos1); -+ final int targetLevel = propagatedLightLevel - Math.max(1, opacity); -+ if (targetLevel <= currentLevel) { -+ continue; -+ } -+ -+ currentNibble.set(localIndex, targetLevel); -+ this.postLightUpdate(offX, offY, offZ); -+ -+ if (targetLevel > 1) { -+ if (queueLength >= queue.length) { -+ queue = this.resizeIncreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)) -+ | (flags); -+ } -+ continue; -+ } -+ } -+ } else { -+ // we actually need to worry about our state here -+ final BlockState fromBlock = this.getBlockState(posX, posY, posZ); -+ this.mutablePos2.set(posX, posY, posZ); -+ for (final AxisDirection propagate : checkDirections) { -+ final int offX = posX + propagate.x; -+ final int offY = posY + propagate.y; -+ final int offZ = posZ + propagate.z; -+ -+ final VoxelShape fromShape = fromBlock.isConditionallyFullOpaque() ? fromBlock.getFaceOcclusionShape(world, this.mutablePos2, propagate.nms) : Shapes.empty(); -+ -+ if (fromShape != Shapes.empty() && Shapes.faceShapeOccludes(Shapes.empty(), fromShape)) { -+ continue; -+ } -+ -+ final int sectionIndex = (offX >> 4) + 5 * (offZ >> 4) + (5 * 5) * (offY >> 4) + sectionOffset; -+ final int localIndex = (offX & 15) | ((offZ & 15) << 4) | ((offY & 15) << 8); -+ -+ final SWMRNibbleArray currentNibble = this.nibbleCache[sectionIndex]; -+ final int currentLevel; -+ -+ if (currentNibble == null || (currentLevel = currentNibble.getUpdating(localIndex)) >= (propagatedLightLevel - 1)) { -+ continue; // already at the level we want -+ } -+ -+ final BlockState blockState = this.getBlockState(sectionIndex, localIndex); -+ if (blockState == null) { -+ continue; -+ } -+ final int opacityCached = blockState.getOpacityIfCached(); -+ if (opacityCached != -1) { -+ final int targetLevel = propagatedLightLevel - Math.max(1, opacityCached); -+ if (targetLevel > currentLevel) { -+ currentNibble.set(localIndex, targetLevel); -+ this.postLightUpdate(offX, offY, offZ); -+ -+ if (targetLevel > 1) { -+ if (queueLength >= queue.length) { -+ queue = this.resizeIncreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)); -+ continue; -+ } -+ } -+ continue; -+ } else { -+ this.mutablePos1.set(offX, offY, offZ); -+ long flags = 0; -+ if (blockState.isConditionallyFullOpaque()) { -+ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms); -+ -+ if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { -+ continue; -+ } -+ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -+ } -+ -+ final int opacity = blockState.getLightBlock(world, this.mutablePos1); -+ final int targetLevel = propagatedLightLevel - Math.max(1, opacity); -+ if (targetLevel <= currentLevel) { -+ continue; -+ } -+ -+ currentNibble.set(localIndex, targetLevel); -+ this.postLightUpdate(offX, offY, offZ); -+ -+ if (targetLevel > 1) { -+ if (queueLength >= queue.length) { -+ queue = this.resizeIncreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | (propagate.everythingButTheOppositeDirection << (6 + 6 + 16 + 4)) -+ | (flags); -+ } -+ continue; -+ } -+ } -+ } -+ } -+ } -+ -+ protected final void performLightDecrease(final LightChunkGetter lightAccess) { -+ final BlockGetter world = lightAccess.getLevel(); -+ long[] queue = this.decreaseQueue; -+ long[] increaseQueue = this.increaseQueue; -+ int queueReadIndex = 0; -+ int queueLength = this.decreaseQueueInitialLength; -+ this.decreaseQueueInitialLength = 0; -+ int increaseQueueLength = this.increaseQueueInitialLength; -+ final int decodeOffsetX = -this.encodeOffsetX; -+ final int decodeOffsetY = -this.encodeOffsetY; -+ final int decodeOffsetZ = -this.encodeOffsetZ; -+ final int encodeOffset = this.coordinateOffset; -+ final int sectionOffset = this.chunkSectionIndexOffset; -+ final int emittedMask = this.emittedLightMask; -+ -+ while (queueReadIndex < queueLength) { -+ final long queueValue = queue[queueReadIndex++]; -+ -+ final int posX = ((int)queueValue & 63) + decodeOffsetX; -+ final int posZ = (((int)queueValue >>> 6) & 63) + decodeOffsetZ; -+ final int posY = (((int)queueValue >>> 12) & ((1 << 16) - 1)) + decodeOffsetY; -+ final int propagatedLightLevel = (int)((queueValue >>> (6 + 6 + 16)) & 0xF); -+ final AxisDirection[] checkDirections = OLD_CHECK_DIRECTIONS[(int)((queueValue >>> (6 + 6 + 16 + 4)) & 63)]; -+ -+ if ((queueValue & FLAG_HAS_SIDED_TRANSPARENT_BLOCKS) == 0L) { -+ // we don't need to worry about our state here. -+ for (final AxisDirection propagate : checkDirections) { -+ final int offX = posX + propagate.x; -+ final int offY = posY + propagate.y; -+ final int offZ = posZ + propagate.z; -+ -+ final int sectionIndex = (offX >> 4) + 5 * (offZ >> 4) + (5 * 5) * (offY >> 4) + sectionOffset; -+ final int localIndex = (offX & 15) | ((offZ & 15) << 4) | ((offY & 15) << 8); -+ -+ final SWMRNibbleArray currentNibble = this.nibbleCache[sectionIndex]; -+ final int lightLevel; -+ -+ if (currentNibble == null || (lightLevel = currentNibble.getUpdating(localIndex)) == 0) { -+ // already at lowest (or unloaded), nothing we can do -+ continue; -+ } -+ -+ final BlockState blockState = this.getBlockState(sectionIndex, localIndex); -+ if (blockState == null) { -+ continue; -+ } -+ final int opacityCached = blockState.getOpacityIfCached(); -+ if (opacityCached != -1) { -+ final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacityCached)); -+ if (lightLevel > targetLevel) { -+ // it looks like another source propagated here, so re-propagate it -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((lightLevel & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | FLAG_RECHECK_LEVEL; -+ continue; -+ } -+ final int emittedLight = blockState.getLightEmission() & emittedMask; -+ if (emittedLight != 0) { -+ // re-propagate source -+ // note: do not set recheck level, or else the propagation will fail -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((emittedLight & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (blockState.isConditionallyFullOpaque() ? (FLAG_WRITE_LEVEL | FLAG_HAS_SIDED_TRANSPARENT_BLOCKS) : FLAG_WRITE_LEVEL); -+ } -+ -+ currentNibble.set(localIndex, 0); -+ this.postLightUpdate(offX, offY, offZ); -+ -+ if (targetLevel > 0) { // we actually need to propagate 0 just in case we find a neighbour... -+ if (queueLength >= queue.length) { -+ queue = this.resizeDecreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)); -+ continue; -+ } -+ continue; -+ } else { -+ this.mutablePos1.set(offX, offY, offZ); -+ long flags = 0; -+ if (blockState.isConditionallyFullOpaque()) { -+ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms); -+ -+ if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) { -+ continue; -+ } -+ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -+ } -+ -+ final int opacity = blockState.getLightBlock(world, this.mutablePos1); -+ final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacity)); -+ if (lightLevel > targetLevel) { -+ // it looks like another source propagated here, so re-propagate it -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((lightLevel & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (FLAG_RECHECK_LEVEL | flags); -+ continue; -+ } -+ final int emittedLight = blockState.getLightEmission() & emittedMask; -+ if (emittedLight != 0) { -+ // re-propagate source -+ // note: do not set recheck level, or else the propagation will fail -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((emittedLight & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (flags | FLAG_WRITE_LEVEL); -+ } -+ -+ currentNibble.set(localIndex, 0); -+ this.postLightUpdate(offX, offY, offZ); -+ -+ if (targetLevel > 0) { -+ if (queueLength >= queue.length) { -+ queue = this.resizeDecreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)) -+ | flags; -+ } -+ continue; -+ } -+ } -+ } else { -+ // we actually need to worry about our state here -+ final BlockState fromBlock = this.getBlockState(posX, posY, posZ); -+ this.mutablePos2.set(posX, posY, posZ); -+ for (final AxisDirection propagate : checkDirections) { -+ final int offX = posX + propagate.x; -+ final int offY = posY + propagate.y; -+ final int offZ = posZ + propagate.z; -+ -+ final int sectionIndex = (offX >> 4) + 5 * (offZ >> 4) + (5 * 5) * (offY >> 4) + sectionOffset; -+ final int localIndex = (offX & 15) | ((offZ & 15) << 4) | ((offY & 15) << 8); -+ -+ final VoxelShape fromShape = (fromBlock.isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(world, this.mutablePos2, propagate.nms) : Shapes.empty(); -+ -+ if (fromShape != Shapes.empty() && Shapes.faceShapeOccludes(Shapes.empty(), fromShape)) { -+ continue; -+ } -+ -+ final SWMRNibbleArray currentNibble = this.nibbleCache[sectionIndex]; -+ final int lightLevel; -+ -+ if (currentNibble == null || (lightLevel = currentNibble.getUpdating(localIndex)) == 0) { -+ // already at lowest (or unloaded), nothing we can do -+ continue; -+ } -+ -+ final BlockState blockState = this.getBlockState(sectionIndex, localIndex); -+ if (blockState == null) { -+ continue; -+ } -+ final int opacityCached = blockState.getOpacityIfCached(); -+ if (opacityCached != -1) { -+ final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacityCached)); -+ if (lightLevel > targetLevel) { -+ // it looks like another source propagated here, so re-propagate it -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((lightLevel & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | FLAG_RECHECK_LEVEL; -+ continue; -+ } -+ final int emittedLight = blockState.getLightEmission() & emittedMask; -+ if (emittedLight != 0) { -+ // re-propagate source -+ // note: do not set recheck level, or else the propagation will fail -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((emittedLight & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (blockState.isConditionallyFullOpaque() ? (FLAG_WRITE_LEVEL | FLAG_HAS_SIDED_TRANSPARENT_BLOCKS) : FLAG_WRITE_LEVEL); -+ } -+ -+ currentNibble.set(localIndex, 0); -+ this.postLightUpdate(offX, offY, offZ); -+ -+ if (targetLevel > 0) { // we actually need to propagate 0 just in case we find a neighbour... -+ if (queueLength >= queue.length) { -+ queue = this.resizeDecreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)); -+ continue; -+ } -+ continue; -+ } else { -+ this.mutablePos1.set(offX, offY, offZ); -+ long flags = 0; -+ if (blockState.isConditionallyFullOpaque()) { -+ final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms); -+ -+ if (Shapes.faceShapeOccludes(fromShape, cullingFace)) { -+ continue; -+ } -+ flags |= FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; -+ } -+ -+ final int opacity = blockState.getLightBlock(world, this.mutablePos1); -+ final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacity)); -+ if (lightLevel > targetLevel) { -+ // it looks like another source propagated here, so re-propagate it -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((lightLevel & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (FLAG_RECHECK_LEVEL | flags); -+ continue; -+ } -+ final int emittedLight = blockState.getLightEmission() & emittedMask; -+ if (emittedLight != 0) { -+ // re-propagate source -+ // note: do not set recheck level, or else the propagation will fail -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((emittedLight & 0xFL) << (6 + 6 + 16)) -+ | (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4)) -+ | (flags | FLAG_WRITE_LEVEL); -+ } -+ -+ currentNibble.set(localIndex, 0); -+ this.postLightUpdate(offX, offY, offZ); -+ -+ if (targetLevel > 0) { // we actually need to propagate 0 just in case we find a neighbour... -+ if (queueLength >= queue.length) { -+ queue = this.resizeDecreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1)) -+ | ((targetLevel & 0xFL) << (6 + 6 + 16)) -+ | ((propagate.everythingButTheOppositeDirection) << (6 + 6 + 16 + 4)) -+ | flags; -+ } -+ continue; -+ } -+ } -+ } -+ } -+ -+ // propagate sources we clobbered -+ this.increaseQueueInitialLength = increaseQueueLength; -+ this.performLightIncrease(lightAccess); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/starlight/common/light/StarLightInterface.java b/src/main/java/ca/spottedleaf/starlight/common/light/StarLightInterface.java -new file mode 100644 -index 0000000000000000000000000000000000000000..e0338db4d6fa359029ed5edeacc3646aa98701f5 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/starlight/common/light/StarLightInterface.java -@@ -0,0 +1,674 @@ -+package ca.spottedleaf.starlight.common.light; -+ -+import ca.spottedleaf.starlight.common.util.CoordinateUtils; -+import ca.spottedleaf.starlight.common.util.WorldUtil; -+import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; -+import it.unimi.dsi.fastutil.shorts.ShortCollection; -+import it.unimi.dsi.fastutil.shorts.ShortOpenHashSet; -+import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; -+import net.minecraft.core.BlockPos; -+import net.minecraft.core.SectionPos; -+import net.minecraft.server.level.ServerChunkCache; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.TicketType; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.status.ChunkStatus; -+import net.minecraft.world.level.chunk.DataLayer; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.LightChunkGetter; -+import net.minecraft.world.level.lighting.LayerLightEventListener; -+import net.minecraft.world.level.lighting.LevelLightEngine; -+import java.util.ArrayDeque; -+import java.util.ArrayList; -+import java.util.List; -+import java.util.Set; -+import java.util.concurrent.CompletableFuture; -+import java.util.function.Consumer; -+import java.util.function.IntConsumer; -+ -+public final class StarLightInterface { -+ -+ public static final TicketType CHUNK_WORK_TICKET = TicketType.create("starlight_chunk_work_ticket", (p1, p2) -> Long.compare(p1.toLong(), p2.toLong())); -+ -+ /** -+ * Can be {@code null}, indicating the light is all empty. -+ */ -+ protected final Level world; -+ protected final LightChunkGetter lightAccess; -+ -+ protected final ArrayDeque cachedSkyPropagators; -+ protected final ArrayDeque cachedBlockPropagators; -+ -+ protected final LightQueue lightQueue = new LightQueue(this); -+ -+ protected final LayerLightEventListener skyReader; -+ protected final LayerLightEventListener blockReader; -+ protected final boolean isClientSide; -+ -+ protected final int minSection; -+ protected final int maxSection; -+ protected final int minLightSection; -+ protected final int maxLightSection; -+ -+ public final LevelLightEngine lightEngine; -+ -+ private final boolean hasBlockLight; -+ private final boolean hasSkyLight; -+ -+ public StarLightInterface(final LightChunkGetter lightAccess, final boolean hasSkyLight, final boolean hasBlockLight, final LevelLightEngine lightEngine) { -+ this.lightAccess = lightAccess; -+ this.world = lightAccess == null ? null : (Level)lightAccess.getLevel(); -+ this.cachedSkyPropagators = hasSkyLight && lightAccess != null ? new ArrayDeque<>() : null; -+ this.cachedBlockPropagators = hasBlockLight && lightAccess != null ? new ArrayDeque<>() : null; -+ this.isClientSide = !(this.world instanceof ServerLevel); -+ if (this.world == null) { -+ this.minSection = -4; -+ this.maxSection = 19; -+ this.minLightSection = -5; -+ this.maxLightSection = 20; -+ } else { -+ this.minSection = WorldUtil.getMinSection(this.world); -+ this.maxSection = WorldUtil.getMaxSection(this.world); -+ this.minLightSection = WorldUtil.getMinLightSection(this.world); -+ this.maxLightSection = WorldUtil.getMaxLightSection(this.world); -+ } -+ this.lightEngine = lightEngine; -+ this.hasBlockLight = hasBlockLight; -+ this.hasSkyLight = hasSkyLight; -+ this.skyReader = !hasSkyLight ? LayerLightEventListener.DummyLightLayerEventListener.INSTANCE : new LayerLightEventListener() { -+ @Override -+ public void checkBlock(final BlockPos blockPos) { -+ StarLightInterface.this.lightEngine.checkBlock(blockPos.immutable()); -+ } -+ -+ @Override -+ public void propagateLightSources(final ChunkPos chunkPos) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public boolean hasLightWork() { -+ // not really correct... -+ return StarLightInterface.this.hasUpdates(); -+ } -+ -+ @Override -+ public int runLightUpdates() { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public void setLightEnabled(final ChunkPos chunkPos, final boolean bl) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public DataLayer getDataLayerData(final SectionPos pos) { -+ final ChunkAccess chunk = StarLightInterface.this.getAnyChunkNow(pos.getX(), pos.getZ()); -+ if (chunk == null || (!StarLightInterface.this.isClientSide && !chunk.isLightCorrect()) || !chunk.getStatus().isOrAfter(ChunkStatus.LIGHT)) { -+ return null; -+ } -+ -+ final int sectionY = pos.getY(); -+ -+ if (sectionY > StarLightInterface.this.maxLightSection || sectionY < StarLightInterface.this.minLightSection) { -+ return null; -+ } -+ -+ if (chunk.getSkyEmptinessMap() == null) { -+ return null; -+ } -+ -+ return chunk.getSkyNibbles()[sectionY - StarLightInterface.this.minLightSection].toVanillaNibble(); -+ } -+ -+ @Override -+ public int getLightValue(final BlockPos blockPos) { -+ return StarLightInterface.this.getSkyLightValue(blockPos, StarLightInterface.this.getAnyChunkNow(blockPos.getX() >> 4, blockPos.getZ() >> 4)); -+ } -+ -+ @Override -+ public void updateSectionStatus(final SectionPos pos, final boolean notReady) { -+ StarLightInterface.this.sectionChange(pos, notReady); -+ } -+ }; -+ this.blockReader = !hasBlockLight ? LayerLightEventListener.DummyLightLayerEventListener.INSTANCE : new LayerLightEventListener() { -+ @Override -+ public void checkBlock(final BlockPos blockPos) { -+ StarLightInterface.this.lightEngine.checkBlock(blockPos.immutable()); -+ } -+ -+ @Override -+ public void propagateLightSources(final ChunkPos chunkPos) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public boolean hasLightWork() { -+ // not really correct... -+ return StarLightInterface.this.hasUpdates(); -+ } -+ -+ @Override -+ public int runLightUpdates() { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public void setLightEnabled(final ChunkPos chunkPos, final boolean bl) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public DataLayer getDataLayerData(final SectionPos pos) { -+ final ChunkAccess chunk = StarLightInterface.this.getAnyChunkNow(pos.getX(), pos.getZ()); -+ -+ if (chunk == null || pos.getY() < StarLightInterface.this.minLightSection || pos.getY() > StarLightInterface.this.maxLightSection) { -+ return null; -+ } -+ -+ return chunk.getBlockNibbles()[pos.getY() - StarLightInterface.this.minLightSection].toVanillaNibble(); -+ } -+ -+ @Override -+ public int getLightValue(final BlockPos blockPos) { -+ return StarLightInterface.this.getBlockLightValue(blockPos, StarLightInterface.this.getAnyChunkNow(blockPos.getX() >> 4, blockPos.getZ() >> 4)); -+ } -+ -+ @Override -+ public void updateSectionStatus(final SectionPos pos, final boolean notReady) { -+ StarLightInterface.this.sectionChange(pos, notReady); -+ } -+ }; -+ } -+ -+ public boolean hasSkyLight() { -+ return this.hasSkyLight; -+ } -+ -+ public boolean hasBlockLight() { -+ return this.hasBlockLight; -+ } -+ -+ public int getSkyLightValue(final BlockPos blockPos, final ChunkAccess chunk) { -+ if (!this.hasSkyLight) { -+ return 0; -+ } -+ final int x = blockPos.getX(); -+ int y = blockPos.getY(); -+ final int z = blockPos.getZ(); -+ -+ final int minSection = this.minSection; -+ final int maxSection = this.maxSection; -+ final int minLightSection = this.minLightSection; -+ final int maxLightSection = this.maxLightSection; -+ -+ if (chunk == null || (!this.isClientSide && !chunk.isLightCorrect()) || !chunk.getStatus().isOrAfter(ChunkStatus.LIGHT)) { -+ return 15; -+ } -+ -+ int sectionY = y >> 4; -+ -+ if (sectionY > maxLightSection) { -+ return 15; -+ } -+ -+ if (sectionY < minLightSection) { -+ sectionY = minLightSection; -+ y = sectionY << 4; -+ } -+ -+ final SWMRNibbleArray[] nibbles = chunk.getSkyNibbles(); -+ final SWMRNibbleArray immediate = nibbles[sectionY - minLightSection]; -+ -+ if (!immediate.isNullNibbleVisible()) { -+ return immediate.getVisible(x, y, z); -+ } -+ -+ final boolean[] emptinessMap = chunk.getSkyEmptinessMap(); -+ -+ if (emptinessMap == null) { -+ return 15; -+ } -+ -+ // are we above this chunk's lowest empty section? -+ int lowestY = minLightSection - 1; -+ for (int currY = maxSection; currY >= minSection; --currY) { -+ if (emptinessMap[currY - minSection]) { -+ continue; -+ } -+ -+ // should always be full lit here -+ lowestY = currY; -+ break; -+ } -+ -+ if (sectionY > lowestY) { -+ return 15; -+ } -+ -+ // this nibble is going to depend solely on the skylight data above it -+ // find first non-null data above (there does exist one, as we just found it above) -+ for (int currY = sectionY + 1; currY <= maxLightSection; ++currY) { -+ final SWMRNibbleArray nibble = nibbles[currY - minLightSection]; -+ if (!nibble.isNullNibbleVisible()) { -+ return nibble.getVisible(x, 0, z); -+ } -+ } -+ -+ // should never reach here -+ return 15; -+ } -+ -+ public int getBlockLightValue(final BlockPos blockPos, final ChunkAccess chunk) { -+ if (!this.hasBlockLight) { -+ return 0; -+ } -+ final int y = blockPos.getY(); -+ final int cy = y >> 4; -+ -+ final int minLightSection = this.minLightSection; -+ final int maxLightSection = this.maxLightSection; -+ -+ if (cy < minLightSection || cy > maxLightSection) { -+ return 0; -+ } -+ -+ if (chunk == null) { -+ return 0; -+ } -+ -+ final SWMRNibbleArray nibble = chunk.getBlockNibbles()[cy - minLightSection]; -+ return nibble.getVisible(blockPos.getX(), y, blockPos.getZ()); -+ } -+ -+ public int getRawBrightness(final BlockPos pos, final int ambientDarkness) { -+ final ChunkAccess chunk = this.getAnyChunkNow(pos.getX() >> 4, pos.getZ() >> 4); -+ -+ final int sky = this.getSkyLightValue(pos, chunk) - ambientDarkness; -+ // Don't fetch the block light level if the skylight level is 15, since the value will never be higher. -+ if (sky == 15) return 15; -+ final int block = this.getBlockLightValue(pos, chunk); -+ return Math.max(sky, block); -+ } -+ -+ public LayerLightEventListener getSkyReader() { -+ return this.skyReader; -+ } -+ -+ public LayerLightEventListener getBlockReader() { -+ return this.blockReader; -+ } -+ -+ public boolean isClientSide() { -+ return this.isClientSide; -+ } -+ -+ public ChunkAccess getAnyChunkNow(final int chunkX, final int chunkZ) { -+ if (this.world == null) { -+ // empty world -+ return null; -+ } -+ -+ final ServerChunkCache chunkProvider = ((ServerLevel)this.world).getChunkSource(); -+ final LevelChunk fullLoaded = chunkProvider.getChunkAtIfLoadedImmediately(chunkX, chunkZ); -+ if (fullLoaded != null) { -+ return fullLoaded; -+ } -+ -+ return chunkProvider.getChunkAtImmediately(chunkX, chunkZ); -+ } -+ -+ public boolean hasUpdates() { -+ return !this.lightQueue.isEmpty(); -+ } -+ -+ public Level getWorld() { -+ return this.world; -+ } -+ -+ public LightChunkGetter getLightAccess() { -+ return this.lightAccess; -+ } -+ -+ protected final SkyStarLightEngine getSkyLightEngine() { -+ if (this.cachedSkyPropagators == null) { -+ return null; -+ } -+ final SkyStarLightEngine ret; -+ synchronized (this.cachedSkyPropagators) { -+ ret = this.cachedSkyPropagators.pollFirst(); -+ } -+ -+ if (ret == null) { -+ return new SkyStarLightEngine(this.world); -+ } -+ return ret; -+ } -+ -+ protected final void releaseSkyLightEngine(final SkyStarLightEngine engine) { -+ if (this.cachedSkyPropagators == null) { -+ return; -+ } -+ synchronized (this.cachedSkyPropagators) { -+ this.cachedSkyPropagators.addFirst(engine); -+ } -+ } -+ -+ protected final BlockStarLightEngine getBlockLightEngine() { -+ if (this.cachedBlockPropagators == null) { -+ return null; -+ } -+ final BlockStarLightEngine ret; -+ synchronized (this.cachedBlockPropagators) { -+ ret = this.cachedBlockPropagators.pollFirst(); -+ } -+ -+ if (ret == null) { -+ return new BlockStarLightEngine(this.world); -+ } -+ return ret; -+ } -+ -+ protected final void releaseBlockLightEngine(final BlockStarLightEngine engine) { -+ if (this.cachedBlockPropagators == null) { -+ return; -+ } -+ synchronized (this.cachedBlockPropagators) { -+ this.cachedBlockPropagators.addFirst(engine); -+ } -+ } -+ -+ public LightQueue.ChunkTasks blockChange(final BlockPos pos) { -+ if (this.world == null || pos.getY() < WorldUtil.getMinBlockY(this.world) || pos.getY() > WorldUtil.getMaxBlockY(this.world)) { // empty world -+ return null; -+ } -+ -+ return this.lightQueue.queueBlockChange(pos); -+ } -+ -+ public LightQueue.ChunkTasks sectionChange(final SectionPos pos, final boolean newEmptyValue) { -+ if (this.world == null) { // empty world -+ return null; -+ } -+ -+ return this.lightQueue.queueSectionChange(pos, newEmptyValue); -+ } -+ -+ public void forceLoadInChunk(final ChunkAccess chunk, final Boolean[] emptySections) { -+ final SkyStarLightEngine skyEngine = this.getSkyLightEngine(); -+ final BlockStarLightEngine blockEngine = this.getBlockLightEngine(); -+ -+ try { -+ if (skyEngine != null) { -+ skyEngine.forceHandleEmptySectionChanges(this.lightAccess, chunk, emptySections); -+ } -+ if (blockEngine != null) { -+ blockEngine.forceHandleEmptySectionChanges(this.lightAccess, chunk, emptySections); -+ } -+ } finally { -+ this.releaseSkyLightEngine(skyEngine); -+ this.releaseBlockLightEngine(blockEngine); -+ } -+ } -+ -+ public void loadInChunk(final int chunkX, final int chunkZ, final Boolean[] emptySections) { -+ final SkyStarLightEngine skyEngine = this.getSkyLightEngine(); -+ final BlockStarLightEngine blockEngine = this.getBlockLightEngine(); -+ -+ try { -+ if (skyEngine != null) { -+ skyEngine.handleEmptySectionChanges(this.lightAccess, chunkX, chunkZ, emptySections); -+ } -+ if (blockEngine != null) { -+ blockEngine.handleEmptySectionChanges(this.lightAccess, chunkX, chunkZ, emptySections); -+ } -+ } finally { -+ this.releaseSkyLightEngine(skyEngine); -+ this.releaseBlockLightEngine(blockEngine); -+ } -+ } -+ -+ public void lightChunk(final ChunkAccess chunk, final Boolean[] emptySections) { -+ final SkyStarLightEngine skyEngine = this.getSkyLightEngine(); -+ final BlockStarLightEngine blockEngine = this.getBlockLightEngine(); -+ -+ try { -+ if (skyEngine != null) { -+ skyEngine.light(this.lightAccess, chunk, emptySections); -+ } -+ if (blockEngine != null) { -+ blockEngine.light(this.lightAccess, chunk, emptySections); -+ } -+ } finally { -+ this.releaseSkyLightEngine(skyEngine); -+ this.releaseBlockLightEngine(blockEngine); -+ } -+ } -+ -+ public void relightChunks(final Set chunks, final Consumer chunkLightCallback, -+ final IntConsumer onComplete) { -+ final SkyStarLightEngine skyEngine = this.getSkyLightEngine(); -+ final BlockStarLightEngine blockEngine = this.getBlockLightEngine(); -+ -+ try { -+ if (skyEngine != null) { -+ skyEngine.relightChunks(this.lightAccess, chunks, blockEngine == null ? chunkLightCallback : null, -+ blockEngine == null ? onComplete : null); -+ } -+ if (blockEngine != null) { -+ blockEngine.relightChunks(this.lightAccess, chunks, chunkLightCallback, onComplete); -+ } -+ } finally { -+ this.releaseSkyLightEngine(skyEngine); -+ this.releaseBlockLightEngine(blockEngine); -+ } -+ } -+ -+ public void checkChunkEdges(final int chunkX, final int chunkZ) { -+ this.checkSkyEdges(chunkX, chunkZ); -+ this.checkBlockEdges(chunkX, chunkZ); -+ } -+ -+ public void checkSkyEdges(final int chunkX, final int chunkZ) { -+ final SkyStarLightEngine skyEngine = this.getSkyLightEngine(); -+ -+ try { -+ if (skyEngine != null) { -+ skyEngine.checkChunkEdges(this.lightAccess, chunkX, chunkZ); -+ } -+ } finally { -+ this.releaseSkyLightEngine(skyEngine); -+ } -+ } -+ -+ public void checkBlockEdges(final int chunkX, final int chunkZ) { -+ final BlockStarLightEngine blockEngine = this.getBlockLightEngine(); -+ try { -+ if (blockEngine != null) { -+ blockEngine.checkChunkEdges(this.lightAccess, chunkX, chunkZ); -+ } -+ } finally { -+ this.releaseBlockLightEngine(blockEngine); -+ } -+ } -+ -+ public void checkSkyEdges(final int chunkX, final int chunkZ, final ShortCollection sections) { -+ final SkyStarLightEngine skyEngine = this.getSkyLightEngine(); -+ -+ try { -+ if (skyEngine != null) { -+ skyEngine.checkChunkEdges(this.lightAccess, chunkX, chunkZ, sections); -+ } -+ } finally { -+ this.releaseSkyLightEngine(skyEngine); -+ } -+ } -+ -+ public void checkBlockEdges(final int chunkX, final int chunkZ, final ShortCollection sections) { -+ final BlockStarLightEngine blockEngine = this.getBlockLightEngine(); -+ try { -+ if (blockEngine != null) { -+ blockEngine.checkChunkEdges(this.lightAccess, chunkX, chunkZ, sections); -+ } -+ } finally { -+ this.releaseBlockLightEngine(blockEngine); -+ } -+ } -+ -+ public void scheduleChunkLight(final ChunkPos pos, final Runnable run) { -+ this.lightQueue.queueChunkLighting(pos, run); -+ } -+ -+ public void removeChunkTasks(final ChunkPos pos) { -+ this.lightQueue.removeChunk(pos); -+ } -+ -+ public void propagateChanges() { -+ if (this.lightQueue.isEmpty()) { -+ return; -+ } -+ -+ final SkyStarLightEngine skyEngine = this.getSkyLightEngine(); -+ final BlockStarLightEngine blockEngine = this.getBlockLightEngine(); -+ -+ try { -+ LightQueue.ChunkTasks task; -+ while ((task = this.lightQueue.removeFirstTask()) != null) { -+ if (task.lightTasks != null) { -+ for (final Runnable run : task.lightTasks) { -+ run.run(); -+ } -+ } -+ -+ final long coordinate = task.chunkCoordinate; -+ final int chunkX = CoordinateUtils.getChunkX(coordinate); -+ final int chunkZ = CoordinateUtils.getChunkZ(coordinate); -+ -+ final Set positions = task.changedPositions; -+ final Boolean[] sectionChanges = task.changedSectionSet; -+ -+ if (skyEngine != null && (!positions.isEmpty() || sectionChanges != null)) { -+ skyEngine.blocksChangedInChunk(this.lightAccess, chunkX, chunkZ, positions, sectionChanges); -+ } -+ if (blockEngine != null && (!positions.isEmpty() || sectionChanges != null)) { -+ blockEngine.blocksChangedInChunk(this.lightAccess, chunkX, chunkZ, positions, sectionChanges); -+ } -+ -+ if (skyEngine != null && task.queuedEdgeChecksSky != null) { -+ skyEngine.checkChunkEdges(this.lightAccess, chunkX, chunkZ, task.queuedEdgeChecksSky); -+ } -+ if (blockEngine != null && task.queuedEdgeChecksBlock != null) { -+ blockEngine.checkChunkEdges(this.lightAccess, chunkX, chunkZ, task.queuedEdgeChecksBlock); -+ } -+ -+ task.onComplete.complete(null); -+ } -+ } finally { -+ this.releaseSkyLightEngine(skyEngine); -+ this.releaseBlockLightEngine(blockEngine); -+ } -+ } -+ -+ public static final class LightQueue { -+ -+ protected final Long2ObjectLinkedOpenHashMap chunkTasks = new Long2ObjectLinkedOpenHashMap<>(); -+ protected final StarLightInterface manager; -+ -+ public LightQueue(final StarLightInterface manager) { -+ this.manager = manager; -+ } -+ -+ public synchronized boolean isEmpty() { -+ return this.chunkTasks.isEmpty(); -+ } -+ -+ public synchronized LightQueue.ChunkTasks queueBlockChange(final BlockPos pos) { -+ final ChunkTasks tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), ChunkTasks::new); -+ tasks.changedPositions.add(pos.immutable()); -+ return tasks; -+ } -+ -+ public synchronized LightQueue.ChunkTasks queueSectionChange(final SectionPos pos, final boolean newEmptyValue) { -+ final ChunkTasks tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), ChunkTasks::new); -+ -+ if (tasks.changedSectionSet == null) { -+ tasks.changedSectionSet = new Boolean[this.manager.maxSection - this.manager.minSection + 1]; -+ } -+ tasks.changedSectionSet[pos.getY() - this.manager.minSection] = Boolean.valueOf(newEmptyValue); -+ -+ return tasks; -+ } -+ -+ public synchronized LightQueue.ChunkTasks queueChunkLighting(final ChunkPos pos, final Runnable lightTask) { -+ final ChunkTasks tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), ChunkTasks::new); -+ if (tasks.lightTasks == null) { -+ tasks.lightTasks = new ArrayList<>(); -+ } -+ tasks.lightTasks.add(lightTask); -+ -+ return tasks; -+ } -+ -+ public synchronized LightQueue.ChunkTasks queueChunkSkylightEdgeCheck(final SectionPos pos, final ShortCollection sections) { -+ final ChunkTasks tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), ChunkTasks::new); -+ -+ ShortOpenHashSet queuedEdges = tasks.queuedEdgeChecksSky; -+ if (queuedEdges == null) { -+ queuedEdges = tasks.queuedEdgeChecksSky = new ShortOpenHashSet(); -+ } -+ queuedEdges.addAll(sections); -+ -+ return tasks; -+ } -+ -+ public synchronized LightQueue.ChunkTasks queueChunkBlocklightEdgeCheck(final SectionPos pos, final ShortCollection sections) { -+ final ChunkTasks tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), ChunkTasks::new); -+ -+ ShortOpenHashSet queuedEdges = tasks.queuedEdgeChecksBlock; -+ if (queuedEdges == null) { -+ queuedEdges = tasks.queuedEdgeChecksBlock = new ShortOpenHashSet(); -+ } -+ queuedEdges.addAll(sections); -+ -+ return tasks; -+ } -+ -+ public void removeChunk(final ChunkPos pos) { -+ final ChunkTasks tasks; -+ synchronized (this) { -+ tasks = this.chunkTasks.remove(CoordinateUtils.getChunkKey(pos)); -+ } -+ if (tasks != null) { -+ tasks.onComplete.complete(null); -+ } -+ } -+ -+ public synchronized ChunkTasks removeFirstTask() { -+ if (this.chunkTasks.isEmpty()) { -+ return null; -+ } -+ return this.chunkTasks.removeFirst(); -+ } -+ -+ public static final class ChunkTasks { -+ -+ public final Set changedPositions = new ObjectOpenHashSet<>(); -+ public Boolean[] changedSectionSet; -+ public ShortOpenHashSet queuedEdgeChecksSky; -+ public ShortOpenHashSet queuedEdgeChecksBlock; -+ public List lightTasks; -+ -+ public boolean isTicketAdded = false; -+ public final CompletableFuture onComplete = new CompletableFuture<>(); -+ -+ public final long chunkCoordinate; -+ -+ public ChunkTasks(final long chunkCoordinate) { -+ this.chunkCoordinate = chunkCoordinate; -+ } -+ } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/starlight/common/util/CoordinateUtils.java b/src/main/java/ca/spottedleaf/starlight/common/util/CoordinateUtils.java -new file mode 100644 -index 0000000000000000000000000000000000000000..16a4a14e7ccf9e4d7fdf1166674fe8f529c06d39 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/starlight/common/util/CoordinateUtils.java -@@ -0,0 +1,128 @@ -+package ca.spottedleaf.starlight.common.util; -+ -+import net.minecraft.core.BlockPos; -+import net.minecraft.core.SectionPos; -+import net.minecraft.util.Mth; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.level.ChunkPos; -+ -+public final class CoordinateUtils { -+ -+ // dx, dz are relative to the target chunk -+ // dx, dz in [-radius, radius] -+ public static int getNeighbourMappedIndex(final int dx, final int dz, final int radius) { -+ return (dx + radius) + (2 * radius + 1)*(dz + radius); -+ } -+ -+ // the chunk keys are compatible with vanilla -+ -+ public static long getChunkKey(final BlockPos pos) { -+ return ((long)(pos.getZ() >> 4) << 32) | ((pos.getX() >> 4) & 0xFFFFFFFFL); -+ } -+ -+ public static long getChunkKey(final Entity entity) { -+ return ((long)(Mth.floor(entity.getZ()) >> 4) << 32) | ((Mth.floor(entity.getX()) >> 4) & 0xFFFFFFFFL); -+ } -+ -+ public static long getChunkKey(final ChunkPos pos) { -+ return ((long)pos.z << 32) | (pos.x & 0xFFFFFFFFL); -+ } -+ -+ public static long getChunkKey(final SectionPos pos) { -+ return ((long)pos.getZ() << 32) | (pos.getX() & 0xFFFFFFFFL); -+ } -+ -+ public static long getChunkKey(final int x, final int z) { -+ return ((long)z << 32) | (x & 0xFFFFFFFFL); -+ } -+ -+ public static int getChunkX(final long chunkKey) { -+ return (int)chunkKey; -+ } -+ -+ public static int getChunkZ(final long chunkKey) { -+ return (int)(chunkKey >>> 32); -+ } -+ -+ public static int getChunkCoordinate(final double blockCoordinate) { -+ return Mth.floor(blockCoordinate) >> 4; -+ } -+ -+ // the section keys are compatible with vanilla's -+ -+ static final int SECTION_X_BITS = 22; -+ static final long SECTION_X_MASK = (1L << SECTION_X_BITS) - 1; -+ static final int SECTION_Y_BITS = 20; -+ static final long SECTION_Y_MASK = (1L << SECTION_Y_BITS) - 1; -+ static final int SECTION_Z_BITS = 22; -+ static final long SECTION_Z_MASK = (1L << SECTION_Z_BITS) - 1; -+ // format is y,z,x (in order of LSB to MSB) -+ static final int SECTION_Y_SHIFT = 0; -+ static final int SECTION_Z_SHIFT = SECTION_Y_SHIFT + SECTION_Y_BITS; -+ static final int SECTION_X_SHIFT = SECTION_Z_SHIFT + SECTION_X_BITS; -+ static final int SECTION_TO_BLOCK_SHIFT = 4; -+ -+ public static long getChunkSectionKey(final int x, final int y, final int z) { -+ return ((x & SECTION_X_MASK) << SECTION_X_SHIFT) -+ | ((y & SECTION_Y_MASK) << SECTION_Y_SHIFT) -+ | ((z & SECTION_Z_MASK) << SECTION_Z_SHIFT); -+ } -+ -+ public static long getChunkSectionKey(final SectionPos pos) { -+ return ((pos.getX() & SECTION_X_MASK) << SECTION_X_SHIFT) -+ | ((pos.getY() & SECTION_Y_MASK) << SECTION_Y_SHIFT) -+ | ((pos.getZ() & SECTION_Z_MASK) << SECTION_Z_SHIFT); -+ } -+ -+ public static long getChunkSectionKey(final ChunkPos pos, final int y) { -+ return ((pos.x & SECTION_X_MASK) << SECTION_X_SHIFT) -+ | ((y & SECTION_Y_MASK) << SECTION_Y_SHIFT) -+ | ((pos.z & SECTION_Z_MASK) << SECTION_Z_SHIFT); -+ } -+ -+ public static long getChunkSectionKey(final BlockPos pos) { -+ return (((long)pos.getX() << (SECTION_X_SHIFT - SECTION_TO_BLOCK_SHIFT)) & (SECTION_X_MASK << SECTION_X_SHIFT)) | -+ ((pos.getY() >> SECTION_TO_BLOCK_SHIFT) & (SECTION_Y_MASK << SECTION_Y_SHIFT)) | -+ (((long)pos.getZ() << (SECTION_Z_SHIFT - SECTION_TO_BLOCK_SHIFT)) & (SECTION_Z_MASK << SECTION_Z_SHIFT)); -+ } -+ -+ public static long getChunkSectionKey(final Entity entity) { -+ return ((Mth.lfloor(entity.getX()) << (SECTION_X_SHIFT - SECTION_TO_BLOCK_SHIFT)) & (SECTION_X_MASK << SECTION_X_SHIFT)) | -+ ((Mth.lfloor(entity.getY()) >> SECTION_TO_BLOCK_SHIFT) & (SECTION_Y_MASK << SECTION_Y_SHIFT)) | -+ ((Mth.lfloor(entity.getZ()) << (SECTION_Z_SHIFT - SECTION_TO_BLOCK_SHIFT)) & (SECTION_Z_MASK << SECTION_Z_SHIFT)); -+ } -+ -+ public static int getChunkSectionX(final long key) { -+ return (int)(key << (Long.SIZE - (SECTION_X_SHIFT + SECTION_X_BITS)) >> (Long.SIZE - SECTION_X_BITS)); -+ } -+ -+ public static int getChunkSectionY(final long key) { -+ return (int)(key << (Long.SIZE - (SECTION_Y_SHIFT + SECTION_Y_BITS)) >> (Long.SIZE - SECTION_Y_BITS)); -+ } -+ -+ public static int getChunkSectionZ(final long key) { -+ return (int)(key << (Long.SIZE - (SECTION_Z_SHIFT + SECTION_Z_BITS)) >> (Long.SIZE - SECTION_Z_BITS)); -+ } -+ -+ // the block coordinates are not necessarily compatible with vanilla's -+ -+ public static int getBlockCoordinate(final double blockCoordinate) { -+ return Mth.floor(blockCoordinate); -+ } -+ -+ public static long getBlockKey(final int x, final int y, final int z) { -+ return ((long)x & 0x7FFFFFF) | (((long)z & 0x7FFFFFF) << 27) | ((long)y << 54); -+ } -+ -+ public static long getBlockKey(final BlockPos pos) { -+ return ((long)pos.getX() & 0x7FFFFFF) | (((long)pos.getZ() & 0x7FFFFFF) << 27) | ((long)pos.getY() << 54); -+ } -+ -+ public static long getBlockKey(final Entity entity) { -+ return ((long)entity.getX() & 0x7FFFFFF) | (((long)entity.getZ() & 0x7FFFFFF) << 27) | ((long)entity.getY() << 54); -+ } -+ -+ private CoordinateUtils() { -+ throw new RuntimeException(); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/starlight/common/util/IntegerUtil.java b/src/main/java/ca/spottedleaf/starlight/common/util/IntegerUtil.java -new file mode 100644 -index 0000000000000000000000000000000000000000..fabf1e97c019c7365212f40018dcd08d3b828113 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/starlight/common/util/IntegerUtil.java -@@ -0,0 +1,242 @@ -+package ca.spottedleaf.starlight.common.util; -+ -+public final class IntegerUtil { -+ -+ public static final int HIGH_BIT_U32 = Integer.MIN_VALUE; -+ public static final long HIGH_BIT_U64 = Long.MIN_VALUE; -+ -+ public static int ceilLog2(final int value) { -+ return Integer.SIZE - Integer.numberOfLeadingZeros(value - 1); // see doc of numberOfLeadingZeros -+ } -+ -+ public static long ceilLog2(final long value) { -+ return Long.SIZE - Long.numberOfLeadingZeros(value - 1); // see doc of numberOfLeadingZeros -+ } -+ -+ public static int floorLog2(final int value) { -+ // xor is optimized subtract for 2^n -1 -+ // note that (2^n -1) - k = (2^n -1) ^ k for k <= (2^n - 1) -+ return (Integer.SIZE - 1) ^ Integer.numberOfLeadingZeros(value); // see doc of numberOfLeadingZeros -+ } -+ -+ public static int floorLog2(final long value) { -+ // xor is optimized subtract for 2^n -1 -+ // note that (2^n -1) - k = (2^n -1) ^ k for k <= (2^n - 1) -+ return (Long.SIZE - 1) ^ Long.numberOfLeadingZeros(value); // see doc of numberOfLeadingZeros -+ } -+ -+ public static int roundCeilLog2(final int value) { -+ // optimized variant of 1 << (32 - leading(val - 1)) -+ // given -+ // 1 << n = HIGH_BIT_32 >>> (31 - n) for n [0, 32) -+ // 1 << (32 - leading(val - 1)) = HIGH_BIT_32 >>> (31 - (32 - leading(val - 1))) -+ // HIGH_BIT_32 >>> (31 - (32 - leading(val - 1))) -+ // HIGH_BIT_32 >>> (31 - 32 + leading(val - 1)) -+ // HIGH_BIT_32 >>> (-1 + leading(val - 1)) -+ return HIGH_BIT_U32 >>> (Integer.numberOfLeadingZeros(value - 1) - 1); -+ } -+ -+ public static long roundCeilLog2(final long value) { -+ // see logic documented above -+ return HIGH_BIT_U64 >>> (Long.numberOfLeadingZeros(value - 1) - 1); -+ } -+ -+ public static int roundFloorLog2(final int value) { -+ // optimized variant of 1 << (31 - leading(val)) -+ // given -+ // 1 << n = HIGH_BIT_32 >>> (31 - n) for n [0, 32) -+ // 1 << (31 - leading(val)) = HIGH_BIT_32 >> (31 - (31 - leading(val))) -+ // HIGH_BIT_32 >> (31 - (31 - leading(val))) -+ // HIGH_BIT_32 >> (31 - 31 + leading(val)) -+ return HIGH_BIT_U32 >>> Integer.numberOfLeadingZeros(value); -+ } -+ -+ public static long roundFloorLog2(final long value) { -+ // see logic documented above -+ return HIGH_BIT_U64 >>> Long.numberOfLeadingZeros(value); -+ } -+ -+ public static boolean isPowerOfTwo(final int n) { -+ // 2^n has one bit -+ // note: this rets true for 0 still -+ return IntegerUtil.getTrailingBit(n) == n; -+ } -+ -+ public static boolean isPowerOfTwo(final long n) { -+ // 2^n has one bit -+ // note: this rets true for 0 still -+ return IntegerUtil.getTrailingBit(n) == n; -+ } -+ -+ public static int getTrailingBit(final int n) { -+ return -n & n; -+ } -+ -+ public static long getTrailingBit(final long n) { -+ return -n & n; -+ } -+ -+ public static int trailingZeros(final int n) { -+ return Integer.numberOfTrailingZeros(n); -+ } -+ -+ public static int trailingZeros(final long n) { -+ return Long.numberOfTrailingZeros(n); -+ } -+ -+ // from hacker's delight (signed division magic value) -+ public static int getDivisorMultiple(final long numbers) { -+ return (int)(numbers >>> 32); -+ } -+ -+ // from hacker's delight (signed division magic value) -+ public static int getDivisorShift(final long numbers) { -+ return (int)numbers; -+ } -+ -+ // copied from hacker's delight (signed division magic value) -+ // http://www.hackersdelight.org/hdcodetxt/magic.c.txt -+ public static long getDivisorNumbers(final int d) { -+ final int ad = branchlessAbs(d); -+ -+ if (ad < 2) { -+ throw new IllegalArgumentException("|number| must be in [2, 2^31 -1], not: " + d); -+ } -+ -+ final int two31 = 0x80000000; -+ final long mask = 0xFFFFFFFFL; // mask for enforcing unsigned behaviour -+ -+ /* -+ Signed usage: -+ int number; -+ long magic = getDivisorNumbers(div); -+ long mul = magic >>> 32; -+ int sign = number >> 31; -+ int result = (int)(((long)number * mul) >>> magic) - sign; -+ */ -+ /* -+ Unsigned usage: -+ int number; -+ long magic = getDivisorNumbers(div); -+ long mul = magic >>> 32; -+ int result = (int)(((long)number * mul) >>> magic); -+ */ -+ -+ int p = 31; -+ -+ // all these variables are UNSIGNED! -+ int t = two31 + (d >>> 31); -+ int anc = t - 1 - (int)((t & mask)%ad); -+ int q1 = (int)((two31 & mask)/(anc & mask)); -+ int r1 = two31 - q1*anc; -+ int q2 = (int)((two31 & mask)/(ad & mask)); -+ int r2 = two31 - q2*ad; -+ int delta; -+ -+ do { -+ p = p + 1; -+ q1 = 2*q1; // Update q1 = 2**p/|nc|. -+ r1 = 2*r1; // Update r1 = rem(2**p, |nc|). -+ if ((r1 & mask) >= (anc & mask)) {// (Must be an unsigned comparison here) -+ q1 = q1 + 1; -+ r1 = r1 - anc; -+ } -+ q2 = 2*q2; // Update q2 = 2**p/|d|. -+ r2 = 2*r2; // Update r2 = rem(2**p, |d|). -+ if ((r2 & mask) >= (ad & mask)) {// (Must be an unsigned comparison here) -+ q2 = q2 + 1; -+ r2 = r2 - ad; -+ } -+ delta = ad - r2; -+ } while ((q1 & mask) < (delta & mask) || (q1 == delta && r1 == 0)); -+ -+ int magicNum = q2 + 1; -+ if (d < 0) { -+ magicNum = -magicNum; -+ } -+ int shift = p; -+ return ((long)magicNum << 32) | shift; -+ } -+ -+ public static int branchlessAbs(final int val) { -+ // -n = -1 ^ n + 1 -+ final int mask = val >> (Integer.SIZE - 1); // -1 if < 0, 0 if >= 0 -+ return (mask ^ val) - mask; // if val < 0, then (0 ^ val) - 0 else (-1 ^ val) + 1 -+ } -+ -+ public static long branchlessAbs(final long val) { -+ // -n = -1 ^ n + 1 -+ final long mask = val >> (Long.SIZE - 1); // -1 if < 0, 0 if >= 0 -+ return (mask ^ val) - mask; // if val < 0, then (0 ^ val) - 0 else (-1 ^ val) + 1 -+ } -+ -+ //https://github.com/skeeto/hash-prospector for hash functions -+ -+ //score = ~590.47984224483832 -+ public static int hash0(int x) { -+ x *= 0x36935555; -+ x ^= x >>> 16; -+ return x; -+ } -+ -+ //score = ~310.01596637036749 -+ public static int hash1(int x) { -+ x ^= x >>> 15; -+ x *= 0x356aaaad; -+ x ^= x >>> 17; -+ return x; -+ } -+ -+ public static int hash2(int x) { -+ x ^= x >>> 16; -+ x *= 0x7feb352d; -+ x ^= x >>> 15; -+ x *= 0x846ca68b; -+ x ^= x >>> 16; -+ return x; -+ } -+ -+ public static int hash3(int x) { -+ x ^= x >>> 17; -+ x *= 0xed5ad4bb; -+ x ^= x >>> 11; -+ x *= 0xac4c1b51; -+ x ^= x >>> 15; -+ x *= 0x31848bab; -+ x ^= x >>> 14; -+ return x; -+ } -+ -+ //score = ~365.79959673201887 -+ public static long hash1(long x) { -+ x ^= x >>> 27; -+ x *= 0xb24924b71d2d354bL; -+ x ^= x >>> 28; -+ return x; -+ } -+ -+ //h2 hash -+ public static long hash2(long x) { -+ x ^= x >>> 32; -+ x *= 0xd6e8feb86659fd93L; -+ x ^= x >>> 32; -+ x *= 0xd6e8feb86659fd93L; -+ x ^= x >>> 32; -+ return x; -+ } -+ -+ public static long hash3(long x) { -+ x ^= x >>> 45; -+ x *= 0xc161abe5704b6c79L; -+ x ^= x >>> 41; -+ x *= 0xe3e5389aedbc90f7L; -+ x ^= x >>> 56; -+ x *= 0x1f9aba75a52db073L; -+ x ^= x >>> 53; -+ return x; -+ } -+ -+ private IntegerUtil() { -+ throw new RuntimeException(); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/starlight/common/util/SaveUtil.java b/src/main/java/ca/spottedleaf/starlight/common/util/SaveUtil.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c2903150c8fc6955f4f4f71acc932b6c2ac83484 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/starlight/common/util/SaveUtil.java -@@ -0,0 +1,192 @@ -+package ca.spottedleaf.starlight.common.util; -+ -+import ca.spottedleaf.starlight.common.light.SWMRNibbleArray; -+import ca.spottedleaf.starlight.common.light.StarLightEngine; -+import com.mojang.logging.LogUtils; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.nbt.ListTag; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.status.ChunkStatus; -+import org.slf4j.Logger; -+ -+public final class SaveUtil { -+ -+ private static final Logger LOGGER = LogUtils.getLogger(); -+ -+ private static final int STARLIGHT_LIGHT_VERSION = 9; -+ -+ public static int getLightVersion() { -+ return STARLIGHT_LIGHT_VERSION; -+ } -+ -+ private static final String BLOCKLIGHT_STATE_TAG = "starlight.blocklight_state"; -+ private static final String SKYLIGHT_STATE_TAG = "starlight.skylight_state"; -+ private static final String STARLIGHT_VERSION_TAG = "starlight.light_version"; -+ -+ public static void saveLightHook(final Level world, final ChunkAccess chunk, final CompoundTag nbt) { -+ try { -+ saveLightHookReal(world, chunk, nbt); -+ } catch (final Throwable ex) { -+ // failing to inject is not fatal so we catch anything here. if it fails, it will have correctly set lit to false -+ // for Vanilla to relight on load and it will not set our lit tag so we will relight on load -+ if (ex instanceof ThreadDeath) { -+ throw (ThreadDeath)ex; -+ } -+ LOGGER.warn("Failed to inject light data into save data for chunk " + chunk.getPos() + ", chunk light will be recalculated on its next load", ex); -+ } -+ } -+ -+ private static void saveLightHookReal(final Level world, final ChunkAccess chunk, final CompoundTag tag) { -+ if (tag == null) { -+ return; -+ } -+ -+ final int minSection = WorldUtil.getMinLightSection(world); -+ final int maxSection = WorldUtil.getMaxLightSection(world); -+ -+ SWMRNibbleArray[] blockNibbles = chunk.getBlockNibbles(); -+ SWMRNibbleArray[] skyNibbles = chunk.getSkyNibbles(); -+ -+ boolean lit = chunk.isLightCorrect() || !(world instanceof ServerLevel); -+ // diff start - store our tag for whether light data is init'd -+ if (lit) { -+ tag.putBoolean("isLightOn", false); -+ } -+ // diff end - store our tag for whether light data is init'd -+ ChunkStatus status = ChunkStatus.byName(tag.getString("Status")); -+ -+ CompoundTag[] sections = new CompoundTag[maxSection - minSection + 1]; -+ -+ ListTag sectionsStored = tag.getList("sections", 10); -+ -+ for (int i = 0; i < sectionsStored.size(); ++i) { -+ CompoundTag sectionStored = sectionsStored.getCompound(i); -+ int k = sectionStored.getByte("Y"); -+ -+ // strip light data -+ sectionStored.remove("BlockLight"); -+ sectionStored.remove("SkyLight"); -+ -+ if (!sectionStored.isEmpty()) { -+ sections[k - minSection] = sectionStored; -+ } -+ } -+ -+ if (lit && status.isOrAfter(ChunkStatus.LIGHT)) { -+ for (int i = minSection; i <= maxSection; ++i) { -+ SWMRNibbleArray.SaveState blockNibble = blockNibbles[i - minSection].getSaveState(); -+ SWMRNibbleArray.SaveState skyNibble = skyNibbles[i - minSection].getSaveState(); -+ if (blockNibble != null || skyNibble != null) { -+ CompoundTag section = sections[i - minSection]; -+ if (section == null) { -+ section = new CompoundTag(); -+ section.putByte("Y", (byte)i); -+ sections[i - minSection] = section; -+ } -+ -+ // we store under the same key so mod programs editing nbt -+ // can still read the data, hopefully. -+ // however, for compatibility we store chunks as unlit so vanilla -+ // is forced to re-light them if it encounters our data. It's too much of a burden -+ // to try and maintain compatibility with a broken and inferior skylight management system. -+ -+ if (blockNibble != null) { -+ if (blockNibble.data != null) { -+ section.putByteArray("BlockLight", blockNibble.data); -+ } -+ section.putInt(BLOCKLIGHT_STATE_TAG, blockNibble.state); -+ } -+ -+ if (skyNibble != null) { -+ if (skyNibble.data != null) { -+ section.putByteArray("SkyLight", skyNibble.data); -+ } -+ section.putInt(SKYLIGHT_STATE_TAG, skyNibble.state); -+ } -+ } -+ } -+ } -+ -+ // rewrite section list -+ sectionsStored.clear(); -+ for (CompoundTag section : sections) { -+ if (section != null) { -+ sectionsStored.add(section); -+ } -+ } -+ tag.put("sections", sectionsStored); -+ if (lit) { -+ tag.putInt(STARLIGHT_VERSION_TAG, STARLIGHT_LIGHT_VERSION); // only mark as fully lit after we have successfully injected our data -+ } -+ } -+ -+ public static void loadLightHook(final Level world, final ChunkPos pos, final CompoundTag tag, final ChunkAccess into) { -+ try { -+ loadLightHookReal(world, pos, tag, into); -+ } catch (final Throwable ex) { -+ // failing to inject is not fatal so we catch anything here. if it fails, then we simply relight. Not a problem, we get correct -+ // lighting in both cases. -+ if (ex instanceof ThreadDeath) { -+ throw (ThreadDeath)ex; -+ } -+ LOGGER.warn("Failed to load light for chunk " + pos + ", light will be recalculated", ex); -+ } -+ } -+ -+ private static void loadLightHookReal(final Level world, final ChunkPos pos, final CompoundTag tag, final ChunkAccess into) { -+ if (into == null) { -+ return; -+ } -+ final int minSection = WorldUtil.getMinLightSection(world); -+ final int maxSection = WorldUtil.getMaxLightSection(world); -+ -+ into.setLightCorrect(false); // mark as unlit in case we fail parsing -+ -+ SWMRNibbleArray[] blockNibbles = StarLightEngine.getFilledEmptyLight(world); -+ SWMRNibbleArray[] skyNibbles = StarLightEngine.getFilledEmptyLight(world); -+ -+ -+ // start copy from the original method -+ boolean lit = tag.get("isLightOn") != null && tag.getInt(STARLIGHT_VERSION_TAG) == STARLIGHT_LIGHT_VERSION; -+ boolean canReadSky = world.dimensionType().hasSkyLight(); -+ ChunkStatus status = ChunkStatus.byName(tag.getString("Status")); -+ if (lit && status.isOrAfter(ChunkStatus.LIGHT)) { // diff - we add the status check here -+ ListTag sections = tag.getList("sections", 10); -+ -+ for (int i = 0; i < sections.size(); ++i) { -+ CompoundTag sectionData = sections.getCompound(i); -+ int y = sectionData.getByte("Y"); -+ -+ if (sectionData.contains("BlockLight", 7)) { -+ // this is where our diff is -+ blockNibbles[y - minSection] = new SWMRNibbleArray(sectionData.getByteArray("BlockLight").clone(), sectionData.getInt(BLOCKLIGHT_STATE_TAG)); // clone for data safety -+ } else { -+ blockNibbles[y - minSection] = new SWMRNibbleArray(null, sectionData.getInt(BLOCKLIGHT_STATE_TAG)); -+ } -+ -+ if (canReadSky) { -+ if (sectionData.contains("SkyLight", 7)) { -+ // we store under the same key so mod programs editing nbt -+ // can still read the data, hopefully. -+ // however, for compatibility we store chunks as unlit so vanilla -+ // is forced to re-light them if it encounters our data. It's too much of a burden -+ // to try and maintain compatibility with a broken and inferior skylight management system. -+ skyNibbles[y - minSection] = new SWMRNibbleArray(sectionData.getByteArray("SkyLight").clone(), sectionData.getInt(SKYLIGHT_STATE_TAG)); // clone for data safety -+ } else { -+ skyNibbles[y - minSection] = new SWMRNibbleArray(null, sectionData.getInt(SKYLIGHT_STATE_TAG)); -+ } -+ } -+ } -+ } -+ // end copy from vanilla -+ -+ into.setBlockNibbles(blockNibbles); -+ into.setSkyNibbles(skyNibbles); -+ into.setLightCorrect(lit); // now we set lit here, only after we've correctly parsed data -+ } -+ -+ private SaveUtil() {} -+} -diff --git a/src/main/java/ca/spottedleaf/starlight/common/util/WorldUtil.java b/src/main/java/ca/spottedleaf/starlight/common/util/WorldUtil.java -new file mode 100644 -index 0000000000000000000000000000000000000000..dd995e25ae620ae36cd5eecb2fe10ad034ba50d2 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/starlight/common/util/WorldUtil.java -@@ -0,0 +1,47 @@ -+package ca.spottedleaf.starlight.common.util; -+ -+import net.minecraft.world.level.LevelHeightAccessor; -+ -+public final class WorldUtil { -+ -+ // min, max are inclusive -+ -+ public static int getMaxSection(final LevelHeightAccessor world) { -+ return world.getMaxSection() - 1; // getMaxSection() is exclusive -+ } -+ -+ public static int getMinSection(final LevelHeightAccessor world) { -+ return world.getMinSection(); -+ } -+ -+ public static int getMaxLightSection(final LevelHeightAccessor world) { -+ return getMaxSection(world) + 1; -+ } -+ -+ public static int getMinLightSection(final LevelHeightAccessor world) { -+ return getMinSection(world) - 1; -+ } -+ -+ -+ -+ public static int getTotalSections(final LevelHeightAccessor world) { -+ return getMaxSection(world) - getMinSection(world) + 1; -+ } -+ -+ public static int getTotalLightSections(final LevelHeightAccessor world) { -+ return getMaxLightSection(world) - getMinLightSection(world) + 1; -+ } -+ -+ public static int getMinBlockY(final LevelHeightAccessor world) { -+ return getMinSection(world) << 4; -+ } -+ -+ public static int getMaxBlockY(final LevelHeightAccessor world) { -+ return (getMaxSection(world) << 4) | 15; -+ } -+ -+ private WorldUtil() { -+ throw new RuntimeException(); -+ } -+ -+} -diff --git a/src/main/java/io/papermc/paper/command/PaperCommand.java b/src/main/java/io/papermc/paper/command/PaperCommand.java -index 46bf42d5ea9e7b046f962531c5962d287cf44a41..a3f43dccb796f30f6e9389e1ae182f06e9024e96 100644 ---- a/src/main/java/io/papermc/paper/command/PaperCommand.java -+++ b/src/main/java/io/papermc/paper/command/PaperCommand.java -@@ -42,6 +42,7 @@ public final class PaperCommand extends Command { - commands.put(Set.of("dumpitem"), new DumpItemCommand()); - commands.put(Set.of("mobcaps", "playermobcaps"), new MobcapsCommand()); - commands.put(Set.of("dumplisteners"), new DumpListenersCommand()); -+ commands.put(Set.of("fixlight"), new FixLightCommand()); - - return commands.entrySet().stream() - .flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue()))) -diff --git a/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java b/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java -new file mode 100644 -index 0000000000000000000000000000000000000000..56524cbe4303901007e1e7fb3703a19efbf79ae7 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/command/subcommands/FixLightCommand.java -@@ -0,0 +1,109 @@ -+package io.papermc.paper.command.subcommands; -+ -+import io.papermc.paper.command.PaperSubcommand; -+import io.papermc.paper.util.MCUtil; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.server.level.ThreadedLevelLightEngine; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import org.bukkit.command.CommandSender; -+import org.bukkit.craftbukkit.entity.CraftPlayer; -+import org.bukkit.entity.Player; -+import org.checkerframework.checker.nullness.qual.NonNull; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.checkerframework.framework.qual.DefaultQualifier; -+ -+import static net.kyori.adventure.text.Component.text; -+import static net.kyori.adventure.text.format.NamedTextColor.BLUE; -+import static net.kyori.adventure.text.format.NamedTextColor.DARK_AQUA; -+import static net.kyori.adventure.text.format.NamedTextColor.RED; -+ -+@DefaultQualifier(NonNull.class) -+public final class FixLightCommand implements PaperSubcommand { -+ @Override -+ public boolean execute(final CommandSender sender, final String subCommand, final String[] args) { -+ this.doFixLight(sender, args); -+ return true; -+ } -+ -+ private void doFixLight(final CommandSender sender, final String[] args) { -+ if (!(sender instanceof Player)) { -+ sender.sendMessage(text("Only players can use this command", RED)); -+ return; -+ } -+ @Nullable Runnable post = null; -+ int radius = 2; -+ if (args.length > 0) { -+ try { -+ final int parsed = Integer.parseInt(args[0]); -+ if (parsed < 0) { -+ sender.sendMessage(text("Radius cannot be negative!", RED)); -+ return; -+ } -+ final int maxRadius = 32; -+ radius = Math.min(maxRadius, parsed); -+ if (radius != parsed) { -+ post = () -> sender.sendMessage(text("Radius '" + parsed + "' was not in the required range [0, " + maxRadius + "], it was lowered to the maximum (" + maxRadius + " chunks).", RED)); -+ } -+ } catch (final Exception e) { -+ sender.sendMessage(text("'" + args[0] + "' is not a valid number.", RED)); -+ return; -+ } -+ } -+ -+ CraftPlayer player = (CraftPlayer) sender; -+ ServerPlayer handle = player.getHandle(); -+ ServerLevel world = (ServerLevel) handle.level(); -+ ThreadedLevelLightEngine lightengine = world.getChunkSource().getLightEngine(); -+ this.starlightFixLight(handle, world, lightengine, radius, post); -+ } -+ -+ private void starlightFixLight( -+ final ServerPlayer sender, -+ final ServerLevel world, -+ final ThreadedLevelLightEngine lightengine, -+ final int radius, -+ final @Nullable Runnable done -+ ) { -+ final long start = System.nanoTime(); -+ final java.util.LinkedHashSet chunks = new java.util.LinkedHashSet<>(MCUtil.getSpiralOutChunks(sender.blockPosition(), radius)); // getChunkCoordinates is actually just bad mappings, this function rets position as blockpos -+ -+ final int[] pending = new int[1]; -+ for (java.util.Iterator iterator = chunks.iterator(); iterator.hasNext(); ) { -+ final ChunkPos chunkPos = iterator.next(); -+ -+ final @Nullable ChunkAccess chunk = (ChunkAccess) world.getChunkSource().getChunkForLighting(chunkPos.x, chunkPos.z); -+ if (chunk == null || !chunk.isLightCorrect() || !chunk.getStatus().isOrAfter(net.minecraft.world.level.chunk.status.ChunkStatus.LIGHT)) { -+ // cannot relight this chunk -+ iterator.remove(); -+ continue; -+ } -+ -+ ++pending[0]; -+ } -+ -+ final int[] relitChunks = new int[1]; -+ lightengine.relight(chunks, -+ (final ChunkPos chunkPos) -> { -+ ++relitChunks[0]; -+ sender.getBukkitEntity().sendMessage(text().color(DARK_AQUA).append( -+ text("Relit chunk ", BLUE), text(chunkPos.toString()), -+ text(", progress: ", BLUE), text((int) (Math.round(100.0 * (double) (relitChunks[0]) / (double) pending[0])) + "%") -+ )); -+ }, -+ (final int totalRelit) -> { -+ final long end = System.nanoTime(); -+ final long diff = Math.round(1.0e-6 * (end - start)); -+ sender.getBukkitEntity().sendMessage(text().color(DARK_AQUA).append( -+ text("Relit ", BLUE), text(totalRelit), -+ text(" chunks. Took ", BLUE), text(diff + "ms") -+ )); -+ if (done != null) { -+ done.run(); -+ } -+ } -+ ); -+ sender.getBukkitEntity().sendMessage(text().color(BLUE).append(text("Relighting "), text(pending[0], DARK_AQUA), text(" chunks"))); -+ } -+} -diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java -index b12921579cb9ab3cbf5607841cc84f2f843624ea..88729d92878f98729eb5669cce5ae5b1418865a1 100644 ---- a/src/main/java/net/minecraft/server/level/ChunkHolder.java -+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java -@@ -51,7 +51,7 @@ public class ChunkHolder { - private volatile CompletableFuture> fullChunkFuture; private int fullChunkCreateCount; private volatile boolean isFullChunkReady; // Paper - cache chunk ticking stage - private volatile CompletableFuture> tickingChunkFuture; private volatile boolean isTickingReady; // Paper - cache chunk ticking stage - private volatile CompletableFuture> entityTickingChunkFuture; private volatile boolean isEntityTickingReady; // Paper - cache chunk ticking stage -- private CompletableFuture chunkToSave; -+ public CompletableFuture chunkToSave; // Paper - public - @Nullable - private final DebugBuffer chunkToSaveHistory; - public int oldTicketLevel; -@@ -261,6 +261,12 @@ public class ChunkHolder { - } - } - -+ // Paper start - starlight -+ public void broadcast(Packet packet, boolean onChunkViewEdge) { -+ this.broadcast(this.playerProvider.getPlayers(this.pos, onChunkViewEdge), packet); -+ } -+ // Paper end - starlight -+ - public void broadcastChanges(LevelChunk chunk) { - if (this.hasChangedSections || !this.skyChangedLightSectionFilter.isEmpty() || !this.blockChangedLightSectionFilter.isEmpty()) { - Level world = chunk.getLevel(); -diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 35f627c58e93c03ee58b44877398432bba57dc2d..d3f63185edd1db9fab3887ea3f08982435b3a23c 100644 ---- a/src/main/java/net/minecraft/server/level/ChunkMap.java -+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -128,7 +128,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - private final LongSet entitiesInLevel; - public final ServerLevel level; - private final ThreadedLevelLightEngine lightEngine; -- private final BlockableEventLoop mainThreadExecutor; -+ public final BlockableEventLoop mainThreadExecutor; // Paper - public - public ChunkGenerator generator; - private final RandomState randomState; - private final ChunkGeneratorStructureState chunkGeneratorState; -diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java -index c473cb1888e9ab0e91ba44f1439b81742758304e..7a48ae2ba962ff56d0abff581b51f28b48bd9aae 100644 ---- a/src/main/java/net/minecraft/server/level/DistanceManager.java -+++ b/src/main/java/net/minecraft/server/level/DistanceManager.java -@@ -379,7 +379,7 @@ public abstract class DistanceManager { - } - - public void removeTicketsOnClosing() { -- ImmutableSet> immutableset = ImmutableSet.of(TicketType.UNKNOWN, TicketType.POST_TELEPORT, TicketType.LIGHT, TicketType.FUTURE_AWAIT); // Paper - add additional tickets to preserve -+ ImmutableSet> immutableset = ImmutableSet.of(TicketType.UNKNOWN, TicketType.POST_TELEPORT, TicketType.LIGHT, TicketType.FUTURE_AWAIT, TicketType.CHUNK_RELIGHT, ca.spottedleaf.starlight.common.light.StarLightInterface.CHUNK_WORK_TICKET); // Paper - add additional tickets to preserve - ObjectIterator>>> objectiterator = this.tickets.long2ObjectEntrySet().fastIterator(); - - while (objectiterator.hasNext()) { -diff --git a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -index 1dfae40ec19c4df0a97359941cf2c948cd1c9cb2..f206df06a7d8895175db31d4a840d7467ffe826f 100644 ---- a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -+++ b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -@@ -23,6 +23,17 @@ import net.minecraft.world.level.chunk.LightChunkGetter; - import net.minecraft.world.level.lighting.LevelLightEngine; - import org.slf4j.Logger; - -+// Paper start -+import ca.spottedleaf.starlight.common.light.StarLightEngine; -+import io.papermc.paper.util.CoordinateUtils; -+import java.util.function.Supplier; -+import net.minecraft.world.level.lighting.LayerLightEventListener; -+import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; -+import it.unimi.dsi.fastutil.longs.LongArrayList; -+import it.unimi.dsi.fastutil.longs.LongIterator; -+import net.minecraft.world.level.chunk.status.ChunkStatus; -+// Paper end -+ - public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCloseable { - public static final int DEFAULT_BATCH_SIZE = 1000; - private static final Logger LOGGER = LogUtils.getLogger(); -@@ -33,6 +44,12 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - private final int taskPerBatch = 1000; - private final AtomicBoolean scheduled = new AtomicBoolean(); - -+ // Paper start - replace light engine impl -+ protected final ca.spottedleaf.starlight.common.light.StarLightInterface theLightEngine; -+ public final boolean hasBlockLight; -+ public final boolean hasSkyLight; -+ // Paper end - replace light engine impl -+ - public ThreadedLevelLightEngine( - LightChunkGetter chunkProvider, - ChunkMap chunkStorage, -@@ -40,11 +57,153 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - ProcessorMailbox processor, - ProcessorHandle> executor - ) { -- super(chunkProvider, true, hasBlockLight); -+ super(chunkProvider, false, false); // Paper - destroy vanilla light engine state - this.chunkMap = chunkStorage; - this.sorterMailbox = executor; - this.taskMailbox = processor; -+ // Paper start - replace light engine impl -+ this.hasBlockLight = true; -+ this.hasSkyLight = hasBlockLight; // Nice variable name. -+ this.theLightEngine = new ca.spottedleaf.starlight.common.light.StarLightInterface(chunkProvider, this.hasSkyLight, this.hasBlockLight, this); -+ // Paper end - replace light engine impl -+ } -+ -+ // Paper start - replace light engine impl -+ protected final ChunkAccess getChunk(final int chunkX, final int chunkZ) { -+ return ((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().getChunkAtImmediately(chunkX, chunkZ); -+ } -+ -+ protected long relightCounter; -+ -+ public int relight(java.util.Set chunks_param, -+ java.util.function.Consumer chunkLightCallback, -+ java.util.function.IntConsumer onComplete) { -+ if (!org.bukkit.Bukkit.isPrimaryThread()) { -+ throw new IllegalStateException("Must only be called on the main thread"); -+ } -+ -+ java.util.Set chunks = new java.util.LinkedHashSet<>(chunks_param); -+ // add tickets -+ java.util.Map ticketIds = new java.util.HashMap<>(); -+ int totalChunks = 0; -+ for (java.util.Iterator iterator = chunks.iterator(); iterator.hasNext();) { -+ final ChunkPos chunkPos = iterator.next(); -+ -+ final ChunkAccess chunk = (ChunkAccess)((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().getChunkForLighting(chunkPos.x, chunkPos.z); -+ if (chunk == null || !chunk.isLightCorrect() || !chunk.getStatus().isOrAfter(ChunkStatus.LIGHT)) { -+ // cannot relight this chunk -+ iterator.remove(); -+ continue; -+ } -+ -+ final Long id = Long.valueOf(this.relightCounter++); -+ -+ ((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().addTicketAtLevel(TicketType.CHUNK_RELIGHT, chunkPos, io.papermc.paper.util.MCUtil.getTicketLevelFor(ChunkStatus.LIGHT), id); -+ ticketIds.put(chunkPos, id); -+ -+ ++totalChunks; -+ } -+ -+ this.taskMailbox.tell(() -> { -+ this.theLightEngine.relightChunks(chunks, (ChunkPos chunkPos) -> { -+ chunkLightCallback.accept(chunkPos); -+ ((java.util.concurrent.Executor)((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().mainThreadProcessor).execute(() -> { -+ ((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().chunkMap.getUpdatingChunkIfPresent(chunkPos.toLong()).broadcast(new net.minecraft.network.protocol.game.ClientboundLightUpdatePacket(chunkPos, ThreadedLevelLightEngine.this, null, null), false); -+ ((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().removeTicketAtLevel(TicketType.CHUNK_RELIGHT, chunkPos, io.papermc.paper.util.MCUtil.getTicketLevelFor(ChunkStatus.LIGHT), ticketIds.get(chunkPos)); -+ }); -+ }, onComplete); -+ }); -+ this.tryScheduleUpdate(); -+ -+ return totalChunks; -+ } -+ -+ private final Long2IntOpenHashMap chunksBeingWorkedOn = new Long2IntOpenHashMap(); -+ -+ private void queueTaskForSection(final int chunkX, final int chunkY, final int chunkZ, -+ final Supplier runnable) { -+ final ServerLevel world = (ServerLevel)this.theLightEngine.getWorld(); -+ -+ final ChunkAccess center = this.theLightEngine.getAnyChunkNow(chunkX, chunkZ); -+ if (center == null || !center.getStatus().isOrAfter(ChunkStatus.LIGHT)) { -+ // do not accept updates in unlit chunks, unless we might be generating a chunk. thanks to the amazing -+ // chunk scheduling, we could be lighting and generating a chunk at the same time -+ return; -+ } -+ -+ if (center.getStatus() != ChunkStatus.FULL) { -+ // do not keep chunk loaded, we are probably in a gen thread -+ // if we proceed to add a ticket the chunk will be loaded, which is not what we want (avoid cascading gen) -+ runnable.get(); -+ return; -+ } -+ -+ if (!world.getChunkSource().chunkMap.mainThreadExecutor.isSameThread()) { -+ // ticket logic is not safe to run off-main, re-schedule -+ world.getChunkSource().chunkMap.mainThreadExecutor.execute(() -> { -+ this.queueTaskForSection(chunkX, chunkY, chunkZ, runnable); -+ }); -+ return; -+ } -+ -+ final long key = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ -+ final ca.spottedleaf.starlight.common.light.StarLightInterface.LightQueue.ChunkTasks updateFuture = runnable.get(); -+ -+ if (updateFuture == null) { -+ // not scheduled -+ return; -+ } -+ -+ if (updateFuture.isTicketAdded) { -+ // ticket already added -+ return; -+ } -+ updateFuture.isTicketAdded = true; -+ -+ final int references = this.chunksBeingWorkedOn.addTo(key, 1); -+ if (references == 0) { -+ final ChunkPos pos = new ChunkPos(chunkX, chunkZ); -+ world.getChunkSource().addRegionTicket(ca.spottedleaf.starlight.common.light.StarLightInterface.CHUNK_WORK_TICKET, pos, 0, pos); -+ } -+ -+ updateFuture.onComplete.thenAcceptAsync((final Void ignore) -> { -+ final int newReferences = this.chunksBeingWorkedOn.get(key); -+ if (newReferences == 1) { -+ this.chunksBeingWorkedOn.remove(key); -+ final ChunkPos pos = new ChunkPos(chunkX, chunkZ); -+ world.getChunkSource().removeRegionTicket(ca.spottedleaf.starlight.common.light.StarLightInterface.CHUNK_WORK_TICKET, pos, 0, pos); -+ } else { -+ this.chunksBeingWorkedOn.put(key, newReferences - 1); -+ } -+ }, world.getChunkSource().chunkMap.mainThreadExecutor).whenComplete((final Void ignore, final Throwable thr) -> { -+ if (thr != null) { -+ LOGGER.error("Failed to remove ticket level for post chunk task " + new ChunkPos(chunkX, chunkZ), thr); -+ } -+ }); -+ } -+ -+ @Override -+ public boolean hasLightWork() { -+ // route to new light engine -+ return this.theLightEngine.hasUpdates(); -+ } -+ -+ @Override -+ public LayerLightEventListener getLayerListener(final LightLayer lightType) { -+ return lightType == LightLayer.BLOCK ? this.theLightEngine.getBlockReader() : this.theLightEngine.getSkyReader(); -+ } -+ -+ @Override -+ public int getRawBrightness(final BlockPos pos, final int ambientDarkness) { -+ // need to use new light hooks for this -+ final int sky = this.theLightEngine.getSkyReader().getLightValue(pos) - ambientDarkness; -+ // Don't fetch the block light level if the skylight level is 15, since the value will never be higher. -+ if (sky == 15) return 15; -+ final int block = this.theLightEngine.getBlockReader().getLightValue(pos); -+ return Math.max(sky, block); - } -+ // Paper end - replace light engine imp - - @Override - public void close() { -@@ -57,16 +216,16 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - - @Override - public void checkBlock(BlockPos pos) { -- BlockPos blockPos = pos.immutable(); -- this.addTask( -- SectionPos.blockToSectionCoord(pos.getX()), -- SectionPos.blockToSectionCoord(pos.getZ()), -- ThreadedLevelLightEngine.TaskType.PRE_UPDATE, -- Util.name(() -> super.checkBlock(blockPos), () -> "checkBlock " + blockPos) -- ); -+ // Paper start - replace light engine impl -+ final BlockPos posCopy = pos.immutable(); -+ this.queueTaskForSection(posCopy.getX() >> 4, posCopy.getY() >> 4, posCopy.getZ() >> 4, () -> { -+ return this.theLightEngine.blockChange(posCopy); -+ }); -+ // Paper end - replace light engine impl - } - - protected void updateChunkStatus(ChunkPos pos) { -+ if (true) return; // Paper - replace light engine impl - this.addTask(pos.x, pos.z, () -> 0, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> { - super.retainData(pos, false); - super.setLightEnabled(pos, false); -@@ -84,17 +243,16 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - - @Override - public void updateSectionStatus(SectionPos pos, boolean notReady) { -- this.addTask( -- pos.x(), -- pos.z(), -- () -> 0, -- ThreadedLevelLightEngine.TaskType.PRE_UPDATE, -- Util.name(() -> super.updateSectionStatus(pos, notReady), () -> "updateSectionStatus " + pos + " " + notReady) -- ); -+ // Paper start - replace light engine impl -+ this.queueTaskForSection(pos.getX(), pos.getY(), pos.getZ(), () -> { -+ return this.theLightEngine.sectionChange(pos, notReady); -+ }); -+ // Paper end - replace light engine impl - } - - @Override - public void propagateLightSources(ChunkPos chunkPos) { -+ if (true) return; // Paper - replace light engine impl - this.addTask( - chunkPos.x, - chunkPos.z, -@@ -105,6 +263,7 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - - @Override - public void setLightEnabled(ChunkPos pos, boolean retainData) { -+ if (true) return; // Paper - replace light engine impl - this.addTask( - pos.x, - pos.z, -@@ -115,6 +274,7 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - - @Override - public void queueSectionData(LightLayer lightType, SectionPos pos, @Nullable DataLayer nibbles) { -+ if (true) return; // Paper - replace light engine impl - this.addTask( - pos.x(), - pos.z(), -@@ -139,12 +299,14 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - - @Override - public void retainData(ChunkPos pos, boolean retainData) { -+ if (true) return; // Paper - replace light engine impl - this.addTask( - pos.x, pos.z, () -> 0, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> super.retainData(pos, retainData), () -> "retainData " + pos) - ); - } - - public CompletableFuture initializeLight(ChunkAccess chunk, boolean bl) { -+ if (true) return CompletableFuture.completedFuture(chunk); // Paper - replace light engine impl - ChunkPos chunkPos = chunk.getPos(); - this.addTask(chunkPos.x, chunkPos.z, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> { - LevelChunkSection[] levelChunkSections = chunk.getSections(); -@@ -165,6 +327,37 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - } - - public CompletableFuture lightChunk(ChunkAccess chunk, boolean excludeBlocks) { -+ // Paper start - replace light engine impl -+ if (true) { -+ boolean lit = excludeBlocks; -+ final ChunkPos chunkPos = chunk.getPos(); -+ -+ return CompletableFuture.supplyAsync(() -> { -+ final Boolean[] emptySections = StarLightEngine.getEmptySectionsForChunk(chunk); -+ if (!lit) { -+ chunk.setLightCorrect(false); -+ this.theLightEngine.lightChunk(chunk, emptySections); -+ chunk.setLightCorrect(true); -+ } else { -+ this.theLightEngine.forceLoadInChunk(chunk, emptySections); -+ // can't really force the chunk to be edged checked, as we need neighbouring chunks - but we don't have -+ // them, so if it's not loaded then i guess we can't do edge checks. later loads of the chunk should -+ // catch what we miss here. -+ this.theLightEngine.checkChunkEdges(chunkPos.x, chunkPos.z); -+ } -+ -+ this.chunkMap.releaseLightTicket(chunkPos); -+ return chunk; -+ }, (runnable) -> { -+ this.theLightEngine.scheduleChunkLight(chunkPos, runnable); -+ this.tryScheduleUpdate(); -+ }).whenComplete((final ChunkAccess c, final Throwable throwable) -> { -+ if (throwable != null) { -+ LOGGER.error("Failed to light chunk " + chunkPos, throwable); -+ } -+ }); -+ } -+ // Paper end - replace light engine impl - ChunkPos chunkPos = chunk.getPos(); - chunk.setLightCorrect(false); - this.addTask(chunkPos.x, chunkPos.z, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> { -@@ -180,7 +373,7 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - } - - public void tryScheduleUpdate() { -- if ((!this.lightTasks.isEmpty() || super.hasLightWork()) && this.scheduled.compareAndSet(false, true)) { -+ if (this.hasLightWork() && this.scheduled.compareAndSet(false, true)) { // Paper // Paper - rewrite light engine - this.taskMailbox.tell(() -> { - this.runUpdate(); - this.scheduled.set(false); -@@ -201,7 +394,7 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - } - - objectListIterator.back(j); -- super.runLightUpdates(); -+ this.theLightEngine.propagateChanges(); // Paper - rewrite light engine - - for (int var5 = 0; objectListIterator.hasNext() && var5 < i; var5++) { - Pair pair2 = objectListIterator.next(); -diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java -index 0d536d72ac918fbd403397ff369d10143ee9c204..6051e5f272838ef23276a90e21c2fc821ca155d1 100644 ---- a/src/main/java/net/minecraft/server/level/TicketType.java -+++ b/src/main/java/net/minecraft/server/level/TicketType.java -@@ -26,6 +26,7 @@ public class TicketType { - public static final TicketType UNKNOWN = TicketType.create("unknown", Comparator.comparingLong(ChunkPos::toLong), 1); - public static final TicketType PLUGIN = TicketType.create("plugin", (a, b) -> 0); // CraftBukkit - public static final TicketType PLUGIN_TICKET = TicketType.create("plugin_ticket", (plugin1, plugin2) -> plugin1.getClass().getName().compareTo(plugin2.getClass().getName())); // CraftBukkit -+ public static final TicketType CHUNK_RELIGHT = create("light_update", Long::compareTo); // Paper - ensure chunks stay loaded for lighting - - public static TicketType create(String name, Comparator argumentComparator) { - return new TicketType<>(name, argumentComparator, 0L); -diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java -index 386fbf79afe91af445f54aeab7d1296d1407a4d8..abbd4140cb4478a34a5185d8555f83d96c04d468 100644 ---- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java -+++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java -@@ -109,6 +109,27 @@ public class WorldGenRegion implements WorldGenLevel { - } - } - -+ // Paper start - starlight -+ @Override -+ public int getBrightness(final net.minecraft.world.level.LightLayer lightLayer, final BlockPos blockPos) { -+ final ChunkAccess chunk = this.getChunk(blockPos.getX() >> 4, blockPos.getZ() >> 4); -+ if (!chunk.isLightCorrect()) { -+ return 0; -+ } -+ return this.getLightEngine().getLayerListener(lightLayer).getLightValue(blockPos); -+ } -+ -+ -+ @Override -+ public int getRawBrightness(final BlockPos blockPos, final int subtract) { -+ final ChunkAccess chunk = this.getChunk(blockPos.getX() >> 4, blockPos.getZ() >> 4); -+ if (!chunk.isLightCorrect()) { -+ return 0; -+ } -+ return this.getLightEngine().getRawBrightness(blockPos, subtract); -+ } -+ // Paper end - starlight -+ - public boolean isOldChunkAround(ChunkPos chunkPos, int checkRadius) { - return this.level.getChunkSource().chunkMap.isOldChunkAround(chunkPos, checkRadius); - } -diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -index f87d9cb38caf3bf92fd32f2118f76799ede418db..c7da359c525522b55763e594a1db0c26a026b73f 100644 ---- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -+++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -@@ -812,6 +812,7 @@ public abstract class BlockBehaviour implements FeatureElement { - this.spawnTerrainParticles = blockbase_info.spawnTerrainParticles; - this.instrument = blockbase_info.instrument; - this.replaceable = blockbase_info.replaceable; -+ this.conditionallyFullOpaque = this.canOcclude & this.useShapeForLightOcclusion; // Paper - } - // Paper start - Perf: impl cached craft block data, lazy load to fix issue with loading at the wrong time - private org.bukkit.craftbukkit.block.data.CraftBlockData cachedCraftBlockData; -@@ -848,6 +849,18 @@ public abstract class BlockBehaviour implements FeatureElement { - return this.shapeExceedsCube; - } - // Paper end -+ // Paper start - starlight -+ protected int opacityIfCached = -1; -+ // ret -1 if opacity is dynamic, or -1 if the block is conditionally full opaque, else return opacity in [0, 15] -+ public final int getOpacityIfCached() { -+ return this.opacityIfCached; -+ } -+ -+ protected final boolean conditionallyFullOpaque; -+ public final boolean isConditionallyFullOpaque() { -+ return this.conditionallyFullOpaque; -+ } -+ // Paper end - starlight - - public void initCache() { - this.fluidState = ((Block) this.owner).getFluidState(this.asState()); -@@ -856,6 +869,7 @@ public abstract class BlockBehaviour implements FeatureElement { - this.cache = new BlockBehaviour.BlockStateBase.Cache(this.asState()); - } - this.shapeExceedsCube = this.cache == null || this.cache.largeCollisionShape; // Paper - moved from actual method to here -+ this.opacityIfCached = this.cache == null || this.isConditionallyFullOpaque() ? -1 : this.cache.lightBlock; // Paper - starlight - cache opacity for light - - this.legacySolid = this.calculateSolid(); - } -diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -index f4e3bd2ae4f63e6d3d25463a3635b8f89fecc068..1f8c72b6c7d8683d67880fa175843c73b3d39b78 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -@@ -77,7 +77,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom - @Nullable - protected BlendingData blendingData; - public final Map heightmaps = Maps.newEnumMap(Heightmap.Types.class); -- protected ChunkSkyLightSources skyLightSources; -+ // Paper - starlight - remove skyLightSources - private final Map structureStarts = Maps.newHashMap(); - private final Map structuresRefences = Maps.newHashMap(); - protected final Map pendingBlockEntities = Maps.newHashMap(); -@@ -89,8 +89,55 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom - private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry(); - public org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer(ChunkAccess.DATA_TYPE_REGISTRY); - // CraftBukkit end -+ // Paper start - rewrite light engine -+ private volatile ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] blockNibbles; -+ -+ private volatile ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] skyNibbles; -+ -+ private volatile boolean[] skyEmptinessMap; -+ -+ private volatile boolean[] blockEmptinessMap; -+ -+ public ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] getBlockNibbles() { -+ return this.blockNibbles; -+ } -+ -+ public void setBlockNibbles(final ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] nibbles) { -+ this.blockNibbles = nibbles; -+ } -+ -+ public ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] getSkyNibbles() { -+ return this.skyNibbles; -+ } -+ -+ public void setSkyNibbles(final ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] nibbles) { -+ this.skyNibbles = nibbles; -+ } -+ -+ public boolean[] getSkyEmptinessMap() { -+ return this.skyEmptinessMap; -+ } -+ -+ public void setSkyEmptinessMap(final boolean[] emptinessMap) { -+ this.skyEmptinessMap = emptinessMap; -+ } -+ -+ public boolean[] getBlockEmptinessMap() { -+ return this.blockEmptinessMap; -+ } -+ -+ public void setBlockEmptinessMap(final boolean[] emptinessMap) { -+ this.blockEmptinessMap = emptinessMap; -+ } -+ // Paper end - rewrite light engine - - public ChunkAccess(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor heightLimitView, Registry biomeRegistry, long inhabitedTime, @Nullable LevelChunkSection[] sectionArray, @Nullable BlendingData blendingData) { -+ // Paper start - rewrite light engine -+ if (!(this instanceof ImposterProtoChunk)) { -+ this.setBlockNibbles(ca.spottedleaf.starlight.common.light.StarLightEngine.getFilledEmptyLight(heightLimitView)); -+ this.setSkyNibbles(ca.spottedleaf.starlight.common.light.StarLightEngine.getFilledEmptyLight(heightLimitView)); -+ } -+ // Paper end - rewrite light engine - this.locX = pos.x; this.locZ = pos.z; // Paper - reduce need for field lookups - this.chunkPos = pos; this.coordinateKey = ChunkPos.asLong(locX, locZ); // Paper - cache long key - this.upgradeData = upgradeData; -@@ -99,7 +146,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom - this.inhabitedTime = inhabitedTime; - this.postProcessing = new ShortList[heightLimitView.getSectionsCount()]; - this.blendingData = blendingData; -- this.skyLightSources = new ChunkSkyLightSources(heightLimitView); -+ // Paper - starlight - remove skyLightSources - if (sectionArray != null) { - if (this.sections.length == sectionArray.length) { - System.arraycopy(sectionArray, 0, this.sections, 0, this.sections.length); -@@ -510,12 +557,12 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom - } - - public void initializeLightSources() { -- this.skyLightSources.fillFrom(this); -+ // Paper - starlight - remove skyLightSources - } - - @Override - public ChunkSkyLightSources getSkyLightSources() { -- return this.skyLightSources; -+ return null; // Paper - starlight - remove skyLightSources - } - - public static record TicksToSave(SerializableTickContainer blocks, SerializableTickContainer fluids) { -diff --git a/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java -index 2ee1658532cb00d7bcd1d11e03f19d21ca7f2a9e..ac754827172a4de600d0a57a7d11853481a2dbf2 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java -+++ b/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java -@@ -21,6 +21,40 @@ public class EmptyLevelChunk extends LevelChunk { - this.biome = biomeEntry; - } - -+ // Paper start - starlight -+ @Override -+ public ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] getBlockNibbles() { -+ return ca.spottedleaf.starlight.common.light.StarLightEngine.getFilledEmptyLight(this.getLevel()); -+ } -+ -+ @Override -+ public void setBlockNibbles(final ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] nibbles) {} -+ -+ @Override -+ public ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] getSkyNibbles() { -+ return ca.spottedleaf.starlight.common.light.StarLightEngine.getFilledEmptyLight(this.getLevel()); -+ } -+ -+ @Override -+ public void setSkyNibbles(final ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] nibbles) {} -+ -+ @Override -+ public boolean[] getSkyEmptinessMap() { -+ return null; -+ } -+ -+ @Override -+ public void setSkyEmptinessMap(final boolean[] emptinessMap) {} -+ -+ @Override -+ public boolean[] getBlockEmptinessMap() { -+ return null; -+ } -+ -+ @Override -+ public void setBlockEmptinessMap(final boolean[] emptinessMap) {} -+ // Paper end - starlight -+ - @Override - public BlockState getBlockState(BlockPos pos) { - return Blocks.VOID_AIR.defaultBlockState(); -diff --git a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java -index 2953e93965aa688be8fc1620580701ba0c9d907e..aa5dee839d4c0dbc3c2abee9b501ec250c575cb3 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java -+++ b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java -@@ -47,6 +47,48 @@ public class ImposterProtoChunk extends ProtoChunk { - this.allowWrites = propagateToWrapped; - } - -+ // Paper start - rewrite light engine -+ @Override -+ public ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] getBlockNibbles() { -+ return this.wrapped.getBlockNibbles(); -+ } -+ -+ @Override -+ public void setBlockNibbles(final ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] nibbles) { -+ this.wrapped.setBlockNibbles(nibbles); -+ } -+ -+ @Override -+ public ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] getSkyNibbles() { -+ return this.wrapped.getSkyNibbles(); -+ } -+ -+ @Override -+ public void setSkyNibbles(final ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] nibbles) { -+ this.wrapped.setSkyNibbles(nibbles); -+ } -+ -+ @Override -+ public boolean[] getSkyEmptinessMap() { -+ return this.wrapped.getSkyEmptinessMap(); -+ } -+ -+ @Override -+ public void setSkyEmptinessMap(final boolean[] emptinessMap) { -+ this.wrapped.setSkyEmptinessMap(emptinessMap); -+ } -+ -+ @Override -+ public boolean[] getBlockEmptinessMap() { -+ return this.wrapped.getBlockEmptinessMap(); -+ } -+ -+ @Override -+ public void setBlockEmptinessMap(final boolean[] emptinessMap) { -+ this.wrapped.setBlockEmptinessMap(emptinessMap); -+ } -+ // Paper end - rewrite light engine -+ - @Nullable - @Override - public BlockEntity getBlockEntity(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 8de6ad8b131061b2dae440dff71e2e6e7af2de39..bac191f92ea3735df19c68d5568c2c7962c8680f 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -222,6 +222,12 @@ public class LevelChunk extends ChunkAccess { - - public LevelChunk(ServerLevel world, ProtoChunk protoChunk, @Nullable LevelChunk.PostLoadProcessor entityLoader) { - this(world, protoChunk.getPos(), protoChunk.getUpgradeData(), protoChunk.unpackBlockTicks(), protoChunk.unpackFluidTicks(), protoChunk.getInhabitedTime(), protoChunk.getSections(), entityLoader, protoChunk.getBlendingData()); -+ // Paper start - rewrite light engine -+ this.setBlockNibbles(protoChunk.getBlockNibbles()); -+ this.setSkyNibbles(protoChunk.getSkyNibbles()); -+ this.setSkyEmptinessMap(protoChunk.getSkyEmptinessMap()); -+ this.setBlockEmptinessMap(protoChunk.getBlockEmptinessMap()); -+ // Paper end - rewrite light engine - Iterator iterator = protoChunk.getBlockEntities().values().iterator(); - - while (iterator.hasNext()) { -@@ -248,7 +254,7 @@ public class LevelChunk extends ChunkAccess { - } - } - -- this.skyLightSources = protoChunk.skyLightSources; -+ // Paper - starlight - remove skyLightSources - this.setLightCorrect(protoChunk.isLightCorrect()); - this.unsaved = true; - this.needsDecoration = true; // CraftBukkit -@@ -437,7 +443,7 @@ public class LevelChunk extends ChunkAccess { - ProfilerFiller gameprofilerfiller = this.level.getProfiler(); - - gameprofilerfiller.push("updateSkyLightSources"); -- this.skyLightSources.update(this, j, i, l); -+ // Paper - starlight - remove skyLightSources - gameprofilerfiller.popPush("queueCheckLight"); - this.level.getChunkSource().getLightEngine().checkBlock(blockposition); - gameprofilerfiller.pop(); -diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -index 2fa0097a9374a89177e4f1068d1bfed30b8ff122..fa9df6ebcd90d4e9e5836a37212b1f60665783b1 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -@@ -155,7 +155,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - return this.get(this.strategy.getIndex(x, y, z)); - } - -- protected T get(int index) { -+ public T get(int index) { // Paper - public - PalettedContainer.Data data = this.data; - return data.palette.valueFor(data.storage.get(index)); - } -diff --git a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java -index bcc70883d23d38c408130ffe778205e371ff4e8a..576ae0cb138b265c8a3995de7b5ebc827d50949d 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java -+++ b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java -@@ -143,7 +143,7 @@ public class ProtoChunk extends ChunkAccess { - } - - if (LightEngine.hasDifferentLightProperties(this, pos, blockState, state)) { -- this.skyLightSources.update(this, m, j, o); -+ // Paper - starlight - remove skyLightSources - this.lightEngine.checkBlock(pos); - } - } -diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java -index ae992aeb8b836e8c2e5bab338ae46cc31c317245..95318092f8281d98132d1d3ceb4a5c36cf32eb05 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java -+++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java -@@ -117,6 +117,18 @@ public class ChunkStatus { - private final ChunkType chunkType; - private final EnumSet heightmapsAfter; - -+ // Paper start - starlight -+ public static ChunkStatus getStatus(String name) { -+ try { -+ // We need this otherwise we return EMPTY for invalid names -+ ResourceLocation key = new ResourceLocation(name); -+ return BuiltInRegistries.CHUNK_STATUS.getOptional(key).orElse(null); -+ } catch (Exception ex) { -+ return null; // invalid name -+ } -+ } -+ // Paper end - starlight -+ - private static ChunkStatus register( - String id, - @Nullable ChunkStatus previous, -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index 88f0aca2da0e14ed5ec0513944fa0ba28b73b5d1..01d6b8683a9fa30d05b03ebfef8ee2dca4e83a56 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -@@ -90,6 +90,14 @@ public class ChunkSerializer { - private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().getDataVersion().getVersion(); - private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion"); - // Paper end - Do not let the server load chunks from newer versions -+ // Paper start - replace light engine impl -+ private static final int STARLIGHT_LIGHT_VERSION = 9; -+ -+ private static final String BLOCKLIGHT_STATE_TAG = "starlight.blocklight_state"; -+ private static final String SKYLIGHT_STATE_TAG = "starlight.skylight_state"; -+ private static final String STARLIGHT_VERSION_TAG = "starlight.light_version"; -+ // Paper end - replace light engine impl -+ - public ChunkSerializer() {} - - // Paper start - guard against serializing mismatching coordinates -@@ -121,19 +129,26 @@ public class ChunkSerializer { - } - - UpgradeData chunkconverter = nbt.contains("UpgradeData", 10) ? new UpgradeData(nbt.getCompound("UpgradeData"), world) : UpgradeData.EMPTY; -- boolean flag = nbt.getBoolean("isLightOn"); -+ boolean flag = getStatus(nbt) != null && getStatus(nbt).isOrAfter(ChunkStatus.LIGHT) && nbt.get("isLightOn") != null && nbt.getInt(STARLIGHT_VERSION_TAG) == STARLIGHT_LIGHT_VERSION; // Paper - ListTag nbttaglist = nbt.getList("sections", 10); - int i = world.getSectionsCount(); - LevelChunkSection[] achunksection = new LevelChunkSection[i]; - boolean flag1 = world.dimensionType().hasSkyLight(); - ServerChunkCache chunkproviderserver = world.getChunkSource(); - LevelLightEngine levellightengine = chunkproviderserver.getLightEngine(); -+ // Paper start -+ ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] blockNibbles = ca.spottedleaf.starlight.common.light.StarLightEngine.getFilledEmptyLight(world); -+ ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] skyNibbles = ca.spottedleaf.starlight.common.light.StarLightEngine.getFilledEmptyLight(world); -+ final int minSection = io.papermc.paper.util.WorldUtil.getMinLightSection(world); -+ final int maxSection = io.papermc.paper.util.WorldUtil.getMaxLightSection(world); -+ boolean canReadSky = world.dimensionType().hasSkyLight(); -+ // Paper end - Registry iregistry = world.registryAccess().registryOrThrow(Registries.BIOME); - Codec>> codec = ChunkSerializer.makeBiomeCodecRW(iregistry); // CraftBukkit - read/write - boolean flag2 = false; - - for (int j = 0; j < nbttaglist.size(); ++j) { -- CompoundTag nbttagcompound1 = nbttaglist.getCompound(j); -+ CompoundTag nbttagcompound1 = nbttaglist.getCompound(j); CompoundTag sectionData = nbttagcompound1; // Paper - byte b0 = nbttagcompound1.getByte("Y"); - int k = world.getSectionIndexFromSectionY(b0); - -@@ -169,19 +184,39 @@ public class ChunkSerializer { - boolean flag3 = nbttagcompound1.contains("BlockLight", 7); - boolean flag4 = flag1 && nbttagcompound1.contains("SkyLight", 7); - -- if (flag3 || flag4) { -- if (!flag2) { -- levellightengine.retainData(chunkPos, true); -- flag2 = true; -- } -- -+ // Paper start - rewrite the light engine -+ if (flag) { -+ try { -+ int y = sectionData.getByte("Y"); -+ // Paper end - rewrite the light engine - if (flag3) { -- levellightengine.queueSectionData(LightLayer.BLOCK, SectionPos.of(chunkPos, b0), new DataLayer(nbttagcompound1.getByteArray("BlockLight"))); -+ // Paper start - rewrite the light engine -+ // this is where our diff is -+ blockNibbles[y - minSection] = new ca.spottedleaf.starlight.common.light.SWMRNibbleArray(sectionData.getByteArray("BlockLight").clone(), sectionData.getInt(BLOCKLIGHT_STATE_TAG)); // clone for data safety -+ } else { -+ blockNibbles[y - minSection] = new ca.spottedleaf.starlight.common.light.SWMRNibbleArray(null, sectionData.getInt(BLOCKLIGHT_STATE_TAG)); -+ // Paper end - rewrite the light engine - } - - if (flag4) { -- levellightengine.queueSectionData(LightLayer.SKY, SectionPos.of(chunkPos, b0), new DataLayer(nbttagcompound1.getByteArray("SkyLight"))); -+ // Paper start - rewrite the light engine -+ // we store under the same key so mod programs editing nbt -+ // can still read the data, hopefully. -+ // however, for compatibility we store chunks as unlit so vanilla -+ // is forced to re-light them if it encounters our data. It's too much of a burden -+ // to try and maintain compatibility with a broken and inferior skylight management system. -+ skyNibbles[y - minSection] = new ca.spottedleaf.starlight.common.light.SWMRNibbleArray(sectionData.getByteArray("SkyLight").clone(), sectionData.getInt(SKYLIGHT_STATE_TAG)); // clone for data safety -+ } else if (flag1) { -+ skyNibbles[y - minSection] = new ca.spottedleaf.starlight.common.light.SWMRNibbleArray(null, sectionData.getInt(SKYLIGHT_STATE_TAG)); -+ // Paper end - rewrite the light engine -+ } -+ -+ // Paper start - rewrite the light engine -+ } catch (Exception ex) { -+ LOGGER.warn("Failed to load light data for chunk " + chunkPos + " in world '" + world.getWorld().getName() + "', light will be regenerated", ex); -+ flag = false; - } -+ // Paper end - rewrite light engine - } - } - -@@ -211,6 +246,8 @@ public class ChunkSerializer { - }, chunkPos); - - object1 = new LevelChunk(world.getLevel(), chunkPos, chunkconverter, levelchunkticks, levelchunkticks1, l, achunksection, ChunkSerializer.postLoadChunk(world, nbt), blendingdata); -+ ((LevelChunk)object1).setBlockNibbles(blockNibbles); // Paper - replace light impl -+ ((LevelChunk)object1).setSkyNibbles(skyNibbles); // Paper - replace light impl - } else { - ProtoChunkTicks protochunkticklist = ProtoChunkTicks.load(nbt.getList("block_ticks", 10), (s) -> { - return BuiltInRegistries.BLOCK.getOptional(ResourceLocation.tryParse(s)); -@@ -219,6 +256,8 @@ public class ChunkSerializer { - return BuiltInRegistries.FLUID.getOptional(ResourceLocation.tryParse(s)); - }, chunkPos); - ProtoChunk protochunk = new ProtoChunk(chunkPos, chunkconverter, achunksection, protochunkticklist, protochunkticklist1, world, iregistry, blendingdata); -+ protochunk.setBlockNibbles(blockNibbles); // Paper - replace light impl -+ protochunk.setSkyNibbles(skyNibbles); // Paper - replace light impl - - object1 = protochunk; - protochunk.setInhabitedTime(l); -@@ -340,6 +379,12 @@ public class ChunkSerializer { - // CraftBukkit end - - public static CompoundTag write(ServerLevel world, ChunkAccess chunk) { -+ // Paper start - rewrite light impl -+ final int minSection = io.papermc.paper.util.WorldUtil.getMinLightSection(world); -+ final int maxSection = io.papermc.paper.util.WorldUtil.getMaxLightSection(world); -+ ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] blockNibbles = chunk.getBlockNibbles(); -+ ca.spottedleaf.starlight.common.light.SWMRNibbleArray[] skyNibbles = chunk.getSkyNibbles(); -+ // Paper end - rewrite light impl - ChunkPos chunkcoordintpair = chunk.getPos(); - CompoundTag nbttagcompound = NbtUtils.addCurrentDataVersion(new CompoundTag()); - -@@ -389,11 +434,14 @@ public class ChunkSerializer { - for (int i = lightenginethreaded.getMinLightSection(); i < lightenginethreaded.getMaxLightSection(); ++i) { - int j = chunk.getSectionIndexFromSectionY(i); - boolean flag1 = j >= 0 && j < achunksection.length; -- DataLayer nibblearray = lightenginethreaded.getLayerListener(LightLayer.BLOCK).getDataLayerData(SectionPos.of(chunkcoordintpair, i)); -- DataLayer nibblearray1 = lightenginethreaded.getLayerListener(LightLayer.SKY).getDataLayerData(SectionPos.of(chunkcoordintpair, i)); -+ // Paper - replace light engine - -- if (flag1 || nibblearray != null || nibblearray1 != null) { -- CompoundTag nbttagcompound1 = new CompoundTag(); -+ // Paper start - replace light engine -+ ca.spottedleaf.starlight.common.light.SWMRNibbleArray.SaveState blockNibble = blockNibbles[i - minSection].getSaveState(); -+ ca.spottedleaf.starlight.common.light.SWMRNibbleArray.SaveState skyNibble = skyNibbles[i - minSection].getSaveState(); -+ if (flag1 || blockNibble != null || skyNibble != null) { -+ // Paper end - replace light engine -+ CompoundTag nbttagcompound1 = new CompoundTag(); CompoundTag section = nbttagcompound1; // Paper - - if (flag1) { - LevelChunkSection chunksection = achunksection[j]; -@@ -402,13 +450,27 @@ public class ChunkSerializer { - nbttagcompound1.put("biomes", (Tag) codec.encodeStart(NbtOps.INSTANCE, chunksection.getBiomes()).getOrThrow()); - } - -- if (nibblearray != null && !nibblearray.isEmpty()) { -- nbttagcompound1.putByteArray("BlockLight", nibblearray.getData()); -+ // Paper start -+ // we store under the same key so mod programs editing nbt -+ // can still read the data, hopefully. -+ // however, for compatibility we store chunks as unlit so vanilla -+ // is forced to re-light them if it encounters our data. It's too much of a burden -+ // to try and maintain compatibility with a broken and inferior skylight management system. -+ -+ if (blockNibble != null) { -+ if (blockNibble.data != null) { -+ section.putByteArray("BlockLight", blockNibble.data); -+ } -+ section.putInt(BLOCKLIGHT_STATE_TAG, blockNibble.state); - } - -- if (nibblearray1 != null && !nibblearray1.isEmpty()) { -- nbttagcompound1.putByteArray("SkyLight", nibblearray1.getData()); -+ if (skyNibble != null) { -+ if (skyNibble.data != null) { -+ section.putByteArray("SkyLight", skyNibble.data); -+ } -+ section.putInt(SKYLIGHT_STATE_TAG, skyNibble.state); - } -+ // Paper end - - if (!nbttagcompound1.isEmpty()) { - nbttagcompound1.putByte("Y", (byte) i); -@@ -419,7 +481,8 @@ public class ChunkSerializer { - - nbttagcompound.put("sections", nbttaglist); - if (flag) { -- nbttagcompound.putBoolean("isLightOn", true); -+ nbttagcompound.putInt(STARLIGHT_VERSION_TAG, STARLIGHT_LIGHT_VERSION); // Paper -+ nbttagcompound.putBoolean("isLightOn", false); // Paper - set to false but still store, this allows us to detect --eraseCache (as eraseCache _removes_) - } - - ListTag nbttaglist1 = new ListTag(); -@@ -493,6 +556,17 @@ public class ChunkSerializer { - })); - } - -+ // Paper start -+ public static @Nullable ChunkStatus getStatus(@Nullable CompoundTag compound) { -+ if (compound == null) { -+ return null; -+ } -+ -+ // Note: Copied from below -+ return ChunkStatus.getStatus(compound.getString("Status")); -+ } -+ // Paper end -+ - public static ChunkType getChunkTypeFromTag(@Nullable CompoundTag nbt) { - return nbt != null ? ChunkStatus.byName(nbt.getString("Status")).getChunkType() : ChunkType.PROTOCHUNK; - } -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 44ed6bd76fb9e81f6c0d99fe46173685dbbfe2a7..7aee9f6b143c89cf8d65ca55eeda808152b4dd26 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -507,12 +507,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { - } - } - -- for (final ChunkPos pos : chunksToRelight) { -- final ChunkAccess chunk = serverChunkCache.getChunk(pos.x, pos.z, false); -- if (chunk != null) { -- serverChunkCache.getLightEngine().lightChunk(chunk, false); -- } -- } -+ serverChunkCache.getLightEngine().relight(chunksToRelight, pos -> {}, relit -> {}); // Paper - Starlight - - return true; - // Paper end - implement regenerate chunk method diff --git a/patches/removed/1.21/0994-Rewrite-chunk-system.patch b/patches/removed/1.21/0994-Rewrite-chunk-system.patch deleted file mode 100644 index 4df84d014cfd..000000000000 --- a/patches/removed/1.21/0994-Rewrite-chunk-system.patch +++ /dev/null @@ -1,21846 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Thu, 11 Mar 2021 02:32:30 -0800 -Subject: [PATCH] Rewrite chunk system - -Rebased patches: - -New player chunk loader system - -Make ChunkStatus.EMPTY not rely on the main thread for completion - -In order to do this, we need to push the POI consistency checks -to a later status. Since FULL is the only other status that -uses the main thread, it can go there. - -The consistency checks are only really for when a desync occurs, -and so that delaying the check only matters when the chunk data -has desync'd. As long as the desync is sorted before the -chunk is full loaded (i.e before setBlock can occur on -a chunk), it should not matter. - -This change is primarily due to behavioural changes -in the chunk task queue brought by region threading - -which is to split the queue into separate regions. As such, -it is required that in order for the sync load to complete -that the region owning the chunk drain and execute the task -while ticking. However, that is not always possible in -region threading. Thus, removing the main thread reliance allows -the chunk to progress without requiring a tick thread. -Specifically, this allows far sync loads (outside of a specific -regions bounds) to occur without issue - namely with structure -searching. - -Increase parallelism for neighbour writing chunk statuses - -Namely, everything after FEATURES. By creating a dependency -chain indicating what chunks are in use, we can safely -schedule completely independent tasks in parallel. This -will allow the chunk system to scale beyond 10 threads -per world. - -Properly cancel chunk load tasks that were not scheduled - -Since the chunk load task was not scheduled, the entity/poi load -task fields will not be set, but the task complete counter -will not be adjusted. Thus, the chunk load task will not complete. - -To resolve this, detect when the entity/poi tasks were not scheduled -and decrement the task complete counter in such cases. - -Mark POI/Entity load tasks as completed before releasing scheduling lock - -It must be marked as completed during that lock hold since the -waiters field is set to null. Thus, any other thread attempting -a cancellation will fail to remove from waiters. Also, any -other thread attempting to cancel may set the completed field -to true which would cause accept() to fail as well. - -Completion was always designed to happen while holding the -scheduling lock to prevent these race conditions. The code -was originally set up to complete while not holding the -scheduling lock to avoid invoking callbacks while holding the -lock, however the access to the completion field was not -considered. - -Resolve this by marking the callback as completed during the -lock, but invoking the accept() function after releasing -the lock. This will prevent any cancellation attempts to be -blocked, and allow the current thread to complete the callback -without any issues. - -Cache whether region files do not exist - -The repeated I/O of creating the directory for the regionfile -or for checking if the file exists can be heavy in -when pushing chunk generation extremely hard - as each chunk gen -request may effectively go through to the I/O thread. - -Use coordinate-based locking to increase chunk system parallelism - -A significant overhead in Folia comes from the chunk system's -locks, the ticket lock and the scheduling lock. The public -test server, which had ~330 players, had signficant performance -problems with these locks: ~80% of the time spent ticking -was _waiting_ for the locks to free. Given that it used -around 15 cores total at peak, this is a complete and utter loss -of potential. - -To address this issue, I have replaced the ticket lock and scheduling -lock with two ReentrantAreaLocks. The ReentrantAreaLock takes a -shift, which is used internally to group positions into sections. -This grouping is neccessary, as the possible radius of area that -needs to be acquired for any given lock usage is up to 64. As such, -the shift is critical to reduce the number of areas required to lock -for any lock operation. Currently, it is set to a shift of 6, which -is identical to the ticket level propagation shift (and, it must be -at least the ticket level propagation shift AND the region shift). - -The chunk system locking changes required a complete rewrite of the -chunk system tick, chunk system unload, and chunk system ticket level -propagation - as all of the previous logic only works with a single -global lock. - -This does introduce two other section shifts: the lock shift, and the -ticket shift. The lock shift is simply what shift the area locks use, -and the ticket shift represents the size of the ticket sections. -Currently, these values are just set to the region shift for simplicity. -However, they are not arbitrary: the lock shift must be at least the size -of the ticket shift and must be at least the size of the region shift. -The ticket shift must also be >= the ceil(log2(max ticket level source)). - -The chunk system's ticket propagator is now global state, instead of -region state. This cleans up the logic for ticket levels significantly, -and removes usage of the region lock in this area, but it also means -that the addition of a ticket no longer creates a region. To alleviate -the side effects of this change, the global tick thread now processes -ticket level updates for each world every tick to guarantee eventual -ticket level processing. The chunk system also provides a hook to -process ticket level changes in a given _section_, so that the -region queue can guarantee that after adding its reference counter -that the region section is created/exists/wont be destroyed. - -The ticket propagator operates by updating the sources in a single ticket -section, and propagating the updates to its 1 radius neighbours. This -allows the ticket updates to occur in parallel or selectively (see above). -Currently, the process ticket level update function operates by -polling from a concurrent queue of sections to update and simply -invoking the single section update logic. This allows the function -to operate completely in parallel, provided the queue is ordered right. -Additionally, this limits the area used in the ticket/scheduling lock -when processing updates, which should massively increase parallelism compared -to before. - -The chunk system ticket addition for expirable ticket types has been modified -to no longer track exact tick deadlines, as this relies on what region the -ticket is in. Instead, the chunk system tracks a map of -lock section -> (chunk coordinate -> expire ticket count) and every ticket -has been changed to have a removeDelay count that is decremented each tick. -Each region searches its own sections to find tickets to try to expire. - -Chunk system unloading has been modified to track unloads by lock section. -The ordering is determined by which section a chunk resides in. -The unload process now removes from unload sections and processes -the full unload stages (1, 2, 3) before moving to the next section, if possible. -This allows the unload logic to only hold one lock section at a time for -each lock, which is a massive parallelism increase. - -In stress testing, these changes lowered the locking overhead to only 5% -from ~70%, which completely fix the original problem as described. - -== AT == -public net.minecraft.server.level.ChunkHolder pos -public net.minecraft.server.level.ChunkMap overworldDataStorage -public-f net.minecraft.world.level.chunk.storage.RegionFileStorage -public net.minecraft.server.level.ChunkMap getPoiManager()Lnet/minecraft/world/entity/ai/village/poi/PoiManager; - -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/lock/ReentrantAreaLock.java b/src/main/java/ca/spottedleaf/concurrentutil/lock/ReentrantAreaLock.java -new file mode 100644 -index 0000000000000000000000000000000000000000..4fd9a0cd8f1e6ae1a97e963dc7731a80bc6fac5b ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/lock/ReentrantAreaLock.java -@@ -0,0 +1,395 @@ -+package ca.spottedleaf.concurrentutil.lock; -+ -+import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; -+import it.unimi.dsi.fastutil.HashCommon; -+import java.util.ArrayList; -+import java.util.List; -+import java.util.concurrent.ConcurrentHashMap; -+import java.util.concurrent.locks.LockSupport; -+ -+public final class ReentrantAreaLock { -+ -+ public final int coordinateShift; -+ -+ // aggressive load factor to reduce contention -+ private final ConcurrentHashMap nodes = new ConcurrentHashMap<>(128, 0.2f); -+ -+ public ReentrantAreaLock(final int coordinateShift) { -+ this.coordinateShift = coordinateShift; -+ } -+ -+ public boolean isHeldByCurrentThread(final int x, final int z) { -+ final Thread currThread = Thread.currentThread(); -+ final int shift = this.coordinateShift; -+ final int sectionX = x >> shift; -+ final int sectionZ = z >> shift; -+ -+ final Coordinate coordinate = new Coordinate(Coordinate.key(sectionX, sectionZ)); -+ final Node node = this.nodes.get(coordinate); -+ -+ return node != null && node.thread == currThread; -+ } -+ -+ public boolean isHeldByCurrentThread(final int centerX, final int centerZ, final int radius) { -+ return this.isHeldByCurrentThread(centerX - radius, centerZ - radius, centerX + radius, centerZ + radius); -+ } -+ -+ public boolean isHeldByCurrentThread(final int fromX, final int fromZ, final int toX, final int toZ) { -+ if (fromX > toX || fromZ > toZ) { -+ throw new IllegalArgumentException(); -+ } -+ -+ final Thread currThread = Thread.currentThread(); -+ final int shift = this.coordinateShift; -+ final int fromSectionX = fromX >> shift; -+ final int fromSectionZ = fromZ >> shift; -+ final int toSectionX = toX >> shift; -+ final int toSectionZ = toZ >> shift; -+ -+ for (int currZ = fromSectionZ; currZ <= toSectionZ; ++currZ) { -+ for (int currX = fromSectionX; currX <= toSectionX; ++currX) { -+ final Coordinate coordinate = new Coordinate(Coordinate.key(currX, currZ)); -+ -+ final Node node = this.nodes.get(coordinate); -+ -+ if (node == null || node.thread != currThread) { -+ return false; -+ } -+ } -+ } -+ -+ return true; -+ } -+ -+ public Node tryLock(final int x, final int z) { -+ return this.tryLock(x, z, x, z); -+ } -+ -+ public Node tryLock(final int centerX, final int centerZ, final int radius) { -+ return this.tryLock(centerX - radius, centerZ - radius, centerX + radius, centerZ + radius); -+ } -+ -+ public Node tryLock(final int fromX, final int fromZ, final int toX, final int toZ) { -+ if (fromX > toX || fromZ > toZ) { -+ throw new IllegalArgumentException(); -+ } -+ -+ final Thread currThread = Thread.currentThread(); -+ final int shift = this.coordinateShift; -+ final int fromSectionX = fromX >> shift; -+ final int fromSectionZ = fromZ >> shift; -+ final int toSectionX = toX >> shift; -+ final int toSectionZ = toZ >> shift; -+ -+ final List areaAffected = new ArrayList<>(); -+ -+ final Node ret = new Node(this, areaAffected, currThread); -+ -+ boolean failed = false; -+ -+ // try to fast acquire area -+ for (int currZ = fromSectionZ; currZ <= toSectionZ; ++currZ) { -+ for (int currX = fromSectionX; currX <= toSectionX; ++currX) { -+ final Coordinate coordinate = new Coordinate(Coordinate.key(currX, currZ)); -+ -+ final Node prev = this.nodes.putIfAbsent(coordinate, ret); -+ -+ if (prev == null) { -+ areaAffected.add(coordinate); -+ continue; -+ } -+ -+ if (prev.thread != currThread) { -+ failed = true; -+ break; -+ } -+ } -+ } -+ -+ if (!failed) { -+ return ret; -+ } -+ -+ // failed, undo logic -+ if (!areaAffected.isEmpty()) { -+ for (int i = 0, len = areaAffected.size(); i < len; ++i) { -+ final Coordinate key = areaAffected.get(i); -+ -+ if (this.nodes.remove(key) != ret) { -+ throw new IllegalStateException(); -+ } -+ } -+ -+ areaAffected.clear(); -+ -+ // since we inserted, we need to drain waiters -+ Thread unpark; -+ while ((unpark = ret.pollOrBlockAdds()) != null) { -+ LockSupport.unpark(unpark); -+ } -+ } -+ -+ return null; -+ } -+ -+ public Node lock(final int x, final int z) { -+ final Thread currThread = Thread.currentThread(); -+ final int shift = this.coordinateShift; -+ final int sectionX = x >> shift; -+ final int sectionZ = z >> shift; -+ -+ final List areaAffected = new ArrayList<>(1); -+ -+ final Node ret = new Node(this, areaAffected, currThread); -+ final Coordinate coordinate = new Coordinate(Coordinate.key(sectionX, sectionZ)); -+ -+ for (long failures = 0L;;) { -+ final Node park; -+ -+ // try to fast acquire area -+ { -+ final Node prev = this.nodes.putIfAbsent(coordinate, ret); -+ -+ if (prev == null) { -+ areaAffected.add(coordinate); -+ return ret; -+ } else if (prev.thread != currThread) { -+ park = prev; -+ } else { -+ // only one node we would want to acquire, and it's owned by this thread already -+ return ret; -+ } -+ } -+ -+ ++failures; -+ -+ if (failures > 128L && park.add(currThread)) { -+ LockSupport.park(); -+ } else { -+ // high contention, spin wait -+ if (failures < 128L) { -+ for (long i = 0; i < failures; ++i) { -+ Thread.onSpinWait(); -+ } -+ failures = failures << 1; -+ } else if (failures < 1_200L) { -+ LockSupport.parkNanos(1_000L); -+ failures = failures + 1L; -+ } else { // scale 0.1ms (100us) per failure -+ Thread.yield(); -+ LockSupport.parkNanos(100_000L * failures); -+ failures = failures + 1L; -+ } -+ } -+ } -+ } -+ -+ public Node lock(final int centerX, final int centerZ, final int radius) { -+ return this.lock(centerX - radius, centerZ - radius, centerX + radius, centerZ + radius); -+ } -+ -+ public Node lock(final int fromX, final int fromZ, final int toX, final int toZ) { -+ if (fromX > toX || fromZ > toZ) { -+ throw new IllegalArgumentException(); -+ } -+ -+ final Thread currThread = Thread.currentThread(); -+ final int shift = this.coordinateShift; -+ final int fromSectionX = fromX >> shift; -+ final int fromSectionZ = fromZ >> shift; -+ final int toSectionX = toX >> shift; -+ final int toSectionZ = toZ >> shift; -+ -+ if (((fromSectionX ^ toSectionX) | (fromSectionZ ^ toSectionZ)) == 0) { -+ return this.lock(fromX, fromZ); -+ } -+ -+ final List areaAffected = new ArrayList<>(); -+ -+ final Node ret = new Node(this, areaAffected, currThread); -+ -+ for (long failures = 0L;;) { -+ Node park = null; -+ boolean addedToArea = false; -+ boolean alreadyOwned = false; -+ boolean allOwned = true; -+ -+ // try to fast acquire area -+ for (int currZ = fromSectionZ; currZ <= toSectionZ; ++currZ) { -+ for (int currX = fromSectionX; currX <= toSectionX; ++currX) { -+ final Coordinate coordinate = new Coordinate(Coordinate.key(currX, currZ)); -+ -+ final Node prev = this.nodes.putIfAbsent(coordinate, ret); -+ -+ if (prev == null) { -+ addedToArea = true; -+ allOwned = false; -+ areaAffected.add(coordinate); -+ continue; -+ } -+ -+ if (prev.thread != currThread) { -+ park = prev; -+ alreadyOwned = true; -+ break; -+ } -+ } -+ } -+ -+ if (park == null) { -+ if (alreadyOwned && !allOwned) { -+ throw new IllegalStateException("Improper lock usage: Should never acquire intersecting areas"); -+ } -+ return ret; -+ } -+ -+ // failed, undo logic -+ if (addedToArea) { -+ for (int i = 0, len = areaAffected.size(); i < len; ++i) { -+ final Coordinate key = areaAffected.get(i); -+ -+ if (this.nodes.remove(key) != ret) { -+ throw new IllegalStateException(); -+ } -+ } -+ -+ areaAffected.clear(); -+ -+ // since we inserted, we need to drain waiters -+ Thread unpark; -+ while ((unpark = ret.pollOrBlockAdds()) != null) { -+ LockSupport.unpark(unpark); -+ } -+ } -+ -+ ++failures; -+ -+ if (failures > 128L && park.add(currThread)) { -+ LockSupport.park(park); -+ } else { -+ // high contention, spin wait -+ if (failures < 128L) { -+ for (long i = 0; i < failures; ++i) { -+ Thread.onSpinWait(); -+ } -+ failures = failures << 1; -+ } else if (failures < 1_200L) { -+ LockSupport.parkNanos(1_000L); -+ failures = failures + 1L; -+ } else { // scale 0.1ms (100us) per failure -+ Thread.yield(); -+ LockSupport.parkNanos(100_000L * failures); -+ failures = failures + 1L; -+ } -+ } -+ -+ if (addedToArea) { -+ // try again, so we need to allow adds so that other threads can properly block on us -+ ret.allowAdds(); -+ } -+ } -+ } -+ -+ public void unlock(final Node node) { -+ if (node.lock != this) { -+ throw new IllegalStateException("Unlock target lock mismatch"); -+ } -+ -+ final List areaAffected = node.areaAffected; -+ -+ if (areaAffected.isEmpty()) { -+ // here we are not in the node map, and so do not need to remove from the node map or unblock any waiters -+ return; -+ } -+ -+ // remove from node map; allowing other threads to lock -+ for (int i = 0, len = areaAffected.size(); i < len; ++i) { -+ final Coordinate coordinate = areaAffected.get(i); -+ if (this.nodes.remove(coordinate) != node) { -+ throw new IllegalStateException(); -+ } -+ } -+ -+ Thread unpark; -+ while ((unpark = node.pollOrBlockAdds()) != null) { -+ LockSupport.unpark(unpark); -+ } -+ } -+ -+ public static final class Node extends MultiThreadedQueue { -+ -+ private final ReentrantAreaLock lock; -+ private final List areaAffected; -+ private final Thread thread; -+ //private final Throwable WHO_CREATED_MY_ASS = new Throwable(); -+ -+ private Node(final ReentrantAreaLock lock, final List areaAffected, final Thread thread) { -+ this.lock = lock; -+ this.areaAffected = areaAffected; -+ this.thread = thread; -+ } -+ -+ @Override -+ public String toString() { -+ return "Node{" + -+ "areaAffected=" + this.areaAffected + -+ ", thread=" + this.thread + -+ '}'; -+ } -+ } -+ -+ private static final class Coordinate implements Comparable { -+ -+ public final long key; -+ -+ public Coordinate(final long key) { -+ this.key = key; -+ } -+ -+ public Coordinate(final int x, final int z) { -+ this.key = key(x, z); -+ } -+ -+ public static long key(final int x, final int z) { -+ return ((long)z << 32) | (x & 0xFFFFFFFFL); -+ } -+ -+ public static int x(final long key) { -+ return (int)key; -+ } -+ -+ public static int z(final long key) { -+ return (int)(key >>> 32); -+ } -+ -+ @Override -+ public int hashCode() { -+ return (int)HashCommon.mix(this.key); -+ } -+ -+ @Override -+ public boolean equals(final Object obj) { -+ if (this == obj) { -+ return true; -+ } -+ -+ if (!(obj instanceof Coordinate other)) { -+ return false; -+ } -+ -+ return this.key == other.key; -+ } -+ -+ // This class is intended for HashMap/ConcurrentHashMap usage, which do treeify bin nodes if the chain -+ // is too large. So we should implement compareTo to help. -+ @Override -+ public int compareTo(final Coordinate other) { -+ return Long.compare(this.key, other.key); -+ } -+ -+ @Override -+ public String toString() { -+ return "[" + x(this.key) + "," + z(this.key) + "]"; -+ } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/concurrentutil/lock/SyncReentrantAreaLock.java b/src/main/java/ca/spottedleaf/concurrentutil/lock/SyncReentrantAreaLock.java -new file mode 100644 -index 0000000000000000000000000000000000000000..64b5803d002b2968841a5ddee987f98b72964e87 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/concurrentutil/lock/SyncReentrantAreaLock.java -@@ -0,0 +1,217 @@ -+package ca.spottedleaf.concurrentutil.lock; -+ -+import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; -+import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; -+import it.unimi.dsi.fastutil.longs.LongArrayList; -+import java.util.concurrent.locks.LockSupport; -+ -+// not concurrent, unlike ReentrantAreaLock -+// no incorrect lock usage detection (acquiring intersecting areas) -+// this class is nothing more than a performance reference for ReentrantAreaLock -+public final class SyncReentrantAreaLock { -+ -+ private final int coordinateShift; -+ -+ // aggressive load factor to reduce contention -+ private final Long2ReferenceOpenHashMap nodes = new Long2ReferenceOpenHashMap<>(128, 0.2f); -+ -+ public SyncReentrantAreaLock(final int coordinateShift) { -+ this.coordinateShift = coordinateShift; -+ } -+ -+ private static long key(final int x, final int z) { -+ return ((long)z << 32) | (x & 0xFFFFFFFFL); -+ } -+ -+ public Node lock(final int x, final int z) { -+ final Thread currThread = Thread.currentThread(); -+ final int shift = this.coordinateShift; -+ final int sectionX = x >> shift; -+ final int sectionZ = z >> shift; -+ -+ final LongArrayList areaAffected = new LongArrayList(); -+ -+ final Node ret = new Node(this, areaAffected, currThread); -+ -+ final long coordinate = key(sectionX, sectionZ); -+ -+ for (long failures = 0L;;) { -+ final Node park; -+ -+ synchronized (this) { -+ // try to fast acquire area -+ final Node prev = this.nodes.putIfAbsent(coordinate, ret); -+ -+ if (prev == null) { -+ areaAffected.add(coordinate); -+ return ret; -+ } else if (prev.thread != currThread) { -+ park = prev; -+ } else { -+ // only one node we would want to acquire, and it's owned by this thread already -+ return ret; -+ } -+ } -+ -+ ++failures; -+ -+ if (failures > 128L && park.add(currThread)) { -+ LockSupport.park(); -+ } else { -+ // high contention, spin wait -+ if (failures < 128L) { -+ for (long i = 0; i < failures; ++i) { -+ Thread.onSpinWait(); -+ } -+ failures = failures << 1; -+ } else if (failures < 1_200L) { -+ LockSupport.parkNanos(1_000L); -+ failures = failures + 1L; -+ } else { // scale 0.1ms (100us) per failure -+ Thread.yield(); -+ LockSupport.parkNanos(100_000L * failures); -+ failures = failures + 1L; -+ } -+ } -+ } -+ } -+ -+ public Node lock(final int centerX, final int centerZ, final int radius) { -+ return this.lock(centerX - radius, centerZ - radius, centerX + radius, centerZ + radius); -+ } -+ -+ public Node lock(final int fromX, final int fromZ, final int toX, final int toZ) { -+ if (fromX > toX || fromZ > toZ) { -+ throw new IllegalArgumentException(); -+ } -+ -+ final Thread currThread = Thread.currentThread(); -+ final int shift = this.coordinateShift; -+ final int fromSectionX = fromX >> shift; -+ final int fromSectionZ = fromZ >> shift; -+ final int toSectionX = toX >> shift; -+ final int toSectionZ = toZ >> shift; -+ -+ final LongArrayList areaAffected = new LongArrayList(); -+ -+ final Node ret = new Node(this, areaAffected, currThread); -+ -+ for (long failures = 0L;;) { -+ Node park = null; -+ boolean addedToArea = false; -+ -+ synchronized (this) { -+ // try to fast acquire area -+ for (int currZ = fromSectionZ; currZ <= toSectionZ; ++currZ) { -+ for (int currX = fromSectionX; currX <= toSectionX; ++currX) { -+ final long coordinate = key(currX, currZ); -+ -+ final Node prev = this.nodes.putIfAbsent(coordinate, ret); -+ -+ if (prev == null) { -+ addedToArea = true; -+ areaAffected.add(coordinate); -+ continue; -+ } -+ -+ if (prev.thread != currThread) { -+ park = prev; -+ break; -+ } -+ } -+ } -+ -+ if (park == null) { -+ return ret; -+ } -+ -+ // failed, undo logic -+ if (!areaAffected.isEmpty()) { -+ for (int i = 0, len = areaAffected.size(); i < len; ++i) { -+ final long key = areaAffected.getLong(i); -+ -+ if (!this.nodes.remove(key, ret)) { -+ throw new IllegalStateException(); -+ } -+ } -+ } -+ } -+ -+ if (addedToArea) { -+ areaAffected.clear(); -+ // since we inserted, we need to drain waiters -+ Thread unpark; -+ while ((unpark = ret.pollOrBlockAdds()) != null) { -+ LockSupport.unpark(unpark); -+ } -+ } -+ -+ ++failures; -+ -+ if (failures > 128L && park.add(currThread)) { -+ LockSupport.park(); -+ } else { -+ // high contention, spin wait -+ if (failures < 128L) { -+ for (long i = 0; i < failures; ++i) { -+ Thread.onSpinWait(); -+ } -+ failures = failures << 1; -+ } else if (failures < 1_200L) { -+ LockSupport.parkNanos(1_000L); -+ failures = failures + 1L; -+ } else { // scale 0.1ms (100us) per failure -+ Thread.yield(); -+ LockSupport.parkNanos(100_000L * failures); -+ failures = failures + 1L; -+ } -+ } -+ -+ if (addedToArea) { -+ // try again, so we need to allow adds so that other threads can properly block on us -+ ret.allowAdds(); -+ } -+ } -+ } -+ -+ public void unlock(final Node node) { -+ if (node.lock != this) { -+ throw new IllegalStateException("Unlock target lock mismatch"); -+ } -+ -+ final LongArrayList areaAffected = node.areaAffected; -+ -+ if (areaAffected.isEmpty()) { -+ // here we are not in the node map, and so do not need to remove from the node map or unblock any waiters -+ return; -+ } -+ -+ // remove from node map; allowing other threads to lock -+ synchronized (this) { -+ for (int i = 0, len = areaAffected.size(); i < len; ++i) { -+ final long coordinate = areaAffected.getLong(i); -+ if (!this.nodes.remove(coordinate, node)) { -+ throw new IllegalStateException(); -+ } -+ } -+ } -+ -+ Thread unpark; -+ while ((unpark = node.pollOrBlockAdds()) != null) { -+ LockSupport.unpark(unpark); -+ } -+ } -+ -+ public static final class Node extends MultiThreadedQueue { -+ -+ private final SyncReentrantAreaLock lock; -+ private final LongArrayList areaAffected; -+ private final Thread thread; -+ -+ private Node(final SyncReentrantAreaLock lock, final LongArrayList areaAffected, final Thread thread) { -+ this.lock = lock; -+ this.areaAffected = areaAffected; -+ this.thread = thread; -+ } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/starlight/common/light/StarLightInterface.java b/src/main/java/ca/spottedleaf/starlight/common/light/StarLightInterface.java -index e0338db4d6fa359029ed5edeacc3646aa98701f5..c03dbb4a74d00d794be4139f0f7c4b5ff1b01d38 100644 ---- a/src/main/java/ca/spottedleaf/starlight/common/light/StarLightInterface.java -+++ b/src/main/java/ca/spottedleaf/starlight/common/light/StarLightInterface.java -@@ -41,14 +41,14 @@ public final class StarLightInterface { - protected final ArrayDeque cachedSkyPropagators; - protected final ArrayDeque cachedBlockPropagators; - -- protected final LightQueue lightQueue = new LightQueue(this); -+ public final io.papermc.paper.chunk.system.light.LightQueue lightQueue; // Paper - replace light queue - - protected final LayerLightEventListener skyReader; - protected final LayerLightEventListener blockReader; - protected final boolean isClientSide; - -- protected final int minSection; -- protected final int maxSection; -+ public final int minSection; // Paper - public -+ public final int maxSection; // Paper - public - protected final int minLightSection; - protected final int maxLightSection; - -@@ -182,6 +182,7 @@ public final class StarLightInterface { - StarLightInterface.this.sectionChange(pos, notReady); - } - }; -+ this.lightQueue = new io.papermc.paper.chunk.system.light.LightQueue(this); // Paper - replace light queue - } - - public boolean hasSkyLight() { -@@ -333,7 +334,7 @@ public final class StarLightInterface { - return this.lightAccess; - } - -- protected final SkyStarLightEngine getSkyLightEngine() { -+ public final SkyStarLightEngine getSkyLightEngine() { // Paper - public - if (this.cachedSkyPropagators == null) { - return null; - } -@@ -348,7 +349,7 @@ public final class StarLightInterface { - return ret; - } - -- protected final void releaseSkyLightEngine(final SkyStarLightEngine engine) { -+ public final void releaseSkyLightEngine(final SkyStarLightEngine engine) { // Paper - public - if (this.cachedSkyPropagators == null) { - return; - } -@@ -357,7 +358,7 @@ public final class StarLightInterface { - } - } - -- protected final BlockStarLightEngine getBlockLightEngine() { -+ public final BlockStarLightEngine getBlockLightEngine() { // Paper - public - if (this.cachedBlockPropagators == null) { - return null; - } -@@ -372,7 +373,7 @@ public final class StarLightInterface { - return ret; - } - -- protected final void releaseBlockLightEngine(final BlockStarLightEngine engine) { -+ public final void releaseBlockLightEngine(final BlockStarLightEngine engine) { // Paper - public - if (this.cachedBlockPropagators == null) { - return; - } -@@ -381,7 +382,7 @@ public final class StarLightInterface { - } - } - -- public LightQueue.ChunkTasks blockChange(final BlockPos pos) { -+ public io.papermc.paper.chunk.system.light.LightQueue.ChunkTasks blockChange(final BlockPos pos) { // Paper - rewrite chunk system - if (this.world == null || pos.getY() < WorldUtil.getMinBlockY(this.world) || pos.getY() > WorldUtil.getMaxBlockY(this.world)) { // empty world - return null; - } -@@ -389,7 +390,7 @@ public final class StarLightInterface { - return this.lightQueue.queueBlockChange(pos); - } - -- public LightQueue.ChunkTasks sectionChange(final SectionPos pos, final boolean newEmptyValue) { -+ public io.papermc.paper.chunk.system.light.LightQueue.ChunkTasks sectionChange(final SectionPos pos, final boolean newEmptyValue) { // Paper - rewrite chunk system - if (this.world == null) { // empty world - return null; - } -@@ -519,57 +520,15 @@ public final class StarLightInterface { - } - - public void scheduleChunkLight(final ChunkPos pos, final Runnable run) { -- this.lightQueue.queueChunkLighting(pos, run); -+ throw new UnsupportedOperationException("No longer implemented, use the new lightQueue field to queue tasks"); // Paper - replace light queue - } - - public void removeChunkTasks(final ChunkPos pos) { -- this.lightQueue.removeChunk(pos); -+ throw new UnsupportedOperationException("No longer implemented, use the new lightQueue field to queue tasks"); // Paper - replace light queue - } - - public void propagateChanges() { -- if (this.lightQueue.isEmpty()) { -- return; -- } -- -- final SkyStarLightEngine skyEngine = this.getSkyLightEngine(); -- final BlockStarLightEngine blockEngine = this.getBlockLightEngine(); -- -- try { -- LightQueue.ChunkTasks task; -- while ((task = this.lightQueue.removeFirstTask()) != null) { -- if (task.lightTasks != null) { -- for (final Runnable run : task.lightTasks) { -- run.run(); -- } -- } -- -- final long coordinate = task.chunkCoordinate; -- final int chunkX = CoordinateUtils.getChunkX(coordinate); -- final int chunkZ = CoordinateUtils.getChunkZ(coordinate); -- -- final Set positions = task.changedPositions; -- final Boolean[] sectionChanges = task.changedSectionSet; -- -- if (skyEngine != null && (!positions.isEmpty() || sectionChanges != null)) { -- skyEngine.blocksChangedInChunk(this.lightAccess, chunkX, chunkZ, positions, sectionChanges); -- } -- if (blockEngine != null && (!positions.isEmpty() || sectionChanges != null)) { -- blockEngine.blocksChangedInChunk(this.lightAccess, chunkX, chunkZ, positions, sectionChanges); -- } -- -- if (skyEngine != null && task.queuedEdgeChecksSky != null) { -- skyEngine.checkChunkEdges(this.lightAccess, chunkX, chunkZ, task.queuedEdgeChecksSky); -- } -- if (blockEngine != null && task.queuedEdgeChecksBlock != null) { -- blockEngine.checkChunkEdges(this.lightAccess, chunkX, chunkZ, task.queuedEdgeChecksBlock); -- } -- -- task.onComplete.complete(null); -- } -- } finally { -- this.releaseSkyLightEngine(skyEngine); -- this.releaseBlockLightEngine(blockEngine); -- } -+ throw new UnsupportedOperationException("No longer implemented, task draining is now performed by the light thread"); // Paper - replace light queue - } - - public static final class LightQueue { -diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java -index 2f0d9b953802dee821cfde82d22b0567cce8ee91..22687667ec69a954261e55e59261286ac1b8b8cd 100644 ---- a/src/main/java/co/aikar/timings/WorldTimingsHandler.java -+++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java -@@ -59,6 +59,16 @@ public class WorldTimingsHandler { - - public final Timing miscMobSpawning; - -+ public final Timing poiUnload; -+ public final Timing chunkUnload; -+ public final Timing poiSaveDataSerialization; -+ public final Timing chunkSave; -+ public final Timing chunkSaveDataSerialization; -+ public final Timing chunkSaveIOWait; -+ public final Timing chunkUnloadPrepareSave; -+ public final Timing chunkUnloadPOISerialization; -+ public final Timing chunkUnloadDataSave; -+ - public WorldTimingsHandler(Level server) { - String name = ((PrimaryLevelData) server.getLevelData()).getLevelName() + " - "; - -@@ -112,6 +122,16 @@ public class WorldTimingsHandler { - - - miscMobSpawning = Timings.ofSafe(name + "Mob spawning - Misc"); -+ -+ poiUnload = Timings.ofSafe(name + "Chunk unload - POI"); -+ chunkUnload = Timings.ofSafe(name + "Chunk unload - Chunk"); -+ poiSaveDataSerialization = Timings.ofSafe(name + "Chunk save - POI Data serialization"); -+ chunkSave = Timings.ofSafe(name + "Chunk save - Chunk"); -+ chunkSaveDataSerialization = Timings.ofSafe(name + "Chunk save - Chunk Data serialization"); -+ chunkSaveIOWait = Timings.ofSafe(name + "Chunk save - Chunk IO Wait"); -+ chunkUnloadPrepareSave = Timings.ofSafe(name + "Chunk unload - Async Save Prepare"); -+ chunkUnloadPOISerialization = Timings.ofSafe(name + "Chunk unload - POI Data Serialization"); -+ chunkUnloadDataSave = Timings.ofSafe(name + "Chunk unload - Data Serialization"); - } - - public static Timing getTickList(ServerLevel worldserver, String timingsType) { -diff --git a/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java b/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java -index cff2f04409fab9abca87ceec85a551e1d59f9e7d..e3f56908cc8a9c3f4580def50fcfdc61bd495a71 100644 ---- a/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java -+++ b/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java -@@ -32,192 +32,41 @@ public final class ChunkSystem { - } - - 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); -+ level.chunkTaskScheduler.scheduleChunkTask(chunkX, chunkZ, run, priority); // Paper - rewrite chunk system - } - - 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 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); -- } -- } -- }); -+ level.chunkTaskScheduler.scheduleChunkLoad(chunkX, chunkZ, gen, toStatus, addTicket, priority, onComplete); // Paper - rewrite chunk system - } - -- static final TicketType CHUNK_LOAD = TicketType.create("chunk_load", Long::compareTo); -- -- private static long chunkLoadCounter = 0L; -+ // Paper - rewrite chunk system - 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 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 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.updatingChunkMap.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -- -- if (holder == null || holder.getTicketLevel() > minLevel) { -- loadCallback.accept(null); -- return; -- } -- -- final CompletableFuture> loadFuture = holder.getOrScheduleFuture(toStatus, level.chunkSource.chunkMap); -- -- if (loadFuture.isDone()) { -- loadCallback.accept(loadFuture.join().left().orElse(null)); -- return; -- } -- -- loadFuture.whenCompleteAsync((final Either 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); -- }); -+ level.chunkTaskScheduler.scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); // Paper - rewrite chunk system - } - - public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ, - final FullChunkStatus toStatus, final boolean addTicket, - final PrioritisedExecutor.Priority priority, final Consumer onComplete) { -- // This method goes unused until the chunk system rewrite -- if (toStatus == 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 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.updatingChunkMap.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -- -- if (holder == null || holder.getTicketLevel() > minLevel) { -- loadCallback.accept(null); -- return; -- } -- -- final CompletableFuture> tickingState; -- switch (toStatus) { -- case FULL: { -- tickingState = holder.getFullChunkFuture(); -- break; -- } -- case BLOCK_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 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); -- }); -+ level.chunkTaskScheduler.scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); // Paper - rewrite chunk system - } - - public static List getVisibleChunkHolders(final ServerLevel level) { -- return new ArrayList<>(level.chunkSource.chunkMap.visibleChunkMap.values()); -+ return level.chunkTaskScheduler.chunkHolderManager.getOldChunkHolders(); // Paper - rewrite chunk system - } - - public static List getUpdatingChunkHolders(final ServerLevel level) { -- return new ArrayList<>(level.chunkSource.chunkMap.updatingChunkMap.values()); -+ return level.chunkTaskScheduler.chunkHolderManager.getOldChunkHolders(); // Paper - rewrite chunk system - } - - public static int getVisibleChunkHolderCount(final ServerLevel level) { -- return level.chunkSource.chunkMap.visibleChunkMap.size(); -+ return level.chunkTaskScheduler.chunkHolderManager.size(); // Paper - rewrite chunk system - } - - public static int getUpdatingChunkHolderCount(final ServerLevel level) { -- return level.chunkSource.chunkMap.updatingChunkMap.size(); -+ return level.chunkTaskScheduler.chunkHolderManager.size(); // Paper - rewrite chunk system - } - - public static boolean hasAnyChunkHolders(final ServerLevel level) { -@@ -244,26 +93,32 @@ public final class ChunkSystem { - - public static void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder) { - chunk.playerChunk = holder; -+ chunk.chunkStatus = net.minecraft.server.level.FullChunkStatus.FULL; - } - - public static void onChunkNotBorder(final LevelChunk chunk, final ChunkHolder holder) { -- -+ chunk.chunkStatus = net.minecraft.server.level.FullChunkStatus.INACCESSIBLE; - } - - public static void onChunkTicking(final LevelChunk chunk, final ChunkHolder holder) { - chunk.level.getChunkSource().tickingChunks.add(chunk); -+ chunk.chunkStatus = net.minecraft.server.level.FullChunkStatus.BLOCK_TICKING; -+ chunk.level.chunkSource.chunkMap.tickingGenerated.incrementAndGet(); - } - - public static void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) { - chunk.level.getChunkSource().tickingChunks.remove(chunk); -+ chunk.chunkStatus = net.minecraft.server.level.FullChunkStatus.FULL; - } - - public static void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { - chunk.level.getChunkSource().entityTickingChunks.add(chunk); -+ chunk.chunkStatus = net.minecraft.server.level.FullChunkStatus.ENTITY_TICKING; - } - - public static void onChunkNotEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { - chunk.level.getChunkSource().entityTickingChunks.remove(chunk); -+ chunk.chunkStatus = net.minecraft.server.level.FullChunkStatus.BLOCK_TICKING; - } - - public static ChunkHolder getUnloadingChunkHolder(final ServerLevel level, final int chunkX, final int chunkZ) { -@@ -271,23 +126,15 @@ public final class ChunkSystem { - } - - public static int getSendViewDistance(final ServerPlayer player) { -- return getLoadViewDistance(player); -+ return io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.getAPISendViewDistance(player); - } - - public static int getLoadViewDistance(final ServerPlayer player) { -- final ServerLevel level = player.serverLevel(); -- if (level == null) { -- return Bukkit.getViewDistance(); -- } -- return level.chunkSource.chunkMap.getPlayerViewDistance(player); -+ return io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.getLoadViewDistance(player); - } - - public static int getTickViewDistance(final ServerPlayer player) { -- final ServerLevel level = player.serverLevel(); -- if (level == null) { -- return Bukkit.getSimulationDistance(); -- } -- return level.chunkSource.chunkMap.distanceManager.simulationDistance; -+ return io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.getAPITickViewDistance(player); - } - - private ChunkSystem() { -diff --git a/src/main/java/io/papermc/paper/chunk/system/RegionizedPlayerChunkLoader.java b/src/main/java/io/papermc/paper/chunk/system/RegionizedPlayerChunkLoader.java -new file mode 100644 -index 0000000000000000000000000000000000000000..ee58c67cb2bd78159cce19ec75f13dc6168a0e7a ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/RegionizedPlayerChunkLoader.java -@@ -0,0 +1,1375 @@ -+package io.papermc.paper.chunk.system; -+ -+import ca.spottedleaf.concurrentutil.collection.SRSWLinkedQueue; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import io.papermc.paper.chunk.system.scheduling.ChunkHolderManager; -+import io.papermc.paper.configuration.GlobalConfiguration; -+import io.papermc.paper.util.CoordinateUtils; -+import io.papermc.paper.util.TickThread; -+import io.papermc.paper.util.player.SingleUserAreaMap; -+import it.unimi.dsi.fastutil.longs.Long2ByteOpenHashMap; -+import it.unimi.dsi.fastutil.longs.LongArrayList; -+import it.unimi.dsi.fastutil.longs.LongComparator; -+import it.unimi.dsi.fastutil.longs.LongHeapPriorityQueue; -+import it.unimi.dsi.fastutil.longs.LongIterator; -+import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet; -+import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -+import net.minecraft.network.protocol.Packet; -+import net.minecraft.network.protocol.game.ClientboundSetChunkCacheCenterPacket; -+import net.minecraft.network.protocol.game.ClientboundSetChunkCacheRadiusPacket; -+import net.minecraft.network.protocol.game.ClientboundSetSimulationDistancePacket; -+import net.minecraft.server.level.ChunkTrackingView; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.server.level.TicketType; -+import net.minecraft.server.network.PlayerChunkSender; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.GameRules; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.status.ChunkStatus; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.levelgen.BelowZeroRetrogen; -+import org.bukkit.craftbukkit.entity.CraftPlayer; -+import org.bukkit.entity.Player; -+import java.lang.invoke.VarHandle; -+import java.util.ArrayDeque; -+import java.util.Arrays; -+import java.util.Objects; -+import java.util.concurrent.TimeUnit; -+import java.util.concurrent.atomic.AtomicLong; -+ -+public class RegionizedPlayerChunkLoader { -+ -+ // expected that this list returns for a given radius, the set of chunks ordered -+ // by manhattan distance -+ private static final long[][] SEARCH_RADIUS_ITERATION_LIST = new long[64+2+1][]; -+ static { -+ for (int i = 0; i < SEARCH_RADIUS_ITERATION_LIST.length; ++i) { -+ // a BFS around -x, -z, +x, +z will give increasing manhatten distance -+ SEARCH_RADIUS_ITERATION_LIST[i] = generateBFSOrder(i); -+ } -+ } -+ -+ private static void expandQuadrants(final CustomLongArray input, final int size) { -+ final int len = input.size(); -+ final long[] array = input.elements(); -+ -+ int writeIndex = size - 1; -+ for (int i = len - 1; i >= 0; --i) { -+ final long key = array[i]; -+ final int chunkX = CoordinateUtils.getChunkX(key); -+ final int chunkZ = CoordinateUtils.getChunkZ(key); -+ -+ if ((chunkX | chunkZ) < 0 || (i != 0 && chunkX == 0 && chunkZ == 0)) { -+ throw new IllegalStateException(); -+ } -+ -+ // Q4 -+ if (chunkZ != 0) { -+ array[writeIndex--] = CoordinateUtils.getChunkKey(chunkX, -chunkZ); -+ } -+ // Q3 -+ if (chunkX != 0 && chunkZ != 0) { -+ array[writeIndex--] = CoordinateUtils.getChunkKey(-chunkX, -chunkZ); -+ } -+ // Q2 -+ if (chunkX != 0) { -+ array[writeIndex--] = CoordinateUtils.getChunkKey(-chunkX, chunkZ); -+ } -+ -+ array[writeIndex--] = key; -+ } -+ -+ input.forceSize(size); -+ -+ if (writeIndex != -1) { -+ throw new IllegalStateException(); -+ } -+ } -+ -+ private static long[] generateBFSOrder(final int radius) { -+ // by using only the first quadrant, we can reduce the total element size by 4 when spreading -+ final CustomLongArray[] byDistance = makeQ1BFS(radius); -+ -+ // to increase generation parallelism, we want to space the chunks out so that they are not nearby when generating -+ // this also means we are minimising locality -+ // but, we need to maintain sorted order by manhatten distance -+ -+ // per manhatten distance we transform the chunk list so that each element is maximally spaced out from each other -+ for (int i = 0, len = byDistance.length; i < len; ++i) { -+ final CustomLongArray points = byDistance[i]; -+ final int expectedSize = getDistanceSize(i, radius); -+ -+ final CustomLongArray spread = spread(points, expectedSize); -+ // add in Q2, Q3, Q4 -+ expandQuadrants(spread, expectedSize); -+ -+ byDistance[i] = spread; -+ } -+ -+ // now, rebuild the list so that it still maintains manhatten distance order -+ final CustomLongArray ret = new CustomLongArray((2 * radius + 1) * (2 * radius + 1)); -+ -+ for (final CustomLongArray dist : byDistance) { -+ ret.addAll(dist); -+ } -+ -+ return ret.elements(); -+ } -+ -+ public static final TicketType REGION_PLAYER_TICKET = TicketType.create("region_player_ticket", Long::compareTo); -+ -+ public static final int MIN_VIEW_DISTANCE = 2; -+ public static final int MAX_VIEW_DISTANCE = 32; -+ -+ public static final int TICK_TICKET_LEVEL = 31; -+ public static final int GENERATED_TICKET_LEVEL = 33 + ChunkStatus.getDistance(ChunkStatus.FULL); -+ public static final int LOADED_TICKET_LEVEL = 33 + ChunkStatus.getDistance(ChunkStatus.EMPTY); -+ -+ public static final record ViewDistances( -+ int tickViewDistance, -+ int loadViewDistance, -+ int sendViewDistance -+ ) { -+ public ViewDistances setTickViewDistance(final int distance) { -+ return new ViewDistances(distance, this.loadViewDistance, this.sendViewDistance); -+ } -+ -+ public ViewDistances setLoadViewDistance(final int distance) { -+ return new ViewDistances(this.tickViewDistance, distance, this.sendViewDistance); -+ } -+ -+ -+ public ViewDistances setSendViewDistance(final int distance) { -+ return new ViewDistances(this.tickViewDistance, this.loadViewDistance, distance); -+ } -+ } -+ -+ public static int getAPITickViewDistance(final Player player) { -+ return getAPITickViewDistance(((CraftPlayer)player).getHandle()); -+ } -+ -+ public static int getAPITickViewDistance(final ServerPlayer player) { -+ final ServerLevel level = (ServerLevel)player.level(); -+ final PlayerChunkLoaderData data = player.chunkLoader; -+ if (data == null) { -+ return level.playerChunkLoader.getAPITickDistance(); -+ } -+ return data.lastTickDistance; -+ } -+ -+ public static int getAPIViewDistance(final Player player) { -+ return getAPIViewDistance(((CraftPlayer)player).getHandle()); -+ } -+ -+ public static int getAPIViewDistance(final ServerPlayer player) { -+ final ServerLevel level = (ServerLevel)player.level(); -+ final PlayerChunkLoaderData data = player.chunkLoader; -+ if (data == null) { -+ return level.playerChunkLoader.getAPIViewDistance(); -+ } -+ // view distance = load distance + 1 -+ return data.lastLoadDistance - 1; -+ } -+ -+ public static int getLoadViewDistance(final ServerPlayer player) { -+ final ServerLevel level = (ServerLevel)player.level(); -+ final PlayerChunkLoaderData data = player.chunkLoader; -+ if (data == null) { -+ return level.playerChunkLoader.getAPIViewDistance(); -+ } -+ // view distance = load distance + 1 -+ return data.lastLoadDistance - 1; -+ } -+ -+ public static int getAPISendViewDistance(final Player player) { -+ return getAPISendViewDistance(((CraftPlayer)player).getHandle()); -+ } -+ -+ public static int getAPISendViewDistance(final ServerPlayer player) { -+ final ServerLevel level = (ServerLevel)player.level(); -+ final PlayerChunkLoaderData data = player.chunkLoader; -+ if (data == null) { -+ return level.playerChunkLoader.getAPISendViewDistance(); -+ } -+ return data.lastSendDistance; -+ } -+ -+ private final ServerLevel world; -+ -+ public RegionizedPlayerChunkLoader(final ServerLevel world) { -+ this.world = world; -+ } -+ -+ public void addPlayer(final ServerPlayer player) { -+ TickThread.ensureTickThread(player, "Cannot add player to player chunk loader async"); -+ if (!player.isRealPlayer) { -+ return; -+ } -+ -+ if (player.chunkLoader != null) { -+ throw new IllegalStateException("Player is already added to player chunk loader"); -+ } -+ -+ final PlayerChunkLoaderData loader = new PlayerChunkLoaderData(this.world, player); -+ -+ player.chunkLoader = loader; -+ loader.add(); -+ } -+ -+ public void updatePlayer(final ServerPlayer player) { -+ final PlayerChunkLoaderData loader = player.chunkLoader; -+ if (loader != null) { -+ loader.update(); -+ } -+ } -+ -+ public void removePlayer(final ServerPlayer player) { -+ TickThread.ensureTickThread(player, "Cannot remove player from player chunk loader async"); -+ if (!player.isRealPlayer) { -+ return; -+ } -+ -+ final PlayerChunkLoaderData loader = player.chunkLoader; -+ -+ if (loader == null) { -+ return; -+ } -+ -+ loader.remove(); -+ player.chunkLoader = null; -+ } -+ -+ public void setSendDistance(final int distance) { -+ this.world.setSendViewDistance(distance); -+ } -+ -+ public void setLoadDistance(final int distance) { -+ this.world.setLoadViewDistance(distance); -+ } -+ -+ public void setTickDistance(final int distance) { -+ this.world.setTickViewDistance(distance); -+ } -+ -+ // Note: follow the player chunk loader so everything stays consistent... -+ public int getAPITickDistance() { -+ final ViewDistances distances = this.world.getViewDistances(); -+ final int tickViewDistance = PlayerChunkLoaderData.getTickDistance(-1, distances.tickViewDistance); -+ return tickViewDistance; -+ } -+ -+ public int getAPIViewDistance() { -+ final ViewDistances distances = this.world.getViewDistances(); -+ final int tickViewDistance = PlayerChunkLoaderData.getTickDistance(-1, distances.tickViewDistance); -+ final int loadDistance = PlayerChunkLoaderData.getLoadViewDistance(tickViewDistance, -1, distances.loadViewDistance); -+ -+ // loadDistance = api view distance + 1 -+ return loadDistance - 1; -+ } -+ -+ public int getAPISendViewDistance() { -+ final ViewDistances distances = this.world.getViewDistances(); -+ final int tickViewDistance = PlayerChunkLoaderData.getTickDistance(-1, distances.tickViewDistance); -+ final int loadDistance = PlayerChunkLoaderData.getLoadViewDistance(tickViewDistance, -1, distances.loadViewDistance); -+ final int sendViewDistance = PlayerChunkLoaderData.getSendViewDistance( -+ loadDistance, -1, -1, distances.sendViewDistance -+ ); -+ -+ return sendViewDistance; -+ } -+ -+ public boolean isChunkSent(final ServerPlayer player, final int chunkX, final int chunkZ, final boolean borderOnly) { -+ return borderOnly ? this.isChunkSentBorderOnly(player, chunkX, chunkZ) : this.isChunkSent(player, chunkX, chunkZ); -+ } -+ -+ public boolean isChunkSent(final ServerPlayer player, final int chunkX, final int chunkZ) { -+ final PlayerChunkLoaderData loader = player.chunkLoader; -+ if (loader == null) { -+ return false; -+ } -+ -+ return loader.sentChunks.contains(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ } -+ -+ public boolean isChunkSentBorderOnly(final ServerPlayer player, final int chunkX, final int chunkZ) { -+ final PlayerChunkLoaderData loader = player.chunkLoader; -+ if (loader == null) { -+ return false; -+ } -+ -+ for (int dz = -1; dz <= 1; ++dz) { -+ for (int dx = -1; dx <= 1; ++dx) { -+ if (!loader.sentChunks.contains(CoordinateUtils.getChunkKey(dx + chunkX, dz + chunkZ))) { -+ return true; -+ } -+ } -+ } -+ -+ return false; -+ } -+ -+ public void tick() { -+ TickThread.ensureTickThread("Cannot tick player chunk loader async"); -+ long currTime = System.nanoTime(); -+ for (final ServerPlayer player : new java.util.ArrayList<>(this.world.players())) { -+ final PlayerChunkLoaderData loader = player.chunkLoader; -+ if (loader == null || loader.world != this.world) { -+ // not our problem anymore -+ continue; -+ } -+ loader.update(); // can't invoke plugin logic -+ loader.updateQueues(currTime); -+ } -+ } -+ -+ public static final class PlayerChunkLoaderData { -+ -+ private static final AtomicLong ID_GENERATOR = new AtomicLong(); -+ private final long id = ID_GENERATOR.incrementAndGet(); -+ private final Long idBoxed = Long.valueOf(this.id); -+ -+ private static final long MAX_RATE = 10_000L; -+ -+ private final ServerPlayer player; -+ private final ServerLevel world; -+ -+ private int lastChunkX = Integer.MIN_VALUE; -+ private int lastChunkZ = Integer.MIN_VALUE; -+ -+ private int lastSendDistance = Integer.MIN_VALUE; -+ private int lastLoadDistance = Integer.MIN_VALUE; -+ private int lastTickDistance = Integer.MIN_VALUE; -+ -+ private int lastSentChunkCenterX = Integer.MIN_VALUE; -+ private int lastSentChunkCenterZ = Integer.MIN_VALUE; -+ -+ private int lastSentChunkRadius = Integer.MIN_VALUE; -+ private int lastSentSimulationDistance = Integer.MIN_VALUE; -+ -+ private boolean canGenerateChunks = true; -+ -+ private final ArrayDeque> delayedTicketOps = new ArrayDeque<>(); -+ private final LongOpenHashSet sentChunks = new LongOpenHashSet(); -+ -+ private static final byte CHUNK_TICKET_STAGE_NONE = 0; -+ private static final byte CHUNK_TICKET_STAGE_LOADING = 1; -+ private static final byte CHUNK_TICKET_STAGE_LOADED = 2; -+ private static final byte CHUNK_TICKET_STAGE_GENERATING = 3; -+ private static final byte CHUNK_TICKET_STAGE_GENERATED = 4; -+ private static final byte CHUNK_TICKET_STAGE_TICK = 5; -+ private static final int[] TICKET_STAGE_TO_LEVEL = new int[] { -+ ChunkHolderManager.MAX_TICKET_LEVEL + 1, -+ LOADED_TICKET_LEVEL, -+ LOADED_TICKET_LEVEL, -+ GENERATED_TICKET_LEVEL, -+ GENERATED_TICKET_LEVEL, -+ TICK_TICKET_LEVEL -+ }; -+ private final Long2ByteOpenHashMap chunkTicketStage = new Long2ByteOpenHashMap(); -+ { -+ this.chunkTicketStage.defaultReturnValue(CHUNK_TICKET_STAGE_NONE); -+ } -+ -+ // rate limiting -+ private final AllocatingRateLimiter chunkSendLimiter = new AllocatingRateLimiter(); -+ private final AllocatingRateLimiter chunkLoadTicketLimiter = new AllocatingRateLimiter(); -+ private final AllocatingRateLimiter chunkGenerateTicketLimiter = new AllocatingRateLimiter(); -+ -+ // queues -+ private final LongComparator CLOSEST_MANHATTAN_DIST = (final long c1, final long c2) -> { -+ final int c1x = CoordinateUtils.getChunkX(c1); -+ final int c1z = CoordinateUtils.getChunkZ(c1); -+ -+ final int c2x = CoordinateUtils.getChunkX(c2); -+ final int c2z = CoordinateUtils.getChunkZ(c2); -+ -+ final int centerX = PlayerChunkLoaderData.this.lastChunkX; -+ final int centerZ = PlayerChunkLoaderData.this.lastChunkZ; -+ -+ return Integer.compare( -+ Math.abs(c1x - centerX) + Math.abs(c1z - centerZ), -+ Math.abs(c2x - centerX) + Math.abs(c2z - centerZ) -+ ); -+ }; -+ private final LongHeapPriorityQueue sendQueue = new LongHeapPriorityQueue(CLOSEST_MANHATTAN_DIST); -+ private final LongHeapPriorityQueue tickingQueue = new LongHeapPriorityQueue(CLOSEST_MANHATTAN_DIST); -+ private final LongHeapPriorityQueue generatingQueue = new LongHeapPriorityQueue(CLOSEST_MANHATTAN_DIST); -+ private final LongHeapPriorityQueue genQueue = new LongHeapPriorityQueue(CLOSEST_MANHATTAN_DIST); -+ private final LongHeapPriorityQueue loadingQueue = new LongHeapPriorityQueue(CLOSEST_MANHATTAN_DIST); -+ private final LongHeapPriorityQueue loadQueue = new LongHeapPriorityQueue(CLOSEST_MANHATTAN_DIST); -+ -+ private volatile boolean removed; -+ -+ public PlayerChunkLoaderData(final ServerLevel world, final ServerPlayer player) { -+ this.world = world; -+ this.player = player; -+ } -+ -+ private void flushDelayedTicketOps() { -+ if (this.delayedTicketOps.isEmpty()) { -+ return; -+ } -+ this.world.chunkTaskScheduler.chunkHolderManager.performTicketUpdates(this.delayedTicketOps); -+ this.delayedTicketOps.clear(); -+ } -+ -+ private void pushDelayedTicketOp(final ChunkHolderManager.TicketOperation op) { -+ this.delayedTicketOps.addLast(op); -+ } -+ -+ private void sendChunk(final int chunkX, final int chunkZ) { -+ if (this.sentChunks.add(CoordinateUtils.getChunkKey(chunkX, chunkZ))) { -+ PlayerChunkSender.sendChunk(this.player.connection, this.world, this.world.getChunkIfLoaded(chunkX, chunkZ)); -+ return; -+ } -+ throw new IllegalStateException(); -+ } -+ -+ private void sendUnloadChunk(final int chunkX, final int chunkZ) { -+ if (!this.sentChunks.remove(CoordinateUtils.getChunkKey(chunkX, chunkZ))) { -+ return; -+ } -+ this.sendUnloadChunkRaw(chunkX, chunkZ); -+ } -+ -+ private void sendUnloadChunkRaw(final int chunkX, final int chunkZ) { -+ PlayerChunkSender.dropChunkStatic(this.player, new ChunkPos(chunkX, chunkZ)); -+ } -+ -+ private final SingleUserAreaMap broadcastMap = new SingleUserAreaMap<>(this) { -+ @Override -+ protected void addCallback(final PlayerChunkLoaderData parameter, final int chunkX, final int chunkZ) { -+ // do nothing, we only care about remove -+ } -+ -+ @Override -+ protected void removeCallback(final PlayerChunkLoaderData parameter, final int chunkX, final int chunkZ) { -+ parameter.sendUnloadChunk(chunkX, chunkZ); -+ } -+ }; -+ private final SingleUserAreaMap loadTicketCleanup = new SingleUserAreaMap<>(this) { -+ @Override -+ protected void addCallback(final PlayerChunkLoaderData parameter, final int chunkX, final int chunkZ) { -+ // do nothing, we only care about remove -+ } -+ -+ @Override -+ protected void removeCallback(final PlayerChunkLoaderData parameter, final int chunkX, final int chunkZ) { -+ final long chunk = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ final byte ticketStage = parameter.chunkTicketStage.remove(chunk); -+ final int level = TICKET_STAGE_TO_LEVEL[ticketStage]; -+ if (level > ChunkHolderManager.MAX_TICKET_LEVEL) { -+ return; -+ } -+ -+ parameter.pushDelayedTicketOp(ChunkHolderManager.TicketOperation.addAndRemove( -+ chunk, -+ TicketType.UNKNOWN, level, new ChunkPos(chunkX, chunkZ), -+ REGION_PLAYER_TICKET, level, parameter.idBoxed -+ )); -+ } -+ }; -+ private final SingleUserAreaMap tickMap = new SingleUserAreaMap<>(this) { -+ @Override -+ protected void addCallback(final PlayerChunkLoaderData parameter, final int chunkX, final int chunkZ) { -+ // do nothing, we will detect ticking chunks when we try to load them -+ } -+ -+ @Override -+ protected void removeCallback(final PlayerChunkLoaderData parameter, final int chunkX, final int chunkZ) { -+ final long chunk = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ // note: by the time this is called, the tick cleanup should have ran - so, if the chunk is at -+ // the tick stage it was deemed in range for loading. Thus, we need to move it to generated -+ if (!parameter.chunkTicketStage.replace(chunk, CHUNK_TICKET_STAGE_TICK, CHUNK_TICKET_STAGE_GENERATED)) { -+ return; -+ } -+ -+ // Since we are possibly downgrading the ticket level, we add an unknown ticket so that -+ // the level is kept until tick(). -+ parameter.pushDelayedTicketOp(ChunkHolderManager.TicketOperation.addAndRemove( -+ chunk, -+ TicketType.UNKNOWN, TICK_TICKET_LEVEL, new ChunkPos(chunkX, chunkZ), -+ REGION_PLAYER_TICKET, TICK_TICKET_LEVEL, parameter.idBoxed -+ )); -+ // keep chunk at new generated level -+ parameter.pushDelayedTicketOp(ChunkHolderManager.TicketOperation.addOp( -+ chunk, -+ REGION_PLAYER_TICKET, GENERATED_TICKET_LEVEL, parameter.idBoxed -+ )); -+ } -+ }; -+ -+ private static boolean wantChunkLoaded(final int centerX, final int centerZ, final int chunkX, final int chunkZ, -+ final int sendRadius) { -+ // expect sendRadius to be = 1 + target viewable radius -+ return ChunkTrackingView.isWithinDistance(centerX, centerZ, sendRadius, chunkX, chunkZ, true); -+ } -+ -+ private static int getClientViewDistance(final ServerPlayer player) { -+ final Integer vd = player.requestedViewDistance(); -+ return vd == null ? -1 : Math.max(0, vd.intValue()); -+ } -+ -+ private static int getTickDistance(final int playerTickViewDistance, final int worldTickViewDistance) { -+ return playerTickViewDistance < 0 ? worldTickViewDistance : playerTickViewDistance; -+ } -+ -+ private static int getLoadViewDistance(final int tickViewDistance, final int playerLoadViewDistance, -+ final int worldLoadViewDistance) { -+ return Math.max(tickViewDistance + 1, playerLoadViewDistance < 0 ? worldLoadViewDistance : playerLoadViewDistance); -+ } -+ -+ private static int getSendViewDistance(final int loadViewDistance, final int clientViewDistance, -+ final int playerSendViewDistance, final int worldSendViewDistance) { -+ return Math.min( -+ loadViewDistance - 1, -+ playerSendViewDistance < 0 ? (!GlobalConfiguration.get().chunkLoadingAdvanced.autoConfigSendDistance || clientViewDistance < 0 ? (worldSendViewDistance < 0 ? (loadViewDistance - 1) : worldSendViewDistance) : clientViewDistance + 1) : playerSendViewDistance -+ ); -+ } -+ -+ private Packet updateClientChunkRadius(final int radius) { -+ this.lastSentChunkRadius = radius; -+ return new ClientboundSetChunkCacheRadiusPacket(radius); -+ } -+ -+ private Packet updateClientSimulationDistance(final int distance) { -+ this.lastSentSimulationDistance = distance; -+ return new ClientboundSetSimulationDistancePacket(distance); -+ } -+ -+ private Packet updateClientChunkCenter(final int chunkX, final int chunkZ) { -+ this.lastSentChunkCenterX = chunkX; -+ this.lastSentChunkCenterZ = chunkZ; -+ return new ClientboundSetChunkCacheCenterPacket(chunkX, chunkZ); -+ } -+ -+ private boolean canPlayerGenerateChunks() { -+ return !this.player.isSpectator() || this.world.getGameRules().getBoolean(GameRules.RULE_SPECTATORSGENERATECHUNKS); -+ } -+ -+ private double getMaxChunkLoadRate() { -+ final double configRate = GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkLoadRate; -+ -+ return configRate < 0.0 || configRate > (double)MAX_RATE ? (double)MAX_RATE : Math.max(1.0, configRate); -+ } -+ -+ private double getMaxChunkGenRate() { -+ final double configRate = GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkGenerateRate; -+ -+ return configRate < 0.0 || configRate > (double)MAX_RATE ? (double)MAX_RATE : Math.max(1.0, configRate); -+ } -+ -+ private double getMaxChunkSendRate() { -+ final double configRate = GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkSendRate; -+ -+ return configRate < 0.0 || configRate > (double)MAX_RATE ? (double)MAX_RATE : Math.max(1.0, configRate); -+ } -+ -+ private long getMaxChunkLoads() { -+ final long radiusChunks = (2L * this.lastLoadDistance + 1L) * (2L * this.lastLoadDistance + 1L); -+ long configLimit = GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkLoads; -+ if (configLimit == 0L) { -+ // by default, only allow 1/5th of the chunks in the view distance to be concurrently active -+ configLimit = Math.max(5L, radiusChunks / 5L); -+ } else if (configLimit < 0L) { -+ configLimit = Integer.MAX_VALUE; -+ } // else: use the value configured -+ configLimit = configLimit - this.loadingQueue.size(); -+ -+ return configLimit; -+ } -+ -+ private long getMaxChunkGenerates() { -+ final long radiusChunks = (2L * this.lastLoadDistance + 1L) * (2L * this.lastLoadDistance + 1L); -+ long configLimit = GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkGenerates; -+ if (configLimit == 0L) { -+ // by default, only allow 1/5th of the chunks in the view distance to be concurrently active -+ configLimit = Math.max(5L, radiusChunks / 5L); -+ } else if (configLimit < 0L) { -+ configLimit = Integer.MAX_VALUE; -+ } // else: use the value configured -+ configLimit = configLimit - this.generatingQueue.size(); -+ -+ return configLimit; -+ } -+ -+ private boolean wantChunkSent(final int chunkX, final int chunkZ) { -+ final int dx = this.lastChunkX - chunkX; -+ final int dz = this.lastChunkZ - chunkZ; -+ return (Math.max(Math.abs(dx), Math.abs(dz)) <= (this.lastSendDistance + 1)) && wantChunkLoaded( -+ this.lastChunkX, this.lastChunkZ, chunkX, chunkZ, this.lastSendDistance -+ ); -+ } -+ -+ private boolean wantChunkTicked(final int chunkX, final int chunkZ) { -+ final int dx = this.lastChunkX - chunkX; -+ final int dz = this.lastChunkZ - chunkZ; -+ return Math.max(Math.abs(dx), Math.abs(dz)) <= this.lastTickDistance; -+ } -+ -+ void updateQueues(final long time) { -+ TickThread.ensureTickThread(this.player, "Cannot tick player chunk loader async"); -+ if (this.removed) { -+ throw new IllegalStateException("Ticking removed player chunk loader"); -+ } -+ // update rate limits -+ final double loadRate = this.getMaxChunkLoadRate(); -+ final double genRate = this.getMaxChunkGenRate(); -+ final double sendRate = this.getMaxChunkSendRate(); -+ -+ this.chunkLoadTicketLimiter.tickAllocation(time, loadRate, loadRate); -+ this.chunkGenerateTicketLimiter.tickAllocation(time, genRate, genRate); -+ this.chunkSendLimiter.tickAllocation(time, sendRate, sendRate); -+ -+ // try to progress chunk loads -+ while (!this.loadingQueue.isEmpty()) { -+ final long pendingLoadChunk = this.loadingQueue.firstLong(); -+ final int pendingChunkX = CoordinateUtils.getChunkX(pendingLoadChunk); -+ final int pendingChunkZ = CoordinateUtils.getChunkZ(pendingLoadChunk); -+ final ChunkAccess pending = this.world.chunkSource.getChunkAtImmediately(pendingChunkX, pendingChunkZ); -+ if (pending == null) { -+ // nothing to do here -+ break; -+ } -+ // chunk has loaded, so we can take it out of the queue -+ this.loadingQueue.dequeueLong(); -+ -+ // try to move to generate queue -+ final byte prev = this.chunkTicketStage.put(pendingLoadChunk, CHUNK_TICKET_STAGE_LOADED); -+ if (prev != CHUNK_TICKET_STAGE_LOADING) { -+ throw new IllegalStateException("Previous state should be " + CHUNK_TICKET_STAGE_LOADING + ", not " + prev); -+ } -+ -+ if (this.canGenerateChunks || this.isLoadedChunkGeneratable(pending)) { -+ this.genQueue.enqueue(pendingLoadChunk); -+ } // else: don't want to generate, so just leave it loaded -+ } -+ -+ // try to push more chunk loads -+ final long maxLoads = Math.max(0L, Math.min(MAX_RATE, Math.min(this.loadQueue.size(), this.getMaxChunkLoads()))); -+ final int maxLoadsThisTick = (int)this.chunkLoadTicketLimiter.takeAllocation(time, loadRate, maxLoads); -+ if (maxLoadsThisTick > 0) { -+ final LongArrayList chunks = new LongArrayList(maxLoadsThisTick); -+ for (int i = 0; i < maxLoadsThisTick; ++i) { -+ final long chunk = this.loadQueue.dequeueLong(); -+ final byte prev = this.chunkTicketStage.put(chunk, CHUNK_TICKET_STAGE_LOADING); -+ if (prev != CHUNK_TICKET_STAGE_NONE) { -+ throw new IllegalStateException("Previous state should be " + CHUNK_TICKET_STAGE_NONE + ", not " + prev); -+ } -+ this.pushDelayedTicketOp( -+ ChunkHolderManager.TicketOperation.addOp( -+ chunk, -+ REGION_PLAYER_TICKET, LOADED_TICKET_LEVEL, this.idBoxed -+ ) -+ ); -+ chunks.add(chunk); -+ this.loadingQueue.enqueue(chunk); -+ } -+ -+ // here we need to flush tickets, as scheduleChunkLoad requires tickets to be propagated with addTicket = false -+ this.flushDelayedTicketOps(); -+ // we only need to call scheduleChunkLoad because the loaded ticket level is not enough to start the chunk -+ // load - only generate ticket levels start anything, but they start generation... -+ // propagate levels -+ // Note: this CAN call plugin logic, so it is VITAL that our bookkeeping logic is completely done by the time this is invoked -+ this.world.chunkTaskScheduler.chunkHolderManager.processTicketUpdates(); -+ -+ if (this.removed) { -+ // process ticket updates may invoke plugin logic, which may remove this player -+ return; -+ } -+ -+ for (int i = 0; i < maxLoadsThisTick; ++i) { -+ final long queuedLoadChunk = chunks.getLong(i); -+ final int queuedChunkX = CoordinateUtils.getChunkX(queuedLoadChunk); -+ final int queuedChunkZ = CoordinateUtils.getChunkZ(queuedLoadChunk); -+ this.world.chunkTaskScheduler.scheduleChunkLoad( -+ queuedChunkX, queuedChunkZ, ChunkStatus.EMPTY, false, PrioritisedExecutor.Priority.NORMAL, null -+ ); -+ if (this.removed) { -+ return; -+ } -+ } -+ } -+ -+ // try to progress chunk generations -+ while (!this.generatingQueue.isEmpty()) { -+ final long pendingGenChunk = this.generatingQueue.firstLong(); -+ final int pendingChunkX = CoordinateUtils.getChunkX(pendingGenChunk); -+ final int pendingChunkZ = CoordinateUtils.getChunkZ(pendingGenChunk); -+ final LevelChunk pending = this.world.chunkSource.getChunkAtIfLoadedMainThreadNoCache(pendingChunkX, pendingChunkZ); -+ if (pending == null) { -+ // nothing to do here -+ break; -+ } -+ -+ // chunk has generated, so we can take it out of queue -+ this.generatingQueue.dequeueLong(); -+ -+ final byte prev = this.chunkTicketStage.put(pendingGenChunk, CHUNK_TICKET_STAGE_GENERATED); -+ if (prev != CHUNK_TICKET_STAGE_GENERATING) { -+ throw new IllegalStateException("Previous state should be " + CHUNK_TICKET_STAGE_GENERATING + ", not " + prev); -+ } -+ -+ // try to move to send queue -+ if (this.wantChunkSent(pendingChunkX, pendingChunkZ)) { -+ this.sendQueue.enqueue(pendingGenChunk); -+ } -+ // try to move to tick queue -+ if (this.wantChunkTicked(pendingChunkX, pendingChunkZ)) { -+ this.tickingQueue.enqueue(pendingGenChunk); -+ } -+ } -+ -+ // try to push more chunk generations -+ final long maxGens = Math.max(0L, Math.min(MAX_RATE, Math.min(this.genQueue.size(), this.getMaxChunkGenerates()))); -+ final int maxGensThisTick = (int)this.chunkGenerateTicketLimiter.takeAllocation(time, genRate, maxGens); -+ int ratedGensThisTick = 0; -+ while (!this.genQueue.isEmpty()) { -+ final long chunkKey = this.genQueue.firstLong(); -+ final int chunkX = CoordinateUtils.getChunkX(chunkKey); -+ final int chunkZ = CoordinateUtils.getChunkZ(chunkKey); -+ final ChunkAccess chunk = this.world.chunkSource.getChunkAtImmediately(chunkX, chunkZ); -+ if (chunk.getStatus() != ChunkStatus.FULL) { -+ // only rate limit actual generations -+ if ((ratedGensThisTick + 1) > maxGensThisTick) { -+ break; -+ } -+ ++ratedGensThisTick; -+ } -+ -+ this.genQueue.dequeueLong(); -+ -+ final byte prev = this.chunkTicketStage.put(chunkKey, CHUNK_TICKET_STAGE_GENERATING); -+ if (prev != CHUNK_TICKET_STAGE_LOADED) { -+ throw new IllegalStateException("Previous state should be " + CHUNK_TICKET_STAGE_LOADED + ", not " + prev); -+ } -+ this.pushDelayedTicketOp( -+ ChunkHolderManager.TicketOperation.addAndRemove( -+ chunkKey, -+ REGION_PLAYER_TICKET, GENERATED_TICKET_LEVEL, this.idBoxed, -+ REGION_PLAYER_TICKET, LOADED_TICKET_LEVEL, this.idBoxed -+ ) -+ ); -+ this.generatingQueue.enqueue(chunkKey); -+ } -+ -+ // try to pull ticking chunks -+ tick_check_outer: -+ while (!this.tickingQueue.isEmpty()) { -+ final long pendingTicking = this.tickingQueue.firstLong(); -+ final int pendingChunkX = CoordinateUtils.getChunkX(pendingTicking); -+ final int pendingChunkZ = CoordinateUtils.getChunkZ(pendingTicking); -+ -+ final int tickingReq = 2; -+ for (int dz = -tickingReq; dz <= tickingReq; ++dz) { -+ for (int dx = -tickingReq; dx <= tickingReq; ++dx) { -+ if ((dx | dz) == 0) { -+ continue; -+ } -+ final long neighbour = CoordinateUtils.getChunkKey(dx + pendingChunkX, dz + pendingChunkZ); -+ final byte stage = this.chunkTicketStage.get(neighbour); -+ if (stage != CHUNK_TICKET_STAGE_GENERATED && stage != CHUNK_TICKET_STAGE_TICK) { -+ break tick_check_outer; -+ } -+ } -+ } -+ // only gets here if all neighbours were marked as generated or ticking themselves -+ this.tickingQueue.dequeueLong(); -+ this.pushDelayedTicketOp( -+ ChunkHolderManager.TicketOperation.addAndRemove( -+ pendingTicking, -+ REGION_PLAYER_TICKET, TICK_TICKET_LEVEL, this.idBoxed, -+ REGION_PLAYER_TICKET, GENERATED_TICKET_LEVEL, this.idBoxed -+ ) -+ ); -+ // there is no queue to add after ticking -+ final byte prev = this.chunkTicketStage.put(pendingTicking, CHUNK_TICKET_STAGE_TICK); -+ if (prev != CHUNK_TICKET_STAGE_GENERATED) { -+ throw new IllegalStateException("Previous state should be " + CHUNK_TICKET_STAGE_GENERATED + ", not " + prev); -+ } -+ } -+ -+ // try to pull sending chunks -+ final long maxSends = Math.max(0L, Math.min(MAX_RATE, Integer.MAX_VALUE)); // no logic to track concurrent sends -+ final int maxSendsThisTick = Math.min((int)this.chunkSendLimiter.takeAllocation(time, sendRate, maxSends), this.sendQueue.size()); -+ // we do not return sends that we took from the allocation back because we want to limit the max send rate, not target it -+ for (int i = 0; i < maxSendsThisTick; ++i) { -+ final long pendingSend = this.sendQueue.firstLong(); -+ final int pendingSendX = CoordinateUtils.getChunkX(pendingSend); -+ final int pendingSendZ = CoordinateUtils.getChunkZ(pendingSend); -+ final LevelChunk chunk = this.world.chunkSource.getChunkAtIfLoadedMainThreadNoCache(pendingSendX, pendingSendZ); -+ if (!chunk.areNeighboursLoaded(1) || !TickThread.isTickThreadFor(this.world, pendingSendX, pendingSendZ)) { -+ // nothing to do -+ // the target chunk may not be owned by this region, but this should be resolved in the future -+ break; -+ } -+ if (!chunk.isPostProcessingDone) { -+ // not yet post-processed, need to do this so that tile entities can properly be sent to clients -+ chunk.postProcessGeneration(); -+ // check if there was any recursive action -+ if (this.removed || this.sendQueue.isEmpty() || this.sendQueue.firstLong() != pendingSend) { -+ return; -+ } // else: good to dequeue and send, fall through -+ } -+ this.sendQueue.dequeueLong(); -+ -+ this.sendChunk(pendingSendX, pendingSendZ); -+ if (this.removed) { -+ // sendChunk may invoke plugin logic -+ return; -+ } -+ } -+ -+ this.flushDelayedTicketOps(); -+ // we assume propagate ticket levels happens after this call -+ } -+ -+ void add() { -+ TickThread.ensureTickThread(this.player, "Cannot add player asynchronously"); -+ if (this.removed) { -+ throw new IllegalStateException("Adding removed player chunk loader"); -+ } -+ final ViewDistances playerDistances = this.player.getViewDistances(); -+ final ViewDistances worldDistances = this.world.getViewDistances(); -+ final int chunkX = this.player.chunkPosition().x; -+ final int chunkZ = this.player.chunkPosition().z; -+ -+ final int tickViewDistance = getTickDistance(playerDistances.tickViewDistance, worldDistances.tickViewDistance); -+ // load view cannot be less-than tick view + 1 -+ final int loadViewDistance = getLoadViewDistance(tickViewDistance, playerDistances.loadViewDistance, worldDistances.loadViewDistance); -+ // send view cannot be greater-than load view -+ final int clientViewDistance = getClientViewDistance(this.player); -+ final int sendViewDistance = getSendViewDistance(loadViewDistance, clientViewDistance, playerDistances.sendViewDistance, worldDistances.sendViewDistance); -+ -+ // send view distances -+ this.player.connection.send(this.updateClientChunkRadius(sendViewDistance)); -+ this.player.connection.send(this.updateClientSimulationDistance(tickViewDistance)); -+ -+ // add to distance maps -+ this.broadcastMap.add(chunkX, chunkZ, sendViewDistance + 1); -+ this.loadTicketCleanup.add(chunkX, chunkZ, loadViewDistance + 1); -+ this.tickMap.add(chunkX, chunkZ, tickViewDistance); -+ -+ // update chunk center -+ this.player.connection.send(this.updateClientChunkCenter(chunkX, chunkZ)); -+ -+ // now we can update -+ this.update(); -+ } -+ -+ private boolean isLoadedChunkGeneratable(final int chunkX, final int chunkZ) { -+ return this.isLoadedChunkGeneratable(this.world.chunkSource.getChunkAtImmediately(chunkX, chunkZ)); -+ } -+ -+ private boolean isLoadedChunkGeneratable(final ChunkAccess chunkAccess) { -+ final BelowZeroRetrogen belowZeroRetrogen; -+ // see PortalForcer#findPortalAround -+ return chunkAccess != null && ( -+ chunkAccess.getStatus() == ChunkStatus.FULL || -+ ((belowZeroRetrogen = chunkAccess.getBelowZeroRetrogen()) != null && belowZeroRetrogen.targetStatus().isOrAfter(ChunkStatus.SPAWN)) -+ ); -+ } -+ -+ void update() { -+ TickThread.ensureTickThread(this.player, "Cannot update player asynchronously"); -+ if (this.removed) { -+ throw new IllegalStateException("Updating removed player chunk loader"); -+ } -+ final ViewDistances playerDistances = this.player.getViewDistances(); -+ final ViewDistances worldDistances = this.world.getViewDistances(); -+ -+ final int tickViewDistance = getTickDistance(playerDistances.tickViewDistance, worldDistances.tickViewDistance); -+ // load view cannot be less-than tick view + 1 -+ final int loadViewDistance = getLoadViewDistance(tickViewDistance, playerDistances.loadViewDistance, worldDistances.loadViewDistance); -+ // send view cannot be greater-than load view -+ final int clientViewDistance = getClientViewDistance(this.player); -+ final int sendViewDistance = getSendViewDistance(loadViewDistance, clientViewDistance, playerDistances.sendViewDistance, worldDistances.sendViewDistance); -+ -+ final ChunkPos playerPos = this.player.chunkPosition(); -+ final boolean canGenerateChunks = this.canPlayerGenerateChunks(); -+ final int currentChunkX = playerPos.x; -+ final int currentChunkZ = playerPos.z; -+ -+ final int prevChunkX = this.lastChunkX; -+ final int prevChunkZ = this.lastChunkZ; -+ -+ if ( -+ // has view distance stayed the same? -+ sendViewDistance == this.lastSendDistance -+ && loadViewDistance == this.lastLoadDistance -+ && tickViewDistance == this.lastTickDistance -+ -+ // has our chunk stayed the same? -+ && prevChunkX == currentChunkX -+ && prevChunkZ == currentChunkZ -+ -+ // can we still generate chunks? -+ && this.canGenerateChunks == canGenerateChunks -+ ) { -+ // nothing we care about changed, so we're not re-calculating -+ return; -+ } -+ -+ // update distance maps -+ this.broadcastMap.update(currentChunkX, currentChunkZ, sendViewDistance + 1); -+ this.loadTicketCleanup.update(currentChunkX, currentChunkZ, loadViewDistance + 1); -+ this.tickMap.update(currentChunkX, currentChunkZ, tickViewDistance); -+ if (sendViewDistance > loadViewDistance || tickViewDistance > loadViewDistance) { -+ throw new IllegalStateException(); -+ } -+ -+ // update VDs for client -+ // this should be after the distance map updates, as they will send unload packets -+ if (this.lastSentChunkRadius != sendViewDistance) { -+ this.player.connection.send(this.updateClientChunkRadius(sendViewDistance)); -+ } -+ if (this.lastSentSimulationDistance != tickViewDistance) { -+ this.player.connection.send(this.updateClientSimulationDistance(tickViewDistance)); -+ } -+ -+ this.sendQueue.clear(); -+ this.tickingQueue.clear(); -+ this.generatingQueue.clear(); -+ this.genQueue.clear(); -+ this.loadingQueue.clear(); -+ this.loadQueue.clear(); -+ -+ this.lastChunkX = currentChunkX; -+ this.lastChunkZ = currentChunkZ; -+ this.lastSendDistance = sendViewDistance; -+ this.lastLoadDistance = loadViewDistance; -+ this.lastTickDistance = tickViewDistance; -+ this.canGenerateChunks = canGenerateChunks; -+ -+ // +1 since we need to load chunks +1 around the load view distance... -+ final long[] toIterate = SEARCH_RADIUS_ITERATION_LIST[loadViewDistance + 1]; -+ // the iteration order is by increasing manhattan distance - so, we do NOT need to -+ // sort anything in the queue! -+ for (final long deltaChunk : toIterate) { -+ final int dx = CoordinateUtils.getChunkX(deltaChunk); -+ final int dz = CoordinateUtils.getChunkZ(deltaChunk); -+ final int chunkX = dx + currentChunkX; -+ final int chunkZ = dz + currentChunkZ; -+ final long chunk = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ final int squareDistance = Math.max(Math.abs(dx), Math.abs(dz)); -+ final int manhattanDistance = Math.abs(dx) + Math.abs(dz); -+ -+ // since chunk sending is not by radius alone, we need an extra check here to account for -+ // everything <= sendDistance -+ // Note: Vanilla may want to send chunks outside the send view distance, so we do need -+ // the dist <= view check -+ final boolean sendChunk = (squareDistance <= (sendViewDistance + 1)) -+ && wantChunkLoaded(currentChunkX, currentChunkZ, chunkX, chunkZ, sendViewDistance); -+ final boolean sentChunk = sendChunk ? this.sentChunks.contains(chunk) : this.sentChunks.remove(chunk); -+ -+ if (!sendChunk && sentChunk) { -+ // have sent the chunk, but don't want it anymore -+ // unload it now -+ this.sendUnloadChunkRaw(chunkX, chunkZ); -+ } -+ -+ final byte stage = this.chunkTicketStage.get(chunk); -+ switch (stage) { -+ case CHUNK_TICKET_STAGE_NONE: { -+ // we want the chunk to be at least loaded -+ this.loadQueue.enqueue(chunk); -+ break; -+ } -+ case CHUNK_TICKET_STAGE_LOADING: { -+ this.loadingQueue.enqueue(chunk); -+ break; -+ } -+ case CHUNK_TICKET_STAGE_LOADED: { -+ if (canGenerateChunks || this.isLoadedChunkGeneratable(chunkX, chunkZ)) { -+ this.genQueue.enqueue(chunk); -+ } -+ break; -+ } -+ case CHUNK_TICKET_STAGE_GENERATING: { -+ this.generatingQueue.enqueue(chunk); -+ break; -+ } -+ case CHUNK_TICKET_STAGE_GENERATED: { -+ if (sendChunk && !sentChunk) { -+ this.sendQueue.enqueue(chunk); -+ } -+ if (squareDistance <= tickViewDistance) { -+ this.tickingQueue.enqueue(chunk); -+ } -+ break; -+ } -+ case CHUNK_TICKET_STAGE_TICK: { -+ if (sendChunk && !sentChunk) { -+ this.sendQueue.enqueue(chunk); -+ } -+ break; -+ } -+ default: { -+ throw new IllegalStateException("Unknown stage: " + stage); -+ } -+ } -+ } -+ -+ // update the chunk center -+ // this must be done last so that the client does not ignore any of our unload chunk packets above -+ if (this.lastSentChunkCenterX != currentChunkX || this.lastSentChunkCenterZ != currentChunkZ) { -+ this.player.connection.send(this.updateClientChunkCenter(currentChunkX, currentChunkZ)); -+ } -+ -+ this.flushDelayedTicketOps(); -+ } -+ -+ void remove() { -+ TickThread.ensureTickThread(this.player, "Cannot add player asynchronously"); -+ if (this.removed) { -+ throw new IllegalStateException("Removing removed player chunk loader"); -+ } -+ this.removed = true; -+ // sends the chunk unload packets -+ this.broadcastMap.remove(); -+ // cleans up loading/generating tickets -+ this.loadTicketCleanup.remove(); -+ // cleans up ticking tickets -+ this.tickMap.remove(); -+ -+ // purge queues -+ this.sendQueue.clear(); -+ this.tickingQueue.clear(); -+ this.generatingQueue.clear(); -+ this.genQueue.clear(); -+ this.loadingQueue.clear(); -+ this.loadQueue.clear(); -+ -+ // flush ticket changes -+ this.flushDelayedTicketOps(); -+ -+ // now all tickets should be removed, which is all of our external state -+ } -+ } -+ -+ // TODO rebase into util patch -+ private static final class AllocatingRateLimiter { -+ -+ // max difference granularity in ns -+ private static final long MAX_GRANULARITY = TimeUnit.SECONDS.toNanos(1L); -+ -+ private double allocation; -+ private long lastAllocationUpdate; -+ private double takeCarry; -+ private long lastTakeUpdate; -+ -+ // rate in units/s, and time in ns -+ public void tickAllocation(final long time, final double rate, final double maxAllocation) { -+ final long diff = Math.min(MAX_GRANULARITY, time - this.lastAllocationUpdate); -+ this.lastAllocationUpdate = time; -+ -+ this.allocation = Math.min(maxAllocation - this.takeCarry, this.allocation + rate * (diff*1.0E-9D)); -+ } -+ -+ // rate in units/s, and time in ns -+ public long takeAllocation(final long time, final double rate, final long maxTake) { -+ if (maxTake < 1L) { -+ return 0L; -+ } -+ -+ double ret = this.takeCarry; -+ final long diff = Math.min(MAX_GRANULARITY, time - this.lastTakeUpdate); -+ this.lastTakeUpdate = time; -+ -+ // note: abs(takeCarry) <= 1.0 -+ final double take = Math.min(Math.min((double)maxTake - this.takeCarry, this.allocation), rate * (diff*1.0E-9)); -+ -+ ret += take; -+ this.allocation -= take; -+ -+ final long retInteger = (long)Math.floor(ret); -+ this.takeCarry = ret - (double)retInteger; -+ -+ return retInteger; -+ } -+ } -+ -+ static final class CountedSRSWLinkedQueue { -+ -+ private final SRSWLinkedQueue queue = new SRSWLinkedQueue<>(); -+ private volatile long countAdded; -+ private volatile long countRemoved; -+ -+ private static final VarHandle COUNT_ADDED_HANDLE = ConcurrentUtil.getVarHandle(CountedSRSWLinkedQueue.class, "countAdded", long.class); -+ private static final VarHandle COUNT_REMOVED_HANDLE = ConcurrentUtil.getVarHandle(CountedSRSWLinkedQueue.class, "countRemoved", long.class); -+ -+ private long getCountAddedPlain() { -+ return (long)COUNT_ADDED_HANDLE.get(this); -+ } -+ -+ private long getCountAddedAcquire() { -+ return (long)COUNT_ADDED_HANDLE.getAcquire(this); -+ } -+ -+ private void setCountAddedRelease(final long to) { -+ COUNT_ADDED_HANDLE.setRelease(this, to); -+ } -+ -+ private long getCountRemovedPlain() { -+ return (long)COUNT_REMOVED_HANDLE.get(this); -+ } -+ -+ private long getCountRemovedAcquire() { -+ return (long)COUNT_REMOVED_HANDLE.getAcquire(this); -+ } -+ -+ private void setCountRemovedRelease(final long to) { -+ COUNT_REMOVED_HANDLE.setRelease(this, to); -+ } -+ -+ public void add(final E element) { -+ this.setCountAddedRelease(this.getCountAddedPlain() + 1L); -+ this.queue.addLast(element); -+ } -+ -+ public E poll() { -+ final E ret = this.queue.poll(); -+ if (ret != null) { -+ this.setCountRemovedRelease(this.getCountRemovedPlain() + 1L); -+ } -+ -+ return ret; -+ } -+ -+ public long size() { -+ final long removed = this.getCountRemovedAcquire(); -+ final long added = this.getCountAddedAcquire(); -+ -+ return added - removed; -+ } -+ } -+ -+ private static class CustomLongArray extends LongArrayList { -+ -+ public CustomLongArray() { -+ super(); -+ } -+ -+ public CustomLongArray(final int expected) { -+ super(expected); -+ } -+ -+ public boolean addAll(final CustomLongArray list) { -+ this.addElements(this.size, list.a, 0, list.size); -+ return list.size != 0; -+ } -+ -+ public void addUnchecked(final long value) { -+ this.a[this.size++] = value; -+ } -+ -+ public void forceSize(final int to) { -+ this.size = to; -+ } -+ -+ @Override -+ public int hashCode() { -+ long h = 1L; -+ -+ Objects.checkFromToIndex(0, this.size, this.a.length); -+ -+ for (int i = 0; i < this.size; ++i) { -+ h = it.unimi.dsi.fastutil.HashCommon.mix(h + this.a[i]); -+ } -+ -+ return (int)h; -+ } -+ -+ @Override -+ public boolean equals(final Object o) { -+ if (o == this) { -+ return true; -+ } -+ -+ if (!(o instanceof CustomLongArray other)) { -+ return false; -+ } -+ -+ return this.size == other.size && Arrays.equals(this.a, 0, this.size, other.a, 0, this.size); -+ } -+ } -+ -+ private static int getDistanceSize(final int radius, final int max) { -+ if (radius == 0) { -+ return 1; -+ } -+ final int diff = radius - max; -+ if (diff <= 0) { -+ return 4*radius; -+ } -+ return 4*(max - Math.max(0, diff - 1)); -+ } -+ -+ private static int getQ1DistanceSize(final int radius, final int max) { -+ if (radius == 0) { -+ return 1; -+ } -+ final int diff = radius - max; -+ if (diff <= 0) { -+ return radius+1; -+ } -+ return max - diff + 1; -+ } -+ -+ private static final class BasicFIFOLQueue { -+ -+ private final long[] values; -+ private int head, tail; -+ -+ public BasicFIFOLQueue(final int cap) { -+ if (cap <= 1) { -+ throw new IllegalArgumentException(); -+ } -+ this.values = new long[cap]; -+ } -+ -+ public boolean isEmpty() { -+ return this.head == this.tail; -+ } -+ -+ public long removeFirst() { -+ final long ret = this.values[this.head]; -+ -+ if (this.head == this.tail) { -+ throw new IllegalStateException(); -+ } -+ -+ ++this.head; -+ if (this.head == this.values.length) { -+ this.head = 0; -+ } -+ -+ return ret; -+ } -+ -+ public void addLast(final long value) { -+ this.values[this.tail++] = value; -+ -+ if (this.tail == this.head) { -+ throw new IllegalStateException(); -+ } -+ -+ if (this.tail == this.values.length) { -+ this.tail = 0; -+ } -+ } -+ } -+ -+ private static CustomLongArray[] makeQ1BFS(final int radius) { -+ final CustomLongArray[] ret = new CustomLongArray[2 * radius + 1]; -+ final BasicFIFOLQueue queue = new BasicFIFOLQueue(Math.max(1, 4 * radius) + 1); -+ final LongOpenHashSet seen = new LongOpenHashSet((radius + 1) * (radius + 1)); -+ -+ seen.add(CoordinateUtils.getChunkKey(0, 0)); -+ queue.addLast(CoordinateUtils.getChunkKey(0, 0)); -+ while (!queue.isEmpty()) { -+ final long chunk = queue.removeFirst(); -+ final int chunkX = CoordinateUtils.getChunkX(chunk); -+ final int chunkZ = CoordinateUtils.getChunkZ(chunk); -+ -+ final int index = Math.abs(chunkX) + Math.abs(chunkZ); -+ final CustomLongArray list = ret[index]; -+ if (list != null) { -+ list.addUnchecked(chunk); -+ } else { -+ (ret[index] = new CustomLongArray(getQ1DistanceSize(index, radius))).addUnchecked(chunk); -+ } -+ -+ for (int i = 0; i < 4; ++i) { -+ // 0 -> -1, 0 -+ // 1 -> 0, -1 -+ // 2 -> 1, 0 -+ // 3 -> 0, 1 -+ -+ final int signInv = -(i >>> 1); // 2/3 -> -(1), 0/1 -> -(0) -+ // note: -n = (~n) + 1 -+ // (n ^ signInv) - signInv = signInv == 0 ? ((n ^ 0) - 0 = n) : ((n ^ -1) - (-1) = ~n + 1) -+ -+ final int axis = i & 1; // 0/2 -> 0, 1/3 -> 1 -+ final int dx = ((axis - 1) ^ signInv) - signInv; // 0 -> -1, 1 -> 0 -+ final int dz = (-axis ^ signInv) - signInv; // 0 -> 0, 1 -> -1 -+ -+ final int neighbourX = chunkX + dx; -+ final int neighbourZ = chunkZ + dz; -+ final long neighbour = CoordinateUtils.getChunkKey(neighbourX, neighbourZ); -+ -+ if ((neighbourX | neighbourZ) < 0 || Math.max(Math.abs(neighbourX), Math.abs(neighbourZ)) > radius) { -+ // don't enqueue out of range -+ continue; -+ } -+ -+ if (!seen.add(neighbour)) { -+ continue; -+ } -+ -+ queue.addLast(neighbour); -+ } -+ } -+ -+ return ret; -+ } -+ -+ // doesn't appear worth optimising this function now, even though it's 70% of the call -+ private static CustomLongArray spread(final CustomLongArray input, final int size) { -+ final LongLinkedOpenHashSet notAdded = new LongLinkedOpenHashSet(input); -+ final CustomLongArray added = new CustomLongArray(size); -+ -+ while (!notAdded.isEmpty()) { -+ if (added.isEmpty()) { -+ added.addUnchecked(notAdded.removeLastLong()); -+ continue; -+ } -+ -+ long maxChunk = -1L; -+ int maxDist = 0; -+ -+ // select the chunk from the not yet added set that has the largest minimum distance from -+ // the current set of added chunks -+ -+ for (final LongIterator iterator = notAdded.iterator(); iterator.hasNext();) { -+ final long chunkKey = iterator.nextLong(); -+ final int chunkX = CoordinateUtils.getChunkX(chunkKey); -+ final int chunkZ = CoordinateUtils.getChunkZ(chunkKey); -+ -+ int minDist = Integer.MAX_VALUE; -+ -+ final int len = added.size(); -+ final long[] addedArr = added.elements(); -+ Objects.checkFromToIndex(0, len, addedArr.length); -+ for (int i = 0; i < len; ++i) { -+ final long addedKey = addedArr[i]; -+ final int addedX = CoordinateUtils.getChunkX(addedKey); -+ final int addedZ = CoordinateUtils.getChunkZ(addedKey); -+ -+ // here we use square distance because chunk generation uses neighbours in a square radius -+ final int dist = Math.max(Math.abs(addedX - chunkX), Math.abs(addedZ - chunkZ)); -+ -+ minDist = Math.min(dist, minDist); -+ } -+ -+ if (minDist > maxDist) { -+ maxDist = minDist; -+ maxChunk = chunkKey; -+ } -+ } -+ -+ // move the selected chunk from the not added set to the added set -+ -+ if (!notAdded.remove(maxChunk)) { -+ throw new IllegalStateException(); -+ } -+ -+ added.addUnchecked(maxChunk); -+ } -+ -+ return added; -+ } -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java b/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java -new file mode 100644 -index 0000000000000000000000000000000000000000..15ee41452992714108efe53b708b5a4e1da7c1ff ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java -@@ -0,0 +1,902 @@ -+package io.papermc.paper.chunk.system.entity; -+ -+import com.destroystokyo.paper.util.maplist.EntityList; -+import com.mojang.logging.LogUtils; -+import io.papermc.paper.util.CoordinateUtils; -+import io.papermc.paper.util.TickThread; -+import io.papermc.paper.util.WorldUtil; -+import io.papermc.paper.world.ChunkEntitySlices; -+import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap; -+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -+import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; -+import net.minecraft.core.BlockPos; -+import io.papermc.paper.chunk.system.ChunkSystem; -+import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.util.AbortableIterationConsumer; -+import net.minecraft.util.Mth; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.entity.EntityType; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.entity.EntityInLevelCallback; -+import net.minecraft.world.level.entity.EntityTypeTest; -+import net.minecraft.world.level.entity.LevelCallback; -+import net.minecraft.server.level.FullChunkStatus; -+import net.minecraft.world.level.entity.LevelEntityGetter; -+import net.minecraft.world.level.entity.Visibility; -+import net.minecraft.world.phys.AABB; -+import net.minecraft.world.phys.Vec3; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+import org.slf4j.Logger; -+import java.util.ArrayList; -+import java.util.Arrays; -+import java.util.Iterator; -+import java.util.List; -+import java.util.NoSuchElementException; -+import java.util.UUID; -+import java.util.concurrent.locks.StampedLock; -+import java.util.function.Consumer; -+import java.util.function.Predicate; -+ -+public final class EntityLookup implements LevelEntityGetter { -+ -+ private static final Logger LOGGER = LogUtils.getClassLogger(); -+ -+ protected static final int REGION_SHIFT = 5; -+ protected static final int REGION_MASK = (1 << REGION_SHIFT) - 1; -+ protected static final int REGION_SIZE = 1 << REGION_SHIFT; -+ -+ public final ServerLevel world; -+ -+ private final StampedLock stateLock = new StampedLock(); -+ protected final Long2ObjectOpenHashMap regions = new Long2ObjectOpenHashMap<>(128, 0.5f); -+ -+ private final int minSection; // inclusive -+ private final int maxSection; // inclusive -+ private final LevelCallback worldCallback; -+ -+ private final StampedLock entityByLock = new StampedLock(); -+ private final Int2ReferenceOpenHashMap entityById = new Int2ReferenceOpenHashMap<>(); -+ private final Object2ReferenceOpenHashMap entityByUUID = new Object2ReferenceOpenHashMap<>(); -+ private final EntityList accessibleEntities = new EntityList(); -+ -+ public EntityLookup(final ServerLevel world, final LevelCallback worldCallback) { -+ this.world = world; -+ this.minSection = WorldUtil.getMinSection(world); -+ this.maxSection = WorldUtil.getMaxSection(world); -+ this.worldCallback = worldCallback; -+ } -+ -+ private static Entity maskNonAccessible(final Entity entity) { -+ if (entity == null) { -+ return null; -+ } -+ final Visibility visibility = EntityLookup.getEntityStatus(entity); -+ return visibility.isAccessible() ? entity : null; -+ } -+ -+ @Nullable -+ @Override -+ public Entity get(final int id) { -+ final long attempt = this.entityByLock.tryOptimisticRead(); -+ if (attempt != 0L) { -+ try { -+ final Entity ret = this.entityById.get(id); -+ -+ if (this.entityByLock.validate(attempt)) { -+ return maskNonAccessible(ret); -+ } -+ } catch (final Error error) { -+ throw error; -+ } catch (final Throwable thr) { -+ // ignore -+ } -+ } -+ -+ this.entityByLock.readLock(); -+ try { -+ return maskNonAccessible(this.entityById.get(id)); -+ } finally { -+ this.entityByLock.tryUnlockRead(); -+ } -+ } -+ -+ @Nullable -+ @Override -+ public Entity get(final UUID id) { -+ final long attempt = this.entityByLock.tryOptimisticRead(); -+ if (attempt != 0L) { -+ try { -+ final Entity ret = this.entityByUUID.get(id); -+ -+ if (this.entityByLock.validate(attempt)) { -+ return maskNonAccessible(ret); -+ } -+ } catch (final Error error) { -+ throw error; -+ } catch (final Throwable thr) { -+ // ignore -+ } -+ } -+ -+ this.entityByLock.readLock(); -+ try { -+ return maskNonAccessible(this.entityByUUID.get(id)); -+ } finally { -+ this.entityByLock.tryUnlockRead(); -+ } -+ } -+ -+ public boolean hasEntity(final UUID uuid) { -+ return this.get(uuid) != null; -+ } -+ -+ public String getDebugInfo() { -+ return "count_id:" + this.entityById.size() + ",count_uuid:" + this.entityByUUID.size() + ",region_count:" + this.regions.size(); -+ } -+ -+ static final class ArrayIterable implements Iterable { -+ -+ private final T[] array; -+ private final int off; -+ private final int length; -+ -+ public ArrayIterable(final T[] array, final int off, final int length) { -+ this.array = array; -+ this.off = off; -+ this.length = length; -+ if (length > array.length) { -+ throw new IllegalArgumentException("Length must be no greater-than the array length"); -+ } -+ } -+ -+ @NotNull -+ @Override -+ public Iterator iterator() { -+ return new ArrayIterator<>(this.array, this.off, this.length); -+ } -+ -+ static final class ArrayIterator implements Iterator { -+ -+ private final T[] array; -+ private int off; -+ private final int length; -+ -+ public ArrayIterator(final T[] array, final int off, final int length) { -+ this.array = array; -+ this.off = off; -+ this.length = length; -+ } -+ -+ @Override -+ public boolean hasNext() { -+ return this.off < this.length; -+ } -+ -+ @Override -+ public T next() { -+ if (this.off >= this.length) { -+ throw new NoSuchElementException(); -+ } -+ return this.array[this.off++]; -+ } -+ -+ @Override -+ public void remove() { -+ throw new UnsupportedOperationException(); -+ } -+ } -+ } -+ -+ @Override -+ public Iterable getAll() { -+ return new ArrayIterable<>(this.accessibleEntities.getRawData(), 0, this.accessibleEntities.size()); -+ } -+ -+ public Entity[] getAllCopy() { -+ return Arrays.copyOf(this.accessibleEntities.getRawData(), this.accessibleEntities.size(), Entity[].class); -+ } -+ -+ @Override -+ public void get(final EntityTypeTest filter, final AbortableIterationConsumer action) { -+ final Int2ReferenceOpenHashMap entityCopy; -+ -+ this.entityByLock.readLock(); -+ try { -+ entityCopy = this.entityById.clone(); -+ } finally { -+ this.entityByLock.tryUnlockRead(); -+ } -+ for (final Entity entity : entityCopy.values()) { -+ final Visibility visibility = EntityLookup.getEntityStatus(entity); -+ if (!visibility.isAccessible()) { -+ continue; -+ } -+ final U casted = filter.tryCast(entity); -+ if (casted != null && action.accept(casted).shouldAbort()) { -+ break; -+ } -+ } -+ } -+ -+ @Override -+ public void get(final AABB box, final Consumer action) { -+ List entities = new ArrayList<>(); -+ this.getEntitiesWithoutDragonParts(null, box, entities, null); -+ for (int i = 0, len = entities.size(); i < len; ++i) { -+ action.accept(entities.get(i)); -+ } -+ } -+ -+ @Override -+ public void get(final EntityTypeTest filter, final AABB box, final AbortableIterationConsumer action) { -+ List entities = new ArrayList<>(); -+ this.getEntitiesWithoutDragonParts(null, box, entities, null); -+ for (int i = 0, len = entities.size(); i < len; ++i) { -+ final U casted = filter.tryCast(entities.get(i)); -+ if (casted != null && action.accept(casted).shouldAbort()) { -+ break; -+ } -+ } -+ } -+ -+ public void entityStatusChange(final Entity entity, final ChunkEntitySlices slices, final Visibility oldVisibility, final Visibility newVisibility, final boolean moved, -+ final boolean created, final boolean destroyed) { -+ TickThread.ensureTickThread(entity, "Entity status change must only happen on the main thread"); -+ -+ if (entity.updatingSectionStatus) { -+ // recursive status update -+ LOGGER.error("Cannot recursively update entity chunk status for entity " + entity, new Throwable()); -+ return; -+ } -+ -+ final boolean entityStatusUpdateBefore = slices == null ? false : slices.startPreventingStatusUpdates(); -+ -+ if (entityStatusUpdateBefore) { -+ LOGGER.error("Cannot update chunk status for entity " + entity + " since entity chunk (" + slices.chunkX + "," + slices.chunkZ + ") is receiving update", new Throwable()); -+ return; -+ } -+ -+ try { -+ final Boolean ticketBlockBefore = this.world.chunkTaskScheduler.chunkHolderManager.blockTicketUpdates(); -+ try { -+ entity.updatingSectionStatus = true; -+ try { -+ if (created) { -+ EntityLookup.this.worldCallback.onCreated(entity); -+ } -+ -+ if (oldVisibility == newVisibility) { -+ if (moved && newVisibility.isAccessible()) { -+ EntityLookup.this.worldCallback.onSectionChange(entity); -+ } -+ return; -+ } -+ -+ if (newVisibility.ordinal() > oldVisibility.ordinal()) { -+ // status upgrade -+ if (!oldVisibility.isAccessible() && newVisibility.isAccessible()) { -+ this.accessibleEntities.add(entity); -+ EntityLookup.this.worldCallback.onTrackingStart(entity); -+ } -+ -+ if (!oldVisibility.isTicking() && newVisibility.isTicking()) { -+ EntityLookup.this.worldCallback.onTickingStart(entity); -+ } -+ } else { -+ // status downgrade -+ if (oldVisibility.isTicking() && !newVisibility.isTicking()) { -+ EntityLookup.this.worldCallback.onTickingEnd(entity); -+ } -+ -+ if (oldVisibility.isAccessible() && !newVisibility.isAccessible()) { -+ this.accessibleEntities.remove(entity); -+ EntityLookup.this.worldCallback.onTrackingEnd(entity); -+ } -+ } -+ -+ if (moved && newVisibility.isAccessible()) { -+ EntityLookup.this.worldCallback.onSectionChange(entity); -+ } -+ -+ if (destroyed) { -+ EntityLookup.this.worldCallback.onDestroyed(entity); -+ } -+ } finally { -+ entity.updatingSectionStatus = false; -+ } -+ } finally { -+ this.world.chunkTaskScheduler.chunkHolderManager.unblockTicketUpdates(ticketBlockBefore); -+ } -+ } finally { -+ if (slices != null) { -+ slices.stopPreventingStatusUpdates(false); -+ } -+ } -+ } -+ -+ public void chunkStatusChange(final int x, final int z, final FullChunkStatus newStatus) { -+ this.getChunk(x, z).updateStatus(newStatus, this); -+ } -+ -+ public void addLegacyChunkEntities(final List entities, final ChunkPos forChunk) { -+ this.addEntityChunk(entities, forChunk, true); -+ } -+ -+ public void addEntityChunkEntities(final List entities, final ChunkPos forChunk) { -+ this.addEntityChunk(entities, forChunk, true); -+ } -+ -+ public void addWorldGenChunkEntities(final List entities, final ChunkPos forChunk) { -+ this.addEntityChunk(entities, forChunk, false); -+ } -+ -+ private void addRecursivelySafe(final Entity root, final boolean fromDisk) { -+ if (!this.addEntity(root, fromDisk)) { -+ // possible we are a passenger, and so should dismount from any valid entity in the world -+ root.stopRiding(true); -+ return; -+ } -+ for (final Entity passenger : root.getPassengers()) { -+ this.addRecursivelySafe(passenger, fromDisk); -+ } -+ } -+ -+ private void addEntityChunk(final List entities, final ChunkPos forChunk, final boolean fromDisk) { -+ for (int i = 0, len = entities.size(); i < len; ++i) { -+ final Entity entity = entities.get(i); -+ if (entity.isPassenger()) { -+ continue; -+ } -+ -+ if (!entity.chunkPosition().equals(forChunk)) { -+ LOGGER.warn("Root entity " + entity + " is outside of serialized chunk " + forChunk); -+ // can't set removed here, as we may not own the chunk position -+ // skip the entity -+ continue; -+ } -+ -+ final Vec3 rootPosition = entity.position(); -+ -+ // always adjust positions before adding passengers in case plugins access the entity, and so that -+ // they are added to the right entity chunk -+ for (final Entity passenger : entity.getIndirectPassengers()) { -+ if (!passenger.chunkPosition().equals(forChunk)) { -+ passenger.setPosRaw(rootPosition.x, rootPosition.y, rootPosition.z, true); -+ } -+ } -+ -+ this.addRecursivelySafe(entity, fromDisk); -+ } -+ } -+ -+ public boolean addNewEntity(final Entity entity) { -+ return this.addEntity(entity, false); -+ } -+ -+ public static Visibility getEntityStatus(final Entity entity) { -+ if (entity.isAlwaysTicking()) { -+ return Visibility.TICKING; -+ } -+ final FullChunkStatus entityStatus = entity.chunkStatus; -+ return Visibility.fromFullChunkStatus(entityStatus == null ? FullChunkStatus.INACCESSIBLE : entityStatus); -+ } -+ -+ private boolean addEntity(final Entity entity, final boolean fromDisk) { -+ final BlockPos pos = entity.blockPosition(); -+ final int sectionX = pos.getX() >> 4; -+ final int sectionY = Mth.clamp(pos.getY() >> 4, this.minSection, this.maxSection); -+ final int sectionZ = pos.getZ() >> 4; -+ TickThread.ensureTickThread(this.world, sectionX, sectionZ, "Cannot add entity off-main thread"); -+ -+ if (entity.isRemoved()) { -+ LOGGER.warn("Refusing to add removed entity: " + entity); -+ return false; -+ } -+ -+ if (entity.updatingSectionStatus) { -+ LOGGER.warn("Entity " + entity + " is currently prevented from being added/removed to world since it is processing section status updates", new Throwable()); -+ return false; -+ } -+ -+ if (fromDisk) { -+ ChunkSystem.onEntityPreAdd(this.world, entity); -+ if (entity.isRemoved()) { -+ // removed from checkDupeUUID call -+ return false; -+ } -+ } -+ -+ this.entityByLock.writeLock(); -+ try { -+ if (this.entityById.containsKey(entity.getId())) { -+ LOGGER.warn("Entity id already exists: " + entity.getId() + ", mapped to " + this.entityById.get(entity.getId()) + ", can't add " + entity); -+ return false; -+ } -+ if (this.entityByUUID.containsKey(entity.getUUID())) { -+ LOGGER.warn("Entity uuid already exists: " + entity.getUUID() + ", mapped to " + this.entityByUUID.get(entity.getUUID()) + ", can't add " + entity); -+ return false; -+ } -+ this.entityById.put(entity.getId(), entity); -+ this.entityByUUID.put(entity.getUUID(), entity); -+ } finally { -+ this.entityByLock.tryUnlockWrite(); -+ } -+ -+ entity.sectionX = sectionX; -+ entity.sectionY = sectionY; -+ entity.sectionZ = sectionZ; -+ final ChunkEntitySlices slices = this.getOrCreateChunk(sectionX, sectionZ); -+ if (!slices.addEntity(entity, sectionY)) { -+ LOGGER.warn("Entity " + entity + " added to world '" + this.world.getWorld().getName() + "', but was already contained in entity chunk (" + sectionX + "," + sectionZ + ")"); -+ } -+ -+ entity.setLevelCallback(new EntityCallback(entity)); -+ -+ this.entityStatusChange(entity, slices, Visibility.HIDDEN, getEntityStatus(entity), false, !fromDisk, false); -+ -+ return true; -+ } -+ -+ public boolean canRemoveEntity(final Entity entity) { -+ if (entity.updatingSectionStatus) { -+ return false; -+ } -+ -+ final int sectionX = entity.sectionX; -+ final int sectionZ = entity.sectionZ; -+ final ChunkEntitySlices slices = this.getChunk(sectionX, sectionZ); -+ return slices == null || !slices.isPreventingStatusUpdates(); -+ } -+ -+ private void removeEntity(final Entity entity) { -+ final int sectionX = entity.sectionX; -+ final int sectionY = entity.sectionY; -+ final int sectionZ = entity.sectionZ; -+ TickThread.ensureTickThread(this.world, sectionX, sectionZ, "Cannot remove entity off-main"); -+ if (!entity.isRemoved()) { -+ throw new IllegalStateException("Only call Entity#setRemoved to remove an entity"); -+ } -+ final ChunkEntitySlices slices = this.getChunk(sectionX, sectionZ); -+ // all entities should be in a chunk -+ if (slices == null) { -+ LOGGER.warn("Cannot remove entity " + entity + " from null entity slices (" + sectionX + "," + sectionZ + ")"); -+ } else { -+ if (slices.isPreventingStatusUpdates()) { -+ throw new IllegalStateException("Attempting to remove entity " + entity + " from entity slices (" + sectionX + "," + sectionZ + ") that is receiving status updates"); -+ } -+ if (!slices.removeEntity(entity, sectionY)) { -+ LOGGER.warn("Failed to remove entity " + entity + " from entity slices (" + sectionX + "," + sectionZ + ")"); -+ } -+ } -+ entity.sectionX = entity.sectionY = entity.sectionZ = Integer.MIN_VALUE; -+ -+ this.entityByLock.writeLock(); -+ try { -+ if (!this.entityById.remove(entity.getId(), entity)) { -+ LOGGER.warn("Failed to remove entity " + entity + " by id, current entity mapped: " + this.entityById.get(entity.getId())); -+ } -+ if (!this.entityByUUID.remove(entity.getUUID(), entity)) { -+ LOGGER.warn("Failed to remove entity " + entity + " by uuid, current entity mapped: " + this.entityByUUID.get(entity.getUUID())); -+ } -+ } finally { -+ this.entityByLock.tryUnlockWrite(); -+ } -+ } -+ -+ private ChunkEntitySlices moveEntity(final Entity entity) { -+ // ensure we own the entity -+ TickThread.ensureTickThread(entity, "Cannot move entity off-main"); -+ -+ final BlockPos newPos = entity.blockPosition(); -+ final int newSectionX = newPos.getX() >> 4; -+ final int newSectionY = Mth.clamp(newPos.getY() >> 4, this.minSection, this.maxSection); -+ final int newSectionZ = newPos.getZ() >> 4; -+ -+ if (newSectionX == entity.sectionX && newSectionY == entity.sectionY && newSectionZ == entity.sectionZ) { -+ return null; -+ } -+ -+ // ensure the new section is owned by this tick thread -+ TickThread.ensureTickThread(this.world, newSectionX, newSectionZ, "Cannot move entity off-main"); -+ -+ // ensure the old section is owned by this tick thread -+ TickThread.ensureTickThread(this.world, entity.sectionX, entity.sectionZ, "Cannot move entity off-main"); -+ -+ final ChunkEntitySlices old = this.getChunk(entity.sectionX, entity.sectionZ); -+ final ChunkEntitySlices slices = this.getOrCreateChunk(newSectionX, newSectionZ); -+ -+ if (!old.removeEntity(entity, entity.sectionY)) { -+ LOGGER.warn("Could not remove entity " + entity + " from its old chunk section (" + entity.sectionX + "," + entity.sectionY + "," + entity.sectionZ + ") since it was not contained in the section"); -+ } -+ -+ if (!slices.addEntity(entity, newSectionY)) { -+ LOGGER.warn("Could not add entity " + entity + " to its new chunk section (" + newSectionX + "," + newSectionY + "," + newSectionZ + ") as it is already contained in the section"); -+ } -+ -+ entity.sectionX = newSectionX; -+ entity.sectionY = newSectionY; -+ entity.sectionZ = newSectionZ; -+ -+ return slices; -+ } -+ -+ public void getEntitiesWithoutDragonParts(final Entity except, final AABB box, final List into, final Predicate predicate) { -+ final int minChunkX = (Mth.floor(box.minX) - 2) >> 4; -+ final int minChunkZ = (Mth.floor(box.minZ) - 2) >> 4; -+ final int maxChunkX = (Mth.floor(box.maxX) + 2) >> 4; -+ final int maxChunkZ = (Mth.floor(box.maxZ) + 2) >> 4; -+ -+ final int minRegionX = minChunkX >> REGION_SHIFT; -+ final int minRegionZ = minChunkZ >> REGION_SHIFT; -+ final int maxRegionX = maxChunkX >> REGION_SHIFT; -+ final int maxRegionZ = maxChunkZ >> REGION_SHIFT; -+ -+ for (int currRegionZ = minRegionZ; currRegionZ <= maxRegionZ; ++currRegionZ) { -+ final int minZ = currRegionZ == minRegionZ ? minChunkZ & REGION_MASK : 0; -+ final int maxZ = currRegionZ == maxRegionZ ? maxChunkZ & REGION_MASK : REGION_MASK; -+ -+ for (int currRegionX = minRegionX; currRegionX <= maxRegionX; ++currRegionX) { -+ final ChunkSlicesRegion region = this.getRegion(currRegionX, currRegionZ); -+ -+ if (region == null) { -+ continue; -+ } -+ -+ final int minX = currRegionX == minRegionX ? minChunkX & REGION_MASK : 0; -+ final int maxX = currRegionX == maxRegionX ? maxChunkX & REGION_MASK : REGION_MASK; -+ -+ for (int currZ = minZ; currZ <= maxZ; ++currZ) { -+ for (int currX = minX; currX <= maxX; ++currX) { -+ final ChunkEntitySlices chunk = region.get(currX | (currZ << REGION_SHIFT)); -+ if (chunk == null || !chunk.status.isOrAfter(FullChunkStatus.FULL)) { -+ continue; -+ } -+ -+ chunk.getEntitiesWithoutDragonParts(except, box, into, predicate); -+ } -+ } -+ } -+ } -+ } -+ -+ public void getEntities(final Entity except, final AABB box, final List into, final Predicate predicate) { -+ final int minChunkX = (Mth.floor(box.minX) - 2) >> 4; -+ final int minChunkZ = (Mth.floor(box.minZ) - 2) >> 4; -+ final int maxChunkX = (Mth.floor(box.maxX) + 2) >> 4; -+ final int maxChunkZ = (Mth.floor(box.maxZ) + 2) >> 4; -+ -+ final int minRegionX = minChunkX >> REGION_SHIFT; -+ final int minRegionZ = minChunkZ >> REGION_SHIFT; -+ final int maxRegionX = maxChunkX >> REGION_SHIFT; -+ final int maxRegionZ = maxChunkZ >> REGION_SHIFT; -+ -+ for (int currRegionZ = minRegionZ; currRegionZ <= maxRegionZ; ++currRegionZ) { -+ final int minZ = currRegionZ == minRegionZ ? minChunkZ & REGION_MASK : 0; -+ final int maxZ = currRegionZ == maxRegionZ ? maxChunkZ & REGION_MASK : REGION_MASK; -+ -+ for (int currRegionX = minRegionX; currRegionX <= maxRegionX; ++currRegionX) { -+ final ChunkSlicesRegion region = this.getRegion(currRegionX, currRegionZ); -+ -+ if (region == null) { -+ continue; -+ } -+ -+ final int minX = currRegionX == minRegionX ? minChunkX & REGION_MASK : 0; -+ final int maxX = currRegionX == maxRegionX ? maxChunkX & REGION_MASK : REGION_MASK; -+ -+ for (int currZ = minZ; currZ <= maxZ; ++currZ) { -+ for (int currX = minX; currX <= maxX; ++currX) { -+ final ChunkEntitySlices chunk = region.get(currX | (currZ << REGION_SHIFT)); -+ if (chunk == null || !chunk.status.isOrAfter(FullChunkStatus.FULL)) { -+ continue; -+ } -+ -+ chunk.getEntities(except, box, into, predicate); -+ } -+ } -+ } -+ } -+ } -+ -+ public void getHardCollidingEntities(final Entity except, final AABB box, final List into, final Predicate predicate) { -+ final int minChunkX = (Mth.floor(box.minX) - 2) >> 4; -+ final int minChunkZ = (Mth.floor(box.minZ) - 2) >> 4; -+ final int maxChunkX = (Mth.floor(box.maxX) + 2) >> 4; -+ final int maxChunkZ = (Mth.floor(box.maxZ) + 2) >> 4; -+ -+ final int minRegionX = minChunkX >> REGION_SHIFT; -+ final int minRegionZ = minChunkZ >> REGION_SHIFT; -+ final int maxRegionX = maxChunkX >> REGION_SHIFT; -+ final int maxRegionZ = maxChunkZ >> REGION_SHIFT; -+ -+ for (int currRegionZ = minRegionZ; currRegionZ <= maxRegionZ; ++currRegionZ) { -+ final int minZ = currRegionZ == minRegionZ ? minChunkZ & REGION_MASK : 0; -+ final int maxZ = currRegionZ == maxRegionZ ? maxChunkZ & REGION_MASK : REGION_MASK; -+ -+ for (int currRegionX = minRegionX; currRegionX <= maxRegionX; ++currRegionX) { -+ final ChunkSlicesRegion region = this.getRegion(currRegionX, currRegionZ); -+ -+ if (region == null) { -+ continue; -+ } -+ -+ final int minX = currRegionX == minRegionX ? minChunkX & REGION_MASK : 0; -+ final int maxX = currRegionX == maxRegionX ? maxChunkX & REGION_MASK : REGION_MASK; -+ -+ for (int currZ = minZ; currZ <= maxZ; ++currZ) { -+ for (int currX = minX; currX <= maxX; ++currX) { -+ final ChunkEntitySlices chunk = region.get(currX | (currZ << REGION_SHIFT)); -+ if (chunk == null || !chunk.status.isOrAfter(FullChunkStatus.FULL)) { -+ continue; -+ } -+ -+ chunk.getHardCollidingEntities(except, box, into, predicate); -+ } -+ } -+ } -+ } -+ } -+ -+ public void getEntities(final EntityType type, final AABB box, final List into, -+ final Predicate predicate) { -+ final int minChunkX = (Mth.floor(box.minX) - 2) >> 4; -+ final int minChunkZ = (Mth.floor(box.minZ) - 2) >> 4; -+ final int maxChunkX = (Mth.floor(box.maxX) + 2) >> 4; -+ final int maxChunkZ = (Mth.floor(box.maxZ) + 2) >> 4; -+ -+ final int minRegionX = minChunkX >> REGION_SHIFT; -+ final int minRegionZ = minChunkZ >> REGION_SHIFT; -+ final int maxRegionX = maxChunkX >> REGION_SHIFT; -+ final int maxRegionZ = maxChunkZ >> REGION_SHIFT; -+ -+ for (int currRegionZ = minRegionZ; currRegionZ <= maxRegionZ; ++currRegionZ) { -+ final int minZ = currRegionZ == minRegionZ ? minChunkZ & REGION_MASK : 0; -+ final int maxZ = currRegionZ == maxRegionZ ? maxChunkZ & REGION_MASK : REGION_MASK; -+ -+ for (int currRegionX = minRegionX; currRegionX <= maxRegionX; ++currRegionX) { -+ final ChunkSlicesRegion region = this.getRegion(currRegionX, currRegionZ); -+ -+ if (region == null) { -+ continue; -+ } -+ -+ final int minX = currRegionX == minRegionX ? minChunkX & REGION_MASK : 0; -+ final int maxX = currRegionX == maxRegionX ? maxChunkX & REGION_MASK : REGION_MASK; -+ -+ for (int currZ = minZ; currZ <= maxZ; ++currZ) { -+ for (int currX = minX; currX <= maxX; ++currX) { -+ final ChunkEntitySlices chunk = region.get(currX | (currZ << REGION_SHIFT)); -+ if (chunk == null || !chunk.status.isOrAfter(FullChunkStatus.FULL)) { -+ continue; -+ } -+ -+ chunk.getEntities(type, box, (List)into, (Predicate)predicate); -+ } -+ } -+ } -+ } -+ } -+ -+ public void getEntities(final Class clazz, final Entity except, final AABB box, final List into, -+ final Predicate predicate) { -+ final int minChunkX = (Mth.floor(box.minX) - 2) >> 4; -+ final int minChunkZ = (Mth.floor(box.minZ) - 2) >> 4; -+ final int maxChunkX = (Mth.floor(box.maxX) + 2) >> 4; -+ final int maxChunkZ = (Mth.floor(box.maxZ) + 2) >> 4; -+ -+ final int minRegionX = minChunkX >> REGION_SHIFT; -+ final int minRegionZ = minChunkZ >> REGION_SHIFT; -+ final int maxRegionX = maxChunkX >> REGION_SHIFT; -+ final int maxRegionZ = maxChunkZ >> REGION_SHIFT; -+ -+ for (int currRegionZ = minRegionZ; currRegionZ <= maxRegionZ; ++currRegionZ) { -+ final int minZ = currRegionZ == minRegionZ ? minChunkZ & REGION_MASK : 0; -+ final int maxZ = currRegionZ == maxRegionZ ? maxChunkZ & REGION_MASK : REGION_MASK; -+ -+ for (int currRegionX = minRegionX; currRegionX <= maxRegionX; ++currRegionX) { -+ final ChunkSlicesRegion region = this.getRegion(currRegionX, currRegionZ); -+ -+ if (region == null) { -+ continue; -+ } -+ -+ final int minX = currRegionX == minRegionX ? minChunkX & REGION_MASK : 0; -+ final int maxX = currRegionX == maxRegionX ? maxChunkX & REGION_MASK : REGION_MASK; -+ -+ for (int currZ = minZ; currZ <= maxZ; ++currZ) { -+ for (int currX = minX; currX <= maxX; ++currX) { -+ final ChunkEntitySlices chunk = region.get(currX | (currZ << REGION_SHIFT)); -+ if (chunk == null || !chunk.status.isOrAfter(FullChunkStatus.FULL)) { -+ continue; -+ } -+ -+ chunk.getEntities(clazz, except, box, into, predicate); -+ } -+ } -+ } -+ } -+ } -+ -+ public void entitySectionLoad(final int chunkX, final int chunkZ, final ChunkEntitySlices slices) { -+ TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Cannot load in entity section off-main"); -+ synchronized (this) { -+ final ChunkEntitySlices curr = this.getChunk(chunkX, chunkZ); -+ if (curr != null) { -+ this.removeChunk(chunkX, chunkZ); -+ -+ curr.mergeInto(slices); -+ -+ this.addChunk(chunkX, chunkZ, slices); -+ } else { -+ this.addChunk(chunkX, chunkZ, slices); -+ } -+ } -+ } -+ -+ public void entitySectionUnload(final int chunkX, final int chunkZ) { -+ TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Cannot unload entity section off-main"); -+ this.removeChunk(chunkX, chunkZ); -+ } -+ -+ public ChunkEntitySlices getChunk(final int chunkX, final int chunkZ) { -+ final ChunkSlicesRegion region = this.getRegion(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT); -+ if (region == null) { -+ return null; -+ } -+ -+ return region.get((chunkX & REGION_MASK) | ((chunkZ & REGION_MASK) << REGION_SHIFT)); -+ } -+ -+ public ChunkEntitySlices getOrCreateChunk(final int chunkX, final int chunkZ) { -+ final ChunkSlicesRegion region = this.getRegion(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT); -+ ChunkEntitySlices ret; -+ if (region == null || (ret = region.get((chunkX & REGION_MASK) | ((chunkZ & REGION_MASK) << REGION_SHIFT))) == null) { -+ // loadInEntityChunk will call addChunk for us -+ return this.world.chunkTaskScheduler.chunkHolderManager.getOrCreateEntityChunk(chunkX, chunkZ, true); -+ } -+ -+ return ret; -+ } -+ -+ public ChunkSlicesRegion getRegion(final int regionX, final int regionZ) { -+ final long key = CoordinateUtils.getChunkKey(regionX, regionZ); -+ final long attempt = this.stateLock.tryOptimisticRead(); -+ if (attempt != 0L) { -+ try { -+ final ChunkSlicesRegion ret = this.regions.get(key); -+ -+ if (this.stateLock.validate(attempt)) { -+ return ret; -+ } -+ } catch (final Error error) { -+ throw error; -+ } catch (final Throwable thr) { -+ // ignore -+ } -+ } -+ -+ this.stateLock.readLock(); -+ try { -+ return this.regions.get(key); -+ } finally { -+ this.stateLock.tryUnlockRead(); -+ } -+ } -+ -+ private synchronized void removeChunk(final int chunkX, final int chunkZ) { -+ final long key = CoordinateUtils.getChunkKey(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT); -+ final int relIndex = (chunkX & REGION_MASK) | ((chunkZ & REGION_MASK) << REGION_SHIFT); -+ -+ final ChunkSlicesRegion region = this.regions.get(key); -+ final int remaining = region.remove(relIndex); -+ -+ if (remaining == 0) { -+ this.stateLock.writeLock(); -+ try { -+ this.regions.remove(key); -+ } finally { -+ this.stateLock.tryUnlockWrite(); -+ } -+ } -+ } -+ -+ public synchronized void addChunk(final int chunkX, final int chunkZ, final ChunkEntitySlices slices) { -+ final long key = CoordinateUtils.getChunkKey(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT); -+ final int relIndex = (chunkX & REGION_MASK) | ((chunkZ & REGION_MASK) << REGION_SHIFT); -+ -+ ChunkSlicesRegion region = this.regions.get(key); -+ if (region != null) { -+ region.add(relIndex, slices); -+ } else { -+ region = new ChunkSlicesRegion(); -+ region.add(relIndex, slices); -+ this.stateLock.writeLock(); -+ try { -+ this.regions.put(key, region); -+ } finally { -+ this.stateLock.tryUnlockWrite(); -+ } -+ } -+ } -+ -+ public static final class ChunkSlicesRegion { -+ -+ protected final ChunkEntitySlices[] slices = new ChunkEntitySlices[REGION_SIZE * REGION_SIZE]; -+ protected int sliceCount; -+ -+ public ChunkEntitySlices get(final int index) { -+ return this.slices[index]; -+ } -+ -+ public int remove(final int index) { -+ final ChunkEntitySlices slices = this.slices[index]; -+ if (slices == null) { -+ throw new IllegalStateException(); -+ } -+ -+ this.slices[index] = null; -+ -+ return --this.sliceCount; -+ } -+ -+ public void add(final int index, final ChunkEntitySlices slices) { -+ final ChunkEntitySlices curr = this.slices[index]; -+ if (curr != null) { -+ throw new IllegalStateException(); -+ } -+ -+ this.slices[index] = slices; -+ -+ ++this.sliceCount; -+ } -+ } -+ -+ private final class EntityCallback implements EntityInLevelCallback { -+ -+ public final Entity entity; -+ -+ public EntityCallback(final Entity entity) { -+ this.entity = entity; -+ } -+ -+ @Override -+ public void onMove() { -+ final Entity entity = this.entity; -+ final Visibility oldVisibility = getEntityStatus(entity); -+ final ChunkEntitySlices newSlices = EntityLookup.this.moveEntity(this.entity); -+ if (newSlices == null) { -+ // no new section, so didn't change sections -+ return; -+ } -+ final Visibility newVisibility = getEntityStatus(entity); -+ -+ EntityLookup.this.entityStatusChange(entity, newSlices, oldVisibility, newVisibility, true, false, false); -+ } -+ -+ @Override -+ public void onRemove(final Entity.RemovalReason reason) { -+ final Entity entity = this.entity; -+ TickThread.ensureTickThread(entity, "Cannot remove entity off-main"); // Paper - rewrite chunk system -+ final Visibility tickingState = EntityLookup.getEntityStatus(entity); -+ -+ EntityLookup.this.removeEntity(entity); -+ -+ EntityLookup.this.entityStatusChange(entity, null, tickingState, Visibility.HIDDEN, false, false, reason.shouldDestroy()); -+ -+ this.entity.setLevelCallback(NoOpCallback.INSTANCE); -+ } -+ } -+ -+ private static final class NoOpCallback implements EntityInLevelCallback { -+ -+ public static final NoOpCallback INSTANCE = new NoOpCallback(); -+ -+ @Override -+ public void onMove() {} -+ -+ @Override -+ public void onRemove(final Entity.RemovalReason reason) {} -+ } -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/io/RegionFileIOThread.java b/src/main/java/io/papermc/paper/chunk/system/io/RegionFileIOThread.java -new file mode 100644 -index 0000000000000000000000000000000000000000..2096e57c025858519e7c46788993b9aac1ec60e8 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/io/RegionFileIOThread.java -@@ -0,0 +1,1289 @@ -+package io.papermc.paper.chunk.system.io; -+ -+import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; -+import ca.spottedleaf.concurrentutil.executor.Cancellable; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedQueueExecutorThread; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadedTaskQueue; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import com.mojang.logging.LogUtils; -+import io.papermc.paper.util.CoordinateUtils; -+import io.papermc.paper.util.TickThread; -+import it.unimi.dsi.fastutil.HashCommon; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.chunk.storage.RegionFile; -+import net.minecraft.world.level.chunk.storage.RegionFileStorage; -+import org.slf4j.Logger; -+import java.io.IOException; -+import java.lang.invoke.VarHandle; -+import java.util.concurrent.CompletableFuture; -+import java.util.concurrent.CompletionException; -+import java.util.concurrent.ConcurrentHashMap; -+import java.util.concurrent.atomic.AtomicInteger; -+import java.util.function.BiConsumer; -+import java.util.function.BiFunction; -+import java.util.function.Consumer; -+import java.util.function.Function; -+ -+/** -+ * Prioritised RegionFile I/O executor, responsible for all RegionFile access. -+ *

    -+ * All functions provided are MT-Safe, however certain ordering constraints are recommended: -+ *

      -+ *
    • -+ * Chunk saves may not occur for unloaded chunks. -+ *
    • -+ *
    • -+ * Tasks must be scheduled on the chunk scheduler thread. -+ *
    • -+ *
    -+ * By following these constraints, no chunk data loss should occur with the exception of underlying I/O problems. -+ */ -+public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { -+ -+ private static final Logger LOGGER = LogUtils.getClassLogger(); -+ -+ /** -+ * The kinds of region files controlled by the region file thread. Add more when needed, and ensure -+ * getControllerFor is updated. -+ */ -+ public static enum RegionFileType { -+ CHUNK_DATA, -+ POI_DATA, -+ ENTITY_DATA; -+ } -+ -+ protected static final RegionFileType[] CACHED_REGIONFILE_TYPES = RegionFileType.values(); -+ -+ private ChunkDataController getControllerFor(final ServerLevel world, final RegionFileType type) { -+ return switch (type) { -+ case CHUNK_DATA -> world.chunkDataControllerNew; -+ case POI_DATA -> world.poiDataControllerNew; -+ case ENTITY_DATA -> world.entityDataControllerNew; -+ default -> throw new IllegalStateException("Unknown controller type " + type); -+ }; -+ } -+ -+ /** -+ * Collects regionfile data for a certain chunk. -+ */ -+ public static final class RegionFileData { -+ -+ private final boolean[] hasResult = new boolean[CACHED_REGIONFILE_TYPES.length]; -+ private final CompoundTag[] data = new CompoundTag[CACHED_REGIONFILE_TYPES.length]; -+ private final Throwable[] throwables = new Throwable[CACHED_REGIONFILE_TYPES.length]; -+ -+ /** -+ * Sets the result associated with the specified regionfile type. Note that -+ * results can only be set once per regionfile type. -+ * -+ * @param type The regionfile type. -+ * @param data The result to set. -+ */ -+ public void setData(final RegionFileType type, final CompoundTag data) { -+ final int index = type.ordinal(); -+ -+ if (this.hasResult[index]) { -+ throw new IllegalArgumentException("Result already exists for type " + type); -+ } -+ this.hasResult[index] = true; -+ this.data[index] = data; -+ } -+ -+ /** -+ * Sets the result associated with the specified regionfile type. Note that -+ * results can only be set once per regionfile type. -+ * -+ * @param type The regionfile type. -+ * @param throwable The result to set. -+ */ -+ public void setThrowable(final RegionFileType type, final Throwable throwable) { -+ final int index = type.ordinal(); -+ -+ if (this.hasResult[index]) { -+ throw new IllegalArgumentException("Result already exists for type " + type); -+ } -+ this.hasResult[index] = true; -+ this.throwables[index] = throwable; -+ } -+ -+ /** -+ * Returns whether there is a result for the specified regionfile type. -+ * -+ * @param type Specified regionfile type. -+ * -+ * @return Whether a result exists for {@code type}. -+ */ -+ public boolean hasResult(final RegionFileType type) { -+ return this.hasResult[type.ordinal()]; -+ } -+ -+ /** -+ * Returns the data result for the regionfile type. -+ * -+ * @param type Specified regionfile type. -+ * -+ * @throws IllegalArgumentException If the result has not been set for {@code type}. -+ * @return The data result for the specified type. If the result is a {@code Throwable}, -+ * then returns {@code null}. -+ */ -+ public CompoundTag getData(final RegionFileType type) { -+ final int index = type.ordinal(); -+ -+ if (!this.hasResult[index]) { -+ throw new IllegalArgumentException("Result does not exist for type " + type); -+ } -+ -+ return this.data[index]; -+ } -+ -+ /** -+ * Returns the throwable result for the regionfile type. -+ * -+ * @param type Specified regionfile type. -+ * -+ * @throws IllegalArgumentException If the result has not been set for {@code type}. -+ * @return The throwable result for the specified type. If the result is an {@code CompoundTag}, -+ * then returns {@code null}. -+ */ -+ public Throwable getThrowable(final RegionFileType type) { -+ final int index = type.ordinal(); -+ -+ if (!this.hasResult[index]) { -+ throw new IllegalArgumentException("Result does not exist for type " + type); -+ } -+ -+ return this.throwables[index]; -+ } -+ } -+ -+ private static final Object INIT_LOCK = new Object(); -+ -+ static RegionFileIOThread[] threads; -+ -+ /* needs to be consistent given a set of parameters */ -+ static RegionFileIOThread selectThread(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { -+ if (threads == null) { -+ throw new IllegalStateException("Threads not initialised"); -+ } -+ -+ final int regionX = chunkX >> 5; -+ final int regionZ = chunkZ >> 5; -+ final int typeOffset = type.ordinal(); -+ -+ return threads[(System.identityHashCode(world) + regionX + regionZ + typeOffset) % threads.length]; -+ } -+ -+ /** -+ * Shuts down the I/O executor(s). Watis for all tasks to complete if specified. -+ * Tasks queued during this call might not be accepted, and tasks queued after will not be accepted. -+ * -+ * @param wait Whether to wait until all tasks have completed. -+ */ -+ public static void close(final boolean wait) { -+ for (int i = 0, len = threads.length; i < len; ++i) { -+ threads[i].close(false, true); -+ } -+ if (wait) { -+ RegionFileIOThread.flush(); -+ } -+ } -+ -+ public static long[] getExecutedTasks() { -+ final long[] ret = new long[threads.length]; -+ for (int i = 0, len = threads.length; i < len; ++i) { -+ ret[i] = threads[i].getTotalTasksExecuted(); -+ } -+ -+ return ret; -+ } -+ -+ public static long[] getTasksScheduled() { -+ final long[] ret = new long[threads.length]; -+ for (int i = 0, len = threads.length; i < len; ++i) { -+ ret[i] = threads[i].getTotalTasksScheduled(); -+ } -+ return ret; -+ } -+ -+ public static void flush() { -+ for (int i = 0, len = threads.length; i < len; ++i) { -+ threads[i].waitUntilAllExecuted(); -+ } -+ } -+ -+ public static void partialFlush(final int totalTasksRemaining) { -+ long failures = 1L; // start out at 0.25ms -+ -+ for (;;) { -+ final long[] executed = getExecutedTasks(); -+ final long[] scheduled = getTasksScheduled(); -+ -+ long sum = 0; -+ for (int i = 0; i < executed.length; ++i) { -+ sum += scheduled[i] - executed[i]; -+ } -+ -+ if (sum <= totalTasksRemaining) { -+ break; -+ } -+ -+ failures = ConcurrentUtil.linearLongBackoff(failures, 250_000L, 5_000_000L); // 500us, 5ms -+ } -+ } -+ -+ /** -+ * Inits the executor with the specified number of threads. -+ * -+ * @param threads Specified number of threads. -+ */ -+ public static void init(final int threads) { -+ synchronized (INIT_LOCK) { -+ if (RegionFileIOThread.threads != null) { -+ throw new IllegalStateException("Already initialised threads"); -+ } -+ -+ RegionFileIOThread.threads = new RegionFileIOThread[threads]; -+ -+ for (int i = 0; i < threads; ++i) { -+ RegionFileIOThread.threads[i] = new RegionFileIOThread(i); -+ RegionFileIOThread.threads[i].start(); -+ } -+ } -+ } -+ -+ private RegionFileIOThread(final int threadNumber) { -+ super(new PrioritisedThreadedTaskQueue(), (int)(1.0e6)); // 1.0ms spinwait time -+ this.setName("RegionFile I/O Thread #" + threadNumber); -+ this.setPriority(Thread.NORM_PRIORITY - 2); // we keep priority close to normal because threads can wait on us -+ this.setUncaughtExceptionHandler((final Thread thread, final Throwable thr) -> { -+ LOGGER.error("Uncaught exception thrown from I/O thread, report this! Thread: " + thread.getName(), thr); -+ }); -+ } -+ -+ /** -+ * Returns whether the current thread is a regionfile I/O executor. -+ * @return Whether the current thread is a regionfile I/O executor. -+ */ -+ public static boolean isRegionFileThread() { -+ return Thread.currentThread() instanceof RegionFileIOThread; -+ } -+ -+ /** -+ * Returns the priority associated with blocking I/O based on the current thread. The goal is to avoid -+ * dumb plugins from taking away priority from threads we consider crucial. -+ * @return The priroity to use with blocking I/O on the current thread. -+ */ -+ public static PrioritisedExecutor.Priority getIOBlockingPriorityForCurrentThread() { -+ if (TickThread.isTickThread()) { -+ return PrioritisedExecutor.Priority.BLOCKING; -+ } -+ return PrioritisedExecutor.Priority.HIGHEST; -+ } -+ -+ /** -+ * Returns the current {@code CompoundTag} pending for write for the specified chunk and regionfile type. -+ * Note that this does not copy the result, so do not modify the result returned. -+ * -+ * @param world Specified world. -+ * @param chunkX Specified chunk x. -+ * @param chunkZ Specified chunk z. -+ * @param type Specified regionfile type. -+ * -+ * @return The compound tag associated for the specified chunk. {@code null} if no write was pending, or if {@code null} is the write pending. -+ */ -+ public static CompoundTag getPendingWrite(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { -+ final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -+ return thread.getPendingWriteInternal(world, chunkX, chunkZ, type); -+ } -+ -+ CompoundTag getPendingWriteInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { -+ final ChunkDataController taskController = this.getControllerFor(world, type); -+ final ChunkDataTask task = taskController.tasks.get(Long.valueOf(CoordinateUtils.getChunkKey(chunkX, chunkZ))); -+ -+ if (task == null) { -+ return null; -+ } -+ -+ final CompoundTag ret = task.inProgressWrite; -+ -+ return ret == ChunkDataTask.NOTHING_TO_WRITE ? null : ret; -+ } -+ -+ /** -+ * Returns the priority for the specified regionfile type for the specified chunk. -+ * @param world Specified world. -+ * @param chunkX Specified chunk x. -+ * @param chunkZ Specified chunk z. -+ * @param type Specified regionfile type. -+ * @return The priority for the chunk -+ */ -+ public static PrioritisedExecutor.Priority getPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { -+ final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -+ return thread.getPriorityInternal(world, chunkX, chunkZ, type); -+ } -+ -+ PrioritisedExecutor.Priority getPriorityInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type) { -+ final ChunkDataController taskController = this.getControllerFor(world, type); -+ final ChunkDataTask task = taskController.tasks.get(Long.valueOf(CoordinateUtils.getChunkKey(chunkX, chunkZ))); -+ -+ if (task == null) { -+ return PrioritisedExecutor.Priority.COMPLETING; -+ } -+ -+ return task.prioritisedTask.getPriority(); -+ } -+ -+ /** -+ * Sets the priority for all regionfile types for the specified chunk. Note that great care should -+ * be taken using this method, as there can be multiple tasks tied to the same chunk that want different -+ * priorities. -+ * -+ * @param world Specified world. -+ * @param chunkX Specified chunk x. -+ * @param chunkZ Specified chunk z. -+ * @param priority New priority. -+ * -+ * @see #raisePriority(ServerLevel, int, int, Priority) -+ * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) -+ * @see #lowerPriority(ServerLevel, int, int, Priority) -+ * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) -+ */ -+ public static void setPriority(final ServerLevel world, final int chunkX, final int chunkZ, -+ final PrioritisedExecutor.Priority priority) { -+ for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { -+ RegionFileIOThread.setPriority(world, chunkX, chunkZ, type, priority); -+ } -+ } -+ -+ /** -+ * Sets the priority for the specified regionfile type for the specified chunk. Note that great care should -+ * be taken using this method, as there can be multiple tasks tied to the same chunk that want different -+ * priorities. -+ * -+ * @param world Specified world. -+ * @param chunkX Specified chunk x. -+ * @param chunkZ Specified chunk z. -+ * @param type Specified regionfile type. -+ * @param priority New priority. -+ * -+ * @see #raisePriority(ServerLevel, int, int, Priority) -+ * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) -+ * @see #lowerPriority(ServerLevel, int, int, Priority) -+ * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) -+ */ -+ public static void setPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -+ final PrioritisedExecutor.Priority priority) { -+ final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -+ thread.setPriorityInternal(world, chunkX, chunkZ, type, priority); -+ } -+ -+ void setPriorityInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -+ final PrioritisedExecutor.Priority priority) { -+ final ChunkDataController taskController = this.getControllerFor(world, type); -+ final ChunkDataTask task = taskController.tasks.get(Long.valueOf(CoordinateUtils.getChunkKey(chunkX, chunkZ))); -+ -+ if (task != null) { -+ task.prioritisedTask.setPriority(priority); -+ } -+ } -+ -+ /** -+ * Raises the priority for all regionfile types for the specified chunk. -+ * -+ * @param world Specified world. -+ * @param chunkX Specified chunk x. -+ * @param chunkZ Specified chunk z. -+ * @param priority New priority. -+ * -+ * @see #setPriority(ServerLevel, int, int, Priority) -+ * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) -+ * @see #lowerPriority(ServerLevel, int, int, Priority) -+ * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) -+ */ -+ public static void raisePriority(final ServerLevel world, final int chunkX, final int chunkZ, -+ final PrioritisedExecutor.Priority priority) { -+ for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { -+ RegionFileIOThread.raisePriority(world, chunkX, chunkZ, type, priority); -+ } -+ } -+ -+ /** -+ * Raises the priority for the specified regionfile type for the specified chunk. -+ * -+ * @param world Specified world. -+ * @param chunkX Specified chunk x. -+ * @param chunkZ Specified chunk z. -+ * @param type Specified regionfile type. -+ * @param priority New priority. -+ * -+ * @see #setPriority(ServerLevel, int, int, Priority) -+ * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) -+ * @see #lowerPriority(ServerLevel, int, int, Priority) -+ * @see #lowerPriority(ServerLevel, int, int, RegionFileType, Priority) -+ */ -+ public static void raisePriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -+ final PrioritisedExecutor.Priority priority) { -+ final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -+ thread.raisePriorityInternal(world, chunkX, chunkZ, type, priority); -+ } -+ -+ void raisePriorityInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -+ final PrioritisedExecutor.Priority priority) { -+ final ChunkDataController taskController = this.getControllerFor(world, type); -+ final ChunkDataTask task = taskController.tasks.get(Long.valueOf(CoordinateUtils.getChunkKey(chunkX, chunkZ))); -+ -+ if (task != null) { -+ task.prioritisedTask.raisePriority(priority); -+ } -+ } -+ -+ /** -+ * Lowers the priority for all regionfile types for the specified chunk. -+ * -+ * @param world Specified world. -+ * @param chunkX Specified chunk x. -+ * @param chunkZ Specified chunk z. -+ * @param priority New priority. -+ * -+ * @see #raisePriority(ServerLevel, int, int, Priority) -+ * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) -+ * @see #setPriority(ServerLevel, int, int, Priority) -+ * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) -+ */ -+ public static void lowerPriority(final ServerLevel world, final int chunkX, final int chunkZ, -+ final PrioritisedExecutor.Priority priority) { -+ for (final RegionFileType type : CACHED_REGIONFILE_TYPES) { -+ RegionFileIOThread.lowerPriority(world, chunkX, chunkZ, type, priority); -+ } -+ } -+ -+ /** -+ * Lowers the priority for the specified regionfile type for the specified chunk. -+ * -+ * @param world Specified world. -+ * @param chunkX Specified chunk x. -+ * @param chunkZ Specified chunk z. -+ * @param type Specified regionfile type. -+ * @param priority New priority. -+ * -+ * @see #raisePriority(ServerLevel, int, int, Priority) -+ * @see #raisePriority(ServerLevel, int, int, RegionFileType, Priority) -+ * @see #setPriority(ServerLevel, int, int, Priority) -+ * @see #setPriority(ServerLevel, int, int, RegionFileType, Priority) -+ */ -+ public static void lowerPriority(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -+ final PrioritisedExecutor.Priority priority) { -+ final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -+ thread.lowerPriorityInternal(world, chunkX, chunkZ, type, priority); -+ } -+ -+ void lowerPriorityInternal(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -+ final PrioritisedExecutor.Priority priority) { -+ final ChunkDataController taskController = this.getControllerFor(world, type); -+ final ChunkDataTask task = taskController.tasks.get(Long.valueOf(CoordinateUtils.getChunkKey(chunkX, chunkZ))); -+ -+ if (task != null) { -+ task.prioritisedTask.lowerPriority(priority); -+ } -+ } -+ -+ /** -+ * Schedules the chunk data to be written asynchronously. -+ *

    -+ * Impl notes: -+ *

      -+ *
    • -+ * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means -+ * saves must be scheduled before a chunk is unloaded. -+ *
    • -+ *
    • -+ * Writes may be called concurrently, although only the "later" write will go through. -+ *
    • -+ *
    -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param data Chunk's data -+ * @param type The regionfile type to write to. -+ * -+ * @throws IllegalStateException If the file io thread has shutdown. -+ */ -+ public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data, -+ final RegionFileType type) { -+ RegionFileIOThread.scheduleSave(world, chunkX, chunkZ, data, type, PrioritisedExecutor.Priority.NORMAL); -+ } -+ -+ /** -+ * Schedules the chunk data to be written asynchronously. -+ *

    -+ * Impl notes: -+ *

      -+ *
    • -+ * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means -+ * saves must be scheduled before a chunk is unloaded. -+ *
    • -+ *
    • -+ * Writes may be called concurrently, although only the "later" write will go through. -+ *
    • -+ *
    -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param data Chunk's data -+ * @param type The regionfile type to write to. -+ * @param priority The minimum priority to schedule at. -+ * -+ * @throws IllegalStateException If the file io thread has shutdown. -+ */ -+ public static void scheduleSave(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data, -+ final RegionFileType type, final PrioritisedExecutor.Priority priority) { -+ final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -+ thread.scheduleSaveInternal(world, chunkX, chunkZ, data, type, priority); -+ } -+ -+ void scheduleSaveInternal(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data, -+ final RegionFileType type, final PrioritisedExecutor.Priority priority) { -+ final ChunkDataController taskController = this.getControllerFor(world, type); -+ -+ final boolean[] created = new boolean[1]; -+ final ChunkCoordinate key = new ChunkCoordinate(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ final ChunkDataTask task = taskController.tasks.compute(key, (final ChunkCoordinate keyInMap, final ChunkDataTask taskRunning) -> { -+ if (taskRunning == null || taskRunning.failedWrite) { -+ // no task is scheduled or the previous write failed - meaning we need to overwrite it -+ -+ // create task -+ final ChunkDataTask newTask = new ChunkDataTask(world, chunkX, chunkZ, taskController, RegionFileIOThread.this, priority); -+ newTask.inProgressWrite = data; -+ created[0] = true; -+ -+ return newTask; -+ } -+ -+ taskRunning.inProgressWrite = data; -+ -+ return taskRunning; -+ }); -+ -+ if (created[0]) { -+ task.prioritisedTask.queue(); -+ } else { -+ task.prioritisedTask.raisePriority(priority); -+ } -+ } -+ -+ /** -+ * Schedules a load to be executed asynchronously. This task will load all regionfile types, and then call -+ * {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean)} -+ * for single load. -+ *

    -+ * Impl notes: -+ *

      -+ *
    • -+ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -+ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -+ * data is undefined behaviour, and can cause deadlock. -+ *
    • -+ *
    -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param onComplete Consumer to execute once this task has completed -+ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -+ * of this call. -+ * -+ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -+ * -+ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) -+ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) -+ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) -+ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) -+ */ -+ public static Cancellable loadAllChunkData(final ServerLevel world, final int chunkX, final int chunkZ, -+ final Consumer onComplete, final boolean intendingToBlock) { -+ return RegionFileIOThread.loadAllChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, PrioritisedExecutor.Priority.NORMAL); -+ } -+ -+ /** -+ * Schedules a load to be executed asynchronously. This task will load all regionfile types, and then call -+ * {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority)} -+ * for single load. -+ *

    -+ * Impl notes: -+ *

      -+ *
    • -+ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -+ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -+ * data is undefined behaviour, and can cause deadlock. -+ *
    • -+ *
    -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param onComplete Consumer to execute once this task has completed -+ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -+ * of this call. -+ * @param priority The minimum priority to load the data at. -+ * -+ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -+ * -+ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) -+ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) -+ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) -+ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) -+ */ -+ public static Cancellable loadAllChunkData(final ServerLevel world, final int chunkX, final int chunkZ, -+ final Consumer onComplete, final boolean intendingToBlock, -+ final PrioritisedExecutor.Priority priority) { -+ return RegionFileIOThread.loadChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, priority, CACHED_REGIONFILE_TYPES); -+ } -+ -+ /** -+ * Schedules a load to be executed asynchronously. This task will load data for the specified regionfile type(s), and -+ * then call {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean)} -+ * for single load. -+ *

    -+ * Impl notes: -+ *

      -+ *
    • -+ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -+ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -+ * data is undefined behaviour, and can cause deadlock. -+ *
    • -+ *
    -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param onComplete Consumer to execute once this task has completed -+ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -+ * of this call. -+ * @param types The regionfile type(s) to load. -+ * -+ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -+ * -+ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) -+ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) -+ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) -+ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) -+ */ -+ public static Cancellable loadChunkData(final ServerLevel world, final int chunkX, final int chunkZ, -+ final Consumer onComplete, final boolean intendingToBlock, -+ final RegionFileType... types) { -+ return RegionFileIOThread.loadChunkData(world, chunkX, chunkZ, onComplete, intendingToBlock, PrioritisedExecutor.Priority.NORMAL, types); -+ } -+ -+ /** -+ * Schedules a load to be executed asynchronously. This task will load data for the specified regionfile type(s), and -+ * then call {@code onComplete}. This is a bulk load operation, see {@link #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority)} -+ * for single load. -+ *

    -+ * Impl notes: -+ *

      -+ *
    • -+ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -+ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -+ * data is undefined behaviour, and can cause deadlock. -+ *
    • -+ *
    -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param onComplete Consumer to execute once this task has completed -+ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -+ * of this call. -+ * @param types The regionfile type(s) to load. -+ * @param priority The minimum priority to load the data at. -+ * -+ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -+ * -+ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean) -+ * @see #loadDataAsync(ServerLevel, int, int, RegionFileType, BiConsumer, boolean, Priority) -+ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) -+ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) -+ */ -+ public static Cancellable loadChunkData(final ServerLevel world, final int chunkX, final int chunkZ, -+ final Consumer onComplete, final boolean intendingToBlock, -+ final PrioritisedExecutor.Priority priority, final RegionFileType... types) { -+ if (types == null) { -+ throw new NullPointerException("Types cannot be null"); -+ } -+ if (types.length == 0) { -+ throw new IllegalArgumentException("Types cannot be empty"); -+ } -+ -+ final RegionFileData ret = new RegionFileData(); -+ -+ final Cancellable[] reads = new CancellableRead[types.length]; -+ final AtomicInteger completions = new AtomicInteger(); -+ final int expectedCompletions = types.length; -+ -+ for (int i = 0; i < expectedCompletions; ++i) { -+ final RegionFileType type = types[i]; -+ reads[i] = RegionFileIOThread.loadDataAsync(world, chunkX, chunkZ, type, -+ (final CompoundTag data, final Throwable throwable) -> { -+ if (throwable != null) { -+ ret.setThrowable(type, throwable); -+ } else { -+ ret.setData(type, data); -+ } -+ -+ if (completions.incrementAndGet() == expectedCompletions) { -+ onComplete.accept(ret); -+ } -+ }, intendingToBlock, priority); -+ } -+ -+ return new CancellableReads(reads); -+ } -+ -+ /** -+ * Schedules a load to be executed asynchronously. This task will load the specified regionfile type, and then call -+ * {@code onComplete}. -+ *

    -+ * Impl notes: -+ *

      -+ *
    • -+ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -+ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -+ * data is undefined behaviour, and can cause deadlock. -+ *
    • -+ *
    -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param onComplete Consumer to execute once this task has completed -+ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -+ * of this call. -+ * -+ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -+ * -+ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) -+ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) -+ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) -+ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) -+ */ -+ public static Cancellable loadDataAsync(final ServerLevel world, final int chunkX, final int chunkZ, -+ final RegionFileType type, final BiConsumer onComplete, -+ final boolean intendingToBlock) { -+ return RegionFileIOThread.loadDataAsync(world, chunkX, chunkZ, type, onComplete, intendingToBlock, PrioritisedExecutor.Priority.NORMAL); -+ } -+ -+ /** -+ * Schedules a load to be executed asynchronously. This task will load the specified regionfile type, and then call -+ * {@code onComplete}. -+ *

    -+ * Impl notes: -+ *

      -+ *
    • -+ * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may -+ * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of -+ * data is undefined behaviour, and can cause deadlock. -+ *
    • -+ *
    -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param onComplete Consumer to execute once this task has completed -+ * @param intendingToBlock Whether the caller is intending to block on completion. This only affects the cost -+ * of this call. -+ * @param priority Minimum priority to load the data at. -+ * -+ * @return The {@link Cancellable} for this chunk load. Cancelling it will not affect other loads for the same chunk data. -+ * -+ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, RegionFileType...) -+ * @see #loadChunkData(ServerLevel, int, int, Consumer, boolean, Priority, RegionFileType...) -+ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean) -+ * @see #loadAllChunkData(ServerLevel, int, int, Consumer, boolean, Priority) -+ */ -+ public static Cancellable loadDataAsync(final ServerLevel world, final int chunkX, final int chunkZ, -+ final RegionFileType type, final BiConsumer onComplete, -+ final boolean intendingToBlock, final PrioritisedExecutor.Priority priority) { -+ final RegionFileIOThread thread = RegionFileIOThread.selectThread(world, chunkX, chunkZ, type); -+ return thread.loadDataAsyncInternal(world, chunkX, chunkZ, type, onComplete, intendingToBlock, priority); -+ } -+ -+ Cancellable loadDataAsyncInternal(final ServerLevel world, final int chunkX, final int chunkZ, -+ final RegionFileType type, final BiConsumer onComplete, -+ final boolean intendingToBlock, final PrioritisedExecutor.Priority priority) { -+ final ChunkDataController taskController = this.getControllerFor(world, type); -+ -+ final ImmediateCallbackCompletion callbackInfo = new ImmediateCallbackCompletion(); -+ -+ final ChunkCoordinate key = new ChunkCoordinate(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ final BiFunction compute = (final ChunkCoordinate keyInMap, final ChunkDataTask running) -> { -+ if (running == null) { -+ // not scheduled -+ -+ // set up task -+ final ChunkDataTask newTask = new ChunkDataTask( -+ world, chunkX, chunkZ, taskController, RegionFileIOThread.this, priority -+ ); -+ newTask.inProgressRead = new RegionFileIOThread.InProgressRead(); -+ newTask.inProgressRead.waiters.add(onComplete); -+ -+ callbackInfo.tasksNeedsScheduling = true; -+ return newTask; -+ } -+ -+ final CompoundTag pendingWrite = running.inProgressWrite; -+ -+ if (pendingWrite == ChunkDataTask.NOTHING_TO_WRITE) { -+ // need to add to waiters here, because the regionfile thread will use compute() to lock and check for cancellations -+ if (!running.inProgressRead.addToWaiters(onComplete)) { -+ callbackInfo.data = running.inProgressRead.value; -+ callbackInfo.throwable = running.inProgressRead.throwable; -+ callbackInfo.completeNow = true; -+ } -+ return running; -+ } -+ // using the result sync here - don't bump priority -+ -+ // at this stage we have to use the in progress write's data to avoid an order issue -+ callbackInfo.data = pendingWrite; -+ callbackInfo.throwable = null; -+ callbackInfo.completeNow = true; -+ return running; -+ }; -+ -+ final ChunkDataTask ret = taskController.tasks.compute(key, compute); -+ -+ // needs to be scheduled -+ if (callbackInfo.tasksNeedsScheduling) { -+ ret.prioritisedTask.queue(); -+ } else if (callbackInfo.completeNow) { -+ try { -+ onComplete.accept(callbackInfo.data, callbackInfo.throwable); -+ } catch (final ThreadDeath thr) { -+ throw thr; -+ } catch (final Throwable thr) { -+ LOGGER.error("Callback " + ConcurrentUtil.genericToString(onComplete) + " synchronously failed to handle chunk data for task " + ret.toString(), thr); -+ } -+ } else { -+ // we're waiting on a task we didn't schedule, so raise its priority to what we want -+ ret.prioritisedTask.raisePriority(priority); -+ } -+ -+ return new CancellableRead(onComplete, ret); -+ } -+ -+ /** -+ * Schedules a load task to be executed asynchronously, and blocks on that task. -+ * -+ * @param world Chunk's world -+ * @param chunkX Chunk's x coordinate -+ * @param chunkZ Chunk's z coordinate -+ * @param type Regionfile type -+ * @param priority Minimum priority to load the data at. -+ * -+ * @return The chunk data for the chunk. Note that a {@code null} result means the chunk or regionfile does not exist on disk. -+ * -+ * @throws IOException If the load fails for any reason -+ */ -+ public static CompoundTag loadData(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileType type, -+ final PrioritisedExecutor.Priority priority) throws IOException { -+ final CompletableFuture ret = new CompletableFuture<>(); -+ -+ RegionFileIOThread.loadDataAsync(world, chunkX, chunkZ, type, (final CompoundTag compound, final Throwable thr) -> { -+ if (thr != null) { -+ ret.completeExceptionally(thr); -+ } else { -+ ret.complete(compound); -+ } -+ }, true, priority); -+ -+ try { -+ return ret.join(); -+ } catch (final CompletionException ex) { -+ throw new IOException(ex); -+ } -+ } -+ -+ private static final class ImmediateCallbackCompletion { -+ -+ public CompoundTag data; -+ public Throwable throwable; -+ public boolean completeNow; -+ public boolean tasksNeedsScheduling; -+ -+ } -+ -+ static final class CancellableRead implements Cancellable { -+ -+ private BiConsumer callback; -+ private RegionFileIOThread.ChunkDataTask task; -+ -+ CancellableRead(final BiConsumer callback, final RegionFileIOThread.ChunkDataTask task) { -+ this.callback = callback; -+ this.task = task; -+ } -+ -+ @Override -+ public boolean cancel() { -+ final BiConsumer callback = this.callback; -+ final RegionFileIOThread.ChunkDataTask task = this.task; -+ -+ if (callback == null || task == null) { -+ return false; -+ } -+ -+ this.callback = null; -+ this.task = null; -+ -+ final RegionFileIOThread.InProgressRead read = task.inProgressRead; -+ -+ // read can be null if no read was scheduled (i.e no regionfile existed or chunk in regionfile didn't) -+ return (read != null && read.waiters.remove(callback)); -+ } -+ } -+ -+ static final class CancellableReads implements Cancellable { -+ -+ private Cancellable[] reads; -+ -+ protected static final VarHandle READS_HANDLE = ConcurrentUtil.getVarHandle(CancellableReads.class, "reads", Cancellable[].class); -+ -+ CancellableReads(final Cancellable[] reads) { -+ this.reads = reads; -+ } -+ -+ @Override -+ public boolean cancel() { -+ final Cancellable[] reads = (Cancellable[])READS_HANDLE.getAndSet((CancellableReads)this, (Cancellable[])null); -+ -+ if (reads == null) { -+ return false; -+ } -+ -+ boolean ret = false; -+ -+ for (final Cancellable read : reads) { -+ ret |= read.cancel(); -+ } -+ -+ return ret; -+ } -+ } -+ -+ static final class InProgressRead { -+ -+ private static final Logger LOGGER = LogUtils.getClassLogger(); -+ -+ CompoundTag value; -+ Throwable throwable; -+ final MultiThreadedQueue> waiters = new MultiThreadedQueue<>(); -+ -+ // rets false if already completed (callback not invoked), true if callback was added -+ boolean addToWaiters(final BiConsumer callback) { -+ return this.waiters.add(callback); -+ } -+ -+ void complete(final RegionFileIOThread.ChunkDataTask task, final CompoundTag value, final Throwable throwable) { -+ this.value = value; -+ this.throwable = throwable; -+ -+ BiConsumer consumer; -+ while ((consumer = this.waiters.pollOrBlockAdds()) != null) { -+ try { -+ consumer.accept(value, throwable); -+ } catch (final ThreadDeath thr) { -+ throw thr; -+ } catch (final Throwable thr) { -+ LOGGER.error("Callback " + ConcurrentUtil.genericToString(consumer) + " failed to handle chunk data for task " + task.toString(), thr); -+ } -+ } -+ } -+ } -+ -+ /** -+ * Class exists to replace {@link Long} usages as keys inside non-fastutil hashtables. The hash for some Long {@code x} -+ * is defined as {@code (x >>> 32) ^ x}. Chunk keys as long values are defined as {@code ((chunkX & 0xFFFFFFFFL) | (chunkZ << 32))}, -+ * which means the hashcode as a Long value will be {@code chunkX ^ chunkZ}. Given that most chunks are created within a radius arounds players, -+ * this will lead to many hash collisions. So, this class uses a better hashing algorithm so that usage of -+ * non-fastutil collections is not degraded. -+ */ -+ public static final class ChunkCoordinate implements Comparable { -+ -+ public final long key; -+ -+ public ChunkCoordinate(final long key) { -+ this.key = key; -+ } -+ -+ @Override -+ public int hashCode() { -+ return (int)HashCommon.mix(this.key); -+ } -+ -+ @Override -+ public boolean equals(final Object obj) { -+ if (this == obj) { -+ return true; -+ } -+ -+ if (!(obj instanceof ChunkCoordinate)) { -+ return false; -+ } -+ -+ final ChunkCoordinate other = (ChunkCoordinate)obj; -+ -+ return this.key == other.key; -+ } -+ -+ // This class is intended for HashMap/ConcurrentHashMap usage, which do treeify bin nodes if the chain -+ // is too large. So we should implement compareTo to help. -+ @Override -+ public int compareTo(final RegionFileIOThread.ChunkCoordinate other) { -+ return Long.compare(this.key, other.key); -+ } -+ -+ @Override -+ public String toString() { -+ return new ChunkPos(this.key).toString(); -+ } -+ } -+ -+ public static abstract class ChunkDataController { -+ -+ // ConcurrentHashMap synchronizes per chain, so reduce the chance of task's hashes colliding. -+ protected final ConcurrentHashMap tasks = new ConcurrentHashMap<>(8192, 0.10f); -+ -+ public final RegionFileType type; -+ -+ public ChunkDataController(final RegionFileType type) { -+ this.type = type; -+ } -+ -+ public abstract RegionFileStorage getCache(); -+ -+ public abstract void writeData(final int chunkX, final int chunkZ, final CompoundTag compound) throws IOException; -+ -+ public abstract CompoundTag readData(final int chunkX, final int chunkZ) throws IOException; -+ -+ public boolean hasTasks() { -+ return !this.tasks.isEmpty(); -+ } -+ -+ public boolean doesRegionFileNotExist(final int chunkX, final int chunkZ) { -+ return this.getCache().doesRegionFileNotExistNoIO(new ChunkPos(chunkX, chunkZ)); -+ } -+ -+ public T computeForRegionFile(final int chunkX, final int chunkZ, final boolean existingOnly, final Function function) { -+ final RegionFileStorage cache = this.getCache(); -+ final RegionFile regionFile; -+ synchronized (cache) { -+ try { -+ regionFile = cache.getRegionFile(new ChunkPos(chunkX, chunkZ), existingOnly, true); -+ } catch (final IOException ex) { -+ throw new RuntimeException(ex); -+ } -+ } -+ -+ try { -+ return function.apply(regionFile); -+ } finally { -+ if (regionFile != null) { -+ regionFile.fileLock.unlock(); -+ } -+ } -+ } -+ -+ public T computeForRegionFileIfLoaded(final int chunkX, final int chunkZ, final Function function) { -+ final RegionFileStorage cache = this.getCache(); -+ final RegionFile regionFile; -+ -+ synchronized (cache) { -+ regionFile = cache.getRegionFileIfLoaded(new ChunkPos(chunkX, chunkZ)); -+ if (regionFile != null) { -+ regionFile.fileLock.lock(); -+ } -+ } -+ -+ try { -+ return function.apply(regionFile); -+ } finally { -+ if (regionFile != null) { -+ regionFile.fileLock.unlock(); -+ } -+ } -+ } -+ } -+ -+ static final class ChunkDataTask implements Runnable { -+ -+ protected static final CompoundTag NOTHING_TO_WRITE = new CompoundTag(); -+ -+ private static final Logger LOGGER = LogUtils.getClassLogger(); -+ -+ RegionFileIOThread.InProgressRead inProgressRead; -+ volatile CompoundTag inProgressWrite = NOTHING_TO_WRITE; // only needs to be acquire/release -+ -+ boolean failedWrite; -+ -+ final ServerLevel world; -+ final int chunkX; -+ final int chunkZ; -+ final RegionFileIOThread.ChunkDataController taskController; -+ -+ final PrioritisedExecutor.PrioritisedTask prioritisedTask; -+ -+ /* -+ * IO thread will perform reads before writes for a given chunk x and z -+ * -+ * How reads/writes are scheduled: -+ * -+ * If read is scheduled while scheduling write, take no special action and just schedule write -+ * If read is scheduled while scheduling read and no write is scheduled, chain the read task -+ * -+ * -+ * If write is scheduled while scheduling read, use the pending write data and ret immediately (so no read is scheduled) -+ * If write is scheduled while scheduling write (ignore read in progress), overwrite the write in progress data -+ * -+ * This allows the reads and writes to act as if they occur synchronously to the thread scheduling them, however -+ * it fails to properly propagate write failures thanks to writes overwriting each other -+ */ -+ -+ public ChunkDataTask(final ServerLevel world, final int chunkX, final int chunkZ, final RegionFileIOThread.ChunkDataController taskController, -+ final PrioritisedExecutor executor, final PrioritisedExecutor.Priority priority) { -+ this.world = world; -+ this.chunkX = chunkX; -+ this.chunkZ = chunkZ; -+ this.taskController = taskController; -+ this.prioritisedTask = executor.createTask(this, priority); -+ } -+ -+ @Override -+ public String toString() { -+ return "Task for world: '" + this.world.getWorld().getName() + "' at (" + this.chunkX + "," + this.chunkZ + -+ ") type: " + this.taskController.type.name() + ", hash: " + this.hashCode(); -+ } -+ -+ @Override -+ public void run() { -+ final RegionFileIOThread.InProgressRead read = this.inProgressRead; -+ final ChunkCoordinate chunkKey = new ChunkCoordinate(CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ)); -+ -+ if (read != null) { -+ final boolean[] canRead = new boolean[] { true }; -+ -+ if (read.waiters.isEmpty()) { -+ // cancelled read? go to task controller to confirm -+ final ChunkDataTask inMap = this.taskController.tasks.compute(chunkKey, (final ChunkCoordinate keyInMap, final ChunkDataTask valueInMap) -> { -+ if (valueInMap == null) { -+ throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkDataTask.this.toString() + ", report this!"); -+ } -+ if (valueInMap != ChunkDataTask.this) { -+ throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkDataTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); -+ } -+ -+ if (!read.waiters.isEmpty()) { // as per usual IntelliJ is unable to figure out that there are concurrent accesses. -+ return valueInMap; -+ } else { -+ canRead[0] = false; -+ } -+ -+ return valueInMap.inProgressWrite == NOTHING_TO_WRITE ? null : valueInMap; -+ }); -+ -+ if (inMap == null) { -+ // read is cancelled - and no write pending, so we're done -+ return; -+ } -+ // if there is a write in progress, we don't actually have to worry about waiters gaining new entries - -+ // the readers will just use the in progress write, so the value in canRead is good to use without -+ // further synchronisation. -+ } -+ -+ if (canRead[0]) { -+ CompoundTag compound = null; -+ Throwable throwable = null; -+ -+ try { -+ compound = this.taskController.readData(this.chunkX, this.chunkZ); -+ } catch (final ThreadDeath thr) { -+ throw thr; -+ } catch (final Throwable thr) { -+ throwable = thr; -+ LOGGER.error("Failed to read chunk data for task: " + this.toString(), thr); -+ } -+ read.complete(this, compound, throwable); -+ } -+ } -+ -+ CompoundTag write = this.inProgressWrite; -+ -+ if (write == NOTHING_TO_WRITE) { -+ final ChunkDataTask inMap = this.taskController.tasks.compute(chunkKey, (final ChunkCoordinate keyInMap, final ChunkDataTask valueInMap) -> { -+ if (valueInMap == null) { -+ throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkDataTask.this.toString() + ", report this!"); -+ } -+ if (valueInMap != ChunkDataTask.this) { -+ throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkDataTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); -+ } -+ return valueInMap.inProgressWrite == NOTHING_TO_WRITE ? null : valueInMap; -+ }); -+ -+ if (inMap == null) { -+ return; // set the task value to null, indicating we're done -+ } // else: inProgressWrite changed, so now we have something to write -+ } -+ -+ for (;;) { -+ write = this.inProgressWrite; -+ final CompoundTag dataWritten = write; -+ -+ boolean failedWrite = false; -+ -+ try { -+ this.taskController.writeData(this.chunkX, this.chunkZ, write); -+ } catch (final ThreadDeath thr) { -+ throw thr; -+ } catch (final Throwable thr) { -+ if (thr instanceof RegionFileStorage.RegionFileSizeException) { -+ final int maxSize = RegionFile.MAX_CHUNK_SIZE / (1024 * 1024); -+ LOGGER.error("Chunk at (" + this.chunkX + "," + this.chunkZ + ") in '" + this.world.getWorld().getName() + "' exceeds max size of " + maxSize + "MiB, it has been deleted from disk."); -+ } else { -+ failedWrite = thr instanceof IOException; -+ LOGGER.error("Failed to write chunk data for task: " + this.toString(), thr); -+ } -+ } -+ -+ final boolean finalFailWrite = failedWrite; -+ final boolean[] done = new boolean[] { false }; -+ -+ this.taskController.tasks.compute(chunkKey, (final ChunkCoordinate keyInMap, final ChunkDataTask valueInMap) -> { -+ if (valueInMap == null) { -+ throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkDataTask.this.toString() + ", report this!"); -+ } -+ if (valueInMap != ChunkDataTask.this) { -+ throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkDataTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); -+ } -+ if (valueInMap.inProgressWrite == dataWritten) { -+ valueInMap.failedWrite = finalFailWrite; -+ done[0] = true; -+ // keep the data in map if we failed the write so we can try to prevent data loss -+ return finalFailWrite ? valueInMap : null; -+ } -+ // different data than expected, means we need to retry write -+ return valueInMap; -+ }); -+ -+ if (done[0]) { -+ return; -+ } -+ -+ // fetch & write new data -+ continue; -+ } -+ } -+ } -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/light/LightQueue.java b/src/main/java/io/papermc/paper/chunk/system/light/LightQueue.java -new file mode 100644 -index 0000000000000000000000000000000000000000..69e9944358951bd69ff5e8b3482da1a5e4476209 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/light/LightQueue.java -@@ -0,0 +1,283 @@ -+package io.papermc.paper.chunk.system.light; -+ -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.starlight.common.light.BlockStarLightEngine; -+import ca.spottedleaf.starlight.common.light.SkyStarLightEngine; -+import ca.spottedleaf.starlight.common.light.StarLightInterface; -+import io.papermc.paper.util.CoordinateUtils; -+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -+import it.unimi.dsi.fastutil.shorts.ShortCollection; -+import it.unimi.dsi.fastutil.shorts.ShortOpenHashSet; -+import net.minecraft.core.BlockPos; -+import net.minecraft.core.SectionPos; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.chunk.status.ChunkStatus; -+import java.util.ArrayList; -+import java.util.HashSet; -+import java.util.List; -+import java.util.Set; -+import java.util.concurrent.CompletableFuture; -+import java.util.function.BooleanSupplier; -+ -+public final class LightQueue { -+ -+ protected final Long2ObjectOpenHashMap chunkTasks = new Long2ObjectOpenHashMap<>(); -+ protected final StarLightInterface manager; -+ protected final ServerLevel world; -+ -+ public LightQueue(final StarLightInterface manager) { -+ this.manager = manager; -+ this.world = ((ServerLevel)manager.getWorld()); -+ } -+ -+ public void lowerPriority(final int chunkX, final int chunkZ, final PrioritisedExecutor.Priority priority) { -+ final ChunkTasks task; -+ synchronized (this) { -+ task = this.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ } -+ if (task != null) { -+ task.lowerPriority(priority); -+ } -+ } -+ -+ public void setPriority(final int chunkX, final int chunkZ, final PrioritisedExecutor.Priority priority) { -+ final ChunkTasks task; -+ synchronized (this) { -+ task = this.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ } -+ if (task != null) { -+ task.setPriority(priority); -+ } -+ } -+ -+ public void raisePriority(final int chunkX, final int chunkZ, final PrioritisedExecutor.Priority priority) { -+ final ChunkTasks task; -+ synchronized (this) { -+ task = this.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ } -+ if (task != null) { -+ task.raisePriority(priority); -+ } -+ } -+ -+ public PrioritisedExecutor.Priority getPriority(final int chunkX, final int chunkZ) { -+ final ChunkTasks task; -+ synchronized (this) { -+ task = this.chunkTasks.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ } -+ if (task != null) { -+ return task.getPriority(); -+ } -+ -+ return PrioritisedExecutor.Priority.COMPLETING; -+ } -+ -+ public boolean isEmpty() { -+ synchronized (this) { -+ return this.chunkTasks.isEmpty(); -+ } -+ } -+ -+ public ChunkTasks queueBlockChange(final BlockPos pos) { -+ final ChunkTasks tasks; -+ synchronized (this) { -+ tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), (final long keyInMap) -> { -+ return new ChunkTasks(keyInMap, LightQueue.this.manager, LightQueue.this); -+ }); -+ tasks.changedPositions.add(pos.immutable()); -+ } -+ -+ tasks.schedule(); -+ -+ return tasks; -+ } -+ -+ public ChunkTasks queueSectionChange(final SectionPos pos, final boolean newEmptyValue) { -+ final ChunkTasks tasks; -+ synchronized (this) { -+ tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), (final long keyInMap) -> { -+ return new ChunkTasks(keyInMap, LightQueue.this.manager, LightQueue.this); -+ }); -+ -+ if (tasks.changedSectionSet == null) { -+ tasks.changedSectionSet = new Boolean[this.manager.maxSection - this.manager.minSection + 1]; -+ } -+ tasks.changedSectionSet[pos.getY() - this.manager.minSection] = Boolean.valueOf(newEmptyValue); -+ } -+ -+ tasks.schedule(); -+ -+ return tasks; -+ } -+ -+ public ChunkTasks queueChunkLightTask(final ChunkPos pos, final BooleanSupplier lightTask, final PrioritisedExecutor.Priority priority) { -+ final ChunkTasks tasks; -+ synchronized (this) { -+ tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), (final long keyInMap) -> { -+ return new ChunkTasks(keyInMap, LightQueue.this.manager, LightQueue.this, priority); -+ }); -+ if (tasks.lightTasks == null) { -+ tasks.lightTasks = new ArrayList<>(); -+ } -+ tasks.lightTasks.add(lightTask); -+ } -+ -+ tasks.schedule(); -+ -+ return tasks; -+ } -+ -+ public ChunkTasks queueChunkSkylightEdgeCheck(final SectionPos pos, final ShortCollection sections) { -+ final ChunkTasks tasks; -+ synchronized (this) { -+ tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), (final long keyInMap) -> { -+ return new ChunkTasks(keyInMap, LightQueue.this.manager, LightQueue.this); -+ }); -+ -+ ShortOpenHashSet queuedEdges = tasks.queuedEdgeChecksSky; -+ if (queuedEdges == null) { -+ queuedEdges = tasks.queuedEdgeChecksSky = new ShortOpenHashSet(); -+ } -+ queuedEdges.addAll(sections); -+ } -+ -+ tasks.schedule(); -+ -+ return tasks; -+ } -+ -+ public ChunkTasks queueChunkBlocklightEdgeCheck(final SectionPos pos, final ShortCollection sections) { -+ final ChunkTasks tasks; -+ -+ synchronized (this) { -+ tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), (final long keyInMap) -> { -+ return new ChunkTasks(keyInMap, LightQueue.this.manager, LightQueue.this); -+ }); -+ -+ ShortOpenHashSet queuedEdges = tasks.queuedEdgeChecksBlock; -+ if (queuedEdges == null) { -+ queuedEdges = tasks.queuedEdgeChecksBlock = new ShortOpenHashSet(); -+ } -+ queuedEdges.addAll(sections); -+ } -+ -+ tasks.schedule(); -+ -+ return tasks; -+ } -+ -+ public void removeChunk(final ChunkPos pos) { -+ final ChunkTasks tasks; -+ synchronized (this) { -+ tasks = this.chunkTasks.remove(CoordinateUtils.getChunkKey(pos)); -+ } -+ if (tasks != null && tasks.cancel()) { -+ tasks.onComplete.complete(null); -+ } -+ } -+ -+ public static final class ChunkTasks implements Runnable { -+ -+ public final CompletableFuture onComplete = new CompletableFuture<>(); -+ public boolean isTicketAdded; -+ public final long chunkCoordinate; -+ -+ private final StarLightInterface lightEngine; -+ private final LightQueue queue; -+ private final PrioritisedExecutor.PrioritisedTask task; -+ private final Set changedPositions = new HashSet<>(); -+ private Boolean[] changedSectionSet; -+ private ShortOpenHashSet queuedEdgeChecksSky; -+ private ShortOpenHashSet queuedEdgeChecksBlock; -+ private List lightTasks; -+ -+ public ChunkTasks(final long chunkCoordinate, final StarLightInterface lightEngine, final LightQueue queue) { -+ this(chunkCoordinate, lightEngine, queue, PrioritisedExecutor.Priority.NORMAL); -+ } -+ -+ public ChunkTasks(final long chunkCoordinate, final StarLightInterface lightEngine, final LightQueue queue, -+ final PrioritisedExecutor.Priority priority) { -+ this.chunkCoordinate = chunkCoordinate; -+ this.lightEngine = lightEngine; -+ this.queue = queue; -+ this.task = queue.world.chunkTaskScheduler.radiusAwareScheduler.createTask( -+ CoordinateUtils.getChunkX(chunkCoordinate), CoordinateUtils.getChunkZ(chunkCoordinate), -+ ChunkStatus.LIGHT.writeRadius, this, priority -+ ); -+ } -+ -+ public void schedule() { -+ this.task.queue(); -+ } -+ -+ public boolean cancel() { -+ return this.task.cancel(); -+ } -+ -+ public PrioritisedExecutor.Priority getPriority() { -+ return this.task.getPriority(); -+ } -+ -+ public void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ this.task.lowerPriority(priority); -+ } -+ -+ public void setPriority(final PrioritisedExecutor.Priority priority) { -+ this.task.setPriority(priority); -+ } -+ -+ public void raisePriority(final PrioritisedExecutor.Priority priority) { -+ this.task.raisePriority(priority); -+ } -+ -+ @Override -+ public void run() { -+ synchronized (this.queue) { -+ this.queue.chunkTasks.remove(this.chunkCoordinate); -+ } -+ -+ boolean litChunk = false; -+ if (this.lightTasks != null) { -+ for (final BooleanSupplier run : this.lightTasks) { -+ if (run.getAsBoolean()) { -+ litChunk = true; -+ break; -+ } -+ } -+ } -+ -+ final SkyStarLightEngine skyEngine = this.lightEngine.getSkyLightEngine(); -+ final BlockStarLightEngine blockEngine = this.lightEngine.getBlockLightEngine(); -+ try { -+ final long coordinate = this.chunkCoordinate; -+ final int chunkX = CoordinateUtils.getChunkX(coordinate); -+ final int chunkZ = CoordinateUtils.getChunkZ(coordinate); -+ -+ final Set positions = this.changedPositions; -+ final Boolean[] sectionChanges = this.changedSectionSet; -+ -+ if (!litChunk) { -+ if (skyEngine != null && (!positions.isEmpty() || sectionChanges != null)) { -+ skyEngine.blocksChangedInChunk(this.lightEngine.getLightAccess(), chunkX, chunkZ, positions, sectionChanges); -+ } -+ if (blockEngine != null && (!positions.isEmpty() || sectionChanges != null)) { -+ blockEngine.blocksChangedInChunk(this.lightEngine.getLightAccess(), chunkX, chunkZ, positions, sectionChanges); -+ } -+ -+ if (skyEngine != null && this.queuedEdgeChecksSky != null) { -+ skyEngine.checkChunkEdges(this.lightEngine.getLightAccess(), chunkX, chunkZ, this.queuedEdgeChecksSky); -+ } -+ if (blockEngine != null && this.queuedEdgeChecksBlock != null) { -+ blockEngine.checkChunkEdges(this.lightEngine.getLightAccess(), chunkX, chunkZ, this.queuedEdgeChecksBlock); -+ } -+ } -+ -+ this.onComplete.complete(null); -+ } finally { -+ this.lightEngine.releaseSkyLightEngine(skyEngine); -+ this.lightEngine.releaseBlockLightEngine(blockEngine); -+ } -+ } -+ } -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/poi/PoiChunk.java b/src/main/java/io/papermc/paper/chunk/system/poi/PoiChunk.java -new file mode 100644 -index 0000000000000000000000000000000000000000..d72041aa814ff179e6e29a45dcd359a91d426d47 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/poi/PoiChunk.java -@@ -0,0 +1,213 @@ -+package io.papermc.paper.chunk.system.poi; -+ -+import com.mojang.logging.LogUtils; -+import com.mojang.serialization.Codec; -+import com.mojang.serialization.DataResult; -+import io.papermc.paper.util.CoordinateUtils; -+import io.papermc.paper.util.TickThread; -+import io.papermc.paper.util.WorldUtil; -+import net.minecraft.SharedConstants; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.nbt.NbtOps; -+import net.minecraft.nbt.Tag; -+import net.minecraft.resources.RegistryOps; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.entity.ai.village.poi.PoiManager; -+import net.minecraft.world.entity.ai.village.poi.PoiSection; -+import org.slf4j.Logger; -+ -+import java.util.Optional; -+ -+public final class PoiChunk { -+ -+ private static final Logger LOGGER = LogUtils.getClassLogger(); -+ -+ public final ServerLevel world; -+ public final int chunkX; -+ public final int chunkZ; -+ public final int minSection; -+ public final int maxSection; -+ -+ protected final PoiSection[] sections; -+ -+ private boolean isDirty; -+ private boolean loaded; -+ -+ public PoiChunk(final ServerLevel world, final int chunkX, final int chunkZ, final int minSection, final int maxSection) { -+ this(world, chunkX, chunkZ, minSection, maxSection, new PoiSection[maxSection - minSection + 1]); -+ } -+ -+ public PoiChunk(final ServerLevel world, final int chunkX, final int chunkZ, final int minSection, final int maxSection, final PoiSection[] sections) { -+ this.world = world; -+ this.chunkX = chunkX; -+ this.chunkZ = chunkZ; -+ this.minSection = minSection; -+ this.maxSection = maxSection; -+ this.sections = sections; -+ if (this.sections.length != (maxSection - minSection + 1)) { -+ throw new IllegalStateException("Incorrect length used, expected " + (maxSection - minSection + 1) + ", got " + this.sections.length); -+ } -+ } -+ -+ public void load() { -+ TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Loading in poi chunk off-main"); -+ if (this.loaded) { -+ return; -+ } -+ this.loaded = true; -+ this.world.chunkSource.getPoiManager().loadInPoiChunk(this); -+ } -+ -+ public boolean isLoaded() { -+ return this.loaded; -+ } -+ -+ public boolean isEmpty() { -+ for (final PoiSection section : this.sections) { -+ if (section != null && !section.isEmpty()) { -+ return false; -+ } -+ } -+ -+ return true; -+ } -+ -+ public PoiSection getOrCreateSection(final int chunkY) { -+ if (chunkY >= this.minSection && chunkY <= this.maxSection) { -+ final int idx = chunkY - this.minSection; -+ final PoiSection ret = this.sections[idx]; -+ if (ret != null) { -+ return ret; -+ } -+ -+ final PoiManager poiManager = this.world.getPoiManager(); -+ final long key = CoordinateUtils.getChunkSectionKey(this.chunkX, chunkY, this.chunkZ); -+ -+ return this.sections[idx] = new PoiSection(() -> { -+ poiManager.setDirty(key); -+ }); -+ } -+ throw new IllegalArgumentException("chunkY is out of bounds, chunkY: " + chunkY + " outside [" + this.minSection + "," + this.maxSection + "]"); -+ } -+ -+ public PoiSection getSection(final int chunkY) { -+ if (chunkY >= this.minSection && chunkY <= this.maxSection) { -+ return this.sections[chunkY - this.minSection]; -+ } -+ return null; -+ } -+ -+ public Optional getSectionForVanilla(final int chunkY) { -+ if (chunkY >= this.minSection && chunkY <= this.maxSection) { -+ final PoiSection ret = this.sections[chunkY - this.minSection]; -+ return ret == null ? Optional.empty() : ret.noAllocateOptional; -+ } -+ return Optional.empty(); -+ } -+ -+ public boolean isDirty() { -+ return this.isDirty; -+ } -+ -+ public void setDirty(final boolean dirty) { -+ this.isDirty = dirty; -+ } -+ -+ // returns null if empty -+ public CompoundTag save() { -+ final RegistryOps registryOps = RegistryOps.create(NbtOps.INSTANCE, world.getPoiManager().registryAccess); -+ -+ final CompoundTag ret = new CompoundTag(); -+ final CompoundTag sections = new CompoundTag(); -+ ret.put("Sections", sections); -+ -+ ret.putInt("DataVersion", SharedConstants.getCurrentVersion().getDataVersion().getVersion()); -+ -+ final ServerLevel world = this.world; -+ final PoiManager poiManager = world.getPoiManager(); -+ final int chunkX = this.chunkX; -+ final int chunkZ = this.chunkZ; -+ -+ for (int sectionY = this.minSection; sectionY <= this.maxSection; ++sectionY) { -+ final PoiSection chunk = this.sections[sectionY - this.minSection]; -+ if (chunk == null || chunk.isEmpty()) { -+ continue; -+ } -+ -+ final long key = CoordinateUtils.getChunkSectionKey(chunkX, sectionY, chunkZ); -+ // codecs are honestly such a fucking disaster. What the fuck is this trash? -+ final Codec codec = PoiSection.codec(() -> { -+ poiManager.setDirty(key); -+ }); -+ -+ final DataResult serializedResult = codec.encodeStart(registryOps, chunk); -+ final int finalSectionY = sectionY; -+ final Tag serialized = serializedResult.resultOrPartial((final String description) -> { -+ LOGGER.error("Failed to serialize poi chunk for world: " + world.getWorld().getName() + ", chunk: (" + chunkX + "," + finalSectionY + "," + chunkZ + "); description: " + description); -+ }).orElse(null); -+ if (serialized == null) { -+ // failed, should be logged from the resultOrPartial -+ continue; -+ } -+ -+ sections.put(Integer.toString(sectionY), serialized); -+ } -+ -+ return sections.isEmpty() ? null : ret; -+ } -+ -+ public static PoiChunk empty(final ServerLevel world, final int chunkX, final int chunkZ) { -+ final PoiChunk ret = new PoiChunk(world, chunkX, chunkZ, WorldUtil.getMinSection(world), WorldUtil.getMaxSection(world)); -+ ret.loaded = true; -+ return ret; -+ } -+ -+ public static PoiChunk parse(final ServerLevel world, final int chunkX, final int chunkZ, final CompoundTag data) { -+ final PoiChunk ret = empty(world, chunkX, chunkZ); -+ -+ final RegistryOps registryOps = RegistryOps.create(NbtOps.INSTANCE, world.getPoiManager().registryAccess); -+ -+ final CompoundTag sections = data.getCompound("Sections"); -+ -+ if (sections.isEmpty()) { -+ // nothing to parse -+ return ret; -+ } -+ -+ final PoiManager poiManager = world.getPoiManager(); -+ -+ boolean readAnything = false; -+ -+ for (int sectionY = ret.minSection; sectionY <= ret.maxSection; ++sectionY) { -+ final String key = Integer.toString(sectionY); -+ if (!sections.contains(key)) { -+ continue; -+ } -+ -+ final long coordinateKey = CoordinateUtils.getChunkSectionKey(chunkX, sectionY, chunkZ); -+ // codecs are honestly such a fucking disaster. What the fuck is this trash? -+ final Codec codec = PoiSection.codec(() -> { -+ poiManager.setDirty(coordinateKey); -+ }); -+ -+ final CompoundTag section = sections.getCompound(key); -+ final DataResult deserializeResult = codec.parse(registryOps, section); -+ final int finalSectionY = sectionY; -+ final PoiSection deserialized = deserializeResult.resultOrPartial((final String description) -> { -+ LOGGER.error("Failed to deserialize poi chunk for world: " + world.getWorld().getName() + ", chunk: (" + chunkX + "," + finalSectionY + "," + chunkZ + "); description: " + description); -+ }).orElse(null); -+ -+ if (deserialized == null || deserialized.isEmpty()) { -+ // completely empty, no point in storing this -+ continue; -+ } -+ -+ readAnything = true; -+ ret.sections[sectionY - ret.minSection] = deserialized; -+ } -+ -+ ret.loaded = !readAnything; // Set loaded to false if we read anything to ensure proper callbacks to PoiManager are made on #load -+ -+ return ret; -+ } -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkFullTask.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkFullTask.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c307b084f59f7bb94dc02f25bbcd3e01e01d2306 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkFullTask.java -@@ -0,0 +1,131 @@ -+package io.papermc.paper.chunk.system.scheduling; -+ -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import com.mojang.logging.LogUtils; -+import io.papermc.paper.chunk.system.poi.PoiChunk; -+import net.minecraft.server.level.ChunkMap; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.status.ChunkStatus; -+import net.minecraft.world.level.chunk.ImposterProtoChunk; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.ProtoChunk; -+import org.slf4j.Logger; -+import java.lang.invoke.VarHandle; -+ -+public final class ChunkFullTask extends ChunkProgressionTask implements Runnable { -+ -+ private static final Logger LOGGER = LogUtils.getClassLogger(); -+ -+ protected final NewChunkHolder chunkHolder; -+ protected final ChunkAccess fromChunk; -+ protected final PrioritisedExecutor.PrioritisedTask convertToFullTask; -+ -+ public ChunkFullTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, final int chunkZ, -+ final NewChunkHolder chunkHolder, final ChunkAccess fromChunk, final PrioritisedExecutor.Priority priority) { -+ super(scheduler, world, chunkX, chunkZ); -+ this.chunkHolder = chunkHolder; -+ this.fromChunk = fromChunk; -+ this.convertToFullTask = scheduler.createChunkTask(chunkX, chunkZ, this, priority); -+ } -+ -+ @Override -+ public ChunkStatus getTargetStatus() { -+ return ChunkStatus.FULL; -+ } -+ -+ @Override -+ public void run() { -+ // See Vanilla protoChunkToFullChunk for what this function should be doing -+ final LevelChunk chunk; -+ try { -+ // moved from the load from nbt stage into here -+ final PoiChunk poiChunk = this.chunkHolder.getPoiChunk(); -+ if (poiChunk == null) { -+ LOGGER.error("Expected poi chunk to be loaded with chunk for task " + this.toString()); -+ } else { -+ poiChunk.load(); -+ this.world.getPoiManager().checkConsistency(this.fromChunk); -+ } -+ -+ if (this.fromChunk instanceof ImposterProtoChunk wrappedFull) { -+ chunk = wrappedFull.getWrapped(); -+ } else { -+ final ServerLevel world = this.world; -+ final ProtoChunk protoChunk = (ProtoChunk)this.fromChunk; -+ chunk = new LevelChunk(this.world, protoChunk, (final LevelChunk unused) -> { -+ ChunkMap.postLoadProtoChunk(world, protoChunk.getEntities(), protoChunk.getPos()); // Paper - rewrite chunk system -+ }); -+ } -+ -+ chunk.setChunkHolder(this.scheduler.chunkHolderManager.getChunkHolder(this.chunkX, this.chunkZ)); // replaces setFullStatus -+ chunk.runPostLoad(); -+ // Unlike Vanilla, we load the entity chunk here, as we load the NBT in empty status (unlike Vanilla) -+ // This brings entity addition back in line with older versions of the game -+ // Since we load the NBT in the empty status, this will never block for I/O -+ this.world.chunkTaskScheduler.chunkHolderManager.getOrCreateEntityChunk(this.chunkX, this.chunkZ, false); -+ -+ // we don't need the entitiesInLevel trash, this system doesn't double run callbacks -+ chunk.setLoaded(true); -+ chunk.registerAllBlockEntitiesAfterLevelLoad(); -+ chunk.registerTickContainerInLevel(this.world); -+ } catch (final Throwable throwable) { -+ this.complete(null, throwable); -+ return; -+ } -+ this.complete(chunk, null); -+ } -+ -+ protected volatile boolean scheduled; -+ protected static final VarHandle SCHEDULED_HANDLE = ConcurrentUtil.getVarHandle(ChunkFullTask.class, "scheduled", boolean.class); -+ -+ @Override -+ public boolean isScheduled() { -+ return this.scheduled; -+ } -+ -+ @Override -+ public void schedule() { -+ if ((boolean)SCHEDULED_HANDLE.getAndSet((ChunkFullTask)this, true)) { -+ throw new IllegalStateException("Cannot double call schedule()"); -+ } -+ this.convertToFullTask.queue(); -+ } -+ -+ @Override -+ public void cancel() { -+ if (this.convertToFullTask.cancel()) { -+ this.complete(null, null); -+ } -+ } -+ -+ @Override -+ public PrioritisedExecutor.Priority getPriority() { -+ return this.convertToFullTask.getPriority(); -+ } -+ -+ @Override -+ public void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } -+ this.convertToFullTask.lowerPriority(priority); -+ } -+ -+ @Override -+ public void setPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } -+ this.convertToFullTask.setPriority(priority); -+ } -+ -+ @Override -+ public void raisePriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } -+ this.convertToFullTask.raisePriority(priority); -+ } -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java -new file mode 100644 -index 0000000000000000000000000000000000000000..5b446e6ac151f99f64f0c442d0b40b5e251bc4c4 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java -@@ -0,0 +1,1500 @@ -+package io.papermc.paper.chunk.system.scheduling; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; -+import ca.spottedleaf.concurrentutil.map.SWMRLong2ObjectHashTable; -+import com.google.common.collect.ImmutableList; -+import com.google.gson.JsonArray; -+import com.google.gson.JsonObject; -+import com.mojang.logging.LogUtils; -+import io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader; -+import io.papermc.paper.chunk.system.io.RegionFileIOThread; -+import io.papermc.paper.chunk.system.poi.PoiChunk; -+import io.papermc.paper.threadedregions.TickRegions; -+import io.papermc.paper.util.CoordinateUtils; -+import io.papermc.paper.util.TickThread; -+import io.papermc.paper.world.ChunkEntitySlices; -+import it.unimi.dsi.fastutil.longs.Long2ByteLinkedOpenHashMap; -+import it.unimi.dsi.fastutil.longs.Long2ByteMap; -+import it.unimi.dsi.fastutil.longs.Long2IntLinkedOpenHashMap; -+import it.unimi.dsi.fastutil.longs.Long2IntMap; -+import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; -+import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -+import it.unimi.dsi.fastutil.longs.LongArrayList; -+import it.unimi.dsi.fastutil.longs.LongIterator; -+import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet; -+import net.minecraft.nbt.CompoundTag; -+import io.papermc.paper.chunk.system.ChunkSystem; -+import net.minecraft.server.MinecraftServer; -+import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.server.level.ChunkLevel; -+import net.minecraft.server.level.FullChunkStatus; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.Ticket; -+import net.minecraft.server.level.TicketType; -+import net.minecraft.util.SortedArraySet; -+import net.minecraft.util.Unit; -+import net.minecraft.world.level.ChunkPos; -+import org.bukkit.plugin.Plugin; -+import org.slf4j.Logger; -+import java.io.IOException; -+import java.text.DecimalFormat; -+import java.util.ArrayDeque; -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.Collections; -+import java.util.Iterator; -+import java.util.List; -+import java.util.concurrent.ConcurrentHashMap; -+import java.util.concurrent.TimeUnit; -+import java.util.concurrent.atomic.AtomicBoolean; -+import java.util.concurrent.atomic.AtomicLong; -+import java.util.concurrent.atomic.AtomicReference; -+import java.util.concurrent.locks.LockSupport; -+import java.util.function.Predicate; -+ -+public final class ChunkHolderManager { -+ -+ private static final Logger LOGGER = LogUtils.getClassLogger(); -+ -+ public static final int FULL_LOADED_TICKET_LEVEL = 33; -+ public static final int BLOCK_TICKING_TICKET_LEVEL = 32; -+ public static final int ENTITY_TICKING_TICKET_LEVEL = 31; -+ public static final int MAX_TICKET_LEVEL = ChunkLevel.MAX_LEVEL; // inclusive -+ -+ private static final long NO_TIMEOUT_MARKER = Long.MIN_VALUE; -+ private static final long PROBE_MARKER = Long.MIN_VALUE + 1; -+ public final ReentrantAreaLock ticketLockArea; -+ -+ private final ConcurrentHashMap>> tickets = new java.util.concurrent.ConcurrentHashMap<>(); -+ private final ConcurrentHashMap sectionToChunkToExpireCount = new java.util.concurrent.ConcurrentHashMap<>(); -+ final ChunkQueue unloadQueue; -+ -+ public boolean processTicketUpdates(final int posX, final int posZ) { -+ final int ticketShift = ThreadedTicketLevelPropagator.SECTION_SHIFT; -+ final int ticketMask = (1 << ticketShift) - 1; -+ final List scheduledTasks = new ArrayList<>(); -+ final List changedFullStatus = new ArrayList<>(); -+ final boolean ret; -+ final ReentrantAreaLock.Node ticketLock = this.ticketLockArea.lock( -+ ((posX >> ticketShift) - 1) << ticketShift, -+ ((posZ >> ticketShift) - 1) << ticketShift, -+ (((posX >> ticketShift) + 1) << ticketShift) | ticketMask, -+ (((posZ >> ticketShift) + 1) << ticketShift) | ticketMask -+ ); -+ try { -+ ret = this.processTicketUpdatesNoLock(posX >> ticketShift, posZ >> ticketShift, scheduledTasks, changedFullStatus); -+ } finally { -+ this.ticketLockArea.unlock(ticketLock); -+ } -+ -+ this.addChangedStatuses(changedFullStatus); -+ -+ for (int i = 0, len = scheduledTasks.size(); i < len; ++i) { -+ scheduledTasks.get(i).schedule(); -+ } -+ -+ return ret; -+ } -+ -+ private boolean processTicketUpdatesNoLock(final int sectionX, final int sectionZ, final List scheduledTasks, -+ final List changedFullStatus) { -+ return this.ticketLevelPropagator.performUpdate( -+ sectionX, sectionZ, this.taskScheduler.schedulingLockArea, scheduledTasks, changedFullStatus -+ ); -+ } -+ -+ private final SWMRLong2ObjectHashTable chunkHolders = new SWMRLong2ObjectHashTable<>(16384, 0.25f); -+ // what a disaster of a name -+ // this is a map of removal tick to a map of chunks and the number of tickets a chunk has that are to expire that tick -+ private final Long2ObjectOpenHashMap removeTickToChunkExpireTicketCount = new Long2ObjectOpenHashMap<>(); -+ private final ServerLevel world; -+ private final ChunkTaskScheduler taskScheduler; -+ private long currentTick; -+ -+ private final ArrayDeque pendingFullLoadUpdate = new ArrayDeque<>(); -+ private final ObjectRBTreeSet autoSaveQueue = new ObjectRBTreeSet<>((final NewChunkHolder c1, final NewChunkHolder c2) -> { -+ if (c1 == c2) { -+ return 0; -+ } -+ -+ final int saveTickCompare = Long.compare(c1.lastAutoSave, c2.lastAutoSave); -+ -+ if (saveTickCompare != 0) { -+ return saveTickCompare; -+ } -+ -+ final long coord1 = CoordinateUtils.getChunkKey(c1.chunkX, c1.chunkZ); -+ final long coord2 = CoordinateUtils.getChunkKey(c2.chunkX, c2.chunkZ); -+ -+ if (coord1 == coord2) { -+ throw new IllegalStateException("Duplicate chunkholder in auto save queue"); -+ } -+ -+ return Long.compare(coord1, coord2); -+ }); -+ -+ public ChunkHolderManager(final ServerLevel world, final ChunkTaskScheduler taskScheduler) { -+ this.world = world; -+ this.taskScheduler = taskScheduler; -+ this.ticketLockArea = new ReentrantAreaLock(taskScheduler.getChunkSystemLockShift()); -+ this.unloadQueue = new ChunkQueue(world.getRegionChunkShift()); -+ } -+ -+ private final AtomicLong statusUpgradeId = new AtomicLong(); -+ -+ long getNextStatusUpgradeId() { -+ return this.statusUpgradeId.incrementAndGet(); -+ } -+ -+ public List getOldChunkHolders() { -+ final List holders = this.getChunkHolders(); -+ final List ret = new ArrayList<>(holders.size()); -+ for (final NewChunkHolder holder : holders) { -+ ret.add(holder.vanillaChunkHolder); -+ } -+ return ret; -+ } -+ -+ public List getChunkHolders() { -+ final List ret = new ArrayList<>(this.chunkHolders.size()); -+ this.chunkHolders.forEachValue(ret::add); -+ return ret; -+ } -+ -+ public int size() { -+ return this.chunkHolders.size(); -+ } -+ -+ public void close(final boolean save, final boolean halt) { -+ TickThread.ensureTickThread("Closing world off-main"); -+ if (halt) { -+ LOGGER.info("Waiting 60s for chunk system to halt for world '" + this.world.getWorld().getName() + "'"); -+ if (!this.taskScheduler.halt(true, TimeUnit.SECONDS.toNanos(60L))) { -+ LOGGER.warn("Failed to halt world generation/loading tasks for world '" + this.world.getWorld().getName() + "'"); -+ } else { -+ LOGGER.info("Halted chunk system for world '" + this.world.getWorld().getName() + "'"); -+ } -+ } -+ -+ if (save) { -+ this.saveAllChunks(true, true, true); -+ } -+ -+ if (this.world.chunkDataControllerNew.hasTasks() || this.world.entityDataControllerNew.hasTasks() || this.world.poiDataControllerNew.hasTasks()) { -+ RegionFileIOThread.flush(); -+ } -+ -+ // kill regionfile cache -+ try { -+ this.world.chunkDataControllerNew.getCache().close(); -+ } catch (final IOException ex) { -+ LOGGER.error("Failed to close chunk regionfile cache for world '" + this.world.getWorld().getName() + "'", ex); -+ } -+ try { -+ this.world.entityDataControllerNew.getCache().close(); -+ } catch (final IOException ex) { -+ LOGGER.error("Failed to close entity regionfile cache for world '" + this.world.getWorld().getName() + "'", ex); -+ } -+ try { -+ this.world.poiDataControllerNew.getCache().close(); -+ } catch (final IOException ex) { -+ LOGGER.error("Failed to close poi regionfile cache for world '" + this.world.getWorld().getName() + "'", ex); -+ } -+ } -+ -+ void ensureInAutosave(final NewChunkHolder holder) { -+ if (!this.autoSaveQueue.contains(holder)) { -+ holder.lastAutoSave = MinecraftServer.currentTick; -+ this.autoSaveQueue.add(holder); -+ } -+ } -+ -+ public void autoSave() { -+ final List reschedule = new ArrayList<>(); -+ final long currentTick = MinecraftServer.currentTickLong; -+ final long maxSaveTime = currentTick - this.world.paperConfig().chunks.autoSaveInterval.value(); -+ for (int autoSaved = 0; autoSaved < this.world.paperConfig().chunks.maxAutoSaveChunksPerTick && !this.autoSaveQueue.isEmpty();) { -+ final NewChunkHolder holder = this.autoSaveQueue.first(); -+ -+ if (holder.lastAutoSave > maxSaveTime) { -+ break; -+ } -+ -+ this.autoSaveQueue.remove(holder); -+ -+ holder.lastAutoSave = currentTick; -+ if (holder.save(false, false) != null) { -+ ++autoSaved; -+ } -+ -+ if (holder.getChunkStatus().isOrAfter(FullChunkStatus.FULL)) { -+ reschedule.add(holder); -+ } -+ } -+ -+ for (final NewChunkHolder holder : reschedule) { -+ if (holder.getChunkStatus().isOrAfter(FullChunkStatus.FULL)) { -+ this.autoSaveQueue.add(holder); -+ } -+ } -+ } -+ -+ public void saveAllChunks(final boolean flush, final boolean shutdown, final boolean logProgress) { -+ final List holders = this.getChunkHolders(); -+ -+ if (logProgress) { -+ LOGGER.info("Saving all chunkholders for world '" + this.world.getWorld().getName() + "'"); -+ } -+ -+ final DecimalFormat format = new DecimalFormat("#0.00"); -+ -+ int saved = 0; -+ -+ long start = System.nanoTime(); -+ long lastLog = start; -+ boolean needsFlush = false; -+ final int flushInterval = 50; -+ -+ int savedChunk = 0; -+ int savedEntity = 0; -+ int savedPoi = 0; -+ -+ for (int i = 0, len = holders.size(); i < len; ++i) { -+ final NewChunkHolder holder = holders.get(i); -+ try { -+ final NewChunkHolder.SaveStat saveStat = holder.save(shutdown, false); -+ if (saveStat != null) { -+ ++saved; -+ needsFlush = flush; -+ if (saveStat.savedChunk()) { -+ ++savedChunk; -+ } -+ if (saveStat.savedEntityChunk()) { -+ ++savedEntity; -+ } -+ if (saveStat.savedPoiChunk()) { -+ ++savedPoi; -+ } -+ } -+ } catch (final ThreadDeath thr) { -+ throw thr; -+ } catch (final Throwable thr) { -+ LOGGER.error("Failed to save chunk (" + holder.chunkX + "," + holder.chunkZ + ") in world '" + this.world.getWorld().getName() + "'", thr); -+ } -+ if (needsFlush && (saved % flushInterval) == 0) { -+ needsFlush = false; -+ RegionFileIOThread.partialFlush(flushInterval / 2); -+ } -+ if (logProgress) { -+ final long currTime = System.nanoTime(); -+ if ((currTime - lastLog) > TimeUnit.SECONDS.toNanos(10L)) { -+ lastLog = currTime; -+ LOGGER.info("Saved " + saved + " chunks (" + format.format((double)(i+1)/(double)len * 100.0) + "%) in world '" + this.world.getWorld().getName() + "'"); -+ } -+ } -+ } -+ if (flush) { -+ RegionFileIOThread.flush(); -+ if (this.world.paperConfig().chunks.flushRegionsOnSave) { -+ try { -+ this.world.chunkSource.chunkMap.regionFileCache.flush(); -+ } catch (IOException ex) { -+ LOGGER.error("Exception when flushing regions in world {}", this.world.getWorld().getName(), ex); -+ } -+ } -+ } -+ if (logProgress) { -+ LOGGER.info("Saved " + savedChunk + " block chunks, " + savedEntity + " entity chunks, " + savedPoi + " poi chunks in world '" + this.world.getWorld().getName() + "' in " + format.format(1.0E-9 * (System.nanoTime() - start)) + "s"); -+ } -+ } -+ -+ protected final ThreadedTicketLevelPropagator ticketLevelPropagator = new ThreadedTicketLevelPropagator() { -+ @Override -+ protected void processLevelUpdates(final Long2ByteLinkedOpenHashMap updates) { -+ // first the necessary chunkholders must be created, so just update the ticket levels -+ for (final Iterator iterator = updates.long2ByteEntrySet().fastIterator(); iterator.hasNext();) { -+ final Long2ByteMap.Entry entry = iterator.next(); -+ final long key = entry.getLongKey(); -+ final int newLevel = convertBetweenTicketLevels((int)entry.getByteValue()); -+ -+ NewChunkHolder current = ChunkHolderManager.this.chunkHolders.get(key); -+ if (current == null && newLevel > MAX_TICKET_LEVEL) { -+ // not loaded and it shouldn't be loaded! -+ iterator.remove(); -+ continue; -+ } -+ -+ final int currentLevel = current == null ? MAX_TICKET_LEVEL + 1 : current.getCurrentTicketLevel(); -+ if (currentLevel == newLevel) { -+ // nothing to do -+ iterator.remove(); -+ continue; -+ } -+ -+ if (current == null) { -+ // must create -+ current = ChunkHolderManager.this.createChunkHolder(key); -+ synchronized (ChunkHolderManager.this.chunkHolders) { -+ ChunkHolderManager.this.chunkHolders.put(key, current); -+ } -+ current.updateTicketLevel(newLevel); -+ } else { -+ current.updateTicketLevel(newLevel); -+ } -+ } -+ } -+ -+ @Override -+ protected void processSchedulingUpdates(final Long2ByteLinkedOpenHashMap updates, final List scheduledTasks, -+ final List changedFullStatus) { -+ final List prev = CURRENT_TICKET_UPDATE_SCHEDULING.get(); -+ CURRENT_TICKET_UPDATE_SCHEDULING.set(scheduledTasks); -+ try { -+ for (final LongIterator iterator = updates.keySet().iterator(); iterator.hasNext();) { -+ final long key = iterator.nextLong(); -+ final NewChunkHolder current = ChunkHolderManager.this.chunkHolders.get(key); -+ -+ if (current == null) { -+ throw new IllegalStateException("Expected chunk holder to be created"); -+ } -+ -+ current.processTicketLevelUpdate(scheduledTasks, changedFullStatus); -+ } -+ } finally { -+ CURRENT_TICKET_UPDATE_SCHEDULING.set(prev); -+ } -+ } -+ }; -+ // function for converting between ticket levels and propagator levels and vice versa -+ // the problem is the ticket level propagator will propagate from a set source down to zero, whereas mojang expects -+ // levels to propagate from a set value up to a maximum value. so we need to convert the levels we put into the propagator -+ // and the levels we get out of the propagator -+ -+ public static int convertBetweenTicketLevels(final int level) { -+ return ChunkLevel.MAX_LEVEL - level + 1; -+ } -+ -+ public String getTicketDebugString(final long coordinate) { -+ final ReentrantAreaLock.Node ticketLock = this.ticketLockArea.lock(CoordinateUtils.getChunkX(coordinate), CoordinateUtils.getChunkZ(coordinate)); -+ try { -+ final SortedArraySet> tickets = this.tickets.get(new RegionFileIOThread.ChunkCoordinate(coordinate)); -+ -+ return tickets != null ? tickets.first().toString() : "no_ticket"; -+ } finally { -+ if (ticketLock != null) { -+ this.ticketLockArea.unlock(ticketLock); -+ } -+ } -+ } -+ -+ public Long2ObjectOpenHashMap>> getTicketsCopy() { -+ final Long2ObjectOpenHashMap>> ret = new Long2ObjectOpenHashMap<>(); -+ final Long2ObjectOpenHashMap> sections = new Long2ObjectOpenHashMap(); -+ final int sectionShift = this.taskScheduler.getChunkSystemLockShift(); -+ for (final RegionFileIOThread.ChunkCoordinate coord : this.tickets.keySet()) { -+ sections.computeIfAbsent( -+ CoordinateUtils.getChunkKey( -+ CoordinateUtils.getChunkX(coord.key) >> sectionShift, -+ CoordinateUtils.getChunkZ(coord.key) >> sectionShift -+ ), -+ (final long keyInMap) -> { -+ return new ArrayList<>(); -+ } -+ ).add(coord); -+ } -+ -+ for (final Iterator>> iterator = sections.long2ObjectEntrySet().fastIterator(); -+ iterator.hasNext();) { -+ final Long2ObjectMap.Entry> entry = iterator.next(); -+ final long sectionKey = entry.getLongKey(); -+ final List coordinates = entry.getValue(); -+ -+ final ReentrantAreaLock.Node ticketLock = this.ticketLockArea.lock( -+ CoordinateUtils.getChunkX(sectionKey) << sectionShift, -+ CoordinateUtils.getChunkZ(sectionKey) << sectionShift -+ ); -+ try { -+ for (final RegionFileIOThread.ChunkCoordinate coord : coordinates) { -+ final SortedArraySet> tickets = this.tickets.get(coord); -+ if (tickets == null) { -+ // removed before we acquired lock -+ continue; -+ } -+ ret.put(coord.key, new SortedArraySet<>(tickets)); -+ } -+ } finally { -+ this.ticketLockArea.unlock(ticketLock); -+ } -+ } -+ -+ return ret; -+ } -+ -+ public Collection getPluginChunkTickets(int x, int z) { -+ ImmutableList.Builder ret; -+ final ReentrantAreaLock.Node ticketLock = this.ticketLockArea.lock(x, z); -+ try { -+ final long coordinate = CoordinateUtils.getChunkKey(x, z); -+ final SortedArraySet> tickets = this.tickets.get(new RegionFileIOThread.ChunkCoordinate(coordinate)); -+ -+ if (tickets == null) { -+ return Collections.emptyList(); -+ } -+ -+ ret = ImmutableList.builder(); -+ for (Ticket ticket : tickets) { -+ if (ticket.getType() == TicketType.PLUGIN_TICKET) { -+ ret.add((Plugin)ticket.key); -+ } -+ } -+ } finally { -+ this.ticketLockArea.unlock(ticketLock); -+ } -+ -+ return ret.build(); -+ } -+ -+ protected final void updateTicketLevel(final long coordinate, final int ticketLevel) { -+ if (ticketLevel > ChunkLevel.MAX_LEVEL) { -+ this.ticketLevelPropagator.removeSource(CoordinateUtils.getChunkX(coordinate), CoordinateUtils.getChunkZ(coordinate)); -+ } else { -+ this.ticketLevelPropagator.setSource(CoordinateUtils.getChunkX(coordinate), CoordinateUtils.getChunkZ(coordinate), convertBetweenTicketLevels(ticketLevel)); -+ } -+ } -+ -+ private static int getTicketLevelAt(SortedArraySet> tickets) { -+ return !tickets.isEmpty() ? tickets.first().getTicketLevel() : MAX_TICKET_LEVEL + 1; -+ } -+ -+ public boolean addTicketAtLevel(final TicketType type, final ChunkPos chunkPos, final int level, -+ final T identifier) { -+ return this.addTicketAtLevel(type, CoordinateUtils.getChunkKey(chunkPos), level, identifier); -+ } -+ -+ public boolean addTicketAtLevel(final TicketType type, final int chunkX, final int chunkZ, final int level, -+ final T identifier) { -+ return this.addTicketAtLevel(type, CoordinateUtils.getChunkKey(chunkX, chunkZ), level, identifier); -+ } -+ -+ private void addExpireCount(final int chunkX, final int chunkZ) { -+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ -+ final int sectionShift = this.world.getRegionChunkShift(); -+ final RegionFileIOThread.ChunkCoordinate sectionKey = new RegionFileIOThread.ChunkCoordinate(CoordinateUtils.getChunkKey( -+ chunkX >> sectionShift, -+ chunkZ >> sectionShift -+ )); -+ -+ this.sectionToChunkToExpireCount.computeIfAbsent(sectionKey, (final RegionFileIOThread.ChunkCoordinate keyInMap) -> { -+ return new Long2IntOpenHashMap(); -+ }).addTo(chunkKey, 1); -+ } -+ -+ private void removeExpireCount(final int chunkX, final int chunkZ) { -+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ -+ final int sectionShift = this.world.getRegionChunkShift(); -+ final RegionFileIOThread.ChunkCoordinate sectionKey = new RegionFileIOThread.ChunkCoordinate(CoordinateUtils.getChunkKey( -+ chunkX >> sectionShift, -+ chunkZ >> sectionShift -+ )); -+ -+ final Long2IntOpenHashMap removeCounts = this.sectionToChunkToExpireCount.get(sectionKey); -+ final int prevCount = removeCounts.addTo(chunkKey, -1); -+ -+ if (prevCount == 1) { -+ removeCounts.remove(chunkKey); -+ if (removeCounts.isEmpty()) { -+ this.sectionToChunkToExpireCount.remove(sectionKey); -+ } -+ } -+ } -+ -+ // supposed to return true if the ticket was added and did not replace another -+ // but, we always return false if the ticket cannot be added -+ public boolean addTicketAtLevel(final TicketType type, final long chunk, final int level, final T identifier) { -+ return this.addTicketAtLevel(type, chunk, level, identifier, true); -+ } -+ -+ boolean addTicketAtLevel(final TicketType type, final long chunk, final int level, final T identifier, final boolean lock) { -+ final long removeDelay = type.timeout <= 0 ? NO_TIMEOUT_MARKER : type.timeout; -+ if (level > MAX_TICKET_LEVEL) { -+ return false; -+ } -+ -+ final int chunkX = CoordinateUtils.getChunkX(chunk); -+ final int chunkZ = CoordinateUtils.getChunkZ(chunk); -+ final RegionFileIOThread.ChunkCoordinate chunkCoord = new RegionFileIOThread.ChunkCoordinate(chunk); -+ final Ticket ticket = new Ticket<>(type, level, identifier, removeDelay); -+ -+ final ReentrantAreaLock.Node ticketLock = lock ? this.ticketLockArea.lock(chunkX, chunkZ) : null; -+ try { -+ final SortedArraySet> ticketsAtChunk = this.tickets.computeIfAbsent(chunkCoord, (final RegionFileIOThread.ChunkCoordinate keyInMap) -> { -+ return SortedArraySet.create(4); -+ }); -+ -+ final int levelBefore = getTicketLevelAt(ticketsAtChunk); -+ final Ticket current = (Ticket)ticketsAtChunk.replace(ticket); -+ final int levelAfter = getTicketLevelAt(ticketsAtChunk); -+ -+ if (current != ticket) { -+ final long oldRemoveDelay = current.removeDelay; -+ if (removeDelay != oldRemoveDelay) { -+ if (oldRemoveDelay != NO_TIMEOUT_MARKER && removeDelay == NO_TIMEOUT_MARKER) { -+ this.removeExpireCount(chunkX, chunkZ); -+ } else if (oldRemoveDelay == NO_TIMEOUT_MARKER) { -+ // since old != new, we have that NO_TIMEOUT_MARKER != new -+ this.addExpireCount(chunkX, chunkZ); -+ } -+ } -+ } else { -+ if (removeDelay != NO_TIMEOUT_MARKER) { -+ this.addExpireCount(chunkX, chunkZ); -+ } -+ } -+ -+ if (levelBefore != levelAfter) { -+ this.updateTicketLevel(chunk, levelAfter); -+ } -+ -+ return current == ticket; -+ } finally { -+ if (ticketLock != null) { -+ this.ticketLockArea.unlock(ticketLock); -+ } -+ } -+ } -+ -+ public boolean removeTicketAtLevel(final TicketType type, final ChunkPos chunkPos, final int level, final T identifier) { -+ return this.removeTicketAtLevel(type, CoordinateUtils.getChunkKey(chunkPos), level, identifier); -+ } -+ -+ public boolean removeTicketAtLevel(final TicketType type, final int chunkX, final int chunkZ, final int level, final T identifier) { -+ return this.removeTicketAtLevel(type, CoordinateUtils.getChunkKey(chunkX, chunkZ), level, identifier); -+ } -+ -+ public boolean removeTicketAtLevel(final TicketType type, final long chunk, final int level, final T identifier) { -+ return this.removeTicketAtLevel(type, chunk, level, identifier, true); -+ } -+ -+ boolean removeTicketAtLevel(final TicketType type, final long chunk, final int level, final T identifier, final boolean lock) { -+ if (level > MAX_TICKET_LEVEL) { -+ return false; -+ } -+ -+ final int chunkX = CoordinateUtils.getChunkX(chunk); -+ final int chunkZ = CoordinateUtils.getChunkZ(chunk); -+ final RegionFileIOThread.ChunkCoordinate chunkCoord = new RegionFileIOThread.ChunkCoordinate(chunk); -+ final Ticket probe = new Ticket<>(type, level, identifier, PROBE_MARKER); -+ -+ final ReentrantAreaLock.Node ticketLock = lock ? this.ticketLockArea.lock(chunkX, chunkZ) : null; -+ try { -+ final SortedArraySet> ticketsAtChunk = this.tickets.get(chunkCoord); -+ if (ticketsAtChunk == null) { -+ return false; -+ } -+ -+ final int oldLevel = getTicketLevelAt(ticketsAtChunk); -+ final Ticket ticket = (Ticket)ticketsAtChunk.removeAndGet(probe); -+ -+ if (ticket == null) { -+ return false; -+ } -+ -+ final int newLevel = getTicketLevelAt(ticketsAtChunk); -+ // we should not change the ticket levels while the target region may be ticking -+ if (oldLevel != newLevel) { -+ // Delay unload chunk patch originally by Aikar, updated to 1.20 by jpenilla -+ // these days, the patch is mostly useful to keep chunks ticking when players teleport -+ // so that their pets can teleport with them as well. -+ final long delayTimeout = this.world.paperConfig().chunks.delayChunkUnloadsBy.ticks(); -+ final TicketType toAdd; -+ final long timeout; -+ if (type == RegionizedPlayerChunkLoader.REGION_PLAYER_TICKET && delayTimeout > 0) { -+ toAdd = TicketType.DELAY_UNLOAD; -+ timeout = delayTimeout; -+ } else { -+ toAdd = TicketType.UNKNOWN; -+ // always expect UNKNOWN to be > 1, but just in case -+ timeout = Math.max(1, toAdd.timeout); -+ } -+ final Ticket unknownTicket = new Ticket<>(toAdd, level, new ChunkPos(chunk), timeout); -+ if (ticketsAtChunk.add(unknownTicket)) { -+ this.addExpireCount(chunkX, chunkZ); -+ } else { -+ throw new IllegalStateException("Should have been able to add " + unknownTicket + " to " + ticketsAtChunk); -+ } -+ } -+ -+ final long removeDelay = ticket.removeDelay; -+ if (removeDelay != NO_TIMEOUT_MARKER) { -+ this.removeExpireCount(chunkX, chunkZ); -+ } -+ -+ return true; -+ } finally { -+ if (ticketLock != null) { -+ this.ticketLockArea.unlock(ticketLock); -+ } -+ } -+ } -+ -+ // atomic with respect to all add/remove/addandremove ticket calls for the given chunk -+ public void addAndRemoveTickets(final long chunk, final TicketType addType, final int addLevel, final T addIdentifier, -+ final TicketType removeType, final int removeLevel, final V removeIdentifier) { -+ final ReentrantAreaLock.Node ticketLock = this.ticketLockArea.lock(CoordinateUtils.getChunkX(chunk), CoordinateUtils.getChunkZ(chunk)); -+ try { -+ this.addTicketAtLevel(addType, chunk, addLevel, addIdentifier, false); -+ this.removeTicketAtLevel(removeType, chunk, removeLevel, removeIdentifier, false); -+ } finally { -+ this.ticketLockArea.unlock(ticketLock); -+ } -+ } -+ -+ // atomic with respect to all add/remove/addandremove ticket calls for the given chunk -+ public boolean addIfRemovedTicket(final long chunk, final TicketType addType, final int addLevel, final T addIdentifier, -+ final TicketType removeType, final int removeLevel, final V removeIdentifier) { -+ final ReentrantAreaLock.Node ticketLock = this.ticketLockArea.lock(CoordinateUtils.getChunkX(chunk), CoordinateUtils.getChunkZ(chunk)); -+ try { -+ if (this.removeTicketAtLevel(removeType, chunk, removeLevel, removeIdentifier, false)) { -+ this.addTicketAtLevel(addType, chunk, addLevel, addIdentifier, false); -+ return true; -+ } -+ return false; -+ } finally { -+ this.ticketLockArea.unlock(ticketLock); -+ } -+ } -+ -+ public void removeAllTicketsFor(final TicketType ticketType, final int ticketLevel, final T ticketIdentifier) { -+ if (ticketLevel > MAX_TICKET_LEVEL) { -+ return; -+ } -+ -+ final Long2ObjectOpenHashMap> sections = new Long2ObjectOpenHashMap(); -+ final int sectionShift = this.taskScheduler.getChunkSystemLockShift(); -+ for (final RegionFileIOThread.ChunkCoordinate coord : this.tickets.keySet()) { -+ sections.computeIfAbsent( -+ CoordinateUtils.getChunkKey( -+ CoordinateUtils.getChunkX(coord.key) >> sectionShift, -+ CoordinateUtils.getChunkZ(coord.key) >> sectionShift -+ ), -+ (final long keyInMap) -> { -+ return new ArrayList<>(); -+ } -+ ).add(coord); -+ } -+ -+ for (final Iterator>> iterator = sections.long2ObjectEntrySet().fastIterator(); -+ iterator.hasNext();) { -+ final Long2ObjectMap.Entry> entry = iterator.next(); -+ final long sectionKey = entry.getLongKey(); -+ final List coordinates = entry.getValue(); -+ -+ final ReentrantAreaLock.Node ticketLock = this.ticketLockArea.lock( -+ CoordinateUtils.getChunkX(sectionKey) << sectionShift, -+ CoordinateUtils.getChunkZ(sectionKey) << sectionShift -+ ); -+ try { -+ for (final RegionFileIOThread.ChunkCoordinate coord : coordinates) { -+ this.removeTicketAtLevel(ticketType, coord.key, ticketLevel, ticketIdentifier, false); -+ } -+ } finally { -+ this.ticketLockArea.unlock(ticketLock); -+ } -+ } -+ } -+ -+ public void tick() { -+ final int sectionShift = this.world.getRegionChunkShift(); -+ -+ final Predicate> expireNow = (final Ticket ticket) -> { -+ if (ticket.removeDelay == NO_TIMEOUT_MARKER) { -+ return false; -+ } -+ return --ticket.removeDelay <= 0L; -+ }; -+ -+ for (final Iterator iterator = this.sectionToChunkToExpireCount.keySet().iterator(); iterator.hasNext();) { -+ final RegionFileIOThread.ChunkCoordinate section = iterator.next(); -+ final long sectionKey = section.key; -+ -+ if (!this.sectionToChunkToExpireCount.containsKey(section)) { -+ // removed concurrently -+ continue; -+ } -+ -+ final ReentrantAreaLock.Node ticketLock = this.ticketLockArea.lock( -+ CoordinateUtils.getChunkX(sectionKey) << sectionShift, -+ CoordinateUtils.getChunkZ(sectionKey) << sectionShift -+ ); -+ -+ try { -+ final Long2IntOpenHashMap chunkToExpireCount = this.sectionToChunkToExpireCount.get(section); -+ if (chunkToExpireCount == null) { -+ // lost to some race -+ continue; -+ } -+ -+ for (final Iterator iterator1 = chunkToExpireCount.long2IntEntrySet().fastIterator(); iterator1.hasNext();) { -+ final Long2IntMap.Entry entry = iterator1.next(); -+ -+ final long chunkKey = entry.getLongKey(); -+ final int expireCount = entry.getIntValue(); -+ -+ final RegionFileIOThread.ChunkCoordinate chunk = new RegionFileIOThread.ChunkCoordinate(chunkKey); -+ -+ final SortedArraySet> tickets = this.tickets.get(chunk); -+ final int levelBefore = getTicketLevelAt(tickets); -+ -+ final int sizeBefore = tickets.size(); -+ tickets.removeIf(expireNow); -+ final int sizeAfter = tickets.size(); -+ final int levelAfter = getTicketLevelAt(tickets); -+ -+ if (tickets.isEmpty()) { -+ this.tickets.remove(chunk); -+ } -+ if (levelBefore != levelAfter) { -+ this.updateTicketLevel(chunkKey, levelAfter); -+ } -+ -+ final int newExpireCount = expireCount - (sizeBefore - sizeAfter); -+ -+ if (newExpireCount == expireCount) { -+ continue; -+ } -+ -+ if (newExpireCount != 0) { -+ entry.setValue(newExpireCount); -+ } else { -+ iterator1.remove(); -+ } -+ } -+ -+ if (chunkToExpireCount.isEmpty()) { -+ this.sectionToChunkToExpireCount.remove(section); -+ } -+ } finally { -+ this.ticketLockArea.unlock(ticketLock); -+ } -+ } -+ -+ this.processTicketUpdates(); -+ } -+ -+ public NewChunkHolder getChunkHolder(final int chunkX, final int chunkZ) { -+ return this.chunkHolders.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ } -+ -+ public NewChunkHolder getChunkHolder(final long position) { -+ return this.chunkHolders.get(position); -+ } -+ -+ public void raisePriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { -+ final NewChunkHolder chunkHolder = this.getChunkHolder(x, z); -+ if (chunkHolder != null) { -+ chunkHolder.raisePriority(priority); -+ } -+ } -+ -+ public void setPriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { -+ final NewChunkHolder chunkHolder = this.getChunkHolder(x, z); -+ if (chunkHolder != null) { -+ chunkHolder.setPriority(priority); -+ } -+ } -+ -+ public void lowerPriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { -+ final NewChunkHolder chunkHolder = this.getChunkHolder(x, z); -+ if (chunkHolder != null) { -+ chunkHolder.lowerPriority(priority); -+ } -+ } -+ -+ private NewChunkHolder createChunkHolder(final long position) { -+ final NewChunkHolder ret = new NewChunkHolder(this.world, CoordinateUtils.getChunkX(position), CoordinateUtils.getChunkZ(position), this.taskScheduler); -+ -+ ChunkSystem.onChunkHolderCreate(this.world, ret.vanillaChunkHolder); -+ ret.vanillaChunkHolder.onChunkAdd(); -+ -+ return ret; -+ } -+ -+ // because this function creates the chunk holder without a ticket, it is the caller's responsibility to ensure -+ // the chunk holder eventually unloads. this should only be used to avoid using processTicketUpdates to create chunkholders, -+ // as processTicketUpdates may call plugin logic; in every other case a ticket is appropriate -+ private NewChunkHolder getOrCreateChunkHolder(final int chunkX, final int chunkZ) { -+ return this.getOrCreateChunkHolder(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ } -+ -+ private NewChunkHolder getOrCreateChunkHolder(final long position) { -+ final int chunkX = CoordinateUtils.getChunkX(position); -+ final int chunkZ = CoordinateUtils.getChunkZ(position); -+ -+ if (!this.ticketLockArea.isHeldByCurrentThread(chunkX, chunkZ)) { -+ throw new IllegalStateException("Must hold ticket level update lock!"); -+ } -+ if (!this.taskScheduler.schedulingLockArea.isHeldByCurrentThread(chunkX, chunkZ)) { -+ throw new IllegalStateException("Must hold scheduler lock!!"); -+ } -+ -+ // we could just acquire these locks, but... -+ // must own the locks because the caller needs to ensure that no unload can occur AFTER this function returns -+ -+ NewChunkHolder current = this.chunkHolders.get(position); -+ if (current != null) { -+ return current; -+ } -+ -+ current = this.createChunkHolder(position); -+ synchronized (this.chunkHolders) { -+ this.chunkHolders.put(position, current); -+ } -+ -+ return current; -+ } -+ -+ private final AtomicLong entityLoadCounter = new AtomicLong(); -+ -+ public ChunkEntitySlices getOrCreateEntityChunk(final int chunkX, final int chunkZ, final boolean transientChunk) { -+ TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Cannot create entity chunk off-main"); -+ ChunkEntitySlices ret; -+ -+ NewChunkHolder current = this.getChunkHolder(chunkX, chunkZ); -+ if (current != null && (ret = current.getEntityChunk()) != null && (transientChunk || !ret.isTransient())) { -+ return ret; -+ } -+ -+ final AtomicBoolean isCompleted = new AtomicBoolean(); -+ final Thread waiter = Thread.currentThread(); -+ final Long entityLoadId = Long.valueOf(this.entityLoadCounter.getAndIncrement()); -+ NewChunkHolder.GenericDataLoadTaskCallback loadTask = null; -+ final ReentrantAreaLock.Node ticketLock = this.ticketLockArea.lock(chunkX, chunkZ); -+ try { -+ this.addTicketAtLevel(TicketType.ENTITY_LOAD, chunkX, chunkZ, MAX_TICKET_LEVEL, entityLoadId); -+ final ReentrantAreaLock.Node schedulingLock = this.taskScheduler.schedulingLockArea.lock(chunkX, chunkZ); -+ try { -+ current = this.getOrCreateChunkHolder(chunkX, chunkZ); -+ if ((ret = current.getEntityChunk()) != null && (transientChunk || !ret.isTransient())) { -+ this.removeTicketAtLevel(TicketType.ENTITY_LOAD, chunkX, chunkZ, MAX_TICKET_LEVEL, entityLoadId); -+ return ret; -+ } -+ -+ if (current.isEntityChunkNBTLoaded()) { -+ isCompleted.setPlain(true); -+ } else { -+ loadTask = current.getOrLoadEntityData((final GenericDataLoadTask.TaskResult result) -> { -+ if (!transientChunk) { -+ isCompleted.set(true); -+ LockSupport.unpark(waiter); -+ } -+ }); -+ final ChunkLoadTask.EntityDataLoadTask entityLoad = current.getEntityDataLoadTask(); -+ -+ if (entityLoad != null && !transientChunk) { -+ entityLoad.raisePriority(PrioritisedExecutor.Priority.BLOCKING); -+ } -+ } -+ } finally { -+ this.taskScheduler.schedulingLockArea.unlock(schedulingLock); -+ } -+ } finally { -+ this.ticketLockArea.unlock(ticketLock); -+ } -+ -+ if (loadTask != null) { -+ loadTask.schedule(); -+ } -+ -+ if (!transientChunk) { -+ // Note: no need to busy wait on the chunk queue, entity load will complete off-main -+ boolean interrupted = false; -+ while (!isCompleted.get()) { -+ interrupted |= Thread.interrupted(); -+ LockSupport.park(); -+ } -+ -+ if (interrupted) { -+ Thread.currentThread().interrupt(); -+ } -+ } -+ -+ // now that the entity data is loaded, we can load it into the world -+ -+ ret = current.loadInEntityChunk(transientChunk); -+ -+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ this.addAndRemoveTickets(chunkKey, -+ TicketType.UNKNOWN, MAX_TICKET_LEVEL, new ChunkPos(chunkX, chunkZ), -+ TicketType.ENTITY_LOAD, MAX_TICKET_LEVEL, entityLoadId -+ ); -+ -+ return ret; -+ } -+ -+ public PoiChunk getPoiChunkIfLoaded(final int chunkX, final int chunkZ, final boolean checkLoadInCallback) { -+ final NewChunkHolder holder = this.getChunkHolder(chunkX, chunkZ); -+ if (holder != null) { -+ final PoiChunk ret = holder.getPoiChunk(); -+ return ret == null || (checkLoadInCallback && !ret.isLoaded()) ? null : ret; -+ } -+ return null; -+ } -+ -+ private final AtomicLong poiLoadCounter = new AtomicLong(); -+ -+ public PoiChunk loadPoiChunk(final int chunkX, final int chunkZ) { -+ TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Cannot create poi chunk off-main"); -+ PoiChunk ret; -+ -+ NewChunkHolder current = this.getChunkHolder(chunkX, chunkZ); -+ if (current != null && (ret = current.getPoiChunk()) != null) { -+ if (!ret.isLoaded()) { -+ ret.load(); -+ } -+ return ret; -+ } -+ -+ final AtomicReference completed = new AtomicReference<>(); -+ final AtomicBoolean isCompleted = new AtomicBoolean(); -+ final Thread waiter = Thread.currentThread(); -+ final Long poiLoadId = Long.valueOf(this.poiLoadCounter.getAndIncrement()); -+ NewChunkHolder.GenericDataLoadTaskCallback loadTask = null; -+ final ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock.Node ticketLock = this.ticketLockArea.lock(chunkX, chunkZ); // Folia - use area based lock to reduce contention -+ try { -+ // Folia - use area based lock to reduce contention -+ this.addTicketAtLevel(TicketType.POI_LOAD, chunkX, chunkZ, MAX_TICKET_LEVEL, poiLoadId); -+ final ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock.Node schedulingLock = this.taskScheduler.schedulingLockArea.lock(chunkX, chunkZ); // Folia - use area based lock to reduce contention -+ try { -+ current = this.getOrCreateChunkHolder(chunkX, chunkZ); -+ if (current.isPoiChunkLoaded()) { -+ this.removeTicketAtLevel(TicketType.POI_LOAD, chunkX, chunkZ, MAX_TICKET_LEVEL, poiLoadId); -+ return current.getPoiChunk(); -+ } -+ -+ loadTask = current.getOrLoadPoiData((final GenericDataLoadTask.TaskResult result) -> { -+ completed.setPlain(result.left()); -+ isCompleted.set(true); -+ LockSupport.unpark(waiter); -+ }); -+ final ChunkLoadTask.PoiDataLoadTask poiLoad = current.getPoiDataLoadTask(); -+ -+ if (poiLoad != null) { -+ poiLoad.raisePriority(PrioritisedExecutor.Priority.BLOCKING); -+ } -+ } finally { -+ this.taskScheduler.schedulingLockArea.unlock(schedulingLock); // Folia - use area based lock to reduce contention -+ } -+ } finally { -+ this.ticketLockArea.unlock(ticketLock); // Folia - use area based lock to reduce contention -+ } -+ -+ if (loadTask != null) { -+ loadTask.schedule(); -+ } -+ -+ // Note: no need to busy wait on the chunk queue, poi load will complete off-main -+ -+ boolean interrupted = false; -+ while (!isCompleted.get()) { -+ interrupted |= Thread.interrupted(); -+ LockSupport.park(); -+ } -+ -+ if (interrupted) { -+ Thread.currentThread().interrupt(); -+ } -+ -+ ret = completed.getPlain(); -+ -+ ret.load(); -+ -+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ this.addAndRemoveTickets(chunkKey, -+ TicketType.UNKNOWN, MAX_TICKET_LEVEL, new ChunkPos(chunkX, chunkZ), -+ TicketType.POI_LOAD, MAX_TICKET_LEVEL, poiLoadId -+ ); -+ -+ return ret; -+ } -+ -+ void addChangedStatuses(final List changedFullStatus) { -+ if (changedFullStatus.isEmpty()) { -+ return; -+ } -+ if (!TickThread.isTickThread()) { -+ this.taskScheduler.scheduleChunkTask(() -> { -+ final ArrayDeque pendingFullLoadUpdate = ChunkHolderManager.this.pendingFullLoadUpdate; -+ for (int i = 0, len = changedFullStatus.size(); i < len; ++i) { -+ pendingFullLoadUpdate.add(changedFullStatus.get(i)); -+ } -+ -+ ChunkHolderManager.this.processPendingFullUpdate(); -+ }, PrioritisedExecutor.Priority.HIGHEST); -+ } else { -+ final ArrayDeque pendingFullLoadUpdate = this.pendingFullLoadUpdate; -+ for (int i = 0, len = changedFullStatus.size(); i < len; ++i) { -+ pendingFullLoadUpdate.add(changedFullStatus.get(i)); -+ } -+ } -+ } -+ -+ private void removeChunkHolder(final NewChunkHolder holder) { -+ holder.killed = true; -+ holder.vanillaChunkHolder.onChunkRemove(); -+ this.autoSaveQueue.remove(holder); -+ ChunkSystem.onChunkHolderDelete(this.world, holder.vanillaChunkHolder); -+ synchronized (this.chunkHolders) { -+ this.chunkHolders.remove(CoordinateUtils.getChunkKey(holder.chunkX, holder.chunkZ)); -+ } -+ } -+ -+ // note: never call while inside the chunk system, this will absolutely break everything -+ public void processUnloads() { -+ TickThread.ensureTickThread("Cannot unload chunks off-main"); -+ -+ if (BLOCK_TICKET_UPDATES.get() == Boolean.TRUE) { -+ throw new IllegalStateException("Cannot unload chunks recursively"); -+ } -+ final int sectionShift = this.unloadQueue.coordinateShift; // sectionShift <= lock shift -+ final List unloadSectionsForRegion = this.unloadQueue.retrieveForAllRegions(); -+ int unloadCountTentative = 0; -+ for (final ChunkQueue.SectionToUnload sectionRef : unloadSectionsForRegion) { -+ final ChunkQueue.UnloadSection section -+ = this.unloadQueue.getSectionUnsynchronized(sectionRef.sectionX(), sectionRef.sectionZ()); -+ -+ if (section == null) { -+ // removed concurrently -+ continue; -+ } -+ -+ // technically reading the size field is unsafe, and it may be incorrect. -+ // We assume that the error here cumulatively goes away over many ticks. If it did not, then it is possible -+ // for chunks to never unload or not unload fast enough. -+ unloadCountTentative += section.chunks.size(); -+ } -+ -+ if (unloadCountTentative <= 0) { -+ // no work to do -+ return; -+ } -+ -+ // Note: The behaviour that we process ticket updates while holding the lock has been dropped here, as it is racey behavior. -+ // But, we do need to process updates here so that any add ticket that is synchronised before this call does not go missed. -+ this.processTicketUpdates(); -+ -+ final int toUnloadCount = Math.max(50, (int)(unloadCountTentative * 0.05)); -+ int processedCount = 0; -+ -+ for (final ChunkQueue.SectionToUnload sectionRef : unloadSectionsForRegion) { -+ final List stage1 = new ArrayList<>(); -+ final List stage2 = new ArrayList<>(); -+ -+ final int sectionLowerX = sectionRef.sectionX() << sectionShift; -+ final int sectionLowerZ = sectionRef.sectionZ() << sectionShift; -+ -+ // stage 1: set up for stage 2 while holding critical locks -+ ReentrantAreaLock.Node ticketLock = this.ticketLockArea.lock(sectionLowerX, sectionLowerZ); -+ try { -+ final ReentrantAreaLock.Node scheduleLock = this.taskScheduler.schedulingLockArea.lock(sectionLowerX, sectionLowerZ); -+ try { -+ final ChunkQueue.UnloadSection section -+ = this.unloadQueue.getSectionUnsynchronized(sectionRef.sectionX(), sectionRef.sectionZ()); -+ -+ if (section == null) { -+ // removed concurrently -+ continue; -+ } -+ -+ // collect the holders to run stage 1 on -+ final int sectionCount = section.chunks.size(); -+ -+ if ((sectionCount + processedCount) <= toUnloadCount) { -+ // we can just drain the entire section -+ -+ for (final LongIterator iterator = section.chunks.iterator(); iterator.hasNext();) { -+ final NewChunkHolder holder = this.chunkHolders.get(iterator.nextLong()); -+ if (holder == null) { -+ throw new IllegalStateException(); -+ } -+ stage1.add(holder); -+ } -+ -+ // remove section -+ this.unloadQueue.removeSection(sectionRef.sectionX(), sectionRef.sectionZ()); -+ } else { -+ // processedCount + len = toUnloadCount -+ // we cannot drain the entire section -+ for (int i = 0, len = toUnloadCount - processedCount; i < len; ++i) { -+ final NewChunkHolder holder = this.chunkHolders.get(section.chunks.removeFirstLong()); -+ if (holder == null) { -+ throw new IllegalStateException(); -+ } -+ stage1.add(holder); -+ } -+ } -+ -+ // run stage 1 -+ for (int i = 0, len = stage1.size(); i < len; ++i) { -+ final NewChunkHolder chunkHolder = stage1.get(i); -+ if (chunkHolder.isSafeToUnload() != null) { -+ LOGGER.error("Chunkholder " + chunkHolder + " is not safe to unload but is inside the unload queue?"); -+ continue; -+ } -+ final NewChunkHolder.UnloadState state = chunkHolder.unloadStage1(); -+ if (state == null) { -+ // can unload immediately -+ this.removeChunkHolder(chunkHolder); -+ continue; -+ } -+ stage2.add(state); -+ } -+ } finally { -+ this.taskScheduler.schedulingLockArea.unlock(scheduleLock); -+ } -+ } finally { -+ this.ticketLockArea.unlock(ticketLock); -+ } -+ -+ // stage 2: invoke expensive unload logic, designed to run without locks thanks to stage 1 -+ final List stage3 = new ArrayList<>(stage2.size()); -+ -+ final Boolean before = this.blockTicketUpdates(); -+ try { -+ for (int i = 0, len = stage2.size(); i < len; ++i) { -+ final NewChunkHolder.UnloadState state = stage2.get(i); -+ final NewChunkHolder holder = state.holder(); -+ -+ holder.unloadStage2(state); -+ stage3.add(holder); -+ } -+ } finally { -+ this.unblockTicketUpdates(before); -+ } -+ -+ // stage 3: actually attempt to remove the chunk holders -+ ticketLock = this.ticketLockArea.lock(sectionLowerX, sectionLowerZ); -+ try { -+ final ReentrantAreaLock.Node scheduleLock = this.taskScheduler.schedulingLockArea.lock(sectionLowerX, sectionLowerZ); -+ try { -+ for (int i = 0, len = stage3.size(); i < len; ++i) { -+ final NewChunkHolder holder = stage3.get(i); -+ -+ if (holder.unloadStage3()) { -+ this.removeChunkHolder(holder); -+ } else { -+ // add cooldown so the next unload check is not immediately next tick -+ this.addTicketAtLevel(TicketType.UNLOAD_COOLDOWN, CoordinateUtils.getChunkKey(holder.chunkX, holder.chunkZ), MAX_TICKET_LEVEL, Unit.INSTANCE, false); -+ } -+ } -+ } finally { -+ this.taskScheduler.schedulingLockArea.unlock(scheduleLock); -+ } -+ } finally { -+ this.ticketLockArea.unlock(ticketLock); -+ } -+ -+ processedCount += stage1.size(); -+ -+ if (processedCount >= toUnloadCount) { -+ break; -+ } -+ } -+ } -+ -+ public enum TicketOperationType { -+ ADD, REMOVE, ADD_IF_REMOVED, ADD_AND_REMOVE -+ } -+ -+ public static record TicketOperation ( -+ TicketOperationType op, long chunkCoord, -+ TicketType ticketType, int ticketLevel, T identifier, -+ TicketType ticketType2, int ticketLevel2, V identifier2 -+ ) { -+ -+ private TicketOperation(TicketOperationType op, long chunkCoord, -+ TicketType ticketType, int ticketLevel, T identifier) { -+ this(op, chunkCoord, ticketType, ticketLevel, identifier, null, 0, null); -+ } -+ -+ public static TicketOperation addOp(final ChunkPos chunk, final TicketType type, final int ticketLevel, final T identifier) { -+ return addOp(CoordinateUtils.getChunkKey(chunk), type, ticketLevel, identifier); -+ } -+ -+ public static TicketOperation addOp(final int chunkX, final int chunkZ, final TicketType type, final int ticketLevel, final T identifier) { -+ return addOp(CoordinateUtils.getChunkKey(chunkX, chunkZ), type, ticketLevel, identifier); -+ } -+ -+ public static TicketOperation addOp(final long chunk, final TicketType type, final int ticketLevel, final T identifier) { -+ return new TicketOperation<>(TicketOperationType.ADD, chunk, type, ticketLevel, identifier); -+ } -+ -+ public static TicketOperation removeOp(final ChunkPos chunk, final TicketType type, final int ticketLevel, final T identifier) { -+ return removeOp(CoordinateUtils.getChunkKey(chunk), type, ticketLevel, identifier); -+ } -+ -+ public static TicketOperation removeOp(final int chunkX, final int chunkZ, final TicketType type, final int ticketLevel, final T identifier) { -+ return removeOp(CoordinateUtils.getChunkKey(chunkX, chunkZ), type, ticketLevel, identifier); -+ } -+ -+ public static TicketOperation removeOp(final long chunk, final TicketType type, final int ticketLevel, final T identifier) { -+ return new TicketOperation<>(TicketOperationType.REMOVE, chunk, type, ticketLevel, identifier); -+ } -+ -+ public static TicketOperation addIfRemovedOp(final long chunk, -+ final TicketType addType, final int addLevel, final T addIdentifier, -+ final TicketType removeType, final int removeLevel, final V removeIdentifier) { -+ return new TicketOperation<>( -+ TicketOperationType.ADD_IF_REMOVED, chunk, addType, addLevel, addIdentifier, -+ removeType, removeLevel, removeIdentifier -+ ); -+ } -+ -+ public static TicketOperation addAndRemove(final long chunk, -+ final TicketType addType, final int addLevel, final T addIdentifier, -+ final TicketType removeType, final int removeLevel, final V removeIdentifier) { -+ return new TicketOperation<>( -+ TicketOperationType.ADD_AND_REMOVE, chunk, addType, addLevel, addIdentifier, -+ removeType, removeLevel, removeIdentifier -+ ); -+ } -+ } -+ -+ private boolean processTicketOp(TicketOperation operation) { -+ boolean ret = false; -+ switch (operation.op) { -+ case ADD: { -+ ret |= this.addTicketAtLevel(operation.ticketType, operation.chunkCoord, operation.ticketLevel, operation.identifier); -+ break; -+ } -+ case REMOVE: { -+ ret |= this.removeTicketAtLevel(operation.ticketType, operation.chunkCoord, operation.ticketLevel, operation.identifier); -+ break; -+ } -+ case ADD_IF_REMOVED: { -+ ret |= this.addIfRemovedTicket( -+ operation.chunkCoord, -+ operation.ticketType, operation.ticketLevel, operation.identifier, -+ operation.ticketType2, operation.ticketLevel2, operation.identifier2 -+ ); -+ break; -+ } -+ case ADD_AND_REMOVE: { -+ ret = true; -+ this.addAndRemoveTickets( -+ operation.chunkCoord, -+ operation.ticketType, operation.ticketLevel, operation.identifier, -+ operation.ticketType2, operation.ticketLevel2, operation.identifier2 -+ ); -+ break; -+ } -+ } -+ -+ return ret; -+ } -+ -+ public void performTicketUpdates(final Collection> operations) { -+ for (final TicketOperation operation : operations) { -+ this.processTicketOp(operation); -+ } -+ } -+ -+ private final ThreadLocal BLOCK_TICKET_UPDATES = ThreadLocal.withInitial(() -> { -+ return Boolean.FALSE; -+ }); -+ -+ public Boolean blockTicketUpdates() { -+ final Boolean ret = BLOCK_TICKET_UPDATES.get(); -+ BLOCK_TICKET_UPDATES.set(Boolean.TRUE); -+ return ret; -+ } -+ -+ public void unblockTicketUpdates(final Boolean before) { -+ BLOCK_TICKET_UPDATES.set(before); -+ } -+ -+ public boolean processTicketUpdates() { -+ return this.processTicketUpdates(true, true, null); -+ } -+ -+ private static final ThreadLocal> CURRENT_TICKET_UPDATE_SCHEDULING = new ThreadLocal<>(); -+ -+ static List getCurrentTicketUpdateScheduling() { -+ return CURRENT_TICKET_UPDATE_SCHEDULING.get(); -+ } -+ -+ private boolean processTicketUpdates(final boolean checkLocks, final boolean processFullUpdates, List scheduledTasks) { -+ TickThread.ensureTickThread("Cannot process ticket levels off-main"); -+ if (BLOCK_TICKET_UPDATES.get() == Boolean.TRUE) { -+ throw new IllegalStateException("Cannot update ticket level while unloading chunks or updating entity manager"); -+ } -+ -+ List changedFullStatus = null; -+ -+ final boolean isTickThread = TickThread.isTickThread(); -+ -+ boolean ret = false; -+ final boolean canProcessFullUpdates = processFullUpdates & isTickThread; -+ final boolean canProcessScheduling = scheduledTasks == null; -+ -+ if (this.ticketLevelPropagator.hasPendingUpdates()) { -+ if (scheduledTasks == null) { -+ scheduledTasks = new ArrayList<>(); -+ } -+ changedFullStatus = new ArrayList<>(); -+ -+ ret |= this.ticketLevelPropagator.performUpdates( -+ this.ticketLockArea, this.taskScheduler.schedulingLockArea, -+ scheduledTasks, changedFullStatus -+ ); -+ } -+ -+ if (changedFullStatus != null) { -+ this.addChangedStatuses(changedFullStatus); -+ } -+ -+ if (canProcessScheduling && scheduledTasks != null) { -+ for (int i = 0, len = scheduledTasks.size(); i < len; ++i) { -+ scheduledTasks.get(i).schedule(); -+ } -+ } -+ -+ if (canProcessFullUpdates) { -+ ret |= this.processPendingFullUpdate(); -+ } -+ -+ return ret; -+ } -+ -+ // only call on tick thread -+ protected final boolean processPendingFullUpdate() { -+ final ArrayDeque pendingFullLoadUpdate = this.pendingFullLoadUpdate; -+ -+ boolean ret = false; -+ -+ List changedFullStatus = new ArrayList<>(); -+ -+ NewChunkHolder holder; -+ while ((holder = pendingFullLoadUpdate.poll()) != null) { -+ ret |= holder.handleFullStatusChange(changedFullStatus); -+ -+ if (!changedFullStatus.isEmpty()) { -+ for (int i = 0, len = changedFullStatus.size(); i < len; ++i) { -+ pendingFullLoadUpdate.add(changedFullStatus.get(i)); -+ } -+ changedFullStatus.clear(); -+ } -+ } -+ -+ return ret; -+ } -+ -+ public JsonObject getDebugJsonForWatchdog() { -+ return this.getDebugJsonNoLock(); -+ } -+ -+ private JsonObject getDebugJsonNoLock() { -+ final JsonObject ret = new JsonObject(); -+ ret.addProperty("current_tick", Long.valueOf(this.currentTick)); -+ -+ final JsonArray unloadQueue = new JsonArray(); -+ ret.add("unload_queue", unloadQueue); -+ ret.addProperty("lock_shift", Integer.valueOf(this.taskScheduler.getChunkSystemLockShift())); -+ ret.addProperty("ticket_shift", Integer.valueOf(ThreadedTicketLevelPropagator.SECTION_SHIFT)); -+ ret.addProperty("region_shift", Integer.valueOf(this.world.getRegionChunkShift())); -+ for (final ChunkQueue.SectionToUnload section : this.unloadQueue.retrieveForAllRegions()) { -+ final JsonObject sectionJson = new JsonObject(); -+ unloadQueue.add(sectionJson); -+ sectionJson.addProperty("sectionX", section.sectionX()); -+ sectionJson.addProperty("sectionZ", section.sectionX()); -+ sectionJson.addProperty("order", section.order()); -+ -+ final JsonArray coordinates = new JsonArray(); -+ sectionJson.add("coordinates", coordinates); -+ -+ final ChunkQueue.UnloadSection actualSection = this.unloadQueue.getSectionUnsynchronized(section.sectionX(), section.sectionZ()); -+ for (final LongIterator iterator = actualSection.chunks.iterator(); iterator.hasNext();) { -+ final long coordinate = iterator.nextLong(); -+ -+ final JsonObject coordinateJson = new JsonObject(); -+ coordinates.add(coordinateJson); -+ -+ coordinateJson.addProperty("chunkX", Integer.valueOf(CoordinateUtils.getChunkX(coordinate))); -+ coordinateJson.addProperty("chunkZ", Integer.valueOf(CoordinateUtils.getChunkZ(coordinate))); -+ } -+ } -+ -+ final JsonArray holders = new JsonArray(); -+ ret.add("chunkholders", holders); -+ -+ for (final NewChunkHolder holder : this.getChunkHolders()) { -+ holders.add(holder.getDebugJson()); -+ } -+ -+ // TODO -+ /* -+ final JsonArray removeTickToChunkExpireTicketCount = new JsonArray(); -+ ret.add("remove_tick_to_chunk_expire_ticket_count", removeTickToChunkExpireTicketCount); -+ -+ for (final Long2ObjectMap.Entry tickEntry : this.removeTickToChunkExpireTicketCount.long2ObjectEntrySet()) { -+ final long tick = tickEntry.getLongKey(); -+ final Long2IntOpenHashMap coordinateToCount = tickEntry.getValue(); -+ -+ final JsonObject tickJson = new JsonObject(); -+ removeTickToChunkExpireTicketCount.add(tickJson); -+ -+ tickJson.addProperty("tick", Long.valueOf(tick)); -+ -+ final JsonArray tickEntries = new JsonArray(); -+ tickJson.add("entries", tickEntries); -+ -+ for (final Long2IntMap.Entry entry : coordinateToCount.long2IntEntrySet()) { -+ final long coordinate = entry.getLongKey(); -+ final int count = entry.getIntValue(); -+ -+ final JsonObject entryJson = new JsonObject(); -+ tickEntries.add(entryJson); -+ -+ entryJson.addProperty("chunkX", Long.valueOf(CoordinateUtils.getChunkX(coordinate))); -+ entryJson.addProperty("chunkZ", Long.valueOf(CoordinateUtils.getChunkZ(coordinate))); -+ entryJson.addProperty("count", Integer.valueOf(count)); -+ } -+ } -+ -+ final JsonArray allTicketsJson = new JsonArray(); -+ ret.add("tickets", allTicketsJson); -+ -+ for (final Long2ObjectMap.Entry>> coordinateTickets : this.tickets.long2ObjectEntrySet()) { -+ final long coordinate = coordinateTickets.getLongKey(); -+ final SortedArraySet> tickets = coordinateTickets.getValue(); -+ -+ final JsonObject coordinateJson = new JsonObject(); -+ allTicketsJson.add(coordinateJson); -+ -+ coordinateJson.addProperty("chunkX", Long.valueOf(CoordinateUtils.getChunkX(coordinate))); -+ coordinateJson.addProperty("chunkZ", Long.valueOf(CoordinateUtils.getChunkZ(coordinate))); -+ -+ final JsonArray ticketsSerialized = new JsonArray(); -+ coordinateJson.add("tickets", ticketsSerialized); -+ -+ for (final Ticket ticket : tickets) { -+ final JsonObject ticketSerialized = new JsonObject(); -+ ticketsSerialized.add(ticketSerialized); -+ -+ ticketSerialized.addProperty("type", ticket.getType().toString()); -+ ticketSerialized.addProperty("level", Integer.valueOf(ticket.getTicketLevel())); -+ ticketSerialized.addProperty("identifier", Objects.toString(ticket.key)); -+ ticketSerialized.addProperty("remove_tick", Long.valueOf(ticket.removalTick)); -+ } -+ } -+ */ -+ -+ return ret; -+ } -+ -+ public JsonObject getDebugJson() { -+ return this.getDebugJsonNoLock(); // Folia - use area based lock to reduce contention -+ } -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkLightTask.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkLightTask.java -new file mode 100644 -index 0000000000000000000000000000000000000000..86e618586d2ad9d843ad761b7336bb3073ed4c23 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkLightTask.java -@@ -0,0 +1,181 @@ -+package io.papermc.paper.chunk.system.scheduling; -+ -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.starlight.common.light.StarLightEngine; -+import ca.spottedleaf.starlight.common.light.StarLightInterface; -+import io.papermc.paper.chunk.system.light.LightQueue; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.status.ChunkStatus; -+import net.minecraft.world.level.chunk.ProtoChunk; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; -+import java.util.function.BooleanSupplier; -+ -+public final class ChunkLightTask extends ChunkProgressionTask { -+ -+ private static final Logger LOGGER = LogManager.getLogger(); -+ -+ protected final ChunkAccess fromChunk; -+ -+ private final LightTaskPriorityHolder priorityHolder; -+ -+ public ChunkLightTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, final int chunkZ, -+ final ChunkAccess chunk, final PrioritisedExecutor.Priority priority) { -+ super(scheduler, world, chunkX, chunkZ); -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } -+ this.priorityHolder = new LightTaskPriorityHolder(priority, this); -+ this.fromChunk = chunk; -+ } -+ -+ @Override -+ public boolean isScheduled() { -+ return this.priorityHolder.isScheduled(); -+ } -+ -+ @Override -+ public ChunkStatus getTargetStatus() { -+ return ChunkStatus.LIGHT; -+ } -+ -+ @Override -+ public void schedule() { -+ this.priorityHolder.schedule(); -+ } -+ -+ @Override -+ public void cancel() { -+ this.priorityHolder.cancel(); -+ } -+ -+ @Override -+ public PrioritisedExecutor.Priority getPriority() { -+ return this.priorityHolder.getPriority(); -+ } -+ -+ @Override -+ public void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ this.priorityHolder.raisePriority(priority); -+ } -+ -+ @Override -+ public void setPriority(final PrioritisedExecutor.Priority priority) { -+ this.priorityHolder.setPriority(priority); -+ } -+ -+ @Override -+ public void raisePriority(final PrioritisedExecutor.Priority priority) { -+ this.priorityHolder.raisePriority(priority); -+ } -+ -+ private static final class LightTaskPriorityHolder extends PriorityHolder { -+ -+ protected final ChunkLightTask task; -+ -+ protected LightTaskPriorityHolder(final PrioritisedExecutor.Priority priority, final ChunkLightTask task) { -+ super(priority); -+ this.task = task; -+ } -+ -+ @Override -+ protected void cancelScheduled() { -+ final ChunkLightTask task = this.task; -+ task.complete(null, null); -+ } -+ -+ @Override -+ protected PrioritisedExecutor.Priority getScheduledPriority() { -+ final ChunkLightTask task = this.task; -+ return task.world.getChunkSource().getLightEngine().theLightEngine.lightQueue.getPriority(task.chunkX, task.chunkZ); -+ } -+ -+ @Override -+ protected void scheduleTask(final PrioritisedExecutor.Priority priority) { -+ final ChunkLightTask task = this.task; -+ final StarLightInterface starLightInterface = task.world.getChunkSource().getLightEngine().theLightEngine; -+ final LightQueue lightQueue = starLightInterface.lightQueue; -+ lightQueue.queueChunkLightTask(new ChunkPos(task.chunkX, task.chunkZ), new LightTask(starLightInterface, task), priority); -+ lightQueue.setPriority(task.chunkX, task.chunkZ, priority); -+ } -+ -+ @Override -+ protected void lowerPriorityScheduled(final PrioritisedExecutor.Priority priority) { -+ final ChunkLightTask task = this.task; -+ final StarLightInterface starLightInterface = task.world.getChunkSource().getLightEngine().theLightEngine; -+ final LightQueue lightQueue = starLightInterface.lightQueue; -+ lightQueue.lowerPriority(task.chunkX, task.chunkZ, priority); -+ } -+ -+ @Override -+ protected void setPriorityScheduled(final PrioritisedExecutor.Priority priority) { -+ final ChunkLightTask task = this.task; -+ final StarLightInterface starLightInterface = task.world.getChunkSource().getLightEngine().theLightEngine; -+ final LightQueue lightQueue = starLightInterface.lightQueue; -+ lightQueue.setPriority(task.chunkX, task.chunkZ, priority); -+ } -+ -+ @Override -+ protected void raisePriorityScheduled(final PrioritisedExecutor.Priority priority) { -+ final ChunkLightTask task = this.task; -+ final StarLightInterface starLightInterface = task.world.getChunkSource().getLightEngine().theLightEngine; -+ final LightQueue lightQueue = starLightInterface.lightQueue; -+ lightQueue.raisePriority(task.chunkX, task.chunkZ, priority); -+ } -+ } -+ -+ private static final class LightTask implements BooleanSupplier { -+ -+ protected final StarLightInterface lightEngine; -+ protected final ChunkLightTask task; -+ -+ public LightTask(final StarLightInterface lightEngine, final ChunkLightTask task) { -+ this.lightEngine = lightEngine; -+ this.task = task; -+ } -+ -+ @Override -+ public boolean getAsBoolean() { -+ final ChunkLightTask task = this.task; -+ // executed on light thread -+ if (!task.priorityHolder.markExecuting()) { -+ // cancelled -+ return false; -+ } -+ -+ try { -+ final Boolean[] emptySections = StarLightEngine.getEmptySectionsForChunk(task.fromChunk); -+ -+ if (task.fromChunk.isLightCorrect() && task.fromChunk.getStatus().isOrAfter(ChunkStatus.LIGHT)) { -+ this.lightEngine.forceLoadInChunk(task.fromChunk, emptySections); -+ this.lightEngine.checkChunkEdges(task.chunkX, task.chunkZ); -+ } else { -+ task.fromChunk.setLightCorrect(false); -+ this.lightEngine.lightChunk(task.fromChunk, emptySections); -+ task.fromChunk.setLightCorrect(true); -+ } -+ // we need to advance status -+ if (task.fromChunk instanceof ProtoChunk chunk && chunk.getStatus() == ChunkStatus.LIGHT.getParent()) { -+ chunk.setStatus(ChunkStatus.LIGHT); -+ } -+ } catch (final Throwable thr) { -+ if (!(thr instanceof ThreadDeath)) { -+ LOGGER.fatal("Failed to light chunk " + task.fromChunk.getPos().toString() + " in world '" + this.lightEngine.getWorld().getWorld().getName() + "'", thr); -+ } -+ -+ task.complete(null, thr); -+ -+ if (thr instanceof ThreadDeath) { -+ throw (ThreadDeath)thr; -+ } -+ -+ return true; -+ } -+ -+ task.complete(task.fromChunk, null); -+ return true; -+ } -+ } -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkLoadTask.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkLoadTask.java -new file mode 100644 -index 0000000000000000000000000000000000000000..5ff994d5af24b0bdd7b3a16e245b2c4100bef3f0 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkLoadTask.java -@@ -0,0 +1,484 @@ -+package io.papermc.paper.chunk.system.scheduling; -+ -+import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import ca.spottedleaf.dataconverter.minecraft.MCDataConverter; -+import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; -+import com.mojang.logging.LogUtils; -+import io.papermc.paper.chunk.system.io.RegionFileIOThread; -+import io.papermc.paper.chunk.system.poi.PoiChunk; -+import net.minecraft.SharedConstants; -+import net.minecraft.core.registries.Registries; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.server.level.ChunkMap; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.status.ChunkStatus; -+import net.minecraft.world.level.chunk.ProtoChunk; -+import net.minecraft.world.level.chunk.UpgradeData; -+import net.minecraft.world.level.chunk.storage.ChunkSerializer; -+import net.minecraft.world.level.chunk.storage.EntityStorage; -+import net.minecraft.world.level.levelgen.blending.BlendingData; -+import org.slf4j.Logger; -+import java.lang.invoke.VarHandle; -+import java.util.Map; -+import java.util.concurrent.atomic.AtomicInteger; -+import java.util.function.Consumer; -+ -+public final class ChunkLoadTask extends ChunkProgressionTask { -+ -+ private static final Logger LOGGER = LogUtils.getClassLogger(); -+ -+ private final NewChunkHolder chunkHolder; -+ private final ChunkDataLoadTask loadTask; -+ -+ private volatile boolean cancelled; -+ private NewChunkHolder.GenericDataLoadTaskCallback entityLoadTask; -+ private NewChunkHolder.GenericDataLoadTaskCallback poiLoadTask; -+ private GenericDataLoadTask.TaskResult loadResult; -+ private final AtomicInteger taskCountToComplete = new AtomicInteger(3); // one for poi, one for entity, and one for chunk data -+ -+ protected ChunkLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, final int chunkZ, -+ final NewChunkHolder chunkHolder, final PrioritisedExecutor.Priority priority) { -+ super(scheduler, world, chunkX, chunkZ); -+ this.chunkHolder = chunkHolder; -+ this.loadTask = new ChunkDataLoadTask(scheduler, world, chunkX, chunkZ, priority); -+ this.loadTask.addCallback((final GenericDataLoadTask.TaskResult result) -> { -+ ChunkLoadTask.this.loadResult = result; // must be before getAndDecrement -+ ChunkLoadTask.this.tryCompleteLoad(); -+ }); -+ } -+ -+ private void tryCompleteLoad() { -+ if (this.taskCountToComplete.decrementAndGet() == 0) { -+ final GenericDataLoadTask.TaskResult result = this.cancelled ? null : this.loadResult; // only after the getAndDecrement -+ ChunkLoadTask.this.complete(result == null ? null : result.left(), result == null ? null : result.right()); -+ } -+ } -+ -+ @Override -+ public ChunkStatus getTargetStatus() { -+ return ChunkStatus.EMPTY; -+ } -+ -+ private boolean scheduled; -+ -+ @Override -+ public boolean isScheduled() { -+ return this.scheduled; -+ } -+ -+ @Override -+ public void schedule() { -+ final NewChunkHolder.GenericDataLoadTaskCallback entityLoadTask; -+ final NewChunkHolder.GenericDataLoadTaskCallback poiLoadTask; -+ -+ final Consumer> scheduleLoadTask = (final GenericDataLoadTask.TaskResult result) -> { -+ ChunkLoadTask.this.tryCompleteLoad(); -+ }; -+ -+ // NOTE: it is IMPOSSIBLE for getOrLoadEntityData/getOrLoadPoiData to complete synchronously, because -+ // they must schedule a task to off main or to on main to complete -+ final ReentrantAreaLock.Node schedulingLock = this.scheduler.schedulingLockArea.lock(this.chunkX, this.chunkZ); -+ try { -+ if (this.scheduled) { -+ throw new IllegalStateException("schedule() called twice"); -+ } -+ this.scheduled = true; -+ if (this.cancelled) { -+ return; -+ } -+ if (!this.chunkHolder.isEntityChunkNBTLoaded()) { -+ entityLoadTask = this.chunkHolder.getOrLoadEntityData((Consumer)scheduleLoadTask); -+ } else { -+ entityLoadTask = null; -+ this.taskCountToComplete.getAndDecrement(); // we know the chunk load is not done here, as it is not scheduled -+ } -+ -+ if (!this.chunkHolder.isPoiChunkLoaded()) { -+ poiLoadTask = this.chunkHolder.getOrLoadPoiData((Consumer)scheduleLoadTask); -+ } else { -+ poiLoadTask = null; -+ this.taskCountToComplete.getAndDecrement(); // we know the chunk load is not done here, as it is not scheduled -+ } -+ -+ this.entityLoadTask = entityLoadTask; -+ this.poiLoadTask = poiLoadTask; -+ } finally { -+ this.scheduler.schedulingLockArea.unlock(schedulingLock); -+ } -+ -+ if (entityLoadTask != null) { -+ entityLoadTask.schedule(); -+ } -+ -+ if (poiLoadTask != null) { -+ poiLoadTask.schedule(); -+ } -+ -+ this.loadTask.schedule(false); -+ } -+ -+ @Override -+ public void cancel() { -+ // must be before load task access, so we can synchronise with the writes to the fields -+ final boolean scheduled; -+ final ReentrantAreaLock.Node schedulingLock = this.scheduler.schedulingLockArea.lock(this.chunkX, this.chunkZ); -+ try { -+ // must read field here, as it may be written later conucrrently - -+ // we need to know if we scheduled _before_ cancellation -+ scheduled = this.scheduled; -+ this.cancelled = true; -+ } finally { -+ this.scheduler.schedulingLockArea.unlock(schedulingLock); -+ } -+ -+ /* -+ Note: The entityLoadTask/poiLoadTask do not complete when cancelled, -+ so we need to manually try to complete in those cases -+ It is also important to note that we set the cancelled field first, just in case -+ the chunk load task attempts to complete with a non-null value -+ */ -+ -+ if (scheduled) { -+ // since we scheduled, we need to cancel the tasks -+ if (this.entityLoadTask != null) { -+ if (this.entityLoadTask.cancel()) { -+ this.tryCompleteLoad(); -+ } -+ } -+ if (this.poiLoadTask != null) { -+ if (this.poiLoadTask.cancel()) { -+ this.tryCompleteLoad(); -+ } -+ } -+ } else { -+ // since nothing was scheduled, we need to decrement the task count here ourselves -+ -+ // for entity load task -+ this.tryCompleteLoad(); -+ -+ // for poi load task -+ this.tryCompleteLoad(); -+ } -+ this.loadTask.cancel(); -+ } -+ -+ @Override -+ public PrioritisedExecutor.Priority getPriority() { -+ return this.loadTask.getPriority(); -+ } -+ -+ @Override -+ public void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ final EntityDataLoadTask entityLoad = this.chunkHolder.getEntityDataLoadTask(); -+ if (entityLoad != null) { -+ entityLoad.lowerPriority(priority); -+ } -+ -+ final PoiDataLoadTask poiLoad = this.chunkHolder.getPoiDataLoadTask(); -+ -+ if (poiLoad != null) { -+ poiLoad.lowerPriority(priority); -+ } -+ -+ this.loadTask.lowerPriority(priority); -+ } -+ -+ @Override -+ public void setPriority(final PrioritisedExecutor.Priority priority) { -+ final EntityDataLoadTask entityLoad = this.chunkHolder.getEntityDataLoadTask(); -+ if (entityLoad != null) { -+ entityLoad.setPriority(priority); -+ } -+ -+ final PoiDataLoadTask poiLoad = this.chunkHolder.getPoiDataLoadTask(); -+ -+ if (poiLoad != null) { -+ poiLoad.setPriority(priority); -+ } -+ -+ this.loadTask.setPriority(priority); -+ } -+ -+ @Override -+ public void raisePriority(final PrioritisedExecutor.Priority priority) { -+ final EntityDataLoadTask entityLoad = this.chunkHolder.getEntityDataLoadTask(); -+ if (entityLoad != null) { -+ entityLoad.raisePriority(priority); -+ } -+ -+ final PoiDataLoadTask poiLoad = this.chunkHolder.getPoiDataLoadTask(); -+ -+ if (poiLoad != null) { -+ poiLoad.raisePriority(priority); -+ } -+ -+ this.loadTask.raisePriority(priority); -+ } -+ -+ protected static abstract class CallbackDataLoadTask extends GenericDataLoadTask { -+ -+ private TaskResult result; -+ private final MultiThreadedQueue>> waiters = new MultiThreadedQueue<>(); -+ -+ protected volatile boolean completed; -+ protected static final VarHandle COMPLETED_HANDLE = ConcurrentUtil.getVarHandle(CallbackDataLoadTask.class, "completed", boolean.class); -+ -+ protected CallbackDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -+ final int chunkZ, final RegionFileIOThread.RegionFileType type, -+ final PrioritisedExecutor.Priority priority) { -+ super(scheduler, world, chunkX, chunkZ, type, priority); -+ } -+ -+ public void addCallback(final Consumer> consumer) { -+ if (!this.waiters.add(consumer)) { -+ try { -+ consumer.accept(this.result); -+ } catch (final Throwable throwable) { -+ this.scheduler.unrecoverableChunkSystemFailure(this.chunkX, this.chunkZ, Map.of( -+ "Consumer", ChunkTaskScheduler.stringIfNull(consumer), -+ "Completed throwable", ChunkTaskScheduler.stringIfNull(this.result.right()) -+ ), throwable); -+ if (throwable instanceof ThreadDeath) { -+ throw (ThreadDeath)throwable; -+ } -+ } -+ } -+ } -+ -+ @Override -+ protected void onComplete(final TaskResult result) { -+ if ((boolean)COMPLETED_HANDLE.getAndSet((CallbackDataLoadTask)this, (boolean)true)) { -+ throw new IllegalStateException("Already completed"); -+ } -+ this.result = result; -+ Consumer> consumer; -+ while ((consumer = this.waiters.pollOrBlockAdds()) != null) { -+ try { -+ consumer.accept(result); -+ } catch (final Throwable throwable) { -+ this.scheduler.unrecoverableChunkSystemFailure(this.chunkX, this.chunkZ, Map.of( -+ "Consumer", ChunkTaskScheduler.stringIfNull(consumer), -+ "Completed throwable", ChunkTaskScheduler.stringIfNull(result.right()) -+ ), throwable); -+ if (throwable instanceof ThreadDeath) { -+ throw (ThreadDeath)throwable; -+ } -+ return; -+ } -+ } -+ } -+ } -+ -+ public static final class ChunkDataLoadTask extends CallbackDataLoadTask { -+ protected ChunkDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -+ final int chunkZ, final PrioritisedExecutor.Priority priority) { -+ super(scheduler, world, chunkX, chunkZ, RegionFileIOThread.RegionFileType.CHUNK_DATA, priority); -+ } -+ -+ @Override -+ protected boolean hasOffMain() { -+ return true; -+ } -+ -+ @Override -+ protected boolean hasOnMain() { -+ return false; -+ } -+ -+ @Override -+ protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ return this.scheduler.loadExecutor.createTask(run, priority); -+ } -+ -+ @Override -+ protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ protected TaskResult completeOnMainOffMain(final ChunkAccess data, final Throwable throwable) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ private ProtoChunk getEmptyChunk() { -+ return new ProtoChunk( -+ new ChunkPos(this.chunkX, this.chunkZ), UpgradeData.EMPTY, this.world, -+ this.world.registryAccess().registryOrThrow(Registries.BIOME), (BlendingData)null -+ ); -+ } -+ -+ @Override -+ protected TaskResult runOffMain(final CompoundTag data, final Throwable throwable) { -+ if (throwable != null) { -+ LOGGER.error("Failed to load chunk data for task: " + this.toString() + ", chunk data will be lost", throwable); -+ return new TaskResult<>(this.getEmptyChunk(), null); -+ } -+ -+ if (data == null) { -+ return new TaskResult<>(this.getEmptyChunk(), null); -+ } -+ -+ // need to convert data, and then deserialize it -+ -+ try { -+ final ChunkPos chunkPos = new ChunkPos(this.chunkX, this.chunkZ); -+ final ChunkMap chunkMap = this.world.getChunkSource().chunkMap; -+ // run converters -+ // note: upgradeChunkTag copies the data already -+ final CompoundTag converted = chunkMap.upgradeChunkTag( -+ this.world.getTypeKey(), chunkMap.overworldDataStorage, data, chunkMap.generator.getTypeNameForDataFixer(), -+ chunkPos, this.world -+ ); -+ // deserialize -+ final ChunkSerializer.InProgressChunkHolder chunkHolder = ChunkSerializer.readInProgressChunkHolder( -+ this.world, chunkMap.getPoiManager(), chunkPos, converted -+ ); -+ -+ return new TaskResult<>(chunkHolder.protoChunk, null); -+ } catch (final ThreadDeath death) { -+ throw death; -+ } catch (final Throwable thr2) { -+ LOGGER.error("Failed to parse chunk data for task: " + this.toString() + ", chunk data will be lost", thr2); -+ return new TaskResult<>(this.getEmptyChunk(), null); -+ } -+ } -+ -+ @Override -+ protected TaskResult runOnMain(final ChunkAccess data, final Throwable throwable) { -+ throw new UnsupportedOperationException(); -+ } -+ } -+ -+ public static final class PoiDataLoadTask extends CallbackDataLoadTask { -+ public PoiDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -+ final int chunkZ, final PrioritisedExecutor.Priority priority) { -+ super(scheduler, world, chunkX, chunkZ, RegionFileIOThread.RegionFileType.POI_DATA, priority); -+ } -+ -+ @Override -+ protected boolean hasOffMain() { -+ return true; -+ } -+ -+ @Override -+ protected boolean hasOnMain() { -+ return false; -+ } -+ -+ @Override -+ protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ return this.scheduler.loadExecutor.createTask(run, priority); -+ } -+ -+ @Override -+ protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ protected TaskResult completeOnMainOffMain(final PoiChunk data, final Throwable throwable) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ protected TaskResult runOffMain(CompoundTag data, final Throwable throwable) { -+ if (throwable != null) { -+ LOGGER.error("Failed to load poi data for task: " + this.toString() + ", poi data will be lost", throwable); -+ return new TaskResult<>(PoiChunk.empty(this.world, this.chunkX, this.chunkZ), null); -+ } -+ -+ if (data == null || data.isEmpty()) { -+ // nothing to do -+ return new TaskResult<>(PoiChunk.empty(this.world, this.chunkX, this.chunkZ), null); -+ } -+ -+ try { -+ data = data.copy(); // coming from the I/O thread, so we need to copy -+ // run converters -+ final int dataVersion = !data.contains(SharedConstants.DATA_VERSION_TAG, net.minecraft.nbt.Tag.TAG_ANY_NUMERIC) ? 1945 : data.getInt(SharedConstants.DATA_VERSION_TAG); -+ final CompoundTag converted = MCDataConverter.convertTag( -+ MCTypeRegistry.POI_CHUNK, data, dataVersion, SharedConstants.getCurrentVersion().getDataVersion().getVersion() -+ ); -+ -+ // now we need to parse it -+ return new TaskResult<>(PoiChunk.parse(this.world, this.chunkX, this.chunkZ, converted), null); -+ } catch (final ThreadDeath death) { -+ throw death; -+ } catch (final Throwable thr2) { -+ LOGGER.error("Failed to run parse poi data for task: " + this.toString() + ", poi data will be lost", thr2); -+ return new TaskResult<>(PoiChunk.empty(this.world, this.chunkX, this.chunkZ), null); -+ } -+ } -+ -+ @Override -+ protected TaskResult runOnMain(final PoiChunk data, final Throwable throwable) { -+ throw new UnsupportedOperationException(); -+ } -+ } -+ -+ public static final class EntityDataLoadTask extends CallbackDataLoadTask { -+ -+ public EntityDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -+ final int chunkZ, final PrioritisedExecutor.Priority priority) { -+ super(scheduler, world, chunkX, chunkZ, RegionFileIOThread.RegionFileType.ENTITY_DATA, priority); -+ } -+ -+ @Override -+ protected boolean hasOffMain() { -+ return true; -+ } -+ -+ @Override -+ protected boolean hasOnMain() { -+ return false; -+ } -+ -+ @Override -+ protected PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ return this.scheduler.loadExecutor.createTask(run, priority); -+ } -+ -+ @Override -+ protected PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ protected TaskResult completeOnMainOffMain(final CompoundTag data, final Throwable throwable) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ protected TaskResult runOffMain(final CompoundTag data, final Throwable throwable) { -+ if (throwable != null) { -+ LOGGER.error("Failed to load entity data for task: " + this.toString() + ", entity data will be lost", throwable); -+ return new TaskResult<>(null, null); -+ } -+ -+ if (data == null || data.isEmpty()) { -+ // nothing to do -+ return new TaskResult<>(null, null); -+ } -+ -+ try { -+ // note: data comes from the I/O thread, so we need to copy it -+ return new TaskResult<>(EntityStorage.upgradeChunkTag(data.copy()), null); -+ } catch (final ThreadDeath death) { -+ throw death; -+ } catch (final Throwable thr2) { -+ LOGGER.error("Failed to run converters for entity data for task: " + this.toString() + ", entity data will be lost", thr2); -+ return new TaskResult<>(null, thr2); -+ } -+ } -+ -+ @Override -+ protected TaskResult runOnMain(final CompoundTag data, final Throwable throwable) { -+ throw new UnsupportedOperationException(); -+ } -+ } -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkProgressionTask.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkProgressionTask.java -new file mode 100644 -index 0000000000000000000000000000000000000000..b2341328bb22f08836ef18785dc27393a36ce8d6 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkProgressionTask.java -@@ -0,0 +1,105 @@ -+package io.papermc.paper.chunk.system.scheduling; -+ -+import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.status.ChunkStatus; -+import java.lang.invoke.VarHandle; -+import java.util.Map; -+import java.util.function.BiConsumer; -+ -+public abstract class ChunkProgressionTask { -+ -+ private final MultiThreadedQueue> waiters = new MultiThreadedQueue<>(); -+ private ChunkAccess completedChunk; -+ private Throwable completedThrowable; -+ -+ protected final ChunkTaskScheduler scheduler; -+ protected final ServerLevel world; -+ protected final int chunkX; -+ protected final int chunkZ; -+ -+ protected volatile boolean completed; -+ protected static final VarHandle COMPLETED_HANDLE = ConcurrentUtil.getVarHandle(ChunkProgressionTask.class, "completed", boolean.class); -+ -+ protected ChunkProgressionTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, final int chunkZ) { -+ this.scheduler = scheduler; -+ this.world = world; -+ this.chunkX = chunkX; -+ this.chunkZ = chunkZ; -+ } -+ -+ // Used only for debug json -+ public abstract boolean isScheduled(); -+ -+ // Note: It is the responsibility of the task to set the chunk's status once it has completed -+ public abstract ChunkStatus getTargetStatus(); -+ -+ /* Only executed once */ -+ /* Implementations must be prepared to handle cases where cancel() is called before schedule() */ -+ public abstract void schedule(); -+ -+ /* May be called multiple times */ -+ public abstract void cancel(); -+ -+ public abstract PrioritisedExecutor.Priority getPriority(); -+ -+ /* Schedule lock is always held for the priority update calls */ -+ -+ public abstract void lowerPriority(final PrioritisedExecutor.Priority priority); -+ -+ public abstract void setPriority(final PrioritisedExecutor.Priority priority); -+ -+ public abstract void raisePriority(final PrioritisedExecutor.Priority priority); -+ -+ public final void onComplete(final BiConsumer onComplete) { -+ if (!this.waiters.add(onComplete)) { -+ try { -+ onComplete.accept(this.completedChunk, this.completedThrowable); -+ } catch (final Throwable throwable) { -+ this.scheduler.unrecoverableChunkSystemFailure(this.chunkX, this.chunkZ, Map.of( -+ "Consumer", ChunkTaskScheduler.stringIfNull(onComplete), -+ "Completed throwable", ChunkTaskScheduler.stringIfNull(this.completedThrowable) -+ ), throwable); -+ if (throwable instanceof ThreadDeath) { -+ throw (ThreadDeath)throwable; -+ } -+ } -+ } -+ } -+ -+ protected final void complete(final ChunkAccess chunk, final Throwable throwable) { -+ try { -+ this.complete0(chunk, throwable); -+ } catch (final Throwable thr2) { -+ this.scheduler.unrecoverableChunkSystemFailure(this.chunkX, this.chunkZ, Map.of( -+ "Completed throwable", ChunkTaskScheduler.stringIfNull(throwable) -+ ), thr2); -+ if (thr2 instanceof ThreadDeath) { -+ throw (ThreadDeath)thr2; -+ } -+ } -+ } -+ -+ private void complete0(final ChunkAccess chunk, final Throwable throwable) { -+ if ((boolean)COMPLETED_HANDLE.getAndSet((ChunkProgressionTask)this, (boolean)true)) { -+ throw new IllegalStateException("Already completed"); -+ } -+ this.completedChunk = chunk; -+ this.completedThrowable = throwable; -+ -+ BiConsumer consumer; -+ while ((consumer = this.waiters.pollOrBlockAdds()) != null) { -+ consumer.accept(chunk, throwable); -+ } -+ } -+ -+ @Override -+ public String toString() { -+ return "ChunkProgressionTask{class: " + this.getClass().getName() + ", for world: " + this.world.getWorld().getName() + -+ ", chunk: (" + this.chunkX + "," + this.chunkZ + "), hashcode: " + System.identityHashCode(this) + ", priority: " + this.getPriority() + -+ ", status: " + this.getTargetStatus().toString() + ", scheduled: " + this.isScheduled() + "}"; -+ } -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkQueue.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkQueue.java -new file mode 100644 -index 0000000000000000000000000000000000000000..4cc1b3ba6d093a9683dbd8b7fe76106ae391e019 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkQueue.java -@@ -0,0 +1,160 @@ -+package io.papermc.paper.chunk.system.scheduling; -+ -+import it.unimi.dsi.fastutil.HashCommon; -+import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet; -+import java.util.ArrayList; -+import java.util.List; -+import java.util.Map; -+import java.util.concurrent.ConcurrentHashMap; -+import java.util.concurrent.atomic.AtomicLong; -+ -+public final class ChunkQueue { -+ -+ public final int coordinateShift; -+ private final AtomicLong orderGenerator = new AtomicLong(); -+ private final ConcurrentHashMap unloadSections = new ConcurrentHashMap<>(); -+ -+ /* -+ * Note: write operations do not occur in parallel for any given section. -+ * Note: coordinateShift <= region shift in order for retrieveForCurrentRegion() to function correctly -+ */ -+ -+ public ChunkQueue(final int coordinateShift) { -+ this.coordinateShift = coordinateShift; -+ } -+ -+ public static record SectionToUnload(int sectionX, int sectionZ, Coordinate coord, long order, int count) {} -+ -+ public List retrieveForAllRegions() { -+ final List ret = new ArrayList<>(); -+ -+ for (final Map.Entry entry : this.unloadSections.entrySet()) { -+ final Coordinate coord = entry.getKey(); -+ final long key = coord.key; -+ final UnloadSection section = entry.getValue(); -+ final int sectionX = Coordinate.x(key); -+ final int sectionZ = Coordinate.z(key); -+ -+ ret.add(new SectionToUnload(sectionX, sectionZ, coord, section.order, section.chunks.size())); -+ } -+ -+ ret.sort((final SectionToUnload s1, final SectionToUnload s2) -> { -+ return Long.compare(s1.order, s2.order); -+ }); -+ -+ return ret; -+ } -+ -+ public UnloadSection getSectionUnsynchronized(final int sectionX, final int sectionZ) { -+ final Coordinate coordinate = new Coordinate(Coordinate.key(sectionX, sectionZ)); -+ return this.unloadSections.get(coordinate); -+ } -+ -+ public UnloadSection removeSection(final int sectionX, final int sectionZ) { -+ final Coordinate coordinate = new Coordinate(Coordinate.key(sectionX, sectionZ)); -+ return this.unloadSections.remove(coordinate); -+ } -+ -+ // write operation -+ public boolean addChunk(final int chunkX, final int chunkZ) { -+ final int shift = this.coordinateShift; -+ final int sectionX = chunkX >> shift; -+ final int sectionZ = chunkZ >> shift; -+ final Coordinate coordinate = new Coordinate(Coordinate.key(sectionX, sectionZ)); -+ final long chunkKey = Coordinate.key(chunkX, chunkZ); -+ -+ UnloadSection section = this.unloadSections.get(coordinate); -+ if (section == null) { -+ section = new UnloadSection(this.orderGenerator.getAndIncrement()); -+ // write operations do not occur in parallel for a given section -+ this.unloadSections.put(coordinate, section); -+ } -+ -+ return section.chunks.add(chunkKey); -+ } -+ -+ // write operation -+ public boolean removeChunk(final int chunkX, final int chunkZ) { -+ final int shift = this.coordinateShift; -+ final int sectionX = chunkX >> shift; -+ final int sectionZ = chunkZ >> shift; -+ final Coordinate coordinate = new Coordinate(Coordinate.key(sectionX, sectionZ)); -+ final long chunkKey = Coordinate.key(chunkX, chunkZ); -+ -+ final UnloadSection section = this.unloadSections.get(coordinate); -+ -+ if (section == null) { -+ return false; -+ } -+ -+ if (!section.chunks.remove(chunkKey)) { -+ return false; -+ } -+ -+ if (section.chunks.isEmpty()) { -+ this.unloadSections.remove(coordinate); -+ } -+ -+ return true; -+ } -+ -+ public static final class UnloadSection { -+ -+ public final long order; -+ public final LongLinkedOpenHashSet chunks = new LongLinkedOpenHashSet(); -+ -+ public UnloadSection(final long order) { -+ this.order = order; -+ } -+ } -+ -+ private static final class Coordinate implements Comparable { -+ -+ public final long key; -+ -+ public Coordinate(final long key) { -+ this.key = key; -+ } -+ -+ public Coordinate(final int x, final int z) { -+ this.key = key(x, z); -+ } -+ -+ public static long key(final int x, final int z) { -+ return ((long)z << 32) | (x & 0xFFFFFFFFL); -+ } -+ -+ public static int x(final long key) { -+ return (int)key; -+ } -+ -+ public static int z(final long key) { -+ return (int)(key >>> 32); -+ } -+ -+ @Override -+ public int hashCode() { -+ return (int)HashCommon.mix(this.key); -+ } -+ -+ @Override -+ public boolean equals(final Object obj) { -+ if (this == obj) { -+ return true; -+ } -+ -+ if (!(obj instanceof Coordinate other)) { -+ return false; -+ } -+ -+ return this.key == other.key; -+ } -+ -+ // This class is intended for HashMap/ConcurrentHashMap usage, which do treeify bin nodes if the chain -+ // is too large. So we should implement compareTo to help. -+ @Override -+ public int compareTo(final Coordinate other) { -+ return Long.compare(this.key, other.key); -+ } -+ } -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java -new file mode 100644 -index 0000000000000000000000000000000000000000..049e20407033073b06fcdeb46c38485f4926d778 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java -@@ -0,0 +1,883 @@ -+package io.papermc.paper.chunk.system.scheduling; -+ -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadedTaskQueue; -+import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import com.mojang.logging.LogUtils; -+import io.papermc.paper.chunk.system.io.RegionFileIOThread; -+import io.papermc.paper.chunk.system.scheduling.queue.RadiusAwarePrioritisedExecutor; -+import io.papermc.paper.configuration.GlobalConfiguration; -+import io.papermc.paper.util.CoordinateUtils; -+import io.papermc.paper.util.TickThread; -+import java.util.function.BooleanSupplier; -+import net.minecraft.CrashReport; -+import net.minecraft.CrashReportCategory; -+import net.minecraft.ReportedException; -+import io.papermc.paper.util.MCUtil; -+import net.minecraft.server.MinecraftServer; -+import net.minecraft.server.level.ChunkMap; -+import net.minecraft.server.level.FullChunkStatus; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.TicketType; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.status.ChunkStatus; -+import net.minecraft.world.level.chunk.LevelChunk; -+import org.bukkit.Bukkit; -+import org.slf4j.Logger; -+import java.io.File; -+import java.util.ArrayDeque; -+import java.util.ArrayList; -+import java.util.Arrays; -+import java.util.Collections; -+import java.util.List; -+import java.util.Map; -+import java.util.Objects; -+import java.util.concurrent.atomic.AtomicBoolean; -+import java.util.concurrent.atomic.AtomicLong; -+import java.util.function.Consumer; -+ -+public final class ChunkTaskScheduler { -+ -+ private static final Logger LOGGER = LogUtils.getClassLogger(); -+ -+ static int newChunkSystemIOThreads; -+ static int newChunkSystemWorkerThreads; -+ static int newChunkSystemGenParallelism; -+ static int newChunkSystemLoadParallelism; -+ -+ public static ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool workerThreads; -+ -+ private static boolean initialised = false; -+ -+ public static void init(final GlobalConfiguration.ChunkSystem config) { -+ if (initialised) { -+ return; -+ } -+ initialised = true; -+ newChunkSystemIOThreads = config.ioThreads; -+ newChunkSystemWorkerThreads = config.workerThreads; -+ if (newChunkSystemIOThreads < 0) { -+ newChunkSystemIOThreads = 1; -+ } else { -+ newChunkSystemIOThreads = Math.max(1, newChunkSystemIOThreads); -+ } -+ int defaultWorkerThreads = Runtime.getRuntime().availableProcessors() / 2; -+ if (defaultWorkerThreads <= 4) { -+ defaultWorkerThreads = defaultWorkerThreads <= 3 ? 1 : 2; -+ } else { -+ defaultWorkerThreads = defaultWorkerThreads / 2; -+ } -+ defaultWorkerThreads = Integer.getInteger("Paper.WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); -+ -+ if (newChunkSystemWorkerThreads < 0) { -+ newChunkSystemWorkerThreads = defaultWorkerThreads; -+ } else { -+ newChunkSystemWorkerThreads = Math.max(1, newChunkSystemWorkerThreads); -+ } -+ -+ String newChunkSystemGenParallelism = config.genParallelism; -+ if (newChunkSystemGenParallelism.equalsIgnoreCase("default")) { -+ newChunkSystemGenParallelism = "true"; -+ } -+ boolean useParallelGen; -+ if (newChunkSystemGenParallelism.equalsIgnoreCase("on") || newChunkSystemGenParallelism.equalsIgnoreCase("enabled") -+ || newChunkSystemGenParallelism.equalsIgnoreCase("true")) { -+ useParallelGen = true; -+ } else if (newChunkSystemGenParallelism.equalsIgnoreCase("off") || newChunkSystemGenParallelism.equalsIgnoreCase("disabled") -+ || newChunkSystemGenParallelism.equalsIgnoreCase("false")) { -+ useParallelGen = false; -+ } else { -+ throw new IllegalStateException("Invalid option for gen-parallelism: must be one of [on, off, enabled, disabled, true, false, default]"); -+ } -+ -+ ChunkTaskScheduler.newChunkSystemGenParallelism = useParallelGen ? newChunkSystemWorkerThreads : 1; -+ ChunkTaskScheduler.newChunkSystemLoadParallelism = newChunkSystemWorkerThreads; -+ -+ RegionFileIOThread.init(newChunkSystemIOThreads); -+ workerThreads = new ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool( -+ "Paper Chunk System Worker Pool", newChunkSystemWorkerThreads, -+ (final Thread thread, final Integer id) -> { -+ thread.setPriority(Thread.NORM_PRIORITY - 2); -+ thread.setName("Tuinity Chunk System Worker #" + id.intValue()); -+ thread.setUncaughtExceptionHandler(io.papermc.paper.chunk.system.scheduling.NewChunkHolder.CHUNKSYSTEM_UNCAUGHT_EXCEPTION_HANDLER); -+ }, (long)(20.0e6)); // 20ms -+ -+ LOGGER.info("Chunk system is using " + newChunkSystemIOThreads + " I/O threads, " + newChunkSystemWorkerThreads + " worker threads, and gen parallelism of " + ChunkTaskScheduler.newChunkSystemGenParallelism + " threads"); -+ } -+ -+ public final ServerLevel world; -+ public final PrioritisedThreadPool workers; -+ public final RadiusAwarePrioritisedExecutor radiusAwareScheduler; -+ public final PrioritisedThreadPool.PrioritisedPoolExecutor parallelGenExecutor; -+ private final PrioritisedThreadPool.PrioritisedPoolExecutor radiusAwareGenExecutor; -+ public final PrioritisedThreadPool.PrioritisedPoolExecutor loadExecutor; -+ -+ private final PrioritisedThreadedTaskQueue mainThreadExecutor = new PrioritisedThreadedTaskQueue(); -+ -+ public final ChunkHolderManager chunkHolderManager; -+ -+ static { -+ ChunkStatus.EMPTY.writeRadius = 0; -+ ChunkStatus.STRUCTURE_STARTS.writeRadius = 0; -+ ChunkStatus.STRUCTURE_REFERENCES.writeRadius = 0; -+ ChunkStatus.BIOMES.writeRadius = 0; -+ ChunkStatus.NOISE.writeRadius = 0; -+ ChunkStatus.SURFACE.writeRadius = 0; -+ ChunkStatus.CARVERS.writeRadius = 0; -+ ChunkStatus.FEATURES.writeRadius = 1; -+ ChunkStatus.INITIALIZE_LIGHT.writeRadius = 0; -+ ChunkStatus.LIGHT.writeRadius = 2; -+ ChunkStatus.SPAWN.writeRadius = 0; -+ ChunkStatus.FULL.writeRadius = 0; -+ -+ /* -+ It's important that the neighbour read radius is taken into account. If _any_ later status is using some chunk as -+ a neighbour, it must be also safe if that neighbour is being generated. i.e for any status later than FEATURES, -+ for a status to be parallel safe it must not read the block data from its neighbours. -+ */ -+ final List parallelCapableStatus = Arrays.asList( -+ // No-op executor. -+ ChunkStatus.EMPTY, -+ -+ // This is parallel capable, as CB has fixed the concurrency issue with stronghold generations. -+ // Does not touch neighbour chunks. -+ ChunkStatus.STRUCTURE_STARTS, -+ -+ // Surprisingly this is parallel capable. It is simply reading the already-created structure starts -+ // into the structure references for the chunk. So while it reads from it neighbours, its neighbours -+ // will not change, even if executed in parallel. -+ ChunkStatus.STRUCTURE_REFERENCES, -+ -+ // Safe. Mojang runs it in parallel as well. -+ ChunkStatus.BIOMES, -+ -+ // Safe. Mojang runs it in parallel as well. -+ ChunkStatus.NOISE, -+ -+ // Parallel safe. Only touches the target chunk. Biome retrieval is now noise based, which is -+ // completely thread-safe. -+ ChunkStatus.SURFACE, -+ -+ // No global state is modified in the carvers. It only touches the specified chunk. So it is parallel safe. -+ ChunkStatus.CARVERS, -+ -+ // FEATURES is not parallel safe. It writes to neighbours. -+ -+ // no-op executor -+ ChunkStatus.INITIALIZE_LIGHT -+ -+ // LIGHT is not parallel safe. It also doesn't run on the generation executor, so no point. -+ -+ // Only writes to the specified chunk. State is not read by later statuses. Parallel safe. -+ // Note: it may look unsafe because it writes to a worldgenregion, but the region size is always 0 - -+ // see the task margin. -+ // However, if the neighbouring FEATURES chunk is unloaded, but then fails to load in again (for whatever -+ // reason), then it would write to this chunk - and since this status reads blocks from itself, it's not -+ // safe to execute this in parallel. -+ // SPAWN -+ -+ // FULL is executed on main. -+ ); -+ -+ for (final ChunkStatus status : parallelCapableStatus) { -+ status.isParallelCapable = true; -+ } -+ } -+ -+ private static final int[] ACCESS_RADIUS_TABLE = new int[ChunkStatus.getStatusList().size()]; -+ private static final int[] MAX_ACCESS_RADIUS_TABLE = new int[ACCESS_RADIUS_TABLE.length]; -+ static { -+ Arrays.fill(ACCESS_RADIUS_TABLE, -1); -+ } -+ -+ private static int getAccessRadius0(final ChunkStatus genStatus) { -+ if (genStatus == ChunkStatus.EMPTY) { -+ return 0; -+ } -+ -+ final int radius = Math.max(genStatus.loadRange, genStatus.getRange()); -+ int maxRange = radius; -+ -+ for (int dist = 1; dist <= radius; ++dist) { -+ final ChunkStatus requiredNeighbourStatus = ChunkMap.getDependencyStatus(genStatus, radius); -+ final int rad = ACCESS_RADIUS_TABLE[requiredNeighbourStatus.getIndex()]; -+ if (rad == -1) { -+ throw new IllegalStateException(); -+ } -+ -+ maxRange = Math.max(maxRange, dist + rad); -+ } -+ -+ return maxRange; -+ } -+ -+ private static int maxAccessRadius; -+ -+ static { -+ final List statuses = ChunkStatus.getStatusList(); -+ for (int i = 0, len = statuses.size(); i < len; ++i) { -+ ACCESS_RADIUS_TABLE[i] = getAccessRadius0(statuses.get(i)); -+ } -+ int max = 0; -+ for (int i = 0, len = statuses.size(); i < len; ++i) { -+ MAX_ACCESS_RADIUS_TABLE[i] = max = Math.max(ACCESS_RADIUS_TABLE[i], max); -+ } -+ maxAccessRadius = max; -+ } -+ -+ public static int getMaxAccessRadius() { -+ return maxAccessRadius; -+ } -+ -+ public static int getAccessRadius(final ChunkStatus genStatus) { -+ return ACCESS_RADIUS_TABLE[genStatus.getIndex()]; -+ } -+ -+ public static int getAccessRadius(final FullChunkStatus status) { -+ return (status.ordinal() - 1) + getAccessRadius(ChunkStatus.FULL); -+ } -+ -+ final ReentrantAreaLock schedulingLockArea; -+ private final int lockShift; -+ -+ public final int getChunkSystemLockShift() { -+ return this.lockShift; -+ } -+ // Folia end - use area based lock to reduce contention -+ -+ public ChunkTaskScheduler(final ServerLevel world, final PrioritisedThreadPool workers) { -+ this.world = world; -+ this.workers = workers; -+ // must be >= region shift (in paper, doesn't exist) and must be >= ticket propagator section shift -+ // it must be >= region shift since the regioniser assumes ticket updates do not occur in parallel for the region sections -+ // it must be >= ticket propagator section shift so that the ticket propagator can assume that owning a position implies owning -+ // the entire section -+ // we just take the max, as we want the smallest shift that satisfies these properties -+ this.lockShift = Math.max(world.getRegionChunkShift(), ThreadedTicketLevelPropagator.SECTION_SHIFT); -+ this.schedulingLockArea = new ReentrantAreaLock(this.getChunkSystemLockShift()); -+ -+ final String worldName = world.getWorld().getName(); -+ this.parallelGenExecutor = workers.createExecutor("Chunk parallel generation executor for world '" + worldName + "'", Math.max(1, newChunkSystemGenParallelism)); -+ this.radiusAwareGenExecutor = -+ newChunkSystemGenParallelism <= 1 ? this.parallelGenExecutor : workers.createExecutor("Chunk radius aware generator for world '" + worldName + "'", newChunkSystemGenParallelism); -+ this.loadExecutor = workers.createExecutor("Chunk load executor for world '" + worldName + "'", newChunkSystemLoadParallelism); -+ this.radiusAwareScheduler = new RadiusAwarePrioritisedExecutor(this.radiusAwareGenExecutor, Math.max(1, newChunkSystemGenParallelism)); -+ this.chunkHolderManager = new ChunkHolderManager(world, this); -+ } -+ -+ private final AtomicBoolean failedChunkSystem = new AtomicBoolean(); -+ -+ public static Object stringIfNull(final Object obj) { -+ return obj == null ? "null" : obj; -+ } -+ -+ public void unrecoverableChunkSystemFailure(final int chunkX, final int chunkZ, final Map objectsOfInterest, final Throwable thr) { -+ final NewChunkHolder holder = this.chunkHolderManager.getChunkHolder(chunkX, chunkZ); -+ LOGGER.error("Chunk system error at chunk (" + chunkX + "," + chunkZ + "), holder: " + holder + ", exception:", new Throwable(thr)); -+ -+ if (this.failedChunkSystem.getAndSet(true)) { -+ return; -+ } -+ -+ final ReportedException reportedException = thr instanceof ReportedException ? (ReportedException)thr : new ReportedException(new CrashReport("Chunk system error", thr)); -+ -+ CrashReportCategory crashReportCategory = reportedException.getReport().addCategory("Chunk system details"); -+ crashReportCategory.setDetail("Chunk coordinate", new ChunkPos(chunkX, chunkZ).toString()); -+ crashReportCategory.setDetail("ChunkHolder", Objects.toString(holder)); -+ crashReportCategory.setDetail("unrecoverableChunkSystemFailure caller thread", Thread.currentThread().getName()); -+ -+ crashReportCategory = reportedException.getReport().addCategory("Chunk System Objects of Interest"); -+ for (final Map.Entry entry : objectsOfInterest.entrySet()) { -+ if (entry.getValue() instanceof Throwable thrObject) { -+ crashReportCategory.setDetailError(Objects.toString(entry.getKey()), thrObject); -+ } else { -+ crashReportCategory.setDetail(Objects.toString(entry.getKey()), Objects.toString(entry.getValue())); -+ } -+ } -+ -+ final Runnable crash = () -> { -+ throw new RuntimeException("Chunk system crash propagated from unrecoverableChunkSystemFailure", reportedException); -+ }; -+ -+ // this may not be good enough, specifically thanks to stupid ass plugins swallowing exceptions -+ this.scheduleChunkTask(chunkX, chunkZ, crash, PrioritisedExecutor.Priority.BLOCKING); -+ // so, make the main thread pick it up -+ MinecraftServer.chunkSystemCrash = new RuntimeException("Chunk system crash propagated from unrecoverableChunkSystemFailure", reportedException); -+ } -+ -+ public boolean executeMainThreadTask() { -+ TickThread.ensureTickThread("Cannot execute main thread task off-main"); -+ return this.mainThreadExecutor.executeTask(); -+ } -+ -+ public void raisePriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { -+ this.chunkHolderManager.raisePriority(x, z, priority); -+ } -+ -+ public void setPriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { -+ this.chunkHolderManager.setPriority(x, z, priority); -+ } -+ -+ public void lowerPriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { -+ this.chunkHolderManager.lowerPriority(x, z, priority); -+ } -+ -+ private final AtomicLong chunkLoadCounter = new AtomicLong(); -+ -+ public void scheduleTickingState(final int chunkX, final int chunkZ, final FullChunkStatus toStatus, -+ final boolean addTicket, final PrioritisedExecutor.Priority priority, -+ final Consumer onComplete) { -+ if (!TickThread.isTickThread()) { -+ this.scheduleChunkTask(chunkX, chunkZ, () -> { -+ ChunkTaskScheduler.this.scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -+ }, priority); -+ return; -+ } -+ final int accessRadius = getAccessRadius(toStatus); -+ if (this.chunkHolderManager.ticketLockArea.isHeldByCurrentThread(chunkX, chunkZ, accessRadius)) { -+ throw new IllegalStateException("Cannot schedule chunk load during ticket level update"); -+ } -+ if (this.schedulingLockArea.isHeldByCurrentThread(chunkX, chunkZ, accessRadius)) { -+ throw new IllegalStateException("Cannot schedule chunk loading recursively"); -+ } -+ -+ if (toStatus == FullChunkStatus.INACCESSIBLE) { -+ throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status"); -+ } -+ -+ final int minLevel = 33 - (toStatus.ordinal() - 1); -+ final Long chunkReference = addTicket ? Long.valueOf(this.chunkLoadCounter.getAndIncrement()) : null; -+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ -+ if (addTicket) { -+ this.chunkHolderManager.addTicketAtLevel(TicketType.CHUNK_LOAD, chunkKey, minLevel, chunkReference); -+ this.chunkHolderManager.processTicketUpdates(); -+ } -+ -+ final Consumer loadCallback = (final LevelChunk chunk) -> { -+ try { -+ if (onComplete != null) { -+ onComplete.accept(chunk); -+ } -+ } finally { -+ if (addTicket) { -+ ChunkTaskScheduler.this.chunkHolderManager.addAndRemoveTickets(chunkKey, -+ TicketType.UNKNOWN, minLevel, new ChunkPos(chunkKey), -+ TicketType.CHUNK_LOAD, minLevel, chunkReference -+ ); -+ } -+ } -+ }; -+ -+ final boolean scheduled; -+ final LevelChunk chunk; -+ final ReentrantAreaLock.Node ticketLock = this.chunkHolderManager.ticketLockArea.lock(chunkX, chunkZ, accessRadius); -+ try { -+ final ReentrantAreaLock.Node schedulingLock = this.schedulingLockArea.lock(chunkX, chunkZ, accessRadius); -+ try { -+ final NewChunkHolder chunkHolder = this.chunkHolderManager.getChunkHolder(chunkKey); -+ if (chunkHolder == null || chunkHolder.getTicketLevel() > minLevel) { -+ scheduled = false; -+ chunk = null; -+ } else { -+ final FullChunkStatus currStatus = chunkHolder.getChunkStatus(); -+ if (currStatus.isOrAfter(toStatus)) { -+ scheduled = false; -+ chunk = (LevelChunk)chunkHolder.getCurrentChunk(); -+ } else { -+ scheduled = true; -+ chunk = null; -+ -+ final int radius = toStatus.ordinal() - 1; // 0 -> BORDER, 1 -> TICKING, 2 -> ENTITY_TICKING -+ for (int dz = -radius; dz <= radius; ++dz) { -+ for (int dx = -radius; dx <= radius; ++dx) { -+ final NewChunkHolder neighbour = -+ (dx | dz) == 0 ? chunkHolder : this.chunkHolderManager.getChunkHolder(dx + chunkX, dz + chunkZ); -+ if (neighbour != null) { -+ neighbour.raisePriority(priority); -+ } -+ } -+ } -+ -+ // ticket level should schedule for us -+ chunkHolder.addFullStatusConsumer(toStatus, loadCallback); -+ } -+ } -+ } finally { -+ this.schedulingLockArea.unlock(schedulingLock); -+ } -+ } finally { -+ this.chunkHolderManager.ticketLockArea.unlock(ticketLock); -+ } -+ -+ if (!scheduled) { -+ // couldn't schedule -+ try { -+ loadCallback.accept(chunk); -+ } catch (final ThreadDeath thr) { -+ throw thr; -+ } catch (final Throwable thr) { -+ LOGGER.error("Failed to process chunk full status callback", thr); -+ } -+ } -+ } -+ -+ public void scheduleChunkLoad(final int chunkX, final int chunkZ, final boolean gen, final ChunkStatus toStatus, final boolean addTicket, -+ final PrioritisedExecutor.Priority priority, final Consumer onComplete) { -+ if (gen) { -+ this.scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -+ return; -+ } -+ this.scheduleChunkLoad(chunkX, chunkZ, ChunkStatus.EMPTY, addTicket, priority, (final ChunkAccess chunk) -> { -+ if (chunk == null) { -+ onComplete.accept(null); -+ } else { -+ if (chunk.getStatus().isOrAfter(toStatus)) { -+ this.scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -+ } else { -+ onComplete.accept(null); -+ } -+ } -+ }); -+ } -+ -+ // only appropriate to use with ServerLevel#syncLoadNonFull -+ public boolean beginChunkLoadForNonFullSync(final int chunkX, final int chunkZ, final ChunkStatus toStatus, -+ final PrioritisedExecutor.Priority priority) { -+ final int accessRadius = getAccessRadius(toStatus); -+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ final int minLevel = 33 + ChunkStatus.getDistance(toStatus); -+ final List tasks = new ArrayList<>(); -+ final ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock.Node ticketLock = this.chunkHolderManager.ticketLockArea.lock(chunkX, chunkZ, accessRadius); // Folia - use area based lock to reduce contention -+ try { -+ final ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock.Node schedulingLock = this.schedulingLockArea.lock(chunkX, chunkZ, accessRadius); // Folia - use area based lock to reduce contention -+ try { -+ final NewChunkHolder chunkHolder = this.chunkHolderManager.getChunkHolder(chunkKey); -+ if (chunkHolder == null || chunkHolder.getTicketLevel() > minLevel) { -+ return false; -+ } else { -+ final ChunkStatus genStatus = chunkHolder.getCurrentGenStatus(); -+ if (genStatus != null && genStatus.isOrAfter(toStatus)) { -+ return true; -+ } else { -+ chunkHolder.raisePriority(priority); -+ -+ if (!chunkHolder.upgradeGenTarget(toStatus)) { -+ this.schedule(chunkX, chunkZ, toStatus, chunkHolder, tasks); -+ } -+ } -+ } -+ } finally { -+ this.schedulingLockArea.unlock(schedulingLock); -+ } -+ } finally { -+ this.chunkHolderManager.ticketLockArea.unlock(ticketLock); -+ } -+ -+ for (int i = 0, len = tasks.size(); i < len; ++i) { -+ tasks.get(i).schedule(); -+ } -+ -+ return true; -+ } -+ -+ public void scheduleChunkLoad(final int chunkX, final int chunkZ, final ChunkStatus toStatus, final boolean addTicket, -+ final PrioritisedExecutor.Priority priority, final Consumer onComplete) { -+ if (!TickThread.isTickThread()) { -+ this.scheduleChunkTask(chunkX, chunkZ, () -> { -+ ChunkTaskScheduler.this.scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -+ }, priority); -+ return; -+ } -+ final int accessRadius = getAccessRadius(toStatus); -+ if (this.chunkHolderManager.ticketLockArea.isHeldByCurrentThread(chunkX, chunkZ, accessRadius)) { -+ throw new IllegalStateException("Cannot schedule chunk load during ticket level update"); -+ } -+ if (this.schedulingLockArea.isHeldByCurrentThread(chunkX, chunkZ, accessRadius)) { -+ throw new IllegalStateException("Cannot schedule chunk loading recursively"); -+ } -+ -+ if (toStatus == ChunkStatus.FULL) { -+ this.scheduleTickingState(chunkX, chunkZ, FullChunkStatus.FULL, addTicket, priority, (Consumer)onComplete); -+ return; -+ } -+ -+ final int minLevel = 33 + ChunkStatus.getDistance(toStatus); -+ final Long chunkReference = addTicket ? Long.valueOf(this.chunkLoadCounter.getAndIncrement()) : null; -+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ -+ if (addTicket) { -+ this.chunkHolderManager.addTicketAtLevel(TicketType.CHUNK_LOAD, chunkKey, minLevel, chunkReference); -+ this.chunkHolderManager.processTicketUpdates(); -+ } -+ -+ final Consumer loadCallback = (final ChunkAccess chunk) -> { -+ try { -+ if (onComplete != null) { -+ onComplete.accept(chunk); -+ } -+ } finally { -+ if (addTicket) { -+ ChunkTaskScheduler.this.chunkHolderManager.addAndRemoveTickets(chunkKey, -+ TicketType.UNKNOWN, minLevel, new ChunkPos(chunkKey), -+ TicketType.CHUNK_LOAD, minLevel, chunkReference -+ ); -+ } -+ } -+ }; -+ -+ final List tasks = new ArrayList<>(); -+ -+ final boolean scheduled; -+ final ChunkAccess chunk; -+ final ReentrantAreaLock.Node ticketLock = this.chunkHolderManager.ticketLockArea.lock(chunkX, chunkZ, accessRadius); -+ try { -+ final ReentrantAreaLock.Node schedulingLock = this.schedulingLockArea.lock(chunkX, chunkZ, accessRadius); -+ try { -+ final NewChunkHolder chunkHolder = this.chunkHolderManager.getChunkHolder(chunkKey); -+ if (chunkHolder == null || chunkHolder.getTicketLevel() > minLevel) { -+ scheduled = false; -+ chunk = null; -+ } else { -+ final ChunkStatus genStatus = chunkHolder.getCurrentGenStatus(); -+ if (genStatus != null && genStatus.isOrAfter(toStatus)) { -+ scheduled = false; -+ chunk = chunkHolder.getCurrentChunk(); -+ } else { -+ scheduled = true; -+ chunk = null; -+ chunkHolder.raisePriority(priority); -+ -+ if (!chunkHolder.upgradeGenTarget(toStatus)) { -+ this.schedule(chunkX, chunkZ, toStatus, chunkHolder, tasks); -+ } -+ chunkHolder.addStatusConsumer(toStatus, loadCallback); -+ } -+ } -+ } finally { -+ this.schedulingLockArea.unlock(schedulingLock); -+ } -+ } finally { -+ this.chunkHolderManager.ticketLockArea.unlock(ticketLock); -+ } -+ -+ for (int i = 0, len = tasks.size(); i < len; ++i) { -+ tasks.get(i).schedule(); -+ } -+ -+ if (!scheduled) { -+ // couldn't schedule -+ try { -+ loadCallback.accept(chunk); -+ } catch (final ThreadDeath thr) { -+ throw thr; -+ } catch (final Throwable thr) { -+ LOGGER.error("Failed to process chunk status callback", thr); -+ } -+ } -+ } -+ -+ private ChunkProgressionTask createTask(final int chunkX, final int chunkZ, final ChunkAccess chunk, -+ final NewChunkHolder chunkHolder, final List neighbours, -+ final ChunkStatus toStatus, final PrioritisedExecutor.Priority initialPriority) { -+ if (toStatus == ChunkStatus.EMPTY) { -+ return new ChunkLoadTask(this, this.world, chunkX, chunkZ, chunkHolder, initialPriority); -+ } -+ if (toStatus == ChunkStatus.LIGHT) { -+ return new ChunkLightTask(this, this.world, chunkX, chunkZ, chunk, initialPriority); -+ } -+ if (toStatus == ChunkStatus.FULL) { -+ return new ChunkFullTask(this, this.world, chunkX, chunkZ, chunkHolder, chunk, initialPriority); -+ } -+ -+ return new ChunkUpgradeGenericStatusTask(this, this.world, chunkX, chunkZ, chunk, neighbours, toStatus, initialPriority); -+ } -+ -+ ChunkProgressionTask schedule(final int chunkX, final int chunkZ, final ChunkStatus targetStatus, final NewChunkHolder chunkHolder, -+ final List allTasks) { -+ return this.schedule(chunkX, chunkZ, targetStatus, chunkHolder, allTasks, chunkHolder.getEffectivePriority()); -+ } -+ -+ // rets new task scheduled for the _specified_ chunk -+ // note: this must hold the scheduling lock -+ // minPriority is only used to pass the priority through to neighbours, as priority calculation has not yet been done -+ // schedule will ignore the generation target, so it should be checked by the caller to ensure the target is not regressed! -+ private ChunkProgressionTask schedule(final int chunkX, final int chunkZ, final ChunkStatus targetStatus, -+ final NewChunkHolder chunkHolder, final List allTasks, -+ final PrioritisedExecutor.Priority minPriority) { -+ if (!this.schedulingLockArea.isHeldByCurrentThread(chunkX, chunkZ, getAccessRadius(targetStatus))) { -+ throw new IllegalStateException("Not holding scheduling lock"); -+ } -+ -+ if (chunkHolder.hasGenerationTask()) { -+ chunkHolder.upgradeGenTarget(targetStatus); -+ return null; -+ } -+ -+ final PrioritisedExecutor.Priority requestedPriority = PrioritisedExecutor.Priority.max(minPriority, chunkHolder.getEffectivePriority()); -+ final ChunkStatus currentGenStatus = chunkHolder.getCurrentGenStatus(); -+ final ChunkAccess chunk = chunkHolder.getCurrentChunk(); -+ -+ if (currentGenStatus == null) { -+ // not yet loaded -+ final ChunkProgressionTask task = this.createTask( -+ chunkX, chunkZ, chunk, chunkHolder, Collections.emptyList(), ChunkStatus.EMPTY, requestedPriority -+ ); -+ -+ allTasks.add(task); -+ -+ final List chunkHolderNeighbours = new ArrayList<>(1); -+ chunkHolderNeighbours.add(chunkHolder); -+ -+ chunkHolder.setGenerationTarget(targetStatus); -+ chunkHolder.setGenerationTask(task, ChunkStatus.EMPTY, chunkHolderNeighbours); -+ -+ return task; -+ } -+ -+ if (currentGenStatus.isOrAfter(targetStatus)) { -+ // nothing to do -+ return null; -+ } -+ -+ // we know for sure now that we want to schedule _something_, so set the target -+ chunkHolder.setGenerationTarget(targetStatus); -+ -+ final ChunkStatus chunkRealStatus = chunk.getStatus(); -+ final ChunkStatus toStatus = currentGenStatus.getNextStatus(); -+ -+ // if this chunk has already generated up to or past the specified status, then we don't -+ // need the neighbours AT ALL. -+ final int neighbourReadRadius = chunkRealStatus.isOrAfter(toStatus) ? toStatus.loadRange : toStatus.getRange(); -+ -+ boolean unGeneratedNeighbours = false; -+ -+ // copied from MCUtil.getSpiralOutChunks -+ for (int r = 1; r <= neighbourReadRadius; r++) { -+ int x = -r; -+ int z = r; -+ -+ // Iterates the edge of half of the box; then negates for other half. -+ while (x <= r && z > -r) { -+ final int radius = Math.max(Math.abs(x), Math.abs(z)); -+ final ChunkStatus requiredNeighbourStatus = ChunkMap.getDependencyStatus(toStatus, radius); -+ -+ unGeneratedNeighbours |= this.checkNeighbour( -+ chunkX + x, chunkZ + z, requiredNeighbourStatus, chunkHolder, allTasks, requestedPriority -+ ); -+ unGeneratedNeighbours |= this.checkNeighbour( -+ chunkX - x, chunkZ - z, requiredNeighbourStatus, chunkHolder, allTasks, requestedPriority -+ ); -+ -+ if (x < r) { -+ x++; -+ } else { -+ z--; -+ } -+ } -+ } -+ -+ if (unGeneratedNeighbours) { -+ // can't schedule, but neighbour completion will schedule for us when they're ALL done -+ -+ // propagate our priority to neighbours -+ chunkHolder.recalculateNeighbourPriorities(); -+ return null; -+ } -+ -+ // need to gather neighbours -+ -+ final List neighbours; -+ final List chunkHolderNeighbours; -+ if (neighbourReadRadius <= 0) { -+ neighbours = new ArrayList<>(1); -+ chunkHolderNeighbours = new ArrayList<>(1); -+ neighbours.add(chunk); -+ chunkHolderNeighbours.add(chunkHolder); -+ } else { -+ // the iteration order is _very_ important, as all generation statuses expect a certain order such that: -+ // chunkAtRelative = neighbours.get(relX + relZ * (2 * radius + 1)) -+ neighbours = new ArrayList<>((2 * neighbourReadRadius + 1) * (2 * neighbourReadRadius + 1)); -+ chunkHolderNeighbours = new ArrayList<>((2 * neighbourReadRadius + 1) * (2 * neighbourReadRadius + 1)); -+ for (int dz = -neighbourReadRadius; dz <= neighbourReadRadius; ++dz) { -+ for (int dx = -neighbourReadRadius; dx <= neighbourReadRadius; ++dx) { -+ final NewChunkHolder holder = (dx | dz) == 0 ? chunkHolder : this.chunkHolderManager.getChunkHolder(dx + chunkX, dz + chunkZ); -+ neighbours.add(holder.getChunkForNeighbourAccess()); -+ chunkHolderNeighbours.add(holder); -+ } -+ } -+ } -+ -+ final ChunkProgressionTask task = this.createTask(chunkX, chunkZ, chunk, chunkHolder, neighbours, toStatus, chunkHolder.getEffectivePriority()); -+ allTasks.add(task); -+ -+ chunkHolder.setGenerationTask(task, toStatus, chunkHolderNeighbours); -+ -+ return task; -+ } -+ -+ // rets true if the neighbour is not at the required status, false otherwise -+ private boolean checkNeighbour(final int chunkX, final int chunkZ, final ChunkStatus requiredStatus, final NewChunkHolder center, -+ final List tasks, final PrioritisedExecutor.Priority minPriority) { -+ final NewChunkHolder chunkHolder = this.chunkHolderManager.getChunkHolder(chunkX, chunkZ); -+ -+ if (chunkHolder == null) { -+ throw new IllegalStateException("Missing chunkholder when required"); -+ } -+ -+ final ChunkStatus holderStatus = chunkHolder.getCurrentGenStatus(); -+ if (holderStatus != null && holderStatus.isOrAfter(requiredStatus)) { -+ return false; -+ } -+ -+ if (chunkHolder.hasFailedGeneration()) { -+ return true; -+ } -+ -+ center.addGenerationBlockingNeighbour(chunkHolder); -+ chunkHolder.addWaitingNeighbour(center, requiredStatus); -+ -+ if (chunkHolder.upgradeGenTarget(requiredStatus)) { -+ return true; -+ } -+ -+ // not at status required, so we need to schedule its generation -+ this.schedule( -+ chunkX, chunkZ, requiredStatus, chunkHolder, tasks, minPriority -+ ); -+ -+ return true; -+ } -+ -+ /** -+ * @deprecated Chunk tasks must be tied to coordinates in the future -+ */ -+ @Deprecated -+ public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final Runnable run) { -+ return this.scheduleChunkTask(run, PrioritisedExecutor.Priority.NORMAL); -+ } -+ -+ /** -+ * @deprecated Chunk tasks must be tied to coordinates in the future -+ */ -+ @Deprecated -+ public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ return this.mainThreadExecutor.queueRunnable(run, priority); -+ } -+ -+ public PrioritisedExecutor.PrioritisedTask createChunkTask(final int chunkX, final int chunkZ, final Runnable run) { -+ return this.createChunkTask(chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); -+ } -+ -+ public PrioritisedExecutor.PrioritisedTask createChunkTask(final int chunkX, final int chunkZ, final Runnable run, -+ final PrioritisedExecutor.Priority priority) { -+ return this.mainThreadExecutor.createTask(run, priority); -+ } -+ -+ public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final int chunkX, final int chunkZ, final Runnable run) { -+ return this.mainThreadExecutor.queueRunnable(run); -+ } -+ -+ public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final int chunkX, final int chunkZ, final Runnable run, -+ final PrioritisedExecutor.Priority priority) { -+ return this.mainThreadExecutor.queueRunnable(run, priority); -+ } -+ -+ public void executeTasksUntil(final BooleanSupplier exit) { -+ if (Bukkit.isPrimaryThread()) { -+ this.mainThreadExecutor.executeConditionally(exit); -+ } else { -+ long counter = 1L; -+ while (!exit.getAsBoolean()) { -+ counter = ConcurrentUtil.linearLongBackoff(counter, 100_000L, 5_000_000L); // 100us, 5ms -+ } -+ } -+ } -+ -+ public boolean halt(final boolean sync, final long maxWaitNS) { -+ this.radiusAwareGenExecutor.halt(); -+ this.parallelGenExecutor.halt(); -+ this.loadExecutor.halt(); -+ final long time = System.nanoTime(); -+ if (sync) { -+ for (long failures = 9L;; failures = ConcurrentUtil.linearLongBackoff(failures, 500_000L, 50_000_000L)) { -+ if ( -+ !this.radiusAwareGenExecutor.isActive() && -+ !this.parallelGenExecutor.isActive() && -+ !this.loadExecutor.isActive() -+ ) { -+ return true; -+ } -+ if ((System.nanoTime() - time) >= maxWaitNS) { -+ return false; -+ } -+ } -+ } -+ -+ return true; -+ } -+ -+ public static final ArrayDeque WAITING_CHUNKS = new ArrayDeque<>(); // stack -+ -+ public static final class ChunkInfo { -+ -+ public final int chunkX; -+ public final int chunkZ; -+ public final ServerLevel world; -+ -+ public ChunkInfo(final int chunkX, final int chunkZ, final ServerLevel world) { -+ this.chunkX = chunkX; -+ this.chunkZ = chunkZ; -+ this.world = world; -+ } -+ -+ @Override -+ public String toString() { -+ return "[( " + this.chunkX + "," + this.chunkZ + ") in '" + this.world.getWorld().getName() + "']"; -+ } -+ } -+ -+ public static void pushChunkWait(final ServerLevel world, final int chunkX, final int chunkZ) { -+ synchronized (WAITING_CHUNKS) { -+ WAITING_CHUNKS.push(new ChunkInfo(chunkX, chunkZ, world)); -+ } -+ } -+ -+ public static void popChunkWait() { -+ synchronized (WAITING_CHUNKS) { -+ WAITING_CHUNKS.pop(); -+ } -+ } -+ -+ public static ChunkInfo[] getChunkInfos() { -+ synchronized (WAITING_CHUNKS) { -+ return WAITING_CHUNKS.toArray(new ChunkInfo[0]); -+ } -+ } -+ -+ public static void dumpAllChunkLoadInfo(final boolean longPrint) { -+ final ChunkInfo[] chunkInfos = getChunkInfos(); -+ if (chunkInfos.length > 0) { -+ LOGGER.error("Chunk wait task info below: "); -+ for (final ChunkInfo chunkInfo : chunkInfos) { -+ final NewChunkHolder holder = chunkInfo.world.chunkTaskScheduler.chunkHolderManager.getChunkHolder(chunkInfo.chunkX, chunkInfo.chunkZ); -+ LOGGER.error("Chunk wait: " + chunkInfo); -+ LOGGER.error("Chunk holder: " + holder); -+ } -+ -+ if (longPrint) { -+ final File file = new File(new File(new File("."), "debug"), "chunks-watchdog.txt"); -+ LOGGER.error("Writing chunk information dump to " + file); -+ try { -+ MCUtil.dumpChunks(file, true); -+ LOGGER.error("Successfully written chunk information!"); -+ } catch (final Throwable thr) { -+ MinecraftServer.LOGGER.warn("Failed to dump chunk information to file " + file.toString(), thr); -+ } -+ } -+ } -+ } -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkUpgradeGenericStatusTask.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkUpgradeGenericStatusTask.java -new file mode 100644 -index 0000000000000000000000000000000000000000..bd0d0c4436f357392e13d9efd4412886385a6924 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkUpgradeGenericStatusTask.java -@@ -0,0 +1,214 @@ -+package io.papermc.paper.chunk.system.scheduling; -+ -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import com.mojang.logging.LogUtils; -+import net.minecraft.server.level.ChunkMap; -+import net.minecraft.server.level.ChunkResult; -+import net.minecraft.server.level.ServerChunkCache; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.status.ChunkStatus; -+import net.minecraft.world.level.chunk.ProtoChunk; -+import net.minecraft.world.level.chunk.status.WorldGenContext; -+import org.slf4j.Logger; -+import java.lang.invoke.VarHandle; -+import java.util.List; -+import java.util.Map; -+import java.util.concurrent.CompletableFuture; -+ -+public final class ChunkUpgradeGenericStatusTask extends ChunkProgressionTask implements Runnable { -+ -+ private static final Logger LOGGER = LogUtils.getClassLogger(); -+ -+ protected final ChunkAccess fromChunk; -+ protected final ChunkStatus fromStatus; -+ protected final ChunkStatus toStatus; -+ protected final List neighbours; -+ -+ protected final PrioritisedExecutor.PrioritisedTask generateTask; -+ -+ public ChunkUpgradeGenericStatusTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -+ final int chunkZ, final ChunkAccess chunk, final List neighbours, -+ final ChunkStatus toStatus, final PrioritisedExecutor.Priority priority) { -+ super(scheduler, world, chunkX, chunkZ); -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } -+ this.fromChunk = chunk; -+ this.fromStatus = chunk.getStatus(); -+ this.toStatus = toStatus; -+ this.neighbours = neighbours; -+ if (this.toStatus.isParallelCapable) { -+ this.generateTask = this.scheduler.parallelGenExecutor.createTask(this, priority); -+ } else { -+ this.generateTask = this.scheduler.radiusAwareScheduler.createTask(chunkX, chunkZ, this.toStatus.writeRadius, this, priority); -+ } -+ } -+ -+ @Override -+ public ChunkStatus getTargetStatus() { -+ return this.toStatus; -+ } -+ -+ private boolean isEmptyTask() { -+ // must use fromStatus here to avoid any race condition with run() overwriting the status -+ final boolean generation = !this.fromStatus.isOrAfter(this.toStatus); -+ return (generation && this.toStatus.isEmptyGenStatus()) || (!generation && this.toStatus.isEmptyLoadStatus()); -+ } -+ -+ @Override -+ public void run() { -+ final ChunkAccess chunk = this.fromChunk; -+ -+ final ServerChunkCache serverChunkCache = this.world.chunkSource; -+ final ChunkMap chunkMap = serverChunkCache.chunkMap; -+ -+ final CompletableFuture completeFuture; -+ -+ final boolean generation; -+ boolean completing = false; -+ -+ // note: should optimise the case where the chunk does not need to execute the status, because -+ // schedule() calls this synchronously if it will run through that path -+ -+ final WorldGenContext ctx = new WorldGenContext( -+ this.world, -+ chunkMap.generator, -+ chunkMap.getWorldGenContext().structureManager(), -+ serverChunkCache.getLightEngine() -+ ); -+ try { -+ generation = !chunk.getStatus().isOrAfter(this.toStatus); -+ if (generation) { -+ if (this.toStatus.isEmptyGenStatus()) { -+ if (chunk instanceof ProtoChunk) { -+ ((ProtoChunk)chunk).setStatus(this.toStatus); -+ } -+ completing = true; -+ this.complete(chunk, null); -+ return; -+ } -+ completeFuture = this.toStatus.generate(ctx, Runnable::run, null, this.neighbours) -+ .whenComplete((final ChunkAccess either, final Throwable throwable) -> { -+ if (either instanceof ProtoChunk proto) { -+ proto.setStatus(ChunkUpgradeGenericStatusTask.this.toStatus); -+ } -+ } -+ ); -+ } else { -+ if (this.toStatus.isEmptyLoadStatus()) { -+ completing = true; -+ this.complete(chunk, null); -+ return; -+ } -+ completeFuture = this.toStatus.load(ctx, null, chunk); -+ } -+ } catch (final Throwable throwable) { -+ if (!completing) { -+ this.complete(null, throwable); -+ -+ if (throwable instanceof ThreadDeath) { -+ throw (ThreadDeath)throwable; -+ } -+ return; -+ } -+ -+ this.scheduler.unrecoverableChunkSystemFailure(this.chunkX, this.chunkZ, Map.of( -+ "Target status", ChunkTaskScheduler.stringIfNull(this.toStatus), -+ "From status", ChunkTaskScheduler.stringIfNull(this.fromStatus), -+ "Generation task", this -+ ), throwable); -+ -+ if (!(throwable instanceof ThreadDeath)) { -+ LOGGER.error("Failed to complete status for chunk: status:" + this.toStatus + ", chunk: (" + this.chunkX + "," + this.chunkZ + "), world: " + this.world.getWorld().getName(), throwable); -+ } else { -+ // ensure the chunk system can respond, then die -+ throw (ThreadDeath)throwable; -+ } -+ return; -+ } -+ -+ if (!completeFuture.isDone() && !this.toStatus.warnedAboutNoImmediateComplete.getAndSet(true)) { -+ LOGGER.warn("Future status not complete after scheduling: " + this.toStatus.toString() + ", generate: " + generation); -+ } -+ -+ final ChunkAccess newChunk; -+ -+ try { -+ newChunk = completeFuture.join(); -+ } catch (final Throwable throwable) { -+ this.complete(null, throwable); -+ // ensure the chunk system can respond, then die -+ if (throwable instanceof ThreadDeath) { -+ throw (ThreadDeath)throwable; -+ } -+ return; -+ } -+ -+ if (newChunk == null) { -+ this.complete(null, new IllegalStateException("Chunk for status: " + ChunkUpgradeGenericStatusTask.this.toStatus.toString() + ", generation: " + generation + " should not be null! Future: " + completeFuture).fillInStackTrace()); -+ return; -+ } -+ -+ this.complete(newChunk, null); -+ } -+ -+ protected volatile boolean scheduled; -+ protected static final VarHandle SCHEDULED_HANDLE = ConcurrentUtil.getVarHandle(ChunkUpgradeGenericStatusTask.class, "scheduled", boolean.class); -+ -+ @Override -+ public boolean isScheduled() { -+ return this.scheduled; -+ } -+ -+ @Override -+ public void schedule() { -+ if ((boolean)SCHEDULED_HANDLE.getAndSet((ChunkUpgradeGenericStatusTask)this, true)) { -+ throw new IllegalStateException("Cannot double call schedule()"); -+ } -+ if (this.isEmptyTask()) { -+ if (this.generateTask.cancel()) { -+ this.run(); -+ } -+ } else { -+ this.generateTask.queue(); -+ } -+ } -+ -+ @Override -+ public void cancel() { -+ if (this.generateTask.cancel()) { -+ this.complete(null, null); -+ } -+ } -+ -+ @Override -+ public PrioritisedExecutor.Priority getPriority() { -+ return this.generateTask.getPriority(); -+ } -+ -+ @Override -+ public void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } -+ this.generateTask.lowerPriority(priority); -+ } -+ -+ @Override -+ public void setPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } -+ this.generateTask.setPriority(priority); -+ } -+ -+ @Override -+ public void raisePriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } -+ this.generateTask.raisePriority(priority); -+ } -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/GenericDataLoadTask.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/GenericDataLoadTask.java -new file mode 100644 -index 0000000000000000000000000000000000000000..396d72c00e47cf1669ae20dc839c1c961b1f262a ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/GenericDataLoadTask.java -@@ -0,0 +1,746 @@ -+package io.papermc.paper.chunk.system.scheduling; -+ -+import ca.spottedleaf.concurrentutil.completable.Completable; -+import ca.spottedleaf.concurrentutil.executor.Cancellable; -+import ca.spottedleaf.concurrentutil.executor.standard.DelayedPrioritisedTask; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import com.mojang.logging.LogUtils; -+import io.papermc.paper.chunk.system.io.RegionFileIOThread; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.server.level.ServerLevel; -+import org.slf4j.Logger; -+import java.lang.invoke.VarHandle; -+import java.util.Map; -+import java.util.concurrent.atomic.AtomicBoolean; -+import java.util.concurrent.atomic.AtomicLong; -+import java.util.function.BiConsumer; -+ -+public abstract class GenericDataLoadTask { -+ -+ private static final Logger LOGGER = LogUtils.getClassLogger(); -+ -+ protected static final CompoundTag CANCELLED_DATA = new CompoundTag(); -+ -+ // reference count is the upper 32 bits -+ protected final AtomicLong stageAndReferenceCount = new AtomicLong(STAGE_NOT_STARTED); -+ -+ protected static final long STAGE_MASK = 0xFFFFFFFFL; -+ protected static final long STAGE_CANCELLED = 0xFFFFFFFFL; -+ protected static final long STAGE_NOT_STARTED = 0L; -+ protected static final long STAGE_LOADING = 1L; -+ protected static final long STAGE_PROCESSING = 2L; -+ protected static final long STAGE_COMPLETED = 3L; -+ -+ // for loading data off disk -+ protected final LoadDataFromDiskTask loadDataFromDiskTask; -+ // processing off-main -+ protected final PrioritisedExecutor.PrioritisedTask processOffMain; -+ // processing on-main -+ protected final PrioritisedExecutor.PrioritisedTask processOnMain; -+ -+ protected final ChunkTaskScheduler scheduler; -+ protected final ServerLevel world; -+ protected final int chunkX; -+ protected final int chunkZ; -+ protected final RegionFileIOThread.RegionFileType type; -+ -+ public GenericDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -+ final int chunkZ, final RegionFileIOThread.RegionFileType type, -+ final PrioritisedExecutor.Priority priority) { -+ this.scheduler = scheduler; -+ this.world = world; -+ this.chunkX = chunkX; -+ this.chunkZ = chunkZ; -+ this.type = type; -+ -+ final ProcessOnMainTask mainTask; -+ if (this.hasOnMain()) { -+ mainTask = new ProcessOnMainTask(); -+ this.processOnMain = this.createOnMain(mainTask, priority); -+ } else { -+ mainTask = null; -+ this.processOnMain = null; -+ } -+ -+ final ProcessOffMainTask offMainTask; -+ if (this.hasOffMain()) { -+ offMainTask = new ProcessOffMainTask(mainTask); -+ this.processOffMain = this.createOffMain(offMainTask, priority); -+ } else { -+ offMainTask = null; -+ this.processOffMain = null; -+ } -+ -+ if (this.processOffMain == null && this.processOnMain == null) { -+ throw new IllegalStateException("Illegal class implementation: " + this.getClass().getName() + ", should be able to schedule at least one task!"); -+ } -+ -+ this.loadDataFromDiskTask = new LoadDataFromDiskTask(world, chunkX, chunkZ, type, new DataLoadCallback(offMainTask, mainTask), priority); -+ } -+ -+ public static final record TaskResult(L left, R right) {} -+ -+ protected abstract boolean hasOffMain(); -+ -+ protected abstract boolean hasOnMain(); -+ -+ protected abstract PrioritisedExecutor.PrioritisedTask createOffMain(final Runnable run, final PrioritisedExecutor.Priority priority); -+ -+ protected abstract PrioritisedExecutor.PrioritisedTask createOnMain(final Runnable run, final PrioritisedExecutor.Priority priority); -+ -+ protected abstract TaskResult runOffMain(final CompoundTag data, final Throwable throwable); -+ -+ protected abstract TaskResult runOnMain(final OnMain data, final Throwable throwable); -+ -+ protected abstract void onComplete(final TaskResult result); -+ -+ protected abstract TaskResult completeOnMainOffMain(final OnMain data, final Throwable throwable); -+ -+ @Override -+ public String toString() { -+ return "GenericDataLoadTask{class: " + this.getClass().getName() + ", world: " + this.world.getWorld().getName() + -+ ", chunk: (" + this.chunkX + "," + this.chunkZ + "), hashcode: " + System.identityHashCode(this) + ", priority: " + this.getPriority() + -+ ", type: " + this.type.toString() + "}"; -+ } -+ -+ public PrioritisedExecutor.Priority getPriority() { -+ if (this.processOnMain != null) { -+ return this.processOnMain.getPriority(); -+ } else { -+ return this.processOffMain.getPriority(); -+ } -+ } -+ -+ public void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ // can't lower I/O tasks, we don't know what they affect -+ if (this.processOffMain != null) { -+ this.processOffMain.lowerPriority(priority); -+ } -+ if (this.processOnMain != null) { -+ this.processOnMain.lowerPriority(priority); -+ } -+ } -+ -+ public void setPriority(final PrioritisedExecutor.Priority priority) { -+ // can't lower I/O tasks, we don't know what they affect -+ this.loadDataFromDiskTask.raisePriority(priority); -+ if (this.processOffMain != null) { -+ this.processOffMain.setPriority(priority); -+ } -+ if (this.processOnMain != null) { -+ this.processOnMain.setPriority(priority); -+ } -+ } -+ -+ public void raisePriority(final PrioritisedExecutor.Priority priority) { -+ // can't lower I/O tasks, we don't know what they affect -+ this.loadDataFromDiskTask.raisePriority(priority); -+ if (this.processOffMain != null) { -+ this.processOffMain.raisePriority(priority); -+ } -+ if (this.processOnMain != null) { -+ this.processOnMain.raisePriority(priority); -+ } -+ } -+ -+ // returns whether scheduleNow() needs to be called -+ public boolean schedule(final boolean delay) { -+ if (this.stageAndReferenceCount.get() != STAGE_NOT_STARTED || -+ !this.stageAndReferenceCount.compareAndSet(STAGE_NOT_STARTED, (1L << 32) | STAGE_LOADING)) { -+ // try and increment reference count -+ int failures = 0; -+ for (long curr = this.stageAndReferenceCount.get();;) { -+ if ((curr & STAGE_MASK) == STAGE_CANCELLED || (curr & STAGE_MASK) == STAGE_COMPLETED) { -+ // cancelled or completed, nothing to do here -+ return false; -+ } -+ -+ if (curr == (curr = this.stageAndReferenceCount.compareAndExchange(curr, curr + (1L << 32)))) { -+ // successful -+ return false; -+ } -+ -+ ++failures; -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ } -+ } -+ -+ if (!delay) { -+ this.scheduleNow(); -+ return false; -+ } -+ return true; -+ } -+ -+ public void scheduleNow() { -+ this.loadDataFromDiskTask.schedule(); // will schedule the rest -+ } -+ -+ // assumes the current stage cannot be completed -+ // returns false if cancelled, returns true if can proceed -+ private boolean advanceStage(final long expect, final long to) { -+ int failures = 0; -+ for (long curr = this.stageAndReferenceCount.get();;) { -+ if ((curr & STAGE_MASK) != expect) { -+ // must be cancelled -+ return false; -+ } -+ -+ final long newVal = (curr & ~STAGE_MASK) | to; -+ if (curr == (curr = this.stageAndReferenceCount.compareAndExchange(curr, newVal))) { -+ return true; -+ } -+ -+ ++failures; -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ } -+ } -+ -+ public boolean cancel() { -+ int failures = 0; -+ for (long curr = this.stageAndReferenceCount.get();;) { -+ if ((curr & STAGE_MASK) == STAGE_COMPLETED || (curr & STAGE_MASK) == STAGE_CANCELLED) { -+ return false; -+ } -+ -+ if ((curr & STAGE_MASK) == STAGE_NOT_STARTED || (curr & ~STAGE_MASK) == (1L << 32)) { -+ // no other references, so we can cancel -+ final long newVal = STAGE_CANCELLED; -+ if (curr == (curr = this.stageAndReferenceCount.compareAndExchange(curr, newVal))) { -+ this.loadDataFromDiskTask.cancel(); -+ if (this.processOffMain != null) { -+ this.processOffMain.cancel(); -+ } -+ if (this.processOnMain != null) { -+ this.processOnMain.cancel(); -+ } -+ this.onComplete(null); -+ return true; -+ } -+ } else { -+ if ((curr & ~STAGE_MASK) == (0L << 32)) { -+ throw new IllegalStateException("Reference count cannot be zero here"); -+ } -+ // just decrease the reference count -+ final long newVal = curr - (1L << 32); -+ if (curr == (curr = this.stageAndReferenceCount.compareAndExchange(curr, newVal))) { -+ return false; -+ } -+ } -+ -+ ++failures; -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ } -+ } -+ -+ protected final class DataLoadCallback implements BiConsumer { -+ -+ protected final ProcessOffMainTask offMainTask; -+ protected final ProcessOnMainTask onMainTask; -+ -+ public DataLoadCallback(final ProcessOffMainTask offMainTask, final ProcessOnMainTask onMainTask) { -+ this.offMainTask = offMainTask; -+ this.onMainTask = onMainTask; -+ } -+ -+ @Override -+ public void accept(final CompoundTag compoundTag, final Throwable throwable) { -+ if (GenericDataLoadTask.this.stageAndReferenceCount.get() == STAGE_CANCELLED) { -+ // don't try to schedule further -+ return; -+ } -+ -+ try { -+ if (compoundTag == CANCELLED_DATA) { -+ // cancelled, except this isn't possible -+ LOGGER.error("Data callback says cancelled, but stage does not?"); -+ return; -+ } -+ -+ // get off of the regionfile callback ASAP, no clue what locks are held right now... -+ if (GenericDataLoadTask.this.processOffMain != null) { -+ this.offMainTask.data = compoundTag; -+ this.offMainTask.throwable = throwable; -+ GenericDataLoadTask.this.processOffMain.queue(); -+ return; -+ } else { -+ // no off-main task, so go straight to main -+ this.onMainTask.data = (OnMain)compoundTag; -+ this.onMainTask.throwable = throwable; -+ GenericDataLoadTask.this.processOnMain.queue(); -+ } -+ } catch (final ThreadDeath death) { -+ throw death; -+ } catch (final Throwable thr2) { -+ LOGGER.error("Failed I/O callback for task: " + GenericDataLoadTask.this.toString(), thr2); -+ GenericDataLoadTask.this.scheduler.unrecoverableChunkSystemFailure( -+ GenericDataLoadTask.this.chunkX, GenericDataLoadTask.this.chunkZ, Map.of( -+ "Callback throwable", ChunkTaskScheduler.stringIfNull(throwable) -+ ), thr2); -+ } -+ } -+ } -+ -+ protected final class ProcessOffMainTask implements Runnable { -+ -+ protected CompoundTag data; -+ protected Throwable throwable; -+ protected final ProcessOnMainTask schedule; -+ -+ public ProcessOffMainTask(final ProcessOnMainTask schedule) { -+ this.schedule = schedule; -+ } -+ -+ @Override -+ public void run() { -+ if (!GenericDataLoadTask.this.advanceStage(STAGE_LOADING, this.schedule == null ? STAGE_COMPLETED : STAGE_PROCESSING)) { -+ // cancelled -+ return; -+ } -+ final TaskResult newData = GenericDataLoadTask.this.runOffMain(this.data, this.throwable); -+ -+ if (GenericDataLoadTask.this.stageAndReferenceCount.get() == STAGE_CANCELLED) { -+ // don't try to schedule further -+ return; -+ } -+ -+ if (this.schedule != null) { -+ final TaskResult syncComplete = GenericDataLoadTask.this.completeOnMainOffMain(newData.left, newData.right); -+ -+ if (syncComplete != null) { -+ if (GenericDataLoadTask.this.advanceStage(STAGE_PROCESSING, STAGE_COMPLETED)) { -+ GenericDataLoadTask.this.onComplete(syncComplete); -+ } // else: cancelled -+ return; -+ } -+ -+ this.schedule.data = newData.left; -+ this.schedule.throwable = newData.right; -+ -+ GenericDataLoadTask.this.processOnMain.queue(); -+ } else { -+ GenericDataLoadTask.this.onComplete((TaskResult)newData); -+ } -+ } -+ } -+ -+ protected final class ProcessOnMainTask implements Runnable { -+ -+ protected OnMain data; -+ protected Throwable throwable; -+ -+ @Override -+ public void run() { -+ if (!GenericDataLoadTask.this.advanceStage(STAGE_PROCESSING, STAGE_COMPLETED)) { -+ // cancelled -+ return; -+ } -+ final TaskResult result = GenericDataLoadTask.this.runOnMain(this.data, this.throwable); -+ -+ GenericDataLoadTask.this.onComplete(result); -+ } -+ } -+ -+ public static final class LoadDataFromDiskTask { -+ -+ protected volatile int priority; -+ protected static final VarHandle PRIORITY_HANDLE = ConcurrentUtil.getVarHandle(LoadDataFromDiskTask.class, "priority", int.class); -+ -+ protected static final int PRIORITY_EXECUTED = Integer.MIN_VALUE >>> 0; -+ protected static final int PRIORITY_LOAD_SCHEDULED = Integer.MIN_VALUE >>> 1; -+ protected static final int PRIORITY_UNLOAD_SCHEDULED = Integer.MIN_VALUE >>> 2; -+ -+ protected static final int PRIORITY_FLAGS = ~Character.MAX_VALUE; -+ -+ protected final int getPriorityVolatile() { -+ return (int)PRIORITY_HANDLE.getVolatile((LoadDataFromDiskTask)this); -+ } -+ -+ protected final int compareAndExchangePriorityVolatile(final int expect, final int update) { -+ return (int)PRIORITY_HANDLE.compareAndExchange((LoadDataFromDiskTask)this, (int)expect, (int)update); -+ } -+ -+ protected final int getAndOrPriorityVolatile(final int val) { -+ return (int)PRIORITY_HANDLE.getAndBitwiseOr((LoadDataFromDiskTask)this, (int)val); -+ } -+ -+ protected final void setPriorityPlain(final int val) { -+ PRIORITY_HANDLE.set((LoadDataFromDiskTask)this, (int)val); -+ } -+ -+ private final ServerLevel world; -+ private final int chunkX; -+ private final int chunkZ; -+ -+ private final RegionFileIOThread.RegionFileType type; -+ private Cancellable dataLoadTask; -+ private Cancellable dataUnloadCancellable; -+ private DelayedPrioritisedTask dataUnloadTask; -+ -+ private final BiConsumer onComplete; -+ -+ // onComplete should be caller sensitive, it may complete synchronously with schedule() - which does -+ // hold a priority lock. -+ public LoadDataFromDiskTask(final ServerLevel world, final int chunkX, final int chunkZ, -+ final RegionFileIOThread.RegionFileType type, -+ final BiConsumer onComplete, -+ final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } -+ this.world = world; -+ this.chunkX = chunkX; -+ this.chunkZ = chunkZ; -+ this.type = type; -+ this.onComplete = onComplete; -+ this.setPriorityPlain(priority.priority); -+ } -+ -+ private void complete(final CompoundTag data, final Throwable throwable) { -+ try { -+ this.onComplete.accept(data, throwable); -+ } catch (final Throwable thr2) { -+ this.world.chunkTaskScheduler.unrecoverableChunkSystemFailure(this.chunkX, this.chunkZ, Map.of( -+ "Completed throwable", ChunkTaskScheduler.stringIfNull(throwable), -+ "Regionfile type", ChunkTaskScheduler.stringIfNull(this.type) -+ ), thr2); -+ if (thr2 instanceof ThreadDeath) { -+ throw (ThreadDeath)thr2; -+ } -+ } -+ } -+ -+ protected boolean markExecuting() { -+ return (this.getAndOrPriorityVolatile(PRIORITY_EXECUTED) & PRIORITY_EXECUTED) == 0; -+ } -+ -+ protected boolean isMarkedExecuted() { -+ return (this.getPriorityVolatile() & PRIORITY_EXECUTED) != 0; -+ } -+ -+ 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_EXECUTED) != 0) { -+ // cancelled or executed -+ return; -+ } -+ -+ if ((curr & PRIORITY_LOAD_SCHEDULED) != 0) { -+ RegionFileIOThread.lowerPriority(this.world, this.chunkX, this.chunkZ, this.type, priority); -+ return; -+ } -+ -+ if ((curr & PRIORITY_UNLOAD_SCHEDULED) != 0) { -+ if (this.dataUnloadTask != null) { -+ this.dataUnloadTask.lowerPriority(priority); -+ } -+ // no return - we need to propagate priority -+ } -+ -+ if (!priority.isHigherPriority(curr & ~PRIORITY_FLAGS)) { -+ return; -+ } -+ -+ if (curr == (curr = this.compareAndExchangePriorityVolatile(curr, priority.priority | (curr & PRIORITY_FLAGS)))) { -+ 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_EXECUTED) != 0) { -+ // cancelled or executed -+ return; -+ } -+ -+ if ((curr & PRIORITY_LOAD_SCHEDULED) != 0) { -+ RegionFileIOThread.setPriority(this.world, this.chunkX, this.chunkZ, this.type, priority); -+ return; -+ } -+ -+ if ((curr & PRIORITY_UNLOAD_SCHEDULED) != 0) { -+ if (this.dataUnloadTask != null) { -+ this.dataUnloadTask.setPriority(priority); -+ } -+ // no return - we need to propagate priority -+ } -+ -+ if (curr == (curr = this.compareAndExchangePriorityVolatile(curr, priority.priority | (curr & PRIORITY_FLAGS)))) { -+ return; -+ } -+ -+ // failed, retry -+ -+ ++failures; -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ } -+ } -+ -+ 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_EXECUTED) != 0) { -+ // cancelled or executed -+ return; -+ } -+ -+ if ((curr & PRIORITY_LOAD_SCHEDULED) != 0) { -+ RegionFileIOThread.raisePriority(this.world, this.chunkX, this.chunkZ, this.type, priority); -+ return; -+ } -+ -+ if ((curr & PRIORITY_UNLOAD_SCHEDULED) != 0) { -+ if (this.dataUnloadTask != null) { -+ this.dataUnloadTask.raisePriority(priority); -+ } -+ // no return - we need to propagate priority -+ } -+ -+ if (!priority.isLowerPriority(curr & ~PRIORITY_FLAGS)) { -+ return; -+ } -+ -+ if (curr == (curr = this.compareAndExchangePriorityVolatile(curr, priority.priority | (curr & PRIORITY_FLAGS)))) { -+ return; -+ } -+ -+ // failed, retry -+ -+ ++failures; -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ } -+ } -+ -+ public void cancel() { -+ if ((this.getAndOrPriorityVolatile(PRIORITY_EXECUTED) & PRIORITY_EXECUTED) != 0) { -+ // cancelled or executed already -+ return; -+ } -+ -+ // OK if we miss the field read, the task cannot complete if the cancelled bit is set and -+ // the write to dataLoadTask will check for the cancelled bit -+ if (this.dataUnloadCancellable != null) { -+ this.dataUnloadCancellable.cancel(); -+ } -+ -+ if (this.dataLoadTask != null) { -+ this.dataLoadTask.cancel(); -+ } -+ -+ this.complete(CANCELLED_DATA, null); -+ } -+ -+ private final AtomicBoolean scheduled = new AtomicBoolean(); -+ -+ public void schedule() { -+ if (this.scheduled.getAndSet(true)) { -+ throw new IllegalStateException("schedule() called twice"); -+ } -+ int priority = this.getPriorityVolatile(); -+ -+ if ((priority & PRIORITY_EXECUTED) != 0) { -+ // cancelled -+ return; -+ } -+ -+ final BiConsumer consumer = (final CompoundTag data, final Throwable thr) -> { -+ // because cancelScheduled() cannot actually stop this task from executing in every case, we need -+ // to mark complete here to ensure we do not double complete -+ if (LoadDataFromDiskTask.this.markExecuting()) { -+ LoadDataFromDiskTask.this.complete(data, thr); -+ } // else: cancelled -+ }; -+ -+ final PrioritisedExecutor.Priority initialPriority = PrioritisedExecutor.Priority.getPriority(priority); -+ boolean scheduledUnload = false; -+ -+ final NewChunkHolder holder = this.world.chunkTaskScheduler.chunkHolderManager.getChunkHolder(this.chunkX, this.chunkZ); -+ if (holder != null) { -+ final BiConsumer unloadConsumer = (final CompoundTag data, final Throwable thr) -> { -+ if (data != null) { -+ consumer.accept(data, null); -+ } else { -+ // need to schedule task -+ LoadDataFromDiskTask.this.schedule(false, consumer, PrioritisedExecutor.Priority.getPriority(LoadDataFromDiskTask.this.getPriorityVolatile() & ~PRIORITY_FLAGS)); -+ } -+ }; -+ Cancellable unloadCancellable = null; -+ CompoundTag syncComplete = null; -+ final NewChunkHolder.UnloadTask unloadTask = holder.getUnloadTask(this.type); // can be null if no task exists -+ final Completable unloadCompletable = unloadTask == null ? null : unloadTask.completable(); -+ if (unloadCompletable != null) { -+ unloadCancellable = unloadCompletable.addAsynchronousWaiter(unloadConsumer); -+ if (unloadCancellable == null) { -+ syncComplete = unloadCompletable.getResult(); -+ } -+ } -+ -+ if (syncComplete != null) { -+ consumer.accept(syncComplete, null); -+ return; -+ } -+ -+ if (unloadCancellable != null) { -+ scheduledUnload = true; -+ this.dataUnloadCancellable = unloadCancellable; -+ this.dataUnloadTask = unloadTask.task(); -+ } -+ } -+ -+ this.schedule(scheduledUnload, consumer, initialPriority); -+ } -+ -+ private void schedule(final boolean scheduledUnload, final BiConsumer consumer, final PrioritisedExecutor.Priority initialPriority) { -+ int priority = this.getPriorityVolatile(); -+ -+ if ((priority & PRIORITY_EXECUTED) != 0) { -+ // cancelled -+ return; -+ } -+ -+ if (!scheduledUnload) { -+ this.dataLoadTask = RegionFileIOThread.loadDataAsync( -+ this.world, this.chunkX, this.chunkZ, this.type, consumer, -+ initialPriority.isHigherPriority(PrioritisedExecutor.Priority.NORMAL), initialPriority -+ ); -+ } -+ -+ int failures = 0; -+ for (;;) { -+ if (priority == (priority = this.compareAndExchangePriorityVolatile(priority, priority | (scheduledUnload ? PRIORITY_UNLOAD_SCHEDULED : PRIORITY_LOAD_SCHEDULED)))) { -+ return; -+ } -+ -+ if ((priority & PRIORITY_EXECUTED) != 0) { -+ // cancelled or executed -+ if (this.dataUnloadCancellable != null) { -+ this.dataUnloadCancellable.cancel(); -+ } -+ -+ if (this.dataLoadTask != null) { -+ this.dataLoadTask.cancel(); -+ } -+ return; -+ } -+ -+ if (scheduledUnload) { -+ if (this.dataUnloadTask != null) { -+ this.dataUnloadTask.setPriority(PrioritisedExecutor.Priority.getPriority(priority & ~PRIORITY_FLAGS)); -+ } -+ } else { -+ RegionFileIOThread.setPriority(this.world, this.chunkX, this.chunkZ, this.type, PrioritisedExecutor.Priority.getPriority(priority & ~PRIORITY_FLAGS)); -+ } -+ -+ ++failures; -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ } -+ } -+ -+ /* -+ private static final class LoadDataPriorityHolder extends PriorityHolder { -+ -+ protected final LoadDataFromDiskTask task; -+ -+ protected LoadDataPriorityHolder(final PrioritisedExecutor.Priority priority, final LoadDataFromDiskTask task) { -+ super(priority); -+ this.task = task; -+ } -+ -+ @Override -+ protected void cancelScheduled() { -+ final Cancellable dataLoadTask = this.task.dataLoadTask; -+ if (dataLoadTask != null) { -+ // OK if we miss the field read, the task cannot complete if the cancelled bit is set and -+ // the write to dataLoadTask will check for the cancelled bit -+ this.task.dataLoadTask.cancel(); -+ } -+ this.task.complete(CANCELLED_DATA, null); -+ } -+ -+ @Override -+ protected PrioritisedExecutor.Priority getScheduledPriority() { -+ final LoadDataFromDiskTask task = this.task; -+ return RegionFileIOThread.getPriority(task.world, task.chunkX, task.chunkZ, task.type); -+ } -+ -+ @Override -+ protected void scheduleTask(final PrioritisedExecutor.Priority priority) { -+ final LoadDataFromDiskTask task = this.task; -+ final BiConsumer consumer = (final CompoundTag data, final Throwable thr) -> { -+ // because cancelScheduled() cannot actually stop this task from executing in every case, we need -+ // to mark complete here to ensure we do not double complete -+ if (LoadDataPriorityHolder.this.markExecuting()) { -+ LoadDataPriorityHolder.this.task.complete(data, thr); -+ } // else: cancelled -+ }; -+ task.dataLoadTask = RegionFileIOThread.loadDataAsync( -+ task.world, task.chunkX, task.chunkZ, task.type, consumer, -+ priority.isHigherPriority(PrioritisedExecutor.Priority.NORMAL), priority -+ ); -+ if (this.isMarkedExecuted()) { -+ // if we are marked as completed, it could be: -+ // 1. we were cancelled -+ // 2. the consumer was completed -+ // in the 2nd case, cancel() does nothing -+ // in the 1st case, we ensure cancel() is called as it is possible for the cancelling thread -+ // to miss the field write here -+ task.dataLoadTask.cancel(); -+ } -+ } -+ -+ @Override -+ protected void lowerPriorityScheduled(final PrioritisedExecutor.Priority priority) { -+ final LoadDataFromDiskTask task = this.task; -+ RegionFileIOThread.lowerPriority(task.world, task.chunkX, task.chunkZ, task.type, priority); -+ } -+ -+ @Override -+ protected void setPriorityScheduled(final PrioritisedExecutor.Priority priority) { -+ final LoadDataFromDiskTask task = this.task; -+ RegionFileIOThread.setPriority(task.world, task.chunkX, task.chunkZ, task.type, priority); -+ } -+ -+ @Override -+ protected void raisePriorityScheduled(final PrioritisedExecutor.Priority priority) { -+ final LoadDataFromDiskTask task = this.task; -+ RegionFileIOThread.raisePriority(task.world, task.chunkX, task.chunkZ, task.type, priority); -+ } -+ } -+ */ -+ } -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java -new file mode 100644 -index 0000000000000000000000000000000000000000..56b07a3306e5735816c8d89601b519cb0db6379a ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java -@@ -0,0 +1,2106 @@ -+package io.papermc.paper.chunk.system.scheduling; -+ -+import ca.spottedleaf.concurrentutil.completable.Completable; -+import ca.spottedleaf.concurrentutil.executor.Cancellable; -+import ca.spottedleaf.concurrentutil.executor.standard.DelayedPrioritisedTask; -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import com.google.gson.JsonArray; -+import com.google.gson.JsonElement; -+import com.google.gson.JsonObject; -+import com.google.gson.JsonPrimitive; -+import com.mojang.logging.LogUtils; -+import io.papermc.paper.chunk.system.io.RegionFileIOThread; -+import io.papermc.paper.chunk.system.poi.PoiChunk; -+import io.papermc.paper.util.CoordinateUtils; -+import io.papermc.paper.util.TickThread; -+import io.papermc.paper.util.WorldUtil; -+import io.papermc.paper.world.ChunkEntitySlices; -+import it.unimi.dsi.fastutil.objects.Reference2ObjectLinkedOpenHashMap; -+import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; -+import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; -+import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.server.level.ChunkLevel; -+import net.minecraft.server.level.FullChunkStatus; -+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.status.ChunkStatus; -+import net.minecraft.world.level.chunk.ImposterProtoChunk; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.storage.ChunkSerializer; -+import net.minecraft.world.level.chunk.storage.EntityStorage; -+import org.slf4j.Logger; -+import java.lang.invoke.VarHandle; -+import java.util.ArrayList; -+import java.util.Iterator; -+import java.util.List; -+import java.util.Map; -+import java.util.Objects; -+import java.util.concurrent.atomic.AtomicBoolean; -+import java.util.function.Consumer; -+ -+public final class NewChunkHolder { -+ -+ private static final Logger LOGGER = LogUtils.getClassLogger(); -+ -+ public static final Thread.UncaughtExceptionHandler CHUNKSYSTEM_UNCAUGHT_EXCEPTION_HANDLER = new Thread.UncaughtExceptionHandler() { -+ @Override -+ public void uncaughtException(final Thread thread, final Throwable throwable) { -+ if (!(throwable instanceof ThreadDeath)) { -+ LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); -+ } -+ } -+ }; -+ -+ public final ServerLevel world; -+ public final int chunkX; -+ public final int chunkZ; -+ -+ public final ChunkTaskScheduler scheduler; -+ -+ // load/unload state -+ -+ // chunk data state -+ -+ private ChunkEntitySlices entityChunk; -+ // entity chunk that is loaded, but not yet deserialized -+ private CompoundTag pendingEntityChunk; -+ -+ ChunkEntitySlices loadInEntityChunk(final boolean transientChunk) { -+ TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Cannot sync load entity data off-main"); -+ final CompoundTag entityChunk; -+ final ChunkEntitySlices ret; -+ final ReentrantAreaLock.Node schedulingLock = this.scheduler.schedulingLockArea.lock(this.chunkX, this.chunkZ); -+ try { -+ if (this.entityChunk != null && (transientChunk || !this.entityChunk.isTransient())) { -+ return this.entityChunk; -+ } -+ final CompoundTag pendingEntityChunk = this.pendingEntityChunk; -+ if (!transientChunk && pendingEntityChunk == null) { -+ throw new IllegalStateException("Must load entity data from disk before loading in the entity chunk!"); -+ } -+ -+ if (this.entityChunk == null) { -+ ret = this.entityChunk = new ChunkEntitySlices( -+ this.world, this.chunkX, this.chunkZ, this.getChunkStatus(), -+ WorldUtil.getMinSection(this.world), WorldUtil.getMaxSection(this.world) -+ ); -+ -+ ret.setTransient(transientChunk); -+ -+ this.world.getEntityLookup().entitySectionLoad(this.chunkX, this.chunkZ, ret); -+ } else { -+ // transientChunk = false here -+ ret = this.entityChunk; -+ this.entityChunk.setTransient(false); -+ } -+ -+ if (!transientChunk) { -+ this.pendingEntityChunk = null; -+ entityChunk = pendingEntityChunk == EMPTY_ENTITY_CHUNK ? null : pendingEntityChunk; -+ } else { -+ entityChunk = null; -+ } -+ } finally { -+ this.scheduler.schedulingLockArea.unlock(schedulingLock); -+ } -+ -+ if (!transientChunk) { -+ if (entityChunk != null) { -+ final List entities = EntityStorage.readEntities(this.world, entityChunk); -+ -+ this.world.getEntityLookup().addEntityChunkEntities(entities, new ChunkPos(this.chunkX, this.chunkZ)); -+ } -+ } -+ -+ return ret; -+ } -+ -+ // needed to distinguish whether the entity chunk has been read from disk but is empty or whether it has _not_ -+ // been read from disk -+ private static final CompoundTag EMPTY_ENTITY_CHUNK = new CompoundTag(); -+ -+ private ChunkLoadTask.EntityDataLoadTask entityDataLoadTask; -+ // note: if entityDataLoadTask is cancelled, but on its completion entityDataLoadTaskWaiters.size() != 0, -+ // then the task is rescheduled -+ private List entityDataLoadTaskWaiters; -+ -+ public ChunkLoadTask.EntityDataLoadTask getEntityDataLoadTask() { -+ return this.entityDataLoadTask; -+ } -+ -+ // must hold schedule lock for the two below functions -+ -+ // returns only if the data has been loaded from disk, DOES NOT relate to whether it has been deserialized -+ // or added into the world (or even into entityChunk) -+ public boolean isEntityChunkNBTLoaded() { -+ return (this.entityChunk != null && !this.entityChunk.isTransient()) || this.pendingEntityChunk != null; -+ } -+ -+ private void completeEntityLoad(final GenericDataLoadTask.TaskResult result) { -+ final List completeWaiters; -+ ChunkLoadTask.EntityDataLoadTask entityDataLoadTask = null; -+ boolean scheduleEntityTask = false; -+ ReentrantAreaLock.Node schedulingLock = this.scheduler.schedulingLockArea.lock(this.chunkX, this.chunkZ); -+ try { -+ final List waiters = this.entityDataLoadTaskWaiters; -+ this.entityDataLoadTask = null; -+ if (result != null) { -+ this.entityDataLoadTaskWaiters = null; -+ this.pendingEntityChunk = result.left() == null ? EMPTY_ENTITY_CHUNK : result.left(); -+ if (result.right() != null) { -+ LOGGER.error("Unhandled entity data load exception, data data will be lost: ", result.right()); -+ } -+ -+ for (final GenericDataLoadTaskCallback callback : waiters) { -+ callback.markCompleted(); -+ } -+ -+ completeWaiters = waiters; -+ } else { -+ // cancelled -+ completeWaiters = null; -+ -+ // need to re-schedule? -+ if (waiters.isEmpty()) { -+ this.entityDataLoadTaskWaiters = null; -+ // no tasks to schedule _for_ -+ } else { -+ entityDataLoadTask = this.entityDataLoadTask = new ChunkLoadTask.EntityDataLoadTask( -+ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority() -+ ); -+ entityDataLoadTask.addCallback(this::completeEntityLoad); -+ // need one schedule() per waiter -+ for (final GenericDataLoadTaskCallback callback : waiters) { -+ scheduleEntityTask |= entityDataLoadTask.schedule(true); -+ } -+ } -+ } -+ } finally { -+ this.scheduler.schedulingLockArea.unlock(schedulingLock); -+ } -+ -+ if (scheduleEntityTask) { -+ entityDataLoadTask.scheduleNow(); -+ } -+ -+ // avoid holding the scheduling lock while completing -+ if (completeWaiters != null) { -+ for (final GenericDataLoadTaskCallback callback : completeWaiters) { -+ callback.acceptCompleted(result); -+ } -+ } -+ -+ schedulingLock = this.scheduler.schedulingLockArea.lock(this.chunkX, this.chunkZ); -+ try { -+ this.checkUnload(); -+ } finally { -+ this.scheduler.schedulingLockArea.unlock(schedulingLock); -+ } -+ } -+ -+ // note: it is guaranteed that the consumer cannot be called for the entirety that the schedule lock is held -+ // however, when the consumer is invoked, it will hold the schedule lock -+ public GenericDataLoadTaskCallback getOrLoadEntityData(final Consumer> consumer) { -+ if (this.isEntityChunkNBTLoaded()) { -+ throw new IllegalStateException("Cannot load entity data, it is already loaded"); -+ } -+ // why not just acquire the lock? because the caller NEEDS to call isEntityChunkNBTLoaded before this! -+ if (!this.scheduler.schedulingLockArea.isHeldByCurrentThread(this.chunkX, this.chunkZ)) { -+ throw new IllegalStateException("Must hold scheduling lock"); -+ } -+ -+ final GenericDataLoadTaskCallback ret = new EntityDataLoadTaskCallback((Consumer)consumer, this); -+ -+ if (this.entityDataLoadTask == null) { -+ this.entityDataLoadTask = new ChunkLoadTask.EntityDataLoadTask( -+ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority() -+ ); -+ this.entityDataLoadTask.addCallback(this::completeEntityLoad); -+ this.entityDataLoadTaskWaiters = new ArrayList<>(); -+ } -+ this.entityDataLoadTaskWaiters.add(ret); -+ if (this.entityDataLoadTask.schedule(true)) { -+ ret.schedule = this.entityDataLoadTask; -+ } -+ this.checkUnload(); -+ -+ return ret; -+ } -+ -+ private static final class EntityDataLoadTaskCallback extends GenericDataLoadTaskCallback { -+ -+ public EntityDataLoadTaskCallback(final Consumer> consumer, final NewChunkHolder chunkHolder) { -+ super(consumer, chunkHolder); -+ } -+ -+ @Override -+ void internalCancel() { -+ this.chunkHolder.entityDataLoadTaskWaiters.remove(this); -+ this.chunkHolder.entityDataLoadTask.cancel(); -+ } -+ } -+ -+ private PoiChunk poiChunk; -+ -+ private ChunkLoadTask.PoiDataLoadTask poiDataLoadTask; -+ // note: if entityDataLoadTask is cancelled, but on its completion entityDataLoadTaskWaiters.size() != 0, -+ // then the task is rescheduled -+ private List poiDataLoadTaskWaiters; -+ -+ public ChunkLoadTask.PoiDataLoadTask getPoiDataLoadTask() { -+ return this.poiDataLoadTask; -+ } -+ -+ // must hold schedule lock for the two below functions -+ -+ public boolean isPoiChunkLoaded() { -+ return this.poiChunk != null; -+ } -+ -+ private void completePoiLoad(final GenericDataLoadTask.TaskResult result) { -+ final List completeWaiters; -+ ChunkLoadTask.PoiDataLoadTask poiDataLoadTask = null; -+ boolean schedulePoiTask = false; -+ ReentrantAreaLock.Node schedulingLock = this.scheduler.schedulingLockArea.lock(this.chunkX, this.chunkZ); -+ try { -+ final List waiters = this.poiDataLoadTaskWaiters; -+ this.poiDataLoadTask = null; -+ if (result != null) { -+ this.poiDataLoadTaskWaiters = null; -+ this.poiChunk = result.left(); -+ if (result.right() != null) { -+ LOGGER.error("Unhandled poi load exception, poi data will be lost: ", result.right()); -+ } -+ -+ for (final GenericDataLoadTaskCallback callback : waiters) { -+ callback.markCompleted(); -+ } -+ -+ completeWaiters = waiters; -+ } else { -+ // cancelled -+ completeWaiters = null; -+ -+ // need to re-schedule? -+ if (waiters.isEmpty()) { -+ this.poiDataLoadTaskWaiters = null; -+ // no tasks to schedule _for_ -+ } else { -+ poiDataLoadTask = this.poiDataLoadTask = new ChunkLoadTask.PoiDataLoadTask( -+ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority() -+ ); -+ poiDataLoadTask.addCallback(this::completePoiLoad); -+ // need one schedule() per waiter -+ for (final GenericDataLoadTaskCallback callback : waiters) { -+ schedulePoiTask |= poiDataLoadTask.schedule(true); -+ } -+ } -+ } -+ } finally { -+ this.scheduler.schedulingLockArea.unlock(schedulingLock); -+ } -+ -+ if (schedulePoiTask) { -+ poiDataLoadTask.scheduleNow(); -+ } -+ -+ // avoid holding the scheduling lock while completing -+ if (completeWaiters != null) { -+ for (final GenericDataLoadTaskCallback callback : completeWaiters) { -+ callback.acceptCompleted(result); -+ } -+ } -+ schedulingLock = this.scheduler.schedulingLockArea.lock(this.chunkX, this.chunkZ); -+ try { -+ this.checkUnload(); -+ } finally { -+ this.scheduler.schedulingLockArea.unlock(schedulingLock); -+ } -+ } -+ -+ // note: it is guaranteed that the consumer cannot be called for the entirety that the schedule lock is held -+ // however, when the consumer is invoked, it will hold the schedule lock -+ public GenericDataLoadTaskCallback getOrLoadPoiData(final Consumer> consumer) { -+ if (this.isPoiChunkLoaded()) { -+ throw new IllegalStateException("Cannot load poi data, it is already loaded"); -+ } -+ // why not just acquire the lock? because the caller NEEDS to call isPoiChunkLoaded before this! -+ if (!this.scheduler.schedulingLockArea.isHeldByCurrentThread(this.chunkX, this.chunkZ)) { -+ throw new IllegalStateException("Must hold scheduling lock"); -+ } -+ -+ final GenericDataLoadTaskCallback ret = new PoiDataLoadTaskCallback((Consumer)consumer, this); -+ -+ if (this.poiDataLoadTask == null) { -+ this.poiDataLoadTask = new ChunkLoadTask.PoiDataLoadTask( -+ this.scheduler, this.world, this.chunkX, this.chunkZ, this.getEffectivePriority() -+ ); -+ this.poiDataLoadTask.addCallback(this::completePoiLoad); -+ this.poiDataLoadTaskWaiters = new ArrayList<>(); -+ } -+ this.poiDataLoadTaskWaiters.add(ret); -+ if (this.poiDataLoadTask.schedule(true)) { -+ ret.schedule = this.poiDataLoadTask; -+ } -+ this.checkUnload(); -+ -+ return ret; -+ } -+ -+ private static final class PoiDataLoadTaskCallback extends GenericDataLoadTaskCallback { -+ -+ public PoiDataLoadTaskCallback(final Consumer> consumer, final NewChunkHolder chunkHolder) { -+ super(consumer, chunkHolder); -+ } -+ -+ @Override -+ void internalCancel() { -+ this.chunkHolder.poiDataLoadTaskWaiters.remove(this); -+ this.chunkHolder.poiDataLoadTask.cancel(); -+ } -+ } -+ -+ public static abstract class GenericDataLoadTaskCallback implements Cancellable { -+ -+ protected final Consumer> consumer; -+ protected final NewChunkHolder chunkHolder; -+ protected boolean completed; -+ protected GenericDataLoadTask schedule; -+ protected final AtomicBoolean scheduled = new AtomicBoolean(); -+ -+ public GenericDataLoadTaskCallback(final Consumer> consumer, -+ final NewChunkHolder chunkHolder) { -+ this.consumer = consumer; -+ this.chunkHolder = chunkHolder; -+ } -+ -+ public void schedule() { -+ if (this.scheduled.getAndSet(true)) { -+ throw new IllegalStateException("Double calling schedule()"); -+ } -+ if (this.schedule != null) { -+ this.schedule.scheduleNow(); -+ this.schedule = null; -+ } -+ } -+ -+ boolean isCompleted() { -+ return this.completed; -+ } -+ -+ // must hold scheduling lock -+ private boolean setCompleted() { -+ if (this.completed) { -+ return false; -+ } -+ return this.completed = true; -+ } -+ -+ // must hold scheduling lock -+ void markCompleted() { -+ if (this.completed) { -+ throw new IllegalStateException("May not be completed here"); -+ } -+ this.completed = true; -+ } -+ -+ void acceptCompleted(final GenericDataLoadTask.TaskResult result) { -+ if (result != null) { -+ if (this.completed) { -+ this.consumer.accept(result); -+ } else { -+ throw new IllegalStateException("Cannot be uncompleted at this point"); -+ } -+ } else { -+ throw new NullPointerException("Result cannot be null (cancelled)"); -+ } -+ } -+ -+ // holds scheduling lock -+ abstract void internalCancel(); -+ -+ @Override -+ public boolean cancel() { -+ final NewChunkHolder holder = this.chunkHolder; // Folia - use area based lock to reduce contention -+ final ReentrantAreaLock.Node schedulingLock = holder.scheduler.schedulingLockArea.lock(holder.chunkX, holder.chunkZ); -+ try { -+ if (!this.completed) { -+ this.completed = true; -+ this.internalCancel(); -+ return true; -+ } -+ return false; -+ } finally { -+ holder.scheduler.schedulingLockArea.unlock(schedulingLock); -+ } -+ } -+ } -+ -+ private ChunkAccess currentChunk; -+ -+ // generation status state -+ -+ /** -+ * Current status the chunk has been brought up to by the chunk system. null indicates no work at all -+ */ -+ private ChunkStatus currentGenStatus; -+ -+ // This allows unsynchronised access to the chunk and last gen status -+ private volatile ChunkCompletion lastChunkCompletion; -+ -+ public ChunkCompletion getLastChunkCompletion() { -+ return this.lastChunkCompletion; -+ } -+ -+ public static final record ChunkCompletion(ChunkAccess chunk, ChunkStatus genStatus) {}; -+ -+ /** -+ * The target final chunk status the chunk system will bring the chunk to. -+ */ -+ private ChunkStatus requestedGenStatus; -+ -+ private ChunkProgressionTask generationTask; -+ private ChunkStatus generationTaskStatus; -+ -+ /** -+ * contains the neighbours that this chunk generation is blocking on -+ */ -+ protected final ReferenceLinkedOpenHashSet neighboursBlockingGenTask = new ReferenceLinkedOpenHashSet<>(4); -+ -+ /** -+ * map of ChunkHolder -> Required Status for this chunk -+ */ -+ protected final Reference2ObjectLinkedOpenHashMap neighboursWaitingForUs = new Reference2ObjectLinkedOpenHashMap<>(); -+ -+ public void addGenerationBlockingNeighbour(final NewChunkHolder neighbour) { -+ this.neighboursBlockingGenTask.add(neighbour); -+ } -+ -+ public void addWaitingNeighbour(final NewChunkHolder neighbour, final ChunkStatus requiredStatus) { -+ final boolean wasEmpty = this.neighboursWaitingForUs.isEmpty(); -+ this.neighboursWaitingForUs.put(neighbour, requiredStatus); -+ if (wasEmpty) { -+ this.checkUnload(); -+ } -+ } -+ -+ // priority state -+ -+ // the target priority for this chunk to generate at -+ // TODO this will screw over scheduling at lower priorities to neighbours, fix -+ private PrioritisedExecutor.Priority priority = PrioritisedExecutor.Priority.NORMAL; -+ private boolean priorityLocked; -+ -+ // the priority neighbouring chunks have requested this chunk generate at -+ private PrioritisedExecutor.Priority neighbourRequestedPriority = PrioritisedExecutor.Priority.IDLE; -+ -+ public PrioritisedExecutor.Priority getEffectivePriority() { -+ return PrioritisedExecutor.Priority.max(this.priority, this.neighbourRequestedPriority); -+ } -+ -+ protected void recalculateNeighbourRequestedPriority() { -+ if (this.neighboursWaitingForUs.isEmpty()) { -+ this.neighbourRequestedPriority = PrioritisedExecutor.Priority.IDLE; -+ return; -+ } -+ -+ PrioritisedExecutor.Priority max = PrioritisedExecutor.Priority.IDLE; -+ -+ for (final NewChunkHolder holder : this.neighboursWaitingForUs.keySet()) { -+ final PrioritisedExecutor.Priority neighbourPriority = holder.getEffectivePriority(); -+ if (neighbourPriority.isHigherPriority(max)) { -+ max = neighbourPriority; -+ } -+ } -+ -+ final PrioritisedExecutor.Priority current = this.getEffectivePriority(); -+ this.neighbourRequestedPriority = max; -+ final PrioritisedExecutor.Priority next = this.getEffectivePriority(); -+ -+ if (current == next) { -+ return; -+ } -+ -+ // our effective priority has changed, so change our task -+ if (this.generationTask != null) { -+ this.generationTask.setPriority(next); -+ } -+ -+ // now propagate this to our neighbours -+ this.recalculateNeighbourPriorities(); -+ } -+ -+ public void recalculateNeighbourPriorities() { -+ for (final NewChunkHolder holder : this.neighboursBlockingGenTask) { -+ holder.recalculateNeighbourRequestedPriority(); -+ } -+ } -+ -+ // must hold scheduling lock -+ public void raisePriority(final PrioritisedExecutor.Priority priority) { -+ if (this.priority != null && this.priority.isHigherOrEqualPriority(priority)) { -+ return; -+ } -+ this.setPriority(priority); -+ } -+ -+ private void lockPriority() { -+ this.priority = PrioritisedExecutor.Priority.NORMAL; -+ this.priorityLocked = true; -+ } -+ -+ // must hold scheduling lock -+ public void setPriority(final PrioritisedExecutor.Priority priority) { -+ if (this.priorityLocked) { -+ return; -+ } -+ final PrioritisedExecutor.Priority old = this.getEffectivePriority(); -+ this.priority = priority; -+ final PrioritisedExecutor.Priority newPriority = this.getEffectivePriority(); -+ -+ if (old != newPriority) { -+ if (this.generationTask != null) { -+ this.generationTask.setPriority(newPriority); -+ } -+ } -+ -+ this.recalculateNeighbourPriorities(); -+ } -+ -+ // must hold scheduling lock -+ public void lowerPriority(final PrioritisedExecutor.Priority priority) { -+ if (this.priority != null && this.priority.isLowerOrEqualPriority(priority)) { -+ return; -+ } -+ this.setPriority(priority); -+ } -+ -+ // error handling state -+ private ChunkStatus failedGenStatus; -+ private Throwable genTaskException; -+ private Thread genTaskFailedThread; -+ -+ private boolean failedLightUpdate; -+ -+ public void failedLightUpdate() { -+ this.failedLightUpdate = true; -+ } -+ -+ public boolean hasFailedGeneration() { -+ return this.genTaskException != null; -+ } -+ -+ // ticket level state -+ private int oldTicketLevel = ChunkLevel.MAX_LEVEL + 1; -+ private int currentTicketLevel = ChunkLevel.MAX_LEVEL + 1; -+ -+ public int getTicketLevel() { -+ return this.currentTicketLevel; -+ } -+ -+ public final ChunkHolder vanillaChunkHolder; -+ -+ public NewChunkHolder(final ServerLevel world, final int chunkX, final int chunkZ, final ChunkTaskScheduler scheduler) { -+ this.world = world; -+ this.chunkX = chunkX; -+ this.chunkZ = chunkZ; -+ this.scheduler = scheduler; -+ this.vanillaChunkHolder = new ChunkHolder(new ChunkPos(chunkX, chunkZ), world, world.getLightEngine(), world.chunkSource.chunkMap, this); -+ } -+ -+ protected ImposterProtoChunk wrappedChunkForNeighbour; -+ -+ // holds scheduling lock -+ public ChunkAccess getChunkForNeighbourAccess() { -+ // Vanilla overrides the status futures with an imposter chunk to prevent writes to full chunks -+ // But we don't store per-status futures, so we need this hack -+ if (this.wrappedChunkForNeighbour != null) { -+ return this.wrappedChunkForNeighbour; -+ } -+ final ChunkAccess ret = this.currentChunk; -+ return ret instanceof LevelChunk fullChunk ? this.wrappedChunkForNeighbour = new ImposterProtoChunk(fullChunk, false) : ret; -+ } -+ -+ public ChunkAccess getCurrentChunk() { -+ return this.currentChunk; -+ } -+ -+ int getCurrentTicketLevel() { -+ return this.currentTicketLevel; -+ } -+ -+ void updateTicketLevel(final int toLevel) { -+ this.currentTicketLevel = toLevel; -+ } -+ -+ private int totalNeighboursUsingThisChunk = 0; -+ -+ // holds schedule lock -+ public void addNeighbourUsingChunk() { -+ final int now = ++this.totalNeighboursUsingThisChunk; -+ -+ if (now == 1) { -+ this.checkUnload(); -+ } -+ } -+ -+ // holds schedule lock -+ public void removeNeighbourUsingChunk() { -+ final int now = --this.totalNeighboursUsingThisChunk; -+ -+ if (now == 0) { -+ this.checkUnload(); -+ } -+ -+ if (now < 0) { -+ throw new IllegalStateException("Neighbours using this chunk cannot be negative"); -+ } -+ } -+ -+ // must hold scheduling lock -+ // returns string reason for why chunk should remain loaded, null otherwise -+ public final String isSafeToUnload() { -+ // is ticket level below threshold? -+ if (this.oldTicketLevel <= ChunkHolderManager.MAX_TICKET_LEVEL) { -+ return "ticket_level"; -+ } -+ -+ // are we being used by another chunk for generation? -+ if (this.totalNeighboursUsingThisChunk != 0) { -+ return "neighbours_generating"; -+ } -+ -+ // are we going to be used by another chunk for generation? -+ if (!this.neighboursWaitingForUs.isEmpty()) { -+ return "neighbours_waiting"; -+ } -+ -+ // chunk must be marked inaccessible (i.e unloaded to plugins) -+ if (this.getChunkStatus() != FullChunkStatus.INACCESSIBLE) { -+ return "fullchunkstatus"; -+ } -+ -+ // are we currently generating anything, or have requested generation? -+ if (this.generationTask != null) { -+ return "generating"; -+ } -+ if (this.requestedGenStatus != null) { -+ return "requested_generation"; -+ } -+ -+ // entity data requested? -+ if (this.entityDataLoadTask != null) { -+ return "entity_data_requested"; -+ } -+ -+ // poi data requested? -+ if (this.poiDataLoadTask != null) { -+ return "poi_data_requested"; -+ } -+ -+ // are we pending serialization? -+ if (this.entityDataUnload != null) { -+ return "entity_serialization"; -+ } -+ if (this.poiDataUnload != null) { -+ return "poi_serialization"; -+ } -+ if (this.chunkDataUnload != null) { -+ return "chunk_serialization"; -+ } -+ -+ // Note: light tasks do not need a check, as they add a ticket. -+ -+ // nothing is using this chunk, so it should be unloaded -+ return null; -+ } -+ -+ /** Unloaded from chunk map */ -+ boolean killed; -+ -+ // must hold scheduling lock -+ private void checkUnload() { -+ if (this.killed) { -+ return; -+ } -+ if (this.isSafeToUnload() == null) { -+ // ensure in unload queue -+ this.scheduler.chunkHolderManager.unloadQueue.addChunk(this.chunkX, this.chunkZ); -+ } else { -+ // ensure not in unload queue -+ this.scheduler.chunkHolderManager.unloadQueue.removeChunk(this.chunkX, this.chunkZ); -+ } -+ } -+ -+ static final record UnloadState(NewChunkHolder holder, ChunkAccess chunk, ChunkEntitySlices entityChunk, PoiChunk poiChunk) {}; -+ -+ // note: these are completed with null to indicate that no write occurred -+ // they are also completed with null to indicate a null write occurred -+ private UnloadTask chunkDataUnload; -+ private UnloadTask entityDataUnload; -+ private UnloadTask poiDataUnload; -+ -+ public static final record UnloadTask(Completable completable, DelayedPrioritisedTask task) {} -+ -+ public UnloadTask getUnloadTask(final RegionFileIOThread.RegionFileType type) { -+ switch (type) { -+ case CHUNK_DATA: -+ return this.chunkDataUnload; -+ case ENTITY_DATA: -+ return this.entityDataUnload; -+ case POI_DATA: -+ return this.poiDataUnload; -+ default: -+ throw new IllegalStateException("Unknown regionfile type " + type); -+ } -+ } -+ -+ private UnloadState unloadState; -+ -+ // holds schedule lock -+ UnloadState unloadStage1() { -+ // because we hold the scheduling lock, we cannot actually unload anything -+ // so we need to null this chunk's state -+ ChunkAccess chunk = this.currentChunk; -+ ChunkEntitySlices entityChunk = this.entityChunk; -+ PoiChunk poiChunk = this.poiChunk; -+ // chunk state -+ this.currentChunk = null; -+ this.currentGenStatus = null; -+ this.wrappedChunkForNeighbour = null; -+ this.lastChunkCompletion = null; -+ // entity chunk state -+ this.entityChunk = null; -+ this.pendingEntityChunk = null; -+ -+ // poi chunk state -+ this.poiChunk = null; -+ -+ // priority state -+ this.priorityLocked = false; -+ -+ if (chunk != null) { -+ this.chunkDataUnload = new UnloadTask(new Completable<>(), new DelayedPrioritisedTask(PrioritisedExecutor.Priority.NORMAL)); -+ } -+ if (poiChunk != null) { -+ this.poiDataUnload = new UnloadTask(new Completable<>(), null); -+ } -+ if (entityChunk != null) { -+ this.entityDataUnload = new UnloadTask(new Completable<>(), null); -+ } -+ -+ return this.unloadState = (chunk != null || entityChunk != null || poiChunk != null) ? new UnloadState(this, chunk, entityChunk, poiChunk) : null; -+ } -+ -+ // data is null if failed or does not need to be saved -+ void completeAsyncChunkDataSave(final CompoundTag data) { -+ if (data != null) { -+ RegionFileIOThread.scheduleSave(this.world, this.chunkX, this.chunkZ, data, RegionFileIOThread.RegionFileType.CHUNK_DATA); -+ } -+ this.chunkDataUnload.completable().complete(data); -+ final ReentrantAreaLock.Node schedulingLock = this.scheduler.schedulingLockArea.lock(this.chunkX, this.chunkZ); -+ try { -+ // can only write to these fields while holding the schedule lock -+ this.chunkDataUnload = null; -+ this.checkUnload(); -+ } finally { -+ this.scheduler.schedulingLockArea.unlock(schedulingLock); -+ } -+ } -+ -+ void unloadStage2(final UnloadState state) { -+ this.unloadState = null; -+ final ChunkAccess chunk = state.chunk(); -+ final ChunkEntitySlices entityChunk = state.entityChunk(); -+ final PoiChunk poiChunk = state.poiChunk(); -+ -+ final boolean shouldLevelChunkNotSave = (chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave); -+ -+ // unload chunk data -+ if (chunk != null) { -+ if (chunk instanceof LevelChunk levelChunk) { -+ levelChunk.setLoaded(false); -+ } -+ -+ if (!shouldLevelChunkNotSave) { -+ this.saveChunk(chunk, true); -+ } else { -+ this.completeAsyncChunkDataSave(null); -+ } -+ -+ if (chunk instanceof LevelChunk levelChunk) { -+ this.world.unload(levelChunk); -+ } -+ } -+ -+ // unload entity data -+ if (entityChunk != null) { -+ this.saveEntities(entityChunk, true); -+ // yes this is a hack to pass the compound tag through... -+ final CompoundTag lastEntityUnload = this.lastEntityUnload; -+ this.lastEntityUnload = null; -+ -+ if (entityChunk.unload()) { -+ final ReentrantAreaLock.Node schedulingLock = this.scheduler.schedulingLockArea.lock(this.chunkX, this.chunkZ); -+ try { -+ entityChunk.setTransient(true); -+ this.entityChunk = entityChunk; -+ } finally { -+ this.scheduler.schedulingLockArea.unlock(schedulingLock); -+ } -+ } else { -+ this.world.getEntityLookup().entitySectionUnload(this.chunkX, this.chunkZ); -+ } -+ // we need to delay the callback until after determining transience, otherwise a potential loader could -+ // set entityChunk before we do -+ this.entityDataUnload.completable().complete(lastEntityUnload); -+ } -+ -+ // unload poi data -+ if (poiChunk != null) { -+ if (poiChunk.isDirty() && !shouldLevelChunkNotSave) { -+ this.savePOI(poiChunk, true); -+ } else { -+ this.poiDataUnload.completable().complete(null); -+ } -+ -+ if (poiChunk.isLoaded()) { -+ this.world.getPoiManager().onUnload(CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ)); -+ } -+ } -+ } -+ -+ boolean unloadStage3() { -+ // can only write to these while holding the schedule lock, and we instantly complete them in stage2 -+ this.poiDataUnload = null; -+ this.entityDataUnload = null; -+ -+ // we need to check if anything has been loaded in the meantime (or if we have transient entities) -+ if (this.entityChunk != null || this.poiChunk != null || this.currentChunk != null) { -+ return false; -+ } -+ -+ return this.isSafeToUnload() == null; -+ } -+ -+ private void cancelGenTask() { -+ if (this.generationTask != null) { -+ this.generationTask.cancel(); -+ } else { -+ // otherwise, we are blocking on neighbours, so remove them -+ if (!this.neighboursBlockingGenTask.isEmpty()) { -+ for (final NewChunkHolder neighbour : this.neighboursBlockingGenTask) { -+ if (neighbour.neighboursWaitingForUs.remove(this) == null) { -+ throw new IllegalStateException("Corrupt state"); -+ } -+ if (neighbour.neighboursWaitingForUs.isEmpty()) { -+ neighbour.checkUnload(); -+ } -+ } -+ this.neighboursBlockingGenTask.clear(); -+ this.checkUnload(); -+ } -+ } -+ } -+ -+ // holds: ticket level update lock -+ // holds: schedule lock -+ public void processTicketLevelUpdate(final List scheduledTasks, final List changedLoadStatus) { -+ final int oldLevel = this.oldTicketLevel; -+ final int newLevel = this.currentTicketLevel; -+ -+ if (oldLevel == newLevel) { -+ return; -+ } -+ -+ this.oldTicketLevel = newLevel; -+ -+ final FullChunkStatus oldState = ChunkLevel.fullStatus(oldLevel); -+ final FullChunkStatus newState = ChunkLevel.fullStatus(newLevel); -+ final boolean oldUnloaded = oldLevel > ChunkHolderManager.MAX_TICKET_LEVEL; -+ final boolean newUnloaded = newLevel > ChunkHolderManager.MAX_TICKET_LEVEL; -+ -+ final ChunkStatus maxGenerationStatusOld = ChunkLevel.generationStatus(oldLevel); -+ final ChunkStatus maxGenerationStatusNew = ChunkLevel.generationStatus(newLevel); -+ -+ // check for cancellations from downgrading ticket level -+ if (this.requestedGenStatus != null && !newState.isOrAfter(FullChunkStatus.FULL) && newLevel > oldLevel) { -+ // note: cancel() may invoke onChunkGenComplete synchronously here -+ if (newUnloaded) { -+ // need to cancel all tasks -+ // note: requested status must be set to null here before cancellation, to indicate to the -+ // completion logic that we do not want rescheduling to occur -+ this.requestedGenStatus = null; -+ this.cancelGenTask(); -+ } else { -+ final ChunkStatus toCancel = maxGenerationStatusNew.getNextStatus(); -+ final ChunkStatus currentRequestedStatus = this.requestedGenStatus; -+ -+ if (currentRequestedStatus.isOrAfter(toCancel)) { -+ // we do have to cancel something here -+ // clamp requested status to the maximum -+ if (this.currentGenStatus != null && this.currentGenStatus.isOrAfter(maxGenerationStatusNew)) { -+ // already generated to status, so we must cancel -+ this.requestedGenStatus = null; -+ this.cancelGenTask(); -+ } else { -+ // not generated to status, so we may have to cancel -+ // note: gen task is always 1 status above current gen status if not null -+ this.requestedGenStatus = maxGenerationStatusNew; -+ if (this.generationTaskStatus != null && this.generationTaskStatus.isOrAfter(toCancel)) { -+ // TOOD is this even possible? i don't think so -+ throw new IllegalStateException("?????"); -+ } -+ } -+ } -+ } -+ } -+ -+ if (newState != oldState) { -+ if (newState.isOrAfter(oldState)) { -+ // status upgrade -+ if (!oldState.isOrAfter(FullChunkStatus.FULL) && newState.isOrAfter(FullChunkStatus.FULL)) { -+ // may need to schedule full load -+ if (this.currentGenStatus != ChunkStatus.FULL) { -+ if (this.requestedGenStatus != null) { -+ this.requestedGenStatus = ChunkStatus.FULL; -+ } else { -+ this.scheduler.schedule( -+ this.chunkX, this.chunkZ, ChunkStatus.FULL, this, scheduledTasks -+ ); -+ } -+ } else { -+ // now we are fully loaded -+ this.queueBorderFullStatus(true, changedLoadStatus); -+ } -+ } -+ } else { -+ // status downgrade -+ if (!newState.isOrAfter(FullChunkStatus.ENTITY_TICKING) && oldState.isOrAfter(FullChunkStatus.ENTITY_TICKING)) { -+ this.completeFullStatusConsumers(FullChunkStatus.ENTITY_TICKING, null); -+ } -+ -+ if (!newState.isOrAfter(FullChunkStatus.BLOCK_TICKING) && oldState.isOrAfter(FullChunkStatus.BLOCK_TICKING)) { -+ this.completeFullStatusConsumers(FullChunkStatus.BLOCK_TICKING, null); -+ } -+ -+ if (!newState.isOrAfter(FullChunkStatus.FULL) && oldState.isOrAfter(FullChunkStatus.FULL)) { -+ this.completeFullStatusConsumers(FullChunkStatus.FULL, null); -+ } -+ } -+ } -+ -+ if (oldState != newState) { -+ if (this.onTicketUpdate(oldState, newState)) { -+ changedLoadStatus.add(this); -+ } -+ } -+ -+ if (oldUnloaded != newUnloaded) { -+ this.checkUnload(); -+ } -+ } -+ -+ /* -+ For full chunks, vanilla just loads chunks around it up to FEATURES, 1 radius -+ -+ For ticking chunks, it updates the persistent entity manager (soon to be completely nuked by EntitySliceManager, which -+ will also need to be updated but with far less implications) -+ It also shoves the scheduled block ticks into the tick scheduler -+ -+ For entity ticking chunks, updates the entity manager (see above) -+ */ -+ -+ static final int NEIGHBOUR_RADIUS = 2; -+ private long fullNeighbourChunksLoadedBitset; -+ -+ private static int getFullNeighbourIndex(final int relativeX, final int relativeZ) { -+ // index = (relativeX + NEIGHBOUR_CACHE_RADIUS) + (relativeZ + NEIGHBOUR_CACHE_RADIUS) * (NEIGHBOUR_CACHE_RADIUS * 2 + 1) -+ // optimised variant of the above by moving some of the ops to compile time -+ return relativeX + (relativeZ * (NEIGHBOUR_RADIUS * 2 + 1)) + (NEIGHBOUR_RADIUS + NEIGHBOUR_RADIUS * ((NEIGHBOUR_RADIUS * 2 + 1))); -+ } -+ public final boolean isNeighbourFullLoaded(final int relativeX, final int relativeZ) { -+ return (this.fullNeighbourChunksLoadedBitset & (1L << getFullNeighbourIndex(relativeX, relativeZ))) != 0; -+ } -+ -+ // returns true if this chunk changed full status -+ public final boolean setNeighbourFullLoaded(final int relativeX, final int relativeZ) { -+ final long before = this.fullNeighbourChunksLoadedBitset; -+ final int index = getFullNeighbourIndex(relativeX, relativeZ); -+ this.fullNeighbourChunksLoadedBitset |= (1L << index); -+ return this.onNeighbourChange(before, this.fullNeighbourChunksLoadedBitset); -+ } -+ -+ // returns true if this chunk changed full status -+ public final boolean setNeighbourFullUnloaded(final int relativeX, final int relativeZ) { -+ final long before = this.fullNeighbourChunksLoadedBitset; -+ final int index = getFullNeighbourIndex(relativeX, relativeZ); -+ this.fullNeighbourChunksLoadedBitset &= ~(1L << index); -+ return this.onNeighbourChange(before, this.fullNeighbourChunksLoadedBitset); -+ } -+ -+ public static boolean areNeighboursFullLoaded(final long bitset, final int radius) { -+ // index = relativeX + (relativeZ * (NEIGHBOUR_CACHE_RADIUS * 2 + 1)) + (NEIGHBOUR_CACHE_RADIUS + NEIGHBOUR_CACHE_RADIUS * ((NEIGHBOUR_CACHE_RADIUS * 2 + 1))) -+ switch (radius) { -+ case 0: { -+ return (bitset & (1L << getFullNeighbourIndex(0, 0))) != 0L; -+ } -+ case 1: { -+ long mask = 0L; -+ for (int dx = -1; dx <= 1; ++dx) { -+ for (int dz = -1; dz <= 1; ++dz) { -+ mask |= (1L << getFullNeighbourIndex(dx, dz)); -+ } -+ } -+ return (bitset & mask) == mask; -+ } -+ case 2: { -+ long mask = 0L; -+ for (int dx = -2; dx <= 2; ++dx) { -+ for (int dz = -2; dz <= 2; ++dz) { -+ mask |= (1L << getFullNeighbourIndex(dx, dz)); -+ } -+ } -+ return (bitset & mask) == mask; -+ } -+ -+ default: { -+ throw new IllegalArgumentException("Radius not recognized: " + radius); -+ } -+ } -+ } -+ -+ // upper 16 bits are pending status, lower 16 bits are current status -+ private volatile long chunkStatus; -+ private static final long PENDING_STATUS_MASK = Long.MIN_VALUE >> 31; -+ private static final FullChunkStatus[] CHUNK_STATUS_BY_ID = FullChunkStatus.values(); -+ private static final VarHandle CHUNK_STATUS_HANDLE = ConcurrentUtil.getVarHandle(NewChunkHolder.class, "chunkStatus", long.class); -+ -+ public static FullChunkStatus getCurrentChunkStatus(final long encoded) { -+ return CHUNK_STATUS_BY_ID[(int)encoded]; -+ } -+ -+ public static FullChunkStatus getPendingChunkStatus(final long encoded) { -+ return CHUNK_STATUS_BY_ID[(int)(encoded >>> 32)]; -+ } -+ -+ public FullChunkStatus getChunkStatus() { -+ return getCurrentChunkStatus(((long)CHUNK_STATUS_HANDLE.getVolatile((NewChunkHolder)this))); -+ } -+ -+ public boolean isEntityTickingReady() { -+ return this.getChunkStatus().isOrAfter(FullChunkStatus.ENTITY_TICKING); -+ } -+ -+ public boolean isTickingReady() { -+ return this.getChunkStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING); -+ } -+ -+ public boolean isFullChunkReady() { -+ return this.getChunkStatus().isOrAfter(FullChunkStatus.FULL); -+ } -+ -+ private static FullChunkStatus getStatusForBitset(final long bitset) { -+ if (areNeighboursFullLoaded(bitset, 2)) { -+ return FullChunkStatus.ENTITY_TICKING; -+ } else if (areNeighboursFullLoaded(bitset, 1)) { -+ return FullChunkStatus.BLOCK_TICKING; -+ } else if (areNeighboursFullLoaded(bitset, 0)) { -+ return FullChunkStatus.FULL; -+ } else { -+ return FullChunkStatus.INACCESSIBLE; -+ } -+ } -+ -+ // note: only while updating ticket level, so holds ticket update lock + scheduling lock -+ protected final boolean onTicketUpdate(final FullChunkStatus oldState, final FullChunkStatus newState) { -+ if (oldState == newState) { -+ return false; -+ } -+ -+ // preserve border request after full status complete, as it does not set anything in the bitset -+ FullChunkStatus byNeighbours = getStatusForBitset(this.fullNeighbourChunksLoadedBitset); -+ if (byNeighbours == FullChunkStatus.INACCESSIBLE && newState.isOrAfter(FullChunkStatus.FULL) && this.currentGenStatus == ChunkStatus.FULL) { -+ byNeighbours = FullChunkStatus.FULL; -+ } -+ -+ final FullChunkStatus toSet; -+ -+ if (newState.isOrAfter(byNeighbours)) { -+ // must clamp to neighbours level, even though we have the ticket level -+ toSet = byNeighbours; -+ } else { -+ // must clamp to ticket level, even though we have the neighbours -+ toSet = newState; -+ } -+ -+ long curr = (long)CHUNK_STATUS_HANDLE.getVolatile((NewChunkHolder)this); -+ -+ if (curr == ((long)toSet.ordinal() | ((long)toSet.ordinal() << 32))) { -+ // nothing to do -+ return false; -+ } -+ -+ int failures = 0; -+ for (;;) { -+ final long update = (curr & ~PENDING_STATUS_MASK) | ((long)toSet.ordinal() << 32); -+ if (curr == (curr = (long)CHUNK_STATUS_HANDLE.compareAndExchange((NewChunkHolder)this, curr, update))) { -+ return true; -+ } -+ -+ ++failures; -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ } -+ } -+ -+ protected final boolean onNeighbourChange(final long bitsetBefore, final long bitsetAfter) { -+ FullChunkStatus oldState = getStatusForBitset(bitsetBefore); -+ FullChunkStatus newState = getStatusForBitset(bitsetAfter); -+ final FullChunkStatus currStateTicketLevel = ChunkLevel.fullStatus(this.oldTicketLevel); -+ if (oldState.isOrAfter(currStateTicketLevel)) { -+ oldState = currStateTicketLevel; -+ } -+ if (newState.isOrAfter(currStateTicketLevel)) { -+ newState = currStateTicketLevel; -+ } -+ // preserve border request after full status complete, as it does not set anything in the bitset -+ if (newState == FullChunkStatus.INACCESSIBLE && currStateTicketLevel.isOrAfter(FullChunkStatus.FULL) && this.currentGenStatus == ChunkStatus.FULL) { -+ newState = FullChunkStatus.FULL; -+ } -+ -+ if (oldState == newState) { -+ return false; -+ } -+ -+ int failures = 0; -+ for (long curr = (long)CHUNK_STATUS_HANDLE.getVolatile((NewChunkHolder)this);;) { -+ final long update = (curr & ~PENDING_STATUS_MASK) | ((long)newState.ordinal() << 32); -+ if (curr == (curr = (long)CHUNK_STATUS_HANDLE.compareAndExchange((NewChunkHolder)this, curr, update))) { -+ return true; -+ } -+ -+ ++failures; -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ } -+ } -+ -+ private boolean queueBorderFullStatus(final boolean loaded, final List changedFullStatus) { -+ final FullChunkStatus toStatus = loaded ? FullChunkStatus.FULL : FullChunkStatus.INACCESSIBLE; -+ -+ int failures = 0; -+ for (long curr = (long)CHUNK_STATUS_HANDLE.getVolatile((NewChunkHolder)this);;) { -+ final FullChunkStatus currPending = getPendingChunkStatus(curr); -+ if (loaded && currPending != FullChunkStatus.INACCESSIBLE) { -+ throw new IllegalStateException("Expected " + FullChunkStatus.INACCESSIBLE + " for pending, but got " + currPending); -+ } -+ -+ final long update = (curr & ~PENDING_STATUS_MASK) | ((long)toStatus.ordinal() << 32); -+ if (curr == (curr = (long)CHUNK_STATUS_HANDLE.compareAndExchange((NewChunkHolder)this, curr, update))) { -+ if ((int)(update) != (int)(update >>> 32)) { -+ changedFullStatus.add(this); -+ return true; -+ } -+ return false; -+ } -+ -+ ++failures; -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ } -+ } -+ -+ // only call on main thread, must hold ticket level and scheduling lock -+ private void onFullChunkLoadChange(final boolean loaded, final List changedFullStatus) { -+ final ReentrantAreaLock.Node schedulingLock = this.scheduler.schedulingLockArea.lock(this.chunkX, this.chunkZ, NEIGHBOUR_RADIUS); -+ try { -+ for (int dz = -NEIGHBOUR_RADIUS; dz <= NEIGHBOUR_RADIUS; ++dz) { -+ for (int dx = -NEIGHBOUR_RADIUS; dx <= NEIGHBOUR_RADIUS; ++dx) { -+ final NewChunkHolder holder = (dx | dz) == 0 ? this : this.scheduler.chunkHolderManager.getChunkHolder(dx + this.chunkX, dz + this.chunkZ); -+ if (loaded) { -+ if (holder.setNeighbourFullLoaded(-dx, -dz)) { -+ changedFullStatus.add(holder); -+ } -+ } else { -+ if (holder != null && holder.setNeighbourFullUnloaded(-dx, -dz)) { -+ changedFullStatus.add(holder); -+ } -+ } -+ } -+ } -+ } finally { -+ this.scheduler.schedulingLockArea.unlock(schedulingLock); -+ } -+ } -+ -+ private FullChunkStatus updateCurrentState(final FullChunkStatus to) { -+ int failures = 0; -+ for (long curr = (long)CHUNK_STATUS_HANDLE.getVolatile((NewChunkHolder)this);;) { -+ final long update = (curr & PENDING_STATUS_MASK) | (long)to.ordinal(); -+ if (curr == (curr = (long)CHUNK_STATUS_HANDLE.compareAndExchange((NewChunkHolder)this, curr, update))) { -+ return getPendingChunkStatus(curr); -+ } -+ -+ ++failures; -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ } -+ } -+ -+ private void changeEntityChunkStatus(final FullChunkStatus toStatus) { -+ this.world.getEntityLookup().chunkStatusChange(this.chunkX, this.chunkZ, toStatus); -+ } -+ -+ private boolean processingFullStatus = false; -+ -+ // only to be called on the main thread, no locks need to be held -+ public boolean handleFullStatusChange(final List changedFullStatus) { -+ TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Cannot update full status thread off-main"); -+ -+ boolean ret = false; -+ -+ if (this.processingFullStatus) { -+ // we cannot process updates recursively -+ return ret; -+ } -+ -+ // note: use opaque reads for chunk status read since we need it to be atomic -+ -+ // test if anything changed -+ long statusCheck = (long)CHUNK_STATUS_HANDLE.getOpaque((NewChunkHolder)this); -+ if ((int)statusCheck == (int)(statusCheck >>> 32)) { -+ // nothing changed -+ return ret; -+ } -+ -+ final ChunkTaskScheduler scheduler = this.scheduler; -+ final ChunkHolderManager holderManager = scheduler.chunkHolderManager; -+ final int ticketKeep; -+ final Long ticketId = Long.valueOf(holderManager.getNextStatusUpgradeId()); -+ final ReentrantAreaLock.Node ticketLock = holderManager.ticketLockArea.lock(this.chunkX, this.chunkZ); -+ try { -+ ticketKeep = this.currentTicketLevel; -+ statusCheck = (long)CHUNK_STATUS_HANDLE.getOpaque((NewChunkHolder)this); -+ // handle race condition where ticket level and target status is updated concurrently -+ if ((int)statusCheck == (int)(statusCheck >>> 32)) { -+ // nothing changed -+ return ret; -+ } -+ holderManager.addTicketAtLevel(TicketType.STATUS_UPGRADE, CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ), ticketKeep, ticketId, false); -+ } finally { -+ holderManager.ticketLockArea.unlock(ticketLock); -+ } -+ -+ this.processingFullStatus = true; -+ try { -+ for (;;) { -+ final long currStateEncoded = (long)CHUNK_STATUS_HANDLE.getOpaque((NewChunkHolder)this); -+ final FullChunkStatus currState = getCurrentChunkStatus(currStateEncoded); -+ FullChunkStatus nextState = getPendingChunkStatus(currStateEncoded); -+ if (currState == nextState) { -+ if (nextState == FullChunkStatus.INACCESSIBLE) { -+ final ReentrantAreaLock.Node schedulingLock = this.scheduler.schedulingLockArea.lock(this.chunkX, this.chunkZ); -+ try { -+ this.checkUnload(); -+ } finally { -+ this.scheduler.schedulingLockArea.unlock(schedulingLock); -+ } -+ } -+ break; -+ } -+ -+ // chunks cannot downgrade state while status is pending a change -+ final LevelChunk chunk = (LevelChunk)this.currentChunk; -+ -+ // Note: we assume that only load/unload contain plugin logic -+ // plugin logic is anything stupid enough to possibly change the chunk status while it is already -+ // being changed (i.e during load it is possible it will try to set to full ticking) -+ // in order to allow this change, we also need this plugin logic to be contained strictly after all -+ // of the chunk system load callbacks are invoked -+ if (nextState.isOrAfter(currState)) { -+ // state upgrade -+ if (!currState.isOrAfter(FullChunkStatus.FULL) && nextState.isOrAfter(FullChunkStatus.FULL)) { -+ nextState = this.updateCurrentState(FullChunkStatus.FULL); -+ holderManager.ensureInAutosave(this); -+ chunk.pushChunkIntoLoadedMap(); -+ this.changeEntityChunkStatus(FullChunkStatus.FULL); -+ chunk.onChunkLoad(this); -+ this.onFullChunkLoadChange(true, changedFullStatus); -+ this.completeFullStatusConsumers(FullChunkStatus.FULL, chunk); -+ } -+ -+ if (!currState.isOrAfter(FullChunkStatus.BLOCK_TICKING) && nextState.isOrAfter(FullChunkStatus.BLOCK_TICKING)) { -+ nextState = this.updateCurrentState(FullChunkStatus.BLOCK_TICKING); -+ this.changeEntityChunkStatus(FullChunkStatus.BLOCK_TICKING); -+ chunk.onChunkTicking(this); -+ this.completeFullStatusConsumers(FullChunkStatus.BLOCK_TICKING, chunk); -+ } -+ -+ if (!currState.isOrAfter(FullChunkStatus.ENTITY_TICKING) && nextState.isOrAfter(FullChunkStatus.ENTITY_TICKING)) { -+ nextState = this.updateCurrentState(FullChunkStatus.ENTITY_TICKING); -+ this.changeEntityChunkStatus(FullChunkStatus.ENTITY_TICKING); -+ chunk.onChunkEntityTicking(this); -+ this.completeFullStatusConsumers(FullChunkStatus.ENTITY_TICKING, chunk); -+ } -+ } else { -+ if (currState.isOrAfter(FullChunkStatus.ENTITY_TICKING) && !nextState.isOrAfter(FullChunkStatus.ENTITY_TICKING)) { -+ this.changeEntityChunkStatus(FullChunkStatus.BLOCK_TICKING); -+ chunk.onChunkNotEntityTicking(this); -+ nextState = this.updateCurrentState(FullChunkStatus.BLOCK_TICKING); -+ } -+ -+ if (currState.isOrAfter(FullChunkStatus.BLOCK_TICKING) && !nextState.isOrAfter(FullChunkStatus.BLOCK_TICKING)) { -+ this.changeEntityChunkStatus(FullChunkStatus.FULL); -+ chunk.onChunkNotTicking(this); -+ nextState = this.updateCurrentState(FullChunkStatus.FULL); -+ } -+ -+ if (currState.isOrAfter(FullChunkStatus.FULL) && !nextState.isOrAfter(FullChunkStatus.FULL)) { -+ this.onFullChunkLoadChange(false, changedFullStatus); -+ this.changeEntityChunkStatus(FullChunkStatus.INACCESSIBLE); -+ chunk.onChunkUnload(this); -+ nextState = this.updateCurrentState(FullChunkStatus.INACCESSIBLE); -+ } -+ } -+ -+ ret = true; -+ } -+ } finally { -+ this.processingFullStatus = false; -+ holderManager.removeTicketAtLevel(TicketType.STATUS_UPGRADE, this.chunkX, this.chunkZ, ticketKeep, ticketId); -+ } -+ -+ return ret; -+ } -+ -+ // note: must hold scheduling lock -+ // rets true if the current requested gen status is not null (effectively, whether further scheduling is not needed) -+ boolean upgradeGenTarget(final ChunkStatus toStatus) { -+ if (toStatus == null) { -+ throw new NullPointerException("toStatus cannot be null"); -+ } -+ if (this.requestedGenStatus == null && this.generationTask == null) { -+ return false; -+ } -+ if (this.requestedGenStatus == null || !this.requestedGenStatus.isOrAfter(toStatus)) { -+ this.requestedGenStatus = toStatus; -+ } -+ return true; -+ } -+ -+ public void setGenerationTarget(final ChunkStatus toStatus) { -+ this.requestedGenStatus = toStatus; -+ } -+ -+ public boolean hasGenerationTask() { -+ return this.generationTask != null; -+ } -+ -+ public ChunkStatus getCurrentGenStatus() { -+ return this.currentGenStatus; -+ } -+ -+ public ChunkStatus getRequestedGenStatus() { -+ return this.requestedGenStatus; -+ } -+ -+ private final Reference2ObjectOpenHashMap>> statusWaiters = new Reference2ObjectOpenHashMap<>(); -+ -+ void addStatusConsumer(final ChunkStatus status, final Consumer consumer) { -+ this.statusWaiters.computeIfAbsent(status, (final ChunkStatus keyInMap) -> { -+ return new ArrayList<>(4); -+ }).add(consumer); -+ } -+ -+ private void completeStatusConsumers(ChunkStatus status, final ChunkAccess chunk) { -+ // need to tell future statuses to complete if cancelled -+ do { -+ this.completeStatusConsumers0(status, chunk); -+ } while (chunk == null && status != (status = status.getNextStatus())); -+ } -+ -+ private void completeStatusConsumers0(final ChunkStatus status, final ChunkAccess chunk) { -+ final List> consumers; -+ consumers = this.statusWaiters.remove(status); -+ -+ if (consumers == null) { -+ return; -+ } -+ -+ // must be scheduled to main, we do not trust the callback to not do anything stupid -+ this.scheduler.scheduleChunkTask(this.chunkX, this.chunkZ, () -> { -+ for (final Consumer consumer : consumers) { -+ try { -+ consumer.accept(chunk); -+ } catch (final ThreadDeath thr) { -+ throw thr; -+ } catch (final Throwable thr) { -+ LOGGER.error("Failed to process chunk status callback", thr); -+ } -+ } -+ }, PrioritisedExecutor.Priority.HIGHEST); -+ } -+ -+ private final Reference2ObjectOpenHashMap>> fullStatusWaiters = new Reference2ObjectOpenHashMap<>(); -+ -+ void addFullStatusConsumer(final FullChunkStatus status, final Consumer consumer) { -+ this.fullStatusWaiters.computeIfAbsent(status, (final FullChunkStatus keyInMap) -> { -+ return new ArrayList<>(4); -+ }).add(consumer); -+ } -+ -+ private void completeFullStatusConsumers(FullChunkStatus status, final LevelChunk chunk) { -+ // need to tell future statuses to complete if cancelled -+ final FullChunkStatus max = CHUNK_STATUS_BY_ID[CHUNK_STATUS_BY_ID.length - 1]; -+ -+ for (;;) { -+ this.completeFullStatusConsumers0(status, chunk); -+ if (chunk != null || status == max) { -+ break; -+ } -+ status = CHUNK_STATUS_BY_ID[status.ordinal() + 1]; -+ } -+ } -+ -+ private void completeFullStatusConsumers0(final FullChunkStatus status, final LevelChunk chunk) { -+ final List> consumers; -+ consumers = this.fullStatusWaiters.remove(status); -+ -+ if (consumers == null) { -+ return; -+ } -+ -+ // must be scheduled to main, we do not trust the callback to not do anything stupid -+ this.scheduler.scheduleChunkTask(this.chunkX, this.chunkZ, () -> { -+ for (final Consumer consumer : consumers) { -+ try { -+ consumer.accept(chunk); -+ } catch (final ThreadDeath thr) { -+ throw thr; -+ } catch (final Throwable thr) { -+ LOGGER.error("Failed to process chunk status callback", thr); -+ } -+ } -+ }, PrioritisedExecutor.Priority.HIGHEST); -+ } -+ -+ // note: must hold scheduling lock -+ private void onChunkGenComplete(final ChunkAccess newChunk, final ChunkStatus newStatus, -+ final List scheduleList, final List changedLoadStatus) { -+ if (!this.neighboursBlockingGenTask.isEmpty()) { -+ throw new IllegalStateException("Cannot have neighbours blocking this gen task"); -+ } -+ if (newChunk != null || (this.requestedGenStatus == null || !this.requestedGenStatus.isOrAfter(newStatus))) { -+ this.completeStatusConsumers(newStatus, newChunk); -+ } -+ // done now, clear state (must be done before scheduling new tasks) -+ this.generationTask = null; -+ this.generationTaskStatus = null; -+ if (newChunk == null) { -+ // task was cancelled -+ // should be careful as this could be called while holding the schedule lock and/or inside the -+ // ticket level update -+ // while a task may be cancelled, it is possible for it to be later re-scheduled -+ // however, because generationTask is only set to null on _completion_, the scheduler leaves -+ // the rescheduling logic to us here -+ final ChunkStatus requestedGenStatus = this.requestedGenStatus; -+ this.requestedGenStatus = null; -+ if (requestedGenStatus != null) { -+ // it looks like it has been requested, so we must reschedule -+ if (!this.neighboursWaitingForUs.isEmpty()) { -+ for (final Iterator> iterator = this.neighboursWaitingForUs.reference2ObjectEntrySet().fastIterator(); iterator.hasNext();) { -+ final Reference2ObjectMap.Entry entry = iterator.next(); -+ -+ final NewChunkHolder chunkHolder = entry.getKey(); -+ final ChunkStatus toStatus = entry.getValue(); -+ -+ if (!requestedGenStatus.isOrAfter(toStatus)) { -+ // if we were cancelled, we are responsible for removing the waiter -+ if (!chunkHolder.neighboursBlockingGenTask.remove(this)) { -+ throw new IllegalStateException("Corrupt state"); -+ } -+ if (chunkHolder.neighboursBlockingGenTask.isEmpty()) { -+ chunkHolder.checkUnload(); -+ } -+ iterator.remove(); -+ continue; -+ } -+ } -+ } -+ -+ // note: only after generationTask -> null, generationTaskStatus -> null, and requestedGenStatus -> null -+ this.scheduler.schedule( -+ this.chunkX, this.chunkZ, requestedGenStatus, this, scheduleList -+ ); -+ -+ // return, can't do anything further -+ return; -+ } -+ -+ if (!this.neighboursWaitingForUs.isEmpty()) { -+ for (final NewChunkHolder chunkHolder : this.neighboursWaitingForUs.keySet()) { -+ if (!chunkHolder.neighboursBlockingGenTask.remove(this)) { -+ throw new IllegalStateException("Corrupt state"); -+ } -+ if (chunkHolder.neighboursBlockingGenTask.isEmpty()) { -+ chunkHolder.checkUnload(); -+ } -+ } -+ this.neighboursWaitingForUs.clear(); -+ } -+ // reset priority, we have nothing left to generate to -+ this.setPriority(PrioritisedExecutor.Priority.NORMAL); -+ this.checkUnload(); -+ return; -+ } -+ -+ this.currentChunk = newChunk; -+ this.currentGenStatus = newStatus; -+ this.lastChunkCompletion = new ChunkCompletion(newChunk, newStatus); -+ -+ final ChunkStatus requestedGenStatus = this.requestedGenStatus; -+ -+ List needsScheduling = null; -+ boolean recalculatePriority = false; -+ for (final Iterator> iterator -+ = this.neighboursWaitingForUs.reference2ObjectEntrySet().fastIterator(); iterator.hasNext();) { -+ final Reference2ObjectMap.Entry entry = iterator.next(); -+ final NewChunkHolder neighbour = entry.getKey(); -+ final ChunkStatus requiredStatus = entry.getValue(); -+ -+ if (!newStatus.isOrAfter(requiredStatus)) { -+ if (requestedGenStatus == null || !requestedGenStatus.isOrAfter(requiredStatus)) { -+ // if we're cancelled, still need to clear this map -+ if (!neighbour.neighboursBlockingGenTask.remove(this)) { -+ throw new IllegalStateException("Neighbour is not waiting for us?"); -+ } -+ if (neighbour.neighboursBlockingGenTask.isEmpty()) { -+ neighbour.checkUnload(); -+ } -+ -+ iterator.remove(); -+ } -+ continue; -+ } -+ -+ // doesn't matter what isCancelled is here, we need to schedule if we can -+ -+ recalculatePriority = true; -+ if (!neighbour.neighboursBlockingGenTask.remove(this)) { -+ throw new IllegalStateException("Neighbour is not waiting for us?"); -+ } -+ -+ if (neighbour.neighboursBlockingGenTask.isEmpty()) { -+ if (neighbour.requestedGenStatus != null) { -+ if (needsScheduling == null) { -+ needsScheduling = new ArrayList<>(); -+ } -+ needsScheduling.add(neighbour); -+ } else { -+ neighbour.checkUnload(); -+ } -+ } -+ -+ // remove last; access to entry will throw if removed -+ iterator.remove(); -+ } -+ -+ if (newStatus == ChunkStatus.FULL) { -+ this.lockPriority(); -+ // must use oldTicketLevel, we hold the schedule lock but not the ticket level lock -+ // however, schedule lock needs to be held for ticket level callback, so we're fine here -+ if (ChunkLevel.fullStatus(this.oldTicketLevel).isOrAfter(FullChunkStatus.FULL)) { -+ this.queueBorderFullStatus(true, changedLoadStatus); -+ } -+ } -+ -+ if (recalculatePriority) { -+ this.recalculateNeighbourRequestedPriority(); -+ } -+ -+ if (requestedGenStatus != null && !newStatus.isOrAfter(requestedGenStatus)) { -+ this.scheduleNeighbours(needsScheduling, scheduleList); -+ -+ // we need to schedule more tasks now -+ this.scheduler.schedule( -+ this.chunkX, this.chunkZ, requestedGenStatus, this, scheduleList -+ ); -+ } else { -+ // we're done now -+ if (requestedGenStatus != null) { -+ this.requestedGenStatus = null; -+ } -+ // reached final stage, so stop scheduling now -+ this.setPriority(PrioritisedExecutor.Priority.NORMAL); -+ this.checkUnload(); -+ -+ this.scheduleNeighbours(needsScheduling, scheduleList); -+ } -+ } -+ -+ private void scheduleNeighbours(final List needsScheduling, final List scheduleList) { -+ if (needsScheduling != null) { -+ for (int i = 0, len = needsScheduling.size(); i < len; ++i) { -+ final NewChunkHolder neighbour = needsScheduling.get(i); -+ -+ this.scheduler.schedule( -+ neighbour.chunkX, neighbour.chunkZ, neighbour.requestedGenStatus, neighbour, scheduleList -+ ); -+ } -+ } -+ } -+ -+ public void setGenerationTask(final ChunkProgressionTask generationTask, final ChunkStatus taskStatus, -+ final List neighbours) { -+ if (this.generationTask != null || (this.currentGenStatus != null && this.currentGenStatus.isOrAfter(taskStatus))) { -+ throw new IllegalStateException("Currently generating or provided task is trying to generate to a level we are already at!"); -+ } -+ if (this.requestedGenStatus == null || !this.requestedGenStatus.isOrAfter(taskStatus)) { -+ throw new IllegalStateException("Cannot schedule generation task when not requested"); -+ } -+ this.generationTask = generationTask; -+ this.generationTaskStatus = taskStatus; -+ -+ for (int i = 0, len = neighbours.size(); i < len; ++i) { -+ neighbours.get(i).addNeighbourUsingChunk(); -+ } -+ -+ this.checkUnload(); -+ -+ generationTask.onComplete((final ChunkAccess access, final Throwable thr) -> { -+ if (generationTask != this.generationTask) { -+ throw new IllegalStateException( -+ "Cannot complete generation task '" + generationTask + "' because we are waiting on '" + this.generationTask + "' instead!" -+ ); -+ } -+ if (thr != null) { -+ if (this.genTaskException != null) { -+ // first one is probably the TRUE problem -+ return; -+ } -+ // don't set generation task to null, so that scheduling will not attempt to create another task and it -+ // will automatically block any further scheduling usage of this chunk as it will wait forever for a failed -+ // task to complete -+ this.genTaskException = thr; -+ this.failedGenStatus = taskStatus; -+ this.genTaskFailedThread = Thread.currentThread(); -+ -+ this.scheduler.unrecoverableChunkSystemFailure(this.chunkX, this.chunkZ, Map.of( -+ "Generation task", ChunkTaskScheduler.stringIfNull(generationTask), -+ "Task to status", ChunkTaskScheduler.stringIfNull(taskStatus) -+ ), thr); -+ return; -+ } -+ -+ final boolean scheduleTasks; -+ List tasks = ChunkHolderManager.getCurrentTicketUpdateScheduling(); -+ if (tasks == null) { -+ scheduleTasks = true; -+ tasks = new ArrayList<>(); -+ } else { -+ scheduleTasks = false; -+ // we are currently updating ticket levels, so we already hold the schedule lock -+ // this means we have to leave the ticket level update to handle the scheduling -+ } -+ final List changedLoadStatus = new ArrayList<>(); -+ // theoretically, we could schedule a chunk at the max radius which performs another max radius access. So we need to double the radius. -+ final ReentrantAreaLock.Node schedulingLock = this.scheduler.schedulingLockArea.lock(this.chunkX, this.chunkZ, 2 * ChunkTaskScheduler.getMaxAccessRadius()); -+ try { -+ for (int i = 0, len = neighbours.size(); i < len; ++i) { -+ neighbours.get(i).removeNeighbourUsingChunk(); -+ } -+ this.onChunkGenComplete(access, taskStatus, tasks, changedLoadStatus); -+ } finally { -+ this.scheduler.schedulingLockArea.unlock(schedulingLock); -+ } -+ this.scheduler.chunkHolderManager.addChangedStatuses(changedLoadStatus); -+ -+ if (scheduleTasks) { -+ // can't hold the lock while scheduling, so we have to build the tasks and then schedule after -+ for (int i = 0, len = tasks.size(); i < len; ++i) { -+ tasks.get(i).schedule(); -+ } -+ } -+ }); -+ } -+ -+ public PoiChunk getPoiChunk() { -+ return this.poiChunk; -+ } -+ -+ public ChunkEntitySlices getEntityChunk() { -+ return this.entityChunk; -+ } -+ -+ public long lastAutoSave; -+ -+ public static final record SaveStat(boolean savedChunk, boolean savedEntityChunk, boolean savedPoiChunk) {} -+ -+ public SaveStat save(final boolean shutdown, final boolean unloading) { -+ TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Cannot save data off-main"); -+ -+ ChunkAccess chunk = this.getCurrentChunk(); -+ PoiChunk poi = this.getPoiChunk(); -+ ChunkEntitySlices entities = this.getEntityChunk(); -+ boolean executedUnloadTask = false; -+ -+ if (shutdown) { -+ // make sure that the async unloads complete -+ if (this.unloadState != null) { -+ // must have errored during unload -+ chunk = this.unloadState.chunk(); -+ poi = this.unloadState.poiChunk(); -+ entities = this.unloadState.entityChunk(); -+ } -+ final UnloadTask chunkUnloadTask = this.chunkDataUnload; -+ final DelayedPrioritisedTask chunkDataUnloadTask = chunkUnloadTask == null ? null : chunkUnloadTask.task(); -+ if (chunkDataUnloadTask != null) { -+ final PrioritisedExecutor.PrioritisedTask unloadTask = chunkDataUnloadTask.getTask(); -+ if (unloadTask != null) { -+ executedUnloadTask = unloadTask.execute(); -+ } -+ } -+ } -+ -+ boolean canSaveChunk = !(chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave) && -+ (chunk != null && ((shutdown || chunk instanceof LevelChunk) && chunk.isUnsaved())); -+ boolean canSavePOI = !(chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave) && (poi != null && poi.isDirty()); -+ boolean canSaveEntities = entities != null; -+ -+ try (co.aikar.timings.Timing ignored = this.world.timings.chunkSave.startTiming()) { // Paper -+ if (canSaveChunk) { -+ canSaveChunk = this.saveChunk(chunk, unloading); -+ } -+ if (canSavePOI) { -+ canSavePOI = this.savePOI(poi, unloading); -+ } -+ if (canSaveEntities) { -+ // on shutdown, we need to force transient entity chunks to save -+ canSaveEntities = this.saveEntities(entities, unloading || shutdown); -+ if (unloading || shutdown) { -+ this.lastEntityUnload = null; -+ } -+ } -+ } -+ -+ return executedUnloadTask | canSaveChunk | canSaveEntities | canSavePOI ? new SaveStat(executedUnloadTask || canSaveChunk, canSaveEntities, canSavePOI): null; -+ } -+ -+ static final class AsyncChunkSerializeTask implements Runnable { -+ -+ private final ServerLevel world; -+ private final ChunkAccess chunk; -+ private final ChunkSerializer.AsyncSaveData asyncSaveData; -+ private final NewChunkHolder toComplete; -+ -+ public AsyncChunkSerializeTask(final ServerLevel world, final ChunkAccess chunk, final ChunkSerializer.AsyncSaveData asyncSaveData, -+ final NewChunkHolder toComplete) { -+ this.world = world; -+ this.chunk = chunk; -+ this.asyncSaveData = asyncSaveData; -+ this.toComplete = toComplete; -+ } -+ -+ @Override -+ public void run() { -+ final CompoundTag toSerialize; -+ try { -+ toSerialize = ChunkSerializer.saveChunk(this.world, this.chunk, this.asyncSaveData); -+ } catch (final ThreadDeath death) { -+ throw death; -+ } catch (final Throwable throwable) { -+ LOGGER.error("Failed to asynchronously save chunk " + this.chunk.getPos() + " for world '" + this.world.getWorld().getName() + "', falling back to synchronous save", throwable); -+ this.world.chunkTaskScheduler.scheduleChunkTask(this.chunk.locX, this.chunk.locZ, () -> { -+ final CompoundTag synchronousSave; -+ try { -+ synchronousSave = ChunkSerializer.saveChunk(AsyncChunkSerializeTask.this.world, AsyncChunkSerializeTask.this.chunk, AsyncChunkSerializeTask.this.asyncSaveData); -+ } catch (final ThreadDeath death) { -+ throw death; -+ } catch (final Throwable throwable2) { -+ LOGGER.error("Failed to synchronously save chunk " + AsyncChunkSerializeTask.this.chunk.getPos() + " for world '" + AsyncChunkSerializeTask.this.world.getWorld().getName() + "', chunk data will be lost", throwable2); -+ AsyncChunkSerializeTask.this.toComplete.completeAsyncChunkDataSave(null); -+ return; -+ } -+ -+ AsyncChunkSerializeTask.this.toComplete.completeAsyncChunkDataSave(synchronousSave); -+ LOGGER.info("Successfully serialized chunk " + AsyncChunkSerializeTask.this.chunk.getPos() + " for world '" + AsyncChunkSerializeTask.this.world.getWorld().getName() + "' synchronously"); -+ -+ }, PrioritisedExecutor.Priority.HIGHEST); -+ return; -+ } -+ this.toComplete.completeAsyncChunkDataSave(toSerialize); -+ } -+ -+ @Override -+ public String toString() { -+ return "AsyncChunkSerializeTask{" + -+ "chunk={pos=" + this.chunk.getPos() + ",world=\"" + this.world.getWorld().getName() + "\"}" + -+ "}"; -+ } -+ } -+ -+ private boolean saveChunk(final ChunkAccess chunk, final boolean unloading) { -+ if (!chunk.isUnsaved()) { -+ if (unloading) { -+ this.completeAsyncChunkDataSave(null); -+ } -+ return false; -+ } -+ boolean completing = false; -+ try { -+ if (unloading) { -+ try { -+ final ChunkSerializer.AsyncSaveData asyncSaveData = ChunkSerializer.getAsyncSaveData(this.world, chunk); -+ -+ final PrioritisedExecutor.PrioritisedTask task = this.scheduler.loadExecutor.createTask(new AsyncChunkSerializeTask(this.world, chunk, asyncSaveData, this)); -+ -+ this.chunkDataUnload.task().setTask(task); -+ -+ task.queue(); -+ -+ chunk.setUnsaved(false); -+ -+ return true; -+ } catch (final ThreadDeath death) { -+ throw death; -+ } catch (final Throwable thr) { -+ LOGGER.error("Failed to prepare async chunk data (" + this.chunkX + "," + this.chunkZ + ") in world '" + this.world.getWorld().getName() + "', falling back to synchronous save", thr); -+ // fall through to synchronous save -+ } -+ } -+ -+ final CompoundTag save = ChunkSerializer.saveChunk(this.world, chunk, null); -+ -+ if (unloading) { -+ completing = true; -+ this.completeAsyncChunkDataSave(save); -+ LOGGER.info("Successfully serialized chunk data (" + this.chunkX + "," + this.chunkZ + ") in world '" + this.world.getWorld().getName() + "' synchronously"); -+ } else { -+ RegionFileIOThread.scheduleSave(this.world, this.chunkX, this.chunkZ, save, RegionFileIOThread.RegionFileType.CHUNK_DATA); -+ } -+ chunk.setUnsaved(false); -+ } catch (final ThreadDeath death) { -+ throw death; -+ } catch (final Throwable thr) { -+ LOGGER.error("Failed to save chunk data (" + this.chunkX + "," + this.chunkZ + ") in world '" + this.world.getWorld().getName() + "'"); -+ if (unloading && !completing) { -+ this.completeAsyncChunkDataSave(null); -+ } -+ } -+ -+ return true; -+ } -+ -+ private boolean lastEntitySaveNull; -+ private CompoundTag lastEntityUnload; -+ private boolean saveEntities(final ChunkEntitySlices entities, final boolean unloading) { -+ try { -+ CompoundTag mergeFrom = null; -+ if (entities.isTransient()) { -+ if (!unloading) { -+ // if we're a transient chunk, we cannot save until unloading because otherwise a double save will -+ // result in double adding the entities -+ return false; -+ } -+ try { -+ mergeFrom = RegionFileIOThread.loadData(this.world, this.chunkX, this.chunkZ, RegionFileIOThread.RegionFileType.ENTITY_DATA, PrioritisedExecutor.Priority.BLOCKING); -+ } catch (final Exception ex) { -+ LOGGER.error("Cannot merge transient entities for chunk (" + this.chunkX + "," + this.chunkZ + ") in world '" + this.world.getWorld().getName() + "', data on disk will be replaced", ex); -+ } -+ } -+ -+ final CompoundTag save = entities.save(); -+ if (mergeFrom != null) { -+ if (save == null) { -+ // don't override the data on disk with nothing -+ return false; -+ } else { -+ EntityStorage.copyEntities(mergeFrom, save); -+ } -+ } -+ if (save == null && this.lastEntitySaveNull) { -+ return false; -+ } -+ -+ RegionFileIOThread.scheduleSave(this.world, this.chunkX, this.chunkZ, save, RegionFileIOThread.RegionFileType.ENTITY_DATA); -+ this.lastEntitySaveNull = save == null; -+ if (unloading) { -+ this.lastEntityUnload = save; -+ } -+ } catch (final ThreadDeath death) { -+ throw death; -+ } catch (final Throwable thr) { -+ LOGGER.error("Failed to save entity data (" + this.chunkX + "," + this.chunkZ + ") in world '" + this.world.getWorld().getName() + "'"); -+ } -+ -+ return true; -+ } -+ -+ private boolean lastPoiSaveNull; -+ private boolean savePOI(final PoiChunk poi, final boolean unloading) { -+ try { -+ final CompoundTag save = poi.save(); -+ poi.setDirty(false); -+ if (save == null && this.lastPoiSaveNull) { -+ if (unloading) { -+ this.poiDataUnload.completable().complete(null); -+ } -+ return false; -+ } -+ -+ RegionFileIOThread.scheduleSave(this.world, this.chunkX, this.chunkZ, save, RegionFileIOThread.RegionFileType.POI_DATA); -+ this.lastPoiSaveNull = save == null; -+ if (unloading) { -+ this.poiDataUnload.completable().complete(save); -+ } -+ } catch (final ThreadDeath death) { -+ throw death; -+ } catch (final Throwable thr) { -+ LOGGER.error("Failed to save poi data (" + this.chunkX + "," + this.chunkZ + ") in world '" + this.world.getWorld().getName() + "'"); -+ } -+ -+ return true; -+ } -+ -+ @Override -+ public String toString() { -+ final ChunkCompletion lastCompletion = this.lastChunkCompletion; -+ final ChunkEntitySlices entityChunk = this.entityChunk; -+ final long chunkStatus = this.chunkStatus; -+ final int fullChunkStatus = (int)chunkStatus; -+ final int pendingChunkStatus = (int)(chunkStatus >>> 32); -+ final FullChunkStatus currentFullStatus = fullChunkStatus < 0 || fullChunkStatus >= CHUNK_STATUS_BY_ID.length ? null : CHUNK_STATUS_BY_ID[fullChunkStatus]; -+ final FullChunkStatus pendingFullStatus = pendingChunkStatus < 0 || pendingChunkStatus >= CHUNK_STATUS_BY_ID.length ? null : CHUNK_STATUS_BY_ID[pendingChunkStatus]; -+ return "NewChunkHolder{" + -+ "world=" + this.world.getWorld().getName() + -+ ", chunkX=" + this.chunkX + -+ ", chunkZ=" + this.chunkZ + -+ ", entityChunkFromDisk=" + (entityChunk != null && !entityChunk.isTransient()) + -+ ", lastChunkCompletion={chunk_class=" + (lastCompletion == null || lastCompletion.chunk() == null ? "null" : lastCompletion.chunk().getClass().getName()) + ",status=" + (lastCompletion == null ? "null" : lastCompletion.genStatus()) + "}" + -+ ", currentGenStatus=" + this.currentGenStatus + -+ ", requestedGenStatus=" + this.requestedGenStatus + -+ ", generationTask=" + this.generationTask + -+ ", generationTaskStatus=" + this.generationTaskStatus + -+ ", priority=" + this.priority + -+ ", priorityLocked=" + this.priorityLocked + -+ ", neighbourRequestedPriority=" + this.neighbourRequestedPriority + -+ ", effective_priority=" + this.getEffectivePriority() + -+ ", oldTicketLevel=" + this.oldTicketLevel + -+ ", currentTicketLevel=" + this.currentTicketLevel + -+ ", totalNeighboursUsingThisChunk=" + this.totalNeighboursUsingThisChunk + -+ ", fullNeighbourChunksLoadedBitset=" + this.fullNeighbourChunksLoadedBitset + -+ ", chunkStatusRaw=" + chunkStatus + -+ ", currentChunkStatus=" + currentFullStatus + -+ ", pendingChunkStatus=" + pendingFullStatus + -+ ", is_unload_safe=" + this.isSafeToUnload() + -+ ", killed=" + this.killed + -+ '}'; -+ } -+ -+ private static JsonElement serializeCompletable(final Completable completable) { -+ if (completable == null) { -+ return new JsonPrimitive("null"); -+ } -+ -+ final JsonObject ret = new JsonObject(); -+ final boolean isCompleted = completable.isCompleted(); -+ ret.addProperty("completed", Boolean.valueOf(isCompleted)); -+ -+ if (isCompleted) { -+ ret.addProperty("completed_exceptionally", Boolean.valueOf(completable.getThrowable() != null)); -+ } -+ -+ return ret; -+ } -+ -+ // holds ticket and scheduling lock -+ public JsonObject getDebugJson() { -+ final JsonObject ret = new JsonObject(); -+ -+ final ChunkCompletion lastCompletion = this.lastChunkCompletion; -+ final ChunkEntitySlices slices = this.entityChunk; -+ final PoiChunk poiChunk = this.poiChunk; -+ -+ ret.addProperty("chunkX", Integer.valueOf(this.chunkX)); -+ ret.addProperty("chunkZ", Integer.valueOf(this.chunkZ)); -+ ret.addProperty("entity_chunk", slices == null ? "null" : "transient=" + slices.isTransient()); -+ ret.addProperty("poi_chunk", "null=" + (poiChunk == null)); -+ ret.addProperty("completed_chunk_class", lastCompletion == null ? "null" : lastCompletion.chunk().getClass().getName()); -+ ret.addProperty("completed_gen_status", lastCompletion == null ? "null" : lastCompletion.genStatus().toString()); -+ ret.addProperty("priority", Objects.toString(this.priority)); -+ ret.addProperty("neighbour_requested_priority", Objects.toString(this.neighbourRequestedPriority)); -+ ret.addProperty("generation_task", Objects.toString(this.generationTask)); -+ ret.addProperty("is_safe_unload", Objects.toString(this.isSafeToUnload())); -+ ret.addProperty("old_ticket_level", Integer.valueOf(this.oldTicketLevel)); -+ ret.addProperty("current_ticket_level", Integer.valueOf(this.currentTicketLevel)); -+ ret.addProperty("neighbours_using_chunk", Integer.valueOf(this.totalNeighboursUsingThisChunk)); -+ -+ final JsonObject neighbourWaitState = new JsonObject(); -+ ret.add("neighbour_state", neighbourWaitState); -+ -+ final JsonArray blockingGenNeighbours = new JsonArray(); -+ neighbourWaitState.add("blocking_gen_task", blockingGenNeighbours); -+ for (final NewChunkHolder blockingGenNeighbour : this.neighboursBlockingGenTask) { -+ final JsonObject neighbour = new JsonObject(); -+ blockingGenNeighbours.add(neighbour); -+ -+ neighbour.addProperty("chunkX", Integer.valueOf(blockingGenNeighbour.chunkX)); -+ neighbour.addProperty("chunkZ", Integer.valueOf(blockingGenNeighbour.chunkZ)); -+ } -+ -+ final JsonArray neighboursWaitingForUs = new JsonArray(); -+ neighbourWaitState.add("neighbours_waiting_on_us", neighboursWaitingForUs); -+ for (final Reference2ObjectMap.Entry entry : this.neighboursWaitingForUs.reference2ObjectEntrySet()) { -+ final NewChunkHolder holder = entry.getKey(); -+ final ChunkStatus status = entry.getValue(); -+ -+ final JsonObject neighbour = new JsonObject(); -+ neighboursWaitingForUs.add(neighbour); -+ -+ -+ neighbour.addProperty("chunkX", Integer.valueOf(holder.chunkX)); -+ neighbour.addProperty("chunkZ", Integer.valueOf(holder.chunkZ)); -+ neighbour.addProperty("waiting_for", Objects.toString(status)); -+ } -+ -+ ret.addProperty("fullchunkstatus", Objects.toString(this.getChunkStatus())); -+ ret.addProperty("fullchunkstatus_raw", Long.valueOf(this.chunkStatus)); -+ ret.addProperty("generation_task", Objects.toString(this.generationTask)); -+ ret.addProperty("requested_generation", Objects.toString(this.requestedGenStatus)); -+ ret.addProperty("has_entity_load_task", Boolean.valueOf(this.entityDataLoadTask != null)); -+ ret.addProperty("has_poi_load_task", Boolean.valueOf(this.poiDataLoadTask != null)); -+ -+ final UnloadTask entityDataUnload = this.entityDataUnload; -+ final UnloadTask poiDataUnload = this.poiDataUnload; -+ final UnloadTask chunkDataUnload = this.chunkDataUnload; -+ -+ ret.add("entity_unload_completable", serializeCompletable(entityDataUnload == null ? null : entityDataUnload.completable())); -+ ret.add("poi_unload_completable", serializeCompletable(poiDataUnload == null ? null : poiDataUnload.completable())); -+ ret.add("chunk_unload_completable", serializeCompletable(chunkDataUnload == null ? null : chunkDataUnload.completable())); -+ -+ final DelayedPrioritisedTask unloadTask = chunkDataUnload == null ? null : chunkDataUnload.task(); -+ if (unloadTask == null) { -+ ret.addProperty("unload_task_priority", "null"); -+ ret.addProperty("unload_task_priority_raw", "null"); -+ } else { -+ ret.addProperty("unload_task_priority", Objects.toString(unloadTask.getPriority())); -+ ret.addProperty("unload_task_priority_raw", Integer.valueOf(unloadTask.getPriorityInternal())); -+ } -+ -+ ret.addProperty("killed", Boolean.valueOf(this.killed)); -+ -+ return ret; -+ } -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/PriorityHolder.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/PriorityHolder.java -new file mode 100644 -index 0000000000000000000000000000000000000000..b4c56bf12dc8dd17452210ece4fd67411cc6b2fd ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/PriorityHolder.java -@@ -0,0 +1,215 @@ -+package io.papermc.paper.chunk.system.scheduling; -+ -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import java.lang.invoke.VarHandle; -+ -+public abstract class PriorityHolder { -+ -+ protected volatile int priority; -+ protected static final VarHandle PRIORITY_HANDLE = ConcurrentUtil.getVarHandle(PriorityHolder.class, "priority", int.class); -+ -+ protected static final int PRIORITY_SCHEDULED = Integer.MIN_VALUE >>> 0; -+ protected static final int PRIORITY_EXECUTED = Integer.MIN_VALUE >>> 1; -+ -+ protected final int getPriorityVolatile() { -+ return (int)PRIORITY_HANDLE.getVolatile((PriorityHolder)this); -+ } -+ -+ protected final int compareAndExchangePriorityVolatile(final int expect, final int update) { -+ return (int)PRIORITY_HANDLE.compareAndExchange((PriorityHolder)this, (int)expect, (int)update); -+ } -+ -+ protected final int getAndOrPriorityVolatile(final int val) { -+ return (int)PRIORITY_HANDLE.getAndBitwiseOr((PriorityHolder)this, (int)val); -+ } -+ -+ protected final void setPriorityPlain(final int val) { -+ PRIORITY_HANDLE.set((PriorityHolder)this, (int)val); -+ } -+ -+ protected PriorityHolder(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } -+ this.setPriorityPlain(priority.priority); -+ } -+ -+ // used only for debug json -+ public boolean isScheduled() { -+ return (this.getPriorityVolatile() & PRIORITY_SCHEDULED) != 0; -+ } -+ -+ // returns false if cancelled -+ protected boolean markExecuting() { -+ return (this.getAndOrPriorityVolatile(PRIORITY_EXECUTED) & PRIORITY_EXECUTED) == 0; -+ } -+ -+ protected boolean isMarkedExecuted() { -+ return (this.getPriorityVolatile() & PRIORITY_EXECUTED) != 0; -+ } -+ -+ public void cancel() { -+ if ((this.getAndOrPriorityVolatile(PRIORITY_EXECUTED) & PRIORITY_EXECUTED) != 0) { -+ // cancelled already -+ return; -+ } -+ this.cancelScheduled(); -+ } -+ -+ public void schedule() { -+ int priority = this.getPriorityVolatile(); -+ -+ if ((priority & PRIORITY_SCHEDULED) != 0) { -+ throw new IllegalStateException("schedule() called twice"); -+ } -+ -+ if ((priority & PRIORITY_EXECUTED) != 0) { -+ // cancelled -+ return; -+ } -+ -+ this.scheduleTask(PrioritisedExecutor.Priority.getPriority(priority)); -+ -+ int failures = 0; -+ for (;;) { -+ if (priority == (priority = this.compareAndExchangePriorityVolatile(priority, priority | PRIORITY_SCHEDULED))) { -+ return; -+ } -+ -+ if ((priority & PRIORITY_SCHEDULED) != 0) { -+ throw new IllegalStateException("schedule() called twice"); -+ } -+ -+ if ((priority & PRIORITY_EXECUTED) != 0) { -+ // cancelled or executed -+ return; -+ } -+ -+ this.setPriorityScheduled(PrioritisedExecutor.Priority.getPriority(priority)); -+ -+ ++failures; -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ } -+ } -+ -+ public final PrioritisedExecutor.Priority getPriority() { -+ final int ret = this.getPriorityVolatile(); -+ if ((ret & PRIORITY_EXECUTED) != 0) { -+ return PrioritisedExecutor.Priority.COMPLETING; -+ } -+ if ((ret & PRIORITY_SCHEDULED) != 0) { -+ return this.getScheduledPriority(); -+ } -+ return PrioritisedExecutor.Priority.getPriority(ret); -+ } -+ -+ public final 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_EXECUTED) != 0) { -+ return; -+ } -+ -+ if ((curr & PRIORITY_SCHEDULED) != 0) { -+ this.lowerPriorityScheduled(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 final 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_EXECUTED) != 0) { -+ return; -+ } -+ -+ if ((curr & PRIORITY_SCHEDULED) != 0) { -+ this.setPriorityScheduled(priority); -+ return; -+ } -+ -+ if (curr == (curr = this.compareAndExchangePriorityVolatile(curr, priority.priority))) { -+ return; -+ } -+ -+ // failed, retry -+ -+ ++failures; -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ } -+ } -+ -+ public final 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_EXECUTED) != 0) { -+ return; -+ } -+ -+ if ((curr & PRIORITY_SCHEDULED) != 0) { -+ this.raisePriorityScheduled(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(); -+ } -+ } -+ } -+ -+ protected abstract void cancelScheduled(); -+ -+ protected abstract PrioritisedExecutor.Priority getScheduledPriority(); -+ -+ protected abstract void scheduleTask(final PrioritisedExecutor.Priority priority); -+ -+ protected abstract void lowerPriorityScheduled(final PrioritisedExecutor.Priority priority); -+ -+ protected abstract void setPriorityScheduled(final PrioritisedExecutor.Priority priority); -+ -+ protected abstract void raisePriorityScheduled(final PrioritisedExecutor.Priority priority); -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ThreadedTicketLevelPropagator.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ThreadedTicketLevelPropagator.java -new file mode 100644 -index 0000000000000000000000000000000000000000..287240ed3b440f2f5733c368416e4276f626405d ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ThreadedTicketLevelPropagator.java -@@ -0,0 +1,1477 @@ -+package io.papermc.paper.chunk.system.scheduling; -+ -+import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; -+import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; -+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; -+import it.unimi.dsi.fastutil.HashCommon; -+import it.unimi.dsi.fastutil.longs.Long2ByteLinkedOpenHashMap; -+import it.unimi.dsi.fastutil.shorts.Short2ByteLinkedOpenHashMap; -+import it.unimi.dsi.fastutil.shorts.Short2ByteMap; -+import it.unimi.dsi.fastutil.shorts.ShortOpenHashSet; -+import java.lang.invoke.VarHandle; -+import java.util.ArrayDeque; -+import java.util.Arrays; -+import java.util.Iterator; -+import java.util.List; -+import java.util.concurrent.ConcurrentHashMap; -+import java.util.concurrent.locks.LockSupport; -+ -+public abstract class ThreadedTicketLevelPropagator { -+ -+ // sections are 64 in length -+ public static final int SECTION_SHIFT = 6; -+ public static final int SECTION_SIZE = 1 << SECTION_SHIFT; -+ private static final int LEVEL_BITS = SECTION_SHIFT; -+ private static final int LEVEL_COUNT = 1 << LEVEL_BITS; -+ private static final int MIN_SOURCE_LEVEL = 1; -+ // we limit the max source to 62 because the depropagation code _must_ attempt to depropagate -+ // a 1 level to 0; and if a source was 63 then it may cross more than 2 sections in depropagation -+ private static final int MAX_SOURCE_LEVEL = 62; -+ -+ private final UpdateQueue updateQueue; -+ private final ConcurrentHashMap sections = new ConcurrentHashMap<>(); -+ -+ public ThreadedTicketLevelPropagator() { -+ this.updateQueue = new UpdateQueue(); -+ } -+ -+ // must hold ticket lock for: -+ // (posX & ~(SECTION_SIZE - 1), posZ & ~(SECTION_SIZE - 1)) to (posX | (SECTION_SIZE - 1), posZ | (SECTION_SIZE - 1)) -+ public void setSource(final int posX, final int posZ, final int to) { -+ if (to < 1 || to > MAX_SOURCE_LEVEL) { -+ throw new IllegalArgumentException("Source: " + to); -+ } -+ -+ final int sectionX = posX >> SECTION_SHIFT; -+ final int sectionZ = posZ >> SECTION_SHIFT; -+ -+ final Coordinate coordinate = new Coordinate(sectionX, sectionZ); -+ Section section = this.sections.get(coordinate); -+ if (section == null) { -+ if (null != this.sections.putIfAbsent(coordinate, section = new Section(sectionX, sectionZ))) { -+ throw new IllegalStateException("Race condition while creating new section"); -+ } -+ } -+ -+ final int localIdx = (posX & (SECTION_SIZE - 1)) | ((posZ & (SECTION_SIZE - 1)) << SECTION_SHIFT); -+ final short sLocalIdx = (short)localIdx; -+ -+ final short sourceAndLevel = section.levels[localIdx]; -+ final int currentSource = (sourceAndLevel >>> 8) & 0xFF; -+ -+ if (currentSource == to) { -+ // nothing to do -+ // make sure to kill the current update, if any -+ section.queuedSources.replace(sLocalIdx, (byte)to); -+ return; -+ } -+ -+ if (section.queuedSources.put(sLocalIdx, (byte)to) == Section.NO_QUEUED_UPDATE && section.queuedSources.size() == 1) { -+ this.queueSectionUpdate(section); -+ } -+ } -+ -+ // must hold ticket lock for: -+ // (posX & ~(SECTION_SIZE - 1), posZ & ~(SECTION_SIZE - 1)) to (posX | (SECTION_SIZE - 1), posZ | (SECTION_SIZE - 1)) -+ public void removeSource(final int posX, final int posZ) { -+ final int sectionX = posX >> SECTION_SHIFT; -+ final int sectionZ = posZ >> SECTION_SHIFT; -+ -+ final Coordinate coordinate = new Coordinate(sectionX, sectionZ); -+ final Section section = this.sections.get(coordinate); -+ -+ if (section == null) { -+ return; -+ } -+ -+ final int localIdx = (posX & (SECTION_SIZE - 1)) | ((posZ & (SECTION_SIZE - 1)) << SECTION_SHIFT); -+ final short sLocalIdx = (short)localIdx; -+ -+ final int currentSource = (section.levels[localIdx] >>> 8) & 0xFF; -+ -+ if (currentSource == 0) { -+ // we use replace here so that we do not possibly multi-queue a section for an update -+ section.queuedSources.replace(sLocalIdx, (byte)0); -+ return; -+ } -+ -+ if (section.queuedSources.put(sLocalIdx, (byte)0) == Section.NO_QUEUED_UPDATE && section.queuedSources.size() == 1) { -+ this.queueSectionUpdate(section); -+ } -+ } -+ -+ private void queueSectionUpdate(final Section section) { -+ this.updateQueue.append(new UpdateQueue.UpdateQueueNode(section, null)); -+ } -+ -+ public boolean hasPendingUpdates() { -+ return !this.updateQueue.isEmpty(); -+ } -+ -+ // holds ticket lock for every chunk section represented by any position in the key set -+ // updates is modifiable and passed to processSchedulingUpdates after this call -+ protected abstract void processLevelUpdates(final Long2ByteLinkedOpenHashMap updates); -+ -+ // holds ticket lock for every chunk section represented by any position in the key set -+ // holds scheduling lock in max access radius for every position held by the ticket lock -+ // updates is cleared after this call -+ protected abstract void processSchedulingUpdates(final Long2ByteLinkedOpenHashMap updates, final List scheduledTasks, -+ final List changedFullStatus); -+ -+ // must hold ticket lock for every position in the sections in one radius around sectionX,sectionZ -+ public boolean performUpdate(final int sectionX, final int sectionZ, final ReentrantAreaLock schedulingLock, -+ final List scheduledTasks, final List changedFullStatus) { -+ if (!this.hasPendingUpdates()) { -+ return false; -+ } -+ -+ final Coordinate coordinate = new Coordinate(Coordinate.key(sectionX, sectionZ)); -+ final Section section = this.sections.get(coordinate); -+ -+ if (section == null || section.queuedSources.isEmpty()) { -+ // no section or no updates -+ return false; -+ } -+ -+ final Propagator propagator = Propagator.acquirePropagator(); -+ final boolean ret = this.performUpdate(section, null, propagator, -+ null, schedulingLock, scheduledTasks, changedFullStatus -+ ); -+ Propagator.returnPropagator(propagator); -+ return ret; -+ } -+ -+ private boolean performUpdate(final Section section, final UpdateQueue.UpdateQueueNode node, final Propagator propagator, -+ final ReentrantAreaLock ticketLock, final ReentrantAreaLock schedulingLock, -+ final List scheduledTasks, final List changedFullStatus) { -+ final int sectionX = section.sectionX; -+ final int sectionZ = section.sectionZ; -+ -+ final int rad1MinX = (sectionX - 1) << SECTION_SHIFT; -+ final int rad1MinZ = (sectionZ - 1) << SECTION_SHIFT; -+ final int rad1MaxX = ((sectionX + 1) << SECTION_SHIFT) | (SECTION_SIZE - 1); -+ final int rad1MaxZ = ((sectionZ + 1) << SECTION_SHIFT) | (SECTION_SIZE - 1); -+ -+ // set up encode offset first as we need to queue level changes _before_ -+ propagator.setupEncodeOffset(sectionX, sectionZ); -+ -+ final int coordinateOffset = propagator.coordinateOffset; -+ -+ final ReentrantAreaLock.Node ticketNode = ticketLock == null ? null : ticketLock.lock(rad1MinX, rad1MinZ, rad1MaxX, rad1MaxZ); -+ final boolean ret; -+ try { -+ // first, check if this update was stolen -+ if (section != this.sections.get(new Coordinate(sectionX, sectionZ))) { -+ // occurs when a stolen update deletes this section -+ // it is possible that another update is scheduled, but that one will have the correct section -+ if (node != null) { -+ this.updateQueue.remove(node); -+ } -+ return false; -+ } -+ -+ final int oldSourceSize = section.sources.size(); -+ -+ // process pending sources -+ for (final Iterator iterator = section.queuedSources.short2ByteEntrySet().fastIterator(); iterator.hasNext();) { -+ final Short2ByteMap.Entry entry = iterator.next(); -+ final int pos = (int)entry.getShortKey(); -+ final int posX = (pos & (SECTION_SIZE - 1)) | (sectionX << SECTION_SHIFT); -+ final int posZ = ((pos >> SECTION_SHIFT) & (SECTION_SIZE - 1)) | (sectionZ << SECTION_SHIFT); -+ final int newSource = (int)entry.getByteValue(); -+ -+ final short currentEncoded = section.levels[pos]; -+ final int currLevel = currentEncoded & 0xFF; -+ final int prevSource = (currentEncoded >>> 8) & 0xFF; -+ -+ if (prevSource == newSource) { -+ // nothing changed -+ continue; -+ } -+ -+ if ((prevSource < currLevel && newSource <= currLevel) || newSource == currLevel) { -+ // just update the source, don't need to propagate change -+ section.levels[pos] = (short)(currLevel | (newSource << 8)); -+ // level is unchanged, don't add to changed positions -+ } else { -+ // set current level and current source to new source -+ section.levels[pos] = (short)(newSource | (newSource << 8)); -+ // must add to updated positions in case this is final -+ propagator.updatedPositions.put(Coordinate.key(posX, posZ), (byte)newSource); -+ if (newSource != 0) { -+ // queue increase with new source level -+ propagator.appendToIncreaseQueue( -+ ((long)(posX + (posZ << Propagator.COORDINATE_BITS) + coordinateOffset) & ((1L << (Propagator.COORDINATE_BITS + Propagator.COORDINATE_BITS)) - 1)) | -+ ((newSource & (LEVEL_COUNT - 1L)) << (Propagator.COORDINATE_BITS + Propagator.COORDINATE_BITS)) | -+ (Propagator.ALL_DIRECTIONS_BITSET << (Propagator.COORDINATE_BITS + Propagator.COORDINATE_BITS + LEVEL_BITS)) -+ ); -+ } -+ // queue decrease with previous level -+ if (newSource < currLevel) { -+ propagator.appendToDecreaseQueue( -+ ((long)(posX + (posZ << Propagator.COORDINATE_BITS) + coordinateOffset) & ((1L << (Propagator.COORDINATE_BITS + Propagator.COORDINATE_BITS)) - 1)) | -+ ((currLevel & (LEVEL_COUNT - 1L)) << (Propagator.COORDINATE_BITS + Propagator.COORDINATE_BITS)) | -+ (Propagator.ALL_DIRECTIONS_BITSET << (Propagator.COORDINATE_BITS + Propagator.COORDINATE_BITS + LEVEL_BITS)) -+ ); -+ } -+ } -+ -+ if (newSource == 0) { -+ // prevSource != newSource, so we are removing this source -+ section.sources.remove((short)pos); -+ } else if (prevSource == 0) { -+ // prevSource != newSource, so we are adding this source -+ section.sources.add((short)pos); -+ } -+ } -+ -+ section.queuedSources.clear(); -+ -+ final int newSourceSize = section.sources.size(); -+ -+ if (oldSourceSize == 0 && newSourceSize != 0) { -+ // need to make sure the sections in 1 radius are initialised -+ for (int dz = -1; dz <= 1; ++dz) { -+ for (int dx = -1; dx <= 1; ++dx) { -+ if ((dx | dz) == 0) { -+ continue; -+ } -+ final int offX = dx + sectionX; -+ final int offZ = dz + sectionZ; -+ final Coordinate coordinate = new Coordinate(offX, offZ); -+ final Section neighbour = this.sections.computeIfAbsent(coordinate, (final Coordinate keyInMap) -> { -+ return new Section(Coordinate.x(keyInMap.key), Coordinate.z(keyInMap.key)); -+ }); -+ -+ // increase ref count -+ ++neighbour.oneRadNeighboursWithSources; -+ if (neighbour.oneRadNeighboursWithSources <= 0 || neighbour.oneRadNeighboursWithSources > 8) { -+ throw new IllegalStateException(Integer.toString(neighbour.oneRadNeighboursWithSources)); -+ } -+ } -+ } -+ } -+ -+ if (propagator.hasUpdates()) { -+ propagator.setupCaches(this, sectionX, sectionZ, 1); -+ propagator.performDecrease(); -+ // don't need try-finally, as any exception will cause the propagator to not be returned -+ propagator.destroyCaches(); -+ } -+ -+ if (newSourceSize == 0) { -+ final boolean decrementRef = oldSourceSize != 0; -+ // check for section de-init -+ for (int dz = -1; dz <= 1; ++dz) { -+ for (int dx = -1; dx <= 1; ++dx) { -+ final int offX = dx + sectionX; -+ final int offZ = dz + sectionZ; -+ final Coordinate coordinate = new Coordinate(offX, offZ); -+ final Section neighbour = this.sections.get(coordinate); -+ -+ if (neighbour == null) { -+ if (oldSourceSize == 0 && (dx | dz) != 0) { -+ // since we don't have sources, this section is allowed to null -+ continue; -+ } -+ throw new IllegalStateException("??"); -+ } -+ -+ if (decrementRef && (dx | dz) != 0) { -+ // decrease ref count, but only for neighbours -+ --neighbour.oneRadNeighboursWithSources; -+ } -+ -+ // we need to check the current section for de-init as well -+ if (neighbour.oneRadNeighboursWithSources == 0) { -+ if (neighbour.queuedSources.isEmpty() && neighbour.sources.isEmpty()) { -+ // need to de-init -+ this.sections.remove(coordinate); -+ } // else: neighbour is queued for an update, and it will de-init itself -+ } else if (neighbour.oneRadNeighboursWithSources < 0 || neighbour.oneRadNeighboursWithSources > 8) { -+ throw new IllegalStateException(Integer.toString(neighbour.oneRadNeighboursWithSources)); -+ } -+ } -+ } -+ } -+ -+ -+ ret = !propagator.updatedPositions.isEmpty(); -+ -+ if (ret) { -+ this.processLevelUpdates(propagator.updatedPositions); -+ -+ if (!propagator.updatedPositions.isEmpty()) { -+ // now we can actually update the ticket levels in the chunk holders -+ final int maxScheduleRadius = 2 * ChunkTaskScheduler.getMaxAccessRadius(); -+ -+ // allow the chunkholders to process ticket level updates without needing to acquire the schedule lock every time -+ final ReentrantAreaLock.Node schedulingNode = schedulingLock.lock( -+ rad1MinX - maxScheduleRadius, rad1MinZ - maxScheduleRadius, -+ rad1MaxX + maxScheduleRadius, rad1MaxZ + maxScheduleRadius -+ ); -+ try { -+ this.processSchedulingUpdates(propagator.updatedPositions, scheduledTasks, changedFullStatus); -+ } finally { -+ schedulingLock.unlock(schedulingNode); -+ } -+ } -+ -+ propagator.updatedPositions.clear(); -+ } -+ } finally { -+ if (ticketLock != null) { -+ ticketLock.unlock(ticketNode); -+ } -+ } -+ -+ // finished -+ if (node != null) { -+ this.updateQueue.remove(node); -+ } -+ -+ return ret; -+ } -+ -+ public boolean performUpdates(final ReentrantAreaLock ticketLock, final ReentrantAreaLock schedulingLock, -+ final List scheduledTasks, final List changedFullStatus) { -+ if (this.updateQueue.isEmpty()) { -+ return false; -+ } -+ -+ final long maxOrder = this.updateQueue.getLastOrder(); -+ -+ boolean updated = false; -+ Propagator propagator = null; -+ -+ for (;;) { -+ final UpdateQueue.UpdateQueueNode toUpdate = this.updateQueue.acquireNextToUpdate(maxOrder); -+ if (toUpdate == null) { -+ this.updateQueue.awaitFirst(maxOrder); -+ -+ if (!this.updateQueue.hasRemainingUpdates(maxOrder)) { -+ if (propagator != null) { -+ Propagator.returnPropagator(propagator); -+ } -+ return updated; -+ } -+ -+ continue; -+ } -+ -+ if (propagator == null) { -+ propagator = Propagator.acquirePropagator(); -+ } -+ -+ updated |= this.performUpdate(toUpdate.section, toUpdate, propagator, ticketLock, schedulingLock, scheduledTasks, changedFullStatus); -+ } -+ } -+ -+ private static final class UpdateQueue { -+ -+ private volatile UpdateQueueNode head; -+ private volatile UpdateQueueNode tail; -+ private volatile UpdateQueueNode lastUpdating; -+ -+ protected static final VarHandle HEAD_HANDLE = ConcurrentUtil.getVarHandle(UpdateQueue.class, "head", UpdateQueueNode.class); -+ protected static final VarHandle TAIL_HANDLE = ConcurrentUtil.getVarHandle(UpdateQueue.class, "tail", UpdateQueueNode.class); -+ protected static final VarHandle LAST_UPDATING = ConcurrentUtil.getVarHandle(UpdateQueue.class, "lastUpdating", UpdateQueueNode.class); -+ -+ /* head */ -+ -+ protected final void setHeadPlain(final UpdateQueueNode newHead) { -+ HEAD_HANDLE.set(this, newHead); -+ } -+ -+ protected final void setHeadOpaque(final UpdateQueueNode newHead) { -+ HEAD_HANDLE.setOpaque(this, newHead); -+ } -+ -+ protected final UpdateQueueNode getHeadPlain() { -+ return (UpdateQueueNode)HEAD_HANDLE.get(this); -+ } -+ -+ protected final UpdateQueueNode getHeadOpaque() { -+ return (UpdateQueueNode)HEAD_HANDLE.getOpaque(this); -+ } -+ -+ protected final UpdateQueueNode getHeadAcquire() { -+ return (UpdateQueueNode)HEAD_HANDLE.getAcquire(this); -+ } -+ -+ /* tail */ -+ -+ protected final void setTailPlain(final UpdateQueueNode newTail) { -+ TAIL_HANDLE.set(this, newTail); -+ } -+ -+ protected final void setTailOpaque(final UpdateQueueNode newTail) { -+ TAIL_HANDLE.setOpaque(this, newTail); -+ } -+ -+ protected final UpdateQueueNode getTailPlain() { -+ return (UpdateQueueNode)TAIL_HANDLE.get(this); -+ } -+ -+ protected final UpdateQueueNode getTailOpaque() { -+ return (UpdateQueueNode)TAIL_HANDLE.getOpaque(this); -+ } -+ -+ /* lastUpdating */ -+ -+ protected final UpdateQueueNode getLastUpdatingVolatile() { -+ return (UpdateQueueNode)LAST_UPDATING.getVolatile(this); -+ } -+ -+ protected final UpdateQueueNode compareAndExchangeLastUpdatingVolatile(final UpdateQueueNode expect, final UpdateQueueNode update) { -+ return (UpdateQueueNode)LAST_UPDATING.compareAndExchange(this, expect, update); -+ } -+ -+ public UpdateQueue() { -+ final UpdateQueueNode dummy = new UpdateQueueNode(null, null); -+ dummy.order = -1L; -+ dummy.preventAdds(); -+ -+ this.setHeadPlain(dummy); -+ this.setTailPlain(dummy); -+ } -+ -+ public boolean isEmpty() { -+ return this.peek() == null; -+ } -+ -+ public boolean hasRemainingUpdates(final long maxUpdate) { -+ final UpdateQueueNode node = this.peek(); -+ return node != null && node.order <= maxUpdate; -+ } -+ -+ public long getLastOrder() { -+ for (UpdateQueueNode tail = this.getTailOpaque(), curr = tail;;) { -+ final UpdateQueueNode next = curr.getNextVolatile(); -+ if (next == null) { -+ // try to update stale tail -+ if (this.getTailOpaque() == tail && curr != tail) { -+ this.setTailOpaque(curr); -+ } -+ return curr.order; -+ } -+ curr = next; -+ } -+ } -+ -+ public UpdateQueueNode acquireNextToUpdate(final long maxOrder) { -+ int failures = 0; -+ for (UpdateQueueNode prev = this.getLastUpdatingVolatile();;) { -+ UpdateQueueNode next = prev == null ? this.peek() : prev.next; -+ -+ if (next == null || next.order > maxOrder) { -+ return null; -+ } -+ -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ -+ if (prev == (prev = this.compareAndExchangeLastUpdatingVolatile(prev, next))) { -+ return next; -+ } -+ -+ ++failures; -+ } -+ } -+ -+ public void awaitFirst(final long maxOrder) { -+ final UpdateQueueNode earliest = this.peek(); -+ if (earliest == null || earliest.order > maxOrder) { -+ return; -+ } -+ -+ final Thread currThread = Thread.currentThread(); -+ // we do not use add-blocking because we use the nullability of the section to block -+ // remove() does not begin to poll from the wait queue until the section is null'd, -+ // and so provided we check the nullability before parking there is no ordering of these operations -+ // such that remove() finishes polling from the wait queue while section is not null -+ earliest.add(currThread); -+ -+ // wait until completed -+ while (earliest.getSectionVolatile() != null) { -+ LockSupport.park(); -+ } -+ } -+ -+ public UpdateQueueNode peek() { -+ for (UpdateQueueNode head = this.getHeadOpaque(), curr = head;;) { -+ final UpdateQueueNode next = curr.getNextVolatile(); -+ final Section element = curr.getSectionVolatile(); /* Likely in sync */ -+ -+ if (element != null) { -+ if (this.getHeadOpaque() == head && curr != head) { -+ this.setHeadOpaque(curr); -+ } -+ return curr; -+ } -+ -+ if (next == null) { -+ if (this.getHeadOpaque() == head && curr != head) { -+ this.setHeadOpaque(curr); -+ } -+ return null; -+ } -+ curr = next; -+ } -+ } -+ -+ public void remove(final UpdateQueueNode node) { -+ // mark as removed -+ node.setSectionVolatile(null); -+ -+ // use peek to advance head -+ this.peek(); -+ -+ // unpark any waiters / block the wait queue -+ Thread unpark; -+ while ((unpark = node.poll()) != null) { -+ LockSupport.unpark(unpark); -+ } -+ } -+ -+ public void append(final UpdateQueueNode node) { -+ int failures = 0; -+ -+ for (UpdateQueueNode 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 UpdateQueueNode next = curr.getNextVolatile(); -+ -+ for (int i = 0; i < failures; ++i) { -+ ConcurrentUtil.backoff(); -+ } -+ -+ if (next == null) { -+ node.order = curr.order + 1L; -+ final UpdateQueueNode compared = curr.compareExchangeNextVolatile(null, node); -+ -+ 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(node); -+ } -+ return; -+ } -+ -+ ++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; -+ } -+ } -+ } -+ } -+ -+ // each node also represents a set of waiters, represented by the MTQ -+ // if the queue is add-blocked, then the update is complete -+ private static final class UpdateQueueNode extends MultiThreadedQueue { -+ private long order; -+ private Section section; -+ private volatile UpdateQueueNode next; -+ -+ protected static final VarHandle SECTION_HANDLE = ConcurrentUtil.getVarHandle(UpdateQueueNode.class, "section", Section.class); -+ protected static final VarHandle NEXT_HANDLE = ConcurrentUtil.getVarHandle(UpdateQueueNode.class, "next", UpdateQueueNode.class); -+ -+ public UpdateQueueNode(final Section section, final UpdateQueueNode next) { -+ SECTION_HANDLE.set(this, section); -+ NEXT_HANDLE.set(this, next); -+ } -+ -+ /* section */ -+ -+ protected final Section getSectionPlain() { -+ return (Section)SECTION_HANDLE.get(this); -+ } -+ -+ protected final Section getSectionVolatile() { -+ return (Section)SECTION_HANDLE.getVolatile(this); -+ } -+ -+ protected final void setSectionPlain(final Section update) { -+ SECTION_HANDLE.set(this, update); -+ } -+ -+ protected final void setSectionOpaque(final Section update) { -+ SECTION_HANDLE.setOpaque(this, update); -+ } -+ -+ protected final void setSectionVolatile(final Section update) { -+ SECTION_HANDLE.setVolatile(this, update); -+ } -+ -+ protected final Section getAndSetSectionVolatile(final Section update) { -+ return (Section)SECTION_HANDLE.getAndSet(this, update); -+ } -+ -+ protected final Section compareExchangeSectionVolatile(final Section expect, final Section update) { -+ return (Section)SECTION_HANDLE.compareAndExchange(this, expect, update); -+ } -+ -+ /* next */ -+ -+ protected final UpdateQueueNode getNextPlain() { -+ return (UpdateQueueNode)NEXT_HANDLE.get(this); -+ } -+ -+ protected final UpdateQueueNode getNextOpaque() { -+ return (UpdateQueueNode)NEXT_HANDLE.getOpaque(this); -+ } -+ -+ protected final UpdateQueueNode getNextAcquire() { -+ return (UpdateQueueNode)NEXT_HANDLE.getAcquire(this); -+ } -+ -+ protected final UpdateQueueNode getNextVolatile() { -+ return (UpdateQueueNode)NEXT_HANDLE.getVolatile(this); -+ } -+ -+ protected final void setNextPlain(final UpdateQueueNode next) { -+ NEXT_HANDLE.set(this, next); -+ } -+ -+ protected final void setNextVolatile(final UpdateQueueNode next) { -+ NEXT_HANDLE.setVolatile(this, next); -+ } -+ -+ protected final UpdateQueueNode compareExchangeNextVolatile(final UpdateQueueNode expect, final UpdateQueueNode set) { -+ return (UpdateQueueNode)NEXT_HANDLE.compareAndExchange(this, expect, set); -+ } -+ } -+ } -+ -+ private static final class Section { -+ -+ // upper 8 bits: sources, lower 8 bits: level -+ // if we REALLY wanted to get crazy, we could make the increase propagator use MethodHandles#byteArrayViewVarHandle -+ // to read and write the lower 8 bits of this array directly rather than reading, updating the bits, then writing back. -+ private final short[] levels = new short[SECTION_SIZE * SECTION_SIZE]; -+ // set of local positions that represent sources -+ private final ShortOpenHashSet sources = new ShortOpenHashSet(); -+ // map of local index to new source level -+ // the source level _cannot_ be updated in the backing storage immediately since the update -+ private static final byte NO_QUEUED_UPDATE = (byte)-1; -+ private final Short2ByteLinkedOpenHashMap queuedSources = new Short2ByteLinkedOpenHashMap(); -+ { -+ this.queuedSources.defaultReturnValue(NO_QUEUED_UPDATE); -+ } -+ private int oneRadNeighboursWithSources = 0; -+ -+ public final int sectionX; -+ public final int sectionZ; -+ -+ public Section(final int sectionX, final int sectionZ) { -+ this.sectionX = sectionX; -+ this.sectionZ = sectionZ; -+ } -+ -+ public boolean isZero() { -+ for (final short val : this.levels) { -+ if (val != 0) { -+ return false; -+ } -+ } -+ return true; -+ } -+ -+ @Override -+ public String toString() { -+ final StringBuilder ret = new StringBuilder(); -+ -+ for (int x = 0; x < SECTION_SIZE; ++x) { -+ ret.append("levels x=").append(x).append("\n"); -+ for (int z = 0; z < SECTION_SIZE; ++z) { -+ final short v = this.levels[x | (z << SECTION_SHIFT)]; -+ ret.append(v & 0xFF).append("."); -+ } -+ ret.append("\n"); -+ ret.append("sources x=").append(x).append("\n"); -+ for (int z = 0; z < SECTION_SIZE; ++z) { -+ final short v = this.levels[x | (z << SECTION_SHIFT)]; -+ ret.append((v >>> 8) & 0xFF).append("."); -+ } -+ ret.append("\n\n"); -+ } -+ -+ return ret.toString(); -+ } -+ } -+ -+ -+ private static final class Propagator { -+ -+ private static final ArrayDeque CACHED_PROPAGATORS = new ArrayDeque<>(); -+ private static final int MAX_PROPAGATORS = Runtime.getRuntime().availableProcessors() * 2; -+ -+ private static Propagator acquirePropagator() { -+ synchronized (CACHED_PROPAGATORS) { -+ final Propagator ret = CACHED_PROPAGATORS.pollFirst(); -+ if (ret != null) { -+ return ret; -+ } -+ } -+ return new Propagator(); -+ } -+ -+ private static void returnPropagator(final Propagator propagator) { -+ synchronized (CACHED_PROPAGATORS) { -+ if (CACHED_PROPAGATORS.size() < MAX_PROPAGATORS) { -+ CACHED_PROPAGATORS.add(propagator); -+ } -+ } -+ } -+ -+ private static final int SECTION_RADIUS = 2; -+ private static final int SECTION_CACHE_WIDTH = 2 * SECTION_RADIUS + 1; -+ // minimum number of bits to represent [0, SECTION_SIZE * SECTION_CACHE_WIDTH) -+ private static final int COORDINATE_BITS = 9; -+ private static final int COORDINATE_SIZE = 1 << COORDINATE_BITS; -+ static { -+ if ((SECTION_SIZE * SECTION_CACHE_WIDTH) > (1 << COORDINATE_BITS)) { -+ throw new IllegalStateException("Adjust COORDINATE_BITS"); -+ } -+ } -+ // index = x + (z * SECTION_CACHE_WIDTH) -+ // (this requires x >= 0 and z >= 0) -+ private final Section[] sections = new Section[SECTION_CACHE_WIDTH * SECTION_CACHE_WIDTH]; -+ -+ private int encodeOffsetX; -+ private int encodeOffsetZ; -+ -+ private int coordinateOffset; -+ -+ private int encodeSectionOffsetX; -+ private int encodeSectionOffsetZ; -+ -+ private int sectionIndexOffset; -+ -+ public final boolean hasUpdates() { -+ return this.decreaseQueueInitialLength != 0 || this.increaseQueueInitialLength != 0; -+ } -+ -+ protected final void setupEncodeOffset(final int centerSectionX, final int centerSectionZ) { -+ final int maxCoordinate = (SECTION_RADIUS * SECTION_SIZE - 1); -+ // must have that encoded >= 0 -+ // coordinates can range from [-maxCoordinate + centerSection*SECTION_SIZE, maxCoordinate + centerSection*SECTION_SIZE] -+ // we want a range of [0, maxCoordinate*2] -+ // so, 0 = -maxCoordinate + centerSection*SECTION_SIZE + offset -+ this.encodeOffsetX = maxCoordinate - (centerSectionX << SECTION_SHIFT); -+ this.encodeOffsetZ = maxCoordinate - (centerSectionZ << SECTION_SHIFT); -+ -+ // encoded coordinates range from [0, SECTION_SIZE * SECTION_CACHE_WIDTH) -+ // coordinate index = (x + encodeOffsetX) + ((z + encodeOffsetZ) << COORDINATE_BITS) -+ this.coordinateOffset = this.encodeOffsetX + (this.encodeOffsetZ << COORDINATE_BITS); -+ -+ // need encoded values to be >= 0 -+ // so, 0 = (-SECTION_RADIUS + centerSectionX) + encodeOffset -+ this.encodeSectionOffsetX = SECTION_RADIUS - centerSectionX; -+ this.encodeSectionOffsetZ = SECTION_RADIUS - centerSectionZ; -+ -+ // section index = (secX + encodeSectionOffsetX) + ((secZ + encodeSectionOffsetZ) * SECTION_CACHE_WIDTH) -+ this.sectionIndexOffset = this.encodeSectionOffsetX + (this.encodeSectionOffsetZ * SECTION_CACHE_WIDTH); -+ } -+ -+ // must hold ticket lock for (centerSectionX,centerSectionZ) in radius rad -+ // must call setupEncodeOffset -+ protected final void setupCaches(final ThreadedTicketLevelPropagator propagator, -+ final int centerSectionX, final int centerSectionZ, -+ final int rad) { -+ for (int dz = -rad; dz <= rad; ++dz) { -+ for (int dx = -rad; dx <= rad; ++dx) { -+ final int sectionX = centerSectionX + dx; -+ final int sectionZ = centerSectionZ + dz; -+ final Coordinate coordinate = new Coordinate(sectionX, sectionZ); -+ final Section section = propagator.sections.get(coordinate); -+ -+ if (section == null) { -+ throw new IllegalStateException("Section at " + coordinate + " should not be null"); -+ } -+ -+ this.setSectionInCache(sectionX, sectionZ, section); -+ } -+ } -+ } -+ -+ protected final void setSectionInCache(final int sectionX, final int sectionZ, final Section section) { -+ this.sections[sectionX + SECTION_CACHE_WIDTH*sectionZ + this.sectionIndexOffset] = section; -+ } -+ -+ protected final Section getSection(final int sectionX, final int sectionZ) { -+ return this.sections[sectionX + SECTION_CACHE_WIDTH*sectionZ + this.sectionIndexOffset]; -+ } -+ -+ protected final int getLevel(final int posX, final int posZ) { -+ final Section section = this.sections[(posX >> SECTION_SHIFT) + SECTION_CACHE_WIDTH*(posZ >> SECTION_SHIFT) + this.sectionIndexOffset]; -+ if (section != null) { -+ return (int)section.levels[(posX & (SECTION_SIZE - 1)) | ((posZ & (SECTION_SIZE - 1)) << SECTION_SHIFT)] & 0xFF; -+ } -+ -+ return 0; -+ } -+ -+ protected final void setLevel(final int posX, final int posZ, final int to) { -+ final Section section = this.sections[(posX >> SECTION_SHIFT) + SECTION_CACHE_WIDTH*(posZ >> SECTION_SHIFT) + this.sectionIndexOffset]; -+ if (section != null) { -+ final int index = (posX & (SECTION_SIZE - 1)) | ((posZ & (SECTION_SIZE - 1)) << SECTION_SHIFT); -+ final short level = section.levels[index]; -+ section.levels[index] = (short)((level & ~0xFF) | (to & 0xFF)); -+ this.updatedPositions.put(Coordinate.key(posX, posZ), (byte)to); -+ } -+ } -+ -+ protected final void destroyCaches() { -+ Arrays.fill(this.sections, null); -+ } -+ -+ // contains: -+ // lower (COORDINATE_BITS(9) + COORDINATE_BITS(9) = 18) bits encoded position: (x | (z << COORDINATE_BITS)) -+ // next LEVEL_BITS (6) bits: propagated level [0, 63] -+ // propagation directions bitset (16 bits): -+ protected static final long ALL_DIRECTIONS_BITSET = ( -+ // z = -1 -+ (1L << ((1 - 1) | ((1 - 1) << 2))) | -+ (1L << ((1 + 0) | ((1 - 1) << 2))) | -+ (1L << ((1 + 1) | ((1 - 1) << 2))) | -+ -+ // z = 0 -+ (1L << ((1 - 1) | ((1 + 0) << 2))) | -+ //(1L << ((1 + 0) | ((1 + 0) << 2))) | // exclude (0,0) -+ (1L << ((1 + 1) | ((1 + 0) << 2))) | -+ -+ // z = 1 -+ (1L << ((1 - 1) | ((1 + 1) << 2))) | -+ (1L << ((1 + 0) | ((1 + 1) << 2))) | -+ (1L << ((1 + 1) | ((1 + 1) << 2))) -+ ); -+ -+ private void ex(int bitset) { -+ for (int i = 0, len = Integer.bitCount(bitset); i < len; ++i) { -+ final int set = Integer.numberOfTrailingZeros(bitset); -+ final int tailingBit = (-bitset) & bitset; -+ // XOR to remove the trailing bit -+ bitset ^= tailingBit; -+ -+ // the encoded value set is (x_val) | (z_val << 2), totaling 4 bits -+ // thus, the bitset is 16 bits wide where each one represents a direction to propagate and the -+ // index of the set bit is the encoded value -+ // the encoded coordinate has 3 valid states: -+ // 0b00 (0) -> -1 -+ // 0b01 (1) -> 0 -+ // 0b10 (2) -> 1 -+ // the decode operation then is val - 1, and the encode operation is val + 1 -+ final int xOff = (set & 3) - 1; -+ final int zOff = ((set >>> 2) & 3) - 1; -+ System.out.println("Encoded: (" + xOff + "," + zOff + ")"); -+ } -+ } -+ -+ private void ch(long bs, int shift) { -+ int bitset = (int)(bs >>> shift); -+ for (int i = 0, len = Integer.bitCount(bitset); i < len; ++i) { -+ final int set = Integer.numberOfTrailingZeros(bitset); -+ final int tailingBit = (-bitset) & bitset; -+ // XOR to remove the trailing bit -+ bitset ^= tailingBit; -+ -+ // the encoded value set is (x_val) | (z_val << 2), totaling 4 bits -+ // thus, the bitset is 16 bits wide where each one represents a direction to propagate and the -+ // index of the set bit is the encoded value -+ // the encoded coordinate has 3 valid states: -+ // 0b00 (0) -> -1 -+ // 0b01 (1) -> 0 -+ // 0b10 (2) -> 1 -+ // the decode operation then is val - 1, and the encode operation is val + 1 -+ final int xOff = (set & 3) - 1; -+ final int zOff = ((set >>> 2) & 3) - 1; -+ if (Math.abs(xOff) > 1 || Math.abs(zOff) > 1 || (xOff | zOff) == 0) { -+ throw new IllegalStateException(); -+ } -+ } -+ } -+ -+ // whether the increase propagator needs to write the propagated level to the position, used to avoid cascading -+ // updates for sources -+ protected static final long FLAG_WRITE_LEVEL = Long.MIN_VALUE >>> 1; -+ // whether the propagation needs to check if its current level is equal to the expected level -+ // used only in increase propagation -+ protected static final long FLAG_RECHECK_LEVEL = Long.MIN_VALUE >>> 0; -+ -+ protected long[] increaseQueue = new long[SECTION_SIZE * SECTION_SIZE * 2]; -+ protected int increaseQueueInitialLength; -+ protected long[] decreaseQueue = new long[SECTION_SIZE * SECTION_SIZE * 2]; -+ protected int decreaseQueueInitialLength; -+ -+ protected final Long2ByteLinkedOpenHashMap updatedPositions = new Long2ByteLinkedOpenHashMap(); -+ -+ protected final long[] resizeIncreaseQueue() { -+ return this.increaseQueue = Arrays.copyOf(this.increaseQueue, this.increaseQueue.length * 2); -+ } -+ -+ protected final long[] resizeDecreaseQueue() { -+ return this.decreaseQueue = Arrays.copyOf(this.decreaseQueue, this.decreaseQueue.length * 2); -+ } -+ -+ protected final void appendToIncreaseQueue(final long value) { -+ final int idx = this.increaseQueueInitialLength++; -+ long[] queue = this.increaseQueue; -+ if (idx >= queue.length) { -+ queue = this.resizeIncreaseQueue(); -+ queue[idx] = value; -+ return; -+ } else { -+ queue[idx] = value; -+ return; -+ } -+ } -+ -+ protected final void appendToDecreaseQueue(final long value) { -+ final int idx = this.decreaseQueueInitialLength++; -+ long[] queue = this.decreaseQueue; -+ if (idx >= queue.length) { -+ queue = this.resizeDecreaseQueue(); -+ queue[idx] = value; -+ return; -+ } else { -+ queue[idx] = value; -+ return; -+ } -+ } -+ -+ protected final void performIncrease() { -+ long[] queue = this.increaseQueue; -+ int queueReadIndex = 0; -+ int queueLength = this.increaseQueueInitialLength; -+ this.increaseQueueInitialLength = 0; -+ final int decodeOffsetX = -this.encodeOffsetX; -+ final int decodeOffsetZ = -this.encodeOffsetZ; -+ final int encodeOffset = this.coordinateOffset; -+ final int sectionOffset = this.sectionIndexOffset; -+ -+ final Long2ByteLinkedOpenHashMap updatedPositions = this.updatedPositions; -+ -+ while (queueReadIndex < queueLength) { -+ final long queueValue = queue[queueReadIndex++]; -+ -+ final int posX = ((int)queueValue & (COORDINATE_SIZE - 1)) + decodeOffsetX; -+ final int posZ = (((int)queueValue >>> COORDINATE_BITS) & (COORDINATE_SIZE - 1)) + decodeOffsetZ; -+ final int propagatedLevel = ((int)queueValue >>> (COORDINATE_BITS + COORDINATE_BITS)) & (LEVEL_COUNT - 1); -+ // note: the above code requires coordinate bits * 2 < 32 -+ // bitset is 16 bits -+ int propagateDirectionBitset = (int)(queueValue >>> (COORDINATE_BITS + COORDINATE_BITS + LEVEL_BITS)) & ((1 << 16) - 1); -+ -+ if ((queueValue & FLAG_RECHECK_LEVEL) != 0L) { -+ if (this.getLevel(posX, posZ) != propagatedLevel) { -+ // not at the level we expect, so something changed. -+ continue; -+ } -+ } else if ((queueValue & FLAG_WRITE_LEVEL) != 0L) { -+ // these are used to restore sources after a propagation decrease -+ this.setLevel(posX, posZ, propagatedLevel); -+ } -+ -+ // this bitset represents the values that we have not propagated to -+ // this bitset lets us determine what directions the neighbours we set should propagate to, in most cases -+ // significantly reducing the total number of ops -+ // since we propagate in a 1 radius, we need a 2 radius bitset to hold all possible values we would possibly need -+ // but if we use only 5x5 bits, then we need to use div/mod to retrieve coordinates from the bitset, so instead -+ // we use an 8x8 bitset and luckily that can be fit into only one long value (64 bits) -+ // to make things easy, we use positions [0, 4] in the bitset, with current position being 2 -+ // index = x | (z << 3) -+ -+ // to start, we eliminate everything 1 radius from the current position as the previous propagator -+ // must guarantee that either we propagate everything in 1 radius or we partially propagate for 1 radius -+ // but the rest not propagated are already handled -+ long currentPropagation = ~( -+ // z = -1 -+ (1L << ((2 - 1) | ((2 - 1) << 3))) | -+ (1L << ((2 + 0) | ((2 - 1) << 3))) | -+ (1L << ((2 + 1) | ((2 - 1) << 3))) | -+ -+ // z = 0 -+ (1L << ((2 - 1) | ((2 + 0) << 3))) | -+ (1L << ((2 + 0) | ((2 + 0) << 3))) | -+ (1L << ((2 + 1) | ((2 + 0) << 3))) | -+ -+ // z = 1 -+ (1L << ((2 - 1) | ((2 + 1) << 3))) | -+ (1L << ((2 + 0) | ((2 + 1) << 3))) | -+ (1L << ((2 + 1) | ((2 + 1) << 3))) -+ ); -+ -+ final int toPropagate = propagatedLevel - 1; -+ -+ // we could use while (propagateDirectionBitset != 0), but it's not a predictable branch. By counting -+ // the bits, the cpu loop predictor should perfectly predict the loop. -+ for (int l = 0, len = Integer.bitCount(propagateDirectionBitset); l < len; ++l) { -+ final int set = Integer.numberOfTrailingZeros(propagateDirectionBitset); -+ final int tailingBit = (-propagateDirectionBitset) & propagateDirectionBitset; -+ propagateDirectionBitset ^= tailingBit; -+ -+ // pDecode is from [0, 2], and 1 must be subtracted to fully decode the offset -+ // it has been split to save some cycles via parallelism -+ final int pDecodeX = (set & 3); -+ final int pDecodeZ = ((set >>> 2) & 3); -+ -+ // re-ordered -1 on the position decode into pos - 1 to occur in parallel with determining pDecodeX -+ final int offX = (posX - 1) + pDecodeX; -+ final int offZ = (posZ - 1) + pDecodeZ; -+ -+ final int sectionIndex = (offX >> SECTION_SHIFT) + ((offZ >> SECTION_SHIFT) * SECTION_CACHE_WIDTH) + sectionOffset; -+ final int localIndex = (offX & (SECTION_SIZE - 1)) | ((offZ & (SECTION_SIZE - 1)) << SECTION_SHIFT); -+ -+ // to retrieve a set of bits from a long value: (n_bitmask << (nstartidx)) & bitset -+ // bitset idx = x | (z << 3) -+ -+ // read three bits, so we need 7L -+ // note that generally: off - pos = (pos - 1) + pDecode - pos = pDecode - 1 -+ // nstartidx1 = x rel -1 for z rel -1 -+ // = (offX - posX - 1 + 2) | ((offZ - posZ - 1 + 2) << 3) -+ // = (pDecodeX - 1 - 1 + 2) | ((pDecodeZ - 1 - 1 + 2) << 3) -+ // = pDecodeX | (pDecodeZ << 3) = start -+ final int start = pDecodeX | (pDecodeZ << 3); -+ final long bitsetLine1 = currentPropagation & (7L << (start)); -+ -+ // nstartidx2 = x rel -1 for z rel 0 = line after line1, so we can just add 8 (row length of bitset) -+ final long bitsetLine2 = currentPropagation & (7L << (start + 8)); -+ -+ // nstartidx2 = x rel -1 for z rel 0 = line after line2, so we can just add 8 (row length of bitset) -+ final long bitsetLine3 = currentPropagation & (7L << (start + (8 + 8))); -+ -+ // remove ("take") lines from bitset -+ currentPropagation ^= (bitsetLine1 | bitsetLine2 | bitsetLine3); -+ -+ // now try to propagate -+ final Section section = this.sections[sectionIndex]; -+ -+ // lower 8 bits are current level, next upper 7 bits are source level, next 1 bit is updated source flag -+ final short currentStoredLevel = section.levels[localIndex]; -+ final int currentLevel = currentStoredLevel & 0xFF; -+ -+ if (currentLevel >= toPropagate) { -+ continue; // already at the level we want -+ } -+ -+ // update level -+ section.levels[localIndex] = (short)((currentStoredLevel & ~0xFF) | (toPropagate & 0xFF)); -+ updatedPositions.putAndMoveToLast(Coordinate.key(offX, offZ), (byte)toPropagate); -+ -+ // queue next -+ if (toPropagate > 1) { -+ // now combine into one bitset to pass to child -+ // the child bitset is 4x4, so we just shift each line by 4 -+ // add the propagation bitset offset to each line to make it easy to OR it into the propagation queue value -+ final long childPropagation = -+ ((bitsetLine1 >>> (start)) << (COORDINATE_BITS + COORDINATE_BITS + LEVEL_BITS)) | // z = -1 -+ ((bitsetLine2 >>> (start + 8)) << (4 + COORDINATE_BITS + COORDINATE_BITS + LEVEL_BITS)) | // z = 0 -+ ((bitsetLine3 >>> (start + (8 + 8))) << (4 + 4 + COORDINATE_BITS + COORDINATE_BITS + LEVEL_BITS)); // z = 1 -+ -+ // don't queue update if toPropagate cannot propagate anything to neighbours -+ // (for increase, propagating 0 to neighbours is useless) -+ if (queueLength >= queue.length) { -+ queue = this.resizeIncreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((long)(offX + (offZ << COORDINATE_BITS) + encodeOffset) & ((1L << (COORDINATE_BITS + COORDINATE_BITS)) - 1)) | -+ ((toPropagate & (LEVEL_COUNT - 1L)) << (COORDINATE_BITS + COORDINATE_BITS)) | -+ childPropagation; //(ALL_DIRECTIONS_BITSET << (COORDINATE_BITS + COORDINATE_BITS + LEVEL_BITS)); -+ continue; -+ } -+ continue; -+ } -+ } -+ } -+ -+ protected final void performDecrease() { -+ long[] queue = this.decreaseQueue; -+ long[] increaseQueue = this.increaseQueue; -+ int queueReadIndex = 0; -+ int queueLength = this.decreaseQueueInitialLength; -+ this.decreaseQueueInitialLength = 0; -+ int increaseQueueLength = this.increaseQueueInitialLength; -+ final int decodeOffsetX = -this.encodeOffsetX; -+ final int decodeOffsetZ = -this.encodeOffsetZ; -+ final int encodeOffset = this.coordinateOffset; -+ final int sectionOffset = this.sectionIndexOffset; -+ -+ final Long2ByteLinkedOpenHashMap updatedPositions = this.updatedPositions; -+ -+ while (queueReadIndex < queueLength) { -+ final long queueValue = queue[queueReadIndex++]; -+ -+ final int posX = ((int)queueValue & (COORDINATE_SIZE - 1)) + decodeOffsetX; -+ final int posZ = (((int)queueValue >>> COORDINATE_BITS) & (COORDINATE_SIZE - 1)) + decodeOffsetZ; -+ final int propagatedLevel = ((int)queueValue >>> (COORDINATE_BITS + COORDINATE_BITS)) & (LEVEL_COUNT - 1); -+ // note: the above code requires coordinate bits * 2 < 32 -+ // bitset is 16 bits -+ int propagateDirectionBitset = (int)(queueValue >>> (COORDINATE_BITS + COORDINATE_BITS + LEVEL_BITS)) & ((1 << 16) - 1); -+ -+ // this bitset represents the values that we have not propagated to -+ // this bitset lets us determine what directions the neighbours we set should propagate to, in most cases -+ // significantly reducing the total number of ops -+ // since we propagate in a 1 radius, we need a 2 radius bitset to hold all possible values we would possibly need -+ // but if we use only 5x5 bits, then we need to use div/mod to retrieve coordinates from the bitset, so instead -+ // we use an 8x8 bitset and luckily that can be fit into only one long value (64 bits) -+ // to make things easy, we use positions [0, 4] in the bitset, with current position being 2 -+ // index = x | (z << 3) -+ -+ // to start, we eliminate everything 1 radius from the current position as the previous propagator -+ // must guarantee that either we propagate everything in 1 radius or we partially propagate for 1 radius -+ // but the rest not propagated are already handled -+ long currentPropagation = ~( -+ // z = -1 -+ (1L << ((2 - 1) | ((2 - 1) << 3))) | -+ (1L << ((2 + 0) | ((2 - 1) << 3))) | -+ (1L << ((2 + 1) | ((2 - 1) << 3))) | -+ -+ // z = 0 -+ (1L << ((2 - 1) | ((2 + 0) << 3))) | -+ (1L << ((2 + 0) | ((2 + 0) << 3))) | -+ (1L << ((2 + 1) | ((2 + 0) << 3))) | -+ -+ // z = 1 -+ (1L << ((2 - 1) | ((2 + 1) << 3))) | -+ (1L << ((2 + 0) | ((2 + 1) << 3))) | -+ (1L << ((2 + 1) | ((2 + 1) << 3))) -+ ); -+ -+ final int toPropagate = propagatedLevel - 1; -+ -+ // we could use while (propagateDirectionBitset != 0), but it's not a predictable branch. By counting -+ // the bits, the cpu loop predictor should perfectly predict the loop. -+ for (int l = 0, len = Integer.bitCount(propagateDirectionBitset); l < len; ++l) { -+ final int set = Integer.numberOfTrailingZeros(propagateDirectionBitset); -+ final int tailingBit = (-propagateDirectionBitset) & propagateDirectionBitset; -+ propagateDirectionBitset ^= tailingBit; -+ -+ -+ // pDecode is from [0, 2], and 1 must be subtracted to fully decode the offset -+ // it has been split to save some cycles via parallelism -+ final int pDecodeX = (set & 3); -+ final int pDecodeZ = ((set >>> 2) & 3); -+ -+ // re-ordered -1 on the position decode into pos - 1 to occur in parallel with determining pDecodeX -+ final int offX = (posX - 1) + pDecodeX; -+ final int offZ = (posZ - 1) + pDecodeZ; -+ -+ final int sectionIndex = (offX >> SECTION_SHIFT) + ((offZ >> SECTION_SHIFT) * SECTION_CACHE_WIDTH) + sectionOffset; -+ final int localIndex = (offX & (SECTION_SIZE - 1)) | ((offZ & (SECTION_SIZE - 1)) << SECTION_SHIFT); -+ -+ // to retrieve a set of bits from a long value: (n_bitmask << (nstartidx)) & bitset -+ // bitset idx = x | (z << 3) -+ -+ // read three bits, so we need 7L -+ // note that generally: off - pos = (pos - 1) + pDecode - pos = pDecode - 1 -+ // nstartidx1 = x rel -1 for z rel -1 -+ // = (offX - posX - 1 + 2) | ((offZ - posZ - 1 + 2) << 3) -+ // = (pDecodeX - 1 - 1 + 2) | ((pDecodeZ - 1 - 1 + 2) << 3) -+ // = pDecodeX | (pDecodeZ << 3) = start -+ final int start = pDecodeX | (pDecodeZ << 3); -+ final long bitsetLine1 = currentPropagation & (7L << (start)); -+ -+ // nstartidx2 = x rel -1 for z rel 0 = line after line1, so we can just add 8 (row length of bitset) -+ final long bitsetLine2 = currentPropagation & (7L << (start + 8)); -+ -+ // nstartidx2 = x rel -1 for z rel 0 = line after line2, so we can just add 8 (row length of bitset) -+ final long bitsetLine3 = currentPropagation & (7L << (start + (8 + 8))); -+ -+ // now try to propagate -+ final Section section = this.sections[sectionIndex]; -+ -+ // lower 8 bits are current level, next upper 7 bits are source level, next 1 bit is updated source flag -+ final short currentStoredLevel = section.levels[localIndex]; -+ final int currentLevel = currentStoredLevel & 0xFF; -+ final int sourceLevel = (currentStoredLevel >>> 8) & 0xFF; -+ -+ if (currentLevel == 0) { -+ continue; // already at the level we want -+ } -+ -+ if (currentLevel > toPropagate) { -+ // it looks like another source propagated here, so re-propagate it -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((long)(offX + (offZ << COORDINATE_BITS) + encodeOffset) & ((1L << (COORDINATE_BITS + COORDINATE_BITS)) - 1)) | -+ ((currentLevel & (LEVEL_COUNT - 1L)) << (COORDINATE_BITS + COORDINATE_BITS)) | -+ (FLAG_RECHECK_LEVEL | (ALL_DIRECTIONS_BITSET << (COORDINATE_BITS + COORDINATE_BITS + LEVEL_BITS))); -+ continue; -+ } -+ -+ // remove ("take") lines from bitset -+ // can't do this during decrease, TODO WHY? -+ //currentPropagation ^= (bitsetLine1 | bitsetLine2 | bitsetLine3); -+ -+ // update level -+ section.levels[localIndex] = (short)((currentStoredLevel & ~0xFF)); -+ updatedPositions.putAndMoveToLast(Coordinate.key(offX, offZ), (byte)0); -+ -+ if (sourceLevel != 0) { -+ // re-propagate source -+ // note: do not set recheck level, or else the propagation will fail -+ if (increaseQueueLength >= increaseQueue.length) { -+ increaseQueue = this.resizeIncreaseQueue(); -+ } -+ increaseQueue[increaseQueueLength++] = -+ ((long)(offX + (offZ << COORDINATE_BITS) + encodeOffset) & ((1L << (COORDINATE_BITS + COORDINATE_BITS)) - 1)) | -+ ((sourceLevel & (LEVEL_COUNT - 1L)) << (COORDINATE_BITS + COORDINATE_BITS)) | -+ (FLAG_WRITE_LEVEL | (ALL_DIRECTIONS_BITSET << (COORDINATE_BITS + COORDINATE_BITS + LEVEL_BITS))); -+ } -+ -+ // queue next -+ // note: targetLevel > 0 here, since toPropagate >= currentLevel and currentLevel > 0 -+ // now combine into one bitset to pass to child -+ // the child bitset is 4x4, so we just shift each line by 4 -+ // add the propagation bitset offset to each line to make it easy to OR it into the propagation queue value -+ final long childPropagation = -+ ((bitsetLine1 >>> (start)) << (COORDINATE_BITS + COORDINATE_BITS + LEVEL_BITS)) | // z = -1 -+ ((bitsetLine2 >>> (start + 8)) << (4 + COORDINATE_BITS + COORDINATE_BITS + LEVEL_BITS)) | // z = 0 -+ ((bitsetLine3 >>> (start + (8 + 8))) << (4 + 4 + COORDINATE_BITS + COORDINATE_BITS + LEVEL_BITS)); // z = 1 -+ -+ // don't queue update if toPropagate cannot propagate anything to neighbours -+ // (for increase, propagating 0 to neighbours is useless) -+ if (queueLength >= queue.length) { -+ queue = this.resizeDecreaseQueue(); -+ } -+ queue[queueLength++] = -+ ((long)(offX + (offZ << COORDINATE_BITS) + encodeOffset) & ((1L << (COORDINATE_BITS + COORDINATE_BITS)) - 1)) | -+ ((toPropagate & (LEVEL_COUNT - 1L)) << (COORDINATE_BITS + COORDINATE_BITS)) | -+ (ALL_DIRECTIONS_BITSET << (COORDINATE_BITS + COORDINATE_BITS + LEVEL_BITS)); //childPropagation; -+ continue; -+ } -+ } -+ -+ // propagate sources we clobbered -+ this.increaseQueueInitialLength = increaseQueueLength; -+ this.performIncrease(); -+ } -+ } -+ -+ private static final class Coordinate implements Comparable { -+ -+ public final long key; -+ -+ public Coordinate(final long key) { -+ this.key = key; -+ } -+ -+ public Coordinate(final int x, final int z) { -+ this.key = key(x, z); -+ } -+ -+ public static long key(final int x, final int z) { -+ return ((long)z << 32) | (x & 0xFFFFFFFFL); -+ } -+ -+ public static int x(final long key) { -+ return (int)key; -+ } -+ -+ public static int z(final long key) { -+ return (int)(key >>> 32); -+ } -+ -+ @Override -+ public int hashCode() { -+ return (int)HashCommon.mix(this.key); -+ } -+ -+ @Override -+ public boolean equals(final Object obj) { -+ if (this == obj) { -+ return true; -+ } -+ -+ if (!(obj instanceof Coordinate other)) { -+ return false; -+ } -+ -+ return this.key == other.key; -+ } -+ -+ // This class is intended for HashMap/ConcurrentHashMap usage, which do treeify bin nodes if the chain -+ // is too large. So we should implement compareTo to help. -+ @Override -+ public int compareTo(final Coordinate other) { -+ return Long.compare(this.key, other.key); -+ } -+ -+ @Override -+ public String toString() { -+ return "[" + x(this.key) + "," + z(this.key) + "]"; -+ } -+ } -+ -+ /* -+ private static final java.util.Random random = new java.util.Random(4L); -+ private static final List> walkers = -+ new java.util.ArrayList<>(); -+ static final int PLAYERS = 0; -+ static final int RAD_BLOCKS = 10000; -+ static final int RAD = RAD_BLOCKS >> 4; -+ static final int RAD_BIG_BLOCKS = 100_000; -+ static final int RAD_BIG = RAD_BIG_BLOCKS >> 4; -+ static final int VD = 4; -+ static final int BIG_PLAYERS = 50; -+ static final double WALK_CHANCE = 0.10; -+ static final double TP_CHANCE = 0.01; -+ static final int TP_BACK_PLAYERS = 200; -+ static final double TP_BACK_CHANCE = 0.25; -+ static final double TP_STEAL_CHANCE = 0.25; -+ private static final List> tpBack = -+ new java.util.ArrayList<>(); -+ -+ public static void main(final String[] args) { -+ final ReentrantAreaLock ticketLock = new ReentrantAreaLock(SECTION_SHIFT); -+ final ReentrantAreaLock schedulingLock = new ReentrantAreaLock(SECTION_SHIFT); -+ final Long2ByteLinkedOpenHashMap levelMap = new Long2ByteLinkedOpenHashMap(); -+ final Long2ByteLinkedOpenHashMap refMap = new Long2ByteLinkedOpenHashMap(); -+ final io.papermc.paper.util.misc.Delayed8WayDistancePropagator2D ref = new io.papermc.paper.util.misc.Delayed8WayDistancePropagator2D((final long coordinate, final byte oldLevel, final byte newLevel) -> { -+ if (newLevel == 0) { -+ refMap.remove(coordinate); -+ } else { -+ refMap.put(coordinate, newLevel); -+ } -+ }); -+ final ThreadedTicketLevelPropagator propagator = new ThreadedTicketLevelPropagator() { -+ @Override -+ protected void processLevelUpdates(Long2ByteLinkedOpenHashMap updates) { -+ for (final long key : updates.keySet()) { -+ final byte val = updates.get(key); -+ if (val == 0) { -+ levelMap.remove(key); -+ } else { -+ levelMap.put(key, val); -+ } -+ } -+ } -+ -+ @Override -+ protected void processSchedulingUpdates(Long2ByteLinkedOpenHashMap updates, List scheduledTasks, List changedFullStatus) {} -+ }; -+ -+ for (;;) { -+ if (walkers.isEmpty() && tpBack.isEmpty()) { -+ for (int i = 0; i < PLAYERS; ++i) { -+ int rad = i < BIG_PLAYERS ? RAD_BIG : RAD; -+ int posX = random.nextInt(-rad, rad + 1); -+ int posZ = random.nextInt(-rad, rad + 1); -+ -+ io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.SingleUserAreaMap map = new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.SingleUserAreaMap<>(null) { -+ @Override -+ protected void addCallback(Void parameter, int chunkX, int chunkZ) { -+ int src = 45 - 31 + 1; -+ ref.setSource(chunkX, chunkZ, src); -+ propagator.setSource(chunkX, chunkZ, src); -+ } -+ -+ @Override -+ protected void removeCallback(Void parameter, int chunkX, int chunkZ) { -+ ref.removeSource(chunkX, chunkZ); -+ propagator.removeSource(chunkX, chunkZ); -+ } -+ }; -+ -+ map.add(posX, posZ, VD); -+ -+ walkers.add(map); -+ } -+ for (int i = 0; i < TP_BACK_PLAYERS; ++i) { -+ int rad = RAD_BIG; -+ int posX = random.nextInt(-rad, rad + 1); -+ int posZ = random.nextInt(-rad, rad + 1); -+ -+ io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.SingleUserAreaMap map = new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.SingleUserAreaMap<>(null) { -+ @Override -+ protected void addCallback(Void parameter, int chunkX, int chunkZ) { -+ int src = 45 - 31 + 1; -+ ref.setSource(chunkX, chunkZ, src); -+ propagator.setSource(chunkX, chunkZ, src); -+ } -+ -+ @Override -+ protected void removeCallback(Void parameter, int chunkX, int chunkZ) { -+ ref.removeSource(chunkX, chunkZ); -+ propagator.removeSource(chunkX, chunkZ); -+ } -+ }; -+ -+ map.add(posX, posZ, random.nextInt(1, 63)); -+ -+ tpBack.add(map); -+ } -+ } else { -+ for (int i = 0; i < PLAYERS; ++i) { -+ if (random.nextDouble() > WALK_CHANCE) { -+ continue; -+ } -+ -+ io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.SingleUserAreaMap map = walkers.get(i); -+ -+ int updateX = random.nextInt(-1, 2); -+ int updateZ = random.nextInt(-1, 2); -+ -+ map.update(map.lastChunkX + updateX, map.lastChunkZ + updateZ, VD); -+ } -+ -+ for (int i = 0; i < PLAYERS; ++i) { -+ if (random.nextDouble() > TP_CHANCE) { -+ continue; -+ } -+ -+ int rad = i < BIG_PLAYERS ? RAD_BIG : RAD; -+ int posX = random.nextInt(-rad, rad + 1); -+ int posZ = random.nextInt(-rad, rad + 1); -+ -+ io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.SingleUserAreaMap map = walkers.get(i); -+ -+ map.update(posX, posZ, VD); -+ } -+ -+ for (int i = 0; i < TP_BACK_PLAYERS; ++i) { -+ if (random.nextDouble() > TP_BACK_CHANCE) { -+ continue; -+ } -+ -+ io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.SingleUserAreaMap map = tpBack.get(i); -+ -+ map.update(-map.lastChunkX, -map.lastChunkZ, random.nextInt(1, 63)); -+ -+ if (random.nextDouble() > TP_STEAL_CHANCE) { -+ propagator.performUpdate( -+ map.lastChunkX >> SECTION_SHIFT, map.lastChunkZ >> SECTION_SHIFT, schedulingLock, null, null -+ ); -+ propagator.performUpdate( -+ (-map.lastChunkX >> SECTION_SHIFT), (-map.lastChunkZ >> SECTION_SHIFT), schedulingLock, null, null -+ ); -+ } -+ } -+ } -+ -+ ref.propagateUpdates(); -+ propagator.performUpdates(ticketLock, schedulingLock, null, null); -+ -+ if (!refMap.equals(levelMap)) { -+ throw new IllegalStateException("Error!"); -+ } -+ } -+ } -+ */ -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/queue/RadiusAwarePrioritisedExecutor.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/queue/RadiusAwarePrioritisedExecutor.java -new file mode 100644 -index 0000000000000000000000000000000000000000..f7b0e2564ac4bd2db1d2b2bdc230c9f52f8a21b7 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/queue/RadiusAwarePrioritisedExecutor.java -@@ -0,0 +1,667 @@ -+package io.papermc.paper.chunk.system.scheduling.queue; -+ -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import io.papermc.paper.util.CoordinateUtils; -+import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; -+import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; -+import java.util.ArrayList; -+import java.util.Comparator; -+import java.util.List; -+import java.util.PriorityQueue; -+ -+public class RadiusAwarePrioritisedExecutor { -+ -+ private static final Comparator DEPENDENCY_NODE_COMPARATOR = (final DependencyNode t1, final DependencyNode t2) -> { -+ return Long.compare(t1.id, t2.id); -+ }; -+ -+ private final DependencyTree[] queues = new DependencyTree[PrioritisedExecutor.Priority.TOTAL_SCHEDULABLE_PRIORITIES]; -+ private static final int NO_TASKS_QUEUED = -1; -+ private int selectedQueue = NO_TASKS_QUEUED; -+ private boolean canQueueTasks = true; -+ -+ public RadiusAwarePrioritisedExecutor(final PrioritisedExecutor executor, final int maxToSchedule) { -+ for (int i = 0; i < this.queues.length; ++i) { -+ this.queues[i] = new DependencyTree(this, executor, maxToSchedule, i); -+ } -+ } -+ -+ private boolean canQueueTasks() { -+ return this.canQueueTasks; -+ } -+ -+ private List treeFinished() { -+ this.canQueueTasks = true; -+ for (int priority = 0; priority < this.queues.length; ++priority) { -+ final DependencyTree queue = this.queues[priority]; -+ if (queue.hasWaitingTasks()) { -+ final List ret = queue.tryPushTasks(); -+ -+ if (ret == null || ret.isEmpty()) { -+ // this happens when the tasks in the wait queue were purged -+ // in this case, the queue was actually empty, we just had to purge it -+ // if we set the selected queue without scheduling any tasks, the queue will never be unselected -+ // as that requires a scheduled task completing... -+ continue; -+ } -+ -+ this.selectedQueue = priority; -+ return ret; -+ } -+ } -+ -+ this.selectedQueue = NO_TASKS_QUEUED; -+ -+ return null; -+ } -+ -+ private List queue(final Task task, final PrioritisedExecutor.Priority priority) { -+ final int priorityId = priority.priority; -+ final DependencyTree queue = this.queues[priorityId]; -+ -+ final DependencyNode node = new DependencyNode(task, queue); -+ -+ if (task.dependencyNode != null) { -+ throw new IllegalStateException(); -+ } -+ task.dependencyNode = node; -+ -+ queue.pushNode(node); -+ -+ if (this.selectedQueue == NO_TASKS_QUEUED) { -+ this.canQueueTasks = true; -+ this.selectedQueue = priorityId; -+ return queue.tryPushTasks(); -+ } -+ -+ if (!this.canQueueTasks) { -+ return null; -+ } -+ -+ if (PrioritisedExecutor.Priority.isHigherPriority(priorityId, this.selectedQueue)) { -+ // prevent the lower priority tree from queueing more tasks -+ this.canQueueTasks = false; -+ return null; -+ } -+ -+ // priorityId != selectedQueue: lower priority, don't care - treeFinished will pick it up -+ return priorityId == this.selectedQueue ? queue.tryPushTasks() : null; -+ } -+ -+ public PrioritisedExecutor.PrioritisedTask createTask(final int chunkX, final int chunkZ, final int radius, -+ final Runnable run, final PrioritisedExecutor.Priority priority) { -+ if (radius < 0) { -+ throw new IllegalArgumentException("Radius must be > 0: " + radius); -+ } -+ return new Task(this, chunkX, chunkZ, radius, run, priority); -+ } -+ -+ public PrioritisedExecutor.PrioritisedTask createTask(final int chunkX, final int chunkZ, final int radius, -+ final Runnable run) { -+ return this.createTask(chunkX, chunkZ, radius, run, PrioritisedExecutor.Priority.NORMAL); -+ } -+ -+ public PrioritisedExecutor.PrioritisedTask queueTask(final int chunkX, final int chunkZ, final int radius, -+ final Runnable run, final PrioritisedExecutor.Priority priority) { -+ final PrioritisedExecutor.PrioritisedTask ret = this.createTask(chunkX, chunkZ, radius, run, priority); -+ -+ ret.queue(); -+ -+ return ret; -+ } -+ -+ public PrioritisedExecutor.PrioritisedTask queueTask(final int chunkX, final int chunkZ, final int radius, -+ final Runnable run) { -+ final PrioritisedExecutor.PrioritisedTask ret = this.createTask(chunkX, chunkZ, radius, run); -+ -+ ret.queue(); -+ -+ return ret; -+ } -+ -+ public PrioritisedExecutor.PrioritisedTask createInfiniteRadiusTask(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ return new Task(this, 0, 0, -1, run, priority); -+ } -+ -+ public PrioritisedExecutor.PrioritisedTask createInfiniteRadiusTask(final Runnable run) { -+ return this.createInfiniteRadiusTask(run, PrioritisedExecutor.Priority.NORMAL); -+ } -+ -+ public PrioritisedExecutor.PrioritisedTask queueInfiniteRadiusTask(final Runnable run, final PrioritisedExecutor.Priority priority) { -+ final PrioritisedExecutor.PrioritisedTask ret = this.createInfiniteRadiusTask(run, priority); -+ -+ ret.queue(); -+ -+ return ret; -+ } -+ -+ public PrioritisedExecutor.PrioritisedTask queueInfiniteRadiusTask(final Runnable run) { -+ final PrioritisedExecutor.PrioritisedTask ret = this.createInfiniteRadiusTask(run, PrioritisedExecutor.Priority.NORMAL); -+ -+ ret.queue(); -+ -+ return ret; -+ } -+ -+ // all accesses must be synchronised by the radius aware object -+ private static final class DependencyTree { -+ -+ private final RadiusAwarePrioritisedExecutor scheduler; -+ private final PrioritisedExecutor executor; -+ private final int maxToSchedule; -+ private final int treeIndex; -+ -+ private int currentlyExecuting; -+ private long idGenerator; -+ -+ private final PriorityQueue awaiting = new PriorityQueue<>(DEPENDENCY_NODE_COMPARATOR); -+ -+ private final PriorityQueue infiniteRadius = new PriorityQueue<>(DEPENDENCY_NODE_COMPARATOR); -+ private boolean isInfiniteRadiusScheduled; -+ -+ private final Long2ReferenceOpenHashMap nodeByPosition = new Long2ReferenceOpenHashMap<>(); -+ -+ public DependencyTree(final RadiusAwarePrioritisedExecutor scheduler, final PrioritisedExecutor executor, -+ final int maxToSchedule, final int treeIndex) { -+ this.scheduler = scheduler; -+ this.executor = executor; -+ this.maxToSchedule = maxToSchedule; -+ this.treeIndex = treeIndex; -+ } -+ -+ public boolean hasWaitingTasks() { -+ return !this.awaiting.isEmpty() || !this.infiniteRadius.isEmpty(); -+ } -+ -+ private long nextId() { -+ return this.idGenerator++; -+ } -+ -+ private boolean isExecutingAnyTasks() { -+ return this.currentlyExecuting != 0; -+ } -+ -+ private void pushNode(final DependencyNode node) { -+ if (!node.task.isFiniteRadius()) { -+ this.infiniteRadius.add(node); -+ return; -+ } -+ -+ // set up dependency for node -+ final Task task = node.task; -+ -+ final int centerX = task.chunkX; -+ final int centerZ = task.chunkZ; -+ final int radius = task.radius; -+ -+ final int minX = centerX - radius; -+ final int maxX = centerX + radius; -+ -+ final int minZ = centerZ - radius; -+ final int maxZ = centerZ + radius; -+ -+ ReferenceOpenHashSet parents = null; -+ for (int currZ = minZ; currZ <= maxZ; ++currZ) { -+ for (int currX = minX; currX <= maxX; ++currX) { -+ final DependencyNode dependency = this.nodeByPosition.put(CoordinateUtils.getChunkKey(currX, currZ), node); -+ if (dependency != null) { -+ if (parents == null) { -+ parents = new ReferenceOpenHashSet<>(); -+ } -+ if (parents.add(dependency)) { -+ // added a dependency, so we need to add as a child to the dependency -+ if (dependency.children == null) { -+ dependency.children = new ArrayList<>(); -+ } -+ dependency.children.add(node); -+ } -+ } -+ } -+ } -+ -+ if (parents == null) { -+ // no dependencies, add straight to awaiting -+ this.awaiting.add(node); -+ } else { -+ node.parents = parents.size(); -+ // we will be added to awaiting once we have no parents -+ } -+ } -+ -+ // called only when a node is returned after being executed -+ private List returnNode(final DependencyNode node) { -+ final Task task = node.task; -+ -+ // now that the task is completed, we can push its children to the awaiting queue -+ this.pushChildren(node); -+ -+ if (task.isFiniteRadius()) { -+ // remove from dependency map -+ this.removeNodeFromMap(node); -+ } else { -+ // mark as no longer executing infinite radius -+ if (!this.isInfiniteRadiusScheduled) { -+ throw new IllegalStateException(); -+ } -+ this.isInfiniteRadiusScheduled = false; -+ } -+ -+ // decrement executing count, we are done executing this task -+ --this.currentlyExecuting; -+ -+ if (this.currentlyExecuting == 0) { -+ return this.scheduler.treeFinished(); -+ } -+ -+ return this.scheduler.canQueueTasks() ? this.tryPushTasks() : null; -+ } -+ -+ private List tryPushTasks() { -+ // tasks are not queued, but only created here - we do hold the lock for the map -+ List ret = null; -+ PrioritisedExecutor.PrioritisedTask pushedTask; -+ while ((pushedTask = this.tryPushTask()) != null) { -+ if (ret == null) { -+ ret = new ArrayList<>(); -+ } -+ ret.add(pushedTask); -+ } -+ -+ return ret; -+ } -+ -+ private void removeNodeFromMap(final DependencyNode node) { -+ final Task task = node.task; -+ -+ final int centerX = task.chunkX; -+ final int centerZ = task.chunkZ; -+ final int radius = task.radius; -+ -+ final int minX = centerX - radius; -+ final int maxX = centerX + radius; -+ -+ final int minZ = centerZ - radius; -+ final int maxZ = centerZ + radius; -+ -+ for (int currZ = minZ; currZ <= maxZ; ++currZ) { -+ for (int currX = minX; currX <= maxX; ++currX) { -+ this.nodeByPosition.remove(CoordinateUtils.getChunkKey(currX, currZ), node); -+ } -+ } -+ } -+ -+ private void pushChildren(final DependencyNode node) { -+ // add all the children that we can into awaiting -+ final List children = node.children; -+ if (children != null) { -+ for (int i = 0, len = children.size(); i < len; ++i) { -+ final DependencyNode child = children.get(i); -+ int newParents = --child.parents; -+ if (newParents == 0) { -+ // no more dependents, we can push to awaiting -+ // even if the child is purged, we need to push it so that its children will be pushed -+ this.awaiting.add(child); -+ } else if (newParents < 0) { -+ throw new IllegalStateException(); -+ } -+ } -+ } -+ } -+ -+ private DependencyNode pollAwaiting() { -+ final DependencyNode ret = this.awaiting.poll(); -+ if (ret == null) { -+ return ret; -+ } -+ -+ if (ret.parents != 0) { -+ throw new IllegalStateException(); -+ } -+ -+ if (ret.purged) { -+ // need to manually remove from state here -+ this.pushChildren(ret); -+ this.removeNodeFromMap(ret); -+ } // else: delay children push until the task has finished -+ -+ return ret; -+ } -+ -+ private DependencyNode pollInfinite() { -+ return this.infiniteRadius.poll(); -+ } -+ -+ public PrioritisedExecutor.PrioritisedTask tryPushTask() { -+ if (this.currentlyExecuting >= this.maxToSchedule || this.isInfiniteRadiusScheduled) { -+ return null; -+ } -+ -+ DependencyNode firstInfinite; -+ while ((firstInfinite = this.infiniteRadius.peek()) != null && firstInfinite.purged) { -+ this.pollInfinite(); -+ } -+ -+ DependencyNode firstAwaiting; -+ while ((firstAwaiting = this.awaiting.peek()) != null && firstAwaiting.purged) { -+ this.pollAwaiting(); -+ } -+ -+ if (firstInfinite == null && firstAwaiting == null) { -+ return null; -+ } -+ -+ // firstAwaiting compared to firstInfinite -+ final int compare; -+ -+ if (firstAwaiting == null) { -+ // we choose first infinite, or infinite < awaiting -+ compare = 1; -+ } else if (firstInfinite == null) { -+ // we choose first awaiting, or awaiting < infinite -+ compare = -1; -+ } else { -+ compare = DEPENDENCY_NODE_COMPARATOR.compare(firstAwaiting, firstInfinite); -+ } -+ -+ if (compare >= 0) { -+ if (this.currentlyExecuting != 0) { -+ // don't queue infinite task while other tasks are executing in parallel -+ return null; -+ } -+ ++this.currentlyExecuting; -+ this.pollInfinite(); -+ this.isInfiniteRadiusScheduled = true; -+ return firstInfinite.task.pushTask(this.executor); -+ } else { -+ ++this.currentlyExecuting; -+ this.pollAwaiting(); -+ return firstAwaiting.task.pushTask(this.executor); -+ } -+ } -+ } -+ -+ private static final class DependencyNode { -+ -+ private final Task task; -+ private final DependencyTree tree; -+ -+ // dependency tree fields -+ // (must hold lock on the scheduler to use) -+ // null is the same as empty, we just use it so that we don't allocate the set unless we need to -+ private List children; -+ // 0 indicates that this task is considered "awaiting" -+ private int parents; -+ // false -> scheduled and not cancelled -+ // true -> scheduled but cancelled -+ private boolean purged; -+ private final long id; -+ -+ public DependencyNode(final Task task, final DependencyTree tree) { -+ this.task = task; -+ this.id = tree.nextId(); -+ this.tree = tree; -+ } -+ } -+ -+ private static final class Task implements PrioritisedExecutor.PrioritisedTask, Runnable { -+ -+ // task specific fields -+ private final RadiusAwarePrioritisedExecutor scheduler; -+ private final int chunkX; -+ private final int chunkZ; -+ private final int radius; -+ private Runnable run; -+ private PrioritisedExecutor.Priority priority; -+ -+ private DependencyNode dependencyNode; -+ private PrioritisedExecutor.PrioritisedTask queuedTask; -+ -+ private Task(final RadiusAwarePrioritisedExecutor scheduler, final int chunkX, final int chunkZ, final int radius, -+ final Runnable run, final PrioritisedExecutor.Priority priority) { -+ this.scheduler = scheduler; -+ this.chunkX = chunkX; -+ this.chunkZ = chunkZ; -+ this.radius = radius; -+ this.run = run; -+ this.priority = priority; -+ } -+ -+ private boolean isFiniteRadius() { -+ return this.radius >= 0; -+ } -+ -+ private PrioritisedExecutor.PrioritisedTask pushTask(final PrioritisedExecutor executor) { -+ return this.queuedTask = executor.createTask(this, this.priority); -+ } -+ -+ private void executeTask() { -+ final Runnable run = this.run; -+ this.run = null; -+ run.run(); -+ } -+ -+ private static void scheduleTasks(final List toSchedule) { -+ if (toSchedule != null) { -+ for (int i = 0, len = toSchedule.size(); i < len; ++i) { -+ toSchedule.get(i).queue(); -+ } -+ } -+ } -+ -+ private void returnNode() { -+ final List toSchedule; -+ synchronized (this.scheduler) { -+ final DependencyNode node = this.dependencyNode; -+ this.dependencyNode = null; -+ toSchedule = node.tree.returnNode(node); -+ } -+ -+ scheduleTasks(toSchedule); -+ } -+ -+ @Override -+ public void run() { -+ final Runnable run = this.run; -+ this.run = null; -+ try { -+ run.run(); -+ } finally { -+ this.returnNode(); -+ } -+ } -+ -+ @Override -+ public boolean queue() { -+ final List toSchedule; -+ synchronized (this.scheduler) { -+ if (this.queuedTask != null || this.dependencyNode != null || this.priority == PrioritisedExecutor.Priority.COMPLETING) { -+ return false; -+ } -+ -+ toSchedule = this.scheduler.queue(this, this.priority); -+ } -+ -+ scheduleTasks(toSchedule); -+ return true; -+ } -+ -+ @Override -+ public boolean cancel() { -+ final PrioritisedExecutor.PrioritisedTask task; -+ synchronized (this.scheduler) { -+ if ((task = this.queuedTask) == null) { -+ if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { -+ return false; -+ } -+ -+ this.priority = PrioritisedExecutor.Priority.COMPLETING; -+ if (this.dependencyNode != null) { -+ this.dependencyNode.purged = true; -+ this.dependencyNode = null; -+ } -+ -+ return true; -+ } -+ } -+ -+ if (task.cancel()) { -+ // must manually return the node -+ this.run = null; -+ this.returnNode(); -+ return true; -+ } -+ return false; -+ } -+ -+ @Override -+ public boolean execute() { -+ final PrioritisedExecutor.PrioritisedTask task; -+ synchronized (this.scheduler) { -+ if ((task = this.queuedTask) == null) { -+ if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { -+ return false; -+ } -+ -+ this.priority = PrioritisedExecutor.Priority.COMPLETING; -+ if (this.dependencyNode != null) { -+ this.dependencyNode.purged = true; -+ this.dependencyNode = null; -+ } -+ // fall through to execution logic -+ } -+ } -+ -+ if (task != null) { -+ // will run the return node logic automatically -+ return task.execute(); -+ } else { -+ // don't run node removal/insertion logic, we aren't actually removed from the dependency tree -+ this.executeTask(); -+ return true; -+ } -+ } -+ -+ @Override -+ public PrioritisedExecutor.Priority getPriority() { -+ final PrioritisedExecutor.PrioritisedTask task; -+ synchronized (this.scheduler) { -+ if ((task = this.queuedTask) == null) { -+ return this.priority; -+ } -+ } -+ -+ return task.getPriority(); -+ } -+ -+ @Override -+ public boolean setPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } -+ -+ final PrioritisedExecutor.PrioritisedTask task; -+ List toSchedule = null; -+ synchronized (this.scheduler) { -+ if ((task = this.queuedTask) == null) { -+ if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { -+ return false; -+ } -+ -+ if (this.priority == priority) { -+ return true; -+ } -+ -+ this.priority = priority; -+ if (this.dependencyNode != null) { -+ // need to re-insert node -+ this.dependencyNode.purged = true; -+ this.dependencyNode = null; -+ toSchedule = this.scheduler.queue(this, priority); -+ } -+ } -+ } -+ -+ if (task != null) { -+ return task.setPriority(priority); -+ } -+ -+ scheduleTasks(toSchedule); -+ -+ return true; -+ } -+ -+ @Override -+ public boolean raisePriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } -+ -+ final PrioritisedExecutor.PrioritisedTask task; -+ List toSchedule = null; -+ synchronized (this.scheduler) { -+ if ((task = this.queuedTask) == null) { -+ if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { -+ return false; -+ } -+ -+ if (this.priority.isHigherOrEqualPriority(priority)) { -+ return true; -+ } -+ -+ this.priority = priority; -+ if (this.dependencyNode != null) { -+ // need to re-insert node -+ this.dependencyNode.purged = true; -+ this.dependencyNode = null; -+ toSchedule = this.scheduler.queue(this, priority); -+ } -+ } -+ } -+ -+ if (task != null) { -+ return task.raisePriority(priority); -+ } -+ -+ scheduleTasks(toSchedule); -+ -+ return true; -+ } -+ -+ @Override -+ public boolean lowerPriority(final PrioritisedExecutor.Priority priority) { -+ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) { -+ throw new IllegalArgumentException("Invalid priority " + priority); -+ } -+ -+ final PrioritisedExecutor.PrioritisedTask task; -+ List toSchedule = null; -+ synchronized (this.scheduler) { -+ if ((task = this.queuedTask) == null) { -+ if (this.priority == PrioritisedExecutor.Priority.COMPLETING) { -+ return false; -+ } -+ -+ if (this.priority.isLowerOrEqualPriority(priority)) { -+ return true; -+ } -+ -+ this.priority = priority; -+ if (this.dependencyNode != null) { -+ // need to re-insert node -+ this.dependencyNode.purged = true; -+ this.dependencyNode = null; -+ toSchedule = this.scheduler.queue(this, priority); -+ } -+ } -+ } -+ -+ if (task != null) { -+ return task.lowerPriority(priority); -+ } -+ -+ scheduleTasks(toSchedule); -+ -+ return true; -+ } -+ } -+} -diff --git a/src/main/java/io/papermc/paper/command/PaperCommand.java b/src/main/java/io/papermc/paper/command/PaperCommand.java -index a3f43dccb796f30f6e9389e1ae182f06e9024e96..92bf78112c1cc75173e4e735bdeec9695fe10df6 100644 ---- a/src/main/java/io/papermc/paper/command/PaperCommand.java -+++ b/src/main/java/io/papermc/paper/command/PaperCommand.java -@@ -43,6 +43,7 @@ public final class PaperCommand extends Command { - commands.put(Set.of("mobcaps", "playermobcaps"), new MobcapsCommand()); - commands.put(Set.of("dumplisteners"), new DumpListenersCommand()); - commands.put(Set.of("fixlight"), new FixLightCommand()); -+ commands.put(Set.of("debug", "chunkinfo", "holderinfo"), new ChunkDebugCommand()); - - return commands.entrySet().stream() - .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..61fa1ab0f6550fec2b9d035ea45c72627eb990d4 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/command/subcommands/ChunkDebugCommand.java -@@ -0,0 +1,265 @@ -+package io.papermc.paper.command.subcommands; -+ -+import io.papermc.paper.command.CommandUtil; -+import io.papermc.paper.command.PaperSubcommand; -+import java.io.File; -+import java.time.LocalDateTime; -+import java.time.format.DateTimeFormatter; -+import java.util.ArrayList; -+import java.util.Collections; -+import java.util.List; -+import java.util.Locale; -+import io.papermc.paper.util.MCUtil; -+import net.minecraft.server.MinecraftServer; -+import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.server.level.FullChunkStatus; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.ImposterProtoChunk; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.ProtoChunk; -+import org.bukkit.Bukkit; -+import org.bukkit.command.CommandSender; -+import org.bukkit.craftbukkit.CraftWorld; -+import org.checkerframework.checker.nullness.qual.NonNull; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.checkerframework.framework.qual.DefaultQualifier; -+ -+import static net.kyori.adventure.text.Component.text; -+import static net.kyori.adventure.text.format.NamedTextColor.BLUE; -+import static net.kyori.adventure.text.format.NamedTextColor.DARK_AQUA; -+import static net.kyori.adventure.text.format.NamedTextColor.GREEN; -+import static net.kyori.adventure.text.format.NamedTextColor.RED; -+ -+@DefaultQualifier(NonNull.class) -+public final class ChunkDebugCommand implements PaperSubcommand { -+ @Override -+ public boolean execute(final CommandSender sender, final String subCommand, final String[] args) { -+ switch (subCommand) { -+ case "debug" -> this.doDebug(sender, args); -+ case "chunkinfo" -> this.doChunkInfo(sender, args); -+ case "holderinfo" -> this.doHolderInfo(sender, args); -+ } -+ return true; -+ } -+ -+ @Override -+ public List tabComplete(final CommandSender sender, final String subCommand, final String[] args) { -+ switch (subCommand) { -+ case "debug" -> { -+ if (args.length == 1) { -+ return CommandUtil.getListMatchingLast(sender, args, "help", "chunks"); -+ } -+ } -+ case "holderinfo" -> { -+ List worldNames = new ArrayList<>(); -+ worldNames.add("*"); -+ for (org.bukkit.World world : Bukkit.getWorlds()) { -+ worldNames.add(world.getName()); -+ } -+ if (args.length == 1) { -+ return CommandUtil.getListMatchingLast(sender, args, worldNames); -+ } -+ } -+ case "chunkinfo" -> { -+ List worldNames = new ArrayList<>(); -+ worldNames.add("*"); -+ for (org.bukkit.World world : Bukkit.getWorlds()) { -+ worldNames.add(world.getName()); -+ } -+ if (args.length == 1) { -+ return CommandUtil.getListMatchingLast(sender, args, worldNames); -+ } -+ } -+ } -+ return Collections.emptyList(); -+ } -+ -+ private void doChunkInfo(final CommandSender sender, final String[] args) { -+ List worlds; -+ if (args.length < 1 || args[0].equals("*")) { -+ worlds = Bukkit.getWorlds(); -+ } else { -+ worlds = new ArrayList<>(args.length); -+ for (final String arg : args) { -+ org.bukkit.@Nullable World world = Bukkit.getWorld(arg); -+ if (world == null) { -+ sender.sendMessage(text("World '" + arg + "' is invalid", RED)); -+ return; -+ } -+ worlds.add(world); -+ } -+ } -+ -+ int accumulatedTotal = 0; -+ int accumulatedInactive = 0; -+ int accumulatedBorder = 0; -+ int accumulatedTicking = 0; -+ int accumulatedEntityTicking = 0; -+ -+ for (final org.bukkit.World bukkitWorld : worlds) { -+ final ServerLevel world = ((CraftWorld) bukkitWorld).getHandle(); -+ -+ int total = 0; -+ int inactive = 0; -+ int full = 0; -+ int blockTicking = 0; -+ int entityTicking = 0; -+ -+ for (final ChunkHolder chunk : io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(world)) { -+ if (chunk.getFullChunkNowUnchecked() == null) { -+ continue; -+ } -+ -+ ++total; -+ -+ FullChunkStatus state = chunk.getFullStatus(); -+ -+ switch (state) { -+ case INACCESSIBLE -> ++inactive; -+ case FULL -> ++full; -+ case BLOCK_TICKING -> ++blockTicking; -+ case ENTITY_TICKING -> ++entityTicking; -+ } -+ } -+ -+ accumulatedTotal += total; -+ accumulatedInactive += inactive; -+ accumulatedBorder += full; -+ accumulatedTicking += blockTicking; -+ accumulatedEntityTicking += entityTicking; -+ -+ sender.sendMessage(text().append(text("Chunks in ", BLUE), text(bukkitWorld.getName(), GREEN), text(":"))); -+ sender.sendMessage(text().color(DARK_AQUA).append( -+ text("Total: ", BLUE), text(total), -+ text(" Inactive: ", BLUE), text(inactive), -+ text(" Full: ", BLUE), text(full), -+ text(" Block Ticking: ", BLUE), text(blockTicking), -+ text(" Entity Ticking: ", BLUE), text(entityTicking) -+ )); -+ } -+ if (worlds.size() > 1) { -+ sender.sendMessage(text().append(text("Chunks in ", BLUE), text("all listed worlds", GREEN), text(":", DARK_AQUA))); -+ sender.sendMessage(text().color(DARK_AQUA).append( -+ text("Total: ", BLUE), text(accumulatedTotal), -+ text(" Inactive: ", BLUE), text(accumulatedInactive), -+ text(" Full: ", BLUE), text(accumulatedBorder), -+ text(" Block Ticking: ", BLUE), text(accumulatedTicking), -+ text(" Entity Ticking: ", BLUE), text(accumulatedEntityTicking) -+ )); -+ } -+ } -+ -+ private void doHolderInfo(final CommandSender sender, final String[] args) { -+ List worlds; -+ if (args.length < 1 || args[0].equals("*")) { -+ worlds = Bukkit.getWorlds(); -+ } else { -+ worlds = new ArrayList<>(args.length); -+ for (final String arg : args) { -+ org.bukkit.@Nullable World world = Bukkit.getWorld(arg); -+ if (world == null) { -+ sender.sendMessage(text("World '" + arg + "' is invalid", RED)); -+ return; -+ } -+ worlds.add(world); -+ } -+ } -+ -+ int accumulatedTotal = 0; -+ int accumulatedCanUnload = 0; -+ int accumulatedNull = 0; -+ int accumulatedReadOnly = 0; -+ int accumulatedProtoChunk = 0; -+ int accumulatedFullChunk = 0; -+ -+ for (final org.bukkit.World bukkitWorld : worlds) { -+ final ServerLevel world = ((CraftWorld) bukkitWorld).getHandle(); -+ -+ int total = 0; -+ int canUnload = 0; -+ int nullChunks = 0; -+ int readOnly = 0; -+ int protoChunk = 0; -+ int fullChunk = 0; -+ -+ for (final ChunkHolder chunk : world.chunkTaskScheduler.chunkHolderManager.getOldChunkHolders()) { // Paper - change updating chunks map -+ final ChunkAccess lastChunk = chunk.getAvailableChunkNow(); -+ -+ ++total; -+ -+ if (lastChunk == null) { -+ ++nullChunks; -+ } else if (lastChunk instanceof ImposterProtoChunk) { -+ ++readOnly; -+ } else if (lastChunk instanceof ProtoChunk) { -+ ++protoChunk; -+ } else if (lastChunk instanceof LevelChunk) { -+ ++fullChunk; -+ } -+ -+ if (chunk.newChunkHolder.isSafeToUnload() == null) { -+ ++canUnload; -+ } -+ } -+ -+ accumulatedTotal += total; -+ accumulatedCanUnload += canUnload; -+ accumulatedNull += nullChunks; -+ accumulatedReadOnly += readOnly; -+ accumulatedProtoChunk += protoChunk; -+ accumulatedFullChunk += fullChunk; -+ -+ sender.sendMessage(text().append(text("Chunks in ", BLUE), text(bukkitWorld.getName(), GREEN), text(":"))); -+ sender.sendMessage(text().color(DARK_AQUA).append( -+ text("Total: ", BLUE), text(total), -+ text(" Unloadable: ", BLUE), text(canUnload), -+ text(" Null: ", BLUE), text(nullChunks), -+ text(" ReadOnly: ", BLUE), text(readOnly), -+ text(" Proto: ", BLUE), text(protoChunk), -+ text(" Full: ", BLUE), text(fullChunk) -+ )); -+ } -+ if (worlds.size() > 1) { -+ sender.sendMessage(text().append(text("Chunks in ", BLUE), text("all listed worlds", GREEN), text(":", DARK_AQUA))); -+ sender.sendMessage(text().color(DARK_AQUA).append( -+ text("Total: ", BLUE), text(accumulatedTotal), -+ text(" Unloadable: ", BLUE), text(accumulatedCanUnload), -+ text(" Null: ", BLUE), text(accumulatedNull), -+ text(" ReadOnly: ", BLUE), text(accumulatedReadOnly), -+ text(" Proto: ", BLUE), text(accumulatedProtoChunk), -+ text(" Full: ", BLUE), text(accumulatedFullChunk) -+ )); -+ } -+ } -+ -+ private void doDebug(final CommandSender sender, final String[] args) { -+ if (args.length < 1) { -+ sender.sendMessage(text("Use /paper debug [chunks] help for more information on a specific command", RED)); -+ return; -+ } -+ -+ final String debugType = args[0].toLowerCase(Locale.ROOT); -+ switch (debugType) { -+ case "chunks" -> { -+ if (args.length >= 2 && args[1].toLowerCase(Locale.ROOT).equals("help")) { -+ sender.sendMessage(text("Use /paper debug chunks [world] to dump loaded chunk information to a file", RED)); -+ break; -+ } -+ File file = new File(new File(new File("."), "debug"), -+ "chunks-" + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + ".txt"); -+ sender.sendMessage(text("Writing chunk information dump to " + file, GREEN)); -+ try { -+ MCUtil.dumpChunks(file, false); -+ sender.sendMessage(text("Successfully written chunk information!", GREEN)); -+ } catch (Throwable thr) { -+ MinecraftServer.LOGGER.warn("Failed to dump chunk information to file " + file.toString(), thr); -+ sender.sendMessage(text("Failed to dump chunk information, see console", RED)); -+ } -+ } -+ // "help" & default -+ default -> sender.sendMessage(text("Use /paper debug [chunks] help for more information on a specific command", RED)); -+ } -+ } -+ -+} -diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 4de88f74182bb596c6b5ad0351cc0dacefd0ce96..2874bc3001c4e7d9191e47ba512c5a68369c21f1 100644 ---- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -+++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -29,6 +29,45 @@ public class GlobalConfiguration extends ConfigurationPart { - public static GlobalConfiguration get() { - return instance; - } -+ -+ public ChunkLoadingBasic chunkLoadingBasic; -+ -+ public class ChunkLoadingBasic extends ConfigurationPart { -+ @Comment("The maximum rate in chunks per second that the server will send to any individual player. Set to -1 to disable this limit.") -+ public double playerMaxChunkSendRate = 75.0; -+ -+ @Comment( -+ "The maximum rate at which chunks will load for any individual player. " + -+ "Note that this setting also affects chunk generations, since a chunk load is always first issued to test if a" + -+ "chunk is already generated. Set to -1 to disable this limit." -+ ) -+ public double playerMaxChunkLoadRate = 100.0; -+ -+ @Comment("The maximum rate at which chunks will generate for any individual player. Set to -1 to disable this limit.") -+ public double playerMaxChunkGenerateRate = -1.0; -+ } -+ -+ public ChunkLoadingAdvanced chunkLoadingAdvanced; -+ -+ public class ChunkLoadingAdvanced extends ConfigurationPart { -+ @Comment( -+ "Set to true if the server will match the chunk send radius that clients have configured" + -+ "in their view distance settings if the client is less-than the server's send distance." -+ ) -+ public boolean autoConfigSendDistance = true; -+ -+ @Comment( -+ "Specifies the maximum amount of concurrent chunk loads that an individual player can have." + -+ "Set to 0 to let the server configure it automatically per player, or set it to -1 to disable the limit." -+ ) -+ public int playerMaxConcurrentChunkLoads = 0; -+ -+ @Comment( -+ "Specifies the maximum amount of concurrent chunk generations that an individual player can have." + -+ "Set to 0 to let the server configure it automatically per player, or set it to -1 to disable the limit." -+ ) -+ public int playerMaxConcurrentChunkGenerates = 0; -+ } - static void set(GlobalConfiguration instance) { - GlobalConfiguration.instance = instance; - } -@@ -130,21 +169,6 @@ public class GlobalConfiguration extends ConfigurationPart { - public int incomingPacketThreshold = 300; - } - -- public ChunkLoading chunkLoading; -- -- public class ChunkLoading extends ConfigurationPart { -- public int minLoadRadius = 2; -- public int maxConcurrentSends = 2; -- public boolean autoconfigSendDistance = true; -- public double targetPlayerChunkSendRate = 100.0; -- public double globalMaxChunkSendRate = -1.0; -- public boolean enableFrustumPriority = false; -- public double globalMaxChunkLoadRate = -1.0; -- public double playerMaxConcurrentLoads = 20.0; -- public double globalMaxConcurrentLoads = 500.0; -- public double playerMaxChunkLoadRate = -1.0; -- } -- - public UnsupportedSettings unsupportedSettings; - - public class UnsupportedSettings extends ConfigurationPart { -@@ -201,7 +225,7 @@ public class GlobalConfiguration extends ConfigurationPart { - - @PostProcess - private void postProcess() { -- //io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.init(this); -+ io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.init(this); - } - } - -diff --git a/src/main/java/io/papermc/paper/threadedregions/TickRegions.java b/src/main/java/io/papermc/paper/threadedregions/TickRegions.java -new file mode 100644 -index 0000000000000000000000000000000000000000..d5d39e9c1f326e91010237b0db80d527ac52f4d6 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/threadedregions/TickRegions.java -@@ -0,0 +1,9 @@ -+package io.papermc.paper.threadedregions; -+ -+// placeholder class for Folia -+public class TickRegions { -+ -+ public static int getRegionChunkShift() { -+ return 4; -+ } -+} -diff --git a/src/main/java/io/papermc/paper/util/IntervalledCounter.java b/src/main/java/io/papermc/paper/util/IntervalledCounter.java -index cea9c098ade00ee87b8efc8164ab72f5279758f0..197224e31175252d8438a8df585bbb65f2288d7f 100644 ---- a/src/main/java/io/papermc/paper/util/IntervalledCounter.java -+++ b/src/main/java/io/papermc/paper/util/IntervalledCounter.java -@@ -2,6 +2,8 @@ package io.papermc.paper.util; - - public final class IntervalledCounter { - -+ private static final int INITIAL_SIZE = 8; -+ - protected long[] times; - protected long[] counts; - protected final long interval; -@@ -11,8 +13,8 @@ public final class IntervalledCounter { - protected int tail; // exclusive - - public IntervalledCounter(final long interval) { -- this.times = new long[8]; -- this.counts = new long[8]; -+ this.times = new long[INITIAL_SIZE]; -+ this.counts = new long[INITIAL_SIZE]; - this.interval = interval; - } - -@@ -67,13 +69,13 @@ public final class IntervalledCounter { - this.tail = nextTail; - } - -- public void updateAndAdd(final int count) { -+ public void updateAndAdd(final long count) { - final long currTime = System.nanoTime(); - this.updateCurrentTime(currTime); - this.addTime(currTime, count); - } - -- public void updateAndAdd(final int count, final long currTime) { -+ public void updateAndAdd(final long count, final long currTime) { - this.updateCurrentTime(currTime); - this.addTime(currTime, count); - } -@@ -93,9 +95,13 @@ public final class IntervalledCounter { - this.tail = size; - - if (tail >= head) { -+ // sequentially ordered from [head, tail) - System.arraycopy(oldElements, head, newElements, 0, size); - System.arraycopy(oldCounts, head, newCounts, 0, size); - } else { -+ // ordered from [head, length) -+ // then followed by [0, tail) -+ - System.arraycopy(oldElements, head, newElements, 0, oldElements.length - head); - System.arraycopy(oldElements, 0, newElements, oldElements.length - head, tail); - -@@ -106,10 +112,18 @@ public final class IntervalledCounter { - - // returns in units per second - public double getRate() { -- return this.size() / (this.interval * 1.0e-9); -+ return (double)this.sum / ((double)this.interval * 1.0E-9); -+ } -+ -+ public long getInterval() { -+ return this.interval; - } - -- public long size() { -+ public long getSum() { - return this.sum; - } -+ -+ public int totalDataPoints() { -+ return this.tail >= this.head ? (this.tail - this.head) : (this.tail + (this.counts.length - this.head)); -+ } - } -diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java -index c95a0af32178fe24448a5ae7a229c86ec883e8de..1d6b3fe2ce240af4ede61588795456b046eee6c9 100644 ---- a/src/main/java/io/papermc/paper/util/MCUtil.java -+++ b/src/main/java/io/papermc/paper/util/MCUtil.java -@@ -7,17 +7,30 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder; - import io.papermc.paper.math.BlockPosition; - import io.papermc.paper.math.FinePosition; - import io.papermc.paper.math.Position; -+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 it.unimi.dsi.fastutil.objects.ReferenceArrayList; - import net.minecraft.core.BlockPos; - import net.minecraft.core.Direction; - import net.minecraft.core.Vec3i; - import net.minecraft.server.MinecraftServer; -+import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.server.level.ChunkMap; -+import net.minecraft.server.level.DistanceManager; - import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.server.level.Ticket; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.level.ChunkPos; - import net.minecraft.world.level.ClipContext; - import net.minecraft.world.level.Level; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.status.ChunkStatus; - import net.minecraft.world.phys.Vec3; - import org.apache.commons.lang.exception.ExceptionUtils; - import com.mojang.authlib.GameProfile; -@@ -30,8 +43,11 @@ import org.spigotmc.AsyncCatcher; - - import javax.annotation.Nonnull; - import javax.annotation.Nullable; -+import java.io.*; -+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; -@@ -532,6 +548,98 @@ public final class MCUtil { - } - } - -+ public static ChunkStatus getChunkStatus(ChunkHolder chunk) { -+ return chunk.getChunkHolderStatus(); -+ } -+ -+ public static void dumpChunks(File file, boolean watchdog) throws IOException { -+ file.getParentFile().mkdirs(); -+ file.createNewFile(); -+ ReferenceArrayList worlds = new ReferenceArrayList<>(org.bukkit.Bukkit.getWorlds()); -+ ReferenceArrayList loadedWorlds = new ReferenceArrayList<>(worlds); -+ JsonObject data = new JsonObject(); -+ -+ data.addProperty("server-version", org.bukkit.Bukkit.getVersion()); -+ data.addProperty("data-version", 1); -+ -+ { -+ JsonArray players = new JsonArray(); -+ data.add("all-players", players); -+ List playerList = MinecraftServer.getServer().getPlayerList().players; -+ for (ServerPlayer player : playerList) { -+ JsonObject playerData = new JsonObject(); -+ players.add(playerData); -+ -+ Level playerWorld = player.level(); -+ org.bukkit.World craftWorld = playerWorld.getWorld(); -+ Entity.RemovalReason removalReason = player.getRemovalReason(); -+ -+ playerData.addProperty("name", player.getScoreboardName()); -+ playerData.addProperty("x", player.getX()); -+ playerData.addProperty("y", player.getY()); -+ playerData.addProperty("z", player.getZ()); -+ playerData.addProperty("world", playerWorld == null ? "null world" : craftWorld.getName()); -+ playerData.addProperty("removalReason", removalReason == null ? "null" : removalReason.name()); -+ -+ if (!worlds.contains(craftWorld)) { -+ worlds.add(craftWorld); -+ } -+ } -+ } -+ -+ JsonArray chunkWaitInformation = new JsonArray(); -+ data.add("chunk-wait-infos", chunkWaitInformation); -+ -+ for (io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.ChunkInfo chunkInfo : io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.getChunkInfos()) { -+ chunkWaitInformation.add(chunkInfo.toString()); -+ } -+ -+ JsonArray worldsData = new JsonArray(); -+ -+ for (org.bukkit.World bukkitWorld : worlds) { -+ JsonObject worldData = new JsonObject(); -+ -+ ServerLevel world = ((org.bukkit.craftbukkit.CraftWorld)bukkitWorld).getHandle(); -+ List players = world.players(); -+ -+ worldData.addProperty("is-loaded", loadedWorlds.contains(bukkitWorld)); -+ worldData.addProperty("name", world.getWorld().getName()); -+ worldData.addProperty("view-distance", world.getWorld().getViewDistance()); // Paper - replace chunk loader system -+ worldData.addProperty("tick-view-distance", world.getWorld().getSimulationDistance()); // Paper - replace chunk loader system -+ -+ JsonArray playersData = new JsonArray(); -+ -+ for (ServerPlayer player : players) { -+ JsonObject playerData = new JsonObject(); -+ -+ playerData.addProperty("name", player.getScoreboardName()); -+ playerData.addProperty("x", player.getX()); -+ playerData.addProperty("y", player.getY()); -+ playerData.addProperty("z", player.getZ()); -+ -+ playersData.add(playerData); -+ } -+ -+ worldData.add("players", playersData); -+ worldData.add("chunk-data", watchdog ? world.chunkTaskScheduler.chunkHolderManager.getDebugJsonForWatchdog() : world.chunkTaskScheduler.chunkHolderManager.getDebugJson()); -+ worldsData.add(worldData); -+ } -+ -+ data.add("worlds", worldsData); -+ -+ StringWriter stringWriter = new StringWriter(); -+ JsonWriter jsonWriter = new JsonWriter(stringWriter); -+ jsonWriter.setIndent(" "); -+ jsonWriter.setLenient(false); -+ Streams.write(data, jsonWriter); -+ -+ String fileData = stringWriter.toString(); -+ -+ try (PrintStream out = new PrintStream(new FileOutputStream(file), false, StandardCharsets.UTF_8)) { -+ out.print(fileData); -+ } -+ } -+ - public static int getTicketLevelFor(net.minecraft.world.level.chunk.status.ChunkStatus status) { - return net.minecraft.server.level.ChunkMap.MAX_VIEW_DISTANCE + net.minecraft.world.level.chunk.status.ChunkStatus.getDistance(status); - } -diff --git a/src/main/java/io/papermc/paper/util/TickThread.java b/src/main/java/io/papermc/paper/util/TickThread.java -index 73e83d56a340f0c7dcb8ff737d621003e72c6de4..bdaf062f9b66ceab303a0807eca301342886a8ea 100644 ---- a/src/main/java/io/papermc/paper/util/TickThread.java -+++ b/src/main/java/io/papermc/paper/util/TickThread.java -@@ -1,12 +1,20 @@ - package io.papermc.paper.util; - -+import net.minecraft.core.BlockPos; - import net.minecraft.server.MinecraftServer; - import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.server.network.ServerGamePacketListenerImpl; -+import net.minecraft.util.Mth; - import net.minecraft.world.entity.Entity; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.phys.AABB; -+import net.minecraft.world.phys.Vec3; - import org.bukkit.Bukkit; - import java.util.concurrent.atomic.AtomicInteger; - --public final class TickThread extends Thread { -+public class TickThread extends Thread { - - public static final boolean STRICT_THREAD_CHECKS = Boolean.getBoolean("paper.strict-thread-checks"); - -@@ -16,6 +24,10 @@ public final class TickThread extends Thread { - } - } - -+ /** -+ * @deprecated -+ */ -+ @Deprecated - public static void softEnsureTickThread(final String reason) { - if (!STRICT_THREAD_CHECKS) { - return; -@@ -23,6 +35,10 @@ public final class TickThread extends Thread { - ensureTickThread(reason); - } - -+ /** -+ * @deprecated -+ */ -+ @Deprecated - public static void ensureTickThread(final String reason) { - if (!isTickThread()) { - MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); -@@ -30,6 +46,20 @@ public final class TickThread extends Thread { - } - } - -+ public static void ensureTickThread(final ServerLevel world, final BlockPos pos, final String reason) { -+ if (!isTickThreadFor(world, pos)) { -+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); -+ throw new IllegalStateException(reason); -+ } -+ } -+ -+ public static void ensureTickThread(final ServerLevel world, final ChunkPos pos, final String reason) { -+ if (!isTickThreadFor(world, pos)) { -+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); -+ throw new IllegalStateException(reason); -+ } -+ } -+ - 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()); -@@ -44,6 +74,20 @@ public final class TickThread extends Thread { - } - } - -+ public static void ensureTickThread(final ServerLevel world, final AABB aabb, final String reason) { -+ if (!isTickThreadFor(world, aabb)) { -+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); -+ throw new IllegalStateException(reason); -+ } -+ } -+ -+ public static void ensureTickThread(final ServerLevel world, final double blockX, final double blockZ, final String reason) { -+ if (!isTickThreadFor(world, blockX, blockZ)) { -+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); -+ throw new IllegalStateException(reason); -+ } -+ } -+ - public final int id; /* We don't override getId as the spec requires that it be unique (with respect to all other threads) */ - - private static final AtomicInteger ID_GENERATOR = new AtomicInteger(); -@@ -66,13 +110,45 @@ public final class TickThread extends Thread { - } - - public static boolean isTickThread() { -- return Bukkit.isPrimaryThread(); -+ return Thread.currentThread() instanceof TickThread; -+ } -+ -+ public static boolean isShutdownThread() { -+ return false; -+ } -+ -+ public static boolean isTickThreadFor(final ServerLevel world, final BlockPos pos) { -+ return isTickThread(); -+ } -+ -+ public static boolean isTickThreadFor(final ServerLevel world, final ChunkPos pos) { -+ return isTickThread(); -+ } -+ -+ public static boolean isTickThreadFor(final ServerLevel world, final Vec3 pos) { -+ return isTickThread(); - } - - public static boolean isTickThreadFor(final ServerLevel world, final int chunkX, final int chunkZ) { - return isTickThread(); - } - -+ public static boolean isTickThreadFor(final ServerLevel world, final AABB aabb) { -+ return isTickThread(); -+ } -+ -+ public static boolean isTickThreadFor(final ServerLevel world, final double blockX, final double blockZ) { -+ return isTickThread(); -+ } -+ -+ public static boolean isTickThreadFor(final ServerLevel world, final Vec3 position, final Vec3 deltaMovement, final int buffer) { -+ return isTickThread(); -+ } -+ -+ public static boolean isTickThreadFor(final ServerLevel world, final int fromChunkX, final int fromChunkZ, final int toChunkX, final int toChunkZ) { -+ return isTickThread(); -+ } -+ - public static boolean isTickThreadFor(final ServerLevel world, final int chunkX, final int chunkZ, final int radius) { - return isTickThread(); - } -diff --git a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c78cbec447032de9fe69748591bef6be300160ed ---- /dev/null -+++ b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java -@@ -0,0 +1,607 @@ -+package io.papermc.paper.world; -+ -+import com.destroystokyo.paper.util.maplist.EntityList; -+import io.papermc.paper.chunk.system.entity.EntityLookup; -+import io.papermc.paper.util.TickThread; -+import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; -+import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.server.level.FullChunkStatus; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.util.Mth; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.entity.EntityType; -+import net.minecraft.world.entity.boss.EnderDragonPart; -+import net.minecraft.world.entity.boss.enderdragon.EnderDragon; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.chunk.storage.EntityStorage; -+import net.minecraft.world.level.entity.Visibility; -+import net.minecraft.world.phys.AABB; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import java.util.ArrayList; -+import java.util.Arrays; -+import java.util.Iterator; -+import java.util.List; -+import java.util.function.Predicate; -+import org.bukkit.event.entity.EntityRemoveEvent; -+ -+public final class ChunkEntitySlices { -+ -+ protected final int minSection; -+ protected final int maxSection; -+ public final int chunkX; -+ public final int chunkZ; -+ protected final ServerLevel world; -+ -+ protected final EntityCollectionBySection allEntities; -+ protected final EntityCollectionBySection hardCollidingEntities; -+ protected final Reference2ObjectOpenHashMap, EntityCollectionBySection> entitiesByClass; -+ protected final EntityList entities = new EntityList(); -+ -+ public FullChunkStatus status; -+ -+ protected boolean isTransient; -+ -+ public boolean isTransient() { -+ return this.isTransient; -+ } -+ -+ public void setTransient(final boolean value) { -+ this.isTransient = value; -+ } -+ -+ // TODO implement container search optimisations -+ -+ public ChunkEntitySlices(final ServerLevel world, final int chunkX, final int chunkZ, final FullChunkStatus status, -+ final int minSection, final int maxSection) { // inclusive, inclusive -+ this.minSection = minSection; -+ this.maxSection = maxSection; -+ this.chunkX = chunkX; -+ this.chunkZ = chunkZ; -+ this.world = world; -+ -+ this.allEntities = new EntityCollectionBySection(this); -+ this.hardCollidingEntities = new EntityCollectionBySection(this); -+ this.entitiesByClass = new Reference2ObjectOpenHashMap<>(); -+ -+ this.status = status; -+ } -+ -+ // Paper start - optimise CraftChunk#getEntities -+ public org.bukkit.entity.Entity[] getChunkEntities() { -+ List ret = new java.util.ArrayList<>(); -+ final Entity[] entities = this.entities.getRawData(); -+ for (int i = 0, size = Math.min(entities.length, this.entities.size()); i < size; ++i) { -+ final Entity entity = entities[i]; -+ if (entity == null) { -+ continue; -+ } -+ final org.bukkit.entity.Entity bukkit = entity.getBukkitEntity(); -+ if (bukkit != null && bukkit.isValid()) { -+ ret.add(bukkit); -+ } -+ } -+ -+ return ret.toArray(new org.bukkit.entity.Entity[0]); -+ } -+ -+ public CompoundTag save() { -+ final int len = this.entities.size(); -+ if (len == 0) { -+ return null; -+ } -+ -+ final Entity[] rawData = this.entities.getRawData(); -+ final List collectedEntities = new ArrayList<>(len); -+ for (int i = 0; i < len; ++i) { -+ final Entity entity = rawData[i]; -+ if (entity.shouldBeSaved()) { -+ collectedEntities.add(entity); -+ } -+ } -+ -+ if (collectedEntities.isEmpty()) { -+ return null; -+ } -+ -+ return EntityStorage.saveEntityChunk(collectedEntities, new ChunkPos(this.chunkX, this.chunkZ), this.world); -+ } -+ -+ // returns true if this chunk has transient entities remaining -+ public boolean unload() { -+ final int len = this.entities.size(); -+ final Entity[] collectedEntities = Arrays.copyOf(this.entities.getRawData(), len); -+ -+ for (int i = 0; i < len; ++i) { -+ final Entity entity = collectedEntities[i]; -+ if (entity.isRemoved()) { -+ // removed by us below -+ continue; -+ } -+ if (entity.shouldBeSaved()) { -+ entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, EntityRemoveEvent.Cause.UNLOAD); -+ if (entity.isVehicle()) { -+ // we cannot assume that these entities are contained within this chunk, because entities can -+ // desync - so we need to remove them all -+ for (final Entity passenger : entity.getIndirectPassengers()) { -+ passenger.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, EntityRemoveEvent.Cause.UNLOAD); -+ } -+ } -+ } -+ } -+ -+ return this.entities.size() != 0; -+ } -+ -+ private List getAllEntities() { -+ final int len = this.entities.size(); -+ if (len == 0) { -+ return new ArrayList<>(); -+ } -+ -+ final Entity[] rawData = this.entities.getRawData(); -+ final List collectedEntities = new ArrayList<>(len); -+ for (int i = 0; i < len; ++i) { -+ collectedEntities.add(rawData[i]); -+ } -+ -+ return collectedEntities; -+ } -+ -+ public void callEntitiesLoadEvent() { -+ CraftEventFactory.callEntitiesLoadEvent(this.world, new ChunkPos(this.chunkX, this.chunkZ), this.getAllEntities()); -+ } -+ -+ public void callEntitiesUnloadEvent() { -+ CraftEventFactory.callEntitiesUnloadEvent(this.world, new ChunkPos(this.chunkX, this.chunkZ), this.getAllEntities()); -+ } -+ // Paper end - optimise CraftChunk#getEntities -+ -+ public boolean isEmpty() { -+ return this.entities.size() == 0; -+ } -+ -+ public void mergeInto(final ChunkEntitySlices slices) { -+ final Entity[] entities = this.entities.getRawData(); -+ for (int i = 0, size = Math.min(entities.length, this.entities.size()); i < size; ++i) { -+ final Entity entity = entities[i]; -+ slices.addEntity(entity, entity.sectionY); -+ } -+ } -+ -+ private boolean preventStatusUpdates; -+ public boolean startPreventingStatusUpdates() { -+ final boolean ret = this.preventStatusUpdates; -+ this.preventStatusUpdates = true; -+ return ret; -+ } -+ -+ public boolean isPreventingStatusUpdates() { -+ return this.preventStatusUpdates; -+ } -+ -+ public void stopPreventingStatusUpdates(final boolean prev) { -+ this.preventStatusUpdates = prev; -+ } -+ -+ public void updateStatus(final FullChunkStatus status, final EntityLookup lookup) { -+ this.status = status; -+ -+ final Entity[] entities = this.entities.getRawData(); -+ -+ for (int i = 0, size = this.entities.size(); i < size; ++i) { -+ final Entity entity = entities[i]; -+ -+ final Visibility oldVisibility = EntityLookup.getEntityStatus(entity); -+ entity.chunkStatus = status; -+ final Visibility newVisibility = EntityLookup.getEntityStatus(entity); -+ -+ lookup.entityStatusChange(entity, this, oldVisibility, newVisibility, false, false, false); -+ } -+ } -+ -+ public boolean addEntity(final Entity entity, final int chunkSection) { -+ if (!this.entities.add(entity)) { -+ return false; -+ } -+ entity.chunkStatus = this.status; -+ final int sectionIndex = chunkSection - this.minSection; -+ -+ this.allEntities.addEntity(entity, sectionIndex); -+ -+ if (entity.hardCollides()) { -+ this.hardCollidingEntities.addEntity(entity, sectionIndex); -+ } -+ -+ for (final Iterator, EntityCollectionBySection>> iterator = -+ this.entitiesByClass.reference2ObjectEntrySet().fastIterator(); iterator.hasNext();) { -+ final Reference2ObjectMap.Entry, EntityCollectionBySection> entry = iterator.next(); -+ -+ if (entry.getKey().isInstance(entity)) { -+ entry.getValue().addEntity(entity, sectionIndex); -+ } -+ } -+ -+ return true; -+ } -+ -+ public boolean removeEntity(final Entity entity, final int chunkSection) { -+ if (!this.entities.remove(entity)) { -+ return false; -+ } -+ entity.chunkStatus = null; -+ final int sectionIndex = chunkSection - this.minSection; -+ -+ this.allEntities.removeEntity(entity, sectionIndex); -+ -+ if (entity.hardCollides()) { -+ this.hardCollidingEntities.removeEntity(entity, sectionIndex); -+ } -+ -+ for (final Iterator, EntityCollectionBySection>> iterator = -+ this.entitiesByClass.reference2ObjectEntrySet().fastIterator(); iterator.hasNext();) { -+ final Reference2ObjectMap.Entry, EntityCollectionBySection> entry = iterator.next(); -+ -+ if (entry.getKey().isInstance(entity)) { -+ entry.getValue().removeEntity(entity, sectionIndex); -+ } -+ } -+ -+ return true; -+ } -+ -+ public void getHardCollidingEntities(final Entity except, final AABB box, final List into, final Predicate predicate) { -+ this.hardCollidingEntities.getEntities(except, box, into, predicate); -+ } -+ -+ public void getEntities(final Entity except, final AABB box, final List into, final Predicate predicate) { -+ this.allEntities.getEntitiesWithEnderDragonParts(except, box, into, predicate); -+ } -+ -+ public void getEntitiesWithoutDragonParts(final Entity except, final AABB box, final List into, final Predicate predicate) { -+ this.allEntities.getEntities(except, box, into, predicate); -+ } -+ -+ public void getEntities(final EntityType type, final AABB box, final List into, -+ final Predicate predicate) { -+ this.allEntities.getEntities(type, box, (List)into, (Predicate)predicate); -+ } -+ -+ protected EntityCollectionBySection initClass(final Class clazz) { -+ final EntityCollectionBySection ret = new EntityCollectionBySection(this); -+ -+ for (int sectionIndex = 0; sectionIndex < this.allEntities.entitiesBySection.length; ++sectionIndex) { -+ final BasicEntityList sectionEntities = this.allEntities.entitiesBySection[sectionIndex]; -+ if (sectionEntities == null) { -+ continue; -+ } -+ -+ final Entity[] storage = sectionEntities.storage; -+ -+ for (int i = 0, len = Math.min(storage.length, sectionEntities.size()); i < len; ++i) { -+ final Entity entity = storage[i]; -+ -+ if (clazz.isInstance(entity)) { -+ ret.addEntity(entity, sectionIndex); -+ } -+ } -+ } -+ -+ return ret; -+ } -+ -+ public void getEntities(final Class clazz, final Entity except, final AABB box, final List into, -+ final Predicate predicate) { -+ EntityCollectionBySection collection = this.entitiesByClass.get(clazz); -+ if (collection != null) { -+ collection.getEntitiesWithEnderDragonParts(except, clazz, box, (List)into, (Predicate)predicate); -+ } else { -+ this.entitiesByClass.putIfAbsent(clazz, collection = this.initClass(clazz)); -+ collection.getEntitiesWithEnderDragonParts(except, clazz, box, (List)into, (Predicate)predicate); -+ } -+ } -+ -+ protected static final class BasicEntityList { -+ -+ protected static final Entity[] EMPTY = new Entity[0]; -+ protected static final int DEFAULT_CAPACITY = 4; -+ -+ protected E[] storage; -+ protected int size; -+ -+ public BasicEntityList() { -+ this(0); -+ } -+ -+ public BasicEntityList(final int cap) { -+ this.storage = (E[])(cap <= 0 ? EMPTY : new Entity[cap]); -+ } -+ -+ public boolean isEmpty() { -+ return this.size == 0; -+ } -+ -+ public int size() { -+ return this.size; -+ } -+ -+ private void resize() { -+ if (this.storage == EMPTY) { -+ this.storage = (E[])new Entity[DEFAULT_CAPACITY]; -+ } else { -+ this.storage = Arrays.copyOf(this.storage, this.storage.length * 2); -+ } -+ } -+ -+ public void add(final E entity) { -+ final int idx = this.size++; -+ if (idx >= this.storage.length) { -+ this.resize(); -+ this.storage[idx] = entity; -+ } else { -+ this.storage[idx] = entity; -+ } -+ } -+ -+ public int indexOf(final E entity) { -+ final E[] storage = this.storage; -+ -+ for (int i = 0, len = Math.min(this.storage.length, this.size); i < len; ++i) { -+ if (storage[i] == entity) { -+ return i; -+ } -+ } -+ -+ return -1; -+ } -+ -+ public boolean remove(final E entity) { -+ final int idx = this.indexOf(entity); -+ if (idx == -1) { -+ return false; -+ } -+ -+ final int size = --this.size; -+ final E[] storage = this.storage; -+ if (idx != size) { -+ System.arraycopy(storage, idx + 1, storage, idx, size - idx); -+ } -+ -+ storage[size] = null; -+ -+ return true; -+ } -+ -+ public boolean has(final E entity) { -+ return this.indexOf(entity) != -1; -+ } -+ } -+ -+ protected static final class EntityCollectionBySection { -+ -+ protected final ChunkEntitySlices manager; -+ protected final long[] nonEmptyBitset; -+ protected final BasicEntityList[] entitiesBySection; -+ protected int count; -+ -+ public EntityCollectionBySection(final ChunkEntitySlices manager) { -+ this.manager = manager; -+ -+ final int sectionCount = manager.maxSection - manager.minSection + 1; -+ -+ this.nonEmptyBitset = new long[(sectionCount + (Long.SIZE - 1)) >>> 6]; // (sectionCount + (Long.SIZE - 1)) / Long.SIZE -+ this.entitiesBySection = new BasicEntityList[sectionCount]; -+ } -+ -+ public void addEntity(final Entity entity, final int sectionIndex) { -+ BasicEntityList list = this.entitiesBySection[sectionIndex]; -+ -+ if (list != null && list.has(entity)) { -+ return; -+ } -+ -+ if (list == null) { -+ this.entitiesBySection[sectionIndex] = list = new BasicEntityList<>(); -+ this.nonEmptyBitset[sectionIndex >>> 6] |= (1L << (sectionIndex & (Long.SIZE - 1))); -+ } -+ -+ list.add(entity); -+ ++this.count; -+ } -+ -+ public void removeEntity(final Entity entity, final int sectionIndex) { -+ final BasicEntityList list = this.entitiesBySection[sectionIndex]; -+ -+ if (list == null || !list.remove(entity)) { -+ return; -+ } -+ -+ --this.count; -+ -+ if (list.isEmpty()) { -+ this.entitiesBySection[sectionIndex] = null; -+ this.nonEmptyBitset[sectionIndex >>> 6] ^= (1L << (sectionIndex & (Long.SIZE - 1))); -+ } -+ } -+ -+ public void getEntities(final Entity except, final AABB box, final List into, final Predicate predicate) { -+ if (this.count == 0) { -+ return; -+ } -+ -+ final int minSection = this.manager.minSection; -+ final int maxSection = this.manager.maxSection; -+ -+ final int min = Mth.clamp(Mth.floor(box.minY - 2.0) >> 4, minSection, maxSection); -+ final int max = Mth.clamp(Mth.floor(box.maxY + 2.0) >> 4, minSection, maxSection); -+ -+ final BasicEntityList[] entitiesBySection = this.entitiesBySection; -+ -+ for (int section = min; section <= max; ++section) { -+ final BasicEntityList list = entitiesBySection[section - minSection]; -+ -+ if (list == null) { -+ continue; -+ } -+ -+ final Entity[] storage = list.storage; -+ -+ for (int i = 0, len = Math.min(storage.length, list.size()); i < len; ++i) { -+ final Entity entity = storage[i]; -+ -+ if (entity == null || entity == except || !entity.getBoundingBox().intersects(box)) { -+ continue; -+ } -+ -+ if (predicate != null && !predicate.test(entity)) { -+ continue; -+ } -+ -+ into.add(entity); -+ } -+ } -+ } -+ -+ public void getEntitiesWithEnderDragonParts(final Entity except, final AABB box, final List into, -+ final Predicate predicate) { -+ if (this.count == 0) { -+ return; -+ } -+ -+ final int minSection = this.manager.minSection; -+ final int maxSection = this.manager.maxSection; -+ -+ final int min = Mth.clamp(Mth.floor(box.minY - 2.0) >> 4, minSection, maxSection); -+ final int max = Mth.clamp(Mth.floor(box.maxY + 2.0) >> 4, minSection, maxSection); -+ -+ final BasicEntityList[] entitiesBySection = this.entitiesBySection; -+ -+ for (int section = min; section <= max; ++section) { -+ final BasicEntityList list = entitiesBySection[section - minSection]; -+ -+ if (list == null) { -+ continue; -+ } -+ -+ final Entity[] storage = list.storage; -+ -+ for (int i = 0, len = Math.min(storage.length, list.size()); i < len; ++i) { -+ final Entity entity = storage[i]; -+ -+ if (entity == null || entity == except || !entity.getBoundingBox().intersects(box)) { -+ continue; -+ } -+ -+ if (predicate == null || predicate.test(entity)) { -+ into.add(entity); -+ } // else: continue to test the ender dragon parts -+ -+ if (entity instanceof EnderDragon) { -+ for (final EnderDragonPart part : ((EnderDragon)entity).subEntities) { -+ if (part == except || !part.getBoundingBox().intersects(box)) { -+ continue; -+ } -+ -+ if (predicate != null && !predicate.test(part)) { -+ continue; -+ } -+ -+ into.add(part); -+ } -+ } -+ } -+ } -+ } -+ -+ public void getEntitiesWithEnderDragonParts(final Entity except, final Class clazz, final AABB box, final List into, -+ final Predicate predicate) { -+ if (this.count == 0) { -+ return; -+ } -+ -+ final int minSection = this.manager.minSection; -+ final int maxSection = this.manager.maxSection; -+ -+ final int min = Mth.clamp(Mth.floor(box.minY - 2.0) >> 4, minSection, maxSection); -+ final int max = Mth.clamp(Mth.floor(box.maxY + 2.0) >> 4, minSection, maxSection); -+ -+ final BasicEntityList[] entitiesBySection = this.entitiesBySection; -+ -+ for (int section = min; section <= max; ++section) { -+ final BasicEntityList list = entitiesBySection[section - minSection]; -+ -+ if (list == null) { -+ continue; -+ } -+ -+ final Entity[] storage = list.storage; -+ -+ for (int i = 0, len = Math.min(storage.length, list.size()); i < len; ++i) { -+ final Entity entity = storage[i]; -+ -+ if (entity == null || entity == except || !entity.getBoundingBox().intersects(box)) { -+ continue; -+ } -+ -+ if (predicate == null || predicate.test(entity)) { -+ into.add(entity); -+ } // else: continue to test the ender dragon parts -+ -+ if (entity instanceof EnderDragon) { -+ for (final EnderDragonPart part : ((EnderDragon)entity).subEntities) { -+ if (part == except || !part.getBoundingBox().intersects(box) || !clazz.isInstance(part)) { -+ continue; -+ } -+ -+ if (predicate != null && !predicate.test(part)) { -+ continue; -+ } -+ -+ into.add(part); -+ } -+ } -+ } -+ } -+ } -+ -+ public void getEntities(final EntityType type, final AABB box, final List into, -+ final Predicate predicate) { -+ if (this.count == 0) { -+ return; -+ } -+ -+ final int minSection = this.manager.minSection; -+ final int maxSection = this.manager.maxSection; -+ -+ final int min = Mth.clamp(Mth.floor(box.minY - 2.0) >> 4, minSection, maxSection); -+ final int max = Mth.clamp(Mth.floor(box.maxY + 2.0) >> 4, minSection, maxSection); -+ -+ final BasicEntityList[] entitiesBySection = this.entitiesBySection; -+ -+ for (int section = min; section <= max; ++section) { -+ final BasicEntityList list = entitiesBySection[section - minSection]; -+ -+ if (list == null) { -+ continue; -+ } -+ -+ final Entity[] storage = list.storage; -+ -+ for (int i = 0, len = Math.min(storage.length, list.size()); i < len; ++i) { -+ final Entity entity = storage[i]; -+ -+ if (entity == null || (type != null && entity.getType() != type) || !entity.getBoundingBox().intersects(box)) { -+ continue; -+ } -+ -+ if (predicate != null && !predicate.test((T)entity)) { -+ continue; -+ } -+ -+ into.add((T)entity); -+ } -+ } -+ } -+ } -+} -diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index c33f85b570f159ab465b5a10a8044a81f2797f43..244a19ecd0234fa1d7a6ecfea20751595688605d 100644 ---- a/src/main/java/net/minecraft/server/Main.java -+++ b/src/main/java/net/minecraft/server/Main.java -@@ -320,6 +320,7 @@ public class Main { - - convertable_conversionsession.saveDataTag(iregistrycustom_dimension, savedata); - */ -+ Class.forName(net.minecraft.world.entity.npc.VillagerTrades.class.getName()); // Paper - load this sync so it won't fail later async - final DedicatedServer dedicatedserver = (DedicatedServer) MinecraftServer.spin((thread) -> { - DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, worldLoader.get(), thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), services, LoggerChunkProgressListener::createFromGameruleRadius); - -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 1a9e323659dcff12ce53919eb3d6d6f66f835292..2e4f20ba5f6f61b797f1eef267302fa3314f94a5 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -315,7 +315,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { - AtomicReference atomicreference = new AtomicReference(); -- Thread thread = new Thread(() -> { -+ Thread thread = new io.papermc.paper.util.TickThread(() -> { // Paper - rewrite chunk system - ((MinecraftServer) atomicreference.get()).runServer(); - }, "Server thread"); - -@@ -651,7 +651,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -- return worldserver1.getChunkSource().chunkMap.hasWork(); -- })) { -- this.nextTickTimeNanos = Util.getNanos() + TimeUtil.NANOSECONDS_PER_MILLISECOND; -- iterator = this.getAllLevels().iterator(); -- -- while (iterator.hasNext()) { -- worldserver = (ServerLevel) iterator.next(); -- worldserver.getChunkSource().removeTicketsOnClosing(); -- worldserver.getChunkSource().tick(() -> { -- return true; -- }, false); -- } -- -- this.waitUntilNextTick(); -- } -- -- this.saveAllChunks(false, true, false); -- iterator = this.getAllLevels().iterator(); -- -- while (iterator.hasNext()) { -- worldserver = (ServerLevel) iterator.next(); -- if (worldserver != null) { -- try { -- worldserver.close(); -- } catch (IOException ioexception) { -- MinecraftServer.LOGGER.error("Exception closing the level", ioexception); -- } -- } -- } -+ this.saveAllChunks(false, true, false, true); // Paper - rewrite chunk system - move closing into here - - this.isSaving = false; - this.resources.close(); -@@ -1020,6 +1001,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -- for (final Entity entity : level.getEntities().getAll()) { -+ for (final Entity entity : level.getEntityLookup().getAllCopy()) { // Paper - rewrite chunk system - if (entity.isRemoved()) { - continue; - } -@@ -2622,6 +2617,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -+ LOGGER.info("Async debug chunks executing"); -+ io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(false); -+ CommandSender sender = MinecraftServer.getServer().console; -+ java.io.File file = new java.io.File(new java.io.File(new java.io.File("."), "debug"), -+ "chunks-" + java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(java.time.LocalDateTime.now()) + ".txt"); -+ sender.sendMessage(net.kyori.adventure.text.Component.text("Writing chunk information dump to " + file, net.kyori.adventure.text.format.NamedTextColor.GREEN)); -+ try { -+ io.papermc.paper.util.MCUtil.dumpChunks(file, true); -+ sender.sendMessage(net.kyori.adventure.text.Component.text("Successfully written chunk information!", net.kyori.adventure.text.format.NamedTextColor.GREEN)); -+ } catch (Throwable thr) { -+ MinecraftServer.LOGGER.warn("Failed to dump chunk information to file " + file.toString(), thr); -+ sender.sendMessage(net.kyori.adventure.text.Component.text("Failed to dump chunk information, see console", net.kyori.adventure.text.format.NamedTextColor.RED)); -+ } -+ }; -+ Thread t = new Thread(run); -+ t.setName("Async debug thread #" + ASYNC_DEBUG_CHUNKS_COUNT.getAndIncrement()); -+ t.setDaemon(true); -+ t.start(); -+ return; -+ } -+ // Paper end - rewrite chunk system - this.serverCommandQueue.add(new ConsoleInput(command, commandSource)); // Paper - Perf: use proper queue - } - -diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java -index 88729d92878f98729eb5669cce5ae5b1418865a1..13d15a135dd0373bef4a5ac9ffb56dbbf53353a0 100644 ---- a/src/main/java/net/minecraft/server/level/ChunkHolder.java -+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java -@@ -46,17 +46,12 @@ public class ChunkHolder { - public static final ChunkResult NOT_DONE_YET = ChunkResult.error("Not done yet"); - private static final CompletableFuture> UNLOADED_LEVEL_CHUNK_FUTURE = CompletableFuture.completedFuture(ChunkHolder.UNLOADED_LEVEL_CHUNK); - private static final List CHUNK_STATUSES = ChunkStatus.getStatusList(); -- private final AtomicReferenceArray>> futures; -+ // Paper - rewrite chunk system - private final LevelHeightAccessor levelHeightAccessor; -- private volatile CompletableFuture> fullChunkFuture; private int fullChunkCreateCount; private volatile boolean isFullChunkReady; // Paper - cache chunk ticking stage -- private volatile CompletableFuture> tickingChunkFuture; private volatile boolean isTickingReady; // Paper - cache chunk ticking stage -- private volatile CompletableFuture> entityTickingChunkFuture; private volatile boolean isEntityTickingReady; // Paper - cache chunk ticking stage -- public CompletableFuture chunkToSave; // Paper - public -+ // Paper - rewrite chunk system - @Nullable - private final DebugBuffer chunkToSaveHistory; -- public int oldTicketLevel; -- private int ticketLevel; -- private int queueLevel; -+ // Paper - rewrite chunk system - public final ChunkPos pos; - private boolean hasChangedSections; - private final ShortSet[] changedBlocksPerSection; -@@ -65,11 +60,20 @@ public class ChunkHolder { - private final LevelLightEngine lightEngine; - private final ChunkHolder.LevelChangeListener onLevelChange; - public final ChunkHolder.PlayerProvider playerProvider; -- private boolean wasAccessibleSinceLastSave; -- private CompletableFuture pendingFullStateConfirmation; -- private CompletableFuture sendSync; -+ // Paper - rewrite chunk system - - private final ChunkMap chunkMap; // Paper -+ // Paper start - no-tick view distance -+ public final LevelChunk getSendingChunk() { -+ // it's important that we use getChunkAtIfLoadedImmediately to mirror the chunk sending logic used -+ // in Chunk's neighbour callback -+ LevelChunk ret = this.chunkMap.level.getChunkSource().getChunkAtIfLoadedImmediately(this.pos.x, this.pos.z); -+ if (ret != null && ret.areNeighboursLoaded(1)) { -+ return ret; -+ } -+ return null; -+ } -+ // Paper end - no-tick view distance - - // Paper start - public void onChunkAdd() { -@@ -81,147 +85,131 @@ public class ChunkHolder { - } - // 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; -- this.tickingChunkFuture = ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE; -- this.entityTickingChunkFuture = ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE; -- this.chunkToSave = CompletableFuture.completedFuture(null); // CraftBukkit - decompile error -+ public final io.papermc.paper.chunk.system.scheduling.NewChunkHolder newChunkHolder; // Paper - rewrite chunk system -+ -+ // Paper start - replace player chunk loader -+ private final com.destroystokyo.paper.util.maplist.ReferenceList playersSentChunkTo = new com.destroystokyo.paper.util.maplist.ReferenceList<>(); -+ -+ public void addPlayer(ServerPlayer player) { -+ if (!this.playersSentChunkTo.add(player)) { -+ throw new IllegalStateException("Already sent chunk " + this.pos + " in world '" + this.chunkMap.level.getWorld().getName() + "' to player " + player); -+ } -+ } -+ -+ public void removePlayer(ServerPlayer player) { -+ if (!this.playersSentChunkTo.remove(player)) { -+ throw new IllegalStateException("Have not sent chunk " + this.pos + " in world '" + this.chunkMap.level.getWorld().getName() + "' to player " + player); -+ } -+ } -+ -+ public boolean hasChunkBeenSent() { -+ return this.playersSentChunkTo.size() != 0; -+ } -+ -+ public boolean hasBeenSent(ServerPlayer to) { -+ return this.playersSentChunkTo.contains(to); -+ } -+ // Paper end - replace player chunk loader -+ public ChunkHolder(ChunkPos pos, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.PlayerProvider playersWatchingChunkProvider, io.papermc.paper.chunk.system.scheduling.NewChunkHolder newChunkHolder) { // Paper - rewrite chunk system -+ this.newChunkHolder = newChunkHolder; // Paper - rewrite chunk system - this.chunkToSaveHistory = null; - this.blockChangedLightSectionFilter = new BitSet(); - this.skyChangedLightSectionFilter = new BitSet(); -- this.pendingFullStateConfirmation = CompletableFuture.completedFuture(null); // CraftBukkit - decompile error -- this.sendSync = CompletableFuture.completedFuture(null); // CraftBukkit - decompile error -+ // Paper - rewrite chunk system - this.pos = pos; - this.levelHeightAccessor = world; - this.lightEngine = lightingProvider; -- this.onLevelChange = levelUpdateListener; -+ this.onLevelChange = null; // Paper - rewrite chunk system - this.playerProvider = playersWatchingChunkProvider; -- this.oldTicketLevel = ChunkLevel.MAX_LEVEL + 1; -- this.ticketLevel = this.oldTicketLevel; -- this.queueLevel = this.oldTicketLevel; -- this.setTicketLevel(level); -+ // Paper - rewrite chunk system - this.changedBlocksPerSection = new ShortSet[world.getSectionsCount()]; - this.chunkMap = (ChunkMap)playersWatchingChunkProvider; // Paper - } - - // Paper start - public @Nullable ChunkAccess getAvailableChunkNow() { -- // TODO can we just getStatusFuture(EMPTY)? -- for (ChunkStatus curr = ChunkStatus.FULL, next = curr.getParent(); curr != next; curr = next, next = next.getParent()) { -- CompletableFuture> future = this.getFutureIfPresentUnchecked(curr); -- ChunkResult either = future.getNow(null); -- if (either == null || either.isSuccess()) { -- continue; -- } -- return either.orElseThrow(IllegalStateException::new); -- } -- return null; -+ return this.newChunkHolder.getCurrentChunk(); // Paper - rewrite chunk system - } - // Paper end - // CraftBukkit start - public LevelChunk getFullChunkNow() { -- // Note: We use the oldTicketLevel for isLoaded checks. -- if (!ChunkLevel.fullStatus(this.oldTicketLevel).isOrAfter(FullChunkStatus.FULL)) return null; -- return this.getFullChunkNowUnchecked(); -+ // Paper start - rewrite chunk system -+ if (!this.isFullChunkReady() || !(this.getAvailableChunkNow() instanceof LevelChunk chunk)) return null; // instanceof to avoid a race condition on off-main threads -+ return chunk; -+ // Paper end - rewrite chunk system - } - - public LevelChunk getFullChunkNowUnchecked() { -- CompletableFuture> statusFuture = this.getFutureIfPresentUnchecked(ChunkStatus.FULL); -- ChunkResult either = statusFuture.getNow(null); -- return (either == null) ? null : (LevelChunk) either.orElse(null); -+ // Paper start - rewrite chunk system -+ return this.getAvailableChunkNow() instanceof LevelChunk chunk ? chunk : null; -+ // Paper end - rewrite chunk system - } - // CraftBukkit end - - public CompletableFuture> getFutureIfPresentUnchecked(ChunkStatus leastStatus) { -- CompletableFuture> completablefuture = (CompletableFuture) this.futures.get(leastStatus.getIndex()); -- -- return completablefuture == null ? ChunkHolder.UNLOADED_CHUNK_FUTURE : completablefuture; -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - public CompletableFuture> getFutureIfPresent(ChunkStatus leastStatus) { -- return ChunkLevel.generationStatus(this.ticketLevel).isOrAfter(leastStatus) ? this.getFutureIfPresentUnchecked(leastStatus) : ChunkHolder.UNLOADED_CHUNK_FUTURE; -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - public final CompletableFuture> getTickingChunkFuture() { // Paper - final for inline -- return this.tickingChunkFuture; -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - public final CompletableFuture> getEntityTickingChunkFuture() { // Paper - final for inline -- return this.entityTickingChunkFuture; -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk systemv - } - - public final CompletableFuture> getFullChunkFuture() { // Paper - final for inline -- return this.fullChunkFuture; -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk systemv - } - - @Nullable - public final LevelChunk getTickingChunk() { // Paper - final for inline -- return (LevelChunk) ((ChunkResult) this.getTickingChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).orElse(null); // CraftBukkit - decompile error -+ // Paper start - rewrite chunk system -+ if (!this.isTickingReady()) { -+ return null; -+ } -+ return (LevelChunk)this.getAvailableChunkNow(); -+ // Paper end - rewrite chunk system - } - - public CompletableFuture getChunkSendSyncFuture() { -- return this.sendSync; -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - @Nullable - public LevelChunk getChunkToSend() { -- return !this.sendSync.isDone() ? null : this.getTickingChunk(); -+ return this.getSendingChunk(); // Paper - rewrite chunk system - } - - @Nullable - public ChunkStatus getLastAvailableStatus() { -- for (int i = ChunkHolder.CHUNK_STATUSES.size() - 1; i >= 0; --i) { -- ChunkStatus chunkstatus = (ChunkStatus) ChunkHolder.CHUNK_STATUSES.get(i); -- CompletableFuture> completablefuture = this.getFutureIfPresentUnchecked(chunkstatus); -- -- if (((ChunkResult) completablefuture.getNow(ChunkHolder.UNLOADED_CHUNK)).isSuccess()) { -- return chunkstatus; -- } -- } -- -- return null; -+ return this.newChunkHolder.getCurrentGenStatus(); // Paper - rewrite chunk system - } - - // Paper start - public @Nullable ChunkStatus getChunkHolderStatus() { -- for (ChunkStatus curr = ChunkStatus.FULL, next = curr.getParent(); curr != next; curr = next, next = next.getParent()) { -- CompletableFuture> future = this.getFutureIfPresentUnchecked(curr); -- ChunkResult either = future.getNow(null); -- if (either == null || !either.isSuccess()) { -- continue; -- } -- return curr; -- } -- -- return null; -+ return this.newChunkHolder.getCurrentGenStatus(); // Paper - rewrite chunk system - } - // Paper end - - @Nullable - public ChunkAccess getLastAvailable() { -- for (int i = ChunkHolder.CHUNK_STATUSES.size() - 1; i >= 0; --i) { -- ChunkStatus chunkstatus = (ChunkStatus) ChunkHolder.CHUNK_STATUSES.get(i); -- CompletableFuture> completablefuture = this.getFutureIfPresentUnchecked(chunkstatus); -- -- if (!completablefuture.isCompletedExceptionally()) { -- ChunkAccess ichunkaccess = (ChunkAccess) ((ChunkResult) completablefuture.getNow(ChunkHolder.UNLOADED_CHUNK)).orElse((Object) null); -- -- if (ichunkaccess != null) { -- return ichunkaccess; -- } -- } -- } -- -- return null; -+ return this.newChunkHolder.getCurrentChunk(); // Paper - rewrite chunk system - } - -- public final CompletableFuture getChunkToSave() { // Paper - final for inline -- return this.chunkToSave; -- } -+ // Paper - rewrite chunk system - - public void blockChanged(BlockPos pos) { -- LevelChunk chunk = this.getTickingChunk(); -+ // Paper start - replace player chunk loader -+ if (this.playersSentChunkTo.size() == 0) { -+ return; -+ } -+ // Paper end - replace player chunk loader -+ LevelChunk chunk = this.getSendingChunk(); // Paper - no-tick view distance - - if (chunk != null) { - int i = this.levelHeightAccessor.getSectionIndex(pos.getY()); -@@ -237,13 +225,13 @@ public class ChunkHolder { - } - - public void sectionLightChanged(LightLayer lightType, int y) { -- ChunkAccess ichunkaccess = (ChunkAccess) ((ChunkResult) this.getFutureIfPresent(ChunkStatus.INITIALIZE_LIGHT).getNow(ChunkHolder.UNLOADED_CHUNK)).orElse(null); // CraftBukkit - decompile error -+ ChunkAccess ichunkaccess = this.getAvailableChunkNow(); // Paper - rewrite chunk system - - if (ichunkaccess != null) { - ichunkaccess.setUnsaved(true); -- LevelChunk chunk = this.getTickingChunk(); -+ LevelChunk chunk = this.getSendingChunk(); // Paper - rewrite chunk system - -- if (chunk != null) { -+ if (this.playersSentChunkTo.size() != 0 && chunk != null) { // Paper - replace player chunk loader - int j = this.lightEngine.getMinLightSection(); - int k = this.lightEngine.getMaxLightSection(); - -@@ -263,7 +251,7 @@ public class ChunkHolder { - - // Paper start - starlight - public void broadcast(Packet packet, boolean onChunkViewEdge) { -- this.broadcast(this.playerProvider.getPlayers(this.pos, onChunkViewEdge), packet); -+ this.broadcast(this.getPlayers(onChunkViewEdge), packet); // Paper - rewrite chunk system - } - // Paper end - starlight - -@@ -273,7 +261,7 @@ public class ChunkHolder { - List list; - - if (!this.skyChangedLightSectionFilter.isEmpty() || !this.blockChangedLightSectionFilter.isEmpty()) { -- list = this.playerProvider.getPlayers(this.pos, true); -+ list = this.getPlayers(true); // Paper - rewrite chunk system - if (!list.isEmpty()) { - ClientboundLightUpdatePacket packetplayoutlightupdate = new ClientboundLightUpdatePacket(chunk.getPos(), this.lightEngine, this.skyChangedLightSectionFilter, this.blockChangedLightSectionFilter); - -@@ -285,7 +273,7 @@ public class ChunkHolder { - } - - if (this.hasChangedSections) { -- list = this.playerProvider.getPlayers(this.pos, false); -+ list = this.getPlayers(false); // Paper - rewrite chunk system - - for (int i = 0; i < this.changedBlocksPerSection.length; ++i) { - ShortSet shortset = this.changedBlocksPerSection[i]; -@@ -343,75 +331,33 @@ public class ChunkHolder { - - } - -- private void broadcast(List players, Packet packet) { -- players.forEach((entityplayer) -> { -- entityplayer.connection.send(packet); -- }); -- } -- -- public CompletableFuture> getOrScheduleFuture(ChunkStatus targetStatus, ChunkMap chunkStorage) { -- int i = targetStatus.getIndex(); -- CompletableFuture> completablefuture = (CompletableFuture) this.futures.get(i); -+ // Paper start - rewrite chunk system -+ public List getPlayers(boolean onlyOnWatchDistanceEdge) { -+ List ret = new java.util.ArrayList<>(); - -- if (completablefuture != null) { -- ChunkResult chunkresult = (ChunkResult) completablefuture.getNow(ChunkHolder.NOT_DONE_YET); -- -- if (chunkresult == null) { -- String s = String.valueOf(targetStatus); -- String s1 = "value in future for status: " + s + " was incorrectly set to null at chunk: " + String.valueOf(this.pos); -- -- throw chunkStorage.debugFuturesAndCreateReportedException(new IllegalStateException("null value previously set for chunk status"), s1); -- } -- -- if (chunkresult == ChunkHolder.NOT_DONE_YET || chunkresult.isSuccess()) { -- return completablefuture; -+ for (int i = 0, len = this.playersSentChunkTo.size(); i < len; ++i) { -+ ServerPlayer player = this.playersSentChunkTo.getUnchecked(i); -+ if (onlyOnWatchDistanceEdge && !this.chunkMap.level.playerChunkLoader.isChunkSent(player, this.pos.x, this.pos.z, onlyOnWatchDistanceEdge)) { -+ continue; - } -+ ret.add(player); - } - -- if (ChunkLevel.generationStatus(this.ticketLevel).isOrAfter(targetStatus)) { -- CompletableFuture> completablefuture1 = chunkStorage.schedule(this, targetStatus); -- -- this.updateChunkToSave(completablefuture1, "schedule " + String.valueOf(targetStatus)); -- this.futures.set(i, completablefuture1); -- return completablefuture1; -- } else { -- return completablefuture == null ? ChunkHolder.UNLOADED_CHUNK_FUTURE : completablefuture; -- } -+ return ret; - } -+ // Paper end - rewrite chunk system - -- protected void addSaveDependency(String thenDesc, CompletableFuture then) { -- if (this.chunkToSaveHistory != null) { -- this.chunkToSaveHistory.push(new ChunkHolder.ChunkSaveDebug(Thread.currentThread(), then, thenDesc)); -- } - -- this.chunkToSave = this.chunkToSave.thenCombine(then, (ichunkaccess, object) -> { -- return ichunkaccess; -- }); -- } -- -- private void updateChunkToSave(CompletableFuture> then, String thenDesc) { -- if (this.chunkToSaveHistory != null) { -- this.chunkToSaveHistory.push(new ChunkHolder.ChunkSaveDebug(Thread.currentThread(), then, thenDesc)); -- } -- -- this.chunkToSave = this.chunkToSave.thenCombine(then, (ichunkaccess, chunkresult) -> { -- return (ChunkAccess) ChunkResult.orElse(chunkresult, ichunkaccess); -+ private void broadcast(List players, Packet packet) { -+ players.forEach((entityplayer) -> { -+ entityplayer.connection.send(packet); - }); - } - -- public void addSendDependency(CompletableFuture postProcessingFuture) { -- if (this.sendSync.isDone()) { -- this.sendSync = postProcessingFuture; -- } else { -- this.sendSync = this.sendSync.thenCombine(postProcessingFuture, (object, object1) -> { -- return null; -- }); -- } -- -- } -+ // Paper - rewrite chunk system - - public FullChunkStatus getFullStatus() { -- return ChunkLevel.fullStatus(this.ticketLevel); -+ return this.newChunkHolder.getChunkStatus(); // Paper - rewrite chunk system - } - - public final ChunkPos getPos() { // Paper - final for inline -@@ -419,238 +365,17 @@ public class ChunkHolder { - } - - public final int getTicketLevel() { // Paper - final for inline -- return this.ticketLevel; -- } -- -- public int getQueueLevel() { -- return this.queueLevel; -- } -- -- private void setQueueLevel(int level) { -- this.queueLevel = level; -- } -- -- public void setTicketLevel(int level) { -- this.ticketLevel = level; -- } -- -- private void scheduleFullChunkPromotion(ChunkMap playerchunkmap, CompletableFuture> completablefuture, Executor executor, FullChunkStatus fullchunkstatus) { -- this.pendingFullStateConfirmation.cancel(false); -- CompletableFuture completablefuture1 = new CompletableFuture(); -- -- completablefuture1.thenRunAsync(() -> { -- playerchunkmap.onFullChunkStatusChange(this.pos, fullchunkstatus); -- }, executor); -- this.pendingFullStateConfirmation = completablefuture1; -- completablefuture.thenAccept((chunkresult) -> { -- chunkresult.ifSuccess((chunk) -> { -- completablefuture1.complete(null); // CraftBukkit - decompile error -- }); -- }); -- } -- -- private void demoteFullChunk(ChunkMap playerchunkmap, FullChunkStatus fullchunkstatus) { -- this.pendingFullStateConfirmation.cancel(false); -- playerchunkmap.onFullChunkStatusChange(this.pos, fullchunkstatus); -- } -- -- protected void updateFutures(ChunkMap chunkStorage, Executor executor) { -- ChunkStatus chunkstatus = ChunkLevel.generationStatus(this.oldTicketLevel); -- ChunkStatus chunkstatus1 = ChunkLevel.generationStatus(this.ticketLevel); -- boolean flag = ChunkLevel.isLoaded(this.oldTicketLevel); -- boolean flag1 = ChunkLevel.isLoaded(this.ticketLevel); -- FullChunkStatus fullchunkstatus = ChunkLevel.fullStatus(this.oldTicketLevel); -- FullChunkStatus fullchunkstatus1 = ChunkLevel.fullStatus(this.ticketLevel); -- // CraftBukkit start -- // ChunkUnloadEvent: Called before the chunk is unloaded: isChunkLoaded is still true and chunk can still be modified by plugins. -- if (fullchunkstatus.isOrAfter(FullChunkStatus.FULL) && !fullchunkstatus1.isOrAfter(FullChunkStatus.FULL)) { -- this.getFutureIfPresentUnchecked(ChunkStatus.FULL).thenAccept((either) -> { -- LevelChunk chunk = (LevelChunk) either.orElse(null); -- if (chunk != null) { -- chunkStorage.callbackExecutor.execute(() -> { -- // 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. -- chunk.setUnsaved(true); -- chunk.unloadCallback(); -- }); -- } -- }).exceptionally((throwable) -> { -- // ensure exceptions are printed, by default this is not the case -- MinecraftServer.LOGGER.error("Failed to schedule unload callback for chunk " + ChunkHolder.this.pos, throwable); -- return null; -- }); -- -- // Run callback right away if the future was already done -- chunkStorage.callbackExecutor.run(); -- } -- // CraftBukkit end -- -- if (flag) { -- ChunkResult chunkresult = ChunkResult.error(() -> { -- return "Unloaded ticket level " + String.valueOf(this.pos); -- }); -- -- for (int i = flag1 ? chunkstatus1.getIndex() + 1 : 0; i <= chunkstatus.getIndex(); ++i) { -- CompletableFuture> completablefuture = (CompletableFuture) this.futures.get(i); -- -- if (completablefuture == null) { -- this.futures.set(i, CompletableFuture.completedFuture(chunkresult)); -- } -- } -- } -- -- boolean flag2 = fullchunkstatus.isOrAfter(FullChunkStatus.FULL); -- boolean flag3 = fullchunkstatus1.isOrAfter(FullChunkStatus.FULL); -- -- this.wasAccessibleSinceLastSave |= flag3; -- if (!flag2 && flag3) { -- int expectCreateCount = ++this.fullChunkCreateCount; // Paper -- this.fullChunkFuture = chunkStorage.prepareAccessibleChunk(this); -- this.scheduleFullChunkPromotion(chunkStorage, this.fullChunkFuture, executor, FullChunkStatus.FULL); -- // Paper start - cache ticking ready status -- this.fullChunkFuture.thenAccept(chunkResult -> { -- chunkResult.ifSuccess(chunk -> { -- if (ChunkHolder.this.fullChunkCreateCount == expectCreateCount) { -- ChunkHolder.this.isFullChunkReady = true; -- io.papermc.paper.chunk.system.ChunkSystem.onChunkBorder(chunk, this); -- } -- }); -- }); -- this.updateChunkToSave(this.fullChunkFuture, "full"); -- } -- -- if (flag2 && !flag3) { -- // Paper start -- if (this.isFullChunkReady) { -- io.papermc.paper.chunk.system.ChunkSystem.onChunkNotBorder(this.fullChunkFuture.join().orElseThrow(IllegalStateException::new), 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 -- this.isFullChunkReady = false; // Paper - cache ticking ready status -- } -- -- boolean flag4 = fullchunkstatus.isOrAfter(FullChunkStatus.BLOCK_TICKING); -- boolean flag5 = fullchunkstatus1.isOrAfter(FullChunkStatus.BLOCK_TICKING); -- -- if (!flag4 && flag5) { -- this.tickingChunkFuture = chunkStorage.prepareTickingChunk(this); -- this.scheduleFullChunkPromotion(chunkStorage, this.tickingChunkFuture, executor, FullChunkStatus.BLOCK_TICKING); -- // Paper start - cache ticking ready status -- this.tickingChunkFuture.thenAccept(chunkResult -> { -- chunkResult.ifSuccess(chunk -> { -- // note: Here is a very good place to add callbacks to logic waiting on this. -- ChunkHolder.this.isTickingReady = true; -- io.papermc.paper.chunk.system.ChunkSystem.onChunkTicking(chunk, this); -- }); -- }); -- // Paper end -- this.updateChunkToSave(this.tickingChunkFuture, "ticking"); -- } -- -- if (flag4 && !flag5) { -- // Paper start -- if (this.isTickingReady) { -- io.papermc.paper.chunk.system.ChunkSystem.onChunkNotTicking(this.tickingChunkFuture.join().orElseThrow(IllegalStateException::new), 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; -- } -- -- boolean flag6 = fullchunkstatus.isOrAfter(FullChunkStatus.ENTITY_TICKING); -- boolean flag7 = fullchunkstatus1.isOrAfter(FullChunkStatus.ENTITY_TICKING); -- -- if (!flag6 && flag7) { -- if (this.entityTickingChunkFuture != ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE) { -- throw (IllegalStateException) Util.pauseInIde(new IllegalStateException()); -- } -- -- this.entityTickingChunkFuture = chunkStorage.prepareEntityTickingChunk(this); -- this.scheduleFullChunkPromotion(chunkStorage, this.entityTickingChunkFuture, executor, FullChunkStatus.ENTITY_TICKING); -- // Paper start - cache ticking ready status -- this.entityTickingChunkFuture.thenAccept(chunkResult -> { -- chunkResult.ifSuccess(chunk -> { -- ChunkHolder.this.isEntityTickingReady = true; -- io.papermc.paper.chunk.system.ChunkSystem.onChunkEntityTicking(chunk, this); -- }); -- }); -- // Paper end -- this.updateChunkToSave(this.entityTickingChunkFuture, "entity ticking"); -- } -- -- if (flag6 && !flag7) { -- // Paper start -- if (this.isEntityTickingReady) { -- io.papermc.paper.chunk.system.ChunkSystem.onChunkNotEntityTicking(this.entityTickingChunkFuture.join().orElseThrow(IllegalStateException::new), 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; -- } -- -- if (!fullchunkstatus1.isOrAfter(fullchunkstatus)) { -- this.demoteFullChunk(chunkStorage, fullchunkstatus1); -- } -- -- this.onLevelChange.onLevelChange(this.pos, this::getQueueLevel, this.ticketLevel, this::setQueueLevel); -- this.oldTicketLevel = this.ticketLevel; -- // CraftBukkit start -- // ChunkLoadEvent: Called after the chunk is loaded: isChunkLoaded returns true and chunk is ready to be modified by plugins. -- if (!fullchunkstatus.isOrAfter(FullChunkStatus.FULL) && fullchunkstatus1.isOrAfter(FullChunkStatus.FULL)) { -- this.getFutureIfPresentUnchecked(ChunkStatus.FULL).thenAccept((either) -> { -- LevelChunk chunk = (LevelChunk) either.orElse(null); -- if (chunk != null) { -- chunkStorage.callbackExecutor.execute(() -> { -- chunk.loadCallback(); -- }); -- } -- }).exceptionally((throwable) -> { -- // ensure exceptions are printed, by default this is not the case -- MinecraftServer.LOGGER.error("Failed to schedule load callback for chunk " + ChunkHolder.this.pos, throwable); -- return null; -- }); -- -- // Run callback right away if the future was already done -- chunkStorage.callbackExecutor.run(); -- } -- // CraftBukkit end -- } -- -- public boolean wasAccessibleSinceLastSave() { -- return this.wasAccessibleSinceLastSave; -+ return this.newChunkHolder.getTicketLevel(); // Paper - rewrite chunk system - } - -- public void refreshAccessibility() { -- this.wasAccessibleSinceLastSave = ChunkLevel.fullStatus(this.ticketLevel).isOrAfter(FullChunkStatus.FULL); -- } -+ // Paper - rewrite chunk system - - public void replaceProtoChunk(ImposterProtoChunk chunk) { -- for (int i = 0; i < this.futures.length(); ++i) { -- CompletableFuture> completablefuture = (CompletableFuture) this.futures.get(i); -- -- if (completablefuture != null) { -- ChunkAccess ichunkaccess = (ChunkAccess) ((ChunkResult) completablefuture.getNow(ChunkHolder.UNLOADED_CHUNK)).orElse((Object) null); -- -- if (ichunkaccess instanceof ProtoChunk) { -- this.futures.set(i, CompletableFuture.completedFuture(ChunkResult.of(chunk))); -- } -- } -- } -- -- this.updateChunkToSave(CompletableFuture.completedFuture(ChunkResult.of(chunk.getWrapped())), "replaceProto"); -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - public List>>> getAllFutures() { -- List>>> list = new ArrayList(); -- -- for (int i = 0; i < ChunkHolder.CHUNK_STATUSES.size(); ++i) { -- list.add(Pair.of((ChunkStatus) ChunkHolder.CHUNK_STATUSES.get(i), (CompletableFuture) this.futures.get(i))); -- } -- -- return list; -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - @FunctionalInterface -@@ -670,15 +395,15 @@ public class ChunkHolder { - - // Paper start - public final boolean isEntityTickingReady() { -- return this.isEntityTickingReady; -+ return this.newChunkHolder.isEntityTickingReady(); // Paper - rewrite chunk system - } - - public final boolean isTickingReady() { -- return this.isTickingReady; -+ return this.newChunkHolder.isTickingReady(); // Paper - rewrite chunk system - } - - public final boolean isFullChunkReady() { -- return this.isFullChunkReady; -+ return this.newChunkHolder.isFullChunkReady(); // Paper - rewrite chunk system - } - // 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 d3f63185edd1db9fab3887ea3f08982435b3a23c..d6ecee1db17cb9eaeffa94b3d8dd150238fdefe5 100644 ---- a/src/main/java/net/minecraft/server/level/ChunkMap.java -+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -122,10 +122,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - public static final int MIN_VIEW_DISTANCE = 2; - public static final int MAX_VIEW_DISTANCE = 32; - public static final int FORCED_TICKET_LEVEL = ChunkLevel.byStatus(FullChunkStatus.ENTITY_TICKING); -- public final Long2ObjectLinkedOpenHashMap updatingChunkMap = new Long2ObjectLinkedOpenHashMap(); -- public volatile Long2ObjectLinkedOpenHashMap visibleChunkMap; -- private final Long2ObjectLinkedOpenHashMap pendingUnloads; -- private final LongSet entitiesInLevel; -+ // Paper - rewrite chunk system - public final ServerLevel level; - private final ThreadedLevelLightEngine lightEngine; - public final BlockableEventLoop mainThreadExecutor; // Paper - public -@@ -134,15 +131,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - private final ChunkGeneratorStructureState chunkGeneratorState; - public final Supplier overworldDataStorage; - private final PoiManager poiManager; -- public final LongSet toDrop; -+ // Paper - rewrite chunk system - private boolean modified; -- private final ChunkTaskPriorityQueueSorter queueSorter; -- private final ProcessorHandle> worldgenMailbox; -- private final ProcessorHandle> mainThreadMailbox; -+ // Paper - rewrite chunk system - public final ChunkProgressListener progressListener; - private final ChunkStatusUpdateListener chunkStatusListener; - public final ChunkMap.ChunkDistanceManager distanceManager; -- private final AtomicInteger tickingGenerated; -+ public final AtomicInteger tickingGenerated; // Paper - public - private final String storageName; - private final PlayerMap playerMap; - public final Int2ObjectMap entityMap; -@@ -150,28 +145,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - private final Long2LongMap chunkSaveCooldowns; - private final Queue unloadQueue; - public int serverViewDistance; -- private WorldGenContext worldGenContext; -- -- // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback() -- public final CallbackExecutor callbackExecutor = new CallbackExecutor(); -- public static final class CallbackExecutor implements java.util.concurrent.Executor, Runnable { -- -- private final java.util.Queue queue = new java.util.ArrayDeque<>(); -- -- @Override -- public void execute(Runnable runnable) { -- this.queue.add(runnable); -- } -- -- @Override -- public void run() { -- Runnable task; -- while ((task = this.queue.poll()) != null) { -- task.run(); -- } -- } -- }; -- // CraftBukkit end -+ private WorldGenContext worldGenContext; public final WorldGenContext getWorldGenContext() { return this.worldGenContext; } // Paper - rewrite chunk system - - // Paper start - distance maps - private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>(); -@@ -181,6 +155,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - int chunkZ = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getZ()); - // Note: players need to be explicitly added to distance maps before they can be updated - this.nearbyPlayers.addPlayer(player); -+ this.level.playerChunkLoader.addPlayer(player); // Paper - replace chunk loader - } - - void removePlayerFromDistanceMaps(ServerPlayer player) { -@@ -188,6 +163,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - int chunkZ = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getZ()); - // Note: players need to be explicitly added to distance maps before they can be updated - this.nearbyPlayers.removePlayer(player); -+ this.level.playerChunkLoader.removePlayer(player); // Paper - replace chunk loader - } - - void updateMaps(ServerPlayer player) { -@@ -195,6 +171,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - int chunkZ = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getZ()); - // Note: players need to be explicitly added to distance maps before they can be updated - this.nearbyPlayers.tickPlayer(player); -+ this.level.playerChunkLoader.updatePlayer(player); // Paper - replace chunk loader - } - // Paper end - // Paper start -@@ -224,17 +201,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - - public final ChunkHolder getUnloadingChunkHolder(int chunkX, int chunkZ) { -- return this.pendingUnloads.get(io.papermc.paper.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ return null; // Paper - rewrite chunk system - } - public final io.papermc.paper.util.player.NearbyPlayers nearbyPlayers; - // Paper end - - public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor executor, BlockableEventLoop mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory, int viewDistance, boolean dsync) { - super(new RegionStorageInfo(session.getLevelId(), world.dimension(), "chunk"), session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync); -- this.visibleChunkMap = this.updatingChunkMap.clone(); -- this.pendingUnloads = new Long2ObjectLinkedOpenHashMap(); -- this.entitiesInLevel = new LongOpenHashSet(); -- this.toDrop = new LongOpenHashSet(); -+ // Paper - rewrite chunk system - this.tickingGenerated = new AtomicInteger(); - this.playerMap = new PlayerMap(); - this.entityMap = new Int2ObjectOpenHashMap(); -@@ -263,19 +237,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - - this.chunkGeneratorState = chunkGenerator.createState(iregistrycustom.lookupOrThrow(Registries.STRUCTURE_SET), this.randomState, j, world.spigotConfig); // Spigot - this.mainThreadExecutor = mainThreadExecutor; -- ProcessorMailbox threadedmailbox = ProcessorMailbox.create(executor, "worldgen"); -+ // Paper - rewrite chunk system - - Objects.requireNonNull(mainThreadExecutor); -- ProcessorHandle mailbox = ProcessorHandle.of("main", mainThreadExecutor::tell); -+ // Paper - rewrite chunk system - - this.progressListener = worldGenerationProgressListener; - this.chunkStatusListener = chunkStatusChangeListener; -- ProcessorMailbox threadedmailbox1 = ProcessorMailbox.create(executor, "light"); -+ // Paper - rewrite chunk system - -- this.queueSorter = new ChunkTaskPriorityQueueSorter(ImmutableList.of(threadedmailbox, mailbox, threadedmailbox1), executor, Integer.MAX_VALUE); -- this.worldgenMailbox = this.queueSorter.getProcessor(threadedmailbox, false); -- this.mainThreadMailbox = this.queueSorter.getProcessor(mailbox, false); -- this.lightEngine = new ThreadedLevelLightEngine(chunkProvider, this, this.level.dimensionType().hasSkyLight(), threadedmailbox1, this.queueSorter.getProcessor(threadedmailbox1, false)); -+ // Paper - rewrite chunk system -+ this.lightEngine = new ThreadedLevelLightEngine(chunkProvider, this, this.level.dimensionType().hasSkyLight(), null, null); // Paper - rewrite chunk system - this.distanceManager = new ChunkMap.ChunkDistanceManager(executor, mainThreadExecutor); - this.overworldDataStorage = persistentStateManagerFactory; - this.poiManager = new PoiManager(new RegionStorageInfo(session.getLevelId(), world.dimension(), "poi"), path.resolve("poi"), dataFixer, dsync, iregistrycustom, world); -@@ -333,23 +305,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - - boolean isChunkTracked(ServerPlayer player, int chunkX, int chunkZ) { -- return player.getChunkTrackingView().contains(chunkX, chunkZ) && !player.connection.chunkSender.isPending(ChunkPos.asLong(chunkX, chunkZ)); -+ // Paper start - rewrite player chunk loader -+ return this.level.playerChunkLoader.isChunkSent(player, chunkX, chunkZ); -+ // Paper end - rewrite player chunk loader - } - - private boolean isChunkOnTrackedBorder(ServerPlayer player, int chunkX, int chunkZ) { -- if (!this.isChunkTracked(player, chunkX, chunkZ)) { -- return false; -- } else { -- for (int k = -1; k <= 1; ++k) { -- for (int l = -1; l <= 1; ++l) { -- if ((k != 0 || l != 0) && !this.isChunkTracked(player, chunkX + k, chunkZ + l)) { -- return true; -- } -- } -- } -- -- return false; -- } -+ // Paper start - rewrite player chunk loader -+ return this.level.playerChunkLoader.isChunkSent(player, chunkX, chunkZ, true); -+ // Paper end - rewrite player chunk loader - } - - protected ThreadedLevelLightEngine getLightEngine() { -@@ -358,20 +322,22 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - - @Nullable - protected ChunkHolder getUpdatingChunkIfPresent(long pos) { -- return (ChunkHolder) this.updatingChunkMap.get(pos); -+ // Paper start - rewrite chunk system -+ io.papermc.paper.chunk.system.scheduling.NewChunkHolder holder = this.level.chunkTaskScheduler.chunkHolderManager.getChunkHolder(pos); -+ return holder == null ? null : holder.vanillaChunkHolder; -+ // Paper end - rewrite chunk system - } - - @Nullable - public ChunkHolder getVisibleChunkIfPresent(long pos) { -- return (ChunkHolder) this.visibleChunkMap.get(pos); -+ // Paper start - rewrite chunk system -+ io.papermc.paper.chunk.system.scheduling.NewChunkHolder holder = this.level.chunkTaskScheduler.chunkHolderManager.getChunkHolder(pos); -+ return holder == null ? null : holder.vanillaChunkHolder; -+ // Paper end - rewrite chunk system - } - - protected IntSupplier getChunkQueueLevel(long pos) { -- return () -> { -- ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos); -- -- return playerchunk == null ? ChunkTaskPriorityQueue.PRIORITY_LEVEL_COUNT - 1 : Math.min(playerchunk.getQueueLevel(), ChunkTaskPriorityQueue.PRIORITY_LEVEL_COUNT - 1); -- }; -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - public String getChunkDebugData(ChunkPos chunkPos) { -@@ -400,80 +366,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - - private CompletableFuture>> getChunkRangeFuture(ChunkHolder centerChunk, int margin, IntFunction distanceToStatus) { -- if (margin == 0) { -- ChunkStatus chunkstatus = (ChunkStatus) distanceToStatus.apply(0); -- -- return centerChunk.getOrScheduleFuture(chunkstatus, this).thenApply((chunkresult) -> { -- return chunkresult.map(List::of); -- }); -- } else { -- List>> list = new ArrayList(); -- List list1 = new ArrayList(); -- ChunkPos chunkcoordintpair = centerChunk.getPos(); -- int j = chunkcoordintpair.x; -- int k = chunkcoordintpair.z; -- -- for (int l = -margin; l <= margin; ++l) { -- for (int i1 = -margin; i1 <= margin; ++i1) { -- int j1 = Math.max(Math.abs(i1), Math.abs(l)); -- ChunkPos chunkcoordintpair1 = new ChunkPos(j + i1, k + l); -- long k1 = chunkcoordintpair1.toLong(); -- ChunkHolder playerchunk1 = this.getUpdatingChunkIfPresent(k1); -- -- if (playerchunk1 == null) { -- return CompletableFuture.completedFuture(ChunkResult.error(() -> { -- return "Unloaded " + String.valueOf(chunkcoordintpair1); -- })); -- } -- -- ChunkStatus chunkstatus1 = (ChunkStatus) distanceToStatus.apply(j1); -- CompletableFuture> completablefuture = playerchunk1.getOrScheduleFuture(chunkstatus1, this); -- -- list1.add(playerchunk1); -- list.add(completablefuture); -- } -- } -- -- CompletableFuture>> completablefuture1 = Util.sequence(list); -- CompletableFuture>> completablefuture2 = completablefuture1.thenApply((list2) -> { -- List list3 = Lists.newArrayList(); -- // CraftBukkit start - decompile error -- int cnt = 0; -- -- for (Iterator iterator = list2.iterator(); iterator.hasNext(); ++cnt) { -- final int l1 = cnt; -- // CraftBukkit end -- ChunkResult chunkresult = (ChunkResult) iterator.next(); -- -- if (chunkresult == null) { -- throw this.debugFuturesAndCreateReportedException(new IllegalStateException("At least one of the chunk futures were null"), "n/a"); -- } -- -- ChunkAccess ichunkaccess = (ChunkAccess) chunkresult.orElse(null); // CraftBukkit - decompile error -- -- if (ichunkaccess == null) { -- return ChunkResult.error(() -> { -- String s = String.valueOf(new ChunkPos(j + l1 % (margin * 2 + 1), k + l1 / (margin * 2 + 1))); -- -- return "Unloaded " + s + " " + chunkresult.getError(); -- }); -- } -- -- list3.add(ichunkaccess); -- } -- -- return ChunkResult.of(list3); -- }); -- Iterator iterator = list1.iterator(); -- -- while (iterator.hasNext()) { -- ChunkHolder playerchunk2 = (ChunkHolder) iterator.next(); -- -- playerchunk2.addSaveDependency("getChunkRangeFuture " + String.valueOf(chunkcoordintpair) + " " + margin, completablefuture2); -- } -- -- return completablefuture2; -- } -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - public ReportedException debugFuturesAndCreateReportedException(IllegalStateException exception, String details) { -@@ -503,263 +396,72 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - - public CompletableFuture> prepareEntityTickingChunk(ChunkHolder chunk) { -- return this.getChunkRangeFuture(chunk, 2, (i) -> { -- return ChunkStatus.FULL; -- }).thenApplyAsync((chunkresult) -> { -- return chunkresult.map((list) -> { -- return (LevelChunk) list.get(list.size() / 2); -- }); -- }, this.mainThreadExecutor); -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - @Nullable - ChunkHolder updateChunkScheduling(long pos, int level, @Nullable ChunkHolder holder, int k) { -- if (!ChunkLevel.isLoaded(k) && !ChunkLevel.isLoaded(level)) { -- return holder; -- } else { -- if (holder != null) { -- holder.setTicketLevel(level); -- } -- -- if (holder != null) { -- if (!ChunkLevel.isLoaded(level)) { -- this.toDrop.add(pos); -- } else { -- this.toDrop.remove(pos); -- } -- } -- -- if (ChunkLevel.isLoaded(level) && holder == null) { -- holder = (ChunkHolder) this.pendingUnloads.remove(pos); -- if (holder != null) { -- holder.setTicketLevel(level); -- } else { -- holder = new ChunkHolder(new ChunkPos(pos), level, this.level, this.lightEngine, this.queueSorter, this); -- // Paper start -- io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderCreate(this.level, holder); -- // Paper end -- } -- -- // Paper start -- holder.onChunkAdd(); -- // Paper end -- this.updatingChunkMap.put(pos, holder); -- this.modified = true; -- } -- -- return holder; -- } -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - @Override - public void close() throws IOException { -- try { -- this.queueSorter.close(); -- this.poiManager.close(); -- } finally { -- super.close(); -- } -+ throw new UnsupportedOperationException("Use ServerChunkCache#close"); // Paper - rewrite chunk system -+ } - -+ // Paper start - rewrite chunk system -+ protected void saveIncrementally() { -+ this.level.chunkTaskScheduler.chunkHolderManager.autoSave(); // Paper - rewrite chunk system - } -+ // Paper end - - rewrite chunk system - - protected void saveAllChunks(boolean flush) { -- if (flush) { -- List list = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).toList(); // Paper -- MutableBoolean mutableboolean = new MutableBoolean(); -- -- do { -- mutableboolean.setFalse(); -- list.stream().map((playerchunk) -> { -- CompletableFuture completablefuture; -- -- do { -- completablefuture = playerchunk.getChunkToSave(); -- BlockableEventLoop iasynctaskhandler = this.mainThreadExecutor; -- -- Objects.requireNonNull(completablefuture); -- iasynctaskhandler.managedBlock(completablefuture::isDone); -- } while (completablefuture != playerchunk.getChunkToSave()); -- -- return (ChunkAccess) completablefuture.join(); -- }).filter((ichunkaccess) -> { -- return ichunkaccess instanceof ImposterProtoChunk || ichunkaccess instanceof LevelChunk; -- }).filter(this::save).forEach((ichunkaccess) -> { -- mutableboolean.setTrue(); -- }); -- } while (mutableboolean.isTrue()); -- -- this.processUnloads(() -> { -- return true; -- }); -- this.flushWorker(); -- } else { -- io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).forEach(this::saveChunkIfNeeded); -- } -- -+ this.level.chunkTaskScheduler.chunkHolderManager.saveAllChunks(flush, false, false); // Paper - rewrite chunk system - } - - protected void tick(BooleanSupplier shouldKeepTicking) { - ProfilerFiller gameprofilerfiller = this.level.getProfiler(); - -+ try (Timing ignored = this.level.timings.poiUnload.startTiming()) { // Paper - gameprofilerfiller.push("poi"); - this.poiManager.tick(shouldKeepTicking); -+ } // Paper - gameprofilerfiller.popPush("chunk_unload"); - if (!this.level.noSave()) { -+ try (Timing ignored = this.level.timings.chunkUnload.startTiming()) { // Paper - this.processUnloads(shouldKeepTicking); -+ } // Paper - } - - gameprofilerfiller.pop(); - } - - public boolean hasWork() { -- return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || io.papermc.paper.chunk.system.ChunkSystem.hasAnyChunkHolders(this.level) || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); // Paper -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - 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); -- -- if (playerchunk != null) { -- playerchunk.onChunkRemove(); // Paper -- this.pendingUnloads.put(j, playerchunk); -- this.modified = true; -- ++i; -- this.scheduleUnload(j, playerchunk); -- } -- } -- -- int k = Math.max(0, this.unloadQueue.size() - 2000); -- -- Runnable runnable; -- -- while ((shouldKeepTicking.getAsBoolean() || k > 0) && (runnable = (Runnable) this.unloadQueue.poll()) != null) { -- --k; -- runnable.run(); -- } -- -- int l = 0; -- Iterator objectiterator = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper -- -- while (l < 20 && shouldKeepTicking.getAsBoolean() && objectiterator.hasNext()) { -- if (this.saveChunkIfNeeded((ChunkHolder) objectiterator.next())) { -- ++l; -- } -- } -+ this.level.chunkTaskScheduler.chunkHolderManager.processUnloads(); // Paper - rewrite chunk system - - } - - private void scheduleUnload(long pos, ChunkHolder holder) { -- CompletableFuture completablefuture = holder.getChunkToSave(); -- Consumer consumer = (ichunkaccess) -> { // CraftBukkit - decompile error -- CompletableFuture completablefuture1 = holder.getChunkToSave(); -- -- if (completablefuture1 != completablefuture) { -- this.scheduleUnload(pos, holder); -- } else { -- // Paper start -- boolean removed; -- if ((removed = this.pendingUnloads.remove(pos, holder)) && ichunkaccess != null) { -- io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderDelete(this.level, holder); -- // Paper end -- if (ichunkaccess instanceof LevelChunk) { -- ((LevelChunk) ichunkaccess).setLoaded(false); -- } -- -- this.save(ichunkaccess); -- if (this.entitiesInLevel.remove(pos) && ichunkaccess instanceof LevelChunk) { -- LevelChunk chunk = (LevelChunk) ichunkaccess; -- -- this.level.unload(chunk); -- } -- -- this.lightEngine.updateChunkStatus(ichunkaccess.getPos()); -- this.lightEngine.tryScheduleUpdate(); -- this.progressListener.onStatusChange(ichunkaccess.getPos(), (ChunkStatus) null); -- this.chunkSaveCooldowns.remove(ichunkaccess.getPos().toLong()); -- } else if (removed) { // Paper start -- io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderDelete(this.level, holder); -- } // Paper end -- -- } -- }; -- Queue queue = this.unloadQueue; -- -- Objects.requireNonNull(this.unloadQueue); -- completablefuture.thenAcceptAsync(consumer, queue::add).whenComplete((ovoid, throwable) -> { -- if (throwable != null) { -- ChunkMap.LOGGER.error("Failed to save chunk {}", holder.getPos(), throwable); -- } -- -- }); -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - protected boolean promoteChunkMap() { -- if (!this.modified) { -- return false; -- } else { -- this.visibleChunkMap = this.updatingChunkMap.clone(); -- this.modified = false; -- return true; -- } -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - public CompletableFuture> schedule(ChunkHolder holder, ChunkStatus requiredStatus) { -- ChunkPos chunkcoordintpair = holder.getPos(); -- -- if (requiredStatus == ChunkStatus.EMPTY) { -- return this.scheduleChunkLoad(chunkcoordintpair).thenApply(ChunkResult::of); -- } else { -- if (requiredStatus == ChunkStatus.LIGHT) { -- this.distanceManager.addTicket(TicketType.LIGHT, chunkcoordintpair, ChunkLevel.byStatus(ChunkStatus.LIGHT), chunkcoordintpair); -- } -- -- if (!requiredStatus.hasLoadDependencies()) { -- ChunkAccess ichunkaccess = (ChunkAccess) ((ChunkResult) holder.getOrScheduleFuture(requiredStatus.getParent(), this).getNow(ChunkHolder.UNLOADED_CHUNK)).orElse((Object) null); -- -- if (ichunkaccess != null && ichunkaccess.getStatus().isOrAfter(requiredStatus)) { -- CompletableFuture completablefuture = requiredStatus.load(this.worldGenContext, (ichunkaccess1) -> { -- return this.protoChunkToFullChunk(holder, ichunkaccess1); -- }, ichunkaccess); -- -- this.progressListener.onStatusChange(chunkcoordintpair, requiredStatus); -- return completablefuture.thenApply(ChunkResult::of); -- } -- } -- -- return this.scheduleChunkGeneration(holder, requiredStatus); -- } -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - private CompletableFuture scheduleChunkLoad(ChunkPos pos) { -- return this.readChunk(pos).thenApply((optional) -> { -- return optional.filter((nbttagcompound) -> { -- boolean flag = ChunkMap.isChunkDataValid(nbttagcompound); -- -- if (!flag) { -- ChunkMap.LOGGER.error("Chunk file at {} is missing level data, skipping", pos); -- } -- -- return flag; -- }); -- }).thenApplyAsync((optional) -> { -- this.level.getProfiler().incrementCounter("chunkLoad"); -- if (optional.isPresent()) { -- ProtoChunk protochunk = ChunkSerializer.read(this.level, this.poiManager, pos, (CompoundTag) optional.get()); -- -- this.markPosition(pos, protochunk.getStatus().getChunkType()); -- return protochunk; -- } else { -- return this.createEmptyChunk(pos); -- } -- }, this.mainThreadExecutor).exceptionallyAsync((throwable) -> { -- return this.handleChunkLoadFailure(throwable, pos); -- }, this.mainThreadExecutor); -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - -- private static boolean isChunkDataValid(CompoundTag nbt) { -+ public static boolean isChunkDataValid(CompoundTag nbt) { // Paper - async chunk loading - return nbt.contains("Status", 8); - } - -@@ -816,60 +518,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - - private CompletableFuture> scheduleChunkGeneration(ChunkHolder holder, ChunkStatus requiredStatus) { -- ChunkPos chunkcoordintpair = holder.getPos(); -- CompletableFuture>> completablefuture = this.getChunkRangeFuture(holder, requiredStatus.getRange(), (i) -> { -- return this.getDependencyStatus(requiredStatus, i); -- }); -- -- this.level.getProfiler().incrementCounter(() -> { -- return "chunkGenerate " + String.valueOf(requiredStatus); -- }); -- Executor executor = (runnable) -> { -- this.worldgenMailbox.tell(ChunkTaskPriorityQueueSorter.message(holder, runnable)); -- }; -- -- return completablefuture.thenComposeAsync((chunkresult) -> { -- List list = (List) chunkresult.orElse(null); // CraftBukkit - decompile error -- -- if (list == null) { -- this.releaseLightTicket(chunkcoordintpair); -- Objects.requireNonNull(chunkresult); -- return CompletableFuture.completedFuture(ChunkResult.error(chunkresult::getError)); -- } else { -- try { -- ChunkAccess ichunkaccess = (ChunkAccess) list.get(list.size() / 2); -- CompletableFuture completablefuture1; -- -- if (ichunkaccess.getStatus().isOrAfter(requiredStatus)) { -- completablefuture1 = requiredStatus.load(this.worldGenContext, (ichunkaccess1) -> { -- return this.protoChunkToFullChunk(holder, ichunkaccess1); -- }, ichunkaccess); -- } else { -- completablefuture1 = requiredStatus.generate(this.worldGenContext, executor, (ichunkaccess1) -> { -- return this.protoChunkToFullChunk(holder, ichunkaccess1); -- }, list); -- } -- -- this.progressListener.onStatusChange(chunkcoordintpair, requiredStatus); -- return completablefuture1.thenApply(ChunkResult::of); -- } catch (Exception exception) { -- exception.getStackTrace(); -- CrashReport crashreport = CrashReport.forThrowable(exception, "Exception generating new chunk"); -- CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Chunk to be generated"); -- -- crashreportsystemdetails.setDetail("Status being generated", () -> { -- return BuiltInRegistries.CHUNK_STATUS.getKey(requiredStatus).toString(); -- }); -- crashreportsystemdetails.setDetail("Location", (Object) String.format(Locale.ROOT, "%d,%d", chunkcoordintpair.x, chunkcoordintpair.z)); -- crashreportsystemdetails.setDetail("Position hash", (Object) ChunkPos.asLong(chunkcoordintpair.x, chunkcoordintpair.z)); -- crashreportsystemdetails.setDetail("Generator", (Object) this.generator); -- this.mainThreadExecutor.execute(() -> { -- throw new ReportedException(crashreport); -- }); -- throw new ReportedException(crashreport); -- } -- } -- }, executor); -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - protected void releaseLightTicket(ChunkPos pos) { -@@ -880,7 +529,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - })); - } - -- private ChunkStatus getDependencyStatus(ChunkStatus centerChunkTargetStatus, int distance) { -+ public static ChunkStatus getDependencyStatus(ChunkStatus centerChunkTargetStatus, int distance) { // Paper -> public, static - ChunkStatus chunkstatus1; - - if (distance == 0) { -@@ -892,7 +541,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - return chunkstatus1; - } - -- private static void postLoadProtoChunk(ServerLevel world, List nbt) { -+ public static void postLoadProtoChunk(ServerLevel world, List nbt, ChunkPos position) { // Paper - public and add chunk position parameter - if (!nbt.isEmpty()) { - // CraftBukkit start - these are spawned serialized (DefinedStructure) and we don't call an add event below at the moment due to ordering complexities - world.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(nbt, world).filter((entity) -> { -@@ -908,45 +557,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - checkDupeUUID(world, entity); // Paper - duplicate uuid resolving - return !needsRemoval; -- })); -+ }), position); // Paper - rewrite chunk system - // CraftBukkit end - } - - } - - private CompletableFuture protoChunkToFullChunk(ChunkHolder playerchunk, ChunkAccess ichunkaccess) { -- return CompletableFuture.supplyAsync(() -> { -- ChunkPos chunkcoordintpair = playerchunk.getPos(); -- ProtoChunk protochunk = (ProtoChunk) ichunkaccess; -- LevelChunk chunk; -- -- if (protochunk instanceof ImposterProtoChunk) { -- chunk = ((ImposterProtoChunk) protochunk).getWrapped(); -- } else { -- chunk = new LevelChunk(this.level, protochunk, (chunk1) -> { -- ChunkMap.postLoadProtoChunk(this.level, protochunk.getEntities()); -- }); -- playerchunk.replaceProtoChunk(new ImposterProtoChunk(chunk, false)); -- } -- -- chunk.setFullStatus(() -> { -- return ChunkLevel.fullStatus(playerchunk.getTicketLevel()); -- }); -- chunk.runPostLoad(); -- if (this.entitiesInLevel.add(chunkcoordintpair.toLong())) { -- chunk.setLoaded(true); -- chunk.registerAllBlockEntitiesAfterLevelLoad(); -- chunk.registerTickContainerInLevel(this.level); -- } -- -- return chunk; -- }, (runnable) -> { -- ProcessorHandle mailbox = this.mainThreadMailbox; -- long i = playerchunk.getPos().toLong(); -- -- Objects.requireNonNull(playerchunk); -- mailbox.tell(ChunkTaskPriorityQueueSorter.message(runnable, i, playerchunk::getTicketLevel)); -- }); -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - // Paper start - duplicate uuid resolving -@@ -990,61 +608,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - // Paper end - duplicate uuid resolving - - public CompletableFuture> prepareTickingChunk(ChunkHolder holder) { -- CompletableFuture>> completablefuture = this.getChunkRangeFuture(holder, 1, (i) -> { -- return ChunkStatus.FULL; -- }); -- CompletableFuture> completablefuture1 = completablefuture.thenApplyAsync((chunkresult) -> { -- return chunkresult.map((list) -> { -- return (LevelChunk) list.get(list.size() / 2); -- }); -- }, (runnable) -> { -- this.mainThreadMailbox.tell(ChunkTaskPriorityQueueSorter.message(holder, runnable)); -- }).thenApplyAsync((chunkresult) -> { -- return chunkresult.ifSuccess((chunk) -> { -- chunk.postProcessGeneration(); -- this.level.startTickingChunk(chunk); -- CompletableFuture completablefuture2 = holder.getChunkSendSyncFuture(); -- -- if (completablefuture2.isDone()) { -- this.onChunkReadyToSend(chunk); -- } else { -- completablefuture2.thenAcceptAsync((object) -> { -- this.onChunkReadyToSend(chunk); -- }, this.mainThreadExecutor); -- } -- -- }); -- }, this.mainThreadExecutor); -- -- completablefuture1.handle((chunkresult, throwable) -> { -- this.tickingGenerated.getAndIncrement(); -- return null; -- }); -- return completablefuture1; -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - private void onChunkReadyToSend(LevelChunk chunk) { -- ChunkPos chunkcoordintpair = chunk.getPos(); -- Iterator iterator = this.playerMap.getAllPlayers().iterator(); -- -- while (iterator.hasNext()) { -- ServerPlayer entityplayer = (ServerPlayer) iterator.next(); -- -- if (entityplayer.getChunkTrackingView().contains(chunkcoordintpair)) { -- ChunkMap.markChunkPendingToSend(entityplayer, chunk); -- } -- } -+ throw new UnsupportedOperationException(); // Paper - rewrite player chunk loader - - } - - public CompletableFuture> prepareAccessibleChunk(ChunkHolder holder) { -- return this.getChunkRangeFuture(holder, 1, ChunkStatus::getStatusAroundFullChunk).thenApplyAsync((chunkresult) -> { -- return chunkresult.map((list) -> { -- return (LevelChunk) list.get(list.size() / 2); -- }); -- }, (runnable) -> { -- this.mainThreadMailbox.tell(ChunkTaskPriorityQueueSorter.message(holder, runnable)); -- }); -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - public int getTickingGenerated() { -@@ -1052,96 +625,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - - private boolean saveChunkIfNeeded(ChunkHolder chunkHolder) { -- if (!chunkHolder.wasAccessibleSinceLastSave()) { -- return false; -- } else { -- ChunkAccess ichunkaccess = (ChunkAccess) chunkHolder.getChunkToSave().getNow(null); // CraftBukkit - decompile error -- -- if (!(ichunkaccess instanceof ImposterProtoChunk) && !(ichunkaccess instanceof LevelChunk)) { -- return false; -- } else { -- long i = ichunkaccess.getPos().toLong(); -- long j = this.chunkSaveCooldowns.getOrDefault(i, -1L); -- long k = System.currentTimeMillis(); -- -- if (k < j) { -- return false; -- } else { -- boolean flag = this.save(ichunkaccess); -- -- chunkHolder.refreshAccessibility(); -- if (flag) { -- this.chunkSaveCooldowns.put(i, k + 10000L); -- } -- -- return flag; -- } -- } -- } -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - public boolean save(ChunkAccess chunk) { -- this.poiManager.flush(chunk.getPos()); -- if (!chunk.isUnsaved()) { -- return false; -- } else { -- chunk.setUnsaved(false); -- ChunkPos chunkcoordintpair = chunk.getPos(); -- -- try { -- ChunkStatus chunkstatus = chunk.getStatus(); -- -- if (chunkstatus.getChunkType() != ChunkType.LEVELCHUNK) { -- if (this.isExistingChunkFull(chunkcoordintpair)) { -- return false; -- } -- -- if (chunkstatus == ChunkStatus.EMPTY && chunk.getAllStarts().values().stream().noneMatch(StructureStart::isValid)) { -- return false; -- } -- } -- -- this.level.getProfiler().incrementCounter("chunkSave"); -- CompoundTag nbttagcompound = ChunkSerializer.write(this.level, chunk); -- -- this.write(chunkcoordintpair, nbttagcompound).exceptionallyAsync((throwable) -> { -- this.level.getServer().reportChunkSaveFailure(chunkcoordintpair); -- return null; -- }, this.mainThreadExecutor); -- this.markPosition(chunkcoordintpair, chunkstatus.getChunkType()); -- return true; -- } catch (Exception exception) { -- ChunkMap.LOGGER.error("Failed to save chunk {},{}", new Object[]{chunkcoordintpair.x, chunkcoordintpair.z, exception}); -- this.level.getServer().reportChunkSaveFailure(chunkcoordintpair); -- return false; -- } -- } -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - private boolean isExistingChunkFull(ChunkPos pos) { -- byte b0 = this.chunkTypeCache.get(pos.toLong()); -- -- if (b0 != 0) { -- return b0 == 1; -- } else { -- CompoundTag nbttagcompound; -- -- try { -- nbttagcompound = (CompoundTag) ((Optional) this.readChunk(pos).join()).orElse((Object) null); -- if (nbttagcompound == null) { -- this.markPositionReplaceable(pos); -- return false; -- } -- } catch (Exception exception) { -- ChunkMap.LOGGER.error("Failed to read chunk {}", pos, exception); -- this.markPositionReplaceable(pos); -- return false; -- } -- -- ChunkType chunktype = ChunkSerializer.getChunkTypeFromTag(nbttagcompound); -- -- return this.markPosition(pos, chunktype) == 1; -- } -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - public void setServerViewDistance(int watchDistance) { // Paper - public -@@ -1149,37 +641,36 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - - if (j != this.serverViewDistance) { - this.serverViewDistance = j; -- this.distanceManager.updatePlayerTickets(this.serverViewDistance); -- Iterator iterator = this.playerMap.getAllPlayers().iterator(); -+ this.level.playerChunkLoader.setLoadDistance(this.serverViewDistance + 1); // Paper - replace player loader system -+ } - -- while (iterator.hasNext()) { -- ServerPlayer entityplayer = (ServerPlayer) iterator.next(); -+ } - -- this.updateChunkTracking(entityplayer); -- } -- } -+ // Paper start - replace player loader system -+ public void setTickViewDistance(int distance) { -+ this.level.playerChunkLoader.setTickDistance(distance); -+ } - -+ public void setSendViewDistance(int distance) { -+ this.level.playerChunkLoader.setSendDistance(distance); - } -+ // Paper end - replace player loader system - - public int getPlayerViewDistance(ServerPlayer player) { // Paper - public -- return Mth.clamp(player.requestedViewDistance(), 2, this.serverViewDistance); -+ return io.papermc.paper.chunk.system.ChunkSystem.getSendViewDistance(player); // Paper - per player view distance - } - - private void markChunkPendingToSend(ServerPlayer player, ChunkPos pos) { -- LevelChunk chunk = this.getChunkToSend(pos.toLong()); -- -- if (chunk != null) { -- ChunkMap.markChunkPendingToSend(player, chunk); -- } -+ throw new UnsupportedOperationException(); // Paper - per player view distance - - } - - private static void markChunkPendingToSend(ServerPlayer player, LevelChunk chunk) { -- player.connection.chunkSender.markChunkPendingToSend(chunk); -+ throw new UnsupportedOperationException(); // Paper - rewrite player chunk loader - } - - private static void dropChunk(ServerPlayer player, ChunkPos pos) { -- player.connection.chunkSender.dropChunk(player, pos); -+ // Paper - rewrite player chunk loader - } - - @Nullable -@@ -1202,30 +693,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(); -- Iterator objectbidirectionaliterator = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper -- -- while (objectbidirectionaliterator.hasNext()) { -- ChunkHolder playerchunk = objectbidirectionaliterator.next(); // Paper -- long i = playerchunk.pos.toLong(); // Paper -- ChunkPos chunkcoordintpair = new ChunkPos(i); -- // Paper -- Optional optional = Optional.ofNullable(playerchunk.getLastAvailable()); -- Optional optional1 = optional.flatMap((ichunkaccess) -> { -- return ichunkaccess instanceof LevelChunk ? Optional.of((LevelChunk) ichunkaccess) : Optional.empty(); -- }); -- -- // 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(); -- }).orElse(0), tickingtracker.getTicketDebugString(i), tickingtracker.getLevel(i), optional1.map((chunk) -> { -- return chunk.getBlockTicks().count(); -- }).orElse(0), optional1.map((chunk) -> { -- return chunk.getFluidTicks().count(); -- }).orElse(0)); -- } -- -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - private static String printFuture(CompletableFuture> future) { -@@ -1240,6 +708,32 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - } - -+ // Paper start - Asynchronous chunk io -+ @Nullable -+ @Override -+ public CompoundTag readSync(ChunkPos chunkcoordintpair) throws IOException { -+ if (!io.papermc.paper.chunk.system.io.RegionFileIOThread.isRegionFileThread()) { -+ return io.papermc.paper.chunk.system.io.RegionFileIOThread.loadData( -+ this.level, chunkcoordintpair.x, chunkcoordintpair.z, io.papermc.paper.chunk.system.io.RegionFileIOThread.RegionFileType.CHUNK_DATA, -+ io.papermc.paper.chunk.system.io.RegionFileIOThread.getIOBlockingPriorityForCurrentThread() -+ ); -+ } -+ return super.readSync(chunkcoordintpair); -+ } -+ -+ @Override -+ public CompletableFuture write(ChunkPos chunkcoordintpair, CompoundTag nbttagcompound) throws IOException { -+ if (!io.papermc.paper.chunk.system.io.RegionFileIOThread.isRegionFileThread()) { -+ io.papermc.paper.chunk.system.io.RegionFileIOThread.scheduleSave( -+ this.level, chunkcoordintpair.x, chunkcoordintpair.z, nbttagcompound, -+ io.papermc.paper.chunk.system.io.RegionFileIOThread.RegionFileType.CHUNK_DATA); -+ return null; -+ } -+ super.write(chunkcoordintpair, nbttagcompound); -+ return null; -+ } -+ // Paper end -+ - private CompletableFuture> readChunk(ChunkPos chunkPos) { - return this.read(chunkPos).thenApplyAsync((optional) -> { - return optional.map((nbttagcompound) -> this.upgradeChunkTag(nbttagcompound, chunkPos)); // CraftBukkit -@@ -1340,8 +834,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - this.distanceManager.addPlayer(SectionPos.of((EntityAccess) player), player); - } - -- player.setChunkTrackingView(ChunkTrackingView.EMPTY); -- this.updateChunkTracking(player); -+ // Paper - handled by player chunk loader - this.addPlayerToDistanceMaps(player); // Paper - distance maps - } else { - SectionPos sectionposition = player.getLastSectionPos(); -@@ -1352,7 +845,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - - this.removePlayerFromDistanceMaps(player); // Paper - distance maps -- this.applyChunkTrackingView(player, ChunkTrackingView.EMPTY); -+ // Paper - handled by player chunk loader - } - - } -@@ -1400,71 +893,30 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - this.playerMap.unIgnorePlayer(player); - } - -- this.updateChunkTracking(player); -+ // Paper - replaced by PlayerChunkLoader - } - - this.updateMaps(player); // Paper - distance maps - } - - private void updateChunkTracking(ServerPlayer player) { -- ChunkPos chunkcoordintpair = player.chunkPosition(); -- int i = this.getPlayerViewDistance(player); -- ChunkTrackingView chunktrackingview = player.getChunkTrackingView(); -- -- if (chunktrackingview instanceof ChunkTrackingView.Positioned chunktrackingview_a) { -- if (chunktrackingview_a.center().equals(chunkcoordintpair) && chunktrackingview_a.viewDistance() == i) { -- return; -- } -- } -- -- this.applyChunkTrackingView(player, ChunkTrackingView.of(chunkcoordintpair, i)); -+ throw new UnsupportedOperationException(); // Paper - replaced by PlayerChunkLoader - } - - private void applyChunkTrackingView(ServerPlayer player, ChunkTrackingView chunkFilter) { -- if (player.level() == this.level) { -- ChunkTrackingView chunktrackingview1 = player.getChunkTrackingView(); -- -- if (chunkFilter instanceof ChunkTrackingView.Positioned) { -- label15: -- { -- ChunkTrackingView.Positioned chunktrackingview_a = (ChunkTrackingView.Positioned) chunkFilter; -- -- if (chunktrackingview1 instanceof ChunkTrackingView.Positioned) { -- ChunkTrackingView.Positioned chunktrackingview_a1 = (ChunkTrackingView.Positioned) chunktrackingview1; -- -- if (chunktrackingview_a1.center().equals(chunktrackingview_a.center())) { -- break label15; -- } -- } -- -- player.connection.send(new ClientboundSetChunkCacheCenterPacket(chunktrackingview_a.center().x, chunktrackingview_a.center().z)); -- } -- } -- -- ChunkTrackingView.difference(chunktrackingview1, chunkFilter, (chunkcoordintpair) -> { -- this.markChunkPendingToSend(player, chunkcoordintpair); -- }, (chunkcoordintpair) -> { -- ChunkMap.dropChunk(player, chunkcoordintpair); -- }); -- player.setChunkTrackingView(chunkFilter); -- } -+ throw new UnsupportedOperationException(); // Paper - replaced by PlayerChunkLoader - } - - @Override - public List getPlayers(ChunkPos chunkPos, boolean onlyOnWatchDistanceEdge) { -- Set set = this.playerMap.getAllPlayers(); -- Builder builder = ImmutableList.builder(); -- Iterator iterator = set.iterator(); -- -- while (iterator.hasNext()) { -- ServerPlayer entityplayer = (ServerPlayer) iterator.next(); -- -- if (onlyOnWatchDistanceEdge && this.isChunkOnTrackedBorder(entityplayer, chunkPos.x, chunkPos.z) || !onlyOnWatchDistanceEdge && this.isChunkTracked(entityplayer, chunkPos.x, chunkPos.z)) { -- builder.add(entityplayer); -- } -+ // Paper start - per player view distance -+ ChunkHolder holder = this.getVisibleChunkIfPresent(chunkPos.toLong()); -+ if (holder == null) { -+ return new java.util.ArrayList<>(); -+ } else { -+ return holder.getPlayers(onlyOnWatchDistanceEdge); - } -- -- return builder.build(); -+ // Paper end - per player view distance - } - - public void addEntity(Entity entity) { -@@ -1535,13 +987,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - - protected void tick() { -- Iterator iterator = this.playerMap.getAllPlayers().iterator(); -- -- while (iterator.hasNext()) { -- ServerPlayer entityplayer = (ServerPlayer) iterator.next(); -- -- this.updateChunkTracking(entityplayer); -- } -+ // Paper - replaced by PlayerChunkLoader - - List list = Lists.newArrayList(); - List list1 = this.level.players(); -@@ -1648,16 +1094,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - - public void waitForLightBeforeSending(ChunkPos centerPos, int radius) { -- int j = radius + 1; -- -- ChunkPos.rangeClosed(centerPos, j).forEach((chunkcoordintpair1) -> { -- ChunkHolder playerchunk = this.getVisibleChunkIfPresent(chunkcoordintpair1.toLong()); -- -- if (playerchunk != null) { -- playerchunk.addSendDependency(this.lightEngine.waitForPendingTasks(chunkcoordintpair1.x, chunkcoordintpair1.z)); -- } -- -- }); -+ // Paper - rewrite player chunk loader - } - - public class ChunkDistanceManager extends DistanceManager { // Paper - public -@@ -1668,7 +1105,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - - @Override - protected boolean isChunkToRemove(long pos) { -- return ChunkMap.this.toDrop.contains(pos); -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - @Nullable -diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java -index 7a48ae2ba962ff56d0abff581b51f28b48bd9aae..ed5154e41ca858f4d6b4d1c276c66831c038d2a6 100644 ---- a/src/main/java/net/minecraft/server/level/DistanceManager.java -+++ b/src/main/java/net/minecraft/server/level/DistanceManager.java -@@ -38,65 +38,28 @@ import org.slf4j.Logger; - - public abstract class DistanceManager { - -+ // Paper start - rewrite chunk system -+ public io.papermc.paper.chunk.system.scheduling.ChunkHolderManager getChunkHolderManager() { -+ return this.chunkMap.level.chunkTaskScheduler.chunkHolderManager; -+ } -+ // Paper end - rewrite chunk system -+ - static final Logger LOGGER = LogUtils.getLogger(); - static final int PLAYER_TICKET_LEVEL = ChunkLevel.byStatus(FullChunkStatus.ENTITY_TICKING); - private static final int INITIAL_TICKET_LIST_CAPACITY = 4; - final Long2ObjectMap> playersPerChunk = new Long2ObjectOpenHashMap(); -- public final Long2ObjectOpenHashMap>> tickets = new Long2ObjectOpenHashMap(); -- private final DistanceManager.ChunkTicketTracker ticketTracker = new DistanceManager.ChunkTicketTracker(); -+ // Paper - rewrite chunk system - private final DistanceManager.FixedPlayerDistanceChunkTracker naturalSpawnChunkCounter = new DistanceManager.FixedPlayerDistanceChunkTracker(8); -- private final TickingTracker tickingTicketsTracker = new TickingTracker(); -- private final DistanceManager.PlayerTicketTracker playerTicketManager = new DistanceManager.PlayerTicketTracker(32); -- final Set chunksToUpdateFutures = Sets.newHashSet(); -- final ChunkTaskPriorityQueueSorter ticketThrottler; -- final ProcessorHandle> ticketThrottlerInput; -- final ProcessorHandle ticketThrottlerReleaser; -- final LongSet ticketsToRelease = new LongOpenHashSet(); -- final Executor mainThreadExecutor; -- private long ticketTickCounter; -- public int simulationDistance = 10; -+ // Paper - rewrite chunk system - private final ChunkMap chunkMap; // Paper - - protected DistanceManager(Executor workerExecutor, Executor mainThreadExecutor, ChunkMap chunkMap) { -- Objects.requireNonNull(mainThreadExecutor); -- ProcessorHandle mailbox = ProcessorHandle.of("player ticket throttler", mainThreadExecutor::execute); -- ChunkTaskPriorityQueueSorter chunktaskqueuesorter = new ChunkTaskPriorityQueueSorter(ImmutableList.of(mailbox), workerExecutor, 4); -- -- this.ticketThrottler = chunktaskqueuesorter; -- this.ticketThrottlerInput = chunktaskqueuesorter.getProcessor(mailbox, true); -- this.ticketThrottlerReleaser = chunktaskqueuesorter.getReleaseProcessor(mailbox); -- this.mainThreadExecutor = mainThreadExecutor; -+ // Paper - rewrite chunk system - this.chunkMap = chunkMap; // Paper - } - - protected void purgeStaleTickets() { -- ++this.ticketTickCounter; -- ObjectIterator>>> objectiterator = this.tickets.long2ObjectEntrySet().fastIterator(); -- -- while (objectiterator.hasNext()) { -- Entry>> entry = (Entry) objectiterator.next(); -- Iterator> iterator = ((SortedArraySet) entry.getValue()).iterator(); -- boolean flag = false; -- -- while (iterator.hasNext()) { -- Ticket ticket = (Ticket) iterator.next(); -- -- if (ticket.timedOut(this.ticketTickCounter)) { -- iterator.remove(); -- flag = true; -- this.tickingTicketsTracker.removeTicket(entry.getLongKey(), ticket); -- } -- } -- -- if (flag) { -- this.ticketTracker.update(entry.getLongKey(), DistanceManager.getTicketLevelAt((SortedArraySet) entry.getValue()), false); -- } -- -- if (((SortedArraySet) entry.getValue()).isEmpty()) { -- objectiterator.remove(); -- } -- } -- -+ this.getChunkHolderManager().tick(); // Paper - rewrite chunk system - } - - private static int getTicketLevelAt(SortedArraySet> tickets) { -@@ -112,108 +75,25 @@ 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.tickingTicketsTracker.runAllUpdates(); -- this.playerTicketManager.runAllUpdates(); -- int i = Integer.MAX_VALUE - this.ticketTracker.runDistanceUpdates(Integer.MAX_VALUE); -- boolean flag = i != 0; -- -- if (flag) { -- ; -- } -- -- if (!this.chunksToUpdateFutures.isEmpty()) { -- // CraftBukkit start -- // Iterate pending chunk updates with protection against concurrent modification exceptions -- java.util.Iterator iter = this.chunksToUpdateFutures.iterator(); -- int expectedSize = this.chunksToUpdateFutures.size(); -- do { -- ChunkHolder playerchunk = iter.next(); -- iter.remove(); -- expectedSize--; -- -- playerchunk.updateFutures(chunkStorage, this.mainThreadExecutor); -- -- // Reset iterator if set was modified using add() -- if (this.chunksToUpdateFutures.size() != expectedSize) { -- expectedSize = this.chunksToUpdateFutures.size(); -- iter = this.chunksToUpdateFutures.iterator(); -- } -- } while (iter.hasNext()); -- // CraftBukkit end -- -- return true; -- } else { -- if (!this.ticketsToRelease.isEmpty()) { -- LongIterator longiterator = this.ticketsToRelease.iterator(); -- -- while (longiterator.hasNext()) { -- long j = longiterator.nextLong(); -- -- if (this.getTickets(j).stream().anyMatch((ticket) -> { -- return ticket.getType() == TicketType.PLAYER; -- })) { -- ChunkHolder playerchunk = chunkStorage.getUpdatingChunkIfPresent(j); -- -- if (playerchunk == null) { -- throw new IllegalStateException(); -- } -- -- CompletableFuture> completablefuture = playerchunk.getEntityTickingChunkFuture(); -- -- completablefuture.thenAccept((chunkresult) -> { -- this.mainThreadExecutor.execute(() -> { -- this.ticketThrottlerReleaser.tell(ChunkTaskPriorityQueueSorter.release(() -> { -- }, j, false)); -- }); -- }); -- } -- } -- -- this.ticketsToRelease.clear(); -- } -- -- return flag; -- } -+ return this.getChunkHolderManager().processTicketUpdates(); // Paper - rewrite chunk system - } - - boolean addTicket(long i, Ticket ticket) { // CraftBukkit - void -> boolean -- SortedArraySet> arraysetsorted = this.getTickets(i); -- int j = DistanceManager.getTicketLevelAt(arraysetsorted); -- Ticket ticket1 = (Ticket) arraysetsorted.addOrGet(ticket); -- -- ticket1.setCreatedTick(this.ticketTickCounter); -- if (ticket.getTicketLevel() < j) { -- this.ticketTracker.update(i, ticket.getTicketLevel(), true); -- } -- -- return ticket == ticket1; // CraftBukkit -+ org.spigotmc.AsyncCatcher.catchOp("ChunkMapDistance::addTicket"); // Paper -+ return this.getChunkHolderManager().addTicketAtLevel((TicketType)ticket.getType(), i, ticket.getTicketLevel(), ticket.key); // Paper - rewrite chunk system - } - - boolean removeTicket(long i, Ticket ticket) { // CraftBukkit - void -> boolean -- SortedArraySet> arraysetsorted = this.getTickets(i); -- -- boolean removed = false; // CraftBukkit -- if (arraysetsorted.remove(ticket)) { -- removed = true; // CraftBukkit -- } -- -- if (arraysetsorted.isEmpty()) { -- this.tickets.remove(i); -- } -- -- this.ticketTracker.update(i, DistanceManager.getTicketLevelAt(arraysetsorted), false); -- return removed; // CraftBukkit -+ org.spigotmc.AsyncCatcher.catchOp("ChunkMapDistance::removeTicket"); // Paper -+ return this.getChunkHolderManager().removeTicketAtLevel((TicketType)ticket.getType(), i, ticket.getTicketLevel(), ticket.key); // Paper - rewrite chunk system - } - - public void addTicket(TicketType type, ChunkPos pos, int level, T argument) { -- this.addTicket(pos.toLong(), new Ticket<>(type, level, argument)); -+ this.getChunkHolderManager().addTicketAtLevel(type, pos, level, argument); // Paper - rewrite chunk system - } - - public void removeTicket(TicketType type, ChunkPos pos, int level, T argument) { -- Ticket ticket = new Ticket<>(type, level, argument); -- -- this.removeTicket(pos.toLong(), ticket); -+ this.getChunkHolderManager().removeTicketAtLevel(type, pos, level, argument); // Paper - rewrite chunk system - } - - public void addRegionTicket(TicketType type, ChunkPos pos, int radius, T argument) { -@@ -222,13 +102,7 @@ public abstract class DistanceManager { - } - - public boolean addRegionTicketAtDistance(TicketType tickettype, ChunkPos chunkcoordintpair, int i, T t0) { -- // CraftBukkit end -- Ticket ticket = new Ticket<>(tickettype, ChunkLevel.byStatus(FullChunkStatus.FULL) - i, t0); -- long j = chunkcoordintpair.toLong(); -- -- boolean added = this.addTicket(j, ticket); // CraftBukkit -- this.tickingTicketsTracker.addTicket(j, ticket); -- return added; // CraftBukkit -+ return this.getChunkHolderManager().addTicketAtLevel(tickettype, chunkcoordintpair, ChunkLevel.byStatus(FullChunkStatus.FULL) - i, t0); // Paper - rewrite chunk system - } - - public void removeRegionTicket(TicketType type, ChunkPos pos, int radius, T argument) { -@@ -237,31 +111,21 @@ public abstract class DistanceManager { - } - - public boolean removeRegionTicketAtDistance(TicketType tickettype, ChunkPos chunkcoordintpair, int i, T t0) { -- // CraftBukkit end -- Ticket ticket = new Ticket<>(tickettype, ChunkLevel.byStatus(FullChunkStatus.FULL) - i, t0); -- long j = chunkcoordintpair.toLong(); -- -- boolean removed = this.removeTicket(j, ticket); // CraftBukkit -- this.tickingTicketsTracker.removeTicket(j, ticket); -- return removed; // CraftBukkit -+ return this.getChunkHolderManager().removeTicketAtLevel(tickettype, chunkcoordintpair, ChunkLevel.byStatus(FullChunkStatus.FULL) - i, t0); // Paper - rewrite chunk system - } - -- private SortedArraySet> getTickets(long position) { -- return (SortedArraySet) this.tickets.computeIfAbsent(position, (j) -> { -- return SortedArraySet.create(4); -- }); -- } -+ // Paper - rewrite chunk system - - protected void updateChunkForced(ChunkPos pos, boolean forced) { -- Ticket ticket = new Ticket<>(TicketType.FORCED, ChunkMap.FORCED_TICKET_LEVEL, pos); -+ Ticket ticket = new Ticket<>(TicketType.FORCED, ChunkMap.FORCED_TICKET_LEVEL, pos, 0L); // Paper - rewrite chunk system - long i = pos.toLong(); - - if (forced) { - this.addTicket(i, ticket); -- this.tickingTicketsTracker.addTicket(i, ticket); -+ //this.tickingTicketsTracker.addTicket(i, ticket); // Paper - no longer used - } else { - this.removeTicket(i, ticket); -- this.tickingTicketsTracker.removeTicket(i, ticket); -+ //this.tickingTicketsTracker.removeTicket(i, ticket); // Paper - no longer used - } - - } -@@ -270,12 +134,10 @@ public abstract class DistanceManager { - ChunkPos chunkcoordintpair = pos.chunk(); - long i = chunkcoordintpair.toLong(); - -- ((ObjectSet) this.playersPerChunk.computeIfAbsent(i, (j) -> { -- return new ObjectOpenHashSet(); -- })).add(player); -+ // Paper - no longer used - this.naturalSpawnChunkCounter.update(i, 0, true); -- this.playerTicketManager.update(i, 0, true); -- this.tickingTicketsTracker.addTicket(TicketType.PLAYER, chunkcoordintpair, this.getPlayerTicketLevel(), chunkcoordintpair); -+ //this.playerTicketManager.update(i, 0, true); // Paper - no longer used -+ //this.tickingTicketsTracker.addTicket(TicketType.PLAYER, chunkcoordintpair, this.getPlayerTicketLevel(), chunkcoordintpair); // Paper - no longer used - } - - public void removePlayer(SectionPos pos, ServerPlayer player) { -@@ -288,40 +150,44 @@ public abstract class DistanceManager { - if (objectset == null || objectset.isEmpty()) { // Paper - this.playersPerChunk.remove(i); - this.naturalSpawnChunkCounter.update(i, Integer.MAX_VALUE, false); -- this.playerTicketManager.update(i, Integer.MAX_VALUE, false); -- this.tickingTicketsTracker.removeTicket(TicketType.PLAYER, chunkcoordintpair, this.getPlayerTicketLevel(), chunkcoordintpair); -+ //this.playerTicketManager.update(i, Integer.MAX_VALUE, false); // Paper - no longer used -+ //this.tickingTicketsTracker.removeTicket(TicketType.PLAYER, chunkcoordintpair, this.getPlayerTicketLevel(), chunkcoordintpair); // Paper - no longer used - } - - } - -- private int getPlayerTicketLevel() { -- return Math.max(0, ChunkLevel.byStatus(FullChunkStatus.ENTITY_TICKING) - this.simulationDistance); -- } -+ // Paper - rewrite chunk system - - public boolean inEntityTickingRange(long chunkPos) { -- return ChunkLevel.isEntityTicking(this.tickingTicketsTracker.getLevel(chunkPos)); -+ // Paper start - replace player chunk loader system -+ ChunkHolder holder = this.chunkMap.getVisibleChunkIfPresent(chunkPos); -+ return holder != null && holder.isEntityTickingReady(); -+ // Paper end - replace player chunk loader system - } - - public boolean inBlockTickingRange(long chunkPos) { -- return ChunkLevel.isBlockTicking(this.tickingTicketsTracker.getLevel(chunkPos)); -+ // Paper start - replace player chunk loader system -+ ChunkHolder holder = this.chunkMap.getVisibleChunkIfPresent(chunkPos); -+ return holder != null && holder.isTickingReady(); -+ // Paper end - replace player chunk loader system - } - - protected String getTicketDebugString(long pos) { -- SortedArraySet> arraysetsorted = (SortedArraySet) this.tickets.get(pos); -- -- return arraysetsorted != null && !arraysetsorted.isEmpty() ? ((Ticket) arraysetsorted.first()).toString() : "no_ticket"; -+ return this.getChunkHolderManager().getTicketDebugString(pos); // Paper - rewrite chunk system - } - - protected void updatePlayerTickets(int viewDistance) { -- this.playerTicketManager.updateViewDistance(viewDistance); -+ this.chunkMap.setServerViewDistance(viewDistance); // Paper - route to player chunk manager - } - -- public void updateSimulationDistance(int simulationDistance) { -- if (simulationDistance != this.simulationDistance) { -- this.simulationDistance = simulationDistance; -- this.tickingTicketsTracker.replacePlayerTicketsLevel(this.getPlayerTicketLevel()); -- } -+ // Paper start -+ public int getSimulationDistance() { -+ return this.chunkMap.level.playerChunkLoader.getAPITickDistance(); -+ } -+ // Paper end - -+ public void updateSimulationDistance(int simulationDistance) { -+ this.chunkMap.level.playerChunkLoader.setTickDistance(simulationDistance); // Paper - route to player chunk manager - } - - public int getNaturalSpawnChunkCount() { -@@ -335,103 +201,26 @@ public abstract class DistanceManager { - } - - public String getDebugStatus() { -- return this.ticketThrottler.getDebugStatus(); -+ return "No DistanceManager stats available"; // Paper - rewrite chunk system - } - -- private void dumpTickets(String path) { -- try { -- FileOutputStream fileoutputstream = new FileOutputStream(new File(path)); -- -- try { -- ObjectIterator objectiterator = this.tickets.long2ObjectEntrySet().iterator(); -- -- while (objectiterator.hasNext()) { -- Entry>> entry = (Entry) objectiterator.next(); -- ChunkPos chunkcoordintpair = new ChunkPos(entry.getLongKey()); -- Iterator iterator = ((SortedArraySet) entry.getValue()).iterator(); -- -- while (iterator.hasNext()) { -- Ticket ticket = (Ticket) iterator.next(); -- -- fileoutputstream.write((chunkcoordintpair.x + "\t" + chunkcoordintpair.z + "\t" + String.valueOf(ticket.getType()) + "\t" + ticket.getTicketLevel() + "\t\n").getBytes(StandardCharsets.UTF_8)); -- } -- } -- } catch (Throwable throwable) { -- try { -- fileoutputstream.close(); -- } catch (Throwable throwable1) { -- throwable.addSuppressed(throwable1); -- } -- -- throw throwable; -- } -- -- fileoutputstream.close(); -- } catch (IOException ioexception) { -- DistanceManager.LOGGER.error("Failed to dump tickets to {}", path, ioexception); -- } -- -- } -- -- @VisibleForTesting -- TickingTracker tickingTracker() { -- return this.tickingTicketsTracker; -- } -+ // Paper - rewrite chunk system - - public void removeTicketsOnClosing() { -- ImmutableSet> immutableset = ImmutableSet.of(TicketType.UNKNOWN, TicketType.POST_TELEPORT, TicketType.LIGHT, TicketType.FUTURE_AWAIT, TicketType.CHUNK_RELIGHT, ca.spottedleaf.starlight.common.light.StarLightInterface.CHUNK_WORK_TICKET); // Paper - add additional tickets to preserve -- ObjectIterator>>> objectiterator = this.tickets.long2ObjectEntrySet().fastIterator(); -- -- while (objectiterator.hasNext()) { -- Entry>> entry = (Entry) objectiterator.next(); -- Iterator> iterator = ((SortedArraySet) entry.getValue()).iterator(); -- boolean flag = false; -- -- while (iterator.hasNext()) { -- Ticket ticket = (Ticket) iterator.next(); -- -- if (!immutableset.contains(ticket.getType())) { -- iterator.remove(); -- flag = true; -- this.tickingTicketsTracker.removeTicket(entry.getLongKey(), ticket); -- } -- } -- -- if (flag) { -- this.ticketTracker.update(entry.getLongKey(), DistanceManager.getTicketLevelAt((SortedArraySet) entry.getValue()), false); -- } -- -- if (((SortedArraySet) entry.getValue()).isEmpty()) { -- objectiterator.remove(); -- } -- } -- -+ // Paper - rewrite chunk system - this stupid hack ain't needed anymore - } - - public boolean hasTickets() { -- return !this.tickets.isEmpty(); -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - // CraftBukkit start - public void removeAllTicketsFor(TicketType ticketType, int ticketLevel, T ticketIdentifier) { -- Ticket target = new Ticket<>(ticketType, ticketLevel, ticketIdentifier); -- -- for (java.util.Iterator>>> iterator = this.tickets.long2ObjectEntrySet().fastIterator(); iterator.hasNext();) { -- Entry>> entry = iterator.next(); -- SortedArraySet> tickets = entry.getValue(); -- if (tickets.remove(target)) { -- // copied from removeTicket -- this.ticketTracker.update(entry.getLongKey(), DistanceManager.getTicketLevelAt(tickets), false); -- -- // can't use entry after it's removed -- if (tickets.isEmpty()) { -- iterator.remove(); -- } -- } -- } -+ this.getChunkHolderManager().removeAllTicketsFor(ticketType, ticketLevel, ticketIdentifier); // Paper - rewrite chunk system - } - // CraftBukkit end - -+ /* Paper - rewrite chunk system - private class ChunkTicketTracker extends ChunkTracker { - - private static final int MAX_LEVEL = ChunkLevel.MAX_LEVEL + 1; -@@ -478,6 +267,7 @@ public abstract class DistanceManager { - return this.runUpdates(distance); - } - } -+ */ // Paper - rewrite chunk system - - private class FixedPlayerDistanceChunkTracker extends ChunkTracker { - -@@ -557,6 +347,7 @@ public abstract class DistanceManager { - } - } - -+ /* Paper - rewrite chunk system - private class PlayerTicketTracker extends DistanceManager.FixedPlayerDistanceChunkTracker { - - private int viewDistance = 0; -@@ -652,4 +443,5 @@ public abstract class DistanceManager { - return distance <= this.viewDistance; - } - } -+ */ // Paper - rewrite chunk system - } -diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 0e89cf0742b9443f5256081987242554de24d893..802e9d266c01eaf8a83e78fe8dbe881e22e8b4d6 100644 ---- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java -+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -71,7 +71,7 @@ public class ServerChunkCache extends ChunkSource { - public final io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet entityTickingChunks = new io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet<>(4096, 0.75f, 4096, 0.15, true); - final com.destroystokyo.paper.util.concurrent.WeakSeqLock loadedChunkMapSeqLock = new com.destroystokyo.paper.util.concurrent.WeakSeqLock(); - final it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap loadedChunkMap = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>(8192, 0.5f); -- long chunkFutureAwaitCounter; -+ final java.util.concurrent.atomic.AtomicLong chunkFutureAwaitCounter = new java.util.concurrent.atomic.AtomicLong(); // Paper - chunk system rewrite - private final LevelChunk[] lastLoadedChunks = new LevelChunk[4 * 4]; - // Paper end - -@@ -195,7 +195,7 @@ public class ServerChunkCache extends ChunkSource { - public LevelChunk getChunkAtIfLoadedImmediately(int x, int z) { - long k = ChunkPos.asLong(x, z); - -- if (Thread.currentThread() == this.mainThread) { -+ if (io.papermc.paper.util.TickThread.isTickThread()) { // Paper - rewrite chunk system - return this.getChunkAtIfLoadedMainThread(x, z); - } - -@@ -247,7 +247,8 @@ public class ServerChunkCache extends ChunkSource { - @Nullable - @Override - public ChunkAccess getChunk(int x, int z, ChunkStatus leastStatus, boolean create) { -- if (Thread.currentThread() != this.mainThread) { -+ final int x1 = x; final int z1 = z; // Paper - conflict on variable change -+ if (!io.papermc.paper.util.TickThread.isTickThread()) { // Paper - rewrite chunk system - return (ChunkAccess) CompletableFuture.supplyAsync(() -> { - return this.getChunk(x, z, leastStatus, create); - }, this.mainThreadProcessor).join(); -@@ -263,15 +264,7 @@ public class ServerChunkCache extends ChunkSource { - gameprofilerfiller.incrementCounter("getChunk"); - long k = ChunkPos.asLong(x, z); - -- for (int l = 0; l < 4; ++l) { -- if (k == this.lastChunkPos[l] && leastStatus == this.lastChunkStatus[l]) { -- ChunkAccess ichunkaccess = this.lastChunk[l]; -- -- if (ichunkaccess != null) { // CraftBukkit - the chunk can become accessible in the meantime TODO for non-null chunks it might also make sense to check that the chunk's state hasn't changed in the meantime -- return ichunkaccess; -- } -- } -- } -+ // Paper - rewrite chunk system - there are no correct callbacks to remove items from cache in the new chunk system - - gameprofilerfiller.incrementCounter("getChunkCacheMiss"); - CompletableFuture> completablefuture = this.getChunkFutureMainThread(x, z, leastStatus, create); -@@ -279,9 +272,11 @@ public class ServerChunkCache extends ChunkSource { - - Objects.requireNonNull(completablefuture); - if (!completablefuture.isDone()) { // Paper -+ io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.pushChunkWait(this.level, x1, z1); // Paper - rewrite chunk system - com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x, z); // Paper - Add debug for sync chunk loads - this.level.timings.syncChunkLoad.startTiming(); // Paper - chunkproviderserver_b.managedBlock(completablefuture::isDone); -+ io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.popChunkWait(); // Paper - rewrite chunk system - this.level.timings.syncChunkLoad.stopTiming(); // Paper - } // Paper - ChunkResult chunkresult = (ChunkResult) completablefuture.join(); -@@ -299,7 +294,7 @@ public class ServerChunkCache extends ChunkSource { - @Nullable - @Override - public LevelChunk getChunkNow(int chunkX, int chunkZ) { -- if (Thread.currentThread() != this.mainThread) { -+ if (!io.papermc.paper.util.TickThread.isTickThread()) { // Paper - rewrite chunk system - return null; - } else { - return this.getChunkAtIfLoadedMainThread(chunkX, chunkZ); // Paper - Perf: Optimise getChunkAt calls for loaded chunks -@@ -313,7 +308,7 @@ public class ServerChunkCache extends ChunkSource { - } - - public CompletableFuture> getChunkFuture(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { -- boolean flag1 = Thread.currentThread() == this.mainThread; -+ boolean flag1 = io.papermc.paper.util.TickThread.isTickThread(); // Paper - rewrite chunk system - CompletableFuture completablefuture; - - if (flag1) { -@@ -333,48 +328,54 @@ public class ServerChunkCache extends ChunkSource { - return completablefuture; - } - -+ - private CompletableFuture> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { -- ChunkPos chunkcoordintpair = new ChunkPos(chunkX, chunkZ); -- long k = chunkcoordintpair.toLong(); -- int l = ChunkLevel.byStatus(leastStatus); -- ChunkHolder playerchunk = this.getVisibleChunkIfPresent(k); -+ // Paper start - add isUrgent - old sig left in place for dirty nms plugins -+ return getChunkFutureMainThread(chunkX, chunkZ, leastStatus, create, false); -+ } -+ private CompletableFuture> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create, boolean isUrgent) { -+ // Paper start - rewrite chunk system -+ io.papermc.paper.util.TickThread.ensureTickThread(this.level, chunkX, chunkZ, "Scheduling chunk load off-main"); -+ int minLevel = ChunkLevel.byStatus(leastStatus); -+ io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder = this.level.chunkTaskScheduler.chunkHolderManager.getChunkHolder(chunkX, chunkZ); - -- // CraftBukkit start - don't add new ticket for currently unloading chunk -- boolean currentlyUnloading = false; -- if (playerchunk != null) { -- FullChunkStatus oldChunkState = ChunkLevel.fullStatus(playerchunk.oldTicketLevel); -- FullChunkStatus currentChunkState = ChunkLevel.fullStatus(playerchunk.getTicketLevel()); -- currentlyUnloading = (oldChunkState.isOrAfter(FullChunkStatus.FULL) && !currentChunkState.isOrAfter(FullChunkStatus.FULL)); -+ boolean needsFullScheduling = leastStatus == ChunkStatus.FULL && (chunkHolder == null || !chunkHolder.getChunkStatus().isOrAfter(FullChunkStatus.FULL)); -+ -+ if ((chunkHolder == null || chunkHolder.getTicketLevel() > minLevel || needsFullScheduling) && !create) { -+ return ChunkHolder.UNLOADED_CHUNK_FUTURE; - } -- if (create && !currentlyUnloading) { -- // CraftBukkit end -- this.distanceManager.addTicket(TicketType.UNKNOWN, chunkcoordintpair, l, chunkcoordintpair); -- if (this.chunkAbsent(playerchunk, l)) { -- ProfilerFiller gameprofilerfiller = this.level.getProfiler(); -- -- gameprofilerfiller.push("chunkLoad"); -- this.runDistanceManagerUpdates(); -- playerchunk = this.getVisibleChunkIfPresent(k); -- gameprofilerfiller.pop(); -- if (this.chunkAbsent(playerchunk, l)) { -- throw (IllegalStateException) Util.pauseInIde(new IllegalStateException("No chunk holder after ticket has been added")); -+ -+ io.papermc.paper.chunk.system.scheduling.NewChunkHolder.ChunkCompletion chunkCompletion = chunkHolder == null ? null : chunkHolder.getLastChunkCompletion(); -+ if (needsFullScheduling || chunkCompletion == null || !chunkCompletion.genStatus().isOrAfter(leastStatus)) { -+ // schedule -+ CompletableFuture> ret = new CompletableFuture<>(); -+ Consumer complete = (ChunkAccess chunk) -> { -+ if (chunk == null) { -+ ret.complete(ChunkResult.error("Unexpected chunk unload")); -+ } else { -+ ret.complete(ChunkResult.of(chunk)); - } -- } -- } -+ }; - -- return this.chunkAbsent(playerchunk, l) ? ChunkHolder.UNLOADED_CHUNK_FUTURE : playerchunk.getOrScheduleFuture(leastStatus, this.chunkMap); -- } -+ this.level.chunkTaskScheduler.scheduleChunkLoad( -+ chunkX, chunkZ, leastStatus, true, -+ isUrgent ? ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.BLOCKING : ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, -+ complete -+ ); - -- private boolean chunkAbsent(@Nullable ChunkHolder holder, int maxLevel) { -- return holder == null || holder.oldTicketLevel > maxLevel; // CraftBukkit using oldTicketLevel for isLoaded checks -+ return ret; -+ } else { -+ // can return now -+ return CompletableFuture.completedFuture(ChunkResult.of(chunkCompletion.chunk())); -+ } -+ // Paper end - rewrite chunk system - } - -+ // Paper - rewrite chunk system -+ - @Override - public boolean hasChunk(int x, int z) { -- ChunkHolder playerchunk = this.getVisibleChunkIfPresent((new ChunkPos(x, z)).toLong()); -- int k = ChunkLevel.byStatus(ChunkStatus.FULL); -- -- return !this.chunkAbsent(playerchunk, k); -+ return this.getChunkAtIfLoadedImmediately(x, z) != null; // Paper - rewrite chunk system - } - - @Nullable -@@ -386,22 +387,13 @@ public class ServerChunkCache extends ChunkSource { - if (playerchunk == null) { - return null; - } else { -- int l = ServerChunkCache.CHUNK_STATUSES.size() - 1; -- -- while (true) { -- ChunkStatus chunkstatus = (ChunkStatus) ServerChunkCache.CHUNK_STATUSES.get(l); -- ChunkAccess ichunkaccess = (ChunkAccess) ((ChunkResult) playerchunk.getFutureIfPresentUnchecked(chunkstatus).getNow(ChunkHolder.UNLOADED_CHUNK)).orElse((Object) null); -- -- if (ichunkaccess != null) { -- return ichunkaccess; -- } -- -- if (chunkstatus == ChunkStatus.INITIALIZE_LIGHT.getParent()) { -- return null; -- } -- -- --l; -+ // Paper start - rewrite chunk system -+ ChunkStatus status = playerchunk.getChunkHolderStatus(); -+ if (status != null && !status.isOrAfter(ChunkStatus.LIGHT.getParent())) { -+ return null; - } -+ return playerchunk.getAvailableChunkNow(); -+ // Paper end - rewrite chunk system - } - } - -@@ -415,15 +407,7 @@ public class ServerChunkCache extends ChunkSource { - } - - public boolean runDistanceManagerUpdates() { // Paper - public -- boolean flag = this.distanceManager.runAllUpdates(this.chunkMap); -- boolean flag1 = this.chunkMap.promoteChunkMap(); -- -- if (!flag && !flag1) { -- return false; -- } else { -- this.clearCache(); -- return true; -- } -+ return this.level.chunkTaskScheduler.chunkHolderManager.processTicketUpdates(); // Paper - rewrite chunk system - } - - // Paper start -@@ -433,9 +417,10 @@ public class ServerChunkCache extends ChunkSource { - // Paper end - - public boolean isPositionTicking(long pos) { -- ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos); -- -- return playerchunk == null ? false : (!this.level.shouldTickBlocksAt(pos) ? false : ((ChunkResult) playerchunk.getTickingChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).isSuccess()); -+ // Paper start - replace player chunk loader system -+ ChunkHolder holder = this.chunkMap.getVisibleChunkIfPresent(pos); -+ return holder != null && holder.isTickingReady(); -+ // Paper end - replace player chunk loader system - } - - public void save(boolean flush) { -@@ -451,17 +436,13 @@ public class ServerChunkCache extends ChunkSource { - this.close(true); - } - -- public void close(boolean save) throws IOException { -- if (save) { -- this.save(true); -- } -- // CraftBukkit end -- this.lightEngine.close(); -- this.chunkMap.close(); -+ public void close(boolean save) { // Paper - rewrite chunk system -+ this.level.chunkTaskScheduler.chunkHolderManager.close(save, true); // Paper - rewrite chunk system - } - - // CraftBukkit start - modelled on below - public void purgeUnload() { -+ if (true) return; // Paper - tickets will be removed later, this behavior isn't really well accounted for by the chunk system - this.level.getProfiler().push("purge"); - this.distanceManager.purgeStaleTickets(); - this.runDistanceManagerUpdates(); -@@ -485,6 +466,7 @@ public class ServerChunkCache extends ChunkSource { - this.level.getProfiler().popPush("chunks"); - if (tickChunks) { - this.level.timings.chunks.startTiming(); // Paper - timings -+ this.chunkMap.level.playerChunkLoader.tick(); // Paper - replace player chunk loader - this is mostly required to account for view distance changes - this.tickChunks(); - this.level.timings.chunks.stopTiming(); // Paper - timings - this.chunkMap.tick(); -@@ -587,7 +569,12 @@ public class ServerChunkCache extends ChunkSource { - ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos); - - if (playerchunk != null) { -- ((ChunkResult) playerchunk.getFullChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).ifSuccess(chunkConsumer); -+ // Paper start - rewrite chunk system -+ LevelChunk chunk = playerchunk.getFullChunkNow(); -+ if (chunk != null) { -+ chunkConsumer.accept(chunk); -+ } -+ // Paper end - rewrite chunk system - } - - } -@@ -753,17 +740,10 @@ public class ServerChunkCache extends ChunkSource { - @Override - // CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task - public boolean pollTask() { -- try { - if (ServerChunkCache.this.runDistanceManagerUpdates()) { - return true; -- } else { -- ServerChunkCache.this.lightEngine.tryScheduleUpdate(); -- return super.pollTask(); - } -- } finally { -- ServerChunkCache.this.chunkMap.callbackExecutor.run(); -- } -- // CraftBukkit end -+ return super.pollTask() | ServerChunkCache.this.level.chunkTaskScheduler.executeMainThreadTask(); // Paper - rewrite chunk system - } - } - -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index b33bf957b1541756e3b983b87b1c83629757739a..0ccdc8d135dd3edb410fbc1d248c20a4a45b37fa 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -199,7 +199,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - public final PrimaryLevelData serverLevelData; // CraftBukkit - type - private int lastSpawnChunkRadius; - final EntityTickList entityTickList; -- public final PersistentEntitySectionManager entityManager; -+ //public final PersistentEntitySectionManager entityManager; // Paper - rewrite chunk system - private final GameEventDispatcher gameEventDispatcher; - public boolean noSave; - private final SleepStatus sleepStatus; -@@ -268,50 +268,65 @@ public class ServerLevel extends Level implements WorldGenLevel { - return true; - } - -- public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, -- java.util.function.Consumer> onLoad) { -- if (Thread.currentThread() != this.thread) { -- this.getChunkSource().mainThreadProcessor.execute(() -> { -- this.loadChunksForMoveAsync(axisalignedbb, priority, onLoad); -- }); -- return; -- } -+ public final void loadChunksAsync(BlockPos pos, int radiusBlocks, -+ ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, -+ java.util.function.Consumer> onLoad) { -+ loadChunksAsync( -+ (pos.getX() - radiusBlocks) >> 4, -+ (pos.getX() + radiusBlocks) >> 4, -+ (pos.getZ() - radiusBlocks) >> 4, -+ (pos.getZ() + radiusBlocks) >> 4, -+ priority, onLoad -+ ); -+ } -+ -+ public final void loadChunksAsync(BlockPos pos, int radiusBlocks, -+ net.minecraft.world.level.chunk.status.ChunkStatus chunkStatus, -+ ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, -+ java.util.function.Consumer> onLoad) { -+ loadChunksAsync( -+ (pos.getX() - radiusBlocks) >> 4, -+ (pos.getX() + radiusBlocks) >> 4, -+ (pos.getZ() - radiusBlocks) >> 4, -+ (pos.getZ() + radiusBlocks) >> 4, -+ chunkStatus, priority, onLoad -+ ); -+ } -+ -+ public final void loadChunksAsync(int minChunkX, int maxChunkX, int minChunkZ, int maxChunkZ, -+ ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, -+ java.util.function.Consumer> onLoad) { -+ this.loadChunksAsync(minChunkX, maxChunkX, minChunkZ, maxChunkZ, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, priority, onLoad); -+ } -+ -+ public final void loadChunksAsync(int minChunkX, int maxChunkX, int minChunkZ, int maxChunkZ, -+ net.minecraft.world.level.chunk.status.ChunkStatus chunkStatus, -+ ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, -+ java.util.function.Consumer> onLoad) { - List ret = new java.util.ArrayList<>(); -- it.unimi.dsi.fastutil.ints.IntArrayList ticketLevels = new it.unimi.dsi.fastutil.ints.IntArrayList(); -- -- int minBlockX = Mth.floor(axisalignedbb.minX - 1.0E-7D) - 3; -- int maxBlockX = Mth.floor(axisalignedbb.maxX + 1.0E-7D) + 3; -- -- int minBlockZ = Mth.floor(axisalignedbb.minZ - 1.0E-7D) - 3; -- int maxBlockZ = Mth.floor(axisalignedbb.maxZ + 1.0E-7D) + 3; -- -- int minChunkX = minBlockX >> 4; -- int maxChunkX = maxBlockX >> 4; -- -- int minChunkZ = minBlockZ >> 4; -- int maxChunkZ = maxBlockZ >> 4; - - ServerChunkCache chunkProvider = this.getChunkSource(); - - int requiredChunks = (maxChunkX - minChunkX + 1) * (maxChunkZ - minChunkZ + 1); -- int[] loadedChunks = new int[1]; -+ java.util.concurrent.atomic.AtomicInteger loadedChunks = new java.util.concurrent.atomic.AtomicInteger(); - -- Long holderIdentifier = Long.valueOf(chunkProvider.chunkFutureAwaitCounter++); -+ Long holderIdentifier = Long.valueOf(chunkProvider.chunkFutureAwaitCounter.getAndIncrement()); -+ -+ int ticketLevel = 33 + net.minecraft.world.level.chunk.status.ChunkStatus.getDistance(chunkStatus); - - java.util.function.Consumer consumer = (net.minecraft.world.level.chunk.ChunkAccess chunk) -> { - if (chunk != null) { -- int ticketLevel = Math.max(33, chunkProvider.chunkMap.getUpdatingChunkIfPresent(chunk.getPos().toLong()).getTicketLevel()); -+ synchronized (ret) { - ret.add(chunk); -- ticketLevels.add(ticketLevel); -+ } - chunkProvider.addTicketAtLevel(TicketType.FUTURE_AWAIT, chunk.getPos(), ticketLevel, holderIdentifier); - } -- if (++loadedChunks[0] == requiredChunks) { -+ if (loadedChunks.incrementAndGet() == requiredChunks) { - try { - onLoad.accept(java.util.Collections.unmodifiableList(ret)); - } finally { - for (int i = 0, len = ret.size(); i < len; ++i) { - ChunkPos chunkPos = ret.get(i).getPos(); -- int ticketLevel = ticketLevels.getInt(i); - - chunkProvider.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, ticketLevel, chunkPos); - chunkProvider.removeTicketAtLevel(TicketType.FUTURE_AWAIT, chunkPos, ticketLevel, holderIdentifier); -@@ -323,12 +338,228 @@ public class ServerLevel extends Level implements WorldGenLevel { - for (int cx = minChunkX; cx <= maxChunkX; ++cx) { - for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) { - io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad( -- this, cx, cz, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, true, priority, consumer -+ this, cx, cz, chunkStatus, true, priority, consumer - ); - } - } - } -- // Paper end -+ -+ public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, -+ java.util.function.Consumer> onLoad) { -+ -+ int minBlockX = Mth.floor(axisalignedbb.minX - 1.0E-7D) - 3; -+ int maxBlockX = Mth.floor(axisalignedbb.maxX + 1.0E-7D) + 3; -+ -+ int minBlockZ = Mth.floor(axisalignedbb.minZ - 1.0E-7D) - 3; -+ int maxBlockZ = Mth.floor(axisalignedbb.maxZ + 1.0E-7D) + 3; -+ -+ int minChunkX = minBlockX >> 4; -+ int maxChunkX = maxBlockX >> 4; -+ -+ int minChunkZ = minBlockZ >> 4; -+ int maxChunkZ = maxBlockZ >> 4; -+ -+ this.loadChunksAsync(minChunkX, maxChunkX, minChunkZ, maxChunkZ, priority, onLoad); -+ } -+ -+ // Paper start - rewrite chunk system -+ public final io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler chunkTaskScheduler; -+ public final io.papermc.paper.chunk.system.io.RegionFileIOThread.ChunkDataController chunkDataControllerNew -+ = new io.papermc.paper.chunk.system.io.RegionFileIOThread.ChunkDataController(io.papermc.paper.chunk.system.io.RegionFileIOThread.RegionFileType.CHUNK_DATA) { -+ -+ @Override -+ public net.minecraft.world.level.chunk.storage.RegionFileStorage getCache() { -+ return ServerLevel.this.getChunkSource().chunkMap.regionFileCache; -+ } -+ -+ @Override -+ public void writeData(int chunkX, int chunkZ, net.minecraft.nbt.CompoundTag compound) throws IOException { -+ ServerLevel.this.getChunkSource().chunkMap.write(new ChunkPos(chunkX, chunkZ), compound); -+ } -+ -+ @Override -+ public net.minecraft.nbt.CompoundTag readData(int chunkX, int chunkZ) throws IOException { -+ return ServerLevel.this.getChunkSource().chunkMap.readSync(new ChunkPos(chunkX, chunkZ)); -+ } -+ }; -+ public final io.papermc.paper.chunk.system.io.RegionFileIOThread.ChunkDataController poiDataControllerNew -+ = new io.papermc.paper.chunk.system.io.RegionFileIOThread.ChunkDataController(io.papermc.paper.chunk.system.io.RegionFileIOThread.RegionFileType.POI_DATA) { -+ -+ @Override -+ public net.minecraft.world.level.chunk.storage.RegionFileStorage getCache() { -+ return ServerLevel.this.getChunkSource().chunkMap.getPoiManager(); -+ } -+ -+ @Override -+ public void writeData(int chunkX, int chunkZ, net.minecraft.nbt.CompoundTag compound) throws IOException { -+ ServerLevel.this.getChunkSource().chunkMap.getPoiManager().write(new ChunkPos(chunkX, chunkZ), compound); -+ } -+ -+ @Override -+ public net.minecraft.nbt.CompoundTag readData(int chunkX, int chunkZ) throws IOException { -+ return ServerLevel.this.getChunkSource().chunkMap.getPoiManager().read(new ChunkPos(chunkX, chunkZ)); -+ } -+ }; -+ public final io.papermc.paper.chunk.system.io.RegionFileIOThread.ChunkDataController entityDataControllerNew -+ = new io.papermc.paper.chunk.system.io.RegionFileIOThread.ChunkDataController(io.papermc.paper.chunk.system.io.RegionFileIOThread.RegionFileType.ENTITY_DATA) { -+ -+ @Override -+ public net.minecraft.world.level.chunk.storage.RegionFileStorage getCache() { -+ return ServerLevel.this.entityStorage; -+ } -+ -+ @Override -+ public void writeData(int chunkX, int chunkZ, net.minecraft.nbt.CompoundTag compound) throws IOException { -+ ServerLevel.this.writeEntityChunk(chunkX, chunkZ, compound); -+ } -+ -+ @Override -+ public net.minecraft.nbt.CompoundTag readData(int chunkX, int chunkZ) throws IOException { -+ return ServerLevel.this.readEntityChunk(chunkX, chunkZ); -+ } -+ }; -+ private final EntityRegionFileStorage entityStorage; -+ -+ private static final class EntityRegionFileStorage extends net.minecraft.world.level.chunk.storage.RegionFileStorage { -+ -+ public EntityRegionFileStorage(RegionStorageInfo storageKey, Path directory, boolean dsync) { -+ super(storageKey, directory, dsync); -+ } -+ -+ protected void write(ChunkPos pos, net.minecraft.nbt.CompoundTag nbt) throws IOException { -+ ChunkPos nbtPos = nbt == null ? null : EntityStorage.readChunkPos(nbt); -+ if (nbtPos != null && !pos.equals(nbtPos)) { -+ throw new IllegalArgumentException( -+ "Entity chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + pos.toString() -+ + " but compound says coordinate is " + nbtPos + " for world: " + this -+ ); -+ } -+ super.write(pos, nbt); -+ } -+ } -+ -+ private void writeEntityChunk(int chunkX, int chunkZ, net.minecraft.nbt.CompoundTag compound) throws IOException { -+ if (!io.papermc.paper.chunk.system.io.RegionFileIOThread.isRegionFileThread()) { -+ io.papermc.paper.chunk.system.io.RegionFileIOThread.scheduleSave( -+ this, chunkX, chunkZ, compound, -+ io.papermc.paper.chunk.system.io.RegionFileIOThread.RegionFileType.ENTITY_DATA); -+ return; -+ } -+ this.entityStorage.write(new ChunkPos(chunkX, chunkZ), compound); -+ } -+ -+ private net.minecraft.nbt.CompoundTag readEntityChunk(int chunkX, int chunkZ) throws IOException { -+ if (!io.papermc.paper.chunk.system.io.RegionFileIOThread.isRegionFileThread()) { -+ return io.papermc.paper.chunk.system.io.RegionFileIOThread.loadData( -+ this, chunkX, chunkZ, io.papermc.paper.chunk.system.io.RegionFileIOThread.RegionFileType.ENTITY_DATA, -+ io.papermc.paper.chunk.system.io.RegionFileIOThread.getIOBlockingPriorityForCurrentThread() -+ ); -+ } -+ return this.entityStorage.read(new ChunkPos(chunkX, chunkZ)); -+ } -+ -+ private final io.papermc.paper.chunk.system.entity.EntityLookup entityLookup; -+ public final io.papermc.paper.chunk.system.entity.EntityLookup getEntityLookup() { -+ return this.entityLookup; -+ } -+ -+ private final java.util.concurrent.atomic.AtomicLong nonFullSyncLoadIdGenerator = new java.util.concurrent.atomic.AtomicLong(); -+ -+ private ChunkAccess getIfAboveStatus(int chunkX, int chunkZ, net.minecraft.world.level.chunk.status.ChunkStatus status) { -+ io.papermc.paper.chunk.system.scheduling.NewChunkHolder loaded = -+ this.chunkTaskScheduler.chunkHolderManager.getChunkHolder(chunkX, chunkZ); -+ io.papermc.paper.chunk.system.scheduling.NewChunkHolder.ChunkCompletion loadedCompletion; -+ if (loaded != null && (loadedCompletion = loaded.getLastChunkCompletion()) != null && loadedCompletion.genStatus().isOrAfter(status)) { -+ return loadedCompletion.chunk(); -+ } -+ -+ return null; -+ } -+ -+ @Override -+ public ChunkAccess syncLoadNonFull(int chunkX, int chunkZ, net.minecraft.world.level.chunk.status.ChunkStatus status) { -+ if (status == null || status.isOrAfter(net.minecraft.world.level.chunk.status.ChunkStatus.FULL)) { -+ throw new IllegalArgumentException("Status: " + status); -+ } -+ ChunkAccess loaded = this.getIfAboveStatus(chunkX, chunkZ, status); -+ if (loaded != null) { -+ return loaded; -+ } -+ -+ Long ticketId = Long.valueOf(this.nonFullSyncLoadIdGenerator.getAndIncrement()); -+ int ticketLevel = 33 + net.minecraft.world.level.chunk.status.ChunkStatus.getDistance(status); -+ this.chunkTaskScheduler.chunkHolderManager.addTicketAtLevel( -+ TicketType.NON_FULL_SYNC_LOAD, chunkX, chunkZ, ticketLevel, ticketId -+ ); -+ this.chunkTaskScheduler.chunkHolderManager.processTicketUpdates(); -+ -+ this.chunkTaskScheduler.beginChunkLoadForNonFullSync(chunkX, chunkZ, status, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.BLOCKING); -+ -+ // we could do a simple spinwait here, since we do not need to process tasks while performing this load -+ // but we process tasks only because it's a better use of the time spent -+ this.chunkSource.mainThreadProcessor.managedBlock(() -> { -+ return ServerLevel.this.getIfAboveStatus(chunkX, chunkZ, status) != null; -+ }); -+ -+ loaded = ServerLevel.this.getIfAboveStatus(chunkX, chunkZ, status); -+ if (loaded == null) { -+ throw new IllegalStateException("Expected chunk to be loaded for status " + status); -+ } -+ -+ this.chunkTaskScheduler.chunkHolderManager.removeTicketAtLevel( -+ TicketType.NON_FULL_SYNC_LOAD, chunkX, chunkZ, ticketLevel, ticketId -+ ); -+ -+ return loaded; -+ } -+ -+ public final int getRegionChunkShift() { -+ // placeholder for folia -+ return io.papermc.paper.threadedregions.TickRegions.getRegionChunkShift(); -+ } -+ // Paper end - rewrite chunk system -+ -+ public final io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader playerChunkLoader = new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader(this); -+ private final java.util.concurrent.atomic.AtomicReference viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1)); -+ -+ public io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances getViewDistances() { -+ return this.viewDistances.get(); -+ } -+ -+ private void updateViewDistance(final java.util.function.Function update) { -+ for (io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances curr = this.viewDistances.get();;) { -+ if (this.viewDistances.compareAndSet(curr, update.apply(curr))) { -+ return; -+ } -+ } -+ } -+ -+ public void setTickViewDistance(final int distance) { -+ if ((distance < io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MIN_VIEW_DISTANCE || distance > io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MAX_VIEW_DISTANCE)) { -+ throw new IllegalArgumentException("Tick view distance must be a number between " + io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MIN_VIEW_DISTANCE + " and " + (io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MAX_VIEW_DISTANCE) + ", got: " + distance); -+ } -+ this.updateViewDistance((input) -> { -+ return input.setTickViewDistance(distance); -+ }); -+ } -+ -+ public void setLoadViewDistance(final int distance) { -+ if (distance != -1 && (distance < io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MIN_VIEW_DISTANCE || distance > io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MAX_VIEW_DISTANCE + 1)) { -+ throw new IllegalArgumentException("Load view distance must be a number between " + io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MIN_VIEW_DISTANCE + " and " + (io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MAX_VIEW_DISTANCE + 1) + " or -1, got: " + distance); -+ } -+ this.updateViewDistance((input) -> { -+ return input.setLoadViewDistance(distance); -+ }); -+ } -+ -+ public void setSendViewDistance(final int distance) { -+ if (distance != -1 && (distance < io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MIN_VIEW_DISTANCE || distance > io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MAX_VIEW_DISTANCE + 1)) { -+ throw new IllegalArgumentException("Send view distance must be a number between " + io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MIN_VIEW_DISTANCE + " and " + (io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MAX_VIEW_DISTANCE + 1) + " or -1, got: " + distance); -+ } -+ this.updateViewDistance((input) -> { -+ return input.setSendViewDistance(distance); -+ }); -+ } - - // Paper start - optimise getPlayerByUUID - @Nullable -@@ -382,16 +613,16 @@ public class ServerLevel extends Level implements WorldGenLevel { - // CraftBukkit end - boolean flag2 = minecraftserver.forceSynchronousWrites(); - DataFixer datafixer = minecraftserver.getFixerUpper(); -- EntityPersistentStorage entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver); -+ this.entityStorage = new EntityRegionFileStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), flag2); // Paper - rewrite chunk system - -- this.entityManager = new PersistentEntitySectionManager<>(Entity.class, new ServerLevel.EntityCallbacks(), entitypersistentstorage); -+ // this.entityManager = new PersistentEntitySectionManager<>(Entity.class, new ServerLevel.EntityCallbacks(), entitypersistentstorage, this.entitySliceManager); // Paper // Paper - rewrite chunk system - StructureTemplateManager structuretemplatemanager = minecraftserver.getStructureManager(); - int j = this.spigotConfig.viewDistance; // Spigot - int k = this.spigotConfig.simulationDistance; // Spigot -- PersistentEntitySectionManager persistententitysectionmanager = this.entityManager; -+ //PersistentEntitySectionManager persistententitysectionmanager = this.entityManager; // Paper - rewrite chunk system - -- Objects.requireNonNull(this.entityManager); -- this.chunkSource = new ServerChunkCache(this, convertable_conversionsession, datafixer, structuretemplatemanager, executor, chunkgenerator, j, k, flag2, worldloadlistener, persistententitysectionmanager::updateChunkStatus, () -> { -+ //Objects.requireNonNull(this.entityManager); // Paper - rewrite chunk system -+ this.chunkSource = new ServerChunkCache(this, convertable_conversionsession, datafixer, structuretemplatemanager, executor, chunkgenerator, j, k, flag2, worldloadlistener, null, () -> { // Paper - rewrite chunk system - return minecraftserver.overworld().getDataStorage(); - }); - this.chunkSource.getGeneratorState().ensureStructuresGenerated(); -@@ -420,6 +651,9 @@ public class ServerLevel extends Level implements WorldGenLevel { - return (RandomSequences) this.getDataStorage().computeIfAbsent(RandomSequences.factory(l), "random_sequences"); - }); - this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit -+ -+ this.chunkTaskScheduler = new io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler(this, io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.workerThreads); // Paper - rewrite chunk system -+ this.entityLookup = new io.papermc.paper.chunk.system.entity.EntityLookup(this, new EntityCallbacks()); // Paper - rewrite chunk system - } - - // Paper start -@@ -552,7 +786,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - gameprofilerfiller.push("checkDespawn"); - entity.checkDespawn(); - gameprofilerfiller.pop(); -- if (this.chunkSource.chunkMap.getDistanceManager().inEntityTickingRange(entity.chunkPosition().toLong())) { -+ if (true || this.chunkSource.chunkMap.getDistanceManager().inEntityTickingRange(entity.chunkPosition().toLong())) { // Paper - now always true if in the ticking list - Entity entity1 = entity.getVehicle(); - - if (entity1 != null) { -@@ -577,13 +811,16 @@ public class ServerLevel extends Level implements WorldGenLevel { - } - - gameprofilerfiller.push("entityManagement"); -- this.entityManager.tick(); -+ //this.entityManager.tick(); // Paper - rewrite chunk system - gameprofilerfiller.pop(); - } - - @Override - public boolean shouldTickBlocksAt(long chunkPos) { -- return this.chunkSource.chunkMap.getDistanceManager().inBlockTickingRange(chunkPos); -+ // Paper start - replace player chunk loader system -+ ChunkHolder holder = this.chunkSource.chunkMap.getVisibleChunkIfPresent(chunkPos); -+ return holder != null && holder.isTickingReady(); -+ // Paper end - replace player chunk loader system - } - - protected void tickTime() { -@@ -1060,6 +1297,11 @@ public class ServerLevel extends Level implements WorldGenLevel { - } - - public void save(@Nullable ProgressListener progressListener, boolean flush, boolean savingDisabled) { -+ // Paper start - rewrite chunk system - add close param -+ this.save(progressListener, flush, savingDisabled, false); -+ } -+ public void save(@Nullable ProgressListener progressListener, boolean flush, boolean savingDisabled, boolean close) { -+ // Paper end - rewrite chunk system - add close param - ServerChunkCache chunkproviderserver = this.getChunkSource(); - - if (!savingDisabled) { -@@ -1075,16 +1317,13 @@ public class ServerLevel extends Level implements WorldGenLevel { - } - - timings.worldSaveChunks.startTiming(); // Paper -- chunkproviderserver.save(flush); -+ if (!close) chunkproviderserver.save(flush); // Paper - rewrite chunk system -+ if (close) chunkproviderserver.close(true); // Paper - rewrite chunk system - timings.worldSaveChunks.stopTiming(); // Paper - }// Paper -- if (flush) { -- this.entityManager.saveAll(); -- } else { -- this.entityManager.autoSave(); -- } -+ // Paper - rewrite chunk system - entity saving moved into ChunkHolder - -- } -+ } else if (close) { chunkproviderserver.close(false); } // Paper - rewrite chunk system - - // CraftBukkit start - moved from MinecraftServer.saveChunks - ServerLevel worldserver1 = this; -@@ -1220,7 +1459,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - this.removePlayerImmediately((ServerPlayer) entity, Entity.RemovalReason.DISCARDED); - } - -- this.entityManager.addNewEntity(player); -+ this.entityLookup.addNewEntity(player); // Paper - rewite chunk system - } - - // CraftBukkit start -@@ -1251,7 +1490,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - } - // CraftBukkit end - -- return this.entityManager.addNewEntity(entity); -+ return this.entityLookup.addNewEntity(entity); // Paper - rewrite chunk system - } - } - -@@ -1263,10 +1502,10 @@ public class ServerLevel extends Level implements WorldGenLevel { - public boolean tryAddFreshEntityWithPassengers(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { - // CraftBukkit end - Stream stream = entity.getSelfAndPassengers().map(Entity::getUUID); // CraftBukkit - decompile error -- PersistentEntitySectionManager persistententitysectionmanager = this.entityManager; -+ //PersistentEntitySectionManager persistententitysectionmanager = this.entityManager; // Paper - rewrite chunk system - -- Objects.requireNonNull(this.entityManager); -- if (stream.anyMatch(persistententitysectionmanager::isLoaded)) { -+ //Objects.requireNonNull(this.entityManager); // Paper - rewrite chunk system -+ if (stream.anyMatch(this.entityLookup::hasEntity)) { // Paper - rewrite chunk system - return false; - } else { - this.addFreshEntityWithPassengers(entity, reason); // CraftBukkit -@@ -1852,7 +2091,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - } - } - -- bufferedwriter.write(String.format(Locale.ROOT, "entities: %s\n", this.entityManager.gatherStats())); -+ bufferedwriter.write(String.format(Locale.ROOT, "entities: %s\n", this.entityLookup.getDebugInfo())); // Paper - rewrite chunk system - bufferedwriter.write(String.format(Locale.ROOT, "block_entity_tickers: %d\n", this.blockEntityTickers.size())); - bufferedwriter.write(String.format(Locale.ROOT, "block_ticks: %d\n", this.getBlockTicks().count())); - bufferedwriter.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count())); -@@ -1901,7 +2140,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - BufferedWriter bufferedwriter2 = Files.newBufferedWriter(path1); - - try { -- playerchunkmap.dumpChunks(bufferedwriter2); -+ //playerchunkmap.dumpChunks(bufferedwriter2); // Paper - rewrite chunk system - } catch (Throwable throwable4) { - if (bufferedwriter2 != null) { - try { -@@ -1922,7 +2161,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - BufferedWriter bufferedwriter3 = Files.newBufferedWriter(path2); - - try { -- this.entityManager.dumpSections(bufferedwriter3); -+ //this.entityManager.dumpSections(bufferedwriter3); // Paper - rewrite chunk system - } catch (Throwable throwable6) { - if (bufferedwriter3 != null) { - try { -@@ -2064,7 +2303,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - - @VisibleForTesting - public String getWatchdogStats() { -- return String.format(Locale.ROOT, "players: %s, entities: %s [%s], block_entities: %d [%s], block_ticks: %d, fluid_ticks: %d, chunk_source: %s", this.players.size(), this.entityManager.gatherStats(), ServerLevel.getTypeCount(this.entityManager.getEntityGetter().getAll(), (entity) -> { -+ return String.format(Locale.ROOT, "players: %s, entities: %s [%s], block_entities: %d [%s], block_ticks: %d, fluid_ticks: %d, chunk_source: %s", this.players.size(), this.entityLookup.getDebugInfo(), ServerLevel.getTypeCount(this.entityLookup.getAll(), (entity) -> { // Paper - rewrite chunk system - return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString(); - }), this.blockEntityTickers.size(), ServerLevel.getTypeCount(this.blockEntityTickers, TickingBlockEntity::getType), this.getBlockTicks().count(), this.getFluidTicks().count(), this.gatherChunkSourceStats()); - } -@@ -2124,15 +2363,15 @@ public class ServerLevel extends Level implements WorldGenLevel { - @Override - public LevelEntityGetter getEntities() { - org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot -- return this.entityManager.getEntityGetter(); -+ return this.entityLookup; // Paper - rewrite chunk system - } - -- public void addLegacyChunkEntities(Stream entities) { -- this.entityManager.addLegacyChunkEntities(entities); -+ public void addLegacyChunkEntities(Stream entities, ChunkPos forChunk) { // Paper - rewrite chunk system -+ this.entityLookup.addLegacyChunkEntities(entities.toList(), forChunk); // Paper - rewrite chunk system - } - -- public void addWorldGenChunkEntities(Stream entities) { -- this.entityManager.addWorldGenChunkEntities(entities); -+ public void addWorldGenChunkEntities(Stream entities, ChunkPos forChunk) { // Paper - rewrite chunk system -+ this.entityLookup.addWorldGenChunkEntities(entities.toList(), forChunk); // Paper - rewrite chunk system - } - - public void startTickingChunk(LevelChunk chunk) { -@@ -2152,34 +2391,49 @@ public class ServerLevel extends Level implements WorldGenLevel { - @Override - public void close() throws IOException { - super.close(); -- this.entityManager.close(); -+ //this.entityManager.close(); // Paper - rewrite chunk system - } - - @Override - public String gatherChunkSourceStats() { - String s = this.chunkSource.gatherStats(); - -- return "Chunks[S] W: " + s + " E: " + this.entityManager.gatherStats(); -+ return "Chunks[S] W: " + s + " E: " + this.entityLookup.getDebugInfo(); // Paper - rewrite chunk system - } - - public boolean areEntitiesLoaded(long chunkPos) { -- return this.entityManager.areEntitiesLoaded(chunkPos); -+ // Paper start - rewrite chunk system -+ return this.getChunkIfLoadedImmediately(ChunkPos.getX(chunkPos), ChunkPos.getZ(chunkPos)) != null; -+ // Paper end - rewrite chunk system - } - - private boolean isPositionTickingWithEntitiesLoaded(long chunkPos) { -- return this.areEntitiesLoaded(chunkPos) && this.chunkSource.isPositionTicking(chunkPos); -+ // Paper start - optimize is ticking ready type functions -+ io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder = this.chunkTaskScheduler.chunkHolderManager.getChunkHolder(chunkPos); -+ // isTicking implies the chunk is loaded, and the chunk is loaded now implies the entities are loaded -+ return chunkHolder != null && chunkHolder.isTickingReady(); -+ // Paper end - } - - public boolean isPositionEntityTicking(BlockPos pos) { -- return this.entityManager.canPositionTick(pos) && this.chunkSource.chunkMap.getDistanceManager().inEntityTickingRange(ChunkPos.asLong(pos)); -+ // Paper start - rewrite chunk system -+ io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder = this.chunkTaskScheduler.chunkHolderManager.getChunkHolder(io.papermc.paper.util.CoordinateUtils.getChunkKey(pos)); -+ return chunkHolder != null && chunkHolder.isEntityTickingReady(); -+ // Paper end - rewrite chunk system - } - - public boolean isNaturalSpawningAllowed(BlockPos pos) { -- return this.entityManager.canPositionTick(pos); -+ // Paper start - rewrite chunk system -+ io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder = this.chunkTaskScheduler.chunkHolderManager.getChunkHolder(io.papermc.paper.util.CoordinateUtils.getChunkKey(pos)); -+ return chunkHolder != null && chunkHolder.isEntityTickingReady(); -+ // Paper end - rewrite chunk system - } - - public boolean isNaturalSpawningAllowed(ChunkPos pos) { -- return this.entityManager.canPositionTick(pos); -+ // Paper start - rewrite chunk system -+ io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder = this.chunkTaskScheduler.chunkHolderManager.getChunkHolder(io.papermc.paper.util.CoordinateUtils.getChunkKey(pos)); -+ return chunkHolder != null && chunkHolder.isEntityTickingReady(); -+ // Paper end - rewrite chunk system - } - - @Override -@@ -2205,7 +2459,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report); - - crashreportsystemdetails.setDetail("Loaded entity count", () -> { -- return String.valueOf(this.entityManager.count()); -+ return String.valueOf(this.entityLookup.getAllCopy().length); // Paper - }); - return crashreportsystemdetails; - } -diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index b032ce115b98af0e0384fb88ca88075eb4ffac11..e2b72b07888e84fb4472920932b3feedbd4829b9 100644 ---- a/src/main/java/net/minecraft/server/level/ServerPlayer.java -+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -293,6 +293,50 @@ public class ServerPlayer extends Player { - public @Nullable String clientBrandName = null; // Paper - Brand support - public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event - -+ // Paper start - replace player chunk loader -+ private final java.util.concurrent.atomic.AtomicReference viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1)); -+ public io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader; -+ -+ public io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances getViewDistances() { -+ return this.viewDistances.get(); -+ } -+ -+ private void updateViewDistance(final java.util.function.Function update) { -+ for (io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances curr = this.viewDistances.get();;) { -+ if (this.viewDistances.compareAndSet(curr, update.apply(curr))) { -+ return; -+ } -+ } -+ } -+ -+ public void setTickViewDistance(final int distance) { -+ if ((distance < io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MIN_VIEW_DISTANCE || distance > io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MAX_VIEW_DISTANCE)) { -+ throw new IllegalArgumentException("Tick view distance must be a number between " + io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MIN_VIEW_DISTANCE + " and " + (io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MAX_VIEW_DISTANCE) + ", got: " + distance); -+ } -+ this.updateViewDistance((input) -> { -+ return input.setTickViewDistance(distance); -+ }); -+ } -+ -+ public void setLoadViewDistance(final int distance) { -+ if (distance != -1 && (distance < io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MIN_VIEW_DISTANCE || distance > io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MAX_VIEW_DISTANCE + 1)) { -+ throw new IllegalArgumentException("Load view distance must be a number between " + io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MIN_VIEW_DISTANCE + " and " + (io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MAX_VIEW_DISTANCE + 1) + " or -1, got: " + distance); -+ } -+ this.updateViewDistance((input) -> { -+ return input.setLoadViewDistance(distance); -+ }); -+ } -+ -+ public void setSendViewDistance(final int distance) { -+ if (distance != -1 && (distance < io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MIN_VIEW_DISTANCE || distance > io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MAX_VIEW_DISTANCE + 1)) { -+ throw new IllegalArgumentException("Send view distance must be a number between " + io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MIN_VIEW_DISTANCE + " and " + (io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.MAX_VIEW_DISTANCE + 1) + " or -1, got: " + distance); -+ } -+ this.updateViewDistance((input) -> { -+ return input.setSendViewDistance(distance); -+ }); -+ } -+ // Paper end - replace player chunk loader -+ - public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) { - super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); - this.chatVisibility = ChatVisiblity.FULL; -diff --git a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -index f206df06a7d8895175db31d4a840d7467ffe826f..8ef22f8f0d6da49247a90152e5cfa9ffc7f596a4 100644 ---- a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -+++ b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -@@ -37,15 +37,12 @@ import net.minecraft.world.level.chunk.status.ChunkStatus; - public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCloseable { - public static final int DEFAULT_BATCH_SIZE = 1000; - private static final Logger LOGGER = LogUtils.getLogger(); -- private final ProcessorMailbox taskMailbox; -- private final ObjectList> lightTasks = new ObjectArrayList<>(); -+ // Paper - rewrite chunk system - private final ChunkMap chunkMap; -- private final ProcessorHandle> sorterMailbox; -- private final int taskPerBatch = 1000; -- private final AtomicBoolean scheduled = new AtomicBoolean(); -+ // Paper - rewrite chunk system - - // Paper start - replace light engine impl -- protected final ca.spottedleaf.starlight.common.light.StarLightInterface theLightEngine; -+ public final ca.spottedleaf.starlight.common.light.StarLightInterface theLightEngine; - public final boolean hasBlockLight; - public final boolean hasSkyLight; - // Paper end - replace light engine impl -@@ -59,8 +56,7 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - ) { - super(chunkProvider, false, false); // Paper - destroy vanilla light engine state - this.chunkMap = chunkStorage; -- this.sorterMailbox = executor; -- this.taskMailbox = processor; -+ // Paper - rewrite chunk system - // Paper start - replace light engine impl - this.hasBlockLight = true; - this.hasSkyLight = hasBlockLight; // Nice variable name. -@@ -104,7 +100,7 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - ++totalChunks; - } - -- this.taskMailbox.tell(() -> { -+ this.chunkMap.level.chunkTaskScheduler.radiusAwareScheduler.queueInfiniteRadiusTask(() -> { // Paper - rewrite chunk system - this.theLightEngine.relightChunks(chunks, (ChunkPos chunkPos) -> { - chunkLightCallback.accept(chunkPos); - ((java.util.concurrent.Executor)((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().mainThreadProcessor).execute(() -> { -@@ -121,7 +117,7 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - private final Long2IntOpenHashMap chunksBeingWorkedOn = new Long2IntOpenHashMap(); - - private void queueTaskForSection(final int chunkX, final int chunkY, final int chunkZ, -- final Supplier runnable) { -+ final Supplier runnable) { // Paper - rewrite chunk system - final ServerLevel world = (ServerLevel)this.theLightEngine.getWorld(); - - final ChunkAccess center = this.theLightEngine.getAnyChunkNow(chunkX, chunkZ); -@@ -148,7 +144,7 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - - final long key = CoordinateUtils.getChunkKey(chunkX, chunkZ); - -- final ca.spottedleaf.starlight.common.light.StarLightInterface.LightQueue.ChunkTasks updateFuture = runnable.get(); -+ final io.papermc.paper.chunk.system.light.LightQueue.ChunkTasks updateFuture = runnable.get(); // Paper - rewrite chunk system - - if (updateFuture == null) { - // not scheduled -@@ -285,16 +281,11 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - } - - private void addTask(int x, int z, ThreadedLevelLightEngine.TaskType stage, Runnable task) { -- this.addTask(x, z, this.chunkMap.getChunkQueueLevel(ChunkPos.asLong(x, z)), stage, task); -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - private void addTask(int x, int z, IntSupplier completedLevelSupplier, ThreadedLevelLightEngine.TaskType stage, Runnable task) { -- this.sorterMailbox.tell(ChunkTaskPriorityQueueSorter.message(() -> { -- this.lightTasks.add(Pair.of(stage, task)); -- if (this.lightTasks.size() >= 1000) { -- this.runUpdate(); -- } -- }, ChunkPos.asLong(x, z), completedLevelSupplier)); -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - @Override -@@ -327,83 +318,15 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - } - - public CompletableFuture lightChunk(ChunkAccess chunk, boolean excludeBlocks) { -- // Paper start - replace light engine impl -- if (true) { -- boolean lit = excludeBlocks; -- final ChunkPos chunkPos = chunk.getPos(); -- -- return CompletableFuture.supplyAsync(() -> { -- final Boolean[] emptySections = StarLightEngine.getEmptySectionsForChunk(chunk); -- if (!lit) { -- chunk.setLightCorrect(false); -- this.theLightEngine.lightChunk(chunk, emptySections); -- chunk.setLightCorrect(true); -- } else { -- this.theLightEngine.forceLoadInChunk(chunk, emptySections); -- // can't really force the chunk to be edged checked, as we need neighbouring chunks - but we don't have -- // them, so if it's not loaded then i guess we can't do edge checks. later loads of the chunk should -- // catch what we miss here. -- this.theLightEngine.checkChunkEdges(chunkPos.x, chunkPos.z); -- } -- -- this.chunkMap.releaseLightTicket(chunkPos); -- return chunk; -- }, (runnable) -> { -- this.theLightEngine.scheduleChunkLight(chunkPos, runnable); -- this.tryScheduleUpdate(); -- }).whenComplete((final ChunkAccess c, final Throwable throwable) -> { -- if (throwable != null) { -- LOGGER.error("Failed to light chunk " + chunkPos, throwable); -- } -- }); -- } -- // Paper end - replace light engine impl -- ChunkPos chunkPos = chunk.getPos(); -- chunk.setLightCorrect(false); -- this.addTask(chunkPos.x, chunkPos.z, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> { -- if (!excludeBlocks) { -- super.propagateLightSources(chunkPos); -- } -- }, () -> "lightChunk " + chunkPos + " " + excludeBlocks)); -- return CompletableFuture.supplyAsync(() -> { -- chunk.setLightCorrect(true); -- this.chunkMap.releaseLightTicket(chunkPos); -- return chunk; -- }, task -> this.addTask(chunkPos.x, chunkPos.z, ThreadedLevelLightEngine.TaskType.POST_UPDATE, task)); -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - public void tryScheduleUpdate() { -- if (this.hasLightWork() && this.scheduled.compareAndSet(false, true)) { // Paper // Paper - rewrite light engine -- this.taskMailbox.tell(() -> { -- this.runUpdate(); -- this.scheduled.set(false); -- }); -- } -+ // Paper - rewrite chunk system - } - - private void runUpdate() { -- int i = Math.min(this.lightTasks.size(), 1000); -- ObjectListIterator> objectListIterator = this.lightTasks.iterator(); -- -- int j; -- for (j = 0; objectListIterator.hasNext() && j < i; j++) { -- Pair pair = objectListIterator.next(); -- if (pair.getFirst() == ThreadedLevelLightEngine.TaskType.PRE_UPDATE) { -- pair.getSecond().run(); -- } -- } -- -- objectListIterator.back(j); -- this.theLightEngine.propagateChanges(); // Paper - rewrite light engine -- -- for (int var5 = 0; objectListIterator.hasNext() && var5 < i; var5++) { -- Pair pair2 = objectListIterator.next(); -- if (pair2.getFirst() == ThreadedLevelLightEngine.TaskType.POST_UPDATE) { -- pair2.getSecond().run(); -- } -- -- objectListIterator.remove(); -- } -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - public CompletableFuture waitForPendingTasks(int x, int z) { -diff --git a/src/main/java/net/minecraft/server/level/Ticket.java b/src/main/java/net/minecraft/server/level/Ticket.java -index eba83b085435150e5954fd5d41dda9ce1d0601ad..e97329f867de2acbdd666925ba5d2aafa7a90574 100644 ---- a/src/main/java/net/minecraft/server/level/Ticket.java -+++ b/src/main/java/net/minecraft/server/level/Ticket.java -@@ -6,9 +6,12 @@ public final class Ticket implements Comparable> { - private final TicketType type; - private final int ticketLevel; - public final T key; -- private long createdTick; -+ // Paper start - rewrite chunk system -+ public long removeDelay; - -- protected Ticket(TicketType type, int level, T argument) { -+ public Ticket(TicketType type, int level, T argument, long removeDelay) { -+ this.removeDelay = removeDelay; -+ // Paper end - rewrite chunk system - this.type = type; - this.ticketLevel = level; - this.key = argument; -@@ -41,7 +44,7 @@ public final class Ticket implements Comparable> { - - @Override - public String toString() { -- return "Ticket[" + this.type + " " + this.ticketLevel + " (" + this.key + ")] at " + this.createdTick; -+ return "Ticket[" + this.type + " " + this.ticketLevel + " (" + this.key + ")] to die in " + this.removeDelay; // Paper - rewrite chunk system - } - - public TicketType getType() { -@@ -53,11 +56,10 @@ public final class Ticket implements Comparable> { - } - - protected void setCreatedTick(long tickCreated) { -- this.createdTick = tickCreated; -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - protected boolean timedOut(long currentTick) { -- long l = this.type.timeout(); -- return l != 0L && currentTick - this.createdTick > l; -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - } -diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java -index 6051e5f272838ef23276a90e21c2fc821ca155d1..658e63ebde81dc14c8ab5850fb246dc0aab25dea 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; - - public class TicketType { - public static final TicketType FUTURE_AWAIT = create("future_await", Long::compareTo); // Paper -+ public static final TicketType ASYNC_LOAD = create("async_load", Long::compareTo); // Paper - - private final String name; - private final Comparator comparator; -@@ -27,6 +28,15 @@ public class TicketType { - public static final TicketType PLUGIN = TicketType.create("plugin", (a, b) -> 0); // CraftBukkit - public static final TicketType PLUGIN_TICKET = TicketType.create("plugin_ticket", (plugin1, plugin2) -> plugin1.getClass().getName().compareTo(plugin2.getClass().getName())); // CraftBukkit - public static final TicketType CHUNK_RELIGHT = create("light_update", Long::compareTo); // Paper - ensure chunks stay loaded for lighting -+ // Paper start - rewrite chunk system -+ public static final TicketType CHUNK_LOAD = create("chunk_load", Long::compareTo); -+ public static final TicketType STATUS_UPGRADE = create("status_upgrade", Long::compareTo); -+ public static final TicketType ENTITY_LOAD = create("entity_load", Long::compareTo); -+ public static final TicketType POI_LOAD = create("poi_load", Long::compareTo); -+ public static final TicketType UNLOAD_COOLDOWN = create("unload_cooldown", (u1, u2) -> 0, 5 * 20); -+ public static final TicketType NON_FULL_SYNC_LOAD = create("non_full_sync_load", Long::compareTo); -+ public static final TicketType DELAY_UNLOAD = create("delay_unload", Comparator.comparingLong(ChunkPos::toLong), 1); -+ // Paper end - rewrite chunk system - - public static TicketType create(String name, Comparator argumentComparator) { - return new TicketType<>(name, argumentComparator, 0L); -diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java -index abbd4140cb4478a34a5185d8555f83d96c04d468..a6c31a558794a6e626e83176a1cbe78b6bd90f6e 100644 ---- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java -+++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java -@@ -554,4 +554,21 @@ public class WorldGenRegion implements WorldGenLevel { - public long nextSubTickCount() { - return this.subTickCount.getAndIncrement(); - } -+ -+ // Paper start -+ // No-op, this class doesn't provide entity access -+ @Override -+ public List getHardCollidingEntities(Entity except, AABB box, Predicate predicate) { -+ return Collections.emptyList(); -+ } -+ -+ @Override -+ public void getEntities(Entity except, AABB box, Predicate predicate, List into) {} -+ -+ @Override -+ public void getHardCollidingEntities(Entity except, AABB box, Predicate predicate, List into) {} -+ -+ @Override -+ public void getEntitiesByClass(Class clazz, Entity except, AABB box, List into, Predicate predicate) {} -+ // Paper end - } -diff --git a/src/main/java/net/minecraft/server/network/PlayerChunkSender.java b/src/main/java/net/minecraft/server/network/PlayerChunkSender.java -index c502d9b85eb68b277ae17dfea34e0475f0156647..27d0f1ed58948039004f8f1eba2f7f9609fdeec0 100644 ---- a/src/main/java/net/minecraft/server/network/PlayerChunkSender.java -+++ b/src/main/java/net/minecraft/server/network/PlayerChunkSender.java -@@ -43,16 +43,23 @@ public class PlayerChunkSender { - - public void dropChunk(ServerPlayer player, ChunkPos pos) { - if (!this.pendingChunks.remove(pos.toLong()) && player.isAlive()) { -+ // Paper start - rewrite player chunk loader -+ dropChunkStatic(player, pos); -+ } -+ } -+ public static void dropChunkStatic(ServerPlayer player, ChunkPos pos) { -+ player.serverLevel().chunkSource.chunkMap.getVisibleChunkIfPresent(pos.toLong()).removePlayer(player); - player.connection.send(new ClientboundForgetLevelChunkPacket(pos)); - // Paper start - PlayerChunkUnloadEvent - if (io.papermc.paper.event.packet.PlayerChunkUnloadEvent.getHandlerList().getRegisteredListeners().length > 0) { - new io.papermc.paper.event.packet.PlayerChunkUnloadEvent(player.getBukkitEntity().getWorld().getChunkAt(pos.longKey), player.getBukkitEntity()).callEvent(); - } - // Paper end - PlayerChunkUnloadEvent -- } - } -+ // Paper end - rewrite player chunk loader - - public void sendNextChunks(ServerPlayer player) { -+ if (true) return; // Paper - rewrite player chunk loader - if (this.unacknowledgedBatches < this.maxUnacknowledgedBatches) { - float f = Math.max(1.0F, this.desiredChunksPerTick); - this.batchQuota = Math.min(this.batchQuota + this.desiredChunksPerTick, f); -@@ -78,7 +85,8 @@ public class PlayerChunkSender { - } - } - -- private static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) { -+ public static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) { // Paper - rewrite chunk loader - public -+ handler.player.serverLevel().chunkSource.chunkMap.getVisibleChunkIfPresent(chunk.getPos().toLong()).addPlayer(handler.player); - handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), null, null)); - // Paper start - PlayerChunkLoadEvent - if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) { -@@ -118,6 +126,7 @@ public class PlayerChunkSender { - } - - public void onChunkBatchReceivedByClient(float desiredBatchSize) { -+ if (true) return; // Paper - rewrite player chunk loader - this.unacknowledgedBatches--; - this.desiredChunksPerTick = Double.isNaN((double)desiredBatchSize) ? 0.01F : Mth.clamp(desiredBatchSize, 0.01F, 64.0F); - if (this.unacknowledgedBatches == 0) { -diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 0aa28caa1254137c0bae8e213bd08c9a654f5335..c4b4e5f5c9366b241686e881cda34568a57b4877 100644 ---- a/src/main/java/net/minecraft/server/players/PlayerList.java -+++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -296,7 +296,7 @@ public abstract class PlayerList { - boolean flag2 = gamerules.getBoolean(GameRules.RULE_LIMITED_CRAFTING); - - // Spigot - view distance -- playerconnection.send(new ClientboundLoginPacket(player.getId(), worlddata.isHardcore(), this.server.levelKeys(), this.getMaxPlayers(), worldserver1.spigotConfig.viewDistance, worldserver1.spigotConfig.simulationDistance, flag1, !flag, flag2, player.createCommonSpawnInfo(worldserver1), this.server.enforceSecureProfile())); -+ playerconnection.send(new ClientboundLoginPacket(player.getId(), worlddata.isHardcore(), this.server.levelKeys(), this.getMaxPlayers(), worldserver1.getWorld().getSendViewDistance(), worldserver1.getWorld().getSimulationDistance(), flag1, !flag, flag2, player.createCommonSpawnInfo(worldserver1), this.server.enforceSecureProfile())); // Paper - replace old player chunk management - player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit - playerconnection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); - playerconnection.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities())); -@@ -943,8 +943,8 @@ public abstract class PlayerList { - LevelData worlddata = worldserver2.getLevelData(); - - entityplayer1.connection.send(new ClientboundRespawnPacket(entityplayer1.createCommonSpawnInfo(worldserver2), (byte) i)); -- entityplayer1.connection.send(new ClientboundSetChunkCacheRadiusPacket(worldserver1.spigotConfig.viewDistance)); // Spigot -- entityplayer1.connection.send(new ClientboundSetSimulationDistancePacket(worldserver1.spigotConfig.simulationDistance)); // Spigot -+ entityplayer1.connection.send(new ClientboundSetChunkCacheRadiusPacket(worldserver1.getWorld().getSendViewDistance())); // Spigot // Paper - replace old player chunk management -+ entityplayer1.connection.send(new ClientboundSetSimulationDistancePacket(worldserver1.getWorld().getSimulationDistance())); // Spigot // Paper - replace old player chunk management - entityplayer1.connection.teleport(CraftLocation.toBukkit(entityplayer1.position(), worldserver2.getWorld(), entityplayer1.getYRot(), entityplayer1.getXRot())); // CraftBukkit - entityplayer1.connection.send(new ClientboundSetDefaultSpawnPositionPacket(worldserver1.getSharedSpawnPos(), worldserver1.getSharedSpawnAngle())); - entityplayer1.connection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); -@@ -1496,7 +1496,7 @@ public abstract class PlayerList { - - public void setViewDistance(int viewDistance) { - this.viewDistance = viewDistance; -- this.broadcastAll(new ClientboundSetChunkCacheRadiusPacket(viewDistance)); -+ //this.broadcastAll(new ClientboundSetChunkCacheRadiusPacket(viewDistance)); // Paper - move into setViewDistance - Iterator iterator = this.server.getAllLevels().iterator(); - - while (iterator.hasNext()) { -@@ -1511,7 +1511,7 @@ public abstract class PlayerList { - - public void setSimulationDistance(int simulationDistance) { - this.simulationDistance = simulationDistance; -- this.broadcastAll(new ClientboundSetSimulationDistancePacket(simulationDistance)); -+ //this.broadcastAll(new ClientboundSetSimulationDistancePacket(simulationDistance)); // Paper - handled by playerchunkloader - Iterator iterator = this.server.getAllLevels().iterator(); - - while (iterator.hasNext()) { -diff --git a/src/main/java/net/minecraft/util/SortedArraySet.java b/src/main/java/net/minecraft/util/SortedArraySet.java -index ea72dcb064a35bc6245bc5c94d592efedd8faf41..0793dfe47e68a2b48b010aad5b12dcfa1701293a 100644 ---- a/src/main/java/net/minecraft/util/SortedArraySet.java -+++ b/src/main/java/net/minecraft/util/SortedArraySet.java -@@ -14,6 +14,14 @@ public class SortedArraySet extends AbstractSet { - T[] contents; - int size; - -+ // Paper start - rewrite chunk system -+ public SortedArraySet(final SortedArraySet other) { -+ this.comparator = other.comparator; -+ this.size = other.size; -+ this.contents = Arrays.copyOf(other.contents, this.size); -+ } -+ // Paper end - rewrite chunk system -+ - private SortedArraySet(int initialCapacity, Comparator comparator) { - this.comparator = comparator; - if (initialCapacity < 0) { -@@ -22,6 +30,41 @@ public class SortedArraySet extends AbstractSet { - this.contents = (T[])castRawArray(new Object[initialCapacity]); - } - } -+ // Paper start - optimise removeIf -+ @Override -+ public boolean removeIf(java.util.function.Predicate filter) { -+ // prev. impl used an iterator, which could be n^2 and creates garbage -+ int i = 0, len = this.size; -+ T[] backingArray = this.contents; -+ -+ for (;;) { -+ if (i >= len) { -+ return false; -+ } -+ if (!filter.test(backingArray[i])) { -+ ++i; -+ continue; -+ } -+ break; -+ } -+ -+ // we only want to write back to backingArray if we really need to -+ -+ int lastIndex = i; // this is where new elements are shifted to -+ -+ for (; i < len; ++i) { -+ T curr = backingArray[i]; -+ if (!filter.test(curr)) { // if test throws we're screwed -+ backingArray[lastIndex++] = curr; -+ } -+ } -+ -+ // cleanup end -+ Arrays.fill(backingArray, lastIndex, len, null); -+ this.size = lastIndex; -+ return true; -+ } -+ // Paper end - optimise removeIf - - public static > SortedArraySet create() { - return create(10); -@@ -110,6 +153,31 @@ public class SortedArraySet extends AbstractSet { - } - } - -+ // Paper start - rewrite chunk system -+ public T replace(T object) { -+ int i = this.findIndex(object); -+ if (i >= 0) { -+ T old = this.contents[i]; -+ this.contents[i] = object; -+ return old; -+ } else { -+ this.addInternal(object, getInsertionPosition(i)); -+ return object; -+ } -+ } -+ -+ public T removeAndGet(T object) { -+ int i = this.findIndex(object); -+ if (i >= 0) { -+ final T ret = this.contents[i]; -+ this.removeInternal(i); -+ return ret; -+ } else { -+ return null; -+ } -+ } -+ // Paper end - rewrite chunk system -+ - @Override - public boolean remove(Object object) { - int i = this.findIndex((T)object); -diff --git a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java -index 0382b6597a130d746f8954a93a756a9d1ac81d50..ffbb3bf9ff3fc968ef69d4f889b0baf7e8ab691b 100644 ---- a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java -+++ b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java -@@ -227,7 +227,13 @@ public class WorldUpgrader { - this.previousWriteFuture.join(); - } - -+ // Paper start - async chunk io -+ try { - this.previousWriteFuture = storage.write(chunkPos, nbttagcompound1); -+ } catch (final IOException e) { -+ com.destroystokyo.paper.util.SneakyThrow.sneaky(e); -+ } -+ // Paper end - async chunk io - return true; - } - } -diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 62363c09111aaa31220fb260940744c097af7b3c..ff497f0e80889508dd8c183b48cd33bc7831ba6c 100644 ---- a/src/main/java/net/minecraft/world/entity/Entity.java -+++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -481,6 +481,58 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - } - // Paper end - -+ // Paper start -+ /** -+ * Overriding this field will cause memory leaks. -+ */ -+ private final boolean hardCollides; -+ -+ private static final java.util.Map, Boolean> cachedOverrides = java.util.Collections.synchronizedMap(new java.util.WeakHashMap<>()); -+ { -+ /* // Goodbye, broken on reobf... -+ Boolean hardCollides = cachedOverrides.get(this.getClass()); -+ if (hardCollides == null) { -+ try { -+ java.lang.reflect.Method getHardCollisionBoxEntityMethod = Entity.class.getMethod("canCollideWith", Entity.class); -+ java.lang.reflect.Method hasHardCollisionBoxMethod = Entity.class.getMethod("canBeCollidedWith"); -+ if (!this.getClass().getMethod(hasHardCollisionBoxMethod.getName(), hasHardCollisionBoxMethod.getParameterTypes()).equals(hasHardCollisionBoxMethod) -+ || !this.getClass().getMethod(getHardCollisionBoxEntityMethod.getName(), getHardCollisionBoxEntityMethod.getParameterTypes()).equals(getHardCollisionBoxEntityMethod)) { -+ hardCollides = Boolean.TRUE; -+ } else { -+ hardCollides = Boolean.FALSE; -+ } -+ cachedOverrides.put(this.getClass(), hardCollides); -+ } -+ catch (ThreadDeath thr) { throw thr; } -+ catch (Throwable thr) { -+ // shouldn't happen, just explode -+ throw new RuntimeException(thr); -+ } -+ } */ -+ this.hardCollides = this instanceof Boat -+ || this instanceof net.minecraft.world.entity.monster.Shulker -+ || this instanceof net.minecraft.world.entity.vehicle.AbstractMinecart -+ || this.shouldHardCollide(); -+ } -+ -+ // plugins can override -+ protected boolean shouldHardCollide() { -+ return false; -+ } -+ -+ public final boolean hardCollides() { -+ return this.hardCollides; -+ } -+ -+ public net.minecraft.server.level.FullChunkStatus chunkStatus; -+ -+ public int sectionX = Integer.MIN_VALUE; -+ public int sectionY = Integer.MIN_VALUE; -+ public int sectionZ = Integer.MIN_VALUE; -+ -+ public boolean updatingSectionStatus = false; -+ // Paper end -+ - public Entity(EntityType type, Level world) { - this.id = Entity.ENTITY_COUNTER.incrementAndGet(); - this.passengers = ImmutableList.of(); -@@ -2607,11 +2659,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - return InteractionResult.PASS; - } - -- public boolean canCollideWith(Entity other) { -+ public boolean canCollideWith(Entity other) { // Paper - diff on change, hard colliding entities override this - TODO CHECK ON UPDATE - AbstractMinecart/Boat override - return other.canBeCollidedWith() && !this.isPassengerOfSameVehicle(other); - } - -- public boolean canBeCollidedWith() { -+ public boolean canBeCollidedWith() { // Paper - diff on change, hard colliding entities override this TODO CHECK ON UPDATE - Boat/Shulker override - return false; - } - -@@ -4042,6 +4094,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - }).count(); - } - -+ // Paper start - rewrite chunk system -+ public boolean hasAnyPlayerPassengers() { -+ // copied from below -+ if (this.passengers.isEmpty()) { return false; } -+ return this.getIndirectPassengersStream().anyMatch((entity) -> entity instanceof Player); -+ } -+ // Paper end - rewrite chunk system - public boolean hasExactlyOnePlayerPassenger() { - if (this.passengers.isEmpty()) { return false; } // Paper - Optimize indirect passenger iteration - return this.countPlayerPassengers() == 1; -@@ -4392,6 +4451,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - return; - } - // Paper end - Block invalid positions and bounding box -+ // Paper start - rewrite chunk system -+ if (this.updatingSectionStatus) { -+ LOGGER.error("Refusing to update position for entity {} to position {} since it is processing a section status update", this, new Vec3(x, y, z), new Throwable()); -+ return; -+ } -+ // Paper end - rewrite chunk system - // Paper start - Fix MC-4 - if (this instanceof ItemEntity) { - if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.fixEntityPositionDesync) { -@@ -4519,6 +4584,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - - @Override - public final void setRemoved(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { -+ // Paper start - rewrite chunk system -+ io.papermc.paper.util.TickThread.ensureTickThread(this, "Cannot remove entity off-main"); -+ if (!((ServerLevel)this.level).getEntityLookup().canRemoveEntity(this)) { -+ LOGGER.warn("Entity " + this + " is currently prevented from being removed from the world since it is processing section status updates", new Throwable()); -+ return; -+ } -+ // Paper end - rewrite chunk system - CraftEventFactory.callEntityRemoveEvent(this, cause); - // CraftBukkit end - final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers -@@ -4530,7 +4602,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - this.stopRiding(); - } - -- this.getPassengers().forEach(Entity::stopRiding); -+ if (entity_removalreason != RemovalReason.UNLOADED_TO_CHUNK) this.getPassengers().forEach(Entity::stopRiding); // Paper - chunk system - don't adjust passenger state when unloading, it's just not safe (and messes with our logic in entity chunk unload) - this.levelCallback.onRemove(entity_removalreason); - // Paper start - Folia schedulers - if (!(this instanceof ServerPlayer) && entity_removalreason != RemovalReason.CHANGED_DIMENSION && !alreadyRemoved) { -@@ -4561,7 +4633,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - - @Override - public boolean shouldBeSaved() { -- return this.removalReason != null && !this.removalReason.shouldSave() ? false : (this.isPassenger() ? false : !this.isVehicle() || !this.hasExactlyOnePlayerPassenger()); -+ return this.removalReason != null && !this.removalReason.shouldSave() ? false : (this.isPassenger() ? false : !this.isVehicle() || !this.hasAnyPlayerPassengers()); // Paper - rewrite chunk system - it should check if the entity has ANY player passengers - } - - @Override -diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -index 71d8909f35a22256406a2232d21adfd7d94dc3a5..7b52b0507cbda76aee1db954641f397bef51f94d 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -+++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -@@ -40,20 +40,40 @@ import net.minecraft.world.level.chunk.storage.SimpleRegionStorage; - public class PoiManager extends SectionStorage { - public static final int MAX_VILLAGE_DISTANCE = 6; - public static final int VILLAGE_SECTION_SIZE = 1; -- private final PoiManager.DistanceTracker distanceTracker; -- private final LongSet loadedChunks = new LongOpenHashSet(); -+ // Paper start - rewrite chunk system -+ // the vanilla tracker needs to be replaced because it does not support level removes -+ public final net.minecraft.server.level.ServerLevel world; -+ private final io.papermc.paper.util.misc.Delayed26WayDistancePropagator3D villageDistanceTracker = new io.papermc.paper.util.misc.Delayed26WayDistancePropagator3D(); -+ static final int POI_DATA_SOURCE = 7; -+ public static int convertBetweenLevels(final int level) { -+ return POI_DATA_SOURCE - level; -+ } -+ -+ protected void updateDistanceTracking(long section) { -+ if (this.isVillageCenter(section)) { -+ this.villageDistanceTracker.setSource(section, POI_DATA_SOURCE); -+ } else { -+ this.villageDistanceTracker.removeSource(section); -+ } -+ } -+ // Paper end - rewrite chunk system - - public PoiManager( - RegionStorageInfo storageKey, Path directory, DataFixer dataFixer, boolean dsync, RegistryAccess registryManager, LevelHeightAccessor world - ) { - super( -+ // Paper start -+ storageKey, -+ directory, -+ dsync, -+ // Paper end - new SimpleRegionStorage(storageKey, directory, dataFixer, dsync, DataFixTypes.POI_CHUNK), - PoiSection::codec, - PoiSection::new, - registryManager, - world - ); -- this.distanceTracker = new PoiManager.DistanceTracker(); -+ this.world = (net.minecraft.server.level.ServerLevel)world; // Paper - rewrite chunk system - } - - public void add(BlockPos pos, Holder type) { -@@ -187,8 +207,8 @@ public class PoiManager extends SectionStorage { - } - - public int sectionsToVillage(SectionPos pos) { -- this.distanceTracker.runAllUpdates(); -- return this.distanceTracker.getLevel(pos.asLong()); -+ this.villageDistanceTracker.propagateUpdates(); // Paper - replace distance tracking util -+ return convertBetweenLevels(this.villageDistanceTracker.getLevel(io.papermc.paper.util.CoordinateUtils.getChunkSectionKey(pos))); // Paper - replace distance tracking util - } - - boolean isVillageCenter(long pos) { -@@ -202,20 +222,117 @@ public class PoiManager extends SectionStorage { - - @Override - public void tick(BooleanSupplier shouldKeepTicking) { -- super.tick(shouldKeepTicking); -- this.distanceTracker.runAllUpdates(); -+ this.villageDistanceTracker.propagateUpdates(); // Paper - rewrite chunk system - } - - @Override -- protected void setDirty(long pos) { -- super.setDirty(pos); -- this.distanceTracker.update(pos, this.distanceTracker.getLevelFromSource(pos), false); -+ public void setDirty(long pos) { -+ // Paper start - rewrite chunk system -+ int chunkX = io.papermc.paper.util.CoordinateUtils.getChunkSectionX(pos); -+ int chunkZ = io.papermc.paper.util.CoordinateUtils.getChunkSectionZ(pos); -+ io.papermc.paper.chunk.system.scheduling.ChunkHolderManager manager = this.world.chunkTaskScheduler.chunkHolderManager; -+ io.papermc.paper.chunk.system.poi.PoiChunk chunk = manager.getPoiChunkIfLoaded(chunkX, chunkZ, false); -+ if (chunk != null) { -+ chunk.setDirty(true); -+ } -+ this.updateDistanceTracking(pos); -+ // Paper end - rewrite chunk system - } - - @Override - protected void onSectionLoad(long pos) { -- this.distanceTracker.update(pos, this.distanceTracker.getLevelFromSource(pos), false); -+ this.updateDistanceTracking(pos); // Paper - move to new distance tracking util -+ } -+ -+ // Paper start - rewrite chunk system -+ @Override -+ public Optional get(long pos) { -+ int chunkX = io.papermc.paper.util.CoordinateUtils.getChunkSectionX(pos); -+ int chunkY = io.papermc.paper.util.CoordinateUtils.getChunkSectionY(pos); -+ int chunkZ = io.papermc.paper.util.CoordinateUtils.getChunkSectionZ(pos); -+ -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Accessing poi chunk off-main"); -+ -+ io.papermc.paper.chunk.system.scheduling.ChunkHolderManager manager = this.world.chunkTaskScheduler.chunkHolderManager; -+ io.papermc.paper.chunk.system.poi.PoiChunk ret = manager.getPoiChunkIfLoaded(chunkX, chunkZ, true); -+ -+ return ret == null ? Optional.empty() : ret.getSectionForVanilla(chunkY); -+ } -+ -+ @Override -+ public Optional getOrLoad(long pos) { -+ int chunkX = io.papermc.paper.util.CoordinateUtils.getChunkSectionX(pos); -+ int chunkY = io.papermc.paper.util.CoordinateUtils.getChunkSectionY(pos); -+ int chunkZ = io.papermc.paper.util.CoordinateUtils.getChunkSectionZ(pos); -+ -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Accessing poi chunk off-main"); -+ -+ io.papermc.paper.chunk.system.scheduling.ChunkHolderManager manager = this.world.chunkTaskScheduler.chunkHolderManager; -+ -+ if (chunkY >= io.papermc.paper.util.WorldUtil.getMinSection(this.world) && -+ chunkY <= io.papermc.paper.util.WorldUtil.getMaxSection(this.world)) { -+ io.papermc.paper.chunk.system.poi.PoiChunk ret = manager.getPoiChunkIfLoaded(chunkX, chunkZ, true); -+ if (ret != null) { -+ return ret.getSectionForVanilla(chunkY); -+ } else { -+ return manager.loadPoiChunk(chunkX, chunkZ).getSectionForVanilla(chunkY); -+ } -+ } -+ // retain vanilla behavior: do not load section if out of bounds! -+ return Optional.empty(); -+ } -+ -+ @Override -+ protected PoiSection getOrCreate(long pos) { -+ int chunkX = io.papermc.paper.util.CoordinateUtils.getChunkSectionX(pos); -+ int chunkY = io.papermc.paper.util.CoordinateUtils.getChunkSectionY(pos); -+ int chunkZ = io.papermc.paper.util.CoordinateUtils.getChunkSectionZ(pos); -+ -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Accessing poi chunk off-main"); -+ -+ io.papermc.paper.chunk.system.scheduling.ChunkHolderManager manager = this.world.chunkTaskScheduler.chunkHolderManager; -+ -+ io.papermc.paper.chunk.system.poi.PoiChunk ret = manager.getPoiChunkIfLoaded(chunkX, chunkZ, true); -+ if (ret != null) { -+ return ret.getOrCreateSection(chunkY); -+ } else { -+ return manager.loadPoiChunk(chunkX, chunkZ).getOrCreateSection(chunkY); -+ } -+ } -+ -+ public void onUnload(long coordinate) { // Paper - rewrite chunk system -+ int chunkX = io.papermc.paper.util.MCUtil.getCoordinateX(coordinate); -+ int chunkZ = io.papermc.paper.util.MCUtil.getCoordinateZ(coordinate); -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Unloading poi chunk off-main"); -+ for (int section = this.levelHeightAccessor.getMinSection(); section < this.levelHeightAccessor.getMaxSection(); ++section) { -+ long sectionPos = SectionPos.asLong(chunkX, section, chunkZ); -+ this.updateDistanceTracking(sectionPos); -+ } -+ } -+ -+ public void loadInPoiChunk(io.papermc.paper.chunk.system.poi.PoiChunk poiChunk) { -+ int chunkX = poiChunk.chunkX; -+ int chunkZ = poiChunk.chunkZ; -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Loading poi chunk off-main"); -+ for (int sectionY = this.levelHeightAccessor.getMinSection(); sectionY < this.levelHeightAccessor.getMaxSection(); ++sectionY) { -+ PoiSection section = poiChunk.getSection(sectionY); -+ if (section != null && !section.isEmpty()) { -+ this.onSectionLoad(SectionPos.asLong(chunkX, sectionY, chunkZ)); -+ } -+ } -+ } -+ -+ public void checkConsistency(net.minecraft.world.level.chunk.ChunkAccess chunk) { -+ int chunkX = chunk.getPos().x; -+ int chunkZ = chunk.getPos().z; -+ int minY = io.papermc.paper.util.WorldUtil.getMinSection(chunk); -+ int maxY = io.papermc.paper.util.WorldUtil.getMaxSection(chunk); -+ LevelChunkSection[] sections = chunk.getSections(); -+ for (int section = minY; section <= maxY; ++section) { -+ this.checkConsistencyWithBlocks(SectionPos.of(chunkX, section, chunkZ), sections[section - minY]); -+ } - } -+ // Paper end - rewrite chunk system - - public void checkConsistencyWithBlocks(SectionPos sectionPos, LevelChunkSection chunkSection) { - Util.ifElse(this.getOrLoad(sectionPos.asLong()), poiSet -> poiSet.refresh(populator -> { -@@ -251,7 +368,7 @@ public class PoiManager extends SectionStorage { - .map(sectionPos -> Pair.of(sectionPos, this.getOrLoad(sectionPos.asLong()))) - .filter(pair -> !pair.getSecond().map(PoiSection::isValid).orElse(false)) - .map(pair -> pair.getFirst().chunk()) -- .filter(chunkPos -> this.loadedChunks.add(chunkPos.toLong())) -+ // Paper - rewrite chunk system - .forEach(chunkPos -> world.getChunk(chunkPos.x, chunkPos.z, ChunkStatus.EMPTY)); - } - -@@ -265,7 +382,7 @@ public class PoiManager extends SectionStorage { - - @Override - protected int getLevelFromSource(long id) { -- return PoiManager.this.isVillageCenter(id) ? 0 : 7; -+ return PoiManager.this.isVillageCenter(id) ? 0 : 7; // Paper - rewrite chunk system - diff on change, this specifies the source level to use for distance tracking - } - - @Override -@@ -287,6 +404,35 @@ public class PoiManager extends SectionStorage { - } - } - -+ // Paper start - Asynchronous chunk io -+ @javax.annotation.Nullable -+ @Override -+ public net.minecraft.nbt.CompoundTag read(ChunkPos chunkcoordintpair) throws java.io.IOException { -+ // Paper start - rewrite chunk system -+ if (!io.papermc.paper.chunk.system.io.RegionFileIOThread.isRegionFileThread()) { -+ return io.papermc.paper.chunk.system.io.RegionFileIOThread.loadData( -+ this.world, chunkcoordintpair.x, chunkcoordintpair.z, io.papermc.paper.chunk.system.io.RegionFileIOThread.RegionFileType.POI_DATA, -+ io.papermc.paper.chunk.system.io.RegionFileIOThread.getIOBlockingPriorityForCurrentThread() -+ ); -+ } -+ // Paper end - rewrite chunk system -+ return super.read(chunkcoordintpair); -+ } -+ -+ @Override -+ public void write(ChunkPos chunkcoordintpair, net.minecraft.nbt.CompoundTag nbttagcompound) throws java.io.IOException { -+ // Paper start - rewrite chunk system -+ if (!io.papermc.paper.chunk.system.io.RegionFileIOThread.isRegionFileThread()) { -+ io.papermc.paper.chunk.system.io.RegionFileIOThread.scheduleSave( -+ this.world, chunkcoordintpair.x, chunkcoordintpair.z, nbttagcompound, -+ io.papermc.paper.chunk.system.io.RegionFileIOThread.RegionFileType.POI_DATA); -+ return; -+ } -+ // Paper end - rewrite chunk system -+ super.write(chunkcoordintpair, nbttagcompound); -+ } -+ // Paper end -+ - public static enum Occupancy { - HAS_SPACE(PoiRecord::hasSpace), - IS_OCCUPIED(PoiRecord::isOccupied), -diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java -index 971fb29a2c3dc713cb8ab1d2eed054cc16f9c93c..5b7deae326228e482b218aeebd857a59b7434eaf 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java -+++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java -@@ -29,6 +29,7 @@ public class PoiSection { - private final Map, Set> byType = Maps.newHashMap(); - private final Runnable setDirty; - private boolean isValid; -+ public final Optional noAllocateOptional = Optional.of(this); // Paper - rewrite chunk system - - public static Codec codec(Runnable updateListener) { - return RecordCodecBuilder.create( -@@ -46,6 +47,12 @@ public class PoiSection { - this(updateListener, true, ImmutableList.of()); - } - -+ // Paper start - isEmpty -+ public boolean isEmpty() { -+ return this.isValid && this.records.isEmpty() && this.byType.isEmpty(); -+ } -+ // Paper end -+ - private PoiSection(Runnable updateListener, boolean valid, List pois) { - this.setDirty = updateListener; - this.isValid = valid; -diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java -index bd20bea7f76a7307f1698fb2dfef37125032d166..9a28912f52824acdc80a62243b136e6f365bf567 100644 ---- a/src/main/java/net/minecraft/world/level/EntityGetter.java -+++ b/src/main/java/net/minecraft/world/level/EntityGetter.java -@@ -19,6 +19,18 @@ import net.minecraft.world.phys.shapes.Shapes; - import net.minecraft.world.phys.shapes.VoxelShape; - - public interface EntityGetter { -+ -+ // Paper start -+ List getHardCollidingEntities(Entity except, AABB box, Predicate predicate); -+ -+ void getEntities(Entity except, AABB box, Predicate predicate, List into); -+ -+ void getHardCollidingEntities(Entity except, AABB box, Predicate predicate, List into); -+ -+ void getEntitiesByClass(Class clazz, Entity except, final AABB box, List into, -+ Predicate predicate); -+ // Paper end -+ - List getEntities(@Nullable Entity except, AABB box, Predicate predicate); - - List getEntities(EntityTypeTest filter, AABB box, Predicate predicate); -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 975fcd4b8f93cb8c602ddeb165c485214eac10a4..d3137c9e5cc42ef191ea233b0d37eafeffc6f82c 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -547,6 +547,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - - if ((i & 2) != 0 && (!this.isClientSide || (i & 4) == 0) && (this.isClientSide || chunk == null || (chunk.getFullStatus() != null && chunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING)))) { // allow chunk to be null here as chunk.isReady() is false when we send our notification during block placement - this.sendBlockUpdated(blockposition, iblockdata1, iblockdata, i); -+ // Paper start - per player view distance - allow block updates for non-ticking chunks in player view distance -+ // if copied from above -+ } else if ((i & 2) != 0 && (!this.isClientSide || (i & 4) == 0)) { // Paper - replace old player chunk management -+ ((ServerLevel)this).getChunkSource().blockChanged(blockposition); -+ // Paper end - per player view distance - } - - if ((i & 1) != 0) { -@@ -941,7 +946,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - } - // Paper end - Perf: Optimize capturedTileEntities lookup - // CraftBukkit end -- return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && Thread.currentThread() != this.thread ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE)); -+ return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && !io.papermc.paper.util.TickThread.isTickThread() ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE)); // Paper - rewrite chunk system - } - - public void setBlockEntity(BlockEntity blockEntity) { -@@ -1032,26 +1037,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - public List getEntities(@Nullable Entity except, AABB box, Predicate predicate) { - this.getProfiler().incrementCounter("getEntities"); - List list = Lists.newArrayList(); -- -- this.getEntities().get(box, (entity1) -> { -- if (entity1 != except && predicate.test(entity1)) { -- list.add(entity1); -- } -- -- if (entity1 instanceof EnderDragon) { -- EnderDragonPart[] aentitycomplexpart = ((EnderDragon) entity1).getSubEntities(); -- int i = aentitycomplexpart.length; -- -- for (int j = 0; j < i; ++j) { -- EnderDragonPart entitycomplexpart = aentitycomplexpart[j]; -- -- if (entity1 != except && predicate.test(entitycomplexpart)) { -- list.add(entitycomplexpart); -- } -- } -- } -- -- }); -+ ((ServerLevel)this).getEntityLookup().getEntities(except, box, list, predicate); // Paper - optimise this call - return list; - } - -@@ -1069,33 +1055,23 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - - public void getEntities(EntityTypeTest filter, AABB box, Predicate predicate, List result, int limit) { - this.getProfiler().incrementCounter("getEntities"); -- this.getEntities().get(filter, box, (entity) -> { -- if (predicate.test(entity)) { -- result.add(entity); -- if (result.size() >= limit) { -- return AbortableIterationConsumer.Continuation.ABORT; -- } -- } -- -- if (entity instanceof EnderDragon entityenderdragon) { -- EnderDragonPart[] aentitycomplexpart = entityenderdragon.getSubEntities(); -- int j = aentitycomplexpart.length; -- -- for (int k = 0; k < j; ++k) { -- EnderDragonPart entitycomplexpart = aentitycomplexpart[k]; -- T t0 = filter.tryCast(entitycomplexpart); // CraftBukkit - decompile error -- -- if (t0 != null && predicate.test(t0)) { -- result.add(t0); -- if (result.size() >= limit) { -- return AbortableIterationConsumer.Continuation.ABORT; -- } -- } -- } -+ // Paper start - optimise this call -+ //TODO use limit -+ if (filter instanceof net.minecraft.world.entity.EntityType entityTypeTest) { -+ ((ServerLevel) this).getEntityLookup().getEntities(entityTypeTest, box, result, predicate); -+ } else { -+ Predicate test = (obj) -> { -+ return filter.tryCast(obj) != null; -+ }; -+ predicate = predicate == null ? test : test.and((Predicate) predicate); -+ Class base; -+ if (filter == null || (base = filter.getBaseClass()) == null || base == Entity.class) { -+ ((ServerLevel) this).getEntityLookup().getEntities((Entity) null, box, (List) result, (Predicate)predicate); -+ } else { -+ ((ServerLevel) this).getEntityLookup().getEntities(base, null, box, (List) result, (Predicate)predicate); // Paper - optimise this call - } -- -- return AbortableIterationConsumer.Continuation.CONTINUE; -- }); -+ } -+ // Paper end - optimise this call - } - - @Nullable -@@ -1385,4 +1361,45 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - } - } - // Paper end - notify observers even if grow failed -+ // Paper start -+ //protected final io.papermc.paper.world.EntitySliceManager entitySliceManager; // Paper - rewrite chunk system -+ -+ public org.bukkit.entity.Entity[] getChunkEntities(int chunkX, int chunkZ) { -+ io.papermc.paper.world.ChunkEntitySlices slices = ((ServerLevel)this).getEntityLookup().getChunk(chunkX, chunkZ); -+ if (slices == null) { -+ return new org.bukkit.entity.Entity[0]; -+ } -+ return slices.getChunkEntities(); -+ } -+ -+ @Override -+ public List getHardCollidingEntities(Entity except, AABB box, Predicate predicate) { -+ List ret = new java.util.ArrayList<>(); -+ ((ServerLevel)this).getEntityLookup().getHardCollidingEntities(except, box, ret, predicate); -+ return ret; -+ } -+ -+ @Override -+ public void getEntities(Entity except, AABB box, Predicate predicate, List into) { -+ ((ServerLevel)this).getEntityLookup().getEntities(except, box, into, predicate); -+ } -+ -+ @Override -+ public void getHardCollidingEntities(Entity except, AABB box, Predicate predicate, List into) { -+ ((ServerLevel)this).getEntityLookup().getHardCollidingEntities(except, box, into, predicate); -+ } -+ -+ @Override -+ public void getEntitiesByClass(Class clazz, Entity except, final AABB box, List into, -+ Predicate predicate) { -+ ((ServerLevel)this).getEntityLookup().getEntities((Class)clazz, except, box, (List)into, (Predicate)predicate); -+ } -+ -+ @Override -+ public List getEntitiesOfClass(Class entityClass, AABB box, Predicate predicate) { -+ List ret = new java.util.ArrayList<>(); -+ ((ServerLevel)this).getEntityLookup().getEntities(entityClass, null, box, ret, predicate); -+ return ret; -+ } -+ // Paper end - } -diff --git a/src/main/java/net/minecraft/world/level/LevelReader.java b/src/main/java/net/minecraft/world/level/LevelReader.java -index a0ae26d6197e1069ca09982b4f8b706c55ae8491..32bfeb9aa87b43a9d2ce46dcc99dbd0ff355b412 100644 ---- a/src/main/java/net/minecraft/world/level/LevelReader.java -+++ b/src/main/java/net/minecraft/world/level/LevelReader.java -@@ -26,6 +26,15 @@ public interface LevelReader extends BlockAndTintGetter, CollisionGetter, Signal - @Nullable - ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create); - -+ // Paper start - rewrite chunk system -+ default ChunkAccess syncLoadNonFull(int chunkX, int chunkZ, ChunkStatus status) { -+ if (status == null || status.isOrAfter(ChunkStatus.FULL)) { -+ throw new IllegalArgumentException("Status: " + status.toString()); -+ } -+ return this.getChunk(chunkX, chunkZ, status, true); -+ } -+ // Paper end - rewrite chunk system -+ - @Nullable ChunkAccess getChunkIfLoadedImmediately(int x, int z); // Paper - ifLoaded api (we need this since current impl blocks if the chunk is loading) - @Nullable default ChunkAccess getChunkIfLoadedImmediately(BlockPos pos) { return this.getChunkIfLoadedImmediately(pos.getX() >> 4, pos.getZ() >> 4);} - -diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index c9cd18ce79a6ee7297a8fd14f4dbe712570b3ced..927bdebdb8ae01613f0cea074b3367bd7ffe9ab1 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -@@ -120,7 +120,7 @@ public abstract class ChunkGenerator { - return CompletableFuture.supplyAsync(Util.wrapThreadWithTaskName("init_biomes", () -> { - chunk.fillBiomesFromNoise(this.biomeSource, noiseConfig.sampler()); - return chunk; -- }), Util.backgroundExecutor()); -+ }), executor); // Paper - run with supplied executor - } - - public abstract void applyCarvers(WorldGenRegion chunkRegion, long seed, RandomState noiseConfig, BiomeManager biomeAccess, StructureManager structureAccessor, ChunkAccess chunk, GenerationStep.Carving carverStep); -@@ -315,7 +315,7 @@ public abstract class ChunkGenerator { - return Pair.of(placement.getLocatePos(pos), holder); - } - -- ChunkAccess ichunkaccess = world.getChunk(pos.x, pos.z, ChunkStatus.STRUCTURE_STARTS); -+ ChunkAccess ichunkaccess = world.syncLoadNonFull(pos.x, pos.z, ChunkStatus.STRUCTURE_STARTS); // Paper - rewrite chunk system - - structurestart = structureAccessor.getStartForStructure(SectionPos.bottomOf(ichunkaccess), (Structure) holder.value(), ichunkaccess); - } while (structurestart == null); -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 bac191f92ea3735df19c68d5568c2c7962c8680f..5d94aee1303d9eca5f1fa9a2e033ad0d12909635 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -86,6 +86,7 @@ public class LevelChunk extends ChunkAccess { - private final Int2ObjectMap gameEventListenerRegistrySections; - private final LevelChunkTicks blockTicks; - private final LevelChunkTicks fluidTicks; -+ public volatile FullChunkStatus chunkStatus = FullChunkStatus.INACCESSIBLE; // Paper - rewrite chunk system - - public LevelChunk(Level world, ChunkPos pos) { - this(world, pos, UpgradeData.EMPTY, new LevelChunkTicks<>(), new LevelChunkTicks<>(), 0L, (LevelChunkSection[]) null, (LevelChunk.PostLoadProcessor) null, (BlendingData) null); -@@ -690,9 +691,26 @@ public class LevelChunk extends ChunkAccess { - - } - -- // CraftBukkit start -- public void loadCallback() { -- // Paper start - neighbour cache -+ // Paper start - new load callbacks -+ private io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder; -+ public io.papermc.paper.chunk.system.scheduling.NewChunkHolder getChunkHolder() { -+ return this.chunkHolder; -+ } -+ -+ public void setChunkHolder(io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder) { -+ if (chunkHolder == null) { -+ throw new NullPointerException("Chunkholder cannot be null"); -+ } -+ if (this.chunkHolder != null) { -+ throw new IllegalStateException("Already have chunkholder: " + this.chunkHolder + ", cannot replace with " + chunkHolder); -+ } -+ this.chunkHolder = chunkHolder; -+ this.playerChunk = chunkHolder.vanillaChunkHolder; -+ } -+ -+ /* Note: We skip the light neighbour chunk loading done for the vanilla full chunk */ -+ /* Starlight does not need these chunks for lighting purposes because of edge checks */ -+ public void pushChunkIntoLoadedMap() { - int chunkX = this.chunkPos.x; - int chunkZ = this.chunkPos.z; - net.minecraft.server.level.ServerChunkCache chunkProvider = this.level.getChunkSource(); -@@ -707,10 +725,55 @@ public class LevelChunk extends ChunkAccess { - } - } - this.setNeighbourLoaded(0, 0, this); -+ this.level.getChunkSource().addLoadedChunk(this); -+ } -+ -+ public void onChunkLoad(io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder) { -+ // figure out how this should interface with: -+ // the entity chunk load event // -> moved to the FULL status -+ // the chunk load event // -> stays here -+ // any entity add to world events // -> in FULL status -+ this.loadCallback(); -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkBorder(this, chunkHolder.vanillaChunkHolder); -+ } -+ -+ public void onChunkUnload(io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder) { -+ // figure out how this should interface with: -+ // the entity chunk load event // -> moved to chunk unload to disk (not written yet) -+ // the chunk load event // -> stays here -+ // any entity add to world events // -> goes into the unload logic, it will completely explode -+ // etc later -+ this.unloadCallback(); -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkNotBorder(this, chunkHolder.vanillaChunkHolder); -+ } -+ -+ public void onChunkTicking(io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder) { -+ this.postProcessGeneration(); -+ this.level.startTickingChunk(this); -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkTicking(this, chunkHolder.vanillaChunkHolder); -+ } -+ -+ public void onChunkNotTicking(io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder) { -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkNotTicking(this, chunkHolder.vanillaChunkHolder); -+ } -+ -+ public void onChunkEntityTicking(io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder) { -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkEntityTicking(this, chunkHolder.vanillaChunkHolder); -+ } -+ -+ public void onChunkNotEntityTicking(io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder) { -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkNotEntityTicking(this, chunkHolder.vanillaChunkHolder); -+ } -+ // Paper end - new load callbacks -+ -+ // CraftBukkit start -+ public void loadCallback() { -+ if (this.loadedTicketLevel) { LOGGER.error("Double calling chunk load!", new Throwable()); } // Paper -+ // Paper - rewrite chunk system - move into separate callback - this.loadedTicketLevel = true; -- // Paper end - neighbour cache -+ // Paper - rewrite chunk system - move into separate callback - org.bukkit.Server server = this.level.getCraftServer(); -- this.level.getChunkSource().addLoadedChunk(this); // Paper -+ // Paper - rewrite chunk system - move into separate callback - if (server != null) { - /* - * If it's a new world, the first few chunks are generated inside -@@ -719,6 +782,7 @@ public class LevelChunk extends ChunkAccess { - */ - org.bukkit.Chunk bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); - server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(bukkitChunk, this.needsDecoration)); -+ this.chunkHolder.getEntityChunk().callEntitiesLoadEvent(); // Paper - rewrite chunk system - - if (this.needsDecoration) { - try (co.aikar.timings.Timing ignored = this.level.timings.chunkLoadPopulate.startTiming()) { // Paper -@@ -747,9 +811,11 @@ public class LevelChunk extends ChunkAccess { - } - - public void unloadCallback() { -+ if (!this.loadedTicketLevel) { LOGGER.error("Double calling chunk unload!", new Throwable()); } // Paper - org.bukkit.Server server = this.level.getCraftServer(); -+ this.chunkHolder.getEntityChunk().callEntitiesUnloadEvent(); // Paper - rewrite chunk system - org.bukkit.Chunk bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); -- org.bukkit.event.world.ChunkUnloadEvent unloadEvent = new org.bukkit.event.world.ChunkUnloadEvent(bukkitChunk, this.isUnsaved()); -+ org.bukkit.event.world.ChunkUnloadEvent unloadEvent = new org.bukkit.event.world.ChunkUnloadEvent(bukkitChunk, true); // Paper - rewrite chunk system - force save to true so that mustNotSave is correctly set below - server.getPluginManager().callEvent(unloadEvent); - // note: saving can be prevented, but not forced if no saving is actually required - this.mustNotSave = !unloadEvent.isSaveChunk(); -@@ -771,9 +837,26 @@ public class LevelChunk extends ChunkAccess { - // Paper end - } - -+ // Paper start - add dirty system to tick lists -+ @Override -+ public void setUnsaved(boolean needsSaving) { -+ if (!needsSaving) { -+ this.blockTicks.clearDirty(); -+ this.fluidTicks.clearDirty(); -+ } -+ super.setUnsaved(needsSaving); -+ } -+ // Paper end - add dirty system to tick lists -+ - @Override - public boolean isUnsaved() { -- return super.isUnsaved() && !this.mustNotSave; -+ // Paper start - add dirty system to tick lists -+ long gameTime = this.level.getLevelData().getGameTime(); -+ if (this.blockTicks.isDirty(gameTime) || this.fluidTicks.isDirty(gameTime)) { -+ return true; -+ } -+ // Paper end - add dirty system to tick lists -+ return super.isUnsaved(); // Paper - rewrite chunk system - do NOT clobber the dirty flag - } - // CraftBukkit end - -@@ -842,7 +925,9 @@ public class LevelChunk extends ChunkAccess { - return this.blockEntities; - } - -+ public boolean isPostProcessingDone; // Paper - replace chunk loader system - public void postProcessGeneration() { -+ try { // Paper - replace chunk loader system - ChunkPos chunkcoordintpair = this.getPos(); - - for (int i = 0; i < this.postProcessing.length; ++i) { -@@ -863,6 +948,7 @@ public class LevelChunk extends ChunkAccess { - BlockState iblockdata1 = Block.updateFromNeighbourShapes(iblockdata, this.level, blockposition); - - this.level.setBlock(blockposition, iblockdata1, 20); -+ if (iblockdata1 != iblockdata) this.level.chunkSource.blockChanged(blockposition); // Paper - replace player chunk loader - notify since we send before processing full updates - } - } - -@@ -880,6 +966,10 @@ public class LevelChunk extends ChunkAccess { - - this.pendingBlockEntities.clear(); - this.upgradeData.upgrade(this); -+ } finally { // Paper start - replace chunk loader system -+ this.isPostProcessingDone = true; -+ } -+ // Paper end - replace chunk loader system - } - - @Nullable -@@ -929,7 +1019,7 @@ public class LevelChunk extends ChunkAccess { - } - - public FullChunkStatus getFullStatus() { -- return this.fullStatus == null ? FullChunkStatus.FULL : (FullChunkStatus) this.fullStatus.get(); -+ return this.chunkHolder == null ? FullChunkStatus.INACCESSIBLE : this.chunkHolder.getChunkStatus(); // Paper - rewrite chunk system - } - - public void setFullStatus(Supplier levelTypeProvider) { -diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java -index 95318092f8281d98132d1d3ceb4a5c36cf32eb05..b81c548c0e1ac53784e9c94b34b65db5f123309c 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java -+++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatus.java -@@ -21,13 +21,15 @@ import net.minecraft.world.level.chunk.ProtoChunk; - import net.minecraft.world.level.levelgen.Heightmap; - - public class ChunkStatus { -+ static final ChunkStatus.LoadingTask PASSTHROUGH_LOAD_TASK = (WorldGenContext context, ChunkStatus status, ToFullChunk fullChunkConverter, ChunkAccess chunk) -> CompletableFuture.completedFuture(chunk); // Paper - rewrite chunk system -+ protected static final java.util.List statuses = new java.util.ArrayList<>(); // Paper - rewrite chunk system - public static final int MAX_STRUCTURE_DISTANCE = 8; - private static final EnumSet PRE_FEATURES = EnumSet.of(Heightmap.Types.OCEAN_FLOOR_WG, Heightmap.Types.WORLD_SURFACE_WG); - public static final EnumSet POST_FEATURES = EnumSet.of( - Heightmap.Types.OCEAN_FLOOR, Heightmap.Types.WORLD_SURFACE, Heightmap.Types.MOTION_BLOCKING, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES - ); - public static final ChunkStatus EMPTY = register( -- "empty", null, -1, false, PRE_FEATURES, ChunkType.PROTOCHUNK, ChunkStatusTasks::generateEmpty, ChunkStatusTasks::loadPassThrough -+ "empty", null, -1, false, PRE_FEATURES, ChunkType.PROTOCHUNK, ChunkStatusTasks::generateEmpty, PASSTHROUGH_LOAD_TASK // Paper - rewrite chunk system - ); - public static final ChunkStatus STRUCTURE_STARTS = register( - "structure_starts", -@@ -47,22 +49,22 @@ public class ChunkStatus { - PRE_FEATURES, - ChunkType.PROTOCHUNK, - ChunkStatusTasks::generateStructureReferences, -- ChunkStatusTasks::loadPassThrough -+ PASSTHROUGH_LOAD_TASK // Paper - rewrite chunk system - ); - public static final ChunkStatus BIOMES = register( -- "biomes", STRUCTURE_REFERENCES, 8, false, PRE_FEATURES, ChunkType.PROTOCHUNK, ChunkStatusTasks::generateBiomes, ChunkStatusTasks::loadPassThrough -+ "biomes", STRUCTURE_REFERENCES, 8, false, PRE_FEATURES, ChunkType.PROTOCHUNK, ChunkStatusTasks::generateBiomes, PASSTHROUGH_LOAD_TASK // Paper - rewrite chunk system - ); - public static final ChunkStatus NOISE = register( -- "noise", BIOMES, 8, false, PRE_FEATURES, ChunkType.PROTOCHUNK, ChunkStatusTasks::generateNoise, ChunkStatusTasks::loadPassThrough -+ "noise", BIOMES, 8, false, PRE_FEATURES, ChunkType.PROTOCHUNK, ChunkStatusTasks::generateNoise, PASSTHROUGH_LOAD_TASK // Paper - rewrite chunk system - ); - public static final ChunkStatus SURFACE = register( -- "surface", NOISE, 8, false, PRE_FEATURES, ChunkType.PROTOCHUNK, ChunkStatusTasks::generateSurface, ChunkStatusTasks::loadPassThrough -+ "surface", NOISE, 8, false, PRE_FEATURES, ChunkType.PROTOCHUNK, ChunkStatusTasks::generateSurface, PASSTHROUGH_LOAD_TASK // Paper - rewrite chunk system - ); - public static final ChunkStatus CARVERS = register( -- "carvers", SURFACE, 8, false, POST_FEATURES, ChunkType.PROTOCHUNK, ChunkStatusTasks::generateCarvers, ChunkStatusTasks::loadPassThrough -+ "carvers", SURFACE, 8, false, POST_FEATURES, ChunkType.PROTOCHUNK, ChunkStatusTasks::generateCarvers, PASSTHROUGH_LOAD_TASK // Paper - rewrite chunk system - ); - public static final ChunkStatus FEATURES = register( -- "features", CARVERS, 8, false, POST_FEATURES, ChunkType.PROTOCHUNK, ChunkStatusTasks::generateFeatures, ChunkStatusTasks::loadPassThrough -+ "features", CARVERS, 8, false, POST_FEATURES, ChunkType.PROTOCHUNK, ChunkStatusTasks::generateFeatures, PASSTHROUGH_LOAD_TASK // Paper - rewrite chunk system - ); - public static final ChunkStatus INITIALIZE_LIGHT = register( - "initialize_light", -@@ -78,7 +80,7 @@ public class ChunkStatus { - "light", INITIALIZE_LIGHT, 1, true, POST_FEATURES, ChunkType.PROTOCHUNK, ChunkStatusTasks::generateLight, ChunkStatusTasks::loadLight - ); - public static final ChunkStatus SPAWN = register( -- "spawn", LIGHT, 1, false, POST_FEATURES, ChunkType.PROTOCHUNK, ChunkStatusTasks::generateSpawn, ChunkStatusTasks::loadPassThrough -+ "spawn", LIGHT, 1, false, POST_FEATURES, ChunkType.PROTOCHUNK, ChunkStatusTasks::generateSpawn, PASSTHROUGH_LOAD_TASK // Paper - rewrite chunk system - ); - public static final ChunkStatus FULL = register( - "full", SPAWN, 0, false, POST_FEATURES, ChunkType.LEVELCHUNK, ChunkStatusTasks::generateFull, ChunkStatusTasks::loadFull -@@ -128,6 +130,27 @@ public class ChunkStatus { - } - } - // Paper end - starlight -+ // Paper start - rewrite chunk system -+ public boolean isParallelCapable; // Paper -+ public int writeRadius = -1; -+ public int loadRange = 0; -+ -+ private ChunkStatus nextStatus; -+ -+ public final ChunkStatus getNextStatus() { -+ return this.nextStatus; -+ } -+ -+ public final boolean isEmptyLoadStatus() { -+ return this.loadingTask == PASSTHROUGH_LOAD_TASK; -+ } -+ -+ public final boolean isEmptyGenStatus() { -+ return this == ChunkStatus.EMPTY; -+ } -+ -+ public final java.util.concurrent.atomic.AtomicBoolean warnedAboutNoImmediateComplete = new java.util.concurrent.atomic.AtomicBoolean(); -+ // Paper end - rewrite chunk system - - private static ChunkStatus register( - String id, -@@ -190,6 +213,13 @@ public class ChunkStatus { - this.chunkType = chunkType; - this.heightmapsAfter = heightMapTypes; - this.index = previous == null ? 0 : previous.getIndex() + 1; -+ // Paper start -+ this.nextStatus = this; -+ if (statuses.size() > 0) { -+ statuses.get(statuses.size() - 1).nextStatus = this; -+ } -+ statuses.add(this); -+ // Paper end - } - - public int getIndex() { -diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -index ce7f154b9dad4e78ee0189405cf57dcb3d5301b8..a5e8078b99161272b0f826b8c39e56d17588c264 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -+++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -@@ -26,8 +26,9 @@ public class ChunkStatusTasks { - return CompletableFuture.completedFuture(chunk); - } - -- static CompletableFuture loadPassThrough(WorldGenContext context, ChunkStatus status, ToFullChunk fullChunkConverter, ChunkAccess chunk) { -- return CompletableFuture.completedFuture(chunk); -+ @io.papermc.paper.annotation.DoNotUse @Deprecated(forRemoval = true) // Paper - rewrite chunk system - use ChunkStatus.PASSTHROUGH_LOAD_TASK instead -+ static CompletableFuture loadPassThrough(WorldGenContext context, ChunkStatus status, ToFullChunk fullChunkConverter, ChunkAccess chunk) { // Paper - rewrite chunk system - diff on change -+ return CompletableFuture.completedFuture(chunk); // Paper - rewrite chunk system - diff on change - } - - static CompletableFuture generateStructureStarts(WorldGenContext context, ChunkStatus status, Executor executor, ToFullChunk fullChunkConverter, List chunks, ChunkAccess chunk) { -@@ -125,7 +126,7 @@ public class ChunkStatusTasks { - ((ProtoChunk) chunk).setLightEngine(lightingProvider); - boolean flag = ChunkStatusTasks.isLighted(chunk); - -- return lightingProvider.initializeLight(chunk, flag); -+ return CompletableFuture.completedFuture(chunk); // Paper - rewrite chunk system - } - - static CompletableFuture generateLight(WorldGenContext context, ChunkStatus status, Executor executor, ToFullChunk fullChunkConverter, List chunks, ChunkAccess chunk) { -@@ -139,7 +140,7 @@ public class ChunkStatusTasks { - private static CompletableFuture lightChunk(ThreadedLevelLightEngine lightingProvider, ChunkAccess chunk) { - boolean flag = ChunkStatusTasks.isLighted(chunk); - -- return lightingProvider.lightChunk(chunk, flag); -+ return CompletableFuture.completedFuture(chunk); // Paper - rewrite chunk system - } - - static CompletableFuture generateSpawn(WorldGenContext context, ChunkStatus status, Executor executor, ToFullChunk fullChunkConverter, List chunks, ChunkAccess chunk) { -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index 01d6b8683a9fa30d05b03ebfef8ee2dca4e83a56..5f85d8d82212f9a8133304dc05bf2cd39da1f9e7 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -@@ -112,7 +112,25 @@ public class ChunkSerializer { - } - } - // Paper end - guard against serializing mismatching coordinates -+ // Paper start - rewrite chunk system -+ public static final class InProgressChunkHolder { -+ -+ public final ProtoChunk protoChunk; -+ -+ public CompoundTag poiData; -+ -+ public InProgressChunkHolder(final ProtoChunk protoChunk) { -+ this.protoChunk = protoChunk; -+ } -+ } - public static ProtoChunk read(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt) { -+ // Paper start - rewrite chunk system -+ InProgressChunkHolder holder = readInProgressChunkHolder(world, poiStorage, chunkPos, nbt); -+ return holder.protoChunk; -+ } -+ -+ public static InProgressChunkHolder readInProgressChunkHolder(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt) { -+ // Paper end - rewrite chunk system - // Paper start - Do not let the server load chunks from newer versions - if (nbt.contains("DataVersion", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC)) { - final int dataVersion = nbt.getInt("DataVersion"); -@@ -178,7 +196,7 @@ public class ChunkSerializer { - achunksection[k] = chunksection; - SectionPos sectionposition = SectionPos.of(chunkPos, b0); - -- poiStorage.checkConsistencyWithBlocks(sectionposition, chunksection); -+ // Paper - rewrite chunk system - moved to final load stage - } - - boolean flag3 = nbttagcompound1.contains("BlockLight", 7); -@@ -325,7 +343,7 @@ public class ChunkSerializer { - } - - if (chunktype == ChunkType.LEVELCHUNK) { -- return new ImposterProtoChunk((LevelChunk) object1, false); -+ return new InProgressChunkHolder(new ImposterProtoChunk((LevelChunk) object1, false)); // Paper - Async chunk loading - } else { - ProtoChunk protochunk1 = (ProtoChunk) object1; - -@@ -360,9 +378,41 @@ public class ChunkSerializer { - protochunk1.setCarvingMask(worldgenstage_features, new CarvingMask(nbttagcompound5.getLongArray(s1), ((ChunkAccess) object1).getMinBuildHeight())); - } - -- return protochunk1; -+ return new InProgressChunkHolder(protochunk1); // Paper - Async chunk loading -+ } -+ } -+ -+ // Paper start - async chunk save for unload -+ public record AsyncSaveData( -+ Tag blockTickList, // non-null if we had to go to the server's tick list -+ Tag fluidTickList, // non-null if we had to go to the server's tick list -+ ListTag blockEntities, -+ long worldTime -+ ) {} -+ -+ // must be called sync -+ public static AsyncSaveData getAsyncSaveData(ServerLevel world, ChunkAccess chunk) { -+ org.spigotmc.AsyncCatcher.catchOp("preparation of chunk data for async save"); -+ -+ final CompoundTag tickLists = new CompoundTag(); -+ ChunkSerializer.saveTicks(world, tickLists, chunk.getTicksForSerialization()); -+ -+ ListTag blockEntitiesSerialized = new ListTag(); -+ for (final BlockPos blockPos : chunk.getBlockEntitiesPos()) { -+ final CompoundTag blockEntityNbt = chunk.getBlockEntityNbtForSaving(blockPos, world.registryAccess()); -+ if (blockEntityNbt != null) { -+ blockEntitiesSerialized.add(blockEntityNbt); -+ } - } -+ -+ return new AsyncSaveData( -+ tickLists.get(BLOCK_TICKS_TAG), -+ tickLists.get(FLUID_TICKS_TAG), -+ blockEntitiesSerialized, -+ world.getGameTime() -+ ); - } -+ // Paper end - - private static void logErrors(ChunkPos chunkPos, int y, String message) { - ChunkSerializer.LOGGER.error("Recoverable errors when loading section [" + chunkPos.x + ", " + y + ", " + chunkPos.z + "]: " + message); -@@ -379,6 +429,11 @@ public class ChunkSerializer { - // CraftBukkit end - - public static CompoundTag write(ServerLevel world, ChunkAccess chunk) { -+ // Paper start -+ return saveChunk(world, chunk, null); -+ } -+ public static CompoundTag saveChunk(ServerLevel world, ChunkAccess chunk, @org.checkerframework.checker.nullness.qual.Nullable AsyncSaveData asyncsavedata) { -+ // Paper end - // Paper start - rewrite light impl - final int minSection = io.papermc.paper.util.WorldUtil.getMinLightSection(world); - final int maxSection = io.papermc.paper.util.WorldUtil.getMaxLightSection(world); -@@ -391,7 +446,7 @@ public class ChunkSerializer { - nbttagcompound.putInt("xPos", chunkcoordintpair.x); - nbttagcompound.putInt("yPos", chunk.getMinSection()); - nbttagcompound.putInt("zPos", chunkcoordintpair.z); -- nbttagcompound.putLong("LastUpdate", world.getGameTime()); -+ nbttagcompound.putLong("LastUpdate", asyncsavedata != null ? asyncsavedata.worldTime : world.getGameTime()); // Paper - async chunk unloading - nbttagcompound.putLong("InhabitedTime", chunk.getInhabitedTime()); - nbttagcompound.putString("Status", BuiltInRegistries.CHUNK_STATUS.getKey(chunk.getStatus()).toString()); - BlendingData blendingdata = chunk.getBlendingData(); -@@ -485,8 +540,17 @@ public class ChunkSerializer { - nbttagcompound.putBoolean("isLightOn", false); // Paper - set to false but still store, this allows us to detect --eraseCache (as eraseCache _removes_) - } - -- ListTag nbttaglist1 = new ListTag(); -- Iterator iterator = chunk.getBlockEntitiesPos().iterator(); -+ // Paper start -+ ListTag nbttaglist1; -+ Iterator iterator; -+ if (asyncsavedata != null) { -+ nbttaglist1 = asyncsavedata.blockEntities; -+ iterator = java.util.Collections.emptyIterator(); -+ } else { -+ nbttaglist1 = new ListTag(); -+ iterator = chunk.getBlockEntitiesPos().iterator(); -+ } -+ // Paper end - - CompoundTag nbttagcompound2; - -@@ -522,7 +586,14 @@ public class ChunkSerializer { - nbttagcompound.put("CarvingMasks", nbttagcompound2); - } - -+ // Paper start -+ if (asyncsavedata != null) { -+ nbttagcompound.put(BLOCK_TICKS_TAG, asyncsavedata.blockTickList); -+ nbttagcompound.put(FLUID_TICKS_TAG, asyncsavedata.fluidTickList); -+ } else { - ChunkSerializer.saveTicks(world, nbttagcompound, chunk.getTicksForSerialization()); -+ } -+ // Paper end - nbttagcompound.put("PostProcessing", ChunkSerializer.packOffsets(chunk.getPostProcessing())); - CompoundTag nbttagcompound3 = new CompoundTag(); - Iterator iterator1 = chunk.getHeightmaps().iterator(); -@@ -578,7 +649,7 @@ public class ChunkSerializer { - - return nbttaglist == null && nbttaglist1 == null ? null : (chunk) -> { - if (nbttaglist != null) { -- world.addLegacyChunkEntities(EntityType.loadEntitiesRecursive(nbttaglist, world)); -+ world.addLegacyChunkEntities(EntityType.loadEntitiesRecursive(nbttaglist, world), chunk.getPos()); // Paper - rewrite chunk system - } - - if (nbttaglist1 != null) { -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -index a62c90e10c0dfa4c6211a05c4071932756d7b218..554dede2ad0e45d3ee4ccc5510b7644f2e9e4250 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -@@ -31,18 +31,21 @@ import net.minecraft.world.level.storage.DimensionDataStorage; - public class ChunkStorage implements AutoCloseable { - - public static final int LAST_MONOLYTH_STRUCTURE_DATA_VERSION = 1493; -- private final IOWorker worker; -+ // Paper start - rewrite chunk system; async chunk IO -+ private final Object persistentDataLock = new Object(); -+ public final RegionFileStorage regionFileCache; -+ // Paper end - rewrite chunk system - protected final DataFixer fixerUpper; - @Nullable - private volatile LegacyStructureDataHandler legacyStructureHandler; - - public ChunkStorage(RegionStorageInfo storageKey, Path directory, DataFixer dataFixer, boolean dsync) { - this.fixerUpper = dataFixer; -- this.worker = new IOWorker(storageKey, directory, dsync); -+ this.regionFileCache = new RegionFileStorage(storageKey, directory, dsync); // Paper - rewrite chunk system; async chunk IO - } - - public boolean isOldChunkAround(ChunkPos chunkPos, int checkRadius) { -- return this.worker.isOldChunkAround(chunkPos, checkRadius); -+ return true; // Paper - rewrite chunk system - } - - // CraftBukkit start -@@ -50,8 +53,9 @@ public class ChunkStorage implements AutoCloseable { - if (true) return true; // Paper - Perf: this isn't even needed anymore, light is purged updating to 1.14+, why are we holding up the conversion process reading chunk data off disk - return true, we need to set light populated to true so the converter recognizes the chunk as being "full" - ChunkPos pos = new ChunkPos(x, z); - if (cps != null) { -- com.google.common.base.Preconditions.checkState(org.bukkit.Bukkit.isPrimaryThread(), "primary thread"); -- if (cps.hasChunk(x, z)) { -+ // Paper start - rewrite chunk system; async chunk IO -+ if (cps.getChunkAtIfCachedImmediately(x, z) != null) { // isLoaded is a ticket level check, not a chunk loaded check! -+ // Paper end - rewrite chunk system - return true; - } - } -@@ -79,6 +83,7 @@ public class ChunkStorage implements AutoCloseable { - - public CompoundTag upgradeChunkTag(ResourceKey resourcekey, Supplier supplier, CompoundTag nbttagcompound, Optional>> optional, ChunkPos pos, @Nullable LevelAccessor generatoraccess) { - // CraftBukkit end -+ nbttagcompound = nbttagcompound.copy(); // Paper - defensive copy, another thread might modify this - int i = ChunkStorage.getVersion(nbttagcompound); - - try { -@@ -97,9 +102,11 @@ public class ChunkStorage implements AutoCloseable { - if (i < 1493) { - ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.CHUNK, nbttagcompound, i, 1493); // Paper - replace chunk converter - if (nbttagcompound.getCompound("Level").getBoolean("hasLegacyStructureData")) { -+ synchronized (this.persistentDataLock) { // Paper - Async chunk loading - LegacyStructureDataHandler persistentstructurelegacy = this.getLegacyStructureHandler(resourcekey, supplier); - - nbttagcompound = persistentstructurelegacy.updateFromLegacy(nbttagcompound); -+ } // Paper - Async chunk loading - } - } - -@@ -139,7 +146,7 @@ public class ChunkStorage implements AutoCloseable { - LegacyStructureDataHandler persistentstructurelegacy = this.legacyStructureHandler; - - if (persistentstructurelegacy == null) { -- synchronized (this) { -+ synchronized (this.persistentDataLock) { // Paper - async chunk loading - persistentstructurelegacy = this.legacyStructureHandler; - if (persistentstructurelegacy == null) { - this.legacyStructureHandler = persistentstructurelegacy = LegacyStructureDataHandler.getLegacyStructureHandler(worldKey, (DimensionDataStorage) stateManagerGetter.get()); -@@ -165,10 +172,20 @@ public class ChunkStorage implements AutoCloseable { - } - - public CompletableFuture> read(ChunkPos chunkPos) { -- return this.worker.loadAsync(chunkPos); -+ // Paper start - async chunk io -+ try { -+ return CompletableFuture.completedFuture(Optional.ofNullable(this.readSync(chunkPos))); -+ } catch (Throwable thr) { -+ return CompletableFuture.failedFuture(thr); -+ } -+ } -+ @Nullable -+ public CompoundTag readSync(ChunkPos chunkPos) throws IOException { -+ return this.regionFileCache.read(chunkPos); - } -+ // Paper end - async chunk io - -- public CompletableFuture write(ChunkPos chunkPos, CompoundTag nbt) { -+ public CompletableFuture write(ChunkPos chunkPos, CompoundTag nbt) throws IOException { // Paper - rewrite chunk system; async chunk io - // Paper start - guard against serializing mismatching coordinates - if (nbt != null && !chunkPos.equals(ChunkSerializer.getChunkCoordinate(nbt))) { - final String world = (this instanceof net.minecraft.server.level.ChunkMap) ? ((net.minecraft.server.level.ChunkMap) this).level.getWorld().getName() : null; -@@ -176,26 +193,39 @@ public class ChunkStorage implements AutoCloseable { - + " but compound says coordinate is " + ChunkSerializer.getChunkCoordinate(nbt) + (world == null ? " for an unknown world" : (" for world: " + world))); - } - // Paper end - guard against serializing mismatching coordinates -+ this.regionFileCache.write(chunkPos, nbt); // Paper - rewrite chunk system; async chunk io, move above legacy structure index - this.handleLegacyStructureIndex(chunkPos); -- return this.worker.store(chunkPos, nbt); -+ // Paper - rewrite chunk system; async chunk io, move above legacy structure index -+ return null; - } - - protected void handleLegacyStructureIndex(ChunkPos chunkPos) { - if (this.legacyStructureHandler != null) { -+ synchronized (this.persistentDataLock) { // Paper - rewrite chunk system; async chunk io - this.legacyStructureHandler.removeIndex(chunkPos.toLong()); -+ } // Paper - rewrite chunk system; async chunk io - } - - } - - public void flushWorker() { -- this.worker.synchronize(true).join(); -+ io.papermc.paper.chunk.system.io.RegionFileIOThread.flush(); // Paper - rewrite chunk system - } - - public void close() throws IOException { -- this.worker.close(); -+ this.regionFileCache.close(); // Paper - nuke IO worker - } - - public ChunkScanAccess chunkScanner() { -- return this.worker; -+ // Paper start - nuke IO worker -+ return ((chunkPos, streamTagVisitor) -> { -+ try { -+ this.regionFileCache.scanChunk(chunkPos, streamTagVisitor); -+ return java.util.concurrent.CompletableFuture.completedFuture(null); -+ } catch (IOException e) { -+ throw new RuntimeException(e); -+ } -+ }); -+ // Paper end - } - } -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java -index 49d8a62d2b6ca6da4e02b3cec7e42c38b7781b57..9fdf8f857a5f9b231c6d0633eaba498244214f74 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java -@@ -27,43 +27,30 @@ public class EntityStorage implements EntityPersistentStorage { - private static final String ENTITIES_TAG = "Entities"; - private static final String POSITION_TAG = "Position"; - public final ServerLevel level; -- private final SimpleRegionStorage simpleRegionStorage; -+ // Paper - rewrite chunk system - private final LongSet emptyChunks = new LongOpenHashSet(); -- public final ProcessorMailbox entityDeserializerQueue; -+ // Paper - rewrite chunk system - - public EntityStorage(SimpleRegionStorage storage, ServerLevel world, Executor executor) { -- this.simpleRegionStorage = storage; -+ // Paper - rewrite chunk system - this.level = world; -- this.entityDeserializerQueue = ProcessorMailbox.create(executor, "entity-deserializer"); -+ // Paper - rewrite chunk system - } - - @Override - public CompletableFuture> loadEntities(ChunkPos pos) { -- return this.emptyChunks.contains(pos.toLong()) -- ? CompletableFuture.completedFuture(emptyChunk(pos)) -- : this.simpleRegionStorage.read(pos).thenApplyAsync(nbt -> { -- if (nbt.isEmpty()) { -- this.emptyChunks.add(pos.toLong()); -- return emptyChunk(pos); -- } else { -- try { -- ChunkPos chunkPos2 = readChunkPos(nbt.get()); -- if (!Objects.equals(pos, chunkPos2)) { -- LOGGER.error("Chunk file at {} is in the wrong location. (Expected {}, got {})", pos, pos, chunkPos2); -- } -- } catch (Exception var6) { -- LOGGER.warn("Failed to parse chunk {} position info", pos, var6); -- } -- -- CompoundTag compoundTag = this.simpleRegionStorage.upgradeChunkTag(nbt.get(), -1); -- ListTag listTag = compoundTag.getList("Entities", 10); -- List list = EntityType.loadEntitiesRecursive(listTag, this.level).collect(ImmutableList.toImmutableList()); -- return new ChunkEntities<>(pos, list); -- } -- }, this.entityDeserializerQueue::tell); -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - copy out read logic into readEntities - } - -- private static ChunkPos readChunkPos(CompoundTag chunkNbt) { -+ // Paper start - rewrite chunk system -+ public static List readEntities(ServerLevel level, CompoundTag compoundTag) { -+ ListTag listTag = compoundTag.getList("Entities", 10); -+ List list = EntityType.loadEntitiesRecursive(listTag, level).collect(ImmutableList.toImmutableList()); -+ return list; -+ } -+ // Paper end - rewrite chunk system -+ -+ public static ChunkPos readChunkPos(CompoundTag chunkNbt) { // Paper - public - int[] is = chunkNbt.getIntArray("Position"); - return new ChunkPos(is[0], is[1]); - } -@@ -78,38 +65,74 @@ public class EntityStorage implements EntityPersistentStorage { - - @Override - public void storeEntities(ChunkEntities dataList) { -+ // Paper start - rewrite chunk system -+ if (true) { -+ throw new UnsupportedOperationException(); -+ } -+ // Paper end - rewrite chunk system - ChunkPos chunkPos = dataList.getPos(); - if (dataList.isEmpty()) { - if (this.emptyChunks.add(chunkPos.toLong())) { -- this.simpleRegionStorage.write(chunkPos, null); -+ // Paper - rewrite chunk system - fix compile for unused field in dead code - } - } else { -- ListTag listTag = new ListTag(); -- dataList.getEntities().forEach(entity -> { -- CompoundTag compoundTagx = new CompoundTag(); -- if (entity.save(compoundTagx)) { -- listTag.add(compoundTagx); -- } -- }); -- CompoundTag compoundTag = NbtUtils.addCurrentDataVersion(new CompoundTag()); -- compoundTag.put("Entities", listTag); -- writeChunkPos(compoundTag, chunkPos); -- this.simpleRegionStorage.write(chunkPos, compoundTag).exceptionally(ex -> { -- LOGGER.error("Failed to store chunk {}", chunkPos, ex); -- return null; -- }); -+ // Paper - move into saveEntityChunk0 - this.emptyChunks.remove(chunkPos.toLong()); - } - } - -+ // Paper start - rewrite chunk system -+ public static void copyEntities(final CompoundTag from, final CompoundTag into) { -+ if (from == null) { -+ return; -+ } -+ final ListTag entitiesFrom = from.getList("Entities", net.minecraft.nbt.Tag.TAG_COMPOUND); -+ if (entitiesFrom == null || entitiesFrom.isEmpty()) { -+ return; -+ } -+ -+ final ListTag entitiesInto = into.getList("Entities", net.minecraft.nbt.Tag.TAG_COMPOUND); -+ into.put("Entities", entitiesInto); // this is in case into doesn't have any entities -+ entitiesInto.addAll(0, entitiesFrom.copy()); // need to copy, this is coming from the save thread -+ } -+ -+ public static CompoundTag saveEntityChunk(List entities, ChunkPos chunkPos, ServerLevel level) { -+ return saveEntityChunk0(entities, chunkPos, level, false); -+ } -+ private static CompoundTag saveEntityChunk0(List entities, ChunkPos chunkPos, ServerLevel level, boolean force) { -+ if (!force && entities.isEmpty()) { -+ return null; -+ } -+ -+ ListTag listTag = new ListTag(); -+ entities.forEach((entity) -> { // diff here: use entities parameter -+ CompoundTag compoundTag = new CompoundTag(); -+ if (entity.save(compoundTag)) { -+ listTag.add(compoundTag); -+ } -+ -+ }); -+ CompoundTag compoundTag = NbtUtils.addCurrentDataVersion(new CompoundTag()); -+ compoundTag.put("Entities", listTag); -+ writeChunkPos(compoundTag, chunkPos); -+ // Paper - remove worker usage -+ -+ return !force && listTag.isEmpty() ? null : compoundTag; -+ } -+ -+ public static CompoundTag upgradeChunkTag(CompoundTag chunkNbt) { -+ int i = NbtUtils.getDataVersion(chunkNbt, -1); -+ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ENTITY_CHUNK, chunkNbt, i, net.minecraft.SharedConstants.getCurrentVersion().getDataVersion().getVersion()); -+ } -+ // Paper end - rewrite chunk system -+ - @Override - public void flush(boolean sync) { -- this.simpleRegionStorage.synchronize(sync).join(); -- this.entityDeserializerQueue.runAll(); -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - - @Override - public void close() throws IOException { -- this.simpleRegionStorage.close(); -+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system - } - } -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 e858436bcf1b234d4bc6e6a117f5224d5c2d9f90..307196b2a58d4f8db3e6e3c3517a8004d4908b13 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 -@@ -48,6 +48,7 @@ public class RegionFile implements AutoCloseable { - private final IntBuffer timestamps; - @VisibleForTesting - protected final RegionBitmap usedSectors; -+ public final java.util.concurrent.locks.ReentrantLock fileLock = new java.util.concurrent.locks.ReentrantLock(); // Paper - - public RegionFile(RegionStorageInfo storageKey, Path directory, Path path, boolean dsync) throws IOException { - this(storageKey, directory, path, RegionFileVersion.getCompressionFormat(), dsync); // Paper - Configurable region compression format -@@ -250,7 +251,7 @@ public class RegionFile implements AutoCloseable { - return (byteCount + 4096 - 1) / 4096; - } - -- public boolean doesChunkExist(ChunkPos pos) { -+ public synchronized boolean doesChunkExist(ChunkPos pos) { // Paper - synchronized - int i = this.getOffset(pos); - - if (i == 0) { -@@ -417,6 +418,11 @@ public class RegionFile implements AutoCloseable { - } - - public void close() throws IOException { -+ // Paper start - Prevent regionfiles from being closed during use -+ this.fileLock.lock(); -+ synchronized (this) { -+ try { -+ // Paper end - try { - this.padToFullSector(); - } finally { -@@ -426,6 +432,10 @@ public class RegionFile implements AutoCloseable { - this.file.close(); - } - } -+ } finally { // Paper start - Prevent regionfiles from being closed during use -+ this.fileLock.unlock(); -+ } -+ } // Paper end - - } - -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 c4eef3aade889c69cefd873bec2d031cc54103ea..3f6955be976064eb542b5c50a9d6d74457c1833c 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,31 +26,99 @@ public class RegionFileStorage implements AutoCloseable { - private final Path folder; - private final boolean sync; - -- RegionFileStorage(RegionStorageInfo storageKey, Path directory, boolean dsync) { -+ // Paper start - cache regionfile does not exist state -+ static final int MAX_NON_EXISTING_CACHE = 1024 * 64; -+ private final it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet nonExistingRegionFiles = new it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet(); -+ private synchronized boolean doesRegionFilePossiblyExist(long position) { -+ if (this.nonExistingRegionFiles.contains(position)) { -+ this.nonExistingRegionFiles.addAndMoveToFirst(position); -+ return false; -+ } -+ return true; -+ } -+ -+ private synchronized void createRegionFile(long position) { -+ this.nonExistingRegionFiles.remove(position); -+ } -+ -+ private synchronized void markNonExisting(long position) { -+ if (this.nonExistingRegionFiles.addAndMoveToFirst(position)) { -+ while (this.nonExistingRegionFiles.size() >= MAX_NON_EXISTING_CACHE) { -+ this.nonExistingRegionFiles.removeLastLong(); -+ } -+ } -+ } -+ -+ public synchronized boolean doesRegionFileNotExistNoIO(ChunkPos pos) { -+ long key = ChunkPos.asLong(pos.getRegionX(), pos.getRegionZ()); -+ return !this.doesRegionFilePossiblyExist(key); -+ } -+ // Paper end - cache regionfile does not exist state -+ -+ protected RegionFileStorage(RegionStorageInfo storageKey, Path directory, boolean dsync) { // Paper - protected constructor - this.folder = directory; - this.sync = dsync; - this.info = storageKey; - } - -- private RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit -- long i = ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ()); -+ // Paper start -+ public synchronized RegionFile getRegionFileIfLoaded(ChunkPos chunkcoordintpair) { -+ return this.regionCache.getAndMoveToFirst(ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ())); -+ } -+ -+ public synchronized boolean chunkExists(ChunkPos pos) throws IOException { -+ RegionFile regionfile = getRegionFile(pos, true); -+ -+ return regionfile != null ? regionfile.hasChunk(pos) : false; -+ } -+ -+ public synchronized RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit -+ return this.getRegionFile(chunkcoordintpair, existingOnly, false); -+ } -+ public synchronized RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly, boolean lock) throws IOException { -+ // Paper end -+ long i = ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ()); final long regionPos = i; // Paper - OBFHELPER - RegionFile regionfile = (RegionFile) this.regionCache.getAndMoveToFirst(i); - - if (regionfile != null) { -+ // Paper start -+ if (lock) { -+ // must be in this synchronized block -+ regionfile.fileLock.lock(); -+ } -+ // Paper end - return regionfile; - } else { -+ // Paper start - cache regionfile does not exist state -+ if (existingOnly && !this.doesRegionFilePossiblyExist(regionPos)) { -+ return null; -+ } -+ // Paper end - cache regionfile does not exist state - if (this.regionCache.size() >= io.papermc.paper.configuration.GlobalConfiguration.get().misc.regionFileCacheSize) { // Paper - Sanitise RegionFileCache and make configurable - ((RegionFile) this.regionCache.removeLast()).close(); - } - -- FileUtil.createDirectoriesSafe(this.folder); -+ // Paper - only create directory if not existing only - moved down - Path path = this.folder; - int j = chunkcoordintpair.getRegionX(); - Path path1 = path.resolve("r." + j + "." + chunkcoordintpair.getRegionZ() + ".mca"); -- if (existingOnly && !java.nio.file.Files.exists(path1)) return null; // CraftBukkit -+ if (existingOnly && !java.nio.file.Files.exists(path1)) { // Paper start - cache regionfile does not exist state -+ this.markNonExisting(regionPos); -+ return null; // CraftBukkit -+ } else { -+ this.createRegionFile(regionPos); -+ } -+ // Paper end - cache regionfile does not exist state -+ FileUtil.createDirectoriesSafe(this.folder); // Paper - only create directory if not existing only - moved from above - RegionFile regionfile1 = new RegionFile(this.info, path1, this.folder, this.sync); - - this.regionCache.putAndMoveToFirst(i, regionfile1); -+ // Paper start -+ if (lock) { -+ // must be in this synchronized block -+ regionfile1.fileLock.lock(); -+ } -+ // Paper end - return regionfile1; - } - } -@@ -58,11 +126,12 @@ public class RegionFileStorage implements AutoCloseable { - @Nullable - public CompoundTag read(ChunkPos pos) throws IOException { - // CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing -- RegionFile regionfile = this.getRegionFile(pos, true); -+ RegionFile regionfile = this.getRegionFile(pos, true, true); // Paper - if (regionfile == null) { - return null; - } - // CraftBukkit end -+ try { // Paper - DataInputStream datainputstream = regionfile.getChunkDataInputStream(pos); - - CompoundTag nbttagcompound; -@@ -99,6 +168,9 @@ public class RegionFileStorage implements AutoCloseable { - } - - return nbttagcompound; -+ } finally { // Paper start -+ regionfile.fileLock.unlock(); -+ } // Paper end - } - - public void scanChunk(ChunkPos chunkPos, StreamTagVisitor scanner) throws IOException { -@@ -133,7 +205,13 @@ public class RegionFileStorage implements AutoCloseable { - } - - protected void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException { -- RegionFile regionfile = this.getRegionFile(pos, false); // CraftBukkit -+ // Paper start - rewrite chunk system -+ RegionFile regionfile = this.getRegionFile(pos, nbt == null, true); // CraftBukkit -+ if (nbt == null && regionfile == null) { -+ return; -+ } -+ try { // Try finally to unlock the region file -+ // Paper end - rewrite chunk system - // Paper start - Chunk save reattempt - int attempts = 0; - Exception lastException = null; -@@ -179,9 +257,14 @@ public class RegionFileStorage implements AutoCloseable { - net.minecraft.server.MinecraftServer.LOGGER.error("Failed to save chunk {}", pos, lastException); - } - // Paper end - Chunk save reattempt -+ // Paper start - rewrite chunk system -+ } finally { -+ regionfile.fileLock.unlock(); -+ } -+ // Paper end - rewrite chunk system - } - -- public void close() throws IOException { -+ public synchronized void close() throws IOException { // Paper -> synchronized - ExceptionCollector exceptionsuppressor = new ExceptionCollector<>(); - ObjectIterator objectiterator = this.regionCache.values().iterator(); - -@@ -198,7 +281,7 @@ public class RegionFileStorage implements AutoCloseable { - exceptionsuppressor.throwIfPresent(); - } - -- public void flush() throws IOException { -+ public synchronized void flush() throws IOException { // Paper - synchronize - ObjectIterator objectiterator = this.regionCache.values().iterator(); - - while (objectiterator.hasNext()) { -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java -index 151fcbca34e02783e19fbb7b54ec4fbec2eed190..883fbe5c81e3be27007a1a0489f80ba1863e5a04 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java -@@ -12,6 +12,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap; - import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; - import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet; - import java.io.IOException; -+import java.nio.file.Path; - import java.util.Map; - import java.util.Optional; - import java.util.concurrent.CompletableFuture; -@@ -31,25 +32,30 @@ import net.minecraft.world.level.ChunkPos; - import net.minecraft.world.level.LevelHeightAccessor; - import org.slf4j.Logger; - --public class SectionStorage implements AutoCloseable { -+public class SectionStorage extends RegionFileStorage implements AutoCloseable { // Paper - nuke IOWorker - private static final Logger LOGGER = LogUtils.getLogger(); - private static final String SECTIONS_TAG = "Sections"; -- private final SimpleRegionStorage simpleRegionStorage; -+ // Paper - remove mojang I/O thread - private final Long2ObjectMap> storage = new Long2ObjectOpenHashMap<>(); - private final LongLinkedOpenHashSet dirty = new LongLinkedOpenHashSet(); - private final Function> codec; - private final Function factory; -- private final RegistryAccess registryAccess; -+ public final RegistryAccess registryAccess; // Paper - rewrite chunk system - public - protected final LevelHeightAccessor levelHeightAccessor; - - public SectionStorage( -+ // Paper start -+ RegionStorageInfo regionStorageInfo, -+ Path path, -+ boolean dsync, -+ // Paper end - SimpleRegionStorage storageAccess, - Function> codecFactory, - Function factory, - RegistryAccess registryManager, - LevelHeightAccessor world - ) { -- this.simpleRegionStorage = storageAccess; -+ super(regionStorageInfo, path, dsync); // Paper - remove mojang I/O thread - this.codec = codecFactory; - this.factory = factory; - this.registryAccess = registryManager; -@@ -112,23 +118,21 @@ public class SectionStorage implements AutoCloseable { - } - - private void readColumn(ChunkPos pos) { -- Optional optional = this.tryRead(pos).join(); -- RegistryOps registryOps = this.registryAccess.createSerializationContext(NbtOps.INSTANCE); -- this.readColumn(pos, registryOps, optional.orElse(null)); -+ throw new IllegalStateException("Only chunk system can load in state, offending class:" + this.getClass().getName()); // Paper - rewrite chunk system - } - - private CompletableFuture> tryRead(ChunkPos pos) { -- return this.simpleRegionStorage.read(pos).exceptionally(throwable -> { -- if (throwable instanceof IOException iOException) { -- LOGGER.error("Error reading chunk {} data from disk", pos, iOException); -- return Optional.empty(); -- } else { -- throw new CompletionException(throwable); -- } -- }); -+ // Paper start - rewrite chunk system -+ try { -+ return CompletableFuture.completedFuture(Optional.ofNullable(this.read(pos))); -+ } catch (Throwable thr) { -+ return CompletableFuture.failedFuture(thr); -+ } -+ // Paper end - rewrite chunk system - } - - private void readColumn(ChunkPos pos, RegistryOps ops, @Nullable CompoundTag nbt) { -+ if (true) throw new IllegalStateException("Only chunk system can load in state, offending class:" + this.getClass().getName()); // Paper - rewrite chunk system - if (nbt == null) { - for (int i = this.levelHeightAccessor.getMinSection(); i < this.levelHeightAccessor.getMaxSection(); i++) { - this.storage.put(getKey(pos, i), Optional.empty()); -@@ -138,7 +142,7 @@ public class SectionStorage implements AutoCloseable { - int j = getVersion(dynamic); - int k = SharedConstants.getCurrentVersion().getDataVersion().getVersion(); - boolean bl = j != k; -- Dynamic dynamic2 = this.simpleRegionStorage.upgradeChunkTag(dynamic, j); -+ Dynamic dynamic2 = null; // Paper - rewrite chunk system - OptionalDynamic optionalDynamic = dynamic2.get("Sections"); - - for (int l = this.levelHeightAccessor.getMinSection(); l < this.levelHeightAccessor.getMaxSection(); l++) { -@@ -162,7 +166,7 @@ public class SectionStorage implements AutoCloseable { - Dynamic dynamic = this.writeColumn(pos, registryOps); - Tag tag = dynamic.getValue(); - if (tag instanceof CompoundTag) { -- this.simpleRegionStorage.write(pos, (CompoundTag)tag); -+ try { this.write(pos, (CompoundTag)tag); } catch (IOException ex) { SectionStorage.LOGGER.error("Error writing poi chunk data to disk for chunk " + pos, ex); } // Paper - nuke IOWorker - } else { - LOGGER.error("Expected compound tag, got {}", tag); - } -@@ -212,7 +216,7 @@ public class SectionStorage implements AutoCloseable { - } - - private static int getVersion(Dynamic dynamic) { -- return dynamic.get("DataVersion").asInt(1945); -+ return dynamic.get("DataVersion").asInt(1945); // Paper - diff on change, constant used in ChunkLoadTask - } - - public void flush(ChunkPos pos) { -@@ -229,6 +233,6 @@ public class SectionStorage implements AutoCloseable { - - @Override - public void close() throws IOException { -- this.simpleRegionStorage.close(); -+ super.close(); // Paper - nuke I/O worker - don't call the worker - } - } -diff --git a/src/main/java/net/minecraft/world/level/entity/EntityTickList.java b/src/main/java/net/minecraft/world/level/entity/EntityTickList.java -index 74a285b8b018a9c94ccea519f1ce8b9e2ef3cb64..83a39f900551e39d5af6f17a339a386ddee4feef 100644 ---- a/src/main/java/net/minecraft/world/level/entity/EntityTickList.java -+++ b/src/main/java/net/minecraft/world/level/entity/EntityTickList.java -@@ -9,52 +9,41 @@ import javax.annotation.Nullable; - import net.minecraft.world.entity.Entity; - - public class EntityTickList { -- private Int2ObjectMap active = new Int2ObjectLinkedOpenHashMap<>(); -- private Int2ObjectMap passive = new Int2ObjectLinkedOpenHashMap<>(); -- @Nullable -- private Int2ObjectMap iterated; -+ private final io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet entities = new io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet<>(true); // Paper - rewrite this, always keep this updated - why would we EVER tick an entity that's not ticking? - - private void ensureActiveIsNotIterated() { -- if (this.iterated == this.active) { -- this.passive.clear(); -- -- for (Entry entry : Int2ObjectMaps.fastIterable(this.active)) { -- this.passive.put(entry.getIntKey(), entry.getValue()); -- } -- -- Int2ObjectMap int2ObjectMap = this.active; -- this.active = this.passive; -- this.passive = int2ObjectMap; -- } -+ // Paper - replace with better logic, do not delay removals - } - - public void add(Entity entity) { -+ io.papermc.paper.util.TickThread.ensureTickThread("Asynchronous entity ticklist addition"); // Paper - this.ensureActiveIsNotIterated(); -- this.active.put(entity.getId(), entity); -+ this.entities.add(entity); // Paper - replace with better logic, do not delay removals/additions - } - - public void remove(Entity entity) { -+ io.papermc.paper.util.TickThread.ensureTickThread("Asynchronous entity ticklist removal"); // Paper - this.ensureActiveIsNotIterated(); -- this.active.remove(entity.getId()); -+ this.entities.remove(entity); // Paper - replace with better logic, do not delay removals/additions - } - - public boolean contains(Entity entity) { -- return this.active.containsKey(entity.getId()); -+ return this.entities.contains(entity); // Paper - replace with better logic, do not delay removals/additions - } - - public void forEach(Consumer action) { -- if (this.iterated != null) { -- throw new UnsupportedOperationException("Only one concurrent iteration supported"); -- } else { -- this.iterated = this.active; -- -- try { -- for (Entity entity : this.active.values()) { -- action.accept(entity); -- } -- } finally { -- this.iterated = null; -+ io.papermc.paper.util.TickThread.ensureTickThread("Asynchronous entity ticklist iteration"); // Paper -+ // Paper start - replace with better logic, do not delay removals/additions -+ // To ensure nothing weird happens with dimension travelling, do not iterate over new entries... -+ // (by dfl iterator() is configured to not iterate over new entries) -+ io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet.Iterator iterator = this.entities.iterator(); -+ try { -+ while (iterator.hasNext()) { -+ action.accept(iterator.next()); - } -+ } finally { -+ iterator.finishedIterating(); - } -+ // Paper end - replace with better logic, do not delay removals/additions - } - } -diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -index 5d15c228c044a36c67014793decb314240cf6be1..dc765b92cc90f5f370254e68bbbdfa5add7935ce 100644 ---- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -+++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -@@ -87,7 +87,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { - return CompletableFuture.supplyAsync(Util.wrapThreadWithTaskName("init_biomes", () -> { - this.doCreateBiomes(blender, noiseConfig, structureAccessor, chunk); - return chunk; -- }), Util.backgroundExecutor()); -+ }), executor); // Paper - run with supplied executor - } - - private void doCreateBiomes(Blender blender, RandomState noiseConfig, StructureManager structureAccessor, ChunkAccess chunk) { -@@ -286,7 +286,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { - - return CompletableFuture.supplyAsync(Util.wrapThreadWithTaskName("wgen_fill_noise", () -> { - return this.doFill(blender, structureAccessor, noiseConfig, chunk, j, k); -- }), Util.backgroundExecutor()).whenCompleteAsync((ichunkaccess1, throwable) -> { -+ }), executor).whenCompleteAsync((ichunkaccess1, throwable) -> { // Paper - run with supplied executor - Iterator iterator = set.iterator(); - - while (iterator.hasNext()) { -diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java b/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java -index 609100ed7aa0b23aa5a9c6fbf6878ea320bd3a93..7068657b28a9bc175ee23f5a18defb41168f1d76 100644 ---- a/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java -+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java -@@ -47,8 +47,101 @@ public class StructureCheck { - private final BiomeSource biomeSource; - private final long seed; - private final DataFixer fixerUpper; -- private final Long2ObjectMap> loadedChunks = new Long2ObjectOpenHashMap<>(); -- private final Map featureChecks = new HashMap<>(); -+ // Paper start - rewrite chunk system - synchronise this class -+ // additionally, make sure to purge entries from the maps so it does not leak memory -+ private static final int CHUNK_TOTAL_LIMIT = 50 * (2 * 100 + 1) * (2 * 100 + 1); // cache 50 structure lookups -+ private static final int PER_FEATURE_CHECK_LIMIT = 50 * (2 * 100 + 1) * (2 * 100 + 1); // cache 50 structure lookups -+ -+ private final SynchronisedLong2ObjectMap> loadedChunksSafe = new SynchronisedLong2ObjectMap<>(CHUNK_TOTAL_LIMIT); -+ private final java.util.concurrent.ConcurrentHashMap featureChecksSafe = new java.util.concurrent.ConcurrentHashMap<>(); -+ -+ private static final class SynchronisedLong2ObjectMap { -+ private final it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap map = new it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap<>(); -+ private final int limit; -+ -+ public SynchronisedLong2ObjectMap(final int limit) { -+ this.limit = limit; -+ } -+ -+ // must hold lock on map -+ private void purgeEntries() { -+ while (this.map.size() > this.limit) { -+ this.map.removeLast(); -+ } -+ } -+ -+ public V get(final long key) { -+ synchronized (this.map) { -+ return this.map.getAndMoveToFirst(key); -+ } -+ } -+ -+ public V put(final long key, final V value) { -+ synchronized (this.map) { -+ final V ret = this.map.putAndMoveToFirst(key, value); -+ this.purgeEntries(); -+ return ret; -+ } -+ } -+ -+ public V compute(final long key, final java.util.function.BiFunction remappingFunction) { -+ synchronized (this.map) { -+ // first, compute the value - if one is added, it will be at the last entry -+ this.map.compute(key, remappingFunction); -+ // move the entry to first, just in case it was added at last -+ final V ret = this.map.getAndMoveToFirst(key); -+ // now purge the last entries -+ this.purgeEntries(); -+ -+ return ret; -+ } -+ } -+ } -+ -+ private static final class SynchronisedLong2BooleanMap { -+ private final it.unimi.dsi.fastutil.longs.Long2BooleanLinkedOpenHashMap map = new it.unimi.dsi.fastutil.longs.Long2BooleanLinkedOpenHashMap(); -+ private final int limit; -+ -+ public SynchronisedLong2BooleanMap(final int limit) { -+ this.limit = limit; -+ } -+ -+ // must hold lock on map -+ private void purgeEntries() { -+ while (this.map.size() > this.limit) { -+ this.map.removeLastBoolean(); -+ } -+ } -+ -+ public boolean remove(final long key) { -+ synchronized (this.map) { -+ return this.map.remove(key); -+ } -+ } -+ -+ // note: -+ public boolean getOrCompute(final long key, final it.unimi.dsi.fastutil.longs.Long2BooleanFunction ifAbsent) { -+ synchronized (this.map) { -+ if (this.map.containsKey(key)) { -+ return this.map.getAndMoveToFirst(key); -+ } -+ } -+ -+ final boolean put = ifAbsent.get(key); -+ -+ synchronized (this.map) { -+ if (this.map.containsKey(key)) { -+ return this.map.getAndMoveToFirst(key); -+ } -+ this.map.putAndMoveToFirst(key, put); -+ -+ this.purgeEntries(); -+ -+ return put; -+ } -+ } -+ } -+ // Paper end - rewrite chunk system - synchronise this class - - public StructureCheck( - ChunkScanAccess chunkIoWorker, -@@ -90,7 +183,7 @@ public class StructureCheck { - - public StructureCheckResult checkStart(ChunkPos pos, Structure type, StructurePlacement placement, boolean skipReferencedStructures) { - long l = pos.toLong(); -- Object2IntMap object2IntMap = this.loadedChunks.get(l); -+ Object2IntMap object2IntMap = this.loadedChunksSafe.get(l); // Paper - rewrite chunk system - synchronise this class - if (object2IntMap != null) { - return this.checkStructureInfo(object2IntMap, type, skipReferencedStructures); - } else { -@@ -100,9 +193,9 @@ public class StructureCheck { - } else if (!placement.applyAdditionalChunkRestrictions(pos.x, pos.z, this.seed, this.getSaltOverride(type))) { // Paper - add missing structure seed configs - return StructureCheckResult.START_NOT_PRESENT; - } else { -- boolean bl = this.featureChecks -- .computeIfAbsent(type, structure2 -> new Long2BooleanOpenHashMap()) -- .computeIfAbsent(l, chunkPos -> this.canCreateStructure(pos, type)); -+ boolean bl = this.featureChecksSafe // Paper - rewrite chunk system - synchronise this class -+ .computeIfAbsent(type, structure2 -> new SynchronisedLong2BooleanMap(PER_FEATURE_CHECK_LIMIT)) // Paper - rewrite chunk system - synchronise this class -+ .getOrCompute(l, chunkPos -> this.canCreateStructure(pos, type)); // Paper - rewrite chunk system - synchronise this class - return !bl ? StructureCheckResult.START_NOT_PRESENT : StructureCheckResult.CHUNK_LOAD_NEEDED; - } - } -@@ -228,15 +321,26 @@ public class StructureCheck { - } - - private void storeFullResults(long pos, Object2IntMap referencesByStructure) { -- this.loadedChunks.put(pos, deduplicateEmptyMap(referencesByStructure)); -- this.featureChecks.values().forEach(generationPossibilityByChunkPos -> generationPossibilityByChunkPos.remove(pos)); -+ // Paper start - rewrite chunk system - synchronise this class -+ this.loadedChunksSafe.put(pos, deduplicateEmptyMap(referencesByStructure)); -+ // once we insert into loadedChunks, we don't really need to be very careful about removing everything -+ // from this map, as everything that checks this map uses loadedChunks first -+ // so, one way or another it's a race condition that doesn't matter -+ for (SynchronisedLong2BooleanMap value : this.featureChecksSafe.values()) { -+ value.remove(pos); -+ } -+ // Paper end - rewrite chunk system - synchronise this class - } - - public void incrementReference(ChunkPos pos, Structure structure) { -- this.loadedChunks.compute(pos.toLong(), (posx, referencesByStructure) -> { -- if (referencesByStructure == null || referencesByStructure.isEmpty()) { -+ this.loadedChunksSafe.compute(pos.toLong(), (posx, referencesByStructure) -> { // Paper start - rewrite chunk system - synchronise this class -+ // make this COW so that we do not mutate state that may be currently in use -+ if (referencesByStructure == null) { - referencesByStructure = new Object2IntOpenHashMap<>(); -+ } else { -+ referencesByStructure = referencesByStructure instanceof Object2IntOpenHashMap fastClone ? fastClone.clone() : new Object2IntOpenHashMap<>(referencesByStructure); - } -+ // Paper end - rewrite chunk system - synchronise this class - - referencesByStructure.computeInt(structure, (feature, references) -> references == null ? 1 : references + 1); - return referencesByStructure; -diff --git a/src/main/java/net/minecraft/world/ticks/LevelChunkTicks.java b/src/main/java/net/minecraft/world/ticks/LevelChunkTicks.java -index 47c2b2da9799690291396effb9e1b06d71efc6fd..2cdd18f724296f10cd4a522d1e8196723d39cf45 100644 ---- a/src/main/java/net/minecraft/world/ticks/LevelChunkTicks.java -+++ b/src/main/java/net/minecraft/world/ticks/LevelChunkTicks.java -@@ -26,6 +26,19 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon - @Nullable - private BiConsumer, ScheduledTick> onTickAdded; - -+ // Paper start - add dirty flag -+ private boolean dirty; -+ private long lastSaved = Long.MIN_VALUE; -+ -+ public boolean isDirty(final long tick) { -+ return this.dirty || (!this.tickQueue.isEmpty() && tick != this.lastSaved); -+ } -+ -+ public void clearDirty() { -+ this.dirty = false; -+ } -+ // Paper end - add dirty flag -+ - public LevelChunkTicks() { - } - -@@ -50,6 +63,7 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon - public ScheduledTick poll() { - ScheduledTick scheduledTick = this.tickQueue.poll(); - if (scheduledTick != null) { -+ this.dirty = true; // Paper - add dirty flag - this.ticksPerPosition.remove(scheduledTick); - } - -@@ -59,6 +73,7 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon - @Override - public void schedule(ScheduledTick orderedTick) { - if (this.ticksPerPosition.add(orderedTick)) { -+ this.dirty = true; // Paper - add dirty flag - this.scheduleUnchecked(orderedTick); - } - } -@@ -81,7 +96,7 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon - while (iterator.hasNext()) { - ScheduledTick scheduledTick = iterator.next(); - if (predicate.test(scheduledTick)) { -- iterator.remove(); -+ iterator.remove(); this.dirty = true; // Paper - add dirty flag - this.ticksPerPosition.remove(scheduledTick); - } - } -@@ -98,6 +113,7 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon - - @Override - public ListTag save(long l, Function function) { -+ this.lastSaved = l; // Paper - add dirty system to level ticks - ListTag listTag = new ListTag(); - if (this.pendingTicks != null) { - for (SavedTick savedTick : this.pendingTicks) { -@@ -114,6 +130,11 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon - - public void unpack(long time) { - if (this.pendingTicks != null) { -+ // Paper start - add dirty system to level chunk ticks -+ if (this.tickQueue.isEmpty()) { -+ this.lastSaved = time; -+ } -+ // Paper end - add dirty system to level chunk ticks - int i = -this.pendingTicks.size(); - - for (SavedTick savedTick : this.pendingTicks) { -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java -index 36a611d06131be00197c915871b8323544bb4972..bb22473df13f68ac3b45a9c000d1de7260e07792 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java -@@ -116,7 +116,7 @@ public class CraftChunk implements Chunk { - - @Override - public boolean isEntitiesLoaded() { -- return this.getCraftWorld().getHandle().entityManager.areEntitiesLoaded(ChunkPos.asLong(this.x, this.z)); -+ return this.getCraftWorld().getHandle().areEntitiesLoaded(io.papermc.paper.util.CoordinateUtils.getChunkKey(this.x, this.z)); // Paper - rewrite chunk system - } - - @Override -@@ -125,51 +125,7 @@ public class CraftChunk implements Chunk { - this.getWorld().getChunkAt(this.x, this.z); // Transient load for this tick - } - -- PersistentEntitySectionManager entityManager = this.getCraftWorld().getHandle().entityManager; -- long pair = ChunkPos.asLong(this.x, this.z); -- -- if (entityManager.areEntitiesLoaded(pair)) { -- return entityManager.getEntities(new ChunkPos(this.x, this.z)).stream() -- .map(net.minecraft.world.entity.Entity::getBukkitEntity) -- .filter(Objects::nonNull).toArray(Entity[]::new); -- } -- -- entityManager.ensureChunkQueuedForLoad(pair); // Start entity loading -- -- // SPIGOT-6772: Use entity mailbox and re-schedule entities if they get unloaded -- ProcessorMailbox mailbox = ((EntityStorage) entityManager.permanentStorage).entityDeserializerQueue; -- BooleanSupplier supplier = () -> { -- // only execute inbox if our entities are not present -- if (entityManager.areEntitiesLoaded(pair)) { -- return true; -- } -- -- if (!entityManager.isPending(pair)) { -- // Our entities got unloaded, this should normally not happen. -- entityManager.ensureChunkQueuedForLoad(pair); // Re-start entity loading -- } -- -- // tick loading inbox, which loads the created entities to the world -- // (if present) -- entityManager.tick(); -- // check if our entities are loaded -- return entityManager.areEntitiesLoaded(pair); -- }; -- -- // now we wait until the entities are loaded, -- // the converting from NBT to entity object is done on the main Thread which is why we wait -- while (!supplier.getAsBoolean()) { -- if (mailbox.size() != 0) { -- mailbox.run(); -- } else { -- Thread.yield(); -- LockSupport.parkNanos("waiting for entity loading", 100000L); -- } -- } -- -- return entityManager.getEntities(new ChunkPos(this.x, this.z)).stream() -- .map(net.minecraft.world.entity.Entity::getBukkitEntity) -- .filter(Objects::nonNull).toArray(Entity[]::new); -+ return this.getCraftWorld().getHandle().getChunkEntities(this.x, this.z); // Paper - rewrite chunk system - } - - @Override -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 16a736e8327450712630b1659b156da879a57352..0e30a227948464979e12c991b10bd00cf7320399 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1426,7 +1426,6 @@ public final class CraftServer implements Server { - // Paper - Put world into worldlist before initing the world; move up - - this.getServer().prepareLevels(internal.getChunkSource().chunkMap.progressListener, internal); -- internal.entityManager.tick(); // SPIGOT-6526: Load pending entities so they are available to the API - - this.pluginManager.callEvent(new WorldLoadEvent(internal.getWorld())); - return internal.getWorld(); -@@ -1471,7 +1470,7 @@ public final class CraftServer implements Server { - } - - handle.getChunkSource().close(save); -- handle.entityManager.close(save); // SPIGOT-6722: close entityManager -+ // handle.entityManager.close(save); // SPIGOT-6722: close entityManager // Paper - rewrite chunk system - handle.convertable.close(); - } catch (Exception ex) { - this.getLogger().log(Level.SEVERE, null, ex); -@@ -2507,7 +2506,7 @@ public final class CraftServer implements Server { - - @Override - public boolean isPrimaryThread() { -- return Thread.currentThread().equals(this.console.serverThread) || this.console.hasStopped() || !org.spigotmc.AsyncCatcher.enabled; // All bets are off if we have shut down (e.g. due to watchdog) -+ return io.papermc.paper.util.TickThread.isTickThread(); // Paper - rewrite chunk system - } - - // Paper start - Adventure -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 7aee9f6b143c89cf8d65ca55eeda808152b4dd26..9c06c3729b09726e1da6ff8fb975cef2aeba9643 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -518,10 +518,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { - ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z)); - if (playerChunk == null) return false; - -- playerChunk.getTickingChunkFuture().thenAccept(either -> { -- either.ifSuccess(chunk -> { -+ // Paper start - rewrite player chunk loader -+ net.minecraft.world.level.chunk.LevelChunk chunk = playerChunk.getSendingChunk(); -+ if (chunk == null) { -+ return false; -+ } -+ // Paper end - rewrite player chunk loader - List playersInRange = playerChunk.playerProvider.getPlayers(playerChunk.getPos(), false); -- if (playersInRange.isEmpty()) return; -+ if (playersInRange.isEmpty()) return true; // Paper - rewrite player chunk loader - - ClientboundLevelChunkWithLightPacket refreshPacket = new ClientboundLevelChunkWithLightPacket(chunk, this.world.getLightEngine(), null, null); - for (ServerPlayer player : playersInRange) { -@@ -529,8 +533,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { - - player.connection.send(refreshPacket); - } -- }); -- }); -+ // Paper - rewrite player chunk loader - - return true; - } -@@ -634,20 +637,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { - @Override - public Collection getPluginChunkTickets(int x, int z) { - DistanceManager chunkDistanceManager = this.world.getChunkSource().chunkMap.distanceManager; -- SortedArraySet> tickets = chunkDistanceManager.tickets.get(ChunkPos.asLong(x, z)); -- -- if (tickets == null) { -- return Collections.emptyList(); -- } -- -- ImmutableList.Builder ret = ImmutableList.builder(); -- for (Ticket ticket : tickets) { -- if (ticket.getType() == TicketType.PLUGIN_TICKET) { -- ret.add((Plugin) ticket.key); -- } -- } -- -- return ret.build(); -+ return chunkDistanceManager.getChunkHolderManager().getPluginChunkTickets(x, z); // Paper - rewrite chunk system - } - - @Override -@@ -655,7 +645,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { - Map> ret = new HashMap<>(); - DistanceManager chunkDistanceManager = this.world.getChunkSource().chunkMap.distanceManager; - -- for (Long2ObjectMap.Entry>> chunkTickets : chunkDistanceManager.tickets.long2ObjectEntrySet()) { -+ for (Long2ObjectMap.Entry>> chunkTickets : chunkDistanceManager.getChunkHolderManager().getTicketsCopy().long2ObjectEntrySet()) { // Paper - rewrite chunk system - long chunkKey = chunkTickets.getLongKey(); - SortedArraySet> tickets = chunkTickets.getValue(); - -@@ -1352,12 +1342,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { - - @Override - public int getViewDistance() { -- return this.world.getChunkSource().chunkMap.serverViewDistance; -+ return this.getHandle().playerChunkLoader.getAPIViewDistance(); // Paper - replace player chunk loader - } - - @Override - public int getSimulationDistance() { -- return this.world.getChunkSource().chunkMap.getDistanceManager().simulationDistance; -+ return this.getHandle().playerChunkLoader.getAPITickDistance(); // Paper - replace player chunk loader - } - - public BlockMetadataStore getBlockMetadata() { -@@ -2520,17 +2510,20 @@ public class CraftWorld extends CraftRegionAccessor implements World { - - @Override - public void setSimulationDistance(final int simulationDistance) { -- throw new UnsupportedOperationException("Not implemented yet"); -+ if (simulationDistance < 2 || simulationDistance > 32) { -+ throw new IllegalArgumentException("Simulation distance " + simulationDistance + " is out of range of [2, 32]"); -+ } -+ this.getHandle().chunkSource.chunkMap.setTickViewDistance(simulationDistance); - } - - @Override - public int getSendViewDistance() { -- return this.getViewDistance(); -+ return this.getHandle().playerChunkLoader.getAPISendViewDistance(); // Paper - replace player chunk loader - } - - @Override - public void setSendViewDistance(final int viewDistance) { -- throw new UnsupportedOperationException("Not implemented yet"); -+ this.getHandle().chunkSource.chunkMap.setSendViewDistance(viewDistance); // Paper - replace player chunk loader - } - - // Paper start - implement pointers -diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 68a0b6b8650e9e80e8e8c4037d92389cae899d72..9aec6efef4094bbdb920101df1a7a5a2a6070dde 100644 ---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3463,31 +3463,31 @@ public class CraftPlayer extends CraftHumanEntity implements Player { - - @Override - public int getViewDistance() { -- return io.papermc.paper.chunk.system.ChunkSystem.getLoadViewDistance(this.getHandle()); -+ return io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.getAPIViewDistance(this); - } - - @Override - public void setViewDistance(final int viewDistance) { -- throw new UnsupportedOperationException("Not implemented yet"); -+ this.getHandle().setLoadViewDistance(viewDistance < 0 ? viewDistance : viewDistance + 1); - } - - @Override - public int getSimulationDistance() { -- return io.papermc.paper.chunk.system.ChunkSystem.getTickViewDistance(this.getHandle()); -+ return io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.getAPITickViewDistance(this); - } - - @Override - public void setSimulationDistance(final int simulationDistance) { -- throw new UnsupportedOperationException("Not implemented yet"); -+ this.getHandle().setTickViewDistance(simulationDistance); - } - - @Override - public int getSendViewDistance() { -- return io.papermc.paper.chunk.system.ChunkSystem.getSendViewDistance(this.getHandle()); -+ return io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.getAPISendViewDistance(this); - } - - @Override - public void setSendViewDistance(final int viewDistance) { -- throw new UnsupportedOperationException("Not implemented yet"); -+ this.getHandle().setSendViewDistance(viewDistance); - } - } -diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java -index b65710b648e31ab74204b5abd9397d9e6e26dac4..c77f722131e0e40e9de29bf8d42f9bc5d8fa2f7d 100644 ---- a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java -+++ b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java -@@ -264,7 +264,7 @@ public class CustomChunkGenerator extends InternalChunkGenerator { - return ichunkaccess1; - }; - -- return future == null ? CompletableFuture.supplyAsync(() -> function.apply(chunk), net.minecraft.Util.backgroundExecutor()) : future.thenApply(function); -+ return future == null ? CompletableFuture.supplyAsync(() -> function.apply(chunk), executor) : future.thenApply(function); // Paper - run with supplied executor - } - - @Override -diff --git a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java -index cd7f1309cf01a5f01a28aded03a36fe15adb1756..41a291d42667c38d3e5bbe47236772761e85929b 100644 ---- a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java -+++ b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java -@@ -815,19 +815,39 @@ public abstract class DelegatedGeneratorAccess implements WorldGenLevel { - @Nullable - @Override - public BlockState getBlockStateIfLoaded(final BlockPos blockposition) { -- return null; -+ return this.handle.getBlockStateIfLoaded(blockposition); - } - - @Nullable - @Override - public FluidState getFluidIfLoaded(final BlockPos blockposition) { -- return null; -+ return this.handle.getFluidIfLoaded(blockposition); - } - - @Nullable - @Override - public ChunkAccess getChunkIfLoadedImmediately(final int x, final int z) { -- return null; -+ return this.handle.getChunkIfLoadedImmediately(x, z); -+ } -+ -+ @Override -+ public void getHardCollidingEntities(final Entity except, final AABB box, final Predicate predicate, final List into) { -+ this.handle.getHardCollidingEntities(except, box, predicate, into); -+ } -+ -+ @Override -+ public List getHardCollidingEntities(final Entity except, final AABB box, final Predicate predicate) { -+ return this.handle.getHardCollidingEntities(except, box, predicate); -+ } -+ -+ @Override -+ public void getEntities(final Entity except, final AABB box, final Predicate predicate, final List into) { -+ this.handle.getEntities(except, box, predicate, into); -+ } -+ -+ @Override -+ public void getEntitiesByClass(final Class clazz, final Entity except, final AABB box, final List into, final Predicate predicate) { -+ this.handle.getEntitiesByClass(clazz, except, box, into, predicate); - } - // Paper end - } -diff --git a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java -index e8a73d34dbb372581b03018aade170a31c266099..210f454a840aa5564f7cbf33b83d31aa74814c84 100644 ---- a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java -+++ b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java -@@ -268,4 +268,19 @@ public class DummyGeneratorAccess implements WorldGenLevel { - @Override - public void scheduleTick(BlockPos pos, Fluid fluid, int delay, net.minecraft.world.ticks.TickPriority priority) {} - // Paper end - add more methods -+ // Paper start -+ @Override -+ public List getHardCollidingEntities(Entity except, AABB box, Predicate predicate) { -+ return java.util.Collections.emptyList(); -+ } -+ -+ @Override -+ public void getEntities(Entity except, AABB box, Predicate predicate, List into) {} -+ -+ @Override -+ public void getHardCollidingEntities(Entity except, AABB box, Predicate predicate, List into) {} -+ -+ @Override -+ public void getEntitiesByClass(Class clazz, Entity except, AABB box, List into, Predicate predicate) {} -+ // Paper end - } -diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java -index e8e3cc48cf1c58bd8151d1f28df28781859cd0e3..2e074c16dab1ead47914070329da0398c3274048 100644 ---- a/src/main/java/org/spigotmc/AsyncCatcher.java -+++ b/src/main/java/org/spigotmc/AsyncCatcher.java -@@ -9,7 +9,7 @@ public class AsyncCatcher - - public static void catchOp(String reason) - { -- if ( (AsyncCatcher.enabled || io.papermc.paper.util.TickThread.STRICT_THREAD_CHECKS) && Thread.currentThread() != MinecraftServer.getServer().serverThread ) // Paper -+ if (!(io.papermc.paper.util.TickThread.isTickThread())) // Paper - { - MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); // Paper - throw new IllegalStateException( "Asynchronous " + reason + "!" ); -diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java -index ad282d34919716b75acd10426cd071da9d064a51..9e5d08f57aa448552d100ca892c211d44441ef68 100644 ---- a/src/main/java/org/spigotmc/WatchdogThread.java -+++ b/src/main/java/org/spigotmc/WatchdogThread.java -@@ -8,7 +8,7 @@ import java.util.logging.Logger; - import net.minecraft.server.MinecraftServer; - import org.bukkit.Bukkit; - --public class WatchdogThread extends Thread -+public final class WatchdogThread extends io.papermc.paper.util.TickThread // Paper - rewrite chunk system - { - - private static WatchdogThread instance; -@@ -115,6 +115,7 @@ public class WatchdogThread extends Thread - // 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 -+ io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(isLongTimeout); // Paper - rewrite chunk system - WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log ); - log.log( Level.SEVERE, "------------------------------" ); - // diff --git a/patches/later/0277-Improve-exact-choice-recipe-ingredients.patch b/patches/unapplied/server/0277-Improve-exact-choice-recipe-ingredients.patch similarity index 100% rename from patches/later/0277-Improve-exact-choice-recipe-ingredients.patch rename to patches/unapplied/server/0277-Improve-exact-choice-recipe-ingredients.patch diff --git a/patches/later/0451-Fix-harming-potion-dupe.patch b/patches/unapplied/server/0451-Fix-harming-potion-dupe.patch similarity index 100% rename from patches/later/0451-Fix-harming-potion-dupe.patch rename to patches/unapplied/server/0451-Fix-harming-potion-dupe.patch diff --git a/patches/later/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch b/patches/unapplied/server/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch similarity index 100% rename from patches/later/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch rename to patches/unapplied/server/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch diff --git a/patches/later/0845-API-for-updating-recipes-on-clients.patch b/patches/unapplied/server/0845-API-for-updating-recipes-on-clients.patch similarity index 100% rename from patches/later/0845-API-for-updating-recipes-on-clients.patch rename to patches/unapplied/server/0845-API-for-updating-recipes-on-clients.patch diff --git a/patches/later/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch b/patches/unapplied/server/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch similarity index 100% rename from patches/later/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch rename to patches/unapplied/server/0986-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch From 348c8550967380d9843e365e769f67eee8a8e474 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Sun, 27 Oct 2024 09:43:00 +0100 Subject: [PATCH 094/119] Readd last API patch (with TODO) --- ...-API-for-updating-recipes-on-clients.patch | 0 ...tch => 0401-Add-PlayerFailMoveEvent.patch} | 0 ...-custom-statistic-criteria-creation.patch} | 0 ...tch => 0403-SculkCatalyst-bloom-API.patch} | 0 ...API-for-an-entity-s-scoreboard-name.patch} | 0 ...lace-methods-with-old-StructureType.patch} | 4 +-- ... => 0406-Add-Listing-API-for-Player.patch} | 0 ...d-BlockFace-during-BlockDamageEvent.patch} | 0 ...h => 0408-Fix-NPE-on-Boat-getStatus.patch} | 0 ...e-API.patch => 0409-Expand-Pose-API.patch} | 0 ...MerchantRecipe-add-copy-constructor.patch} | 0 ...patch => 0411-More-DragonBattle-API.patch} | 0 ...tch => 0412-Add-PlayerPickItemEvent.patch} | 0 ...=> 0413-Allow-trident-custom-damage.patch} | 0 ...pose-hand-during-BlockCanBuildEvent.patch} | 0 ...t-setBurnTime-to-valid-short-values.patch} | 0 ... 0416-Add-OfflinePlayer-isConnected.patch} | 0 ...titleOverride-to-InventoryOpenEvent.patch} | 0 ...roper-checking-of-empty-item-stacks.patch} | 0 ...dItemsEvent-throwing-exception-when.patch} | 0 ...> 0420-Add-player-idle-duration-API.patch} | 0 ...e-collision-shape-of-a-block-before.patch} | 0 ...redicate-for-blocks-when-raytracing.patch} | 0 ...h-event-for-all-player-interactions.patch} | 0 ...Attribute-Modifier-API-improvements.patch} | 0 ... => 0425-Expand-LingeringPotion-API.patch} | 0 ...y-durability-check-in-ItemStack-isS.patch} | 0 ...tch => 0427-Add-Structure-check-API.patch} | 0 ...428-Experimental-annotations-change.patch} | 0 ...tch => 0429-Add-more-scoreboard-API.patch} | 0 ...stry.patch => 0430-Improve-Registry.patch} | 0 ...h => 0431-Add-experience-points-API.patch} | 0 ...h => 0432-Add-missing-InventoryType.patch} | 0 ...h => 0433-Add-drops-to-shear-events.patch} | 0 ... => 0434-Add-HiddenPotionEffect-API.patch} | 0 ...> 0435-Add-PlayerShieldDisableEvent.patch} | 0 ...mpty-String-in-NamespacedKey.fromSt.patch} | 0 ...-Add-BlockStateMeta-clearBlockState.patch} | 0 ...38-Expose-LootTable-of-DecoratedPot.patch} | 0 ...h => 0439-Add-ShulkerDuplicateEvent.patch} | 0 ...dd-api-for-spawn-egg-texture-colors.patch} | 0 ... => 0441-Add-Lifecycle-Event-system.patch} | 0 ...patch => 0442-ItemStack-Tooltip-API.patch} | 0 ...Snapshot-includeLightData-parameter.patch} | 0 ...PI.patch => 0444-Add-FluidState-API.patch} | 0 ...patch => 0445-add-number-format-api.patch} | 0 ...patch => 0446-improve-BanList-types.patch} | 8 ++--- ...=> 0447-Suspicious-Effect-Entry-API.patch} | 0 ....patch => 0448-Fix-DamageSource-API.patch} | 0 ...I.patch => 0449-Expanded-Hopper-API.patch} | 0 ...tables-to-prevent-unexpected-issues.patch} | 0 ...1-Add-BlockBreakProgressUpdateEvent.patch} | 0 ...=> 0452-Deprecate-ItemStack-setType.patch} | 0 ...s.patch => 0453-Item-Mutation-Fixes.patch} | 0 ...> 0454-API-for-checking-sent-chunks.patch} | 0 ...ch => 0455-Add-CartographyItemEvent.patch} | 0 ...aid-API.patch => 0456-More-Raid-API.patch} | 0 ...0457-Fix-SpawnerEntry-Equipment-API.patch} | 0 ...emFlags.patch => 0458-Fix-ItemFlags.patch} | 0 ...ifying-library-loader-jars-bytecode.patch} | 0 ...0460-Add-hook-to-remap-library-jars.patch} | 0 ...=> 0461-Add-GameMode-isInvulnerable.patch} | 0 ...62-Expose-hasColor-to-leather-armor.patch} | 0 ...-API-to-get-player-ha-proxy-address.patch} | 0 ....patch => 0464-More-Chest-Block-API.patch} | 0 ...=> 0465-Brigadier-based-command-API.patch} | 0 ... => 0466-Fix-issues-with-recipe-API.patch} | 0 ...67-Fix-equipment-slot-and-group-API.patch} | 0 ...lugin-to-use-Paper-PluginLoader-API.patch} | 0 ...atch => 0469-General-ItemMeta-fixes.patch} | 0 ...470-Add-missing-fishing-event-state.patch} | 0 ...ate-InvAction-HOTBAR_MOVE_AND_READD.patch} | 0 ...h => 0472-Registry-Modification-API.patch} | 0 ...troduce-registry-entry-and-builders.patch} | 0 ...4-Proxy-ItemStack-to-CraftItemStack.patch} | 0 ...-accessible-directly-from-ItemStack.patch} | 0 ...h => 0476-Fix-HelpCommand-searching.patch} | 0 ...atch => 0477-add-Plugin-getDataPath.patch} | 0 ...0478-Fix-PickupStatus-getting-reset.patch} | 0 ...anPlaceOn-and-CanDestroy-NBT-values.patch} | 0 ...tandardMessenger-exception-messages.patch} | 0 ... 0481-Add-even-more-Enchantment-API.patch} | 0 ...ble-API.patch => 0482-Leashable-API.patch} | 0 ...483-Add-enchantment-seed-update-API.patch} | 0 ...removal-all-OldEnum-related-methods.patch} | 0 ...I.patch => 0485-Add-FeatureFlag-API.patch} | 0 ....patch => 0486-Tag-Lifecycle-Events.patch} | 0 ... => 0487-Item-serialization-as-json.patch} | 0 ...488-create-TileStateInventoryHolder.patch} | 0 ...evels-with-enchantment-registry-set.patch} | 0 ...h => 0490-Improve-entity-effect-API.patch} | 0 ...me.patch => 0491-Add-recipeBrewTime.patch} | 0 ...92-Add-PlayerInsertLecternBookEvent.patch} | 0 ... 0493-Void-damage-configuration-API.patch} | 0 ...I.patch => 0494-Add-Offline-PDC-API.patch} | 0 ...w-bypassEnchantmentLevelRestriction.patch} | 0 ...tch => 0496-fix-DamageTypeTags-init.patch} | 0 ...-API-for-updating-recipes-on-clients.patch | 34 +++++++++---------- ...-custom-statistic-criteria-creation.patch} | 0 ...atch => 0847-Bandaid-fix-for-Effect.patch} | 0 ...tch => 0848-SculkCatalyst-bloom-API.patch} | 0 ...API-for-an-entity-s-scoreboard-name.patch} | 0 ...lace-methods-with-old-StructureType.patch} | 6 ++-- ...e-namespaced-commands-if-send-names.patch} | 0 ...-handle-BlockBreakEvent-isDropItems.patch} | 0 ...entity-death-event-for-ender-dragon.patch} | 0 ...tity-tracking-range-by-Y-coordinate.patch} | 0 ... => 0855-Add-Listing-API-for-Player.patch} | 2 +- ...figurable-Region-Compression-Format.patch} | 0 ...7-Add-BlockFace-to-BlockDamageEvent.patch} | 0 ...h => 0858-Fix-NPE-on-Boat-getStatus.patch} | 0 ...e-API.patch => 0859-Expand-Pose-API.patch} | 0 ...patch => 0860-More-DragonBattle-API.patch} | 0 ...tch => 0861-Add-PlayerPickItemEvent.patch} | 0 ...=> 0862-Allow-trident-custom-damage.patch} | 0 ...3-Expose-hand-in-BlockCanBuildEvent.patch} | 0 ...-nearest-structure-border-iteration.patch} | 0 ...Implement-OfflinePlayer-isConnected.patch} | 0 ...esync.patch => 0866-Fix-slot-desync.patch} | 0 ...titleOverride-to-InventoryOpenEvent.patch} | 0 ...68-Configure-sniffer-egg-hatch-time.patch} | 0 ...-proximity-check-before-entity-look.patch} | 0 ...kip-POI-finding-if-stuck-in-vehicle.patch} | 0 ...t-sanity-checks-in-container-clicks.patch} | 0 ...ll-BlockRedstoneEvents-for-lecterns.patch} | 0 ...roper-checking-of-empty-item-stacks.patch} | 0 ...ix-silent-equipment-change-for-mobs.patch} | 0 ...h => 0875-Fix-spigot-s-Forced-Stats.patch} | 0 ...ing-InventoryHolders-to-inventories.patch} | 0 ...entities-in-chunks-that-are-positio.patch} | 0 ...sing-logs-for-log-ips-config-option.patch} | 0 ...n-on-UpgradeData.BlockFixers-class-.patch} | 0 ...-AdvancementProgress-getDateAwarded.patch} | 0 ...idebar-objectives-not-being-cleared.patch} | 0 ...x-missing-map-initialize-event-call.patch} | 0 ...a-when-attaching-firework-to-entity.patch} | 0 ...84-Fix-UnsafeValues-loadAdvancement.patch} | 0 ...> 0885-Add-player-idle-duration-API.patch} | 0 ...-if-we-can-see-non-visible-entities.patch} | 0 ...NPE-in-SculkBloomEvent-world-access.patch} | 0 ...tack-for-Player-sendEquipmentChange.patch} | 0 ...Ints.patch => 0889-Optimize-VarInts.patch} | 0 ...e-collision-shape-of-a-block-before.patch} | 0 ...redicate-for-blocks-when-raytracing.patch} | 0 ...em-packets-with-collector-as-source.patch} | 0 ... => 0893-Expand-LingeringPotion-API.patch} | 0 ...ngEffect-powers-lightning-rods-and-.patch} | 0 ...h-event-for-all-player-interactions.patch} | 0 ...everal-issues-with-EntityBreedEvent.patch} | 0 ...897-Add-UUID-attribute-modifier-API.patch} | 0 ...-event-call-for-entity-teleport-API.patch} | 0 ...y-create-LootContext-for-criterions.patch} | 0 ...-t-fire-sync-events-during-worldgen.patch} | 0 ...tch => 0901-Add-Structure-check-API.patch} | 0 ...-getAttributeModifier-duplication-c.patch} | 0 ...store-vanilla-entity-drops-behavior.patch} | 0 ...-Dont-resend-blocks-on-interactions.patch} | 0 ...tch => 0905-add-more-scoreboard-API.patch} | 0 ...stry.patch => 0906-Improve-Registry.patch} | 0 ...on-null-loc-for-EntityTeleportEvent.patch} | 0 ...h => 0908-Add-experience-points-API.patch} | 0 ...h => 0909-Add-drops-to-shear-events.patch} | 0 ...> 0910-Add-PlayerShieldDisableEvent.patch} | 0 ...ate-ResourceLocation-in-NBT-reading.patch} | 0 ...-experience-dropping-on-block-break.patch} | 0 ...> 0913-Fixup-NamespacedKey-handling.patch} | 0 ...14-Expose-LootTable-of-DecoratedPot.patch} | 0 ...location-of-Vec3D-by-entity-tracker.patch} | 0 ...rTradeEvent-and-PlayerPurchaseEvent.patch} | 0 ...h => 0917-Add-ShulkerDuplicateEvent.patch} | 0 ...dd-api-for-spawn-egg-texture-colors.patch} | 0 ... => 0919-Add-Lifecycle-Event-system.patch} | 2 +- ...patch => 0920-ItemStack-Tooltip-API.patch} | 0 ...Snapshot-includeLightData-parameter.patch} | 0 ...PI.patch => 0922-Add-FluidState-API.patch} | 0 ...patch => 0923-add-number-format-api.patch} | 0 ...patch => 0924-improve-BanList-types.patch} | 4 +-- ...I.patch => 0925-Expanded-Hopper-API.patch} | 0 ...6-Add-BlockBreakProgressUpdateEvent.patch} | 0 ...=> 0927-Deprecate-ItemStack-setType.patch} | 0 ...ch => 0928-Add-CartographyItemEvent.patch} | 0 ...aid-API.patch => 0929-More-Raid-API.patch} | 0 ...ng-message-for-initial-server-start.patch} | 0 ...-Configurable-max-block-fluid-ticks.patch} | 0 ...=> 0932-Fix-bees-aging-inside-hives.patch} | 0 ...3-Disable-memory-reserve-allocating.patch} | 0 ...ByEntityEvent-for-unowned-wither-sk.patch} | 0 ....patch => 0935-Fix-DamageSource-API.patch} | 0 ...nvalid-block-entity-during-world-ge.patch} | 0 ...ackOverflowError-for-some-dispenses.patch} | 0 ...=> 0938-Improve-tag-parser-handling.patch} | 0 ...s.patch => 0939-Item-Mutation-Fixes.patch} | 0 ...-Per-world-ticks-per-spawn-settings.patch} | 0 ...e-changed-item-from-dispense-events.patch} | 0 ...nd-End-Portal-Frames-from-being-des.patch} | 0 ...-for-mobs-immune-to-default-effects.patch} | 0 ... => 0944-Deep-clone-nbt-tags-in-PDC.patch} | 0 ...945-Support-old-UUID-format-for-NBT.patch} | 0 ...46-Fix-shield-disable-inconsistency.patch} | 0 ...-Large-Packets-disconnecting-client.patch} | 0 ...emFlags.patch => 0948-Fix-ItemFlags.patch} | 0 ...et-damage-reduction-inconsistencies.patch} | 0 ...-handling-of-LivingEntity-actuallyH.patch} | 0 ...e-checking-handled-tags-in-itemmeta.patch} | 0 ...52-Expose-hasColor-to-leather-armor.patch} | 0 ...-API-to-get-player-ha-proxy-address.patch} | 0 ...atch => 0954-General-ItemMeta-fixes.patch} | 0 ....patch => 0955-More-Chest-Block-API.patch} | 0 ...ta-component-type-on-encoding-error.patch} | 0 ...=> 0957-Brigadier-based-command-API.patch} | 2 +- ... => 0958-Fix-issues-with-Recipe-API.patch} | 0 ...59-Fix-equipment-slot-and-group-API.patch} | 0 ...lugin-to-use-Paper-PluginLoader-API.patch} | 0 ...versized-item-data-in-equipment-and.patch} | 0 ...nt-NPE-if-hooked-entity-was-cleared.patch} | 0 ...ng-BlockPlaceEvent-calling-onRemove.patch} | 0 ...964-Add-missing-fishing-event-state.patch} | 0 ...ate-InvAction-HOTBAR_MOVE_AND_READD.patch} | 0 ...nnect-packet-in-phases-where-it-doe.patch} | 0 ...tch => 0967-Adopt-MaterialRerouting.patch} | 0 ...=> 0968-Suspicious-Effect-Entry-API.patch} | 0 ...eck-if-itemstack-is-stackable-first.patch} | 0 ...emoving-recipes-from-RecipeIterator.patch} | 0 ...mage-tick-when-blocking-with-shield.patch} | 0 ...he-experimental-smithing-inventory-.patch} | 0 ...73-disable-forced-empty-world-ticks.patch} | 0 ...dBounds-and-getBlockState-for-inlin.patch} | 0 ...tem-frames-performance-and-bug-fixe.patch} | 0 ...Manager-and-add-advanced-packet-sup.patch} | 0 ...77-Allow-Saving-of-Oversized-Chunks.patch} | 0 ...978-Flat-bedrock-generator-settings.patch} | 0 ...=> 0979-Entity-Activation-Range-2.0.patch} | 0 ...9-Anti-Xray.patch => 0980-Anti-Xray.patch} | 6 ++-- ...city-compression-and-cipher-natives.patch} | 0 ...timize-Collision-to-not-load-chunks.patch} | 2 +- ...alSelector-Goal.Flag-Set-operations.patch} | 0 ...pers.patch => 0984-Optimize-Hoppers.patch} | 0 ...> 0985-Optimize-Voxel-Shape-Merging.patch} | 0 ...Optimize-Bit-Operations-by-inlining.patch} | 0 ...> 0987-Remove-streams-from-hot-code.patch} | 0 ...er-Remove-Streams-Optimized-collect.patch} | 0 ...-type-tags-suggestions-in-selectors.patch} | 0 ...-Oversized-block-entities-in-chunks.patch} | 0 ...eck-distance-in-entity-interactions.patch} | 0 ...ch => 0992-Configurable-Sand-Duping.patch} | 0 ...ch => 0993-Properly-resend-entities.patch} | 2 +- ...h => 0994-Registry-Modification-API.patch} | 0 ...995-Add-registry-entry-and-builders.patch} | 0 ...6-Proxy-ItemStack-to-CraftItemStack.patch} | 0 ...-accessible-directly-from-ItemStack.patch} | 0 ...aft-commands-in-function-parsing-an.patch} | 0 ...99-optimize-dirt-and-snow-spreading.patch} | 0 ... 1000-Fix-NPE-for-Jukebox-setRecord.patch} | 0 ...patch => 1001-fix-horse-inventories.patch} | 0 ...ityDamageEvents-before-actuallyHurt.patch} | 0 ... => 1003-Add-ItemType-getItemRarity.patch} | 0 ... => 1004-Add-plugin-info-at-startup.patch} | 0 ...tion-leniency-distance-configurable.patch} | 0 ...1006-Fix-PickupStatus-getting-reset.patch} | 0 ...ype-in-SculkSensorBlock-canActivate.patch} | 0 ...anPlaceOn-and-CanDestroy-NBT-values.patch} | 0 ...on-for-horizontal-only-item-merging.patch} | 0 ...010-Add-skipping-world-symlink-scan.patch} | 0 ... 1011-Add-even-more-Enchantment-API.patch} | 0 ...ble-API.patch => 1012-Leashable-API.patch} | 0 ...=> 1013-Fix-CraftBukkit-drag-system.patch} | 0 ...ent-firing-for-block-entity-loading.patch} | 0 ...-lootable-item-function-from-compas.patch} | 0 ...016-Add-enchantment-seed-update-API.patch} | 0 ...ending-chat-to-client-with-updating.patch} | 0 ...Fix-InventoryOpenEvent-cancellation.patch} | 0 ...ire-BlockExpEvent-on-grindstone-use.patch} | 0 ... => 1020-Check-dead-flag-in-isAlive.patch} | 0 ...I.patch => 1021-Add-FeatureFlag-API.patch} | 0 ....patch => 1022-Tag-Lifecycle-Events.patch} | 0 ... => 1023-Item-serialization-as-json.patch} | 0 ...ate-slot-in-PlayerInventory-setSlot.patch} | 0 ...ll-time-unused-skip-tick-protection.patch} | 0 ...tty-printing-for-advancement-saving.patch} | 0 ...dPreprocessEvent-on-signed-commands.patch} | 0 ...evels-with-enchantment-registry-set.patch} | 0 ...h => 1029-Improve-entity-effect-API.patch} | 0 ...me.patch => 1030-Add-recipeBrewTime.patch} | 0 ...31-Call-bucket-events-for-cauldrons.patch} | 0 ...32-Add-PlayerInsertLecternBookEvent.patch} | 0 ... 1033-Void-damage-configuration-API.patch} | 0 ...I.patch => 1034-Add-Offline-PDC-API.patch} | 0 ...w-bypassEnchantmentLevelRestriction.patch} | 0 ...-proper-async-player-disconnections.patch} | 0 ...-send-Banner-patterns-to-the-client.patch} | 0 ...> 1038-Rewrite-dataconverter-system.patch} | 0 ... 1039-Moonrise-optimisation-patches.patch} | 10 +++--- ...> 1040-API-for-checking-sent-chunks.patch} | 0 ...041-Fix-CraftWorld-isChunkGenerated.patch} | 0 ...tup-flag-to-disable-gamerule-limits.patch} | 0 ...h => 1043-Improved-Watchdog-Support.patch} | 2 +- ...-more-information-in-watchdog-dumps.patch} | 0 ...45-Entity-load-save-limit-per-chunk.patch} | 0 ...ulate-regionfile-header-if-it-is-co.patch} | 0 ...le-spark.patch => 1047-Bundle-spark.patch} | 2 +- ...-Improve-performance-of-mass-crafts.patch} | 0 301 files changed, 42 insertions(+), 44 deletions(-) rename patches/{unapplied => }/api/0400-API-for-updating-recipes-on-clients.patch (100%) rename patches/api/{0400-Add-PlayerFailMoveEvent.patch => 0401-Add-PlayerFailMoveEvent.patch} (100%) rename patches/api/{0401-Fix-custom-statistic-criteria-creation.patch => 0402-Fix-custom-statistic-criteria-creation.patch} (100%) rename patches/api/{0402-SculkCatalyst-bloom-API.patch => 0403-SculkCatalyst-bloom-API.patch} (100%) rename patches/api/{0403-API-for-an-entity-s-scoreboard-name.patch => 0404-API-for-an-entity-s-scoreboard-name.patch} (100%) rename patches/api/{0404-Deprecate-and-replace-methods-with-old-StructureType.patch => 0405-Deprecate-and-replace-methods-with-old-StructureType.patch} (97%) rename patches/api/{0405-Add-Listing-API-for-Player.patch => 0406-Add-Listing-API-for-Player.patch} (100%) rename patches/api/{0406-Expose-clicked-BlockFace-during-BlockDamageEvent.patch => 0407-Expose-clicked-BlockFace-during-BlockDamageEvent.patch} (100%) rename patches/api/{0407-Fix-NPE-on-Boat-getStatus.patch => 0408-Fix-NPE-on-Boat-getStatus.patch} (100%) rename patches/api/{0408-Expand-Pose-API.patch => 0409-Expand-Pose-API.patch} (100%) rename patches/api/{0409-MerchantRecipe-add-copy-constructor.patch => 0410-MerchantRecipe-add-copy-constructor.patch} (100%) rename patches/api/{0410-More-DragonBattle-API.patch => 0411-More-DragonBattle-API.patch} (100%) rename patches/api/{0411-Add-PlayerPickItemEvent.patch => 0412-Add-PlayerPickItemEvent.patch} (100%) rename patches/api/{0412-Allow-trident-custom-damage.patch => 0413-Allow-trident-custom-damage.patch} (100%) rename patches/api/{0413-Expose-hand-during-BlockCanBuildEvent.patch => 0414-Expose-hand-during-BlockCanBuildEvent.patch} (100%) rename patches/api/{0414-Limit-setBurnTime-to-valid-short-values.patch => 0415-Limit-setBurnTime-to-valid-short-values.patch} (100%) rename patches/api/{0415-Add-OfflinePlayer-isConnected.patch => 0416-Add-OfflinePlayer-isConnected.patch} (100%) rename patches/api/{0416-Add-titleOverride-to-InventoryOpenEvent.patch => 0417-Add-titleOverride-to-InventoryOpenEvent.patch} (100%) rename patches/api/{0417-Allow-proper-checking-of-empty-item-stacks.patch => 0418-Allow-proper-checking-of-empty-item-stacks.patch} (100%) rename patches/api/{0418-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch => 0419-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch} (100%) rename patches/api/{0419-Add-player-idle-duration-API.patch => 0420-Add-player-idle-duration-API.patch} (100%) rename patches/api/{0420-Add-API-to-get-the-collision-shape-of-a-block-before.patch => 0421-Add-API-to-get-the-collision-shape-of-a-block-before.patch} (100%) rename patches/api/{0421-Add-predicate-for-blocks-when-raytracing.patch => 0422-Add-predicate-for-blocks-when-raytracing.patch} (100%) rename patches/api/{0422-Add-hand-to-fish-event-for-all-player-interactions.patch => 0423-Add-hand-to-fish-event-for-all-player-interactions.patch} (100%) rename patches/api/{0423-Attribute-Modifier-API-improvements.patch => 0424-Attribute-Modifier-API-improvements.patch} (100%) rename patches/api/{0424-Expand-LingeringPotion-API.patch => 0425-Expand-LingeringPotion-API.patch} (100%) rename patches/api/{0425-Remove-unnecessary-durability-check-in-ItemStack-isS.patch => 0426-Remove-unnecessary-durability-check-in-ItemStack-isS.patch} (100%) rename patches/api/{0426-Add-Structure-check-API.patch => 0427-Add-Structure-check-API.patch} (100%) rename patches/api/{0427-Experimental-annotations-change.patch => 0428-Experimental-annotations-change.patch} (100%) rename patches/api/{0428-Add-more-scoreboard-API.patch => 0429-Add-more-scoreboard-API.patch} (100%) rename patches/api/{0429-Improve-Registry.patch => 0430-Improve-Registry.patch} (100%) rename patches/api/{0430-Add-experience-points-API.patch => 0431-Add-experience-points-API.patch} (100%) rename patches/api/{0431-Add-missing-InventoryType.patch => 0432-Add-missing-InventoryType.patch} (100%) rename patches/api/{0432-Add-drops-to-shear-events.patch => 0433-Add-drops-to-shear-events.patch} (100%) rename patches/api/{0433-Add-HiddenPotionEffect-API.patch => 0434-Add-HiddenPotionEffect-API.patch} (100%) rename patches/api/{0434-Add-PlayerShieldDisableEvent.patch => 0435-Add-PlayerShieldDisableEvent.patch} (100%) rename patches/api/{0435-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch => 0436-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch} (100%) rename patches/api/{0436-Add-BlockStateMeta-clearBlockState.patch => 0437-Add-BlockStateMeta-clearBlockState.patch} (100%) rename patches/api/{0437-Expose-LootTable-of-DecoratedPot.patch => 0438-Expose-LootTable-of-DecoratedPot.patch} (100%) rename patches/api/{0438-Add-ShulkerDuplicateEvent.patch => 0439-Add-ShulkerDuplicateEvent.patch} (100%) rename patches/api/{0439-Add-api-for-spawn-egg-texture-colors.patch => 0440-Add-api-for-spawn-egg-texture-colors.patch} (100%) rename patches/api/{0440-Add-Lifecycle-Event-system.patch => 0441-Add-Lifecycle-Event-system.patch} (100%) rename patches/api/{0441-ItemStack-Tooltip-API.patch => 0442-ItemStack-Tooltip-API.patch} (100%) rename patches/api/{0442-Add-getChunkSnapshot-includeLightData-parameter.patch => 0443-Add-getChunkSnapshot-includeLightData-parameter.patch} (100%) rename patches/api/{0443-Add-FluidState-API.patch => 0444-Add-FluidState-API.patch} (100%) rename patches/api/{0444-add-number-format-api.patch => 0445-add-number-format-api.patch} (100%) rename patches/api/{0445-improve-BanList-types.patch => 0446-improve-BanList-types.patch} (94%) rename patches/api/{0446-Suspicious-Effect-Entry-API.patch => 0447-Suspicious-Effect-Entry-API.patch} (100%) rename patches/api/{0447-Fix-DamageSource-API.patch => 0448-Fix-DamageSource-API.patch} (100%) rename patches/api/{0448-Expanded-Hopper-API.patch => 0449-Expanded-Hopper-API.patch} (100%) rename patches/api/{0449-Clone-mutables-to-prevent-unexpected-issues.patch => 0450-Clone-mutables-to-prevent-unexpected-issues.patch} (100%) rename patches/api/{0450-Add-BlockBreakProgressUpdateEvent.patch => 0451-Add-BlockBreakProgressUpdateEvent.patch} (100%) rename patches/api/{0451-Deprecate-ItemStack-setType.patch => 0452-Deprecate-ItemStack-setType.patch} (100%) rename patches/api/{0452-Item-Mutation-Fixes.patch => 0453-Item-Mutation-Fixes.patch} (100%) rename patches/api/{0453-API-for-checking-sent-chunks.patch => 0454-API-for-checking-sent-chunks.patch} (100%) rename patches/api/{0454-Add-CartographyItemEvent.patch => 0455-Add-CartographyItemEvent.patch} (100%) rename patches/api/{0455-More-Raid-API.patch => 0456-More-Raid-API.patch} (100%) rename patches/api/{0456-Fix-SpawnerEntry-Equipment-API.patch => 0457-Fix-SpawnerEntry-Equipment-API.patch} (100%) rename patches/api/{0457-Fix-ItemFlags.patch => 0458-Fix-ItemFlags.patch} (100%) rename patches/api/{0458-Allow-modifying-library-loader-jars-bytecode.patch => 0459-Allow-modifying-library-loader-jars-bytecode.patch} (100%) rename patches/api/{0459-Add-hook-to-remap-library-jars.patch => 0460-Add-hook-to-remap-library-jars.patch} (100%) rename patches/api/{0460-Add-GameMode-isInvulnerable.patch => 0461-Add-GameMode-isInvulnerable.patch} (100%) rename patches/api/{0461-Expose-hasColor-to-leather-armor.patch => 0462-Expose-hasColor-to-leather-armor.patch} (100%) rename patches/api/{0462-Added-API-to-get-player-ha-proxy-address.patch => 0463-Added-API-to-get-player-ha-proxy-address.patch} (100%) rename patches/api/{0463-More-Chest-Block-API.patch => 0464-More-Chest-Block-API.patch} (100%) rename patches/api/{0464-Brigadier-based-command-API.patch => 0465-Brigadier-based-command-API.patch} (100%) rename patches/api/{0465-Fix-issues-with-recipe-API.patch => 0466-Fix-issues-with-recipe-API.patch} (100%) rename patches/api/{0466-Fix-equipment-slot-and-group-API.patch => 0467-Fix-equipment-slot-and-group-API.patch} (100%) rename patches/api/{0467-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch => 0468-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch} (100%) rename patches/api/{0468-General-ItemMeta-fixes.patch => 0469-General-ItemMeta-fixes.patch} (100%) rename patches/api/{0469-Add-missing-fishing-event-state.patch => 0470-Add-missing-fishing-event-state.patch} (100%) rename patches/api/{0470-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch => 0471-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch} (100%) rename patches/api/{0471-Registry-Modification-API.patch => 0472-Registry-Modification-API.patch} (100%) rename patches/api/{0472-Introduce-registry-entry-and-builders.patch => 0473-Introduce-registry-entry-and-builders.patch} (100%) rename patches/api/{0473-Proxy-ItemStack-to-CraftItemStack.patch => 0474-Proxy-ItemStack-to-CraftItemStack.patch} (100%) rename patches/api/{0474-Make-a-PDC-view-accessible-directly-from-ItemStack.patch => 0475-Make-a-PDC-view-accessible-directly-from-ItemStack.patch} (100%) rename patches/api/{0475-Fix-HelpCommand-searching.patch => 0476-Fix-HelpCommand-searching.patch} (100%) rename patches/api/{0476-add-Plugin-getDataPath.patch => 0477-add-Plugin-getDataPath.patch} (100%) rename patches/api/{0477-Fix-PickupStatus-getting-reset.patch => 0478-Fix-PickupStatus-getting-reset.patch} (100%) rename patches/api/{0478-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch => 0479-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch} (100%) rename patches/api/{0479-Improve-StandardMessenger-exception-messages.patch => 0480-Improve-StandardMessenger-exception-messages.patch} (100%) rename patches/api/{0480-Add-even-more-Enchantment-API.patch => 0481-Add-even-more-Enchantment-API.patch} (100%) rename patches/api/{0481-Leashable-API.patch => 0482-Leashable-API.patch} (100%) rename patches/api/{0482-Add-enchantment-seed-update-API.patch => 0483-Add-enchantment-seed-update-API.patch} (100%) rename patches/api/{0483-Deprecate-for-removal-all-OldEnum-related-methods.patch => 0484-Deprecate-for-removal-all-OldEnum-related-methods.patch} (100%) rename patches/api/{0484-Add-FeatureFlag-API.patch => 0485-Add-FeatureFlag-API.patch} (100%) rename patches/api/{0485-Tag-Lifecycle-Events.patch => 0486-Tag-Lifecycle-Events.patch} (100%) rename patches/api/{0486-Item-serialization-as-json.patch => 0487-Item-serialization-as-json.patch} (100%) rename patches/api/{0487-create-TileStateInventoryHolder.patch => 0488-create-TileStateInventoryHolder.patch} (100%) rename patches/api/{0488-Add-enchantWithLevels-with-enchantment-registry-set.patch => 0489-Add-enchantWithLevels-with-enchantment-registry-set.patch} (100%) rename patches/api/{0489-Improve-entity-effect-API.patch => 0490-Improve-entity-effect-API.patch} (100%) rename patches/api/{0490-Add-recipeBrewTime.patch => 0491-Add-recipeBrewTime.patch} (100%) rename patches/api/{0491-Add-PlayerInsertLecternBookEvent.patch => 0492-Add-PlayerInsertLecternBookEvent.patch} (100%) rename patches/api/{0492-Void-damage-configuration-API.patch => 0493-Void-damage-configuration-API.patch} (100%) rename patches/api/{0493-Add-Offline-PDC-API.patch => 0494-Add-Offline-PDC-API.patch} (100%) rename patches/api/{0494-Add-AnvilView-bypassEnchantmentLevelRestriction.patch => 0495-Add-AnvilView-bypassEnchantmentLevelRestriction.patch} (100%) rename patches/api/{0495-fix-DamageTypeTags-init.patch => 0496-fix-DamageTypeTags-init.patch} (100%) rename patches/{unapplied => }/server/0845-API-for-updating-recipes-on-clients.patch (73%) rename patches/server/{0845-Fix-custom-statistic-criteria-creation.patch => 0846-Fix-custom-statistic-criteria-creation.patch} (100%) rename patches/server/{0846-Bandaid-fix-for-Effect.patch => 0847-Bandaid-fix-for-Effect.patch} (100%) rename patches/server/{0847-SculkCatalyst-bloom-API.patch => 0848-SculkCatalyst-bloom-API.patch} (100%) rename patches/server/{0848-API-for-an-entity-s-scoreboard-name.patch => 0849-API-for-an-entity-s-scoreboard-name.patch} (100%) rename patches/server/{0849-Deprecate-and-replace-methods-with-old-StructureType.patch => 0850-Deprecate-and-replace-methods-with-old-StructureType.patch} (92%) rename patches/server/{0850-Don-t-tab-complete-namespaced-commands-if-send-names.patch => 0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch} (100%) rename patches/server/{0851-Properly-handle-BlockBreakEvent-isDropItems.patch => 0852-Properly-handle-BlockBreakEvent-isDropItems.patch} (100%) rename patches/server/{0852-Fire-entity-death-event-for-ender-dragon.patch => 0853-Fire-entity-death-event-for-ender-dragon.patch} (100%) rename patches/server/{0853-Configurable-entity-tracking-range-by-Y-coordinate.patch => 0854-Configurable-entity-tracking-range-by-Y-coordinate.patch} (100%) rename patches/server/{0854-Add-Listing-API-for-Player.patch => 0855-Add-Listing-API-for-Player.patch} (99%) rename patches/server/{0855-Configurable-Region-Compression-Format.patch => 0856-Configurable-Region-Compression-Format.patch} (100%) rename patches/server/{0856-Add-BlockFace-to-BlockDamageEvent.patch => 0857-Add-BlockFace-to-BlockDamageEvent.patch} (100%) rename patches/server/{0857-Fix-NPE-on-Boat-getStatus.patch => 0858-Fix-NPE-on-Boat-getStatus.patch} (100%) rename patches/server/{0858-Expand-Pose-API.patch => 0859-Expand-Pose-API.patch} (100%) rename patches/server/{0859-More-DragonBattle-API.patch => 0860-More-DragonBattle-API.patch} (100%) rename patches/server/{0860-Add-PlayerPickItemEvent.patch => 0861-Add-PlayerPickItemEvent.patch} (100%) rename patches/server/{0861-Allow-trident-custom-damage.patch => 0862-Allow-trident-custom-damage.patch} (100%) rename patches/server/{0862-Expose-hand-in-BlockCanBuildEvent.patch => 0863-Expose-hand-in-BlockCanBuildEvent.patch} (100%) rename patches/server/{0863-Optimize-nearest-structure-border-iteration.patch => 0864-Optimize-nearest-structure-border-iteration.patch} (100%) rename patches/server/{0864-Implement-OfflinePlayer-isConnected.patch => 0865-Implement-OfflinePlayer-isConnected.patch} (100%) rename patches/server/{0865-Fix-slot-desync.patch => 0866-Fix-slot-desync.patch} (100%) rename patches/server/{0866-Add-titleOverride-to-InventoryOpenEvent.patch => 0867-Add-titleOverride-to-InventoryOpenEvent.patch} (100%) rename patches/server/{0867-Configure-sniffer-egg-hatch-time.patch => 0868-Configure-sniffer-egg-hatch-time.patch} (100%) rename patches/server/{0868-Do-crystal-portal-proximity-check-before-entity-look.patch => 0869-Do-crystal-portal-proximity-check-before-entity-look.patch} (100%) rename patches/server/{0869-Skip-POI-finding-if-stuck-in-vehicle.patch => 0870-Skip-POI-finding-if-stuck-in-vehicle.patch} (100%) rename patches/server/{0870-Add-slot-sanity-checks-in-container-clicks.patch => 0871-Add-slot-sanity-checks-in-container-clicks.patch} (100%) rename patches/server/{0871-Call-BlockRedstoneEvents-for-lecterns.patch => 0872-Call-BlockRedstoneEvents-for-lecterns.patch} (100%) rename patches/server/{0872-Allow-proper-checking-of-empty-item-stacks.patch => 0873-Allow-proper-checking-of-empty-item-stacks.patch} (100%) rename patches/server/{0873-Fix-silent-equipment-change-for-mobs.patch => 0874-Fix-silent-equipment-change-for-mobs.patch} (100%) rename patches/server/{0874-Fix-spigot-s-Forced-Stats.patch => 0875-Fix-spigot-s-Forced-Stats.patch} (100%) rename patches/server/{0875-Add-missing-InventoryHolders-to-inventories.patch => 0876-Add-missing-InventoryHolders-to-inventories.patch} (100%) rename patches/server/{0876-Do-not-read-tile-entities-in-chunks-that-are-positio.patch => 0877-Do-not-read-tile-entities-in-chunks-that-are-positio.patch} (100%) rename patches/server/{0877-Add-missing-logs-for-log-ips-config-option.patch => 0878-Add-missing-logs-for-log-ips-config-option.patch} (100%) rename patches/server/{0878-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch => 0879-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch} (100%) rename patches/server/{0879-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch => 0880-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch} (100%) rename patches/server/{0880-Fix-team-sidebar-objectives-not-being-cleared.patch => 0881-Fix-team-sidebar-objectives-not-being-cleared.patch} (100%) rename patches/server/{0881-Fix-missing-map-initialize-event-call.patch => 0882-Fix-missing-map-initialize-event-call.patch} (100%) rename patches/server/{0882-Update-entity-data-when-attaching-firework-to-entity.patch => 0883-Update-entity-data-when-attaching-firework-to-entity.patch} (100%) rename patches/server/{0883-Fix-UnsafeValues-loadAdvancement.patch => 0884-Fix-UnsafeValues-loadAdvancement.patch} (100%) rename patches/server/{0884-Add-player-idle-duration-API.patch => 0885-Add-player-idle-duration-API.patch} (100%) rename patches/server/{0885-Don-t-check-if-we-can-see-non-visible-entities.patch => 0886-Don-t-check-if-we-can-see-non-visible-entities.patch} (100%) rename patches/server/{0886-Fix-NPE-in-SculkBloomEvent-world-access.patch => 0887-Fix-NPE-in-SculkBloomEvent-world-access.patch} (100%) rename patches/server/{0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch => 0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch} (100%) rename patches/server/{0888-Optimize-VarInts.patch => 0889-Optimize-VarInts.patch} (100%) rename patches/server/{0889-Add-API-to-get-the-collision-shape-of-a-block-before.patch => 0890-Add-API-to-get-the-collision-shape-of-a-block-before.patch} (100%) rename patches/server/{0890-Add-predicate-for-blocks-when-raytracing.patch => 0891-Add-predicate-for-blocks-when-raytracing.patch} (100%) rename patches/server/{0891-Broadcast-take-item-packets-with-collector-as-source.patch => 0892-Broadcast-take-item-packets-with-collector-as-source.patch} (100%) rename patches/server/{0892-Expand-LingeringPotion-API.patch => 0893-Expand-LingeringPotion-API.patch} (100%) rename patches/server/{0893-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch => 0894-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch} (100%) rename patches/server/{0894-Add-hand-to-fish-event-for-all-player-interactions.patch => 0895-Add-hand-to-fish-event-for-all-player-interactions.patch} (100%) rename patches/server/{0895-Fix-several-issues-with-EntityBreedEvent.patch => 0896-Fix-several-issues-with-EntityBreedEvent.patch} (100%) rename patches/server/{0896-Add-UUID-attribute-modifier-API.patch => 0897-Add-UUID-attribute-modifier-API.patch} (100%) rename patches/server/{0897-Fix-missing-event-call-for-entity-teleport-API.patch => 0898-Fix-missing-event-call-for-entity-teleport-API.patch} (100%) rename patches/server/{0898-Lazily-create-LootContext-for-criterions.patch => 0899-Lazily-create-LootContext-for-criterions.patch} (100%) rename patches/server/{0899-Don-t-fire-sync-events-during-worldgen.patch => 0900-Don-t-fire-sync-events-during-worldgen.patch} (100%) rename patches/server/{0900-Add-Structure-check-API.patch => 0901-Add-Structure-check-API.patch} (100%) rename patches/server/{0901-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch => 0902-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch} (100%) rename patches/server/{0902-Restore-vanilla-entity-drops-behavior.patch => 0903-Restore-vanilla-entity-drops-behavior.patch} (100%) rename patches/server/{0903-Dont-resend-blocks-on-interactions.patch => 0904-Dont-resend-blocks-on-interactions.patch} (100%) rename patches/server/{0904-add-more-scoreboard-API.patch => 0905-add-more-scoreboard-API.patch} (100%) rename patches/server/{0905-Improve-Registry.patch => 0906-Improve-Registry.patch} (100%) rename patches/server/{0906-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch => 0907-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch} (100%) rename patches/server/{0907-Add-experience-points-API.patch => 0908-Add-experience-points-API.patch} (100%) rename patches/server/{0908-Add-drops-to-shear-events.patch => 0909-Add-drops-to-shear-events.patch} (100%) rename patches/server/{0909-Add-PlayerShieldDisableEvent.patch => 0910-Add-PlayerShieldDisableEvent.patch} (100%) rename patches/server/{0910-Validate-ResourceLocation-in-NBT-reading.patch => 0911-Validate-ResourceLocation-in-NBT-reading.patch} (100%) rename patches/server/{0911-Properly-handle-experience-dropping-on-block-break.patch => 0912-Properly-handle-experience-dropping-on-block-break.patch} (100%) rename patches/server/{0912-Fixup-NamespacedKey-handling.patch => 0913-Fixup-NamespacedKey-handling.patch} (100%) rename patches/server/{0913-Expose-LootTable-of-DecoratedPot.patch => 0914-Expose-LootTable-of-DecoratedPot.patch} (100%) rename patches/server/{0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch => 0915-Reduce-allocation-of-Vec3D-by-entity-tracker.patch} (100%) rename patches/server/{0915-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch => 0916-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch} (100%) rename patches/server/{0916-Add-ShulkerDuplicateEvent.patch => 0917-Add-ShulkerDuplicateEvent.patch} (100%) rename patches/server/{0917-Add-api-for-spawn-egg-texture-colors.patch => 0918-Add-api-for-spawn-egg-texture-colors.patch} (100%) rename patches/server/{0918-Add-Lifecycle-Event-system.patch => 0919-Add-Lifecycle-Event-system.patch} (99%) rename patches/server/{0919-ItemStack-Tooltip-API.patch => 0920-ItemStack-Tooltip-API.patch} (100%) rename patches/server/{0920-Add-getChunkSnapshot-includeLightData-parameter.patch => 0921-Add-getChunkSnapshot-includeLightData-parameter.patch} (100%) rename patches/server/{0921-Add-FluidState-API.patch => 0922-Add-FluidState-API.patch} (100%) rename patches/server/{0922-add-number-format-api.patch => 0923-add-number-format-api.patch} (100%) rename patches/server/{0923-improve-BanList-types.patch => 0924-improve-BanList-types.patch} (89%) rename patches/server/{0924-Expanded-Hopper-API.patch => 0925-Expanded-Hopper-API.patch} (100%) rename patches/server/{0925-Add-BlockBreakProgressUpdateEvent.patch => 0926-Add-BlockBreakProgressUpdateEvent.patch} (100%) rename patches/server/{0926-Deprecate-ItemStack-setType.patch => 0927-Deprecate-ItemStack-setType.patch} (100%) rename patches/server/{0927-Add-CartographyItemEvent.patch => 0928-Add-CartographyItemEvent.patch} (100%) rename patches/server/{0928-More-Raid-API.patch => 0929-More-Raid-API.patch} (100%) rename patches/server/{0929-Add-onboarding-message-for-initial-server-start.patch => 0930-Add-onboarding-message-for-initial-server-start.patch} (100%) rename patches/server/{0930-Configurable-max-block-fluid-ticks.patch => 0931-Configurable-max-block-fluid-ticks.patch} (100%) rename patches/server/{0931-Fix-bees-aging-inside-hives.patch => 0932-Fix-bees-aging-inside-hives.patch} (100%) rename patches/server/{0932-Disable-memory-reserve-allocating.patch => 0933-Disable-memory-reserve-allocating.patch} (100%) rename patches/server/{0933-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch => 0934-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch} (100%) rename patches/server/{0934-Fix-DamageSource-API.patch => 0935-Fix-DamageSource-API.patch} (100%) rename patches/server/{0935-Fix-creation-of-invalid-block-entity-during-world-ge.patch => 0936-Fix-creation-of-invalid-block-entity-during-world-ge.patch} (100%) rename patches/server/{0936-Fix-possible-StackOverflowError-for-some-dispenses.patch => 0937-Fix-possible-StackOverflowError-for-some-dispenses.patch} (100%) rename patches/server/{0937-Improve-tag-parser-handling.patch => 0938-Improve-tag-parser-handling.patch} (100%) rename patches/server/{0938-Item-Mutation-Fixes.patch => 0939-Item-Mutation-Fixes.patch} (100%) rename patches/server/{0939-Per-world-ticks-per-spawn-settings.patch => 0940-Per-world-ticks-per-spawn-settings.patch} (100%) rename patches/server/{0940-Properly-track-the-changed-item-from-dispense-events.patch => 0941-Properly-track-the-changed-item-from-dispense-events.patch} (100%) rename patches/server/{0941-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch => 0942-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch} (100%) rename patches/server/{0942-Add-config-for-mobs-immune-to-default-effects.patch => 0943-Add-config-for-mobs-immune-to-default-effects.patch} (100%) rename patches/server/{0943-Deep-clone-nbt-tags-in-PDC.patch => 0944-Deep-clone-nbt-tags-in-PDC.patch} (100%) rename patches/server/{0944-Support-old-UUID-format-for-NBT.patch => 0945-Support-old-UUID-format-for-NBT.patch} (100%) rename patches/server/{0945-Fix-shield-disable-inconsistency.patch => 0946-Fix-shield-disable-inconsistency.patch} (100%) rename patches/server/{0946-Handle-Large-Packets-disconnecting-client.patch => 0947-Handle-Large-Packets-disconnecting-client.patch} (100%) rename patches/server/{0947-Fix-ItemFlags.patch => 0948-Fix-ItemFlags.patch} (100%) rename patches/server/{0948-Fix-helmet-damage-reduction-inconsistencies.patch => 0949-Fix-helmet-damage-reduction-inconsistencies.patch} (100%) rename patches/server/{0949-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch => 0950-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch} (100%) rename patches/server/{0950-improve-checking-handled-tags-in-itemmeta.patch => 0951-improve-checking-handled-tags-in-itemmeta.patch} (100%) rename patches/server/{0951-Expose-hasColor-to-leather-armor.patch => 0952-Expose-hasColor-to-leather-armor.patch} (100%) rename patches/server/{0952-Added-API-to-get-player-ha-proxy-address.patch => 0953-Added-API-to-get-player-ha-proxy-address.patch} (100%) rename patches/server/{0953-General-ItemMeta-fixes.patch => 0954-General-ItemMeta-fixes.patch} (100%) rename patches/server/{0954-More-Chest-Block-API.patch => 0955-More-Chest-Block-API.patch} (100%) rename patches/server/{0955-Print-data-component-type-on-encoding-error.patch => 0956-Print-data-component-type-on-encoding-error.patch} (100%) rename patches/server/{0956-Brigadier-based-command-API.patch => 0957-Brigadier-based-command-API.patch} (99%) rename patches/server/{0957-Fix-issues-with-Recipe-API.patch => 0958-Fix-issues-with-Recipe-API.patch} (100%) rename patches/server/{0958-Fix-equipment-slot-and-group-API.patch => 0959-Fix-equipment-slot-and-group-API.patch} (100%) rename patches/server/{0959-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch => 0960-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch} (100%) rename patches/server/{0960-Prevent-sending-oversized-item-data-in-equipment-and.patch => 0961-Prevent-sending-oversized-item-data-in-equipment-and.patch} (100%) rename patches/server/{0961-Prevent-NPE-if-hooked-entity-was-cleared.patch => 0962-Prevent-NPE-if-hooked-entity-was-cleared.patch} (100%) rename patches/server/{0962-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch => 0963-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch} (100%) rename patches/server/{0963-Add-missing-fishing-event-state.patch => 0964-Add-missing-fishing-event-state.patch} (100%) rename patches/server/{0964-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch => 0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch} (100%) rename patches/server/{0965-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch => 0966-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch} (100%) rename patches/server/{0966-Adopt-MaterialRerouting.patch => 0967-Adopt-MaterialRerouting.patch} (100%) rename patches/server/{0967-Suspicious-Effect-Entry-API.patch => 0968-Suspicious-Effect-Entry-API.patch} (100%) rename patches/server/{0968-check-if-itemstack-is-stackable-first.patch => 0969-check-if-itemstack-is-stackable-first.patch} (100%) rename patches/server/{0969-Fix-removing-recipes-from-RecipeIterator.patch => 0970-Fix-removing-recipes-from-RecipeIterator.patch} (100%) rename patches/server/{0970-Configurable-damage-tick-when-blocking-with-shield.patch => 0971-Configurable-damage-tick-when-blocking-with-shield.patch} (100%) rename patches/server/{0971-Properly-remove-the-experimental-smithing-inventory-.patch => 0972-Properly-remove-the-experimental-smithing-inventory-.patch} (100%) rename patches/server/{0972-disable-forced-empty-world-ticks.patch => 0973-disable-forced-empty-world-ticks.patch} (100%) rename patches/server/{0973-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch => 0974-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch} (100%) rename patches/server/{0974-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch => 0975-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch} (100%) rename patches/server/{0975-Optimize-Network-Manager-and-add-advanced-packet-sup.patch => 0976-Optimize-Network-Manager-and-add-advanced-packet-sup.patch} (100%) rename patches/server/{0976-Allow-Saving-of-Oversized-Chunks.patch => 0977-Allow-Saving-of-Oversized-Chunks.patch} (100%) rename patches/server/{0977-Flat-bedrock-generator-settings.patch => 0978-Flat-bedrock-generator-settings.patch} (100%) rename patches/server/{0978-Entity-Activation-Range-2.0.patch => 0979-Entity-Activation-Range-2.0.patch} (100%) rename patches/server/{0979-Anti-Xray.patch => 0980-Anti-Xray.patch} (99%) rename patches/server/{0980-Use-Velocity-compression-and-cipher-natives.patch => 0981-Use-Velocity-compression-and-cipher-natives.patch} (100%) rename patches/server/{0981-Optimize-Collision-to-not-load-chunks.patch => 0982-Optimize-Collision-to-not-load-chunks.patch} (98%) rename patches/server/{0982-Optimize-GoalSelector-Goal.Flag-Set-operations.patch => 0983-Optimize-GoalSelector-Goal.Flag-Set-operations.patch} (100%) rename patches/server/{0983-Optimize-Hoppers.patch => 0984-Optimize-Hoppers.patch} (100%) rename patches/server/{0984-Optimize-Voxel-Shape-Merging.patch => 0985-Optimize-Voxel-Shape-Merging.patch} (100%) rename patches/server/{0985-Optimize-Bit-Operations-by-inlining.patch => 0986-Optimize-Bit-Operations-by-inlining.patch} (100%) rename patches/server/{0986-Remove-streams-from-hot-code.patch => 0987-Remove-streams-from-hot-code.patch} (100%) rename patches/server/{0987-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch => 0988-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch} (100%) rename patches/server/{0988-Fix-entity-type-tags-suggestions-in-selectors.patch => 0989-Fix-entity-type-tags-suggestions-in-selectors.patch} (100%) rename patches/server/{0989-Handle-Oversized-block-entities-in-chunks.patch => 0990-Handle-Oversized-block-entities-in-chunks.patch} (100%) rename patches/server/{0990-Check-distance-in-entity-interactions.patch => 0991-Check-distance-in-entity-interactions.patch} (100%) rename patches/server/{0991-Configurable-Sand-Duping.patch => 0992-Configurable-Sand-Duping.patch} (100%) rename patches/server/{0992-Properly-resend-entities.patch => 0993-Properly-resend-entities.patch} (99%) rename patches/server/{0993-Registry-Modification-API.patch => 0994-Registry-Modification-API.patch} (100%) rename patches/server/{0994-Add-registry-entry-and-builders.patch => 0995-Add-registry-entry-and-builders.patch} (100%) rename patches/server/{0995-Proxy-ItemStack-to-CraftItemStack.patch => 0996-Proxy-ItemStack-to-CraftItemStack.patch} (100%) rename patches/server/{0996-Make-a-PDC-view-accessible-directly-from-ItemStack.patch => 0997-Make-a-PDC-view-accessible-directly-from-ItemStack.patch} (100%) rename patches/server/{0997-Prioritize-Minecraft-commands-in-function-parsing-an.patch => 0998-Prioritize-Minecraft-commands-in-function-parsing-an.patch} (100%) rename patches/server/{0998-optimize-dirt-and-snow-spreading.patch => 0999-optimize-dirt-and-snow-spreading.patch} (100%) rename patches/server/{0999-Fix-NPE-for-Jukebox-setRecord.patch => 1000-Fix-NPE-for-Jukebox-setRecord.patch} (100%) rename patches/server/{1000-fix-horse-inventories.patch => 1001-fix-horse-inventories.patch} (100%) rename patches/server/{1001-Only-call-EntityDamageEvents-before-actuallyHurt.patch => 1002-Only-call-EntityDamageEvents-before-actuallyHurt.patch} (100%) rename patches/server/{1002-Add-ItemType-getItemRarity.patch => 1003-Add-ItemType-getItemRarity.patch} (100%) rename patches/server/{1003-Add-plugin-info-at-startup.patch => 1004-Add-plugin-info-at-startup.patch} (100%) rename patches/server/{1004-Make-interaction-leniency-distance-configurable.patch => 1005-Make-interaction-leniency-distance-configurable.patch} (100%) rename patches/server/{1005-Fix-PickupStatus-getting-reset.patch => 1006-Fix-PickupStatus-getting-reset.patch} (100%) rename patches/server/{1006-Check-for-block-type-in-SculkSensorBlock-canActivate.patch => 1007-Check-for-block-type-in-SculkSensorBlock-canActivate.patch} (100%) rename patches/server/{1007-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch => 1008-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch} (100%) rename patches/server/{1008-Configuration-for-horizontal-only-item-merging.patch => 1009-Configuration-for-horizontal-only-item-merging.patch} (100%) rename patches/server/{1009-Add-skipping-world-symlink-scan.patch => 1010-Add-skipping-world-symlink-scan.patch} (100%) rename patches/server/{1010-Add-even-more-Enchantment-API.patch => 1011-Add-even-more-Enchantment-API.patch} (100%) rename patches/server/{1011-Leashable-API.patch => 1012-Leashable-API.patch} (100%) rename patches/server/{1012-Fix-CraftBukkit-drag-system.patch => 1013-Fix-CraftBukkit-drag-system.patch} (100%) rename patches/server/{1013-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch => 1014-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch} (100%) rename patches/server/{1014-Remove-set-damage-lootable-item-function-from-compas.patch => 1015-Remove-set-damage-lootable-item-function-from-compas.patch} (100%) rename patches/server/{1015-Add-enchantment-seed-update-API.patch => 1016-Add-enchantment-seed-update-API.patch} (100%) rename patches/server/{1016-Fix-synchronise-sending-chat-to-client-with-updating.patch => 1017-Fix-synchronise-sending-chat-to-client-with-updating.patch} (100%) rename patches/server/{1017-Fix-InventoryOpenEvent-cancellation.patch => 1018-Fix-InventoryOpenEvent-cancellation.patch} (100%) rename patches/server/{1018-Fire-BlockExpEvent-on-grindstone-use.patch => 1019-Fire-BlockExpEvent-on-grindstone-use.patch} (100%) rename patches/server/{1019-Check-dead-flag-in-isAlive.patch => 1020-Check-dead-flag-in-isAlive.patch} (100%) rename patches/server/{1020-Add-FeatureFlag-API.patch => 1021-Add-FeatureFlag-API.patch} (100%) rename patches/server/{1021-Tag-Lifecycle-Events.patch => 1022-Tag-Lifecycle-Events.patch} (100%) rename patches/server/{1022-Item-serialization-as-json.patch => 1023-Item-serialization-as-json.patch} (100%) rename patches/server/{1023-Validate-slot-in-PlayerInventory-setSlot.patch => 1024-Validate-slot-in-PlayerInventory-setSlot.patch} (100%) rename patches/server/{1024-Remove-wall-time-unused-skip-tick-protection.patch => 1025-Remove-wall-time-unused-skip-tick-protection.patch} (100%) rename patches/server/{1025-Disable-pretty-printing-for-advancement-saving.patch => 1026-Disable-pretty-printing-for-advancement-saving.patch} (100%) rename patches/server/{1026-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch => 1027-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch} (100%) rename patches/server/{1027-Add-enchantWithLevels-with-enchantment-registry-set.patch => 1028-Add-enchantWithLevels-with-enchantment-registry-set.patch} (100%) rename patches/server/{1028-Improve-entity-effect-API.patch => 1029-Improve-entity-effect-API.patch} (100%) rename patches/server/{1029-Add-recipeBrewTime.patch => 1030-Add-recipeBrewTime.patch} (100%) rename patches/server/{1030-Call-bucket-events-for-cauldrons.patch => 1031-Call-bucket-events-for-cauldrons.patch} (100%) rename patches/server/{1031-Add-PlayerInsertLecternBookEvent.patch => 1032-Add-PlayerInsertLecternBookEvent.patch} (100%) rename patches/server/{1032-Void-damage-configuration-API.patch => 1033-Void-damage-configuration-API.patch} (100%) rename patches/server/{1033-Add-Offline-PDC-API.patch => 1034-Add-Offline-PDC-API.patch} (100%) rename patches/server/{1034-Add-AnvilView-bypassEnchantmentLevelRestriction.patch => 1035-Add-AnvilView-bypassEnchantmentLevelRestriction.patch} (100%) rename patches/server/{1035-Add-proper-async-player-disconnections.patch => 1036-Add-proper-async-player-disconnections.patch} (100%) rename patches/server/{1036-Always-send-Banner-patterns-to-the-client.patch => 1037-Always-send-Banner-patterns-to-the-client.patch} (100%) rename patches/server/{1037-Rewrite-dataconverter-system.patch => 1038-Rewrite-dataconverter-system.patch} (100%) rename patches/server/{1038-Moonrise-optimisation-patches.patch => 1039-Moonrise-optimisation-patches.patch} (99%) rename patches/server/{1039-API-for-checking-sent-chunks.patch => 1040-API-for-checking-sent-chunks.patch} (100%) rename patches/server/{1040-Fix-CraftWorld-isChunkGenerated.patch => 1041-Fix-CraftWorld-isChunkGenerated.patch} (100%) rename patches/server/{1041-Add-startup-flag-to-disable-gamerule-limits.patch => 1042-Add-startup-flag-to-disable-gamerule-limits.patch} (100%) rename patches/server/{1042-Improved-Watchdog-Support.patch => 1043-Improved-Watchdog-Support.patch} (99%) rename patches/server/{1043-Detail-more-information-in-watchdog-dumps.patch => 1044-Detail-more-information-in-watchdog-dumps.patch} (100%) rename patches/server/{1044-Entity-load-save-limit-per-chunk.patch => 1045-Entity-load-save-limit-per-chunk.patch} (100%) rename patches/server/{1045-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch => 1046-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch} (100%) rename patches/server/{1046-Bundle-spark.patch => 1047-Bundle-spark.patch} (99%) rename patches/server/{1047-Improve-performance-of-mass-crafts.patch => 1048-Improve-performance-of-mass-crafts.patch} (100%) diff --git a/patches/unapplied/api/0400-API-for-updating-recipes-on-clients.patch b/patches/api/0400-API-for-updating-recipes-on-clients.patch similarity index 100% rename from patches/unapplied/api/0400-API-for-updating-recipes-on-clients.patch rename to patches/api/0400-API-for-updating-recipes-on-clients.patch diff --git a/patches/api/0400-Add-PlayerFailMoveEvent.patch b/patches/api/0401-Add-PlayerFailMoveEvent.patch similarity index 100% rename from patches/api/0400-Add-PlayerFailMoveEvent.patch rename to patches/api/0401-Add-PlayerFailMoveEvent.patch diff --git a/patches/api/0401-Fix-custom-statistic-criteria-creation.patch b/patches/api/0402-Fix-custom-statistic-criteria-creation.patch similarity index 100% rename from patches/api/0401-Fix-custom-statistic-criteria-creation.patch rename to patches/api/0402-Fix-custom-statistic-criteria-creation.patch diff --git a/patches/api/0402-SculkCatalyst-bloom-API.patch b/patches/api/0403-SculkCatalyst-bloom-API.patch similarity index 100% rename from patches/api/0402-SculkCatalyst-bloom-API.patch rename to patches/api/0403-SculkCatalyst-bloom-API.patch diff --git a/patches/api/0403-API-for-an-entity-s-scoreboard-name.patch b/patches/api/0404-API-for-an-entity-s-scoreboard-name.patch similarity index 100% rename from patches/api/0403-API-for-an-entity-s-scoreboard-name.patch rename to patches/api/0404-API-for-an-entity-s-scoreboard-name.patch diff --git a/patches/api/0404-Deprecate-and-replace-methods-with-old-StructureType.patch b/patches/api/0405-Deprecate-and-replace-methods-with-old-StructureType.patch similarity index 97% rename from patches/api/0404-Deprecate-and-replace-methods-with-old-StructureType.patch rename to patches/api/0405-Deprecate-and-replace-methods-with-old-StructureType.patch index f09ff7714f41..a832ca9f1d91 100644 --- a/patches/api/0404-Deprecate-and-replace-methods-with-old-StructureType.patch +++ b/patches/api/0405-Deprecate-and-replace-methods-with-old-StructureType.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Deprecate and replace methods with old StructureType diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 50efe16bb80c618c3dfae03b70c8c165183af8ec..85ad1f7f0de9a6f9048981c3ee509b42ddbeef1a 100644 +index 52c601328bbf5c1642aa620c8bb466a9d2d231be..c8fa12acaf52cd3923a7a8702ccc50cfdc9170a2 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java @@ -949,9 +949,6 @@ public final class Bukkit { @@ -84,7 +84,7 @@ index 50efe16bb80c618c3dfae03b70c8c165183af8ec..85ad1f7f0de9a6f9048981c3ee509b42 /** * Reloads the server, refreshing settings and plugin information. diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 1b8d6a3333a4fa9155b79644e683e2343c134e12..640ef81d204f480f4af83d420c7e968ce569a38d 100644 +index 8ba2fbaab7428a42b506fd000fbc162f68ddaed1..50ffca9bccfb582d58ccb13f0decf66e5d91aef3 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -817,16 +817,15 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi diff --git a/patches/api/0405-Add-Listing-API-for-Player.patch b/patches/api/0406-Add-Listing-API-for-Player.patch similarity index 100% rename from patches/api/0405-Add-Listing-API-for-Player.patch rename to patches/api/0406-Add-Listing-API-for-Player.patch diff --git a/patches/api/0406-Expose-clicked-BlockFace-during-BlockDamageEvent.patch b/patches/api/0407-Expose-clicked-BlockFace-during-BlockDamageEvent.patch similarity index 100% rename from patches/api/0406-Expose-clicked-BlockFace-during-BlockDamageEvent.patch rename to patches/api/0407-Expose-clicked-BlockFace-during-BlockDamageEvent.patch diff --git a/patches/api/0407-Fix-NPE-on-Boat-getStatus.patch b/patches/api/0408-Fix-NPE-on-Boat-getStatus.patch similarity index 100% rename from patches/api/0407-Fix-NPE-on-Boat-getStatus.patch rename to patches/api/0408-Fix-NPE-on-Boat-getStatus.patch diff --git a/patches/api/0408-Expand-Pose-API.patch b/patches/api/0409-Expand-Pose-API.patch similarity index 100% rename from patches/api/0408-Expand-Pose-API.patch rename to patches/api/0409-Expand-Pose-API.patch diff --git a/patches/api/0409-MerchantRecipe-add-copy-constructor.patch b/patches/api/0410-MerchantRecipe-add-copy-constructor.patch similarity index 100% rename from patches/api/0409-MerchantRecipe-add-copy-constructor.patch rename to patches/api/0410-MerchantRecipe-add-copy-constructor.patch diff --git a/patches/api/0410-More-DragonBattle-API.patch b/patches/api/0411-More-DragonBattle-API.patch similarity index 100% rename from patches/api/0410-More-DragonBattle-API.patch rename to patches/api/0411-More-DragonBattle-API.patch diff --git a/patches/api/0411-Add-PlayerPickItemEvent.patch b/patches/api/0412-Add-PlayerPickItemEvent.patch similarity index 100% rename from patches/api/0411-Add-PlayerPickItemEvent.patch rename to patches/api/0412-Add-PlayerPickItemEvent.patch diff --git a/patches/api/0412-Allow-trident-custom-damage.patch b/patches/api/0413-Allow-trident-custom-damage.patch similarity index 100% rename from patches/api/0412-Allow-trident-custom-damage.patch rename to patches/api/0413-Allow-trident-custom-damage.patch diff --git a/patches/api/0413-Expose-hand-during-BlockCanBuildEvent.patch b/patches/api/0414-Expose-hand-during-BlockCanBuildEvent.patch similarity index 100% rename from patches/api/0413-Expose-hand-during-BlockCanBuildEvent.patch rename to patches/api/0414-Expose-hand-during-BlockCanBuildEvent.patch diff --git a/patches/api/0414-Limit-setBurnTime-to-valid-short-values.patch b/patches/api/0415-Limit-setBurnTime-to-valid-short-values.patch similarity index 100% rename from patches/api/0414-Limit-setBurnTime-to-valid-short-values.patch rename to patches/api/0415-Limit-setBurnTime-to-valid-short-values.patch diff --git a/patches/api/0415-Add-OfflinePlayer-isConnected.patch b/patches/api/0416-Add-OfflinePlayer-isConnected.patch similarity index 100% rename from patches/api/0415-Add-OfflinePlayer-isConnected.patch rename to patches/api/0416-Add-OfflinePlayer-isConnected.patch diff --git a/patches/api/0416-Add-titleOverride-to-InventoryOpenEvent.patch b/patches/api/0417-Add-titleOverride-to-InventoryOpenEvent.patch similarity index 100% rename from patches/api/0416-Add-titleOverride-to-InventoryOpenEvent.patch rename to patches/api/0417-Add-titleOverride-to-InventoryOpenEvent.patch diff --git a/patches/api/0417-Allow-proper-checking-of-empty-item-stacks.patch b/patches/api/0418-Allow-proper-checking-of-empty-item-stacks.patch similarity index 100% rename from patches/api/0417-Allow-proper-checking-of-empty-item-stacks.patch rename to patches/api/0418-Allow-proper-checking-of-empty-item-stacks.patch diff --git a/patches/api/0418-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch b/patches/api/0419-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch similarity index 100% rename from patches/api/0418-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch rename to patches/api/0419-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch diff --git a/patches/api/0419-Add-player-idle-duration-API.patch b/patches/api/0420-Add-player-idle-duration-API.patch similarity index 100% rename from patches/api/0419-Add-player-idle-duration-API.patch rename to patches/api/0420-Add-player-idle-duration-API.patch diff --git a/patches/api/0420-Add-API-to-get-the-collision-shape-of-a-block-before.patch b/patches/api/0421-Add-API-to-get-the-collision-shape-of-a-block-before.patch similarity index 100% rename from patches/api/0420-Add-API-to-get-the-collision-shape-of-a-block-before.patch rename to patches/api/0421-Add-API-to-get-the-collision-shape-of-a-block-before.patch diff --git a/patches/api/0421-Add-predicate-for-blocks-when-raytracing.patch b/patches/api/0422-Add-predicate-for-blocks-when-raytracing.patch similarity index 100% rename from patches/api/0421-Add-predicate-for-blocks-when-raytracing.patch rename to patches/api/0422-Add-predicate-for-blocks-when-raytracing.patch diff --git a/patches/api/0422-Add-hand-to-fish-event-for-all-player-interactions.patch b/patches/api/0423-Add-hand-to-fish-event-for-all-player-interactions.patch similarity index 100% rename from patches/api/0422-Add-hand-to-fish-event-for-all-player-interactions.patch rename to patches/api/0423-Add-hand-to-fish-event-for-all-player-interactions.patch diff --git a/patches/api/0423-Attribute-Modifier-API-improvements.patch b/patches/api/0424-Attribute-Modifier-API-improvements.patch similarity index 100% rename from patches/api/0423-Attribute-Modifier-API-improvements.patch rename to patches/api/0424-Attribute-Modifier-API-improvements.patch diff --git a/patches/api/0424-Expand-LingeringPotion-API.patch b/patches/api/0425-Expand-LingeringPotion-API.patch similarity index 100% rename from patches/api/0424-Expand-LingeringPotion-API.patch rename to patches/api/0425-Expand-LingeringPotion-API.patch diff --git a/patches/api/0425-Remove-unnecessary-durability-check-in-ItemStack-isS.patch b/patches/api/0426-Remove-unnecessary-durability-check-in-ItemStack-isS.patch similarity index 100% rename from patches/api/0425-Remove-unnecessary-durability-check-in-ItemStack-isS.patch rename to patches/api/0426-Remove-unnecessary-durability-check-in-ItemStack-isS.patch diff --git a/patches/api/0426-Add-Structure-check-API.patch b/patches/api/0427-Add-Structure-check-API.patch similarity index 100% rename from patches/api/0426-Add-Structure-check-API.patch rename to patches/api/0427-Add-Structure-check-API.patch diff --git a/patches/api/0427-Experimental-annotations-change.patch b/patches/api/0428-Experimental-annotations-change.patch similarity index 100% rename from patches/api/0427-Experimental-annotations-change.patch rename to patches/api/0428-Experimental-annotations-change.patch diff --git a/patches/api/0428-Add-more-scoreboard-API.patch b/patches/api/0429-Add-more-scoreboard-API.patch similarity index 100% rename from patches/api/0428-Add-more-scoreboard-API.patch rename to patches/api/0429-Add-more-scoreboard-API.patch diff --git a/patches/api/0429-Improve-Registry.patch b/patches/api/0430-Improve-Registry.patch similarity index 100% rename from patches/api/0429-Improve-Registry.patch rename to patches/api/0430-Improve-Registry.patch diff --git a/patches/api/0430-Add-experience-points-API.patch b/patches/api/0431-Add-experience-points-API.patch similarity index 100% rename from patches/api/0430-Add-experience-points-API.patch rename to patches/api/0431-Add-experience-points-API.patch diff --git a/patches/api/0431-Add-missing-InventoryType.patch b/patches/api/0432-Add-missing-InventoryType.patch similarity index 100% rename from patches/api/0431-Add-missing-InventoryType.patch rename to patches/api/0432-Add-missing-InventoryType.patch diff --git a/patches/api/0432-Add-drops-to-shear-events.patch b/patches/api/0433-Add-drops-to-shear-events.patch similarity index 100% rename from patches/api/0432-Add-drops-to-shear-events.patch rename to patches/api/0433-Add-drops-to-shear-events.patch diff --git a/patches/api/0433-Add-HiddenPotionEffect-API.patch b/patches/api/0434-Add-HiddenPotionEffect-API.patch similarity index 100% rename from patches/api/0433-Add-HiddenPotionEffect-API.patch rename to patches/api/0434-Add-HiddenPotionEffect-API.patch diff --git a/patches/api/0434-Add-PlayerShieldDisableEvent.patch b/patches/api/0435-Add-PlayerShieldDisableEvent.patch similarity index 100% rename from patches/api/0434-Add-PlayerShieldDisableEvent.patch rename to patches/api/0435-Add-PlayerShieldDisableEvent.patch diff --git a/patches/api/0435-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch b/patches/api/0436-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch similarity index 100% rename from patches/api/0435-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch rename to patches/api/0436-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch diff --git a/patches/api/0436-Add-BlockStateMeta-clearBlockState.patch b/patches/api/0437-Add-BlockStateMeta-clearBlockState.patch similarity index 100% rename from patches/api/0436-Add-BlockStateMeta-clearBlockState.patch rename to patches/api/0437-Add-BlockStateMeta-clearBlockState.patch diff --git a/patches/api/0437-Expose-LootTable-of-DecoratedPot.patch b/patches/api/0438-Expose-LootTable-of-DecoratedPot.patch similarity index 100% rename from patches/api/0437-Expose-LootTable-of-DecoratedPot.patch rename to patches/api/0438-Expose-LootTable-of-DecoratedPot.patch diff --git a/patches/api/0438-Add-ShulkerDuplicateEvent.patch b/patches/api/0439-Add-ShulkerDuplicateEvent.patch similarity index 100% rename from patches/api/0438-Add-ShulkerDuplicateEvent.patch rename to patches/api/0439-Add-ShulkerDuplicateEvent.patch diff --git a/patches/api/0439-Add-api-for-spawn-egg-texture-colors.patch b/patches/api/0440-Add-api-for-spawn-egg-texture-colors.patch similarity index 100% rename from patches/api/0439-Add-api-for-spawn-egg-texture-colors.patch rename to patches/api/0440-Add-api-for-spawn-egg-texture-colors.patch diff --git a/patches/api/0440-Add-Lifecycle-Event-system.patch b/patches/api/0441-Add-Lifecycle-Event-system.patch similarity index 100% rename from patches/api/0440-Add-Lifecycle-Event-system.patch rename to patches/api/0441-Add-Lifecycle-Event-system.patch diff --git a/patches/api/0441-ItemStack-Tooltip-API.patch b/patches/api/0442-ItemStack-Tooltip-API.patch similarity index 100% rename from patches/api/0441-ItemStack-Tooltip-API.patch rename to patches/api/0442-ItemStack-Tooltip-API.patch diff --git a/patches/api/0442-Add-getChunkSnapshot-includeLightData-parameter.patch b/patches/api/0443-Add-getChunkSnapshot-includeLightData-parameter.patch similarity index 100% rename from patches/api/0442-Add-getChunkSnapshot-includeLightData-parameter.patch rename to patches/api/0443-Add-getChunkSnapshot-includeLightData-parameter.patch diff --git a/patches/api/0443-Add-FluidState-API.patch b/patches/api/0444-Add-FluidState-API.patch similarity index 100% rename from patches/api/0443-Add-FluidState-API.patch rename to patches/api/0444-Add-FluidState-API.patch diff --git a/patches/api/0444-add-number-format-api.patch b/patches/api/0445-add-number-format-api.patch similarity index 100% rename from patches/api/0444-add-number-format-api.patch rename to patches/api/0445-add-number-format-api.patch diff --git a/patches/api/0445-improve-BanList-types.patch b/patches/api/0446-improve-BanList-types.patch similarity index 94% rename from patches/api/0445-improve-BanList-types.patch rename to patches/api/0446-improve-BanList-types.patch index 0c89e083a6ce..bfb2a6a550f7 100644 --- a/patches/api/0445-improve-BanList-types.patch +++ b/patches/api/0446-improve-BanList-types.patch @@ -70,10 +70,10 @@ index a77c0411a68a9bad33ddfb335b7a996a843e478c..739d9d3ec789e58c10c8d818a9ca59ce /** * Banned player names diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 85ad1f7f0de9a6f9048981c3ee509b42ddbeef1a..2d466b308b2f8bd31c50f5d05416eadf20c9cb71 100644 +index c8fa12acaf52cd3923a7a8702ccc50cfdc9170a2..e20e4239a5a1f952e1c70e899549989d5e42f73c 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -1611,11 +1611,27 @@ public final class Bukkit { +@@ -1663,11 +1663,27 @@ public final class Bukkit { * @param The ban target * * @return a ban list of the specified type @@ -102,10 +102,10 @@ index 85ad1f7f0de9a6f9048981c3ee509b42ddbeef1a..2d466b308b2f8bd31c50f5d05416eadf /** * Gets a set containing all player operators. diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 640ef81d204f480f4af83d420c7e968ce569a38d..20750c09d819d62f32491db8672936b929e1098e 100644 +index 50ffca9bccfb582d58ccb13f0decf66e5d91aef3..6246251caf2c6f025c824b8e7a944b8d48751fa1 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -1374,10 +1374,25 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -1425,10 +1425,25 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi * @param The ban target * * @return a ban list of the specified type diff --git a/patches/api/0446-Suspicious-Effect-Entry-API.patch b/patches/api/0447-Suspicious-Effect-Entry-API.patch similarity index 100% rename from patches/api/0446-Suspicious-Effect-Entry-API.patch rename to patches/api/0447-Suspicious-Effect-Entry-API.patch diff --git a/patches/api/0447-Fix-DamageSource-API.patch b/patches/api/0448-Fix-DamageSource-API.patch similarity index 100% rename from patches/api/0447-Fix-DamageSource-API.patch rename to patches/api/0448-Fix-DamageSource-API.patch diff --git a/patches/api/0448-Expanded-Hopper-API.patch b/patches/api/0449-Expanded-Hopper-API.patch similarity index 100% rename from patches/api/0448-Expanded-Hopper-API.patch rename to patches/api/0449-Expanded-Hopper-API.patch diff --git a/patches/api/0449-Clone-mutables-to-prevent-unexpected-issues.patch b/patches/api/0450-Clone-mutables-to-prevent-unexpected-issues.patch similarity index 100% rename from patches/api/0449-Clone-mutables-to-prevent-unexpected-issues.patch rename to patches/api/0450-Clone-mutables-to-prevent-unexpected-issues.patch diff --git a/patches/api/0450-Add-BlockBreakProgressUpdateEvent.patch b/patches/api/0451-Add-BlockBreakProgressUpdateEvent.patch similarity index 100% rename from patches/api/0450-Add-BlockBreakProgressUpdateEvent.patch rename to patches/api/0451-Add-BlockBreakProgressUpdateEvent.patch diff --git a/patches/api/0451-Deprecate-ItemStack-setType.patch b/patches/api/0452-Deprecate-ItemStack-setType.patch similarity index 100% rename from patches/api/0451-Deprecate-ItemStack-setType.patch rename to patches/api/0452-Deprecate-ItemStack-setType.patch diff --git a/patches/api/0452-Item-Mutation-Fixes.patch b/patches/api/0453-Item-Mutation-Fixes.patch similarity index 100% rename from patches/api/0452-Item-Mutation-Fixes.patch rename to patches/api/0453-Item-Mutation-Fixes.patch diff --git a/patches/api/0453-API-for-checking-sent-chunks.patch b/patches/api/0454-API-for-checking-sent-chunks.patch similarity index 100% rename from patches/api/0453-API-for-checking-sent-chunks.patch rename to patches/api/0454-API-for-checking-sent-chunks.patch diff --git a/patches/api/0454-Add-CartographyItemEvent.patch b/patches/api/0455-Add-CartographyItemEvent.patch similarity index 100% rename from patches/api/0454-Add-CartographyItemEvent.patch rename to patches/api/0455-Add-CartographyItemEvent.patch diff --git a/patches/api/0455-More-Raid-API.patch b/patches/api/0456-More-Raid-API.patch similarity index 100% rename from patches/api/0455-More-Raid-API.patch rename to patches/api/0456-More-Raid-API.patch diff --git a/patches/api/0456-Fix-SpawnerEntry-Equipment-API.patch b/patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch similarity index 100% rename from patches/api/0456-Fix-SpawnerEntry-Equipment-API.patch rename to patches/api/0457-Fix-SpawnerEntry-Equipment-API.patch diff --git a/patches/api/0457-Fix-ItemFlags.patch b/patches/api/0458-Fix-ItemFlags.patch similarity index 100% rename from patches/api/0457-Fix-ItemFlags.patch rename to patches/api/0458-Fix-ItemFlags.patch diff --git a/patches/api/0458-Allow-modifying-library-loader-jars-bytecode.patch b/patches/api/0459-Allow-modifying-library-loader-jars-bytecode.patch similarity index 100% rename from patches/api/0458-Allow-modifying-library-loader-jars-bytecode.patch rename to patches/api/0459-Allow-modifying-library-loader-jars-bytecode.patch diff --git a/patches/api/0459-Add-hook-to-remap-library-jars.patch b/patches/api/0460-Add-hook-to-remap-library-jars.patch similarity index 100% rename from patches/api/0459-Add-hook-to-remap-library-jars.patch rename to patches/api/0460-Add-hook-to-remap-library-jars.patch diff --git a/patches/api/0460-Add-GameMode-isInvulnerable.patch b/patches/api/0461-Add-GameMode-isInvulnerable.patch similarity index 100% rename from patches/api/0460-Add-GameMode-isInvulnerable.patch rename to patches/api/0461-Add-GameMode-isInvulnerable.patch diff --git a/patches/api/0461-Expose-hasColor-to-leather-armor.patch b/patches/api/0462-Expose-hasColor-to-leather-armor.patch similarity index 100% rename from patches/api/0461-Expose-hasColor-to-leather-armor.patch rename to patches/api/0462-Expose-hasColor-to-leather-armor.patch diff --git a/patches/api/0462-Added-API-to-get-player-ha-proxy-address.patch b/patches/api/0463-Added-API-to-get-player-ha-proxy-address.patch similarity index 100% rename from patches/api/0462-Added-API-to-get-player-ha-proxy-address.patch rename to patches/api/0463-Added-API-to-get-player-ha-proxy-address.patch diff --git a/patches/api/0463-More-Chest-Block-API.patch b/patches/api/0464-More-Chest-Block-API.patch similarity index 100% rename from patches/api/0463-More-Chest-Block-API.patch rename to patches/api/0464-More-Chest-Block-API.patch diff --git a/patches/api/0464-Brigadier-based-command-API.patch b/patches/api/0465-Brigadier-based-command-API.patch similarity index 100% rename from patches/api/0464-Brigadier-based-command-API.patch rename to patches/api/0465-Brigadier-based-command-API.patch diff --git a/patches/api/0465-Fix-issues-with-recipe-API.patch b/patches/api/0466-Fix-issues-with-recipe-API.patch similarity index 100% rename from patches/api/0465-Fix-issues-with-recipe-API.patch rename to patches/api/0466-Fix-issues-with-recipe-API.patch diff --git a/patches/api/0466-Fix-equipment-slot-and-group-API.patch b/patches/api/0467-Fix-equipment-slot-and-group-API.patch similarity index 100% rename from patches/api/0466-Fix-equipment-slot-and-group-API.patch rename to patches/api/0467-Fix-equipment-slot-and-group-API.patch diff --git a/patches/api/0467-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch b/patches/api/0468-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch similarity index 100% rename from patches/api/0467-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch rename to patches/api/0468-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch diff --git a/patches/api/0468-General-ItemMeta-fixes.patch b/patches/api/0469-General-ItemMeta-fixes.patch similarity index 100% rename from patches/api/0468-General-ItemMeta-fixes.patch rename to patches/api/0469-General-ItemMeta-fixes.patch diff --git a/patches/api/0469-Add-missing-fishing-event-state.patch b/patches/api/0470-Add-missing-fishing-event-state.patch similarity index 100% rename from patches/api/0469-Add-missing-fishing-event-state.patch rename to patches/api/0470-Add-missing-fishing-event-state.patch diff --git a/patches/api/0470-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch b/patches/api/0471-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch similarity index 100% rename from patches/api/0470-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch rename to patches/api/0471-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch diff --git a/patches/api/0471-Registry-Modification-API.patch b/patches/api/0472-Registry-Modification-API.patch similarity index 100% rename from patches/api/0471-Registry-Modification-API.patch rename to patches/api/0472-Registry-Modification-API.patch diff --git a/patches/api/0472-Introduce-registry-entry-and-builders.patch b/patches/api/0473-Introduce-registry-entry-and-builders.patch similarity index 100% rename from patches/api/0472-Introduce-registry-entry-and-builders.patch rename to patches/api/0473-Introduce-registry-entry-and-builders.patch diff --git a/patches/api/0473-Proxy-ItemStack-to-CraftItemStack.patch b/patches/api/0474-Proxy-ItemStack-to-CraftItemStack.patch similarity index 100% rename from patches/api/0473-Proxy-ItemStack-to-CraftItemStack.patch rename to patches/api/0474-Proxy-ItemStack-to-CraftItemStack.patch diff --git a/patches/api/0474-Make-a-PDC-view-accessible-directly-from-ItemStack.patch b/patches/api/0475-Make-a-PDC-view-accessible-directly-from-ItemStack.patch similarity index 100% rename from patches/api/0474-Make-a-PDC-view-accessible-directly-from-ItemStack.patch rename to patches/api/0475-Make-a-PDC-view-accessible-directly-from-ItemStack.patch diff --git a/patches/api/0475-Fix-HelpCommand-searching.patch b/patches/api/0476-Fix-HelpCommand-searching.patch similarity index 100% rename from patches/api/0475-Fix-HelpCommand-searching.patch rename to patches/api/0476-Fix-HelpCommand-searching.patch diff --git a/patches/api/0476-add-Plugin-getDataPath.patch b/patches/api/0477-add-Plugin-getDataPath.patch similarity index 100% rename from patches/api/0476-add-Plugin-getDataPath.patch rename to patches/api/0477-add-Plugin-getDataPath.patch diff --git a/patches/api/0477-Fix-PickupStatus-getting-reset.patch b/patches/api/0478-Fix-PickupStatus-getting-reset.patch similarity index 100% rename from patches/api/0477-Fix-PickupStatus-getting-reset.patch rename to patches/api/0478-Fix-PickupStatus-getting-reset.patch diff --git a/patches/api/0478-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch b/patches/api/0479-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch similarity index 100% rename from patches/api/0478-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch rename to patches/api/0479-Add-an-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch diff --git a/patches/api/0479-Improve-StandardMessenger-exception-messages.patch b/patches/api/0480-Improve-StandardMessenger-exception-messages.patch similarity index 100% rename from patches/api/0479-Improve-StandardMessenger-exception-messages.patch rename to patches/api/0480-Improve-StandardMessenger-exception-messages.patch diff --git a/patches/api/0480-Add-even-more-Enchantment-API.patch b/patches/api/0481-Add-even-more-Enchantment-API.patch similarity index 100% rename from patches/api/0480-Add-even-more-Enchantment-API.patch rename to patches/api/0481-Add-even-more-Enchantment-API.patch diff --git a/patches/api/0481-Leashable-API.patch b/patches/api/0482-Leashable-API.patch similarity index 100% rename from patches/api/0481-Leashable-API.patch rename to patches/api/0482-Leashable-API.patch diff --git a/patches/api/0482-Add-enchantment-seed-update-API.patch b/patches/api/0483-Add-enchantment-seed-update-API.patch similarity index 100% rename from patches/api/0482-Add-enchantment-seed-update-API.patch rename to patches/api/0483-Add-enchantment-seed-update-API.patch diff --git a/patches/api/0483-Deprecate-for-removal-all-OldEnum-related-methods.patch b/patches/api/0484-Deprecate-for-removal-all-OldEnum-related-methods.patch similarity index 100% rename from patches/api/0483-Deprecate-for-removal-all-OldEnum-related-methods.patch rename to patches/api/0484-Deprecate-for-removal-all-OldEnum-related-methods.patch diff --git a/patches/api/0484-Add-FeatureFlag-API.patch b/patches/api/0485-Add-FeatureFlag-API.patch similarity index 100% rename from patches/api/0484-Add-FeatureFlag-API.patch rename to patches/api/0485-Add-FeatureFlag-API.patch diff --git a/patches/api/0485-Tag-Lifecycle-Events.patch b/patches/api/0486-Tag-Lifecycle-Events.patch similarity index 100% rename from patches/api/0485-Tag-Lifecycle-Events.patch rename to patches/api/0486-Tag-Lifecycle-Events.patch diff --git a/patches/api/0486-Item-serialization-as-json.patch b/patches/api/0487-Item-serialization-as-json.patch similarity index 100% rename from patches/api/0486-Item-serialization-as-json.patch rename to patches/api/0487-Item-serialization-as-json.patch diff --git a/patches/api/0487-create-TileStateInventoryHolder.patch b/patches/api/0488-create-TileStateInventoryHolder.patch similarity index 100% rename from patches/api/0487-create-TileStateInventoryHolder.patch rename to patches/api/0488-create-TileStateInventoryHolder.patch diff --git a/patches/api/0488-Add-enchantWithLevels-with-enchantment-registry-set.patch b/patches/api/0489-Add-enchantWithLevels-with-enchantment-registry-set.patch similarity index 100% rename from patches/api/0488-Add-enchantWithLevels-with-enchantment-registry-set.patch rename to patches/api/0489-Add-enchantWithLevels-with-enchantment-registry-set.patch diff --git a/patches/api/0489-Improve-entity-effect-API.patch b/patches/api/0490-Improve-entity-effect-API.patch similarity index 100% rename from patches/api/0489-Improve-entity-effect-API.patch rename to patches/api/0490-Improve-entity-effect-API.patch diff --git a/patches/api/0490-Add-recipeBrewTime.patch b/patches/api/0491-Add-recipeBrewTime.patch similarity index 100% rename from patches/api/0490-Add-recipeBrewTime.patch rename to patches/api/0491-Add-recipeBrewTime.patch diff --git a/patches/api/0491-Add-PlayerInsertLecternBookEvent.patch b/patches/api/0492-Add-PlayerInsertLecternBookEvent.patch similarity index 100% rename from patches/api/0491-Add-PlayerInsertLecternBookEvent.patch rename to patches/api/0492-Add-PlayerInsertLecternBookEvent.patch diff --git a/patches/api/0492-Void-damage-configuration-API.patch b/patches/api/0493-Void-damage-configuration-API.patch similarity index 100% rename from patches/api/0492-Void-damage-configuration-API.patch rename to patches/api/0493-Void-damage-configuration-API.patch diff --git a/patches/api/0493-Add-Offline-PDC-API.patch b/patches/api/0494-Add-Offline-PDC-API.patch similarity index 100% rename from patches/api/0493-Add-Offline-PDC-API.patch rename to patches/api/0494-Add-Offline-PDC-API.patch diff --git a/patches/api/0494-Add-AnvilView-bypassEnchantmentLevelRestriction.patch b/patches/api/0495-Add-AnvilView-bypassEnchantmentLevelRestriction.patch similarity index 100% rename from patches/api/0494-Add-AnvilView-bypassEnchantmentLevelRestriction.patch rename to patches/api/0495-Add-AnvilView-bypassEnchantmentLevelRestriction.patch diff --git a/patches/api/0495-fix-DamageTypeTags-init.patch b/patches/api/0496-fix-DamageTypeTags-init.patch similarity index 100% rename from patches/api/0495-fix-DamageTypeTags-init.patch rename to patches/api/0496-fix-DamageTypeTags-init.patch diff --git a/patches/unapplied/server/0845-API-for-updating-recipes-on-clients.patch b/patches/server/0845-API-for-updating-recipes-on-clients.patch similarity index 73% rename from patches/unapplied/server/0845-API-for-updating-recipes-on-clients.patch rename to patches/server/0845-API-for-updating-recipes-on-clients.patch index 7cae85735941..0435961d1f54 100644 --- a/patches/unapplied/server/0845-API-for-updating-recipes-on-clients.patch +++ b/patches/server/0845-API-for-updating-recipes-on-clients.patch @@ -5,10 +5,10 @@ Subject: [PATCH] API for updating recipes on clients diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 2912b15ccda373cf52cec020b0e06ac2c5cf2950..a6caf3a0df22f124a4ee1cfb3981bbeb23a8630e 100644 +index a9063533ea4b2b349d476127b99c822203d7dfcb..a1228d09b91dca3989a4be3120f9724a6e138040 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1490,6 +1490,13 @@ public abstract class PlayerList { +@@ -1450,6 +1450,13 @@ public abstract class PlayerList { } public void reloadResources() { @@ -22,27 +22,25 @@ index 2912b15ccda373cf52cec020b0e06ac2c5cf2950..a6caf3a0df22f124a4ee1cfb3981bbeb // CraftBukkit start /*Iterator iterator = this.advancements.values().iterator(); -@@ -1505,7 +1512,15 @@ public abstract class PlayerList { +@@ -1465,7 +1472,13 @@ public abstract class PlayerList { } // CraftBukkit end + // Paper start - API for updating recipes on clients + } + public void reloadTagData() { -+ // Paper end - API for updating recipes on clients this.broadcastAll(new ClientboundUpdateTagsPacket(TagNetworkSerialization.serializeTagsToNetwork(this.registries))); -+ // Paper start - API for updating recipes on clients + } + public void reloadRecipeData() { + // Paper end - API for updating recipes on clients - ClientboundUpdateRecipesPacket packetplayoutrecipeupdate = new ClientboundUpdateRecipesPacket(this.server.getRecipeManager().getOrderedRecipes()); + RecipeManager craftingmanager = this.server.getRecipeManager(); + ClientboundUpdateRecipesPacket packetplayoutrecipeupdate = new ClientboundUpdateRecipesPacket(craftingmanager.getSynchronizedItemProperties(), craftingmanager.getSynchronizedStonecutterRecipes()); Iterator iterator1 = this.players.iterator(); - diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index bb89247a87067a74d793a1acc1eb95b98ace3d9e..75c222e592d676e98b293767d00de54a61411ae7 100644 +index 3cf3b353cfb4337abdbb3b6842fd8fa128271948..0433de3c2455cf18584d5ab651843f8d1d874036 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1176,6 +1176,18 @@ public final class CraftServer implements Server { +@@ -1179,6 +1179,18 @@ public final class CraftServer implements Server { ReloadCommand.reload(this.console); } @@ -61,7 +59,7 @@ index bb89247a87067a74d793a1acc1eb95b98ace3d9e..75c222e592d676e98b293767d00de54a private void loadIcon() { this.icon = new CraftIconCache(null); try { -@@ -1555,6 +1567,13 @@ public final class CraftServer implements Server { +@@ -1558,6 +1570,13 @@ public final class CraftServer implements Server { @Override public boolean addRecipe(Recipe recipe) { @@ -75,19 +73,19 @@ index bb89247a87067a74d793a1acc1eb95b98ace3d9e..75c222e592d676e98b293767d00de54a CraftRecipe toAdd; if (recipe instanceof CraftRecipe) { toAdd = (CraftRecipe) recipe; -@@ -1584,6 +1603,11 @@ public final class CraftServer implements Server { +@@ -1589,6 +1608,11 @@ public final class CraftServer implements Server { } } toAdd.addToCraftingManager(); + // Paper start - API for updating recipes on clients -+ if (resendRecipes) { ++ if (true || resendRecipes) { // Always needs to be resent now... TODO + this.playerList.reloadRecipeData(); + } + // Paper end - API for updating recipes on clients return true; } -@@ -1764,10 +1788,23 @@ public final class CraftServer implements Server { +@@ -1769,9 +1793,23 @@ public final class CraftServer implements Server { @Override public boolean removeRecipe(NamespacedKey recipeKey) { @@ -100,15 +98,15 @@ index bb89247a87067a74d793a1acc1eb95b98ace3d9e..75c222e592d676e98b293767d00de54a + // Paper end - API for updating recipes on clients Preconditions.checkArgument(recipeKey != null, "recipeKey == null"); - ResourceLocation mcKey = CraftNamespacedKey.toMinecraft(recipeKey); -- return this.getServer().getRecipeManager().removeRecipe(mcKey); +- return this.getServer().getRecipeManager().removeRecipe(CraftRecipe.toMinecraft(recipeKey)); + // Paper start - resend recipes on successful removal -+ boolean removed = this.getServer().getRecipeManager().removeRecipe(mcKey); -+ if (removed && resendRecipes) { ++ final ResourceKey> minecraftKey = CraftRecipe.toMinecraft(recipeKey); ++ final boolean removed = this.getServer().getRecipeManager().removeRecipe(minecraftKey); ++ if (removed/* && resendRecipes*/) { // TODO Always need to resend them rn - deprecate this method? + this.playerList.reloadRecipeData(); + } + return removed; -+ // Paper end ++ // Paper end - resend recipes on successful removal } @Override diff --git a/patches/server/0845-Fix-custom-statistic-criteria-creation.patch b/patches/server/0846-Fix-custom-statistic-criteria-creation.patch similarity index 100% rename from patches/server/0845-Fix-custom-statistic-criteria-creation.patch rename to patches/server/0846-Fix-custom-statistic-criteria-creation.patch diff --git a/patches/server/0846-Bandaid-fix-for-Effect.patch b/patches/server/0847-Bandaid-fix-for-Effect.patch similarity index 100% rename from patches/server/0846-Bandaid-fix-for-Effect.patch rename to patches/server/0847-Bandaid-fix-for-Effect.patch diff --git a/patches/server/0847-SculkCatalyst-bloom-API.patch b/patches/server/0848-SculkCatalyst-bloom-API.patch similarity index 100% rename from patches/server/0847-SculkCatalyst-bloom-API.patch rename to patches/server/0848-SculkCatalyst-bloom-API.patch diff --git a/patches/server/0848-API-for-an-entity-s-scoreboard-name.patch b/patches/server/0849-API-for-an-entity-s-scoreboard-name.patch similarity index 100% rename from patches/server/0848-API-for-an-entity-s-scoreboard-name.patch rename to patches/server/0849-API-for-an-entity-s-scoreboard-name.patch diff --git a/patches/server/0849-Deprecate-and-replace-methods-with-old-StructureType.patch b/patches/server/0850-Deprecate-and-replace-methods-with-old-StructureType.patch similarity index 92% rename from patches/server/0849-Deprecate-and-replace-methods-with-old-StructureType.patch rename to patches/server/0850-Deprecate-and-replace-methods-with-old-StructureType.patch index b4264b8b52aa..82cc3b437362 100644 --- a/patches/server/0849-Deprecate-and-replace-methods-with-old-StructureType.patch +++ b/patches/server/0850-Deprecate-and-replace-methods-with-old-StructureType.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Deprecate and replace methods with old StructureType diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 3cf3b353cfb4337abdbb3b6842fd8fa128271948..dbdf52a306d7018f0bf01fcf6c24a6d1dc269be5 100644 +index 0433de3c2455cf18584d5ab651843f8d1d874036..83c3de4ae733199f64fe0f967f9f816545d20f1c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1970,6 +1970,11 @@ public final class CraftServer implements Server { +@@ -2008,6 +2008,11 @@ public final class CraftServer implements Server { ServerLevel worldServer = ((CraftWorld) world).getHandle(); Location structureLocation = world.locateNearestStructure(location, structureType, radius, findUnexplored); @@ -20,7 +20,7 @@ index 3cf3b353cfb4337abdbb3b6842fd8fa128271948..dbdf52a306d7018f0bf01fcf6c24a6d1 BlockPos structurePosition = CraftLocation.toBlockPosition(structureLocation); // Create map with trackPlayer = true, unlimitedTracking = true -@@ -1980,6 +1985,31 @@ public final class CraftServer implements Server { +@@ -2018,6 +2023,31 @@ public final class CraftServer implements Server { return CraftItemStack.asBukkitCopy(stack); } diff --git a/patches/server/0850-Don-t-tab-complete-namespaced-commands-if-send-names.patch b/patches/server/0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch similarity index 100% rename from patches/server/0850-Don-t-tab-complete-namespaced-commands-if-send-names.patch rename to patches/server/0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch diff --git a/patches/server/0851-Properly-handle-BlockBreakEvent-isDropItems.patch b/patches/server/0852-Properly-handle-BlockBreakEvent-isDropItems.patch similarity index 100% rename from patches/server/0851-Properly-handle-BlockBreakEvent-isDropItems.patch rename to patches/server/0852-Properly-handle-BlockBreakEvent-isDropItems.patch diff --git a/patches/server/0852-Fire-entity-death-event-for-ender-dragon.patch b/patches/server/0853-Fire-entity-death-event-for-ender-dragon.patch similarity index 100% rename from patches/server/0852-Fire-entity-death-event-for-ender-dragon.patch rename to patches/server/0853-Fire-entity-death-event-for-ender-dragon.patch diff --git a/patches/server/0853-Configurable-entity-tracking-range-by-Y-coordinate.patch b/patches/server/0854-Configurable-entity-tracking-range-by-Y-coordinate.patch similarity index 100% rename from patches/server/0853-Configurable-entity-tracking-range-by-Y-coordinate.patch rename to patches/server/0854-Configurable-entity-tracking-range-by-Y-coordinate.patch diff --git a/patches/server/0854-Add-Listing-API-for-Player.patch b/patches/server/0855-Add-Listing-API-for-Player.patch similarity index 99% rename from patches/server/0854-Add-Listing-API-for-Player.patch rename to patches/server/0855-Add-Listing-API-for-Player.patch index e99f679a7084..05d3d3e57172 100644 --- a/patches/server/0854-Add-Listing-API-for-Player.patch +++ b/patches/server/0855-Add-Listing-API-for-Player.patch @@ -85,7 +85,7 @@ index 29b465fc1dc50e0e84ddb889c5303e80fe662874..4d67d98257b2cb9045d03c999cfd4ba2 static class EntryBuilder { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index a9063533ea4b2b349d476127b99c822203d7dfcb..218e18b9c7836bc4c9d3eba78e0717cabb9d6b61 100644 +index a1228d09b91dca3989a4be3120f9724a6e138040..fa951c6e33d583f9c2ca103fbaaa035e40c163f9 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -363,14 +363,22 @@ public abstract class PlayerList { diff --git a/patches/server/0855-Configurable-Region-Compression-Format.patch b/patches/server/0856-Configurable-Region-Compression-Format.patch similarity index 100% rename from patches/server/0855-Configurable-Region-Compression-Format.patch rename to patches/server/0856-Configurable-Region-Compression-Format.patch diff --git a/patches/server/0856-Add-BlockFace-to-BlockDamageEvent.patch b/patches/server/0857-Add-BlockFace-to-BlockDamageEvent.patch similarity index 100% rename from patches/server/0856-Add-BlockFace-to-BlockDamageEvent.patch rename to patches/server/0857-Add-BlockFace-to-BlockDamageEvent.patch diff --git a/patches/server/0857-Fix-NPE-on-Boat-getStatus.patch b/patches/server/0858-Fix-NPE-on-Boat-getStatus.patch similarity index 100% rename from patches/server/0857-Fix-NPE-on-Boat-getStatus.patch rename to patches/server/0858-Fix-NPE-on-Boat-getStatus.patch diff --git a/patches/server/0858-Expand-Pose-API.patch b/patches/server/0859-Expand-Pose-API.patch similarity index 100% rename from patches/server/0858-Expand-Pose-API.patch rename to patches/server/0859-Expand-Pose-API.patch diff --git a/patches/server/0859-More-DragonBattle-API.patch b/patches/server/0860-More-DragonBattle-API.patch similarity index 100% rename from patches/server/0859-More-DragonBattle-API.patch rename to patches/server/0860-More-DragonBattle-API.patch diff --git a/patches/server/0860-Add-PlayerPickItemEvent.patch b/patches/server/0861-Add-PlayerPickItemEvent.patch similarity index 100% rename from patches/server/0860-Add-PlayerPickItemEvent.patch rename to patches/server/0861-Add-PlayerPickItemEvent.patch diff --git a/patches/server/0861-Allow-trident-custom-damage.patch b/patches/server/0862-Allow-trident-custom-damage.patch similarity index 100% rename from patches/server/0861-Allow-trident-custom-damage.patch rename to patches/server/0862-Allow-trident-custom-damage.patch diff --git a/patches/server/0862-Expose-hand-in-BlockCanBuildEvent.patch b/patches/server/0863-Expose-hand-in-BlockCanBuildEvent.patch similarity index 100% rename from patches/server/0862-Expose-hand-in-BlockCanBuildEvent.patch rename to patches/server/0863-Expose-hand-in-BlockCanBuildEvent.patch diff --git a/patches/server/0863-Optimize-nearest-structure-border-iteration.patch b/patches/server/0864-Optimize-nearest-structure-border-iteration.patch similarity index 100% rename from patches/server/0863-Optimize-nearest-structure-border-iteration.patch rename to patches/server/0864-Optimize-nearest-structure-border-iteration.patch diff --git a/patches/server/0864-Implement-OfflinePlayer-isConnected.patch b/patches/server/0865-Implement-OfflinePlayer-isConnected.patch similarity index 100% rename from patches/server/0864-Implement-OfflinePlayer-isConnected.patch rename to patches/server/0865-Implement-OfflinePlayer-isConnected.patch diff --git a/patches/server/0865-Fix-slot-desync.patch b/patches/server/0866-Fix-slot-desync.patch similarity index 100% rename from patches/server/0865-Fix-slot-desync.patch rename to patches/server/0866-Fix-slot-desync.patch diff --git a/patches/server/0866-Add-titleOverride-to-InventoryOpenEvent.patch b/patches/server/0867-Add-titleOverride-to-InventoryOpenEvent.patch similarity index 100% rename from patches/server/0866-Add-titleOverride-to-InventoryOpenEvent.patch rename to patches/server/0867-Add-titleOverride-to-InventoryOpenEvent.patch diff --git a/patches/server/0867-Configure-sniffer-egg-hatch-time.patch b/patches/server/0868-Configure-sniffer-egg-hatch-time.patch similarity index 100% rename from patches/server/0867-Configure-sniffer-egg-hatch-time.patch rename to patches/server/0868-Configure-sniffer-egg-hatch-time.patch diff --git a/patches/server/0868-Do-crystal-portal-proximity-check-before-entity-look.patch b/patches/server/0869-Do-crystal-portal-proximity-check-before-entity-look.patch similarity index 100% rename from patches/server/0868-Do-crystal-portal-proximity-check-before-entity-look.patch rename to patches/server/0869-Do-crystal-portal-proximity-check-before-entity-look.patch diff --git a/patches/server/0869-Skip-POI-finding-if-stuck-in-vehicle.patch b/patches/server/0870-Skip-POI-finding-if-stuck-in-vehicle.patch similarity index 100% rename from patches/server/0869-Skip-POI-finding-if-stuck-in-vehicle.patch rename to patches/server/0870-Skip-POI-finding-if-stuck-in-vehicle.patch diff --git a/patches/server/0870-Add-slot-sanity-checks-in-container-clicks.patch b/patches/server/0871-Add-slot-sanity-checks-in-container-clicks.patch similarity index 100% rename from patches/server/0870-Add-slot-sanity-checks-in-container-clicks.patch rename to patches/server/0871-Add-slot-sanity-checks-in-container-clicks.patch diff --git a/patches/server/0871-Call-BlockRedstoneEvents-for-lecterns.patch b/patches/server/0872-Call-BlockRedstoneEvents-for-lecterns.patch similarity index 100% rename from patches/server/0871-Call-BlockRedstoneEvents-for-lecterns.patch rename to patches/server/0872-Call-BlockRedstoneEvents-for-lecterns.patch diff --git a/patches/server/0872-Allow-proper-checking-of-empty-item-stacks.patch b/patches/server/0873-Allow-proper-checking-of-empty-item-stacks.patch similarity index 100% rename from patches/server/0872-Allow-proper-checking-of-empty-item-stacks.patch rename to patches/server/0873-Allow-proper-checking-of-empty-item-stacks.patch diff --git a/patches/server/0873-Fix-silent-equipment-change-for-mobs.patch b/patches/server/0874-Fix-silent-equipment-change-for-mobs.patch similarity index 100% rename from patches/server/0873-Fix-silent-equipment-change-for-mobs.patch rename to patches/server/0874-Fix-silent-equipment-change-for-mobs.patch diff --git a/patches/server/0874-Fix-spigot-s-Forced-Stats.patch b/patches/server/0875-Fix-spigot-s-Forced-Stats.patch similarity index 100% rename from patches/server/0874-Fix-spigot-s-Forced-Stats.patch rename to patches/server/0875-Fix-spigot-s-Forced-Stats.patch diff --git a/patches/server/0875-Add-missing-InventoryHolders-to-inventories.patch b/patches/server/0876-Add-missing-InventoryHolders-to-inventories.patch similarity index 100% rename from patches/server/0875-Add-missing-InventoryHolders-to-inventories.patch rename to patches/server/0876-Add-missing-InventoryHolders-to-inventories.patch diff --git a/patches/server/0876-Do-not-read-tile-entities-in-chunks-that-are-positio.patch b/patches/server/0877-Do-not-read-tile-entities-in-chunks-that-are-positio.patch similarity index 100% rename from patches/server/0876-Do-not-read-tile-entities-in-chunks-that-are-positio.patch rename to patches/server/0877-Do-not-read-tile-entities-in-chunks-that-are-positio.patch diff --git a/patches/server/0877-Add-missing-logs-for-log-ips-config-option.patch b/patches/server/0878-Add-missing-logs-for-log-ips-config-option.patch similarity index 100% rename from patches/server/0877-Add-missing-logs-for-log-ips-config-option.patch rename to patches/server/0878-Add-missing-logs-for-log-ips-config-option.patch diff --git a/patches/server/0878-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch b/patches/server/0879-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch similarity index 100% rename from patches/server/0878-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch rename to patches/server/0879-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch diff --git a/patches/server/0879-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch b/patches/server/0880-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch similarity index 100% rename from patches/server/0879-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch rename to patches/server/0880-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch diff --git a/patches/server/0880-Fix-team-sidebar-objectives-not-being-cleared.patch b/patches/server/0881-Fix-team-sidebar-objectives-not-being-cleared.patch similarity index 100% rename from patches/server/0880-Fix-team-sidebar-objectives-not-being-cleared.patch rename to patches/server/0881-Fix-team-sidebar-objectives-not-being-cleared.patch diff --git a/patches/server/0881-Fix-missing-map-initialize-event-call.patch b/patches/server/0882-Fix-missing-map-initialize-event-call.patch similarity index 100% rename from patches/server/0881-Fix-missing-map-initialize-event-call.patch rename to patches/server/0882-Fix-missing-map-initialize-event-call.patch diff --git a/patches/server/0882-Update-entity-data-when-attaching-firework-to-entity.patch b/patches/server/0883-Update-entity-data-when-attaching-firework-to-entity.patch similarity index 100% rename from patches/server/0882-Update-entity-data-when-attaching-firework-to-entity.patch rename to patches/server/0883-Update-entity-data-when-attaching-firework-to-entity.patch diff --git a/patches/server/0883-Fix-UnsafeValues-loadAdvancement.patch b/patches/server/0884-Fix-UnsafeValues-loadAdvancement.patch similarity index 100% rename from patches/server/0883-Fix-UnsafeValues-loadAdvancement.patch rename to patches/server/0884-Fix-UnsafeValues-loadAdvancement.patch diff --git a/patches/server/0884-Add-player-idle-duration-API.patch b/patches/server/0885-Add-player-idle-duration-API.patch similarity index 100% rename from patches/server/0884-Add-player-idle-duration-API.patch rename to patches/server/0885-Add-player-idle-duration-API.patch diff --git a/patches/server/0885-Don-t-check-if-we-can-see-non-visible-entities.patch b/patches/server/0886-Don-t-check-if-we-can-see-non-visible-entities.patch similarity index 100% rename from patches/server/0885-Don-t-check-if-we-can-see-non-visible-entities.patch rename to patches/server/0886-Don-t-check-if-we-can-see-non-visible-entities.patch diff --git a/patches/server/0886-Fix-NPE-in-SculkBloomEvent-world-access.patch b/patches/server/0887-Fix-NPE-in-SculkBloomEvent-world-access.patch similarity index 100% rename from patches/server/0886-Fix-NPE-in-SculkBloomEvent-world-access.patch rename to patches/server/0887-Fix-NPE-in-SculkBloomEvent-world-access.patch diff --git a/patches/server/0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch b/patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch similarity index 100% rename from patches/server/0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch rename to patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch diff --git a/patches/server/0888-Optimize-VarInts.patch b/patches/server/0889-Optimize-VarInts.patch similarity index 100% rename from patches/server/0888-Optimize-VarInts.patch rename to patches/server/0889-Optimize-VarInts.patch diff --git a/patches/server/0889-Add-API-to-get-the-collision-shape-of-a-block-before.patch b/patches/server/0890-Add-API-to-get-the-collision-shape-of-a-block-before.patch similarity index 100% rename from patches/server/0889-Add-API-to-get-the-collision-shape-of-a-block-before.patch rename to patches/server/0890-Add-API-to-get-the-collision-shape-of-a-block-before.patch diff --git a/patches/server/0890-Add-predicate-for-blocks-when-raytracing.patch b/patches/server/0891-Add-predicate-for-blocks-when-raytracing.patch similarity index 100% rename from patches/server/0890-Add-predicate-for-blocks-when-raytracing.patch rename to patches/server/0891-Add-predicate-for-blocks-when-raytracing.patch diff --git a/patches/server/0891-Broadcast-take-item-packets-with-collector-as-source.patch b/patches/server/0892-Broadcast-take-item-packets-with-collector-as-source.patch similarity index 100% rename from patches/server/0891-Broadcast-take-item-packets-with-collector-as-source.patch rename to patches/server/0892-Broadcast-take-item-packets-with-collector-as-source.patch diff --git a/patches/server/0892-Expand-LingeringPotion-API.patch b/patches/server/0893-Expand-LingeringPotion-API.patch similarity index 100% rename from patches/server/0892-Expand-LingeringPotion-API.patch rename to patches/server/0893-Expand-LingeringPotion-API.patch diff --git a/patches/server/0893-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch b/patches/server/0894-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch similarity index 100% rename from patches/server/0893-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch rename to patches/server/0894-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch diff --git a/patches/server/0894-Add-hand-to-fish-event-for-all-player-interactions.patch b/patches/server/0895-Add-hand-to-fish-event-for-all-player-interactions.patch similarity index 100% rename from patches/server/0894-Add-hand-to-fish-event-for-all-player-interactions.patch rename to patches/server/0895-Add-hand-to-fish-event-for-all-player-interactions.patch diff --git a/patches/server/0895-Fix-several-issues-with-EntityBreedEvent.patch b/patches/server/0896-Fix-several-issues-with-EntityBreedEvent.patch similarity index 100% rename from patches/server/0895-Fix-several-issues-with-EntityBreedEvent.patch rename to patches/server/0896-Fix-several-issues-with-EntityBreedEvent.patch diff --git a/patches/server/0896-Add-UUID-attribute-modifier-API.patch b/patches/server/0897-Add-UUID-attribute-modifier-API.patch similarity index 100% rename from patches/server/0896-Add-UUID-attribute-modifier-API.patch rename to patches/server/0897-Add-UUID-attribute-modifier-API.patch diff --git a/patches/server/0897-Fix-missing-event-call-for-entity-teleport-API.patch b/patches/server/0898-Fix-missing-event-call-for-entity-teleport-API.patch similarity index 100% rename from patches/server/0897-Fix-missing-event-call-for-entity-teleport-API.patch rename to patches/server/0898-Fix-missing-event-call-for-entity-teleport-API.patch diff --git a/patches/server/0898-Lazily-create-LootContext-for-criterions.patch b/patches/server/0899-Lazily-create-LootContext-for-criterions.patch similarity index 100% rename from patches/server/0898-Lazily-create-LootContext-for-criterions.patch rename to patches/server/0899-Lazily-create-LootContext-for-criterions.patch diff --git a/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch b/patches/server/0900-Don-t-fire-sync-events-during-worldgen.patch similarity index 100% rename from patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch rename to patches/server/0900-Don-t-fire-sync-events-during-worldgen.patch diff --git a/patches/server/0900-Add-Structure-check-API.patch b/patches/server/0901-Add-Structure-check-API.patch similarity index 100% rename from patches/server/0900-Add-Structure-check-API.patch rename to patches/server/0901-Add-Structure-check-API.patch diff --git a/patches/server/0901-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch b/patches/server/0902-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch similarity index 100% rename from patches/server/0901-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch rename to patches/server/0902-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch diff --git a/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch b/patches/server/0903-Restore-vanilla-entity-drops-behavior.patch similarity index 100% rename from patches/server/0902-Restore-vanilla-entity-drops-behavior.patch rename to patches/server/0903-Restore-vanilla-entity-drops-behavior.patch diff --git a/patches/server/0903-Dont-resend-blocks-on-interactions.patch b/patches/server/0904-Dont-resend-blocks-on-interactions.patch similarity index 100% rename from patches/server/0903-Dont-resend-blocks-on-interactions.patch rename to patches/server/0904-Dont-resend-blocks-on-interactions.patch diff --git a/patches/server/0904-add-more-scoreboard-API.patch b/patches/server/0905-add-more-scoreboard-API.patch similarity index 100% rename from patches/server/0904-add-more-scoreboard-API.patch rename to patches/server/0905-add-more-scoreboard-API.patch diff --git a/patches/server/0905-Improve-Registry.patch b/patches/server/0906-Improve-Registry.patch similarity index 100% rename from patches/server/0905-Improve-Registry.patch rename to patches/server/0906-Improve-Registry.patch diff --git a/patches/server/0906-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch b/patches/server/0907-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch similarity index 100% rename from patches/server/0906-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch rename to patches/server/0907-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch diff --git a/patches/server/0907-Add-experience-points-API.patch b/patches/server/0908-Add-experience-points-API.patch similarity index 100% rename from patches/server/0907-Add-experience-points-API.patch rename to patches/server/0908-Add-experience-points-API.patch diff --git a/patches/server/0908-Add-drops-to-shear-events.patch b/patches/server/0909-Add-drops-to-shear-events.patch similarity index 100% rename from patches/server/0908-Add-drops-to-shear-events.patch rename to patches/server/0909-Add-drops-to-shear-events.patch diff --git a/patches/server/0909-Add-PlayerShieldDisableEvent.patch b/patches/server/0910-Add-PlayerShieldDisableEvent.patch similarity index 100% rename from patches/server/0909-Add-PlayerShieldDisableEvent.patch rename to patches/server/0910-Add-PlayerShieldDisableEvent.patch diff --git a/patches/server/0910-Validate-ResourceLocation-in-NBT-reading.patch b/patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch similarity index 100% rename from patches/server/0910-Validate-ResourceLocation-in-NBT-reading.patch rename to patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch diff --git a/patches/server/0911-Properly-handle-experience-dropping-on-block-break.patch b/patches/server/0912-Properly-handle-experience-dropping-on-block-break.patch similarity index 100% rename from patches/server/0911-Properly-handle-experience-dropping-on-block-break.patch rename to patches/server/0912-Properly-handle-experience-dropping-on-block-break.patch diff --git a/patches/server/0912-Fixup-NamespacedKey-handling.patch b/patches/server/0913-Fixup-NamespacedKey-handling.patch similarity index 100% rename from patches/server/0912-Fixup-NamespacedKey-handling.patch rename to patches/server/0913-Fixup-NamespacedKey-handling.patch diff --git a/patches/server/0913-Expose-LootTable-of-DecoratedPot.patch b/patches/server/0914-Expose-LootTable-of-DecoratedPot.patch similarity index 100% rename from patches/server/0913-Expose-LootTable-of-DecoratedPot.patch rename to patches/server/0914-Expose-LootTable-of-DecoratedPot.patch diff --git a/patches/server/0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch b/patches/server/0915-Reduce-allocation-of-Vec3D-by-entity-tracker.patch similarity index 100% rename from patches/server/0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch rename to patches/server/0915-Reduce-allocation-of-Vec3D-by-entity-tracker.patch diff --git a/patches/server/0915-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch b/patches/server/0916-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch similarity index 100% rename from patches/server/0915-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch rename to patches/server/0916-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch diff --git a/patches/server/0916-Add-ShulkerDuplicateEvent.patch b/patches/server/0917-Add-ShulkerDuplicateEvent.patch similarity index 100% rename from patches/server/0916-Add-ShulkerDuplicateEvent.patch rename to patches/server/0917-Add-ShulkerDuplicateEvent.patch diff --git a/patches/server/0917-Add-api-for-spawn-egg-texture-colors.patch b/patches/server/0918-Add-api-for-spawn-egg-texture-colors.patch similarity index 100% rename from patches/server/0917-Add-api-for-spawn-egg-texture-colors.patch rename to patches/server/0918-Add-api-for-spawn-egg-texture-colors.patch diff --git a/patches/server/0918-Add-Lifecycle-Event-system.patch b/patches/server/0919-Add-Lifecycle-Event-system.patch similarity index 99% rename from patches/server/0918-Add-Lifecycle-Event-system.patch rename to patches/server/0919-Add-Lifecycle-Event-system.patch index d93b26d6b3df..611ac658507b 100644 --- a/patches/server/0918-Add-Lifecycle-Event-system.patch +++ b/patches/server/0919-Add-Lifecycle-Event-system.patch @@ -727,7 +727,7 @@ index 2e96308696e131f3f013469a395e5ddda2c5d529..65a66e484c1c39c5f41d97db52f31c67 } catch (Throwable e) { LOGGER.error("Failed to run bootstrapper for %s. This plugin will not be loaded.".formatted(provider.getSource()), e); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index dbdf52a306d7018f0bf01fcf6c24a6d1dc269be5..fb55dced981d16a82e4cc233fbf25695850a1b99 100644 +index 83c3de4ae733199f64fe0f967f9f816545d20f1c..581a15957478fd9f394a27269c2bd68a117ad8c2 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1051,6 +1051,11 @@ public final class CraftServer implements Server { diff --git a/patches/server/0919-ItemStack-Tooltip-API.patch b/patches/server/0920-ItemStack-Tooltip-API.patch similarity index 100% rename from patches/server/0919-ItemStack-Tooltip-API.patch rename to patches/server/0920-ItemStack-Tooltip-API.patch diff --git a/patches/server/0920-Add-getChunkSnapshot-includeLightData-parameter.patch b/patches/server/0921-Add-getChunkSnapshot-includeLightData-parameter.patch similarity index 100% rename from patches/server/0920-Add-getChunkSnapshot-includeLightData-parameter.patch rename to patches/server/0921-Add-getChunkSnapshot-includeLightData-parameter.patch diff --git a/patches/server/0921-Add-FluidState-API.patch b/patches/server/0922-Add-FluidState-API.patch similarity index 100% rename from patches/server/0921-Add-FluidState-API.patch rename to patches/server/0922-Add-FluidState-API.patch diff --git a/patches/server/0922-add-number-format-api.patch b/patches/server/0923-add-number-format-api.patch similarity index 100% rename from patches/server/0922-add-number-format-api.patch rename to patches/server/0923-add-number-format-api.patch diff --git a/patches/server/0923-improve-BanList-types.patch b/patches/server/0924-improve-BanList-types.patch similarity index 89% rename from patches/server/0923-improve-BanList-types.patch rename to patches/server/0924-improve-BanList-types.patch index 1b56c10b04a0..96871b48ee57 100644 --- a/patches/server/0923-improve-BanList-types.patch +++ b/patches/server/0924-improve-BanList-types.patch @@ -5,10 +5,10 @@ Subject: [PATCH] improve BanList types diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index fb55dced981d16a82e4cc233fbf25695850a1b99..82a85a4e2dd58d22e6aad797e4bd8f7c5b355caf 100644 +index 581a15957478fd9f394a27269c2bd68a117ad8c2..f7e478a14ef17ad6d747d0ab56418b0b5b20492d 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2223,6 +2223,21 @@ public final class CraftServer implements Server { +@@ -2261,6 +2261,21 @@ public final class CraftServer implements Server { }; } diff --git a/patches/server/0924-Expanded-Hopper-API.patch b/patches/server/0925-Expanded-Hopper-API.patch similarity index 100% rename from patches/server/0924-Expanded-Hopper-API.patch rename to patches/server/0925-Expanded-Hopper-API.patch diff --git a/patches/server/0925-Add-BlockBreakProgressUpdateEvent.patch b/patches/server/0926-Add-BlockBreakProgressUpdateEvent.patch similarity index 100% rename from patches/server/0925-Add-BlockBreakProgressUpdateEvent.patch rename to patches/server/0926-Add-BlockBreakProgressUpdateEvent.patch diff --git a/patches/server/0926-Deprecate-ItemStack-setType.patch b/patches/server/0927-Deprecate-ItemStack-setType.patch similarity index 100% rename from patches/server/0926-Deprecate-ItemStack-setType.patch rename to patches/server/0927-Deprecate-ItemStack-setType.patch diff --git a/patches/server/0927-Add-CartographyItemEvent.patch b/patches/server/0928-Add-CartographyItemEvent.patch similarity index 100% rename from patches/server/0927-Add-CartographyItemEvent.patch rename to patches/server/0928-Add-CartographyItemEvent.patch diff --git a/patches/server/0928-More-Raid-API.patch b/patches/server/0929-More-Raid-API.patch similarity index 100% rename from patches/server/0928-More-Raid-API.patch rename to patches/server/0929-More-Raid-API.patch diff --git a/patches/server/0929-Add-onboarding-message-for-initial-server-start.patch b/patches/server/0930-Add-onboarding-message-for-initial-server-start.patch similarity index 100% rename from patches/server/0929-Add-onboarding-message-for-initial-server-start.patch rename to patches/server/0930-Add-onboarding-message-for-initial-server-start.patch diff --git a/patches/server/0930-Configurable-max-block-fluid-ticks.patch b/patches/server/0931-Configurable-max-block-fluid-ticks.patch similarity index 100% rename from patches/server/0930-Configurable-max-block-fluid-ticks.patch rename to patches/server/0931-Configurable-max-block-fluid-ticks.patch diff --git a/patches/server/0931-Fix-bees-aging-inside-hives.patch b/patches/server/0932-Fix-bees-aging-inside-hives.patch similarity index 100% rename from patches/server/0931-Fix-bees-aging-inside-hives.patch rename to patches/server/0932-Fix-bees-aging-inside-hives.patch diff --git a/patches/server/0932-Disable-memory-reserve-allocating.patch b/patches/server/0933-Disable-memory-reserve-allocating.patch similarity index 100% rename from patches/server/0932-Disable-memory-reserve-allocating.patch rename to patches/server/0933-Disable-memory-reserve-allocating.patch diff --git a/patches/server/0933-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch b/patches/server/0934-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch similarity index 100% rename from patches/server/0933-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch rename to patches/server/0934-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch diff --git a/patches/server/0934-Fix-DamageSource-API.patch b/patches/server/0935-Fix-DamageSource-API.patch similarity index 100% rename from patches/server/0934-Fix-DamageSource-API.patch rename to patches/server/0935-Fix-DamageSource-API.patch diff --git a/patches/server/0935-Fix-creation-of-invalid-block-entity-during-world-ge.patch b/patches/server/0936-Fix-creation-of-invalid-block-entity-during-world-ge.patch similarity index 100% rename from patches/server/0935-Fix-creation-of-invalid-block-entity-during-world-ge.patch rename to patches/server/0936-Fix-creation-of-invalid-block-entity-during-world-ge.patch diff --git a/patches/server/0936-Fix-possible-StackOverflowError-for-some-dispenses.patch b/patches/server/0937-Fix-possible-StackOverflowError-for-some-dispenses.patch similarity index 100% rename from patches/server/0936-Fix-possible-StackOverflowError-for-some-dispenses.patch rename to patches/server/0937-Fix-possible-StackOverflowError-for-some-dispenses.patch diff --git a/patches/server/0937-Improve-tag-parser-handling.patch b/patches/server/0938-Improve-tag-parser-handling.patch similarity index 100% rename from patches/server/0937-Improve-tag-parser-handling.patch rename to patches/server/0938-Improve-tag-parser-handling.patch diff --git a/patches/server/0938-Item-Mutation-Fixes.patch b/patches/server/0939-Item-Mutation-Fixes.patch similarity index 100% rename from patches/server/0938-Item-Mutation-Fixes.patch rename to patches/server/0939-Item-Mutation-Fixes.patch diff --git a/patches/server/0939-Per-world-ticks-per-spawn-settings.patch b/patches/server/0940-Per-world-ticks-per-spawn-settings.patch similarity index 100% rename from patches/server/0939-Per-world-ticks-per-spawn-settings.patch rename to patches/server/0940-Per-world-ticks-per-spawn-settings.patch diff --git a/patches/server/0940-Properly-track-the-changed-item-from-dispense-events.patch b/patches/server/0941-Properly-track-the-changed-item-from-dispense-events.patch similarity index 100% rename from patches/server/0940-Properly-track-the-changed-item-from-dispense-events.patch rename to patches/server/0941-Properly-track-the-changed-item-from-dispense-events.patch diff --git a/patches/server/0941-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch b/patches/server/0942-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch similarity index 100% rename from patches/server/0941-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch rename to patches/server/0942-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch diff --git a/patches/server/0942-Add-config-for-mobs-immune-to-default-effects.patch b/patches/server/0943-Add-config-for-mobs-immune-to-default-effects.patch similarity index 100% rename from patches/server/0942-Add-config-for-mobs-immune-to-default-effects.patch rename to patches/server/0943-Add-config-for-mobs-immune-to-default-effects.patch diff --git a/patches/server/0943-Deep-clone-nbt-tags-in-PDC.patch b/patches/server/0944-Deep-clone-nbt-tags-in-PDC.patch similarity index 100% rename from patches/server/0943-Deep-clone-nbt-tags-in-PDC.patch rename to patches/server/0944-Deep-clone-nbt-tags-in-PDC.patch diff --git a/patches/server/0944-Support-old-UUID-format-for-NBT.patch b/patches/server/0945-Support-old-UUID-format-for-NBT.patch similarity index 100% rename from patches/server/0944-Support-old-UUID-format-for-NBT.patch rename to patches/server/0945-Support-old-UUID-format-for-NBT.patch diff --git a/patches/server/0945-Fix-shield-disable-inconsistency.patch b/patches/server/0946-Fix-shield-disable-inconsistency.patch similarity index 100% rename from patches/server/0945-Fix-shield-disable-inconsistency.patch rename to patches/server/0946-Fix-shield-disable-inconsistency.patch diff --git a/patches/server/0946-Handle-Large-Packets-disconnecting-client.patch b/patches/server/0947-Handle-Large-Packets-disconnecting-client.patch similarity index 100% rename from patches/server/0946-Handle-Large-Packets-disconnecting-client.patch rename to patches/server/0947-Handle-Large-Packets-disconnecting-client.patch diff --git a/patches/server/0947-Fix-ItemFlags.patch b/patches/server/0948-Fix-ItemFlags.patch similarity index 100% rename from patches/server/0947-Fix-ItemFlags.patch rename to patches/server/0948-Fix-ItemFlags.patch diff --git a/patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch b/patches/server/0949-Fix-helmet-damage-reduction-inconsistencies.patch similarity index 100% rename from patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch rename to patches/server/0949-Fix-helmet-damage-reduction-inconsistencies.patch diff --git a/patches/server/0949-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch b/patches/server/0950-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch similarity index 100% rename from patches/server/0949-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch rename to patches/server/0950-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch diff --git a/patches/server/0950-improve-checking-handled-tags-in-itemmeta.patch b/patches/server/0951-improve-checking-handled-tags-in-itemmeta.patch similarity index 100% rename from patches/server/0950-improve-checking-handled-tags-in-itemmeta.patch rename to patches/server/0951-improve-checking-handled-tags-in-itemmeta.patch diff --git a/patches/server/0951-Expose-hasColor-to-leather-armor.patch b/patches/server/0952-Expose-hasColor-to-leather-armor.patch similarity index 100% rename from patches/server/0951-Expose-hasColor-to-leather-armor.patch rename to patches/server/0952-Expose-hasColor-to-leather-armor.patch diff --git a/patches/server/0952-Added-API-to-get-player-ha-proxy-address.patch b/patches/server/0953-Added-API-to-get-player-ha-proxy-address.patch similarity index 100% rename from patches/server/0952-Added-API-to-get-player-ha-proxy-address.patch rename to patches/server/0953-Added-API-to-get-player-ha-proxy-address.patch diff --git a/patches/server/0953-General-ItemMeta-fixes.patch b/patches/server/0954-General-ItemMeta-fixes.patch similarity index 100% rename from patches/server/0953-General-ItemMeta-fixes.patch rename to patches/server/0954-General-ItemMeta-fixes.patch diff --git a/patches/server/0954-More-Chest-Block-API.patch b/patches/server/0955-More-Chest-Block-API.patch similarity index 100% rename from patches/server/0954-More-Chest-Block-API.patch rename to patches/server/0955-More-Chest-Block-API.patch diff --git a/patches/server/0955-Print-data-component-type-on-encoding-error.patch b/patches/server/0956-Print-data-component-type-on-encoding-error.patch similarity index 100% rename from patches/server/0955-Print-data-component-type-on-encoding-error.patch rename to patches/server/0956-Print-data-component-type-on-encoding-error.patch diff --git a/patches/server/0956-Brigadier-based-command-API.patch b/patches/server/0957-Brigadier-based-command-API.patch similarity index 99% rename from patches/server/0956-Brigadier-based-command-API.patch rename to patches/server/0957-Brigadier-based-command-API.patch index 103527a38c67..f305e6146b7b 100644 --- a/patches/server/0956-Brigadier-based-command-API.patch +++ b/patches/server/0957-Brigadier-based-command-API.patch @@ -2388,7 +2388,7 @@ index 2cef6390ce8cdc43ae7566683afc157cb3a6fd78..af3e0049beb5590520ed84b52d6df85a // CraftBukkit end diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 82a85a4e2dd58d22e6aad797e4bd8f7c5b355caf..52710b4196dde7118eb1438a2f78b7c9557e00f8 100644 +index f7e478a14ef17ad6d747d0ab56418b0b5b20492d..15b406935047f591a7866d81b40841a5a9878f55 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -275,11 +275,11 @@ public final class CraftServer implements Server { diff --git a/patches/server/0957-Fix-issues-with-Recipe-API.patch b/patches/server/0958-Fix-issues-with-Recipe-API.patch similarity index 100% rename from patches/server/0957-Fix-issues-with-Recipe-API.patch rename to patches/server/0958-Fix-issues-with-Recipe-API.patch diff --git a/patches/server/0958-Fix-equipment-slot-and-group-API.patch b/patches/server/0959-Fix-equipment-slot-and-group-API.patch similarity index 100% rename from patches/server/0958-Fix-equipment-slot-and-group-API.patch rename to patches/server/0959-Fix-equipment-slot-and-group-API.patch diff --git a/patches/server/0959-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch b/patches/server/0960-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch similarity index 100% rename from patches/server/0959-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch rename to patches/server/0960-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch diff --git a/patches/server/0960-Prevent-sending-oversized-item-data-in-equipment-and.patch b/patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch similarity index 100% rename from patches/server/0960-Prevent-sending-oversized-item-data-in-equipment-and.patch rename to patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch diff --git a/patches/server/0961-Prevent-NPE-if-hooked-entity-was-cleared.patch b/patches/server/0962-Prevent-NPE-if-hooked-entity-was-cleared.patch similarity index 100% rename from patches/server/0961-Prevent-NPE-if-hooked-entity-was-cleared.patch rename to patches/server/0962-Prevent-NPE-if-hooked-entity-was-cleared.patch diff --git a/patches/server/0962-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch b/patches/server/0963-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch similarity index 100% rename from patches/server/0962-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch rename to patches/server/0963-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch diff --git a/patches/server/0963-Add-missing-fishing-event-state.patch b/patches/server/0964-Add-missing-fishing-event-state.patch similarity index 100% rename from patches/server/0963-Add-missing-fishing-event-state.patch rename to patches/server/0964-Add-missing-fishing-event-state.patch diff --git a/patches/server/0964-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch b/patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch similarity index 100% rename from patches/server/0964-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch rename to patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch diff --git a/patches/server/0965-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch b/patches/server/0966-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch similarity index 100% rename from patches/server/0965-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch rename to patches/server/0966-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch diff --git a/patches/server/0966-Adopt-MaterialRerouting.patch b/patches/server/0967-Adopt-MaterialRerouting.patch similarity index 100% rename from patches/server/0966-Adopt-MaterialRerouting.patch rename to patches/server/0967-Adopt-MaterialRerouting.patch diff --git a/patches/server/0967-Suspicious-Effect-Entry-API.patch b/patches/server/0968-Suspicious-Effect-Entry-API.patch similarity index 100% rename from patches/server/0967-Suspicious-Effect-Entry-API.patch rename to patches/server/0968-Suspicious-Effect-Entry-API.patch diff --git a/patches/server/0968-check-if-itemstack-is-stackable-first.patch b/patches/server/0969-check-if-itemstack-is-stackable-first.patch similarity index 100% rename from patches/server/0968-check-if-itemstack-is-stackable-first.patch rename to patches/server/0969-check-if-itemstack-is-stackable-first.patch diff --git a/patches/server/0969-Fix-removing-recipes-from-RecipeIterator.patch b/patches/server/0970-Fix-removing-recipes-from-RecipeIterator.patch similarity index 100% rename from patches/server/0969-Fix-removing-recipes-from-RecipeIterator.patch rename to patches/server/0970-Fix-removing-recipes-from-RecipeIterator.patch diff --git a/patches/server/0970-Configurable-damage-tick-when-blocking-with-shield.patch b/patches/server/0971-Configurable-damage-tick-when-blocking-with-shield.patch similarity index 100% rename from patches/server/0970-Configurable-damage-tick-when-blocking-with-shield.patch rename to patches/server/0971-Configurable-damage-tick-when-blocking-with-shield.patch diff --git a/patches/server/0971-Properly-remove-the-experimental-smithing-inventory-.patch b/patches/server/0972-Properly-remove-the-experimental-smithing-inventory-.patch similarity index 100% rename from patches/server/0971-Properly-remove-the-experimental-smithing-inventory-.patch rename to patches/server/0972-Properly-remove-the-experimental-smithing-inventory-.patch diff --git a/patches/server/0972-disable-forced-empty-world-ticks.patch b/patches/server/0973-disable-forced-empty-world-ticks.patch similarity index 100% rename from patches/server/0972-disable-forced-empty-world-ticks.patch rename to patches/server/0973-disable-forced-empty-world-ticks.patch diff --git a/patches/server/0973-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch b/patches/server/0974-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch similarity index 100% rename from patches/server/0973-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch rename to patches/server/0974-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch diff --git a/patches/server/0974-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/patches/server/0975-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch similarity index 100% rename from patches/server/0974-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch rename to patches/server/0975-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch diff --git a/patches/server/0975-Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/patches/server/0976-Optimize-Network-Manager-and-add-advanced-packet-sup.patch similarity index 100% rename from patches/server/0975-Optimize-Network-Manager-and-add-advanced-packet-sup.patch rename to patches/server/0976-Optimize-Network-Manager-and-add-advanced-packet-sup.patch diff --git a/patches/server/0976-Allow-Saving-of-Oversized-Chunks.patch b/patches/server/0977-Allow-Saving-of-Oversized-Chunks.patch similarity index 100% rename from patches/server/0976-Allow-Saving-of-Oversized-Chunks.patch rename to patches/server/0977-Allow-Saving-of-Oversized-Chunks.patch diff --git a/patches/server/0977-Flat-bedrock-generator-settings.patch b/patches/server/0978-Flat-bedrock-generator-settings.patch similarity index 100% rename from patches/server/0977-Flat-bedrock-generator-settings.patch rename to patches/server/0978-Flat-bedrock-generator-settings.patch diff --git a/patches/server/0978-Entity-Activation-Range-2.0.patch b/patches/server/0979-Entity-Activation-Range-2.0.patch similarity index 100% rename from patches/server/0978-Entity-Activation-Range-2.0.patch rename to patches/server/0979-Entity-Activation-Range-2.0.patch diff --git a/patches/server/0979-Anti-Xray.patch b/patches/server/0980-Anti-Xray.patch similarity index 99% rename from patches/server/0979-Anti-Xray.patch rename to patches/server/0980-Anti-Xray.patch index 7ab86199c5d7..1e72722f63d7 100644 --- a/patches/server/0979-Anti-Xray.patch +++ b/patches/server/0980-Anti-Xray.patch @@ -1157,7 +1157,7 @@ index cdd66e6ce96e2613afe7f06ca8da3cfaa6704b2d..dafa2cf7d3c49fc5bdcd68d2a9528127 if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) { new io.papermc.paper.event.packet.PlayerChunkLoadEvent(new org.bukkit.craftbukkit.CraftChunk(chunk), handler.getPlayer().getBukkitEntity()).callEvent(); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 218e18b9c7836bc4c9d3eba78e0717cabb9d6b61..d12ac1b045c6721255780c5afbbad6e7103629eb 100644 +index fa951c6e33d583f9c2ca103fbaaa035e40c163f9..b0a43a24f2a43b1513600f26f1f02646c6031cef 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -427,7 +427,7 @@ public abstract class PlayerList { @@ -1598,10 +1598,10 @@ index 5fc9e8e969debb3e15ed474b36a1c48b086d0449..f65cc95ab28e8a3b21eac2b16bd9ebe9 private static final byte[] EMPTY_LIGHT = new byte[2048]; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 52710b4196dde7118eb1438a2f78b7c9557e00f8..8348ab336029848eab1cbe9b67b056abf1f5866f 100644 +index 15b406935047f591a7866d81b40841a5a9878f55..b29220ced6f5294594af23d9227532f5bb292e4c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2655,7 +2655,7 @@ public final class CraftServer implements Server { +@@ -2693,7 +2693,7 @@ public final class CraftServer implements Server { public ChunkGenerator.ChunkData createChunkData(World world) { Preconditions.checkArgument(world != null, "World cannot be null"); ServerLevel handle = ((CraftWorld) world).getHandle(); diff --git a/patches/server/0980-Use-Velocity-compression-and-cipher-natives.patch b/patches/server/0981-Use-Velocity-compression-and-cipher-natives.patch similarity index 100% rename from patches/server/0980-Use-Velocity-compression-and-cipher-natives.patch rename to patches/server/0981-Use-Velocity-compression-and-cipher-natives.patch diff --git a/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch b/patches/server/0982-Optimize-Collision-to-not-load-chunks.patch similarity index 98% rename from patches/server/0981-Optimize-Collision-to-not-load-chunks.patch rename to patches/server/0982-Optimize-Collision-to-not-load-chunks.patch index daa6249dc3bf..22bbfc1040fd 100644 --- a/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch +++ b/patches/server/0982-Optimize-Collision-to-not-load-chunks.patch @@ -14,7 +14,7 @@ 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 d12ac1b045c6721255780c5afbbad6e7103629eb..59cc1702079f1d182bdbe8068aa37b5b979aa64d 100644 +index b0a43a24f2a43b1513600f26f1f02646c6031cef..aa245fe0945b267ef03700758e75edd445c7c60d 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -827,6 +827,7 @@ public abstract class PlayerList { diff --git a/patches/server/0982-Optimize-GoalSelector-Goal.Flag-Set-operations.patch b/patches/server/0983-Optimize-GoalSelector-Goal.Flag-Set-operations.patch similarity index 100% rename from patches/server/0982-Optimize-GoalSelector-Goal.Flag-Set-operations.patch rename to patches/server/0983-Optimize-GoalSelector-Goal.Flag-Set-operations.patch diff --git a/patches/server/0983-Optimize-Hoppers.patch b/patches/server/0984-Optimize-Hoppers.patch similarity index 100% rename from patches/server/0983-Optimize-Hoppers.patch rename to patches/server/0984-Optimize-Hoppers.patch diff --git a/patches/server/0984-Optimize-Voxel-Shape-Merging.patch b/patches/server/0985-Optimize-Voxel-Shape-Merging.patch similarity index 100% rename from patches/server/0984-Optimize-Voxel-Shape-Merging.patch rename to patches/server/0985-Optimize-Voxel-Shape-Merging.patch diff --git a/patches/server/0985-Optimize-Bit-Operations-by-inlining.patch b/patches/server/0986-Optimize-Bit-Operations-by-inlining.patch similarity index 100% rename from patches/server/0985-Optimize-Bit-Operations-by-inlining.patch rename to patches/server/0986-Optimize-Bit-Operations-by-inlining.patch diff --git a/patches/server/0986-Remove-streams-from-hot-code.patch b/patches/server/0987-Remove-streams-from-hot-code.patch similarity index 100% rename from patches/server/0986-Remove-streams-from-hot-code.patch rename to patches/server/0987-Remove-streams-from-hot-code.patch diff --git a/patches/server/0987-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch b/patches/server/0988-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch similarity index 100% rename from patches/server/0987-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch rename to patches/server/0988-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch diff --git a/patches/server/0988-Fix-entity-type-tags-suggestions-in-selectors.patch b/patches/server/0989-Fix-entity-type-tags-suggestions-in-selectors.patch similarity index 100% rename from patches/server/0988-Fix-entity-type-tags-suggestions-in-selectors.patch rename to patches/server/0989-Fix-entity-type-tags-suggestions-in-selectors.patch diff --git a/patches/server/0989-Handle-Oversized-block-entities-in-chunks.patch b/patches/server/0990-Handle-Oversized-block-entities-in-chunks.patch similarity index 100% rename from patches/server/0989-Handle-Oversized-block-entities-in-chunks.patch rename to patches/server/0990-Handle-Oversized-block-entities-in-chunks.patch diff --git a/patches/server/0990-Check-distance-in-entity-interactions.patch b/patches/server/0991-Check-distance-in-entity-interactions.patch similarity index 100% rename from patches/server/0990-Check-distance-in-entity-interactions.patch rename to patches/server/0991-Check-distance-in-entity-interactions.patch diff --git a/patches/server/0991-Configurable-Sand-Duping.patch b/patches/server/0992-Configurable-Sand-Duping.patch similarity index 100% rename from patches/server/0991-Configurable-Sand-Duping.patch rename to patches/server/0992-Configurable-Sand-Duping.patch diff --git a/patches/server/0992-Properly-resend-entities.patch b/patches/server/0993-Properly-resend-entities.patch similarity index 99% rename from patches/server/0992-Properly-resend-entities.patch rename to patches/server/0993-Properly-resend-entities.patch index e7bcb808c95c..95bcb49a7cc1 100644 --- a/patches/server/0992-Properly-resend-entities.patch +++ b/patches/server/0993-Properly-resend-entities.patch @@ -102,7 +102,7 @@ index 52eafd99ed63f5fc9596225cf45175b1287f20a1..e5db85f858ab376b225172e22b92b841 } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 59cc1702079f1d182bdbe8068aa37b5b979aa64d..90c469193ecf9d04dd9e3f1a38157d47c5094985 100644 +index aa245fe0945b267ef03700758e75edd445c7c60d..f55d7f6ed653b19f28694f91ca5bcc54873e33c3 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -397,7 +397,7 @@ public abstract class PlayerList { diff --git a/patches/server/0993-Registry-Modification-API.patch b/patches/server/0994-Registry-Modification-API.patch similarity index 100% rename from patches/server/0993-Registry-Modification-API.patch rename to patches/server/0994-Registry-Modification-API.patch diff --git a/patches/server/0994-Add-registry-entry-and-builders.patch b/patches/server/0995-Add-registry-entry-and-builders.patch similarity index 100% rename from patches/server/0994-Add-registry-entry-and-builders.patch rename to patches/server/0995-Add-registry-entry-and-builders.patch diff --git a/patches/server/0995-Proxy-ItemStack-to-CraftItemStack.patch b/patches/server/0996-Proxy-ItemStack-to-CraftItemStack.patch similarity index 100% rename from patches/server/0995-Proxy-ItemStack-to-CraftItemStack.patch rename to patches/server/0996-Proxy-ItemStack-to-CraftItemStack.patch diff --git a/patches/server/0996-Make-a-PDC-view-accessible-directly-from-ItemStack.patch b/patches/server/0997-Make-a-PDC-view-accessible-directly-from-ItemStack.patch similarity index 100% rename from patches/server/0996-Make-a-PDC-view-accessible-directly-from-ItemStack.patch rename to patches/server/0997-Make-a-PDC-view-accessible-directly-from-ItemStack.patch diff --git a/patches/server/0997-Prioritize-Minecraft-commands-in-function-parsing-an.patch b/patches/server/0998-Prioritize-Minecraft-commands-in-function-parsing-an.patch similarity index 100% rename from patches/server/0997-Prioritize-Minecraft-commands-in-function-parsing-an.patch rename to patches/server/0998-Prioritize-Minecraft-commands-in-function-parsing-an.patch diff --git a/patches/server/0998-optimize-dirt-and-snow-spreading.patch b/patches/server/0999-optimize-dirt-and-snow-spreading.patch similarity index 100% rename from patches/server/0998-optimize-dirt-and-snow-spreading.patch rename to patches/server/0999-optimize-dirt-and-snow-spreading.patch diff --git a/patches/server/0999-Fix-NPE-for-Jukebox-setRecord.patch b/patches/server/1000-Fix-NPE-for-Jukebox-setRecord.patch similarity index 100% rename from patches/server/0999-Fix-NPE-for-Jukebox-setRecord.patch rename to patches/server/1000-Fix-NPE-for-Jukebox-setRecord.patch diff --git a/patches/server/1000-fix-horse-inventories.patch b/patches/server/1001-fix-horse-inventories.patch similarity index 100% rename from patches/server/1000-fix-horse-inventories.patch rename to patches/server/1001-fix-horse-inventories.patch diff --git a/patches/server/1001-Only-call-EntityDamageEvents-before-actuallyHurt.patch b/patches/server/1002-Only-call-EntityDamageEvents-before-actuallyHurt.patch similarity index 100% rename from patches/server/1001-Only-call-EntityDamageEvents-before-actuallyHurt.patch rename to patches/server/1002-Only-call-EntityDamageEvents-before-actuallyHurt.patch diff --git a/patches/server/1002-Add-ItemType-getItemRarity.patch b/patches/server/1003-Add-ItemType-getItemRarity.patch similarity index 100% rename from patches/server/1002-Add-ItemType-getItemRarity.patch rename to patches/server/1003-Add-ItemType-getItemRarity.patch diff --git a/patches/server/1003-Add-plugin-info-at-startup.patch b/patches/server/1004-Add-plugin-info-at-startup.patch similarity index 100% rename from patches/server/1003-Add-plugin-info-at-startup.patch rename to patches/server/1004-Add-plugin-info-at-startup.patch diff --git a/patches/server/1004-Make-interaction-leniency-distance-configurable.patch b/patches/server/1005-Make-interaction-leniency-distance-configurable.patch similarity index 100% rename from patches/server/1004-Make-interaction-leniency-distance-configurable.patch rename to patches/server/1005-Make-interaction-leniency-distance-configurable.patch diff --git a/patches/server/1005-Fix-PickupStatus-getting-reset.patch b/patches/server/1006-Fix-PickupStatus-getting-reset.patch similarity index 100% rename from patches/server/1005-Fix-PickupStatus-getting-reset.patch rename to patches/server/1006-Fix-PickupStatus-getting-reset.patch diff --git a/patches/server/1006-Check-for-block-type-in-SculkSensorBlock-canActivate.patch b/patches/server/1007-Check-for-block-type-in-SculkSensorBlock-canActivate.patch similarity index 100% rename from patches/server/1006-Check-for-block-type-in-SculkSensorBlock-canActivate.patch rename to patches/server/1007-Check-for-block-type-in-SculkSensorBlock-canActivate.patch diff --git a/patches/server/1007-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch b/patches/server/1008-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch similarity index 100% rename from patches/server/1007-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch rename to patches/server/1008-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch diff --git a/patches/server/1008-Configuration-for-horizontal-only-item-merging.patch b/patches/server/1009-Configuration-for-horizontal-only-item-merging.patch similarity index 100% rename from patches/server/1008-Configuration-for-horizontal-only-item-merging.patch rename to patches/server/1009-Configuration-for-horizontal-only-item-merging.patch diff --git a/patches/server/1009-Add-skipping-world-symlink-scan.patch b/patches/server/1010-Add-skipping-world-symlink-scan.patch similarity index 100% rename from patches/server/1009-Add-skipping-world-symlink-scan.patch rename to patches/server/1010-Add-skipping-world-symlink-scan.patch diff --git a/patches/server/1010-Add-even-more-Enchantment-API.patch b/patches/server/1011-Add-even-more-Enchantment-API.patch similarity index 100% rename from patches/server/1010-Add-even-more-Enchantment-API.patch rename to patches/server/1011-Add-even-more-Enchantment-API.patch diff --git a/patches/server/1011-Leashable-API.patch b/patches/server/1012-Leashable-API.patch similarity index 100% rename from patches/server/1011-Leashable-API.patch rename to patches/server/1012-Leashable-API.patch diff --git a/patches/server/1012-Fix-CraftBukkit-drag-system.patch b/patches/server/1013-Fix-CraftBukkit-drag-system.patch similarity index 100% rename from patches/server/1012-Fix-CraftBukkit-drag-system.patch rename to patches/server/1013-Fix-CraftBukkit-drag-system.patch diff --git a/patches/server/1013-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch b/patches/server/1014-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch similarity index 100% rename from patches/server/1013-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch rename to patches/server/1014-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch diff --git a/patches/server/1014-Remove-set-damage-lootable-item-function-from-compas.patch b/patches/server/1015-Remove-set-damage-lootable-item-function-from-compas.patch similarity index 100% rename from patches/server/1014-Remove-set-damage-lootable-item-function-from-compas.patch rename to patches/server/1015-Remove-set-damage-lootable-item-function-from-compas.patch diff --git a/patches/server/1015-Add-enchantment-seed-update-API.patch b/patches/server/1016-Add-enchantment-seed-update-API.patch similarity index 100% rename from patches/server/1015-Add-enchantment-seed-update-API.patch rename to patches/server/1016-Add-enchantment-seed-update-API.patch diff --git a/patches/server/1016-Fix-synchronise-sending-chat-to-client-with-updating.patch b/patches/server/1017-Fix-synchronise-sending-chat-to-client-with-updating.patch similarity index 100% rename from patches/server/1016-Fix-synchronise-sending-chat-to-client-with-updating.patch rename to patches/server/1017-Fix-synchronise-sending-chat-to-client-with-updating.patch diff --git a/patches/server/1017-Fix-InventoryOpenEvent-cancellation.patch b/patches/server/1018-Fix-InventoryOpenEvent-cancellation.patch similarity index 100% rename from patches/server/1017-Fix-InventoryOpenEvent-cancellation.patch rename to patches/server/1018-Fix-InventoryOpenEvent-cancellation.patch diff --git a/patches/server/1018-Fire-BlockExpEvent-on-grindstone-use.patch b/patches/server/1019-Fire-BlockExpEvent-on-grindstone-use.patch similarity index 100% rename from patches/server/1018-Fire-BlockExpEvent-on-grindstone-use.patch rename to patches/server/1019-Fire-BlockExpEvent-on-grindstone-use.patch diff --git a/patches/server/1019-Check-dead-flag-in-isAlive.patch b/patches/server/1020-Check-dead-flag-in-isAlive.patch similarity index 100% rename from patches/server/1019-Check-dead-flag-in-isAlive.patch rename to patches/server/1020-Check-dead-flag-in-isAlive.patch diff --git a/patches/server/1020-Add-FeatureFlag-API.patch b/patches/server/1021-Add-FeatureFlag-API.patch similarity index 100% rename from patches/server/1020-Add-FeatureFlag-API.patch rename to patches/server/1021-Add-FeatureFlag-API.patch diff --git a/patches/server/1021-Tag-Lifecycle-Events.patch b/patches/server/1022-Tag-Lifecycle-Events.patch similarity index 100% rename from patches/server/1021-Tag-Lifecycle-Events.patch rename to patches/server/1022-Tag-Lifecycle-Events.patch diff --git a/patches/server/1022-Item-serialization-as-json.patch b/patches/server/1023-Item-serialization-as-json.patch similarity index 100% rename from patches/server/1022-Item-serialization-as-json.patch rename to patches/server/1023-Item-serialization-as-json.patch diff --git a/patches/server/1023-Validate-slot-in-PlayerInventory-setSlot.patch b/patches/server/1024-Validate-slot-in-PlayerInventory-setSlot.patch similarity index 100% rename from patches/server/1023-Validate-slot-in-PlayerInventory-setSlot.patch rename to patches/server/1024-Validate-slot-in-PlayerInventory-setSlot.patch diff --git a/patches/server/1024-Remove-wall-time-unused-skip-tick-protection.patch b/patches/server/1025-Remove-wall-time-unused-skip-tick-protection.patch similarity index 100% rename from patches/server/1024-Remove-wall-time-unused-skip-tick-protection.patch rename to patches/server/1025-Remove-wall-time-unused-skip-tick-protection.patch diff --git a/patches/server/1025-Disable-pretty-printing-for-advancement-saving.patch b/patches/server/1026-Disable-pretty-printing-for-advancement-saving.patch similarity index 100% rename from patches/server/1025-Disable-pretty-printing-for-advancement-saving.patch rename to patches/server/1026-Disable-pretty-printing-for-advancement-saving.patch diff --git a/patches/server/1026-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch b/patches/server/1027-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch similarity index 100% rename from patches/server/1026-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch rename to patches/server/1027-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch diff --git a/patches/server/1027-Add-enchantWithLevels-with-enchantment-registry-set.patch b/patches/server/1028-Add-enchantWithLevels-with-enchantment-registry-set.patch similarity index 100% rename from patches/server/1027-Add-enchantWithLevels-with-enchantment-registry-set.patch rename to patches/server/1028-Add-enchantWithLevels-with-enchantment-registry-set.patch diff --git a/patches/server/1028-Improve-entity-effect-API.patch b/patches/server/1029-Improve-entity-effect-API.patch similarity index 100% rename from patches/server/1028-Improve-entity-effect-API.patch rename to patches/server/1029-Improve-entity-effect-API.patch diff --git a/patches/server/1029-Add-recipeBrewTime.patch b/patches/server/1030-Add-recipeBrewTime.patch similarity index 100% rename from patches/server/1029-Add-recipeBrewTime.patch rename to patches/server/1030-Add-recipeBrewTime.patch diff --git a/patches/server/1030-Call-bucket-events-for-cauldrons.patch b/patches/server/1031-Call-bucket-events-for-cauldrons.patch similarity index 100% rename from patches/server/1030-Call-bucket-events-for-cauldrons.patch rename to patches/server/1031-Call-bucket-events-for-cauldrons.patch diff --git a/patches/server/1031-Add-PlayerInsertLecternBookEvent.patch b/patches/server/1032-Add-PlayerInsertLecternBookEvent.patch similarity index 100% rename from patches/server/1031-Add-PlayerInsertLecternBookEvent.patch rename to patches/server/1032-Add-PlayerInsertLecternBookEvent.patch diff --git a/patches/server/1032-Void-damage-configuration-API.patch b/patches/server/1033-Void-damage-configuration-API.patch similarity index 100% rename from patches/server/1032-Void-damage-configuration-API.patch rename to patches/server/1033-Void-damage-configuration-API.patch diff --git a/patches/server/1033-Add-Offline-PDC-API.patch b/patches/server/1034-Add-Offline-PDC-API.patch similarity index 100% rename from patches/server/1033-Add-Offline-PDC-API.patch rename to patches/server/1034-Add-Offline-PDC-API.patch diff --git a/patches/server/1034-Add-AnvilView-bypassEnchantmentLevelRestriction.patch b/patches/server/1035-Add-AnvilView-bypassEnchantmentLevelRestriction.patch similarity index 100% rename from patches/server/1034-Add-AnvilView-bypassEnchantmentLevelRestriction.patch rename to patches/server/1035-Add-AnvilView-bypassEnchantmentLevelRestriction.patch diff --git a/patches/server/1035-Add-proper-async-player-disconnections.patch b/patches/server/1036-Add-proper-async-player-disconnections.patch similarity index 100% rename from patches/server/1035-Add-proper-async-player-disconnections.patch rename to patches/server/1036-Add-proper-async-player-disconnections.patch diff --git a/patches/server/1036-Always-send-Banner-patterns-to-the-client.patch b/patches/server/1037-Always-send-Banner-patterns-to-the-client.patch similarity index 100% rename from patches/server/1036-Always-send-Banner-patterns-to-the-client.patch rename to patches/server/1037-Always-send-Banner-patterns-to-the-client.patch diff --git a/patches/server/1037-Rewrite-dataconverter-system.patch b/patches/server/1038-Rewrite-dataconverter-system.patch similarity index 100% rename from patches/server/1037-Rewrite-dataconverter-system.patch rename to patches/server/1038-Rewrite-dataconverter-system.patch diff --git a/patches/server/1038-Moonrise-optimisation-patches.patch b/patches/server/1039-Moonrise-optimisation-patches.patch similarity index 99% rename from patches/server/1038-Moonrise-optimisation-patches.patch rename to patches/server/1039-Moonrise-optimisation-patches.patch index 2160af1a6b52..8bd5172b9660 100644 --- a/patches/server/1038-Moonrise-optimisation-patches.patch +++ b/patches/server/1039-Moonrise-optimisation-patches.patch @@ -28032,7 +28032,7 @@ index b7d29389a357f142237cecd75f8ca91cf1eb6b5b..e4b0dc3121101d54394a0c3a413dabf8 this.generatingStep = generationStep; this.cache = chunks; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 90c469193ecf9d04dd9e3f1a38157d47c5094985..bbefb529607d1cffe8917b883389494a8fa126c0 100644 +index f55d7f6ed653b19f28694f91ca5bcc54873e33c3..a6964ceb3874acebdcb8cdc8fe0c128bd56bea48 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -1422,7 +1422,7 @@ public abstract class PlayerList { @@ -36000,10 +36000,10 @@ index f65cc95ab28e8a3b21eac2b16bd9ebe97e56e571..0074bc0e7147dc3a8c538e796f14ac9b @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 8348ab336029848eab1cbe9b67b056abf1f5866f..a34e40e273a79a234c3d79b6ad360ce3a4d35ba3 100644 +index b29220ced6f5294594af23d9227532f5bb292e4c..d45d4d43f8e960f164c00bb534ebfbb6da6a803b 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1421,7 +1421,7 @@ public final class CraftServer implements Server { +@@ -1433,7 +1433,7 @@ public final class CraftServer implements Server { // Paper - Put world into worldlist before initing the world; move up this.getServer().prepareLevels(internal.getChunkSource().chunkMap.progressListener, internal); @@ -36012,7 +36012,7 @@ index 8348ab336029848eab1cbe9b67b056abf1f5866f..a34e40e273a79a234c3d79b6ad360ce3 this.pluginManager.callEvent(new WorldLoadEvent(internal.getWorld())); return internal.getWorld(); -@@ -1466,7 +1466,7 @@ public final class CraftServer implements Server { +@@ -1478,7 +1478,7 @@ public final class CraftServer implements Server { } handle.getChunkSource().close(save); @@ -36021,7 +36021,7 @@ index 8348ab336029848eab1cbe9b67b056abf1f5866f..a34e40e273a79a234c3d79b6ad360ce3 handle.convertable.close(); } catch (Exception ex) { this.getLogger().log(Level.SEVERE, null, ex); -@@ -2478,7 +2478,7 @@ public final class CraftServer implements Server { +@@ -2516,7 +2516,7 @@ public final class CraftServer implements Server { @Override public boolean isPrimaryThread() { diff --git a/patches/server/1039-API-for-checking-sent-chunks.patch b/patches/server/1040-API-for-checking-sent-chunks.patch similarity index 100% rename from patches/server/1039-API-for-checking-sent-chunks.patch rename to patches/server/1040-API-for-checking-sent-chunks.patch diff --git a/patches/server/1040-Fix-CraftWorld-isChunkGenerated.patch b/patches/server/1041-Fix-CraftWorld-isChunkGenerated.patch similarity index 100% rename from patches/server/1040-Fix-CraftWorld-isChunkGenerated.patch rename to patches/server/1041-Fix-CraftWorld-isChunkGenerated.patch diff --git a/patches/server/1041-Add-startup-flag-to-disable-gamerule-limits.patch b/patches/server/1042-Add-startup-flag-to-disable-gamerule-limits.patch similarity index 100% rename from patches/server/1041-Add-startup-flag-to-disable-gamerule-limits.patch rename to patches/server/1042-Add-startup-flag-to-disable-gamerule-limits.patch diff --git a/patches/server/1042-Improved-Watchdog-Support.patch b/patches/server/1043-Improved-Watchdog-Support.patch similarity index 99% rename from patches/server/1042-Improved-Watchdog-Support.patch rename to patches/server/1043-Improved-Watchdog-Support.patch index 25ec2402023d..9ce6a1fe4ad3 100644 --- a/patches/server/1042-Improved-Watchdog-Support.patch +++ b/patches/server/1043-Improved-Watchdog-Support.patch @@ -302,7 +302,7 @@ index 3ed19896a0e06fe834953e6450f23abdc805a6cc..7a79541db29cc47c844d617fc8a4360f } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index bbefb529607d1cffe8917b883389494a8fa126c0..511e7254d938733aca508efd5de82e61678c7620 100644 +index a6964ceb3874acebdcb8cdc8fe0c128bd56bea48..3642444d45038fd1a07768ff96bfbd8678b02e04 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -554,7 +554,7 @@ public abstract class PlayerList { diff --git a/patches/server/1043-Detail-more-information-in-watchdog-dumps.patch b/patches/server/1044-Detail-more-information-in-watchdog-dumps.patch similarity index 100% rename from patches/server/1043-Detail-more-information-in-watchdog-dumps.patch rename to patches/server/1044-Detail-more-information-in-watchdog-dumps.patch diff --git a/patches/server/1044-Entity-load-save-limit-per-chunk.patch b/patches/server/1045-Entity-load-save-limit-per-chunk.patch similarity index 100% rename from patches/server/1044-Entity-load-save-limit-per-chunk.patch rename to patches/server/1045-Entity-load-save-limit-per-chunk.patch diff --git a/patches/server/1045-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch b/patches/server/1046-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch similarity index 100% rename from patches/server/1045-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch rename to patches/server/1046-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch diff --git a/patches/server/1046-Bundle-spark.patch b/patches/server/1047-Bundle-spark.patch similarity index 99% rename from patches/server/1046-Bundle-spark.patch rename to patches/server/1047-Bundle-spark.patch index 585f155a2006..f66e0b42bb6d 100644 --- a/patches/server/1046-Bundle-spark.patch +++ b/patches/server/1047-Bundle-spark.patch @@ -334,7 +334,7 @@ index 7a79541db29cc47c844d617fc8a4360f61c73372..f8ee4b6c481d3fe15f48bf4a93696dd2 com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - 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 a34e40e273a79a234c3d79b6ad360ce3a4d35ba3..742d4cd3b42c1f4807c8ecb27ffa6df905d7f0ac 100644 +index d45d4d43f8e960f164c00bb534ebfbb6da6a803b..4db0d960adc637c37cb322471357876837ef9e8e 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -312,6 +312,7 @@ public final class CraftServer implements Server { diff --git a/patches/server/1047-Improve-performance-of-mass-crafts.patch b/patches/server/1048-Improve-performance-of-mass-crafts.patch similarity index 100% rename from patches/server/1047-Improve-performance-of-mass-crafts.patch rename to patches/server/1048-Improve-performance-of-mass-crafts.patch From b6305644f91fbbd78b648b47740a10194bda6916 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Sun, 27 Oct 2024 10:26:44 +0100 Subject: [PATCH 095/119] More patches --- ...Incremental-chunk-and-player-saving.patch} | 44 ++--- .../1050-Optimise-general-POI-access.patch} | 32 ++-- ...r-desync-when-new-players-are-added.patch} | 36 ++-- .../1052-Lag-compensation-ticks.patch} | 38 ++-- ...n-checking-in-player-move-packet-ha.patch} | 20 +-- .../1028-Write-SavedData-IO-async.patch | 164 ------------------ 6 files changed, 82 insertions(+), 252 deletions(-) rename patches/{unapplied/server/1030-Incremental-chunk-and-player-saving.patch => server/1049-Incremental-chunk-and-player-saving.patch} (79%) rename patches/{unapplied/server/1011-Optimise-general-POI-access.patch => server/1050-Optimise-general-POI-access.patch} (97%) rename patches/{unapplied/server/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch => server/1051-Fix-entity-tracker-desync-when-new-players-are-added.patch} (74%) rename patches/{unapplied/server/1026-Lag-compensation-ticks.patch => server/1052-Lag-compensation-ticks.patch} (81%) rename patches/{unapplied/server/1039-Optimise-collision-checking-in-player-move-packet-ha.patch => server/1053-Optimise-collision-checking-in-player-move-packet-ha.patch} (93%) delete mode 100644 patches/unapplied/server/1028-Write-SavedData-IO-async.patch diff --git a/patches/unapplied/server/1030-Incremental-chunk-and-player-saving.patch b/patches/server/1049-Incremental-chunk-and-player-saving.patch similarity index 79% rename from patches/unapplied/server/1030-Incremental-chunk-and-player-saving.patch rename to patches/server/1049-Incremental-chunk-and-player-saving.patch index 92967eb763b3..9a12860c6a54 100644 --- a/patches/unapplied/server/1030-Incremental-chunk-and-player-saving.patch +++ b/patches/server/1049-Incremental-chunk-and-player-saving.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Incremental chunk and player saving diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index b64c3e29e2b8e890073fee0b45c8b8dfc2b642fd..aa38e3b297209cc121e7dc7a6ac9588c18bf9357 100644 +index de80ac827c8ac3630d68b73cb425d4b56f7d2cd7..f422cbcb69d6fda2b4e229cbdbf10abd0d36d6f9 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -992,7 +992,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0 && this.ticksUntilAutosave <= 0) { -- this.ticksUntilAutosave = this.autosavePeriod; -- // CraftBukkit end -- MinecraftServer.LOGGER.debug("Autosave started"); -- this.profiler.push("save"); -- this.saveEverything(true, false, false); -- this.profiler.pop(); -- MinecraftServer.LOGGER.debug("Autosave finished"); +- if (this.autosavePeriod > 0 && this.ticksUntilAutosave <= 0) { // CraftBukkit +- this.autoSave(); + // Paper start - Incremental chunk and player saving ++ final ProfilerFiller profiler = Profiler.get(); + int playerSaveInterval = io.papermc.paper.configuration.GlobalConfiguration.get().playerAutoSave.rate; + if (playerSaveInterval < 0) { + playerSaveInterval = autosavePeriod; + } -+ this.profiler.push("save"); ++ profiler.push("save"); + final boolean fullSave = autosavePeriod > 0 && this.tickCount % autosavePeriod == 0; + try { + this.isSaving = true; + if (playerSaveInterval > 0) { + this.playerList.saveAll(playerSaveInterval); + } -+ for (ServerLevel level : this.getAllLevels()) { ++ for (final ServerLevel level : this.getAllLevels()) { + if (level.paperConfig().chunks.autoSaveInterval.value() > 0) { + level.saveIncrementally(fullSave); + } @@ -50,16 +44,16 @@ index b64c3e29e2b8e890073fee0b45c8b8dfc2b642fd..aa38e3b297209cc121e7dc7a6ac9588c + } finally { + this.isSaving = false; } -+ this.profiler.pop(); ++ profiler.pop(); + // Paper end - Incremental chunk and player saving - // Paper start - move executeAll() into full server tick timing - try (co.aikar.timings.Timing ignored = MinecraftTimings.processTasksTimer.startTiming()) { - this.runAllTasks(); + + ProfilerFiller gameprofilerfiller = Profiler.get(); + diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 202975cf97ae143622a0c19826b0d63ad2afa0ce..f9abf63e12ea930275121b470e4e4906cff0fc12 100644 +index a7420e4522e0dff72ce7f8a791b9cd4bfa270106..fd07824ff6a928ca6e2f56477a63bac7aaeb8c15 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1315,6 +1315,35 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1371,6 +1371,35 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return !this.server.isUnderSpawnProtection(this, pos, player) && this.getWorldBorder().isWithinBounds(pos); } @@ -96,10 +90,10 @@ index 202975cf97ae143622a0c19826b0d63ad2afa0ce..f9abf63e12ea930275121b470e4e4906 // Paper start - add close param this.save(progressListener, flush, savingDisabled, false); diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 8dc3ba983fd4c61e463867be8d224aa90424215a..6c280abdef5f80b668d6090f9d35283a33e21e0c 100644 +index 8ceeebb561046933cba0725e15732fa074226884..8c9148426f23cbbdfaf7ae66657d1a620f8bd853 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -203,6 +203,7 @@ import org.bukkit.inventory.MainHand; +@@ -221,6 +221,7 @@ import org.bukkit.inventory.MainHand; public class ServerPlayer extends net.minecraft.world.entity.player.Player implements ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer { // Paper - rewrite chunk system private static final Logger LOGGER = LogUtils.getLogger(); @@ -108,10 +102,10 @@ index 8dc3ba983fd4c61e463867be8d224aa90424215a..6c280abdef5f80b668d6090f9d35283a private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10; private static final int FLY_STAT_RECORDING_SPEED = 25; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 30b6f5d4af1dc799d5ffee6a345bcf92528df7cd..5e2c4969e77c669acbb4a13c07033cb267c3d586 100644 +index 3642444d45038fd1a07768ff96bfbd8678b02e04..f8f8e8f602f416fe97fc23ef6efeee7af2749292 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -569,6 +569,7 @@ public abstract class PlayerList { +@@ -519,6 +519,7 @@ public abstract class PlayerList { protected void save(ServerPlayer player) { if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit @@ -119,7 +113,7 @@ index 30b6f5d4af1dc799d5ffee6a345bcf92528df7cd..5e2c4969e77c669acbb4a13c07033cb2 this.playerIo.save(player); ServerStatsCounter serverstatisticmanager = (ServerStatsCounter) player.getStats(); // CraftBukkit -@@ -1193,10 +1194,22 @@ public abstract class PlayerList { +@@ -1153,10 +1154,22 @@ public abstract class PlayerList { } public void saveAll() { diff --git a/patches/unapplied/server/1011-Optimise-general-POI-access.patch b/patches/server/1050-Optimise-general-POI-access.patch similarity index 97% rename from patches/unapplied/server/1011-Optimise-general-POI-access.patch rename to patches/server/1050-Optimise-general-POI-access.patch index b3636fe59110..0e3d18cfa408 100644 --- a/patches/unapplied/server/1011-Optimise-general-POI-access.patch +++ b/patches/server/1050-Optimise-general-POI-access.patch @@ -886,10 +886,10 @@ index d5a549f08b98c80a5cf0eef02cb8a389c32dfecb..92731b6b593289e9f583c9b705b219e8 BlockPos blockPos = path.getTarget(); Optional> optional = poiManager.getType(blockPos); diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -index d7a6eab60bf26916f78f858e224573560e581fef..a908bf1dc5e821dcf6981a8c21076fb0bdc6516d 100644 +index 5930a430983061afddf20e3208ff2462ca1b78cd..63a94b6068fdaef8bb26675c2927cb729ced1dac 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -@@ -268,36 +268,45 @@ public class PoiManager extends SectionStorage implements ca.spotted +@@ -254,36 +254,45 @@ public class PoiManager extends SectionStorage im public Optional find( Predicate> typePredicate, Predicate posPredicate, BlockPos pos, int radius, PoiManager.Occupancy occupationStatus ) { @@ -903,10 +903,10 @@ index d7a6eab60bf26916f78f858e224573560e581fef..a908bf1dc5e821dcf6981a8c21076fb0 public Optional findClosest(Predicate> typePredicate, BlockPos pos, int radius, PoiManager.Occupancy occupationStatus) { - return this.getInRange(typePredicate, pos, radius, occupationStatus) - .map(PoiRecord::getPos) -- .min(Comparator.comparingDouble(blockPos2 -> blockPos2.distSqr(pos))); +- .min(Comparator.comparingDouble(poiPos -> poiPos.distSqr(pos))); + // Paper start - re-route to faster logic -+ BlockPos ret = io.papermc.paper.util.PoiAccess.findClosestPoiDataPosition(this, typePredicate, null, pos, radius, radius * radius, occupationStatus, false); -+ return Optional.ofNullable(ret); ++ BlockPos closestPos = io.papermc.paper.util.PoiAccess.findClosestPoiDataPosition(this, typePredicate, null, pos, radius, radius * radius, occupationStatus, false); ++ return Optional.ofNullable(closestPos); + // Paper end - re-route to faster logic } @@ -929,27 +929,27 @@ index d7a6eab60bf26916f78f858e224573560e581fef..a908bf1dc5e821dcf6981a8c21076fb0 - return this.getInRange(typePredicate, pos, radius, occupationStatus) - .map(PoiRecord::getPos) - .filter(posPredicate) -- .min(Comparator.comparingDouble(blockPos2 -> blockPos2.distSqr(pos))); +- .min(Comparator.comparingDouble(poiPos -> poiPos.distSqr(pos))); + // Paper start - re-route to faster logic -+ BlockPos ret = io.papermc.paper.util.PoiAccess.findClosestPoiDataPosition(this, typePredicate, posPredicate, pos, radius, radius * radius, occupationStatus, false); -+ return Optional.ofNullable(ret); ++ BlockPos closestPos = io.papermc.paper.util.PoiAccess.findClosestPoiDataPosition(this, typePredicate, posPredicate, pos, radius, radius * radius, occupationStatus, false); ++ return Optional.ofNullable(closestPos); + // Paper end - re-route to faster logic } - public Optional take(Predicate> typePredicate, BiPredicate, BlockPos> biPredicate, BlockPos pos, int radius) { + public Optional take(Predicate> typePredicate, BiPredicate, BlockPos> posPredicate, BlockPos pos, int radius) { - return this.getInRange(typePredicate, pos, radius, PoiManager.Occupancy.HAS_SPACE) -- .filter(poi -> biPredicate.test(poi.getPoiType(), poi.getPos())) +- .filter(poi -> posPredicate.test(poi.getPoiType(), poi.getPos())) - .findFirst() + // Paper start - re-route to faster logic + final @javax.annotation.Nullable PoiRecord closest = io.papermc.paper.util.PoiAccess.findClosestPoiDataRecord( -+ this, typePredicate, biPredicate, pos, radius, radius * radius, Occupancy.HAS_SPACE, false ++ this, typePredicate, posPredicate, pos, radius, radius * radius, Occupancy.HAS_SPACE, false + ); + return Optional.ofNullable(closest) + // Paper end - re-route to faster logic .map(poi -> { poi.acquireTicket(); return poi.getPos(); -@@ -312,8 +321,21 @@ public class PoiManager extends SectionStorage implements ca.spotted +@@ -298,8 +307,21 @@ public class PoiManager extends SectionStorage im int radius, RandomSource random ) { @@ -974,7 +974,7 @@ index d7a6eab60bf26916f78f858e224573560e581fef..a908bf1dc5e821dcf6981a8c21076fb0 public boolean release(BlockPos pos) { diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java -index a6c0e89cb645693034f8e90ac2de8f2da457453c..11e895d837794d79a76303b912092096bd7d07a8 100644 +index 712cbfc100e8aaf612d1d651dae64f57f892a768..827991ee61406bcda3f4794dcc735c0e2e0e09af 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java @@ -26,7 +26,7 @@ import org.slf4j.Logger; @@ -987,10 +987,10 @@ index a6c0e89cb645693034f8e90ac2de8f2da457453c..11e895d837794d79a76303b912092096 private boolean isValid; diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java -index c7ed3eb80f6e8b918434153093644776866aa220..21de1b95f2a5d136149447472e871f675760ba1a 100644 +index c3beb7fcad46a917d2b61bd0a0e98e5106056728..9b97fb2d125df4df715599aab27e074707731466 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java -@@ -81,11 +81,11 @@ public abstract class SectionStorage implements AutoCloseable, ca.spottedleaf +@@ -131,11 +131,11 @@ public class SectionStorage implements AutoCloseable, ca.spottedleaf.moonr } @Nullable @@ -1005,7 +1005,7 @@ index c7ed3eb80f6e8b918434153093644776866aa220..21de1b95f2a5d136149447472e871f67 return Optional.empty(); } else { diff --git a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java -index fd04a50183ccb1f21fc6efa70256e1bb4db2d6d4..49f7ba292b82bac1643cc07aa576f3c37b8e8ab3 100644 +index 83d294f6f48b867d09ea0d339c779011bf4138a5..9204bb0538297f233442a86733a33e6d0eea8114 100644 --- a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java +++ b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java @@ -53,17 +53,39 @@ public class PortalForcer { diff --git a/patches/unapplied/server/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch b/patches/server/1051-Fix-entity-tracker-desync-when-new-players-are-added.patch similarity index 74% rename from patches/unapplied/server/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch rename to patches/server/1051-Fix-entity-tracker-desync-when-new-players-are-added.patch index f767b9ab9193..6aecc462a4d0 100644 --- a/patches/unapplied/server/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch +++ b/patches/server/1051-Fix-entity-tracker-desync-when-new-players-are-added.patch @@ -29,7 +29,7 @@ client will not tick the entity and thus not lerp the entity from its old position to its new position. diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java -index 854baa554da2215a656f976ae2973341c3b2d61c..792b9a72a610cc512a8920d61013b6ba02f71e47 100644 +index f6e1deb2f849d8b01b15cfa69e2f6cd5f2b1512b..f66e40326c510aa3267542b1a24ed75d1ed6d3f1 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java @@ -42,9 +42,11 @@ public class ClientboundAddEntityPacket implements Packet= 1 || Math.abs(b1 - this.lastSentXRot) >= 1; +@@ -199,7 +206,7 @@ public class ServerEntity { + long k = this.positionCodec.encodeZ(vec3d); + boolean flag5 = i < -32768L || i > 32767L || j < -32768L || j > 32767L || k < -32768L || k > 32767L; -@@ -185,7 +192,7 @@ public class ServerEntity { - long i1 = this.positionCodec.encodeZ(vec3d); - boolean flag6 = k < -32768L || k > 32767L || l < -32768L || l > 32767L || i1 < -32768L || i1 > 32767L; - -- if (!flag6 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.onGround()) { -+ if (!this.forceStateResync && !flag6 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.onGround()) { // Paper - fix desync when a player is added to the tracker - if ((!flag2 || !flag3) && !(this.entity instanceof AbstractArrow)) { - if (flag2) { - packet1 = new ClientboundMoveEntityPacket.Pos(this.entity.getId(), (short) ((int) k), (short) ((int) l), (short) ((int) i1), this.entity.onGround()); -@@ -249,6 +256,7 @@ public class ServerEntity { +- if (!flag5 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.onGround()) { ++ if (!this.forceStateResync && !flag5 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.onGround()) { // Paper - fix desync when a player is added to the tracker + if ((!flag2 || !flag) && !(this.entity instanceof AbstractArrow)) { + if (flag2) { + packet1 = new ClientboundMoveEntityPacket.Pos(this.entity.getId(), (short) ((int) i), (short) ((int) j), (short) ((int) k), this.entity.onGround()); +@@ -265,6 +272,7 @@ public class ServerEntity { } this.entity.hasImpulse = false; diff --git a/patches/unapplied/server/1026-Lag-compensation-ticks.patch b/patches/server/1052-Lag-compensation-ticks.patch similarity index 81% rename from patches/unapplied/server/1026-Lag-compensation-ticks.patch rename to patches/server/1052-Lag-compensation-ticks.patch index aa8b7f2d462c..2643c943aabb 100644 --- a/patches/unapplied/server/1026-Lag-compensation-ticks.patch +++ b/patches/server/1052-Lag-compensation-ticks.patch @@ -8,10 +8,10 @@ Areas affected by lag comepnsation: - Eating food items diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index d25d500a2206d4f7e821de3766e8a523df4370e3..b64c3e29e2b8e890073fee0b45c8b8dfc2b642fd 100644 +index f422cbcb69d6fda2b4e229cbdbf10abd0d36d6f9..73855f4555f781741f70267be65dec1ebb98b46a 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -321,6 +321,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); -@@ -1763,6 +1764,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers + worldserver.updateLagCompensationTick(); // Paper - lag compensation - this.profiler.push(() -> { + gameprofilerfiller.push(() -> { String s = String.valueOf(worldserver); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index d223ecfbb0b8986507ce8b6728edbf7c8d818b7d..9e1af229f52a8ac09833901ad53bd154fed34a4f 100644 +index fd07824ff6a928ca6e2f56477a63bac7aaeb8c15..b2bbc9f3efbb7c949cc862eeee5d5f47be5d804f 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -485,6 +485,17 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - return this.entityTickingChunks; +@@ -577,6 +577,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + ); } - // Paper end - rewrite chunk system + // Paper end - chunk tick iteration + // Paper start - lag compensation + private long lagCompensationTick = net.minecraft.server.MinecraftServer.SERVER_INIT; + @@ -50,10 +50,10 @@ index d223ecfbb0b8986507ce8b6728edbf7c8d818b7d..9e1af229f52a8ac09833901ad53bd154 // Add env and gen to constructor, IWorldDataServer -> WorldDataServer public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, 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/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index 24b1715397ba8e6f5e9841a030d0e3d964356f89..cc01ead133cc6859ca5d7a1d0ac3c12955e590da 100644 +index 504c996220b278c194c93e001a3b326d549868ec..a96f859a5d0c6ec692d4627a69f3c9ee49199dbc 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -129,7 +129,7 @@ public class ServerPlayerGameMode { +@@ -127,7 +127,7 @@ public class ServerPlayerGameMode { } public void tick() { @@ -63,10 +63,10 @@ index 24b1715397ba8e6f5e9841a030d0e3d964356f89..cc01ead133cc6859ca5d7a1d0ac3c129 if (this.hasDelayedDestroy) { diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 5079775ce8f86fb061e616190513f56ff086e409..13c93281f6b81e88f2f54befb8e6a3e4bdabf53d 100644 +index 22b3d3d945cbddae25abfca7d900324c79d32293..a68ca22d5f8909d2ad37feded448f777736bf7db 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3900,6 +3900,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4052,6 +4052,10 @@ public abstract class LivingEntity extends Entity implements Attackable { this.resendPossiblyDesyncedDataValues(java.util.List.of(DATA_LIVING_ENTITY_FLAGS), serverPlayer); } // Paper end - Properly cancel usable items @@ -77,21 +77,21 @@ index 5079775ce8f86fb061e616190513f56ff086e409..13c93281f6b81e88f2f54befb8e6a3e4 private void updatingUsingItem() { if (this.isUsingItem()) { if (ItemStack.isSameItem(this.getItemInHand(this.getUsedItemHand()), this.useItem)) { -@@ -3918,7 +3922,12 @@ public abstract class LivingEntity extends Entity implements Attackable { - this.triggerItemUseEffects(stack, 5); - } +@@ -4066,7 +4070,12 @@ public abstract class LivingEntity extends Entity implements Attackable { + protected void updateUsingItem(ItemStack stack) { + stack.onUseTick(this.level(), this, this.getUseItemRemainingTicks()); - if (--this.useItemRemaining == 0 && !this.level().isClientSide && !stack.useOnRelease()) { + // Paper start - lag compensate eating + // we add 1 to the expected time to avoid lag compensating when we should not -+ boolean shouldLagCompensate = this.useItem.has(DataComponents.FOOD) && this.eatStartTime != -1 && (System.nanoTime() - this.eatStartTime) > ((1L + this.totalEatTimeTicks) * 50L * (1000L * 1000L)); ++ final boolean shouldLagCompensate = this.useItem.has(DataComponents.FOOD) && this.eatStartTime != -1 && (System.nanoTime() - this.eatStartTime) > ((1L + this.totalEatTimeTicks) * 50L * (1000L * 1000L)); + if ((--this.useItemRemaining == 0 || shouldLagCompensate) && !this.level().isClientSide && !stack.useOnRelease()) { + this.useItemRemaining = 0; + // Paper end - lag compensate eating this.completeUsingItem(); } -@@ -3964,7 +3973,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4104,7 +4113,10 @@ public abstract class LivingEntity extends Entity implements Attackable { if (!itemstack.isEmpty() && !this.isUsingItem() || forceUpdate) { // Paper - Prevent consuming the wrong itemstack this.useItem = itemstack; @@ -103,7 +103,7 @@ index 5079775ce8f86fb061e616190513f56ff086e409..13c93281f6b81e88f2f54befb8e6a3e4 if (!this.level().isClientSide) { this.setLivingEntityFlag(1, true); this.setLivingEntityFlag(2, hand == InteractionHand.OFF_HAND); -@@ -3989,7 +4001,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4129,7 +4141,10 @@ public abstract class LivingEntity extends Entity implements Attackable { } } else if (!this.isUsingItem() && !this.useItem.isEmpty()) { this.useItem = ItemStack.EMPTY; @@ -115,7 +115,7 @@ index 5079775ce8f86fb061e616190513f56ff086e409..13c93281f6b81e88f2f54befb8e6a3e4 } } -@@ -4132,7 +4147,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4260,7 +4275,10 @@ public abstract class LivingEntity extends Entity implements Attackable { } this.useItem = ItemStack.EMPTY; diff --git a/patches/unapplied/server/1039-Optimise-collision-checking-in-player-move-packet-ha.patch b/patches/server/1053-Optimise-collision-checking-in-player-move-packet-ha.patch similarity index 93% rename from patches/unapplied/server/1039-Optimise-collision-checking-in-player-move-packet-ha.patch rename to patches/server/1053-Optimise-collision-checking-in-player-move-packet-ha.patch index 2caf83aaca86..a75038dc8aa6 100644 --- a/patches/unapplied/server/1039-Optimise-collision-checking-in-player-move-packet-ha.patch +++ b/patches/server/1053-Optimise-collision-checking-in-player-move-packet-ha.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Optimise collision checking in player move packet handling Move collision logic to just the hasNewCollision call instead of getCubes + hasNewCollision diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d6aeb69a0 100644 +index eef96e946b80064fe211039a65db4192ea7a52d3..c4b016a2fb5c79fb3f191e243712bee7cbe5cd2c 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -572,7 +572,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -577,7 +577,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return; } @@ -18,7 +18,7 @@ index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d d6 = d3 - this.vehicleLastGoodX; // Paper - diff on change, used for checking large move vectors above d7 = d4 - this.vehicleLastGoodY - 1.0E-6D; // Paper - diff on change, used for checking large move vectors above -@@ -588,6 +588,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -593,6 +593,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } entity.move(MoverType.PLAYER, new Vec3(d6, d7, d8)); @@ -26,7 +26,7 @@ index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d double d11 = d7; d6 = d3 - entity.getX(); -@@ -601,15 +602,23 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -606,15 +607,23 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl boolean flag2 = false; if (d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot @@ -53,7 +53,7 @@ index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d entity.absMoveTo(d0, d1, d2, f, f1); this.player.absMoveTo(d0, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit this.send(new ClientboundMoveVehiclePacket(entity)); -@@ -691,7 +700,32 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -697,7 +706,32 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } private boolean noBlocksAround(Entity entity) { @@ -87,7 +87,7 @@ index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d } @Override -@@ -1386,7 +1420,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1398,7 +1432,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } @@ -96,7 +96,7 @@ index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d d6 = d0 - this.lastGoodX; // Paper - diff on change, used for checking large move vectors above d7 = d1 - this.lastGoodY; // Paper - diff on change, used for checking large move vectors above -@@ -1428,6 +1462,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1440,6 +1474,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.move(MoverType.PLAYER, new Vec3(d6, d7, d8)); this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move @@ -104,7 +104,7 @@ index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d // Paper start - prevent position desync if (this.awaitingPositionFromClient != null) { return; // ... thanks Mojang for letting move calls teleport across dimensions. -@@ -1458,7 +1493,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1470,7 +1505,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // Paper start - Add fail move event @@ -123,7 +123,7 @@ index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d if (teleportBack) { io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK, toX, toY, toZ, toYaw, toPitch, false); -@@ -1569,7 +1614,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1594,7 +1639,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private boolean updateAwaitingTeleport() { if (this.awaitingPositionFromClient != null) { @@ -132,7 +132,7 @@ index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d this.awaitingTeleportTime = this.tickCount; this.teleport(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.getYRot(), this.player.getXRot()); } -@@ -1582,6 +1627,33 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1607,6 +1652,33 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } diff --git a/patches/unapplied/server/1028-Write-SavedData-IO-async.patch b/patches/unapplied/server/1028-Write-SavedData-IO-async.patch deleted file mode 100644 index cceb676e45af..000000000000 --- a/patches/unapplied/server/1028-Write-SavedData-IO-async.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Cryptite -Date: Tue, 27 Jun 2023 11:35:52 -0500 -Subject: [PATCH] Write SavedData IO async - -Co-Authored-By: Shane Freeder - -diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 4a5dc7fd4eb1a7ab1ec371f0f107de882f88149c..dcb5651d1d9b10b40430fb2f713beedf68336704 100644 ---- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java -+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -369,6 +369,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - - public void close(boolean save) throws IOException { - ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.close(save, true); // Paper - rewrite chunk system -+ // Paper start - Write SavedData IO async -+ try { -+ this.dataStorage.close(); -+ } catch (final IOException e) { -+ LOGGER.error("Failed to close persistent world data", e); -+ } -+ // Paper end - Write SavedData IO async - } - - // CraftBukkit start - modelled on below -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index c5698b05cc3ea4cb1bc6789c30f2aab76748d491..2931e1dd0c8ae5ac1c9ec42f90dd5ab57595bf60 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1330,7 +1330,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel")); - } - -- this.saveLevelData(); -+ this.saveLevelData(!close); // Paper - Write SavedData IO async - if (progressListener != null) { - progressListener.progressStage(Component.translatable("menu.savingChunks")); - } -@@ -1361,12 +1361,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - // CraftBukkit end - } - -- private void saveLevelData() { -+ private void saveLevelData(boolean async) { // Paper - Write SavedData IO async - if (this.dragonFight != null) { - this.serverLevelData.setEndDragonFightData(this.dragonFight.saveData()); // CraftBukkit - } - -- this.getChunkSource().getDataStorage().save(); -+ this.getChunkSource().getDataStorage().save(async); // Paper - Write SavedData IO async - } - - public List getEntities(EntityTypeTest filter, Predicate predicate) { -diff --git a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java -index 0382b6597a130d746f8954a93a756a9d1ac81d50..cb39c629af1827078f35904a373d35a63fea17ff 100644 ---- a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java -+++ b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java -@@ -116,7 +116,13 @@ public class WorldUpgrader { - (new WorldUpgrader.PoiUpgrader(this)).upgrade(); - WorldUpgrader.LOGGER.info("Upgrading blocks"); - (new WorldUpgrader.ChunkUpgrader()).upgrade(); -- this.overworldDataStorage.save(); -+ // Paper start - Write SavedData IO async -+ try { -+ this.overworldDataStorage.close(); -+ } catch (final IOException e) { -+ LOGGER.error("Failed to close persistent world data", e); -+ } -+ // Paper end - Write SavedData IO async - i = Util.getMillis() - i; - WorldUpgrader.LOGGER.info("World optimizaton finished after {} seconds", i / 1000L); - this.finished = true; -diff --git a/src/main/java/net/minecraft/world/level/saveddata/SavedData.java b/src/main/java/net/minecraft/world/level/saveddata/SavedData.java -index 9cc3850bb70dfbcf342651360314a19fd9ea3ecc..4cbb943b702baaeb8bfd2b558cc848e719cf095d 100644 ---- a/src/main/java/net/minecraft/world/level/saveddata/SavedData.java -+++ b/src/main/java/net/minecraft/world/level/saveddata/SavedData.java -@@ -30,20 +30,36 @@ public abstract class SavedData { - return this.dirty; - } - -+ // Paper start - Write SavedData IO async - joining is evil, but we assume the old blocking behavior here just for safety -+ @io.papermc.paper.annotation.DoNotUse - public void save(File file, HolderLookup.Provider registryLookup) { -+ save(file, registryLookup, null).join(); -+ } -+ -+ public java.util.concurrent.CompletableFuture save(File file, HolderLookup.Provider registryLookup, @org.jetbrains.annotations.Nullable java.util.concurrent.ExecutorService ioExecutor) { -+ // Paper end - Write SavedData IO async - if (this.isDirty()) { - CompoundTag compoundTag = new CompoundTag(); - compoundTag.put("data", this.save(new CompoundTag(), registryLookup)); - NbtUtils.addCurrentDataVersion(compoundTag); - -+ Runnable writeRunnable = () -> { // Paper - Write SavedData IO async - try { - NbtIo.writeCompressed(compoundTag, file.toPath()); - } catch (IOException var5) { - LOGGER.error("Could not save data {}", this, var5); - } -+ }; // Paper - Write SavedData IO async - - this.setDirty(false); -+ // Paper start - Write SavedData IO async -+ if (ioExecutor == null) { -+ return java.util.concurrent.CompletableFuture.runAsync(writeRunnable); // No executor, just use common pool -+ } -+ return java.util.concurrent.CompletableFuture.runAsync(writeRunnable, ioExecutor); - } -+ return java.util.concurrent.CompletableFuture.completedFuture(null); -+ // Paper end - Write SavedData IO async - } - - public static record Factory( -diff --git a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java -index 7d98d2911e9d6ec429ce7df1f1f2650c7ea32325..6e23e69abd56eeda3b52a22019e1b74ae10682e7 100644 ---- a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java -+++ b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java -@@ -23,17 +23,19 @@ import net.minecraft.util.datafix.DataFixTypes; - import net.minecraft.world.level.saveddata.SavedData; - import org.slf4j.Logger; - --public class DimensionDataStorage { -+public class DimensionDataStorage implements java.io.Closeable { // Paper - Write SavedData IO async - private static final Logger LOGGER = LogUtils.getLogger(); - public final Map cache = Maps.newHashMap(); - private final DataFixer fixerUpper; - private final HolderLookup.Provider registries; - private final File dataFolder; -+ protected final java.util.concurrent.ExecutorService ioExecutor; // Paper - Write SavedData IO async - - public DimensionDataStorage(File directory, DataFixer dataFixer, HolderLookup.Provider registryLookup) { - this.fixerUpper = dataFixer; - this.dataFolder = directory; - this.registries = registryLookup; -+ this.ioExecutor = java.util.concurrent.Executors.newSingleThreadExecutor(new com.google.common.util.concurrent.ThreadFactoryBuilder().setNameFormat("DimensionDataIO - " + dataFolder.getParent() + " - %d").setDaemon(true).build()); // Paper - Write SavedData IO async - } - - private File getDataFile(String id) { -@@ -123,10 +125,23 @@ public class DimensionDataStorage { - return bl; - } - -- public void save() { -+ // Paper start - Write SavedData IO async -+ @Override -+ public void close() throws IOException { -+ save(false); -+ this.ioExecutor.shutdown(); -+ } -+ // Paper end - Write SavedData IO async -+ -+ public void save(boolean async) { // Paper - Write SavedData IO async - this.cache.forEach((id, state) -> { - if (state != null) { -- state.save(this.getDataFile(id), this.registries); -+ // Paper start - Write SavedData IO async -+ final java.util.concurrent.CompletableFuture save = state.save(this.getDataFile(id), this.registries, this.ioExecutor); -+ if (!async) { -+ save.join(); -+ } -+ // Paper end - Write SavedData IO async - } - }); - } From 3cb16c9d91eb133a9d95605bdb8afc6ed40d6ee9 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Sun, 27 Oct 2024 11:56:51 +0100 Subject: [PATCH 096/119] Add back per player mob spawning Also removes the `info.mobCategoryCounts.mergeInt` call that - at least from what I can tell - has been wrongly counting spawned mobs twice. The runner passed via `info::afterSpawn` already counts up that exact number in the same exact places (where `j`, the return value used here, is incremented) --- ...1054-Optional-per-player-mob-spawns.patch} | 181 ++++++++---------- 1 file changed, 76 insertions(+), 105 deletions(-) rename patches/{later/0991-Optional-per-player-mob-spawns.patch => server/1054-Optional-per-player-mob-spawns.patch} (51%) diff --git a/patches/later/0991-Optional-per-player-mob-spawns.patch b/patches/server/1054-Optional-per-player-mob-spawns.patch similarity index 51% rename from patches/later/0991-Optional-per-player-mob-spawns.patch rename to patches/server/1054-Optional-per-player-mob-spawns.patch index fee5589666b9..e08da27a0488 100644 --- a/patches/later/0991-Optional-per-player-mob-spawns.patch +++ b/patches/server/1054-Optional-per-player-mob-spawns.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Optional per player mob spawns diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 48b8fa3dea0244f9a0f4e0b8850b17a6d23b639c..56f7a63e65cce587512b77aafdb4ced18b43d024 100644 +index bf43bdb43c5301c0e0954729bc531fb6a5045075..97a24cb410cf7d22a1a8edf8a5622d03a3d5a9c7 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -223,8 +223,26 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -231,8 +231,26 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } // Paper start @@ -37,43 +37,44 @@ index 48b8fa3dea0244f9a0f4e0b8850b17a6d23b639c..56f7a63e65cce587512b77aafdb4ced1 // Paper end diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 9ccb3ffc375298fda4dca97803e65e39df8493eb..e18c3e08f9fbfe17c797c1f96dce1b86fa41fab6 100644 +index 4b5985c284faac7b06c0f99d53065f5060ecff4a..ba989879c43cb7d614198444fd2ead85ea71eae9 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -450,14 +450,26 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - gameprofilerfiller.popPush("naturalSpawnCount"); - this.level.timings.countNaturalMobs.startTiming(); // Paper - timings - int k = this.distanceManager.getNaturalSpawnChunkCount(); -- NaturalSpawner.SpawnState spawnercreature_d = NaturalSpawner.createState(k, this.level.getAllEntities(), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap)); -+ // Paper start - Optional per player mob spawns -+ int naturalSpawnChunkCount = k; -+ NaturalSpawner.SpawnState spawnercreature_d; // moved down -+ if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled -+ // re-set mob counts -+ for (ServerPlayer player : this.level.players) { -+ Arrays.fill(player.mobCounts, 0); -+ } -+ spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, null, true); -+ } else { -+ spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); -+ } -+ // Paper end - Optional per player mob spawns - this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings - - this.lastSpawnState = spawnercreature_d; - gameprofilerfiller.popPush("spawnAndTick"); - boolean flag = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit +@@ -503,7 +503,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + gameprofilerfiller.popPush("shuffleChunks"); + // Paper start - chunk tick iteration optimisation + this.shuffleRandom.setSeed(this.level.random.nextLong()); +- Util.shuffle(list, this.shuffleRandom); ++ if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) Util.shuffle(list, this.shuffleRandom); // Paper - Optional per player mob spawns; do not need this when per-player is enabled + // Paper end - chunk tick iteration optimisation + this.tickChunks(gameprofilerfiller, j, list); + gameprofilerfiller.pop(); +@@ -563,7 +563,19 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + profiler.popPush("naturalSpawnCount"); + this.level.timings.countNaturalMobs.startTiming(); // Paper - timings + int j = this.distanceManager.getNaturalSpawnChunkCount(); +- NaturalSpawner.SpawnState spawnercreature_d = NaturalSpawner.createState(j, this.level.getAllEntities(), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap)); ++ // Paper start - Optional per player mob spawns ++ final int naturalSpawnChunkCount = j; ++ NaturalSpawner.SpawnState spawnercreature_d; // moved down ++ if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled ++ // re-set mob counts ++ for (ServerPlayer player : this.level.players) { ++ Arrays.fill(player.mobCounts, 0); ++ } ++ spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, null, true); ++ } else { ++ spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); ++ } ++ // Paper end - Optional per player mob spawns + this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings -- Util.shuffle(list, this.level.random); -+ if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) Util.shuffle(list, this.level.random); // Paper - per player mob spawns - do not need this when per-player is enabled - // Paper start - PlayerNaturallySpawnCreaturesEvent - int chunkRange = level.spigotConfig.mobSpawnRange; - chunkRange = (chunkRange > level.spigotConfig.viewDistance) ? (byte) level.spigotConfig.viewDistance : chunkRange; + 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 30f53916a9e49165bcfef2bea2c0b50a26f5a8a3..cb961d9051416626f499c1ca87107f1114433c94 100644 +index 8c9148426f23cbbdfaf7ae66657d1a620f8bd853..8cc02ee9b1a710e35eb65a5a095681cc7dc542bb 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -276,6 +276,10 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple +@@ -303,6 +303,10 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple public boolean queueHealthUpdatePacket; public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket; // Paper end - cancellable death event @@ -85,10 +86,10 @@ index 30f53916a9e49165bcfef2bea2c0b50a26f5a8a3..cb961d9051416626f499c1ca87107f11 // CraftBukkit start public CraftPlayer.TransferCookieConnection transferCookieConnection; diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index ea6533c1ac218aa075da3401807a06fcb7892321..364510c0d0667e67aa3b25099a021f5f856fc113 100644 +index 6eb69ebe688c1c52d5a5986dfc63cdd42e66687e..f3b52e61ddde25a60c1d178a7607b220ca01f770 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -67,6 +67,12 @@ public final class NaturalSpawner { +@@ -71,6 +71,12 @@ public final class NaturalSpawner { private NaturalSpawner() {} public static NaturalSpawner.SpawnState createState(int spawningChunkCount, Iterable entities, NaturalSpawner.ChunkGetter chunkSource, LocalMobCapCalculator densityCapper) { @@ -101,7 +102,7 @@ index ea6533c1ac218aa075da3401807a06fcb7892321..364510c0d0667e67aa3b25099a021f5f PotentialCalculator spawnercreatureprobabilities = new PotentialCalculator(); Object2IntOpenHashMap object2intopenhashmap = new Object2IntOpenHashMap(); Iterator iterator = entities.iterator(); -@@ -99,11 +105,16 @@ public final class NaturalSpawner { +@@ -103,11 +109,16 @@ public final class NaturalSpawner { spawnercreatureprobabilities.addCharge(entity.blockPosition(), biomesettingsmobs_b.charge()); } @@ -119,17 +120,32 @@ index ea6533c1ac218aa075da3401807a06fcb7892321..364510c0d0667e67aa3b25099a021f5f }); } } -@@ -138,13 +149,35 @@ public final class NaturalSpawner { +@@ -142,7 +153,7 @@ public final class NaturalSpawner { continue; } -- if ((spawnAnimals || !enumcreaturetype.isFriendly()) && (spawnMonsters || enumcreaturetype.isFriendly()) && (rareSpawn || !enumcreaturetype.isPersistent()) && info.canSpawnForCategory(enumcreaturetype, chunk.getPos(), limit)) { -+ // Paper start - Optional per player mob spawns; only allow spawns upto the limit per chunk and update count afterwards -+ int currEntityCount = info.mobCategoryCounts.getInt(enumcreaturetype); -+ int k1 = limit * info.getSpawnableChunkCount() / NaturalSpawner.MAGIC_NUMBER; -+ int difference = k1 - currEntityCount; -+ +- if ((flag || !enumcreaturetype.isFriendly()) && (flag1 || enumcreaturetype.isFriendly()) && (flag2 || !enumcreaturetype.isPersistent()) && spawnercreature_d.canSpawnForCategoryGlobal(enumcreaturetype, limit)) { ++ if ((flag || !enumcreaturetype.isFriendly()) && (flag1 || enumcreaturetype.isFriendly()) && (flag2 || !enumcreaturetype.isPersistent()) && (!worldserver.paperConfig().entities.spawning.perPlayerMobSpawns || spawnercreature_d.canSpawnForCategoryGlobal(enumcreaturetype, limit))) { // Paper - Optional per player mob spawns; remove global check, check later during the local one + // CraftBukkit end + list.add(enumcreaturetype); + } +@@ -161,12 +172,43 @@ public final class NaturalSpawner { + while (iterator.hasNext()) { + MobCategory enumcreaturetype = (MobCategory) iterator.next(); + +- if (info.canSpawnForCategoryLocal(enumcreaturetype, chunk.getPos())) { ++ // Paper start - Optional per player mob spawns ++ final boolean canSpawn; ++ int maxSpawns = Integer.MAX_VALUE; + if (world.paperConfig().entities.spawning.perPlayerMobSpawns) { ++ // Copied from getFilteredSpawningCategories ++ int limit = enumcreaturetype.getMaxInstancesPerChunk(); ++ SpawnCategory spawnCategory = CraftSpawnCategory.toBukkit(enumcreaturetype); ++ if (CraftSpawnCategory.isValidForLimits(spawnCategory)) { ++ limit = world.getWorld().getSpawnLimit(spawnCategory); ++ } ++ ++ // Apply per-player limit + int minDiff = Integer.MAX_VALUE; + final ca.spottedleaf.moonrise.common.list.ReferenceList inRange = + world.moonrise$getNearbyPlayers().getPlayers(chunk.getPos(), ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.TICK_VIEW_DISTANCE); @@ -139,44 +155,44 @@ index ea6533c1ac218aa075da3401807a06fcb7892321..364510c0d0667e67aa3b25099a021f5f + minDiff = Math.min(limit - world.getChunkSource().chunkMap.getMobCountNear(backingSet[k], enumcreaturetype), minDiff); + } + } -+ difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff; ++ ++ maxSpawns = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff; ++ canSpawn = maxSpawns > 0; ++ } else { ++ canSpawn = info.canSpawnForCategoryLocal(enumcreaturetype, chunk.getPos()); + } -+ if ((spawnAnimals || !enumcreaturetype.isFriendly()) && (spawnMonsters || enumcreaturetype.isFriendly()) && (rareSpawn || !enumcreaturetype.isPersistent()) && difference > 0) { ++ if (canSpawn) { + // Paper end - Optional per player mob spawns - // CraftBukkit end Objects.requireNonNull(info); NaturalSpawner.SpawnPredicate spawnercreature_c = info::canSpawn; Objects.requireNonNull(info); - NaturalSpawner.spawnCategoryForChunk(enumcreaturetype, world, chunk, spawnercreature_c, info::afterSpawn); + // Paper start - Optional per player mob spawns -+ int spawnCount = NaturalSpawner.spawnCategoryForChunk(enumcreaturetype, world, chunk, spawnercreature_c, info::afterSpawn, -+ difference, world.paperConfig().entities.spawning.perPlayerMobSpawns ? world.getChunkSource().chunkMap::updatePlayerMobTypeMap : null); -+ info.mobCategoryCounts.mergeInt(enumcreaturetype, spawnCount, Integer::sum); ++ NaturalSpawner.spawnCategoryForChunk(enumcreaturetype, world, chunk, spawnercreature_c, info::afterSpawn, ++ maxSpawns, world.paperConfig().entities.spawning.perPlayerMobSpawns ? world.getChunkSource().chunkMap::updatePlayerMobTypeMap : null); + // Paper end - Optional per player mob spawns } } -@@ -163,11 +196,17 @@ public final class NaturalSpawner { +@@ -185,10 +227,15 @@ public final class NaturalSpawner { // Paper end - Add mobcaps commands public static void spawnCategoryForChunk(MobCategory group, ServerLevel world, LevelChunk chunk, NaturalSpawner.SpawnPredicate checker, NaturalSpawner.AfterSpawnCallback runner) { + // Paper start - Optional per player mob spawns + spawnCategoryForChunk(group, world, chunk, checker, runner, Integer.MAX_VALUE, null); + } -+ public static int spawnCategoryForChunk(MobCategory group, ServerLevel world, LevelChunk chunk, NaturalSpawner.SpawnPredicate checker, NaturalSpawner.AfterSpawnCallback runner, int maxSpawns, Consumer trackEntity) { ++ public static void spawnCategoryForChunk(MobCategory group, ServerLevel world, LevelChunk chunk, NaturalSpawner.SpawnPredicate checker, NaturalSpawner.AfterSpawnCallback runner, int maxSpawns, Consumer trackEntity) { + // Paper end - Optional per player mob spawns BlockPos blockposition = NaturalSpawner.getRandomPosWithin(world, chunk); - if (blockposition.getY() >= world.getMinBuildHeight() + 1) { + if (blockposition.getY() >= world.getMinY() + 1) { - NaturalSpawner.spawnCategoryForPosition(group, world, chunk, blockposition, checker, runner); -+ return NaturalSpawner.spawnCategoryForPosition(group, world, chunk, blockposition, checker, runner, maxSpawns, trackEntity); // Paper - Optional per player mob spawns ++ NaturalSpawner.spawnCategoryForPosition(group, world, chunk, blockposition, checker, runner, maxSpawns, trackEntity); // Paper - Optional per player mob spawns } -+ return 0; // Paper - Optional per player mob spawns } - @VisibleForDebug -@@ -178,15 +217,21 @@ public final class NaturalSpawner { +@@ -200,7 +247,12 @@ public final class NaturalSpawner { }); } @@ -184,39 +200,12 @@ index ea6533c1ac218aa075da3401807a06fcb7892321..364510c0d0667e67aa3b25099a021f5f public static void spawnCategoryForPosition(MobCategory group, ServerLevel world, ChunkAccess chunk, BlockPos pos, NaturalSpawner.SpawnPredicate checker, NaturalSpawner.AfterSpawnCallback runner) { + spawnCategoryForPosition(group, world,chunk, pos, checker, runner, Integer.MAX_VALUE, null); + } -+ public static int spawnCategoryForPosition(MobCategory group, ServerLevel world, ChunkAccess chunk, BlockPos pos, NaturalSpawner.SpawnPredicate checker, NaturalSpawner.AfterSpawnCallback runner, int maxSpawns, Consumer trackEntity) { ++ public static void spawnCategoryForPosition(MobCategory group, ServerLevel world, ChunkAccess chunk, BlockPos pos, NaturalSpawner.SpawnPredicate checker, NaturalSpawner.AfterSpawnCallback runner, int maxSpawns, Consumer trackEntity) { + // Paper end - Optional per player mob spawns StructureManager structuremanager = world.structureManager(); ChunkGenerator chunkgenerator = world.getChunkSource().getGenerator(); int i = pos.getY(); - BlockState iblockdata = world.getBlockStateIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn -+ int j = 0; // Paper - Optional per player mob spawns; moved up - - if (iblockdata != null && !iblockdata.isRedstoneConductor(chunk, pos)) { // Paper - don't load chunks for mob spawn - BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); -- int j = 0; -+ //int j = 0; // Paper - Optional per player mob spawns; moved up - int k = 0; - - while (k < 3) { -@@ -228,14 +273,14 @@ public final class NaturalSpawner { - // Paper start - PreCreatureSpawnEvent - PreSpawnStatus doSpawning = isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2); - if (doSpawning == PreSpawnStatus.ABORT) { -- return; -+ return j; // Paper - Optional per player mob spawns - } - if (doSpawning == PreSpawnStatus.SUCCESS && checker.test(biomesettingsmobs_c.type, blockposition_mutableblockposition, chunk)) { - // Paper end - PreCreatureSpawnEvent - Mob entityinsentient = NaturalSpawner.getMobForSpawn(world, biomesettingsmobs_c.type); - - if (entityinsentient == null) { -- return; -+ return j; // Paper - Optional per player mob spawns - } - - entityinsentient.moveTo(d0, (double) i, d1, world.random.nextFloat() * 360.0F, 0.0F); -@@ -248,10 +293,15 @@ public final class NaturalSpawner { +@@ -270,9 +322,14 @@ public final class NaturalSpawner { ++j; ++k1; runner.run(entityinsentient, chunk); @@ -228,21 +217,11 @@ index ea6533c1ac218aa075da3401807a06fcb7892321..364510c0d0667e67aa3b25099a021f5f } // CraftBukkit end - if (j >= entityinsentient.getMaxSpawnClusterSize()) { -- return; + if (j >= entityinsentient.getMaxSpawnClusterSize() || j >= maxSpawns) { // Paper - Optional per player mob spawns -+ return j; // Paper - Optional per player mob spawns + return; } - if (entityinsentient.isMaxGroupSizeReached(k1)) { -@@ -273,6 +323,7 @@ public final class NaturalSpawner { - } - - } -+ return j; // Paper - Optional per player mob spawns - } - - private static boolean isRightDistanceToPlayerAndSpawnPoint(ServerLevel world, ChunkAccess chunk, BlockPos.MutableBlockPos pos, double squaredDistance) { -@@ -523,7 +574,7 @@ public final class NaturalSpawner { +@@ -545,7 +602,7 @@ public final class NaturalSpawner { MobCategory enumcreaturetype = entitytypes.getCategory(); this.mobCategoryCounts.addTo(enumcreaturetype, 1); @@ -251,11 +230,3 @@ index ea6533c1ac218aa075da3401807a06fcb7892321..364510c0d0667e67aa3b25099a021f5f } public int getSpawnableChunkCount() { -@@ -539,6 +590,7 @@ public final class NaturalSpawner { - int i = limit * this.spawnableChunkCount / NaturalSpawner.MAGIC_NUMBER; - // CraftBukkit end - -+ if (this.localMobCapCalculator == null) return this.mobCategoryCounts.getInt(enumcreaturetype) < i; // Paper - Optional per player mob spawns - return this.mobCategoryCounts.getInt(enumcreaturetype) >= i ? false : this.localMobCapCalculator.canSpawn(enumcreaturetype, chunkcoordintpair); - } - } From fe7b7415459bcb673b39400a7cb22d2b1de79ef5 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Sun, 27 Oct 2024 12:02:26 +0100 Subject: [PATCH 097/119] Another one --- ...g-PreCreatureSpawnEvent-with-per-pl.patch} | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) rename patches/{unapplied/server/0995-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch => server/1055-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch} (68%) diff --git a/patches/unapplied/server/0995-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch b/patches/server/1055-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch similarity index 68% rename from patches/unapplied/server/0995-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch rename to patches/server/1055-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch index 29e8f0972162..46bbbf1a99b8 100644 --- a/patches/unapplied/server/0995-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch +++ b/patches/server/1055-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Improve cancelling PreCreatureSpawnEvent with per player mob diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 56f7a63e65cce587512b77aafdb4ced18b43d024..21370ed6c7d98d3f3546f0365ac50e5c26ba3bde 100644 +index 97a24cb410cf7d22a1a8edf8a5622d03a3d5a9c7..72fdcb65c1cc76d69369306c2c7e9a0f5dcb1f96 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -240,8 +240,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -248,8 +248,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider ++(backingSet[i].mobCounts[index]); } } @@ -37,33 +37,33 @@ index 56f7a63e65cce587512b77aafdb4ced18b43d024..21370ed6c7d98d3f3546f0365ac50e5c } // Paper end diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index e18c3e08f9fbfe17c797c1f96dce1b86fa41fab6..4a5dc7fd4eb1a7ab1ec371f0f107de882f88149c 100644 +index ba989879c43cb7d614198444fd2ead85ea71eae9..b3024770b4fd140370a75afa55b966a404969428 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -456,7 +456,17 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled - // re-set mob counts - for (ServerPlayer player : this.level.players) { -- Arrays.fill(player.mobCounts, 0); -+ // Paper start - per player mob spawning backoff -+ for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) { -+ player.mobCounts[ii] = 0; +@@ -569,7 +569,17 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled + // re-set mob counts + for (ServerPlayer player : this.level.players) { +- Arrays.fill(player.mobCounts, 0); ++ // Paper start - per player mob spawning backoff ++ for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) { ++ player.mobCounts[ii] = 0; + -+ int newBackoff = player.mobBackoffCounts[ii] - 1; // TODO make configurable bleed // TODO use nonlinear algorithm? -+ if (newBackoff < 0) { -+ newBackoff = 0; -+ } -+ player.mobBackoffCounts[ii] = newBackoff; -+ } -+ // Paper end - per player mob spawning backoff - } - spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, null, true); - } else { ++ int newBackoff = player.mobBackoffCounts[ii] - 1; // TODO make configurable bleed // TODO use nonlinear algorithm? ++ if (newBackoff < 0) { ++ newBackoff = 0; ++ } ++ player.mobBackoffCounts[ii] = newBackoff; ++ } ++ // Paper end - per player mob spawning backoff + } + spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, null, true); + } else { diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index cb961d9051416626f499c1ca87107f1114433c94..8dc3ba983fd4c61e463867be8d224aa90424215a 100644 +index 8cc02ee9b1a710e35eb65a5a095681cc7dc542bb..4e4e5b7e8c387cf13cf5bc5e39d334c3222c9103 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -280,6 +280,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple +@@ -307,6 +307,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple public static final int MOBCATEGORY_TOTAL_ENUMS = net.minecraft.world.entity.MobCategory.values().length; public final int[] mobCounts = new int[MOBCATEGORY_TOTAL_ENUMS]; // Paper // Paper end - Optional per player mob spawns @@ -72,10 +72,10 @@ index cb961d9051416626f499c1ca87107f1114433c94..8dc3ba983fd4c61e463867be8d224aa9 // CraftBukkit start public CraftPlayer.TransferCookieConnection transferCookieConnection; diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 364510c0d0667e67aa3b25099a021f5f856fc113..e524b27d185da3e88668f8ef107517272860bd66 100644 +index f3b52e61ddde25a60c1d178a7607b220ca01f770..848bfa93ebbdf78b0c3bae50e1726377fb78c862 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -272,6 +272,11 @@ public final class NaturalSpawner { +@@ -301,6 +301,11 @@ public final class NaturalSpawner { // Paper start - PreCreatureSpawnEvent PreSpawnStatus doSpawning = isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2); @@ -85,5 +85,5 @@ index 364510c0d0667e67aa3b25099a021f5f856fc113..e524b27d185da3e88668f8ef10751727 + } + // Paper end - per player mob count backoff if (doSpawning == PreSpawnStatus.ABORT) { - return j; // Paper - Optional per player mob spawns + return; } From 12ed02105177f54906a7d4422b235929426bc264 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Sun, 27 Oct 2024 12:20:17 +0100 Subject: [PATCH 098/119] Update material tags and entity effect --- patches/api/0147-Add-Material-Tags.patch | 24 +++++++++---------- .../api/0490-Improve-entity-effect-API.patch | 13 +++++++--- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/patches/api/0147-Add-Material-Tags.patch b/patches/api/0147-Add-Material-Tags.patch index c9fb3747a620..69e9e51ae865 100644 --- a/patches/api/0147-Add-Material-Tags.patch +++ b/patches/api/0147-Add-Material-Tags.patch @@ -118,7 +118,7 @@ index 0000000000000000000000000000000000000000..28282090c8b3668c11faefa0523f9e4a +} diff --git a/src/main/java/com/destroystokyo/paper/MaterialTags.java b/src/main/java/com/destroystokyo/paper/MaterialTags.java new file mode 100644 -index 0000000000000000000000000000000000000000..be212b4fbeabab32a4dab6ae554768c368efaa88 +index 0000000000000000000000000000000000000000..41eaa8159f8c028faa118300e95f6a0fb9cfe989 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/MaterialTags.java @@ -0,0 +1,717 @@ @@ -227,7 +227,7 @@ index 0000000000000000000000000000000000000000..be212b4fbeabab32a4dab6ae554768c3 + */ + public static final MaterialSetTag DOORS = new MaterialSetTag(keyFor("doors")) + .endsWith("_DOOR") -+ .ensureSize("DOORS", 20).lock(); ++ .ensureSize("DOORS", 21).lock(); + + /** + * Covers all dyes. @@ -241,14 +241,14 @@ index 0000000000000000000000000000000000000000..be212b4fbeabab32a4dab6ae554768c3 + */ + public static final MaterialSetTag FENCE_GATES = new MaterialSetTag(keyFor("fence_gates")) + .endsWith("_GATE") -+ .ensureSize("FENCE_GATES", 11).lock(); ++ .ensureSize("FENCE_GATES", 12).lock(); + + /** + * Covers all variants of fences. + */ + public static final MaterialSetTag FENCES = new MaterialSetTag(keyFor("fences")) + .endsWith("_FENCE") -+ .ensureSize("FENCES", 12).lock(); ++ .ensureSize("FENCES", 13).lock(); + + /** + * Covers all variants of fish buckets. @@ -362,7 +362,7 @@ index 0000000000000000000000000000000000000000..be212b4fbeabab32a4dab6ae554768c3 + */ + public static final MaterialSetTag PRESSURE_PLATES = new MaterialSetTag(keyFor("pressure_plates")) + .endsWith("_PRESSURE_PLATE") -+ .ensureSize("PRESSURE_PLATES", 15).lock(); ++ .ensureSize("PRESSURE_PLATES", 16).lock(); + + /** + * Covers the variants of prismarine blocks. @@ -441,7 +441,7 @@ index 0000000000000000000000000000000000000000..be212b4fbeabab32a4dab6ae554768c3 + */ + public static final MaterialSetTag SPAWN_EGGS = new MaterialSetTag(keyFor("spawn_eggs")) + .endsWith("_SPAWN_EGG") -+ .ensureSize("SPAWN_EGGS", 80).lock(); ++ .ensureSize("SPAWN_EGGS", 81).lock(); + + /** + * Covers all colors of stained glass. @@ -462,7 +462,7 @@ index 0000000000000000000000000000000000000000..be212b4fbeabab32a4dab6ae554768c3 + */ + public static final MaterialSetTag TRAPDOORS = new MaterialSetTag(keyFor("trapdoors")) + .endsWith("_TRAPDOOR") -+ .ensureSize("TRAPDOORS", 20).lock(); ++ .ensureSize("TRAPDOORS", 21).lock(); + + /** + * Covers all wood variants of doors. @@ -471,7 +471,7 @@ index 0000000000000000000000000000000000000000..be212b4fbeabab32a4dab6ae554768c3 + .endsWith("_DOOR") + .not(Material.IRON_DOOR) + .notContains("COPPER") -+ .ensureSize("WOODEN_DOORS", 11).lock(); ++ .ensureSize("WOODEN_DOORS", 12).lock(); + + /** + * Covers all wood variants of fences. @@ -479,7 +479,7 @@ index 0000000000000000000000000000000000000000..be212b4fbeabab32a4dab6ae554768c3 + public static final MaterialSetTag WOODEN_FENCES = new MaterialSetTag(keyFor("wooden_fences")) + .endsWith("_FENCE") + .not(Material.NETHER_BRICK_FENCE) -+ .ensureSize("WOODEN_FENCES", 11).lock(); ++ .ensureSize("WOODEN_FENCES", 12).lock(); + + /** + * Covers all wood variants of trapdoors. @@ -488,14 +488,14 @@ index 0000000000000000000000000000000000000000..be212b4fbeabab32a4dab6ae554768c3 + .endsWith("_TRAPDOOR") + .not(Material.IRON_TRAPDOOR) + .notContains("COPPER") -+ .ensureSize("WOODEN_TRAPDOORS", 11).lock(); ++ .ensureSize("WOODEN_TRAPDOORS", 12).lock(); + + /** + * Covers the wood variants of gates. + */ + public static final MaterialSetTag WOODEN_GATES = new MaterialSetTag(keyFor("wooden_gates")) + .endsWith("_GATE") -+ .ensureSize("WOODEN_GATES", 11).lock(); ++ .ensureSize("WOODEN_GATES", 12).lock(); + + /** + * Covers the variants of purpur. @@ -509,7 +509,7 @@ index 0000000000000000000000000000000000000000..be212b4fbeabab32a4dab6ae554768c3 + */ + public static final MaterialSetTag SIGNS = new MaterialSetTag(keyFor("signs")) + .endsWith("_SIGN") -+ .ensureSize("SIGNS", 44).lock(); ++ .ensureSize("SIGNS", 48).lock(); + + /** + * Covers the variants of a regular torch. diff --git a/patches/api/0490-Improve-entity-effect-API.patch b/patches/api/0490-Improve-entity-effect-API.patch index 48043155689c..582a5027352f 100644 --- a/patches/api/0490-Improve-entity-effect-API.patch +++ b/patches/api/0490-Improve-entity-effect-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Improve entity effect API diff --git a/src/main/java/org/bukkit/EntityEffect.java b/src/main/java/org/bukkit/EntityEffect.java -index 5341957b10cccd7bce5a7595699b1d90412a01d0..83d623cc824ddeeae7350c9f9a757fcf8e97c9ea 100644 +index 5341957b10cccd7bce5a7595699b1d90412a01d0..912dafd5a8884d7973b2126f97ecdbe54e78937f 100644 --- a/src/main/java/org/bukkit/EntityEffect.java +++ b/src/main/java/org/bukkit/EntityEffect.java @@ -112,11 +112,25 @@ public enum EntityEffect { @@ -76,7 +76,7 @@ index 5341957b10cccd7bce5a7595699b1d90412a01d0..83d623cc824ddeeae7350c9f9a757fcf HURT_BERRY_BUSH(44, LivingEntity.class), /** * Fox chews the food in its mouth -@@ -331,7 +355,17 @@ public enum EntityEffect { +@@ -331,7 +355,24 @@ public enum EntityEffect { * Sniffer must have a target and be in {@link Sniffer.State#SEARCHING} or * {@link Sniffer.State#DIGGING} */ @@ -90,7 +90,14 @@ index 5341957b10cccd7bce5a7595699b1d90412a01d0..83d623cc824ddeeae7350c9f9a757fcf + /** + * {@link org.bukkit.inventory.EquipmentSlot#BODY} armor piece breaks + */ -+ BODY_BREAK(65, LivingEntity.class); ++ BODY_BREAK(65, LivingEntity.class), ++ /** ++ * A creaking transient shaking when being hit. ++ * Does not apply to plain creaking entities as they are not invulnerable like the transient ones spawned by the ++ * creaking heart. ++ */ ++ @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) ++ SHAKE(66, org.bukkit.entity.CreakingTransient.class); + // Paper end - add missing EntityEffect private final byte data; From 02bca1e6558bf4ac0cbf928d48e90f497b10b0a3 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Sun, 27 Oct 2024 18:11:15 +0100 Subject: [PATCH 099/119] Remove timings impl --- patches/api/0011-Timings-v2.patch | 62 +- ...-option-to-load-extra-plugin-jars-no.patch | 2 +- ...0015-Expose-server-build-information.patch | 13 +- .../0021-Add-exception-reporting-event.patch | 2 +- ...Add-Raw-Byte-ItemStack-Serialization.patch | 4 +- ...y-Counter-to-allow-plugins-to-use-va.patch | 4 +- patches/api/0253-Expand-world-key-API.patch | 4 +- .../api/0255-Expose-protocol-version.patch | 4 +- .../api/0272-ItemStack-repair-check-API.patch | 4 +- .../0304-Get-entity-default-attributes.patch | 4 +- ...12-Add-Raw-Byte-Entity-Serialization.patch | 4 +- ...0358-Add-NamespacedKey-biome-methods.patch | 4 +- ...x-custom-statistic-criteria-creation.patch | 4 +- ...Add-api-for-spawn-egg-texture-colors.patch | 4 +- .../api/0441-Add-Lifecycle-Event-system.patch | 4 +- patches/api/0442-ItemStack-Tooltip-API.patch | 4 +- .../api/0472-Registry-Modification-API.patch | 4 +- ...74-Proxy-ItemStack-to-CraftItemStack.patch | 4 +- patches/api/0485-Add-FeatureFlag-API.patch | 4 +- .../api/0487-Item-serialization-as-json.patch | 4 +- patches/server/0005-Paper-config-files.patch | 29 +- patches/server/0009-MC-Utils.patch | 4 +- ...23-Further-improve-server-tick-loop.patch} | 14 +- patches/server/0023-Timings-v2.patch | 2077 ----------------- .../server/0024-Remove-Spigot-timings.patch | 967 ++++++++ ...-option-to-load-extra-plugin-jars-no.patch | 4 +- ...0033-Expose-server-build-information.patch | 30 +- patches/server/0036-Entity-Origin-API.patch | 4 +- ...vent-block-entity-and-entity-crashes.patch | 16 +- ...ties-to-activation-range-ignore-list.patch | 4 +- patches/server/0043-Optimize-explosions.patch | 8 +- patches/server/0045-Disable-thunder.patch | 4 +- .../server/0046-Disable-ice-and-snow.patch | 6 +- .../0052-Disable-spigot-tick-limiters.patch | 4 +- ...awn-location-event-changing-location.patch | 4 +- ...055-Improve-Player-chat-API-handling.patch | 14 +- .../0057-Expose-server-CommandMap.patch | 4 +- .../server/0061-Add-velocity-warnings.patch | 2 +- .../0062-Add-exception-reporting-event.patch | 18 +- ...oreboards-for-non-players-by-default.patch | 4 +- ...ading-permissions.yml-before-plugins.patch | 6 +- ...llow-Reloading-of-Custom-Permissions.patch | 4 +- .../0069-Remove-Metadata-on-reload.patch | 4 +- .../server/0072-Add-World-Util-Methods.patch | 4 +- ...3-Custom-replacement-for-eaten-items.patch | 8 +- ...th-absorb-values-and-repair-bad-data.patch | 8 +- ...le-spawn-chances-for-skeleton-horses.patch | 4 +- ...ckPhysicsEvent-if-a-plugin-has-a-lis.patch | 12 +- ...Entity-AddTo-RemoveFrom-World-Events.patch | 6 +- ...79-Configurable-Chunk-Inhabited-Time.patch | 2 +- ...0083-Add-PlayerUseUnknownEntityEvent.patch | 4 +- ...g-BlockPlaceEvent-triggering-physics.patch | 4 +- .../0088-Configurable-Player-Collision.patch | 14 +- ...ityRegainHealthEvent-isFastRegen-API.patch | 4 +- ...-possibility-for-getServer-singleton.patch | 8 +- .../0097-Async-GameProfileCache-saving.patch | 8 +- ...r-redstone-torch-rapid-clock-removal.patch | 4 +- .../0101-Fix-global-sound-handling.patch | 6 +- ...setting-for-proxy-online-mode-status.patch | 8 +- ...onfigurable-packet-in-spam-threshold.patch | 2 +- ...07-Configurable-flying-kick-messages.patch | 2 +- ...1-Allow-Reloading-of-Command-Aliases.patch | 4 +- ...ize-Level.hasChunkAt-BlockPosition-Z.patch | 4 +- ...rovide-E-TE-Chunk-count-stat-methods.patch | 2 +- .../0124-Enforce-Sync-Player-Saves.patch | 10 +- ...PI-for-Reason-Source-Triggering-play.patch | 8 +- .../server/0126-Cap-Entity-Collisions.patch | 4 +- ...e-CraftScheduler-Async-Task-Debugger.patch | 10 +- ...le-async-calls-to-restart-the-server.patch | 12 +- ...ke-parrots-stay-on-shoulders-despite.patch | 4 +- ...n-option-to-prevent-player-names-fro.patch | 4 +- .../server/0136-Basic-PlayerProfile-API.patch | 4 +- .../server/0137-Add-UnknownCommandEvent.patch | 4 +- .../0145-ProfileWhitelistVerifyEvent.patch | 6 +- patches/server/0151-Add-PlayerJumpEvent.patch | 2 +- .../0156-Add-PlayerArmorChangeEvent.patch | 4 +- ...117075-Block-entity-unload-lag-spike.patch | 8 +- ...e-implementations-for-captured-block.patch | 8 +- ...-get-a-BlockState-without-a-snapshot.patch | 8 +- .../server/0161-AsyncTabCompleteEvent.patch | 6 +- ...4-PlayerNaturallySpawnCreaturesEvent.patch | 10 +- .../server/0166-PreCreatureSpawnEvent.patch | 10 +- ...nt-extended-PaperServerListPingEvent.patch | 4 +- .../0176-Player.setPlayerProfile-API.patch | 4 +- .../server/0177-getPlayerUniqueId-API.patch | 4 +- .../0178-Improved-Async-Task-Scheduler.patch | 43 +- ...ld.spawnParticle-API-and-add-Builder.patch | 4 +- ...e-shield-blocking-delay-configurable.patch | 4 +- .../0201-Add-entity-knockback-events.patch | 10 +- .../server/0202-Expand-Explosions-API.patch | 6 +- .../0207-InventoryCloseEvent-Reason-API.patch | 14 +- ...t-armor-stands-from-doing-entity-loo.patch | 4 +- ...5-Vanished-players-don-t-have-rights.patch | 4 +- ...nd-make-tab-spam-limits-configurable.patch | 2 +- ...ies-option-to-debug-dupe-uuid-issues.patch | 4 +- ...dd-Early-Warning-Feature-to-WatchDog.patch | 14 +- ...26-Use-ConcurrentHashMap-in-JsonList.patch | 4 +- ...27-Use-a-Queue-for-Queueing-Commands.patch | 7 +- ...-ray-tracing-methods-to-LivingEntity.patch | 4 +- .../server/0241-Improve-death-events.patch | 14 +- ...wning-from-loading-generating-chunks.patch | 6 +- ...251-Add-LivingEntity-getTargetEntity.patch | 4 +- ...event-players-from-moving-into-unloa.patch | 2 +- ...er-Thread-Pool-and-Thread-Priorities.patch | 4 +- .../0261-Optimize-World-Time-Updates.patch | 10 +- ...t-allow-digging-into-unloaded-chunks.patch | 2 +- ...ault-permission-message-configurable.patch | 4 +- ...entity-dismount-during-teleportation.patch | 4 +- patches/server/0268-Book-size-limits.patch | 2 +- ...-Replace-OfflinePlayer-getLastPlayed.patch | 4 +- patches/server/0273-BlockDestroyEvent.patch | 4 +- .../0274-Async-command-map-building.patch | 6 +- .../server/0275-Brigadier-Mojang-API.patch | 2 +- .../0276-Limit-Client-Sign-length-more.patch | 4 +- ...oggleEvent-when-whitelist-is-toggled.patch | 4 +- ...nd-additions-to-the-spawn-reason-API.patch | 12 +- .../0280-Add-PlayerPostRespawnEvent.patch | 10 +- patches/server/0281-Server-Tick-Events.patch | 20 +- ...Optimize-Captured-BlockEntity-Lookup.patch | 4 +- ...288-Expose-the-internal-current-tick.patch | 4 +- ...al-Spawned-mobs-towards-natural-spaw.patch | 2 +- ...revent-consuming-the-wrong-itemstack.patch | 8 +- ...ptimise-EntityGetter-getPlayerByUUID.patch | 4 +- ...0302-Fix-items-not-falling-correctly.patch | 4 +- .../0306-Tracking-Range-Improvements.patch | 4 +- ...e-getChunkAt-calls-for-loaded-chunks.patch | 4 +- .../0310-Add-debug-for-sync-chunk-loads.patch | 14 +- patches/server/0313-Entity-Jump-API.patch | 4 +- .../server/0320-Optimise-Chunk-getFluid.patch | 2 +- ...-Add-tick-times-API-and-mspt-command.patch | 14 +- ...323-Expose-MinecraftServer-isRunning.patch | 4 +- ...Add-Raw-Byte-ItemStack-Serialization.patch | 6 +- ...nnections-shouldn-t-hold-up-shutdown.patch | 4 +- ...-PlayerChunkMap-adds-crashing-server.patch | 10 +- ...move-existing-players-to-world-spawn.patch | 4 +- ...-entity-collision-code-if-not-needed.patch | 4 +- ...nEvent-when-Player-is-actually-ready.patch | 12 +- ...pawn-point-if-spawn-in-unloaded-worl.patch | 8 +- ...PlayerAttackEntityCooldownResetEvent.patch | 4 +- ...item-duplication-and-teleport-issues.patch | 6 +- ...PickItem-Packet-and-kick-for-invalid.patch | 2 +- .../server/0348-misc-debugging-dumps.patch | 12 +- ...49-Prevent-teleporting-dead-entities.patch | 2 +- .../server/0350-Implement-Mob-Goal-API.patch | 4 +- ...Wait-for-Async-Tasks-during-shutdown.patch | 8 +- ...er-runTaskTimerAsynchronously-Plugin.patch | 4 +- ...t-position-desync-causing-tp-exploit.patch | 2 +- .../0366-Add-PlayerRecipeBookClickEvent.patch | 4 +- ...68-Add-permission-for-command-blocks.patch | 2 +- ...ld-Difficulty-Remembering-Difficulty.patch | 20 +- ...-Plugin-Tickets-to-API-Chunk-Methods.patch | 6 +- ...o-not-accept-invalid-client-settings.patch | 4 +- ...k-for-portal-on-world-gen-entity-add.patch | 4 +- ...geEvent-not-firing-for-all-use-cases.patch | 4 +- .../0403-Cache-block-data-strings.patch | 4 +- ...ortation-and-cancel-velocity-if-tele.patch | 2 +- ...p-capture-to-capture-all-items-added.patch | 4 +- ...y-Counter-to-allow-plugins-to-use-va.patch | 6 +- ...-non-whitelisted-player-when-white-l.patch | 4 +- ...r-large-move-vectors-crashing-server.patch | 2 +- ...ace-order-when-capturing-blockstates.patch | 2 +- ...-Add-getOfflinePlayerIfCached-String.patch | 4 +- ...ix-client-lag-on-advancement-loading.patch | 4 +- .../server/0427-Add-API-for-quit-reason.patch | 4 +- ...-should-not-bypass-cramming-gamerule.patch | 6 +- .../server/0438-Limit-recipe-packets.patch | 4 +- ...act-event-not-being-called-sometimes.patch | 4 +- ...457-Add-ServerResourcesReloadedEvent.patch | 6 +- patches/server/0464-Remove-stale-POIs.patch | 4 +- .../0465-Fix-villager-boat-exploit.patch | 4 +- patches/server/0466-Add-sendOpLevel-API.patch | 6 +- ...gistryAccess-for-managing-Registries.patch | 6 +- patches/server/0480-Add-EntityMoveEvent.patch | 12 +- ...disable-pathfinding-updates-on-block.patch | 6 +- ...ainThreadExecutor-to-BukkitScheduler.patch | 4 +- ...0490-fix-converting-txt-to-json-file.patch | 10 +- ...-using-signs-inside-spawn-protection.patch | 2 +- .../server/0496-Expand-world-key-API.patch | 14 +- ...ed-item-when-player-has-disconnected.patch | 4 +- ...telist-use-configurable-kick-message.patch | 4 +- ...ignore-result-of-PlayerEditBookEvent.patch | 2 +- .../server/0501-Expose-protocol-version.patch | 6 +- ...tab-completions-for-brigadier-comman.patch | 6 +- ...ItemConsumeEvent-cancelling-properly.patch | 4 +- ...fix-PlayerItemHeldEvent-firing-twice.patch | 2 +- ...s-to-convert-between-Component-and-B.patch | 4 +- .../server/0525-Add-basic-Datapack-API.patch | 6 +- ...527-Expand-PlayerGameModeChangeEvent.patch | 4 +- .../0528-ItemStack-repair-check-API.patch | 6 +- ...ove-range-check-for-block-placing-up.patch | 2 +- .../0533-Add-Unix-domain-socket-support.patch | 10 +- ...5-Improve-item-default-attribute-API.patch | 4 +- ...cause-to-Weather-ThunderChangeEvents.patch | 8 +- .../0539-Add-PlayerKickEvent-causes.patch | 28 +- .../server/0548-Line-Of-Sight-Changes.patch | 4 +- ...etChunkIfLoadedImmediately-in-places.patch | 8 +- .../server/0557-Add-PlayerArmSwingEvent.patch | 4 +- ...k-event-leave-message-not-being-sent.patch | 6 +- ...nd-timings-for-sensors-and-behaviors.patch | 61 +- .../0563-Add-System.out-err-catcher.patch | 2 +- ...-AFK-kick-while-watching-end-credits.patch | 2 +- .../server/0566-Add-PlayerSetSpawnEvent.patch | 4 +- .../0574-Add-BlockBreakBlockEvent.patch | 4 +- ...o-find-targets-for-lightning-strikes.patch | 6 +- .../0580-Get-entity-default-attributes.patch | 6 +- ...89-Add-Raw-Byte-Entity-Serialization.patch | 4 +- ...-logic-for-inventories-on-chunk-unlo.patch | 4 +- ...0593-Improve-and-expand-AsyncCatcher.patch | 6 +- ...aper-mobcaps-and-paper-playermobcaps.patch | 8 +- ...d-getChunkAt-has-inlined-logic-for-l.patch | 4 +- ...rimise-map-impl-for-tracked-players.patch} | 4 +- .../server/0601-Time-scoreboard-search.patch | 43 - ...h => 0602-Add-missing-InventoryType.patch} | 0 ...imise-BlockSoil-nearby-water-lookup.patch} | 0 ...ntory-not-closing-on-entity-removal.patch} | 4 +- ...rement-before-suggesting-root-nodes.patch} | 0 ...ServerboundCommandSuggestionPacket-.patch} | 2 +- ...h => 0607-Add-packet-limiter-config.patch} | 0 ...nColor-on-tropical-fish-bucket-meta.patch} | 0 ...=> 0609-Ensure-valid-vehicle-status.patch} | 0 ...ftlocked-end-exit-portal-generation.patch} | 0 ...r-causing-a-crash-when-trying-to-ge.patch} | 0 ...-t-log-debug-logging-being-disabled.patch} | 0 ...ous-menus-with-empty-level-accesses.patch} | 0 ...h => 0614-Preserve-overstacked-loot.patch} | 0 ...ate-head-rotation-in-missing-places.patch} | 0 ...unintended-light-block-manipulation.patch} | 0 ...0617-Fix-CraftCriteria-defaults-map.patch} | 0 ...Fix-upstreams-block-state-factories.patch} | 4 +- ... => 0619-Configurable-feature-seeds.patch} | 13 - ... 0620-Add-root-admin-user-detection.patch} | 4 +- ...t-attempt-to-teleport-dead-entities.patch} | 0 ...ive-velocity-through-repeated-crits.patch} | 4 +- ...e-code-using-deprecated-for-removal.patch} | 0 ...=> 0624-Fix-Spigot-growth-modifiers.patch} | 0 ...OpenersCounter-openCount-from-going.patch} | 0 ...0626-Add-PlayerItemFrameChangeEvent.patch} | 0 ...tch => 0627-Optimize-HashMapPalette.patch} | 0 ...-isSectionEmpty-int-and-optimize-Pa.patch} | 0 ...patch => 0629-Add-more-Campfire-API.patch} | 0 ...data-to-disk-if-it-serializes-witho.patch} | 0 ...ard-CraftEntity-in-teleport-command.patch} | 0 ... => 0632-Improve-scoreboard-entries.patch} | 0 ...ch => 0633-Entity-powdered-snow-API.patch} | 0 ...0634-Add-API-for-item-entity-health.patch} | 0 ...ax-block-light-for-monster-spawning.patch} | 0 ...pistons-and-BlockPistonRetractEvent.patch} | 0 ...-canSmelt-methods-to-FurnaceInvento.patch} | 0 ...le-API.patch => 0638-Bucketable-API.patch} | 0 ...es.patch => 0639-Validate-usernames.patch} | 4 +- ...er-animal-spawn-height-configurable.patch} | 0 ...anilla-BiomeProvider-from-WorldInfo.patch} | 12 +- ...ion-for-worlds-affected-by-time-cmd.patch} | 0 ...heck-for-PersistentDataContainer-ha.patch} | 0 ...4-Multiple-Entries-with-Scoreboards.patch} | 0 ...645-Reset-placed-block-on-exception.patch} | 0 ...configurable-height-for-slime-spawn.patch} | 0 ...0647-Fix-xp-reward-for-baby-zombies.patch} | 0 ...lti-Block-Change-API-Implementation.patch} | 0 ...ent.patch => 0649-Fix-NotePlayEvent.patch} | 0 ....patch => 0650-Freeze-Tick-Lock-API.patch} | 4 +- ...h => 0651-More-PotionEffectType-API.patch} | 0 ...for-StructureTemplate.Pallete-cache.patch} | 0 ...command-sender-which-forwards-feedb.patch} | 4 +- ...-missing-structure-set-seed-configs.patch} | 0 ...lled-powdered-snow-bucket-placement.patch} | 0 ...ate-calls-to-CraftServer-getSpawnLi.patch} | 4 +- ...gs.patch => 0657-Add-GameEvent-tags.patch} | 6 +- ...ks-fairly-for-worlds-while-waiting-.patch} | 6 +- ...tch => 0659-Furnace-RecipesUsed-API.patch} | 0 ...gurable-sculk-sensor-listener-range.patch} | 0 ... => 0661-Add-missing-block-data-API.patch} | 0 ...fault-CustomSpawners-in-custom-worl.patch} | 4 +- ...-worldlist-before-initing-the-world.patch} | 8 +- ...s.patch => 0664-Custom-Potion-Mixes.patch} | 10 +- ...65-Force-close-world-loading-screen.patch} | 4 +- ...666-Fix-falling-block-spawn-methods.patch} | 0 ...Expose-furnace-minecart-push-values.patch} | 0 ...ojectileHitEvent-for-piercing-arrow.patch} | 0 ...I.patch => 0669-More-Projectile-API.patch} | 0 ...x-swamp-hut-cat-generation-deadlock.patch} | 0 ...le-movement-from-players-while-tele.patch} | 2 +- ...0672-Implement-getComputedBiome-API.patch} | 0 ...> 0673-Make-some-itemstacks-nonnull.patch} | 0 ...674-Implement-enchantWithLevels-API.patch} | 0 ...h => 0675-Fix-saving-in-unloadWorld.patch} | 4 +- ...h => 0676-Buffer-OOB-setBlock-calls.patch} | 0 ... 0677-Add-TameableDeathMessageEvent.patch} | 0 ...ock-data-for-EntityChangeBlockEvent.patch} | 0 ...bles-running-when-mob-loot-gamerule.patch} | 0 ...ssenger-world-matches-ridden-entity.patch} | 0 ...ys-and-optimize-reference-Holder-ta.patch} | 0 ...low-changing-the-EnderDragon-podium.patch} | 0 ...erriding-a-block-entity-during-worl.patch} | 0 ...t-tile-entity-copies-loading-chunks.patch} | 4 +- ...ead-of-display-name-in-PlayerList-g.patch} | 4 +- ...> 0686-Expand-PlayerItemDamageEvent.patch} | 0 ...> 0687-WorldCreator-keepSpawnLoaded.patch} | 4 +- ...-in-CraftPersistentDataTypeRegistry.patch} | 0 ...destroyed-trigger-in-the-correct-pl.patch} | 0 ...Event-and-CollarColorable-interface.patch} | 0 ...CauldronLevelChange-on-initial-fill.patch} | 0 ...snow-cauldrons-not-turning-to-water.patch} | 0 ...> 0693-Add-PlayerStopUsingItemEvent.patch} | 4 +- ...rs.patch => 0694-Don-t-tick-markers.patch} | 4 +- ...tch => 0695-Expand-FallingBlock-API.patch} | 0 ...0696-Add-support-for-Proxy-Protocol.patch} | 0 ...x-OfflinePlayer-getBedSpawnLocation.patch} | 0 ...tory-for-smokers-and-blast-furnaces.patch} | 0 ... 0699-Sanitize-sent-BlockEntity-NBT.patch} | 4 +- ...-selector-resolving-in-books-by-def.patch} | 0 ...ntity-loading-causing-async-lookups.patch} | 0 ...-on-world-create-while-being-ticked.patch} | 26 +- ...03-Dont-resent-entity-on-art-update.patch} | 0 ... => 0704-Add-WardenAngerChangeEvent.patch} | 0 ...strict-advancement-dimension-checks.patch} | 0 ...tant-BlockStateListPopulator-method.patch} | 0 ...I.patch => 0707-Nameable-Banner-API.patch} | 0 ...roadcast-messages-to-command-blocks.patch} | 4 +- ...pty-items-from-being-added-to-world.patch} | 4 +- ...hPotion-and-LingeringPotion-spawnin.patch} | 0 ...atch => 0711-Add-Player-getFishHook.patch} | 0 ...chunk-for-dynamic-game-event-listen.patch} | 0 ...s-missing-EntityDropItemEvent-calls.patch} | 0 ...PE.patch => 0714-Fix-Bee-flower-NPE.patch} | 0 ...API.patch => 0715-More-Teleport-API.patch} | 2 +- ... => 0716-Add-EntityPortalReadyEvent.patch} | 0 ...level-random-in-entity-constructors.patch} | 0 ...k-entities-after-destroy-prediction.patch} | 2 +- ...on-plugins-accessing-faraway-chunks.patch} | 4 +- ...tom-Chat-Completion-Suggestions-API.patch} | 0 ...Add-and-fix-missing-BlockFadeEvents.patch} | 0 ...ion-API.patch => 0722-Collision-API.patch} | 0 ...nd-message-for-brigadier-syntax-exc.patch} | 0 ...API.patch => 0724-Block-Ticking-API.patch} | 0 ...-Add-Velocity-IP-Forwarding-Support.patch} | 8 +- ...726-Add-NamespacedKey-biome-methods.patch} | 18 +- ...x-plugin-loggers-on-server-shutdown.patch} | 4 +- ...ok-changes-from-crashing-the-server.patch} | 4 +- ...tityChangeBlockEvent-in-more-places.patch} | 0 ...> 0730-Missing-eating-regain-reason.patch} | 0 ....patch => 0731-Missing-effect-cause.patch} | 0 ...serialization-deserialization-for-P.patch} | 0 ...3-Call-BlockPhysicsEvent-more-often.patch} | 0 ...0734-Configurable-chat-thread-limit.patch} | 4 +- ...of-WorldCreator-keepSpawnLoaded-ret.patch} | 0 ... 0736-fix-Jigsaw-block-kicking-user.patch} | 0 ...mEvent-for-mud-converting-into-clay.patch} | 0 ... => 0738-Add-getDrops-to-BlockState.patch} | 0 ...=> 0739-Fix-a-bunch-of-vanilla-bugs.patch} | 16 +- ...y-onTrackingStart-during-navigation.patch} | 6 +- ... 0741-Fix-custom-piglin-loved-items.patch} | 0 ...=> 0742-EntityPickupItemEvent-fixes.patch} | 0 ...interactions-with-items-on-cooldown.patch} | 0 ...-Add-PlayerInventorySlotChangeEvent.patch} | 0 ... 0745-Elder-Guardian-appearance-API.patch} | 0 ...ch => 0746-Add-entity-knockback-API.patch} | 0 ....patch => 0747-Detect-headless-JREs.patch} | 0 ...-vehicle-collision-event-not-called.patch} | 0 ...ch => 0749-Add-EntityToggleSitEvent.patch} | 0 ... => 0750-Add-fire-tick-delay-option.patch} | 0 ...patch => 0751-Add-Moving-Piston-API.patch} | 0 ...> 0752-Ignore-impossible-spawn-tick.patch} | 0 ...t-and-EntitySelectorParser-permissi.patch} | 0 ...Event-cancellation-cant-fully-preve.patch} | 0 ...0755-Add-PrePlayerAttackEntityEvent.patch} | 0 ...e-reset-EnderDragon-boss-event-name.patch} | 0 ... 0757-Add-Player-Warden-Warning-API.patch} | 0 ...a-friendly-methods-to-update-trades.patch} | 0 ...759-Add-paper-dumplisteners-command.patch} | 0 ...lobal-player-list-where-appropriate.patch} | 8 +- ...sync-entity-add-due-to-fungus-trees.patch} | 0 ....patch => 0762-ItemStack-damage-API.patch} | 0 ...tion-API.patch => 0763-Friction-API.patch} | 10 +- ...trol-player-s-insomnia-and-phantoms.patch} | 0 ...-premature-player-kicks-on-shutdown.patch} | 4 +- ... => 0766-Sync-offhand-slot-in-menus.patch} | 0 ... 0767-Player-Entity-Tracking-Events.patch} | 4 +- ...tch => 0768-Limit-pet-look-distance.patch} | 0 ...ments.patch => 0769-fix-Instruments.patch} | 0 ...for-some-hot-BlockBehavior-and-Flui.patch} | 0 ...tch => 0771-Add-BlockLockCheckEvent.patch} | 0 ... 0772-Add-Sneaking-API-for-Entities.patch} | 0 ... => 0773-Improve-logging-and-errors.patch} | 8 +- ....patch => 0774-Improve-PortalEvents.patch} | 0 ...ion-for-spider-worldborder-climbing.patch} | 0 ...sing-SpigotConfig-logCommands-check.patch} | 2 +- ...Allay-stopDancing-while-not-dancing.patch} | 0 ...ge.patch => 0778-Flying-Fall-Damage.patch} | 0 ...ion-moving-velocity-to-VehicleBlock.patch} | 0 ...onfig-for-disabling-entity-tag-tags.patch} | 4 +- ...e-player-info-update-packet-on-join.patch} | 10 +- ...k-items-during-EntityResurrectEvent.patch} | 4 +- ...en-API.patch => 0783-Win-Screen-API.patch} | 0 ...ItemStack-setAmount-null-assignment.patch} | 0 ...ix-force-opening-enchantment-tables.patch} | 0 ...tch => 0786-Add-Entity-Body-Yaw-API.patch} | 0 ...vent-sleeping-villagers-moving-towa.patch} | 0 ...=> 0788-Add-EntityFertilizeEggEvent.patch} | 0 ...ty-drop-not-updating-the-client-inv.patch} | 0 ...temEvent-and-EntityCompostItemEvent.patch} | 0 ...ctly-handle-ArmorStand-invisibility.patch} | 0 ...ancement-triggers-for-entity-damage.patch} | 6 +- ...793-Fix-text-display-error-on-spawn.patch} | 0 ...nventories-returning-null-Locations.patch} | 0 ...API.patch => 0795-Add-Shearable-API.patch} | 0 ...Fix-SpawnEggMeta-get-setSpawnedType.patch} | 0 ...g-to-bad-recipes-in-furnace-like-ti.patch} | 0 ...ence-violations-like-they-should-be.patch} | 2 +- ...xpired-keys-from-impacting-new-join.patch} | 4 +- ...ts-being-fired-from-unloaded-chunks.patch} | 4 +- ...0801-Use-array-for-gamerule-storage.patch} | 0 ...Fix-a-couple-of-upstream-bed-issues.patch} | 0 ...ix-demo-flag-not-enabling-demo-mode.patch} | 0 ... 0804-Add-Mob-Experience-reward-API.patch} | 0 ...redstone-on-top-of-trap-doors-early.patch} | 0 ...Lazy-Initialization-for-Enum-Fields.patch} | 0 ...07-More-accurate-isInOpenWater-impl.patch} | 0 ... => 0808-Expand-PlayerItemMendEvent.patch} | 0 ...sh-ProjectileSource-for-projectiles.patch} | 0 ... => 0810-Add-transient-modifier-API.patch} | 0 ...patch => 0811-Fix-block-place-logic.patch} | 4 +- ...nd-playing-for-BlockItem-ItemStacks.patch} | 0 ...l-BlockGrowEvent-for-missing-blocks.patch} | 0 ...nhasbukkit-default-if-alias-block-e.patch} | 2 +- ...pLike-spam-for-missing-key-selector.patch} | 0 ...-Fix-sniffer-removeExploredLocation.patch} | 0 ...to-remove-all-active-potion-effects.patch} | 0 ...8-Add-event-for-player-editing-sign.patch} | 0 ...k-item-frames-if-players-can-see-it.patch} | 0 ...ermission-levels-for-command-blocks.patch} | 0 ...Add-option-to-disable-block-updates.patch} | 0 ...822-Call-missing-BlockDispenseEvent.patch} | 0 ...-chunks-for-supporting-block-checks.patch} | 0 ...Optimize-player-lookups-for-beacons.patch} | 0 ...I.patch => 0825-More-Sign-Block-API.patch} | 0 ...6-fix-item-meta-for-tadpole-buckets.patch} | 0 ...t-API.patch => 0827-Fix-BanList-API.patch} | 0 ...d-water-fluid-explosion-resistance-.patch} | 0 ...x-possible-NPE-on-painting-creation.patch} | 0 ...imer-for-Wandering-Traders-spawned-.patch} | 0 ...nceOrb-should-call-EntitySpawnEvent.patch} | 0 ...t-throw-both-Spread-and-Grow-Events.patch} | 0 ....patch => 0833-Add-whitelist-events.patch} | 0 ... 0834-Implement-PlayerFailMoveEvent.patch} | 4 +- ...olia-scheduler-and-owned-region-API.patch} | 16 +- ...se-allay-memory-on-non-item-targets.patch} | 0 ...tion-when-spawning-display-entities.patch} | 0 ...838-Only-capture-actual-tree-growth.patch} | 4 +- ...rce-for-mushroom-block-spread-event.patch} | 0 ...Data-on-more-entities-when-spawning.patch} | 0 ...-Use-correct-seed-on-api-world-load.patch} | 4 +- ...ta-neighbour-ticks-outside-of-range.patch} | 0 ...> 0843-Cache-map-ids-on-item-frames.patch} | 0 ...API-for-updating-recipes-on-clients.patch} | 16 +- ...-custom-statistic-criteria-creation.patch} | 18 +- ...atch => 0846-Bandaid-fix-for-Effect.patch} | 0 ...tch => 0847-SculkCatalyst-bloom-API.patch} | 0 ...API-for-an-entity-s-scoreboard-name.patch} | 0 ...lace-methods-with-old-StructureType.patch} | 6 +- ...e-namespaced-commands-if-send-names.patch} | 2 +- ...-handle-BlockBreakEvent-isDropItems.patch} | 4 +- ...entity-death-event-for-ender-dragon.patch} | 0 ...tity-tracking-range-by-Y-coordinate.patch} | 4 +- ... => 0854-Add-Listing-API-for-Player.patch} | 6 +- ...figurable-Region-Compression-Format.patch} | 0 ...6-Add-BlockFace-to-BlockDamageEvent.patch} | 0 ...h => 0857-Fix-NPE-on-Boat-getStatus.patch} | 0 ...e-API.patch => 0858-Expand-Pose-API.patch} | 0 ...patch => 0859-More-DragonBattle-API.patch} | 0 ...tch => 0860-Add-PlayerPickItemEvent.patch} | 2 +- ...=> 0861-Allow-trident-custom-damage.patch} | 0 ...2-Expose-hand-in-BlockCanBuildEvent.patch} | 0 ...-nearest-structure-border-iteration.patch} | 0 ...Implement-OfflinePlayer-isConnected.patch} | 0 ...esync.patch => 0865-Fix-slot-desync.patch} | 4 +- ...titleOverride-to-InventoryOpenEvent.patch} | 0 ...67-Configure-sniffer-egg-hatch-time.patch} | 0 ...-proximity-check-before-entity-look.patch} | 0 ...kip-POI-finding-if-stuck-in-vehicle.patch} | 0 ...t-sanity-checks-in-container-clicks.patch} | 4 +- ...ll-BlockRedstoneEvents-for-lecterns.patch} | 0 ...roper-checking-of-empty-item-stacks.patch} | 0 ...ix-silent-equipment-change-for-mobs.patch} | 0 ...h => 0874-Fix-spigot-s-Forced-Stats.patch} | 0 ...ing-InventoryHolders-to-inventories.patch} | 0 ...entities-in-chunks-that-are-positio.patch} | 0 ...sing-logs-for-log-ips-config-option.patch} | 0 ...n-on-UpgradeData.BlockFixers-class-.patch} | 0 ...-AdvancementProgress-getDateAwarded.patch} | 0 ...idebar-objectives-not-being-cleared.patch} | 2 +- ...x-missing-map-initialize-event-call.patch} | 4 +- ...a-when-attaching-firework-to-entity.patch} | 0 ...83-Fix-UnsafeValues-loadAdvancement.patch} | 4 +- ...> 0884-Add-player-idle-duration-API.patch} | 0 ...-if-we-can-see-non-visible-entities.patch} | 4 +- ...NPE-in-SculkBloomEvent-world-access.patch} | 0 ...tack-for-Player-sendEquipmentChange.patch} | 0 ...Ints.patch => 0888-Optimize-VarInts.patch} | 0 ...e-collision-shape-of-a-block-before.patch} | 0 ...redicate-for-blocks-when-raytracing.patch} | 0 ...em-packets-with-collector-as-source.patch} | 4 +- ... => 0892-Expand-LingeringPotion-API.patch} | 0 ...ngEffect-powers-lightning-rods-and-.patch} | 0 ...h-event-for-all-player-interactions.patch} | 0 ...everal-issues-with-EntityBreedEvent.patch} | 0 ...896-Add-UUID-attribute-modifier-API.patch} | 0 ...-event-call-for-entity-teleport-API.patch} | 0 ...y-create-LootContext-for-criterions.patch} | 0 ...-t-fire-sync-events-during-worldgen.patch} | 16 +- ...tch => 0900-Add-Structure-check-API.patch} | 0 ...-getAttributeModifier-duplication-c.patch} | 0 ...store-vanilla-entity-drops-behavior.patch} | 4 +- ...-Dont-resend-blocks-on-interactions.patch} | 0 ...tch => 0904-add-more-scoreboard-API.patch} | 0 ...stry.patch => 0905-Improve-Registry.patch} | 0 ...on-null-loc-for-EntityTeleportEvent.patch} | 4 +- ...h => 0907-Add-experience-points-API.patch} | 0 ...h => 0908-Add-drops-to-shear-events.patch} | 0 ...> 0909-Add-PlayerShieldDisableEvent.patch} | 0 ...ate-ResourceLocation-in-NBT-reading.patch} | 8 +- ...-experience-dropping-on-block-break.patch} | 10 +- ...> 0912-Fixup-NamespacedKey-handling.patch} | 0 ...13-Expose-LootTable-of-DecoratedPot.patch} | 0 ...location-of-Vec3D-by-entity-tracker.patch} | 4 +- ...rTradeEvent-and-PlayerPurchaseEvent.patch} | 0 ...h => 0916-Add-ShulkerDuplicateEvent.patch} | 0 ...dd-api-for-spawn-egg-texture-colors.patch} | 6 +- ... => 0918-Add-Lifecycle-Event-system.patch} | 8 +- ...patch => 0919-ItemStack-Tooltip-API.patch} | 18 +- ...Snapshot-includeLightData-parameter.patch} | 0 ...PI.patch => 0921-Add-FluidState-API.patch} | 0 ...patch => 0922-add-number-format-api.patch} | 0 ...patch => 0923-improve-BanList-types.patch} | 4 +- ...I.patch => 0924-Expanded-Hopper-API.patch} | 0 ...5-Add-BlockBreakProgressUpdateEvent.patch} | 4 +- ...=> 0926-Deprecate-ItemStack-setType.patch} | 0 ...ch => 0927-Add-CartographyItemEvent.patch} | 4 +- ...aid-API.patch => 0928-More-Raid-API.patch} | 0 ...ng-message-for-initial-server-start.patch} | 8 +- ...-Configurable-max-block-fluid-ticks.patch} | 6 +- ...=> 0931-Fix-bees-aging-inside-hives.patch} | 0 ...2-Disable-memory-reserve-allocating.patch} | 0 ...ByEntityEvent-for-unowned-wither-sk.patch} | 0 ....patch => 0934-Fix-DamageSource-API.patch} | 0 ...nvalid-block-entity-during-world-ge.patch} | 4 +- ...ackOverflowError-for-some-dispenses.patch} | 0 ...=> 0937-Improve-tag-parser-handling.patch} | 2 +- ...s.patch => 0938-Item-Mutation-Fixes.patch} | 0 ...-Per-world-ticks-per-spawn-settings.patch} | 6 +- ...e-changed-item-from-dispense-events.patch} | 0 ...nd-End-Portal-Frames-from-being-des.patch} | 18 +- ...-for-mobs-immune-to-default-effects.patch} | 0 ... => 0943-Deep-clone-nbt-tags-in-PDC.patch} | 0 ...944-Support-old-UUID-format-for-NBT.patch} | 0 ...45-Fix-shield-disable-inconsistency.patch} | 4 +- ...-Large-Packets-disconnecting-client.patch} | 0 ...emFlags.patch => 0947-Fix-ItemFlags.patch} | 0 ...et-damage-reduction-inconsistencies.patch} | 0 ...-handling-of-LivingEntity-actuallyH.patch} | 10 +- ...e-checking-handled-tags-in-itemmeta.patch} | 0 ...51-Expose-hasColor-to-leather-armor.patch} | 0 ...-API-to-get-player-ha-proxy-address.patch} | 0 ...atch => 0953-General-ItemMeta-fixes.patch} | 4 +- ....patch => 0954-More-Chest-Block-API.patch} | 0 ...ta-component-type-on-encoding-error.patch} | 0 ...=> 0956-Brigadier-based-command-API.patch} | 40 +- ... => 0957-Fix-issues-with-Recipe-API.patch} | 0 ...58-Fix-equipment-slot-and-group-API.patch} | 0 ...lugin-to-use-Paper-PluginLoader-API.patch} | 0 ...versized-item-data-in-equipment-and.patch} | 4 +- ...nt-NPE-if-hooked-entity-was-cleared.patch} | 0 ...ng-BlockPlaceEvent-calling-onRemove.patch} | 4 +- ...963-Add-missing-fishing-event-state.patch} | 0 ...ate-InvAction-HOTBAR_MOVE_AND_READD.patch} | 0 ...nnect-packet-in-phases-where-it-doe.patch} | 0 ...tch => 0966-Adopt-MaterialRerouting.patch} | 0 ...=> 0967-Suspicious-Effect-Entry-API.patch} | 0 ...eck-if-itemstack-is-stackable-first.patch} | 0 ...emoving-recipes-from-RecipeIterator.patch} | 0 ...mage-tick-when-blocking-with-shield.patch} | 4 +- ...he-experimental-smithing-inventory-.patch} | 0 ...72-disable-forced-empty-world-ticks.patch} | 4 +- ...dBounds-and-getBlockState-for-inlin.patch} | 4 +- ...tem-frames-performance-and-bug-fixe.patch} | 4 +- ...Manager-and-add-advanced-packet-sup.patch} | 0 ...76-Allow-Saving-of-Oversized-Chunks.patch} | 0 ...977-Flat-bedrock-generator-settings.patch} | 0 ...=> 0978-Entity-Activation-Range-2.0.patch} | 94 +- ...0-Anti-Xray.patch => 0979-Anti-Xray.patch} | 26 +- ...city-compression-and-cipher-natives.patch} | 0 ...timize-Collision-to-not-load-chunks.patch} | 4 +- ...alSelector-Goal.Flag-Set-operations.patch} | 0 ...pers.patch => 0983-Optimize-Hoppers.patch} | 14 +- ...> 0984-Optimize-Voxel-Shape-Merging.patch} | 0 ...Optimize-Bit-Operations-by-inlining.patch} | 0 ...> 0986-Remove-streams-from-hot-code.patch} | 0 ...er-Remove-Streams-Optimized-collect.patch} | 0 ...-type-tags-suggestions-in-selectors.patch} | 0 ...-Oversized-block-entities-in-chunks.patch} | 0 ...eck-distance-in-entity-interactions.patch} | 8 +- ...ch => 0991-Configurable-Sand-Duping.patch} | 0 ...ch => 0992-Properly-resend-entities.patch} | 10 +- ...h => 0993-Registry-Modification-API.patch} | 4 +- ...994-Add-registry-entry-and-builders.patch} | 0 ...5-Proxy-ItemStack-to-CraftItemStack.patch} | 4 +- ...-accessible-directly-from-ItemStack.patch} | 0 ...aft-commands-in-function-parsing-an.patch} | 0 ...98-optimize-dirt-and-snow-spreading.patch} | 0 ... 0999-Fix-NPE-for-Jukebox-setRecord.patch} | 0 ...patch => 1000-fix-horse-inventories.patch} | 0 ...ityDamageEvents-before-actuallyHurt.patch} | 10 +- ... => 1002-Add-ItemType-getItemRarity.patch} | 0 ... => 1003-Add-plugin-info-at-startup.patch} | 0 ...tion-leniency-distance-configurable.patch} | 0 ...1005-Fix-PickupStatus-getting-reset.patch} | 0 ...ype-in-SculkSensorBlock-canActivate.patch} | 0 ...anPlaceOn-and-CanDestroy-NBT-values.patch} | 0 ...on-for-horizontal-only-item-merging.patch} | 0 ...009-Add-skipping-world-symlink-scan.patch} | 0 ... 1010-Add-even-more-Enchantment-API.patch} | 0 ...ble-API.patch => 1011-Leashable-API.patch} | 0 ...=> 1012-Fix-CraftBukkit-drag-system.patch} | 0 ...ent-firing-for-block-entity-loading.patch} | 0 ...-lootable-item-function-from-compas.patch} | 0 ...015-Add-enchantment-seed-update-API.patch} | 0 ...ending-chat-to-client-with-updating.patch} | 0 ...Fix-InventoryOpenEvent-cancellation.patch} | 0 ...ire-BlockExpEvent-on-grindstone-use.patch} | 0 ... => 1019-Check-dead-flag-in-isAlive.patch} | 4 +- ...I.patch => 1020-Add-FeatureFlag-API.patch} | 4 +- ....patch => 1021-Tag-Lifecycle-Events.patch} | 4 +- ... => 1022-Item-serialization-as-json.patch} | 4 +- ...ate-slot-in-PlayerInventory-setSlot.patch} | 0 ...ll-time-unused-skip-tick-protection.patch} | 0 ...tty-printing-for-advancement-saving.patch} | 0 ...dPreprocessEvent-on-signed-commands.patch} | 0 ...evels-with-enchantment-registry-set.patch} | 0 ...h => 1028-Improve-entity-effect-API.patch} | 0 ...me.patch => 1029-Add-recipeBrewTime.patch} | 0 ...30-Call-bucket-events-for-cauldrons.patch} | 0 ...31-Add-PlayerInsertLecternBookEvent.patch} | 0 ... 1032-Void-damage-configuration-API.patch} | 4 +- ...I.patch => 1033-Add-Offline-PDC-API.patch} | 0 ...w-bypassEnchantmentLevelRestriction.patch} | 0 ...-proper-async-player-disconnections.patch} | 0 ...-send-Banner-patterns-to-the-client.patch} | 0 ...> 1037-Rewrite-dataconverter-system.patch} | 6 +- ... 1038-Moonrise-optimisation-patches.patch} | 244 +- ...> 1039-API-for-checking-sent-chunks.patch} | 0 ...040-Fix-CraftWorld-isChunkGenerated.patch} | 0 ...tup-flag-to-disable-gamerule-limits.patch} | 0 ...h => 1042-Improved-Watchdog-Support.patch} | 46 +- ...-more-information-in-watchdog-dumps.patch} | 19 +- ...44-Entity-load-save-limit-per-chunk.patch} | 4 +- ...ulate-regionfile-header-if-it-is-co.patch} | 0 ...le-spark.patch => 1046-Bundle-spark.patch} | 36 +- ...-Improve-performance-of-mass-crafts.patch} | 0 ...Incremental-chunk-and-player-saving.patch} | 56 +- ...=> 1049-Optimise-general-POI-access.patch} | 0 ...r-desync-when-new-players-are-added.patch} | 4 +- ...atch => 1051-Lag-compensation-ticks.patch} | 22 +- ...n-checking-in-player-move-packet-ha.patch} | 0 ...1053-Optional-per-player-mob-spawns.patch} | 26 +- ...g-PreCreatureSpawnEvent-with-per-pl.patch} | 12 +- 665 files changed, 2226 insertions(+), 3556 deletions(-) rename patches/server/{0024-Further-improve-server-tick-loop.patch => 0023-Further-improve-server-tick-loop.patch} (96%) delete mode 100644 patches/server/0023-Timings-v2.patch create mode 100644 patches/server/0024-Remove-Spigot-timings.patch rename patches/server/{0602-Oprimise-map-impl-for-tracked-players.patch => 0601-Oprimise-map-impl-for-tracked-players.patch} (87%) delete mode 100644 patches/server/0601-Time-scoreboard-search.patch rename patches/server/{0603-Add-missing-InventoryType.patch => 0602-Add-missing-InventoryType.patch} (100%) rename patches/server/{0604-Optimise-BlockSoil-nearby-water-lookup.patch => 0603-Optimise-BlockSoil-nearby-water-lookup.patch} (100%) rename patches/server/{0605-Fix-merchant-inventory-not-closing-on-entity-removal.patch => 0604-Fix-merchant-inventory-not-closing-on-entity-removal.patch} (90%) rename patches/server/{0606-Check-requirement-before-suggesting-root-nodes.patch => 0605-Check-requirement-before-suggesting-root-nodes.patch} (100%) rename patches/server/{0607-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch => 0606-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch} (92%) rename patches/server/{0608-Add-packet-limiter-config.patch => 0607-Add-packet-limiter-config.patch} (100%) rename patches/server/{0609-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch => 0608-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch} (100%) rename patches/server/{0610-Ensure-valid-vehicle-status.patch => 0609-Ensure-valid-vehicle-status.patch} (100%) rename patches/server/{0611-Prevent-softlocked-end-exit-portal-generation.patch => 0610-Prevent-softlocked-end-exit-portal-generation.patch} (100%) rename patches/server/{0612-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch => 0611-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch} (100%) rename patches/server/{0613-Don-t-log-debug-logging-being-disabled.patch => 0612-Don-t-log-debug-logging-being-disabled.patch} (100%) rename patches/server/{0614-fix-various-menus-with-empty-level-accesses.patch => 0613-fix-various-menus-with-empty-level-accesses.patch} (100%) rename patches/server/{0615-Preserve-overstacked-loot.patch => 0614-Preserve-overstacked-loot.patch} (100%) rename patches/server/{0616-Update-head-rotation-in-missing-places.patch => 0615-Update-head-rotation-in-missing-places.patch} (100%) rename patches/server/{0617-prevent-unintended-light-block-manipulation.patch => 0616-prevent-unintended-light-block-manipulation.patch} (100%) rename patches/server/{0618-Fix-CraftCriteria-defaults-map.patch => 0617-Fix-CraftCriteria-defaults-map.patch} (100%) rename patches/server/{0619-Fix-upstreams-block-state-factories.patch => 0618-Fix-upstreams-block-state-factories.patch} (99%) rename patches/server/{0620-Configurable-feature-seeds.patch => 0619-Configurable-feature-seeds.patch} (62%) rename patches/server/{0621-Add-root-admin-user-detection.patch => 0620-Add-root-admin-user-detection.patch} (95%) rename patches/server/{0622-don-t-attempt-to-teleport-dead-entities.patch => 0621-don-t-attempt-to-teleport-dead-entities.patch} (100%) rename patches/server/{0623-Prevent-excessive-velocity-through-repeated-crits.patch => 0622-Prevent-excessive-velocity-through-repeated-crits.patch} (92%) rename patches/server/{0624-Remove-client-side-code-using-deprecated-for-removal.patch => 0623-Remove-client-side-code-using-deprecated-for-removal.patch} (100%) rename patches/server/{0625-Fix-Spigot-growth-modifiers.patch => 0624-Fix-Spigot-growth-modifiers.patch} (100%) rename patches/server/{0626-Prevent-ContainerOpenersCounter-openCount-from-going.patch => 0625-Prevent-ContainerOpenersCounter-openCount-from-going.patch} (100%) rename patches/server/{0627-Add-PlayerItemFrameChangeEvent.patch => 0626-Add-PlayerItemFrameChangeEvent.patch} (100%) rename patches/server/{0628-Optimize-HashMapPalette.patch => 0627-Optimize-HashMapPalette.patch} (100%) rename patches/server/{0629-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch => 0628-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch} (100%) rename patches/server/{0630-Add-more-Campfire-API.patch => 0629-Add-more-Campfire-API.patch} (100%) rename patches/server/{0631-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch => 0630-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch} (100%) rename patches/server/{0632-Forward-CraftEntity-in-teleport-command.patch => 0631-Forward-CraftEntity-in-teleport-command.patch} (100%) rename patches/server/{0633-Improve-scoreboard-entries.patch => 0632-Improve-scoreboard-entries.patch} (100%) rename patches/server/{0634-Entity-powdered-snow-API.patch => 0633-Entity-powdered-snow-API.patch} (100%) rename patches/server/{0635-Add-API-for-item-entity-health.patch => 0634-Add-API-for-item-entity-health.patch} (100%) rename patches/server/{0636-Configurable-max-block-light-for-monster-spawning.patch => 0635-Configurable-max-block-light-for-monster-spawning.patch} (100%) rename patches/server/{0637-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch => 0636-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch} (100%) rename patches/server/{0638-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch => 0637-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch} (100%) rename patches/server/{0639-Bucketable-API.patch => 0638-Bucketable-API.patch} (100%) rename patches/server/{0640-Validate-usernames.patch => 0639-Validate-usernames.patch} (96%) rename patches/server/{0641-Make-water-animal-spawn-height-configurable.patch => 0640-Make-water-animal-spawn-height-configurable.patch} (100%) rename patches/server/{0642-Expose-vanilla-BiomeProvider-from-WorldInfo.patch => 0641-Expose-vanilla-BiomeProvider-from-WorldInfo.patch} (95%) rename patches/server/{0643-Add-config-option-for-worlds-affected-by-time-cmd.patch => 0642-Add-config-option-for-worlds-affected-by-time-cmd.patch} (100%) rename patches/server/{0644-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch => 0643-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch} (100%) rename patches/server/{0645-Multiple-Entries-with-Scoreboards.patch => 0644-Multiple-Entries-with-Scoreboards.patch} (100%) rename patches/server/{0646-Reset-placed-block-on-exception.patch => 0645-Reset-placed-block-on-exception.patch} (100%) rename patches/server/{0647-Add-configurable-height-for-slime-spawn.patch => 0646-Add-configurable-height-for-slime-spawn.patch} (100%) rename patches/server/{0648-Fix-xp-reward-for-baby-zombies.patch => 0647-Fix-xp-reward-for-baby-zombies.patch} (100%) rename patches/server/{0649-Multi-Block-Change-API-Implementation.patch => 0648-Multi-Block-Change-API-Implementation.patch} (100%) rename patches/server/{0650-Fix-NotePlayEvent.patch => 0649-Fix-NotePlayEvent.patch} (100%) rename patches/server/{0651-Freeze-Tick-Lock-API.patch => 0650-Freeze-Tick-Lock-API.patch} (96%) rename patches/server/{0652-More-PotionEffectType-API.patch => 0651-More-PotionEffectType-API.patch} (100%) rename patches/server/{0653-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch => 0652-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch} (100%) rename patches/server/{0654-API-for-creating-command-sender-which-forwards-feedb.patch => 0653-API-for-creating-command-sender-which-forwards-feedb.patch} (97%) rename patches/server/{0655-Add-missing-structure-set-seed-configs.patch => 0654-Add-missing-structure-set-seed-configs.patch} (100%) rename patches/server/{0656-Fix-cancelled-powdered-snow-bucket-placement.patch => 0655-Fix-cancelled-powdered-snow-bucket-placement.patch} (100%) rename patches/server/{0657-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch => 0656-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch} (86%) rename patches/server/{0658-Add-GameEvent-tags.patch => 0657-Add-GameEvent-tags.patch} (95%) rename patches/server/{0659-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch => 0658-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch} (87%) rename patches/server/{0660-Furnace-RecipesUsed-API.patch => 0659-Furnace-RecipesUsed-API.patch} (100%) rename patches/server/{0661-Configurable-sculk-sensor-listener-range.patch => 0660-Configurable-sculk-sensor-listener-range.patch} (100%) rename patches/server/{0662-Add-missing-block-data-API.patch => 0661-Add-missing-block-data-API.patch} (100%) rename patches/server/{0663-Option-to-have-default-CustomSpawners-in-custom-worl.patch => 0662-Option-to-have-default-CustomSpawners-in-custom-worl.patch} (94%) rename patches/server/{0664-Put-world-into-worldlist-before-initing-the-world.patch => 0663-Put-world-into-worldlist-before-initing-the-world.patch} (86%) rename patches/server/{0665-Custom-Potion-Mixes.patch => 0664-Custom-Potion-Mixes.patch} (97%) rename patches/server/{0666-Force-close-world-loading-screen.patch => 0665-Force-close-world-loading-screen.patch} (93%) rename patches/server/{0667-Fix-falling-block-spawn-methods.patch => 0666-Fix-falling-block-spawn-methods.patch} (100%) rename patches/server/{0668-Expose-furnace-minecart-push-values.patch => 0667-Expose-furnace-minecart-push-values.patch} (100%) rename patches/server/{0669-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch => 0668-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch} (100%) rename patches/server/{0670-More-Projectile-API.patch => 0669-More-Projectile-API.patch} (100%) rename patches/server/{0671-Fix-swamp-hut-cat-generation-deadlock.patch => 0670-Fix-swamp-hut-cat-generation-deadlock.patch} (100%) rename patches/server/{0672-Don-t-allow-vehicle-movement-from-players-while-tele.patch => 0671-Don-t-allow-vehicle-movement-from-players-while-tele.patch} (94%) rename patches/server/{0673-Implement-getComputedBiome-API.patch => 0672-Implement-getComputedBiome-API.patch} (100%) rename patches/server/{0674-Make-some-itemstacks-nonnull.patch => 0673-Make-some-itemstacks-nonnull.patch} (100%) rename patches/server/{0675-Implement-enchantWithLevels-API.patch => 0674-Implement-enchantWithLevels-API.patch} (100%) rename patches/server/{0676-Fix-saving-in-unloadWorld.patch => 0675-Fix-saving-in-unloadWorld.patch} (83%) rename patches/server/{0677-Buffer-OOB-setBlock-calls.patch => 0676-Buffer-OOB-setBlock-calls.patch} (100%) rename patches/server/{0678-Add-TameableDeathMessageEvent.patch => 0677-Add-TameableDeathMessageEvent.patch} (100%) rename patches/server/{0679-Fix-new-block-data-for-EntityChangeBlockEvent.patch => 0678-Fix-new-block-data-for-EntityChangeBlockEvent.patch} (100%) rename patches/server/{0680-fix-player-loottables-running-when-mob-loot-gamerule.patch => 0679-fix-player-loottables-running-when-mob-loot-gamerule.patch} (100%) rename patches/server/{0681-Ensure-entity-passenger-world-matches-ridden-entity.patch => 0680-Ensure-entity-passenger-world-matches-ridden-entity.patch} (100%) rename patches/server/{0682-Cache-resource-keys-and-optimize-reference-Holder-ta.patch => 0681-Cache-resource-keys-and-optimize-reference-Holder-ta.patch} (100%) rename patches/server/{0683-Allow-changing-the-EnderDragon-podium.patch => 0682-Allow-changing-the-EnderDragon-podium.patch} (100%) rename patches/server/{0684-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch => 0683-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch} (100%) rename patches/server/{0685-Prevent-tile-entity-copies-loading-chunks.patch => 0684-Prevent-tile-entity-copies-loading-chunks.patch} (90%) rename patches/server/{0686-Use-username-instead-of-display-name-in-PlayerList-g.patch => 0685-Use-username-instead-of-display-name-in-PlayerList-g.patch} (87%) rename patches/server/{0687-Expand-PlayerItemDamageEvent.patch => 0686-Expand-PlayerItemDamageEvent.patch} (100%) rename patches/server/{0688-WorldCreator-keepSpawnLoaded.patch => 0687-WorldCreator-keepSpawnLoaded.patch} (87%) rename patches/server/{0689-Fix-CME-in-CraftPersistentDataTypeRegistry.patch => 0688-Fix-CME-in-CraftPersistentDataTypeRegistry.patch} (100%) rename patches/server/{0690-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch => 0689-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch} (100%) rename patches/server/{0691-Add-EntityDyeEvent-and-CollarColorable-interface.patch => 0690-Add-EntityDyeEvent-and-CollarColorable-interface.patch} (100%) rename patches/server/{0692-Fire-CauldronLevelChange-on-initial-fill.patch => 0691-Fire-CauldronLevelChange-on-initial-fill.patch} (100%) rename patches/server/{0693-fix-powder-snow-cauldrons-not-turning-to-water.patch => 0692-fix-powder-snow-cauldrons-not-turning-to-water.patch} (100%) rename patches/server/{0694-Add-PlayerStopUsingItemEvent.patch => 0693-Add-PlayerStopUsingItemEvent.patch} (85%) rename patches/server/{0695-Don-t-tick-markers.patch => 0694-Don-t-tick-markers.patch} (93%) rename patches/server/{0696-Expand-FallingBlock-API.patch => 0695-Expand-FallingBlock-API.patch} (100%) rename patches/server/{0697-Add-support-for-Proxy-Protocol.patch => 0696-Add-support-for-Proxy-Protocol.patch} (100%) rename patches/server/{0698-Fix-OfflinePlayer-getBedSpawnLocation.patch => 0697-Fix-OfflinePlayer-getBedSpawnLocation.patch} (100%) rename patches/server/{0699-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch => 0698-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch} (100%) rename patches/server/{0700-Sanitize-sent-BlockEntity-NBT.patch => 0699-Sanitize-sent-BlockEntity-NBT.patch} (95%) rename patches/server/{0701-Disable-component-selector-resolving-in-books-by-def.patch => 0700-Disable-component-selector-resolving-in-books-by-def.patch} (100%) rename patches/server/{0702-Prevent-entity-loading-causing-async-lookups.patch => 0701-Prevent-entity-loading-causing-async-lookups.patch} (100%) rename patches/server/{0703-Throw-exception-on-world-create-while-being-ticked.patch => 0702-Throw-exception-on-world-create-while-being-ticked.patch} (80%) rename patches/server/{0704-Dont-resent-entity-on-art-update.patch => 0703-Dont-resent-entity-on-art-update.patch} (100%) rename patches/server/{0705-Add-WardenAngerChangeEvent.patch => 0704-Add-WardenAngerChangeEvent.patch} (100%) rename patches/server/{0706-Add-option-for-strict-advancement-dimension-checks.patch => 0705-Add-option-for-strict-advancement-dimension-checks.patch} (100%) rename patches/server/{0707-Add-missing-important-BlockStateListPopulator-method.patch => 0706-Add-missing-important-BlockStateListPopulator-method.patch} (100%) rename patches/server/{0708-Nameable-Banner-API.patch => 0707-Nameable-Banner-API.patch} (100%) rename patches/server/{0709-Don-t-broadcast-messages-to-command-blocks.patch => 0708-Don-t-broadcast-messages-to-command-blocks.patch} (92%) rename patches/server/{0710-Prevent-empty-items-from-being-added-to-world.patch => 0709-Prevent-empty-items-from-being-added-to-world.patch} (89%) rename patches/server/{0711-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch => 0710-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch} (100%) rename patches/server/{0712-Add-Player-getFishHook.patch => 0711-Add-Player-getFishHook.patch} (100%) rename patches/server/{0713-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch => 0712-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch} (100%) rename patches/server/{0714-Add-various-missing-EntityDropItemEvent-calls.patch => 0713-Add-various-missing-EntityDropItemEvent-calls.patch} (100%) rename patches/server/{0715-Fix-Bee-flower-NPE.patch => 0714-Fix-Bee-flower-NPE.patch} (100%) rename patches/server/{0716-More-Teleport-API.patch => 0715-More-Teleport-API.patch} (99%) rename patches/server/{0717-Add-EntityPortalReadyEvent.patch => 0716-Add-EntityPortalReadyEvent.patch} (100%) rename patches/server/{0718-Don-t-use-level-random-in-entity-constructors.patch => 0717-Don-t-use-level-random-in-entity-constructors.patch} (100%) rename patches/server/{0719-Send-block-entities-after-destroy-prediction.patch => 0718-Send-block-entities-after-destroy-prediction.patch} (98%) rename patches/server/{0720-Warn-on-plugins-accessing-faraway-chunks.patch => 0719-Warn-on-plugins-accessing-faraway-chunks.patch} (97%) rename patches/server/{0721-Custom-Chat-Completion-Suggestions-API.patch => 0720-Custom-Chat-Completion-Suggestions-API.patch} (100%) rename patches/server/{0722-Add-and-fix-missing-BlockFadeEvents.patch => 0721-Add-and-fix-missing-BlockFadeEvents.patch} (100%) rename patches/server/{0723-Collision-API.patch => 0722-Collision-API.patch} (100%) rename patches/server/{0724-Fix-suggest-command-message-for-brigadier-syntax-exc.patch => 0723-Fix-suggest-command-message-for-brigadier-syntax-exc.patch} (100%) rename patches/server/{0725-Block-Ticking-API.patch => 0724-Block-Ticking-API.patch} (100%) rename patches/server/{0726-Add-Velocity-IP-Forwarding-Support.patch => 0725-Add-Velocity-IP-Forwarding-Support.patch} (97%) rename patches/server/{0727-Add-NamespacedKey-biome-methods.patch => 0726-Add-NamespacedKey-biome-methods.patch} (76%) rename patches/server/{0728-Fix-plugin-loggers-on-server-shutdown.patch => 0727-Fix-plugin-loggers-on-server-shutdown.patch} (94%) rename patches/server/{0729-Stop-large-look-changes-from-crashing-the-server.patch => 0728-Stop-large-look-changes-from-crashing-the-server.patch} (94%) rename patches/server/{0730-Fire-EntityChangeBlockEvent-in-more-places.patch => 0729-Fire-EntityChangeBlockEvent-in-more-places.patch} (100%) rename patches/server/{0731-Missing-eating-regain-reason.patch => 0730-Missing-eating-regain-reason.patch} (100%) rename patches/server/{0732-Missing-effect-cause.patch => 0731-Missing-effect-cause.patch} (100%) rename patches/server/{0733-Added-byte-array-serialization-deserialization-for-P.patch => 0732-Added-byte-array-serialization-deserialization-for-P.patch} (100%) rename patches/server/{0734-Call-BlockPhysicsEvent-more-often.patch => 0733-Call-BlockPhysicsEvent-more-often.patch} (100%) rename patches/server/{0735-Configurable-chat-thread-limit.patch => 0734-Configurable-chat-thread-limit.patch} (94%) rename patches/server/{0736-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch => 0735-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch} (100%) rename patches/server/{0737-fix-Jigsaw-block-kicking-user.patch => 0736-fix-Jigsaw-block-kicking-user.patch} (100%) rename patches/server/{0738-use-BlockFormEvent-for-mud-converting-into-clay.patch => 0737-use-BlockFormEvent-for-mud-converting-into-clay.patch} (100%) rename patches/server/{0739-Add-getDrops-to-BlockState.patch => 0738-Add-getDrops-to-BlockState.patch} (100%) rename patches/server/{0740-Fix-a-bunch-of-vanilla-bugs.patch => 0739-Fix-a-bunch-of-vanilla-bugs.patch} (97%) rename patches/server/{0741-Remove-unnecessary-onTrackingStart-during-navigation.patch => 0740-Remove-unnecessary-onTrackingStart-during-navigation.patch} (88%) rename patches/server/{0742-Fix-custom-piglin-loved-items.patch => 0741-Fix-custom-piglin-loved-items.patch} (100%) rename patches/server/{0743-EntityPickupItemEvent-fixes.patch => 0742-EntityPickupItemEvent-fixes.patch} (100%) rename patches/server/{0744-Correctly-handle-interactions-with-items-on-cooldown.patch => 0743-Correctly-handle-interactions-with-items-on-cooldown.patch} (100%) rename patches/server/{0745-Add-PlayerInventorySlotChangeEvent.patch => 0744-Add-PlayerInventorySlotChangeEvent.patch} (100%) rename patches/server/{0746-Elder-Guardian-appearance-API.patch => 0745-Elder-Guardian-appearance-API.patch} (100%) rename patches/server/{0747-Add-entity-knockback-API.patch => 0746-Add-entity-knockback-API.patch} (100%) rename patches/server/{0748-Detect-headless-JREs.patch => 0747-Detect-headless-JREs.patch} (100%) rename patches/server/{0749-fix-entity-vehicle-collision-event-not-called.patch => 0748-fix-entity-vehicle-collision-event-not-called.patch} (100%) rename patches/server/{0750-Add-EntityToggleSitEvent.patch => 0749-Add-EntityToggleSitEvent.patch} (100%) rename patches/server/{0751-Add-fire-tick-delay-option.patch => 0750-Add-fire-tick-delay-option.patch} (100%) rename patches/server/{0752-Add-Moving-Piston-API.patch => 0751-Add-Moving-Piston-API.patch} (100%) rename patches/server/{0753-Ignore-impossible-spawn-tick.patch => 0752-Ignore-impossible-spawn-tick.patch} (100%) rename patches/server/{0754-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch => 0753-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch} (100%) rename patches/server/{0755-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch => 0754-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch} (100%) rename patches/server/{0756-Add-PrePlayerAttackEntityEvent.patch => 0755-Add-PrePlayerAttackEntityEvent.patch} (100%) rename patches/server/{0757-ensure-reset-EnderDragon-boss-event-name.patch => 0756-ensure-reset-EnderDragon-boss-event-name.patch} (100%) rename patches/server/{0758-Add-Player-Warden-Warning-API.patch => 0757-Add-Player-Warden-Warning-API.patch} (100%) rename patches/server/{0759-More-vanilla-friendly-methods-to-update-trades.patch => 0758-More-vanilla-friendly-methods-to-update-trades.patch} (100%) rename patches/server/{0760-Add-paper-dumplisteners-command.patch => 0759-Add-paper-dumplisteners-command.patch} (100%) rename patches/server/{0761-check-global-player-list-where-appropriate.patch => 0760-check-global-player-list-where-appropriate.patch} (93%) rename patches/server/{0762-Fix-async-entity-add-due-to-fungus-trees.patch => 0761-Fix-async-entity-add-due-to-fungus-trees.patch} (100%) rename patches/server/{0763-ItemStack-damage-API.patch => 0762-ItemStack-damage-API.patch} (100%) rename patches/server/{0764-Friction-API.patch => 0763-Friction-API.patch} (95%) rename patches/server/{0765-Ability-to-control-player-s-insomnia-and-phantoms.patch => 0764-Ability-to-control-player-s-insomnia-and-phantoms.patch} (100%) rename patches/server/{0766-Fix-premature-player-kicks-on-shutdown.patch => 0765-Fix-premature-player-kicks-on-shutdown.patch} (95%) rename patches/server/{0767-Sync-offhand-slot-in-menus.patch => 0766-Sync-offhand-slot-in-menus.patch} (100%) rename patches/server/{0768-Player-Entity-Tracking-Events.patch => 0767-Player-Entity-Tracking-Events.patch} (93%) rename patches/server/{0769-Limit-pet-look-distance.patch => 0768-Limit-pet-look-distance.patch} (100%) rename patches/server/{0770-fix-Instruments.patch => 0769-fix-Instruments.patch} (100%) rename patches/server/{0771-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch => 0770-Improve-inlining-for-some-hot-BlockBehavior-and-Flui.patch} (100%) rename patches/server/{0772-Add-BlockLockCheckEvent.patch => 0771-Add-BlockLockCheckEvent.patch} (100%) rename patches/server/{0773-Add-Sneaking-API-for-Entities.patch => 0772-Add-Sneaking-API-for-Entities.patch} (100%) rename patches/server/{0774-Improve-logging-and-errors.patch => 0773-Improve-logging-and-errors.patch} (95%) rename patches/server/{0775-Improve-PortalEvents.patch => 0774-Improve-PortalEvents.patch} (100%) rename patches/server/{0776-Add-config-option-for-spider-worldborder-climbing.patch => 0775-Add-config-option-for-spider-worldborder-climbing.patch} (100%) rename patches/server/{0777-Add-missing-SpigotConfig-logCommands-check.patch => 0776-Add-missing-SpigotConfig-logCommands-check.patch} (95%) rename patches/server/{0778-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch => 0777-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch} (100%) rename patches/server/{0779-Flying-Fall-Damage.patch => 0778-Flying-Fall-Damage.patch} (100%) rename patches/server/{0780-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch => 0779-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch} (100%) rename patches/server/{0781-config-for-disabling-entity-tag-tags.patch => 0780-config-for-disabling-entity-tag-tags.patch} (89%) rename patches/server/{0782-Use-single-player-info-update-packet-on-join.patch => 0781-Use-single-player-info-update-packet-on-join.patch} (89%) rename patches/server/{0783-Correctly-shrink-items-during-EntityResurrectEvent.patch => 0782-Correctly-shrink-items-during-EntityResurrectEvent.patch} (92%) rename patches/server/{0784-Win-Screen-API.patch => 0783-Win-Screen-API.patch} (100%) rename patches/server/{0785-Remove-CraftItemStack-setAmount-null-assignment.patch => 0784-Remove-CraftItemStack-setAmount-null-assignment.patch} (100%) rename patches/server/{0786-Fix-force-opening-enchantment-tables.patch => 0785-Fix-force-opening-enchantment-tables.patch} (100%) rename patches/server/{0787-Add-Entity-Body-Yaw-API.patch => 0786-Add-Entity-Body-Yaw-API.patch} (100%) rename patches/server/{0788-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch => 0787-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch} (100%) rename patches/server/{0789-Add-EntityFertilizeEggEvent.patch => 0788-Add-EntityFertilizeEggEvent.patch} (100%) rename patches/server/{0790-Fix-HumanEntity-drop-not-updating-the-client-inv.patch => 0789-Fix-HumanEntity-drop-not-updating-the-client-inv.patch} (100%) rename patches/server/{0791-Add-CompostItemEvent-and-EntityCompostItemEvent.patch => 0790-Add-CompostItemEvent-and-EntityCompostItemEvent.patch} (100%) rename patches/server/{0792-Correctly-handle-ArmorStand-invisibility.patch => 0791-Correctly-handle-ArmorStand-invisibility.patch} (100%) rename patches/server/{0793-Fix-advancement-triggers-for-entity-damage.patch => 0792-Fix-advancement-triggers-for-entity-damage.patch} (93%) rename patches/server/{0794-Fix-text-display-error-on-spawn.patch => 0793-Fix-text-display-error-on-spawn.patch} (100%) rename patches/server/{0795-Fix-inventories-returning-null-Locations.patch => 0794-Fix-inventories-returning-null-Locations.patch} (100%) rename patches/server/{0796-Add-Shearable-API.patch => 0795-Add-Shearable-API.patch} (100%) rename patches/server/{0797-Fix-SpawnEggMeta-get-setSpawnedType.patch => 0796-Fix-SpawnEggMeta-get-setSpawnedType.patch} (100%) rename patches/server/{0798-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch => 0797-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch} (100%) rename patches/server/{0799-Treat-sequence-violations-like-they-should-be.patch => 0798-Treat-sequence-violations-like-they-should-be.patch} (92%) rename patches/server/{0800-Prevent-causing-expired-keys-from-impacting-new-join.patch => 0799-Prevent-causing-expired-keys-from-impacting-new-join.patch} (96%) rename patches/server/{0801-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch => 0800-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch} (86%) rename patches/server/{0802-Use-array-for-gamerule-storage.patch => 0801-Use-array-for-gamerule-storage.patch} (100%) rename patches/server/{0803-Fix-a-couple-of-upstream-bed-issues.patch => 0802-Fix-a-couple-of-upstream-bed-issues.patch} (100%) rename patches/server/{0804-Fix-demo-flag-not-enabling-demo-mode.patch => 0803-Fix-demo-flag-not-enabling-demo-mode.patch} (100%) rename patches/server/{0805-Add-Mob-Experience-reward-API.patch => 0804-Add-Mob-Experience-reward-API.patch} (100%) rename patches/server/{0806-Break-redstone-on-top-of-trap-doors-early.patch => 0805-Break-redstone-on-top-of-trap-doors-early.patch} (100%) rename patches/server/{0807-Avoid-Lazy-Initialization-for-Enum-Fields.patch => 0806-Avoid-Lazy-Initialization-for-Enum-Fields.patch} (100%) rename patches/server/{0808-More-accurate-isInOpenWater-impl.patch => 0807-More-accurate-isInOpenWater-impl.patch} (100%) rename patches/server/{0809-Expand-PlayerItemMendEvent.patch => 0808-Expand-PlayerItemMendEvent.patch} (100%) rename patches/server/{0810-Refresh-ProjectileSource-for-projectiles.patch => 0809-Refresh-ProjectileSource-for-projectiles.patch} (100%) rename patches/server/{0811-Add-transient-modifier-API.patch => 0810-Add-transient-modifier-API.patch} (100%) rename patches/server/{0812-Fix-block-place-logic.patch => 0811-Fix-block-place-logic.patch} (95%) rename patches/server/{0813-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch => 0812-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch} (100%) rename patches/server/{0814-Call-BlockGrowEvent-for-missing-blocks.patch => 0813-Call-BlockGrowEvent-for-missing-blocks.patch} (100%) rename patches/server/{0815-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch => 0814-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch} (94%) rename patches/server/{0816-fix-MapLike-spam-for-missing-key-selector.patch => 0815-fix-MapLike-spam-for-missing-key-selector.patch} (100%) rename patches/server/{0817-Fix-sniffer-removeExploredLocation.patch => 0816-Fix-sniffer-removeExploredLocation.patch} (100%) rename patches/server/{0818-Add-method-to-remove-all-active-potion-effects.patch => 0817-Add-method-to-remove-all-active-potion-effects.patch} (100%) rename patches/server/{0819-Add-event-for-player-editing-sign.patch => 0818-Add-event-for-player-editing-sign.patch} (100%) rename patches/server/{0820-Only-tick-item-frames-if-players-can-see-it.patch => 0819-Only-tick-item-frames-if-players-can-see-it.patch} (100%) rename patches/server/{0821-Fix-cmd-permission-levels-for-command-blocks.patch => 0820-Fix-cmd-permission-levels-for-command-blocks.patch} (100%) rename patches/server/{0822-Add-option-to-disable-block-updates.patch => 0821-Add-option-to-disable-block-updates.patch} (100%) rename patches/server/{0823-Call-missing-BlockDispenseEvent.patch => 0822-Call-missing-BlockDispenseEvent.patch} (100%) rename patches/server/{0824-Don-t-load-chunks-for-supporting-block-checks.patch => 0823-Don-t-load-chunks-for-supporting-block-checks.patch} (100%) rename patches/server/{0825-Optimize-player-lookups-for-beacons.patch => 0824-Optimize-player-lookups-for-beacons.patch} (100%) rename patches/server/{0826-More-Sign-Block-API.patch => 0825-More-Sign-Block-API.patch} (100%) rename patches/server/{0827-fix-item-meta-for-tadpole-buckets.patch => 0826-fix-item-meta-for-tadpole-buckets.patch} (100%) rename patches/server/{0828-Fix-BanList-API.patch => 0827-Fix-BanList-API.patch} (100%) rename patches/server/{0829-Determine-lava-and-water-fluid-explosion-resistance-.patch => 0828-Determine-lava-and-water-fluid-explosion-resistance-.patch} (100%) rename patches/server/{0830-Fix-possible-NPE-on-painting-creation.patch => 0829-Fix-possible-NPE-on-painting-creation.patch} (100%) rename patches/server/{0831-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch => 0830-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch} (100%) rename patches/server/{0832-ExperienceOrb-should-call-EntitySpawnEvent.patch => 0831-ExperienceOrb-should-call-EntitySpawnEvent.patch} (100%) rename patches/server/{0833-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch => 0832-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch} (100%) rename patches/server/{0834-Add-whitelist-events.patch => 0833-Add-whitelist-events.patch} (100%) rename patches/server/{0835-Implement-PlayerFailMoveEvent.patch => 0834-Implement-PlayerFailMoveEvent.patch} (98%) rename patches/server/{0836-Folia-scheduler-and-owned-region-API.patch => 0835-Folia-scheduler-and-owned-region-API.patch} (98%) rename patches/server/{0837-Only-erase-allay-memory-on-non-item-targets.patch => 0836-Only-erase-allay-memory-on-non-item-targets.patch} (100%) rename patches/server/{0838-Fix-rotation-when-spawning-display-entities.patch => 0837-Fix-rotation-when-spawning-display-entities.patch} (100%) rename patches/server/{0839-Only-capture-actual-tree-growth.patch => 0838-Only-capture-actual-tree-growth.patch} (97%) rename patches/server/{0840-Use-correct-source-for-mushroom-block-spread-event.patch => 0839-Use-correct-source-for-mushroom-block-spread-event.patch} (100%) rename patches/server/{0841-Respect-randomizeData-on-more-entities-when-spawning.patch => 0840-Respect-randomizeData-on-more-entities-when-spawning.patch} (100%) rename patches/server/{0842-Use-correct-seed-on-api-world-load.patch => 0841-Use-correct-seed-on-api-world-load.patch} (87%) rename patches/server/{0843-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch => 0842-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch} (100%) rename patches/server/{0844-Cache-map-ids-on-item-frames.patch => 0843-Cache-map-ids-on-item-frames.patch} (100%) rename patches/server/{0845-API-for-updating-recipes-on-clients.patch => 0844-API-for-updating-recipes-on-clients.patch} (88%) rename patches/server/{0846-Fix-custom-statistic-criteria-creation.patch => 0845-Fix-custom-statistic-criteria-creation.patch} (59%) rename patches/server/{0847-Bandaid-fix-for-Effect.patch => 0846-Bandaid-fix-for-Effect.patch} (100%) rename patches/server/{0848-SculkCatalyst-bloom-API.patch => 0847-SculkCatalyst-bloom-API.patch} (100%) rename patches/server/{0849-API-for-an-entity-s-scoreboard-name.patch => 0848-API-for-an-entity-s-scoreboard-name.patch} (100%) rename patches/server/{0850-Deprecate-and-replace-methods-with-old-StructureType.patch => 0849-Deprecate-and-replace-methods-with-old-StructureType.patch} (92%) rename patches/server/{0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch => 0850-Don-t-tab-complete-namespaced-commands-if-send-names.patch} (95%) rename patches/server/{0852-Properly-handle-BlockBreakEvent-isDropItems.patch => 0851-Properly-handle-BlockBreakEvent-isDropItems.patch} (98%) rename patches/server/{0853-Fire-entity-death-event-for-ender-dragon.patch => 0852-Fire-entity-death-event-for-ender-dragon.patch} (100%) rename patches/server/{0854-Configurable-entity-tracking-range-by-Y-coordinate.patch => 0853-Configurable-entity-tracking-range-by-Y-coordinate.patch} (92%) rename patches/server/{0855-Add-Listing-API-for-Player.patch => 0854-Add-Listing-API-for-Player.patch} (98%) rename patches/server/{0856-Configurable-Region-Compression-Format.patch => 0855-Configurable-Region-Compression-Format.patch} (100%) rename patches/server/{0857-Add-BlockFace-to-BlockDamageEvent.patch => 0856-Add-BlockFace-to-BlockDamageEvent.patch} (100%) rename patches/server/{0858-Fix-NPE-on-Boat-getStatus.patch => 0857-Fix-NPE-on-Boat-getStatus.patch} (100%) rename patches/server/{0859-Expand-Pose-API.patch => 0858-Expand-Pose-API.patch} (100%) rename patches/server/{0860-More-DragonBattle-API.patch => 0859-More-DragonBattle-API.patch} (100%) rename patches/server/{0861-Add-PlayerPickItemEvent.patch => 0860-Add-PlayerPickItemEvent.patch} (96%) rename patches/server/{0862-Allow-trident-custom-damage.patch => 0861-Allow-trident-custom-damage.patch} (100%) rename patches/server/{0863-Expose-hand-in-BlockCanBuildEvent.patch => 0862-Expose-hand-in-BlockCanBuildEvent.patch} (100%) rename patches/server/{0864-Optimize-nearest-structure-border-iteration.patch => 0863-Optimize-nearest-structure-border-iteration.patch} (100%) rename patches/server/{0865-Implement-OfflinePlayer-isConnected.patch => 0864-Implement-OfflinePlayer-isConnected.patch} (100%) rename patches/server/{0866-Fix-slot-desync.patch => 0865-Fix-slot-desync.patch} (98%) rename patches/server/{0867-Add-titleOverride-to-InventoryOpenEvent.patch => 0866-Add-titleOverride-to-InventoryOpenEvent.patch} (100%) rename patches/server/{0868-Configure-sniffer-egg-hatch-time.patch => 0867-Configure-sniffer-egg-hatch-time.patch} (100%) rename patches/server/{0869-Do-crystal-portal-proximity-check-before-entity-look.patch => 0868-Do-crystal-portal-proximity-check-before-entity-look.patch} (100%) rename patches/server/{0870-Skip-POI-finding-if-stuck-in-vehicle.patch => 0869-Skip-POI-finding-if-stuck-in-vehicle.patch} (100%) rename patches/server/{0871-Add-slot-sanity-checks-in-container-clicks.patch => 0870-Add-slot-sanity-checks-in-container-clicks.patch} (94%) rename patches/server/{0872-Call-BlockRedstoneEvents-for-lecterns.patch => 0871-Call-BlockRedstoneEvents-for-lecterns.patch} (100%) rename patches/server/{0873-Allow-proper-checking-of-empty-item-stacks.patch => 0872-Allow-proper-checking-of-empty-item-stacks.patch} (100%) rename patches/server/{0874-Fix-silent-equipment-change-for-mobs.patch => 0873-Fix-silent-equipment-change-for-mobs.patch} (100%) rename patches/server/{0875-Fix-spigot-s-Forced-Stats.patch => 0874-Fix-spigot-s-Forced-Stats.patch} (100%) rename patches/server/{0876-Add-missing-InventoryHolders-to-inventories.patch => 0875-Add-missing-InventoryHolders-to-inventories.patch} (100%) rename patches/server/{0877-Do-not-read-tile-entities-in-chunks-that-are-positio.patch => 0876-Do-not-read-tile-entities-in-chunks-that-are-positio.patch} (100%) rename patches/server/{0878-Add-missing-logs-for-log-ips-config-option.patch => 0877-Add-missing-logs-for-log-ips-config-option.patch} (100%) rename patches/server/{0879-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch => 0878-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch} (100%) rename patches/server/{0880-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch => 0879-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch} (100%) rename patches/server/{0881-Fix-team-sidebar-objectives-not-being-cleared.patch => 0880-Fix-team-sidebar-objectives-not-being-cleared.patch} (94%) rename patches/server/{0882-Fix-missing-map-initialize-event-call.patch => 0881-Fix-missing-map-initialize-event-call.patch} (93%) rename patches/server/{0883-Update-entity-data-when-attaching-firework-to-entity.patch => 0882-Update-entity-data-when-attaching-firework-to-entity.patch} (100%) rename patches/server/{0884-Fix-UnsafeValues-loadAdvancement.patch => 0883-Fix-UnsafeValues-loadAdvancement.patch} (94%) rename patches/server/{0885-Add-player-idle-duration-API.patch => 0884-Add-player-idle-duration-API.patch} (100%) rename patches/server/{0886-Don-t-check-if-we-can-see-non-visible-entities.patch => 0885-Don-t-check-if-we-can-see-non-visible-entities.patch} (85%) rename patches/server/{0887-Fix-NPE-in-SculkBloomEvent-world-access.patch => 0886-Fix-NPE-in-SculkBloomEvent-world-access.patch} (100%) rename patches/server/{0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch => 0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch} (100%) rename patches/server/{0889-Optimize-VarInts.patch => 0888-Optimize-VarInts.patch} (100%) rename patches/server/{0890-Add-API-to-get-the-collision-shape-of-a-block-before.patch => 0889-Add-API-to-get-the-collision-shape-of-a-block-before.patch} (100%) rename patches/server/{0891-Add-predicate-for-blocks-when-raytracing.patch => 0890-Add-predicate-for-blocks-when-raytracing.patch} (100%) rename patches/server/{0892-Broadcast-take-item-packets-with-collector-as-source.patch => 0891-Broadcast-take-item-packets-with-collector-as-source.patch} (88%) rename patches/server/{0893-Expand-LingeringPotion-API.patch => 0892-Expand-LingeringPotion-API.patch} (100%) rename patches/server/{0894-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch => 0893-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch} (100%) rename patches/server/{0895-Add-hand-to-fish-event-for-all-player-interactions.patch => 0894-Add-hand-to-fish-event-for-all-player-interactions.patch} (100%) rename patches/server/{0896-Fix-several-issues-with-EntityBreedEvent.patch => 0895-Fix-several-issues-with-EntityBreedEvent.patch} (100%) rename patches/server/{0897-Add-UUID-attribute-modifier-API.patch => 0896-Add-UUID-attribute-modifier-API.patch} (100%) rename patches/server/{0898-Fix-missing-event-call-for-entity-teleport-API.patch => 0897-Fix-missing-event-call-for-entity-teleport-API.patch} (100%) rename patches/server/{0899-Lazily-create-LootContext-for-criterions.patch => 0898-Lazily-create-LootContext-for-criterions.patch} (100%) rename patches/server/{0900-Don-t-fire-sync-events-during-worldgen.patch => 0899-Don-t-fire-sync-events-during-worldgen.patch} (95%) rename patches/server/{0901-Add-Structure-check-API.patch => 0900-Add-Structure-check-API.patch} (100%) rename patches/server/{0902-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch => 0901-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch} (100%) rename patches/server/{0903-Restore-vanilla-entity-drops-behavior.patch => 0902-Restore-vanilla-entity-drops-behavior.patch} (99%) rename patches/server/{0904-Dont-resend-blocks-on-interactions.patch => 0903-Dont-resend-blocks-on-interactions.patch} (100%) rename patches/server/{0905-add-more-scoreboard-API.patch => 0904-add-more-scoreboard-API.patch} (100%) rename patches/server/{0906-Improve-Registry.patch => 0905-Improve-Registry.patch} (100%) rename patches/server/{0907-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch => 0906-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch} (96%) rename patches/server/{0908-Add-experience-points-API.patch => 0907-Add-experience-points-API.patch} (100%) rename patches/server/{0909-Add-drops-to-shear-events.patch => 0908-Add-drops-to-shear-events.patch} (100%) rename patches/server/{0910-Add-PlayerShieldDisableEvent.patch => 0909-Add-PlayerShieldDisableEvent.patch} (100%) rename patches/server/{0911-Validate-ResourceLocation-in-NBT-reading.patch => 0910-Validate-ResourceLocation-in-NBT-reading.patch} (97%) rename patches/server/{0912-Properly-handle-experience-dropping-on-block-break.patch => 0911-Properly-handle-experience-dropping-on-block-break.patch} (94%) rename patches/server/{0913-Fixup-NamespacedKey-handling.patch => 0912-Fixup-NamespacedKey-handling.patch} (100%) rename patches/server/{0914-Expose-LootTable-of-DecoratedPot.patch => 0913-Expose-LootTable-of-DecoratedPot.patch} (100%) rename patches/server/{0915-Reduce-allocation-of-Vec3D-by-entity-tracker.patch => 0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch} (95%) rename patches/server/{0916-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch => 0915-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch} (100%) rename patches/server/{0917-Add-ShulkerDuplicateEvent.patch => 0916-Add-ShulkerDuplicateEvent.patch} (100%) rename patches/server/{0918-Add-api-for-spawn-egg-texture-colors.patch => 0917-Add-api-for-spawn-egg-texture-colors.patch} (82%) rename patches/server/{0919-Add-Lifecycle-Event-system.patch => 0918-Add-Lifecycle-Event-system.patch} (99%) rename patches/server/{0920-ItemStack-Tooltip-API.patch => 0919-ItemStack-Tooltip-API.patch} (78%) rename patches/server/{0921-Add-getChunkSnapshot-includeLightData-parameter.patch => 0920-Add-getChunkSnapshot-includeLightData-parameter.patch} (100%) rename patches/server/{0922-Add-FluidState-API.patch => 0921-Add-FluidState-API.patch} (100%) rename patches/server/{0923-add-number-format-api.patch => 0922-add-number-format-api.patch} (100%) rename patches/server/{0924-improve-BanList-types.patch => 0923-improve-BanList-types.patch} (89%) rename patches/server/{0925-Expanded-Hopper-API.patch => 0924-Expanded-Hopper-API.patch} (100%) rename patches/server/{0926-Add-BlockBreakProgressUpdateEvent.patch => 0925-Add-BlockBreakProgressUpdateEvent.patch} (90%) rename patches/server/{0927-Deprecate-ItemStack-setType.patch => 0926-Deprecate-ItemStack-setType.patch} (100%) rename patches/server/{0928-Add-CartographyItemEvent.patch => 0927-Add-CartographyItemEvent.patch} (94%) rename patches/server/{0929-More-Raid-API.patch => 0928-More-Raid-API.patch} (100%) rename patches/server/{0930-Add-onboarding-message-for-initial-server-start.patch => 0929-Add-onboarding-message-for-initial-server-start.patch} (94%) rename patches/server/{0931-Configurable-max-block-fluid-ticks.patch => 0930-Configurable-max-block-fluid-ticks.patch} (83%) rename patches/server/{0932-Fix-bees-aging-inside-hives.patch => 0931-Fix-bees-aging-inside-hives.patch} (100%) rename patches/server/{0933-Disable-memory-reserve-allocating.patch => 0932-Disable-memory-reserve-allocating.patch} (100%) rename patches/server/{0934-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch => 0933-Fire-EntityDamageByEntityEvent-for-unowned-wither-sk.patch} (100%) rename patches/server/{0935-Fix-DamageSource-API.patch => 0934-Fix-DamageSource-API.patch} (100%) rename patches/server/{0936-Fix-creation-of-invalid-block-entity-during-world-ge.patch => 0935-Fix-creation-of-invalid-block-entity-during-world-ge.patch} (96%) rename patches/server/{0937-Fix-possible-StackOverflowError-for-some-dispenses.patch => 0936-Fix-possible-StackOverflowError-for-some-dispenses.patch} (100%) rename patches/server/{0938-Improve-tag-parser-handling.patch => 0937-Improve-tag-parser-handling.patch} (99%) rename patches/server/{0939-Item-Mutation-Fixes.patch => 0938-Item-Mutation-Fixes.patch} (100%) rename patches/server/{0940-Per-world-ticks-per-spawn-settings.patch => 0939-Per-world-ticks-per-spawn-settings.patch} (87%) rename patches/server/{0941-Properly-track-the-changed-item-from-dispense-events.patch => 0940-Properly-track-the-changed-item-from-dispense-events.patch} (100%) rename patches/server/{0942-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch => 0941-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch} (94%) rename patches/server/{0943-Add-config-for-mobs-immune-to-default-effects.patch => 0942-Add-config-for-mobs-immune-to-default-effects.patch} (100%) rename patches/server/{0944-Deep-clone-nbt-tags-in-PDC.patch => 0943-Deep-clone-nbt-tags-in-PDC.patch} (100%) rename patches/server/{0945-Support-old-UUID-format-for-NBT.patch => 0944-Support-old-UUID-format-for-NBT.patch} (100%) rename patches/server/{0946-Fix-shield-disable-inconsistency.patch => 0945-Fix-shield-disable-inconsistency.patch} (87%) rename patches/server/{0947-Handle-Large-Packets-disconnecting-client.patch => 0946-Handle-Large-Packets-disconnecting-client.patch} (100%) rename patches/server/{0948-Fix-ItemFlags.patch => 0947-Fix-ItemFlags.patch} (100%) rename patches/server/{0949-Fix-helmet-damage-reduction-inconsistencies.patch => 0948-Fix-helmet-damage-reduction-inconsistencies.patch} (100%) rename patches/server/{0950-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch => 0949-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch} (88%) rename patches/server/{0951-improve-checking-handled-tags-in-itemmeta.patch => 0950-improve-checking-handled-tags-in-itemmeta.patch} (100%) rename patches/server/{0952-Expose-hasColor-to-leather-armor.patch => 0951-Expose-hasColor-to-leather-armor.patch} (100%) rename patches/server/{0953-Added-API-to-get-player-ha-proxy-address.patch => 0952-Added-API-to-get-player-ha-proxy-address.patch} (100%) rename patches/server/{0954-General-ItemMeta-fixes.patch => 0953-General-ItemMeta-fixes.patch} (99%) rename patches/server/{0955-More-Chest-Block-API.patch => 0954-More-Chest-Block-API.patch} (100%) rename patches/server/{0956-Print-data-component-type-on-encoding-error.patch => 0955-Print-data-component-type-on-encoding-error.patch} (100%) rename patches/server/{0957-Brigadier-based-command-API.patch => 0956-Brigadier-based-command-API.patch} (98%) rename patches/server/{0958-Fix-issues-with-Recipe-API.patch => 0957-Fix-issues-with-Recipe-API.patch} (100%) rename patches/server/{0959-Fix-equipment-slot-and-group-API.patch => 0958-Fix-equipment-slot-and-group-API.patch} (100%) rename patches/server/{0960-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch => 0959-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch} (100%) rename patches/server/{0961-Prevent-sending-oversized-item-data-in-equipment-and.patch => 0960-Prevent-sending-oversized-item-data-in-equipment-and.patch} (98%) rename patches/server/{0962-Prevent-NPE-if-hooked-entity-was-cleared.patch => 0961-Prevent-NPE-if-hooked-entity-was-cleared.patch} (100%) rename patches/server/{0963-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch => 0962-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch} (94%) rename patches/server/{0964-Add-missing-fishing-event-state.patch => 0963-Add-missing-fishing-event-state.patch} (100%) rename patches/server/{0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch => 0964-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch} (100%) rename patches/server/{0966-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch => 0965-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch} (100%) rename patches/server/{0967-Adopt-MaterialRerouting.patch => 0966-Adopt-MaterialRerouting.patch} (100%) rename patches/server/{0968-Suspicious-Effect-Entry-API.patch => 0967-Suspicious-Effect-Entry-API.patch} (100%) rename patches/server/{0969-check-if-itemstack-is-stackable-first.patch => 0968-check-if-itemstack-is-stackable-first.patch} (100%) rename patches/server/{0970-Fix-removing-recipes-from-RecipeIterator.patch => 0969-Fix-removing-recipes-from-RecipeIterator.patch} (100%) rename patches/server/{0971-Configurable-damage-tick-when-blocking-with-shield.patch => 0970-Configurable-damage-tick-when-blocking-with-shield.patch} (88%) rename patches/server/{0972-Properly-remove-the-experimental-smithing-inventory-.patch => 0971-Properly-remove-the-experimental-smithing-inventory-.patch} (100%) rename patches/server/{0973-disable-forced-empty-world-ticks.patch => 0972-disable-forced-empty-world-ticks.patch} (87%) rename patches/server/{0974-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch => 0973-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch} (96%) rename patches/server/{0975-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch => 0974-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch} (97%) rename patches/server/{0976-Optimize-Network-Manager-and-add-advanced-packet-sup.patch => 0975-Optimize-Network-Manager-and-add-advanced-packet-sup.patch} (100%) rename patches/server/{0977-Allow-Saving-of-Oversized-Chunks.patch => 0976-Allow-Saving-of-Oversized-Chunks.patch} (100%) rename patches/server/{0978-Flat-bedrock-generator-settings.patch => 0977-Flat-bedrock-generator-settings.patch} (100%) rename patches/server/{0979-Entity-Activation-Range-2.0.patch => 0978-Entity-Activation-Range-2.0.patch} (93%) rename patches/server/{0980-Anti-Xray.patch => 0979-Anti-Xray.patch} (98%) rename patches/server/{0981-Use-Velocity-compression-and-cipher-natives.patch => 0980-Use-Velocity-compression-and-cipher-natives.patch} (100%) rename patches/server/{0982-Optimize-Collision-to-not-load-chunks.patch => 0981-Optimize-Collision-to-not-load-chunks.patch} (97%) rename patches/server/{0983-Optimize-GoalSelector-Goal.Flag-Set-operations.patch => 0982-Optimize-GoalSelector-Goal.Flag-Set-operations.patch} (100%) rename patches/server/{0984-Optimize-Hoppers.patch => 0983-Optimize-Hoppers.patch} (98%) rename patches/server/{0985-Optimize-Voxel-Shape-Merging.patch => 0984-Optimize-Voxel-Shape-Merging.patch} (100%) rename patches/server/{0986-Optimize-Bit-Operations-by-inlining.patch => 0985-Optimize-Bit-Operations-by-inlining.patch} (100%) rename patches/server/{0987-Remove-streams-from-hot-code.patch => 0986-Remove-streams-from-hot-code.patch} (100%) rename patches/server/{0988-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch => 0987-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch} (100%) rename patches/server/{0989-Fix-entity-type-tags-suggestions-in-selectors.patch => 0988-Fix-entity-type-tags-suggestions-in-selectors.patch} (100%) rename patches/server/{0990-Handle-Oversized-block-entities-in-chunks.patch => 0989-Handle-Oversized-block-entities-in-chunks.patch} (100%) rename patches/server/{0991-Check-distance-in-entity-interactions.patch => 0990-Check-distance-in-entity-interactions.patch} (93%) rename patches/server/{0992-Configurable-Sand-Duping.patch => 0991-Configurable-Sand-Duping.patch} (100%) rename patches/server/{0993-Properly-resend-entities.patch => 0992-Properly-resend-entities.patch} (97%) rename patches/server/{0994-Registry-Modification-API.patch => 0993-Registry-Modification-API.patch} (99%) rename patches/server/{0995-Add-registry-entry-and-builders.patch => 0994-Add-registry-entry-and-builders.patch} (100%) rename patches/server/{0996-Proxy-ItemStack-to-CraftItemStack.patch => 0995-Proxy-ItemStack-to-CraftItemStack.patch} (98%) rename patches/server/{0997-Make-a-PDC-view-accessible-directly-from-ItemStack.patch => 0996-Make-a-PDC-view-accessible-directly-from-ItemStack.patch} (100%) rename patches/server/{0998-Prioritize-Minecraft-commands-in-function-parsing-an.patch => 0997-Prioritize-Minecraft-commands-in-function-parsing-an.patch} (100%) rename patches/server/{0999-optimize-dirt-and-snow-spreading.patch => 0998-optimize-dirt-and-snow-spreading.patch} (100%) rename patches/server/{1000-Fix-NPE-for-Jukebox-setRecord.patch => 0999-Fix-NPE-for-Jukebox-setRecord.patch} (100%) rename patches/server/{1001-fix-horse-inventories.patch => 1000-fix-horse-inventories.patch} (100%) rename patches/server/{1002-Only-call-EntityDamageEvents-before-actuallyHurt.patch => 1001-Only-call-EntityDamageEvents-before-actuallyHurt.patch} (91%) rename patches/server/{1003-Add-ItemType-getItemRarity.patch => 1002-Add-ItemType-getItemRarity.patch} (100%) rename patches/server/{1004-Add-plugin-info-at-startup.patch => 1003-Add-plugin-info-at-startup.patch} (100%) rename patches/server/{1005-Make-interaction-leniency-distance-configurable.patch => 1004-Make-interaction-leniency-distance-configurable.patch} (100%) rename patches/server/{1006-Fix-PickupStatus-getting-reset.patch => 1005-Fix-PickupStatus-getting-reset.patch} (100%) rename patches/server/{1007-Check-for-block-type-in-SculkSensorBlock-canActivate.patch => 1006-Check-for-block-type-in-SculkSensorBlock-canActivate.patch} (100%) rename patches/server/{1008-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch => 1007-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch} (100%) rename patches/server/{1009-Configuration-for-horizontal-only-item-merging.patch => 1008-Configuration-for-horizontal-only-item-merging.patch} (100%) rename patches/server/{1010-Add-skipping-world-symlink-scan.patch => 1009-Add-skipping-world-symlink-scan.patch} (100%) rename patches/server/{1011-Add-even-more-Enchantment-API.patch => 1010-Add-even-more-Enchantment-API.patch} (100%) rename patches/server/{1012-Leashable-API.patch => 1011-Leashable-API.patch} (100%) rename patches/server/{1013-Fix-CraftBukkit-drag-system.patch => 1012-Fix-CraftBukkit-drag-system.patch} (100%) rename patches/server/{1014-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch => 1013-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch} (100%) rename patches/server/{1015-Remove-set-damage-lootable-item-function-from-compas.patch => 1014-Remove-set-damage-lootable-item-function-from-compas.patch} (100%) rename patches/server/{1016-Add-enchantment-seed-update-API.patch => 1015-Add-enchantment-seed-update-API.patch} (100%) rename patches/server/{1017-Fix-synchronise-sending-chat-to-client-with-updating.patch => 1016-Fix-synchronise-sending-chat-to-client-with-updating.patch} (100%) rename patches/server/{1018-Fix-InventoryOpenEvent-cancellation.patch => 1017-Fix-InventoryOpenEvent-cancellation.patch} (100%) rename patches/server/{1019-Fire-BlockExpEvent-on-grindstone-use.patch => 1018-Fire-BlockExpEvent-on-grindstone-use.patch} (100%) rename patches/server/{1020-Check-dead-flag-in-isAlive.patch => 1019-Check-dead-flag-in-isAlive.patch} (90%) rename patches/server/{1021-Add-FeatureFlag-API.patch => 1020-Add-FeatureFlag-API.patch} (99%) rename patches/server/{1022-Tag-Lifecycle-Events.patch => 1021-Tag-Lifecycle-Events.patch} (99%) rename patches/server/{1023-Item-serialization-as-json.patch => 1022-Item-serialization-as-json.patch} (96%) rename patches/server/{1024-Validate-slot-in-PlayerInventory-setSlot.patch => 1023-Validate-slot-in-PlayerInventory-setSlot.patch} (100%) rename patches/server/{1025-Remove-wall-time-unused-skip-tick-protection.patch => 1024-Remove-wall-time-unused-skip-tick-protection.patch} (100%) rename patches/server/{1026-Disable-pretty-printing-for-advancement-saving.patch => 1025-Disable-pretty-printing-for-advancement-saving.patch} (100%) rename patches/server/{1027-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch => 1026-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch} (100%) rename patches/server/{1028-Add-enchantWithLevels-with-enchantment-registry-set.patch => 1027-Add-enchantWithLevels-with-enchantment-registry-set.patch} (100%) rename patches/server/{1029-Improve-entity-effect-API.patch => 1028-Improve-entity-effect-API.patch} (100%) rename patches/server/{1030-Add-recipeBrewTime.patch => 1029-Add-recipeBrewTime.patch} (100%) rename patches/server/{1031-Call-bucket-events-for-cauldrons.patch => 1030-Call-bucket-events-for-cauldrons.patch} (100%) rename patches/server/{1032-Add-PlayerInsertLecternBookEvent.patch => 1031-Add-PlayerInsertLecternBookEvent.patch} (100%) rename patches/server/{1033-Void-damage-configuration-API.patch => 1032-Void-damage-configuration-API.patch} (96%) rename patches/server/{1034-Add-Offline-PDC-API.patch => 1033-Add-Offline-PDC-API.patch} (100%) rename patches/server/{1035-Add-AnvilView-bypassEnchantmentLevelRestriction.patch => 1034-Add-AnvilView-bypassEnchantmentLevelRestriction.patch} (100%) rename patches/server/{1036-Add-proper-async-player-disconnections.patch => 1035-Add-proper-async-player-disconnections.patch} (100%) rename patches/server/{1037-Always-send-Banner-patterns-to-the-client.patch => 1036-Always-send-Banner-patterns-to-the-client.patch} (100%) rename patches/server/{1038-Rewrite-dataconverter-system.patch => 1037-Rewrite-dataconverter-system.patch} (99%) rename patches/server/{1039-Moonrise-optimisation-patches.patch => 1038-Moonrise-optimisation-patches.patch} (99%) rename patches/server/{1040-API-for-checking-sent-chunks.patch => 1039-API-for-checking-sent-chunks.patch} (100%) rename patches/server/{1041-Fix-CraftWorld-isChunkGenerated.patch => 1040-Fix-CraftWorld-isChunkGenerated.patch} (100%) rename patches/server/{1042-Add-startup-flag-to-disable-gamerule-limits.patch => 1041-Add-startup-flag-to-disable-gamerule-limits.patch} (100%) rename patches/server/{1043-Improved-Watchdog-Support.patch => 1042-Improved-Watchdog-Support.patch} (94%) rename patches/server/{1044-Detail-more-information-in-watchdog-dumps.patch => 1043-Detail-more-information-in-watchdog-dumps.patch} (95%) rename patches/server/{1045-Entity-load-save-limit-per-chunk.patch => 1044-Entity-load-save-limit-per-chunk.patch} (97%) rename patches/server/{1046-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch => 1045-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch} (100%) rename patches/server/{1047-Bundle-spark.patch => 1046-Bundle-spark.patch} (94%) rename patches/server/{1048-Improve-performance-of-mass-crafts.patch => 1047-Improve-performance-of-mass-crafts.patch} (100%) rename patches/server/{1049-Incremental-chunk-and-player-saving.patch => 1048-Incremental-chunk-and-player-saving.patch} (74%) rename patches/server/{1050-Optimise-general-POI-access.patch => 1049-Optimise-general-POI-access.patch} (100%) rename patches/server/{1051-Fix-entity-tracker-desync-when-new-players-are-added.patch => 1050-Fix-entity-tracker-desync-when-new-players-are-added.patch} (97%) rename patches/server/{1052-Lag-compensation-ticks.patch => 1051-Lag-compensation-ticks.patch} (89%) rename patches/server/{1053-Optimise-collision-checking-in-player-move-packet-ha.patch => 1052-Optimise-collision-checking-in-player-move-packet-ha.patch} (100%) rename patches/server/{1054-Optional-per-player-mob-spawns.patch => 1053-Optional-per-player-mob-spawns.patch} (93%) rename patches/server/{1055-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch => 1054-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch} (92%) diff --git a/patches/api/0011-Timings-v2.patch b/patches/api/0011-Timings-v2.patch index 36aae5482290..a484a8afd2be 100644 --- a/patches/api/0011-Timings-v2.patch +++ b/patches/api/0011-Timings-v2.patch @@ -8,7 +8,7 @@ expose isRunning diff --git a/src/main/java/co/aikar/timings/FullServerTickHandler.java b/src/main/java/co/aikar/timings/FullServerTickHandler.java new file mode 100644 -index 0000000000000000000000000000000000000000..3e747abde6fefae90f1c15cb00158bc5303cbe50 +index 0000000000000000000000000000000000000000..73b125979e2f2dfd13cbf689a90b29cc68a36e09 --- /dev/null +++ b/src/main/java/co/aikar/timings/FullServerTickHandler.java @@ -0,0 +1,89 @@ @@ -94,7 +94,7 @@ index 0000000000000000000000000000000000000000..3e747abde6fefae90f1c15cb00158bc5 + TimingsManager.HISTORY.add(new TimingHistory()); + TimingsManager.resetTimings(); + } -+ Bukkit.getUnsafe().reportTimings(); ++ //Bukkit.getUnsafe().reportTimings(); + } + + boolean isViolated() { @@ -1275,10 +1275,10 @@ index 0000000000000000000000000000000000000000..df142a89b8c43acb81eb383eac0ef048 +} diff --git a/src/main/java/co/aikar/timings/Timings.java b/src/main/java/co/aikar/timings/Timings.java new file mode 100644 -index 0000000000000000000000000000000000000000..e81d0bc309de877ed2b5da6122f55c162e9b5f10 +index 0000000000000000000000000000000000000000..95b7cdf0677ef71e6885fa78aa5c75bb500f5f53 --- /dev/null +++ b/src/main/java/co/aikar/timings/Timings.java -@@ -0,0 +1,331 @@ +@@ -0,0 +1,325 @@ +/* + * This file is licensed under the MIT License (MIT). + * @@ -1426,14 +1426,8 @@ index 0000000000000000000000000000000000000000..e81d0bc309de877ed2b5da6122f55c16 + * @param enabled Should timings be reported + */ + public static void setTimingsEnabled(boolean enabled) { -+ timingsEnabled = enabled; -+ warnAboutDeprecationOnEnable(); -+ reset(); -+ } -+ -+ private static void warnAboutDeprecationOnEnable() { -+ if (timingsEnabled && !warnedAboutDeprecationOnEnable) { -+ Bukkit.getLogger().warning(PlainTextComponentSerializer.plainText().serialize(deprecationMessage())); ++ if (enabled && !warnedAboutDeprecationOnEnable) { ++ Bukkit.getLogger().severe(PlainTextComponentSerializer.plainText().serialize(deprecationMessage())); + warnedAboutDeprecationOnEnable = true; + } + } @@ -1441,7 +1435,7 @@ index 0000000000000000000000000000000000000000..e81d0bc309de877ed2b5da6122f55c16 + public static Component deprecationMessage() { + return Component.text() + .color(TextColor.color(0xffc93a)) -+ .append(Component.text("[!] The timings profiler has been enabled but has been scheduled for removal from Paper in the future.")) ++ .append(Component.text("[!] The timings profiler is in no-op mode and will be fully removed in a later update.")) + .append(Component.newline()) + .append(Component.text(" We recommend migrating to the spark profiler.")) + .append(Component.newline()) @@ -1612,10 +1606,10 @@ index 0000000000000000000000000000000000000000..e81d0bc309de877ed2b5da6122f55c16 + diff --git a/src/main/java/co/aikar/timings/TimingsCommand.java b/src/main/java/co/aikar/timings/TimingsCommand.java new file mode 100644 -index 0000000000000000000000000000000000000000..95d87c9dbf2b237787294dfbe7fed87a36e6dedf +index 0000000000000000000000000000000000000000..b83e5ff7ada8771fdf27ba9807c77ba6a4ce12da --- /dev/null +++ b/src/main/java/co/aikar/timings/TimingsCommand.java -@@ -0,0 +1,126 @@ +@@ -0,0 +1,127 @@ +/* + * This file is licensed under the MIT License (MIT). + * @@ -1674,8 +1668,9 @@ index 0000000000000000000000000000000000000000..95d87c9dbf2b237787294dfbe7fed87a + if (!testPermission(sender)) { + return true; + } -+ if (false) { ++ if (true) { + sender.sendMessage(Timings.deprecationMessage()); ++ return true; + } + if (args.length < 1) { + sender.sendMessage(text("Usage: " + this.usageMessage, NamedTextColor.RED)); @@ -2906,35 +2901,6 @@ index fa6ad07214d5e38866bf6bee9139c6c938e9f51a..57c9b560c77a56588870598acb543469 /** * Sends the component to the player * -diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index d8b346fe0f9634218954fe818d53272a0896af9c..12ef99f1c91b92a133611c5f5aeaaeebd02ce232 100644 ---- a/src/main/java/org/bukkit/UnsafeValues.java -+++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -40,6 +40,11 @@ public interface UnsafeValues { - net.kyori.adventure.text.Component resolveWithContext(net.kyori.adventure.text.Component component, org.bukkit.command.CommandSender context, org.bukkit.entity.Entity scoreboardSubject, boolean bypassPermissions) throws java.io.IOException; - // Paper end - -+ /** -+ * @deprecated Timings will be removed in the future -+ */ -+ @Deprecated(forRemoval = true) -+ void reportTimings(); // Paper - Material toLegacy(Material material); - - Material fromLegacy(Material material); -@@ -151,4 +156,12 @@ public interface UnsafeValues { - return !Bukkit.getUnsafe().isSupportedApiVersion(plugin.getDescription().getAPIVersion()); - } - // Paper end -+ -+ // Paper start -+ /** -+ * @deprecated Timings will be removed in the future -+ */ -+ @Deprecated(forRemoval = true) -+ String getTimingsServerName(); -+ // Paper end - } diff --git a/src/main/java/org/bukkit/command/BufferedCommandSender.java b/src/main/java/org/bukkit/command/BufferedCommandSender.java new file mode 100644 index 0000000000000000000000000000000000000000..45ed63797b13e114bf3795c80a6c3967d8eb2351 @@ -3508,7 +3474,7 @@ index 84befa1e5123038b80e0734622a5174634f5a982..22de066aef71ad2cf135d5b6f5d6f224 @NotNull diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java -index 46c7be5fa69f13900860b9944523beea16f2409b..6018574cd15b802833613beefa88da15dc2730cb 100644 +index 46c7be5fa69f13900860b9944523beea16f2409b..f97669c8b58bc287fc289eeb098836ae314b053a 100644 --- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -381,7 +381,6 @@ public final class SimplePluginManager implements PluginManager { @@ -3559,9 +3525,11 @@ index 46c7be5fa69f13900860b9944523beea16f2409b..6018574cd15b802833613beefa88da15 } /** -@@ -933,7 +933,7 @@ public final class SimplePluginManager implements PluginManager { +@@ -932,8 +932,9 @@ public final class SimplePluginManager implements PluginManager { + * * @param use True if per event timing code should be used */ ++ @Deprecated(forRemoval = true) public void useTimings(boolean use) { - useTimings = use; + co.aikar.timings.Timings.setTimingsEnabled(use); // Paper diff --git a/patches/api/0012-Add-command-line-option-to-load-extra-plugin-jars-no.patch b/patches/api/0012-Add-command-line-option-to-load-extra-plugin-jars-no.patch index c73bf65b9727..1faeb9019097 100644 --- a/patches/api/0012-Add-command-line-option-to-load-extra-plugin-jars-no.patch +++ b/patches/api/0012-Add-command-line-option-to-load-extra-plugin-jars-no.patch @@ -55,7 +55,7 @@ index 57c9b560c77a56588870598acb543469040ceec1..8949b8e29ae7f412481291630a5cb7b5 * Used for all administrative messages, such as an operator using a * command. diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java -index 6018574cd15b802833613beefa88da15dc2730cb..e7b1895d3918487d711afcbe41d76863d85c0a62 100644 +index f97669c8b58bc287fc289eeb098836ae314b053a..2c77b6ab388bd689acb8d84ec62bd5df1eb9373e 100644 --- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -117,9 +117,22 @@ public final class SimplePluginManager implements PluginManager { diff --git a/patches/api/0015-Expose-server-build-information.patch b/patches/api/0015-Expose-server-build-information.patch index f1bf77caf847..2853b4562644 100644 --- a/patches/api/0015-Expose-server-build-information.patch +++ b/patches/api/0015-Expose-server-build-information.patch @@ -316,21 +316,22 @@ index ba28d9f3213ca4b5f15178dc637bff37a8896edc..8a07f21eeb04fb54032ce377a1478f60 * Gets a view of all currently logged in players. This {@linkplain * Collections#unmodifiableCollection(Collection) view} is a reused diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 12ef99f1c91b92a133611c5f5aeaaeebd02ce232..6e67fdb091a006d2d13bc2d93db4d55348af4c8f 100644 +index d8b346fe0f9634218954fe818d53272a0896af9c..45ed0007d6de20b98794b3ccaef57aed213e72d4 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -163,5 +163,12 @@ public interface UnsafeValues { - */ - @Deprecated(forRemoval = true) - String getTimingsServerName(); +@@ -151,4 +151,13 @@ public interface UnsafeValues { + return !Bukkit.getUnsafe().isSupportedApiVersion(plugin.getDescription().getAPIVersion()); + } + // Paper end + ++ // Paper start + /** + * Called once by the version command on first use, then cached. + */ + default com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { + return new com.destroystokyo.paper.util.VersionFetcher.DummyVersionFetcher(); + } - // Paper end ++ // Paper end } diff --git a/src/main/java/org/bukkit/command/defaults/VersionCommand.java b/src/main/java/org/bukkit/command/defaults/VersionCommand.java index 263208d3cba36cb80c9ee4e3022ef702ea113df2..e64bb57f74e6d6f78927be228825b3e0bdf41f48 100644 diff --git a/patches/api/0021-Add-exception-reporting-event.patch b/patches/api/0021-Add-exception-reporting-event.patch index adf50a8c29ac..c592c2b2ee3c 100644 --- a/patches/api/0021-Add-exception-reporting-event.patch +++ b/patches/api/0021-Add-exception-reporting-event.patch @@ -494,7 +494,7 @@ index 36fc2c35395c72f8b81a2a2f3265fd205384ce26..c7fa1d235cea78bda4656ed66b8d42b1 } diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java -index e7b1895d3918487d711afcbe41d76863d85c0a62..003bece642b682985625db93cad93026352bfc66 100644 +index 2c77b6ab388bd689acb8d84ec62bd5df1eb9373e..b878e7167cfcdea0e224c182b40abeadd339d3b3 100644 --- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -528,7 +528,8 @@ public final class SimplePluginManager implements PluginManager { diff --git a/patches/api/0182-Add-Raw-Byte-ItemStack-Serialization.patch b/patches/api/0182-Add-Raw-Byte-ItemStack-Serialization.patch index bfdff2a3f4af..b852c64ded54 100644 --- a/patches/api/0182-Add-Raw-Byte-ItemStack-Serialization.patch +++ b/patches/api/0182-Add-Raw-Byte-ItemStack-Serialization.patch @@ -8,10 +8,10 @@ Serializes using NBT which is safer for server data migrations than bukkits form Co-authored-by: Nassim Jahnke diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 6e67fdb091a006d2d13bc2d93db4d55348af4c8f..e41d5d9b810c8816cd0d1eba5fd1ea56252fb0df 100644 +index 45ed0007d6de20b98794b3ccaef57aed213e72d4..dd81e309c584e37e4bc7644261ecc649e1237570 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -170,5 +170,9 @@ public interface UnsafeValues { +@@ -159,5 +159,9 @@ public interface UnsafeValues { default com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { return new com.destroystokyo.paper.util.VersionFetcher.DummyVersionFetcher(); } diff --git a/patches/api/0205-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch b/patches/api/0205-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch index c5e6d200ab88..241d581e0cd4 100644 --- a/patches/api/0205-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch +++ b/patches/api/0205-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Expose the Entity Counter to allow plugins to use valid and diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index e41d5d9b810c8816cd0d1eba5fd1ea56252fb0df..64be4e60a03cb7cdc21013837d241d288695b69d 100644 +index dd81e309c584e37e4bc7644261ecc649e1237570..db48f30704efa6928599a5cebf5ce577c8430198 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -174,5 +174,12 @@ public interface UnsafeValues { +@@ -163,5 +163,12 @@ public interface UnsafeValues { byte[] serializeItem(ItemStack item); ItemStack deserializeItem(byte[] data); diff --git a/patches/api/0253-Expand-world-key-API.patch b/patches/api/0253-Expand-world-key-API.patch index 2436c924af19..2716158a70bf 100644 --- a/patches/api/0253-Expand-world-key-API.patch +++ b/patches/api/0253-Expand-world-key-API.patch @@ -100,10 +100,10 @@ index 943f8881ea23481ea5d5125b6ec7c9c6f763f0b0..42930006b6425b5d82233e4ffe7025ce * Create a new virtual {@link WorldBorder}. *

    diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 64be4e60a03cb7cdc21013837d241d288695b69d..0231b79d96d535e0ae37296b3e806844740783ca 100644 +index db48f30704efa6928599a5cebf5ce577c8430198..4229db3c6abb693803a4bdd5a71e426c688f26cc 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -181,5 +181,10 @@ public interface UnsafeValues { +@@ -170,5 +170,10 @@ public interface UnsafeValues { * Use this when sending custom packets, so that there are no collisions on the client or server. */ public int nextEntityId(); diff --git a/patches/api/0255-Expose-protocol-version.patch b/patches/api/0255-Expose-protocol-version.patch index 9ba0c40a9613..f6cace865e17 100644 --- a/patches/api/0255-Expose-protocol-version.patch +++ b/patches/api/0255-Expose-protocol-version.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Expose protocol version diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 0231b79d96d535e0ae37296b3e806844740783ca..51473ffbec65a2344449daa8ff5cf535b0b60520 100644 +index 4229db3c6abb693803a4bdd5a71e426c688f26cc..f33426207c403906c3c6fb99e848fd7ecbffd127 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -186,5 +186,12 @@ public interface UnsafeValues { +@@ -175,5 +175,12 @@ public interface UnsafeValues { * Just don't use it. */ @org.jetbrains.annotations.NotNull String getMainLevelName(); diff --git a/patches/api/0272-ItemStack-repair-check-API.patch b/patches/api/0272-ItemStack-repair-check-API.patch index 6ef26350c743..6385fdeb47ea 100644 --- a/patches/api/0272-ItemStack-repair-check-API.patch +++ b/patches/api/0272-ItemStack-repair-check-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] ItemStack repair check API diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 51473ffbec65a2344449daa8ff5cf535b0b60520..07669aad6d9910174fbc8fdf3cdd54211fbfcee3 100644 +index f33426207c403906c3c6fb99e848fd7ecbffd127..3ef6ffb506a7fdd05a08353f342e45de8066ca19 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -193,5 +193,15 @@ public interface UnsafeValues { +@@ -182,5 +182,15 @@ public interface UnsafeValues { * @return the server's protocol version */ int getProtocolVersion(); diff --git a/patches/api/0304-Get-entity-default-attributes.patch b/patches/api/0304-Get-entity-default-attributes.patch index fd13ed8d7cfb..deca580fd38d 100644 --- a/patches/api/0304-Get-entity-default-attributes.patch +++ b/patches/api/0304-Get-entity-default-attributes.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Get entity default attributes diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 07669aad6d9910174fbc8fdf3cdd54211fbfcee3..a25f7378e5cef3899c38dd34d369da0441951f24 100644 +index 3ef6ffb506a7fdd05a08353f342e45de8066ca19..b8627d845bbc8c845af364408d3b6abb57c7308b 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -203,5 +203,22 @@ public interface UnsafeValues { +@@ -192,5 +192,22 @@ public interface UnsafeValues { * @return true if valid repair, false if not */ public boolean isValidRepairItemStack(@org.jetbrains.annotations.NotNull ItemStack itemToBeRepaired, @org.jetbrains.annotations.NotNull ItemStack repairMaterial); diff --git a/patches/api/0312-Add-Raw-Byte-Entity-Serialization.patch b/patches/api/0312-Add-Raw-Byte-Entity-Serialization.patch index 790704d4e93f..abe5d9f16364 100644 --- a/patches/api/0312-Add-Raw-Byte-Entity-Serialization.patch +++ b/patches/api/0312-Add-Raw-Byte-Entity-Serialization.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Raw Byte Entity Serialization diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index a25f7378e5cef3899c38dd34d369da0441951f24..3aeac7b102f7c6e6186d168294ea73ff022f9349 100644 +index b8627d845bbc8c845af364408d3b6abb57c7308b..ef22077e2bf9709bef21e259cfa6435f80305b5e 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -175,6 +175,14 @@ public interface UnsafeValues { +@@ -164,6 +164,14 @@ public interface UnsafeValues { ItemStack deserializeItem(byte[] data); diff --git a/patches/api/0358-Add-NamespacedKey-biome-methods.patch b/patches/api/0358-Add-NamespacedKey-biome-methods.patch index adc8f6a1e21b..be2c0e7b2aa2 100644 --- a/patches/api/0358-Add-NamespacedKey-biome-methods.patch +++ b/patches/api/0358-Add-NamespacedKey-biome-methods.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add NamespacedKey biome methods Co-authored-by: Thonk <30448663+ExcessiveAmountsOfZombies@users.noreply.github.com> diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 3aeac7b102f7c6e6186d168294ea73ff022f9349..4f3e6e2698b28922e7b6448eddd5b166f4631759 100644 +index ef22077e2bf9709bef21e259cfa6435f80305b5e..14cf57a96f47ba666f05cedbc0005ff0fec6a33d 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -229,4 +229,33 @@ public interface UnsafeValues { +@@ -218,4 +218,33 @@ public interface UnsafeValues { */ @org.jetbrains.annotations.NotNull org.bukkit.attribute.Attributable getDefaultEntityAttributes(@org.jetbrains.annotations.NotNull NamespacedKey entityKey); // Paper end diff --git a/patches/api/0402-Fix-custom-statistic-criteria-creation.patch b/patches/api/0402-Fix-custom-statistic-criteria-creation.patch index 5e3f26f4f3fe..ff4bad9d3519 100644 --- a/patches/api/0402-Fix-custom-statistic-criteria-creation.patch +++ b/patches/api/0402-Fix-custom-statistic-criteria-creation.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix custom statistic criteria creation diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 4f3e6e2698b28922e7b6448eddd5b166f4631759..334e392800803816cf502c2920c4a85774d6b0b2 100644 +index 14cf57a96f47ba666f05cedbc0005ff0fec6a33d..57b51acd566f6ccabeea0b3f4c76b19547d35b5a 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -258,4 +258,6 @@ public interface UnsafeValues { +@@ -247,4 +247,6 @@ public interface UnsafeValues { */ void setBiomeKey(RegionAccessor accessor, int x, int y, int z, NamespacedKey biomeKey); // Paper end - namespaced key biome methods diff --git a/patches/api/0440-Add-api-for-spawn-egg-texture-colors.patch b/patches/api/0440-Add-api-for-spawn-egg-texture-colors.patch index 996340cf25a9..14a80bca1c12 100644 --- a/patches/api/0440-Add-api-for-spawn-egg-texture-colors.patch +++ b/patches/api/0440-Add-api-for-spawn-egg-texture-colors.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add api for spawn egg texture colors diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 334e392800803816cf502c2920c4a85774d6b0b2..27ac8e80192924eb38e5ceaee575ac418e92b410 100644 +index 57b51acd566f6ccabeea0b3f4c76b19547d35b5a..38e84d98670b45b1f855885cf07ce13f0433fa49 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -260,4 +260,17 @@ public interface UnsafeValues { +@@ -249,4 +249,17 @@ public interface UnsafeValues { // Paper end - namespaced key biome methods String getStatisticCriteriaKey(@NotNull org.bukkit.Statistic statistic); // Paper - fix custom stats criteria creation diff --git a/patches/api/0441-Add-Lifecycle-Event-system.patch b/patches/api/0441-Add-Lifecycle-Event-system.patch index 31bfe9a70f5b..2d2d639018c9 100644 --- a/patches/api/0441-Add-Lifecycle-Event-system.patch +++ b/patches/api/0441-Add-Lifecycle-Event-system.patch @@ -546,10 +546,10 @@ index 0000000000000000000000000000000000000000..f70814de0d6c40b2c1c9921b8abdd116 + } +} diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 27ac8e80192924eb38e5ceaee575ac418e92b410..141d5a964cc299284aecd4d34d57008a32f94247 100644 +index 38e84d98670b45b1f855885cf07ce13f0433fa49..81b1c024e27a7021982336b94fc1e1ba33308f6c 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -273,4 +273,12 @@ public interface UnsafeValues { +@@ -262,4 +262,12 @@ public interface UnsafeValues { */ @Nullable org.bukkit.Color getSpawnEggLayerColor(org.bukkit.entity.EntityType entityType, int layer); // Paper end - spawn egg color visibility diff --git a/patches/api/0442-ItemStack-Tooltip-API.patch b/patches/api/0442-ItemStack-Tooltip-API.patch index 4af91c3ade27..1d0644e6e126 100644 --- a/patches/api/0442-ItemStack-Tooltip-API.patch +++ b/patches/api/0442-ItemStack-Tooltip-API.patch @@ -110,10 +110,10 @@ index 0000000000000000000000000000000000000000..a649b90dfac6000c01579a48234a1138 + } +} diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 141d5a964cc299284aecd4d34d57008a32f94247..31217b38e769f97801fa1afefeb223d1c755cabd 100644 +index 81b1c024e27a7021982336b94fc1e1ba33308f6c..e5144471056e69586c1693a9264a3995387de3cc 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -281,4 +281,6 @@ public interface UnsafeValues { +@@ -270,4 +270,6 @@ public interface UnsafeValues { @org.jetbrains.annotations.ApiStatus.Internal io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager createPluginLifecycleEventManager(final org.bukkit.plugin.java.JavaPlugin plugin, final java.util.function.BooleanSupplier registrationCheck); // Paper end - lifecycle event API diff --git a/patches/api/0472-Registry-Modification-API.patch b/patches/api/0472-Registry-Modification-API.patch index 6eca654483ab..b51badfa70a6 100644 --- a/patches/api/0472-Registry-Modification-API.patch +++ b/patches/api/0472-Registry-Modification-API.patch @@ -900,10 +900,10 @@ index 67cf3fcad21a8977d6fad172cc776b628ab68f25..b4ef3133fdd9d79a3381cf8f659ff561 } } diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 31217b38e769f97801fa1afefeb223d1c755cabd..9bdba60fa96edbc4be5dcf54a815579db887048b 100644 +index e5144471056e69586c1693a9264a3995387de3cc..2c365ecf3f5a5252e489bc1dc04359e766a2d739 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -283,4 +283,6 @@ public interface UnsafeValues { +@@ -272,4 +272,6 @@ public interface UnsafeValues { // Paper end - lifecycle event API @NotNull java.util.List computeTooltipLines(@NotNull ItemStack itemStack, @NotNull io.papermc.paper.inventory.tooltip.TooltipContext tooltipContext, @Nullable org.bukkit.entity.Player player); // Paper - expose itemstack tooltip lines diff --git a/patches/api/0474-Proxy-ItemStack-to-CraftItemStack.patch b/patches/api/0474-Proxy-ItemStack-to-CraftItemStack.patch index 246fa425d8f4..157b63eeb46c 100644 --- a/patches/api/0474-Proxy-ItemStack-to-CraftItemStack.patch +++ b/patches/api/0474-Proxy-ItemStack-to-CraftItemStack.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Proxy ItemStack to CraftItemStack diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 9bdba60fa96edbc4be5dcf54a815579db887048b..330e3013eda204aa9b33d5e1c3104e0b595abdbc 100644 +index 2c365ecf3f5a5252e489bc1dc04359e766a2d739..06b7af5dbae3dd1c5cb024cc875162725a0b8c37 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -285,4 +285,6 @@ public interface UnsafeValues { +@@ -274,4 +274,6 @@ public interface UnsafeValues { @NotNull java.util.List computeTooltipLines(@NotNull ItemStack itemStack, @NotNull io.papermc.paper.inventory.tooltip.TooltipContext tooltipContext, @Nullable org.bukkit.entity.Player player); // Paper - expose itemstack tooltip lines io.papermc.paper.registry.tag.@Nullable Tag getTag(io.papermc.paper.registry.tag.@NotNull TagKey tagKey); // Paper - hack to get tags for non-server backed registries diff --git a/patches/api/0485-Add-FeatureFlag-API.patch b/patches/api/0485-Add-FeatureFlag-API.patch index 9afc6440146f..26442d7b0125 100644 --- a/patches/api/0485-Add-FeatureFlag-API.patch +++ b/patches/api/0485-Add-FeatureFlag-API.patch @@ -247,10 +247,10 @@ index eb33e8e671972aa308ad75a7ce9aa9ac526f470f..05ecf3cb38ff42c8b52405d900197e6b /** * Gets the {@link Biome} at the given {@link Location}. diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 330e3013eda204aa9b33d5e1c3104e0b595abdbc..c80e0ef587a001ee6de3f5c182cc9696d58bafeb 100644 +index 06b7af5dbae3dd1c5cb024cc875162725a0b8c37..aa3916b0d8e40615a7ae142e254277744b4f024e 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -114,8 +114,7 @@ public interface UnsafeValues { +@@ -109,8 +109,7 @@ public interface UnsafeValues { String getTranslationKey(Attribute attribute); diff --git a/patches/api/0487-Item-serialization-as-json.patch b/patches/api/0487-Item-serialization-as-json.patch index d2951870a15d..c2b00d8d3de7 100644 --- a/patches/api/0487-Item-serialization-as-json.patch +++ b/patches/api/0487-Item-serialization-as-json.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Item serialization as json diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index c80e0ef587a001ee6de3f5c182cc9696d58bafeb..10c87b7c19ed3eab28fdce5f225df3767292ee0a 100644 +index aa3916b0d8e40615a7ae142e254277744b4f024e..e4084369d12390bb5c92ab58ad34ff07afea1142 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -174,6 +174,36 @@ public interface UnsafeValues { +@@ -163,6 +163,36 @@ public interface UnsafeValues { ItemStack deserializeItem(byte[] data); diff --git a/patches/server/0005-Paper-config-files.patch b/patches/server/0005-Paper-config-files.patch index 3303f32c8ae6..c4181a6029bc 100644 --- a/patches/server/0005-Paper-config-files.patch +++ b/patches/server/0005-Paper-config-files.patch @@ -487,13 +487,12 @@ index 0000000000000000000000000000000000000000..d9502ba028a96f9cc846f9ed428bd806 +} diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java new file mode 100644 -index 0000000000000000000000000000000000000000..7e88b1fc1ff700a7771b38f139f4472eaeaf8714 +index 0000000000000000000000000000000000000000..f0d470d7770e119f734b9e72021c806d0ea8ecbd --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -0,0 +1,355 @@ +@@ -0,0 +1,330 @@ +package io.papermc.paper.configuration; + -+import co.aikar.timings.MinecraftTimings; +import com.mojang.logging.LogUtils; +import io.papermc.paper.configuration.constraint.Constraints; +import io.papermc.paper.configuration.type.number.DoubleOr; @@ -510,7 +509,6 @@ index 0000000000000000000000000000000000000000..7e88b1fc1ff700a7771b38f139f4472e +import org.spongepowered.configurate.objectmapping.meta.Required; +import org.spongepowered.configurate.objectmapping.meta.Setting; + -+import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.OptionalInt; @@ -592,29 +590,6 @@ index 0000000000000000000000000000000000000000..7e88b1fc1ff700a7771b38f139f4472e + public boolean enableImmediately = false; + } + -+ @Deprecated(forRemoval = true) -+ public Timings timings; -+ -+ @Deprecated(forRemoval = true) -+ public class Timings extends ConfigurationPart { -+ public boolean enabled = false; -+ public boolean verbose = true; -+ public String url = "https://timings.aikar.co/"; -+ public boolean serverNamePrivacy = false; -+ public List hiddenConfigEntries = List.of( -+ "database", -+ "proxies.velocity.secret" -+ ); -+ public int historyInterval = 300; -+ public int historyLength = 3600; -+ public String serverName = "Unknown Server"; -+ -+ @PostProcess -+ private void postProcess() { -+ MinecraftTimings.processConfig(this); -+ } -+ } -+ + public Proxies proxies; + + public class Proxies extends ConfigurationPart { diff --git a/patches/server/0009-MC-Utils.patch b/patches/server/0009-MC-Utils.patch index b7549f7365ac..c7768b91e2b8 100644 --- a/patches/server/0009-MC-Utils.patch +++ b/patches/server/0009-MC-Utils.patch @@ -4542,10 +4542,10 @@ index 46cab7a8c7b87ab01b26074b04f5a02b3907cfc4..49019b4a9bc4e634d54a9b0acaf9229a + // Paper end } diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 7e88b1fc1ff700a7771b38f139f4472eaeaf8714..904d2f96a60e72aa089fdfe6be08044b04f995c1 100644 +index f0d470d7770e119f734b9e72021c806d0ea8ecbd..c3fe4481dd35f80815716e48beeeb07b1f51e30b 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -242,7 +242,7 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -217,7 +217,7 @@ public class GlobalConfiguration extends ConfigurationPart { @PostProcess private void postProcess() { diff --git a/patches/server/0024-Further-improve-server-tick-loop.patch b/patches/server/0023-Further-improve-server-tick-loop.patch similarity index 96% rename from patches/server/0024-Further-improve-server-tick-loop.patch rename to patches/server/0023-Further-improve-server-tick-loop.patch index 798d5e4b4dc1..87be9b027e28 100644 --- a/patches/server/0024-Further-improve-server-tick-loop.patch +++ b/patches/server/0023-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 a76e2f5d29315d21212ff121f0047bf1140ad5ef..31582d4f9d52c86cf834b9dc10e58b68c67f1272 100644 +index 3322865949fe5ddaab2dffc39260b75093f0f204..4a573e8b7cd90f65c190982662e92a11f79a1d3e 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -307,7 +307,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop -Date: Thu, 3 Mar 2016 04:00:11 -0600 -Subject: [PATCH] Timings v2 - - -diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java -new file mode 100644 -index 0000000000000000000000000000000000000000..4bd813161a5d76a83cdbd0a9209b9ea9e60ffe1b ---- /dev/null -+++ b/src/main/java/co/aikar/timings/MinecraftTimings.java -@@ -0,0 +1,169 @@ -+package co.aikar.timings; -+ -+import com.google.common.collect.MapMaker; -+import io.papermc.paper.configuration.GlobalConfiguration; -+import net.minecraft.commands.functions.CommandFunction; -+import net.minecraft.network.protocol.Packet; -+import net.minecraft.world.level.block.Block; -+import net.minecraft.world.level.block.entity.BlockEntity; -+import org.bukkit.plugin.Plugin; -+import org.bukkit.scheduler.BukkitTask; -+ -+import org.bukkit.craftbukkit.scheduler.CraftTask; -+ -+import java.util.Map; -+ -+// TODO: Re-implement missing timers -+@Deprecated(forRemoval = true) -+public final class MinecraftTimings { -+ -+ public static final Timing serverOversleep = Timings.ofSafe("Server Oversleep"); -+ public static final Timing playerListTimer = Timings.ofSafe("Player List"); -+ public static final Timing commandFunctionsTimer = Timings.ofSafe("Command Functions"); -+ public static final Timing connectionTimer = Timings.ofSafe("Connection Handler"); -+ public static final Timing tickablesTimer = Timings.ofSafe("Tickables"); -+ public static final Timing minecraftSchedulerTimer = Timings.ofSafe("Minecraft Scheduler"); -+ public static final Timing bukkitSchedulerTimer = Timings.ofSafe("Bukkit Scheduler"); -+ public static final Timing bukkitSchedulerPendingTimer = Timings.ofSafe("Bukkit Scheduler - Pending"); -+ public static final Timing bukkitSchedulerFinishTimer = Timings.ofSafe("Bukkit Scheduler - Finishing"); -+ public static final Timing chunkIOTickTimer = Timings.ofSafe("ChunkIOTick"); -+ public static final Timing timeUpdateTimer = Timings.ofSafe("Time Update"); -+ public static final Timing serverCommandTimer = Timings.ofSafe("Server Command"); -+ public static final Timing savePlayers = Timings.ofSafe("Save Players"); -+ -+ public static final Timing tickEntityTimer = Timings.ofSafe("## tickEntity"); -+ public static final Timing tickTileEntityTimer = Timings.ofSafe("## tickTileEntity"); -+ public static final Timing packetProcessTimer = Timings.ofSafe("## Packet Processing"); -+ public static final Timing scheduledBlocksTimer = Timings.ofSafe("## Scheduled Blocks"); -+ public static final Timing structureGenerationTimer = Timings.ofSafe("Structure Generation"); -+ -+ public static final Timing processQueueTimer = Timings.ofSafe("processQueue"); -+ public static final Timing processTasksTimer = Timings.ofSafe("processTasks"); -+ -+ public static final Timing playerCommandTimer = Timings.ofSafe("playerCommand"); -+ -+ public static final Timing entityActivationCheckTimer = Timings.ofSafe("entityActivationCheck"); -+ -+ public static final Timing antiXrayUpdateTimer = Timings.ofSafe("anti-xray - update"); -+ public static final Timing antiXrayObfuscateTimer = Timings.ofSafe("anti-xray - obfuscate"); -+ -+ private static final Map, String> taskNameCache = new MapMaker().weakKeys().makeMap(); -+ -+ private MinecraftTimings() {} -+ -+ public static Timing getInternalTaskName(String taskName) { -+ return Timings.ofSafe(taskName); -+ } -+ -+ /** -+ * Gets a timer associated with a plugins tasks. -+ * @param bukkitTask -+ * @param period -+ * @return -+ */ -+ public static Timing getPluginTaskTimings(BukkitTask bukkitTask, long period) { -+ if (!bukkitTask.isSync()) { -+ return NullTimingHandler.NULL; -+ } -+ Plugin plugin; -+ -+ CraftTask craftTask = (CraftTask) bukkitTask; -+ -+ final Class taskClass = craftTask.getTaskClass(); -+ if (bukkitTask.getOwner() != null) { -+ plugin = bukkitTask.getOwner(); -+ } else { -+ plugin = TimingsManager.getPluginByClassloader(taskClass); -+ } -+ -+ final String taskname = taskNameCache.computeIfAbsent(taskClass, clazz -> { -+ try { -+ String clsName = !clazz.isMemberClass() -+ ? clazz.getName() -+ : clazz.getCanonicalName(); -+ if (clsName != null && clsName.contains("$Lambda$")) { -+ clsName = clsName.replaceAll("(Lambda\\$.*?)/.*", "$1"); -+ } -+ return clsName != null ? clsName : "UnknownTask"; -+ } catch (Throwable ex) { -+ new Exception("Error occurred detecting class name", ex).printStackTrace(); -+ return "MangledClassFile"; -+ } -+ }); -+ -+ StringBuilder name = new StringBuilder(64); -+ name.append("Task: ").append(taskname); -+ if (period > 0) { -+ name.append(" (interval:").append(period).append(")"); -+ } else { -+ name.append(" (Single)"); -+ } -+ -+ if (plugin == null) { -+ return Timings.ofSafe(null, name.toString()); -+ } -+ -+ return Timings.ofSafe(plugin, name.toString()); -+ } -+ -+ /** -+ * Get a named timer for the specified entity type to track type specific timings. -+ * @param entityType -+ * @return -+ */ -+ public static Timing getEntityTimings(String entityType, String type) { -+ return Timings.ofSafe("Minecraft", "## tickEntity - " + entityType + " - " + type, tickEntityTimer); -+ } -+ -+ /** -+ * Get a named timer for the specified tile entity type to track type specific timings. -+ * @param entity -+ * @return -+ */ -+ public static Timing getTileEntityTimings(BlockEntity entity) { -+ String entityType = entity.getClass().getName(); -+ return Timings.ofSafe("Minecraft", "## tickTileEntity - " + entityType, tickTileEntityTimer); -+ } -+ public static Timing getCancelTasksTimer() { -+ return Timings.ofSafe("Cancel Tasks"); -+ } -+ public static Timing getCancelTasksTimer(Plugin plugin) { -+ return Timings.ofSafe(plugin, "Cancel Tasks"); -+ } -+ -+ public static void stopServer() { -+ TimingsManager.stopServer(); -+ } -+ -+ public static Timing getBlockTiming(Block block) { -+ return Timings.ofSafe("## Scheduled Block: " + block.toString(), scheduledBlocksTimer); -+ } -+/* -+ public static Timing getStructureTiming(StructureGenerator structureGenerator) { -+ return Timings.ofSafe("Structure Generator - " + structureGenerator.getName(), structureGenerationTimer); -+ }*/ -+ -+ public static Timing getPacketTiming(Packet packet) { -+ return Timings.ofSafe("## Packet - " + packet.getClass().getName(), packetProcessTimer); -+ } -+ -+ public static Timing getCommandFunctionTiming(CommandFunction function) { -+ return Timings.ofSafe("Command Function - " + function.id()); -+ } -+ -+ public static void processConfig(GlobalConfiguration.Timings config) { -+ TimingsManager.url = config.url; -+ if (!TimingsManager.url.endsWith("/")) { -+ TimingsManager.url += "/"; -+ } -+ TimingsManager.privacy = config.serverNamePrivacy; -+ if (!config.hiddenConfigEntries.contains("proxies.velocity.secret")) { -+ config.hiddenConfigEntries.add("proxies.velocity.secret"); -+ } -+ TimingsManager.hiddenConfigs.addAll(config.hiddenConfigEntries); -+ co.aikar.timings.Timings.setVerboseTimingsEnabled(config.verbose); -+ co.aikar.timings.Timings.setTimingsEnabled(config.enabled); -+ co.aikar.timings.Timings.setHistoryInterval(config.historyInterval * 20); -+ co.aikar.timings.Timings.setHistoryLength(config.historyLength * 20); -+ } -+} -diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java -new file mode 100644 -index 0000000000000000000000000000000000000000..49028463ba47e760281545c2f7597e3db8d6c453 ---- /dev/null -+++ b/src/main/java/co/aikar/timings/TimingsExport.java -@@ -0,0 +1,388 @@ -+/* -+ * This file is licensed under the MIT License (MIT). -+ * -+ * Copyright (c) 2014 Daniel Ennis -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a copy -+ * of this software and associated documentation files (the "Software"), to deal -+ * in the Software without restriction, including without limitation the rights -+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+ * copies of the Software, and to permit persons to whom the Software is -+ * furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -+ * THE SOFTWARE. -+ */ -+package co.aikar.timings; -+ -+import com.google.common.collect.Sets; -+import io.papermc.paper.adventure.PaperAdventure; -+import net.kyori.adventure.text.event.ClickEvent; -+import net.kyori.adventure.text.format.NamedTextColor; -+import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; -+import net.minecraft.server.MinecraftServer; -+import org.apache.commons.lang.StringUtils; -+import org.bukkit.Bukkit; -+import org.bukkit.Material; -+import org.bukkit.configuration.ConfigurationSection; -+import org.bukkit.configuration.MemorySection; -+import org.bukkit.entity.EntityType; -+import org.json.simple.JSONObject; -+import org.json.simple.JSONValue; -+import oshi.SystemInfo; -+import oshi.hardware.HardwareAbstractionLayer; -+ -+import java.io.ByteArrayOutputStream; -+import java.io.IOException; -+import java.io.InputStream; -+import java.io.OutputStream; -+import java.lang.management.ManagementFactory; -+import java.lang.management.OperatingSystemMXBean; -+import java.lang.management.RuntimeMXBean; -+import java.net.HttpURLConnection; -+import java.net.InetAddress; -+import java.net.URL; -+import java.util.List; -+import java.util.Map; -+import java.util.Set; -+import java.util.logging.Level; -+import java.util.zip.GZIPOutputStream; -+ -+import static co.aikar.timings.TimingsManager.HISTORY; -+import static co.aikar.util.JSONUtil.appendObjectData; -+import static co.aikar.util.JSONUtil.createObject; -+import static co.aikar.util.JSONUtil.pair; -+import static co.aikar.util.JSONUtil.toArray; -+import static co.aikar.util.JSONUtil.toArrayMapper; -+import static co.aikar.util.JSONUtil.toObjectMapper; -+import static net.kyori.adventure.text.Component.text; -+ -+@SuppressWarnings({"rawtypes", "SuppressionAnnotation"}) -+@Deprecated(forRemoval = true) -+public class TimingsExport extends Thread { -+ -+ private final TimingsReportListener listeners; -+ private final Map out; -+ private final TimingHistory[] history; -+ private static long lastReport = 0; -+ -+ private TimingsExport(TimingsReportListener listeners, Map out, TimingHistory[] history) { -+ super("Timings paste thread"); -+ this.listeners = listeners; -+ this.out = out; -+ this.history = history; -+ } -+ -+ /** -+ * Checks if any pending reports are being requested, and builds one if needed. -+ */ -+ public static void reportTimings() { -+ if (Timings.requestingReport.isEmpty()) { -+ return; -+ } -+ TimingsReportListener listeners = new TimingsReportListener(Timings.requestingReport); -+ listeners.addConsoleIfNeeded(); -+ -+ Timings.requestingReport.clear(); -+ long now = System.currentTimeMillis(); -+ final long lastReportDiff = now - lastReport; -+ if (lastReportDiff < 60000) { -+ listeners.sendMessage(text("Please wait at least 1 minute in between Timings reports. (" + (int)((60000 - lastReportDiff) / 1000) + " seconds)", NamedTextColor.RED)); -+ listeners.done(); -+ return; -+ } -+ final long lastStartDiff = now - TimingsManager.timingStart; -+ if (lastStartDiff < 180000) { -+ listeners.sendMessage(text("Please wait at least 3 minutes before generating a Timings report. Unlike Timings v1, v2 benefits from longer timings and is not as useful with short timings. (" + (int)((180000 - lastStartDiff) / 1000) + " seconds)", NamedTextColor.RED)); -+ listeners.done(); -+ return; -+ } -+ listeners.sendMessage(text("Preparing Timings Report...", NamedTextColor.GREEN)); -+ lastReport = now; -+ Map parent = createObject( -+ // Get some basic system details about the server -+ pair("version", Bukkit.getVersion()), -+ pair("maxplayers", Bukkit.getMaxPlayers()), -+ pair("start", TimingsManager.timingStart / 1000), -+ pair("end", System.currentTimeMillis() / 1000), -+ pair("online-mode", Bukkit.getServer().getOnlineMode()), -+ pair("sampletime", (System.currentTimeMillis() - TimingsManager.timingStart) / 1000), -+ pair("datapacks", toArrayMapper(MinecraftServer.getServer().getPackRepository().getSelectedPacks(), pack -> { -+ return PlainTextComponentSerializer.plainText().serialize(PaperAdventure.asAdventure(pack.getChatLink(true))); -+ })) -+ ); -+ if (!TimingsManager.privacy) { -+ appendObjectData(parent, -+ pair("server", Bukkit.getUnsafe().getTimingsServerName()), -+ pair("motd", Bukkit.getServer().getMotd()), -+ pair("icon", Bukkit.getServer().getServerIcon().getData()) -+ ); -+ } -+ -+ final Runtime runtime = Runtime.getRuntime(); -+ RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean(); -+ -+ OperatingSystemMXBean osInfo = ManagementFactory.getOperatingSystemMXBean(); -+ -+ HardwareAbstractionLayer hardwareInfo = new SystemInfo().getHardware(); -+ -+ parent.put("system", createObject( -+ pair("timingcost", getCost()), -+ pair("loadavg", osInfo.getSystemLoadAverage()), -+ pair("name", System.getProperty("os.name")), -+ pair("version", System.getProperty("os.version")), -+ pair("jvmversion", System.getProperty("java.version")), -+ pair("jvmvendor", System.getProperty("java.vendor")), -+ pair("jvmvendorversion", System.getProperty("java.vendor.version")), -+ pair("arch", System.getProperty("os.arch")), -+ pair("maxmem", runtime.maxMemory()), -+ pair("memory", createObject( -+ pair("heap", ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().toString()), -+ pair("nonheap", ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().toString()), -+ pair("finalizing", ManagementFactory.getMemoryMXBean().getObjectPendingFinalizationCount()) -+ )), -+ pair("cpu", runtime.availableProcessors()), -+ pair("cpuname", hardwareInfo.getProcessor().getProcessorIdentifier().getName().trim()), -+ pair("runtime", runtimeBean.getUptime()), -+ pair("flags", StringUtils.join(runtimeBean.getInputArguments(), " ")), -+ pair("gc", toObjectMapper(ManagementFactory.getGarbageCollectorMXBeans(), input -> pair(input.getName(), toArray(input.getCollectionCount(), input.getCollectionTime())))) -+ ) -+ ); -+ -+ parent.put("worlds", toObjectMapper(MinecraftServer.getServer().getAllLevels(), world -> { -+ if (world.getWorld().getName().equals("worldeditregentempworld")) return null; -+ return pair(world.getWorld().getName(), createObject( -+ pair("gamerules", toObjectMapper(world.getWorld().getGameRules(), rule -> { -+ return pair(rule, world.getWorld().getGameRuleValue(rule)); -+ })), -+ pair("ticking-distance", world.getWorld().getSimulationDistance()), -+ pair("no-ticking-distance", world.getWorld().getViewDistance()), -+ pair("sending-distance", world.getWorld().getSendViewDistance()) -+ )); -+ })); -+ -+ Set tileEntityTypeSet = Sets.newHashSet(); -+ Set entityTypeSet = Sets.newHashSet(); -+ -+ int size = HISTORY.size(); -+ TimingHistory[] history = new TimingHistory[size + 1]; -+ int i = 0; -+ for (TimingHistory timingHistory : HISTORY) { -+ tileEntityTypeSet.addAll(timingHistory.tileEntityTypeSet); -+ entityTypeSet.addAll(timingHistory.entityTypeSet); -+ history[i++] = timingHistory; -+ } -+ -+ history[i] = new TimingHistory(); // Current snapshot -+ tileEntityTypeSet.addAll(history[i].tileEntityTypeSet); -+ entityTypeSet.addAll(history[i].entityTypeSet); -+ -+ -+ Map handlers = createObject(); -+ Map groupData; -+ synchronized (TimingIdentifier.GROUP_MAP) { -+ for (TimingIdentifier.TimingGroup group : TimingIdentifier.GROUP_MAP.values()) { -+ synchronized (group.handlers) { -+ for (TimingHandler id : group.handlers) { -+ -+ if (!id.isTimed() && !id.isSpecial()) { -+ continue; -+ } -+ -+ String name = id.identifier.name; -+ if (name.startsWith("##")) { -+ name = name.substring(3); -+ } -+ handlers.put(id.id, toArray( -+ group.id, -+ name -+ )); -+ } -+ } -+ } -+ -+ groupData = toObjectMapper( -+ TimingIdentifier.GROUP_MAP.values(), group -> pair(group.id, group.name)); -+ } -+ -+ parent.put("idmap", createObject( -+ pair("groups", groupData), -+ pair("handlers", handlers), -+ pair("worlds", toObjectMapper(TimingHistory.worldMap.entrySet(), input -> pair(input.getValue(), input.getKey()))), -+ pair("tileentity", -+ toObjectMapper(tileEntityTypeSet, input -> pair(input.ordinal(), input.name()))), -+ pair("entity", -+ toObjectMapper(entityTypeSet, input -> pair(input.ordinal(), input.name()))) -+ )); -+ -+ // Information about loaded plugins -+ -+ parent.put("plugins", toObjectMapper(Bukkit.getPluginManager().getPlugins(), -+ plugin -> pair(plugin.getName(), createObject( -+ pair("version", plugin.getDescription().getVersion()), -+ pair("description", String.valueOf(plugin.getDescription().getDescription()).trim()), -+ pair("website", plugin.getDescription().getWebsite()), -+ pair("authors", StringUtils.join(plugin.getDescription().getAuthors(), ", ")) -+ )))); -+ -+ -+ -+ // Information on the users Config -+ -+ parent.put("config", createObject( -+ pair("spigot", mapAsJSON(Bukkit.spigot().getSpigotConfig(), null)), -+ pair("bukkit", mapAsJSON(Bukkit.spigot().getBukkitConfig(), null)), -+ pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)) -+ )); -+ -+ new TimingsExport(listeners, parent, history).start(); -+ } -+ -+ static long getCost() { -+ // Benchmark the users System.nanotime() for cost basis -+ int passes = 100; -+ TimingHandler SAMPLER1 = Timings.ofSafe("Timings Sampler 1"); -+ TimingHandler SAMPLER2 = Timings.ofSafe("Timings Sampler 2"); -+ TimingHandler SAMPLER3 = Timings.ofSafe("Timings Sampler 3"); -+ TimingHandler SAMPLER4 = Timings.ofSafe("Timings Sampler 4"); -+ TimingHandler SAMPLER5 = Timings.ofSafe("Timings Sampler 5"); -+ TimingHandler SAMPLER6 = Timings.ofSafe("Timings Sampler 6"); -+ -+ long start = System.nanoTime(); -+ for (int i = 0; i < passes; i++) { -+ SAMPLER1.startTiming(); -+ SAMPLER2.startTiming(); -+ SAMPLER3.startTiming(); -+ SAMPLER3.stopTiming(); -+ SAMPLER4.startTiming(); -+ SAMPLER5.startTiming(); -+ SAMPLER6.startTiming(); -+ SAMPLER6.stopTiming(); -+ SAMPLER5.stopTiming(); -+ SAMPLER4.stopTiming(); -+ SAMPLER2.stopTiming(); -+ SAMPLER1.stopTiming(); -+ } -+ long timingsCost = (System.nanoTime() - start) / passes / 6; -+ SAMPLER1.reset(true); -+ SAMPLER2.reset(true); -+ SAMPLER3.reset(true); -+ SAMPLER4.reset(true); -+ SAMPLER5.reset(true); -+ SAMPLER6.reset(true); -+ return timingsCost; -+ } -+ -+ private static JSONObject mapAsJSON(ConfigurationSection config, String parentKey) { -+ -+ JSONObject object = new JSONObject(); -+ for (String key : config.getKeys(false)) { -+ String fullKey = (parentKey != null ? parentKey + "." + key : key); -+ if (fullKey.equals("database") || fullKey.equals("settings.bungeecord-addresses") || TimingsManager.hiddenConfigs.contains(fullKey) || key.startsWith("seed-") || key.equals("worldeditregentempworld")) { -+ continue; -+ } -+ final Object val = config.get(key); -+ -+ object.put(key, valAsJSON(val, fullKey)); -+ } -+ return object; -+ } -+ -+ private static Object valAsJSON(Object val, final String parentKey) { -+ if (!(val instanceof MemorySection)) { -+ if (val instanceof List) { -+ Iterable v = (Iterable) val; -+ return toArrayMapper(v, input -> valAsJSON(input, parentKey)); -+ } else { -+ return String.valueOf(val); -+ } -+ } else { -+ return mapAsJSON((ConfigurationSection) val, parentKey); -+ } -+ } -+ -+ @Override -+ public void run() { -+ out.put("data", toArrayMapper(history, TimingHistory::export)); -+ -+ -+ String response = null; -+ String timingsURL = null; -+ try { -+ HttpURLConnection con = (HttpURLConnection) new URL(TimingsManager.url + "post").openConnection(); -+ con.setDoOutput(true); -+ String hostName = "BrokenHost"; -+ try { -+ hostName = InetAddress.getLocalHost().getHostName(); -+ } catch (Exception ignored) {} -+ con.setRequestProperty("User-Agent", "Paper/" + Bukkit.getUnsafe().getTimingsServerName() + "/" + hostName); -+ con.setRequestMethod("POST"); -+ con.setInstanceFollowRedirects(false); -+ -+ OutputStream request = new GZIPOutputStream(con.getOutputStream()) {{ -+ this.def.setLevel(7); -+ }}; -+ -+ request.write(JSONValue.toJSONString(out).getBytes("UTF-8")); -+ request.close(); -+ -+ response = getResponse(con); -+ -+ if (con.getResponseCode() != 302) { -+ listeners.sendMessage(text( "Upload Error: " + con.getResponseCode() + ": " + con.getResponseMessage(), NamedTextColor.RED)); -+ listeners.sendMessage(text("Check your logs for more information", NamedTextColor.RED)); -+ if (response != null) { -+ Bukkit.getLogger().log(Level.SEVERE, response); -+ } -+ return; -+ } -+ -+ timingsURL = con.getHeaderField("Location"); -+ listeners.sendMessage(text("View Timings Report: ", NamedTextColor.GREEN).append(text(timingsURL).clickEvent(ClickEvent.clickEvent(ClickEvent.Action.OPEN_URL, timingsURL)))); -+ -+ if (response != null && !response.isEmpty()) { -+ Bukkit.getLogger().log(Level.INFO, "Timing Response: " + response); -+ } -+ } catch (IOException ex) { -+ listeners.sendMessage(text("Error uploading timings, check your logs for more information", NamedTextColor.RED)); -+ if (response != null) { -+ Bukkit.getLogger().log(Level.SEVERE, response); -+ } -+ Bukkit.getLogger().log(Level.SEVERE, "Could not paste timings", ex); -+ } finally { -+ this.listeners.done(timingsURL); -+ } -+ } -+ -+ private String getResponse(HttpURLConnection con) throws IOException { -+ InputStream is = null; -+ try { -+ is = con.getInputStream(); -+ ByteArrayOutputStream bos = new ByteArrayOutputStream(); -+ -+ byte[] b = new byte[1024]; -+ int bytesRead; -+ while ((bytesRead = is.read(b)) != -1) { -+ bos.write(b, 0, bytesRead); -+ } -+ return bos.toString(); -+ -+ } catch (IOException ex) { -+ listeners.sendMessage(text("Error uploading timings, check your logs for more information", NamedTextColor.RED)); -+ Bukkit.getLogger().log(Level.WARNING, con.getResponseMessage(), ex); -+ return null; -+ } finally { -+ if (is != null) { -+ is.close(); -+ } -+ } -+ } -+} -diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java -new file mode 100644 -index 0000000000000000000000000000000000000000..2f0d9b953802dee821cfde82d22b0567cce8ee91 ---- /dev/null -+++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java -@@ -0,0 +1,120 @@ -+package co.aikar.timings; -+ -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.storage.PrimaryLevelData; -+ -+/** -+ * Set of timers per world, to track world specific timings. -+ */ -+// TODO: Re-implement missing timers -+@Deprecated(forRemoval = true) -+public class WorldTimingsHandler { -+ public final Timing mobSpawn; -+ public final Timing doChunkUnload; -+ public final Timing doPortalForcer; -+ public final Timing scheduledBlocks; -+ public final Timing scheduledBlocksCleanup; -+ public final Timing scheduledBlocksTicking; -+ public final Timing chunkTicks; -+ public final Timing lightChunk; -+ public final Timing chunkTicksBlocks; -+ public final Timing doVillages; -+ public final Timing doChunkMap; -+ public final Timing doChunkMapUpdate; -+ public final Timing doChunkMapToUpdate; -+ public final Timing doChunkMapSortMissing; -+ public final Timing doChunkMapSortSendToPlayers; -+ public final Timing doChunkMapPlayersNeedingChunks; -+ public final Timing doChunkMapPendingSendToPlayers; -+ public final Timing doChunkMapUnloadChunks; -+ public final Timing doChunkGC; -+ public final Timing doSounds; -+ public final Timing entityRemoval; -+ public final Timing entityTick; -+ public final Timing tileEntityTick; -+ public final Timing tileEntityPending; -+ public final Timing tracker1; -+ public final Timing tracker2; -+ public final Timing doTick; -+ public final Timing tickEntities; -+ public final Timing chunks; -+ public final Timing newEntities; -+ public final Timing raids; -+ public final Timing chunkProviderTick; -+ public final Timing broadcastChunkUpdates; -+ public final Timing countNaturalMobs; -+ -+ public final Timing chunkLoad; -+ public final Timing chunkLoadPopulate; -+ public final Timing syncChunkLoad; -+ public final Timing chunkLoadLevelTimer; -+ public final Timing chunkIO; -+ public final Timing chunkPostLoad; -+ public final Timing worldSave; -+ public final Timing worldSaveChunks; -+ public final Timing worldSaveLevel; -+ public final Timing chunkSaveData; -+ -+ -+ public final Timing miscMobSpawning; -+ -+ public WorldTimingsHandler(Level server) { -+ String name = ((PrimaryLevelData) server.getLevelData()).getLevelName() + " - "; -+ -+ mobSpawn = Timings.ofSafe(name + "mobSpawn"); -+ doChunkUnload = Timings.ofSafe(name + "doChunkUnload"); -+ scheduledBlocks = Timings.ofSafe(name + "Scheduled Blocks"); -+ scheduledBlocksCleanup = Timings.ofSafe(name + "Scheduled Blocks - Cleanup"); -+ scheduledBlocksTicking = Timings.ofSafe(name + "Scheduled Blocks - Ticking"); -+ chunkTicks = Timings.ofSafe(name + "Chunk Ticks"); -+ lightChunk = Timings.ofSafe(name + "Light Chunk"); -+ chunkTicksBlocks = Timings.ofSafe(name + "Chunk Ticks - Blocks"); -+ doVillages = Timings.ofSafe(name + "doVillages"); -+ doChunkMap = Timings.ofSafe(name + "doChunkMap"); -+ doChunkMapUpdate = Timings.ofSafe(name + "doChunkMap - Update"); -+ doChunkMapToUpdate = Timings.ofSafe(name + "doChunkMap - To Update"); -+ doChunkMapSortMissing = Timings.ofSafe(name + "doChunkMap - Sort Missing"); -+ doChunkMapSortSendToPlayers = Timings.ofSafe(name + "doChunkMap - Sort Send To Players"); -+ doChunkMapPlayersNeedingChunks = Timings.ofSafe(name + "doChunkMap - Players Needing Chunks"); -+ doChunkMapPendingSendToPlayers = Timings.ofSafe(name + "doChunkMap - Pending Send To Players"); -+ doChunkMapUnloadChunks = Timings.ofSafe(name + "doChunkMap - Unload Chunks"); -+ doSounds = Timings.ofSafe(name + "doSounds"); -+ doChunkGC = Timings.ofSafe(name + "doChunkGC"); -+ doPortalForcer = Timings.ofSafe(name + "doPortalForcer"); -+ entityTick = Timings.ofSafe(name + "entityTick"); -+ entityRemoval = Timings.ofSafe(name + "entityRemoval"); -+ tileEntityTick = Timings.ofSafe(name + "tileEntityTick"); -+ tileEntityPending = Timings.ofSafe(name + "tileEntityPending"); -+ -+ chunkLoad = Timings.ofSafe(name + "Chunk Load"); -+ chunkLoadPopulate = Timings.ofSafe(name + "Chunk Load - Populate"); -+ syncChunkLoad = Timings.ofSafe(name + "Sync Chunk Load"); -+ chunkLoadLevelTimer = Timings.ofSafe(name + "Chunk Load - Load Level"); -+ chunkIO = Timings.ofSafe(name + "Chunk Load - DiskIO"); -+ chunkPostLoad = Timings.ofSafe(name + "Chunk Load - Post Load"); -+ worldSave = Timings.ofSafe(name + "World Save"); -+ worldSaveLevel = Timings.ofSafe(name + "World Save - Level"); -+ worldSaveChunks = Timings.ofSafe(name + "World Save - Chunks"); -+ chunkSaveData = Timings.ofSafe(name + "Chunk Save - Data"); -+ -+ tracker1 = Timings.ofSafe(name + "tracker stage 1"); -+ tracker2 = Timings.ofSafe(name + "tracker stage 2"); -+ doTick = Timings.ofSafe(name + "doTick"); -+ tickEntities = Timings.ofSafe(name + "tickEntities"); -+ -+ chunks = Timings.ofSafe(name + "Chunks"); -+ newEntities = Timings.ofSafe(name + "New entity registration"); -+ raids = Timings.ofSafe(name + "Raids"); -+ chunkProviderTick = Timings.ofSafe(name + "Chunk provider tick"); -+ broadcastChunkUpdates = Timings.ofSafe(name + "Broadcast chunk updates"); -+ countNaturalMobs = Timings.ofSafe(name + "Count natural mobs"); -+ -+ -+ miscMobSpawning = Timings.ofSafe(name + "Mob spawning - Misc"); -+ } -+ -+ public static Timing getTickList(ServerLevel worldserver, String timingsType) { -+ return Timings.ofSafe(((PrimaryLevelData) worldserver.getLevelData()).getLevelName() + " - Scheduled " + timingsType); -+ } -+} -diff --git a/src/main/java/net/minecraft/network/protocol/PacketUtils.java b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -index f7197f1347251a37dd0f6d9ffa2f09bc3a4e1233..d0d36a57ec4896bcb74970f8fb24d8f3e17db133 100644 ---- a/src/main/java/net/minecraft/network/protocol/PacketUtils.java -+++ b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -@@ -31,7 +31,8 @@ public class PacketUtils { - engine.executeIfPossible(() -> { - if (listener instanceof ServerCommonPacketListenerImpl serverCommonPacketListener && serverCommonPacketListener.processedDisconnect) return; // CraftBukkit - Don't handle sync packets for kicked players - if (listener.shouldHandleMessage(packet)) { -- try { -+ co.aikar.timings.Timing timing = co.aikar.timings.MinecraftTimings.getPacketTiming(packet); // Paper - timings -+ try (co.aikar.timings.Timing ignored = timing.startTiming()) { // Paper - timings - packet.handle(listener); - } catch (Exception exception) { - if (exception instanceof ReportedException) { -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 3322865949fe5ddaab2dffc39260b75093f0f204..a76e2f5d29315d21212ff121f0047bf1140ad5ef 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -203,7 +203,7 @@ import org.bukkit.craftbukkit.Main; - import org.bukkit.event.server.ServerLoadEvent; - // CraftBukkit end - --import org.bukkit.craftbukkit.SpigotTimings; // Spigot -+import co.aikar.timings.MinecraftTimings; // Paper - - public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource { - -@@ -926,6 +926,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -- return !this.haveTime(); -+ return !this.canSleepForTickNoOversleep(); // Paper - move oversleep into full server tick - }); - } finally { - this.waitingForNextTick = false; -@@ -1371,6 +1384,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -+ return !this.canOversleep(); -+ }); -+ isOversleep = false;MinecraftTimings.serverOversleep.stopTiming(); -+ // Paper end -+ - ++this.tickCount; - this.tickRateManager.tick(); - this.tickChildren(shouldKeepTicking); -@@ -1409,6 +1430,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { - entityplayer.connection.suspendFlushing(); - }); -- SpigotTimings.schedulerTimer.startTiming(); // Spigot -+ MinecraftTimings.bukkitSchedulerTimer.startTiming(); // Spigot // Paper - this.server.getScheduler().mainThreadHeartbeat(); // CraftBukkit -- SpigotTimings.schedulerTimer.stopTiming(); // Spigot -+ MinecraftTimings.bukkitSchedulerTimer.stopTiming(); // Spigot // Paper - io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.CALLBACK_MANAGER.handleQueue(this.tickCount); // Paper - gameprofilerfiller.push("commandFunctions"); -- SpigotTimings.commandFunctionsTimer.startTiming(); // Spigot -+ MinecraftTimings.commandFunctionsTimer.startTiming(); // Spigot // Paper - this.getFunctions().tick(); -- SpigotTimings.commandFunctionsTimer.stopTiming(); // Spigot -+ MinecraftTimings.commandFunctionsTimer.stopTiming(); // Spigot // Paper - gameprofilerfiller.popPush("levels"); - Iterator iterator = this.getAllLevels().iterator(); - - // CraftBukkit start - // Run tasks that are waiting on processing -- SpigotTimings.processQueueTimer.startTiming(); // Spigot -+ MinecraftTimings.processQueueTimer.startTiming(); // Spigot - while (!this.processQueue.isEmpty()) { - this.processQueue.remove().run(); - } -- SpigotTimings.processQueueTimer.stopTiming(); // Spigot -+ MinecraftTimings.processQueueTimer.stopTiming(); // Spigot - -- SpigotTimings.timeUpdateTimer.startTiming(); // Spigot -+ MinecraftTimings.timeUpdateTimer.startTiming(); // Spigot // Paper - // Send time updates to everyone, it will get the right time from the world the player is in. - if (this.tickCount % 20 == 0) { - for (int i = 0; i < this.getPlayerList().players.size(); ++i) { -@@ -1533,7 +1556,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop command = new java.util.concurrent.atomic.AtomicReference<>(s); // Paper - this.executeBlocking(() -> { - CommandSourceStack wrapper = rconConsoleSource.createCommandSourceStack(); - RemoteServerCommandEvent event = new RemoteServerCommandEvent(rconConsoleSource.getBukkitSender(wrapper), s); -@@ -702,9 +705,39 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface - if (event.isCancelled()) { - return; - } -+ // Paper start -+ command.set(event.getCommand()); -+ if (event.getCommand().toLowerCase(java.util.Locale.ROOT).startsWith("timings") && event.getCommand().toLowerCase(java.util.Locale.ROOT).matches("timings (report|paste|get|merged|seperate)")) { -+ org.bukkit.command.BufferedCommandSender sender = new org.bukkit.command.BufferedCommandSender(); -+ Waitable waitable = new Waitable<>() { -+ @Override -+ protected String evaluate() { -+ return sender.getBuffer(); -+ } -+ }; -+ waitableArray[0] = waitable; -+ co.aikar.timings.Timings.generateReport(new co.aikar.timings.TimingsReportListener(sender, waitable)); -+ } else { -+ // Paper end - ConsoleInput serverCommand = new ConsoleInput(event.getCommand(), wrapper); - this.server.dispatchServerCommand(event.getSender(), serverCommand); -+ } // Paper - }); -+ // Paper start -+ if (waitableArray[0] != null) { -+ //noinspection unchecked -+ Waitable waitable = waitableArray[0]; -+ try { -+ return waitable.get(); -+ } catch (java.util.concurrent.ExecutionException e) { -+ throw new RuntimeException("Exception processing rcon command " + command.get(), e.getCause()); -+ } catch (InterruptedException e) { -+ Thread.currentThread().interrupt(); // Maintain interrupted state -+ throw new RuntimeException("Interrupted processing rcon command " + command.get(), e); -+ } -+ -+ } -+ // Paper end - return rconConsoleSource.getCommandResponse(); - // CraftBukkit end - } -diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 3bb6eaabe8f62b556a52b83227b48f8324a9d0f0..30b28d9523820ed138c837ab9ee9bbb23c0dd285 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 @@ - package net.minecraft.server.level; - -+import co.aikar.timings.Timing; // Paper - import com.google.common.collect.ImmutableList; - import com.google.common.collect.ImmutableList.Builder; - import com.google.common.collect.Iterables; -+import com.google.common.collect.ComparisonChain; // Paper - import com.google.common.collect.Lists; - import com.google.common.collect.Queues; - import com.google.common.collect.Sets; -@@ -1355,6 +1357,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - List list = Lists.newArrayList(); - List list1 = this.level.players(); - ObjectIterator objectiterator = this.entityMap.values().iterator(); -+ level.timings.tracker1.startTiming(); // Paper - - ChunkMap.TrackedEntity playerchunkmap_entitytracker; - -@@ -1379,14 +1382,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - playerchunkmap_entitytracker.serverEntity.sendChanges(); - } - } -+ level.timings.tracker1.stopTiming(); // Paper - - if (!list.isEmpty()) { - objectiterator = this.entityMap.values().iterator(); - -+ level.timings.tracker2.startTiming(); // Paper - while (objectiterator.hasNext()) { - playerchunkmap_entitytracker = (ChunkMap.TrackedEntity) objectiterator.next(); - playerchunkmap_entitytracker.updatePlayers(list); - } -+ level.timings.tracker2.stopTiming(); // Paper - } - - } -diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index c615510f3f59292715bcff1bd9e4e896c9733436..93422468474189343cdc1e29f06f6dfb12e4760a 100644 ---- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java -+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -207,13 +207,15 @@ public class ServerChunkCache extends ChunkSource { - } - - gameprofilerfiller.incrementCounter("getChunkCacheMiss"); -- this.level.timings.syncChunkLoadTimer.startTiming(); // Spigot - CompletableFuture> completablefuture = this.getChunkFutureMainThread(x, z, leastStatus, create); - ServerChunkCache.MainThreadExecutor chunkproviderserver_b = this.mainThreadProcessor; - - Objects.requireNonNull(completablefuture); -+ if (!completablefuture.isDone()) { // Paper -+ this.level.timings.syncChunkLoad.startTiming(); // Paper - chunkproviderserver_b.managedBlock(completablefuture::isDone); -- this.level.timings.syncChunkLoadTimer.stopTiming(); // Spigot -+ this.level.timings.syncChunkLoad.stopTiming(); // Paper -+ } // Paper - ChunkResult chunkresult = (ChunkResult) completablefuture.join(); - ChunkAccess ichunkaccess1 = (ChunkAccess) chunkresult.orElse(null); // CraftBukkit - decompile error - -@@ -382,7 +384,9 @@ public class ServerChunkCache extends ChunkSource { - - public void save(boolean flush) { - this.runDistanceManagerUpdates(); -+ try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings - this.chunkMap.saveAllChunks(flush); -+ } // Paper - Timings - } - - @Override -@@ -429,10 +433,10 @@ public class ServerChunkCache extends ChunkSource { - this.level.timings.doChunkMap.stopTiming(); // Spigot - gameprofilerfiller.popPush("chunks"); - if (tickChunks) { -+ this.level.timings.chunks.startTiming(); // Paper - timings - this.tickChunks(); -- this.level.timings.tracker.startTiming(); // Spigot -+ this.level.timings.chunks.stopTiming(); // Paper - timings - this.chunkMap.tick(); -- this.level.timings.tracker.stopTiming(); // Spigot - } - - this.level.timings.doChunkUnload.startTiming(); // Spigot -@@ -481,7 +485,9 @@ public class ServerChunkCache extends ChunkSource { - LevelChunk chunk = playerchunk.getTickingChunk(); - - if (chunk != null) { -+ this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing - playerchunk.broadcastChanges(chunk); -+ this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing - } - } - -@@ -502,8 +508,10 @@ public class ServerChunkCache extends ChunkSource { - - private void tickChunks(ProfilerFiller profiler, long timeDelta, List chunks) { - profiler.popPush("naturalSpawnCount"); -+ this.level.timings.countNaturalMobs.startTiming(); // Paper - timings - int j = this.distanceManager.getNaturalSpawnChunkCount(); - NaturalSpawner.SpawnState spawnercreature_d = NaturalSpawner.createState(j, this.level.getAllEntities(), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap)); -+ this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings - - this.lastSpawnState = spawnercreature_d; - profiler.popPush("spawnAndTick"); -@@ -531,15 +539,17 @@ public class ServerChunkCache extends ChunkSource { - } - - if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { -- this.level.timings.doTickTiles.startTiming(); // Spigot - this.level.tickChunk(chunk, k); -- this.level.timings.doTickTiles.stopTiming(); // Spigot - } - } - -+ this.level.timings.chunkTicks.stopTiming(); // Paper -+ - profiler.popPush("customSpawners"); - if (flag) { -+ try (co.aikar.timings.Timing ignored = this.level.timings.miscMobSpawning.startTiming()) { // Paper - timings - this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies); -+ } - } - - } -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index c6ded1ac73ddbc0336000f77c0f99fa20551a0de..a1565304c436258b561d97a6cc7aacecf68816b7 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 @@ - package net.minecraft.server.level; - - import com.google.common.annotations.VisibleForTesting; -+import co.aikar.timings.TimingHistory; // Paper -+import co.aikar.timings.Timings; // Paper - import com.google.common.collect.Lists; - import com.mojang.datafixers.DataFixer; - import com.mojang.datafixers.util.Pair; -@@ -176,7 +178,6 @@ import net.minecraft.world.ticks.LevelTicks; - import org.slf4j.Logger; - import org.bukkit.Bukkit; - import org.bukkit.WeatherType; --import org.bukkit.craftbukkit.SpigotTimings; // Spigot - import org.bukkit.craftbukkit.event.CraftEventFactory; - import org.bukkit.craftbukkit.generator.CustomWorldChunkManager; - import org.bukkit.craftbukkit.util.WorldUUID; -@@ -469,7 +470,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - } - - gameprofilerfiller.push("tickPending"); -- this.timings.doTickPending.startTiming(); // Spigot -+ this.timings.scheduledBlocks.startTiming(); // Paper - if (!this.isDebug() && flag) { - j = this.getGameTime(); - gameprofilerfiller.push("blockTicks"); -@@ -478,15 +479,19 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - this.fluidTicks.tick(j, 65536, this::tickFluid); - gameprofilerfiller.pop(); - } -- this.timings.doTickPending.stopTiming(); // Spigot -+ this.timings.scheduledBlocks.stopTiming(); // Paper - - gameprofilerfiller.popPush("raid"); - if (flag) { -+ this.timings.raids.startTiming(); // Paper - timings - this.raids.tick(); -+ this.timings.raids.stopTiming(); // Paper - timings - } - - gameprofilerfiller.popPush("chunkSource"); -+ this.timings.chunkProviderTick.startTiming(); // Paper - timings - this.getChunkSource().tick(shouldKeepTicking, true); -+ this.timings.chunkProviderTick.stopTiming(); // Paper - timings - gameprofilerfiller.popPush("blockEvents"); - if (flag) { - this.timings.doSounds.startTiming(); // Spigot -@@ -635,6 +640,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - } - - gameprofilerfiller.popPush("tickBlocks"); -+ timings.chunkTicksBlocks.startTiming(); // Paper - if (randomTickSpeed > 0) { - LevelChunkSection[] achunksection = chunk.getSections(); - -@@ -667,6 +673,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - } - } - -+ timings.chunkTicksBlocks.stopTiming(); // Paper - gameprofilerfiller.pop(); - } - -@@ -944,14 +951,22 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - } - - public void tickNonPassenger(Entity entity) { -+ ++TimingHistory.entityTicks; // Paper - timings - // Spigot start -+ co.aikar.timings.Timing timer; // Paper - if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { - entity.tickCount++; -+ timer = entity.getType().inactiveTickTimer.startTiming(); try { // Paper - timings - entity.inactiveTick(); -+ } finally { timer.stopTiming(); } // Paper - return; - } - // Spigot end -- entity.tickTimer.startTiming(); // Spigot -+ // Paper start- timings -+ TimingHistory.activatedEntityTicks++; -+ timer = entity.getVehicle() != null ? entity.getType().passengerTickTimer.startTiming() : entity.getType().tickTimer.startTiming(); -+ try { -+ // Paper end - timings - entity.setOldPosAndRot(); - ProfilerFiller gameprofilerfiller = Profiler.get(); - -@@ -970,7 +985,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - - this.tickPassenger(entity, entity1); - } -- entity.tickTimer.stopTiming(); // Spigot -+ } finally { timer.stopTiming(); } // Paper - timings - - } - -@@ -1012,6 +1027,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - - if (!savingDisabled) { - org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(this.getWorld())); // CraftBukkit -+ try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) { // Paper - if (progressListener != null) { - progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel")); - } -@@ -1021,7 +1037,10 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - progressListener.progressStage(Component.translatable("menu.savingChunks")); - } - -+ timings.worldSaveChunks.startTiming(); // Paper - chunkproviderserver.save(flush); -+ timings.worldSaveChunks.stopTiming(); // Paper -+ }// Paper - if (flush) { - this.entityManager.saveAll(); - } else { -diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 18d56058073b6cc4f9020f0a6137e4ac26eed0b2..d8fd2103a40d278c7ee4135c19dea3eb4534dda8 100644 ---- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -339,7 +339,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - - @Override - public void tick() { -- org.bukkit.craftbukkit.SpigotTimings.playerConnectionTimer.startTiming(); // Spigot - if (this.ackBlockChangesUpTo > -1) { - this.send(new ClientboundBlockChangedAckPacket(this.ackBlockChangesUpTo)); - this.ackBlockChangesUpTo = -1; -@@ -395,7 +394,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 - this.disconnect((Component) Component.translatable("multiplayer.disconnect.idling")); - } -- org.bukkit.craftbukkit.SpigotTimings.playerConnectionTimer.stopTiming(); // Spigot - - } - -@@ -2122,7 +2120,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - } - - private void handleCommand(String s) { -- org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.startTiming(); // Spigot -+ co.aikar.timings.MinecraftTimings.playerCommandTimer.startTiming(); // Paper - if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot - this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s); - -@@ -2132,7 +2130,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - this.cserver.getPluginManager().callEvent(event); - - if (event.isCancelled()) { -- org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot -+ co.aikar.timings.MinecraftTimings.playerCommandTimer.stopTiming(); // Paper - return; - } - -@@ -2145,7 +2143,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - java.util.logging.Logger.getLogger(ServerGamePacketListenerImpl.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); - return; - } finally { -- org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot -+ co.aikar.timings.MinecraftTimings.playerCommandTimer.stopTiming(); // Paper - } - } - // 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 56f046bac04205a813441907058c4ce21982d927..b103d49458330be9f7fb3382c764b204a02a925a 100644 ---- a/src/main/java/net/minecraft/server/players/PlayerList.java -+++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1,5 +1,6 @@ - package net.minecraft.server.players; - -+import co.aikar.timings.MinecraftTimings; - import com.google.common.collect.Lists; - import com.google.common.collect.Maps; - import com.google.common.collect.Sets; -@@ -976,10 +977,11 @@ public abstract class PlayerList { - } - - public void saveAll() { -+ MinecraftTimings.savePlayers.startTiming(); // Paper - for (int i = 0; i < this.players.size(); ++i) { - this.save((ServerPlayer) this.players.get(i)); - } -- -+ MinecraftTimings.savePlayers.stopTiming(); // Paper - } - - public UserWhiteList getWhiteList() { -diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index c010d18061f58a583c69e85fc29305497523f569..c8b8102d84119dfb6093f4b79aa3124c594f9a88 100644 ---- a/src/main/java/net/minecraft/world/entity/Entity.java -+++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -148,7 +148,6 @@ import org.bukkit.command.CommandSender; - import org.bukkit.entity.Hanging; - import org.bukkit.entity.LivingEntity; - import org.bukkit.entity.Vehicle; --import org.spigotmc.CustomTimingsHandler; // Spigot - import org.bukkit.event.entity.EntityCombustByEntityEvent; - import org.bukkit.event.hanging.HangingBreakByEntityEvent; - import org.bukkit.event.vehicle.VehicleBlockCollisionEvent; -@@ -326,7 +325,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - // Marks an entity, that it was removed by a plugin via Entity#remove - // Main use case currently is for SPIGOT-7487, preventing dropping of leash when leash is removed - public boolean pluginRemoved = false; -- public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getEntityTimings(this); // Spigot - // Spigot start - public final org.spigotmc.ActivationRange.ActivationType activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this); - public final boolean defaultActivationState; -@@ -866,7 +864,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - } - - public void move(MoverType type, Vec3 movement) { -- org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.startTiming(); // Spigot - if (this.noPhysics) { - this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z); - } else { -@@ -978,7 +975,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - gameprofilerfiller.pop(); - } - } -- org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.stopTiming(); // Spigot - } - - private void applyMovementEmissionAndPlaySound(Entity.MovementEmission moveEffect, Vec3 movement, BlockPos landingPos, BlockState landingState) { -diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 17ab230c95901f0533997ac117d5b3d852fcd467..970161efa46b3a71ddae665f9df5966c70fd3471 100644 ---- a/src/main/java/net/minecraft/world/entity/EntityType.java -+++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -413,6 +413,15 @@ public class EntityType implements FeatureElement, EntityTypeT - } - - public EntityType(EntityType.EntityFactory factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet canSpawnInside, EntityDimensions dimensions, float spawnBoxScale, int maxTrackDistance, int trackTickInterval, String translationKey, Optional> lootTable, FeatureFlagSet requiredFeatures) { -+ // Paper start -+ this(factory, spawnGroup, saveable, summonable, fireImmune, spawnableFarFromPlayer, canSpawnInside, dimensions, spawnBoxScale, maxTrackDistance, trackTickInterval, translationKey, lootTable, requiredFeatures, "custom"); -+ } -+ public EntityType(EntityType.EntityFactory factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet canSpawnInside, EntityDimensions dimensions, float spawnBoxScale, int maxTrackDistance, int trackTickInterval, String translationKey, Optional> lootTable, FeatureFlagSet requiredFeatures, String id) { -+ this.tickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "tick"); -+ this.inactiveTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "inactiveTick"); -+ this.passengerTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "passengerTick"); -+ this.passengerInactiveTickTimer = co.aikar.timings.MinecraftTimings.getEntityTimings(id, "passengerInactiveTick"); -+ // Paper end - this.builtInRegistryHolder = BuiltInRegistries.ENTITY_TYPE.createIntrusiveHolder(this); - this.factory = factory; - this.category = spawnGroup; -@@ -720,6 +729,12 @@ public class EntityType implements FeatureElement, EntityTypeT - return this.updateInterval; - } - -+ // Paper start - timings -+ public final co.aikar.timings.Timing tickTimer; -+ public final co.aikar.timings.Timing inactiveTickTimer; -+ public final co.aikar.timings.Timing passengerTickTimer; -+ public final co.aikar.timings.Timing passengerInactiveTickTimer; -+ // Paper end - public boolean trackDeltas() { - return this != EntityType.PLAYER && this != EntityType.LLAMA_SPIT && this != EntityType.WITHER && this != EntityType.BAT && this != EntityType.ITEM_FRAME && this != EntityType.GLOW_ITEM_FRAME && this != EntityType.LEASH_KNOT && this != EntityType.PAINTING && this != EntityType.END_CRYSTAL && this != EntityType.EVOKER_FANGS; - } -diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 9aa4e70f1d1c4de2138d31701dceaed25062e69c..6cc86412d45186dff312d9b1246fd1d03dbc15d8 100644 ---- a/src/main/java/net/minecraft/world/entity/LivingEntity.java -+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -162,7 +162,7 @@ import org.bukkit.event.entity.EntityTeleportEvent; - import org.bukkit.event.player.PlayerItemConsumeEvent; - // CraftBukkit end - --import org.bukkit.craftbukkit.SpigotTimings; // Spigot -+import co.aikar.timings.MinecraftTimings; // Paper - - public abstract class LivingEntity extends Entity implements Attackable { - -@@ -3090,7 +3090,6 @@ public abstract class LivingEntity extends Entity implements Attackable { - - @Override - public void tick() { -- SpigotTimings.timerEntityBaseTick.startTiming(); // Spigot - super.tick(); - this.updatingUsingItem(); - this.updateSwimAmount(); -@@ -3132,9 +3131,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - } - - if (!this.isRemoved()) { -- SpigotTimings.timerEntityBaseTick.stopTiming(); // Spigot - this.aiStep(); -- SpigotTimings.timerEntityTickRest.startTiming(); // Spigot - } - - double d0 = this.getX() - this.xo; -@@ -3228,7 +3225,6 @@ public abstract class LivingEntity extends Entity implements Attackable { - } - - this.elytraAnimationState.tick(); -- SpigotTimings.timerEntityTickRest.stopTiming(); // Spigot - } - - public void detectEquipmentUpdatesPublic() { // CraftBukkit -@@ -3435,7 +3431,6 @@ public abstract class LivingEntity extends Entity implements Attackable { - ProfilerFiller gameprofilerfiller = Profiler.get(); - - gameprofilerfiller.push("ai"); -- SpigotTimings.timerEntityAI.startTiming(); // Spigot - if (this.isImmobile()) { - this.jumping = false; - this.xxa = 0.0F; -@@ -3445,7 +3440,6 @@ public abstract class LivingEntity extends Entity implements Attackable { - this.serverAiStep(); - gameprofilerfiller.pop(); - } -- SpigotTimings.timerEntityAI.stopTiming(); // Spigot - - gameprofilerfiller.pop(); - gameprofilerfiller.push("jump"); -@@ -3488,7 +3482,6 @@ public abstract class LivingEntity extends Entity implements Attackable { - this.resetFallDistance(); - } - -- SpigotTimings.timerEntityAIMove.startTiming(); // Spigot - label112: - { - LivingEntity entityliving = this.getControllingPassenger(); -@@ -3502,7 +3495,6 @@ public abstract class LivingEntity extends Entity implements Attackable { - - this.travel(vec3d1); - } -- SpigotTimings.timerEntityAIMove.stopTiming(); // Spigot - - if (!this.level().isClientSide() || this.isControlledByLocalInstance()) { - this.applyEffectsFromBlocks(); -@@ -3538,9 +3530,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - this.checkAutoSpinAttack(axisalignedbb, this.getBoundingBox()); - } - -- SpigotTimings.timerEntityAICollision.startTiming(); // Spigot - this.pushEntities(); -- SpigotTimings.timerEntityAICollision.stopTiming(); // Spigot - gameprofilerfiller.pop(); - world = this.level(); - if (world instanceof ServerLevel worldserver) { -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 3fb17bbcecf6dc4af3b231835adff25f86e1379f..5df862e026e15e10e2fcc7c5a49e8a8022125579 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -95,7 +95,6 @@ import net.minecraft.network.protocol.game.ClientboundSetBorderWarningDistancePa - import org.bukkit.Bukkit; - import org.bukkit.craftbukkit.CraftServer; - import org.bukkit.craftbukkit.CraftWorld; --import org.bukkit.craftbukkit.SpigotTimings; // Spigot - import org.bukkit.craftbukkit.block.CapturedBlockState; - import org.bukkit.craftbukkit.block.CraftBlockState; - import org.bukkit.craftbukkit.block.data.CraftBlockData; -@@ -165,7 +164,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - } - // Paper end - add paper world config - -- public final SpigotTimings.WorldTimingsHandler timings; // Spigot -+ public final co.aikar.timings.WorldTimingsHandler timings; // Paper - public static BlockPos lastPhysicsProblem; // Spigot - private org.spigotmc.TickLimiter entityLimiter; - private org.spigotmc.TickLimiter tileLimiter; -@@ -259,7 +258,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - public void onBorderSetDamageSafeZOne(WorldBorder border, double safeZoneRadius) {} - }); - // CraftBukkit end -- this.timings = new SpigotTimings.WorldTimingsHandler(this); // Spigot - code below can generate new world and access timings -+ this.timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings - this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime); - this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); - } -@@ -725,15 +724,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - - this.timings.tileEntityTick.stopTiming(); // Spigot - this.tickingBlockEntities = false; -+ co.aikar.timings.TimingHistory.tileEntityTicks += this.blockEntityTickers.size(); // Paper - gameprofilerfiller.pop(); - this.spigotConfig.currentPrimedTnt = 0; // Spigot - } - - public void guardEntityTick(Consumer tickConsumer, T entity) { - try { -- SpigotTimings.tickEntityTimer.startTiming(); // Spigot - tickConsumer.accept(entity); -- SpigotTimings.tickEntityTimer.stopTiming(); // Spigot - } catch (Throwable throwable) { - CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking entity"); - CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being ticked"); -diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index 27cbec37c6ea278232970ae035795fdecca71735..3cefda12d4c2ca2c4e9ef97eff961a55af164d6b 100644 ---- a/src/main/java/net/minecraft/world/level/block/Block.java -+++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -88,6 +88,15 @@ public class Block extends BlockBehaviour implements ItemLike { - public static final int UPDATE_LIMIT = 512; - protected final StateDefinition stateDefinition; - private BlockState defaultBlockState; -+ // Paper start -+ public co.aikar.timings.Timing timing; -+ public co.aikar.timings.Timing getTiming() { -+ if (timing == null) { -+ timing = co.aikar.timings.MinecraftTimings.getBlockTiming(this); -+ } -+ return timing; -+ } -+ // Paper end - @Nullable - private Item item; - private static final int CACHE_SIZE = 256; -diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index 4c3bc3a495990bc486fce7ba1758bf731c3baf02..9afe509b3455a7aabd11976fb8a7430d1bce065d 100644 ---- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -+++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -34,10 +34,12 @@ import org.bukkit.inventory.InventoryHolder; - // CraftBukkit end - - import org.spigotmc.CustomTimingsHandler; // Spigot -+import co.aikar.timings.MinecraftTimings; // Paper -+import co.aikar.timings.Timing; // Paper - - public abstract class BlockEntity { - -- public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getTileEntityTimings(this); // Spigot -+ public Timing tickTimer = MinecraftTimings.getTileEntityTimings(this); // Paper - // CraftBukkit start - data containers - private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); - public CraftPersistentDataContainer persistentDataContainer; -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 d76591694c3b167b8b8f17b61a373a43140a8b68..717e4bf9f5ee0ec2c3a0b5cc65a50b0f6d649a8d 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -627,6 +627,7 @@ public class LevelChunk extends ChunkAccess { - server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(bukkitChunk, this.needsDecoration)); - - if (this.needsDecoration) { -+ try (co.aikar.timings.Timing ignored = this.level.timings.chunkLoadPopulate.startTiming()) { // Paper - this.needsDecoration = false; - java.util.Random random = new java.util.Random(); - random.setSeed(this.level.getSeed()); -@@ -646,6 +647,7 @@ public class LevelChunk extends ChunkAccess { - } - } - server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(bukkitChunk)); -+ } // Paper - } - } - } -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index d1b82dec25069a7027aaf53086b1829e511fc301..4367ccc628bb4f404d6a081083002518442f462b 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -@@ -576,15 +576,12 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun - @Nullable - private static LevelChunk.PostLoadProcessor postLoadChunk(ServerLevel world, List entities, List blockEntities) { - return entities.isEmpty() && blockEntities.isEmpty() ? null : (chunk) -> { -- world.timings.syncChunkLoadEntitiesTimer.startTiming(); // Spigot - if (!entities.isEmpty()) { - world.addLegacyChunkEntities(EntityType.loadEntitiesRecursive(entities, world, EntitySpawnReason.LOAD)); - } -- world.timings.syncChunkLoadEntitiesTimer.stopTiming(); // Spigot - - Iterator iterator = blockEntities.iterator(); - -- world.timings.syncChunkLoadTileEntitiesTimer.startTiming(); // Spigot - while (iterator.hasNext()) { - CompoundTag nbttagcompound = (CompoundTag) iterator.next(); - boolean flag = nbttagcompound.getBoolean("keepPacked"); -@@ -600,7 +597,6 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun - } - } - } -- world.timings.syncChunkLoadTileEntitiesTimer.stopTiming(); // Spigot - - }; - } -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 9bf8c4d9154c433e586f59587e8d7db7c310bb9c..232a21080ff416ac5b9fdf913f6784eb3bcdacfa 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -379,7 +379,7 @@ public final class CraftServer implements Server { - this.saveCommandsConfig(); - this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*"); - this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions"); -- this.pluginManager.useTimings(this.configuration.getBoolean("settings.plugin-profiling")); -+ //this.pluginManager.useTimings(this.configuration.getBoolean("settings.plugin-profiling")); // Paper - we already moved this - this.overrideSpawnLimits(); - console.autosavePeriod = this.configuration.getInt("ticks-per.autosave"); - this.warningState = WarningState.value(this.configuration.getString("settings.deprecated-verbose")); -@@ -2636,12 +2636,31 @@ public final class CraftServer implements Server { - private final org.bukkit.Server.Spigot spigot = new org.bukkit.Server.Spigot() - { - -+ @Deprecated - @Override - public YamlConfiguration getConfig() - { - return org.spigotmc.SpigotConfig.config; - } - -+ @Override -+ public YamlConfiguration getBukkitConfig() -+ { -+ return configuration; -+ } -+ -+ @Override -+ public YamlConfiguration getSpigotConfig() -+ { -+ return org.spigotmc.SpigotConfig.config; -+ } -+ -+ @Override -+ public YamlConfiguration getPaperConfig() -+ { -+ return CraftServer.this.console.paperConfigurations.createLegacyObject(CraftServer.this.console); -+ } -+ - @Override - public void restart() { - org.spigotmc.RestartCommand.restart(); -diff --git a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java -deleted file mode 100644 -index b0ffa23faf62629043dfd613315eaf9c5fcc2cfe..0000000000000000000000000000000000000000 ---- a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java -+++ /dev/null -@@ -1,163 +0,0 @@ --package org.bukkit.craftbukkit; -- --import java.util.HashMap; --import net.minecraft.world.entity.Entity; --import net.minecraft.world.level.Level; --import net.minecraft.world.level.block.entity.BlockEntity; --import net.minecraft.world.level.storage.PrimaryLevelData; --import org.bukkit.craftbukkit.scheduler.CraftTask; --import org.bukkit.plugin.java.JavaPluginLoader; --import org.bukkit.scheduler.BukkitTask; --import org.spigotmc.CustomTimingsHandler; -- --public class SpigotTimings { -- -- public static final CustomTimingsHandler serverTickTimer = new CustomTimingsHandler("** Full Server Tick"); -- public static final CustomTimingsHandler playerListTimer = new CustomTimingsHandler("Player List"); -- public static final CustomTimingsHandler commandFunctionsTimer = new CustomTimingsHandler("Command Functions"); -- public static final CustomTimingsHandler connectionTimer = new CustomTimingsHandler("Connection Handler"); -- public static final CustomTimingsHandler playerConnectionTimer = new CustomTimingsHandler("** PlayerConnection"); -- public static final CustomTimingsHandler tickablesTimer = new CustomTimingsHandler("Tickables"); -- public static final CustomTimingsHandler schedulerTimer = new CustomTimingsHandler("Scheduler"); -- public static final CustomTimingsHandler timeUpdateTimer = new CustomTimingsHandler("Time Update"); -- public static final CustomTimingsHandler serverCommandTimer = new CustomTimingsHandler("Server Command"); -- public static final CustomTimingsHandler worldSaveTimer = new CustomTimingsHandler("World Save"); -- -- public static final CustomTimingsHandler entityMoveTimer = new CustomTimingsHandler("** entityMove"); -- public static final CustomTimingsHandler tickEntityTimer = new CustomTimingsHandler("** tickEntity"); -- public static final CustomTimingsHandler activatedEntityTimer = new CustomTimingsHandler("** activatedTickEntity"); -- public static final CustomTimingsHandler tickTileEntityTimer = new CustomTimingsHandler("** tickTileEntity"); -- -- public static final CustomTimingsHandler timerEntityBaseTick = new CustomTimingsHandler("** livingEntityBaseTick"); -- public static final CustomTimingsHandler timerEntityAI = new CustomTimingsHandler("** livingEntityAI"); -- public static final CustomTimingsHandler timerEntityAICollision = new CustomTimingsHandler("** livingEntityAICollision"); -- public static final CustomTimingsHandler timerEntityAIMove = new CustomTimingsHandler("** livingEntityAIMove"); -- public static final CustomTimingsHandler timerEntityTickRest = new CustomTimingsHandler("** livingEntityTickRest"); -- -- public static final CustomTimingsHandler processQueueTimer = new CustomTimingsHandler("processQueue"); -- public static final CustomTimingsHandler schedulerSyncTimer = new CustomTimingsHandler("** Scheduler - Sync Tasks", JavaPluginLoader.pluginParentTimer); -- -- public static final CustomTimingsHandler playerCommandTimer = new CustomTimingsHandler("** playerCommand"); -- -- public static final CustomTimingsHandler entityActivationCheckTimer = new CustomTimingsHandler("entityActivationCheck"); -- public static final CustomTimingsHandler checkIfActiveTimer = new CustomTimingsHandler("** checkIfActive"); -- -- public static final HashMap entityTypeTimingMap = new HashMap(); -- public static final HashMap tileEntityTypeTimingMap = new HashMap(); -- public static final HashMap pluginTaskTimingMap = new HashMap(); -- -- /** -- * Gets a timer associated with a plugins tasks. -- * @param task -- * @param period -- * @return -- */ -- public static CustomTimingsHandler getPluginTaskTimings(BukkitTask task, long period) { -- if (!task.isSync()) { -- return null; -- } -- String plugin; -- final CraftTask ctask = (CraftTask) task; -- -- if (task.getOwner() != null) { -- plugin = task.getOwner().getDescription().getFullName(); -- } else { -- plugin = "Unknown"; -- } -- String taskname = ctask.getTaskName(); -- -- String name = "Task: " + plugin + " Runnable: " + taskname; -- if (period > 0) { -- name += "(interval:" + period + ")"; -- } else { -- name += "(Single)"; -- } -- CustomTimingsHandler result = SpigotTimings.pluginTaskTimingMap.get(name); -- if (result == null) { -- result = new CustomTimingsHandler(name, SpigotTimings.schedulerSyncTimer); -- SpigotTimings.pluginTaskTimingMap.put(name, result); -- } -- return result; -- } -- -- /** -- * Get a named timer for the specified entity type to track type specific timings. -- * @param entity -- * @return -- */ -- public static CustomTimingsHandler getEntityTimings(Entity entity) { -- String entityType = entity.getClass().getName(); -- CustomTimingsHandler result = SpigotTimings.entityTypeTimingMap.get(entityType); -- if (result == null) { -- result = new CustomTimingsHandler("** tickEntity - " + entity.getClass().getSimpleName(), SpigotTimings.activatedEntityTimer); -- SpigotTimings.entityTypeTimingMap.put(entityType, result); -- } -- return result; -- } -- -- /** -- * Get a named timer for the specified tile entity type to track type specific timings. -- * @param entity -- * @return -- */ -- public static CustomTimingsHandler getTileEntityTimings(BlockEntity entity) { -- String entityType = entity.getClass().getName(); -- CustomTimingsHandler result = SpigotTimings.tileEntityTypeTimingMap.get(entityType); -- if (result == null) { -- result = new CustomTimingsHandler("** tickTileEntity - " + entity.getClass().getSimpleName(), SpigotTimings.tickTileEntityTimer); -- SpigotTimings.tileEntityTypeTimingMap.put(entityType, result); -- } -- return result; -- } -- -- /** -- * Set of timers per world, to track world specific timings. -- */ -- public static class WorldTimingsHandler { -- public final CustomTimingsHandler mobSpawn; -- public final CustomTimingsHandler doChunkUnload; -- public final CustomTimingsHandler doTickPending; -- public final CustomTimingsHandler doTickTiles; -- public final CustomTimingsHandler doChunkMap; -- public final CustomTimingsHandler doSounds; -- public final CustomTimingsHandler entityTick; -- public final CustomTimingsHandler tileEntityTick; -- public final CustomTimingsHandler tileEntityPending; -- public final CustomTimingsHandler tracker; -- public final CustomTimingsHandler doTick; -- public final CustomTimingsHandler tickEntities; -- -- public final CustomTimingsHandler syncChunkLoadTimer; -- public final CustomTimingsHandler syncChunkLoadStructuresTimer; -- public final CustomTimingsHandler syncChunkLoadEntitiesTimer; -- public final CustomTimingsHandler syncChunkLoadTileEntitiesTimer; -- public final CustomTimingsHandler syncChunkLoadTileTicksTimer; -- public final CustomTimingsHandler syncChunkLoadPostTimer; -- -- public WorldTimingsHandler(Level server) { -- String name = ((PrimaryLevelData) server.levelData).getLevelName() + " - "; -- -- this.mobSpawn = new CustomTimingsHandler("** " + name + "mobSpawn"); -- this.doChunkUnload = new CustomTimingsHandler("** " + name + "doChunkUnload"); -- this.doTickPending = new CustomTimingsHandler("** " + name + "doTickPending"); -- this.doTickTiles = new CustomTimingsHandler("** " + name + "doTickTiles"); -- this.doChunkMap = new CustomTimingsHandler("** " + name + "doChunkMap"); -- this.doSounds = new CustomTimingsHandler("** " + name + "doSounds"); -- this.entityTick = new CustomTimingsHandler("** " + name + "entityTick"); -- this.tileEntityTick = new CustomTimingsHandler("** " + name + "tileEntityTick"); -- this.tileEntityPending = new CustomTimingsHandler("** " + name + "tileEntityPending"); -- -- this.syncChunkLoadTimer = new CustomTimingsHandler("** " + name + "syncChunkLoad"); -- this.syncChunkLoadStructuresTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Structures"); -- this.syncChunkLoadEntitiesTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Entities"); -- this.syncChunkLoadTileEntitiesTimer = new CustomTimingsHandler("** " + name + "chunkLoad - TileEntities"); -- this.syncChunkLoadTileTicksTimer = new CustomTimingsHandler("** " + name + "chunkLoad - TileTicks"); -- this.syncChunkLoadPostTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Post"); -- -- -- this.tracker = new CustomTimingsHandler(name + "tracker"); -- this.doTick = new CustomTimingsHandler(name + "doTick"); -- this.tickEntities = new CustomTimingsHandler(name + "tickEntities"); -- } -- } --} -diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 24631135f90bb74bf829160ed079e152573666a2..f7833cd528797ba46b001db5208c29eb11ae2529 100644 ---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2809,6 +2809,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { - - CraftPlayer.this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundSystemChatPacket(components, position == net.md_5.bungee.api.ChatMessageType.ACTION_BAR)); - } -+ -+ // Paper start -+ @Override -+ public int getPing() -+ { -+ return CraftPlayer.this.getPing(); -+ } -+ // Paper end - }; - - public Player.Spigot spigot() -diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -index 6effe47b32a8551aa6f6b11bc0315714a119e199..4c376f67ae311b4fedea27b3475f9fb56054aec2 100644 ---- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -@@ -1,5 +1,6 @@ - package org.bukkit.craftbukkit.scheduler; - -+import co.aikar.timings.MinecraftTimings; // Paper - import com.google.common.base.Preconditions; - import com.google.common.util.concurrent.ThreadFactoryBuilder; - import java.util.ArrayList; -@@ -271,7 +272,7 @@ public class CraftScheduler implements BukkitScheduler { - } - return false; - } -- }); -+ }){{this.timings=co.aikar.timings.MinecraftTimings.getCancelTasksTimer();}}; // Paper - this.handle(task, 0L); - for (CraftTask taskPending = this.head.getNext(); taskPending != null; taskPending = taskPending.getNext()) { - if (taskPending == task) { -@@ -306,7 +307,7 @@ public class CraftScheduler implements BukkitScheduler { - } - } - } -- }); -+ }){{this.timings=co.aikar.timings.MinecraftTimings.getCancelTasksTimer(plugin);}}; // Paper - this.handle(task, 0L); - for (CraftTask taskPending = this.head.getNext(); taskPending != null; taskPending = taskPending.getNext()) { - if (taskPending == task) { -@@ -413,9 +414,7 @@ public class CraftScheduler implements BukkitScheduler { - if (task.isSync()) { - this.currentTask = task; - try { -- task.timings.startTiming(); // Spigot - task.run(); -- task.timings.stopTiming(); // Spigot - } catch (final Throwable throwable) { - task.getOwner().getLogger().log( - Level.WARNING, -@@ -442,8 +441,10 @@ public class CraftScheduler implements BukkitScheduler { - this.runners.remove(task.getTaskId()); - } - } -+ MinecraftTimings.bukkitSchedulerFinishTimer.startTiming(); // Paper - this.pending.addAll(temp); - temp.clear(); -+ MinecraftTimings.bukkitSchedulerFinishTimer.stopTiming(); // Paper - this.debugHead = this.debugHead.getNextHead(this.currentTick); - } - -@@ -480,6 +481,7 @@ public class CraftScheduler implements BukkitScheduler { - } - - private void parsePending() { -+ MinecraftTimings.bukkitSchedulerPendingTimer.startTiming(); - CraftTask head = this.head; - CraftTask task = head.getNext(); - CraftTask lastTask = head; -@@ -498,6 +500,7 @@ public class CraftScheduler implements BukkitScheduler { - task.setNext(null); - } - this.head = lastTask; -+ MinecraftTimings.bukkitSchedulerPendingTimer.stopTiming(); - } - - private boolean isReady(final int currentTick) { -diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java -index e4d1eb4a0ce2c9874922585f6bb0d9ead433fde1..ba369f3dcfdf498e971dc4405d39657a9b6e97cc 100644 ---- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java -+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java -@@ -1,12 +1,15 @@ - package org.bukkit.craftbukkit.scheduler; - - import java.util.function.Consumer; -+ -+import co.aikar.timings.NullTimingHandler; - import org.bukkit.Bukkit; - import org.bukkit.plugin.Plugin; - import org.bukkit.scheduler.BukkitTask; - --import org.bukkit.craftbukkit.SpigotTimings; // Spigot - import org.spigotmc.CustomTimingsHandler; // Spigot -+import co.aikar.timings.MinecraftTimings; // Paper -+import co.aikar.timings.Timing; // Paper - - public class CraftTask implements BukkitTask, Runnable { // Spigot - -@@ -26,13 +29,13 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot - */ - private volatile long period; - private long nextRun; -- private final Runnable rTask; -- private final Consumer cTask; -+ public final Runnable rTask; // Paper -+ public final Consumer cTask; // Paper -+ public Timing timings; // Paper - private final Plugin plugin; - private final int id; - private final long createdAt = System.nanoTime(); - -- final CustomTimingsHandler timings; // Spigot - CraftTask() { - this(null, null, CraftTask.NO_REPEATING, CraftTask.NO_REPEATING); - } -@@ -58,7 +61,7 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot - } - this.id = id; - this.period = period; -- this.timings = this.isSync() ? SpigotTimings.getPluginTaskTimings(this, period) : null; // Spigot -+ timings = task != null ? MinecraftTimings.getPluginTaskTimings(this, period) : NullTimingHandler.NULL; // Paper - } - - @Override -@@ -78,11 +81,13 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot - - @Override - public void run() { -+ try (Timing ignored = timings.startTiming()) { // Paper - if (this.rTask != null) { - this.rTask.run(); - } else { - this.cTask.accept(this); - } -+ } // Paper - } - - long getCreatedAt() { -@@ -113,7 +118,7 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot - this.next = next; - } - -- Class getTaskClass() { -+ public Class getTaskClass() { // Paper - return (this.rTask != null) ? this.rTask.getClass() : ((this.cTask != null) ? this.cTask.getClass() : null); - } - -@@ -137,9 +142,4 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot - return true; - } - -- // Spigot start -- public String getTaskName() { -- return (this.getTaskClass() == null) ? "Unknown" : this.getTaskClass().getName(); -- } -- // Spigot end - } -diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java b/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java -index f97eccb6a17c7876e1e002d798eb67bbe80571a0..76effc345d362047e64d064eb64a5222612aec14 100644 ---- a/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java -+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java -@@ -8,4 +8,11 @@ public class CraftIconCache implements CachedServerIcon { - public CraftIconCache(final byte[] value) { - this.value = value; - } -+ -+ public String getData() { -+ if (value == null) { -+ return null; -+ } -+ return "data:image/png;base64," + new String(java.util.Base64.getEncoder().encode(value), java.nio.charset.StandardCharsets.UTF_8); -+ } // Paper - } -diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 4b2377a1de608b9142a28c66389d04290f7c0330..0285349c0e882c1d928240a7ece2f9cc9f4122f2 100644 ---- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -199,6 +199,12 @@ public final class CraftMagicNumbers implements UnsafeValues { - return CraftNamespacedKey.toMinecraft(mat.getKey()); - } - // ======================================================================== -+ // Paper start -+ @Override -+ public void reportTimings() { -+ co.aikar.timings.TimingsExport.reportTimings(); -+ } -+ // Paper end - - public static byte toLegacyData(BlockState data) { - return CraftLegacy.toLegacyData(data); -@@ -448,6 +454,12 @@ public final class CraftMagicNumbers implements UnsafeValues { - public DamageSource.Builder createDamageSourceBuilder(DamageType damageType) { - return new CraftDamageSourceBuilder(damageType); - } -+ // Paper start -+ @Override -+ public String getTimingsServerName() { -+ return io.papermc.paper.configuration.GlobalConfiguration.get().timings.serverName; -+ } -+ // Paper end - - @Override - public String get(Class aClass, String s) { -diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 3591b79481ac17bd02e59ac3c623d1c6991abd84..2122e044d99902d2aff86693aaa424a50b9f8a13 100644 ---- a/src/main/java/org/spigotmc/ActivationRange.java -+++ b/src/main/java/org/spigotmc/ActivationRange.java -@@ -27,7 +27,7 @@ import net.minecraft.world.entity.projectile.ThrownTrident; - import net.minecraft.world.entity.raid.Raider; - import net.minecraft.world.level.Level; - import net.minecraft.world.phys.AABB; --import org.bukkit.craftbukkit.SpigotTimings; -+import co.aikar.timings.MinecraftTimings; - - public class ActivationRange - { -@@ -74,8 +74,8 @@ public class ActivationRange - /** - * These entities are excluded from Activation range checks. - * -- * @param entity -- * @param config -+ * @param entity Entity to initialize -+ * @param config Spigot config to determine ranges - * @return boolean If it should always tick. - */ - public static boolean initializeEntityActivationState(Entity entity, SpigotWorldConfig config) -@@ -110,7 +110,7 @@ public class ActivationRange - */ - public static void activateEntities(Level world) - { -- SpigotTimings.entityActivationCheckTimer.startTiming(); -+ MinecraftTimings.entityActivationCheckTimer.startTiming(); - final int miscActivationRange = world.spigotConfig.miscActivationRange; - final int raiderActivationRange = world.spigotConfig.raiderActivationRange; - final int animalActivationRange = world.spigotConfig.animalActivationRange; -@@ -137,7 +137,7 @@ public class ActivationRange - - world.getEntities().get(ActivationRange.maxBB, ActivationRange::activateEntity); - } -- SpigotTimings.entityActivationCheckTimer.stopTiming(); -+ MinecraftTimings.entityActivationCheckTimer.stopTiming(); - } - - /** -@@ -232,10 +232,8 @@ public class ActivationRange - */ - public static boolean checkIfActive(Entity entity) - { -- SpigotTimings.checkIfActiveTimer.startTiming(); - // Never safe to skip fireworks or entities not yet added to chunk - if ( entity instanceof FireworkRocketEntity ) { -- SpigotTimings.checkIfActiveTimer.stopTiming(); - return true; - } - -@@ -259,7 +257,6 @@ public class ActivationRange - { - isActive = false; - } -- SpigotTimings.checkIfActiveTimer.stopTiming(); - return isActive; - } - } diff --git a/patches/server/0024-Remove-Spigot-timings.patch b/patches/server/0024-Remove-Spigot-timings.patch new file mode 100644 index 000000000000..6913a8e21f09 --- /dev/null +++ b/patches/server/0024-Remove-Spigot-timings.patch @@ -0,0 +1,967 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Thu, 3 Mar 2016 04:00:11 -0600 +Subject: [PATCH] Remove Spigot timings + + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 4a573e8b7cd90f65c190982662e92a11f79a1d3e..709c6361aa5eb78071ce9d0f2a65ce8a56af1443 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -203,7 +203,6 @@ import org.bukkit.craftbukkit.Main; + import org.bukkit.event.server.ServerLoadEvent; + // CraftBukkit end + +-import org.bukkit.craftbukkit.SpigotTimings; // Spigot + + public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource { + +@@ -1456,7 +1455,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { + entityplayer.connection.suspendFlushing(); + }); +- SpigotTimings.schedulerTimer.startTiming(); // Spigot + this.server.getScheduler().mainThreadHeartbeat(); // CraftBukkit +- SpigotTimings.schedulerTimer.stopTiming(); // Spigot + io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.CALLBACK_MANAGER.handleQueue(this.tickCount); // Paper + gameprofilerfiller.push("commandFunctions"); +- SpigotTimings.commandFunctionsTimer.startTiming(); // Spigot + this.getFunctions().tick(); +- SpigotTimings.commandFunctionsTimer.stopTiming(); // Spigot + gameprofilerfiller.popPush("levels"); + Iterator iterator = this.getAllLevels().iterator(); + + // CraftBukkit start + // Run tasks that are waiting on processing +- SpigotTimings.processQueueTimer.startTiming(); // Spigot + while (!this.processQueue.isEmpty()) { + this.processQueue.remove().run(); + } +- SpigotTimings.processQueueTimer.stopTiming(); // Spigot + +- SpigotTimings.timeUpdateTimer.startTiming(); // Spigot + // Send time updates to everyone, it will get the right time from the world the player is in. + if (this.tickCount % 20 == 0) { + for (int i = 0; i < this.getPlayerList().players.size(); ++i) { +@@ -1596,7 +1584,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> completablefuture = this.getChunkFutureMainThread(x, z, leastStatus, create); + ServerChunkCache.MainThreadExecutor chunkproviderserver_b = this.mainThreadProcessor; + + Objects.requireNonNull(completablefuture); + chunkproviderserver_b.managedBlock(completablefuture::isDone); +- this.level.timings.syncChunkLoadTimer.stopTiming(); // Spigot + ChunkResult chunkresult = (ChunkResult) completablefuture.join(); + ChunkAccess ichunkaccess1 = (ChunkAccess) chunkresult.orElse(null); // CraftBukkit - decompile error + +@@ -420,25 +418,19 @@ public class ServerChunkCache extends ChunkSource { + ProfilerFiller gameprofilerfiller = Profiler.get(); + + gameprofilerfiller.push("purge"); +- this.level.timings.doChunkMap.startTiming(); // Spigot + if (this.level.tickRateManager().runsNormally() || !tickChunks || this.level.spigotConfig.unloadFrozenChunks) { // Spigot + this.distanceManager.purgeStaleTickets(); + } + + this.runDistanceManagerUpdates(); +- this.level.timings.doChunkMap.stopTiming(); // Spigot + gameprofilerfiller.popPush("chunks"); + if (tickChunks) { + this.tickChunks(); +- this.level.timings.tracker.startTiming(); // Spigot + this.chunkMap.tick(); +- this.level.timings.tracker.stopTiming(); // Spigot + } + +- this.level.timings.doChunkUnload.startTiming(); // Spigot + gameprofilerfiller.popPush("unload"); + this.chunkMap.tick(shouldKeepTicking); +- this.level.timings.doChunkUnload.stopTiming(); // Spigot + gameprofilerfiller.pop(); + this.clearCache(); + } +@@ -531,9 +523,7 @@ public class ServerChunkCache extends ChunkSource { + } + + if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { +- this.level.timings.doTickTiles.startTiming(); // Spigot + this.level.tickChunk(chunk, k); +- this.level.timings.doTickTiles.stopTiming(); // Spigot + } + } + +diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java +index c6ded1ac73ddbc0336000f77c0f99fa20551a0de..f3633da64f990972cddc03f2fcfd34ced2955a7a 100644 +--- a/src/main/java/net/minecraft/server/level/ServerLevel.java ++++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +@@ -176,7 +176,6 @@ import net.minecraft.world.ticks.LevelTicks; + import org.slf4j.Logger; + import org.bukkit.Bukkit; + import org.bukkit.WeatherType; +-import org.bukkit.craftbukkit.SpigotTimings; // Spigot + import org.bukkit.craftbukkit.event.CraftEventFactory; + import org.bukkit.craftbukkit.generator.CustomWorldChunkManager; + import org.bukkit.craftbukkit.util.WorldUUID; +@@ -469,7 +468,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + } + + gameprofilerfiller.push("tickPending"); +- this.timings.doTickPending.startTiming(); // Spigot + if (!this.isDebug() && flag) { + j = this.getGameTime(); + gameprofilerfiller.push("blockTicks"); +@@ -478,7 +476,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + this.fluidTicks.tick(j, 65536, this::tickFluid); + gameprofilerfiller.pop(); + } +- this.timings.doTickPending.stopTiming(); // Spigot + + gameprofilerfiller.popPush("raid"); + if (flag) { +@@ -489,9 +486,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + this.getChunkSource().tick(shouldKeepTicking, true); + gameprofilerfiller.popPush("blockEvents"); + if (flag) { +- this.timings.doSounds.startTiming(); // Spigot + this.runBlockEvents(); +- this.timings.doSounds.stopTiming(); // Spigot + } + + this.handlingTick = false; +@@ -504,7 +499,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + + if (flag1 || this.emptyTime++ < 300) { + gameprofilerfiller.push("entities"); +- this.timings.tickEntities.startTiming(); // Spigot + if (this.dragonFight != null && flag) { + gameprofilerfiller.push("dragonFight"); + this.dragonFight.tick(); +@@ -512,7 +506,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + } + + org.spigotmc.ActivationRange.activateEntities(this); // Spigot +- this.timings.entityTick.startTiming(); // Spigot + this.entityTickList.forEach((entity) -> { + if (!entity.isRemoved()) { + if (!tickratemanager.isEntityFrozen(entity)) { +@@ -537,8 +530,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + } + } + }); +- this.timings.entityTick.stopTiming(); // Spigot +- this.timings.tickEntities.stopTiming(); // Spigot + gameprofilerfiller.pop(); + this.tickBlockEntities(); + } +@@ -951,7 +942,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + return; + } + // Spigot end +- entity.tickTimer.startTiming(); // Spigot + entity.setOldPosAndRot(); + ProfilerFiller gameprofilerfiller = Profiler.get(); + +@@ -970,7 +960,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + + this.tickPassenger(entity, entity1); + } +- entity.tickTimer.stopTiming(); // Spigot + + } + +diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index 18d56058073b6cc4f9020f0a6137e4ac26eed0b2..fddc6b5abbad66ebe556ff8565c38c60b7883fce 100644 +--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -339,7 +339,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + + @Override + public void tick() { +- org.bukkit.craftbukkit.SpigotTimings.playerConnectionTimer.startTiming(); // Spigot + if (this.ackBlockChangesUpTo > -1) { + this.send(new ClientboundBlockChangedAckPacket(this.ackBlockChangesUpTo)); + this.ackBlockChangesUpTo = -1; +@@ -395,7 +394,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 + this.disconnect((Component) Component.translatable("multiplayer.disconnect.idling")); + } +- org.bukkit.craftbukkit.SpigotTimings.playerConnectionTimer.stopTiming(); // Spigot + + } + +@@ -2122,7 +2120,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + } + + private void handleCommand(String s) { +- org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.startTiming(); // Spigot + if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot + this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s); + +@@ -2132,7 +2129,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + this.cserver.getPluginManager().callEvent(event); + + if (event.isCancelled()) { +- org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot + return; + } + +@@ -2145,7 +2141,6 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + java.util.logging.Logger.getLogger(ServerGamePacketListenerImpl.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + return; + } finally { +- org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot + } + } + // CraftBukkit end +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index c010d18061f58a583c69e85fc29305497523f569..c8b8102d84119dfb6093f4b79aa3124c594f9a88 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -148,7 +148,6 @@ import org.bukkit.command.CommandSender; + import org.bukkit.entity.Hanging; + import org.bukkit.entity.LivingEntity; + import org.bukkit.entity.Vehicle; +-import org.spigotmc.CustomTimingsHandler; // Spigot + import org.bukkit.event.entity.EntityCombustByEntityEvent; + import org.bukkit.event.hanging.HangingBreakByEntityEvent; + import org.bukkit.event.vehicle.VehicleBlockCollisionEvent; +@@ -326,7 +325,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + // Marks an entity, that it was removed by a plugin via Entity#remove + // Main use case currently is for SPIGOT-7487, preventing dropping of leash when leash is removed + public boolean pluginRemoved = false; +- public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getEntityTimings(this); // Spigot + // Spigot start + public final org.spigotmc.ActivationRange.ActivationType activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this); + public final boolean defaultActivationState; +@@ -866,7 +864,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + + public void move(MoverType type, Vec3 movement) { +- org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.startTiming(); // Spigot + if (this.noPhysics) { + this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z); + } else { +@@ -978,7 +975,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + gameprofilerfiller.pop(); + } + } +- org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.stopTiming(); // Spigot + } + + private void applyMovementEmissionAndPlaySound(Entity.MovementEmission moveEffect, Vec3 movement, BlockPos landingPos, BlockState landingState) { +diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java +index 9aa4e70f1d1c4de2138d31701dceaed25062e69c..6dba567e9f7a197af16598647f216b5323d1b601 100644 +--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java ++++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java +@@ -162,8 +162,6 @@ import org.bukkit.event.entity.EntityTeleportEvent; + import org.bukkit.event.player.PlayerItemConsumeEvent; + // CraftBukkit end + +-import org.bukkit.craftbukkit.SpigotTimings; // Spigot +- + public abstract class LivingEntity extends Entity implements Attackable { + + private static final Logger LOGGER = LogUtils.getLogger(); +@@ -3090,7 +3088,6 @@ public abstract class LivingEntity extends Entity implements Attackable { + + @Override + public void tick() { +- SpigotTimings.timerEntityBaseTick.startTiming(); // Spigot + super.tick(); + this.updatingUsingItem(); + this.updateSwimAmount(); +@@ -3132,9 +3129,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + } + + if (!this.isRemoved()) { +- SpigotTimings.timerEntityBaseTick.stopTiming(); // Spigot + this.aiStep(); +- SpigotTimings.timerEntityTickRest.startTiming(); // Spigot + } + + double d0 = this.getX() - this.xo; +@@ -3228,7 +3223,6 @@ public abstract class LivingEntity extends Entity implements Attackable { + } + + this.elytraAnimationState.tick(); +- SpigotTimings.timerEntityTickRest.stopTiming(); // Spigot + } + + public void detectEquipmentUpdatesPublic() { // CraftBukkit +@@ -3435,7 +3429,6 @@ public abstract class LivingEntity extends Entity implements Attackable { + ProfilerFiller gameprofilerfiller = Profiler.get(); + + gameprofilerfiller.push("ai"); +- SpigotTimings.timerEntityAI.startTiming(); // Spigot + if (this.isImmobile()) { + this.jumping = false; + this.xxa = 0.0F; +@@ -3445,7 +3438,6 @@ public abstract class LivingEntity extends Entity implements Attackable { + this.serverAiStep(); + gameprofilerfiller.pop(); + } +- SpigotTimings.timerEntityAI.stopTiming(); // Spigot + + gameprofilerfiller.pop(); + gameprofilerfiller.push("jump"); +@@ -3488,7 +3480,6 @@ public abstract class LivingEntity extends Entity implements Attackable { + this.resetFallDistance(); + } + +- SpigotTimings.timerEntityAIMove.startTiming(); // Spigot + label112: + { + LivingEntity entityliving = this.getControllingPassenger(); +@@ -3502,7 +3493,6 @@ public abstract class LivingEntity extends Entity implements Attackable { + + this.travel(vec3d1); + } +- SpigotTimings.timerEntityAIMove.stopTiming(); // Spigot + + if (!this.level().isClientSide() || this.isControlledByLocalInstance()) { + this.applyEffectsFromBlocks(); +@@ -3538,9 +3528,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + this.checkAutoSpinAttack(axisalignedbb, this.getBoundingBox()); + } + +- SpigotTimings.timerEntityAICollision.startTiming(); // Spigot + this.pushEntities(); +- SpigotTimings.timerEntityAICollision.stopTiming(); // Spigot + gameprofilerfiller.pop(); + world = this.level(); + if (world instanceof ServerLevel worldserver) { +diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java +index 3fb17bbcecf6dc4af3b231835adff25f86e1379f..c5e480c43668211a091e44ae50b40b025ff1dca9 100644 +--- a/src/main/java/net/minecraft/world/level/Level.java ++++ b/src/main/java/net/minecraft/world/level/Level.java +@@ -95,7 +95,6 @@ import net.minecraft.network.protocol.game.ClientboundSetBorderWarningDistancePa + import org.bukkit.Bukkit; + import org.bukkit.craftbukkit.CraftServer; + import org.bukkit.craftbukkit.CraftWorld; +-import org.bukkit.craftbukkit.SpigotTimings; // Spigot + import org.bukkit.craftbukkit.block.CapturedBlockState; + import org.bukkit.craftbukkit.block.CraftBlockState; + import org.bukkit.craftbukkit.block.data.CraftBlockData; +@@ -165,7 +164,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + } + // Paper end - add paper world config + +- public final SpigotTimings.WorldTimingsHandler timings; // Spigot + public static BlockPos lastPhysicsProblem; // Spigot + private org.spigotmc.TickLimiter entityLimiter; + private org.spigotmc.TickLimiter tileLimiter; +@@ -259,7 +257,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + public void onBorderSetDamageSafeZOne(WorldBorder border, double safeZoneRadius) {} + }); + // CraftBukkit end +- this.timings = new SpigotTimings.WorldTimingsHandler(this); // Spigot - code below can generate new world and access timings + this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime); + this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); + } +@@ -692,15 +689,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + ProfilerFiller gameprofilerfiller = Profiler.get(); + + gameprofilerfiller.push("blockEntities"); +- this.timings.tileEntityPending.startTiming(); // Spigot + this.tickingBlockEntities = true; + if (!this.pendingBlockEntityTickers.isEmpty()) { + this.blockEntityTickers.addAll(this.pendingBlockEntityTickers); + this.pendingBlockEntityTickers.clear(); + } +- this.timings.tileEntityPending.stopTiming(); // Spigot + +- this.timings.tileEntityTick.startTiming(); // Spigot + // Spigot start + // Iterator iterator = this.blockEntityTickers.iterator(); + boolean flag = this.tickRateManager().runsNormally(); +@@ -723,7 +717,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + } + } + +- this.timings.tileEntityTick.stopTiming(); // Spigot + this.tickingBlockEntities = false; + gameprofilerfiller.pop(); + this.spigotConfig.currentPrimedTnt = 0; // Spigot +@@ -731,9 +724,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + + public void guardEntityTick(Consumer tickConsumer, T entity) { + try { +- SpigotTimings.tickEntityTimer.startTiming(); // Spigot + tickConsumer.accept(entity); +- SpigotTimings.tickEntityTimer.stopTiming(); // Spigot + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking entity"); + CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being ticked"); +diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java +index 1fe93e01c5e37397aded5d1f99214bf1bffe70b7..9389fd53f2bff0a9ca389694b312dc6da58befaf 100644 +--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java ++++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java +@@ -148,7 +148,6 @@ public final class NaturalSpawner { + ProfilerFiller gameprofilerfiller = Profiler.get(); + + gameprofilerfiller.push("spawner"); +- world.timings.mobSpawn.startTiming(); // Spigot + Iterator iterator = spawnableGroups.iterator(); + + while (iterator.hasNext()) { +@@ -163,7 +162,6 @@ public final class NaturalSpawner { + } + } + +- world.timings.mobSpawn.stopTiming(); // Spigot + gameprofilerfiller.pop(); + } + +diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +index 4c3bc3a495990bc486fce7ba1758bf731c3baf02..751a5ae04e4de3f5d85eda20092a87ef4f547436 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +@@ -33,11 +33,8 @@ import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; + import org.bukkit.inventory.InventoryHolder; + // CraftBukkit end + +-import org.spigotmc.CustomTimingsHandler; // Spigot +- + public abstract class BlockEntity { + +- public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getTileEntityTimings(this); // Spigot + // CraftBukkit start - data containers + private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); + public CraftPersistentDataContainer persistentDataContainer; +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 d76591694c3b167b8b8f17b61a373a43140a8b68..f63d55bfe42b117c5b437e690124a98d94752a9a 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java ++++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +@@ -971,7 +971,6 @@ public class LevelChunk extends ChunkAccess { + ProfilerFiller gameprofilerfiller = Profiler.get(); + + gameprofilerfiller.push(this::getType); +- this.blockEntity.tickTimer.startTiming(); // Spigot + BlockState iblockdata = LevelChunk.this.getBlockState(blockposition); + + if (this.blockEntity.getType().isValid(iblockdata)) { +@@ -990,9 +989,6 @@ public class LevelChunk extends ChunkAccess { + this.blockEntity.fillCrashReportCategory(crashreportsystemdetails); + throw new ReportedException(crashreport); + // Spigot start +- } finally { +- this.blockEntity.tickTimer.stopTiming(); +- // Spigot end + } + } + } +diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +index d1b82dec25069a7027aaf53086b1829e511fc301..4367ccc628bb4f404d6a081083002518442f462b 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java ++++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +@@ -576,15 +576,12 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + @Nullable + private static LevelChunk.PostLoadProcessor postLoadChunk(ServerLevel world, List entities, List blockEntities) { + return entities.isEmpty() && blockEntities.isEmpty() ? null : (chunk) -> { +- world.timings.syncChunkLoadEntitiesTimer.startTiming(); // Spigot + if (!entities.isEmpty()) { + world.addLegacyChunkEntities(EntityType.loadEntitiesRecursive(entities, world, EntitySpawnReason.LOAD)); + } +- world.timings.syncChunkLoadEntitiesTimer.stopTiming(); // Spigot + + Iterator iterator = blockEntities.iterator(); + +- world.timings.syncChunkLoadTileEntitiesTimer.startTiming(); // Spigot + while (iterator.hasNext()) { + CompoundTag nbttagcompound = (CompoundTag) iterator.next(); + boolean flag = nbttagcompound.getBoolean("keepPacked"); +@@ -600,7 +597,6 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + } + } + } +- world.timings.syncChunkLoadTileEntitiesTimer.stopTiming(); // Spigot + + }; + } +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index 7c5b0db8115dc4032a3a364299ca06c88efd9a26..5650b4cfcd4008ac7f351d5bfb1fb8cc81da4caa 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -379,7 +379,6 @@ public final class CraftServer implements Server { + this.saveCommandsConfig(); + this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*"); + this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions"); +- this.pluginManager.useTimings(this.configuration.getBoolean("settings.plugin-profiling")); + this.overrideSpawnLimits(); + console.autosavePeriod = this.configuration.getInt("ticks-per.autosave"); + this.warningState = WarningState.value(this.configuration.getString("settings.deprecated-verbose")); +@@ -2636,12 +2635,31 @@ public final class CraftServer implements Server { + private final org.bukkit.Server.Spigot spigot = new org.bukkit.Server.Spigot() + { + ++ @Deprecated + @Override + public YamlConfiguration getConfig() + { + return org.spigotmc.SpigotConfig.config; + } + ++ @Override ++ public YamlConfiguration getBukkitConfig() ++ { ++ return configuration; ++ } ++ ++ @Override ++ public YamlConfiguration getSpigotConfig() ++ { ++ return org.spigotmc.SpigotConfig.config; ++ } ++ ++ @Override ++ public YamlConfiguration getPaperConfig() ++ { ++ return CraftServer.this.console.paperConfigurations.createLegacyObject(CraftServer.this.console); ++ } ++ + @Override + public void restart() { + org.spigotmc.RestartCommand.restart(); +diff --git a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java +deleted file mode 100644 +index b0ffa23faf62629043dfd613315eaf9c5fcc2cfe..0000000000000000000000000000000000000000 +--- a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java ++++ /dev/null +@@ -1,163 +0,0 @@ +-package org.bukkit.craftbukkit; +- +-import java.util.HashMap; +-import net.minecraft.world.entity.Entity; +-import net.minecraft.world.level.Level; +-import net.minecraft.world.level.block.entity.BlockEntity; +-import net.minecraft.world.level.storage.PrimaryLevelData; +-import org.bukkit.craftbukkit.scheduler.CraftTask; +-import org.bukkit.plugin.java.JavaPluginLoader; +-import org.bukkit.scheduler.BukkitTask; +-import org.spigotmc.CustomTimingsHandler; +- +-public class SpigotTimings { +- +- public static final CustomTimingsHandler serverTickTimer = new CustomTimingsHandler("** Full Server Tick"); +- public static final CustomTimingsHandler playerListTimer = new CustomTimingsHandler("Player List"); +- public static final CustomTimingsHandler commandFunctionsTimer = new CustomTimingsHandler("Command Functions"); +- public static final CustomTimingsHandler connectionTimer = new CustomTimingsHandler("Connection Handler"); +- public static final CustomTimingsHandler playerConnectionTimer = new CustomTimingsHandler("** PlayerConnection"); +- public static final CustomTimingsHandler tickablesTimer = new CustomTimingsHandler("Tickables"); +- public static final CustomTimingsHandler schedulerTimer = new CustomTimingsHandler("Scheduler"); +- public static final CustomTimingsHandler timeUpdateTimer = new CustomTimingsHandler("Time Update"); +- public static final CustomTimingsHandler serverCommandTimer = new CustomTimingsHandler("Server Command"); +- public static final CustomTimingsHandler worldSaveTimer = new CustomTimingsHandler("World Save"); +- +- public static final CustomTimingsHandler entityMoveTimer = new CustomTimingsHandler("** entityMove"); +- public static final CustomTimingsHandler tickEntityTimer = new CustomTimingsHandler("** tickEntity"); +- public static final CustomTimingsHandler activatedEntityTimer = new CustomTimingsHandler("** activatedTickEntity"); +- public static final CustomTimingsHandler tickTileEntityTimer = new CustomTimingsHandler("** tickTileEntity"); +- +- public static final CustomTimingsHandler timerEntityBaseTick = new CustomTimingsHandler("** livingEntityBaseTick"); +- public static final CustomTimingsHandler timerEntityAI = new CustomTimingsHandler("** livingEntityAI"); +- public static final CustomTimingsHandler timerEntityAICollision = new CustomTimingsHandler("** livingEntityAICollision"); +- public static final CustomTimingsHandler timerEntityAIMove = new CustomTimingsHandler("** livingEntityAIMove"); +- public static final CustomTimingsHandler timerEntityTickRest = new CustomTimingsHandler("** livingEntityTickRest"); +- +- public static final CustomTimingsHandler processQueueTimer = new CustomTimingsHandler("processQueue"); +- public static final CustomTimingsHandler schedulerSyncTimer = new CustomTimingsHandler("** Scheduler - Sync Tasks", JavaPluginLoader.pluginParentTimer); +- +- public static final CustomTimingsHandler playerCommandTimer = new CustomTimingsHandler("** playerCommand"); +- +- public static final CustomTimingsHandler entityActivationCheckTimer = new CustomTimingsHandler("entityActivationCheck"); +- public static final CustomTimingsHandler checkIfActiveTimer = new CustomTimingsHandler("** checkIfActive"); +- +- public static final HashMap entityTypeTimingMap = new HashMap(); +- public static final HashMap tileEntityTypeTimingMap = new HashMap(); +- public static final HashMap pluginTaskTimingMap = new HashMap(); +- +- /** +- * Gets a timer associated with a plugins tasks. +- * @param task +- * @param period +- * @return +- */ +- public static CustomTimingsHandler getPluginTaskTimings(BukkitTask task, long period) { +- if (!task.isSync()) { +- return null; +- } +- String plugin; +- final CraftTask ctask = (CraftTask) task; +- +- if (task.getOwner() != null) { +- plugin = task.getOwner().getDescription().getFullName(); +- } else { +- plugin = "Unknown"; +- } +- String taskname = ctask.getTaskName(); +- +- String name = "Task: " + plugin + " Runnable: " + taskname; +- if (period > 0) { +- name += "(interval:" + period + ")"; +- } else { +- name += "(Single)"; +- } +- CustomTimingsHandler result = SpigotTimings.pluginTaskTimingMap.get(name); +- if (result == null) { +- result = new CustomTimingsHandler(name, SpigotTimings.schedulerSyncTimer); +- SpigotTimings.pluginTaskTimingMap.put(name, result); +- } +- return result; +- } +- +- /** +- * Get a named timer for the specified entity type to track type specific timings. +- * @param entity +- * @return +- */ +- public static CustomTimingsHandler getEntityTimings(Entity entity) { +- String entityType = entity.getClass().getName(); +- CustomTimingsHandler result = SpigotTimings.entityTypeTimingMap.get(entityType); +- if (result == null) { +- result = new CustomTimingsHandler("** tickEntity - " + entity.getClass().getSimpleName(), SpigotTimings.activatedEntityTimer); +- SpigotTimings.entityTypeTimingMap.put(entityType, result); +- } +- return result; +- } +- +- /** +- * Get a named timer for the specified tile entity type to track type specific timings. +- * @param entity +- * @return +- */ +- public static CustomTimingsHandler getTileEntityTimings(BlockEntity entity) { +- String entityType = entity.getClass().getName(); +- CustomTimingsHandler result = SpigotTimings.tileEntityTypeTimingMap.get(entityType); +- if (result == null) { +- result = new CustomTimingsHandler("** tickTileEntity - " + entity.getClass().getSimpleName(), SpigotTimings.tickTileEntityTimer); +- SpigotTimings.tileEntityTypeTimingMap.put(entityType, result); +- } +- return result; +- } +- +- /** +- * Set of timers per world, to track world specific timings. +- */ +- public static class WorldTimingsHandler { +- public final CustomTimingsHandler mobSpawn; +- public final CustomTimingsHandler doChunkUnload; +- public final CustomTimingsHandler doTickPending; +- public final CustomTimingsHandler doTickTiles; +- public final CustomTimingsHandler doChunkMap; +- public final CustomTimingsHandler doSounds; +- public final CustomTimingsHandler entityTick; +- public final CustomTimingsHandler tileEntityTick; +- public final CustomTimingsHandler tileEntityPending; +- public final CustomTimingsHandler tracker; +- public final CustomTimingsHandler doTick; +- public final CustomTimingsHandler tickEntities; +- +- public final CustomTimingsHandler syncChunkLoadTimer; +- public final CustomTimingsHandler syncChunkLoadStructuresTimer; +- public final CustomTimingsHandler syncChunkLoadEntitiesTimer; +- public final CustomTimingsHandler syncChunkLoadTileEntitiesTimer; +- public final CustomTimingsHandler syncChunkLoadTileTicksTimer; +- public final CustomTimingsHandler syncChunkLoadPostTimer; +- +- public WorldTimingsHandler(Level server) { +- String name = ((PrimaryLevelData) server.levelData).getLevelName() + " - "; +- +- this.mobSpawn = new CustomTimingsHandler("** " + name + "mobSpawn"); +- this.doChunkUnload = new CustomTimingsHandler("** " + name + "doChunkUnload"); +- this.doTickPending = new CustomTimingsHandler("** " + name + "doTickPending"); +- this.doTickTiles = new CustomTimingsHandler("** " + name + "doTickTiles"); +- this.doChunkMap = new CustomTimingsHandler("** " + name + "doChunkMap"); +- this.doSounds = new CustomTimingsHandler("** " + name + "doSounds"); +- this.entityTick = new CustomTimingsHandler("** " + name + "entityTick"); +- this.tileEntityTick = new CustomTimingsHandler("** " + name + "tileEntityTick"); +- this.tileEntityPending = new CustomTimingsHandler("** " + name + "tileEntityPending"); +- +- this.syncChunkLoadTimer = new CustomTimingsHandler("** " + name + "syncChunkLoad"); +- this.syncChunkLoadStructuresTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Structures"); +- this.syncChunkLoadEntitiesTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Entities"); +- this.syncChunkLoadTileEntitiesTimer = new CustomTimingsHandler("** " + name + "chunkLoad - TileEntities"); +- this.syncChunkLoadTileTicksTimer = new CustomTimingsHandler("** " + name + "chunkLoad - TileTicks"); +- this.syncChunkLoadPostTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Post"); +- +- +- this.tracker = new CustomTimingsHandler(name + "tracker"); +- this.doTick = new CustomTimingsHandler(name + "doTick"); +- this.tickEntities = new CustomTimingsHandler(name + "tickEntities"); +- } +- } +-} +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 24631135f90bb74bf829160ed079e152573666a2..f7833cd528797ba46b001db5208c29eb11ae2529 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -2809,6 +2809,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + + CraftPlayer.this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundSystemChatPacket(components, position == net.md_5.bungee.api.ChatMessageType.ACTION_BAR)); + } ++ ++ // Paper start ++ @Override ++ public int getPing() ++ { ++ return CraftPlayer.this.getPing(); ++ } ++ // Paper end + }; + + public Player.Spigot spigot() +diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +index 6effe47b32a8551aa6f6b11bc0315714a119e199..2c36d0796714997191c6540c34a9df60718065f6 100644 +--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java ++++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +@@ -413,9 +413,7 @@ public class CraftScheduler implements BukkitScheduler { + if (task.isSync()) { + this.currentTask = task; + try { +- task.timings.startTiming(); // Spigot + task.run(); +- task.timings.stopTiming(); // Spigot + } catch (final Throwable throwable) { + task.getOwner().getLogger().log( + Level.WARNING, +diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java +index e4d1eb4a0ce2c9874922585f6bb0d9ead433fde1..17680f112d0c7e7aee07e34477daa21ef2ddaa6f 100644 +--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java ++++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java +@@ -1,13 +1,11 @@ + package org.bukkit.craftbukkit.scheduler; + + import java.util.function.Consumer; ++ + import org.bukkit.Bukkit; + import org.bukkit.plugin.Plugin; + import org.bukkit.scheduler.BukkitTask; + +-import org.bukkit.craftbukkit.SpigotTimings; // Spigot +-import org.spigotmc.CustomTimingsHandler; // Spigot +- + public class CraftTask implements BukkitTask, Runnable { // Spigot + + private volatile CraftTask next = null; +@@ -26,13 +24,12 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot + */ + private volatile long period; + private long nextRun; +- private final Runnable rTask; +- private final Consumer cTask; ++ public final Runnable rTask; ++ public final Consumer cTask; + private final Plugin plugin; + private final int id; + private final long createdAt = System.nanoTime(); + +- final CustomTimingsHandler timings; // Spigot + CraftTask() { + this(null, null, CraftTask.NO_REPEATING, CraftTask.NO_REPEATING); + } +@@ -58,7 +55,6 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot + } + this.id = id; + this.period = period; +- this.timings = this.isSync() ? SpigotTimings.getPluginTaskTimings(this, period) : null; // Spigot + } + + @Override +@@ -137,9 +133,4 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot + return true; + } + +- // Spigot start +- public String getTaskName() { +- return (this.getTaskClass() == null) ? "Unknown" : this.getTaskClass().getName(); +- } +- // Spigot end + } +diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java b/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java +index f97eccb6a17c7876e1e002d798eb67bbe80571a0..dba31a2cbcfebe1f28883545ce4a70fcb9251aa6 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java +@@ -1,6 +1,7 @@ + package org.bukkit.craftbukkit.util; + + import org.bukkit.util.CachedServerIcon; ++import org.jetbrains.annotations.Nullable; + + public class CraftIconCache implements CachedServerIcon { + public final byte[] value; +@@ -8,4 +9,12 @@ public class CraftIconCache implements CachedServerIcon { + public CraftIconCache(final byte[] value) { + this.value = value; + } ++ ++ @Override ++ public @Nullable String getData() { ++ if (this.value == null) { ++ return null; ++ } ++ return "data:image/png;base64," + new String(java.util.Base64.getEncoder().encode(this.value), java.nio.charset.StandardCharsets.UTF_8); ++ } + } +diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java +index 3591b79481ac17bd02e59ac3c623d1c6991abd84..263df52c7f5e172a6b9118b4bc4672e443adedba 100644 +--- a/src/main/java/org/spigotmc/ActivationRange.java ++++ b/src/main/java/org/spigotmc/ActivationRange.java +@@ -27,7 +27,6 @@ import net.minecraft.world.entity.projectile.ThrownTrident; + import net.minecraft.world.entity.raid.Raider; + import net.minecraft.world.level.Level; + import net.minecraft.world.phys.AABB; +-import org.bukkit.craftbukkit.SpigotTimings; + + public class ActivationRange + { +@@ -110,7 +109,6 @@ public class ActivationRange + */ + public static void activateEntities(Level world) + { +- SpigotTimings.entityActivationCheckTimer.startTiming(); + final int miscActivationRange = world.spigotConfig.miscActivationRange; + final int raiderActivationRange = world.spigotConfig.raiderActivationRange; + final int animalActivationRange = world.spigotConfig.animalActivationRange; +@@ -137,7 +135,6 @@ public class ActivationRange + + world.getEntities().get(ActivationRange.maxBB, ActivationRange::activateEntity); + } +- SpigotTimings.entityActivationCheckTimer.stopTiming(); + } + + /** +@@ -232,10 +229,8 @@ public class ActivationRange + */ + public static boolean checkIfActive(Entity entity) + { +- SpigotTimings.checkIfActiveTimer.startTiming(); + // Never safe to skip fireworks or entities not yet added to chunk + if ( entity instanceof FireworkRocketEntity ) { +- SpigotTimings.checkIfActiveTimer.stopTiming(); + return true; + } + +@@ -259,7 +254,6 @@ public class ActivationRange + { + isActive = false; + } +- SpigotTimings.checkIfActiveTimer.stopTiming(); + return isActive; + } + } diff --git a/patches/server/0025-Add-command-line-option-to-load-extra-plugin-jars-no.patch b/patches/server/0025-Add-command-line-option-to-load-extra-plugin-jars-no.patch index ef3594f35424..5e58214e0f38 100644 --- a/patches/server/0025-Add-command-line-option-to-load-extra-plugin-jars-no.patch +++ b/patches/server/0025-Add-command-line-option-to-load-extra-plugin-jars-no.patch @@ -7,10 +7,10 @@ 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 f7af198966928ac28bd7e2851caae93a27974e5c..10e1b6bf90b249a5dd04bb10f0a742cdedae0a01 100644 +index 5650b4cfcd4008ac7f351d5bfb1fb8cc81da4caa..db7cad60c8f805dd1b4089673f5f9d073a429a67 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -462,6 +462,35 @@ public final class CraftServer implements Server { +@@ -461,6 +461,35 @@ public final class CraftServer implements Server { io.papermc.paper.plugin.entrypoint.LaunchEntryPointHandler.INSTANCE.enter(io.papermc.paper.plugin.entrypoint.Entrypoint.PLUGIN); // Paper - replace implementation } diff --git a/patches/server/0033-Expose-server-build-information.patch b/patches/server/0033-Expose-server-build-information.patch index b560e277bd0f..83f13af41a6a 100644 --- a/patches/server/0033-Expose-server-build-information.patch +++ b/patches/server/0033-Expose-server-build-information.patch @@ -533,7 +533,7 @@ index 0000000000000000000000000000000000000000..790bad0494454ca12ee152e3de6da3da + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 31582d4f9d52c86cf834b9dc10e58b68c67f1272..5ce80e72ed677b464e7e7b2dcb616cdcb399686b 100644 +index 709c6361aa5eb78071ce9d0f2a65ce8a56af1443..b86d8a3756cb8c1adb1aceda57f60b0ccdb3f659 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -45,7 +45,6 @@ import java.util.Set; @@ -553,7 +553,7 @@ index 31582d4f9d52c86cf834b9dc10e58b68c67f1272..5ce80e72ed677b464e7e7b2dcb616cdc import org.bukkit.event.server.ServerLoadEvent; // CraftBukkit end -@@ -1784,7 +1781,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java index f697d45e0ac4e9cdc8a46121510a04c0f294d91f..e086765dec32241bc5a77afcf072c77a40c6d785 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java diff --git a/patches/server/0036-Entity-Origin-API.patch b/patches/server/0036-Entity-Origin-API.patch index e1281dbfae6d..47721fa03df7 100644 --- a/patches/server/0036-Entity-Origin-API.patch +++ b/patches/server/0036-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 a1565304c436258b561d97a6cc7aacecf68816b7..e2e949dbd8be52dc6a00414f0f79746ee554acd7 100644 +index f3633da64f990972cddc03f2fcfd34ced2955a7a..025363e6b51ff8aa089715b1ec2a0fa1caab65d6 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2212,6 +2212,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2182,6 +2182,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe entity.updateDynamicGameEventListener(DynamicGameEventListener::add); entity.inWorld = true; // CraftBukkit - Mark entity as in world entity.valid = true; // CraftBukkit diff --git a/patches/server/0037-Prevent-block-entity-and-entity-crashes.patch b/patches/server/0037-Prevent-block-entity-and-entity-crashes.patch index 01c8a71861fd..72263726831b 100644 --- a/patches/server/0037-Prevent-block-entity-and-entity-crashes.patch +++ b/patches/server/0037-Prevent-block-entity-and-entity-crashes.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent block entity and entity crashes diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 5df862e026e15e10e2fcc7c5a49e8a8022125579..d15c7ed69068ba5832c92860cae56ff4a96cd398 100644 +index c5e480c43668211a091e44ae50b40b025ff1dca9..071545e60f838fa6c930edc35f46e0ce9b73fb44 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -733,11 +733,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -726,11 +726,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { try { tickConsumer.accept(entity); } catch (Throwable throwable) { @@ -26,10 +26,10 @@ index 5df862e026e15e10e2fcc7c5a49e8a8022125579..d15c7ed69068ba5832c92860cae56ff4 } diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index 9afe509b3455a7aabd11976fb8a7430d1bce065d..4536632687e71b02d5945cac3816b72ac540935e 100644 +index 751a5ae04e4de3f5d85eda20092a87ef4f547436..3d7c5db5514f9d4401da22d2df88c5614051e568 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -273,7 +273,12 @@ public abstract class BlockEntity { +@@ -268,7 +268,12 @@ public abstract class BlockEntity { public void fillCrashReportCategory(CrashReportCategory crashReportSection) { crashReportSection.setDetail("Name", this::getNameForReporting); if (this.level != null) { @@ -44,10 +44,10 @@ index 9afe509b3455a7aabd11976fb8a7430d1bce065d..4536632687e71b02d5945cac3816b72a } } 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 717e4bf9f5ee0ec2c3a0b5cc65a50b0f6d649a8d..e1cd7497b1355030bf44b53aa30400604dff9aca 100644 +index f63d55bfe42b117c5b437e690124a98d94752a9a..79cf3089c128ef3c17d956da1e380670279ee5da 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -986,11 +986,11 @@ public class LevelChunk extends ChunkAccess { +@@ -983,11 +983,11 @@ public class LevelChunk extends ChunkAccess { gameprofilerfiller.pop(); } catch (Throwable throwable) { @@ -62,5 +62,5 @@ index 717e4bf9f5ee0ec2c3a0b5cc65a50b0f6d649a8d..e1cd7497b1355030bf44b53aa3040060 + LevelChunk.this.removeBlockEntity(this.getPos()); + // Paper end - Prevent block entity and entity crashes // Spigot start - } finally { - this.blockEntity.tickTimer.stopTiming(); + } + } diff --git a/patches/server/0040-Add-more-entities-to-activation-range-ignore-list.patch b/patches/server/0040-Add-more-entities-to-activation-range-ignore-list.patch index 9eaf33d852ef..2c4e1fe5780d 100644 --- a/patches/server/0040-Add-more-entities-to-activation-range-ignore-list.patch +++ b/patches/server/0040-Add-more-entities-to-activation-range-ignore-list.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add more entities to activation range ignore list diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 2122e044d99902d2aff86693aaa424a50b9f8a13..5dac9bdb23de3d143cd678e583eaf6e8095bb209 100644 +index 263df52c7f5e172a6b9118b4bc4672e443adedba..dd1c5bc7522a4710cbfdd4764f6431e1e28d63cc 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java -@@ -92,6 +92,9 @@ public class ActivationRange +@@ -91,6 +91,9 @@ public class ActivationRange || entity instanceof AbstractHurtingProjectile || entity instanceof LightningBolt || entity instanceof PrimedTnt diff --git a/patches/server/0043-Optimize-explosions.patch b/patches/server/0043-Optimize-explosions.patch index 78e4626f211f..a5a195040211 100644 --- a/patches/server/0043-Optimize-explosions.patch +++ b/patches/server/0043-Optimize-explosions.patch @@ -10,10 +10,10 @@ 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 5ce80e72ed677b464e7e7b2dcb616cdcb399686b..d04ce36f79523417c7c2b49a8324b52ef6a6f0f4 100644 +index b86d8a3756cb8c1adb1aceda57f60b0ccdb3f659..cc4c5fcbeca4862d8ff78b127cb3f2c07956dfaf 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -401,6 +401,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0) { diff --git a/patches/server/0052-Disable-spigot-tick-limiters.patch b/patches/server/0052-Disable-spigot-tick-limiters.patch index a588d23369b9..2872d59fb9a2 100644 --- a/patches/server/0052-Disable-spigot-tick-limiters.patch +++ b/patches/server/0052-Disable-spigot-tick-limiters.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Disable spigot tick limiters diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index a0b89abe50f4cea64f29e8957c535400658d4524..5fe8726af73eb5334f47046c93096341e987269b 100644 +index e90dac1e46bca60896b027f670ba521d67c02c1e..ed15f5c4a365a199d04e92d688035e4ab755e8db 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -706,9 +706,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -701,9 +701,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { boolean flag = this.tickRateManager().runsNormally(); int tilesThisCycle = 0; diff --git a/patches/server/0053-Fix-spawn-location-event-changing-location.patch b/patches/server/0053-Fix-spawn-location-event-changing-location.patch index 07448453cfe5..15086ed363cf 100644 --- a/patches/server/0053-Fix-spawn-location-event-changing-location.patch +++ b/patches/server/0053-Fix-spawn-location-event-changing-location.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Fix spawn location event changing location public net.minecraft.world.entity.Entity setRot(FF)V diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index b103d49458330be9f7fb3382c764b204a02a925a..2af4b853fde493c1fa5c8d530aae4d68b79f7ba0 100644 +index 56f046bac04205a813441907058c4ce21982d927..50b1e493a9adfa687dc22c66044c6aa243340b3f 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -235,7 +235,10 @@ public abstract class PlayerList { +@@ -234,7 +234,10 @@ public abstract class PlayerList { player.spawnIn(worldserver1); player.gameMode.setLevel((ServerLevel) player.level()); diff --git a/patches/server/0055-Improve-Player-chat-API-handling.patch b/patches/server/0055-Improve-Player-chat-API-handling.patch index c119f3275003..8c63e9bdb414 100644 --- a/patches/server/0055-Improve-Player-chat-API-handling.patch +++ b/patches/server/0055-Improve-Player-chat-API-handling.patch @@ -17,7 +17,7 @@ Co-authored-by: Jake Potrebic Co-authored-by: SoSeDiK diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index d8fd2103a40d278c7ee4135c19dea3eb4534dda8..ab31b31c61d652275a667f34ab018e4c8d0cdc08 100644 +index fddc6b5abbad66ebe556ff8565c38c60b7883fce..55d61a4c93233c0d3994e75f41e29065c2f1ea93 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -2032,7 +2032,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -29,21 +29,19 @@ index d8fd2103a40d278c7ee4135c19dea3eb4534dda8..ab31b31c61d652275a667f34ab018e4c this.handleCommand(s); } else if (this.player.getChatVisibility() == ChatVisiblity.SYSTEM) { // Do nothing, this is coming from a plugin -@@ -2119,7 +2119,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - } +@@ -2120,6 +2120,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } -- private void handleCommand(String s) { -+ public void handleCommand(String s) { // Paper - private -> public + private void handleCommand(String s) { + org.spigotmc.AsyncCatcher.catchOp("Command Dispatched Async: " + s); // Paper - Add async catcher - co.aikar.timings.MinecraftTimings.playerCommandTimer.startTiming(); // Paper if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s); + diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 9683759c36de3b9d791e56dc1fb993087c1bc37c..3b58cc979c4e2fb5382f0c67ccfaa8440e9c785b 100644 +index 2bfa790a9f0ca07217c9d9f7dd916950d859530c..ec0d7e44235378380b7180ca1a9ca56b14dac1c7 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -937,7 +937,7 @@ public final class CraftServer implements Server { +@@ -936,7 +936,7 @@ public final class CraftServer implements Server { public boolean dispatchCommand(CommandSender sender, String commandLine) { Preconditions.checkArgument(sender != null, "sender cannot be null"); Preconditions.checkArgument(commandLine != null, "commandLine cannot be null"); diff --git a/patches/server/0057-Expose-server-CommandMap.patch b/patches/server/0057-Expose-server-CommandMap.patch index b491a4208321..bc0e6fd63e13 100644 --- a/patches/server/0057-Expose-server-CommandMap.patch +++ b/patches/server/0057-Expose-server-CommandMap.patch @@ -5,10 +5,10 @@ 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 3b58cc979c4e2fb5382f0c67ccfaa8440e9c785b..89778f8df5a4b639bb0fe5e7a0164ef55b96041a 100644 +index ec0d7e44235378380b7180ca1a9ca56b14dac1c7..63573ec7e8f855a1afd892c9615a45c1bc742ac1 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2183,6 +2183,7 @@ public final class CraftServer implements Server { +@@ -2182,6 +2182,7 @@ public final class CraftServer implements Server { return this.helpMap; } diff --git a/patches/server/0061-Add-velocity-warnings.patch b/patches/server/0061-Add-velocity-warnings.patch index a8358fe2a49e..aafd524684f2 100644 --- a/patches/server/0061-Add-velocity-warnings.patch +++ b/patches/server/0061-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 89778f8df5a4b639bb0fe5e7a0164ef55b96041a..c80fe475edffce53363dfea658b9f13a2c6de1ca 100644 +index 63573ec7e8f855a1afd892c9615a45c1bc742ac1..bb562ada45b828c79d83afdd1687edd32cbaf1dc 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -305,6 +305,7 @@ public final class CraftServer implements Server { diff --git a/patches/server/0062-Add-exception-reporting-event.patch b/patches/server/0062-Add-exception-reporting-event.patch index 17d813039c60..52fe575b573e 100644 --- a/patches/server/0062-Add-exception-reporting-event.patch +++ b/patches/server/0062-Add-exception-reporting-event.patch @@ -91,10 +91,10 @@ index a5b18a04f482d05d3ca74918a580499b21c2fc3c..bd3f71c3eaa33258ff56062ea3a2099c } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 5fe8726af73eb5334f47046c93096341e987269b..574d8d311001ce15c2a2391caaec0a0b0b1653b5 100644 +index ed15f5c4a365a199d04e92d688035e4ab755e8db..f900c86697f5a3da45b724944a663fca8f89413e 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -735,6 +735,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -728,6 +728,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Paper start - Prevent block entity and entity crashes 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); @@ -103,10 +103,10 @@ index 5fe8726af73eb5334f47046c93096341e987269b..574d8d311001ce15c2a2391caaec0a0b // Paper end - Prevent block entity and entity crashes } diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 1fe93e01c5e37397aded5d1f99214bf1bffe70b7..400166ad0199dd4b96684904ef4748cdb72381bb 100644 +index 9389fd53f2bff0a9ca389694b312dc6da58befaf..da0ddb8285e157be0cc7b940a9590be5e3061e3d 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -296,6 +296,7 @@ public final class NaturalSpawner { +@@ -294,6 +294,7 @@ public final class NaturalSpawner { NaturalSpawner.LOGGER.warn("Can't spawn entity of type: {}", BuiltInRegistries.ENTITY_TYPE.getKey(type)); } catch (Exception exception) { NaturalSpawner.LOGGER.warn("Failed to create mob", exception); @@ -114,7 +114,7 @@ index 1fe93e01c5e37397aded5d1f99214bf1bffe70b7..400166ad0199dd4b96684904ef4748cd } return null; -@@ -384,6 +385,7 @@ public final class NaturalSpawner { +@@ -382,6 +383,7 @@ public final class NaturalSpawner { entity = biomesettingsmobs_c.type.create(world.getLevel(), EntitySpawnReason.NATURAL); } catch (Exception exception) { NaturalSpawner.LOGGER.warn("Failed to create mob", exception); @@ -123,7 +123,7 @@ index 1fe93e01c5e37397aded5d1f99214bf1bffe70b7..400166ad0199dd4b96684904ef4748cd } 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 e1cd7497b1355030bf44b53aa30400604dff9aca..401f18deb9e9f019ea17ad684f2d5c4ea5e7ef97 100644 +index 79cf3089c128ef3c17d956da1e380670279ee5da..96ea7a5d5d4a69c83c2401e64750d41cd70088fc 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -496,8 +496,13 @@ public class LevelChunk extends ChunkAccess { @@ -142,7 +142,7 @@ index e1cd7497b1355030bf44b53aa30400604dff9aca..401f18deb9e9f019ea17ad684f2d5c4e } else { BlockState iblockdata1 = blockEntity.getBlockState(); -@@ -989,6 +994,7 @@ public class LevelChunk extends ChunkAccess { +@@ -986,6 +991,7 @@ public class LevelChunk extends ChunkAccess { // Paper start - Prevent block 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); @@ -171,10 +171,10 @@ index 15f273aa592828719de6e092d79a407dc8652dfe..b24e8255ab18eb5b2e4968aa62aa3d72 try { filechannel.close(); diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -index 4c376f67ae311b4fedea27b3475f9fb56054aec2..22ddc74d85efb4e80e6f06acdf93341a122804fc 100644 +index 2c36d0796714997191c6540c34a9df60718065f6..0c0115ccd8541ac62975f4759b4e2083ac560332 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -@@ -416,20 +416,25 @@ public class CraftScheduler implements BukkitScheduler { +@@ -415,20 +415,25 @@ public class CraftScheduler implements BukkitScheduler { try { task.run(); } catch (final Throwable throwable) { diff --git a/patches/server/0063-Disable-Scoreboards-for-non-players-by-default.patch b/patches/server/0063-Disable-Scoreboards-for-non-players-by-default.patch index e5db1eccb030..3d53b13e30fb 100644 --- a/patches/server/0063-Disable-Scoreboards-for-non-players-by-default.patch +++ b/patches/server/0063-Disable-Scoreboards-for-non-players-by-default.patch @@ -23,10 +23,10 @@ index 49df5f4b09926556986e3a45d52ff299b878af76..8a61ca3cba2888e03e440519714705fe } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 6cc86412d45186dff312d9b1246fd1d03dbc15d8..b3f7d20c7853afaa396a90fbe23ed33d03fda8eb 100644 +index 6dba567e9f7a197af16598647f216b5323d1b601..47403887721914b632565947efae0dfa7c841588 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -873,6 +873,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -871,6 +871,7 @@ public abstract class LivingEntity extends Entity implements Attackable { String s = nbt.getString("Team"); Scoreboard scoreboard = this.level().getScoreboard(); PlayerTeam scoreboardteam = scoreboard.getPlayerTeam(s); diff --git a/patches/server/0067-Default-loading-permissions.yml-before-plugins.patch b/patches/server/0067-Default-loading-permissions.yml-before-plugins.patch index 8cf22bcec703..e933d73ae3c6 100644 --- a/patches/server/0067-Default-loading-permissions.yml-before-plugins.patch +++ b/patches/server/0067-Default-loading-permissions.yml-before-plugins.patch @@ -16,10 +16,10 @@ 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 c80fe475edffce53363dfea658b9f13a2c6de1ca..bd18711474807518ceefa9d097d94a78b9e66158 100644 +index bb562ada45b828c79d83afdd1687edd32cbaf1dc..d581bfad059e60a693bc27285a723979e7d7dd34 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -491,6 +491,7 @@ public final class CraftServer implements Server { +@@ -490,6 +490,7 @@ public final class CraftServer implements Server { if (type == PluginLoadOrder.STARTUP) { this.helpMap.clear(); this.helpMap.initializeGeneralTopics(); @@ -27,7 +27,7 @@ index c80fe475edffce53363dfea658b9f13a2c6de1ca..bd18711474807518ceefa9d097d94a78 } Plugin[] plugins = this.pluginManager.getPlugins(); -@@ -510,7 +511,7 @@ public final class CraftServer implements Server { +@@ -509,7 +510,7 @@ public final class CraftServer implements Server { this.commandMap.registerServerAliases(); DefaultPermissions.registerCorePermissions(); CraftDefaultPermissions.registerCorePermissions(); diff --git a/patches/server/0068-Allow-Reloading-of-Custom-Permissions.patch b/patches/server/0068-Allow-Reloading-of-Custom-Permissions.patch index b7b06d1ab87c..8205a118dd47 100644 --- a/patches/server/0068-Allow-Reloading-of-Custom-Permissions.patch +++ b/patches/server/0068-Allow-Reloading-of-Custom-Permissions.patch @@ -6,10 +6,10 @@ 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 bd18711474807518ceefa9d097d94a78b9e66158..2cc9faa6c560ceb8e50984e01a8f5caa042b62ba 100644 +index d581bfad059e60a693bc27285a723979e7d7dd34..2b4c1c3cc4b740d5aceb483c4066f23433c175d9 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2809,5 +2809,23 @@ public final class CraftServer implements Server { +@@ -2808,5 +2808,23 @@ public final class CraftServer implements Server { } return this.adventure$audiences; } diff --git a/patches/server/0069-Remove-Metadata-on-reload.patch b/patches/server/0069-Remove-Metadata-on-reload.patch index ec1a1512d4b9..e5592929ff10 100644 --- a/patches/server/0069-Remove-Metadata-on-reload.patch +++ b/patches/server/0069-Remove-Metadata-on-reload.patch @@ -7,10 +7,10 @@ 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 2cc9faa6c560ceb8e50984e01a8f5caa042b62ba..e9e612581683b27f35c0ef7adaae8e8b7eb677ec 100644 +index 2b4c1c3cc4b740d5aceb483c4066f23433c175d9..c6ea35f752c9a0bf9e5e07e3b501fd3fe8c30084 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1006,8 +1006,16 @@ public final class CraftServer implements Server { +@@ -1005,8 +1005,16 @@ public final class CraftServer implements Server { world.spigotConfig.init(); // Spigot } diff --git a/patches/server/0072-Add-World-Util-Methods.patch b/patches/server/0072-Add-World-Util-Methods.patch index 11bb708681e6..4c7b9c4d2737 100644 --- a/patches/server/0072-Add-World-Util-Methods.patch +++ b/patches/server/0072-Add-World-Util-Methods.patch @@ -6,10 +6,10 @@ 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/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 574d8d311001ce15c2a2391caaec0a0b0b1653b5..b37aeadf48e112170d64adc7587fdacbf6466aee 100644 +index f900c86697f5a3da45b724944a663fca8f89413e..d1b117f25bafb294f00c18be02be593061120956 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -341,6 +341,22 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -339,6 +339,22 @@ public abstract class Level implements LevelAccessor, AutoCloseable { return chunk == null ? null : chunk.getFluidState(blockposition); } diff --git a/patches/server/0073-Custom-replacement-for-eaten-items.patch b/patches/server/0073-Custom-replacement-for-eaten-items.patch index 04ecd8892577..25ce9478525b 100644 --- a/patches/server/0073-Custom-replacement-for-eaten-items.patch +++ b/patches/server/0073-Custom-replacement-for-eaten-items.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Custom replacement for eaten items diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index b3f7d20c7853afaa396a90fbe23ed33d03fda8eb..4fa5e7127549e090338b11e6493413a3fab254a0 100644 +index 47403887721914b632565947efae0dfa7c841588..031b7f51959d1b8ca30e4a9fda0a2832516c9c0c 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3984,10 +3984,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3982,10 +3982,11 @@ public abstract class LivingEntity extends Entity implements Attackable { if (!this.useItem.isEmpty() && this.isUsingItem()) { // CraftBukkit start - fire PlayerItemConsumeEvent ItemStack itemstack; @@ -21,7 +21,7 @@ index b3f7d20c7853afaa396a90fbe23ed33d03fda8eb..4fa5e7127549e090338b11e6493413a3 this.level().getCraftServer().getPluginManager().callEvent(event); if (event.isCancelled()) { -@@ -4005,6 +4006,12 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4003,6 +4004,12 @@ public abstract class LivingEntity extends Entity implements Attackable { } else { itemstack = this.useItem.finishUsingItem(this.level(), this); } @@ -34,7 +34,7 @@ index b3f7d20c7853afaa396a90fbe23ed33d03fda8eb..4fa5e7127549e090338b11e6493413a3 // CraftBukkit end if (itemstack != this.useItem) { -@@ -4012,6 +4019,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4010,6 +4017,11 @@ public abstract class LivingEntity extends Entity implements Attackable { } this.stopUsingItem(); diff --git a/patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch b/patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch index b46ff88f535a..d019f5b8cbeb 100644 --- a/patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch +++ b/patches/server/0074-handle-NaN-health-absorb-values-and-repair-bad-data.patch @@ -5,10 +5,10 @@ Subject: [PATCH] handle NaN health/absorb values and repair bad data diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 4fa5e7127549e090338b11e6493413a3fab254a0..14d9e62c86309676ddd7eed19cce2f4b30a59b94 100644 +index 031b7f51959d1b8ca30e4a9fda0a2832516c9c0c..e5d1877f570b302f0b193e77ff5fdd7e89532513 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -833,7 +833,13 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -831,7 +831,13 @@ public abstract class LivingEntity extends Entity implements Attackable { @Override public void readAdditionalSaveData(CompoundTag nbt) { @@ -23,7 +23,7 @@ index 4fa5e7127549e090338b11e6493413a3fab254a0..14d9e62c86309676ddd7eed19cce2f4b if (nbt.contains("attributes", 9) && this.level() != null && !this.level().isClientSide) { this.getAttributes().load(nbt.getList("attributes", 10)); } -@@ -1373,6 +1379,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1371,6 +1377,10 @@ public abstract class LivingEntity extends Entity implements Attackable { } public void setHealth(float health) { @@ -34,7 +34,7 @@ index 4fa5e7127549e090338b11e6493413a3fab254a0..14d9e62c86309676ddd7eed19cce2f4b // CraftBukkit start - Handle scaled health if (this instanceof ServerPlayer) { org.bukkit.craftbukkit.entity.CraftPlayer player = ((ServerPlayer) this).getBukkitEntity(); -@@ -3841,7 +3851,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3839,7 +3849,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } public final void setAbsorptionAmount(float absorptionAmount) { diff --git a/patches/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch b/patches/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch index 2a2c4f2b31f7..4cf4bf11817d 100644 --- a/patches/server/0076-Configurable-spawn-chances-for-skeleton-horses.patch +++ b/patches/server/0076-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 821df759e3410428b4558e22042c79f29238ebe2..b80af01529206bf55ed028dac41798f91da22f51 100644 +index 0e967e4c73dabc6cf6580d863c640cf4dff4f3bf..e623f8e75ec895d18d854a1f2c0dbe41a67dffc8 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -608,7 +608,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -594,7 +594,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (this.isRainingAt(blockposition)) { DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition); diff --git a/patches/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch b/patches/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch index 58b312e58f2e..169cb0c090db 100644 --- a/patches/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch +++ b/patches/server/0077-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch @@ -6,10 +6,10 @@ 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 d04ce36f79523417c7c2b49a8324b52ef6a6f0f4..412f97df192788bf38103a4c1754def47931fad4 100644 +index cc4c5fcbeca4862d8ff78b127cb3f2c07956dfaf..ece7f630937abd6d341a2498bac2f0afcfb1ce0f 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1621,6 +1621,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { String s = String.valueOf(worldserver); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index b80af01529206bf55ed028dac41798f91da22f51..237a0b4dd0e1c437a021e1d2104e6d523b1f745a 100644 +index e623f8e75ec895d18d854a1f2c0dbe41a67dffc8..50296ff319fd6f97e27ec1cb6bdcd7b85a6ce926 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -230,6 +230,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -228,6 +228,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // CraftBukkit start public final LevelStorageSource.LevelStorageAccess convertable; public final UUID uuid; @@ -30,10 +30,10 @@ index b80af01529206bf55ed028dac41798f91da22f51..237a0b4dd0e1c437a021e1d2104e6d52 public LevelChunk getChunkIfLoaded(int x, int z) { return this.chunkSource.getChunk(x, z, false); diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index b37aeadf48e112170d64adc7587fdacbf6466aee..9ad531912c4298658915b45b2870539059e8aadd 100644 +index d1b117f25bafb294f00c18be02be593061120956..9e88e9c473d1ab02344afd9634c625b95b5f38ef 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -491,7 +491,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -489,7 +489,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // CraftBukkit start iblockdata1.updateIndirectNeighbourShapes(this, blockposition, k, j - 1); // Don't call an event for the old block to limit event spam CraftWorld world = ((ServerLevel) this).getWorld(); diff --git a/patches/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch b/patches/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch index e529f629a621..2c0ae7a0fd1e 100644 --- a/patches/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch +++ b/patches/server/0078-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 237a0b4dd0e1c437a021e1d2104e6d523b1f745a..6ec83b72bb9f762d606fcbf4b93c70f2b025f48f 100644 +index 50296ff319fd6f97e27ec1cb6bdcd7b85a6ce926..c36032803e8b7e4a8537f02738075e1a6baed3b1 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2224,6 +2224,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2194,6 +2194,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe entity.setOrigin(entity.getOriginVector().toLocation(getWorld())); } // Paper end - Entity origin API @@ -16,7 +16,7 @@ index 237a0b4dd0e1c437a021e1d2104e6d523b1f745a..6ec83b72bb9f762d606fcbf4b93c70f2 } public void onTrackingEnd(Entity entity) { -@@ -2294,6 +2295,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2264,6 +2265,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } } // CraftBukkit end diff --git a/patches/server/0079-Configurable-Chunk-Inhabited-Time.patch b/patches/server/0079-Configurable-Chunk-Inhabited-Time.patch index 5a4d79299411..d5d3a231fca0 100644 --- a/patches/server/0079-Configurable-Chunk-Inhabited-Time.patch +++ b/patches/server/0079-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 401f18deb9e9f019ea17ad684f2d5c4ea5e7ef97..add5ec0f8e8bd0b89511dcb656e1d4cda702a86b 100644 +index 96ea7a5d5d4a69c83c2401e64750d41cd70088fc..a1b6c13d496519ef6ce240036cec6642626903b9 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -195,6 +195,13 @@ public class LevelChunk extends ChunkAccess { diff --git a/patches/server/0083-Add-PlayerUseUnknownEntityEvent.patch b/patches/server/0083-Add-PlayerUseUnknownEntityEvent.patch index 4f7a58fe85d7..d895ad41174a 100644 --- a/patches/server/0083-Add-PlayerUseUnknownEntityEvent.patch +++ b/patches/server/0083-Add-PlayerUseUnknownEntityEvent.patch @@ -28,10 +28,10 @@ index 1e9c68cd1868d083e6a790d56006dd4aa432010a..8a0ee9564fc36a2badf1357f7e6c47b5 + // Paper end - PlayerUseUnknownEntityEvent } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index ab31b31c61d652275a667f34ab018e4c8d0cdc08..33caf2d025a5770d2e3ebf044562314df6eb2c15 100644 +index 55d61a4c93233c0d3994e75f41e29065c2f1ea93..79db369b905744ab2fd69de1afc34feec589ec82 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2513,7 +2513,26 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2510,7 +2510,26 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl }); } } diff --git a/patches/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch b/patches/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch index f087a2a35fe5..6e252c8f8ba5 100644 --- a/patches/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch +++ b/patches/server/0085-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 6ec83b72bb9f762d606fcbf4b93c70f2b025f48f..5a9c703a252d0c1c57c23ef021e57cdd1de31585 100644 +index c36032803e8b7e4a8537f02738075e1a6baed3b1..828f47c6aadb609402f7237f8c234d595f39c970 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1402,11 +1402,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1372,11 +1372,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public void updateNeighborsAt(BlockPos pos, Block block) { diff --git a/patches/server/0088-Configurable-Player-Collision.patch b/patches/server/0088-Configurable-Player-Collision.patch index fe965dbf88d8..ef8bb51af960 100644 --- a/patches/server/0088-Configurable-Player-Collision.patch +++ b/patches/server/0088-Configurable-Player-Collision.patch @@ -18,10 +18,10 @@ index 9a1a961eabd4362c171da78c6be82c867f3696a4..1d0c473442b5c72245c356054440323e ComponentSerialization.TRUSTED_STREAM_CODEC.encode(buf, this.playerPrefix); ComponentSerialization.TRUSTED_STREAM_CODEC.encode(buf, this.playerSuffix); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 412f97df192788bf38103a4c1754def47931fad4..adab3f49722daa580dbb66012ab654a2a4a8084f 100644 +index ece7f630937abd6d341a2498bac2f0afcfb1ce0f..2e6531f39c6b65d79fc544459629ef61b2ad961a 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -655,6 +655,20 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop playersByName = new java.util.HashMap<>(); @@ -54,7 +54,7 @@ index 2af4b853fde493c1fa5c8d530aae4d68b79f7ba0..04e25dba87cc1531898bdf9640d6da44 public PlayerList(MinecraftServer server, LayeredRegistryAccess registryManager, PlayerDataStorage saveHandler, int maxPlayers) { this.cserver = server.server = new CraftServer((DedicatedServer) server, this); -@@ -349,6 +350,13 @@ public abstract class PlayerList { +@@ -348,6 +349,13 @@ public abstract class PlayerList { player.loadAndSpawnParentVehicle(optional); player.initInventoryMenu(); // CraftBukkit - Moved from above, added world @@ -68,7 +68,7 @@ index 2af4b853fde493c1fa5c8d530aae4d68b79f7ba0..04e25dba87cc1531898bdf9640d6da44 PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ()); } -@@ -471,6 +479,16 @@ public abstract class PlayerList { +@@ -470,6 +478,16 @@ public abstract class PlayerList { entityplayer.doTick(); // SPIGOT-924 // CraftBukkit end @@ -85,7 +85,7 @@ index 2af4b853fde493c1fa5c8d530aae4d68b79f7ba0..04e25dba87cc1531898bdf9640d6da44 this.save(entityplayer); if (entityplayer.isPassenger()) { Entity entity = entityplayer.getRootVehicle(); -@@ -1098,6 +1116,13 @@ public abstract class PlayerList { +@@ -1096,6 +1114,13 @@ public abstract class PlayerList { } // CraftBukkit end diff --git a/patches/server/0091-EntityRegainHealthEvent-isFastRegen-API.patch b/patches/server/0091-EntityRegainHealthEvent-isFastRegen-API.patch index b9219fec5773..c6c6929c40a9 100644 --- a/patches/server/0091-EntityRegainHealthEvent-isFastRegen-API.patch +++ b/patches/server/0091-EntityRegainHealthEvent-isFastRegen-API.patch @@ -6,10 +6,10 @@ Subject: [PATCH] EntityRegainHealthEvent isFastRegen API Don't even get me started diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 14d9e62c86309676ddd7eed19cce2f4b30a59b94..6ea3488a578a7464bd34df265742a777575c9029 100644 +index e5d1877f570b302f0b193e77ff5fdd7e89532513..4a6f9a8b7db8d0e1c3cca5a0a4856d38cb38b94e 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1352,10 +1352,16 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1350,10 +1350,16 @@ public abstract class LivingEntity extends Entity implements Attackable { } public void heal(float f, EntityRegainHealthEvent.RegainReason regainReason) { diff --git a/patches/server/0093-remove-null-possibility-for-getServer-singleton.patch b/patches/server/0093-remove-null-possibility-for-getServer-singleton.patch index bc56cf8017b5..3ebd34b206f0 100644 --- a/patches/server/0093-remove-null-possibility-for-getServer-singleton.patch +++ b/patches/server/0093-remove-null-possibility-for-getServer-singleton.patch @@ -6,10 +6,10 @@ 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 adab3f49722daa580dbb66012ab654a2a4a8084f..55d376d4ddc522cc1a9841471514aa077ebfaac9 100644 +index 2e6531f39c6b65d79fc544459629ef61b2ad961a..bdc4eafcad57bb0073662e904bde87e9ac5ed0f3 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -204,6 +204,7 @@ import co.aikar.timings.MinecraftTimings; // Paper +@@ -203,6 +203,7 @@ import org.bukkit.event.server.ServerLoadEvent; public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource { @@ -17,7 +17,7 @@ index adab3f49722daa580dbb66012ab654a2a4a8084f..55d376d4ddc522cc1a9841471514aa07 public static final Logger LOGGER = LogUtils.getLogger(); public static final net.kyori.adventure.text.logger.slf4j.ComponentLogger COMPONENT_LOGGER = net.kyori.adventure.text.logger.slf4j.ComponentLogger.logger(LOGGER.getName()); // Paper public static final String VANILLA_BRAND = "vanilla"; -@@ -341,6 +342,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { this.stopRecordingMetrics(); -@@ -2625,9 +2627,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions diff --git a/patches/server/0101-Fix-global-sound-handling.patch b/patches/server/0101-Fix-global-sound-handling.patch index 1c4cad79e331..8af9a82deaab 100644 --- a/patches/server/0101-Fix-global-sound-handling.patch +++ b/patches/server/0101-Fix-global-sound-handling.patch @@ -11,10 +11,10 @@ Co-authored-by: lexikiq Co-authored-by: Aikar diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 5a9c703a252d0c1c57c23ef021e57cdd1de31585..022ec2ff1c5a6a1de867b2a6dafb339d55a0905d 100644 +index 828f47c6aadb609402f7237f8c234d595f39c970..88c93a2e67c8d1bc227c7fa35bb919a40009f931 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1335,7 +1335,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1305,7 +1305,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public void levelEvent(@Nullable Player player, int eventId, BlockPos pos, int data) { @@ -23,7 +23,7 @@ index 5a9c703a252d0c1c57c23ef021e57cdd1de31585..022ec2ff1c5a6a1de867b2a6dafb339d } public int getLogicalHeight() { -@@ -2152,6 +2152,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2122,6 +2122,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return this.serverLevelData.getGameRules(); } diff --git a/patches/server/0104-Add-setting-for-proxy-online-mode-status.patch b/patches/server/0104-Add-setting-for-proxy-online-mode-status.patch index 8158eb6cc79e..58541b2ca3bd 100644 --- a/patches/server/0104-Add-setting-for-proxy-online-mode-status.patch +++ b/patches/server/0104-Add-setting-for-proxy-online-mode-status.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add setting for proxy online mode status TODO: Add isProxyOnlineMode check to Metrics diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 07969f82a3df1b71bee275a99ef9170a4f9bbbb0..a5880be1ec88c70f7ee46225036b04dac87943d4 100644 +index 5d9772a6c35e8f849e8879f510b2c586b148074c..7c2b2dbc03bf4c3308a3e2a34260fee56d646488 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -575,7 +575,11 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -571,7 +571,11 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface public boolean enforceSecureProfile() { DedicatedServerProperties dedicatedserverproperties = this.getProperties(); @@ -60,10 +60,10 @@ index a0b0614ac7d2009db5c6c10ab4a5f09dd447c635..653856d0b8dcf2baf4cc77a276f17c8c } 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 e9e612581683b27f35c0ef7adaae8e8b7eb677ec..e04c3f623a316ac3a7b3700cfd5165e799bc0afc 100644 +index c6ea35f752c9a0bf9e5e07e3b501fd3fe8c30084..f970f821f5ac8cbad90ebb8dd8e8bf222ae229ae 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1892,7 +1892,7 @@ public final class CraftServer implements Server { +@@ -1891,7 +1891,7 @@ public final class CraftServer implements Server { if (result == null) { GameProfile profile = null; // Only fetch an online UUID in online mode diff --git a/patches/server/0106-Configurable-packet-in-spam-threshold.patch b/patches/server/0106-Configurable-packet-in-spam-threshold.patch index 3a0784210e17..b28e8580373f 100644 --- a/patches/server/0106-Configurable-packet-in-spam-threshold.patch +++ b/patches/server/0106-Configurable-packet-in-spam-threshold.patch @@ -5,7 +5,7 @@ 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 33caf2d025a5770d2e3ebf044562314df6eb2c15..d5952a0ea86a562cb7ff2e9597260ed9c8ad7192 100644 +index 79db369b905744ab2fd69de1afc34feec589ec82..be690a8a22c126b007e623c8fe627bab00a28bad 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1545,13 +1545,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0107-Configurable-flying-kick-messages.patch b/patches/server/0107-Configurable-flying-kick-messages.patch index 1c746539c16b..00bd53261422 100644 --- a/patches/server/0107-Configurable-flying-kick-messages.patch +++ b/patches/server/0107-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 d5952a0ea86a562cb7ff2e9597260ed9c8ad7192..d02c743c8a4fe5d640df53dda881e1d1cba05f5f 100644 +index be690a8a22c126b007e623c8fe627bab00a28bad..bc0d7bfb01a613c8fa567238f973f834cf3e3f17 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -355,7 +355,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0111-Allow-Reloading-of-Command-Aliases.patch b/patches/server/0111-Allow-Reloading-of-Command-Aliases.patch index a4e93d3f78fd..aa356f414e51 100644 --- a/patches/server/0111-Allow-Reloading-of-Command-Aliases.patch +++ b/patches/server/0111-Allow-Reloading-of-Command-Aliases.patch @@ -6,10 +6,10 @@ 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 e04c3f623a316ac3a7b3700cfd5165e799bc0afc..1f028c40dbe159f836e255ec52287903bca9fab8 100644 +index f970f821f5ac8cbad90ebb8dd8e8bf222ae229ae..c36bba560d5b17c69c2034cd1fcd711234c13414 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2835,5 +2835,24 @@ public final class CraftServer implements Server { +@@ -2834,5 +2834,24 @@ public final class CraftServer implements Server { DefaultPermissions.registerCorePermissions(); CraftDefaultPermissions.registerCorePermissions(); } diff --git a/patches/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch b/patches/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch index 2fc9b6d3419d..526301e39dcc 100644 --- a/patches/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch +++ b/patches/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Optimize Level.hasChunkAt(BlockPosition)Z Reduce method invocations for World.isLoaded(BlockPosition)Z diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 529b6eccb634f1f4677118c48e174b42eead2c0b..658ceb9c43bb48f88596cd7270e276a369a3937e 100644 +index 675dcb6eb5c33f6ec582ff20118d2f73745914a9..943c14b26cf5b1c9f9ea1acec058cecac3b93bf7 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -342,6 +342,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -340,6 +340,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { return chunk == null ? null : chunk.getFluidState(blockposition); } diff --git a/patches/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch b/patches/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch index ad688961b8cf..96ee3335c033 100644 --- a/patches/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch +++ b/patches/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch @@ -7,7 +7,7 @@ Provides counts without the ineffeciency of using .getEntities().size() which creates copy of the collections. diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 658ceb9c43bb48f88596cd7270e276a369a3937e..b34663ba24a0925c7fe65b354f4029c51ecc3bd1 100644 +index 943c14b26cf5b1c9f9ea1acec058cecac3b93bf7..e5eac1977f77b7ce1112bfe7ac1b77d9ef4d90f4 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -116,7 +116,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { diff --git a/patches/server/0124-Enforce-Sync-Player-Saves.patch b/patches/server/0124-Enforce-Sync-Player-Saves.patch index 7278b203686e..bbf020dcb342 100644 --- a/patches/server/0124-Enforce-Sync-Player-Saves.patch +++ b/patches/server/0124-Enforce-Sync-Player-Saves.patch @@ -7,20 +7,18 @@ 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 04e25dba87cc1531898bdf9640d6da44ee3bf410..18d4ee1e1fb37848ac6587a0a68785be1851b1e8 100644 +index d0d2b687ec851e3fa08864897774897a1fcd7df8..f9ffae36beb13db416432068d8ee00de21d0c1fe 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -998,11 +998,13 @@ public abstract class PlayerList { +@@ -997,10 +997,12 @@ public abstract class PlayerList { } public void saveAll() { + io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main - MinecraftTimings.savePlayers.startTiming(); // Paper for (int i = 0; i < this.players.size(); ++i) { -- this.save((ServerPlayer) this.players.get(i)); -+ this.save(this.players.get(i)); + this.save((ServerPlayer) this.players.get(i)); } - MinecraftTimings.savePlayers.stopTiming(); // Paper + + return null; }); // Paper - ensure main } diff --git a/patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch b/patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch index 6f2899e0dbad..122c225e0199 100644 --- a/patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch +++ b/patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch @@ -127,10 +127,10 @@ index 7f3ac3e8631e30c968ef664f994ad208d05eb4a3..b9160ebca0d11dbbf96da5f0f5810d30 @Override diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 6ea3488a578a7464bd34df265742a777575c9029..237025be183b3cc93920430075edcc0bb2899b68 100644 +index 4a6f9a8b7db8d0e1c3cca5a0a4856d38cb38b94e..7a648a8c3f25397e1c883a42648b21a05901513f 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1837,7 +1837,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1835,7 +1835,7 @@ public abstract class LivingEntity extends Entity implements Attackable { protected void dropExperience(ServerLevel world, @Nullable Entity attacker) { // CraftBukkit start - Update getExpReward() above if the removed if() changes! if (!(this instanceof net.minecraft.world.entity.boss.enderdragon.EnderDragon)) { // CraftBukkit - SPIGOT-2420: Special case ender dragon will drop the xp over time @@ -285,10 +285,10 @@ index 56d8ed71861b0a47692fde4c5acc97aaba8166da..13bc52bc856031c930370828b0381e43 world.levelEvent(1042, blockposition, 0); diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index 3cefda12d4c2ca2c4e9ef97eff961a55af164d6b..43c2b411115d3a8a0e47d3e2277789b2667897af 100644 +index 27cbec37c6ea278232970ae035795fdecca71735..f1711f774f844024ca7b678385daaace6cda9f46 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -363,8 +363,13 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -354,8 +354,13 @@ public class Block extends BlockBehaviour implements ItemLike { } public void popExperience(ServerLevel world, BlockPos pos, int size) { diff --git a/patches/server/0126-Cap-Entity-Collisions.patch b/patches/server/0126-Cap-Entity-Collisions.patch index c5acd9fe9a1f..0a1d097e37bb 100644 --- a/patches/server/0126-Cap-Entity-Collisions.patch +++ b/patches/server/0126-Cap-Entity-Collisions.patch @@ -24,10 +24,10 @@ index 847fd720f11e89d906430c820bc92afe0454761d..b1b26e7c0f66f0697bcfe9eb045d45f3 @javax.annotation.Nullable private org.bukkit.util.Vector origin; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 237025be183b3cc93920430075edcc0bb2899b68..f2f8fbc8a8cf32bcba0ad7ac9b6cdd75468e062a 100644 +index 7a648a8c3f25397e1c883a42648b21a05901513f..bcc0137fec45406e70231b4e2a5bd69dc08ffb5a 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3642,10 +3642,12 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3640,10 +3640,12 @@ public abstract class LivingEntity extends Entity implements Attackable { } Iterator iterator1 = list.iterator(); diff --git a/patches/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch b/patches/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch index 8c7d283f779a..15ad3dc3e232 100644 --- a/patches/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch +++ b/patches/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch @@ -9,10 +9,10 @@ One report of a suspected memory leak with the system. This adds additional overhead to asynchronous task dispatching diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -index 22ddc74d85efb4e80e6f06acdf93341a122804fc..0e7f402a7b841c5f6f5a4b699b7bb3d9f46b1af6 100644 +index 0c0115ccd8541ac62975f4759b4e2083ac560332..300d31e31a55dbee3489320e21e42f14ac429478 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -@@ -433,7 +433,7 @@ public class CraftScheduler implements BukkitScheduler { +@@ -432,7 +432,7 @@ public class CraftScheduler implements BukkitScheduler { } this.parsePending(); } else { @@ -21,16 +21,16 @@ index 22ddc74d85efb4e80e6f06acdf93341a122804fc..0e7f402a7b841c5f6f5a4b699b7bb3d9 this.executor.execute(new com.destroystokyo.paper.ServerSchedulerReportingWrapper(task)); // Paper // We don't need to parse pending // (async tasks must live with race-conditions if they attempt to cancel between these few lines of code) -@@ -450,7 +450,7 @@ public class CraftScheduler implements BukkitScheduler { +@@ -447,7 +447,7 @@ public class CraftScheduler implements BukkitScheduler { + } this.pending.addAll(temp); temp.clear(); - MinecraftTimings.bukkitSchedulerFinishTimer.stopTiming(); // Paper - this.debugHead = this.debugHead.getNextHead(this.currentTick); + //this.debugHead = this.debugHead.getNextHead(this.currentTick); // Paper } private void addTask(final CraftTask task) { -@@ -514,10 +514,15 @@ public class CraftScheduler implements BukkitScheduler { +@@ -509,10 +509,15 @@ public class CraftScheduler implements BukkitScheduler { @Override public String toString() { diff --git a/patches/server/0128-Properly-handle-async-calls-to-restart-the-server.patch b/patches/server/0128-Properly-handle-async-calls-to-restart-the-server.patch index f34ed462be27..2c9eb1dd3cb7 100644 --- a/patches/server/0128-Properly-handle-async-calls-to-restart-the-server.patch +++ b/patches/server/0128-Properly-handle-async-calls-to-restart-the-server.patch @@ -30,10 +30,10 @@ 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 d32f0edc31f099f53656fe56dafb98903f132502..5e9b85a46708cfe297533f13255629d72cd09c73 100644 +index 383808406dd3a6c5b6098db93e638749489b80e3..0adba72139779a20eed8f489f7cfaff9e84e24f4 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -248,6 +248,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop, ServerLevel> levels; private PlayerList playerList; private volatile boolean running; @@ -41,7 +41,7 @@ index d32f0edc31f099f53656fe56dafb98903f132502..5e9b85a46708cfe297533f13255629d7 private boolean stopped; private int tickCount; private int ticksUntilAutosave; -@@ -953,7 +954,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop capturedTileEntities = new HashMap<>(); public List captureDrops; public final it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap ticksPerSpawnCategory = new it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<>(); -@@ -384,7 +384,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -382,7 +382,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public boolean setBlock(BlockPos pos, BlockState state, int flags, int maxUpdateDepth) { // CraftBukkit start - tree generation if (this.captureTreeGeneration) { @@ -39,7 +39,7 @@ index 106f4dd7f49d3b81a9bc08cd034cccac90042f84..c628524274110bcad175472dbcb82e6c if (blockstate == null) { blockstate = CapturedBlockState.getTreeBlockState(this, pos, flags); this.capturedBlockStates.put(pos.immutable(), blockstate); -@@ -405,7 +405,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -403,7 +403,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // CraftBukkit start - capture blockstates boolean captured = false; if (this.captureBlockStates && !this.capturedBlockStates.containsKey(pos)) { @@ -49,7 +49,7 @@ index 106f4dd7f49d3b81a9bc08cd034cccac90042f84..c628524274110bcad175472dbcb82e6c this.capturedBlockStates.put(pos.immutable(), blockstate); captured = true; } -@@ -608,7 +609,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -606,7 +607,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public BlockState getBlockState(BlockPos pos) { // CraftBukkit start - tree generation if (this.captureTreeGeneration) { diff --git a/patches/server/0160-API-to-get-a-BlockState-without-a-snapshot.patch b/patches/server/0160-API-to-get-a-BlockState-without-a-snapshot.patch index 3b12a520095a..97e12295c92a 100644 --- a/patches/server/0160-API-to-get-a-BlockState-without-a-snapshot.patch +++ b/patches/server/0160-API-to-get-a-BlockState-without-a-snapshot.patch @@ -13,10 +13,10 @@ also Avoid NPE during CraftBlockEntityState load if could not get TE If Tile Entity was null, correct Sign to return empty lines instead of null diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index 4536632687e71b02d5945cac3816b72ac540935e..46a831f86b512f4228be8ccee40fb0f7bf0d6df6 100644 +index 3d7c5db5514f9d4401da22d2df88c5614051e568..50413d317ce0282752c57535637f87d529f4c09f 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -59,6 +59,7 @@ public abstract class BlockEntity { +@@ -54,6 +54,7 @@ public abstract class BlockEntity { this.worldPosition = pos.immutable(); this.validateBlockState(state); this.blockState = state; @@ -24,7 +24,7 @@ index 4536632687e71b02d5945cac3816b72ac540935e..46a831f86b512f4228be8ccee40fb0f7 } private void validateBlockState(BlockState state) { -@@ -92,7 +93,7 @@ public abstract class BlockEntity { +@@ -87,7 +88,7 @@ public abstract class BlockEntity { // CraftBukkit start - read container protected void loadAdditional(CompoundTag nbt, HolderLookup.Provider registries) { @@ -33,7 +33,7 @@ index 4536632687e71b02d5945cac3816b72ac540935e..46a831f86b512f4228be8ccee40fb0f7 net.minecraft.nbt.Tag persistentDataTag = nbt.get("PublicBukkitValues"); if (persistentDataTag instanceof CompoundTag) { -@@ -380,8 +381,15 @@ public abstract class BlockEntity { +@@ -375,8 +376,15 @@ public abstract class BlockEntity { // CraftBukkit start - add method public InventoryHolder getOwner() { diff --git a/patches/server/0161-AsyncTabCompleteEvent.patch b/patches/server/0161-AsyncTabCompleteEvent.patch index 8bf913b966ee..2436de291140 100644 --- a/patches/server/0161-AsyncTabCompleteEvent.patch +++ b/patches/server/0161-AsyncTabCompleteEvent.patch @@ -16,7 +16,7 @@ Also adds isCommand and getLocation to the sync TabCompleteEvent Co-authored-by: Aikar diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 1140eac4bb9443508df61e7a50d54add4b206654..752460c4650bebb2860bea82ca186a0f97b1692b 100644 +index 414077a1fed2955bd64ac7091af1daeda2a92e2c..79d9a58c66382fd94ab5f6020285e341b0114f6a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -722,21 +722,58 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -80,10 +80,10 @@ index 1140eac4bb9443508df61e7a50d54add4b206654..752460c4650bebb2860bea82ca186a0f this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index fa6284ebe3bdbf97b40a2ab61ba94062cdcf045e..367ecbb023ddfbadb92aa4351ff601a3ed58a358 100644 +index 2d1f92f75e83aacd39440d2619befdf6cd545af4..1dd440057cb1d8acce7bfaa7ab1814937a4c63af 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2298,7 +2298,7 @@ public final class CraftServer implements Server { +@@ -2297,7 +2297,7 @@ public final class CraftServer implements Server { offers = this.tabCompleteChat(player, message); } diff --git a/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch b/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch index 176e32776450..f61ad3434c98 100644 --- a/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch +++ b/patches/server/0164-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 30b28d9523820ed138c837ab9ee9bbb23c0dd285..01c32ed14b1047671883911f8606ef2924ebee73 100644 +index 3bb6eaabe8f62b556a52b83227b48f8324a9d0f0..b8aff86c8533ea92b0244ea85ed786073c4053a8 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1100,7 +1100,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1098,7 +1098,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider chunkRange = (chunkRange > this.level.spigotConfig.viewDistance) ? (byte) this.level.spigotConfig.viewDistance : chunkRange; chunkRange = (chunkRange > 8) ? 8 : chunkRange; @@ -23,7 +23,7 @@ index 30b28d9523820ed138c837ab9ee9bbb23c0dd285..01c32ed14b1047671883911f8606ef29 // Spigot end Iterator iterator = this.playerMap.getAllPlayers().iterator(); -@@ -1112,6 +1114,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1110,6 +1112,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } entityplayer = (ServerPlayer) iterator.next(); @@ -40,10 +40,10 @@ index 30b28d9523820ed138c837ab9ee9bbb23c0dd285..01c32ed14b1047671883911f8606ef29 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 93422468474189343cdc1e29f06f6dfb12e4760a..fef86453d5cf0fe0f11a2a061169cd301b777434 100644 +index ccb6f28689a3cf7da4ea323c5dd8f595036c4b43..d4eb7608a3e40d2da4c427e9b3a2ce916be86df1 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -520,6 +520,15 @@ public class ServerChunkCache extends ChunkSource { +@@ -504,6 +504,15 @@ public class ServerChunkCache extends ChunkSource { List list1; if (flag && (this.spawnEnemies || this.spawnFriendlies)) { diff --git a/patches/server/0166-PreCreatureSpawnEvent.patch b/patches/server/0166-PreCreatureSpawnEvent.patch index 8c22573ffb05..0f7306bfc5f9 100644 --- a/patches/server/0166-PreCreatureSpawnEvent.patch +++ b/patches/server/0166-PreCreatureSpawnEvent.patch @@ -55,10 +55,10 @@ index e139ed6bc6f2dd07fe546588b31309ba30ed9755..34c3bf85473b3ad89355ebc21b68c59b if (t0 != null) { diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 970161efa46b3a71ddae665f9df5966c70fd3471..5fe268b5c3297de7650f5d1f310cdf8ac231de75 100644 +index 17ab230c95901f0533997ac117d5b3d852fcd467..8f4ec4f0ea7ff2f9a952120785aea65f6559f897 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -506,6 +506,16 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -497,6 +497,16 @@ public class EntityType implements FeatureElement, EntityTypeT @Nullable public T spawn(ServerLevel worldserver, @Nullable Consumer consumer, BlockPos blockposition, EntitySpawnReason entityspawnreason, boolean flag, boolean flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { // CraftBukkit end @@ -114,10 +114,10 @@ index 6c29e55239fdcf8df3b9dc012aa80cebcd3a837a..bb3f3bec350dda43dbf5eda0a8c8057a Entity entity = EntityType.loadEntityRecursive(nbttagcompound, world, EntitySpawnReason.SPAWNER, (entity1) -> { entity1.moveTo(d0, d1, d2, entity1.getYRot(), entity1.getXRot()); diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 400166ad0199dd4b96684904ef4748cdb72381bb..0b41149ae134084cef4016241ce923dac0349846 100644 +index da0ddb8285e157be0cc7b940a9590be5e3061e3d..5a0ea71dc39c582ef6c843dc0532adb04ba120ce 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -230,7 +230,13 @@ public final class NaturalSpawner { +@@ -228,7 +228,13 @@ public final class NaturalSpawner { j1 = biomesettingsmobs_c.minCount + world.random.nextInt(1 + biomesettingsmobs_c.maxCount - biomesettingsmobs_c.minCount); } @@ -132,7 +132,7 @@ index 400166ad0199dd4b96684904ef4748cdb72381bb..0b41149ae134084cef4016241ce923da Mob entityinsentient = NaturalSpawner.getMobForSpawn(world, biomesettingsmobs_c.type); if (entityinsentient == null) { -@@ -278,10 +284,31 @@ public final class NaturalSpawner { +@@ -276,10 +282,31 @@ public final class NaturalSpawner { return squaredDistance <= 576.0D ? false : (world.getSharedSpawnPos().closerToCenterThan(new Vec3((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D), 24.0D) ? false : Objects.equals(new ChunkPos(pos), chunk.getPos()) || world.isNaturalSpawningAllowed((BlockPos) pos)); } diff --git a/patches/server/0174-Implement-extended-PaperServerListPingEvent.patch b/patches/server/0174-Implement-extended-PaperServerListPingEvent.patch index caa788dc531d..e0dbee4fe8c0 100644 --- a/patches/server/0174-Implement-extended-PaperServerListPingEvent.patch +++ b/patches/server/0174-Implement-extended-PaperServerListPingEvent.patch @@ -170,7 +170,7 @@ index 0000000000000000000000000000000000000000..30a19d10869f73d67b794e8e4c035bc5 + +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 5e9b85a46708cfe297533f13255629d72cd09c73..fe981e45b3b61f24da3e137c68312e98977dad73 100644 +index 0adba72139779a20eed8f489f7cfaff9e84e24f4..260d755666efc94e2ea2c8fdb38d7deddda82c08 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -3,6 +3,9 @@ package net.minecraft.server; @@ -183,7 +183,7 @@ index 5e9b85a46708cfe297533f13255629d72cd09c73..fe981e45b3b61f24da3e137c68312e98 import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -@@ -1592,7 +1595,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop() { @Override public int compare(final CraftTask o1, final CraftTask o2) { -@@ -93,12 +93,13 @@ public class CraftScheduler implements BukkitScheduler { +@@ -92,12 +92,13 @@ public class CraftScheduler implements BukkitScheduler { /** * These are tasks that are currently active. It's provided for 'viewing' the current state. */ @@ -187,7 +187,7 @@ index 0e7f402a7b841c5f6f5a4b699b7bb3d9f46b1af6..fd5a058dd802599598a64467cf25f083 private final Executor executor = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("Craft Scheduler Thread - %d").build()); private CraftAsyncDebugger debugHead = new CraftAsyncDebugger(-1, null, null) { @Override -@@ -107,12 +108,31 @@ public class CraftScheduler implements BukkitScheduler { +@@ -106,12 +107,31 @@ public class CraftScheduler implements BukkitScheduler { } }; private CraftAsyncDebugger debugTail = this.debugHead; @@ -219,7 +219,7 @@ index 0e7f402a7b841c5f6f5a4b699b7bb3d9f46b1af6..fd5a058dd802599598a64467cf25f083 @Override public int scheduleSyncDelayedTask(final Plugin plugin, final Runnable task) { return this.scheduleSyncDelayedTask(plugin, task, 0L); -@@ -229,7 +249,7 @@ public class CraftScheduler implements BukkitScheduler { +@@ -228,7 +248,7 @@ public class CraftScheduler implements BukkitScheduler { } else if (period < CraftTask.NO_REPEATING) { period = CraftTask.NO_REPEATING; } @@ -228,7 +228,7 @@ index 0e7f402a7b841c5f6f5a4b699b7bb3d9f46b1af6..fd5a058dd802599598a64467cf25f083 } @Override -@@ -245,6 +265,11 @@ public class CraftScheduler implements BukkitScheduler { +@@ -244,6 +264,11 @@ public class CraftScheduler implements BukkitScheduler { if (taskId <= 0) { return; } @@ -240,7 +240,7 @@ index 0e7f402a7b841c5f6f5a4b699b7bb3d9f46b1af6..fd5a058dd802599598a64467cf25f083 CraftTask task = this.runners.get(taskId); if (task != null) { task.cancel0(); -@@ -287,6 +312,11 @@ public class CraftScheduler implements BukkitScheduler { +@@ -286,6 +311,11 @@ public class CraftScheduler implements BukkitScheduler { @Override public void cancelTasks(final Plugin plugin) { Preconditions.checkArgument(plugin != null, "Cannot cancel tasks of null plugin"); @@ -252,7 +252,7 @@ index 0e7f402a7b841c5f6f5a4b699b7bb3d9f46b1af6..fd5a058dd802599598a64467cf25f083 final CraftTask task = new CraftTask( new Runnable() { @Override -@@ -326,6 +356,13 @@ public class CraftScheduler implements BukkitScheduler { +@@ -325,6 +355,13 @@ public class CraftScheduler implements BukkitScheduler { @Override public boolean isCurrentlyRunning(final int taskId) { @@ -266,7 +266,7 @@ index 0e7f402a7b841c5f6f5a4b699b7bb3d9f46b1af6..fd5a058dd802599598a64467cf25f083 final CraftTask task = this.runners.get(taskId); if (task == null) { return false; -@@ -344,6 +381,11 @@ public class CraftScheduler implements BukkitScheduler { +@@ -343,6 +380,11 @@ public class CraftScheduler implements BukkitScheduler { if (taskId <= 0) { return false; } @@ -278,7 +278,7 @@ index 0e7f402a7b841c5f6f5a4b699b7bb3d9f46b1af6..fd5a058dd802599598a64467cf25f083 for (CraftTask task = this.head.getNext(); task != null; task = task.getNext()) { if (task.getTaskId() == taskId) { return task.getPeriod() >= CraftTask.NO_REPEATING; // The task will run -@@ -355,6 +397,12 @@ public class CraftScheduler implements BukkitScheduler { +@@ -354,6 +396,12 @@ public class CraftScheduler implements BukkitScheduler { @Override public List getActiveWorkers() { @@ -291,7 +291,7 @@ index 0e7f402a7b841c5f6f5a4b699b7bb3d9f46b1af6..fd5a058dd802599598a64467cf25f083 final ArrayList workers = new ArrayList(); for (final CraftTask taskObj : this.runners.values()) { // Iterator will be a best-effort (may fail to grab very new values) if called from an async thread -@@ -392,6 +440,11 @@ public class CraftScheduler implements BukkitScheduler { +@@ -391,6 +439,11 @@ public class CraftScheduler implements BukkitScheduler { pending.add(task); } } @@ -303,7 +303,7 @@ index 0e7f402a7b841c5f6f5a4b699b7bb3d9f46b1af6..fd5a058dd802599598a64467cf25f083 return pending; } -@@ -400,6 +453,11 @@ public class CraftScheduler implements BukkitScheduler { +@@ -399,6 +452,11 @@ public class CraftScheduler implements BukkitScheduler { */ public void mainThreadHeartbeat() { this.currentTick++; @@ -315,7 +315,7 @@ index 0e7f402a7b841c5f6f5a4b699b7bb3d9f46b1af6..fd5a058dd802599598a64467cf25f083 final List temp = this.temp; this.parsePending(); while (this.isReady(this.currentTick)) { -@@ -434,7 +492,7 @@ public class CraftScheduler implements BukkitScheduler { +@@ -433,7 +491,7 @@ public class CraftScheduler implements BukkitScheduler { this.parsePending(); } else { // this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(this.currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); // Paper @@ -324,7 +324,7 @@ index 0e7f402a7b841c5f6f5a4b699b7bb3d9f46b1af6..fd5a058dd802599598a64467cf25f083 // We don't need to parse pending // (async tasks must live with race-conditions if they attempt to cancel between these few lines of code) } -@@ -453,7 +511,7 @@ public class CraftScheduler implements BukkitScheduler { +@@ -450,7 +508,7 @@ public class CraftScheduler implements BukkitScheduler { //this.debugHead = this.debugHead.getNextHead(this.currentTick); // Paper } @@ -333,7 +333,7 @@ index 0e7f402a7b841c5f6f5a4b699b7bb3d9f46b1af6..fd5a058dd802599598a64467cf25f083 final AtomicReference tail = this.tail; CraftTask tailTask = tail.get(); while (!tail.compareAndSet(tailTask, task)) { -@@ -462,7 +520,13 @@ public class CraftScheduler implements BukkitScheduler { +@@ -459,7 +517,13 @@ public class CraftScheduler implements BukkitScheduler { tailTask.setNext(task); } @@ -348,23 +348,12 @@ index 0e7f402a7b841c5f6f5a4b699b7bb3d9f46b1af6..fd5a058dd802599598a64467cf25f083 task.setNextRun(this.currentTick + delay); this.addTask(task); return task; -@@ -485,8 +549,8 @@ public class CraftScheduler implements BukkitScheduler { +@@ -482,7 +546,7 @@ public class CraftScheduler implements BukkitScheduler { return id; } - private void parsePending() { -- MinecraftTimings.bukkitSchedulerPendingTimer.startTiming(); + void parsePending() { // Paper -+ if (!this.isAsyncScheduler) MinecraftTimings.bukkitSchedulerPendingTimer.startTiming(); // Paper CraftTask head = this.head; CraftTask task = head.getNext(); CraftTask lastTask = head; -@@ -505,7 +569,7 @@ public class CraftScheduler implements BukkitScheduler { - task.setNext(null); - } - this.head = lastTask; -- MinecraftTimings.bukkitSchedulerPendingTimer.stopTiming(); -+ if (!this.isAsyncScheduler) MinecraftTimings.bukkitSchedulerPendingTimer.stopTiming(); // Paper - } - - private boolean isReady(final int currentTick) { diff --git a/patches/server/0186-Expand-World.spawnParticle-API-and-add-Builder.patch b/patches/server/0186-Expand-World.spawnParticle-API-and-add-Builder.patch index 8fcc3562f248..da14ccdaa5bd 100644 --- a/patches/server/0186-Expand-World.spawnParticle-API-and-add-Builder.patch +++ b/patches/server/0186-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 022ec2ff1c5a6a1de867b2a6dafb339d55a0905d..17cb827bc90d980d73719776fca967a1d307ce0a 100644 +index 88c93a2e67c8d1bc227c7fa35bb919a40009f931..0c0d19708832a49734ea08ae05696e0cb20616e4 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1566,12 +1566,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1536,12 +1536,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } public int sendParticles(ServerPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) { diff --git a/patches/server/0198-Make-shield-blocking-delay-configurable.patch b/patches/server/0198-Make-shield-blocking-delay-configurable.patch index 8bd30c1391bf..0c056446f0f1 100644 --- a/patches/server/0198-Make-shield-blocking-delay-configurable.patch +++ b/patches/server/0198-Make-shield-blocking-delay-configurable.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Make shield blocking delay configurable diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 76b71af07a311bc415b36f517afab31505a14483..0a4d2abc5b70c5e4e93dc06fe112e2398d9916e7 100644 +index 84e11e2c62e643f959f1a570a27f6ad07df165d4..08a2fbca50e26938e46e49dae7b101cfc375b02e 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -4103,12 +4103,24 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4101,12 +4101,24 @@ public abstract class LivingEntity extends Entity implements Attackable { if (this.isUsingItem() && !this.useItem.isEmpty()) { Item item = this.useItem.getItem(); diff --git a/patches/server/0201-Add-entity-knockback-events.patch b/patches/server/0201-Add-entity-knockback-events.patch index c41689a1967c..8615d22e3dc7 100644 --- a/patches/server/0201-Add-entity-knockback-events.patch +++ b/patches/server/0201-Add-entity-knockback-events.patch @@ -38,10 +38,10 @@ index 087f030985180b91a809fb45244e23106da62e34..011006bc2e88a9fec98796f939c07d88 } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 0a4d2abc5b70c5e4e93dc06fe112e2398d9916e7..c9d7589a18e9cee204f4e52368a60aa421c1e150 100644 +index 08a2fbca50e26938e46e49dae7b101cfc375b02e..cfff596d720efe5f5ee4ad1990c3ee0fd6e4e836 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1565,7 +1565,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1563,7 +1563,7 @@ public abstract class LivingEntity extends Entity implements Attackable { d1 = source.getSourcePosition().z() - this.getZ(); } @@ -50,7 +50,7 @@ index 0a4d2abc5b70c5e4e93dc06fe112e2398d9916e7..c9d7589a18e9cee204f4e52368a60aa4 if (!flag) { this.indicateDamage(d0, d1); } -@@ -1622,7 +1622,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1620,7 +1620,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } protected void blockedByShield(LivingEntity target) { @@ -59,7 +59,7 @@ index 0a4d2abc5b70c5e4e93dc06fe112e2398d9916e7..c9d7589a18e9cee204f4e52368a60aa4 } private boolean checkTotemDeathProtection(DamageSource source) { -@@ -1908,10 +1908,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1906,10 +1906,10 @@ public abstract class LivingEntity extends Entity implements Attackable { public void knockback(double strength, double x, double z) { // CraftBukkit start - EntityKnockbackEvent @@ -72,7 +72,7 @@ index 0a4d2abc5b70c5e4e93dc06fe112e2398d9916e7..c9d7589a18e9cee204f4e52368a60aa4 d0 *= 1.0D - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE); if (true || d0 > 0.0D) { // CraftBukkit - Call event even when force is 0 //this.hasImpulse = true; // CraftBukkit - Move down -@@ -1924,13 +1924,17 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1922,13 +1922,17 @@ public abstract class LivingEntity extends Entity implements Attackable { Vec3 vec3d1 = (new Vec3(d1, 0.0D, d2)).normalize().scale(d0); diff --git a/patches/server/0202-Expand-Explosions-API.patch b/patches/server/0202-Expand-Explosions-API.patch index b9a5452eb8d6..1952633714ed 100644 --- a/patches/server/0202-Expand-Explosions-API.patch +++ b/patches/server/0202-Expand-Explosions-API.patch @@ -9,10 +9,10 @@ Co-authored-by: Esoteric Enderman <90862990+EsotericEnderman@users.noreply.githu Co-authored-by: Bjarne Koll diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 17cb827bc90d980d73719776fca967a1d307ce0a..6283f3496f122d4b0c4ac297943baf469e44aee3 100644 +index 0c0d19708832a49734ea08ae05696e0cb20616e4..3324156c004e0506df8be23050f497d462b4b9c1 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1449,6 +1449,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1419,6 +1419,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } public ServerExplosion explode0(@Nullable Entity entity, @Nullable DamageSource damagesource, @Nullable ExplosionDamageCalculator explosiondamagecalculator, double d0, double d1, double d2, float f, boolean flag, Level.ExplosionInteraction world_a, ParticleOptions particleparam, ParticleOptions particleparam1, Holder holder) { @@ -24,7 +24,7 @@ index 17cb827bc90d980d73719776fca967a1d307ce0a..6283f3496f122d4b0c4ac297943baf46 // CraftBukkit end Explosion.BlockInteraction explosion_effect; -@@ -1480,6 +1485,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1450,6 +1455,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe Explosion.BlockInteraction explosion_effect1 = explosion_effect; Vec3 vec3d = new Vec3(d0, d1, d2); ServerExplosion serverexplosion = new ServerExplosion(this, entity, damagesource, explosiondamagecalculator, vec3d, f, flag, explosion_effect1); diff --git a/patches/server/0207-InventoryCloseEvent-Reason-API.patch b/patches/server/0207-InventoryCloseEvent-Reason-API.patch index 968d1a87f8e6..8e604276488b 100644 --- a/patches/server/0207-InventoryCloseEvent-Reason-API.patch +++ b/patches/server/0207-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 6283f3496f122d4b0c4ac297943baf469e44aee3..425c22fe94e83d880b331cbfb16dc67f22def1c7 100644 +index 3324156c004e0506df8be23050f497d462b4b9c1..75b2caba214c312f9afdd231ee3d75689380a5f3 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1234,7 +1234,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1204,7 +1204,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe 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 6283f3496f122d4b0c4ac297943baf469e44aee3..425c22fe94e83d880b331cbfb16dc67f } } } -@@ -2279,7 +2279,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2249,7 +2249,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // 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())) { @@ -75,10 +75,10 @@ index 98aeafcc51e23a7534c8d57e4db0eb58abb3f30b..29b836a75b835f0d5233db419fc5ca8d 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 752460c4650bebb2860bea82ca186a0f97b1692b..5f514f87b171c5c845d5d7714d2d2179fbb0c1a1 100644 +index 79d9a58c66382fd94ab5f6020285e341b0114f6a..f36d72153c1ec0426790ed3033500c3cb766af2d 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2641,10 +2641,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2638,10 +2638,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handleContainerClose(ServerboundContainerClosePacket packet) { @@ -96,10 +96,10 @@ index 752460c4650bebb2860bea82ca186a0f97b1692b..5f514f87b171c5c845d5d7714d2d2179 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 95b9341859ba6da6945faebf8430a044cc1ee828..038c5f16e60f0e182774e6df5b6c5359153a4b07 100644 +index a929c809dc1dcb2bdab4db0d2a8ca794189e93d9..c9c3ebcb7239bf01617a89f03cd0ad12dd0b2c34 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -469,7 +469,7 @@ public abstract class PlayerList { +@@ -468,7 +468,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/0214-Option-to-prevent-armor-stands-from-doing-entity-loo.patch b/patches/server/0214-Option-to-prevent-armor-stands-from-doing-entity-loo.patch index db5ae6ef6478..8f032f18fa4d 100644 --- a/patches/server/0214-Option-to-prevent-armor-stands-from-doing-entity-loo.patch +++ b/patches/server/0214-Option-to-prevent-armor-stands-from-doing-entity-loo.patch @@ -17,10 +17,10 @@ index aea97a30a9226275f8fbf9cb2c15d5ddf36371ac..e9d6211eb0f955eb95d2f73ad96799ef Iterator iterator = list.iterator(); diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index c628524274110bcad175472dbcb82e6c62476a12..3ccd28193bec6363eb87f916589310ee8b45dd3a 100644 +index e0986a141384de0ede38c88c2b116e083c63efe4..fb68aff87670f545ae5ba26db9f074a34375031e 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -766,6 +766,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -759,6 +759,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Paper end - Prevent block entity and entity crashes } } diff --git a/patches/server/0215-Vanished-players-don-t-have-rights.patch b/patches/server/0215-Vanished-players-don-t-have-rights.patch index 3bdc5087c3d1..dd1cb5bca923 100644 --- a/patches/server/0215-Vanished-players-don-t-have-rights.patch +++ b/patches/server/0215-Vanished-players-don-t-have-rights.patch @@ -39,10 +39,10 @@ index 752929f3bcd6404b08dad1c67e9a0023b671f10d..407f5db0a4b3884440bc49bf4f00d9c0 BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(context.getLevel(), context.getClickedPos()), player, CraftBlockData.fromData(state), defaultReturn); diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 3ccd28193bec6363eb87f916589310ee8b45dd3a..cf422de89f0ed81e7c9759328e28ca6b190283ef 100644 +index fb68aff87670f545ae5ba26db9f074a34375031e..924b496aaaa19c7ef69498730725ae9287e46e28 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -265,6 +265,45 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -263,6 +263,45 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); } diff --git a/patches/server/0221-Break-up-and-make-tab-spam-limits-configurable.patch b/patches/server/0221-Break-up-and-make-tab-spam-limits-configurable.patch index ceaa06bf27ed..92f889e9c052 100644 --- a/patches/server/0221-Break-up-and-make-tab-spam-limits-configurable.patch +++ b/patches/server/0221-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 5f514f87b171c5c845d5d7714d2d2179fbb0c1a1..4f6985d4458cfba8fd8323d06363763871da2fa0 100644 +index f36d72153c1ec0426790ed3033500c3cb766af2d..af519e9914bae40fa1605b0cd4cf02ca1d44f0e8 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -274,6 +274,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0224-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch b/patches/server/0224-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch index 4338c3faf291..6cd73f5ba74d 100644 --- a/patches/server/0224-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch +++ b/patches/server/0224-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Debug Entities option to debug dupe uuid issues diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 425c22fe94e83d880b331cbfb16dc67f22def1c7..a12d5de8834bbc3176be3d2c8353b2d4372dbc1d 100644 +index 75b2caba214c312f9afdd231ee3d75689380a5f3..0635e7ed67d45abb7c419cf4ebda0e64718b630e 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1196,6 +1196,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1166,6 +1166,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // CraftBukkit start private boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) { org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot diff --git a/patches/server/0225-Add-Early-Warning-Feature-to-WatchDog.patch b/patches/server/0225-Add-Early-Warning-Feature-to-WatchDog.patch index f6b02a9c462e..685cfead736d 100644 --- a/patches/server/0225-Add-Early-Warning-Feature-to-WatchDog.patch +++ b/patches/server/0225-Add-Early-Warning-Feature-to-WatchDog.patch @@ -9,10 +9,10 @@ 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 fe981e45b3b61f24da3e137c68312e98977dad73..87cfbc87198209acfe4354424974afc3cd33f5cd 100644 +index 260d755666efc94e2ea2c8fdb38d7deddda82c08..eb0adba0178a88243946e0c7f39503aa8c7d8feb 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1123,6 +1123,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop collidableExemptions = new HashSet<>(); public boolean bukkitPickUpLoot; public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper @@ -90,7 +90,7 @@ index 35dfaf46429f5478049835e1a5e4b03c362a64e8..a7e950bc5aa827c1b137a12c9eaaf7ea @Override public float getBukkitYaw() { -@@ -1574,11 +1575,12 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1572,11 +1573,12 @@ public abstract class LivingEntity extends Entity implements Attackable { if (this.isDeadOrDying()) { if (!this.checkTotemDeathProtection(source)) { @@ -106,7 +106,7 @@ index 35dfaf46429f5478049835e1a5e4b03c362a64e8..a7e950bc5aa827c1b137a12c9eaaf7ea } } else if (flag1) { this.playHurtSound(source); -@@ -1740,6 +1742,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1738,6 +1740,7 @@ public abstract class LivingEntity extends Entity implements Attackable { Entity entity = damageSource.getEntity(); LivingEntity entityliving = this.getKillCredit(); @@ -114,7 +114,7 @@ index 35dfaf46429f5478049835e1a5e4b03c362a64e8..a7e950bc5aa827c1b137a12c9eaaf7ea if (this.deathScore >= 0 && entityliving != null) { entityliving.awardKillScore(this, this.deathScore, damageSource); } -@@ -1751,24 +1754,59 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1749,24 +1752,59 @@ public abstract class LivingEntity extends Entity implements Attackable { if (!this.level().isClientSide && this.hasCustomName()) { if (org.spigotmc.SpigotConfig.logNamedDeaths) LivingEntity.LOGGER.info("Named entity {} died: {}", this, this.getCombatTracker().getDeathMessage().getString()); // Spigot } @@ -178,7 +178,7 @@ index 35dfaf46429f5478049835e1a5e4b03c362a64e8..a7e950bc5aa827c1b137a12c9eaaf7ea } } -@@ -1778,7 +1816,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1776,7 +1814,7 @@ public abstract class LivingEntity extends Entity implements Attackable { if (world instanceof ServerLevel worldserver) { boolean flag = false; @@ -187,7 +187,7 @@ index 35dfaf46429f5478049835e1a5e4b03c362a64e8..a7e950bc5aa827c1b137a12c9eaaf7ea if (worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { BlockPos blockposition = this.blockPosition(); BlockState iblockdata = Blocks.WITHER_ROSE.defaultBlockState(); -@@ -1807,24 +1845,37 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1805,24 +1843,37 @@ public abstract class LivingEntity extends Entity implements Attackable { } } diff --git a/patches/server/0245-Prevent-mob-spawning-from-loading-generating-chunks.patch b/patches/server/0245-Prevent-mob-spawning-from-loading-generating-chunks.patch index 1908c1da0cd8..e9d396eb027e 100644 --- a/patches/server/0245-Prevent-mob-spawning-from-loading-generating-chunks.patch +++ b/patches/server/0245-Prevent-mob-spawning-from-loading-generating-chunks.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Prevent mob spawning from loading/generating chunks also prevents if out of world border bounds diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 0b41149ae134084cef4016241ce923dac0349846..be2412ef8f8c331a881e442577cf05aec43f52bb 100644 +index 5a0ea71dc39c582ef6c843dc0532adb04ba120ce..c826bd20d1ba32ebb9069737ede88e122294ea7a 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -187,9 +187,9 @@ public final class NaturalSpawner { +@@ -185,9 +185,9 @@ public final class NaturalSpawner { StructureManager structuremanager = world.structureManager(); ChunkGenerator chunkgenerator = world.getChunkSource().getGenerator(); int i = pos.getY(); @@ -21,7 +21,7 @@ index 0b41149ae134084cef4016241ce923dac0349846..be2412ef8f8c331a881e442577cf05ae BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); int j = 0; int k = 0; -@@ -218,7 +218,7 @@ public final class NaturalSpawner { +@@ -216,7 +216,7 @@ public final class NaturalSpawner { if (entityhuman != null) { double d2 = entityhuman.distanceToSqr(d0, (double) i, d1); diff --git a/patches/server/0251-Add-LivingEntity-getTargetEntity.patch b/patches/server/0251-Add-LivingEntity-getTargetEntity.patch index 5b17b5d4ffa8..8f5a3aa5fa8d 100644 --- a/patches/server/0251-Add-LivingEntity-getTargetEntity.patch +++ b/patches/server/0251-Add-LivingEntity-getTargetEntity.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add LivingEntity#getTargetEntity diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index a7e950bc5aa827c1b137a12c9eaaf7eac867bdc3..b87b59a2ead87b6bda8a8c5bcfd63b128c88f626 100644 +index 7a89c25fcd1c76e4b176c257600db89788aa0f21..3bcf2ba5f065d946ded4020b9882bc4e19af0e08 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -4178,6 +4178,38 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4176,6 +4176,38 @@ public abstract class LivingEntity extends Entity implements Attackable { return this.level().clip(raytrace); } diff --git a/patches/server/0257-Add-option-to-prevent-players-from-moving-into-unloa.patch b/patches/server/0257-Add-option-to-prevent-players-from-moving-into-unloa.patch index 33cebcaddbc4..a382aa3965a7 100644 --- a/patches/server/0257-Add-option-to-prevent-players-from-moving-into-unloa.patch +++ b/patches/server/0257-Add-option-to-prevent-players-from-moving-into-unloa.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add option to prevent players from moving into unloaded diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 4f6985d4458cfba8fd8323d06363763871da2fa0..b15cd1b5b4e4e20a70099acd351e3ac1025a6f31 100644 +index af519e9914bae40fa1605b0cd4cf02ca1d44f0e8..f57c133de5e974d2c86145f697d3636347a29d65 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -498,9 +498,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0260-Improve-Server-Thread-Pool-and-Thread-Priorities.patch b/patches/server/0260-Improve-Server-Thread-Pool-and-Thread-Priorities.patch index 6a48c451fb47..71b311db27f3 100644 --- a/patches/server/0260-Improve-Server-Thread-Pool-and-Thread-Priorities.patch +++ b/patches/server/0260-Improve-Server-Thread-Pool-and-Thread-Priorities.patch @@ -94,10 +94,10 @@ index 8cac2075077b1d9c2b01e09c99780ff9e204abb2..bf2833c92eca6491699b4a89410e4e46 return new TracingExecutor(executorService); } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 87cfbc87198209acfe4354424974afc3cd33f5cd..3c5c3d6d3f95378181a2316337e6f9b910c19003 100644 +index eb0adba0178a88243946e0c7f39503aa8c7d8feb..3669a2943b01e0e9add41df1ff38afd1cd40e96b 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -333,6 +333,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { MinecraftServer.LOGGER.error("Uncaught exception in server thread", throwable); }); diff --git a/patches/server/0261-Optimize-World-Time-Updates.patch b/patches/server/0261-Optimize-World-Time-Updates.patch index 96a00b757783..15bcb789439e 100644 --- a/patches/server/0261-Optimize-World-Time-Updates.patch +++ b/patches/server/0261-Optimize-World-Time-Updates.patch @@ -8,12 +8,12 @@ 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 3c5c3d6d3f95378181a2316337e6f9b910c19003..2011ffeeee5815f667f585d94c5ffdf52ff94884 100644 +index 3669a2943b01e0e9add41df1ff38afd1cd40e96b..a4c897000a5e70e64b5fe4306581b04d8d38bce2 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1639,12 +1639,24 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements FeatureElement, EntityTypeT +@@ -433,7 +433,7 @@ public class EntityType implements FeatureElement, EntityTypeT @Nullable public T spawn(ServerLevel world, @Nullable ItemStack stack, @Nullable Player player, BlockPos pos, EntitySpawnReason spawnReason, boolean alignPosition, boolean invertY) { // CraftBukkit start diff --git a/patches/server/0280-Add-PlayerPostRespawnEvent.patch b/patches/server/0280-Add-PlayerPostRespawnEvent.patch index 5adb0c50ef42..a887fd99185f 100644 --- a/patches/server/0280-Add-PlayerPostRespawnEvent.patch +++ b/patches/server/0280-Add-PlayerPostRespawnEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerPostRespawnEvent diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index dffc7f0c9c730bc629ee169eca3a7a997c2cc7b1..29110c0b950c3073ab699d8ad1523ece2e8d3408 100644 +index fd1fe9a72a1d4e87b97a34fc79ab1429d31207e5..2cfc2213e3036585dc4723eecf747e1c37d53b72 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -705,6 +705,10 @@ public abstract class PlayerList { +@@ -704,6 +704,10 @@ public abstract class PlayerList { entityplayer1.addTag(s); } @@ -19,7 +19,7 @@ index dffc7f0c9c730bc629ee169eca3a7a997c2cc7b1..29110c0b950c3073ab699d8ad1523ece // CraftBukkit start - fire PlayerRespawnEvent TeleportTransition teleporttransition; -@@ -712,11 +716,16 @@ public abstract class PlayerList { +@@ -711,11 +715,16 @@ public abstract class PlayerList { teleporttransition = entityplayer.findRespawnPositionAndUseSpawnBlock(!flag, TeleportTransition.DO_NOTHING, reason); if (!flag) entityplayer.reset(); // SPIGOT-4785 @@ -37,7 +37,7 @@ index dffc7f0c9c730bc629ee169eca3a7a997c2cc7b1..29110c0b950c3073ab699d8ad1523ece return entityplayer; } // Spigot End -@@ -764,6 +773,11 @@ public abstract class PlayerList { +@@ -763,6 +772,11 @@ public abstract class PlayerList { if (iblockdata.is(Blocks.RESPAWN_ANCHOR)) { entityplayer1.connection.send(new ClientboundSoundPacket(SoundEvents.RESPAWN_ANCHOR_DEPLETE, SoundSource.BLOCKS, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 1.0F, 1.0F, worldserver.getRandom().nextLong())); } @@ -49,7 +49,7 @@ index dffc7f0c9c730bc629ee169eca3a7a997c2cc7b1..29110c0b950c3073ab699d8ad1523ece } // Added from changeDimension this.sendAllPlayerInfo(entityplayer); // Update health, etc... -@@ -785,6 +799,13 @@ public abstract class PlayerList { +@@ -784,6 +798,13 @@ public abstract class PlayerList { if (entityplayer.connection.isDisconnected()) { this.save(entityplayer); } diff --git a/patches/server/0281-Server-Tick-Events.patch b/patches/server/0281-Server-Tick-Events.patch index 597da613b90d..5e040767919f 100644 --- a/patches/server/0281-Server-Tick-Events.patch +++ b/patches/server/0281-Server-Tick-Events.patch @@ -6,21 +6,21 @@ 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 7f511a811a73a092ea6a27e4f8afef58dd83b50a..f245b10bc2931ab165057f27a8ff79ea77ea726e 100644 +index 8f427475f7418bbfb8121dbd3e25e7827775ea41..447b8f9ede3f57c6c5f968a0d25153c5c8770c5a 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1504,6 +1504,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop chunkresult = (ChunkResult) completablefuture.join(); + ChunkAccess ichunkaccess1 = (ChunkAccess) chunkresult.orElse(null); // CraftBukkit - decompile error + diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index a0a38a78987f05fe47b5a85a49659e7469674210..6e3765b00272548318fca647a80c56ad634b7ecc 100644 +index 800dd7338d77289b7d0e6e126342eaea184d3e43..ecb9f6f0c9b24313b9e55b3a4c4f4bba40bc8fb3 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -412,6 +412,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -410,6 +410,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit } diff --git a/patches/server/0313-Entity-Jump-API.patch b/patches/server/0313-Entity-Jump-API.patch index 290c2cea302e..66167bd061bd 100644 --- a/patches/server/0313-Entity-Jump-API.patch +++ b/patches/server/0313-Entity-Jump-API.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Entity Jump API public net.minecraft.world.entity.LivingEntity jumping diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index f720d4d93ed13b1b9287a1ee7dc8bc4794834e1a..304a401fb1f378ff2cbfd888acf56a8516f79310 100644 +index ebfea3adbedd2695f645421019a276efbc73ee63..724fe482f1711008dc43fef96c4512a18ed54a48 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3539,8 +3539,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3537,8 +3537,10 @@ public abstract class LivingEntity extends Entity implements Attackable { } else if (this.isInLava() && (!this.onGround() || d3 > d4)) { this.jumpInLiquid(FluidTags.LAVA); } else if ((this.onGround() || flag && d3 <= d4) && this.noJumpDelay == 0) { diff --git a/patches/server/0320-Optimise-Chunk-getFluid.patch b/patches/server/0320-Optimise-Chunk-getFluid.patch index 1126b881da2f..b81a71067cd9 100644 --- a/patches/server/0320-Optimise-Chunk-getFluid.patch +++ b/patches/server/0320-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 add5ec0f8e8bd0b89511dcb656e1d4cda702a86b..7181acfafad91aa5f6ab7ce663d9be4a1b65b02a 100644 +index a1b6c13d496519ef6ce240036cec6642626903b9..d4bd4cbc5c4773659662a6d7a09b21a99463c1fb 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -293,18 +293,20 @@ public class LevelChunk extends ChunkAccess { diff --git a/patches/server/0322-Add-tick-times-API-and-mspt-command.patch b/patches/server/0322-Add-tick-times-API-and-mspt-command.patch index 9426f15bec79..cbef13696103 100644 --- a/patches/server/0322-Add-tick-times-API-and-mspt-command.patch +++ b/patches/server/0322-Add-tick-times-API-and-mspt-command.patch @@ -125,10 +125,10 @@ index 72f2e81b9905a0d57ed8e2a88578f62d5235c456..7b58b2d6297800c2dcdbf7539e5ab8e7 public static void registerCommands(final MinecraftServer server) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index f245b10bc2931ab165057f27a8ff79ea77ea726e..5cc5f4c0a91e7c667e9271de17ffa845f566bd4d 100644 +index 447b8f9ede3f57c6c5f968a0d25153c5c8770c5a..652626c30a5e25ada797ec01273f1e016798aae1 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -264,6 +264,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 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 6e3765b00272548318fca647a80c56ad634b7ecc..609c2e1946c86deabb885d7d703cf42273839f1e 100644 +index ecb9f6f0c9b24313b9e55b3a4c4f4bba40bc8fb3..0995a3a274df988a5c63c813de8213019a7c47c4 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2232,7 +2232,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2202,7 +2202,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public void onTrackingStart(Entity entity) { org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot @@ -37,7 +37,7 @@ index 6e3765b00272548318fca647a80c56ad634b7ecc..609c2e1946c86deabb885d7d703cf422 if (entity instanceof ServerPlayer entityplayer) { ServerLevel.this.players.add(entityplayer); ServerLevel.this.updateSleepingPlayerList(); -@@ -2262,6 +2262,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2232,6 +2232,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe entity.updateDynamicGameEventListener(DynamicGameEventListener::add); entity.inWorld = true; // CraftBukkit - Mark entity as in world entity.valid = true; // CraftBukkit diff --git a/patches/server/0331-Don-t-move-existing-players-to-world-spawn.patch b/patches/server/0331-Don-t-move-existing-players-to-world-spawn.patch index 6750b4fb1af6..4c5196324898 100644 --- a/patches/server/0331-Don-t-move-existing-players-to-world-spawn.patch +++ b/patches/server/0331-Don-t-move-existing-players-to-world-spawn.patch @@ -35,10 +35,10 @@ index 965ca28a8877f5e541741c45bace7075d15a77d7..adbc8e74f0b454403bc682de11bd0342 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 29110c0b950c3073ab699d8ad1523ece2e8d3408..074f3518b060c4aa079b1d311b7fcb10d4a95981 100644 +index 2cfc2213e3036585dc4723eecf747e1c37d53b72..ad4f5a4e00b9b517841acd0b4ff5088e45451bf4 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -227,6 +227,7 @@ public abstract class PlayerList { +@@ -226,6 +226,7 @@ public abstract class PlayerList { // Paper start - Entity#getEntitySpawnReason if (optional.isEmpty()) { player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login diff --git a/patches/server/0336-Don-t-run-entity-collision-code-if-not-needed.patch b/patches/server/0336-Don-t-run-entity-collision-code-if-not-needed.patch index e0919bb4b1e3..543230b8509a 100644 --- a/patches/server/0336-Don-t-run-entity-collision-code-if-not-needed.patch +++ b/patches/server/0336-Don-t-run-entity-collision-code-if-not-needed.patch @@ -12,10 +12,10 @@ The entity's current team collision rule causes them to NEVER collide. Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 304a401fb1f378ff2cbfd888acf56a8516f79310..ecf188d659c8542ca2b52c5e7ec779bfacb5614c 100644 +index 724fe482f1711008dc43fef96c4512a18ed54a48..4fb99e3ee14d2e7fe2720e25af1c890004b0c250 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3683,10 +3683,24 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3681,10 +3681,24 @@ public abstract class LivingEntity extends Entity implements Attackable { if (!(world instanceof ServerLevel worldserver)) { this.level().getEntities(EntityTypeTest.forClass(net.minecraft.world.entity.player.Player.class), this.getBoundingBox(), EntitySelector.pushableBy(this)).forEach(this::doPush); } else { diff --git a/patches/server/0339-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch b/patches/server/0339-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch index 0863194ba30a..d7a416c036ce 100644 --- a/patches/server/0339-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch +++ b/patches/server/0339-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch @@ -31,10 +31,10 @@ delays anymore. public net.minecraft.server.level.ChunkMap addEntity(Lnet/minecraft/world/entity/Entity;)V diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 926e1ebfe3a011a28fb82b855511aaabca0c4072..4d8dcc47b39d28ab715110e55110869fe3c9b456 100644 +index 5963f38e050c1ea5c77dde91028d306dfe9b94ba..352675e0b835d5f04576db6599e8840754a40340 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1307,6 +1307,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1305,6 +1305,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider return; } // Paper end - ignore and warn about illegal addEntity calls instead of crashing server @@ -55,10 +55,10 @@ index 9911e231ad021286f2da90057b06874f7b4e3b4d..807068fc6065f71961d34cb4f18b6eb3 // CraftBukkit end public boolean isRealPlayer; // Paper diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 074f3518b060c4aa079b1d311b7fcb10d4a95981..ec5673ff22706006a2bcfb5f5a9e8840ee27ac45 100644 +index ad4f5a4e00b9b517841acd0b4ff5088e45451bf4..4ff14dc6996634b0fcd365f76055023601ad2be0 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -300,6 +300,13 @@ public abstract class PlayerList { +@@ -299,6 +299,13 @@ public abstract class PlayerList { this.playersByUUID.put(player.getUUID(), player); // this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(entityplayer))); // CraftBukkit - replaced with loop below @@ -72,7 +72,7 @@ index 074f3518b060c4aa079b1d311b7fcb10d4a95981..ec5673ff22706006a2bcfb5f5a9e8840 // CraftBukkit start CraftPlayer bukkitPlayer = player.getBukkitEntity(); -@@ -338,6 +345,8 @@ public abstract class PlayerList { +@@ -337,6 +344,8 @@ public abstract class PlayerList { player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(entityplayer1))); } player.sentListPacket = true; @@ -81,7 +81,7 @@ index 074f3518b060c4aa079b1d311b7fcb10d4a95981..ec5673ff22706006a2bcfb5f5a9e8840 // CraftBukkit end player.refreshEntityData(player); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn -@@ -353,8 +362,7 @@ public abstract class PlayerList { +@@ -352,8 +361,7 @@ public abstract class PlayerList { worldserver1 = player.serverLevel(); // CraftBukkit - Update in case join event changed it // CraftBukkit end this.sendActivePlayerEffects(player); diff --git a/patches/server/0340-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch b/patches/server/0340-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch index 270260266ebf..3dae78af463b 100644 --- a/patches/server/0340-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch +++ b/patches/server/0340-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch @@ -10,10 +10,10 @@ Co-authored-by: Wyatt Childers Co-authored-by: Jake Potrebic diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index ec5673ff22706006a2bcfb5f5a9e8840ee27ac45..c8c27311ade7d4a70d5398b3a4cb50eedd02a2f9 100644 +index 4ff14dc6996634b0fcd365f76055023601ad2be0..530369764cad77466995f8f65070eec6a5de74f2 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -198,6 +198,7 @@ public abstract class PlayerList { +@@ -197,6 +197,7 @@ public abstract class PlayerList { } Optional optional = this.load(player); // CraftBukkit - decompile error @@ -21,7 +21,7 @@ index ec5673ff22706006a2bcfb5f5a9e8840ee27ac45..c8c27311ade7d4a70d5398b3a4cb50ee // CraftBukkit start - Better rename detection if (optional.isPresent()) { CompoundTag nbttagcompound = optional.get(); -@@ -207,19 +208,47 @@ public abstract class PlayerList { +@@ -206,19 +207,47 @@ public abstract class PlayerList { } } // CraftBukkit end @@ -72,7 +72,7 @@ index ec5673ff22706006a2bcfb5f5a9e8840ee27ac45..c8c27311ade7d4a70d5398b3a4cb50ee } else { worldserver1 = worldserver; } -@@ -227,6 +256,10 @@ public abstract class PlayerList { +@@ -226,6 +255,10 @@ public abstract class PlayerList { // Paper start - Entity#getEntitySpawnReason if (optional.isEmpty()) { player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login diff --git a/patches/server/0341-Add-PlayerAttackEntityCooldownResetEvent.patch b/patches/server/0341-Add-PlayerAttackEntityCooldownResetEvent.patch index ce70659c9038..620e81e21006 100644 --- a/patches/server/0341-Add-PlayerAttackEntityCooldownResetEvent.patch +++ b/patches/server/0341-Add-PlayerAttackEntityCooldownResetEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerAttackEntityCooldownResetEvent diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index ecf188d659c8542ca2b52c5e7ec779bfacb5614c..324d654420c3d11f0695fdf029fde0300a865317 100644 +index 4fb99e3ee14d2e7fe2720e25af1c890004b0c250..25a2085ed68d393afbb658b63a1cd39af98f39fa 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2354,7 +2354,17 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2352,7 +2352,17 @@ public abstract class LivingEntity extends Entity implements Attackable { } if (damagesource.getEntity() instanceof net.minecraft.world.entity.player.Player) { diff --git a/patches/server/0344-Fix-item-duplication-and-teleport-issues.patch b/patches/server/0344-Fix-item-duplication-and-teleport-issues.patch index 77d7c3a5b207..d818b547f11b 100644 --- a/patches/server/0344-Fix-item-duplication-and-teleport-issues.patch +++ b/patches/server/0344-Fix-item-duplication-and-teleport-issues.patch @@ -68,10 +68,10 @@ index 5b8e264098f1b713de15f714bae59d3efda365cf..d5f96ed753e8298085e40c6181285cd6 Iterator iterator = this.getPassengers().iterator(); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 324d654420c3d11f0695fdf029fde0300a865317..f7323f54b2ac7236d26da8998a88432f9776e1ea 100644 +index 25a2085ed68d393afbb658b63a1cd39af98f39fa..718ccabb46d4520ba363d21a33e06eb2c9ff62ee 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1767,9 +1767,9 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1765,9 +1765,9 @@ public abstract class LivingEntity extends Entity implements Attackable { // Paper start org.bukkit.event.entity.EntityDeathEvent deathEvent = this.dropAllDeathLoot(worldserver, damageSource); if (deathEvent == null || !deathEvent.isCancelled()) { @@ -84,7 +84,7 @@ index 324d654420c3d11f0695fdf029fde0300a865317..f7323f54b2ac7236d26da8998a88432f // Paper start - clear equipment if event is not cancelled if (this instanceof Mob) { for (EquipmentSlot slot : this.clearedEquipmentSlots) { -@@ -1863,8 +1863,13 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1861,8 +1861,13 @@ public abstract class LivingEntity extends Entity implements Attackable { this.dropCustomDeathLoot(world, damageSource, flag); this.clearEquipmentSlots = prev; // Paper } diff --git a/patches/server/0346-Validate-PickItem-Packet-and-kick-for-invalid.patch b/patches/server/0346-Validate-PickItem-Packet-and-kick-for-invalid.patch index cc98d91687ab..6b1b7c3df379 100644 --- a/patches/server/0346-Validate-PickItem-Packet-and-kick-for-invalid.patch +++ b/patches/server/0346-Validate-PickItem-Packet-and-kick-for-invalid.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Validate PickItem Packet and kick for invalid diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index df2718d7e7dd7969f49b3467347fa2adcf60132a..1b82e733c107540618cb1f69511ea9e1a4a13fc8 100644 +index 8a58c1bdda065edd7b8560cd43e805de3fe0b178..59c12f6d5d96835b4b37ed5a761f25f8f147c54a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -906,7 +906,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0348-misc-debugging-dumps.patch b/patches/server/0348-misc-debugging-dumps.patch index c11d5f369e0c..64ee1d9744f0 100644 --- a/patches/server/0348-misc-debugging-dumps.patch +++ b/patches/server/0348-misc-debugging-dumps.patch @@ -49,10 +49,10 @@ index c847fbdb6f52386570eb4c070fcc01d39cc52151..a7eb2a37a81a414dcb19319c075faefe StackTraceElement[] astacktraceelement = exception.getStackTrace(); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 5cc5f4c0a91e7c667e9271de17ffa845f566bd4d..07045495e7d3f7e256bf30a777a5a7536dfe2446 100644 +index 652626c30a5e25ada797ec01273f1e016798aae1..909302aa0afc082a2d0bf55fd31ff9c510e8c3c5 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -931,6 +931,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop task, long delay, long period) throws IllegalArgumentException { diff --git a/patches/server/0364-Prevent-position-desync-causing-tp-exploit.patch b/patches/server/0364-Prevent-position-desync-causing-tp-exploit.patch index ebbd08637af1..8b73d196cfd9 100644 --- a/patches/server/0364-Prevent-position-desync-causing-tp-exploit.patch +++ b/patches/server/0364-Prevent-position-desync-causing-tp-exploit.patch @@ -13,7 +13,7 @@ behaviour, we need to move all of this dangerous logic outside of the move call and into an appropriate place in the tick method. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 9286012c7a07e1a621035b0563cb06a3421ea945..f4f2b6733780312c289af96ec8ffe1fbf732651e 100644 +index 6c9f7a4d3c7551157d22f17e8a66ada2c50c0550..12827fdd39bb7571739efa482ceb1e32f64ea982 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1359,6 +1359,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0366-Add-PlayerRecipeBookClickEvent.patch b/patches/server/0366-Add-PlayerRecipeBookClickEvent.patch index 504a8bac86db..8083914a426a 100644 --- a/patches/server/0366-Add-PlayerRecipeBookClickEvent.patch +++ b/patches/server/0366-Add-PlayerRecipeBookClickEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerRecipeBookClickEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index f4f2b6733780312c289af96ec8ffe1fbf732651e..09b478545ab5eed86dda17c5c74c585c7d3e6df8 100644 +index 12827fdd39bb7571739efa482ceb1e32f64ea982..300f543913979427b28578e5bb3270b20065098c 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -199,6 +199,7 @@ import net.minecraft.world.phys.Vec3; @@ -16,7 +16,7 @@ index f4f2b6733780312c289af96ec8ffe1fbf732651e..09b478545ab5eed86dda17c5c74c585c import org.slf4j.Logger; // CraftBukkit start -@@ -3093,21 +3094,41 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3090,21 +3091,41 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl ServerGamePacketListenerImpl.LOGGER.debug("Player {} tried to place impossible recipe {}", this.player, recipeholder.id().location()); return; } diff --git a/patches/server/0368-Add-permission-for-command-blocks.patch b/patches/server/0368-Add-permission-for-command-blocks.patch index f971d5b25aad..0a7fb386cc21 100644 --- a/patches/server/0368-Add-permission-for-command-blocks.patch +++ b/patches/server/0368-Add-permission-for-command-blocks.patch @@ -18,7 +18,7 @@ index 4623c8acd125dff4919c4e2045b848310d785da5..86e4559da2344f228ef4d1c4ac3c115f return false; } else if (this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 09b478545ab5eed86dda17c5c74c585c7d3e6df8..acf13898f316c0ddf3c31c0ac716322c23234318 100644 +index 300f543913979427b28578e5bb3270b20065098c..0884f71d3264c2a09d2a0958d4751962e4156526 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -818,7 +818,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch b/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch index feb2f98133e3..95cf927bee75 100644 --- a/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch +++ b/patches/server/0370-Fix-Per-World-Difficulty-Remembering-Difficulty.patch @@ -8,10 +8,10 @@ makes it so that the server keeps the last difficulty used instead of restoring the server.properties every single load. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 075928ac5095f95789839c82b528f60b356918b3..1be085de963e1c4e5b5b1902f8dc46b120846226 100644 +index 03d6045fd5721b32852a357f1f2e3d2e16efb85b..fce70aa2b0d92c6291720b75a07a6472eb55855b 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -852,7 +852,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L) { this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 -@@ -3091,6 +3093,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3088,6 +3090,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @Override public void handlePlaceRecipe(ServerboundPlaceRecipePacket packet) { diff --git a/patches/server/0452-Fix-interact-event-not-being-called-sometimes.patch b/patches/server/0452-Fix-interact-event-not-being-called-sometimes.patch index aba682dc6c5d..72c54e87a3f1 100644 --- a/patches/server/0452-Fix-interact-event-not-being-called-sometimes.patch +++ b/patches/server/0452-Fix-interact-event-not-being-called-sometimes.patch @@ -11,7 +11,7 @@ Subject: [PATCH] Fix interact event not being called sometimes Co-authored-by: Moulberry diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index bca6e44c6a6584be2537d8be1279497b3394c447..0254ca5ed57de292ecd17900bb4f3d2874e12556 100644 +index f2c1893677004b1699beb16ebfcbe9816aad2a78..03e87e35f4478d948602569c319a7b5a0e938cd5 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1785,7 +1785,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -23,7 +23,7 @@ index bca6e44c6a6584be2537d8be1279497b3394c447..0254ca5ed57de292ecd17900bb4f3d28 this.player.swing(enumhand, true); } } -@@ -2409,13 +2409,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2406,13 +2406,20 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl double d3 = Math.max(this.player.blockInteractionRange(), this.player.entityInteractionRange()); // SPIGOT-5607: Only call interact event if no block or entity is being clicked. Use bukkit ray trace method, because it handles blocks and entities at the same time // SPIGOT-7429: Make sure to call PlayerInteractEvent for spectators and non-pickable entities diff --git a/patches/server/0457-Add-ServerResourcesReloadedEvent.patch b/patches/server/0457-Add-ServerResourcesReloadedEvent.patch index efe5237d8b5a..71fc31fbfd1b 100644 --- a/patches/server/0457-Add-ServerResourcesReloadedEvent.patch +++ b/patches/server/0457-Add-ServerResourcesReloadedEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add ServerResourcesReloadedEvent diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index a26e3620346b80b00e2ca29e7f393bca404d8a50..c4882d30b64c3dd7efe44c38ff130c045d5549d8 100644 +index f6667d9f514a821fd539e193dde1f78e77ca0fbf..264d0f57422b4fc03c5845d7456b22c9a48dd7ae 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2194,7 +2194,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop completablefuture = CompletableFuture.supplyAsync(() -> { Stream stream = dataPacks.stream(); // CraftBukkit - decompile error PackRepository resourcepackrepository = this.packRepository; -@@ -2229,6 +2235,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { this.getServer().execute(() -> { diff --git a/patches/server/0465-Fix-villager-boat-exploit.patch b/patches/server/0465-Fix-villager-boat-exploit.patch index f35fe8a11e7b..adb461e1ed98 100644 --- a/patches/server/0465-Fix-villager-boat-exploit.patch +++ b/patches/server/0465-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 4975b4222d52eddbb42e9c9cd08eef56859080c8..70b7871091ab9b64d2a5503620a71c3d5585c25d 100644 +index 819fb4ef54dce33ec91604491132771f157c8d83..1e5cc810748af34f591d305055fe00a688213617 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -545,6 +545,14 @@ public abstract class PlayerList { +@@ -544,6 +544,14 @@ public abstract class PlayerList { PlayerList.LOGGER.debug("Removing player mount"); entityplayer.stopRiding(); entity.getPassengersAndSelf().forEach((entity1) -> { diff --git a/patches/server/0466-Add-sendOpLevel-API.patch b/patches/server/0466-Add-sendOpLevel-API.patch index fde6ae317a57..c938f70a51a8 100644 --- a/patches/server/0466-Add-sendOpLevel-API.patch +++ b/patches/server/0466-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 70b7871091ab9b64d2a5503620a71c3d5585c25d..7676dbe55b4bf6e0472dc0190c01e6ecfcbb464e 100644 +index 1e5cc810748af34f591d305055fe00a688213617..240a0e487ede08d1dd5050812ca4f68db4cd2dd1 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1026,6 +1026,11 @@ public abstract class PlayerList { +@@ -1025,6 +1025,11 @@ public abstract class PlayerList { } private void sendPlayerPermissionLevel(ServerPlayer player, int permissionLevel) { @@ -20,7 +20,7 @@ index 70b7871091ab9b64d2a5503620a71c3d5585c25d..7676dbe55b4bf6e0472dc0190c01e6ec if (player.connection != null) { byte b0; -@@ -1040,8 +1045,10 @@ public abstract class PlayerList { +@@ -1039,8 +1044,10 @@ public abstract class PlayerList { player.connection.send(new ClientboundEntityEventPacket(player, b0)); } diff --git a/patches/server/0467-Add-RegistryAccess-for-managing-Registries.patch b/patches/server/0467-Add-RegistryAccess-for-managing-Registries.patch index 2f3085960e10..ccdf448b22c2 100644 --- a/patches/server/0467-Add-RegistryAccess-for-managing-Registries.patch +++ b/patches/server/0467-Add-RegistryAccess-for-managing-Registries.patch @@ -861,7 +861,7 @@ index b4ed857f2437759b71b75d7ab36c986a2fd71dbc..09929f580164abcd1c04061d04c6aa99 @Override public B get(NamespacedKey namespacedKey) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index dd3940c2aacfa835b528a882f3ec5dd4d98bd59f..ee231d93d216571a45b11b49663b2ea91c47a1c7 100644 +index 30675a23a25dc065e09d97b9b08386c9f41989d8..a12dc990a9094e964be2af26a5135e3b798f9666 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -284,7 +284,7 @@ public final class CraftServer implements Server { @@ -873,7 +873,7 @@ index dd3940c2aacfa835b528a882f3ec5dd4d98bd59f..ee231d93d216571a45b11b49663b2ea9 private YamlConfiguration configuration; private YamlConfiguration commandsConfiguration; private final Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions())); -@@ -432,6 +432,7 @@ public final class CraftServer implements Server { +@@ -431,6 +431,7 @@ public final class CraftServer implements Server { } private void loadCompatibilities() { @@ -881,7 +881,7 @@ index dd3940c2aacfa835b528a882f3ec5dd4d98bd59f..ee231d93d216571a45b11b49663b2ea9 ConfigurationSection compatibilities = this.configuration.getConfigurationSection("settings.compatibility"); if (compatibilities == null) { this.activeCompatibilities = Collections.emptySet(); -@@ -2745,7 +2746,7 @@ public final class CraftServer implements Server { +@@ -2744,7 +2745,7 @@ public final class CraftServer implements Server { @Override public Registry getRegistry(Class aClass) { diff --git a/patches/server/0480-Add-EntityMoveEvent.patch b/patches/server/0480-Add-EntityMoveEvent.patch index 977aa2c046b0..6dfa7990a673 100644 --- a/patches/server/0480-Add-EntityMoveEvent.patch +++ b/patches/server/0480-Add-EntityMoveEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add EntityMoveEvent diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index c4882d30b64c3dd7efe44c38ff130c045d5549d8..a6435cc675bca502994a31d2f2d91257c8c1fa2f 100644 +index 264d0f57422b4fc03c5845d7456b22c9a48dd7ae..a200aacb1eaa749baa36be8be63b3f1421913b60 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1684,6 +1684,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent @@ -17,10 +17,10 @@ index c4882d30b64c3dd7efe44c38ff130c045d5549d8..a6435cc675bca502994a31d2f2d91257 gameprofilerfiller.push(() -> { String s = String.valueOf(worldserver); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 840651df480dfc6e494240aaa46ea4063171c0de..12f46c94710830f464ff27a3d415140c36065e10 100644 +index 0e984f3521b578779dd9d0142bce7db433b78f07..1c3f41d7ed7320342fe68c5ab6eb57dbdfd4bf69 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -231,6 +231,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -229,6 +229,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public final LevelStorageSource.LevelStorageAccess convertable; public final UUID uuid; public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent @@ -29,10 +29,10 @@ index 840651df480dfc6e494240aaa46ea4063171c0de..12f46c94710830f464ff27a3d415140c public LevelChunk getChunkIfLoaded(int x, int z) { return this.chunkSource.getChunk(x, z, false); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 5a551e24be8d4d8157adb0f20f8e7bd3c5c61854..8bb10bcc26577ff7b806fbcc48c3d71b241c5963 100644 +index d361e39ba50958e7bdaea0b95c37d13f48a89771..ce9369e730ba8862cd1e6e26f8825c35b16fcfb9 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3628,6 +3628,20 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3626,6 +3626,20 @@ public abstract class LivingEntity extends Entity implements Attackable { this.pushEntities(); gameprofilerfiller.pop(); diff --git a/patches/server/0481-added-option-to-disable-pathfinding-updates-on-block.patch b/patches/server/0481-added-option-to-disable-pathfinding-updates-on-block.patch index c2bfd19f1422..d10ca06cedc3 100644 --- a/patches/server/0481-added-option-to-disable-pathfinding-updates-on-block.patch +++ b/patches/server/0481-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 12f46c94710830f464ff27a3d415140c36065e10..8352e42a3dceb33477c5885433d24840e1332b87 100644 +index 1c3f41d7ed7320342fe68c5ab6eb57dbdfd4bf69..cefd68cd2f28e5c14dba99b31d9a88125f169337 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1387,6 +1387,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1357,6 +1357,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.getChunkSource().blockChanged(pos); this.pathTypesByPosCache.invalidate(pos); @@ -16,7 +16,7 @@ index 12f46c94710830f464ff27a3d415140c36065e10..8352e42a3dceb33477c5885433d24840 VoxelShape voxelshape = oldState.getCollisionShape(this, pos); VoxelShape voxelshape1 = newState.getCollisionShape(this, pos); -@@ -1428,6 +1429,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1398,6 +1399,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } } diff --git a/patches/server/0484-Add-getMainThreadExecutor-to-BukkitScheduler.patch b/patches/server/0484-Add-getMainThreadExecutor-to-BukkitScheduler.patch index e2b8629ca85e..ead28f59cbb5 100644 --- a/patches/server/0484-Add-getMainThreadExecutor-to-BukkitScheduler.patch +++ b/patches/server/0484-Add-getMainThreadExecutor-to-BukkitScheduler.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add getMainThreadExecutor to BukkitScheduler diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -index fdfdcac6644e5343fb1f1cbe5d9aa76a79627046..5fc88196b2c873427c817e9802ad3b12009f265f 100644 +index a700dac93499650fdaa0af06ff77607ffa4dbbb2..6fef86e47e37eab6721cfd67d494afb25a2ded68 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -@@ -642,4 +642,15 @@ public class CraftScheduler implements BukkitScheduler { +@@ -637,4 +637,15 @@ public class CraftScheduler implements BukkitScheduler { public BukkitTask runTaskTimerAsynchronously(Plugin plugin, BukkitRunnable task, long delay, long period) throws IllegalArgumentException { throw new UnsupportedOperationException("Use BukkitRunnable#runTaskTimerAsynchronously(Plugin, long, long)"); } diff --git a/patches/server/0490-fix-converting-txt-to-json-file.patch b/patches/server/0490-fix-converting-txt-to-json-file.patch index 19ad56834740..130584b001e8 100644 --- a/patches/server/0490-fix-converting-txt-to-json-file.patch +++ b/patches/server/0490-fix-converting-txt-to-json-file.patch @@ -21,10 +21,10 @@ index 929f59bce01c8e6ed4b0b551744d42e131b8fc80..22c4f8dea99f92a1eb3da2baf0a15bf9 this.saveUserBanList(); this.loadIpBanList(); diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 20a3138c6c2a6c8ada8b6008913abae0eea76f2d..e95d592b6001dd4320c58133d841359f99c2d9c4 100644 +index 9a3e73a5c206b78dfcf6f41a47b614342e52acc8..9d05e998d6df1069c2de69478a1f9688ac435e67 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -215,6 +215,12 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -213,6 +213,12 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface this.paperConfigurations.initializeGlobalConfiguration(this.registryAccess()); this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess()); // Paper end - initialize global and world-defaults configuration @@ -37,7 +37,7 @@ index 20a3138c6c2a6c8ada8b6008913abae0eea76f2d..e95d592b6001dd4320c58133d841359f org.spigotmc.WatchdogThread.doStart(org.spigotmc.SpigotConfig.timeoutTime, org.spigotmc.SpigotConfig.restartOnCrash); // Paper - start watchdog thread io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics -@@ -269,9 +275,6 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -267,9 +273,6 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface DedicatedServer.LOGGER.warn("To change this, set \"online-mode\" to \"true\" in the server.properties file."); } @@ -48,10 +48,10 @@ index 20a3138c6c2a6c8ada8b6008913abae0eea76f2d..e95d592b6001dd4320c58133d841359f 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 7676dbe55b4bf6e0472dc0190c01e6ecfcbb464e..26e0414645f7ab11ca3e77c7c5e458612625aee9 100644 +index 240a0e487ede08d1dd5050812ca4f68db4cd2dd1..82f5451add3652d9f1afba4f809f30ceaa1b2951 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -180,6 +180,7 @@ public abstract class PlayerList { +@@ -179,6 +179,7 @@ public abstract class PlayerList { this.maxPlayers = maxPlayers; this.playerIo = saveHandler; } diff --git a/patches/server/0495-Allow-using-signs-inside-spawn-protection.patch b/patches/server/0495-Allow-using-signs-inside-spawn-protection.patch index 09955d8b696c..cbb5462bf66d 100644 --- a/patches/server/0495-Allow-using-signs-inside-spawn-protection.patch +++ b/patches/server/0495-Allow-using-signs-inside-spawn-protection.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Allow using signs inside spawn protection diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 0254ca5ed57de292ecd17900bb4f3d2874e12556..d93dfaf50c48b1975d59f9aa24b895f151d2e1b1 100644 +index 03e87e35f4478d948602569c319a7b5a0e938cd5..03ab4e27e141716e1c9ae92d41f42cfb7a48db66 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1770,7 +1770,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0496-Expand-world-key-API.patch b/patches/server/0496-Expand-world-key-API.patch index da317765ced6..80f4011a34f9 100644 --- a/patches/server/0496-Expand-world-key-API.patch +++ b/patches/server/0496-Expand-world-key-API.patch @@ -20,10 +20,10 @@ index 15da29058f80a2d7cf2be26c48421c1746815a10..a070b2a83edaa702b13bc6d302691412 // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index ee231d93d216571a45b11b49663b2ea91c47a1c7..dc20a383950a72aba5d056912d257912d3c0e808 100644 +index a12dc990a9094e964be2af26a5135e3b798f9666..85b2298efface87ee97e0f996d939cc135ca981d 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1186,9 +1186,15 @@ public final class CraftServer implements Server { +@@ -1185,9 +1185,15 @@ public final class CraftServer implements Server { File folder = new File(this.getWorldContainer(), name); World world = this.getWorld(name); @@ -41,7 +41,7 @@ index ee231d93d216571a45b11b49663b2ea91c47a1c7..dc20a383950a72aba5d056912d257912 if (folder.exists()) { Preconditions.checkArgument(folder.isDirectory(), "File (%s) exists and isn't a folder", name); -@@ -1314,7 +1320,7 @@ public final class CraftServer implements Server { +@@ -1313,7 +1319,7 @@ public final class CraftServer implements Server { } else if (name.equals(levelName + "_the_end")) { worldKey = net.minecraft.world.level.Level.END; } else { @@ -50,7 +50,7 @@ index ee231d93d216571a45b11b49663b2ea91c47a1c7..dc20a383950a72aba5d056912d257912 } // If set to not keep spawn in memory (changed from default) then adjust rule accordingly -@@ -1410,6 +1416,15 @@ public final class CraftServer implements Server { +@@ -1409,6 +1415,15 @@ public final class CraftServer implements Server { return null; } @@ -67,10 +67,10 @@ index ee231d93d216571a45b11b49663b2ea91c47a1c7..dc20a383950a72aba5d056912d257912 // Check if a World already exists with the UID. if (this.getWorld(world.getUID()) != null) { diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 6e8351363af9aea752286311074d53f245196e8d..e53610ac0ef0c80932e6e50f0c3971938b4bcf9b 100644 +index af8fde74b3162d2de740ecae1122b4f2115baeb6..77f0d6c44c3773968b1e858d02cfc4ffb25fe99b 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -522,6 +522,11 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -527,6 +527,11 @@ public final class CraftMagicNumbers implements UnsafeValues { public int nextEntityId() { return net.minecraft.world.entity.Entity.nextEntityId(); } @@ -81,4 +81,4 @@ index 6e8351363af9aea752286311074d53f245196e8d..e53610ac0ef0c80932e6e50f0c397193 + } // Paper end - @Override + /** diff --git a/patches/server/0498-Drop-carried-item-when-player-has-disconnected.patch b/patches/server/0498-Drop-carried-item-when-player-has-disconnected.patch index a13f458eea40..bebcb8d12170 100644 --- a/patches/server/0498-Drop-carried-item-when-player-has-disconnected.patch +++ b/patches/server/0498-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 26e0414645f7ab11ca3e77c7c5e458612625aee9..6f7807cc0da427485037b3a72a9c60c81a858294 100644 +index 82f5451add3652d9f1afba4f809f30ceaa1b2951..7a18061834096a73b140bee37b55b3c1724b51ef 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -538,6 +538,14 @@ public abstract class PlayerList { +@@ -537,6 +537,14 @@ public abstract class PlayerList { } // Paper end - Configurable player collision diff --git a/patches/server/0499-forced-whitelist-use-configurable-kick-message.patch b/patches/server/0499-forced-whitelist-use-configurable-kick-message.patch index 6dcbff2ff81d..e3d3ef89a743 100644 --- a/patches/server/0499-forced-whitelist-use-configurable-kick-message.patch +++ b/patches/server/0499-forced-whitelist-use-configurable-kick-message.patch @@ -5,10 +5,10 @@ Subject: [PATCH] forced whitelist: use configurable kick message diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index a6435cc675bca502994a31d2f2d91257c8c1fa2f..1cf78a61a5737aafd4e9384dc76af1a9fbc98621 100644 +index a200aacb1eaa749baa36be8be63b3f1421913b60..67a9bc450f545dd7b05398968a278a14f1e518fe 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2369,7 +2369,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop getDefaultAttributeModifiers(Material material, EquipmentSlot slot) { diff --git a/patches/server/0536-Add-cause-to-Weather-ThunderChangeEvents.patch b/patches/server/0536-Add-cause-to-Weather-ThunderChangeEvents.patch index 9e50f7f9b71e..ef0b70b8d806 100644 --- a/patches/server/0536-Add-cause-to-Weather-ThunderChangeEvents.patch +++ b/patches/server/0536-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 8352e42a3dceb33477c5885433d24840e1332b87..1be314ed35d07e6db9a3f6a4f493b0f4bb59a45f 100644 +index cefd68cd2f28e5c14dba99b31d9a88125f169337..f58069f0c9d836cb33f3ea09c562708951a91797 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -431,8 +431,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -429,8 +429,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.serverLevelData.setClearWeatherTime(clearDuration); this.serverLevelData.setRainTime(rainDuration); this.serverLevelData.setThunderTime(rainDuration); @@ -19,7 +19,7 @@ index 8352e42a3dceb33477c5885433d24840e1332b87..1be314ed35d07e6db9a3f6a4f493b0f4 } @Override -@@ -862,8 +862,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -846,8 +846,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.serverLevelData.setThunderTime(j); this.serverLevelData.setRainTime(k); this.serverLevelData.setClearWeatherTime(i); @@ -30,7 +30,7 @@ index 8352e42a3dceb33477c5885433d24840e1332b87..1be314ed35d07e6db9a3f6a4f493b0f4 } this.oThunderLevel = this.thunderLevel; -@@ -930,14 +930,14 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -914,14 +914,14 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @VisibleForTesting public void resetWeatherCycle() { // CraftBukkit start diff --git a/patches/server/0539-Add-PlayerKickEvent-causes.patch b/patches/server/0539-Add-PlayerKickEvent-causes.patch index 1ba9b46938be..7c4ea36fb36b 100644 --- a/patches/server/0539-Add-PlayerKickEvent-causes.patch +++ b/patches/server/0539-Add-PlayerKickEvent-causes.patch @@ -43,10 +43,10 @@ index dbcf183483766f39334d7f7e8336033906625f3f..300929a406905f5ff1ede664d5b99fb0 } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 1cf78a61a5737aafd4e9384dc76af1a9fbc98621..f191209b9a1d581235a638bd89ee2eb4050d5cb0 100644 +index 67a9bc450f545dd7b05398968a278a14f1e518fe..7ab9a9c04f94a68dccb5ec9bfc8171bfc02927a2 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2369,7 +2369,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 4096) { @@ -384,7 +384,7 @@ index 674149f3a392a600a506e55f20db044619328cd2..0fb16f3193c88c5f58d16aaf85129bbf } } -@@ -2599,7 +2599,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2596,7 +2596,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Spigot Start if ( entity == this.player && !this.player.isSpectator() ) { @@ -393,7 +393,7 @@ index 674149f3a392a600a506e55f20db044619328cd2..0fb16f3193c88c5f58d16aaf85129bbf return; } // Spigot End -@@ -2715,7 +2715,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2712,7 +2712,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } @@ -402,7 +402,7 @@ index 674149f3a392a600a506e55f20db044619328cd2..0fb16f3193c88c5f58d16aaf85129bbf ServerGamePacketListenerImpl.LOGGER.warn("Player {} tried to attack an invalid entity", ServerGamePacketListenerImpl.this.player.getName().getString()); } }); -@@ -3114,7 +3114,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3111,7 +3111,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Paper start - auto recipe limit if (!org.bukkit.Bukkit.isPrimaryThread()) { if (!this.recipeSpamPackets.isIncrementAndUnderThreshold()) { @@ -411,7 +411,7 @@ index 674149f3a392a600a506e55f20db044619328cd2..0fb16f3193c88c5f58d16aaf85129bbf return; } } -@@ -3385,7 +3385,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3382,7 +3382,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (!Objects.equals(profilepublickey_a, profilepublickey_a1)) { if (profilepublickey_a != null && profilepublickey_a1.expiresAt().isBefore(profilepublickey_a.expiresAt())) { @@ -420,7 +420,7 @@ index 674149f3a392a600a506e55f20db044619328cd2..0fb16f3193c88c5f58d16aaf85129bbf } else { try { SignatureValidator signaturevalidator = this.server.getProfileKeySignatureValidator(); -@@ -3398,7 +3398,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3395,7 +3395,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.resetPlayerChatState(remotechatsession_a.validate(this.player.getGameProfile(), signaturevalidator)); } catch (ProfilePublicKey.ValidationException profilepublickey_b) { ServerGamePacketListenerImpl.LOGGER.error("Failed to validate profile key: {}", profilepublickey_b.getMessage()); @@ -443,10 +443,10 @@ index 9d5723cdfdbf6257a71e57842aea9ba317fc049a..1e4b288f20153ce0c91fabf164c5c832 } // 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 6f7807cc0da427485037b3a72a9c60c81a858294..3ec8d38ca514048d94d24424d2132a90c10f529f 100644 +index 7a18061834096a73b140bee37b55b3c1724b51ef..e6b92f085291aaf4fa78d96f8379aeef2200592b 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -633,7 +633,7 @@ public abstract class PlayerList { +@@ -632,7 +632,7 @@ public abstract class PlayerList { while (iterator.hasNext()) { entityplayer = (ServerPlayer) iterator.next(); this.save(entityplayer); // CraftBukkit - Force the player's inventory to be saved @@ -455,7 +455,7 @@ index 6f7807cc0da427485037b3a72a9c60c81a858294..3ec8d38ca514048d94d24424d2132a90 } // Instead of kicking then returning, we need to store the kick reason -@@ -1238,7 +1238,7 @@ public abstract class PlayerList { +@@ -1236,7 +1236,7 @@ public abstract class PlayerList { // Paper end // CraftBukkit start - disconnect safely for (ServerPlayer player : this.players) { diff --git a/patches/server/0548-Line-Of-Sight-Changes.patch b/patches/server/0548-Line-Of-Sight-Changes.patch index d8a956a3092b..0b72d78709ee 100644 --- a/patches/server/0548-Line-Of-Sight-Changes.patch +++ b/patches/server/0548-Line-Of-Sight-Changes.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Line Of Sight Changes diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 9829419d3531ed6af55e37ac253903975c648a3e..1cb118c12e1b09cb6ae8d3b6949212b46c91b85b 100644 +index 9d56e7d4185401767359907337d5891ff0058abb..8939ce9fed5d935cec31c9a27833d1cec4de7b01 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3907,7 +3907,8 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3905,7 +3905,8 @@ public abstract class LivingEntity extends Entity implements Attackable { Vec3 vec3d = new Vec3(this.getX(), this.getEyeY(), this.getZ()); Vec3 vec3d1 = new Vec3(entity.getX(), entityY.getAsDouble(), entity.getZ()); diff --git a/patches/server/0555-Use-getChunkIfLoadedImmediately-in-places.patch b/patches/server/0555-Use-getChunkIfLoadedImmediately-in-places.patch index a5b4d06295df..99a97d953d9b 100644 --- a/patches/server/0555-Use-getChunkIfLoadedImmediately-in-places.patch +++ b/patches/server/0555-Use-getChunkIfLoadedImmediately-in-places.patch @@ -8,10 +8,10 @@ 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 1be314ed35d07e6db9a3f6a4f493b0f4bb59a45f..d8f7d7512db9432f67b07e7d64a6a9349dfab245 100644 +index f58069f0c9d836cb33f3ea09c562708951a91797..91fb83761885752743adb53cc9ed30ddc879263d 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -234,7 +234,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -232,7 +232,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent public LevelChunk getChunkIfLoaded(int x, int z) { @@ -21,10 +21,10 @@ index 1be314ed35d07e6db9a3f6a4f493b0f4bb59a45f..d8f7d7512db9432f67b07e7d64a6a934 @Override diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index aff89d2e3274b91238989fc1e7d8c119c2a3c097..560777a99b58c4f82cc0e8fb087de04a564163b5 100644 +index 71e9c1504d4b85ffb695401974748d56fefb66e6..9536e127ff4d45ca59b74fe0f3dbde9a18c04f42 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -180,6 +180,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -179,6 +179,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public CraftServer getCraftServer() { return (CraftServer) Bukkit.getServer(); } diff --git a/patches/server/0557-Add-PlayerArmSwingEvent.patch b/patches/server/0557-Add-PlayerArmSwingEvent.patch index c334885378ce..5b14fa047df2 100644 --- a/patches/server/0557-Add-PlayerArmSwingEvent.patch +++ b/patches/server/0557-Add-PlayerArmSwingEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerArmSwingEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 0fb16f3193c88c5f58d16aaf85129bbfd01fdfcd..7e11789a8d64b112c5eb354a30ae9618722526b1 100644 +index 36127f7c9ae50a628e88e7b456889a8f259b06da..e48c6f37ba0ebe698e28042e9331ab2ec0c39e7c 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2431,7 +2431,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2428,7 +2428,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // Paper end - Call interact event // Arm swing animation diff --git a/patches/server/0558-Fix-kick-event-leave-message-not-being-sent.patch b/patches/server/0558-Fix-kick-event-leave-message-not-being-sent.patch index 0068fffc6ea8..170b51853dbb 100644 --- a/patches/server/0558-Fix-kick-event-leave-message-not-being-sent.patch +++ b/patches/server/0558-Fix-kick-event-leave-message-not-being-sent.patch @@ -55,7 +55,7 @@ index 59d20fd62e850a38380d877cef95ed69cb46ecbd..fc242acade3ff06c9213428cde103cf0 MinecraftServer minecraftserver = this.server; Connection networkmanager = this.connection; diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 7e11789a8d64b112c5eb354a30ae9618722526b1..a550f23227770001862e5e837ab2f09e746d76f1 100644 +index e48c6f37ba0ebe698e28042e9331ab2ec0c39e7c..0229b3e6c27b142ff726de8e2e15104a6acbc1f0 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1915,6 +1915,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -101,10 +101,10 @@ index 7e11789a8d64b112c5eb354a30ae9618722526b1..a550f23227770001862e5e837ab2f09e 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 3ec8d38ca514048d94d24424d2132a90c10f529f..55e1e8ab83e8ca44735a0b1a7365526d0a3b24e7 100644 +index e6b92f085291aaf4fa78d96f8379aeef2200592b..adba2f7632df2e876c22ebe3a5232d93f6581282 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -511,6 +511,11 @@ public abstract class PlayerList { +@@ -510,6 +510,11 @@ public abstract class PlayerList { } public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer) { // CraftBukkit - return string // Paper - return Component diff --git a/patches/server/0560-Rate-options-and-timings-for-sensors-and-behaviors.patch b/patches/server/0560-Rate-options-and-timings-for-sensors-and-behaviors.patch index 3f0d6720edae..3473ea4ceb85 100644 --- a/patches/server/0560-Rate-options-and-timings-for-sensors-and-behaviors.patch +++ b/patches/server/0560-Rate-options-and-timings-for-sensors-and-behaviors.patch @@ -8,41 +8,21 @@ This adds config options to specify the tick rate for sensors for those in order to be able to have some metrics as to which ones might need tweaking. -diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java -index 4bd813161a5d76a83cdbd0a9209b9ea9e60ffe1b..e2764186bd6b838ed5cd86c15597a08d079ef984 100644 ---- a/src/main/java/co/aikar/timings/MinecraftTimings.java -+++ b/src/main/java/co/aikar/timings/MinecraftTimings.java -@@ -115,6 +115,14 @@ public final class MinecraftTimings { - return Timings.ofSafe("Minecraft", "## tickEntity - " + entityType + " - " + type, tickEntityTimer); - } - -+ public static Timing getBehaviorTimings(String type) { -+ return Timings.ofSafe("## Behavior - " + type); -+ } -+ -+ public static Timing getSensorTimings(String type, int rate) { -+ return Timings.ofSafe("## Sensor - " + type + " (Default rate: " + rate + ")"); -+ } -+ - /** - * Get a named timer for the specified tile entity type to track type specific timings. - * @param entity diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java b/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java -index f639cafa64d98a001e622882c647701547f5c3ac..9379dd4056018b52c93ed4888dcdc94579bd9691 100644 +index f639cafa64d98a001e622882c647701547f5c3ac..ba951cc1aaa94b58ee7985f197d41cc8be747fc8 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java -@@ -14,6 +14,10 @@ public abstract class Behavior implements BehaviorContro +@@ -14,6 +14,9 @@ public abstract class Behavior implements BehaviorContro private long endTimestamp; private final int minDuration; private final int maxDuration; + // Paper start - configurable behavior tick rate and timings + private final String configKey; -+ private final co.aikar.timings.Timing timing; + // Paper end - configurable behavior tick rate and timings public Behavior(Map, MemoryStatus> requiredMemoryState) { this(requiredMemoryState, 60); -@@ -27,6 +31,15 @@ public abstract class Behavior implements BehaviorContro +@@ -27,6 +30,14 @@ public abstract class Behavior implements BehaviorContro this.minDuration = minRunTime; this.maxDuration = maxRunTime; this.entryCondition = requiredMemoryState; @@ -53,12 +33,11 @@ index f639cafa64d98a001e622882c647701547f5c3ac..9379dd4056018b52c93ed4888dcdc945 + key = key.substring(lastSeparator + 1); + } + this.configKey = key.toLowerCase(java.util.Locale.ROOT); -+ this.timing = co.aikar.timings.MinecraftTimings.getBehaviorTimings(configKey); + // Paper end - configurable behavior tick rate and timings } @Override -@@ -36,11 +49,19 @@ public abstract class Behavior implements BehaviorContro +@@ -36,6 +47,12 @@ public abstract class Behavior implements BehaviorContro @Override public final boolean tryStart(ServerLevel world, E entity, long time) { @@ -71,38 +50,16 @@ index f639cafa64d98a001e622882c647701547f5c3ac..9379dd4056018b52c93ed4888dcdc945 if (this.hasRequiredMemories(entity) && this.checkExtraStartConditions(world, entity)) { this.status = Behavior.Status.RUNNING; int i = this.minDuration + world.getRandom().nextInt(this.maxDuration + 1 - this.minDuration); - this.endTimestamp = time + (long)i; -+ this.timing.startTiming(); // Paper - behavior timings - this.start(world, entity, time); -+ this.timing.stopTiming(); // Paper - behavior timings - return true; - } else { - return false; -@@ -52,11 +73,13 @@ public abstract class Behavior implements BehaviorContro - - @Override - public final void tickOrStop(ServerLevel world, E entity, long time) { -+ this.timing.startTiming(); // Paper - behavior timings - if (!this.timedOut(time) && this.canStillUse(world, entity, time)) { - this.tick(world, entity, time); - } else { - this.doStop(world, entity, time); - } -+ this.timing.stopTiming(); // Paper - behavior timings - } - - protected void tick(ServerLevel world, E entity, long time) { diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java -index 4d451f6cb5862411848bb9b6b5692ab512dcaa25..8bc7979fb9c2a796921a2a279b78294809f2ed03 100644 +index 4d451f6cb5862411848bb9b6b5692ab512dcaa25..fb1f5375eafb030ae08c735a80e9c8149726cda4 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java -@@ -29,8 +29,21 @@ public abstract class Sensor { +@@ -29,8 +29,19 @@ public abstract class Sensor { .ignoreInvisibilityTesting(); private final int scanRate; private long timeToTick; + // Paper start - configurable sensor tick rate and timings + private final String configKey; -+ private final co.aikar.timings.Timing timing; + // Paper end public Sensor(int senseInterval) { @@ -113,23 +70,19 @@ index 4d451f6cb5862411848bb9b6b5692ab512dcaa25..8bc7979fb9c2a796921a2a279b782948 + key = key.substring(lastSeparator + 1); + } + this.configKey = key.toLowerCase(java.util.Locale.ROOT); -+ this.timing = co.aikar.timings.MinecraftTimings.getSensorTimings(configKey, senseInterval); + // Paper end this.scanRate = senseInterval; this.timeToTick = (long)RANDOM.nextInt(senseInterval); } -@@ -41,9 +54,13 @@ public abstract class Sensor { +@@ -41,8 +52,10 @@ public abstract class Sensor { public final void tick(ServerLevel world, E entity) { if (--this.timeToTick <= 0L) { - this.timeToTick = (long)this.scanRate; + // Paper start - configurable sensor tick rate and timings + this.timeToTick = java.util.Objects.requireNonNullElse(world.paperConfig().tickRates.sensor.get(entity.getType(), this.configKey), this.scanRate); -+ this.timing.startTiming(); this.updateTargetingConditionRanges(entity); + // Paper end this.doTick(world, entity); -+ this.timing.stopTiming(); // Paper - sensor timings } } - diff --git a/patches/server/0563-Add-System.out-err-catcher.patch b/patches/server/0563-Add-System.out-err-catcher.patch index c975b94d8f26..1904f817de28 100644 --- a/patches/server/0563-Add-System.out-err-catcher.patch +++ b/patches/server/0563-Add-System.out-err-catcher.patch @@ -105,7 +105,7 @@ index 0000000000000000000000000000000000000000..a8e813ca89b033f061e695288b3383bd + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index d921b15100b83cb7073d79f2a1b2bfbdc7b745ca..35e5a3dc58f93b85f93ec5301cc9b5c7505503bc 100644 +index a17b26dadbbbf6e6c84f80f6fe8293d87ca19d0a..ecf7ee1ca39d58f1780580bd24366fc8037df34a 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -310,6 +310,7 @@ public final class CraftServer implements Server { diff --git a/patches/server/0564-Prevent-AFK-kick-while-watching-end-credits.patch b/patches/server/0564-Prevent-AFK-kick-while-watching-end-credits.patch index 3413c09bdaa6..dc3eed68eb14 100644 --- a/patches/server/0564-Prevent-AFK-kick-while-watching-end-credits.patch +++ b/patches/server/0564-Prevent-AFK-kick-while-watching-end-credits.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Prevent AFK kick while watching end credits diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index a550f23227770001862e5e837ab2f09e746d76f1..ea793f9ccf3082a7abcb003b9df03901f9b4c0f0 100644 +index 0229b3e6c27b142ff726de8e2e15104a6acbc1f0..70b891bd018029eda8cda4fb9f919e77524dbc5e 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -396,7 +396,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0566-Add-PlayerSetSpawnEvent.patch b/patches/server/0566-Add-PlayerSetSpawnEvent.patch index 6c4f8f48bc94..d290efd76669 100644 --- a/patches/server/0566-Add-PlayerSetSpawnEvent.patch +++ b/patches/server/0566-Add-PlayerSetSpawnEvent.patch @@ -154,10 +154,10 @@ index 94cc69ed1ccbcfcc8f431762fef641c313b2f634..c680b311760601bb539d685bceddba67 public SectionPos getLastSectionPos() { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 55e1e8ab83e8ca44735a0b1a7365526d0a3b24e7..1b6540ae28d73501c59581b1864f0e01ab53e365 100644 +index adba2f7632df2e876c22ebe3a5232d93f6581282..dd7b19a7762b91a8b27717098cebd2c48cb96f68 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -803,7 +803,7 @@ public abstract class PlayerList { +@@ -802,7 +802,7 @@ public abstract class PlayerList { // CraftBukkit end if (teleporttransition.missingRespawnBlock()) { entityplayer1.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0F)); diff --git a/patches/server/0574-Add-BlockBreakBlockEvent.patch b/patches/server/0574-Add-BlockBreakBlockEvent.patch index 4a3af0251e1a..fbd3627b5cc5 100644 --- a/patches/server/0574-Add-BlockBreakBlockEvent.patch +++ b/patches/server/0574-Add-BlockBreakBlockEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add BlockBreakBlockEvent diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index 43c2b411115d3a8a0e47d3e2277789b2667897af..4d140bd83ca0e1554afad80ec4fc6186188a79d8 100644 +index f1711f774f844024ca7b678385daaace6cda9f46..9d8c4ecd89b05a0e5d4ebb5e686eba5d899765f2 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -304,6 +304,24 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -295,6 +295,24 @@ public class Block extends BlockBehaviour implements ItemLike { } diff --git a/patches/server/0579-Add-methods-to-find-targets-for-lightning-strikes.patch b/patches/server/0579-Add-methods-to-find-targets-for-lightning-strikes.patch index 6727d31ea681..0a2ba7ccde68 100644 --- a/patches/server/0579-Add-methods-to-find-targets-for-lightning-strikes.patch +++ b/patches/server/0579-Add-methods-to-find-targets-for-lightning-strikes.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Add methods to find targets for lightning strikes public net.minecraft.server.level.ServerLevel findLightningRod(Lnet/minecraft/core/BlockPos;)Ljava/util/Optional; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index d8f7d7512db9432f67b07e7d64a6a9349dfab245..3137738307bb7b43190fa65da26e0b038012a9f4 100644 +index 91fb83761885752743adb53cc9ed30ddc879263d..3c281cdd24acbc9484c968c07f737d50be2deced 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -751,6 +751,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -735,6 +735,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } protected BlockPos findLightningTargetAround(BlockPos pos) { @@ -22,7 +22,7 @@ index d8f7d7512db9432f67b07e7d64a6a9349dfab245..3137738307bb7b43190fa65da26e0b03 BlockPos blockposition1 = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, pos); Optional optional = this.findLightningRod(blockposition1); -@@ -765,6 +770,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -749,6 +754,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (!list.isEmpty()) { return ((LivingEntity) list.get(this.random.nextInt(list.size()))).blockPosition(); } else { diff --git a/patches/server/0580-Get-entity-default-attributes.patch b/patches/server/0580-Get-entity-default-attributes.patch index ef862f64a60e..6d512ca6376f 100644 --- a/patches/server/0580-Get-entity-default-attributes.patch +++ b/patches/server/0580-Get-entity-default-attributes.patch @@ -81,10 +81,10 @@ index 0000000000000000000000000000000000000000..ec9ebd2d539333293c51b7edfa18f18b + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 7e33f55e4a269fd8e96080776c97f49d65e895c4..c9e0a2a4c7c8ab50f6dbb6079f2cba06652a92a3 100644 +index ffc98d8ed238cc653a7a6518a46c4e45a1b3682c..31b625779dfe27602ac198259258e64195c1796d 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -544,6 +544,18 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -549,6 +549,18 @@ public final class CraftMagicNumbers implements UnsafeValues { } return CraftItemStack.unwrap(itemToBeRepaired).isValidRepairItem(CraftItemStack.unwrap(repairMaterial)); } @@ -102,7 +102,7 @@ index 7e33f55e4a269fd8e96080776c97f49d65e895c4..c9e0a2a4c7c8ab50f6dbb6079f2cba06 + } // Paper end - @Override + /** diff --git a/src/test/java/io/papermc/paper/attribute/EntityTypeAttributesTest.java b/src/test/java/io/papermc/paper/attribute/EntityTypeAttributesTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f512d416df883036965ff6c802fd242a4c9c8079 diff --git a/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch b/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch index 5a6f0f60003a..0b866c52fb33 100644 --- a/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch +++ b/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch @@ -50,10 +50,10 @@ index 0c1c9033646dedcf1d11dee74d6965683adadf0a..1ed01978611cddb2558e441863dadc46 @Override public boolean isInvisible() { // Paper - moved up from LivingEntity diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index c9e0a2a4c7c8ab50f6dbb6079f2cba06652a92a3..8d51786837448db1a96d0071293025d07e14c225 100644 +index 31b625779dfe27602ac198259258e64195c1796d..1ab160c3d042be43df3bd19d095534b91c4c2f71 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -494,7 +494,33 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -499,7 +499,33 @@ public final class CraftMagicNumbers implements UnsafeValues { return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(MinecraftServer.getServer().registryAccess(), compound).orElseThrow()); } diff --git a/patches/server/0591-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch b/patches/server/0591-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch index 8404f01faa07..27c3f61502fd 100644 --- a/patches/server/0591-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch +++ b/patches/server/0591-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 3137738307bb7b43190fa65da26e0b038012a9f4..0485312d40dca972d2477b8d4a4725ff25deacbc 100644 +index 3c281cdd24acbc9484c968c07f737d50be2deced..ecb4dc0642685d67621c82bb24fb0e939c805ce4 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1269,9 +1269,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1239,9 +1239,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // 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/0593-Improve-and-expand-AsyncCatcher.patch b/patches/server/0593-Improve-and-expand-AsyncCatcher.patch index 921cb5a829ab..0e27a17c00e7 100644 --- a/patches/server/0593-Improve-and-expand-AsyncCatcher.patch +++ b/patches/server/0593-Improve-and-expand-AsyncCatcher.patch @@ -17,7 +17,7 @@ Async catch modifications to critical entity state Co-authored-by: Jake Potrebic diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index ea793f9ccf3082a7abcb003b9df03901f9b4c0f0..8084bf547a52f3e5c890d2be3757acb364370d34 100644 +index 70b891bd018029eda8cda4fb9f919e77524dbc5e..a4abcbc69ccd023a936d02d359ba4c08198ed31e 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1597,6 +1597,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -29,10 +29,10 @@ index ea793f9ccf3082a7abcb003b9df03901f9b4c0f0..8084bf547a52f3e5c890d2be3757acb3 if (player.isRemoved()) { LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName()); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 1cb118c12e1b09cb6ae8d3b6949212b46c91b85b..21f9fc5c3111dc126d0197a02bb61541fc422933 100644 +index 8939ce9fed5d935cec31c9a27833d1cec4de7b01..564024738cc346abc024967c2d55f2553af3e660 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1145,7 +1145,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1143,7 +1143,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } public boolean addEffect(MobEffectInstance mobeffect, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause) { diff --git a/patches/server/0594-Add-paper-mobcaps-and-paper-playermobcaps.patch b/patches/server/0594-Add-paper-mobcaps-and-paper-playermobcaps.patch index b998ef75b4d5..2eb0c233895c 100644 --- a/patches/server/0594-Add-paper-mobcaps-and-paper-playermobcaps.patch +++ b/patches/server/0594-Add-paper-mobcaps-and-paper-playermobcaps.patch @@ -257,10 +257,10 @@ index 0000000000000000000000000000000000000000..d3b39d88a72ca25057fd8574d32f28db + } +} diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 485c6044d603f15878f9413a644a538dab68db3e..6eb69ebe688c1c52d5a5986dfc63cdd42e66687e 100644 +index 606a60fe273974b71ed2bd40be819d848627e777..bf943feca387b77a3154773a59da7190d38d8621 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -174,6 +174,16 @@ public final class NaturalSpawner { +@@ -172,6 +172,16 @@ public final class NaturalSpawner { gameprofilerfiller.pop(); } @@ -278,10 +278,10 @@ index 485c6044d603f15878f9413a644a538dab68db3e..6eb69ebe688c1c52d5a5986dfc63cdd4 BlockPos blockposition = NaturalSpawner.getRandomPosWithin(world, chunk); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 35e5a3dc58f93b85f93ec5301cc9b5c7505503bc..f69504676d2f48f3778f489ec1e08e2b3dec85cc 100644 +index ecf7ee1ca39d58f1780580bd24366fc8037df34a..1c72862b3167acc05f06b44cd9a0929ad8d2b9c8 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2335,6 +2335,11 @@ public final class CraftServer implements Server { +@@ -2334,6 +2334,11 @@ public final class CraftServer implements Server { @Override public int getSpawnLimit(SpawnCategory spawnCategory) { diff --git a/patches/server/0598-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch b/patches/server/0598-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch index e87128411d00..9efbcafadb65 100644 --- a/patches/server/0598-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch +++ b/patches/server/0598-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch @@ -10,10 +10,10 @@ chunks did get inlined, but the standard CPS.getChunkAt method was not inlined. diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 560777a99b58c4f82cc0e8fb087de04a564163b5..8269bf24f5e17f9e3936659aa0cbc9d4f95fb665 100644 +index 9536e127ff4d45ca59b74fe0f3dbde9a18c04f42..9afc0eaaca5ab7b6445d90ce53e31a6ae76f8848 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -352,7 +352,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -350,7 +350,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @Override public final LevelChunk getChunk(int chunkX, int chunkZ) { // Paper - final to help inline diff --git a/patches/server/0602-Oprimise-map-impl-for-tracked-players.patch b/patches/server/0601-Oprimise-map-impl-for-tracked-players.patch similarity index 87% rename from patches/server/0602-Oprimise-map-impl-for-tracked-players.patch rename to patches/server/0601-Oprimise-map-impl-for-tracked-players.patch index c0bbabf27c02..026136cdd5fe 100644 --- a/patches/server/0602-Oprimise-map-impl-for-tracked-players.patch +++ b/patches/server/0601-Oprimise-map-impl-for-tracked-players.patch @@ -7,10 +7,10 @@ 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 4d8dcc47b39d28ab715110e55110869fe3c9b456..75854574aa8d4aef35d84ba4c0fc7df9a67ae48c 100644 +index 352675e0b835d5f04576db6599e8840754a40340..b92a889d0b0c46c1fa247d770f303d7d37dfc36c 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1520,7 +1520,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1514,7 +1514,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider final Entity entity; private final int range; SectionPos lastSectionPos; diff --git a/patches/server/0601-Time-scoreboard-search.patch b/patches/server/0601-Time-scoreboard-search.patch deleted file mode 100644 index 8d1508475872..000000000000 --- a/patches/server/0601-Time-scoreboard-search.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Tue, 21 Apr 2020 01:53:22 -0700 -Subject: [PATCH] Time scoreboard search - -Plugins leaking scoreboards will make this very expensive, -let server owners debug it easily - -diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java -index e2764186bd6b838ed5cd86c15597a08d079ef984..6b3cde6d4d1e63bec01f502f2027ee9fddac08aa 100644 ---- a/src/main/java/co/aikar/timings/MinecraftTimings.java -+++ b/src/main/java/co/aikar/timings/MinecraftTimings.java -@@ -46,6 +46,7 @@ public final class MinecraftTimings { - - public static final Timing antiXrayUpdateTimer = Timings.ofSafe("anti-xray - update"); - public static final Timing antiXrayObfuscateTimer = Timings.ofSafe("anti-xray - obfuscate"); -+ public static final Timing scoreboardScoreSearch = Timings.ofSafe("Scoreboard score search"); // Paper - add timings for scoreboard search - - private static final Map, String> taskNameCache = new MapMaker().weakKeys().makeMap(); - -diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java -index c7ca6210d6ae37fe95068c9baa5fb654f95307e0..cad42a0f3c016bf65181e50d139ae4e2fb9158a5 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 { - - // CraftBukkit method - public void forAllObjectives(ObjectiveCriteria criteria, ScoreHolder holder, Consumer consumer) { -+ // Paper start - add timings for scoreboard search -+ // plugins leaking scoreboards will make this very expensive, let server owners debug it easily -+ co.aikar.timings.MinecraftTimings.scoreboardScoreSearch.startTimingIfSync(); -+ try { -+ // Paper end - add timings for scoreboard search - for (CraftScoreboard scoreboard : this.scoreboards) { - Scoreboard board = scoreboard.board; - board.forAllObjectives(criteria, holder, (score) -> consumer.accept(score)); - } -+ } finally { // Paper start - add timings for scoreboard search -+ co.aikar.timings.MinecraftTimings.scoreboardScoreSearch.stopTimingIfSync(); -+ } -+ // Paper end - add timings for scoreboard search - } - } diff --git a/patches/server/0603-Add-missing-InventoryType.patch b/patches/server/0602-Add-missing-InventoryType.patch similarity index 100% rename from patches/server/0603-Add-missing-InventoryType.patch rename to patches/server/0602-Add-missing-InventoryType.patch diff --git a/patches/server/0604-Optimise-BlockSoil-nearby-water-lookup.patch b/patches/server/0603-Optimise-BlockSoil-nearby-water-lookup.patch similarity index 100% rename from patches/server/0604-Optimise-BlockSoil-nearby-water-lookup.patch rename to patches/server/0603-Optimise-BlockSoil-nearby-water-lookup.patch diff --git a/patches/server/0605-Fix-merchant-inventory-not-closing-on-entity-removal.patch b/patches/server/0604-Fix-merchant-inventory-not-closing-on-entity-removal.patch similarity index 90% rename from patches/server/0605-Fix-merchant-inventory-not-closing-on-entity-removal.patch rename to patches/server/0604-Fix-merchant-inventory-not-closing-on-entity-removal.patch index 4b017db5b613..87e006c31f6e 100644 --- a/patches/server/0605-Fix-merchant-inventory-not-closing-on-entity-removal.patch +++ b/patches/server/0604-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 0485312d40dca972d2477b8d4a4725ff25deacbc..3ca2c0d937dc840ac64fb1efd73dbc5b045bc77d 100644 +index ecb4dc0642685d67621c82bb24fb0e939c805ce4..3b3024fcf39266cc6ae61fb77dbffb391dc96c92 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2328,6 +2328,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2298,6 +2298,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // 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/0606-Check-requirement-before-suggesting-root-nodes.patch b/patches/server/0605-Check-requirement-before-suggesting-root-nodes.patch similarity index 100% rename from patches/server/0606-Check-requirement-before-suggesting-root-nodes.patch rename to patches/server/0605-Check-requirement-before-suggesting-root-nodes.patch diff --git a/patches/server/0607-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch b/patches/server/0606-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch similarity index 92% rename from patches/server/0607-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch rename to patches/server/0606-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch index 60d634041c8e..db870d424045 100644 --- a/patches/server/0607-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch +++ b/patches/server/0606-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Don't respond to ServerboundCommandSuggestionPacket when diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 8084bf547a52f3e5c890d2be3757acb364370d34..0790d904a408652c593dc8d87b1b2087169e7490 100644 +index a4abcbc69ccd023a936d02d359ba4c08198ed31e..7f1e0c6801a1d8b0857fba9826fc56e30bd41497 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -760,6 +760,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0608-Add-packet-limiter-config.patch b/patches/server/0607-Add-packet-limiter-config.patch similarity index 100% rename from patches/server/0608-Add-packet-limiter-config.patch rename to patches/server/0607-Add-packet-limiter-config.patch diff --git a/patches/server/0609-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch b/patches/server/0608-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch similarity index 100% rename from patches/server/0609-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch rename to patches/server/0608-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch diff --git a/patches/server/0610-Ensure-valid-vehicle-status.patch b/patches/server/0609-Ensure-valid-vehicle-status.patch similarity index 100% rename from patches/server/0610-Ensure-valid-vehicle-status.patch rename to patches/server/0609-Ensure-valid-vehicle-status.patch diff --git a/patches/server/0611-Prevent-softlocked-end-exit-portal-generation.patch b/patches/server/0610-Prevent-softlocked-end-exit-portal-generation.patch similarity index 100% rename from patches/server/0611-Prevent-softlocked-end-exit-portal-generation.patch rename to patches/server/0610-Prevent-softlocked-end-exit-portal-generation.patch diff --git a/patches/server/0612-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch b/patches/server/0611-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch similarity index 100% rename from patches/server/0612-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch rename to patches/server/0611-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch diff --git a/patches/server/0613-Don-t-log-debug-logging-being-disabled.patch b/patches/server/0612-Don-t-log-debug-logging-being-disabled.patch similarity index 100% rename from patches/server/0613-Don-t-log-debug-logging-being-disabled.patch rename to patches/server/0612-Don-t-log-debug-logging-being-disabled.patch diff --git a/patches/server/0614-fix-various-menus-with-empty-level-accesses.patch b/patches/server/0613-fix-various-menus-with-empty-level-accesses.patch similarity index 100% rename from patches/server/0614-fix-various-menus-with-empty-level-accesses.patch rename to patches/server/0613-fix-various-menus-with-empty-level-accesses.patch diff --git a/patches/server/0615-Preserve-overstacked-loot.patch b/patches/server/0614-Preserve-overstacked-loot.patch similarity index 100% rename from patches/server/0615-Preserve-overstacked-loot.patch rename to patches/server/0614-Preserve-overstacked-loot.patch diff --git a/patches/server/0616-Update-head-rotation-in-missing-places.patch b/patches/server/0615-Update-head-rotation-in-missing-places.patch similarity index 100% rename from patches/server/0616-Update-head-rotation-in-missing-places.patch rename to patches/server/0615-Update-head-rotation-in-missing-places.patch diff --git a/patches/server/0617-prevent-unintended-light-block-manipulation.patch b/patches/server/0616-prevent-unintended-light-block-manipulation.patch similarity index 100% rename from patches/server/0617-prevent-unintended-light-block-manipulation.patch rename to patches/server/0616-prevent-unintended-light-block-manipulation.patch diff --git a/patches/server/0618-Fix-CraftCriteria-defaults-map.patch b/patches/server/0617-Fix-CraftCriteria-defaults-map.patch similarity index 100% rename from patches/server/0618-Fix-CraftCriteria-defaults-map.patch rename to patches/server/0617-Fix-CraftCriteria-defaults-map.patch diff --git a/patches/server/0619-Fix-upstreams-block-state-factories.patch b/patches/server/0618-Fix-upstreams-block-state-factories.patch similarity index 99% rename from patches/server/0619-Fix-upstreams-block-state-factories.patch rename to patches/server/0618-Fix-upstreams-block-state-factories.patch index bca94bd673c9..93376fc4b13f 100644 --- a/patches/server/0619-Fix-upstreams-block-state-factories.patch +++ b/patches/server/0618-Fix-upstreams-block-state-factories.patch @@ -13,10 +13,10 @@ the material type of the block at that location. public net.minecraft.world.level.block.entity.BlockEntityType validBlocks diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index 46a831f86b512f4228be8ccee40fb0f7bf0d6df6..3de01d92e1c97e287a1f0d1f8de81b4f530b4a84 100644 +index 50413d317ce0282752c57535637f87d529f4c09f..09b85c4caa4ebaae1e8c2910b090c40a039a1be7 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -388,7 +388,7 @@ public abstract class BlockEntity { +@@ -383,7 +383,7 @@ public abstract class BlockEntity { // Paper end if (this.level == null) return null; org.bukkit.block.Block block = this.level.getWorld().getBlockAt(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ()); diff --git a/patches/server/0620-Configurable-feature-seeds.patch b/patches/server/0619-Configurable-feature-seeds.patch similarity index 62% rename from patches/server/0620-Configurable-feature-seeds.patch rename to patches/server/0619-Configurable-feature-seeds.patch index ffca9db1e262..b374cbddbfec 100644 --- a/patches/server/0620-Configurable-feature-seeds.patch +++ b/patches/server/0619-Configurable-feature-seeds.patch @@ -5,19 +5,6 @@ Subject: [PATCH] Configurable feature seeds Co-authored-by: Thonk <30448663+ExcessiveAmountsOfZombies@users.noreply.github.com> -diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java -index 49028463ba47e760281545c2f7597e3db8d6c453..7620c72a4c243cbeea245203ce03a97cbfa7d922 100644 ---- a/src/main/java/co/aikar/timings/TimingsExport.java -+++ b/src/main/java/co/aikar/timings/TimingsExport.java -@@ -286,7 +286,7 @@ public class TimingsExport extends Thread { - JSONObject object = new JSONObject(); - for (String key : config.getKeys(false)) { - String fullKey = (parentKey != null ? parentKey + "." + key : key); -- if (fullKey.equals("database") || fullKey.equals("settings.bungeecord-addresses") || TimingsManager.hiddenConfigs.contains(fullKey) || key.startsWith("seed-") || key.equals("worldeditregentempworld")) { -+ if (fullKey.equals("database") || fullKey.equals("settings.bungeecord-addresses") || TimingsManager.hiddenConfigs.contains(fullKey) || key.startsWith("seed-") || key.equals("worldeditregentempworld") || key.equals("feature-seeds")) { - continue; - } - final Object val = config.get(key); diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java index e3c5a49611d584fbd19a44da5aa78ff6d7c43881..fc8e3edd9734fa7b69f0fc6b4eefd8a704e451cf 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java diff --git a/patches/server/0621-Add-root-admin-user-detection.patch b/patches/server/0620-Add-root-admin-user-detection.patch similarity index 95% rename from patches/server/0621-Add-root-admin-user-detection.patch rename to patches/server/0620-Add-root-admin-user-detection.patch index af7475ee7fa1..df739cc33c9d 100644 --- a/patches/server/0621-Add-root-admin-user-detection.patch +++ b/patches/server/0620-Add-root-admin-user-detection.patch @@ -40,10 +40,10 @@ index 0000000000000000000000000000000000000000..68098dfe716e93aafcca4d8d5b5a81d8 + } +} diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index e30a5ad17d7ba8bcec8911a72281830c419b0288..3c3be48b29fcd38c5dea1bfca8d8690850aa948e 100644 +index 21d6f728d6ecd35a05933e9406a386c36135a456..ac7fc2497b860a143ef08498f5f477a373a29be7 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -195,6 +195,16 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -193,6 +193,16 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface DedicatedServer.LOGGER.warn("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\""); } diff --git a/patches/server/0622-don-t-attempt-to-teleport-dead-entities.patch b/patches/server/0621-don-t-attempt-to-teleport-dead-entities.patch similarity index 100% rename from patches/server/0622-don-t-attempt-to-teleport-dead-entities.patch rename to patches/server/0621-don-t-attempt-to-teleport-dead-entities.patch diff --git a/patches/server/0623-Prevent-excessive-velocity-through-repeated-crits.patch b/patches/server/0622-Prevent-excessive-velocity-through-repeated-crits.patch similarity index 92% rename from patches/server/0623-Prevent-excessive-velocity-through-repeated-crits.patch rename to patches/server/0622-Prevent-excessive-velocity-through-repeated-crits.patch index 9db70149e677..d7f8266ad656 100644 --- a/patches/server/0623-Prevent-excessive-velocity-through-repeated-crits.patch +++ b/patches/server/0622-Prevent-excessive-velocity-through-repeated-crits.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent excessive velocity through repeated crits diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 21f9fc5c3111dc126d0197a02bb61541fc422933..8c7ffa884f64a4263c9399953a7cfca6e35aab61 100644 +index 564024738cc346abc024967c2d55f2553af3e660..8e0805bf6d330717f7555fbdb28d416295f8495a 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2865,17 +2865,29 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2863,17 +2863,29 @@ public abstract class LivingEntity extends Entity implements Attackable { return this.hasEffect(MobEffects.JUMP) ? 0.1F * ((float) this.getEffect(MobEffects.JUMP).getAmplifier() + 1.0F) : 0.0F; } diff --git a/patches/server/0624-Remove-client-side-code-using-deprecated-for-removal.patch b/patches/server/0623-Remove-client-side-code-using-deprecated-for-removal.patch similarity index 100% rename from patches/server/0624-Remove-client-side-code-using-deprecated-for-removal.patch rename to patches/server/0623-Remove-client-side-code-using-deprecated-for-removal.patch diff --git a/patches/server/0625-Fix-Spigot-growth-modifiers.patch b/patches/server/0624-Fix-Spigot-growth-modifiers.patch similarity index 100% rename from patches/server/0625-Fix-Spigot-growth-modifiers.patch rename to patches/server/0624-Fix-Spigot-growth-modifiers.patch diff --git a/patches/server/0626-Prevent-ContainerOpenersCounter-openCount-from-going.patch b/patches/server/0625-Prevent-ContainerOpenersCounter-openCount-from-going.patch similarity index 100% rename from patches/server/0626-Prevent-ContainerOpenersCounter-openCount-from-going.patch rename to patches/server/0625-Prevent-ContainerOpenersCounter-openCount-from-going.patch diff --git a/patches/server/0627-Add-PlayerItemFrameChangeEvent.patch b/patches/server/0626-Add-PlayerItemFrameChangeEvent.patch similarity index 100% rename from patches/server/0627-Add-PlayerItemFrameChangeEvent.patch rename to patches/server/0626-Add-PlayerItemFrameChangeEvent.patch diff --git a/patches/server/0628-Optimize-HashMapPalette.patch b/patches/server/0627-Optimize-HashMapPalette.patch similarity index 100% rename from patches/server/0628-Optimize-HashMapPalette.patch rename to patches/server/0627-Optimize-HashMapPalette.patch diff --git a/patches/server/0629-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch b/patches/server/0628-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch similarity index 100% rename from patches/server/0629-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch rename to patches/server/0628-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch diff --git a/patches/server/0630-Add-more-Campfire-API.patch b/patches/server/0629-Add-more-Campfire-API.patch similarity index 100% rename from patches/server/0630-Add-more-Campfire-API.patch rename to patches/server/0629-Add-more-Campfire-API.patch diff --git a/patches/server/0631-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch b/patches/server/0630-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch similarity index 100% rename from patches/server/0631-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch rename to patches/server/0630-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch diff --git a/patches/server/0632-Forward-CraftEntity-in-teleport-command.patch b/patches/server/0631-Forward-CraftEntity-in-teleport-command.patch similarity index 100% rename from patches/server/0632-Forward-CraftEntity-in-teleport-command.patch rename to patches/server/0631-Forward-CraftEntity-in-teleport-command.patch diff --git a/patches/server/0633-Improve-scoreboard-entries.patch b/patches/server/0632-Improve-scoreboard-entries.patch similarity index 100% rename from patches/server/0633-Improve-scoreboard-entries.patch rename to patches/server/0632-Improve-scoreboard-entries.patch diff --git a/patches/server/0634-Entity-powdered-snow-API.patch b/patches/server/0633-Entity-powdered-snow-API.patch similarity index 100% rename from patches/server/0634-Entity-powdered-snow-API.patch rename to patches/server/0633-Entity-powdered-snow-API.patch diff --git a/patches/server/0635-Add-API-for-item-entity-health.patch b/patches/server/0634-Add-API-for-item-entity-health.patch similarity index 100% rename from patches/server/0635-Add-API-for-item-entity-health.patch rename to patches/server/0634-Add-API-for-item-entity-health.patch diff --git a/patches/server/0636-Configurable-max-block-light-for-monster-spawning.patch b/patches/server/0635-Configurable-max-block-light-for-monster-spawning.patch similarity index 100% rename from patches/server/0636-Configurable-max-block-light-for-monster-spawning.patch rename to patches/server/0635-Configurable-max-block-light-for-monster-spawning.patch diff --git a/patches/server/0637-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch b/patches/server/0636-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch similarity index 100% rename from patches/server/0637-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch rename to patches/server/0636-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch diff --git a/patches/server/0638-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch b/patches/server/0637-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch similarity index 100% rename from patches/server/0638-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch rename to patches/server/0637-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch diff --git a/patches/server/0639-Bucketable-API.patch b/patches/server/0638-Bucketable-API.patch similarity index 100% rename from patches/server/0639-Bucketable-API.patch rename to patches/server/0638-Bucketable-API.patch diff --git a/patches/server/0640-Validate-usernames.patch b/patches/server/0639-Validate-usernames.patch similarity index 96% rename from patches/server/0640-Validate-usernames.patch rename to patches/server/0639-Validate-usernames.patch index 74facbf23825..89dbf3385d26 100644 --- a/patches/server/0640-Validate-usernames.patch +++ b/patches/server/0639-Validate-usernames.patch @@ -32,10 +32,10 @@ index 1e4b288f20153ce0c91fabf164c5c8320c90ba7d..cb5dd77892283a1aaec45434fb99bb7f 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 1b6540ae28d73501c59581b1864f0e01ab53e365..f34cad30c982f2bb563f0deab030111720858fa8 100644 +index dd7b19a7762b91a8b27717098cebd2c48cb96f68..2497aeb46ff4188948e9253c21d83a218fd73e85 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -628,7 +628,7 @@ public abstract class PlayerList { +@@ -627,7 +627,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/0641-Make-water-animal-spawn-height-configurable.patch b/patches/server/0640-Make-water-animal-spawn-height-configurable.patch similarity index 100% rename from patches/server/0641-Make-water-animal-spawn-height-configurable.patch rename to patches/server/0640-Make-water-animal-spawn-height-configurable.patch diff --git a/patches/server/0642-Expose-vanilla-BiomeProvider-from-WorldInfo.patch b/patches/server/0641-Expose-vanilla-BiomeProvider-from-WorldInfo.patch similarity index 95% rename from patches/server/0642-Expose-vanilla-BiomeProvider-from-WorldInfo.patch rename to patches/server/0641-Expose-vanilla-BiomeProvider-from-WorldInfo.patch index ecf4c51174ef..b09fd4e69919 100644 --- a/patches/server/0642-Expose-vanilla-BiomeProvider-from-WorldInfo.patch +++ b/patches/server/0641-Expose-vanilla-BiomeProvider-from-WorldInfo.patch @@ -5,10 +5,10 @@ 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 f191209b9a1d581235a638bd89ee2eb4050d5cb0..ac9b2eb3fadc2aa6f740a53b13029aa65724a37a 100644 +index 7ab9a9c04f94a68dccb5ec9bfc8171bfc02927a2..8cbc8eeaa8719f8bb136543e80ec85248c90e154 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -627,7 +627,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(iworlddataserver)); LevelStem worlddimension = (LevelStem) dimensions.getValue(dimensionKey); @@ -18,10 +18,10 @@ index f191209b9a1d581235a638bd89ee2eb4050d5cb0..ac9b2eb3fadc2aa6f740a53b13029aa6 biomeProvider = gen.getDefaultBiomeProvider(worldInfo); } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 3ca2c0d937dc840ac64fb1efd73dbc5b045bc77d..9ac6d2e87bbad00c9b97028b0e9c2a42cf29801b 100644 +index 3b3024fcf39266cc6ae61fb77dbffb391dc96c92..2d77e9526917a83987ae0486a669538d5417b781 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -359,7 +359,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -357,7 +357,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.serverLevelData.setWorld(this); if (biomeProvider != null) { @@ -31,10 +31,10 @@ index 3ca2c0d937dc840ac64fb1efd73dbc5b045bc77d..9ac6d2e87bbad00c9b97028b0e9c2a42 chunkgenerator = new NoiseBasedChunkGenerator(worldChunkManager, cga.settings); } else if (chunkgenerator instanceof FlatLevelSource cpf) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index f69504676d2f48f3778f489ec1e08e2b3dec85cc..d30c1e853bb2e27922a00d890dffca153cdcbe97 100644 +index 1c72862b3167acc05f06b44cd9a0929ad8d2b9c8..6d32505266fef119289bcf6761c1948368238eb9 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1311,7 +1311,7 @@ public final class CraftServer implements Server { +@@ -1310,7 +1310,7 @@ public final class CraftServer implements Server { List list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(worlddata)); LevelStem worlddimension = iregistry.getValue(actualDimension); diff --git a/patches/server/0643-Add-config-option-for-worlds-affected-by-time-cmd.patch b/patches/server/0642-Add-config-option-for-worlds-affected-by-time-cmd.patch similarity index 100% rename from patches/server/0643-Add-config-option-for-worlds-affected-by-time-cmd.patch rename to patches/server/0642-Add-config-option-for-worlds-affected-by-time-cmd.patch diff --git a/patches/server/0644-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch b/patches/server/0643-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch similarity index 100% rename from patches/server/0644-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch rename to patches/server/0643-Add-missing-IAE-check-for-PersistentDataContainer-ha.patch diff --git a/patches/server/0645-Multiple-Entries-with-Scoreboards.patch b/patches/server/0644-Multiple-Entries-with-Scoreboards.patch similarity index 100% rename from patches/server/0645-Multiple-Entries-with-Scoreboards.patch rename to patches/server/0644-Multiple-Entries-with-Scoreboards.patch diff --git a/patches/server/0646-Reset-placed-block-on-exception.patch b/patches/server/0645-Reset-placed-block-on-exception.patch similarity index 100% rename from patches/server/0646-Reset-placed-block-on-exception.patch rename to patches/server/0645-Reset-placed-block-on-exception.patch diff --git a/patches/server/0647-Add-configurable-height-for-slime-spawn.patch b/patches/server/0646-Add-configurable-height-for-slime-spawn.patch similarity index 100% rename from patches/server/0647-Add-configurable-height-for-slime-spawn.patch rename to patches/server/0646-Add-configurable-height-for-slime-spawn.patch diff --git a/patches/server/0648-Fix-xp-reward-for-baby-zombies.patch b/patches/server/0647-Fix-xp-reward-for-baby-zombies.patch similarity index 100% rename from patches/server/0648-Fix-xp-reward-for-baby-zombies.patch rename to patches/server/0647-Fix-xp-reward-for-baby-zombies.patch diff --git a/patches/server/0649-Multi-Block-Change-API-Implementation.patch b/patches/server/0648-Multi-Block-Change-API-Implementation.patch similarity index 100% rename from patches/server/0649-Multi-Block-Change-API-Implementation.patch rename to patches/server/0648-Multi-Block-Change-API-Implementation.patch diff --git a/patches/server/0650-Fix-NotePlayEvent.patch b/patches/server/0649-Fix-NotePlayEvent.patch similarity index 100% rename from patches/server/0650-Fix-NotePlayEvent.patch rename to patches/server/0649-Fix-NotePlayEvent.patch diff --git a/patches/server/0651-Freeze-Tick-Lock-API.patch b/patches/server/0650-Freeze-Tick-Lock-API.patch similarity index 96% rename from patches/server/0651-Freeze-Tick-Lock-API.patch rename to patches/server/0650-Freeze-Tick-Lock-API.patch index 0244ffe42018..f658b3b299c7 100644 --- a/patches/server/0651-Freeze-Tick-Lock-API.patch +++ b/patches/server/0650-Freeze-Tick-Lock-API.patch @@ -46,10 +46,10 @@ index 3df8cfccba9bc4420b37dcbdfc4a12c720b51205..4f9ebf7a577223d85ceaad0babd2d0b4 } catch (Throwable throwable) { diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 8c7ffa884f64a4263c9399953a7cfca6e35aab61..0aa7291b3c28c58767fed5f9f01e381b671b5d27 100644 +index 8e0805bf6d330717f7555fbdb28d416295f8495a..8b454382f59ee36ec6f45ca8445b3f1a956ff668 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3611,7 +3611,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3609,7 +3609,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.calculateEntityAnimation(this instanceof FlyingAnimal); gameprofilerfiller.pop(); gameprofilerfiller.push("freezing"); diff --git a/patches/server/0652-More-PotionEffectType-API.patch b/patches/server/0651-More-PotionEffectType-API.patch similarity index 100% rename from patches/server/0652-More-PotionEffectType-API.patch rename to patches/server/0651-More-PotionEffectType-API.patch diff --git a/patches/server/0653-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch b/patches/server/0652-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch similarity index 100% rename from patches/server/0653-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch rename to patches/server/0652-Use-a-CHM-for-StructureTemplate.Pallete-cache.patch diff --git a/patches/server/0654-API-for-creating-command-sender-which-forwards-feedb.patch b/patches/server/0653-API-for-creating-command-sender-which-forwards-feedb.patch similarity index 97% rename from patches/server/0654-API-for-creating-command-sender-which-forwards-feedb.patch rename to patches/server/0653-API-for-creating-command-sender-which-forwards-feedb.patch index de6e7d281108..76a09348afdd 100644 --- a/patches/server/0654-API-for-creating-command-sender-which-forwards-feedb.patch +++ b/patches/server/0653-API-for-creating-command-sender-which-forwards-feedb.patch @@ -122,10 +122,10 @@ index 0000000000000000000000000000000000000000..e3a5f1ec376319bdfda87fa27ae217bf + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index d30c1e853bb2e27922a00d890dffca153cdcbe97..93811e7770546c202085487642699e0c74b9f498 100644 +index 6d32505266fef119289bcf6761c1948368238eb9..9de7978c7383f8364feba82e9cd3efbfcce00e3c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2166,6 +2166,13 @@ public final class CraftServer implements Server { +@@ -2165,6 +2165,13 @@ public final class CraftServer implements Server { return this.console.console; } diff --git a/patches/server/0655-Add-missing-structure-set-seed-configs.patch b/patches/server/0654-Add-missing-structure-set-seed-configs.patch similarity index 100% rename from patches/server/0655-Add-missing-structure-set-seed-configs.patch rename to patches/server/0654-Add-missing-structure-set-seed-configs.patch diff --git a/patches/server/0656-Fix-cancelled-powdered-snow-bucket-placement.patch b/patches/server/0655-Fix-cancelled-powdered-snow-bucket-placement.patch similarity index 100% rename from patches/server/0656-Fix-cancelled-powdered-snow-bucket-placement.patch rename to patches/server/0655-Fix-cancelled-powdered-snow-bucket-placement.patch diff --git a/patches/server/0657-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch b/patches/server/0656-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch similarity index 86% rename from patches/server/0657-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch rename to patches/server/0656-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch index f3ca4340b021..3f4362495aad 100644 --- a/patches/server/0657-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch +++ b/patches/server/0656-Add-missing-Validate-calls-to-CraftServer-getSpawnLi.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add missing Validate calls to CraftServer#getSpawnLimit Copies appropriate checks from CraftWorld#getSpawnLimit diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 93811e7770546c202085487642699e0c74b9f498..8d9816f84e551f1257972f467352e9c9ee09473e 100644 +index 9de7978c7383f8364feba82e9cd3efbfcce00e3c..c1bdefbad35fd259e3d90c6e330da14c9d072090 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2343,6 +2343,8 @@ public final class CraftServer implements Server { +@@ -2342,6 +2342,8 @@ public final class CraftServer implements Server { @Override public int getSpawnLimit(SpawnCategory spawnCategory) { // Paper start - Add mobcaps commands diff --git a/patches/server/0658-Add-GameEvent-tags.patch b/patches/server/0657-Add-GameEvent-tags.patch similarity index 95% rename from patches/server/0658-Add-GameEvent-tags.patch rename to patches/server/0657-Add-GameEvent-tags.patch index 34a9b8a43edd..0f1b9f52d218 100644 --- a/patches/server/0658-Add-GameEvent-tags.patch +++ b/patches/server/0657-Add-GameEvent-tags.patch @@ -46,10 +46,10 @@ index 0000000000000000000000000000000000000000..874c420e60b6be09c806d64f40cf6366 + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 8d9816f84e551f1257972f467352e9c9ee09473e..db6b4ec0cfbda7a65cebaa50d16f038916886475 100644 +index c1bdefbad35fd259e3d90c6e330da14c9d072090..59690263f1cb27f2289b027ffd31c1e1ac4f2e69 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2700,6 +2700,15 @@ public final class CraftServer implements Server { +@@ -2699,6 +2699,15 @@ public final class CraftServer implements Server { return (org.bukkit.Tag) new CraftDamageTag(damageRegistry, damageTagKey); } } @@ -65,7 +65,7 @@ index 8d9816f84e551f1257972f467352e9c9ee09473e..db6b4ec0cfbda7a65cebaa50d16f0389 default -> throw new IllegalArgumentException(); } -@@ -2737,6 +2746,13 @@ public final class CraftServer implements Server { +@@ -2736,6 +2745,13 @@ public final class CraftServer implements Server { net.minecraft.core.Registry damageTags = CraftRegistry.getMinecraftRegistry(Registries.DAMAGE_TYPE); return damageTags.getTags().map(pair -> (org.bukkit.Tag) new CraftDamageTag(damageTags, pair.key())).collect(ImmutableList.toImmutableList()); } diff --git a/patches/server/0659-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch b/patches/server/0658-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch similarity index 87% rename from patches/server/0659-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch rename to patches/server/0658-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch index 3b556cd312e5..7d399f3858f1 100644 --- a/patches/server/0659-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch +++ b/patches/server/0658-Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch @@ -9,10 +9,10 @@ This might result in chunks loading far slower in the nether, for example. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index ac9b2eb3fadc2aa6f740a53b13029aa65724a37a..ff75c95f13b18171064f521f7c3b4367d9a5b9b8 100644 +index 8cbc8eeaa8719f8bb136543e80ec85248c90e154..3cd23d329fae0a6a4eff36510edc5d9bd27c804e 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1419,6 +1419,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); -@@ -1659,7 +1660,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent -@@ -1725,6 +1728,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop(this.worlds.values()); } @@ -60,7 +60,7 @@ index d0a72476d36294792550425a8c0646a7c0be75a7..f2898c356182fee8a1f525ab762d9c12 public DedicatedPlayerList getHandle() { return this.playerList; } -@@ -1183,6 +1188,7 @@ public final class CraftServer implements Server { +@@ -1182,6 +1187,7 @@ public final class CraftServer implements Server { @Override public World createWorld(WorldCreator creator) { Preconditions.checkState(this.console.getAllLevels().iterator().hasNext(), "Cannot create additional worlds on STARTUP"); @@ -68,7 +68,7 @@ index d0a72476d36294792550425a8c0646a7c0be75a7..f2898c356182fee8a1f525ab762d9c12 Preconditions.checkArgument(creator != null, "WorldCreator cannot be null"); String name = creator.name(); -@@ -1359,6 +1365,7 @@ public final class CraftServer implements Server { +@@ -1358,6 +1364,7 @@ public final class CraftServer implements Server { @Override public boolean unloadWorld(World world, boolean save) { diff --git a/patches/server/0704-Dont-resent-entity-on-art-update.patch b/patches/server/0703-Dont-resent-entity-on-art-update.patch similarity index 100% rename from patches/server/0704-Dont-resent-entity-on-art-update.patch rename to patches/server/0703-Dont-resent-entity-on-art-update.patch diff --git a/patches/server/0705-Add-WardenAngerChangeEvent.patch b/patches/server/0704-Add-WardenAngerChangeEvent.patch similarity index 100% rename from patches/server/0705-Add-WardenAngerChangeEvent.patch rename to patches/server/0704-Add-WardenAngerChangeEvent.patch diff --git a/patches/server/0706-Add-option-for-strict-advancement-dimension-checks.patch b/patches/server/0705-Add-option-for-strict-advancement-dimension-checks.patch similarity index 100% rename from patches/server/0706-Add-option-for-strict-advancement-dimension-checks.patch rename to patches/server/0705-Add-option-for-strict-advancement-dimension-checks.patch diff --git a/patches/server/0707-Add-missing-important-BlockStateListPopulator-method.patch b/patches/server/0706-Add-missing-important-BlockStateListPopulator-method.patch similarity index 100% rename from patches/server/0707-Add-missing-important-BlockStateListPopulator-method.patch rename to patches/server/0706-Add-missing-important-BlockStateListPopulator-method.patch diff --git a/patches/server/0708-Nameable-Banner-API.patch b/patches/server/0707-Nameable-Banner-API.patch similarity index 100% rename from patches/server/0708-Nameable-Banner-API.patch rename to patches/server/0707-Nameable-Banner-API.patch diff --git a/patches/server/0709-Don-t-broadcast-messages-to-command-blocks.patch b/patches/server/0708-Don-t-broadcast-messages-to-command-blocks.patch similarity index 92% rename from patches/server/0709-Don-t-broadcast-messages-to-command-blocks.patch rename to patches/server/0708-Don-t-broadcast-messages-to-command-blocks.patch index dc3625422718..428c5de1aa25 100644 --- a/patches/server/0709-Don-t-broadcast-messages-to-command-blocks.patch +++ b/patches/server/0708-Don-t-broadcast-messages-to-command-blocks.patch @@ -20,10 +20,10 @@ index a0e59b236dff1f861a0e987764a77ee203504412..5cb39f95bd2d45b6c18554605f01d2eb Date date = new Date(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index f2898c356182fee8a1f525ab762d9c126d2108fc..0c037618005265ed6b9533ea60848753141d8e0b 100644 +index 2d16e96c7c329cde6369f1d5b739f60f1776bb4b..3deb58f3cd2e29b51944ac81cb3e0e52ec496242 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1929,7 +1929,7 @@ public final class CraftServer implements Server { +@@ -1928,7 +1928,7 @@ public final class CraftServer implements Server { // Paper end Set recipients = new HashSet<>(); for (Permissible permissible : this.getPluginManager().getPermissionSubscriptions(permission)) { diff --git a/patches/server/0710-Prevent-empty-items-from-being-added-to-world.patch b/patches/server/0709-Prevent-empty-items-from-being-added-to-world.patch similarity index 89% rename from patches/server/0710-Prevent-empty-items-from-being-added-to-world.patch rename to patches/server/0709-Prevent-empty-items-from-being-added-to-world.patch index 9c6532791944..4b6241c7701f 100644 --- a/patches/server/0710-Prevent-empty-items-from-being-added-to-world.patch +++ b/patches/server/0709-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 cb33c53d441d2d535b48cb80f5ac445b52cd98be..f9f00a3862ab829e7695b1da484cb752bdef5c4f 100644 +index f4b1b5f1903015b3c4650186466c8183560c9de0..f3f93e8cbc2a5c9d0a3841ec7de010477bfd976a 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1230,6 +1230,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1200,6 +1200,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // 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/0711-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch b/patches/server/0710-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch similarity index 100% rename from patches/server/0711-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch rename to patches/server/0710-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch diff --git a/patches/server/0712-Add-Player-getFishHook.patch b/patches/server/0711-Add-Player-getFishHook.patch similarity index 100% rename from patches/server/0712-Add-Player-getFishHook.patch rename to patches/server/0711-Add-Player-getFishHook.patch diff --git a/patches/server/0713-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch b/patches/server/0712-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch similarity index 100% rename from patches/server/0713-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch rename to patches/server/0712-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch diff --git a/patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch b/patches/server/0713-Add-various-missing-EntityDropItemEvent-calls.patch similarity index 100% rename from patches/server/0714-Add-various-missing-EntityDropItemEvent-calls.patch rename to patches/server/0713-Add-various-missing-EntityDropItemEvent-calls.patch diff --git a/patches/server/0715-Fix-Bee-flower-NPE.patch b/patches/server/0714-Fix-Bee-flower-NPE.patch similarity index 100% rename from patches/server/0715-Fix-Bee-flower-NPE.patch rename to patches/server/0714-Fix-Bee-flower-NPE.patch diff --git a/patches/server/0716-More-Teleport-API.patch b/patches/server/0715-More-Teleport-API.patch similarity index 99% rename from patches/server/0716-More-Teleport-API.patch rename to patches/server/0715-More-Teleport-API.patch index c2d39bdc6395..7f4fab5c3051 100644 --- a/patches/server/0716-More-Teleport-API.patch +++ b/patches/server/0715-More-Teleport-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] More Teleport API diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index ac2ad33a44ce04d9673adc08ff21a167d606e4db..349da8b85b7a122977fcad80a399605109b88db2 100644 +index bc8f9bd50de3894e6262e13ed55252c98f22ed8a..4d64eedfbe5b967572b7140ddfb55efa1ccc3650 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1585,11 +1585,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0717-Add-EntityPortalReadyEvent.patch b/patches/server/0716-Add-EntityPortalReadyEvent.patch similarity index 100% rename from patches/server/0717-Add-EntityPortalReadyEvent.patch rename to patches/server/0716-Add-EntityPortalReadyEvent.patch diff --git a/patches/server/0718-Don-t-use-level-random-in-entity-constructors.patch b/patches/server/0717-Don-t-use-level-random-in-entity-constructors.patch similarity index 100% rename from patches/server/0718-Don-t-use-level-random-in-entity-constructors.patch rename to patches/server/0717-Don-t-use-level-random-in-entity-constructors.patch diff --git a/patches/server/0719-Send-block-entities-after-destroy-prediction.patch b/patches/server/0718-Send-block-entities-after-destroy-prediction.patch similarity index 98% rename from patches/server/0719-Send-block-entities-after-destroy-prediction.patch rename to patches/server/0718-Send-block-entities-after-destroy-prediction.patch index 2742769b83a4..6fcd859761f1 100644 --- a/patches/server/0719-Send-block-entities-after-destroy-prediction.patch +++ b/patches/server/0718-Send-block-entities-after-destroy-prediction.patch @@ -57,7 +57,7 @@ index 5c3e5c348e6fececccd8097355f423b9e7ad982b..064a7a3e1c4d192010e072a5e985a541 } } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 349da8b85b7a122977fcad80a399605109b88db2..32ed76fca856b7d121e2215748be4f6d1b18791a 100644 +index 4d64eedfbe5b967572b7140ddfb55efa1ccc3650..b48966424fb8e937552c0e7bffaedaefc63ef77f 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1723,8 +1723,28 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0720-Warn-on-plugins-accessing-faraway-chunks.patch b/patches/server/0719-Warn-on-plugins-accessing-faraway-chunks.patch similarity index 97% rename from patches/server/0720-Warn-on-plugins-accessing-faraway-chunks.patch rename to patches/server/0719-Warn-on-plugins-accessing-faraway-chunks.patch index c1e4213d1cb6..2b2ca909d024 100644 --- a/patches/server/0720-Warn-on-plugins-accessing-faraway-chunks.patch +++ b/patches/server/0719-Warn-on-plugins-accessing-faraway-chunks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Warn on plugins accessing faraway chunks diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 8269bf24f5e17f9e3936659aa0cbc9d4f95fb665..a6f538372830f3f80740ef503733736e0561d1bd 100644 +index 9afc0eaaca5ab7b6445d90ce53e31a6ae76f8848..f0c2187a92de633a1d4cc7e71ff62cbe30ce8774 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -339,7 +339,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -337,7 +337,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } private static boolean isInWorldBoundsHorizontal(BlockPos pos) { diff --git a/patches/server/0721-Custom-Chat-Completion-Suggestions-API.patch b/patches/server/0720-Custom-Chat-Completion-Suggestions-API.patch similarity index 100% rename from patches/server/0721-Custom-Chat-Completion-Suggestions-API.patch rename to patches/server/0720-Custom-Chat-Completion-Suggestions-API.patch diff --git a/patches/server/0722-Add-and-fix-missing-BlockFadeEvents.patch b/patches/server/0721-Add-and-fix-missing-BlockFadeEvents.patch similarity index 100% rename from patches/server/0722-Add-and-fix-missing-BlockFadeEvents.patch rename to patches/server/0721-Add-and-fix-missing-BlockFadeEvents.patch diff --git a/patches/server/0723-Collision-API.patch b/patches/server/0722-Collision-API.patch similarity index 100% rename from patches/server/0723-Collision-API.patch rename to patches/server/0722-Collision-API.patch diff --git a/patches/server/0724-Fix-suggest-command-message-for-brigadier-syntax-exc.patch b/patches/server/0723-Fix-suggest-command-message-for-brigadier-syntax-exc.patch similarity index 100% rename from patches/server/0724-Fix-suggest-command-message-for-brigadier-syntax-exc.patch rename to patches/server/0723-Fix-suggest-command-message-for-brigadier-syntax-exc.patch diff --git a/patches/server/0725-Block-Ticking-API.patch b/patches/server/0724-Block-Ticking-API.patch similarity index 100% rename from patches/server/0725-Block-Ticking-API.patch rename to patches/server/0724-Block-Ticking-API.patch diff --git a/patches/server/0726-Add-Velocity-IP-Forwarding-Support.patch b/patches/server/0725-Add-Velocity-IP-Forwarding-Support.patch similarity index 97% rename from patches/server/0726-Add-Velocity-IP-Forwarding-Support.patch rename to patches/server/0725-Add-Velocity-IP-Forwarding-Support.patch index cba81cdb0f83..d5eb9544e551 100644 --- a/patches/server/0726-Add-Velocity-IP-Forwarding-Support.patch +++ b/patches/server/0725-Add-Velocity-IP-Forwarding-Support.patch @@ -106,10 +106,10 @@ index 0000000000000000000000000000000000000000..1b797955357612a4319452de7461ba04 + } +} diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 3c3be48b29fcd38c5dea1bfca8d8690850aa948e..4037a1057ebc87e3df6333e0d546fc85b5148d2a 100644 +index ac7fc2497b860a143ef08498f5f477a373a29be7..4e47611f85f3db6a638d0fc6a0dd712b245cf229 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -290,13 +290,20 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -288,13 +288,20 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.STARTUP); // CraftBukkit end @@ -228,10 +228,10 @@ index cb5dd77892283a1aaec45434fb99bb7f08ee5394..4a89b73d972f366e70f4d2bd96c6ee41 } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 0c037618005265ed6b9533ea60848753141d8e0b..ff7bd67f593bbaabb5eb4c2b845acb2d428f1670 100644 +index 3deb58f3cd2e29b51944ac81cb3e0e52ec496242..b84dc11212aba4c06375cdbefa91c09d86a2b957 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -849,7 +849,7 @@ public final class CraftServer implements Server { +@@ -848,7 +848,7 @@ public final class CraftServer implements Server { @Override public long getConnectionThrottle() { // Spigot Start - Automatically set connection throttle for bungee configurations diff --git a/patches/server/0727-Add-NamespacedKey-biome-methods.patch b/patches/server/0726-Add-NamespacedKey-biome-methods.patch similarity index 76% rename from patches/server/0727-Add-NamespacedKey-biome-methods.patch rename to patches/server/0726-Add-NamespacedKey-biome-methods.patch index 547d0fb0b746..015b2064d994 100644 --- a/patches/server/0727-Add-NamespacedKey-biome-methods.patch +++ b/patches/server/0726-Add-NamespacedKey-biome-methods.patch @@ -6,14 +6,14 @@ Subject: [PATCH] Add NamespacedKey biome methods Co-authored-by: Thonk <30448663+ExcessiveAmountsOfZombies@users.noreply.github.com> diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 8d51786837448db1a96d0071293025d07e14c225..9e0af05e066132b66fafff84ff0a0957c1a44f9f 100644 +index 1ab160c3d042be43df3bd19d095534b91c4c2f71..9f4124485dac3d029ec8247b64098042aa1a48d2 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -584,6 +584,21 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -587,6 +587,19 @@ public final class CraftMagicNumbers implements UnsafeValues { + var supplier = net.minecraft.world.entity.ai.attributes.DefaultAttributes.getSupplier((net.minecraft.world.entity.EntityType) net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.getValue(CraftNamespacedKey.toMinecraft(bukkitEntityKey))); + return new io.papermc.paper.attribute.UnmodifiableAttributeMap(supplier); } - // Paper end - -+ // Paper start - namespaced key biome methods ++ + @Override + public org.bukkit.NamespacedKey getBiomeKey(org.bukkit.RegionAccessor accessor, int x, int y, int z) { + org.bukkit.craftbukkit.CraftRegionAccessor cra = (org.bukkit.craftbukkit.CraftRegionAccessor) accessor; @@ -26,8 +26,6 @@ index 8d51786837448db1a96d0071293025d07e14c225..9e0af05e066132b66fafff84ff0a0957 + net.minecraft.core.Holder biomeBase = cra.getHandle().registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BIOME).getOrThrow(net.minecraft.resources.ResourceKey.create(net.minecraft.core.registries.Registries.BIOME, org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(biomeKey))); + cra.setBiome(x, y, z, biomeBase); + } -+ // Paper end - namespaced key biome methods -+ - @Override - public String get(Class aClass, String s) { - if (aClass == Enchantment.class) { + // Paper end + + /** diff --git a/patches/server/0728-Fix-plugin-loggers-on-server-shutdown.patch b/patches/server/0727-Fix-plugin-loggers-on-server-shutdown.patch similarity index 94% rename from patches/server/0728-Fix-plugin-loggers-on-server-shutdown.patch rename to patches/server/0727-Fix-plugin-loggers-on-server-shutdown.patch index 5e13337ca631..7f6f4755d14f 100644 --- a/patches/server/0728-Fix-plugin-loggers-on-server-shutdown.patch +++ b/patches/server/0727-Fix-plugin-loggers-on-server-shutdown.patch @@ -37,10 +37,10 @@ index 0000000000000000000000000000000000000000..c1d3bac79bb8b4796c013ff4472f75dc + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 8fe1514bdc6b2e81a10e445952bd71afa5892552..57080f1343aa5408d70b320375813b00b205aafa 100644 +index aa9a4a0f35d0200777bdc83520ba82a970bfa900..cb40a2d855e7ac8c1c8b4ec679fd057a31f3fc6f 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1279,6 +1279,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index d41c0f1aa501cbe17c88029bafbe034901f6d562..7705c791bfbb386f0b9f326c4b0ee0057ed0e6f5 100644 +index 786ac2127bc743cf2a33776314a4b5c197f35538..b367f6e329f44801c6f0d34f447497093d86ae3b 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3272,37 +3272,15 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3270,37 +3270,15 @@ public abstract class LivingEntity extends Entity implements Attackable { gameprofilerfiller.pop(); gameprofilerfiller.push("rangeChecks"); diff --git a/patches/server/0730-Fire-EntityChangeBlockEvent-in-more-places.patch b/patches/server/0729-Fire-EntityChangeBlockEvent-in-more-places.patch similarity index 100% rename from patches/server/0730-Fire-EntityChangeBlockEvent-in-more-places.patch rename to patches/server/0729-Fire-EntityChangeBlockEvent-in-more-places.patch diff --git a/patches/server/0731-Missing-eating-regain-reason.patch b/patches/server/0730-Missing-eating-regain-reason.patch similarity index 100% rename from patches/server/0731-Missing-eating-regain-reason.patch rename to patches/server/0730-Missing-eating-regain-reason.patch diff --git a/patches/server/0732-Missing-effect-cause.patch b/patches/server/0731-Missing-effect-cause.patch similarity index 100% rename from patches/server/0732-Missing-effect-cause.patch rename to patches/server/0731-Missing-effect-cause.patch diff --git a/patches/server/0733-Added-byte-array-serialization-deserialization-for-P.patch b/patches/server/0732-Added-byte-array-serialization-deserialization-for-P.patch similarity index 100% rename from patches/server/0733-Added-byte-array-serialization-deserialization-for-P.patch rename to patches/server/0732-Added-byte-array-serialization-deserialization-for-P.patch diff --git a/patches/server/0734-Call-BlockPhysicsEvent-more-often.patch b/patches/server/0733-Call-BlockPhysicsEvent-more-often.patch similarity index 100% rename from patches/server/0734-Call-BlockPhysicsEvent-more-often.patch rename to patches/server/0733-Call-BlockPhysicsEvent-more-often.patch diff --git a/patches/server/0735-Configurable-chat-thread-limit.patch b/patches/server/0734-Configurable-chat-thread-limit.patch similarity index 94% rename from patches/server/0735-Configurable-chat-thread-limit.patch rename to patches/server/0734-Configurable-chat-thread-limit.patch index 1432c0659448..a02e95e2bf39 100644 --- a/patches/server/0735-Configurable-chat-thread-limit.patch +++ b/patches/server/0734-Configurable-chat-thread-limit.patch @@ -22,10 +22,10 @@ is actually processed, this is honestly really just exposed for the misnomers or who just wanna ensure that this won't grow over a specific size if chat gets stupidly active diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 904d2f96a60e72aa089fdfe6be08044b04f995c1..36b96e0ed5c0d25068ec4678eddd8a19a020d345 100644 +index c3fe4481dd35f80815716e48beeeb07b1f51e30b..56798215644d8bca1695856b3a941e8089f49e48 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -327,7 +327,18 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -302,7 +302,18 @@ public class GlobalConfiguration extends ConfigurationPart { @PostProcess private void postProcess() { diff --git a/patches/server/0736-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch b/patches/server/0735-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch similarity index 100% rename from patches/server/0736-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch rename to patches/server/0735-Mitigate-effects-of-WorldCreator-keepSpawnLoaded-ret.patch diff --git a/patches/server/0737-fix-Jigsaw-block-kicking-user.patch b/patches/server/0736-fix-Jigsaw-block-kicking-user.patch similarity index 100% rename from patches/server/0737-fix-Jigsaw-block-kicking-user.patch rename to patches/server/0736-fix-Jigsaw-block-kicking-user.patch diff --git a/patches/server/0738-use-BlockFormEvent-for-mud-converting-into-clay.patch b/patches/server/0737-use-BlockFormEvent-for-mud-converting-into-clay.patch similarity index 100% rename from patches/server/0738-use-BlockFormEvent-for-mud-converting-into-clay.patch rename to patches/server/0737-use-BlockFormEvent-for-mud-converting-into-clay.patch diff --git a/patches/server/0739-Add-getDrops-to-BlockState.patch b/patches/server/0738-Add-getDrops-to-BlockState.patch similarity index 100% rename from patches/server/0739-Add-getDrops-to-BlockState.patch rename to patches/server/0738-Add-getDrops-to-BlockState.patch diff --git a/patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch b/patches/server/0739-Fix-a-bunch-of-vanilla-bugs.patch similarity index 97% rename from patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch rename to patches/server/0739-Fix-a-bunch-of-vanilla-bugs.patch index 69ca61a6dc2b..93ef32db8ae1 100644 --- a/patches/server/0740-Fix-a-bunch-of-vanilla-bugs.patch +++ b/patches/server/0739-Fix-a-bunch-of-vanilla-bugs.patch @@ -91,10 +91,10 @@ index 6854ca4d4fec2b4fa541c3fabf63787665572609..e7b444a10b244828827b3c66c5346520 } diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 75854574aa8d4aef35d84ba4c0fc7df9a67ae48c..3f3124bbb5077a18c3d3afac7748a47e84b8fe35 100644 +index b92a889d0b0c46c1fa247d770f303d7d37dfc36c..e1c69c3c8e4809c7ccd2e1e12ee8538ab4bd3d5c 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1080,7 +1080,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1078,7 +1078,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } @@ -104,10 +104,10 @@ index 75854574aa8d4aef35d84ba4c0fc7df9a67ae48c..3f3124bbb5077a18c3d3afac7748a47e return this.anyPlayerCloseEnoughForSpawning(pos, false); } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index f9f00a3862ab829e7695b1da484cb752bdef5c4f..fbee72c0b6e7d73cb0a999330ac7871bb8a7d7e4 100644 +index f3f93e8cbc2a5c9d0a3841ec7de010477bfd976a..d01f42aad003c7b0ea5700d32109eed4a264fa4c 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -764,7 +764,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -748,7 +748,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } else { AABB axisalignedbb = AABB.encapsulatingFullBlocks(blockposition1, blockposition1.atY(this.getMaxY() + 1)).inflate(3.0D); List list = this.getEntitiesOfClass(LivingEntity.class, axisalignedbb, (entityliving) -> { @@ -130,7 +130,7 @@ index 064a7a3e1c4d192010e072a5e985a54135748d87..a706f0855fdf88cc9aece3ba00ef574b this.player.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, this.player), this.player); // CraftBukkit this.level.updateSleepingPlayerList(); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 32ed76fca856b7d121e2215748be4f6d1b18791a..72ac67c6d42a1763fd63bd0d0db18ba709f48314 100644 +index b48966424fb8e937552c0e7bffaedaefc63ef77f..79eceb995f92b3f3d7b695dc6d2a0a4a824ce871 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1831,7 +1831,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -143,10 +143,10 @@ index 32ed76fca856b7d121e2215748be4f6d1b18791a..72ac67c6d42a1763fd63bd0d0db18ba7 MutableComponent ichatmutablecomponent1 = Component.translatable("build.tooHigh", i).withStyle(ChatFormatting.RED); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 0646e435e869b5cc067968feb09ff5c6a979a8a7..61c37bf5f75207085f22093e48986dab8231e1c1 100644 +index 3d741bd09cd2086aa63b77636fe3ecfc55577aad..6332d5e281bb355bee1a112d11e96ee26e337ebf 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -261,7 +261,7 @@ public abstract class PlayerList { +@@ -260,7 +260,7 @@ public abstract class PlayerList { } if (optional.isEmpty() || invalidPlayerWorld[0]) { // Paper end - reset to main world spawn if first spawn or invalid world @@ -155,7 +155,7 @@ index 0646e435e869b5cc067968feb09ff5c6a979a8a7..61c37bf5f75207085f22093e48986dab } // Paper end - Entity#getEntitySpawnReason player.setServerLevel(worldserver1); -@@ -661,8 +661,10 @@ public abstract class PlayerList { +@@ -660,8 +660,10 @@ public abstract class PlayerList { Player player = entity.getBukkitEntity(); PlayerLoginEvent event = new PlayerLoginEvent(player, loginlistener.connection.hostname, ((java.net.InetSocketAddress) socketaddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.connection.channel.remoteAddress()).getAddress()); diff --git a/patches/server/0741-Remove-unnecessary-onTrackingStart-during-navigation.patch b/patches/server/0740-Remove-unnecessary-onTrackingStart-during-navigation.patch similarity index 88% rename from patches/server/0741-Remove-unnecessary-onTrackingStart-during-navigation.patch rename to patches/server/0740-Remove-unnecessary-onTrackingStart-during-navigation.patch index b26563ecdf18..ad0baf535fa1 100644 --- a/patches/server/0741-Remove-unnecessary-onTrackingStart-during-navigation.patch +++ b/patches/server/0740-Remove-unnecessary-onTrackingStart-during-navigation.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Remove unnecessary onTrackingStart during navigation warning diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index fbee72c0b6e7d73cb0a999330ac7871bb8a7d7e4..18d39f4a8b1b15960a9b8351d46a62bea848f9c8 100644 +index d01f42aad003c7b0ea5700d32109eed4a264fa4c..45e61a08152517a61260e662764d8bb0335537e3 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2267,7 +2267,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2237,7 +2237,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } if (entity instanceof Mob entityinsentient) { @@ -17,7 +17,7 @@ index fbee72c0b6e7d73cb0a999330ac7871bb8a7d7e4..18d39f4a8b1b15960a9b8351d46a62be String s = "onTrackingStart called during navigation iteration"; Util.logAndPauseIfInIde("onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")); -@@ -2347,7 +2347,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2317,7 +2317,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } if (entity instanceof Mob entityinsentient) { diff --git a/patches/server/0742-Fix-custom-piglin-loved-items.patch b/patches/server/0741-Fix-custom-piglin-loved-items.patch similarity index 100% rename from patches/server/0742-Fix-custom-piglin-loved-items.patch rename to patches/server/0741-Fix-custom-piglin-loved-items.patch diff --git a/patches/server/0743-EntityPickupItemEvent-fixes.patch b/patches/server/0742-EntityPickupItemEvent-fixes.patch similarity index 100% rename from patches/server/0743-EntityPickupItemEvent-fixes.patch rename to patches/server/0742-EntityPickupItemEvent-fixes.patch diff --git a/patches/server/0744-Correctly-handle-interactions-with-items-on-cooldown.patch b/patches/server/0743-Correctly-handle-interactions-with-items-on-cooldown.patch similarity index 100% rename from patches/server/0744-Correctly-handle-interactions-with-items-on-cooldown.patch rename to patches/server/0743-Correctly-handle-interactions-with-items-on-cooldown.patch diff --git a/patches/server/0745-Add-PlayerInventorySlotChangeEvent.patch b/patches/server/0744-Add-PlayerInventorySlotChangeEvent.patch similarity index 100% rename from patches/server/0745-Add-PlayerInventorySlotChangeEvent.patch rename to patches/server/0744-Add-PlayerInventorySlotChangeEvent.patch diff --git a/patches/server/0746-Elder-Guardian-appearance-API.patch b/patches/server/0745-Elder-Guardian-appearance-API.patch similarity index 100% rename from patches/server/0746-Elder-Guardian-appearance-API.patch rename to patches/server/0745-Elder-Guardian-appearance-API.patch diff --git a/patches/server/0747-Add-entity-knockback-API.patch b/patches/server/0746-Add-entity-knockback-API.patch similarity index 100% rename from patches/server/0747-Add-entity-knockback-API.patch rename to patches/server/0746-Add-entity-knockback-API.patch diff --git a/patches/server/0748-Detect-headless-JREs.patch b/patches/server/0747-Detect-headless-JREs.patch similarity index 100% rename from patches/server/0748-Detect-headless-JREs.patch rename to patches/server/0747-Detect-headless-JREs.patch diff --git a/patches/server/0749-fix-entity-vehicle-collision-event-not-called.patch b/patches/server/0748-fix-entity-vehicle-collision-event-not-called.patch similarity index 100% rename from patches/server/0749-fix-entity-vehicle-collision-event-not-called.patch rename to patches/server/0748-fix-entity-vehicle-collision-event-not-called.patch diff --git a/patches/server/0750-Add-EntityToggleSitEvent.patch b/patches/server/0749-Add-EntityToggleSitEvent.patch similarity index 100% rename from patches/server/0750-Add-EntityToggleSitEvent.patch rename to patches/server/0749-Add-EntityToggleSitEvent.patch diff --git a/patches/server/0751-Add-fire-tick-delay-option.patch b/patches/server/0750-Add-fire-tick-delay-option.patch similarity index 100% rename from patches/server/0751-Add-fire-tick-delay-option.patch rename to patches/server/0750-Add-fire-tick-delay-option.patch diff --git a/patches/server/0752-Add-Moving-Piston-API.patch b/patches/server/0751-Add-Moving-Piston-API.patch similarity index 100% rename from patches/server/0752-Add-Moving-Piston-API.patch rename to patches/server/0751-Add-Moving-Piston-API.patch diff --git a/patches/server/0753-Ignore-impossible-spawn-tick.patch b/patches/server/0752-Ignore-impossible-spawn-tick.patch similarity index 100% rename from patches/server/0753-Ignore-impossible-spawn-tick.patch rename to patches/server/0752-Ignore-impossible-spawn-tick.patch diff --git a/patches/server/0754-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch b/patches/server/0753-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch similarity index 100% rename from patches/server/0754-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch rename to patches/server/0753-Fix-EntityArgument-and-EntitySelectorParser-permissi.patch diff --git a/patches/server/0755-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch b/patches/server/0754-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch similarity index 100% rename from patches/server/0755-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch rename to patches/server/0754-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch diff --git a/patches/server/0756-Add-PrePlayerAttackEntityEvent.patch b/patches/server/0755-Add-PrePlayerAttackEntityEvent.patch similarity index 100% rename from patches/server/0756-Add-PrePlayerAttackEntityEvent.patch rename to patches/server/0755-Add-PrePlayerAttackEntityEvent.patch diff --git a/patches/server/0757-ensure-reset-EnderDragon-boss-event-name.patch b/patches/server/0756-ensure-reset-EnderDragon-boss-event-name.patch similarity index 100% rename from patches/server/0757-ensure-reset-EnderDragon-boss-event-name.patch rename to patches/server/0756-ensure-reset-EnderDragon-boss-event-name.patch diff --git a/patches/server/0758-Add-Player-Warden-Warning-API.patch b/patches/server/0757-Add-Player-Warden-Warning-API.patch similarity index 100% rename from patches/server/0758-Add-Player-Warden-Warning-API.patch rename to patches/server/0757-Add-Player-Warden-Warning-API.patch diff --git a/patches/server/0759-More-vanilla-friendly-methods-to-update-trades.patch b/patches/server/0758-More-vanilla-friendly-methods-to-update-trades.patch similarity index 100% rename from patches/server/0759-More-vanilla-friendly-methods-to-update-trades.patch rename to patches/server/0758-More-vanilla-friendly-methods-to-update-trades.patch diff --git a/patches/server/0760-Add-paper-dumplisteners-command.patch b/patches/server/0759-Add-paper-dumplisteners-command.patch similarity index 100% rename from patches/server/0760-Add-paper-dumplisteners-command.patch rename to patches/server/0759-Add-paper-dumplisteners-command.patch diff --git a/patches/server/0761-check-global-player-list-where-appropriate.patch b/patches/server/0760-check-global-player-list-where-appropriate.patch similarity index 93% rename from patches/server/0761-check-global-player-list-where-appropriate.patch rename to patches/server/0760-check-global-player-list-where-appropriate.patch index e96a666062de..393c169165f2 100644 --- a/patches/server/0761-check-global-player-list-where-appropriate.patch +++ b/patches/server/0760-check-global-player-list-where-appropriate.patch @@ -7,10 +7,10 @@ Makes certain entities check all players when searching for a player instead of just checking players in their world. diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 18d39f4a8b1b15960a9b8351d46a62bea848f9c8..79acbaf880d5f47efd210627a60ce1e930b63e39 100644 +index 45e61a08152517a61260e662764d8bb0335537e3..b81d814619e4175f42aee397811b07cae420c2e8 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2383,4 +2383,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2353,4 +2353,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe entity.updateDynamicGameEventListener(DynamicGameEventListener::move); } } @@ -24,10 +24,10 @@ index 18d39f4a8b1b15960a9b8351d46a62bea848f9c8..79acbaf880d5f47efd210627a60ce1e9 + // Paper end - check global player list where appropriate } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 7705c791bfbb386f0b9f326c4b0ee0057ed0e6f5..2c343617f9467bbef03f4d131ce94b1f1a090a80 100644 +index b367f6e329f44801c6f0d34f447497093d86ae3b..5330f6315cecfa6afd04b711a5b8656717cb5ede 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3867,7 +3867,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3865,7 +3865,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } public void onItemPickup(ItemEntity item) { diff --git a/patches/server/0762-Fix-async-entity-add-due-to-fungus-trees.patch b/patches/server/0761-Fix-async-entity-add-due-to-fungus-trees.patch similarity index 100% rename from patches/server/0762-Fix-async-entity-add-due-to-fungus-trees.patch rename to patches/server/0761-Fix-async-entity-add-due-to-fungus-trees.patch diff --git a/patches/server/0763-ItemStack-damage-API.patch b/patches/server/0762-ItemStack-damage-API.patch similarity index 100% rename from patches/server/0763-ItemStack-damage-API.patch rename to patches/server/0762-ItemStack-damage-API.patch diff --git a/patches/server/0764-Friction-API.patch b/patches/server/0763-Friction-API.patch similarity index 95% rename from patches/server/0764-Friction-API.patch rename to patches/server/0763-Friction-API.patch index 469868818a40..25f88d845f80 100644 --- a/patches/server/0764-Friction-API.patch +++ b/patches/server/0763-Friction-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Friction API diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 2c343617f9467bbef03f4d131ce94b1f1a090a80..5520d0cdd5af75a6188a68f809aafb6c5880878a 100644 +index 5330f6315cecfa6afd04b711a5b8656717cb5ede..8b0a764984f886b711cb337a7f70608167916bf3 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -298,6 +298,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -296,6 +296,7 @@ public abstract class LivingEntity extends Entity implements Attackable { public boolean bukkitPickUpLoot; public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper public boolean silentDeath = false; // Paper - mark entity as dying silently for cancellable death event @@ -16,7 +16,7 @@ index 2c343617f9467bbef03f4d131ce94b1f1a090a80..5520d0cdd5af75a6188a68f809aafb6c @Override public float getBukkitYaw() { -@@ -724,7 +725,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -722,7 +723,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } public boolean shouldDiscardFriction() { @@ -25,7 +25,7 @@ index 2c343617f9467bbef03f4d131ce94b1f1a090a80..5520d0cdd5af75a6188a68f809aafb6c } public void setDiscardFriction(boolean noDrag) { -@@ -798,6 +799,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -796,6 +797,11 @@ public abstract class LivingEntity extends Entity implements Attackable { @Override public void addAdditionalSaveData(CompoundTag nbt) { @@ -37,7 +37,7 @@ index 2c343617f9467bbef03f4d131ce94b1f1a090a80..5520d0cdd5af75a6188a68f809aafb6c nbt.putFloat("Health", this.getHealth()); nbt.putShort("HurtTime", (short) this.hurtTime); nbt.putInt("HurtByTimestamp", this.lastHurtByMobTimestamp); -@@ -841,6 +847,16 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -839,6 +845,16 @@ public abstract class LivingEntity extends Entity implements Attackable { } this.internalSetAbsorptionAmount(absorptionAmount); // Paper end - Check for NaN diff --git a/patches/server/0765-Ability-to-control-player-s-insomnia-and-phantoms.patch b/patches/server/0764-Ability-to-control-player-s-insomnia-and-phantoms.patch similarity index 100% rename from patches/server/0765-Ability-to-control-player-s-insomnia-and-phantoms.patch rename to patches/server/0764-Ability-to-control-player-s-insomnia-and-phantoms.patch diff --git a/patches/server/0766-Fix-premature-player-kicks-on-shutdown.patch b/patches/server/0765-Fix-premature-player-kicks-on-shutdown.patch similarity index 95% rename from patches/server/0766-Fix-premature-player-kicks-on-shutdown.patch rename to patches/server/0765-Fix-premature-player-kicks-on-shutdown.patch index 2c4fc7c2c0dc..5a0d9d65c0bd 100644 --- a/patches/server/0766-Fix-premature-player-kicks-on-shutdown.patch +++ b/patches/server/0765-Fix-premature-player-kicks-on-shutdown.patch @@ -47,10 +47,10 @@ index 4d9f1fc884050993287adfa4578a87da710623fb..a8dfe7a4b3d01bf75587be078f471d1e this.disconnect((Component) Component.translatable("multiplayer.disconnect.server_shutdown")); } catch (ClassCastException classcastexception) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 57080f1343aa5408d70b320375813b00b205aafa..736ff3988d66b8694475d5f62673da61fcb76179 100644 +index cb40a2d855e7ac8c1c8b4ec679fd057a31f3fc6f..8f7a808b0c89953a7f2932e68e2c85f9330469f2 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2171,7 +2171,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 6f3e25d41420b5e54721e88c84fd3194d6170b9a..59b64ea82c84ff7d9b9123473b4466ec01918cd2 100644 +index 345d5069d0ebb8ad74158334fd230d0ea64b909d..af8a513c2692b71ad56abce24048b61eb78d41c4 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -2078,7 +2078,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0778-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch b/patches/server/0777-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch similarity index 100% rename from patches/server/0778-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch rename to patches/server/0777-Fix-NPE-on-Allay-stopDancing-while-not-dancing.patch diff --git a/patches/server/0779-Flying-Fall-Damage.patch b/patches/server/0778-Flying-Fall-Damage.patch similarity index 100% rename from patches/server/0779-Flying-Fall-Damage.patch rename to patches/server/0778-Flying-Fall-Damage.patch diff --git a/patches/server/0780-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch b/patches/server/0779-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch similarity index 100% rename from patches/server/0780-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch rename to patches/server/0779-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch diff --git a/patches/server/0781-config-for-disabling-entity-tag-tags.patch b/patches/server/0780-config-for-disabling-entity-tag-tags.patch similarity index 89% rename from patches/server/0781-config-for-disabling-entity-tag-tags.patch rename to patches/server/0780-config-for-disabling-entity-tag-tags.patch index f1526d5e31b9..59c33843cef1 100644 --- a/patches/server/0781-config-for-disabling-entity-tag-tags.patch +++ b/patches/server/0780-config-for-disabling-entity-tag-tags.patch @@ -5,10 +5,10 @@ Subject: [PATCH] config for disabling entity tag tags diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index e5dc6f868f090d1957306a6389d85cf9dbbc444d..ca9e63942f3cb8986456410b2a77aafc6541aad2 100644 +index 989b766bc166141a391e0a7c1a5eb815e20acfac..64dc0bd1900575e40ac72a98c6df371223bd244c 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -578,6 +578,16 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -569,6 +569,16 @@ public class EntityType implements FeatureElement, EntityTypeT if (minecraftserver != null && entity != null) { if (world.isClientSide || !entity.onlyOpCanSetNbt() || player != null && minecraftserver.getPlayerList().isOp(player.getGameProfile())) { diff --git a/patches/server/0782-Use-single-player-info-update-packet-on-join.patch b/patches/server/0781-Use-single-player-info-update-packet-on-join.patch similarity index 89% rename from patches/server/0782-Use-single-player-info-update-packet-on-join.patch rename to patches/server/0781-Use-single-player-info-update-packet-on-join.patch index 68e488cbf6ca..c1e89be3e8fe 100644 --- a/patches/server/0782-Use-single-player-info-update-packet-on-join.patch +++ b/patches/server/0781-Use-single-player-info-update-packet-on-join.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Use single player info update packet on join diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 59b64ea82c84ff7d9b9123473b4466ec01918cd2..51f4d1e5c02c516b5c57095d35348ba53f5b3193 100644 +index af8a513c2692b71ad56abce24048b61eb78d41c4..5802bca38fdeccbc1353990ecb425034f86e8332 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3489,7 +3489,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3486,7 +3486,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.signedMessageDecoder = session.createMessageDecoder(this.player.getUUID()); this.chatMessageChain.append(() -> { this.player.setChatSession(session); @@ -18,10 +18,10 @@ index 59b64ea82c84ff7d9b9123473b4466ec01918cd2..51f4d1e5c02c516b5c57095d35348ba5 } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 61c37bf5f75207085f22093e48986dab8231e1c1..f9212fc2db00531da1618780e231e8ad21285907 100644 +index 6332d5e281bb355bee1a112d11e96ee26e337ebf..af0ea5b5bbc35cced959beb3ecb576fff46c6a51 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -365,6 +365,7 @@ public abstract class PlayerList { +@@ -364,6 +364,7 @@ public abstract class PlayerList { // CraftBukkit start - sendAll above replaced with this loop ClientboundPlayerInfoUpdatePacket packet = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player)); @@ -29,7 +29,7 @@ index 61c37bf5f75207085f22093e48986dab8231e1c1..f9212fc2db00531da1618780e231e8ad for (int i = 0; i < this.players.size(); ++i) { ServerPlayer entityplayer1 = (ServerPlayer) this.players.get(i); -@@ -372,12 +373,17 @@ public abstract class PlayerList { +@@ -371,12 +372,17 @@ public abstract class PlayerList { entityplayer1.connection.send(packet); } diff --git a/patches/server/0783-Correctly-shrink-items-during-EntityResurrectEvent.patch b/patches/server/0782-Correctly-shrink-items-during-EntityResurrectEvent.patch similarity index 92% rename from patches/server/0783-Correctly-shrink-items-during-EntityResurrectEvent.patch rename to patches/server/0782-Correctly-shrink-items-during-EntityResurrectEvent.patch index c14b32588290..b778104720fc 100644 --- a/patches/server/0783-Correctly-shrink-items-during-EntityResurrectEvent.patch +++ b/patches/server/0782-Correctly-shrink-items-during-EntityResurrectEvent.patch @@ -22,10 +22,10 @@ This patch corrects this behaviour by only shrinking the item if a totem of undying was found and the event was called uncancelled. diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 5520d0cdd5af75a6188a68f809aafb6c5880878a..da42691504177e1e2614db777cbe346f73725eda 100644 +index 8b0a764984f886b711cb337a7f70608167916bf3..9ef5c617cb05f08758105772b9124f6c318b5c17 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1674,7 +1674,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1672,7 +1672,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.level().getCraftServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { diff --git a/patches/server/0784-Win-Screen-API.patch b/patches/server/0783-Win-Screen-API.patch similarity index 100% rename from patches/server/0784-Win-Screen-API.patch rename to patches/server/0783-Win-Screen-API.patch diff --git a/patches/server/0785-Remove-CraftItemStack-setAmount-null-assignment.patch b/patches/server/0784-Remove-CraftItemStack-setAmount-null-assignment.patch similarity index 100% rename from patches/server/0785-Remove-CraftItemStack-setAmount-null-assignment.patch rename to patches/server/0784-Remove-CraftItemStack-setAmount-null-assignment.patch diff --git a/patches/server/0786-Fix-force-opening-enchantment-tables.patch b/patches/server/0785-Fix-force-opening-enchantment-tables.patch similarity index 100% rename from patches/server/0786-Fix-force-opening-enchantment-tables.patch rename to patches/server/0785-Fix-force-opening-enchantment-tables.patch diff --git a/patches/server/0787-Add-Entity-Body-Yaw-API.patch b/patches/server/0786-Add-Entity-Body-Yaw-API.patch similarity index 100% rename from patches/server/0787-Add-Entity-Body-Yaw-API.patch rename to patches/server/0786-Add-Entity-Body-Yaw-API.patch diff --git a/patches/server/0788-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch b/patches/server/0787-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch similarity index 100% rename from patches/server/0788-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch rename to patches/server/0787-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch diff --git a/patches/server/0789-Add-EntityFertilizeEggEvent.patch b/patches/server/0788-Add-EntityFertilizeEggEvent.patch similarity index 100% rename from patches/server/0789-Add-EntityFertilizeEggEvent.patch rename to patches/server/0788-Add-EntityFertilizeEggEvent.patch diff --git a/patches/server/0790-Fix-HumanEntity-drop-not-updating-the-client-inv.patch b/patches/server/0789-Fix-HumanEntity-drop-not-updating-the-client-inv.patch similarity index 100% rename from patches/server/0790-Fix-HumanEntity-drop-not-updating-the-client-inv.patch rename to patches/server/0789-Fix-HumanEntity-drop-not-updating-the-client-inv.patch diff --git a/patches/server/0791-Add-CompostItemEvent-and-EntityCompostItemEvent.patch b/patches/server/0790-Add-CompostItemEvent-and-EntityCompostItemEvent.patch similarity index 100% rename from patches/server/0791-Add-CompostItemEvent-and-EntityCompostItemEvent.patch rename to patches/server/0790-Add-CompostItemEvent-and-EntityCompostItemEvent.patch diff --git a/patches/server/0792-Correctly-handle-ArmorStand-invisibility.patch b/patches/server/0791-Correctly-handle-ArmorStand-invisibility.patch similarity index 100% rename from patches/server/0792-Correctly-handle-ArmorStand-invisibility.patch rename to patches/server/0791-Correctly-handle-ArmorStand-invisibility.patch diff --git a/patches/server/0793-Fix-advancement-triggers-for-entity-damage.patch b/patches/server/0792-Fix-advancement-triggers-for-entity-damage.patch similarity index 93% rename from patches/server/0793-Fix-advancement-triggers-for-entity-damage.patch rename to patches/server/0792-Fix-advancement-triggers-for-entity-damage.patch index d85577a07808..c7075265f1fd 100644 --- a/patches/server/0793-Fix-advancement-triggers-for-entity-damage.patch +++ b/patches/server/0792-Fix-advancement-triggers-for-entity-damage.patch @@ -23,10 +23,10 @@ index 821bb93e1b055ba38fafe3b7079d79aa062ebe8a..221d73676fe2fd240a47cf312c1179e0 return !this.getResponse(); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index da42691504177e1e2614db777cbe346f73725eda..a4d24269c1365f32f232116f1530ac75b096c6ab 100644 +index 9ef5c617cb05f08758105772b9124f6c318b5c17..24245cfb160dc990b3661388c2f95b9383f98428 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2465,7 +2465,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2463,7 +2463,7 @@ public abstract class LivingEntity extends Entity implements Attackable { // Duplicate triggers if blocking if (event.getDamage(DamageModifier.BLOCKING) < 0) { if (this instanceof ServerPlayer) { @@ -35,7 +35,7 @@ index da42691504177e1e2614db777cbe346f73725eda..a4d24269c1365f32f232116f1530ac75 f2 = (float) -event.getDamage(DamageModifier.BLOCKING); if (f2 > 0.0F && f2 < 3.4028235E37F) { ((ServerPlayer) this).awardStat(Stats.DAMAGE_BLOCKED_BY_SHIELD, Math.round(originalDamage * 10.0F)); -@@ -2473,7 +2473,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2471,7 +2471,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } if (damagesource.getEntity() instanceof ServerPlayer) { diff --git a/patches/server/0794-Fix-text-display-error-on-spawn.patch b/patches/server/0793-Fix-text-display-error-on-spawn.patch similarity index 100% rename from patches/server/0794-Fix-text-display-error-on-spawn.patch rename to patches/server/0793-Fix-text-display-error-on-spawn.patch diff --git a/patches/server/0795-Fix-inventories-returning-null-Locations.patch b/patches/server/0794-Fix-inventories-returning-null-Locations.patch similarity index 100% rename from patches/server/0795-Fix-inventories-returning-null-Locations.patch rename to patches/server/0794-Fix-inventories-returning-null-Locations.patch diff --git a/patches/server/0796-Add-Shearable-API.patch b/patches/server/0795-Add-Shearable-API.patch similarity index 100% rename from patches/server/0796-Add-Shearable-API.patch rename to patches/server/0795-Add-Shearable-API.patch diff --git a/patches/server/0797-Fix-SpawnEggMeta-get-setSpawnedType.patch b/patches/server/0796-Fix-SpawnEggMeta-get-setSpawnedType.patch similarity index 100% rename from patches/server/0797-Fix-SpawnEggMeta-get-setSpawnedType.patch rename to patches/server/0796-Fix-SpawnEggMeta-get-setSpawnedType.patch diff --git a/patches/server/0798-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch b/patches/server/0797-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch similarity index 100% rename from patches/server/0798-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch rename to patches/server/0797-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch diff --git a/patches/server/0799-Treat-sequence-violations-like-they-should-be.patch b/patches/server/0798-Treat-sequence-violations-like-they-should-be.patch similarity index 92% rename from patches/server/0799-Treat-sequence-violations-like-they-should-be.patch rename to patches/server/0798-Treat-sequence-violations-like-they-should-be.patch index 387f4dcf4f6f..2a7a2399bc2b 100644 --- a/patches/server/0799-Treat-sequence-violations-like-they-should-be.patch +++ b/patches/server/0798-Treat-sequence-violations-like-they-should-be.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Treat sequence violations like they should be diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 51f4d1e5c02c516b5c57095d35348ba53f5b3193..c2328bc821730dd829440ab17b7c8b1800a1f5ca 100644 +index 5802bca38fdeccbc1353990ecb425034f86e8332..3e9247f662afde4dcca900b69b6a78140f9566fa 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1997,6 +1997,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0800-Prevent-causing-expired-keys-from-impacting-new-join.patch b/patches/server/0799-Prevent-causing-expired-keys-from-impacting-new-join.patch similarity index 96% rename from patches/server/0800-Prevent-causing-expired-keys-from-impacting-new-join.patch rename to patches/server/0799-Prevent-causing-expired-keys-from-impacting-new-join.patch index 2001b0974ca0..7a5bcdc7de65 100644 --- a/patches/server/0800-Prevent-causing-expired-keys-from-impacting-new-join.patch +++ b/patches/server/0799-Prevent-causing-expired-keys-from-impacting-new-join.patch @@ -26,7 +26,7 @@ index d0b2a8b5ded71a9a41753f4addea1c49826b34a3..29b465fc1dc50e0e84ddb889c5303e80 UPDATE_GAME_MODE((serialized, buf) -> serialized.gameMode = GameType.byId(buf.readVarInt()), (buf, entry) -> buf.writeVarInt(entry.gameMode().getId())), UPDATE_LISTED((serialized, buf) -> serialized.listed = buf.readBoolean(), (buf, entry) -> buf.writeBoolean(entry.listed())), diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index c2328bc821730dd829440ab17b7c8b1800a1f5ca..60d58622fd568932c019ba6a4e4070a881fdda53 100644 +index 3e9247f662afde4dcca900b69b6a78140f9566fa..919b0ffb69720b3edeb9d25c7f41291a09976505 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -305,6 +305,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -51,7 +51,7 @@ index c2328bc821730dd829440ab17b7c8b1800a1f5ca..60d58622fd568932c019ba6a4e4070a8 } private int getMaximumFlyingTicks(Entity vehicle) { -@@ -3487,6 +3495,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3484,6 +3492,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private void resetPlayerChatState(RemoteChatSession session) { this.chatSession = session; diff --git a/patches/server/0801-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch b/patches/server/0800-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch similarity index 86% rename from patches/server/0801-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch rename to patches/server/0800-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch index bb2d2b2c3159..5ddc60ef9150 100644 --- a/patches/server/0801-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch +++ b/patches/server/0800-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent GameEvents being fired from unloaded chunks diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 79acbaf880d5f47efd210627a60ce1e930b63e39..537a755d097d7713404d83dc47cd17828b15a906 100644 +index b81d814619e4175f42aee397811b07cae420c2e8..e9096a138175448279a03a55043982b6d83fbe12 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1385,6 +1385,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1355,6 +1355,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public void gameEvent(Holder event, Vec3 emitterPos, GameEvent.Context emitter) { diff --git a/patches/server/0802-Use-array-for-gamerule-storage.patch b/patches/server/0801-Use-array-for-gamerule-storage.patch similarity index 100% rename from patches/server/0802-Use-array-for-gamerule-storage.patch rename to patches/server/0801-Use-array-for-gamerule-storage.patch diff --git a/patches/server/0803-Fix-a-couple-of-upstream-bed-issues.patch b/patches/server/0802-Fix-a-couple-of-upstream-bed-issues.patch similarity index 100% rename from patches/server/0803-Fix-a-couple-of-upstream-bed-issues.patch rename to patches/server/0802-Fix-a-couple-of-upstream-bed-issues.patch diff --git a/patches/server/0804-Fix-demo-flag-not-enabling-demo-mode.patch b/patches/server/0803-Fix-demo-flag-not-enabling-demo-mode.patch similarity index 100% rename from patches/server/0804-Fix-demo-flag-not-enabling-demo-mode.patch rename to patches/server/0803-Fix-demo-flag-not-enabling-demo-mode.patch diff --git a/patches/server/0805-Add-Mob-Experience-reward-API.patch b/patches/server/0804-Add-Mob-Experience-reward-API.patch similarity index 100% rename from patches/server/0805-Add-Mob-Experience-reward-API.patch rename to patches/server/0804-Add-Mob-Experience-reward-API.patch diff --git a/patches/server/0806-Break-redstone-on-top-of-trap-doors-early.patch b/patches/server/0805-Break-redstone-on-top-of-trap-doors-early.patch similarity index 100% rename from patches/server/0806-Break-redstone-on-top-of-trap-doors-early.patch rename to patches/server/0805-Break-redstone-on-top-of-trap-doors-early.patch diff --git a/patches/server/0807-Avoid-Lazy-Initialization-for-Enum-Fields.patch b/patches/server/0806-Avoid-Lazy-Initialization-for-Enum-Fields.patch similarity index 100% rename from patches/server/0807-Avoid-Lazy-Initialization-for-Enum-Fields.patch rename to patches/server/0806-Avoid-Lazy-Initialization-for-Enum-Fields.patch diff --git a/patches/server/0808-More-accurate-isInOpenWater-impl.patch b/patches/server/0807-More-accurate-isInOpenWater-impl.patch similarity index 100% rename from patches/server/0808-More-accurate-isInOpenWater-impl.patch rename to patches/server/0807-More-accurate-isInOpenWater-impl.patch diff --git a/patches/server/0809-Expand-PlayerItemMendEvent.patch b/patches/server/0808-Expand-PlayerItemMendEvent.patch similarity index 100% rename from patches/server/0809-Expand-PlayerItemMendEvent.patch rename to patches/server/0808-Expand-PlayerItemMendEvent.patch diff --git a/patches/server/0810-Refresh-ProjectileSource-for-projectiles.patch b/patches/server/0809-Refresh-ProjectileSource-for-projectiles.patch similarity index 100% rename from patches/server/0810-Refresh-ProjectileSource-for-projectiles.patch rename to patches/server/0809-Refresh-ProjectileSource-for-projectiles.patch diff --git a/patches/server/0811-Add-transient-modifier-API.patch b/patches/server/0810-Add-transient-modifier-API.patch similarity index 100% rename from patches/server/0811-Add-transient-modifier-API.patch rename to patches/server/0810-Add-transient-modifier-API.patch diff --git a/patches/server/0812-Fix-block-place-logic.patch b/patches/server/0811-Fix-block-place-logic.patch similarity index 95% rename from patches/server/0812-Fix-block-place-logic.patch rename to patches/server/0811-Fix-block-place-logic.patch index 6f5dfc260e3b..4f22f03cabff 100644 --- a/patches/server/0812-Fix-block-place-logic.patch +++ b/patches/server/0811-Fix-block-place-logic.patch @@ -22,10 +22,10 @@ index 44cc12a3338b5f0448c88192c8674cd36531db34..d59120f0304823361cc4112f55833239 itemstack.consume(1, entityhuman); return InteractionResult.SUCCESS; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index a6f538372830f3f80740ef503733736e0561d1bd..d048d0e4b16459b5bad44ebfa3c6a8f336f6762b 100644 +index f0c2187a92de633a1d4cc7e71ff62cbe30ce8774..18c011c1943867dbc4abee338b03b9be499876dd 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -552,17 +552,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -550,17 +550,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // CraftBukkit start iblockdata1.updateIndirectNeighbourShapes(this, blockposition, k, j - 1); // Don't call an event for the old block to limit event spam CraftWorld world = ((ServerLevel) this).getWorld(); diff --git a/patches/server/0813-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch b/patches/server/0812-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch similarity index 100% rename from patches/server/0813-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch rename to patches/server/0812-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch diff --git a/patches/server/0814-Call-BlockGrowEvent-for-missing-blocks.patch b/patches/server/0813-Call-BlockGrowEvent-for-missing-blocks.patch similarity index 100% rename from patches/server/0814-Call-BlockGrowEvent-for-missing-blocks.patch rename to patches/server/0813-Call-BlockGrowEvent-for-missing-blocks.patch diff --git a/patches/server/0815-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch b/patches/server/0814-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch similarity index 94% rename from patches/server/0815-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch rename to patches/server/0814-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch index 761e3cb98fb4..4cc150197bde 100644 --- a/patches/server/0815-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch +++ b/patches/server/0814-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Don't enforce icanhasbukkit default if alias block exists diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index ff7bd67f593bbaabb5eb4c2b845acb2d428f1670..1310bdd5ced5941b2ab4ed1f15365722c0b8252d 100644 +index b84dc11212aba4c06375cdbefa91c09d86a2b957..a7b79c9ec51f037287fad609c29b240e2071f2f8 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -358,7 +358,11 @@ public final class CraftServer implements Server { diff --git a/patches/server/0816-fix-MapLike-spam-for-missing-key-selector.patch b/patches/server/0815-fix-MapLike-spam-for-missing-key-selector.patch similarity index 100% rename from patches/server/0816-fix-MapLike-spam-for-missing-key-selector.patch rename to patches/server/0815-fix-MapLike-spam-for-missing-key-selector.patch diff --git a/patches/server/0817-Fix-sniffer-removeExploredLocation.patch b/patches/server/0816-Fix-sniffer-removeExploredLocation.patch similarity index 100% rename from patches/server/0817-Fix-sniffer-removeExploredLocation.patch rename to patches/server/0816-Fix-sniffer-removeExploredLocation.patch diff --git a/patches/server/0818-Add-method-to-remove-all-active-potion-effects.patch b/patches/server/0817-Add-method-to-remove-all-active-potion-effects.patch similarity index 100% rename from patches/server/0818-Add-method-to-remove-all-active-potion-effects.patch rename to patches/server/0817-Add-method-to-remove-all-active-potion-effects.patch diff --git a/patches/server/0819-Add-event-for-player-editing-sign.patch b/patches/server/0818-Add-event-for-player-editing-sign.patch similarity index 100% rename from patches/server/0819-Add-event-for-player-editing-sign.patch rename to patches/server/0818-Add-event-for-player-editing-sign.patch diff --git a/patches/server/0820-Only-tick-item-frames-if-players-can-see-it.patch b/patches/server/0819-Only-tick-item-frames-if-players-can-see-it.patch similarity index 100% rename from patches/server/0820-Only-tick-item-frames-if-players-can-see-it.patch rename to patches/server/0819-Only-tick-item-frames-if-players-can-see-it.patch diff --git a/patches/server/0821-Fix-cmd-permission-levels-for-command-blocks.patch b/patches/server/0820-Fix-cmd-permission-levels-for-command-blocks.patch similarity index 100% rename from patches/server/0821-Fix-cmd-permission-levels-for-command-blocks.patch rename to patches/server/0820-Fix-cmd-permission-levels-for-command-blocks.patch diff --git a/patches/server/0822-Add-option-to-disable-block-updates.patch b/patches/server/0821-Add-option-to-disable-block-updates.patch similarity index 100% rename from patches/server/0822-Add-option-to-disable-block-updates.patch rename to patches/server/0821-Add-option-to-disable-block-updates.patch diff --git a/patches/server/0823-Call-missing-BlockDispenseEvent.patch b/patches/server/0822-Call-missing-BlockDispenseEvent.patch similarity index 100% rename from patches/server/0823-Call-missing-BlockDispenseEvent.patch rename to patches/server/0822-Call-missing-BlockDispenseEvent.patch diff --git a/patches/server/0824-Don-t-load-chunks-for-supporting-block-checks.patch b/patches/server/0823-Don-t-load-chunks-for-supporting-block-checks.patch similarity index 100% rename from patches/server/0824-Don-t-load-chunks-for-supporting-block-checks.patch rename to patches/server/0823-Don-t-load-chunks-for-supporting-block-checks.patch diff --git a/patches/server/0825-Optimize-player-lookups-for-beacons.patch b/patches/server/0824-Optimize-player-lookups-for-beacons.patch similarity index 100% rename from patches/server/0825-Optimize-player-lookups-for-beacons.patch rename to patches/server/0824-Optimize-player-lookups-for-beacons.patch diff --git a/patches/server/0826-More-Sign-Block-API.patch b/patches/server/0825-More-Sign-Block-API.patch similarity index 100% rename from patches/server/0826-More-Sign-Block-API.patch rename to patches/server/0825-More-Sign-Block-API.patch diff --git a/patches/server/0827-fix-item-meta-for-tadpole-buckets.patch b/patches/server/0826-fix-item-meta-for-tadpole-buckets.patch similarity index 100% rename from patches/server/0827-fix-item-meta-for-tadpole-buckets.patch rename to patches/server/0826-fix-item-meta-for-tadpole-buckets.patch diff --git a/patches/server/0828-Fix-BanList-API.patch b/patches/server/0827-Fix-BanList-API.patch similarity index 100% rename from patches/server/0828-Fix-BanList-API.patch rename to patches/server/0827-Fix-BanList-API.patch diff --git a/patches/server/0829-Determine-lava-and-water-fluid-explosion-resistance-.patch b/patches/server/0828-Determine-lava-and-water-fluid-explosion-resistance-.patch similarity index 100% rename from patches/server/0829-Determine-lava-and-water-fluid-explosion-resistance-.patch rename to patches/server/0828-Determine-lava-and-water-fluid-explosion-resistance-.patch diff --git a/patches/server/0830-Fix-possible-NPE-on-painting-creation.patch b/patches/server/0829-Fix-possible-NPE-on-painting-creation.patch similarity index 100% rename from patches/server/0830-Fix-possible-NPE-on-painting-creation.patch rename to patches/server/0829-Fix-possible-NPE-on-painting-creation.patch diff --git a/patches/server/0831-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch b/patches/server/0830-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch similarity index 100% rename from patches/server/0831-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch rename to patches/server/0830-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch diff --git a/patches/server/0832-ExperienceOrb-should-call-EntitySpawnEvent.patch b/patches/server/0831-ExperienceOrb-should-call-EntitySpawnEvent.patch similarity index 100% rename from patches/server/0832-ExperienceOrb-should-call-EntitySpawnEvent.patch rename to patches/server/0831-ExperienceOrb-should-call-EntitySpawnEvent.patch diff --git a/patches/server/0833-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch b/patches/server/0832-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch similarity index 100% rename from patches/server/0833-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch rename to patches/server/0832-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch diff --git a/patches/server/0834-Add-whitelist-events.patch b/patches/server/0833-Add-whitelist-events.patch similarity index 100% rename from patches/server/0834-Add-whitelist-events.patch rename to patches/server/0833-Add-whitelist-events.patch diff --git a/patches/server/0835-Implement-PlayerFailMoveEvent.patch b/patches/server/0834-Implement-PlayerFailMoveEvent.patch similarity index 98% rename from patches/server/0835-Implement-PlayerFailMoveEvent.patch rename to patches/server/0834-Implement-PlayerFailMoveEvent.patch index 19858740af64..1c34e55f29cb 100644 --- a/patches/server/0835-Implement-PlayerFailMoveEvent.patch +++ b/patches/server/0834-Implement-PlayerFailMoveEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Implement PlayerFailMoveEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 60d58622fd568932c019ba6a4e4070a881fdda53..368547270a3e6cdbda812fcf0ed2519d71383b81 100644 +index 919b0ffb69720b3edeb9d25c7f41291a09976505..134d9fbdb757094a4624325c0ad8f32efadd61b6 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1271,8 +1271,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -91,7 +91,7 @@ index 60d58622fd568932c019ba6a4e4070a881fdda53..368547270a3e6cdbda812fcf0ed2519d this.internalTeleport(d3, d4, d5, f, f1); // CraftBukkit - SPIGOT-1807: Don't call teleport event, when the client thinks the player is falling, because the chunks are not loaded on the client yet. this.player.doCheckFallDamage(this.player.getX() - d3, this.player.getY() - d4, this.player.getZ() - d5, packet.isOnGround()); } else { -@@ -3537,4 +3567,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3534,4 +3564,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl InteractionResult run(ServerPlayer player, Entity entity, InteractionHand hand); } diff --git a/patches/server/0836-Folia-scheduler-and-owned-region-API.patch b/patches/server/0835-Folia-scheduler-and-owned-region-API.patch similarity index 98% rename from patches/server/0836-Folia-scheduler-and-owned-region-API.patch rename to patches/server/0835-Folia-scheduler-and-owned-region-API.patch index 33561d0d1fba..fe1d592753d3 100644 --- a/patches/server/0836-Folia-scheduler-and-owned-region-API.patch +++ b/patches/server/0835-Folia-scheduler-and-owned-region-API.patch @@ -1148,13 +1148,13 @@ index 0000000000000000000000000000000000000000..d306f911757a4d556c82c0070d4837db + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 736ff3988d66b8694475d5f62673da61fcb76179..7e83a0de08488c5acf3c1a5d7107564e2a8ed7e0 100644 +index 8f7a808b0c89953a7f2932e68e2c85f9330469f2..be188079f12b3f7b394ae91db62cc17b1d0f4e79 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1655,6 +1655,20 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { @@ -1171,12 +1171,12 @@ index 736ff3988d66b8694475d5f62673da61fcb76179..7e83a0de08488c5acf3c1a5d7107564e + // Paper end - Folia scheduler API io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.CALLBACK_MANAGER.handleQueue(this.tickCount); // Paper gameprofilerfiller.push("commandFunctions"); - MinecraftTimings.commandFunctionsTimer.startTiming(); // Spigot // Paper + this.getFunctions().tick(); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index f9212fc2db00531da1618780e231e8ad21285907..a9063533ea4b2b349d476127b99c822203d7dfcb 100644 +index af0ea5b5bbc35cced959beb3ecb576fff46c6a51..74cbc6092d49f573f7fab1895c42a0360bb80bdf 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -598,6 +598,7 @@ public abstract class PlayerList { +@@ -597,6 +597,7 @@ public abstract class PlayerList { } worldserver.removePlayerImmediately(entityplayer, Entity.RemovalReason.UNLOADED_WITH_PLAYER); @@ -1249,7 +1249,7 @@ index 3444b1a2da80b85e2b1928d69ff0dd980c5fb34f..463dd4f91212318b51174c5d2f4d25ba public void setLevelCallback(EntityInLevelCallback changeListener) { this.levelCallback = changeListener; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 1310bdd5ced5941b2ab4ed1f15365722c0b8252d..0193505562d7bdc6d2ab91b637a916cdecdec911 100644 +index a7b79c9ec51f037287fad609c29b240e2071f2f8..46807d5d94a0f90b230dfaf4d37378a3bfa21414 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -313,6 +313,76 @@ public final class CraftServer implements Server { diff --git a/patches/server/0837-Only-erase-allay-memory-on-non-item-targets.patch b/patches/server/0836-Only-erase-allay-memory-on-non-item-targets.patch similarity index 100% rename from patches/server/0837-Only-erase-allay-memory-on-non-item-targets.patch rename to patches/server/0836-Only-erase-allay-memory-on-non-item-targets.patch diff --git a/patches/server/0838-Fix-rotation-when-spawning-display-entities.patch b/patches/server/0837-Fix-rotation-when-spawning-display-entities.patch similarity index 100% rename from patches/server/0838-Fix-rotation-when-spawning-display-entities.patch rename to patches/server/0837-Fix-rotation-when-spawning-display-entities.patch diff --git a/patches/server/0839-Only-capture-actual-tree-growth.patch b/patches/server/0838-Only-capture-actual-tree-growth.patch similarity index 97% rename from patches/server/0839-Only-capture-actual-tree-growth.patch rename to patches/server/0838-Only-capture-actual-tree-growth.patch index 58fb59ab7ddd..f1dee3ad482e 100644 --- a/patches/server/0839-Only-capture-actual-tree-growth.patch +++ b/patches/server/0838-Only-capture-actual-tree-growth.patch @@ -17,10 +17,10 @@ index f8f570a97789ab16e57774f233506a289277d5d9..18304349c9ab24657c4152aff800dba9 } } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 537a755d097d7713404d83dc47cd17828b15a906..9270584d74edf5c1af473b1a13f7edca74cc1ec7 100644 +index e9096a138175448279a03a55043982b6d83fbe12..0db41d36d5daf015c750fb0246ab3e5da1cd81a2 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2228,6 +2228,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2198,6 +2198,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return range <= 0 ? 64.0 * 64.0 : range * range; // 64 is taken from default in ServerLevel#levelEvent } // Paper end - respect global sound events gamerule diff --git a/patches/server/0840-Use-correct-source-for-mushroom-block-spread-event.patch b/patches/server/0839-Use-correct-source-for-mushroom-block-spread-event.patch similarity index 100% rename from patches/server/0840-Use-correct-source-for-mushroom-block-spread-event.patch rename to patches/server/0839-Use-correct-source-for-mushroom-block-spread-event.patch diff --git a/patches/server/0841-Respect-randomizeData-on-more-entities-when-spawning.patch b/patches/server/0840-Respect-randomizeData-on-more-entities-when-spawning.patch similarity index 100% rename from patches/server/0841-Respect-randomizeData-on-more-entities-when-spawning.patch rename to patches/server/0840-Respect-randomizeData-on-more-entities-when-spawning.patch diff --git a/patches/server/0842-Use-correct-seed-on-api-world-load.patch b/patches/server/0841-Use-correct-seed-on-api-world-load.patch similarity index 87% rename from patches/server/0842-Use-correct-seed-on-api-world-load.patch rename to patches/server/0841-Use-correct-seed-on-api-world-load.patch index 099c091a6452..997631e23b84 100644 --- a/patches/server/0842-Use-correct-seed-on-api-world-load.patch +++ b/patches/server/0841-Use-correct-seed-on-api-world-load.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Use correct seed on api world load diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 0193505562d7bdc6d2ab91b637a916cdecdec911..3cf3b353cfb4337abdbb3b6842fd8fa128271948 100644 +index 46807d5d94a0f90b230dfaf4d37378a3bfa21414..da3819f49b105bd98ce94b5abdf1c7652ff625a4 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1389,7 +1389,7 @@ public final class CraftServer implements Server { +@@ -1388,7 +1388,7 @@ public final class CraftServer implements Server { net.minecraft.server.Main.forceUpgrade(worldSession, DataFixers.getDataFixer(), this.console.options.has("eraseCache"), () -> true, iregistrycustom_dimension, this.console.options.has("recreateRegionFiles")); } diff --git a/patches/server/0843-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch b/patches/server/0842-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch similarity index 100% rename from patches/server/0843-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch rename to patches/server/0842-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch diff --git a/patches/server/0844-Cache-map-ids-on-item-frames.patch b/patches/server/0843-Cache-map-ids-on-item-frames.patch similarity index 100% rename from patches/server/0844-Cache-map-ids-on-item-frames.patch rename to patches/server/0843-Cache-map-ids-on-item-frames.patch diff --git a/patches/server/0845-API-for-updating-recipes-on-clients.patch b/patches/server/0844-API-for-updating-recipes-on-clients.patch similarity index 88% rename from patches/server/0845-API-for-updating-recipes-on-clients.patch rename to patches/server/0844-API-for-updating-recipes-on-clients.patch index 0435961d1f54..28b0572357f8 100644 --- a/patches/server/0845-API-for-updating-recipes-on-clients.patch +++ b/patches/server/0844-API-for-updating-recipes-on-clients.patch @@ -5,10 +5,10 @@ Subject: [PATCH] API for updating recipes on clients diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index a9063533ea4b2b349d476127b99c822203d7dfcb..a1228d09b91dca3989a4be3120f9724a6e138040 100644 +index 74cbc6092d49f573f7fab1895c42a0360bb80bdf..db19a2483f37fb3554f86577e44162f6fe29592a 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1450,6 +1450,13 @@ public abstract class PlayerList { +@@ -1448,6 +1448,13 @@ public abstract class PlayerList { } public void reloadResources() { @@ -22,7 +22,7 @@ index a9063533ea4b2b349d476127b99c822203d7dfcb..a1228d09b91dca3989a4be3120f9724a // CraftBukkit start /*Iterator iterator = this.advancements.values().iterator(); -@@ -1465,7 +1472,13 @@ public abstract class PlayerList { +@@ -1463,7 +1470,13 @@ public abstract class PlayerList { } // CraftBukkit end @@ -37,10 +37,10 @@ index a9063533ea4b2b349d476127b99c822203d7dfcb..a1228d09b91dca3989a4be3120f9724a ClientboundUpdateRecipesPacket packetplayoutrecipeupdate = new ClientboundUpdateRecipesPacket(craftingmanager.getSynchronizedItemProperties(), craftingmanager.getSynchronizedStonecutterRecipes()); Iterator iterator1 = this.players.iterator(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 3cf3b353cfb4337abdbb3b6842fd8fa128271948..0433de3c2455cf18584d5ab651843f8d1d874036 100644 +index da3819f49b105bd98ce94b5abdf1c7652ff625a4..fa505c0714bb95b2ab08b4bbb9ea79ce98898f4b 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1179,6 +1179,18 @@ public final class CraftServer implements Server { +@@ -1178,6 +1178,18 @@ public final class CraftServer implements Server { ReloadCommand.reload(this.console); } @@ -59,7 +59,7 @@ index 3cf3b353cfb4337abdbb3b6842fd8fa128271948..0433de3c2455cf18584d5ab651843f8d private void loadIcon() { this.icon = new CraftIconCache(null); try { -@@ -1558,6 +1570,13 @@ public final class CraftServer implements Server { +@@ -1557,6 +1569,13 @@ public final class CraftServer implements Server { @Override public boolean addRecipe(Recipe recipe) { @@ -73,7 +73,7 @@ index 3cf3b353cfb4337abdbb3b6842fd8fa128271948..0433de3c2455cf18584d5ab651843f8d CraftRecipe toAdd; if (recipe instanceof CraftRecipe) { toAdd = (CraftRecipe) recipe; -@@ -1589,6 +1608,11 @@ public final class CraftServer implements Server { +@@ -1588,6 +1607,11 @@ public final class CraftServer implements Server { } } toAdd.addToCraftingManager(); @@ -85,7 +85,7 @@ index 3cf3b353cfb4337abdbb3b6842fd8fa128271948..0433de3c2455cf18584d5ab651843f8d return true; } -@@ -1769,9 +1793,23 @@ public final class CraftServer implements Server { +@@ -1768,9 +1792,23 @@ public final class CraftServer implements Server { @Override public boolean removeRecipe(NamespacedKey recipeKey) { diff --git a/patches/server/0846-Fix-custom-statistic-criteria-creation.patch b/patches/server/0845-Fix-custom-statistic-criteria-creation.patch similarity index 59% rename from patches/server/0846-Fix-custom-statistic-criteria-creation.patch rename to patches/server/0845-Fix-custom-statistic-criteria-creation.patch index 420f7179e993..c57ac9625590 100644 --- a/patches/server/0846-Fix-custom-statistic-criteria-creation.patch +++ b/patches/server/0845-Fix-custom-statistic-criteria-creation.patch @@ -5,21 +5,19 @@ Subject: [PATCH] Fix custom statistic criteria creation diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 9e0af05e066132b66fafff84ff0a0957c1a44f9f..766ef49d72eef0ff80247a807db5379f7fc60302 100644 +index 9f4124485dac3d029ec8247b64098042aa1a48d2..a74784ddf63d316f253381ed803822a149e92bc7 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -599,6 +599,14 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -600,6 +600,12 @@ public final class CraftMagicNumbers implements UnsafeValues { + net.minecraft.core.Holder biomeBase = cra.getHandle().registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BIOME).getOrThrow(net.minecraft.resources.ResourceKey.create(net.minecraft.core.registries.Registries.BIOME, org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(biomeKey))); + cra.setBiome(x, y, z, biomeBase); } - // Paper end - namespaced key biome methods - -+ // Paper start - fix custom stats criteria creation ++ + @Override + public String getStatisticCriteriaKey(org.bukkit.Statistic statistic) { + if (statistic.getType() != org.bukkit.Statistic.Type.UNTYPED) return "minecraft.custom:minecraft." + statistic.getKey().getKey(); + return org.bukkit.craftbukkit.CraftStatistic.getNMSStatistic(statistic).getName(); + } -+ // Paper end - fix custom stats criteria creation -+ - @Override - public String get(Class aClass, String s) { - if (aClass == Enchantment.class) { + // Paper end + + /** diff --git a/patches/server/0847-Bandaid-fix-for-Effect.patch b/patches/server/0846-Bandaid-fix-for-Effect.patch similarity index 100% rename from patches/server/0847-Bandaid-fix-for-Effect.patch rename to patches/server/0846-Bandaid-fix-for-Effect.patch diff --git a/patches/server/0848-SculkCatalyst-bloom-API.patch b/patches/server/0847-SculkCatalyst-bloom-API.patch similarity index 100% rename from patches/server/0848-SculkCatalyst-bloom-API.patch rename to patches/server/0847-SculkCatalyst-bloom-API.patch diff --git a/patches/server/0849-API-for-an-entity-s-scoreboard-name.patch b/patches/server/0848-API-for-an-entity-s-scoreboard-name.patch similarity index 100% rename from patches/server/0849-API-for-an-entity-s-scoreboard-name.patch rename to patches/server/0848-API-for-an-entity-s-scoreboard-name.patch diff --git a/patches/server/0850-Deprecate-and-replace-methods-with-old-StructureType.patch b/patches/server/0849-Deprecate-and-replace-methods-with-old-StructureType.patch similarity index 92% rename from patches/server/0850-Deprecate-and-replace-methods-with-old-StructureType.patch rename to patches/server/0849-Deprecate-and-replace-methods-with-old-StructureType.patch index 82cc3b437362..80817c11759d 100644 --- a/patches/server/0850-Deprecate-and-replace-methods-with-old-StructureType.patch +++ b/patches/server/0849-Deprecate-and-replace-methods-with-old-StructureType.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Deprecate and replace methods with old StructureType diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 0433de3c2455cf18584d5ab651843f8d1d874036..83c3de4ae733199f64fe0f967f9f816545d20f1c 100644 +index fa505c0714bb95b2ab08b4bbb9ea79ce98898f4b..a1f2c8fd0348a6a5dad521430f473867bdadd1a5 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2008,6 +2008,11 @@ public final class CraftServer implements Server { +@@ -2007,6 +2007,11 @@ public final class CraftServer implements Server { ServerLevel worldServer = ((CraftWorld) world).getHandle(); Location structureLocation = world.locateNearestStructure(location, structureType, radius, findUnexplored); @@ -20,7 +20,7 @@ index 0433de3c2455cf18584d5ab651843f8d1d874036..83c3de4ae733199f64fe0f967f9f8165 BlockPos structurePosition = CraftLocation.toBlockPosition(structureLocation); // Create map with trackPlayer = true, unlimitedTracking = true -@@ -2018,6 +2023,31 @@ public final class CraftServer implements Server { +@@ -2017,6 +2022,31 @@ public final class CraftServer implements Server { return CraftItemStack.asBukkitCopy(stack); } diff --git a/patches/server/0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch b/patches/server/0850-Don-t-tab-complete-namespaced-commands-if-send-names.patch similarity index 95% rename from patches/server/0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch rename to patches/server/0850-Don-t-tab-complete-namespaced-commands-if-send-names.patch index 58454d72670c..8834a03dcbe1 100644 --- a/patches/server/0851-Don-t-tab-complete-namespaced-commands-if-send-names.patch +++ b/patches/server/0850-Don-t-tab-complete-namespaced-commands-if-send-names.patch @@ -11,7 +11,7 @@ This patch prevents server from sending namespaced commands when player requests tab-complete only commands. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 368547270a3e6cdbda812fcf0ed2519d71383b81..293c42dd5e870986a2797840756bd7c4d6a34a5d 100644 +index 134d9fbdb757094a4624325c0ad8f32efadd61b6..688d6e51bc8b844ba7648cf1aed1bdd9629c1675 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -832,6 +832,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0852-Properly-handle-BlockBreakEvent-isDropItems.patch b/patches/server/0851-Properly-handle-BlockBreakEvent-isDropItems.patch similarity index 98% rename from patches/server/0852-Properly-handle-BlockBreakEvent-isDropItems.patch rename to patches/server/0851-Properly-handle-BlockBreakEvent-isDropItems.patch index 6c61a65a1c40..7bf30bb1122d 100644 --- a/patches/server/0852-Properly-handle-BlockBreakEvent-isDropItems.patch +++ b/patches/server/0851-Properly-handle-BlockBreakEvent-isDropItems.patch @@ -39,10 +39,10 @@ index d5ed53c37bba79f84b60d616887cd5176e124f10..6c0ea0bde1c36edda92807e317ed37f8 if (!EnchantmentHelper.hasTag(tool, EnchantmentTags.PREVENTS_BEE_SPAWNS_WHEN_MINING)) { tileentitybeehive.emptyAllLivingFromHive(player, state, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY); diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index 4d140bd83ca0e1554afad80ec4fc6186188a79d8..6fb3f551f432d7e668c606fb7bd3514408e0478a 100644 +index 9d8c4ecd89b05a0e5d4ebb5e686eba5d899765f2..4ff32e3fb1a1979827ef063cda196a43995440fe 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -405,10 +405,18 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -396,10 +396,18 @@ public class Block extends BlockBehaviour implements ItemLike { return this.defaultBlockState(); } diff --git a/patches/server/0853-Fire-entity-death-event-for-ender-dragon.patch b/patches/server/0852-Fire-entity-death-event-for-ender-dragon.patch similarity index 100% rename from patches/server/0853-Fire-entity-death-event-for-ender-dragon.patch rename to patches/server/0852-Fire-entity-death-event-for-ender-dragon.patch diff --git a/patches/server/0854-Configurable-entity-tracking-range-by-Y-coordinate.patch b/patches/server/0853-Configurable-entity-tracking-range-by-Y-coordinate.patch similarity index 92% rename from patches/server/0854-Configurable-entity-tracking-range-by-Y-coordinate.patch rename to patches/server/0853-Configurable-entity-tracking-range-by-Y-coordinate.patch index 75dd71166a36..a8f7a157ae07 100644 --- a/patches/server/0854-Configurable-entity-tracking-range-by-Y-coordinate.patch +++ b/patches/server/0853-Configurable-entity-tracking-range-by-Y-coordinate.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Configurable entity tracking range by Y coordinate Options to configure entity tracking by Y coordinate, also for each entity category. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 7810df9c5045a78c2731ee416366da4f973e5d29..502d73830ed87e06529f194090a4ffb895b2623c 100644 +index 53e180e230d5a1652f3e19193243c37095d6b39e..5da3eee41ba0cbec5932cf9a7dac53777a2463fb 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1583,7 +1583,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1577,7 +1577,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider double d0 = (double) Math.min(this.getEffectiveRange(), i * 16); double d1 = vec3d.x * vec3d.x + vec3d.z * vec3d.z; double d2 = d0 * d0; diff --git a/patches/server/0855-Add-Listing-API-for-Player.patch b/patches/server/0854-Add-Listing-API-for-Player.patch similarity index 98% rename from patches/server/0855-Add-Listing-API-for-Player.patch rename to patches/server/0854-Add-Listing-API-for-Player.patch index 05d3d3e57172..a4116283404c 100644 --- a/patches/server/0855-Add-Listing-API-for-Player.patch +++ b/patches/server/0854-Add-Listing-API-for-Player.patch @@ -85,10 +85,10 @@ index 29b465fc1dc50e0e84ddb889c5303e80fe662874..4d67d98257b2cb9045d03c999cfd4ba2 static class EntryBuilder { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index a1228d09b91dca3989a4be3120f9724a6e138040..fa951c6e33d583f9c2ca103fbaaa035e40c163f9 100644 +index db19a2483f37fb3554f86577e44162f6fe29592a..409010fae4b175ba7dcbe0f38676022ed9b77b1d 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -363,14 +363,22 @@ public abstract class PlayerList { +@@ -362,14 +362,22 @@ public abstract class PlayerList { // CraftBukkit end // CraftBukkit start - sendAll above replaced with this loop @@ -112,7 +112,7 @@ index a1228d09b91dca3989a4be3120f9724a6e138040..fa951c6e33d583f9c2ca103fbaaa035e } if (entityplayer1 == player || !bukkitPlayer.canSee(entityplayer1.getBukkitEntity())) { // Paper - Use single player info update packet on join; Don't include joining player -@@ -381,7 +389,7 @@ public abstract class PlayerList { +@@ -380,7 +388,7 @@ public abstract class PlayerList { } // Paper start - Use single player info update packet on join if (!onlinePlayers.isEmpty()) { diff --git a/patches/server/0856-Configurable-Region-Compression-Format.patch b/patches/server/0855-Configurable-Region-Compression-Format.patch similarity index 100% rename from patches/server/0856-Configurable-Region-Compression-Format.patch rename to patches/server/0855-Configurable-Region-Compression-Format.patch diff --git a/patches/server/0857-Add-BlockFace-to-BlockDamageEvent.patch b/patches/server/0856-Add-BlockFace-to-BlockDamageEvent.patch similarity index 100% rename from patches/server/0857-Add-BlockFace-to-BlockDamageEvent.patch rename to patches/server/0856-Add-BlockFace-to-BlockDamageEvent.patch diff --git a/patches/server/0858-Fix-NPE-on-Boat-getStatus.patch b/patches/server/0857-Fix-NPE-on-Boat-getStatus.patch similarity index 100% rename from patches/server/0858-Fix-NPE-on-Boat-getStatus.patch rename to patches/server/0857-Fix-NPE-on-Boat-getStatus.patch diff --git a/patches/server/0859-Expand-Pose-API.patch b/patches/server/0858-Expand-Pose-API.patch similarity index 100% rename from patches/server/0859-Expand-Pose-API.patch rename to patches/server/0858-Expand-Pose-API.patch diff --git a/patches/server/0860-More-DragonBattle-API.patch b/patches/server/0859-More-DragonBattle-API.patch similarity index 100% rename from patches/server/0860-More-DragonBattle-API.patch rename to patches/server/0859-More-DragonBattle-API.patch diff --git a/patches/server/0861-Add-PlayerPickItemEvent.patch b/patches/server/0860-Add-PlayerPickItemEvent.patch similarity index 96% rename from patches/server/0861-Add-PlayerPickItemEvent.patch rename to patches/server/0860-Add-PlayerPickItemEvent.patch index 8a28695a2b67..0290c1d95099 100644 --- a/patches/server/0861-Add-PlayerPickItemEvent.patch +++ b/patches/server/0860-Add-PlayerPickItemEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerPickItemEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 293c42dd5e870986a2797840756bd7c4d6a34a5d..c50c3d11700aadd4c0e7114b4b6d5c5d15a33ac4 100644 +index 688d6e51bc8b844ba7648cf1aed1bdd9629c1675..b840f7aac9c830b8aa0aa133bf43f87dfc598b2c 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -947,7 +947,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl diff --git a/patches/server/0862-Allow-trident-custom-damage.patch b/patches/server/0861-Allow-trident-custom-damage.patch similarity index 100% rename from patches/server/0862-Allow-trident-custom-damage.patch rename to patches/server/0861-Allow-trident-custom-damage.patch diff --git a/patches/server/0863-Expose-hand-in-BlockCanBuildEvent.patch b/patches/server/0862-Expose-hand-in-BlockCanBuildEvent.patch similarity index 100% rename from patches/server/0863-Expose-hand-in-BlockCanBuildEvent.patch rename to patches/server/0862-Expose-hand-in-BlockCanBuildEvent.patch diff --git a/patches/server/0864-Optimize-nearest-structure-border-iteration.patch b/patches/server/0863-Optimize-nearest-structure-border-iteration.patch similarity index 100% rename from patches/server/0864-Optimize-nearest-structure-border-iteration.patch rename to patches/server/0863-Optimize-nearest-structure-border-iteration.patch diff --git a/patches/server/0865-Implement-OfflinePlayer-isConnected.patch b/patches/server/0864-Implement-OfflinePlayer-isConnected.patch similarity index 100% rename from patches/server/0865-Implement-OfflinePlayer-isConnected.patch rename to patches/server/0864-Implement-OfflinePlayer-isConnected.patch diff --git a/patches/server/0866-Fix-slot-desync.patch b/patches/server/0865-Fix-slot-desync.patch similarity index 98% rename from patches/server/0866-Fix-slot-desync.patch rename to patches/server/0865-Fix-slot-desync.patch index deb1575edeb0..7c1808398cb9 100644 --- a/patches/server/0866-Fix-slot-desync.patch +++ b/patches/server/0865-Fix-slot-desync.patch @@ -22,10 +22,10 @@ index f05a9fd321a4af28e9771bbf39d73f80dd4160c9..90aa8e401e1d092a31ff21699409b836 this.containerMenu.findSlot(this.getInventory(), this.getInventory().selected).ifPresent(s -> { this.containerSynchronizer.sendSlotChange(this.containerMenu, s, this.getMainHandItem()); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index c50c3d11700aadd4c0e7114b4b6d5c5d15a33ac4..af7696900171ea6b7941251046bfc10c1f4eb469 100644 +index b840f7aac9c830b8aa0aa133bf43f87dfc598b2c..0cb0d2f863efb86bb589b30bae61ac57bda40fab 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2749,10 +2749,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2746,10 +2746,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Refresh the current entity metadata entity.refreshEntityData(ServerGamePacketListenerImpl.this.player); // SPIGOT-7136 - Allays diff --git a/patches/server/0867-Add-titleOverride-to-InventoryOpenEvent.patch b/patches/server/0866-Add-titleOverride-to-InventoryOpenEvent.patch similarity index 100% rename from patches/server/0867-Add-titleOverride-to-InventoryOpenEvent.patch rename to patches/server/0866-Add-titleOverride-to-InventoryOpenEvent.patch diff --git a/patches/server/0868-Configure-sniffer-egg-hatch-time.patch b/patches/server/0867-Configure-sniffer-egg-hatch-time.patch similarity index 100% rename from patches/server/0868-Configure-sniffer-egg-hatch-time.patch rename to patches/server/0867-Configure-sniffer-egg-hatch-time.patch diff --git a/patches/server/0869-Do-crystal-portal-proximity-check-before-entity-look.patch b/patches/server/0868-Do-crystal-portal-proximity-check-before-entity-look.patch similarity index 100% rename from patches/server/0869-Do-crystal-portal-proximity-check-before-entity-look.patch rename to patches/server/0868-Do-crystal-portal-proximity-check-before-entity-look.patch diff --git a/patches/server/0870-Skip-POI-finding-if-stuck-in-vehicle.patch b/patches/server/0869-Skip-POI-finding-if-stuck-in-vehicle.patch similarity index 100% rename from patches/server/0870-Skip-POI-finding-if-stuck-in-vehicle.patch rename to patches/server/0869-Skip-POI-finding-if-stuck-in-vehicle.patch diff --git a/patches/server/0871-Add-slot-sanity-checks-in-container-clicks.patch b/patches/server/0870-Add-slot-sanity-checks-in-container-clicks.patch similarity index 94% rename from patches/server/0871-Add-slot-sanity-checks-in-container-clicks.patch rename to patches/server/0870-Add-slot-sanity-checks-in-container-clicks.patch index 08f85bdb3bff..0925155fcfc9 100644 --- a/patches/server/0871-Add-slot-sanity-checks-in-container-clicks.patch +++ b/patches/server/0870-Add-slot-sanity-checks-in-container-clicks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add slot sanity checks in container clicks diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index af7696900171ea6b7941251046bfc10c1f4eb469..836e6b705b201253f2b81d1ca0228b8a0266a1dd 100644 +index 0cb0d2f863efb86bb589b30bae61ac57bda40fab..f92624ccd43f448abdee92c975d613cbcb3457c6 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3011,6 +3011,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3008,6 +3008,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl break; case SWAP: if ((packet.getButtonNum() >= 0 && packet.getButtonNum() < 9) || packet.getButtonNum() == 40) { diff --git a/patches/server/0872-Call-BlockRedstoneEvents-for-lecterns.patch b/patches/server/0871-Call-BlockRedstoneEvents-for-lecterns.patch similarity index 100% rename from patches/server/0872-Call-BlockRedstoneEvents-for-lecterns.patch rename to patches/server/0871-Call-BlockRedstoneEvents-for-lecterns.patch diff --git a/patches/server/0873-Allow-proper-checking-of-empty-item-stacks.patch b/patches/server/0872-Allow-proper-checking-of-empty-item-stacks.patch similarity index 100% rename from patches/server/0873-Allow-proper-checking-of-empty-item-stacks.patch rename to patches/server/0872-Allow-proper-checking-of-empty-item-stacks.patch diff --git a/patches/server/0874-Fix-silent-equipment-change-for-mobs.patch b/patches/server/0873-Fix-silent-equipment-change-for-mobs.patch similarity index 100% rename from patches/server/0874-Fix-silent-equipment-change-for-mobs.patch rename to patches/server/0873-Fix-silent-equipment-change-for-mobs.patch diff --git a/patches/server/0875-Fix-spigot-s-Forced-Stats.patch b/patches/server/0874-Fix-spigot-s-Forced-Stats.patch similarity index 100% rename from patches/server/0875-Fix-spigot-s-Forced-Stats.patch rename to patches/server/0874-Fix-spigot-s-Forced-Stats.patch diff --git a/patches/server/0876-Add-missing-InventoryHolders-to-inventories.patch b/patches/server/0875-Add-missing-InventoryHolders-to-inventories.patch similarity index 100% rename from patches/server/0876-Add-missing-InventoryHolders-to-inventories.patch rename to patches/server/0875-Add-missing-InventoryHolders-to-inventories.patch diff --git a/patches/server/0877-Do-not-read-tile-entities-in-chunks-that-are-positio.patch b/patches/server/0876-Do-not-read-tile-entities-in-chunks-that-are-positio.patch similarity index 100% rename from patches/server/0877-Do-not-read-tile-entities-in-chunks-that-are-positio.patch rename to patches/server/0876-Do-not-read-tile-entities-in-chunks-that-are-positio.patch diff --git a/patches/server/0878-Add-missing-logs-for-log-ips-config-option.patch b/patches/server/0877-Add-missing-logs-for-log-ips-config-option.patch similarity index 100% rename from patches/server/0878-Add-missing-logs-for-log-ips-config-option.patch rename to patches/server/0877-Add-missing-logs-for-log-ips-config-option.patch diff --git a/patches/server/0879-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch b/patches/server/0878-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch similarity index 100% rename from patches/server/0879-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch rename to patches/server/0878-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch diff --git a/patches/server/0880-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch b/patches/server/0879-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch similarity index 100% rename from patches/server/0880-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch rename to patches/server/0879-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch diff --git a/patches/server/0881-Fix-team-sidebar-objectives-not-being-cleared.patch b/patches/server/0880-Fix-team-sidebar-objectives-not-being-cleared.patch similarity index 94% rename from patches/server/0881-Fix-team-sidebar-objectives-not-being-cleared.patch rename to patches/server/0880-Fix-team-sidebar-objectives-not-being-cleared.patch index 88a39d0b2021..cebe7aefc27f 100644 --- a/patches/server/0881-Fix-team-sidebar-objectives-not-being-cleared.patch +++ b/patches/server/0880-Fix-team-sidebar-objectives-not-being-cleared.patch @@ -9,7 +9,7 @@ scoreboards. If a player's scoreboard has a displayed objective for the still had a 'gold' team, it would still be displayed diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java -index cad42a0f3c016bf65181e50d139ae4e2fb9158a5..b3e1adeb932da9b3bed16acd94e2f16da48a7c72 100644 +index c7ca6210d6ae37fe95068c9baa5fb654f95307e0..f3184be3853dfc4df4ae4b8af764dfef07628ef4 100644 --- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java +++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java @@ -87,8 +87,8 @@ public final class CraftScoreboardManager implements ScoreboardManager { diff --git a/patches/server/0882-Fix-missing-map-initialize-event-call.patch b/patches/server/0881-Fix-missing-map-initialize-event-call.patch similarity index 93% rename from patches/server/0882-Fix-missing-map-initialize-event-call.patch rename to patches/server/0881-Fix-missing-map-initialize-event-call.patch index f2047845c647..0eb662ab8269 100644 --- a/patches/server/0882-Fix-missing-map-initialize-event-call.patch +++ b/patches/server/0881-Fix-missing-map-initialize-event-call.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Fix missing map initialize event call public net.minecraft.world.level.storage.DimensionDataStorage readSavedData(Ljava/util/function/Function;Lnet/minecraft/util/datafix/DataFixTypes;Ljava/lang/String;)Lnet/minecraft/world/level/saveddata/SavedData; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 9270584d74edf5c1af473b1a13f7edca74cc1ec7..1bacbb0d0bd5198d0f946a959b2335d6fba0ca88 100644 +index 0db41d36d5daf015c750fb0246ab3e5da1cd81a2..7cecbac43f1cd2d9516034ea9d2633c0c76e61f4 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1726,13 +1726,29 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1696,13 +1696,29 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Nullable @Override public MapItemSavedData getMapData(MapId id) { diff --git a/patches/server/0883-Update-entity-data-when-attaching-firework-to-entity.patch b/patches/server/0882-Update-entity-data-when-attaching-firework-to-entity.patch similarity index 100% rename from patches/server/0883-Update-entity-data-when-attaching-firework-to-entity.patch rename to patches/server/0882-Update-entity-data-when-attaching-firework-to-entity.patch diff --git a/patches/server/0884-Fix-UnsafeValues-loadAdvancement.patch b/patches/server/0883-Fix-UnsafeValues-loadAdvancement.patch similarity index 94% rename from patches/server/0884-Fix-UnsafeValues-loadAdvancement.patch rename to patches/server/0883-Fix-UnsafeValues-loadAdvancement.patch index fa08d471abd2..dc4c28926e54 100644 --- a/patches/server/0884-Fix-UnsafeValues-loadAdvancement.patch +++ b/patches/server/0883-Fix-UnsafeValues-loadAdvancement.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix UnsafeValues#loadAdvancement diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 766ef49d72eef0ff80247a807db5379f7fc60302..3900f95f3ea41b010b8ea79c043fe322fa233461 100644 +index a74784ddf63d316f253381ed803822a149e92bc7..1835f8cfda0222fadd9db31abfb7e85899051853 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -308,9 +308,30 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -302,9 +302,30 @@ public final class CraftMagicNumbers implements UnsafeValues { ResourceLocation minecraftkey = CraftNamespacedKey.toMinecraft(key); JsonElement jsonelement = JsonParser.parseString(advancement); diff --git a/patches/server/0885-Add-player-idle-duration-API.patch b/patches/server/0884-Add-player-idle-duration-API.patch similarity index 100% rename from patches/server/0885-Add-player-idle-duration-API.patch rename to patches/server/0884-Add-player-idle-duration-API.patch diff --git a/patches/server/0886-Don-t-check-if-we-can-see-non-visible-entities.patch b/patches/server/0885-Don-t-check-if-we-can-see-non-visible-entities.patch similarity index 85% rename from patches/server/0886-Don-t-check-if-we-can-see-non-visible-entities.patch rename to patches/server/0885-Don-t-check-if-we-can-see-non-visible-entities.patch index 5078fe7f0179..00d8ff96c11e 100644 --- a/patches/server/0886-Don-t-check-if-we-can-see-non-visible-entities.patch +++ b/patches/server/0885-Don-t-check-if-we-can-see-non-visible-entities.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Don't check if we can see non-visible entities diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 502d73830ed87e06529f194090a4ffb895b2623c..95c70de2c9f0e26742c0d66ad6c3bcc310a923f6 100644 +index 5da3eee41ba0cbec5932cf9a7dac53777a2463fb..bf6d5f9e23387da845d6fe246c9013ec4d13cfb1 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1596,7 +1596,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1590,7 +1590,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper end - Configurable entity tracking range by Y // CraftBukkit start - respect vanish API diff --git a/patches/server/0887-Fix-NPE-in-SculkBloomEvent-world-access.patch b/patches/server/0886-Fix-NPE-in-SculkBloomEvent-world-access.patch similarity index 100% rename from patches/server/0887-Fix-NPE-in-SculkBloomEvent-world-access.patch rename to patches/server/0886-Fix-NPE-in-SculkBloomEvent-world-access.patch diff --git a/patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch b/patches/server/0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch similarity index 100% rename from patches/server/0888-Allow-null-itemstack-for-Player-sendEquipmentChange.patch rename to patches/server/0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch diff --git a/patches/server/0889-Optimize-VarInts.patch b/patches/server/0888-Optimize-VarInts.patch similarity index 100% rename from patches/server/0889-Optimize-VarInts.patch rename to patches/server/0888-Optimize-VarInts.patch diff --git a/patches/server/0890-Add-API-to-get-the-collision-shape-of-a-block-before.patch b/patches/server/0889-Add-API-to-get-the-collision-shape-of-a-block-before.patch similarity index 100% rename from patches/server/0890-Add-API-to-get-the-collision-shape-of-a-block-before.patch rename to patches/server/0889-Add-API-to-get-the-collision-shape-of-a-block-before.patch diff --git a/patches/server/0891-Add-predicate-for-blocks-when-raytracing.patch b/patches/server/0890-Add-predicate-for-blocks-when-raytracing.patch similarity index 100% rename from patches/server/0891-Add-predicate-for-blocks-when-raytracing.patch rename to patches/server/0890-Add-predicate-for-blocks-when-raytracing.patch diff --git a/patches/server/0892-Broadcast-take-item-packets-with-collector-as-source.patch b/patches/server/0891-Broadcast-take-item-packets-with-collector-as-source.patch similarity index 88% rename from patches/server/0892-Broadcast-take-item-packets-with-collector-as-source.patch rename to patches/server/0891-Broadcast-take-item-packets-with-collector-as-source.patch index 03d6650dc143..1fb19203b6a8 100644 --- a/patches/server/0892-Broadcast-take-item-packets-with-collector-as-source.patch +++ b/patches/server/0891-Broadcast-take-item-packets-with-collector-as-source.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Broadcast take item packets with collector as source This fixes players (which can't view the collector) seeing item pickups with themselves as the target. diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index a4d24269c1365f32f232116f1530ac75b096c6ab..30424789ba1c8d25f830145501b4a7399b91f2d1 100644 +index 24245cfb160dc990b3661388c2f95b9383f98428..09bd6ba5907d42bed08872f18d40d8c743d392ff 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3893,7 +3893,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3891,7 +3891,7 @@ public abstract class LivingEntity extends Entity implements Attackable { public void take(Entity item, int count) { if (!item.isRemoved() && !this.level().isClientSide && (item instanceof ItemEntity || item instanceof AbstractArrow || item instanceof ExperienceOrb)) { diff --git a/patches/server/0893-Expand-LingeringPotion-API.patch b/patches/server/0892-Expand-LingeringPotion-API.patch similarity index 100% rename from patches/server/0893-Expand-LingeringPotion-API.patch rename to patches/server/0892-Expand-LingeringPotion-API.patch diff --git a/patches/server/0894-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch b/patches/server/0893-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch similarity index 100% rename from patches/server/0894-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch rename to patches/server/0893-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch diff --git a/patches/server/0895-Add-hand-to-fish-event-for-all-player-interactions.patch b/patches/server/0894-Add-hand-to-fish-event-for-all-player-interactions.patch similarity index 100% rename from patches/server/0895-Add-hand-to-fish-event-for-all-player-interactions.patch rename to patches/server/0894-Add-hand-to-fish-event-for-all-player-interactions.patch diff --git a/patches/server/0896-Fix-several-issues-with-EntityBreedEvent.patch b/patches/server/0895-Fix-several-issues-with-EntityBreedEvent.patch similarity index 100% rename from patches/server/0896-Fix-several-issues-with-EntityBreedEvent.patch rename to patches/server/0895-Fix-several-issues-with-EntityBreedEvent.patch diff --git a/patches/server/0897-Add-UUID-attribute-modifier-API.patch b/patches/server/0896-Add-UUID-attribute-modifier-API.patch similarity index 100% rename from patches/server/0897-Add-UUID-attribute-modifier-API.patch rename to patches/server/0896-Add-UUID-attribute-modifier-API.patch diff --git a/patches/server/0898-Fix-missing-event-call-for-entity-teleport-API.patch b/patches/server/0897-Fix-missing-event-call-for-entity-teleport-API.patch similarity index 100% rename from patches/server/0898-Fix-missing-event-call-for-entity-teleport-API.patch rename to patches/server/0897-Fix-missing-event-call-for-entity-teleport-API.patch diff --git a/patches/server/0899-Lazily-create-LootContext-for-criterions.patch b/patches/server/0898-Lazily-create-LootContext-for-criterions.patch similarity index 100% rename from patches/server/0899-Lazily-create-LootContext-for-criterions.patch rename to patches/server/0898-Lazily-create-LootContext-for-criterions.patch diff --git a/patches/server/0900-Don-t-fire-sync-events-during-worldgen.patch b/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch similarity index 95% rename from patches/server/0900-Don-t-fire-sync-events-during-worldgen.patch rename to patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch index 389d1d5fde69..f530a9f4e784 100644 --- a/patches/server/0900-Don-t-fire-sync-events-during-worldgen.patch +++ b/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch @@ -19,10 +19,10 @@ where generation happened directly to a ServerLevel and the entity still has the flag set. diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 1bacbb0d0bd5198d0f946a959b2335d6fba0ca88..a628da8a0ed7ae2c7b46df3881bd75dc5b4fd607 100644 +index 7cecbac43f1cd2d9516034ea9d2633c0c76e61f4..7a985c30a973efacf3e8b70e7163c550d86b0870 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1219,6 +1219,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1189,6 +1189,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // CraftBukkit start private boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) { org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot @@ -48,10 +48,10 @@ index c0539c8826a60cbe25855319cc174fb1520798c0..02b9d280486a23d8eef650566dfaa10a this.entityData.set(Entity.DATA_POSE, pose); } diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index ca9e63942f3cb8986456410b2a77aafc6541aad2..ccee69813597f45d382268bd1792a49722afebe9 100644 +index 64dc0bd1900575e40ac72a98c6df371223bd244c..c2693d530be00af16b2aa4ca4afd1d136db68183 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -658,9 +658,15 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -649,9 +649,15 @@ public class EntityType implements FeatureElement, EntityTypeT } public static Optional create(CompoundTag nbt, Level world, EntitySpawnReason reason) { @@ -68,10 +68,10 @@ index ca9e63942f3cb8986456410b2a77aafc6541aad2..ccee69813597f45d382268bd1792a497 }, () -> { EntityType.LOGGER.warn("Skipping Entity with id {}", nbt.getString("id")); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 30424789ba1c8d25f830145501b4a7399b91f2d1..9bc6ed9fd8e5154d39fe12ffed1ecd5ec8e70df8 100644 +index 09bd6ba5907d42bed08872f18d40d8c743d392ff..251abe382f951c3ddac8112a0ffe1dc906b88e4c 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1161,6 +1161,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1159,6 +1159,11 @@ public abstract class LivingEntity extends Entity implements Attackable { } public boolean addEffect(MobEffectInstance mobeffect, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause) { @@ -83,7 +83,7 @@ index 30424789ba1c8d25f830145501b4a7399b91f2d1..9bc6ed9fd8e5154d39fe12ffed1ecd5e // org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot // Paper - move to API if (this.isTickingEffects) { this.effectsToProcess.add(new ProcessableEffect(mobeffect, cause)); -@@ -1180,10 +1185,13 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1178,10 +1183,13 @@ public abstract class LivingEntity extends Entity implements Attackable { override = new MobEffectInstance(mobeffect1).update(mobeffect); } @@ -97,7 +97,7 @@ index 30424789ba1c8d25f830145501b4a7399b91f2d1..9bc6ed9fd8e5154d39fe12ffed1ecd5e // CraftBukkit end if (mobeffect1 == null) { -@@ -1192,7 +1200,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1190,7 +1198,7 @@ public abstract class LivingEntity extends Entity implements Attackable { flag = true; mobeffect.onEffectAdded(this); // CraftBukkit start diff --git a/patches/server/0901-Add-Structure-check-API.patch b/patches/server/0900-Add-Structure-check-API.patch similarity index 100% rename from patches/server/0901-Add-Structure-check-API.patch rename to patches/server/0900-Add-Structure-check-API.patch diff --git a/patches/server/0902-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch b/patches/server/0901-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch similarity index 100% rename from patches/server/0902-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch rename to patches/server/0901-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch diff --git a/patches/server/0903-Restore-vanilla-entity-drops-behavior.patch b/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch similarity index 99% rename from patches/server/0903-Restore-vanilla-entity-drops-behavior.patch rename to patches/server/0902-Restore-vanilla-entity-drops-behavior.patch index bbad1a93c726..c19f1327f4a0 100644 --- a/patches/server/0903-Restore-vanilla-entity-drops-behavior.patch +++ b/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch @@ -89,10 +89,10 @@ index 02b9d280486a23d8eef650566dfaa10ac0b96c9c..cdc5ea3dd9559c076049c86a9fdb4e8b return this.spawnAtLocation(world, entityitem); } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 9bc6ed9fd8e5154d39fe12ffed1ecd5ec8e70df8..4b9108e48d052919bca000ddb54f9bf4589c33e6 100644 +index 251abe382f951c3ddac8112a0ffe1dc906b88e4c..adde7352cdbcb8684f43d6bf5978b6943e9f165b 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -291,7 +291,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -289,7 +289,7 @@ public abstract class LivingEntity extends Entity implements Attackable { protected float appliedScale; // CraftBukkit start public int expToDrop; diff --git a/patches/server/0904-Dont-resend-blocks-on-interactions.patch b/patches/server/0903-Dont-resend-blocks-on-interactions.patch similarity index 100% rename from patches/server/0904-Dont-resend-blocks-on-interactions.patch rename to patches/server/0903-Dont-resend-blocks-on-interactions.patch diff --git a/patches/server/0905-add-more-scoreboard-API.patch b/patches/server/0904-add-more-scoreboard-API.patch similarity index 100% rename from patches/server/0905-add-more-scoreboard-API.patch rename to patches/server/0904-add-more-scoreboard-API.patch diff --git a/patches/server/0906-Improve-Registry.patch b/patches/server/0905-Improve-Registry.patch similarity index 100% rename from patches/server/0906-Improve-Registry.patch rename to patches/server/0905-Improve-Registry.patch diff --git a/patches/server/0907-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch b/patches/server/0906-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch similarity index 96% rename from patches/server/0907-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch rename to patches/server/0906-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch index 394a12efc224..dc1f06ed5606 100644 --- a/patches/server/0907-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch +++ b/patches/server/0906-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch @@ -26,10 +26,10 @@ index c6dcc37ac5fcf50bcb246f533b99983dfc5c19c2..c13b6f14c3061710c2b27034db240cc9 d3 = to.getX(); d4 = to.getY(); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 4b9108e48d052919bca000ddb54f9bf4589c33e6..1c4ec3857c5c3ecf58f842292c280a4a1f00a04c 100644 +index adde7352cdbcb8684f43d6bf5978b6943e9f165b..9d3d6f012cfca60884019ed9710804aa37b11fbf 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -4365,7 +4365,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4363,7 +4363,7 @@ public abstract class LivingEntity extends Entity implements Attackable { if (!(this instanceof ServerPlayer)) { EntityTeleportEvent teleport = new EntityTeleportEvent(this.getBukkitEntity(), new Location(this.level().getWorld(), d3, d4, d5), new Location(this.level().getWorld(), d0, d6, d2)); this.level().getCraftServer().getPluginManager().callEvent(teleport); diff --git a/patches/server/0908-Add-experience-points-API.patch b/patches/server/0907-Add-experience-points-API.patch similarity index 100% rename from patches/server/0908-Add-experience-points-API.patch rename to patches/server/0907-Add-experience-points-API.patch diff --git a/patches/server/0909-Add-drops-to-shear-events.patch b/patches/server/0908-Add-drops-to-shear-events.patch similarity index 100% rename from patches/server/0909-Add-drops-to-shear-events.patch rename to patches/server/0908-Add-drops-to-shear-events.patch diff --git a/patches/server/0910-Add-PlayerShieldDisableEvent.patch b/patches/server/0909-Add-PlayerShieldDisableEvent.patch similarity index 100% rename from patches/server/0910-Add-PlayerShieldDisableEvent.patch rename to patches/server/0909-Add-PlayerShieldDisableEvent.patch diff --git a/patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch b/patches/server/0910-Validate-ResourceLocation-in-NBT-reading.patch similarity index 97% rename from patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch rename to patches/server/0910-Validate-ResourceLocation-in-NBT-reading.patch index 5a6790a25df3..a7e42195f17f 100644 --- a/patches/server/0911-Validate-ResourceLocation-in-NBT-reading.patch +++ b/patches/server/0910-Validate-ResourceLocation-in-NBT-reading.patch @@ -53,10 +53,10 @@ index 084935138b1484f3d96e99f4e5655a6c04931907..9e357abe13f55bd9ce3a1d5348bcf19a if (nbt.contains("LootTableSeed", 4)) { this.setLootTableSeed(nbt.getLong("LootTableSeed")); diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index ccee69813597f45d382268bd1792a49722afebe9..e56050bef4a5aaa0fca17192dab4cf5e6a55fbae 100644 +index c2693d530be00af16b2aa4ca4afd1d136db68183..629c1316920ad4c111fff489f8c3ea0ed39d0099 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -689,7 +689,7 @@ public class EntityType implements FeatureElement, EntityTypeT +@@ -680,7 +680,7 @@ public class EntityType implements FeatureElement, EntityTypeT } public static Optional> by(CompoundTag nbt) { @@ -85,10 +85,10 @@ index b7721ed97305d1cd6725935f965c2effc1bef5a1..5f880a8809f9c20bc8e8c0b2d48590ba if (nbt.contains("leash", 11)) { Either either = (Either) NbtUtils.readBlockPos(nbt, "leash").map(Either::right).orElse(null); // CraftBukkit - decompile error diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 1c4ec3857c5c3ecf58f842292c280a4a1f00a04c..7196340fefd95845f290329faef489f2b2626ecb 100644 +index 9d3d6f012cfca60884019ed9710804aa37b11fbf..49b3d8d2bc34c0785f143bbc8976308f5bf8c9de 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -911,11 +911,13 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -909,11 +909,13 @@ public abstract class LivingEntity extends Entity implements Attackable { if (nbt.contains("SleepingX", 99) && nbt.contains("SleepingY", 99) && nbt.contains("SleepingZ", 99)) { BlockPos blockposition = new BlockPos(nbt.getInt("SleepingX"), nbt.getInt("SleepingY"), nbt.getInt("SleepingZ")); diff --git a/patches/server/0912-Properly-handle-experience-dropping-on-block-break.patch b/patches/server/0911-Properly-handle-experience-dropping-on-block-break.patch similarity index 94% rename from patches/server/0912-Properly-handle-experience-dropping-on-block-break.patch rename to patches/server/0911-Properly-handle-experience-dropping-on-block-break.patch index e5caf980cddf..5b45a7fb9204 100644 --- a/patches/server/0912-Properly-handle-experience-dropping-on-block-break.patch +++ b/patches/server/0911-Properly-handle-experience-dropping-on-block-break.patch @@ -7,10 +7,10 @@ This causes spawnAfterBreak to spawn xp by default, removing the need to manuall For classes that use custom xp amounts, they can drop the resources with disabling diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..83537aa240ebff8dd19b450956730dc3d4f355a0 100644 +index 18c011c1943867dbc4abee338b03b9be499876dd..01fbefdbed48ab85481c811cca532c91860626f7 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -617,7 +617,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -615,7 +615,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { if (drop) { BlockEntity tileentity = iblockdata.hasBlockEntity() ? this.getBlockEntity(pos) : null; @@ -21,10 +21,10 @@ index d048d0e4b16459b5bad44ebfa3c6a8f336f6762b..83537aa240ebff8dd19b450956730dc3 boolean flag1 = this.setBlock(pos, fluid.createLegacyBlock(), 3, maxUpdateDepth); diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index 6fb3f551f432d7e668c606fb7bd3514408e0478a..9917df070d9815b6915e4a0b022dfe4e5b7861e7 100644 +index 4ff32e3fb1a1979827ef063cda196a43995440fe..dc242451f397ae6a30b830ef1f211f1a066423a4 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -311,23 +311,31 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -302,23 +302,31 @@ public class Block extends BlockBehaviour implements ItemLike { for (ItemStack drop : Block.getDrops(state, serverLevel, pos, blockEntity)) { items.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(drop)); } @@ -58,7 +58,7 @@ index 6fb3f551f432d7e668c606fb7bd3514408e0478a..9917df070d9815b6915e4a0b022dfe4e } } -@@ -415,7 +423,7 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -406,7 +414,7 @@ public class Block extends BlockBehaviour implements ItemLike { player.awardStat(Stats.BLOCK_MINED.get(this)); player.causeFoodExhaustion(0.005F, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.BLOCK_MINED); // CraftBukkit - EntityExhaustionEvent if (includeDrops) { // Paper - fix drops not preventing stats/food exhaustion diff --git a/patches/server/0913-Fixup-NamespacedKey-handling.patch b/patches/server/0912-Fixup-NamespacedKey-handling.patch similarity index 100% rename from patches/server/0913-Fixup-NamespacedKey-handling.patch rename to patches/server/0912-Fixup-NamespacedKey-handling.patch diff --git a/patches/server/0914-Expose-LootTable-of-DecoratedPot.patch b/patches/server/0913-Expose-LootTable-of-DecoratedPot.patch similarity index 100% rename from patches/server/0914-Expose-LootTable-of-DecoratedPot.patch rename to patches/server/0913-Expose-LootTable-of-DecoratedPot.patch diff --git a/patches/server/0915-Reduce-allocation-of-Vec3D-by-entity-tracker.patch b/patches/server/0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch similarity index 95% rename from patches/server/0915-Reduce-allocation-of-Vec3D-by-entity-tracker.patch rename to patches/server/0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch index 2fd7060c00b0..cd53371b6bf7 100644 --- a/patches/server/0915-Reduce-allocation-of-Vec3D-by-entity-tracker.patch +++ b/patches/server/0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch @@ -18,10 +18,10 @@ index a043ac10834562d357ef0b5aded2e916e2a0d056..74276c368016fcc4dbf9579b2ecbadc9 @VisibleForTesting static long encode(double value) { diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 95c70de2c9f0e26742c0d66ad6c3bcc310a923f6..182513bb175feb5f30f0fb1cd5db501b6d483afd 100644 +index bf6d5f9e23387da845d6fe246c9013ec4d13cfb1..9b64dfe8f1727519673cc87be2398d43601e68ef 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1578,10 +1578,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1572,10 +1572,14 @@ 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/0916-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch b/patches/server/0915-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch similarity index 100% rename from patches/server/0916-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch rename to patches/server/0915-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch diff --git a/patches/server/0917-Add-ShulkerDuplicateEvent.patch b/patches/server/0916-Add-ShulkerDuplicateEvent.patch similarity index 100% rename from patches/server/0917-Add-ShulkerDuplicateEvent.patch rename to patches/server/0916-Add-ShulkerDuplicateEvent.patch diff --git a/patches/server/0918-Add-api-for-spawn-egg-texture-colors.patch b/patches/server/0917-Add-api-for-spawn-egg-texture-colors.patch similarity index 82% rename from patches/server/0918-Add-api-for-spawn-egg-texture-colors.patch rename to patches/server/0917-Add-api-for-spawn-egg-texture-colors.patch index ee55eb2e4a4d..af708be49f2e 100644 --- a/patches/server/0918-Add-api-for-spawn-egg-texture-colors.patch +++ b/patches/server/0917-Add-api-for-spawn-egg-texture-colors.patch @@ -5,12 +5,12 @@ Subject: [PATCH] Add api for spawn egg texture colors diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 3900f95f3ea41b010b8ea79c043fe322fa233461..7ae4567bc6f2f0374d1a4a3859f6329eaace7415 100644 +index 1835f8cfda0222fadd9db31abfb7e85899051853..30106a999db1bae217333b5e94913b9ec55e4615 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -643,6 +643,15 @@ public final class CraftMagicNumbers implements UnsafeValues { - return CraftRegistry.get(registry, namespacedKey, ApiVersion.CURRENT); +@@ -629,6 +629,15 @@ public final class CraftMagicNumbers implements UnsafeValues { } + // Paper end + // Paper start - spawn egg color visibility + @Override diff --git a/patches/server/0919-Add-Lifecycle-Event-system.patch b/patches/server/0918-Add-Lifecycle-Event-system.patch similarity index 99% rename from patches/server/0919-Add-Lifecycle-Event-system.patch rename to patches/server/0918-Add-Lifecycle-Event-system.patch index 611ac658507b..0eaff54d3402 100644 --- a/patches/server/0919-Add-Lifecycle-Event-system.patch +++ b/patches/server/0918-Add-Lifecycle-Event-system.patch @@ -727,10 +727,10 @@ index 2e96308696e131f3f013469a395e5ddda2c5d529..65a66e484c1c39c5f41d97db52f31c67 } catch (Throwable e) { LOGGER.error("Failed to run bootstrapper for %s. This plugin will not be loaded.".formatted(provider.getSource()), e); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 83c3de4ae733199f64fe0f967f9f816545d20f1c..581a15957478fd9f394a27269c2bd68a117ad8c2 100644 +index a1f2c8fd0348a6a5dad521430f473867bdadd1a5..a2c749b2997557fec5c978f3bed8c35d7614e740 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1051,6 +1051,11 @@ public final class CraftServer implements Server { +@@ -1050,6 +1050,11 @@ public final class CraftServer implements Server { @Override public void reload() { @@ -743,10 +743,10 @@ index 83c3de4ae733199f64fe0f967f9f816545d20f1c..581a15957478fd9f394a27269c2bd68a this.reloadCount++; this.configuration = YamlConfiguration.loadConfiguration(this.getConfigFile()); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 7ae4567bc6f2f0374d1a4a3859f6329eaace7415..ca201861b383bac4ea93284ac017e85ae0b3b17c 100644 +index 30106a999db1bae217333b5e94913b9ec55e4615..06d66c8043daec3c736d82d972ceb98d55eae9d1 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -652,6 +652,13 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -638,6 +638,13 @@ public final class CraftMagicNumbers implements UnsafeValues { } // Paper end - spawn egg color visibility diff --git a/patches/server/0920-ItemStack-Tooltip-API.patch b/patches/server/0919-ItemStack-Tooltip-API.patch similarity index 78% rename from patches/server/0920-ItemStack-Tooltip-API.patch rename to patches/server/0919-ItemStack-Tooltip-API.patch index 7279f3026121..f06c4356cdba 100644 --- a/patches/server/0920-ItemStack-Tooltip-API.patch +++ b/patches/server/0919-ItemStack-Tooltip-API.patch @@ -5,14 +5,14 @@ Subject: [PATCH] ItemStack Tooltip API diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index ca201861b383bac4ea93284ac017e85ae0b3b17c..8feba2bd411abe36e64a39a0c599c73d07c19e20 100644 +index 06d66c8043daec3c736d82d972ceb98d55eae9d1..51d5629b00ec4929c12ed9e6ba5a37f5903cf13e 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -628,6 +628,21 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -627,6 +627,19 @@ public final class CraftMagicNumbers implements UnsafeValues { + if (statistic.getType() != org.bukkit.Statistic.Type.UNTYPED) return "minecraft.custom:minecraft." + statistic.getKey().getKey(); + return org.bukkit.craftbukkit.CraftStatistic.getNMSStatistic(statistic).getName(); } - // Paper end - fix custom stats criteria creation - -+ // Paper start - expose itemstack tooltip lines ++ + @Override + public java.util.List computeTooltipLines(final ItemStack itemStack, final io.papermc.paper.inventory.tooltip.TooltipContext tooltipContext, final org.bukkit.entity.Player player) { + Preconditions.checkArgument(tooltipContext != null, "tooltipContext cannot be null"); @@ -25,8 +25,6 @@ index ca201861b383bac4ea93284ac017e85ae0b3b17c..8feba2bd411abe36e64a39a0c599c73d + player == null ? null : ((org.bukkit.craftbukkit.entity.CraftPlayer) player).getHandle(), flag); + return lines.stream().map(io.papermc.paper.adventure.PaperAdventure::asAdventure).toList(); + } -+ // Paper end - expose itemstack tooltip lines -+ - @Override - public String get(Class aClass, String s) { - if (aClass == Enchantment.class) { + // Paper end + + // Paper start - spawn egg color visibility diff --git a/patches/server/0921-Add-getChunkSnapshot-includeLightData-parameter.patch b/patches/server/0920-Add-getChunkSnapshot-includeLightData-parameter.patch similarity index 100% rename from patches/server/0921-Add-getChunkSnapshot-includeLightData-parameter.patch rename to patches/server/0920-Add-getChunkSnapshot-includeLightData-parameter.patch diff --git a/patches/server/0922-Add-FluidState-API.patch b/patches/server/0921-Add-FluidState-API.patch similarity index 100% rename from patches/server/0922-Add-FluidState-API.patch rename to patches/server/0921-Add-FluidState-API.patch diff --git a/patches/server/0923-add-number-format-api.patch b/patches/server/0922-add-number-format-api.patch similarity index 100% rename from patches/server/0923-add-number-format-api.patch rename to patches/server/0922-add-number-format-api.patch diff --git a/patches/server/0924-improve-BanList-types.patch b/patches/server/0923-improve-BanList-types.patch similarity index 89% rename from patches/server/0924-improve-BanList-types.patch rename to patches/server/0923-improve-BanList-types.patch index 96871b48ee57..c89914131fbe 100644 --- a/patches/server/0924-improve-BanList-types.patch +++ b/patches/server/0923-improve-BanList-types.patch @@ -5,10 +5,10 @@ Subject: [PATCH] improve BanList types diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 581a15957478fd9f394a27269c2bd68a117ad8c2..f7e478a14ef17ad6d747d0ab56418b0b5b20492d 100644 +index a2c749b2997557fec5c978f3bed8c35d7614e740..6136037d3d096300d93b9710dd854224b30e0738 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2261,6 +2261,21 @@ public final class CraftServer implements Server { +@@ -2260,6 +2260,21 @@ public final class CraftServer implements Server { }; } diff --git a/patches/server/0925-Expanded-Hopper-API.patch b/patches/server/0924-Expanded-Hopper-API.patch similarity index 100% rename from patches/server/0925-Expanded-Hopper-API.patch rename to patches/server/0924-Expanded-Hopper-API.patch diff --git a/patches/server/0926-Add-BlockBreakProgressUpdateEvent.patch b/patches/server/0925-Add-BlockBreakProgressUpdateEvent.patch similarity index 90% rename from patches/server/0926-Add-BlockBreakProgressUpdateEvent.patch rename to patches/server/0925-Add-BlockBreakProgressUpdateEvent.patch index 2c5061f42f46..9b57c89df593 100644 --- a/patches/server/0926-Add-BlockBreakProgressUpdateEvent.patch +++ b/patches/server/0925-Add-BlockBreakProgressUpdateEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add BlockBreakProgressUpdateEvent diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index a628da8a0ed7ae2c7b46df3881bd75dc5b4fd607..99e6021bc0dc5775f4443bdb77debd535a2cf29f 100644 +index 7a985c30a973efacf3e8b70e7163c550d86b0870..ea1281c9a3b83b17de64d583e029db9bacabcd88 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1315,6 +1315,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1285,6 +1285,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (entity instanceof Player) entityhuman = (Player) entity; // CraftBukkit end diff --git a/patches/server/0927-Deprecate-ItemStack-setType.patch b/patches/server/0926-Deprecate-ItemStack-setType.patch similarity index 100% rename from patches/server/0927-Deprecate-ItemStack-setType.patch rename to patches/server/0926-Deprecate-ItemStack-setType.patch diff --git a/patches/server/0928-Add-CartographyItemEvent.patch b/patches/server/0927-Add-CartographyItemEvent.patch similarity index 94% rename from patches/server/0928-Add-CartographyItemEvent.patch rename to patches/server/0927-Add-CartographyItemEvent.patch index b8a1377ce941..544bc15eda79 100644 --- a/patches/server/0928-Add-CartographyItemEvent.patch +++ b/patches/server/0927-Add-CartographyItemEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add CartographyItemEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 836e6b705b201253f2b81d1ca0228b8a0266a1dd..d3975496dcf94d3474e891bcd3105120559b6a61 100644 +index f92624ccd43f448abdee92c975d613cbcb3457c6..90bed0a36b2d518b56164a414350ec02822ad42a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -3133,6 +3133,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -3130,6 +3130,19 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } diff --git a/patches/server/0929-More-Raid-API.patch b/patches/server/0928-More-Raid-API.patch similarity index 100% rename from patches/server/0929-More-Raid-API.patch rename to patches/server/0928-More-Raid-API.patch diff --git a/patches/server/0930-Add-onboarding-message-for-initial-server-start.patch b/patches/server/0929-Add-onboarding-message-for-initial-server-start.patch similarity index 94% rename from patches/server/0930-Add-onboarding-message-for-initial-server-start.patch rename to patches/server/0929-Add-onboarding-message-for-initial-server-start.patch index 70718c71a46a..73d18bd703a4 100644 --- a/patches/server/0930-Add-onboarding-message-for-initial-server-start.patch +++ b/patches/server/0929-Add-onboarding-message-for-initial-server-start.patch @@ -17,10 +17,10 @@ index d9502ba028a96f9cc846f9ed428bd8066b857ca3..87e5f614ba988547a827486740db217e node = loader.load(); this.verifyGlobalConfigVersion(node); diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 36b96e0ed5c0d25068ec4678eddd8a19a020d345..8a0cb603cd4dbfa1839e0f4e1606876cbb373277 100644 +index 56798215644d8bca1695856b3a941e8089f49e48..46c37c8db8ecf3cc808fcf59f6bee5fe6ca49b75 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -27,6 +27,7 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -25,6 +25,7 @@ public class GlobalConfiguration extends ConfigurationPart { private static final Logger LOGGER = LogUtils.getLogger(); static final int CURRENT_VERSION = 29; // (when you change the version, change the comment, so it conflicts on rebases): private static GlobalConfiguration instance; @@ -29,10 +29,10 @@ index 36b96e0ed5c0d25068ec4678eddd8a19a020d345..8a0cb603cd4dbfa1839e0f4e1606876c return instance; } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 7e83a0de08488c5acf3c1a5d7107564e2a8ed7e0..6de199b7cf7728479fede534338829cecade50f2 100644 +index be188079f12b3f7b394ae91db62cc17b1d0f4e79..2de0ae09de41f3ed254318a78d65045fc76e5016 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1151,6 +1151,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop getTypeKey(); -@@ -199,7 +208,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -198,7 +207,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // CraftBukkit Ticks things for (SpawnCategory spawnCategory : SpawnCategory.values()) { if (CraftSpawnCategory.isValidForLimits(spawnCategory)) { diff --git a/patches/server/0941-Properly-track-the-changed-item-from-dispense-events.patch b/patches/server/0940-Properly-track-the-changed-item-from-dispense-events.patch similarity index 100% rename from patches/server/0941-Properly-track-the-changed-item-from-dispense-events.patch rename to patches/server/0940-Properly-track-the-changed-item-from-dispense-events.patch diff --git a/patches/server/0942-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch b/patches/server/0941-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch similarity index 94% rename from patches/server/0942-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch rename to patches/server/0941-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch index 40895c886c0e..5c06384279e0 100644 --- a/patches/server/0942-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch +++ b/patches/server/0941-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch @@ -13,10 +13,10 @@ A config is provided if you rather let players use these exploits, and let them destroy the worlds End Portals and get on top of the nether easy. diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index ffe894f3034a967f7e3d820c6416acb8adbcfb84..35b9a6d382e420844fc21c88b7d8044e3b8b8368 100644 +index 083b72ebacfbba22af2230fb69b311aeee62cb6a..ba4006bc7dc31d10f37023cba7995a9621796f73 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -447,6 +447,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -445,6 +445,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public boolean setBlock(BlockPos pos, BlockState state, int flags, int maxUpdateDepth) { // CraftBukkit start - tree generation if (this.captureTreeGeneration) { @@ -40,13 +40,14 @@ index 86656de31b1e33381eddd3ef210122118b31e620..fd1ecedfab037e377e4dded61539689b if (!this.level.isInWorldBounds(blockposition)) { diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index 9917df070d9815b6915e4a0b022dfe4e5b7861e7..729c3d8279b13d21c65ede89ea50869b69d5bfe6 100644 +index dc242451f397ae6a30b830ef1f211f1a066423a4..0f7b73634930df02d7b0a7f44890597cc2e6deca 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -89,6 +89,19 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -88,6 +88,21 @@ public class Block extends BlockBehaviour implements ItemLike { + public static final int UPDATE_LIMIT = 512; protected final StateDefinition stateDefinition; private BlockState defaultBlockState; - // Paper start ++ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed + public final boolean isDestroyable() { + return io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits || + this != Blocks.BARRIER && @@ -60,9 +61,10 @@ index 9917df070d9815b6915e4a0b022dfe4e5b7861e7..729c3d8279b13d21c65ede89ea50869b + this != Blocks.STRUCTURE_BLOCK && + this != Blocks.JIGSAW; + } - public co.aikar.timings.Timing timing; - public co.aikar.timings.Timing getTiming() { - if (timing == null) { ++ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed + @Nullable + private Item item; + private static final int CACHE_SIZE = 256; diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java index e841fccb8f298ef692677583b468869f56dc722c..4b51472502d08ea357da437afeb4b581979e9cff 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java diff --git a/patches/server/0943-Add-config-for-mobs-immune-to-default-effects.patch b/patches/server/0942-Add-config-for-mobs-immune-to-default-effects.patch similarity index 100% rename from patches/server/0943-Add-config-for-mobs-immune-to-default-effects.patch rename to patches/server/0942-Add-config-for-mobs-immune-to-default-effects.patch diff --git a/patches/server/0944-Deep-clone-nbt-tags-in-PDC.patch b/patches/server/0943-Deep-clone-nbt-tags-in-PDC.patch similarity index 100% rename from patches/server/0944-Deep-clone-nbt-tags-in-PDC.patch rename to patches/server/0943-Deep-clone-nbt-tags-in-PDC.patch diff --git a/patches/server/0945-Support-old-UUID-format-for-NBT.patch b/patches/server/0944-Support-old-UUID-format-for-NBT.patch similarity index 100% rename from patches/server/0945-Support-old-UUID-format-for-NBT.patch rename to patches/server/0944-Support-old-UUID-format-for-NBT.patch diff --git a/patches/server/0946-Fix-shield-disable-inconsistency.patch b/patches/server/0945-Fix-shield-disable-inconsistency.patch similarity index 87% rename from patches/server/0946-Fix-shield-disable-inconsistency.patch rename to patches/server/0945-Fix-shield-disable-inconsistency.patch index 8d372bca9df1..0f02785268c7 100644 --- a/patches/server/0946-Fix-shield-disable-inconsistency.patch +++ b/patches/server/0945-Fix-shield-disable-inconsistency.patch @@ -8,10 +8,10 @@ it will not disable the shield if the attacker is holding an axe item. diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 7196340fefd95845f290329faef489f2b2626ecb..b33dd288065b665e6feb642d090de1fd6e725448 100644 +index 49b3d8d2bc34c0785f143bbc8976308f5bf8c9de..f6d55ff3027bb7f0dcef186c52d48d9c5358ffd0 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2426,7 +2426,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2424,7 +2424,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.hurtCurrentlyUsedShield((float) -event.getDamage(DamageModifier.BLOCKING)); Entity entity = damagesource.getDirectEntity(); diff --git a/patches/server/0947-Handle-Large-Packets-disconnecting-client.patch b/patches/server/0946-Handle-Large-Packets-disconnecting-client.patch similarity index 100% rename from patches/server/0947-Handle-Large-Packets-disconnecting-client.patch rename to patches/server/0946-Handle-Large-Packets-disconnecting-client.patch diff --git a/patches/server/0948-Fix-ItemFlags.patch b/patches/server/0947-Fix-ItemFlags.patch similarity index 100% rename from patches/server/0948-Fix-ItemFlags.patch rename to patches/server/0947-Fix-ItemFlags.patch diff --git a/patches/server/0949-Fix-helmet-damage-reduction-inconsistencies.patch b/patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch similarity index 100% rename from patches/server/0949-Fix-helmet-damage-reduction-inconsistencies.patch rename to patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch diff --git a/patches/server/0950-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch b/patches/server/0949-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch similarity index 88% rename from patches/server/0950-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch rename to patches/server/0949-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch index e31dca1bf590..035254da6706 100644 --- a/patches/server/0950-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch +++ b/patches/server/0949-Revert-to-vanilla-handling-of-LivingEntity-actuallyH.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Revert to vanilla handling of LivingEntity#actuallyHurt diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index b33dd288065b665e6feb642d090de1fd6e725448..0cb9de4ff9ba0611a3bfc444088accb07ee19252 100644 +index f6d55ff3027bb7f0dcef186c52d48d9c5358ffd0..563e008740bf2017a1767470a2e34629dfa5cfa1 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1457,7 +1457,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1455,7 +1455,7 @@ public abstract class LivingEntity extends Entity implements Attackable { amount = 0.0F; } @@ -17,7 +17,7 @@ index b33dd288065b665e6feb642d090de1fd6e725448..0cb9de4ff9ba0611a3bfc444088accb0 boolean flag = amount > 0.0F && this.isDamageSourceBlocked(source); // Copied from below float f2 = 0.0F; -@@ -1515,6 +1515,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1513,6 +1513,7 @@ public abstract class LivingEntity extends Entity implements Attackable { if (!this.actuallyHurt(world, source, (float) event.getFinalDamage() - this.lastHurt, event)) { return false; } @@ -25,7 +25,7 @@ index b33dd288065b665e6feb642d090de1fd6e725448..0cb9de4ff9ba0611a3bfc444088accb0 // CraftBukkit end this.lastHurt = amount; flag1 = false; -@@ -1523,6 +1524,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1521,6 +1522,7 @@ public abstract class LivingEntity extends Entity implements Attackable { if (!this.actuallyHurt(world, source, (float) event.getFinalDamage(), event)) { return false; } @@ -33,7 +33,7 @@ index b33dd288065b665e6feb642d090de1fd6e725448..0cb9de4ff9ba0611a3bfc444088accb0 this.lastHurt = amount; this.invulnerableTime = this.invulnerableDuration; // CraftBukkit - restore use of maxNoDamageTicks // this.actuallyHurt(worldserver, damagesource, f); -@@ -2488,12 +2490,12 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2486,12 +2488,12 @@ public abstract class LivingEntity extends Entity implements Attackable { return true; } else { diff --git a/patches/server/0951-improve-checking-handled-tags-in-itemmeta.patch b/patches/server/0950-improve-checking-handled-tags-in-itemmeta.patch similarity index 100% rename from patches/server/0951-improve-checking-handled-tags-in-itemmeta.patch rename to patches/server/0950-improve-checking-handled-tags-in-itemmeta.patch diff --git a/patches/server/0952-Expose-hasColor-to-leather-armor.patch b/patches/server/0951-Expose-hasColor-to-leather-armor.patch similarity index 100% rename from patches/server/0952-Expose-hasColor-to-leather-armor.patch rename to patches/server/0951-Expose-hasColor-to-leather-armor.patch diff --git a/patches/server/0953-Added-API-to-get-player-ha-proxy-address.patch b/patches/server/0952-Added-API-to-get-player-ha-proxy-address.patch similarity index 100% rename from patches/server/0953-Added-API-to-get-player-ha-proxy-address.patch rename to patches/server/0952-Added-API-to-get-player-ha-proxy-address.patch diff --git a/patches/server/0954-General-ItemMeta-fixes.patch b/patches/server/0953-General-ItemMeta-fixes.patch similarity index 99% rename from patches/server/0954-General-ItemMeta-fixes.patch rename to patches/server/0953-General-ItemMeta-fixes.patch index ce6a04d22fb7..9421f612dd97 100644 --- a/patches/server/0954-General-ItemMeta-fixes.patch +++ b/patches/server/0953-General-ItemMeta-fixes.patch @@ -28,10 +28,10 @@ index 98b5208baeaa12a5ff2788e457c542000d6ea48b..babd89f39c43b0c64709d99bf8aca6cd // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index 63e234fb72952dcede4eeaa5d3d3390d137d88a2..b4aff394694417cff1930cf8fbd6696b9f9c9d01 100644 +index 645a7ec0709cbd3c0cfbf75f7b8622a67515f74c..39fc5aa6ac8c66d8dd7437262124b61c4c138689 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -152,6 +152,11 @@ public abstract class BlockEntity { +@@ -147,6 +147,11 @@ public abstract class BlockEntity { CompoundTag nbttagcompound = new CompoundTag(); this.saveAdditional(nbttagcompound, registries); diff --git a/patches/server/0955-More-Chest-Block-API.patch b/patches/server/0954-More-Chest-Block-API.patch similarity index 100% rename from patches/server/0955-More-Chest-Block-API.patch rename to patches/server/0954-More-Chest-Block-API.patch diff --git a/patches/server/0956-Print-data-component-type-on-encoding-error.patch b/patches/server/0955-Print-data-component-type-on-encoding-error.patch similarity index 100% rename from patches/server/0956-Print-data-component-type-on-encoding-error.patch rename to patches/server/0955-Print-data-component-type-on-encoding-error.patch diff --git a/patches/server/0957-Brigadier-based-command-API.patch b/patches/server/0956-Brigadier-based-command-API.patch similarity index 98% rename from patches/server/0957-Brigadier-based-command-API.patch rename to patches/server/0956-Brigadier-based-command-API.patch index f305e6146b7b..a0f076f9b28d 100644 --- a/patches/server/0957-Brigadier-based-command-API.patch +++ b/patches/server/0956-Brigadier-based-command-API.patch @@ -2228,10 +2228,10 @@ index 55484826fc5ddd04ae024e25a0251796d7fa9c28..237e4f7b24908e9ade9a483eb7ae05fa Component component = message.resolveComponent(commandSourceStack); CommandSigningContext commandSigningContext = commandSourceStack.getSigningContext(); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 6de199b7cf7728479fede534338829cecade50f2..a6975966f7fbf2dc765b10214ea434bc0c73b66e 100644 +index 2de0ae09de41f3ed254318a78d65045fc76e5016..2d2bb7ed1456d90e7d9218a445a1cf26aaaa6ede 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -317,7 +317,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; @@ -2240,7 +2240,7 @@ index 6de199b7cf7728479fede534338829cecade50f2..a6975966f7fbf2dc765b10214ea434bc private boolean forceTicks; // CraftBukkit end // Spigot start -@@ -407,7 +407,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { @@ -2269,7 +2269,7 @@ index 6de199b7cf7728479fede534338829cecade50f2..a6975966f7fbf2dc765b10214ea434bc this.packRepository.setSelected(dataPacks); WorldDataConfiguration worlddataconfiguration = new WorldDataConfiguration(MinecraftServer.getSelectedPacks(this.packRepository, true), this.worldData.enabledFeatures()); -@@ -2276,6 +2278,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop public +- private void handleCommand(String s) { - org.spigotmc.AsyncCatcher.catchOp("Command Dispatched Async: " + s); // Paper - Add async catcher -- co.aikar.timings.MinecraftTimings.playerCommandTimer.startTiming(); // Paper - if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot - this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s); - @@ -2358,7 +2356,6 @@ index 2cef6390ce8cdc43ae7566683afc157cb3a6fd78..af3e0049beb5590520ed84b52d6df85a - this.cserver.getPluginManager().callEvent(event); - - if (event.isCancelled()) { -- co.aikar.timings.MinecraftTimings.playerCommandTimer.stopTiming(); // Paper - return; - } - @@ -2371,7 +2368,8 @@ index 2cef6390ce8cdc43ae7566683afc157cb3a6fd78..af3e0049beb5590520ed84b52d6df85a - java.util.logging.Logger.getLogger(ServerGamePacketListenerImpl.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); - return; - } finally { -- co.aikar.timings.MinecraftTimings.playerCommandTimer.stopTiming(); // Paper ++ @Deprecated // Paper ++ public void handleCommand(String s) { // Paper - private -> public + // Paper start - Remove all this old duplicated logic + if (s.startsWith("/")) { + s = s.substring(1); @@ -2388,7 +2386,7 @@ index 2cef6390ce8cdc43ae7566683afc157cb3a6fd78..af3e0049beb5590520ed84b52d6df85a // CraftBukkit end diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index f7e478a14ef17ad6d747d0ab56418b0b5b20492d..15b406935047f591a7866d81b40841a5a9878f55 100644 +index 6136037d3d096300d93b9710dd854224b30e0738..694eacb7d3ffd28fe7684139554113e58be1ebfa 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -275,11 +275,11 @@ public final class CraftServer implements Server { @@ -2419,7 +2417,7 @@ index f7e478a14ef17ad6d747d0ab56418b0b5b20492d..15b406935047f591a7866d81b40841a5 CraftRegistry.setMinecraftRegistry(console.registryAccess()); -@@ -606,48 +612,11 @@ public final class CraftServer implements Server { +@@ -605,48 +611,11 @@ public final class CraftServer implements Server { } private void setVanillaCommands(boolean first) { // Spigot @@ -2470,7 +2468,7 @@ index f7e478a14ef17ad6d747d0ab56418b0b5b20492d..15b406935047f591a7866d81b40841a5 // Refresh commands for (ServerPlayer player : this.getHandle().players) { -@@ -1034,17 +1003,31 @@ public final class CraftServer implements Server { +@@ -1033,17 +1002,31 @@ public final class CraftServer implements Server { return true; } @@ -2512,7 +2510,7 @@ index f7e478a14ef17ad6d747d0ab56418b0b5b20492d..15b406935047f591a7866d81b40841a5 return false; } -@@ -1053,7 +1036,7 @@ public final class CraftServer implements Server { +@@ -1052,7 +1035,7 @@ public final class CraftServer implements Server { public void reload() { // Paper start - lifecycle events if (io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner.INSTANCE.blocksPluginReloading()) { @@ -2521,7 +2519,7 @@ index f7e478a14ef17ad6d747d0ab56418b0b5b20492d..15b406935047f591a7866d81b40841a5 } // Paper end - lifecycle events org.spigotmc.WatchdogThread.hasStarted = false; // Paper - Disable watchdog early timeout on reload -@@ -1108,8 +1091,9 @@ public final class CraftServer implements Server { +@@ -1107,8 +1090,9 @@ public final class CraftServer implements Server { } Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper @@ -2532,7 +2530,7 @@ index f7e478a14ef17ad6d747d0ab56418b0b5b20492d..15b406935047f591a7866d81b40841a5 // Paper start for (Plugin plugin : pluginClone) { entityMetadata.removeAll(plugin); -@@ -1149,6 +1133,12 @@ public final class CraftServer implements Server { +@@ -1148,6 +1132,12 @@ public final class CraftServer implements Server { this.enablePlugins(PluginLoadOrder.STARTUP); this.enablePlugins(PluginLoadOrder.POSTWORLD); if (io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper != null) io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper.pluginsEnabled(); // Paper - Remap plugins diff --git a/patches/server/0958-Fix-issues-with-Recipe-API.patch b/patches/server/0957-Fix-issues-with-Recipe-API.patch similarity index 100% rename from patches/server/0958-Fix-issues-with-Recipe-API.patch rename to patches/server/0957-Fix-issues-with-Recipe-API.patch diff --git a/patches/server/0959-Fix-equipment-slot-and-group-API.patch b/patches/server/0958-Fix-equipment-slot-and-group-API.patch similarity index 100% rename from patches/server/0959-Fix-equipment-slot-and-group-API.patch rename to patches/server/0958-Fix-equipment-slot-and-group-API.patch diff --git a/patches/server/0960-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch b/patches/server/0959-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch similarity index 100% rename from patches/server/0960-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch rename to patches/server/0959-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch diff --git a/patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch b/patches/server/0960-Prevent-sending-oversized-item-data-in-equipment-and.patch similarity index 98% rename from patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch rename to patches/server/0960-Prevent-sending-oversized-item-data-in-equipment-and.patch index 6f1042e76767..ec6969e74219 100644 --- a/patches/server/0961-Prevent-sending-oversized-item-data-in-equipment-and.patch +++ b/patches/server/0960-Prevent-sending-oversized-item-data-in-equipment-and.patch @@ -222,10 +222,10 @@ index af3e0049beb5590520ed84b52d6df85ad22a8f23..b7ff8607cd33d8e6bdab9533792cf43a ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); // Paper - fix slot desync - always refresh player inventory diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 0cb9de4ff9ba0611a3bfc444088accb07ee19252..6fa442fe4cf585f7056bedcfbd384e15da90f613 100644 +index 563e008740bf2017a1767470a2e34629dfa5cfa1..51c3ab2baae8cbd246464777b8ddbde2d3d9d0ef 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3462,7 +3462,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3460,7 +3460,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } }); diff --git a/patches/server/0962-Prevent-NPE-if-hooked-entity-was-cleared.patch b/patches/server/0961-Prevent-NPE-if-hooked-entity-was-cleared.patch similarity index 100% rename from patches/server/0962-Prevent-NPE-if-hooked-entity-was-cleared.patch rename to patches/server/0961-Prevent-NPE-if-hooked-entity-was-cleared.patch diff --git a/patches/server/0963-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch b/patches/server/0962-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch similarity index 94% rename from patches/server/0963-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch rename to patches/server/0962-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch index 6043bb02b6db..4b06a0c06a26 100644 --- a/patches/server/0963-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch +++ b/patches/server/0962-Fix-cancelling-BlockPlaceEvent-calling-onRemove.patch @@ -21,7 +21,7 @@ index babd89f39c43b0c64709d99bf8aca6cdc6ca1b24..947e2a3620d73569552c5185664b7564 // Brute force all possible updates diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 35b9a6d382e420844fc21c88b7d8044e3b8b8368..1b899473c6deeaa1aef9007d8b7bcec98580e61c 100644 +index ba4006bc7dc31d10f37023cba7995a9621796f73..96f18fa8fb5eb856a95e94a42504c00046eb491a 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -152,6 +152,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -33,7 +33,7 @@ index 35b9a6d382e420844fc21c88b7d8044e3b8b8368..1b899473c6deeaa1aef9007d8b7bcec9 public Map capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper - Retain block place order when capturing blockstates public List captureDrops; 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 5dd1df0da1f954778aebe0f40611ae0f3a7866ab..325d1e38a72a4b30f30261267e9adfb8a8726b11 100644 +index 7a794bb0587ce55b067c67dd17ab5be6a4773030..56227ce823ab2997e2602f0807bbd54e54454344 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -369,7 +369,7 @@ public class LevelChunk extends ChunkAccess { diff --git a/patches/server/0964-Add-missing-fishing-event-state.patch b/patches/server/0963-Add-missing-fishing-event-state.patch similarity index 100% rename from patches/server/0964-Add-missing-fishing-event-state.patch rename to patches/server/0963-Add-missing-fishing-event-state.patch diff --git a/patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch b/patches/server/0964-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch similarity index 100% rename from patches/server/0965-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch rename to patches/server/0964-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch diff --git a/patches/server/0966-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch b/patches/server/0965-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch similarity index 100% rename from patches/server/0966-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch rename to patches/server/0965-Fix-sending-disconnect-packet-in-phases-where-it-doe.patch diff --git a/patches/server/0967-Adopt-MaterialRerouting.patch b/patches/server/0966-Adopt-MaterialRerouting.patch similarity index 100% rename from patches/server/0967-Adopt-MaterialRerouting.patch rename to patches/server/0966-Adopt-MaterialRerouting.patch diff --git a/patches/server/0968-Suspicious-Effect-Entry-API.patch b/patches/server/0967-Suspicious-Effect-Entry-API.patch similarity index 100% rename from patches/server/0968-Suspicious-Effect-Entry-API.patch rename to patches/server/0967-Suspicious-Effect-Entry-API.patch diff --git a/patches/server/0969-check-if-itemstack-is-stackable-first.patch b/patches/server/0968-check-if-itemstack-is-stackable-first.patch similarity index 100% rename from patches/server/0969-check-if-itemstack-is-stackable-first.patch rename to patches/server/0968-check-if-itemstack-is-stackable-first.patch diff --git a/patches/server/0970-Fix-removing-recipes-from-RecipeIterator.patch b/patches/server/0969-Fix-removing-recipes-from-RecipeIterator.patch similarity index 100% rename from patches/server/0970-Fix-removing-recipes-from-RecipeIterator.patch rename to patches/server/0969-Fix-removing-recipes-from-RecipeIterator.patch diff --git a/patches/server/0971-Configurable-damage-tick-when-blocking-with-shield.patch b/patches/server/0970-Configurable-damage-tick-when-blocking-with-shield.patch similarity index 88% rename from patches/server/0971-Configurable-damage-tick-when-blocking-with-shield.patch rename to patches/server/0970-Configurable-damage-tick-when-blocking-with-shield.patch index 33e21b4cb108..95d97e81fa6a 100644 --- a/patches/server/0971-Configurable-damage-tick-when-blocking-with-shield.patch +++ b/patches/server/0970-Configurable-damage-tick-when-blocking-with-shield.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Configurable damage tick when blocking with shield diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 6fa442fe4cf585f7056bedcfbd384e15da90f613..4f6a9c9a1a9fa0f98ee2c3bfdc4c5b3202c5cdd0 100644 +index 51c3ab2baae8cbd246464777b8ddbde2d3d9d0ef..afa33711426ee28f70be216497941a10de3416ee 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2488,7 +2488,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2486,7 +2486,7 @@ public abstract class LivingEntity extends Entity implements Attackable { CriteriaTriggers.PLAYER_HURT_ENTITY.trigger((ServerPlayer) damagesource.getEntity(), this, damagesource, originalDamage, f, true); // Paper - fix taken/dealt param order } diff --git a/patches/server/0972-Properly-remove-the-experimental-smithing-inventory-.patch b/patches/server/0971-Properly-remove-the-experimental-smithing-inventory-.patch similarity index 100% rename from patches/server/0972-Properly-remove-the-experimental-smithing-inventory-.patch rename to patches/server/0971-Properly-remove-the-experimental-smithing-inventory-.patch diff --git a/patches/server/0973-disable-forced-empty-world-ticks.patch b/patches/server/0972-disable-forced-empty-world-ticks.patch similarity index 87% rename from patches/server/0973-disable-forced-empty-world-ticks.patch rename to patches/server/0972-disable-forced-empty-world-ticks.patch index 343cd32ea2e0..ae366dd7f05b 100644 --- a/patches/server/0973-disable-forced-empty-world-ticks.patch +++ b/patches/server/0972-disable-forced-empty-world-ticks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] disable forced empty world ticks diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index eed2d1ec425bbd34563fae9e69a4518ec154fc23..982d44b539e189f4a857e72554cc81f8a4501ad6 100644 +index 711d5136124c0fa21015f0154057ab5742071e59..24df2baaeb34eccbe148ac0e518f44e9a869ffa5 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -519,7 +519,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -509,7 +509,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.handlingTick = false; gameprofilerfiller.pop(); diff --git a/patches/server/0974-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch b/patches/server/0973-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch similarity index 96% rename from patches/server/0974-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch rename to patches/server/0973-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch index f7d697b6899f..178cf52c88cc 100644 --- a/patches/server/0974-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch +++ b/patches/server/0973-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch @@ -29,10 +29,10 @@ index 2f2bcc1b9b32e58bf70ae6c171177ceb333ed6cd..d7afddd1d961495f0b50302a8da0a70f this.x = x; this.y = y; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 1b899473c6deeaa1aef9007d8b7bcec98580e61c..8adf12491e01830464b07e7a795db995d31f7a31 100644 +index 96f18fa8fb5eb856a95e94a42504c00046eb491a..a124a360f45cd71810b8253ce266d52145b6f83b 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -341,7 +341,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -339,7 +339,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Paper end public boolean isInWorldBounds(BlockPos pos) { diff --git a/patches/server/0975-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/patches/server/0974-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch similarity index 97% rename from patches/server/0975-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch rename to patches/server/0974-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch index f4600638dab1..dc903d6e3914 100644 --- a/patches/server/0975-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch +++ b/patches/server/0974-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 982d44b539e189f4a857e72554cc81f8a4501ad6..fe610561e6fbb9bc547d27123793395fb0ad80aa 100644 +index 24df2baaeb34eccbe148ac0e518f44e9a869ffa5..ce148cf5930cdcf0163c7f6416cbbd89e4d22720 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2363,6 +2363,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2333,6 +2333,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe { if ( iter.next().player == entity ) { diff --git a/patches/server/0976-Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/patches/server/0975-Optimize-Network-Manager-and-add-advanced-packet-sup.patch similarity index 100% rename from patches/server/0976-Optimize-Network-Manager-and-add-advanced-packet-sup.patch rename to patches/server/0975-Optimize-Network-Manager-and-add-advanced-packet-sup.patch diff --git a/patches/server/0977-Allow-Saving-of-Oversized-Chunks.patch b/patches/server/0976-Allow-Saving-of-Oversized-Chunks.patch similarity index 100% rename from patches/server/0977-Allow-Saving-of-Oversized-Chunks.patch rename to patches/server/0976-Allow-Saving-of-Oversized-Chunks.patch diff --git a/patches/server/0978-Flat-bedrock-generator-settings.patch b/patches/server/0977-Flat-bedrock-generator-settings.patch similarity index 100% rename from patches/server/0978-Flat-bedrock-generator-settings.patch rename to patches/server/0977-Flat-bedrock-generator-settings.patch diff --git a/patches/server/0979-Entity-Activation-Range-2.0.patch b/patches/server/0978-Entity-Activation-Range-2.0.patch similarity index 93% rename from patches/server/0979-Entity-Activation-Range-2.0.patch rename to patches/server/0978-Entity-Activation-Range-2.0.patch index 6a879cf17f30..a4edc8e8a090 100644 --- a/patches/server/0979-Entity-Activation-Range-2.0.patch +++ b/patches/server/0978-Entity-Activation-Range-2.0.patch @@ -17,40 +17,26 @@ Adds villagers as separate config public net.minecraft.world.entity.Entity isInsidePortal diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index fe610561e6fbb9bc547d27123793395fb0ad80aa..ce5fd95cabadd7c92726c401ae35e05dde3e30f6 100644 +index ce148cf5930cdcf0163c7f6416cbbd89e4d22720..75c388a5c9de26f0053015619e6c19bcff219478 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; - - import com.google.common.annotations.VisibleForTesting; - import co.aikar.timings.TimingHistory; // Paper --import co.aikar.timings.Timings; // Paper - import com.google.common.collect.Lists; - import com.mojang.datafixers.DataFixer; - import com.mojang.datafixers.util.Pair; -@@ -980,17 +979,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - ++TimingHistory.entityTicks; // Paper - timings +@@ -962,12 +962,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + + public void tickNonPassenger(Entity entity) { // Spigot start - co.aikar.timings.Timing timer; // Paper - if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { -+ /*if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { // Paper - comment out - EAR 2, reimplement below ++ /*if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { // Paper - comment out EAR 2 entity.tickCount++; - timer = entity.getType().inactiveTickTimer.startTiming(); try { // Paper - timings entity.inactiveTick(); - } finally { timer.stopTiming(); } // Paper return; - } + }*/ // Paper - comment out EAR 2 // Spigot end - // Paper start- timings -- TimingHistory.activatedEntityTicks++; -- timer = entity.getVehicle() != null ? entity.getType().passengerTickTimer.startTiming() : entity.getType().tickTimer.startTiming(); -+ final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); -+ timer = isActive ? entity.getType().tickTimer.startTiming() : entity.getType().inactiveTickTimer.startTiming(); // Paper - try { - // Paper end - timings ++ final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); // Paper - EAR 2 entity.setOldPosAndRot(); -@@ -1001,21 +1000,24 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + ProfilerFiller gameprofilerfiller = Profiler.get(); + +@@ -976,20 +977,22 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString(); }); gameprofilerfiller.incrementCounter("tickNonPassenger"); @@ -59,7 +45,6 @@ index fe610561e6fbb9bc547d27123793395fb0ad80aa..ce5fd95cabadd7c92726c401ae35e05d entity.postTick(); // CraftBukkit + } else { entity.inactiveTick(); } // Paper - EAR 2 gameprofilerfiller.pop(); -+ } finally { timer.stopTiming(); } // Paper - timings // EAR 2 Iterator iterator = entity.getPassengers().iterator(); while (iterator.hasNext()) { @@ -68,8 +53,6 @@ index fe610561e6fbb9bc547d27123793395fb0ad80aa..ce5fd95cabadd7c92726c401ae35e05d - this.tickPassenger(entity, entity1); + this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2 } -- } finally { timer.stopTiming(); } // Paper - timings -+ // } finally { timer.stopTiming(); } // Paper - timings // EAR 2 } @@ -78,7 +61,7 @@ index fe610561e6fbb9bc547d27123793395fb0ad80aa..ce5fd95cabadd7c92726c401ae35e05d if (!passenger.isRemoved() && passenger.getVehicle() == vehicle) { if (passenger instanceof Player || this.entityTickList.contains(passenger)) { passenger.setOldPosAndRot(); -@@ -1026,15 +1028,24 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1000,15 +1003,24 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return BuiltInRegistries.ENTITY_TYPE.getKey(passenger.getType()).toString(); }); gameprofilerfiller.incrementCounter("tickPassenger"); @@ -335,7 +318,7 @@ index f0a005724ab64a3b0cbc44d8f430716f7958461c..d81a6874e8b25f098df619f84c359e14 + } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 8adf12491e01830464b07e7a795db995d31f7a31..cef07ec3dfc8db3f3206fa2f5c2acf64c4b4aa65 100644 +index a124a360f45cd71810b8253ce266d52145b6f83b..128bda0d2a690a69b41325a1bb9a2b924cc883cc 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -157,6 +157,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -367,10 +350,10 @@ index 46afba838cf12eeb1bbccaa260131a76f090364b..e1c9a961064887070b29207efd7af478 } } diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index ad15c7db36bdeadaa8f2ec8f15f41d6f3395bd55..e4252c5a6aec351a4a0a8be372d3b63f7fb771e7 100644 +index f8387277d915460d755bdd35198d2547d1a49bde..6ffe86aa887ebf96f21114a468e16376c2449911 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java -@@ -1,33 +1,43 @@ +@@ -1,26 +1,35 @@ package org.spigotmc; +import net.minecraft.core.BlockPos; @@ -408,26 +391,17 @@ index ad15c7db36bdeadaa8f2ec8f15f41d6f3395bd55..e4252c5a6aec351a4a0a8be372d3b63f import net.minecraft.world.entity.projectile.FireworkRocketEntity; import net.minecraft.world.entity.projectile.ThrowableProjectile; import net.minecraft.world.entity.projectile.ThrownTrident; - import net.minecraft.world.entity.raid.Raider; -+import co.aikar.timings.MinecraftTimings; -+import net.minecraft.world.entity.schedule.Activity; - import net.minecraft.world.level.Level; - import net.minecraft.world.phys.AABB; --import co.aikar.timings.MinecraftTimings; - - public class ActivationRange - { -@@ -44,6 +54,43 @@ public class ActivationRange +@@ -43,6 +52,43 @@ public class ActivationRange AABB boundingBox = new AABB( 0, 0, 0, 0, 0, 0 ); } + // Paper start + -+ static Activity[] VILLAGER_PANIC_IMMUNITIES = { -+ Activity.HIDE, -+ Activity.PRE_RAID, -+ Activity.RAID, -+ Activity.PANIC ++ static net.minecraft.world.entity.schedule.Activity[] VILLAGER_PANIC_IMMUNITIES = { ++ net.minecraft.world.entity.schedule.Activity.HIDE, ++ net.minecraft.world.entity.schedule.Activity.PRE_RAID, ++ net.minecraft.world.entity.schedule.Activity.RAID, ++ net.minecraft.world.entity.schedule.Activity.PANIC + }; + + private static int checkInactiveWakeup(Entity entity) { @@ -461,7 +435,7 @@ index ad15c7db36bdeadaa8f2ec8f15f41d6f3395bd55..e4252c5a6aec351a4a0a8be372d3b63f static AABB maxBB = new AABB( 0, 0, 0, 0, 0, 0 ); -@@ -56,10 +103,13 @@ public class ActivationRange +@@ -55,10 +101,13 @@ public class ActivationRange */ public static ActivationType initializeEntityActivationType(Entity entity) { @@ -476,7 +450,7 @@ index ad15c7db36bdeadaa8f2ec8f15f41d6f3395bd55..e4252c5a6aec351a4a0a8be372d3b63f { return ActivationType.MONSTER; } else if ( entity instanceof PathfinderMob || entity instanceof AmbientCreature ) -@@ -80,10 +130,14 @@ public class ActivationRange +@@ -79,10 +128,14 @@ public class ActivationRange */ public static boolean initializeEntityActivationState(Entity entity, SpigotWorldConfig config) { @@ -495,7 +469,7 @@ index ad15c7db36bdeadaa8f2ec8f15f41d6f3395bd55..e4252c5a6aec351a4a0a8be372d3b63f || entity instanceof Player || entity instanceof ThrowableProjectile || entity instanceof EnderDragon -@@ -118,10 +172,25 @@ public class ActivationRange +@@ -116,10 +169,25 @@ public class ActivationRange final int raiderActivationRange = world.spigotConfig.raiderActivationRange; final int animalActivationRange = world.spigotConfig.animalActivationRange; final int monsterActivationRange = world.spigotConfig.monsterActivationRange; @@ -521,7 +495,7 @@ index ad15c7db36bdeadaa8f2ec8f15f41d6f3395bd55..e4252c5a6aec351a4a0a8be372d3b63f maxRange = Math.min( ( world.spigotConfig.simulationDistance << 4 ) - 8, maxRange ); for ( Player player : world.players() ) -@@ -132,13 +201,30 @@ public class ActivationRange +@@ -130,13 +198,30 @@ public class ActivationRange continue; } @@ -556,9 +530,9 @@ index ad15c7db36bdeadaa8f2ec8f15f41d6f3395bd55..e4252c5a6aec351a4a0a8be372d3b63f + } + // Paper end } - MinecraftTimings.entityActivationCheckTimer.stopTiming(); } -@@ -171,60 +257,118 @@ public class ActivationRange + +@@ -168,60 +253,118 @@ public class ActivationRange * @param entity * @return */ @@ -620,7 +594,8 @@ index ad15c7db36bdeadaa8f2ec8f15f41d6f3395bd55..e4252c5a6aec351a4a0a8be372d3b63f { - return true; + return 20; // Paper -+ } + } +- if ( entity instanceof Villager && ( (Villager) entity ).canBreed() ) + // Paper start + if (entity instanceof Bee) { + Bee bee = (Bee)entity; @@ -631,13 +606,12 @@ index ad15c7db36bdeadaa8f2ec8f15f41d6f3395bd55..e4252c5a6aec351a4a0a8be372d3b63f + ) { + return 20; + } - } -- if ( entity instanceof Villager && ( (Villager) entity ).canBreed() ) ++ } + if ( entity instanceof Villager ) { + Brain behaviorController = ((Villager) entity).getBrain(); + + if (config.villagersActiveForPanic) { -+ for (Activity activity : VILLAGER_PANIC_IMMUNITIES) { ++ for (net.minecraft.world.entity.schedule.Activity activity : VILLAGER_PANIC_IMMUNITIES) { + if (behaviorController.isActive(activity)) { + return 20*5; + } @@ -645,7 +619,7 @@ index ad15c7db36bdeadaa8f2ec8f15f41d6f3395bd55..e4252c5a6aec351a4a0a8be372d3b63f + } + + if (config.villagersWorkImmunityAfter > 0 && inactiveFor >= config.villagersWorkImmunityAfter) { -+ if (behaviorController.isActive(Activity.WORK)) { ++ if (behaviorController.isActive(net.minecraft.world.entity.schedule.Activity.WORK)) { + return config.villagersWorkImmunityFor; + } + } @@ -677,11 +651,11 @@ index ad15c7db36bdeadaa8f2ec8f15f41d6f3395bd55..e4252c5a6aec351a4a0a8be372d3b63f + // Paper start + if (entity instanceof Mob && ((Mob) entity).targetSelector.hasTasks() ) { + return 0; - } ++ } + if (entity instanceof Pillager) { + Pillager pillager = (Pillager) entity; + // TODO:? -+ } + } + // Paper end } // SPIGOT-6644: Otherwise the target refresh tick will be missed @@ -694,7 +668,7 @@ index ad15c7db36bdeadaa8f2ec8f15f41d6f3395bd55..e4252c5a6aec351a4a0a8be372d3b63f } /** -@@ -239,8 +383,19 @@ public class ActivationRange +@@ -236,8 +379,19 @@ public class ActivationRange if ( entity instanceof FireworkRocketEntity ) { return true; } @@ -715,7 +689,7 @@ index ad15c7db36bdeadaa8f2ec8f15f41d6f3395bd55..e4252c5a6aec351a4a0a8be372d3b63f // Should this entity tick? if ( !isActive ) -@@ -248,15 +403,19 @@ public class ActivationRange +@@ -245,15 +399,19 @@ public class ActivationRange if ( ( MinecraftServer.currentTick - entity.activatedTick - 1 ) % 20 == 0 ) { // Check immunities every 20 ticks. diff --git a/patches/server/0980-Anti-Xray.patch b/patches/server/0979-Anti-Xray.patch similarity index 98% rename from patches/server/0980-Anti-Xray.patch rename to patches/server/0979-Anti-Xray.patch index 1e72722f63d7..6164bec6d871 100644 --- a/patches/server/0980-Anti-Xray.patch +++ b/patches/server/0979-Anti-Xray.patch @@ -1104,10 +1104,10 @@ index 183b2191fa1c1b27adedf39593e1b5a223fb1279..8ead66c134688b11dca15f6509147e72 private ClientboundLevelChunkWithLightPacket(RegistryFriendlyByteBuf buf) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index ce5fd95cabadd7c92726c401ae35e05dde3e30f6..878bd04b63f257cc625953e45b953beb06917107 100644 +index 75c388a5c9de26f0053015619e6c19bcff219478..c0de354ac03a62f159540f25940dc3700cc0c575 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -344,7 +344,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -343,7 +343,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // Add env and gen to constructor, IWorldDataServer -> WorldDataServer public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { @@ -1157,10 +1157,10 @@ index cdd66e6ce96e2613afe7f06ca8da3cfaa6704b2d..dafa2cf7d3c49fc5bdcd68d2a9528127 if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) { new io.papermc.paper.event.packet.PlayerChunkLoadEvent(new org.bukkit.craftbukkit.CraftChunk(chunk), handler.getPlayer().getBukkitEntity()).callEvent(); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index fa951c6e33d583f9c2ca103fbaaa035e40c163f9..b0a43a24f2a43b1513600f26f1f02646c6031cef 100644 +index 409010fae4b175ba7dcbe0f38676022ed9b77b1d..781de82a8bee2836bf154341c91f23b34d98d4ad 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -427,7 +427,7 @@ public abstract class PlayerList { +@@ -426,7 +426,7 @@ public abstract class PlayerList { .getOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS); player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket( new net.minecraft.world.level.chunk.EmptyLevelChunk(worldserver1, player.chunkPosition(), plains), @@ -1170,7 +1170,7 @@ index fa951c6e33d583f9c2ca103fbaaa035e40c163f9..b0a43a24f2a43b1513600f26f1f02646 } // Paper end - Send empty chunk diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index cef07ec3dfc8db3f3206fa2f5c2acf64c4b4aa65..ce6c9b82a64a32c4b952d1839260015b1a446365 100644 +index 128bda0d2a690a69b41325a1bb9a2b924cc883cc..078088a854d466e66411d25d6dd6bcc536db78f3 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -172,6 +172,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -1178,10 +1178,10 @@ index cef07ec3dfc8db3f3206fa2f5c2acf64c4b4aa65..ce6c9b82a64a32c4b952d1839260015b // Paper end - add paper world config + public final com.destroystokyo.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray - public final co.aikar.timings.WorldTimingsHandler timings; // Paper public static BlockPos lastPhysicsProblem; // Spigot private org.spigotmc.TickLimiter entityLimiter; -@@ -206,7 +207,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + private org.spigotmc.TickLimiter tileLimiter; +@@ -205,7 +206,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public abstract ResourceKey getTypeKey(); @@ -1190,15 +1190,15 @@ index cef07ec3dfc8db3f3206fa2f5c2acf64c4b4aa65..ce6c9b82a64a32c4b952d1839260015b this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config this.generator = gen; -@@ -287,6 +288,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - this.timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings +@@ -285,6 +286,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + // CraftBukkit end this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime); this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); + this.chunkPacketBlockController = this.paperConfig().anticheat.antiXray.enabled ? new com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray(this, executor) : com.destroystokyo.paper.antixray.ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray } // Paper start - Cancel hit for vanished players -@@ -487,6 +489,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -485,6 +487,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // CraftBukkit end BlockState iblockdata1 = chunk.setBlockState(pos, state, (flags & 64) != 0, (flags & 1024) == 0); // CraftBukkit custom NO_PLACE flag @@ -1232,7 +1232,7 @@ index a846dd210ed1de0dc3e8b686663ee346bff33dc8..63d7d6b93119d96d753230472df30a9d } 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 325d1e38a72a4b30f30261267e9adfb8a8726b11..71dfd0abb930ecf4f1ba900c80c161fa2a858685 100644 +index 56227ce823ab2997e2602f0807bbd54e54454344..5d15aed0f340a49a47e035fb0ce23413946bc124 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 { @@ -1598,10 +1598,10 @@ index 5fc9e8e969debb3e15ed474b36a1c48b086d0449..f65cc95ab28e8a3b21eac2b16bd9ebe9 private static final byte[] EMPTY_LIGHT = new byte[2048]; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 15b406935047f591a7866d81b40841a5a9878f55..b29220ced6f5294594af23d9227532f5bb292e4c 100644 +index 694eacb7d3ffd28fe7684139554113e58be1ebfa..f3ec7e48f0c1ff3476886a7d64cc0dcc4edeab5f 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2693,7 +2693,7 @@ public final class CraftServer implements Server { +@@ -2692,7 +2692,7 @@ public final class CraftServer implements Server { public ChunkGenerator.ChunkData createChunkData(World world) { Preconditions.checkArgument(world != null, "World cannot be null"); ServerLevel handle = ((CraftWorld) world).getHandle(); diff --git a/patches/server/0981-Use-Velocity-compression-and-cipher-natives.patch b/patches/server/0980-Use-Velocity-compression-and-cipher-natives.patch similarity index 100% rename from patches/server/0981-Use-Velocity-compression-and-cipher-natives.patch rename to patches/server/0980-Use-Velocity-compression-and-cipher-natives.patch diff --git a/patches/server/0982-Optimize-Collision-to-not-load-chunks.patch b/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch similarity index 97% rename from patches/server/0982-Optimize-Collision-to-not-load-chunks.patch rename to patches/server/0981-Optimize-Collision-to-not-load-chunks.patch index 22bbfc1040fd..327fd5c6c2c2 100644 --- a/patches/server/0982-Optimize-Collision-to-not-load-chunks.patch +++ b/patches/server/0981-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 b0a43a24f2a43b1513600f26f1f02646c6031cef..aa245fe0945b267ef03700758e75edd445c7c60d 100644 +index 781de82a8bee2836bf154341c91f23b34d98d4ad..661498e404bd1b0e4857e159b79a3eeca6df1d8a 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -827,6 +827,7 @@ public abstract class PlayerList { +@@ -826,6 +826,7 @@ public abstract class PlayerList { Vec3 vec3d = teleporttransition.position(); entityplayer1.forceSetPositionRotation(vec3d.x, vec3d.y, vec3d.z, teleporttransition.yRot(), teleporttransition.xRot()); diff --git a/patches/server/0983-Optimize-GoalSelector-Goal.Flag-Set-operations.patch b/patches/server/0982-Optimize-GoalSelector-Goal.Flag-Set-operations.patch similarity index 100% rename from patches/server/0983-Optimize-GoalSelector-Goal.Flag-Set-operations.patch rename to patches/server/0982-Optimize-GoalSelector-Goal.Flag-Set-operations.patch diff --git a/patches/server/0984-Optimize-Hoppers.patch b/patches/server/0983-Optimize-Hoppers.patch similarity index 98% rename from patches/server/0984-Optimize-Hoppers.patch rename to patches/server/0983-Optimize-Hoppers.patch index bd4a72c0e2d3..f44f270f974b 100644 --- a/patches/server/0984-Optimize-Hoppers.patch +++ b/patches/server/0983-Optimize-Hoppers.patch @@ -50,10 +50,10 @@ index 0000000000000000000000000000000000000000..5c42823726e70ce6c9d0121d07431548 + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index a6975966f7fbf2dc765b10214ea434bc0c73b66e..7981abcea38196658556d403cbb588a7ddfff6ba 100644 +index 2d2bb7ed1456d90e7d9218a445a1cf26aaaa6ede..e3e3099bb33d21055e480fdbd2df2a3e159f0f1a 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1725,6 +1725,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent @@ -85,18 +85,18 @@ index 947e2a3620d73569552c5185664b7564e908007e..33e7d2884195677c4d6340d8b84c1dd8 itemstack.setPopTime(this.getPopTime()); return itemstack; diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index b4aff394694417cff1930cf8fbd6696b9f9c9d01..fb00e5a02bb8c64e27d6d009068ba041098951d6 100644 +index 39fc5aa6ac8c66d8dd7437262124b61c4c138689..1f929b467a0ece3143af58a657cf5983c07a8d51 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -38,6 +38,7 @@ import co.aikar.timings.MinecraftTimings; // Paper - import co.aikar.timings.Timing; // Paper +@@ -34,6 +34,7 @@ import org.bukkit.inventory.InventoryHolder; + // CraftBukkit end public abstract class BlockEntity { + static boolean ignoreTileUpdates; // Paper - Perf: Optimize Hoppers - public Timing tickTimer = MinecraftTimings.getTileEntityTimings(this); // Paper // CraftBukkit start - data containers -@@ -230,6 +231,7 @@ public abstract class BlockEntity { + private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); +@@ -225,6 +226,7 @@ public abstract class BlockEntity { public void setChanged() { if (this.level != null) { diff --git a/patches/server/0985-Optimize-Voxel-Shape-Merging.patch b/patches/server/0984-Optimize-Voxel-Shape-Merging.patch similarity index 100% rename from patches/server/0985-Optimize-Voxel-Shape-Merging.patch rename to patches/server/0984-Optimize-Voxel-Shape-Merging.patch diff --git a/patches/server/0986-Optimize-Bit-Operations-by-inlining.patch b/patches/server/0985-Optimize-Bit-Operations-by-inlining.patch similarity index 100% rename from patches/server/0986-Optimize-Bit-Operations-by-inlining.patch rename to patches/server/0985-Optimize-Bit-Operations-by-inlining.patch diff --git a/patches/server/0987-Remove-streams-from-hot-code.patch b/patches/server/0986-Remove-streams-from-hot-code.patch similarity index 100% rename from patches/server/0987-Remove-streams-from-hot-code.patch rename to patches/server/0986-Remove-streams-from-hot-code.patch diff --git a/patches/server/0988-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch b/patches/server/0987-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch similarity index 100% rename from patches/server/0988-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch rename to patches/server/0987-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch diff --git a/patches/server/0989-Fix-entity-type-tags-suggestions-in-selectors.patch b/patches/server/0988-Fix-entity-type-tags-suggestions-in-selectors.patch similarity index 100% rename from patches/server/0989-Fix-entity-type-tags-suggestions-in-selectors.patch rename to patches/server/0988-Fix-entity-type-tags-suggestions-in-selectors.patch diff --git a/patches/server/0990-Handle-Oversized-block-entities-in-chunks.patch b/patches/server/0989-Handle-Oversized-block-entities-in-chunks.patch similarity index 100% rename from patches/server/0990-Handle-Oversized-block-entities-in-chunks.patch rename to patches/server/0989-Handle-Oversized-block-entities-in-chunks.patch diff --git a/patches/server/0991-Check-distance-in-entity-interactions.patch b/patches/server/0990-Check-distance-in-entity-interactions.patch similarity index 93% rename from patches/server/0991-Check-distance-in-entity-interactions.patch rename to patches/server/0990-Check-distance-in-entity-interactions.patch index f8d61a567e41..238e3e451871 100644 --- a/patches/server/0991-Check-distance-in-entity-interactions.patch +++ b/patches/server/0990-Check-distance-in-entity-interactions.patch @@ -17,10 +17,10 @@ index 57223285860f61119b6cf348aa78e59384a04e22..ccfe9ef24dce9f34613692adb13738d3 }; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 4f6a9c9a1a9fa0f98ee2c3bfdc4c5b3202c5cdd0..52ca53b4795981080476fa9425e01f2c804ae6b7 100644 +index afa33711426ee28f70be216497941a10de3416ee..22f520414442c05986cc620208afaa895d8ee4fa 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1469,7 +1469,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1467,7 +1467,7 @@ public abstract class LivingEntity extends Entity implements Attackable { if (!source.is(DamageTypeTags.IS_PROJECTILE)) { Entity entity = source.getDirectEntity(); @@ -29,7 +29,7 @@ index 4f6a9c9a1a9fa0f98ee2c3bfdc4c5b3202c5cdd0..52ca53b4795981080476fa9425e01f2c LivingEntity entityliving = (LivingEntity) entity; this.blockUsingShield(entityliving); -@@ -1593,6 +1593,14 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1591,6 +1591,14 @@ public abstract class LivingEntity extends Entity implements Attackable { d0 = source.getSourcePosition().x() - this.getX(); d1 = source.getSourcePosition().z() - this.getZ(); } @@ -44,7 +44,7 @@ index 4f6a9c9a1a9fa0f98ee2c3bfdc4c5b3202c5cdd0..52ca53b4795981080476fa9425e01f2c this.knockback(0.4000000059604645D, d0, d1, entity1, entity1 == null ? io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE : io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // CraftBukkit // Paper - knockback events if (!flag) { -@@ -2428,7 +2436,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2426,7 +2434,7 @@ public abstract class LivingEntity extends Entity implements Attackable { this.hurtCurrentlyUsedShield((float) -event.getDamage(DamageModifier.BLOCKING)); Entity entity = damagesource.getDirectEntity(); diff --git a/patches/server/0992-Configurable-Sand-Duping.patch b/patches/server/0991-Configurable-Sand-Duping.patch similarity index 100% rename from patches/server/0992-Configurable-Sand-Duping.patch rename to patches/server/0991-Configurable-Sand-Duping.patch diff --git a/patches/server/0993-Properly-resend-entities.patch b/patches/server/0992-Properly-resend-entities.patch similarity index 97% rename from patches/server/0993-Properly-resend-entities.patch rename to patches/server/0992-Properly-resend-entities.patch index 95bcb49a7cc1..85cf1b2bdec2 100644 --- a/patches/server/0993-Properly-resend-entities.patch +++ b/patches/server/0992-Properly-resend-entities.patch @@ -102,10 +102,10 @@ index 52eafd99ed63f5fc9596225cf45175b1287f20a1..e5db85f858ab376b225172e22b92b841 } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index aa245fe0945b267ef03700758e75edd445c7c60d..f55d7f6ed653b19f28694f91ca5bcc54873e33c3 100644 +index 661498e404bd1b0e4857e159b79a3eeca6df1d8a..7fdadac8f3bc3810ae5adeeed2a77c043bb107c3 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -397,7 +397,7 @@ public abstract class PlayerList { +@@ -396,7 +396,7 @@ public abstract class PlayerList { ((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - Fire PlayerJoinEvent when Player is actually ready; track entity now // CraftBukkit end @@ -114,7 +114,7 @@ index aa245fe0945b267ef03700758e75edd445c7c60d..f55d7f6ed653b19f28694f91ca5bcc54 this.sendLevelInfo(player, worldserver1); -@@ -908,12 +908,17 @@ public abstract class PlayerList { +@@ -907,12 +907,17 @@ public abstract class PlayerList { } public void sendActiveEffects(LivingEntity entity, ServerGamePacketListenerImpl networkHandler) { @@ -186,10 +186,10 @@ index aa7d3383c773d3537335e449636f33d69cde12bb..6a0472eaae9ad890692862590b8d2311 public boolean equals(Object object) { return object instanceof Entity ? ((Entity) object).id == this.id : false; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 52ca53b4795981080476fa9425e01f2c804ae6b7..ed84f06d64afb117e08e8c8b54e992c0159a4a77 100644 +index 22f520414442c05986cc620208afaa895d8ee4fa..5e4716158da891216acc835f2560f980f527c66f 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -4031,6 +4031,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4029,6 +4029,11 @@ public abstract class LivingEntity extends Entity implements Attackable { return ((Byte) this.entityData.get(LivingEntity.DATA_LIVING_ENTITY_FLAGS) & 2) > 0 ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND; } diff --git a/patches/server/0994-Registry-Modification-API.patch b/patches/server/0993-Registry-Modification-API.patch similarity index 99% rename from patches/server/0994-Registry-Modification-API.patch rename to patches/server/0993-Registry-Modification-API.patch index 9568730b7f11..13cda87ccc50 100644 --- a/patches/server/0994-Registry-Modification-API.patch +++ b/patches/server/0993-Registry-Modification-API.patch @@ -1359,10 +1359,10 @@ index f8450a2abd1e96fac7827d252cc00038b9dee839..891ccc39d52331648a11b4e7cce78d4c + // Paper end - RegistrySet API } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 8feba2bd411abe36e64a39a0c599c73d07c19e20..75b5ec1023e2cf974696ee077195b195025ddc74 100644 +index 51d5629b00ec4929c12ed9e6ba5a37f5903cf13e..d728bf1d83877290e4d3fdaa7649ed077c0ee1ec 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -674,6 +674,21 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -658,6 +658,21 @@ public final class CraftMagicNumbers implements UnsafeValues { } // Paper end - lifecycle event API diff --git a/patches/server/0995-Add-registry-entry-and-builders.patch b/patches/server/0994-Add-registry-entry-and-builders.patch similarity index 100% rename from patches/server/0995-Add-registry-entry-and-builders.patch rename to patches/server/0994-Add-registry-entry-and-builders.patch diff --git a/patches/server/0996-Proxy-ItemStack-to-CraftItemStack.patch b/patches/server/0995-Proxy-ItemStack-to-CraftItemStack.patch similarity index 98% rename from patches/server/0996-Proxy-ItemStack-to-CraftItemStack.patch rename to patches/server/0995-Proxy-ItemStack-to-CraftItemStack.patch index f37751ee6f15..40da32a4fb75 100644 --- a/patches/server/0996-Proxy-ItemStack-to-CraftItemStack.patch +++ b/patches/server/0995-Proxy-ItemStack-to-CraftItemStack.patch @@ -205,10 +205,10 @@ index 6cc9d7a9e6d4bfdc27e52fc581b2bb832616f121..6930d0afb230a88aa813b02e4d55c95d + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 75b5ec1023e2cf974696ee077195b195025ddc74..f1178a6c8ccd1ad099d67b906f755eea1dfc0e53 100644 +index d728bf1d83877290e4d3fdaa7649ed077c0ee1ec..d3759c1262a5ce8ff82215a99abd31f20af95fc5 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -689,6 +689,13 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -673,6 +673,13 @@ public final class CraftMagicNumbers implements UnsafeValues { } // Paper end - hack to get tags for non server-backed registries diff --git a/patches/server/0997-Make-a-PDC-view-accessible-directly-from-ItemStack.patch b/patches/server/0996-Make-a-PDC-view-accessible-directly-from-ItemStack.patch similarity index 100% rename from patches/server/0997-Make-a-PDC-view-accessible-directly-from-ItemStack.patch rename to patches/server/0996-Make-a-PDC-view-accessible-directly-from-ItemStack.patch diff --git a/patches/server/0998-Prioritize-Minecraft-commands-in-function-parsing-an.patch b/patches/server/0997-Prioritize-Minecraft-commands-in-function-parsing-an.patch similarity index 100% rename from patches/server/0998-Prioritize-Minecraft-commands-in-function-parsing-an.patch rename to patches/server/0997-Prioritize-Minecraft-commands-in-function-parsing-an.patch diff --git a/patches/server/0999-optimize-dirt-and-snow-spreading.patch b/patches/server/0998-optimize-dirt-and-snow-spreading.patch similarity index 100% rename from patches/server/0999-optimize-dirt-and-snow-spreading.patch rename to patches/server/0998-optimize-dirt-and-snow-spreading.patch diff --git a/patches/server/1000-Fix-NPE-for-Jukebox-setRecord.patch b/patches/server/0999-Fix-NPE-for-Jukebox-setRecord.patch similarity index 100% rename from patches/server/1000-Fix-NPE-for-Jukebox-setRecord.patch rename to patches/server/0999-Fix-NPE-for-Jukebox-setRecord.patch diff --git a/patches/server/1001-fix-horse-inventories.patch b/patches/server/1000-fix-horse-inventories.patch similarity index 100% rename from patches/server/1001-fix-horse-inventories.patch rename to patches/server/1000-fix-horse-inventories.patch diff --git a/patches/server/1002-Only-call-EntityDamageEvents-before-actuallyHurt.patch b/patches/server/1001-Only-call-EntityDamageEvents-before-actuallyHurt.patch similarity index 91% rename from patches/server/1002-Only-call-EntityDamageEvents-before-actuallyHurt.patch rename to patches/server/1001-Only-call-EntityDamageEvents-before-actuallyHurt.patch index fb40d00f9a5a..9a4b69900924 100644 --- a/patches/server/1002-Only-call-EntityDamageEvents-before-actuallyHurt.patch +++ b/patches/server/1001-Only-call-EntityDamageEvents-before-actuallyHurt.patch @@ -12,10 +12,10 @@ This patch moves the invocation directly before the #actuallyHurt calls, respective invulnerable timings. diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index ed84f06d64afb117e08e8c8b54e992c0159a4a77..ab9eec00c8c7d4b9501c6c860065909263da0b10 100644 +index 5e4716158da891216acc835f2560f980f527c66f..ad536c76010957650814b293fc8220ac525c13f1 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1491,12 +1491,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1489,12 +1489,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } // CraftBukkit start @@ -29,7 +29,7 @@ index ed84f06d64afb117e08e8c8b54e992c0159a4a77..ab9eec00c8c7d4b9501c6c8600659092 // CraftBukkit end this.walkAnimation.setSpeed(1.5F); -@@ -1511,6 +1506,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1509,6 +1504,11 @@ public abstract class LivingEntity extends Entity implements Attackable { return false; } @@ -41,7 +41,7 @@ index ed84f06d64afb117e08e8c8b54e992c0159a4a77..ab9eec00c8c7d4b9501c6c8600659092 // CraftBukkit start if (!this.actuallyHurt(world, source, (float) event.getFinalDamage() - this.lastHurt, event)) { return false; -@@ -1520,6 +1520,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1518,6 +1518,10 @@ public abstract class LivingEntity extends Entity implements Attackable { this.lastHurt = amount; flag1 = false; } else { @@ -52,7 +52,7 @@ index ed84f06d64afb117e08e8c8b54e992c0159a4a77..ab9eec00c8c7d4b9501c6c8600659092 // CraftBukkit start if (!this.actuallyHurt(world, source, (float) event.getFinalDamage(), event)) { return false; -@@ -1655,6 +1659,18 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1653,6 +1657,18 @@ public abstract class LivingEntity extends Entity implements Attackable { } } diff --git a/patches/server/1003-Add-ItemType-getItemRarity.patch b/patches/server/1002-Add-ItemType-getItemRarity.patch similarity index 100% rename from patches/server/1003-Add-ItemType-getItemRarity.patch rename to patches/server/1002-Add-ItemType-getItemRarity.patch diff --git a/patches/server/1004-Add-plugin-info-at-startup.patch b/patches/server/1003-Add-plugin-info-at-startup.patch similarity index 100% rename from patches/server/1004-Add-plugin-info-at-startup.patch rename to patches/server/1003-Add-plugin-info-at-startup.patch diff --git a/patches/server/1005-Make-interaction-leniency-distance-configurable.patch b/patches/server/1004-Make-interaction-leniency-distance-configurable.patch similarity index 100% rename from patches/server/1005-Make-interaction-leniency-distance-configurable.patch rename to patches/server/1004-Make-interaction-leniency-distance-configurable.patch diff --git a/patches/server/1006-Fix-PickupStatus-getting-reset.patch b/patches/server/1005-Fix-PickupStatus-getting-reset.patch similarity index 100% rename from patches/server/1006-Fix-PickupStatus-getting-reset.patch rename to patches/server/1005-Fix-PickupStatus-getting-reset.patch diff --git a/patches/server/1007-Check-for-block-type-in-SculkSensorBlock-canActivate.patch b/patches/server/1006-Check-for-block-type-in-SculkSensorBlock-canActivate.patch similarity index 100% rename from patches/server/1007-Check-for-block-type-in-SculkSensorBlock-canActivate.patch rename to patches/server/1006-Check-for-block-type-in-SculkSensorBlock-canActivate.patch diff --git a/patches/server/1008-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch b/patches/server/1007-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch similarity index 100% rename from patches/server/1008-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch rename to patches/server/1007-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch diff --git a/patches/server/1009-Configuration-for-horizontal-only-item-merging.patch b/patches/server/1008-Configuration-for-horizontal-only-item-merging.patch similarity index 100% rename from patches/server/1009-Configuration-for-horizontal-only-item-merging.patch rename to patches/server/1008-Configuration-for-horizontal-only-item-merging.patch diff --git a/patches/server/1010-Add-skipping-world-symlink-scan.patch b/patches/server/1009-Add-skipping-world-symlink-scan.patch similarity index 100% rename from patches/server/1010-Add-skipping-world-symlink-scan.patch rename to patches/server/1009-Add-skipping-world-symlink-scan.patch diff --git a/patches/server/1011-Add-even-more-Enchantment-API.patch b/patches/server/1010-Add-even-more-Enchantment-API.patch similarity index 100% rename from patches/server/1011-Add-even-more-Enchantment-API.patch rename to patches/server/1010-Add-even-more-Enchantment-API.patch diff --git a/patches/server/1012-Leashable-API.patch b/patches/server/1011-Leashable-API.patch similarity index 100% rename from patches/server/1012-Leashable-API.patch rename to patches/server/1011-Leashable-API.patch diff --git a/patches/server/1013-Fix-CraftBukkit-drag-system.patch b/patches/server/1012-Fix-CraftBukkit-drag-system.patch similarity index 100% rename from patches/server/1013-Fix-CraftBukkit-drag-system.patch rename to patches/server/1012-Fix-CraftBukkit-drag-system.patch diff --git a/patches/server/1014-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch b/patches/server/1013-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch similarity index 100% rename from patches/server/1014-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch rename to patches/server/1013-Fix-SculkBloomEvent-firing-for-block-entity-loading.patch diff --git a/patches/server/1015-Remove-set-damage-lootable-item-function-from-compas.patch b/patches/server/1014-Remove-set-damage-lootable-item-function-from-compas.patch similarity index 100% rename from patches/server/1015-Remove-set-damage-lootable-item-function-from-compas.patch rename to patches/server/1014-Remove-set-damage-lootable-item-function-from-compas.patch diff --git a/patches/server/1016-Add-enchantment-seed-update-API.patch b/patches/server/1015-Add-enchantment-seed-update-API.patch similarity index 100% rename from patches/server/1016-Add-enchantment-seed-update-API.patch rename to patches/server/1015-Add-enchantment-seed-update-API.patch diff --git a/patches/server/1017-Fix-synchronise-sending-chat-to-client-with-updating.patch b/patches/server/1016-Fix-synchronise-sending-chat-to-client-with-updating.patch similarity index 100% rename from patches/server/1017-Fix-synchronise-sending-chat-to-client-with-updating.patch rename to patches/server/1016-Fix-synchronise-sending-chat-to-client-with-updating.patch diff --git a/patches/server/1018-Fix-InventoryOpenEvent-cancellation.patch b/patches/server/1017-Fix-InventoryOpenEvent-cancellation.patch similarity index 100% rename from patches/server/1018-Fix-InventoryOpenEvent-cancellation.patch rename to patches/server/1017-Fix-InventoryOpenEvent-cancellation.patch diff --git a/patches/server/1019-Fire-BlockExpEvent-on-grindstone-use.patch b/patches/server/1018-Fire-BlockExpEvent-on-grindstone-use.patch similarity index 100% rename from patches/server/1019-Fire-BlockExpEvent-on-grindstone-use.patch rename to patches/server/1018-Fire-BlockExpEvent-on-grindstone-use.patch diff --git a/patches/server/1020-Check-dead-flag-in-isAlive.patch b/patches/server/1019-Check-dead-flag-in-isAlive.patch similarity index 90% rename from patches/server/1020-Check-dead-flag-in-isAlive.patch rename to patches/server/1019-Check-dead-flag-in-isAlive.patch index 2136c68a7a38..e2836e573862 100644 --- a/patches/server/1020-Check-dead-flag-in-isAlive.patch +++ b/patches/server/1019-Check-dead-flag-in-isAlive.patch @@ -15,10 +15,10 @@ Also, even if the plugin is responsibly checking !isDead() before modifying heal I am currently unable to replicate, these "revived" entities can still appear diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index ab9eec00c8c7d4b9501c6c860065909263da0b10..6db0613904c172fb6ae7e868f542f56aeaa63a5e 100644 +index ad536c76010957650814b293fc8220ac525c13f1..ceaba7b82e9ff73a14fdef046e63b07c4d0fd5e9 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2147,7 +2147,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2145,7 +2145,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @Override public boolean isAlive() { diff --git a/patches/server/1021-Add-FeatureFlag-API.patch b/patches/server/1020-Add-FeatureFlag-API.patch similarity index 99% rename from patches/server/1021-Add-FeatureFlag-API.patch rename to patches/server/1020-Add-FeatureFlag-API.patch index cc3530746f0b..eaaa35ce8306 100644 --- a/patches/server/1021-Add-FeatureFlag-API.patch +++ b/patches/server/1020-Add-FeatureFlag-API.patch @@ -284,7 +284,7 @@ index 6cf790c9fa23ea313423fdaeb7c181bf530828c6..0bcb9df1103050441f8922a688b163dc public static PotionEffectType minecraftHolderToBukkit(Holder minecraft) { return CraftPotionEffectType.minecraftToBukkit(minecraft.value()); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index f1178a6c8ccd1ad099d67b906f755eea1dfc0e53..e1186f840670aabb73668e03d66789f9e306e234 100644 +index d3759c1262a5ce8ff82215a99abd31f20af95fc5..15bb55f0b4c60b0519918b910398a0908022128f 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -47,7 +47,7 @@ import org.bukkit.advancement.Advancement; @@ -296,7 +296,7 @@ index f1178a6c8ccd1ad099d67b906f755eea1dfc0e53..e1186f840670aabb73668e03d66789f9 import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.attribute.CraftAttribute; -@@ -461,11 +461,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -455,11 +455,7 @@ public final class CraftMagicNumbers implements UnsafeValues { return CraftAttribute.bukkitToMinecraft(attribute).getDescriptionId(); } diff --git a/patches/server/1022-Tag-Lifecycle-Events.patch b/patches/server/1021-Tag-Lifecycle-Events.patch similarity index 99% rename from patches/server/1022-Tag-Lifecycle-Events.patch rename to patches/server/1021-Tag-Lifecycle-Events.patch index a247efaccc60..943c370a5bc6 100644 --- a/patches/server/1022-Tag-Lifecycle-Events.patch +++ b/patches/server/1021-Tag-Lifecycle-Events.patch @@ -474,10 +474,10 @@ index fdc88e52235a152dbe3cca273990b4b68f8daaf8..13797035494a1e010e1da529fb46040f static void loadContentsFromNetwork( diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 7981abcea38196658556d403cbb588a7ddfff6ba..257e7cf628af0e539e14f836ca47280ae97bd90d 100644 +index e3e3099bb33d21055e480fdbd2df2a3e159f0f1a..843f8ccce6302a6db6cc61c496a5eee21305a88f 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2252,7 +2252,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoopmap(resourcepackrepository::getPack).filter(Objects::nonNull).map(Pack::open).collect(ImmutableList.toImmutableList()); // CraftBukkit - decompile error // Paper - decompile error // todo: is this needed anymore? }, this).thenCompose((immutablelist) -> { MultiPackResourceManager resourcemanager = new MultiPackResourceManager(PackType.SERVER_DATA, immutablelist); diff --git a/patches/server/1023-Item-serialization-as-json.patch b/patches/server/1022-Item-serialization-as-json.patch similarity index 96% rename from patches/server/1023-Item-serialization-as-json.patch rename to patches/server/1022-Item-serialization-as-json.patch index 9e7e7399ca2b..6b8500a0d76d 100644 --- a/patches/server/1023-Item-serialization-as-json.patch +++ b/patches/server/1022-Item-serialization-as-json.patch @@ -28,10 +28,10 @@ index c80fd4960dfbb0fde37363e7df25b0a5411bdb11..ff7f6916f65466c25a7bde35d64682c1 public static final Codec CODEC_WITH_ID = CODEC.validate( component -> component.getUnsafe().contains("id", 8) ? DataResult.success(component) : DataResult.error(() -> "Missing id for entity in: " + component) diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index e1186f840670aabb73668e03d66789f9e306e234..2a5c5e9e04d90c4e218b200bb55ff6bf2877ad73 100644 +index 15bb55f0b4c60b0519918b910398a0908022128f..ef0ef0872a44eb34fe41358728f3ddcf262297e9 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -511,6 +511,39 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -516,6 +516,39 @@ public final class CraftMagicNumbers implements UnsafeValues { return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(MinecraftServer.getServer().registryAccess(), compound).orElseThrow()); } diff --git a/patches/server/1024-Validate-slot-in-PlayerInventory-setSlot.patch b/patches/server/1023-Validate-slot-in-PlayerInventory-setSlot.patch similarity index 100% rename from patches/server/1024-Validate-slot-in-PlayerInventory-setSlot.patch rename to patches/server/1023-Validate-slot-in-PlayerInventory-setSlot.patch diff --git a/patches/server/1025-Remove-wall-time-unused-skip-tick-protection.patch b/patches/server/1024-Remove-wall-time-unused-skip-tick-protection.patch similarity index 100% rename from patches/server/1025-Remove-wall-time-unused-skip-tick-protection.patch rename to patches/server/1024-Remove-wall-time-unused-skip-tick-protection.patch diff --git a/patches/server/1026-Disable-pretty-printing-for-advancement-saving.patch b/patches/server/1025-Disable-pretty-printing-for-advancement-saving.patch similarity index 100% rename from patches/server/1026-Disable-pretty-printing-for-advancement-saving.patch rename to patches/server/1025-Disable-pretty-printing-for-advancement-saving.patch diff --git a/patches/server/1027-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch b/patches/server/1026-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch similarity index 100% rename from patches/server/1027-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch rename to patches/server/1026-Fix-PlayerCommandPreprocessEvent-on-signed-commands.patch diff --git a/patches/server/1028-Add-enchantWithLevels-with-enchantment-registry-set.patch b/patches/server/1027-Add-enchantWithLevels-with-enchantment-registry-set.patch similarity index 100% rename from patches/server/1028-Add-enchantWithLevels-with-enchantment-registry-set.patch rename to patches/server/1027-Add-enchantWithLevels-with-enchantment-registry-set.patch diff --git a/patches/server/1029-Improve-entity-effect-API.patch b/patches/server/1028-Improve-entity-effect-API.patch similarity index 100% rename from patches/server/1029-Improve-entity-effect-API.patch rename to patches/server/1028-Improve-entity-effect-API.patch diff --git a/patches/server/1030-Add-recipeBrewTime.patch b/patches/server/1029-Add-recipeBrewTime.patch similarity index 100% rename from patches/server/1030-Add-recipeBrewTime.patch rename to patches/server/1029-Add-recipeBrewTime.patch diff --git a/patches/server/1031-Call-bucket-events-for-cauldrons.patch b/patches/server/1030-Call-bucket-events-for-cauldrons.patch similarity index 100% rename from patches/server/1031-Call-bucket-events-for-cauldrons.patch rename to patches/server/1030-Call-bucket-events-for-cauldrons.patch diff --git a/patches/server/1032-Add-PlayerInsertLecternBookEvent.patch b/patches/server/1031-Add-PlayerInsertLecternBookEvent.patch similarity index 100% rename from patches/server/1032-Add-PlayerInsertLecternBookEvent.patch rename to patches/server/1031-Add-PlayerInsertLecternBookEvent.patch diff --git a/patches/server/1033-Void-damage-configuration-API.patch b/patches/server/1032-Void-damage-configuration-API.patch similarity index 96% rename from patches/server/1033-Void-damage-configuration-API.patch rename to patches/server/1032-Void-damage-configuration-API.patch index 6270e63ff888..0bebf025157e 100644 --- a/patches/server/1033-Void-damage-configuration-API.patch +++ b/patches/server/1032-Void-damage-configuration-API.patch @@ -20,10 +20,10 @@ index 6a0472eaae9ad890692862590b8d23110e48536d..7d16f9935407931823ad3e420f336c7e && (!(this instanceof Player player) || !player.getAbilities().invulnerable))) { // Paper end - Configurable nether ceiling damage diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 6db0613904c172fb6ae7e868f542f56aeaa63a5e..22b3d3d945cbddae25abfca7d900324c79d32293 100644 +index ceaba7b82e9ff73a14fdef046e63b07c4d0fd5e9..2914be5f6681c513bf2878a92c0c60ad997852dc 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2702,7 +2702,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2700,7 +2700,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @Override protected void onBelowWorld() { diff --git a/patches/server/1034-Add-Offline-PDC-API.patch b/patches/server/1033-Add-Offline-PDC-API.patch similarity index 100% rename from patches/server/1034-Add-Offline-PDC-API.patch rename to patches/server/1033-Add-Offline-PDC-API.patch diff --git a/patches/server/1035-Add-AnvilView-bypassEnchantmentLevelRestriction.patch b/patches/server/1034-Add-AnvilView-bypassEnchantmentLevelRestriction.patch similarity index 100% rename from patches/server/1035-Add-AnvilView-bypassEnchantmentLevelRestriction.patch rename to patches/server/1034-Add-AnvilView-bypassEnchantmentLevelRestriction.patch diff --git a/patches/server/1036-Add-proper-async-player-disconnections.patch b/patches/server/1035-Add-proper-async-player-disconnections.patch similarity index 100% rename from patches/server/1036-Add-proper-async-player-disconnections.patch rename to patches/server/1035-Add-proper-async-player-disconnections.patch diff --git a/patches/server/1037-Always-send-Banner-patterns-to-the-client.patch b/patches/server/1036-Always-send-Banner-patterns-to-the-client.patch similarity index 100% rename from patches/server/1037-Always-send-Banner-patterns-to-the-client.patch rename to patches/server/1036-Always-send-Banner-patterns-to-the-client.patch diff --git a/patches/server/1038-Rewrite-dataconverter-system.patch b/patches/server/1037-Rewrite-dataconverter-system.patch similarity index 99% rename from patches/server/1038-Rewrite-dataconverter-system.patch rename to patches/server/1037-Rewrite-dataconverter-system.patch index c56d13c8730e..e91a834827c6 100644 --- a/patches/server/1038-Rewrite-dataconverter-system.patch +++ b/patches/server/1037-Rewrite-dataconverter-system.patch @@ -30384,10 +30384,10 @@ index b54a3741cd3ba615c83c98985cb4b3c4c586ed7a..b148cf247acdd36f856d0495cde4cc5a return nbttagcompound; }); diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 2a5c5e9e04d90c4e218b200bb55ff6bf2877ad73..bc53c263682ada9eebcaccc13e741844d310a7a6 100644 +index ef0ef0872a44eb34fe41358728f3ddcf262297e9..05a62b2cf9ca8e0141274bd7f44ef8fb703466d1 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -507,7 +507,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -512,7 +512,7 @@ public final class CraftMagicNumbers implements UnsafeValues { net.minecraft.nbt.CompoundTag compound = deserializeNbtFromBytes(data); final int dataVersion = compound.getInt("DataVersion"); @@ -30396,7 +30396,7 @@ index 2a5c5e9e04d90c4e218b200bb55ff6bf2877ad73..bc53c263682ada9eebcaccc13e741844 return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(MinecraftServer.getServer().registryAccess(), compound).orElseThrow()); } -@@ -561,7 +561,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -566,7 +566,7 @@ public final class CraftMagicNumbers implements UnsafeValues { net.minecraft.nbt.CompoundTag compound = deserializeNbtFromBytes(data); int dataVersion = compound.getInt("DataVersion"); diff --git a/patches/server/1039-Moonrise-optimisation-patches.patch b/patches/server/1038-Moonrise-optimisation-patches.patch similarity index 99% rename from patches/server/1039-Moonrise-optimisation-patches.patch rename to patches/server/1038-Moonrise-optimisation-patches.patch index 8bd5172b9660..1e69b3cb33d8 100644 --- a/patches/server/1039-Moonrise-optimisation-patches.patch +++ b/patches/server/1038-Moonrise-optimisation-patches.patch @@ -23189,10 +23189,10 @@ index 0000000000000000000000000000000000000000..85950a1aa732ab8c01ad28bec9e0de14 + } +} diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 8a0cb603cd4dbfa1839e0f4e1606876cbb373277..e4df6312fc676ab2d573f060b007e0442d60a6a9 100644 +index 46c37c8db8ecf3cc808fcf59f6bee5fe6ca49b75..cbd0f2c6636b8ae332f20a3cb763b06855dfe795 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -244,6 +244,23 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -219,6 +219,23 @@ public class GlobalConfiguration extends ConfigurationPart { @PostProcess private void postProcess() { ca.spottedleaf.moonrise.common.util.MoonriseCommon.adjustWorkerThreads(this.workerThreads, this.ioThreads); @@ -23386,19 +23386,19 @@ index fc6ce3485dc890f5105a37fe3e344a1460867556..e114e687f2f4503546687fd6792226a6 DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, worldLoader.get(), thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), services, LoggerChunkProgressListener::createFromGameruleRadius); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 257e7cf628af0e539e14f836ca47280ae97bd90d..0b095c559c6a95ba2d9d7717d527cc2d8b7b6354 100644 +index 843f8ccce6302a6db6cc61c496a5eee21305a88f..e0b80b23197307d156ade8427a5227acbc45eb92 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -205,7 +205,7 @@ import org.bukkit.event.server.ServerLoadEvent; +@@ -204,7 +204,7 @@ import org.bukkit.event.server.ServerLoadEvent; + // CraftBukkit end - import co.aikar.timings.MinecraftTimings; // Paper -public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource { +public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource, ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer { // Paper - rewrite chunk system private static MinecraftServer SERVER; // Paper public static final Logger LOGGER = LogUtils.getLogger(); -@@ -332,7 +332,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); @@ -23407,7 +23407,7 @@ index 257e7cf628af0e539e14f836ca47280ae97bd90d..0b095c559c6a95ba2d9d7717d527cc2d ((MinecraftServer) atomicreference.get()).runServer(); }, "Server thread"); -@@ -351,6 +351,77 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { return false; } : this::haveTime); @@ -23574,7 +23574,7 @@ index 257e7cf628af0e539e14f836ca47280ae97bd90d..0b095c559c6a95ba2d9d7717d527cc2d this.tickFrame.end(); gameprofilerfiller.popPush("nextTickWait"); this.mayHaveDelayedTasks = true; -@@ -1440,6 +1519,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> UNLOADED_CHUNK_LIST_RESULT = ChunkResult.error("Unloaded chunks found in range"); private static final CompletableFuture>> UNLOADED_CHUNK_LIST_FUTURE = CompletableFuture.completedFuture(ChunkMap.UNLOADED_CHUNK_LIST_RESULT); -@@ -125,10 +125,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -123,10 +123,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider public static final int MIN_VIEW_DISTANCE = 2; public static final int MAX_VIEW_DISTANCE = 32; public static final int FORCED_TICKET_LEVEL = ChunkLevel.byStatus(FullChunkStatus.ENTITY_TICKING); @@ -24165,7 +24165,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d public final ServerLevel level; private final ThreadedLevelLightEngine lightEngine; private final BlockableEventLoop mainThreadExecutor; -@@ -138,22 +135,18 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -136,22 +133,18 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider private final PoiManager poiManager; public final LongSet toDrop; private boolean modified; @@ -24192,7 +24192,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback() public final CallbackExecutor callbackExecutor = new CallbackExecutor(); -@@ -178,24 +171,26 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -176,24 +169,26 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper start public final ChunkHolder getUnloadingChunkHolder(int chunkX, int chunkZ) { @@ -24227,7 +24227,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d Path path = session.getDimensionPath(world.dimension()); this.storageName = path.getFileName().toString(); -@@ -223,18 +218,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -221,18 +216,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.chunkStatusListener = chunkStatusChangeListener; ConsecutiveExecutor consecutiveexecutor1 = new ConsecutiveExecutor(executor, "light"); @@ -24249,7 +24249,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d } // Paper start -@@ -265,23 +258,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -263,23 +256,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } boolean isChunkTracked(ServerPlayer player, int chunkX, int chunkZ) { @@ -24275,7 +24275,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d } protected ThreadedLevelLightEngine getLightEngine() { -@@ -290,20 +271,22 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -288,20 +269,22 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @Nullable protected ChunkHolder getUpdatingChunkIfPresent(long pos) { @@ -24305,7 +24305,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d } public String getChunkDebugData(ChunkPos chunkPos) { -@@ -332,56 +315,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -330,56 +313,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } private CompletableFuture>> getChunkRangeFuture(ChunkHolder centerChunk, int margin, IntFunction distanceToStatus) { @@ -24363,7 +24363,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d } public ReportedException debugFuturesAndCreateReportedException(IllegalStateException exception, String details) { -@@ -411,104 +345,30 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -409,104 +343,30 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public CompletableFuture> prepareEntityTickingChunk(ChunkHolder holder) { @@ -24477,7 +24477,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d } -@@ -526,143 +386,29 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -524,143 +384,29 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public boolean hasWork() { @@ -24628,7 +24628,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d } private ChunkAccess handleChunkLoadFailure(Throwable throwable, ChunkPos chunkPos) { -@@ -718,139 +464,43 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -716,139 +462,43 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @Override public GenerationChunkHolder acquireGeneration(long pos) { @@ -24777,7 +24777,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d } public int getTickingGenerated() { -@@ -858,144 +508,80 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -856,144 +506,80 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } private boolean saveChunkIfNeeded(ChunkHolder chunkHolder, long currentTime) { @@ -24970,7 +24970,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d @Nullable public LevelChunk getChunkToSend(long pos) { ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos); -@@ -1061,7 +647,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1059,7 +645,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } // CraftBukkit start @@ -24979,7 +24979,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d return this.upgradeChunkTag(this.level.getTypeKey(), this.overworldDataStorage, nbttagcompound, this.generator().getTypeNameForDataFixer(), chunkcoordintpair, this.level); // CraftBukkit end } -@@ -1071,7 +657,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1069,7 +655,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider while (longiterator.hasNext()) { long i = longiterator.nextLong(); @@ -24988,7 +24988,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d if (playerchunk != null && this.anyPlayerCloseEnoughForSpawningInternal(playerchunk.getPos())) { callback.accept(playerchunk); -@@ -1086,7 +672,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1084,7 +670,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } boolean anyPlayerCloseEnoughForSpawning(ChunkPos chunkcoordintpair, boolean reducedRange) { @@ -24997,7 +24997,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d // Spigot end } -@@ -1104,16 +690,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1102,16 +688,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider //double blockRange = (reducedRange) ? Math.pow(chunkRange << 4, 2) : 16384.0D; // Paper - use from event double blockRange = 16384.0D; // Paper // Spigot end @@ -25026,7 +25026,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d // Paper start - PlayerNaturallySpawnCreaturesEvent com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event; blockRange = 16384.0D; -@@ -1123,33 +713,47 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1121,33 +711,47 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider blockRange = (double) ((event.getSpawnRadius() << 4) * (event.getSpawnRadius() << 4)); } // Paper end - PlayerNaturallySpawnCreaturesEvent @@ -25089,7 +25089,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d if (entityplayer.isSpectator()) { return false; } else { -@@ -1172,19 +776,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1170,19 +774,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.updatePlayerPos(player); if (!flag1) { this.distanceManager.addPlayer(SectionPos.of((EntityAccess) player), player); @@ -25113,7 +25113,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d } } -@@ -1196,17 +802,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1194,17 +800,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void move(ServerPlayer player) { @@ -25132,7 +25132,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d SectionPos sectionposition = player.getLastSectionPos(); SectionPos sectionposition1 = SectionPos.of((EntityAccess) player); -@@ -1216,6 +812,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1214,6 +810,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider if (flag2 || flag != flag1) { this.updatePlayerPos(player); @@ -25140,7 +25140,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d if (!flag) { this.distanceManager.removePlayer(sectionposition, player); } -@@ -1232,70 +829,30 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1230,70 +827,30 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.playerMap.unIgnorePlayer(player); } @@ -25222,7 +25222,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d } public void addEntity(Entity entity) { -@@ -1322,6 +879,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1320,6 +877,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider ChunkMap.TrackedEntity playerchunkmap_entitytracker = new ChunkMap.TrackedEntity(entity, i, j, entitytypes.trackDeltas()); this.entityMap.put(entity.getId(), playerchunkmap_entitytracker); @@ -25235,7 +25235,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d playerchunkmap_entitytracker.updatePlayers(this.level.players()); if (entity instanceof ServerPlayer) { ServerPlayer entityplayer = (ServerPlayer) entity; -@@ -1362,16 +925,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1360,16 +923,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider playerchunkmap_entitytracker1.broadcastRemoved(); } @@ -25279,7 +25279,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d List list = Lists.newArrayList(); List list1 = this.level.players(); -@@ -1478,27 +1063,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1472,27 +1057,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void waitForLightBeforeSending(ChunkPos centerPos, int radius) { @@ -25317,7 +25317,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d } @Nullable -@@ -1514,7 +1097,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1508,7 +1091,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } } @@ -25326,7 +25326,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d public final ServerEntity serverEntity; final Entity entity; -@@ -1522,6 +1105,89 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1516,6 +1099,89 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider SectionPos lastSectionPos; public final Set seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl @@ -25416,7 +25416,7 @@ index 182513bb175feb5f30f0fb1cd5db501b6d483afd..d692af061ded8cd5bcf1d268e6bd521d public TrackedEntity(final Entity entity, final int i, final int j, final boolean flag) { this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit this.entity = entity; -@@ -1624,20 +1290,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1618,20 +1284,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } private int getEffectiveRange() { @@ -26268,7 +26268,7 @@ index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a } } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 350bfa9c891130b1aa2ab973e86668de187ee1e0..4b5985c284faac7b06c0f99d53065f5060ecff4a 100644 +index 76cb7ffad02dcc27966ca13da6552edbb696e41f..07dde7dbf4d9e1d2f61426e3f1dc3cd5be55f193 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -52,7 +52,7 @@ import net.minecraft.world.level.storage.DimensionDataStorage; @@ -26396,7 +26396,7 @@ index 350bfa9c891130b1aa2ab973e86668de187ee1e0..4b5985c284faac7b06c0f99d53065f50 @Nullable public ChunkAccess getChunkAtImmediately(int x, int z) { -@@ -186,63 +274,42 @@ public class ServerChunkCache extends ChunkSource { +@@ -186,59 +274,42 @@ public class ServerChunkCache extends ChunkSource { @Nullable @Override public ChunkAccess getChunk(int x, int z, ChunkStatus leastStatus, boolean create) { @@ -26436,12 +26436,8 @@ index 350bfa9c891130b1aa2ab973e86668de187ee1e0..4b5985c284faac7b06c0f99d53065f50 - ServerChunkCache.MainThreadExecutor chunkproviderserver_b = this.mainThreadProcessor; - - Objects.requireNonNull(completablefuture); -- if (!completablefuture.isDone()) { // Paper -- com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x, z); // Paper - Add debug for sync chunk loads -- this.level.timings.syncChunkLoad.startTiming(); // Paper - chunkproviderserver_b.managedBlock(completablefuture::isDone); -- this.level.timings.syncChunkLoad.stopTiming(); // Paper -- } // Paper +- // com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x, z); // Paper - Add debug for sync chunk loads - ChunkResult chunkresult = (ChunkResult) completablefuture.join(); - ChunkAccess ichunkaccess1 = (ChunkAccess) chunkresult.orElse(null); // CraftBukkit - decompile error - @@ -26486,7 +26482,7 @@ index 350bfa9c891130b1aa2ab973e86668de187ee1e0..4b5985c284faac7b06c0f99d53065f50 } private void clearCache() { -@@ -273,56 +340,59 @@ public class ServerChunkCache extends ChunkSource { +@@ -269,56 +340,59 @@ public class ServerChunkCache extends ChunkSource { } private CompletableFuture> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { @@ -26584,7 +26580,7 @@ index 350bfa9c891130b1aa2ab973e86668de187ee1e0..4b5985c284faac7b06c0f99d53065f50 } @Override -@@ -335,16 +405,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -331,16 +405,7 @@ public class ServerChunkCache extends ChunkSource { } public boolean runDistanceManagerUpdates() { // Paper - public @@ -26602,7 +26598,7 @@ index 350bfa9c891130b1aa2ab973e86668de187ee1e0..4b5985c284faac7b06c0f99d53065f50 } // Paper start -@@ -354,17 +415,14 @@ public class ServerChunkCache extends ChunkSource { +@@ -350,17 +415,14 @@ public class ServerChunkCache extends ChunkSource { // Paper end public boolean isPositionTicking(long pos) { @@ -26622,10 +26618,10 @@ index 350bfa9c891130b1aa2ab973e86668de187ee1e0..4b5985c284faac7b06c0f99d53065f50 public void save(boolean flush) { - this.runDistanceManagerUpdates(); + // Paper - rewrite chunk system - try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings this.chunkMap.saveAllChunks(flush); - } // Paper - Timings -@@ -377,17 +435,15 @@ public class ServerChunkCache extends ChunkSource { + } + +@@ -371,17 +433,15 @@ public class ServerChunkCache extends ChunkSource { } public void close(boolean save) throws IOException { @@ -26646,15 +26642,15 @@ index 350bfa9c891130b1aa2ab973e86668de187ee1e0..4b5985c284faac7b06c0f99d53065f50 ProfilerFiller gameprofilerfiller = Profiler.get(); gameprofilerfiller.push("purge"); -@@ -415,6 +471,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -406,6 +466,7 @@ public class ServerChunkCache extends ChunkSource { + this.runDistanceManagerUpdates(); gameprofilerfiller.popPush("chunks"); if (tickChunks) { - this.level.timings.chunks.startTiming(); // Paper - timings + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getPlayerChunkLoader().tick(); // Paper - rewrite chunk system this.tickChunks(); - this.level.timings.chunks.stopTiming(); // Paper - timings this.chunkMap.tick(); -@@ -444,7 +501,10 @@ public class ServerChunkCache extends ChunkSource { + } +@@ -432,7 +493,10 @@ public class ServerChunkCache extends ChunkSource { gameprofilerfiller.push("filteringTickingChunks"); this.collectTickingChunks(list); gameprofilerfiller.popPush("shuffleChunks"); @@ -26666,7 +26662,7 @@ index 350bfa9c891130b1aa2ab973e86668de187ee1e0..4b5985c284faac7b06c0f99d53065f50 this.tickChunks(gameprofilerfiller, j, list); gameprofilerfiller.pop(); } finally { -@@ -477,14 +537,26 @@ public class ServerChunkCache extends ChunkSource { +@@ -463,14 +527,26 @@ public class ServerChunkCache extends ChunkSource { } private void collectTickingChunks(List chunks) { @@ -26698,7 +26694,7 @@ index 350bfa9c891130b1aa2ab973e86668de187ee1e0..4b5985c284faac7b06c0f99d53065f50 } private void tickChunks(ProfilerFiller profiler, long timeDelta, List chunks) { -@@ -528,7 +600,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -512,7 +588,7 @@ public class ServerChunkCache extends ChunkSource { NaturalSpawner.spawnForChunk(this.level, chunk, spawnercreature_d, list1); } @@ -26707,7 +26703,7 @@ index 350bfa9c891130b1aa2ab973e86668de187ee1e0..4b5985c284faac7b06c0f99d53065f50 this.level.tickChunk(chunk, k); } } -@@ -545,11 +617,13 @@ public class ServerChunkCache extends ChunkSource { +@@ -525,11 +601,13 @@ public class ServerChunkCache extends ChunkSource { } private void getFullChunk(long pos, Consumer chunkConsumer) { @@ -26725,7 +26721,7 @@ index 350bfa9c891130b1aa2ab973e86668de187ee1e0..4b5985c284faac7b06c0f99d53065f50 } -@@ -643,6 +717,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -623,6 +701,12 @@ public class ServerChunkCache extends ChunkSource { this.chunkMap.setServerViewDistance(watchDistance); } @@ -26738,7 +26734,7 @@ index 350bfa9c891130b1aa2ab973e86668de187ee1e0..4b5985c284faac7b06c0f99d53065f50 public void setSimulationDistance(int simulationDistance) { this.distanceManager.updateSimulationDistance(simulationDistance); } -@@ -734,21 +814,19 @@ public class ServerChunkCache extends ChunkSource { +@@ -714,21 +798,19 @@ public class ServerChunkCache extends ChunkSource { @Override // CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task public boolean pollTask() { @@ -26783,10 +26779,10 @@ index b2fd3e936559c8fcb8b02ae3ef63c4f3bd0edb08..5bbc7ceaafc163f12344e5d5d355ad2f if (!list.equals(this.lastPassengers)) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d4b294e8c 100644 +index c0de354ac03a62f159540f25940dc3700cc0c575..9af879115a24145ec290ac200565004e49ee7b0b 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -186,7 +186,7 @@ import org.bukkit.event.weather.LightningStrikeEvent; +@@ -185,7 +185,7 @@ import org.bukkit.event.weather.LightningStrikeEvent; import org.bukkit.event.world.TimeSkipEvent; // CraftBukkit end @@ -26795,7 +26791,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d public static final BlockPos END_SPAWN_POINT = new BlockPos(100, 50, 0); public static final IntProvider RAIN_DELAY = UniformInt.of(12000, 180000); -@@ -202,7 +202,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -201,7 +201,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public final PrimaryLevelData serverLevelData; // CraftBukkit - type private int lastSpawnChunkRadius; final EntityTickList entityTickList = new EntityTickList(); @@ -26804,7 +26800,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d private final GameEventDispatcher gameEventDispatcher; public boolean noSave; private final SleepStatus sleepStatus; -@@ -273,15 +273,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -272,15 +272,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.util.Priority priority, java.util.function.Consumer> onLoad) { @@ -26821,7 +26817,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d int minBlockX = Mth.floor(axisalignedbb.minX - 1.0E-7D) - 3; int maxBlockX = Mth.floor(axisalignedbb.maxX + 1.0E-7D) + 3; -@@ -294,30 +286,159 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -293,30 +285,159 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe int minChunkZ = minBlockZ >> 4; int maxChunkZ = maxBlockZ >> 4; @@ -26995,7 +26991,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d } } } -@@ -325,22 +446,137 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -324,22 +445,137 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe for (int cx = minChunkX; cx <= maxChunkX; ++cx) { for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) { @@ -27143,7 +27139,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d // Add env and gen to constructor, IWorldDataServer -> WorldDataServer public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { -@@ -374,14 +610,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -373,14 +609,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe DataFixer datafixer = minecraftserver.getFixerUpper(); EntityPersistentStorage entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver); @@ -27161,7 +27157,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d return minecraftserver.overworld().getDataStorage(); }); this.chunkSource.getGeneratorState().ensureStructuresGenerated(); -@@ -409,6 +644,20 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -408,6 +643,20 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.randomSequences = (RandomSequences) Objects.requireNonNullElseGet(randomsequences, () -> { return (RandomSequences) this.getDataStorage().computeIfAbsent(RandomSequences.factory(l), "random_sequences"); }); @@ -27182,7 +27178,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit } -@@ -541,7 +790,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -530,7 +779,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe gameprofilerfiller.push("checkDespawn"); entity.checkDespawn(); gameprofilerfiller.pop(); @@ -27191,7 +27187,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d Entity entity1 = entity.getVehicle(); if (entity1 != null) { -@@ -566,13 +815,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -553,13 +802,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } gameprofilerfiller.push("entityManagement"); @@ -27210,7 +27206,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d } protected void tickTime() { -@@ -612,7 +864,60 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -599,7 +851,60 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe }); } @@ -27271,7 +27267,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d ChunkPos chunkcoordintpair = chunk.getPos(); boolean flag = this.isRaining(); int j = chunkcoordintpair.getMinBlockX(); -@@ -620,7 +925,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -607,7 +912,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe ProfilerFiller gameprofilerfiller = Profiler.get(); gameprofilerfiller.push("thunder"); @@ -27280,7 +27276,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d BlockPos blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15)); if (this.isRainingAt(blockposition)) { -@@ -652,7 +957,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -639,7 +944,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (!this.paperConfig().environment.disableIceAndSnow) { // Paper - Option to disable ice and snow for (int l = 0; l < randomTickSpeed; ++l) { @@ -27289,9 +27285,9 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d this.tickPrecipitation(this.getBlockRandomPos(j, 0, k, 15)); } } -@@ -661,35 +966,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -647,35 +952,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + gameprofilerfiller.popPush("tickBlocks"); - timings.chunkTicksBlocks.startTiming(); // Paper if (randomTickSpeed > 0) { - LevelChunkSection[] achunksection = chunk.getSections(); - @@ -27325,8 +27321,8 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d + this.optimiseRandomTick(chunk, randomTickSpeed); // Paper - optimise random ticking } - timings.chunkTicksBlocks.stopTiming(); // Paper -@@ -963,6 +1240,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + gameprofilerfiller.pop(); +@@ -948,6 +1225,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (fluid1.is(fluid)) { fluid1.tick(this, pos, iblockdata); } @@ -27338,7 +27334,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d } -@@ -972,6 +1254,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -957,6 +1239,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (iblockdata.is(block)) { iblockdata.tick(this, pos, this.random); } @@ -27350,7 +27346,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d } -@@ -1060,6 +1347,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1035,6 +1322,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } public void save(@Nullable ProgressListener progressListener, boolean flush, boolean savingDisabled) { @@ -27362,19 +27358,17 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d ServerChunkCache chunkproviderserver = this.getChunkSource(); if (!savingDisabled) { -@@ -1075,16 +1367,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1048,14 +1340,19 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + progressListener.progressStage(Component.translatable("menu.savingChunks")); } - timings.worldSaveChunks.startTiming(); // Paper - chunkproviderserver.save(flush); -+ if (!close) { chunkproviderserver.save(flush); } // Paper - add close param - timings.worldSaveChunks.stopTiming(); // Paper - }// Paper - if (flush) { - this.entityManager.saveAll(); - } else { - this.entityManager.autoSave(); - } ++ if (!close) { chunkproviderserver.save(flush); } // Paper - add close param + // Paper - rewrite chunk system } @@ -27390,7 +27384,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d // CraftBukkit start - moved from MinecraftServer.saveChunks ServerLevel worldserver1 = this; -@@ -1224,7 +1521,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1195,7 +1492,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.removePlayerImmediately((ServerPlayer) entity, Entity.RemovalReason.DISCARDED); } @@ -27399,7 +27393,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d } // CraftBukkit start -@@ -1255,7 +1552,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1226,7 +1523,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } // CraftBukkit end @@ -27408,7 +27402,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d } } -@@ -1266,11 +1563,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1237,11 +1534,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public boolean tryAddFreshEntityWithPassengers(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { // CraftBukkit end @@ -27421,7 +27415,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d return false; } else { this.addFreshEntityWithPassengers(entity, reason); // CraftBukkit -@@ -1930,7 +2223,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1901,7 +2194,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } } @@ -27430,7 +27424,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d bufferedwriter.write(String.format(Locale.ROOT, "block_entity_tickers: %d\n", this.blockEntityTickers.size())); bufferedwriter.write(String.format(Locale.ROOT, "block_ticks: %d\n", this.getBlockTicks().count())); bufferedwriter.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count())); -@@ -1979,7 +2272,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1950,7 +2243,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe BufferedWriter bufferedwriter2 = Files.newBufferedWriter(path1); try { @@ -27439,7 +27433,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d } catch (Throwable throwable4) { if (bufferedwriter2 != null) { try { -@@ -2000,7 +2293,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1971,7 +2264,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe BufferedWriter bufferedwriter3 = Files.newBufferedWriter(path2); try { @@ -27448,7 +27442,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d } catch (Throwable throwable6) { if (bufferedwriter3 != null) { try { -@@ -2142,7 +2435,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2113,7 +2406,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @VisibleForTesting public String getWatchdogStats() { @@ -27457,7 +27451,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString(); }), this.blockEntityTickers.size(), ServerLevel.getTypeCount(this.blockEntityTickers, TickingBlockEntity::getType), this.getBlockTicks().count(), this.getFluidTicks().count(), this.gatherChunkSourceStats()); } -@@ -2172,15 +2465,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2143,15 +2436,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public LevelEntityGetter getEntities() { org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot @@ -27486,7 +27480,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d } public void startTickingChunk(LevelChunk chunk) { -@@ -2200,34 +2503,47 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2171,34 +2474,47 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public void close() throws IOException { super.close(); @@ -27541,7 +27535,7 @@ index 878bd04b63f257cc625953e45b953beb06917107..3b55367865b3583e11ef886678114d4d } @Override -@@ -2283,7 +2599,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2254,7 +2570,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report); crashreportsystemdetails.setDetail("Loaded entity count", () -> { @@ -28032,10 +28026,10 @@ index b7d29389a357f142237cecd75f8ca91cf1eb6b5b..e4b0dc3121101d54394a0c3a413dabf8 this.generatingStep = generationStep; this.cache = chunks; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index f55d7f6ed653b19f28694f91ca5bcc54873e33c3..a6964ceb3874acebdcb8cdc8fe0c128bd56bea48 100644 +index 7fdadac8f3bc3810ae5adeeed2a77c043bb107c3..296002eafb028e60aaa5d9728cd035f86abe6913 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1422,7 +1422,7 @@ public abstract class PlayerList { +@@ -1420,7 +1420,7 @@ public abstract class PlayerList { public void setViewDistance(int viewDistance) { this.viewDistance = viewDistance; @@ -29471,7 +29465,7 @@ index e185a33b5b1f8e8e0a0e666b24ba3e9186a8a7ff..5d7a6e4b73f032db356e7ec369b15001 // Paper start - Affects Spawning API diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index ce6c9b82a64a32c4b952d1839260015b1a446365..bb2d3ba2065b6bf67af24a8630ac2d58169fe783 100644 +index 078088a854d466e66411d25d6dd6bcc536db78f3..86cd6e1b8f68dd0564ee2a7c60f02d7af287af67 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -83,6 +83,7 @@ import net.minecraft.world.level.storage.LevelData; @@ -29491,7 +29485,7 @@ index ce6c9b82a64a32c4b952d1839260015b1a446365..bb2d3ba2065b6bf67af24a8630ac2d58 public static final Codec> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION); public static final ResourceKey OVERWORLD = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld")); -@@ -207,7 +208,639 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -206,7 +207,639 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public abstract ResourceKey getTypeKey(); @@ -30131,7 +30125,7 @@ index ce6c9b82a64a32c4b952d1839260015b1a446365..bb2d3ba2065b6bf67af24a8630ac2d58 this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config this.generator = gen; -@@ -289,6 +922,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -287,6 +920,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime); this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); this.chunkPacketBlockController = this.paperConfig().anticheat.antiXray.enabled ? new com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray(this, executor) : com.destroystokyo.paper.antixray.ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray @@ -30139,7 +30133,7 @@ index ce6c9b82a64a32c4b952d1839260015b1a446365..bb2d3ba2065b6bf67af24a8630ac2d58 } // Paper start - Cancel hit for vanished players -@@ -558,7 +1192,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -556,7 +1190,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.setBlocksDirty(blockposition, iblockdata1, iblockdata2); } @@ -30148,7 +30142,7 @@ index ce6c9b82a64a32c4b952d1839260015b1a446365..bb2d3ba2065b6bf67af24a8630ac2d58 this.sendBlockUpdated(blockposition, iblockdata1, iblockdata, i); } -@@ -824,6 +1458,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -819,6 +1453,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Iterator iterator = this.blockEntityTickers.iterator(); boolean flag = this.tickRateManager().runsNormally(); @@ -30157,7 +30151,7 @@ index ce6c9b82a64a32c4b952d1839260015b1a446365..bb2d3ba2065b6bf67af24a8630ac2d58 int tilesThisCycle = 0; var toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet(); // Paper - Fix MC-117075; use removeAll toRemove.add(null); // Paper - Fix MC-117075 -@@ -839,6 +1475,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -834,6 +1470,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Spigot end } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { tickingblockentity.tick(); @@ -30169,7 +30163,7 @@ index ce6c9b82a64a32c4b952d1839260015b1a446365..bb2d3ba2065b6bf67af24a8630ac2d58 } } this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 -@@ -861,12 +1502,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -854,12 +1495,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable { entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); // Paper end - Prevent block entity and entity crashes } @@ -30191,7 +30185,7 @@ index ce6c9b82a64a32c4b952d1839260015b1a446365..bb2d3ba2065b6bf67af24a8630ac2d58 } // Paper end - Option to prevent armor stands from doing entity lookups -@@ -918,7 +1567,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -911,7 +1560,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } // Paper end - Perf: Optimize capturedTileEntities lookup // CraftBukkit end @@ -30200,7 +30194,7 @@ index ce6c9b82a64a32c4b952d1839260015b1a446365..bb2d3ba2065b6bf67af24a8630ac2d58 } public void setBlockEntity(BlockEntity blockEntity) { -@@ -1010,26 +1659,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1003,26 +1652,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable { Profiler.get().incrementCounter("getEntities"); List list = Lists.newArrayList(); @@ -30233,7 +30227,7 @@ index ce6c9b82a64a32c4b952d1839260015b1a446365..bb2d3ba2065b6bf67af24a8630ac2d58 } @Override -@@ -1044,36 +1682,94 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1037,36 +1675,94 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.getEntities(filter, box, predicate, result, Integer.MAX_VALUE); } @@ -30863,10 +30857,10 @@ index 01352cc83b25eb0e30b7e0ff521fc7c1b3d5155b..90f8360f547ce709fd13ee34f8e67d8b public interface NoiseBiomeSource { diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index 729c3d8279b13d21c65ede89ea50869b69d5bfe6..fa19720fbb911842db42a4eb0ccf8406cb27c137 100644 +index 0f7b73634930df02d7b0a7f44890597cc2e6deca..b6d6c2cb9b227a17fb4ce42bc75f92206fbea043 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -278,7 +278,7 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -271,7 +271,7 @@ public class Block extends BlockBehaviour implements ItemLike { } public static boolean isShapeFullBlock(VoxelShape shape) { @@ -31673,7 +31667,7 @@ index f38700e5fbeeb8a913272d4464b8aa325d511dac..1eb8022f3e31603322e6c56516304afc @Override public BlockEntity getBlockEntity(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 71dfd0abb930ecf4f1ba900c80c161fa2a858685..e03d57f58a9f962cd429e8851fb3f35f3491e2c0 100644 +index 5d15aed0f340a49a47e035fb0ce23413946bc124..01cfb478764b8deb38be5692390dd9f014b8999f 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -54,7 +54,7 @@ import net.minecraft.world.ticks.LevelChunkTicks; @@ -31791,8 +31785,8 @@ index 71dfd0abb930ecf4f1ba900c80c161fa2a858685..e03d57f58a9f962cd429e8851fb3f35f + org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesLoadEvent(this.level, this.chunkPos, ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk().getAllEntities()); // Paper - rewrite chunk system if (this.needsDecoration) { - try (co.aikar.timings.Timing ignored = this.level.timings.chunkLoadPopulate.startTiming()) { // Paper -@@ -668,13 +717,15 @@ public class LevelChunk extends ChunkAccess { + this.needsDecoration = false; +@@ -666,13 +715,15 @@ public class LevelChunk extends ChunkAccess { } public void unloadCallback() { @@ -31810,7 +31804,7 @@ index 71dfd0abb930ecf4f1ba900c80c161fa2a858685..e03d57f58a9f962cd429e8851fb3f35f // Paper start this.loadedTicketLevel = false; // Paper end -@@ -682,8 +733,31 @@ public class LevelChunk extends ChunkAccess { +@@ -680,8 +731,31 @@ public class LevelChunk extends ChunkAccess { @Override public boolean isUnsaved() { @@ -31843,7 +31837,7 @@ index 71dfd0abb930ecf4f1ba900c80c161fa2a858685..e03d57f58a9f962cd429e8851fb3f35f // CraftBukkit end public boolean isEmpty() { -@@ -791,6 +865,7 @@ public class LevelChunk extends ChunkAccess { +@@ -789,6 +863,7 @@ public class LevelChunk extends ChunkAccess { this.pendingBlockEntities.clear(); this.upgradeData.upgrade(this); @@ -36000,10 +35994,10 @@ index f65cc95ab28e8a3b21eac2b16bd9ebe97e56e571..0074bc0e7147dc3a8c538e796f14ac9b @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index b29220ced6f5294594af23d9227532f5bb292e4c..d45d4d43f8e960f164c00bb534ebfbb6da6a803b 100644 +index f3ec7e48f0c1ff3476886a7d64cc0dcc4edeab5f..ca92d377a774ee46d13e108c528ce78941f906ec 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1433,7 +1433,7 @@ public final class CraftServer implements Server { +@@ -1432,7 +1432,7 @@ public final class CraftServer implements Server { // Paper - Put world into worldlist before initing the world; move up this.getServer().prepareLevels(internal.getChunkSource().chunkMap.progressListener, internal); @@ -36012,7 +36006,7 @@ index b29220ced6f5294594af23d9227532f5bb292e4c..d45d4d43f8e960f164c00bb534ebfbb6 this.pluginManager.callEvent(new WorldLoadEvent(internal.getWorld())); return internal.getWorld(); -@@ -1478,7 +1478,7 @@ public final class CraftServer implements Server { +@@ -1477,7 +1477,7 @@ public final class CraftServer implements Server { } handle.getChunkSource().close(save); @@ -36021,7 +36015,7 @@ index b29220ced6f5294594af23d9227532f5bb292e4c..d45d4d43f8e960f164c00bb534ebfbb6 handle.convertable.close(); } catch (Exception ex) { this.getLogger().log(Level.SEVERE, null, ex); -@@ -2516,7 +2516,7 @@ public final class CraftServer implements Server { +@@ -2515,7 +2515,7 @@ public final class CraftServer implements Server { @Override public boolean isPrimaryThread() { diff --git a/patches/server/1040-API-for-checking-sent-chunks.patch b/patches/server/1039-API-for-checking-sent-chunks.patch similarity index 100% rename from patches/server/1040-API-for-checking-sent-chunks.patch rename to patches/server/1039-API-for-checking-sent-chunks.patch diff --git a/patches/server/1041-Fix-CraftWorld-isChunkGenerated.patch b/patches/server/1040-Fix-CraftWorld-isChunkGenerated.patch similarity index 100% rename from patches/server/1041-Fix-CraftWorld-isChunkGenerated.patch rename to patches/server/1040-Fix-CraftWorld-isChunkGenerated.patch diff --git a/patches/server/1042-Add-startup-flag-to-disable-gamerule-limits.patch b/patches/server/1041-Add-startup-flag-to-disable-gamerule-limits.patch similarity index 100% rename from patches/server/1042-Add-startup-flag-to-disable-gamerule-limits.patch rename to patches/server/1041-Add-startup-flag-to-disable-gamerule-limits.patch diff --git a/patches/server/1043-Improved-Watchdog-Support.patch b/patches/server/1042-Improved-Watchdog-Support.patch similarity index 94% rename from patches/server/1043-Improved-Watchdog-Support.patch rename to patches/server/1042-Improved-Watchdog-Support.patch index 9ce6a1fe4ad3..f272bf52470b 100644 --- a/patches/server/1043-Improved-Watchdog-Support.patch +++ b/patches/server/1042-Improved-Watchdog-Support.patch @@ -115,10 +115,10 @@ index e114e687f2f4503546687fd6792226a643af8793..90ca25c4aaf92a5639839a7cdaee2ffc /* CraftBukkit start - Replace everything OptionParser optionparser = new OptionParser(); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 0b095c559c6a95ba2d9d7717d527cc2d8b7b6354..79f3dc4f53dce892c4756b0850352e0ca2eb95a6 100644 +index e0b80b23197307d156ade8427a5227acbc45eb92..7a671772760152f26e5bb60ea2f2a7765c017c37 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -318,7 +318,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; // Paper - don't store the vanilla dispatcher @@ -127,7 +127,7 @@ index 0b095c559c6a95ba2d9d7717d527cc2d8b7b6354..79f3dc4f53dce892c4756b0850352e0c // CraftBukkit end // Spigot start public static final int TPS = 20; -@@ -330,6 +330,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); Thread thread = new ca.spottedleaf.moonrise.common.util.TickThread(() -> { // Paper - rewrite chunk system -@@ -504,6 +507,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements FeatureElement, EntityTypeT +@@ -706,9 +706,20 @@ public class EntityType implements FeatureElement, EntityTypeT final Spliterator spliterator = entityNbtList.spliterator(); return StreamSupport.stream(new Spliterator() { diff --git a/patches/server/1046-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch b/patches/server/1045-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch similarity index 100% rename from patches/server/1046-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch rename to patches/server/1045-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch diff --git a/patches/server/1047-Bundle-spark.patch b/patches/server/1046-Bundle-spark.patch similarity index 94% rename from patches/server/1047-Bundle-spark.patch rename to patches/server/1046-Bundle-spark.patch index f66e0b42bb6d..8db706fc97ae 100644 --- a/patches/server/1047-Bundle-spark.patch +++ b/patches/server/1046-Bundle-spark.patch @@ -269,10 +269,10 @@ index 6b8ed8a0baaf4a57d20e57cec3400af5561ddd79..48604e7f96adc9e226e034054c5e2bad } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 79f3dc4f53dce892c4756b0850352e0ca2eb95a6..de80ac827c8ac3630d68b73cb425d4b56f7d2cd7 100644 +index 7a671772760152f26e5bb60ea2f2a7765c017c37..3fc6e7cb5e02792e5e87beb7525cde96bc45df1c 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -766,6 +766,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { // Paper - Ensure main - MinecraftTimings.savePlayers.startTiming(); // Paper + int numSaved = 0; + long now = MinecraftServer.currentTick; for (int i = 0; i < this.players.size(); ++i) { -- this.save(this.players.get(i)); -+ ServerPlayer entityplayer = this.players.get(i); -+ if (interval == -1 || now - entityplayer.lastSave >= interval) { -+ this.save(entityplayer); +- this.save((ServerPlayer) this.players.get(i)); ++ final ServerPlayer player = this.players.get(i); ++ if (interval == -1 || now - player.lastSave >= interval) { ++ this.save(player); + if (interval != -1 && ++numSaved >= io.papermc.paper.configuration.GlobalConfiguration.get().playerAutoSave.maxPerTick()) { break; } + } + // Paper end - Incremental chunk and player saving } - MinecraftTimings.savePlayers.stopTiming(); // Paper + return null; }); // Paper - ensure main diff --git a/patches/server/1050-Optimise-general-POI-access.patch b/patches/server/1049-Optimise-general-POI-access.patch similarity index 100% rename from patches/server/1050-Optimise-general-POI-access.patch rename to patches/server/1049-Optimise-general-POI-access.patch diff --git a/patches/server/1051-Fix-entity-tracker-desync-when-new-players-are-added.patch b/patches/server/1050-Fix-entity-tracker-desync-when-new-players-are-added.patch similarity index 97% rename from patches/server/1051-Fix-entity-tracker-desync-when-new-players-are-added.patch rename to patches/server/1050-Fix-entity-tracker-desync-when-new-players-are-added.patch index 6aecc462a4d0..c123fccefa59 100644 --- a/patches/server/1051-Fix-entity-tracker-desync-when-new-players-are-added.patch +++ b/patches/server/1050-Fix-entity-tracker-desync-when-new-players-are-added.patch @@ -48,10 +48,10 @@ index f6e1deb2f849d8b01b15cfa69e2f6cd5f2b1512b..f66e40326c510aa3267542b1a24ed75d entityTrackerEntry.getLastSentYRot(), entity.getType(), diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index d692af061ded8cd5bcf1d268e6bd521d84f99c39..bf43bdb43c5301c0e0954729bc531fb6a5045075 100644 +index c11ba8d9e97a68cda1811b570f0df117e6c38138..c7a9a22d84583764fc1cbcc1bdeb01a339d33687 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1277,6 +1277,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1271,6 +1271,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.serverEntity.addPairing(player); } // Paper end - entity tracking events diff --git a/patches/server/1052-Lag-compensation-ticks.patch b/patches/server/1051-Lag-compensation-ticks.patch similarity index 89% rename from patches/server/1052-Lag-compensation-ticks.patch rename to patches/server/1051-Lag-compensation-ticks.patch index 2643c943aabb..eb783423fedc 100644 --- a/patches/server/1052-Lag-compensation-ticks.patch +++ b/patches/server/1051-Lag-compensation-ticks.patch @@ -8,10 +8,10 @@ Areas affected by lag comepnsation: - Eating food items diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index f422cbcb69d6fda2b4e229cbdbf10abd0d36d6f9..73855f4555f781741f70267be65dec1ebb98b46a 100644 +index 27a50ce8f9ed5a6024f16444be5585f61062c2e9..1636c4347bb6e5a0b4c2e08c7ed9c49587769a2b 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -332,6 +332,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); -@@ -1874,6 +1875,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers @@ -28,10 +28,10 @@ index f422cbcb69d6fda2b4e229cbdbf10abd0d36d6f9..73855f4555f781741f70267be65dec1e gameprofilerfiller.push(() -> { String s = String.valueOf(worldserver); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index fd07824ff6a928ca6e2f56477a63bac7aaeb8c15..b2bbc9f3efbb7c949cc862eeee5d5f47be5d804f 100644 +index 2519a886317362db4ac0aeadb3655624f175cd99..e65cfb1132f5f0c9e1fa5ae4a46a8abed0c56be1 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -577,6 +577,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -576,6 +576,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe ); } // Paper end - chunk tick iteration @@ -63,10 +63,10 @@ index 504c996220b278c194c93e001a3b326d549868ec..a96f859a5d0c6ec692d4627a69f3c9ee if (this.hasDelayedDestroy) { diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 22b3d3d945cbddae25abfca7d900324c79d32293..a68ca22d5f8909d2ad37feded448f777736bf7db 100644 +index 2914be5f6681c513bf2878a92c0c60ad997852dc..0831d69d6ac1aa112dfe8243b01adcf5e8eba6a0 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -4052,6 +4052,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4050,6 +4050,10 @@ public abstract class LivingEntity extends Entity implements Attackable { this.resendPossiblyDesyncedDataValues(java.util.List.of(DATA_LIVING_ENTITY_FLAGS), serverPlayer); } // Paper end - Properly cancel usable items @@ -77,7 +77,7 @@ index 22b3d3d945cbddae25abfca7d900324c79d32293..a68ca22d5f8909d2ad37feded448f777 private void updatingUsingItem() { if (this.isUsingItem()) { if (ItemStack.isSameItem(this.getItemInHand(this.getUsedItemHand()), this.useItem)) { -@@ -4066,7 +4070,12 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4064,7 +4068,12 @@ public abstract class LivingEntity extends Entity implements Attackable { protected void updateUsingItem(ItemStack stack) { stack.onUseTick(this.level(), this, this.getUseItemRemainingTicks()); @@ -91,7 +91,7 @@ index 22b3d3d945cbddae25abfca7d900324c79d32293..a68ca22d5f8909d2ad37feded448f777 this.completeUsingItem(); } -@@ -4104,7 +4113,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4102,7 +4111,10 @@ public abstract class LivingEntity extends Entity implements Attackable { if (!itemstack.isEmpty() && !this.isUsingItem() || forceUpdate) { // Paper - Prevent consuming the wrong itemstack this.useItem = itemstack; @@ -103,7 +103,7 @@ index 22b3d3d945cbddae25abfca7d900324c79d32293..a68ca22d5f8909d2ad37feded448f777 if (!this.level().isClientSide) { this.setLivingEntityFlag(1, true); this.setLivingEntityFlag(2, hand == InteractionHand.OFF_HAND); -@@ -4129,7 +4141,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4127,7 +4139,10 @@ public abstract class LivingEntity extends Entity implements Attackable { } } else if (!this.isUsingItem() && !this.useItem.isEmpty()) { this.useItem = ItemStack.EMPTY; @@ -115,7 +115,7 @@ index 22b3d3d945cbddae25abfca7d900324c79d32293..a68ca22d5f8909d2ad37feded448f777 } } -@@ -4260,7 +4275,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4258,7 +4273,10 @@ public abstract class LivingEntity extends Entity implements Attackable { } this.useItem = ItemStack.EMPTY; diff --git a/patches/server/1053-Optimise-collision-checking-in-player-move-packet-ha.patch b/patches/server/1052-Optimise-collision-checking-in-player-move-packet-ha.patch similarity index 100% rename from patches/server/1053-Optimise-collision-checking-in-player-move-packet-ha.patch rename to patches/server/1052-Optimise-collision-checking-in-player-move-packet-ha.patch diff --git a/patches/server/1054-Optional-per-player-mob-spawns.patch b/patches/server/1053-Optional-per-player-mob-spawns.patch similarity index 93% rename from patches/server/1054-Optional-per-player-mob-spawns.patch rename to patches/server/1053-Optional-per-player-mob-spawns.patch index e08da27a0488..604904f337ac 100644 --- a/patches/server/1054-Optional-per-player-mob-spawns.patch +++ b/patches/server/1053-Optional-per-player-mob-spawns.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Optional per player mob spawns diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index bf43bdb43c5301c0e0954729bc531fb6a5045075..97a24cb410cf7d22a1a8edf8a5622d03a3d5a9c7 100644 +index c7a9a22d84583764fc1cbcc1bdeb01a339d33687..c9e5df9a598a1211aeba88920e774b0f765b3a14 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -231,8 +231,26 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -229,8 +229,26 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } // Paper start @@ -37,10 +37,10 @@ index bf43bdb43c5301c0e0954729bc531fb6a5045075..97a24cb410cf7d22a1a8edf8a5622d03 // Paper end diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 4b5985c284faac7b06c0f99d53065f5060ecff4a..ba989879c43cb7d614198444fd2ead85ea71eae9 100644 +index 07dde7dbf4d9e1d2f61426e3f1dc3cd5be55f193..12f49deea35ecbaea08869332982c00af7cf99d9 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -503,7 +503,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -495,7 +495,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon gameprofilerfiller.popPush("shuffleChunks"); // Paper start - chunk tick iteration optimisation this.shuffleRandom.setSeed(this.level.random.nextLong()); @@ -49,9 +49,9 @@ index 4b5985c284faac7b06c0f99d53065f5060ecff4a..ba989879c43cb7d614198444fd2ead85 // Paper end - chunk tick iteration optimisation this.tickChunks(gameprofilerfiller, j, list); gameprofilerfiller.pop(); -@@ -563,7 +563,19 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -552,7 +552,19 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + private void tickChunks(ProfilerFiller profiler, long timeDelta, List chunks) { profiler.popPush("naturalSpawnCount"); - this.level.timings.countNaturalMobs.startTiming(); // Paper - timings int j = this.distanceManager.getNaturalSpawnChunkCount(); - NaturalSpawner.SpawnState spawnercreature_d = NaturalSpawner.createState(j, this.level.getAllEntities(), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap)); + // Paper start - Optional per player mob spawns @@ -67,9 +67,9 @@ index 4b5985c284faac7b06c0f99d53065f5060ecff4a..ba989879c43cb7d614198444fd2ead85 + spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); + } + // Paper end - Optional per player mob spawns - this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings this.lastSpawnState = spawnercreature_d; + profiler.popPush("spawnAndTick"); diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java index 8c9148426f23cbbdfaf7ae66657d1a620f8bd853..8cc02ee9b1a710e35eb65a5a095681cc7dc542bb 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -86,7 +86,7 @@ index 8c9148426f23cbbdfaf7ae66657d1a620f8bd853..8cc02ee9b1a710e35eb65a5a095681cc // CraftBukkit start public CraftPlayer.TransferCookieConnection transferCookieConnection; diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 6eb69ebe688c1c52d5a5986dfc63cdd42e66687e..f3b52e61ddde25a60c1d178a7607b220ca01f770 100644 +index bf943feca387b77a3154773a59da7190d38d8621..0beb5ab48c5405d9bc2ad8d0c430312f456d38c2 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java @@ -71,6 +71,12 @@ public final class NaturalSpawner { @@ -129,7 +129,7 @@ index 6eb69ebe688c1c52d5a5986dfc63cdd42e66687e..f3b52e61ddde25a60c1d178a7607b220 // CraftBukkit end list.add(enumcreaturetype); } -@@ -161,12 +172,43 @@ public final class NaturalSpawner { +@@ -160,12 +171,43 @@ public final class NaturalSpawner { while (iterator.hasNext()) { MobCategory enumcreaturetype = (MobCategory) iterator.next(); @@ -175,7 +175,7 @@ index 6eb69ebe688c1c52d5a5986dfc63cdd42e66687e..f3b52e61ddde25a60c1d178a7607b220 } } -@@ -185,10 +227,15 @@ public final class NaturalSpawner { +@@ -183,10 +225,15 @@ public final class NaturalSpawner { // Paper end - Add mobcaps commands public static void spawnCategoryForChunk(MobCategory group, ServerLevel world, LevelChunk chunk, NaturalSpawner.SpawnPredicate checker, NaturalSpawner.AfterSpawnCallback runner) { @@ -192,7 +192,7 @@ index 6eb69ebe688c1c52d5a5986dfc63cdd42e66687e..f3b52e61ddde25a60c1d178a7607b220 } } -@@ -200,7 +247,12 @@ public final class NaturalSpawner { +@@ -198,7 +245,12 @@ public final class NaturalSpawner { }); } @@ -205,7 +205,7 @@ index 6eb69ebe688c1c52d5a5986dfc63cdd42e66687e..f3b52e61ddde25a60c1d178a7607b220 StructureManager structuremanager = world.structureManager(); ChunkGenerator chunkgenerator = world.getChunkSource().getGenerator(); int i = pos.getY(); -@@ -270,9 +322,14 @@ public final class NaturalSpawner { +@@ -268,9 +320,14 @@ public final class NaturalSpawner { ++j; ++k1; runner.run(entityinsentient, chunk); @@ -221,7 +221,7 @@ index 6eb69ebe688c1c52d5a5986dfc63cdd42e66687e..f3b52e61ddde25a60c1d178a7607b220 return; } -@@ -545,7 +602,7 @@ public final class NaturalSpawner { +@@ -543,7 +600,7 @@ public final class NaturalSpawner { MobCategory enumcreaturetype = entitytypes.getCategory(); this.mobCategoryCounts.addTo(enumcreaturetype, 1); diff --git a/patches/server/1055-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch b/patches/server/1054-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch similarity index 92% rename from patches/server/1055-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch rename to patches/server/1054-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch index 46bbbf1a99b8..e9cea51b0d06 100644 --- a/patches/server/1055-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch +++ b/patches/server/1054-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Improve cancelling PreCreatureSpawnEvent with per player mob diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 97a24cb410cf7d22a1a8edf8a5622d03a3d5a9c7..72fdcb65c1cc76d69369306c2c7e9a0f5dcb1f96 100644 +index c9e5df9a598a1211aeba88920e774b0f765b3a14..f4b578c7f839f58da265f2cbcb53e5654ca3edc8 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -248,8 +248,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -246,8 +246,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider ++(backingSet[i].mobCounts[index]); } } @@ -37,10 +37,10 @@ index 97a24cb410cf7d22a1a8edf8a5622d03a3d5a9c7..72fdcb65c1cc76d69369306c2c7e9a0f } // Paper end diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index ba989879c43cb7d614198444fd2ead85ea71eae9..b3024770b4fd140370a75afa55b966a404969428 100644 +index 12f49deea35ecbaea08869332982c00af7cf99d9..3c711e1df57ac5b0f8795ebb12299d275792b1d4 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -569,7 +569,17 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -558,7 +558,17 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled // re-set mob counts for (ServerPlayer player : this.level.players) { @@ -72,10 +72,10 @@ index 8cc02ee9b1a710e35eb65a5a095681cc7dc542bb..4e4e5b7e8c387cf13cf5bc5e39d334c3 // CraftBukkit start public CraftPlayer.TransferCookieConnection transferCookieConnection; diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index f3b52e61ddde25a60c1d178a7607b220ca01f770..848bfa93ebbdf78b0c3bae50e1726377fb78c862 100644 +index 0beb5ab48c5405d9bc2ad8d0c430312f456d38c2..5297798c2be1ba85569c2b92ed221956bf75477a 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -301,6 +301,11 @@ public final class NaturalSpawner { +@@ -299,6 +299,11 @@ public final class NaturalSpawner { // Paper start - PreCreatureSpawnEvent PreSpawnStatus doSpawning = isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2); From 4d873026726a150bcfe5cc6924bdd4dc8510d909 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Sun, 27 Oct 2024 18:47:50 +0100 Subject: [PATCH 100/119] Fix NPE and StackOverflowError for dispensers --- .../0459-Add-BlockFailedDispenseEvent.patch | 4 +- .../0473-Add-BlockPreDispenseEvent.patch | 4 +- ...ckOverflowError-and-NPE-for-some-dis.patch | 309 ++++++++++++++++++ ...tackOverflowError-for-some-dispenses.patch | 95 ------ ...he-changed-item-from-dispense-events.patch | 6 +- ...met-damage-reduction-inconsistencies.patch | 2 +- ...-Fix-InventoryOpenEvent-cancellation.patch | 2 +- 7 files changed, 318 insertions(+), 104 deletions(-) create mode 100644 patches/server/0936-Fix-possible-StackOverflowError-and-NPE-for-some-dis.patch delete mode 100644 patches/server/0936-Fix-possible-StackOverflowError-for-some-dispenses.patch diff --git a/patches/server/0459-Add-BlockFailedDispenseEvent.patch b/patches/server/0459-Add-BlockFailedDispenseEvent.patch index ee65c26c996d..c0dc74c0fe16 100644 --- a/patches/server/0459-Add-BlockFailedDispenseEvent.patch +++ b/patches/server/0459-Add-BlockFailedDispenseEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add BlockFailedDispenseEvent diff --git a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java -index f4510b8e14d0b9997907ce1d1368ba3b3b5daf3e..f4853a5ff8a45efcda2d7781c1fa897c47d8ea46 100644 +index 3d05e71fef8fa70df05311a6a9ddad99994892a6..352f5412fc469a1fde6f14ffcaf00e88613b2704 100644 --- a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java @@ -98,8 +98,10 @@ public class DispenserBlock extends BaseEntityBlock { @@ -20,7 +20,7 @@ index f4510b8e14d0b9997907ce1d1368ba3b3b5daf3e..f4853a5ff8a45efcda2d7781c1fa897c ItemStack itemstack = tileentitydispenser.getItem(i); DispenseItemBehavior idispensebehavior = this.getDispenseMethod(world, itemstack); diff --git a/src/main/java/net/minecraft/world/level/block/DropperBlock.java b/src/main/java/net/minecraft/world/level/block/DropperBlock.java -index a08e8571f3a83afc80c2f1758a9029cd28ed6947..91b514967405115f22edf4255775361a672e5c2f 100644 +index 09e5ff5a0270cb88f3505a28c07ef816f18ac23b..3e09d4b11c881b9c7d3447df379286238076cfee 100644 --- a/src/main/java/net/minecraft/world/level/block/DropperBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DropperBlock.java @@ -60,6 +60,7 @@ public class DropperBlock extends DispenserBlock { diff --git a/patches/server/0473-Add-BlockPreDispenseEvent.patch b/patches/server/0473-Add-BlockPreDispenseEvent.patch index d280bd07f124..d2ba7470a3d0 100644 --- a/patches/server/0473-Add-BlockPreDispenseEvent.patch +++ b/patches/server/0473-Add-BlockPreDispenseEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add BlockPreDispenseEvent diff --git a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java -index f4853a5ff8a45efcda2d7781c1fa897c47d8ea46..a02f24448b002824b068278fa427003008c0d0f1 100644 +index 352f5412fc469a1fde6f14ffcaf00e88613b2704..9f99a9ec8f8269a0aeee2d6aa68f8a344f5f64b6 100644 --- a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java @@ -107,6 +107,7 @@ public class DispenserBlock extends BaseEntityBlock { @@ -17,7 +17,7 @@ index f4853a5ff8a45efcda2d7781c1fa897c47d8ea46..a02f24448b002824b068278fa4270030 tileentitydispenser.setItem(i, idispensebehavior.dispense(sourceblock, itemstack)); } diff --git a/src/main/java/net/minecraft/world/level/block/DropperBlock.java b/src/main/java/net/minecraft/world/level/block/DropperBlock.java -index 91b514967405115f22edf4255775361a672e5c2f..ddecf443df3679e3098eb54edd19585a0512e342 100644 +index 3e09d4b11c881b9c7d3447df379286238076cfee..1762415720caa722600ab7e81344ee9168e42011 100644 --- a/src/main/java/net/minecraft/world/level/block/DropperBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DropperBlock.java @@ -71,6 +71,7 @@ public class DropperBlock extends DispenserBlock { diff --git a/patches/server/0936-Fix-possible-StackOverflowError-and-NPE-for-some-dis.patch b/patches/server/0936-Fix-possible-StackOverflowError-and-NPE-for-some-dis.patch new file mode 100644 index 000000000000..a4d1c6d91ee6 --- /dev/null +++ b/patches/server/0936-Fix-possible-StackOverflowError-and-NPE-for-some-dis.patch @@ -0,0 +1,309 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 29 Oct 2022 17:02:42 -0700 +Subject: [PATCH] Fix possible StackOverflowError and NPE for some dispenses + +For saddles, carpets, horse armor, and chests for horse-likes +a BlockDispenseEvent handler that always mutated the item without +changing the type would result in a SO error because when it went +to find the replacement dispense behavior (since the item "changed") +it didn't properly handle if the replacement was the same instance +of dispense behavior. + +Additionally equippable mob heads, wither skulls, and carved pumpkins +are subject to the same possible error. + +Furthermore since 1.21.2, the DISPENSER_REGISTRY map doesn't have a default +return value anymore and some dispense behaviors like equippable and +regular items will not have a defined behavior in that map and might throw +a NPE in that case. + +== AT == +public net.minecraft.world.level.block.DispenserBlock getDispenseMethod(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/core/dispenser/DispenseItemBehavior; + +diff --git a/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java +index 36180e80dbd681e68c60e097015dad890a48b574..dff30954e4c588ee4cc79d3f6dab6fb456934d65 100644 +--- a/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java ++++ b/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java +@@ -67,7 +67,7 @@ public class BoatDispenseItemBehavior extends DefaultDispenseItemBehavior { + stack.grow(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { + idispensebehavior.dispense(pointer, eventStack); + return stack; +diff --git a/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java +index 39c96f5db6e90a470404c6387fa0c1d5531822e5..8aae1d113e84dfad9f2b6f0bcd203ca6c68bc5ce 100644 +--- a/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java ++++ b/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java +@@ -101,7 +101,7 @@ public class DefaultDispenseItemBehavior implements DispenseItemBehavior { + if (!dropper && !event.getItem().getType().equals(craftItem.getType())) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(sourceblock, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior.getClass() != DefaultDispenseItemBehavior.class) { + idispensebehavior.dispense(sourceblock, eventStack); + } else { +diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +index 18304349c9ab24657c4152aff800dba969174665..94b2647f69035dce9a3d56b6978e3884e06c5583 100644 +--- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java ++++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +@@ -124,7 +124,7 @@ public interface DispenseItemBehavior { + stack.grow(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { + idispensebehavior.dispense(pointer, eventStack); + return stack; +@@ -178,7 +178,7 @@ public interface DispenseItemBehavior { + stack.grow(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { + idispensebehavior.dispense(pointer, eventStack); + return stack; +@@ -231,8 +231,8 @@ public interface DispenseItemBehavior { + stack.grow(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); +- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE) { ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior ++ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE && idispensebehavior != this) { // Paper - fix possible StackOverflowError + idispensebehavior.dispense(pointer, eventStack); + return stack; + } +@@ -282,8 +282,8 @@ public interface DispenseItemBehavior { + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); +- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE) { ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior ++ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE && idispensebehavior != this) { // Paper - fix possible StackOverflowError + idispensebehavior.dispense(pointer, eventStack); + return stack; + } +@@ -352,7 +352,7 @@ public interface DispenseItemBehavior { + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { + idispensebehavior.dispense(pointer, eventStack); + return stack; +@@ -414,7 +414,7 @@ public interface DispenseItemBehavior { + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { + idispensebehavior.dispense(pointer, eventStack); + return stack; +@@ -452,7 +452,7 @@ public interface DispenseItemBehavior { + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { + idispensebehavior.dispense(pointer, eventStack); + return stack; +@@ -514,7 +514,7 @@ public interface DispenseItemBehavior { + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { + idispensebehavior.dispense(pointer, eventStack); + return stack; +@@ -585,7 +585,7 @@ public interface DispenseItemBehavior { + stack.grow(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { + idispensebehavior.dispense(pointer, eventStack); + return stack; +@@ -625,7 +625,7 @@ public interface DispenseItemBehavior { + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { + idispensebehavior.dispense(pointer, eventStack); + return stack; +@@ -645,7 +645,7 @@ public interface DispenseItemBehavior { + stack.shrink(1); + this.setSuccess(true); + } else { +- this.setSuccess(EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack)); ++ this.setSuccess(EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack, this)); // Paper - fix possible StackOverflowError + } + + return stack; +@@ -674,7 +674,7 @@ public interface DispenseItemBehavior { + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { + idispensebehavior.dispense(pointer, eventStack); + return stack; +@@ -691,7 +691,7 @@ public interface DispenseItemBehavior { + stack.shrink(1); + this.setSuccess(true); + } else { +- this.setSuccess(EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack)); ++ this.setSuccess(EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack, this)); // Paper - fix possible StackOverflowError + } + + return stack; +@@ -736,7 +736,7 @@ public interface DispenseItemBehavior { + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { + idispensebehavior.dispense(pointer, eventStack); + return stack; +@@ -818,8 +818,8 @@ public interface DispenseItemBehavior { + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); +- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE) { ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior ++ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE && idispensebehavior != this) { // Paper - fix possible StackOverflowError + idispensebehavior.dispense(pointer, eventStack); + return stack; + } +diff --git a/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java +index a03cc350973fda213251cad273a2db86f438904b..a43ea83dbbd5946096cdde31af766674bda6c3be 100644 +--- a/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java ++++ b/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java +@@ -23,10 +23,15 @@ public class EquipmentDispenseItemBehavior extends DefaultDispenseItemBehavior { + + @Override + protected ItemStack execute(BlockSource pointer, ItemStack stack) { +- return EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack) ? stack : super.execute(pointer, stack); ++ return EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack, this) ? stack : super.execute(pointer, stack); // Paper - fix possible StackOverflowError + } + +- public static boolean dispenseEquipment(BlockSource pointer, ItemStack stack) { ++ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper ++ public static boolean dispenseEquipment(BlockSource pointer, ItemStack armor) { ++ // Paper start ++ return dispenseEquipment(pointer, armor, null); ++ } ++ public static boolean dispenseEquipment(BlockSource pointer, ItemStack stack, @javax.annotation.Nullable DispenseItemBehavior currentBehavior) { + BlockPos blockposition = pointer.pos().relative((Direction) pointer.state().getValue(DispenserBlock.FACING)); + List list = pointer.level().getEntitiesOfClass(LivingEntity.class, new AABB(blockposition), (entityliving) -> { + return entityliving.canEquipWithDispenser(stack); +@@ -58,8 +63,8 @@ public class EquipmentDispenseItemBehavior extends DefaultDispenseItemBehavior { + stack.grow(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); +- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE) { ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior ++ if (idispensebehavior != DispenseItemBehavior.NOOP && (currentBehavior == null || idispensebehavior != currentBehavior)) { // Paper - fix possible StackOverflowError + idispensebehavior.dispense(pointer, eventStack); + return true; + } +diff --git a/src/main/java/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java +index f2e19218cf0d3b44a617c7d74f782c3e15e3f07f..aae9ec8f3bd39685b37251bef3f9ac846d65c192 100644 +--- a/src/main/java/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java ++++ b/src/main/java/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java +@@ -87,7 +87,7 @@ public class MinecartDispenseItemBehavior extends DefaultDispenseItemBehavior { + stack.grow(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { + idispensebehavior.dispense(pointer, eventStack); + return stack; +diff --git a/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java b/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java +index a9d230d6ff22d5e3a11b2f31e7d751f44888a12c..aba0ddfc5009a11b6c5cba95a90479083643bdad 100644 +--- a/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java ++++ b/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java +@@ -57,7 +57,7 @@ public class ProjectileDispenseBehavior extends DefaultDispenseItemBehavior { + stack.grow(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { + idispensebehavior.dispense(pointer, eventStack); + return stack; +diff --git a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java +index f5206e4176f58cff4cfe70c94f014afebc98c589..afad4fa3ca1a3186c4569ea073f776dac16817e1 100644 +--- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java ++++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java +@@ -52,7 +52,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior { + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { + idispensebehavior.dispense(pointer, eventStack); + return stack; +diff --git a/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java +index f84987c36a16df19286d6f1badfb1ffb9cc7e770..cc85e96035f7cb2e6493b1cc4748031171d7dbee 100644 +--- a/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java ++++ b/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java +@@ -48,7 +48,7 @@ public class ShulkerBoxDispenseBehavior extends OptionalDispenseItemBehavior { + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { + idispensebehavior.dispense(pointer, eventStack); + return stack; +diff --git a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java +index 9f99a9ec8f8269a0aeee2d6aa68f8a344f5f64b6..716d1a98775d7338a121af9fd0868a65e2c28288 100644 +--- a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java +@@ -116,6 +116,12 @@ public class DispenserBlock extends BaseEntityBlock { + } + } + ++ // Paper start - Fix NPE with equippable and items without behavior ++ public static DispenseItemBehavior getDispenseBehavior(BlockSource pointer, ItemStack stack) { ++ return ((DispenserBlock) pointer.state().getBlock()).getDispenseMethod(pointer.level(), stack); ++ } ++ // Paper end - Fix NPE with equippable and items without behavior ++ + public DispenseItemBehavior getDispenseMethod(Level world, ItemStack stack) { + if (!stack.isItemEnabled(world.enabledFeatures())) { + return DispenserBlock.DEFAULT_BEHAVIOR; +diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +index 96b901d07718d8926a2175925e867b4417c3947c..418e67ef5896325fe143501f5a4f1604b065ba0f 100644 +--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java ++++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +@@ -2232,7 +2232,7 @@ public class CraftEventFactory { + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); +- net.minecraft.core.dispenser.DispenseItemBehavior itemBehavior = net.minecraft.world.level.block.DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ net.minecraft.core.dispenser.DispenseItemBehavior itemBehavior = net.minecraft.world.level.block.DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior + if (itemBehavior != net.minecraft.core.dispenser.DispenseItemBehavior.NOOP && itemBehavior != instance) { + itemBehavior.dispense(pointer, eventStack); + return itemStack; diff --git a/patches/server/0936-Fix-possible-StackOverflowError-for-some-dispenses.patch b/patches/server/0936-Fix-possible-StackOverflowError-for-some-dispenses.patch deleted file mode 100644 index 7e0fabb39a2a..000000000000 --- a/patches/server/0936-Fix-possible-StackOverflowError-for-some-dispenses.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sat, 29 Oct 2022 17:02:42 -0700 -Subject: [PATCH] Fix possible StackOverflowError for some dispenses - -For saddles, carpets, horse armor, and chests for horse-likes -a BlockDispenseEvent handler that always mutated the item without -changing the type would result in a SO error because when it went -to find the replacement dispense behavior (since the item "changed") -it didn't properly handle if the replacement was the same instance -of dispense behavior. - -Additionally equippable mob heads, wither skulls, and carved pumpkins -are subject to the same possible error. - -diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -index 18304349c9ab24657c4152aff800dba969174665..63b8c806b6ee0ea3cc5e6a7f613b5e57c94bfcf1 100644 ---- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -+++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -232,7 +232,7 @@ public interface DispenseItemBehavior { - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE) { -+ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE && idispensebehavior != this) { // Paper - fix possible StackOverflowError - idispensebehavior.dispense(pointer, eventStack); - return stack; - } -@@ -283,7 +283,7 @@ public interface DispenseItemBehavior { - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE) { -+ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE && idispensebehavior != this) { // Paper - fix possible StackOverflowError - idispensebehavior.dispense(pointer, eventStack); - return stack; - } -@@ -645,7 +645,7 @@ public interface DispenseItemBehavior { - stack.shrink(1); - this.setSuccess(true); - } else { -- this.setSuccess(EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack)); -+ this.setSuccess(EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack, this)); // Paper - fix possible StackOverflowError - } - - return stack; -@@ -691,7 +691,7 @@ public interface DispenseItemBehavior { - stack.shrink(1); - this.setSuccess(true); - } else { -- this.setSuccess(EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack)); -+ this.setSuccess(EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack, this)); // Paper - fix possible StackOverflowError - } - - return stack; -@@ -819,7 +819,7 @@ public interface DispenseItemBehavior { - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE) { -+ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE && idispensebehavior != this) { // Paper - fix possible StackOverflowError - idispensebehavior.dispense(pointer, eventStack); - return stack; - } -diff --git a/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java -index a03cc350973fda213251cad273a2db86f438904b..036dd3b15dfee4cd079710eba1255d2bdb4d7220 100644 ---- a/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java -+++ b/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java -@@ -23,10 +23,15 @@ public class EquipmentDispenseItemBehavior extends DefaultDispenseItemBehavior { - - @Override - protected ItemStack execute(BlockSource pointer, ItemStack stack) { -- return EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack) ? stack : super.execute(pointer, stack); -+ return EquipmentDispenseItemBehavior.dispenseEquipment(pointer, stack, null) ? stack : super.execute(pointer, stack); // Paper - fix possible StackOverflowError - } - -- public static boolean dispenseEquipment(BlockSource pointer, ItemStack stack) { -+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper -+ public static boolean dispenseEquipment(BlockSource pointer, ItemStack armor) { -+ // Paper start -+ return dispenseEquipment(pointer, armor, null); -+ } -+ public static boolean dispenseEquipment(BlockSource pointer, ItemStack stack, @javax.annotation.Nullable DispenseItemBehavior currentBehavior) { - BlockPos blockposition = pointer.pos().relative((Direction) pointer.state().getValue(DispenserBlock.FACING)); - List list = pointer.level().getEntitiesOfClass(LivingEntity.class, new AABB(blockposition), (entityliving) -> { - return entityliving.canEquipWithDispenser(stack); -@@ -59,7 +64,7 @@ public class EquipmentDispenseItemBehavior extends DefaultDispenseItemBehavior { - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -- if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE) { -+ if (idispensebehavior != DispenseItemBehavior.NOOP && (currentBehavior == null || idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE)) { // Paper - fix possible StackOverflowError - idispensebehavior.dispense(pointer, eventStack); - return true; - } diff --git a/patches/server/0940-Properly-track-the-changed-item-from-dispense-events.patch b/patches/server/0940-Properly-track-the-changed-item-from-dispense-events.patch index 3885b9f8a228..d653a24df563 100644 --- a/patches/server/0940-Properly-track-the-changed-item-from-dispense-events.patch +++ b/patches/server/0940-Properly-track-the-changed-item-from-dispense-events.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Properly track the changed item from dispense events diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -index 63b8c806b6ee0ea3cc5e6a7f613b5e57c94bfcf1..cd77e86ff289634d2dd1c56002e569ff70d15f25 100644 +index 94b2647f69035dce9a3d56b6978e3884e06c5583..a09b089565f9167e1a2d53116ae879d9f868342e 100644 --- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java @@ -129,10 +129,14 @@ public interface DispenseItemBehavior { @@ -72,7 +72,7 @@ index 63b8c806b6ee0ea3cc5e6a7f613b5e57c94bfcf1..cd77e86ff289634d2dd1c56002e569ff } else { return this.defaultDispenseItemBehavior.dispense(pointer, stack); diff --git a/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java b/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java -index a9d230d6ff22d5e3a11b2f31e7d751f44888a12c..af222679d0d44d24b2b10455eb52fa8a797ca28a 100644 +index aba0ddfc5009a11b6c5cba95a90479083643bdad..b341792b694e4d6d7ca98061976b8857d83c4233 100644 --- a/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java @@ -64,7 +64,7 @@ public class ProjectileDispenseBehavior extends DefaultDispenseItemBehavior { @@ -85,7 +85,7 @@ index a9d230d6ff22d5e3a11b2f31e7d751f44888a12c..af222679d0d44d24b2b10455eb52fa8a // itemstack.shrink(1); // CraftBukkit - Handled during event processing // CraftBukkit end diff --git a/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java -index f84987c36a16df19286d6f1badfb1ffb9cc7e770..8e089f7d5e7fa9ddeccd0691185555f279d55426 100644 +index cc85e96035f7cb2e6493b1cc4748031171d7dbee..16b435216dc7c6a3f8c1c0f9e2323e6afb3a6cb9 100644 --- a/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java @@ -57,7 +57,12 @@ public class ShulkerBoxDispenseBehavior extends OptionalDispenseItemBehavior { diff --git a/patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch b/patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch index ef4efc0ef7b6..262b84900d43 100644 --- a/patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch +++ b/patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch @@ -7,7 +7,7 @@ Affect the falling stalactite damage type where the reduction is not applied like in Vanilla diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 96b901d07718d8926a2175925e867b4417c3947c..6c60bb4f4d1133844a4232df518c062216847fdc 100644 +index 418e67ef5896325fe143501f5a4f1604b065ba0f..1e98f68e51618606f1178c12be77c1a945362630 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -1226,7 +1226,7 @@ public class CraftEventFactory { diff --git a/patches/server/1017-Fix-InventoryOpenEvent-cancellation.patch b/patches/server/1017-Fix-InventoryOpenEvent-cancellation.patch index 6f31e5f36371..05ec9a126664 100644 --- a/patches/server/1017-Fix-InventoryOpenEvent-cancellation.patch +++ b/patches/server/1017-Fix-InventoryOpenEvent-cancellation.patch @@ -183,7 +183,7 @@ index 673a92d383db463b5c4e2ac3a4ecbd7e97c15c6d..6a2123cd808fa79f3cdb1cb56632d29b return InteractionResult.SUCCESS; diff --git a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java -index a02f24448b002824b068278fa427003008c0d0f1..0427d590912561cb4f0354715e4ac513e53b3eb3 100644 +index 716d1a98775d7338a121af9fd0868a65e2c28288..b2243e883388d1c12480e470c391bb97b993b77d 100644 --- a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java @@ -80,8 +80,9 @@ public class DispenserBlock extends BaseEntityBlock { From f8f230a0d0e8cdff82be2b10bce947adfe4f0f2d Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sun, 27 Oct 2024 11:26:21 -0700 Subject: [PATCH 101/119] Remove unnecessary AT --- patches/server/0459-Add-BlockFailedDispenseEvent.patch | 4 ++-- patches/server/0473-Add-BlockPreDispenseEvent.patch | 4 ++-- ...-possible-StackOverflowError-and-NPE-for-some-dis.patch | 7 ++----- .../server/1017-Fix-InventoryOpenEvent-cancellation.patch | 2 +- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/patches/server/0459-Add-BlockFailedDispenseEvent.patch b/patches/server/0459-Add-BlockFailedDispenseEvent.patch index c0dc74c0fe16..ee65c26c996d 100644 --- a/patches/server/0459-Add-BlockFailedDispenseEvent.patch +++ b/patches/server/0459-Add-BlockFailedDispenseEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add BlockFailedDispenseEvent diff --git a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java -index 3d05e71fef8fa70df05311a6a9ddad99994892a6..352f5412fc469a1fde6f14ffcaf00e88613b2704 100644 +index f4510b8e14d0b9997907ce1d1368ba3b3b5daf3e..f4853a5ff8a45efcda2d7781c1fa897c47d8ea46 100644 --- a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java @@ -98,8 +98,10 @@ public class DispenserBlock extends BaseEntityBlock { @@ -20,7 +20,7 @@ index 3d05e71fef8fa70df05311a6a9ddad99994892a6..352f5412fc469a1fde6f14ffcaf00e88 ItemStack itemstack = tileentitydispenser.getItem(i); DispenseItemBehavior idispensebehavior = this.getDispenseMethod(world, itemstack); diff --git a/src/main/java/net/minecraft/world/level/block/DropperBlock.java b/src/main/java/net/minecraft/world/level/block/DropperBlock.java -index 09e5ff5a0270cb88f3505a28c07ef816f18ac23b..3e09d4b11c881b9c7d3447df379286238076cfee 100644 +index a08e8571f3a83afc80c2f1758a9029cd28ed6947..91b514967405115f22edf4255775361a672e5c2f 100644 --- a/src/main/java/net/minecraft/world/level/block/DropperBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DropperBlock.java @@ -60,6 +60,7 @@ public class DropperBlock extends DispenserBlock { diff --git a/patches/server/0473-Add-BlockPreDispenseEvent.patch b/patches/server/0473-Add-BlockPreDispenseEvent.patch index d2ba7470a3d0..d280bd07f124 100644 --- a/patches/server/0473-Add-BlockPreDispenseEvent.patch +++ b/patches/server/0473-Add-BlockPreDispenseEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add BlockPreDispenseEvent diff --git a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java -index 352f5412fc469a1fde6f14ffcaf00e88613b2704..9f99a9ec8f8269a0aeee2d6aa68f8a344f5f64b6 100644 +index f4853a5ff8a45efcda2d7781c1fa897c47d8ea46..a02f24448b002824b068278fa427003008c0d0f1 100644 --- a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java @@ -107,6 +107,7 @@ public class DispenserBlock extends BaseEntityBlock { @@ -17,7 +17,7 @@ index 352f5412fc469a1fde6f14ffcaf00e88613b2704..9f99a9ec8f8269a0aeee2d6aa68f8a34 tileentitydispenser.setItem(i, idispensebehavior.dispense(sourceblock, itemstack)); } diff --git a/src/main/java/net/minecraft/world/level/block/DropperBlock.java b/src/main/java/net/minecraft/world/level/block/DropperBlock.java -index 3e09d4b11c881b9c7d3447df379286238076cfee..1762415720caa722600ab7e81344ee9168e42011 100644 +index 91b514967405115f22edf4255775361a672e5c2f..ddecf443df3679e3098eb54edd19585a0512e342 100644 --- a/src/main/java/net/minecraft/world/level/block/DropperBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DropperBlock.java @@ -71,6 +71,7 @@ public class DropperBlock extends DispenserBlock { diff --git a/patches/server/0936-Fix-possible-StackOverflowError-and-NPE-for-some-dis.patch b/patches/server/0936-Fix-possible-StackOverflowError-and-NPE-for-some-dis.patch index a4d1c6d91ee6..20702237808a 100644 --- a/patches/server/0936-Fix-possible-StackOverflowError-and-NPE-for-some-dis.patch +++ b/patches/server/0936-Fix-possible-StackOverflowError-and-NPE-for-some-dis.patch @@ -18,9 +18,6 @@ return value anymore and some dispense behaviors like equippable and regular items will not have a defined behavior in that map and might throw a NPE in that case. -== AT == -public net.minecraft.world.level.block.DispenserBlock getDispenseMethod(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/core/dispenser/DispenseItemBehavior; - diff --git a/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java index 36180e80dbd681e68c60e097015dad890a48b574..dff30954e4c588ee4cc79d3f6dab6fb456934d65 100644 --- a/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java @@ -278,7 +275,7 @@ index f84987c36a16df19286d6f1badfb1ffb9cc7e770..cc85e96035f7cb2e6493b1cc47480311 idispensebehavior.dispense(pointer, eventStack); return stack; diff --git a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java -index 9f99a9ec8f8269a0aeee2d6aa68f8a344f5f64b6..716d1a98775d7338a121af9fd0868a65e2c28288 100644 +index a02f24448b002824b068278fa427003008c0d0f1..500c56c4ef0878434582a50d6dba2ccca9773275 100644 --- a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java @@ -116,6 +116,12 @@ public class DispenserBlock extends BaseEntityBlock { @@ -291,7 +288,7 @@ index 9f99a9ec8f8269a0aeee2d6aa68f8a344f5f64b6..716d1a98775d7338a121af9fd0868a65 + } + // Paper end - Fix NPE with equippable and items without behavior + - public DispenseItemBehavior getDispenseMethod(Level world, ItemStack stack) { + protected DispenseItemBehavior getDispenseMethod(Level world, ItemStack stack) { if (!stack.isItemEnabled(world.enabledFeatures())) { return DispenserBlock.DEFAULT_BEHAVIOR; diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java diff --git a/patches/server/1017-Fix-InventoryOpenEvent-cancellation.patch b/patches/server/1017-Fix-InventoryOpenEvent-cancellation.patch index 05ec9a126664..e63b2489a903 100644 --- a/patches/server/1017-Fix-InventoryOpenEvent-cancellation.patch +++ b/patches/server/1017-Fix-InventoryOpenEvent-cancellation.patch @@ -183,7 +183,7 @@ index 673a92d383db463b5c4e2ac3a4ecbd7e97c15c6d..6a2123cd808fa79f3cdb1cb56632d29b return InteractionResult.SUCCESS; diff --git a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java -index 716d1a98775d7338a121af9fd0868a65e2c28288..b2243e883388d1c12480e470c391bb97b993b77d 100644 +index 500c56c4ef0878434582a50d6dba2ccca9773275..5a6c153fa2873aecba0d0d02be2cc2a514f445e3 100644 --- a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java @@ -80,8 +80,9 @@ public class DispenserBlock extends BaseEntityBlock { From 29bf7beba9a16467abc7d901d92c08130c18a9f5 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sun, 27 Oct 2024 12:09:27 -0700 Subject: [PATCH 102/119] Fix unused parameter in PlayerList#remove --- ...-Fix-kick-event-leave-message-not-being-sent.patch | 11 ++++++++++- patches/server/0566-Add-PlayerSetSpawnEvent.patch | 2 +- patches/server/0639-Validate-usernames.patch | 2 +- .../0665-Force-close-world-loading-screen.patch | 2 +- ...name-instead-of-display-name-in-PlayerList-g.patch | 2 +- patches/server/0739-Fix-a-bunch-of-vanilla-bugs.patch | 2 +- ...Use-single-player-info-update-packet-on-join.patch | 2 +- .../0835-Folia-scheduler-and-owned-region-API.patch | 2 +- .../0844-API-for-updating-recipes-on-clients.patch | 2 +- patches/server/0854-Add-Listing-API-for-Player.patch | 2 +- patches/server/0979-Anti-Xray.patch | 2 +- .../0981-Optimize-Collision-to-not-load-chunks.patch | 2 +- patches/server/0992-Properly-resend-entities.patch | 2 +- .../server/1038-Moonrise-optimisation-patches.patch | 2 +- patches/server/1042-Improved-Watchdog-Support.patch | 2 +- .../1048-Incremental-chunk-and-player-saving.patch | 2 +- 16 files changed, 25 insertions(+), 16 deletions(-) diff --git a/patches/server/0558-Fix-kick-event-leave-message-not-being-sent.patch b/patches/server/0558-Fix-kick-event-leave-message-not-being-sent.patch index 170b51853dbb..8334a5dd25a5 100644 --- a/patches/server/0558-Fix-kick-event-leave-message-not-being-sent.patch +++ b/patches/server/0558-Fix-kick-event-leave-message-not-being-sent.patch @@ -101,7 +101,7 @@ index e48c6f37ba0ebe698e28042e9331ab2ec0c39e7c..0229b3e6c27b142ff726de8e2e15104a 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 e6b92f085291aaf4fa78d96f8379aeef2200592b..adba2f7632df2e876c22ebe3a5232d93f6581282 100644 +index e6b92f085291aaf4fa78d96f8379aeef2200592b..2c810cb5d2fcf1a88423cfe4e063dd810ecaaeb0 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -510,6 +510,11 @@ public abstract class PlayerList { @@ -116,3 +116,12 @@ index e6b92f085291aaf4fa78d96f8379aeef2200592b..adba2f7632df2e876c22ebe3a5232d93 ServerLevel worldserver = entityplayer.serverLevel(); entityplayer.awardStat(Stats.LEAVE_GAME); +@@ -520,7 +525,7 @@ public abstract class PlayerList { + entityplayer.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DISCONNECT); // Paper - Inventory close reason + } + +- 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() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName())), entityplayer.quitReason); // Paper - Adventure & Add API for quit reason ++ PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(entityplayer.getBukkitEntity(), leaveMessage, entityplayer.quitReason); // Paper - Adventure & Add API for quit reason + this.cserver.getPluginManager().callEvent(playerQuitEvent); + entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage()); + diff --git a/patches/server/0566-Add-PlayerSetSpawnEvent.patch b/patches/server/0566-Add-PlayerSetSpawnEvent.patch index d290efd76669..e6b0fc435a7f 100644 --- a/patches/server/0566-Add-PlayerSetSpawnEvent.patch +++ b/patches/server/0566-Add-PlayerSetSpawnEvent.patch @@ -154,7 +154,7 @@ index 94cc69ed1ccbcfcc8f431762fef641c313b2f634..c680b311760601bb539d685bceddba67 public SectionPos getLastSectionPos() { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index adba2f7632df2e876c22ebe3a5232d93f6581282..dd7b19a7762b91a8b27717098cebd2c48cb96f68 100644 +index 2c810cb5d2fcf1a88423cfe4e063dd810ecaaeb0..a62858d3cd83358f2356c15fc102b99c41969a74 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -802,7 +802,7 @@ public abstract class PlayerList { diff --git a/patches/server/0639-Validate-usernames.patch b/patches/server/0639-Validate-usernames.patch index 89dbf3385d26..1845ec8d6014 100644 --- a/patches/server/0639-Validate-usernames.patch +++ b/patches/server/0639-Validate-usernames.patch @@ -32,7 +32,7 @@ index 1e4b288f20153ce0c91fabf164c5c8320c90ba7d..cb5dd77892283a1aaec45434fb99bb7f 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 dd7b19a7762b91a8b27717098cebd2c48cb96f68..2497aeb46ff4188948e9253c21d83a218fd73e85 100644 +index a62858d3cd83358f2356c15fc102b99c41969a74..bb301d1ce9c1792ead2681c9f3d38bb2079b0112 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -627,7 +627,7 @@ public abstract class PlayerList { diff --git a/patches/server/0665-Force-close-world-loading-screen.patch b/patches/server/0665-Force-close-world-loading-screen.patch index 481f82aff5e7..376fbf1282cc 100644 --- a/patches/server/0665-Force-close-world-loading-screen.patch +++ b/patches/server/0665-Force-close-world-loading-screen.patch @@ -10,7 +10,7 @@ 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 2497aeb46ff4188948e9253c21d83a218fd73e85..f1530fbcaf9913e43143b40117fb7fe63b326d1d 100644 +index bb301d1ce9c1792ead2681c9f3d38bb2079b0112..11f86e1b119d20f668e67b83f09137dcb24d4bf1 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -406,6 +406,16 @@ public abstract class PlayerList { diff --git a/patches/server/0685-Use-username-instead-of-display-name-in-PlayerList-g.patch b/patches/server/0685-Use-username-instead-of-display-name-in-PlayerList-g.patch index 5603d7b000bc..3cb43bf44945 100644 --- a/patches/server/0685-Use-username-instead-of-display-name-in-PlayerList-g.patch +++ b/patches/server/0685-Use-username-instead-of-display-name-in-PlayerList-g.patch @@ -6,7 +6,7 @@ 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 f1530fbcaf9913e43143b40117fb7fe63b326d1d..3d741bd09cd2086aa63b77636fe3ecfc55577aad 100644 +index 11f86e1b119d20f668e67b83f09137dcb24d4bf1..6409463c9834a660f2a2e2b6bbfac8b3beb80db7 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -1352,7 +1352,7 @@ public abstract class PlayerList { diff --git a/patches/server/0739-Fix-a-bunch-of-vanilla-bugs.patch b/patches/server/0739-Fix-a-bunch-of-vanilla-bugs.patch index 93ef32db8ae1..ddd8b7606308 100644 --- a/patches/server/0739-Fix-a-bunch-of-vanilla-bugs.patch +++ b/patches/server/0739-Fix-a-bunch-of-vanilla-bugs.patch @@ -143,7 +143,7 @@ index b48966424fb8e937552c0e7bffaedaefc63ef77f..79eceb995f92b3f3d7b695dc6d2a0a4a MutableComponent ichatmutablecomponent1 = Component.translatable("build.tooHigh", i).withStyle(ChatFormatting.RED); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 3d741bd09cd2086aa63b77636fe3ecfc55577aad..6332d5e281bb355bee1a112d11e96ee26e337ebf 100644 +index 6409463c9834a660f2a2e2b6bbfac8b3beb80db7..9b01ef9e9b00274f1213c006a4cad0f75e412e13 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -260,7 +260,7 @@ public abstract class PlayerList { diff --git a/patches/server/0781-Use-single-player-info-update-packet-on-join.patch b/patches/server/0781-Use-single-player-info-update-packet-on-join.patch index c1e89be3e8fe..271efab27a44 100644 --- a/patches/server/0781-Use-single-player-info-update-packet-on-join.patch +++ b/patches/server/0781-Use-single-player-info-update-packet-on-join.patch @@ -18,7 +18,7 @@ index af8a513c2692b71ad56abce24048b61eb78d41c4..5802bca38fdeccbc1353990ecb425034 } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 6332d5e281bb355bee1a112d11e96ee26e337ebf..af0ea5b5bbc35cced959beb3ecb576fff46c6a51 100644 +index 9b01ef9e9b00274f1213c006a4cad0f75e412e13..cbba549176b3acfc25ec42c2935b31ab2176e0fa 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -364,6 +364,7 @@ public abstract class PlayerList { diff --git a/patches/server/0835-Folia-scheduler-and-owned-region-API.patch b/patches/server/0835-Folia-scheduler-and-owned-region-API.patch index fe1d592753d3..3ff79fb2c604 100644 --- a/patches/server/0835-Folia-scheduler-and-owned-region-API.patch +++ b/patches/server/0835-Folia-scheduler-and-owned-region-API.patch @@ -1173,7 +1173,7 @@ index 8f7a808b0c89953a7f2932e68e2c85f9330469f2..be188079f12b3f7b394ae91db62cc17b gameprofilerfiller.push("commandFunctions"); this.getFunctions().tick(); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index af0ea5b5bbc35cced959beb3ecb576fff46c6a51..74cbc6092d49f573f7fab1895c42a0360bb80bdf 100644 +index cbba549176b3acfc25ec42c2935b31ab2176e0fa..4ac0bb0ec3222ebdd3fa386696dcb0723dc162a4 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -597,6 +597,7 @@ public abstract class PlayerList { diff --git a/patches/server/0844-API-for-updating-recipes-on-clients.patch b/patches/server/0844-API-for-updating-recipes-on-clients.patch index 28b0572357f8..bda5ca5713ff 100644 --- a/patches/server/0844-API-for-updating-recipes-on-clients.patch +++ b/patches/server/0844-API-for-updating-recipes-on-clients.patch @@ -5,7 +5,7 @@ Subject: [PATCH] API for updating recipes on clients diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 74cbc6092d49f573f7fab1895c42a0360bb80bdf..db19a2483f37fb3554f86577e44162f6fe29592a 100644 +index 4ac0bb0ec3222ebdd3fa386696dcb0723dc162a4..d92fb522d88a790d9cea2e6c4edad30bb73298fc 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -1448,6 +1448,13 @@ public abstract class PlayerList { diff --git a/patches/server/0854-Add-Listing-API-for-Player.patch b/patches/server/0854-Add-Listing-API-for-Player.patch index a4116283404c..3a1a36d29ae2 100644 --- a/patches/server/0854-Add-Listing-API-for-Player.patch +++ b/patches/server/0854-Add-Listing-API-for-Player.patch @@ -85,7 +85,7 @@ index 29b465fc1dc50e0e84ddb889c5303e80fe662874..4d67d98257b2cb9045d03c999cfd4ba2 static class EntryBuilder { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index db19a2483f37fb3554f86577e44162f6fe29592a..409010fae4b175ba7dcbe0f38676022ed9b77b1d 100644 +index d92fb522d88a790d9cea2e6c4edad30bb73298fc..a20e5f896cfbd0a3e60b741562194e30257449c1 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -362,14 +362,22 @@ public abstract class PlayerList { diff --git a/patches/server/0979-Anti-Xray.patch b/patches/server/0979-Anti-Xray.patch index 6164bec6d871..45f4e9200984 100644 --- a/patches/server/0979-Anti-Xray.patch +++ b/patches/server/0979-Anti-Xray.patch @@ -1157,7 +1157,7 @@ index cdd66e6ce96e2613afe7f06ca8da3cfaa6704b2d..dafa2cf7d3c49fc5bdcd68d2a9528127 if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) { new io.papermc.paper.event.packet.PlayerChunkLoadEvent(new org.bukkit.craftbukkit.CraftChunk(chunk), handler.getPlayer().getBukkitEntity()).callEvent(); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 409010fae4b175ba7dcbe0f38676022ed9b77b1d..781de82a8bee2836bf154341c91f23b34d98d4ad 100644 +index a20e5f896cfbd0a3e60b741562194e30257449c1..7097d87dead028c8dd44cefc97694bada93f608b 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -426,7 +426,7 @@ public abstract class PlayerList { diff --git a/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch b/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch index 327fd5c6c2c2..27b03b47bf0c 100644 --- a/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch +++ b/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch @@ -14,7 +14,7 @@ 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 781de82a8bee2836bf154341c91f23b34d98d4ad..661498e404bd1b0e4857e159b79a3eeca6df1d8a 100644 +index 7097d87dead028c8dd44cefc97694bada93f608b..751fc4b0fe60c6d26ea0f768f3d66031a4bad963 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -826,6 +826,7 @@ public abstract class PlayerList { diff --git a/patches/server/0992-Properly-resend-entities.patch b/patches/server/0992-Properly-resend-entities.patch index 85cf1b2bdec2..3b68910eac57 100644 --- a/patches/server/0992-Properly-resend-entities.patch +++ b/patches/server/0992-Properly-resend-entities.patch @@ -102,7 +102,7 @@ index 52eafd99ed63f5fc9596225cf45175b1287f20a1..e5db85f858ab376b225172e22b92b841 } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 661498e404bd1b0e4857e159b79a3eeca6df1d8a..7fdadac8f3bc3810ae5adeeed2a77c043bb107c3 100644 +index 751fc4b0fe60c6d26ea0f768f3d66031a4bad963..700ab5ef2f8ab1466c4f659cd34679dc809efbaf 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -396,7 +396,7 @@ public abstract class PlayerList { diff --git a/patches/server/1038-Moonrise-optimisation-patches.patch b/patches/server/1038-Moonrise-optimisation-patches.patch index 1e69b3cb33d8..68646b52eb0c 100644 --- a/patches/server/1038-Moonrise-optimisation-patches.patch +++ b/patches/server/1038-Moonrise-optimisation-patches.patch @@ -28026,7 +28026,7 @@ index b7d29389a357f142237cecd75f8ca91cf1eb6b5b..e4b0dc3121101d54394a0c3a413dabf8 this.generatingStep = generationStep; this.cache = chunks; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 7fdadac8f3bc3810ae5adeeed2a77c043bb107c3..296002eafb028e60aaa5d9728cd035f86abe6913 100644 +index 700ab5ef2f8ab1466c4f659cd34679dc809efbaf..b28b23c69512b054e856388f2f94d27d35347b8c 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -1420,7 +1420,7 @@ public abstract class PlayerList { diff --git a/patches/server/1042-Improved-Watchdog-Support.patch b/patches/server/1042-Improved-Watchdog-Support.patch index f272bf52470b..d19dc9a1736f 100644 --- a/patches/server/1042-Improved-Watchdog-Support.patch +++ b/patches/server/1042-Improved-Watchdog-Support.patch @@ -302,7 +302,7 @@ index bf2bae3166df06be240dbbeecce16a24c85897a9..c06863578c5d654706d93e73059d89c1 } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 296002eafb028e60aaa5d9728cd035f86abe6913..60ddba097ba09a5f6a69adafbeabc496a3c2766f 100644 +index b28b23c69512b054e856388f2f94d27d35347b8c..88f40e54fa3b78d82261e06f941ef42587d52c25 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -553,7 +553,7 @@ public abstract class PlayerList { diff --git a/patches/server/1048-Incremental-chunk-and-player-saving.patch b/patches/server/1048-Incremental-chunk-and-player-saving.patch index 09e62595a7ec..32dfa5f3fa6b 100644 --- a/patches/server/1048-Incremental-chunk-and-player-saving.patch +++ b/patches/server/1048-Incremental-chunk-and-player-saving.patch @@ -97,7 +97,7 @@ index 8ceeebb561046933cba0725e15732fa074226884..8c9148426f23cbbdfaf7ae66657d1a62 private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10; private static final int FLY_STAT_RECORDING_SPEED = 25; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 60ddba097ba09a5f6a69adafbeabc496a3c2766f..d66fb339eb66d340a9cd29cf6032a7bfcfd9d793 100644 +index 88f40e54fa3b78d82261e06f941ef42587d52c25..cf42042c754b30e41c0ec8a6a15195369bdbd199 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -518,6 +518,7 @@ public abstract class PlayerList { From 9e35192360a837e81e669c59e89f1c5c4ab0f2f1 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sun, 27 Oct 2024 14:00:06 -0700 Subject: [PATCH 103/119] Execute spark tasks during tick sleep (#11525) --- patches/server/1046-Bundle-spark.patch | 42 ++++++++++++++++--- ...-Incremental-chunk-and-player-saving.patch | 4 +- .../server/1051-Lag-compensation-ticks.patch | 4 +- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/patches/server/1046-Bundle-spark.patch b/patches/server/1046-Bundle-spark.patch index 8db706fc97ae..312f3bae9c5b 100644 --- a/patches/server/1046-Bundle-spark.patch +++ b/patches/server/1046-Bundle-spark.patch @@ -21,10 +21,10 @@ index 9966576652ed6007d2228237f292c1dc83ede485..9b3a6b336cb1344d4e74e0e4f7c50ffd paperweight { diff --git a/src/main/java/io/papermc/paper/SparksFly.java b/src/main/java/io/papermc/paper/SparksFly.java new file mode 100644 -index 0000000000000000000000000000000000000000..2955b7ec9832a5752ea4aff9fc9d34ae2f9ee83e +index 0000000000000000000000000000000000000000..62e2d5704c348955bc8284dc2d54c933b7bcdd06 --- /dev/null +++ b/src/main/java/io/papermc/paper/SparksFly.java -@@ -0,0 +1,201 @@ +@@ -0,0 +1,211 @@ +package io.papermc.paper; + +import io.papermc.paper.configuration.GlobalConfiguration; @@ -34,6 +34,7 @@ index 0000000000000000000000000000000000000000..2955b7ec9832a5752ea4aff9fc9d34ae +import io.papermc.paper.util.MCUtil; +import java.util.Collection; +import java.util.List; ++import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.logging.Level; +import java.util.logging.Logger; +import me.lucko.spark.paper.api.Compatibility; @@ -59,11 +60,13 @@ index 0000000000000000000000000000000000000000..2955b7ec9832a5752ea4aff9fc9d34ae + + private final Logger logger; + private final PaperSparkModule spark; ++ private final ConcurrentLinkedQueue mainThreadTaskQueue; + + private boolean enabled; + private boolean disabledInConfigurationWarningLogged; + + public SparksFly(final Server server) { ++ this.mainThreadTaskQueue = new ConcurrentLinkedQueue<>(); + this.logger = Logger.getLogger(ID); + this.logger.log(Level.INFO, "This server bundles the spark profiler. For more information please visit https://docs.papermc.io/paper/profiling"); + this.spark = PaperSparkModule.create(Compatibility.VERSION_1_0, server, this.logger, new PaperScheduler() { @@ -74,7 +77,7 @@ index 0000000000000000000000000000000000000000..2955b7ec9832a5752ea4aff9fc9d34ae + + @Override + public void executeSync(final Runnable runnable) { -+ MCUtil.ensureMain(this.catching(runnable, "synchronous")); ++ SparksFly.this.mainThreadTaskQueue.offer(this.catching(runnable, "synchronous")); + } + + private Runnable catching(final Runnable runnable, final String type) { @@ -111,6 +114,13 @@ index 0000000000000000000000000000000000000000..2955b7ec9832a5752ea4aff9fc9d34ae + }); + } + ++ public void executeMainThreadTasks() { ++ Runnable task; ++ while ((task = this.mainThreadTaskQueue.poll()) != null) { ++ task.run(); ++ } ++ } ++ + public void enableEarlyIfRequested() { + if (!isPluginPreferred() && shouldEnableImmediately()) { + this.enable(); @@ -269,7 +279,7 @@ index 6b8ed8a0baaf4a57d20e57cec3400af5561ddd79..48604e7f96adc9e226e034054c5e2bad } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 7a671772760152f26e5bb60ea2f2a7765c017c37..3fc6e7cb5e02792e5e87beb7525cde96bc45df1c 100644 +index 7a671772760152f26e5bb60ea2f2a7765c017c37..8a45960de3fd890991a1c75a103fec1adb03c0cb 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -765,6 +765,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop= j) { ++ this.server.spark.tickStart(); // Paper - spark + if (this.emptyTicks == j) { + MinecraftServer.LOGGER.info("Server empty for {} seconds, pausing", this.pauseWhileEmptySeconds()); + this.autoSave(); + } + + this.server.getScheduler().mainThreadHeartbeat(); // CraftBukkit ++ this.server.spark.executeMainThreadTasks(); // Paper - spark + this.tickConnection(); ++ this.server.spark.tickEnd(((double)(System.nanoTime() - lastTick) / 1000000D)); // Paper - spark + return; } } @@ -305,7 +329,13 @@ index 7a671772760152f26e5bb60ea2f2a7765c017c37..3fc6e7cb5e02792e5e87beb7525cde96 new com.destroystokyo.paper.event.server.ServerTickStartEvent(this.tickCount+1).callEvent(); // Paper - Server Tick Events ++this.tickCount; this.tickRateManager.tick(); -@@ -1660,6 +1665,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); -@@ -1838,6 +1839,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers From e35f199344de61da86c9ee052a059973720862f0 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sun, 27 Oct 2024 18:29:34 -0700 Subject: [PATCH 104/119] Use declaration order for state holder property iteration Mostly an aesthetic change for serialization, should not have any impact on performance or correctness. --- patches/server/1038-Moonrise-optimisation-patches.patch | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/patches/server/1038-Moonrise-optimisation-patches.patch b/patches/server/1038-Moonrise-optimisation-patches.patch index 68646b52eb0c..ed29e35d38f2 100644 --- a/patches/server/1038-Moonrise-optimisation-patches.patch +++ b/patches/server/1038-Moonrise-optimisation-patches.patch @@ -443,7 +443,7 @@ index 0000000000000000000000000000000000000000..01da52b9e8a786824f199a057b62ce04 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java new file mode 100644 -index 0000000000000000000000000000000000000000..b5335a2a8cb5dc7637c7112c8f7193389d726489 +index 0000000000000000000000000000000000000000..866f38eb0f379ffbe2888023a7d1c290f521a231 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java @@ -0,0 +1,230 @@ @@ -458,7 +458,7 @@ index 0000000000000000000000000000000000000000..b5335a2a8cb5dc7637c7112c8f719338 +import it.unimi.dsi.fastutil.objects.ObjectIterator; +import it.unimi.dsi.fastutil.objects.ObjectSet; +import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; -+import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; ++import it.unimi.dsi.fastutil.objects.ReferenceArrayList; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; @@ -476,7 +476,7 @@ index 0000000000000000000000000000000000000000..b5335a2a8cb5dc7637c7112c8f719338 + + public ZeroCollidingReferenceStateTable(final Collection> properties) { + this.propertyToIndexer = new Int2ObjectOpenHashMap<>(properties.size()); -+ this.properties = new ReferenceOpenHashSet<>(properties); ++ this.properties = new ReferenceArrayList<>(properties); + + final List> sortedProperties = new ArrayList<>(properties); + From 6288adb001b71a2f2a0a1866fc406016ada06bb5 Mon Sep 17 00:00:00 2001 From: granny Date: Mon, 28 Oct 2024 00:03:55 -0700 Subject: [PATCH 105/119] Remove leftover missed timings calls (#11527) * remove leftover timings calls * remove unused imports --- .../0956-Brigadier-based-command-API.patch | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/patches/server/0956-Brigadier-based-command-API.patch b/patches/server/0956-Brigadier-based-command-API.patch index a0f076f9b28d..fd34bd975c82 100644 --- a/patches/server/0956-Brigadier-based-command-API.patch +++ b/patches/server/0956-Brigadier-based-command-API.patch @@ -1858,13 +1858,12 @@ index 0000000000000000000000000000000000000000..5eef7ae5197bd395fbd6800530ffe34d +} diff --git a/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java b/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java new file mode 100644 -index 0000000000000000000000000000000000000000..0c3c82b28e581286b798ee58ca4193efc2faff4a +index 0000000000000000000000000000000000000000..1814cd072aaca3e72249f0509a9c3b3cb154eaba --- /dev/null +++ b/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java -@@ -0,0 +1,148 @@ +@@ -0,0 +1,138 @@ +package io.papermc.paper.command.brigadier.bukkit; + -+import co.aikar.timings.Timing; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.RequiredArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; @@ -1875,7 +1874,6 @@ index 0000000000000000000000000000000000000000..0c3c82b28e581286b798ee58ca4193ef +import com.mojang.brigadier.tree.LiteralCommandNode; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import java.util.ArrayList; -+import java.util.Collections; +import net.minecraft.commands.CommandSource; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; @@ -1888,7 +1886,6 @@ index 0000000000000000000000000000000000000000..0c3c82b28e581286b798ee58ca4193ef +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.logging.Level; -+import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.server.TabCompleteEvent; + @@ -1942,18 +1939,11 @@ index 0000000000000000000000000000000000000000..0c3c82b28e581286b798ee58ca4193ef + public int run(CommandContext context) throws CommandSyntaxException { + CommandSender sender = context.getSource().getSender(); + -+ // Plugins do weird things to workaround normal registration -+ if (this.command.timings == null) { -+ this.command.timings = co.aikar.timings.TimingsManager.getCommandTiming(null, this.command); -+ } -+ + String content = context.getRange().get(context.getInput()); + String[] args = org.apache.commons.lang3.StringUtils.split(content, ' '); // fix adjacent spaces (from console/plugins) causing empty array elements + -+ try (Timing ignored = this.command.timings.startTiming()) { -+ // Note: we don't return the result of target.execute as thats success / failure, we return handled (true) or not handled (false) -+ this.command.execute(sender, this.literal, Arrays.copyOfRange(args, 1, args.length)); -+ } ++ // Note: we don't return the result of target.execute as thats success / failure, we return handled (true) or not handled (false) ++ this.command.execute(sender, this.literal, Arrays.copyOfRange(args, 1, args.length)); + + // return true as command was handled + return 1; From 99b1bf9b0f256874fa846e77cfa6bb8d45a5270e Mon Sep 17 00:00:00 2001 From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:14:00 -0400 Subject: [PATCH 106/119] Use new ClientboundPlayerRotationPacket for setting player rotation --- patches/server/0715-More-Teleport-API.patch | 24 +++++++------------ ...stom-Chat-Completion-Suggestions-API.patch | 2 +- .../0745-Elder-Guardian-appearance-API.patch | 4 ++-- .../0757-Add-Player-Warden-Warning-API.patch | 4 ++-- patches/server/0769-fix-Instruments.patch | 2 +- patches/server/0778-Flying-Fall-Damage.patch | 4 ++-- patches/server/0783-Win-Screen-API.patch | 2 +- .../0808-Expand-PlayerItemMendEvent.patch | 4 ++-- patches/server/0827-Fix-BanList-API.patch | 6 ++--- .../server/0846-Bandaid-fix-for-Effect.patch | 2 +- .../0854-Add-Listing-API-for-Player.patch | 6 ++--- ...-Implement-OfflinePlayer-isConnected.patch | 2 +- .../0884-Add-player-idle-duration-API.patch | 4 ++-- ...stack-for-Player-sendEquipmentChange.patch | 2 +- .../0907-Add-experience-points-API.patch | 4 ++-- ...d-API-to-get-player-ha-proxy-address.patch | 2 +- .../1028-Improve-entity-effect-API.patch | 4 ++-- .../1038-Moonrise-optimisation-patches.patch | 8 +++---- .../1039-API-for-checking-sent-chunks.patch | 4 ++-- 19 files changed, 42 insertions(+), 48 deletions(-) diff --git a/patches/server/0715-More-Teleport-API.patch b/patches/server/0715-More-Teleport-API.patch index 7f4fab5c3051..e567640ee1d3 100644 --- a/patches/server/0715-More-Teleport-API.patch +++ b/patches/server/0715-More-Teleport-API.patch @@ -112,24 +112,18 @@ index 4e6afa243d6108cb946a8a7cf96c4036a3c2ac0c..a314e401ee8a306dc12a2d98a3d400ae private final org.bukkit.entity.Entity.Spigot spigot = new org.bukkit.entity.Entity.Spigot() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index fe0c355f8203c9bfa30d2ec48392a5a1a3d616ae..baae7a129853a296273b7f295f58cbb99187da22 100644 +index fe0c355f8203c9bfa30d2ec48392a5a1a3d616ae..4c4b8c14b41816173466232113252ef1ba2bb2ee 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1303,13 +1303,102 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1303,13 +1303,96 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setRotation(float yaw, float pitch) { - throw new UnsupportedOperationException("Cannot set rotation of players. Consider teleporting instead."); + // Paper start - Teleport API -+ Location targetLocation = this.getEyeLocation(); -+ targetLocation.setYaw(yaw); -+ targetLocation.setPitch(pitch); -+ -+ org.bukkit.util.Vector direction = targetLocation.getDirection(); -+ direction.multiply(9999999); // We need to move the target block.. FAR out -+ targetLocation.add(direction); -+ this.lookAt(targetLocation, io.papermc.paper.entity.LookAnchor.EYES); -+ // Paper end ++ if (this.getHandle().connection == null) return; ++ this.getHandle().forceSetRotation(yaw, pitch); ++ // Paper end - Teleportation API } @Override @@ -219,7 +213,7 @@ index fe0c355f8203c9bfa30d2ec48392a5a1a3d616ae..baae7a129853a296273b7f295f58cbb9 location.checkFinite(); ServerPlayer entity = this.getHandle(); -@@ -1322,7 +1411,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1322,7 +1405,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return false; } @@ -228,7 +222,7 @@ index fe0c355f8203c9bfa30d2ec48392a5a1a3d616ae..baae7a129853a296273b7f295f58cbb9 return false; } -@@ -1331,7 +1420,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1331,7 +1414,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // To = Players new Location if Teleport is Successful Location to = location; // Create & Call the Teleport Event. @@ -237,7 +231,7 @@ index fe0c355f8203c9bfa30d2ec48392a5a1a3d616ae..baae7a129853a296273b7f295f58cbb9 this.server.getPluginManager().callEvent(event); // Return False to inform the Plugin that the Teleport was unsuccessful/cancelled. -@@ -1340,7 +1429,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1340,7 +1423,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // If this player is riding another entity, we must dismount before teleporting. @@ -246,7 +240,7 @@ index fe0c355f8203c9bfa30d2ec48392a5a1a3d616ae..baae7a129853a296273b7f295f58cbb9 // SPIGOT-5509: Wakeup, similar to riding if (this.isSleeping()) { -@@ -1356,13 +1445,21 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1356,13 +1439,21 @@ public class CraftPlayer extends CraftHumanEntity implements Player { ServerLevel toWorld = ((CraftWorld) to.getWorld()).getHandle(); // Close any foreign inventory diff --git a/patches/server/0720-Custom-Chat-Completion-Suggestions-API.patch b/patches/server/0720-Custom-Chat-Completion-Suggestions-API.patch index 9908dc279cca..6dba5504c2bb 100644 --- a/patches/server/0720-Custom-Chat-Completion-Suggestions-API.patch +++ b/patches/server/0720-Custom-Chat-Completion-Suggestions-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Custom Chat Completion Suggestions API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index baae7a129853a296273b7f295f58cbb99187da22..58f3ca95b1d79269bed3b6473cd69d8988ede162 100644 +index 4c4b8c14b41816173466232113252ef1ba2bb2ee..2aaf9e87a7322392d713bd869b0bdddae88db7ff 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -708,6 +708,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0745-Elder-Guardian-appearance-API.patch b/patches/server/0745-Elder-Guardian-appearance-API.patch index 772a3c2cd3e9..b7e5065d43d0 100644 --- a/patches/server/0745-Elder-Guardian-appearance-API.patch +++ b/patches/server/0745-Elder-Guardian-appearance-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Elder Guardian appearance API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 58f3ca95b1d79269bed3b6473cd69d8988ede162..667796909ea6b56b93ec591aae1c393ec2f8940a 100644 +index 2aaf9e87a7322392d713bd869b0bdddae88db7ff..dc09ddfb8e695606fe4dfd2594d75ab312ee9b78 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3328,6 +3328,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3322,6 +3322,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end diff --git a/patches/server/0757-Add-Player-Warden-Warning-API.patch b/patches/server/0757-Add-Player-Warden-Warning-API.patch index 2ce951d03613..08e5c3298180 100644 --- a/patches/server/0757-Add-Player-Warden-Warning-API.patch +++ b/patches/server/0757-Add-Player-Warden-Warning-API.patch @@ -10,10 +10,10 @@ public net.minecraft.world.entity.monster.warden.WardenSpawnTracker cooldownTick public net.minecraft.world.entity.monster.warden.WardenSpawnTracker increaseWarningLevel()V diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 667796909ea6b56b93ec591aae1c393ec2f8940a..7ef67f0b5da392fa09a99d1213eefa373aad96b6 100644 +index dc09ddfb8e695606fe4dfd2594d75ab312ee9b78..9f31ea3cb0b5dac2c50be0f51ad002e593d6fb5c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3333,6 +3333,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3327,6 +3327,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void showElderGuardian(boolean silent) { if (getHandle().connection != null) getHandle().connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.GUARDIAN_ELDER_EFFECT, silent ? 0F : 1F)); } diff --git a/patches/server/0769-fix-Instruments.patch b/patches/server/0769-fix-Instruments.patch index ff46175c0f40..cfa8db1be6d9 100644 --- a/patches/server/0769-fix-Instruments.patch +++ b/patches/server/0769-fix-Instruments.patch @@ -6,7 +6,7 @@ Subject: [PATCH] fix Instruments properly handle Player#playNote diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 7ef67f0b5da392fa09a99d1213eefa373aad96b6..f710776d2a81c426cbe75532b06da4f8b1ef4787 100644 +index 9f31ea3cb0b5dac2c50be0f51ad002e593d6fb5c..f41d97bdb046747a6540dc22cbdc322d764f1e0a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -785,7 +785,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0778-Flying-Fall-Damage.patch b/patches/server/0778-Flying-Fall-Damage.patch index a09b209fd2c6..edf295a42023 100644 --- a/patches/server/0778-Flying-Fall-Damage.patch +++ b/patches/server/0778-Flying-Fall-Damage.patch @@ -26,10 +26,10 @@ index 30e0a5fe3f9bd85d2b702c2c877c5682ed35d461..aca888c2f02b09ac6739bdc81b194c45 } else { if (fallDistance >= 2.0F) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index f710776d2a81c426cbe75532b06da4f8b1ef4787..35722608d2c2d702429f5724732e8af39bb37488 100644 +index f41d97bdb046747a6540dc22cbdc322d764f1e0a..3b6bd9a4b3c9767cdc13cda75e0be6d9aed0b672 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2611,6 +2611,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2605,6 +2605,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().onUpdateAbilities(); } diff --git a/patches/server/0783-Win-Screen-API.patch b/patches/server/0783-Win-Screen-API.patch index 8412d997bc15..89c5499a4ee7 100644 --- a/patches/server/0783-Win-Screen-API.patch +++ b/patches/server/0783-Win-Screen-API.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Win Screen API public net.minecraft.server.level.ServerPlayer seenCredits diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 35722608d2c2d702429f5724732e8af39bb37488..83e29f518a57bd2eb4113d5b93cdf47af119c715 100644 +index 3b6bd9a4b3c9767cdc13cda75e0be6d9aed0b672..3419024a58a3c68b160f16350c72d1250c10d4dd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1322,6 +1322,25 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0808-Expand-PlayerItemMendEvent.patch b/patches/server/0808-Expand-PlayerItemMendEvent.patch index 7c61c0095c8d..93c7b9d1e22f 100644 --- a/patches/server/0808-Expand-PlayerItemMendEvent.patch +++ b/patches/server/0808-Expand-PlayerItemMendEvent.patch @@ -30,10 +30,10 @@ index 3a7af27bb1ce0cbe56bd3760cd400083daf98d4c..bf0838f574fa3fb9654e087d602b8d38 if (l > 0) { // this.value = l; // CraftBukkit - update exp value of orb for PlayerItemMendEvent calls // Paper - the value field should not be mutated here because it doesn't take "count" into account diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 83e29f518a57bd2eb4113d5b93cdf47af119c715..0d2fd570463d7ad1b6457a8b14303273b97716dd 100644 +index 3419024a58a3c68b160f16350c72d1250c10d4dd..d48a0d67853fb17cc73bba94c9b6660d2689c8fc 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1883,11 +1883,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1877,11 +1877,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { handle.serverLevel(), itemstack, amount ); int i = Math.min(possibleDurabilityFromXp, itemstack.getDamageValue()); diff --git a/patches/server/0827-Fix-BanList-API.patch b/patches/server/0827-Fix-BanList-API.patch index 1164a2d94969..63be621a49f6 100644 --- a/patches/server/0827-Fix-BanList-API.patch +++ b/patches/server/0827-Fix-BanList-API.patch @@ -208,10 +208,10 @@ index 172202accf4448a933fcf1ff820316c7910dd7f7..50ee7656580d386db473c054f5c5ec57 return null; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 0d2fd570463d7ad1b6457a8b14303273b97716dd..ccf2c23ecf6f406ae07a2d7614d52e65da8ca586 100644 +index d48a0d67853fb17cc73bba94c9b6660d2689c8fc..3ddf3b893605f5763b1f685ad951b1ccdd4a44ce 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1777,23 +1777,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1771,23 +1771,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override @@ -240,7 +240,7 @@ index 0d2fd570463d7ad1b6457a8b14303273b97716dd..ccf2c23ecf6f406ae07a2d7614d52e65 if (kickPlayer) { this.kickPlayer(reason); } -@@ -1801,12 +1801,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1795,12 +1795,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override diff --git a/patches/server/0846-Bandaid-fix-for-Effect.patch b/patches/server/0846-Bandaid-fix-for-Effect.patch index 8c6534f28eff..9d00be010b3d 100644 --- a/patches/server/0846-Bandaid-fix-for-Effect.patch +++ b/patches/server/0846-Bandaid-fix-for-Effect.patch @@ -81,7 +81,7 @@ index c0f5e4497e1ffc93f56fc2b5748bcf76569e8c3a..188bd33f46b6baaa3fc21c9da6fa9a9d // Special case: the axis is optional for ELECTRIC_SPARK Preconditions.checkArgument(effect.getData() == null || effect == Effect.ELECTRIC_SPARK, "Wrong kind of data for the %s effect", effect); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index ccf2c23ecf6f406ae07a2d7614d52e65da8ca586..80877e62d0743891f38abeee5b5b04b4f3bc4010 100644 +index 3ddf3b893605f5763b1f685ad951b1ccdd4a44ce..abb0370243ad95260c5c6034e20097a09415fe00 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -934,7 +934,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0854-Add-Listing-API-for-Player.patch b/patches/server/0854-Add-Listing-API-for-Player.patch index 3a1a36d29ae2..f391783edbbd 100644 --- a/patches/server/0854-Add-Listing-API-for-Player.patch +++ b/patches/server/0854-Add-Listing-API-for-Player.patch @@ -122,7 +122,7 @@ index d92fb522d88a790d9cea2e6c4edad30bb73298fc..a20e5f896cfbd0a3e60b741562194e30 // Paper end - Use single player info update packet on join player.sentListPacket = true; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 80877e62d0743891f38abeee5b5b04b4f3bc4010..1943cb7b691573d3f9755d21d4b5a4210c1cc329 100644 +index abb0370243ad95260c5c6034e20097a09415fe00..47180d44b7e168352b17bc295ffb6d3ea6e0a937 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -206,6 +206,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -133,7 +133,7 @@ index 80877e62d0743891f38abeee5b5b04b4f3bc4010..1943cb7b691573d3f9755d21d4b5a421 private static final WeakHashMap> pluginWeakReferences = new WeakHashMap<>(); private int hash = 0; private double health = 20; -@@ -2122,7 +2123,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2116,7 +2117,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { otherPlayer.setUUID(uuidOverride); } // Paper end @@ -142,7 +142,7 @@ index 80877e62d0743891f38abeee5b5b04b4f3bc4010..1943cb7b691573d3f9755d21d4b5a421 if (original != null) otherPlayer.setUUID(original); // Paper - uuid override } -@@ -2226,6 +2227,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2220,6 +2221,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return (entity != null) ? this.canSee(entity) : false; // If we can't find it, we can't see it } diff --git a/patches/server/0864-Implement-OfflinePlayer-isConnected.patch b/patches/server/0864-Implement-OfflinePlayer-isConnected.patch index ebef6c5101cb..213901ccea20 100644 --- a/patches/server/0864-Implement-OfflinePlayer-isConnected.patch +++ b/patches/server/0864-Implement-OfflinePlayer-isConnected.patch @@ -23,7 +23,7 @@ index 2c2c4db31a746b4eb853dc04c6b3e5631bbfa034..4f4e3ee18d586f61706504218cddc06a public String getName() { Player player = this.getPlayer(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 1943cb7b691573d3f9755d21d4b5a4210c1cc329..3b2d7837486424a2d1759c4ba5d1b1d492e9ec48 100644 +index 47180d44b7e168352b17bc295ffb6d3ea6e0a937..96d8bd55ecfb6aca8a6f65bc2a25e5756eecc4d8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -261,6 +261,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0884-Add-player-idle-duration-API.patch b/patches/server/0884-Add-player-idle-duration-API.patch index 3bf9d659b766..ebbd9c2f34e9 100644 --- a/patches/server/0884-Add-player-idle-duration-API.patch +++ b/patches/server/0884-Add-player-idle-duration-API.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add player idle duration API Implements API for getting and resetting a player's idle duration. diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 3b2d7837486424a2d1759c4ba5d1b1d492e9ec48..b72d6395768a762cd72f2b98bc8cb2598dc286b9 100644 +index 96d8bd55ecfb6aca8a6f65bc2a25e5756eecc4d8..fee7f60d457f34dd46756efc51bf21bd5498d854 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3449,6 +3449,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3443,6 +3443,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end diff --git a/patches/server/0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch b/patches/server/0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch index c5594fd831dd..1569ec7b59b4 100644 --- a/patches/server/0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch +++ b/patches/server/0887-Allow-null-itemstack-for-Player-sendEquipmentChange.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Allow null itemstack for Player#sendEquipmentChange diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index b72d6395768a762cd72f2b98bc8cb2598dc286b9..542c2d85da9695da0f8cc5c34f2e3c0b925dfb7c 100644 +index fee7f60d457f34dd46756efc51bf21bd5498d854..90df4f4a70b416b2d750f3d2063a68848bd38085 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1144,7 +1144,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0907-Add-experience-points-API.patch b/patches/server/0907-Add-experience-points-API.patch index 1b8c5e9d3f3c..333f2cdfbf5a 100644 --- a/patches/server/0907-Add-experience-points-API.patch +++ b/patches/server/0907-Add-experience-points-API.patch @@ -18,10 +18,10 @@ index aca888c2f02b09ac6739bdc81b194c4527dd69f5..a19a795deaa7f46c92b97912e2ade006 // Paper start - send while respecting visibility private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 542c2d85da9695da0f8cc5c34f2e3c0b925dfb7c..0a3d44ac5bfe252854377011ac363d52991c15ed 100644 +index 90df4f4a70b416b2d750f3d2063a68848bd38085..933390c4244200dc1be5311a174e5df95f6ac633 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1951,6 +1951,49 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1945,6 +1945,49 @@ public class CraftPlayer extends CraftHumanEntity implements Player { Preconditions.checkArgument(exp >= 0, "Total experience points must not be negative (%s)", exp); this.getHandle().totalExperience = exp; } diff --git a/patches/server/0952-Added-API-to-get-player-ha-proxy-address.patch b/patches/server/0952-Added-API-to-get-player-ha-proxy-address.patch index 1871d148106a..02a74b9639a1 100644 --- a/patches/server/0952-Added-API-to-get-player-ha-proxy-address.patch +++ b/patches/server/0952-Added-API-to-get-player-ha-proxy-address.patch @@ -35,7 +35,7 @@ index c62df32af11636ad408b584fcc590590ce4fb0d0..baed0bb80d44973f9323bbe536551182 } else { super.channelRead(ctx, msg); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 0a3d44ac5bfe252854377011ac363d52991c15ed..72b9bffb12ef94d029c9502be90fb8c1bd37a4d1 100644 +index 933390c4244200dc1be5311a174e5df95f6ac633..e1e73e877dfef5bcf30a99b275ececbf42f59c95 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -270,7 +270,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/1028-Improve-entity-effect-API.patch b/patches/server/1028-Improve-entity-effect-API.patch index 6599dd255e85..eeec7bf075f8 100644 --- a/patches/server/1028-Improve-entity-effect-API.patch +++ b/patches/server/1028-Improve-entity-effect-API.patch @@ -25,7 +25,7 @@ index b0e49ad831f1ebc6b126bf82c5fddaebffb91312..179886dcbda29c5cdb7dbd43e44951ae + // Paper end - broadcast hurt animation } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 72b9bffb12ef94d029c9502be90fb8c1bd37a4d1..d5dc7ecb9c4dddfd2c92d89b27c15512a0822b08 100644 +index e1e73e877dfef5bcf30a99b275ececbf42f59c95..4eb2cd3f75e8e727199193dc8b1c01d4c855223c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1294,6 +1294,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -49,7 +49,7 @@ index 72b9bffb12ef94d029c9502be90fb8c1bd37a4d1..d5dc7ecb9c4dddfd2c92d89b27c15512 } @Override -@@ -3548,4 +3553,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3542,4 +3547,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void setSendViewDistance(final int viewDistance) { throw new UnsupportedOperationException("Not implemented yet"); } diff --git a/patches/server/1038-Moonrise-optimisation-patches.patch b/patches/server/1038-Moonrise-optimisation-patches.patch index ed29e35d38f2..f7408d9d931a 100644 --- a/patches/server/1038-Moonrise-optimisation-patches.patch +++ b/patches/server/1038-Moonrise-optimisation-patches.patch @@ -36127,10 +36127,10 @@ index 6dc3fc701d1e16a51d99f934ea3dc192363a6762..2058671a77cac4cfa6494461a5142aba // Paper start - implement pointers diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index d5dc7ecb9c4dddfd2c92d89b27c15512a0822b08..ed29e06422aa5e73adfaf9578cda3dfc5777f64c 100644 +index 4eb2cd3f75e8e727199193dc8b1c01d4c855223c..f071e5cf0bf05e12fb922eb1cd70c7bb4a3cf486 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3531,7 +3531,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3525,7 +3525,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setViewDistance(final int viewDistance) { @@ -36141,7 +36141,7 @@ index d5dc7ecb9c4dddfd2c92d89b27c15512a0822b08..ed29e06422aa5e73adfaf9578cda3dfc } @Override -@@ -3541,7 +3543,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3535,7 +3537,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setSimulationDistance(final int simulationDistance) { @@ -36152,7 +36152,7 @@ index d5dc7ecb9c4dddfd2c92d89b27c15512a0822b08..ed29e06422aa5e73adfaf9578cda3dfc } @Override -@@ -3551,7 +3555,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3545,7 +3549,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setSendViewDistance(final int viewDistance) { diff --git a/patches/server/1039-API-for-checking-sent-chunks.patch b/patches/server/1039-API-for-checking-sent-chunks.patch index 7f0201844b96..51cfc8602fbc 100644 --- a/patches/server/1039-API-for-checking-sent-chunks.patch +++ b/patches/server/1039-API-for-checking-sent-chunks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] API for checking sent chunks diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index ed29e06422aa5e73adfaf9578cda3dfc5777f64c..550e175c7fec97818644933a4e4f7805e54d7d5f 100644 +index f071e5cf0bf05e12fb922eb1cd70c7bb4a3cf486..9e4c416ddeccff87ea9ed5b45a2ef04eae2280bf 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3518,6 +3518,35 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3512,6 +3512,35 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end From 40211a0ba010c7fb5cff09a39b10a5749d62c395 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:17:48 -0700 Subject: [PATCH 107/119] Update Gradle wrapper to 8.10.2 --- gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 5 ++++- gradlew.bat | 2 ++ 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f3d4ba8a0da8d277868979cfbc8ad796..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch delta 12612 zcmY+pRa6|n(lttO3GVLh?(Xh3xVuAe26uONcL=V5;I6?T_zdn2`Oi5I_gl9gx~lft zRjVKRp?B~8Wyrx5$mS3|py!Njy{0Wt4i%@s8v88pK z6fPNA45)|*9+*w5kcg$o)}2g}%JfXe6l9ig4T8ia3Hlw#3f^fAKW63%<~GZJd-0YA z9YjleCs~#Y?V+`#nr+49hhsr$K$k!lg}AZDw@>2j=f7t~5IW6#K|lAX7|^N}lJ)I!km`nrwx> z))1Es16__aXGVzQM0EC8xH+O!nqTFBg9Ci{NwRK*CP<6s`Gq(~#lqb(zOlh6ZDBK* zr$|NDj^s6VanrKa+QC;5>twePaexqRI%RO~OY075y?NN90I|f^(P# zF=b>fZ73b5JzD`#GC3lTQ_B3lMeBWgQUGYnFw*HQC}^z{$6G4j(n4y-pRxPT(d2Wgb%vCH(?+t&Pj z)QM`zc`U`+<~D+9E{4Uj2kc#*6eZMU$4Oj6QMfA^K!rbl`iBix=2sPrs7j@aqIrE zTaZJ2M09>rp$mgyUZ!r2$UK{+DGqgl`n;*qFF~M(r#eh`T{MO?2&j?xgr8FU$u3-` zhRDc_I23LL4)K&xg$^&l-W=!Jp-P(_Ie07q>Je;QLxi8LaEc%;WIacJD_T69egF?7 z;I_Sg_!+qrur8$Hq4grigaiVF>U7uWJ@Hkd&%kmFnQN-P^fq0gB1|uRt!U#X;DnlV zo?yHWTw7g5B;#xxY`adhi4yZn@f(7-Xa(J6S=#d@&rlFw!qfvholE>MEb|VWn^g}G zMSrK&zQ^vDId&ojL!{%{o7?s{7;{+u%L{|tar(gp?Uxq3p?xAysB>0E$eG#$tvkk9 z2Q2gEP17{U6@UD*v({5MP-CTZfvWMItVjb4c;i~WLq&{?Q1(koX&vt7+$z}10{^Id z{KDjGi0JpD7@;~odF__0m|p;5rIrHidOP9^mwKe#-&JX-X@acc)06G{LO1Wu)#gvZ za~y9(fhA%UwkDOVU1LBJ`0ROE z4&)dJKK%mG@+CIm?+wt9f~@xIMr8}UH*K1j| z0pppo{7gv3v{URwxVMeg>Ps!L5IKxm zjac2egjgb0vH5i75$s|sY_RYec#>faqJk|AGgV;v=^%BM(^p{p;(^SVt-88G9f!q; z>p}9E4^f0=01S2pQBE4}9YqE%TV)*hlU^8k9{&=K76+*Ax^r=AkBb%OCP^P2nm0Ri z;D-|Zk?gGeU<12ti2CnPVNA(Pb)02+r|&yTWW-OJO7 zNLb0pps6aN?A~NJp5kj{{IOlf!5KWMleV@-hYLift)D>-7K+tgs=7Ake}oBnIy-y1 z(Hn@Hjw=_(x>dO5ysQsrnE%A*bk0K<-j{1Yqz@#n#jOL^AzCr#wR|WYzqk6i7v)Lf zkXdKxzuu20aP{Tbg$(+9&oh7cd(Uoqqf<#ujb$q4sZ~gxFbQfS zS)kNklyL*{2AELgjZ(LBu*>S(oH5AaJ;YiB@;l@=O%F6B?oanzoYRM^fQ9-<~^=3$H0g^JPMLQo@SZ@QuNvy)tyJ)LSj`+()#fy?{aV4Yg^7dlQ7AQM^3GLCR2dAFR zJjtfKiVqF`l-H_fz0HD|9g>)pOxn}k!vdZ=DO!7Sikm{Z%P6BrRkBS6W?ZB5W&7rT z@uYpf@M@a!z7H&o@-yrcCL^Ff3e7p3T`R9p?@o-acXmbTSa0>ZANzCSgovsd%;i$| zVus`not!oL#(W`L-!9w0jdaECaG4hk{V7IOs676ZquZH~0TX5hDq|)x z6T497l|E?f4)LA>j=S8}b$0LS=I4h|hUFJYJODT8Li@#6kF$k0)@*l{RnM1HQ%?VT ze-Pqlc!~t(oumVC*?5fwR;P6u{tHaZ~*LlD;B)4f? z?lpWfa2P@)g57flVl83Ej%P`2)gGyaPjhvD(%i~{`2b>#3!+y&` z!2nuwHMFA-zUY}f1^0B8<`N)Gr=A4TS@b1qykmd0Pq{?r)+1^^+D(=xasb^Tf!oK9 zBLL+*p6M_#ufgLzgq1zcSwZsZnQWFLC3`Yxdg-2=*tT`J9nrfYt)RF)YryBf8_gW{ zvKbB+oZLehfT)S#<|y1)E0hW^?+AnqPXq9Hu;v3dsMGdr{SVyF63;K<8VcgI#~}1i zLYSBL0K;RTT(;>2x=*!1Di9w0mwr;`CN}kM65|Ay{~z}_^JKOsRaN<~#9O^iiW<5P zYN7r~HV!#Nz~IZU`P>1Xe%4f~K}KcF#X&5kO*G}-)74S*tQ8CietdPcA1Yl;S=Mr# z`#MYY!{s^uo=jn7;k6O%(}fN+*0cWMpt~#n9DR<3NyU?+3D^AgI}S)Cu-Tljg`VY} zX1=fq$?8$DtOeGxE6f8lbS_6Q3C4+LDTO$}_IpM$Xv<|QSC%+Oll^q$y`7o@jD{dp zNDl|&X)r7wETa-#h*d`KXntxI(Y{vLha{$0i7@G8xx^m=c<{lJ9?p-i!^W{%j7-oo z0W^SzZ^(Wkyz*We{lEn%Yhu-ycUOHtrRiVJL4~&S91*D0MrLu}Q>v-Mc?GcWfpyz% zX|UvcN@krFO#@v|CtYM}g|=L3%aMo$E5<@CM%c*;?u>LOTz00@+dt1{yg1y=$h+{|D17U}$*^fE^H&8b431EUE z<9tv0V_#%#&1N#j7AKCj!tTK@J%oFW*ESW<(#Gl#Xs%v<@AitI?s92nLzm<)w3Wkkom1f$gcdUi%g_*jofy&}N#luL<$GVIe{iQkQ)sIHVy zBgItnPBFamrv6Kb{eE($Q(f`ZPeW!Hm%Y@F*OF1sKB{Yy|C>WEv_mfvv-N-jh)B-5 z4a!1WcT@9a+hGaBrc~sz=>G?Q!*Zp^JFRUvBMyNR1;`)j$RhH$6gEyVKhd$&K-CFT zXaWC-Y=fyOnqT84iMn9o5oLEOI(_3fk!W^8-74|q1QhQ|CmT0i=b;6Z3u?E{p7V{? z;f#Q-33!L+4&QQcZ~GAqu$NS{M;u%`+#9=7^Oa5PKvCCCWNG_~l(CidS!+xr-*gg{ z$UQ`_1tLT_9jB=Hckkwu>G{s0b0F4bnR7GibmHo?>TR&<3?D;5Fb#gd8*wYa$$~ar z7epl1qM)L{kwiNjQk}?)CFpNTd?0wAOUZ|gC{Ub|c-7h~+Rm(JbdoRe!RNVBQi!M8 z+~U6E2X&KSA*T6KJvsqwqZl#1&==Dm(#b^&VAKQ>7ygv*Fyr;)q9*^F@dCTg2g!w~ z%hg)UXAUyIpIbLXJv1nZX+a_C)BOH2hUim|>=JHCRf(!dtTidb&*~I!JrfRe+PO>w z@ox$G2a3i9d_N9J=|2$y2m-P&#PTNwe!oLBZFs;z|F5kXvBDn<)WwE0E3$ow=zg3R zK(9;sf0t;VEV3@gAg7jRtnj%-6O@!Hvg*;XcUAw}!=2*aErvB(eQIm(-UGmq^J=XN zTqJo$Y|WKo^HlBF3BXJrA#}7ZLg=r*w`I*~Ix`o&2k8^(0mt8Rp=A>F`&gehhp@Jy z^e^#B2!~$LvNCKugg)8)-G%&THdk~kfextilegP9?#C#()F59U$&eo(h|5>ceo*Em z{PEE79T$YP|Kr7K`WBHbtQwyxFkCl6xX&+oUf90B5xoi3_5KHHCyEE*oPbOQkfMz& z6^hT8_NXd2iWk{q9IKae1{_7hMPH8I7_BMtVOM4 z6jm?E0QJOn$qrgsJ`9w##GB9?G})-GXSQo6(tYS(Q0-Ct$co?Zzl0?NHsDRron?;_ zZZgQg)%XW>P?8_&zoGuF(>Och2kEJXsu1_X&~w87x!b z>~h!a>e7{`p@+#hXF88wI*JeWRZ;J4ev4<}HWf|Z;(7$E!S5l9wzBHFe>^I{2`a;a)QnAwa2xv1e(bq$<}!8o^ofGvYpk7dBR+`*%iE;hUY5 zaHF}OjGO9r*{%lmcK^uFiTHgoUD`^9Nx@~;Bg!V* zuuJ&ti{DQiq7RyJAR94wem{}cPK1J(Yxnn_{=>?USqz-~&QXRStS^s-7TksZ$AEI! z#og36s3JGtGU{CnDHRFtipFqvrE*gw7_K@NN0h+ItTq@4fqN!HeQU1y7*X?9+IfZT4Vxebpt z%#VzgdDK~-&+=Z*#>=n#XUhNvBZp3=Cr41jMqwJkHLf3L7Vm~V#GgJ(Jpii~PmJ#s zA7Ft!{xD@z>9DUb4JbiUBdNEcU4BO$651iN*mp*f)HbRRM`Cx5cR?5IfEcU{IZWwf zz(M6CDv)>xa3x}K6%tP^i15P1&&DOLK=k~+jNR$UK3frSl+|PjSC-dBItvD~LL! z>_g(YYdO4k(5EbPOw+v+;G7~jYm>F@Ai|o`gs%F)F8tDz$dl7Q%aCe|v|$UkAul_R zNlA-beBX^IJU?kgS`E$it7nF4DaI!SJAGq)2P&Few(-|tp z?K+%D3e4{pfkayrcbm0ftu6Ol2ZzdKM+4i!hNP3NRL`EvvZJ3yvNr2MV%igZ4kj``Qrdb_OI$7jWP z;l0DYf&0(-*QcP5zrP`HVznW+SbH63Qx$7_9~NjRNg7eKqI!UJ=XH`g^=t8GiFTu( z?2L{JKEu%jJx&XjNzU(*!ZNmL1@RlJA0G$2_LrAb_7lmjil(GSlSM zwTes`m+3R;3#N~Xg#9owh3ycXV8@ZlaY_16kpPFA={721b~URO4HD3sp%fmkZM}k) zZB0#)kP=RkNB~R-MCk8aljG_bagt4vIb~8)BV%(b8_;)&Kf9GX+%O_cNG|(D$!3&D zL(I8}*LqN5NntipFlN13=`D>6!{D@CFMBH0kW3=HccJV+xW~|$qeFR5i-2{X+iWMu zI2$gepQ)H_B%ip_BlWOQ*|pErXs|4ir{IHccgaIJ84irE{?+$KDABXr&f`jB^V-c% z$$u`uU1YB^{<+UN2cNg#7&0bz@yF?5>j|;)5&IV3wIQp58X#OE-M^$HdyvL|Um5t? zhZlAG!Mz%XkUe3t471JM*Yur}o30vzu6RN7gJyNcf!IItsDO730mcJ*O!~V``y5=3 zNJGp34DZ}wd1H6V`Uuy%es>BiO_aE-S8jzir#$& zyk)@2a5tP$@g%jW^b^JGdo)X@Q%sE`^lDQmY9m%uDFpPX`w9%=yQ+nneMm#OaXcD` z9}{tn5A2b2z9783vL2_jSao?uxJhWJoq%47*RafM4o0@gY(p)F>qT4^XM5GLzV#6j zC+HoGhAne7o_w{WUo(B++z7lU3Y0k1rYv9|TSv0vR-Du(5=VakbbelgZTeDn+a_Wv zq_j-^+Qz1WAl;Zg>ahX|CERbX1V%B!hTKN?M}fGoA07M(WU&NfT&TmN`P@56U2 z^)vLDs|Ln~0iTtn-?KTeQl@T&bskJFuTUS!m+$CS9vnd}8(UMO|Kv6TCfGN9NUu&4 zL{)GTxPq>fwsJ~aU=4Qhuq8*RzDsP(LZh$BHezq&9gK$IS<|DYbm})$QTGCS6T;Dr zEkLct!b+#<1r9OKG@P!f1wm8>=Nz!7OzJm!g<+`?N3;YaA3(P@EL=(sTaRMDD!c8=-XN^4BXp(eVkj$NmEMYPP>YJ4bJ3yUud z<3BeJAJ$6z^TuywnfH5lv#$lgwraNw{IV=tIznPH1DT`v-5yS=!)J<}xxl}uZf9azA2A97Haf!;<3y01hlw?dWNEv@TLi1s-mO4vmIT%O_42nS z$VRWrs9NngqRRkWAnWkn%`Rw@?wH|)7XL`EL5EZu$qyJW31&CB^T_)qwIv!{;E_6 zo-9XAryQRlk-O0>o#-SZO>|6OYq;}<*>Wu1AsVRiXY4f8qb;+sItv3AyS!4Ry+q}) zA!pAB|BmC;=RIOk^^vlsEH(!Q!7_1FK~ZB2err*o!+b(r=m1b?$6d!%zmN+69LXnT z&gRmM+n_R-F@sT*IYv0_mGPvur!u`iWbQO7SqiGFLeY&yga zf`lM&B74FA2C?N@8_z652fjhBEoDUKbP8hL{0{HAF%qDo7)o3=3rg#6)T7%%5^wl% z9R0*S*<~>nzYOdQk2l`9h#t+gJy_xujw6xjV(8S<_DbVg61&pT%Hi42l%D73G?adn znB%UdNM0p}lEF-P2%TAMam2zpQev71e>a$$%i+r~b+D9G9pF|oY_*(-u*89oKsXLY+UIbqq)MQ%(GYS{(*n_S_*RN$*~`zUtab%0aKwhx znc)Yo?{xq1sJCgQD)TeTci1ucvbez9q=A72H(-SB18Kl&6^vHV8^i!p@>iF!DIw17 z+8Q)TNisB7>pwyww4y)yJx*wX6SJO78eLBC-ar1+k$Z9fy;wBD|3kzI{<+l*>PSY^ z_?nLOZaeWbU@C3hfK?X;Di*8CHCPkx2qco6(ZyJdqSzp^TJ_5Lpa0UP{Gy+!b0Lr% z@xYxSjUKoY6L#>$qx~KD$-0=|OF7zhVP~ntMgEALYPIfhj@+ z!;JJ7te>CcovruwHsJH6Lta$nm|%^C@=V-rmhU{+I~0(|XHQ9jt@L7pb{gx#{4r!) zg($FyFTslcgu(~6lYr$nW?)%*l#VJ=R-jxK(x=t1bWlu(nL66T#qj%3aZ@uVhy}Co zDU_q61DD5FqqJ*#c|(M5tV)XBN?Ac^12*q)VN4yKPJ|#==S_`_QD9|0ls!`2)SwuHDRA_OfXQDq3%qW&MZB}Z!=k-9xqev8jHz(H z{^D@cIB~QiK>~wa)A&^Ll^Wi6QgCzU;iv-BHsLBs zH7=jN%|>0S`SjP%M&AF1PNVDp_FZ?2Bm@7`DC&v(pYrw!!yD#4 z6+<=HS0Ln6MhoKxF<%~H`y20{vf#pxh=;j{zY381gvAFekgG|>G1zo8$&az{V=;JR zy_puF4$L$?EMhT?;TpQoR*j16ll`#AS4e96C}yp_aGKkBe?1H|k_;gG-~Xorc<;lI zkB}fB{$c-D2mGA&{rm<*@F5)c3X+6??g~XoEwuzSuch0D@W~P5(2I8v8F$c2$Vw51 zP#YLSBDqtWW^EYBl^QYHF+MA7am6f4DOhwnJM=W9$uvMOsZ%_~?)2C#wb?CkI$7{K zEi)=#|5pFvg^){zK5kpBLjB2kZ+$ZB|L=W|aNwyyb(gC2l7bcpx{E-H@)q6@D6N^xh`{1E%ItF2$eeB_SjI@b2WgTpS1thwg&n`jiIzw^TtXUyB{00($GIq>vbj|}bav}}Q_~wp3>k8!E@hVC;OMUTu|= zAy#vXH*GrUHu7^cNZWe1>y;2(51js9wbu+R3Aa*(wzH9+X0dIsf&gc_x|_LP z>~CF^?(~U}+l~ehe|i>?4eo!xkq&Lk+RR-1duNP#o~>@1x)s&i&u zRaYL@+D&_M|JLI6fHbEr_`U;HgPTh#E3?sB)A$*gqyBgg*ql|a-m*TX5rACbWKCE6 zdeQ`v8m6>g^ugv`p|HY^#1QZrGGUj0^HVDc@{?Q0yhalbBEV{+|HzC^-{&e{5K%z9 z6Bxtnfu1!@Mp+Q&*&~;FOg&*Vm<@4b;{FG0-!UUXX!|)1w}op!B_|7_s~d(+=9Gba zKp8`LaB4D(H=cGcspJ_TjYaOwMb=sGn^gtUVhK!UI~2KKYEE-NC}F>+BEY7IVvy%KRvm00tg!Q`y=er}wpEetX}K@;}(}{s9AzV#q2@ zBy7}->|N?13POrs`;U?(qAG(I$~Gt+Rgw%aNZ_0fs_utVvRJT-7z4!@x36v@=NBX=IqkK{#Kg0w48de@?#Yb4M(Svj5=T+<ONr8-oh7l?Cji@+erqur zFhZ=9|Lk=$`c}v4u`)-!!UI=!9Jo@h&7p4RlS#u! zZ7-prn75JkV?VjptX;@$#`U`{vB!=Z?V`T*FBF>J?vsML7e6@2GbUteMFfX-TUu{2 zLNIG*;dV)8GV8gAgEf#)X3A>p3^CRka1v?~8x^anBhQ=L=LsOl=&pcOYHo98m##ye z34MtGCDK!`ptl?taGMr5q{!zVc? zG00e){TV?`YA9eB;(lA3lXI?RrB4BYQGk?vOmTIUJED=(`_*gtn2DB-t4WW54as*W zb2kD-lWX>lb$+W!VFakki>B^Vc+u$?NLF>)!U%b@Y}gYJ>m2H=^x0=nsE0TF^Yu0h ztgH8-o1%+jCk(+&`|)tTfEVHq0cMeFa{Uz)X$;fCq%Y=SOWML6bYfeP8j5hktL`KK z(18`XrUn&WN9PtFxh&dX`y~YBsmdhi7Kw%tKzM%^VEhdD<_XkulW-x=JN6OPbFI4@ zzDDRN+f=@{0h*MswwOqG6gJ?{NuHx(y-|FUGsxyZ*x0~$MW(eY>vqq4Fh#t7uzw=- zKB?|!0N~!h^AMdLa)oR!Ca#HZ9&Zf)ghuO<^RN)4twRlygHnQG(BE{cDc5E}OF4;xss6gYyV~EcJvJkX)xNWb=@yw!uq0v-sf^rvkp-;?DPWK@*SEw|V;IH=7 zfQqEV_>DjOPT~8X*J|H8=&RnzK4~S7ML~nLX^%s-Vqc^aWy7N$y57qciZGcqy#=zU zs8hcHiI=D$+RB{|62{ohCTiaML6FI4Uhzo5D{Jik@poCs0w7F)*w}F4r0sJ~#u-72 z5bK=ANt=M$Dh5NKnxGsg9NRR?WD-x|FhTwBjd zD<-K>44DB~i%frJOfnzh1R>PRY34kw!6~p3M$JLaD1r@`=h)~Ngks-(gdXh^Q?BTP zZ^Zj5w1AwtuR2$~E7s9iZdF}z%pv1em^V2rM{1tLUY@-+Sc0(9jA|iZWml1;v13=U zHf?y@#mb--7z6$ue>`qjhE~brk$AY-RG90~5wcBbDReXR2)pKg{L>;H(DI`U!MLNQ zY9rFJP@ZQ}jlcMh%WSCo%vf+nd0Gmd*F%KMIe>slCUh)8Ma|;M_I+v#;|ueg9oLg; zq2HtZX%&#F7vdpNlkX?}(C7dGC^y#NB#m4%69RzTNrk%4ol~hSI%>2r6B|*ZkW(*P z;u#s;+faHo{tfy+1L^RzWDi*^JR0iY(zJDB36y_QJ+|E-2x+cY z!V8uLNktH~q>WQZuY!Ap66WP|E!0PA1jK~)^8oJVGbspJs6QL!!-5Qm7 zHYI|_`Actg?vDzdg5{86w@GS$G6ANzff7->6i5pB$T4O}`fZ_;{217Om0gN5zTr12 z5mW{hCzCE-QubjxN$TAE-XgI-8dTY@OZmq`y+y_>dk*(qXF0{nam|q@~i}Utp*k{yurq(DW54hkDT4bbg z=_etM?Nf5W^o-HEu9_?&xEqPg^P^mTxLH8n%u$!mWvFG|{&)jtnU&6|5-`~eaNz0%D1BDo`{ zS1N5(KW5v^2eLdd_%`uaRndF@h0Uo6=M|8?b~KbOLZk{HXEnGmtgZXf2inI*1r%n! zQ3&%RI4r{f&dwW~HwH0Ked9b!k6{>_19H z_Ai>5IChDMY(FfMyG%;30?SQ{iV9KyGru62+Y)~qSQ91}b~}w<&*}R&1c#$O`H@~c z5)2S_eXx}M#N{MuGeQS9@#UJB@;W_j50b}jIhxMPloEFQZdvwxiU^RYycTzgK)-vl3LT&$L8~@68$C8~5_U{cR$E#w*x65(qw&eoL@>%ZHvj zWnEMlSh*(o&oy|J7eJ5OD`ssy%F?*Vp?`Cq;FShyl{ZoKCG5g{y}>usznni#8ki(i zO{w@n{iAj1_ooX@+s*!uW60WcH~*bNOT6z%0jVML5};wVrQp~`Uss_{cO2oud_nNA8^B$?07fJ6?iI)Q zuo9G)O-z)DqstrBqf>B%S05hf-wep0@$BFHKSrkZ{za3D)yVzRz)2{wf8(Wp+xyAM z$rtyx$gi3A=V~V!`Q3;BM0$>*VVtxEM|xDL^gew7ydy3Q6YzD&THRz*q33Ms_D;M- zbCx1Ft#UNB)V3bf`~{ImI72OTp^|bF8?G8#FRj+Biy8ET5#rA3sd|0FR@U(LAJ%w8 zS1%n8Z=Amhw)92rIsof=YVWF4jw&F*j1LG@-`+cR0-~2LqXRH8(Ccne{y#MCPncF64U`0uO zWmi$dlii~1D0rLR{qc|_2M!C$t8^=G7xQY)9!#Y331A|>N)EhmyVdLWL9I3YLJ`7? zZmpqUJB>Ni9oiL)^1IK1UoMyhWE{$9M2M6Xi zPKk7GpMsA6vjZbU7~i+u|J6Nk|Ci!Y3UMUT2|`M;JsNQACdJ%ooo9Yt{?A+0hMpxi znEa~~sxC>rKrU6bd=WRb;%wsH>A#j4{({&1GYSNR57Gama(3)2A;SM>qop}l>Jk2* zn1+C$fIxuwzg3mCU#SOqb-wOCb6mBcYlA5+mt<&_J~sBxc(GQtBFINUO~Mr7<-uu($>P HJ4oML2Lo<@i8BwbL^1~GkG`E7C$SEa_ zF^}Ea+#Je`Xy6;#D0FPnSrR%Y!QGA~NA^{oWmW8C<3dr{x6wWQ{4+bzemqV5W$i5~ z=J0jXZ>uZb>DT@0Ks?4QJ{`z?8JWl3$y;2pj#$XP*pv$>$g(z43{YH9KmmR6<#sIn zA`#=0#sgycaBQ^&}Xba!|KaZ8~b30v~nLt z9%#gz_*=~KD{3t^X~l>480*}PhKN=??g`RV|4Ud{Gyyl187MJ}r(#e+H$GEdI+p1s zq_25h;fV)$EPK%Dw-(G=f`yHB-_tttsC!?k7*#!|4a>`Ahj8nm?&n>NRs%jkZW^3-0P_yMP5&*6a26{MRj1&TPF zyE#|c)5uUHzMWx=rMKpuPih*V=S;W3MzIZTw2uTbr}8`p2bm+Z6Sa%vvWAWSf4H)p(+ zSQ8;EvUa#wqWV+9vmIio(%7wukK2SwjUS8Yl%Rq%=~PU)2$Tvm6`1!r3H@U#_|bB0 zmlT1PS3wPB(b&^+@YY7Y$n4l3mV3-X0$>z|gZp6O*Lhzn&?Gad2ZCF;+#95-Y?#y+ z?*l@Yf=a4w{Px=o!N|3~_XKfk&G;fN>Ps&dp2FpA~qD=0~=!NOS@B#XAKKkND>Y{4>rqxrViKD7;?>j8`R` z&G)3FN|dfsxnaI^!d1G%=>AbTTxZWo;n-DLrQ!sj=f~VAOe5zhGS(dgx|!ls62fbX zV@<7Ck^!}R=`Swr?(7w1rY6Nmq~sfXJ?TiKJLn=&SQdEt9$@0 zA+h1Wbwbri0s-stc8yVq;mRa6@kEf8^KXUz&jcic!+avDvvJFa>k0ioWug=T3oPw; zyj4it&0@>_*uI@2=^+T7sL1_!^aJW@Xfo8aC#3^WtQC7fET8b9C} z*u^ue6Ojn z7@(eskJ2+cNnH9~VyfIh<-|7!je~vGy*odz(sk-u$~SrYF3glruZ*W`{sqnS+9=;Z zh{D@MSG91%lr&ua8%$sJF%y1I<|e;EdfJykY8#D$Hc_81n5`$7;1N|b0tvvPLzSg& zn7!5x?T*@rQUKcUhTIjV(rw*5oQYlm5DbEO?60#mohHfbR$3_x#+PZoYi@Vd4`#YgKyTd^!4n{fN~WZDY61sAOm6 zl!d^i*a01QxpWM9Pcl?&{RgO}uq%ErOk5WpECvnfEh!*YP&1Sl)uTN4hg??Vqs~i5 zYsfufz3?{TtwuBN=`0~Qg1PlWH#OGG$ zLLWU17$v``)CE1cds_7kj8mJ{-+l8{DS|zAQ&3|qpOY=!J|kXUhXue9|H>4gqk|n) z-i34GmxLFj8asb3D#D&=ya*a5`C<=o?G;Ev^LV%;l#nH#O=7Nh@z1Do>j6Q;I5S2P zhg|AZbC&|c7}uSJt57s2IK#rSWuararn-02dkptTjo*R{c5o(bWV}_k3BBnKcE|6l zrHl&ezUyw^DmaMdDFVn<8ZY=7_{u{uW&*F<7Al6};lD(u;SB=RpIwI)PTyL=e25h* zGi{lRT}snjbMK~IUx|EGonH+w;iC2Ws)x>=5_{5$m?K z5(*1jMn%u0V1Y%m@`YS3kskt~`1p(rA4uk;Cs!w^KL$w>MH)+cP6|XKr4FfHIATJH z!EGAK4N>1yFR`-zW|w%ByRe#=&kA&#WyUldDGpt!wf-8SFWiSi!5QZL+l7*CE?u!NW1T$<1rdLJ9y3u{_zvHaM?#Rm4 zFk}^1!ffcrB|XK3gsO-s=wr*sUe&^$yN|KxrA)uW00Gu60%pw_+DcUjW`oW<35OC8 zq2{j8SgC}W$?10pvFU83(SL$%C?Kctu3*cs0aa%q!fjn1%xD*Jrm!F3HGR9-C{b?- zHp(cL;ezXMpL@0-1v0DMWddSDNZ5h?q50cOZyVi#bU3&PWE=(hpVn|M4_KYG5h9LffKNRsfhr^=SYiKg?#r&HNMi2@cd4aYL9lw(5_IvQJ zcB*DD()hUSAD^PdA0y|QrVnqwgI@pUXZXjHq3lG2OU&7sPOxxU$Y3&ytj6Qb=2#cC z;{d-{k|xI*bu+Vy&N+}{i(+1me!M;nshY_*&ZQLTGG*xNw#{RpI`3^eGfHck+*38NRgiGahkFethtVY=czJs#)VVc{T65rhU#3Vf?X)8f0)X{w!J3J{z|Sq|%?)nA+zo?$>L9@o`Kc|*7sJo4UjIqu0Ir~S5k^vEH};6K?-dZ0h*m%-1L zf!VC%YbM1~sZOG5zu&Sh>R;(md*_)kGHP)<;OA44W?y53PI%{&@MEN}9TOiqu+1a3AGetBr$c)Ao3OX>iGxmA;^^_alwS818r4Pn&uYe^;z6dh z)68T|AN=hjNdGpF7n>y+RTAZc9&opTXf zqWfK_dUv=mW{p_vN>|(cIkd(+Jy}qnK{IW%X*3!l`^H~FbAHwof+vLZ0C2ZXN1$v7 zgN&R9c8IO`fkR{6U%ERq8FN<1DQYbAN0-pH7EfcA{A&nhT!Be>jj>J!bNRw4NF|}! z1c70_#fkk!VQ!q1h2ff@`yDyrI1`np>*e#D4-Z~*!T^8#o*$V~!8bWQaie?P@KGBb z8rXc!YDL!$3ZgZZ%;-%~0Kn<+d+{xJ$stQbtN8GWV?MCJvzPU|(E(1z;rFw{&6vy) z3*@y%7Tx8rH-p$boS>bLyod?OKRE8v`QSBvGfY6f}_{Zo1q85xoyOF16n~yHx2W ziydUoYLkJmzq|n&2S(O!ZmLdP1(o1Jsq88cX)x3V-BK5eF&0e_0G!5?U7&3KN0`mc zH&Lt)q8!d_VgzxyL^(@xrbp2y)Hmr^V48));RSfE=*Ly0uh9!$3dv-vMZr2URf@l5zdwLjGZB zugY>7_fd_vbV*Qv1?H~>Z%RD%nEeFSI$n$$Lrpc6g>i4+XdBB!%zM$Bhrz5Swzyg? z$~I~n@~-wTBY3-T&pr+|gC+OHDoR?I(eLWa{Z#Rsh>lc~%u0!&R|s0pA*w<7QZ}{i z*AFr~0F3y~f$MGh_HDL7J_1?SxKL}fWIk!$G}`^{)xh*dZ5kK>xGL9>V`WZZg_ z)^Vm)EQK`yfh5KiR(vb&aHvhich z_5o+{d~0+4BEBqYJXyXBIEb1UgVDs;a!N2$9WA>CbfrWryqT25)S4E4)QXBd*3jN} z?phkAt`1rKW?xoLzEm!*IfkH|P>BtECVr0l8-IGk_`UjE#IWkUGqvyS+dMrCnFl<7RCgSMX^qn|Ld_4iYRldO zY&cHhv)GDo8nKvKwAbfyLR%t?9gG?R7~PSD#4D-;?F&!kV59O}neYut5AGbKwy-(U zqyBi=&Mgj|VIo>$u!DHM`R7O?W8-idbePuxiJMH``6c_5L-chKd}=rGC5Gfrc{f!* zWFEBm?l@_b7kzY7%1RQQbG5V<4=ZlkZ%sF74Q|mKOc7Ak7dP2#quiGcZ0_J%7Q?j{ zv9{WFw;n5G-Mn%r#0R;{jLt{yy}9J6rQ(>X9pJ`7Xy?Zv z=lNit#qXaq?CnElK^zF~sG}U5oCpR0T>FH=ZX}Prju$);?;VOhFH8L3I><9P_A|C+ z{;>~dk%9rrq(snjsEm}oUz2FQ21MCG*e?g)?{!&|eg7PX@I+Q0!hL6C7ZVY|g2E>i zr!Ri2@OfEu$)d52+>+cpgh6Z;cLYCZ&EMR0i<^~4&wEu_bdo;y^6}+U2GIQgW$|Od z_jg{O=pU>0-H$P-EOlWyQy#W0r@@_uT}Lg+!d5NxMii7aT1=|qm6BRaWOf{Pws54v zTu=}LR!V(JzI07>QR;;px0+zq=(s+XH-0~rVbmGp8<)7G+Jf)UYs<$Dd>-K+4}CsD zS}KYLmkbRvjwBO3PB%2@j(vOpm)!JABH_E7X^f#V-bzifSaKtE)|QrczC1$sC<<*Y z$hY*3E10fYk`2W09gM_U<2>+r^+ro$Bqh-O7uSa)cfPE_<#^O) zF+5V;-8LaCLKdIh3UB@idQZL`0Vx8`OE#6*1<;8(zi&E7MWB1S%~HAm%axyIHN2vd zA(pJGm_PraB0Aat3~?obWBs?iSc*NhM!{-l_WNCx4@F7I?)5&oI|z{o@JKd1HZ}zf*#}JjK3$ z-;3V*WJZvUcKvSOBH4c7C{fl8oRw8-vfgKQjNiR|KhQ%k6hWNEke(k8w-Ro| z7Y3)FsY-?7%;VT64vRM)l0%&HI~BXkSAOV#F3Bf#|3QLZM%6C{paqLTb3MU-_)`{R zRdfVQ)uX90VCa3ja$8m;cdtxQ*(tNjIfVb%#TCJWeH?o4RY#LWpyZBJHR| z6G-!4W5O^Z8U}e5GfZ!_M{B``ve{r0Z#CXV0x@~X#Pc;}{{ClY_uw^=wWurj0RKnoFzeY` z;gS!PCLCo*c}-hLc?C&wv&>P1hH75=p#;D3{Q8UZ0ctX!b)_@Ur=WCMEuz>pTs$@s z#7bIutL9Pm2FDb~d+H}uBI#pu6R}T{nzpz9U0XLb9lu@=9bTY&PEyFwhHHtXFX~6C zrcg|qqTk(|MIM%KQ<@j=DOjt|V)+8K26wE_CBNnZTg+Z+s}AU|jp6CFoIptG1{J*# z7Ne~l;ba*=bSwAMQ|Vq#fW~+je4PXA91YFzBubNF?ovIOw-$C-8=Ehed{lGD0}(Id zRe4sh8L>&T%{>8o))he}eE;5_ zxoXk3wX?MyNl-xF!q1d$G?=wp^`@09(jU&X zOqZIBI#dN`2PJNdATR3ivtub|nO$dulSaP|e4)WXF1YAGN1pDQIbIjXFG!oC85Mt; zW$eteoL{y^5t4TMRwP$jNPjZFpGsWnGe=jMMqKtcZm9Y9PFZLi*1p@qoKKub^T@2+ zk$@*KYdQ?Z`}<%4ALwk*Yc{(WTf@#u;as(fvE^9{Gk)lWbJP*SjttWofV0s?AB({~l zZI1hZVWFT~W-T?nfMMcnCS4-#6H-MU7H$KxD;yaM46K4Kc@~Q>xzB+QnD_I`b_l3m zo9pRx46b!p?a^&zCDwygqqV3epjs(s0NQI6ARA1n!Yy-qduipxQ& zUAlqRpNjBS+y-ZheD(!R;F}&^V_}b_gqH%tVZ5%%ziO7k^w=es+wZtK^i*vmrWNLMs{oWu_CIov|s1raZiS)>38>pYu;i+-t zI_DiNe6aA4KTZ2P09qPj(0~K4nUq^0+f(2$g`229zkG4jLzRvJUWE0oF1XHL4t3UN zDH466G56sy9hTZoAJB!C3;@F;ONxEk5u6Mv%zdo}Rq`=* zw1n7MOhfNSV48TS989ArIcj`C%Gk8~93~u>)!Yt2b4ZriKj9x2d`H2HQNJ=I>hkDlcZn zqRj>!;oRMTIOu zx|Zfsu~v76T{z7AC(jxj^c@tnJHZtGPsq$DE!8kqvkDx5W?KUJPL+!Ffpwfa+|5z5 zKPCiOPqZZrAG;2%OH0T$W|`C@C*!Z`@Wkop{CTjB&Tk`+{XPnt`ND`Haz;xV`H^RS zyXYtw@WlqTvToi;=mq1<-|IQ(gcOpU%)b#_46|IuWL#4$oYLbqwuk6=Q@xZaJSKVF zZcHs~ZBl;&lF3=+nK; zF`4gSCeZXlwmC_t4I`#PUNQ*)Uv&oGxMALip|sxv^lyVV73tKI7)+QY5=tEMas{vTD-BaTJ^*Y6gq~PU;F5X!sxqiq$iFCo+Uv7m%1w((=e}Vf*=dtds|6 zbX}91!G?C*KG03eHoN}RZS9DJxa&8YwNCT8?JxMXyZqZr13NA|GB{+vG`08C{V(yy zf*Lw$+tYSU_+dI`3n{bMrPdDb`A=Mkg!O=k>1|*3MC8j~- zXL79J4E=U^H=iBLTeHE_OKzE&dws8RNynsSJ!d;`zK?P92U{f)xvD7VQVosrXZrL+ z6lMVdD1YgL;%(1cq{#bS6yXmp|DS@nax#AqqlZhtUQdh<^2vr5`EpAO

    LGYq)sa(w9^3-f}NHy=GR4v%t2YZly3m1G@5y`xBh_HGrD%f z>;|Ty?9FiJAc&UVD(StT4I` zfVQwxhE9bXE6r2mKO8Ag7{L^jCyqQb0QqKDPE=RAgqn8q1O^>(z7h5kE(6va%QqRZ zkIOmp(})rLSS(2{=C12e&@!W2=Jel-^_R``0xHO^+t!(oXbcv5yhD4g*$t_F)_5Dl zSVCgesW%;DtYPCFs{G;GX_o?1J3;QQPPv)rWw;>} zJ&KwnUqwNXloNXlK_+pNDfI~hON#SokVJb&ilg8d7^NWo2ZQymCqQMnjfi>ePibjr z-Z@q!?RGN$Mj}Nk){X_vaj6?Mj$>ACR*z|6MsXy3VZ^PFn@yHkPo(>m(iWepn8SC@ z>D2;R4m+gDRZ=SIX!b+CP(qE=JDIUkn=D$aUu+Ihn9-+k1LS3PreQg0N5eWIG@x${nC3v^7caS>1!PKNAY9J z#}E}Q9w#SP>(GY7Hbj&z4$Li6o5taBO|4+F`yS9zq*LJ<38wy4I>HA9(&GYrk4dLajKGww))BWli6Ln1A^Lda@N~p+snkb9C z@OthI+<##vp8!HVQT4Wk(=@zQ{OvZ$EKWS73+JHb)eYLGD-cqi6^|vd$<+IHuc?Nq zW7JertT~3))4?J|28n$I@nAD0c1%9C&IVhEZX~mUsf{efyS(XNG%ch;!N~d7S(Ri7 zb&=BuON95aVA&kLn6&MVU|x}xPMp7xwWxNU1wS+F6#y}1@^wQZB*(&ecT?RnQcI}Y z2*z!^!D?gDUhc@;M^OpLs4mq>C&p{}OWVv<)S9KMars@0JQ{c_ScGsFo3BJ)Irg++ zAWwypJdTO-_{Uh8m(Z!3KL7K{ZZzKHj;{M8I$mV>k znTM?sa0);^=X^cglL`uC+^J)M7nEa$w=VwFULg~%DJllw+7dJAj3{qnP5i3@wr7%y zjXp?Wl2%Th=my&3u?Q$RV6N5tzKMSPTsc#J+-cDDp~qFB6bL2C8AS7Y3PKtVhdhl) zIaLqH5+OnWPWSt(lQCgkN8lczc-V%_iZ{>#1%Z$N*>lu#S;0MZ$T2Y8Kg!U;hAZj> z6S#%$DQ_`Ic%Zr@?}GgjRXg@qTj^17n`65oJ@Wj0u1X8&+UVd|Xs?J+i_^GZ94m6= zUc96~Q`OJvlKB_Lr15*Yw_PUPEr?f?H&00b^-W%26mD)(n(rGGNfK9~2h=C>p-7BZ zFd&*&Msdu{w~(eyFOglwCPH^Rb}O(N7LtS+nnEwDx*pGD?|&9Si~M43a+*L(b0$5A zv`T`(G3xO;I_sx;FwTP21ZlfDpz zOo?}Vlgf~fo{YWm@n_JyD*frOg{XsvBA~|Tn4V6hu>Gd>89-rblfVJUaGvj6X%NZ} z$tFF9sx=4_$*c~G`9iPLGh@=sV+O{D2-t*K@J7H=`V+oVt}8?04WwU3h1BgS!f%1P zFak-T#7`TtLcR=Yz>g0R!ZQrH!YiZOQN=_V-UyncN1Rc18?KY?#O`v#JK+pq0K$~H z3D@v9DZF42R)b9#BBX{^$DOMlJ!g)Gc za{o-1e%F6NvgKq9tC8pV+9S$;9*zNv{J*)n&dmf~anP1)4~N%~h#c(=B#3*KgzhCKhFdgDoWi2IDog{RVyzK|Y`rCUs3T~pJMmdZJy4?b z&s5G=zhf**(t7Y^oC_mcTsE-{^}wiaoUu&?kojLKs>SJPxjcP>{a5CbXCx92AcBE) zHtqP}LjZ{W>PH?Tu(E0X=%{PBMW@F_?#7b&#!^q`<-5$ur+-q6 z{dn=(^UZw6*3-XM_(=@<1_*i&XM4=0t5u!gm6 z{UlmNGPKgO_;e;q9|#esq~Sq`<}%d{+sRmhvsA{5i*91=tub>OZZ%)xUA#4q$dDyy z1`w4%?OPLg3JeZb#cqSMO?*Xn%|-FCcuH2i2fn_{IFusub6;NQdN|7TD1N?%E8*g? z$apAt@cEe!I%jB=*q$p_3=t_5R0ph%{qaq+QDg!c99Y!Xa!&oDZOeis_ot)gNXr{l zdY$|So2Qed2Y7KMNBrS^E169kG%h<+z{Z_p_;shB!uY)>yAVcK=&!bg`lVg)4T1|7 z0}7FpfydVH4F87K@c!nEG+WGKm{Ouo)Slpl;#qcEIQ0zdMfLA#;dBxYw;p;KoVv6| z3_D5&7rJdG12CnDSvZUW?$UC6^UVSW^|vw|o-_4bz)(w5(3AiVhpeT(|=f#x_}E?s#qHZF#xA6AF_ujl$G z-jHD%q(d2}v2PhXx&6YWps~m(^+RXl91Q#xRRJBhjKl$FG4bk);|ag;ieUZ&!Ii3$ z(iGz1+0m7#g5>ASldBbNZL=ZHh=tmmJt$!71; zIML2GhEz1pg@1rQN(M^_691wAGkJ@Pga_05WuQ6! zG5RkGY2^`@(H~pp7&Ga+Pwh3L!Njj!-rc;^bTIfo5hP@H##1X8xUZJckrx>id`bAd3QUx9GuomqBYZ!uN1-&o zvTxC?;p8vL67&fW8fw(YOqt>L@bdLrEF*3OgYe$4n4{ zEB40LiU#6-0@5jdN`0w}N0qi@c0~oT2FP z)LNk&a82my?jv(tQpiMi$TK_L@lub#lsM$R{Dk?Ya@%%%huZkct~tSWM714c!45k}-ZLVA-bVM`>|_ZBbW_m-7| z3U%xrAhi}n?T(2F{_n4EZ10inkIFl#y09?7$uwBoJgqY8vylwev)fDOn;>0R!aEnV zBz%j0Mqpx~EZU3q@%+oV7;}|vt7$~ou@faEIq{p?FY$XXg&6*K)b_LP=}gi9`Bij3 zN`zEo|B6*|-;>S`rNa^BKRDbDAk>X#MsR`EvL>6bqU@SaDDs z8>bu@3YdRaWs*Te@G-UHjU%F~kTHw5(0PVJ+pwh#ha2u;DB+UMo@A5UYIl#5rtBV- zGX_hIpw}3C@H*Us(Cc-d#-gNrG#w$(9+S=GxO>3SR`SE2fHZ2KrDc#_C^$jI>Y}#; zMwY=R6@+dWi~0RXw(c@3GZ&%~9K(q&ee0Zw;pwL`E_tZak-#8^_b)Dpyi73^he?xV zXJ08&wh5-M&}qy4f7!D&=E)puDD(Nmg1d_(j`4LvxM5x_huNg-pGG%9rYqO6mImyJ@}*3Y>^3OvcnTG%EV1) zq_Ap?Z!Iw__7#D=pOWnQN$gB!Mr0!9yx|g<4icJh{cFOu3B8}&RiYm+Mb;VEK``LK zL(NcpcTiGieOIssSjr?ob}^``nNf&UcJhXyncO9m{6gD$kqSD`S69(aF8dkWz5>!9 zBLe4Sib7Hs2x_L2Ls6Ish$MGVKrGt5+_2zCyP1byaCg3upo+-I}R4&$m)8 zQ7|jc1Z^VWggpuQj*cP;>Zo9LS!VSzrqmZczaf;u`d0J(f%Z9r%An@s!e>n9%y=n!IZ_tVGu{Jmsbp}Fk%HJIU?a+-~bjfLTuH|JExA8EROowzr zqW9{YyZhR0a4clRK>1I4Ncx&WER~{iE;F^$T7K%X@3PGOA%6#Z%p3TS^&M;Dnjw@i z^o!$9nhcsmcHcY4?4j9+ofL_CWsZ4Hcch(rjsGfGD(nsH>w}^ERqGnz%iGj0j{g}h z7wMkJ-2Z2~eS>2!i}0~B63i;>SyFJU2+>VCS^AxaDOx%g6-t0eM^P<3+*z`ztvOqrG3)&#$K?& z_Y0wbWID47@cU`E1A6A&!`aZk0ZE@z-h#l1NqX2#`$Uev2gepW`rf8*!=rD5&;Jb{ zl08rU>dPo=K%-1Ao1~G-@4ve~y5#9E8x;TE0k5d^TC(=Zc>mwjW^c=+U-<9}b0ku~}gj z3sbW>R2M6DR!g#NUP;nxo>)@7*=RP{U18SDop6b2&PHce^&h97@xx3t+VK+!keE#} z;(Uf&89as9k8{$nkLbuB!-d7TP`_VJpL^Xs8OKB~ri$YUbW8fch64}7|0EWoT(TRj{ z*GT<7Y<7DsrCi79ZsM)z#c(!nNOGySOCkY1fAuQOq12&iUVC!a`#O;dBLf=d?&4*B zI~LgAO7E0qxK(uRTM;IgJ}+z^gD+bi-6I!3x{r9`l~%8TRP%UE0V8E*Sz>Nl1NVG<<7(wDHZ+HcOkQm$O&k+vyx)y)x{Pz!U8hS$*m zByc0h6BUI*BOpuL==P+H|Hx%`>7!W+1H!l9vi&)`V zyn2o9{z=lc+VX*!Vh~SF=)L}Z40XeG>LF6cP^b+R$NxSeUqbK^Q*UTalKzP8X%{9@RSCXm_NhF>{=S2 zi}ezam_^P`S!!-cyEW9y7DBbK93roz@Raccy*v}?mKXScU9E_4g;hBU7}zSofAFda zKYEe?{{I54 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a4413138c96c..df97d72b8b91 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index b740cf13397a..f5feea6d6b11 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 25da30dbdeee..9d21a21834d5 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## From 49eae0d5fbef659be9ff398c38da4c4bcf5ebd11 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Tue, 29 Oct 2024 15:33:42 +0100 Subject: [PATCH 108/119] remove some leftovers --- patches/api/0490-Improve-entity-effect-API.patch | 5 +++-- ...possible-StackOverflowError-and-NPE-for-some-dis.patch | 8 ++++---- ...erly-track-the-changed-item-from-dispense-events.patch | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/patches/api/0490-Improve-entity-effect-API.patch b/patches/api/0490-Improve-entity-effect-API.patch index 582a5027352f..6ec450bcea5e 100644 --- a/patches/api/0490-Improve-entity-effect-API.patch +++ b/patches/api/0490-Improve-entity-effect-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Improve entity effect API diff --git a/src/main/java/org/bukkit/EntityEffect.java b/src/main/java/org/bukkit/EntityEffect.java -index 5341957b10cccd7bce5a7595699b1d90412a01d0..912dafd5a8884d7973b2126f97ecdbe54e78937f 100644 +index 5341957b10cccd7bce5a7595699b1d90412a01d0..ef0acab253db878f1edee51b585fd1b20ef9161d 100644 --- a/src/main/java/org/bukkit/EntityEffect.java +++ b/src/main/java/org/bukkit/EntityEffect.java @@ -112,11 +112,25 @@ public enum EntityEffect { @@ -76,7 +76,7 @@ index 5341957b10cccd7bce5a7595699b1d90412a01d0..912dafd5a8884d7973b2126f97ecdbe5 HURT_BERRY_BUSH(44, LivingEntity.class), /** * Fox chews the food in its mouth -@@ -331,7 +355,24 @@ public enum EntityEffect { +@@ -331,7 +355,25 @@ public enum EntityEffect { * Sniffer must have a target and be in {@link Sniffer.State#SEARCHING} or * {@link Sniffer.State#DIGGING} */ @@ -97,6 +97,7 @@ index 5341957b10cccd7bce5a7595699b1d90412a01d0..912dafd5a8884d7973b2126f97ecdbe5 + * creaking heart. + */ + @MinecraftExperimental(MinecraftExperimental.Requires.WINTER_DROP) ++ @org.jetbrains.annotations.ApiStatus.Experimental + SHAKE(66, org.bukkit.entity.CreakingTransient.class); + // Paper end - add missing EntityEffect diff --git a/patches/server/0936-Fix-possible-StackOverflowError-and-NPE-for-some-dis.patch b/patches/server/0936-Fix-possible-StackOverflowError-and-NPE-for-some-dis.patch index 20702237808a..25ace4aa4113 100644 --- a/patches/server/0936-Fix-possible-StackOverflowError-and-NPE-for-some-dis.patch +++ b/patches/server/0936-Fix-possible-StackOverflowError-and-NPE-for-some-dis.patch @@ -45,7 +45,7 @@ index 39c96f5db6e90a470404c6387fa0c1d5531822e5..8aae1d113e84dfad9f2b6f0bcd203ca6 idispensebehavior.dispense(sourceblock, eventStack); } else { diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -index 18304349c9ab24657c4152aff800dba969174665..94b2647f69035dce9a3d56b6978e3884e06c5583 100644 +index 18304349c9ab24657c4152aff800dba969174665..681c38f4457fc10806c10518b16159580c0f2619 100644 --- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java @@ -124,7 +124,7 @@ public interface DispenseItemBehavior { @@ -73,7 +73,7 @@ index 18304349c9ab24657c4152aff800dba969174665..94b2647f69035dce9a3d56b6978e3884 - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); - if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE) { + DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior -+ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE && idispensebehavior != this) { // Paper - fix possible StackOverflowError ++ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { // Paper - fix possible StackOverflowError idispensebehavior.dispense(pointer, eventStack); return stack; } @@ -84,7 +84,7 @@ index 18304349c9ab24657c4152aff800dba969174665..94b2647f69035dce9a3d56b6978e3884 - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); - if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE) { + DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior -+ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE && idispensebehavior != this) { // Paper - fix possible StackOverflowError ++ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { // Paper - fix possible StackOverflowError idispensebehavior.dispense(pointer, eventStack); return stack; } @@ -185,7 +185,7 @@ index 18304349c9ab24657c4152aff800dba969174665..94b2647f69035dce9a3d56b6978e3884 - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); - if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE) { + DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior -+ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != EquipmentDispenseItemBehavior.INSTANCE && idispensebehavior != this) { // Paper - fix possible StackOverflowError ++ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { // Paper - fix possible StackOverflowError idispensebehavior.dispense(pointer, eventStack); return stack; } diff --git a/patches/server/0940-Properly-track-the-changed-item-from-dispense-events.patch b/patches/server/0940-Properly-track-the-changed-item-from-dispense-events.patch index d653a24df563..872400fdee81 100644 --- a/patches/server/0940-Properly-track-the-changed-item-from-dispense-events.patch +++ b/patches/server/0940-Properly-track-the-changed-item-from-dispense-events.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Properly track the changed item from dispense events diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -index 94b2647f69035dce9a3d56b6978e3884e06c5583..a09b089565f9167e1a2d53116ae879d9f868342e 100644 +index 681c38f4457fc10806c10518b16159580c0f2619..8f9b86e50717746e55232293d9e5ac05b8616aa0 100644 --- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java @@ -129,10 +129,14 @@ public interface DispenseItemBehavior { From d576cfc23496bccc68282ff2ca8ee378122da02f Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Tue, 29 Oct 2024 16:54:40 +0100 Subject: [PATCH 109/119] cleanup bugfix patch --- patches/server/0009-MC-Utils.patch | 2 +- ...4-PlayerNaturallySpawnCreaturesEvent.patch | 2 +- .../0306-Tracking-Range-Improvements.patch | 2 +- ...-PlayerChunkMap-adds-crashing-server.patch | 2 +- ...nEvent-when-Player-is-actually-ready.patch | 2 +- ...primise-map-impl-for-tracked-players.patch | 2 +- .../0739-Fix-a-bunch-of-vanilla-bugs.patch | 82 +++++++------------ .../0767-Player-Entity-Tracking-Events.patch | 2 +- .../0843-Cache-map-ids-on-item-frames.patch | 2 +- ...ntity-tracking-range-by-Y-coordinate.patch | 2 +- ...k-if-we-can-see-non-visible-entities.patch | 2 +- ...llocation-of-Vec3D-by-entity-tracker.patch | 2 +- .../1038-Moonrise-optimisation-patches.patch | 2 +- ...er-desync-when-new-players-are-added.patch | 2 +- .../1053-Optional-per-player-mob-spawns.patch | 2 +- ...ng-PreCreatureSpawnEvent-with-per-pl.patch | 2 +- 16 files changed, 45 insertions(+), 67 deletions(-) diff --git a/patches/server/0009-MC-Utils.patch b/patches/server/0009-MC-Utils.patch index c7768b91e2b8..f656e93a6489 100644 --- a/patches/server/0009-MC-Utils.patch +++ b/patches/server/0009-MC-Utils.patch @@ -5166,7 +5166,7 @@ index 59bc334ade71c106e01e54db8d21fb65563dd3f1..b9ab241b930edc63a39dbbcf14cd0b5e } diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 952936754cbe5a6fae543d19432599e30eb495b0..3bb6eaabe8f62b556a52b83227b48f8324a9d0f0 100644 +index ad2d29b106df33965090be521d4f945601965a00..261943f1f188643793a72bd239dfc5fe604e3b99 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -174,6 +174,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch b/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch index f61ad3434c98..2c2148e2532b 100644 --- a/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch +++ b/patches/server/0164-PlayerNaturallySpawnCreaturesEvent.patch @@ -9,7 +9,7 @@ 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 3bb6eaabe8f62b556a52b83227b48f8324a9d0f0..b8aff86c8533ea92b0244ea85ed786073c4053a8 100644 +index 261943f1f188643793a72bd239dfc5fe604e3b99..985ba48a5ac027d3c3dcd9b710b53748508966fb 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1098,7 +1098,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0306-Tracking-Range-Improvements.patch b/patches/server/0306-Tracking-Range-Improvements.patch index 620c26dc9962..c22d82fbf9a9 100644 --- a/patches/server/0306-Tracking-Range-Improvements.patch +++ b/patches/server/0306-Tracking-Range-Improvements.patch @@ -8,7 +8,7 @@ Sets tracking range of watermobs to animals instead of misc and simplifies code Also ignores Enderdragon, defaulting it to Mojang's setting diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index b8aff86c8533ea92b0244ea85ed786073c4053a8..0c5eb6ee56710b1ff71714b2090fbccd6da8456b 100644 +index 985ba48a5ac027d3c3dcd9b710b53748508966fb..5f85d7f7ec57fc1b0375e62a8e8e3e8783f34193 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1598,6 +1598,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0328-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch b/patches/server/0328-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch index e085f84be195..f3de36db4bd6 100644 --- a/patches/server/0328-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch +++ b/patches/server/0328-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch @@ -7,7 +7,7 @@ Suspected case would be around the technique used in .stopRiding Stack will identify any causer of this and warn instead of crashing. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 0c5eb6ee56710b1ff71714b2090fbccd6da8456b..5963f38e050c1ea5c77dde91028d306dfe9b94ba 100644 +index 5f85d7f7ec57fc1b0375e62a8e8e3e8783f34193..396310a51480cf0d1ea4c0959d3f8e4ed77b99e3 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1298,6 +1298,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0339-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch b/patches/server/0339-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch index d7a416c036ce..463ceefd14b1 100644 --- a/patches/server/0339-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch +++ b/patches/server/0339-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch @@ -31,7 +31,7 @@ delays anymore. public net.minecraft.server.level.ChunkMap addEntity(Lnet/minecraft/world/entity/Entity;)V diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 5963f38e050c1ea5c77dde91028d306dfe9b94ba..352675e0b835d5f04576db6599e8840754a40340 100644 +index 396310a51480cf0d1ea4c0959d3f8e4ed77b99e3..0f8fc275af95750871aa6917aa12053f75c112f7 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1305,6 +1305,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0601-Oprimise-map-impl-for-tracked-players.patch b/patches/server/0601-Oprimise-map-impl-for-tracked-players.patch index 026136cdd5fe..286a4f8c945d 100644 --- a/patches/server/0601-Oprimise-map-impl-for-tracked-players.patch +++ b/patches/server/0601-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 352675e0b835d5f04576db6599e8840754a40340..b92a889d0b0c46c1fa247d770f303d7d37dfc36c 100644 +index 0f8fc275af95750871aa6917aa12053f75c112f7..51a6735b35e73175680e61c2d67d4adbedf305c9 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1514,7 +1514,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0739-Fix-a-bunch-of-vanilla-bugs.patch b/patches/server/0739-Fix-a-bunch-of-vanilla-bugs.patch index ddd8b7606308..bd4227733382 100644 --- a/patches/server/0739-Fix-a-bunch-of-vanilla-bugs.patch +++ b/patches/server/0739-Fix-a-bunch-of-vanilla-bugs.patch @@ -28,9 +28,6 @@ https://bugs.mojang.com/browse/MC-259571 https://bugs.mojang.com/browse/MC-262422 Fix lightning being able to hit spectators -https://bugs.mojang.com/browse/MC-224454 - Fix mobs attempting to pathfind through azalea blocks - https://bugs.mojang.com/browse/MC-263999 Fix mobs breaking doors not spawning block break particles @@ -60,6 +57,7 @@ https://bugs.mojang.com/browse/MC-273635 == AT == public net/minecraft/world/entity/Mob leashInfoTag +public net/minecraft/server/level/ChunkMap anyPlayerCloseEnoughForSpawning(Lnet/minecraft/world/level/ChunkPos;)Z Co-authored-by: William Blake Galbreath Co-authored-by: Spottedleaf @@ -90,19 +88,6 @@ index 6854ca4d4fec2b4fa541c3fabf63787665572609..e7b444a10b244828827b3c66c5346520 } } -diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index b92a889d0b0c46c1fa247d770f303d7d37dfc36c..e1c69c3c8e4809c7ccd2e1e12ee8538ab4bd3d5c 100644 ---- a/src/main/java/net/minecraft/server/level/ChunkMap.java -+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1078,7 +1078,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - - } - -- boolean anyPlayerCloseEnoughForSpawning(ChunkPos pos) { -+ public boolean anyPlayerCloseEnoughForSpawning(ChunkPos pos) { // Paper - public - // Spigot start - return this.anyPlayerCloseEnoughForSpawning(pos, false); - } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java index f3f93e8cbc2a5c9d0a3841ec7de010477bfd976a..d01f42aad003c7b0ea5700d32109eed4a264fa4c 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -235,7 +220,7 @@ index 14b47d6fa189f2a666b12ef7e7708d204c2b0452..4c6dc427b90012b0945e073dd905dc7e } diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -index 30af4cbb17148c247a46c0346419d6c838dbc9d2..65f7f1f98f415a564aadb440d3a67143699e43db 100644 +index 30af4cbb17148c247a46c0346419d6c838dbc9d2..d431ee93cd7e87a24ff4079288facd089053d725 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java @@ -272,6 +272,14 @@ public class ItemFrame extends HangingEntity { @@ -246,7 +231,7 @@ index 30af4cbb17148c247a46c0346419d6c838dbc9d2..65f7f1f98f415a564aadb440d3a67143 + @Nullable + @Override + public net.minecraft.world.entity.item.ItemEntity spawnAtLocation(ServerLevel serverLevel, ItemStack stack) { -+ return this.spawnAtLocation(serverLevel, stack, getDirection().equals(Direction.DOWN) ? -0.6F : 0.0F); ++ return this.spawnAtLocation(serverLevel, stack, this.getDirection() == Direction.DOWN ? -0.6F : 0.0F); + } + // Paper end + @@ -335,54 +320,25 @@ index 8aab6f68f576fb022eb59798585e264f5aafbc69..edd6017937a7f20a1b43fa15204ec130 } diff --git a/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java b/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java -index e64a30577e9000e5c4d22fd3d9cf8a9381c5c459..b9690f31d410e82d833b2ca805df2fa68abcb6d1 100644 +index e64a30577e9000e5c4d22fd3d9cf8a9381c5c459..a49f83784f85f5420091692aae588ef067aa5fcd 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java +++ b/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java -@@ -101,17 +101,19 @@ public class TrialSpawnerData { +@@ -101,9 +101,9 @@ public class TrialSpawnerData { this.ejectingLootTable = rewardLootTable; } - public void reset() { + public void reset(TrialSpawner logic) { // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 this.currentMobs.clear(); - this.nextSpawnData = Optional.empty(); -- this.resetStatistics(); -+ this.resetStatistics(logic); - } - -- public void resetStatistics() { -+ public void resetStatistics(TrialSpawner logic) { // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 - this.detectedPlayers.clear(); - this.totalMobsSpawned = 0; - this.nextMobSpawnsAt = 0L; - this.cooldownEndsAt = 0L; -+ this.nextSpawnData = Optional.empty(); +- this.nextSpawnData = Optional.empty(); + if (!logic.getConfig().spawnPotentialsDefinition().isEmpty()) this.nextSpawnData = Optional.empty(); // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 + this.resetStatistics(); } - public boolean hasMobToSpawn(TrialSpawner logic, RandomSource random) { diff --git a/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java b/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java -index 83cdeee5e2ce115ff696a5afc5465dc4301779b9..027d5c4117feba1e152d0ecf9923aef77ba72207 100644 +index 83cdeee5e2ce115ff696a5afc5465dc4301779b9..192ee216b617d3533f592e62719b6d75d20b5a96 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java +++ b/src/main/java/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java -@@ -68,7 +68,7 @@ public enum TrialSpawnerState implements StringRepresentable { - case INACTIVE -> trialSpawnerData.getOrCreateDisplayEntity(logic, world, WAITING_FOR_PLAYERS) == null ? this : WAITING_FOR_PLAYERS; - case WAITING_FOR_PLAYERS -> { - if (!logic.canSpawnInLevel(world)) { -- trialSpawnerData.resetStatistics(); -+ trialSpawnerData.resetStatistics(logic); // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 - yield this; - } else if (!trialSpawnerData.hasMobToSpawn(logic, world.random)) { - yield INACTIVE; -@@ -79,7 +79,7 @@ public enum TrialSpawnerState implements StringRepresentable { - } - case ACTIVE -> { - if (!logic.canSpawnInLevel(world)) { -- trialSpawnerData.resetStatistics(); -+ trialSpawnerData.resetStatistics(logic); // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 - yield WAITING_FOR_PLAYERS; - } else if (!trialSpawnerData.hasMobToSpawn(logic, world.random)) { - yield INACTIVE; @@ -145,7 +145,7 @@ public enum TrialSpawnerState implements StringRepresentable { yield ACTIVE; } else if (trialSpawnerData.isCooldownFinished(world)) { @@ -392,3 +348,25 @@ index 83cdeee5e2ce115ff696a5afc5465dc4301779b9..027d5c4117feba1e152d0ecf9923aef7 yield WAITING_FOR_PLAYERS; } else { yield this; +diff --git a/src/main/java/net/minecraft/world/level/portal/TeleportTransition.java b/src/main/java/net/minecraft/world/level/portal/TeleportTransition.java +index cf27b0d6a9fe53b9f91090db4740776b335a2e9b..7d5909431f98f7e8b84d740bba9c044fec6d8e96 100644 +--- a/src/main/java/net/minecraft/world/level/portal/TeleportTransition.java ++++ b/src/main/java/net/minecraft/world/level/portal/TeleportTransition.java +@@ -53,7 +53,7 @@ public record TeleportTransition(ServerLevel newLevel, Vec3 position, Vec3 delta + } + + public TeleportTransition(ServerLevel worldserver, Entity entity, TeleportTransition.PostTeleportTransition teleporttransition_a, PlayerTeleportEvent.TeleportCause cause) { +- this(worldserver, findAdjustedSharedSpawnPos(worldserver, entity), Vec3.ZERO, 0.0F, 0.0F, false, false, Set.of(), teleporttransition_a, cause); ++ this(worldserver, findAdjustedSharedSpawnPos(worldserver, entity), Vec3.ZERO, worldserver.getSharedSpawnAngle(), 0.0F, false, false, Set.of(), teleporttransition_a, cause); // Paper - MC-200092 - fix first spawn pos yaw being ignored + // CraftBukkit end + } + +@@ -69,7 +69,7 @@ public record TeleportTransition(ServerLevel newLevel, Vec3 position, Vec3 delta + } + + public static TeleportTransition missingRespawnBlock(ServerLevel world, Entity entity, TeleportTransition.PostTeleportTransition postDimensionTransition) { +- return new TeleportTransition(world, findAdjustedSharedSpawnPos(world, entity), Vec3.ZERO, 0.0F, 0.0F, true, false, Set.of(), postDimensionTransition); ++ return new TeleportTransition(world, findAdjustedSharedSpawnPos(world, entity), Vec3.ZERO, world.getSharedSpawnAngle(), 0.0F, true, false, Set.of(), postDimensionTransition); // Paper - MC-200092 - fix spawn pos yaw being ignored + } + + private static Vec3 findAdjustedSharedSpawnPos(ServerLevel world, Entity entity) { diff --git a/patches/server/0767-Player-Entity-Tracking-Events.patch b/patches/server/0767-Player-Entity-Tracking-Events.patch index 8010e7f0d6a6..5b5c2566a065 100644 --- a/patches/server/0767-Player-Entity-Tracking-Events.patch +++ b/patches/server/0767-Player-Entity-Tracking-Events.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Player Entity Tracking Events diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index e1c69c3c8e4809c7ccd2e1e12ee8538ab4bd3d5c..53e180e230d5a1652f3e19193243c37095d6b39e 100644 +index 51a6735b35e73175680e61c2d67d4adbedf305c9..8b5d11aceb77135c917c3581f4db792ef4b647ec 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1586,7 +1586,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0843-Cache-map-ids-on-item-frames.patch b/patches/server/0843-Cache-map-ids-on-item-frames.patch index 38554e1a9c2f..01fb83165d8b 100644 --- a/patches/server/0843-Cache-map-ids-on-item-frames.patch +++ b/patches/server/0843-Cache-map-ids-on-item-frames.patch @@ -18,7 +18,7 @@ index 3cdcc4f44608d24550f2a8c6f3f5ce675d7777c5..7118e1f806af98159ec292f9340d7e40 if (worldmap != null) { diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -index 65f7f1f98f415a564aadb440d3a67143699e43db..d6f835320014c07f9d174d05929ed8cc16a10c10 100644 +index d431ee93cd7e87a24ff4079288facd089053d725..bbdaaa1cc0b4aed28bc39385508d221055b99d4d 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java @@ -51,6 +51,7 @@ public class ItemFrame extends HangingEntity { diff --git a/patches/server/0853-Configurable-entity-tracking-range-by-Y-coordinate.patch b/patches/server/0853-Configurable-entity-tracking-range-by-Y-coordinate.patch index a8f7a157ae07..feb7011cca5a 100644 --- a/patches/server/0853-Configurable-entity-tracking-range-by-Y-coordinate.patch +++ b/patches/server/0853-Configurable-entity-tracking-range-by-Y-coordinate.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Configurable entity tracking range by Y coordinate Options to configure entity tracking by Y coordinate, also for each entity category. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 53e180e230d5a1652f3e19193243c37095d6b39e..5da3eee41ba0cbec5932cf9a7dac53777a2463fb 100644 +index 8b5d11aceb77135c917c3581f4db792ef4b647ec..5b993cb8a99c6a0257b9d3d93162f9b2fff552b0 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1577,7 +1577,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0885-Don-t-check-if-we-can-see-non-visible-entities.patch b/patches/server/0885-Don-t-check-if-we-can-see-non-visible-entities.patch index 00d8ff96c11e..5a591c2450e2 100644 --- a/patches/server/0885-Don-t-check-if-we-can-see-non-visible-entities.patch +++ b/patches/server/0885-Don-t-check-if-we-can-see-non-visible-entities.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Don't check if we can see non-visible entities diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 5da3eee41ba0cbec5932cf9a7dac53777a2463fb..bf6d5f9e23387da845d6fe246c9013ec4d13cfb1 100644 +index 5b993cb8a99c6a0257b9d3d93162f9b2fff552b0..7483f9f2639c58a4f43e264211791f4377e1db64 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1590,7 +1590,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch b/patches/server/0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch index cd53371b6bf7..c1b9e8e12bec 100644 --- a/patches/server/0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch +++ b/patches/server/0914-Reduce-allocation-of-Vec3D-by-entity-tracker.patch @@ -18,7 +18,7 @@ index a043ac10834562d357ef0b5aded2e916e2a0d056..74276c368016fcc4dbf9579b2ecbadc9 @VisibleForTesting static long encode(double value) { diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index bf6d5f9e23387da845d6fe246c9013ec4d13cfb1..9b64dfe8f1727519673cc87be2398d43601e68ef 100644 +index 7483f9f2639c58a4f43e264211791f4377e1db64..7317c353edab8b11d9d94e257f968ac49284f47a 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1572,10 +1572,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/1038-Moonrise-optimisation-patches.patch b/patches/server/1038-Moonrise-optimisation-patches.patch index f7408d9d931a..a6bd51f78b78 100644 --- a/patches/server/1038-Moonrise-optimisation-patches.patch +++ b/patches/server/1038-Moonrise-optimisation-patches.patch @@ -24141,7 +24141,7 @@ index d9ad32acdf46a43a649334a3b736aeb7b3af21d1..fae17a075d7efaf24d916877dd5968eb public static final int RADIUS_AROUND_FULL_CHUNK = FULL_CHUNK_STEP.accumulatedDependencies().getRadius(); public static final int MAX_LEVEL = 33 + RADIUS_AROUND_FULL_CHUNK; diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 9b64dfe8f1727519673cc87be2398d43601e68ef..c11ba8d9e97a68cda1811b570f0df117e6c38138 100644 +index 7317c353edab8b11d9d94e257f968ac49284f47a..cb3850939955ae068d4776c835522e0b8f228984 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -108,7 +108,7 @@ import org.slf4j.Logger; diff --git a/patches/server/1050-Fix-entity-tracker-desync-when-new-players-are-added.patch b/patches/server/1050-Fix-entity-tracker-desync-when-new-players-are-added.patch index c123fccefa59..99803672f26e 100644 --- a/patches/server/1050-Fix-entity-tracker-desync-when-new-players-are-added.patch +++ b/patches/server/1050-Fix-entity-tracker-desync-when-new-players-are-added.patch @@ -48,7 +48,7 @@ index f6e1deb2f849d8b01b15cfa69e2f6cd5f2b1512b..f66e40326c510aa3267542b1a24ed75d entityTrackerEntry.getLastSentYRot(), entity.getType(), diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index c11ba8d9e97a68cda1811b570f0df117e6c38138..c7a9a22d84583764fc1cbcc1bdeb01a339d33687 100644 +index cb3850939955ae068d4776c835522e0b8f228984..f1999729cd1c00071c5e1835ee49ea5fcafa7b05 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1271,6 +1271,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/1053-Optional-per-player-mob-spawns.patch b/patches/server/1053-Optional-per-player-mob-spawns.patch index 604904f337ac..e002a911c0cb 100644 --- a/patches/server/1053-Optional-per-player-mob-spawns.patch +++ b/patches/server/1053-Optional-per-player-mob-spawns.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Optional per player mob spawns diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index c7a9a22d84583764fc1cbcc1bdeb01a339d33687..c9e5df9a598a1211aeba88920e774b0f765b3a14 100644 +index f1999729cd1c00071c5e1835ee49ea5fcafa7b05..4896c3ba81ead769972fa9efdbe563d4006e4401 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -229,8 +229,26 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/1054-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch b/patches/server/1054-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch index e9cea51b0d06..0bc36284ccbb 100644 --- a/patches/server/1054-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch +++ b/patches/server/1054-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Improve cancelling PreCreatureSpawnEvent with per player mob diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index c9e5df9a598a1211aeba88920e774b0f765b3a14..f4b578c7f839f58da265f2cbcb53e5654ca3edc8 100644 +index 4896c3ba81ead769972fa9efdbe563d4006e4401..5b3a886c624b36557cbfaccdc3fb05a46a4ba36a 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -246,8 +246,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider From 1196ab550520c50ea6b9cb173385b8dee57d18de Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Tue, 29 Oct 2024 12:46:33 -0700 Subject: [PATCH 110/119] Avoid issues with certain tasks not processing during sleep (#11526) --- ...h-certain-tasks-not-processing-durin.patch | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 patches/server/1055-Avoid-issues-with-certain-tasks-not-processing-durin.patch diff --git a/patches/server/1055-Avoid-issues-with-certain-tasks-not-processing-durin.patch b/patches/server/1055-Avoid-issues-with-certain-tasks-not-processing-durin.patch new file mode 100644 index 000000000000..b61b952456f4 --- /dev/null +++ b/patches/server/1055-Avoid-issues-with-certain-tasks-not-processing-durin.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> +Date: Sun, 27 Oct 2024 14:18:28 -0700 +Subject: [PATCH] Avoid issues with certain tasks not processing during sleep + +Execute processQueue tasks during sleep: needed for console tab completions, pre join event, etc. + +Upstream has set precedent that the bukkit scheduler will still tick during sleep, which avoids some problems +with plugins not accounting for the new sleep feature, but can still lead to others. Because of this we have disabled +sleep by default, which avoids the problem and makes it more obvious to check if this is the cause of issues when +enabled. We also unload chunks during sleep to prevent memory leaks caused by plugin chunk loads. + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index af7c6f56444c0e495fd39da872f8030199afc634..7933d6900dac67a24fb5f9378097dbde34be30b1 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -1639,6 +1639,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop true, false); ++ } ++ // Paper end - avoid issues with certain tasks not processing during sleep + this.server.spark.executeMainThreadTasks(); // Paper - spark + this.tickConnection(); + this.server.spark.tickEnd(((double)(System.nanoTime() - lastTick) / 1000000D)); // Paper - spark +diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java +index 52e61f75f922a075ccc745198f4ba6ad8fa58ea2..149a542c4afa09d491cb33ae33563ba15786758d 100644 +--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java ++++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java +@@ -160,7 +160,7 @@ public class DedicatedServerProperties extends Settings Date: Tue, 29 Oct 2024 22:35:10 +0100 Subject: [PATCH 111/119] Fix portal exit resulting in bad teleport transition --- .../0578-Add-back-EntityPortalExitEvent.patch | 17 ++++++++++------- ...0589-Add-Raw-Byte-Entity-Serialization.patch | 2 +- ...Update-head-rotation-in-missing-places.patch | 2 +- ...on-t-attempt-to-teleport-dead-entities.patch | 2 +- ...orward-CraftEntity-in-teleport-command.patch | 4 ++-- patches/server/0650-Freeze-Tick-Lock-API.patch | 2 +- ...-passenger-world-matches-ridden-entity.patch | 2 +- ...t-entity-loading-causing-async-lookups.patch | 2 +- ...ious-missing-EntityDropItemEvent-calls.patch | 2 +- ...ustEvent-cancellation-cant-fully-preve.patch | 2 +- .../0767-Player-Entity-Tracking-Events.patch | 4 ++-- patches/server/0774-Improve-PortalEvents.patch | 4 ++-- ...lision-moving-velocity-to-VehicleBlock.patch | 2 +- ...fresh-ProjectileSource-for-projectiles.patch | 2 +- ...oad-chunks-for-supporting-block-checks.patch | 2 +- ...5-Folia-scheduler-and-owned-region-API.patch | 6 +++--- patches/server/0858-Expand-Pose-API.patch | 2 +- patches/server/0865-Fix-slot-desync.patch | 2 +- ...Don-t-fire-sync-events-during-worldgen.patch | 2 +- ...-Restore-vanilla-entity-drops-behavior.patch | 2 +- patches/server/0934-Fix-DamageSource-API.patch | 2 +- .../0978-Entity-Activation-Range-2.0.patch | 2 +- ...-Optimize-Collision-to-not-load-chunks.patch | 2 +- .../server/0992-Properly-resend-entities.patch | 2 +- .../1032-Void-damage-configuration-API.patch | 2 +- .../1038-Moonrise-optimisation-patches.patch | 14 +++++++------- ...ail-more-information-in-watchdog-dumps.patch | 6 +++--- 27 files changed, 49 insertions(+), 46 deletions(-) diff --git a/patches/server/0578-Add-back-EntityPortalExitEvent.patch b/patches/server/0578-Add-back-EntityPortalExitEvent.patch index 2ddd256c17c9..a0823113061c 100644 --- a/patches/server/0578-Add-back-EntityPortalExitEvent.patch +++ b/patches/server/0578-Add-back-EntityPortalExitEvent.patch @@ -5,26 +5,28 @@ Subject: [PATCH] Add back EntityPortalExitEvent diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index fe9cdd104d6203233a90068b55e0876be4964afe..8dc2684a748e19e14c3efedf58be5efba99a45b4 100644 +index fe9cdd104d6203233a90068b55e0876be4964afe..96d73407edd440c16d41c8a586797ade30792f46 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -3491,7 +3491,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3491,7 +3491,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess if (!this.isRemoved()) { // CraftBukkit start PositionMoveRotation absolutePosition = PositionMoveRotation.calculateAbsolute(PositionMoveRotation.of(this), PositionMoveRotation.of(teleportTarget), teleportTarget.relatives()); - Location to = CraftLocation.toBukkit(absolutePosition.position(), teleportTarget.newLevel().getWorld(), absolutePosition.yRot(), absolutePosition.xRot()); ++ Vec3 velocity = absolutePosition.deltaMovement(); // Paper + Location to = CraftLocation.toBukkit(absolutePosition.position(), teleportTarget.newLevel().getWorld(), absolutePosition.yRot(), this.getXRot()); // Paper - use getXRot (doesn't respect DimensionTransition pitch) // Why? // Paper start - gateway-specific teleport event final EntityTeleportEvent teleEvent; if (this.portalProcess != null && this.portalProcess.isSamePortal(((net.minecraft.world.level.block.EndGatewayBlock) net.minecraft.world.level.block.Blocks.END_GATEWAY)) && this.level.getBlockEntity(this.portalProcess.getEntryPosition()) instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity theEndGatewayBlockEntity) { -@@ -3508,6 +3508,27 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3507,7 +3508,29 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + if (!to.equals(teleEvent.getTo())) { to = teleEvent.getTo(); teleportTarget = new TeleportTransition(((CraftWorld) to.getWorld()).getHandle(), CraftLocation.toVec3D(to), Vec3.ZERO, to.getYaw(), to.getPitch(), teleportTarget.missingRespawnBlock(), teleportTarget.asPassenger(), Set.of(), teleportTarget.postTeleportTransition(), teleportTarget.cause()); ++ // Paper start - Call EntityPortalExitEvent ++ velocity = Vec3.ZERO; } -+ // Paper start - Call EntityPortalExitEvent + if (this.portalProcess != null) { // if in a portal + CraftEntity bukkitEntity = this.getBukkitEntity(); -+ Vec3 velocity = teleportTarget.deltaMovement(); + org.bukkit.event.entity.EntityPortalExitEvent event = new org.bukkit.event.entity.EntityPortalExitEvent( + bukkitEntity, + bukkitEntity.getLocation(), to.clone(), @@ -32,11 +34,12 @@ index fe9cdd104d6203233a90068b55e0876be4964afe..8dc2684a748e19e14c3efedf58be5efb + ); + event.callEvent(); + -+ if (!event.isCancelled() && event.getTo() != null) { ++ // Only change the target if actually needed, since we reset relative flags ++ if (!event.isCancelled() && event.getTo() != null && (!event.getTo().equals(event.getFrom()) || !event.getAfter().equals(event.getBefore()))) { + to = event.getTo().clone(); + velocity = org.bukkit.craftbukkit.util.CraftVector.toNMS(event.getAfter()); ++ teleportTarget = new TeleportTransition(((CraftWorld) to.getWorld()).getHandle(), CraftLocation.toVec3D(to), velocity, to.getYaw(), to.getPitch(), teleportTarget.missingRespawnBlock(), teleportTarget.asPassenger(), Set.of(), teleportTarget.postTeleportTransition(), teleportTarget.cause()); + } -+ teleportTarget = new TeleportTransition(((CraftWorld) to.getWorld()).getHandle(), CraftLocation.toVec3D(to), velocity, to.getYaw(), to.getPitch(), teleportTarget.missingRespawnBlock(), teleportTarget.asPassenger(), Set.of(), teleportTarget.postTeleportTransition(), teleportTarget.cause()); + } + if (this.isRemoved()) { + return null; diff --git a/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch b/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch index 0b866c52fb33..24a102b9d622 100644 --- a/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch +++ b/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Add Raw Byte Entity Serialization public net.minecraft.world.entity.Entity setLevel(Lnet/minecraft/world/level/Level;)V diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 8dc2684a748e19e14c3efedf58be5efba99a45b4..11b3a0ece27cb2c01b908a9ac0c3d75f407f5ed0 100644 +index 96d73407edd440c16d41c8a586797ade30792f46..66b1711a4e05270f15703229459f4bebb2fb19b7 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2260,6 +2260,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0615-Update-head-rotation-in-missing-places.patch b/patches/server/0615-Update-head-rotation-in-missing-places.patch index c1f529129db3..d24623bdc1b2 100644 --- a/patches/server/0615-Update-head-rotation-in-missing-places.patch +++ b/patches/server/0615-Update-head-rotation-in-missing-places.patch @@ -8,7 +8,7 @@ This is because bukkit uses a separate head rotation field for yaw. This issue only applies to players. diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 11b3a0ece27cb2c01b908a9ac0c3d75f407f5ed0..7b01d1cd5db771a1b6ee030664070ffb75579a4c 100644 +index 66b1711a4e05270f15703229459f4bebb2fb19b7..58949beb5fcdc1618674f206feb90d0f5335c67f 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -1914,6 +1914,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0621-don-t-attempt-to-teleport-dead-entities.patch b/patches/server/0621-don-t-attempt-to-teleport-dead-entities.patch index 89c8f26c2c18..7963ba88c516 100644 --- a/patches/server/0621-don-t-attempt-to-teleport-dead-entities.patch +++ b/patches/server/0621-don-t-attempt-to-teleport-dead-entities.patch @@ -5,7 +5,7 @@ Subject: [PATCH] don't attempt to teleport dead entities diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 7b01d1cd5db771a1b6ee030664070ffb75579a4c..34cbb7c48535da774527b40f2e99f6f1d31c377d 100644 +index 58949beb5fcdc1618674f206feb90d0f5335c67f..1cb02ee453133f6f019887ec02d2d2aca958a959 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -713,7 +713,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0631-Forward-CraftEntity-in-teleport-command.patch b/patches/server/0631-Forward-CraftEntity-in-teleport-command.patch index 908c4651291b..257107983669 100644 --- a/patches/server/0631-Forward-CraftEntity-in-teleport-command.patch +++ b/patches/server/0631-Forward-CraftEntity-in-teleport-command.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Forward CraftEntity in teleport command diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 34cbb7c48535da774527b40f2e99f6f1d31c377d..3df8cfccba9bc4420b37dcbdfc4a12c720b51205 100644 +index 1cb02ee453133f6f019887ec02d2d2aca958a959..f2dbeb6b1bdcd447b24fb06279301bcbca489511 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -3480,6 +3480,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -22,7 +22,7 @@ index 34cbb7c48535da774527b40f2e99f6f1d31c377d..3df8cfccba9bc4420b37dcbdfc4a12c7 CompoundTag nbttagcompound = original.saveWithoutId(new CompoundTag()); nbttagcompound.remove("Dimension"); -@@ -3615,8 +3622,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3617,8 +3624,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess entity.restoreFrom(this); this.removeAfterChangingDimensions(); // CraftBukkit start - Forward the CraftEntity to the new entity diff --git a/patches/server/0650-Freeze-Tick-Lock-API.patch b/patches/server/0650-Freeze-Tick-Lock-API.patch index f658b3b299c7..c882f88035f3 100644 --- a/patches/server/0650-Freeze-Tick-Lock-API.patch +++ b/patches/server/0650-Freeze-Tick-Lock-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Freeze Tick Lock API diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 3df8cfccba9bc4420b37dcbdfc4a12c720b51205..4f9ebf7a577223d85ceaad0babd2d0b4f492b6df 100644 +index f2dbeb6b1bdcd447b24fb06279301bcbca489511..954c70b45a0d96d16332424a7d31e4241088601f 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -414,6 +414,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0680-Ensure-entity-passenger-world-matches-ridden-entity.patch b/patches/server/0680-Ensure-entity-passenger-world-matches-ridden-entity.patch index 62372a6087fc..184e75059ae2 100644 --- a/patches/server/0680-Ensure-entity-passenger-world-matches-ridden-entity.patch +++ b/patches/server/0680-Ensure-entity-passenger-world-matches-ridden-entity.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Ensure entity passenger world matches ridden entity Bad plugins doing this would cause some obvious problems... diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 4f9ebf7a577223d85ceaad0babd2d0b4f492b6df..a4a07dc11edf3738698deed929cc224ff7114684 100644 +index 954c70b45a0d96d16332424a7d31e4241088601f..47e7405db3f8cfd674ec7704e8d40b628e94678b 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2802,7 +2802,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0701-Prevent-entity-loading-causing-async-lookups.patch b/patches/server/0701-Prevent-entity-loading-causing-async-lookups.patch index 97d528c05ac1..3d298a96af7c 100644 --- a/patches/server/0701-Prevent-entity-loading-causing-async-lookups.patch +++ b/patches/server/0701-Prevent-entity-loading-causing-async-lookups.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Prevent entity loading causing async lookups diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index a4a07dc11edf3738698deed929cc224ff7114684..73428cefa737e430c3c8c0d59e1fa763114b8c5a 100644 +index 47e7405db3f8cfd674ec7704e8d40b628e94678b..f13b9050c4de9ddc7a8620b89478df20bccafe06 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -724,6 +724,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0713-Add-various-missing-EntityDropItemEvent-calls.patch b/patches/server/0713-Add-various-missing-EntityDropItemEvent-calls.patch index 8e1fc7a091ae..758e8905c21d 100644 --- a/patches/server/0713-Add-various-missing-EntityDropItemEvent-calls.patch +++ b/patches/server/0713-Add-various-missing-EntityDropItemEvent-calls.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add various missing EntityDropItemEvent calls diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 73428cefa737e430c3c8c0d59e1fa763114b8c5a..619879bc0a05e16d450b4f7bb766b371e986193c 100644 +index f13b9050c4de9ddc7a8620b89478df20bccafe06..73882f5b5a25779841b3a8fe507bbb92cf113691 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2672,6 +2672,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0754-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch b/patches/server/0754-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch index ab6fac6da32f..231d47c34bb1 100644 --- a/patches/server/0754-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch +++ b/patches/server/0754-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Fix EntityCombustEvent cancellation cant fully prevent diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 619879bc0a05e16d450b4f7bb766b371e986193c..8aabd17178543eab0724a05226e4741ead85ea87 100644 +index 73882f5b5a25779841b3a8fe507bbb92cf113691..eeefe0a8f36618d6df513d9ea5443e222ae8826e 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -3320,6 +3320,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0767-Player-Entity-Tracking-Events.patch b/patches/server/0767-Player-Entity-Tracking-Events.patch index 5b5c2566a065..fd7aeb4e069c 100644 --- a/patches/server/0767-Player-Entity-Tracking-Events.patch +++ b/patches/server/0767-Player-Entity-Tracking-Events.patch @@ -21,10 +21,10 @@ index 51a6735b35e73175680e61c2d67d4adbedf305c9..8b5d11aceb77135c917c3581f4db792e } else if (this.seenBy.remove(player.connection)) { this.serverEntity.removePairing(player); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 8aabd17178543eab0724a05226e4741ead85ea87..47a2cd3ea7c88681929351c6db9090149e2c4f2e 100644 +index eeefe0a8f36618d6df513d9ea5443e222ae8826e..149852c5ed532c1bbb4f647c0988d282915fa43d 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -4069,7 +4069,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4071,7 +4071,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public void startSeenByPlayer(ServerPlayer player) {} diff --git a/patches/server/0774-Improve-PortalEvents.patch b/patches/server/0774-Improve-PortalEvents.patch index a4cf96f882ce..dc475e1825f2 100644 --- a/patches/server/0774-Improve-PortalEvents.patch +++ b/patches/server/0774-Improve-PortalEvents.patch @@ -18,10 +18,10 @@ index 25b1e8bec23465f0e9a17f156bdff7fe716db84c..f05a9fd321a4af28e9771bbf39d73f80 // Paper start - gateway-specific teleport event if (this.portalProcess != null && this.portalProcess.isSamePortal(((net.minecraft.world.level.block.EndGatewayBlock) net.minecraft.world.level.block.Blocks.END_GATEWAY)) && this.serverLevel().getBlockEntity(this.portalProcess.getEntryPosition()) instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity theEndGatewayBlockEntity) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 47a2cd3ea7c88681929351c6db9090149e2c4f2e..37419819758574631486886307f3133a8a3c1c36 100644 +index 149852c5ed532c1bbb4f647c0988d282915fa43d..4ad6ba0b5f7b53943643be2abb0590748222e984 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -3740,7 +3740,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3742,7 +3742,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity(); Location enter = bukkitEntity.getLocation(); diff --git a/patches/server/0779-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch b/patches/server/0779-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch index c08dab2b2da1..8b27b7a489cd 100644 --- a/patches/server/0779-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch +++ b/patches/server/0779-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Expose pre-collision moving velocity to diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 37419819758574631486886307f3133a8a3c1c36..0e52f67f0185cba47838f0a99a97b4d70314c8fa 100644 +index 4ad6ba0b5f7b53943643be2abb0590748222e984..19c200743c4b5384f2b43554cfe29eafcea9b227 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -968,6 +968,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0809-Refresh-ProjectileSource-for-projectiles.patch b/patches/server/0809-Refresh-ProjectileSource-for-projectiles.patch index eee4855e6b1a..dcbbac97e127 100644 --- a/patches/server/0809-Refresh-ProjectileSource-for-projectiles.patch +++ b/patches/server/0809-Refresh-ProjectileSource-for-projectiles.patch @@ -14,7 +14,7 @@ clearing the owner. Co-authored-by: Warrior <50800980+Warriorrrr@users.noreply.github.com> diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 0e52f67f0185cba47838f0a99a97b4d70314c8fa..e126f1d5117a5826c5bfec20719633d7ca5f2870 100644 +index 19c200743c4b5384f2b43554cfe29eafcea9b227..2397f88634aef5abce427c0cd751bdbfc6455b38 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -393,6 +393,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0823-Don-t-load-chunks-for-supporting-block-checks.patch b/patches/server/0823-Don-t-load-chunks-for-supporting-block-checks.patch index 5f0cc1154678..d55a98cf81c0 100644 --- a/patches/server/0823-Don-t-load-chunks-for-supporting-block-checks.patch +++ b/patches/server/0823-Don-t-load-chunks-for-supporting-block-checks.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Don't load chunks for supporting block checks diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index e126f1d5117a5826c5bfec20719633d7ca5f2870..3444b1a2da80b85e2b1928d69ff0dd980c5fb34f 100644 +index 2397f88634aef5abce427c0cd751bdbfc6455b38..72cb4a97188596db49e69fd2a332fea907d10456 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -1228,7 +1228,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0835-Folia-scheduler-and-owned-region-API.patch b/patches/server/0835-Folia-scheduler-and-owned-region-API.patch index 3ff79fb2c604..ae8d94eb4791 100644 --- a/patches/server/0835-Folia-scheduler-and-owned-region-API.patch +++ b/patches/server/0835-Folia-scheduler-and-owned-region-API.patch @@ -1185,7 +1185,7 @@ index cbba549176b3acfc25ec42c2935b31ab2176e0fa..4ac0bb0ec3222ebdd3fa386696dcb072 this.players.remove(entityplayer); this.playersByName.remove(entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 3444b1a2da80b85e2b1928d69ff0dd980c5fb34f..463dd4f91212318b51174c5d2f4d25ba95c25f50 100644 +index 72cb4a97188596db49e69fd2a332fea907d10456..8695e003e20912840d4968adf81c17cb8b545096 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -262,10 +262,21 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -1211,7 +1211,7 @@ index 3444b1a2da80b85e2b1928d69ff0dd980c5fb34f..463dd4f91212318b51174c5d2f4d25ba // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir() public int getDefaultMaxAirSupply() { -@@ -4674,6 +4685,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4676,6 +4687,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public final void setRemoved(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit end @@ -1219,7 +1219,7 @@ index 3444b1a2da80b85e2b1928d69ff0dd980c5fb34f..463dd4f91212318b51174c5d2f4d25ba if (this.removalReason == null) { this.removalReason = entity_removalreason; } -@@ -4685,12 +4697,28 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4687,12 +4699,28 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.getPassengers().forEach(Entity::stopRiding); this.levelCallback.onRemove(entity_removalreason); this.onRemoval(entity_removalreason); diff --git a/patches/server/0858-Expand-Pose-API.patch b/patches/server/0858-Expand-Pose-API.patch index 47312a863501..836f4405e5d8 100644 --- a/patches/server/0858-Expand-Pose-API.patch +++ b/patches/server/0858-Expand-Pose-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Expand Pose API diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 463dd4f91212318b51174c5d2f4d25ba95c25f50..eadea35bcb9c2a8d65789e09dbabe7cb4a126542 100644 +index 8695e003e20912840d4968adf81c17cb8b545096..5c1ee438e85167ab6382f18421f14e2a1ea0acf1 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -427,6 +427,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0865-Fix-slot-desync.patch b/patches/server/0865-Fix-slot-desync.patch index 7c1808398cb9..089eb53892f3 100644 --- a/patches/server/0865-Fix-slot-desync.patch +++ b/patches/server/0865-Fix-slot-desync.patch @@ -40,7 +40,7 @@ index b840f7aac9c830b8aa0aa133bf43f87dfc598b2c..0cb0d2f863efb86bb589b30bae61ac57 if (event.isCancelled()) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index eadea35bcb9c2a8d65789e09dbabe7cb4a126542..c0539c8826a60cbe25855319cc174fb1520798c0 100644 +index 5c1ee438e85167ab6382f18421f14e2a1ea0acf1..18147e93d99417e696cbb24603fec2aa0a1057e3 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2752,8 +2752,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch b/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch index f530a9f4e784..a45762da8fb6 100644 --- a/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch +++ b/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch @@ -31,7 +31,7 @@ index 7cecbac43f1cd2d9516034ea9d2633c0c76e61f4..7a985c30a973efacf3e8b70e7163c550 if (entity.valid) { MinecraftServer.LOGGER.error("Attempted Double World add on {}", entity, new Throwable()); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index c0539c8826a60cbe25855319cc174fb1520798c0..02b9d280486a23d8eef650566dfaa10ac0b96c9c 100644 +index 18147e93d99417e696cbb24603fec2aa0a1057e3..d495c20f337594507114cde436d759c9a81451b4 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -631,7 +631,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch b/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch index c19f1327f4a0..489f9a4c1a5d 100644 --- a/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch +++ b/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch @@ -37,7 +37,7 @@ index 419fcb4cd97cf10a2601e02024b999a51a0ff952..df21cd1bd2a3dda7169edbea18bbfdf0 loot.addAll(this.drops); this.drops.clear(); // SPIGOT-5188: make sure to clear diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 02b9d280486a23d8eef650566dfaa10ac0b96c9c..cdc5ea3dd9559c076049c86a9fdb4e8bf85ff6c0 100644 +index d495c20f337594507114cde436d759c9a81451b4..189bc1bcd902a37f684a980088578c19ba66ceb5 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2678,19 +2678,45 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0934-Fix-DamageSource-API.patch b/patches/server/0934-Fix-DamageSource-API.patch index 113d204beef2..c8083b462480 100644 --- a/patches/server/0934-Fix-DamageSource-API.patch +++ b/patches/server/0934-Fix-DamageSource-API.patch @@ -84,7 +84,7 @@ index fddbdb7322a2063996a28c5c3d93c265188b1256..be87cb3cfa15a7d889118cdc4b87232e public DamageSource sonicBoom(Entity attacker) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index cdc5ea3dd9559c076049c86a9fdb4e8bf85ff6c0..23095ace5a6aa6fd6cc1d5defa4a783ccb637b1d 100644 +index 189bc1bcd902a37f684a980088578c19ba66ceb5..51dc99e367e8b9d6b2373d1f8e01dfa3ed34a283 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -3388,7 +3388,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0978-Entity-Activation-Range-2.0.patch b/patches/server/0978-Entity-Activation-Range-2.0.patch index a4edc8e8a090..e2e0609b445e 100644 --- a/patches/server/0978-Entity-Activation-Range-2.0.patch +++ b/patches/server/0978-Entity-Activation-Range-2.0.patch @@ -88,7 +88,7 @@ index ce148cf5930cdcf0163c7f6416cbbd89e4d22720..75c388a5c9de26f0053015619e6c19bc } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 23095ace5a6aa6fd6cc1d5defa4a783ccb637b1d..9a37a898eba0cd9ab18ec5ee241cf054c8a71b32 100644 +index 51dc99e367e8b9d6b2373d1f8e01dfa3ed34a283..2cc92228d48b78e8318c106bfe49e06f56256927 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -420,6 +420,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch b/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch index 27b03b47bf0c..0a4446e68f71 100644 --- a/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch +++ b/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch @@ -26,7 +26,7 @@ index 7097d87dead028c8dd44cefc97694bada93f608b..751fc4b0fe60c6d26ea0f768f3d66031 if (teleporttransition.missingRespawnBlock()) { entityplayer1.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0F)); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 9a37a898eba0cd9ab18ec5ee241cf054c8a71b32..aa7d3383c773d3537335e449636f33d69cde12bb 100644 +index 2cc92228d48b78e8318c106bfe49e06f56256927..0a26653eb6d72b646bedeba3839868241851c1c9 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -258,6 +258,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0992-Properly-resend-entities.patch b/patches/server/0992-Properly-resend-entities.patch index 3b68910eac57..5487d9a3b175 100644 --- a/patches/server/0992-Properly-resend-entities.patch +++ b/patches/server/0992-Properly-resend-entities.patch @@ -134,7 +134,7 @@ index 751fc4b0fe60c6d26ea0f768f3d66031a4bad963..700ab5ef2f8ab1466c4f659cd34679dc } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index aa7d3383c773d3537335e449636f33d69cde12bb..6a0472eaae9ad890692862590b8d23110e48536d 100644 +index 0a26653eb6d72b646bedeba3839868241851c1c9..28d4c6d308f2c69b22d21302e4fa505162a1d782 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -598,13 +598,45 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/1032-Void-damage-configuration-API.patch b/patches/server/1032-Void-damage-configuration-API.patch index 0bebf025157e..d14c24317793 100644 --- a/patches/server/1032-Void-damage-configuration-API.patch +++ b/patches/server/1032-Void-damage-configuration-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Void damage configuration API diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 6a0472eaae9ad890692862590b8d23110e48536d..7d16f9935407931823ad3e420f336c7ec69528b2 100644 +index 28d4c6d308f2c69b22d21302e4fa505162a1d782..fc958b43ce0972362eb3be76ec6b9f7388f45f22 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -853,8 +853,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/1038-Moonrise-optimisation-patches.patch b/patches/server/1038-Moonrise-optimisation-patches.patch index a6bd51f78b78..529aeae1685b 100644 --- a/patches/server/1038-Moonrise-optimisation-patches.patch +++ b/patches/server/1038-Moonrise-optimisation-patches.patch @@ -28416,7 +28416,7 @@ index 50040c497a819cd1229042ab3cb057d34a32cacc..1f9c436a632e4f110be61cf76fcfc3b7 + // Paper end - block counting } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 7d16f9935407931823ad3e420f336c7ec69528b2..b36a915e6d337d7ec3f797bf1773b14c5b231d76 100644 +index fc958b43ce0972362eb3be76ec6b9f7388f45f22..288f9cdf57bb9356a048d8d3d795e9a7a1b3a216 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -175,7 +175,7 @@ import org.bukkit.event.player.PlayerTeleportEvent; @@ -28808,7 +28808,7 @@ index 7d16f9935407931823ad3e420f336c7ec69528b2..b36a915e6d337d7ec3f797bf1773b14c } public InteractionResult interact(Player player, InteractionHand hand) { -@@ -4269,14 +4546,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4271,14 +4548,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public Iterable getIndirectPassengers() { @@ -28833,7 +28833,7 @@ index 7d16f9935407931823ad3e420f336c7ec69528b2..b36a915e6d337d7ec3f797bf1773b14c } private Iterable getIndirectPassengers_old() { // Paper end - Optimize indirect passenger iteration -@@ -4405,82 +4685,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4407,82 +4687,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return Mth.lerp(delta, this.yRotO, this.yRot); } @@ -29028,7 +29028,7 @@ index 7d16f9935407931823ad3e420f336c7ec69528b2..b36a915e6d337d7ec3f797bf1773b14c public boolean touchingUnloadedChunk() { AABB axisalignedbb = this.getBoundingBox().inflate(1.0D); -@@ -4632,6 +4966,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4634,6 +4968,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.setPosRaw(x, y, z, false); } public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) { @@ -29044,7 +29044,7 @@ index 7d16f9935407931823ad3e420f336c7ec69528b2..b36a915e6d337d7ec3f797bf1773b14c if (!checkPosition(this, x, y, z)) { return; } -@@ -4761,6 +5104,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4763,6 +5106,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public final void setRemoved(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { @@ -29057,7 +29057,7 @@ index 7d16f9935407931823ad3e420f336c7ec69528b2..b36a915e6d337d7ec3f797bf1773b14c CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit end final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers -@@ -4772,7 +5121,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4774,7 +5123,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.stopRiding(); } @@ -29066,7 +29066,7 @@ index 7d16f9935407931823ad3e420f336c7ec69528b2..b36a915e6d337d7ec3f797bf1773b14c this.levelCallback.onRemove(entity_removalreason); this.onRemoval(entity_removalreason); // Paper start - Folia schedulers -@@ -4804,7 +5153,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4806,7 +5155,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public boolean shouldBeSaved() { diff --git a/patches/server/1043-Detail-more-information-in-watchdog-dumps.patch b/patches/server/1043-Detail-more-information-in-watchdog-dumps.patch index 46e97e3b0d65..e23f02def30f 100644 --- a/patches/server/1043-Detail-more-information-in-watchdog-dumps.patch +++ b/patches/server/1043-Detail-more-information-in-watchdog-dumps.patch @@ -121,7 +121,7 @@ index 9af879115a24145ec290ac200565004e49ee7b0b..c9d7ea8fbaf8858564282b42f6f6dda3 private void tickPassenger(Entity vehicle, Entity passenger, boolean isActive) { // Paper - EAR 2 diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index b36a915e6d337d7ec3f797bf1773b14c5b231d76..6817015f0cf39df03029e36cd845d590618031dc 100644 +index 288f9cdf57bb9356a048d8d3d795e9a7a1b3a216..bc81faf083e2a5455a7da0ba7cc18eae5e014a7a 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -1171,8 +1171,43 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -182,7 +182,7 @@ index b36a915e6d337d7ec3f797bf1773b14c5b231d76..6817015f0cf39df03029e36cd845d590 } private void applyMovementEmissionAndPlaySound(Entity.MovementEmission moveEffect, Vec3 movement, BlockPos landingPos, BlockState landingState) { -@@ -4884,7 +4926,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4886,7 +4928,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public void setDeltaMovement(Vec3 velocity) { @@ -192,7 +192,7 @@ index b36a915e6d337d7ec3f797bf1773b14c5b231d76..6817015f0cf39df03029e36cd845d590 } public void addDeltaMovement(Vec3 velocity) { -@@ -4990,7 +5034,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4992,7 +5036,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } // Paper end - Fix MC-4 if (this.position.x != x || this.position.y != y || this.position.z != z) { From 9f1fa0b4f8ea807b0adab45660b1ad8f89f267ef Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Wed, 30 Oct 2024 14:06:43 +0100 Subject: [PATCH 112/119] Fix item gravity on inactive items, remove dumb active skipping --- ...ly.patch => 0302-Fix-item-EAR-ticks.patch} | 42 +++++++++---------- .../0305-Alternative-item-despawn-rate.patch | 2 +- ...n-to-fix-items-merging-through-walls.patch | 2 +- ...-level-random-in-entity-constructors.patch | 2 +- patches/server/0763-Friction-API.patch | 2 +- .../0978-Entity-Activation-Range-2.0.patch | 27 +++++------- patches/server/0979-Anti-Xray.patch | 2 +- ...ion-for-horizontal-only-item-merging.patch | 2 +- ...all-time-unused-skip-tick-protection.patch | 2 +- .../1038-Moonrise-optimisation-patches.patch | 2 +- ...l-more-information-in-watchdog-dumps.patch | 2 +- ...-Incremental-chunk-and-player-saving.patch | 2 +- .../server/1051-Lag-compensation-ticks.patch | 2 +- 13 files changed, 42 insertions(+), 49 deletions(-) rename patches/server/{0302-Fix-items-not-falling-correctly.patch => 0302-Fix-item-EAR-ticks.patch} (51%) diff --git a/patches/server/0302-Fix-items-not-falling-correctly.patch b/patches/server/0302-Fix-item-EAR-ticks.patch similarity index 51% rename from patches/server/0302-Fix-items-not-falling-correctly.patch rename to patches/server/0302-Fix-item-EAR-ticks.patch index bc379f9af2a7..8fd577191b39 100644 --- a/patches/server/0302-Fix-items-not-falling-correctly.patch +++ b/patches/server/0302-Fix-item-EAR-ticks.patch @@ -1,21 +1,14 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AJMFactsheets -Date: Fri, 17 Jan 2020 17:17:54 -0600 -Subject: [PATCH] Fix items not falling correctly +From: Nassim Jahnke +Date: Wed, 30 Oct 2024 13:51:54 +0100 +Subject: [PATCH] Fix item EAR ticks -Since 1.14, Mojang has added an optimization which skips checking if -an item should fall every fourth tick. - -However, Spigot's entity activation range class also has an -optimization which skips ticking active entities every fourth tick. -This can result in a state where an item will never properly fall -due to its move method never being called. - -This patch resolves the conflict by offsetting checking Spigot's entity -activation range check from an item's move method. +Item entities only have their gravity ticked every 4 ticks when on ground. +Fix that and also remove Spigot's arbitrary tick skipping. It's a terribly +cheap way of getting extra performance that doesn't really work at all. diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index 75ebf09777e19645eee296a9edabac39c858ffb9..c390d8b3a706d0177b9f3105a7b9a84265688ece 100644 +index 75ebf09777e19645eee296a9edabac39c858ffb9..c21fa55c62d97d9511e41a1e313e904330a6eee6 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -175,7 +175,7 @@ public class ItemEntity extends Entity implements TraceableEntity { @@ -23,20 +16,27 @@ index 75ebf09777e19645eee296a9edabac39c858ffb9..c390d8b3a706d0177b9f3105a7b9a842 } - if (!this.onGround() || this.getDeltaMovement().horizontalDistanceSqr() > 9.999999747378752E-6D || (this.tickCount + this.getId()) % 4 == 0) { -+ if (!this.onGround() || this.getDeltaMovement().horizontalDistanceSqr() > 9.999999747378752E-6D || (this.tickCount + this.getId()) % 4 == 0) { // Paper - Diff on change ++ if (!this.onGround() || this.getDeltaMovement().horizontalDistanceSqr() > 9.999999747378752E-6D || (this.tickCount + this.getId()) % 4 == 0) { // Paper - Diff on change; ActivationRange immunity this.move(MoverType.SELF, this.getDeltaMovement()); this.applyEffectsFromBlocks(); float f = 0.98F; diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index dd1c5bc7522a4710cbfdd4764f6431e1e28d63cc..f8387277d915460d755bdd35198d2547d1a49bde 100644 +index dd1c5bc7522a4710cbfdd4764f6431e1e28d63cc..05ad15fc40ccb7feed5c51ad0ad0a98bd0d02af6 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java -@@ -253,7 +253,7 @@ public class ActivationRange +@@ -251,12 +251,11 @@ public class ActivationRange + entity.activatedTick = MinecraftServer.currentTick + 20; + } isActive = true; ++ } else if (entity instanceof net.minecraft.world.entity.item.ItemEntity && (entity.tickCount + entity.getId()) % 4 == 0) { // Paper - Needed for item gravity, see ItemEntity tick ++ isActive = true; } - // Add a little performance juice to active entities. Skip 1/4 if not immune. +- // Add a little performance juice to active entities. Skip 1/4 if not immune. - } else if ( !entity.defaultActivationState && entity.tickCount % 4 == 0 && !ActivationRange.checkEntityImmunities( entity ) ) -+ } else if ( !entity.defaultActivationState && (entity.tickCount + entity.getId()) % 4 == 0 && !ActivationRange.checkEntityImmunities( entity ) ) // Paper - Ensure checking item movement is offset from Spigot's entity activation range check - { - isActive = false; +- { +- isActive = false; } ++ // Paper - remove dumb tick skipping for active entities + return isActive; + } + } diff --git a/patches/server/0305-Alternative-item-despawn-rate.patch b/patches/server/0305-Alternative-item-despawn-rate.patch index d9614e183d55..ba7e9db85de8 100644 --- a/patches/server/0305-Alternative-item-despawn-rate.patch +++ b/patches/server/0305-Alternative-item-despawn-rate.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Alternative item-despawn-rate Co-authored-by: Noah van der Aa diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index c390d8b3a706d0177b9f3105a7b9a84265688ece..65deb4568a80577f67f39de3af9fb568975a649d 100644 +index c21fa55c62d97d9511e41a1e313e904330a6eee6..9974aec00935a1c3068eceee6d7042f14f15ac56 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -62,6 +62,7 @@ public class ItemEntity extends Entity implements TraceableEntity { diff --git a/patches/server/0543-Add-option-to-fix-items-merging-through-walls.patch b/patches/server/0543-Add-option-to-fix-items-merging-through-walls.patch index e0dd59d329b7..b4e4e39ae1d7 100644 --- a/patches/server/0543-Add-option-to-fix-items-merging-through-walls.patch +++ b/patches/server/0543-Add-option-to-fix-items-merging-through-walls.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add option to fix items merging through walls diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index 65deb4568a80577f67f39de3af9fb568975a649d..6b19689a19465554b943470fc6f959e48169ac5b 100644 +index 9974aec00935a1c3068eceee6d7042f14f15ac56..586257fe5c9f5cddd0ed164254f46777c6e71d66 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -285,6 +285,14 @@ public class ItemEntity extends Entity implements TraceableEntity { diff --git a/patches/server/0717-Don-t-use-level-random-in-entity-constructors.patch b/patches/server/0717-Don-t-use-level-random-in-entity-constructors.patch index 9ec489bd3e8d..83efb1446fbc 100644 --- a/patches/server/0717-Don-t-use-level-random-in-entity-constructors.patch +++ b/patches/server/0717-Don-t-use-level-random-in-entity-constructors.patch @@ -9,7 +9,7 @@ should be supported. Some entities (for whatever reason) use the level's random in some places. diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index 6b19689a19465554b943470fc6f959e48169ac5b..aa41c4cf8d3ae291c4147118c96190ff0bb807b2 100644 +index 586257fe5c9f5cddd0ed164254f46777c6e71d66..d555fd0b200c012f30ed0c0ec09a37b25a737b76 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -72,7 +72,12 @@ public class ItemEntity extends Entity implements TraceableEntity { diff --git a/patches/server/0763-Friction-API.patch b/patches/server/0763-Friction-API.patch index 25f88d845f80..8d3dd8593522 100644 --- a/patches/server/0763-Friction-API.patch +++ b/patches/server/0763-Friction-API.patch @@ -55,7 +55,7 @@ index 5330f6315cecfa6afd04b711a5b8656717cb5ede..8b0a764984f886b711cb337a7f706081 this.getAttributes().load(nbt.getList("attributes", 10)); } diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index aa41c4cf8d3ae291c4147118c96190ff0bb807b2..e83a705f54063a17fc69a22683333aacad5a43ce 100644 +index d555fd0b200c012f30ed0c0ec09a37b25a737b76..7a6d51020d9c6be33b4c34c0d608559589d5b390 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -63,6 +63,7 @@ public class ItemEntity extends Entity implements TraceableEntity { diff --git a/patches/server/0978-Entity-Activation-Range-2.0.patch b/patches/server/0978-Entity-Activation-Range-2.0.patch index e2e0609b445e..b1255a6dd54b 100644 --- a/patches/server/0978-Entity-Activation-Range-2.0.patch +++ b/patches/server/0978-Entity-Activation-Range-2.0.patch @@ -17,10 +17,10 @@ Adds villagers as separate config public net.minecraft.world.entity.Entity isInsidePortal diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index ce148cf5930cdcf0163c7f6416cbbd89e4d22720..75c388a5c9de26f0053015619e6c19bcff219478 100644 +index ce148cf5930cdcf0163c7f6416cbbd89e4d22720..cd00b534e4c527e0b4a5ad78cde87c22c49b4c33 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -962,12 +962,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -962,11 +962,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public void tickNonPassenger(Entity entity) { // Spigot start @@ -32,14 +32,13 @@ index ce148cf5930cdcf0163c7f6416cbbd89e4d22720..75c388a5c9de26f0053015619e6c19bc - } + }*/ // Paper - comment out EAR 2 // Spigot end -+ final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); // Paper - EAR 2 entity.setOldPosAndRot(); ProfilerFiller gameprofilerfiller = Profiler.get(); - -@@ -976,20 +977,22 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -976,20 +976,23 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString(); }); gameprofilerfiller.incrementCounter("tickNonPassenger"); ++ final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); // Paper - EAR 2 + if (isActive) { // Paper - EAR 2 entity.tick(); entity.postTick(); // CraftBukkit @@ -350,7 +349,7 @@ index 46afba838cf12eeb1bbccaa260131a76f090364b..e1c9a961064887070b29207efd7af478 } } diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index f8387277d915460d755bdd35198d2547d1a49bde..6ffe86aa887ebf96f21114a468e16376c2449911 100644 +index 05ad15fc40ccb7feed5c51ad0ad0a98bd0d02af6..133bcf639a45bd7fa1a2d02410ea3e8568265007 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -1,26 +1,35 @@ @@ -651,11 +650,11 @@ index f8387277d915460d755bdd35198d2547d1a49bde..6ffe86aa887ebf96f21114a468e16376 + // Paper start + if (entity instanceof Mob && ((Mob) entity).targetSelector.hasTasks() ) { + return 0; -+ } + } + if (entity instanceof Pillager) { + Pillager pillager = (Pillager) entity; + // TODO:? - } ++ } + // Paper end } // SPIGOT-6644: Otherwise the target refresh tick will be missed @@ -689,7 +688,7 @@ index f8387277d915460d755bdd35198d2547d1a49bde..6ffe86aa887ebf96f21114a468e16376 // Should this entity tick? if ( !isActive ) -@@ -245,15 +399,19 @@ public class ActivationRange +@@ -245,11 +399,14 @@ public class ActivationRange if ( ( MinecraftServer.currentTick - entity.activatedTick - 1 ) % 20 == 0 ) { // Check immunities every 20 ticks. @@ -706,14 +705,8 @@ index f8387277d915460d755bdd35198d2547d1a49bde..6ffe86aa887ebf96f21114a468e16376 } + // Paper end isActive = true; -+ - } - // Add a little performance juice to active entities. Skip 1/4 if not immune. -- } else if ( !entity.defaultActivationState && (entity.tickCount + entity.getId()) % 4 == 0 && !ActivationRange.checkEntityImmunities( entity ) ) // Paper - Ensure checking item movement is offset from Spigot's entity activation range check -+ } else if ( (entity.tickCount + entity.getId()) % 4 == 0 && ActivationRange.checkEntityImmunities( entity ) < 0 ) // Paper - { - isActive = false; - } + } else if (entity instanceof net.minecraft.world.entity.item.ItemEntity && (entity.tickCount + entity.getId()) % 4 == 0) { // Paper - Needed for item gravity, see ItemEntity tick + isActive = true; diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java index 2b263246135c85aa225120519e9702a628773935..2c408fa4abcbe1171c58aee8799c8cf7867d0f0a 100644 --- a/src/main/java/org/spigotmc/SpigotWorldConfig.java diff --git a/patches/server/0979-Anti-Xray.patch b/patches/server/0979-Anti-Xray.patch index 45f4e9200984..cae330b5648b 100644 --- a/patches/server/0979-Anti-Xray.patch +++ b/patches/server/0979-Anti-Xray.patch @@ -1104,7 +1104,7 @@ index 183b2191fa1c1b27adedf39593e1b5a223fb1279..8ead66c134688b11dca15f6509147e72 private ClientboundLevelChunkWithLightPacket(RegistryFriendlyByteBuf buf) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 75c388a5c9de26f0053015619e6c19bcff219478..c0de354ac03a62f159540f25940dc3700cc0c575 100644 +index cd00b534e4c527e0b4a5ad78cde87c22c49b4c33..32f8186b1502b481c1100f7fdba0339ae3dd34fa 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -343,7 +343,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/1008-Configuration-for-horizontal-only-item-merging.patch b/patches/server/1008-Configuration-for-horizontal-only-item-merging.patch index 4b16b244dd13..4b1c29914b08 100644 --- a/patches/server/1008-Configuration-for-horizontal-only-item-merging.patch +++ b/patches/server/1008-Configuration-for-horizontal-only-item-merging.patch @@ -14,7 +14,7 @@ This allows us to have both the reduced number of item entities a high item-merg without most of the visual artifacts caused by items merging vertically. diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index e83a705f54063a17fc69a22683333aacad5a43ce..246b5649883e4f305afa5a887b9df0f3735f7593 100644 +index 7a6d51020d9c6be33b4c34c0d608559589d5b390..4ce041726661dbbd19f36a516f2fd7f5e3307ef0 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -285,7 +285,7 @@ public class ItemEntity extends Entity implements TraceableEntity { diff --git a/patches/server/1024-Remove-wall-time-unused-skip-tick-protection.patch b/patches/server/1024-Remove-wall-time-unused-skip-tick-protection.patch index da0d05dd0d5d..deaf422ec720 100644 --- a/patches/server/1024-Remove-wall-time-unused-skip-tick-protection.patch +++ b/patches/server/1024-Remove-wall-time-unused-skip-tick-protection.patch @@ -30,7 +30,7 @@ completely unnecessary, which also rids paper of the previous described incompatibility with non-ticking chunks. diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index 246b5649883e4f305afa5a887b9df0f3735f7593..5d8885bca55503bf7e1a2a4e1bb9b3bd86d55391 100644 +index 4ce041726661dbbd19f36a516f2fd7f5e3307ef0..0f086af57a5ff08c264dcbf89a8c3931ec73a609 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -60,7 +60,7 @@ public class ItemEntity extends Entity implements TraceableEntity { diff --git a/patches/server/1038-Moonrise-optimisation-patches.patch b/patches/server/1038-Moonrise-optimisation-patches.patch index 529aeae1685b..a1ca50384067 100644 --- a/patches/server/1038-Moonrise-optimisation-patches.patch +++ b/patches/server/1038-Moonrise-optimisation-patches.patch @@ -26779,7 +26779,7 @@ index b2fd3e936559c8fcb8b02ae3ef63c4f3bd0edb08..5bbc7ceaafc163f12344e5d5d355ad2f if (!list.equals(this.lastPassengers)) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index c0de354ac03a62f159540f25940dc3700cc0c575..9af879115a24145ec290ac200565004e49ee7b0b 100644 +index 32f8186b1502b481c1100f7fdba0339ae3dd34fa..70efc63102b3d3727be376d42f1bef70174468a3 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -185,7 +185,7 @@ import org.bukkit.event.weather.LightningStrikeEvent; diff --git a/patches/server/1043-Detail-more-information-in-watchdog-dumps.patch b/patches/server/1043-Detail-more-information-in-watchdog-dumps.patch index e23f02def30f..472a49bc31ce 100644 --- a/patches/server/1043-Detail-more-information-in-watchdog-dumps.patch +++ b/patches/server/1043-Detail-more-information-in-watchdog-dumps.patch @@ -76,7 +76,7 @@ index f7197f1347251a37dd0f6d9ffa2f09bc3a4e1233..1f7f68aad97ee73763c042837f239bdc }); 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 9af879115a24145ec290ac200565004e49ee7b0b..c9d7ea8fbaf8858564282b42f6f6dda3d6927f8e 100644 +index 70efc63102b3d3727be376d42f1bef70174468a3..7b936a01888d71fe305863054471b6b4a3aa95b8 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1247,7 +1247,26 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/1048-Incremental-chunk-and-player-saving.patch b/patches/server/1048-Incremental-chunk-and-player-saving.patch index 180dd1300421..9494da1fd094 100644 --- a/patches/server/1048-Incremental-chunk-and-player-saving.patch +++ b/patches/server/1048-Incremental-chunk-and-player-saving.patch @@ -50,7 +50,7 @@ index 8a45960de3fd890991a1c75a103fec1adb03c0cb..c1e8d2679083516040e9d1768d79f5e4 ProfilerFiller gameprofilerfiller = Profiler.get(); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index c9d7ea8fbaf8858564282b42f6f6dda3d6927f8e..2519a886317362db4ac0aeadb3655624f175cd99 100644 +index 7b936a01888d71fe305863054471b6b4a3aa95b8..c09c718c1b1c9f27fdf1e4160b2df6887cf1d1a2 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1347,6 +1347,30 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe diff --git a/patches/server/1051-Lag-compensation-ticks.patch b/patches/server/1051-Lag-compensation-ticks.patch index e00741dadd11..a919d8ba478f 100644 --- a/patches/server/1051-Lag-compensation-ticks.patch +++ b/patches/server/1051-Lag-compensation-ticks.patch @@ -28,7 +28,7 @@ index c1e8d2679083516040e9d1768d79f5e4d71bf0a6..af7c6f56444c0e495fd39da872f80301 gameprofilerfiller.push(() -> { String s = String.valueOf(worldserver); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 2519a886317362db4ac0aeadb3655624f175cd99..e65cfb1132f5f0c9e1fa5ae4a46a8abed0c56be1 100644 +index c09c718c1b1c9f27fdf1e4160b2df6887cf1d1a2..21c78bc96c39f6261adaad2e7c225948b6f1606f 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -576,6 +576,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe From 1a1d0cf01ad0a245e8e80e6085075ce5e89181fe Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Wed, 30 Oct 2024 14:31:03 +0100 Subject: [PATCH 113/119] Use target pitch in teleport (generally the same thing) --- patches/server/0578-Add-back-EntityPortalExitEvent.patch | 8 +++----- .../server/0589-Add-Raw-Byte-Entity-Serialization.patch | 2 +- .../0615-Update-head-rotation-in-missing-places.patch | 2 +- .../0621-don-t-attempt-to-teleport-dead-entities.patch | 2 +- .../0631-Forward-CraftEntity-in-teleport-command.patch | 2 +- patches/server/0650-Freeze-Tick-Lock-API.patch | 2 +- ...ure-entity-passenger-world-matches-ridden-entity.patch | 2 +- ...701-Prevent-entity-loading-causing-async-lookups.patch | 2 +- ...13-Add-various-missing-EntityDropItemEvent-calls.patch | 2 +- ...EntityCombustEvent-cancellation-cant-fully-preve.patch | 2 +- patches/server/0767-Player-Entity-Tracking-Events.patch | 2 +- patches/server/0774-Improve-PortalEvents.patch | 2 +- ...se-pre-collision-moving-velocity-to-VehicleBlock.patch | 2 +- .../0809-Refresh-ProjectileSource-for-projectiles.patch | 2 +- ...23-Don-t-load-chunks-for-supporting-block-checks.patch | 2 +- .../0835-Folia-scheduler-and-owned-region-API.patch | 2 +- patches/server/0858-Expand-Pose-API.patch | 2 +- patches/server/0865-Fix-slot-desync.patch | 2 +- .../0899-Don-t-fire-sync-events-during-worldgen.patch | 2 +- .../0902-Restore-vanilla-entity-drops-behavior.patch | 2 +- patches/server/0934-Fix-DamageSource-API.patch | 2 +- patches/server/0978-Entity-Activation-Range-2.0.patch | 2 +- .../0981-Optimize-Collision-to-not-load-chunks.patch | 2 +- patches/server/0992-Properly-resend-entities.patch | 2 +- patches/server/1032-Void-damage-configuration-API.patch | 2 +- patches/server/1038-Moonrise-optimisation-patches.patch | 2 +- .../1043-Detail-more-information-in-watchdog-dumps.patch | 2 +- 27 files changed, 29 insertions(+), 31 deletions(-) diff --git a/patches/server/0578-Add-back-EntityPortalExitEvent.patch b/patches/server/0578-Add-back-EntityPortalExitEvent.patch index a0823113061c..5e3f9b5ffdcf 100644 --- a/patches/server/0578-Add-back-EntityPortalExitEvent.patch +++ b/patches/server/0578-Add-back-EntityPortalExitEvent.patch @@ -5,19 +5,17 @@ Subject: [PATCH] Add back EntityPortalExitEvent diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index fe9cdd104d6203233a90068b55e0876be4964afe..96d73407edd440c16d41c8a586797ade30792f46 100644 +index fe9cdd104d6203233a90068b55e0876be4964afe..88d3b1997bba632c5746d295bb39095f5d328369 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -3491,7 +3491,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3491,6 +3491,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess if (!this.isRemoved()) { // CraftBukkit start PositionMoveRotation absolutePosition = PositionMoveRotation.calculateAbsolute(PositionMoveRotation.of(this), PositionMoveRotation.of(teleportTarget), teleportTarget.relatives()); -- Location to = CraftLocation.toBukkit(absolutePosition.position(), teleportTarget.newLevel().getWorld(), absolutePosition.yRot(), absolutePosition.xRot()); + Vec3 velocity = absolutePosition.deltaMovement(); // Paper -+ Location to = CraftLocation.toBukkit(absolutePosition.position(), teleportTarget.newLevel().getWorld(), absolutePosition.yRot(), this.getXRot()); // Paper - use getXRot (doesn't respect DimensionTransition pitch) // Why? + Location to = CraftLocation.toBukkit(absolutePosition.position(), teleportTarget.newLevel().getWorld(), absolutePosition.yRot(), absolutePosition.xRot()); // Paper start - gateway-specific teleport event final EntityTeleportEvent teleEvent; - if (this.portalProcess != null && this.portalProcess.isSamePortal(((net.minecraft.world.level.block.EndGatewayBlock) net.minecraft.world.level.block.Blocks.END_GATEWAY)) && this.level.getBlockEntity(this.portalProcess.getEntryPosition()) instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity theEndGatewayBlockEntity) { @@ -3507,7 +3508,29 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess if (!to.equals(teleEvent.getTo())) { to = teleEvent.getTo(); diff --git a/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch b/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch index 24a102b9d622..660fb63c77aa 100644 --- a/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch +++ b/patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Add Raw Byte Entity Serialization public net.minecraft.world.entity.Entity setLevel(Lnet/minecraft/world/level/Level;)V diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 96d73407edd440c16d41c8a586797ade30792f46..66b1711a4e05270f15703229459f4bebb2fb19b7 100644 +index 88d3b1997bba632c5746d295bb39095f5d328369..900765b0129e8bf485aca93af6f523c9948e288b 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2260,6 +2260,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0615-Update-head-rotation-in-missing-places.patch b/patches/server/0615-Update-head-rotation-in-missing-places.patch index d24623bdc1b2..51b3e36d06e0 100644 --- a/patches/server/0615-Update-head-rotation-in-missing-places.patch +++ b/patches/server/0615-Update-head-rotation-in-missing-places.patch @@ -8,7 +8,7 @@ This is because bukkit uses a separate head rotation field for yaw. This issue only applies to players. diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 66b1711a4e05270f15703229459f4bebb2fb19b7..58949beb5fcdc1618674f206feb90d0f5335c67f 100644 +index 900765b0129e8bf485aca93af6f523c9948e288b..3903bbc53d541e66d9362eea27029ed320a74772 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -1914,6 +1914,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0621-don-t-attempt-to-teleport-dead-entities.patch b/patches/server/0621-don-t-attempt-to-teleport-dead-entities.patch index 7963ba88c516..92fa7ea8540a 100644 --- a/patches/server/0621-don-t-attempt-to-teleport-dead-entities.patch +++ b/patches/server/0621-don-t-attempt-to-teleport-dead-entities.patch @@ -5,7 +5,7 @@ Subject: [PATCH] don't attempt to teleport dead entities diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 58949beb5fcdc1618674f206feb90d0f5335c67f..1cb02ee453133f6f019887ec02d2d2aca958a959 100644 +index 3903bbc53d541e66d9362eea27029ed320a74772..d6bbefe3d3b21c6fc9be3cfe3ba304226bab6883 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -713,7 +713,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0631-Forward-CraftEntity-in-teleport-command.patch b/patches/server/0631-Forward-CraftEntity-in-teleport-command.patch index 257107983669..9d0cbe05951d 100644 --- a/patches/server/0631-Forward-CraftEntity-in-teleport-command.patch +++ b/patches/server/0631-Forward-CraftEntity-in-teleport-command.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Forward CraftEntity in teleport command diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 1cb02ee453133f6f019887ec02d2d2aca958a959..f2dbeb6b1bdcd447b24fb06279301bcbca489511 100644 +index d6bbefe3d3b21c6fc9be3cfe3ba304226bab6883..06d7aed2539a0f38fabe5b10c91d8da10c43605f 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -3480,6 +3480,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0650-Freeze-Tick-Lock-API.patch b/patches/server/0650-Freeze-Tick-Lock-API.patch index c882f88035f3..98811e564539 100644 --- a/patches/server/0650-Freeze-Tick-Lock-API.patch +++ b/patches/server/0650-Freeze-Tick-Lock-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Freeze Tick Lock API diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index f2dbeb6b1bdcd447b24fb06279301bcbca489511..954c70b45a0d96d16332424a7d31e4241088601f 100644 +index 06d7aed2539a0f38fabe5b10c91d8da10c43605f..4b0b768a4563281ec4ef1a16a3a21c24a1272849 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -414,6 +414,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0680-Ensure-entity-passenger-world-matches-ridden-entity.patch b/patches/server/0680-Ensure-entity-passenger-world-matches-ridden-entity.patch index 184e75059ae2..e85a7e401966 100644 --- a/patches/server/0680-Ensure-entity-passenger-world-matches-ridden-entity.patch +++ b/patches/server/0680-Ensure-entity-passenger-world-matches-ridden-entity.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Ensure entity passenger world matches ridden entity Bad plugins doing this would cause some obvious problems... diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 954c70b45a0d96d16332424a7d31e4241088601f..47e7405db3f8cfd674ec7704e8d40b628e94678b 100644 +index 4b0b768a4563281ec4ef1a16a3a21c24a1272849..dcd6cb204d5d19da17664e446da7f3edef104b80 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2802,7 +2802,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0701-Prevent-entity-loading-causing-async-lookups.patch b/patches/server/0701-Prevent-entity-loading-causing-async-lookups.patch index 3d298a96af7c..93303844469a 100644 --- a/patches/server/0701-Prevent-entity-loading-causing-async-lookups.patch +++ b/patches/server/0701-Prevent-entity-loading-causing-async-lookups.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Prevent entity loading causing async lookups diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 47e7405db3f8cfd674ec7704e8d40b628e94678b..f13b9050c4de9ddc7a8620b89478df20bccafe06 100644 +index dcd6cb204d5d19da17664e446da7f3edef104b80..736b8bb59631a4e6f8639d84715a7d8cf9dbb775 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -724,6 +724,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0713-Add-various-missing-EntityDropItemEvent-calls.patch b/patches/server/0713-Add-various-missing-EntityDropItemEvent-calls.patch index 758e8905c21d..9b07c23cf818 100644 --- a/patches/server/0713-Add-various-missing-EntityDropItemEvent-calls.patch +++ b/patches/server/0713-Add-various-missing-EntityDropItemEvent-calls.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add various missing EntityDropItemEvent calls diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index f13b9050c4de9ddc7a8620b89478df20bccafe06..73882f5b5a25779841b3a8fe507bbb92cf113691 100644 +index 736b8bb59631a4e6f8639d84715a7d8cf9dbb775..0de6c90c195439564810036c90f31e8296538666 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2672,6 +2672,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0754-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch b/patches/server/0754-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch index 231d47c34bb1..1c5db8b76dc5 100644 --- a/patches/server/0754-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch +++ b/patches/server/0754-Fix-EntityCombustEvent-cancellation-cant-fully-preve.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Fix EntityCombustEvent cancellation cant fully prevent diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 73882f5b5a25779841b3a8fe507bbb92cf113691..eeefe0a8f36618d6df513d9ea5443e222ae8826e 100644 +index 0de6c90c195439564810036c90f31e8296538666..8b2b0cf8318f06f0fef59908ece650fb54b6a6b3 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -3320,6 +3320,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0767-Player-Entity-Tracking-Events.patch b/patches/server/0767-Player-Entity-Tracking-Events.patch index fd7aeb4e069c..fc9f07d3da2f 100644 --- a/patches/server/0767-Player-Entity-Tracking-Events.patch +++ b/patches/server/0767-Player-Entity-Tracking-Events.patch @@ -21,7 +21,7 @@ index 51a6735b35e73175680e61c2d67d4adbedf305c9..8b5d11aceb77135c917c3581f4db792e } else if (this.seenBy.remove(player.connection)) { this.serverEntity.removePairing(player); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index eeefe0a8f36618d6df513d9ea5443e222ae8826e..149852c5ed532c1bbb4f647c0988d282915fa43d 100644 +index 8b2b0cf8318f06f0fef59908ece650fb54b6a6b3..429cdb83252b417c810d529125fc7343dca7990d 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -4071,7 +4071,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0774-Improve-PortalEvents.patch b/patches/server/0774-Improve-PortalEvents.patch index dc475e1825f2..af78ad7bc060 100644 --- a/patches/server/0774-Improve-PortalEvents.patch +++ b/patches/server/0774-Improve-PortalEvents.patch @@ -18,7 +18,7 @@ index 25b1e8bec23465f0e9a17f156bdff7fe716db84c..f05a9fd321a4af28e9771bbf39d73f80 // Paper start - gateway-specific teleport event if (this.portalProcess != null && this.portalProcess.isSamePortal(((net.minecraft.world.level.block.EndGatewayBlock) net.minecraft.world.level.block.Blocks.END_GATEWAY)) && this.serverLevel().getBlockEntity(this.portalProcess.getEntryPosition()) instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity theEndGatewayBlockEntity) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 149852c5ed532c1bbb4f647c0988d282915fa43d..4ad6ba0b5f7b53943643be2abb0590748222e984 100644 +index 429cdb83252b417c810d529125fc7343dca7990d..411ffaf842841709eaef48776e2c6ce4f524af05 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -3742,7 +3742,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0779-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch b/patches/server/0779-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch index 8b27b7a489cd..3af6c787dbfa 100644 --- a/patches/server/0779-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch +++ b/patches/server/0779-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Expose pre-collision moving velocity to diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 4ad6ba0b5f7b53943643be2abb0590748222e984..19c200743c4b5384f2b43554cfe29eafcea9b227 100644 +index 411ffaf842841709eaef48776e2c6ce4f524af05..5340d6d911a7e586468f2b7e2e74b3386d1dc72d 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -968,6 +968,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0809-Refresh-ProjectileSource-for-projectiles.patch b/patches/server/0809-Refresh-ProjectileSource-for-projectiles.patch index dcbbac97e127..ccbd8c45c027 100644 --- a/patches/server/0809-Refresh-ProjectileSource-for-projectiles.patch +++ b/patches/server/0809-Refresh-ProjectileSource-for-projectiles.patch @@ -14,7 +14,7 @@ clearing the owner. Co-authored-by: Warrior <50800980+Warriorrrr@users.noreply.github.com> diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 19c200743c4b5384f2b43554cfe29eafcea9b227..2397f88634aef5abce427c0cd751bdbfc6455b38 100644 +index 5340d6d911a7e586468f2b7e2e74b3386d1dc72d..90b47da5c6df05565b522636e08c4ebb7165c351 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -393,6 +393,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0823-Don-t-load-chunks-for-supporting-block-checks.patch b/patches/server/0823-Don-t-load-chunks-for-supporting-block-checks.patch index d55a98cf81c0..4984d9ef4c64 100644 --- a/patches/server/0823-Don-t-load-chunks-for-supporting-block-checks.patch +++ b/patches/server/0823-Don-t-load-chunks-for-supporting-block-checks.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Don't load chunks for supporting block checks diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 2397f88634aef5abce427c0cd751bdbfc6455b38..72cb4a97188596db49e69fd2a332fea907d10456 100644 +index 90b47da5c6df05565b522636e08c4ebb7165c351..a8bb9caaf0db01d8b7cfb18e5f162c6eeada5d6a 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -1228,7 +1228,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0835-Folia-scheduler-and-owned-region-API.patch b/patches/server/0835-Folia-scheduler-and-owned-region-API.patch index ae8d94eb4791..2ee4d8a5b522 100644 --- a/patches/server/0835-Folia-scheduler-and-owned-region-API.patch +++ b/patches/server/0835-Folia-scheduler-and-owned-region-API.patch @@ -1185,7 +1185,7 @@ index cbba549176b3acfc25ec42c2935b31ab2176e0fa..4ac0bb0ec3222ebdd3fa386696dcb072 this.players.remove(entityplayer); this.playersByName.remove(entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 72cb4a97188596db49e69fd2a332fea907d10456..8695e003e20912840d4968adf81c17cb8b545096 100644 +index a8bb9caaf0db01d8b7cfb18e5f162c6eeada5d6a..cc4906ed08e84beaca0ba93200693a0a3730fb4c 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -262,10 +262,21 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0858-Expand-Pose-API.patch b/patches/server/0858-Expand-Pose-API.patch index 836f4405e5d8..118d44664465 100644 --- a/patches/server/0858-Expand-Pose-API.patch +++ b/patches/server/0858-Expand-Pose-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Expand Pose API diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 8695e003e20912840d4968adf81c17cb8b545096..5c1ee438e85167ab6382f18421f14e2a1ea0acf1 100644 +index cc4906ed08e84beaca0ba93200693a0a3730fb4c..67dda7d37cc4af2f09734da5653e8fa33098c7db 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -427,6 +427,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0865-Fix-slot-desync.patch b/patches/server/0865-Fix-slot-desync.patch index 089eb53892f3..eb0e27694525 100644 --- a/patches/server/0865-Fix-slot-desync.patch +++ b/patches/server/0865-Fix-slot-desync.patch @@ -40,7 +40,7 @@ index b840f7aac9c830b8aa0aa133bf43f87dfc598b2c..0cb0d2f863efb86bb589b30bae61ac57 if (event.isCancelled()) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 5c1ee438e85167ab6382f18421f14e2a1ea0acf1..18147e93d99417e696cbb24603fec2aa0a1057e3 100644 +index 67dda7d37cc4af2f09734da5653e8fa33098c7db..56f2ac87f42572556646eb62f16274726e7ae455 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2752,8 +2752,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch b/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch index a45762da8fb6..24339297b71a 100644 --- a/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch +++ b/patches/server/0899-Don-t-fire-sync-events-during-worldgen.patch @@ -31,7 +31,7 @@ index 7cecbac43f1cd2d9516034ea9d2633c0c76e61f4..7a985c30a973efacf3e8b70e7163c550 if (entity.valid) { MinecraftServer.LOGGER.error("Attempted Double World add on {}", entity, new Throwable()); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 18147e93d99417e696cbb24603fec2aa0a1057e3..d495c20f337594507114cde436d759c9a81451b4 100644 +index 56f2ac87f42572556646eb62f16274726e7ae455..5c7df0efee4a0aa078e36d3e262cd0b48a27cf47 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -631,7 +631,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch b/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch index 489f9a4c1a5d..d6f9795558e7 100644 --- a/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch +++ b/patches/server/0902-Restore-vanilla-entity-drops-behavior.patch @@ -37,7 +37,7 @@ index 419fcb4cd97cf10a2601e02024b999a51a0ff952..df21cd1bd2a3dda7169edbea18bbfdf0 loot.addAll(this.drops); this.drops.clear(); // SPIGOT-5188: make sure to clear diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index d495c20f337594507114cde436d759c9a81451b4..189bc1bcd902a37f684a980088578c19ba66ceb5 100644 +index 5c7df0efee4a0aa078e36d3e262cd0b48a27cf47..b78395ab8f393a0f6551951731ddce7a5228b44c 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2678,19 +2678,45 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0934-Fix-DamageSource-API.patch b/patches/server/0934-Fix-DamageSource-API.patch index c8083b462480..bdeb62149f99 100644 --- a/patches/server/0934-Fix-DamageSource-API.patch +++ b/patches/server/0934-Fix-DamageSource-API.patch @@ -84,7 +84,7 @@ index fddbdb7322a2063996a28c5c3d93c265188b1256..be87cb3cfa15a7d889118cdc4b87232e public DamageSource sonicBoom(Entity attacker) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 189bc1bcd902a37f684a980088578c19ba66ceb5..51dc99e367e8b9d6b2373d1f8e01dfa3ed34a283 100644 +index b78395ab8f393a0f6551951731ddce7a5228b44c..e2322f361271712aca31c95b8b79cdf1c04945f2 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -3388,7 +3388,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0978-Entity-Activation-Range-2.0.patch b/patches/server/0978-Entity-Activation-Range-2.0.patch index b1255a6dd54b..13245e49f465 100644 --- a/patches/server/0978-Entity-Activation-Range-2.0.patch +++ b/patches/server/0978-Entity-Activation-Range-2.0.patch @@ -87,7 +87,7 @@ index ce148cf5930cdcf0163c7f6416cbbd89e4d22720..cd00b534e4c527e0b4a5ad78cde87c22 } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 51dc99e367e8b9d6b2373d1f8e01dfa3ed34a283..2cc92228d48b78e8318c106bfe49e06f56256927 100644 +index e2322f361271712aca31c95b8b79cdf1c04945f2..4c76002af5eee553b92a026688c83ab36429fe4f 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -420,6 +420,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch b/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch index 0a4446e68f71..1dc4b385f4e8 100644 --- a/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch +++ b/patches/server/0981-Optimize-Collision-to-not-load-chunks.patch @@ -26,7 +26,7 @@ index 7097d87dead028c8dd44cefc97694bada93f608b..751fc4b0fe60c6d26ea0f768f3d66031 if (teleporttransition.missingRespawnBlock()) { entityplayer1.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0F)); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 2cc92228d48b78e8318c106bfe49e06f56256927..0a26653eb6d72b646bedeba3839868241851c1c9 100644 +index 4c76002af5eee553b92a026688c83ab36429fe4f..7fbaaed892b39ca920b15e08d6c44943a69a35d7 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -258,6 +258,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/0992-Properly-resend-entities.patch b/patches/server/0992-Properly-resend-entities.patch index 5487d9a3b175..2b67ccc75f0d 100644 --- a/patches/server/0992-Properly-resend-entities.patch +++ b/patches/server/0992-Properly-resend-entities.patch @@ -134,7 +134,7 @@ index 751fc4b0fe60c6d26ea0f768f3d66031a4bad963..700ab5ef2f8ab1466c4f659cd34679dc } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 0a26653eb6d72b646bedeba3839868241851c1c9..28d4c6d308f2c69b22d21302e4fa505162a1d782 100644 +index 7fbaaed892b39ca920b15e08d6c44943a69a35d7..ddfc4818f091802e5999c6b99e5bc57c6f370648 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -598,13 +598,45 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/1032-Void-damage-configuration-API.patch b/patches/server/1032-Void-damage-configuration-API.patch index d14c24317793..dd9e6079b9e8 100644 --- a/patches/server/1032-Void-damage-configuration-API.patch +++ b/patches/server/1032-Void-damage-configuration-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Void damage configuration API diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 28d4c6d308f2c69b22d21302e4fa505162a1d782..fc958b43ce0972362eb3be76ec6b9f7388f45f22 100644 +index ddfc4818f091802e5999c6b99e5bc57c6f370648..e5466be840ef32e4fa17c0e9446c4d0b30a56e26 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -853,8 +853,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/patches/server/1038-Moonrise-optimisation-patches.patch b/patches/server/1038-Moonrise-optimisation-patches.patch index a1ca50384067..c40f78385521 100644 --- a/patches/server/1038-Moonrise-optimisation-patches.patch +++ b/patches/server/1038-Moonrise-optimisation-patches.patch @@ -28416,7 +28416,7 @@ index 50040c497a819cd1229042ab3cb057d34a32cacc..1f9c436a632e4f110be61cf76fcfc3b7 + // Paper end - block counting } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index fc958b43ce0972362eb3be76ec6b9f7388f45f22..288f9cdf57bb9356a048d8d3d795e9a7a1b3a216 100644 +index e5466be840ef32e4fa17c0e9446c4d0b30a56e26..88543de6e51acbe76b89aef4a84de20337d616e4 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -175,7 +175,7 @@ import org.bukkit.event.player.PlayerTeleportEvent; diff --git a/patches/server/1043-Detail-more-information-in-watchdog-dumps.patch b/patches/server/1043-Detail-more-information-in-watchdog-dumps.patch index 472a49bc31ce..c14568a5d7b0 100644 --- a/patches/server/1043-Detail-more-information-in-watchdog-dumps.patch +++ b/patches/server/1043-Detail-more-information-in-watchdog-dumps.patch @@ -121,7 +121,7 @@ index 70efc63102b3d3727be376d42f1bef70174468a3..7b936a01888d71fe305863054471b6b4 private void tickPassenger(Entity vehicle, Entity passenger, boolean isActive) { // Paper - EAR 2 diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 288f9cdf57bb9356a048d8d3d795e9a7a1b3a216..bc81faf083e2a5455a7da0ba7cc18eae5e014a7a 100644 +index 88543de6e51acbe76b89aef4a84de20337d616e4..6574219da33a7b9a4906883e65b78d7806f6e67b 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -1171,8 +1171,43 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess From 8ba30733439c3cce627b779d1a902f054927d25a Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Wed, 30 Oct 2024 14:55:46 +0100 Subject: [PATCH 114/119] fix "is_freezing" damage type tag --- ...0948-Fix-damage-modifier-inconsistencies.patch} | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) rename patches/server/{0948-Fix-helmet-damage-reduction-inconsistencies.patch => 0948-Fix-damage-modifier-inconsistencies.patch} (59%) diff --git a/patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch b/patches/server/0948-Fix-damage-modifier-inconsistencies.patch similarity index 59% rename from patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch rename to patches/server/0948-Fix-damage-modifier-inconsistencies.patch index 262b84900d43..1494c35c0642 100644 --- a/patches/server/0948-Fix-helmet-damage-reduction-inconsistencies.patch +++ b/patches/server/0948-Fix-damage-modifier-inconsistencies.patch @@ -1,16 +1,22 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Sat, 27 Apr 2024 21:51:58 +0200 -Subject: [PATCH] Fix helmet damage reduction inconsistencies +Subject: [PATCH] Fix damage modifier inconsistencies Affect the falling stalactite damage type where the -reduction is not applied like in Vanilla +reduction is not applied like in Vanilla. +Additionally fix the "is_freezing" damage type tag. diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 418e67ef5896325fe143501f5a4f1604b065ba0f..1e98f68e51618606f1178c12be77c1a945362630 100644 +index 418e67ef5896325fe143501f5a4f1604b065ba0f..864e4c660bf3d381880e5928b6945bea213ac57e 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1226,7 +1226,7 @@ public class CraftEventFactory { +@@ -1222,11 +1222,11 @@ public class CraftEventFactory { + Map> modifierFunctions = new EnumMap<>(DamageModifier.class); + modifiers.put(DamageModifier.BASE, rawDamage); + modifierFunctions.put(DamageModifier.BASE, CraftEventFactory.ZERO); +- if (source.is(DamageTypes.FREEZE)) { ++ if (source.is(DamageTypeTags.IS_FREEZING)) { // Paper modifiers.put(DamageModifier.FREEZING, freezingModifier); modifierFunctions.put(DamageModifier.FREEZING, freezing); } From 1523212d4eb850f0d7b1be46308ac53e2825f859 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Wed, 30 Oct 2024 17:07:49 +0100 Subject: [PATCH 115/119] don't resend effects when PlayerItemConsumeEvent is cancelled --- .../0992-Properly-resend-entities.patch | 52 ++++--------------- ...tityDamageEvents-before-actuallyHurt.patch | 2 +- .../1019-Check-dead-flag-in-isAlive.patch | 2 +- .../1032-Void-damage-configuration-API.patch | 2 +- .../1038-Moonrise-optimisation-patches.patch | 4 +- .../1042-Improved-Watchdog-Support.patch | 2 +- ...-Incremental-chunk-and-player-saving.patch | 4 +- .../server/1051-Lag-compensation-ticks.patch | 2 +- 8 files changed, 20 insertions(+), 50 deletions(-) diff --git a/patches/server/0992-Properly-resend-entities.patch b/patches/server/0992-Properly-resend-entities.patch index 2b67ccc75f0d..4fe85b019146 100644 --- a/patches/server/0992-Properly-resend-entities.patch +++ b/patches/server/0992-Properly-resend-entities.patch @@ -102,7 +102,7 @@ index 52eafd99ed63f5fc9596225cf45175b1287f20a1..e5db85f858ab376b225172e22b92b841 } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 751fc4b0fe60c6d26ea0f768f3d66031a4bad963..700ab5ef2f8ab1466c4f659cd34679dc809efbaf 100644 +index 751fc4b0fe60c6d26ea0f768f3d66031a4bad963..f6eed6cb2bd69c15aa36a8d8d9abdfda6d4a0622 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -396,7 +396,7 @@ public abstract class PlayerList { @@ -114,25 +114,6 @@ index 751fc4b0fe60c6d26ea0f768f3d66031a4bad963..700ab5ef2f8ab1466c4f659cd34679dc this.sendLevelInfo(player, worldserver1); -@@ -907,12 +907,17 @@ public abstract class PlayerList { - } - - public void sendActiveEffects(LivingEntity entity, ServerGamePacketListenerImpl networkHandler) { -+ // Paper start - collect packets -+ this.sendActiveEffects(entity, networkHandler::send); -+ } -+ public void sendActiveEffects(LivingEntity entity, java.util.function.Consumer> packetConsumer) { -+ // Paper end - collect packets - Iterator iterator = entity.getActiveEffects().iterator(); - - while (iterator.hasNext()) { - MobEffectInstance mobeffect = (MobEffectInstance) iterator.next(); - -- networkHandler.send(new ClientboundUpdateMobEffectPacket(entity.getId(), mobeffect, false)); -+ packetConsumer.accept(new ClientboundUpdateMobEffectPacket(entity.getId(), mobeffect, false)); // Paper - collect packets - } - - } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index 7fbaaed892b39ca920b15e08d6c44943a69a35d7..ddfc4818f091802e5999c6b99e5bc57c6f370648 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java @@ -186,7 +167,7 @@ index 7fbaaed892b39ca920b15e08d6c44943a69a35d7..ddfc4818f091802e5999c6b99e5bc57c public boolean equals(Object object) { return object instanceof Entity ? ((Entity) object).id == this.id : false; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 22f520414442c05986cc620208afaa895d8ee4fa..5e4716158da891216acc835f2560f980f527c66f 100644 +index 22f520414442c05986cc620208afaa895d8ee4fa..d19a9aa8f73b3a07e7d3d63efa5d411add163fa4 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -4029,6 +4029,11 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -201,6 +182,15 @@ index 22f520414442c05986cc620208afaa895d8ee4fa..5e4716158da891216acc835f2560f980 private void updatingUsingItem() { if (this.isUsingItem()) { if (ItemStack.isSameItem(this.getItemInHand(this.getUsedItemHand()), this.useItem)) { +@@ -4164,7 +4169,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + this.stopUsingItem(); // Paper - event is using an item, clear active item to reset its use + // Update client + Consumable consumable = this.useItem.get(DataComponents.CONSUMABLE); +- if (consumable != null) { ++ if (false && consumable != null) { // Paper + consumable.cancelUsingItem(entityPlayer, this.useItem); + } + entityPlayer.getBukkitEntity().updateInventory(); diff --git a/src/main/java/net/minecraft/world/entity/animal/Bucketable.java b/src/main/java/net/minecraft/world/entity/animal/Bucketable.java index 5a12f4c1de2d020e84af933d491397b38d227824..4eca5996a867086be22d22d99db81ab001467516 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Bucketable.java @@ -215,26 +205,6 @@ index 5a12f4c1de2d020e84af933d491397b38d227824..4eca5996a867086be22d22d99db81ab0 return Optional.of(InteractionResult.FAIL); } entity.playSound(((Bucketable) entity).getPickupSound(), 1.0F, 1.0F); -diff --git a/src/main/java/net/minecraft/world/item/component/SuspiciousStewEffects.java b/src/main/java/net/minecraft/world/item/component/SuspiciousStewEffects.java -index 04760d8ba7c560bd9d11191c666715ae8c3e4bff..768f90682cd10045c16337fecc2702f57dfe8a50 100644 ---- a/src/main/java/net/minecraft/world/item/component/SuspiciousStewEffects.java -+++ b/src/main/java/net/minecraft/world/item/component/SuspiciousStewEffects.java -@@ -47,9 +47,14 @@ public record SuspiciousStewEffects(List effects) i - // CraftBukkit start - @Override - public void cancelUsingItem(net.minecraft.server.level.ServerPlayer entityplayer, ItemStack itemstack) { -+ final List> packets = new java.util.ArrayList<>(); // Paper - bundlize packets - for (SuspiciousStewEffects.Entry suspicioussteweffects_a : this.effects) { -- entityplayer.connection.send(new net.minecraft.network.protocol.game.ClientboundRemoveMobEffectPacket(entityplayer.getId(), suspicioussteweffects_a.effect())); -+ packets.add(new net.minecraft.network.protocol.game.ClientboundRemoveMobEffectPacket(entityplayer.getId(), suspicioussteweffects_a.effect())); // Paper - bundlize packets - } -+ // Paper start - bundlize packets -+ entityplayer.server.getPlayerList().sendActiveEffects(entityplayer, packets::add); -+ entityplayer.connection.send(new net.minecraft.network.protocol.game.ClientboundBundlePacket(packets)); -+ // Paper end - bundlize packets - } - // CraftBukkit end - diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index 7536ab5c22d97a074c08a95fff6bc756d61e387d..b0e49ad831f1ebc6b126bf82c5fddaebffb91312 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java diff --git a/patches/server/1001-Only-call-EntityDamageEvents-before-actuallyHurt.patch b/patches/server/1001-Only-call-EntityDamageEvents-before-actuallyHurt.patch index 9a4b69900924..4dfe84dde115 100644 --- a/patches/server/1001-Only-call-EntityDamageEvents-before-actuallyHurt.patch +++ b/patches/server/1001-Only-call-EntityDamageEvents-before-actuallyHurt.patch @@ -12,7 +12,7 @@ This patch moves the invocation directly before the #actuallyHurt calls, respective invulnerable timings. diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 5e4716158da891216acc835f2560f980f527c66f..ad536c76010957650814b293fc8220ac525c13f1 100644 +index d19a9aa8f73b3a07e7d3d63efa5d411add163fa4..14420fb1ab7f77ef649a86d4fb58e747e4bab0cd 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -1489,12 +1489,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/1019-Check-dead-flag-in-isAlive.patch b/patches/server/1019-Check-dead-flag-in-isAlive.patch index e2836e573862..b4ac221ddf88 100644 --- a/patches/server/1019-Check-dead-flag-in-isAlive.patch +++ b/patches/server/1019-Check-dead-flag-in-isAlive.patch @@ -15,7 +15,7 @@ Also, even if the plugin is responsibly checking !isDead() before modifying heal I am currently unable to replicate, these "revived" entities can still appear diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index ad536c76010957650814b293fc8220ac525c13f1..ceaba7b82e9ff73a14fdef046e63b07c4d0fd5e9 100644 +index 14420fb1ab7f77ef649a86d4fb58e747e4bab0cd..3cc0b820363e748bca7f8770239b38f3845dd6a6 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -2145,7 +2145,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/1032-Void-damage-configuration-API.patch b/patches/server/1032-Void-damage-configuration-API.patch index dd9e6079b9e8..e570f4305a17 100644 --- a/patches/server/1032-Void-damage-configuration-API.patch +++ b/patches/server/1032-Void-damage-configuration-API.patch @@ -20,7 +20,7 @@ index ddfc4818f091802e5999c6b99e5bc57c6f370648..e5466be840ef32e4fa17c0e9446c4d0b && (!(this instanceof Player player) || !player.getAbilities().invulnerable))) { // Paper end - Configurable nether ceiling damage diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index ceaba7b82e9ff73a14fdef046e63b07c4d0fd5e9..2914be5f6681c513bf2878a92c0c60ad997852dc 100644 +index 3cc0b820363e748bca7f8770239b38f3845dd6a6..a7a2306433014f45e2a448ebe125b668cc49b3d1 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -2700,7 +2700,7 @@ public abstract class LivingEntity extends Entity implements Attackable { diff --git a/patches/server/1038-Moonrise-optimisation-patches.patch b/patches/server/1038-Moonrise-optimisation-patches.patch index c40f78385521..6faf764e051a 100644 --- a/patches/server/1038-Moonrise-optimisation-patches.patch +++ b/patches/server/1038-Moonrise-optimisation-patches.patch @@ -28026,10 +28026,10 @@ index b7d29389a357f142237cecd75f8ca91cf1eb6b5b..e4b0dc3121101d54394a0c3a413dabf8 this.generatingStep = generationStep; this.cache = chunks; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 700ab5ef2f8ab1466c4f659cd34679dc809efbaf..b28b23c69512b054e856388f2f94d27d35347b8c 100644 +index f6eed6cb2bd69c15aa36a8d8d9abdfda6d4a0622..1ada5a98169027cbb04f6bc37c96245c17d44c1e 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1420,7 +1420,7 @@ public abstract class PlayerList { +@@ -1415,7 +1415,7 @@ public abstract class PlayerList { public void setViewDistance(int viewDistance) { this.viewDistance = viewDistance; diff --git a/patches/server/1042-Improved-Watchdog-Support.patch b/patches/server/1042-Improved-Watchdog-Support.patch index d19dc9a1736f..77dc664f2898 100644 --- a/patches/server/1042-Improved-Watchdog-Support.patch +++ b/patches/server/1042-Improved-Watchdog-Support.patch @@ -302,7 +302,7 @@ index bf2bae3166df06be240dbbeecce16a24c85897a9..c06863578c5d654706d93e73059d89c1 } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index b28b23c69512b054e856388f2f94d27d35347b8c..88f40e54fa3b78d82261e06f941ef42587d52c25 100644 +index 1ada5a98169027cbb04f6bc37c96245c17d44c1e..9c474f3e603c6c274610e15f184468dc640b5eb0 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -553,7 +553,7 @@ public abstract class PlayerList { diff --git a/patches/server/1048-Incremental-chunk-and-player-saving.patch b/patches/server/1048-Incremental-chunk-and-player-saving.patch index 9494da1fd094..239e73fd1540 100644 --- a/patches/server/1048-Incremental-chunk-and-player-saving.patch +++ b/patches/server/1048-Incremental-chunk-and-player-saving.patch @@ -97,7 +97,7 @@ index 8ceeebb561046933cba0725e15732fa074226884..8c9148426f23cbbdfaf7ae66657d1a62 private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10; private static final int FLY_STAT_RECORDING_SPEED = 25; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 88f40e54fa3b78d82261e06f941ef42587d52c25..cf42042c754b30e41c0ec8a6a15195369bdbd199 100644 +index 9c474f3e603c6c274610e15f184468dc640b5eb0..0856313f8da044bf021bf04f5ef67a17f4a9f7c6 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -518,6 +518,7 @@ public abstract class PlayerList { @@ -108,7 +108,7 @@ index 88f40e54fa3b78d82261e06f941ef42587d52c25..cf42042c754b30e41c0ec8a6a1519536 this.playerIo.save(player); ServerStatsCounter serverstatisticmanager = (ServerStatsCounter) player.getStats(); // CraftBukkit -@@ -1152,9 +1153,21 @@ public abstract class PlayerList { +@@ -1147,9 +1148,21 @@ public abstract class PlayerList { } public void saveAll() { diff --git a/patches/server/1051-Lag-compensation-ticks.patch b/patches/server/1051-Lag-compensation-ticks.patch index a919d8ba478f..61cc0cc04807 100644 --- a/patches/server/1051-Lag-compensation-ticks.patch +++ b/patches/server/1051-Lag-compensation-ticks.patch @@ -63,7 +63,7 @@ index 504c996220b278c194c93e001a3b326d549868ec..a96f859a5d0c6ec692d4627a69f3c9ee if (this.hasDelayedDestroy) { diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 2914be5f6681c513bf2878a92c0c60ad997852dc..0831d69d6ac1aa112dfe8243b01adcf5e8eba6a0 100644 +index a7a2306433014f45e2a448ebe125b668cc49b3d1..e3b81e5b2591fde8e15dfd0bee393000dd633096 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -4050,6 +4050,10 @@ public abstract class LivingEntity extends Entity implements Attackable { From 13308806ac522a5617733630bf3d9536088f2fe9 Mon Sep 17 00:00:00 2001 From: Noah van der Aa Date: Wed, 30 Oct 2024 17:31:33 +0100 Subject: [PATCH 116/119] Add Friction API to minecarts --- patches/api/0376-Friction-API.patch | 13 ++++ patches/server/0763-Friction-API.patch | 89 ++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/patches/api/0376-Friction-API.patch b/patches/api/0376-Friction-API.patch index 7e07d5afbb91..8dc2a9591021 100644 --- a/patches/api/0376-Friction-API.patch +++ b/patches/api/0376-Friction-API.patch @@ -71,3 +71,16 @@ index 9f3e2903c955f2a5d1b25825c49188df62d20cef..016529563381a674db8050cb328f9e8f /** * Gets the height of the living entity's eyes above its Location. +diff --git a/src/main/java/org/bukkit/entity/Minecart.java b/src/main/java/org/bukkit/entity/Minecart.java +index 148d8cddba48a886eddef72a3de63d5eaa15949f..52cac73b7680806299a92013bbf959ecacac824f 100644 +--- a/src/main/java/org/bukkit/entity/Minecart.java ++++ b/src/main/java/org/bukkit/entity/Minecart.java +@@ -11,7 +11,7 @@ import org.jetbrains.annotations.Nullable; + /** + * Represents a minecart entity. + */ +-public interface Minecart extends Vehicle { ++public interface Minecart extends Vehicle, io.papermc.paper.entity.Frictional { // Paper + + /** + * Sets a minecart's damage. diff --git a/patches/server/0763-Friction-API.patch b/patches/server/0763-Friction-API.patch index 8d3dd8593522..8a1f01205303 100644 --- a/patches/server/0763-Friction-API.patch +++ b/patches/server/0763-Friction-API.patch @@ -109,6 +109,72 @@ index d555fd0b200c012f30ed0c0ec09a37b25a737b76..7a6d51020d9c6be33b4c34c0d6085595 if (this.getItem().isEmpty()) { this.discard(null); // CraftBukkit - add Bukkit remove cause } +diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java +index d8fcd6d1edec1f31a861fab4b86cbeb15ddc799d..d277f56fef882313d6d21f636fafae2f26630ad7 100644 +--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java ++++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java +@@ -93,6 +93,7 @@ public abstract class AbstractMinecart extends VehicleEntity { + private double flyingZ = 0.95; + public double maxSpeed = 0.4D; + // CraftBukkit end ++ public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API + + protected AbstractMinecart(EntityType type, Level world) { + super(type, world); +@@ -552,6 +553,16 @@ public abstract class AbstractMinecart extends VehicleEntity { + + this.flipped = nbt.getBoolean("FlippedRotation"); + this.firstTick = nbt.getBoolean("HasTicked"); ++ // Paper start - Friction API ++ if (nbt.contains("Paper.FrictionState")) { ++ String fs = nbt.getString("Paper.FrictionState"); ++ try { ++ frictionState = net.kyori.adventure.util.TriState.valueOf(fs); ++ } catch (Exception ignored) { ++ com.mojang.logging.LogUtils.getLogger().error("Unknown friction state " + fs + " for " + this); ++ } ++ } ++ // Paper end - Friction API + } + + @Override +@@ -564,6 +575,12 @@ public abstract class AbstractMinecart extends VehicleEntity { + + nbt.putBoolean("FlippedRotation", this.flipped); + nbt.putBoolean("HasTicked", this.firstTick); ++ ++ // Paper start - Friction API ++ if (this.frictionState != net.kyori.adventure.util.TriState.NOT_SET) { ++ nbt.putString("Paper.FrictionState", this.frictionState.toString()); ++ } ++ // Paper end - Friction API + } + + @Override +diff --git a/src/main/java/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java b/src/main/java/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java +index 00b0004940339dc105fb95f813bd35b16f7a9fb4..a8718ee94cd6b9a20bd1e9a49d58d39e6f3f2a7a 100644 +--- a/src/main/java/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java ++++ b/src/main/java/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java +@@ -548,6 +548,7 @@ public class NewMinecartBehavior extends MinecartBehavior { + + @Override + public double getSlowdownFactor() { ++ if (this.minecart.frictionState == net.kyori.adventure.util.TriState.FALSE) return 1; // Paper + return this.minecart.isVehicle() || !this.minecart.slowWhenEmpty ? 0.997D : 0.975D; // CraftBukkit - add !this.slowWhenEmpty + } + +diff --git a/src/main/java/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java b/src/main/java/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java +index cf871c174091139c8ad1affb84f98fcd74b60dee..23cbafcc12f6e5f5755215a72879a6cab306ad18 100644 +--- a/src/main/java/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java ++++ b/src/main/java/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java +@@ -522,6 +522,7 @@ public class OldMinecartBehavior extends MinecartBehavior { + + @Override + public double getSlowdownFactor() { ++ if (this.minecart.frictionState == net.kyori.adventure.util.TriState.FALSE) return 1; // Paper + return this.minecart.isVehicle() || !this.minecart.slowWhenEmpty ? 0.997D : 0.96D; // CraftBukkit - add !this.slowWhenEmpty + } + } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java index 1a291dd8a287db30e71dcb315599fc4b038764c4..30d62ee4d5cd2ddacb8783b5bbbf475d592b3e02 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java @@ -154,3 +220,26 @@ index 1ceaa081231a617bd87331b308c24d9c7a8dcf2b..2fd4a3068d86a37cc18c9203448823c5 + } + // Paper end - friction API } +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java +index d35c1a10e58932b19c8053c5dacdc25fd7f22e8c..ab9d06a9a4951a5b8aa14d47818a3850433e92b8 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java +@@ -137,4 +137,18 @@ public abstract class CraftMinecart extends CraftVehicle implements Minecart { + public int getDisplayBlockOffset() { + return this.getHandle().getDisplayOffset(); + } ++ ++ // Paper start - Friction API ++ @org.jetbrains.annotations.NotNull ++ @Override ++ public net.kyori.adventure.util.TriState getFrictionState() { ++ return this.getHandle().frictionState; ++ } ++ ++ @Override ++ public void setFrictionState(@org.jetbrains.annotations.NotNull net.kyori.adventure.util.TriState state) { ++ java.util.Objects.requireNonNull(state, "state may not be null"); ++ this.getHandle().frictionState = state; ++ } ++ // Paper end - Friction API + } From 580a61055099b3ee07cabca5cf7c5c68bb94bc1a Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Wed, 30 Oct 2024 10:09:05 -0700 Subject: [PATCH 117/119] Allow using old ender pearl behavior & apply ender pearl exploit patch (#11524) When enabled, ender pearls will not load chunks and will save to the world instead of the player. Also changes the exploit config to be default false, as it only makes sense when legacy behavior is enabled. --- patches/server/0005-Paper-config-files.patch | 7 ++- .../server/0211-PlayerElytraBoostEvent.patch | 2 +- .../0212-PlayerLaunchProjectileEvent.patch | 2 +- ...5-Vanished-players-don-t-have-rights.patch | 2 +- ...nd-additions-to-the-spawn-reason-API.patch | 2 +- ...gurable-projectile-relative-velocity.patch | 2 +- patches/server/0669-More-Projectile-API.patch | 2 +- ...ook-changes-from-crashing-the-server.patch | 2 +- ...esh-ProjectileSource-for-projectiles.patch | 2 +- .../1005-Fix-PickupStatus-getting-reset.patch | 2 +- ...Allow-using-old-ender-pearl-behavior.patch | 62 +++++++++++++++++++ ...056-Block-Enderpearl-Travel-Exploit.patch} | 13 ++-- 12 files changed, 81 insertions(+), 19 deletions(-) create mode 100644 patches/server/1055-Allow-using-old-ender-pearl-behavior.patch rename patches/{removed/1.21.2/0186-Block-Enderpearl-Travel-Exploit.patch => server/1056-Block-Enderpearl-Travel-Exploit.patch} (73%) diff --git a/patches/server/0005-Paper-config-files.patch b/patches/server/0005-Paper-config-files.patch index c4181a6029bc..a1e58cd06d02 100644 --- a/patches/server/0005-Paper-config-files.patch +++ b/patches/server/0005-Paper-config-files.patch @@ -1423,10 +1423,10 @@ index 0000000000000000000000000000000000000000..279b24c689b9979884b65df7eb1f0590 +} diff --git a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java new file mode 100644 -index 0000000000000000000000000000000000000000..a81a332ffb80e67d7f886295099b5cd2ae8994c5 +index 0000000000000000000000000000000000000000..dad3fcc689ec806f985122a7cbd501a7d0fd0d36 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java -@@ -0,0 +1,580 @@ +@@ -0,0 +1,581 @@ +package io.papermc.paper.configuration; + +import com.google.common.collect.HashBasedTable; @@ -1889,7 +1889,7 @@ index 0000000000000000000000000000000000000000..a81a332ffb80e67d7f886295099b5cd2 + + public class Fixes extends ConfigurationPart { + public boolean fixItemsMergingThroughWalls = false; -+ public boolean disableUnloadedChunkEnderpearlExploit = true; ++ public boolean disableUnloadedChunkEnderpearlExploit = false; + public boolean preventTntFromMovingInWater = false; + public boolean splitOverstackedLoot = true; + public IntOr.Disabled fallingBlockHeightNerf = IntOr.Disabled.DISABLED; @@ -1997,6 +1997,7 @@ index 0000000000000000000000000000000000000000..a81a332ffb80e67d7f886295099b5cd2 + public boolean disableSprintInterruptionOnAttack = false; + public int shieldBlockingDelay = 5; + public boolean disableRelativeProjectileVelocity = false; ++ public boolean legacyEnderPearlBehavior = false; + + public enum RedstoneImplementation { + VANILLA, EIGENCRAFT, ALTERNATE_CURRENT diff --git a/patches/server/0211-PlayerElytraBoostEvent.patch b/patches/server/0211-PlayerElytraBoostEvent.patch index 907b6b84e09f..3042206c2064 100644 --- a/patches/server/0211-PlayerElytraBoostEvent.patch +++ b/patches/server/0211-PlayerElytraBoostEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] PlayerElytraBoostEvent diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 46eff02aa250890485d58a10e76d571052086aa8..fd8afa4b12d66d1e0a789cef41ca77c45c64e2e8 100644 +index fed01aea47090b990939becde837add6c36bf418..f8ae12a3540c4a7aa7e2c1656cbd866e33e11f57 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -219,11 +219,34 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/0212-PlayerLaunchProjectileEvent.patch b/patches/server/0212-PlayerLaunchProjectileEvent.patch index 73ad83abbd81..b41463a06a15 100644 --- a/patches/server/0212-PlayerLaunchProjectileEvent.patch +++ b/patches/server/0212-PlayerLaunchProjectileEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] PlayerLaunchProjectileEvent diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index fd8afa4b12d66d1e0a789cef41ca77c45c64e2e8..d29d58fd9879d69a7d3fd7cbcad8cc31c89fa679 100644 +index f8ae12a3540c4a7aa7e2c1656cbd866e33e11f57..d6dfda0580d919eb8a000113e7f9dd9794117b45 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -197,7 +197,12 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/0215-Vanished-players-don-t-have-rights.patch b/patches/server/0215-Vanished-players-don-t-have-rights.patch index dd1cb5bca923..4d196bf7d16b 100644 --- a/patches/server/0215-Vanished-players-don-t-have-rights.patch +++ b/patches/server/0215-Vanished-players-don-t-have-rights.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Vanished players don't have rights diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index d29d58fd9879d69a7d3fd7cbcad8cc31c89fa679..07b7187382fefc8b03a8822a097fb04e647f7732 100644 +index d6dfda0580d919eb8a000113e7f9dd9794117b45..6c7f644738548da30908a08dcfde8142b597c0b7 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -387,6 +387,15 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch b/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch index 51eb46f1253b..cc586b335c34 100644 --- a/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch +++ b/patches/server/0278-Fixes-and-additions-to-the-spawn-reason-API.patch @@ -173,7 +173,7 @@ index 2eecdcbea3d51b1fb6e0c3db0667464a699ca0df..c68ddccd5fbe27f6a62cedbdc2337f1b this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause } diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 07b7187382fefc8b03a8822a097fb04e647f7732..e21b9a34d07fcd75f9c470074c545862d0aa9363 100644 +index 6c7f644738548da30908a08dcfde8142b597c0b7..80637835a35dbfd7c7458b246ddee9d836e5101a 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -214,7 +214,12 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/0291-Configurable-projectile-relative-velocity.patch b/patches/server/0291-Configurable-projectile-relative-velocity.patch index c2d2345882ac..93e1cc2d7d26 100644 --- a/patches/server/0291-Configurable-projectile-relative-velocity.patch +++ b/patches/server/0291-Configurable-projectile-relative-velocity.patch @@ -25,7 +25,7 @@ P3) Solutions for 1) and especially 2) might not be future-proof, while this server-internal fix makes this change future-proof. diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index e21b9a34d07fcd75f9c470074c545862d0aa9363..09d1131c7f2b32b6c032341a60521608b098c109 100644 +index 80637835a35dbfd7c7458b246ddee9d836e5101a..0e4ba92d97998937ccb83ebd60aaad3fb68f7546 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -192,8 +192,11 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/0669-More-Projectile-API.patch b/patches/server/0669-More-Projectile-API.patch index 9f9c1e0dd46d..afff65d722f8 100644 --- a/patches/server/0669-More-Projectile-API.patch +++ b/patches/server/0669-More-Projectile-API.patch @@ -54,7 +54,7 @@ index 536196a740f607adda2a5ae7f644981ac26bef98..1f95234c0a1457050574aa0f6c4b2a8c public boolean calculateOpenWater(BlockPos pos) { FishingHook.OpenWaterType entityfishinghook_waterposition = FishingHook.OpenWaterType.INVALID; diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 09d1131c7f2b32b6c032341a60521608b098c109..824090367e833c57a22c1017981f0508b28a35d2 100644 +index 0e4ba92d97998937ccb83ebd60aaad3fb68f7546..01684c903930b14a0df3a146176e2b476a374efb 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -288,7 +288,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/0728-Stop-large-look-changes-from-crashing-the-server.patch b/patches/server/0728-Stop-large-look-changes-from-crashing-the-server.patch index 028287678e1a..2c6afde2fa22 100644 --- a/patches/server/0728-Stop-large-look-changes-from-crashing-the-server.patch +++ b/patches/server/0728-Stop-large-look-changes-from-crashing-the-server.patch @@ -54,7 +54,7 @@ index 786ac2127bc743cf2a33776314a4b5c197f35538..b367f6e329f44801c6f0d34f44749709 gameprofilerfiller.pop(); this.animStep += f2; diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 824090367e833c57a22c1017981f0508b28a35d2..df0417f27bbf0f18f007746afe24fab48e2a0a08 100644 +index 01684c903930b14a0df3a146176e2b476a374efb..bf7f81d99af300e89834981eab32568a3747d270 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -428,13 +428,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/0809-Refresh-ProjectileSource-for-projectiles.patch b/patches/server/0809-Refresh-ProjectileSource-for-projectiles.patch index ccbd8c45c027..4e706befacd8 100644 --- a/patches/server/0809-Refresh-ProjectileSource-for-projectiles.patch +++ b/patches/server/0809-Refresh-ProjectileSource-for-projectiles.patch @@ -26,7 +26,7 @@ index 5340d6d911a7e586468f2b7e2e74b3386d1dc72d..90b47da5c6df05565b522636e08c4ebb public boolean lastDamageCancelled; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled public boolean persistentInvisibility = false; diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index df0417f27bbf0f18f007746afe24fab48e2a0a08..1a45fca020f5ecee7af837af01b60ed4590b845a 100644 +index bf7f81d99af300e89834981eab32568a3747d270..52d539d54113c4dcd2d8d748ae0abf6dec5bfc72 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -63,17 +63,35 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/1005-Fix-PickupStatus-getting-reset.patch b/patches/server/1005-Fix-PickupStatus-getting-reset.patch index 4f8f62e8bc2e..5008a8638b23 100644 --- a/patches/server/1005-Fix-PickupStatus-getting-reset.patch +++ b/patches/server/1005-Fix-PickupStatus-getting-reset.patch @@ -24,7 +24,7 @@ index 14e31ae88e90d8ea1a98800cc6c1c3527bb2ed6b..accc246f441c8bf5e1a755cfc0db8f97 byte b0 = 0; diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 1a45fca020f5ecee7af837af01b60ed4590b845a..49c0f09f91f9ea2428fd3b13b00c99073074beba 100644 +index 52d539d54113c4dcd2d8d748ae0abf6dec5bfc72..bf2e79c50092acd13e97ab6e32471a9c527a524e 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -353,7 +353,13 @@ public abstract class Projectile extends Entity implements TraceableEntity { diff --git a/patches/server/1055-Allow-using-old-ender-pearl-behavior.patch b/patches/server/1055-Allow-using-old-ender-pearl-behavior.patch new file mode 100644 index 000000000000..116240194a22 --- /dev/null +++ b/patches/server/1055-Allow-using-old-ender-pearl-behavior.patch @@ -0,0 +1,62 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> +Date: Sun, 27 Oct 2024 12:36:53 -0700 +Subject: [PATCH] Allow using old ender pearl behavior + +When enabled, ender pearls will not load chunks and will save to the world instead of the player. + +== AT == +public net.minecraft.world.entity.projectile.Projectile cachedOwner + +diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java +index 4e4e5b7e8c387cf13cf5bc5e39d334c3222c9103..cffbd3300967e5d80b5973b35a76235bb2aa1b73 100644 +--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java ++++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +@@ -836,6 +836,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple + + while (iterator.hasNext()) { + ThrownEnderpearl entityenderpearl = (ThrownEnderpearl) iterator.next(); ++ if (entityenderpearl.level().paperConfig().misc.legacyEnderPearlBehavior) continue; // Paper - Allow using old ender pearl behavior + + if (entityenderpearl.isRemoved()) { + ServerPlayer.LOGGER.warn("Trying to save removed ender pearl, skipping"); +@@ -3146,7 +3147,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple + } + + public static long placeEnderPearlTicket(ServerLevel world, ChunkPos chunkPos) { +- world.getChunkSource().addRegionTicket(TicketType.ENDER_PEARL, chunkPos, 2, chunkPos); ++ if (!world.paperConfig().misc.legacyEnderPearlBehavior) world.getChunkSource().addRegionTicket(TicketType.ENDER_PEARL, chunkPos, 2, chunkPos); // Paper - Allow using old ender pearl behavior + return TicketType.ENDER_PEARL.timeout(); + } + +diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java +index cf42042c754b30e41c0ec8a6a15195369bdbd199..1fcd9cd9344b0d2c4752042b07142db7d727dce8 100644 +--- a/src/main/java/net/minecraft/server/players/PlayerList.java ++++ b/src/main/java/net/minecraft/server/players/PlayerList.java +@@ -602,7 +602,13 @@ public abstract class PlayerList { + while (iterator.hasNext()) { + ThrownEnderpearl entityenderpearl = (ThrownEnderpearl) iterator.next(); + ++ // Paper start - Allow using old ender pearl behavior ++ if (!entityenderpearl.level().paperConfig().misc.legacyEnderPearlBehavior) { + entityenderpearl.setRemoved(Entity.RemovalReason.UNLOADED_WITH_PLAYER, EntityRemoveEvent.Cause.PLAYER_QUIT); // CraftBukkit - add Bukkit remove cause ++ } else { ++ entityenderpearl.cachedOwner = null; ++ } ++ // Paper end - Allow using old ender pearl behavior + } + + worldserver.removePlayerImmediately(entityplayer, Entity.RemovalReason.UNLOADED_WITH_PLAYER); +diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java +index 5f790dd24f2bdae827c6dc597064b9b265089751..bd2684528157f928460f2143dd71a48e11983123 100644 +--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java ++++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java +@@ -252,7 +252,7 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { + Entity entity = super.teleport(teleportTarget); + + if (entity != null) { +- entity.placePortalTicket(BlockPos.containing(entity.position())); ++ if (!this.level().paperConfig().misc.legacyEnderPearlBehavior) entity.placePortalTicket(BlockPos.containing(entity.position())); // Paper - Allow using old ender pearl behavior + } + + return entity; diff --git a/patches/removed/1.21.2/0186-Block-Enderpearl-Travel-Exploit.patch b/patches/server/1056-Block-Enderpearl-Travel-Exploit.patch similarity index 73% rename from patches/removed/1.21.2/0186-Block-Enderpearl-Travel-Exploit.patch rename to patches/server/1056-Block-Enderpearl-Travel-Exploit.patch index 677f86fec00c..a72d72a784a3 100644 --- a/patches/removed/1.21.2/0186-Block-Enderpearl-Travel-Exploit.patch +++ b/patches/server/1056-Block-Enderpearl-Travel-Exploit.patch @@ -16,19 +16,18 @@ Might be worth to re-add once an option to disable the above vanilla mechanic is fully prevent enderpearl travel exploits. == AT == -public net.minecraft.world.entity.projectile.Projectile cachedOwner public net.minecraft.world.entity.projectile.Projectile ownerUUID diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 21c3d771a3dd921767c2cba1e11583d015879ca9..332d378979925f1197f4218919442688a4c47c23 100644 +index e65cfb1132f5f0c9e1fa5ae4a46a8abed0c56be1..d5b9db881a49612c7587f8821adf923e28791d07 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2194,6 +2194,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2658,6 +2658,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public void onTickingEnd(Entity entity) { ServerLevel.this.entityTickList.remove(entity); + // Paper start - Reset pearls when they stop being ticked -+ if (paperConfig().fixes.disableUnloadedChunkEnderpearlExploit && entity instanceof net.minecraft.world.entity.projectile.ThrownEnderpearl pearl) { ++ if (ServerLevel.this.paperConfig().fixes.disableUnloadedChunkEnderpearlExploit && ServerLevel.this.paperConfig().misc.legacyEnderPearlBehavior && entity instanceof net.minecraft.world.entity.projectile.ThrownEnderpearl pearl) { + pearl.cachedOwner = null; + pearl.ownerUUID = null; + } @@ -37,14 +36,14 @@ index 21c3d771a3dd921767c2cba1e11583d015879ca9..332d378979925f1197f4218919442688 public void onTrackingStart(Entity entity) { diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index fed01aea47090b990939becde837add6c36bf418..a1840bb4a3307492f80f93c4433eec3be7f862f1 100644 +index bf2e79c50092acd13e97ab6e32471a9c527a524e..6c2d4d6f3a36ab452dfd3c33f66e54f152906639 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -116,6 +116,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { +@@ -134,6 +134,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { protected void readAdditionalSaveData(CompoundTag nbt) { if (nbt.hasUUID("Owner")) { this.setOwnerThroughUUID(nbt.getUUID("Owner")); -+ if (this instanceof ThrownEnderpearl && this.level() != null && this.level().paperConfig().fixes.disableUnloadedChunkEnderpearlExploit) { this.ownerUUID = null; } // Paper - Reset pearls when they stop being ticked; Don't store shooter name for pearls to block enderpearl travel exploit ++ if (this instanceof ThrownEnderpearl && this.level() != null && this.level().paperConfig().fixes.disableUnloadedChunkEnderpearlExploit && this.level().paperConfig().misc.legacyEnderPearlBehavior) { this.ownerUUID = null; } // Paper - Reset pearls when they stop being ticked; Don't store shooter name for pearls to block enderpearl travel exploit } this.leftOwner = nbt.getBoolean("LeftOwner"); From 40a960db45f45f381328a60695e933615475aea8 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Wed, 30 Oct 2024 18:36:22 +0100 Subject: [PATCH 118/119] Rebuild patches --- ...or.patch => 1056-Allow-using-old-ender-pearl-behavior.patch} | 2 +- ...Exploit.patch => 1057-Block-Enderpearl-Travel-Exploit.patch} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename patches/server/{1055-Allow-using-old-ender-pearl-behavior.patch => 1056-Allow-using-old-ender-pearl-behavior.patch} (97%) rename patches/server/{1056-Block-Enderpearl-Travel-Exploit.patch => 1057-Block-Enderpearl-Travel-Exploit.patch} (96%) diff --git a/patches/server/1055-Allow-using-old-ender-pearl-behavior.patch b/patches/server/1056-Allow-using-old-ender-pearl-behavior.patch similarity index 97% rename from patches/server/1055-Allow-using-old-ender-pearl-behavior.patch rename to patches/server/1056-Allow-using-old-ender-pearl-behavior.patch index 116240194a22..554c760b1aa3 100644 --- a/patches/server/1055-Allow-using-old-ender-pearl-behavior.patch +++ b/patches/server/1056-Allow-using-old-ender-pearl-behavior.patch @@ -30,7 +30,7 @@ index 4e4e5b7e8c387cf13cf5bc5e39d334c3222c9103..cffbd3300967e5d80b5973b35a76235b } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index cf42042c754b30e41c0ec8a6a15195369bdbd199..1fcd9cd9344b0d2c4752042b07142db7d727dce8 100644 +index 0856313f8da044bf021bf04f5ef67a17f4a9f7c6..6b885e55334f3d5c469e889f070e95d94ae782d3 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -602,7 +602,13 @@ public abstract class PlayerList { diff --git a/patches/server/1056-Block-Enderpearl-Travel-Exploit.patch b/patches/server/1057-Block-Enderpearl-Travel-Exploit.patch similarity index 96% rename from patches/server/1056-Block-Enderpearl-Travel-Exploit.patch rename to patches/server/1057-Block-Enderpearl-Travel-Exploit.patch index a72d72a784a3..75bce7f50ba7 100644 --- a/patches/server/1056-Block-Enderpearl-Travel-Exploit.patch +++ b/patches/server/1057-Block-Enderpearl-Travel-Exploit.patch @@ -19,7 +19,7 @@ fully prevent enderpearl travel exploits. public net.minecraft.world.entity.projectile.Projectile ownerUUID diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index e65cfb1132f5f0c9e1fa5ae4a46a8abed0c56be1..d5b9db881a49612c7587f8821adf923e28791d07 100644 +index 21c78bc96c39f6261adaad2e7c225948b6f1606f..5964d601c05176f48167cc92057a59e52a4da92b 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2658,6 +2658,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe From eeb8c37461f6923fa6d153b22841b37a0c83c26a Mon Sep 17 00:00:00 2001 From: Abel Date: Wed, 30 Oct 2024 23:30:16 +0100 Subject: [PATCH 119/119] Add test for org.bukkit.craftbukkit.entity.CraftMinecart#minecartEntityTypeToMaterial --- ....bukkit.craftbukkit.entity.CraftMine.patch | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 patches/server/1058-Add-test-for-org.bukkit.craftbukkit.entity.CraftMine.patch diff --git a/patches/server/1058-Add-test-for-org.bukkit.craftbukkit.entity.CraftMine.patch b/patches/server/1058-Add-test-for-org.bukkit.craftbukkit.entity.CraftMine.patch new file mode 100644 index 000000000000..1b3fe8c527c4 --- /dev/null +++ b/patches/server/1058-Add-test-for-org.bukkit.craftbukkit.entity.CraftMine.patch @@ -0,0 +1,50 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Abel +Date: Wed, 30 Oct 2024 23:29:26 +0100 +Subject: [PATCH] Add test for + org.bukkit.craftbukkit.entity.CraftMinecart#minecartEntityTypeToMaterial + + +diff --git a/src/test/java/org/bukkit/craftbukkit/entity/CraftMinecartTest.java b/src/test/java/org/bukkit/craftbukkit/entity/CraftMinecartTest.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ea7c81ecc5deedc198dc2c3618d5c4a06d656e84 +--- /dev/null ++++ b/src/test/java/org/bukkit/craftbukkit/entity/CraftMinecartTest.java +@@ -0,0 +1,37 @@ ++package org.bukkit.craftbukkit.entity; ++ ++import java.util.stream.Stream; ++import net.minecraft.world.entity.EntityType; ++import net.minecraft.world.item.Item; ++import net.minecraft.world.item.Items; ++import org.junit.jupiter.params.ParameterizedTest; ++import org.junit.jupiter.params.provider.Arguments; ++import org.junit.jupiter.params.provider.MethodSource; ++ ++import static org.junit.jupiter.api.Assertions.*; ++ ++class CraftMinecartTest { ++ ++ private static Stream minecartTypesAsArguments() { ++ ++ return Stream.of( ++ Arguments.of(EntityType.MINECART, Items.MINECART), ++ Arguments.of(EntityType.CHEST_MINECART, Items.CHEST_MINECART), ++ Arguments.of(EntityType.FURNACE_MINECART, Items.FURNACE_MINECART), ++ Arguments.of(EntityType.SPAWNER_MINECART, Items.MINECART), ++ Arguments.of(EntityType.COMMAND_BLOCK_MINECART, Items.COMMAND_BLOCK_MINECART), ++ Arguments.of(EntityType.HOPPER_MINECART, Items.HOPPER_MINECART), ++ Arguments.of(EntityType.TNT_MINECART, Items.TNT_MINECART) ++ ); ++ ++ } ++ ++ @ParameterizedTest ++ @MethodSource("minecartTypesAsArguments") ++ void minecartEntityTypeToMaterial(EntityType type, Item material) { ++ ++ assertEquals(CraftMinecart.minecartEntityTypeToMaterial(type), material, "EntityType %s doesn't match the material %s.".formatted(type.toString(), material.toString())); ++ ++ } ++ ++}